UNPKG

787 kBJavaScriptView Raw
1/** @license React v16.8.6
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 isSameOriginFrame(iframe) {
5336 try {
5337 // Accessing the contentDocument of a HTMLIframeElement can cause the browser
5338 // to throw, e.g. if it has a cross-origin src attribute.
5339 // Safari will show an error in the console when the access results in "Blocked a frame with origin". e.g:
5340 // iframe.contentDocument.defaultView;
5341 // A safety way is to access one of the cross origin properties: Window or Location
5342 // Which might result in "SecurityError" DOM Exception and it is compatible to Safari.
5343 // https://html.spec.whatwg.org/multipage/browsers.html#integration-with-idl
5344
5345 return typeof iframe.contentWindow.location.href === 'string';
5346 } catch (err) {
5347 return false;
5348 }
5349}
5350
5351function getActiveElementDeep() {
5352 var win = window;
5353 var element = getActiveElement();
5354 while (element instanceof win.HTMLIFrameElement) {
5355 if (isSameOriginFrame(element)) {
5356 win = element.contentWindow;
5357 } else {
5358 return element;
5359 }
5360 element = getActiveElement(win.document);
5361 }
5362 return element;
5363}
5364
5365/**
5366 * @ReactInputSelection: React input selection module. Based on Selection.js,
5367 * but modified to be suitable for react and has a couple of bug fixes (doesn't
5368 * assume buttons have range selections allowed).
5369 * Input selection module for React.
5370 */
5371
5372/**
5373 * @hasSelectionCapabilities: we get the element types that support selection
5374 * from https://html.spec.whatwg.org/#do-not-apply, looking at `selectionStart`
5375 * and `selectionEnd` rows.
5376 */
5377function hasSelectionCapabilities(elem) {
5378 var nodeName = elem && elem.nodeName && elem.nodeName.toLowerCase();
5379 return nodeName && (nodeName === 'input' && (elem.type === 'text' || elem.type === 'search' || elem.type === 'tel' || elem.type === 'url' || elem.type === 'password') || nodeName === 'textarea' || elem.contentEditable === 'true');
5380}
5381
5382function getSelectionInformation() {
5383 var focusedElem = getActiveElementDeep();
5384 return {
5385 focusedElem: focusedElem,
5386 selectionRange: hasSelectionCapabilities(focusedElem) ? getSelection$1(focusedElem) : null
5387 };
5388}
5389
5390/**
5391 * @restoreSelection: If any selection information was potentially lost,
5392 * restore it. This is useful when performing operations that could remove dom
5393 * nodes and place them back in, resulting in focus being lost.
5394 */
5395function restoreSelection(priorSelectionInformation) {
5396 var curFocusedElem = getActiveElementDeep();
5397 var priorFocusedElem = priorSelectionInformation.focusedElem;
5398 var priorSelectionRange = priorSelectionInformation.selectionRange;
5399 if (curFocusedElem !== priorFocusedElem && isInDocument(priorFocusedElem)) {
5400 if (priorSelectionRange !== null && hasSelectionCapabilities(priorFocusedElem)) {
5401 setSelection(priorFocusedElem, priorSelectionRange);
5402 }
5403
5404 // Focusing a node can change the scroll position, which is undesirable
5405 var ancestors = [];
5406 var ancestor = priorFocusedElem;
5407 while (ancestor = ancestor.parentNode) {
5408 if (ancestor.nodeType === ELEMENT_NODE) {
5409 ancestors.push({
5410 element: ancestor,
5411 left: ancestor.scrollLeft,
5412 top: ancestor.scrollTop
5413 });
5414 }
5415 }
5416
5417 if (typeof priorFocusedElem.focus === 'function') {
5418 priorFocusedElem.focus();
5419 }
5420
5421 for (var i = 0; i < ancestors.length; i++) {
5422 var info = ancestors[i];
5423 info.element.scrollLeft = info.left;
5424 info.element.scrollTop = info.top;
5425 }
5426 }
5427}
5428
5429/**
5430 * @getSelection: Gets the selection bounds of a focused textarea, input or
5431 * contentEditable node.
5432 * -@input: Look up selection bounds of this input
5433 * -@return {start: selectionStart, end: selectionEnd}
5434 */
5435function getSelection$1(input) {
5436 var selection = void 0;
5437
5438 if ('selectionStart' in input) {
5439 // Modern browser with input or textarea.
5440 selection = {
5441 start: input.selectionStart,
5442 end: input.selectionEnd
5443 };
5444 } else {
5445 // Content editable or old IE textarea.
5446 selection = getOffsets(input);
5447 }
5448
5449 return selection || { start: 0, end: 0 };
5450}
5451
5452/**
5453 * @setSelection: Sets the selection bounds of a textarea or input and focuses
5454 * the input.
5455 * -@input Set selection bounds of this input or textarea
5456 * -@offsets Object of same form that is returned from get*
5457 */
5458function setSelection(input, offsets) {
5459 var start = offsets.start,
5460 end = offsets.end;
5461
5462 if (end === undefined) {
5463 end = start;
5464 }
5465
5466 if ('selectionStart' in input) {
5467 input.selectionStart = start;
5468 input.selectionEnd = Math.min(end, input.value.length);
5469 } else {
5470 setOffsets(input, offsets);
5471 }
5472}
5473
5474var skipSelectionChangeEvent = canUseDOM && 'documentMode' in document && document.documentMode <= 11;
5475
5476var eventTypes$3 = {
5477 select: {
5478 phasedRegistrationNames: {
5479 bubbled: 'onSelect',
5480 captured: 'onSelectCapture'
5481 },
5482 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]
5483 }
5484};
5485
5486var activeElement$1 = null;
5487var activeElementInst$1 = null;
5488var lastSelection = null;
5489var mouseDown = false;
5490
5491/**
5492 * Get an object which is a unique representation of the current selection.
5493 *
5494 * The return value will not be consistent across nodes or browsers, but
5495 * two identical selections on the same node will return identical objects.
5496 *
5497 * @param {DOMElement} node
5498 * @return {object}
5499 */
5500function getSelection(node) {
5501 if ('selectionStart' in node && hasSelectionCapabilities(node)) {
5502 return {
5503 start: node.selectionStart,
5504 end: node.selectionEnd
5505 };
5506 } else {
5507 var win = node.ownerDocument && node.ownerDocument.defaultView || window;
5508 var selection = win.getSelection();
5509 return {
5510 anchorNode: selection.anchorNode,
5511 anchorOffset: selection.anchorOffset,
5512 focusNode: selection.focusNode,
5513 focusOffset: selection.focusOffset
5514 };
5515 }
5516}
5517
5518/**
5519 * Get document associated with the event target.
5520 *
5521 * @param {object} nativeEventTarget
5522 * @return {Document}
5523 */
5524function getEventTargetDocument(eventTarget) {
5525 return eventTarget.window === eventTarget ? eventTarget.document : eventTarget.nodeType === DOCUMENT_NODE ? eventTarget : eventTarget.ownerDocument;
5526}
5527
5528/**
5529 * Poll selection to see whether it's changed.
5530 *
5531 * @param {object} nativeEvent
5532 * @param {object} nativeEventTarget
5533 * @return {?SyntheticEvent}
5534 */
5535function constructSelectEvent(nativeEvent, nativeEventTarget) {
5536 // Ensure we have the right element, and that the user is not dragging a
5537 // selection (this matches native `select` event behavior). In HTML5, select
5538 // fires only on input and textarea thus if there's no focused element we
5539 // won't dispatch.
5540 var doc = getEventTargetDocument(nativeEventTarget);
5541
5542 if (mouseDown || activeElement$1 == null || activeElement$1 !== getActiveElement(doc)) {
5543 return null;
5544 }
5545
5546 // Only fire when selection has actually changed.
5547 var currentSelection = getSelection(activeElement$1);
5548 if (!lastSelection || !shallowEqual(lastSelection, currentSelection)) {
5549 lastSelection = currentSelection;
5550
5551 var syntheticEvent = SyntheticEvent.getPooled(eventTypes$3.select, activeElementInst$1, nativeEvent, nativeEventTarget);
5552
5553 syntheticEvent.type = 'select';
5554 syntheticEvent.target = activeElement$1;
5555
5556 accumulateTwoPhaseDispatches(syntheticEvent);
5557
5558 return syntheticEvent;
5559 }
5560
5561 return null;
5562}
5563
5564/**
5565 * This plugin creates an `onSelect` event that normalizes select events
5566 * across form elements.
5567 *
5568 * Supported elements are:
5569 * - input (see `isTextInputElement`)
5570 * - textarea
5571 * - contentEditable
5572 *
5573 * This differs from native browser implementations in the following ways:
5574 * - Fires on contentEditable fields as well as inputs.
5575 * - Fires for collapsed selection.
5576 * - Fires after user input.
5577 */
5578var SelectEventPlugin = {
5579 eventTypes: eventTypes$3,
5580
5581 extractEvents: function (topLevelType, targetInst, nativeEvent, nativeEventTarget) {
5582 var doc = getEventTargetDocument(nativeEventTarget);
5583 // Track whether all listeners exists for this plugin. If none exist, we do
5584 // not extract events. See #3639.
5585 if (!doc || !isListeningToAllDependencies('onSelect', doc)) {
5586 return null;
5587 }
5588
5589 var targetNode = targetInst ? getNodeFromInstance$1(targetInst) : window;
5590
5591 switch (topLevelType) {
5592 // Track the input node that has focus.
5593 case TOP_FOCUS:
5594 if (isTextInputElement(targetNode) || targetNode.contentEditable === 'true') {
5595 activeElement$1 = targetNode;
5596 activeElementInst$1 = targetInst;
5597 lastSelection = null;
5598 }
5599 break;
5600 case TOP_BLUR:
5601 activeElement$1 = null;
5602 activeElementInst$1 = null;
5603 lastSelection = null;
5604 break;
5605 // Don't fire the event while the user is dragging. This matches the
5606 // semantics of the native select event.
5607 case TOP_MOUSE_DOWN:
5608 mouseDown = true;
5609 break;
5610 case TOP_CONTEXT_MENU:
5611 case TOP_MOUSE_UP:
5612 case TOP_DRAG_END:
5613 mouseDown = false;
5614 return constructSelectEvent(nativeEvent, nativeEventTarget);
5615 // Chrome and IE fire non-standard event when selection is changed (and
5616 // sometimes when it hasn't). IE's event fires out of order with respect
5617 // to key and input events on deletion, so we discard it.
5618 //
5619 // Firefox doesn't support selectionchange, so check selection status
5620 // after each key entry. The selection changes after keydown and before
5621 // keyup, but we check on keydown as well in the case of holding down a
5622 // key, when multiple keydown events are fired but only one keyup is.
5623 // This is also our approach for IE handling, for the reason above.
5624 case TOP_SELECTION_CHANGE:
5625 if (skipSelectionChangeEvent) {
5626 break;
5627 }
5628 // falls through
5629 case TOP_KEY_DOWN:
5630 case TOP_KEY_UP:
5631 return constructSelectEvent(nativeEvent, nativeEventTarget);
5632 }
5633
5634 return null;
5635 }
5636};
5637
5638/**
5639 * Inject modules for resolving DOM hierarchy and plugin ordering.
5640 */
5641injection.injectEventPluginOrder(DOMEventPluginOrder);
5642setComponentTree(getFiberCurrentPropsFromNode$1, getInstanceFromNode$1, getNodeFromInstance$1);
5643
5644/**
5645 * Some important event plugins included by default (without having to require
5646 * them).
5647 */
5648injection.injectEventPluginsByName({
5649 SimpleEventPlugin: SimpleEventPlugin,
5650 EnterLeaveEventPlugin: EnterLeaveEventPlugin,
5651 ChangeEventPlugin: ChangeEventPlugin,
5652 SelectEventPlugin: SelectEventPlugin,
5653 BeforeInputEventPlugin: BeforeInputEventPlugin
5654});
5655
5656var didWarnSelectedSetOnOption = false;
5657var didWarnInvalidChild = false;
5658
5659function flattenChildren(children) {
5660 var content = '';
5661
5662 // Flatten children. We'll warn if they are invalid
5663 // during validateProps() which runs for hydration too.
5664 // Note that this would throw on non-element objects.
5665 // Elements are stringified (which is normally irrelevant
5666 // but matters for <fbt>).
5667 React.Children.forEach(children, function (child) {
5668 if (child == null) {
5669 return;
5670 }
5671 content += child;
5672 // Note: we don't warn about invalid children here.
5673 // Instead, this is done separately below so that
5674 // it happens during the hydration codepath too.
5675 });
5676
5677 return content;
5678}
5679
5680/**
5681 * Implements an <option> host component that warns when `selected` is set.
5682 */
5683
5684function validateProps(element, props) {
5685 {
5686 // This mirrors the codepath above, but runs for hydration too.
5687 // Warn about invalid children here so that client and hydration are consistent.
5688 // TODO: this seems like it could cause a DEV-only throw for hydration
5689 // if children contains a non-element object. We should try to avoid that.
5690 if (typeof props.children === 'object' && props.children !== null) {
5691 React.Children.forEach(props.children, function (child) {
5692 if (child == null) {
5693 return;
5694 }
5695 if (typeof child === 'string' || typeof child === 'number') {
5696 return;
5697 }
5698 if (typeof child.type !== 'string') {
5699 return;
5700 }
5701 if (!didWarnInvalidChild) {
5702 didWarnInvalidChild = true;
5703 warning$1(false, 'Only strings and numbers are supported as <option> children.');
5704 }
5705 });
5706 }
5707
5708 // TODO: Remove support for `selected` in <option>.
5709 if (props.selected != null && !didWarnSelectedSetOnOption) {
5710 warning$1(false, 'Use the `defaultValue` or `value` props on <select> instead of ' + 'setting `selected` on <option>.');
5711 didWarnSelectedSetOnOption = true;
5712 }
5713 }
5714}
5715
5716function postMountWrapper$1(element, props) {
5717 // value="" should make a value attribute (#6219)
5718 if (props.value != null) {
5719 element.setAttribute('value', toString(getToStringValue(props.value)));
5720 }
5721}
5722
5723function getHostProps$1(element, props) {
5724 var hostProps = _assign({ children: undefined }, props);
5725 var content = flattenChildren(props.children);
5726
5727 if (content) {
5728 hostProps.children = content;
5729 }
5730
5731 return hostProps;
5732}
5733
5734// TODO: direct imports like some-package/src/* are bad. Fix me.
5735var didWarnValueDefaultValue$1 = void 0;
5736
5737{
5738 didWarnValueDefaultValue$1 = false;
5739}
5740
5741function getDeclarationErrorAddendum() {
5742 var ownerName = getCurrentFiberOwnerNameInDevOrNull();
5743 if (ownerName) {
5744 return '\n\nCheck the render method of `' + ownerName + '`.';
5745 }
5746 return '';
5747}
5748
5749var valuePropNames = ['value', 'defaultValue'];
5750
5751/**
5752 * Validation function for `value` and `defaultValue`.
5753 */
5754function checkSelectPropTypes(props) {
5755 ReactControlledValuePropTypes.checkPropTypes('select', props);
5756
5757 for (var i = 0; i < valuePropNames.length; i++) {
5758 var propName = valuePropNames[i];
5759 if (props[propName] == null) {
5760 continue;
5761 }
5762 var isArray = Array.isArray(props[propName]);
5763 if (props.multiple && !isArray) {
5764 warning$1(false, 'The `%s` prop supplied to <select> must be an array if ' + '`multiple` is true.%s', propName, getDeclarationErrorAddendum());
5765 } else if (!props.multiple && isArray) {
5766 warning$1(false, 'The `%s` prop supplied to <select> must be a scalar ' + 'value if `multiple` is false.%s', propName, getDeclarationErrorAddendum());
5767 }
5768 }
5769}
5770
5771function updateOptions(node, multiple, propValue, setDefaultSelected) {
5772 var options = node.options;
5773
5774 if (multiple) {
5775 var selectedValues = propValue;
5776 var selectedValue = {};
5777 for (var i = 0; i < selectedValues.length; i++) {
5778 // Prefix to avoid chaos with special keys.
5779 selectedValue['$' + selectedValues[i]] = true;
5780 }
5781 for (var _i = 0; _i < options.length; _i++) {
5782 var selected = selectedValue.hasOwnProperty('$' + options[_i].value);
5783 if (options[_i].selected !== selected) {
5784 options[_i].selected = selected;
5785 }
5786 if (selected && setDefaultSelected) {
5787 options[_i].defaultSelected = true;
5788 }
5789 }
5790 } else {
5791 // Do not set `select.value` as exact behavior isn't consistent across all
5792 // browsers for all cases.
5793 var _selectedValue = toString(getToStringValue(propValue));
5794 var defaultSelected = null;
5795 for (var _i2 = 0; _i2 < options.length; _i2++) {
5796 if (options[_i2].value === _selectedValue) {
5797 options[_i2].selected = true;
5798 if (setDefaultSelected) {
5799 options[_i2].defaultSelected = true;
5800 }
5801 return;
5802 }
5803 if (defaultSelected === null && !options[_i2].disabled) {
5804 defaultSelected = options[_i2];
5805 }
5806 }
5807 if (defaultSelected !== null) {
5808 defaultSelected.selected = true;
5809 }
5810 }
5811}
5812
5813/**
5814 * Implements a <select> host component that allows optionally setting the
5815 * props `value` and `defaultValue`. If `multiple` is false, the prop must be a
5816 * stringable. If `multiple` is true, the prop must be an array of stringables.
5817 *
5818 * If `value` is not supplied (or null/undefined), user actions that change the
5819 * selected option will trigger updates to the rendered options.
5820 *
5821 * If it is supplied (and not null/undefined), the rendered options will not
5822 * update in response to user actions. Instead, the `value` prop must change in
5823 * order for the rendered options to update.
5824 *
5825 * If `defaultValue` is provided, any options with the supplied values will be
5826 * selected.
5827 */
5828
5829function getHostProps$2(element, props) {
5830 return _assign({}, props, {
5831 value: undefined
5832 });
5833}
5834
5835function initWrapperState$1(element, props) {
5836 var node = element;
5837 {
5838 checkSelectPropTypes(props);
5839 }
5840
5841 node._wrapperState = {
5842 wasMultiple: !!props.multiple
5843 };
5844
5845 {
5846 if (props.value !== undefined && props.defaultValue !== undefined && !didWarnValueDefaultValue$1) {
5847 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');
5848 didWarnValueDefaultValue$1 = true;
5849 }
5850 }
5851}
5852
5853function postMountWrapper$2(element, props) {
5854 var node = element;
5855 node.multiple = !!props.multiple;
5856 var value = props.value;
5857 if (value != null) {
5858 updateOptions(node, !!props.multiple, value, false);
5859 } else if (props.defaultValue != null) {
5860 updateOptions(node, !!props.multiple, props.defaultValue, true);
5861 }
5862}
5863
5864function postUpdateWrapper(element, props) {
5865 var node = element;
5866 var wasMultiple = node._wrapperState.wasMultiple;
5867 node._wrapperState.wasMultiple = !!props.multiple;
5868
5869 var value = props.value;
5870 if (value != null) {
5871 updateOptions(node, !!props.multiple, value, false);
5872 } else if (wasMultiple !== !!props.multiple) {
5873 // For simplicity, reapply `defaultValue` if `multiple` is toggled.
5874 if (props.defaultValue != null) {
5875 updateOptions(node, !!props.multiple, props.defaultValue, true);
5876 } else {
5877 // Revert the select back to its default unselected state.
5878 updateOptions(node, !!props.multiple, props.multiple ? [] : '', false);
5879 }
5880 }
5881}
5882
5883function restoreControlledState$2(element, props) {
5884 var node = element;
5885 var value = props.value;
5886
5887 if (value != null) {
5888 updateOptions(node, !!props.multiple, value, false);
5889 }
5890}
5891
5892var didWarnValDefaultVal = false;
5893
5894/**
5895 * Implements a <textarea> host component that allows setting `value`, and
5896 * `defaultValue`. This differs from the traditional DOM API because value is
5897 * usually set as PCDATA children.
5898 *
5899 * If `value` is not supplied (or null/undefined), user actions that affect the
5900 * value will trigger updates to the element.
5901 *
5902 * If `value` is supplied (and not null/undefined), the rendered element will
5903 * not trigger updates to the element. Instead, the `value` prop must change in
5904 * order for the rendered element to be updated.
5905 *
5906 * The rendered element will be initialized with an empty value, the prop
5907 * `defaultValue` if specified, or the children content (deprecated).
5908 */
5909
5910function getHostProps$3(element, props) {
5911 var node = element;
5912 !(props.dangerouslySetInnerHTML == null) ? invariant(false, '`dangerouslySetInnerHTML` does not make sense on <textarea>.') : void 0;
5913
5914 // Always set children to the same thing. In IE9, the selection range will
5915 // get reset if `textContent` is mutated. We could add a check in setTextContent
5916 // to only set the value if/when the value differs from the node value (which would
5917 // completely solve this IE9 bug), but Sebastian+Sophie seemed to like this
5918 // solution. The value can be a boolean or object so that's why it's forced
5919 // to be a string.
5920 var hostProps = _assign({}, props, {
5921 value: undefined,
5922 defaultValue: undefined,
5923 children: toString(node._wrapperState.initialValue)
5924 });
5925
5926 return hostProps;
5927}
5928
5929function initWrapperState$2(element, props) {
5930 var node = element;
5931 {
5932 ReactControlledValuePropTypes.checkPropTypes('textarea', props);
5933 if (props.value !== undefined && props.defaultValue !== undefined && !didWarnValDefaultVal) {
5934 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');
5935 didWarnValDefaultVal = true;
5936 }
5937 }
5938
5939 var initialValue = props.value;
5940
5941 // Only bother fetching default value if we're going to use it
5942 if (initialValue == null) {
5943 var defaultValue = props.defaultValue;
5944 // TODO (yungsters): Remove support for children content in <textarea>.
5945 var children = props.children;
5946 if (children != null) {
5947 {
5948 warning$1(false, 'Use the `defaultValue` or `value` props instead of setting ' + 'children on <textarea>.');
5949 }
5950 !(defaultValue == null) ? invariant(false, 'If you supply `defaultValue` on a <textarea>, do not pass children.') : void 0;
5951 if (Array.isArray(children)) {
5952 !(children.length <= 1) ? invariant(false, '<textarea> can only have at most one child.') : void 0;
5953 children = children[0];
5954 }
5955
5956 defaultValue = children;
5957 }
5958 if (defaultValue == null) {
5959 defaultValue = '';
5960 }
5961 initialValue = defaultValue;
5962 }
5963
5964 node._wrapperState = {
5965 initialValue: getToStringValue(initialValue)
5966 };
5967}
5968
5969function updateWrapper$1(element, props) {
5970 var node = element;
5971 var value = getToStringValue(props.value);
5972 var defaultValue = getToStringValue(props.defaultValue);
5973 if (value != null) {
5974 // Cast `value` to a string to ensure the value is set correctly. While
5975 // browsers typically do this as necessary, jsdom doesn't.
5976 var newValue = toString(value);
5977 // To avoid side effects (such as losing text selection), only set value if changed
5978 if (newValue !== node.value) {
5979 node.value = newValue;
5980 }
5981 if (props.defaultValue == null && node.defaultValue !== newValue) {
5982 node.defaultValue = newValue;
5983 }
5984 }
5985 if (defaultValue != null) {
5986 node.defaultValue = toString(defaultValue);
5987 }
5988}
5989
5990function postMountWrapper$3(element, props) {
5991 var node = element;
5992 // This is in postMount because we need access to the DOM node, which is not
5993 // available until after the component has mounted.
5994 var textContent = node.textContent;
5995
5996 // Only set node.value if textContent is equal to the expected
5997 // initial value. In IE10/IE11 there is a bug where the placeholder attribute
5998 // will populate textContent as well.
5999 // https://developer.microsoft.com/microsoft-edge/platform/issues/101525/
6000 if (textContent === node._wrapperState.initialValue) {
6001 node.value = textContent;
6002 }
6003}
6004
6005function restoreControlledState$3(element, props) {
6006 // DOM component is still mounted; update
6007 updateWrapper$1(element, props);
6008}
6009
6010var HTML_NAMESPACE$1 = 'http://www.w3.org/1999/xhtml';
6011var MATH_NAMESPACE = 'http://www.w3.org/1998/Math/MathML';
6012var SVG_NAMESPACE = 'http://www.w3.org/2000/svg';
6013
6014var Namespaces = {
6015 html: HTML_NAMESPACE$1,
6016 mathml: MATH_NAMESPACE,
6017 svg: SVG_NAMESPACE
6018};
6019
6020// Assumes there is no parent namespace.
6021function getIntrinsicNamespace(type) {
6022 switch (type) {
6023 case 'svg':
6024 return SVG_NAMESPACE;
6025 case 'math':
6026 return MATH_NAMESPACE;
6027 default:
6028 return HTML_NAMESPACE$1;
6029 }
6030}
6031
6032function getChildNamespace(parentNamespace, type) {
6033 if (parentNamespace == null || parentNamespace === HTML_NAMESPACE$1) {
6034 // No (or default) parent namespace: potential entry point.
6035 return getIntrinsicNamespace(type);
6036 }
6037 if (parentNamespace === SVG_NAMESPACE && type === 'foreignObject') {
6038 // We're leaving SVG.
6039 return HTML_NAMESPACE$1;
6040 }
6041 // By default, pass namespace below.
6042 return parentNamespace;
6043}
6044
6045/* globals MSApp */
6046
6047/**
6048 * Create a function which has 'unsafe' privileges (required by windows8 apps)
6049 */
6050var createMicrosoftUnsafeLocalFunction = function (func) {
6051 if (typeof MSApp !== 'undefined' && MSApp.execUnsafeLocalFunction) {
6052 return function (arg0, arg1, arg2, arg3) {
6053 MSApp.execUnsafeLocalFunction(function () {
6054 return func(arg0, arg1, arg2, arg3);
6055 });
6056 };
6057 } else {
6058 return func;
6059 }
6060};
6061
6062// SVG temp container for IE lacking innerHTML
6063var reusableSVGContainer = void 0;
6064
6065/**
6066 * Set the innerHTML property of a node
6067 *
6068 * @param {DOMElement} node
6069 * @param {string} html
6070 * @internal
6071 */
6072var setInnerHTML = createMicrosoftUnsafeLocalFunction(function (node, html) {
6073 // IE does not have innerHTML for SVG nodes, so instead we inject the
6074 // new markup in a temp node and then move the child nodes across into
6075 // the target node
6076
6077 if (node.namespaceURI === Namespaces.svg && !('innerHTML' in node)) {
6078 reusableSVGContainer = reusableSVGContainer || document.createElement('div');
6079 reusableSVGContainer.innerHTML = '<svg>' + html + '</svg>';
6080 var svgNode = reusableSVGContainer.firstChild;
6081 while (node.firstChild) {
6082 node.removeChild(node.firstChild);
6083 }
6084 while (svgNode.firstChild) {
6085 node.appendChild(svgNode.firstChild);
6086 }
6087 } else {
6088 node.innerHTML = html;
6089 }
6090});
6091
6092/**
6093 * Set the textContent property of a node. For text updates, it's faster
6094 * to set the `nodeValue` of the Text node directly instead of using
6095 * `.textContent` which will remove the existing node and create a new one.
6096 *
6097 * @param {DOMElement} node
6098 * @param {string} text
6099 * @internal
6100 */
6101var setTextContent = function (node, text) {
6102 if (text) {
6103 var firstChild = node.firstChild;
6104
6105 if (firstChild && firstChild === node.lastChild && firstChild.nodeType === TEXT_NODE) {
6106 firstChild.nodeValue = text;
6107 return;
6108 }
6109 }
6110 node.textContent = text;
6111};
6112
6113// List derived from Gecko source code:
6114// https://github.com/mozilla/gecko-dev/blob/4e638efc71/layout/style/test/property_database.js
6115var shorthandToLonghand = {
6116 animation: ['animationDelay', 'animationDirection', 'animationDuration', 'animationFillMode', 'animationIterationCount', 'animationName', 'animationPlayState', 'animationTimingFunction'],
6117 background: ['backgroundAttachment', 'backgroundClip', 'backgroundColor', 'backgroundImage', 'backgroundOrigin', 'backgroundPositionX', 'backgroundPositionY', 'backgroundRepeat', 'backgroundSize'],
6118 backgroundPosition: ['backgroundPositionX', 'backgroundPositionY'],
6119 border: ['borderBottomColor', 'borderBottomStyle', 'borderBottomWidth', 'borderImageOutset', 'borderImageRepeat', 'borderImageSlice', 'borderImageSource', 'borderImageWidth', 'borderLeftColor', 'borderLeftStyle', 'borderLeftWidth', 'borderRightColor', 'borderRightStyle', 'borderRightWidth', 'borderTopColor', 'borderTopStyle', 'borderTopWidth'],
6120 borderBlockEnd: ['borderBlockEndColor', 'borderBlockEndStyle', 'borderBlockEndWidth'],
6121 borderBlockStart: ['borderBlockStartColor', 'borderBlockStartStyle', 'borderBlockStartWidth'],
6122 borderBottom: ['borderBottomColor', 'borderBottomStyle', 'borderBottomWidth'],
6123 borderColor: ['borderBottomColor', 'borderLeftColor', 'borderRightColor', 'borderTopColor'],
6124 borderImage: ['borderImageOutset', 'borderImageRepeat', 'borderImageSlice', 'borderImageSource', 'borderImageWidth'],
6125 borderInlineEnd: ['borderInlineEndColor', 'borderInlineEndStyle', 'borderInlineEndWidth'],
6126 borderInlineStart: ['borderInlineStartColor', 'borderInlineStartStyle', 'borderInlineStartWidth'],
6127 borderLeft: ['borderLeftColor', 'borderLeftStyle', 'borderLeftWidth'],
6128 borderRadius: ['borderBottomLeftRadius', 'borderBottomRightRadius', 'borderTopLeftRadius', 'borderTopRightRadius'],
6129 borderRight: ['borderRightColor', 'borderRightStyle', 'borderRightWidth'],
6130 borderStyle: ['borderBottomStyle', 'borderLeftStyle', 'borderRightStyle', 'borderTopStyle'],
6131 borderTop: ['borderTopColor', 'borderTopStyle', 'borderTopWidth'],
6132 borderWidth: ['borderBottomWidth', 'borderLeftWidth', 'borderRightWidth', 'borderTopWidth'],
6133 columnRule: ['columnRuleColor', 'columnRuleStyle', 'columnRuleWidth'],
6134 columns: ['columnCount', 'columnWidth'],
6135 flex: ['flexBasis', 'flexGrow', 'flexShrink'],
6136 flexFlow: ['flexDirection', 'flexWrap'],
6137 font: ['fontFamily', 'fontFeatureSettings', 'fontKerning', 'fontLanguageOverride', 'fontSize', 'fontSizeAdjust', 'fontStretch', 'fontStyle', 'fontVariant', 'fontVariantAlternates', 'fontVariantCaps', 'fontVariantEastAsian', 'fontVariantLigatures', 'fontVariantNumeric', 'fontVariantPosition', 'fontWeight', 'lineHeight'],
6138 fontVariant: ['fontVariantAlternates', 'fontVariantCaps', 'fontVariantEastAsian', 'fontVariantLigatures', 'fontVariantNumeric', 'fontVariantPosition'],
6139 gap: ['columnGap', 'rowGap'],
6140 grid: ['gridAutoColumns', 'gridAutoFlow', 'gridAutoRows', 'gridTemplateAreas', 'gridTemplateColumns', 'gridTemplateRows'],
6141 gridArea: ['gridColumnEnd', 'gridColumnStart', 'gridRowEnd', 'gridRowStart'],
6142 gridColumn: ['gridColumnEnd', 'gridColumnStart'],
6143 gridColumnGap: ['columnGap'],
6144 gridGap: ['columnGap', 'rowGap'],
6145 gridRow: ['gridRowEnd', 'gridRowStart'],
6146 gridRowGap: ['rowGap'],
6147 gridTemplate: ['gridTemplateAreas', 'gridTemplateColumns', 'gridTemplateRows'],
6148 listStyle: ['listStyleImage', 'listStylePosition', 'listStyleType'],
6149 margin: ['marginBottom', 'marginLeft', 'marginRight', 'marginTop'],
6150 marker: ['markerEnd', 'markerMid', 'markerStart'],
6151 mask: ['maskClip', 'maskComposite', 'maskImage', 'maskMode', 'maskOrigin', 'maskPositionX', 'maskPositionY', 'maskRepeat', 'maskSize'],
6152 maskPosition: ['maskPositionX', 'maskPositionY'],
6153 outline: ['outlineColor', 'outlineStyle', 'outlineWidth'],
6154 overflow: ['overflowX', 'overflowY'],
6155 padding: ['paddingBottom', 'paddingLeft', 'paddingRight', 'paddingTop'],
6156 placeContent: ['alignContent', 'justifyContent'],
6157 placeItems: ['alignItems', 'justifyItems'],
6158 placeSelf: ['alignSelf', 'justifySelf'],
6159 textDecoration: ['textDecorationColor', 'textDecorationLine', 'textDecorationStyle'],
6160 textEmphasis: ['textEmphasisColor', 'textEmphasisStyle'],
6161 transition: ['transitionDelay', 'transitionDuration', 'transitionProperty', 'transitionTimingFunction'],
6162 wordWrap: ['overflowWrap']
6163};
6164
6165/**
6166 * CSS properties which accept numbers but are not in units of "px".
6167 */
6168var isUnitlessNumber = {
6169 animationIterationCount: true,
6170 borderImageOutset: true,
6171 borderImageSlice: true,
6172 borderImageWidth: true,
6173 boxFlex: true,
6174 boxFlexGroup: true,
6175 boxOrdinalGroup: true,
6176 columnCount: true,
6177 columns: true,
6178 flex: true,
6179 flexGrow: true,
6180 flexPositive: true,
6181 flexShrink: true,
6182 flexNegative: true,
6183 flexOrder: true,
6184 gridArea: true,
6185 gridRow: true,
6186 gridRowEnd: true,
6187 gridRowSpan: true,
6188 gridRowStart: true,
6189 gridColumn: true,
6190 gridColumnEnd: true,
6191 gridColumnSpan: true,
6192 gridColumnStart: true,
6193 fontWeight: true,
6194 lineClamp: true,
6195 lineHeight: true,
6196 opacity: true,
6197 order: true,
6198 orphans: true,
6199 tabSize: true,
6200 widows: true,
6201 zIndex: true,
6202 zoom: true,
6203
6204 // SVG-related properties
6205 fillOpacity: true,
6206 floodOpacity: true,
6207 stopOpacity: true,
6208 strokeDasharray: true,
6209 strokeDashoffset: true,
6210 strokeMiterlimit: true,
6211 strokeOpacity: true,
6212 strokeWidth: true
6213};
6214
6215/**
6216 * @param {string} prefix vendor-specific prefix, eg: Webkit
6217 * @param {string} key style name, eg: transitionDuration
6218 * @return {string} style name prefixed with `prefix`, properly camelCased, eg:
6219 * WebkitTransitionDuration
6220 */
6221function prefixKey(prefix, key) {
6222 return prefix + key.charAt(0).toUpperCase() + key.substring(1);
6223}
6224
6225/**
6226 * Support style names that may come passed in prefixed by adding permutations
6227 * of vendor prefixes.
6228 */
6229var prefixes = ['Webkit', 'ms', 'Moz', 'O'];
6230
6231// Using Object.keys here, or else the vanilla for-in loop makes IE8 go into an
6232// infinite loop, because it iterates over the newly added props too.
6233Object.keys(isUnitlessNumber).forEach(function (prop) {
6234 prefixes.forEach(function (prefix) {
6235 isUnitlessNumber[prefixKey(prefix, prop)] = isUnitlessNumber[prop];
6236 });
6237});
6238
6239/**
6240 * Convert a value into the proper css writable value. The style name `name`
6241 * should be logical (no hyphens), as specified
6242 * in `CSSProperty.isUnitlessNumber`.
6243 *
6244 * @param {string} name CSS property name such as `topMargin`.
6245 * @param {*} value CSS property value such as `10px`.
6246 * @return {string} Normalized style value with dimensions applied.
6247 */
6248function dangerousStyleValue(name, value, isCustomProperty) {
6249 // Note that we've removed escapeTextForBrowser() calls here since the
6250 // whole string will be escaped when the attribute is injected into
6251 // the markup. If you provide unsafe user data here they can inject
6252 // arbitrary CSS which may be problematic (I couldn't repro this):
6253 // https://www.owasp.org/index.php/XSS_Filter_Evasion_Cheat_Sheet
6254 // http://www.thespanner.co.uk/2007/11/26/ultimate-xss-css-injection/
6255 // This is not an XSS hole but instead a potential CSS injection issue
6256 // which has lead to a greater discussion about how we're going to
6257 // trust URLs moving forward. See #2115901
6258
6259 var isEmpty = value == null || typeof value === 'boolean' || value === '';
6260 if (isEmpty) {
6261 return '';
6262 }
6263
6264 if (!isCustomProperty && typeof value === 'number' && value !== 0 && !(isUnitlessNumber.hasOwnProperty(name) && isUnitlessNumber[name])) {
6265 return value + 'px'; // Presumes implicit 'px' suffix for unitless numbers
6266 }
6267
6268 return ('' + value).trim();
6269}
6270
6271var uppercasePattern = /([A-Z])/g;
6272var msPattern = /^ms-/;
6273
6274/**
6275 * Hyphenates a camelcased CSS property name, for example:
6276 *
6277 * > hyphenateStyleName('backgroundColor')
6278 * < "background-color"
6279 * > hyphenateStyleName('MozTransition')
6280 * < "-moz-transition"
6281 * > hyphenateStyleName('msTransition')
6282 * < "-ms-transition"
6283 *
6284 * As Modernizr suggests (http://modernizr.com/docs/#prefixed), an `ms` prefix
6285 * is converted to `-ms-`.
6286 */
6287function hyphenateStyleName(name) {
6288 return name.replace(uppercasePattern, '-$1').toLowerCase().replace(msPattern, '-ms-');
6289}
6290
6291var warnValidStyle = function () {};
6292
6293{
6294 // 'msTransform' is correct, but the other prefixes should be capitalized
6295 var badVendoredStyleNamePattern = /^(?:webkit|moz|o)[A-Z]/;
6296 var msPattern$1 = /^-ms-/;
6297 var hyphenPattern = /-(.)/g;
6298
6299 // style values shouldn't contain a semicolon
6300 var badStyleValueWithSemicolonPattern = /;\s*$/;
6301
6302 var warnedStyleNames = {};
6303 var warnedStyleValues = {};
6304 var warnedForNaNValue = false;
6305 var warnedForInfinityValue = false;
6306
6307 var camelize = function (string) {
6308 return string.replace(hyphenPattern, function (_, character) {
6309 return character.toUpperCase();
6310 });
6311 };
6312
6313 var warnHyphenatedStyleName = function (name) {
6314 if (warnedStyleNames.hasOwnProperty(name) && warnedStyleNames[name]) {
6315 return;
6316 }
6317
6318 warnedStyleNames[name] = true;
6319 warning$1(false, 'Unsupported style property %s. Did you mean %s?', name,
6320 // As Andi Smith suggests
6321 // (http://www.andismith.com/blog/2012/02/modernizr-prefixed/), an `-ms` prefix
6322 // is converted to lowercase `ms`.
6323 camelize(name.replace(msPattern$1, 'ms-')));
6324 };
6325
6326 var warnBadVendoredStyleName = function (name) {
6327 if (warnedStyleNames.hasOwnProperty(name) && warnedStyleNames[name]) {
6328 return;
6329 }
6330
6331 warnedStyleNames[name] = true;
6332 warning$1(false, 'Unsupported vendor-prefixed style property %s. Did you mean %s?', name, name.charAt(0).toUpperCase() + name.slice(1));
6333 };
6334
6335 var warnStyleValueWithSemicolon = function (name, value) {
6336 if (warnedStyleValues.hasOwnProperty(value) && warnedStyleValues[value]) {
6337 return;
6338 }
6339
6340 warnedStyleValues[value] = true;
6341 warning$1(false, "Style property values shouldn't contain a semicolon. " + 'Try "%s: %s" instead.', name, value.replace(badStyleValueWithSemicolonPattern, ''));
6342 };
6343
6344 var warnStyleValueIsNaN = function (name, value) {
6345 if (warnedForNaNValue) {
6346 return;
6347 }
6348
6349 warnedForNaNValue = true;
6350 warning$1(false, '`NaN` is an invalid value for the `%s` css style property.', name);
6351 };
6352
6353 var warnStyleValueIsInfinity = function (name, value) {
6354 if (warnedForInfinityValue) {
6355 return;
6356 }
6357
6358 warnedForInfinityValue = true;
6359 warning$1(false, '`Infinity` is an invalid value for the `%s` css style property.', name);
6360 };
6361
6362 warnValidStyle = function (name, value) {
6363 if (name.indexOf('-') > -1) {
6364 warnHyphenatedStyleName(name);
6365 } else if (badVendoredStyleNamePattern.test(name)) {
6366 warnBadVendoredStyleName(name);
6367 } else if (badStyleValueWithSemicolonPattern.test(value)) {
6368 warnStyleValueWithSemicolon(name, value);
6369 }
6370
6371 if (typeof value === 'number') {
6372 if (isNaN(value)) {
6373 warnStyleValueIsNaN(name, value);
6374 } else if (!isFinite(value)) {
6375 warnStyleValueIsInfinity(name, value);
6376 }
6377 }
6378 };
6379}
6380
6381var warnValidStyle$1 = warnValidStyle;
6382
6383/**
6384 * Operations for dealing with CSS properties.
6385 */
6386
6387/**
6388 * This creates a string that is expected to be equivalent to the style
6389 * attribute generated by server-side rendering. It by-passes warnings and
6390 * security checks so it's not safe to use this value for anything other than
6391 * comparison. It is only used in DEV for SSR validation.
6392 */
6393function createDangerousStringForStyles(styles) {
6394 {
6395 var serialized = '';
6396 var delimiter = '';
6397 for (var styleName in styles) {
6398 if (!styles.hasOwnProperty(styleName)) {
6399 continue;
6400 }
6401 var styleValue = styles[styleName];
6402 if (styleValue != null) {
6403 var isCustomProperty = styleName.indexOf('--') === 0;
6404 serialized += delimiter + hyphenateStyleName(styleName) + ':';
6405 serialized += dangerousStyleValue(styleName, styleValue, isCustomProperty);
6406
6407 delimiter = ';';
6408 }
6409 }
6410 return serialized || null;
6411 }
6412}
6413
6414/**
6415 * Sets the value for multiple styles on a node. If a value is specified as
6416 * '' (empty string), the corresponding style property will be unset.
6417 *
6418 * @param {DOMElement} node
6419 * @param {object} styles
6420 */
6421function setValueForStyles(node, styles) {
6422 var style = node.style;
6423 for (var styleName in styles) {
6424 if (!styles.hasOwnProperty(styleName)) {
6425 continue;
6426 }
6427 var isCustomProperty = styleName.indexOf('--') === 0;
6428 {
6429 if (!isCustomProperty) {
6430 warnValidStyle$1(styleName, styles[styleName]);
6431 }
6432 }
6433 var styleValue = dangerousStyleValue(styleName, styles[styleName], isCustomProperty);
6434 if (styleName === 'float') {
6435 styleName = 'cssFloat';
6436 }
6437 if (isCustomProperty) {
6438 style.setProperty(styleName, styleValue);
6439 } else {
6440 style[styleName] = styleValue;
6441 }
6442 }
6443}
6444
6445function isValueEmpty(value) {
6446 return value == null || typeof value === 'boolean' || value === '';
6447}
6448
6449/**
6450 * Given {color: 'red', overflow: 'hidden'} returns {
6451 * color: 'color',
6452 * overflowX: 'overflow',
6453 * overflowY: 'overflow',
6454 * }. This can be read as "the overflowY property was set by the overflow
6455 * shorthand". That is, the values are the property that each was derived from.
6456 */
6457function expandShorthandMap(styles) {
6458 var expanded = {};
6459 for (var key in styles) {
6460 var longhands = shorthandToLonghand[key] || [key];
6461 for (var i = 0; i < longhands.length; i++) {
6462 expanded[longhands[i]] = key;
6463 }
6464 }
6465 return expanded;
6466}
6467
6468/**
6469 * When mixing shorthand and longhand property names, we warn during updates if
6470 * we expect an incorrect result to occur. In particular, we warn for:
6471 *
6472 * Updating a shorthand property (longhand gets overwritten):
6473 * {font: 'foo', fontVariant: 'bar'} -> {font: 'baz', fontVariant: 'bar'}
6474 * becomes .style.font = 'baz'
6475 * Removing a shorthand property (longhand gets lost too):
6476 * {font: 'foo', fontVariant: 'bar'} -> {fontVariant: 'bar'}
6477 * becomes .style.font = ''
6478 * Removing a longhand property (should revert to shorthand; doesn't):
6479 * {font: 'foo', fontVariant: 'bar'} -> {font: 'foo'}
6480 * becomes .style.fontVariant = ''
6481 */
6482function validateShorthandPropertyCollisionInDev(styleUpdates, nextStyles) {
6483 if (!warnAboutShorthandPropertyCollision) {
6484 return;
6485 }
6486
6487 if (!nextStyles) {
6488 return;
6489 }
6490
6491 var expandedUpdates = expandShorthandMap(styleUpdates);
6492 var expandedStyles = expandShorthandMap(nextStyles);
6493 var warnedAbout = {};
6494 for (var key in expandedUpdates) {
6495 var originalKey = expandedUpdates[key];
6496 var correctOriginalKey = expandedStyles[key];
6497 if (correctOriginalKey && originalKey !== correctOriginalKey) {
6498 var warningKey = originalKey + ',' + correctOriginalKey;
6499 if (warnedAbout[warningKey]) {
6500 continue;
6501 }
6502 warnedAbout[warningKey] = true;
6503 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);
6504 }
6505 }
6506}
6507
6508// For HTML, certain tags should omit their close tag. We keep a whitelist for
6509// those special-case tags.
6510
6511var omittedCloseTags = {
6512 area: true,
6513 base: true,
6514 br: true,
6515 col: true,
6516 embed: true,
6517 hr: true,
6518 img: true,
6519 input: true,
6520 keygen: true,
6521 link: true,
6522 meta: true,
6523 param: true,
6524 source: true,
6525 track: true,
6526 wbr: true
6527 // NOTE: menuitem's close tag should be omitted, but that causes problems.
6528};
6529
6530// For HTML, certain tags cannot have children. This has the same purpose as
6531// `omittedCloseTags` except that `menuitem` should still have its closing tag.
6532
6533var voidElementTags = _assign({
6534 menuitem: true
6535}, omittedCloseTags);
6536
6537// TODO: We can remove this if we add invariantWithStack()
6538// or add stack by default to invariants where possible.
6539var HTML$1 = '__html';
6540
6541var ReactDebugCurrentFrame$2 = null;
6542{
6543 ReactDebugCurrentFrame$2 = ReactSharedInternals.ReactDebugCurrentFrame;
6544}
6545
6546function assertValidProps(tag, props) {
6547 if (!props) {
6548 return;
6549 }
6550 // Note the use of `==` which checks for null or undefined.
6551 if (voidElementTags[tag]) {
6552 !(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;
6553 }
6554 if (props.dangerouslySetInnerHTML != null) {
6555 !(props.children == null) ? invariant(false, 'Can only set one of `children` or `props.dangerouslySetInnerHTML`.') : void 0;
6556 !(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;
6557 }
6558 {
6559 !(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;
6560 }
6561 !(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;
6562}
6563
6564function isCustomComponent(tagName, props) {
6565 if (tagName.indexOf('-') === -1) {
6566 return typeof props.is === 'string';
6567 }
6568 switch (tagName) {
6569 // These are reserved SVG and MathML elements.
6570 // We don't mind this whitelist too much because we expect it to never grow.
6571 // The alternative is to track the namespace in a few places which is convoluted.
6572 // https://w3c.github.io/webcomponents/spec/custom/#custom-elements-core-concepts
6573 case 'annotation-xml':
6574 case 'color-profile':
6575 case 'font-face':
6576 case 'font-face-src':
6577 case 'font-face-uri':
6578 case 'font-face-format':
6579 case 'font-face-name':
6580 case 'missing-glyph':
6581 return false;
6582 default:
6583 return true;
6584 }
6585}
6586
6587// When adding attributes to the HTML or SVG whitelist, be sure to
6588// also add them to this module to ensure casing and incorrect name
6589// warnings.
6590var possibleStandardNames = {
6591 // HTML
6592 accept: 'accept',
6593 acceptcharset: 'acceptCharset',
6594 'accept-charset': 'acceptCharset',
6595 accesskey: 'accessKey',
6596 action: 'action',
6597 allowfullscreen: 'allowFullScreen',
6598 alt: 'alt',
6599 as: 'as',
6600 async: 'async',
6601 autocapitalize: 'autoCapitalize',
6602 autocomplete: 'autoComplete',
6603 autocorrect: 'autoCorrect',
6604 autofocus: 'autoFocus',
6605 autoplay: 'autoPlay',
6606 autosave: 'autoSave',
6607 capture: 'capture',
6608 cellpadding: 'cellPadding',
6609 cellspacing: 'cellSpacing',
6610 challenge: 'challenge',
6611 charset: 'charSet',
6612 checked: 'checked',
6613 children: 'children',
6614 cite: 'cite',
6615 class: 'className',
6616 classid: 'classID',
6617 classname: 'className',
6618 cols: 'cols',
6619 colspan: 'colSpan',
6620 content: 'content',
6621 contenteditable: 'contentEditable',
6622 contextmenu: 'contextMenu',
6623 controls: 'controls',
6624 controlslist: 'controlsList',
6625 coords: 'coords',
6626 crossorigin: 'crossOrigin',
6627 dangerouslysetinnerhtml: 'dangerouslySetInnerHTML',
6628 data: 'data',
6629 datetime: 'dateTime',
6630 default: 'default',
6631 defaultchecked: 'defaultChecked',
6632 defaultvalue: 'defaultValue',
6633 defer: 'defer',
6634 dir: 'dir',
6635 disabled: 'disabled',
6636 download: 'download',
6637 draggable: 'draggable',
6638 enctype: 'encType',
6639 for: 'htmlFor',
6640 form: 'form',
6641 formmethod: 'formMethod',
6642 formaction: 'formAction',
6643 formenctype: 'formEncType',
6644 formnovalidate: 'formNoValidate',
6645 formtarget: 'formTarget',
6646 frameborder: 'frameBorder',
6647 headers: 'headers',
6648 height: 'height',
6649 hidden: 'hidden',
6650 high: 'high',
6651 href: 'href',
6652 hreflang: 'hrefLang',
6653 htmlfor: 'htmlFor',
6654 httpequiv: 'httpEquiv',
6655 'http-equiv': 'httpEquiv',
6656 icon: 'icon',
6657 id: 'id',
6658 innerhtml: 'innerHTML',
6659 inputmode: 'inputMode',
6660 integrity: 'integrity',
6661 is: 'is',
6662 itemid: 'itemID',
6663 itemprop: 'itemProp',
6664 itemref: 'itemRef',
6665 itemscope: 'itemScope',
6666 itemtype: 'itemType',
6667 keyparams: 'keyParams',
6668 keytype: 'keyType',
6669 kind: 'kind',
6670 label: 'label',
6671 lang: 'lang',
6672 list: 'list',
6673 loop: 'loop',
6674 low: 'low',
6675 manifest: 'manifest',
6676 marginwidth: 'marginWidth',
6677 marginheight: 'marginHeight',
6678 max: 'max',
6679 maxlength: 'maxLength',
6680 media: 'media',
6681 mediagroup: 'mediaGroup',
6682 method: 'method',
6683 min: 'min',
6684 minlength: 'minLength',
6685 multiple: 'multiple',
6686 muted: 'muted',
6687 name: 'name',
6688 nomodule: 'noModule',
6689 nonce: 'nonce',
6690 novalidate: 'noValidate',
6691 open: 'open',
6692 optimum: 'optimum',
6693 pattern: 'pattern',
6694 placeholder: 'placeholder',
6695 playsinline: 'playsInline',
6696 poster: 'poster',
6697 preload: 'preload',
6698 profile: 'profile',
6699 radiogroup: 'radioGroup',
6700 readonly: 'readOnly',
6701 referrerpolicy: 'referrerPolicy',
6702 rel: 'rel',
6703 required: 'required',
6704 reversed: 'reversed',
6705 role: 'role',
6706 rows: 'rows',
6707 rowspan: 'rowSpan',
6708 sandbox: 'sandbox',
6709 scope: 'scope',
6710 scoped: 'scoped',
6711 scrolling: 'scrolling',
6712 seamless: 'seamless',
6713 selected: 'selected',
6714 shape: 'shape',
6715 size: 'size',
6716 sizes: 'sizes',
6717 span: 'span',
6718 spellcheck: 'spellCheck',
6719 src: 'src',
6720 srcdoc: 'srcDoc',
6721 srclang: 'srcLang',
6722 srcset: 'srcSet',
6723 start: 'start',
6724 step: 'step',
6725 style: 'style',
6726 summary: 'summary',
6727 tabindex: 'tabIndex',
6728 target: 'target',
6729 title: 'title',
6730 type: 'type',
6731 usemap: 'useMap',
6732 value: 'value',
6733 width: 'width',
6734 wmode: 'wmode',
6735 wrap: 'wrap',
6736
6737 // SVG
6738 about: 'about',
6739 accentheight: 'accentHeight',
6740 'accent-height': 'accentHeight',
6741 accumulate: 'accumulate',
6742 additive: 'additive',
6743 alignmentbaseline: 'alignmentBaseline',
6744 'alignment-baseline': 'alignmentBaseline',
6745 allowreorder: 'allowReorder',
6746 alphabetic: 'alphabetic',
6747 amplitude: 'amplitude',
6748 arabicform: 'arabicForm',
6749 'arabic-form': 'arabicForm',
6750 ascent: 'ascent',
6751 attributename: 'attributeName',
6752 attributetype: 'attributeType',
6753 autoreverse: 'autoReverse',
6754 azimuth: 'azimuth',
6755 basefrequency: 'baseFrequency',
6756 baselineshift: 'baselineShift',
6757 'baseline-shift': 'baselineShift',
6758 baseprofile: 'baseProfile',
6759 bbox: 'bbox',
6760 begin: 'begin',
6761 bias: 'bias',
6762 by: 'by',
6763 calcmode: 'calcMode',
6764 capheight: 'capHeight',
6765 'cap-height': 'capHeight',
6766 clip: 'clip',
6767 clippath: 'clipPath',
6768 'clip-path': 'clipPath',
6769 clippathunits: 'clipPathUnits',
6770 cliprule: 'clipRule',
6771 'clip-rule': 'clipRule',
6772 color: 'color',
6773 colorinterpolation: 'colorInterpolation',
6774 'color-interpolation': 'colorInterpolation',
6775 colorinterpolationfilters: 'colorInterpolationFilters',
6776 'color-interpolation-filters': 'colorInterpolationFilters',
6777 colorprofile: 'colorProfile',
6778 'color-profile': 'colorProfile',
6779 colorrendering: 'colorRendering',
6780 'color-rendering': 'colorRendering',
6781 contentscripttype: 'contentScriptType',
6782 contentstyletype: 'contentStyleType',
6783 cursor: 'cursor',
6784 cx: 'cx',
6785 cy: 'cy',
6786 d: 'd',
6787 datatype: 'datatype',
6788 decelerate: 'decelerate',
6789 descent: 'descent',
6790 diffuseconstant: 'diffuseConstant',
6791 direction: 'direction',
6792 display: 'display',
6793 divisor: 'divisor',
6794 dominantbaseline: 'dominantBaseline',
6795 'dominant-baseline': 'dominantBaseline',
6796 dur: 'dur',
6797 dx: 'dx',
6798 dy: 'dy',
6799 edgemode: 'edgeMode',
6800 elevation: 'elevation',
6801 enablebackground: 'enableBackground',
6802 'enable-background': 'enableBackground',
6803 end: 'end',
6804 exponent: 'exponent',
6805 externalresourcesrequired: 'externalResourcesRequired',
6806 fill: 'fill',
6807 fillopacity: 'fillOpacity',
6808 'fill-opacity': 'fillOpacity',
6809 fillrule: 'fillRule',
6810 'fill-rule': 'fillRule',
6811 filter: 'filter',
6812 filterres: 'filterRes',
6813 filterunits: 'filterUnits',
6814 floodopacity: 'floodOpacity',
6815 'flood-opacity': 'floodOpacity',
6816 floodcolor: 'floodColor',
6817 'flood-color': 'floodColor',
6818 focusable: 'focusable',
6819 fontfamily: 'fontFamily',
6820 'font-family': 'fontFamily',
6821 fontsize: 'fontSize',
6822 'font-size': 'fontSize',
6823 fontsizeadjust: 'fontSizeAdjust',
6824 'font-size-adjust': 'fontSizeAdjust',
6825 fontstretch: 'fontStretch',
6826 'font-stretch': 'fontStretch',
6827 fontstyle: 'fontStyle',
6828 'font-style': 'fontStyle',
6829 fontvariant: 'fontVariant',
6830 'font-variant': 'fontVariant',
6831 fontweight: 'fontWeight',
6832 'font-weight': 'fontWeight',
6833 format: 'format',
6834 from: 'from',
6835 fx: 'fx',
6836 fy: 'fy',
6837 g1: 'g1',
6838 g2: 'g2',
6839 glyphname: 'glyphName',
6840 'glyph-name': 'glyphName',
6841 glyphorientationhorizontal: 'glyphOrientationHorizontal',
6842 'glyph-orientation-horizontal': 'glyphOrientationHorizontal',
6843 glyphorientationvertical: 'glyphOrientationVertical',
6844 'glyph-orientation-vertical': 'glyphOrientationVertical',
6845 glyphref: 'glyphRef',
6846 gradienttransform: 'gradientTransform',
6847 gradientunits: 'gradientUnits',
6848 hanging: 'hanging',
6849 horizadvx: 'horizAdvX',
6850 'horiz-adv-x': 'horizAdvX',
6851 horizoriginx: 'horizOriginX',
6852 'horiz-origin-x': 'horizOriginX',
6853 ideographic: 'ideographic',
6854 imagerendering: 'imageRendering',
6855 'image-rendering': 'imageRendering',
6856 in2: 'in2',
6857 in: 'in',
6858 inlist: 'inlist',
6859 intercept: 'intercept',
6860 k1: 'k1',
6861 k2: 'k2',
6862 k3: 'k3',
6863 k4: 'k4',
6864 k: 'k',
6865 kernelmatrix: 'kernelMatrix',
6866 kernelunitlength: 'kernelUnitLength',
6867 kerning: 'kerning',
6868 keypoints: 'keyPoints',
6869 keysplines: 'keySplines',
6870 keytimes: 'keyTimes',
6871 lengthadjust: 'lengthAdjust',
6872 letterspacing: 'letterSpacing',
6873 'letter-spacing': 'letterSpacing',
6874 lightingcolor: 'lightingColor',
6875 'lighting-color': 'lightingColor',
6876 limitingconeangle: 'limitingConeAngle',
6877 local: 'local',
6878 markerend: 'markerEnd',
6879 'marker-end': 'markerEnd',
6880 markerheight: 'markerHeight',
6881 markermid: 'markerMid',
6882 'marker-mid': 'markerMid',
6883 markerstart: 'markerStart',
6884 'marker-start': 'markerStart',
6885 markerunits: 'markerUnits',
6886 markerwidth: 'markerWidth',
6887 mask: 'mask',
6888 maskcontentunits: 'maskContentUnits',
6889 maskunits: 'maskUnits',
6890 mathematical: 'mathematical',
6891 mode: 'mode',
6892 numoctaves: 'numOctaves',
6893 offset: 'offset',
6894 opacity: 'opacity',
6895 operator: 'operator',
6896 order: 'order',
6897 orient: 'orient',
6898 orientation: 'orientation',
6899 origin: 'origin',
6900 overflow: 'overflow',
6901 overlineposition: 'overlinePosition',
6902 'overline-position': 'overlinePosition',
6903 overlinethickness: 'overlineThickness',
6904 'overline-thickness': 'overlineThickness',
6905 paintorder: 'paintOrder',
6906 'paint-order': 'paintOrder',
6907 panose1: 'panose1',
6908 'panose-1': 'panose1',
6909 pathlength: 'pathLength',
6910 patterncontentunits: 'patternContentUnits',
6911 patterntransform: 'patternTransform',
6912 patternunits: 'patternUnits',
6913 pointerevents: 'pointerEvents',
6914 'pointer-events': 'pointerEvents',
6915 points: 'points',
6916 pointsatx: 'pointsAtX',
6917 pointsaty: 'pointsAtY',
6918 pointsatz: 'pointsAtZ',
6919 prefix: 'prefix',
6920 preservealpha: 'preserveAlpha',
6921 preserveaspectratio: 'preserveAspectRatio',
6922 primitiveunits: 'primitiveUnits',
6923 property: 'property',
6924 r: 'r',
6925 radius: 'radius',
6926 refx: 'refX',
6927 refy: 'refY',
6928 renderingintent: 'renderingIntent',
6929 'rendering-intent': 'renderingIntent',
6930 repeatcount: 'repeatCount',
6931 repeatdur: 'repeatDur',
6932 requiredextensions: 'requiredExtensions',
6933 requiredfeatures: 'requiredFeatures',
6934 resource: 'resource',
6935 restart: 'restart',
6936 result: 'result',
6937 results: 'results',
6938 rotate: 'rotate',
6939 rx: 'rx',
6940 ry: 'ry',
6941 scale: 'scale',
6942 security: 'security',
6943 seed: 'seed',
6944 shaperendering: 'shapeRendering',
6945 'shape-rendering': 'shapeRendering',
6946 slope: 'slope',
6947 spacing: 'spacing',
6948 specularconstant: 'specularConstant',
6949 specularexponent: 'specularExponent',
6950 speed: 'speed',
6951 spreadmethod: 'spreadMethod',
6952 startoffset: 'startOffset',
6953 stddeviation: 'stdDeviation',
6954 stemh: 'stemh',
6955 stemv: 'stemv',
6956 stitchtiles: 'stitchTiles',
6957 stopcolor: 'stopColor',
6958 'stop-color': 'stopColor',
6959 stopopacity: 'stopOpacity',
6960 'stop-opacity': 'stopOpacity',
6961 strikethroughposition: 'strikethroughPosition',
6962 'strikethrough-position': 'strikethroughPosition',
6963 strikethroughthickness: 'strikethroughThickness',
6964 'strikethrough-thickness': 'strikethroughThickness',
6965 string: 'string',
6966 stroke: 'stroke',
6967 strokedasharray: 'strokeDasharray',
6968 'stroke-dasharray': 'strokeDasharray',
6969 strokedashoffset: 'strokeDashoffset',
6970 'stroke-dashoffset': 'strokeDashoffset',
6971 strokelinecap: 'strokeLinecap',
6972 'stroke-linecap': 'strokeLinecap',
6973 strokelinejoin: 'strokeLinejoin',
6974 'stroke-linejoin': 'strokeLinejoin',
6975 strokemiterlimit: 'strokeMiterlimit',
6976 'stroke-miterlimit': 'strokeMiterlimit',
6977 strokewidth: 'strokeWidth',
6978 'stroke-width': 'strokeWidth',
6979 strokeopacity: 'strokeOpacity',
6980 'stroke-opacity': 'strokeOpacity',
6981 suppresscontenteditablewarning: 'suppressContentEditableWarning',
6982 suppresshydrationwarning: 'suppressHydrationWarning',
6983 surfacescale: 'surfaceScale',
6984 systemlanguage: 'systemLanguage',
6985 tablevalues: 'tableValues',
6986 targetx: 'targetX',
6987 targety: 'targetY',
6988 textanchor: 'textAnchor',
6989 'text-anchor': 'textAnchor',
6990 textdecoration: 'textDecoration',
6991 'text-decoration': 'textDecoration',
6992 textlength: 'textLength',
6993 textrendering: 'textRendering',
6994 'text-rendering': 'textRendering',
6995 to: 'to',
6996 transform: 'transform',
6997 typeof: 'typeof',
6998 u1: 'u1',
6999 u2: 'u2',
7000 underlineposition: 'underlinePosition',
7001 'underline-position': 'underlinePosition',
7002 underlinethickness: 'underlineThickness',
7003 'underline-thickness': 'underlineThickness',
7004 unicode: 'unicode',
7005 unicodebidi: 'unicodeBidi',
7006 'unicode-bidi': 'unicodeBidi',
7007 unicoderange: 'unicodeRange',
7008 'unicode-range': 'unicodeRange',
7009 unitsperem: 'unitsPerEm',
7010 'units-per-em': 'unitsPerEm',
7011 unselectable: 'unselectable',
7012 valphabetic: 'vAlphabetic',
7013 'v-alphabetic': 'vAlphabetic',
7014 values: 'values',
7015 vectoreffect: 'vectorEffect',
7016 'vector-effect': 'vectorEffect',
7017 version: 'version',
7018 vertadvy: 'vertAdvY',
7019 'vert-adv-y': 'vertAdvY',
7020 vertoriginx: 'vertOriginX',
7021 'vert-origin-x': 'vertOriginX',
7022 vertoriginy: 'vertOriginY',
7023 'vert-origin-y': 'vertOriginY',
7024 vhanging: 'vHanging',
7025 'v-hanging': 'vHanging',
7026 videographic: 'vIdeographic',
7027 'v-ideographic': 'vIdeographic',
7028 viewbox: 'viewBox',
7029 viewtarget: 'viewTarget',
7030 visibility: 'visibility',
7031 vmathematical: 'vMathematical',
7032 'v-mathematical': 'vMathematical',
7033 vocab: 'vocab',
7034 widths: 'widths',
7035 wordspacing: 'wordSpacing',
7036 'word-spacing': 'wordSpacing',
7037 writingmode: 'writingMode',
7038 'writing-mode': 'writingMode',
7039 x1: 'x1',
7040 x2: 'x2',
7041 x: 'x',
7042 xchannelselector: 'xChannelSelector',
7043 xheight: 'xHeight',
7044 'x-height': 'xHeight',
7045 xlinkactuate: 'xlinkActuate',
7046 'xlink:actuate': 'xlinkActuate',
7047 xlinkarcrole: 'xlinkArcrole',
7048 'xlink:arcrole': 'xlinkArcrole',
7049 xlinkhref: 'xlinkHref',
7050 'xlink:href': 'xlinkHref',
7051 xlinkrole: 'xlinkRole',
7052 'xlink:role': 'xlinkRole',
7053 xlinkshow: 'xlinkShow',
7054 'xlink:show': 'xlinkShow',
7055 xlinktitle: 'xlinkTitle',
7056 'xlink:title': 'xlinkTitle',
7057 xlinktype: 'xlinkType',
7058 'xlink:type': 'xlinkType',
7059 xmlbase: 'xmlBase',
7060 'xml:base': 'xmlBase',
7061 xmllang: 'xmlLang',
7062 'xml:lang': 'xmlLang',
7063 xmlns: 'xmlns',
7064 'xml:space': 'xmlSpace',
7065 xmlnsxlink: 'xmlnsXlink',
7066 'xmlns:xlink': 'xmlnsXlink',
7067 xmlspace: 'xmlSpace',
7068 y1: 'y1',
7069 y2: 'y2',
7070 y: 'y',
7071 ychannelselector: 'yChannelSelector',
7072 z: 'z',
7073 zoomandpan: 'zoomAndPan'
7074};
7075
7076var ariaProperties = {
7077 'aria-current': 0, // state
7078 'aria-details': 0,
7079 'aria-disabled': 0, // state
7080 'aria-hidden': 0, // state
7081 'aria-invalid': 0, // state
7082 'aria-keyshortcuts': 0,
7083 'aria-label': 0,
7084 'aria-roledescription': 0,
7085 // Widget Attributes
7086 'aria-autocomplete': 0,
7087 'aria-checked': 0,
7088 'aria-expanded': 0,
7089 'aria-haspopup': 0,
7090 'aria-level': 0,
7091 'aria-modal': 0,
7092 'aria-multiline': 0,
7093 'aria-multiselectable': 0,
7094 'aria-orientation': 0,
7095 'aria-placeholder': 0,
7096 'aria-pressed': 0,
7097 'aria-readonly': 0,
7098 'aria-required': 0,
7099 'aria-selected': 0,
7100 'aria-sort': 0,
7101 'aria-valuemax': 0,
7102 'aria-valuemin': 0,
7103 'aria-valuenow': 0,
7104 'aria-valuetext': 0,
7105 // Live Region Attributes
7106 'aria-atomic': 0,
7107 'aria-busy': 0,
7108 'aria-live': 0,
7109 'aria-relevant': 0,
7110 // Drag-and-Drop Attributes
7111 'aria-dropeffect': 0,
7112 'aria-grabbed': 0,
7113 // Relationship Attributes
7114 'aria-activedescendant': 0,
7115 'aria-colcount': 0,
7116 'aria-colindex': 0,
7117 'aria-colspan': 0,
7118 'aria-controls': 0,
7119 'aria-describedby': 0,
7120 'aria-errormessage': 0,
7121 'aria-flowto': 0,
7122 'aria-labelledby': 0,
7123 'aria-owns': 0,
7124 'aria-posinset': 0,
7125 'aria-rowcount': 0,
7126 'aria-rowindex': 0,
7127 'aria-rowspan': 0,
7128 'aria-setsize': 0
7129};
7130
7131var warnedProperties = {};
7132var rARIA = new RegExp('^(aria)-[' + ATTRIBUTE_NAME_CHAR + ']*$');
7133var rARIACamel = new RegExp('^(aria)[A-Z][' + ATTRIBUTE_NAME_CHAR + ']*$');
7134
7135var hasOwnProperty$2 = Object.prototype.hasOwnProperty;
7136
7137function validateProperty(tagName, name) {
7138 if (hasOwnProperty$2.call(warnedProperties, name) && warnedProperties[name]) {
7139 return true;
7140 }
7141
7142 if (rARIACamel.test(name)) {
7143 var ariaName = 'aria-' + name.slice(4).toLowerCase();
7144 var correctName = ariaProperties.hasOwnProperty(ariaName) ? ariaName : null;
7145
7146 // If this is an aria-* attribute, but is not listed in the known DOM
7147 // DOM properties, then it is an invalid aria-* attribute.
7148 if (correctName == null) {
7149 warning$1(false, 'Invalid ARIA attribute `%s`. ARIA attributes follow the pattern aria-* and must be lowercase.', name);
7150 warnedProperties[name] = true;
7151 return true;
7152 }
7153 // aria-* attributes should be lowercase; suggest the lowercase version.
7154 if (name !== correctName) {
7155 warning$1(false, 'Invalid ARIA attribute `%s`. Did you mean `%s`?', name, correctName);
7156 warnedProperties[name] = true;
7157 return true;
7158 }
7159 }
7160
7161 if (rARIA.test(name)) {
7162 var lowerCasedName = name.toLowerCase();
7163 var standardName = ariaProperties.hasOwnProperty(lowerCasedName) ? lowerCasedName : null;
7164
7165 // If this is an aria-* attribute, but is not listed in the known DOM
7166 // DOM properties, then it is an invalid aria-* attribute.
7167 if (standardName == null) {
7168 warnedProperties[name] = true;
7169 return false;
7170 }
7171 // aria-* attributes should be lowercase; suggest the lowercase version.
7172 if (name !== standardName) {
7173 warning$1(false, 'Unknown ARIA attribute `%s`. Did you mean `%s`?', name, standardName);
7174 warnedProperties[name] = true;
7175 return true;
7176 }
7177 }
7178
7179 return true;
7180}
7181
7182function warnInvalidARIAProps(type, props) {
7183 var invalidProps = [];
7184
7185 for (var key in props) {
7186 var isValid = validateProperty(type, key);
7187 if (!isValid) {
7188 invalidProps.push(key);
7189 }
7190 }
7191
7192 var unknownPropString = invalidProps.map(function (prop) {
7193 return '`' + prop + '`';
7194 }).join(', ');
7195
7196 if (invalidProps.length === 1) {
7197 warning$1(false, 'Invalid aria prop %s on <%s> tag. ' + 'For details, see https://fb.me/invalid-aria-prop', unknownPropString, type);
7198 } else if (invalidProps.length > 1) {
7199 warning$1(false, 'Invalid aria props %s on <%s> tag. ' + 'For details, see https://fb.me/invalid-aria-prop', unknownPropString, type);
7200 }
7201}
7202
7203function validateProperties(type, props) {
7204 if (isCustomComponent(type, props)) {
7205 return;
7206 }
7207 warnInvalidARIAProps(type, props);
7208}
7209
7210var didWarnValueNull = false;
7211
7212function validateProperties$1(type, props) {
7213 if (type !== 'input' && type !== 'textarea' && type !== 'select') {
7214 return;
7215 }
7216
7217 if (props != null && props.value === null && !didWarnValueNull) {
7218 didWarnValueNull = true;
7219 if (type === 'select' && props.multiple) {
7220 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);
7221 } else {
7222 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);
7223 }
7224 }
7225}
7226
7227var validateProperty$1 = function () {};
7228
7229{
7230 var warnedProperties$1 = {};
7231 var _hasOwnProperty = Object.prototype.hasOwnProperty;
7232 var EVENT_NAME_REGEX = /^on./;
7233 var INVALID_EVENT_NAME_REGEX = /^on[^A-Z]/;
7234 var rARIA$1 = new RegExp('^(aria)-[' + ATTRIBUTE_NAME_CHAR + ']*$');
7235 var rARIACamel$1 = new RegExp('^(aria)[A-Z][' + ATTRIBUTE_NAME_CHAR + ']*$');
7236
7237 validateProperty$1 = function (tagName, name, value, canUseEventSystem) {
7238 if (_hasOwnProperty.call(warnedProperties$1, name) && warnedProperties$1[name]) {
7239 return true;
7240 }
7241
7242 var lowerCasedName = name.toLowerCase();
7243 if (lowerCasedName === 'onfocusin' || lowerCasedName === 'onfocusout') {
7244 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.');
7245 warnedProperties$1[name] = true;
7246 return true;
7247 }
7248
7249 // We can't rely on the event system being injected on the server.
7250 if (canUseEventSystem) {
7251 if (registrationNameModules.hasOwnProperty(name)) {
7252 return true;
7253 }
7254 var registrationName = possibleRegistrationNames.hasOwnProperty(lowerCasedName) ? possibleRegistrationNames[lowerCasedName] : null;
7255 if (registrationName != null) {
7256 warning$1(false, 'Invalid event handler property `%s`. Did you mean `%s`?', name, registrationName);
7257 warnedProperties$1[name] = true;
7258 return true;
7259 }
7260 if (EVENT_NAME_REGEX.test(name)) {
7261 warning$1(false, 'Unknown event handler property `%s`. It will be ignored.', name);
7262 warnedProperties$1[name] = true;
7263 return true;
7264 }
7265 } else if (EVENT_NAME_REGEX.test(name)) {
7266 // If no event plugins have been injected, we are in a server environment.
7267 // So we can't tell if the event name is correct for sure, but we can filter
7268 // out known bad ones like `onclick`. We can't suggest a specific replacement though.
7269 if (INVALID_EVENT_NAME_REGEX.test(name)) {
7270 warning$1(false, 'Invalid event handler property `%s`. ' + 'React events use the camelCase naming convention, for example `onClick`.', name);
7271 }
7272 warnedProperties$1[name] = true;
7273 return true;
7274 }
7275
7276 // Let the ARIA attribute hook validate ARIA attributes
7277 if (rARIA$1.test(name) || rARIACamel$1.test(name)) {
7278 return true;
7279 }
7280
7281 if (lowerCasedName === 'innerhtml') {
7282 warning$1(false, 'Directly setting property `innerHTML` is not permitted. ' + 'For more information, lookup documentation on `dangerouslySetInnerHTML`.');
7283 warnedProperties$1[name] = true;
7284 return true;
7285 }
7286
7287 if (lowerCasedName === 'aria') {
7288 warning$1(false, 'The `aria` attribute is reserved for future use in React. ' + 'Pass individual `aria-` attributes instead.');
7289 warnedProperties$1[name] = true;
7290 return true;
7291 }
7292
7293 if (lowerCasedName === 'is' && value !== null && value !== undefined && typeof value !== 'string') {
7294 warning$1(false, 'Received a `%s` for a string attribute `is`. If this is expected, cast ' + 'the value to a string.', typeof value);
7295 warnedProperties$1[name] = true;
7296 return true;
7297 }
7298
7299 if (typeof value === 'number' && isNaN(value)) {
7300 warning$1(false, 'Received NaN for the `%s` attribute. If this is expected, cast ' + 'the value to a string.', name);
7301 warnedProperties$1[name] = true;
7302 return true;
7303 }
7304
7305 var propertyInfo = getPropertyInfo(name);
7306 var isReserved = propertyInfo !== null && propertyInfo.type === RESERVED;
7307
7308 // Known attributes should match the casing specified in the property config.
7309 if (possibleStandardNames.hasOwnProperty(lowerCasedName)) {
7310 var standardName = possibleStandardNames[lowerCasedName];
7311 if (standardName !== name) {
7312 warning$1(false, 'Invalid DOM property `%s`. Did you mean `%s`?', name, standardName);
7313 warnedProperties$1[name] = true;
7314 return true;
7315 }
7316 } else if (!isReserved && name !== lowerCasedName) {
7317 // Unknown attributes should have lowercase casing since that's how they
7318 // will be cased anyway with server rendering.
7319 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);
7320 warnedProperties$1[name] = true;
7321 return true;
7322 }
7323
7324 if (typeof value === 'boolean' && shouldRemoveAttributeWithWarning(name, value, propertyInfo, false)) {
7325 if (value) {
7326 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);
7327 } else {
7328 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);
7329 }
7330 warnedProperties$1[name] = true;
7331 return true;
7332 }
7333
7334 // Now that we've validated casing, do not validate
7335 // data types for reserved props
7336 if (isReserved) {
7337 return true;
7338 }
7339
7340 // Warn when a known attribute is a bad type
7341 if (shouldRemoveAttributeWithWarning(name, value, propertyInfo, false)) {
7342 warnedProperties$1[name] = true;
7343 return false;
7344 }
7345
7346 // Warn when passing the strings 'false' or 'true' into a boolean prop
7347 if ((value === 'false' || value === 'true') && propertyInfo !== null && propertyInfo.type === BOOLEAN) {
7348 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);
7349 warnedProperties$1[name] = true;
7350 return true;
7351 }
7352
7353 return true;
7354 };
7355}
7356
7357var warnUnknownProperties = function (type, props, canUseEventSystem) {
7358 var unknownProps = [];
7359 for (var key in props) {
7360 var isValid = validateProperty$1(type, key, props[key], canUseEventSystem);
7361 if (!isValid) {
7362 unknownProps.push(key);
7363 }
7364 }
7365
7366 var unknownPropString = unknownProps.map(function (prop) {
7367 return '`' + prop + '`';
7368 }).join(', ');
7369 if (unknownProps.length === 1) {
7370 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);
7371 } else if (unknownProps.length > 1) {
7372 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);
7373 }
7374};
7375
7376function validateProperties$2(type, props, canUseEventSystem) {
7377 if (isCustomComponent(type, props)) {
7378 return;
7379 }
7380 warnUnknownProperties(type, props, canUseEventSystem);
7381}
7382
7383// TODO: direct imports like some-package/src/* are bad. Fix me.
7384var didWarnInvalidHydration = false;
7385var didWarnShadyDOM = false;
7386
7387var DANGEROUSLY_SET_INNER_HTML = 'dangerouslySetInnerHTML';
7388var SUPPRESS_CONTENT_EDITABLE_WARNING = 'suppressContentEditableWarning';
7389var SUPPRESS_HYDRATION_WARNING$1 = 'suppressHydrationWarning';
7390var AUTOFOCUS = 'autoFocus';
7391var CHILDREN = 'children';
7392var STYLE$1 = 'style';
7393var HTML = '__html';
7394
7395var HTML_NAMESPACE = Namespaces.html;
7396
7397
7398var warnedUnknownTags = void 0;
7399var suppressHydrationWarning = void 0;
7400
7401var validatePropertiesInDevelopment = void 0;
7402var warnForTextDifference = void 0;
7403var warnForPropDifference = void 0;
7404var warnForExtraAttributes = void 0;
7405var warnForInvalidEventListener = void 0;
7406var canDiffStyleForHydrationWarning = void 0;
7407
7408var normalizeMarkupForTextOrAttribute = void 0;
7409var normalizeHTML = void 0;
7410
7411{
7412 warnedUnknownTags = {
7413 // Chrome is the only major browser not shipping <time>. But as of July
7414 // 2017 it intends to ship it due to widespread usage. We intentionally
7415 // *don't* warn for <time> even if it's unrecognized by Chrome because
7416 // it soon will be, and many apps have been using it anyway.
7417 time: true,
7418 // There are working polyfills for <dialog>. Let people use it.
7419 dialog: true,
7420 // Electron ships a custom <webview> tag to display external web content in
7421 // an isolated frame and process.
7422 // This tag is not present in non Electron environments such as JSDom which
7423 // is often used for testing purposes.
7424 // @see https://electronjs.org/docs/api/webview-tag
7425 webview: true
7426 };
7427
7428 validatePropertiesInDevelopment = function (type, props) {
7429 validateProperties(type, props);
7430 validateProperties$1(type, props);
7431 validateProperties$2(type, props, /* canUseEventSystem */true);
7432 };
7433
7434 // IE 11 parses & normalizes the style attribute as opposed to other
7435 // browsers. It adds spaces and sorts the properties in some
7436 // non-alphabetical order. Handling that would require sorting CSS
7437 // properties in the client & server versions or applying
7438 // `expectedStyle` to a temporary DOM node to read its `style` attribute
7439 // normalized. Since it only affects IE, we're skipping style warnings
7440 // in that browser completely in favor of doing all that work.
7441 // See https://github.com/facebook/react/issues/11807
7442 canDiffStyleForHydrationWarning = canUseDOM && !document.documentMode;
7443
7444 // HTML parsing normalizes CR and CRLF to LF.
7445 // It also can turn \u0000 into \uFFFD inside attributes.
7446 // https://www.w3.org/TR/html5/single-page.html#preprocessing-the-input-stream
7447 // If we have a mismatch, it might be caused by that.
7448 // We will still patch up in this case but not fire the warning.
7449 var NORMALIZE_NEWLINES_REGEX = /\r\n?/g;
7450 var NORMALIZE_NULL_AND_REPLACEMENT_REGEX = /\u0000|\uFFFD/g;
7451
7452 normalizeMarkupForTextOrAttribute = function (markup) {
7453 var markupString = typeof markup === 'string' ? markup : '' + markup;
7454 return markupString.replace(NORMALIZE_NEWLINES_REGEX, '\n').replace(NORMALIZE_NULL_AND_REPLACEMENT_REGEX, '');
7455 };
7456
7457 warnForTextDifference = function (serverText, clientText) {
7458 if (didWarnInvalidHydration) {
7459 return;
7460 }
7461 var normalizedClientText = normalizeMarkupForTextOrAttribute(clientText);
7462 var normalizedServerText = normalizeMarkupForTextOrAttribute(serverText);
7463 if (normalizedServerText === normalizedClientText) {
7464 return;
7465 }
7466 didWarnInvalidHydration = true;
7467 warningWithoutStack$1(false, 'Text content did not match. Server: "%s" Client: "%s"', normalizedServerText, normalizedClientText);
7468 };
7469
7470 warnForPropDifference = function (propName, serverValue, clientValue) {
7471 if (didWarnInvalidHydration) {
7472 return;
7473 }
7474 var normalizedClientValue = normalizeMarkupForTextOrAttribute(clientValue);
7475 var normalizedServerValue = normalizeMarkupForTextOrAttribute(serverValue);
7476 if (normalizedServerValue === normalizedClientValue) {
7477 return;
7478 }
7479 didWarnInvalidHydration = true;
7480 warningWithoutStack$1(false, 'Prop `%s` did not match. Server: %s Client: %s', propName, JSON.stringify(normalizedServerValue), JSON.stringify(normalizedClientValue));
7481 };
7482
7483 warnForExtraAttributes = function (attributeNames) {
7484 if (didWarnInvalidHydration) {
7485 return;
7486 }
7487 didWarnInvalidHydration = true;
7488 var names = [];
7489 attributeNames.forEach(function (name) {
7490 names.push(name);
7491 });
7492 warningWithoutStack$1(false, 'Extra attributes from the server: %s', names);
7493 };
7494
7495 warnForInvalidEventListener = function (registrationName, listener) {
7496 if (listener === false) {
7497 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);
7498 } else {
7499 warning$1(false, 'Expected `%s` listener to be a function, instead got a value of `%s` type.', registrationName, typeof listener);
7500 }
7501 };
7502
7503 // Parse the HTML and read it back to normalize the HTML string so that it
7504 // can be used for comparison.
7505 normalizeHTML = function (parent, html) {
7506 // We could have created a separate document here to avoid
7507 // re-initializing custom elements if they exist. But this breaks
7508 // how <noscript> is being handled. So we use the same document.
7509 // See the discussion in https://github.com/facebook/react/pull/11157.
7510 var testElement = parent.namespaceURI === HTML_NAMESPACE ? parent.ownerDocument.createElement(parent.tagName) : parent.ownerDocument.createElementNS(parent.namespaceURI, parent.tagName);
7511 testElement.innerHTML = html;
7512 return testElement.innerHTML;
7513 };
7514}
7515
7516function ensureListeningTo(rootContainerElement, registrationName) {
7517 var isDocumentOrFragment = rootContainerElement.nodeType === DOCUMENT_NODE || rootContainerElement.nodeType === DOCUMENT_FRAGMENT_NODE;
7518 var doc = isDocumentOrFragment ? rootContainerElement : rootContainerElement.ownerDocument;
7519 listenTo(registrationName, doc);
7520}
7521
7522function getOwnerDocumentFromRootContainer(rootContainerElement) {
7523 return rootContainerElement.nodeType === DOCUMENT_NODE ? rootContainerElement : rootContainerElement.ownerDocument;
7524}
7525
7526function noop() {}
7527
7528function trapClickOnNonInteractiveElement(node) {
7529 // Mobile Safari does not fire properly bubble click events on
7530 // non-interactive elements, which means delegated click listeners do not
7531 // fire. The workaround for this bug involves attaching an empty click
7532 // listener on the target node.
7533 // http://www.quirksmode.org/blog/archives/2010/09/click_event_del.html
7534 // Just set it using the onclick property so that we don't have to manage any
7535 // bookkeeping for it. Not sure if we need to clear it when the listener is
7536 // removed.
7537 // TODO: Only do this for the relevant Safaris maybe?
7538 node.onclick = noop;
7539}
7540
7541function setInitialDOMProperties(tag, domElement, rootContainerElement, nextProps, isCustomComponentTag) {
7542 for (var propKey in nextProps) {
7543 if (!nextProps.hasOwnProperty(propKey)) {
7544 continue;
7545 }
7546 var nextProp = nextProps[propKey];
7547 if (propKey === STYLE$1) {
7548 {
7549 if (nextProp) {
7550 // Freeze the next style object so that we can assume it won't be
7551 // mutated. We have already warned for this in the past.
7552 Object.freeze(nextProp);
7553 }
7554 }
7555 // Relies on `updateStylesByID` not mutating `styleUpdates`.
7556 setValueForStyles(domElement, nextProp);
7557 } else if (propKey === DANGEROUSLY_SET_INNER_HTML) {
7558 var nextHtml = nextProp ? nextProp[HTML] : undefined;
7559 if (nextHtml != null) {
7560 setInnerHTML(domElement, nextHtml);
7561 }
7562 } else if (propKey === CHILDREN) {
7563 if (typeof nextProp === 'string') {
7564 // Avoid setting initial textContent when the text is empty. In IE11 setting
7565 // textContent on a <textarea> will cause the placeholder to not
7566 // show within the <textarea> until it has been focused and blurred again.
7567 // https://github.com/facebook/react/issues/6731#issuecomment-254874553
7568 var canSetTextContent = tag !== 'textarea' || nextProp !== '';
7569 if (canSetTextContent) {
7570 setTextContent(domElement, nextProp);
7571 }
7572 } else if (typeof nextProp === 'number') {
7573 setTextContent(domElement, '' + nextProp);
7574 }
7575 } else if (propKey === SUPPRESS_CONTENT_EDITABLE_WARNING || propKey === SUPPRESS_HYDRATION_WARNING$1) {
7576 // Noop
7577 } else if (propKey === AUTOFOCUS) {
7578 // We polyfill it separately on the client during commit.
7579 // We could have excluded it in the property list instead of
7580 // adding a special case here, but then it wouldn't be emitted
7581 // on server rendering (but we *do* want to emit it in SSR).
7582 } else if (registrationNameModules.hasOwnProperty(propKey)) {
7583 if (nextProp != null) {
7584 if (true && typeof nextProp !== 'function') {
7585 warnForInvalidEventListener(propKey, nextProp);
7586 }
7587 ensureListeningTo(rootContainerElement, propKey);
7588 }
7589 } else if (nextProp != null) {
7590 setValueForProperty(domElement, propKey, nextProp, isCustomComponentTag);
7591 }
7592 }
7593}
7594
7595function updateDOMProperties(domElement, updatePayload, wasCustomComponentTag, isCustomComponentTag) {
7596 // TODO: Handle wasCustomComponentTag
7597 for (var i = 0; i < updatePayload.length; i += 2) {
7598 var propKey = updatePayload[i];
7599 var propValue = updatePayload[i + 1];
7600 if (propKey === STYLE$1) {
7601 setValueForStyles(domElement, propValue);
7602 } else if (propKey === DANGEROUSLY_SET_INNER_HTML) {
7603 setInnerHTML(domElement, propValue);
7604 } else if (propKey === CHILDREN) {
7605 setTextContent(domElement, propValue);
7606 } else {
7607 setValueForProperty(domElement, propKey, propValue, isCustomComponentTag);
7608 }
7609 }
7610}
7611
7612function createElement(type, props, rootContainerElement, parentNamespace) {
7613 var isCustomComponentTag = void 0;
7614
7615 // We create tags in the namespace of their parent container, except HTML
7616 // tags get no namespace.
7617 var ownerDocument = getOwnerDocumentFromRootContainer(rootContainerElement);
7618 var domElement = void 0;
7619 var namespaceURI = parentNamespace;
7620 if (namespaceURI === HTML_NAMESPACE) {
7621 namespaceURI = getIntrinsicNamespace(type);
7622 }
7623 if (namespaceURI === HTML_NAMESPACE) {
7624 {
7625 isCustomComponentTag = isCustomComponent(type, props);
7626 // Should this check be gated by parent namespace? Not sure we want to
7627 // allow <SVG> or <mATH>.
7628 !(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;
7629 }
7630
7631 if (type === 'script') {
7632 // Create the script via .innerHTML so its "parser-inserted" flag is
7633 // set to true and it does not execute
7634 var div = ownerDocument.createElement('div');
7635 div.innerHTML = '<script><' + '/script>'; // eslint-disable-line
7636 // This is guaranteed to yield a script element.
7637 var firstChild = div.firstChild;
7638 domElement = div.removeChild(firstChild);
7639 } else if (typeof props.is === 'string') {
7640 // $FlowIssue `createElement` should be updated for Web Components
7641 domElement = ownerDocument.createElement(type, { is: props.is });
7642 } else {
7643 // Separate else branch instead of using `props.is || undefined` above because of a Firefox bug.
7644 // See discussion in https://github.com/facebook/react/pull/6896
7645 // and discussion in https://bugzilla.mozilla.org/show_bug.cgi?id=1276240
7646 domElement = ownerDocument.createElement(type);
7647 // Normally attributes are assigned in `setInitialDOMProperties`, however the `multiple` and `size`
7648 // attributes on `select`s needs to be added before `option`s are inserted.
7649 // This prevents:
7650 // - a bug where the `select` does not scroll to the correct option because singular
7651 // `select` elements automatically pick the first item #13222
7652 // - a bug where the `select` set the first item as selected despite the `size` attribute #14239
7653 // See https://github.com/facebook/react/issues/13222
7654 // and https://github.com/facebook/react/issues/14239
7655 if (type === 'select') {
7656 var node = domElement;
7657 if (props.multiple) {
7658 node.multiple = true;
7659 } else if (props.size) {
7660 // Setting a size greater than 1 causes a select to behave like `multiple=true`, where
7661 // it is possible that no option is selected.
7662 //
7663 // This is only necessary when a select in "single selection mode".
7664 node.size = props.size;
7665 }
7666 }
7667 }
7668 } else {
7669 domElement = ownerDocument.createElementNS(namespaceURI, type);
7670 }
7671
7672 {
7673 if (namespaceURI === HTML_NAMESPACE) {
7674 if (!isCustomComponentTag && Object.prototype.toString.call(domElement) === '[object HTMLUnknownElement]' && !Object.prototype.hasOwnProperty.call(warnedUnknownTags, type)) {
7675 warnedUnknownTags[type] = true;
7676 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);
7677 }
7678 }
7679 }
7680
7681 return domElement;
7682}
7683
7684function createTextNode(text, rootContainerElement) {
7685 return getOwnerDocumentFromRootContainer(rootContainerElement).createTextNode(text);
7686}
7687
7688function setInitialProperties(domElement, tag, rawProps, rootContainerElement) {
7689 var isCustomComponentTag = isCustomComponent(tag, rawProps);
7690 {
7691 validatePropertiesInDevelopment(tag, rawProps);
7692 if (isCustomComponentTag && !didWarnShadyDOM && domElement.shadyRoot) {
7693 warning$1(false, '%s is using shady DOM. Using shady DOM with React can ' + 'cause things to break subtly.', getCurrentFiberOwnerNameInDevOrNull() || 'A component');
7694 didWarnShadyDOM = true;
7695 }
7696 }
7697
7698 // TODO: Make sure that we check isMounted before firing any of these events.
7699 var props = void 0;
7700 switch (tag) {
7701 case 'iframe':
7702 case 'object':
7703 trapBubbledEvent(TOP_LOAD, domElement);
7704 props = rawProps;
7705 break;
7706 case 'video':
7707 case 'audio':
7708 // Create listener for each media event
7709 for (var i = 0; i < mediaEventTypes.length; i++) {
7710 trapBubbledEvent(mediaEventTypes[i], domElement);
7711 }
7712 props = rawProps;
7713 break;
7714 case 'source':
7715 trapBubbledEvent(TOP_ERROR, domElement);
7716 props = rawProps;
7717 break;
7718 case 'img':
7719 case 'image':
7720 case 'link':
7721 trapBubbledEvent(TOP_ERROR, domElement);
7722 trapBubbledEvent(TOP_LOAD, domElement);
7723 props = rawProps;
7724 break;
7725 case 'form':
7726 trapBubbledEvent(TOP_RESET, domElement);
7727 trapBubbledEvent(TOP_SUBMIT, domElement);
7728 props = rawProps;
7729 break;
7730 case 'details':
7731 trapBubbledEvent(TOP_TOGGLE, domElement);
7732 props = rawProps;
7733 break;
7734 case 'input':
7735 initWrapperState(domElement, rawProps);
7736 props = getHostProps(domElement, rawProps);
7737 trapBubbledEvent(TOP_INVALID, domElement);
7738 // For controlled components we always need to ensure we're listening
7739 // to onChange. Even if there is no listener.
7740 ensureListeningTo(rootContainerElement, 'onChange');
7741 break;
7742 case 'option':
7743 validateProps(domElement, rawProps);
7744 props = getHostProps$1(domElement, rawProps);
7745 break;
7746 case 'select':
7747 initWrapperState$1(domElement, rawProps);
7748 props = getHostProps$2(domElement, rawProps);
7749 trapBubbledEvent(TOP_INVALID, domElement);
7750 // For controlled components we always need to ensure we're listening
7751 // to onChange. Even if there is no listener.
7752 ensureListeningTo(rootContainerElement, 'onChange');
7753 break;
7754 case 'textarea':
7755 initWrapperState$2(domElement, rawProps);
7756 props = getHostProps$3(domElement, rawProps);
7757 trapBubbledEvent(TOP_INVALID, domElement);
7758 // For controlled components we always need to ensure we're listening
7759 // to onChange. Even if there is no listener.
7760 ensureListeningTo(rootContainerElement, 'onChange');
7761 break;
7762 default:
7763 props = rawProps;
7764 }
7765
7766 assertValidProps(tag, props);
7767
7768 setInitialDOMProperties(tag, domElement, rootContainerElement, props, isCustomComponentTag);
7769
7770 switch (tag) {
7771 case 'input':
7772 // TODO: Make sure we check if this is still unmounted or do any clean
7773 // up necessary since we never stop tracking anymore.
7774 track(domElement);
7775 postMountWrapper(domElement, rawProps, false);
7776 break;
7777 case 'textarea':
7778 // TODO: Make sure we check if this is still unmounted or do any clean
7779 // up necessary since we never stop tracking anymore.
7780 track(domElement);
7781 postMountWrapper$3(domElement, rawProps);
7782 break;
7783 case 'option':
7784 postMountWrapper$1(domElement, rawProps);
7785 break;
7786 case 'select':
7787 postMountWrapper$2(domElement, rawProps);
7788 break;
7789 default:
7790 if (typeof props.onClick === 'function') {
7791 // TODO: This cast may not be sound for SVG, MathML or custom elements.
7792 trapClickOnNonInteractiveElement(domElement);
7793 }
7794 break;
7795 }
7796}
7797
7798// Calculate the diff between the two objects.
7799function diffProperties(domElement, tag, lastRawProps, nextRawProps, rootContainerElement) {
7800 {
7801 validatePropertiesInDevelopment(tag, nextRawProps);
7802 }
7803
7804 var updatePayload = null;
7805
7806 var lastProps = void 0;
7807 var nextProps = void 0;
7808 switch (tag) {
7809 case 'input':
7810 lastProps = getHostProps(domElement, lastRawProps);
7811 nextProps = getHostProps(domElement, nextRawProps);
7812 updatePayload = [];
7813 break;
7814 case 'option':
7815 lastProps = getHostProps$1(domElement, lastRawProps);
7816 nextProps = getHostProps$1(domElement, nextRawProps);
7817 updatePayload = [];
7818 break;
7819 case 'select':
7820 lastProps = getHostProps$2(domElement, lastRawProps);
7821 nextProps = getHostProps$2(domElement, nextRawProps);
7822 updatePayload = [];
7823 break;
7824 case 'textarea':
7825 lastProps = getHostProps$3(domElement, lastRawProps);
7826 nextProps = getHostProps$3(domElement, nextRawProps);
7827 updatePayload = [];
7828 break;
7829 default:
7830 lastProps = lastRawProps;
7831 nextProps = nextRawProps;
7832 if (typeof lastProps.onClick !== 'function' && typeof nextProps.onClick === 'function') {
7833 // TODO: This cast may not be sound for SVG, MathML or custom elements.
7834 trapClickOnNonInteractiveElement(domElement);
7835 }
7836 break;
7837 }
7838
7839 assertValidProps(tag, nextProps);
7840
7841 var propKey = void 0;
7842 var styleName = void 0;
7843 var styleUpdates = null;
7844 for (propKey in lastProps) {
7845 if (nextProps.hasOwnProperty(propKey) || !lastProps.hasOwnProperty(propKey) || lastProps[propKey] == null) {
7846 continue;
7847 }
7848 if (propKey === STYLE$1) {
7849 var lastStyle = lastProps[propKey];
7850 for (styleName in lastStyle) {
7851 if (lastStyle.hasOwnProperty(styleName)) {
7852 if (!styleUpdates) {
7853 styleUpdates = {};
7854 }
7855 styleUpdates[styleName] = '';
7856 }
7857 }
7858 } else if (propKey === DANGEROUSLY_SET_INNER_HTML || propKey === CHILDREN) {
7859 // Noop. This is handled by the clear text mechanism.
7860 } else if (propKey === SUPPRESS_CONTENT_EDITABLE_WARNING || propKey === SUPPRESS_HYDRATION_WARNING$1) {
7861 // Noop
7862 } else if (propKey === AUTOFOCUS) {
7863 // Noop. It doesn't work on updates anyway.
7864 } else if (registrationNameModules.hasOwnProperty(propKey)) {
7865 // This is a special case. If any listener updates we need to ensure
7866 // that the "current" fiber pointer gets updated so we need a commit
7867 // to update this element.
7868 if (!updatePayload) {
7869 updatePayload = [];
7870 }
7871 } else {
7872 // For all other deleted properties we add it to the queue. We use
7873 // the whitelist in the commit phase instead.
7874 (updatePayload = updatePayload || []).push(propKey, null);
7875 }
7876 }
7877 for (propKey in nextProps) {
7878 var nextProp = nextProps[propKey];
7879 var lastProp = lastProps != null ? lastProps[propKey] : undefined;
7880 if (!nextProps.hasOwnProperty(propKey) || nextProp === lastProp || nextProp == null && lastProp == null) {
7881 continue;
7882 }
7883 if (propKey === STYLE$1) {
7884 {
7885 if (nextProp) {
7886 // Freeze the next style object so that we can assume it won't be
7887 // mutated. We have already warned for this in the past.
7888 Object.freeze(nextProp);
7889 }
7890 }
7891 if (lastProp) {
7892 // Unset styles on `lastProp` but not on `nextProp`.
7893 for (styleName in lastProp) {
7894 if (lastProp.hasOwnProperty(styleName) && (!nextProp || !nextProp.hasOwnProperty(styleName))) {
7895 if (!styleUpdates) {
7896 styleUpdates = {};
7897 }
7898 styleUpdates[styleName] = '';
7899 }
7900 }
7901 // Update styles that changed since `lastProp`.
7902 for (styleName in nextProp) {
7903 if (nextProp.hasOwnProperty(styleName) && lastProp[styleName] !== nextProp[styleName]) {
7904 if (!styleUpdates) {
7905 styleUpdates = {};
7906 }
7907 styleUpdates[styleName] = nextProp[styleName];
7908 }
7909 }
7910 } else {
7911 // Relies on `updateStylesByID` not mutating `styleUpdates`.
7912 if (!styleUpdates) {
7913 if (!updatePayload) {
7914 updatePayload = [];
7915 }
7916 updatePayload.push(propKey, styleUpdates);
7917 }
7918 styleUpdates = nextProp;
7919 }
7920 } else if (propKey === DANGEROUSLY_SET_INNER_HTML) {
7921 var nextHtml = nextProp ? nextProp[HTML] : undefined;
7922 var lastHtml = lastProp ? lastProp[HTML] : undefined;
7923 if (nextHtml != null) {
7924 if (lastHtml !== nextHtml) {
7925 (updatePayload = updatePayload || []).push(propKey, '' + nextHtml);
7926 }
7927 } else {
7928 // TODO: It might be too late to clear this if we have children
7929 // inserted already.
7930 }
7931 } else if (propKey === CHILDREN) {
7932 if (lastProp !== nextProp && (typeof nextProp === 'string' || typeof nextProp === 'number')) {
7933 (updatePayload = updatePayload || []).push(propKey, '' + nextProp);
7934 }
7935 } else if (propKey === SUPPRESS_CONTENT_EDITABLE_WARNING || propKey === SUPPRESS_HYDRATION_WARNING$1) {
7936 // Noop
7937 } else if (registrationNameModules.hasOwnProperty(propKey)) {
7938 if (nextProp != null) {
7939 // We eagerly listen to this even though we haven't committed yet.
7940 if (true && typeof nextProp !== 'function') {
7941 warnForInvalidEventListener(propKey, nextProp);
7942 }
7943 ensureListeningTo(rootContainerElement, propKey);
7944 }
7945 if (!updatePayload && lastProp !== nextProp) {
7946 // This is a special case. If any listener updates we need to ensure
7947 // that the "current" props pointer gets updated so we need a commit
7948 // to update this element.
7949 updatePayload = [];
7950 }
7951 } else {
7952 // For any other property we always add it to the queue and then we
7953 // filter it out using the whitelist during the commit.
7954 (updatePayload = updatePayload || []).push(propKey, nextProp);
7955 }
7956 }
7957 if (styleUpdates) {
7958 {
7959 validateShorthandPropertyCollisionInDev(styleUpdates, nextProps[STYLE$1]);
7960 }
7961 (updatePayload = updatePayload || []).push(STYLE$1, styleUpdates);
7962 }
7963 return updatePayload;
7964}
7965
7966// Apply the diff.
7967function updateProperties(domElement, updatePayload, tag, lastRawProps, nextRawProps) {
7968 // Update checked *before* name.
7969 // In the middle of an update, it is possible to have multiple checked.
7970 // When a checked radio tries to change name, browser makes another radio's checked false.
7971 if (tag === 'input' && nextRawProps.type === 'radio' && nextRawProps.name != null) {
7972 updateChecked(domElement, nextRawProps);
7973 }
7974
7975 var wasCustomComponentTag = isCustomComponent(tag, lastRawProps);
7976 var isCustomComponentTag = isCustomComponent(tag, nextRawProps);
7977 // Apply the diff.
7978 updateDOMProperties(domElement, updatePayload, wasCustomComponentTag, isCustomComponentTag);
7979
7980 // TODO: Ensure that an update gets scheduled if any of the special props
7981 // changed.
7982 switch (tag) {
7983 case 'input':
7984 // Update the wrapper around inputs *after* updating props. This has to
7985 // happen after `updateDOMProperties`. Otherwise HTML5 input validations
7986 // raise warnings and prevent the new value from being assigned.
7987 updateWrapper(domElement, nextRawProps);
7988 break;
7989 case 'textarea':
7990 updateWrapper$1(domElement, nextRawProps);
7991 break;
7992 case 'select':
7993 // <select> value update needs to occur after <option> children
7994 // reconciliation
7995 postUpdateWrapper(domElement, nextRawProps);
7996 break;
7997 }
7998}
7999
8000function getPossibleStandardName(propName) {
8001 {
8002 var lowerCasedName = propName.toLowerCase();
8003 if (!possibleStandardNames.hasOwnProperty(lowerCasedName)) {
8004 return null;
8005 }
8006 return possibleStandardNames[lowerCasedName] || null;
8007 }
8008 return null;
8009}
8010
8011function diffHydratedProperties(domElement, tag, rawProps, parentNamespace, rootContainerElement) {
8012 var isCustomComponentTag = void 0;
8013 var extraAttributeNames = void 0;
8014
8015 {
8016 suppressHydrationWarning = rawProps[SUPPRESS_HYDRATION_WARNING$1] === true;
8017 isCustomComponentTag = isCustomComponent(tag, rawProps);
8018 validatePropertiesInDevelopment(tag, rawProps);
8019 if (isCustomComponentTag && !didWarnShadyDOM && domElement.shadyRoot) {
8020 warning$1(false, '%s is using shady DOM. Using shady DOM with React can ' + 'cause things to break subtly.', getCurrentFiberOwnerNameInDevOrNull() || 'A component');
8021 didWarnShadyDOM = true;
8022 }
8023 }
8024
8025 // TODO: Make sure that we check isMounted before firing any of these events.
8026 switch (tag) {
8027 case 'iframe':
8028 case 'object':
8029 trapBubbledEvent(TOP_LOAD, domElement);
8030 break;
8031 case 'video':
8032 case 'audio':
8033 // Create listener for each media event
8034 for (var i = 0; i < mediaEventTypes.length; i++) {
8035 trapBubbledEvent(mediaEventTypes[i], domElement);
8036 }
8037 break;
8038 case 'source':
8039 trapBubbledEvent(TOP_ERROR, domElement);
8040 break;
8041 case 'img':
8042 case 'image':
8043 case 'link':
8044 trapBubbledEvent(TOP_ERROR, domElement);
8045 trapBubbledEvent(TOP_LOAD, domElement);
8046 break;
8047 case 'form':
8048 trapBubbledEvent(TOP_RESET, domElement);
8049 trapBubbledEvent(TOP_SUBMIT, domElement);
8050 break;
8051 case 'details':
8052 trapBubbledEvent(TOP_TOGGLE, domElement);
8053 break;
8054 case 'input':
8055 initWrapperState(domElement, rawProps);
8056 trapBubbledEvent(TOP_INVALID, domElement);
8057 // For controlled components we always need to ensure we're listening
8058 // to onChange. Even if there is no listener.
8059 ensureListeningTo(rootContainerElement, 'onChange');
8060 break;
8061 case 'option':
8062 validateProps(domElement, rawProps);
8063 break;
8064 case 'select':
8065 initWrapperState$1(domElement, rawProps);
8066 trapBubbledEvent(TOP_INVALID, domElement);
8067 // For controlled components we always need to ensure we're listening
8068 // to onChange. Even if there is no listener.
8069 ensureListeningTo(rootContainerElement, 'onChange');
8070 break;
8071 case 'textarea':
8072 initWrapperState$2(domElement, rawProps);
8073 trapBubbledEvent(TOP_INVALID, domElement);
8074 // For controlled components we always need to ensure we're listening
8075 // to onChange. Even if there is no listener.
8076 ensureListeningTo(rootContainerElement, 'onChange');
8077 break;
8078 }
8079
8080 assertValidProps(tag, rawProps);
8081
8082 {
8083 extraAttributeNames = new Set();
8084 var attributes = domElement.attributes;
8085 for (var _i = 0; _i < attributes.length; _i++) {
8086 var name = attributes[_i].name.toLowerCase();
8087 switch (name) {
8088 // Built-in SSR attribute is whitelisted
8089 case 'data-reactroot':
8090 break;
8091 // Controlled attributes are not validated
8092 // TODO: Only ignore them on controlled tags.
8093 case 'value':
8094 break;
8095 case 'checked':
8096 break;
8097 case 'selected':
8098 break;
8099 default:
8100 // Intentionally use the original name.
8101 // See discussion in https://github.com/facebook/react/pull/10676.
8102 extraAttributeNames.add(attributes[_i].name);
8103 }
8104 }
8105 }
8106
8107 var updatePayload = null;
8108 for (var propKey in rawProps) {
8109 if (!rawProps.hasOwnProperty(propKey)) {
8110 continue;
8111 }
8112 var nextProp = rawProps[propKey];
8113 if (propKey === CHILDREN) {
8114 // For text content children we compare against textContent. This
8115 // might match additional HTML that is hidden when we read it using
8116 // textContent. E.g. "foo" will match "f<span>oo</span>" but that still
8117 // satisfies our requirement. Our requirement is not to produce perfect
8118 // HTML and attributes. Ideally we should preserve structure but it's
8119 // ok not to if the visible content is still enough to indicate what
8120 // even listeners these nodes might be wired up to.
8121 // TODO: Warn if there is more than a single textNode as a child.
8122 // TODO: Should we use domElement.firstChild.nodeValue to compare?
8123 if (typeof nextProp === 'string') {
8124 if (domElement.textContent !== nextProp) {
8125 if (true && !suppressHydrationWarning) {
8126 warnForTextDifference(domElement.textContent, nextProp);
8127 }
8128 updatePayload = [CHILDREN, nextProp];
8129 }
8130 } else if (typeof nextProp === 'number') {
8131 if (domElement.textContent !== '' + nextProp) {
8132 if (true && !suppressHydrationWarning) {
8133 warnForTextDifference(domElement.textContent, nextProp);
8134 }
8135 updatePayload = [CHILDREN, '' + nextProp];
8136 }
8137 }
8138 } else if (registrationNameModules.hasOwnProperty(propKey)) {
8139 if (nextProp != null) {
8140 if (true && typeof nextProp !== 'function') {
8141 warnForInvalidEventListener(propKey, nextProp);
8142 }
8143 ensureListeningTo(rootContainerElement, propKey);
8144 }
8145 } else if (true &&
8146 // Convince Flow we've calculated it (it's DEV-only in this method.)
8147 typeof isCustomComponentTag === 'boolean') {
8148 // Validate that the properties correspond to their expected values.
8149 var serverValue = void 0;
8150 var propertyInfo = getPropertyInfo(propKey);
8151 if (suppressHydrationWarning) {
8152 // Don't bother comparing. We're ignoring all these warnings.
8153 } else if (propKey === SUPPRESS_CONTENT_EDITABLE_WARNING || propKey === SUPPRESS_HYDRATION_WARNING$1 ||
8154 // Controlled attributes are not validated
8155 // TODO: Only ignore them on controlled tags.
8156 propKey === 'value' || propKey === 'checked' || propKey === 'selected') {
8157 // Noop
8158 } else if (propKey === DANGEROUSLY_SET_INNER_HTML) {
8159 var serverHTML = domElement.innerHTML;
8160 var nextHtml = nextProp ? nextProp[HTML] : undefined;
8161 var expectedHTML = normalizeHTML(domElement, nextHtml != null ? nextHtml : '');
8162 if (expectedHTML !== serverHTML) {
8163 warnForPropDifference(propKey, serverHTML, expectedHTML);
8164 }
8165 } else if (propKey === STYLE$1) {
8166 // $FlowFixMe - Should be inferred as not undefined.
8167 extraAttributeNames.delete(propKey);
8168
8169 if (canDiffStyleForHydrationWarning) {
8170 var expectedStyle = createDangerousStringForStyles(nextProp);
8171 serverValue = domElement.getAttribute('style');
8172 if (expectedStyle !== serverValue) {
8173 warnForPropDifference(propKey, serverValue, expectedStyle);
8174 }
8175 }
8176 } else if (isCustomComponentTag) {
8177 // $FlowFixMe - Should be inferred as not undefined.
8178 extraAttributeNames.delete(propKey.toLowerCase());
8179 serverValue = getValueForAttribute(domElement, propKey, nextProp);
8180
8181 if (nextProp !== serverValue) {
8182 warnForPropDifference(propKey, serverValue, nextProp);
8183 }
8184 } else if (!shouldIgnoreAttribute(propKey, propertyInfo, isCustomComponentTag) && !shouldRemoveAttribute(propKey, nextProp, propertyInfo, isCustomComponentTag)) {
8185 var isMismatchDueToBadCasing = false;
8186 if (propertyInfo !== null) {
8187 // $FlowFixMe - Should be inferred as not undefined.
8188 extraAttributeNames.delete(propertyInfo.attributeName);
8189 serverValue = getValueForProperty(domElement, propKey, nextProp, propertyInfo);
8190 } else {
8191 var ownNamespace = parentNamespace;
8192 if (ownNamespace === HTML_NAMESPACE) {
8193 ownNamespace = getIntrinsicNamespace(tag);
8194 }
8195 if (ownNamespace === HTML_NAMESPACE) {
8196 // $FlowFixMe - Should be inferred as not undefined.
8197 extraAttributeNames.delete(propKey.toLowerCase());
8198 } else {
8199 var standardName = getPossibleStandardName(propKey);
8200 if (standardName !== null && standardName !== propKey) {
8201 // If an SVG prop is supplied with bad casing, it will
8202 // be successfully parsed from HTML, but will produce a mismatch
8203 // (and would be incorrectly rendered on the client).
8204 // However, we already warn about bad casing elsewhere.
8205 // So we'll skip the misleading extra mismatch warning in this case.
8206 isMismatchDueToBadCasing = true;
8207 // $FlowFixMe - Should be inferred as not undefined.
8208 extraAttributeNames.delete(standardName);
8209 }
8210 // $FlowFixMe - Should be inferred as not undefined.
8211 extraAttributeNames.delete(propKey);
8212 }
8213 serverValue = getValueForAttribute(domElement, propKey, nextProp);
8214 }
8215
8216 if (nextProp !== serverValue && !isMismatchDueToBadCasing) {
8217 warnForPropDifference(propKey, serverValue, nextProp);
8218 }
8219 }
8220 }
8221 }
8222
8223 {
8224 // $FlowFixMe - Should be inferred as not undefined.
8225 if (extraAttributeNames.size > 0 && !suppressHydrationWarning) {
8226 // $FlowFixMe - Should be inferred as not undefined.
8227 warnForExtraAttributes(extraAttributeNames);
8228 }
8229 }
8230
8231 switch (tag) {
8232 case 'input':
8233 // TODO: Make sure we check if this is still unmounted or do any clean
8234 // up necessary since we never stop tracking anymore.
8235 track(domElement);
8236 postMountWrapper(domElement, rawProps, true);
8237 break;
8238 case 'textarea':
8239 // TODO: Make sure we check if this is still unmounted or do any clean
8240 // up necessary since we never stop tracking anymore.
8241 track(domElement);
8242 postMountWrapper$3(domElement, rawProps);
8243 break;
8244 case 'select':
8245 case 'option':
8246 // For input and textarea we current always set the value property at
8247 // post mount to force it to diverge from attributes. However, for
8248 // option and select we don't quite do the same thing and select
8249 // is not resilient to the DOM state changing so we don't do that here.
8250 // TODO: Consider not doing this for input and textarea.
8251 break;
8252 default:
8253 if (typeof rawProps.onClick === 'function') {
8254 // TODO: This cast may not be sound for SVG, MathML or custom elements.
8255 trapClickOnNonInteractiveElement(domElement);
8256 }
8257 break;
8258 }
8259
8260 return updatePayload;
8261}
8262
8263function diffHydratedText(textNode, text) {
8264 var isDifferent = textNode.nodeValue !== text;
8265 return isDifferent;
8266}
8267
8268function warnForUnmatchedText(textNode, text) {
8269 {
8270 warnForTextDifference(textNode.nodeValue, text);
8271 }
8272}
8273
8274function warnForDeletedHydratableElement(parentNode, child) {
8275 {
8276 if (didWarnInvalidHydration) {
8277 return;
8278 }
8279 didWarnInvalidHydration = true;
8280 warningWithoutStack$1(false, 'Did not expect server HTML to contain a <%s> in <%s>.', child.nodeName.toLowerCase(), parentNode.nodeName.toLowerCase());
8281 }
8282}
8283
8284function warnForDeletedHydratableText(parentNode, child) {
8285 {
8286 if (didWarnInvalidHydration) {
8287 return;
8288 }
8289 didWarnInvalidHydration = true;
8290 warningWithoutStack$1(false, 'Did not expect server HTML to contain the text node "%s" in <%s>.', child.nodeValue, parentNode.nodeName.toLowerCase());
8291 }
8292}
8293
8294function warnForInsertedHydratedElement(parentNode, tag, props) {
8295 {
8296 if (didWarnInvalidHydration) {
8297 return;
8298 }
8299 didWarnInvalidHydration = true;
8300 warningWithoutStack$1(false, 'Expected server HTML to contain a matching <%s> in <%s>.', tag, parentNode.nodeName.toLowerCase());
8301 }
8302}
8303
8304function warnForInsertedHydratedText(parentNode, text) {
8305 {
8306 if (text === '') {
8307 // We expect to insert empty text nodes since they're not represented in
8308 // the HTML.
8309 // TODO: Remove this special case if we can just avoid inserting empty
8310 // text nodes.
8311 return;
8312 }
8313 if (didWarnInvalidHydration) {
8314 return;
8315 }
8316 didWarnInvalidHydration = true;
8317 warningWithoutStack$1(false, 'Expected server HTML to contain a matching text node for "%s" in <%s>.', text, parentNode.nodeName.toLowerCase());
8318 }
8319}
8320
8321function restoreControlledState$1(domElement, tag, props) {
8322 switch (tag) {
8323 case 'input':
8324 restoreControlledState(domElement, props);
8325 return;
8326 case 'textarea':
8327 restoreControlledState$3(domElement, props);
8328 return;
8329 case 'select':
8330 restoreControlledState$2(domElement, props);
8331 return;
8332 }
8333}
8334
8335// TODO: direct imports like some-package/src/* are bad. Fix me.
8336var validateDOMNesting = function () {};
8337var updatedAncestorInfo = function () {};
8338
8339{
8340 // This validation code was written based on the HTML5 parsing spec:
8341 // https://html.spec.whatwg.org/multipage/syntax.html#has-an-element-in-scope
8342 //
8343 // Note: this does not catch all invalid nesting, nor does it try to (as it's
8344 // not clear what practical benefit doing so provides); instead, we warn only
8345 // for cases where the parser will give a parse tree differing from what React
8346 // intended. For example, <b><div></div></b> is invalid but we don't warn
8347 // because it still parses correctly; we do warn for other cases like nested
8348 // <p> tags where the beginning of the second element implicitly closes the
8349 // first, causing a confusing mess.
8350
8351 // https://html.spec.whatwg.org/multipage/syntax.html#special
8352 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'];
8353
8354 // https://html.spec.whatwg.org/multipage/syntax.html#has-an-element-in-scope
8355 var inScopeTags = ['applet', 'caption', 'html', 'table', 'td', 'th', 'marquee', 'object', 'template',
8356
8357 // https://html.spec.whatwg.org/multipage/syntax.html#html-integration-point
8358 // TODO: Distinguish by namespace here -- for <title>, including it here
8359 // errs on the side of fewer warnings
8360 'foreignObject', 'desc', 'title'];
8361
8362 // https://html.spec.whatwg.org/multipage/syntax.html#has-an-element-in-button-scope
8363 var buttonScopeTags = inScopeTags.concat(['button']);
8364
8365 // https://html.spec.whatwg.org/multipage/syntax.html#generate-implied-end-tags
8366 var impliedEndTags = ['dd', 'dt', 'li', 'option', 'optgroup', 'p', 'rp', 'rt'];
8367
8368 var emptyAncestorInfo = {
8369 current: null,
8370
8371 formTag: null,
8372 aTagInScope: null,
8373 buttonTagInScope: null,
8374 nobrTagInScope: null,
8375 pTagInButtonScope: null,
8376
8377 listItemTagAutoclosing: null,
8378 dlItemTagAutoclosing: null
8379 };
8380
8381 updatedAncestorInfo = function (oldInfo, tag) {
8382 var ancestorInfo = _assign({}, oldInfo || emptyAncestorInfo);
8383 var info = { tag: tag };
8384
8385 if (inScopeTags.indexOf(tag) !== -1) {
8386 ancestorInfo.aTagInScope = null;
8387 ancestorInfo.buttonTagInScope = null;
8388 ancestorInfo.nobrTagInScope = null;
8389 }
8390 if (buttonScopeTags.indexOf(tag) !== -1) {
8391 ancestorInfo.pTagInButtonScope = null;
8392 }
8393
8394 // See rules for 'li', 'dd', 'dt' start tags in
8395 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inbody
8396 if (specialTags.indexOf(tag) !== -1 && tag !== 'address' && tag !== 'div' && tag !== 'p') {
8397 ancestorInfo.listItemTagAutoclosing = null;
8398 ancestorInfo.dlItemTagAutoclosing = null;
8399 }
8400
8401 ancestorInfo.current = info;
8402
8403 if (tag === 'form') {
8404 ancestorInfo.formTag = info;
8405 }
8406 if (tag === 'a') {
8407 ancestorInfo.aTagInScope = info;
8408 }
8409 if (tag === 'button') {
8410 ancestorInfo.buttonTagInScope = info;
8411 }
8412 if (tag === 'nobr') {
8413 ancestorInfo.nobrTagInScope = info;
8414 }
8415 if (tag === 'p') {
8416 ancestorInfo.pTagInButtonScope = info;
8417 }
8418 if (tag === 'li') {
8419 ancestorInfo.listItemTagAutoclosing = info;
8420 }
8421 if (tag === 'dd' || tag === 'dt') {
8422 ancestorInfo.dlItemTagAutoclosing = info;
8423 }
8424
8425 return ancestorInfo;
8426 };
8427
8428 /**
8429 * Returns whether
8430 */
8431 var isTagValidWithParent = function (tag, parentTag) {
8432 // First, let's check if we're in an unusual parsing mode...
8433 switch (parentTag) {
8434 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inselect
8435 case 'select':
8436 return tag === 'option' || tag === 'optgroup' || tag === '#text';
8437 case 'optgroup':
8438 return tag === 'option' || tag === '#text';
8439 // Strictly speaking, seeing an <option> doesn't mean we're in a <select>
8440 // but
8441 case 'option':
8442 return tag === '#text';
8443 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intd
8444 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-incaption
8445 // No special behavior since these rules fall back to "in body" mode for
8446 // all except special table nodes which cause bad parsing behavior anyway.
8447
8448 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intr
8449 case 'tr':
8450 return tag === 'th' || tag === 'td' || tag === 'style' || tag === 'script' || tag === 'template';
8451 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intbody
8452 case 'tbody':
8453 case 'thead':
8454 case 'tfoot':
8455 return tag === 'tr' || tag === 'style' || tag === 'script' || tag === 'template';
8456 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-incolgroup
8457 case 'colgroup':
8458 return tag === 'col' || tag === 'template';
8459 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intable
8460 case 'table':
8461 return tag === 'caption' || tag === 'colgroup' || tag === 'tbody' || tag === 'tfoot' || tag === 'thead' || tag === 'style' || tag === 'script' || tag === 'template';
8462 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inhead
8463 case 'head':
8464 return tag === 'base' || tag === 'basefont' || tag === 'bgsound' || tag === 'link' || tag === 'meta' || tag === 'title' || tag === 'noscript' || tag === 'noframes' || tag === 'style' || tag === 'script' || tag === 'template';
8465 // https://html.spec.whatwg.org/multipage/semantics.html#the-html-element
8466 case 'html':
8467 return tag === 'head' || tag === 'body';
8468 case '#document':
8469 return tag === 'html';
8470 }
8471
8472 // Probably in the "in body" parsing mode, so we outlaw only tag combos
8473 // where the parsing rules cause implicit opens or closes to be added.
8474 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inbody
8475 switch (tag) {
8476 case 'h1':
8477 case 'h2':
8478 case 'h3':
8479 case 'h4':
8480 case 'h5':
8481 case 'h6':
8482 return parentTag !== 'h1' && parentTag !== 'h2' && parentTag !== 'h3' && parentTag !== 'h4' && parentTag !== 'h5' && parentTag !== 'h6';
8483
8484 case 'rp':
8485 case 'rt':
8486 return impliedEndTags.indexOf(parentTag) === -1;
8487
8488 case 'body':
8489 case 'caption':
8490 case 'col':
8491 case 'colgroup':
8492 case 'frame':
8493 case 'head':
8494 case 'html':
8495 case 'tbody':
8496 case 'td':
8497 case 'tfoot':
8498 case 'th':
8499 case 'thead':
8500 case 'tr':
8501 // These tags are only valid with a few parents that have special child
8502 // parsing rules -- if we're down here, then none of those matched and
8503 // so we allow it only if we don't know what the parent is, as all other
8504 // cases are invalid.
8505 return parentTag == null;
8506 }
8507
8508 return true;
8509 };
8510
8511 /**
8512 * Returns whether
8513 */
8514 var findInvalidAncestorForTag = function (tag, ancestorInfo) {
8515 switch (tag) {
8516 case 'address':
8517 case 'article':
8518 case 'aside':
8519 case 'blockquote':
8520 case 'center':
8521 case 'details':
8522 case 'dialog':
8523 case 'dir':
8524 case 'div':
8525 case 'dl':
8526 case 'fieldset':
8527 case 'figcaption':
8528 case 'figure':
8529 case 'footer':
8530 case 'header':
8531 case 'hgroup':
8532 case 'main':
8533 case 'menu':
8534 case 'nav':
8535 case 'ol':
8536 case 'p':
8537 case 'section':
8538 case 'summary':
8539 case 'ul':
8540 case 'pre':
8541 case 'listing':
8542 case 'table':
8543 case 'hr':
8544 case 'xmp':
8545 case 'h1':
8546 case 'h2':
8547 case 'h3':
8548 case 'h4':
8549 case 'h5':
8550 case 'h6':
8551 return ancestorInfo.pTagInButtonScope;
8552
8553 case 'form':
8554 return ancestorInfo.formTag || ancestorInfo.pTagInButtonScope;
8555
8556 case 'li':
8557 return ancestorInfo.listItemTagAutoclosing;
8558
8559 case 'dd':
8560 case 'dt':
8561 return ancestorInfo.dlItemTagAutoclosing;
8562
8563 case 'button':
8564 return ancestorInfo.buttonTagInScope;
8565
8566 case 'a':
8567 // Spec says something about storing a list of markers, but it sounds
8568 // equivalent to this check.
8569 return ancestorInfo.aTagInScope;
8570
8571 case 'nobr':
8572 return ancestorInfo.nobrTagInScope;
8573 }
8574
8575 return null;
8576 };
8577
8578 var didWarn = {};
8579
8580 validateDOMNesting = function (childTag, childText, ancestorInfo) {
8581 ancestorInfo = ancestorInfo || emptyAncestorInfo;
8582 var parentInfo = ancestorInfo.current;
8583 var parentTag = parentInfo && parentInfo.tag;
8584
8585 if (childText != null) {
8586 !(childTag == null) ? warningWithoutStack$1(false, 'validateDOMNesting: when childText is passed, childTag should be null') : void 0;
8587 childTag = '#text';
8588 }
8589
8590 var invalidParent = isTagValidWithParent(childTag, parentTag) ? null : parentInfo;
8591 var invalidAncestor = invalidParent ? null : findInvalidAncestorForTag(childTag, ancestorInfo);
8592 var invalidParentOrAncestor = invalidParent || invalidAncestor;
8593 if (!invalidParentOrAncestor) {
8594 return;
8595 }
8596
8597 var ancestorTag = invalidParentOrAncestor.tag;
8598 var addendum = getCurrentFiberStackInDev();
8599
8600 var warnKey = !!invalidParent + '|' + childTag + '|' + ancestorTag + '|' + addendum;
8601 if (didWarn[warnKey]) {
8602 return;
8603 }
8604 didWarn[warnKey] = true;
8605
8606 var tagDisplayName = childTag;
8607 var whitespaceInfo = '';
8608 if (childTag === '#text') {
8609 if (/\S/.test(childText)) {
8610 tagDisplayName = 'Text nodes';
8611 } else {
8612 tagDisplayName = 'Whitespace text nodes';
8613 whitespaceInfo = " Make sure you don't have any extra whitespace between tags on " + 'each line of your source code.';
8614 }
8615 } else {
8616 tagDisplayName = '<' + childTag + '>';
8617 }
8618
8619 if (invalidParent) {
8620 var info = '';
8621 if (ancestorTag === 'table' && childTag === 'tr') {
8622 info += ' Add a <tbody> to your code to match the DOM tree generated by ' + 'the browser.';
8623 }
8624 warningWithoutStack$1(false, 'validateDOMNesting(...): %s cannot appear as a child of <%s>.%s%s%s', tagDisplayName, ancestorTag, whitespaceInfo, info, addendum);
8625 } else {
8626 warningWithoutStack$1(false, 'validateDOMNesting(...): %s cannot appear as a descendant of ' + '<%s>.%s', tagDisplayName, ancestorTag, addendum);
8627 }
8628 };
8629}
8630
8631// Renderers that don't support persistence
8632// can re-export everything from this module.
8633
8634function shim() {
8635 invariant(false, 'The current renderer does not support persistence. This error is likely caused by a bug in React. Please file an issue.');
8636}
8637
8638// Persistence (when unsupported)
8639var supportsPersistence = false;
8640var cloneInstance = shim;
8641var createContainerChildSet = shim;
8642var appendChildToContainerChildSet = shim;
8643var finalizeContainerChildren = shim;
8644var replaceContainerChildren = shim;
8645var cloneHiddenInstance = shim;
8646var cloneUnhiddenInstance = shim;
8647var createHiddenTextInstance = shim;
8648
8649var SUPPRESS_HYDRATION_WARNING = void 0;
8650{
8651 SUPPRESS_HYDRATION_WARNING = 'suppressHydrationWarning';
8652}
8653
8654var SUSPENSE_START_DATA = '$';
8655var SUSPENSE_END_DATA = '/$';
8656
8657var STYLE = 'style';
8658
8659var eventsEnabled = null;
8660var selectionInformation = null;
8661
8662function shouldAutoFocusHostComponent(type, props) {
8663 switch (type) {
8664 case 'button':
8665 case 'input':
8666 case 'select':
8667 case 'textarea':
8668 return !!props.autoFocus;
8669 }
8670 return false;
8671}
8672
8673function getRootHostContext(rootContainerInstance) {
8674 var type = void 0;
8675 var namespace = void 0;
8676 var nodeType = rootContainerInstance.nodeType;
8677 switch (nodeType) {
8678 case DOCUMENT_NODE:
8679 case DOCUMENT_FRAGMENT_NODE:
8680 {
8681 type = nodeType === DOCUMENT_NODE ? '#document' : '#fragment';
8682 var root = rootContainerInstance.documentElement;
8683 namespace = root ? root.namespaceURI : getChildNamespace(null, '');
8684 break;
8685 }
8686 default:
8687 {
8688 var container = nodeType === COMMENT_NODE ? rootContainerInstance.parentNode : rootContainerInstance;
8689 var ownNamespace = container.namespaceURI || null;
8690 type = container.tagName;
8691 namespace = getChildNamespace(ownNamespace, type);
8692 break;
8693 }
8694 }
8695 {
8696 var validatedTag = type.toLowerCase();
8697 var _ancestorInfo = updatedAncestorInfo(null, validatedTag);
8698 return { namespace: namespace, ancestorInfo: _ancestorInfo };
8699 }
8700 return namespace;
8701}
8702
8703function getChildHostContext(parentHostContext, type, rootContainerInstance) {
8704 {
8705 var parentHostContextDev = parentHostContext;
8706 var _namespace = getChildNamespace(parentHostContextDev.namespace, type);
8707 var _ancestorInfo2 = updatedAncestorInfo(parentHostContextDev.ancestorInfo, type);
8708 return { namespace: _namespace, ancestorInfo: _ancestorInfo2 };
8709 }
8710 var parentNamespace = parentHostContext;
8711 return getChildNamespace(parentNamespace, type);
8712}
8713
8714function getPublicInstance(instance) {
8715 return instance;
8716}
8717
8718function prepareForCommit(containerInfo) {
8719 eventsEnabled = isEnabled();
8720 selectionInformation = getSelectionInformation();
8721 setEnabled(false);
8722}
8723
8724function resetAfterCommit(containerInfo) {
8725 restoreSelection(selectionInformation);
8726 selectionInformation = null;
8727 setEnabled(eventsEnabled);
8728 eventsEnabled = null;
8729}
8730
8731function createInstance(type, props, rootContainerInstance, hostContext, internalInstanceHandle) {
8732 var parentNamespace = void 0;
8733 {
8734 // TODO: take namespace into account when validating.
8735 var hostContextDev = hostContext;
8736 validateDOMNesting(type, null, hostContextDev.ancestorInfo);
8737 if (typeof props.children === 'string' || typeof props.children === 'number') {
8738 var string = '' + props.children;
8739 var ownAncestorInfo = updatedAncestorInfo(hostContextDev.ancestorInfo, type);
8740 validateDOMNesting(null, string, ownAncestorInfo);
8741 }
8742 parentNamespace = hostContextDev.namespace;
8743 }
8744 var domElement = createElement(type, props, rootContainerInstance, parentNamespace);
8745 precacheFiberNode(internalInstanceHandle, domElement);
8746 updateFiberProps(domElement, props);
8747 return domElement;
8748}
8749
8750function appendInitialChild(parentInstance, child) {
8751 parentInstance.appendChild(child);
8752}
8753
8754function finalizeInitialChildren(domElement, type, props, rootContainerInstance, hostContext) {
8755 setInitialProperties(domElement, type, props, rootContainerInstance);
8756 return shouldAutoFocusHostComponent(type, props);
8757}
8758
8759function prepareUpdate(domElement, type, oldProps, newProps, rootContainerInstance, hostContext) {
8760 {
8761 var hostContextDev = hostContext;
8762 if (typeof newProps.children !== typeof oldProps.children && (typeof newProps.children === 'string' || typeof newProps.children === 'number')) {
8763 var string = '' + newProps.children;
8764 var ownAncestorInfo = updatedAncestorInfo(hostContextDev.ancestorInfo, type);
8765 validateDOMNesting(null, string, ownAncestorInfo);
8766 }
8767 }
8768 return diffProperties(domElement, type, oldProps, newProps, rootContainerInstance);
8769}
8770
8771function shouldSetTextContent(type, props) {
8772 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;
8773}
8774
8775function shouldDeprioritizeSubtree(type, props) {
8776 return !!props.hidden;
8777}
8778
8779function createTextInstance(text, rootContainerInstance, hostContext, internalInstanceHandle) {
8780 {
8781 var hostContextDev = hostContext;
8782 validateDOMNesting(null, text, hostContextDev.ancestorInfo);
8783 }
8784 var textNode = createTextNode(text, rootContainerInstance);
8785 precacheFiberNode(internalInstanceHandle, textNode);
8786 return textNode;
8787}
8788
8789var isPrimaryRenderer = true;
8790// This initialization code may run even on server environments
8791// if a component just imports ReactDOM (e.g. for findDOMNode).
8792// Some environments might not have setTimeout or clearTimeout.
8793var scheduleTimeout = typeof setTimeout === 'function' ? setTimeout : undefined;
8794var cancelTimeout = typeof clearTimeout === 'function' ? clearTimeout : undefined;
8795var noTimeout = -1;
8796var schedulePassiveEffects = scheduler.unstable_scheduleCallback;
8797var cancelPassiveEffects = scheduler.unstable_cancelCallback;
8798
8799// -------------------
8800// Mutation
8801// -------------------
8802
8803var supportsMutation = true;
8804
8805function commitMount(domElement, type, newProps, internalInstanceHandle) {
8806 // Despite the naming that might imply otherwise, this method only
8807 // fires if there is an `Update` effect scheduled during mounting.
8808 // This happens if `finalizeInitialChildren` returns `true` (which it
8809 // does to implement the `autoFocus` attribute on the client). But
8810 // there are also other cases when this might happen (such as patching
8811 // up text content during hydration mismatch). So we'll check this again.
8812 if (shouldAutoFocusHostComponent(type, newProps)) {
8813 domElement.focus();
8814 }
8815}
8816
8817function commitUpdate(domElement, updatePayload, type, oldProps, newProps, internalInstanceHandle) {
8818 // Update the props handle so that we know which props are the ones with
8819 // with current event handlers.
8820 updateFiberProps(domElement, newProps);
8821 // Apply the diff to the DOM node.
8822 updateProperties(domElement, updatePayload, type, oldProps, newProps);
8823}
8824
8825function resetTextContent(domElement) {
8826 setTextContent(domElement, '');
8827}
8828
8829function commitTextUpdate(textInstance, oldText, newText) {
8830 textInstance.nodeValue = newText;
8831}
8832
8833function appendChild(parentInstance, child) {
8834 parentInstance.appendChild(child);
8835}
8836
8837function appendChildToContainer(container, child) {
8838 var parentNode = void 0;
8839 if (container.nodeType === COMMENT_NODE) {
8840 parentNode = container.parentNode;
8841 parentNode.insertBefore(child, container);
8842 } else {
8843 parentNode = container;
8844 parentNode.appendChild(child);
8845 }
8846 // This container might be used for a portal.
8847 // If something inside a portal is clicked, that click should bubble
8848 // through the React tree. However, on Mobile Safari the click would
8849 // never bubble through the *DOM* tree unless an ancestor with onclick
8850 // event exists. So we wouldn't see it and dispatch it.
8851 // This is why we ensure that non React root containers have inline onclick
8852 // defined.
8853 // https://github.com/facebook/react/issues/11918
8854 var reactRootContainer = container._reactRootContainer;
8855 if ((reactRootContainer === null || reactRootContainer === undefined) && parentNode.onclick === null) {
8856 // TODO: This cast may not be sound for SVG, MathML or custom elements.
8857 trapClickOnNonInteractiveElement(parentNode);
8858 }
8859}
8860
8861function insertBefore(parentInstance, child, beforeChild) {
8862 parentInstance.insertBefore(child, beforeChild);
8863}
8864
8865function insertInContainerBefore(container, child, beforeChild) {
8866 if (container.nodeType === COMMENT_NODE) {
8867 container.parentNode.insertBefore(child, beforeChild);
8868 } else {
8869 container.insertBefore(child, beforeChild);
8870 }
8871}
8872
8873function removeChild(parentInstance, child) {
8874 parentInstance.removeChild(child);
8875}
8876
8877function removeChildFromContainer(container, child) {
8878 if (container.nodeType === COMMENT_NODE) {
8879 container.parentNode.removeChild(child);
8880 } else {
8881 container.removeChild(child);
8882 }
8883}
8884
8885function clearSuspenseBoundary(parentInstance, suspenseInstance) {
8886 var node = suspenseInstance;
8887 // Delete all nodes within this suspense boundary.
8888 // There might be nested nodes so we need to keep track of how
8889 // deep we are and only break out when we're back on top.
8890 var depth = 0;
8891 do {
8892 var nextNode = node.nextSibling;
8893 parentInstance.removeChild(node);
8894 if (nextNode && nextNode.nodeType === COMMENT_NODE) {
8895 var data = nextNode.data;
8896 if (data === SUSPENSE_END_DATA) {
8897 if (depth === 0) {
8898 parentInstance.removeChild(nextNode);
8899 return;
8900 } else {
8901 depth--;
8902 }
8903 } else if (data === SUSPENSE_START_DATA) {
8904 depth++;
8905 }
8906 }
8907 node = nextNode;
8908 } while (node);
8909 // TODO: Warn, we didn't find the end comment boundary.
8910}
8911
8912function clearSuspenseBoundaryFromContainer(container, suspenseInstance) {
8913 if (container.nodeType === COMMENT_NODE) {
8914 clearSuspenseBoundary(container.parentNode, suspenseInstance);
8915 } else if (container.nodeType === ELEMENT_NODE) {
8916 clearSuspenseBoundary(container, suspenseInstance);
8917 } else {
8918 // Document nodes should never contain suspense boundaries.
8919 }
8920}
8921
8922function hideInstance(instance) {
8923 // TODO: Does this work for all element types? What about MathML? Should we
8924 // pass host context to this method?
8925 instance = instance;
8926 instance.style.display = 'none';
8927}
8928
8929function hideTextInstance(textInstance) {
8930 textInstance.nodeValue = '';
8931}
8932
8933function unhideInstance(instance, props) {
8934 instance = instance;
8935 var styleProp = props[STYLE];
8936 var display = styleProp !== undefined && styleProp !== null && styleProp.hasOwnProperty('display') ? styleProp.display : null;
8937 instance.style.display = dangerousStyleValue('display', display);
8938}
8939
8940function unhideTextInstance(textInstance, text) {
8941 textInstance.nodeValue = text;
8942}
8943
8944// -------------------
8945// Hydration
8946// -------------------
8947
8948var supportsHydration = true;
8949
8950function canHydrateInstance(instance, type, props) {
8951 if (instance.nodeType !== ELEMENT_NODE || type.toLowerCase() !== instance.nodeName.toLowerCase()) {
8952 return null;
8953 }
8954 // This has now been refined to an element node.
8955 return instance;
8956}
8957
8958function canHydrateTextInstance(instance, text) {
8959 if (text === '' || instance.nodeType !== TEXT_NODE) {
8960 // Empty strings are not parsed by HTML so there won't be a correct match here.
8961 return null;
8962 }
8963 // This has now been refined to a text node.
8964 return instance;
8965}
8966
8967function canHydrateSuspenseInstance(instance) {
8968 if (instance.nodeType !== COMMENT_NODE) {
8969 // Empty strings are not parsed by HTML so there won't be a correct match here.
8970 return null;
8971 }
8972 // This has now been refined to a suspense node.
8973 return instance;
8974}
8975
8976function getNextHydratableSibling(instance) {
8977 var node = instance.nextSibling;
8978 // Skip non-hydratable nodes.
8979 while (node && node.nodeType !== ELEMENT_NODE && node.nodeType !== TEXT_NODE && (!enableSuspenseServerRenderer || node.nodeType !== COMMENT_NODE || node.data !== SUSPENSE_START_DATA)) {
8980 node = node.nextSibling;
8981 }
8982 return node;
8983}
8984
8985function getFirstHydratableChild(parentInstance) {
8986 var next = parentInstance.firstChild;
8987 // Skip non-hydratable nodes.
8988 while (next && next.nodeType !== ELEMENT_NODE && next.nodeType !== TEXT_NODE && (!enableSuspenseServerRenderer || next.nodeType !== COMMENT_NODE || next.data !== SUSPENSE_START_DATA)) {
8989 next = next.nextSibling;
8990 }
8991 return next;
8992}
8993
8994function hydrateInstance(instance, type, props, rootContainerInstance, hostContext, internalInstanceHandle) {
8995 precacheFiberNode(internalInstanceHandle, instance);
8996 // TODO: Possibly defer this until the commit phase where all the events
8997 // get attached.
8998 updateFiberProps(instance, props);
8999 var parentNamespace = void 0;
9000 {
9001 var hostContextDev = hostContext;
9002 parentNamespace = hostContextDev.namespace;
9003 }
9004 return diffHydratedProperties(instance, type, props, parentNamespace, rootContainerInstance);
9005}
9006
9007function hydrateTextInstance(textInstance, text, internalInstanceHandle) {
9008 precacheFiberNode(internalInstanceHandle, textInstance);
9009 return diffHydratedText(textInstance, text);
9010}
9011
9012function getNextHydratableInstanceAfterSuspenseInstance(suspenseInstance) {
9013 var node = suspenseInstance.nextSibling;
9014 // Skip past all nodes within this suspense boundary.
9015 // There might be nested nodes so we need to keep track of how
9016 // deep we are and only break out when we're back on top.
9017 var depth = 0;
9018 while (node) {
9019 if (node.nodeType === COMMENT_NODE) {
9020 var data = node.data;
9021 if (data === SUSPENSE_END_DATA) {
9022 if (depth === 0) {
9023 return getNextHydratableSibling(node);
9024 } else {
9025 depth--;
9026 }
9027 } else if (data === SUSPENSE_START_DATA) {
9028 depth++;
9029 }
9030 }
9031 node = node.nextSibling;
9032 }
9033 // TODO: Warn, we didn't find the end comment boundary.
9034 return null;
9035}
9036
9037function didNotMatchHydratedContainerTextInstance(parentContainer, textInstance, text) {
9038 {
9039 warnForUnmatchedText(textInstance, text);
9040 }
9041}
9042
9043function didNotMatchHydratedTextInstance(parentType, parentProps, parentInstance, textInstance, text) {
9044 if (true && parentProps[SUPPRESS_HYDRATION_WARNING] !== true) {
9045 warnForUnmatchedText(textInstance, text);
9046 }
9047}
9048
9049function didNotHydrateContainerInstance(parentContainer, instance) {
9050 {
9051 if (instance.nodeType === ELEMENT_NODE) {
9052 warnForDeletedHydratableElement(parentContainer, instance);
9053 } else if (instance.nodeType === COMMENT_NODE) {
9054 // TODO: warnForDeletedHydratableSuspenseBoundary
9055 } else {
9056 warnForDeletedHydratableText(parentContainer, instance);
9057 }
9058 }
9059}
9060
9061function didNotHydrateInstance(parentType, parentProps, parentInstance, instance) {
9062 if (true && parentProps[SUPPRESS_HYDRATION_WARNING] !== true) {
9063 if (instance.nodeType === ELEMENT_NODE) {
9064 warnForDeletedHydratableElement(parentInstance, instance);
9065 } else if (instance.nodeType === COMMENT_NODE) {
9066 // TODO: warnForDeletedHydratableSuspenseBoundary
9067 } else {
9068 warnForDeletedHydratableText(parentInstance, instance);
9069 }
9070 }
9071}
9072
9073function didNotFindHydratableContainerInstance(parentContainer, type, props) {
9074 {
9075 warnForInsertedHydratedElement(parentContainer, type, props);
9076 }
9077}
9078
9079function didNotFindHydratableContainerTextInstance(parentContainer, text) {
9080 {
9081 warnForInsertedHydratedText(parentContainer, text);
9082 }
9083}
9084
9085
9086
9087function didNotFindHydratableInstance(parentType, parentProps, parentInstance, type, props) {
9088 if (true && parentProps[SUPPRESS_HYDRATION_WARNING] !== true) {
9089 warnForInsertedHydratedElement(parentInstance, type, props);
9090 }
9091}
9092
9093function didNotFindHydratableTextInstance(parentType, parentProps, parentInstance, text) {
9094 if (true && parentProps[SUPPRESS_HYDRATION_WARNING] !== true) {
9095 warnForInsertedHydratedText(parentInstance, text);
9096 }
9097}
9098
9099function didNotFindHydratableSuspenseInstance(parentType, parentProps, parentInstance) {
9100 if (true && parentProps[SUPPRESS_HYDRATION_WARNING] !== true) {
9101 // TODO: warnForInsertedHydratedSuspense(parentInstance);
9102 }
9103}
9104
9105// This is just to get the setup running.
9106// TODO: real implementation.
9107// console.log('Hello from Fire host config.');
9108
9109// Prefix measurements so that it's possible to filter them.
9110// Longer prefixes are hard to read in DevTools.
9111var reactEmoji = '\u269B';
9112var warningEmoji = '\u26D4';
9113var supportsUserTiming = typeof performance !== 'undefined' && typeof performance.mark === 'function' && typeof performance.clearMarks === 'function' && typeof performance.measure === 'function' && typeof performance.clearMeasures === 'function';
9114
9115// Keep track of current fiber so that we know the path to unwind on pause.
9116// TODO: this looks the same as nextUnitOfWork in scheduler. Can we unify them?
9117var currentFiber = null;
9118// If we're in the middle of user code, which fiber and method is it?
9119// Reusing `currentFiber` would be confusing for this because user code fiber
9120// can change during commit phase too, but we don't need to unwind it (since
9121// lifecycles in the commit phase don't resemble a tree).
9122var currentPhase = null;
9123var currentPhaseFiber = null;
9124// Did lifecycle hook schedule an update? This is often a performance problem,
9125// so we will keep track of it, and include it in the report.
9126// Track commits caused by cascading updates.
9127var isCommitting = false;
9128var hasScheduledUpdateInCurrentCommit = false;
9129var hasScheduledUpdateInCurrentPhase = false;
9130var commitCountInCurrentWorkLoop = 0;
9131var effectCountInCurrentCommit = 0;
9132var isWaitingForCallback = false;
9133// During commits, we only show a measurement once per method name
9134// to avoid stretch the commit phase with measurement overhead.
9135var labelsInCurrentCommit = new Set();
9136
9137var formatMarkName = function (markName) {
9138 return reactEmoji + ' ' + markName;
9139};
9140
9141var formatLabel = function (label, warning) {
9142 var prefix = warning ? warningEmoji + ' ' : reactEmoji + ' ';
9143 var suffix = warning ? ' Warning: ' + warning : '';
9144 return '' + prefix + label + suffix;
9145};
9146
9147var beginMark = function (markName) {
9148 performance.mark(formatMarkName(markName));
9149};
9150
9151var clearMark = function (markName) {
9152 performance.clearMarks(formatMarkName(markName));
9153};
9154
9155var endMark = function (label, markName, warning) {
9156 var formattedMarkName = formatMarkName(markName);
9157 var formattedLabel = formatLabel(label, warning);
9158 try {
9159 performance.measure(formattedLabel, formattedMarkName);
9160 } catch (err) {}
9161 // If previous mark was missing for some reason, this will throw.
9162 // This could only happen if React crashed in an unexpected place earlier.
9163 // Don't pile on with more errors.
9164
9165 // Clear marks immediately to avoid growing buffer.
9166 performance.clearMarks(formattedMarkName);
9167 performance.clearMeasures(formattedLabel);
9168};
9169
9170var getFiberMarkName = function (label, debugID) {
9171 return label + ' (#' + debugID + ')';
9172};
9173
9174var getFiberLabel = function (componentName, isMounted, phase) {
9175 if (phase === null) {
9176 // These are composite component total time measurements.
9177 return componentName + ' [' + (isMounted ? 'update' : 'mount') + ']';
9178 } else {
9179 // Composite component methods.
9180 return componentName + '.' + phase;
9181 }
9182};
9183
9184var beginFiberMark = function (fiber, phase) {
9185 var componentName = getComponentName(fiber.type) || 'Unknown';
9186 var debugID = fiber._debugID;
9187 var isMounted = fiber.alternate !== null;
9188 var label = getFiberLabel(componentName, isMounted, phase);
9189
9190 if (isCommitting && labelsInCurrentCommit.has(label)) {
9191 // During the commit phase, we don't show duplicate labels because
9192 // there is a fixed overhead for every measurement, and we don't
9193 // want to stretch the commit phase beyond necessary.
9194 return false;
9195 }
9196 labelsInCurrentCommit.add(label);
9197
9198 var markName = getFiberMarkName(label, debugID);
9199 beginMark(markName);
9200 return true;
9201};
9202
9203var clearFiberMark = function (fiber, phase) {
9204 var componentName = getComponentName(fiber.type) || 'Unknown';
9205 var debugID = fiber._debugID;
9206 var isMounted = fiber.alternate !== null;
9207 var label = getFiberLabel(componentName, isMounted, phase);
9208 var markName = getFiberMarkName(label, debugID);
9209 clearMark(markName);
9210};
9211
9212var endFiberMark = function (fiber, phase, warning) {
9213 var componentName = getComponentName(fiber.type) || 'Unknown';
9214 var debugID = fiber._debugID;
9215 var isMounted = fiber.alternate !== null;
9216 var label = getFiberLabel(componentName, isMounted, phase);
9217 var markName = getFiberMarkName(label, debugID);
9218 endMark(label, markName, warning);
9219};
9220
9221var shouldIgnoreFiber = function (fiber) {
9222 // Host components should be skipped in the timeline.
9223 // We could check typeof fiber.type, but does this work with RN?
9224 switch (fiber.tag) {
9225 case HostRoot:
9226 case HostComponent:
9227 case HostText:
9228 case HostPortal:
9229 case Fragment:
9230 case ContextProvider:
9231 case ContextConsumer:
9232 case Mode:
9233 return true;
9234 default:
9235 return false;
9236 }
9237};
9238
9239var clearPendingPhaseMeasurement = function () {
9240 if (currentPhase !== null && currentPhaseFiber !== null) {
9241 clearFiberMark(currentPhaseFiber, currentPhase);
9242 }
9243 currentPhaseFiber = null;
9244 currentPhase = null;
9245 hasScheduledUpdateInCurrentPhase = false;
9246};
9247
9248var pauseTimers = function () {
9249 // Stops all currently active measurements so that they can be resumed
9250 // if we continue in a later deferred loop from the same unit of work.
9251 var fiber = currentFiber;
9252 while (fiber) {
9253 if (fiber._debugIsCurrentlyTiming) {
9254 endFiberMark(fiber, null, null);
9255 }
9256 fiber = fiber.return;
9257 }
9258};
9259
9260var resumeTimersRecursively = function (fiber) {
9261 if (fiber.return !== null) {
9262 resumeTimersRecursively(fiber.return);
9263 }
9264 if (fiber._debugIsCurrentlyTiming) {
9265 beginFiberMark(fiber, null);
9266 }
9267};
9268
9269var resumeTimers = function () {
9270 // Resumes all measurements that were active during the last deferred loop.
9271 if (currentFiber !== null) {
9272 resumeTimersRecursively(currentFiber);
9273 }
9274};
9275
9276function recordEffect() {
9277 if (enableUserTimingAPI) {
9278 effectCountInCurrentCommit++;
9279 }
9280}
9281
9282function recordScheduleUpdate() {
9283 if (enableUserTimingAPI) {
9284 if (isCommitting) {
9285 hasScheduledUpdateInCurrentCommit = true;
9286 }
9287 if (currentPhase !== null && currentPhase !== 'componentWillMount' && currentPhase !== 'componentWillReceiveProps') {
9288 hasScheduledUpdateInCurrentPhase = true;
9289 }
9290 }
9291}
9292
9293function startRequestCallbackTimer() {
9294 if (enableUserTimingAPI) {
9295 if (supportsUserTiming && !isWaitingForCallback) {
9296 isWaitingForCallback = true;
9297 beginMark('(Waiting for async callback...)');
9298 }
9299 }
9300}
9301
9302function stopRequestCallbackTimer(didExpire, expirationTime) {
9303 if (enableUserTimingAPI) {
9304 if (supportsUserTiming) {
9305 isWaitingForCallback = false;
9306 var warning = didExpire ? 'React was blocked by main thread' : null;
9307 endMark('(Waiting for async callback... will force flush in ' + expirationTime + ' ms)', '(Waiting for async callback...)', warning);
9308 }
9309 }
9310}
9311
9312function startWorkTimer(fiber) {
9313 if (enableUserTimingAPI) {
9314 if (!supportsUserTiming || shouldIgnoreFiber(fiber)) {
9315 return;
9316 }
9317 // If we pause, this is the fiber to unwind from.
9318 currentFiber = fiber;
9319 if (!beginFiberMark(fiber, null)) {
9320 return;
9321 }
9322 fiber._debugIsCurrentlyTiming = true;
9323 }
9324}
9325
9326function cancelWorkTimer(fiber) {
9327 if (enableUserTimingAPI) {
9328 if (!supportsUserTiming || shouldIgnoreFiber(fiber)) {
9329 return;
9330 }
9331 // Remember we shouldn't complete measurement for this fiber.
9332 // Otherwise flamechart will be deep even for small updates.
9333 fiber._debugIsCurrentlyTiming = false;
9334 clearFiberMark(fiber, null);
9335 }
9336}
9337
9338function stopWorkTimer(fiber) {
9339 if (enableUserTimingAPI) {
9340 if (!supportsUserTiming || shouldIgnoreFiber(fiber)) {
9341 return;
9342 }
9343 // If we pause, its parent is the fiber to unwind from.
9344 currentFiber = fiber.return;
9345 if (!fiber._debugIsCurrentlyTiming) {
9346 return;
9347 }
9348 fiber._debugIsCurrentlyTiming = false;
9349 endFiberMark(fiber, null, null);
9350 }
9351}
9352
9353function stopFailedWorkTimer(fiber) {
9354 if (enableUserTimingAPI) {
9355 if (!supportsUserTiming || shouldIgnoreFiber(fiber)) {
9356 return;
9357 }
9358 // If we pause, its parent is the fiber to unwind from.
9359 currentFiber = fiber.return;
9360 if (!fiber._debugIsCurrentlyTiming) {
9361 return;
9362 }
9363 fiber._debugIsCurrentlyTiming = false;
9364 var warning = fiber.tag === SuspenseComponent || fiber.tag === DehydratedSuspenseComponent ? 'Rendering was suspended' : 'An error was thrown inside this error boundary';
9365 endFiberMark(fiber, null, warning);
9366 }
9367}
9368
9369function startPhaseTimer(fiber, phase) {
9370 if (enableUserTimingAPI) {
9371 if (!supportsUserTiming) {
9372 return;
9373 }
9374 clearPendingPhaseMeasurement();
9375 if (!beginFiberMark(fiber, phase)) {
9376 return;
9377 }
9378 currentPhaseFiber = fiber;
9379 currentPhase = phase;
9380 }
9381}
9382
9383function stopPhaseTimer() {
9384 if (enableUserTimingAPI) {
9385 if (!supportsUserTiming) {
9386 return;
9387 }
9388 if (currentPhase !== null && currentPhaseFiber !== null) {
9389 var warning = hasScheduledUpdateInCurrentPhase ? 'Scheduled a cascading update' : null;
9390 endFiberMark(currentPhaseFiber, currentPhase, warning);
9391 }
9392 currentPhase = null;
9393 currentPhaseFiber = null;
9394 }
9395}
9396
9397function startWorkLoopTimer(nextUnitOfWork) {
9398 if (enableUserTimingAPI) {
9399 currentFiber = nextUnitOfWork;
9400 if (!supportsUserTiming) {
9401 return;
9402 }
9403 commitCountInCurrentWorkLoop = 0;
9404 // This is top level call.
9405 // Any other measurements are performed within.
9406 beginMark('(React Tree Reconciliation)');
9407 // Resume any measurements that were in progress during the last loop.
9408 resumeTimers();
9409 }
9410}
9411
9412function stopWorkLoopTimer(interruptedBy, didCompleteRoot) {
9413 if (enableUserTimingAPI) {
9414 if (!supportsUserTiming) {
9415 return;
9416 }
9417 var warning = null;
9418 if (interruptedBy !== null) {
9419 if (interruptedBy.tag === HostRoot) {
9420 warning = 'A top-level update interrupted the previous render';
9421 } else {
9422 var componentName = getComponentName(interruptedBy.type) || 'Unknown';
9423 warning = 'An update to ' + componentName + ' interrupted the previous render';
9424 }
9425 } else if (commitCountInCurrentWorkLoop > 1) {
9426 warning = 'There were cascading updates';
9427 }
9428 commitCountInCurrentWorkLoop = 0;
9429 var label = didCompleteRoot ? '(React Tree Reconciliation: Completed Root)' : '(React Tree Reconciliation: Yielded)';
9430 // Pause any measurements until the next loop.
9431 pauseTimers();
9432 endMark(label, '(React Tree Reconciliation)', warning);
9433 }
9434}
9435
9436function startCommitTimer() {
9437 if (enableUserTimingAPI) {
9438 if (!supportsUserTiming) {
9439 return;
9440 }
9441 isCommitting = true;
9442 hasScheduledUpdateInCurrentCommit = false;
9443 labelsInCurrentCommit.clear();
9444 beginMark('(Committing Changes)');
9445 }
9446}
9447
9448function stopCommitTimer() {
9449 if (enableUserTimingAPI) {
9450 if (!supportsUserTiming) {
9451 return;
9452 }
9453
9454 var warning = null;
9455 if (hasScheduledUpdateInCurrentCommit) {
9456 warning = 'Lifecycle hook scheduled a cascading update';
9457 } else if (commitCountInCurrentWorkLoop > 0) {
9458 warning = 'Caused by a cascading update in earlier commit';
9459 }
9460 hasScheduledUpdateInCurrentCommit = false;
9461 commitCountInCurrentWorkLoop++;
9462 isCommitting = false;
9463 labelsInCurrentCommit.clear();
9464
9465 endMark('(Committing Changes)', '(Committing Changes)', warning);
9466 }
9467}
9468
9469function startCommitSnapshotEffectsTimer() {
9470 if (enableUserTimingAPI) {
9471 if (!supportsUserTiming) {
9472 return;
9473 }
9474 effectCountInCurrentCommit = 0;
9475 beginMark('(Committing Snapshot Effects)');
9476 }
9477}
9478
9479function stopCommitSnapshotEffectsTimer() {
9480 if (enableUserTimingAPI) {
9481 if (!supportsUserTiming) {
9482 return;
9483 }
9484 var count = effectCountInCurrentCommit;
9485 effectCountInCurrentCommit = 0;
9486 endMark('(Committing Snapshot Effects: ' + count + ' Total)', '(Committing Snapshot Effects)', null);
9487 }
9488}
9489
9490function startCommitHostEffectsTimer() {
9491 if (enableUserTimingAPI) {
9492 if (!supportsUserTiming) {
9493 return;
9494 }
9495 effectCountInCurrentCommit = 0;
9496 beginMark('(Committing Host Effects)');
9497 }
9498}
9499
9500function stopCommitHostEffectsTimer() {
9501 if (enableUserTimingAPI) {
9502 if (!supportsUserTiming) {
9503 return;
9504 }
9505 var count = effectCountInCurrentCommit;
9506 effectCountInCurrentCommit = 0;
9507 endMark('(Committing Host Effects: ' + count + ' Total)', '(Committing Host Effects)', null);
9508 }
9509}
9510
9511function startCommitLifeCyclesTimer() {
9512 if (enableUserTimingAPI) {
9513 if (!supportsUserTiming) {
9514 return;
9515 }
9516 effectCountInCurrentCommit = 0;
9517 beginMark('(Calling Lifecycle Methods)');
9518 }
9519}
9520
9521function stopCommitLifeCyclesTimer() {
9522 if (enableUserTimingAPI) {
9523 if (!supportsUserTiming) {
9524 return;
9525 }
9526 var count = effectCountInCurrentCommit;
9527 effectCountInCurrentCommit = 0;
9528 endMark('(Calling Lifecycle Methods: ' + count + ' Total)', '(Calling Lifecycle Methods)', null);
9529 }
9530}
9531
9532var valueStack = [];
9533
9534var fiberStack = void 0;
9535
9536{
9537 fiberStack = [];
9538}
9539
9540var index = -1;
9541
9542function createCursor(defaultValue) {
9543 return {
9544 current: defaultValue
9545 };
9546}
9547
9548function pop(cursor, fiber) {
9549 if (index < 0) {
9550 {
9551 warningWithoutStack$1(false, 'Unexpected pop.');
9552 }
9553 return;
9554 }
9555
9556 {
9557 if (fiber !== fiberStack[index]) {
9558 warningWithoutStack$1(false, 'Unexpected Fiber popped.');
9559 }
9560 }
9561
9562 cursor.current = valueStack[index];
9563
9564 valueStack[index] = null;
9565
9566 {
9567 fiberStack[index] = null;
9568 }
9569
9570 index--;
9571}
9572
9573function push(cursor, value, fiber) {
9574 index++;
9575
9576 valueStack[index] = cursor.current;
9577
9578 {
9579 fiberStack[index] = fiber;
9580 }
9581
9582 cursor.current = value;
9583}
9584
9585function checkThatStackIsEmpty() {
9586 {
9587 if (index !== -1) {
9588 warningWithoutStack$1(false, 'Expected an empty stack. Something was not reset properly.');
9589 }
9590 }
9591}
9592
9593function resetStackAfterFatalErrorInDev() {
9594 {
9595 index = -1;
9596 valueStack.length = 0;
9597 fiberStack.length = 0;
9598 }
9599}
9600
9601var warnedAboutMissingGetChildContext = void 0;
9602
9603{
9604 warnedAboutMissingGetChildContext = {};
9605}
9606
9607var emptyContextObject = {};
9608{
9609 Object.freeze(emptyContextObject);
9610}
9611
9612// A cursor to the current merged context object on the stack.
9613var contextStackCursor = createCursor(emptyContextObject);
9614// A cursor to a boolean indicating whether the context has changed.
9615var didPerformWorkStackCursor = createCursor(false);
9616// Keep track of the previous context object that was on the stack.
9617// We use this to get access to the parent context after we have already
9618// pushed the next context provider, and now need to merge their contexts.
9619var previousContext = emptyContextObject;
9620
9621function getUnmaskedContext(workInProgress, Component, didPushOwnContextIfProvider) {
9622 if (didPushOwnContextIfProvider && isContextProvider(Component)) {
9623 // If the fiber is a context provider itself, when we read its context
9624 // we may have already pushed its own child context on the stack. A context
9625 // provider should not "see" its own child context. Therefore we read the
9626 // previous (parent) context instead for a context provider.
9627 return previousContext;
9628 }
9629 return contextStackCursor.current;
9630}
9631
9632function cacheContext(workInProgress, unmaskedContext, maskedContext) {
9633 var instance = workInProgress.stateNode;
9634 instance.__reactInternalMemoizedUnmaskedChildContext = unmaskedContext;
9635 instance.__reactInternalMemoizedMaskedChildContext = maskedContext;
9636}
9637
9638function getMaskedContext(workInProgress, unmaskedContext) {
9639 var type = workInProgress.type;
9640 var contextTypes = type.contextTypes;
9641 if (!contextTypes) {
9642 return emptyContextObject;
9643 }
9644
9645 // Avoid recreating masked context unless unmasked context has changed.
9646 // Failing to do this will result in unnecessary calls to componentWillReceiveProps.
9647 // This may trigger infinite loops if componentWillReceiveProps calls setState.
9648 var instance = workInProgress.stateNode;
9649 if (instance && instance.__reactInternalMemoizedUnmaskedChildContext === unmaskedContext) {
9650 return instance.__reactInternalMemoizedMaskedChildContext;
9651 }
9652
9653 var context = {};
9654 for (var key in contextTypes) {
9655 context[key] = unmaskedContext[key];
9656 }
9657
9658 {
9659 var name = getComponentName(type) || 'Unknown';
9660 checkPropTypes(contextTypes, context, 'context', name, getCurrentFiberStackInDev);
9661 }
9662
9663 // Cache unmasked context so we can avoid recreating masked context unless necessary.
9664 // Context is created before the class component is instantiated so check for instance.
9665 if (instance) {
9666 cacheContext(workInProgress, unmaskedContext, context);
9667 }
9668
9669 return context;
9670}
9671
9672function hasContextChanged() {
9673 return didPerformWorkStackCursor.current;
9674}
9675
9676function isContextProvider(type) {
9677 var childContextTypes = type.childContextTypes;
9678 return childContextTypes !== null && childContextTypes !== undefined;
9679}
9680
9681function popContext(fiber) {
9682 pop(didPerformWorkStackCursor, fiber);
9683 pop(contextStackCursor, fiber);
9684}
9685
9686function popTopLevelContextObject(fiber) {
9687 pop(didPerformWorkStackCursor, fiber);
9688 pop(contextStackCursor, fiber);
9689}
9690
9691function pushTopLevelContextObject(fiber, context, didChange) {
9692 !(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;
9693
9694 push(contextStackCursor, context, fiber);
9695 push(didPerformWorkStackCursor, didChange, fiber);
9696}
9697
9698function processChildContext(fiber, type, parentContext) {
9699 var instance = fiber.stateNode;
9700 var childContextTypes = type.childContextTypes;
9701
9702 // TODO (bvaughn) Replace this behavior with an invariant() in the future.
9703 // It has only been added in Fiber to match the (unintentional) behavior in Stack.
9704 if (typeof instance.getChildContext !== 'function') {
9705 {
9706 var componentName = getComponentName(type) || 'Unknown';
9707
9708 if (!warnedAboutMissingGetChildContext[componentName]) {
9709 warnedAboutMissingGetChildContext[componentName] = true;
9710 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);
9711 }
9712 }
9713 return parentContext;
9714 }
9715
9716 var childContext = void 0;
9717 {
9718 setCurrentPhase('getChildContext');
9719 }
9720 startPhaseTimer(fiber, 'getChildContext');
9721 childContext = instance.getChildContext();
9722 stopPhaseTimer();
9723 {
9724 setCurrentPhase(null);
9725 }
9726 for (var contextKey in childContext) {
9727 !(contextKey in childContextTypes) ? invariant(false, '%s.getChildContext(): key "%s" is not defined in childContextTypes.', getComponentName(type) || 'Unknown', contextKey) : void 0;
9728 }
9729 {
9730 var name = getComponentName(type) || 'Unknown';
9731 checkPropTypes(childContextTypes, childContext, 'child context', name,
9732 // In practice, there is one case in which we won't get a stack. It's when
9733 // somebody calls unstable_renderSubtreeIntoContainer() and we process
9734 // context from the parent component instance. The stack will be missing
9735 // because it's outside of the reconciliation, and so the pointer has not
9736 // been set. This is rare and doesn't matter. We'll also remove that API.
9737 getCurrentFiberStackInDev);
9738 }
9739
9740 return _assign({}, parentContext, childContext);
9741}
9742
9743function pushContextProvider(workInProgress) {
9744 var instance = workInProgress.stateNode;
9745 // We push the context as early as possible to ensure stack integrity.
9746 // If the instance does not exist yet, we will push null at first,
9747 // and replace it on the stack later when invalidating the context.
9748 var memoizedMergedChildContext = instance && instance.__reactInternalMemoizedMergedChildContext || emptyContextObject;
9749
9750 // Remember the parent context so we can merge with it later.
9751 // Inherit the parent's did-perform-work value to avoid inadvertently blocking updates.
9752 previousContext = contextStackCursor.current;
9753 push(contextStackCursor, memoizedMergedChildContext, workInProgress);
9754 push(didPerformWorkStackCursor, didPerformWorkStackCursor.current, workInProgress);
9755
9756 return true;
9757}
9758
9759function invalidateContextProvider(workInProgress, type, didChange) {
9760 var instance = workInProgress.stateNode;
9761 !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;
9762
9763 if (didChange) {
9764 // Merge parent and own context.
9765 // Skip this if we're not updating due to sCU.
9766 // This avoids unnecessarily recomputing memoized values.
9767 var mergedContext = processChildContext(workInProgress, type, previousContext);
9768 instance.__reactInternalMemoizedMergedChildContext = mergedContext;
9769
9770 // Replace the old (or empty) context with the new one.
9771 // It is important to unwind the context in the reverse order.
9772 pop(didPerformWorkStackCursor, workInProgress);
9773 pop(contextStackCursor, workInProgress);
9774 // Now push the new context and mark that it has changed.
9775 push(contextStackCursor, mergedContext, workInProgress);
9776 push(didPerformWorkStackCursor, didChange, workInProgress);
9777 } else {
9778 pop(didPerformWorkStackCursor, workInProgress);
9779 push(didPerformWorkStackCursor, didChange, workInProgress);
9780 }
9781}
9782
9783function findCurrentUnmaskedContext(fiber) {
9784 // Currently this is only used with renderSubtreeIntoContainer; not sure if it
9785 // makes sense elsewhere
9786 !(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;
9787
9788 var node = fiber;
9789 do {
9790 switch (node.tag) {
9791 case HostRoot:
9792 return node.stateNode.context;
9793 case ClassComponent:
9794 {
9795 var Component = node.type;
9796 if (isContextProvider(Component)) {
9797 return node.stateNode.__reactInternalMemoizedMergedChildContext;
9798 }
9799 break;
9800 }
9801 }
9802 node = node.return;
9803 } while (node !== null);
9804 invariant(false, 'Found unexpected detached subtree parent. This error is likely caused by a bug in React. Please file an issue.');
9805}
9806
9807var onCommitFiberRoot = null;
9808var onCommitFiberUnmount = null;
9809var hasLoggedError = false;
9810
9811function catchErrors(fn) {
9812 return function (arg) {
9813 try {
9814 return fn(arg);
9815 } catch (err) {
9816 if (true && !hasLoggedError) {
9817 hasLoggedError = true;
9818 warningWithoutStack$1(false, 'React DevTools encountered an error: %s', err);
9819 }
9820 }
9821 };
9822}
9823
9824var isDevToolsPresent = typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ !== 'undefined';
9825
9826function injectInternals(internals) {
9827 if (typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ === 'undefined') {
9828 // No DevTools
9829 return false;
9830 }
9831 var hook = __REACT_DEVTOOLS_GLOBAL_HOOK__;
9832 if (hook.isDisabled) {
9833 // This isn't a real property on the hook, but it can be set to opt out
9834 // of DevTools integration and associated warnings and logs.
9835 // https://github.com/facebook/react/issues/3877
9836 return true;
9837 }
9838 if (!hook.supportsFiber) {
9839 {
9840 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');
9841 }
9842 // DevTools exists, even though it doesn't support Fiber.
9843 return true;
9844 }
9845 try {
9846 var rendererID = hook.inject(internals);
9847 // We have successfully injected, so now it is safe to set up hooks.
9848 onCommitFiberRoot = catchErrors(function (root) {
9849 return hook.onCommitFiberRoot(rendererID, root);
9850 });
9851 onCommitFiberUnmount = catchErrors(function (fiber) {
9852 return hook.onCommitFiberUnmount(rendererID, fiber);
9853 });
9854 } catch (err) {
9855 // Catch all errors because it is unsafe to throw during initialization.
9856 {
9857 warningWithoutStack$1(false, 'React DevTools encountered an error: %s.', err);
9858 }
9859 }
9860 // DevTools exists
9861 return true;
9862}
9863
9864function onCommitRoot(root) {
9865 if (typeof onCommitFiberRoot === 'function') {
9866 onCommitFiberRoot(root);
9867 }
9868}
9869
9870function onCommitUnmount(fiber) {
9871 if (typeof onCommitFiberUnmount === 'function') {
9872 onCommitFiberUnmount(fiber);
9873 }
9874}
9875
9876// Max 31 bit integer. The max integer size in V8 for 32-bit systems.
9877// Math.pow(2, 30) - 1
9878// 0b111111111111111111111111111111
9879var maxSigned31BitInt = 1073741823;
9880
9881var NoWork = 0;
9882var Never = 1;
9883var Sync = maxSigned31BitInt;
9884
9885var UNIT_SIZE = 10;
9886var MAGIC_NUMBER_OFFSET = maxSigned31BitInt - 1;
9887
9888// 1 unit of expiration time represents 10ms.
9889function msToExpirationTime(ms) {
9890 // Always add an offset so that we don't clash with the magic number for NoWork.
9891 return MAGIC_NUMBER_OFFSET - (ms / UNIT_SIZE | 0);
9892}
9893
9894function expirationTimeToMs(expirationTime) {
9895 return (MAGIC_NUMBER_OFFSET - expirationTime) * UNIT_SIZE;
9896}
9897
9898function ceiling(num, precision) {
9899 return ((num / precision | 0) + 1) * precision;
9900}
9901
9902function computeExpirationBucket(currentTime, expirationInMs, bucketSizeMs) {
9903 return MAGIC_NUMBER_OFFSET - ceiling(MAGIC_NUMBER_OFFSET - currentTime + expirationInMs / UNIT_SIZE, bucketSizeMs / UNIT_SIZE);
9904}
9905
9906var LOW_PRIORITY_EXPIRATION = 5000;
9907var LOW_PRIORITY_BATCH_SIZE = 250;
9908
9909function computeAsyncExpiration(currentTime) {
9910 return computeExpirationBucket(currentTime, LOW_PRIORITY_EXPIRATION, LOW_PRIORITY_BATCH_SIZE);
9911}
9912
9913// We intentionally set a higher expiration time for interactive updates in
9914// dev than in production.
9915//
9916// If the main thread is being blocked so long that you hit the expiration,
9917// it's a problem that could be solved with better scheduling.
9918//
9919// People will be more likely to notice this and fix it with the long
9920// expiration time in development.
9921//
9922// In production we opt for better UX at the risk of masking scheduling
9923// problems, by expiring fast.
9924var HIGH_PRIORITY_EXPIRATION = 500;
9925var HIGH_PRIORITY_BATCH_SIZE = 100;
9926
9927function computeInteractiveExpiration(currentTime) {
9928 return computeExpirationBucket(currentTime, HIGH_PRIORITY_EXPIRATION, HIGH_PRIORITY_BATCH_SIZE);
9929}
9930
9931var NoContext = 0;
9932var ConcurrentMode = 1;
9933var StrictMode = 2;
9934var ProfileMode = 4;
9935
9936var hasBadMapPolyfill = void 0;
9937
9938{
9939 hasBadMapPolyfill = false;
9940 try {
9941 var nonExtensibleObject = Object.preventExtensions({});
9942 var testMap = new Map([[nonExtensibleObject, null]]);
9943 var testSet = new Set([nonExtensibleObject]);
9944 // This is necessary for Rollup to not consider these unused.
9945 // https://github.com/rollup/rollup/issues/1771
9946 // TODO: we can remove these if Rollup fixes the bug.
9947 testMap.set(0, 0);
9948 testSet.add(0);
9949 } catch (e) {
9950 // TODO: Consider warning about bad polyfills
9951 hasBadMapPolyfill = true;
9952 }
9953}
9954
9955// A Fiber is work on a Component that needs to be done or was done. There can
9956// be more than one per component.
9957
9958
9959var debugCounter = void 0;
9960
9961{
9962 debugCounter = 1;
9963}
9964
9965function FiberNode(tag, pendingProps, key, mode) {
9966 // Instance
9967 this.tag = tag;
9968 this.key = key;
9969 this.elementType = null;
9970 this.type = null;
9971 this.stateNode = null;
9972
9973 // Fiber
9974 this.return = null;
9975 this.child = null;
9976 this.sibling = null;
9977 this.index = 0;
9978
9979 this.ref = null;
9980
9981 this.pendingProps = pendingProps;
9982 this.memoizedProps = null;
9983 this.updateQueue = null;
9984 this.memoizedState = null;
9985 this.contextDependencies = null;
9986
9987 this.mode = mode;
9988
9989 // Effects
9990 this.effectTag = NoEffect;
9991 this.nextEffect = null;
9992
9993 this.firstEffect = null;
9994 this.lastEffect = null;
9995
9996 this.expirationTime = NoWork;
9997 this.childExpirationTime = NoWork;
9998
9999 this.alternate = null;
10000
10001 if (enableProfilerTimer) {
10002 // Note: The following is done to avoid a v8 performance cliff.
10003 //
10004 // Initializing the fields below to smis and later updating them with
10005 // double values will cause Fibers to end up having separate shapes.
10006 // This behavior/bug has something to do with Object.preventExtension().
10007 // Fortunately this only impacts DEV builds.
10008 // Unfortunately it makes React unusably slow for some applications.
10009 // To work around this, initialize the fields below with doubles.
10010 //
10011 // Learn more about this here:
10012 // https://github.com/facebook/react/issues/14365
10013 // https://bugs.chromium.org/p/v8/issues/detail?id=8538
10014 this.actualDuration = Number.NaN;
10015 this.actualStartTime = Number.NaN;
10016 this.selfBaseDuration = Number.NaN;
10017 this.treeBaseDuration = Number.NaN;
10018
10019 // It's okay to replace the initial doubles with smis after initialization.
10020 // This won't trigger the performance cliff mentioned above,
10021 // and it simplifies other profiler code (including DevTools).
10022 this.actualDuration = 0;
10023 this.actualStartTime = -1;
10024 this.selfBaseDuration = 0;
10025 this.treeBaseDuration = 0;
10026 }
10027
10028 {
10029 this._debugID = debugCounter++;
10030 this._debugSource = null;
10031 this._debugOwner = null;
10032 this._debugIsCurrentlyTiming = false;
10033 this._debugHookTypes = null;
10034 if (!hasBadMapPolyfill && typeof Object.preventExtensions === 'function') {
10035 Object.preventExtensions(this);
10036 }
10037 }
10038}
10039
10040// This is a constructor function, rather than a POJO constructor, still
10041// please ensure we do the following:
10042// 1) Nobody should add any instance methods on this. Instance methods can be
10043// more difficult to predict when they get optimized and they are almost
10044// never inlined properly in static compilers.
10045// 2) Nobody should rely on `instanceof Fiber` for type testing. We should
10046// always know when it is a fiber.
10047// 3) We might want to experiment with using numeric keys since they are easier
10048// to optimize in a non-JIT environment.
10049// 4) We can easily go from a constructor to a createFiber object literal if that
10050// is faster.
10051// 5) It should be easy to port this to a C struct and keep a C implementation
10052// compatible.
10053var createFiber = function (tag, pendingProps, key, mode) {
10054 // $FlowFixMe: the shapes are exact here but Flow doesn't like constructors
10055 return new FiberNode(tag, pendingProps, key, mode);
10056};
10057
10058function shouldConstruct(Component) {
10059 var prototype = Component.prototype;
10060 return !!(prototype && prototype.isReactComponent);
10061}
10062
10063function isSimpleFunctionComponent(type) {
10064 return typeof type === 'function' && !shouldConstruct(type) && type.defaultProps === undefined;
10065}
10066
10067function resolveLazyComponentTag(Component) {
10068 if (typeof Component === 'function') {
10069 return shouldConstruct(Component) ? ClassComponent : FunctionComponent;
10070 } else if (Component !== undefined && Component !== null) {
10071 var $$typeof = Component.$$typeof;
10072 if ($$typeof === REACT_FORWARD_REF_TYPE) {
10073 return ForwardRef;
10074 }
10075 if ($$typeof === REACT_MEMO_TYPE) {
10076 return MemoComponent;
10077 }
10078 }
10079 return IndeterminateComponent;
10080}
10081
10082// This is used to create an alternate fiber to do work on.
10083function createWorkInProgress(current, pendingProps, expirationTime) {
10084 var workInProgress = current.alternate;
10085 if (workInProgress === null) {
10086 // We use a double buffering pooling technique because we know that we'll
10087 // only ever need at most two versions of a tree. We pool the "other" unused
10088 // node that we're free to reuse. This is lazily created to avoid allocating
10089 // extra objects for things that are never updated. It also allow us to
10090 // reclaim the extra memory if needed.
10091 workInProgress = createFiber(current.tag, pendingProps, current.key, current.mode);
10092 workInProgress.elementType = current.elementType;
10093 workInProgress.type = current.type;
10094 workInProgress.stateNode = current.stateNode;
10095
10096 {
10097 // DEV-only fields
10098 workInProgress._debugID = current._debugID;
10099 workInProgress._debugSource = current._debugSource;
10100 workInProgress._debugOwner = current._debugOwner;
10101 workInProgress._debugHookTypes = current._debugHookTypes;
10102 }
10103
10104 workInProgress.alternate = current;
10105 current.alternate = workInProgress;
10106 } else {
10107 workInProgress.pendingProps = pendingProps;
10108
10109 // We already have an alternate.
10110 // Reset the effect tag.
10111 workInProgress.effectTag = NoEffect;
10112
10113 // The effect list is no longer valid.
10114 workInProgress.nextEffect = null;
10115 workInProgress.firstEffect = null;
10116 workInProgress.lastEffect = null;
10117
10118 if (enableProfilerTimer) {
10119 // We intentionally reset, rather than copy, actualDuration & actualStartTime.
10120 // This prevents time from endlessly accumulating in new commits.
10121 // This has the downside of resetting values for different priority renders,
10122 // But works for yielding (the common case) and should support resuming.
10123 workInProgress.actualDuration = 0;
10124 workInProgress.actualStartTime = -1;
10125 }
10126 }
10127
10128 workInProgress.childExpirationTime = current.childExpirationTime;
10129 workInProgress.expirationTime = current.expirationTime;
10130
10131 workInProgress.child = current.child;
10132 workInProgress.memoizedProps = current.memoizedProps;
10133 workInProgress.memoizedState = current.memoizedState;
10134 workInProgress.updateQueue = current.updateQueue;
10135 workInProgress.contextDependencies = current.contextDependencies;
10136
10137 // These will be overridden during the parent's reconciliation
10138 workInProgress.sibling = current.sibling;
10139 workInProgress.index = current.index;
10140 workInProgress.ref = current.ref;
10141
10142 if (enableProfilerTimer) {
10143 workInProgress.selfBaseDuration = current.selfBaseDuration;
10144 workInProgress.treeBaseDuration = current.treeBaseDuration;
10145 }
10146
10147 return workInProgress;
10148}
10149
10150function createHostRootFiber(isConcurrent) {
10151 var mode = isConcurrent ? ConcurrentMode | StrictMode : NoContext;
10152
10153 if (enableProfilerTimer && isDevToolsPresent) {
10154 // Always collect profile timings when DevTools are present.
10155 // This enables DevTools to start capturing timing at any point–
10156 // Without some nodes in the tree having empty base times.
10157 mode |= ProfileMode;
10158 }
10159
10160 return createFiber(HostRoot, null, null, mode);
10161}
10162
10163function createFiberFromTypeAndProps(type, // React$ElementType
10164key, pendingProps, owner, mode, expirationTime) {
10165 var fiber = void 0;
10166
10167 var fiberTag = IndeterminateComponent;
10168 // The resolved type is set if we know what the final type will be. I.e. it's not lazy.
10169 var resolvedType = type;
10170 if (typeof type === 'function') {
10171 if (shouldConstruct(type)) {
10172 fiberTag = ClassComponent;
10173 }
10174 } else if (typeof type === 'string') {
10175 fiberTag = HostComponent;
10176 } else {
10177 getTag: switch (type) {
10178 case REACT_FRAGMENT_TYPE:
10179 return createFiberFromFragment(pendingProps.children, mode, expirationTime, key);
10180 case REACT_CONCURRENT_MODE_TYPE:
10181 return createFiberFromMode(pendingProps, mode | ConcurrentMode | StrictMode, expirationTime, key);
10182 case REACT_STRICT_MODE_TYPE:
10183 return createFiberFromMode(pendingProps, mode | StrictMode, expirationTime, key);
10184 case REACT_PROFILER_TYPE:
10185 return createFiberFromProfiler(pendingProps, mode, expirationTime, key);
10186 case REACT_SUSPENSE_TYPE:
10187 return createFiberFromSuspense(pendingProps, mode, expirationTime, key);
10188 default:
10189 {
10190 if (typeof type === 'object' && type !== null) {
10191 switch (type.$$typeof) {
10192 case REACT_PROVIDER_TYPE:
10193 fiberTag = ContextProvider;
10194 break getTag;
10195 case REACT_CONTEXT_TYPE:
10196 // This is a consumer
10197 fiberTag = ContextConsumer;
10198 break getTag;
10199 case REACT_FORWARD_REF_TYPE:
10200 fiberTag = ForwardRef;
10201 break getTag;
10202 case REACT_MEMO_TYPE:
10203 fiberTag = MemoComponent;
10204 break getTag;
10205 case REACT_LAZY_TYPE:
10206 fiberTag = LazyComponent;
10207 resolvedType = null;
10208 break getTag;
10209 }
10210 }
10211 var info = '';
10212 {
10213 if (type === undefined || typeof type === 'object' && type !== null && Object.keys(type).length === 0) {
10214 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.';
10215 }
10216 var ownerName = owner ? getComponentName(owner.type) : null;
10217 if (ownerName) {
10218 info += '\n\nCheck the render method of `' + ownerName + '`.';
10219 }
10220 }
10221 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);
10222 }
10223 }
10224 }
10225
10226 fiber = createFiber(fiberTag, pendingProps, key, mode);
10227 fiber.elementType = type;
10228 fiber.type = resolvedType;
10229 fiber.expirationTime = expirationTime;
10230
10231 return fiber;
10232}
10233
10234function createFiberFromElement(element, mode, expirationTime) {
10235 var owner = null;
10236 {
10237 owner = element._owner;
10238 }
10239 var type = element.type;
10240 var key = element.key;
10241 var pendingProps = element.props;
10242 var fiber = createFiberFromTypeAndProps(type, key, pendingProps, owner, mode, expirationTime);
10243 {
10244 fiber._debugSource = element._source;
10245 fiber._debugOwner = element._owner;
10246 }
10247 return fiber;
10248}
10249
10250function createFiberFromFragment(elements, mode, expirationTime, key) {
10251 var fiber = createFiber(Fragment, elements, key, mode);
10252 fiber.expirationTime = expirationTime;
10253 return fiber;
10254}
10255
10256function createFiberFromProfiler(pendingProps, mode, expirationTime, key) {
10257 {
10258 if (typeof pendingProps.id !== 'string' || typeof pendingProps.onRender !== 'function') {
10259 warningWithoutStack$1(false, 'Profiler must specify an "id" string and "onRender" function as props');
10260 }
10261 }
10262
10263 var fiber = createFiber(Profiler, pendingProps, key, mode | ProfileMode);
10264 // TODO: The Profiler fiber shouldn't have a type. It has a tag.
10265 fiber.elementType = REACT_PROFILER_TYPE;
10266 fiber.type = REACT_PROFILER_TYPE;
10267 fiber.expirationTime = expirationTime;
10268
10269 return fiber;
10270}
10271
10272function createFiberFromMode(pendingProps, mode, expirationTime, key) {
10273 var fiber = createFiber(Mode, pendingProps, key, mode);
10274
10275 // TODO: The Mode fiber shouldn't have a type. It has a tag.
10276 var type = (mode & ConcurrentMode) === NoContext ? REACT_STRICT_MODE_TYPE : REACT_CONCURRENT_MODE_TYPE;
10277 fiber.elementType = type;
10278 fiber.type = type;
10279
10280 fiber.expirationTime = expirationTime;
10281 return fiber;
10282}
10283
10284function createFiberFromSuspense(pendingProps, mode, expirationTime, key) {
10285 var fiber = createFiber(SuspenseComponent, pendingProps, key, mode);
10286
10287 // TODO: The SuspenseComponent fiber shouldn't have a type. It has a tag.
10288 var type = REACT_SUSPENSE_TYPE;
10289 fiber.elementType = type;
10290 fiber.type = type;
10291
10292 fiber.expirationTime = expirationTime;
10293 return fiber;
10294}
10295
10296function createFiberFromText(content, mode, expirationTime) {
10297 var fiber = createFiber(HostText, content, null, mode);
10298 fiber.expirationTime = expirationTime;
10299 return fiber;
10300}
10301
10302function createFiberFromHostInstanceForDeletion() {
10303 var fiber = createFiber(HostComponent, null, null, NoContext);
10304 // TODO: These should not need a type.
10305 fiber.elementType = 'DELETED';
10306 fiber.type = 'DELETED';
10307 return fiber;
10308}
10309
10310function createFiberFromPortal(portal, mode, expirationTime) {
10311 var pendingProps = portal.children !== null ? portal.children : [];
10312 var fiber = createFiber(HostPortal, pendingProps, portal.key, mode);
10313 fiber.expirationTime = expirationTime;
10314 fiber.stateNode = {
10315 containerInfo: portal.containerInfo,
10316 pendingChildren: null, // Used by persistent updates
10317 implementation: portal.implementation
10318 };
10319 return fiber;
10320}
10321
10322// Used for stashing WIP properties to replay failed work in DEV.
10323function assignFiberPropertiesInDEV(target, source) {
10324 if (target === null) {
10325 // This Fiber's initial properties will always be overwritten.
10326 // We only use a Fiber to ensure the same hidden class so DEV isn't slow.
10327 target = createFiber(IndeterminateComponent, null, null, NoContext);
10328 }
10329
10330 // This is intentionally written as a list of all properties.
10331 // We tried to use Object.assign() instead but this is called in
10332 // the hottest path, and Object.assign() was too slow:
10333 // https://github.com/facebook/react/issues/12502
10334 // This code is DEV-only so size is not a concern.
10335
10336 target.tag = source.tag;
10337 target.key = source.key;
10338 target.elementType = source.elementType;
10339 target.type = source.type;
10340 target.stateNode = source.stateNode;
10341 target.return = source.return;
10342 target.child = source.child;
10343 target.sibling = source.sibling;
10344 target.index = source.index;
10345 target.ref = source.ref;
10346 target.pendingProps = source.pendingProps;
10347 target.memoizedProps = source.memoizedProps;
10348 target.updateQueue = source.updateQueue;
10349 target.memoizedState = source.memoizedState;
10350 target.contextDependencies = source.contextDependencies;
10351 target.mode = source.mode;
10352 target.effectTag = source.effectTag;
10353 target.nextEffect = source.nextEffect;
10354 target.firstEffect = source.firstEffect;
10355 target.lastEffect = source.lastEffect;
10356 target.expirationTime = source.expirationTime;
10357 target.childExpirationTime = source.childExpirationTime;
10358 target.alternate = source.alternate;
10359 if (enableProfilerTimer) {
10360 target.actualDuration = source.actualDuration;
10361 target.actualStartTime = source.actualStartTime;
10362 target.selfBaseDuration = source.selfBaseDuration;
10363 target.treeBaseDuration = source.treeBaseDuration;
10364 }
10365 target._debugID = source._debugID;
10366 target._debugSource = source._debugSource;
10367 target._debugOwner = source._debugOwner;
10368 target._debugIsCurrentlyTiming = source._debugIsCurrentlyTiming;
10369 target._debugHookTypes = source._debugHookTypes;
10370 return target;
10371}
10372
10373// TODO: This should be lifted into the renderer.
10374
10375
10376// The following attributes are only used by interaction tracing builds.
10377// They enable interactions to be associated with their async work,
10378// And expose interaction metadata to the React DevTools Profiler plugin.
10379// Note that these attributes are only defined when the enableSchedulerTracing flag is enabled.
10380
10381
10382// Exported FiberRoot type includes all properties,
10383// To avoid requiring potentially error-prone :any casts throughout the project.
10384// Profiling properties are only safe to access in profiling builds (when enableSchedulerTracing is true).
10385// The types are defined separately within this file to ensure they stay in sync.
10386// (We don't have to use an inline :any cast when enableSchedulerTracing is disabled.)
10387
10388
10389function createFiberRoot(containerInfo, isConcurrent, hydrate) {
10390 // Cyclic construction. This cheats the type system right now because
10391 // stateNode is any.
10392 var uninitializedFiber = createHostRootFiber(isConcurrent);
10393
10394 var root = void 0;
10395 if (enableSchedulerTracing) {
10396 root = {
10397 current: uninitializedFiber,
10398 containerInfo: containerInfo,
10399 pendingChildren: null,
10400
10401 earliestPendingTime: NoWork,
10402 latestPendingTime: NoWork,
10403 earliestSuspendedTime: NoWork,
10404 latestSuspendedTime: NoWork,
10405 latestPingedTime: NoWork,
10406
10407 pingCache: null,
10408
10409 didError: false,
10410
10411 pendingCommitExpirationTime: NoWork,
10412 finishedWork: null,
10413 timeoutHandle: noTimeout,
10414 context: null,
10415 pendingContext: null,
10416 hydrate: hydrate,
10417 nextExpirationTimeToWorkOn: NoWork,
10418 expirationTime: NoWork,
10419 firstBatch: null,
10420 nextScheduledRoot: null,
10421
10422 interactionThreadID: tracing.unstable_getThreadID(),
10423 memoizedInteractions: new Set(),
10424 pendingInteractionMap: new Map()
10425 };
10426 } else {
10427 root = {
10428 current: uninitializedFiber,
10429 containerInfo: containerInfo,
10430 pendingChildren: null,
10431
10432 pingCache: null,
10433
10434 earliestPendingTime: NoWork,
10435 latestPendingTime: NoWork,
10436 earliestSuspendedTime: NoWork,
10437 latestSuspendedTime: NoWork,
10438 latestPingedTime: NoWork,
10439
10440 didError: false,
10441
10442 pendingCommitExpirationTime: NoWork,
10443 finishedWork: null,
10444 timeoutHandle: noTimeout,
10445 context: null,
10446 pendingContext: null,
10447 hydrate: hydrate,
10448 nextExpirationTimeToWorkOn: NoWork,
10449 expirationTime: NoWork,
10450 firstBatch: null,
10451 nextScheduledRoot: null
10452 };
10453 }
10454
10455 uninitializedFiber.stateNode = root;
10456
10457 // The reason for the way the Flow types are structured in this file,
10458 // Is to avoid needing :any casts everywhere interaction tracing fields are used.
10459 // Unfortunately that requires an :any cast for non-interaction tracing capable builds.
10460 // $FlowFixMe Remove this :any cast and replace it with something better.
10461 return root;
10462}
10463
10464/**
10465 * Forked from fbjs/warning:
10466 * https://github.com/facebook/fbjs/blob/e66ba20ad5be433eb54423f2b097d829324d9de6/packages/fbjs/src/__forks__/warning.js
10467 *
10468 * Only change is we use console.warn instead of console.error,
10469 * and do nothing when 'console' is not supported.
10470 * This really simplifies the code.
10471 * ---
10472 * Similar to invariant but only logs a warning if the condition is not met.
10473 * This can be used to log issues in development environments in critical
10474 * paths. Removing the logging code for production environments will keep the
10475 * same logic and follow the same code paths.
10476 */
10477
10478var lowPriorityWarning = function () {};
10479
10480{
10481 var printWarning = function (format) {
10482 for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
10483 args[_key - 1] = arguments[_key];
10484 }
10485
10486 var argIndex = 0;
10487 var message = 'Warning: ' + format.replace(/%s/g, function () {
10488 return args[argIndex++];
10489 });
10490 if (typeof console !== 'undefined') {
10491 console.warn(message);
10492 }
10493 try {
10494 // --- Welcome to debugging React ---
10495 // This error was thrown as a convenience so that you can use this stack
10496 // to find the callsite that caused this warning to fire.
10497 throw new Error(message);
10498 } catch (x) {}
10499 };
10500
10501 lowPriorityWarning = function (condition, format) {
10502 if (format === undefined) {
10503 throw new Error('`lowPriorityWarning(condition, format, ...args)` requires a warning ' + 'message argument');
10504 }
10505 if (!condition) {
10506 for (var _len2 = arguments.length, args = Array(_len2 > 2 ? _len2 - 2 : 0), _key2 = 2; _key2 < _len2; _key2++) {
10507 args[_key2 - 2] = arguments[_key2];
10508 }
10509
10510 printWarning.apply(undefined, [format].concat(args));
10511 }
10512 };
10513}
10514
10515var lowPriorityWarning$1 = lowPriorityWarning;
10516
10517var ReactStrictModeWarnings = {
10518 discardPendingWarnings: function () {},
10519 flushPendingDeprecationWarnings: function () {},
10520 flushPendingUnsafeLifecycleWarnings: function () {},
10521 recordDeprecationWarnings: function (fiber, instance) {},
10522 recordUnsafeLifecycleWarnings: function (fiber, instance) {},
10523 recordLegacyContextWarning: function (fiber, instance) {},
10524 flushLegacyContextWarning: function () {}
10525};
10526
10527{
10528 var LIFECYCLE_SUGGESTIONS = {
10529 UNSAFE_componentWillMount: 'componentDidMount',
10530 UNSAFE_componentWillReceiveProps: 'static getDerivedStateFromProps',
10531 UNSAFE_componentWillUpdate: 'componentDidUpdate'
10532 };
10533
10534 var pendingComponentWillMountWarnings = [];
10535 var pendingComponentWillReceivePropsWarnings = [];
10536 var pendingComponentWillUpdateWarnings = [];
10537 var pendingUnsafeLifecycleWarnings = new Map();
10538 var pendingLegacyContextWarning = new Map();
10539
10540 // Tracks components we have already warned about.
10541 var didWarnAboutDeprecatedLifecycles = new Set();
10542 var didWarnAboutUnsafeLifecycles = new Set();
10543 var didWarnAboutLegacyContext = new Set();
10544
10545 var setToSortedString = function (set) {
10546 var array = [];
10547 set.forEach(function (value) {
10548 array.push(value);
10549 });
10550 return array.sort().join(', ');
10551 };
10552
10553 ReactStrictModeWarnings.discardPendingWarnings = function () {
10554 pendingComponentWillMountWarnings = [];
10555 pendingComponentWillReceivePropsWarnings = [];
10556 pendingComponentWillUpdateWarnings = [];
10557 pendingUnsafeLifecycleWarnings = new Map();
10558 pendingLegacyContextWarning = new Map();
10559 };
10560
10561 ReactStrictModeWarnings.flushPendingUnsafeLifecycleWarnings = function () {
10562 pendingUnsafeLifecycleWarnings.forEach(function (lifecycleWarningsMap, strictRoot) {
10563 var lifecyclesWarningMessages = [];
10564
10565 Object.keys(lifecycleWarningsMap).forEach(function (lifecycle) {
10566 var lifecycleWarnings = lifecycleWarningsMap[lifecycle];
10567 if (lifecycleWarnings.length > 0) {
10568 var componentNames = new Set();
10569 lifecycleWarnings.forEach(function (fiber) {
10570 componentNames.add(getComponentName(fiber.type) || 'Component');
10571 didWarnAboutUnsafeLifecycles.add(fiber.type);
10572 });
10573
10574 var formatted = lifecycle.replace('UNSAFE_', '');
10575 var suggestion = LIFECYCLE_SUGGESTIONS[lifecycle];
10576 var sortedComponentNames = setToSortedString(componentNames);
10577
10578 lifecyclesWarningMessages.push(formatted + ': Please update the following components to use ' + (suggestion + ' instead: ' + sortedComponentNames));
10579 }
10580 });
10581
10582 if (lifecyclesWarningMessages.length > 0) {
10583 var strictRootComponentStack = getStackByFiberInDevAndProd(strictRoot);
10584
10585 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'));
10586 }
10587 });
10588
10589 pendingUnsafeLifecycleWarnings = new Map();
10590 };
10591
10592 var findStrictRoot = function (fiber) {
10593 var maybeStrictRoot = null;
10594
10595 var node = fiber;
10596 while (node !== null) {
10597 if (node.mode & StrictMode) {
10598 maybeStrictRoot = node;
10599 }
10600 node = node.return;
10601 }
10602
10603 return maybeStrictRoot;
10604 };
10605
10606 ReactStrictModeWarnings.flushPendingDeprecationWarnings = function () {
10607 if (pendingComponentWillMountWarnings.length > 0) {
10608 var uniqueNames = new Set();
10609 pendingComponentWillMountWarnings.forEach(function (fiber) {
10610 uniqueNames.add(getComponentName(fiber.type) || 'Component');
10611 didWarnAboutDeprecatedLifecycles.add(fiber.type);
10612 });
10613
10614 var sortedNames = setToSortedString(uniqueNames);
10615
10616 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);
10617
10618 pendingComponentWillMountWarnings = [];
10619 }
10620
10621 if (pendingComponentWillReceivePropsWarnings.length > 0) {
10622 var _uniqueNames = new Set();
10623 pendingComponentWillReceivePropsWarnings.forEach(function (fiber) {
10624 _uniqueNames.add(getComponentName(fiber.type) || 'Component');
10625 didWarnAboutDeprecatedLifecycles.add(fiber.type);
10626 });
10627
10628 var _sortedNames = setToSortedString(_uniqueNames);
10629
10630 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);
10631
10632 pendingComponentWillReceivePropsWarnings = [];
10633 }
10634
10635 if (pendingComponentWillUpdateWarnings.length > 0) {
10636 var _uniqueNames2 = new Set();
10637 pendingComponentWillUpdateWarnings.forEach(function (fiber) {
10638 _uniqueNames2.add(getComponentName(fiber.type) || 'Component');
10639 didWarnAboutDeprecatedLifecycles.add(fiber.type);
10640 });
10641
10642 var _sortedNames2 = setToSortedString(_uniqueNames2);
10643
10644 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);
10645
10646 pendingComponentWillUpdateWarnings = [];
10647 }
10648 };
10649
10650 ReactStrictModeWarnings.recordDeprecationWarnings = function (fiber, instance) {
10651 // Dedup strategy: Warn once per component.
10652 if (didWarnAboutDeprecatedLifecycles.has(fiber.type)) {
10653 return;
10654 }
10655
10656 // Don't warn about react-lifecycles-compat polyfilled components.
10657 if (typeof instance.componentWillMount === 'function' && instance.componentWillMount.__suppressDeprecationWarning !== true) {
10658 pendingComponentWillMountWarnings.push(fiber);
10659 }
10660 if (typeof instance.componentWillReceiveProps === 'function' && instance.componentWillReceiveProps.__suppressDeprecationWarning !== true) {
10661 pendingComponentWillReceivePropsWarnings.push(fiber);
10662 }
10663 if (typeof instance.componentWillUpdate === 'function' && instance.componentWillUpdate.__suppressDeprecationWarning !== true) {
10664 pendingComponentWillUpdateWarnings.push(fiber);
10665 }
10666 };
10667
10668 ReactStrictModeWarnings.recordUnsafeLifecycleWarnings = function (fiber, instance) {
10669 var strictRoot = findStrictRoot(fiber);
10670 if (strictRoot === null) {
10671 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.');
10672 return;
10673 }
10674
10675 // Dedup strategy: Warn once per component.
10676 // This is difficult to track any other way since component names
10677 // are often vague and are likely to collide between 3rd party libraries.
10678 // An expand property is probably okay to use here since it's DEV-only,
10679 // and will only be set in the event of serious warnings.
10680 if (didWarnAboutUnsafeLifecycles.has(fiber.type)) {
10681 return;
10682 }
10683
10684 var warningsForRoot = void 0;
10685 if (!pendingUnsafeLifecycleWarnings.has(strictRoot)) {
10686 warningsForRoot = {
10687 UNSAFE_componentWillMount: [],
10688 UNSAFE_componentWillReceiveProps: [],
10689 UNSAFE_componentWillUpdate: []
10690 };
10691
10692 pendingUnsafeLifecycleWarnings.set(strictRoot, warningsForRoot);
10693 } else {
10694 warningsForRoot = pendingUnsafeLifecycleWarnings.get(strictRoot);
10695 }
10696
10697 var unsafeLifecycles = [];
10698 if (typeof instance.componentWillMount === 'function' && instance.componentWillMount.__suppressDeprecationWarning !== true || typeof instance.UNSAFE_componentWillMount === 'function') {
10699 unsafeLifecycles.push('UNSAFE_componentWillMount');
10700 }
10701 if (typeof instance.componentWillReceiveProps === 'function' && instance.componentWillReceiveProps.__suppressDeprecationWarning !== true || typeof instance.UNSAFE_componentWillReceiveProps === 'function') {
10702 unsafeLifecycles.push('UNSAFE_componentWillReceiveProps');
10703 }
10704 if (typeof instance.componentWillUpdate === 'function' && instance.componentWillUpdate.__suppressDeprecationWarning !== true || typeof instance.UNSAFE_componentWillUpdate === 'function') {
10705 unsafeLifecycles.push('UNSAFE_componentWillUpdate');
10706 }
10707
10708 if (unsafeLifecycles.length > 0) {
10709 unsafeLifecycles.forEach(function (lifecycle) {
10710 warningsForRoot[lifecycle].push(fiber);
10711 });
10712 }
10713 };
10714
10715 ReactStrictModeWarnings.recordLegacyContextWarning = function (fiber, instance) {
10716 var strictRoot = findStrictRoot(fiber);
10717 if (strictRoot === null) {
10718 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.');
10719 return;
10720 }
10721
10722 // Dedup strategy: Warn once per component.
10723 if (didWarnAboutLegacyContext.has(fiber.type)) {
10724 return;
10725 }
10726
10727 var warningsForRoot = pendingLegacyContextWarning.get(strictRoot);
10728
10729 if (fiber.type.contextTypes != null || fiber.type.childContextTypes != null || instance !== null && typeof instance.getChildContext === 'function') {
10730 if (warningsForRoot === undefined) {
10731 warningsForRoot = [];
10732 pendingLegacyContextWarning.set(strictRoot, warningsForRoot);
10733 }
10734 warningsForRoot.push(fiber);
10735 }
10736 };
10737
10738 ReactStrictModeWarnings.flushLegacyContextWarning = function () {
10739 pendingLegacyContextWarning.forEach(function (fiberArray, strictRoot) {
10740 var uniqueNames = new Set();
10741 fiberArray.forEach(function (fiber) {
10742 uniqueNames.add(getComponentName(fiber.type) || 'Component');
10743 didWarnAboutLegacyContext.add(fiber.type);
10744 });
10745
10746 var sortedNames = setToSortedString(uniqueNames);
10747 var strictRootComponentStack = getStackByFiberInDevAndProd(strictRoot);
10748
10749 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);
10750 });
10751 };
10752}
10753
10754// This lets us hook into Fiber to debug what it's doing.
10755// See https://github.com/facebook/react/pull/8033.
10756// This is not part of the public API, not even for React DevTools.
10757// You may only inject a debugTool if you work on React Fiber itself.
10758var ReactFiberInstrumentation = {
10759 debugTool: null
10760};
10761
10762var ReactFiberInstrumentation_1 = ReactFiberInstrumentation;
10763
10764// TODO: Offscreen updates should never suspend. However, a promise that
10765// suspended inside an offscreen subtree should be able to ping at the priority
10766// of the outer render.
10767
10768function markPendingPriorityLevel(root, expirationTime) {
10769 // If there's a gap between completing a failed root and retrying it,
10770 // additional updates may be scheduled. Clear `didError`, in case the update
10771 // is sufficient to fix the error.
10772 root.didError = false;
10773
10774 // Update the latest and earliest pending times
10775 var earliestPendingTime = root.earliestPendingTime;
10776 if (earliestPendingTime === NoWork) {
10777 // No other pending updates.
10778 root.earliestPendingTime = root.latestPendingTime = expirationTime;
10779 } else {
10780 if (earliestPendingTime < expirationTime) {
10781 // This is the earliest pending update.
10782 root.earliestPendingTime = expirationTime;
10783 } else {
10784 var latestPendingTime = root.latestPendingTime;
10785 if (latestPendingTime > expirationTime) {
10786 // This is the latest pending update
10787 root.latestPendingTime = expirationTime;
10788 }
10789 }
10790 }
10791 findNextExpirationTimeToWorkOn(expirationTime, root);
10792}
10793
10794function markCommittedPriorityLevels(root, earliestRemainingTime) {
10795 root.didError = false;
10796
10797 if (earliestRemainingTime === NoWork) {
10798 // Fast path. There's no remaining work. Clear everything.
10799 root.earliestPendingTime = NoWork;
10800 root.latestPendingTime = NoWork;
10801 root.earliestSuspendedTime = NoWork;
10802 root.latestSuspendedTime = NoWork;
10803 root.latestPingedTime = NoWork;
10804 findNextExpirationTimeToWorkOn(NoWork, root);
10805 return;
10806 }
10807
10808 if (earliestRemainingTime < root.latestPingedTime) {
10809 root.latestPingedTime = NoWork;
10810 }
10811
10812 // Let's see if the previous latest known pending level was just flushed.
10813 var latestPendingTime = root.latestPendingTime;
10814 if (latestPendingTime !== NoWork) {
10815 if (latestPendingTime > earliestRemainingTime) {
10816 // We've flushed all the known pending levels.
10817 root.earliestPendingTime = root.latestPendingTime = NoWork;
10818 } else {
10819 var earliestPendingTime = root.earliestPendingTime;
10820 if (earliestPendingTime > earliestRemainingTime) {
10821 // We've flushed the earliest known pending level. Set this to the
10822 // latest pending time.
10823 root.earliestPendingTime = root.latestPendingTime;
10824 }
10825 }
10826 }
10827
10828 // Now let's handle the earliest remaining level in the whole tree. We need to
10829 // decide whether to treat it as a pending level or as suspended. Check
10830 // it falls within the range of known suspended levels.
10831
10832 var earliestSuspendedTime = root.earliestSuspendedTime;
10833 if (earliestSuspendedTime === NoWork) {
10834 // There's no suspended work. Treat the earliest remaining level as a
10835 // pending level.
10836 markPendingPriorityLevel(root, earliestRemainingTime);
10837 findNextExpirationTimeToWorkOn(NoWork, root);
10838 return;
10839 }
10840
10841 var latestSuspendedTime = root.latestSuspendedTime;
10842 if (earliestRemainingTime < latestSuspendedTime) {
10843 // The earliest remaining level is later than all the suspended work. That
10844 // means we've flushed all the suspended work.
10845 root.earliestSuspendedTime = NoWork;
10846 root.latestSuspendedTime = NoWork;
10847 root.latestPingedTime = NoWork;
10848
10849 // There's no suspended work. Treat the earliest remaining level as a
10850 // pending level.
10851 markPendingPriorityLevel(root, earliestRemainingTime);
10852 findNextExpirationTimeToWorkOn(NoWork, root);
10853 return;
10854 }
10855
10856 if (earliestRemainingTime > earliestSuspendedTime) {
10857 // The earliest remaining time is earlier than all the suspended work.
10858 // Treat it as a pending update.
10859 markPendingPriorityLevel(root, earliestRemainingTime);
10860 findNextExpirationTimeToWorkOn(NoWork, root);
10861 return;
10862 }
10863
10864 // The earliest remaining time falls within the range of known suspended
10865 // levels. We should treat this as suspended work.
10866 findNextExpirationTimeToWorkOn(NoWork, root);
10867}
10868
10869function hasLowerPriorityWork(root, erroredExpirationTime) {
10870 var latestPendingTime = root.latestPendingTime;
10871 var latestSuspendedTime = root.latestSuspendedTime;
10872 var latestPingedTime = root.latestPingedTime;
10873 return latestPendingTime !== NoWork && latestPendingTime < erroredExpirationTime || latestSuspendedTime !== NoWork && latestSuspendedTime < erroredExpirationTime || latestPingedTime !== NoWork && latestPingedTime < erroredExpirationTime;
10874}
10875
10876function isPriorityLevelSuspended(root, expirationTime) {
10877 var earliestSuspendedTime = root.earliestSuspendedTime;
10878 var latestSuspendedTime = root.latestSuspendedTime;
10879 return earliestSuspendedTime !== NoWork && expirationTime <= earliestSuspendedTime && expirationTime >= latestSuspendedTime;
10880}
10881
10882function markSuspendedPriorityLevel(root, suspendedTime) {
10883 root.didError = false;
10884 clearPing(root, suspendedTime);
10885
10886 // First, check the known pending levels and update them if needed.
10887 var earliestPendingTime = root.earliestPendingTime;
10888 var latestPendingTime = root.latestPendingTime;
10889 if (earliestPendingTime === suspendedTime) {
10890 if (latestPendingTime === suspendedTime) {
10891 // Both known pending levels were suspended. Clear them.
10892 root.earliestPendingTime = root.latestPendingTime = NoWork;
10893 } else {
10894 // The earliest pending level was suspended. Clear by setting it to the
10895 // latest pending level.
10896 root.earliestPendingTime = latestPendingTime;
10897 }
10898 } else if (latestPendingTime === suspendedTime) {
10899 // The latest pending level was suspended. Clear by setting it to the
10900 // latest pending level.
10901 root.latestPendingTime = earliestPendingTime;
10902 }
10903
10904 // Finally, update the known suspended levels.
10905 var earliestSuspendedTime = root.earliestSuspendedTime;
10906 var latestSuspendedTime = root.latestSuspendedTime;
10907 if (earliestSuspendedTime === NoWork) {
10908 // No other suspended levels.
10909 root.earliestSuspendedTime = root.latestSuspendedTime = suspendedTime;
10910 } else {
10911 if (earliestSuspendedTime < suspendedTime) {
10912 // This is the earliest suspended level.
10913 root.earliestSuspendedTime = suspendedTime;
10914 } else if (latestSuspendedTime > suspendedTime) {
10915 // This is the latest suspended level
10916 root.latestSuspendedTime = suspendedTime;
10917 }
10918 }
10919
10920 findNextExpirationTimeToWorkOn(suspendedTime, root);
10921}
10922
10923function markPingedPriorityLevel(root, pingedTime) {
10924 root.didError = false;
10925
10926 // TODO: When we add back resuming, we need to ensure the progressed work
10927 // is thrown out and not reused during the restarted render. One way to
10928 // invalidate the progressed work is to restart at expirationTime + 1.
10929 var latestPingedTime = root.latestPingedTime;
10930 if (latestPingedTime === NoWork || latestPingedTime > pingedTime) {
10931 root.latestPingedTime = pingedTime;
10932 }
10933 findNextExpirationTimeToWorkOn(pingedTime, root);
10934}
10935
10936function clearPing(root, completedTime) {
10937 var latestPingedTime = root.latestPingedTime;
10938 if (latestPingedTime >= completedTime) {
10939 root.latestPingedTime = NoWork;
10940 }
10941}
10942
10943function findEarliestOutstandingPriorityLevel(root, renderExpirationTime) {
10944 var earliestExpirationTime = renderExpirationTime;
10945
10946 var earliestPendingTime = root.earliestPendingTime;
10947 var earliestSuspendedTime = root.earliestSuspendedTime;
10948 if (earliestPendingTime > earliestExpirationTime) {
10949 earliestExpirationTime = earliestPendingTime;
10950 }
10951 if (earliestSuspendedTime > earliestExpirationTime) {
10952 earliestExpirationTime = earliestSuspendedTime;
10953 }
10954 return earliestExpirationTime;
10955}
10956
10957function didExpireAtExpirationTime(root, currentTime) {
10958 var expirationTime = root.expirationTime;
10959 if (expirationTime !== NoWork && currentTime <= expirationTime) {
10960 // The root has expired. Flush all work up to the current time.
10961 root.nextExpirationTimeToWorkOn = currentTime;
10962 }
10963}
10964
10965function findNextExpirationTimeToWorkOn(completedExpirationTime, root) {
10966 var earliestSuspendedTime = root.earliestSuspendedTime;
10967 var latestSuspendedTime = root.latestSuspendedTime;
10968 var earliestPendingTime = root.earliestPendingTime;
10969 var latestPingedTime = root.latestPingedTime;
10970
10971 // Work on the earliest pending time. Failing that, work on the latest
10972 // pinged time.
10973 var nextExpirationTimeToWorkOn = earliestPendingTime !== NoWork ? earliestPendingTime : latestPingedTime;
10974
10975 // If there is no pending or pinged work, check if there's suspended work
10976 // that's lower priority than what we just completed.
10977 if (nextExpirationTimeToWorkOn === NoWork && (completedExpirationTime === NoWork || latestSuspendedTime < completedExpirationTime)) {
10978 // The lowest priority suspended work is the work most likely to be
10979 // committed next. Let's start rendering it again, so that if it times out,
10980 // it's ready to commit.
10981 nextExpirationTimeToWorkOn = latestSuspendedTime;
10982 }
10983
10984 var expirationTime = nextExpirationTimeToWorkOn;
10985 if (expirationTime !== NoWork && earliestSuspendedTime > expirationTime) {
10986 // Expire using the earliest known expiration time.
10987 expirationTime = earliestSuspendedTime;
10988 }
10989
10990 root.nextExpirationTimeToWorkOn = nextExpirationTimeToWorkOn;
10991 root.expirationTime = expirationTime;
10992}
10993
10994function resolveDefaultProps(Component, baseProps) {
10995 if (Component && Component.defaultProps) {
10996 // Resolve default props. Taken from ReactElement
10997 var props = _assign({}, baseProps);
10998 var defaultProps = Component.defaultProps;
10999 for (var propName in defaultProps) {
11000 if (props[propName] === undefined) {
11001 props[propName] = defaultProps[propName];
11002 }
11003 }
11004 return props;
11005 }
11006 return baseProps;
11007}
11008
11009function readLazyComponentType(lazyComponent) {
11010 var status = lazyComponent._status;
11011 var result = lazyComponent._result;
11012 switch (status) {
11013 case Resolved:
11014 {
11015 var Component = result;
11016 return Component;
11017 }
11018 case Rejected:
11019 {
11020 var error = result;
11021 throw error;
11022 }
11023 case Pending:
11024 {
11025 var thenable = result;
11026 throw thenable;
11027 }
11028 default:
11029 {
11030 lazyComponent._status = Pending;
11031 var ctor = lazyComponent._ctor;
11032 var _thenable = ctor();
11033 _thenable.then(function (moduleObject) {
11034 if (lazyComponent._status === Pending) {
11035 var defaultExport = moduleObject.default;
11036 {
11037 if (defaultExport === undefined) {
11038 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);
11039 }
11040 }
11041 lazyComponent._status = Resolved;
11042 lazyComponent._result = defaultExport;
11043 }
11044 }, function (error) {
11045 if (lazyComponent._status === Pending) {
11046 lazyComponent._status = Rejected;
11047 lazyComponent._result = error;
11048 }
11049 });
11050 // Handle synchronous thenables.
11051 switch (lazyComponent._status) {
11052 case Resolved:
11053 return lazyComponent._result;
11054 case Rejected:
11055 throw lazyComponent._result;
11056 }
11057 lazyComponent._result = _thenable;
11058 throw _thenable;
11059 }
11060 }
11061}
11062
11063var fakeInternalInstance = {};
11064var isArray$1 = Array.isArray;
11065
11066// React.Component uses a shared frozen object by default.
11067// We'll use it to determine whether we need to initialize legacy refs.
11068var emptyRefsObject = new React.Component().refs;
11069
11070var didWarnAboutStateAssignmentForComponent = void 0;
11071var didWarnAboutUninitializedState = void 0;
11072var didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate = void 0;
11073var didWarnAboutLegacyLifecyclesAndDerivedState = void 0;
11074var didWarnAboutUndefinedDerivedState = void 0;
11075var warnOnUndefinedDerivedState = void 0;
11076var warnOnInvalidCallback$1 = void 0;
11077var didWarnAboutDirectlyAssigningPropsToState = void 0;
11078var didWarnAboutContextTypeAndContextTypes = void 0;
11079var didWarnAboutInvalidateContextType = void 0;
11080
11081{
11082 didWarnAboutStateAssignmentForComponent = new Set();
11083 didWarnAboutUninitializedState = new Set();
11084 didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate = new Set();
11085 didWarnAboutLegacyLifecyclesAndDerivedState = new Set();
11086 didWarnAboutDirectlyAssigningPropsToState = new Set();
11087 didWarnAboutUndefinedDerivedState = new Set();
11088 didWarnAboutContextTypeAndContextTypes = new Set();
11089 didWarnAboutInvalidateContextType = new Set();
11090
11091 var didWarnOnInvalidCallback = new Set();
11092
11093 warnOnInvalidCallback$1 = function (callback, callerName) {
11094 if (callback === null || typeof callback === 'function') {
11095 return;
11096 }
11097 var key = callerName + '_' + callback;
11098 if (!didWarnOnInvalidCallback.has(key)) {
11099 didWarnOnInvalidCallback.add(key);
11100 warningWithoutStack$1(false, '%s(...): Expected the last optional `callback` argument to be a ' + 'function. Instead received: %s.', callerName, callback);
11101 }
11102 };
11103
11104 warnOnUndefinedDerivedState = function (type, partialState) {
11105 if (partialState === undefined) {
11106 var componentName = getComponentName(type) || 'Component';
11107 if (!didWarnAboutUndefinedDerivedState.has(componentName)) {
11108 didWarnAboutUndefinedDerivedState.add(componentName);
11109 warningWithoutStack$1(false, '%s.getDerivedStateFromProps(): A valid state object (or null) must be returned. ' + 'You have returned undefined.', componentName);
11110 }
11111 }
11112 };
11113
11114 // This is so gross but it's at least non-critical and can be removed if
11115 // it causes problems. This is meant to give a nicer error message for
11116 // ReactDOM15.unstable_renderSubtreeIntoContainer(reactDOM16Component,
11117 // ...)) which otherwise throws a "_processChildContext is not a function"
11118 // exception.
11119 Object.defineProperty(fakeInternalInstance, '_processChildContext', {
11120 enumerable: false,
11121 value: function () {
11122 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).');
11123 }
11124 });
11125 Object.freeze(fakeInternalInstance);
11126}
11127
11128function applyDerivedStateFromProps(workInProgress, ctor, getDerivedStateFromProps, nextProps) {
11129 var prevState = workInProgress.memoizedState;
11130
11131 {
11132 if (debugRenderPhaseSideEffects || debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) {
11133 // Invoke the function an extra time to help detect side-effects.
11134 getDerivedStateFromProps(nextProps, prevState);
11135 }
11136 }
11137
11138 var partialState = getDerivedStateFromProps(nextProps, prevState);
11139
11140 {
11141 warnOnUndefinedDerivedState(ctor, partialState);
11142 }
11143 // Merge the partial state and the previous state.
11144 var memoizedState = partialState === null || partialState === undefined ? prevState : _assign({}, prevState, partialState);
11145 workInProgress.memoizedState = memoizedState;
11146
11147 // Once the update queue is empty, persist the derived state onto the
11148 // base state.
11149 var updateQueue = workInProgress.updateQueue;
11150 if (updateQueue !== null && workInProgress.expirationTime === NoWork) {
11151 updateQueue.baseState = memoizedState;
11152 }
11153}
11154
11155var classComponentUpdater = {
11156 isMounted: isMounted,
11157 enqueueSetState: function (inst, payload, callback) {
11158 var fiber = get(inst);
11159 var currentTime = requestCurrentTime();
11160 var expirationTime = computeExpirationForFiber(currentTime, fiber);
11161
11162 var update = createUpdate(expirationTime);
11163 update.payload = payload;
11164 if (callback !== undefined && callback !== null) {
11165 {
11166 warnOnInvalidCallback$1(callback, 'setState');
11167 }
11168 update.callback = callback;
11169 }
11170
11171 flushPassiveEffects();
11172 enqueueUpdate(fiber, update);
11173 scheduleWork(fiber, expirationTime);
11174 },
11175 enqueueReplaceState: function (inst, payload, callback) {
11176 var fiber = get(inst);
11177 var currentTime = requestCurrentTime();
11178 var expirationTime = computeExpirationForFiber(currentTime, fiber);
11179
11180 var update = createUpdate(expirationTime);
11181 update.tag = ReplaceState;
11182 update.payload = payload;
11183
11184 if (callback !== undefined && callback !== null) {
11185 {
11186 warnOnInvalidCallback$1(callback, 'replaceState');
11187 }
11188 update.callback = callback;
11189 }
11190
11191 flushPassiveEffects();
11192 enqueueUpdate(fiber, update);
11193 scheduleWork(fiber, expirationTime);
11194 },
11195 enqueueForceUpdate: function (inst, callback) {
11196 var fiber = get(inst);
11197 var currentTime = requestCurrentTime();
11198 var expirationTime = computeExpirationForFiber(currentTime, fiber);
11199
11200 var update = createUpdate(expirationTime);
11201 update.tag = ForceUpdate;
11202
11203 if (callback !== undefined && callback !== null) {
11204 {
11205 warnOnInvalidCallback$1(callback, 'forceUpdate');
11206 }
11207 update.callback = callback;
11208 }
11209
11210 flushPassiveEffects();
11211 enqueueUpdate(fiber, update);
11212 scheduleWork(fiber, expirationTime);
11213 }
11214};
11215
11216function checkShouldComponentUpdate(workInProgress, ctor, oldProps, newProps, oldState, newState, nextContext) {
11217 var instance = workInProgress.stateNode;
11218 if (typeof instance.shouldComponentUpdate === 'function') {
11219 startPhaseTimer(workInProgress, 'shouldComponentUpdate');
11220 var shouldUpdate = instance.shouldComponentUpdate(newProps, newState, nextContext);
11221 stopPhaseTimer();
11222
11223 {
11224 !(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;
11225 }
11226
11227 return shouldUpdate;
11228 }
11229
11230 if (ctor.prototype && ctor.prototype.isPureReactComponent) {
11231 return !shallowEqual(oldProps, newProps) || !shallowEqual(oldState, newState);
11232 }
11233
11234 return true;
11235}
11236
11237function checkClassInstance(workInProgress, ctor, newProps) {
11238 var instance = workInProgress.stateNode;
11239 {
11240 var name = getComponentName(ctor) || 'Component';
11241 var renderPresent = instance.render;
11242
11243 if (!renderPresent) {
11244 if (ctor.prototype && typeof ctor.prototype.render === 'function') {
11245 warningWithoutStack$1(false, '%s(...): No `render` method found on the returned component ' + 'instance: did you accidentally return an object from the constructor?', name);
11246 } else {
11247 warningWithoutStack$1(false, '%s(...): No `render` method found on the returned component ' + 'instance: you may have forgotten to define `render`.', name);
11248 }
11249 }
11250
11251 var noGetInitialStateOnES6 = !instance.getInitialState || instance.getInitialState.isReactClassApproved || instance.state;
11252 !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;
11253 var noGetDefaultPropsOnES6 = !instance.getDefaultProps || instance.getDefaultProps.isReactClassApproved;
11254 !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;
11255 var noInstancePropTypes = !instance.propTypes;
11256 !noInstancePropTypes ? warningWithoutStack$1(false, 'propTypes was defined as an instance property on %s. Use a static ' + 'property to define propTypes instead.', name) : void 0;
11257 var noInstanceContextType = !instance.contextType;
11258 !noInstanceContextType ? warningWithoutStack$1(false, 'contextType was defined as an instance property on %s. Use a static ' + 'property to define contextType instead.', name) : void 0;
11259 var noInstanceContextTypes = !instance.contextTypes;
11260 !noInstanceContextTypes ? warningWithoutStack$1(false, 'contextTypes was defined as an instance property on %s. Use a static ' + 'property to define contextTypes instead.', name) : void 0;
11261
11262 if (ctor.contextType && ctor.contextTypes && !didWarnAboutContextTypeAndContextTypes.has(ctor)) {
11263 didWarnAboutContextTypeAndContextTypes.add(ctor);
11264 warningWithoutStack$1(false, '%s declares both contextTypes and contextType static properties. ' + 'The legacy contextTypes property will be ignored.', name);
11265 }
11266
11267 var noComponentShouldUpdate = typeof instance.componentShouldUpdate !== 'function';
11268 !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;
11269 if (ctor.prototype && ctor.prototype.isPureReactComponent && typeof instance.shouldComponentUpdate !== 'undefined') {
11270 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');
11271 }
11272 var noComponentDidUnmount = typeof instance.componentDidUnmount !== 'function';
11273 !noComponentDidUnmount ? warningWithoutStack$1(false, '%s has a method called ' + 'componentDidUnmount(). But there is no such lifecycle method. ' + 'Did you mean componentWillUnmount()?', name) : void 0;
11274 var noComponentDidReceiveProps = typeof instance.componentDidReceiveProps !== 'function';
11275 !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;
11276 var noComponentWillRecieveProps = typeof instance.componentWillRecieveProps !== 'function';
11277 !noComponentWillRecieveProps ? warningWithoutStack$1(false, '%s has a method called ' + 'componentWillRecieveProps(). Did you mean componentWillReceiveProps()?', name) : void 0;
11278 var noUnsafeComponentWillRecieveProps = typeof instance.UNSAFE_componentWillRecieveProps !== 'function';
11279 !noUnsafeComponentWillRecieveProps ? warningWithoutStack$1(false, '%s has a method called ' + 'UNSAFE_componentWillRecieveProps(). Did you mean UNSAFE_componentWillReceiveProps()?', name) : void 0;
11280 var hasMutatedProps = instance.props !== newProps;
11281 !(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;
11282 var noInstanceDefaultProps = !instance.defaultProps;
11283 !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;
11284
11285 if (typeof instance.getSnapshotBeforeUpdate === 'function' && typeof instance.componentDidUpdate !== 'function' && !didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate.has(ctor)) {
11286 didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate.add(ctor);
11287 warningWithoutStack$1(false, '%s: getSnapshotBeforeUpdate() should be used with componentDidUpdate(). ' + 'This component defines getSnapshotBeforeUpdate() only.', getComponentName(ctor));
11288 }
11289
11290 var noInstanceGetDerivedStateFromProps = typeof instance.getDerivedStateFromProps !== 'function';
11291 !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;
11292 var noInstanceGetDerivedStateFromCatch = typeof instance.getDerivedStateFromError !== 'function';
11293 !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;
11294 var noStaticGetSnapshotBeforeUpdate = typeof ctor.getSnapshotBeforeUpdate !== 'function';
11295 !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;
11296 var _state = instance.state;
11297 if (_state && (typeof _state !== 'object' || isArray$1(_state))) {
11298 warningWithoutStack$1(false, '%s.state: must be set to an object or null', name);
11299 }
11300 if (typeof instance.getChildContext === 'function') {
11301 !(typeof ctor.childContextTypes === 'object') ? warningWithoutStack$1(false, '%s.getChildContext(): childContextTypes must be defined in order to ' + 'use getChildContext().', name) : void 0;
11302 }
11303 }
11304}
11305
11306function adoptClassInstance(workInProgress, instance) {
11307 instance.updater = classComponentUpdater;
11308 workInProgress.stateNode = instance;
11309 // The instance needs access to the fiber so that it can schedule updates
11310 set(instance, workInProgress);
11311 {
11312 instance._reactInternalInstance = fakeInternalInstance;
11313 }
11314}
11315
11316function constructClassInstance(workInProgress, ctor, props, renderExpirationTime) {
11317 var isLegacyContextConsumer = false;
11318 var unmaskedContext = emptyContextObject;
11319 var context = null;
11320 var contextType = ctor.contextType;
11321
11322 {
11323 if ('contextType' in ctor) {
11324 var isValid =
11325 // Allow null for conditional declaration
11326 contextType === null || contextType !== undefined && contextType.$$typeof === REACT_CONTEXT_TYPE && contextType._context === undefined; // Not a <Context.Consumer>
11327
11328 if (!isValid && !didWarnAboutInvalidateContextType.has(ctor)) {
11329 didWarnAboutInvalidateContextType.add(ctor);
11330
11331 var addendum = '';
11332 if (contextType === undefined) {
11333 addendum = ' However, it is set to undefined. ' + 'This can be caused by a typo or by mixing up named and default imports. ' + 'This can also happen due to a circular dependency, so ' + 'try moving the createContext() call to a separate file.';
11334 } else if (typeof contextType !== 'object') {
11335 addendum = ' However, it is set to a ' + typeof contextType + '.';
11336 } else if (contextType.$$typeof === REACT_PROVIDER_TYPE) {
11337 addendum = ' Did you accidentally pass the Context.Provider instead?';
11338 } else if (contextType._context !== undefined) {
11339 // <Context.Consumer>
11340 addendum = ' Did you accidentally pass the Context.Consumer instead?';
11341 } else {
11342 addendum = ' However, it is set to an object with keys {' + Object.keys(contextType).join(', ') + '}.';
11343 }
11344 warningWithoutStack$1(false, '%s defines an invalid contextType. ' + 'contextType should point to the Context object returned by React.createContext().%s', getComponentName(ctor) || 'Component', addendum);
11345 }
11346 }
11347 }
11348
11349 if (typeof contextType === 'object' && contextType !== null) {
11350 context = readContext(contextType);
11351 } else {
11352 unmaskedContext = getUnmaskedContext(workInProgress, ctor, true);
11353 var contextTypes = ctor.contextTypes;
11354 isLegacyContextConsumer = contextTypes !== null && contextTypes !== undefined;
11355 context = isLegacyContextConsumer ? getMaskedContext(workInProgress, unmaskedContext) : emptyContextObject;
11356 }
11357
11358 // Instantiate twice to help detect side-effects.
11359 {
11360 if (debugRenderPhaseSideEffects || debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) {
11361 new ctor(props, context); // eslint-disable-line no-new
11362 }
11363 }
11364
11365 var instance = new ctor(props, context);
11366 var state = workInProgress.memoizedState = instance.state !== null && instance.state !== undefined ? instance.state : null;
11367 adoptClassInstance(workInProgress, instance);
11368
11369 {
11370 if (typeof ctor.getDerivedStateFromProps === 'function' && state === null) {
11371 var componentName = getComponentName(ctor) || 'Component';
11372 if (!didWarnAboutUninitializedState.has(componentName)) {
11373 didWarnAboutUninitializedState.add(componentName);
11374 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);
11375 }
11376 }
11377
11378 // If new component APIs are defined, "unsafe" lifecycles won't be called.
11379 // Warn about these lifecycles if they are present.
11380 // Don't warn about react-lifecycles-compat polyfilled methods though.
11381 if (typeof ctor.getDerivedStateFromProps === 'function' || typeof instance.getSnapshotBeforeUpdate === 'function') {
11382 var foundWillMountName = null;
11383 var foundWillReceivePropsName = null;
11384 var foundWillUpdateName = null;
11385 if (typeof instance.componentWillMount === 'function' && instance.componentWillMount.__suppressDeprecationWarning !== true) {
11386 foundWillMountName = 'componentWillMount';
11387 } else if (typeof instance.UNSAFE_componentWillMount === 'function') {
11388 foundWillMountName = 'UNSAFE_componentWillMount';
11389 }
11390 if (typeof instance.componentWillReceiveProps === 'function' && instance.componentWillReceiveProps.__suppressDeprecationWarning !== true) {
11391 foundWillReceivePropsName = 'componentWillReceiveProps';
11392 } else if (typeof instance.UNSAFE_componentWillReceiveProps === 'function') {
11393 foundWillReceivePropsName = 'UNSAFE_componentWillReceiveProps';
11394 }
11395 if (typeof instance.componentWillUpdate === 'function' && instance.componentWillUpdate.__suppressDeprecationWarning !== true) {
11396 foundWillUpdateName = 'componentWillUpdate';
11397 } else if (typeof instance.UNSAFE_componentWillUpdate === 'function') {
11398 foundWillUpdateName = 'UNSAFE_componentWillUpdate';
11399 }
11400 if (foundWillMountName !== null || foundWillReceivePropsName !== null || foundWillUpdateName !== null) {
11401 var _componentName = getComponentName(ctor) || 'Component';
11402 var newApiName = typeof ctor.getDerivedStateFromProps === 'function' ? 'getDerivedStateFromProps()' : 'getSnapshotBeforeUpdate()';
11403 if (!didWarnAboutLegacyLifecyclesAndDerivedState.has(_componentName)) {
11404 didWarnAboutLegacyLifecyclesAndDerivedState.add(_componentName);
11405 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 : '');
11406 }
11407 }
11408 }
11409 }
11410
11411 // Cache unmasked context so we can avoid recreating masked context unless necessary.
11412 // ReactFiberContext usually updates this cache but can't for newly-created instances.
11413 if (isLegacyContextConsumer) {
11414 cacheContext(workInProgress, unmaskedContext, context);
11415 }
11416
11417 return instance;
11418}
11419
11420function callComponentWillMount(workInProgress, instance) {
11421 startPhaseTimer(workInProgress, 'componentWillMount');
11422 var oldState = instance.state;
11423
11424 if (typeof instance.componentWillMount === 'function') {
11425 instance.componentWillMount();
11426 }
11427 if (typeof instance.UNSAFE_componentWillMount === 'function') {
11428 instance.UNSAFE_componentWillMount();
11429 }
11430
11431 stopPhaseTimer();
11432
11433 if (oldState !== instance.state) {
11434 {
11435 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');
11436 }
11437 classComponentUpdater.enqueueReplaceState(instance, instance.state, null);
11438 }
11439}
11440
11441function callComponentWillReceiveProps(workInProgress, instance, newProps, nextContext) {
11442 var oldState = instance.state;
11443 startPhaseTimer(workInProgress, 'componentWillReceiveProps');
11444 if (typeof instance.componentWillReceiveProps === 'function') {
11445 instance.componentWillReceiveProps(newProps, nextContext);
11446 }
11447 if (typeof instance.UNSAFE_componentWillReceiveProps === 'function') {
11448 instance.UNSAFE_componentWillReceiveProps(newProps, nextContext);
11449 }
11450 stopPhaseTimer();
11451
11452 if (instance.state !== oldState) {
11453 {
11454 var componentName = getComponentName(workInProgress.type) || 'Component';
11455 if (!didWarnAboutStateAssignmentForComponent.has(componentName)) {
11456 didWarnAboutStateAssignmentForComponent.add(componentName);
11457 warningWithoutStack$1(false, '%s.componentWillReceiveProps(): Assigning directly to ' + "this.state is deprecated (except inside a component's " + 'constructor). Use setState instead.', componentName);
11458 }
11459 }
11460 classComponentUpdater.enqueueReplaceState(instance, instance.state, null);
11461 }
11462}
11463
11464// Invokes the mount life-cycles on a previously never rendered instance.
11465function mountClassInstance(workInProgress, ctor, newProps, renderExpirationTime) {
11466 {
11467 checkClassInstance(workInProgress, ctor, newProps);
11468 }
11469
11470 var instance = workInProgress.stateNode;
11471 instance.props = newProps;
11472 instance.state = workInProgress.memoizedState;
11473 instance.refs = emptyRefsObject;
11474
11475 var contextType = ctor.contextType;
11476 if (typeof contextType === 'object' && contextType !== null) {
11477 instance.context = readContext(contextType);
11478 } else {
11479 var unmaskedContext = getUnmaskedContext(workInProgress, ctor, true);
11480 instance.context = getMaskedContext(workInProgress, unmaskedContext);
11481 }
11482
11483 {
11484 if (instance.state === newProps) {
11485 var componentName = getComponentName(ctor) || 'Component';
11486 if (!didWarnAboutDirectlyAssigningPropsToState.has(componentName)) {
11487 didWarnAboutDirectlyAssigningPropsToState.add(componentName);
11488 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);
11489 }
11490 }
11491
11492 if (workInProgress.mode & StrictMode) {
11493 ReactStrictModeWarnings.recordUnsafeLifecycleWarnings(workInProgress, instance);
11494
11495 ReactStrictModeWarnings.recordLegacyContextWarning(workInProgress, instance);
11496 }
11497
11498 if (warnAboutDeprecatedLifecycles) {
11499 ReactStrictModeWarnings.recordDeprecationWarnings(workInProgress, instance);
11500 }
11501 }
11502
11503 var updateQueue = workInProgress.updateQueue;
11504 if (updateQueue !== null) {
11505 processUpdateQueue(workInProgress, updateQueue, newProps, instance, renderExpirationTime);
11506 instance.state = workInProgress.memoizedState;
11507 }
11508
11509 var getDerivedStateFromProps = ctor.getDerivedStateFromProps;
11510 if (typeof getDerivedStateFromProps === 'function') {
11511 applyDerivedStateFromProps(workInProgress, ctor, getDerivedStateFromProps, newProps);
11512 instance.state = workInProgress.memoizedState;
11513 }
11514
11515 // In order to support react-lifecycles-compat polyfilled components,
11516 // Unsafe lifecycles should not be invoked for components using the new APIs.
11517 if (typeof ctor.getDerivedStateFromProps !== 'function' && typeof instance.getSnapshotBeforeUpdate !== 'function' && (typeof instance.UNSAFE_componentWillMount === 'function' || typeof instance.componentWillMount === 'function')) {
11518 callComponentWillMount(workInProgress, instance);
11519 // If we had additional state updates during this life-cycle, let's
11520 // process them now.
11521 updateQueue = workInProgress.updateQueue;
11522 if (updateQueue !== null) {
11523 processUpdateQueue(workInProgress, updateQueue, newProps, instance, renderExpirationTime);
11524 instance.state = workInProgress.memoizedState;
11525 }
11526 }
11527
11528 if (typeof instance.componentDidMount === 'function') {
11529 workInProgress.effectTag |= Update;
11530 }
11531}
11532
11533function resumeMountClassInstance(workInProgress, ctor, newProps, renderExpirationTime) {
11534 var instance = workInProgress.stateNode;
11535
11536 var oldProps = workInProgress.memoizedProps;
11537 instance.props = oldProps;
11538
11539 var oldContext = instance.context;
11540 var contextType = ctor.contextType;
11541 var nextContext = void 0;
11542 if (typeof contextType === 'object' && contextType !== null) {
11543 nextContext = readContext(contextType);
11544 } else {
11545 var nextLegacyUnmaskedContext = getUnmaskedContext(workInProgress, ctor, true);
11546 nextContext = getMaskedContext(workInProgress, nextLegacyUnmaskedContext);
11547 }
11548
11549 var getDerivedStateFromProps = ctor.getDerivedStateFromProps;
11550 var hasNewLifecycles = typeof getDerivedStateFromProps === 'function' || typeof instance.getSnapshotBeforeUpdate === 'function';
11551
11552 // Note: During these life-cycles, instance.props/instance.state are what
11553 // ever the previously attempted to render - not the "current". However,
11554 // during componentDidUpdate we pass the "current" props.
11555
11556 // In order to support react-lifecycles-compat polyfilled components,
11557 // Unsafe lifecycles should not be invoked for components using the new APIs.
11558 if (!hasNewLifecycles && (typeof instance.UNSAFE_componentWillReceiveProps === 'function' || typeof instance.componentWillReceiveProps === 'function')) {
11559 if (oldProps !== newProps || oldContext !== nextContext) {
11560 callComponentWillReceiveProps(workInProgress, instance, newProps, nextContext);
11561 }
11562 }
11563
11564 resetHasForceUpdateBeforeProcessing();
11565
11566 var oldState = workInProgress.memoizedState;
11567 var newState = instance.state = oldState;
11568 var updateQueue = workInProgress.updateQueue;
11569 if (updateQueue !== null) {
11570 processUpdateQueue(workInProgress, updateQueue, newProps, instance, renderExpirationTime);
11571 newState = workInProgress.memoizedState;
11572 }
11573 if (oldProps === newProps && oldState === newState && !hasContextChanged() && !checkHasForceUpdateAfterProcessing()) {
11574 // If an update was already in progress, we should schedule an Update
11575 // effect even though we're bailing out, so that cWU/cDU are called.
11576 if (typeof instance.componentDidMount === 'function') {
11577 workInProgress.effectTag |= Update;
11578 }
11579 return false;
11580 }
11581
11582 if (typeof getDerivedStateFromProps === 'function') {
11583 applyDerivedStateFromProps(workInProgress, ctor, getDerivedStateFromProps, newProps);
11584 newState = workInProgress.memoizedState;
11585 }
11586
11587 var shouldUpdate = checkHasForceUpdateAfterProcessing() || checkShouldComponentUpdate(workInProgress, ctor, oldProps, newProps, oldState, newState, nextContext);
11588
11589 if (shouldUpdate) {
11590 // In order to support react-lifecycles-compat polyfilled components,
11591 // Unsafe lifecycles should not be invoked for components using the new APIs.
11592 if (!hasNewLifecycles && (typeof instance.UNSAFE_componentWillMount === 'function' || typeof instance.componentWillMount === 'function')) {
11593 startPhaseTimer(workInProgress, 'componentWillMount');
11594 if (typeof instance.componentWillMount === 'function') {
11595 instance.componentWillMount();
11596 }
11597 if (typeof instance.UNSAFE_componentWillMount === 'function') {
11598 instance.UNSAFE_componentWillMount();
11599 }
11600 stopPhaseTimer();
11601 }
11602 if (typeof instance.componentDidMount === 'function') {
11603 workInProgress.effectTag |= Update;
11604 }
11605 } else {
11606 // If an update was already in progress, we should schedule an Update
11607 // effect even though we're bailing out, so that cWU/cDU are called.
11608 if (typeof instance.componentDidMount === 'function') {
11609 workInProgress.effectTag |= Update;
11610 }
11611
11612 // If shouldComponentUpdate returned false, we should still update the
11613 // memoized state to indicate that this work can be reused.
11614 workInProgress.memoizedProps = newProps;
11615 workInProgress.memoizedState = newState;
11616 }
11617
11618 // Update the existing instance's state, props, and context pointers even
11619 // if shouldComponentUpdate returns false.
11620 instance.props = newProps;
11621 instance.state = newState;
11622 instance.context = nextContext;
11623
11624 return shouldUpdate;
11625}
11626
11627// Invokes the update life-cycles and returns false if it shouldn't rerender.
11628function updateClassInstance(current, workInProgress, ctor, newProps, renderExpirationTime) {
11629 var instance = workInProgress.stateNode;
11630
11631 var oldProps = workInProgress.memoizedProps;
11632 instance.props = workInProgress.type === workInProgress.elementType ? oldProps : resolveDefaultProps(workInProgress.type, oldProps);
11633
11634 var oldContext = instance.context;
11635 var contextType = ctor.contextType;
11636 var nextContext = void 0;
11637 if (typeof contextType === 'object' && contextType !== null) {
11638 nextContext = readContext(contextType);
11639 } else {
11640 var nextUnmaskedContext = getUnmaskedContext(workInProgress, ctor, true);
11641 nextContext = getMaskedContext(workInProgress, nextUnmaskedContext);
11642 }
11643
11644 var getDerivedStateFromProps = ctor.getDerivedStateFromProps;
11645 var hasNewLifecycles = typeof getDerivedStateFromProps === 'function' || typeof instance.getSnapshotBeforeUpdate === 'function';
11646
11647 // Note: During these life-cycles, instance.props/instance.state are what
11648 // ever the previously attempted to render - not the "current". However,
11649 // during componentDidUpdate we pass the "current" props.
11650
11651 // In order to support react-lifecycles-compat polyfilled components,
11652 // Unsafe lifecycles should not be invoked for components using the new APIs.
11653 if (!hasNewLifecycles && (typeof instance.UNSAFE_componentWillReceiveProps === 'function' || typeof instance.componentWillReceiveProps === 'function')) {
11654 if (oldProps !== newProps || oldContext !== nextContext) {
11655 callComponentWillReceiveProps(workInProgress, instance, newProps, nextContext);
11656 }
11657 }
11658
11659 resetHasForceUpdateBeforeProcessing();
11660
11661 var oldState = workInProgress.memoizedState;
11662 var newState = instance.state = oldState;
11663 var updateQueue = workInProgress.updateQueue;
11664 if (updateQueue !== null) {
11665 processUpdateQueue(workInProgress, updateQueue, newProps, instance, renderExpirationTime);
11666 newState = workInProgress.memoizedState;
11667 }
11668
11669 if (oldProps === newProps && oldState === newState && !hasContextChanged() && !checkHasForceUpdateAfterProcessing()) {
11670 // If an update was already in progress, we should schedule an Update
11671 // effect even though we're bailing out, so that cWU/cDU are called.
11672 if (typeof instance.componentDidUpdate === 'function') {
11673 if (oldProps !== current.memoizedProps || oldState !== current.memoizedState) {
11674 workInProgress.effectTag |= Update;
11675 }
11676 }
11677 if (typeof instance.getSnapshotBeforeUpdate === 'function') {
11678 if (oldProps !== current.memoizedProps || oldState !== current.memoizedState) {
11679 workInProgress.effectTag |= Snapshot;
11680 }
11681 }
11682 return false;
11683 }
11684
11685 if (typeof getDerivedStateFromProps === 'function') {
11686 applyDerivedStateFromProps(workInProgress, ctor, getDerivedStateFromProps, newProps);
11687 newState = workInProgress.memoizedState;
11688 }
11689
11690 var shouldUpdate = checkHasForceUpdateAfterProcessing() || checkShouldComponentUpdate(workInProgress, ctor, oldProps, newProps, oldState, newState, nextContext);
11691
11692 if (shouldUpdate) {
11693 // In order to support react-lifecycles-compat polyfilled components,
11694 // Unsafe lifecycles should not be invoked for components using the new APIs.
11695 if (!hasNewLifecycles && (typeof instance.UNSAFE_componentWillUpdate === 'function' || typeof instance.componentWillUpdate === 'function')) {
11696 startPhaseTimer(workInProgress, 'componentWillUpdate');
11697 if (typeof instance.componentWillUpdate === 'function') {
11698 instance.componentWillUpdate(newProps, newState, nextContext);
11699 }
11700 if (typeof instance.UNSAFE_componentWillUpdate === 'function') {
11701 instance.UNSAFE_componentWillUpdate(newProps, newState, nextContext);
11702 }
11703 stopPhaseTimer();
11704 }
11705 if (typeof instance.componentDidUpdate === 'function') {
11706 workInProgress.effectTag |= Update;
11707 }
11708 if (typeof instance.getSnapshotBeforeUpdate === 'function') {
11709 workInProgress.effectTag |= Snapshot;
11710 }
11711 } else {
11712 // If an update was already in progress, we should schedule an Update
11713 // effect even though we're bailing out, so that cWU/cDU are called.
11714 if (typeof instance.componentDidUpdate === 'function') {
11715 if (oldProps !== current.memoizedProps || oldState !== current.memoizedState) {
11716 workInProgress.effectTag |= Update;
11717 }
11718 }
11719 if (typeof instance.getSnapshotBeforeUpdate === 'function') {
11720 if (oldProps !== current.memoizedProps || oldState !== current.memoizedState) {
11721 workInProgress.effectTag |= Snapshot;
11722 }
11723 }
11724
11725 // If shouldComponentUpdate returned false, we should still update the
11726 // memoized props/state to indicate that this work can be reused.
11727 workInProgress.memoizedProps = newProps;
11728 workInProgress.memoizedState = newState;
11729 }
11730
11731 // Update the existing instance's state, props, and context pointers even
11732 // if shouldComponentUpdate returns false.
11733 instance.props = newProps;
11734 instance.state = newState;
11735 instance.context = nextContext;
11736
11737 return shouldUpdate;
11738}
11739
11740var didWarnAboutMaps = void 0;
11741var didWarnAboutGenerators = void 0;
11742var didWarnAboutStringRefInStrictMode = void 0;
11743var ownerHasKeyUseWarning = void 0;
11744var ownerHasFunctionTypeWarning = void 0;
11745var warnForMissingKey = function (child) {};
11746
11747{
11748 didWarnAboutMaps = false;
11749 didWarnAboutGenerators = false;
11750 didWarnAboutStringRefInStrictMode = {};
11751
11752 /**
11753 * Warn if there's no key explicitly set on dynamic arrays of children or
11754 * object keys are not valid. This allows us to keep track of children between
11755 * updates.
11756 */
11757 ownerHasKeyUseWarning = {};
11758 ownerHasFunctionTypeWarning = {};
11759
11760 warnForMissingKey = function (child) {
11761 if (child === null || typeof child !== 'object') {
11762 return;
11763 }
11764 if (!child._store || child._store.validated || child.key != null) {
11765 return;
11766 }
11767 !(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;
11768 child._store.validated = true;
11769
11770 var currentComponentErrorInfo = 'Each child in a list should have a unique ' + '"key" prop. See https://fb.me/react-warning-keys for ' + 'more information.' + getCurrentFiberStackInDev();
11771 if (ownerHasKeyUseWarning[currentComponentErrorInfo]) {
11772 return;
11773 }
11774 ownerHasKeyUseWarning[currentComponentErrorInfo] = true;
11775
11776 warning$1(false, 'Each child in a list should have a unique ' + '"key" prop. See https://fb.me/react-warning-keys for ' + 'more information.');
11777 };
11778}
11779
11780var isArray = Array.isArray;
11781
11782function coerceRef(returnFiber, current$$1, element) {
11783 var mixedRef = element.ref;
11784 if (mixedRef !== null && typeof mixedRef !== 'function' && typeof mixedRef !== 'object') {
11785 {
11786 if (returnFiber.mode & StrictMode) {
11787 var componentName = getComponentName(returnFiber.type) || 'Component';
11788 if (!didWarnAboutStringRefInStrictMode[componentName]) {
11789 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));
11790 didWarnAboutStringRefInStrictMode[componentName] = true;
11791 }
11792 }
11793 }
11794
11795 if (element._owner) {
11796 var owner = element._owner;
11797 var inst = void 0;
11798 if (owner) {
11799 var ownerFiber = owner;
11800 !(ownerFiber.tag === ClassComponent) ? invariant(false, 'Function components cannot have refs. Did you mean to use React.forwardRef()?') : void 0;
11801 inst = ownerFiber.stateNode;
11802 }
11803 !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;
11804 var stringRef = '' + mixedRef;
11805 // Check if previous string ref matches new string ref
11806 if (current$$1 !== null && current$$1.ref !== null && typeof current$$1.ref === 'function' && current$$1.ref._stringRef === stringRef) {
11807 return current$$1.ref;
11808 }
11809 var ref = function (value) {
11810 var refs = inst.refs;
11811 if (refs === emptyRefsObject) {
11812 // This is a lazy pooled frozen object, so we need to initialize.
11813 refs = inst.refs = {};
11814 }
11815 if (value === null) {
11816 delete refs[stringRef];
11817 } else {
11818 refs[stringRef] = value;
11819 }
11820 };
11821 ref._stringRef = stringRef;
11822 return ref;
11823 } else {
11824 !(typeof mixedRef === 'string') ? invariant(false, 'Expected ref to be a function, a string, an object returned by React.createRef(), or null.') : void 0;
11825 !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;
11826 }
11827 }
11828 return mixedRef;
11829}
11830
11831function throwOnInvalidObjectType(returnFiber, newChild) {
11832 if (returnFiber.type !== 'textarea') {
11833 var addendum = '';
11834 {
11835 addendum = ' If you meant to render a collection of children, use an array ' + 'instead.' + getCurrentFiberStackInDev();
11836 }
11837 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);
11838 }
11839}
11840
11841function warnOnFunctionType() {
11842 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();
11843
11844 if (ownerHasFunctionTypeWarning[currentComponentErrorInfo]) {
11845 return;
11846 }
11847 ownerHasFunctionTypeWarning[currentComponentErrorInfo] = true;
11848
11849 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.');
11850}
11851
11852// This wrapper function exists because I expect to clone the code in each path
11853// to be able to optimize each path individually by branching early. This needs
11854// a compiler or we can do it manually. Helpers that don't need this branching
11855// live outside of this function.
11856function ChildReconciler(shouldTrackSideEffects) {
11857 function deleteChild(returnFiber, childToDelete) {
11858 if (!shouldTrackSideEffects) {
11859 // Noop.
11860 return;
11861 }
11862 // Deletions are added in reversed order so we add it to the front.
11863 // At this point, the return fiber's effect list is empty except for
11864 // deletions, so we can just append the deletion to the list. The remaining
11865 // effects aren't added until the complete phase. Once we implement
11866 // resuming, this may not be true.
11867 var last = returnFiber.lastEffect;
11868 if (last !== null) {
11869 last.nextEffect = childToDelete;
11870 returnFiber.lastEffect = childToDelete;
11871 } else {
11872 returnFiber.firstEffect = returnFiber.lastEffect = childToDelete;
11873 }
11874 childToDelete.nextEffect = null;
11875 childToDelete.effectTag = Deletion;
11876 }
11877
11878 function deleteRemainingChildren(returnFiber, currentFirstChild) {
11879 if (!shouldTrackSideEffects) {
11880 // Noop.
11881 return null;
11882 }
11883
11884 // TODO: For the shouldClone case, this could be micro-optimized a bit by
11885 // assuming that after the first child we've already added everything.
11886 var childToDelete = currentFirstChild;
11887 while (childToDelete !== null) {
11888 deleteChild(returnFiber, childToDelete);
11889 childToDelete = childToDelete.sibling;
11890 }
11891 return null;
11892 }
11893
11894 function mapRemainingChildren(returnFiber, currentFirstChild) {
11895 // Add the remaining children to a temporary map so that we can find them by
11896 // keys quickly. Implicit (null) keys get added to this set with their index
11897 var existingChildren = new Map();
11898
11899 var existingChild = currentFirstChild;
11900 while (existingChild !== null) {
11901 if (existingChild.key !== null) {
11902 existingChildren.set(existingChild.key, existingChild);
11903 } else {
11904 existingChildren.set(existingChild.index, existingChild);
11905 }
11906 existingChild = existingChild.sibling;
11907 }
11908 return existingChildren;
11909 }
11910
11911 function useFiber(fiber, pendingProps, expirationTime) {
11912 // We currently set sibling to null and index to 0 here because it is easy
11913 // to forget to do before returning it. E.g. for the single child case.
11914 var clone = createWorkInProgress(fiber, pendingProps, expirationTime);
11915 clone.index = 0;
11916 clone.sibling = null;
11917 return clone;
11918 }
11919
11920 function placeChild(newFiber, lastPlacedIndex, newIndex) {
11921 newFiber.index = newIndex;
11922 if (!shouldTrackSideEffects) {
11923 // Noop.
11924 return lastPlacedIndex;
11925 }
11926 var current$$1 = newFiber.alternate;
11927 if (current$$1 !== null) {
11928 var oldIndex = current$$1.index;
11929 if (oldIndex < lastPlacedIndex) {
11930 // This is a move.
11931 newFiber.effectTag = Placement;
11932 return lastPlacedIndex;
11933 } else {
11934 // This item can stay in place.
11935 return oldIndex;
11936 }
11937 } else {
11938 // This is an insertion.
11939 newFiber.effectTag = Placement;
11940 return lastPlacedIndex;
11941 }
11942 }
11943
11944 function placeSingleChild(newFiber) {
11945 // This is simpler for the single child case. We only need to do a
11946 // placement for inserting new children.
11947 if (shouldTrackSideEffects && newFiber.alternate === null) {
11948 newFiber.effectTag = Placement;
11949 }
11950 return newFiber;
11951 }
11952
11953 function updateTextNode(returnFiber, current$$1, textContent, expirationTime) {
11954 if (current$$1 === null || current$$1.tag !== HostText) {
11955 // Insert
11956 var created = createFiberFromText(textContent, returnFiber.mode, expirationTime);
11957 created.return = returnFiber;
11958 return created;
11959 } else {
11960 // Update
11961 var existing = useFiber(current$$1, textContent, expirationTime);
11962 existing.return = returnFiber;
11963 return existing;
11964 }
11965 }
11966
11967 function updateElement(returnFiber, current$$1, element, expirationTime) {
11968 if (current$$1 !== null && current$$1.elementType === element.type) {
11969 // Move based on index
11970 var existing = useFiber(current$$1, element.props, expirationTime);
11971 existing.ref = coerceRef(returnFiber, current$$1, element);
11972 existing.return = returnFiber;
11973 {
11974 existing._debugSource = element._source;
11975 existing._debugOwner = element._owner;
11976 }
11977 return existing;
11978 } else {
11979 // Insert
11980 var created = createFiberFromElement(element, returnFiber.mode, expirationTime);
11981 created.ref = coerceRef(returnFiber, current$$1, element);
11982 created.return = returnFiber;
11983 return created;
11984 }
11985 }
11986
11987 function updatePortal(returnFiber, current$$1, portal, expirationTime) {
11988 if (current$$1 === null || current$$1.tag !== HostPortal || current$$1.stateNode.containerInfo !== portal.containerInfo || current$$1.stateNode.implementation !== portal.implementation) {
11989 // Insert
11990 var created = createFiberFromPortal(portal, returnFiber.mode, expirationTime);
11991 created.return = returnFiber;
11992 return created;
11993 } else {
11994 // Update
11995 var existing = useFiber(current$$1, portal.children || [], expirationTime);
11996 existing.return = returnFiber;
11997 return existing;
11998 }
11999 }
12000
12001 function updateFragment(returnFiber, current$$1, fragment, expirationTime, key) {
12002 if (current$$1 === null || current$$1.tag !== Fragment) {
12003 // Insert
12004 var created = createFiberFromFragment(fragment, returnFiber.mode, expirationTime, key);
12005 created.return = returnFiber;
12006 return created;
12007 } else {
12008 // Update
12009 var existing = useFiber(current$$1, fragment, expirationTime);
12010 existing.return = returnFiber;
12011 return existing;
12012 }
12013 }
12014
12015 function createChild(returnFiber, newChild, expirationTime) {
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 var created = createFiberFromText('' + newChild, returnFiber.mode, expirationTime);
12021 created.return = returnFiber;
12022 return created;
12023 }
12024
12025 if (typeof newChild === 'object' && newChild !== null) {
12026 switch (newChild.$$typeof) {
12027 case REACT_ELEMENT_TYPE:
12028 {
12029 var _created = createFiberFromElement(newChild, returnFiber.mode, expirationTime);
12030 _created.ref = coerceRef(returnFiber, null, newChild);
12031 _created.return = returnFiber;
12032 return _created;
12033 }
12034 case REACT_PORTAL_TYPE:
12035 {
12036 var _created2 = createFiberFromPortal(newChild, returnFiber.mode, expirationTime);
12037 _created2.return = returnFiber;
12038 return _created2;
12039 }
12040 }
12041
12042 if (isArray(newChild) || getIteratorFn(newChild)) {
12043 var _created3 = createFiberFromFragment(newChild, returnFiber.mode, expirationTime, null);
12044 _created3.return = returnFiber;
12045 return _created3;
12046 }
12047
12048 throwOnInvalidObjectType(returnFiber, newChild);
12049 }
12050
12051 {
12052 if (typeof newChild === 'function') {
12053 warnOnFunctionType();
12054 }
12055 }
12056
12057 return null;
12058 }
12059
12060 function updateSlot(returnFiber, oldFiber, newChild, expirationTime) {
12061 // Update the fiber if the keys match, otherwise return null.
12062
12063 var key = oldFiber !== null ? oldFiber.key : null;
12064
12065 if (typeof newChild === 'string' || typeof newChild === 'number') {
12066 // Text nodes don't have keys. If the previous node is implicitly keyed
12067 // we can continue to replace it without aborting even if it is not a text
12068 // node.
12069 if (key !== null) {
12070 return null;
12071 }
12072 return updateTextNode(returnFiber, oldFiber, '' + newChild, expirationTime);
12073 }
12074
12075 if (typeof newChild === 'object' && newChild !== null) {
12076 switch (newChild.$$typeof) {
12077 case REACT_ELEMENT_TYPE:
12078 {
12079 if (newChild.key === key) {
12080 if (newChild.type === REACT_FRAGMENT_TYPE) {
12081 return updateFragment(returnFiber, oldFiber, newChild.props.children, expirationTime, key);
12082 }
12083 return updateElement(returnFiber, oldFiber, newChild, expirationTime);
12084 } else {
12085 return null;
12086 }
12087 }
12088 case REACT_PORTAL_TYPE:
12089 {
12090 if (newChild.key === key) {
12091 return updatePortal(returnFiber, oldFiber, newChild, expirationTime);
12092 } else {
12093 return null;
12094 }
12095 }
12096 }
12097
12098 if (isArray(newChild) || getIteratorFn(newChild)) {
12099 if (key !== null) {
12100 return null;
12101 }
12102
12103 return updateFragment(returnFiber, oldFiber, newChild, expirationTime, null);
12104 }
12105
12106 throwOnInvalidObjectType(returnFiber, newChild);
12107 }
12108
12109 {
12110 if (typeof newChild === 'function') {
12111 warnOnFunctionType();
12112 }
12113 }
12114
12115 return null;
12116 }
12117
12118 function updateFromMap(existingChildren, returnFiber, newIdx, newChild, expirationTime) {
12119 if (typeof newChild === 'string' || typeof newChild === 'number') {
12120 // Text nodes don't have keys, so we neither have to check the old nor
12121 // new node for the key. If both are text nodes, they match.
12122 var matchedFiber = existingChildren.get(newIdx) || null;
12123 return updateTextNode(returnFiber, matchedFiber, '' + newChild, expirationTime);
12124 }
12125
12126 if (typeof newChild === 'object' && newChild !== null) {
12127 switch (newChild.$$typeof) {
12128 case REACT_ELEMENT_TYPE:
12129 {
12130 var _matchedFiber = existingChildren.get(newChild.key === null ? newIdx : newChild.key) || null;
12131 if (newChild.type === REACT_FRAGMENT_TYPE) {
12132 return updateFragment(returnFiber, _matchedFiber, newChild.props.children, expirationTime, newChild.key);
12133 }
12134 return updateElement(returnFiber, _matchedFiber, newChild, expirationTime);
12135 }
12136 case REACT_PORTAL_TYPE:
12137 {
12138 var _matchedFiber2 = existingChildren.get(newChild.key === null ? newIdx : newChild.key) || null;
12139 return updatePortal(returnFiber, _matchedFiber2, newChild, expirationTime);
12140 }
12141 }
12142
12143 if (isArray(newChild) || getIteratorFn(newChild)) {
12144 var _matchedFiber3 = existingChildren.get(newIdx) || null;
12145 return updateFragment(returnFiber, _matchedFiber3, newChild, expirationTime, null);
12146 }
12147
12148 throwOnInvalidObjectType(returnFiber, newChild);
12149 }
12150
12151 {
12152 if (typeof newChild === 'function') {
12153 warnOnFunctionType();
12154 }
12155 }
12156
12157 return null;
12158 }
12159
12160 /**
12161 * Warns if there is a duplicate or missing key
12162 */
12163 function warnOnInvalidKey(child, knownKeys) {
12164 {
12165 if (typeof child !== 'object' || child === null) {
12166 return knownKeys;
12167 }
12168 switch (child.$$typeof) {
12169 case REACT_ELEMENT_TYPE:
12170 case REACT_PORTAL_TYPE:
12171 warnForMissingKey(child);
12172 var key = child.key;
12173 if (typeof key !== 'string') {
12174 break;
12175 }
12176 if (knownKeys === null) {
12177 knownKeys = new Set();
12178 knownKeys.add(key);
12179 break;
12180 }
12181 if (!knownKeys.has(key)) {
12182 knownKeys.add(key);
12183 break;
12184 }
12185 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);
12186 break;
12187 default:
12188 break;
12189 }
12190 }
12191 return knownKeys;
12192 }
12193
12194 function reconcileChildrenArray(returnFiber, currentFirstChild, newChildren, expirationTime) {
12195 // This algorithm can't optimize by searching from both ends since we
12196 // don't have backpointers on fibers. I'm trying to see how far we can get
12197 // with that model. If it ends up not being worth the tradeoffs, we can
12198 // add it later.
12199
12200 // Even with a two ended optimization, we'd want to optimize for the case
12201 // where there are few changes and brute force the comparison instead of
12202 // going for the Map. It'd like to explore hitting that path first in
12203 // forward-only mode and only go for the Map once we notice that we need
12204 // lots of look ahead. This doesn't handle reversal as well as two ended
12205 // search but that's unusual. Besides, for the two ended optimization to
12206 // work on Iterables, we'd need to copy the whole set.
12207
12208 // In this first iteration, we'll just live with hitting the bad case
12209 // (adding everything to a Map) in for every insert/move.
12210
12211 // If you change this code, also update reconcileChildrenIterator() which
12212 // uses the same algorithm.
12213
12214 {
12215 // First, validate keys.
12216 var knownKeys = null;
12217 for (var i = 0; i < newChildren.length; i++) {
12218 var child = newChildren[i];
12219 knownKeys = warnOnInvalidKey(child, knownKeys);
12220 }
12221 }
12222
12223 var resultingFirstChild = null;
12224 var previousNewFiber = null;
12225
12226 var oldFiber = currentFirstChild;
12227 var lastPlacedIndex = 0;
12228 var newIdx = 0;
12229 var nextOldFiber = null;
12230 for (; oldFiber !== null && newIdx < newChildren.length; newIdx++) {
12231 if (oldFiber.index > newIdx) {
12232 nextOldFiber = oldFiber;
12233 oldFiber = null;
12234 } else {
12235 nextOldFiber = oldFiber.sibling;
12236 }
12237 var newFiber = updateSlot(returnFiber, oldFiber, newChildren[newIdx], expirationTime);
12238 if (newFiber === null) {
12239 // TODO: This breaks on empty slots like null children. That's
12240 // unfortunate because it triggers the slow path all the time. We need
12241 // a better way to communicate whether this was a miss or null,
12242 // boolean, undefined, etc.
12243 if (oldFiber === null) {
12244 oldFiber = nextOldFiber;
12245 }
12246 break;
12247 }
12248 if (shouldTrackSideEffects) {
12249 if (oldFiber && newFiber.alternate === null) {
12250 // We matched the slot, but we didn't reuse the existing fiber, so we
12251 // need to delete the existing child.
12252 deleteChild(returnFiber, oldFiber);
12253 }
12254 }
12255 lastPlacedIndex = placeChild(newFiber, lastPlacedIndex, newIdx);
12256 if (previousNewFiber === null) {
12257 // TODO: Move out of the loop. This only happens for the first run.
12258 resultingFirstChild = newFiber;
12259 } else {
12260 // TODO: Defer siblings if we're not at the right index for this slot.
12261 // I.e. if we had null values before, then we want to defer this
12262 // for each null value. However, we also don't want to call updateSlot
12263 // with the previous one.
12264 previousNewFiber.sibling = newFiber;
12265 }
12266 previousNewFiber = newFiber;
12267 oldFiber = nextOldFiber;
12268 }
12269
12270 if (newIdx === newChildren.length) {
12271 // We've reached the end of the new children. We can delete the rest.
12272 deleteRemainingChildren(returnFiber, oldFiber);
12273 return resultingFirstChild;
12274 }
12275
12276 if (oldFiber === null) {
12277 // If we don't have any more existing children we can choose a fast path
12278 // since the rest will all be insertions.
12279 for (; newIdx < newChildren.length; newIdx++) {
12280 var _newFiber = createChild(returnFiber, newChildren[newIdx], expirationTime);
12281 if (!_newFiber) {
12282 continue;
12283 }
12284 lastPlacedIndex = placeChild(_newFiber, lastPlacedIndex, newIdx);
12285 if (previousNewFiber === null) {
12286 // TODO: Move out of the loop. This only happens for the first run.
12287 resultingFirstChild = _newFiber;
12288 } else {
12289 previousNewFiber.sibling = _newFiber;
12290 }
12291 previousNewFiber = _newFiber;
12292 }
12293 return resultingFirstChild;
12294 }
12295
12296 // Add all children to a key map for quick lookups.
12297 var existingChildren = mapRemainingChildren(returnFiber, oldFiber);
12298
12299 // Keep scanning and use the map to restore deleted items as moves.
12300 for (; newIdx < newChildren.length; newIdx++) {
12301 var _newFiber2 = updateFromMap(existingChildren, returnFiber, newIdx, newChildren[newIdx], expirationTime);
12302 if (_newFiber2) {
12303 if (shouldTrackSideEffects) {
12304 if (_newFiber2.alternate !== null) {
12305 // The new fiber is a work in progress, but if there exists a
12306 // current, that means that we reused the fiber. We need to delete
12307 // it from the child list so that we don't add it to the deletion
12308 // list.
12309 existingChildren.delete(_newFiber2.key === null ? newIdx : _newFiber2.key);
12310 }
12311 }
12312 lastPlacedIndex = placeChild(_newFiber2, lastPlacedIndex, newIdx);
12313 if (previousNewFiber === null) {
12314 resultingFirstChild = _newFiber2;
12315 } else {
12316 previousNewFiber.sibling = _newFiber2;
12317 }
12318 previousNewFiber = _newFiber2;
12319 }
12320 }
12321
12322 if (shouldTrackSideEffects) {
12323 // Any existing children that weren't consumed above were deleted. We need
12324 // to add them to the deletion list.
12325 existingChildren.forEach(function (child) {
12326 return deleteChild(returnFiber, child);
12327 });
12328 }
12329
12330 return resultingFirstChild;
12331 }
12332
12333 function reconcileChildrenIterator(returnFiber, currentFirstChild, newChildrenIterable, expirationTime) {
12334 // This is the same implementation as reconcileChildrenArray(),
12335 // but using the iterator instead.
12336
12337 var iteratorFn = getIteratorFn(newChildrenIterable);
12338 !(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;
12339
12340 {
12341 // We don't support rendering Generators because it's a mutation.
12342 // See https://github.com/facebook/react/issues/12995
12343 if (typeof Symbol === 'function' &&
12344 // $FlowFixMe Flow doesn't know about toStringTag
12345 newChildrenIterable[Symbol.toStringTag] === 'Generator') {
12346 !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;
12347 didWarnAboutGenerators = true;
12348 }
12349
12350 // Warn about using Maps as children
12351 if (newChildrenIterable.entries === iteratorFn) {
12352 !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;
12353 didWarnAboutMaps = true;
12354 }
12355
12356 // First, validate keys.
12357 // We'll get a different iterator later for the main pass.
12358 var _newChildren = iteratorFn.call(newChildrenIterable);
12359 if (_newChildren) {
12360 var knownKeys = null;
12361 var _step = _newChildren.next();
12362 for (; !_step.done; _step = _newChildren.next()) {
12363 var child = _step.value;
12364 knownKeys = warnOnInvalidKey(child, knownKeys);
12365 }
12366 }
12367 }
12368
12369 var newChildren = iteratorFn.call(newChildrenIterable);
12370 !(newChildren != null) ? invariant(false, 'An iterable object provided no iterator.') : void 0;
12371
12372 var resultingFirstChild = null;
12373 var previousNewFiber = null;
12374
12375 var oldFiber = currentFirstChild;
12376 var lastPlacedIndex = 0;
12377 var newIdx = 0;
12378 var nextOldFiber = null;
12379
12380 var step = newChildren.next();
12381 for (; oldFiber !== null && !step.done; newIdx++, step = newChildren.next()) {
12382 if (oldFiber.index > newIdx) {
12383 nextOldFiber = oldFiber;
12384 oldFiber = null;
12385 } else {
12386 nextOldFiber = oldFiber.sibling;
12387 }
12388 var newFiber = updateSlot(returnFiber, oldFiber, step.value, expirationTime);
12389 if (newFiber === null) {
12390 // TODO: This breaks on empty slots like null children. That's
12391 // unfortunate because it triggers the slow path all the time. We need
12392 // a better way to communicate whether this was a miss or null,
12393 // boolean, undefined, etc.
12394 if (!oldFiber) {
12395 oldFiber = nextOldFiber;
12396 }
12397 break;
12398 }
12399 if (shouldTrackSideEffects) {
12400 if (oldFiber && newFiber.alternate === null) {
12401 // We matched the slot, but we didn't reuse the existing fiber, so we
12402 // need to delete the existing child.
12403 deleteChild(returnFiber, oldFiber);
12404 }
12405 }
12406 lastPlacedIndex = placeChild(newFiber, lastPlacedIndex, newIdx);
12407 if (previousNewFiber === null) {
12408 // TODO: Move out of the loop. This only happens for the first run.
12409 resultingFirstChild = newFiber;
12410 } else {
12411 // TODO: Defer siblings if we're not at the right index for this slot.
12412 // I.e. if we had null values before, then we want to defer this
12413 // for each null value. However, we also don't want to call updateSlot
12414 // with the previous one.
12415 previousNewFiber.sibling = newFiber;
12416 }
12417 previousNewFiber = newFiber;
12418 oldFiber = nextOldFiber;
12419 }
12420
12421 if (step.done) {
12422 // We've reached the end of the new children. We can delete the rest.
12423 deleteRemainingChildren(returnFiber, oldFiber);
12424 return resultingFirstChild;
12425 }
12426
12427 if (oldFiber === null) {
12428 // If we don't have any more existing children we can choose a fast path
12429 // since the rest will all be insertions.
12430 for (; !step.done; newIdx++, step = newChildren.next()) {
12431 var _newFiber3 = createChild(returnFiber, step.value, expirationTime);
12432 if (_newFiber3 === null) {
12433 continue;
12434 }
12435 lastPlacedIndex = placeChild(_newFiber3, lastPlacedIndex, newIdx);
12436 if (previousNewFiber === null) {
12437 // TODO: Move out of the loop. This only happens for the first run.
12438 resultingFirstChild = _newFiber3;
12439 } else {
12440 previousNewFiber.sibling = _newFiber3;
12441 }
12442 previousNewFiber = _newFiber3;
12443 }
12444 return resultingFirstChild;
12445 }
12446
12447 // Add all children to a key map for quick lookups.
12448 var existingChildren = mapRemainingChildren(returnFiber, oldFiber);
12449
12450 // Keep scanning and use the map to restore deleted items as moves.
12451 for (; !step.done; newIdx++, step = newChildren.next()) {
12452 var _newFiber4 = updateFromMap(existingChildren, returnFiber, newIdx, step.value, expirationTime);
12453 if (_newFiber4 !== null) {
12454 if (shouldTrackSideEffects) {
12455 if (_newFiber4.alternate !== null) {
12456 // The new fiber is a work in progress, but if there exists a
12457 // current, that means that we reused the fiber. We need to delete
12458 // it from the child list so that we don't add it to the deletion
12459 // list.
12460 existingChildren.delete(_newFiber4.key === null ? newIdx : _newFiber4.key);
12461 }
12462 }
12463 lastPlacedIndex = placeChild(_newFiber4, lastPlacedIndex, newIdx);
12464 if (previousNewFiber === null) {
12465 resultingFirstChild = _newFiber4;
12466 } else {
12467 previousNewFiber.sibling = _newFiber4;
12468 }
12469 previousNewFiber = _newFiber4;
12470 }
12471 }
12472
12473 if (shouldTrackSideEffects) {
12474 // Any existing children that weren't consumed above were deleted. We need
12475 // to add them to the deletion list.
12476 existingChildren.forEach(function (child) {
12477 return deleteChild(returnFiber, child);
12478 });
12479 }
12480
12481 return resultingFirstChild;
12482 }
12483
12484 function reconcileSingleTextNode(returnFiber, currentFirstChild, textContent, expirationTime) {
12485 // There's no need to check for keys on text nodes since we don't have a
12486 // way to define them.
12487 if (currentFirstChild !== null && currentFirstChild.tag === HostText) {
12488 // We already have an existing node so let's just update it and delete
12489 // the rest.
12490 deleteRemainingChildren(returnFiber, currentFirstChild.sibling);
12491 var existing = useFiber(currentFirstChild, textContent, expirationTime);
12492 existing.return = returnFiber;
12493 return existing;
12494 }
12495 // The existing first child is not a text node so we need to create one
12496 // and delete the existing ones.
12497 deleteRemainingChildren(returnFiber, currentFirstChild);
12498 var created = createFiberFromText(textContent, returnFiber.mode, expirationTime);
12499 created.return = returnFiber;
12500 return created;
12501 }
12502
12503 function reconcileSingleElement(returnFiber, currentFirstChild, element, expirationTime) {
12504 var key = element.key;
12505 var child = currentFirstChild;
12506 while (child !== null) {
12507 // TODO: If key === null and child.key === null, then this only applies to
12508 // the first item in the list.
12509 if (child.key === key) {
12510 if (child.tag === Fragment ? element.type === REACT_FRAGMENT_TYPE : child.elementType === element.type) {
12511 deleteRemainingChildren(returnFiber, child.sibling);
12512 var existing = useFiber(child, element.type === REACT_FRAGMENT_TYPE ? element.props.children : element.props, expirationTime);
12513 existing.ref = coerceRef(returnFiber, child, element);
12514 existing.return = returnFiber;
12515 {
12516 existing._debugSource = element._source;
12517 existing._debugOwner = element._owner;
12518 }
12519 return existing;
12520 } else {
12521 deleteRemainingChildren(returnFiber, child);
12522 break;
12523 }
12524 } else {
12525 deleteChild(returnFiber, child);
12526 }
12527 child = child.sibling;
12528 }
12529
12530 if (element.type === REACT_FRAGMENT_TYPE) {
12531 var created = createFiberFromFragment(element.props.children, returnFiber.mode, expirationTime, element.key);
12532 created.return = returnFiber;
12533 return created;
12534 } else {
12535 var _created4 = createFiberFromElement(element, returnFiber.mode, expirationTime);
12536 _created4.ref = coerceRef(returnFiber, currentFirstChild, element);
12537 _created4.return = returnFiber;
12538 return _created4;
12539 }
12540 }
12541
12542 function reconcileSinglePortal(returnFiber, currentFirstChild, portal, expirationTime) {
12543 var key = portal.key;
12544 var child = currentFirstChild;
12545 while (child !== null) {
12546 // TODO: If key === null and child.key === null, then this only applies to
12547 // the first item in the list.
12548 if (child.key === key) {
12549 if (child.tag === HostPortal && child.stateNode.containerInfo === portal.containerInfo && child.stateNode.implementation === portal.implementation) {
12550 deleteRemainingChildren(returnFiber, child.sibling);
12551 var existing = useFiber(child, portal.children || [], expirationTime);
12552 existing.return = returnFiber;
12553 return existing;
12554 } else {
12555 deleteRemainingChildren(returnFiber, child);
12556 break;
12557 }
12558 } else {
12559 deleteChild(returnFiber, child);
12560 }
12561 child = child.sibling;
12562 }
12563
12564 var created = createFiberFromPortal(portal, returnFiber.mode, expirationTime);
12565 created.return = returnFiber;
12566 return created;
12567 }
12568
12569 // This API will tag the children with the side-effect of the reconciliation
12570 // itself. They will be added to the side-effect list as we pass through the
12571 // children and the parent.
12572 function reconcileChildFibers(returnFiber, currentFirstChild, newChild, expirationTime) {
12573 // This function is not recursive.
12574 // If the top level item is an array, we treat it as a set of children,
12575 // not as a fragment. Nested arrays on the other hand will be treated as
12576 // fragment nodes. Recursion happens at the normal flow.
12577
12578 // Handle top level unkeyed fragments as if they were arrays.
12579 // This leads to an ambiguity between <>{[...]}</> and <>...</>.
12580 // We treat the ambiguous cases above the same.
12581 var isUnkeyedTopLevelFragment = typeof newChild === 'object' && newChild !== null && newChild.type === REACT_FRAGMENT_TYPE && newChild.key === null;
12582 if (isUnkeyedTopLevelFragment) {
12583 newChild = newChild.props.children;
12584 }
12585
12586 // Handle object types
12587 var isObject = typeof newChild === 'object' && newChild !== null;
12588
12589 if (isObject) {
12590 switch (newChild.$$typeof) {
12591 case REACT_ELEMENT_TYPE:
12592 return placeSingleChild(reconcileSingleElement(returnFiber, currentFirstChild, newChild, expirationTime));
12593 case REACT_PORTAL_TYPE:
12594 return placeSingleChild(reconcileSinglePortal(returnFiber, currentFirstChild, newChild, expirationTime));
12595 }
12596 }
12597
12598 if (typeof newChild === 'string' || typeof newChild === 'number') {
12599 return placeSingleChild(reconcileSingleTextNode(returnFiber, currentFirstChild, '' + newChild, expirationTime));
12600 }
12601
12602 if (isArray(newChild)) {
12603 return reconcileChildrenArray(returnFiber, currentFirstChild, newChild, expirationTime);
12604 }
12605
12606 if (getIteratorFn(newChild)) {
12607 return reconcileChildrenIterator(returnFiber, currentFirstChild, newChild, expirationTime);
12608 }
12609
12610 if (isObject) {
12611 throwOnInvalidObjectType(returnFiber, newChild);
12612 }
12613
12614 {
12615 if (typeof newChild === 'function') {
12616 warnOnFunctionType();
12617 }
12618 }
12619 if (typeof newChild === 'undefined' && !isUnkeyedTopLevelFragment) {
12620 // If the new child is undefined, and the return fiber is a composite
12621 // component, throw an error. If Fiber return types are disabled,
12622 // we already threw above.
12623 switch (returnFiber.tag) {
12624 case ClassComponent:
12625 {
12626 {
12627 var instance = returnFiber.stateNode;
12628 if (instance.render._isMockFunction) {
12629 // We allow auto-mocks to proceed as if they're returning null.
12630 break;
12631 }
12632 }
12633 }
12634 // Intentionally fall through to the next case, which handles both
12635 // functions and classes
12636 // eslint-disable-next-lined no-fallthrough
12637 case FunctionComponent:
12638 {
12639 var Component = returnFiber.type;
12640 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');
12641 }
12642 }
12643 }
12644
12645 // Remaining cases are all treated as empty.
12646 return deleteRemainingChildren(returnFiber, currentFirstChild);
12647 }
12648
12649 return reconcileChildFibers;
12650}
12651
12652var reconcileChildFibers = ChildReconciler(true);
12653var mountChildFibers = ChildReconciler(false);
12654
12655function cloneChildFibers(current$$1, workInProgress) {
12656 !(current$$1 === null || workInProgress.child === current$$1.child) ? invariant(false, 'Resuming work not yet implemented.') : void 0;
12657
12658 if (workInProgress.child === null) {
12659 return;
12660 }
12661
12662 var currentChild = workInProgress.child;
12663 var newChild = createWorkInProgress(currentChild, currentChild.pendingProps, currentChild.expirationTime);
12664 workInProgress.child = newChild;
12665
12666 newChild.return = workInProgress;
12667 while (currentChild.sibling !== null) {
12668 currentChild = currentChild.sibling;
12669 newChild = newChild.sibling = createWorkInProgress(currentChild, currentChild.pendingProps, currentChild.expirationTime);
12670 newChild.return = workInProgress;
12671 }
12672 newChild.sibling = null;
12673}
12674
12675var NO_CONTEXT = {};
12676
12677var contextStackCursor$1 = createCursor(NO_CONTEXT);
12678var contextFiberStackCursor = createCursor(NO_CONTEXT);
12679var rootInstanceStackCursor = createCursor(NO_CONTEXT);
12680
12681function requiredContext(c) {
12682 !(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;
12683 return c;
12684}
12685
12686function getRootHostContainer() {
12687 var rootInstance = requiredContext(rootInstanceStackCursor.current);
12688 return rootInstance;
12689}
12690
12691function pushHostContainer(fiber, nextRootInstance) {
12692 // Push current root instance onto the stack;
12693 // This allows us to reset root when portals are popped.
12694 push(rootInstanceStackCursor, nextRootInstance, fiber);
12695 // Track the context and the Fiber that provided it.
12696 // This enables us to pop only Fibers that provide unique contexts.
12697 push(contextFiberStackCursor, fiber, fiber);
12698
12699 // Finally, we need to push the host context to the stack.
12700 // However, we can't just call getRootHostContext() and push it because
12701 // we'd have a different number of entries on the stack depending on
12702 // whether getRootHostContext() throws somewhere in renderer code or not.
12703 // So we push an empty value first. This lets us safely unwind on errors.
12704 push(contextStackCursor$1, NO_CONTEXT, fiber);
12705 var nextRootContext = getRootHostContext(nextRootInstance);
12706 // Now that we know this function doesn't throw, replace it.
12707 pop(contextStackCursor$1, fiber);
12708 push(contextStackCursor$1, nextRootContext, fiber);
12709}
12710
12711function popHostContainer(fiber) {
12712 pop(contextStackCursor$1, fiber);
12713 pop(contextFiberStackCursor, fiber);
12714 pop(rootInstanceStackCursor, fiber);
12715}
12716
12717function getHostContext() {
12718 var context = requiredContext(contextStackCursor$1.current);
12719 return context;
12720}
12721
12722function pushHostContext(fiber) {
12723 var rootInstance = requiredContext(rootInstanceStackCursor.current);
12724 var context = requiredContext(contextStackCursor$1.current);
12725 var nextContext = getChildHostContext(context, fiber.type, rootInstance);
12726
12727 // Don't push this Fiber's context unless it's unique.
12728 if (context === nextContext) {
12729 return;
12730 }
12731
12732 // Track the context and the Fiber that provided it.
12733 // This enables us to pop only Fibers that provide unique contexts.
12734 push(contextFiberStackCursor, fiber, fiber);
12735 push(contextStackCursor$1, nextContext, fiber);
12736}
12737
12738function popHostContext(fiber) {
12739 // Do not pop unless this Fiber provided the current context.
12740 // pushHostContext() only pushes Fibers that provide unique contexts.
12741 if (contextFiberStackCursor.current !== fiber) {
12742 return;
12743 }
12744
12745 pop(contextStackCursor$1, fiber);
12746 pop(contextFiberStackCursor, fiber);
12747}
12748
12749var NoEffect$1 = /* */0;
12750var UnmountSnapshot = /* */2;
12751var UnmountMutation = /* */4;
12752var MountMutation = /* */8;
12753var UnmountLayout = /* */16;
12754var MountLayout = /* */32;
12755var MountPassive = /* */64;
12756var UnmountPassive = /* */128;
12757
12758var ReactCurrentDispatcher$1 = ReactSharedInternals.ReactCurrentDispatcher;
12759
12760
12761var didWarnAboutMismatchedHooksForComponent = void 0;
12762{
12763 didWarnAboutMismatchedHooksForComponent = new Set();
12764}
12765
12766// These are set right before calling the component.
12767var renderExpirationTime = NoWork;
12768// The work-in-progress fiber. I've named it differently to distinguish it from
12769// the work-in-progress hook.
12770var currentlyRenderingFiber$1 = null;
12771
12772// Hooks are stored as a linked list on the fiber's memoizedState field. The
12773// current hook list is the list that belongs to the current fiber. The
12774// work-in-progress hook list is a new list that will be added to the
12775// work-in-progress fiber.
12776var currentHook = null;
12777var nextCurrentHook = null;
12778var firstWorkInProgressHook = null;
12779var workInProgressHook = null;
12780var nextWorkInProgressHook = null;
12781
12782var remainingExpirationTime = NoWork;
12783var componentUpdateQueue = null;
12784var sideEffectTag = 0;
12785
12786// Updates scheduled during render will trigger an immediate re-render at the
12787// end of the current pass. We can't store these updates on the normal queue,
12788// because if the work is aborted, they should be discarded. Because this is
12789// a relatively rare case, we also don't want to add an additional field to
12790// either the hook or queue object types. So we store them in a lazily create
12791// map of queue -> render-phase updates, which are discarded once the component
12792// completes without re-rendering.
12793
12794// Whether an update was scheduled during the currently executing render pass.
12795var didScheduleRenderPhaseUpdate = false;
12796// Lazily created map of render-phase updates
12797var renderPhaseUpdates = null;
12798// Counter to prevent infinite loops.
12799var numberOfReRenders = 0;
12800var RE_RENDER_LIMIT = 25;
12801
12802// In DEV, this is the name of the currently executing primitive hook
12803var currentHookNameInDev = null;
12804
12805// In DEV, this list ensures that hooks are called in the same order between renders.
12806// The list stores the order of hooks used during the initial render (mount).
12807// Subsequent renders (updates) reference this list.
12808var hookTypesDev = null;
12809var hookTypesUpdateIndexDev = -1;
12810
12811function mountHookTypesDev() {
12812 {
12813 var hookName = currentHookNameInDev;
12814
12815 if (hookTypesDev === null) {
12816 hookTypesDev = [hookName];
12817 } else {
12818 hookTypesDev.push(hookName);
12819 }
12820 }
12821}
12822
12823function updateHookTypesDev() {
12824 {
12825 var hookName = currentHookNameInDev;
12826
12827 if (hookTypesDev !== null) {
12828 hookTypesUpdateIndexDev++;
12829 if (hookTypesDev[hookTypesUpdateIndexDev] !== hookName) {
12830 warnOnHookMismatchInDev(hookName);
12831 }
12832 }
12833 }
12834}
12835
12836function warnOnHookMismatchInDev(currentHookName) {
12837 {
12838 var componentName = getComponentName(currentlyRenderingFiber$1.type);
12839 if (!didWarnAboutMismatchedHooksForComponent.has(componentName)) {
12840 didWarnAboutMismatchedHooksForComponent.add(componentName);
12841
12842 if (hookTypesDev !== null) {
12843 var table = '';
12844
12845 var secondColumnStart = 30;
12846
12847 for (var i = 0; i <= hookTypesUpdateIndexDev; i++) {
12848 var oldHookName = hookTypesDev[i];
12849 var newHookName = i === hookTypesUpdateIndexDev ? currentHookName : oldHookName;
12850
12851 var row = i + 1 + '. ' + oldHookName;
12852
12853 // Extra space so second column lines up
12854 // lol @ IE not supporting String#repeat
12855 while (row.length < secondColumnStart) {
12856 row += ' ';
12857 }
12858
12859 row += newHookName + '\n';
12860
12861 table += row;
12862 }
12863
12864 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);
12865 }
12866 }
12867 }
12868}
12869
12870function throwInvalidHookError() {
12871 invariant(false, 'Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:\n1. You might have mismatching versions of React and the renderer (such as React DOM)\n2. You might be breaking the Rules of Hooks\n3. You might have more than one copy of React in the same app\nSee https://fb.me/react-invalid-hook-call for tips about how to debug and fix this problem.');
12872}
12873
12874function areHookInputsEqual(nextDeps, prevDeps) {
12875 if (prevDeps === null) {
12876 {
12877 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);
12878 }
12879 return false;
12880 }
12881
12882 {
12883 // Don't bother comparing lengths in prod because these arrays should be
12884 // passed inline.
12885 if (nextDeps.length !== prevDeps.length) {
12886 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(', ') + ']');
12887 }
12888 }
12889 for (var i = 0; i < prevDeps.length && i < nextDeps.length; i++) {
12890 if (is(nextDeps[i], prevDeps[i])) {
12891 continue;
12892 }
12893 return false;
12894 }
12895 return true;
12896}
12897
12898function renderWithHooks(current, workInProgress, Component, props, refOrContext, nextRenderExpirationTime) {
12899 renderExpirationTime = nextRenderExpirationTime;
12900 currentlyRenderingFiber$1 = workInProgress;
12901 nextCurrentHook = current !== null ? current.memoizedState : null;
12902
12903 {
12904 hookTypesDev = current !== null ? current._debugHookTypes : null;
12905 hookTypesUpdateIndexDev = -1;
12906 }
12907
12908 // The following should have already been reset
12909 // currentHook = null;
12910 // workInProgressHook = null;
12911
12912 // remainingExpirationTime = NoWork;
12913 // componentUpdateQueue = null;
12914
12915 // didScheduleRenderPhaseUpdate = false;
12916 // renderPhaseUpdates = null;
12917 // numberOfReRenders = 0;
12918 // sideEffectTag = 0;
12919
12920 // TODO Warn if no hooks are used at all during mount, then some are used during update.
12921 // Currently we will identify the update render as a mount because nextCurrentHook === null.
12922 // This is tricky because it's valid for certain types of components (e.g. React.lazy)
12923
12924 // Using nextCurrentHook to differentiate between mount/update only works if at least one stateful hook is used.
12925 // Non-stateful hooks (e.g. context) don't get added to memoizedState,
12926 // so nextCurrentHook would be null during updates and mounts.
12927 {
12928 if (nextCurrentHook !== null) {
12929 ReactCurrentDispatcher$1.current = HooksDispatcherOnUpdateInDEV;
12930 } else if (hookTypesDev !== null) {
12931 // This dispatcher handles an edge case where a component is updating,
12932 // but no stateful hooks have been used.
12933 // We want to match the production code behavior (which will use HooksDispatcherOnMount),
12934 // but with the extra DEV validation to ensure hooks ordering hasn't changed.
12935 // This dispatcher does that.
12936 ReactCurrentDispatcher$1.current = HooksDispatcherOnMountWithHookTypesInDEV;
12937 } else {
12938 ReactCurrentDispatcher$1.current = HooksDispatcherOnMountInDEV;
12939 }
12940 }
12941
12942 var children = Component(props, refOrContext);
12943
12944 if (didScheduleRenderPhaseUpdate) {
12945 do {
12946 didScheduleRenderPhaseUpdate = false;
12947 numberOfReRenders += 1;
12948
12949 // Start over from the beginning of the list
12950 nextCurrentHook = current !== null ? current.memoizedState : null;
12951 nextWorkInProgressHook = firstWorkInProgressHook;
12952
12953 currentHook = null;
12954 workInProgressHook = null;
12955 componentUpdateQueue = null;
12956
12957 {
12958 // Also validate hook order for cascading updates.
12959 hookTypesUpdateIndexDev = -1;
12960 }
12961
12962 ReactCurrentDispatcher$1.current = HooksDispatcherOnUpdateInDEV;
12963
12964 children = Component(props, refOrContext);
12965 } while (didScheduleRenderPhaseUpdate);
12966
12967 renderPhaseUpdates = null;
12968 numberOfReRenders = 0;
12969 }
12970
12971 // We can assume the previous dispatcher is always this one, since we set it
12972 // at the beginning of the render phase and there's no re-entrancy.
12973 ReactCurrentDispatcher$1.current = ContextOnlyDispatcher;
12974
12975 var renderedWork = currentlyRenderingFiber$1;
12976
12977 renderedWork.memoizedState = firstWorkInProgressHook;
12978 renderedWork.expirationTime = remainingExpirationTime;
12979 renderedWork.updateQueue = componentUpdateQueue;
12980 renderedWork.effectTag |= sideEffectTag;
12981
12982 {
12983 renderedWork._debugHookTypes = hookTypesDev;
12984 }
12985
12986 // This check uses currentHook so that it works the same in DEV and prod bundles.
12987 // hookTypesDev could catch more cases (e.g. context) but only in DEV bundles.
12988 var didRenderTooFewHooks = currentHook !== null && currentHook.next !== null;
12989
12990 renderExpirationTime = NoWork;
12991 currentlyRenderingFiber$1 = null;
12992
12993 currentHook = null;
12994 nextCurrentHook = null;
12995 firstWorkInProgressHook = null;
12996 workInProgressHook = null;
12997 nextWorkInProgressHook = null;
12998
12999 {
13000 currentHookNameInDev = null;
13001 hookTypesDev = null;
13002 hookTypesUpdateIndexDev = -1;
13003 }
13004
13005 remainingExpirationTime = NoWork;
13006 componentUpdateQueue = null;
13007 sideEffectTag = 0;
13008
13009 // These were reset above
13010 // didScheduleRenderPhaseUpdate = false;
13011 // renderPhaseUpdates = null;
13012 // numberOfReRenders = 0;
13013
13014 !!didRenderTooFewHooks ? invariant(false, 'Rendered fewer hooks than expected. This may be caused by an accidental early return statement.') : void 0;
13015
13016 return children;
13017}
13018
13019function bailoutHooks(current, workInProgress, expirationTime) {
13020 workInProgress.updateQueue = current.updateQueue;
13021 workInProgress.effectTag &= ~(Passive | Update);
13022 if (current.expirationTime <= expirationTime) {
13023 current.expirationTime = NoWork;
13024 }
13025}
13026
13027function resetHooks() {
13028 // We can assume the previous dispatcher is always this one, since we set it
13029 // at the beginning of the render phase and there's no re-entrancy.
13030 ReactCurrentDispatcher$1.current = ContextOnlyDispatcher;
13031
13032 // This is used to reset the state of this module when a component throws.
13033 // It's also called inside mountIndeterminateComponent if we determine the
13034 // component is a module-style component.
13035 renderExpirationTime = NoWork;
13036 currentlyRenderingFiber$1 = null;
13037
13038 currentHook = null;
13039 nextCurrentHook = null;
13040 firstWorkInProgressHook = null;
13041 workInProgressHook = null;
13042 nextWorkInProgressHook = null;
13043
13044 {
13045 hookTypesDev = null;
13046 hookTypesUpdateIndexDev = -1;
13047
13048 currentHookNameInDev = null;
13049 }
13050
13051 remainingExpirationTime = NoWork;
13052 componentUpdateQueue = null;
13053 sideEffectTag = 0;
13054
13055 didScheduleRenderPhaseUpdate = false;
13056 renderPhaseUpdates = null;
13057 numberOfReRenders = 0;
13058}
13059
13060function mountWorkInProgressHook() {
13061 var hook = {
13062 memoizedState: null,
13063
13064 baseState: null,
13065 queue: null,
13066 baseUpdate: null,
13067
13068 next: null
13069 };
13070
13071 if (workInProgressHook === null) {
13072 // This is the first hook in the list
13073 firstWorkInProgressHook = workInProgressHook = hook;
13074 } else {
13075 // Append to the end of the list
13076 workInProgressHook = workInProgressHook.next = hook;
13077 }
13078 return workInProgressHook;
13079}
13080
13081function updateWorkInProgressHook() {
13082 // This function is used both for updates and for re-renders triggered by a
13083 // render phase update. It assumes there is either a current hook we can
13084 // clone, or a work-in-progress hook from a previous render pass that we can
13085 // use as a base. When we reach the end of the base list, we must switch to
13086 // the dispatcher used for mounts.
13087 if (nextWorkInProgressHook !== null) {
13088 // There's already a work-in-progress. Reuse it.
13089 workInProgressHook = nextWorkInProgressHook;
13090 nextWorkInProgressHook = workInProgressHook.next;
13091
13092 currentHook = nextCurrentHook;
13093 nextCurrentHook = currentHook !== null ? currentHook.next : null;
13094 } else {
13095 // Clone from the current hook.
13096 !(nextCurrentHook !== null) ? invariant(false, 'Rendered more hooks than during the previous render.') : void 0;
13097 currentHook = nextCurrentHook;
13098
13099 var newHook = {
13100 memoizedState: currentHook.memoizedState,
13101
13102 baseState: currentHook.baseState,
13103 queue: currentHook.queue,
13104 baseUpdate: currentHook.baseUpdate,
13105
13106 next: null
13107 };
13108
13109 if (workInProgressHook === null) {
13110 // This is the first hook in the list.
13111 workInProgressHook = firstWorkInProgressHook = newHook;
13112 } else {
13113 // Append to the end of the list.
13114 workInProgressHook = workInProgressHook.next = newHook;
13115 }
13116 nextCurrentHook = currentHook.next;
13117 }
13118 return workInProgressHook;
13119}
13120
13121function createFunctionComponentUpdateQueue() {
13122 return {
13123 lastEffect: null
13124 };
13125}
13126
13127function basicStateReducer(state, action) {
13128 return typeof action === 'function' ? action(state) : action;
13129}
13130
13131function mountReducer(reducer, initialArg, init) {
13132 var hook = mountWorkInProgressHook();
13133 var initialState = void 0;
13134 if (init !== undefined) {
13135 initialState = init(initialArg);
13136 } else {
13137 initialState = initialArg;
13138 }
13139 hook.memoizedState = hook.baseState = initialState;
13140 var queue = hook.queue = {
13141 last: null,
13142 dispatch: null,
13143 lastRenderedReducer: reducer,
13144 lastRenderedState: initialState
13145 };
13146 var dispatch = queue.dispatch = dispatchAction.bind(null,
13147 // Flow doesn't know this is non-null, but we do.
13148 currentlyRenderingFiber$1, queue);
13149 return [hook.memoizedState, dispatch];
13150}
13151
13152function updateReducer(reducer, initialArg, init) {
13153 var hook = updateWorkInProgressHook();
13154 var queue = hook.queue;
13155 !(queue !== null) ? invariant(false, 'Should have a queue. This is likely a bug in React. Please file an issue.') : void 0;
13156
13157 queue.lastRenderedReducer = reducer;
13158
13159 if (numberOfReRenders > 0) {
13160 // This is a re-render. Apply the new render phase updates to the previous
13161 var _dispatch = queue.dispatch;
13162 if (renderPhaseUpdates !== null) {
13163 // Render phase updates are stored in a map of queue -> linked list
13164 var firstRenderPhaseUpdate = renderPhaseUpdates.get(queue);
13165 if (firstRenderPhaseUpdate !== undefined) {
13166 renderPhaseUpdates.delete(queue);
13167 var newState = hook.memoizedState;
13168 var update = firstRenderPhaseUpdate;
13169 do {
13170 // Process this render phase update. We don't have to check the
13171 // priority because it will always be the same as the current
13172 // render's.
13173 var _action = update.action;
13174 newState = reducer(newState, _action);
13175 update = update.next;
13176 } while (update !== null);
13177
13178 // Mark that the fiber performed work, but only if the new state is
13179 // different from the current state.
13180 if (!is(newState, hook.memoizedState)) {
13181 markWorkInProgressReceivedUpdate();
13182 }
13183
13184 hook.memoizedState = newState;
13185 // Don't persist the state accumlated from the render phase updates to
13186 // the base state unless the queue is empty.
13187 // TODO: Not sure if this is the desired semantics, but it's what we
13188 // do for gDSFP. I can't remember why.
13189 if (hook.baseUpdate === queue.last) {
13190 hook.baseState = newState;
13191 }
13192
13193 queue.lastRenderedState = newState;
13194
13195 return [newState, _dispatch];
13196 }
13197 }
13198 return [hook.memoizedState, _dispatch];
13199 }
13200
13201 // The last update in the entire queue
13202 var last = queue.last;
13203 // The last update that is part of the base state.
13204 var baseUpdate = hook.baseUpdate;
13205 var baseState = hook.baseState;
13206
13207 // Find the first unprocessed update.
13208 var first = void 0;
13209 if (baseUpdate !== null) {
13210 if (last !== null) {
13211 // For the first update, the queue is a circular linked list where
13212 // `queue.last.next = queue.first`. Once the first update commits, and
13213 // the `baseUpdate` is no longer empty, we can unravel the list.
13214 last.next = null;
13215 }
13216 first = baseUpdate.next;
13217 } else {
13218 first = last !== null ? last.next : null;
13219 }
13220 if (first !== null) {
13221 var _newState = baseState;
13222 var newBaseState = null;
13223 var newBaseUpdate = null;
13224 var prevUpdate = baseUpdate;
13225 var _update = first;
13226 var didSkip = false;
13227 do {
13228 var updateExpirationTime = _update.expirationTime;
13229 if (updateExpirationTime < renderExpirationTime) {
13230 // Priority is insufficient. Skip this update. If this is the first
13231 // skipped update, the previous update/state is the new base
13232 // update/state.
13233 if (!didSkip) {
13234 didSkip = true;
13235 newBaseUpdate = prevUpdate;
13236 newBaseState = _newState;
13237 }
13238 // Update the remaining priority in the queue.
13239 if (updateExpirationTime > remainingExpirationTime) {
13240 remainingExpirationTime = updateExpirationTime;
13241 }
13242 } else {
13243 // Process this update.
13244 if (_update.eagerReducer === reducer) {
13245 // If this update was processed eagerly, and its reducer matches the
13246 // current reducer, we can use the eagerly computed state.
13247 _newState = _update.eagerState;
13248 } else {
13249 var _action2 = _update.action;
13250 _newState = reducer(_newState, _action2);
13251 }
13252 }
13253 prevUpdate = _update;
13254 _update = _update.next;
13255 } while (_update !== null && _update !== first);
13256
13257 if (!didSkip) {
13258 newBaseUpdate = prevUpdate;
13259 newBaseState = _newState;
13260 }
13261
13262 // Mark that the fiber performed work, but only if the new state is
13263 // different from the current state.
13264 if (!is(_newState, hook.memoizedState)) {
13265 markWorkInProgressReceivedUpdate();
13266 }
13267
13268 hook.memoizedState = _newState;
13269 hook.baseUpdate = newBaseUpdate;
13270 hook.baseState = newBaseState;
13271
13272 queue.lastRenderedState = _newState;
13273 }
13274
13275 var dispatch = queue.dispatch;
13276 return [hook.memoizedState, dispatch];
13277}
13278
13279function mountState(initialState) {
13280 var hook = mountWorkInProgressHook();
13281 if (typeof initialState === 'function') {
13282 initialState = initialState();
13283 }
13284 hook.memoizedState = hook.baseState = initialState;
13285 var queue = hook.queue = {
13286 last: null,
13287 dispatch: null,
13288 lastRenderedReducer: basicStateReducer,
13289 lastRenderedState: initialState
13290 };
13291 var dispatch = queue.dispatch = dispatchAction.bind(null,
13292 // Flow doesn't know this is non-null, but we do.
13293 currentlyRenderingFiber$1, queue);
13294 return [hook.memoizedState, dispatch];
13295}
13296
13297function updateState(initialState) {
13298 return updateReducer(basicStateReducer, initialState);
13299}
13300
13301function pushEffect(tag, create, destroy, deps) {
13302 var effect = {
13303 tag: tag,
13304 create: create,
13305 destroy: destroy,
13306 deps: deps,
13307 // Circular
13308 next: null
13309 };
13310 if (componentUpdateQueue === null) {
13311 componentUpdateQueue = createFunctionComponentUpdateQueue();
13312 componentUpdateQueue.lastEffect = effect.next = effect;
13313 } else {
13314 var _lastEffect = componentUpdateQueue.lastEffect;
13315 if (_lastEffect === null) {
13316 componentUpdateQueue.lastEffect = effect.next = effect;
13317 } else {
13318 var firstEffect = _lastEffect.next;
13319 _lastEffect.next = effect;
13320 effect.next = firstEffect;
13321 componentUpdateQueue.lastEffect = effect;
13322 }
13323 }
13324 return effect;
13325}
13326
13327function mountRef(initialValue) {
13328 var hook = mountWorkInProgressHook();
13329 var ref = { current: initialValue };
13330 {
13331 Object.seal(ref);
13332 }
13333 hook.memoizedState = ref;
13334 return ref;
13335}
13336
13337function updateRef(initialValue) {
13338 var hook = updateWorkInProgressHook();
13339 return hook.memoizedState;
13340}
13341
13342function mountEffectImpl(fiberEffectTag, hookEffectTag, create, deps) {
13343 var hook = mountWorkInProgressHook();
13344 var nextDeps = deps === undefined ? null : deps;
13345 sideEffectTag |= fiberEffectTag;
13346 hook.memoizedState = pushEffect(hookEffectTag, create, undefined, nextDeps);
13347}
13348
13349function updateEffectImpl(fiberEffectTag, hookEffectTag, create, deps) {
13350 var hook = updateWorkInProgressHook();
13351 var nextDeps = deps === undefined ? null : deps;
13352 var destroy = undefined;
13353
13354 if (currentHook !== null) {
13355 var prevEffect = currentHook.memoizedState;
13356 destroy = prevEffect.destroy;
13357 if (nextDeps !== null) {
13358 var prevDeps = prevEffect.deps;
13359 if (areHookInputsEqual(nextDeps, prevDeps)) {
13360 pushEffect(NoEffect$1, create, destroy, nextDeps);
13361 return;
13362 }
13363 }
13364 }
13365
13366 sideEffectTag |= fiberEffectTag;
13367 hook.memoizedState = pushEffect(hookEffectTag, create, destroy, nextDeps);
13368}
13369
13370function mountEffect(create, deps) {
13371 return mountEffectImpl(Update | Passive, UnmountPassive | MountPassive, create, deps);
13372}
13373
13374function updateEffect(create, deps) {
13375 return updateEffectImpl(Update | Passive, UnmountPassive | MountPassive, create, deps);
13376}
13377
13378function mountLayoutEffect(create, deps) {
13379 return mountEffectImpl(Update, UnmountMutation | MountLayout, create, deps);
13380}
13381
13382function updateLayoutEffect(create, deps) {
13383 return updateEffectImpl(Update, UnmountMutation | MountLayout, create, deps);
13384}
13385
13386function imperativeHandleEffect(create, ref) {
13387 if (typeof ref === 'function') {
13388 var refCallback = ref;
13389 var _inst = create();
13390 refCallback(_inst);
13391 return function () {
13392 refCallback(null);
13393 };
13394 } else if (ref !== null && ref !== undefined) {
13395 var refObject = ref;
13396 {
13397 !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;
13398 }
13399 var _inst2 = create();
13400 refObject.current = _inst2;
13401 return function () {
13402 refObject.current = null;
13403 };
13404 }
13405}
13406
13407function mountImperativeHandle(ref, create, deps) {
13408 {
13409 !(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;
13410 }
13411
13412 // TODO: If deps are provided, should we skip comparing the ref itself?
13413 var effectDeps = deps !== null && deps !== undefined ? deps.concat([ref]) : null;
13414
13415 return mountEffectImpl(Update, UnmountMutation | MountLayout, imperativeHandleEffect.bind(null, create, ref), effectDeps);
13416}
13417
13418function updateImperativeHandle(ref, create, deps) {
13419 {
13420 !(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;
13421 }
13422
13423 // TODO: If deps are provided, should we skip comparing the ref itself?
13424 var effectDeps = deps !== null && deps !== undefined ? deps.concat([ref]) : null;
13425
13426 return updateEffectImpl(Update, UnmountMutation | MountLayout, imperativeHandleEffect.bind(null, create, ref), effectDeps);
13427}
13428
13429function mountDebugValue(value, formatterFn) {
13430 // This hook is normally a no-op.
13431 // The react-debug-hooks package injects its own implementation
13432 // so that e.g. DevTools can display custom hook values.
13433}
13434
13435var updateDebugValue = mountDebugValue;
13436
13437function mountCallback(callback, deps) {
13438 var hook = mountWorkInProgressHook();
13439 var nextDeps = deps === undefined ? null : deps;
13440 hook.memoizedState = [callback, nextDeps];
13441 return callback;
13442}
13443
13444function updateCallback(callback, deps) {
13445 var hook = updateWorkInProgressHook();
13446 var nextDeps = deps === undefined ? null : deps;
13447 var prevState = hook.memoizedState;
13448 if (prevState !== null) {
13449 if (nextDeps !== null) {
13450 var prevDeps = prevState[1];
13451 if (areHookInputsEqual(nextDeps, prevDeps)) {
13452 return prevState[0];
13453 }
13454 }
13455 }
13456 hook.memoizedState = [callback, nextDeps];
13457 return callback;
13458}
13459
13460function mountMemo(nextCreate, deps) {
13461 var hook = mountWorkInProgressHook();
13462 var nextDeps = deps === undefined ? null : deps;
13463 var nextValue = nextCreate();
13464 hook.memoizedState = [nextValue, nextDeps];
13465 return nextValue;
13466}
13467
13468function updateMemo(nextCreate, deps) {
13469 var hook = updateWorkInProgressHook();
13470 var nextDeps = deps === undefined ? null : deps;
13471 var prevState = hook.memoizedState;
13472 if (prevState !== null) {
13473 // Assume these are defined. If they're not, areHookInputsEqual will warn.
13474 if (nextDeps !== null) {
13475 var prevDeps = prevState[1];
13476 if (areHookInputsEqual(nextDeps, prevDeps)) {
13477 return prevState[0];
13478 }
13479 }
13480 }
13481 var nextValue = nextCreate();
13482 hook.memoizedState = [nextValue, nextDeps];
13483 return nextValue;
13484}
13485
13486// in a test-like environment, we want to warn if dispatchAction()
13487// is called outside of a batchedUpdates/TestUtils.act(...) call.
13488var shouldWarnForUnbatchedSetState = false;
13489
13490{
13491 // jest isn't a 'global', it's just exposed to tests via a wrapped function
13492 // further, this isn't a test file, so flow doesn't recognize the symbol. So...
13493 // $FlowExpectedError - because requirements don't give a damn about your type sigs.
13494 if ('undefined' !== typeof jest) {
13495 shouldWarnForUnbatchedSetState = true;
13496 }
13497}
13498
13499function dispatchAction(fiber, queue, action) {
13500 !(numberOfReRenders < RE_RENDER_LIMIT) ? invariant(false, 'Too many re-renders. React limits the number of renders to prevent an infinite loop.') : void 0;
13501
13502 {
13503 !(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;
13504 }
13505
13506 var alternate = fiber.alternate;
13507 if (fiber === currentlyRenderingFiber$1 || alternate !== null && alternate === currentlyRenderingFiber$1) {
13508 // This is a render phase update. Stash it in a lazily-created map of
13509 // queue -> linked list of updates. After this render pass, we'll restart
13510 // and apply the stashed updates on top of the work-in-progress hook.
13511 didScheduleRenderPhaseUpdate = true;
13512 var update = {
13513 expirationTime: renderExpirationTime,
13514 action: action,
13515 eagerReducer: null,
13516 eagerState: null,
13517 next: null
13518 };
13519 if (renderPhaseUpdates === null) {
13520 renderPhaseUpdates = new Map();
13521 }
13522 var firstRenderPhaseUpdate = renderPhaseUpdates.get(queue);
13523 if (firstRenderPhaseUpdate === undefined) {
13524 renderPhaseUpdates.set(queue, update);
13525 } else {
13526 // Append the update to the end of the list.
13527 var lastRenderPhaseUpdate = firstRenderPhaseUpdate;
13528 while (lastRenderPhaseUpdate.next !== null) {
13529 lastRenderPhaseUpdate = lastRenderPhaseUpdate.next;
13530 }
13531 lastRenderPhaseUpdate.next = update;
13532 }
13533 } else {
13534 flushPassiveEffects();
13535
13536 var currentTime = requestCurrentTime();
13537 var _expirationTime = computeExpirationForFiber(currentTime, fiber);
13538
13539 var _update2 = {
13540 expirationTime: _expirationTime,
13541 action: action,
13542 eagerReducer: null,
13543 eagerState: null,
13544 next: null
13545 };
13546
13547 // Append the update to the end of the list.
13548 var _last = queue.last;
13549 if (_last === null) {
13550 // This is the first update. Create a circular list.
13551 _update2.next = _update2;
13552 } else {
13553 var first = _last.next;
13554 if (first !== null) {
13555 // Still circular.
13556 _update2.next = first;
13557 }
13558 _last.next = _update2;
13559 }
13560 queue.last = _update2;
13561
13562 if (fiber.expirationTime === NoWork && (alternate === null || alternate.expirationTime === NoWork)) {
13563 // The queue is currently empty, which means we can eagerly compute the
13564 // next state before entering the render phase. If the new state is the
13565 // same as the current state, we may be able to bail out entirely.
13566 var _lastRenderedReducer = queue.lastRenderedReducer;
13567 if (_lastRenderedReducer !== null) {
13568 var prevDispatcher = void 0;
13569 {
13570 prevDispatcher = ReactCurrentDispatcher$1.current;
13571 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
13572 }
13573 try {
13574 var currentState = queue.lastRenderedState;
13575 var _eagerState = _lastRenderedReducer(currentState, action);
13576 // Stash the eagerly computed state, and the reducer used to compute
13577 // it, on the update object. If the reducer hasn't changed by the
13578 // time we enter the render phase, then the eager state can be used
13579 // without calling the reducer again.
13580 _update2.eagerReducer = _lastRenderedReducer;
13581 _update2.eagerState = _eagerState;
13582 if (is(_eagerState, currentState)) {
13583 // Fast path. We can bail out without scheduling React to re-render.
13584 // It's still possible that we'll need to rebase this update later,
13585 // if the component re-renders for a different reason and by that
13586 // time the reducer has changed.
13587 return;
13588 }
13589 } catch (error) {
13590 // Suppress the error. It will throw again in the render phase.
13591 } finally {
13592 {
13593 ReactCurrentDispatcher$1.current = prevDispatcher;
13594 }
13595 }
13596 }
13597 }
13598 {
13599 if (shouldWarnForUnbatchedSetState === true) {
13600 warnIfNotCurrentlyBatchingInDev(fiber);
13601 }
13602 }
13603 scheduleWork(fiber, _expirationTime);
13604 }
13605}
13606
13607var ContextOnlyDispatcher = {
13608 readContext: readContext,
13609
13610 useCallback: throwInvalidHookError,
13611 useContext: throwInvalidHookError,
13612 useEffect: throwInvalidHookError,
13613 useImperativeHandle: throwInvalidHookError,
13614 useLayoutEffect: throwInvalidHookError,
13615 useMemo: throwInvalidHookError,
13616 useReducer: throwInvalidHookError,
13617 useRef: throwInvalidHookError,
13618 useState: throwInvalidHookError,
13619 useDebugValue: throwInvalidHookError
13620};
13621
13622var HooksDispatcherOnMountInDEV = null;
13623var HooksDispatcherOnMountWithHookTypesInDEV = null;
13624var HooksDispatcherOnUpdateInDEV = null;
13625var InvalidNestedHooksDispatcherOnMountInDEV = null;
13626var InvalidNestedHooksDispatcherOnUpdateInDEV = null;
13627
13628{
13629 var warnInvalidContextAccess = function () {
13630 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().');
13631 };
13632
13633 var warnInvalidHookAccess = function () {
13634 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');
13635 };
13636
13637 HooksDispatcherOnMountInDEV = {
13638 readContext: function (context, observedBits) {
13639 return readContext(context, observedBits);
13640 },
13641 useCallback: function (callback, deps) {
13642 currentHookNameInDev = 'useCallback';
13643 mountHookTypesDev();
13644 return mountCallback(callback, deps);
13645 },
13646 useContext: function (context, observedBits) {
13647 currentHookNameInDev = 'useContext';
13648 mountHookTypesDev();
13649 return readContext(context, observedBits);
13650 },
13651 useEffect: function (create, deps) {
13652 currentHookNameInDev = 'useEffect';
13653 mountHookTypesDev();
13654 return mountEffect(create, deps);
13655 },
13656 useImperativeHandle: function (ref, create, deps) {
13657 currentHookNameInDev = 'useImperativeHandle';
13658 mountHookTypesDev();
13659 return mountImperativeHandle(ref, create, deps);
13660 },
13661 useLayoutEffect: function (create, deps) {
13662 currentHookNameInDev = 'useLayoutEffect';
13663 mountHookTypesDev();
13664 return mountLayoutEffect(create, deps);
13665 },
13666 useMemo: function (create, deps) {
13667 currentHookNameInDev = 'useMemo';
13668 mountHookTypesDev();
13669 var prevDispatcher = ReactCurrentDispatcher$1.current;
13670 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
13671 try {
13672 return mountMemo(create, deps);
13673 } finally {
13674 ReactCurrentDispatcher$1.current = prevDispatcher;
13675 }
13676 },
13677 useReducer: function (reducer, initialArg, init) {
13678 currentHookNameInDev = 'useReducer';
13679 mountHookTypesDev();
13680 var prevDispatcher = ReactCurrentDispatcher$1.current;
13681 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
13682 try {
13683 return mountReducer(reducer, initialArg, init);
13684 } finally {
13685 ReactCurrentDispatcher$1.current = prevDispatcher;
13686 }
13687 },
13688 useRef: function (initialValue) {
13689 currentHookNameInDev = 'useRef';
13690 mountHookTypesDev();
13691 return mountRef(initialValue);
13692 },
13693 useState: function (initialState) {
13694 currentHookNameInDev = 'useState';
13695 mountHookTypesDev();
13696 var prevDispatcher = ReactCurrentDispatcher$1.current;
13697 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
13698 try {
13699 return mountState(initialState);
13700 } finally {
13701 ReactCurrentDispatcher$1.current = prevDispatcher;
13702 }
13703 },
13704 useDebugValue: function (value, formatterFn) {
13705 currentHookNameInDev = 'useDebugValue';
13706 mountHookTypesDev();
13707 return mountDebugValue(value, formatterFn);
13708 }
13709 };
13710
13711 HooksDispatcherOnMountWithHookTypesInDEV = {
13712 readContext: function (context, observedBits) {
13713 return readContext(context, observedBits);
13714 },
13715 useCallback: function (callback, deps) {
13716 currentHookNameInDev = 'useCallback';
13717 updateHookTypesDev();
13718 return mountCallback(callback, deps);
13719 },
13720 useContext: function (context, observedBits) {
13721 currentHookNameInDev = 'useContext';
13722 updateHookTypesDev();
13723 return readContext(context, observedBits);
13724 },
13725 useEffect: function (create, deps) {
13726 currentHookNameInDev = 'useEffect';
13727 updateHookTypesDev();
13728 return mountEffect(create, deps);
13729 },
13730 useImperativeHandle: function (ref, create, deps) {
13731 currentHookNameInDev = 'useImperativeHandle';
13732 updateHookTypesDev();
13733 return mountImperativeHandle(ref, create, deps);
13734 },
13735 useLayoutEffect: function (create, deps) {
13736 currentHookNameInDev = 'useLayoutEffect';
13737 updateHookTypesDev();
13738 return mountLayoutEffect(create, deps);
13739 },
13740 useMemo: function (create, deps) {
13741 currentHookNameInDev = 'useMemo';
13742 updateHookTypesDev();
13743 var prevDispatcher = ReactCurrentDispatcher$1.current;
13744 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
13745 try {
13746 return mountMemo(create, deps);
13747 } finally {
13748 ReactCurrentDispatcher$1.current = prevDispatcher;
13749 }
13750 },
13751 useReducer: function (reducer, initialArg, init) {
13752 currentHookNameInDev = 'useReducer';
13753 updateHookTypesDev();
13754 var prevDispatcher = ReactCurrentDispatcher$1.current;
13755 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
13756 try {
13757 return mountReducer(reducer, initialArg, init);
13758 } finally {
13759 ReactCurrentDispatcher$1.current = prevDispatcher;
13760 }
13761 },
13762 useRef: function (initialValue) {
13763 currentHookNameInDev = 'useRef';
13764 updateHookTypesDev();
13765 return mountRef(initialValue);
13766 },
13767 useState: function (initialState) {
13768 currentHookNameInDev = 'useState';
13769 updateHookTypesDev();
13770 var prevDispatcher = ReactCurrentDispatcher$1.current;
13771 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
13772 try {
13773 return mountState(initialState);
13774 } finally {
13775 ReactCurrentDispatcher$1.current = prevDispatcher;
13776 }
13777 },
13778 useDebugValue: function (value, formatterFn) {
13779 currentHookNameInDev = 'useDebugValue';
13780 updateHookTypesDev();
13781 return mountDebugValue(value, formatterFn);
13782 }
13783 };
13784
13785 HooksDispatcherOnUpdateInDEV = {
13786 readContext: function (context, observedBits) {
13787 return readContext(context, observedBits);
13788 },
13789 useCallback: function (callback, deps) {
13790 currentHookNameInDev = 'useCallback';
13791 updateHookTypesDev();
13792 return updateCallback(callback, deps);
13793 },
13794 useContext: function (context, observedBits) {
13795 currentHookNameInDev = 'useContext';
13796 updateHookTypesDev();
13797 return readContext(context, observedBits);
13798 },
13799 useEffect: function (create, deps) {
13800 currentHookNameInDev = 'useEffect';
13801 updateHookTypesDev();
13802 return updateEffect(create, deps);
13803 },
13804 useImperativeHandle: function (ref, create, deps) {
13805 currentHookNameInDev = 'useImperativeHandle';
13806 updateHookTypesDev();
13807 return updateImperativeHandle(ref, create, deps);
13808 },
13809 useLayoutEffect: function (create, deps) {
13810 currentHookNameInDev = 'useLayoutEffect';
13811 updateHookTypesDev();
13812 return updateLayoutEffect(create, deps);
13813 },
13814 useMemo: function (create, deps) {
13815 currentHookNameInDev = 'useMemo';
13816 updateHookTypesDev();
13817 var prevDispatcher = ReactCurrentDispatcher$1.current;
13818 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
13819 try {
13820 return updateMemo(create, deps);
13821 } finally {
13822 ReactCurrentDispatcher$1.current = prevDispatcher;
13823 }
13824 },
13825 useReducer: function (reducer, initialArg, init) {
13826 currentHookNameInDev = 'useReducer';
13827 updateHookTypesDev();
13828 var prevDispatcher = ReactCurrentDispatcher$1.current;
13829 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
13830 try {
13831 return updateReducer(reducer, initialArg, init);
13832 } finally {
13833 ReactCurrentDispatcher$1.current = prevDispatcher;
13834 }
13835 },
13836 useRef: function (initialValue) {
13837 currentHookNameInDev = 'useRef';
13838 updateHookTypesDev();
13839 return updateRef(initialValue);
13840 },
13841 useState: function (initialState) {
13842 currentHookNameInDev = 'useState';
13843 updateHookTypesDev();
13844 var prevDispatcher = ReactCurrentDispatcher$1.current;
13845 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
13846 try {
13847 return updateState(initialState);
13848 } finally {
13849 ReactCurrentDispatcher$1.current = prevDispatcher;
13850 }
13851 },
13852 useDebugValue: function (value, formatterFn) {
13853 currentHookNameInDev = 'useDebugValue';
13854 updateHookTypesDev();
13855 return updateDebugValue(value, formatterFn);
13856 }
13857 };
13858
13859 InvalidNestedHooksDispatcherOnMountInDEV = {
13860 readContext: function (context, observedBits) {
13861 warnInvalidContextAccess();
13862 return readContext(context, observedBits);
13863 },
13864 useCallback: function (callback, deps) {
13865 currentHookNameInDev = 'useCallback';
13866 warnInvalidHookAccess();
13867 mountHookTypesDev();
13868 return mountCallback(callback, deps);
13869 },
13870 useContext: function (context, observedBits) {
13871 currentHookNameInDev = 'useContext';
13872 warnInvalidHookAccess();
13873 mountHookTypesDev();
13874 return readContext(context, observedBits);
13875 },
13876 useEffect: function (create, deps) {
13877 currentHookNameInDev = 'useEffect';
13878 warnInvalidHookAccess();
13879 mountHookTypesDev();
13880 return mountEffect(create, deps);
13881 },
13882 useImperativeHandle: function (ref, create, deps) {
13883 currentHookNameInDev = 'useImperativeHandle';
13884 warnInvalidHookAccess();
13885 mountHookTypesDev();
13886 return mountImperativeHandle(ref, create, deps);
13887 },
13888 useLayoutEffect: function (create, deps) {
13889 currentHookNameInDev = 'useLayoutEffect';
13890 warnInvalidHookAccess();
13891 mountHookTypesDev();
13892 return mountLayoutEffect(create, deps);
13893 },
13894 useMemo: function (create, deps) {
13895 currentHookNameInDev = 'useMemo';
13896 warnInvalidHookAccess();
13897 mountHookTypesDev();
13898 var prevDispatcher = ReactCurrentDispatcher$1.current;
13899 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
13900 try {
13901 return mountMemo(create, deps);
13902 } finally {
13903 ReactCurrentDispatcher$1.current = prevDispatcher;
13904 }
13905 },
13906 useReducer: function (reducer, initialArg, init) {
13907 currentHookNameInDev = 'useReducer';
13908 warnInvalidHookAccess();
13909 mountHookTypesDev();
13910 var prevDispatcher = ReactCurrentDispatcher$1.current;
13911 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
13912 try {
13913 return mountReducer(reducer, initialArg, init);
13914 } finally {
13915 ReactCurrentDispatcher$1.current = prevDispatcher;
13916 }
13917 },
13918 useRef: function (initialValue) {
13919 currentHookNameInDev = 'useRef';
13920 warnInvalidHookAccess();
13921 mountHookTypesDev();
13922 return mountRef(initialValue);
13923 },
13924 useState: function (initialState) {
13925 currentHookNameInDev = 'useState';
13926 warnInvalidHookAccess();
13927 mountHookTypesDev();
13928 var prevDispatcher = ReactCurrentDispatcher$1.current;
13929 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
13930 try {
13931 return mountState(initialState);
13932 } finally {
13933 ReactCurrentDispatcher$1.current = prevDispatcher;
13934 }
13935 },
13936 useDebugValue: function (value, formatterFn) {
13937 currentHookNameInDev = 'useDebugValue';
13938 warnInvalidHookAccess();
13939 mountHookTypesDev();
13940 return mountDebugValue(value, formatterFn);
13941 }
13942 };
13943
13944 InvalidNestedHooksDispatcherOnUpdateInDEV = {
13945 readContext: function (context, observedBits) {
13946 warnInvalidContextAccess();
13947 return readContext(context, observedBits);
13948 },
13949 useCallback: function (callback, deps) {
13950 currentHookNameInDev = 'useCallback';
13951 warnInvalidHookAccess();
13952 updateHookTypesDev();
13953 return updateCallback(callback, deps);
13954 },
13955 useContext: function (context, observedBits) {
13956 currentHookNameInDev = 'useContext';
13957 warnInvalidHookAccess();
13958 updateHookTypesDev();
13959 return readContext(context, observedBits);
13960 },
13961 useEffect: function (create, deps) {
13962 currentHookNameInDev = 'useEffect';
13963 warnInvalidHookAccess();
13964 updateHookTypesDev();
13965 return updateEffect(create, deps);
13966 },
13967 useImperativeHandle: function (ref, create, deps) {
13968 currentHookNameInDev = 'useImperativeHandle';
13969 warnInvalidHookAccess();
13970 updateHookTypesDev();
13971 return updateImperativeHandle(ref, create, deps);
13972 },
13973 useLayoutEffect: function (create, deps) {
13974 currentHookNameInDev = 'useLayoutEffect';
13975 warnInvalidHookAccess();
13976 updateHookTypesDev();
13977 return updateLayoutEffect(create, deps);
13978 },
13979 useMemo: function (create, deps) {
13980 currentHookNameInDev = 'useMemo';
13981 warnInvalidHookAccess();
13982 updateHookTypesDev();
13983 var prevDispatcher = ReactCurrentDispatcher$1.current;
13984 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
13985 try {
13986 return updateMemo(create, deps);
13987 } finally {
13988 ReactCurrentDispatcher$1.current = prevDispatcher;
13989 }
13990 },
13991 useReducer: function (reducer, initialArg, init) {
13992 currentHookNameInDev = 'useReducer';
13993 warnInvalidHookAccess();
13994 updateHookTypesDev();
13995 var prevDispatcher = ReactCurrentDispatcher$1.current;
13996 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
13997 try {
13998 return updateReducer(reducer, initialArg, init);
13999 } finally {
14000 ReactCurrentDispatcher$1.current = prevDispatcher;
14001 }
14002 },
14003 useRef: function (initialValue) {
14004 currentHookNameInDev = 'useRef';
14005 warnInvalidHookAccess();
14006 updateHookTypesDev();
14007 return updateRef(initialValue);
14008 },
14009 useState: function (initialState) {
14010 currentHookNameInDev = 'useState';
14011 warnInvalidHookAccess();
14012 updateHookTypesDev();
14013 var prevDispatcher = ReactCurrentDispatcher$1.current;
14014 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
14015 try {
14016 return updateState(initialState);
14017 } finally {
14018 ReactCurrentDispatcher$1.current = prevDispatcher;
14019 }
14020 },
14021 useDebugValue: function (value, formatterFn) {
14022 currentHookNameInDev = 'useDebugValue';
14023 warnInvalidHookAccess();
14024 updateHookTypesDev();
14025 return updateDebugValue(value, formatterFn);
14026 }
14027 };
14028}
14029
14030var commitTime = 0;
14031var profilerStartTime = -1;
14032
14033function getCommitTime() {
14034 return commitTime;
14035}
14036
14037function recordCommitTime() {
14038 if (!enableProfilerTimer) {
14039 return;
14040 }
14041 commitTime = scheduler.unstable_now();
14042}
14043
14044function startProfilerTimer(fiber) {
14045 if (!enableProfilerTimer) {
14046 return;
14047 }
14048
14049 profilerStartTime = scheduler.unstable_now();
14050
14051 if (fiber.actualStartTime < 0) {
14052 fiber.actualStartTime = scheduler.unstable_now();
14053 }
14054}
14055
14056function stopProfilerTimerIfRunning(fiber) {
14057 if (!enableProfilerTimer) {
14058 return;
14059 }
14060 profilerStartTime = -1;
14061}
14062
14063function stopProfilerTimerIfRunningAndRecordDelta(fiber, overrideBaseTime) {
14064 if (!enableProfilerTimer) {
14065 return;
14066 }
14067
14068 if (profilerStartTime >= 0) {
14069 var elapsedTime = scheduler.unstable_now() - profilerStartTime;
14070 fiber.actualDuration += elapsedTime;
14071 if (overrideBaseTime) {
14072 fiber.selfBaseDuration = elapsedTime;
14073 }
14074 profilerStartTime = -1;
14075 }
14076}
14077
14078// The deepest Fiber on the stack involved in a hydration context.
14079// This may have been an insertion or a hydration.
14080var hydrationParentFiber = null;
14081var nextHydratableInstance = null;
14082var isHydrating = false;
14083
14084function enterHydrationState(fiber) {
14085 if (!supportsHydration) {
14086 return false;
14087 }
14088
14089 var parentInstance = fiber.stateNode.containerInfo;
14090 nextHydratableInstance = getFirstHydratableChild(parentInstance);
14091 hydrationParentFiber = fiber;
14092 isHydrating = true;
14093 return true;
14094}
14095
14096function reenterHydrationStateFromDehydratedSuspenseInstance(fiber) {
14097 if (!supportsHydration) {
14098 return false;
14099 }
14100
14101 var suspenseInstance = fiber.stateNode;
14102 nextHydratableInstance = getNextHydratableSibling(suspenseInstance);
14103 popToNextHostParent(fiber);
14104 isHydrating = true;
14105 return true;
14106}
14107
14108function deleteHydratableInstance(returnFiber, instance) {
14109 {
14110 switch (returnFiber.tag) {
14111 case HostRoot:
14112 didNotHydrateContainerInstance(returnFiber.stateNode.containerInfo, instance);
14113 break;
14114 case HostComponent:
14115 didNotHydrateInstance(returnFiber.type, returnFiber.memoizedProps, returnFiber.stateNode, instance);
14116 break;
14117 }
14118 }
14119
14120 var childToDelete = createFiberFromHostInstanceForDeletion();
14121 childToDelete.stateNode = instance;
14122 childToDelete.return = returnFiber;
14123 childToDelete.effectTag = Deletion;
14124
14125 // This might seem like it belongs on progressedFirstDeletion. However,
14126 // these children are not part of the reconciliation list of children.
14127 // Even if we abort and rereconcile the children, that will try to hydrate
14128 // again and the nodes are still in the host tree so these will be
14129 // recreated.
14130 if (returnFiber.lastEffect !== null) {
14131 returnFiber.lastEffect.nextEffect = childToDelete;
14132 returnFiber.lastEffect = childToDelete;
14133 } else {
14134 returnFiber.firstEffect = returnFiber.lastEffect = childToDelete;
14135 }
14136}
14137
14138function insertNonHydratedInstance(returnFiber, fiber) {
14139 fiber.effectTag |= Placement;
14140 {
14141 switch (returnFiber.tag) {
14142 case HostRoot:
14143 {
14144 var parentContainer = returnFiber.stateNode.containerInfo;
14145 switch (fiber.tag) {
14146 case HostComponent:
14147 var type = fiber.type;
14148 var props = fiber.pendingProps;
14149 didNotFindHydratableContainerInstance(parentContainer, type, props);
14150 break;
14151 case HostText:
14152 var text = fiber.pendingProps;
14153 didNotFindHydratableContainerTextInstance(parentContainer, text);
14154 break;
14155 case SuspenseComponent:
14156
14157 break;
14158 }
14159 break;
14160 }
14161 case HostComponent:
14162 {
14163 var parentType = returnFiber.type;
14164 var parentProps = returnFiber.memoizedProps;
14165 var parentInstance = returnFiber.stateNode;
14166 switch (fiber.tag) {
14167 case HostComponent:
14168 var _type = fiber.type;
14169 var _props = fiber.pendingProps;
14170 didNotFindHydratableInstance(parentType, parentProps, parentInstance, _type, _props);
14171 break;
14172 case HostText:
14173 var _text = fiber.pendingProps;
14174 didNotFindHydratableTextInstance(parentType, parentProps, parentInstance, _text);
14175 break;
14176 case SuspenseComponent:
14177 didNotFindHydratableSuspenseInstance(parentType, parentProps, parentInstance);
14178 break;
14179 }
14180 break;
14181 }
14182 default:
14183 return;
14184 }
14185 }
14186}
14187
14188function tryHydrate(fiber, nextInstance) {
14189 switch (fiber.tag) {
14190 case HostComponent:
14191 {
14192 var type = fiber.type;
14193 var props = fiber.pendingProps;
14194 var instance = canHydrateInstance(nextInstance, type, props);
14195 if (instance !== null) {
14196 fiber.stateNode = instance;
14197 return true;
14198 }
14199 return false;
14200 }
14201 case HostText:
14202 {
14203 var text = fiber.pendingProps;
14204 var textInstance = canHydrateTextInstance(nextInstance, text);
14205 if (textInstance !== null) {
14206 fiber.stateNode = textInstance;
14207 return true;
14208 }
14209 return false;
14210 }
14211 case SuspenseComponent:
14212 {
14213 if (enableSuspenseServerRenderer) {
14214 var suspenseInstance = canHydrateSuspenseInstance(nextInstance);
14215 if (suspenseInstance !== null) {
14216 // Downgrade the tag to a dehydrated component until we've hydrated it.
14217 fiber.tag = DehydratedSuspenseComponent;
14218 fiber.stateNode = suspenseInstance;
14219 return true;
14220 }
14221 }
14222 return false;
14223 }
14224 default:
14225 return false;
14226 }
14227}
14228
14229function tryToClaimNextHydratableInstance(fiber) {
14230 if (!isHydrating) {
14231 return;
14232 }
14233 var nextInstance = nextHydratableInstance;
14234 if (!nextInstance) {
14235 // Nothing to hydrate. Make it an insertion.
14236 insertNonHydratedInstance(hydrationParentFiber, fiber);
14237 isHydrating = false;
14238 hydrationParentFiber = fiber;
14239 return;
14240 }
14241 var firstAttemptedInstance = nextInstance;
14242 if (!tryHydrate(fiber, nextInstance)) {
14243 // If we can't hydrate this instance let's try the next one.
14244 // We use this as a heuristic. It's based on intuition and not data so it
14245 // might be flawed or unnecessary.
14246 nextInstance = getNextHydratableSibling(firstAttemptedInstance);
14247 if (!nextInstance || !tryHydrate(fiber, nextInstance)) {
14248 // Nothing to hydrate. Make it an insertion.
14249 insertNonHydratedInstance(hydrationParentFiber, fiber);
14250 isHydrating = false;
14251 hydrationParentFiber = fiber;
14252 return;
14253 }
14254 // We matched the next one, we'll now assume that the first one was
14255 // superfluous and we'll delete it. Since we can't eagerly delete it
14256 // we'll have to schedule a deletion. To do that, this node needs a dummy
14257 // fiber associated with it.
14258 deleteHydratableInstance(hydrationParentFiber, firstAttemptedInstance);
14259 }
14260 hydrationParentFiber = fiber;
14261 nextHydratableInstance = getFirstHydratableChild(nextInstance);
14262}
14263
14264function prepareToHydrateHostInstance(fiber, rootContainerInstance, hostContext) {
14265 if (!supportsHydration) {
14266 invariant(false, 'Expected prepareToHydrateHostInstance() to never be called. This error is likely caused by a bug in React. Please file an issue.');
14267 }
14268
14269 var instance = fiber.stateNode;
14270 var updatePayload = hydrateInstance(instance, fiber.type, fiber.memoizedProps, rootContainerInstance, hostContext, fiber);
14271 // TODO: Type this specific to this type of component.
14272 fiber.updateQueue = updatePayload;
14273 // If the update payload indicates that there is a change or if there
14274 // is a new ref we mark this as an update.
14275 if (updatePayload !== null) {
14276 return true;
14277 }
14278 return false;
14279}
14280
14281function prepareToHydrateHostTextInstance(fiber) {
14282 if (!supportsHydration) {
14283 invariant(false, 'Expected prepareToHydrateHostTextInstance() to never be called. This error is likely caused by a bug in React. Please file an issue.');
14284 }
14285
14286 var textInstance = fiber.stateNode;
14287 var textContent = fiber.memoizedProps;
14288 var shouldUpdate = hydrateTextInstance(textInstance, textContent, fiber);
14289 {
14290 if (shouldUpdate) {
14291 // We assume that prepareToHydrateHostTextInstance is called in a context where the
14292 // hydration parent is the parent host component of this host text.
14293 var returnFiber = hydrationParentFiber;
14294 if (returnFiber !== null) {
14295 switch (returnFiber.tag) {
14296 case HostRoot:
14297 {
14298 var parentContainer = returnFiber.stateNode.containerInfo;
14299 didNotMatchHydratedContainerTextInstance(parentContainer, textInstance, textContent);
14300 break;
14301 }
14302 case HostComponent:
14303 {
14304 var parentType = returnFiber.type;
14305 var parentProps = returnFiber.memoizedProps;
14306 var parentInstance = returnFiber.stateNode;
14307 didNotMatchHydratedTextInstance(parentType, parentProps, parentInstance, textInstance, textContent);
14308 break;
14309 }
14310 }
14311 }
14312 }
14313 }
14314 return shouldUpdate;
14315}
14316
14317function skipPastDehydratedSuspenseInstance(fiber) {
14318 if (!supportsHydration) {
14319 invariant(false, 'Expected skipPastDehydratedSuspenseInstance() to never be called. This error is likely caused by a bug in React. Please file an issue.');
14320 }
14321 var suspenseInstance = fiber.stateNode;
14322 !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;
14323 nextHydratableInstance = getNextHydratableInstanceAfterSuspenseInstance(suspenseInstance);
14324}
14325
14326function popToNextHostParent(fiber) {
14327 var parent = fiber.return;
14328 while (parent !== null && parent.tag !== HostComponent && parent.tag !== HostRoot && parent.tag !== DehydratedSuspenseComponent) {
14329 parent = parent.return;
14330 }
14331 hydrationParentFiber = parent;
14332}
14333
14334function popHydrationState(fiber) {
14335 if (!supportsHydration) {
14336 return false;
14337 }
14338 if (fiber !== hydrationParentFiber) {
14339 // We're deeper than the current hydration context, inside an inserted
14340 // tree.
14341 return false;
14342 }
14343 if (!isHydrating) {
14344 // If we're not currently hydrating but we're in a hydration context, then
14345 // we were an insertion and now need to pop up reenter hydration of our
14346 // siblings.
14347 popToNextHostParent(fiber);
14348 isHydrating = true;
14349 return false;
14350 }
14351
14352 var type = fiber.type;
14353
14354 // If we have any remaining hydratable nodes, we need to delete them now.
14355 // We only do this deeper than head and body since they tend to have random
14356 // other nodes in them. We also ignore components with pure text content in
14357 // side of them.
14358 // TODO: Better heuristic.
14359 if (fiber.tag !== HostComponent || type !== 'head' && type !== 'body' && !shouldSetTextContent(type, fiber.memoizedProps)) {
14360 var nextInstance = nextHydratableInstance;
14361 while (nextInstance) {
14362 deleteHydratableInstance(fiber, nextInstance);
14363 nextInstance = getNextHydratableSibling(nextInstance);
14364 }
14365 }
14366
14367 popToNextHostParent(fiber);
14368 nextHydratableInstance = hydrationParentFiber ? getNextHydratableSibling(fiber.stateNode) : null;
14369 return true;
14370}
14371
14372function resetHydrationState() {
14373 if (!supportsHydration) {
14374 return;
14375 }
14376
14377 hydrationParentFiber = null;
14378 nextHydratableInstance = null;
14379 isHydrating = false;
14380}
14381
14382var ReactCurrentOwner$3 = ReactSharedInternals.ReactCurrentOwner;
14383
14384var didReceiveUpdate = false;
14385
14386var didWarnAboutBadClass = void 0;
14387var didWarnAboutContextTypeOnFunctionComponent = void 0;
14388var didWarnAboutGetDerivedStateOnFunctionComponent = void 0;
14389var didWarnAboutFunctionRefs = void 0;
14390var didWarnAboutReassigningProps = void 0;
14391
14392{
14393 didWarnAboutBadClass = {};
14394 didWarnAboutContextTypeOnFunctionComponent = {};
14395 didWarnAboutGetDerivedStateOnFunctionComponent = {};
14396 didWarnAboutFunctionRefs = {};
14397 didWarnAboutReassigningProps = false;
14398}
14399
14400function reconcileChildren(current$$1, workInProgress, nextChildren, renderExpirationTime) {
14401 if (current$$1 === null) {
14402 // If this is a fresh new component that hasn't been rendered yet, we
14403 // won't update its child set by applying minimal side-effects. Instead,
14404 // we will add them all to the child before it gets rendered. That means
14405 // we can optimize this reconciliation pass by not tracking side-effects.
14406 workInProgress.child = mountChildFibers(workInProgress, null, nextChildren, renderExpirationTime);
14407 } else {
14408 // If the current child is the same as the work in progress, it means that
14409 // we haven't yet started any work on these children. Therefore, we use
14410 // the clone algorithm to create a copy of all the current children.
14411
14412 // If we had any progressed work already, that is invalid at this point so
14413 // let's throw it out.
14414 workInProgress.child = reconcileChildFibers(workInProgress, current$$1.child, nextChildren, renderExpirationTime);
14415 }
14416}
14417
14418function forceUnmountCurrentAndReconcile(current$$1, workInProgress, nextChildren, renderExpirationTime) {
14419 // This function is fork of reconcileChildren. It's used in cases where we
14420 // want to reconcile without matching against the existing set. This has the
14421 // effect of all current children being unmounted; even if the type and key
14422 // are the same, the old child is unmounted and a new child is created.
14423 //
14424 // To do this, we're going to go through the reconcile algorithm twice. In
14425 // the first pass, we schedule a deletion for all the current children by
14426 // passing null.
14427 workInProgress.child = reconcileChildFibers(workInProgress, current$$1.child, null, renderExpirationTime);
14428 // In the second pass, we mount the new children. The trick here is that we
14429 // pass null in place of where we usually pass the current child set. This has
14430 // the effect of remounting all children regardless of whether their their
14431 // identity matches.
14432 workInProgress.child = reconcileChildFibers(workInProgress, null, nextChildren, renderExpirationTime);
14433}
14434
14435function updateForwardRef(current$$1, workInProgress, Component, nextProps, renderExpirationTime) {
14436 // TODO: current can be non-null here even if the component
14437 // hasn't yet mounted. This happens after the first render suspends.
14438 // We'll need to figure out if this is fine or can cause issues.
14439
14440 {
14441 if (workInProgress.type !== workInProgress.elementType) {
14442 // Lazy component props can't be validated in createElement
14443 // because they're only guaranteed to be resolved here.
14444 var innerPropTypes = Component.propTypes;
14445 if (innerPropTypes) {
14446 checkPropTypes(innerPropTypes, nextProps, // Resolved props
14447 'prop', getComponentName(Component), getCurrentFiberStackInDev);
14448 }
14449 }
14450 }
14451
14452 var render = Component.render;
14453 var ref = workInProgress.ref;
14454
14455 // The rest is a fork of updateFunctionComponent
14456 var nextChildren = void 0;
14457 prepareToReadContext(workInProgress, renderExpirationTime);
14458 {
14459 ReactCurrentOwner$3.current = workInProgress;
14460 setCurrentPhase('render');
14461 nextChildren = renderWithHooks(current$$1, workInProgress, render, nextProps, ref, renderExpirationTime);
14462 if (debugRenderPhaseSideEffects || debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) {
14463 // Only double-render components with Hooks
14464 if (workInProgress.memoizedState !== null) {
14465 nextChildren = renderWithHooks(current$$1, workInProgress, render, nextProps, ref, renderExpirationTime);
14466 }
14467 }
14468 setCurrentPhase(null);
14469 }
14470
14471 if (current$$1 !== null && !didReceiveUpdate) {
14472 bailoutHooks(current$$1, workInProgress, renderExpirationTime);
14473 return bailoutOnAlreadyFinishedWork(current$$1, workInProgress, renderExpirationTime);
14474 }
14475
14476 // React DevTools reads this flag.
14477 workInProgress.effectTag |= PerformedWork;
14478 reconcileChildren(current$$1, workInProgress, nextChildren, renderExpirationTime);
14479 return workInProgress.child;
14480}
14481
14482function updateMemoComponent(current$$1, workInProgress, Component, nextProps, updateExpirationTime, renderExpirationTime) {
14483 if (current$$1 === null) {
14484 var type = Component.type;
14485 if (isSimpleFunctionComponent(type) && Component.compare === null &&
14486 // SimpleMemoComponent codepath doesn't resolve outer props either.
14487 Component.defaultProps === undefined) {
14488 // If this is a plain function component without default props,
14489 // and with only the default shallow comparison, we upgrade it
14490 // to a SimpleMemoComponent to allow fast path updates.
14491 workInProgress.tag = SimpleMemoComponent;
14492 workInProgress.type = type;
14493 {
14494 validateFunctionComponentInDev(workInProgress, type);
14495 }
14496 return updateSimpleMemoComponent(current$$1, workInProgress, type, nextProps, updateExpirationTime, renderExpirationTime);
14497 }
14498 {
14499 var innerPropTypes = type.propTypes;
14500 if (innerPropTypes) {
14501 // Inner memo component props aren't currently validated in createElement.
14502 // We could move it there, but we'd still need this for lazy code path.
14503 checkPropTypes(innerPropTypes, nextProps, // Resolved props
14504 'prop', getComponentName(type), getCurrentFiberStackInDev);
14505 }
14506 }
14507 var child = createFiberFromTypeAndProps(Component.type, null, nextProps, null, workInProgress.mode, renderExpirationTime);
14508 child.ref = workInProgress.ref;
14509 child.return = workInProgress;
14510 workInProgress.child = child;
14511 return child;
14512 }
14513 {
14514 var _type = Component.type;
14515 var _innerPropTypes = _type.propTypes;
14516 if (_innerPropTypes) {
14517 // Inner memo component props aren't currently validated in createElement.
14518 // We could move it there, but we'd still need this for lazy code path.
14519 checkPropTypes(_innerPropTypes, nextProps, // Resolved props
14520 'prop', getComponentName(_type), getCurrentFiberStackInDev);
14521 }
14522 }
14523 var currentChild = current$$1.child; // This is always exactly one child
14524 if (updateExpirationTime < renderExpirationTime) {
14525 // This will be the props with resolved defaultProps,
14526 // unlike current.memoizedProps which will be the unresolved ones.
14527 var prevProps = currentChild.memoizedProps;
14528 // Default to shallow comparison
14529 var compare = Component.compare;
14530 compare = compare !== null ? compare : shallowEqual;
14531 if (compare(prevProps, nextProps) && current$$1.ref === workInProgress.ref) {
14532 return bailoutOnAlreadyFinishedWork(current$$1, workInProgress, renderExpirationTime);
14533 }
14534 }
14535 // React DevTools reads this flag.
14536 workInProgress.effectTag |= PerformedWork;
14537 var newChild = createWorkInProgress(currentChild, nextProps, renderExpirationTime);
14538 newChild.ref = workInProgress.ref;
14539 newChild.return = workInProgress;
14540 workInProgress.child = newChild;
14541 return newChild;
14542}
14543
14544function updateSimpleMemoComponent(current$$1, workInProgress, Component, nextProps, updateExpirationTime, renderExpirationTime) {
14545 // TODO: current can be non-null here even if the component
14546 // hasn't yet mounted. This happens when the inner render suspends.
14547 // We'll need to figure out if this is fine or can cause issues.
14548
14549 {
14550 if (workInProgress.type !== workInProgress.elementType) {
14551 // Lazy component props can't be validated in createElement
14552 // because they're only guaranteed to be resolved here.
14553 var outerMemoType = workInProgress.elementType;
14554 if (outerMemoType.$$typeof === REACT_LAZY_TYPE) {
14555 // We warn when you define propTypes on lazy()
14556 // so let's just skip over it to find memo() outer wrapper.
14557 // Inner props for memo are validated later.
14558 outerMemoType = refineResolvedLazyComponent(outerMemoType);
14559 }
14560 var outerPropTypes = outerMemoType && outerMemoType.propTypes;
14561 if (outerPropTypes) {
14562 checkPropTypes(outerPropTypes, nextProps, // Resolved (SimpleMemoComponent has no defaultProps)
14563 'prop', getComponentName(outerMemoType), getCurrentFiberStackInDev);
14564 }
14565 // Inner propTypes will be validated in the function component path.
14566 }
14567 }
14568 if (current$$1 !== null) {
14569 var prevProps = current$$1.memoizedProps;
14570 if (shallowEqual(prevProps, nextProps) && current$$1.ref === workInProgress.ref) {
14571 didReceiveUpdate = false;
14572 if (updateExpirationTime < renderExpirationTime) {
14573 return bailoutOnAlreadyFinishedWork(current$$1, workInProgress, renderExpirationTime);
14574 }
14575 }
14576 }
14577 return updateFunctionComponent(current$$1, workInProgress, Component, nextProps, renderExpirationTime);
14578}
14579
14580function updateFragment(current$$1, workInProgress, renderExpirationTime) {
14581 var nextChildren = workInProgress.pendingProps;
14582 reconcileChildren(current$$1, workInProgress, nextChildren, renderExpirationTime);
14583 return workInProgress.child;
14584}
14585
14586function updateMode(current$$1, workInProgress, renderExpirationTime) {
14587 var nextChildren = workInProgress.pendingProps.children;
14588 reconcileChildren(current$$1, workInProgress, nextChildren, renderExpirationTime);
14589 return workInProgress.child;
14590}
14591
14592function updateProfiler(current$$1, workInProgress, renderExpirationTime) {
14593 if (enableProfilerTimer) {
14594 workInProgress.effectTag |= Update;
14595 }
14596 var nextProps = workInProgress.pendingProps;
14597 var nextChildren = nextProps.children;
14598 reconcileChildren(current$$1, workInProgress, nextChildren, renderExpirationTime);
14599 return workInProgress.child;
14600}
14601
14602function markRef(current$$1, workInProgress) {
14603 var ref = workInProgress.ref;
14604 if (current$$1 === null && ref !== null || current$$1 !== null && current$$1.ref !== ref) {
14605 // Schedule a Ref effect
14606 workInProgress.effectTag |= Ref;
14607 }
14608}
14609
14610function updateFunctionComponent(current$$1, workInProgress, Component, nextProps, renderExpirationTime) {
14611 {
14612 if (workInProgress.type !== workInProgress.elementType) {
14613 // Lazy component props can't be validated in createElement
14614 // because they're only guaranteed to be resolved here.
14615 var innerPropTypes = Component.propTypes;
14616 if (innerPropTypes) {
14617 checkPropTypes(innerPropTypes, nextProps, // Resolved props
14618 'prop', getComponentName(Component), getCurrentFiberStackInDev);
14619 }
14620 }
14621 }
14622
14623 var unmaskedContext = getUnmaskedContext(workInProgress, Component, true);
14624 var context = getMaskedContext(workInProgress, unmaskedContext);
14625
14626 var nextChildren = void 0;
14627 prepareToReadContext(workInProgress, renderExpirationTime);
14628 {
14629 ReactCurrentOwner$3.current = workInProgress;
14630 setCurrentPhase('render');
14631 nextChildren = renderWithHooks(current$$1, workInProgress, Component, nextProps, context, renderExpirationTime);
14632 if (debugRenderPhaseSideEffects || debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) {
14633 // Only double-render components with Hooks
14634 if (workInProgress.memoizedState !== null) {
14635 nextChildren = renderWithHooks(current$$1, workInProgress, Component, nextProps, context, renderExpirationTime);
14636 }
14637 }
14638 setCurrentPhase(null);
14639 }
14640
14641 if (current$$1 !== null && !didReceiveUpdate) {
14642 bailoutHooks(current$$1, workInProgress, renderExpirationTime);
14643 return bailoutOnAlreadyFinishedWork(current$$1, workInProgress, renderExpirationTime);
14644 }
14645
14646 // React DevTools reads this flag.
14647 workInProgress.effectTag |= PerformedWork;
14648 reconcileChildren(current$$1, workInProgress, nextChildren, renderExpirationTime);
14649 return workInProgress.child;
14650}
14651
14652function updateClassComponent(current$$1, workInProgress, Component, nextProps, renderExpirationTime) {
14653 {
14654 if (workInProgress.type !== workInProgress.elementType) {
14655 // Lazy component props can't be validated in createElement
14656 // because they're only guaranteed to be resolved here.
14657 var innerPropTypes = Component.propTypes;
14658 if (innerPropTypes) {
14659 checkPropTypes(innerPropTypes, nextProps, // Resolved props
14660 'prop', getComponentName(Component), getCurrentFiberStackInDev);
14661 }
14662 }
14663 }
14664
14665 // Push context providers early to prevent context stack mismatches.
14666 // During mounting we don't know the child context yet as the instance doesn't exist.
14667 // We will invalidate the child context in finishClassComponent() right after rendering.
14668 var hasContext = void 0;
14669 if (isContextProvider(Component)) {
14670 hasContext = true;
14671 pushContextProvider(workInProgress);
14672 } else {
14673 hasContext = false;
14674 }
14675 prepareToReadContext(workInProgress, renderExpirationTime);
14676
14677 var instance = workInProgress.stateNode;
14678 var shouldUpdate = void 0;
14679 if (instance === null) {
14680 if (current$$1 !== null) {
14681 // An class component without an instance only mounts if it suspended
14682 // inside a non- concurrent tree, in an inconsistent state. We want to
14683 // tree it like a new mount, even though an empty version of it already
14684 // committed. Disconnect the alternate pointers.
14685 current$$1.alternate = null;
14686 workInProgress.alternate = null;
14687 // Since this is conceptually a new fiber, schedule a Placement effect
14688 workInProgress.effectTag |= Placement;
14689 }
14690 // In the initial pass we might need to construct the instance.
14691 constructClassInstance(workInProgress, Component, nextProps, renderExpirationTime);
14692 mountClassInstance(workInProgress, Component, nextProps, renderExpirationTime);
14693 shouldUpdate = true;
14694 } else if (current$$1 === null) {
14695 // In a resume, we'll already have an instance we can reuse.
14696 shouldUpdate = resumeMountClassInstance(workInProgress, Component, nextProps, renderExpirationTime);
14697 } else {
14698 shouldUpdate = updateClassInstance(current$$1, workInProgress, Component, nextProps, renderExpirationTime);
14699 }
14700 var nextUnitOfWork = finishClassComponent(current$$1, workInProgress, Component, shouldUpdate, hasContext, renderExpirationTime);
14701 {
14702 var inst = workInProgress.stateNode;
14703 if (inst.props !== nextProps) {
14704 !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;
14705 didWarnAboutReassigningProps = true;
14706 }
14707 }
14708 return nextUnitOfWork;
14709}
14710
14711function finishClassComponent(current$$1, workInProgress, Component, shouldUpdate, hasContext, renderExpirationTime) {
14712 // Refs should update even if shouldComponentUpdate returns false
14713 markRef(current$$1, workInProgress);
14714
14715 var didCaptureError = (workInProgress.effectTag & DidCapture) !== NoEffect;
14716
14717 if (!shouldUpdate && !didCaptureError) {
14718 // Context providers should defer to sCU for rendering
14719 if (hasContext) {
14720 invalidateContextProvider(workInProgress, Component, false);
14721 }
14722
14723 return bailoutOnAlreadyFinishedWork(current$$1, workInProgress, renderExpirationTime);
14724 }
14725
14726 var instance = workInProgress.stateNode;
14727
14728 // Rerender
14729 ReactCurrentOwner$3.current = workInProgress;
14730 var nextChildren = void 0;
14731 if (didCaptureError && typeof Component.getDerivedStateFromError !== 'function') {
14732 // If we captured an error, but getDerivedStateFrom catch is not defined,
14733 // unmount all the children. componentDidCatch will schedule an update to
14734 // re-render a fallback. This is temporary until we migrate everyone to
14735 // the new API.
14736 // TODO: Warn in a future release.
14737 nextChildren = null;
14738
14739 if (enableProfilerTimer) {
14740 stopProfilerTimerIfRunning(workInProgress);
14741 }
14742 } else {
14743 {
14744 setCurrentPhase('render');
14745 nextChildren = instance.render();
14746 if (debugRenderPhaseSideEffects || debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) {
14747 instance.render();
14748 }
14749 setCurrentPhase(null);
14750 }
14751 }
14752
14753 // React DevTools reads this flag.
14754 workInProgress.effectTag |= PerformedWork;
14755 if (current$$1 !== null && didCaptureError) {
14756 // If we're recovering from an error, reconcile without reusing any of
14757 // the existing children. Conceptually, the normal children and the children
14758 // that are shown on error are two different sets, so we shouldn't reuse
14759 // normal children even if their identities match.
14760 forceUnmountCurrentAndReconcile(current$$1, workInProgress, nextChildren, renderExpirationTime);
14761 } else {
14762 reconcileChildren(current$$1, workInProgress, nextChildren, renderExpirationTime);
14763 }
14764
14765 // Memoize state using the values we just used to render.
14766 // TODO: Restructure so we never read values from the instance.
14767 workInProgress.memoizedState = instance.state;
14768
14769 // The context might have changed so we need to recalculate it.
14770 if (hasContext) {
14771 invalidateContextProvider(workInProgress, Component, true);
14772 }
14773
14774 return workInProgress.child;
14775}
14776
14777function pushHostRootContext(workInProgress) {
14778 var root = workInProgress.stateNode;
14779 if (root.pendingContext) {
14780 pushTopLevelContextObject(workInProgress, root.pendingContext, root.pendingContext !== root.context);
14781 } else if (root.context) {
14782 // Should always be set
14783 pushTopLevelContextObject(workInProgress, root.context, false);
14784 }
14785 pushHostContainer(workInProgress, root.containerInfo);
14786}
14787
14788function updateHostRoot(current$$1, workInProgress, renderExpirationTime) {
14789 pushHostRootContext(workInProgress);
14790 var updateQueue = workInProgress.updateQueue;
14791 !(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;
14792 var nextProps = workInProgress.pendingProps;
14793 var prevState = workInProgress.memoizedState;
14794 var prevChildren = prevState !== null ? prevState.element : null;
14795 processUpdateQueue(workInProgress, updateQueue, nextProps, null, renderExpirationTime);
14796 var nextState = workInProgress.memoizedState;
14797 // Caution: React DevTools currently depends on this property
14798 // being called "element".
14799 var nextChildren = nextState.element;
14800 if (nextChildren === prevChildren) {
14801 // If the state is the same as before, that's a bailout because we had
14802 // no work that expires at this time.
14803 resetHydrationState();
14804 return bailoutOnAlreadyFinishedWork(current$$1, workInProgress, renderExpirationTime);
14805 }
14806 var root = workInProgress.stateNode;
14807 if ((current$$1 === null || current$$1.child === null) && root.hydrate && enterHydrationState(workInProgress)) {
14808 // If we don't have any current children this might be the first pass.
14809 // We always try to hydrate. If this isn't a hydration pass there won't
14810 // be any children to hydrate which is effectively the same thing as
14811 // not hydrating.
14812
14813 // This is a bit of a hack. We track the host root as a placement to
14814 // know that we're currently in a mounting state. That way isMounted
14815 // works as expected. We must reset this before committing.
14816 // TODO: Delete this when we delete isMounted and findDOMNode.
14817 workInProgress.effectTag |= Placement;
14818
14819 // Ensure that children mount into this root without tracking
14820 // side-effects. This ensures that we don't store Placement effects on
14821 // nodes that will be hydrated.
14822 workInProgress.child = mountChildFibers(workInProgress, null, nextChildren, renderExpirationTime);
14823 } else {
14824 // Otherwise reset hydration state in case we aborted and resumed another
14825 // root.
14826 reconcileChildren(current$$1, workInProgress, nextChildren, renderExpirationTime);
14827 resetHydrationState();
14828 }
14829 return workInProgress.child;
14830}
14831
14832function updateHostComponent(current$$1, workInProgress, renderExpirationTime) {
14833 pushHostContext(workInProgress);
14834
14835 if (current$$1 === null) {
14836 tryToClaimNextHydratableInstance(workInProgress);
14837 }
14838
14839 var type = workInProgress.type;
14840 var nextProps = workInProgress.pendingProps;
14841 var prevProps = current$$1 !== null ? current$$1.memoizedProps : null;
14842
14843 var nextChildren = nextProps.children;
14844 var isDirectTextChild = shouldSetTextContent(type, nextProps);
14845
14846 if (isDirectTextChild) {
14847 // We special case a direct text child of a host node. This is a common
14848 // case. We won't handle it as a reified child. We will instead handle
14849 // this in the host environment that also have access to this prop. That
14850 // avoids allocating another HostText fiber and traversing it.
14851 nextChildren = null;
14852 } else if (prevProps !== null && shouldSetTextContent(type, prevProps)) {
14853 // If we're switching from a direct text child to a normal child, or to
14854 // empty, we need to schedule the text content to be reset.
14855 workInProgress.effectTag |= ContentReset;
14856 }
14857
14858 markRef(current$$1, workInProgress);
14859
14860 // Check the host config to see if the children are offscreen/hidden.
14861 if (renderExpirationTime !== Never && workInProgress.mode & ConcurrentMode && shouldDeprioritizeSubtree(type, nextProps)) {
14862 // Schedule this fiber to re-render at offscreen priority. Then bailout.
14863 workInProgress.expirationTime = workInProgress.childExpirationTime = Never;
14864 return null;
14865 }
14866
14867 reconcileChildren(current$$1, workInProgress, nextChildren, renderExpirationTime);
14868 return workInProgress.child;
14869}
14870
14871function updateHostText(current$$1, workInProgress) {
14872 if (current$$1 === null) {
14873 tryToClaimNextHydratableInstance(workInProgress);
14874 }
14875 // Nothing to do here. This is terminal. We'll do the completion step
14876 // immediately after.
14877 return null;
14878}
14879
14880function mountLazyComponent(_current, workInProgress, elementType, updateExpirationTime, renderExpirationTime) {
14881 if (_current !== null) {
14882 // An lazy component only mounts if it suspended inside a non-
14883 // concurrent tree, in an inconsistent state. We want to treat it like
14884 // a new mount, even though an empty version of it already committed.
14885 // Disconnect the alternate pointers.
14886 _current.alternate = null;
14887 workInProgress.alternate = null;
14888 // Since this is conceptually a new fiber, schedule a Placement effect
14889 workInProgress.effectTag |= Placement;
14890 }
14891
14892 var props = workInProgress.pendingProps;
14893 // We can't start a User Timing measurement with correct label yet.
14894 // Cancel and resume right after we know the tag.
14895 cancelWorkTimer(workInProgress);
14896 var Component = readLazyComponentType(elementType);
14897 // Store the unwrapped component in the type.
14898 workInProgress.type = Component;
14899 var resolvedTag = workInProgress.tag = resolveLazyComponentTag(Component);
14900 startWorkTimer(workInProgress);
14901 var resolvedProps = resolveDefaultProps(Component, props);
14902 var child = void 0;
14903 switch (resolvedTag) {
14904 case FunctionComponent:
14905 {
14906 {
14907 validateFunctionComponentInDev(workInProgress, Component);
14908 }
14909 child = updateFunctionComponent(null, workInProgress, Component, resolvedProps, renderExpirationTime);
14910 break;
14911 }
14912 case ClassComponent:
14913 {
14914 child = updateClassComponent(null, workInProgress, Component, resolvedProps, renderExpirationTime);
14915 break;
14916 }
14917 case ForwardRef:
14918 {
14919 child = updateForwardRef(null, workInProgress, Component, resolvedProps, renderExpirationTime);
14920 break;
14921 }
14922 case MemoComponent:
14923 {
14924 {
14925 if (workInProgress.type !== workInProgress.elementType) {
14926 var outerPropTypes = Component.propTypes;
14927 if (outerPropTypes) {
14928 checkPropTypes(outerPropTypes, resolvedProps, // Resolved for outer only
14929 'prop', getComponentName(Component), getCurrentFiberStackInDev);
14930 }
14931 }
14932 }
14933 child = updateMemoComponent(null, workInProgress, Component, resolveDefaultProps(Component.type, resolvedProps), // The inner type can have defaults too
14934 updateExpirationTime, renderExpirationTime);
14935 break;
14936 }
14937 default:
14938 {
14939 var hint = '';
14940 {
14941 if (Component !== null && typeof Component === 'object' && Component.$$typeof === REACT_LAZY_TYPE) {
14942 hint = ' Did you wrap a component in React.lazy() more than once?';
14943 }
14944 }
14945 // This message intentionally doesn't mention ForwardRef or MemoComponent
14946 // because the fact that it's a separate type of work is an
14947 // implementation detail.
14948 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);
14949 }
14950 }
14951 return child;
14952}
14953
14954function mountIncompleteClassComponent(_current, workInProgress, Component, nextProps, renderExpirationTime) {
14955 if (_current !== null) {
14956 // An incomplete component only mounts if it suspended inside a non-
14957 // concurrent tree, in an inconsistent state. We want to treat it like
14958 // a new mount, even though an empty version of it already committed.
14959 // Disconnect the alternate pointers.
14960 _current.alternate = null;
14961 workInProgress.alternate = null;
14962 // Since this is conceptually a new fiber, schedule a Placement effect
14963 workInProgress.effectTag |= Placement;
14964 }
14965
14966 // Promote the fiber to a class and try rendering again.
14967 workInProgress.tag = ClassComponent;
14968
14969 // The rest of this function is a fork of `updateClassComponent`
14970
14971 // Push context providers early to prevent context stack mismatches.
14972 // During mounting we don't know the child context yet as the instance doesn't exist.
14973 // We will invalidate the child context in finishClassComponent() right after rendering.
14974 var hasContext = void 0;
14975 if (isContextProvider(Component)) {
14976 hasContext = true;
14977 pushContextProvider(workInProgress);
14978 } else {
14979 hasContext = false;
14980 }
14981 prepareToReadContext(workInProgress, renderExpirationTime);
14982
14983 constructClassInstance(workInProgress, Component, nextProps, renderExpirationTime);
14984 mountClassInstance(workInProgress, Component, nextProps, renderExpirationTime);
14985
14986 return finishClassComponent(null, workInProgress, Component, true, hasContext, renderExpirationTime);
14987}
14988
14989function mountIndeterminateComponent(_current, workInProgress, Component, renderExpirationTime) {
14990 if (_current !== null) {
14991 // An indeterminate component only mounts if it suspended inside a non-
14992 // concurrent tree, in an inconsistent state. We want to treat it like
14993 // a new mount, even though an empty version of it already committed.
14994 // Disconnect the alternate pointers.
14995 _current.alternate = null;
14996 workInProgress.alternate = null;
14997 // Since this is conceptually a new fiber, schedule a Placement effect
14998 workInProgress.effectTag |= Placement;
14999 }
15000
15001 var props = workInProgress.pendingProps;
15002 var unmaskedContext = getUnmaskedContext(workInProgress, Component, false);
15003 var context = getMaskedContext(workInProgress, unmaskedContext);
15004
15005 prepareToReadContext(workInProgress, renderExpirationTime);
15006
15007 var value = void 0;
15008
15009 {
15010 if (Component.prototype && typeof Component.prototype.render === 'function') {
15011 var componentName = getComponentName(Component) || 'Unknown';
15012
15013 if (!didWarnAboutBadClass[componentName]) {
15014 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);
15015 didWarnAboutBadClass[componentName] = true;
15016 }
15017 }
15018
15019 if (workInProgress.mode & StrictMode) {
15020 ReactStrictModeWarnings.recordLegacyContextWarning(workInProgress, null);
15021 }
15022
15023 ReactCurrentOwner$3.current = workInProgress;
15024 value = renderWithHooks(null, workInProgress, Component, props, context, renderExpirationTime);
15025 }
15026 // React DevTools reads this flag.
15027 workInProgress.effectTag |= PerformedWork;
15028
15029 if (typeof value === 'object' && value !== null && typeof value.render === 'function' && value.$$typeof === undefined) {
15030 // Proceed under the assumption that this is a class instance
15031 workInProgress.tag = ClassComponent;
15032
15033 // Throw out any hooks that were used.
15034 resetHooks();
15035
15036 // Push context providers early to prevent context stack mismatches.
15037 // During mounting we don't know the child context yet as the instance doesn't exist.
15038 // We will invalidate the child context in finishClassComponent() right after rendering.
15039 var hasContext = false;
15040 if (isContextProvider(Component)) {
15041 hasContext = true;
15042 pushContextProvider(workInProgress);
15043 } else {
15044 hasContext = false;
15045 }
15046
15047 workInProgress.memoizedState = value.state !== null && value.state !== undefined ? value.state : null;
15048
15049 var getDerivedStateFromProps = Component.getDerivedStateFromProps;
15050 if (typeof getDerivedStateFromProps === 'function') {
15051 applyDerivedStateFromProps(workInProgress, Component, getDerivedStateFromProps, props);
15052 }
15053
15054 adoptClassInstance(workInProgress, value);
15055 mountClassInstance(workInProgress, Component, props, renderExpirationTime);
15056 return finishClassComponent(null, workInProgress, Component, true, hasContext, renderExpirationTime);
15057 } else {
15058 // Proceed under the assumption that this is a function component
15059 workInProgress.tag = FunctionComponent;
15060 {
15061 if (debugRenderPhaseSideEffects || debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) {
15062 // Only double-render components with Hooks
15063 if (workInProgress.memoizedState !== null) {
15064 value = renderWithHooks(null, workInProgress, Component, props, context, renderExpirationTime);
15065 }
15066 }
15067 }
15068 reconcileChildren(null, workInProgress, value, renderExpirationTime);
15069 {
15070 validateFunctionComponentInDev(workInProgress, Component);
15071 }
15072 return workInProgress.child;
15073 }
15074}
15075
15076function validateFunctionComponentInDev(workInProgress, Component) {
15077 if (Component) {
15078 !!Component.childContextTypes ? warningWithoutStack$1(false, '%s(...): childContextTypes cannot be defined on a function component.', Component.displayName || Component.name || 'Component') : void 0;
15079 }
15080 if (workInProgress.ref !== null) {
15081 var info = '';
15082 var ownerName = getCurrentFiberOwnerNameInDevOrNull();
15083 if (ownerName) {
15084 info += '\n\nCheck the render method of `' + ownerName + '`.';
15085 }
15086
15087 var warningKey = ownerName || workInProgress._debugID || '';
15088 var debugSource = workInProgress._debugSource;
15089 if (debugSource) {
15090 warningKey = debugSource.fileName + ':' + debugSource.lineNumber;
15091 }
15092 if (!didWarnAboutFunctionRefs[warningKey]) {
15093 didWarnAboutFunctionRefs[warningKey] = true;
15094 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);
15095 }
15096 }
15097
15098 if (typeof Component.getDerivedStateFromProps === 'function') {
15099 var componentName = getComponentName(Component) || 'Unknown';
15100
15101 if (!didWarnAboutGetDerivedStateOnFunctionComponent[componentName]) {
15102 warningWithoutStack$1(false, '%s: Function components do not support getDerivedStateFromProps.', componentName);
15103 didWarnAboutGetDerivedStateOnFunctionComponent[componentName] = true;
15104 }
15105 }
15106
15107 if (typeof Component.contextType === 'object' && Component.contextType !== null) {
15108 var _componentName = getComponentName(Component) || 'Unknown';
15109
15110 if (!didWarnAboutContextTypeOnFunctionComponent[_componentName]) {
15111 warningWithoutStack$1(false, '%s: Function components do not support contextType.', _componentName);
15112 didWarnAboutContextTypeOnFunctionComponent[_componentName] = true;
15113 }
15114 }
15115}
15116
15117function updateSuspenseComponent(current$$1, workInProgress, renderExpirationTime) {
15118 var mode = workInProgress.mode;
15119 var nextProps = workInProgress.pendingProps;
15120
15121 // We should attempt to render the primary children unless this boundary
15122 // already suspended during this render (`alreadyCaptured` is true).
15123 var nextState = workInProgress.memoizedState;
15124
15125 var nextDidTimeout = void 0;
15126 if ((workInProgress.effectTag & DidCapture) === NoEffect) {
15127 // This is the first attempt.
15128 nextState = null;
15129 nextDidTimeout = false;
15130 } else {
15131 // Something in this boundary's subtree already suspended. Switch to
15132 // rendering the fallback children.
15133 nextState = {
15134 timedOutAt: nextState !== null ? nextState.timedOutAt : NoWork
15135 };
15136 nextDidTimeout = true;
15137 workInProgress.effectTag &= ~DidCapture;
15138 }
15139
15140 // This next part is a bit confusing. If the children timeout, we switch to
15141 // showing the fallback children in place of the "primary" children.
15142 // However, we don't want to delete the primary children because then their
15143 // state will be lost (both the React state and the host state, e.g.
15144 // uncontrolled form inputs). Instead we keep them mounted and hide them.
15145 // Both the fallback children AND the primary children are rendered at the
15146 // same time. Once the primary children are un-suspended, we can delete
15147 // the fallback children — don't need to preserve their state.
15148 //
15149 // The two sets of children are siblings in the host environment, but
15150 // semantically, for purposes of reconciliation, they are two separate sets.
15151 // So we store them using two fragment fibers.
15152 //
15153 // However, we want to avoid allocating extra fibers for every placeholder.
15154 // They're only necessary when the children time out, because that's the
15155 // only time when both sets are mounted.
15156 //
15157 // So, the extra fragment fibers are only used if the children time out.
15158 // Otherwise, we render the primary children directly. This requires some
15159 // custom reconciliation logic to preserve the state of the primary
15160 // children. It's essentially a very basic form of re-parenting.
15161
15162 // `child` points to the child fiber. In the normal case, this is the first
15163 // fiber of the primary children set. In the timed-out case, it's a
15164 // a fragment fiber containing the primary children.
15165 var child = void 0;
15166 // `next` points to the next fiber React should render. In the normal case,
15167 // it's the same as `child`: the first fiber of the primary children set.
15168 // In the timed-out case, it's a fragment fiber containing the *fallback*
15169 // children -- we skip over the primary children entirely.
15170 var next = void 0;
15171 if (current$$1 === null) {
15172 if (enableSuspenseServerRenderer) {
15173 // If we're currently hydrating, try to hydrate this boundary.
15174 // But only if this has a fallback.
15175 if (nextProps.fallback !== undefined) {
15176 tryToClaimNextHydratableInstance(workInProgress);
15177 // This could've changed the tag if this was a dehydrated suspense component.
15178 if (workInProgress.tag === DehydratedSuspenseComponent) {
15179 return updateDehydratedSuspenseComponent(null, workInProgress, renderExpirationTime);
15180 }
15181 }
15182 }
15183
15184 // This is the initial mount. This branch is pretty simple because there's
15185 // no previous state that needs to be preserved.
15186 if (nextDidTimeout) {
15187 // Mount separate fragments for primary and fallback children.
15188 var nextFallbackChildren = nextProps.fallback;
15189 var primaryChildFragment = createFiberFromFragment(null, mode, NoWork, null);
15190
15191 if ((workInProgress.mode & ConcurrentMode) === NoContext) {
15192 // Outside of concurrent mode, we commit the effects from the
15193 var progressedState = workInProgress.memoizedState;
15194 var progressedPrimaryChild = progressedState !== null ? workInProgress.child.child : workInProgress.child;
15195 primaryChildFragment.child = progressedPrimaryChild;
15196 }
15197
15198 var fallbackChildFragment = createFiberFromFragment(nextFallbackChildren, mode, renderExpirationTime, null);
15199 primaryChildFragment.sibling = fallbackChildFragment;
15200 child = primaryChildFragment;
15201 // Skip the primary children, and continue working on the
15202 // fallback children.
15203 next = fallbackChildFragment;
15204 child.return = next.return = workInProgress;
15205 } else {
15206 // Mount the primary children without an intermediate fragment fiber.
15207 var nextPrimaryChildren = nextProps.children;
15208 child = next = mountChildFibers(workInProgress, null, nextPrimaryChildren, renderExpirationTime);
15209 }
15210 } else {
15211 // This is an update. This branch is more complicated because we need to
15212 // ensure the state of the primary children is preserved.
15213 var prevState = current$$1.memoizedState;
15214 var prevDidTimeout = prevState !== null;
15215 if (prevDidTimeout) {
15216 // The current tree already timed out. That means each child set is
15217 var currentPrimaryChildFragment = current$$1.child;
15218 var currentFallbackChildFragment = currentPrimaryChildFragment.sibling;
15219 if (nextDidTimeout) {
15220 // Still timed out. Reuse the current primary children by cloning
15221 // its fragment. We're going to skip over these entirely.
15222 var _nextFallbackChildren = nextProps.fallback;
15223 var _primaryChildFragment = createWorkInProgress(currentPrimaryChildFragment, currentPrimaryChildFragment.pendingProps, NoWork);
15224
15225 if ((workInProgress.mode & ConcurrentMode) === NoContext) {
15226 // Outside of concurrent mode, we commit the effects from the
15227 var _progressedState = workInProgress.memoizedState;
15228 var _progressedPrimaryChild = _progressedState !== null ? workInProgress.child.child : workInProgress.child;
15229 if (_progressedPrimaryChild !== currentPrimaryChildFragment.child) {
15230 _primaryChildFragment.child = _progressedPrimaryChild;
15231 }
15232 }
15233
15234 // Because primaryChildFragment is a new fiber that we're inserting as the
15235 // parent of a new tree, we need to set its treeBaseDuration.
15236 if (enableProfilerTimer && workInProgress.mode & ProfileMode) {
15237 // treeBaseDuration is the sum of all the child tree base durations.
15238 var treeBaseDuration = 0;
15239 var hiddenChild = _primaryChildFragment.child;
15240 while (hiddenChild !== null) {
15241 treeBaseDuration += hiddenChild.treeBaseDuration;
15242 hiddenChild = hiddenChild.sibling;
15243 }
15244 _primaryChildFragment.treeBaseDuration = treeBaseDuration;
15245 }
15246
15247 // Clone the fallback child fragment, too. These we'll continue
15248 // working on.
15249 var _fallbackChildFragment = _primaryChildFragment.sibling = createWorkInProgress(currentFallbackChildFragment, _nextFallbackChildren, currentFallbackChildFragment.expirationTime);
15250 child = _primaryChildFragment;
15251 _primaryChildFragment.childExpirationTime = NoWork;
15252 // Skip the primary children, and continue working on the
15253 // fallback children.
15254 next = _fallbackChildFragment;
15255 child.return = next.return = workInProgress;
15256 } else {
15257 // No longer suspended. Switch back to showing the primary children,
15258 // and remove the intermediate fragment fiber.
15259 var _nextPrimaryChildren = nextProps.children;
15260 var currentPrimaryChild = currentPrimaryChildFragment.child;
15261 var primaryChild = reconcileChildFibers(workInProgress, currentPrimaryChild, _nextPrimaryChildren, renderExpirationTime);
15262
15263 // If this render doesn't suspend, we need to delete the fallback
15264 // children. Wait until the complete phase, after we've confirmed the
15265 // fallback is no longer needed.
15266 // TODO: Would it be better to store the fallback fragment on
15267 // the stateNode?
15268
15269 // Continue rendering the children, like we normally do.
15270 child = next = primaryChild;
15271 }
15272 } else {
15273 // The current tree has not already timed out. That means the primary
15274 // children are not wrapped in a fragment fiber.
15275 var _currentPrimaryChild = current$$1.child;
15276 if (nextDidTimeout) {
15277 // Timed out. Wrap the children in a fragment fiber to keep them
15278 // separate from the fallback children.
15279 var _nextFallbackChildren2 = nextProps.fallback;
15280 var _primaryChildFragment2 = createFiberFromFragment(
15281 // It shouldn't matter what the pending props are because we aren't
15282 // going to render this fragment.
15283 null, mode, NoWork, null);
15284 _primaryChildFragment2.child = _currentPrimaryChild;
15285
15286 // Even though we're creating a new fiber, there are no new children,
15287 // because we're reusing an already mounted tree. So we don't need to
15288 // schedule a placement.
15289 // primaryChildFragment.effectTag |= Placement;
15290
15291 if ((workInProgress.mode & ConcurrentMode) === NoContext) {
15292 // Outside of concurrent mode, we commit the effects from the
15293 var _progressedState2 = workInProgress.memoizedState;
15294 var _progressedPrimaryChild2 = _progressedState2 !== null ? workInProgress.child.child : workInProgress.child;
15295 _primaryChildFragment2.child = _progressedPrimaryChild2;
15296 }
15297
15298 // Because primaryChildFragment is a new fiber that we're inserting as the
15299 // parent of a new tree, we need to set its treeBaseDuration.
15300 if (enableProfilerTimer && workInProgress.mode & ProfileMode) {
15301 // treeBaseDuration is the sum of all the child tree base durations.
15302 var _treeBaseDuration = 0;
15303 var _hiddenChild = _primaryChildFragment2.child;
15304 while (_hiddenChild !== null) {
15305 _treeBaseDuration += _hiddenChild.treeBaseDuration;
15306 _hiddenChild = _hiddenChild.sibling;
15307 }
15308 _primaryChildFragment2.treeBaseDuration = _treeBaseDuration;
15309 }
15310
15311 // Create a fragment from the fallback children, too.
15312 var _fallbackChildFragment2 = _primaryChildFragment2.sibling = createFiberFromFragment(_nextFallbackChildren2, mode, renderExpirationTime, null);
15313 _fallbackChildFragment2.effectTag |= Placement;
15314 child = _primaryChildFragment2;
15315 _primaryChildFragment2.childExpirationTime = NoWork;
15316 // Skip the primary children, and continue working on the
15317 // fallback children.
15318 next = _fallbackChildFragment2;
15319 child.return = next.return = workInProgress;
15320 } else {
15321 // Still haven't timed out. Continue rendering the children, like we
15322 // normally do.
15323 var _nextPrimaryChildren2 = nextProps.children;
15324 next = child = reconcileChildFibers(workInProgress, _currentPrimaryChild, _nextPrimaryChildren2, renderExpirationTime);
15325 }
15326 }
15327 workInProgress.stateNode = current$$1.stateNode;
15328 }
15329
15330 workInProgress.memoizedState = nextState;
15331 workInProgress.child = child;
15332 return next;
15333}
15334
15335function updateDehydratedSuspenseComponent(current$$1, workInProgress, renderExpirationTime) {
15336 if (current$$1 === null) {
15337 // During the first pass, we'll bail out and not drill into the children.
15338 // Instead, we'll leave the content in place and try to hydrate it later.
15339 workInProgress.expirationTime = Never;
15340 return null;
15341 }
15342 // We use childExpirationTime to indicate that a child might depend on context, so if
15343 // any context has changed, we need to treat is as if the input might have changed.
15344 var hasContextChanged$$1 = current$$1.childExpirationTime >= renderExpirationTime;
15345 if (didReceiveUpdate || hasContextChanged$$1) {
15346 // This boundary has changed since the first render. This means that we are now unable to
15347 // hydrate it. We might still be able to hydrate it using an earlier expiration time but
15348 // during this render we can't. Instead, we're going to delete the whole subtree and
15349 // instead inject a new real Suspense boundary to take its place, which may render content
15350 // or fallback. The real Suspense boundary will suspend for a while so we have some time
15351 // to ensure it can produce real content, but all state and pending events will be lost.
15352
15353 // Detach from the current dehydrated boundary.
15354 current$$1.alternate = null;
15355 workInProgress.alternate = null;
15356
15357 // Insert a deletion in the effect list.
15358 var returnFiber = workInProgress.return;
15359 !(returnFiber !== null) ? invariant(false, 'Suspense boundaries are never on the root. This is probably a bug in React.') : void 0;
15360 var last = returnFiber.lastEffect;
15361 if (last !== null) {
15362 last.nextEffect = current$$1;
15363 returnFiber.lastEffect = current$$1;
15364 } else {
15365 returnFiber.firstEffect = returnFiber.lastEffect = current$$1;
15366 }
15367 current$$1.nextEffect = null;
15368 current$$1.effectTag = Deletion;
15369
15370 // Upgrade this work in progress to a real Suspense component.
15371 workInProgress.tag = SuspenseComponent;
15372 workInProgress.stateNode = null;
15373 workInProgress.memoizedState = null;
15374 // This is now an insertion.
15375 workInProgress.effectTag |= Placement;
15376 // Retry as a real Suspense component.
15377 return updateSuspenseComponent(null, workInProgress, renderExpirationTime);
15378 }
15379 if ((workInProgress.effectTag & DidCapture) === NoEffect) {
15380 // This is the first attempt.
15381 reenterHydrationStateFromDehydratedSuspenseInstance(workInProgress);
15382 var nextProps = workInProgress.pendingProps;
15383 var nextChildren = nextProps.children;
15384 workInProgress.child = mountChildFibers(workInProgress, null, nextChildren, renderExpirationTime);
15385 return workInProgress.child;
15386 } else {
15387 // Something suspended. Leave the existing children in place.
15388 // TODO: In non-concurrent mode, should we commit the nodes we have hydrated so far?
15389 workInProgress.child = null;
15390 return null;
15391 }
15392}
15393
15394function updatePortalComponent(current$$1, workInProgress, renderExpirationTime) {
15395 pushHostContainer(workInProgress, workInProgress.stateNode.containerInfo);
15396 var nextChildren = workInProgress.pendingProps;
15397 if (current$$1 === null) {
15398 // Portals are special because we don't append the children during mount
15399 // but at commit. Therefore we need to track insertions which the normal
15400 // flow doesn't do during mount. This doesn't happen at the root because
15401 // the root always starts with a "current" with a null child.
15402 // TODO: Consider unifying this with how the root works.
15403 workInProgress.child = reconcileChildFibers(workInProgress, null, nextChildren, renderExpirationTime);
15404 } else {
15405 reconcileChildren(current$$1, workInProgress, nextChildren, renderExpirationTime);
15406 }
15407 return workInProgress.child;
15408}
15409
15410function updateContextProvider(current$$1, workInProgress, renderExpirationTime) {
15411 var providerType = workInProgress.type;
15412 var context = providerType._context;
15413
15414 var newProps = workInProgress.pendingProps;
15415 var oldProps = workInProgress.memoizedProps;
15416
15417 var newValue = newProps.value;
15418
15419 {
15420 var providerPropTypes = workInProgress.type.propTypes;
15421
15422 if (providerPropTypes) {
15423 checkPropTypes(providerPropTypes, newProps, 'prop', 'Context.Provider', getCurrentFiberStackInDev);
15424 }
15425 }
15426
15427 pushProvider(workInProgress, newValue);
15428
15429 if (oldProps !== null) {
15430 var oldValue = oldProps.value;
15431 var changedBits = calculateChangedBits(context, newValue, oldValue);
15432 if (changedBits === 0) {
15433 // No change. Bailout early if children are the same.
15434 if (oldProps.children === newProps.children && !hasContextChanged()) {
15435 return bailoutOnAlreadyFinishedWork(current$$1, workInProgress, renderExpirationTime);
15436 }
15437 } else {
15438 // The context value changed. Search for matching consumers and schedule
15439 // them to update.
15440 propagateContextChange(workInProgress, context, changedBits, renderExpirationTime);
15441 }
15442 }
15443
15444 var newChildren = newProps.children;
15445 reconcileChildren(current$$1, workInProgress, newChildren, renderExpirationTime);
15446 return workInProgress.child;
15447}
15448
15449var hasWarnedAboutUsingContextAsConsumer = false;
15450
15451function updateContextConsumer(current$$1, workInProgress, renderExpirationTime) {
15452 var context = workInProgress.type;
15453 // The logic below for Context differs depending on PROD or DEV mode. In
15454 // DEV mode, we create a separate object for Context.Consumer that acts
15455 // like a proxy to Context. This proxy object adds unnecessary code in PROD
15456 // so we use the old behaviour (Context.Consumer references Context) to
15457 // reduce size and overhead. The separate object references context via
15458 // a property called "_context", which also gives us the ability to check
15459 // in DEV mode if this property exists or not and warn if it does not.
15460 {
15461 if (context._context === undefined) {
15462 // This may be because it's a Context (rather than a Consumer).
15463 // Or it may be because it's older React where they're the same thing.
15464 // We only want to warn if we're sure it's a new React.
15465 if (context !== context.Consumer) {
15466 if (!hasWarnedAboutUsingContextAsConsumer) {
15467 hasWarnedAboutUsingContextAsConsumer = true;
15468 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?');
15469 }
15470 }
15471 } else {
15472 context = context._context;
15473 }
15474 }
15475 var newProps = workInProgress.pendingProps;
15476 var render = newProps.children;
15477
15478 {
15479 !(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;
15480 }
15481
15482 prepareToReadContext(workInProgress, renderExpirationTime);
15483 var newValue = readContext(context, newProps.unstable_observedBits);
15484 var newChildren = void 0;
15485 {
15486 ReactCurrentOwner$3.current = workInProgress;
15487 setCurrentPhase('render');
15488 newChildren = render(newValue);
15489 setCurrentPhase(null);
15490 }
15491
15492 // React DevTools reads this flag.
15493 workInProgress.effectTag |= PerformedWork;
15494 reconcileChildren(current$$1, workInProgress, newChildren, renderExpirationTime);
15495 return workInProgress.child;
15496}
15497
15498function markWorkInProgressReceivedUpdate() {
15499 didReceiveUpdate = true;
15500}
15501
15502function bailoutOnAlreadyFinishedWork(current$$1, workInProgress, renderExpirationTime) {
15503 cancelWorkTimer(workInProgress);
15504
15505 if (current$$1 !== null) {
15506 // Reuse previous context list
15507 workInProgress.contextDependencies = current$$1.contextDependencies;
15508 }
15509
15510 if (enableProfilerTimer) {
15511 // Don't update "base" render times for bailouts.
15512 stopProfilerTimerIfRunning(workInProgress);
15513 }
15514
15515 // Check if the children have any pending work.
15516 var childExpirationTime = workInProgress.childExpirationTime;
15517 if (childExpirationTime < renderExpirationTime) {
15518 // The children don't have any work either. We can skip them.
15519 // TODO: Once we add back resuming, we should check if the children are
15520 // a work-in-progress set. If so, we need to transfer their effects.
15521 return null;
15522 } else {
15523 // This fiber doesn't have work, but its subtree does. Clone the child
15524 // fibers and continue.
15525 cloneChildFibers(current$$1, workInProgress);
15526 return workInProgress.child;
15527 }
15528}
15529
15530function beginWork(current$$1, workInProgress, renderExpirationTime) {
15531 var updateExpirationTime = workInProgress.expirationTime;
15532
15533 if (current$$1 !== null) {
15534 var oldProps = current$$1.memoizedProps;
15535 var newProps = workInProgress.pendingProps;
15536
15537 if (oldProps !== newProps || hasContextChanged()) {
15538 // If props or context changed, mark the fiber as having performed work.
15539 // This may be unset if the props are determined to be equal later (memo).
15540 didReceiveUpdate = true;
15541 } else if (updateExpirationTime < renderExpirationTime) {
15542 didReceiveUpdate = false;
15543 // This fiber does not have any pending work. Bailout without entering
15544 // the begin phase. There's still some bookkeeping we that needs to be done
15545 // in this optimized path, mostly pushing stuff onto the stack.
15546 switch (workInProgress.tag) {
15547 case HostRoot:
15548 pushHostRootContext(workInProgress);
15549 resetHydrationState();
15550 break;
15551 case HostComponent:
15552 pushHostContext(workInProgress);
15553 break;
15554 case ClassComponent:
15555 {
15556 var Component = workInProgress.type;
15557 if (isContextProvider(Component)) {
15558 pushContextProvider(workInProgress);
15559 }
15560 break;
15561 }
15562 case HostPortal:
15563 pushHostContainer(workInProgress, workInProgress.stateNode.containerInfo);
15564 break;
15565 case ContextProvider:
15566 {
15567 var newValue = workInProgress.memoizedProps.value;
15568 pushProvider(workInProgress, newValue);
15569 break;
15570 }
15571 case Profiler:
15572 if (enableProfilerTimer) {
15573 workInProgress.effectTag |= Update;
15574 }
15575 break;
15576 case SuspenseComponent:
15577 {
15578 var state = workInProgress.memoizedState;
15579 var didTimeout = state !== null;
15580 if (didTimeout) {
15581 // If this boundary is currently timed out, we need to decide
15582 // whether to retry the primary children, or to skip over it and
15583 // go straight to the fallback. Check the priority of the primary
15584 var primaryChildFragment = workInProgress.child;
15585 var primaryChildExpirationTime = primaryChildFragment.childExpirationTime;
15586 if (primaryChildExpirationTime !== NoWork && primaryChildExpirationTime >= renderExpirationTime) {
15587 // The primary children have pending work. Use the normal path
15588 // to attempt to render the primary children again.
15589 return updateSuspenseComponent(current$$1, workInProgress, renderExpirationTime);
15590 } else {
15591 // The primary children do not have pending work with sufficient
15592 // priority. Bailout.
15593 var child = bailoutOnAlreadyFinishedWork(current$$1, workInProgress, renderExpirationTime);
15594 if (child !== null) {
15595 // The fallback children have pending work. Skip over the
15596 // primary children and work on the fallback.
15597 return child.sibling;
15598 } else {
15599 return null;
15600 }
15601 }
15602 }
15603 break;
15604 }
15605 case DehydratedSuspenseComponent:
15606 {
15607 if (enableSuspenseServerRenderer) {
15608 // We know that this component will suspend again because if it has
15609 // been unsuspended it has committed as a regular Suspense component.
15610 // If it needs to be retried, it should have work scheduled on it.
15611 workInProgress.effectTag |= DidCapture;
15612 break;
15613 }
15614 }
15615 }
15616 return bailoutOnAlreadyFinishedWork(current$$1, workInProgress, renderExpirationTime);
15617 }
15618 } else {
15619 didReceiveUpdate = false;
15620 }
15621
15622 // Before entering the begin phase, clear the expiration time.
15623 workInProgress.expirationTime = NoWork;
15624
15625 switch (workInProgress.tag) {
15626 case IndeterminateComponent:
15627 {
15628 var elementType = workInProgress.elementType;
15629 return mountIndeterminateComponent(current$$1, workInProgress, elementType, renderExpirationTime);
15630 }
15631 case LazyComponent:
15632 {
15633 var _elementType = workInProgress.elementType;
15634 return mountLazyComponent(current$$1, workInProgress, _elementType, updateExpirationTime, renderExpirationTime);
15635 }
15636 case FunctionComponent:
15637 {
15638 var _Component = workInProgress.type;
15639 var unresolvedProps = workInProgress.pendingProps;
15640 var resolvedProps = workInProgress.elementType === _Component ? unresolvedProps : resolveDefaultProps(_Component, unresolvedProps);
15641 return updateFunctionComponent(current$$1, workInProgress, _Component, resolvedProps, renderExpirationTime);
15642 }
15643 case ClassComponent:
15644 {
15645 var _Component2 = workInProgress.type;
15646 var _unresolvedProps = workInProgress.pendingProps;
15647 var _resolvedProps = workInProgress.elementType === _Component2 ? _unresolvedProps : resolveDefaultProps(_Component2, _unresolvedProps);
15648 return updateClassComponent(current$$1, workInProgress, _Component2, _resolvedProps, renderExpirationTime);
15649 }
15650 case HostRoot:
15651 return updateHostRoot(current$$1, workInProgress, renderExpirationTime);
15652 case HostComponent:
15653 return updateHostComponent(current$$1, workInProgress, renderExpirationTime);
15654 case HostText:
15655 return updateHostText(current$$1, workInProgress);
15656 case SuspenseComponent:
15657 return updateSuspenseComponent(current$$1, workInProgress, renderExpirationTime);
15658 case HostPortal:
15659 return updatePortalComponent(current$$1, workInProgress, renderExpirationTime);
15660 case ForwardRef:
15661 {
15662 var type = workInProgress.type;
15663 var _unresolvedProps2 = workInProgress.pendingProps;
15664 var _resolvedProps2 = workInProgress.elementType === type ? _unresolvedProps2 : resolveDefaultProps(type, _unresolvedProps2);
15665 return updateForwardRef(current$$1, workInProgress, type, _resolvedProps2, renderExpirationTime);
15666 }
15667 case Fragment:
15668 return updateFragment(current$$1, workInProgress, renderExpirationTime);
15669 case Mode:
15670 return updateMode(current$$1, workInProgress, renderExpirationTime);
15671 case Profiler:
15672 return updateProfiler(current$$1, workInProgress, renderExpirationTime);
15673 case ContextProvider:
15674 return updateContextProvider(current$$1, workInProgress, renderExpirationTime);
15675 case ContextConsumer:
15676 return updateContextConsumer(current$$1, workInProgress, renderExpirationTime);
15677 case MemoComponent:
15678 {
15679 var _type2 = workInProgress.type;
15680 var _unresolvedProps3 = workInProgress.pendingProps;
15681 // Resolve outer props first, then resolve inner props.
15682 var _resolvedProps3 = resolveDefaultProps(_type2, _unresolvedProps3);
15683 {
15684 if (workInProgress.type !== workInProgress.elementType) {
15685 var outerPropTypes = _type2.propTypes;
15686 if (outerPropTypes) {
15687 checkPropTypes(outerPropTypes, _resolvedProps3, // Resolved for outer only
15688 'prop', getComponentName(_type2), getCurrentFiberStackInDev);
15689 }
15690 }
15691 }
15692 _resolvedProps3 = resolveDefaultProps(_type2.type, _resolvedProps3);
15693 return updateMemoComponent(current$$1, workInProgress, _type2, _resolvedProps3, updateExpirationTime, renderExpirationTime);
15694 }
15695 case SimpleMemoComponent:
15696 {
15697 return updateSimpleMemoComponent(current$$1, workInProgress, workInProgress.type, workInProgress.pendingProps, updateExpirationTime, renderExpirationTime);
15698 }
15699 case IncompleteClassComponent:
15700 {
15701 var _Component3 = workInProgress.type;
15702 var _unresolvedProps4 = workInProgress.pendingProps;
15703 var _resolvedProps4 = workInProgress.elementType === _Component3 ? _unresolvedProps4 : resolveDefaultProps(_Component3, _unresolvedProps4);
15704 return mountIncompleteClassComponent(current$$1, workInProgress, _Component3, _resolvedProps4, renderExpirationTime);
15705 }
15706 case DehydratedSuspenseComponent:
15707 {
15708 if (enableSuspenseServerRenderer) {
15709 return updateDehydratedSuspenseComponent(current$$1, workInProgress, renderExpirationTime);
15710 }
15711 break;
15712 }
15713 }
15714 invariant(false, 'Unknown unit of work tag. This error is likely caused by a bug in React. Please file an issue.');
15715}
15716
15717var valueCursor = createCursor(null);
15718
15719var rendererSigil = void 0;
15720{
15721 // Use this to detect multiple renderers using the same context
15722 rendererSigil = {};
15723}
15724
15725var currentlyRenderingFiber = null;
15726var lastContextDependency = null;
15727var lastContextWithAllBitsObserved = null;
15728
15729var isDisallowedContextReadInDEV = false;
15730
15731function resetContextDependences() {
15732 // This is called right before React yields execution, to ensure `readContext`
15733 // cannot be called outside the render phase.
15734 currentlyRenderingFiber = null;
15735 lastContextDependency = null;
15736 lastContextWithAllBitsObserved = null;
15737 {
15738 isDisallowedContextReadInDEV = false;
15739 }
15740}
15741
15742function enterDisallowedContextReadInDEV() {
15743 {
15744 isDisallowedContextReadInDEV = true;
15745 }
15746}
15747
15748function exitDisallowedContextReadInDEV() {
15749 {
15750 isDisallowedContextReadInDEV = false;
15751 }
15752}
15753
15754function pushProvider(providerFiber, nextValue) {
15755 var context = providerFiber.type._context;
15756
15757 if (isPrimaryRenderer) {
15758 push(valueCursor, context._currentValue, providerFiber);
15759
15760 context._currentValue = nextValue;
15761 {
15762 !(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;
15763 context._currentRenderer = rendererSigil;
15764 }
15765 } else {
15766 push(valueCursor, context._currentValue2, providerFiber);
15767
15768 context._currentValue2 = nextValue;
15769 {
15770 !(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;
15771 context._currentRenderer2 = rendererSigil;
15772 }
15773 }
15774}
15775
15776function popProvider(providerFiber) {
15777 var currentValue = valueCursor.current;
15778
15779 pop(valueCursor, providerFiber);
15780
15781 var context = providerFiber.type._context;
15782 if (isPrimaryRenderer) {
15783 context._currentValue = currentValue;
15784 } else {
15785 context._currentValue2 = currentValue;
15786 }
15787}
15788
15789function calculateChangedBits(context, newValue, oldValue) {
15790 if (is(oldValue, newValue)) {
15791 // No change
15792 return 0;
15793 } else {
15794 var changedBits = typeof context._calculateChangedBits === 'function' ? context._calculateChangedBits(oldValue, newValue) : maxSigned31BitInt;
15795
15796 {
15797 !((changedBits & maxSigned31BitInt) === changedBits) ? warning$1(false, 'calculateChangedBits: Expected the return value to be a ' + '31-bit integer. Instead received: %s', changedBits) : void 0;
15798 }
15799 return changedBits | 0;
15800 }
15801}
15802
15803function scheduleWorkOnParentPath(parent, renderExpirationTime) {
15804 // Update the child expiration time of all the ancestors, including
15805 // the alternates.
15806 var node = parent;
15807 while (node !== null) {
15808 var alternate = node.alternate;
15809 if (node.childExpirationTime < renderExpirationTime) {
15810 node.childExpirationTime = renderExpirationTime;
15811 if (alternate !== null && alternate.childExpirationTime < renderExpirationTime) {
15812 alternate.childExpirationTime = renderExpirationTime;
15813 }
15814 } else if (alternate !== null && alternate.childExpirationTime < renderExpirationTime) {
15815 alternate.childExpirationTime = renderExpirationTime;
15816 } else {
15817 // Neither alternate was updated, which means the rest of the
15818 // ancestor path already has sufficient priority.
15819 break;
15820 }
15821 node = node.return;
15822 }
15823}
15824
15825function propagateContextChange(workInProgress, context, changedBits, renderExpirationTime) {
15826 var fiber = workInProgress.child;
15827 if (fiber !== null) {
15828 // Set the return pointer of the child to the work-in-progress fiber.
15829 fiber.return = workInProgress;
15830 }
15831 while (fiber !== null) {
15832 var nextFiber = void 0;
15833
15834 // Visit this fiber.
15835 var list = fiber.contextDependencies;
15836 if (list !== null) {
15837 nextFiber = fiber.child;
15838
15839 var dependency = list.first;
15840 while (dependency !== null) {
15841 // Check if the context matches.
15842 if (dependency.context === context && (dependency.observedBits & changedBits) !== 0) {
15843 // Match! Schedule an update on this fiber.
15844
15845 if (fiber.tag === ClassComponent) {
15846 // Schedule a force update on the work-in-progress.
15847 var update = createUpdate(renderExpirationTime);
15848 update.tag = ForceUpdate;
15849 // TODO: Because we don't have a work-in-progress, this will add the
15850 // update to the current fiber, too, which means it will persist even if
15851 // this render is thrown away. Since it's a race condition, not sure it's
15852 // worth fixing.
15853 enqueueUpdate(fiber, update);
15854 }
15855
15856 if (fiber.expirationTime < renderExpirationTime) {
15857 fiber.expirationTime = renderExpirationTime;
15858 }
15859 var alternate = fiber.alternate;
15860 if (alternate !== null && alternate.expirationTime < renderExpirationTime) {
15861 alternate.expirationTime = renderExpirationTime;
15862 }
15863
15864 scheduleWorkOnParentPath(fiber.return, renderExpirationTime);
15865
15866 // Mark the expiration time on the list, too.
15867 if (list.expirationTime < renderExpirationTime) {
15868 list.expirationTime = renderExpirationTime;
15869 }
15870
15871 // Since we already found a match, we can stop traversing the
15872 // dependency list.
15873 break;
15874 }
15875 dependency = dependency.next;
15876 }
15877 } else if (fiber.tag === ContextProvider) {
15878 // Don't scan deeper if this is a matching provider
15879 nextFiber = fiber.type === workInProgress.type ? null : fiber.child;
15880 } else if (enableSuspenseServerRenderer && fiber.tag === DehydratedSuspenseComponent) {
15881 // If a dehydrated suspense component is in this subtree, we don't know
15882 // if it will have any context consumers in it. The best we can do is
15883 // mark it as having updates on its children.
15884 if (fiber.expirationTime < renderExpirationTime) {
15885 fiber.expirationTime = renderExpirationTime;
15886 }
15887 var _alternate = fiber.alternate;
15888 if (_alternate !== null && _alternate.expirationTime < renderExpirationTime) {
15889 _alternate.expirationTime = renderExpirationTime;
15890 }
15891 // This is intentionally passing this fiber as the parent
15892 // because we want to schedule this fiber as having work
15893 // on its children. We'll use the childExpirationTime on
15894 // this fiber to indicate that a context has changed.
15895 scheduleWorkOnParentPath(fiber, renderExpirationTime);
15896 nextFiber = fiber.sibling;
15897 } else {
15898 // Traverse down.
15899 nextFiber = fiber.child;
15900 }
15901
15902 if (nextFiber !== null) {
15903 // Set the return pointer of the child to the work-in-progress fiber.
15904 nextFiber.return = fiber;
15905 } else {
15906 // No child. Traverse to next sibling.
15907 nextFiber = fiber;
15908 while (nextFiber !== null) {
15909 if (nextFiber === workInProgress) {
15910 // We're back to the root of this subtree. Exit.
15911 nextFiber = null;
15912 break;
15913 }
15914 var sibling = nextFiber.sibling;
15915 if (sibling !== null) {
15916 // Set the return pointer of the sibling to the work-in-progress fiber.
15917 sibling.return = nextFiber.return;
15918 nextFiber = sibling;
15919 break;
15920 }
15921 // No more siblings. Traverse up.
15922 nextFiber = nextFiber.return;
15923 }
15924 }
15925 fiber = nextFiber;
15926 }
15927}
15928
15929function prepareToReadContext(workInProgress, renderExpirationTime) {
15930 currentlyRenderingFiber = workInProgress;
15931 lastContextDependency = null;
15932 lastContextWithAllBitsObserved = null;
15933
15934 var currentDependencies = workInProgress.contextDependencies;
15935 if (currentDependencies !== null && currentDependencies.expirationTime >= renderExpirationTime) {
15936 // Context list has a pending update. Mark that this fiber performed work.
15937 markWorkInProgressReceivedUpdate();
15938 }
15939
15940 // Reset the work-in-progress list
15941 workInProgress.contextDependencies = null;
15942}
15943
15944function readContext(context, observedBits) {
15945 {
15946 // This warning would fire if you read context inside a Hook like useMemo.
15947 // Unlike the class check below, it's not enforced in production for perf.
15948 !!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;
15949 }
15950
15951 if (lastContextWithAllBitsObserved === context) {
15952 // Nothing to do. We already observe everything in this context.
15953 } else if (observedBits === false || observedBits === 0) {
15954 // Do not observe any updates.
15955 } else {
15956 var resolvedObservedBits = void 0; // Avoid deopting on observable arguments or heterogeneous types.
15957 if (typeof observedBits !== 'number' || observedBits === maxSigned31BitInt) {
15958 // Observe all updates.
15959 lastContextWithAllBitsObserved = context;
15960 resolvedObservedBits = maxSigned31BitInt;
15961 } else {
15962 resolvedObservedBits = observedBits;
15963 }
15964
15965 var contextItem = {
15966 context: context,
15967 observedBits: resolvedObservedBits,
15968 next: null
15969 };
15970
15971 if (lastContextDependency === null) {
15972 !(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;
15973
15974 // This is the first dependency for this component. Create a new list.
15975 lastContextDependency = contextItem;
15976 currentlyRenderingFiber.contextDependencies = {
15977 first: contextItem,
15978 expirationTime: NoWork
15979 };
15980 } else {
15981 // Append a new context item.
15982 lastContextDependency = lastContextDependency.next = contextItem;
15983 }
15984 }
15985 return isPrimaryRenderer ? context._currentValue : context._currentValue2;
15986}
15987
15988// UpdateQueue is a linked list of prioritized updates.
15989//
15990// Like fibers, update queues come in pairs: a current queue, which represents
15991// the visible state of the screen, and a work-in-progress queue, which can be
15992// mutated and processed asynchronously before it is committed — a form of
15993// double buffering. If a work-in-progress render is discarded before finishing,
15994// we create a new work-in-progress by cloning the current queue.
15995//
15996// Both queues share a persistent, singly-linked list structure. To schedule an
15997// update, we append it to the end of both queues. Each queue maintains a
15998// pointer to first update in the persistent list that hasn't been processed.
15999// The work-in-progress pointer always has a position equal to or greater than
16000// the current queue, since we always work on that one. The current queue's
16001// pointer is only updated during the commit phase, when we swap in the
16002// work-in-progress.
16003//
16004// For example:
16005//
16006// Current pointer: A - B - C - D - E - F
16007// Work-in-progress pointer: D - E - F
16008// ^
16009// The work-in-progress queue has
16010// processed more updates than current.
16011//
16012// The reason we append to both queues is because otherwise we might drop
16013// updates without ever processing them. For example, if we only add updates to
16014// the work-in-progress queue, some updates could be lost whenever a work-in
16015// -progress render restarts by cloning from current. Similarly, if we only add
16016// updates to the current queue, the updates will be lost whenever an already
16017// in-progress queue commits and swaps with the current queue. However, by
16018// adding to both queues, we guarantee that the update will be part of the next
16019// work-in-progress. (And because the work-in-progress queue becomes the
16020// current queue once it commits, there's no danger of applying the same
16021// update twice.)
16022//
16023// Prioritization
16024// --------------
16025//
16026// Updates are not sorted by priority, but by insertion; new updates are always
16027// appended to the end of the list.
16028//
16029// The priority is still important, though. When processing the update queue
16030// during the render phase, only the updates with sufficient priority are
16031// included in the result. If we skip an update because it has insufficient
16032// priority, it remains in the queue to be processed later, during a lower
16033// priority render. Crucially, all updates subsequent to a skipped update also
16034// remain in the queue *regardless of their priority*. That means high priority
16035// updates are sometimes processed twice, at two separate priorities. We also
16036// keep track of a base state, that represents the state before the first
16037// update in the queue is applied.
16038//
16039// For example:
16040//
16041// Given a base state of '', and the following queue of updates
16042//
16043// A1 - B2 - C1 - D2
16044//
16045// where the number indicates the priority, and the update is applied to the
16046// previous state by appending a letter, React will process these updates as
16047// two separate renders, one per distinct priority level:
16048//
16049// First render, at priority 1:
16050// Base state: ''
16051// Updates: [A1, C1]
16052// Result state: 'AC'
16053//
16054// Second render, at priority 2:
16055// Base state: 'A' <- The base state does not include C1,
16056// because B2 was skipped.
16057// Updates: [B2, C1, D2] <- C1 was rebased on top of B2
16058// Result state: 'ABCD'
16059//
16060// Because we process updates in insertion order, and rebase high priority
16061// updates when preceding updates are skipped, the final result is deterministic
16062// regardless of priority. Intermediate state may vary according to system
16063// resources, but the final state is always the same.
16064
16065var UpdateState = 0;
16066var ReplaceState = 1;
16067var ForceUpdate = 2;
16068var CaptureUpdate = 3;
16069
16070// Global state that is reset at the beginning of calling `processUpdateQueue`.
16071// It should only be read right after calling `processUpdateQueue`, via
16072// `checkHasForceUpdateAfterProcessing`.
16073var hasForceUpdate = false;
16074
16075var didWarnUpdateInsideUpdate = void 0;
16076var currentlyProcessingQueue = void 0;
16077var resetCurrentlyProcessingQueue = void 0;
16078{
16079 didWarnUpdateInsideUpdate = false;
16080 currentlyProcessingQueue = null;
16081 resetCurrentlyProcessingQueue = function () {
16082 currentlyProcessingQueue = null;
16083 };
16084}
16085
16086function createUpdateQueue(baseState) {
16087 var queue = {
16088 baseState: baseState,
16089 firstUpdate: null,
16090 lastUpdate: null,
16091 firstCapturedUpdate: null,
16092 lastCapturedUpdate: null,
16093 firstEffect: null,
16094 lastEffect: null,
16095 firstCapturedEffect: null,
16096 lastCapturedEffect: null
16097 };
16098 return queue;
16099}
16100
16101function cloneUpdateQueue(currentQueue) {
16102 var queue = {
16103 baseState: currentQueue.baseState,
16104 firstUpdate: currentQueue.firstUpdate,
16105 lastUpdate: currentQueue.lastUpdate,
16106
16107 // TODO: With resuming, if we bail out and resuse the child tree, we should
16108 // keep these effects.
16109 firstCapturedUpdate: null,
16110 lastCapturedUpdate: null,
16111
16112 firstEffect: null,
16113 lastEffect: null,
16114
16115 firstCapturedEffect: null,
16116 lastCapturedEffect: null
16117 };
16118 return queue;
16119}
16120
16121function createUpdate(expirationTime) {
16122 return {
16123 expirationTime: expirationTime,
16124
16125 tag: UpdateState,
16126 payload: null,
16127 callback: null,
16128
16129 next: null,
16130 nextEffect: null
16131 };
16132}
16133
16134function appendUpdateToQueue(queue, update) {
16135 // Append the update to the end of the list.
16136 if (queue.lastUpdate === null) {
16137 // Queue is empty
16138 queue.firstUpdate = queue.lastUpdate = update;
16139 } else {
16140 queue.lastUpdate.next = update;
16141 queue.lastUpdate = update;
16142 }
16143}
16144
16145function enqueueUpdate(fiber, update) {
16146 // Update queues are created lazily.
16147 var alternate = fiber.alternate;
16148 var queue1 = void 0;
16149 var queue2 = void 0;
16150 if (alternate === null) {
16151 // There's only one fiber.
16152 queue1 = fiber.updateQueue;
16153 queue2 = null;
16154 if (queue1 === null) {
16155 queue1 = fiber.updateQueue = createUpdateQueue(fiber.memoizedState);
16156 }
16157 } else {
16158 // There are two owners.
16159 queue1 = fiber.updateQueue;
16160 queue2 = alternate.updateQueue;
16161 if (queue1 === null) {
16162 if (queue2 === null) {
16163 // Neither fiber has an update queue. Create new ones.
16164 queue1 = fiber.updateQueue = createUpdateQueue(fiber.memoizedState);
16165 queue2 = alternate.updateQueue = createUpdateQueue(alternate.memoizedState);
16166 } else {
16167 // Only one fiber has an update queue. Clone to create a new one.
16168 queue1 = fiber.updateQueue = cloneUpdateQueue(queue2);
16169 }
16170 } else {
16171 if (queue2 === null) {
16172 // Only one fiber has an update queue. Clone to create a new one.
16173 queue2 = alternate.updateQueue = cloneUpdateQueue(queue1);
16174 } else {
16175 // Both owners have an update queue.
16176 }
16177 }
16178 }
16179 if (queue2 === null || queue1 === queue2) {
16180 // There's only a single queue.
16181 appendUpdateToQueue(queue1, update);
16182 } else {
16183 // There are two queues. We need to append the update to both queues,
16184 // while accounting for the persistent structure of the list — we don't
16185 // want the same update to be added multiple times.
16186 if (queue1.lastUpdate === null || queue2.lastUpdate === null) {
16187 // One of the queues is not empty. We must add the update to both queues.
16188 appendUpdateToQueue(queue1, update);
16189 appendUpdateToQueue(queue2, update);
16190 } else {
16191 // Both queues are non-empty. The last update is the same in both lists,
16192 // because of structural sharing. So, only append to one of the lists.
16193 appendUpdateToQueue(queue1, update);
16194 // But we still need to update the `lastUpdate` pointer of queue2.
16195 queue2.lastUpdate = update;
16196 }
16197 }
16198
16199 {
16200 if (fiber.tag === ClassComponent && (currentlyProcessingQueue === queue1 || queue2 !== null && currentlyProcessingQueue === queue2) && !didWarnUpdateInsideUpdate) {
16201 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.');
16202 didWarnUpdateInsideUpdate = true;
16203 }
16204 }
16205}
16206
16207function enqueueCapturedUpdate(workInProgress, update) {
16208 // Captured updates go into a separate list, and only on the work-in-
16209 // progress queue.
16210 var workInProgressQueue = workInProgress.updateQueue;
16211 if (workInProgressQueue === null) {
16212 workInProgressQueue = workInProgress.updateQueue = createUpdateQueue(workInProgress.memoizedState);
16213 } else {
16214 // TODO: I put this here rather than createWorkInProgress so that we don't
16215 // clone the queue unnecessarily. There's probably a better way to
16216 // structure this.
16217 workInProgressQueue = ensureWorkInProgressQueueIsAClone(workInProgress, workInProgressQueue);
16218 }
16219
16220 // Append the update to the end of the list.
16221 if (workInProgressQueue.lastCapturedUpdate === null) {
16222 // This is the first render phase update
16223 workInProgressQueue.firstCapturedUpdate = workInProgressQueue.lastCapturedUpdate = update;
16224 } else {
16225 workInProgressQueue.lastCapturedUpdate.next = update;
16226 workInProgressQueue.lastCapturedUpdate = update;
16227 }
16228}
16229
16230function ensureWorkInProgressQueueIsAClone(workInProgress, queue) {
16231 var current = workInProgress.alternate;
16232 if (current !== null) {
16233 // If the work-in-progress queue is equal to the current queue,
16234 // we need to clone it first.
16235 if (queue === current.updateQueue) {
16236 queue = workInProgress.updateQueue = cloneUpdateQueue(queue);
16237 }
16238 }
16239 return queue;
16240}
16241
16242function getStateFromUpdate(workInProgress, queue, update, prevState, nextProps, instance) {
16243 switch (update.tag) {
16244 case ReplaceState:
16245 {
16246 var _payload = update.payload;
16247 if (typeof _payload === 'function') {
16248 // Updater function
16249 {
16250 enterDisallowedContextReadInDEV();
16251 if (debugRenderPhaseSideEffects || debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) {
16252 _payload.call(instance, prevState, nextProps);
16253 }
16254 }
16255 var nextState = _payload.call(instance, prevState, nextProps);
16256 {
16257 exitDisallowedContextReadInDEV();
16258 }
16259 return nextState;
16260 }
16261 // State object
16262 return _payload;
16263 }
16264 case CaptureUpdate:
16265 {
16266 workInProgress.effectTag = workInProgress.effectTag & ~ShouldCapture | DidCapture;
16267 }
16268 // Intentional fallthrough
16269 case UpdateState:
16270 {
16271 var _payload2 = update.payload;
16272 var partialState = void 0;
16273 if (typeof _payload2 === 'function') {
16274 // Updater function
16275 {
16276 enterDisallowedContextReadInDEV();
16277 if (debugRenderPhaseSideEffects || debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) {
16278 _payload2.call(instance, prevState, nextProps);
16279 }
16280 }
16281 partialState = _payload2.call(instance, prevState, nextProps);
16282 {
16283 exitDisallowedContextReadInDEV();
16284 }
16285 } else {
16286 // Partial state object
16287 partialState = _payload2;
16288 }
16289 if (partialState === null || partialState === undefined) {
16290 // Null and undefined are treated as no-ops.
16291 return prevState;
16292 }
16293 // Merge the partial state and the previous state.
16294 return _assign({}, prevState, partialState);
16295 }
16296 case ForceUpdate:
16297 {
16298 hasForceUpdate = true;
16299 return prevState;
16300 }
16301 }
16302 return prevState;
16303}
16304
16305function processUpdateQueue(workInProgress, queue, props, instance, renderExpirationTime) {
16306 hasForceUpdate = false;
16307
16308 queue = ensureWorkInProgressQueueIsAClone(workInProgress, queue);
16309
16310 {
16311 currentlyProcessingQueue = queue;
16312 }
16313
16314 // These values may change as we process the queue.
16315 var newBaseState = queue.baseState;
16316 var newFirstUpdate = null;
16317 var newExpirationTime = NoWork;
16318
16319 // Iterate through the list of updates to compute the result.
16320 var update = queue.firstUpdate;
16321 var resultState = newBaseState;
16322 while (update !== null) {
16323 var updateExpirationTime = update.expirationTime;
16324 if (updateExpirationTime < renderExpirationTime) {
16325 // This update does not have sufficient priority. Skip it.
16326 if (newFirstUpdate === null) {
16327 // This is the first skipped update. It will be the first update in
16328 // the new list.
16329 newFirstUpdate = update;
16330 // Since this is the first update that was skipped, the current result
16331 // is the new base state.
16332 newBaseState = resultState;
16333 }
16334 // Since this update will remain in the list, update the remaining
16335 // expiration time.
16336 if (newExpirationTime < updateExpirationTime) {
16337 newExpirationTime = updateExpirationTime;
16338 }
16339 } else {
16340 // This update does have sufficient priority. Process it and compute
16341 // a new result.
16342 resultState = getStateFromUpdate(workInProgress, queue, update, resultState, props, instance);
16343 var _callback = update.callback;
16344 if (_callback !== null) {
16345 workInProgress.effectTag |= Callback;
16346 // Set this to null, in case it was mutated during an aborted render.
16347 update.nextEffect = null;
16348 if (queue.lastEffect === null) {
16349 queue.firstEffect = queue.lastEffect = update;
16350 } else {
16351 queue.lastEffect.nextEffect = update;
16352 queue.lastEffect = update;
16353 }
16354 }
16355 }
16356 // Continue to the next update.
16357 update = update.next;
16358 }
16359
16360 // Separately, iterate though the list of captured updates.
16361 var newFirstCapturedUpdate = null;
16362 update = queue.firstCapturedUpdate;
16363 while (update !== null) {
16364 var _updateExpirationTime = update.expirationTime;
16365 if (_updateExpirationTime < renderExpirationTime) {
16366 // This update does not have sufficient priority. Skip it.
16367 if (newFirstCapturedUpdate === null) {
16368 // This is the first skipped captured update. It will be the first
16369 // update in the new list.
16370 newFirstCapturedUpdate = update;
16371 // If this is the first update that was skipped, the current result is
16372 // the new base state.
16373 if (newFirstUpdate === null) {
16374 newBaseState = resultState;
16375 }
16376 }
16377 // Since this update will remain in the list, update the remaining
16378 // expiration time.
16379 if (newExpirationTime < _updateExpirationTime) {
16380 newExpirationTime = _updateExpirationTime;
16381 }
16382 } else {
16383 // This update does have sufficient priority. Process it and compute
16384 // a new result.
16385 resultState = getStateFromUpdate(workInProgress, queue, update, resultState, props, instance);
16386 var _callback2 = update.callback;
16387 if (_callback2 !== null) {
16388 workInProgress.effectTag |= Callback;
16389 // Set this to null, in case it was mutated during an aborted render.
16390 update.nextEffect = null;
16391 if (queue.lastCapturedEffect === null) {
16392 queue.firstCapturedEffect = queue.lastCapturedEffect = update;
16393 } else {
16394 queue.lastCapturedEffect.nextEffect = update;
16395 queue.lastCapturedEffect = update;
16396 }
16397 }
16398 }
16399 update = update.next;
16400 }
16401
16402 if (newFirstUpdate === null) {
16403 queue.lastUpdate = null;
16404 }
16405 if (newFirstCapturedUpdate === null) {
16406 queue.lastCapturedUpdate = null;
16407 } else {
16408 workInProgress.effectTag |= Callback;
16409 }
16410 if (newFirstUpdate === null && newFirstCapturedUpdate === null) {
16411 // We processed every update, without skipping. That means the new base
16412 // state is the same as the result state.
16413 newBaseState = resultState;
16414 }
16415
16416 queue.baseState = newBaseState;
16417 queue.firstUpdate = newFirstUpdate;
16418 queue.firstCapturedUpdate = newFirstCapturedUpdate;
16419
16420 // Set the remaining expiration time to be whatever is remaining in the queue.
16421 // This should be fine because the only two other things that contribute to
16422 // expiration time are props and context. We're already in the middle of the
16423 // begin phase by the time we start processing the queue, so we've already
16424 // dealt with the props. Context in components that specify
16425 // shouldComponentUpdate is tricky; but we'll have to account for
16426 // that regardless.
16427 workInProgress.expirationTime = newExpirationTime;
16428 workInProgress.memoizedState = resultState;
16429
16430 {
16431 currentlyProcessingQueue = null;
16432 }
16433}
16434
16435function callCallback(callback, context) {
16436 !(typeof callback === 'function') ? invariant(false, 'Invalid argument passed as callback. Expected a function. Instead received: %s', callback) : void 0;
16437 callback.call(context);
16438}
16439
16440function resetHasForceUpdateBeforeProcessing() {
16441 hasForceUpdate = false;
16442}
16443
16444function checkHasForceUpdateAfterProcessing() {
16445 return hasForceUpdate;
16446}
16447
16448function commitUpdateQueue(finishedWork, finishedQueue, instance, renderExpirationTime) {
16449 // If the finished render included captured updates, and there are still
16450 // lower priority updates left over, we need to keep the captured updates
16451 // in the queue so that they are rebased and not dropped once we process the
16452 // queue again at the lower priority.
16453 if (finishedQueue.firstCapturedUpdate !== null) {
16454 // Join the captured update list to the end of the normal list.
16455 if (finishedQueue.lastUpdate !== null) {
16456 finishedQueue.lastUpdate.next = finishedQueue.firstCapturedUpdate;
16457 finishedQueue.lastUpdate = finishedQueue.lastCapturedUpdate;
16458 }
16459 // Clear the list of captured updates.
16460 finishedQueue.firstCapturedUpdate = finishedQueue.lastCapturedUpdate = null;
16461 }
16462
16463 // Commit the effects
16464 commitUpdateEffects(finishedQueue.firstEffect, instance);
16465 finishedQueue.firstEffect = finishedQueue.lastEffect = null;
16466
16467 commitUpdateEffects(finishedQueue.firstCapturedEffect, instance);
16468 finishedQueue.firstCapturedEffect = finishedQueue.lastCapturedEffect = null;
16469}
16470
16471function commitUpdateEffects(effect, instance) {
16472 while (effect !== null) {
16473 var _callback3 = effect.callback;
16474 if (_callback3 !== null) {
16475 effect.callback = null;
16476 callCallback(_callback3, instance);
16477 }
16478 effect = effect.nextEffect;
16479 }
16480}
16481
16482function createCapturedValue(value, source) {
16483 // If the value is an error, call this function immediately after it is thrown
16484 // so the stack is accurate.
16485 return {
16486 value: value,
16487 source: source,
16488 stack: getStackByFiberInDevAndProd(source)
16489 };
16490}
16491
16492function markUpdate(workInProgress) {
16493 // Tag the fiber with an update effect. This turns a Placement into
16494 // a PlacementAndUpdate.
16495 workInProgress.effectTag |= Update;
16496}
16497
16498function markRef$1(workInProgress) {
16499 workInProgress.effectTag |= Ref;
16500}
16501
16502var appendAllChildren = void 0;
16503var updateHostContainer = void 0;
16504var updateHostComponent$1 = void 0;
16505var updateHostText$1 = void 0;
16506if (supportsMutation) {
16507 // Mutation mode
16508
16509 appendAllChildren = function (parent, workInProgress, needsVisibilityToggle, isHidden) {
16510 // We only have the top Fiber that was created but we need recurse down its
16511 // children to find all the terminal nodes.
16512 var node = workInProgress.child;
16513 while (node !== null) {
16514 if (node.tag === HostComponent || node.tag === HostText) {
16515 appendInitialChild(parent, node.stateNode);
16516 } else if (node.tag === HostPortal) {
16517 // If we have a portal child, then we don't want to traverse
16518 // down its children. Instead, we'll get insertions from each child in
16519 // the portal directly.
16520 } else if (node.child !== null) {
16521 node.child.return = node;
16522 node = node.child;
16523 continue;
16524 }
16525 if (node === workInProgress) {
16526 return;
16527 }
16528 while (node.sibling === null) {
16529 if (node.return === null || node.return === workInProgress) {
16530 return;
16531 }
16532 node = node.return;
16533 }
16534 node.sibling.return = node.return;
16535 node = node.sibling;
16536 }
16537 };
16538
16539 updateHostContainer = function (workInProgress) {
16540 // Noop
16541 };
16542 updateHostComponent$1 = function (current, workInProgress, type, newProps, rootContainerInstance) {
16543 // If we have an alternate, that means this is an update and we need to
16544 // schedule a side-effect to do the updates.
16545 var oldProps = current.memoizedProps;
16546 if (oldProps === newProps) {
16547 // In mutation mode, this is sufficient for a bailout because
16548 // we won't touch this node even if children changed.
16549 return;
16550 }
16551
16552 // If we get updated because one of our children updated, we don't
16553 // have newProps so we'll have to reuse them.
16554 // TODO: Split the update API as separate for the props vs. children.
16555 // Even better would be if children weren't special cased at all tho.
16556 var instance = workInProgress.stateNode;
16557 var currentHostContext = getHostContext();
16558 // TODO: Experiencing an error where oldProps is null. Suggests a host
16559 // component is hitting the resume path. Figure out why. Possibly
16560 // related to `hidden`.
16561 var updatePayload = prepareUpdate(instance, type, oldProps, newProps, rootContainerInstance, currentHostContext);
16562 // TODO: Type this specific to this type of component.
16563 workInProgress.updateQueue = updatePayload;
16564 // If the update payload indicates that there is a change or if there
16565 // is a new ref we mark this as an update. All the work is done in commitWork.
16566 if (updatePayload) {
16567 markUpdate(workInProgress);
16568 }
16569 };
16570 updateHostText$1 = function (current, workInProgress, oldText, newText) {
16571 // If the text differs, mark it as an update. All the work in done in commitWork.
16572 if (oldText !== newText) {
16573 markUpdate(workInProgress);
16574 }
16575 };
16576} else if (supportsPersistence) {
16577 // Persistent host tree mode
16578
16579 appendAllChildren = function (parent, workInProgress, needsVisibilityToggle, isHidden) {
16580 // We only have the top Fiber that was created but we need recurse down its
16581 // children to find all the terminal nodes.
16582 var node = workInProgress.child;
16583 while (node !== null) {
16584 // eslint-disable-next-line no-labels
16585 branches: if (node.tag === HostComponent) {
16586 var instance = node.stateNode;
16587 if (needsVisibilityToggle) {
16588 var props = node.memoizedProps;
16589 var type = node.type;
16590 if (isHidden) {
16591 // This child is inside a timed out tree. Hide it.
16592 instance = cloneHiddenInstance(instance, type, props, node);
16593 } else {
16594 // This child was previously inside a timed out tree. If it was not
16595 // updated during this render, it may need to be unhidden. Clone
16596 // again to be sure.
16597 instance = cloneUnhiddenInstance(instance, type, props, node);
16598 }
16599 node.stateNode = instance;
16600 }
16601 appendInitialChild(parent, instance);
16602 } else if (node.tag === HostText) {
16603 var _instance = node.stateNode;
16604 if (needsVisibilityToggle) {
16605 var text = node.memoizedProps;
16606 var rootContainerInstance = getRootHostContainer();
16607 var currentHostContext = getHostContext();
16608 if (isHidden) {
16609 _instance = createHiddenTextInstance(text, rootContainerInstance, currentHostContext, workInProgress);
16610 } else {
16611 _instance = createTextInstance(text, rootContainerInstance, currentHostContext, workInProgress);
16612 }
16613 node.stateNode = _instance;
16614 }
16615 appendInitialChild(parent, _instance);
16616 } else if (node.tag === HostPortal) {
16617 // If we have a portal child, then we don't want to traverse
16618 // down its children. Instead, we'll get insertions from each child in
16619 // the portal directly.
16620 } else if (node.tag === SuspenseComponent) {
16621 var current = node.alternate;
16622 if (current !== null) {
16623 var oldState = current.memoizedState;
16624 var newState = node.memoizedState;
16625 var oldIsHidden = oldState !== null;
16626 var newIsHidden = newState !== null;
16627 if (oldIsHidden !== newIsHidden) {
16628 // The placeholder either just timed out or switched back to the normal
16629 // children after having previously timed out. Toggle the visibility of
16630 // the direct host children.
16631 var primaryChildParent = newIsHidden ? node.child : node;
16632 if (primaryChildParent !== null) {
16633 appendAllChildren(parent, primaryChildParent, true, newIsHidden);
16634 }
16635 // eslint-disable-next-line no-labels
16636 break branches;
16637 }
16638 }
16639 if (node.child !== null) {
16640 // Continue traversing like normal
16641 node.child.return = node;
16642 node = node.child;
16643 continue;
16644 }
16645 } else if (node.child !== null) {
16646 node.child.return = node;
16647 node = node.child;
16648 continue;
16649 }
16650 // $FlowFixMe This is correct but Flow is confused by the labeled break.
16651 node = node;
16652 if (node === workInProgress) {
16653 return;
16654 }
16655 while (node.sibling === null) {
16656 if (node.return === null || node.return === workInProgress) {
16657 return;
16658 }
16659 node = node.return;
16660 }
16661 node.sibling.return = node.return;
16662 node = node.sibling;
16663 }
16664 };
16665
16666 // An unfortunate fork of appendAllChildren because we have two different parent types.
16667 var appendAllChildrenToContainer = function (containerChildSet, workInProgress, needsVisibilityToggle, isHidden) {
16668 // We only have the top Fiber that was created but we need recurse down its
16669 // children to find all the terminal nodes.
16670 var node = workInProgress.child;
16671 while (node !== null) {
16672 // eslint-disable-next-line no-labels
16673 branches: if (node.tag === HostComponent) {
16674 var instance = node.stateNode;
16675 if (needsVisibilityToggle) {
16676 var props = node.memoizedProps;
16677 var type = node.type;
16678 if (isHidden) {
16679 // This child is inside a timed out tree. Hide it.
16680 instance = cloneHiddenInstance(instance, type, props, node);
16681 } else {
16682 // This child was previously inside a timed out tree. If it was not
16683 // updated during this render, it may need to be unhidden. Clone
16684 // again to be sure.
16685 instance = cloneUnhiddenInstance(instance, type, props, node);
16686 }
16687 node.stateNode = instance;
16688 }
16689 appendChildToContainerChildSet(containerChildSet, instance);
16690 } else if (node.tag === HostText) {
16691 var _instance2 = node.stateNode;
16692 if (needsVisibilityToggle) {
16693 var text = node.memoizedProps;
16694 var rootContainerInstance = getRootHostContainer();
16695 var currentHostContext = getHostContext();
16696 if (isHidden) {
16697 _instance2 = createHiddenTextInstance(text, rootContainerInstance, currentHostContext, workInProgress);
16698 } else {
16699 _instance2 = createTextInstance(text, rootContainerInstance, currentHostContext, workInProgress);
16700 }
16701 node.stateNode = _instance2;
16702 }
16703 appendChildToContainerChildSet(containerChildSet, _instance2);
16704 } else if (node.tag === HostPortal) {
16705 // If we have a portal child, then we don't want to traverse
16706 // down its children. Instead, we'll get insertions from each child in
16707 // the portal directly.
16708 } else if (node.tag === SuspenseComponent) {
16709 var current = node.alternate;
16710 if (current !== null) {
16711 var oldState = current.memoizedState;
16712 var newState = node.memoizedState;
16713 var oldIsHidden = oldState !== null;
16714 var newIsHidden = newState !== null;
16715 if (oldIsHidden !== newIsHidden) {
16716 // The placeholder either just timed out or switched back to the normal
16717 // children after having previously timed out. Toggle the visibility of
16718 // the direct host children.
16719 var primaryChildParent = newIsHidden ? node.child : node;
16720 if (primaryChildParent !== null) {
16721 appendAllChildrenToContainer(containerChildSet, primaryChildParent, true, newIsHidden);
16722 }
16723 // eslint-disable-next-line no-labels
16724 break branches;
16725 }
16726 }
16727 if (node.child !== null) {
16728 // Continue traversing like normal
16729 node.child.return = node;
16730 node = node.child;
16731 continue;
16732 }
16733 } else if (node.child !== null) {
16734 node.child.return = node;
16735 node = node.child;
16736 continue;
16737 }
16738 // $FlowFixMe This is correct but Flow is confused by the labeled break.
16739 node = node;
16740 if (node === workInProgress) {
16741 return;
16742 }
16743 while (node.sibling === null) {
16744 if (node.return === null || node.return === workInProgress) {
16745 return;
16746 }
16747 node = node.return;
16748 }
16749 node.sibling.return = node.return;
16750 node = node.sibling;
16751 }
16752 };
16753 updateHostContainer = function (workInProgress) {
16754 var portalOrRoot = workInProgress.stateNode;
16755 var childrenUnchanged = workInProgress.firstEffect === null;
16756 if (childrenUnchanged) {
16757 // No changes, just reuse the existing instance.
16758 } else {
16759 var container = portalOrRoot.containerInfo;
16760 var newChildSet = createContainerChildSet(container);
16761 // If children might have changed, we have to add them all to the set.
16762 appendAllChildrenToContainer(newChildSet, workInProgress, false, false);
16763 portalOrRoot.pendingChildren = newChildSet;
16764 // Schedule an update on the container to swap out the container.
16765 markUpdate(workInProgress);
16766 finalizeContainerChildren(container, newChildSet);
16767 }
16768 };
16769 updateHostComponent$1 = function (current, workInProgress, type, newProps, rootContainerInstance) {
16770 var currentInstance = current.stateNode;
16771 var oldProps = current.memoizedProps;
16772 // If there are no effects associated with this node, then none of our children had any updates.
16773 // This guarantees that we can reuse all of them.
16774 var childrenUnchanged = workInProgress.firstEffect === null;
16775 if (childrenUnchanged && oldProps === newProps) {
16776 // No changes, just reuse the existing instance.
16777 // Note that this might release a previous clone.
16778 workInProgress.stateNode = currentInstance;
16779 return;
16780 }
16781 var recyclableInstance = workInProgress.stateNode;
16782 var currentHostContext = getHostContext();
16783 var updatePayload = null;
16784 if (oldProps !== newProps) {
16785 updatePayload = prepareUpdate(recyclableInstance, type, oldProps, newProps, rootContainerInstance, currentHostContext);
16786 }
16787 if (childrenUnchanged && updatePayload === null) {
16788 // No changes, just reuse the existing instance.
16789 // Note that this might release a previous clone.
16790 workInProgress.stateNode = currentInstance;
16791 return;
16792 }
16793 var newInstance = cloneInstance(currentInstance, updatePayload, type, oldProps, newProps, workInProgress, childrenUnchanged, recyclableInstance);
16794 if (finalizeInitialChildren(newInstance, type, newProps, rootContainerInstance, currentHostContext)) {
16795 markUpdate(workInProgress);
16796 }
16797 workInProgress.stateNode = newInstance;
16798 if (childrenUnchanged) {
16799 // If there are no other effects in this tree, we need to flag this node as having one.
16800 // Even though we're not going to use it for anything.
16801 // Otherwise parents won't know that there are new children to propagate upwards.
16802 markUpdate(workInProgress);
16803 } else {
16804 // If children might have changed, we have to add them all to the set.
16805 appendAllChildren(newInstance, workInProgress, false, false);
16806 }
16807 };
16808 updateHostText$1 = function (current, workInProgress, oldText, newText) {
16809 if (oldText !== newText) {
16810 // If the text content differs, we'll create a new text instance for it.
16811 var rootContainerInstance = getRootHostContainer();
16812 var currentHostContext = getHostContext();
16813 workInProgress.stateNode = createTextInstance(newText, rootContainerInstance, currentHostContext, workInProgress);
16814 // We'll have to mark it as having an effect, even though we won't use the effect for anything.
16815 // This lets the parents know that at least one of their children has changed.
16816 markUpdate(workInProgress);
16817 }
16818 };
16819} else {
16820 // No host operations
16821 updateHostContainer = function (workInProgress) {
16822 // Noop
16823 };
16824 updateHostComponent$1 = function (current, workInProgress, type, newProps, rootContainerInstance) {
16825 // Noop
16826 };
16827 updateHostText$1 = function (current, workInProgress, oldText, newText) {
16828 // Noop
16829 };
16830}
16831
16832function completeWork(current, workInProgress, renderExpirationTime) {
16833 var newProps = workInProgress.pendingProps;
16834
16835 switch (workInProgress.tag) {
16836 case IndeterminateComponent:
16837 break;
16838 case LazyComponent:
16839 break;
16840 case SimpleMemoComponent:
16841 case FunctionComponent:
16842 break;
16843 case ClassComponent:
16844 {
16845 var Component = workInProgress.type;
16846 if (isContextProvider(Component)) {
16847 popContext(workInProgress);
16848 }
16849 break;
16850 }
16851 case HostRoot:
16852 {
16853 popHostContainer(workInProgress);
16854 popTopLevelContextObject(workInProgress);
16855 var fiberRoot = workInProgress.stateNode;
16856 if (fiberRoot.pendingContext) {
16857 fiberRoot.context = fiberRoot.pendingContext;
16858 fiberRoot.pendingContext = null;
16859 }
16860 if (current === null || current.child === null) {
16861 // If we hydrated, pop so that we can delete any remaining children
16862 // that weren't hydrated.
16863 popHydrationState(workInProgress);
16864 // This resets the hacky state to fix isMounted before committing.
16865 // TODO: Delete this when we delete isMounted and findDOMNode.
16866 workInProgress.effectTag &= ~Placement;
16867 }
16868 updateHostContainer(workInProgress);
16869 break;
16870 }
16871 case HostComponent:
16872 {
16873 popHostContext(workInProgress);
16874 var rootContainerInstance = getRootHostContainer();
16875 var type = workInProgress.type;
16876 if (current !== null && workInProgress.stateNode != null) {
16877 updateHostComponent$1(current, workInProgress, type, newProps, rootContainerInstance);
16878
16879 if (current.ref !== workInProgress.ref) {
16880 markRef$1(workInProgress);
16881 }
16882 } else {
16883 if (!newProps) {
16884 !(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;
16885 // This can happen when we abort work.
16886 break;
16887 }
16888
16889 var currentHostContext = getHostContext();
16890 // TODO: Move createInstance to beginWork and keep it on a context
16891 // "stack" as the parent. Then append children as we go in beginWork
16892 // or completeWork depending on we want to add then top->down or
16893 // bottom->up. Top->down is faster in IE11.
16894 var wasHydrated = popHydrationState(workInProgress);
16895 if (wasHydrated) {
16896 // TODO: Move this and createInstance step into the beginPhase
16897 // to consolidate.
16898 if (prepareToHydrateHostInstance(workInProgress, rootContainerInstance, currentHostContext)) {
16899 // If changes to the hydrated node needs to be applied at the
16900 // commit-phase we mark this as such.
16901 markUpdate(workInProgress);
16902 }
16903 } else {
16904 var instance = createInstance(type, newProps, rootContainerInstance, currentHostContext, workInProgress);
16905
16906 appendAllChildren(instance, workInProgress, false, false);
16907
16908 // Certain renderers require commit-time effects for initial mount.
16909 // (eg DOM renderer supports auto-focus for certain elements).
16910 // Make sure such renderers get scheduled for later work.
16911 if (finalizeInitialChildren(instance, type, newProps, rootContainerInstance, currentHostContext)) {
16912 markUpdate(workInProgress);
16913 }
16914 workInProgress.stateNode = instance;
16915 }
16916
16917 if (workInProgress.ref !== null) {
16918 // If there is a ref on a host node we need to schedule a callback
16919 markRef$1(workInProgress);
16920 }
16921 }
16922 break;
16923 }
16924 case HostText:
16925 {
16926 var newText = newProps;
16927 if (current && workInProgress.stateNode != null) {
16928 var oldText = current.memoizedProps;
16929 // If we have an alternate, that means this is an update and we need
16930 // to schedule a side-effect to do the updates.
16931 updateHostText$1(current, workInProgress, oldText, newText);
16932 } else {
16933 if (typeof newText !== 'string') {
16934 !(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;
16935 // This can happen when we abort work.
16936 }
16937 var _rootContainerInstance = getRootHostContainer();
16938 var _currentHostContext = getHostContext();
16939 var _wasHydrated = popHydrationState(workInProgress);
16940 if (_wasHydrated) {
16941 if (prepareToHydrateHostTextInstance(workInProgress)) {
16942 markUpdate(workInProgress);
16943 }
16944 } else {
16945 workInProgress.stateNode = createTextInstance(newText, _rootContainerInstance, _currentHostContext, workInProgress);
16946 }
16947 }
16948 break;
16949 }
16950 case ForwardRef:
16951 break;
16952 case SuspenseComponent:
16953 {
16954 var nextState = workInProgress.memoizedState;
16955 if ((workInProgress.effectTag & DidCapture) !== NoEffect) {
16956 // Something suspended. Re-render with the fallback children.
16957 workInProgress.expirationTime = renderExpirationTime;
16958 // Do not reset the effect list.
16959 return workInProgress;
16960 }
16961
16962 var nextDidTimeout = nextState !== null;
16963 var prevDidTimeout = current !== null && current.memoizedState !== null;
16964
16965 if (current !== null && !nextDidTimeout && prevDidTimeout) {
16966 // We just switched from the fallback to the normal children. Delete
16967 // the fallback.
16968 // TODO: Would it be better to store the fallback fragment on
16969 var currentFallbackChild = current.child.sibling;
16970 if (currentFallbackChild !== null) {
16971 // Deletions go at the beginning of the return fiber's effect list
16972 var first = workInProgress.firstEffect;
16973 if (first !== null) {
16974 workInProgress.firstEffect = currentFallbackChild;
16975 currentFallbackChild.nextEffect = first;
16976 } else {
16977 workInProgress.firstEffect = workInProgress.lastEffect = currentFallbackChild;
16978 currentFallbackChild.nextEffect = null;
16979 }
16980 currentFallbackChild.effectTag = Deletion;
16981 }
16982 }
16983
16984 if (nextDidTimeout || prevDidTimeout) {
16985 // If the children are hidden, or if they were previous hidden, schedule
16986 // an effect to toggle their visibility. This is also used to attach a
16987 // retry listener to the promise.
16988 workInProgress.effectTag |= Update;
16989 }
16990 break;
16991 }
16992 case Fragment:
16993 break;
16994 case Mode:
16995 break;
16996 case Profiler:
16997 break;
16998 case HostPortal:
16999 popHostContainer(workInProgress);
17000 updateHostContainer(workInProgress);
17001 break;
17002 case ContextProvider:
17003 // Pop provider fiber
17004 popProvider(workInProgress);
17005 break;
17006 case ContextConsumer:
17007 break;
17008 case MemoComponent:
17009 break;
17010 case IncompleteClassComponent:
17011 {
17012 // Same as class component case. I put it down here so that the tags are
17013 // sequential to ensure this switch is compiled to a jump table.
17014 var _Component = workInProgress.type;
17015 if (isContextProvider(_Component)) {
17016 popContext(workInProgress);
17017 }
17018 break;
17019 }
17020 case DehydratedSuspenseComponent:
17021 {
17022 if (enableSuspenseServerRenderer) {
17023 if (current === null) {
17024 var _wasHydrated2 = popHydrationState(workInProgress);
17025 !_wasHydrated2 ? invariant(false, 'A dehydrated suspense component was completed without a hydrated node. This is probably a bug in React.') : void 0;
17026 skipPastDehydratedSuspenseInstance(workInProgress);
17027 } else if ((workInProgress.effectTag & DidCapture) === NoEffect) {
17028 // This boundary did not suspend so it's now hydrated.
17029 // To handle any future suspense cases, we're going to now upgrade it
17030 // to a Suspense component. We detach it from the existing current fiber.
17031 current.alternate = null;
17032 workInProgress.alternate = null;
17033 workInProgress.tag = SuspenseComponent;
17034 workInProgress.memoizedState = null;
17035 workInProgress.stateNode = null;
17036 }
17037 }
17038 break;
17039 }
17040 default:
17041 invariant(false, 'Unknown unit of work tag. This error is likely caused by a bug in React. Please file an issue.');
17042 }
17043
17044 return null;
17045}
17046
17047function shouldCaptureSuspense(workInProgress) {
17048 // In order to capture, the Suspense component must have a fallback prop.
17049 if (workInProgress.memoizedProps.fallback === undefined) {
17050 return false;
17051 }
17052 // If it was the primary children that just suspended, capture and render the
17053 // fallback. Otherwise, don't capture and bubble to the next boundary.
17054 var nextState = workInProgress.memoizedState;
17055 return nextState === null;
17056}
17057
17058// This module is forked in different environments.
17059// By default, return `true` to log errors to the console.
17060// Forks can return `false` if this isn't desirable.
17061function showErrorDialog(capturedError) {
17062 return true;
17063}
17064
17065function logCapturedError(capturedError) {
17066 var logError = showErrorDialog(capturedError);
17067
17068 // Allow injected showErrorDialog() to prevent default console.error logging.
17069 // This enables renderers like ReactNative to better manage redbox behavior.
17070 if (logError === false) {
17071 return;
17072 }
17073
17074 var error = capturedError.error;
17075 {
17076 var componentName = capturedError.componentName,
17077 componentStack = capturedError.componentStack,
17078 errorBoundaryName = capturedError.errorBoundaryName,
17079 errorBoundaryFound = capturedError.errorBoundaryFound,
17080 willRetry = capturedError.willRetry;
17081
17082 // Browsers support silencing uncaught errors by calling
17083 // `preventDefault()` in window `error` handler.
17084 // We record this information as an expando on the error.
17085
17086 if (error != null && error._suppressLogging) {
17087 if (errorBoundaryFound && willRetry) {
17088 // The error is recoverable and was silenced.
17089 // Ignore it and don't print the stack addendum.
17090 // This is handy for testing error boundaries without noise.
17091 return;
17092 }
17093 // The error is fatal. Since the silencing might have
17094 // been accidental, we'll surface it anyway.
17095 // However, the browser would have silenced the original error
17096 // so we'll print it first, and then print the stack addendum.
17097 console.error(error);
17098 // For a more detailed description of this block, see:
17099 // https://github.com/facebook/react/pull/13384
17100 }
17101
17102 var componentNameMessage = componentName ? 'The above error occurred in the <' + componentName + '> component:' : 'The above error occurred in one of your React components:';
17103
17104 var errorBoundaryMessage = void 0;
17105 // errorBoundaryFound check is sufficient; errorBoundaryName check is to satisfy Flow.
17106 if (errorBoundaryFound && errorBoundaryName) {
17107 if (willRetry) {
17108 errorBoundaryMessage = 'React will try to recreate this component tree from scratch ' + ('using the error boundary you provided, ' + errorBoundaryName + '.');
17109 } else {
17110 errorBoundaryMessage = 'This error was initially handled by the error boundary ' + errorBoundaryName + '.\n' + 'Recreating the tree from scratch failed so React will unmount the tree.';
17111 }
17112 } else {
17113 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.';
17114 }
17115 var combinedMessage = '' + componentNameMessage + componentStack + '\n\n' + ('' + errorBoundaryMessage);
17116
17117 // In development, we provide our own message with just the component stack.
17118 // We don't include the original error message and JS stack because the browser
17119 // has already printed it. Even if the application swallows the error, it is still
17120 // displayed by the browser thanks to the DEV-only fake event trick in ReactErrorUtils.
17121 console.error(combinedMessage);
17122 }
17123}
17124
17125var didWarnAboutUndefinedSnapshotBeforeUpdate = null;
17126{
17127 didWarnAboutUndefinedSnapshotBeforeUpdate = new Set();
17128}
17129
17130var PossiblyWeakSet$1 = typeof WeakSet === 'function' ? WeakSet : Set;
17131
17132function logError(boundary, errorInfo) {
17133 var source = errorInfo.source;
17134 var stack = errorInfo.stack;
17135 if (stack === null && source !== null) {
17136 stack = getStackByFiberInDevAndProd(source);
17137 }
17138
17139 var capturedError = {
17140 componentName: source !== null ? getComponentName(source.type) : null,
17141 componentStack: stack !== null ? stack : '',
17142 error: errorInfo.value,
17143 errorBoundary: null,
17144 errorBoundaryName: null,
17145 errorBoundaryFound: false,
17146 willRetry: false
17147 };
17148
17149 if (boundary !== null && boundary.tag === ClassComponent) {
17150 capturedError.errorBoundary = boundary.stateNode;
17151 capturedError.errorBoundaryName = getComponentName(boundary.type);
17152 capturedError.errorBoundaryFound = true;
17153 capturedError.willRetry = true;
17154 }
17155
17156 try {
17157 logCapturedError(capturedError);
17158 } catch (e) {
17159 // This method must not throw, or React internal state will get messed up.
17160 // If console.error is overridden, or logCapturedError() shows a dialog that throws,
17161 // we want to report this error outside of the normal stack as a last resort.
17162 // https://github.com/facebook/react/issues/13188
17163 setTimeout(function () {
17164 throw e;
17165 });
17166 }
17167}
17168
17169var callComponentWillUnmountWithTimer = function (current$$1, instance) {
17170 startPhaseTimer(current$$1, 'componentWillUnmount');
17171 instance.props = current$$1.memoizedProps;
17172 instance.state = current$$1.memoizedState;
17173 instance.componentWillUnmount();
17174 stopPhaseTimer();
17175};
17176
17177// Capture errors so they don't interrupt unmounting.
17178function safelyCallComponentWillUnmount(current$$1, instance) {
17179 {
17180 invokeGuardedCallback(null, callComponentWillUnmountWithTimer, null, current$$1, instance);
17181 if (hasCaughtError()) {
17182 var unmountError = clearCaughtError();
17183 captureCommitPhaseError(current$$1, unmountError);
17184 }
17185 }
17186}
17187
17188function safelyDetachRef(current$$1) {
17189 var ref = current$$1.ref;
17190 if (ref !== null) {
17191 if (typeof ref === 'function') {
17192 {
17193 invokeGuardedCallback(null, ref, null, null);
17194 if (hasCaughtError()) {
17195 var refError = clearCaughtError();
17196 captureCommitPhaseError(current$$1, refError);
17197 }
17198 }
17199 } else {
17200 ref.current = null;
17201 }
17202 }
17203}
17204
17205function safelyCallDestroy(current$$1, destroy) {
17206 {
17207 invokeGuardedCallback(null, destroy, null);
17208 if (hasCaughtError()) {
17209 var error = clearCaughtError();
17210 captureCommitPhaseError(current$$1, error);
17211 }
17212 }
17213}
17214
17215function commitBeforeMutationLifeCycles(current$$1, finishedWork) {
17216 switch (finishedWork.tag) {
17217 case FunctionComponent:
17218 case ForwardRef:
17219 case SimpleMemoComponent:
17220 {
17221 commitHookEffectList(UnmountSnapshot, NoEffect$1, finishedWork);
17222 return;
17223 }
17224 case ClassComponent:
17225 {
17226 if (finishedWork.effectTag & Snapshot) {
17227 if (current$$1 !== null) {
17228 var prevProps = current$$1.memoizedProps;
17229 var prevState = current$$1.memoizedState;
17230 startPhaseTimer(finishedWork, 'getSnapshotBeforeUpdate');
17231 var instance = finishedWork.stateNode;
17232 // We could update instance props and state here,
17233 // but instead we rely on them being set during last render.
17234 // TODO: revisit this when we implement resuming.
17235 {
17236 if (finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps) {
17237 !(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;
17238 !(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;
17239 }
17240 }
17241 var snapshot = instance.getSnapshotBeforeUpdate(finishedWork.elementType === finishedWork.type ? prevProps : resolveDefaultProps(finishedWork.type, prevProps), prevState);
17242 {
17243 var didWarnSet = didWarnAboutUndefinedSnapshotBeforeUpdate;
17244 if (snapshot === undefined && !didWarnSet.has(finishedWork.type)) {
17245 didWarnSet.add(finishedWork.type);
17246 warningWithoutStack$1(false, '%s.getSnapshotBeforeUpdate(): A snapshot value (or null) ' + 'must be returned. You have returned undefined.', getComponentName(finishedWork.type));
17247 }
17248 }
17249 instance.__reactInternalSnapshotBeforeUpdate = snapshot;
17250 stopPhaseTimer();
17251 }
17252 }
17253 return;
17254 }
17255 case HostRoot:
17256 case HostComponent:
17257 case HostText:
17258 case HostPortal:
17259 case IncompleteClassComponent:
17260 // Nothing to do for these component types
17261 return;
17262 default:
17263 {
17264 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.');
17265 }
17266 }
17267}
17268
17269function commitHookEffectList(unmountTag, mountTag, finishedWork) {
17270 var updateQueue = finishedWork.updateQueue;
17271 var lastEffect = updateQueue !== null ? updateQueue.lastEffect : null;
17272 if (lastEffect !== null) {
17273 var firstEffect = lastEffect.next;
17274 var effect = firstEffect;
17275 do {
17276 if ((effect.tag & unmountTag) !== NoEffect$1) {
17277 // Unmount
17278 var destroy = effect.destroy;
17279 effect.destroy = undefined;
17280 if (destroy !== undefined) {
17281 destroy();
17282 }
17283 }
17284 if ((effect.tag & mountTag) !== NoEffect$1) {
17285 // Mount
17286 var create = effect.create;
17287 effect.destroy = create();
17288
17289 {
17290 var _destroy = effect.destroy;
17291 if (_destroy !== undefined && typeof _destroy !== 'function') {
17292 var addendum = void 0;
17293 if (_destroy === null) {
17294 addendum = ' You returned null. If your effect does not require clean ' + 'up, return undefined (or nothing).';
17295 } else if (typeof _destroy.then === 'function') {
17296 addendum = '\n\nIt looks like you wrote useEffect(async () => ...) or returned a Promise. ' + 'Instead, write the async function inside your effect ' + 'and call it immediately:\n\n' + 'useEffect(() => {\n' + ' async function fetchData() {\n' + ' // You can await here\n' + ' const response = await MyAPI.getData(someId);\n' + ' // ...\n' + ' }\n' + ' fetchData();\n' + '}, [someId]); // Or [] if effect doesn\'t need props or state\n\n' + 'Learn more about data fetching with Hooks: https://fb.me/react-hooks-data-fetching';
17297 } else {
17298 addendum = ' You returned: ' + _destroy;
17299 }
17300 warningWithoutStack$1(false, 'An effect function must not return anything besides a function, ' + 'which is used for clean-up.%s%s', addendum, getStackByFiberInDevAndProd(finishedWork));
17301 }
17302 }
17303 }
17304 effect = effect.next;
17305 } while (effect !== firstEffect);
17306 }
17307}
17308
17309function commitPassiveHookEffects(finishedWork) {
17310 commitHookEffectList(UnmountPassive, NoEffect$1, finishedWork);
17311 commitHookEffectList(NoEffect$1, MountPassive, finishedWork);
17312}
17313
17314function commitLifeCycles(finishedRoot, current$$1, finishedWork, committedExpirationTime) {
17315 switch (finishedWork.tag) {
17316 case FunctionComponent:
17317 case ForwardRef:
17318 case SimpleMemoComponent:
17319 {
17320 commitHookEffectList(UnmountLayout, MountLayout, finishedWork);
17321 break;
17322 }
17323 case ClassComponent:
17324 {
17325 var instance = finishedWork.stateNode;
17326 if (finishedWork.effectTag & Update) {
17327 if (current$$1 === null) {
17328 startPhaseTimer(finishedWork, 'componentDidMount');
17329 // We could update instance props and state here,
17330 // but instead we rely on them being set during last render.
17331 // TODO: revisit this when we implement resuming.
17332 {
17333 if (finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps) {
17334 !(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;
17335 !(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;
17336 }
17337 }
17338 instance.componentDidMount();
17339 stopPhaseTimer();
17340 } else {
17341 var prevProps = finishedWork.elementType === finishedWork.type ? current$$1.memoizedProps : resolveDefaultProps(finishedWork.type, current$$1.memoizedProps);
17342 var prevState = current$$1.memoizedState;
17343 startPhaseTimer(finishedWork, 'componentDidUpdate');
17344 // We could update instance props and state here,
17345 // but instead we rely on them being set during last render.
17346 // TODO: revisit this when we implement resuming.
17347 {
17348 if (finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps) {
17349 !(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;
17350 !(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;
17351 }
17352 }
17353 instance.componentDidUpdate(prevProps, prevState, instance.__reactInternalSnapshotBeforeUpdate);
17354 stopPhaseTimer();
17355 }
17356 }
17357 var updateQueue = finishedWork.updateQueue;
17358 if (updateQueue !== null) {
17359 {
17360 if (finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps) {
17361 !(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;
17362 !(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;
17363 }
17364 }
17365 // We could update instance props and state here,
17366 // but instead we rely on them being set during last render.
17367 // TODO: revisit this when we implement resuming.
17368 commitUpdateQueue(finishedWork, updateQueue, instance, committedExpirationTime);
17369 }
17370 return;
17371 }
17372 case HostRoot:
17373 {
17374 var _updateQueue = finishedWork.updateQueue;
17375 if (_updateQueue !== null) {
17376 var _instance = null;
17377 if (finishedWork.child !== null) {
17378 switch (finishedWork.child.tag) {
17379 case HostComponent:
17380 _instance = getPublicInstance(finishedWork.child.stateNode);
17381 break;
17382 case ClassComponent:
17383 _instance = finishedWork.child.stateNode;
17384 break;
17385 }
17386 }
17387 commitUpdateQueue(finishedWork, _updateQueue, _instance, committedExpirationTime);
17388 }
17389 return;
17390 }
17391 case HostComponent:
17392 {
17393 var _instance2 = finishedWork.stateNode;
17394
17395 // Renderers may schedule work to be done after host components are mounted
17396 // (eg DOM renderer may schedule auto-focus for inputs and form controls).
17397 // These effects should only be committed when components are first mounted,
17398 // aka when there is no current/alternate.
17399 if (current$$1 === null && finishedWork.effectTag & Update) {
17400 var type = finishedWork.type;
17401 var props = finishedWork.memoizedProps;
17402 commitMount(_instance2, type, props, finishedWork);
17403 }
17404
17405 return;
17406 }
17407 case HostText:
17408 {
17409 // We have no life-cycles associated with text.
17410 return;
17411 }
17412 case HostPortal:
17413 {
17414 // We have no life-cycles associated with portals.
17415 return;
17416 }
17417 case Profiler:
17418 {
17419 if (enableProfilerTimer) {
17420 var onRender = finishedWork.memoizedProps.onRender;
17421
17422 if (enableSchedulerTracing) {
17423 onRender(finishedWork.memoizedProps.id, current$$1 === null ? 'mount' : 'update', finishedWork.actualDuration, finishedWork.treeBaseDuration, finishedWork.actualStartTime, getCommitTime(), finishedRoot.memoizedInteractions);
17424 } else {
17425 onRender(finishedWork.memoizedProps.id, current$$1 === null ? 'mount' : 'update', finishedWork.actualDuration, finishedWork.treeBaseDuration, finishedWork.actualStartTime, getCommitTime());
17426 }
17427 }
17428 return;
17429 }
17430 case SuspenseComponent:
17431 break;
17432 case IncompleteClassComponent:
17433 break;
17434 default:
17435 {
17436 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.');
17437 }
17438 }
17439}
17440
17441function hideOrUnhideAllChildren(finishedWork, isHidden) {
17442 if (supportsMutation) {
17443 // We only have the top Fiber that was inserted but we need to recurse down its
17444 var node = finishedWork;
17445 while (true) {
17446 if (node.tag === HostComponent) {
17447 var instance = node.stateNode;
17448 if (isHidden) {
17449 hideInstance(instance);
17450 } else {
17451 unhideInstance(node.stateNode, node.memoizedProps);
17452 }
17453 } else if (node.tag === HostText) {
17454 var _instance3 = node.stateNode;
17455 if (isHidden) {
17456 hideTextInstance(_instance3);
17457 } else {
17458 unhideTextInstance(_instance3, node.memoizedProps);
17459 }
17460 } else if (node.tag === SuspenseComponent && node.memoizedState !== null) {
17461 // Found a nested Suspense component that timed out. Skip over the
17462 var fallbackChildFragment = node.child.sibling;
17463 fallbackChildFragment.return = node;
17464 node = fallbackChildFragment;
17465 continue;
17466 } else if (node.child !== null) {
17467 node.child.return = node;
17468 node = node.child;
17469 continue;
17470 }
17471 if (node === finishedWork) {
17472 return;
17473 }
17474 while (node.sibling === null) {
17475 if (node.return === null || node.return === finishedWork) {
17476 return;
17477 }
17478 node = node.return;
17479 }
17480 node.sibling.return = node.return;
17481 node = node.sibling;
17482 }
17483 }
17484}
17485
17486function commitAttachRef(finishedWork) {
17487 var ref = finishedWork.ref;
17488 if (ref !== null) {
17489 var instance = finishedWork.stateNode;
17490 var instanceToUse = void 0;
17491 switch (finishedWork.tag) {
17492 case HostComponent:
17493 instanceToUse = getPublicInstance(instance);
17494 break;
17495 default:
17496 instanceToUse = instance;
17497 }
17498 if (typeof ref === 'function') {
17499 ref(instanceToUse);
17500 } else {
17501 {
17502 if (!ref.hasOwnProperty('current')) {
17503 warningWithoutStack$1(false, 'Unexpected ref object provided for %s. ' + 'Use either a ref-setter function or React.createRef().%s', getComponentName(finishedWork.type), getStackByFiberInDevAndProd(finishedWork));
17504 }
17505 }
17506
17507 ref.current = instanceToUse;
17508 }
17509 }
17510}
17511
17512function commitDetachRef(current$$1) {
17513 var currentRef = current$$1.ref;
17514 if (currentRef !== null) {
17515 if (typeof currentRef === 'function') {
17516 currentRef(null);
17517 } else {
17518 currentRef.current = null;
17519 }
17520 }
17521}
17522
17523// User-originating errors (lifecycles and refs) should not interrupt
17524// deletion, so don't let them throw. Host-originating errors should
17525// interrupt deletion, so it's okay
17526function commitUnmount(current$$1) {
17527 onCommitUnmount(current$$1);
17528
17529 switch (current$$1.tag) {
17530 case FunctionComponent:
17531 case ForwardRef:
17532 case MemoComponent:
17533 case SimpleMemoComponent:
17534 {
17535 var updateQueue = current$$1.updateQueue;
17536 if (updateQueue !== null) {
17537 var lastEffect = updateQueue.lastEffect;
17538 if (lastEffect !== null) {
17539 var firstEffect = lastEffect.next;
17540 var effect = firstEffect;
17541 do {
17542 var destroy = effect.destroy;
17543 if (destroy !== undefined) {
17544 safelyCallDestroy(current$$1, destroy);
17545 }
17546 effect = effect.next;
17547 } while (effect !== firstEffect);
17548 }
17549 }
17550 break;
17551 }
17552 case ClassComponent:
17553 {
17554 safelyDetachRef(current$$1);
17555 var instance = current$$1.stateNode;
17556 if (typeof instance.componentWillUnmount === 'function') {
17557 safelyCallComponentWillUnmount(current$$1, instance);
17558 }
17559 return;
17560 }
17561 case HostComponent:
17562 {
17563 safelyDetachRef(current$$1);
17564 return;
17565 }
17566 case HostPortal:
17567 {
17568 // TODO: this is recursive.
17569 // We are also not using this parent because
17570 // the portal will get pushed immediately.
17571 if (supportsMutation) {
17572 unmountHostComponents(current$$1);
17573 } else if (supportsPersistence) {
17574 emptyPortalContainer(current$$1);
17575 }
17576 return;
17577 }
17578 }
17579}
17580
17581function commitNestedUnmounts(root) {
17582 // While we're inside a removed host node we don't want to call
17583 // removeChild on the inner nodes because they're removed by the top
17584 // call anyway. We also want to call componentWillUnmount on all
17585 // composites before this host node is removed from the tree. Therefore
17586 var node = root;
17587 while (true) {
17588 commitUnmount(node);
17589 // Visit children because they may contain more composite or host nodes.
17590 // Skip portals because commitUnmount() currently visits them recursively.
17591 if (node.child !== null && (
17592 // If we use mutation we drill down into portals using commitUnmount above.
17593 // If we don't use mutation we drill down into portals here instead.
17594 !supportsMutation || node.tag !== HostPortal)) {
17595 node.child.return = node;
17596 node = node.child;
17597 continue;
17598 }
17599 if (node === root) {
17600 return;
17601 }
17602 while (node.sibling === null) {
17603 if (node.return === null || node.return === root) {
17604 return;
17605 }
17606 node = node.return;
17607 }
17608 node.sibling.return = node.return;
17609 node = node.sibling;
17610 }
17611}
17612
17613function detachFiber(current$$1) {
17614 // Cut off the return pointers to disconnect it from the tree. Ideally, we
17615 // should clear the child pointer of the parent alternate to let this
17616 // get GC:ed but we don't know which for sure which parent is the current
17617 // one so we'll settle for GC:ing the subtree of this child. This child
17618 // itself will be GC:ed when the parent updates the next time.
17619 current$$1.return = null;
17620 current$$1.child = null;
17621 current$$1.memoizedState = null;
17622 current$$1.updateQueue = null;
17623 var alternate = current$$1.alternate;
17624 if (alternate !== null) {
17625 alternate.return = null;
17626 alternate.child = null;
17627 alternate.memoizedState = null;
17628 alternate.updateQueue = null;
17629 }
17630}
17631
17632function emptyPortalContainer(current$$1) {
17633 if (!supportsPersistence) {
17634 return;
17635 }
17636
17637 var portal = current$$1.stateNode;
17638 var containerInfo = portal.containerInfo;
17639
17640 var emptyChildSet = createContainerChildSet(containerInfo);
17641 replaceContainerChildren(containerInfo, emptyChildSet);
17642}
17643
17644function commitContainer(finishedWork) {
17645 if (!supportsPersistence) {
17646 return;
17647 }
17648
17649 switch (finishedWork.tag) {
17650 case ClassComponent:
17651 {
17652 return;
17653 }
17654 case HostComponent:
17655 {
17656 return;
17657 }
17658 case HostText:
17659 {
17660 return;
17661 }
17662 case HostRoot:
17663 case HostPortal:
17664 {
17665 var portalOrRoot = finishedWork.stateNode;
17666 var containerInfo = portalOrRoot.containerInfo,
17667 _pendingChildren = portalOrRoot.pendingChildren;
17668
17669 replaceContainerChildren(containerInfo, _pendingChildren);
17670 return;
17671 }
17672 default:
17673 {
17674 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.');
17675 }
17676 }
17677}
17678
17679function getHostParentFiber(fiber) {
17680 var parent = fiber.return;
17681 while (parent !== null) {
17682 if (isHostParent(parent)) {
17683 return parent;
17684 }
17685 parent = parent.return;
17686 }
17687 invariant(false, 'Expected to find a host parent. This error is likely caused by a bug in React. Please file an issue.');
17688}
17689
17690function isHostParent(fiber) {
17691 return fiber.tag === HostComponent || fiber.tag === HostRoot || fiber.tag === HostPortal;
17692}
17693
17694function getHostSibling(fiber) {
17695 // We're going to search forward into the tree until we find a sibling host
17696 // node. Unfortunately, if multiple insertions are done in a row we have to
17697 // search past them. This leads to exponential search for the next sibling.
17698 var node = fiber;
17699 siblings: while (true) {
17700 // If we didn't find anything, let's try the next sibling.
17701 while (node.sibling === null) {
17702 if (node.return === null || isHostParent(node.return)) {
17703 // If we pop out of the root or hit the parent the fiber we are the
17704 // last sibling.
17705 return null;
17706 }
17707 node = node.return;
17708 }
17709 node.sibling.return = node.return;
17710 node = node.sibling;
17711 while (node.tag !== HostComponent && node.tag !== HostText && node.tag !== DehydratedSuspenseComponent) {
17712 // If it is not host node and, we might have a host node inside it.
17713 // Try to search down until we find one.
17714 if (node.effectTag & Placement) {
17715 // If we don't have a child, try the siblings instead.
17716 continue siblings;
17717 }
17718 // If we don't have a child, try the siblings instead.
17719 // We also skip portals because they are not part of this host tree.
17720 if (node.child === null || node.tag === HostPortal) {
17721 continue siblings;
17722 } else {
17723 node.child.return = node;
17724 node = node.child;
17725 }
17726 }
17727 // Check if this host node is stable or about to be placed.
17728 if (!(node.effectTag & Placement)) {
17729 // Found it!
17730 return node.stateNode;
17731 }
17732 }
17733}
17734
17735function commitPlacement(finishedWork) {
17736 if (!supportsMutation) {
17737 return;
17738 }
17739
17740 // Recursively insert all host nodes into the parent.
17741 var parentFiber = getHostParentFiber(finishedWork);
17742
17743 // Note: these two variables *must* always be updated together.
17744 var parent = void 0;
17745 var isContainer = void 0;
17746
17747 switch (parentFiber.tag) {
17748 case HostComponent:
17749 parent = parentFiber.stateNode;
17750 isContainer = false;
17751 break;
17752 case HostRoot:
17753 parent = parentFiber.stateNode.containerInfo;
17754 isContainer = true;
17755 break;
17756 case HostPortal:
17757 parent = parentFiber.stateNode.containerInfo;
17758 isContainer = true;
17759 break;
17760 default:
17761 invariant(false, 'Invalid host parent fiber. This error is likely caused by a bug in React. Please file an issue.');
17762 }
17763 if (parentFiber.effectTag & ContentReset) {
17764 // Reset the text content of the parent before doing any insertions
17765 resetTextContent(parent);
17766 // Clear ContentReset from the effect tag
17767 parentFiber.effectTag &= ~ContentReset;
17768 }
17769
17770 var before = getHostSibling(finishedWork);
17771 // We only have the top Fiber that was inserted but we need to recurse down its
17772 // children to find all the terminal nodes.
17773 var node = finishedWork;
17774 while (true) {
17775 if (node.tag === HostComponent || node.tag === HostText) {
17776 if (before) {
17777 if (isContainer) {
17778 insertInContainerBefore(parent, node.stateNode, before);
17779 } else {
17780 insertBefore(parent, node.stateNode, before);
17781 }
17782 } else {
17783 if (isContainer) {
17784 appendChildToContainer(parent, node.stateNode);
17785 } else {
17786 appendChild(parent, node.stateNode);
17787 }
17788 }
17789 } else if (node.tag === HostPortal) {
17790 // If the insertion itself is a portal, then we don't want to traverse
17791 // down its children. Instead, we'll get insertions from each child in
17792 // the portal directly.
17793 } else if (node.child !== null) {
17794 node.child.return = node;
17795 node = node.child;
17796 continue;
17797 }
17798 if (node === finishedWork) {
17799 return;
17800 }
17801 while (node.sibling === null) {
17802 if (node.return === null || node.return === finishedWork) {
17803 return;
17804 }
17805 node = node.return;
17806 }
17807 node.sibling.return = node.return;
17808 node = node.sibling;
17809 }
17810}
17811
17812function unmountHostComponents(current$$1) {
17813 // We only have the top Fiber that was deleted but we need to recurse down its
17814 var node = current$$1;
17815
17816 // Each iteration, currentParent is populated with node's host parent if not
17817 // currentParentIsValid.
17818 var currentParentIsValid = false;
17819
17820 // Note: these two variables *must* always be updated together.
17821 var currentParent = void 0;
17822 var currentParentIsContainer = void 0;
17823
17824 while (true) {
17825 if (!currentParentIsValid) {
17826 var parent = node.return;
17827 findParent: while (true) {
17828 !(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;
17829 switch (parent.tag) {
17830 case HostComponent:
17831 currentParent = parent.stateNode;
17832 currentParentIsContainer = false;
17833 break findParent;
17834 case HostRoot:
17835 currentParent = parent.stateNode.containerInfo;
17836 currentParentIsContainer = true;
17837 break findParent;
17838 case HostPortal:
17839 currentParent = parent.stateNode.containerInfo;
17840 currentParentIsContainer = true;
17841 break findParent;
17842 }
17843 parent = parent.return;
17844 }
17845 currentParentIsValid = true;
17846 }
17847
17848 if (node.tag === HostComponent || node.tag === HostText) {
17849 commitNestedUnmounts(node);
17850 // After all the children have unmounted, it is now safe to remove the
17851 // node from the tree.
17852 if (currentParentIsContainer) {
17853 removeChildFromContainer(currentParent, node.stateNode);
17854 } else {
17855 removeChild(currentParent, node.stateNode);
17856 }
17857 // Don't visit children because we already visited them.
17858 } else if (enableSuspenseServerRenderer && node.tag === DehydratedSuspenseComponent) {
17859 // Delete the dehydrated suspense boundary and all of its content.
17860 if (currentParentIsContainer) {
17861 clearSuspenseBoundaryFromContainer(currentParent, node.stateNode);
17862 } else {
17863 clearSuspenseBoundary(currentParent, node.stateNode);
17864 }
17865 } else if (node.tag === HostPortal) {
17866 if (node.child !== null) {
17867 // When we go into a portal, it becomes the parent to remove from.
17868 // We will reassign it back when we pop the portal on the way up.
17869 currentParent = node.stateNode.containerInfo;
17870 currentParentIsContainer = true;
17871 // Visit children because portals might contain host components.
17872 node.child.return = node;
17873 node = node.child;
17874 continue;
17875 }
17876 } else {
17877 commitUnmount(node);
17878 // Visit children because we may find more host components below.
17879 if (node.child !== null) {
17880 node.child.return = node;
17881 node = node.child;
17882 continue;
17883 }
17884 }
17885 if (node === current$$1) {
17886 return;
17887 }
17888 while (node.sibling === null) {
17889 if (node.return === null || node.return === current$$1) {
17890 return;
17891 }
17892 node = node.return;
17893 if (node.tag === HostPortal) {
17894 // When we go out of the portal, we need to restore the parent.
17895 // Since we don't keep a stack of them, we will search for it.
17896 currentParentIsValid = false;
17897 }
17898 }
17899 node.sibling.return = node.return;
17900 node = node.sibling;
17901 }
17902}
17903
17904function commitDeletion(current$$1) {
17905 if (supportsMutation) {
17906 // Recursively delete all host nodes from the parent.
17907 // Detach refs and call componentWillUnmount() on the whole subtree.
17908 unmountHostComponents(current$$1);
17909 } else {
17910 // Detach refs and call componentWillUnmount() on the whole subtree.
17911 commitNestedUnmounts(current$$1);
17912 }
17913 detachFiber(current$$1);
17914}
17915
17916function commitWork(current$$1, finishedWork) {
17917 if (!supportsMutation) {
17918 switch (finishedWork.tag) {
17919 case FunctionComponent:
17920 case ForwardRef:
17921 case MemoComponent:
17922 case SimpleMemoComponent:
17923 {
17924 // Note: We currently never use MountMutation, but useLayout uses
17925 // UnmountMutation.
17926 commitHookEffectList(UnmountMutation, MountMutation, finishedWork);
17927 return;
17928 }
17929 }
17930
17931 commitContainer(finishedWork);
17932 return;
17933 }
17934
17935 switch (finishedWork.tag) {
17936 case FunctionComponent:
17937 case ForwardRef:
17938 case MemoComponent:
17939 case SimpleMemoComponent:
17940 {
17941 // Note: We currently never use MountMutation, but useLayout uses
17942 // UnmountMutation.
17943 commitHookEffectList(UnmountMutation, MountMutation, finishedWork);
17944 return;
17945 }
17946 case ClassComponent:
17947 {
17948 return;
17949 }
17950 case HostComponent:
17951 {
17952 var instance = finishedWork.stateNode;
17953 if (instance != null) {
17954 // Commit the work prepared earlier.
17955 var newProps = finishedWork.memoizedProps;
17956 // For hydration we reuse the update path but we treat the oldProps
17957 // as the newProps. The updatePayload will contain the real change in
17958 // this case.
17959 var oldProps = current$$1 !== null ? current$$1.memoizedProps : newProps;
17960 var type = finishedWork.type;
17961 // TODO: Type the updateQueue to be specific to host components.
17962 var updatePayload = finishedWork.updateQueue;
17963 finishedWork.updateQueue = null;
17964 if (updatePayload !== null) {
17965 commitUpdate(instance, updatePayload, type, oldProps, newProps, finishedWork);
17966 }
17967 }
17968 return;
17969 }
17970 case HostText:
17971 {
17972 !(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;
17973 var textInstance = finishedWork.stateNode;
17974 var newText = finishedWork.memoizedProps;
17975 // For hydration we reuse the update path but we treat the oldProps
17976 // as the newProps. The updatePayload will contain the real change in
17977 // this case.
17978 var oldText = current$$1 !== null ? current$$1.memoizedProps : newText;
17979 commitTextUpdate(textInstance, oldText, newText);
17980 return;
17981 }
17982 case HostRoot:
17983 {
17984 return;
17985 }
17986 case Profiler:
17987 {
17988 return;
17989 }
17990 case SuspenseComponent:
17991 {
17992 var newState = finishedWork.memoizedState;
17993
17994 var newDidTimeout = void 0;
17995 var primaryChildParent = finishedWork;
17996 if (newState === null) {
17997 newDidTimeout = false;
17998 } else {
17999 newDidTimeout = true;
18000 primaryChildParent = finishedWork.child;
18001 if (newState.timedOutAt === NoWork) {
18002 // If the children had not already timed out, record the time.
18003 // This is used to compute the elapsed time during subsequent
18004 // attempts to render the children.
18005 newState.timedOutAt = requestCurrentTime();
18006 }
18007 }
18008
18009 if (primaryChildParent !== null) {
18010 hideOrUnhideAllChildren(primaryChildParent, newDidTimeout);
18011 }
18012
18013 // If this boundary just timed out, then it will have a set of thenables.
18014 // For each thenable, attach a listener so that when it resolves, React
18015 // attempts to re-render the boundary in the primary (pre-timeout) state.
18016 var thenables = finishedWork.updateQueue;
18017 if (thenables !== null) {
18018 finishedWork.updateQueue = null;
18019 var retryCache = finishedWork.stateNode;
18020 if (retryCache === null) {
18021 retryCache = finishedWork.stateNode = new PossiblyWeakSet$1();
18022 }
18023 thenables.forEach(function (thenable) {
18024 // Memoize using the boundary fiber to prevent redundant listeners.
18025 var retry = retryTimedOutBoundary.bind(null, finishedWork, thenable);
18026 if (enableSchedulerTracing) {
18027 retry = tracing.unstable_wrap(retry);
18028 }
18029 if (!retryCache.has(thenable)) {
18030 retryCache.add(thenable);
18031 thenable.then(retry, retry);
18032 }
18033 });
18034 }
18035
18036 return;
18037 }
18038 case IncompleteClassComponent:
18039 {
18040 return;
18041 }
18042 default:
18043 {
18044 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.');
18045 }
18046 }
18047}
18048
18049function commitResetTextContent(current$$1) {
18050 if (!supportsMutation) {
18051 return;
18052 }
18053 resetTextContent(current$$1.stateNode);
18054}
18055
18056var PossiblyWeakSet = typeof WeakSet === 'function' ? WeakSet : Set;
18057var PossiblyWeakMap = typeof WeakMap === 'function' ? WeakMap : Map;
18058
18059function createRootErrorUpdate(fiber, errorInfo, expirationTime) {
18060 var update = createUpdate(expirationTime);
18061 // Unmount the root by rendering null.
18062 update.tag = CaptureUpdate;
18063 // Caution: React DevTools currently depends on this property
18064 // being called "element".
18065 update.payload = { element: null };
18066 var error = errorInfo.value;
18067 update.callback = function () {
18068 onUncaughtError(error);
18069 logError(fiber, errorInfo);
18070 };
18071 return update;
18072}
18073
18074function createClassErrorUpdate(fiber, errorInfo, expirationTime) {
18075 var update = createUpdate(expirationTime);
18076 update.tag = CaptureUpdate;
18077 var getDerivedStateFromError = fiber.type.getDerivedStateFromError;
18078 if (typeof getDerivedStateFromError === 'function') {
18079 var error = errorInfo.value;
18080 update.payload = function () {
18081 return getDerivedStateFromError(error);
18082 };
18083 }
18084
18085 var inst = fiber.stateNode;
18086 if (inst !== null && typeof inst.componentDidCatch === 'function') {
18087 update.callback = function callback() {
18088 if (typeof getDerivedStateFromError !== 'function') {
18089 // To preserve the preexisting retry behavior of error boundaries,
18090 // we keep track of which ones already failed during this batch.
18091 // This gets reset before we yield back to the browser.
18092 // TODO: Warn in strict mode if getDerivedStateFromError is
18093 // not defined.
18094 markLegacyErrorBoundaryAsFailed(this);
18095 }
18096 var error = errorInfo.value;
18097 var stack = errorInfo.stack;
18098 logError(fiber, errorInfo);
18099 this.componentDidCatch(error, {
18100 componentStack: stack !== null ? stack : ''
18101 });
18102 {
18103 if (typeof getDerivedStateFromError !== 'function') {
18104 // If componentDidCatch is the only error boundary method defined,
18105 // then it needs to call setState to recover from errors.
18106 // If no state update is scheduled then the boundary will swallow the error.
18107 !(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;
18108 }
18109 }
18110 };
18111 }
18112 return update;
18113}
18114
18115function attachPingListener(root, renderExpirationTime, thenable) {
18116 // Attach a listener to the promise to "ping" the root and retry. But
18117 // only if one does not already exist for the current render expiration
18118 // time (which acts like a "thread ID" here).
18119 var pingCache = root.pingCache;
18120 var threadIDs = void 0;
18121 if (pingCache === null) {
18122 pingCache = root.pingCache = new PossiblyWeakMap();
18123 threadIDs = new Set();
18124 pingCache.set(thenable, threadIDs);
18125 } else {
18126 threadIDs = pingCache.get(thenable);
18127 if (threadIDs === undefined) {
18128 threadIDs = new Set();
18129 pingCache.set(thenable, threadIDs);
18130 }
18131 }
18132 if (!threadIDs.has(renderExpirationTime)) {
18133 // Memoize using the thread ID to prevent redundant listeners.
18134 threadIDs.add(renderExpirationTime);
18135 var ping = pingSuspendedRoot.bind(null, root, thenable, renderExpirationTime);
18136 if (enableSchedulerTracing) {
18137 ping = tracing.unstable_wrap(ping);
18138 }
18139 thenable.then(ping, ping);
18140 }
18141}
18142
18143function throwException(root, returnFiber, sourceFiber, value, renderExpirationTime) {
18144 // The source fiber did not complete.
18145 sourceFiber.effectTag |= Incomplete;
18146 // Its effect list is no longer valid.
18147 sourceFiber.firstEffect = sourceFiber.lastEffect = null;
18148
18149 if (value !== null && typeof value === 'object' && typeof value.then === 'function') {
18150 // This is a thenable.
18151 var thenable = value;
18152
18153 // Find the earliest timeout threshold of all the placeholders in the
18154 // ancestor path. We could avoid this traversal by storing the thresholds on
18155 // the stack, but we choose not to because we only hit this path if we're
18156 // IO-bound (i.e. if something suspends). Whereas the stack is used even in
18157 // the non-IO- bound case.
18158 var _workInProgress = returnFiber;
18159 var earliestTimeoutMs = -1;
18160 var startTimeMs = -1;
18161 do {
18162 if (_workInProgress.tag === SuspenseComponent) {
18163 var current$$1 = _workInProgress.alternate;
18164 if (current$$1 !== null) {
18165 var currentState = current$$1.memoizedState;
18166 if (currentState !== null) {
18167 // Reached a boundary that already timed out. Do not search
18168 // any further.
18169 var timedOutAt = currentState.timedOutAt;
18170 startTimeMs = expirationTimeToMs(timedOutAt);
18171 // Do not search any further.
18172 break;
18173 }
18174 }
18175 var timeoutPropMs = _workInProgress.pendingProps.maxDuration;
18176 if (typeof timeoutPropMs === 'number') {
18177 if (timeoutPropMs <= 0) {
18178 earliestTimeoutMs = 0;
18179 } else if (earliestTimeoutMs === -1 || timeoutPropMs < earliestTimeoutMs) {
18180 earliestTimeoutMs = timeoutPropMs;
18181 }
18182 }
18183 }
18184 // If there is a DehydratedSuspenseComponent we don't have to do anything because
18185 // if something suspends inside it, we will simply leave that as dehydrated. It
18186 // will never timeout.
18187 _workInProgress = _workInProgress.return;
18188 } while (_workInProgress !== null);
18189
18190 // Schedule the nearest Suspense to re-render the timed out view.
18191 _workInProgress = returnFiber;
18192 do {
18193 if (_workInProgress.tag === SuspenseComponent && shouldCaptureSuspense(_workInProgress)) {
18194 // Found the nearest boundary.
18195
18196 // Stash the promise on the boundary fiber. If the boundary times out, we'll
18197 var thenables = _workInProgress.updateQueue;
18198 if (thenables === null) {
18199 var updateQueue = new Set();
18200 updateQueue.add(thenable);
18201 _workInProgress.updateQueue = updateQueue;
18202 } else {
18203 thenables.add(thenable);
18204 }
18205
18206 // If the boundary is outside of concurrent mode, we should *not*
18207 // suspend the commit. Pretend as if the suspended component rendered
18208 // null and keep rendering. In the commit phase, we'll schedule a
18209 // subsequent synchronous update to re-render the Suspense.
18210 //
18211 // Note: It doesn't matter whether the component that suspended was
18212 // inside a concurrent mode tree. If the Suspense is outside of it, we
18213 // should *not* suspend the commit.
18214 if ((_workInProgress.mode & ConcurrentMode) === NoEffect) {
18215 _workInProgress.effectTag |= DidCapture;
18216
18217 // We're going to commit this fiber even though it didn't complete.
18218 // But we shouldn't call any lifecycle methods or callbacks. Remove
18219 // all lifecycle effect tags.
18220 sourceFiber.effectTag &= ~(LifecycleEffectMask | Incomplete);
18221
18222 if (sourceFiber.tag === ClassComponent) {
18223 var currentSourceFiber = sourceFiber.alternate;
18224 if (currentSourceFiber === null) {
18225 // This is a new mount. Change the tag so it's not mistaken for a
18226 // completed class component. For example, we should not call
18227 // componentWillUnmount if it is deleted.
18228 sourceFiber.tag = IncompleteClassComponent;
18229 } else {
18230 // When we try rendering again, we should not reuse the current fiber,
18231 // since it's known to be in an inconsistent state. Use a force updte to
18232 // prevent a bail out.
18233 var update = createUpdate(Sync);
18234 update.tag = ForceUpdate;
18235 enqueueUpdate(sourceFiber, update);
18236 }
18237 }
18238
18239 // The source fiber did not complete. Mark it with Sync priority to
18240 // indicate that it still has pending work.
18241 sourceFiber.expirationTime = Sync;
18242
18243 // Exit without suspending.
18244 return;
18245 }
18246
18247 // Confirmed that the boundary is in a concurrent mode tree. Continue
18248 // with the normal suspend path.
18249
18250 attachPingListener(root, renderExpirationTime, thenable);
18251
18252 var absoluteTimeoutMs = void 0;
18253 if (earliestTimeoutMs === -1) {
18254 // If no explicit threshold is given, default to an arbitrarily large
18255 // value. The actual size doesn't matter because the threshold for the
18256 // whole tree will be clamped to the expiration time.
18257 absoluteTimeoutMs = maxSigned31BitInt;
18258 } else {
18259 if (startTimeMs === -1) {
18260 // This suspend happened outside of any already timed-out
18261 // placeholders. We don't know exactly when the update was
18262 // scheduled, but we can infer an approximate start time from the
18263 // expiration time. First, find the earliest uncommitted expiration
18264 // time in the tree, including work that is suspended. Then subtract
18265 // the offset used to compute an async update's expiration time.
18266 // This will cause high priority (interactive) work to expire
18267 // earlier than necessary, but we can account for this by adjusting
18268 // for the Just Noticeable Difference.
18269 var earliestExpirationTime = findEarliestOutstandingPriorityLevel(root, renderExpirationTime);
18270 var earliestExpirationTimeMs = expirationTimeToMs(earliestExpirationTime);
18271 startTimeMs = earliestExpirationTimeMs - LOW_PRIORITY_EXPIRATION;
18272 }
18273 absoluteTimeoutMs = startTimeMs + earliestTimeoutMs;
18274 }
18275
18276 // Mark the earliest timeout in the suspended fiber's ancestor path.
18277 // After completing the root, we'll take the largest of all the
18278 // suspended fiber's timeouts and use it to compute a timeout for the
18279 // whole tree.
18280 renderDidSuspend(root, absoluteTimeoutMs, renderExpirationTime);
18281
18282 _workInProgress.effectTag |= ShouldCapture;
18283 _workInProgress.expirationTime = renderExpirationTime;
18284 return;
18285 } else if (enableSuspenseServerRenderer && _workInProgress.tag === DehydratedSuspenseComponent) {
18286 attachPingListener(root, renderExpirationTime, thenable);
18287
18288 // Since we already have a current fiber, we can eagerly add a retry listener.
18289 var retryCache = _workInProgress.memoizedState;
18290 if (retryCache === null) {
18291 retryCache = _workInProgress.memoizedState = new PossiblyWeakSet();
18292 var _current = _workInProgress.alternate;
18293 !_current ? invariant(false, 'A dehydrated suspense boundary must commit before trying to render. This is probably a bug in React.') : void 0;
18294 _current.memoizedState = retryCache;
18295 }
18296 // Memoize using the boundary fiber to prevent redundant listeners.
18297 if (!retryCache.has(thenable)) {
18298 retryCache.add(thenable);
18299 var retry = retryTimedOutBoundary.bind(null, _workInProgress, thenable);
18300 if (enableSchedulerTracing) {
18301 retry = tracing.unstable_wrap(retry);
18302 }
18303 thenable.then(retry, retry);
18304 }
18305 _workInProgress.effectTag |= ShouldCapture;
18306 _workInProgress.expirationTime = renderExpirationTime;
18307 return;
18308 }
18309 // This boundary already captured during this render. Continue to the next
18310 // boundary.
18311 _workInProgress = _workInProgress.return;
18312 } while (_workInProgress !== null);
18313 // No boundary was found. Fallthrough to error mode.
18314 // TODO: Use invariant so the message is stripped in prod?
18315 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));
18316 }
18317
18318 // We didn't find a boundary that could handle this type of exception. Start
18319 // over and traverse parent path again, this time treating the exception
18320 // as an error.
18321 renderDidError();
18322 value = createCapturedValue(value, sourceFiber);
18323 var workInProgress = returnFiber;
18324 do {
18325 switch (workInProgress.tag) {
18326 case HostRoot:
18327 {
18328 var _errorInfo = value;
18329 workInProgress.effectTag |= ShouldCapture;
18330 workInProgress.expirationTime = renderExpirationTime;
18331 var _update = createRootErrorUpdate(workInProgress, _errorInfo, renderExpirationTime);
18332 enqueueCapturedUpdate(workInProgress, _update);
18333 return;
18334 }
18335 case ClassComponent:
18336 // Capture and retry
18337 var errorInfo = value;
18338 var ctor = workInProgress.type;
18339 var instance = workInProgress.stateNode;
18340 if ((workInProgress.effectTag & DidCapture) === NoEffect && (typeof ctor.getDerivedStateFromError === 'function' || instance !== null && typeof instance.componentDidCatch === 'function' && !isAlreadyFailedLegacyErrorBoundary(instance))) {
18341 workInProgress.effectTag |= ShouldCapture;
18342 workInProgress.expirationTime = renderExpirationTime;
18343 // Schedule the error boundary to re-render using updated state
18344 var _update2 = createClassErrorUpdate(workInProgress, errorInfo, renderExpirationTime);
18345 enqueueCapturedUpdate(workInProgress, _update2);
18346 return;
18347 }
18348 break;
18349 default:
18350 break;
18351 }
18352 workInProgress = workInProgress.return;
18353 } while (workInProgress !== null);
18354}
18355
18356function unwindWork(workInProgress, renderExpirationTime) {
18357 switch (workInProgress.tag) {
18358 case ClassComponent:
18359 {
18360 var Component = workInProgress.type;
18361 if (isContextProvider(Component)) {
18362 popContext(workInProgress);
18363 }
18364 var effectTag = workInProgress.effectTag;
18365 if (effectTag & ShouldCapture) {
18366 workInProgress.effectTag = effectTag & ~ShouldCapture | DidCapture;
18367 return workInProgress;
18368 }
18369 return null;
18370 }
18371 case HostRoot:
18372 {
18373 popHostContainer(workInProgress);
18374 popTopLevelContextObject(workInProgress);
18375 var _effectTag = workInProgress.effectTag;
18376 !((_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;
18377 workInProgress.effectTag = _effectTag & ~ShouldCapture | DidCapture;
18378 return workInProgress;
18379 }
18380 case HostComponent:
18381 {
18382 // TODO: popHydrationState
18383 popHostContext(workInProgress);
18384 return null;
18385 }
18386 case SuspenseComponent:
18387 {
18388 var _effectTag2 = workInProgress.effectTag;
18389 if (_effectTag2 & ShouldCapture) {
18390 workInProgress.effectTag = _effectTag2 & ~ShouldCapture | DidCapture;
18391 // Captured a suspense effect. Re-render the boundary.
18392 return workInProgress;
18393 }
18394 return null;
18395 }
18396 case DehydratedSuspenseComponent:
18397 {
18398 if (enableSuspenseServerRenderer) {
18399 // TODO: popHydrationState
18400 var _effectTag3 = workInProgress.effectTag;
18401 if (_effectTag3 & ShouldCapture) {
18402 workInProgress.effectTag = _effectTag3 & ~ShouldCapture | DidCapture;
18403 // Captured a suspense effect. Re-render the boundary.
18404 return workInProgress;
18405 }
18406 }
18407 return null;
18408 }
18409 case HostPortal:
18410 popHostContainer(workInProgress);
18411 return null;
18412 case ContextProvider:
18413 popProvider(workInProgress);
18414 return null;
18415 default:
18416 return null;
18417 }
18418}
18419
18420function unwindInterruptedWork(interruptedWork) {
18421 switch (interruptedWork.tag) {
18422 case ClassComponent:
18423 {
18424 var childContextTypes = interruptedWork.type.childContextTypes;
18425 if (childContextTypes !== null && childContextTypes !== undefined) {
18426 popContext(interruptedWork);
18427 }
18428 break;
18429 }
18430 case HostRoot:
18431 {
18432 popHostContainer(interruptedWork);
18433 popTopLevelContextObject(interruptedWork);
18434 break;
18435 }
18436 case HostComponent:
18437 {
18438 popHostContext(interruptedWork);
18439 break;
18440 }
18441 case HostPortal:
18442 popHostContainer(interruptedWork);
18443 break;
18444 case ContextProvider:
18445 popProvider(interruptedWork);
18446 break;
18447 default:
18448 break;
18449 }
18450}
18451
18452var ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher;
18453var ReactCurrentOwner$2 = ReactSharedInternals.ReactCurrentOwner;
18454
18455
18456var didWarnAboutStateTransition = void 0;
18457var didWarnSetStateChildContext = void 0;
18458var warnAboutUpdateOnUnmounted = void 0;
18459var warnAboutInvalidUpdates = void 0;
18460
18461if (enableSchedulerTracing) {
18462 // Provide explicit error message when production+profiling bundle of e.g. react-dom
18463 // is used with production (non-profiling) bundle of scheduler/tracing
18464 !(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;
18465}
18466
18467{
18468 didWarnAboutStateTransition = false;
18469 didWarnSetStateChildContext = false;
18470 var didWarnStateUpdateForUnmountedComponent = {};
18471
18472 warnAboutUpdateOnUnmounted = function (fiber, isClass) {
18473 // We show the whole stack but dedupe on the top component's name because
18474 // the problematic code almost always lies inside that component.
18475 var componentName = getComponentName(fiber.type) || 'ReactComponent';
18476 if (didWarnStateUpdateForUnmountedComponent[componentName]) {
18477 return;
18478 }
18479 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));
18480 didWarnStateUpdateForUnmountedComponent[componentName] = true;
18481 };
18482
18483 warnAboutInvalidUpdates = function (instance) {
18484 switch (phase) {
18485 case 'getChildContext':
18486 if (didWarnSetStateChildContext) {
18487 return;
18488 }
18489 warningWithoutStack$1(false, 'setState(...): Cannot call setState() inside getChildContext()');
18490 didWarnSetStateChildContext = true;
18491 break;
18492 case 'render':
18493 if (didWarnAboutStateTransition) {
18494 return;
18495 }
18496 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.');
18497 didWarnAboutStateTransition = true;
18498 break;
18499 }
18500 };
18501}
18502
18503// Used to ensure computeUniqueAsyncExpiration is monotonically decreasing.
18504var lastUniqueAsyncExpiration = Sync - 1;
18505
18506var isWorking = false;
18507
18508// The next work in progress fiber that we're currently working on.
18509var nextUnitOfWork = null;
18510var nextRoot = null;
18511// The time at which we're currently rendering work.
18512var nextRenderExpirationTime = NoWork;
18513var nextLatestAbsoluteTimeoutMs = -1;
18514var nextRenderDidError = false;
18515
18516// The next fiber with an effect that we're currently committing.
18517var nextEffect = null;
18518
18519var isCommitting$1 = false;
18520var rootWithPendingPassiveEffects = null;
18521var passiveEffectCallbackHandle = null;
18522var passiveEffectCallback = null;
18523
18524var legacyErrorBoundariesThatAlreadyFailed = null;
18525
18526// Used for performance tracking.
18527var interruptedBy = null;
18528
18529var stashedWorkInProgressProperties = void 0;
18530var replayUnitOfWork = void 0;
18531var mayReplayFailedUnitOfWork = void 0;
18532var isReplayingFailedUnitOfWork = void 0;
18533var originalReplayError = void 0;
18534var rethrowOriginalError = void 0;
18535if (true && replayFailedUnitOfWorkWithInvokeGuardedCallback) {
18536 stashedWorkInProgressProperties = null;
18537 mayReplayFailedUnitOfWork = true;
18538 isReplayingFailedUnitOfWork = false;
18539 originalReplayError = null;
18540 replayUnitOfWork = function (failedUnitOfWork, thrownValue, isYieldy) {
18541 if (thrownValue !== null && typeof thrownValue === 'object' && typeof thrownValue.then === 'function') {
18542 // Don't replay promises. Treat everything else like an error.
18543 // TODO: Need to figure out a different strategy if/when we add
18544 // support for catching other types.
18545 return;
18546 }
18547
18548 // Restore the original state of the work-in-progress
18549 if (stashedWorkInProgressProperties === null) {
18550 // This should never happen. Don't throw because this code is DEV-only.
18551 warningWithoutStack$1(false, 'Could not replay rendering after an error. This is likely a bug in React. ' + 'Please file an issue.');
18552 return;
18553 }
18554 assignFiberPropertiesInDEV(failedUnitOfWork, stashedWorkInProgressProperties);
18555
18556 switch (failedUnitOfWork.tag) {
18557 case HostRoot:
18558 popHostContainer(failedUnitOfWork);
18559 popTopLevelContextObject(failedUnitOfWork);
18560 break;
18561 case HostComponent:
18562 popHostContext(failedUnitOfWork);
18563 break;
18564 case ClassComponent:
18565 {
18566 var Component = failedUnitOfWork.type;
18567 if (isContextProvider(Component)) {
18568 popContext(failedUnitOfWork);
18569 }
18570 break;
18571 }
18572 case HostPortal:
18573 popHostContainer(failedUnitOfWork);
18574 break;
18575 case ContextProvider:
18576 popProvider(failedUnitOfWork);
18577 break;
18578 }
18579 // Replay the begin phase.
18580 isReplayingFailedUnitOfWork = true;
18581 originalReplayError = thrownValue;
18582 invokeGuardedCallback(null, workLoop, null, isYieldy);
18583 isReplayingFailedUnitOfWork = false;
18584 originalReplayError = null;
18585 if (hasCaughtError()) {
18586 var replayError = clearCaughtError();
18587 if (replayError != null && thrownValue != null) {
18588 try {
18589 // Reading the expando property is intentionally
18590 // inside `try` because it might be a getter or Proxy.
18591 if (replayError._suppressLogging) {
18592 // Also suppress logging for the original error.
18593 thrownValue._suppressLogging = true;
18594 }
18595 } catch (inner) {
18596 // Ignore.
18597 }
18598 }
18599 } else {
18600 // If the begin phase did not fail the second time, set this pointer
18601 // back to the original value.
18602 nextUnitOfWork = failedUnitOfWork;
18603 }
18604 };
18605 rethrowOriginalError = function () {
18606 throw originalReplayError;
18607 };
18608}
18609
18610function resetStack() {
18611 if (nextUnitOfWork !== null) {
18612 var interruptedWork = nextUnitOfWork.return;
18613 while (interruptedWork !== null) {
18614 unwindInterruptedWork(interruptedWork);
18615 interruptedWork = interruptedWork.return;
18616 }
18617 }
18618
18619 {
18620 ReactStrictModeWarnings.discardPendingWarnings();
18621 checkThatStackIsEmpty();
18622 }
18623
18624 nextRoot = null;
18625 nextRenderExpirationTime = NoWork;
18626 nextLatestAbsoluteTimeoutMs = -1;
18627 nextRenderDidError = false;
18628 nextUnitOfWork = null;
18629}
18630
18631function commitAllHostEffects() {
18632 while (nextEffect !== null) {
18633 {
18634 setCurrentFiber(nextEffect);
18635 }
18636 recordEffect();
18637
18638 var effectTag = nextEffect.effectTag;
18639
18640 if (effectTag & ContentReset) {
18641 commitResetTextContent(nextEffect);
18642 }
18643
18644 if (effectTag & Ref) {
18645 var current$$1 = nextEffect.alternate;
18646 if (current$$1 !== null) {
18647 commitDetachRef(current$$1);
18648 }
18649 }
18650
18651 // The following switch statement is only concerned about placement,
18652 // updates, and deletions. To avoid needing to add a case for every
18653 // possible bitmap value, we remove the secondary effects from the
18654 // effect tag and switch on that value.
18655 var primaryEffectTag = effectTag & (Placement | Update | Deletion);
18656 switch (primaryEffectTag) {
18657 case Placement:
18658 {
18659 commitPlacement(nextEffect);
18660 // Clear the "placement" from effect tag so that we know that this is inserted, before
18661 // any life-cycles like componentDidMount gets called.
18662 // TODO: findDOMNode doesn't rely on this any more but isMounted
18663 // does and isMounted is deprecated anyway so we should be able
18664 // to kill this.
18665 nextEffect.effectTag &= ~Placement;
18666 break;
18667 }
18668 case PlacementAndUpdate:
18669 {
18670 // Placement
18671 commitPlacement(nextEffect);
18672 // Clear the "placement" from effect tag so that we know that this is inserted, before
18673 // any life-cycles like componentDidMount gets called.
18674 nextEffect.effectTag &= ~Placement;
18675
18676 // Update
18677 var _current = nextEffect.alternate;
18678 commitWork(_current, nextEffect);
18679 break;
18680 }
18681 case Update:
18682 {
18683 var _current2 = nextEffect.alternate;
18684 commitWork(_current2, nextEffect);
18685 break;
18686 }
18687 case Deletion:
18688 {
18689 commitDeletion(nextEffect);
18690 break;
18691 }
18692 }
18693 nextEffect = nextEffect.nextEffect;
18694 }
18695
18696 {
18697 resetCurrentFiber();
18698 }
18699}
18700
18701function commitBeforeMutationLifecycles() {
18702 while (nextEffect !== null) {
18703 {
18704 setCurrentFiber(nextEffect);
18705 }
18706
18707 var effectTag = nextEffect.effectTag;
18708 if (effectTag & Snapshot) {
18709 recordEffect();
18710 var current$$1 = nextEffect.alternate;
18711 commitBeforeMutationLifeCycles(current$$1, nextEffect);
18712 }
18713
18714 nextEffect = nextEffect.nextEffect;
18715 }
18716
18717 {
18718 resetCurrentFiber();
18719 }
18720}
18721
18722function commitAllLifeCycles(finishedRoot, committedExpirationTime) {
18723 {
18724 ReactStrictModeWarnings.flushPendingUnsafeLifecycleWarnings();
18725 ReactStrictModeWarnings.flushLegacyContextWarning();
18726
18727 if (warnAboutDeprecatedLifecycles) {
18728 ReactStrictModeWarnings.flushPendingDeprecationWarnings();
18729 }
18730 }
18731 while (nextEffect !== null) {
18732 {
18733 setCurrentFiber(nextEffect);
18734 }
18735 var effectTag = nextEffect.effectTag;
18736
18737 if (effectTag & (Update | Callback)) {
18738 recordEffect();
18739 var current$$1 = nextEffect.alternate;
18740 commitLifeCycles(finishedRoot, current$$1, nextEffect, committedExpirationTime);
18741 }
18742
18743 if (effectTag & Ref) {
18744 recordEffect();
18745 commitAttachRef(nextEffect);
18746 }
18747
18748 if (effectTag & Passive) {
18749 rootWithPendingPassiveEffects = finishedRoot;
18750 }
18751
18752 nextEffect = nextEffect.nextEffect;
18753 }
18754 {
18755 resetCurrentFiber();
18756 }
18757}
18758
18759function commitPassiveEffects(root, firstEffect) {
18760 rootWithPendingPassiveEffects = null;
18761 passiveEffectCallbackHandle = null;
18762 passiveEffectCallback = null;
18763
18764 // Set this to true to prevent re-entrancy
18765 var previousIsRendering = isRendering;
18766 isRendering = true;
18767
18768 var effect = firstEffect;
18769 do {
18770 {
18771 setCurrentFiber(effect);
18772 }
18773
18774 if (effect.effectTag & Passive) {
18775 var didError = false;
18776 var error = void 0;
18777 {
18778 invokeGuardedCallback(null, commitPassiveHookEffects, null, effect);
18779 if (hasCaughtError()) {
18780 didError = true;
18781 error = clearCaughtError();
18782 }
18783 }
18784 if (didError) {
18785 captureCommitPhaseError(effect, error);
18786 }
18787 }
18788 effect = effect.nextEffect;
18789 } while (effect !== null);
18790 {
18791 resetCurrentFiber();
18792 }
18793
18794 isRendering = previousIsRendering;
18795
18796 // Check if work was scheduled by one of the effects
18797 var rootExpirationTime = root.expirationTime;
18798 if (rootExpirationTime !== NoWork) {
18799 requestWork(root, rootExpirationTime);
18800 }
18801 // Flush any sync work that was scheduled by effects
18802 if (!isBatchingUpdates && !isRendering) {
18803 performSyncWork();
18804 }
18805}
18806
18807function isAlreadyFailedLegacyErrorBoundary(instance) {
18808 return legacyErrorBoundariesThatAlreadyFailed !== null && legacyErrorBoundariesThatAlreadyFailed.has(instance);
18809}
18810
18811function markLegacyErrorBoundaryAsFailed(instance) {
18812 if (legacyErrorBoundariesThatAlreadyFailed === null) {
18813 legacyErrorBoundariesThatAlreadyFailed = new Set([instance]);
18814 } else {
18815 legacyErrorBoundariesThatAlreadyFailed.add(instance);
18816 }
18817}
18818
18819function flushPassiveEffects() {
18820 if (passiveEffectCallbackHandle !== null) {
18821 cancelPassiveEffects(passiveEffectCallbackHandle);
18822 }
18823 if (passiveEffectCallback !== null) {
18824 // We call the scheduled callback instead of commitPassiveEffects directly
18825 // to ensure tracing works correctly.
18826 passiveEffectCallback();
18827 }
18828}
18829
18830function commitRoot(root, finishedWork) {
18831 isWorking = true;
18832 isCommitting$1 = true;
18833 startCommitTimer();
18834
18835 !(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;
18836 var committedExpirationTime = root.pendingCommitExpirationTime;
18837 !(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;
18838 root.pendingCommitExpirationTime = NoWork;
18839
18840 // Update the pending priority levels to account for the work that we are
18841 // about to commit. This needs to happen before calling the lifecycles, since
18842 // they may schedule additional updates.
18843 var updateExpirationTimeBeforeCommit = finishedWork.expirationTime;
18844 var childExpirationTimeBeforeCommit = finishedWork.childExpirationTime;
18845 var earliestRemainingTimeBeforeCommit = childExpirationTimeBeforeCommit > updateExpirationTimeBeforeCommit ? childExpirationTimeBeforeCommit : updateExpirationTimeBeforeCommit;
18846 markCommittedPriorityLevels(root, earliestRemainingTimeBeforeCommit);
18847
18848 var prevInteractions = null;
18849 if (enableSchedulerTracing) {
18850 // Restore any pending interactions at this point,
18851 // So that cascading work triggered during the render phase will be accounted for.
18852 prevInteractions = tracing.__interactionsRef.current;
18853 tracing.__interactionsRef.current = root.memoizedInteractions;
18854 }
18855
18856 // Reset this to null before calling lifecycles
18857 ReactCurrentOwner$2.current = null;
18858
18859 var firstEffect = void 0;
18860 if (finishedWork.effectTag > PerformedWork) {
18861 // A fiber's effect list consists only of its children, not itself. So if
18862 // the root has an effect, we need to add it to the end of the list. The
18863 // resulting list is the set that would belong to the root's parent, if
18864 // it had one; that is, all the effects in the tree including the root.
18865 if (finishedWork.lastEffect !== null) {
18866 finishedWork.lastEffect.nextEffect = finishedWork;
18867 firstEffect = finishedWork.firstEffect;
18868 } else {
18869 firstEffect = finishedWork;
18870 }
18871 } else {
18872 // There is no effect on the root.
18873 firstEffect = finishedWork.firstEffect;
18874 }
18875
18876 prepareForCommit(root.containerInfo);
18877
18878 // Invoke instances of getSnapshotBeforeUpdate before mutation.
18879 nextEffect = firstEffect;
18880 startCommitSnapshotEffectsTimer();
18881 while (nextEffect !== null) {
18882 var didError = false;
18883 var error = void 0;
18884 {
18885 invokeGuardedCallback(null, commitBeforeMutationLifecycles, null);
18886 if (hasCaughtError()) {
18887 didError = true;
18888 error = clearCaughtError();
18889 }
18890 }
18891 if (didError) {
18892 !(nextEffect !== null) ? invariant(false, 'Should have next effect. This error is likely caused by a bug in React. Please file an issue.') : void 0;
18893 captureCommitPhaseError(nextEffect, error);
18894 // Clean-up
18895 if (nextEffect !== null) {
18896 nextEffect = nextEffect.nextEffect;
18897 }
18898 }
18899 }
18900 stopCommitSnapshotEffectsTimer();
18901
18902 if (enableProfilerTimer) {
18903 // Mark the current commit time to be shared by all Profilers in this batch.
18904 // This enables them to be grouped later.
18905 recordCommitTime();
18906 }
18907
18908 // Commit all the side-effects within a tree. We'll do this in two passes.
18909 // The first pass performs all the host insertions, updates, deletions and
18910 // ref unmounts.
18911 nextEffect = firstEffect;
18912 startCommitHostEffectsTimer();
18913 while (nextEffect !== null) {
18914 var _didError = false;
18915 var _error = void 0;
18916 {
18917 invokeGuardedCallback(null, commitAllHostEffects, null);
18918 if (hasCaughtError()) {
18919 _didError = true;
18920 _error = clearCaughtError();
18921 }
18922 }
18923 if (_didError) {
18924 !(nextEffect !== null) ? invariant(false, 'Should have next effect. This error is likely caused by a bug in React. Please file an issue.') : void 0;
18925 captureCommitPhaseError(nextEffect, _error);
18926 // Clean-up
18927 if (nextEffect !== null) {
18928 nextEffect = nextEffect.nextEffect;
18929 }
18930 }
18931 }
18932 stopCommitHostEffectsTimer();
18933
18934 resetAfterCommit(root.containerInfo);
18935
18936 // The work-in-progress tree is now the current tree. This must come after
18937 // the first pass of the commit phase, so that the previous tree is still
18938 // current during componentWillUnmount, but before the second pass, so that
18939 // the finished work is current during componentDidMount/Update.
18940 root.current = finishedWork;
18941
18942 // In the second pass we'll perform all life-cycles and ref callbacks.
18943 // Life-cycles happen as a separate pass so that all placements, updates,
18944 // and deletions in the entire tree have already been invoked.
18945 // This pass also triggers any renderer-specific initial effects.
18946 nextEffect = firstEffect;
18947 startCommitLifeCyclesTimer();
18948 while (nextEffect !== null) {
18949 var _didError2 = false;
18950 var _error2 = void 0;
18951 {
18952 invokeGuardedCallback(null, commitAllLifeCycles, null, root, committedExpirationTime);
18953 if (hasCaughtError()) {
18954 _didError2 = true;
18955 _error2 = clearCaughtError();
18956 }
18957 }
18958 if (_didError2) {
18959 !(nextEffect !== null) ? invariant(false, 'Should have next effect. This error is likely caused by a bug in React. Please file an issue.') : void 0;
18960 captureCommitPhaseError(nextEffect, _error2);
18961 if (nextEffect !== null) {
18962 nextEffect = nextEffect.nextEffect;
18963 }
18964 }
18965 }
18966
18967 if (firstEffect !== null && rootWithPendingPassiveEffects !== null) {
18968 // This commit included a passive effect. These do not need to fire until
18969 // after the next paint. Schedule an callback to fire them in an async
18970 // event. To ensure serial execution, the callback will be flushed early if
18971 // we enter rootWithPendingPassiveEffects commit phase before then.
18972 var callback = commitPassiveEffects.bind(null, root, firstEffect);
18973 if (enableSchedulerTracing) {
18974 // TODO: Avoid this extra callback by mutating the tracing ref directly,
18975 // like we do at the beginning of commitRoot. I've opted not to do that
18976 // here because that code is still in flux.
18977 callback = tracing.unstable_wrap(callback);
18978 }
18979 passiveEffectCallbackHandle = scheduler.unstable_runWithPriority(scheduler.unstable_NormalPriority, function () {
18980 return schedulePassiveEffects(callback);
18981 });
18982 passiveEffectCallback = callback;
18983 }
18984
18985 isCommitting$1 = false;
18986 isWorking = false;
18987 stopCommitLifeCyclesTimer();
18988 stopCommitTimer();
18989 onCommitRoot(finishedWork.stateNode);
18990 if (true && ReactFiberInstrumentation_1.debugTool) {
18991 ReactFiberInstrumentation_1.debugTool.onCommitWork(finishedWork);
18992 }
18993
18994 var updateExpirationTimeAfterCommit = finishedWork.expirationTime;
18995 var childExpirationTimeAfterCommit = finishedWork.childExpirationTime;
18996 var earliestRemainingTimeAfterCommit = childExpirationTimeAfterCommit > updateExpirationTimeAfterCommit ? childExpirationTimeAfterCommit : updateExpirationTimeAfterCommit;
18997 if (earliestRemainingTimeAfterCommit === NoWork) {
18998 // If there's no remaining work, we can clear the set of already failed
18999 // error boundaries.
19000 legacyErrorBoundariesThatAlreadyFailed = null;
19001 }
19002 onCommit(root, earliestRemainingTimeAfterCommit);
19003
19004 if (enableSchedulerTracing) {
19005 tracing.__interactionsRef.current = prevInteractions;
19006
19007 var subscriber = void 0;
19008
19009 try {
19010 subscriber = tracing.__subscriberRef.current;
19011 if (subscriber !== null && root.memoizedInteractions.size > 0) {
19012 var threadID = computeThreadID(committedExpirationTime, root.interactionThreadID);
19013 subscriber.onWorkStopped(root.memoizedInteractions, threadID);
19014 }
19015 } catch (error) {
19016 // It's not safe for commitRoot() to throw.
19017 // Store the error for now and we'll re-throw in finishRendering().
19018 if (!hasUnhandledError) {
19019 hasUnhandledError = true;
19020 unhandledError = error;
19021 }
19022 } finally {
19023 // Clear completed interactions from the pending Map.
19024 // Unless the render was suspended or cascading work was scheduled,
19025 // In which case– leave pending interactions until the subsequent render.
19026 var pendingInteractionMap = root.pendingInteractionMap;
19027 pendingInteractionMap.forEach(function (scheduledInteractions, scheduledExpirationTime) {
19028 // Only decrement the pending interaction count if we're done.
19029 // If there's still work at the current priority,
19030 // That indicates that we are waiting for suspense data.
19031 if (scheduledExpirationTime > earliestRemainingTimeAfterCommit) {
19032 pendingInteractionMap.delete(scheduledExpirationTime);
19033
19034 scheduledInteractions.forEach(function (interaction) {
19035 interaction.__count--;
19036
19037 if (subscriber !== null && interaction.__count === 0) {
19038 try {
19039 subscriber.onInteractionScheduledWorkCompleted(interaction);
19040 } catch (error) {
19041 // It's not safe for commitRoot() to throw.
19042 // Store the error for now and we'll re-throw in finishRendering().
19043 if (!hasUnhandledError) {
19044 hasUnhandledError = true;
19045 unhandledError = error;
19046 }
19047 }
19048 }
19049 });
19050 }
19051 });
19052 }
19053 }
19054}
19055
19056function resetChildExpirationTime(workInProgress, renderTime) {
19057 if (renderTime !== Never && workInProgress.childExpirationTime === Never) {
19058 // The children of this component are hidden. Don't bubble their
19059 // expiration times.
19060 return;
19061 }
19062
19063 var newChildExpirationTime = NoWork;
19064
19065 // Bubble up the earliest expiration time.
19066 if (enableProfilerTimer && workInProgress.mode & ProfileMode) {
19067 // We're in profiling mode.
19068 // Let's use this same traversal to update the render durations.
19069 var actualDuration = workInProgress.actualDuration;
19070 var treeBaseDuration = workInProgress.selfBaseDuration;
19071
19072 // When a fiber is cloned, its actualDuration is reset to 0.
19073 // This value will only be updated if work is done on the fiber (i.e. it doesn't bailout).
19074 // When work is done, it should bubble to the parent's actualDuration.
19075 // If the fiber has not been cloned though, (meaning no work was done),
19076 // Then this value will reflect the amount of time spent working on a previous render.
19077 // In that case it should not bubble.
19078 // We determine whether it was cloned by comparing the child pointer.
19079 var shouldBubbleActualDurations = workInProgress.alternate === null || workInProgress.child !== workInProgress.alternate.child;
19080
19081 var child = workInProgress.child;
19082 while (child !== null) {
19083 var childUpdateExpirationTime = child.expirationTime;
19084 var childChildExpirationTime = child.childExpirationTime;
19085 if (childUpdateExpirationTime > newChildExpirationTime) {
19086 newChildExpirationTime = childUpdateExpirationTime;
19087 }
19088 if (childChildExpirationTime > newChildExpirationTime) {
19089 newChildExpirationTime = childChildExpirationTime;
19090 }
19091 if (shouldBubbleActualDurations) {
19092 actualDuration += child.actualDuration;
19093 }
19094 treeBaseDuration += child.treeBaseDuration;
19095 child = child.sibling;
19096 }
19097 workInProgress.actualDuration = actualDuration;
19098 workInProgress.treeBaseDuration = treeBaseDuration;
19099 } else {
19100 var _child = workInProgress.child;
19101 while (_child !== null) {
19102 var _childUpdateExpirationTime = _child.expirationTime;
19103 var _childChildExpirationTime = _child.childExpirationTime;
19104 if (_childUpdateExpirationTime > newChildExpirationTime) {
19105 newChildExpirationTime = _childUpdateExpirationTime;
19106 }
19107 if (_childChildExpirationTime > newChildExpirationTime) {
19108 newChildExpirationTime = _childChildExpirationTime;
19109 }
19110 _child = _child.sibling;
19111 }
19112 }
19113
19114 workInProgress.childExpirationTime = newChildExpirationTime;
19115}
19116
19117function completeUnitOfWork(workInProgress) {
19118 // Attempt to complete the current unit of work, then move to the
19119 // next sibling. If there are no more siblings, return to the
19120 // parent fiber.
19121 while (true) {
19122 // The current, flushed, state of this fiber is the alternate.
19123 // Ideally nothing should rely on this, but relying on it here
19124 // means that we don't need an additional field on the work in
19125 // progress.
19126 var current$$1 = workInProgress.alternate;
19127 {
19128 setCurrentFiber(workInProgress);
19129 }
19130
19131 var returnFiber = workInProgress.return;
19132 var siblingFiber = workInProgress.sibling;
19133
19134 if ((workInProgress.effectTag & Incomplete) === NoEffect) {
19135 if (true && replayFailedUnitOfWorkWithInvokeGuardedCallback) {
19136 // Don't replay if it fails during completion phase.
19137 mayReplayFailedUnitOfWork = false;
19138 }
19139 // This fiber completed.
19140 // Remember we're completing this unit so we can find a boundary if it fails.
19141 nextUnitOfWork = workInProgress;
19142 if (enableProfilerTimer) {
19143 if (workInProgress.mode & ProfileMode) {
19144 startProfilerTimer(workInProgress);
19145 }
19146 nextUnitOfWork = completeWork(current$$1, workInProgress, nextRenderExpirationTime);
19147 if (workInProgress.mode & ProfileMode) {
19148 // Update render duration assuming we didn't error.
19149 stopProfilerTimerIfRunningAndRecordDelta(workInProgress, false);
19150 }
19151 } else {
19152 nextUnitOfWork = completeWork(current$$1, workInProgress, nextRenderExpirationTime);
19153 }
19154 if (true && replayFailedUnitOfWorkWithInvokeGuardedCallback) {
19155 // We're out of completion phase so replaying is fine now.
19156 mayReplayFailedUnitOfWork = true;
19157 }
19158 stopWorkTimer(workInProgress);
19159 resetChildExpirationTime(workInProgress, nextRenderExpirationTime);
19160 {
19161 resetCurrentFiber();
19162 }
19163
19164 if (nextUnitOfWork !== null) {
19165 // Completing this fiber spawned new work. Work on that next.
19166 return nextUnitOfWork;
19167 }
19168
19169 if (returnFiber !== null &&
19170 // Do not append effects to parents if a sibling failed to complete
19171 (returnFiber.effectTag & Incomplete) === NoEffect) {
19172 // Append all the effects of the subtree and this fiber onto the effect
19173 // list of the parent. The completion order of the children affects the
19174 // side-effect order.
19175 if (returnFiber.firstEffect === null) {
19176 returnFiber.firstEffect = workInProgress.firstEffect;
19177 }
19178 if (workInProgress.lastEffect !== null) {
19179 if (returnFiber.lastEffect !== null) {
19180 returnFiber.lastEffect.nextEffect = workInProgress.firstEffect;
19181 }
19182 returnFiber.lastEffect = workInProgress.lastEffect;
19183 }
19184
19185 // If this fiber had side-effects, we append it AFTER the children's
19186 // side-effects. We can perform certain side-effects earlier if
19187 // needed, by doing multiple passes over the effect list. We don't want
19188 // to schedule our own side-effect on our own list because if end up
19189 // reusing children we'll schedule this effect onto itself since we're
19190 // at the end.
19191 var effectTag = workInProgress.effectTag;
19192 // Skip both NoWork and PerformedWork tags when creating the effect list.
19193 // PerformedWork effect is read by React DevTools but shouldn't be committed.
19194 if (effectTag > PerformedWork) {
19195 if (returnFiber.lastEffect !== null) {
19196 returnFiber.lastEffect.nextEffect = workInProgress;
19197 } else {
19198 returnFiber.firstEffect = workInProgress;
19199 }
19200 returnFiber.lastEffect = workInProgress;
19201 }
19202 }
19203
19204 if (true && ReactFiberInstrumentation_1.debugTool) {
19205 ReactFiberInstrumentation_1.debugTool.onCompleteWork(workInProgress);
19206 }
19207
19208 if (siblingFiber !== null) {
19209 // If there is more work to do in this returnFiber, do that next.
19210 return siblingFiber;
19211 } else if (returnFiber !== null) {
19212 // If there's no more work in this returnFiber. Complete the returnFiber.
19213 workInProgress = returnFiber;
19214 continue;
19215 } else {
19216 // We've reached the root.
19217 return null;
19218 }
19219 } else {
19220 if (enableProfilerTimer && workInProgress.mode & ProfileMode) {
19221 // Record the render duration for the fiber that errored.
19222 stopProfilerTimerIfRunningAndRecordDelta(workInProgress, false);
19223
19224 // Include the time spent working on failed children before continuing.
19225 var actualDuration = workInProgress.actualDuration;
19226 var child = workInProgress.child;
19227 while (child !== null) {
19228 actualDuration += child.actualDuration;
19229 child = child.sibling;
19230 }
19231 workInProgress.actualDuration = actualDuration;
19232 }
19233
19234 // This fiber did not complete because something threw. Pop values off
19235 // the stack without entering the complete phase. If this is a boundary,
19236 // capture values if possible.
19237 var next = unwindWork(workInProgress, nextRenderExpirationTime);
19238 // Because this fiber did not complete, don't reset its expiration time.
19239 if (workInProgress.effectTag & DidCapture) {
19240 // Restarting an error boundary
19241 stopFailedWorkTimer(workInProgress);
19242 } else {
19243 stopWorkTimer(workInProgress);
19244 }
19245
19246 {
19247 resetCurrentFiber();
19248 }
19249
19250 if (next !== null) {
19251 stopWorkTimer(workInProgress);
19252 if (true && ReactFiberInstrumentation_1.debugTool) {
19253 ReactFiberInstrumentation_1.debugTool.onCompleteWork(workInProgress);
19254 }
19255
19256 // If completing this work spawned new work, do that next. We'll come
19257 // back here again.
19258 // Since we're restarting, remove anything that is not a host effect
19259 // from the effect tag.
19260 next.effectTag &= HostEffectMask;
19261 return next;
19262 }
19263
19264 if (returnFiber !== null) {
19265 // Mark the parent fiber as incomplete and clear its effect list.
19266 returnFiber.firstEffect = returnFiber.lastEffect = null;
19267 returnFiber.effectTag |= Incomplete;
19268 }
19269
19270 if (true && ReactFiberInstrumentation_1.debugTool) {
19271 ReactFiberInstrumentation_1.debugTool.onCompleteWork(workInProgress);
19272 }
19273
19274 if (siblingFiber !== null) {
19275 // If there is more work to do in this returnFiber, do that next.
19276 return siblingFiber;
19277 } else if (returnFiber !== null) {
19278 // If there's no more work in this returnFiber. Complete the returnFiber.
19279 workInProgress = returnFiber;
19280 continue;
19281 } else {
19282 return null;
19283 }
19284 }
19285 }
19286
19287 // Without this explicit null return Flow complains of invalid return type
19288 // TODO Remove the above while(true) loop
19289 // eslint-disable-next-line no-unreachable
19290 return null;
19291}
19292
19293function performUnitOfWork(workInProgress) {
19294 // The current, flushed, state of this fiber is the alternate.
19295 // Ideally nothing should rely on this, but relying on it here
19296 // means that we don't need an additional field on the work in
19297 // progress.
19298 var current$$1 = workInProgress.alternate;
19299
19300 // See if beginning this work spawns more work.
19301 startWorkTimer(workInProgress);
19302 {
19303 setCurrentFiber(workInProgress);
19304 }
19305
19306 if (true && replayFailedUnitOfWorkWithInvokeGuardedCallback) {
19307 stashedWorkInProgressProperties = assignFiberPropertiesInDEV(stashedWorkInProgressProperties, workInProgress);
19308 }
19309
19310 var next = void 0;
19311 if (enableProfilerTimer) {
19312 if (workInProgress.mode & ProfileMode) {
19313 startProfilerTimer(workInProgress);
19314 }
19315
19316 next = beginWork(current$$1, workInProgress, nextRenderExpirationTime);
19317 workInProgress.memoizedProps = workInProgress.pendingProps;
19318
19319 if (workInProgress.mode & ProfileMode) {
19320 // Record the render duration assuming we didn't bailout (or error).
19321 stopProfilerTimerIfRunningAndRecordDelta(workInProgress, true);
19322 }
19323 } else {
19324 next = beginWork(current$$1, workInProgress, nextRenderExpirationTime);
19325 workInProgress.memoizedProps = workInProgress.pendingProps;
19326 }
19327
19328 {
19329 resetCurrentFiber();
19330 if (isReplayingFailedUnitOfWork) {
19331 // Currently replaying a failed unit of work. This should be unreachable,
19332 // because the render phase is meant to be idempotent, and it should
19333 // have thrown again. Since it didn't, rethrow the original error, so
19334 // React's internal stack is not misaligned.
19335 rethrowOriginalError();
19336 }
19337 }
19338 if (true && ReactFiberInstrumentation_1.debugTool) {
19339 ReactFiberInstrumentation_1.debugTool.onBeginWork(workInProgress);
19340 }
19341
19342 if (next === null) {
19343 // If this doesn't spawn new work, complete the current work.
19344 next = completeUnitOfWork(workInProgress);
19345 }
19346
19347 ReactCurrentOwner$2.current = null;
19348
19349 return next;
19350}
19351
19352function workLoop(isYieldy) {
19353 if (!isYieldy) {
19354 // Flush work without yielding
19355 while (nextUnitOfWork !== null) {
19356 nextUnitOfWork = performUnitOfWork(nextUnitOfWork);
19357 }
19358 } else {
19359 // Flush asynchronous work until there's a higher priority event
19360 while (nextUnitOfWork !== null && !shouldYieldToRenderer()) {
19361 nextUnitOfWork = performUnitOfWork(nextUnitOfWork);
19362 }
19363 }
19364}
19365
19366function renderRoot(root, isYieldy) {
19367 !!isWorking ? invariant(false, 'renderRoot was called recursively. This error is likely caused by a bug in React. Please file an issue.') : void 0;
19368
19369 flushPassiveEffects();
19370
19371 isWorking = true;
19372 var previousDispatcher = ReactCurrentDispatcher.current;
19373 ReactCurrentDispatcher.current = ContextOnlyDispatcher;
19374
19375 var expirationTime = root.nextExpirationTimeToWorkOn;
19376
19377 // Check if we're starting from a fresh stack, or if we're resuming from
19378 // previously yielded work.
19379 if (expirationTime !== nextRenderExpirationTime || root !== nextRoot || nextUnitOfWork === null) {
19380 // Reset the stack and start working from the root.
19381 resetStack();
19382 nextRoot = root;
19383 nextRenderExpirationTime = expirationTime;
19384 nextUnitOfWork = createWorkInProgress(nextRoot.current, null, nextRenderExpirationTime);
19385 root.pendingCommitExpirationTime = NoWork;
19386
19387 if (enableSchedulerTracing) {
19388 // Determine which interactions this batch of work currently includes,
19389 // So that we can accurately attribute time spent working on it,
19390 var interactions = new Set();
19391 root.pendingInteractionMap.forEach(function (scheduledInteractions, scheduledExpirationTime) {
19392 if (scheduledExpirationTime >= expirationTime) {
19393 scheduledInteractions.forEach(function (interaction) {
19394 return interactions.add(interaction);
19395 });
19396 }
19397 });
19398
19399 // Store the current set of interactions on the FiberRoot for a few reasons:
19400 // We can re-use it in hot functions like renderRoot() without having to recalculate it.
19401 // We will also use it in commitWork() to pass to any Profiler onRender() hooks.
19402 // This also provides DevTools with a way to access it when the onCommitRoot() hook is called.
19403 root.memoizedInteractions = interactions;
19404
19405 if (interactions.size > 0) {
19406 var subscriber = tracing.__subscriberRef.current;
19407 if (subscriber !== null) {
19408 var threadID = computeThreadID(expirationTime, root.interactionThreadID);
19409 try {
19410 subscriber.onWorkStarted(interactions, threadID);
19411 } catch (error) {
19412 // Work thrown by an interaction tracing subscriber should be rethrown,
19413 // But only once it's safe (to avoid leaving the scheduler in an invalid state).
19414 // Store the error for now and we'll re-throw in finishRendering().
19415 if (!hasUnhandledError) {
19416 hasUnhandledError = true;
19417 unhandledError = error;
19418 }
19419 }
19420 }
19421 }
19422 }
19423 }
19424
19425 var prevInteractions = null;
19426 if (enableSchedulerTracing) {
19427 // We're about to start new traced work.
19428 // Restore pending interactions so cascading work triggered during the render phase will be accounted for.
19429 prevInteractions = tracing.__interactionsRef.current;
19430 tracing.__interactionsRef.current = root.memoizedInteractions;
19431 }
19432
19433 var didFatal = false;
19434
19435 startWorkLoopTimer(nextUnitOfWork);
19436
19437 do {
19438 try {
19439 workLoop(isYieldy);
19440 } catch (thrownValue) {
19441 resetContextDependences();
19442 resetHooks();
19443
19444 // Reset in case completion throws.
19445 // This is only used in DEV and when replaying is on.
19446 var mayReplay = void 0;
19447 if (true && replayFailedUnitOfWorkWithInvokeGuardedCallback) {
19448 mayReplay = mayReplayFailedUnitOfWork;
19449 mayReplayFailedUnitOfWork = true;
19450 }
19451
19452 if (nextUnitOfWork === null) {
19453 // This is a fatal error.
19454 didFatal = true;
19455 onUncaughtError(thrownValue);
19456 } else {
19457 if (enableProfilerTimer && nextUnitOfWork.mode & ProfileMode) {
19458 // Record the time spent rendering before an error was thrown.
19459 // This avoids inaccurate Profiler durations in the case of a suspended render.
19460 stopProfilerTimerIfRunningAndRecordDelta(nextUnitOfWork, true);
19461 }
19462
19463 {
19464 // Reset global debug state
19465 // We assume this is defined in DEV
19466 resetCurrentlyProcessingQueue();
19467 }
19468
19469 if (true && replayFailedUnitOfWorkWithInvokeGuardedCallback) {
19470 if (mayReplay) {
19471 var failedUnitOfWork = nextUnitOfWork;
19472 replayUnitOfWork(failedUnitOfWork, thrownValue, isYieldy);
19473 }
19474 }
19475
19476 // TODO: we already know this isn't true in some cases.
19477 // At least this shows a nicer error message until we figure out the cause.
19478 // https://github.com/facebook/react/issues/12449#issuecomment-386727431
19479 !(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;
19480
19481 var sourceFiber = nextUnitOfWork;
19482 var returnFiber = sourceFiber.return;
19483 if (returnFiber === null) {
19484 // This is the root. The root could capture its own errors. However,
19485 // we don't know if it errors before or after we pushed the host
19486 // context. This information is needed to avoid a stack mismatch.
19487 // Because we're not sure, treat this as a fatal error. We could track
19488 // which phase it fails in, but doesn't seem worth it. At least
19489 // for now.
19490 didFatal = true;
19491 onUncaughtError(thrownValue);
19492 } else {
19493 throwException(root, returnFiber, sourceFiber, thrownValue, nextRenderExpirationTime);
19494 nextUnitOfWork = completeUnitOfWork(sourceFiber);
19495 continue;
19496 }
19497 }
19498 }
19499 break;
19500 } while (true);
19501
19502 if (enableSchedulerTracing) {
19503 // Traced work is done for now; restore the previous interactions.
19504 tracing.__interactionsRef.current = prevInteractions;
19505 }
19506
19507 // We're done performing work. Time to clean up.
19508 isWorking = false;
19509 ReactCurrentDispatcher.current = previousDispatcher;
19510 resetContextDependences();
19511 resetHooks();
19512
19513 // Yield back to main thread.
19514 if (didFatal) {
19515 var _didCompleteRoot = false;
19516 stopWorkLoopTimer(interruptedBy, _didCompleteRoot);
19517 interruptedBy = null;
19518 // There was a fatal error.
19519 {
19520 resetStackAfterFatalErrorInDev();
19521 }
19522 // `nextRoot` points to the in-progress root. A non-null value indicates
19523 // that we're in the middle of an async render. Set it to null to indicate
19524 // there's no more work to be done in the current batch.
19525 nextRoot = null;
19526 onFatal(root);
19527 return;
19528 }
19529
19530 if (nextUnitOfWork !== null) {
19531 // There's still remaining async work in this tree, but we ran out of time
19532 // in the current frame. Yield back to the renderer. Unless we're
19533 // interrupted by a higher priority update, we'll continue later from where
19534 // we left off.
19535 var _didCompleteRoot2 = false;
19536 stopWorkLoopTimer(interruptedBy, _didCompleteRoot2);
19537 interruptedBy = null;
19538 onYield(root);
19539 return;
19540 }
19541
19542 // We completed the whole tree.
19543 var didCompleteRoot = true;
19544 stopWorkLoopTimer(interruptedBy, didCompleteRoot);
19545 var rootWorkInProgress = root.current.alternate;
19546 !(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;
19547
19548 // `nextRoot` points to the in-progress root. A non-null value indicates
19549 // that we're in the middle of an async render. Set it to null to indicate
19550 // there's no more work to be done in the current batch.
19551 nextRoot = null;
19552 interruptedBy = null;
19553
19554 if (nextRenderDidError) {
19555 // There was an error
19556 if (hasLowerPriorityWork(root, expirationTime)) {
19557 // There's lower priority work. If so, it may have the effect of fixing
19558 // the exception that was just thrown. Exit without committing. This is
19559 // similar to a suspend, but without a timeout because we're not waiting
19560 // for a promise to resolve. React will restart at the lower
19561 // priority level.
19562 markSuspendedPriorityLevel(root, expirationTime);
19563 var suspendedExpirationTime = expirationTime;
19564 var rootExpirationTime = root.expirationTime;
19565 onSuspend(root, rootWorkInProgress, suspendedExpirationTime, rootExpirationTime, -1 // Indicates no timeout
19566 );
19567 return;
19568 } else if (
19569 // There's no lower priority work, but we're rendering asynchronously.
19570 // Synchronously attempt to render the same level one more time. This is
19571 // similar to a suspend, but without a timeout because we're not waiting
19572 // for a promise to resolve.
19573 !root.didError && isYieldy) {
19574 root.didError = true;
19575 var _suspendedExpirationTime = root.nextExpirationTimeToWorkOn = expirationTime;
19576 var _rootExpirationTime = root.expirationTime = Sync;
19577 onSuspend(root, rootWorkInProgress, _suspendedExpirationTime, _rootExpirationTime, -1 // Indicates no timeout
19578 );
19579 return;
19580 }
19581 }
19582
19583 if (isYieldy && nextLatestAbsoluteTimeoutMs !== -1) {
19584 // The tree was suspended.
19585 var _suspendedExpirationTime2 = expirationTime;
19586 markSuspendedPriorityLevel(root, _suspendedExpirationTime2);
19587
19588 // Find the earliest uncommitted expiration time in the tree, including
19589 // work that is suspended. The timeout threshold cannot be longer than
19590 // the overall expiration.
19591 var earliestExpirationTime = findEarliestOutstandingPriorityLevel(root, expirationTime);
19592 var earliestExpirationTimeMs = expirationTimeToMs(earliestExpirationTime);
19593 if (earliestExpirationTimeMs < nextLatestAbsoluteTimeoutMs) {
19594 nextLatestAbsoluteTimeoutMs = earliestExpirationTimeMs;
19595 }
19596
19597 // Subtract the current time from the absolute timeout to get the number
19598 // of milliseconds until the timeout. In other words, convert an absolute
19599 // timestamp to a relative time. This is the value that is passed
19600 // to `setTimeout`.
19601 var currentTimeMs = expirationTimeToMs(requestCurrentTime());
19602 var msUntilTimeout = nextLatestAbsoluteTimeoutMs - currentTimeMs;
19603 msUntilTimeout = msUntilTimeout < 0 ? 0 : msUntilTimeout;
19604
19605 // TODO: Account for the Just Noticeable Difference
19606
19607 var _rootExpirationTime2 = root.expirationTime;
19608 onSuspend(root, rootWorkInProgress, _suspendedExpirationTime2, _rootExpirationTime2, msUntilTimeout);
19609 return;
19610 }
19611
19612 // Ready to commit.
19613 onComplete(root, rootWorkInProgress, expirationTime);
19614}
19615
19616function captureCommitPhaseError(sourceFiber, value) {
19617 var expirationTime = Sync;
19618 var fiber = sourceFiber.return;
19619 while (fiber !== null) {
19620 switch (fiber.tag) {
19621 case ClassComponent:
19622 var ctor = fiber.type;
19623 var instance = fiber.stateNode;
19624 if (typeof ctor.getDerivedStateFromError === 'function' || typeof instance.componentDidCatch === 'function' && !isAlreadyFailedLegacyErrorBoundary(instance)) {
19625 var errorInfo = createCapturedValue(value, sourceFiber);
19626 var update = createClassErrorUpdate(fiber, errorInfo, expirationTime);
19627 enqueueUpdate(fiber, update);
19628 scheduleWork(fiber, expirationTime);
19629 return;
19630 }
19631 break;
19632 case HostRoot:
19633 {
19634 var _errorInfo = createCapturedValue(value, sourceFiber);
19635 var _update = createRootErrorUpdate(fiber, _errorInfo, expirationTime);
19636 enqueueUpdate(fiber, _update);
19637 scheduleWork(fiber, expirationTime);
19638 return;
19639 }
19640 }
19641 fiber = fiber.return;
19642 }
19643
19644 if (sourceFiber.tag === HostRoot) {
19645 // Error was thrown at the root. There is no parent, so the root
19646 // itself should capture it.
19647 var rootFiber = sourceFiber;
19648 var _errorInfo2 = createCapturedValue(value, rootFiber);
19649 var _update2 = createRootErrorUpdate(rootFiber, _errorInfo2, expirationTime);
19650 enqueueUpdate(rootFiber, _update2);
19651 scheduleWork(rootFiber, expirationTime);
19652 }
19653}
19654
19655function computeThreadID(expirationTime, interactionThreadID) {
19656 // Interaction threads are unique per root and expiration time.
19657 return expirationTime * 1000 + interactionThreadID;
19658}
19659
19660// Creates a unique async expiration time.
19661function computeUniqueAsyncExpiration() {
19662 var currentTime = requestCurrentTime();
19663 var result = computeAsyncExpiration(currentTime);
19664 if (result >= lastUniqueAsyncExpiration) {
19665 // Since we assume the current time monotonically increases, we only hit
19666 // this branch when computeUniqueAsyncExpiration is fired multiple times
19667 // within a 200ms window (or whatever the async bucket size is).
19668 result = lastUniqueAsyncExpiration - 1;
19669 }
19670 lastUniqueAsyncExpiration = result;
19671 return lastUniqueAsyncExpiration;
19672}
19673
19674function computeExpirationForFiber(currentTime, fiber) {
19675 var priorityLevel = scheduler.unstable_getCurrentPriorityLevel();
19676
19677 var expirationTime = void 0;
19678 if ((fiber.mode & ConcurrentMode) === NoContext) {
19679 // Outside of concurrent mode, updates are always synchronous.
19680 expirationTime = Sync;
19681 } else if (isWorking && !isCommitting$1) {
19682 // During render phase, updates expire during as the current render.
19683 expirationTime = nextRenderExpirationTime;
19684 } else {
19685 switch (priorityLevel) {
19686 case scheduler.unstable_ImmediatePriority:
19687 expirationTime = Sync;
19688 break;
19689 case scheduler.unstable_UserBlockingPriority:
19690 expirationTime = computeInteractiveExpiration(currentTime);
19691 break;
19692 case scheduler.unstable_NormalPriority:
19693 // This is a normal, concurrent update
19694 expirationTime = computeAsyncExpiration(currentTime);
19695 break;
19696 case scheduler.unstable_LowPriority:
19697 case scheduler.unstable_IdlePriority:
19698 expirationTime = Never;
19699 break;
19700 default:
19701 invariant(false, 'Unknown priority level. This error is likely caused by a bug in React. Please file an issue.');
19702 }
19703
19704 // If we're in the middle of rendering a tree, do not update at the same
19705 // expiration time that is already rendering.
19706 if (nextRoot !== null && expirationTime === nextRenderExpirationTime) {
19707 expirationTime -= 1;
19708 }
19709 }
19710
19711 // Keep track of the lowest pending interactive expiration time. This
19712 // allows us to synchronously flush all interactive updates
19713 // when needed.
19714 // TODO: Move this to renderer?
19715 if (priorityLevel === scheduler.unstable_UserBlockingPriority && (lowestPriorityPendingInteractiveExpirationTime === NoWork || expirationTime < lowestPriorityPendingInteractiveExpirationTime)) {
19716 lowestPriorityPendingInteractiveExpirationTime = expirationTime;
19717 }
19718
19719 return expirationTime;
19720}
19721
19722function renderDidSuspend(root, absoluteTimeoutMs, suspendedTime) {
19723 // Schedule the timeout.
19724 if (absoluteTimeoutMs >= 0 && nextLatestAbsoluteTimeoutMs < absoluteTimeoutMs) {
19725 nextLatestAbsoluteTimeoutMs = absoluteTimeoutMs;
19726 }
19727}
19728
19729function renderDidError() {
19730 nextRenderDidError = true;
19731}
19732
19733function pingSuspendedRoot(root, thenable, pingTime) {
19734 // A promise that previously suspended React from committing has resolved.
19735 // If React is still suspended, try again at the previous level (pingTime).
19736
19737 var pingCache = root.pingCache;
19738 if (pingCache !== null) {
19739 // The thenable resolved, so we no longer need to memoize, because it will
19740 // never be thrown again.
19741 pingCache.delete(thenable);
19742 }
19743
19744 if (nextRoot !== null && nextRenderExpirationTime === pingTime) {
19745 // Received a ping at the same priority level at which we're currently
19746 // rendering. Restart from the root.
19747 nextRoot = null;
19748 } else {
19749 // Confirm that the root is still suspended at this level. Otherwise exit.
19750 if (isPriorityLevelSuspended(root, pingTime)) {
19751 // Ping at the original level
19752 markPingedPriorityLevel(root, pingTime);
19753 var rootExpirationTime = root.expirationTime;
19754 if (rootExpirationTime !== NoWork) {
19755 requestWork(root, rootExpirationTime);
19756 }
19757 }
19758 }
19759}
19760
19761function retryTimedOutBoundary(boundaryFiber, thenable) {
19762 // The boundary fiber (a Suspense component) previously timed out and was
19763 // rendered in its fallback state. One of the promises that suspended it has
19764 // resolved, which means at least part of the tree was likely unblocked. Try
19765 var retryCache = void 0;
19766 if (enableSuspenseServerRenderer) {
19767 switch (boundaryFiber.tag) {
19768 case SuspenseComponent:
19769 retryCache = boundaryFiber.stateNode;
19770 break;
19771 case DehydratedSuspenseComponent:
19772 retryCache = boundaryFiber.memoizedState;
19773 break;
19774 default:
19775 invariant(false, 'Pinged unknown suspense boundary type. This is probably a bug in React.');
19776 }
19777 } else {
19778 retryCache = boundaryFiber.stateNode;
19779 }
19780 if (retryCache !== null) {
19781 // The thenable resolved, so we no longer need to memoize, because it will
19782 // never be thrown again.
19783 retryCache.delete(thenable);
19784 }
19785
19786 var currentTime = requestCurrentTime();
19787 var retryTime = computeExpirationForFiber(currentTime, boundaryFiber);
19788 var root = scheduleWorkToRoot(boundaryFiber, retryTime);
19789 if (root !== null) {
19790 markPendingPriorityLevel(root, retryTime);
19791 var rootExpirationTime = root.expirationTime;
19792 if (rootExpirationTime !== NoWork) {
19793 requestWork(root, rootExpirationTime);
19794 }
19795 }
19796}
19797
19798function scheduleWorkToRoot(fiber, expirationTime) {
19799 recordScheduleUpdate();
19800
19801 {
19802 if (fiber.tag === ClassComponent) {
19803 var instance = fiber.stateNode;
19804 warnAboutInvalidUpdates(instance);
19805 }
19806 }
19807
19808 // Update the source fiber's expiration time
19809 if (fiber.expirationTime < expirationTime) {
19810 fiber.expirationTime = expirationTime;
19811 }
19812 var alternate = fiber.alternate;
19813 if (alternate !== null && alternate.expirationTime < expirationTime) {
19814 alternate.expirationTime = expirationTime;
19815 }
19816 // Walk the parent path to the root and update the child expiration time.
19817 var node = fiber.return;
19818 var root = null;
19819 if (node === null && fiber.tag === HostRoot) {
19820 root = fiber.stateNode;
19821 } else {
19822 while (node !== null) {
19823 alternate = node.alternate;
19824 if (node.childExpirationTime < expirationTime) {
19825 node.childExpirationTime = expirationTime;
19826 if (alternate !== null && alternate.childExpirationTime < expirationTime) {
19827 alternate.childExpirationTime = expirationTime;
19828 }
19829 } else if (alternate !== null && alternate.childExpirationTime < expirationTime) {
19830 alternate.childExpirationTime = expirationTime;
19831 }
19832 if (node.return === null && node.tag === HostRoot) {
19833 root = node.stateNode;
19834 break;
19835 }
19836 node = node.return;
19837 }
19838 }
19839
19840 if (enableSchedulerTracing) {
19841 if (root !== null) {
19842 var interactions = tracing.__interactionsRef.current;
19843 if (interactions.size > 0) {
19844 var pendingInteractionMap = root.pendingInteractionMap;
19845 var pendingInteractions = pendingInteractionMap.get(expirationTime);
19846 if (pendingInteractions != null) {
19847 interactions.forEach(function (interaction) {
19848 if (!pendingInteractions.has(interaction)) {
19849 // Update the pending async work count for previously unscheduled interaction.
19850 interaction.__count++;
19851 }
19852
19853 pendingInteractions.add(interaction);
19854 });
19855 } else {
19856 pendingInteractionMap.set(expirationTime, new Set(interactions));
19857
19858 // Update the pending async work count for the current interactions.
19859 interactions.forEach(function (interaction) {
19860 interaction.__count++;
19861 });
19862 }
19863
19864 var subscriber = tracing.__subscriberRef.current;
19865 if (subscriber !== null) {
19866 var threadID = computeThreadID(expirationTime, root.interactionThreadID);
19867 subscriber.onWorkScheduled(interactions, threadID);
19868 }
19869 }
19870 }
19871 }
19872 return root;
19873}
19874
19875function warnIfNotCurrentlyBatchingInDev(fiber) {
19876 {
19877 if (isRendering === false && isBatchingUpdates === false) {
19878 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));
19879 }
19880 }
19881}
19882
19883function scheduleWork(fiber, expirationTime) {
19884 var root = scheduleWorkToRoot(fiber, expirationTime);
19885 if (root === null) {
19886 {
19887 switch (fiber.tag) {
19888 case ClassComponent:
19889 warnAboutUpdateOnUnmounted(fiber, true);
19890 break;
19891 case FunctionComponent:
19892 case ForwardRef:
19893 case MemoComponent:
19894 case SimpleMemoComponent:
19895 warnAboutUpdateOnUnmounted(fiber, false);
19896 break;
19897 }
19898 }
19899 return;
19900 }
19901
19902 if (!isWorking && nextRenderExpirationTime !== NoWork && expirationTime > nextRenderExpirationTime) {
19903 // This is an interruption. (Used for performance tracking.)
19904 interruptedBy = fiber;
19905 resetStack();
19906 }
19907 markPendingPriorityLevel(root, expirationTime);
19908 if (
19909 // If we're in the render phase, we don't need to schedule this root
19910 // for an update, because we'll do it before we exit...
19911 !isWorking || isCommitting$1 ||
19912 // ...unless this is a different root than the one we're rendering.
19913 nextRoot !== root) {
19914 var rootExpirationTime = root.expirationTime;
19915 requestWork(root, rootExpirationTime);
19916 }
19917 if (nestedUpdateCount > NESTED_UPDATE_LIMIT) {
19918 // Reset this back to zero so subsequent updates don't throw.
19919 nestedUpdateCount = 0;
19920 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.');
19921 }
19922}
19923
19924function syncUpdates(fn, a, b, c, d) {
19925 return scheduler.unstable_runWithPriority(scheduler.unstable_ImmediatePriority, function () {
19926 return fn(a, b, c, d);
19927 });
19928}
19929
19930// TODO: Everything below this is written as if it has been lifted to the
19931// renderers. I'll do this in a follow-up.
19932
19933// Linked-list of roots
19934var firstScheduledRoot = null;
19935var lastScheduledRoot = null;
19936
19937var callbackExpirationTime = NoWork;
19938var callbackID = void 0;
19939var isRendering = false;
19940var nextFlushedRoot = null;
19941var nextFlushedExpirationTime = NoWork;
19942var lowestPriorityPendingInteractiveExpirationTime = NoWork;
19943var hasUnhandledError = false;
19944var unhandledError = null;
19945
19946var isBatchingUpdates = false;
19947var isUnbatchingUpdates = false;
19948
19949var completedBatches = null;
19950
19951var originalStartTimeMs = scheduler.unstable_now();
19952var currentRendererTime = msToExpirationTime(originalStartTimeMs);
19953var currentSchedulerTime = currentRendererTime;
19954
19955// Use these to prevent an infinite loop of nested updates
19956var NESTED_UPDATE_LIMIT = 50;
19957var nestedUpdateCount = 0;
19958var lastCommittedRootDuringThisBatch = null;
19959
19960function recomputeCurrentRendererTime() {
19961 var currentTimeMs = scheduler.unstable_now() - originalStartTimeMs;
19962 currentRendererTime = msToExpirationTime(currentTimeMs);
19963}
19964
19965function scheduleCallbackWithExpirationTime(root, expirationTime) {
19966 if (callbackExpirationTime !== NoWork) {
19967 // A callback is already scheduled. Check its expiration time (timeout).
19968 if (expirationTime < callbackExpirationTime) {
19969 // Existing callback has sufficient timeout. Exit.
19970 return;
19971 } else {
19972 if (callbackID !== null) {
19973 // Existing callback has insufficient timeout. Cancel and schedule a
19974 // new one.
19975 scheduler.unstable_cancelCallback(callbackID);
19976 }
19977 }
19978 // The request callback timer is already running. Don't start a new one.
19979 } else {
19980 startRequestCallbackTimer();
19981 }
19982
19983 callbackExpirationTime = expirationTime;
19984 var currentMs = scheduler.unstable_now() - originalStartTimeMs;
19985 var expirationTimeMs = expirationTimeToMs(expirationTime);
19986 var timeout = expirationTimeMs - currentMs;
19987 callbackID = scheduler.unstable_scheduleCallback(performAsyncWork, { timeout: timeout });
19988}
19989
19990// For every call to renderRoot, one of onFatal, onComplete, onSuspend, and
19991// onYield is called upon exiting. We use these in lieu of returning a tuple.
19992// I've also chosen not to inline them into renderRoot because these will
19993// eventually be lifted into the renderer.
19994function onFatal(root) {
19995 root.finishedWork = null;
19996}
19997
19998function onComplete(root, finishedWork, expirationTime) {
19999 root.pendingCommitExpirationTime = expirationTime;
20000 root.finishedWork = finishedWork;
20001}
20002
20003function onSuspend(root, finishedWork, suspendedExpirationTime, rootExpirationTime, msUntilTimeout) {
20004 root.expirationTime = rootExpirationTime;
20005 if (msUntilTimeout === 0 && !shouldYieldToRenderer()) {
20006 // Don't wait an additional tick. Commit the tree immediately.
20007 root.pendingCommitExpirationTime = suspendedExpirationTime;
20008 root.finishedWork = finishedWork;
20009 } else if (msUntilTimeout > 0) {
20010 // Wait `msUntilTimeout` milliseconds before committing.
20011 root.timeoutHandle = scheduleTimeout(onTimeout.bind(null, root, finishedWork, suspendedExpirationTime), msUntilTimeout);
20012 }
20013}
20014
20015function onYield(root) {
20016 root.finishedWork = null;
20017}
20018
20019function onTimeout(root, finishedWork, suspendedExpirationTime) {
20020 // The root timed out. Commit it.
20021 root.pendingCommitExpirationTime = suspendedExpirationTime;
20022 root.finishedWork = finishedWork;
20023 // Read the current time before entering the commit phase. We can be
20024 // certain this won't cause tearing related to batching of event updates
20025 // because we're at the top of a timer event.
20026 recomputeCurrentRendererTime();
20027 currentSchedulerTime = currentRendererTime;
20028 flushRoot(root, suspendedExpirationTime);
20029}
20030
20031function onCommit(root, expirationTime) {
20032 root.expirationTime = expirationTime;
20033 root.finishedWork = null;
20034}
20035
20036function requestCurrentTime() {
20037 // requestCurrentTime is called by the scheduler to compute an expiration
20038 // time.
20039 //
20040 // Expiration times are computed by adding to the current time (the start
20041 // time). However, if two updates are scheduled within the same event, we
20042 // should treat their start times as simultaneous, even if the actual clock
20043 // time has advanced between the first and second call.
20044
20045 // In other words, because expiration times determine how updates are batched,
20046 // we want all updates of like priority that occur within the same event to
20047 // receive the same expiration time. Otherwise we get tearing.
20048 //
20049 // We keep track of two separate times: the current "renderer" time and the
20050 // current "scheduler" time. The renderer time can be updated whenever; it
20051 // only exists to minimize the calls performance.now.
20052 //
20053 // But the scheduler time can only be updated if there's no pending work, or
20054 // if we know for certain that we're not in the middle of an event.
20055
20056 if (isRendering) {
20057 // We're already rendering. Return the most recently read time.
20058 return currentSchedulerTime;
20059 }
20060 // Check if there's pending work.
20061 findHighestPriorityRoot();
20062 if (nextFlushedExpirationTime === NoWork || nextFlushedExpirationTime === Never) {
20063 // If there's no pending work, or if the pending work is offscreen, we can
20064 // read the current time without risk of tearing.
20065 recomputeCurrentRendererTime();
20066 currentSchedulerTime = currentRendererTime;
20067 return currentSchedulerTime;
20068 }
20069 // There's already pending work. We might be in the middle of a browser
20070 // event. If we were to read the current time, it could cause multiple updates
20071 // within the same event to receive different expiration times, leading to
20072 // tearing. Return the last read time. During the next idle callback, the
20073 // time will be updated.
20074 return currentSchedulerTime;
20075}
20076
20077// requestWork is called by the scheduler whenever a root receives an update.
20078// It's up to the renderer to call renderRoot at some point in the future.
20079function requestWork(root, expirationTime) {
20080 addRootToSchedule(root, expirationTime);
20081 if (isRendering) {
20082 // Prevent reentrancy. Remaining work will be scheduled at the end of
20083 // the currently rendering batch.
20084 return;
20085 }
20086
20087 if (isBatchingUpdates) {
20088 // Flush work at the end of the batch.
20089 if (isUnbatchingUpdates) {
20090 // ...unless we're inside unbatchedUpdates, in which case we should
20091 // flush it now.
20092 nextFlushedRoot = root;
20093 nextFlushedExpirationTime = Sync;
20094 performWorkOnRoot(root, Sync, false);
20095 }
20096 return;
20097 }
20098
20099 // TODO: Get rid of Sync and use current time?
20100 if (expirationTime === Sync) {
20101 performSyncWork();
20102 } else {
20103 scheduleCallbackWithExpirationTime(root, expirationTime);
20104 }
20105}
20106
20107function addRootToSchedule(root, expirationTime) {
20108 // Add the root to the schedule.
20109 // Check if this root is already part of the schedule.
20110 if (root.nextScheduledRoot === null) {
20111 // This root is not already scheduled. Add it.
20112 root.expirationTime = expirationTime;
20113 if (lastScheduledRoot === null) {
20114 firstScheduledRoot = lastScheduledRoot = root;
20115 root.nextScheduledRoot = root;
20116 } else {
20117 lastScheduledRoot.nextScheduledRoot = root;
20118 lastScheduledRoot = root;
20119 lastScheduledRoot.nextScheduledRoot = firstScheduledRoot;
20120 }
20121 } else {
20122 // This root is already scheduled, but its priority may have increased.
20123 var remainingExpirationTime = root.expirationTime;
20124 if (expirationTime > remainingExpirationTime) {
20125 // Update the priority.
20126 root.expirationTime = expirationTime;
20127 }
20128 }
20129}
20130
20131function findHighestPriorityRoot() {
20132 var highestPriorityWork = NoWork;
20133 var highestPriorityRoot = null;
20134 if (lastScheduledRoot !== null) {
20135 var previousScheduledRoot = lastScheduledRoot;
20136 var root = firstScheduledRoot;
20137 while (root !== null) {
20138 var remainingExpirationTime = root.expirationTime;
20139 if (remainingExpirationTime === NoWork) {
20140 // This root no longer has work. Remove it from the scheduler.
20141
20142 // TODO: This check is redudant, but Flow is confused by the branch
20143 // below where we set lastScheduledRoot to null, even though we break
20144 // from the loop right after.
20145 !(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;
20146 if (root === root.nextScheduledRoot) {
20147 // This is the only root in the list.
20148 root.nextScheduledRoot = null;
20149 firstScheduledRoot = lastScheduledRoot = null;
20150 break;
20151 } else if (root === firstScheduledRoot) {
20152 // This is the first root in the list.
20153 var next = root.nextScheduledRoot;
20154 firstScheduledRoot = next;
20155 lastScheduledRoot.nextScheduledRoot = next;
20156 root.nextScheduledRoot = null;
20157 } else if (root === lastScheduledRoot) {
20158 // This is the last root in the list.
20159 lastScheduledRoot = previousScheduledRoot;
20160 lastScheduledRoot.nextScheduledRoot = firstScheduledRoot;
20161 root.nextScheduledRoot = null;
20162 break;
20163 } else {
20164 previousScheduledRoot.nextScheduledRoot = root.nextScheduledRoot;
20165 root.nextScheduledRoot = null;
20166 }
20167 root = previousScheduledRoot.nextScheduledRoot;
20168 } else {
20169 if (remainingExpirationTime > highestPriorityWork) {
20170 // Update the priority, if it's higher
20171 highestPriorityWork = remainingExpirationTime;
20172 highestPriorityRoot = root;
20173 }
20174 if (root === lastScheduledRoot) {
20175 break;
20176 }
20177 if (highestPriorityWork === Sync) {
20178 // Sync is highest priority by definition so
20179 // we can stop searching.
20180 break;
20181 }
20182 previousScheduledRoot = root;
20183 root = root.nextScheduledRoot;
20184 }
20185 }
20186 }
20187
20188 nextFlushedRoot = highestPriorityRoot;
20189 nextFlushedExpirationTime = highestPriorityWork;
20190}
20191
20192// TODO: This wrapper exists because many of the older tests (the ones that use
20193// flushDeferredPri) rely on the number of times `shouldYield` is called. We
20194// should get rid of it.
20195var didYield = false;
20196function shouldYieldToRenderer() {
20197 if (didYield) {
20198 return true;
20199 }
20200 if (scheduler.unstable_shouldYield()) {
20201 didYield = true;
20202 return true;
20203 }
20204 return false;
20205}
20206
20207function performAsyncWork() {
20208 try {
20209 if (!shouldYieldToRenderer()) {
20210 // The callback timed out. That means at least one update has expired.
20211 // Iterate through the root schedule. If they contain expired work, set
20212 // the next render expiration time to the current time. This has the effect
20213 // of flushing all expired work in a single batch, instead of flushing each
20214 // level one at a time.
20215 if (firstScheduledRoot !== null) {
20216 recomputeCurrentRendererTime();
20217 var root = firstScheduledRoot;
20218 do {
20219 didExpireAtExpirationTime(root, currentRendererTime);
20220 // The root schedule is circular, so this is never null.
20221 root = root.nextScheduledRoot;
20222 } while (root !== firstScheduledRoot);
20223 }
20224 }
20225 performWork(NoWork, true);
20226 } finally {
20227 didYield = false;
20228 }
20229}
20230
20231function performSyncWork() {
20232 performWork(Sync, false);
20233}
20234
20235function performWork(minExpirationTime, isYieldy) {
20236 // Keep working on roots until there's no more work, or until there's a higher
20237 // priority event.
20238 findHighestPriorityRoot();
20239
20240 if (isYieldy) {
20241 recomputeCurrentRendererTime();
20242 currentSchedulerTime = currentRendererTime;
20243
20244 if (enableUserTimingAPI) {
20245 var didExpire = nextFlushedExpirationTime > currentRendererTime;
20246 var timeout = expirationTimeToMs(nextFlushedExpirationTime);
20247 stopRequestCallbackTimer(didExpire, timeout);
20248 }
20249
20250 while (nextFlushedRoot !== null && nextFlushedExpirationTime !== NoWork && minExpirationTime <= nextFlushedExpirationTime && !(didYield && currentRendererTime > nextFlushedExpirationTime)) {
20251 performWorkOnRoot(nextFlushedRoot, nextFlushedExpirationTime, currentRendererTime > nextFlushedExpirationTime);
20252 findHighestPriorityRoot();
20253 recomputeCurrentRendererTime();
20254 currentSchedulerTime = currentRendererTime;
20255 }
20256 } else {
20257 while (nextFlushedRoot !== null && nextFlushedExpirationTime !== NoWork && minExpirationTime <= nextFlushedExpirationTime) {
20258 performWorkOnRoot(nextFlushedRoot, nextFlushedExpirationTime, false);
20259 findHighestPriorityRoot();
20260 }
20261 }
20262
20263 // We're done flushing work. Either we ran out of time in this callback,
20264 // or there's no more work left with sufficient priority.
20265
20266 // If we're inside a callback, set this to false since we just completed it.
20267 if (isYieldy) {
20268 callbackExpirationTime = NoWork;
20269 callbackID = null;
20270 }
20271 // If there's work left over, schedule a new callback.
20272 if (nextFlushedExpirationTime !== NoWork) {
20273 scheduleCallbackWithExpirationTime(nextFlushedRoot, nextFlushedExpirationTime);
20274 }
20275
20276 // Clean-up.
20277 finishRendering();
20278}
20279
20280function flushRoot(root, expirationTime) {
20281 !!isRendering ? invariant(false, 'work.commit(): Cannot commit while already rendering. This likely means you attempted to commit from inside a lifecycle method.') : void 0;
20282 // Perform work on root as if the given expiration time is the current time.
20283 // This has the effect of synchronously flushing all work up to and
20284 // including the given time.
20285 nextFlushedRoot = root;
20286 nextFlushedExpirationTime = expirationTime;
20287 performWorkOnRoot(root, expirationTime, false);
20288 // Flush any sync work that was scheduled by lifecycles
20289 performSyncWork();
20290}
20291
20292function finishRendering() {
20293 nestedUpdateCount = 0;
20294 lastCommittedRootDuringThisBatch = null;
20295
20296 if (completedBatches !== null) {
20297 var batches = completedBatches;
20298 completedBatches = null;
20299 for (var i = 0; i < batches.length; i++) {
20300 var batch = batches[i];
20301 try {
20302 batch._onComplete();
20303 } catch (error) {
20304 if (!hasUnhandledError) {
20305 hasUnhandledError = true;
20306 unhandledError = error;
20307 }
20308 }
20309 }
20310 }
20311
20312 if (hasUnhandledError) {
20313 var error = unhandledError;
20314 unhandledError = null;
20315 hasUnhandledError = false;
20316 throw error;
20317 }
20318}
20319
20320function performWorkOnRoot(root, expirationTime, isYieldy) {
20321 !!isRendering ? invariant(false, 'performWorkOnRoot was called recursively. This error is likely caused by a bug in React. Please file an issue.') : void 0;
20322
20323 isRendering = true;
20324
20325 // Check if this is async work or sync/expired work.
20326 if (!isYieldy) {
20327 // Flush work without yielding.
20328 // TODO: Non-yieldy work does not necessarily imply expired work. A renderer
20329 // may want to perform some work without yielding, but also without
20330 // requiring the root to complete (by triggering placeholders).
20331
20332 var finishedWork = root.finishedWork;
20333 if (finishedWork !== null) {
20334 // This root is already complete. We can commit it.
20335 completeRoot(root, finishedWork, expirationTime);
20336 } else {
20337 root.finishedWork = null;
20338 // If this root previously suspended, clear its existing timeout, since
20339 // we're about to try rendering again.
20340 var timeoutHandle = root.timeoutHandle;
20341 if (timeoutHandle !== noTimeout) {
20342 root.timeoutHandle = noTimeout;
20343 // $FlowFixMe Complains noTimeout is not a TimeoutID, despite the check above
20344 cancelTimeout(timeoutHandle);
20345 }
20346 renderRoot(root, isYieldy);
20347 finishedWork = root.finishedWork;
20348 if (finishedWork !== null) {
20349 // We've completed the root. Commit it.
20350 completeRoot(root, finishedWork, expirationTime);
20351 }
20352 }
20353 } else {
20354 // Flush async work.
20355 var _finishedWork = root.finishedWork;
20356 if (_finishedWork !== null) {
20357 // This root is already complete. We can commit it.
20358 completeRoot(root, _finishedWork, expirationTime);
20359 } else {
20360 root.finishedWork = null;
20361 // If this root previously suspended, clear its existing timeout, since
20362 // we're about to try rendering again.
20363 var _timeoutHandle = root.timeoutHandle;
20364 if (_timeoutHandle !== noTimeout) {
20365 root.timeoutHandle = noTimeout;
20366 // $FlowFixMe Complains noTimeout is not a TimeoutID, despite the check above
20367 cancelTimeout(_timeoutHandle);
20368 }
20369 renderRoot(root, isYieldy);
20370 _finishedWork = root.finishedWork;
20371 if (_finishedWork !== null) {
20372 // We've completed the root. Check the if we should yield one more time
20373 // before committing.
20374 if (!shouldYieldToRenderer()) {
20375 // Still time left. Commit the root.
20376 completeRoot(root, _finishedWork, expirationTime);
20377 } else {
20378 // There's no time left. Mark this root as complete. We'll come
20379 // back and commit it later.
20380 root.finishedWork = _finishedWork;
20381 }
20382 }
20383 }
20384 }
20385
20386 isRendering = false;
20387}
20388
20389function completeRoot(root, finishedWork, expirationTime) {
20390 // Check if there's a batch that matches this expiration time.
20391 var firstBatch = root.firstBatch;
20392 if (firstBatch !== null && firstBatch._expirationTime >= expirationTime) {
20393 if (completedBatches === null) {
20394 completedBatches = [firstBatch];
20395 } else {
20396 completedBatches.push(firstBatch);
20397 }
20398 if (firstBatch._defer) {
20399 // This root is blocked from committing by a batch. Unschedule it until
20400 // we receive another update.
20401 root.finishedWork = finishedWork;
20402 root.expirationTime = NoWork;
20403 return;
20404 }
20405 }
20406
20407 // Commit the root.
20408 root.finishedWork = null;
20409
20410 // Check if this is a nested update (a sync update scheduled during the
20411 // commit phase).
20412 if (root === lastCommittedRootDuringThisBatch) {
20413 // If the next root is the same as the previous root, this is a nested
20414 // update. To prevent an infinite loop, increment the nested update count.
20415 nestedUpdateCount++;
20416 } else {
20417 // Reset whenever we switch roots.
20418 lastCommittedRootDuringThisBatch = root;
20419 nestedUpdateCount = 0;
20420 }
20421 scheduler.unstable_runWithPriority(scheduler.unstable_ImmediatePriority, function () {
20422 commitRoot(root, finishedWork);
20423 });
20424}
20425
20426function onUncaughtError(error) {
20427 !(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;
20428 // Unschedule this root so we don't work on it again until there's
20429 // another update.
20430 nextFlushedRoot.expirationTime = NoWork;
20431 if (!hasUnhandledError) {
20432 hasUnhandledError = true;
20433 unhandledError = error;
20434 }
20435}
20436
20437// TODO: Batching should be implemented at the renderer level, not inside
20438// the reconciler.
20439function batchedUpdates$1(fn, a) {
20440 var previousIsBatchingUpdates = isBatchingUpdates;
20441 isBatchingUpdates = true;
20442 try {
20443 return fn(a);
20444 } finally {
20445 isBatchingUpdates = previousIsBatchingUpdates;
20446 if (!isBatchingUpdates && !isRendering) {
20447 performSyncWork();
20448 }
20449 }
20450}
20451
20452// TODO: Batching should be implemented at the renderer level, not inside
20453// the reconciler.
20454function unbatchedUpdates(fn, a) {
20455 if (isBatchingUpdates && !isUnbatchingUpdates) {
20456 isUnbatchingUpdates = true;
20457 try {
20458 return fn(a);
20459 } finally {
20460 isUnbatchingUpdates = false;
20461 }
20462 }
20463 return fn(a);
20464}
20465
20466// TODO: Batching should be implemented at the renderer level, not within
20467// the reconciler.
20468function flushSync(fn, a) {
20469 !!isRendering ? invariant(false, 'flushSync was called from inside a lifecycle method. It cannot be called when React is already rendering.') : void 0;
20470 var previousIsBatchingUpdates = isBatchingUpdates;
20471 isBatchingUpdates = true;
20472 try {
20473 return syncUpdates(fn, a);
20474 } finally {
20475 isBatchingUpdates = previousIsBatchingUpdates;
20476 performSyncWork();
20477 }
20478}
20479
20480function interactiveUpdates$1(fn, a, b) {
20481 // If there are any pending interactive updates, synchronously flush them.
20482 // This needs to happen before we read any handlers, because the effect of
20483 // the previous event may influence which handlers are called during
20484 // this event.
20485 if (!isBatchingUpdates && !isRendering && lowestPriorityPendingInteractiveExpirationTime !== NoWork) {
20486 // Synchronously flush pending interactive updates.
20487 performWork(lowestPriorityPendingInteractiveExpirationTime, false);
20488 lowestPriorityPendingInteractiveExpirationTime = NoWork;
20489 }
20490 var previousIsBatchingUpdates = isBatchingUpdates;
20491 isBatchingUpdates = true;
20492 try {
20493 return scheduler.unstable_runWithPriority(scheduler.unstable_UserBlockingPriority, function () {
20494 return fn(a, b);
20495 });
20496 } finally {
20497 isBatchingUpdates = previousIsBatchingUpdates;
20498 if (!isBatchingUpdates && !isRendering) {
20499 performSyncWork();
20500 }
20501 }
20502}
20503
20504function flushInteractiveUpdates$1() {
20505 if (!isRendering && lowestPriorityPendingInteractiveExpirationTime !== NoWork) {
20506 // Synchronously flush pending interactive updates.
20507 performWork(lowestPriorityPendingInteractiveExpirationTime, false);
20508 lowestPriorityPendingInteractiveExpirationTime = NoWork;
20509 }
20510}
20511
20512function flushControlled(fn) {
20513 var previousIsBatchingUpdates = isBatchingUpdates;
20514 isBatchingUpdates = true;
20515 try {
20516 syncUpdates(fn);
20517 } finally {
20518 isBatchingUpdates = previousIsBatchingUpdates;
20519 if (!isBatchingUpdates && !isRendering) {
20520 performSyncWork();
20521 }
20522 }
20523}
20524
20525// 0 is PROD, 1 is DEV.
20526// Might add PROFILE later.
20527
20528
20529var didWarnAboutNestedUpdates = void 0;
20530var didWarnAboutFindNodeInStrictMode = void 0;
20531
20532{
20533 didWarnAboutNestedUpdates = false;
20534 didWarnAboutFindNodeInStrictMode = {};
20535}
20536
20537function getContextForSubtree(parentComponent) {
20538 if (!parentComponent) {
20539 return emptyContextObject;
20540 }
20541
20542 var fiber = get(parentComponent);
20543 var parentContext = findCurrentUnmaskedContext(fiber);
20544
20545 if (fiber.tag === ClassComponent) {
20546 var Component = fiber.type;
20547 if (isContextProvider(Component)) {
20548 return processChildContext(fiber, Component, parentContext);
20549 }
20550 }
20551
20552 return parentContext;
20553}
20554
20555function scheduleRootUpdate(current$$1, element, expirationTime, callback) {
20556 {
20557 if (phase === 'render' && current !== null && !didWarnAboutNestedUpdates) {
20558 didWarnAboutNestedUpdates = true;
20559 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');
20560 }
20561 }
20562
20563 var update = createUpdate(expirationTime);
20564 // Caution: React DevTools currently depends on this property
20565 // being called "element".
20566 update.payload = { element: element };
20567
20568 callback = callback === undefined ? null : callback;
20569 if (callback !== null) {
20570 !(typeof callback === 'function') ? warningWithoutStack$1(false, 'render(...): Expected the last optional `callback` argument to be a ' + 'function. Instead received: %s.', callback) : void 0;
20571 update.callback = callback;
20572 }
20573
20574 flushPassiveEffects();
20575 enqueueUpdate(current$$1, update);
20576 scheduleWork(current$$1, expirationTime);
20577
20578 return expirationTime;
20579}
20580
20581function updateContainerAtExpirationTime(element, container, parentComponent, expirationTime, callback) {
20582 // TODO: If this is a nested container, this won't be the root.
20583 var current$$1 = container.current;
20584
20585 {
20586 if (ReactFiberInstrumentation_1.debugTool) {
20587 if (current$$1.alternate === null) {
20588 ReactFiberInstrumentation_1.debugTool.onMountContainer(container);
20589 } else if (element === null) {
20590 ReactFiberInstrumentation_1.debugTool.onUnmountContainer(container);
20591 } else {
20592 ReactFiberInstrumentation_1.debugTool.onUpdateContainer(container);
20593 }
20594 }
20595 }
20596
20597 var context = getContextForSubtree(parentComponent);
20598 if (container.context === null) {
20599 container.context = context;
20600 } else {
20601 container.pendingContext = context;
20602 }
20603
20604 return scheduleRootUpdate(current$$1, element, expirationTime, callback);
20605}
20606
20607function findHostInstance(component) {
20608 var fiber = get(component);
20609 if (fiber === undefined) {
20610 if (typeof component.render === 'function') {
20611 invariant(false, 'Unable to find node on an unmounted component.');
20612 } else {
20613 invariant(false, 'Argument appears to not be a ReactComponent. Keys: %s', Object.keys(component));
20614 }
20615 }
20616 var hostFiber = findCurrentHostFiber(fiber);
20617 if (hostFiber === null) {
20618 return null;
20619 }
20620 return hostFiber.stateNode;
20621}
20622
20623function findHostInstanceWithWarning(component, methodName) {
20624 {
20625 var fiber = get(component);
20626 if (fiber === undefined) {
20627 if (typeof component.render === 'function') {
20628 invariant(false, 'Unable to find node on an unmounted component.');
20629 } else {
20630 invariant(false, 'Argument appears to not be a ReactComponent. Keys: %s', Object.keys(component));
20631 }
20632 }
20633 var hostFiber = findCurrentHostFiber(fiber);
20634 if (hostFiber === null) {
20635 return null;
20636 }
20637 if (hostFiber.mode & StrictMode) {
20638 var componentName = getComponentName(fiber.type) || 'Component';
20639 if (!didWarnAboutFindNodeInStrictMode[componentName]) {
20640 didWarnAboutFindNodeInStrictMode[componentName] = true;
20641 if (fiber.mode & StrictMode) {
20642 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));
20643 } else {
20644 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));
20645 }
20646 }
20647 }
20648 return hostFiber.stateNode;
20649 }
20650 return findHostInstance(component);
20651}
20652
20653function createContainer(containerInfo, isConcurrent, hydrate) {
20654 return createFiberRoot(containerInfo, isConcurrent, hydrate);
20655}
20656
20657function updateContainer(element, container, parentComponent, callback) {
20658 var current$$1 = container.current;
20659 var currentTime = requestCurrentTime();
20660 var expirationTime = computeExpirationForFiber(currentTime, current$$1);
20661 return updateContainerAtExpirationTime(element, container, parentComponent, expirationTime, callback);
20662}
20663
20664function getPublicRootInstance(container) {
20665 var containerFiber = container.current;
20666 if (!containerFiber.child) {
20667 return null;
20668 }
20669 switch (containerFiber.child.tag) {
20670 case HostComponent:
20671 return getPublicInstance(containerFiber.child.stateNode);
20672 default:
20673 return containerFiber.child.stateNode;
20674 }
20675}
20676
20677function findHostInstanceWithNoPortals(fiber) {
20678 var hostFiber = findCurrentHostFiberWithNoPortals(fiber);
20679 if (hostFiber === null) {
20680 return null;
20681 }
20682 return hostFiber.stateNode;
20683}
20684
20685var overrideProps = null;
20686
20687{
20688 var copyWithSetImpl = function (obj, path, idx, value) {
20689 if (idx >= path.length) {
20690 return value;
20691 }
20692 var key = path[idx];
20693 var updated = Array.isArray(obj) ? obj.slice() : _assign({}, obj);
20694 // $FlowFixMe number or string is fine here
20695 updated[key] = copyWithSetImpl(obj[key], path, idx + 1, value);
20696 return updated;
20697 };
20698
20699 var copyWithSet = function (obj, path, value) {
20700 return copyWithSetImpl(obj, path, 0, value);
20701 };
20702
20703 // Support DevTools props for function components, forwardRef, memo, host components, etc.
20704 overrideProps = function (fiber, path, value) {
20705 flushPassiveEffects();
20706 fiber.pendingProps = copyWithSet(fiber.memoizedProps, path, value);
20707 if (fiber.alternate) {
20708 fiber.alternate.pendingProps = fiber.pendingProps;
20709 }
20710 scheduleWork(fiber, Sync);
20711 };
20712}
20713
20714function injectIntoDevTools(devToolsConfig) {
20715 var findFiberByHostInstance = devToolsConfig.findFiberByHostInstance;
20716 var ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher;
20717
20718
20719 return injectInternals(_assign({}, devToolsConfig, {
20720 overrideProps: overrideProps,
20721 currentDispatcherRef: ReactCurrentDispatcher,
20722 findHostInstanceByFiber: function (fiber) {
20723 var hostFiber = findCurrentHostFiber(fiber);
20724 if (hostFiber === null) {
20725 return null;
20726 }
20727 return hostFiber.stateNode;
20728 },
20729 findFiberByHostInstance: function (instance) {
20730 if (!findFiberByHostInstance) {
20731 // Might not be implemented by the renderer.
20732 return null;
20733 }
20734 return findFiberByHostInstance(instance);
20735 }
20736 }));
20737}
20738
20739// This file intentionally does *not* have the Flow annotation.
20740// Don't add it. See `./inline-typed.js` for an explanation.
20741
20742function createPortal$1(children, containerInfo,
20743// TODO: figure out the API for cross-renderer implementation.
20744implementation) {
20745 var key = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null;
20746
20747 return {
20748 // This tag allow us to uniquely identify this as a React Portal
20749 $$typeof: REACT_PORTAL_TYPE,
20750 key: key == null ? null : '' + key,
20751 children: children,
20752 containerInfo: containerInfo,
20753 implementation: implementation
20754 };
20755}
20756
20757// TODO: this is special because it gets imported during build.
20758
20759var ReactVersion = '16.8.6';
20760
20761// This file is copy paste from ReactDOM with adjusted paths
20762// and a different host config import (react-reconciler/inline.fire).
20763// TODO: real implementation.
20764// console.log('Hello from Fire entry point.');
20765
20766// TODO: This type is shared between the reconciler and ReactDOM, but will
20767// eventually be lifted out to the renderer.
20768
20769var ReactCurrentOwner = ReactSharedInternals.ReactCurrentOwner;
20770
20771var topLevelUpdateWarnings = void 0;
20772var warnOnInvalidCallback = void 0;
20773var didWarnAboutUnstableCreatePortal = false;
20774
20775{
20776 if (typeof Map !== 'function' ||
20777 // $FlowIssue Flow incorrectly thinks Map has no prototype
20778 Map.prototype == null || typeof Map.prototype.forEach !== 'function' || typeof Set !== 'function' ||
20779 // $FlowIssue Flow incorrectly thinks Set has no prototype
20780 Set.prototype == null || typeof Set.prototype.clear !== 'function' || typeof Set.prototype.forEach !== 'function') {
20781 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');
20782 }
20783
20784 topLevelUpdateWarnings = function (container) {
20785 if (container._reactRootContainer && container.nodeType !== COMMENT_NODE) {
20786 var hostInstance = findHostInstanceWithNoPortals(container._reactRootContainer._internalRoot.current);
20787 if (hostInstance) {
20788 !(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;
20789 }
20790 }
20791
20792 var isRootRenderedBySomeReact = !!container._reactRootContainer;
20793 var rootEl = getReactRootElementInContainer(container);
20794 var hasNonRootReactChild = !!(rootEl && getInstanceFromNode$1(rootEl));
20795
20796 !(!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;
20797
20798 !(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;
20799 };
20800
20801 warnOnInvalidCallback = function (callback, callerName) {
20802 !(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;
20803 };
20804}
20805
20806setRestoreImplementation(restoreControlledState$1);
20807
20808function ReactBatch(root) {
20809 var expirationTime = computeUniqueAsyncExpiration();
20810 this._expirationTime = expirationTime;
20811 this._root = root;
20812 this._next = null;
20813 this._callbacks = null;
20814 this._didComplete = false;
20815 this._hasChildren = false;
20816 this._children = null;
20817 this._defer = true;
20818}
20819ReactBatch.prototype.render = function (children) {
20820 !this._defer ? invariant(false, 'batch.render: Cannot render a batch that already committed.') : void 0;
20821 this._hasChildren = true;
20822 this._children = children;
20823 var internalRoot = this._root._internalRoot;
20824 var expirationTime = this._expirationTime;
20825 var work = new ReactWork();
20826 updateContainerAtExpirationTime(children, internalRoot, null, expirationTime, work._onCommit);
20827 return work;
20828};
20829ReactBatch.prototype.then = function (onComplete) {
20830 if (this._didComplete) {
20831 onComplete();
20832 return;
20833 }
20834 var callbacks = this._callbacks;
20835 if (callbacks === null) {
20836 callbacks = this._callbacks = [];
20837 }
20838 callbacks.push(onComplete);
20839};
20840ReactBatch.prototype.commit = function () {
20841 var internalRoot = this._root._internalRoot;
20842 var firstBatch = internalRoot.firstBatch;
20843 !(this._defer && firstBatch !== null) ? invariant(false, 'batch.commit: Cannot commit a batch multiple times.') : void 0;
20844
20845 if (!this._hasChildren) {
20846 // This batch is empty. Return.
20847 this._next = null;
20848 this._defer = false;
20849 return;
20850 }
20851
20852 var expirationTime = this._expirationTime;
20853
20854 // Ensure this is the first batch in the list.
20855 if (firstBatch !== this) {
20856 // This batch is not the earliest batch. We need to move it to the front.
20857 // Update its expiration time to be the expiration time of the earliest
20858 // batch, so that we can flush it without flushing the other batches.
20859 if (this._hasChildren) {
20860 expirationTime = this._expirationTime = firstBatch._expirationTime;
20861 // Rendering this batch again ensures its children will be the final state
20862 // when we flush (updates are processed in insertion order: last
20863 // update wins).
20864 // TODO: This forces a restart. Should we print a warning?
20865 this.render(this._children);
20866 }
20867
20868 // Remove the batch from the list.
20869 var previous = null;
20870 var batch = firstBatch;
20871 while (batch !== this) {
20872 previous = batch;
20873 batch = batch._next;
20874 }
20875 !(previous !== null) ? invariant(false, 'batch.commit: Cannot commit a batch multiple times.') : void 0;
20876 previous._next = batch._next;
20877
20878 // Add it to the front.
20879 this._next = firstBatch;
20880 firstBatch = internalRoot.firstBatch = this;
20881 }
20882
20883 // Synchronously flush all the work up to this batch's expiration time.
20884 this._defer = false;
20885 flushRoot(internalRoot, expirationTime);
20886
20887 // Pop the batch from the list.
20888 var next = this._next;
20889 this._next = null;
20890 firstBatch = internalRoot.firstBatch = next;
20891
20892 // Append the next earliest batch's children to the update queue.
20893 if (firstBatch !== null && firstBatch._hasChildren) {
20894 firstBatch.render(firstBatch._children);
20895 }
20896};
20897ReactBatch.prototype._onComplete = function () {
20898 if (this._didComplete) {
20899 return;
20900 }
20901 this._didComplete = true;
20902 var callbacks = this._callbacks;
20903 if (callbacks === null) {
20904 return;
20905 }
20906 // TODO: Error handling.
20907 for (var i = 0; i < callbacks.length; i++) {
20908 var _callback = callbacks[i];
20909 _callback();
20910 }
20911};
20912
20913function ReactWork() {
20914 this._callbacks = null;
20915 this._didCommit = false;
20916 // TODO: Avoid need to bind by replacing callbacks in the update queue with
20917 // list of Work objects.
20918 this._onCommit = this._onCommit.bind(this);
20919}
20920ReactWork.prototype.then = function (onCommit) {
20921 if (this._didCommit) {
20922 onCommit();
20923 return;
20924 }
20925 var callbacks = this._callbacks;
20926 if (callbacks === null) {
20927 callbacks = this._callbacks = [];
20928 }
20929 callbacks.push(onCommit);
20930};
20931ReactWork.prototype._onCommit = function () {
20932 if (this._didCommit) {
20933 return;
20934 }
20935 this._didCommit = true;
20936 var callbacks = this._callbacks;
20937 if (callbacks === null) {
20938 return;
20939 }
20940 // TODO: Error handling.
20941 for (var i = 0; i < callbacks.length; i++) {
20942 var _callback2 = callbacks[i];
20943 !(typeof _callback2 === 'function') ? invariant(false, 'Invalid argument passed as callback. Expected a function. Instead received: %s', _callback2) : void 0;
20944 _callback2();
20945 }
20946};
20947
20948function ReactRoot(container, isConcurrent, hydrate) {
20949 var root = createContainer(container, isConcurrent, hydrate);
20950 this._internalRoot = root;
20951}
20952ReactRoot.prototype.render = function (children, callback) {
20953 var root = this._internalRoot;
20954 var work = new ReactWork();
20955 callback = callback === undefined ? null : callback;
20956 {
20957 warnOnInvalidCallback(callback, 'render');
20958 }
20959 if (callback !== null) {
20960 work.then(callback);
20961 }
20962 updateContainer(children, root, null, work._onCommit);
20963 return work;
20964};
20965ReactRoot.prototype.unmount = function (callback) {
20966 var root = this._internalRoot;
20967 var work = new ReactWork();
20968 callback = callback === undefined ? null : callback;
20969 {
20970 warnOnInvalidCallback(callback, 'render');
20971 }
20972 if (callback !== null) {
20973 work.then(callback);
20974 }
20975 updateContainer(null, root, null, work._onCommit);
20976 return work;
20977};
20978ReactRoot.prototype.legacy_renderSubtreeIntoContainer = function (parentComponent, children, callback) {
20979 var root = this._internalRoot;
20980 var work = new ReactWork();
20981 callback = callback === undefined ? null : callback;
20982 {
20983 warnOnInvalidCallback(callback, 'render');
20984 }
20985 if (callback !== null) {
20986 work.then(callback);
20987 }
20988 updateContainer(children, root, parentComponent, work._onCommit);
20989 return work;
20990};
20991ReactRoot.prototype.createBatch = function () {
20992 var batch = new ReactBatch(this);
20993 var expirationTime = batch._expirationTime;
20994
20995 var internalRoot = this._internalRoot;
20996 var firstBatch = internalRoot.firstBatch;
20997 if (firstBatch === null) {
20998 internalRoot.firstBatch = batch;
20999 batch._next = null;
21000 } else {
21001 // Insert sorted by expiration time then insertion order
21002 var insertAfter = null;
21003 var insertBefore = firstBatch;
21004 while (insertBefore !== null && insertBefore._expirationTime >= expirationTime) {
21005 insertAfter = insertBefore;
21006 insertBefore = insertBefore._next;
21007 }
21008 batch._next = insertBefore;
21009 if (insertAfter !== null) {
21010 insertAfter._next = batch;
21011 }
21012 }
21013
21014 return batch;
21015};
21016
21017/**
21018 * True if the supplied DOM node is a valid node element.
21019 *
21020 * @param {?DOMElement} node The candidate DOM node.
21021 * @return {boolean} True if the DOM is a valid DOM node.
21022 * @internal
21023 */
21024function isValidContainer(node) {
21025 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 '));
21026}
21027
21028function getReactRootElementInContainer(container) {
21029 if (!container) {
21030 return null;
21031 }
21032
21033 if (container.nodeType === DOCUMENT_NODE) {
21034 return container.documentElement;
21035 } else {
21036 return container.firstChild;
21037 }
21038}
21039
21040function shouldHydrateDueToLegacyHeuristic(container) {
21041 var rootElement = getReactRootElementInContainer(container);
21042 return !!(rootElement && rootElement.nodeType === ELEMENT_NODE && rootElement.hasAttribute(ROOT_ATTRIBUTE_NAME));
21043}
21044
21045setBatchingImplementation(batchedUpdates$1, interactiveUpdates$1, flushInteractiveUpdates$1);
21046
21047var warnedAboutHydrateAPI = false;
21048
21049function legacyCreateRootFromDOMContainer(container, forceHydrate) {
21050 var shouldHydrate = forceHydrate || shouldHydrateDueToLegacyHeuristic(container);
21051 // First clear any existing content.
21052 if (!shouldHydrate) {
21053 var warned = false;
21054 var rootSibling = void 0;
21055 while (rootSibling = container.lastChild) {
21056 {
21057 if (!warned && rootSibling.nodeType === ELEMENT_NODE && rootSibling.hasAttribute(ROOT_ATTRIBUTE_NAME)) {
21058 warned = true;
21059 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.');
21060 }
21061 }
21062 container.removeChild(rootSibling);
21063 }
21064 }
21065 {
21066 if (shouldHydrate && !forceHydrate && !warnedAboutHydrateAPI) {
21067 warnedAboutHydrateAPI = true;
21068 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.');
21069 }
21070 }
21071 // Legacy roots are not async by default.
21072 var isConcurrent = false;
21073 return new ReactRoot(container, isConcurrent, shouldHydrate);
21074}
21075
21076function legacyRenderSubtreeIntoContainer(parentComponent, children, container, forceHydrate, callback) {
21077 {
21078 topLevelUpdateWarnings(container);
21079 }
21080
21081 // TODO: Without `any` type, Flow says "Property cannot be accessed on any
21082 // member of intersection type." Whyyyyyy.
21083 var root = container._reactRootContainer;
21084 if (!root) {
21085 // Initial mount
21086 root = container._reactRootContainer = legacyCreateRootFromDOMContainer(container, forceHydrate);
21087 if (typeof callback === 'function') {
21088 var originalCallback = callback;
21089 callback = function () {
21090 var instance = getPublicRootInstance(root._internalRoot);
21091 originalCallback.call(instance);
21092 };
21093 }
21094 // Initial mount should not be batched.
21095 unbatchedUpdates(function () {
21096 if (parentComponent != null) {
21097 root.legacy_renderSubtreeIntoContainer(parentComponent, children, callback);
21098 } else {
21099 root.render(children, callback);
21100 }
21101 });
21102 } else {
21103 if (typeof callback === 'function') {
21104 var _originalCallback = callback;
21105 callback = function () {
21106 var instance = getPublicRootInstance(root._internalRoot);
21107 _originalCallback.call(instance);
21108 };
21109 }
21110 // Update
21111 if (parentComponent != null) {
21112 root.legacy_renderSubtreeIntoContainer(parentComponent, children, callback);
21113 } else {
21114 root.render(children, callback);
21115 }
21116 }
21117 return getPublicRootInstance(root._internalRoot);
21118}
21119
21120function createPortal$$1(children, container) {
21121 var key = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
21122
21123 !isValidContainer(container) ? invariant(false, 'Target container is not a DOM element.') : void 0;
21124 // TODO: pass ReactDOM portal implementation as third argument
21125 return createPortal$1(children, container, null, key);
21126}
21127
21128var ReactDOM = {
21129 createPortal: createPortal$$1,
21130
21131 findDOMNode: function (componentOrElement) {
21132 {
21133 var owner = ReactCurrentOwner.current;
21134 if (owner !== null && owner.stateNode !== null) {
21135 var warnedAboutRefsInRender = owner.stateNode._warnedAboutRefsInRender;
21136 !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;
21137 owner.stateNode._warnedAboutRefsInRender = true;
21138 }
21139 }
21140 if (componentOrElement == null) {
21141 return null;
21142 }
21143 if (componentOrElement.nodeType === ELEMENT_NODE) {
21144 return componentOrElement;
21145 }
21146 {
21147 return findHostInstanceWithWarning(componentOrElement, 'findDOMNode');
21148 }
21149 return findHostInstance(componentOrElement);
21150 },
21151 hydrate: function (element, container, callback) {
21152 !isValidContainer(container) ? invariant(false, 'Target container is not a DOM element.') : void 0;
21153 {
21154 !!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;
21155 }
21156 // TODO: throw or warn if we couldn't hydrate?
21157 return legacyRenderSubtreeIntoContainer(null, element, container, true, callback);
21158 },
21159 render: function (element, container, callback) {
21160 !isValidContainer(container) ? invariant(false, 'Target container is not a DOM element.') : void 0;
21161 {
21162 !!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;
21163 }
21164 return legacyRenderSubtreeIntoContainer(null, element, container, false, callback);
21165 },
21166 unstable_renderSubtreeIntoContainer: function (parentComponent, element, containerNode, callback) {
21167 !isValidContainer(containerNode) ? invariant(false, 'Target container is not a DOM element.') : void 0;
21168 !(parentComponent != null && has(parentComponent)) ? invariant(false, 'parentComponent must be a valid React Component') : void 0;
21169 return legacyRenderSubtreeIntoContainer(parentComponent, element, containerNode, false, callback);
21170 },
21171 unmountComponentAtNode: function (container) {
21172 !isValidContainer(container) ? invariant(false, 'unmountComponentAtNode(...): Target container is not a DOM element.') : void 0;
21173
21174 {
21175 !!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;
21176 }
21177
21178 if (container._reactRootContainer) {
21179 {
21180 var rootEl = getReactRootElementInContainer(container);
21181 var renderedByDifferentReact = rootEl && !getInstanceFromNode$1(rootEl);
21182 !!renderedByDifferentReact ? warningWithoutStack$1(false, "unmountComponentAtNode(): The node you're attempting to unmount " + 'was rendered by another copy of React.') : void 0;
21183 }
21184
21185 // Unmount should not be batched.
21186 unbatchedUpdates(function () {
21187 legacyRenderSubtreeIntoContainer(null, null, container, false, function () {
21188 container._reactRootContainer = null;
21189 });
21190 });
21191 // If you call unmountComponentAtNode twice in quick succession, you'll
21192 // get `true` twice. That's probably fine?
21193 return true;
21194 } else {
21195 {
21196 var _rootEl = getReactRootElementInContainer(container);
21197 var hasNonRootReactChild = !!(_rootEl && getInstanceFromNode$1(_rootEl));
21198
21199 // Check if the container itself is a React root node.
21200 var isContainerReactRoot = container.nodeType === ELEMENT_NODE && isValidContainer(container.parentNode) && !!container.parentNode._reactRootContainer;
21201
21202 !!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;
21203 }
21204
21205 return false;
21206 }
21207 },
21208
21209
21210 // Temporary alias since we already shipped React 16 RC with it.
21211 // TODO: remove in React 17.
21212 unstable_createPortal: function () {
21213 if (!didWarnAboutUnstableCreatePortal) {
21214 didWarnAboutUnstableCreatePortal = true;
21215 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.');
21216 }
21217 return createPortal$$1.apply(undefined, arguments);
21218 },
21219
21220
21221 unstable_batchedUpdates: batchedUpdates$1,
21222
21223 unstable_interactiveUpdates: interactiveUpdates$1,
21224
21225 flushSync: flushSync,
21226
21227 unstable_createRoot: createRoot,
21228 unstable_flushControlled: flushControlled,
21229
21230 __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED: {
21231 // Keep in sync with ReactDOMUnstableNativeDependencies.js
21232 // and ReactTestUtils.js. This is an array for better minification.
21233 Events: [getInstanceFromNode$1, getNodeFromInstance$1, getFiberCurrentPropsFromNode$1, injection.injectEventPluginsByName, eventNameDispatchConfigs, accumulateTwoPhaseDispatches, accumulateDirectDispatches, enqueueStateRestore, restoreStateIfNeeded, dispatchEvent, runEventsInBatch]
21234 }
21235};
21236
21237function createRoot(container, options) {
21238 var functionName = enableStableConcurrentModeAPIs ? 'createRoot' : 'unstable_createRoot';
21239 !isValidContainer(container) ? invariant(false, '%s(...): Target container is not a DOM element.', functionName) : void 0;
21240 {
21241 !!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;
21242 container._reactHasBeenPassedToCreateRootDEV = true;
21243 }
21244 var hydrate = options != null && options.hydrate === true;
21245 return new ReactRoot(container, true, hydrate);
21246}
21247
21248if (enableStableConcurrentModeAPIs) {
21249 ReactDOM.createRoot = createRoot;
21250 ReactDOM.unstable_createRoot = undefined;
21251}
21252
21253var foundDevTools = injectIntoDevTools({
21254 findFiberByHostInstance: getClosestInstanceFromNode,
21255 bundleType: 1,
21256 version: ReactVersion,
21257 rendererPackageName: 'react-dom'
21258});
21259
21260{
21261 if (!foundDevTools && canUseDOM && window.top === window.self) {
21262 // If we're in Chrome or Firefox, provide a download link if not installed.
21263 if (navigator.userAgent.indexOf('Chrome') > -1 && navigator.userAgent.indexOf('Edge') === -1 || navigator.userAgent.indexOf('Firefox') > -1) {
21264 var protocol = window.location.protocol;
21265 // Don't warn in exotic cases like chrome-extension://.
21266 if (/^(https?|file):$/.test(protocol)) {
21267 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');
21268 }
21269 }
21270 }
21271}
21272
21273
21274
21275var ReactFire = Object.freeze({
21276 default: ReactDOM
21277});
21278
21279var ReactFire$1 = ( ReactFire && ReactDOM ) || ReactFire;
21280
21281// TODO: decide on the top-level export form.
21282// This is hacky but makes it work with both Rollup and Jest.
21283var unstableFire = ReactFire$1.default || ReactFire$1;
21284
21285module.exports = unstableFire;
21286 })();
21287}