UNPKG

787 kBJavaScriptView Raw
1/** @license React v16.8.6
2 * react-dom.development.js
3 *
4 * Copyright (c) Facebook, Inc. and its affiliates.
5 *
6 * This source code is licensed under the MIT license found in the
7 * LICENSE file in the root directory of this source tree.
8 */
9
10'use strict';
11
12
13
14if (process.env.NODE_ENV !== "production") {
15 (function() {
16'use strict';
17
18var React = require('react');
19var _assign = require('object-assign');
20var checkPropTypes = require('prop-types/checkPropTypes');
21var scheduler = require('scheduler');
22var tracing = require('scheduler/tracing');
23
24/**
25 * Use invariant() to assert state which your program assumes to be true.
26 *
27 * Provide sprintf-style format (only %s is supported) and arguments
28 * to provide information about what broke and what you were
29 * expecting.
30 *
31 * The invariant message will be stripped in production, but the invariant
32 * will remain to ensure logic does not differ in production.
33 */
34
35var validateFormat = function () {};
36
37{
38 validateFormat = function (format) {
39 if (format === undefined) {
40 throw new Error('invariant requires an error message argument');
41 }
42 };
43}
44
45function invariant(condition, format, a, b, c, d, e, f) {
46 validateFormat(format);
47
48 if (!condition) {
49 var error = void 0;
50 if (format === undefined) {
51 error = new Error('Minified exception occurred; use the non-minified dev environment ' + 'for the full error message and additional helpful warnings.');
52 } else {
53 var args = [a, b, c, d, e, f];
54 var argIndex = 0;
55 error = new Error(format.replace(/%s/g, function () {
56 return args[argIndex++];
57 }));
58 error.name = 'Invariant Violation';
59 }
60
61 error.framesToPop = 1; // we don't care about invariant's own frame
62 throw error;
63 }
64}
65
66// Relying on the `invariant()` implementation lets us
67// preserve the format and params in the www builds.
68
69!React ? invariant(false, 'ReactDOM was loaded before React. Make sure you load the React package before loading ReactDOM.') : void 0;
70
71var invokeGuardedCallbackImpl = function (name, func, context, a, b, c, d, e, f) {
72 var funcArgs = Array.prototype.slice.call(arguments, 3);
73 try {
74 func.apply(context, funcArgs);
75 } catch (error) {
76 this.onError(error);
77 }
78};
79
80{
81 // In DEV mode, we swap out invokeGuardedCallback for a special version
82 // that plays more nicely with the browser's DevTools. The idea is to preserve
83 // "Pause on exceptions" behavior. Because React wraps all user-provided
84 // functions in invokeGuardedCallback, and the production version of
85 // invokeGuardedCallback uses a try-catch, all user exceptions are treated
86 // like caught exceptions, and the DevTools won't pause unless the developer
87 // takes the extra step of enabling pause on caught exceptions. This is
88 // unintuitive, though, because even though React has caught the error, from
89 // the developer's perspective, the error is uncaught.
90 //
91 // To preserve the expected "Pause on exceptions" behavior, we don't use a
92 // try-catch in DEV. Instead, we synchronously dispatch a fake event to a fake
93 // DOM node, and call the user-provided callback from inside an event handler
94 // for that fake event. If the callback throws, the error is "captured" using
95 // a global event handler. But because the error happens in a different
96 // event loop context, it does not interrupt the normal program flow.
97 // Effectively, this gives us try-catch behavior without actually using
98 // try-catch. Neat!
99
100 // Check that the browser supports the APIs we need to implement our special
101 // DEV version of invokeGuardedCallback
102 if (typeof window !== 'undefined' && typeof window.dispatchEvent === 'function' && typeof document !== 'undefined' && typeof document.createEvent === 'function') {
103 var fakeNode = document.createElement('react');
104
105 var invokeGuardedCallbackDev = function (name, func, context, a, b, c, d, e, f) {
106 // If document doesn't exist we know for sure we will crash in this method
107 // when we call document.createEvent(). However this can cause confusing
108 // errors: https://github.com/facebookincubator/create-react-app/issues/3482
109 // So we preemptively throw with a better message instead.
110 !(typeof document !== 'undefined') ? invariant(false, 'The `document` global was defined when React was initialized, but is not defined anymore. This can happen in a test environment if a component schedules an update from an asynchronous callback, but the test has already finished running. To solve this, you can either unmount the component at the end of your test (and ensure that any asynchronous operations get canceled in `componentWillUnmount`), or you can change the test itself to be asynchronous.') : void 0;
111 var evt = document.createEvent('Event');
112
113 // Keeps track of whether the user-provided callback threw an error. We
114 // set this to true at the beginning, then set it to false right after
115 // calling the function. If the function errors, `didError` will never be
116 // set to false. This strategy works even if the browser is flaky and
117 // fails to call our global error handler, because it doesn't rely on
118 // the error event at all.
119 var didError = true;
120
121 // Keeps track of the value of window.event so that we can reset it
122 // during the callback to let user code access window.event in the
123 // browsers that support it.
124 var windowEvent = window.event;
125
126 // Keeps track of the descriptor of window.event to restore it after event
127 // dispatching: https://github.com/facebook/react/issues/13688
128 var windowEventDescriptor = Object.getOwnPropertyDescriptor(window, 'event');
129
130 // Create an event handler for our fake event. We will synchronously
131 // dispatch our fake event using `dispatchEvent`. Inside the handler, we
132 // call the user-provided callback.
133 var funcArgs = Array.prototype.slice.call(arguments, 3);
134 function callCallback() {
135 // We immediately remove the callback from event listeners so that
136 // nested `invokeGuardedCallback` calls do not clash. Otherwise, a
137 // nested call would trigger the fake event handlers of any call higher
138 // in the stack.
139 fakeNode.removeEventListener(evtType, callCallback, false);
140
141 // We check for window.hasOwnProperty('event') to prevent the
142 // window.event assignment in both IE <= 10 as they throw an error
143 // "Member not found" in strict mode, and in Firefox which does not
144 // support window.event.
145 if (typeof window.event !== 'undefined' && window.hasOwnProperty('event')) {
146 window.event = windowEvent;
147 }
148
149 func.apply(context, funcArgs);
150 didError = false;
151 }
152
153 // Create a global error event handler. We use this to capture the value
154 // that was thrown. It's possible that this error handler will fire more
155 // than once; for example, if non-React code also calls `dispatchEvent`
156 // and a handler for that event throws. We should be resilient to most of
157 // those cases. Even if our error event handler fires more than once, the
158 // last error event is always used. If the callback actually does error,
159 // we know that the last error event is the correct one, because it's not
160 // possible for anything else to have happened in between our callback
161 // erroring and the code that follows the `dispatchEvent` call below. If
162 // the callback doesn't error, but the error event was fired, we know to
163 // ignore it because `didError` will be false, as described above.
164 var error = void 0;
165 // Use this to track whether the error event is ever called.
166 var didSetError = false;
167 var isCrossOriginError = false;
168
169 function handleWindowError(event) {
170 error = event.error;
171 didSetError = true;
172 if (error === null && event.colno === 0 && event.lineno === 0) {
173 isCrossOriginError = true;
174 }
175 if (event.defaultPrevented) {
176 // Some other error handler has prevented default.
177 // Browsers silence the error report if this happens.
178 // We'll remember this to later decide whether to log it or not.
179 if (error != null && typeof error === 'object') {
180 try {
181 error._suppressLogging = true;
182 } catch (inner) {
183 // Ignore.
184 }
185 }
186 }
187 }
188
189 // Create a fake event type.
190 var evtType = 'react-' + (name ? name : 'invokeguardedcallback');
191
192 // Attach our event handlers
193 window.addEventListener('error', handleWindowError);
194 fakeNode.addEventListener(evtType, callCallback, false);
195
196 // Synchronously dispatch our fake event. If the user-provided function
197 // errors, it will trigger our global error handler.
198 evt.initEvent(evtType, false, false);
199 fakeNode.dispatchEvent(evt);
200
201 if (windowEventDescriptor) {
202 Object.defineProperty(window, 'event', windowEventDescriptor);
203 }
204
205 if (didError) {
206 if (!didSetError) {
207 // The callback errored, but the error event never fired.
208 error = new Error('An error was thrown inside one of your components, but React ' + "doesn't know what it was. This is likely due to browser " + 'flakiness. React does its best to preserve the "Pause on ' + 'exceptions" behavior of the DevTools, which requires some ' + "DEV-mode only tricks. It's possible that these don't work in " + 'your browser. Try triggering the error in production mode, ' + 'or switching to a modern browser. If you suspect that this is ' + 'actually an issue with React, please file an issue.');
209 } else if (isCrossOriginError) {
210 error = new Error("A cross-origin error was thrown. React doesn't have access to " + 'the actual error object in development. ' + 'See https://fb.me/react-crossorigin-error for more information.');
211 }
212 this.onError(error);
213 }
214
215 // Remove our event listeners
216 window.removeEventListener('error', handleWindowError);
217 };
218
219 invokeGuardedCallbackImpl = invokeGuardedCallbackDev;
220 }
221}
222
223var invokeGuardedCallbackImpl$1 = invokeGuardedCallbackImpl;
224
225// Used by Fiber to simulate a try-catch.
226var hasError = false;
227var caughtError = null;
228
229// Used by event system to capture/rethrow the first error.
230var hasRethrowError = false;
231var rethrowError = null;
232
233var reporter = {
234 onError: function (error) {
235 hasError = true;
236 caughtError = error;
237 }
238};
239
240/**
241 * Call a function while guarding against errors that happens within it.
242 * Returns an error if it throws, otherwise null.
243 *
244 * In production, this is implemented using a try-catch. The reason we don't
245 * use a try-catch directly is so that we can swap out a different
246 * implementation in DEV mode.
247 *
248 * @param {String} name of the guard to use for logging or debugging
249 * @param {Function} func The function to invoke
250 * @param {*} context The context to use when calling the function
251 * @param {...*} args Arguments for function
252 */
253function invokeGuardedCallback(name, func, context, a, b, c, d, e, f) {
254 hasError = false;
255 caughtError = null;
256 invokeGuardedCallbackImpl$1.apply(reporter, arguments);
257}
258
259/**
260 * Same as invokeGuardedCallback, but instead of returning an error, it stores
261 * it in a global so it can be rethrown by `rethrowCaughtError` later.
262 * TODO: See if caughtError and rethrowError can be unified.
263 *
264 * @param {String} name of the guard to use for logging or debugging
265 * @param {Function} func The function to invoke
266 * @param {*} context The context to use when calling the function
267 * @param {...*} args Arguments for function
268 */
269function invokeGuardedCallbackAndCatchFirstError(name, func, context, a, b, c, d, e, f) {
270 invokeGuardedCallback.apply(this, arguments);
271 if (hasError) {
272 var error = clearCaughtError();
273 if (!hasRethrowError) {
274 hasRethrowError = true;
275 rethrowError = error;
276 }
277 }
278}
279
280/**
281 * During execution of guarded functions we will capture the first error which
282 * we will rethrow to be handled by the top level error handler.
283 */
284function rethrowCaughtError() {
285 if (hasRethrowError) {
286 var error = rethrowError;
287 hasRethrowError = false;
288 rethrowError = null;
289 throw error;
290 }
291}
292
293function hasCaughtError() {
294 return hasError;
295}
296
297function clearCaughtError() {
298 if (hasError) {
299 var error = caughtError;
300 hasError = false;
301 caughtError = null;
302 return error;
303 } else {
304 invariant(false, 'clearCaughtError was called but no error was captured. This error is likely caused by a bug in React. Please file an issue.');
305 }
306}
307
308/**
309 * Injectable ordering of event plugins.
310 */
311var eventPluginOrder = null;
312
313/**
314 * Injectable mapping from names to event plugin modules.
315 */
316var namesToPlugins = {};
317
318/**
319 * Recomputes the plugin list using the injected plugins and plugin ordering.
320 *
321 * @private
322 */
323function recomputePluginOrdering() {
324 if (!eventPluginOrder) {
325 // Wait until an `eventPluginOrder` is injected.
326 return;
327 }
328 for (var pluginName in namesToPlugins) {
329 var pluginModule = namesToPlugins[pluginName];
330 var pluginIndex = eventPluginOrder.indexOf(pluginName);
331 !(pluginIndex > -1) ? invariant(false, 'EventPluginRegistry: Cannot inject event plugins that do not exist in the plugin ordering, `%s`.', pluginName) : void 0;
332 if (plugins[pluginIndex]) {
333 continue;
334 }
335 !pluginModule.extractEvents ? invariant(false, 'EventPluginRegistry: Event plugins must implement an `extractEvents` method, but `%s` does not.', pluginName) : void 0;
336 plugins[pluginIndex] = pluginModule;
337 var publishedEvents = pluginModule.eventTypes;
338 for (var eventName in publishedEvents) {
339 !publishEventForPlugin(publishedEvents[eventName], pluginModule, eventName) ? invariant(false, 'EventPluginRegistry: Failed to publish event `%s` for plugin `%s`.', eventName, pluginName) : void 0;
340 }
341 }
342}
343
344/**
345 * Publishes an event so that it can be dispatched by the supplied plugin.
346 *
347 * @param {object} dispatchConfig Dispatch configuration for the event.
348 * @param {object} PluginModule Plugin publishing the event.
349 * @return {boolean} True if the event was successfully published.
350 * @private
351 */
352function publishEventForPlugin(dispatchConfig, pluginModule, eventName) {
353 !!eventNameDispatchConfigs.hasOwnProperty(eventName) ? invariant(false, 'EventPluginHub: More than one plugin attempted to publish the same event name, `%s`.', eventName) : void 0;
354 eventNameDispatchConfigs[eventName] = dispatchConfig;
355
356 var phasedRegistrationNames = dispatchConfig.phasedRegistrationNames;
357 if (phasedRegistrationNames) {
358 for (var phaseName in phasedRegistrationNames) {
359 if (phasedRegistrationNames.hasOwnProperty(phaseName)) {
360 var phasedRegistrationName = phasedRegistrationNames[phaseName];
361 publishRegistrationName(phasedRegistrationName, pluginModule, eventName);
362 }
363 }
364 return true;
365 } else if (dispatchConfig.registrationName) {
366 publishRegistrationName(dispatchConfig.registrationName, pluginModule, eventName);
367 return true;
368 }
369 return false;
370}
371
372/**
373 * Publishes a registration name that is used to identify dispatched events.
374 *
375 * @param {string} registrationName Registration name to add.
376 * @param {object} PluginModule Plugin publishing the event.
377 * @private
378 */
379function publishRegistrationName(registrationName, pluginModule, eventName) {
380 !!registrationNameModules[registrationName] ? invariant(false, 'EventPluginHub: More than one plugin attempted to publish the same registration name, `%s`.', registrationName) : void 0;
381 registrationNameModules[registrationName] = pluginModule;
382 registrationNameDependencies[registrationName] = pluginModule.eventTypes[eventName].dependencies;
383
384 {
385 var lowerCasedName = registrationName.toLowerCase();
386 possibleRegistrationNames[lowerCasedName] = registrationName;
387
388 if (registrationName === 'onDoubleClick') {
389 possibleRegistrationNames.ondblclick = registrationName;
390 }
391 }
392}
393
394/**
395 * Registers plugins so that they can extract and dispatch events.
396 *
397 * @see {EventPluginHub}
398 */
399
400/**
401 * Ordered list of injected plugins.
402 */
403var plugins = [];
404
405/**
406 * Mapping from event name to dispatch config
407 */
408var eventNameDispatchConfigs = {};
409
410/**
411 * Mapping from registration name to plugin module
412 */
413var registrationNameModules = {};
414
415/**
416 * Mapping from registration name to event name
417 */
418var registrationNameDependencies = {};
419
420/**
421 * Mapping from lowercase registration names to the properly cased version,
422 * used to warn in the case of missing event handlers. Available
423 * only in true.
424 * @type {Object}
425 */
426var possibleRegistrationNames = {};
427// Trust the developer to only use possibleRegistrationNames in true
428
429/**
430 * Injects an ordering of plugins (by plugin name). This allows the ordering
431 * to be decoupled from injection of the actual plugins so that ordering is
432 * always deterministic regardless of packaging, on-the-fly injection, etc.
433 *
434 * @param {array} InjectedEventPluginOrder
435 * @internal
436 * @see {EventPluginHub.injection.injectEventPluginOrder}
437 */
438function injectEventPluginOrder(injectedEventPluginOrder) {
439 !!eventPluginOrder ? invariant(false, 'EventPluginRegistry: Cannot inject event plugin ordering more than once. You are likely trying to load more than one copy of React.') : void 0;
440 // Clone the ordering so it cannot be dynamically mutated.
441 eventPluginOrder = Array.prototype.slice.call(injectedEventPluginOrder);
442 recomputePluginOrdering();
443}
444
445/**
446 * Injects plugins to be used by `EventPluginHub`. The plugin names must be
447 * in the ordering injected by `injectEventPluginOrder`.
448 *
449 * Plugins can be injected as part of page initialization or on-the-fly.
450 *
451 * @param {object} injectedNamesToPlugins Map from names to plugin modules.
452 * @internal
453 * @see {EventPluginHub.injection.injectEventPluginsByName}
454 */
455function injectEventPluginsByName(injectedNamesToPlugins) {
456 var isOrderingDirty = false;
457 for (var pluginName in injectedNamesToPlugins) {
458 if (!injectedNamesToPlugins.hasOwnProperty(pluginName)) {
459 continue;
460 }
461 var pluginModule = injectedNamesToPlugins[pluginName];
462 if (!namesToPlugins.hasOwnProperty(pluginName) || namesToPlugins[pluginName] !== pluginModule) {
463 !!namesToPlugins[pluginName] ? invariant(false, 'EventPluginRegistry: Cannot inject two different event plugins using the same name, `%s`.', pluginName) : void 0;
464 namesToPlugins[pluginName] = pluginModule;
465 isOrderingDirty = true;
466 }
467 }
468 if (isOrderingDirty) {
469 recomputePluginOrdering();
470 }
471}
472
473/**
474 * Similar to invariant but only logs a warning if the condition is not met.
475 * This can be used to log issues in development environments in critical
476 * paths. Removing the logging code for production environments will keep the
477 * same logic and follow the same code paths.
478 */
479
480var warningWithoutStack = function () {};
481
482{
483 warningWithoutStack = function (condition, format) {
484 for (var _len = arguments.length, args = Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) {
485 args[_key - 2] = arguments[_key];
486 }
487
488 if (format === undefined) {
489 throw new Error('`warningWithoutStack(condition, format, ...args)` requires a warning ' + 'message argument');
490 }
491 if (args.length > 8) {
492 // Check before the condition to catch violations early.
493 throw new Error('warningWithoutStack() currently supports at most 8 arguments.');
494 }
495 if (condition) {
496 return;
497 }
498 if (typeof console !== 'undefined') {
499 var argsWithFormat = args.map(function (item) {
500 return '' + item;
501 });
502 argsWithFormat.unshift('Warning: ' + format);
503
504 // We intentionally don't use spread (or .apply) directly because it
505 // breaks IE9: https://github.com/facebook/react/issues/13610
506 Function.prototype.apply.call(console.error, console, argsWithFormat);
507 }
508 try {
509 // --- Welcome to debugging React ---
510 // This error was thrown as a convenience so that you can use this stack
511 // to find the callsite that caused this warning to fire.
512 var argIndex = 0;
513 var message = 'Warning: ' + format.replace(/%s/g, function () {
514 return args[argIndex++];
515 });
516 throw new Error(message);
517 } catch (x) {}
518 };
519}
520
521var warningWithoutStack$1 = warningWithoutStack;
522
523var getFiberCurrentPropsFromNode = null;
524var getInstanceFromNode = null;
525var getNodeFromInstance = null;
526
527function setComponentTree(getFiberCurrentPropsFromNodeImpl, getInstanceFromNodeImpl, getNodeFromInstanceImpl) {
528 getFiberCurrentPropsFromNode = getFiberCurrentPropsFromNodeImpl;
529 getInstanceFromNode = getInstanceFromNodeImpl;
530 getNodeFromInstance = getNodeFromInstanceImpl;
531 {
532 !(getNodeFromInstance && getInstanceFromNode) ? warningWithoutStack$1(false, 'EventPluginUtils.setComponentTree(...): Injected ' + 'module is missing getNodeFromInstance or getInstanceFromNode.') : void 0;
533 }
534}
535
536var validateEventDispatches = void 0;
537{
538 validateEventDispatches = function (event) {
539 var dispatchListeners = event._dispatchListeners;
540 var dispatchInstances = event._dispatchInstances;
541
542 var listenersIsArr = Array.isArray(dispatchListeners);
543 var listenersLen = listenersIsArr ? dispatchListeners.length : dispatchListeners ? 1 : 0;
544
545 var instancesIsArr = Array.isArray(dispatchInstances);
546 var instancesLen = instancesIsArr ? dispatchInstances.length : dispatchInstances ? 1 : 0;
547
548 !(instancesIsArr === listenersIsArr && instancesLen === listenersLen) ? warningWithoutStack$1(false, 'EventPluginUtils: Invalid `event`.') : void 0;
549 };
550}
551
552/**
553 * Dispatch the event to the listener.
554 * @param {SyntheticEvent} event SyntheticEvent to handle
555 * @param {function} listener Application-level callback
556 * @param {*} inst Internal component instance
557 */
558function executeDispatch(event, listener, inst) {
559 var type = event.type || 'unknown-event';
560 event.currentTarget = getNodeFromInstance(inst);
561 invokeGuardedCallbackAndCatchFirstError(type, listener, undefined, event);
562 event.currentTarget = null;
563}
564
565/**
566 * Standard/simple iteration through an event's collected dispatches.
567 */
568function executeDispatchesInOrder(event) {
569 var dispatchListeners = event._dispatchListeners;
570 var dispatchInstances = event._dispatchInstances;
571 {
572 validateEventDispatches(event);
573 }
574 if (Array.isArray(dispatchListeners)) {
575 for (var i = 0; i < dispatchListeners.length; i++) {
576 if (event.isPropagationStopped()) {
577 break;
578 }
579 // Listeners and Instances are two parallel arrays that are always in sync.
580 executeDispatch(event, dispatchListeners[i], dispatchInstances[i]);
581 }
582 } else if (dispatchListeners) {
583 executeDispatch(event, dispatchListeners, dispatchInstances);
584 }
585 event._dispatchListeners = null;
586 event._dispatchInstances = null;
587}
588
589/**
590 * @see executeDispatchesInOrderStopAtTrueImpl
591 */
592
593
594/**
595 * Execution of a "direct" dispatch - there must be at most one dispatch
596 * accumulated on the event or it is considered an error. It doesn't really make
597 * sense for an event with multiple dispatches (bubbled) to keep track of the
598 * return values at each dispatch execution, but it does tend to make sense when
599 * dealing with "direct" dispatches.
600 *
601 * @return {*} The return value of executing the single dispatch.
602 */
603
604
605/**
606 * @param {SyntheticEvent} event
607 * @return {boolean} True iff number of dispatches accumulated is greater than 0.
608 */
609
610/**
611 * Accumulates items that must not be null or undefined into the first one. This
612 * is used to conserve memory by avoiding array allocations, and thus sacrifices
613 * API cleanness. Since `current` can be null before being passed in and not
614 * null after this function, make sure to assign it back to `current`:
615 *
616 * `a = accumulateInto(a, b);`
617 *
618 * This API should be sparingly used. Try `accumulate` for something cleaner.
619 *
620 * @return {*|array<*>} An accumulation of items.
621 */
622
623function accumulateInto(current, next) {
624 !(next != null) ? invariant(false, 'accumulateInto(...): Accumulated items must not be null or undefined.') : void 0;
625
626 if (current == null) {
627 return next;
628 }
629
630 // Both are not empty. Warning: Never call x.concat(y) when you are not
631 // certain that x is an Array (x could be a string with concat method).
632 if (Array.isArray(current)) {
633 if (Array.isArray(next)) {
634 current.push.apply(current, next);
635 return current;
636 }
637 current.push(next);
638 return current;
639 }
640
641 if (Array.isArray(next)) {
642 // A bit too dangerous to mutate `next`.
643 return [current].concat(next);
644 }
645
646 return [current, next];
647}
648
649/**
650 * @param {array} arr an "accumulation" of items which is either an Array or
651 * a single item. Useful when paired with the `accumulate` module. This is a
652 * simple utility that allows us to reason about a collection of items, but
653 * handling the case when there is exactly one item (and we do not need to
654 * allocate an array).
655 * @param {function} cb Callback invoked with each element or a collection.
656 * @param {?} [scope] Scope used as `this` in a callback.
657 */
658function forEachAccumulated(arr, cb, scope) {
659 if (Array.isArray(arr)) {
660 arr.forEach(cb, scope);
661 } else if (arr) {
662 cb.call(scope, arr);
663 }
664}
665
666/**
667 * Internal queue of events that have accumulated their dispatches and are
668 * waiting to have their dispatches executed.
669 */
670var eventQueue = null;
671
672/**
673 * Dispatches an event and releases it back into the pool, unless persistent.
674 *
675 * @param {?object} event Synthetic event to be dispatched.
676 * @private
677 */
678var executeDispatchesAndRelease = function (event) {
679 if (event) {
680 executeDispatchesInOrder(event);
681
682 if (!event.isPersistent()) {
683 event.constructor.release(event);
684 }
685 }
686};
687var executeDispatchesAndReleaseTopLevel = function (e) {
688 return executeDispatchesAndRelease(e);
689};
690
691function isInteractive(tag) {
692 return tag === 'button' || tag === 'input' || tag === 'select' || tag === 'textarea';
693}
694
695function shouldPreventMouseEvent(name, type, props) {
696 switch (name) {
697 case 'onClick':
698 case 'onClickCapture':
699 case 'onDoubleClick':
700 case 'onDoubleClickCapture':
701 case 'onMouseDown':
702 case 'onMouseDownCapture':
703 case 'onMouseMove':
704 case 'onMouseMoveCapture':
705 case 'onMouseUp':
706 case 'onMouseUpCapture':
707 return !!(props.disabled && isInteractive(type));
708 default:
709 return false;
710 }
711}
712
713/**
714 * This is a unified interface for event plugins to be installed and configured.
715 *
716 * Event plugins can implement the following properties:
717 *
718 * `extractEvents` {function(string, DOMEventTarget, string, object): *}
719 * Required. When a top-level event is fired, this method is expected to
720 * extract synthetic events that will in turn be queued and dispatched.
721 *
722 * `eventTypes` {object}
723 * Optional, plugins that fire events must publish a mapping of registration
724 * names that are used to register listeners. Values of this mapping must
725 * be objects that contain `registrationName` or `phasedRegistrationNames`.
726 *
727 * `executeDispatch` {function(object, function, string)}
728 * Optional, allows plugins to override how an event gets dispatched. By
729 * default, the listener is simply invoked.
730 *
731 * Each plugin that is injected into `EventsPluginHub` is immediately operable.
732 *
733 * @public
734 */
735
736/**
737 * Methods for injecting dependencies.
738 */
739var injection = {
740 /**
741 * @param {array} InjectedEventPluginOrder
742 * @public
743 */
744 injectEventPluginOrder: injectEventPluginOrder,
745
746 /**
747 * @param {object} injectedNamesToPlugins Map from names to plugin modules.
748 */
749 injectEventPluginsByName: injectEventPluginsByName
750};
751
752/**
753 * @param {object} inst The instance, which is the source of events.
754 * @param {string} registrationName Name of listener (e.g. `onClick`).
755 * @return {?function} The stored callback.
756 */
757function getListener(inst, registrationName) {
758 var listener = void 0;
759
760 // TODO: shouldPreventMouseEvent is DOM-specific and definitely should not
761 // live here; needs to be moved to a better place soon
762 var stateNode = inst.stateNode;
763 if (!stateNode) {
764 // Work in progress (ex: onload events in incremental mode).
765 return null;
766 }
767 var props = getFiberCurrentPropsFromNode(stateNode);
768 if (!props) {
769 // Work in progress.
770 return null;
771 }
772 listener = props[registrationName];
773 if (shouldPreventMouseEvent(registrationName, inst.type, props)) {
774 return null;
775 }
776 !(!listener || typeof listener === 'function') ? invariant(false, 'Expected `%s` listener to be a function, instead got a value of `%s` type.', registrationName, typeof listener) : void 0;
777 return listener;
778}
779
780/**
781 * Allows registered plugins an opportunity to extract events from top-level
782 * native browser events.
783 *
784 * @return {*} An accumulation of synthetic events.
785 * @internal
786 */
787function extractEvents(topLevelType, targetInst, nativeEvent, nativeEventTarget) {
788 var events = null;
789 for (var i = 0; i < plugins.length; i++) {
790 // Not every plugin in the ordering may be loaded at runtime.
791 var possiblePlugin = plugins[i];
792 if (possiblePlugin) {
793 var extractedEvents = possiblePlugin.extractEvents(topLevelType, targetInst, nativeEvent, nativeEventTarget);
794 if (extractedEvents) {
795 events = accumulateInto(events, extractedEvents);
796 }
797 }
798 }
799 return events;
800}
801
802function runEventsInBatch(events) {
803 if (events !== null) {
804 eventQueue = accumulateInto(eventQueue, events);
805 }
806
807 // Set `eventQueue` to null before processing it so that we can tell if more
808 // events get enqueued while processing.
809 var processingEventQueue = eventQueue;
810 eventQueue = null;
811
812 if (!processingEventQueue) {
813 return;
814 }
815
816 forEachAccumulated(processingEventQueue, executeDispatchesAndReleaseTopLevel);
817 !!eventQueue ? invariant(false, 'processEventQueue(): Additional events were enqueued while processing an event queue. Support for this has not yet been implemented.') : void 0;
818 // This would be a good time to rethrow if any of the event handlers threw.
819 rethrowCaughtError();
820}
821
822function runExtractedEventsInBatch(topLevelType, targetInst, nativeEvent, nativeEventTarget) {
823 var events = extractEvents(topLevelType, targetInst, nativeEvent, nativeEventTarget);
824 runEventsInBatch(events);
825}
826
827var FunctionComponent = 0;
828var ClassComponent = 1;
829var IndeterminateComponent = 2; // Before we know whether it is function or class
830var HostRoot = 3; // Root of a host tree. Could be nested inside another node.
831var HostPortal = 4; // A subtree. Could be an entry point to a different renderer.
832var HostComponent = 5;
833var HostText = 6;
834var Fragment = 7;
835var Mode = 8;
836var ContextConsumer = 9;
837var ContextProvider = 10;
838var ForwardRef = 11;
839var Profiler = 12;
840var SuspenseComponent = 13;
841var MemoComponent = 14;
842var SimpleMemoComponent = 15;
843var LazyComponent = 16;
844var IncompleteClassComponent = 17;
845var DehydratedSuspenseComponent = 18;
846
847var randomKey = Math.random().toString(36).slice(2);
848var internalInstanceKey = '__reactInternalInstance$' + randomKey;
849var internalEventHandlersKey = '__reactEventHandlers$' + randomKey;
850
851function precacheFiberNode(hostInst, node) {
852 node[internalInstanceKey] = hostInst;
853}
854
855/**
856 * Given a DOM node, return the closest ReactDOMComponent or
857 * ReactDOMTextComponent instance ancestor.
858 */
859function getClosestInstanceFromNode(node) {
860 if (node[internalInstanceKey]) {
861 return node[internalInstanceKey];
862 }
863
864 while (!node[internalInstanceKey]) {
865 if (node.parentNode) {
866 node = node.parentNode;
867 } else {
868 // Top of the tree. This node must not be part of a React tree (or is
869 // unmounted, potentially).
870 return null;
871 }
872 }
873
874 var inst = node[internalInstanceKey];
875 if (inst.tag === HostComponent || inst.tag === HostText) {
876 // In Fiber, this will always be the deepest root.
877 return inst;
878 }
879
880 return null;
881}
882
883/**
884 * Given a DOM node, return the ReactDOMComponent or ReactDOMTextComponent
885 * instance, or null if the node was not rendered by this React.
886 */
887function getInstanceFromNode$1(node) {
888 var inst = node[internalInstanceKey];
889 if (inst) {
890 if (inst.tag === HostComponent || inst.tag === HostText) {
891 return inst;
892 } else {
893 return null;
894 }
895 }
896 return null;
897}
898
899/**
900 * Given a ReactDOMComponent or ReactDOMTextComponent, return the corresponding
901 * DOM node.
902 */
903function getNodeFromInstance$1(inst) {
904 if (inst.tag === HostComponent || inst.tag === HostText) {
905 // In Fiber this, is just the state node right now. We assume it will be
906 // a host component or host text.
907 return inst.stateNode;
908 }
909
910 // Without this first invariant, passing a non-DOM-component triggers the next
911 // invariant for a missing parent, which is super confusing.
912 invariant(false, 'getNodeFromInstance: Invalid argument.');
913}
914
915function getFiberCurrentPropsFromNode$1(node) {
916 return node[internalEventHandlersKey] || null;
917}
918
919function updateFiberProps(node, props) {
920 node[internalEventHandlersKey] = props;
921}
922
923function getParent(inst) {
924 do {
925 inst = inst.return;
926 // TODO: If this is a HostRoot we might want to bail out.
927 // That is depending on if we want nested subtrees (layers) to bubble
928 // events to their parent. We could also go through parentNode on the
929 // host node but that wouldn't work for React Native and doesn't let us
930 // do the portal feature.
931 } while (inst && inst.tag !== HostComponent);
932 if (inst) {
933 return inst;
934 }
935 return null;
936}
937
938/**
939 * Return the lowest common ancestor of A and B, or null if they are in
940 * different trees.
941 */
942function getLowestCommonAncestor(instA, instB) {
943 var depthA = 0;
944 for (var tempA = instA; tempA; tempA = getParent(tempA)) {
945 depthA++;
946 }
947 var depthB = 0;
948 for (var tempB = instB; tempB; tempB = getParent(tempB)) {
949 depthB++;
950 }
951
952 // If A is deeper, crawl up.
953 while (depthA - depthB > 0) {
954 instA = getParent(instA);
955 depthA--;
956 }
957
958 // If B is deeper, crawl up.
959 while (depthB - depthA > 0) {
960 instB = getParent(instB);
961 depthB--;
962 }
963
964 // Walk in lockstep until we find a match.
965 var depth = depthA;
966 while (depth--) {
967 if (instA === instB || instA === instB.alternate) {
968 return instA;
969 }
970 instA = getParent(instA);
971 instB = getParent(instB);
972 }
973 return null;
974}
975
976/**
977 * Return if A is an ancestor of B.
978 */
979
980
981/**
982 * Return the parent instance of the passed-in instance.
983 */
984
985
986/**
987 * Simulates the traversal of a two-phase, capture/bubble event dispatch.
988 */
989function traverseTwoPhase(inst, fn, arg) {
990 var path = [];
991 while (inst) {
992 path.push(inst);
993 inst = getParent(inst);
994 }
995 var i = void 0;
996 for (i = path.length; i-- > 0;) {
997 fn(path[i], 'captured', arg);
998 }
999 for (i = 0; i < path.length; i++) {
1000 fn(path[i], 'bubbled', arg);
1001 }
1002}
1003
1004/**
1005 * Traverses the ID hierarchy and invokes the supplied `cb` on any IDs that
1006 * should would receive a `mouseEnter` or `mouseLeave` event.
1007 *
1008 * Does not invoke the callback on the nearest common ancestor because nothing
1009 * "entered" or "left" that element.
1010 */
1011function traverseEnterLeave(from, to, fn, argFrom, argTo) {
1012 var common = from && to ? getLowestCommonAncestor(from, to) : null;
1013 var pathFrom = [];
1014 while (true) {
1015 if (!from) {
1016 break;
1017 }
1018 if (from === common) {
1019 break;
1020 }
1021 var alternate = from.alternate;
1022 if (alternate !== null && alternate === common) {
1023 break;
1024 }
1025 pathFrom.push(from);
1026 from = getParent(from);
1027 }
1028 var pathTo = [];
1029 while (true) {
1030 if (!to) {
1031 break;
1032 }
1033 if (to === common) {
1034 break;
1035 }
1036 var _alternate = to.alternate;
1037 if (_alternate !== null && _alternate === common) {
1038 break;
1039 }
1040 pathTo.push(to);
1041 to = getParent(to);
1042 }
1043 for (var i = 0; i < pathFrom.length; i++) {
1044 fn(pathFrom[i], 'bubbled', argFrom);
1045 }
1046 for (var _i = pathTo.length; _i-- > 0;) {
1047 fn(pathTo[_i], 'captured', argTo);
1048 }
1049}
1050
1051/**
1052 * Some event types have a notion of different registration names for different
1053 * "phases" of propagation. This finds listeners by a given phase.
1054 */
1055function listenerAtPhase(inst, event, propagationPhase) {
1056 var registrationName = event.dispatchConfig.phasedRegistrationNames[propagationPhase];
1057 return getListener(inst, registrationName);
1058}
1059
1060/**
1061 * A small set of propagation patterns, each of which will accept a small amount
1062 * of information, and generate a set of "dispatch ready event objects" - which
1063 * are sets of events that have already been annotated with a set of dispatched
1064 * listener functions/ids. The API is designed this way to discourage these
1065 * propagation strategies from actually executing the dispatches, since we
1066 * always want to collect the entire set of dispatches before executing even a
1067 * single one.
1068 */
1069
1070/**
1071 * Tags a `SyntheticEvent` with dispatched listeners. Creating this function
1072 * here, allows us to not have to bind or create functions for each event.
1073 * Mutating the event's members allows us to not have to create a wrapping
1074 * "dispatch" object that pairs the event with the listener.
1075 */
1076function accumulateDirectionalDispatches(inst, phase, event) {
1077 {
1078 !inst ? warningWithoutStack$1(false, 'Dispatching inst must not be null') : void 0;
1079 }
1080 var listener = listenerAtPhase(inst, event, phase);
1081 if (listener) {
1082 event._dispatchListeners = accumulateInto(event._dispatchListeners, listener);
1083 event._dispatchInstances = accumulateInto(event._dispatchInstances, inst);
1084 }
1085}
1086
1087/**
1088 * Collect dispatches (must be entirely collected before dispatching - see unit
1089 * tests). Lazily allocate the array to conserve memory. We must loop through
1090 * each event and perform the traversal for each one. We cannot perform a
1091 * single traversal for the entire collection of events because each event may
1092 * have a different target.
1093 */
1094function accumulateTwoPhaseDispatchesSingle(event) {
1095 if (event && event.dispatchConfig.phasedRegistrationNames) {
1096 traverseTwoPhase(event._targetInst, accumulateDirectionalDispatches, event);
1097 }
1098}
1099
1100/**
1101 * Accumulates without regard to direction, does not look for phased
1102 * registration names. Same as `accumulateDirectDispatchesSingle` but without
1103 * requiring that the `dispatchMarker` be the same as the dispatched ID.
1104 */
1105function accumulateDispatches(inst, ignoredDirection, event) {
1106 if (inst && event && event.dispatchConfig.registrationName) {
1107 var registrationName = event.dispatchConfig.registrationName;
1108 var listener = getListener(inst, registrationName);
1109 if (listener) {
1110 event._dispatchListeners = accumulateInto(event._dispatchListeners, listener);
1111 event._dispatchInstances = accumulateInto(event._dispatchInstances, inst);
1112 }
1113 }
1114}
1115
1116/**
1117 * Accumulates dispatches on an `SyntheticEvent`, but only for the
1118 * `dispatchMarker`.
1119 * @param {SyntheticEvent} event
1120 */
1121function accumulateDirectDispatchesSingle(event) {
1122 if (event && event.dispatchConfig.registrationName) {
1123 accumulateDispatches(event._targetInst, null, event);
1124 }
1125}
1126
1127function accumulateTwoPhaseDispatches(events) {
1128 forEachAccumulated(events, accumulateTwoPhaseDispatchesSingle);
1129}
1130
1131
1132
1133function accumulateEnterLeaveDispatches(leave, enter, from, to) {
1134 traverseEnterLeave(from, to, accumulateDispatches, leave, enter);
1135}
1136
1137function accumulateDirectDispatches(events) {
1138 forEachAccumulated(events, accumulateDirectDispatchesSingle);
1139}
1140
1141var canUseDOM = !!(typeof window !== 'undefined' && window.document && window.document.createElement);
1142
1143// Do not uses the below two methods directly!
1144// Instead use constants exported from DOMTopLevelEventTypes in ReactDOM.
1145// (It is the only module that is allowed to access these methods.)
1146
1147function unsafeCastStringToDOMTopLevelType(topLevelType) {
1148 return topLevelType;
1149}
1150
1151function unsafeCastDOMTopLevelTypeToString(topLevelType) {
1152 return topLevelType;
1153}
1154
1155/**
1156 * Generate a mapping of standard vendor prefixes using the defined style property and event name.
1157 *
1158 * @param {string} styleProp
1159 * @param {string} eventName
1160 * @returns {object}
1161 */
1162function makePrefixMap(styleProp, eventName) {
1163 var prefixes = {};
1164
1165 prefixes[styleProp.toLowerCase()] = eventName.toLowerCase();
1166 prefixes['Webkit' + styleProp] = 'webkit' + eventName;
1167 prefixes['Moz' + styleProp] = 'moz' + eventName;
1168
1169 return prefixes;
1170}
1171
1172/**
1173 * A list of event names to a configurable list of vendor prefixes.
1174 */
1175var vendorPrefixes = {
1176 animationend: makePrefixMap('Animation', 'AnimationEnd'),
1177 animationiteration: makePrefixMap('Animation', 'AnimationIteration'),
1178 animationstart: makePrefixMap('Animation', 'AnimationStart'),
1179 transitionend: makePrefixMap('Transition', 'TransitionEnd')
1180};
1181
1182/**
1183 * Event names that have already been detected and prefixed (if applicable).
1184 */
1185var prefixedEventNames = {};
1186
1187/**
1188 * Element to check for prefixes on.
1189 */
1190var style = {};
1191
1192/**
1193 * Bootstrap if a DOM exists.
1194 */
1195if (canUseDOM) {
1196 style = document.createElement('div').style;
1197
1198 // On some platforms, in particular some releases of Android 4.x,
1199 // the un-prefixed "animation" and "transition" properties are defined on the
1200 // style object but the events that fire will still be prefixed, so we need
1201 // to check if the un-prefixed events are usable, and if not remove them from the map.
1202 if (!('AnimationEvent' in window)) {
1203 delete vendorPrefixes.animationend.animation;
1204 delete vendorPrefixes.animationiteration.animation;
1205 delete vendorPrefixes.animationstart.animation;
1206 }
1207
1208 // Same as above
1209 if (!('TransitionEvent' in window)) {
1210 delete vendorPrefixes.transitionend.transition;
1211 }
1212}
1213
1214/**
1215 * Attempts to determine the correct vendor prefixed event name.
1216 *
1217 * @param {string} eventName
1218 * @returns {string}
1219 */
1220function getVendorPrefixedEventName(eventName) {
1221 if (prefixedEventNames[eventName]) {
1222 return prefixedEventNames[eventName];
1223 } else if (!vendorPrefixes[eventName]) {
1224 return eventName;
1225 }
1226
1227 var prefixMap = vendorPrefixes[eventName];
1228
1229 for (var styleProp in prefixMap) {
1230 if (prefixMap.hasOwnProperty(styleProp) && styleProp in style) {
1231 return prefixedEventNames[eventName] = prefixMap[styleProp];
1232 }
1233 }
1234
1235 return eventName;
1236}
1237
1238/**
1239 * To identify top level events in ReactDOM, we use constants defined by this
1240 * module. This is the only module that uses the unsafe* methods to express
1241 * that the constants actually correspond to the browser event names. This lets
1242 * us save some bundle size by avoiding a top level type -> event name map.
1243 * The rest of ReactDOM code should import top level types from this file.
1244 */
1245var TOP_ABORT = unsafeCastStringToDOMTopLevelType('abort');
1246var TOP_ANIMATION_END = unsafeCastStringToDOMTopLevelType(getVendorPrefixedEventName('animationend'));
1247var TOP_ANIMATION_ITERATION = unsafeCastStringToDOMTopLevelType(getVendorPrefixedEventName('animationiteration'));
1248var TOP_ANIMATION_START = unsafeCastStringToDOMTopLevelType(getVendorPrefixedEventName('animationstart'));
1249var TOP_BLUR = unsafeCastStringToDOMTopLevelType('blur');
1250var TOP_CAN_PLAY = unsafeCastStringToDOMTopLevelType('canplay');
1251var TOP_CAN_PLAY_THROUGH = unsafeCastStringToDOMTopLevelType('canplaythrough');
1252var TOP_CANCEL = unsafeCastStringToDOMTopLevelType('cancel');
1253var TOP_CHANGE = unsafeCastStringToDOMTopLevelType('change');
1254var TOP_CLICK = unsafeCastStringToDOMTopLevelType('click');
1255var TOP_CLOSE = unsafeCastStringToDOMTopLevelType('close');
1256var TOP_COMPOSITION_END = unsafeCastStringToDOMTopLevelType('compositionend');
1257var TOP_COMPOSITION_START = unsafeCastStringToDOMTopLevelType('compositionstart');
1258var TOP_COMPOSITION_UPDATE = unsafeCastStringToDOMTopLevelType('compositionupdate');
1259var TOP_CONTEXT_MENU = unsafeCastStringToDOMTopLevelType('contextmenu');
1260var TOP_COPY = unsafeCastStringToDOMTopLevelType('copy');
1261var TOP_CUT = unsafeCastStringToDOMTopLevelType('cut');
1262var TOP_DOUBLE_CLICK = unsafeCastStringToDOMTopLevelType('dblclick');
1263var TOP_AUX_CLICK = unsafeCastStringToDOMTopLevelType('auxclick');
1264var TOP_DRAG = unsafeCastStringToDOMTopLevelType('drag');
1265var TOP_DRAG_END = unsafeCastStringToDOMTopLevelType('dragend');
1266var TOP_DRAG_ENTER = unsafeCastStringToDOMTopLevelType('dragenter');
1267var TOP_DRAG_EXIT = unsafeCastStringToDOMTopLevelType('dragexit');
1268var TOP_DRAG_LEAVE = unsafeCastStringToDOMTopLevelType('dragleave');
1269var TOP_DRAG_OVER = unsafeCastStringToDOMTopLevelType('dragover');
1270var TOP_DRAG_START = unsafeCastStringToDOMTopLevelType('dragstart');
1271var TOP_DROP = unsafeCastStringToDOMTopLevelType('drop');
1272var TOP_DURATION_CHANGE = unsafeCastStringToDOMTopLevelType('durationchange');
1273var TOP_EMPTIED = unsafeCastStringToDOMTopLevelType('emptied');
1274var TOP_ENCRYPTED = unsafeCastStringToDOMTopLevelType('encrypted');
1275var TOP_ENDED = unsafeCastStringToDOMTopLevelType('ended');
1276var TOP_ERROR = unsafeCastStringToDOMTopLevelType('error');
1277var TOP_FOCUS = unsafeCastStringToDOMTopLevelType('focus');
1278var TOP_GOT_POINTER_CAPTURE = unsafeCastStringToDOMTopLevelType('gotpointercapture');
1279var TOP_INPUT = unsafeCastStringToDOMTopLevelType('input');
1280var TOP_INVALID = unsafeCastStringToDOMTopLevelType('invalid');
1281var TOP_KEY_DOWN = unsafeCastStringToDOMTopLevelType('keydown');
1282var TOP_KEY_PRESS = unsafeCastStringToDOMTopLevelType('keypress');
1283var TOP_KEY_UP = unsafeCastStringToDOMTopLevelType('keyup');
1284var TOP_LOAD = unsafeCastStringToDOMTopLevelType('load');
1285var TOP_LOAD_START = unsafeCastStringToDOMTopLevelType('loadstart');
1286var TOP_LOADED_DATA = unsafeCastStringToDOMTopLevelType('loadeddata');
1287var TOP_LOADED_METADATA = unsafeCastStringToDOMTopLevelType('loadedmetadata');
1288var TOP_LOST_POINTER_CAPTURE = unsafeCastStringToDOMTopLevelType('lostpointercapture');
1289var TOP_MOUSE_DOWN = unsafeCastStringToDOMTopLevelType('mousedown');
1290var TOP_MOUSE_MOVE = unsafeCastStringToDOMTopLevelType('mousemove');
1291var TOP_MOUSE_OUT = unsafeCastStringToDOMTopLevelType('mouseout');
1292var TOP_MOUSE_OVER = unsafeCastStringToDOMTopLevelType('mouseover');
1293var TOP_MOUSE_UP = unsafeCastStringToDOMTopLevelType('mouseup');
1294var TOP_PASTE = unsafeCastStringToDOMTopLevelType('paste');
1295var TOP_PAUSE = unsafeCastStringToDOMTopLevelType('pause');
1296var TOP_PLAY = unsafeCastStringToDOMTopLevelType('play');
1297var TOP_PLAYING = unsafeCastStringToDOMTopLevelType('playing');
1298var TOP_POINTER_CANCEL = unsafeCastStringToDOMTopLevelType('pointercancel');
1299var TOP_POINTER_DOWN = unsafeCastStringToDOMTopLevelType('pointerdown');
1300
1301
1302var TOP_POINTER_MOVE = unsafeCastStringToDOMTopLevelType('pointermove');
1303var TOP_POINTER_OUT = unsafeCastStringToDOMTopLevelType('pointerout');
1304var TOP_POINTER_OVER = unsafeCastStringToDOMTopLevelType('pointerover');
1305var TOP_POINTER_UP = unsafeCastStringToDOMTopLevelType('pointerup');
1306var TOP_PROGRESS = unsafeCastStringToDOMTopLevelType('progress');
1307var TOP_RATE_CHANGE = unsafeCastStringToDOMTopLevelType('ratechange');
1308var TOP_RESET = unsafeCastStringToDOMTopLevelType('reset');
1309var TOP_SCROLL = unsafeCastStringToDOMTopLevelType('scroll');
1310var TOP_SEEKED = unsafeCastStringToDOMTopLevelType('seeked');
1311var TOP_SEEKING = unsafeCastStringToDOMTopLevelType('seeking');
1312var TOP_SELECTION_CHANGE = unsafeCastStringToDOMTopLevelType('selectionchange');
1313var TOP_STALLED = unsafeCastStringToDOMTopLevelType('stalled');
1314var TOP_SUBMIT = unsafeCastStringToDOMTopLevelType('submit');
1315var TOP_SUSPEND = unsafeCastStringToDOMTopLevelType('suspend');
1316var TOP_TEXT_INPUT = unsafeCastStringToDOMTopLevelType('textInput');
1317var TOP_TIME_UPDATE = unsafeCastStringToDOMTopLevelType('timeupdate');
1318var TOP_TOGGLE = unsafeCastStringToDOMTopLevelType('toggle');
1319var TOP_TOUCH_CANCEL = unsafeCastStringToDOMTopLevelType('touchcancel');
1320var TOP_TOUCH_END = unsafeCastStringToDOMTopLevelType('touchend');
1321var TOP_TOUCH_MOVE = unsafeCastStringToDOMTopLevelType('touchmove');
1322var TOP_TOUCH_START = unsafeCastStringToDOMTopLevelType('touchstart');
1323var TOP_TRANSITION_END = unsafeCastStringToDOMTopLevelType(getVendorPrefixedEventName('transitionend'));
1324var TOP_VOLUME_CHANGE = unsafeCastStringToDOMTopLevelType('volumechange');
1325var TOP_WAITING = unsafeCastStringToDOMTopLevelType('waiting');
1326var TOP_WHEEL = unsafeCastStringToDOMTopLevelType('wheel');
1327
1328// List of events that need to be individually attached to media elements.
1329// Note that events in this list will *not* be listened to at the top level
1330// unless they're explicitly whitelisted in `ReactBrowserEventEmitter.listenTo`.
1331var mediaEventTypes = [TOP_ABORT, TOP_CAN_PLAY, TOP_CAN_PLAY_THROUGH, TOP_DURATION_CHANGE, TOP_EMPTIED, TOP_ENCRYPTED, TOP_ENDED, TOP_ERROR, TOP_LOADED_DATA, TOP_LOADED_METADATA, TOP_LOAD_START, TOP_PAUSE, TOP_PLAY, TOP_PLAYING, TOP_PROGRESS, TOP_RATE_CHANGE, TOP_SEEKED, TOP_SEEKING, TOP_STALLED, TOP_SUSPEND, TOP_TIME_UPDATE, TOP_VOLUME_CHANGE, TOP_WAITING];
1332
1333function getRawEventName(topLevelType) {
1334 return unsafeCastDOMTopLevelTypeToString(topLevelType);
1335}
1336
1337/**
1338 * These variables store information about text content of a target node,
1339 * allowing comparison of content before and after a given event.
1340 *
1341 * Identify the node where selection currently begins, then observe
1342 * both its text content and its current position in the DOM. Since the
1343 * browser may natively replace the target node during composition, we can
1344 * use its position to find its replacement.
1345 *
1346 *
1347 */
1348
1349var root = null;
1350var startText = null;
1351var fallbackText = null;
1352
1353function initialize(nativeEventTarget) {
1354 root = nativeEventTarget;
1355 startText = getText();
1356 return true;
1357}
1358
1359function reset() {
1360 root = null;
1361 startText = null;
1362 fallbackText = null;
1363}
1364
1365function getData() {
1366 if (fallbackText) {
1367 return fallbackText;
1368 }
1369
1370 var start = void 0;
1371 var startValue = startText;
1372 var startLength = startValue.length;
1373 var end = void 0;
1374 var endValue = getText();
1375 var endLength = endValue.length;
1376
1377 for (start = 0; start < startLength; start++) {
1378 if (startValue[start] !== endValue[start]) {
1379 break;
1380 }
1381 }
1382
1383 var minEnd = startLength - start;
1384 for (end = 1; end <= minEnd; end++) {
1385 if (startValue[startLength - end] !== endValue[endLength - end]) {
1386 break;
1387 }
1388 }
1389
1390 var sliceTail = end > 1 ? 1 - end : undefined;
1391 fallbackText = endValue.slice(start, sliceTail);
1392 return fallbackText;
1393}
1394
1395function getText() {
1396 if ('value' in root) {
1397 return root.value;
1398 }
1399 return root.textContent;
1400}
1401
1402/* eslint valid-typeof: 0 */
1403
1404var EVENT_POOL_SIZE = 10;
1405
1406/**
1407 * @interface Event
1408 * @see http://www.w3.org/TR/DOM-Level-3-Events/
1409 */
1410var EventInterface = {
1411 type: null,
1412 target: null,
1413 // currentTarget is set when dispatching; no use in copying it here
1414 currentTarget: function () {
1415 return null;
1416 },
1417 eventPhase: null,
1418 bubbles: null,
1419 cancelable: null,
1420 timeStamp: function (event) {
1421 return event.timeStamp || Date.now();
1422 },
1423 defaultPrevented: null,
1424 isTrusted: null
1425};
1426
1427function functionThatReturnsTrue() {
1428 return true;
1429}
1430
1431function functionThatReturnsFalse() {
1432 return false;
1433}
1434
1435/**
1436 * Synthetic events are dispatched by event plugins, typically in response to a
1437 * top-level event delegation handler.
1438 *
1439 * These systems should generally use pooling to reduce the frequency of garbage
1440 * collection. The system should check `isPersistent` to determine whether the
1441 * event should be released into the pool after being dispatched. Users that
1442 * need a persisted event should invoke `persist`.
1443 *
1444 * Synthetic events (and subclasses) implement the DOM Level 3 Events API by
1445 * normalizing browser quirks. Subclasses do not necessarily have to implement a
1446 * DOM interface; custom application-specific events can also subclass this.
1447 *
1448 * @param {object} dispatchConfig Configuration used to dispatch this event.
1449 * @param {*} targetInst Marker identifying the event target.
1450 * @param {object} nativeEvent Native browser event.
1451 * @param {DOMEventTarget} nativeEventTarget Target node.
1452 */
1453function SyntheticEvent(dispatchConfig, targetInst, nativeEvent, nativeEventTarget) {
1454 {
1455 // these have a getter/setter for warnings
1456 delete this.nativeEvent;
1457 delete this.preventDefault;
1458 delete this.stopPropagation;
1459 delete this.isDefaultPrevented;
1460 delete this.isPropagationStopped;
1461 }
1462
1463 this.dispatchConfig = dispatchConfig;
1464 this._targetInst = targetInst;
1465 this.nativeEvent = nativeEvent;
1466
1467 var Interface = this.constructor.Interface;
1468 for (var propName in Interface) {
1469 if (!Interface.hasOwnProperty(propName)) {
1470 continue;
1471 }
1472 {
1473 delete this[propName]; // this has a getter/setter for warnings
1474 }
1475 var normalize = Interface[propName];
1476 if (normalize) {
1477 this[propName] = normalize(nativeEvent);
1478 } else {
1479 if (propName === 'target') {
1480 this.target = nativeEventTarget;
1481 } else {
1482 this[propName] = nativeEvent[propName];
1483 }
1484 }
1485 }
1486
1487 var defaultPrevented = nativeEvent.defaultPrevented != null ? nativeEvent.defaultPrevented : nativeEvent.returnValue === false;
1488 if (defaultPrevented) {
1489 this.isDefaultPrevented = functionThatReturnsTrue;
1490 } else {
1491 this.isDefaultPrevented = functionThatReturnsFalse;
1492 }
1493 this.isPropagationStopped = functionThatReturnsFalse;
1494 return this;
1495}
1496
1497_assign(SyntheticEvent.prototype, {
1498 preventDefault: function () {
1499 this.defaultPrevented = true;
1500 var event = this.nativeEvent;
1501 if (!event) {
1502 return;
1503 }
1504
1505 if (event.preventDefault) {
1506 event.preventDefault();
1507 } else if (typeof event.returnValue !== 'unknown') {
1508 event.returnValue = false;
1509 }
1510 this.isDefaultPrevented = functionThatReturnsTrue;
1511 },
1512
1513 stopPropagation: function () {
1514 var event = this.nativeEvent;
1515 if (!event) {
1516 return;
1517 }
1518
1519 if (event.stopPropagation) {
1520 event.stopPropagation();
1521 } else if (typeof event.cancelBubble !== 'unknown') {
1522 // The ChangeEventPlugin registers a "propertychange" event for
1523 // IE. This event does not support bubbling or cancelling, and
1524 // any references to cancelBubble throw "Member not found". A
1525 // typeof check of "unknown" circumvents this issue (and is also
1526 // IE specific).
1527 event.cancelBubble = true;
1528 }
1529
1530 this.isPropagationStopped = functionThatReturnsTrue;
1531 },
1532
1533 /**
1534 * We release all dispatched `SyntheticEvent`s after each event loop, adding
1535 * them back into the pool. This allows a way to hold onto a reference that
1536 * won't be added back into the pool.
1537 */
1538 persist: function () {
1539 this.isPersistent = functionThatReturnsTrue;
1540 },
1541
1542 /**
1543 * Checks if this event should be released back into the pool.
1544 *
1545 * @return {boolean} True if this should not be released, false otherwise.
1546 */
1547 isPersistent: functionThatReturnsFalse,
1548
1549 /**
1550 * `PooledClass` looks for `destructor` on each instance it releases.
1551 */
1552 destructor: function () {
1553 var Interface = this.constructor.Interface;
1554 for (var propName in Interface) {
1555 {
1556 Object.defineProperty(this, propName, getPooledWarningPropertyDefinition(propName, Interface[propName]));
1557 }
1558 }
1559 this.dispatchConfig = null;
1560 this._targetInst = null;
1561 this.nativeEvent = null;
1562 this.isDefaultPrevented = functionThatReturnsFalse;
1563 this.isPropagationStopped = functionThatReturnsFalse;
1564 this._dispatchListeners = null;
1565 this._dispatchInstances = null;
1566 {
1567 Object.defineProperty(this, 'nativeEvent', getPooledWarningPropertyDefinition('nativeEvent', null));
1568 Object.defineProperty(this, 'isDefaultPrevented', getPooledWarningPropertyDefinition('isDefaultPrevented', functionThatReturnsFalse));
1569 Object.defineProperty(this, 'isPropagationStopped', getPooledWarningPropertyDefinition('isPropagationStopped', functionThatReturnsFalse));
1570 Object.defineProperty(this, 'preventDefault', getPooledWarningPropertyDefinition('preventDefault', function () {}));
1571 Object.defineProperty(this, 'stopPropagation', getPooledWarningPropertyDefinition('stopPropagation', function () {}));
1572 }
1573 }
1574});
1575
1576SyntheticEvent.Interface = EventInterface;
1577
1578/**
1579 * Helper to reduce boilerplate when creating subclasses.
1580 */
1581SyntheticEvent.extend = function (Interface) {
1582 var Super = this;
1583
1584 var E = function () {};
1585 E.prototype = Super.prototype;
1586 var prototype = new E();
1587
1588 function Class() {
1589 return Super.apply(this, arguments);
1590 }
1591 _assign(prototype, Class.prototype);
1592 Class.prototype = prototype;
1593 Class.prototype.constructor = Class;
1594
1595 Class.Interface = _assign({}, Super.Interface, Interface);
1596 Class.extend = Super.extend;
1597 addEventPoolingTo(Class);
1598
1599 return Class;
1600};
1601
1602addEventPoolingTo(SyntheticEvent);
1603
1604/**
1605 * Helper to nullify syntheticEvent instance properties when destructing
1606 *
1607 * @param {String} propName
1608 * @param {?object} getVal
1609 * @return {object} defineProperty object
1610 */
1611function getPooledWarningPropertyDefinition(propName, getVal) {
1612 var isFunction = typeof getVal === 'function';
1613 return {
1614 configurable: true,
1615 set: set,
1616 get: get
1617 };
1618
1619 function set(val) {
1620 var action = isFunction ? 'setting the method' : 'setting the property';
1621 warn(action, 'This is effectively a no-op');
1622 return val;
1623 }
1624
1625 function get() {
1626 var action = isFunction ? 'accessing the method' : 'accessing the property';
1627 var result = isFunction ? 'This is a no-op function' : 'This is set to null';
1628 warn(action, result);
1629 return getVal;
1630 }
1631
1632 function warn(action, result) {
1633 var warningCondition = false;
1634 !warningCondition ? warningWithoutStack$1(false, "This synthetic event is reused for performance reasons. If you're seeing this, " + "you're %s `%s` on a released/nullified synthetic event. %s. " + 'If you must keep the original synthetic event around, use event.persist(). ' + 'See https://fb.me/react-event-pooling for more information.', action, propName, result) : void 0;
1635 }
1636}
1637
1638function getPooledEvent(dispatchConfig, targetInst, nativeEvent, nativeInst) {
1639 var EventConstructor = this;
1640 if (EventConstructor.eventPool.length) {
1641 var instance = EventConstructor.eventPool.pop();
1642 EventConstructor.call(instance, dispatchConfig, targetInst, nativeEvent, nativeInst);
1643 return instance;
1644 }
1645 return new EventConstructor(dispatchConfig, targetInst, nativeEvent, nativeInst);
1646}
1647
1648function releasePooledEvent(event) {
1649 var EventConstructor = this;
1650 !(event instanceof EventConstructor) ? invariant(false, 'Trying to release an event instance into a pool of a different type.') : void 0;
1651 event.destructor();
1652 if (EventConstructor.eventPool.length < EVENT_POOL_SIZE) {
1653 EventConstructor.eventPool.push(event);
1654 }
1655}
1656
1657function addEventPoolingTo(EventConstructor) {
1658 EventConstructor.eventPool = [];
1659 EventConstructor.getPooled = getPooledEvent;
1660 EventConstructor.release = releasePooledEvent;
1661}
1662
1663/**
1664 * @interface Event
1665 * @see http://www.w3.org/TR/DOM-Level-3-Events/#events-compositionevents
1666 */
1667var SyntheticCompositionEvent = SyntheticEvent.extend({
1668 data: null
1669});
1670
1671/**
1672 * @interface Event
1673 * @see http://www.w3.org/TR/2013/WD-DOM-Level-3-Events-20131105
1674 * /#events-inputevents
1675 */
1676var SyntheticInputEvent = SyntheticEvent.extend({
1677 data: null
1678});
1679
1680var END_KEYCODES = [9, 13, 27, 32]; // Tab, Return, Esc, Space
1681var START_KEYCODE = 229;
1682
1683var canUseCompositionEvent = canUseDOM && 'CompositionEvent' in window;
1684
1685var documentMode = null;
1686if (canUseDOM && 'documentMode' in document) {
1687 documentMode = document.documentMode;
1688}
1689
1690// Webkit offers a very useful `textInput` event that can be used to
1691// directly represent `beforeInput`. The IE `textinput` event is not as
1692// useful, so we don't use it.
1693var canUseTextInputEvent = canUseDOM && 'TextEvent' in window && !documentMode;
1694
1695// In IE9+, we have access to composition events, but the data supplied
1696// by the native compositionend event may be incorrect. Japanese ideographic
1697// spaces, for instance (\u3000) are not recorded correctly.
1698var useFallbackCompositionData = canUseDOM && (!canUseCompositionEvent || documentMode && documentMode > 8 && documentMode <= 11);
1699
1700var SPACEBAR_CODE = 32;
1701var SPACEBAR_CHAR = String.fromCharCode(SPACEBAR_CODE);
1702
1703// Events and their corresponding property names.
1704var eventTypes = {
1705 beforeInput: {
1706 phasedRegistrationNames: {
1707 bubbled: 'onBeforeInput',
1708 captured: 'onBeforeInputCapture'
1709 },
1710 dependencies: [TOP_COMPOSITION_END, TOP_KEY_PRESS, TOP_TEXT_INPUT, TOP_PASTE]
1711 },
1712 compositionEnd: {
1713 phasedRegistrationNames: {
1714 bubbled: 'onCompositionEnd',
1715 captured: 'onCompositionEndCapture'
1716 },
1717 dependencies: [TOP_BLUR, TOP_COMPOSITION_END, TOP_KEY_DOWN, TOP_KEY_PRESS, TOP_KEY_UP, TOP_MOUSE_DOWN]
1718 },
1719 compositionStart: {
1720 phasedRegistrationNames: {
1721 bubbled: 'onCompositionStart',
1722 captured: 'onCompositionStartCapture'
1723 },
1724 dependencies: [TOP_BLUR, TOP_COMPOSITION_START, TOP_KEY_DOWN, TOP_KEY_PRESS, TOP_KEY_UP, TOP_MOUSE_DOWN]
1725 },
1726 compositionUpdate: {
1727 phasedRegistrationNames: {
1728 bubbled: 'onCompositionUpdate',
1729 captured: 'onCompositionUpdateCapture'
1730 },
1731 dependencies: [TOP_BLUR, TOP_COMPOSITION_UPDATE, TOP_KEY_DOWN, TOP_KEY_PRESS, TOP_KEY_UP, TOP_MOUSE_DOWN]
1732 }
1733};
1734
1735// Track whether we've ever handled a keypress on the space key.
1736var hasSpaceKeypress = false;
1737
1738/**
1739 * Return whether a native keypress event is assumed to be a command.
1740 * This is required because Firefox fires `keypress` events for key commands
1741 * (cut, copy, select-all, etc.) even though no character is inserted.
1742 */
1743function isKeypressCommand(nativeEvent) {
1744 return (nativeEvent.ctrlKey || nativeEvent.altKey || nativeEvent.metaKey) &&
1745 // ctrlKey && altKey is equivalent to AltGr, and is not a command.
1746 !(nativeEvent.ctrlKey && nativeEvent.altKey);
1747}
1748
1749/**
1750 * Translate native top level events into event types.
1751 *
1752 * @param {string} topLevelType
1753 * @return {object}
1754 */
1755function getCompositionEventType(topLevelType) {
1756 switch (topLevelType) {
1757 case TOP_COMPOSITION_START:
1758 return eventTypes.compositionStart;
1759 case TOP_COMPOSITION_END:
1760 return eventTypes.compositionEnd;
1761 case TOP_COMPOSITION_UPDATE:
1762 return eventTypes.compositionUpdate;
1763 }
1764}
1765
1766/**
1767 * Does our fallback best-guess model think this event signifies that
1768 * composition has begun?
1769 *
1770 * @param {string} topLevelType
1771 * @param {object} nativeEvent
1772 * @return {boolean}
1773 */
1774function isFallbackCompositionStart(topLevelType, nativeEvent) {
1775 return topLevelType === TOP_KEY_DOWN && nativeEvent.keyCode === START_KEYCODE;
1776}
1777
1778/**
1779 * Does our fallback mode think that this event is the end of composition?
1780 *
1781 * @param {string} topLevelType
1782 * @param {object} nativeEvent
1783 * @return {boolean}
1784 */
1785function isFallbackCompositionEnd(topLevelType, nativeEvent) {
1786 switch (topLevelType) {
1787 case TOP_KEY_UP:
1788 // Command keys insert or clear IME input.
1789 return END_KEYCODES.indexOf(nativeEvent.keyCode) !== -1;
1790 case TOP_KEY_DOWN:
1791 // Expect IME keyCode on each keydown. If we get any other
1792 // code we must have exited earlier.
1793 return nativeEvent.keyCode !== START_KEYCODE;
1794 case TOP_KEY_PRESS:
1795 case TOP_MOUSE_DOWN:
1796 case TOP_BLUR:
1797 // Events are not possible without cancelling IME.
1798 return true;
1799 default:
1800 return false;
1801 }
1802}
1803
1804/**
1805 * Google Input Tools provides composition data via a CustomEvent,
1806 * with the `data` property populated in the `detail` object. If this
1807 * is available on the event object, use it. If not, this is a plain
1808 * composition event and we have nothing special to extract.
1809 *
1810 * @param {object} nativeEvent
1811 * @return {?string}
1812 */
1813function getDataFromCustomEvent(nativeEvent) {
1814 var detail = nativeEvent.detail;
1815 if (typeof detail === 'object' && 'data' in detail) {
1816 return detail.data;
1817 }
1818 return null;
1819}
1820
1821/**
1822 * Check if a composition event was triggered by Korean IME.
1823 * Our fallback mode does not work well with IE's Korean IME,
1824 * so just use native composition events when Korean IME is used.
1825 * Although CompositionEvent.locale property is deprecated,
1826 * it is available in IE, where our fallback mode is enabled.
1827 *
1828 * @param {object} nativeEvent
1829 * @return {boolean}
1830 */
1831function isUsingKoreanIME(nativeEvent) {
1832 return nativeEvent.locale === 'ko';
1833}
1834
1835// Track the current IME composition status, if any.
1836var isComposing = false;
1837
1838/**
1839 * @return {?object} A SyntheticCompositionEvent.
1840 */
1841function extractCompositionEvent(topLevelType, targetInst, nativeEvent, nativeEventTarget) {
1842 var eventType = void 0;
1843 var fallbackData = void 0;
1844
1845 if (canUseCompositionEvent) {
1846 eventType = getCompositionEventType(topLevelType);
1847 } else if (!isComposing) {
1848 if (isFallbackCompositionStart(topLevelType, nativeEvent)) {
1849 eventType = eventTypes.compositionStart;
1850 }
1851 } else if (isFallbackCompositionEnd(topLevelType, nativeEvent)) {
1852 eventType = eventTypes.compositionEnd;
1853 }
1854
1855 if (!eventType) {
1856 return null;
1857 }
1858
1859 if (useFallbackCompositionData && !isUsingKoreanIME(nativeEvent)) {
1860 // The current composition is stored statically and must not be
1861 // overwritten while composition continues.
1862 if (!isComposing && eventType === eventTypes.compositionStart) {
1863 isComposing = initialize(nativeEventTarget);
1864 } else if (eventType === eventTypes.compositionEnd) {
1865 if (isComposing) {
1866 fallbackData = getData();
1867 }
1868 }
1869 }
1870
1871 var event = SyntheticCompositionEvent.getPooled(eventType, targetInst, nativeEvent, nativeEventTarget);
1872
1873 if (fallbackData) {
1874 // Inject data generated from fallback path into the synthetic event.
1875 // This matches the property of native CompositionEventInterface.
1876 event.data = fallbackData;
1877 } else {
1878 var customData = getDataFromCustomEvent(nativeEvent);
1879 if (customData !== null) {
1880 event.data = customData;
1881 }
1882 }
1883
1884 accumulateTwoPhaseDispatches(event);
1885 return event;
1886}
1887
1888/**
1889 * @param {TopLevelType} topLevelType Number from `TopLevelType`.
1890 * @param {object} nativeEvent Native browser event.
1891 * @return {?string} The string corresponding to this `beforeInput` event.
1892 */
1893function getNativeBeforeInputChars(topLevelType, nativeEvent) {
1894 switch (topLevelType) {
1895 case TOP_COMPOSITION_END:
1896 return getDataFromCustomEvent(nativeEvent);
1897 case TOP_KEY_PRESS:
1898 /**
1899 * If native `textInput` events are available, our goal is to make
1900 * use of them. However, there is a special case: the spacebar key.
1901 * In Webkit, preventing default on a spacebar `textInput` event
1902 * cancels character insertion, but it *also* causes the browser
1903 * to fall back to its default spacebar behavior of scrolling the
1904 * page.
1905 *
1906 * Tracking at:
1907 * https://code.google.com/p/chromium/issues/detail?id=355103
1908 *
1909 * To avoid this issue, use the keypress event as if no `textInput`
1910 * event is available.
1911 */
1912 var which = nativeEvent.which;
1913 if (which !== SPACEBAR_CODE) {
1914 return null;
1915 }
1916
1917 hasSpaceKeypress = true;
1918 return SPACEBAR_CHAR;
1919
1920 case TOP_TEXT_INPUT:
1921 // Record the characters to be added to the DOM.
1922 var chars = nativeEvent.data;
1923
1924 // If it's a spacebar character, assume that we have already handled
1925 // it at the keypress level and bail immediately. Android Chrome
1926 // doesn't give us keycodes, so we need to ignore it.
1927 if (chars === SPACEBAR_CHAR && hasSpaceKeypress) {
1928 return null;
1929 }
1930
1931 return chars;
1932
1933 default:
1934 // For other native event types, do nothing.
1935 return null;
1936 }
1937}
1938
1939/**
1940 * For browsers that do not provide the `textInput` event, extract the
1941 * appropriate string to use for SyntheticInputEvent.
1942 *
1943 * @param {number} topLevelType Number from `TopLevelEventTypes`.
1944 * @param {object} nativeEvent Native browser event.
1945 * @return {?string} The fallback string for this `beforeInput` event.
1946 */
1947function getFallbackBeforeInputChars(topLevelType, nativeEvent) {
1948 // If we are currently composing (IME) and using a fallback to do so,
1949 // try to extract the composed characters from the fallback object.
1950 // If composition event is available, we extract a string only at
1951 // compositionevent, otherwise extract it at fallback events.
1952 if (isComposing) {
1953 if (topLevelType === TOP_COMPOSITION_END || !canUseCompositionEvent && isFallbackCompositionEnd(topLevelType, nativeEvent)) {
1954 var chars = getData();
1955 reset();
1956 isComposing = false;
1957 return chars;
1958 }
1959 return null;
1960 }
1961
1962 switch (topLevelType) {
1963 case TOP_PASTE:
1964 // If a paste event occurs after a keypress, throw out the input
1965 // chars. Paste events should not lead to BeforeInput events.
1966 return null;
1967 case TOP_KEY_PRESS:
1968 /**
1969 * As of v27, Firefox may fire keypress events even when no character
1970 * will be inserted. A few possibilities:
1971 *
1972 * - `which` is `0`. Arrow keys, Esc key, etc.
1973 *
1974 * - `which` is the pressed key code, but no char is available.
1975 * Ex: 'AltGr + d` in Polish. There is no modified character for
1976 * this key combination and no character is inserted into the
1977 * document, but FF fires the keypress for char code `100` anyway.
1978 * No `input` event will occur.
1979 *
1980 * - `which` is the pressed key code, but a command combination is
1981 * being used. Ex: `Cmd+C`. No character is inserted, and no
1982 * `input` event will occur.
1983 */
1984 if (!isKeypressCommand(nativeEvent)) {
1985 // IE fires the `keypress` event when a user types an emoji via
1986 // Touch keyboard of Windows. In such a case, the `char` property
1987 // holds an emoji character like `\uD83D\uDE0A`. Because its length
1988 // is 2, the property `which` does not represent an emoji correctly.
1989 // In such a case, we directly return the `char` property instead of
1990 // using `which`.
1991 if (nativeEvent.char && nativeEvent.char.length > 1) {
1992 return nativeEvent.char;
1993 } else if (nativeEvent.which) {
1994 return String.fromCharCode(nativeEvent.which);
1995 }
1996 }
1997 return null;
1998 case TOP_COMPOSITION_END:
1999 return useFallbackCompositionData && !isUsingKoreanIME(nativeEvent) ? null : nativeEvent.data;
2000 default:
2001 return null;
2002 }
2003}
2004
2005/**
2006 * Extract a SyntheticInputEvent for `beforeInput`, based on either native
2007 * `textInput` or fallback behavior.
2008 *
2009 * @return {?object} A SyntheticInputEvent.
2010 */
2011function extractBeforeInputEvent(topLevelType, targetInst, nativeEvent, nativeEventTarget) {
2012 var chars = void 0;
2013
2014 if (canUseTextInputEvent) {
2015 chars = getNativeBeforeInputChars(topLevelType, nativeEvent);
2016 } else {
2017 chars = getFallbackBeforeInputChars(topLevelType, nativeEvent);
2018 }
2019
2020 // If no characters are being inserted, no BeforeInput event should
2021 // be fired.
2022 if (!chars) {
2023 return null;
2024 }
2025
2026 var event = SyntheticInputEvent.getPooled(eventTypes.beforeInput, targetInst, nativeEvent, nativeEventTarget);
2027
2028 event.data = chars;
2029 accumulateTwoPhaseDispatches(event);
2030 return event;
2031}
2032
2033/**
2034 * Create an `onBeforeInput` event to match
2035 * http://www.w3.org/TR/2013/WD-DOM-Level-3-Events-20131105/#events-inputevents.
2036 *
2037 * This event plugin is based on the native `textInput` event
2038 * available in Chrome, Safari, Opera, and IE. This event fires after
2039 * `onKeyPress` and `onCompositionEnd`, but before `onInput`.
2040 *
2041 * `beforeInput` is spec'd but not implemented in any browsers, and
2042 * the `input` event does not provide any useful information about what has
2043 * actually been added, contrary to the spec. Thus, `textInput` is the best
2044 * available event to identify the characters that have actually been inserted
2045 * into the target node.
2046 *
2047 * This plugin is also responsible for emitting `composition` events, thus
2048 * allowing us to share composition fallback code for both `beforeInput` and
2049 * `composition` event types.
2050 */
2051var BeforeInputEventPlugin = {
2052 eventTypes: eventTypes,
2053
2054 extractEvents: function (topLevelType, targetInst, nativeEvent, nativeEventTarget) {
2055 var composition = extractCompositionEvent(topLevelType, targetInst, nativeEvent, nativeEventTarget);
2056
2057 var beforeInput = extractBeforeInputEvent(topLevelType, targetInst, nativeEvent, nativeEventTarget);
2058
2059 if (composition === null) {
2060 return beforeInput;
2061 }
2062
2063 if (beforeInput === null) {
2064 return composition;
2065 }
2066
2067 return [composition, beforeInput];
2068 }
2069};
2070
2071// Use to restore controlled state after a change event has fired.
2072
2073var restoreImpl = null;
2074var restoreTarget = null;
2075var restoreQueue = null;
2076
2077function restoreStateOfTarget(target) {
2078 // We perform this translation at the end of the event loop so that we
2079 // always receive the correct fiber here
2080 var internalInstance = getInstanceFromNode(target);
2081 if (!internalInstance) {
2082 // Unmounted
2083 return;
2084 }
2085 !(typeof restoreImpl === 'function') ? invariant(false, 'setRestoreImplementation() needs to be called to handle a target for controlled events. This error is likely caused by a bug in React. Please file an issue.') : void 0;
2086 var props = getFiberCurrentPropsFromNode(internalInstance.stateNode);
2087 restoreImpl(internalInstance.stateNode, internalInstance.type, props);
2088}
2089
2090function setRestoreImplementation(impl) {
2091 restoreImpl = impl;
2092}
2093
2094function enqueueStateRestore(target) {
2095 if (restoreTarget) {
2096 if (restoreQueue) {
2097 restoreQueue.push(target);
2098 } else {
2099 restoreQueue = [target];
2100 }
2101 } else {
2102 restoreTarget = target;
2103 }
2104}
2105
2106function needsStateRestore() {
2107 return restoreTarget !== null || restoreQueue !== null;
2108}
2109
2110function restoreStateIfNeeded() {
2111 if (!restoreTarget) {
2112 return;
2113 }
2114 var target = restoreTarget;
2115 var queuedTargets = restoreQueue;
2116 restoreTarget = null;
2117 restoreQueue = null;
2118
2119 restoreStateOfTarget(target);
2120 if (queuedTargets) {
2121 for (var i = 0; i < queuedTargets.length; i++) {
2122 restoreStateOfTarget(queuedTargets[i]);
2123 }
2124 }
2125}
2126
2127// Used as a way to call batchedUpdates when we don't have a reference to
2128// the renderer. Such as when we're dispatching events or if third party
2129// libraries need to call batchedUpdates. Eventually, this API will go away when
2130// everything is batched by default. We'll then have a similar API to opt-out of
2131// scheduled work and instead do synchronous work.
2132
2133// Defaults
2134var _batchedUpdatesImpl = function (fn, bookkeeping) {
2135 return fn(bookkeeping);
2136};
2137var _interactiveUpdatesImpl = function (fn, a, b) {
2138 return fn(a, b);
2139};
2140var _flushInteractiveUpdatesImpl = function () {};
2141
2142var isBatching = false;
2143function batchedUpdates(fn, bookkeeping) {
2144 if (isBatching) {
2145 // If we are currently inside another batch, we need to wait until it
2146 // fully completes before restoring state.
2147 return fn(bookkeeping);
2148 }
2149 isBatching = true;
2150 try {
2151 return _batchedUpdatesImpl(fn, bookkeeping);
2152 } finally {
2153 // Here we wait until all updates have propagated, which is important
2154 // when using controlled components within layers:
2155 // https://github.com/facebook/react/issues/1698
2156 // Then we restore state of any controlled component.
2157 isBatching = false;
2158 var controlledComponentsHavePendingUpdates = needsStateRestore();
2159 if (controlledComponentsHavePendingUpdates) {
2160 // If a controlled event was fired, we may need to restore the state of
2161 // the DOM node back to the controlled value. This is necessary when React
2162 // bails out of the update without touching the DOM.
2163 _flushInteractiveUpdatesImpl();
2164 restoreStateIfNeeded();
2165 }
2166 }
2167}
2168
2169function interactiveUpdates(fn, a, b) {
2170 return _interactiveUpdatesImpl(fn, a, b);
2171}
2172
2173
2174
2175function setBatchingImplementation(batchedUpdatesImpl, interactiveUpdatesImpl, flushInteractiveUpdatesImpl) {
2176 _batchedUpdatesImpl = batchedUpdatesImpl;
2177 _interactiveUpdatesImpl = interactiveUpdatesImpl;
2178 _flushInteractiveUpdatesImpl = flushInteractiveUpdatesImpl;
2179}
2180
2181/**
2182 * @see http://www.whatwg.org/specs/web-apps/current-work/multipage/the-input-element.html#input-type-attr-summary
2183 */
2184var supportedInputTypes = {
2185 color: true,
2186 date: true,
2187 datetime: true,
2188 'datetime-local': true,
2189 email: true,
2190 month: true,
2191 number: true,
2192 password: true,
2193 range: true,
2194 search: true,
2195 tel: true,
2196 text: true,
2197 time: true,
2198 url: true,
2199 week: true
2200};
2201
2202function isTextInputElement(elem) {
2203 var nodeName = elem && elem.nodeName && elem.nodeName.toLowerCase();
2204
2205 if (nodeName === 'input') {
2206 return !!supportedInputTypes[elem.type];
2207 }
2208
2209 if (nodeName === 'textarea') {
2210 return true;
2211 }
2212
2213 return false;
2214}
2215
2216/**
2217 * HTML nodeType values that represent the type of the node
2218 */
2219
2220var ELEMENT_NODE = 1;
2221var TEXT_NODE = 3;
2222var COMMENT_NODE = 8;
2223var DOCUMENT_NODE = 9;
2224var DOCUMENT_FRAGMENT_NODE = 11;
2225
2226/**
2227 * Gets the target node from a native browser event by accounting for
2228 * inconsistencies in browser DOM APIs.
2229 *
2230 * @param {object} nativeEvent Native browser event.
2231 * @return {DOMEventTarget} Target node.
2232 */
2233function getEventTarget(nativeEvent) {
2234 // Fallback to nativeEvent.srcElement for IE9
2235 // https://github.com/facebook/react/issues/12506
2236 var target = nativeEvent.target || nativeEvent.srcElement || window;
2237
2238 // Normalize SVG <use> element events #4963
2239 if (target.correspondingUseElement) {
2240 target = target.correspondingUseElement;
2241 }
2242
2243 // Safari may fire events on text nodes (Node.TEXT_NODE is 3).
2244 // @see http://www.quirksmode.org/js/events_properties.html
2245 return target.nodeType === TEXT_NODE ? target.parentNode : target;
2246}
2247
2248/**
2249 * Checks if an event is supported in the current execution environment.
2250 *
2251 * NOTE: This will not work correctly for non-generic events such as `change`,
2252 * `reset`, `load`, `error`, and `select`.
2253 *
2254 * Borrows from Modernizr.
2255 *
2256 * @param {string} eventNameSuffix Event name, e.g. "click".
2257 * @return {boolean} True if the event is supported.
2258 * @internal
2259 * @license Modernizr 3.0.0pre (Custom Build) | MIT
2260 */
2261function isEventSupported(eventNameSuffix) {
2262 if (!canUseDOM) {
2263 return false;
2264 }
2265
2266 var eventName = 'on' + eventNameSuffix;
2267 var isSupported = eventName in document;
2268
2269 if (!isSupported) {
2270 var element = document.createElement('div');
2271 element.setAttribute(eventName, 'return;');
2272 isSupported = typeof element[eventName] === 'function';
2273 }
2274
2275 return isSupported;
2276}
2277
2278function isCheckable(elem) {
2279 var type = elem.type;
2280 var nodeName = elem.nodeName;
2281 return nodeName && nodeName.toLowerCase() === 'input' && (type === 'checkbox' || type === 'radio');
2282}
2283
2284function getTracker(node) {
2285 return node._valueTracker;
2286}
2287
2288function detachTracker(node) {
2289 node._valueTracker = null;
2290}
2291
2292function getValueFromNode(node) {
2293 var value = '';
2294 if (!node) {
2295 return value;
2296 }
2297
2298 if (isCheckable(node)) {
2299 value = node.checked ? 'true' : 'false';
2300 } else {
2301 value = node.value;
2302 }
2303
2304 return value;
2305}
2306
2307function trackValueOnNode(node) {
2308 var valueField = isCheckable(node) ? 'checked' : 'value';
2309 var descriptor = Object.getOwnPropertyDescriptor(node.constructor.prototype, valueField);
2310
2311 var currentValue = '' + node[valueField];
2312
2313 // if someone has already defined a value or Safari, then bail
2314 // and don't track value will cause over reporting of changes,
2315 // but it's better then a hard failure
2316 // (needed for certain tests that spyOn input values and Safari)
2317 if (node.hasOwnProperty(valueField) || typeof descriptor === 'undefined' || typeof descriptor.get !== 'function' || typeof descriptor.set !== 'function') {
2318 return;
2319 }
2320 var get = descriptor.get,
2321 set = descriptor.set;
2322
2323 Object.defineProperty(node, valueField, {
2324 configurable: true,
2325 get: function () {
2326 return get.call(this);
2327 },
2328 set: function (value) {
2329 currentValue = '' + value;
2330 set.call(this, value);
2331 }
2332 });
2333 // We could've passed this the first time
2334 // but it triggers a bug in IE11 and Edge 14/15.
2335 // Calling defineProperty() again should be equivalent.
2336 // https://github.com/facebook/react/issues/11768
2337 Object.defineProperty(node, valueField, {
2338 enumerable: descriptor.enumerable
2339 });
2340
2341 var tracker = {
2342 getValue: function () {
2343 return currentValue;
2344 },
2345 setValue: function (value) {
2346 currentValue = '' + value;
2347 },
2348 stopTracking: function () {
2349 detachTracker(node);
2350 delete node[valueField];
2351 }
2352 };
2353 return tracker;
2354}
2355
2356function track(node) {
2357 if (getTracker(node)) {
2358 return;
2359 }
2360
2361 // TODO: Once it's just Fiber we can move this to node._wrapperState
2362 node._valueTracker = trackValueOnNode(node);
2363}
2364
2365function updateValueIfChanged(node) {
2366 if (!node) {
2367 return false;
2368 }
2369
2370 var tracker = getTracker(node);
2371 // if there is no tracker at this point it's unlikely
2372 // that trying again will succeed
2373 if (!tracker) {
2374 return true;
2375 }
2376
2377 var lastValue = tracker.getValue();
2378 var nextValue = getValueFromNode(node);
2379 if (nextValue !== lastValue) {
2380 tracker.setValue(nextValue);
2381 return true;
2382 }
2383 return false;
2384}
2385
2386var ReactSharedInternals = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
2387
2388// Prevent newer renderers from RTE when used with older react package versions.
2389// Current owner and dispatcher used to share the same ref,
2390// but PR #14548 split them out to better support the react-debug-tools package.
2391if (!ReactSharedInternals.hasOwnProperty('ReactCurrentDispatcher')) {
2392 ReactSharedInternals.ReactCurrentDispatcher = {
2393 current: null
2394 };
2395}
2396
2397var BEFORE_SLASH_RE = /^(.*)[\\\/]/;
2398
2399var describeComponentFrame = function (name, source, ownerName) {
2400 var sourceInfo = '';
2401 if (source) {
2402 var path = source.fileName;
2403 var fileName = path.replace(BEFORE_SLASH_RE, '');
2404 {
2405 // In DEV, include code for a common special case:
2406 // prefer "folder/index.js" instead of just "index.js".
2407 if (/^index\./.test(fileName)) {
2408 var match = path.match(BEFORE_SLASH_RE);
2409 if (match) {
2410 var pathBeforeSlash = match[1];
2411 if (pathBeforeSlash) {
2412 var folderName = pathBeforeSlash.replace(BEFORE_SLASH_RE, '');
2413 fileName = folderName + '/' + fileName;
2414 }
2415 }
2416 }
2417 }
2418 sourceInfo = ' (at ' + fileName + ':' + source.lineNumber + ')';
2419 } else if (ownerName) {
2420 sourceInfo = ' (created by ' + ownerName + ')';
2421 }
2422 return '\n in ' + (name || 'Unknown') + sourceInfo;
2423};
2424
2425// The Symbol used to tag the ReactElement-like types. If there is no native Symbol
2426// nor polyfill, then a plain number is used for performance.
2427var hasSymbol = typeof Symbol === 'function' && Symbol.for;
2428
2429var REACT_ELEMENT_TYPE = hasSymbol ? Symbol.for('react.element') : 0xeac7;
2430var REACT_PORTAL_TYPE = hasSymbol ? Symbol.for('react.portal') : 0xeaca;
2431var REACT_FRAGMENT_TYPE = hasSymbol ? Symbol.for('react.fragment') : 0xeacb;
2432var REACT_STRICT_MODE_TYPE = hasSymbol ? Symbol.for('react.strict_mode') : 0xeacc;
2433var REACT_PROFILER_TYPE = hasSymbol ? Symbol.for('react.profiler') : 0xead2;
2434var REACT_PROVIDER_TYPE = hasSymbol ? Symbol.for('react.provider') : 0xeacd;
2435var REACT_CONTEXT_TYPE = hasSymbol ? Symbol.for('react.context') : 0xeace;
2436
2437var REACT_CONCURRENT_MODE_TYPE = hasSymbol ? Symbol.for('react.concurrent_mode') : 0xeacf;
2438var REACT_FORWARD_REF_TYPE = hasSymbol ? Symbol.for('react.forward_ref') : 0xead0;
2439var REACT_SUSPENSE_TYPE = hasSymbol ? Symbol.for('react.suspense') : 0xead1;
2440var REACT_MEMO_TYPE = hasSymbol ? Symbol.for('react.memo') : 0xead3;
2441var REACT_LAZY_TYPE = hasSymbol ? Symbol.for('react.lazy') : 0xead4;
2442
2443var MAYBE_ITERATOR_SYMBOL = typeof Symbol === 'function' && Symbol.iterator;
2444var FAUX_ITERATOR_SYMBOL = '@@iterator';
2445
2446function getIteratorFn(maybeIterable) {
2447 if (maybeIterable === null || typeof maybeIterable !== 'object') {
2448 return null;
2449 }
2450 var maybeIterator = MAYBE_ITERATOR_SYMBOL && maybeIterable[MAYBE_ITERATOR_SYMBOL] || maybeIterable[FAUX_ITERATOR_SYMBOL];
2451 if (typeof maybeIterator === 'function') {
2452 return maybeIterator;
2453 }
2454 return null;
2455}
2456
2457var Pending = 0;
2458var Resolved = 1;
2459var Rejected = 2;
2460
2461function refineResolvedLazyComponent(lazyComponent) {
2462 return lazyComponent._status === Resolved ? lazyComponent._result : null;
2463}
2464
2465function getWrappedName(outerType, innerType, wrapperName) {
2466 var functionName = innerType.displayName || innerType.name || '';
2467 return outerType.displayName || (functionName !== '' ? wrapperName + '(' + functionName + ')' : wrapperName);
2468}
2469
2470function getComponentName(type) {
2471 if (type == null) {
2472 // Host root, text node or just invalid type.
2473 return null;
2474 }
2475 {
2476 if (typeof type.tag === 'number') {
2477 warningWithoutStack$1(false, 'Received an unexpected object in getComponentName(). ' + 'This is likely a bug in React. Please file an issue.');
2478 }
2479 }
2480 if (typeof type === 'function') {
2481 return type.displayName || type.name || null;
2482 }
2483 if (typeof type === 'string') {
2484 return type;
2485 }
2486 switch (type) {
2487 case REACT_CONCURRENT_MODE_TYPE:
2488 return 'ConcurrentMode';
2489 case REACT_FRAGMENT_TYPE:
2490 return 'Fragment';
2491 case REACT_PORTAL_TYPE:
2492 return 'Portal';
2493 case REACT_PROFILER_TYPE:
2494 return 'Profiler';
2495 case REACT_STRICT_MODE_TYPE:
2496 return 'StrictMode';
2497 case REACT_SUSPENSE_TYPE:
2498 return 'Suspense';
2499 }
2500 if (typeof type === 'object') {
2501 switch (type.$$typeof) {
2502 case REACT_CONTEXT_TYPE:
2503 return 'Context.Consumer';
2504 case REACT_PROVIDER_TYPE:
2505 return 'Context.Provider';
2506 case REACT_FORWARD_REF_TYPE:
2507 return getWrappedName(type, type.render, 'ForwardRef');
2508 case REACT_MEMO_TYPE:
2509 return getComponentName(type.type);
2510 case REACT_LAZY_TYPE:
2511 {
2512 var thenable = type;
2513 var resolvedThenable = refineResolvedLazyComponent(thenable);
2514 if (resolvedThenable) {
2515 return getComponentName(resolvedThenable);
2516 }
2517 }
2518 }
2519 }
2520 return null;
2521}
2522
2523var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame;
2524
2525function describeFiber(fiber) {
2526 switch (fiber.tag) {
2527 case HostRoot:
2528 case HostPortal:
2529 case HostText:
2530 case Fragment:
2531 case ContextProvider:
2532 case ContextConsumer:
2533 return '';
2534 default:
2535 var owner = fiber._debugOwner;
2536 var source = fiber._debugSource;
2537 var name = getComponentName(fiber.type);
2538 var ownerName = null;
2539 if (owner) {
2540 ownerName = getComponentName(owner.type);
2541 }
2542 return describeComponentFrame(name, source, ownerName);
2543 }
2544}
2545
2546function getStackByFiberInDevAndProd(workInProgress) {
2547 var info = '';
2548 var node = workInProgress;
2549 do {
2550 info += describeFiber(node);
2551 node = node.return;
2552 } while (node);
2553 return info;
2554}
2555
2556var current = null;
2557var phase = null;
2558
2559function getCurrentFiberOwnerNameInDevOrNull() {
2560 {
2561 if (current === null) {
2562 return null;
2563 }
2564 var owner = current._debugOwner;
2565 if (owner !== null && typeof owner !== 'undefined') {
2566 return getComponentName(owner.type);
2567 }
2568 }
2569 return null;
2570}
2571
2572function getCurrentFiberStackInDev() {
2573 {
2574 if (current === null) {
2575 return '';
2576 }
2577 // Safe because if current fiber exists, we are reconciling,
2578 // and it is guaranteed to be the work-in-progress version.
2579 return getStackByFiberInDevAndProd(current);
2580 }
2581 return '';
2582}
2583
2584function resetCurrentFiber() {
2585 {
2586 ReactDebugCurrentFrame.getCurrentStack = null;
2587 current = null;
2588 phase = null;
2589 }
2590}
2591
2592function setCurrentFiber(fiber) {
2593 {
2594 ReactDebugCurrentFrame.getCurrentStack = getCurrentFiberStackInDev;
2595 current = fiber;
2596 phase = null;
2597 }
2598}
2599
2600function setCurrentPhase(lifeCyclePhase) {
2601 {
2602 phase = lifeCyclePhase;
2603 }
2604}
2605
2606/**
2607 * Similar to invariant but only logs a warning if the condition is not met.
2608 * This can be used to log issues in development environments in critical
2609 * paths. Removing the logging code for production environments will keep the
2610 * same logic and follow the same code paths.
2611 */
2612
2613var warning = warningWithoutStack$1;
2614
2615{
2616 warning = function (condition, format) {
2617 if (condition) {
2618 return;
2619 }
2620 var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame;
2621 var stack = ReactDebugCurrentFrame.getStackAddendum();
2622 // eslint-disable-next-line react-internal/warning-and-invariant-args
2623
2624 for (var _len = arguments.length, args = Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) {
2625 args[_key - 2] = arguments[_key];
2626 }
2627
2628 warningWithoutStack$1.apply(undefined, [false, format + '%s'].concat(args, [stack]));
2629 };
2630}
2631
2632var warning$1 = warning;
2633
2634// A reserved attribute.
2635// It is handled by React separately and shouldn't be written to the DOM.
2636var RESERVED = 0;
2637
2638// A simple string attribute.
2639// Attributes that aren't in the whitelist are presumed to have this type.
2640var STRING = 1;
2641
2642// A string attribute that accepts booleans in React. In HTML, these are called
2643// "enumerated" attributes with "true" and "false" as possible values.
2644// When true, it should be set to a "true" string.
2645// When false, it should be set to a "false" string.
2646var BOOLEANISH_STRING = 2;
2647
2648// A real boolean attribute.
2649// When true, it should be present (set either to an empty string or its name).
2650// When false, it should be omitted.
2651var BOOLEAN = 3;
2652
2653// An attribute that can be used as a flag as well as with a value.
2654// When true, it should be present (set either to an empty string or its name).
2655// When false, it should be omitted.
2656// For any other value, should be present with that value.
2657var OVERLOADED_BOOLEAN = 4;
2658
2659// An attribute that must be numeric or parse as a numeric.
2660// When falsy, it should be removed.
2661var NUMERIC = 5;
2662
2663// An attribute that must be positive numeric or parse as a positive numeric.
2664// When falsy, it should be removed.
2665var POSITIVE_NUMERIC = 6;
2666
2667/* eslint-disable max-len */
2668var ATTRIBUTE_NAME_START_CHAR = ':A-Z_a-z\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02FF\\u0370-\\u037D\\u037F-\\u1FFF\\u200C-\\u200D\\u2070-\\u218F\\u2C00-\\u2FEF\\u3001-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFFD';
2669/* eslint-enable max-len */
2670var ATTRIBUTE_NAME_CHAR = ATTRIBUTE_NAME_START_CHAR + '\\-.0-9\\u00B7\\u0300-\\u036F\\u203F-\\u2040';
2671
2672
2673var ROOT_ATTRIBUTE_NAME = 'data-reactroot';
2674var VALID_ATTRIBUTE_NAME_REGEX = new RegExp('^[' + ATTRIBUTE_NAME_START_CHAR + '][' + ATTRIBUTE_NAME_CHAR + ']*$');
2675
2676var hasOwnProperty = Object.prototype.hasOwnProperty;
2677var illegalAttributeNameCache = {};
2678var validatedAttributeNameCache = {};
2679
2680function isAttributeNameSafe(attributeName) {
2681 if (hasOwnProperty.call(validatedAttributeNameCache, attributeName)) {
2682 return true;
2683 }
2684 if (hasOwnProperty.call(illegalAttributeNameCache, attributeName)) {
2685 return false;
2686 }
2687 if (VALID_ATTRIBUTE_NAME_REGEX.test(attributeName)) {
2688 validatedAttributeNameCache[attributeName] = true;
2689 return true;
2690 }
2691 illegalAttributeNameCache[attributeName] = true;
2692 {
2693 warning$1(false, 'Invalid attribute name: `%s`', attributeName);
2694 }
2695 return false;
2696}
2697
2698function shouldIgnoreAttribute(name, propertyInfo, isCustomComponentTag) {
2699 if (propertyInfo !== null) {
2700 return propertyInfo.type === RESERVED;
2701 }
2702 if (isCustomComponentTag) {
2703 return false;
2704 }
2705 if (name.length > 2 && (name[0] === 'o' || name[0] === 'O') && (name[1] === 'n' || name[1] === 'N')) {
2706 return true;
2707 }
2708 return false;
2709}
2710
2711function shouldRemoveAttributeWithWarning(name, value, propertyInfo, isCustomComponentTag) {
2712 if (propertyInfo !== null && propertyInfo.type === RESERVED) {
2713 return false;
2714 }
2715 switch (typeof value) {
2716 case 'function':
2717 // $FlowIssue symbol is perfectly valid here
2718 case 'symbol':
2719 // eslint-disable-line
2720 return true;
2721 case 'boolean':
2722 {
2723 if (isCustomComponentTag) {
2724 return false;
2725 }
2726 if (propertyInfo !== null) {
2727 return !propertyInfo.acceptsBooleans;
2728 } else {
2729 var prefix = name.toLowerCase().slice(0, 5);
2730 return prefix !== 'data-' && prefix !== 'aria-';
2731 }
2732 }
2733 default:
2734 return false;
2735 }
2736}
2737
2738function shouldRemoveAttribute(name, value, propertyInfo, isCustomComponentTag) {
2739 if (value === null || typeof value === 'undefined') {
2740 return true;
2741 }
2742 if (shouldRemoveAttributeWithWarning(name, value, propertyInfo, isCustomComponentTag)) {
2743 return true;
2744 }
2745 if (isCustomComponentTag) {
2746 return false;
2747 }
2748 if (propertyInfo !== null) {
2749 switch (propertyInfo.type) {
2750 case BOOLEAN:
2751 return !value;
2752 case OVERLOADED_BOOLEAN:
2753 return value === false;
2754 case NUMERIC:
2755 return isNaN(value);
2756 case POSITIVE_NUMERIC:
2757 return isNaN(value) || value < 1;
2758 }
2759 }
2760 return false;
2761}
2762
2763function getPropertyInfo(name) {
2764 return properties.hasOwnProperty(name) ? properties[name] : null;
2765}
2766
2767function PropertyInfoRecord(name, type, mustUseProperty, attributeName, attributeNamespace) {
2768 this.acceptsBooleans = type === BOOLEANISH_STRING || type === BOOLEAN || type === OVERLOADED_BOOLEAN;
2769 this.attributeName = attributeName;
2770 this.attributeNamespace = attributeNamespace;
2771 this.mustUseProperty = mustUseProperty;
2772 this.propertyName = name;
2773 this.type = type;
2774}
2775
2776// When adding attributes to this list, be sure to also add them to
2777// the `possibleStandardNames` module to ensure casing and incorrect
2778// name warnings.
2779var properties = {};
2780
2781// These props are reserved by React. They shouldn't be written to the DOM.
2782['children', 'dangerouslySetInnerHTML',
2783// TODO: This prevents the assignment of defaultValue to regular
2784// elements (not just inputs). Now that ReactDOMInput assigns to the
2785// defaultValue property -- do we need this?
2786'defaultValue', 'defaultChecked', 'innerHTML', 'suppressContentEditableWarning', 'suppressHydrationWarning', 'style'].forEach(function (name) {
2787 properties[name] = new PropertyInfoRecord(name, RESERVED, false, // mustUseProperty
2788 name, // attributeName
2789 null);
2790} // attributeNamespace
2791);
2792
2793// A few React string attributes have a different name.
2794// This is a mapping from React prop names to the attribute names.
2795[['acceptCharset', 'accept-charset'], ['className', 'class'], ['htmlFor', 'for'], ['httpEquiv', 'http-equiv']].forEach(function (_ref) {
2796 var name = _ref[0],
2797 attributeName = _ref[1];
2798
2799 properties[name] = new PropertyInfoRecord(name, STRING, false, // mustUseProperty
2800 attributeName, // attributeName
2801 null);
2802} // attributeNamespace
2803);
2804
2805// These are "enumerated" HTML attributes that accept "true" and "false".
2806// In React, we let users pass `true` and `false` even though technically
2807// these aren't boolean attributes (they are coerced to strings).
2808['contentEditable', 'draggable', 'spellCheck', 'value'].forEach(function (name) {
2809 properties[name] = new PropertyInfoRecord(name, BOOLEANISH_STRING, false, // mustUseProperty
2810 name.toLowerCase(), // attributeName
2811 null);
2812} // attributeNamespace
2813);
2814
2815// These are "enumerated" SVG attributes that accept "true" and "false".
2816// In React, we let users pass `true` and `false` even though technically
2817// these aren't boolean attributes (they are coerced to strings).
2818// Since these are SVG attributes, their attribute names are case-sensitive.
2819['autoReverse', 'externalResourcesRequired', 'focusable', 'preserveAlpha'].forEach(function (name) {
2820 properties[name] = new PropertyInfoRecord(name, BOOLEANISH_STRING, false, // mustUseProperty
2821 name, // attributeName
2822 null);
2823} // attributeNamespace
2824);
2825
2826// These are HTML boolean attributes.
2827['allowFullScreen', 'async',
2828// Note: there is a special case that prevents it from being written to the DOM
2829// on the client side because the browsers are inconsistent. Instead we call focus().
2830'autoFocus', 'autoPlay', 'controls', 'default', 'defer', 'disabled', 'formNoValidate', 'hidden', 'loop', 'noModule', 'noValidate', 'open', 'playsInline', 'readOnly', 'required', 'reversed', 'scoped', 'seamless',
2831// Microdata
2832'itemScope'].forEach(function (name) {
2833 properties[name] = new PropertyInfoRecord(name, BOOLEAN, false, // mustUseProperty
2834 name.toLowerCase(), // attributeName
2835 null);
2836} // attributeNamespace
2837);
2838
2839// These are the few React props that we set as DOM properties
2840// rather than attributes. These are all booleans.
2841['checked',
2842// Note: `option.selected` is not updated if `select.multiple` is
2843// disabled with `removeAttribute`. We have special logic for handling this.
2844'multiple', 'muted', 'selected'].forEach(function (name) {
2845 properties[name] = new PropertyInfoRecord(name, BOOLEAN, true, // mustUseProperty
2846 name, // attributeName
2847 null);
2848} // attributeNamespace
2849);
2850
2851// These are HTML attributes that are "overloaded booleans": they behave like
2852// booleans, but can also accept a string value.
2853['capture', 'download'].forEach(function (name) {
2854 properties[name] = new PropertyInfoRecord(name, OVERLOADED_BOOLEAN, false, // mustUseProperty
2855 name, // attributeName
2856 null);
2857} // attributeNamespace
2858);
2859
2860// These are HTML attributes that must be positive numbers.
2861['cols', 'rows', 'size', 'span'].forEach(function (name) {
2862 properties[name] = new PropertyInfoRecord(name, POSITIVE_NUMERIC, false, // mustUseProperty
2863 name, // attributeName
2864 null);
2865} // attributeNamespace
2866);
2867
2868// These are HTML attributes that must be numbers.
2869['rowSpan', 'start'].forEach(function (name) {
2870 properties[name] = new PropertyInfoRecord(name, NUMERIC, false, // mustUseProperty
2871 name.toLowerCase(), // attributeName
2872 null);
2873} // attributeNamespace
2874);
2875
2876var CAMELIZE = /[\-\:]([a-z])/g;
2877var capitalize = function (token) {
2878 return token[1].toUpperCase();
2879};
2880
2881// This is a list of all SVG attributes that need special casing, namespacing,
2882// or boolean value assignment. Regular attributes that just accept strings
2883// and have the same names are omitted, just like in the HTML whitelist.
2884// Some of these attributes can be hard to find. This list was created by
2885// scrapping the MDN documentation.
2886['accent-height', 'alignment-baseline', 'arabic-form', 'baseline-shift', 'cap-height', 'clip-path', 'clip-rule', 'color-interpolation', 'color-interpolation-filters', 'color-profile', 'color-rendering', 'dominant-baseline', 'enable-background', 'fill-opacity', 'fill-rule', 'flood-color', 'flood-opacity', 'font-family', 'font-size', 'font-size-adjust', 'font-stretch', 'font-style', 'font-variant', 'font-weight', 'glyph-name', 'glyph-orientation-horizontal', 'glyph-orientation-vertical', 'horiz-adv-x', 'horiz-origin-x', 'image-rendering', 'letter-spacing', 'lighting-color', 'marker-end', 'marker-mid', 'marker-start', 'overline-position', 'overline-thickness', 'paint-order', 'panose-1', 'pointer-events', 'rendering-intent', 'shape-rendering', 'stop-color', 'stop-opacity', 'strikethrough-position', 'strikethrough-thickness', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke-width', 'text-anchor', 'text-decoration', 'text-rendering', 'underline-position', 'underline-thickness', 'unicode-bidi', 'unicode-range', 'units-per-em', 'v-alphabetic', 'v-hanging', 'v-ideographic', 'v-mathematical', 'vector-effect', 'vert-adv-y', 'vert-origin-x', 'vert-origin-y', 'word-spacing', 'writing-mode', 'xmlns:xlink', 'x-height'].forEach(function (attributeName) {
2887 var name = attributeName.replace(CAMELIZE, capitalize);
2888 properties[name] = new PropertyInfoRecord(name, STRING, false, // mustUseProperty
2889 attributeName, null);
2890} // attributeNamespace
2891);
2892
2893// String SVG attributes with the xlink namespace.
2894['xlink:actuate', 'xlink:arcrole', 'xlink:href', 'xlink:role', 'xlink:show', 'xlink:title', 'xlink:type'].forEach(function (attributeName) {
2895 var name = attributeName.replace(CAMELIZE, capitalize);
2896 properties[name] = new PropertyInfoRecord(name, STRING, false, // mustUseProperty
2897 attributeName, 'http://www.w3.org/1999/xlink');
2898});
2899
2900// String SVG attributes with the xml namespace.
2901['xml:base', 'xml:lang', 'xml:space'].forEach(function (attributeName) {
2902 var name = attributeName.replace(CAMELIZE, capitalize);
2903 properties[name] = new PropertyInfoRecord(name, STRING, false, // mustUseProperty
2904 attributeName, 'http://www.w3.org/XML/1998/namespace');
2905});
2906
2907// These attribute exists both in HTML and SVG.
2908// The attribute name is case-sensitive in SVG so we can't just use
2909// the React name like we do for attributes that exist only in HTML.
2910['tabIndex', 'crossOrigin'].forEach(function (attributeName) {
2911 properties[attributeName] = new PropertyInfoRecord(attributeName, STRING, false, // mustUseProperty
2912 attributeName.toLowerCase(), // attributeName
2913 null);
2914} // attributeNamespace
2915);
2916
2917/**
2918 * Get the value for a property on a node. Only used in DEV for SSR validation.
2919 * The "expected" argument is used as a hint of what the expected value is.
2920 * Some properties have multiple equivalent values.
2921 */
2922function getValueForProperty(node, name, expected, propertyInfo) {
2923 {
2924 if (propertyInfo.mustUseProperty) {
2925 var propertyName = propertyInfo.propertyName;
2926
2927 return node[propertyName];
2928 } else {
2929 var attributeName = propertyInfo.attributeName;
2930
2931 var stringValue = null;
2932
2933 if (propertyInfo.type === OVERLOADED_BOOLEAN) {
2934 if (node.hasAttribute(attributeName)) {
2935 var value = node.getAttribute(attributeName);
2936 if (value === '') {
2937 return true;
2938 }
2939 if (shouldRemoveAttribute(name, expected, propertyInfo, false)) {
2940 return value;
2941 }
2942 if (value === '' + expected) {
2943 return expected;
2944 }
2945 return value;
2946 }
2947 } else if (node.hasAttribute(attributeName)) {
2948 if (shouldRemoveAttribute(name, expected, propertyInfo, false)) {
2949 // We had an attribute but shouldn't have had one, so read it
2950 // for the error message.
2951 return node.getAttribute(attributeName);
2952 }
2953 if (propertyInfo.type === BOOLEAN) {
2954 // If this was a boolean, it doesn't matter what the value is
2955 // the fact that we have it is the same as the expected.
2956 return expected;
2957 }
2958 // Even if this property uses a namespace we use getAttribute
2959 // because we assume its namespaced name is the same as our config.
2960 // To use getAttributeNS we need the local name which we don't have
2961 // in our config atm.
2962 stringValue = node.getAttribute(attributeName);
2963 }
2964
2965 if (shouldRemoveAttribute(name, expected, propertyInfo, false)) {
2966 return stringValue === null ? expected : stringValue;
2967 } else if (stringValue === '' + expected) {
2968 return expected;
2969 } else {
2970 return stringValue;
2971 }
2972 }
2973 }
2974}
2975
2976/**
2977 * Get the value for a attribute on a node. Only used in DEV for SSR validation.
2978 * The third argument is used as a hint of what the expected value is. Some
2979 * attributes have multiple equivalent values.
2980 */
2981function getValueForAttribute(node, name, expected) {
2982 {
2983 if (!isAttributeNameSafe(name)) {
2984 return;
2985 }
2986 if (!node.hasAttribute(name)) {
2987 return expected === undefined ? undefined : null;
2988 }
2989 var value = node.getAttribute(name);
2990 if (value === '' + expected) {
2991 return expected;
2992 }
2993 return value;
2994 }
2995}
2996
2997/**
2998 * Sets the value for a property on a node.
2999 *
3000 * @param {DOMElement} node
3001 * @param {string} name
3002 * @param {*} value
3003 */
3004function setValueForProperty(node, name, value, isCustomComponentTag) {
3005 var propertyInfo = getPropertyInfo(name);
3006 if (shouldIgnoreAttribute(name, propertyInfo, isCustomComponentTag)) {
3007 return;
3008 }
3009 if (shouldRemoveAttribute(name, value, propertyInfo, isCustomComponentTag)) {
3010 value = null;
3011 }
3012 // If the prop isn't in the special list, treat it as a simple attribute.
3013 if (isCustomComponentTag || propertyInfo === null) {
3014 if (isAttributeNameSafe(name)) {
3015 var _attributeName = name;
3016 if (value === null) {
3017 node.removeAttribute(_attributeName);
3018 } else {
3019 node.setAttribute(_attributeName, '' + value);
3020 }
3021 }
3022 return;
3023 }
3024 var mustUseProperty = propertyInfo.mustUseProperty;
3025
3026 if (mustUseProperty) {
3027 var propertyName = propertyInfo.propertyName;
3028
3029 if (value === null) {
3030 var type = propertyInfo.type;
3031
3032 node[propertyName] = type === BOOLEAN ? false : '';
3033 } else {
3034 // Contrary to `setAttribute`, object properties are properly
3035 // `toString`ed by IE8/9.
3036 node[propertyName] = value;
3037 }
3038 return;
3039 }
3040 // The rest are treated as attributes with special cases.
3041 var attributeName = propertyInfo.attributeName,
3042 attributeNamespace = propertyInfo.attributeNamespace;
3043
3044 if (value === null) {
3045 node.removeAttribute(attributeName);
3046 } else {
3047 var _type = propertyInfo.type;
3048
3049 var attributeValue = void 0;
3050 if (_type === BOOLEAN || _type === OVERLOADED_BOOLEAN && value === true) {
3051 attributeValue = '';
3052 } else {
3053 // `setAttribute` with objects becomes only `[object]` in IE8/9,
3054 // ('' + value) makes it output the correct toString()-value.
3055 attributeValue = '' + value;
3056 }
3057 if (attributeNamespace) {
3058 node.setAttributeNS(attributeNamespace, attributeName, attributeValue);
3059 } else {
3060 node.setAttribute(attributeName, attributeValue);
3061 }
3062 }
3063}
3064
3065// Flow does not allow string concatenation of most non-string types. To work
3066// around this limitation, we use an opaque type that can only be obtained by
3067// passing the value through getToStringValue first.
3068function toString(value) {
3069 return '' + value;
3070}
3071
3072function getToStringValue(value) {
3073 switch (typeof value) {
3074 case 'boolean':
3075 case 'number':
3076 case 'object':
3077 case 'string':
3078 case 'undefined':
3079 return value;
3080 default:
3081 // function, symbol are assigned as empty strings
3082 return '';
3083 }
3084}
3085
3086var ReactDebugCurrentFrame$1 = null;
3087
3088var ReactControlledValuePropTypes = {
3089 checkPropTypes: null
3090};
3091
3092{
3093 ReactDebugCurrentFrame$1 = ReactSharedInternals.ReactDebugCurrentFrame;
3094
3095 var hasReadOnlyValue = {
3096 button: true,
3097 checkbox: true,
3098 image: true,
3099 hidden: true,
3100 radio: true,
3101 reset: true,
3102 submit: true
3103 };
3104
3105 var propTypes = {
3106 value: function (props, propName, componentName) {
3107 if (hasReadOnlyValue[props.type] || props.onChange || props.readOnly || props.disabled || props[propName] == null) {
3108 return null;
3109 }
3110 return new Error('You provided a `value` prop to a form field without an ' + '`onChange` handler. This will render a read-only field. If ' + 'the field should be mutable use `defaultValue`. Otherwise, ' + 'set either `onChange` or `readOnly`.');
3111 },
3112 checked: function (props, propName, componentName) {
3113 if (props.onChange || props.readOnly || props.disabled || props[propName] == null) {
3114 return null;
3115 }
3116 return new Error('You provided a `checked` prop to a form field without an ' + '`onChange` handler. This will render a read-only field. If ' + 'the field should be mutable use `defaultChecked`. Otherwise, ' + 'set either `onChange` or `readOnly`.');
3117 }
3118 };
3119
3120 /**
3121 * Provide a linked `value` attribute for controlled forms. You should not use
3122 * this outside of the ReactDOM controlled form components.
3123 */
3124 ReactControlledValuePropTypes.checkPropTypes = function (tagName, props) {
3125 checkPropTypes(propTypes, props, 'prop', tagName, ReactDebugCurrentFrame$1.getStackAddendum);
3126 };
3127}
3128
3129var enableUserTimingAPI = true;
3130
3131// Helps identify side effects in begin-phase lifecycle hooks and setState reducers:
3132var debugRenderPhaseSideEffects = false;
3133
3134// In some cases, StrictMode should also double-render lifecycles.
3135// This can be confusing for tests though,
3136// And it can be bad for performance in production.
3137// This feature flag can be used to control the behavior:
3138var debugRenderPhaseSideEffectsForStrictMode = true;
3139
3140// To preserve the "Pause on caught exceptions" behavior of the debugger, we
3141// replay the begin phase of a failed component inside invokeGuardedCallback.
3142var replayFailedUnitOfWorkWithInvokeGuardedCallback = true;
3143
3144// Warn about deprecated, async-unsafe lifecycles; relates to RFC #6:
3145var warnAboutDeprecatedLifecycles = false;
3146
3147// Gather advanced timing metrics for Profiler subtrees.
3148var enableProfilerTimer = true;
3149
3150// Trace which interactions trigger each commit.
3151var enableSchedulerTracing = true;
3152
3153// Only used in www builds.
3154var enableSuspenseServerRenderer = false; // TODO: true? Here it might just be false.
3155
3156// Only used in www builds.
3157
3158
3159// Only used in www builds.
3160
3161
3162// React Fire: prevent the value and checked attributes from syncing
3163// with their related DOM properties
3164var disableInputAttributeSyncing = false;
3165
3166// These APIs will no longer be "unstable" in the upcoming 16.7 release,
3167// Control this behavior with a flag to support 16.6 minor releases in the meanwhile.
3168var enableStableConcurrentModeAPIs = false;
3169
3170var warnAboutShorthandPropertyCollision = false;
3171
3172// TODO: direct imports like some-package/src/* are bad. Fix me.
3173var didWarnValueDefaultValue = false;
3174var didWarnCheckedDefaultChecked = false;
3175var didWarnControlledToUncontrolled = false;
3176var didWarnUncontrolledToControlled = false;
3177
3178function isControlled(props) {
3179 var usesChecked = props.type === 'checkbox' || props.type === 'radio';
3180 return usesChecked ? props.checked != null : props.value != null;
3181}
3182
3183/**
3184 * Implements an <input> host component that allows setting these optional
3185 * props: `checked`, `value`, `defaultChecked`, and `defaultValue`.
3186 *
3187 * If `checked` or `value` are not supplied (or null/undefined), user actions
3188 * that affect the checked state or value will trigger updates to the element.
3189 *
3190 * If they are supplied (and not null/undefined), the rendered element will not
3191 * trigger updates to the element. Instead, the props must change in order for
3192 * the rendered element to be updated.
3193 *
3194 * The rendered element will be initialized as unchecked (or `defaultChecked`)
3195 * with an empty value (or `defaultValue`).
3196 *
3197 * See http://www.w3.org/TR/2012/WD-html5-20121025/the-input-element.html
3198 */
3199
3200function getHostProps(element, props) {
3201 var node = element;
3202 var checked = props.checked;
3203
3204 var hostProps = _assign({}, props, {
3205 defaultChecked: undefined,
3206 defaultValue: undefined,
3207 value: undefined,
3208 checked: checked != null ? checked : node._wrapperState.initialChecked
3209 });
3210
3211 return hostProps;
3212}
3213
3214function initWrapperState(element, props) {
3215 {
3216 ReactControlledValuePropTypes.checkPropTypes('input', props);
3217
3218 if (props.checked !== undefined && props.defaultChecked !== undefined && !didWarnCheckedDefaultChecked) {
3219 warning$1(false, '%s contains an input of type %s with both checked and defaultChecked props. ' + 'Input elements must be either controlled or uncontrolled ' + '(specify either the checked prop, or the defaultChecked prop, but not ' + 'both). Decide between using a controlled or uncontrolled input ' + 'element and remove one of these props. More info: ' + 'https://fb.me/react-controlled-components', getCurrentFiberOwnerNameInDevOrNull() || 'A component', props.type);
3220 didWarnCheckedDefaultChecked = true;
3221 }
3222 if (props.value !== undefined && props.defaultValue !== undefined && !didWarnValueDefaultValue) {
3223 warning$1(false, '%s contains an input of type %s with both value and defaultValue props. ' + 'Input elements must be either controlled or uncontrolled ' + '(specify either the value prop, or the defaultValue prop, but not ' + 'both). Decide between using a controlled or uncontrolled input ' + 'element and remove one of these props. More info: ' + 'https://fb.me/react-controlled-components', getCurrentFiberOwnerNameInDevOrNull() || 'A component', props.type);
3224 didWarnValueDefaultValue = true;
3225 }
3226 }
3227
3228 var node = element;
3229 var defaultValue = props.defaultValue == null ? '' : props.defaultValue;
3230
3231 node._wrapperState = {
3232 initialChecked: props.checked != null ? props.checked : props.defaultChecked,
3233 initialValue: getToStringValue(props.value != null ? props.value : defaultValue),
3234 controlled: isControlled(props)
3235 };
3236}
3237
3238function updateChecked(element, props) {
3239 var node = element;
3240 var checked = props.checked;
3241 if (checked != null) {
3242 setValueForProperty(node, 'checked', checked, false);
3243 }
3244}
3245
3246function updateWrapper(element, props) {
3247 var node = element;
3248 {
3249 var _controlled = isControlled(props);
3250
3251 if (!node._wrapperState.controlled && _controlled && !didWarnUncontrolledToControlled) {
3252 warning$1(false, 'A component is changing an uncontrolled input of type %s to be controlled. ' + 'Input elements should not switch from uncontrolled to controlled (or vice versa). ' + 'Decide between using a controlled or uncontrolled input ' + 'element for the lifetime of the component. More info: https://fb.me/react-controlled-components', props.type);
3253 didWarnUncontrolledToControlled = true;
3254 }
3255 if (node._wrapperState.controlled && !_controlled && !didWarnControlledToUncontrolled) {
3256 warning$1(false, 'A component is changing a controlled input of type %s to be uncontrolled. ' + 'Input elements should not switch from controlled to uncontrolled (or vice versa). ' + 'Decide between using a controlled or uncontrolled input ' + 'element for the lifetime of the component. More info: https://fb.me/react-controlled-components', props.type);
3257 didWarnControlledToUncontrolled = true;
3258 }
3259 }
3260
3261 updateChecked(element, props);
3262
3263 var value = getToStringValue(props.value);
3264 var type = props.type;
3265
3266 if (value != null) {
3267 if (type === 'number') {
3268 if (value === 0 && node.value === '' ||
3269 // We explicitly want to coerce to number here if possible.
3270 // eslint-disable-next-line
3271 node.value != value) {
3272 node.value = toString(value);
3273 }
3274 } else if (node.value !== toString(value)) {
3275 node.value = toString(value);
3276 }
3277 } else if (type === 'submit' || type === 'reset') {
3278 // Submit/reset inputs need the attribute removed completely to avoid
3279 // blank-text buttons.
3280 node.removeAttribute('value');
3281 return;
3282 }
3283
3284 if (disableInputAttributeSyncing) {
3285 // When not syncing the value attribute, React only assigns a new value
3286 // whenever the defaultValue React prop has changed. When not present,
3287 // React does nothing
3288 if (props.hasOwnProperty('defaultValue')) {
3289 setDefaultValue(node, props.type, getToStringValue(props.defaultValue));
3290 }
3291 } else {
3292 // When syncing the value attribute, the value comes from a cascade of
3293 // properties:
3294 // 1. The value React property
3295 // 2. The defaultValue React property
3296 // 3. Otherwise there should be no change
3297 if (props.hasOwnProperty('value')) {
3298 setDefaultValue(node, props.type, value);
3299 } else if (props.hasOwnProperty('defaultValue')) {
3300 setDefaultValue(node, props.type, getToStringValue(props.defaultValue));
3301 }
3302 }
3303
3304 if (disableInputAttributeSyncing) {
3305 // When not syncing the checked attribute, the attribute is directly
3306 // controllable from the defaultValue React property. It needs to be
3307 // updated as new props come in.
3308 if (props.defaultChecked == null) {
3309 node.removeAttribute('checked');
3310 } else {
3311 node.defaultChecked = !!props.defaultChecked;
3312 }
3313 } else {
3314 // When syncing the checked attribute, it only changes when it needs
3315 // to be removed, such as transitioning from a checkbox into a text input
3316 if (props.checked == null && props.defaultChecked != null) {
3317 node.defaultChecked = !!props.defaultChecked;
3318 }
3319 }
3320}
3321
3322function postMountWrapper(element, props, isHydrating) {
3323 var node = element;
3324
3325 // Do not assign value if it is already set. This prevents user text input
3326 // from being lost during SSR hydration.
3327 if (props.hasOwnProperty('value') || props.hasOwnProperty('defaultValue')) {
3328 var type = props.type;
3329 var isButton = type === 'submit' || type === 'reset';
3330
3331 // Avoid setting value attribute on submit/reset inputs as it overrides the
3332 // default value provided by the browser. See: #12872
3333 if (isButton && (props.value === undefined || props.value === null)) {
3334 return;
3335 }
3336
3337 var _initialValue = toString(node._wrapperState.initialValue);
3338
3339 // Do not assign value if it is already set. This prevents user text input
3340 // from being lost during SSR hydration.
3341 if (!isHydrating) {
3342 if (disableInputAttributeSyncing) {
3343 var value = getToStringValue(props.value);
3344
3345 // When not syncing the value attribute, the value property points
3346 // directly to the React prop. Only assign it if it exists.
3347 if (value != null) {
3348 // Always assign on buttons so that it is possible to assign an
3349 // empty string to clear button text.
3350 //
3351 // Otherwise, do not re-assign the value property if is empty. This
3352 // potentially avoids a DOM write and prevents Firefox (~60.0.1) from
3353 // prematurely marking required inputs as invalid. Equality is compared
3354 // to the current value in case the browser provided value is not an
3355 // empty string.
3356 if (isButton || value !== node.value) {
3357 node.value = toString(value);
3358 }
3359 }
3360 } else {
3361 // When syncing the value attribute, the value property should use
3362 // the wrapperState._initialValue property. This uses:
3363 //
3364 // 1. The value React property when present
3365 // 2. The defaultValue React property when present
3366 // 3. An empty string
3367 if (_initialValue !== node.value) {
3368 node.value = _initialValue;
3369 }
3370 }
3371 }
3372
3373 if (disableInputAttributeSyncing) {
3374 // When not syncing the value attribute, assign the value attribute
3375 // directly from the defaultValue React property (when present)
3376 var defaultValue = getToStringValue(props.defaultValue);
3377 if (defaultValue != null) {
3378 node.defaultValue = toString(defaultValue);
3379 }
3380 } else {
3381 // Otherwise, the value attribute is synchronized to the property,
3382 // so we assign defaultValue to the same thing as the value property
3383 // assignment step above.
3384 node.defaultValue = _initialValue;
3385 }
3386 }
3387
3388 // Normally, we'd just do `node.checked = node.checked` upon initial mount, less this bug
3389 // this is needed to work around a chrome bug where setting defaultChecked
3390 // will sometimes influence the value of checked (even after detachment).
3391 // Reference: https://bugs.chromium.org/p/chromium/issues/detail?id=608416
3392 // We need to temporarily unset name to avoid disrupting radio button groups.
3393 var name = node.name;
3394 if (name !== '') {
3395 node.name = '';
3396 }
3397
3398 if (disableInputAttributeSyncing) {
3399 // When not syncing the checked attribute, the checked property
3400 // never gets assigned. It must be manually set. We don't want
3401 // to do this when hydrating so that existing user input isn't
3402 // modified
3403 if (!isHydrating) {
3404 updateChecked(element, props);
3405 }
3406
3407 // Only assign the checked attribute if it is defined. This saves
3408 // a DOM write when controlling the checked attribute isn't needed
3409 // (text inputs, submit/reset)
3410 if (props.hasOwnProperty('defaultChecked')) {
3411 node.defaultChecked = !node.defaultChecked;
3412 node.defaultChecked = !!props.defaultChecked;
3413 }
3414 } else {
3415 // When syncing the checked attribute, both the checked property and
3416 // attribute are assigned at the same time using defaultChecked. This uses:
3417 //
3418 // 1. The checked React property when present
3419 // 2. The defaultChecked React property when present
3420 // 3. Otherwise, false
3421 node.defaultChecked = !node.defaultChecked;
3422 node.defaultChecked = !!node._wrapperState.initialChecked;
3423 }
3424
3425 if (name !== '') {
3426 node.name = name;
3427 }
3428}
3429
3430function restoreControlledState(element, props) {
3431 var node = element;
3432 updateWrapper(node, props);
3433 updateNamedCousins(node, props);
3434}
3435
3436function updateNamedCousins(rootNode, props) {
3437 var name = props.name;
3438 if (props.type === 'radio' && name != null) {
3439 var queryRoot = rootNode;
3440
3441 while (queryRoot.parentNode) {
3442 queryRoot = queryRoot.parentNode;
3443 }
3444
3445 // If `rootNode.form` was non-null, then we could try `form.elements`,
3446 // but that sometimes behaves strangely in IE8. We could also try using
3447 // `form.getElementsByName`, but that will only return direct children
3448 // and won't include inputs that use the HTML5 `form=` attribute. Since
3449 // the input might not even be in a form. It might not even be in the
3450 // document. Let's just use the local `querySelectorAll` to ensure we don't
3451 // miss anything.
3452 var group = queryRoot.querySelectorAll('input[name=' + JSON.stringify('' + name) + '][type="radio"]');
3453
3454 for (var i = 0; i < group.length; i++) {
3455 var otherNode = group[i];
3456 if (otherNode === rootNode || otherNode.form !== rootNode.form) {
3457 continue;
3458 }
3459 // This will throw if radio buttons rendered by different copies of React
3460 // and the same name are rendered into the same form (same as #1939).
3461 // That's probably okay; we don't support it just as we don't support
3462 // mixing React radio buttons with non-React ones.
3463 var otherProps = getFiberCurrentPropsFromNode$1(otherNode);
3464 !otherProps ? invariant(false, 'ReactDOMInput: Mixing React and non-React radio inputs with the same `name` is not supported.') : void 0;
3465
3466 // We need update the tracked value on the named cousin since the value
3467 // was changed but the input saw no event or value set
3468 updateValueIfChanged(otherNode);
3469
3470 // If this is a controlled radio button group, forcing the input that
3471 // was previously checked to update will cause it to be come re-checked
3472 // as appropriate.
3473 updateWrapper(otherNode, otherProps);
3474 }
3475 }
3476}
3477
3478// In Chrome, assigning defaultValue to certain input types triggers input validation.
3479// For number inputs, the display value loses trailing decimal points. For email inputs,
3480// Chrome raises "The specified value <x> is not a valid email address".
3481//
3482// Here we check to see if the defaultValue has actually changed, avoiding these problems
3483// when the user is inputting text
3484//
3485// https://github.com/facebook/react/issues/7253
3486function setDefaultValue(node, type, value) {
3487 if (
3488 // Focused number inputs synchronize on blur. See ChangeEventPlugin.js
3489 type !== 'number' || node.ownerDocument.activeElement !== node) {
3490 if (value == null) {
3491 node.defaultValue = toString(node._wrapperState.initialValue);
3492 } else if (node.defaultValue !== toString(value)) {
3493 node.defaultValue = toString(value);
3494 }
3495 }
3496}
3497
3498var eventTypes$1 = {
3499 change: {
3500 phasedRegistrationNames: {
3501 bubbled: 'onChange',
3502 captured: 'onChangeCapture'
3503 },
3504 dependencies: [TOP_BLUR, TOP_CHANGE, TOP_CLICK, TOP_FOCUS, TOP_INPUT, TOP_KEY_DOWN, TOP_KEY_UP, TOP_SELECTION_CHANGE]
3505 }
3506};
3507
3508function createAndAccumulateChangeEvent(inst, nativeEvent, target) {
3509 var event = SyntheticEvent.getPooled(eventTypes$1.change, inst, nativeEvent, target);
3510 event.type = 'change';
3511 // Flag this event loop as needing state restore.
3512 enqueueStateRestore(target);
3513 accumulateTwoPhaseDispatches(event);
3514 return event;
3515}
3516/**
3517 * For IE shims
3518 */
3519var activeElement = null;
3520var activeElementInst = null;
3521
3522/**
3523 * SECTION: handle `change` event
3524 */
3525function shouldUseChangeEvent(elem) {
3526 var nodeName = elem.nodeName && elem.nodeName.toLowerCase();
3527 return nodeName === 'select' || nodeName === 'input' && elem.type === 'file';
3528}
3529
3530function manualDispatchChangeEvent(nativeEvent) {
3531 var event = createAndAccumulateChangeEvent(activeElementInst, nativeEvent, getEventTarget(nativeEvent));
3532
3533 // If change and propertychange bubbled, we'd just bind to it like all the
3534 // other events and have it go through ReactBrowserEventEmitter. Since it
3535 // doesn't, we manually listen for the events and so we have to enqueue and
3536 // process the abstract event manually.
3537 //
3538 // Batching is necessary here in order to ensure that all event handlers run
3539 // before the next rerender (including event handlers attached to ancestor
3540 // elements instead of directly on the input). Without this, controlled
3541 // components don't work properly in conjunction with event bubbling because
3542 // the component is rerendered and the value reverted before all the event
3543 // handlers can run. See https://github.com/facebook/react/issues/708.
3544 batchedUpdates(runEventInBatch, event);
3545}
3546
3547function runEventInBatch(event) {
3548 runEventsInBatch(event);
3549}
3550
3551function getInstIfValueChanged(targetInst) {
3552 var targetNode = getNodeFromInstance$1(targetInst);
3553 if (updateValueIfChanged(targetNode)) {
3554 return targetInst;
3555 }
3556}
3557
3558function getTargetInstForChangeEvent(topLevelType, targetInst) {
3559 if (topLevelType === TOP_CHANGE) {
3560 return targetInst;
3561 }
3562}
3563
3564/**
3565 * SECTION: handle `input` event
3566 */
3567var isInputEventSupported = false;
3568if (canUseDOM) {
3569 // IE9 claims to support the input event but fails to trigger it when
3570 // deleting text, so we ignore its input events.
3571 isInputEventSupported = isEventSupported('input') && (!document.documentMode || document.documentMode > 9);
3572}
3573
3574/**
3575 * (For IE <=9) Starts tracking propertychange events on the passed-in element
3576 * and override the value property so that we can distinguish user events from
3577 * value changes in JS.
3578 */
3579function startWatchingForValueChange(target, targetInst) {
3580 activeElement = target;
3581 activeElementInst = targetInst;
3582 activeElement.attachEvent('onpropertychange', handlePropertyChange);
3583}
3584
3585/**
3586 * (For IE <=9) Removes the event listeners from the currently-tracked element,
3587 * if any exists.
3588 */
3589function stopWatchingForValueChange() {
3590 if (!activeElement) {
3591 return;
3592 }
3593 activeElement.detachEvent('onpropertychange', handlePropertyChange);
3594 activeElement = null;
3595 activeElementInst = null;
3596}
3597
3598/**
3599 * (For IE <=9) Handles a propertychange event, sending a `change` event if
3600 * the value of the active element has changed.
3601 */
3602function handlePropertyChange(nativeEvent) {
3603 if (nativeEvent.propertyName !== 'value') {
3604 return;
3605 }
3606 if (getInstIfValueChanged(activeElementInst)) {
3607 manualDispatchChangeEvent(nativeEvent);
3608 }
3609}
3610
3611function handleEventsForInputEventPolyfill(topLevelType, target, targetInst) {
3612 if (topLevelType === TOP_FOCUS) {
3613 // In IE9, propertychange fires for most input events but is buggy and
3614 // doesn't fire when text is deleted, but conveniently, selectionchange
3615 // appears to fire in all of the remaining cases so we catch those and
3616 // forward the event if the value has changed
3617 // In either case, we don't want to call the event handler if the value
3618 // is changed from JS so we redefine a setter for `.value` that updates
3619 // our activeElementValue variable, allowing us to ignore those changes
3620 //
3621 // stopWatching() should be a noop here but we call it just in case we
3622 // missed a blur event somehow.
3623 stopWatchingForValueChange();
3624 startWatchingForValueChange(target, targetInst);
3625 } else if (topLevelType === TOP_BLUR) {
3626 stopWatchingForValueChange();
3627 }
3628}
3629
3630// For IE8 and IE9.
3631function getTargetInstForInputEventPolyfill(topLevelType, targetInst) {
3632 if (topLevelType === TOP_SELECTION_CHANGE || topLevelType === TOP_KEY_UP || topLevelType === TOP_KEY_DOWN) {
3633 // On the selectionchange event, the target is just document which isn't
3634 // helpful for us so just check activeElement instead.
3635 //
3636 // 99% of the time, keydown and keyup aren't necessary. IE8 fails to fire
3637 // propertychange on the first input event after setting `value` from a
3638 // script and fires only keydown, keypress, keyup. Catching keyup usually
3639 // gets it and catching keydown lets us fire an event for the first
3640 // keystroke if user does a key repeat (it'll be a little delayed: right
3641 // before the second keystroke). Other input methods (e.g., paste) seem to
3642 // fire selectionchange normally.
3643 return getInstIfValueChanged(activeElementInst);
3644 }
3645}
3646
3647/**
3648 * SECTION: handle `click` event
3649 */
3650function shouldUseClickEvent(elem) {
3651 // Use the `click` event to detect changes to checkbox and radio inputs.
3652 // This approach works across all browsers, whereas `change` does not fire
3653 // until `blur` in IE8.
3654 var nodeName = elem.nodeName;
3655 return nodeName && nodeName.toLowerCase() === 'input' && (elem.type === 'checkbox' || elem.type === 'radio');
3656}
3657
3658function getTargetInstForClickEvent(topLevelType, targetInst) {
3659 if (topLevelType === TOP_CLICK) {
3660 return getInstIfValueChanged(targetInst);
3661 }
3662}
3663
3664function getTargetInstForInputOrChangeEvent(topLevelType, targetInst) {
3665 if (topLevelType === TOP_INPUT || topLevelType === TOP_CHANGE) {
3666 return getInstIfValueChanged(targetInst);
3667 }
3668}
3669
3670function handleControlledInputBlur(node) {
3671 var state = node._wrapperState;
3672
3673 if (!state || !state.controlled || node.type !== 'number') {
3674 return;
3675 }
3676
3677 if (!disableInputAttributeSyncing) {
3678 // If controlled, assign the value attribute to the current value on blur
3679 setDefaultValue(node, 'number', node.value);
3680 }
3681}
3682
3683/**
3684 * This plugin creates an `onChange` event that normalizes change events
3685 * across form elements. This event fires at a time when it's possible to
3686 * change the element's value without seeing a flicker.
3687 *
3688 * Supported elements are:
3689 * - input (see `isTextInputElement`)
3690 * - textarea
3691 * - select
3692 */
3693var ChangeEventPlugin = {
3694 eventTypes: eventTypes$1,
3695
3696 _isInputEventSupported: isInputEventSupported,
3697
3698 extractEvents: function (topLevelType, targetInst, nativeEvent, nativeEventTarget) {
3699 var targetNode = targetInst ? getNodeFromInstance$1(targetInst) : window;
3700
3701 var getTargetInstFunc = void 0,
3702 handleEventFunc = void 0;
3703 if (shouldUseChangeEvent(targetNode)) {
3704 getTargetInstFunc = getTargetInstForChangeEvent;
3705 } else if (isTextInputElement(targetNode)) {
3706 if (isInputEventSupported) {
3707 getTargetInstFunc = getTargetInstForInputOrChangeEvent;
3708 } else {
3709 getTargetInstFunc = getTargetInstForInputEventPolyfill;
3710 handleEventFunc = handleEventsForInputEventPolyfill;
3711 }
3712 } else if (shouldUseClickEvent(targetNode)) {
3713 getTargetInstFunc = getTargetInstForClickEvent;
3714 }
3715
3716 if (getTargetInstFunc) {
3717 var inst = getTargetInstFunc(topLevelType, targetInst);
3718 if (inst) {
3719 var event = createAndAccumulateChangeEvent(inst, nativeEvent, nativeEventTarget);
3720 return event;
3721 }
3722 }
3723
3724 if (handleEventFunc) {
3725 handleEventFunc(topLevelType, targetNode, targetInst);
3726 }
3727
3728 // When blurring, set the value attribute for number inputs
3729 if (topLevelType === TOP_BLUR) {
3730 handleControlledInputBlur(targetNode);
3731 }
3732 }
3733};
3734
3735/**
3736 * Module that is injectable into `EventPluginHub`, that specifies a
3737 * deterministic ordering of `EventPlugin`s. A convenient way to reason about
3738 * plugins, without having to package every one of them. This is better than
3739 * having plugins be ordered in the same order that they are injected because
3740 * that ordering would be influenced by the packaging order.
3741 * `ResponderEventPlugin` must occur before `SimpleEventPlugin` so that
3742 * preventing default on events is convenient in `SimpleEventPlugin` handlers.
3743 */
3744var DOMEventPluginOrder = ['ResponderEventPlugin', 'SimpleEventPlugin', 'EnterLeaveEventPlugin', 'ChangeEventPlugin', 'SelectEventPlugin', 'BeforeInputEventPlugin'];
3745
3746var SyntheticUIEvent = SyntheticEvent.extend({
3747 view: null,
3748 detail: null
3749});
3750
3751var modifierKeyToProp = {
3752 Alt: 'altKey',
3753 Control: 'ctrlKey',
3754 Meta: 'metaKey',
3755 Shift: 'shiftKey'
3756};
3757
3758// Older browsers (Safari <= 10, iOS Safari <= 10.2) do not support
3759// getModifierState. If getModifierState is not supported, we map it to a set of
3760// modifier keys exposed by the event. In this case, Lock-keys are not supported.
3761/**
3762 * Translation from modifier key to the associated property in the event.
3763 * @see http://www.w3.org/TR/DOM-Level-3-Events/#keys-Modifiers
3764 */
3765
3766function modifierStateGetter(keyArg) {
3767 var syntheticEvent = this;
3768 var nativeEvent = syntheticEvent.nativeEvent;
3769 if (nativeEvent.getModifierState) {
3770 return nativeEvent.getModifierState(keyArg);
3771 }
3772 var keyProp = modifierKeyToProp[keyArg];
3773 return keyProp ? !!nativeEvent[keyProp] : false;
3774}
3775
3776function getEventModifierState(nativeEvent) {
3777 return modifierStateGetter;
3778}
3779
3780var previousScreenX = 0;
3781var previousScreenY = 0;
3782// Use flags to signal movementX/Y has already been set
3783var isMovementXSet = false;
3784var isMovementYSet = false;
3785
3786/**
3787 * @interface MouseEvent
3788 * @see http://www.w3.org/TR/DOM-Level-3-Events/
3789 */
3790var SyntheticMouseEvent = SyntheticUIEvent.extend({
3791 screenX: null,
3792 screenY: null,
3793 clientX: null,
3794 clientY: null,
3795 pageX: null,
3796 pageY: null,
3797 ctrlKey: null,
3798 shiftKey: null,
3799 altKey: null,
3800 metaKey: null,
3801 getModifierState: getEventModifierState,
3802 button: null,
3803 buttons: null,
3804 relatedTarget: function (event) {
3805 return event.relatedTarget || (event.fromElement === event.srcElement ? event.toElement : event.fromElement);
3806 },
3807 movementX: function (event) {
3808 if ('movementX' in event) {
3809 return event.movementX;
3810 }
3811
3812 var screenX = previousScreenX;
3813 previousScreenX = event.screenX;
3814
3815 if (!isMovementXSet) {
3816 isMovementXSet = true;
3817 return 0;
3818 }
3819
3820 return event.type === 'mousemove' ? event.screenX - screenX : 0;
3821 },
3822 movementY: function (event) {
3823 if ('movementY' in event) {
3824 return event.movementY;
3825 }
3826
3827 var screenY = previousScreenY;
3828 previousScreenY = event.screenY;
3829
3830 if (!isMovementYSet) {
3831 isMovementYSet = true;
3832 return 0;
3833 }
3834
3835 return event.type === 'mousemove' ? event.screenY - screenY : 0;
3836 }
3837});
3838
3839/**
3840 * @interface PointerEvent
3841 * @see http://www.w3.org/TR/pointerevents/
3842 */
3843var SyntheticPointerEvent = SyntheticMouseEvent.extend({
3844 pointerId: null,
3845 width: null,
3846 height: null,
3847 pressure: null,
3848 tangentialPressure: null,
3849 tiltX: null,
3850 tiltY: null,
3851 twist: null,
3852 pointerType: null,
3853 isPrimary: null
3854});
3855
3856var eventTypes$2 = {
3857 mouseEnter: {
3858 registrationName: 'onMouseEnter',
3859 dependencies: [TOP_MOUSE_OUT, TOP_MOUSE_OVER]
3860 },
3861 mouseLeave: {
3862 registrationName: 'onMouseLeave',
3863 dependencies: [TOP_MOUSE_OUT, TOP_MOUSE_OVER]
3864 },
3865 pointerEnter: {
3866 registrationName: 'onPointerEnter',
3867 dependencies: [TOP_POINTER_OUT, TOP_POINTER_OVER]
3868 },
3869 pointerLeave: {
3870 registrationName: 'onPointerLeave',
3871 dependencies: [TOP_POINTER_OUT, TOP_POINTER_OVER]
3872 }
3873};
3874
3875var EnterLeaveEventPlugin = {
3876 eventTypes: eventTypes$2,
3877
3878 /**
3879 * For almost every interaction we care about, there will be both a top-level
3880 * `mouseover` and `mouseout` event that occurs. Only use `mouseout` so that
3881 * we do not extract duplicate events. However, moving the mouse into the
3882 * browser from outside will not fire a `mouseout` event. In this case, we use
3883 * the `mouseover` top-level event.
3884 */
3885 extractEvents: function (topLevelType, targetInst, nativeEvent, nativeEventTarget) {
3886 var isOverEvent = topLevelType === TOP_MOUSE_OVER || topLevelType === TOP_POINTER_OVER;
3887 var isOutEvent = topLevelType === TOP_MOUSE_OUT || topLevelType === TOP_POINTER_OUT;
3888
3889 if (isOverEvent && (nativeEvent.relatedTarget || nativeEvent.fromElement)) {
3890 return null;
3891 }
3892
3893 if (!isOutEvent && !isOverEvent) {
3894 // Must not be a mouse or pointer in or out - ignoring.
3895 return null;
3896 }
3897
3898 var win = void 0;
3899 if (nativeEventTarget.window === nativeEventTarget) {
3900 // `nativeEventTarget` is probably a window object.
3901 win = nativeEventTarget;
3902 } else {
3903 // TODO: Figure out why `ownerDocument` is sometimes undefined in IE8.
3904 var doc = nativeEventTarget.ownerDocument;
3905 if (doc) {
3906 win = doc.defaultView || doc.parentWindow;
3907 } else {
3908 win = window;
3909 }
3910 }
3911
3912 var from = void 0;
3913 var to = void 0;
3914 if (isOutEvent) {
3915 from = targetInst;
3916 var related = nativeEvent.relatedTarget || nativeEvent.toElement;
3917 to = related ? getClosestInstanceFromNode(related) : null;
3918 } else {
3919 // Moving to a node from outside the window.
3920 from = null;
3921 to = targetInst;
3922 }
3923
3924 if (from === to) {
3925 // Nothing pertains to our managed components.
3926 return null;
3927 }
3928
3929 var eventInterface = void 0,
3930 leaveEventType = void 0,
3931 enterEventType = void 0,
3932 eventTypePrefix = void 0;
3933
3934 if (topLevelType === TOP_MOUSE_OUT || topLevelType === TOP_MOUSE_OVER) {
3935 eventInterface = SyntheticMouseEvent;
3936 leaveEventType = eventTypes$2.mouseLeave;
3937 enterEventType = eventTypes$2.mouseEnter;
3938 eventTypePrefix = 'mouse';
3939 } else if (topLevelType === TOP_POINTER_OUT || topLevelType === TOP_POINTER_OVER) {
3940 eventInterface = SyntheticPointerEvent;
3941 leaveEventType = eventTypes$2.pointerLeave;
3942 enterEventType = eventTypes$2.pointerEnter;
3943 eventTypePrefix = 'pointer';
3944 }
3945
3946 var fromNode = from == null ? win : getNodeFromInstance$1(from);
3947 var toNode = to == null ? win : getNodeFromInstance$1(to);
3948
3949 var leave = eventInterface.getPooled(leaveEventType, from, nativeEvent, nativeEventTarget);
3950 leave.type = eventTypePrefix + 'leave';
3951 leave.target = fromNode;
3952 leave.relatedTarget = toNode;
3953
3954 var enter = eventInterface.getPooled(enterEventType, to, nativeEvent, nativeEventTarget);
3955 enter.type = eventTypePrefix + 'enter';
3956 enter.target = toNode;
3957 enter.relatedTarget = fromNode;
3958
3959 accumulateEnterLeaveDispatches(leave, enter, from, to);
3960
3961 return [leave, enter];
3962 }
3963};
3964
3965/**
3966 * inlined Object.is polyfill to avoid requiring consumers ship their own
3967 * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is
3968 */
3969function is(x, y) {
3970 return x === y && (x !== 0 || 1 / x === 1 / y) || x !== x && y !== y // eslint-disable-line no-self-compare
3971 ;
3972}
3973
3974var hasOwnProperty$1 = Object.prototype.hasOwnProperty;
3975
3976/**
3977 * Performs equality by iterating through keys on an object and returning false
3978 * when any key has values which are not strictly equal between the arguments.
3979 * Returns true when the values of all keys are strictly equal.
3980 */
3981function shallowEqual(objA, objB) {
3982 if (is(objA, objB)) {
3983 return true;
3984 }
3985
3986 if (typeof objA !== 'object' || objA === null || typeof objB !== 'object' || objB === null) {
3987 return false;
3988 }
3989
3990 var keysA = Object.keys(objA);
3991 var keysB = Object.keys(objB);
3992
3993 if (keysA.length !== keysB.length) {
3994 return false;
3995 }
3996
3997 // Test for A's keys different from B.
3998 for (var i = 0; i < keysA.length; i++) {
3999 if (!hasOwnProperty$1.call(objB, keysA[i]) || !is(objA[keysA[i]], objB[keysA[i]])) {
4000 return false;
4001 }
4002 }
4003
4004 return true;
4005}
4006
4007/**
4008 * `ReactInstanceMap` maintains a mapping from a public facing stateful
4009 * instance (key) and the internal representation (value). This allows public
4010 * methods to accept the user facing instance as an argument and map them back
4011 * to internal methods.
4012 *
4013 * Note that this module is currently shared and assumed to be stateless.
4014 * If this becomes an actual Map, that will break.
4015 */
4016
4017/**
4018 * This API should be called `delete` but we'd have to make sure to always
4019 * transform these to strings for IE support. When this transform is fully
4020 * supported we can rename it.
4021 */
4022
4023
4024function get(key) {
4025 return key._reactInternalFiber;
4026}
4027
4028function has(key) {
4029 return key._reactInternalFiber !== undefined;
4030}
4031
4032function set(key, value) {
4033 key._reactInternalFiber = value;
4034}
4035
4036// Don't change these two values. They're used by React Dev Tools.
4037var NoEffect = /* */0;
4038var PerformedWork = /* */1;
4039
4040// You can change the rest (and add more).
4041var Placement = /* */2;
4042var Update = /* */4;
4043var PlacementAndUpdate = /* */6;
4044var Deletion = /* */8;
4045var ContentReset = /* */16;
4046var Callback = /* */32;
4047var DidCapture = /* */64;
4048var Ref = /* */128;
4049var Snapshot = /* */256;
4050var Passive = /* */512;
4051
4052// Passive & Update & Callback & Ref & Snapshot
4053var LifecycleEffectMask = /* */932;
4054
4055// Union of all host effects
4056var HostEffectMask = /* */1023;
4057
4058var Incomplete = /* */1024;
4059var ShouldCapture = /* */2048;
4060
4061var ReactCurrentOwner$1 = ReactSharedInternals.ReactCurrentOwner;
4062
4063var MOUNTING = 1;
4064var MOUNTED = 2;
4065var UNMOUNTED = 3;
4066
4067function isFiberMountedImpl(fiber) {
4068 var node = fiber;
4069 if (!fiber.alternate) {
4070 // If there is no alternate, this might be a new tree that isn't inserted
4071 // yet. If it is, then it will have a pending insertion effect on it.
4072 if ((node.effectTag & Placement) !== NoEffect) {
4073 return MOUNTING;
4074 }
4075 while (node.return) {
4076 node = node.return;
4077 if ((node.effectTag & Placement) !== NoEffect) {
4078 return MOUNTING;
4079 }
4080 }
4081 } else {
4082 while (node.return) {
4083 node = node.return;
4084 }
4085 }
4086 if (node.tag === HostRoot) {
4087 // TODO: Check if this was a nested HostRoot when used with
4088 // renderContainerIntoSubtree.
4089 return MOUNTED;
4090 }
4091 // If we didn't hit the root, that means that we're in an disconnected tree
4092 // that has been unmounted.
4093 return UNMOUNTED;
4094}
4095
4096function isFiberMounted(fiber) {
4097 return isFiberMountedImpl(fiber) === MOUNTED;
4098}
4099
4100function isMounted(component) {
4101 {
4102 var owner = ReactCurrentOwner$1.current;
4103 if (owner !== null && owner.tag === ClassComponent) {
4104 var ownerFiber = owner;
4105 var instance = ownerFiber.stateNode;
4106 !instance._warnedAboutRefsInRender ? warningWithoutStack$1(false, '%s is accessing isMounted inside its render() function. ' + 'render() should be a pure function of props and state. It should ' + 'never access something that requires stale data from the previous ' + 'render, such as refs. Move this logic to componentDidMount and ' + 'componentDidUpdate instead.', getComponentName(ownerFiber.type) || 'A component') : void 0;
4107 instance._warnedAboutRefsInRender = true;
4108 }
4109 }
4110
4111 var fiber = get(component);
4112 if (!fiber) {
4113 return false;
4114 }
4115 return isFiberMountedImpl(fiber) === MOUNTED;
4116}
4117
4118function assertIsMounted(fiber) {
4119 !(isFiberMountedImpl(fiber) === MOUNTED) ? invariant(false, 'Unable to find node on an unmounted component.') : void 0;
4120}
4121
4122function findCurrentFiberUsingSlowPath(fiber) {
4123 var alternate = fiber.alternate;
4124 if (!alternate) {
4125 // If there is no alternate, then we only need to check if it is mounted.
4126 var state = isFiberMountedImpl(fiber);
4127 !(state !== UNMOUNTED) ? invariant(false, 'Unable to find node on an unmounted component.') : void 0;
4128 if (state === MOUNTING) {
4129 return null;
4130 }
4131 return fiber;
4132 }
4133 // If we have two possible branches, we'll walk backwards up to the root
4134 // to see what path the root points to. On the way we may hit one of the
4135 // special cases and we'll deal with them.
4136 var a = fiber;
4137 var b = alternate;
4138 while (true) {
4139 var parentA = a.return;
4140 var parentB = parentA ? parentA.alternate : null;
4141 if (!parentA || !parentB) {
4142 // We're at the root.
4143 break;
4144 }
4145
4146 // If both copies of the parent fiber point to the same child, we can
4147 // assume that the child is current. This happens when we bailout on low
4148 // priority: the bailed out fiber's child reuses the current child.
4149 if (parentA.child === parentB.child) {
4150 var child = parentA.child;
4151 while (child) {
4152 if (child === a) {
4153 // We've determined that A is the current branch.
4154 assertIsMounted(parentA);
4155 return fiber;
4156 }
4157 if (child === b) {
4158 // We've determined that B is the current branch.
4159 assertIsMounted(parentA);
4160 return alternate;
4161 }
4162 child = child.sibling;
4163 }
4164 // We should never have an alternate for any mounting node. So the only
4165 // way this could possibly happen is if this was unmounted, if at all.
4166 invariant(false, 'Unable to find node on an unmounted component.');
4167 }
4168
4169 if (a.return !== b.return) {
4170 // The return pointer of A and the return pointer of B point to different
4171 // fibers. We assume that return pointers never criss-cross, so A must
4172 // belong to the child set of A.return, and B must belong to the child
4173 // set of B.return.
4174 a = parentA;
4175 b = parentB;
4176 } else {
4177 // The return pointers point to the same fiber. We'll have to use the
4178 // default, slow path: scan the child sets of each parent alternate to see
4179 // which child belongs to which set.
4180 //
4181 // Search parent A's child set
4182 var didFindChild = false;
4183 var _child = parentA.child;
4184 while (_child) {
4185 if (_child === a) {
4186 didFindChild = true;
4187 a = parentA;
4188 b = parentB;
4189 break;
4190 }
4191 if (_child === b) {
4192 didFindChild = true;
4193 b = parentA;
4194 a = parentB;
4195 break;
4196 }
4197 _child = _child.sibling;
4198 }
4199 if (!didFindChild) {
4200 // Search parent B's child set
4201 _child = parentB.child;
4202 while (_child) {
4203 if (_child === a) {
4204 didFindChild = true;
4205 a = parentB;
4206 b = parentA;
4207 break;
4208 }
4209 if (_child === b) {
4210 didFindChild = true;
4211 b = parentB;
4212 a = parentA;
4213 break;
4214 }
4215 _child = _child.sibling;
4216 }
4217 !didFindChild ? invariant(false, 'Child was not found in either parent set. This indicates a bug in React related to the return pointer. Please file an issue.') : void 0;
4218 }
4219 }
4220
4221 !(a.alternate === b) ? invariant(false, 'Return fibers should always be each others\' alternates. This error is likely caused by a bug in React. Please file an issue.') : void 0;
4222 }
4223 // If the root is not a host container, we're in a disconnected tree. I.e.
4224 // unmounted.
4225 !(a.tag === HostRoot) ? invariant(false, 'Unable to find node on an unmounted component.') : void 0;
4226 if (a.stateNode.current === a) {
4227 // We've determined that A is the current branch.
4228 return fiber;
4229 }
4230 // Otherwise B has to be current branch.
4231 return alternate;
4232}
4233
4234function findCurrentHostFiber(parent) {
4235 var currentParent = findCurrentFiberUsingSlowPath(parent);
4236 if (!currentParent) {
4237 return null;
4238 }
4239
4240 // Next we'll drill down this component to find the first HostComponent/Text.
4241 var node = currentParent;
4242 while (true) {
4243 if (node.tag === HostComponent || node.tag === HostText) {
4244 return node;
4245 } else if (node.child) {
4246 node.child.return = node;
4247 node = node.child;
4248 continue;
4249 }
4250 if (node === currentParent) {
4251 return null;
4252 }
4253 while (!node.sibling) {
4254 if (!node.return || node.return === currentParent) {
4255 return null;
4256 }
4257 node = node.return;
4258 }
4259 node.sibling.return = node.return;
4260 node = node.sibling;
4261 }
4262 // Flow needs the return null here, but ESLint complains about it.
4263 // eslint-disable-next-line no-unreachable
4264 return null;
4265}
4266
4267function findCurrentHostFiberWithNoPortals(parent) {
4268 var currentParent = findCurrentFiberUsingSlowPath(parent);
4269 if (!currentParent) {
4270 return null;
4271 }
4272
4273 // Next we'll drill down this component to find the first HostComponent/Text.
4274 var node = currentParent;
4275 while (true) {
4276 if (node.tag === HostComponent || node.tag === HostText) {
4277 return node;
4278 } else if (node.child && node.tag !== HostPortal) {
4279 node.child.return = node;
4280 node = node.child;
4281 continue;
4282 }
4283 if (node === currentParent) {
4284 return null;
4285 }
4286 while (!node.sibling) {
4287 if (!node.return || node.return === currentParent) {
4288 return null;
4289 }
4290 node = node.return;
4291 }
4292 node.sibling.return = node.return;
4293 node = node.sibling;
4294 }
4295 // Flow needs the return null here, but ESLint complains about it.
4296 // eslint-disable-next-line no-unreachable
4297 return null;
4298}
4299
4300function addEventBubbleListener(element, eventType, listener) {
4301 element.addEventListener(eventType, listener, false);
4302}
4303
4304function addEventCaptureListener(element, eventType, listener) {
4305 element.addEventListener(eventType, listener, true);
4306}
4307
4308/**
4309 * @interface Event
4310 * @see http://www.w3.org/TR/css3-animations/#AnimationEvent-interface
4311 * @see https://developer.mozilla.org/en-US/docs/Web/API/AnimationEvent
4312 */
4313var SyntheticAnimationEvent = SyntheticEvent.extend({
4314 animationName: null,
4315 elapsedTime: null,
4316 pseudoElement: null
4317});
4318
4319/**
4320 * @interface Event
4321 * @see http://www.w3.org/TR/clipboard-apis/
4322 */
4323var SyntheticClipboardEvent = SyntheticEvent.extend({
4324 clipboardData: function (event) {
4325 return 'clipboardData' in event ? event.clipboardData : window.clipboardData;
4326 }
4327});
4328
4329/**
4330 * @interface FocusEvent
4331 * @see http://www.w3.org/TR/DOM-Level-3-Events/
4332 */
4333var SyntheticFocusEvent = SyntheticUIEvent.extend({
4334 relatedTarget: null
4335});
4336
4337/**
4338 * `charCode` represents the actual "character code" and is safe to use with
4339 * `String.fromCharCode`. As such, only keys that correspond to printable
4340 * characters produce a valid `charCode`, the only exception to this is Enter.
4341 * The Tab-key is considered non-printable and does not have a `charCode`,
4342 * presumably because it does not produce a tab-character in browsers.
4343 *
4344 * @param {object} nativeEvent Native browser event.
4345 * @return {number} Normalized `charCode` property.
4346 */
4347function getEventCharCode(nativeEvent) {
4348 var charCode = void 0;
4349 var keyCode = nativeEvent.keyCode;
4350
4351 if ('charCode' in nativeEvent) {
4352 charCode = nativeEvent.charCode;
4353
4354 // FF does not set `charCode` for the Enter-key, check against `keyCode`.
4355 if (charCode === 0 && keyCode === 13) {
4356 charCode = 13;
4357 }
4358 } else {
4359 // IE8 does not implement `charCode`, but `keyCode` has the correct value.
4360 charCode = keyCode;
4361 }
4362
4363 // IE and Edge (on Windows) and Chrome / Safari (on Windows and Linux)
4364 // report Enter as charCode 10 when ctrl is pressed.
4365 if (charCode === 10) {
4366 charCode = 13;
4367 }
4368
4369 // Some non-printable keys are reported in `charCode`/`keyCode`, discard them.
4370 // Must not discard the (non-)printable Enter-key.
4371 if (charCode >= 32 || charCode === 13) {
4372 return charCode;
4373 }
4374
4375 return 0;
4376}
4377
4378/**
4379 * Normalization of deprecated HTML5 `key` values
4380 * @see https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent#Key_names
4381 */
4382var normalizeKey = {
4383 Esc: 'Escape',
4384 Spacebar: ' ',
4385 Left: 'ArrowLeft',
4386 Up: 'ArrowUp',
4387 Right: 'ArrowRight',
4388 Down: 'ArrowDown',
4389 Del: 'Delete',
4390 Win: 'OS',
4391 Menu: 'ContextMenu',
4392 Apps: 'ContextMenu',
4393 Scroll: 'ScrollLock',
4394 MozPrintableKey: 'Unidentified'
4395};
4396
4397/**
4398 * Translation from legacy `keyCode` to HTML5 `key`
4399 * Only special keys supported, all others depend on keyboard layout or browser
4400 * @see https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent#Key_names
4401 */
4402var translateToKey = {
4403 '8': 'Backspace',
4404 '9': 'Tab',
4405 '12': 'Clear',
4406 '13': 'Enter',
4407 '16': 'Shift',
4408 '17': 'Control',
4409 '18': 'Alt',
4410 '19': 'Pause',
4411 '20': 'CapsLock',
4412 '27': 'Escape',
4413 '32': ' ',
4414 '33': 'PageUp',
4415 '34': 'PageDown',
4416 '35': 'End',
4417 '36': 'Home',
4418 '37': 'ArrowLeft',
4419 '38': 'ArrowUp',
4420 '39': 'ArrowRight',
4421 '40': 'ArrowDown',
4422 '45': 'Insert',
4423 '46': 'Delete',
4424 '112': 'F1',
4425 '113': 'F2',
4426 '114': 'F3',
4427 '115': 'F4',
4428 '116': 'F5',
4429 '117': 'F6',
4430 '118': 'F7',
4431 '119': 'F8',
4432 '120': 'F9',
4433 '121': 'F10',
4434 '122': 'F11',
4435 '123': 'F12',
4436 '144': 'NumLock',
4437 '145': 'ScrollLock',
4438 '224': 'Meta'
4439};
4440
4441/**
4442 * @param {object} nativeEvent Native browser event.
4443 * @return {string} Normalized `key` property.
4444 */
4445function getEventKey(nativeEvent) {
4446 if (nativeEvent.key) {
4447 // Normalize inconsistent values reported by browsers due to
4448 // implementations of a working draft specification.
4449
4450 // FireFox implements `key` but returns `MozPrintableKey` for all
4451 // printable characters (normalized to `Unidentified`), ignore it.
4452 var key = normalizeKey[nativeEvent.key] || nativeEvent.key;
4453 if (key !== 'Unidentified') {
4454 return key;
4455 }
4456 }
4457
4458 // Browser does not implement `key`, polyfill as much of it as we can.
4459 if (nativeEvent.type === 'keypress') {
4460 var charCode = getEventCharCode(nativeEvent);
4461
4462 // The enter-key is technically both printable and non-printable and can
4463 // thus be captured by `keypress`, no other non-printable key should.
4464 return charCode === 13 ? 'Enter' : String.fromCharCode(charCode);
4465 }
4466 if (nativeEvent.type === 'keydown' || nativeEvent.type === 'keyup') {
4467 // While user keyboard layout determines the actual meaning of each
4468 // `keyCode` value, almost all function keys have a universal value.
4469 return translateToKey[nativeEvent.keyCode] || 'Unidentified';
4470 }
4471 return '';
4472}
4473
4474/**
4475 * @interface KeyboardEvent
4476 * @see http://www.w3.org/TR/DOM-Level-3-Events/
4477 */
4478var SyntheticKeyboardEvent = SyntheticUIEvent.extend({
4479 key: getEventKey,
4480 location: null,
4481 ctrlKey: null,
4482 shiftKey: null,
4483 altKey: null,
4484 metaKey: null,
4485 repeat: null,
4486 locale: null,
4487 getModifierState: getEventModifierState,
4488 // Legacy Interface
4489 charCode: function (event) {
4490 // `charCode` is the result of a KeyPress event and represents the value of
4491 // the actual printable character.
4492
4493 // KeyPress is deprecated, but its replacement is not yet final and not
4494 // implemented in any major browser. Only KeyPress has charCode.
4495 if (event.type === 'keypress') {
4496 return getEventCharCode(event);
4497 }
4498 return 0;
4499 },
4500 keyCode: function (event) {
4501 // `keyCode` is the result of a KeyDown/Up event and represents the value of
4502 // physical keyboard key.
4503
4504 // The actual meaning of the value depends on the users' keyboard layout
4505 // which cannot be detected. Assuming that it is a US keyboard layout
4506 // provides a surprisingly accurate mapping for US and European users.
4507 // Due to this, it is left to the user to implement at this time.
4508 if (event.type === 'keydown' || event.type === 'keyup') {
4509 return event.keyCode;
4510 }
4511 return 0;
4512 },
4513 which: function (event) {
4514 // `which` is an alias for either `keyCode` or `charCode` depending on the
4515 // type of the event.
4516 if (event.type === 'keypress') {
4517 return getEventCharCode(event);
4518 }
4519 if (event.type === 'keydown' || event.type === 'keyup') {
4520 return event.keyCode;
4521 }
4522 return 0;
4523 }
4524});
4525
4526/**
4527 * @interface DragEvent
4528 * @see http://www.w3.org/TR/DOM-Level-3-Events/
4529 */
4530var SyntheticDragEvent = SyntheticMouseEvent.extend({
4531 dataTransfer: null
4532});
4533
4534/**
4535 * @interface TouchEvent
4536 * @see http://www.w3.org/TR/touch-events/
4537 */
4538var SyntheticTouchEvent = SyntheticUIEvent.extend({
4539 touches: null,
4540 targetTouches: null,
4541 changedTouches: null,
4542 altKey: null,
4543 metaKey: null,
4544 ctrlKey: null,
4545 shiftKey: null,
4546 getModifierState: getEventModifierState
4547});
4548
4549/**
4550 * @interface Event
4551 * @see http://www.w3.org/TR/2009/WD-css3-transitions-20090320/#transition-events-
4552 * @see https://developer.mozilla.org/en-US/docs/Web/API/TransitionEvent
4553 */
4554var SyntheticTransitionEvent = SyntheticEvent.extend({
4555 propertyName: null,
4556 elapsedTime: null,
4557 pseudoElement: null
4558});
4559
4560/**
4561 * @interface WheelEvent
4562 * @see http://www.w3.org/TR/DOM-Level-3-Events/
4563 */
4564var SyntheticWheelEvent = SyntheticMouseEvent.extend({
4565 deltaX: function (event) {
4566 return 'deltaX' in event ? event.deltaX : // Fallback to `wheelDeltaX` for Webkit and normalize (right is positive).
4567 'wheelDeltaX' in event ? -event.wheelDeltaX : 0;
4568 },
4569 deltaY: function (event) {
4570 return 'deltaY' in event ? event.deltaY : // Fallback to `wheelDeltaY` for Webkit and normalize (down is positive).
4571 'wheelDeltaY' in event ? -event.wheelDeltaY : // Fallback to `wheelDelta` for IE<9 and normalize (down is positive).
4572 'wheelDelta' in event ? -event.wheelDelta : 0;
4573 },
4574
4575 deltaZ: null,
4576
4577 // Browsers without "deltaMode" is reporting in raw wheel delta where one
4578 // notch on the scroll is always +/- 120, roughly equivalent to pixels.
4579 // A good approximation of DOM_DELTA_LINE (1) is 5% of viewport size or
4580 // ~40 pixels, for DOM_DELTA_SCREEN (2) it is 87.5% of viewport size.
4581 deltaMode: null
4582});
4583
4584/**
4585 * Turns
4586 * ['abort', ...]
4587 * into
4588 * eventTypes = {
4589 * 'abort': {
4590 * phasedRegistrationNames: {
4591 * bubbled: 'onAbort',
4592 * captured: 'onAbortCapture',
4593 * },
4594 * dependencies: [TOP_ABORT],
4595 * },
4596 * ...
4597 * };
4598 * topLevelEventsToDispatchConfig = new Map([
4599 * [TOP_ABORT, { sameConfig }],
4600 * ]);
4601 */
4602
4603var interactiveEventTypeNames = [[TOP_BLUR, 'blur'], [TOP_CANCEL, 'cancel'], [TOP_CLICK, 'click'], [TOP_CLOSE, 'close'], [TOP_CONTEXT_MENU, 'contextMenu'], [TOP_COPY, 'copy'], [TOP_CUT, 'cut'], [TOP_AUX_CLICK, 'auxClick'], [TOP_DOUBLE_CLICK, 'doubleClick'], [TOP_DRAG_END, 'dragEnd'], [TOP_DRAG_START, 'dragStart'], [TOP_DROP, 'drop'], [TOP_FOCUS, 'focus'], [TOP_INPUT, 'input'], [TOP_INVALID, 'invalid'], [TOP_KEY_DOWN, 'keyDown'], [TOP_KEY_PRESS, 'keyPress'], [TOP_KEY_UP, 'keyUp'], [TOP_MOUSE_DOWN, 'mouseDown'], [TOP_MOUSE_UP, 'mouseUp'], [TOP_PASTE, 'paste'], [TOP_PAUSE, 'pause'], [TOP_PLAY, 'play'], [TOP_POINTER_CANCEL, 'pointerCancel'], [TOP_POINTER_DOWN, 'pointerDown'], [TOP_POINTER_UP, 'pointerUp'], [TOP_RATE_CHANGE, 'rateChange'], [TOP_RESET, 'reset'], [TOP_SEEKED, 'seeked'], [TOP_SUBMIT, 'submit'], [TOP_TOUCH_CANCEL, 'touchCancel'], [TOP_TOUCH_END, 'touchEnd'], [TOP_TOUCH_START, 'touchStart'], [TOP_VOLUME_CHANGE, 'volumeChange']];
4604var nonInteractiveEventTypeNames = [[TOP_ABORT, 'abort'], [TOP_ANIMATION_END, 'animationEnd'], [TOP_ANIMATION_ITERATION, 'animationIteration'], [TOP_ANIMATION_START, 'animationStart'], [TOP_CAN_PLAY, 'canPlay'], [TOP_CAN_PLAY_THROUGH, 'canPlayThrough'], [TOP_DRAG, 'drag'], [TOP_DRAG_ENTER, 'dragEnter'], [TOP_DRAG_EXIT, 'dragExit'], [TOP_DRAG_LEAVE, 'dragLeave'], [TOP_DRAG_OVER, 'dragOver'], [TOP_DURATION_CHANGE, 'durationChange'], [TOP_EMPTIED, 'emptied'], [TOP_ENCRYPTED, 'encrypted'], [TOP_ENDED, 'ended'], [TOP_ERROR, 'error'], [TOP_GOT_POINTER_CAPTURE, 'gotPointerCapture'], [TOP_LOAD, 'load'], [TOP_LOADED_DATA, 'loadedData'], [TOP_LOADED_METADATA, 'loadedMetadata'], [TOP_LOAD_START, 'loadStart'], [TOP_LOST_POINTER_CAPTURE, 'lostPointerCapture'], [TOP_MOUSE_MOVE, 'mouseMove'], [TOP_MOUSE_OUT, 'mouseOut'], [TOP_MOUSE_OVER, 'mouseOver'], [TOP_PLAYING, 'playing'], [TOP_POINTER_MOVE, 'pointerMove'], [TOP_POINTER_OUT, 'pointerOut'], [TOP_POINTER_OVER, 'pointerOver'], [TOP_PROGRESS, 'progress'], [TOP_SCROLL, 'scroll'], [TOP_SEEKING, 'seeking'], [TOP_STALLED, 'stalled'], [TOP_SUSPEND, 'suspend'], [TOP_TIME_UPDATE, 'timeUpdate'], [TOP_TOGGLE, 'toggle'], [TOP_TOUCH_MOVE, 'touchMove'], [TOP_TRANSITION_END, 'transitionEnd'], [TOP_WAITING, 'waiting'], [TOP_WHEEL, 'wheel']];
4605
4606var eventTypes$4 = {};
4607var topLevelEventsToDispatchConfig = {};
4608
4609function addEventTypeNameToConfig(_ref, isInteractive) {
4610 var topEvent = _ref[0],
4611 event = _ref[1];
4612
4613 var capitalizedEvent = event[0].toUpperCase() + event.slice(1);
4614 var onEvent = 'on' + capitalizedEvent;
4615
4616 var type = {
4617 phasedRegistrationNames: {
4618 bubbled: onEvent,
4619 captured: onEvent + 'Capture'
4620 },
4621 dependencies: [topEvent],
4622 isInteractive: isInteractive
4623 };
4624 eventTypes$4[event] = type;
4625 topLevelEventsToDispatchConfig[topEvent] = type;
4626}
4627
4628interactiveEventTypeNames.forEach(function (eventTuple) {
4629 addEventTypeNameToConfig(eventTuple, true);
4630});
4631nonInteractiveEventTypeNames.forEach(function (eventTuple) {
4632 addEventTypeNameToConfig(eventTuple, false);
4633});
4634
4635// Only used in DEV for exhaustiveness validation.
4636var knownHTMLTopLevelTypes = [TOP_ABORT, TOP_CANCEL, TOP_CAN_PLAY, TOP_CAN_PLAY_THROUGH, TOP_CLOSE, TOP_DURATION_CHANGE, TOP_EMPTIED, TOP_ENCRYPTED, TOP_ENDED, TOP_ERROR, TOP_INPUT, TOP_INVALID, TOP_LOAD, TOP_LOADED_DATA, TOP_LOADED_METADATA, TOP_LOAD_START, TOP_PAUSE, TOP_PLAY, TOP_PLAYING, TOP_PROGRESS, TOP_RATE_CHANGE, TOP_RESET, TOP_SEEKED, TOP_SEEKING, TOP_STALLED, TOP_SUBMIT, TOP_SUSPEND, TOP_TIME_UPDATE, TOP_TOGGLE, TOP_VOLUME_CHANGE, TOP_WAITING];
4637
4638var SimpleEventPlugin = {
4639 eventTypes: eventTypes$4,
4640
4641 isInteractiveTopLevelEventType: function (topLevelType) {
4642 var config = topLevelEventsToDispatchConfig[topLevelType];
4643 return config !== undefined && config.isInteractive === true;
4644 },
4645
4646
4647 extractEvents: function (topLevelType, targetInst, nativeEvent, nativeEventTarget) {
4648 var dispatchConfig = topLevelEventsToDispatchConfig[topLevelType];
4649 if (!dispatchConfig) {
4650 return null;
4651 }
4652 var EventConstructor = void 0;
4653 switch (topLevelType) {
4654 case TOP_KEY_PRESS:
4655 // Firefox creates a keypress event for function keys too. This removes
4656 // the unwanted keypress events. Enter is however both printable and
4657 // non-printable. One would expect Tab to be as well (but it isn't).
4658 if (getEventCharCode(nativeEvent) === 0) {
4659 return null;
4660 }
4661 /* falls through */
4662 case TOP_KEY_DOWN:
4663 case TOP_KEY_UP:
4664 EventConstructor = SyntheticKeyboardEvent;
4665 break;
4666 case TOP_BLUR:
4667 case TOP_FOCUS:
4668 EventConstructor = SyntheticFocusEvent;
4669 break;
4670 case TOP_CLICK:
4671 // Firefox creates a click event on right mouse clicks. This removes the
4672 // unwanted click events.
4673 if (nativeEvent.button === 2) {
4674 return null;
4675 }
4676 /* falls through */
4677 case TOP_AUX_CLICK:
4678 case TOP_DOUBLE_CLICK:
4679 case TOP_MOUSE_DOWN:
4680 case TOP_MOUSE_MOVE:
4681 case TOP_MOUSE_UP:
4682 // TODO: Disabled elements should not respond to mouse events
4683 /* falls through */
4684 case TOP_MOUSE_OUT:
4685 case TOP_MOUSE_OVER:
4686 case TOP_CONTEXT_MENU:
4687 EventConstructor = SyntheticMouseEvent;
4688 break;
4689 case TOP_DRAG:
4690 case TOP_DRAG_END:
4691 case TOP_DRAG_ENTER:
4692 case TOP_DRAG_EXIT:
4693 case TOP_DRAG_LEAVE:
4694 case TOP_DRAG_OVER:
4695 case TOP_DRAG_START:
4696 case TOP_DROP:
4697 EventConstructor = SyntheticDragEvent;
4698 break;
4699 case TOP_TOUCH_CANCEL:
4700 case TOP_TOUCH_END:
4701 case TOP_TOUCH_MOVE:
4702 case TOP_TOUCH_START:
4703 EventConstructor = SyntheticTouchEvent;
4704 break;
4705 case TOP_ANIMATION_END:
4706 case TOP_ANIMATION_ITERATION:
4707 case TOP_ANIMATION_START:
4708 EventConstructor = SyntheticAnimationEvent;
4709 break;
4710 case TOP_TRANSITION_END:
4711 EventConstructor = SyntheticTransitionEvent;
4712 break;
4713 case TOP_SCROLL:
4714 EventConstructor = SyntheticUIEvent;
4715 break;
4716 case TOP_WHEEL:
4717 EventConstructor = SyntheticWheelEvent;
4718 break;
4719 case TOP_COPY:
4720 case TOP_CUT:
4721 case TOP_PASTE:
4722 EventConstructor = SyntheticClipboardEvent;
4723 break;
4724 case TOP_GOT_POINTER_CAPTURE:
4725 case TOP_LOST_POINTER_CAPTURE:
4726 case TOP_POINTER_CANCEL:
4727 case TOP_POINTER_DOWN:
4728 case TOP_POINTER_MOVE:
4729 case TOP_POINTER_OUT:
4730 case TOP_POINTER_OVER:
4731 case TOP_POINTER_UP:
4732 EventConstructor = SyntheticPointerEvent;
4733 break;
4734 default:
4735 {
4736 if (knownHTMLTopLevelTypes.indexOf(topLevelType) === -1) {
4737 warningWithoutStack$1(false, 'SimpleEventPlugin: Unhandled event type, `%s`. This warning ' + 'is likely caused by a bug in React. Please file an issue.', topLevelType);
4738 }
4739 }
4740 // HTML Events
4741 // @see http://www.w3.org/TR/html5/index.html#events-0
4742 EventConstructor = SyntheticEvent;
4743 break;
4744 }
4745 var event = EventConstructor.getPooled(dispatchConfig, targetInst, nativeEvent, nativeEventTarget);
4746 accumulateTwoPhaseDispatches(event);
4747 return event;
4748 }
4749};
4750
4751var isInteractiveTopLevelEventType = SimpleEventPlugin.isInteractiveTopLevelEventType;
4752
4753
4754var CALLBACK_BOOKKEEPING_POOL_SIZE = 10;
4755var callbackBookkeepingPool = [];
4756
4757/**
4758 * Find the deepest React component completely containing the root of the
4759 * passed-in instance (for use when entire React trees are nested within each
4760 * other). If React trees are not nested, returns null.
4761 */
4762function findRootContainerNode(inst) {
4763 // TODO: It may be a good idea to cache this to prevent unnecessary DOM
4764 // traversal, but caching is difficult to do correctly without using a
4765 // mutation observer to listen for all DOM changes.
4766 while (inst.return) {
4767 inst = inst.return;
4768 }
4769 if (inst.tag !== HostRoot) {
4770 // This can happen if we're in a detached tree.
4771 return null;
4772 }
4773 return inst.stateNode.containerInfo;
4774}
4775
4776// Used to store ancestor hierarchy in top level callback
4777function getTopLevelCallbackBookKeeping(topLevelType, nativeEvent, targetInst) {
4778 if (callbackBookkeepingPool.length) {
4779 var instance = callbackBookkeepingPool.pop();
4780 instance.topLevelType = topLevelType;
4781 instance.nativeEvent = nativeEvent;
4782 instance.targetInst = targetInst;
4783 return instance;
4784 }
4785 return {
4786 topLevelType: topLevelType,
4787 nativeEvent: nativeEvent,
4788 targetInst: targetInst,
4789 ancestors: []
4790 };
4791}
4792
4793function releaseTopLevelCallbackBookKeeping(instance) {
4794 instance.topLevelType = null;
4795 instance.nativeEvent = null;
4796 instance.targetInst = null;
4797 instance.ancestors.length = 0;
4798 if (callbackBookkeepingPool.length < CALLBACK_BOOKKEEPING_POOL_SIZE) {
4799 callbackBookkeepingPool.push(instance);
4800 }
4801}
4802
4803function handleTopLevel(bookKeeping) {
4804 var targetInst = bookKeeping.targetInst;
4805
4806 // Loop through the hierarchy, in case there's any nested components.
4807 // It's important that we build the array of ancestors before calling any
4808 // event handlers, because event handlers can modify the DOM, leading to
4809 // inconsistencies with ReactMount's node cache. See #1105.
4810 var ancestor = targetInst;
4811 do {
4812 if (!ancestor) {
4813 bookKeeping.ancestors.push(ancestor);
4814 break;
4815 }
4816 var root = findRootContainerNode(ancestor);
4817 if (!root) {
4818 break;
4819 }
4820 bookKeeping.ancestors.push(ancestor);
4821 ancestor = getClosestInstanceFromNode(root);
4822 } while (ancestor);
4823
4824 for (var i = 0; i < bookKeeping.ancestors.length; i++) {
4825 targetInst = bookKeeping.ancestors[i];
4826 runExtractedEventsInBatch(bookKeeping.topLevelType, targetInst, bookKeeping.nativeEvent, getEventTarget(bookKeeping.nativeEvent));
4827 }
4828}
4829
4830// TODO: can we stop exporting these?
4831var _enabled = true;
4832
4833function setEnabled(enabled) {
4834 _enabled = !!enabled;
4835}
4836
4837function isEnabled() {
4838 return _enabled;
4839}
4840
4841/**
4842 * Traps top-level events by using event bubbling.
4843 *
4844 * @param {number} topLevelType Number from `TopLevelEventTypes`.
4845 * @param {object} element Element on which to attach listener.
4846 * @return {?object} An object with a remove function which will forcefully
4847 * remove the listener.
4848 * @internal
4849 */
4850function trapBubbledEvent(topLevelType, element) {
4851 if (!element) {
4852 return null;
4853 }
4854 var dispatch = isInteractiveTopLevelEventType(topLevelType) ? dispatchInteractiveEvent : dispatchEvent;
4855
4856 addEventBubbleListener(element, getRawEventName(topLevelType),
4857 // Check if interactive and wrap in interactiveUpdates
4858 dispatch.bind(null, topLevelType));
4859}
4860
4861/**
4862 * Traps a top-level event by using event capturing.
4863 *
4864 * @param {number} topLevelType Number from `TopLevelEventTypes`.
4865 * @param {object} element Element on which to attach listener.
4866 * @return {?object} An object with a remove function which will forcefully
4867 * remove the listener.
4868 * @internal
4869 */
4870function trapCapturedEvent(topLevelType, element) {
4871 if (!element) {
4872 return null;
4873 }
4874 var dispatch = isInteractiveTopLevelEventType(topLevelType) ? dispatchInteractiveEvent : dispatchEvent;
4875
4876 addEventCaptureListener(element, getRawEventName(topLevelType),
4877 // Check if interactive and wrap in interactiveUpdates
4878 dispatch.bind(null, topLevelType));
4879}
4880
4881function dispatchInteractiveEvent(topLevelType, nativeEvent) {
4882 interactiveUpdates(dispatchEvent, topLevelType, nativeEvent);
4883}
4884
4885function dispatchEvent(topLevelType, nativeEvent) {
4886 if (!_enabled) {
4887 return;
4888 }
4889
4890 var nativeEventTarget = getEventTarget(nativeEvent);
4891 var targetInst = getClosestInstanceFromNode(nativeEventTarget);
4892 if (targetInst !== null && typeof targetInst.tag === 'number' && !isFiberMounted(targetInst)) {
4893 // If we get an event (ex: img onload) before committing that
4894 // component's mount, ignore it for now (that is, treat it as if it was an
4895 // event on a non-React tree). We might also consider queueing events and
4896 // dispatching them after the mount.
4897 targetInst = null;
4898 }
4899
4900 var bookKeeping = getTopLevelCallbackBookKeeping(topLevelType, nativeEvent, targetInst);
4901
4902 try {
4903 // Event queue being processed in the same cycle allows
4904 // `preventDefault`.
4905 batchedUpdates(handleTopLevel, bookKeeping);
4906 } finally {
4907 releaseTopLevelCallbackBookKeeping(bookKeeping);
4908 }
4909}
4910
4911/**
4912 * Summary of `ReactBrowserEventEmitter` event handling:
4913 *
4914 * - Top-level delegation is used to trap most native browser events. This
4915 * may only occur in the main thread and is the responsibility of
4916 * ReactDOMEventListener, which is injected and can therefore support
4917 * pluggable event sources. This is the only work that occurs in the main
4918 * thread.
4919 *
4920 * - We normalize and de-duplicate events to account for browser quirks. This
4921 * may be done in the worker thread.
4922 *
4923 * - Forward these native events (with the associated top-level type used to
4924 * trap it) to `EventPluginHub`, which in turn will ask plugins if they want
4925 * to extract any synthetic events.
4926 *
4927 * - The `EventPluginHub` will then process each event by annotating them with
4928 * "dispatches", a sequence of listeners and IDs that care about that event.
4929 *
4930 * - The `EventPluginHub` then dispatches the events.
4931 *
4932 * Overview of React and the event system:
4933 *
4934 * +------------+ .
4935 * | DOM | .
4936 * +------------+ .
4937 * | .
4938 * v .
4939 * +------------+ .
4940 * | ReactEvent | .
4941 * | Listener | .
4942 * +------------+ . +-----------+
4943 * | . +--------+|SimpleEvent|
4944 * | . | |Plugin |
4945 * +-----|------+ . v +-----------+
4946 * | | | . +--------------+ +------------+
4947 * | +-----------.--->|EventPluginHub| | Event |
4948 * | | . | | +-----------+ | Propagators|
4949 * | ReactEvent | . | | |TapEvent | |------------|
4950 * | Emitter | . | |<---+|Plugin | |other plugin|
4951 * | | . | | +-----------+ | utilities |
4952 * | +-----------.--->| | +------------+
4953 * | | | . +--------------+
4954 * +-----|------+ . ^ +-----------+
4955 * | . | |Enter/Leave|
4956 * + . +-------+|Plugin |
4957 * +-------------+ . +-----------+
4958 * | application | .
4959 * |-------------| .
4960 * | | .
4961 * | | .
4962 * +-------------+ .
4963 * .
4964 * React Core . General Purpose Event Plugin System
4965 */
4966
4967var alreadyListeningTo = {};
4968var reactTopListenersCounter = 0;
4969
4970/**
4971 * To ensure no conflicts with other potential React instances on the page
4972 */
4973var topListenersIDKey = '_reactListenersID' + ('' + Math.random()).slice(2);
4974
4975function getListeningForDocument(mountAt) {
4976 // In IE8, `mountAt` is a host object and doesn't have `hasOwnProperty`
4977 // directly.
4978 if (!Object.prototype.hasOwnProperty.call(mountAt, topListenersIDKey)) {
4979 mountAt[topListenersIDKey] = reactTopListenersCounter++;
4980 alreadyListeningTo[mountAt[topListenersIDKey]] = {};
4981 }
4982 return alreadyListeningTo[mountAt[topListenersIDKey]];
4983}
4984
4985/**
4986 * We listen for bubbled touch events on the document object.
4987 *
4988 * Firefox v8.01 (and possibly others) exhibited strange behavior when
4989 * mounting `onmousemove` events at some node that was not the document
4990 * element. The symptoms were that if your mouse is not moving over something
4991 * contained within that mount point (for example on the background) the
4992 * top-level listeners for `onmousemove` won't be called. However, if you
4993 * register the `mousemove` on the document object, then it will of course
4994 * catch all `mousemove`s. This along with iOS quirks, justifies restricting
4995 * top-level listeners to the document object only, at least for these
4996 * movement types of events and possibly all events.
4997 *
4998 * @see http://www.quirksmode.org/blog/archives/2010/09/click_event_del.html
4999 *
5000 * Also, `keyup`/`keypress`/`keydown` do not bubble to the window on IE, but
5001 * they bubble to document.
5002 *
5003 * @param {string} registrationName Name of listener (e.g. `onClick`).
5004 * @param {object} mountAt Container where to mount the listener
5005 */
5006function listenTo(registrationName, mountAt) {
5007 var isListening = getListeningForDocument(mountAt);
5008 var dependencies = registrationNameDependencies[registrationName];
5009
5010 for (var i = 0; i < dependencies.length; i++) {
5011 var dependency = dependencies[i];
5012 if (!(isListening.hasOwnProperty(dependency) && isListening[dependency])) {
5013 switch (dependency) {
5014 case TOP_SCROLL:
5015 trapCapturedEvent(TOP_SCROLL, mountAt);
5016 break;
5017 case TOP_FOCUS:
5018 case TOP_BLUR:
5019 trapCapturedEvent(TOP_FOCUS, mountAt);
5020 trapCapturedEvent(TOP_BLUR, mountAt);
5021 // We set the flag for a single dependency later in this function,
5022 // but this ensures we mark both as attached rather than just one.
5023 isListening[TOP_BLUR] = true;
5024 isListening[TOP_FOCUS] = true;
5025 break;
5026 case TOP_CANCEL:
5027 case TOP_CLOSE:
5028 if (isEventSupported(getRawEventName(dependency))) {
5029 trapCapturedEvent(dependency, mountAt);
5030 }
5031 break;
5032 case TOP_INVALID:
5033 case TOP_SUBMIT:
5034 case TOP_RESET:
5035 // We listen to them on the target DOM elements.
5036 // Some of them bubble so we don't want them to fire twice.
5037 break;
5038 default:
5039 // By default, listen on the top level to all non-media events.
5040 // Media events don't bubble so adding the listener wouldn't do anything.
5041 var isMediaEvent = mediaEventTypes.indexOf(dependency) !== -1;
5042 if (!isMediaEvent) {
5043 trapBubbledEvent(dependency, mountAt);
5044 }
5045 break;
5046 }
5047 isListening[dependency] = true;
5048 }
5049 }
5050}
5051
5052function isListeningToAllDependencies(registrationName, mountAt) {
5053 var isListening = getListeningForDocument(mountAt);
5054 var dependencies = registrationNameDependencies[registrationName];
5055 for (var i = 0; i < dependencies.length; i++) {
5056 var dependency = dependencies[i];
5057 if (!(isListening.hasOwnProperty(dependency) && isListening[dependency])) {
5058 return false;
5059 }
5060 }
5061 return true;
5062}
5063
5064function getActiveElement(doc) {
5065 doc = doc || (typeof document !== 'undefined' ? document : undefined);
5066 if (typeof doc === 'undefined') {
5067 return null;
5068 }
5069 try {
5070 return doc.activeElement || doc.body;
5071 } catch (e) {
5072 return doc.body;
5073 }
5074}
5075
5076/**
5077 * Given any node return the first leaf node without children.
5078 *
5079 * @param {DOMElement|DOMTextNode} node
5080 * @return {DOMElement|DOMTextNode}
5081 */
5082function getLeafNode(node) {
5083 while (node && node.firstChild) {
5084 node = node.firstChild;
5085 }
5086 return node;
5087}
5088
5089/**
5090 * Get the next sibling within a container. This will walk up the
5091 * DOM if a node's siblings have been exhausted.
5092 *
5093 * @param {DOMElement|DOMTextNode} node
5094 * @return {?DOMElement|DOMTextNode}
5095 */
5096function getSiblingNode(node) {
5097 while (node) {
5098 if (node.nextSibling) {
5099 return node.nextSibling;
5100 }
5101 node = node.parentNode;
5102 }
5103}
5104
5105/**
5106 * Get object describing the nodes which contain characters at offset.
5107 *
5108 * @param {DOMElement|DOMTextNode} root
5109 * @param {number} offset
5110 * @return {?object}
5111 */
5112function getNodeForCharacterOffset(root, offset) {
5113 var node = getLeafNode(root);
5114 var nodeStart = 0;
5115 var nodeEnd = 0;
5116
5117 while (node) {
5118 if (node.nodeType === TEXT_NODE) {
5119 nodeEnd = nodeStart + node.textContent.length;
5120
5121 if (nodeStart <= offset && nodeEnd >= offset) {
5122 return {
5123 node: node,
5124 offset: offset - nodeStart
5125 };
5126 }
5127
5128 nodeStart = nodeEnd;
5129 }
5130
5131 node = getLeafNode(getSiblingNode(node));
5132 }
5133}
5134
5135/**
5136 * @param {DOMElement} outerNode
5137 * @return {?object}
5138 */
5139function getOffsets(outerNode) {
5140 var ownerDocument = outerNode.ownerDocument;
5141
5142 var win = ownerDocument && ownerDocument.defaultView || window;
5143 var selection = win.getSelection && win.getSelection();
5144
5145 if (!selection || selection.rangeCount === 0) {
5146 return null;
5147 }
5148
5149 var anchorNode = selection.anchorNode,
5150 anchorOffset = selection.anchorOffset,
5151 focusNode = selection.focusNode,
5152 focusOffset = selection.focusOffset;
5153
5154 // In Firefox, anchorNode and focusNode can be "anonymous divs", e.g. the
5155 // up/down buttons on an <input type="number">. Anonymous divs do not seem to
5156 // expose properties, triggering a "Permission denied error" if any of its
5157 // properties are accessed. The only seemingly possible way to avoid erroring
5158 // is to access a property that typically works for non-anonymous divs and
5159 // catch any error that may otherwise arise. See
5160 // https://bugzilla.mozilla.org/show_bug.cgi?id=208427
5161
5162 try {
5163 /* eslint-disable no-unused-expressions */
5164 anchorNode.nodeType;
5165 focusNode.nodeType;
5166 /* eslint-enable no-unused-expressions */
5167 } catch (e) {
5168 return null;
5169 }
5170
5171 return getModernOffsetsFromPoints(outerNode, anchorNode, anchorOffset, focusNode, focusOffset);
5172}
5173
5174/**
5175 * Returns {start, end} where `start` is the character/codepoint index of
5176 * (anchorNode, anchorOffset) within the textContent of `outerNode`, and
5177 * `end` is the index of (focusNode, focusOffset).
5178 *
5179 * Returns null if you pass in garbage input but we should probably just crash.
5180 *
5181 * Exported only for testing.
5182 */
5183function getModernOffsetsFromPoints(outerNode, anchorNode, anchorOffset, focusNode, focusOffset) {
5184 var length = 0;
5185 var start = -1;
5186 var end = -1;
5187 var indexWithinAnchor = 0;
5188 var indexWithinFocus = 0;
5189 var node = outerNode;
5190 var parentNode = null;
5191
5192 outer: while (true) {
5193 var next = null;
5194
5195 while (true) {
5196 if (node === anchorNode && (anchorOffset === 0 || node.nodeType === TEXT_NODE)) {
5197 start = length + anchorOffset;
5198 }
5199 if (node === focusNode && (focusOffset === 0 || node.nodeType === TEXT_NODE)) {
5200 end = length + focusOffset;
5201 }
5202
5203 if (node.nodeType === TEXT_NODE) {
5204 length += node.nodeValue.length;
5205 }
5206
5207 if ((next = node.firstChild) === null) {
5208 break;
5209 }
5210 // Moving from `node` to its first child `next`.
5211 parentNode = node;
5212 node = next;
5213 }
5214
5215 while (true) {
5216 if (node === outerNode) {
5217 // If `outerNode` has children, this is always the second time visiting
5218 // it. If it has no children, this is still the first loop, and the only
5219 // valid selection is anchorNode and focusNode both equal to this node
5220 // and both offsets 0, in which case we will have handled above.
5221 break outer;
5222 }
5223 if (parentNode === anchorNode && ++indexWithinAnchor === anchorOffset) {
5224 start = length;
5225 }
5226 if (parentNode === focusNode && ++indexWithinFocus === focusOffset) {
5227 end = length;
5228 }
5229 if ((next = node.nextSibling) !== null) {
5230 break;
5231 }
5232 node = parentNode;
5233 parentNode = node.parentNode;
5234 }
5235
5236 // Moving from `node` to its next sibling `next`.
5237 node = next;
5238 }
5239
5240 if (start === -1 || end === -1) {
5241 // This should never happen. (Would happen if the anchor/focus nodes aren't
5242 // actually inside the passed-in node.)
5243 return null;
5244 }
5245
5246 return {
5247 start: start,
5248 end: end
5249 };
5250}
5251
5252/**
5253 * In modern non-IE browsers, we can support both forward and backward
5254 * selections.
5255 *
5256 * Note: IE10+ supports the Selection object, but it does not support
5257 * the `extend` method, which means that even in modern IE, it's not possible
5258 * to programmatically create a backward selection. Thus, for all IE
5259 * versions, we use the old IE API to create our selections.
5260 *
5261 * @param {DOMElement|DOMTextNode} node
5262 * @param {object} offsets
5263 */
5264function setOffsets(node, offsets) {
5265 var doc = node.ownerDocument || document;
5266 var win = doc && doc.defaultView || window;
5267
5268 // Edge fails with "Object expected" in some scenarios.
5269 // (For instance: TinyMCE editor used in a list component that supports pasting to add more,
5270 // fails when pasting 100+ items)
5271 if (!win.getSelection) {
5272 return;
5273 }
5274
5275 var selection = win.getSelection();
5276 var length = node.textContent.length;
5277 var start = Math.min(offsets.start, length);
5278 var end = offsets.end === undefined ? start : Math.min(offsets.end, length);
5279
5280 // IE 11 uses modern selection, but doesn't support the extend method.
5281 // Flip backward selections, so we can set with a single range.
5282 if (!selection.extend && start > end) {
5283 var temp = end;
5284 end = start;
5285 start = temp;
5286 }
5287
5288 var startMarker = getNodeForCharacterOffset(node, start);
5289 var endMarker = getNodeForCharacterOffset(node, end);
5290
5291 if (startMarker && endMarker) {
5292 if (selection.rangeCount === 1 && selection.anchorNode === startMarker.node && selection.anchorOffset === startMarker.offset && selection.focusNode === endMarker.node && selection.focusOffset === endMarker.offset) {
5293 return;
5294 }
5295 var range = doc.createRange();
5296 range.setStart(startMarker.node, startMarker.offset);
5297 selection.removeAllRanges();
5298
5299 if (start > end) {
5300 selection.addRange(range);
5301 selection.extend(endMarker.node, endMarker.offset);
5302 } else {
5303 range.setEnd(endMarker.node, endMarker.offset);
5304 selection.addRange(range);
5305 }
5306 }
5307}
5308
5309function isTextNode(node) {
5310 return node && node.nodeType === TEXT_NODE;
5311}
5312
5313function containsNode(outerNode, innerNode) {
5314 if (!outerNode || !innerNode) {
5315 return false;
5316 } else if (outerNode === innerNode) {
5317 return true;
5318 } else if (isTextNode(outerNode)) {
5319 return false;
5320 } else if (isTextNode(innerNode)) {
5321 return containsNode(outerNode, innerNode.parentNode);
5322 } else if ('contains' in outerNode) {
5323 return outerNode.contains(innerNode);
5324 } else if (outerNode.compareDocumentPosition) {
5325 return !!(outerNode.compareDocumentPosition(innerNode) & 16);
5326 } else {
5327 return false;
5328 }
5329}
5330
5331function isInDocument(node) {
5332 return node && node.ownerDocument && containsNode(node.ownerDocument.documentElement, node);
5333}
5334
5335function 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// Prefix measurements so that it's possible to filter them.
9106// Longer prefixes are hard to read in DevTools.
9107var reactEmoji = '\u269B';
9108var warningEmoji = '\u26D4';
9109var supportsUserTiming = typeof performance !== 'undefined' && typeof performance.mark === 'function' && typeof performance.clearMarks === 'function' && typeof performance.measure === 'function' && typeof performance.clearMeasures === 'function';
9110
9111// Keep track of current fiber so that we know the path to unwind on pause.
9112// TODO: this looks the same as nextUnitOfWork in scheduler. Can we unify them?
9113var currentFiber = null;
9114// If we're in the middle of user code, which fiber and method is it?
9115// Reusing `currentFiber` would be confusing for this because user code fiber
9116// can change during commit phase too, but we don't need to unwind it (since
9117// lifecycles in the commit phase don't resemble a tree).
9118var currentPhase = null;
9119var currentPhaseFiber = null;
9120// Did lifecycle hook schedule an update? This is often a performance problem,
9121// so we will keep track of it, and include it in the report.
9122// Track commits caused by cascading updates.
9123var isCommitting = false;
9124var hasScheduledUpdateInCurrentCommit = false;
9125var hasScheduledUpdateInCurrentPhase = false;
9126var commitCountInCurrentWorkLoop = 0;
9127var effectCountInCurrentCommit = 0;
9128var isWaitingForCallback = false;
9129// During commits, we only show a measurement once per method name
9130// to avoid stretch the commit phase with measurement overhead.
9131var labelsInCurrentCommit = new Set();
9132
9133var formatMarkName = function (markName) {
9134 return reactEmoji + ' ' + markName;
9135};
9136
9137var formatLabel = function (label, warning) {
9138 var prefix = warning ? warningEmoji + ' ' : reactEmoji + ' ';
9139 var suffix = warning ? ' Warning: ' + warning : '';
9140 return '' + prefix + label + suffix;
9141};
9142
9143var beginMark = function (markName) {
9144 performance.mark(formatMarkName(markName));
9145};
9146
9147var clearMark = function (markName) {
9148 performance.clearMarks(formatMarkName(markName));
9149};
9150
9151var endMark = function (label, markName, warning) {
9152 var formattedMarkName = formatMarkName(markName);
9153 var formattedLabel = formatLabel(label, warning);
9154 try {
9155 performance.measure(formattedLabel, formattedMarkName);
9156 } catch (err) {}
9157 // If previous mark was missing for some reason, this will throw.
9158 // This could only happen if React crashed in an unexpected place earlier.
9159 // Don't pile on with more errors.
9160
9161 // Clear marks immediately to avoid growing buffer.
9162 performance.clearMarks(formattedMarkName);
9163 performance.clearMeasures(formattedLabel);
9164};
9165
9166var getFiberMarkName = function (label, debugID) {
9167 return label + ' (#' + debugID + ')';
9168};
9169
9170var getFiberLabel = function (componentName, isMounted, phase) {
9171 if (phase === null) {
9172 // These are composite component total time measurements.
9173 return componentName + ' [' + (isMounted ? 'update' : 'mount') + ']';
9174 } else {
9175 // Composite component methods.
9176 return componentName + '.' + phase;
9177 }
9178};
9179
9180var beginFiberMark = function (fiber, phase) {
9181 var componentName = getComponentName(fiber.type) || 'Unknown';
9182 var debugID = fiber._debugID;
9183 var isMounted = fiber.alternate !== null;
9184 var label = getFiberLabel(componentName, isMounted, phase);
9185
9186 if (isCommitting && labelsInCurrentCommit.has(label)) {
9187 // During the commit phase, we don't show duplicate labels because
9188 // there is a fixed overhead for every measurement, and we don't
9189 // want to stretch the commit phase beyond necessary.
9190 return false;
9191 }
9192 labelsInCurrentCommit.add(label);
9193
9194 var markName = getFiberMarkName(label, debugID);
9195 beginMark(markName);
9196 return true;
9197};
9198
9199var clearFiberMark = function (fiber, phase) {
9200 var componentName = getComponentName(fiber.type) || 'Unknown';
9201 var debugID = fiber._debugID;
9202 var isMounted = fiber.alternate !== null;
9203 var label = getFiberLabel(componentName, isMounted, phase);
9204 var markName = getFiberMarkName(label, debugID);
9205 clearMark(markName);
9206};
9207
9208var endFiberMark = function (fiber, phase, warning) {
9209 var componentName = getComponentName(fiber.type) || 'Unknown';
9210 var debugID = fiber._debugID;
9211 var isMounted = fiber.alternate !== null;
9212 var label = getFiberLabel(componentName, isMounted, phase);
9213 var markName = getFiberMarkName(label, debugID);
9214 endMark(label, markName, warning);
9215};
9216
9217var shouldIgnoreFiber = function (fiber) {
9218 // Host components should be skipped in the timeline.
9219 // We could check typeof fiber.type, but does this work with RN?
9220 switch (fiber.tag) {
9221 case HostRoot:
9222 case HostComponent:
9223 case HostText:
9224 case HostPortal:
9225 case Fragment:
9226 case ContextProvider:
9227 case ContextConsumer:
9228 case Mode:
9229 return true;
9230 default:
9231 return false;
9232 }
9233};
9234
9235var clearPendingPhaseMeasurement = function () {
9236 if (currentPhase !== null && currentPhaseFiber !== null) {
9237 clearFiberMark(currentPhaseFiber, currentPhase);
9238 }
9239 currentPhaseFiber = null;
9240 currentPhase = null;
9241 hasScheduledUpdateInCurrentPhase = false;
9242};
9243
9244var pauseTimers = function () {
9245 // Stops all currently active measurements so that they can be resumed
9246 // if we continue in a later deferred loop from the same unit of work.
9247 var fiber = currentFiber;
9248 while (fiber) {
9249 if (fiber._debugIsCurrentlyTiming) {
9250 endFiberMark(fiber, null, null);
9251 }
9252 fiber = fiber.return;
9253 }
9254};
9255
9256var resumeTimersRecursively = function (fiber) {
9257 if (fiber.return !== null) {
9258 resumeTimersRecursively(fiber.return);
9259 }
9260 if (fiber._debugIsCurrentlyTiming) {
9261 beginFiberMark(fiber, null);
9262 }
9263};
9264
9265var resumeTimers = function () {
9266 // Resumes all measurements that were active during the last deferred loop.
9267 if (currentFiber !== null) {
9268 resumeTimersRecursively(currentFiber);
9269 }
9270};
9271
9272function recordEffect() {
9273 if (enableUserTimingAPI) {
9274 effectCountInCurrentCommit++;
9275 }
9276}
9277
9278function recordScheduleUpdate() {
9279 if (enableUserTimingAPI) {
9280 if (isCommitting) {
9281 hasScheduledUpdateInCurrentCommit = true;
9282 }
9283 if (currentPhase !== null && currentPhase !== 'componentWillMount' && currentPhase !== 'componentWillReceiveProps') {
9284 hasScheduledUpdateInCurrentPhase = true;
9285 }
9286 }
9287}
9288
9289function startRequestCallbackTimer() {
9290 if (enableUserTimingAPI) {
9291 if (supportsUserTiming && !isWaitingForCallback) {
9292 isWaitingForCallback = true;
9293 beginMark('(Waiting for async callback...)');
9294 }
9295 }
9296}
9297
9298function stopRequestCallbackTimer(didExpire, expirationTime) {
9299 if (enableUserTimingAPI) {
9300 if (supportsUserTiming) {
9301 isWaitingForCallback = false;
9302 var warning = didExpire ? 'React was blocked by main thread' : null;
9303 endMark('(Waiting for async callback... will force flush in ' + expirationTime + ' ms)', '(Waiting for async callback...)', warning);
9304 }
9305 }
9306}
9307
9308function startWorkTimer(fiber) {
9309 if (enableUserTimingAPI) {
9310 if (!supportsUserTiming || shouldIgnoreFiber(fiber)) {
9311 return;
9312 }
9313 // If we pause, this is the fiber to unwind from.
9314 currentFiber = fiber;
9315 if (!beginFiberMark(fiber, null)) {
9316 return;
9317 }
9318 fiber._debugIsCurrentlyTiming = true;
9319 }
9320}
9321
9322function cancelWorkTimer(fiber) {
9323 if (enableUserTimingAPI) {
9324 if (!supportsUserTiming || shouldIgnoreFiber(fiber)) {
9325 return;
9326 }
9327 // Remember we shouldn't complete measurement for this fiber.
9328 // Otherwise flamechart will be deep even for small updates.
9329 fiber._debugIsCurrentlyTiming = false;
9330 clearFiberMark(fiber, null);
9331 }
9332}
9333
9334function stopWorkTimer(fiber) {
9335 if (enableUserTimingAPI) {
9336 if (!supportsUserTiming || shouldIgnoreFiber(fiber)) {
9337 return;
9338 }
9339 // If we pause, its parent is the fiber to unwind from.
9340 currentFiber = fiber.return;
9341 if (!fiber._debugIsCurrentlyTiming) {
9342 return;
9343 }
9344 fiber._debugIsCurrentlyTiming = false;
9345 endFiberMark(fiber, null, null);
9346 }
9347}
9348
9349function stopFailedWorkTimer(fiber) {
9350 if (enableUserTimingAPI) {
9351 if (!supportsUserTiming || shouldIgnoreFiber(fiber)) {
9352 return;
9353 }
9354 // If we pause, its parent is the fiber to unwind from.
9355 currentFiber = fiber.return;
9356 if (!fiber._debugIsCurrentlyTiming) {
9357 return;
9358 }
9359 fiber._debugIsCurrentlyTiming = false;
9360 var warning = fiber.tag === SuspenseComponent || fiber.tag === DehydratedSuspenseComponent ? 'Rendering was suspended' : 'An error was thrown inside this error boundary';
9361 endFiberMark(fiber, null, warning);
9362 }
9363}
9364
9365function startPhaseTimer(fiber, phase) {
9366 if (enableUserTimingAPI) {
9367 if (!supportsUserTiming) {
9368 return;
9369 }
9370 clearPendingPhaseMeasurement();
9371 if (!beginFiberMark(fiber, phase)) {
9372 return;
9373 }
9374 currentPhaseFiber = fiber;
9375 currentPhase = phase;
9376 }
9377}
9378
9379function stopPhaseTimer() {
9380 if (enableUserTimingAPI) {
9381 if (!supportsUserTiming) {
9382 return;
9383 }
9384 if (currentPhase !== null && currentPhaseFiber !== null) {
9385 var warning = hasScheduledUpdateInCurrentPhase ? 'Scheduled a cascading update' : null;
9386 endFiberMark(currentPhaseFiber, currentPhase, warning);
9387 }
9388 currentPhase = null;
9389 currentPhaseFiber = null;
9390 }
9391}
9392
9393function startWorkLoopTimer(nextUnitOfWork) {
9394 if (enableUserTimingAPI) {
9395 currentFiber = nextUnitOfWork;
9396 if (!supportsUserTiming) {
9397 return;
9398 }
9399 commitCountInCurrentWorkLoop = 0;
9400 // This is top level call.
9401 // Any other measurements are performed within.
9402 beginMark('(React Tree Reconciliation)');
9403 // Resume any measurements that were in progress during the last loop.
9404 resumeTimers();
9405 }
9406}
9407
9408function stopWorkLoopTimer(interruptedBy, didCompleteRoot) {
9409 if (enableUserTimingAPI) {
9410 if (!supportsUserTiming) {
9411 return;
9412 }
9413 var warning = null;
9414 if (interruptedBy !== null) {
9415 if (interruptedBy.tag === HostRoot) {
9416 warning = 'A top-level update interrupted the previous render';
9417 } else {
9418 var componentName = getComponentName(interruptedBy.type) || 'Unknown';
9419 warning = 'An update to ' + componentName + ' interrupted the previous render';
9420 }
9421 } else if (commitCountInCurrentWorkLoop > 1) {
9422 warning = 'There were cascading updates';
9423 }
9424 commitCountInCurrentWorkLoop = 0;
9425 var label = didCompleteRoot ? '(React Tree Reconciliation: Completed Root)' : '(React Tree Reconciliation: Yielded)';
9426 // Pause any measurements until the next loop.
9427 pauseTimers();
9428 endMark(label, '(React Tree Reconciliation)', warning);
9429 }
9430}
9431
9432function startCommitTimer() {
9433 if (enableUserTimingAPI) {
9434 if (!supportsUserTiming) {
9435 return;
9436 }
9437 isCommitting = true;
9438 hasScheduledUpdateInCurrentCommit = false;
9439 labelsInCurrentCommit.clear();
9440 beginMark('(Committing Changes)');
9441 }
9442}
9443
9444function stopCommitTimer() {
9445 if (enableUserTimingAPI) {
9446 if (!supportsUserTiming) {
9447 return;
9448 }
9449
9450 var warning = null;
9451 if (hasScheduledUpdateInCurrentCommit) {
9452 warning = 'Lifecycle hook scheduled a cascading update';
9453 } else if (commitCountInCurrentWorkLoop > 0) {
9454 warning = 'Caused by a cascading update in earlier commit';
9455 }
9456 hasScheduledUpdateInCurrentCommit = false;
9457 commitCountInCurrentWorkLoop++;
9458 isCommitting = false;
9459 labelsInCurrentCommit.clear();
9460
9461 endMark('(Committing Changes)', '(Committing Changes)', warning);
9462 }
9463}
9464
9465function startCommitSnapshotEffectsTimer() {
9466 if (enableUserTimingAPI) {
9467 if (!supportsUserTiming) {
9468 return;
9469 }
9470 effectCountInCurrentCommit = 0;
9471 beginMark('(Committing Snapshot Effects)');
9472 }
9473}
9474
9475function stopCommitSnapshotEffectsTimer() {
9476 if (enableUserTimingAPI) {
9477 if (!supportsUserTiming) {
9478 return;
9479 }
9480 var count = effectCountInCurrentCommit;
9481 effectCountInCurrentCommit = 0;
9482 endMark('(Committing Snapshot Effects: ' + count + ' Total)', '(Committing Snapshot Effects)', null);
9483 }
9484}
9485
9486function startCommitHostEffectsTimer() {
9487 if (enableUserTimingAPI) {
9488 if (!supportsUserTiming) {
9489 return;
9490 }
9491 effectCountInCurrentCommit = 0;
9492 beginMark('(Committing Host Effects)');
9493 }
9494}
9495
9496function stopCommitHostEffectsTimer() {
9497 if (enableUserTimingAPI) {
9498 if (!supportsUserTiming) {
9499 return;
9500 }
9501 var count = effectCountInCurrentCommit;
9502 effectCountInCurrentCommit = 0;
9503 endMark('(Committing Host Effects: ' + count + ' Total)', '(Committing Host Effects)', null);
9504 }
9505}
9506
9507function startCommitLifeCyclesTimer() {
9508 if (enableUserTimingAPI) {
9509 if (!supportsUserTiming) {
9510 return;
9511 }
9512 effectCountInCurrentCommit = 0;
9513 beginMark('(Calling Lifecycle Methods)');
9514 }
9515}
9516
9517function stopCommitLifeCyclesTimer() {
9518 if (enableUserTimingAPI) {
9519 if (!supportsUserTiming) {
9520 return;
9521 }
9522 var count = effectCountInCurrentCommit;
9523 effectCountInCurrentCommit = 0;
9524 endMark('(Calling Lifecycle Methods: ' + count + ' Total)', '(Calling Lifecycle Methods)', null);
9525 }
9526}
9527
9528var valueStack = [];
9529
9530var fiberStack = void 0;
9531
9532{
9533 fiberStack = [];
9534}
9535
9536var index = -1;
9537
9538function createCursor(defaultValue) {
9539 return {
9540 current: defaultValue
9541 };
9542}
9543
9544function pop(cursor, fiber) {
9545 if (index < 0) {
9546 {
9547 warningWithoutStack$1(false, 'Unexpected pop.');
9548 }
9549 return;
9550 }
9551
9552 {
9553 if (fiber !== fiberStack[index]) {
9554 warningWithoutStack$1(false, 'Unexpected Fiber popped.');
9555 }
9556 }
9557
9558 cursor.current = valueStack[index];
9559
9560 valueStack[index] = null;
9561
9562 {
9563 fiberStack[index] = null;
9564 }
9565
9566 index--;
9567}
9568
9569function push(cursor, value, fiber) {
9570 index++;
9571
9572 valueStack[index] = cursor.current;
9573
9574 {
9575 fiberStack[index] = fiber;
9576 }
9577
9578 cursor.current = value;
9579}
9580
9581function checkThatStackIsEmpty() {
9582 {
9583 if (index !== -1) {
9584 warningWithoutStack$1(false, 'Expected an empty stack. Something was not reset properly.');
9585 }
9586 }
9587}
9588
9589function resetStackAfterFatalErrorInDev() {
9590 {
9591 index = -1;
9592 valueStack.length = 0;
9593 fiberStack.length = 0;
9594 }
9595}
9596
9597var warnedAboutMissingGetChildContext = void 0;
9598
9599{
9600 warnedAboutMissingGetChildContext = {};
9601}
9602
9603var emptyContextObject = {};
9604{
9605 Object.freeze(emptyContextObject);
9606}
9607
9608// A cursor to the current merged context object on the stack.
9609var contextStackCursor = createCursor(emptyContextObject);
9610// A cursor to a boolean indicating whether the context has changed.
9611var didPerformWorkStackCursor = createCursor(false);
9612// Keep track of the previous context object that was on the stack.
9613// We use this to get access to the parent context after we have already
9614// pushed the next context provider, and now need to merge their contexts.
9615var previousContext = emptyContextObject;
9616
9617function getUnmaskedContext(workInProgress, Component, didPushOwnContextIfProvider) {
9618 if (didPushOwnContextIfProvider && isContextProvider(Component)) {
9619 // If the fiber is a context provider itself, when we read its context
9620 // we may have already pushed its own child context on the stack. A context
9621 // provider should not "see" its own child context. Therefore we read the
9622 // previous (parent) context instead for a context provider.
9623 return previousContext;
9624 }
9625 return contextStackCursor.current;
9626}
9627
9628function cacheContext(workInProgress, unmaskedContext, maskedContext) {
9629 var instance = workInProgress.stateNode;
9630 instance.__reactInternalMemoizedUnmaskedChildContext = unmaskedContext;
9631 instance.__reactInternalMemoizedMaskedChildContext = maskedContext;
9632}
9633
9634function getMaskedContext(workInProgress, unmaskedContext) {
9635 var type = workInProgress.type;
9636 var contextTypes = type.contextTypes;
9637 if (!contextTypes) {
9638 return emptyContextObject;
9639 }
9640
9641 // Avoid recreating masked context unless unmasked context has changed.
9642 // Failing to do this will result in unnecessary calls to componentWillReceiveProps.
9643 // This may trigger infinite loops if componentWillReceiveProps calls setState.
9644 var instance = workInProgress.stateNode;
9645 if (instance && instance.__reactInternalMemoizedUnmaskedChildContext === unmaskedContext) {
9646 return instance.__reactInternalMemoizedMaskedChildContext;
9647 }
9648
9649 var context = {};
9650 for (var key in contextTypes) {
9651 context[key] = unmaskedContext[key];
9652 }
9653
9654 {
9655 var name = getComponentName(type) || 'Unknown';
9656 checkPropTypes(contextTypes, context, 'context', name, getCurrentFiberStackInDev);
9657 }
9658
9659 // Cache unmasked context so we can avoid recreating masked context unless necessary.
9660 // Context is created before the class component is instantiated so check for instance.
9661 if (instance) {
9662 cacheContext(workInProgress, unmaskedContext, context);
9663 }
9664
9665 return context;
9666}
9667
9668function hasContextChanged() {
9669 return didPerformWorkStackCursor.current;
9670}
9671
9672function isContextProvider(type) {
9673 var childContextTypes = type.childContextTypes;
9674 return childContextTypes !== null && childContextTypes !== undefined;
9675}
9676
9677function popContext(fiber) {
9678 pop(didPerformWorkStackCursor, fiber);
9679 pop(contextStackCursor, fiber);
9680}
9681
9682function popTopLevelContextObject(fiber) {
9683 pop(didPerformWorkStackCursor, fiber);
9684 pop(contextStackCursor, fiber);
9685}
9686
9687function pushTopLevelContextObject(fiber, context, didChange) {
9688 !(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;
9689
9690 push(contextStackCursor, context, fiber);
9691 push(didPerformWorkStackCursor, didChange, fiber);
9692}
9693
9694function processChildContext(fiber, type, parentContext) {
9695 var instance = fiber.stateNode;
9696 var childContextTypes = type.childContextTypes;
9697
9698 // TODO (bvaughn) Replace this behavior with an invariant() in the future.
9699 // It has only been added in Fiber to match the (unintentional) behavior in Stack.
9700 if (typeof instance.getChildContext !== 'function') {
9701 {
9702 var componentName = getComponentName(type) || 'Unknown';
9703
9704 if (!warnedAboutMissingGetChildContext[componentName]) {
9705 warnedAboutMissingGetChildContext[componentName] = true;
9706 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);
9707 }
9708 }
9709 return parentContext;
9710 }
9711
9712 var childContext = void 0;
9713 {
9714 setCurrentPhase('getChildContext');
9715 }
9716 startPhaseTimer(fiber, 'getChildContext');
9717 childContext = instance.getChildContext();
9718 stopPhaseTimer();
9719 {
9720 setCurrentPhase(null);
9721 }
9722 for (var contextKey in childContext) {
9723 !(contextKey in childContextTypes) ? invariant(false, '%s.getChildContext(): key "%s" is not defined in childContextTypes.', getComponentName(type) || 'Unknown', contextKey) : void 0;
9724 }
9725 {
9726 var name = getComponentName(type) || 'Unknown';
9727 checkPropTypes(childContextTypes, childContext, 'child context', name,
9728 // In practice, there is one case in which we won't get a stack. It's when
9729 // somebody calls unstable_renderSubtreeIntoContainer() and we process
9730 // context from the parent component instance. The stack will be missing
9731 // because it's outside of the reconciliation, and so the pointer has not
9732 // been set. This is rare and doesn't matter. We'll also remove that API.
9733 getCurrentFiberStackInDev);
9734 }
9735
9736 return _assign({}, parentContext, childContext);
9737}
9738
9739function pushContextProvider(workInProgress) {
9740 var instance = workInProgress.stateNode;
9741 // We push the context as early as possible to ensure stack integrity.
9742 // If the instance does not exist yet, we will push null at first,
9743 // and replace it on the stack later when invalidating the context.
9744 var memoizedMergedChildContext = instance && instance.__reactInternalMemoizedMergedChildContext || emptyContextObject;
9745
9746 // Remember the parent context so we can merge with it later.
9747 // Inherit the parent's did-perform-work value to avoid inadvertently blocking updates.
9748 previousContext = contextStackCursor.current;
9749 push(contextStackCursor, memoizedMergedChildContext, workInProgress);
9750 push(didPerformWorkStackCursor, didPerformWorkStackCursor.current, workInProgress);
9751
9752 return true;
9753}
9754
9755function invalidateContextProvider(workInProgress, type, didChange) {
9756 var instance = workInProgress.stateNode;
9757 !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;
9758
9759 if (didChange) {
9760 // Merge parent and own context.
9761 // Skip this if we're not updating due to sCU.
9762 // This avoids unnecessarily recomputing memoized values.
9763 var mergedContext = processChildContext(workInProgress, type, previousContext);
9764 instance.__reactInternalMemoizedMergedChildContext = mergedContext;
9765
9766 // Replace the old (or empty) context with the new one.
9767 // It is important to unwind the context in the reverse order.
9768 pop(didPerformWorkStackCursor, workInProgress);
9769 pop(contextStackCursor, workInProgress);
9770 // Now push the new context and mark that it has changed.
9771 push(contextStackCursor, mergedContext, workInProgress);
9772 push(didPerformWorkStackCursor, didChange, workInProgress);
9773 } else {
9774 pop(didPerformWorkStackCursor, workInProgress);
9775 push(didPerformWorkStackCursor, didChange, workInProgress);
9776 }
9777}
9778
9779function findCurrentUnmaskedContext(fiber) {
9780 // Currently this is only used with renderSubtreeIntoContainer; not sure if it
9781 // makes sense elsewhere
9782 !(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;
9783
9784 var node = fiber;
9785 do {
9786 switch (node.tag) {
9787 case HostRoot:
9788 return node.stateNode.context;
9789 case ClassComponent:
9790 {
9791 var Component = node.type;
9792 if (isContextProvider(Component)) {
9793 return node.stateNode.__reactInternalMemoizedMergedChildContext;
9794 }
9795 break;
9796 }
9797 }
9798 node = node.return;
9799 } while (node !== null);
9800 invariant(false, 'Found unexpected detached subtree parent. This error is likely caused by a bug in React. Please file an issue.');
9801}
9802
9803var onCommitFiberRoot = null;
9804var onCommitFiberUnmount = null;
9805var hasLoggedError = false;
9806
9807function catchErrors(fn) {
9808 return function (arg) {
9809 try {
9810 return fn(arg);
9811 } catch (err) {
9812 if (true && !hasLoggedError) {
9813 hasLoggedError = true;
9814 warningWithoutStack$1(false, 'React DevTools encountered an error: %s', err);
9815 }
9816 }
9817 };
9818}
9819
9820var isDevToolsPresent = typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ !== 'undefined';
9821
9822function injectInternals(internals) {
9823 if (typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ === 'undefined') {
9824 // No DevTools
9825 return false;
9826 }
9827 var hook = __REACT_DEVTOOLS_GLOBAL_HOOK__;
9828 if (hook.isDisabled) {
9829 // This isn't a real property on the hook, but it can be set to opt out
9830 // of DevTools integration and associated warnings and logs.
9831 // https://github.com/facebook/react/issues/3877
9832 return true;
9833 }
9834 if (!hook.supportsFiber) {
9835 {
9836 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');
9837 }
9838 // DevTools exists, even though it doesn't support Fiber.
9839 return true;
9840 }
9841 try {
9842 var rendererID = hook.inject(internals);
9843 // We have successfully injected, so now it is safe to set up hooks.
9844 onCommitFiberRoot = catchErrors(function (root) {
9845 return hook.onCommitFiberRoot(rendererID, root);
9846 });
9847 onCommitFiberUnmount = catchErrors(function (fiber) {
9848 return hook.onCommitFiberUnmount(rendererID, fiber);
9849 });
9850 } catch (err) {
9851 // Catch all errors because it is unsafe to throw during initialization.
9852 {
9853 warningWithoutStack$1(false, 'React DevTools encountered an error: %s.', err);
9854 }
9855 }
9856 // DevTools exists
9857 return true;
9858}
9859
9860function onCommitRoot(root) {
9861 if (typeof onCommitFiberRoot === 'function') {
9862 onCommitFiberRoot(root);
9863 }
9864}
9865
9866function onCommitUnmount(fiber) {
9867 if (typeof onCommitFiberUnmount === 'function') {
9868 onCommitFiberUnmount(fiber);
9869 }
9870}
9871
9872// Max 31 bit integer. The max integer size in V8 for 32-bit systems.
9873// Math.pow(2, 30) - 1
9874// 0b111111111111111111111111111111
9875var maxSigned31BitInt = 1073741823;
9876
9877var NoWork = 0;
9878var Never = 1;
9879var Sync = maxSigned31BitInt;
9880
9881var UNIT_SIZE = 10;
9882var MAGIC_NUMBER_OFFSET = maxSigned31BitInt - 1;
9883
9884// 1 unit of expiration time represents 10ms.
9885function msToExpirationTime(ms) {
9886 // Always add an offset so that we don't clash with the magic number for NoWork.
9887 return MAGIC_NUMBER_OFFSET - (ms / UNIT_SIZE | 0);
9888}
9889
9890function expirationTimeToMs(expirationTime) {
9891 return (MAGIC_NUMBER_OFFSET - expirationTime) * UNIT_SIZE;
9892}
9893
9894function ceiling(num, precision) {
9895 return ((num / precision | 0) + 1) * precision;
9896}
9897
9898function computeExpirationBucket(currentTime, expirationInMs, bucketSizeMs) {
9899 return MAGIC_NUMBER_OFFSET - ceiling(MAGIC_NUMBER_OFFSET - currentTime + expirationInMs / UNIT_SIZE, bucketSizeMs / UNIT_SIZE);
9900}
9901
9902var LOW_PRIORITY_EXPIRATION = 5000;
9903var LOW_PRIORITY_BATCH_SIZE = 250;
9904
9905function computeAsyncExpiration(currentTime) {
9906 return computeExpirationBucket(currentTime, LOW_PRIORITY_EXPIRATION, LOW_PRIORITY_BATCH_SIZE);
9907}
9908
9909// We intentionally set a higher expiration time for interactive updates in
9910// dev than in production.
9911//
9912// If the main thread is being blocked so long that you hit the expiration,
9913// it's a problem that could be solved with better scheduling.
9914//
9915// People will be more likely to notice this and fix it with the long
9916// expiration time in development.
9917//
9918// In production we opt for better UX at the risk of masking scheduling
9919// problems, by expiring fast.
9920var HIGH_PRIORITY_EXPIRATION = 500;
9921var HIGH_PRIORITY_BATCH_SIZE = 100;
9922
9923function computeInteractiveExpiration(currentTime) {
9924 return computeExpirationBucket(currentTime, HIGH_PRIORITY_EXPIRATION, HIGH_PRIORITY_BATCH_SIZE);
9925}
9926
9927var NoContext = 0;
9928var ConcurrentMode = 1;
9929var StrictMode = 2;
9930var ProfileMode = 4;
9931
9932var hasBadMapPolyfill = void 0;
9933
9934{
9935 hasBadMapPolyfill = false;
9936 try {
9937 var nonExtensibleObject = Object.preventExtensions({});
9938 var testMap = new Map([[nonExtensibleObject, null]]);
9939 var testSet = new Set([nonExtensibleObject]);
9940 // This is necessary for Rollup to not consider these unused.
9941 // https://github.com/rollup/rollup/issues/1771
9942 // TODO: we can remove these if Rollup fixes the bug.
9943 testMap.set(0, 0);
9944 testSet.add(0);
9945 } catch (e) {
9946 // TODO: Consider warning about bad polyfills
9947 hasBadMapPolyfill = true;
9948 }
9949}
9950
9951// A Fiber is work on a Component that needs to be done or was done. There can
9952// be more than one per component.
9953
9954
9955var debugCounter = void 0;
9956
9957{
9958 debugCounter = 1;
9959}
9960
9961function FiberNode(tag, pendingProps, key, mode) {
9962 // Instance
9963 this.tag = tag;
9964 this.key = key;
9965 this.elementType = null;
9966 this.type = null;
9967 this.stateNode = null;
9968
9969 // Fiber
9970 this.return = null;
9971 this.child = null;
9972 this.sibling = null;
9973 this.index = 0;
9974
9975 this.ref = null;
9976
9977 this.pendingProps = pendingProps;
9978 this.memoizedProps = null;
9979 this.updateQueue = null;
9980 this.memoizedState = null;
9981 this.contextDependencies = null;
9982
9983 this.mode = mode;
9984
9985 // Effects
9986 this.effectTag = NoEffect;
9987 this.nextEffect = null;
9988
9989 this.firstEffect = null;
9990 this.lastEffect = null;
9991
9992 this.expirationTime = NoWork;
9993 this.childExpirationTime = NoWork;
9994
9995 this.alternate = null;
9996
9997 if (enableProfilerTimer) {
9998 // Note: The following is done to avoid a v8 performance cliff.
9999 //
10000 // Initializing the fields below to smis and later updating them with
10001 // double values will cause Fibers to end up having separate shapes.
10002 // This behavior/bug has something to do with Object.preventExtension().
10003 // Fortunately this only impacts DEV builds.
10004 // Unfortunately it makes React unusably slow for some applications.
10005 // To work around this, initialize the fields below with doubles.
10006 //
10007 // Learn more about this here:
10008 // https://github.com/facebook/react/issues/14365
10009 // https://bugs.chromium.org/p/v8/issues/detail?id=8538
10010 this.actualDuration = Number.NaN;
10011 this.actualStartTime = Number.NaN;
10012 this.selfBaseDuration = Number.NaN;
10013 this.treeBaseDuration = Number.NaN;
10014
10015 // It's okay to replace the initial doubles with smis after initialization.
10016 // This won't trigger the performance cliff mentioned above,
10017 // and it simplifies other profiler code (including DevTools).
10018 this.actualDuration = 0;
10019 this.actualStartTime = -1;
10020 this.selfBaseDuration = 0;
10021 this.treeBaseDuration = 0;
10022 }
10023
10024 {
10025 this._debugID = debugCounter++;
10026 this._debugSource = null;
10027 this._debugOwner = null;
10028 this._debugIsCurrentlyTiming = false;
10029 this._debugHookTypes = null;
10030 if (!hasBadMapPolyfill && typeof Object.preventExtensions === 'function') {
10031 Object.preventExtensions(this);
10032 }
10033 }
10034}
10035
10036// This is a constructor function, rather than a POJO constructor, still
10037// please ensure we do the following:
10038// 1) Nobody should add any instance methods on this. Instance methods can be
10039// more difficult to predict when they get optimized and they are almost
10040// never inlined properly in static compilers.
10041// 2) Nobody should rely on `instanceof Fiber` for type testing. We should
10042// always know when it is a fiber.
10043// 3) We might want to experiment with using numeric keys since they are easier
10044// to optimize in a non-JIT environment.
10045// 4) We can easily go from a constructor to a createFiber object literal if that
10046// is faster.
10047// 5) It should be easy to port this to a C struct and keep a C implementation
10048// compatible.
10049var createFiber = function (tag, pendingProps, key, mode) {
10050 // $FlowFixMe: the shapes are exact here but Flow doesn't like constructors
10051 return new FiberNode(tag, pendingProps, key, mode);
10052};
10053
10054function shouldConstruct(Component) {
10055 var prototype = Component.prototype;
10056 return !!(prototype && prototype.isReactComponent);
10057}
10058
10059function isSimpleFunctionComponent(type) {
10060 return typeof type === 'function' && !shouldConstruct(type) && type.defaultProps === undefined;
10061}
10062
10063function resolveLazyComponentTag(Component) {
10064 if (typeof Component === 'function') {
10065 return shouldConstruct(Component) ? ClassComponent : FunctionComponent;
10066 } else if (Component !== undefined && Component !== null) {
10067 var $$typeof = Component.$$typeof;
10068 if ($$typeof === REACT_FORWARD_REF_TYPE) {
10069 return ForwardRef;
10070 }
10071 if ($$typeof === REACT_MEMO_TYPE) {
10072 return MemoComponent;
10073 }
10074 }
10075 return IndeterminateComponent;
10076}
10077
10078// This is used to create an alternate fiber to do work on.
10079function createWorkInProgress(current, pendingProps, expirationTime) {
10080 var workInProgress = current.alternate;
10081 if (workInProgress === null) {
10082 // We use a double buffering pooling technique because we know that we'll
10083 // only ever need at most two versions of a tree. We pool the "other" unused
10084 // node that we're free to reuse. This is lazily created to avoid allocating
10085 // extra objects for things that are never updated. It also allow us to
10086 // reclaim the extra memory if needed.
10087 workInProgress = createFiber(current.tag, pendingProps, current.key, current.mode);
10088 workInProgress.elementType = current.elementType;
10089 workInProgress.type = current.type;
10090 workInProgress.stateNode = current.stateNode;
10091
10092 {
10093 // DEV-only fields
10094 workInProgress._debugID = current._debugID;
10095 workInProgress._debugSource = current._debugSource;
10096 workInProgress._debugOwner = current._debugOwner;
10097 workInProgress._debugHookTypes = current._debugHookTypes;
10098 }
10099
10100 workInProgress.alternate = current;
10101 current.alternate = workInProgress;
10102 } else {
10103 workInProgress.pendingProps = pendingProps;
10104
10105 // We already have an alternate.
10106 // Reset the effect tag.
10107 workInProgress.effectTag = NoEffect;
10108
10109 // The effect list is no longer valid.
10110 workInProgress.nextEffect = null;
10111 workInProgress.firstEffect = null;
10112 workInProgress.lastEffect = null;
10113
10114 if (enableProfilerTimer) {
10115 // We intentionally reset, rather than copy, actualDuration & actualStartTime.
10116 // This prevents time from endlessly accumulating in new commits.
10117 // This has the downside of resetting values for different priority renders,
10118 // But works for yielding (the common case) and should support resuming.
10119 workInProgress.actualDuration = 0;
10120 workInProgress.actualStartTime = -1;
10121 }
10122 }
10123
10124 workInProgress.childExpirationTime = current.childExpirationTime;
10125 workInProgress.expirationTime = current.expirationTime;
10126
10127 workInProgress.child = current.child;
10128 workInProgress.memoizedProps = current.memoizedProps;
10129 workInProgress.memoizedState = current.memoizedState;
10130 workInProgress.updateQueue = current.updateQueue;
10131 workInProgress.contextDependencies = current.contextDependencies;
10132
10133 // These will be overridden during the parent's reconciliation
10134 workInProgress.sibling = current.sibling;
10135 workInProgress.index = current.index;
10136 workInProgress.ref = current.ref;
10137
10138 if (enableProfilerTimer) {
10139 workInProgress.selfBaseDuration = current.selfBaseDuration;
10140 workInProgress.treeBaseDuration = current.treeBaseDuration;
10141 }
10142
10143 return workInProgress;
10144}
10145
10146function createHostRootFiber(isConcurrent) {
10147 var mode = isConcurrent ? ConcurrentMode | StrictMode : NoContext;
10148
10149 if (enableProfilerTimer && isDevToolsPresent) {
10150 // Always collect profile timings when DevTools are present.
10151 // This enables DevTools to start capturing timing at any point–
10152 // Without some nodes in the tree having empty base times.
10153 mode |= ProfileMode;
10154 }
10155
10156 return createFiber(HostRoot, null, null, mode);
10157}
10158
10159function createFiberFromTypeAndProps(type, // React$ElementType
10160key, pendingProps, owner, mode, expirationTime) {
10161 var fiber = void 0;
10162
10163 var fiberTag = IndeterminateComponent;
10164 // The resolved type is set if we know what the final type will be. I.e. it's not lazy.
10165 var resolvedType = type;
10166 if (typeof type === 'function') {
10167 if (shouldConstruct(type)) {
10168 fiberTag = ClassComponent;
10169 }
10170 } else if (typeof type === 'string') {
10171 fiberTag = HostComponent;
10172 } else {
10173 getTag: switch (type) {
10174 case REACT_FRAGMENT_TYPE:
10175 return createFiberFromFragment(pendingProps.children, mode, expirationTime, key);
10176 case REACT_CONCURRENT_MODE_TYPE:
10177 return createFiberFromMode(pendingProps, mode | ConcurrentMode | StrictMode, expirationTime, key);
10178 case REACT_STRICT_MODE_TYPE:
10179 return createFiberFromMode(pendingProps, mode | StrictMode, expirationTime, key);
10180 case REACT_PROFILER_TYPE:
10181 return createFiberFromProfiler(pendingProps, mode, expirationTime, key);
10182 case REACT_SUSPENSE_TYPE:
10183 return createFiberFromSuspense(pendingProps, mode, expirationTime, key);
10184 default:
10185 {
10186 if (typeof type === 'object' && type !== null) {
10187 switch (type.$$typeof) {
10188 case REACT_PROVIDER_TYPE:
10189 fiberTag = ContextProvider;
10190 break getTag;
10191 case REACT_CONTEXT_TYPE:
10192 // This is a consumer
10193 fiberTag = ContextConsumer;
10194 break getTag;
10195 case REACT_FORWARD_REF_TYPE:
10196 fiberTag = ForwardRef;
10197 break getTag;
10198 case REACT_MEMO_TYPE:
10199 fiberTag = MemoComponent;
10200 break getTag;
10201 case REACT_LAZY_TYPE:
10202 fiberTag = LazyComponent;
10203 resolvedType = null;
10204 break getTag;
10205 }
10206 }
10207 var info = '';
10208 {
10209 if (type === undefined || typeof type === 'object' && type !== null && Object.keys(type).length === 0) {
10210 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.';
10211 }
10212 var ownerName = owner ? getComponentName(owner.type) : null;
10213 if (ownerName) {
10214 info += '\n\nCheck the render method of `' + ownerName + '`.';
10215 }
10216 }
10217 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);
10218 }
10219 }
10220 }
10221
10222 fiber = createFiber(fiberTag, pendingProps, key, mode);
10223 fiber.elementType = type;
10224 fiber.type = resolvedType;
10225 fiber.expirationTime = expirationTime;
10226
10227 return fiber;
10228}
10229
10230function createFiberFromElement(element, mode, expirationTime) {
10231 var owner = null;
10232 {
10233 owner = element._owner;
10234 }
10235 var type = element.type;
10236 var key = element.key;
10237 var pendingProps = element.props;
10238 var fiber = createFiberFromTypeAndProps(type, key, pendingProps, owner, mode, expirationTime);
10239 {
10240 fiber._debugSource = element._source;
10241 fiber._debugOwner = element._owner;
10242 }
10243 return fiber;
10244}
10245
10246function createFiberFromFragment(elements, mode, expirationTime, key) {
10247 var fiber = createFiber(Fragment, elements, key, mode);
10248 fiber.expirationTime = expirationTime;
10249 return fiber;
10250}
10251
10252function createFiberFromProfiler(pendingProps, mode, expirationTime, key) {
10253 {
10254 if (typeof pendingProps.id !== 'string' || typeof pendingProps.onRender !== 'function') {
10255 warningWithoutStack$1(false, 'Profiler must specify an "id" string and "onRender" function as props');
10256 }
10257 }
10258
10259 var fiber = createFiber(Profiler, pendingProps, key, mode | ProfileMode);
10260 // TODO: The Profiler fiber shouldn't have a type. It has a tag.
10261 fiber.elementType = REACT_PROFILER_TYPE;
10262 fiber.type = REACT_PROFILER_TYPE;
10263 fiber.expirationTime = expirationTime;
10264
10265 return fiber;
10266}
10267
10268function createFiberFromMode(pendingProps, mode, expirationTime, key) {
10269 var fiber = createFiber(Mode, pendingProps, key, mode);
10270
10271 // TODO: The Mode fiber shouldn't have a type. It has a tag.
10272 var type = (mode & ConcurrentMode) === NoContext ? REACT_STRICT_MODE_TYPE : REACT_CONCURRENT_MODE_TYPE;
10273 fiber.elementType = type;
10274 fiber.type = type;
10275
10276 fiber.expirationTime = expirationTime;
10277 return fiber;
10278}
10279
10280function createFiberFromSuspense(pendingProps, mode, expirationTime, key) {
10281 var fiber = createFiber(SuspenseComponent, pendingProps, key, mode);
10282
10283 // TODO: The SuspenseComponent fiber shouldn't have a type. It has a tag.
10284 var type = REACT_SUSPENSE_TYPE;
10285 fiber.elementType = type;
10286 fiber.type = type;
10287
10288 fiber.expirationTime = expirationTime;
10289 return fiber;
10290}
10291
10292function createFiberFromText(content, mode, expirationTime) {
10293 var fiber = createFiber(HostText, content, null, mode);
10294 fiber.expirationTime = expirationTime;
10295 return fiber;
10296}
10297
10298function createFiberFromHostInstanceForDeletion() {
10299 var fiber = createFiber(HostComponent, null, null, NoContext);
10300 // TODO: These should not need a type.
10301 fiber.elementType = 'DELETED';
10302 fiber.type = 'DELETED';
10303 return fiber;
10304}
10305
10306function createFiberFromPortal(portal, mode, expirationTime) {
10307 var pendingProps = portal.children !== null ? portal.children : [];
10308 var fiber = createFiber(HostPortal, pendingProps, portal.key, mode);
10309 fiber.expirationTime = expirationTime;
10310 fiber.stateNode = {
10311 containerInfo: portal.containerInfo,
10312 pendingChildren: null, // Used by persistent updates
10313 implementation: portal.implementation
10314 };
10315 return fiber;
10316}
10317
10318// Used for stashing WIP properties to replay failed work in DEV.
10319function assignFiberPropertiesInDEV(target, source) {
10320 if (target === null) {
10321 // This Fiber's initial properties will always be overwritten.
10322 // We only use a Fiber to ensure the same hidden class so DEV isn't slow.
10323 target = createFiber(IndeterminateComponent, null, null, NoContext);
10324 }
10325
10326 // This is intentionally written as a list of all properties.
10327 // We tried to use Object.assign() instead but this is called in
10328 // the hottest path, and Object.assign() was too slow:
10329 // https://github.com/facebook/react/issues/12502
10330 // This code is DEV-only so size is not a concern.
10331
10332 target.tag = source.tag;
10333 target.key = source.key;
10334 target.elementType = source.elementType;
10335 target.type = source.type;
10336 target.stateNode = source.stateNode;
10337 target.return = source.return;
10338 target.child = source.child;
10339 target.sibling = source.sibling;
10340 target.index = source.index;
10341 target.ref = source.ref;
10342 target.pendingProps = source.pendingProps;
10343 target.memoizedProps = source.memoizedProps;
10344 target.updateQueue = source.updateQueue;
10345 target.memoizedState = source.memoizedState;
10346 target.contextDependencies = source.contextDependencies;
10347 target.mode = source.mode;
10348 target.effectTag = source.effectTag;
10349 target.nextEffect = source.nextEffect;
10350 target.firstEffect = source.firstEffect;
10351 target.lastEffect = source.lastEffect;
10352 target.expirationTime = source.expirationTime;
10353 target.childExpirationTime = source.childExpirationTime;
10354 target.alternate = source.alternate;
10355 if (enableProfilerTimer) {
10356 target.actualDuration = source.actualDuration;
10357 target.actualStartTime = source.actualStartTime;
10358 target.selfBaseDuration = source.selfBaseDuration;
10359 target.treeBaseDuration = source.treeBaseDuration;
10360 }
10361 target._debugID = source._debugID;
10362 target._debugSource = source._debugSource;
10363 target._debugOwner = source._debugOwner;
10364 target._debugIsCurrentlyTiming = source._debugIsCurrentlyTiming;
10365 target._debugHookTypes = source._debugHookTypes;
10366 return target;
10367}
10368
10369// TODO: This should be lifted into the renderer.
10370
10371
10372// The following attributes are only used by interaction tracing builds.
10373// They enable interactions to be associated with their async work,
10374// And expose interaction metadata to the React DevTools Profiler plugin.
10375// Note that these attributes are only defined when the enableSchedulerTracing flag is enabled.
10376
10377
10378// Exported FiberRoot type includes all properties,
10379// To avoid requiring potentially error-prone :any casts throughout the project.
10380// Profiling properties are only safe to access in profiling builds (when enableSchedulerTracing is true).
10381// The types are defined separately within this file to ensure they stay in sync.
10382// (We don't have to use an inline :any cast when enableSchedulerTracing is disabled.)
10383
10384
10385function createFiberRoot(containerInfo, isConcurrent, hydrate) {
10386 // Cyclic construction. This cheats the type system right now because
10387 // stateNode is any.
10388 var uninitializedFiber = createHostRootFiber(isConcurrent);
10389
10390 var root = void 0;
10391 if (enableSchedulerTracing) {
10392 root = {
10393 current: uninitializedFiber,
10394 containerInfo: containerInfo,
10395 pendingChildren: null,
10396
10397 earliestPendingTime: NoWork,
10398 latestPendingTime: NoWork,
10399 earliestSuspendedTime: NoWork,
10400 latestSuspendedTime: NoWork,
10401 latestPingedTime: NoWork,
10402
10403 pingCache: null,
10404
10405 didError: false,
10406
10407 pendingCommitExpirationTime: NoWork,
10408 finishedWork: null,
10409 timeoutHandle: noTimeout,
10410 context: null,
10411 pendingContext: null,
10412 hydrate: hydrate,
10413 nextExpirationTimeToWorkOn: NoWork,
10414 expirationTime: NoWork,
10415 firstBatch: null,
10416 nextScheduledRoot: null,
10417
10418 interactionThreadID: tracing.unstable_getThreadID(),
10419 memoizedInteractions: new Set(),
10420 pendingInteractionMap: new Map()
10421 };
10422 } else {
10423 root = {
10424 current: uninitializedFiber,
10425 containerInfo: containerInfo,
10426 pendingChildren: null,
10427
10428 pingCache: null,
10429
10430 earliestPendingTime: NoWork,
10431 latestPendingTime: NoWork,
10432 earliestSuspendedTime: NoWork,
10433 latestSuspendedTime: NoWork,
10434 latestPingedTime: NoWork,
10435
10436 didError: false,
10437
10438 pendingCommitExpirationTime: NoWork,
10439 finishedWork: null,
10440 timeoutHandle: noTimeout,
10441 context: null,
10442 pendingContext: null,
10443 hydrate: hydrate,
10444 nextExpirationTimeToWorkOn: NoWork,
10445 expirationTime: NoWork,
10446 firstBatch: null,
10447 nextScheduledRoot: null
10448 };
10449 }
10450
10451 uninitializedFiber.stateNode = root;
10452
10453 // The reason for the way the Flow types are structured in this file,
10454 // Is to avoid needing :any casts everywhere interaction tracing fields are used.
10455 // Unfortunately that requires an :any cast for non-interaction tracing capable builds.
10456 // $FlowFixMe Remove this :any cast and replace it with something better.
10457 return root;
10458}
10459
10460/**
10461 * Forked from fbjs/warning:
10462 * https://github.com/facebook/fbjs/blob/e66ba20ad5be433eb54423f2b097d829324d9de6/packages/fbjs/src/__forks__/warning.js
10463 *
10464 * Only change is we use console.warn instead of console.error,
10465 * and do nothing when 'console' is not supported.
10466 * This really simplifies the code.
10467 * ---
10468 * Similar to invariant but only logs a warning if the condition is not met.
10469 * This can be used to log issues in development environments in critical
10470 * paths. Removing the logging code for production environments will keep the
10471 * same logic and follow the same code paths.
10472 */
10473
10474var lowPriorityWarning = function () {};
10475
10476{
10477 var printWarning = function (format) {
10478 for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
10479 args[_key - 1] = arguments[_key];
10480 }
10481
10482 var argIndex = 0;
10483 var message = 'Warning: ' + format.replace(/%s/g, function () {
10484 return args[argIndex++];
10485 });
10486 if (typeof console !== 'undefined') {
10487 console.warn(message);
10488 }
10489 try {
10490 // --- Welcome to debugging React ---
10491 // This error was thrown as a convenience so that you can use this stack
10492 // to find the callsite that caused this warning to fire.
10493 throw new Error(message);
10494 } catch (x) {}
10495 };
10496
10497 lowPriorityWarning = function (condition, format) {
10498 if (format === undefined) {
10499 throw new Error('`lowPriorityWarning(condition, format, ...args)` requires a warning ' + 'message argument');
10500 }
10501 if (!condition) {
10502 for (var _len2 = arguments.length, args = Array(_len2 > 2 ? _len2 - 2 : 0), _key2 = 2; _key2 < _len2; _key2++) {
10503 args[_key2 - 2] = arguments[_key2];
10504 }
10505
10506 printWarning.apply(undefined, [format].concat(args));
10507 }
10508 };
10509}
10510
10511var lowPriorityWarning$1 = lowPriorityWarning;
10512
10513var ReactStrictModeWarnings = {
10514 discardPendingWarnings: function () {},
10515 flushPendingDeprecationWarnings: function () {},
10516 flushPendingUnsafeLifecycleWarnings: function () {},
10517 recordDeprecationWarnings: function (fiber, instance) {},
10518 recordUnsafeLifecycleWarnings: function (fiber, instance) {},
10519 recordLegacyContextWarning: function (fiber, instance) {},
10520 flushLegacyContextWarning: function () {}
10521};
10522
10523{
10524 var LIFECYCLE_SUGGESTIONS = {
10525 UNSAFE_componentWillMount: 'componentDidMount',
10526 UNSAFE_componentWillReceiveProps: 'static getDerivedStateFromProps',
10527 UNSAFE_componentWillUpdate: 'componentDidUpdate'
10528 };
10529
10530 var pendingComponentWillMountWarnings = [];
10531 var pendingComponentWillReceivePropsWarnings = [];
10532 var pendingComponentWillUpdateWarnings = [];
10533 var pendingUnsafeLifecycleWarnings = new Map();
10534 var pendingLegacyContextWarning = new Map();
10535
10536 // Tracks components we have already warned about.
10537 var didWarnAboutDeprecatedLifecycles = new Set();
10538 var didWarnAboutUnsafeLifecycles = new Set();
10539 var didWarnAboutLegacyContext = new Set();
10540
10541 var setToSortedString = function (set) {
10542 var array = [];
10543 set.forEach(function (value) {
10544 array.push(value);
10545 });
10546 return array.sort().join(', ');
10547 };
10548
10549 ReactStrictModeWarnings.discardPendingWarnings = function () {
10550 pendingComponentWillMountWarnings = [];
10551 pendingComponentWillReceivePropsWarnings = [];
10552 pendingComponentWillUpdateWarnings = [];
10553 pendingUnsafeLifecycleWarnings = new Map();
10554 pendingLegacyContextWarning = new Map();
10555 };
10556
10557 ReactStrictModeWarnings.flushPendingUnsafeLifecycleWarnings = function () {
10558 pendingUnsafeLifecycleWarnings.forEach(function (lifecycleWarningsMap, strictRoot) {
10559 var lifecyclesWarningMessages = [];
10560
10561 Object.keys(lifecycleWarningsMap).forEach(function (lifecycle) {
10562 var lifecycleWarnings = lifecycleWarningsMap[lifecycle];
10563 if (lifecycleWarnings.length > 0) {
10564 var componentNames = new Set();
10565 lifecycleWarnings.forEach(function (fiber) {
10566 componentNames.add(getComponentName(fiber.type) || 'Component');
10567 didWarnAboutUnsafeLifecycles.add(fiber.type);
10568 });
10569
10570 var formatted = lifecycle.replace('UNSAFE_', '');
10571 var suggestion = LIFECYCLE_SUGGESTIONS[lifecycle];
10572 var sortedComponentNames = setToSortedString(componentNames);
10573
10574 lifecyclesWarningMessages.push(formatted + ': Please update the following components to use ' + (suggestion + ' instead: ' + sortedComponentNames));
10575 }
10576 });
10577
10578 if (lifecyclesWarningMessages.length > 0) {
10579 var strictRootComponentStack = getStackByFiberInDevAndProd(strictRoot);
10580
10581 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'));
10582 }
10583 });
10584
10585 pendingUnsafeLifecycleWarnings = new Map();
10586 };
10587
10588 var findStrictRoot = function (fiber) {
10589 var maybeStrictRoot = null;
10590
10591 var node = fiber;
10592 while (node !== null) {
10593 if (node.mode & StrictMode) {
10594 maybeStrictRoot = node;
10595 }
10596 node = node.return;
10597 }
10598
10599 return maybeStrictRoot;
10600 };
10601
10602 ReactStrictModeWarnings.flushPendingDeprecationWarnings = function () {
10603 if (pendingComponentWillMountWarnings.length > 0) {
10604 var uniqueNames = new Set();
10605 pendingComponentWillMountWarnings.forEach(function (fiber) {
10606 uniqueNames.add(getComponentName(fiber.type) || 'Component');
10607 didWarnAboutDeprecatedLifecycles.add(fiber.type);
10608 });
10609
10610 var sortedNames = setToSortedString(uniqueNames);
10611
10612 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);
10613
10614 pendingComponentWillMountWarnings = [];
10615 }
10616
10617 if (pendingComponentWillReceivePropsWarnings.length > 0) {
10618 var _uniqueNames = new Set();
10619 pendingComponentWillReceivePropsWarnings.forEach(function (fiber) {
10620 _uniqueNames.add(getComponentName(fiber.type) || 'Component');
10621 didWarnAboutDeprecatedLifecycles.add(fiber.type);
10622 });
10623
10624 var _sortedNames = setToSortedString(_uniqueNames);
10625
10626 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);
10627
10628 pendingComponentWillReceivePropsWarnings = [];
10629 }
10630
10631 if (pendingComponentWillUpdateWarnings.length > 0) {
10632 var _uniqueNames2 = new Set();
10633 pendingComponentWillUpdateWarnings.forEach(function (fiber) {
10634 _uniqueNames2.add(getComponentName(fiber.type) || 'Component');
10635 didWarnAboutDeprecatedLifecycles.add(fiber.type);
10636 });
10637
10638 var _sortedNames2 = setToSortedString(_uniqueNames2);
10639
10640 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);
10641
10642 pendingComponentWillUpdateWarnings = [];
10643 }
10644 };
10645
10646 ReactStrictModeWarnings.recordDeprecationWarnings = function (fiber, instance) {
10647 // Dedup strategy: Warn once per component.
10648 if (didWarnAboutDeprecatedLifecycles.has(fiber.type)) {
10649 return;
10650 }
10651
10652 // Don't warn about react-lifecycles-compat polyfilled components.
10653 if (typeof instance.componentWillMount === 'function' && instance.componentWillMount.__suppressDeprecationWarning !== true) {
10654 pendingComponentWillMountWarnings.push(fiber);
10655 }
10656 if (typeof instance.componentWillReceiveProps === 'function' && instance.componentWillReceiveProps.__suppressDeprecationWarning !== true) {
10657 pendingComponentWillReceivePropsWarnings.push(fiber);
10658 }
10659 if (typeof instance.componentWillUpdate === 'function' && instance.componentWillUpdate.__suppressDeprecationWarning !== true) {
10660 pendingComponentWillUpdateWarnings.push(fiber);
10661 }
10662 };
10663
10664 ReactStrictModeWarnings.recordUnsafeLifecycleWarnings = function (fiber, instance) {
10665 var strictRoot = findStrictRoot(fiber);
10666 if (strictRoot === null) {
10667 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.');
10668 return;
10669 }
10670
10671 // Dedup strategy: Warn once per component.
10672 // This is difficult to track any other way since component names
10673 // are often vague and are likely to collide between 3rd party libraries.
10674 // An expand property is probably okay to use here since it's DEV-only,
10675 // and will only be set in the event of serious warnings.
10676 if (didWarnAboutUnsafeLifecycles.has(fiber.type)) {
10677 return;
10678 }
10679
10680 var warningsForRoot = void 0;
10681 if (!pendingUnsafeLifecycleWarnings.has(strictRoot)) {
10682 warningsForRoot = {
10683 UNSAFE_componentWillMount: [],
10684 UNSAFE_componentWillReceiveProps: [],
10685 UNSAFE_componentWillUpdate: []
10686 };
10687
10688 pendingUnsafeLifecycleWarnings.set(strictRoot, warningsForRoot);
10689 } else {
10690 warningsForRoot = pendingUnsafeLifecycleWarnings.get(strictRoot);
10691 }
10692
10693 var unsafeLifecycles = [];
10694 if (typeof instance.componentWillMount === 'function' && instance.componentWillMount.__suppressDeprecationWarning !== true || typeof instance.UNSAFE_componentWillMount === 'function') {
10695 unsafeLifecycles.push('UNSAFE_componentWillMount');
10696 }
10697 if (typeof instance.componentWillReceiveProps === 'function' && instance.componentWillReceiveProps.__suppressDeprecationWarning !== true || typeof instance.UNSAFE_componentWillReceiveProps === 'function') {
10698 unsafeLifecycles.push('UNSAFE_componentWillReceiveProps');
10699 }
10700 if (typeof instance.componentWillUpdate === 'function' && instance.componentWillUpdate.__suppressDeprecationWarning !== true || typeof instance.UNSAFE_componentWillUpdate === 'function') {
10701 unsafeLifecycles.push('UNSAFE_componentWillUpdate');
10702 }
10703
10704 if (unsafeLifecycles.length > 0) {
10705 unsafeLifecycles.forEach(function (lifecycle) {
10706 warningsForRoot[lifecycle].push(fiber);
10707 });
10708 }
10709 };
10710
10711 ReactStrictModeWarnings.recordLegacyContextWarning = function (fiber, instance) {
10712 var strictRoot = findStrictRoot(fiber);
10713 if (strictRoot === null) {
10714 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.');
10715 return;
10716 }
10717
10718 // Dedup strategy: Warn once per component.
10719 if (didWarnAboutLegacyContext.has(fiber.type)) {
10720 return;
10721 }
10722
10723 var warningsForRoot = pendingLegacyContextWarning.get(strictRoot);
10724
10725 if (fiber.type.contextTypes != null || fiber.type.childContextTypes != null || instance !== null && typeof instance.getChildContext === 'function') {
10726 if (warningsForRoot === undefined) {
10727 warningsForRoot = [];
10728 pendingLegacyContextWarning.set(strictRoot, warningsForRoot);
10729 }
10730 warningsForRoot.push(fiber);
10731 }
10732 };
10733
10734 ReactStrictModeWarnings.flushLegacyContextWarning = function () {
10735 pendingLegacyContextWarning.forEach(function (fiberArray, strictRoot) {
10736 var uniqueNames = new Set();
10737 fiberArray.forEach(function (fiber) {
10738 uniqueNames.add(getComponentName(fiber.type) || 'Component');
10739 didWarnAboutLegacyContext.add(fiber.type);
10740 });
10741
10742 var sortedNames = setToSortedString(uniqueNames);
10743 var strictRootComponentStack = getStackByFiberInDevAndProd(strictRoot);
10744
10745 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);
10746 });
10747 };
10748}
10749
10750// This lets us hook into Fiber to debug what it's doing.
10751// See https://github.com/facebook/react/pull/8033.
10752// This is not part of the public API, not even for React DevTools.
10753// You may only inject a debugTool if you work on React Fiber itself.
10754var ReactFiberInstrumentation = {
10755 debugTool: null
10756};
10757
10758var ReactFiberInstrumentation_1 = ReactFiberInstrumentation;
10759
10760// TODO: Offscreen updates should never suspend. However, a promise that
10761// suspended inside an offscreen subtree should be able to ping at the priority
10762// of the outer render.
10763
10764function markPendingPriorityLevel(root, expirationTime) {
10765 // If there's a gap between completing a failed root and retrying it,
10766 // additional updates may be scheduled. Clear `didError`, in case the update
10767 // is sufficient to fix the error.
10768 root.didError = false;
10769
10770 // Update the latest and earliest pending times
10771 var earliestPendingTime = root.earliestPendingTime;
10772 if (earliestPendingTime === NoWork) {
10773 // No other pending updates.
10774 root.earliestPendingTime = root.latestPendingTime = expirationTime;
10775 } else {
10776 if (earliestPendingTime < expirationTime) {
10777 // This is the earliest pending update.
10778 root.earliestPendingTime = expirationTime;
10779 } else {
10780 var latestPendingTime = root.latestPendingTime;
10781 if (latestPendingTime > expirationTime) {
10782 // This is the latest pending update
10783 root.latestPendingTime = expirationTime;
10784 }
10785 }
10786 }
10787 findNextExpirationTimeToWorkOn(expirationTime, root);
10788}
10789
10790function markCommittedPriorityLevels(root, earliestRemainingTime) {
10791 root.didError = false;
10792
10793 if (earliestRemainingTime === NoWork) {
10794 // Fast path. There's no remaining work. Clear everything.
10795 root.earliestPendingTime = NoWork;
10796 root.latestPendingTime = NoWork;
10797 root.earliestSuspendedTime = NoWork;
10798 root.latestSuspendedTime = NoWork;
10799 root.latestPingedTime = NoWork;
10800 findNextExpirationTimeToWorkOn(NoWork, root);
10801 return;
10802 }
10803
10804 if (earliestRemainingTime < root.latestPingedTime) {
10805 root.latestPingedTime = NoWork;
10806 }
10807
10808 // Let's see if the previous latest known pending level was just flushed.
10809 var latestPendingTime = root.latestPendingTime;
10810 if (latestPendingTime !== NoWork) {
10811 if (latestPendingTime > earliestRemainingTime) {
10812 // We've flushed all the known pending levels.
10813 root.earliestPendingTime = root.latestPendingTime = NoWork;
10814 } else {
10815 var earliestPendingTime = root.earliestPendingTime;
10816 if (earliestPendingTime > earliestRemainingTime) {
10817 // We've flushed the earliest known pending level. Set this to the
10818 // latest pending time.
10819 root.earliestPendingTime = root.latestPendingTime;
10820 }
10821 }
10822 }
10823
10824 // Now let's handle the earliest remaining level in the whole tree. We need to
10825 // decide whether to treat it as a pending level or as suspended. Check
10826 // it falls within the range of known suspended levels.
10827
10828 var earliestSuspendedTime = root.earliestSuspendedTime;
10829 if (earliestSuspendedTime === NoWork) {
10830 // There's no suspended work. Treat the earliest remaining level as a
10831 // pending level.
10832 markPendingPriorityLevel(root, earliestRemainingTime);
10833 findNextExpirationTimeToWorkOn(NoWork, root);
10834 return;
10835 }
10836
10837 var latestSuspendedTime = root.latestSuspendedTime;
10838 if (earliestRemainingTime < latestSuspendedTime) {
10839 // The earliest remaining level is later than all the suspended work. That
10840 // means we've flushed all the suspended work.
10841 root.earliestSuspendedTime = NoWork;
10842 root.latestSuspendedTime = NoWork;
10843 root.latestPingedTime = NoWork;
10844
10845 // There's no suspended work. Treat the earliest remaining level as a
10846 // pending level.
10847 markPendingPriorityLevel(root, earliestRemainingTime);
10848 findNextExpirationTimeToWorkOn(NoWork, root);
10849 return;
10850 }
10851
10852 if (earliestRemainingTime > earliestSuspendedTime) {
10853 // The earliest remaining time is earlier than all the suspended work.
10854 // Treat it as a pending update.
10855 markPendingPriorityLevel(root, earliestRemainingTime);
10856 findNextExpirationTimeToWorkOn(NoWork, root);
10857 return;
10858 }
10859
10860 // The earliest remaining time falls within the range of known suspended
10861 // levels. We should treat this as suspended work.
10862 findNextExpirationTimeToWorkOn(NoWork, root);
10863}
10864
10865function hasLowerPriorityWork(root, erroredExpirationTime) {
10866 var latestPendingTime = root.latestPendingTime;
10867 var latestSuspendedTime = root.latestSuspendedTime;
10868 var latestPingedTime = root.latestPingedTime;
10869 return latestPendingTime !== NoWork && latestPendingTime < erroredExpirationTime || latestSuspendedTime !== NoWork && latestSuspendedTime < erroredExpirationTime || latestPingedTime !== NoWork && latestPingedTime < erroredExpirationTime;
10870}
10871
10872function isPriorityLevelSuspended(root, expirationTime) {
10873 var earliestSuspendedTime = root.earliestSuspendedTime;
10874 var latestSuspendedTime = root.latestSuspendedTime;
10875 return earliestSuspendedTime !== NoWork && expirationTime <= earliestSuspendedTime && expirationTime >= latestSuspendedTime;
10876}
10877
10878function markSuspendedPriorityLevel(root, suspendedTime) {
10879 root.didError = false;
10880 clearPing(root, suspendedTime);
10881
10882 // First, check the known pending levels and update them if needed.
10883 var earliestPendingTime = root.earliestPendingTime;
10884 var latestPendingTime = root.latestPendingTime;
10885 if (earliestPendingTime === suspendedTime) {
10886 if (latestPendingTime === suspendedTime) {
10887 // Both known pending levels were suspended. Clear them.
10888 root.earliestPendingTime = root.latestPendingTime = NoWork;
10889 } else {
10890 // The earliest pending level was suspended. Clear by setting it to the
10891 // latest pending level.
10892 root.earliestPendingTime = latestPendingTime;
10893 }
10894 } else if (latestPendingTime === suspendedTime) {
10895 // The latest pending level was suspended. Clear by setting it to the
10896 // latest pending level.
10897 root.latestPendingTime = earliestPendingTime;
10898 }
10899
10900 // Finally, update the known suspended levels.
10901 var earliestSuspendedTime = root.earliestSuspendedTime;
10902 var latestSuspendedTime = root.latestSuspendedTime;
10903 if (earliestSuspendedTime === NoWork) {
10904 // No other suspended levels.
10905 root.earliestSuspendedTime = root.latestSuspendedTime = suspendedTime;
10906 } else {
10907 if (earliestSuspendedTime < suspendedTime) {
10908 // This is the earliest suspended level.
10909 root.earliestSuspendedTime = suspendedTime;
10910 } else if (latestSuspendedTime > suspendedTime) {
10911 // This is the latest suspended level
10912 root.latestSuspendedTime = suspendedTime;
10913 }
10914 }
10915
10916 findNextExpirationTimeToWorkOn(suspendedTime, root);
10917}
10918
10919function markPingedPriorityLevel(root, pingedTime) {
10920 root.didError = false;
10921
10922 // TODO: When we add back resuming, we need to ensure the progressed work
10923 // is thrown out and not reused during the restarted render. One way to
10924 // invalidate the progressed work is to restart at expirationTime + 1.
10925 var latestPingedTime = root.latestPingedTime;
10926 if (latestPingedTime === NoWork || latestPingedTime > pingedTime) {
10927 root.latestPingedTime = pingedTime;
10928 }
10929 findNextExpirationTimeToWorkOn(pingedTime, root);
10930}
10931
10932function clearPing(root, completedTime) {
10933 var latestPingedTime = root.latestPingedTime;
10934 if (latestPingedTime >= completedTime) {
10935 root.latestPingedTime = NoWork;
10936 }
10937}
10938
10939function findEarliestOutstandingPriorityLevel(root, renderExpirationTime) {
10940 var earliestExpirationTime = renderExpirationTime;
10941
10942 var earliestPendingTime = root.earliestPendingTime;
10943 var earliestSuspendedTime = root.earliestSuspendedTime;
10944 if (earliestPendingTime > earliestExpirationTime) {
10945 earliestExpirationTime = earliestPendingTime;
10946 }
10947 if (earliestSuspendedTime > earliestExpirationTime) {
10948 earliestExpirationTime = earliestSuspendedTime;
10949 }
10950 return earliestExpirationTime;
10951}
10952
10953function didExpireAtExpirationTime(root, currentTime) {
10954 var expirationTime = root.expirationTime;
10955 if (expirationTime !== NoWork && currentTime <= expirationTime) {
10956 // The root has expired. Flush all work up to the current time.
10957 root.nextExpirationTimeToWorkOn = currentTime;
10958 }
10959}
10960
10961function findNextExpirationTimeToWorkOn(completedExpirationTime, root) {
10962 var earliestSuspendedTime = root.earliestSuspendedTime;
10963 var latestSuspendedTime = root.latestSuspendedTime;
10964 var earliestPendingTime = root.earliestPendingTime;
10965 var latestPingedTime = root.latestPingedTime;
10966
10967 // Work on the earliest pending time. Failing that, work on the latest
10968 // pinged time.
10969 var nextExpirationTimeToWorkOn = earliestPendingTime !== NoWork ? earliestPendingTime : latestPingedTime;
10970
10971 // If there is no pending or pinged work, check if there's suspended work
10972 // that's lower priority than what we just completed.
10973 if (nextExpirationTimeToWorkOn === NoWork && (completedExpirationTime === NoWork || latestSuspendedTime < completedExpirationTime)) {
10974 // The lowest priority suspended work is the work most likely to be
10975 // committed next. Let's start rendering it again, so that if it times out,
10976 // it's ready to commit.
10977 nextExpirationTimeToWorkOn = latestSuspendedTime;
10978 }
10979
10980 var expirationTime = nextExpirationTimeToWorkOn;
10981 if (expirationTime !== NoWork && earliestSuspendedTime > expirationTime) {
10982 // Expire using the earliest known expiration time.
10983 expirationTime = earliestSuspendedTime;
10984 }
10985
10986 root.nextExpirationTimeToWorkOn = nextExpirationTimeToWorkOn;
10987 root.expirationTime = expirationTime;
10988}
10989
10990function resolveDefaultProps(Component, baseProps) {
10991 if (Component && Component.defaultProps) {
10992 // Resolve default props. Taken from ReactElement
10993 var props = _assign({}, baseProps);
10994 var defaultProps = Component.defaultProps;
10995 for (var propName in defaultProps) {
10996 if (props[propName] === undefined) {
10997 props[propName] = defaultProps[propName];
10998 }
10999 }
11000 return props;
11001 }
11002 return baseProps;
11003}
11004
11005function readLazyComponentType(lazyComponent) {
11006 var status = lazyComponent._status;
11007 var result = lazyComponent._result;
11008 switch (status) {
11009 case Resolved:
11010 {
11011 var Component = result;
11012 return Component;
11013 }
11014 case Rejected:
11015 {
11016 var error = result;
11017 throw error;
11018 }
11019 case Pending:
11020 {
11021 var thenable = result;
11022 throw thenable;
11023 }
11024 default:
11025 {
11026 lazyComponent._status = Pending;
11027 var ctor = lazyComponent._ctor;
11028 var _thenable = ctor();
11029 _thenable.then(function (moduleObject) {
11030 if (lazyComponent._status === Pending) {
11031 var defaultExport = moduleObject.default;
11032 {
11033 if (defaultExport === undefined) {
11034 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);
11035 }
11036 }
11037 lazyComponent._status = Resolved;
11038 lazyComponent._result = defaultExport;
11039 }
11040 }, function (error) {
11041 if (lazyComponent._status === Pending) {
11042 lazyComponent._status = Rejected;
11043 lazyComponent._result = error;
11044 }
11045 });
11046 // Handle synchronous thenables.
11047 switch (lazyComponent._status) {
11048 case Resolved:
11049 return lazyComponent._result;
11050 case Rejected:
11051 throw lazyComponent._result;
11052 }
11053 lazyComponent._result = _thenable;
11054 throw _thenable;
11055 }
11056 }
11057}
11058
11059var fakeInternalInstance = {};
11060var isArray$1 = Array.isArray;
11061
11062// React.Component uses a shared frozen object by default.
11063// We'll use it to determine whether we need to initialize legacy refs.
11064var emptyRefsObject = new React.Component().refs;
11065
11066var didWarnAboutStateAssignmentForComponent = void 0;
11067var didWarnAboutUninitializedState = void 0;
11068var didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate = void 0;
11069var didWarnAboutLegacyLifecyclesAndDerivedState = void 0;
11070var didWarnAboutUndefinedDerivedState = void 0;
11071var warnOnUndefinedDerivedState = void 0;
11072var warnOnInvalidCallback$1 = void 0;
11073var didWarnAboutDirectlyAssigningPropsToState = void 0;
11074var didWarnAboutContextTypeAndContextTypes = void 0;
11075var didWarnAboutInvalidateContextType = void 0;
11076
11077{
11078 didWarnAboutStateAssignmentForComponent = new Set();
11079 didWarnAboutUninitializedState = new Set();
11080 didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate = new Set();
11081 didWarnAboutLegacyLifecyclesAndDerivedState = new Set();
11082 didWarnAboutDirectlyAssigningPropsToState = new Set();
11083 didWarnAboutUndefinedDerivedState = new Set();
11084 didWarnAboutContextTypeAndContextTypes = new Set();
11085 didWarnAboutInvalidateContextType = new Set();
11086
11087 var didWarnOnInvalidCallback = new Set();
11088
11089 warnOnInvalidCallback$1 = function (callback, callerName) {
11090 if (callback === null || typeof callback === 'function') {
11091 return;
11092 }
11093 var key = callerName + '_' + callback;
11094 if (!didWarnOnInvalidCallback.has(key)) {
11095 didWarnOnInvalidCallback.add(key);
11096 warningWithoutStack$1(false, '%s(...): Expected the last optional `callback` argument to be a ' + 'function. Instead received: %s.', callerName, callback);
11097 }
11098 };
11099
11100 warnOnUndefinedDerivedState = function (type, partialState) {
11101 if (partialState === undefined) {
11102 var componentName = getComponentName(type) || 'Component';
11103 if (!didWarnAboutUndefinedDerivedState.has(componentName)) {
11104 didWarnAboutUndefinedDerivedState.add(componentName);
11105 warningWithoutStack$1(false, '%s.getDerivedStateFromProps(): A valid state object (or null) must be returned. ' + 'You have returned undefined.', componentName);
11106 }
11107 }
11108 };
11109
11110 // This is so gross but it's at least non-critical and can be removed if
11111 // it causes problems. This is meant to give a nicer error message for
11112 // ReactDOM15.unstable_renderSubtreeIntoContainer(reactDOM16Component,
11113 // ...)) which otherwise throws a "_processChildContext is not a function"
11114 // exception.
11115 Object.defineProperty(fakeInternalInstance, '_processChildContext', {
11116 enumerable: false,
11117 value: function () {
11118 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).');
11119 }
11120 });
11121 Object.freeze(fakeInternalInstance);
11122}
11123
11124function applyDerivedStateFromProps(workInProgress, ctor, getDerivedStateFromProps, nextProps) {
11125 var prevState = workInProgress.memoizedState;
11126
11127 {
11128 if (debugRenderPhaseSideEffects || debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) {
11129 // Invoke the function an extra time to help detect side-effects.
11130 getDerivedStateFromProps(nextProps, prevState);
11131 }
11132 }
11133
11134 var partialState = getDerivedStateFromProps(nextProps, prevState);
11135
11136 {
11137 warnOnUndefinedDerivedState(ctor, partialState);
11138 }
11139 // Merge the partial state and the previous state.
11140 var memoizedState = partialState === null || partialState === undefined ? prevState : _assign({}, prevState, partialState);
11141 workInProgress.memoizedState = memoizedState;
11142
11143 // Once the update queue is empty, persist the derived state onto the
11144 // base state.
11145 var updateQueue = workInProgress.updateQueue;
11146 if (updateQueue !== null && workInProgress.expirationTime === NoWork) {
11147 updateQueue.baseState = memoizedState;
11148 }
11149}
11150
11151var classComponentUpdater = {
11152 isMounted: isMounted,
11153 enqueueSetState: function (inst, payload, callback) {
11154 var fiber = get(inst);
11155 var currentTime = requestCurrentTime();
11156 var expirationTime = computeExpirationForFiber(currentTime, fiber);
11157
11158 var update = createUpdate(expirationTime);
11159 update.payload = payload;
11160 if (callback !== undefined && callback !== null) {
11161 {
11162 warnOnInvalidCallback$1(callback, 'setState');
11163 }
11164 update.callback = callback;
11165 }
11166
11167 flushPassiveEffects();
11168 enqueueUpdate(fiber, update);
11169 scheduleWork(fiber, expirationTime);
11170 },
11171 enqueueReplaceState: function (inst, payload, callback) {
11172 var fiber = get(inst);
11173 var currentTime = requestCurrentTime();
11174 var expirationTime = computeExpirationForFiber(currentTime, fiber);
11175
11176 var update = createUpdate(expirationTime);
11177 update.tag = ReplaceState;
11178 update.payload = payload;
11179
11180 if (callback !== undefined && callback !== null) {
11181 {
11182 warnOnInvalidCallback$1(callback, 'replaceState');
11183 }
11184 update.callback = callback;
11185 }
11186
11187 flushPassiveEffects();
11188 enqueueUpdate(fiber, update);
11189 scheduleWork(fiber, expirationTime);
11190 },
11191 enqueueForceUpdate: function (inst, callback) {
11192 var fiber = get(inst);
11193 var currentTime = requestCurrentTime();
11194 var expirationTime = computeExpirationForFiber(currentTime, fiber);
11195
11196 var update = createUpdate(expirationTime);
11197 update.tag = ForceUpdate;
11198
11199 if (callback !== undefined && callback !== null) {
11200 {
11201 warnOnInvalidCallback$1(callback, 'forceUpdate');
11202 }
11203 update.callback = callback;
11204 }
11205
11206 flushPassiveEffects();
11207 enqueueUpdate(fiber, update);
11208 scheduleWork(fiber, expirationTime);
11209 }
11210};
11211
11212function checkShouldComponentUpdate(workInProgress, ctor, oldProps, newProps, oldState, newState, nextContext) {
11213 var instance = workInProgress.stateNode;
11214 if (typeof instance.shouldComponentUpdate === 'function') {
11215 startPhaseTimer(workInProgress, 'shouldComponentUpdate');
11216 var shouldUpdate = instance.shouldComponentUpdate(newProps, newState, nextContext);
11217 stopPhaseTimer();
11218
11219 {
11220 !(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;
11221 }
11222
11223 return shouldUpdate;
11224 }
11225
11226 if (ctor.prototype && ctor.prototype.isPureReactComponent) {
11227 return !shallowEqual(oldProps, newProps) || !shallowEqual(oldState, newState);
11228 }
11229
11230 return true;
11231}
11232
11233function checkClassInstance(workInProgress, ctor, newProps) {
11234 var instance = workInProgress.stateNode;
11235 {
11236 var name = getComponentName(ctor) || 'Component';
11237 var renderPresent = instance.render;
11238
11239 if (!renderPresent) {
11240 if (ctor.prototype && typeof ctor.prototype.render === 'function') {
11241 warningWithoutStack$1(false, '%s(...): No `render` method found on the returned component ' + 'instance: did you accidentally return an object from the constructor?', name);
11242 } else {
11243 warningWithoutStack$1(false, '%s(...): No `render` method found on the returned component ' + 'instance: you may have forgotten to define `render`.', name);
11244 }
11245 }
11246
11247 var noGetInitialStateOnES6 = !instance.getInitialState || instance.getInitialState.isReactClassApproved || instance.state;
11248 !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;
11249 var noGetDefaultPropsOnES6 = !instance.getDefaultProps || instance.getDefaultProps.isReactClassApproved;
11250 !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;
11251 var noInstancePropTypes = !instance.propTypes;
11252 !noInstancePropTypes ? warningWithoutStack$1(false, 'propTypes was defined as an instance property on %s. Use a static ' + 'property to define propTypes instead.', name) : void 0;
11253 var noInstanceContextType = !instance.contextType;
11254 !noInstanceContextType ? warningWithoutStack$1(false, 'contextType was defined as an instance property on %s. Use a static ' + 'property to define contextType instead.', name) : void 0;
11255 var noInstanceContextTypes = !instance.contextTypes;
11256 !noInstanceContextTypes ? warningWithoutStack$1(false, 'contextTypes was defined as an instance property on %s. Use a static ' + 'property to define contextTypes instead.', name) : void 0;
11257
11258 if (ctor.contextType && ctor.contextTypes && !didWarnAboutContextTypeAndContextTypes.has(ctor)) {
11259 didWarnAboutContextTypeAndContextTypes.add(ctor);
11260 warningWithoutStack$1(false, '%s declares both contextTypes and contextType static properties. ' + 'The legacy contextTypes property will be ignored.', name);
11261 }
11262
11263 var noComponentShouldUpdate = typeof instance.componentShouldUpdate !== 'function';
11264 !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;
11265 if (ctor.prototype && ctor.prototype.isPureReactComponent && typeof instance.shouldComponentUpdate !== 'undefined') {
11266 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');
11267 }
11268 var noComponentDidUnmount = typeof instance.componentDidUnmount !== 'function';
11269 !noComponentDidUnmount ? warningWithoutStack$1(false, '%s has a method called ' + 'componentDidUnmount(). But there is no such lifecycle method. ' + 'Did you mean componentWillUnmount()?', name) : void 0;
11270 var noComponentDidReceiveProps = typeof instance.componentDidReceiveProps !== 'function';
11271 !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;
11272 var noComponentWillRecieveProps = typeof instance.componentWillRecieveProps !== 'function';
11273 !noComponentWillRecieveProps ? warningWithoutStack$1(false, '%s has a method called ' + 'componentWillRecieveProps(). Did you mean componentWillReceiveProps()?', name) : void 0;
11274 var noUnsafeComponentWillRecieveProps = typeof instance.UNSAFE_componentWillRecieveProps !== 'function';
11275 !noUnsafeComponentWillRecieveProps ? warningWithoutStack$1(false, '%s has a method called ' + 'UNSAFE_componentWillRecieveProps(). Did you mean UNSAFE_componentWillReceiveProps()?', name) : void 0;
11276 var hasMutatedProps = instance.props !== newProps;
11277 !(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;
11278 var noInstanceDefaultProps = !instance.defaultProps;
11279 !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;
11280
11281 if (typeof instance.getSnapshotBeforeUpdate === 'function' && typeof instance.componentDidUpdate !== 'function' && !didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate.has(ctor)) {
11282 didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate.add(ctor);
11283 warningWithoutStack$1(false, '%s: getSnapshotBeforeUpdate() should be used with componentDidUpdate(). ' + 'This component defines getSnapshotBeforeUpdate() only.', getComponentName(ctor));
11284 }
11285
11286 var noInstanceGetDerivedStateFromProps = typeof instance.getDerivedStateFromProps !== 'function';
11287 !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;
11288 var noInstanceGetDerivedStateFromCatch = typeof instance.getDerivedStateFromError !== 'function';
11289 !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;
11290 var noStaticGetSnapshotBeforeUpdate = typeof ctor.getSnapshotBeforeUpdate !== 'function';
11291 !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;
11292 var _state = instance.state;
11293 if (_state && (typeof _state !== 'object' || isArray$1(_state))) {
11294 warningWithoutStack$1(false, '%s.state: must be set to an object or null', name);
11295 }
11296 if (typeof instance.getChildContext === 'function') {
11297 !(typeof ctor.childContextTypes === 'object') ? warningWithoutStack$1(false, '%s.getChildContext(): childContextTypes must be defined in order to ' + 'use getChildContext().', name) : void 0;
11298 }
11299 }
11300}
11301
11302function adoptClassInstance(workInProgress, instance) {
11303 instance.updater = classComponentUpdater;
11304 workInProgress.stateNode = instance;
11305 // The instance needs access to the fiber so that it can schedule updates
11306 set(instance, workInProgress);
11307 {
11308 instance._reactInternalInstance = fakeInternalInstance;
11309 }
11310}
11311
11312function constructClassInstance(workInProgress, ctor, props, renderExpirationTime) {
11313 var isLegacyContextConsumer = false;
11314 var unmaskedContext = emptyContextObject;
11315 var context = null;
11316 var contextType = ctor.contextType;
11317
11318 {
11319 if ('contextType' in ctor) {
11320 var isValid =
11321 // Allow null for conditional declaration
11322 contextType === null || contextType !== undefined && contextType.$$typeof === REACT_CONTEXT_TYPE && contextType._context === undefined; // Not a <Context.Consumer>
11323
11324 if (!isValid && !didWarnAboutInvalidateContextType.has(ctor)) {
11325 didWarnAboutInvalidateContextType.add(ctor);
11326
11327 var addendum = '';
11328 if (contextType === undefined) {
11329 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.';
11330 } else if (typeof contextType !== 'object') {
11331 addendum = ' However, it is set to a ' + typeof contextType + '.';
11332 } else if (contextType.$$typeof === REACT_PROVIDER_TYPE) {
11333 addendum = ' Did you accidentally pass the Context.Provider instead?';
11334 } else if (contextType._context !== undefined) {
11335 // <Context.Consumer>
11336 addendum = ' Did you accidentally pass the Context.Consumer instead?';
11337 } else {
11338 addendum = ' However, it is set to an object with keys {' + Object.keys(contextType).join(', ') + '}.';
11339 }
11340 warningWithoutStack$1(false, '%s defines an invalid contextType. ' + 'contextType should point to the Context object returned by React.createContext().%s', getComponentName(ctor) || 'Component', addendum);
11341 }
11342 }
11343 }
11344
11345 if (typeof contextType === 'object' && contextType !== null) {
11346 context = readContext(contextType);
11347 } else {
11348 unmaskedContext = getUnmaskedContext(workInProgress, ctor, true);
11349 var contextTypes = ctor.contextTypes;
11350 isLegacyContextConsumer = contextTypes !== null && contextTypes !== undefined;
11351 context = isLegacyContextConsumer ? getMaskedContext(workInProgress, unmaskedContext) : emptyContextObject;
11352 }
11353
11354 // Instantiate twice to help detect side-effects.
11355 {
11356 if (debugRenderPhaseSideEffects || debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) {
11357 new ctor(props, context); // eslint-disable-line no-new
11358 }
11359 }
11360
11361 var instance = new ctor(props, context);
11362 var state = workInProgress.memoizedState = instance.state !== null && instance.state !== undefined ? instance.state : null;
11363 adoptClassInstance(workInProgress, instance);
11364
11365 {
11366 if (typeof ctor.getDerivedStateFromProps === 'function' && state === null) {
11367 var componentName = getComponentName(ctor) || 'Component';
11368 if (!didWarnAboutUninitializedState.has(componentName)) {
11369 didWarnAboutUninitializedState.add(componentName);
11370 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);
11371 }
11372 }
11373
11374 // If new component APIs are defined, "unsafe" lifecycles won't be called.
11375 // Warn about these lifecycles if they are present.
11376 // Don't warn about react-lifecycles-compat polyfilled methods though.
11377 if (typeof ctor.getDerivedStateFromProps === 'function' || typeof instance.getSnapshotBeforeUpdate === 'function') {
11378 var foundWillMountName = null;
11379 var foundWillReceivePropsName = null;
11380 var foundWillUpdateName = null;
11381 if (typeof instance.componentWillMount === 'function' && instance.componentWillMount.__suppressDeprecationWarning !== true) {
11382 foundWillMountName = 'componentWillMount';
11383 } else if (typeof instance.UNSAFE_componentWillMount === 'function') {
11384 foundWillMountName = 'UNSAFE_componentWillMount';
11385 }
11386 if (typeof instance.componentWillReceiveProps === 'function' && instance.componentWillReceiveProps.__suppressDeprecationWarning !== true) {
11387 foundWillReceivePropsName = 'componentWillReceiveProps';
11388 } else if (typeof instance.UNSAFE_componentWillReceiveProps === 'function') {
11389 foundWillReceivePropsName = 'UNSAFE_componentWillReceiveProps';
11390 }
11391 if (typeof instance.componentWillUpdate === 'function' && instance.componentWillUpdate.__suppressDeprecationWarning !== true) {
11392 foundWillUpdateName = 'componentWillUpdate';
11393 } else if (typeof instance.UNSAFE_componentWillUpdate === 'function') {
11394 foundWillUpdateName = 'UNSAFE_componentWillUpdate';
11395 }
11396 if (foundWillMountName !== null || foundWillReceivePropsName !== null || foundWillUpdateName !== null) {
11397 var _componentName = getComponentName(ctor) || 'Component';
11398 var newApiName = typeof ctor.getDerivedStateFromProps === 'function' ? 'getDerivedStateFromProps()' : 'getSnapshotBeforeUpdate()';
11399 if (!didWarnAboutLegacyLifecyclesAndDerivedState.has(_componentName)) {
11400 didWarnAboutLegacyLifecyclesAndDerivedState.add(_componentName);
11401 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 : '');
11402 }
11403 }
11404 }
11405 }
11406
11407 // Cache unmasked context so we can avoid recreating masked context unless necessary.
11408 // ReactFiberContext usually updates this cache but can't for newly-created instances.
11409 if (isLegacyContextConsumer) {
11410 cacheContext(workInProgress, unmaskedContext, context);
11411 }
11412
11413 return instance;
11414}
11415
11416function callComponentWillMount(workInProgress, instance) {
11417 startPhaseTimer(workInProgress, 'componentWillMount');
11418 var oldState = instance.state;
11419
11420 if (typeof instance.componentWillMount === 'function') {
11421 instance.componentWillMount();
11422 }
11423 if (typeof instance.UNSAFE_componentWillMount === 'function') {
11424 instance.UNSAFE_componentWillMount();
11425 }
11426
11427 stopPhaseTimer();
11428
11429 if (oldState !== instance.state) {
11430 {
11431 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');
11432 }
11433 classComponentUpdater.enqueueReplaceState(instance, instance.state, null);
11434 }
11435}
11436
11437function callComponentWillReceiveProps(workInProgress, instance, newProps, nextContext) {
11438 var oldState = instance.state;
11439 startPhaseTimer(workInProgress, 'componentWillReceiveProps');
11440 if (typeof instance.componentWillReceiveProps === 'function') {
11441 instance.componentWillReceiveProps(newProps, nextContext);
11442 }
11443 if (typeof instance.UNSAFE_componentWillReceiveProps === 'function') {
11444 instance.UNSAFE_componentWillReceiveProps(newProps, nextContext);
11445 }
11446 stopPhaseTimer();
11447
11448 if (instance.state !== oldState) {
11449 {
11450 var componentName = getComponentName(workInProgress.type) || 'Component';
11451 if (!didWarnAboutStateAssignmentForComponent.has(componentName)) {
11452 didWarnAboutStateAssignmentForComponent.add(componentName);
11453 warningWithoutStack$1(false, '%s.componentWillReceiveProps(): Assigning directly to ' + "this.state is deprecated (except inside a component's " + 'constructor). Use setState instead.', componentName);
11454 }
11455 }
11456 classComponentUpdater.enqueueReplaceState(instance, instance.state, null);
11457 }
11458}
11459
11460// Invokes the mount life-cycles on a previously never rendered instance.
11461function mountClassInstance(workInProgress, ctor, newProps, renderExpirationTime) {
11462 {
11463 checkClassInstance(workInProgress, ctor, newProps);
11464 }
11465
11466 var instance = workInProgress.stateNode;
11467 instance.props = newProps;
11468 instance.state = workInProgress.memoizedState;
11469 instance.refs = emptyRefsObject;
11470
11471 var contextType = ctor.contextType;
11472 if (typeof contextType === 'object' && contextType !== null) {
11473 instance.context = readContext(contextType);
11474 } else {
11475 var unmaskedContext = getUnmaskedContext(workInProgress, ctor, true);
11476 instance.context = getMaskedContext(workInProgress, unmaskedContext);
11477 }
11478
11479 {
11480 if (instance.state === newProps) {
11481 var componentName = getComponentName(ctor) || 'Component';
11482 if (!didWarnAboutDirectlyAssigningPropsToState.has(componentName)) {
11483 didWarnAboutDirectlyAssigningPropsToState.add(componentName);
11484 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);
11485 }
11486 }
11487
11488 if (workInProgress.mode & StrictMode) {
11489 ReactStrictModeWarnings.recordUnsafeLifecycleWarnings(workInProgress, instance);
11490
11491 ReactStrictModeWarnings.recordLegacyContextWarning(workInProgress, instance);
11492 }
11493
11494 if (warnAboutDeprecatedLifecycles) {
11495 ReactStrictModeWarnings.recordDeprecationWarnings(workInProgress, instance);
11496 }
11497 }
11498
11499 var updateQueue = workInProgress.updateQueue;
11500 if (updateQueue !== null) {
11501 processUpdateQueue(workInProgress, updateQueue, newProps, instance, renderExpirationTime);
11502 instance.state = workInProgress.memoizedState;
11503 }
11504
11505 var getDerivedStateFromProps = ctor.getDerivedStateFromProps;
11506 if (typeof getDerivedStateFromProps === 'function') {
11507 applyDerivedStateFromProps(workInProgress, ctor, getDerivedStateFromProps, newProps);
11508 instance.state = workInProgress.memoizedState;
11509 }
11510
11511 // In order to support react-lifecycles-compat polyfilled components,
11512 // Unsafe lifecycles should not be invoked for components using the new APIs.
11513 if (typeof ctor.getDerivedStateFromProps !== 'function' && typeof instance.getSnapshotBeforeUpdate !== 'function' && (typeof instance.UNSAFE_componentWillMount === 'function' || typeof instance.componentWillMount === 'function')) {
11514 callComponentWillMount(workInProgress, instance);
11515 // If we had additional state updates during this life-cycle, let's
11516 // process them now.
11517 updateQueue = workInProgress.updateQueue;
11518 if (updateQueue !== null) {
11519 processUpdateQueue(workInProgress, updateQueue, newProps, instance, renderExpirationTime);
11520 instance.state = workInProgress.memoizedState;
11521 }
11522 }
11523
11524 if (typeof instance.componentDidMount === 'function') {
11525 workInProgress.effectTag |= Update;
11526 }
11527}
11528
11529function resumeMountClassInstance(workInProgress, ctor, newProps, renderExpirationTime) {
11530 var instance = workInProgress.stateNode;
11531
11532 var oldProps = workInProgress.memoizedProps;
11533 instance.props = oldProps;
11534
11535 var oldContext = instance.context;
11536 var contextType = ctor.contextType;
11537 var nextContext = void 0;
11538 if (typeof contextType === 'object' && contextType !== null) {
11539 nextContext = readContext(contextType);
11540 } else {
11541 var nextLegacyUnmaskedContext = getUnmaskedContext(workInProgress, ctor, true);
11542 nextContext = getMaskedContext(workInProgress, nextLegacyUnmaskedContext);
11543 }
11544
11545 var getDerivedStateFromProps = ctor.getDerivedStateFromProps;
11546 var hasNewLifecycles = typeof getDerivedStateFromProps === 'function' || typeof instance.getSnapshotBeforeUpdate === 'function';
11547
11548 // Note: During these life-cycles, instance.props/instance.state are what
11549 // ever the previously attempted to render - not the "current". However,
11550 // during componentDidUpdate we pass the "current" props.
11551
11552 // In order to support react-lifecycles-compat polyfilled components,
11553 // Unsafe lifecycles should not be invoked for components using the new APIs.
11554 if (!hasNewLifecycles && (typeof instance.UNSAFE_componentWillReceiveProps === 'function' || typeof instance.componentWillReceiveProps === 'function')) {
11555 if (oldProps !== newProps || oldContext !== nextContext) {
11556 callComponentWillReceiveProps(workInProgress, instance, newProps, nextContext);
11557 }
11558 }
11559
11560 resetHasForceUpdateBeforeProcessing();
11561
11562 var oldState = workInProgress.memoizedState;
11563 var newState = instance.state = oldState;
11564 var updateQueue = workInProgress.updateQueue;
11565 if (updateQueue !== null) {
11566 processUpdateQueue(workInProgress, updateQueue, newProps, instance, renderExpirationTime);
11567 newState = workInProgress.memoizedState;
11568 }
11569 if (oldProps === newProps && oldState === newState && !hasContextChanged() && !checkHasForceUpdateAfterProcessing()) {
11570 // If an update was already in progress, we should schedule an Update
11571 // effect even though we're bailing out, so that cWU/cDU are called.
11572 if (typeof instance.componentDidMount === 'function') {
11573 workInProgress.effectTag |= Update;
11574 }
11575 return false;
11576 }
11577
11578 if (typeof getDerivedStateFromProps === 'function') {
11579 applyDerivedStateFromProps(workInProgress, ctor, getDerivedStateFromProps, newProps);
11580 newState = workInProgress.memoizedState;
11581 }
11582
11583 var shouldUpdate = checkHasForceUpdateAfterProcessing() || checkShouldComponentUpdate(workInProgress, ctor, oldProps, newProps, oldState, newState, nextContext);
11584
11585 if (shouldUpdate) {
11586 // In order to support react-lifecycles-compat polyfilled components,
11587 // Unsafe lifecycles should not be invoked for components using the new APIs.
11588 if (!hasNewLifecycles && (typeof instance.UNSAFE_componentWillMount === 'function' || typeof instance.componentWillMount === 'function')) {
11589 startPhaseTimer(workInProgress, 'componentWillMount');
11590 if (typeof instance.componentWillMount === 'function') {
11591 instance.componentWillMount();
11592 }
11593 if (typeof instance.UNSAFE_componentWillMount === 'function') {
11594 instance.UNSAFE_componentWillMount();
11595 }
11596 stopPhaseTimer();
11597 }
11598 if (typeof instance.componentDidMount === 'function') {
11599 workInProgress.effectTag |= Update;
11600 }
11601 } else {
11602 // If an update was already in progress, we should schedule an Update
11603 // effect even though we're bailing out, so that cWU/cDU are called.
11604 if (typeof instance.componentDidMount === 'function') {
11605 workInProgress.effectTag |= Update;
11606 }
11607
11608 // If shouldComponentUpdate returned false, we should still update the
11609 // memoized state to indicate that this work can be reused.
11610 workInProgress.memoizedProps = newProps;
11611 workInProgress.memoizedState = newState;
11612 }
11613
11614 // Update the existing instance's state, props, and context pointers even
11615 // if shouldComponentUpdate returns false.
11616 instance.props = newProps;
11617 instance.state = newState;
11618 instance.context = nextContext;
11619
11620 return shouldUpdate;
11621}
11622
11623// Invokes the update life-cycles and returns false if it shouldn't rerender.
11624function updateClassInstance(current, workInProgress, ctor, newProps, renderExpirationTime) {
11625 var instance = workInProgress.stateNode;
11626
11627 var oldProps = workInProgress.memoizedProps;
11628 instance.props = workInProgress.type === workInProgress.elementType ? oldProps : resolveDefaultProps(workInProgress.type, oldProps);
11629
11630 var oldContext = instance.context;
11631 var contextType = ctor.contextType;
11632 var nextContext = void 0;
11633 if (typeof contextType === 'object' && contextType !== null) {
11634 nextContext = readContext(contextType);
11635 } else {
11636 var nextUnmaskedContext = getUnmaskedContext(workInProgress, ctor, true);
11637 nextContext = getMaskedContext(workInProgress, nextUnmaskedContext);
11638 }
11639
11640 var getDerivedStateFromProps = ctor.getDerivedStateFromProps;
11641 var hasNewLifecycles = typeof getDerivedStateFromProps === 'function' || typeof instance.getSnapshotBeforeUpdate === 'function';
11642
11643 // Note: During these life-cycles, instance.props/instance.state are what
11644 // ever the previously attempted to render - not the "current". However,
11645 // during componentDidUpdate we pass the "current" props.
11646
11647 // In order to support react-lifecycles-compat polyfilled components,
11648 // Unsafe lifecycles should not be invoked for components using the new APIs.
11649 if (!hasNewLifecycles && (typeof instance.UNSAFE_componentWillReceiveProps === 'function' || typeof instance.componentWillReceiveProps === 'function')) {
11650 if (oldProps !== newProps || oldContext !== nextContext) {
11651 callComponentWillReceiveProps(workInProgress, instance, newProps, nextContext);
11652 }
11653 }
11654
11655 resetHasForceUpdateBeforeProcessing();
11656
11657 var oldState = workInProgress.memoizedState;
11658 var newState = instance.state = oldState;
11659 var updateQueue = workInProgress.updateQueue;
11660 if (updateQueue !== null) {
11661 processUpdateQueue(workInProgress, updateQueue, newProps, instance, renderExpirationTime);
11662 newState = workInProgress.memoizedState;
11663 }
11664
11665 if (oldProps === newProps && oldState === newState && !hasContextChanged() && !checkHasForceUpdateAfterProcessing()) {
11666 // If an update was already in progress, we should schedule an Update
11667 // effect even though we're bailing out, so that cWU/cDU are called.
11668 if (typeof instance.componentDidUpdate === 'function') {
11669 if (oldProps !== current.memoizedProps || oldState !== current.memoizedState) {
11670 workInProgress.effectTag |= Update;
11671 }
11672 }
11673 if (typeof instance.getSnapshotBeforeUpdate === 'function') {
11674 if (oldProps !== current.memoizedProps || oldState !== current.memoizedState) {
11675 workInProgress.effectTag |= Snapshot;
11676 }
11677 }
11678 return false;
11679 }
11680
11681 if (typeof getDerivedStateFromProps === 'function') {
11682 applyDerivedStateFromProps(workInProgress, ctor, getDerivedStateFromProps, newProps);
11683 newState = workInProgress.memoizedState;
11684 }
11685
11686 var shouldUpdate = checkHasForceUpdateAfterProcessing() || checkShouldComponentUpdate(workInProgress, ctor, oldProps, newProps, oldState, newState, nextContext);
11687
11688 if (shouldUpdate) {
11689 // In order to support react-lifecycles-compat polyfilled components,
11690 // Unsafe lifecycles should not be invoked for components using the new APIs.
11691 if (!hasNewLifecycles && (typeof instance.UNSAFE_componentWillUpdate === 'function' || typeof instance.componentWillUpdate === 'function')) {
11692 startPhaseTimer(workInProgress, 'componentWillUpdate');
11693 if (typeof instance.componentWillUpdate === 'function') {
11694 instance.componentWillUpdate(newProps, newState, nextContext);
11695 }
11696 if (typeof instance.UNSAFE_componentWillUpdate === 'function') {
11697 instance.UNSAFE_componentWillUpdate(newProps, newState, nextContext);
11698 }
11699 stopPhaseTimer();
11700 }
11701 if (typeof instance.componentDidUpdate === 'function') {
11702 workInProgress.effectTag |= Update;
11703 }
11704 if (typeof instance.getSnapshotBeforeUpdate === 'function') {
11705 workInProgress.effectTag |= Snapshot;
11706 }
11707 } else {
11708 // If an update was already in progress, we should schedule an Update
11709 // effect even though we're bailing out, so that cWU/cDU are called.
11710 if (typeof instance.componentDidUpdate === 'function') {
11711 if (oldProps !== current.memoizedProps || oldState !== current.memoizedState) {
11712 workInProgress.effectTag |= Update;
11713 }
11714 }
11715 if (typeof instance.getSnapshotBeforeUpdate === 'function') {
11716 if (oldProps !== current.memoizedProps || oldState !== current.memoizedState) {
11717 workInProgress.effectTag |= Snapshot;
11718 }
11719 }
11720
11721 // If shouldComponentUpdate returned false, we should still update the
11722 // memoized props/state to indicate that this work can be reused.
11723 workInProgress.memoizedProps = newProps;
11724 workInProgress.memoizedState = newState;
11725 }
11726
11727 // Update the existing instance's state, props, and context pointers even
11728 // if shouldComponentUpdate returns false.
11729 instance.props = newProps;
11730 instance.state = newState;
11731 instance.context = nextContext;
11732
11733 return shouldUpdate;
11734}
11735
11736var didWarnAboutMaps = void 0;
11737var didWarnAboutGenerators = void 0;
11738var didWarnAboutStringRefInStrictMode = void 0;
11739var ownerHasKeyUseWarning = void 0;
11740var ownerHasFunctionTypeWarning = void 0;
11741var warnForMissingKey = function (child) {};
11742
11743{
11744 didWarnAboutMaps = false;
11745 didWarnAboutGenerators = false;
11746 didWarnAboutStringRefInStrictMode = {};
11747
11748 /**
11749 * Warn if there's no key explicitly set on dynamic arrays of children or
11750 * object keys are not valid. This allows us to keep track of children between
11751 * updates.
11752 */
11753 ownerHasKeyUseWarning = {};
11754 ownerHasFunctionTypeWarning = {};
11755
11756 warnForMissingKey = function (child) {
11757 if (child === null || typeof child !== 'object') {
11758 return;
11759 }
11760 if (!child._store || child._store.validated || child.key != null) {
11761 return;
11762 }
11763 !(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;
11764 child._store.validated = true;
11765
11766 var currentComponentErrorInfo = 'Each child in a list should have a unique ' + '"key" prop. See https://fb.me/react-warning-keys for ' + 'more information.' + getCurrentFiberStackInDev();
11767 if (ownerHasKeyUseWarning[currentComponentErrorInfo]) {
11768 return;
11769 }
11770 ownerHasKeyUseWarning[currentComponentErrorInfo] = true;
11771
11772 warning$1(false, 'Each child in a list should have a unique ' + '"key" prop. See https://fb.me/react-warning-keys for ' + 'more information.');
11773 };
11774}
11775
11776var isArray = Array.isArray;
11777
11778function coerceRef(returnFiber, current$$1, element) {
11779 var mixedRef = element.ref;
11780 if (mixedRef !== null && typeof mixedRef !== 'function' && typeof mixedRef !== 'object') {
11781 {
11782 if (returnFiber.mode & StrictMode) {
11783 var componentName = getComponentName(returnFiber.type) || 'Component';
11784 if (!didWarnAboutStringRefInStrictMode[componentName]) {
11785 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));
11786 didWarnAboutStringRefInStrictMode[componentName] = true;
11787 }
11788 }
11789 }
11790
11791 if (element._owner) {
11792 var owner = element._owner;
11793 var inst = void 0;
11794 if (owner) {
11795 var ownerFiber = owner;
11796 !(ownerFiber.tag === ClassComponent) ? invariant(false, 'Function components cannot have refs. Did you mean to use React.forwardRef()?') : void 0;
11797 inst = ownerFiber.stateNode;
11798 }
11799 !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;
11800 var stringRef = '' + mixedRef;
11801 // Check if previous string ref matches new string ref
11802 if (current$$1 !== null && current$$1.ref !== null && typeof current$$1.ref === 'function' && current$$1.ref._stringRef === stringRef) {
11803 return current$$1.ref;
11804 }
11805 var ref = function (value) {
11806 var refs = inst.refs;
11807 if (refs === emptyRefsObject) {
11808 // This is a lazy pooled frozen object, so we need to initialize.
11809 refs = inst.refs = {};
11810 }
11811 if (value === null) {
11812 delete refs[stringRef];
11813 } else {
11814 refs[stringRef] = value;
11815 }
11816 };
11817 ref._stringRef = stringRef;
11818 return ref;
11819 } else {
11820 !(typeof mixedRef === 'string') ? invariant(false, 'Expected ref to be a function, a string, an object returned by React.createRef(), or null.') : void 0;
11821 !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;
11822 }
11823 }
11824 return mixedRef;
11825}
11826
11827function throwOnInvalidObjectType(returnFiber, newChild) {
11828 if (returnFiber.type !== 'textarea') {
11829 var addendum = '';
11830 {
11831 addendum = ' If you meant to render a collection of children, use an array ' + 'instead.' + getCurrentFiberStackInDev();
11832 }
11833 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);
11834 }
11835}
11836
11837function warnOnFunctionType() {
11838 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();
11839
11840 if (ownerHasFunctionTypeWarning[currentComponentErrorInfo]) {
11841 return;
11842 }
11843 ownerHasFunctionTypeWarning[currentComponentErrorInfo] = true;
11844
11845 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.');
11846}
11847
11848// This wrapper function exists because I expect to clone the code in each path
11849// to be able to optimize each path individually by branching early. This needs
11850// a compiler or we can do it manually. Helpers that don't need this branching
11851// live outside of this function.
11852function ChildReconciler(shouldTrackSideEffects) {
11853 function deleteChild(returnFiber, childToDelete) {
11854 if (!shouldTrackSideEffects) {
11855 // Noop.
11856 return;
11857 }
11858 // Deletions are added in reversed order so we add it to the front.
11859 // At this point, the return fiber's effect list is empty except for
11860 // deletions, so we can just append the deletion to the list. The remaining
11861 // effects aren't added until the complete phase. Once we implement
11862 // resuming, this may not be true.
11863 var last = returnFiber.lastEffect;
11864 if (last !== null) {
11865 last.nextEffect = childToDelete;
11866 returnFiber.lastEffect = childToDelete;
11867 } else {
11868 returnFiber.firstEffect = returnFiber.lastEffect = childToDelete;
11869 }
11870 childToDelete.nextEffect = null;
11871 childToDelete.effectTag = Deletion;
11872 }
11873
11874 function deleteRemainingChildren(returnFiber, currentFirstChild) {
11875 if (!shouldTrackSideEffects) {
11876 // Noop.
11877 return null;
11878 }
11879
11880 // TODO: For the shouldClone case, this could be micro-optimized a bit by
11881 // assuming that after the first child we've already added everything.
11882 var childToDelete = currentFirstChild;
11883 while (childToDelete !== null) {
11884 deleteChild(returnFiber, childToDelete);
11885 childToDelete = childToDelete.sibling;
11886 }
11887 return null;
11888 }
11889
11890 function mapRemainingChildren(returnFiber, currentFirstChild) {
11891 // Add the remaining children to a temporary map so that we can find them by
11892 // keys quickly. Implicit (null) keys get added to this set with their index
11893 var existingChildren = new Map();
11894
11895 var existingChild = currentFirstChild;
11896 while (existingChild !== null) {
11897 if (existingChild.key !== null) {
11898 existingChildren.set(existingChild.key, existingChild);
11899 } else {
11900 existingChildren.set(existingChild.index, existingChild);
11901 }
11902 existingChild = existingChild.sibling;
11903 }
11904 return existingChildren;
11905 }
11906
11907 function useFiber(fiber, pendingProps, expirationTime) {
11908 // We currently set sibling to null and index to 0 here because it is easy
11909 // to forget to do before returning it. E.g. for the single child case.
11910 var clone = createWorkInProgress(fiber, pendingProps, expirationTime);
11911 clone.index = 0;
11912 clone.sibling = null;
11913 return clone;
11914 }
11915
11916 function placeChild(newFiber, lastPlacedIndex, newIndex) {
11917 newFiber.index = newIndex;
11918 if (!shouldTrackSideEffects) {
11919 // Noop.
11920 return lastPlacedIndex;
11921 }
11922 var current$$1 = newFiber.alternate;
11923 if (current$$1 !== null) {
11924 var oldIndex = current$$1.index;
11925 if (oldIndex < lastPlacedIndex) {
11926 // This is a move.
11927 newFiber.effectTag = Placement;
11928 return lastPlacedIndex;
11929 } else {
11930 // This item can stay in place.
11931 return oldIndex;
11932 }
11933 } else {
11934 // This is an insertion.
11935 newFiber.effectTag = Placement;
11936 return lastPlacedIndex;
11937 }
11938 }
11939
11940 function placeSingleChild(newFiber) {
11941 // This is simpler for the single child case. We only need to do a
11942 // placement for inserting new children.
11943 if (shouldTrackSideEffects && newFiber.alternate === null) {
11944 newFiber.effectTag = Placement;
11945 }
11946 return newFiber;
11947 }
11948
11949 function updateTextNode(returnFiber, current$$1, textContent, expirationTime) {
11950 if (current$$1 === null || current$$1.tag !== HostText) {
11951 // Insert
11952 var created = createFiberFromText(textContent, returnFiber.mode, expirationTime);
11953 created.return = returnFiber;
11954 return created;
11955 } else {
11956 // Update
11957 var existing = useFiber(current$$1, textContent, expirationTime);
11958 existing.return = returnFiber;
11959 return existing;
11960 }
11961 }
11962
11963 function updateElement(returnFiber, current$$1, element, expirationTime) {
11964 if (current$$1 !== null && current$$1.elementType === element.type) {
11965 // Move based on index
11966 var existing = useFiber(current$$1, element.props, expirationTime);
11967 existing.ref = coerceRef(returnFiber, current$$1, element);
11968 existing.return = returnFiber;
11969 {
11970 existing._debugSource = element._source;
11971 existing._debugOwner = element._owner;
11972 }
11973 return existing;
11974 } else {
11975 // Insert
11976 var created = createFiberFromElement(element, returnFiber.mode, expirationTime);
11977 created.ref = coerceRef(returnFiber, current$$1, element);
11978 created.return = returnFiber;
11979 return created;
11980 }
11981 }
11982
11983 function updatePortal(returnFiber, current$$1, portal, expirationTime) {
11984 if (current$$1 === null || current$$1.tag !== HostPortal || current$$1.stateNode.containerInfo !== portal.containerInfo || current$$1.stateNode.implementation !== portal.implementation) {
11985 // Insert
11986 var created = createFiberFromPortal(portal, returnFiber.mode, expirationTime);
11987 created.return = returnFiber;
11988 return created;
11989 } else {
11990 // Update
11991 var existing = useFiber(current$$1, portal.children || [], expirationTime);
11992 existing.return = returnFiber;
11993 return existing;
11994 }
11995 }
11996
11997 function updateFragment(returnFiber, current$$1, fragment, expirationTime, key) {
11998 if (current$$1 === null || current$$1.tag !== Fragment) {
11999 // Insert
12000 var created = createFiberFromFragment(fragment, returnFiber.mode, expirationTime, key);
12001 created.return = returnFiber;
12002 return created;
12003 } else {
12004 // Update
12005 var existing = useFiber(current$$1, fragment, expirationTime);
12006 existing.return = returnFiber;
12007 return existing;
12008 }
12009 }
12010
12011 function createChild(returnFiber, newChild, expirationTime) {
12012 if (typeof newChild === 'string' || typeof newChild === 'number') {
12013 // Text nodes don't have keys. If the previous node is implicitly keyed
12014 // we can continue to replace it without aborting even if it is not a text
12015 // node.
12016 var created = createFiberFromText('' + newChild, returnFiber.mode, expirationTime);
12017 created.return = returnFiber;
12018 return created;
12019 }
12020
12021 if (typeof newChild === 'object' && newChild !== null) {
12022 switch (newChild.$$typeof) {
12023 case REACT_ELEMENT_TYPE:
12024 {
12025 var _created = createFiberFromElement(newChild, returnFiber.mode, expirationTime);
12026 _created.ref = coerceRef(returnFiber, null, newChild);
12027 _created.return = returnFiber;
12028 return _created;
12029 }
12030 case REACT_PORTAL_TYPE:
12031 {
12032 var _created2 = createFiberFromPortal(newChild, returnFiber.mode, expirationTime);
12033 _created2.return = returnFiber;
12034 return _created2;
12035 }
12036 }
12037
12038 if (isArray(newChild) || getIteratorFn(newChild)) {
12039 var _created3 = createFiberFromFragment(newChild, returnFiber.mode, expirationTime, null);
12040 _created3.return = returnFiber;
12041 return _created3;
12042 }
12043
12044 throwOnInvalidObjectType(returnFiber, newChild);
12045 }
12046
12047 {
12048 if (typeof newChild === 'function') {
12049 warnOnFunctionType();
12050 }
12051 }
12052
12053 return null;
12054 }
12055
12056 function updateSlot(returnFiber, oldFiber, newChild, expirationTime) {
12057 // Update the fiber if the keys match, otherwise return null.
12058
12059 var key = oldFiber !== null ? oldFiber.key : null;
12060
12061 if (typeof newChild === 'string' || typeof newChild === 'number') {
12062 // Text nodes don't have keys. If the previous node is implicitly keyed
12063 // we can continue to replace it without aborting even if it is not a text
12064 // node.
12065 if (key !== null) {
12066 return null;
12067 }
12068 return updateTextNode(returnFiber, oldFiber, '' + newChild, expirationTime);
12069 }
12070
12071 if (typeof newChild === 'object' && newChild !== null) {
12072 switch (newChild.$$typeof) {
12073 case REACT_ELEMENT_TYPE:
12074 {
12075 if (newChild.key === key) {
12076 if (newChild.type === REACT_FRAGMENT_TYPE) {
12077 return updateFragment(returnFiber, oldFiber, newChild.props.children, expirationTime, key);
12078 }
12079 return updateElement(returnFiber, oldFiber, newChild, expirationTime);
12080 } else {
12081 return null;
12082 }
12083 }
12084 case REACT_PORTAL_TYPE:
12085 {
12086 if (newChild.key === key) {
12087 return updatePortal(returnFiber, oldFiber, newChild, expirationTime);
12088 } else {
12089 return null;
12090 }
12091 }
12092 }
12093
12094 if (isArray(newChild) || getIteratorFn(newChild)) {
12095 if (key !== null) {
12096 return null;
12097 }
12098
12099 return updateFragment(returnFiber, oldFiber, newChild, expirationTime, null);
12100 }
12101
12102 throwOnInvalidObjectType(returnFiber, newChild);
12103 }
12104
12105 {
12106 if (typeof newChild === 'function') {
12107 warnOnFunctionType();
12108 }
12109 }
12110
12111 return null;
12112 }
12113
12114 function updateFromMap(existingChildren, returnFiber, newIdx, newChild, expirationTime) {
12115 if (typeof newChild === 'string' || typeof newChild === 'number') {
12116 // Text nodes don't have keys, so we neither have to check the old nor
12117 // new node for the key. If both are text nodes, they match.
12118 var matchedFiber = existingChildren.get(newIdx) || null;
12119 return updateTextNode(returnFiber, matchedFiber, '' + newChild, expirationTime);
12120 }
12121
12122 if (typeof newChild === 'object' && newChild !== null) {
12123 switch (newChild.$$typeof) {
12124 case REACT_ELEMENT_TYPE:
12125 {
12126 var _matchedFiber = existingChildren.get(newChild.key === null ? newIdx : newChild.key) || null;
12127 if (newChild.type === REACT_FRAGMENT_TYPE) {
12128 return updateFragment(returnFiber, _matchedFiber, newChild.props.children, expirationTime, newChild.key);
12129 }
12130 return updateElement(returnFiber, _matchedFiber, newChild, expirationTime);
12131 }
12132 case REACT_PORTAL_TYPE:
12133 {
12134 var _matchedFiber2 = existingChildren.get(newChild.key === null ? newIdx : newChild.key) || null;
12135 return updatePortal(returnFiber, _matchedFiber2, newChild, expirationTime);
12136 }
12137 }
12138
12139 if (isArray(newChild) || getIteratorFn(newChild)) {
12140 var _matchedFiber3 = existingChildren.get(newIdx) || null;
12141 return updateFragment(returnFiber, _matchedFiber3, newChild, expirationTime, null);
12142 }
12143
12144 throwOnInvalidObjectType(returnFiber, newChild);
12145 }
12146
12147 {
12148 if (typeof newChild === 'function') {
12149 warnOnFunctionType();
12150 }
12151 }
12152
12153 return null;
12154 }
12155
12156 /**
12157 * Warns if there is a duplicate or missing key
12158 */
12159 function warnOnInvalidKey(child, knownKeys) {
12160 {
12161 if (typeof child !== 'object' || child === null) {
12162 return knownKeys;
12163 }
12164 switch (child.$$typeof) {
12165 case REACT_ELEMENT_TYPE:
12166 case REACT_PORTAL_TYPE:
12167 warnForMissingKey(child);
12168 var key = child.key;
12169 if (typeof key !== 'string') {
12170 break;
12171 }
12172 if (knownKeys === null) {
12173 knownKeys = new Set();
12174 knownKeys.add(key);
12175 break;
12176 }
12177 if (!knownKeys.has(key)) {
12178 knownKeys.add(key);
12179 break;
12180 }
12181 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);
12182 break;
12183 default:
12184 break;
12185 }
12186 }
12187 return knownKeys;
12188 }
12189
12190 function reconcileChildrenArray(returnFiber, currentFirstChild, newChildren, expirationTime) {
12191 // This algorithm can't optimize by searching from both ends since we
12192 // don't have backpointers on fibers. I'm trying to see how far we can get
12193 // with that model. If it ends up not being worth the tradeoffs, we can
12194 // add it later.
12195
12196 // Even with a two ended optimization, we'd want to optimize for the case
12197 // where there are few changes and brute force the comparison instead of
12198 // going for the Map. It'd like to explore hitting that path first in
12199 // forward-only mode and only go for the Map once we notice that we need
12200 // lots of look ahead. This doesn't handle reversal as well as two ended
12201 // search but that's unusual. Besides, for the two ended optimization to
12202 // work on Iterables, we'd need to copy the whole set.
12203
12204 // In this first iteration, we'll just live with hitting the bad case
12205 // (adding everything to a Map) in for every insert/move.
12206
12207 // If you change this code, also update reconcileChildrenIterator() which
12208 // uses the same algorithm.
12209
12210 {
12211 // First, validate keys.
12212 var knownKeys = null;
12213 for (var i = 0; i < newChildren.length; i++) {
12214 var child = newChildren[i];
12215 knownKeys = warnOnInvalidKey(child, knownKeys);
12216 }
12217 }
12218
12219 var resultingFirstChild = null;
12220 var previousNewFiber = null;
12221
12222 var oldFiber = currentFirstChild;
12223 var lastPlacedIndex = 0;
12224 var newIdx = 0;
12225 var nextOldFiber = null;
12226 for (; oldFiber !== null && newIdx < newChildren.length; newIdx++) {
12227 if (oldFiber.index > newIdx) {
12228 nextOldFiber = oldFiber;
12229 oldFiber = null;
12230 } else {
12231 nextOldFiber = oldFiber.sibling;
12232 }
12233 var newFiber = updateSlot(returnFiber, oldFiber, newChildren[newIdx], expirationTime);
12234 if (newFiber === null) {
12235 // TODO: This breaks on empty slots like null children. That's
12236 // unfortunate because it triggers the slow path all the time. We need
12237 // a better way to communicate whether this was a miss or null,
12238 // boolean, undefined, etc.
12239 if (oldFiber === null) {
12240 oldFiber = nextOldFiber;
12241 }
12242 break;
12243 }
12244 if (shouldTrackSideEffects) {
12245 if (oldFiber && newFiber.alternate === null) {
12246 // We matched the slot, but we didn't reuse the existing fiber, so we
12247 // need to delete the existing child.
12248 deleteChild(returnFiber, oldFiber);
12249 }
12250 }
12251 lastPlacedIndex = placeChild(newFiber, lastPlacedIndex, newIdx);
12252 if (previousNewFiber === null) {
12253 // TODO: Move out of the loop. This only happens for the first run.
12254 resultingFirstChild = newFiber;
12255 } else {
12256 // TODO: Defer siblings if we're not at the right index for this slot.
12257 // I.e. if we had null values before, then we want to defer this
12258 // for each null value. However, we also don't want to call updateSlot
12259 // with the previous one.
12260 previousNewFiber.sibling = newFiber;
12261 }
12262 previousNewFiber = newFiber;
12263 oldFiber = nextOldFiber;
12264 }
12265
12266 if (newIdx === newChildren.length) {
12267 // We've reached the end of the new children. We can delete the rest.
12268 deleteRemainingChildren(returnFiber, oldFiber);
12269 return resultingFirstChild;
12270 }
12271
12272 if (oldFiber === null) {
12273 // If we don't have any more existing children we can choose a fast path
12274 // since the rest will all be insertions.
12275 for (; newIdx < newChildren.length; newIdx++) {
12276 var _newFiber = createChild(returnFiber, newChildren[newIdx], expirationTime);
12277 if (!_newFiber) {
12278 continue;
12279 }
12280 lastPlacedIndex = placeChild(_newFiber, lastPlacedIndex, newIdx);
12281 if (previousNewFiber === null) {
12282 // TODO: Move out of the loop. This only happens for the first run.
12283 resultingFirstChild = _newFiber;
12284 } else {
12285 previousNewFiber.sibling = _newFiber;
12286 }
12287 previousNewFiber = _newFiber;
12288 }
12289 return resultingFirstChild;
12290 }
12291
12292 // Add all children to a key map for quick lookups.
12293 var existingChildren = mapRemainingChildren(returnFiber, oldFiber);
12294
12295 // Keep scanning and use the map to restore deleted items as moves.
12296 for (; newIdx < newChildren.length; newIdx++) {
12297 var _newFiber2 = updateFromMap(existingChildren, returnFiber, newIdx, newChildren[newIdx], expirationTime);
12298 if (_newFiber2) {
12299 if (shouldTrackSideEffects) {
12300 if (_newFiber2.alternate !== null) {
12301 // The new fiber is a work in progress, but if there exists a
12302 // current, that means that we reused the fiber. We need to delete
12303 // it from the child list so that we don't add it to the deletion
12304 // list.
12305 existingChildren.delete(_newFiber2.key === null ? newIdx : _newFiber2.key);
12306 }
12307 }
12308 lastPlacedIndex = placeChild(_newFiber2, lastPlacedIndex, newIdx);
12309 if (previousNewFiber === null) {
12310 resultingFirstChild = _newFiber2;
12311 } else {
12312 previousNewFiber.sibling = _newFiber2;
12313 }
12314 previousNewFiber = _newFiber2;
12315 }
12316 }
12317
12318 if (shouldTrackSideEffects) {
12319 // Any existing children that weren't consumed above were deleted. We need
12320 // to add them to the deletion list.
12321 existingChildren.forEach(function (child) {
12322 return deleteChild(returnFiber, child);
12323 });
12324 }
12325
12326 return resultingFirstChild;
12327 }
12328
12329 function reconcileChildrenIterator(returnFiber, currentFirstChild, newChildrenIterable, expirationTime) {
12330 // This is the same implementation as reconcileChildrenArray(),
12331 // but using the iterator instead.
12332
12333 var iteratorFn = getIteratorFn(newChildrenIterable);
12334 !(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;
12335
12336 {
12337 // We don't support rendering Generators because it's a mutation.
12338 // See https://github.com/facebook/react/issues/12995
12339 if (typeof Symbol === 'function' &&
12340 // $FlowFixMe Flow doesn't know about toStringTag
12341 newChildrenIterable[Symbol.toStringTag] === 'Generator') {
12342 !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;
12343 didWarnAboutGenerators = true;
12344 }
12345
12346 // Warn about using Maps as children
12347 if (newChildrenIterable.entries === iteratorFn) {
12348 !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;
12349 didWarnAboutMaps = true;
12350 }
12351
12352 // First, validate keys.
12353 // We'll get a different iterator later for the main pass.
12354 var _newChildren = iteratorFn.call(newChildrenIterable);
12355 if (_newChildren) {
12356 var knownKeys = null;
12357 var _step = _newChildren.next();
12358 for (; !_step.done; _step = _newChildren.next()) {
12359 var child = _step.value;
12360 knownKeys = warnOnInvalidKey(child, knownKeys);
12361 }
12362 }
12363 }
12364
12365 var newChildren = iteratorFn.call(newChildrenIterable);
12366 !(newChildren != null) ? invariant(false, 'An iterable object provided no iterator.') : void 0;
12367
12368 var resultingFirstChild = null;
12369 var previousNewFiber = null;
12370
12371 var oldFiber = currentFirstChild;
12372 var lastPlacedIndex = 0;
12373 var newIdx = 0;
12374 var nextOldFiber = null;
12375
12376 var step = newChildren.next();
12377 for (; oldFiber !== null && !step.done; newIdx++, step = newChildren.next()) {
12378 if (oldFiber.index > newIdx) {
12379 nextOldFiber = oldFiber;
12380 oldFiber = null;
12381 } else {
12382 nextOldFiber = oldFiber.sibling;
12383 }
12384 var newFiber = updateSlot(returnFiber, oldFiber, step.value, expirationTime);
12385 if (newFiber === null) {
12386 // TODO: This breaks on empty slots like null children. That's
12387 // unfortunate because it triggers the slow path all the time. We need
12388 // a better way to communicate whether this was a miss or null,
12389 // boolean, undefined, etc.
12390 if (!oldFiber) {
12391 oldFiber = nextOldFiber;
12392 }
12393 break;
12394 }
12395 if (shouldTrackSideEffects) {
12396 if (oldFiber && newFiber.alternate === null) {
12397 // We matched the slot, but we didn't reuse the existing fiber, so we
12398 // need to delete the existing child.
12399 deleteChild(returnFiber, oldFiber);
12400 }
12401 }
12402 lastPlacedIndex = placeChild(newFiber, lastPlacedIndex, newIdx);
12403 if (previousNewFiber === null) {
12404 // TODO: Move out of the loop. This only happens for the first run.
12405 resultingFirstChild = newFiber;
12406 } else {
12407 // TODO: Defer siblings if we're not at the right index for this slot.
12408 // I.e. if we had null values before, then we want to defer this
12409 // for each null value. However, we also don't want to call updateSlot
12410 // with the previous one.
12411 previousNewFiber.sibling = newFiber;
12412 }
12413 previousNewFiber = newFiber;
12414 oldFiber = nextOldFiber;
12415 }
12416
12417 if (step.done) {
12418 // We've reached the end of the new children. We can delete the rest.
12419 deleteRemainingChildren(returnFiber, oldFiber);
12420 return resultingFirstChild;
12421 }
12422
12423 if (oldFiber === null) {
12424 // If we don't have any more existing children we can choose a fast path
12425 // since the rest will all be insertions.
12426 for (; !step.done; newIdx++, step = newChildren.next()) {
12427 var _newFiber3 = createChild(returnFiber, step.value, expirationTime);
12428 if (_newFiber3 === null) {
12429 continue;
12430 }
12431 lastPlacedIndex = placeChild(_newFiber3, lastPlacedIndex, newIdx);
12432 if (previousNewFiber === null) {
12433 // TODO: Move out of the loop. This only happens for the first run.
12434 resultingFirstChild = _newFiber3;
12435 } else {
12436 previousNewFiber.sibling = _newFiber3;
12437 }
12438 previousNewFiber = _newFiber3;
12439 }
12440 return resultingFirstChild;
12441 }
12442
12443 // Add all children to a key map for quick lookups.
12444 var existingChildren = mapRemainingChildren(returnFiber, oldFiber);
12445
12446 // Keep scanning and use the map to restore deleted items as moves.
12447 for (; !step.done; newIdx++, step = newChildren.next()) {
12448 var _newFiber4 = updateFromMap(existingChildren, returnFiber, newIdx, step.value, expirationTime);
12449 if (_newFiber4 !== null) {
12450 if (shouldTrackSideEffects) {
12451 if (_newFiber4.alternate !== null) {
12452 // The new fiber is a work in progress, but if there exists a
12453 // current, that means that we reused the fiber. We need to delete
12454 // it from the child list so that we don't add it to the deletion
12455 // list.
12456 existingChildren.delete(_newFiber4.key === null ? newIdx : _newFiber4.key);
12457 }
12458 }
12459 lastPlacedIndex = placeChild(_newFiber4, lastPlacedIndex, newIdx);
12460 if (previousNewFiber === null) {
12461 resultingFirstChild = _newFiber4;
12462 } else {
12463 previousNewFiber.sibling = _newFiber4;
12464 }
12465 previousNewFiber = _newFiber4;
12466 }
12467 }
12468
12469 if (shouldTrackSideEffects) {
12470 // Any existing children that weren't consumed above were deleted. We need
12471 // to add them to the deletion list.
12472 existingChildren.forEach(function (child) {
12473 return deleteChild(returnFiber, child);
12474 });
12475 }
12476
12477 return resultingFirstChild;
12478 }
12479
12480 function reconcileSingleTextNode(returnFiber, currentFirstChild, textContent, expirationTime) {
12481 // There's no need to check for keys on text nodes since we don't have a
12482 // way to define them.
12483 if (currentFirstChild !== null && currentFirstChild.tag === HostText) {
12484 // We already have an existing node so let's just update it and delete
12485 // the rest.
12486 deleteRemainingChildren(returnFiber, currentFirstChild.sibling);
12487 var existing = useFiber(currentFirstChild, textContent, expirationTime);
12488 existing.return = returnFiber;
12489 return existing;
12490 }
12491 // The existing first child is not a text node so we need to create one
12492 // and delete the existing ones.
12493 deleteRemainingChildren(returnFiber, currentFirstChild);
12494 var created = createFiberFromText(textContent, returnFiber.mode, expirationTime);
12495 created.return = returnFiber;
12496 return created;
12497 }
12498
12499 function reconcileSingleElement(returnFiber, currentFirstChild, element, expirationTime) {
12500 var key = element.key;
12501 var child = currentFirstChild;
12502 while (child !== null) {
12503 // TODO: If key === null and child.key === null, then this only applies to
12504 // the first item in the list.
12505 if (child.key === key) {
12506 if (child.tag === Fragment ? element.type === REACT_FRAGMENT_TYPE : child.elementType === element.type) {
12507 deleteRemainingChildren(returnFiber, child.sibling);
12508 var existing = useFiber(child, element.type === REACT_FRAGMENT_TYPE ? element.props.children : element.props, expirationTime);
12509 existing.ref = coerceRef(returnFiber, child, element);
12510 existing.return = returnFiber;
12511 {
12512 existing._debugSource = element._source;
12513 existing._debugOwner = element._owner;
12514 }
12515 return existing;
12516 } else {
12517 deleteRemainingChildren(returnFiber, child);
12518 break;
12519 }
12520 } else {
12521 deleteChild(returnFiber, child);
12522 }
12523 child = child.sibling;
12524 }
12525
12526 if (element.type === REACT_FRAGMENT_TYPE) {
12527 var created = createFiberFromFragment(element.props.children, returnFiber.mode, expirationTime, element.key);
12528 created.return = returnFiber;
12529 return created;
12530 } else {
12531 var _created4 = createFiberFromElement(element, returnFiber.mode, expirationTime);
12532 _created4.ref = coerceRef(returnFiber, currentFirstChild, element);
12533 _created4.return = returnFiber;
12534 return _created4;
12535 }
12536 }
12537
12538 function reconcileSinglePortal(returnFiber, currentFirstChild, portal, expirationTime) {
12539 var key = portal.key;
12540 var child = currentFirstChild;
12541 while (child !== null) {
12542 // TODO: If key === null and child.key === null, then this only applies to
12543 // the first item in the list.
12544 if (child.key === key) {
12545 if (child.tag === HostPortal && child.stateNode.containerInfo === portal.containerInfo && child.stateNode.implementation === portal.implementation) {
12546 deleteRemainingChildren(returnFiber, child.sibling);
12547 var existing = useFiber(child, portal.children || [], expirationTime);
12548 existing.return = returnFiber;
12549 return existing;
12550 } else {
12551 deleteRemainingChildren(returnFiber, child);
12552 break;
12553 }
12554 } else {
12555 deleteChild(returnFiber, child);
12556 }
12557 child = child.sibling;
12558 }
12559
12560 var created = createFiberFromPortal(portal, returnFiber.mode, expirationTime);
12561 created.return = returnFiber;
12562 return created;
12563 }
12564
12565 // This API will tag the children with the side-effect of the reconciliation
12566 // itself. They will be added to the side-effect list as we pass through the
12567 // children and the parent.
12568 function reconcileChildFibers(returnFiber, currentFirstChild, newChild, expirationTime) {
12569 // This function is not recursive.
12570 // If the top level item is an array, we treat it as a set of children,
12571 // not as a fragment. Nested arrays on the other hand will be treated as
12572 // fragment nodes. Recursion happens at the normal flow.
12573
12574 // Handle top level unkeyed fragments as if they were arrays.
12575 // This leads to an ambiguity between <>{[...]}</> and <>...</>.
12576 // We treat the ambiguous cases above the same.
12577 var isUnkeyedTopLevelFragment = typeof newChild === 'object' && newChild !== null && newChild.type === REACT_FRAGMENT_TYPE && newChild.key === null;
12578 if (isUnkeyedTopLevelFragment) {
12579 newChild = newChild.props.children;
12580 }
12581
12582 // Handle object types
12583 var isObject = typeof newChild === 'object' && newChild !== null;
12584
12585 if (isObject) {
12586 switch (newChild.$$typeof) {
12587 case REACT_ELEMENT_TYPE:
12588 return placeSingleChild(reconcileSingleElement(returnFiber, currentFirstChild, newChild, expirationTime));
12589 case REACT_PORTAL_TYPE:
12590 return placeSingleChild(reconcileSinglePortal(returnFiber, currentFirstChild, newChild, expirationTime));
12591 }
12592 }
12593
12594 if (typeof newChild === 'string' || typeof newChild === 'number') {
12595 return placeSingleChild(reconcileSingleTextNode(returnFiber, currentFirstChild, '' + newChild, expirationTime));
12596 }
12597
12598 if (isArray(newChild)) {
12599 return reconcileChildrenArray(returnFiber, currentFirstChild, newChild, expirationTime);
12600 }
12601
12602 if (getIteratorFn(newChild)) {
12603 return reconcileChildrenIterator(returnFiber, currentFirstChild, newChild, expirationTime);
12604 }
12605
12606 if (isObject) {
12607 throwOnInvalidObjectType(returnFiber, newChild);
12608 }
12609
12610 {
12611 if (typeof newChild === 'function') {
12612 warnOnFunctionType();
12613 }
12614 }
12615 if (typeof newChild === 'undefined' && !isUnkeyedTopLevelFragment) {
12616 // If the new child is undefined, and the return fiber is a composite
12617 // component, throw an error. If Fiber return types are disabled,
12618 // we already threw above.
12619 switch (returnFiber.tag) {
12620 case ClassComponent:
12621 {
12622 {
12623 var instance = returnFiber.stateNode;
12624 if (instance.render._isMockFunction) {
12625 // We allow auto-mocks to proceed as if they're returning null.
12626 break;
12627 }
12628 }
12629 }
12630 // Intentionally fall through to the next case, which handles both
12631 // functions and classes
12632 // eslint-disable-next-lined no-fallthrough
12633 case FunctionComponent:
12634 {
12635 var Component = returnFiber.type;
12636 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');
12637 }
12638 }
12639 }
12640
12641 // Remaining cases are all treated as empty.
12642 return deleteRemainingChildren(returnFiber, currentFirstChild);
12643 }
12644
12645 return reconcileChildFibers;
12646}
12647
12648var reconcileChildFibers = ChildReconciler(true);
12649var mountChildFibers = ChildReconciler(false);
12650
12651function cloneChildFibers(current$$1, workInProgress) {
12652 !(current$$1 === null || workInProgress.child === current$$1.child) ? invariant(false, 'Resuming work not yet implemented.') : void 0;
12653
12654 if (workInProgress.child === null) {
12655 return;
12656 }
12657
12658 var currentChild = workInProgress.child;
12659 var newChild = createWorkInProgress(currentChild, currentChild.pendingProps, currentChild.expirationTime);
12660 workInProgress.child = newChild;
12661
12662 newChild.return = workInProgress;
12663 while (currentChild.sibling !== null) {
12664 currentChild = currentChild.sibling;
12665 newChild = newChild.sibling = createWorkInProgress(currentChild, currentChild.pendingProps, currentChild.expirationTime);
12666 newChild.return = workInProgress;
12667 }
12668 newChild.sibling = null;
12669}
12670
12671var NO_CONTEXT = {};
12672
12673var contextStackCursor$1 = createCursor(NO_CONTEXT);
12674var contextFiberStackCursor = createCursor(NO_CONTEXT);
12675var rootInstanceStackCursor = createCursor(NO_CONTEXT);
12676
12677function requiredContext(c) {
12678 !(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;
12679 return c;
12680}
12681
12682function getRootHostContainer() {
12683 var rootInstance = requiredContext(rootInstanceStackCursor.current);
12684 return rootInstance;
12685}
12686
12687function pushHostContainer(fiber, nextRootInstance) {
12688 // Push current root instance onto the stack;
12689 // This allows us to reset root when portals are popped.
12690 push(rootInstanceStackCursor, nextRootInstance, fiber);
12691 // Track the context and the Fiber that provided it.
12692 // This enables us to pop only Fibers that provide unique contexts.
12693 push(contextFiberStackCursor, fiber, fiber);
12694
12695 // Finally, we need to push the host context to the stack.
12696 // However, we can't just call getRootHostContext() and push it because
12697 // we'd have a different number of entries on the stack depending on
12698 // whether getRootHostContext() throws somewhere in renderer code or not.
12699 // So we push an empty value first. This lets us safely unwind on errors.
12700 push(contextStackCursor$1, NO_CONTEXT, fiber);
12701 var nextRootContext = getRootHostContext(nextRootInstance);
12702 // Now that we know this function doesn't throw, replace it.
12703 pop(contextStackCursor$1, fiber);
12704 push(contextStackCursor$1, nextRootContext, fiber);
12705}
12706
12707function popHostContainer(fiber) {
12708 pop(contextStackCursor$1, fiber);
12709 pop(contextFiberStackCursor, fiber);
12710 pop(rootInstanceStackCursor, fiber);
12711}
12712
12713function getHostContext() {
12714 var context = requiredContext(contextStackCursor$1.current);
12715 return context;
12716}
12717
12718function pushHostContext(fiber) {
12719 var rootInstance = requiredContext(rootInstanceStackCursor.current);
12720 var context = requiredContext(contextStackCursor$1.current);
12721 var nextContext = getChildHostContext(context, fiber.type, rootInstance);
12722
12723 // Don't push this Fiber's context unless it's unique.
12724 if (context === nextContext) {
12725 return;
12726 }
12727
12728 // Track the context and the Fiber that provided it.
12729 // This enables us to pop only Fibers that provide unique contexts.
12730 push(contextFiberStackCursor, fiber, fiber);
12731 push(contextStackCursor$1, nextContext, fiber);
12732}
12733
12734function popHostContext(fiber) {
12735 // Do not pop unless this Fiber provided the current context.
12736 // pushHostContext() only pushes Fibers that provide unique contexts.
12737 if (contextFiberStackCursor.current !== fiber) {
12738 return;
12739 }
12740
12741 pop(contextStackCursor$1, fiber);
12742 pop(contextFiberStackCursor, fiber);
12743}
12744
12745var NoEffect$1 = /* */0;
12746var UnmountSnapshot = /* */2;
12747var UnmountMutation = /* */4;
12748var MountMutation = /* */8;
12749var UnmountLayout = /* */16;
12750var MountLayout = /* */32;
12751var MountPassive = /* */64;
12752var UnmountPassive = /* */128;
12753
12754var ReactCurrentDispatcher$1 = ReactSharedInternals.ReactCurrentDispatcher;
12755
12756
12757var didWarnAboutMismatchedHooksForComponent = void 0;
12758{
12759 didWarnAboutMismatchedHooksForComponent = new Set();
12760}
12761
12762// These are set right before calling the component.
12763var renderExpirationTime = NoWork;
12764// The work-in-progress fiber. I've named it differently to distinguish it from
12765// the work-in-progress hook.
12766var currentlyRenderingFiber$1 = null;
12767
12768// Hooks are stored as a linked list on the fiber's memoizedState field. The
12769// current hook list is the list that belongs to the current fiber. The
12770// work-in-progress hook list is a new list that will be added to the
12771// work-in-progress fiber.
12772var currentHook = null;
12773var nextCurrentHook = null;
12774var firstWorkInProgressHook = null;
12775var workInProgressHook = null;
12776var nextWorkInProgressHook = null;
12777
12778var remainingExpirationTime = NoWork;
12779var componentUpdateQueue = null;
12780var sideEffectTag = 0;
12781
12782// Updates scheduled during render will trigger an immediate re-render at the
12783// end of the current pass. We can't store these updates on the normal queue,
12784// because if the work is aborted, they should be discarded. Because this is
12785// a relatively rare case, we also don't want to add an additional field to
12786// either the hook or queue object types. So we store them in a lazily create
12787// map of queue -> render-phase updates, which are discarded once the component
12788// completes without re-rendering.
12789
12790// Whether an update was scheduled during the currently executing render pass.
12791var didScheduleRenderPhaseUpdate = false;
12792// Lazily created map of render-phase updates
12793var renderPhaseUpdates = null;
12794// Counter to prevent infinite loops.
12795var numberOfReRenders = 0;
12796var RE_RENDER_LIMIT = 25;
12797
12798// In DEV, this is the name of the currently executing primitive hook
12799var currentHookNameInDev = null;
12800
12801// In DEV, this list ensures that hooks are called in the same order between renders.
12802// The list stores the order of hooks used during the initial render (mount).
12803// Subsequent renders (updates) reference this list.
12804var hookTypesDev = null;
12805var hookTypesUpdateIndexDev = -1;
12806
12807function mountHookTypesDev() {
12808 {
12809 var hookName = currentHookNameInDev;
12810
12811 if (hookTypesDev === null) {
12812 hookTypesDev = [hookName];
12813 } else {
12814 hookTypesDev.push(hookName);
12815 }
12816 }
12817}
12818
12819function updateHookTypesDev() {
12820 {
12821 var hookName = currentHookNameInDev;
12822
12823 if (hookTypesDev !== null) {
12824 hookTypesUpdateIndexDev++;
12825 if (hookTypesDev[hookTypesUpdateIndexDev] !== hookName) {
12826 warnOnHookMismatchInDev(hookName);
12827 }
12828 }
12829 }
12830}
12831
12832function warnOnHookMismatchInDev(currentHookName) {
12833 {
12834 var componentName = getComponentName(currentlyRenderingFiber$1.type);
12835 if (!didWarnAboutMismatchedHooksForComponent.has(componentName)) {
12836 didWarnAboutMismatchedHooksForComponent.add(componentName);
12837
12838 if (hookTypesDev !== null) {
12839 var table = '';
12840
12841 var secondColumnStart = 30;
12842
12843 for (var i = 0; i <= hookTypesUpdateIndexDev; i++) {
12844 var oldHookName = hookTypesDev[i];
12845 var newHookName = i === hookTypesUpdateIndexDev ? currentHookName : oldHookName;
12846
12847 var row = i + 1 + '. ' + oldHookName;
12848
12849 // Extra space so second column lines up
12850 // lol @ IE not supporting String#repeat
12851 while (row.length < secondColumnStart) {
12852 row += ' ';
12853 }
12854
12855 row += newHookName + '\n';
12856
12857 table += row;
12858 }
12859
12860 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);
12861 }
12862 }
12863 }
12864}
12865
12866function throwInvalidHookError() {
12867 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.');
12868}
12869
12870function areHookInputsEqual(nextDeps, prevDeps) {
12871 if (prevDeps === null) {
12872 {
12873 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);
12874 }
12875 return false;
12876 }
12877
12878 {
12879 // Don't bother comparing lengths in prod because these arrays should be
12880 // passed inline.
12881 if (nextDeps.length !== prevDeps.length) {
12882 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(', ') + ']');
12883 }
12884 }
12885 for (var i = 0; i < prevDeps.length && i < nextDeps.length; i++) {
12886 if (is(nextDeps[i], prevDeps[i])) {
12887 continue;
12888 }
12889 return false;
12890 }
12891 return true;
12892}
12893
12894function renderWithHooks(current, workInProgress, Component, props, refOrContext, nextRenderExpirationTime) {
12895 renderExpirationTime = nextRenderExpirationTime;
12896 currentlyRenderingFiber$1 = workInProgress;
12897 nextCurrentHook = current !== null ? current.memoizedState : null;
12898
12899 {
12900 hookTypesDev = current !== null ? current._debugHookTypes : null;
12901 hookTypesUpdateIndexDev = -1;
12902 }
12903
12904 // The following should have already been reset
12905 // currentHook = null;
12906 // workInProgressHook = null;
12907
12908 // remainingExpirationTime = NoWork;
12909 // componentUpdateQueue = null;
12910
12911 // didScheduleRenderPhaseUpdate = false;
12912 // renderPhaseUpdates = null;
12913 // numberOfReRenders = 0;
12914 // sideEffectTag = 0;
12915
12916 // TODO Warn if no hooks are used at all during mount, then some are used during update.
12917 // Currently we will identify the update render as a mount because nextCurrentHook === null.
12918 // This is tricky because it's valid for certain types of components (e.g. React.lazy)
12919
12920 // Using nextCurrentHook to differentiate between mount/update only works if at least one stateful hook is used.
12921 // Non-stateful hooks (e.g. context) don't get added to memoizedState,
12922 // so nextCurrentHook would be null during updates and mounts.
12923 {
12924 if (nextCurrentHook !== null) {
12925 ReactCurrentDispatcher$1.current = HooksDispatcherOnUpdateInDEV;
12926 } else if (hookTypesDev !== null) {
12927 // This dispatcher handles an edge case where a component is updating,
12928 // but no stateful hooks have been used.
12929 // We want to match the production code behavior (which will use HooksDispatcherOnMount),
12930 // but with the extra DEV validation to ensure hooks ordering hasn't changed.
12931 // This dispatcher does that.
12932 ReactCurrentDispatcher$1.current = HooksDispatcherOnMountWithHookTypesInDEV;
12933 } else {
12934 ReactCurrentDispatcher$1.current = HooksDispatcherOnMountInDEV;
12935 }
12936 }
12937
12938 var children = Component(props, refOrContext);
12939
12940 if (didScheduleRenderPhaseUpdate) {
12941 do {
12942 didScheduleRenderPhaseUpdate = false;
12943 numberOfReRenders += 1;
12944
12945 // Start over from the beginning of the list
12946 nextCurrentHook = current !== null ? current.memoizedState : null;
12947 nextWorkInProgressHook = firstWorkInProgressHook;
12948
12949 currentHook = null;
12950 workInProgressHook = null;
12951 componentUpdateQueue = null;
12952
12953 {
12954 // Also validate hook order for cascading updates.
12955 hookTypesUpdateIndexDev = -1;
12956 }
12957
12958 ReactCurrentDispatcher$1.current = HooksDispatcherOnUpdateInDEV;
12959
12960 children = Component(props, refOrContext);
12961 } while (didScheduleRenderPhaseUpdate);
12962
12963 renderPhaseUpdates = null;
12964 numberOfReRenders = 0;
12965 }
12966
12967 // We can assume the previous dispatcher is always this one, since we set it
12968 // at the beginning of the render phase and there's no re-entrancy.
12969 ReactCurrentDispatcher$1.current = ContextOnlyDispatcher;
12970
12971 var renderedWork = currentlyRenderingFiber$1;
12972
12973 renderedWork.memoizedState = firstWorkInProgressHook;
12974 renderedWork.expirationTime = remainingExpirationTime;
12975 renderedWork.updateQueue = componentUpdateQueue;
12976 renderedWork.effectTag |= sideEffectTag;
12977
12978 {
12979 renderedWork._debugHookTypes = hookTypesDev;
12980 }
12981
12982 // This check uses currentHook so that it works the same in DEV and prod bundles.
12983 // hookTypesDev could catch more cases (e.g. context) but only in DEV bundles.
12984 var didRenderTooFewHooks = currentHook !== null && currentHook.next !== null;
12985
12986 renderExpirationTime = NoWork;
12987 currentlyRenderingFiber$1 = null;
12988
12989 currentHook = null;
12990 nextCurrentHook = null;
12991 firstWorkInProgressHook = null;
12992 workInProgressHook = null;
12993 nextWorkInProgressHook = null;
12994
12995 {
12996 currentHookNameInDev = null;
12997 hookTypesDev = null;
12998 hookTypesUpdateIndexDev = -1;
12999 }
13000
13001 remainingExpirationTime = NoWork;
13002 componentUpdateQueue = null;
13003 sideEffectTag = 0;
13004
13005 // These were reset above
13006 // didScheduleRenderPhaseUpdate = false;
13007 // renderPhaseUpdates = null;
13008 // numberOfReRenders = 0;
13009
13010 !!didRenderTooFewHooks ? invariant(false, 'Rendered fewer hooks than expected. This may be caused by an accidental early return statement.') : void 0;
13011
13012 return children;
13013}
13014
13015function bailoutHooks(current, workInProgress, expirationTime) {
13016 workInProgress.updateQueue = current.updateQueue;
13017 workInProgress.effectTag &= ~(Passive | Update);
13018 if (current.expirationTime <= expirationTime) {
13019 current.expirationTime = NoWork;
13020 }
13021}
13022
13023function resetHooks() {
13024 // We can assume the previous dispatcher is always this one, since we set it
13025 // at the beginning of the render phase and there's no re-entrancy.
13026 ReactCurrentDispatcher$1.current = ContextOnlyDispatcher;
13027
13028 // This is used to reset the state of this module when a component throws.
13029 // It's also called inside mountIndeterminateComponent if we determine the
13030 // component is a module-style component.
13031 renderExpirationTime = NoWork;
13032 currentlyRenderingFiber$1 = null;
13033
13034 currentHook = null;
13035 nextCurrentHook = null;
13036 firstWorkInProgressHook = null;
13037 workInProgressHook = null;
13038 nextWorkInProgressHook = null;
13039
13040 {
13041 hookTypesDev = null;
13042 hookTypesUpdateIndexDev = -1;
13043
13044 currentHookNameInDev = null;
13045 }
13046
13047 remainingExpirationTime = NoWork;
13048 componentUpdateQueue = null;
13049 sideEffectTag = 0;
13050
13051 didScheduleRenderPhaseUpdate = false;
13052 renderPhaseUpdates = null;
13053 numberOfReRenders = 0;
13054}
13055
13056function mountWorkInProgressHook() {
13057 var hook = {
13058 memoizedState: null,
13059
13060 baseState: null,
13061 queue: null,
13062 baseUpdate: null,
13063
13064 next: null
13065 };
13066
13067 if (workInProgressHook === null) {
13068 // This is the first hook in the list
13069 firstWorkInProgressHook = workInProgressHook = hook;
13070 } else {
13071 // Append to the end of the list
13072 workInProgressHook = workInProgressHook.next = hook;
13073 }
13074 return workInProgressHook;
13075}
13076
13077function updateWorkInProgressHook() {
13078 // This function is used both for updates and for re-renders triggered by a
13079 // render phase update. It assumes there is either a current hook we can
13080 // clone, or a work-in-progress hook from a previous render pass that we can
13081 // use as a base. When we reach the end of the base list, we must switch to
13082 // the dispatcher used for mounts.
13083 if (nextWorkInProgressHook !== null) {
13084 // There's already a work-in-progress. Reuse it.
13085 workInProgressHook = nextWorkInProgressHook;
13086 nextWorkInProgressHook = workInProgressHook.next;
13087
13088 currentHook = nextCurrentHook;
13089 nextCurrentHook = currentHook !== null ? currentHook.next : null;
13090 } else {
13091 // Clone from the current hook.
13092 !(nextCurrentHook !== null) ? invariant(false, 'Rendered more hooks than during the previous render.') : void 0;
13093 currentHook = nextCurrentHook;
13094
13095 var newHook = {
13096 memoizedState: currentHook.memoizedState,
13097
13098 baseState: currentHook.baseState,
13099 queue: currentHook.queue,
13100 baseUpdate: currentHook.baseUpdate,
13101
13102 next: null
13103 };
13104
13105 if (workInProgressHook === null) {
13106 // This is the first hook in the list.
13107 workInProgressHook = firstWorkInProgressHook = newHook;
13108 } else {
13109 // Append to the end of the list.
13110 workInProgressHook = workInProgressHook.next = newHook;
13111 }
13112 nextCurrentHook = currentHook.next;
13113 }
13114 return workInProgressHook;
13115}
13116
13117function createFunctionComponentUpdateQueue() {
13118 return {
13119 lastEffect: null
13120 };
13121}
13122
13123function basicStateReducer(state, action) {
13124 return typeof action === 'function' ? action(state) : action;
13125}
13126
13127function mountReducer(reducer, initialArg, init) {
13128 var hook = mountWorkInProgressHook();
13129 var initialState = void 0;
13130 if (init !== undefined) {
13131 initialState = init(initialArg);
13132 } else {
13133 initialState = initialArg;
13134 }
13135 hook.memoizedState = hook.baseState = initialState;
13136 var queue = hook.queue = {
13137 last: null,
13138 dispatch: null,
13139 lastRenderedReducer: reducer,
13140 lastRenderedState: initialState
13141 };
13142 var dispatch = queue.dispatch = dispatchAction.bind(null,
13143 // Flow doesn't know this is non-null, but we do.
13144 currentlyRenderingFiber$1, queue);
13145 return [hook.memoizedState, dispatch];
13146}
13147
13148function updateReducer(reducer, initialArg, init) {
13149 var hook = updateWorkInProgressHook();
13150 var queue = hook.queue;
13151 !(queue !== null) ? invariant(false, 'Should have a queue. This is likely a bug in React. Please file an issue.') : void 0;
13152
13153 queue.lastRenderedReducer = reducer;
13154
13155 if (numberOfReRenders > 0) {
13156 // This is a re-render. Apply the new render phase updates to the previous
13157 var _dispatch = queue.dispatch;
13158 if (renderPhaseUpdates !== null) {
13159 // Render phase updates are stored in a map of queue -> linked list
13160 var firstRenderPhaseUpdate = renderPhaseUpdates.get(queue);
13161 if (firstRenderPhaseUpdate !== undefined) {
13162 renderPhaseUpdates.delete(queue);
13163 var newState = hook.memoizedState;
13164 var update = firstRenderPhaseUpdate;
13165 do {
13166 // Process this render phase update. We don't have to check the
13167 // priority because it will always be the same as the current
13168 // render's.
13169 var _action = update.action;
13170 newState = reducer(newState, _action);
13171 update = update.next;
13172 } while (update !== null);
13173
13174 // Mark that the fiber performed work, but only if the new state is
13175 // different from the current state.
13176 if (!is(newState, hook.memoizedState)) {
13177 markWorkInProgressReceivedUpdate();
13178 }
13179
13180 hook.memoizedState = newState;
13181 // Don't persist the state accumlated from the render phase updates to
13182 // the base state unless the queue is empty.
13183 // TODO: Not sure if this is the desired semantics, but it's what we
13184 // do for gDSFP. I can't remember why.
13185 if (hook.baseUpdate === queue.last) {
13186 hook.baseState = newState;
13187 }
13188
13189 queue.lastRenderedState = newState;
13190
13191 return [newState, _dispatch];
13192 }
13193 }
13194 return [hook.memoizedState, _dispatch];
13195 }
13196
13197 // The last update in the entire queue
13198 var last = queue.last;
13199 // The last update that is part of the base state.
13200 var baseUpdate = hook.baseUpdate;
13201 var baseState = hook.baseState;
13202
13203 // Find the first unprocessed update.
13204 var first = void 0;
13205 if (baseUpdate !== null) {
13206 if (last !== null) {
13207 // For the first update, the queue is a circular linked list where
13208 // `queue.last.next = queue.first`. Once the first update commits, and
13209 // the `baseUpdate` is no longer empty, we can unravel the list.
13210 last.next = null;
13211 }
13212 first = baseUpdate.next;
13213 } else {
13214 first = last !== null ? last.next : null;
13215 }
13216 if (first !== null) {
13217 var _newState = baseState;
13218 var newBaseState = null;
13219 var newBaseUpdate = null;
13220 var prevUpdate = baseUpdate;
13221 var _update = first;
13222 var didSkip = false;
13223 do {
13224 var updateExpirationTime = _update.expirationTime;
13225 if (updateExpirationTime < renderExpirationTime) {
13226 // Priority is insufficient. Skip this update. If this is the first
13227 // skipped update, the previous update/state is the new base
13228 // update/state.
13229 if (!didSkip) {
13230 didSkip = true;
13231 newBaseUpdate = prevUpdate;
13232 newBaseState = _newState;
13233 }
13234 // Update the remaining priority in the queue.
13235 if (updateExpirationTime > remainingExpirationTime) {
13236 remainingExpirationTime = updateExpirationTime;
13237 }
13238 } else {
13239 // Process this update.
13240 if (_update.eagerReducer === reducer) {
13241 // If this update was processed eagerly, and its reducer matches the
13242 // current reducer, we can use the eagerly computed state.
13243 _newState = _update.eagerState;
13244 } else {
13245 var _action2 = _update.action;
13246 _newState = reducer(_newState, _action2);
13247 }
13248 }
13249 prevUpdate = _update;
13250 _update = _update.next;
13251 } while (_update !== null && _update !== first);
13252
13253 if (!didSkip) {
13254 newBaseUpdate = prevUpdate;
13255 newBaseState = _newState;
13256 }
13257
13258 // Mark that the fiber performed work, but only if the new state is
13259 // different from the current state.
13260 if (!is(_newState, hook.memoizedState)) {
13261 markWorkInProgressReceivedUpdate();
13262 }
13263
13264 hook.memoizedState = _newState;
13265 hook.baseUpdate = newBaseUpdate;
13266 hook.baseState = newBaseState;
13267
13268 queue.lastRenderedState = _newState;
13269 }
13270
13271 var dispatch = queue.dispatch;
13272 return [hook.memoizedState, dispatch];
13273}
13274
13275function mountState(initialState) {
13276 var hook = mountWorkInProgressHook();
13277 if (typeof initialState === 'function') {
13278 initialState = initialState();
13279 }
13280 hook.memoizedState = hook.baseState = initialState;
13281 var queue = hook.queue = {
13282 last: null,
13283 dispatch: null,
13284 lastRenderedReducer: basicStateReducer,
13285 lastRenderedState: initialState
13286 };
13287 var dispatch = queue.dispatch = dispatchAction.bind(null,
13288 // Flow doesn't know this is non-null, but we do.
13289 currentlyRenderingFiber$1, queue);
13290 return [hook.memoizedState, dispatch];
13291}
13292
13293function updateState(initialState) {
13294 return updateReducer(basicStateReducer, initialState);
13295}
13296
13297function pushEffect(tag, create, destroy, deps) {
13298 var effect = {
13299 tag: tag,
13300 create: create,
13301 destroy: destroy,
13302 deps: deps,
13303 // Circular
13304 next: null
13305 };
13306 if (componentUpdateQueue === null) {
13307 componentUpdateQueue = createFunctionComponentUpdateQueue();
13308 componentUpdateQueue.lastEffect = effect.next = effect;
13309 } else {
13310 var _lastEffect = componentUpdateQueue.lastEffect;
13311 if (_lastEffect === null) {
13312 componentUpdateQueue.lastEffect = effect.next = effect;
13313 } else {
13314 var firstEffect = _lastEffect.next;
13315 _lastEffect.next = effect;
13316 effect.next = firstEffect;
13317 componentUpdateQueue.lastEffect = effect;
13318 }
13319 }
13320 return effect;
13321}
13322
13323function mountRef(initialValue) {
13324 var hook = mountWorkInProgressHook();
13325 var ref = { current: initialValue };
13326 {
13327 Object.seal(ref);
13328 }
13329 hook.memoizedState = ref;
13330 return ref;
13331}
13332
13333function updateRef(initialValue) {
13334 var hook = updateWorkInProgressHook();
13335 return hook.memoizedState;
13336}
13337
13338function mountEffectImpl(fiberEffectTag, hookEffectTag, create, deps) {
13339 var hook = mountWorkInProgressHook();
13340 var nextDeps = deps === undefined ? null : deps;
13341 sideEffectTag |= fiberEffectTag;
13342 hook.memoizedState = pushEffect(hookEffectTag, create, undefined, nextDeps);
13343}
13344
13345function updateEffectImpl(fiberEffectTag, hookEffectTag, create, deps) {
13346 var hook = updateWorkInProgressHook();
13347 var nextDeps = deps === undefined ? null : deps;
13348 var destroy = undefined;
13349
13350 if (currentHook !== null) {
13351 var prevEffect = currentHook.memoizedState;
13352 destroy = prevEffect.destroy;
13353 if (nextDeps !== null) {
13354 var prevDeps = prevEffect.deps;
13355 if (areHookInputsEqual(nextDeps, prevDeps)) {
13356 pushEffect(NoEffect$1, create, destroy, nextDeps);
13357 return;
13358 }
13359 }
13360 }
13361
13362 sideEffectTag |= fiberEffectTag;
13363 hook.memoizedState = pushEffect(hookEffectTag, create, destroy, nextDeps);
13364}
13365
13366function mountEffect(create, deps) {
13367 return mountEffectImpl(Update | Passive, UnmountPassive | MountPassive, create, deps);
13368}
13369
13370function updateEffect(create, deps) {
13371 return updateEffectImpl(Update | Passive, UnmountPassive | MountPassive, create, deps);
13372}
13373
13374function mountLayoutEffect(create, deps) {
13375 return mountEffectImpl(Update, UnmountMutation | MountLayout, create, deps);
13376}
13377
13378function updateLayoutEffect(create, deps) {
13379 return updateEffectImpl(Update, UnmountMutation | MountLayout, create, deps);
13380}
13381
13382function imperativeHandleEffect(create, ref) {
13383 if (typeof ref === 'function') {
13384 var refCallback = ref;
13385 var _inst = create();
13386 refCallback(_inst);
13387 return function () {
13388 refCallback(null);
13389 };
13390 } else if (ref !== null && ref !== undefined) {
13391 var refObject = ref;
13392 {
13393 !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;
13394 }
13395 var _inst2 = create();
13396 refObject.current = _inst2;
13397 return function () {
13398 refObject.current = null;
13399 };
13400 }
13401}
13402
13403function mountImperativeHandle(ref, create, deps) {
13404 {
13405 !(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;
13406 }
13407
13408 // TODO: If deps are provided, should we skip comparing the ref itself?
13409 var effectDeps = deps !== null && deps !== undefined ? deps.concat([ref]) : null;
13410
13411 return mountEffectImpl(Update, UnmountMutation | MountLayout, imperativeHandleEffect.bind(null, create, ref), effectDeps);
13412}
13413
13414function updateImperativeHandle(ref, create, deps) {
13415 {
13416 !(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;
13417 }
13418
13419 // TODO: If deps are provided, should we skip comparing the ref itself?
13420 var effectDeps = deps !== null && deps !== undefined ? deps.concat([ref]) : null;
13421
13422 return updateEffectImpl(Update, UnmountMutation | MountLayout, imperativeHandleEffect.bind(null, create, ref), effectDeps);
13423}
13424
13425function mountDebugValue(value, formatterFn) {
13426 // This hook is normally a no-op.
13427 // The react-debug-hooks package injects its own implementation
13428 // so that e.g. DevTools can display custom hook values.
13429}
13430
13431var updateDebugValue = mountDebugValue;
13432
13433function mountCallback(callback, deps) {
13434 var hook = mountWorkInProgressHook();
13435 var nextDeps = deps === undefined ? null : deps;
13436 hook.memoizedState = [callback, nextDeps];
13437 return callback;
13438}
13439
13440function updateCallback(callback, deps) {
13441 var hook = updateWorkInProgressHook();
13442 var nextDeps = deps === undefined ? null : deps;
13443 var prevState = hook.memoizedState;
13444 if (prevState !== null) {
13445 if (nextDeps !== null) {
13446 var prevDeps = prevState[1];
13447 if (areHookInputsEqual(nextDeps, prevDeps)) {
13448 return prevState[0];
13449 }
13450 }
13451 }
13452 hook.memoizedState = [callback, nextDeps];
13453 return callback;
13454}
13455
13456function mountMemo(nextCreate, deps) {
13457 var hook = mountWorkInProgressHook();
13458 var nextDeps = deps === undefined ? null : deps;
13459 var nextValue = nextCreate();
13460 hook.memoizedState = [nextValue, nextDeps];
13461 return nextValue;
13462}
13463
13464function updateMemo(nextCreate, deps) {
13465 var hook = updateWorkInProgressHook();
13466 var nextDeps = deps === undefined ? null : deps;
13467 var prevState = hook.memoizedState;
13468 if (prevState !== null) {
13469 // Assume these are defined. If they're not, areHookInputsEqual will warn.
13470 if (nextDeps !== null) {
13471 var prevDeps = prevState[1];
13472 if (areHookInputsEqual(nextDeps, prevDeps)) {
13473 return prevState[0];
13474 }
13475 }
13476 }
13477 var nextValue = nextCreate();
13478 hook.memoizedState = [nextValue, nextDeps];
13479 return nextValue;
13480}
13481
13482// in a test-like environment, we want to warn if dispatchAction()
13483// is called outside of a batchedUpdates/TestUtils.act(...) call.
13484var shouldWarnForUnbatchedSetState = false;
13485
13486{
13487 // jest isn't a 'global', it's just exposed to tests via a wrapped function
13488 // further, this isn't a test file, so flow doesn't recognize the symbol. So...
13489 // $FlowExpectedError - because requirements don't give a damn about your type sigs.
13490 if ('undefined' !== typeof jest) {
13491 shouldWarnForUnbatchedSetState = true;
13492 }
13493}
13494
13495function dispatchAction(fiber, queue, action) {
13496 !(numberOfReRenders < RE_RENDER_LIMIT) ? invariant(false, 'Too many re-renders. React limits the number of renders to prevent an infinite loop.') : void 0;
13497
13498 {
13499 !(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;
13500 }
13501
13502 var alternate = fiber.alternate;
13503 if (fiber === currentlyRenderingFiber$1 || alternate !== null && alternate === currentlyRenderingFiber$1) {
13504 // This is a render phase update. Stash it in a lazily-created map of
13505 // queue -> linked list of updates. After this render pass, we'll restart
13506 // and apply the stashed updates on top of the work-in-progress hook.
13507 didScheduleRenderPhaseUpdate = true;
13508 var update = {
13509 expirationTime: renderExpirationTime,
13510 action: action,
13511 eagerReducer: null,
13512 eagerState: null,
13513 next: null
13514 };
13515 if (renderPhaseUpdates === null) {
13516 renderPhaseUpdates = new Map();
13517 }
13518 var firstRenderPhaseUpdate = renderPhaseUpdates.get(queue);
13519 if (firstRenderPhaseUpdate === undefined) {
13520 renderPhaseUpdates.set(queue, update);
13521 } else {
13522 // Append the update to the end of the list.
13523 var lastRenderPhaseUpdate = firstRenderPhaseUpdate;
13524 while (lastRenderPhaseUpdate.next !== null) {
13525 lastRenderPhaseUpdate = lastRenderPhaseUpdate.next;
13526 }
13527 lastRenderPhaseUpdate.next = update;
13528 }
13529 } else {
13530 flushPassiveEffects();
13531
13532 var currentTime = requestCurrentTime();
13533 var _expirationTime = computeExpirationForFiber(currentTime, fiber);
13534
13535 var _update2 = {
13536 expirationTime: _expirationTime,
13537 action: action,
13538 eagerReducer: null,
13539 eagerState: null,
13540 next: null
13541 };
13542
13543 // Append the update to the end of the list.
13544 var _last = queue.last;
13545 if (_last === null) {
13546 // This is the first update. Create a circular list.
13547 _update2.next = _update2;
13548 } else {
13549 var first = _last.next;
13550 if (first !== null) {
13551 // Still circular.
13552 _update2.next = first;
13553 }
13554 _last.next = _update2;
13555 }
13556 queue.last = _update2;
13557
13558 if (fiber.expirationTime === NoWork && (alternate === null || alternate.expirationTime === NoWork)) {
13559 // The queue is currently empty, which means we can eagerly compute the
13560 // next state before entering the render phase. If the new state is the
13561 // same as the current state, we may be able to bail out entirely.
13562 var _lastRenderedReducer = queue.lastRenderedReducer;
13563 if (_lastRenderedReducer !== null) {
13564 var prevDispatcher = void 0;
13565 {
13566 prevDispatcher = ReactCurrentDispatcher$1.current;
13567 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
13568 }
13569 try {
13570 var currentState = queue.lastRenderedState;
13571 var _eagerState = _lastRenderedReducer(currentState, action);
13572 // Stash the eagerly computed state, and the reducer used to compute
13573 // it, on the update object. If the reducer hasn't changed by the
13574 // time we enter the render phase, then the eager state can be used
13575 // without calling the reducer again.
13576 _update2.eagerReducer = _lastRenderedReducer;
13577 _update2.eagerState = _eagerState;
13578 if (is(_eagerState, currentState)) {
13579 // Fast path. We can bail out without scheduling React to re-render.
13580 // It's still possible that we'll need to rebase this update later,
13581 // if the component re-renders for a different reason and by that
13582 // time the reducer has changed.
13583 return;
13584 }
13585 } catch (error) {
13586 // Suppress the error. It will throw again in the render phase.
13587 } finally {
13588 {
13589 ReactCurrentDispatcher$1.current = prevDispatcher;
13590 }
13591 }
13592 }
13593 }
13594 {
13595 if (shouldWarnForUnbatchedSetState === true) {
13596 warnIfNotCurrentlyBatchingInDev(fiber);
13597 }
13598 }
13599 scheduleWork(fiber, _expirationTime);
13600 }
13601}
13602
13603var ContextOnlyDispatcher = {
13604 readContext: readContext,
13605
13606 useCallback: throwInvalidHookError,
13607 useContext: throwInvalidHookError,
13608 useEffect: throwInvalidHookError,
13609 useImperativeHandle: throwInvalidHookError,
13610 useLayoutEffect: throwInvalidHookError,
13611 useMemo: throwInvalidHookError,
13612 useReducer: throwInvalidHookError,
13613 useRef: throwInvalidHookError,
13614 useState: throwInvalidHookError,
13615 useDebugValue: throwInvalidHookError
13616};
13617
13618var HooksDispatcherOnMountInDEV = null;
13619var HooksDispatcherOnMountWithHookTypesInDEV = null;
13620var HooksDispatcherOnUpdateInDEV = null;
13621var InvalidNestedHooksDispatcherOnMountInDEV = null;
13622var InvalidNestedHooksDispatcherOnUpdateInDEV = null;
13623
13624{
13625 var warnInvalidContextAccess = function () {
13626 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().');
13627 };
13628
13629 var warnInvalidHookAccess = function () {
13630 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');
13631 };
13632
13633 HooksDispatcherOnMountInDEV = {
13634 readContext: function (context, observedBits) {
13635 return readContext(context, observedBits);
13636 },
13637 useCallback: function (callback, deps) {
13638 currentHookNameInDev = 'useCallback';
13639 mountHookTypesDev();
13640 return mountCallback(callback, deps);
13641 },
13642 useContext: function (context, observedBits) {
13643 currentHookNameInDev = 'useContext';
13644 mountHookTypesDev();
13645 return readContext(context, observedBits);
13646 },
13647 useEffect: function (create, deps) {
13648 currentHookNameInDev = 'useEffect';
13649 mountHookTypesDev();
13650 return mountEffect(create, deps);
13651 },
13652 useImperativeHandle: function (ref, create, deps) {
13653 currentHookNameInDev = 'useImperativeHandle';
13654 mountHookTypesDev();
13655 return mountImperativeHandle(ref, create, deps);
13656 },
13657 useLayoutEffect: function (create, deps) {
13658 currentHookNameInDev = 'useLayoutEffect';
13659 mountHookTypesDev();
13660 return mountLayoutEffect(create, deps);
13661 },
13662 useMemo: function (create, deps) {
13663 currentHookNameInDev = 'useMemo';
13664 mountHookTypesDev();
13665 var prevDispatcher = ReactCurrentDispatcher$1.current;
13666 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
13667 try {
13668 return mountMemo(create, deps);
13669 } finally {
13670 ReactCurrentDispatcher$1.current = prevDispatcher;
13671 }
13672 },
13673 useReducer: function (reducer, initialArg, init) {
13674 currentHookNameInDev = 'useReducer';
13675 mountHookTypesDev();
13676 var prevDispatcher = ReactCurrentDispatcher$1.current;
13677 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
13678 try {
13679 return mountReducer(reducer, initialArg, init);
13680 } finally {
13681 ReactCurrentDispatcher$1.current = prevDispatcher;
13682 }
13683 },
13684 useRef: function (initialValue) {
13685 currentHookNameInDev = 'useRef';
13686 mountHookTypesDev();
13687 return mountRef(initialValue);
13688 },
13689 useState: function (initialState) {
13690 currentHookNameInDev = 'useState';
13691 mountHookTypesDev();
13692 var prevDispatcher = ReactCurrentDispatcher$1.current;
13693 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
13694 try {
13695 return mountState(initialState);
13696 } finally {
13697 ReactCurrentDispatcher$1.current = prevDispatcher;
13698 }
13699 },
13700 useDebugValue: function (value, formatterFn) {
13701 currentHookNameInDev = 'useDebugValue';
13702 mountHookTypesDev();
13703 return mountDebugValue(value, formatterFn);
13704 }
13705 };
13706
13707 HooksDispatcherOnMountWithHookTypesInDEV = {
13708 readContext: function (context, observedBits) {
13709 return readContext(context, observedBits);
13710 },
13711 useCallback: function (callback, deps) {
13712 currentHookNameInDev = 'useCallback';
13713 updateHookTypesDev();
13714 return mountCallback(callback, deps);
13715 },
13716 useContext: function (context, observedBits) {
13717 currentHookNameInDev = 'useContext';
13718 updateHookTypesDev();
13719 return readContext(context, observedBits);
13720 },
13721 useEffect: function (create, deps) {
13722 currentHookNameInDev = 'useEffect';
13723 updateHookTypesDev();
13724 return mountEffect(create, deps);
13725 },
13726 useImperativeHandle: function (ref, create, deps) {
13727 currentHookNameInDev = 'useImperativeHandle';
13728 updateHookTypesDev();
13729 return mountImperativeHandle(ref, create, deps);
13730 },
13731 useLayoutEffect: function (create, deps) {
13732 currentHookNameInDev = 'useLayoutEffect';
13733 updateHookTypesDev();
13734 return mountLayoutEffect(create, deps);
13735 },
13736 useMemo: function (create, deps) {
13737 currentHookNameInDev = 'useMemo';
13738 updateHookTypesDev();
13739 var prevDispatcher = ReactCurrentDispatcher$1.current;
13740 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
13741 try {
13742 return mountMemo(create, deps);
13743 } finally {
13744 ReactCurrentDispatcher$1.current = prevDispatcher;
13745 }
13746 },
13747 useReducer: function (reducer, initialArg, init) {
13748 currentHookNameInDev = 'useReducer';
13749 updateHookTypesDev();
13750 var prevDispatcher = ReactCurrentDispatcher$1.current;
13751 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
13752 try {
13753 return mountReducer(reducer, initialArg, init);
13754 } finally {
13755 ReactCurrentDispatcher$1.current = prevDispatcher;
13756 }
13757 },
13758 useRef: function (initialValue) {
13759 currentHookNameInDev = 'useRef';
13760 updateHookTypesDev();
13761 return mountRef(initialValue);
13762 },
13763 useState: function (initialState) {
13764 currentHookNameInDev = 'useState';
13765 updateHookTypesDev();
13766 var prevDispatcher = ReactCurrentDispatcher$1.current;
13767 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
13768 try {
13769 return mountState(initialState);
13770 } finally {
13771 ReactCurrentDispatcher$1.current = prevDispatcher;
13772 }
13773 },
13774 useDebugValue: function (value, formatterFn) {
13775 currentHookNameInDev = 'useDebugValue';
13776 updateHookTypesDev();
13777 return mountDebugValue(value, formatterFn);
13778 }
13779 };
13780
13781 HooksDispatcherOnUpdateInDEV = {
13782 readContext: function (context, observedBits) {
13783 return readContext(context, observedBits);
13784 },
13785 useCallback: function (callback, deps) {
13786 currentHookNameInDev = 'useCallback';
13787 updateHookTypesDev();
13788 return updateCallback(callback, deps);
13789 },
13790 useContext: function (context, observedBits) {
13791 currentHookNameInDev = 'useContext';
13792 updateHookTypesDev();
13793 return readContext(context, observedBits);
13794 },
13795 useEffect: function (create, deps) {
13796 currentHookNameInDev = 'useEffect';
13797 updateHookTypesDev();
13798 return updateEffect(create, deps);
13799 },
13800 useImperativeHandle: function (ref, create, deps) {
13801 currentHookNameInDev = 'useImperativeHandle';
13802 updateHookTypesDev();
13803 return updateImperativeHandle(ref, create, deps);
13804 },
13805 useLayoutEffect: function (create, deps) {
13806 currentHookNameInDev = 'useLayoutEffect';
13807 updateHookTypesDev();
13808 return updateLayoutEffect(create, deps);
13809 },
13810 useMemo: function (create, deps) {
13811 currentHookNameInDev = 'useMemo';
13812 updateHookTypesDev();
13813 var prevDispatcher = ReactCurrentDispatcher$1.current;
13814 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
13815 try {
13816 return updateMemo(create, deps);
13817 } finally {
13818 ReactCurrentDispatcher$1.current = prevDispatcher;
13819 }
13820 },
13821 useReducer: function (reducer, initialArg, init) {
13822 currentHookNameInDev = 'useReducer';
13823 updateHookTypesDev();
13824 var prevDispatcher = ReactCurrentDispatcher$1.current;
13825 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
13826 try {
13827 return updateReducer(reducer, initialArg, init);
13828 } finally {
13829 ReactCurrentDispatcher$1.current = prevDispatcher;
13830 }
13831 },
13832 useRef: function (initialValue) {
13833 currentHookNameInDev = 'useRef';
13834 updateHookTypesDev();
13835 return updateRef(initialValue);
13836 },
13837 useState: function (initialState) {
13838 currentHookNameInDev = 'useState';
13839 updateHookTypesDev();
13840 var prevDispatcher = ReactCurrentDispatcher$1.current;
13841 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
13842 try {
13843 return updateState(initialState);
13844 } finally {
13845 ReactCurrentDispatcher$1.current = prevDispatcher;
13846 }
13847 },
13848 useDebugValue: function (value, formatterFn) {
13849 currentHookNameInDev = 'useDebugValue';
13850 updateHookTypesDev();
13851 return updateDebugValue(value, formatterFn);
13852 }
13853 };
13854
13855 InvalidNestedHooksDispatcherOnMountInDEV = {
13856 readContext: function (context, observedBits) {
13857 warnInvalidContextAccess();
13858 return readContext(context, observedBits);
13859 },
13860 useCallback: function (callback, deps) {
13861 currentHookNameInDev = 'useCallback';
13862 warnInvalidHookAccess();
13863 mountHookTypesDev();
13864 return mountCallback(callback, deps);
13865 },
13866 useContext: function (context, observedBits) {
13867 currentHookNameInDev = 'useContext';
13868 warnInvalidHookAccess();
13869 mountHookTypesDev();
13870 return readContext(context, observedBits);
13871 },
13872 useEffect: function (create, deps) {
13873 currentHookNameInDev = 'useEffect';
13874 warnInvalidHookAccess();
13875 mountHookTypesDev();
13876 return mountEffect(create, deps);
13877 },
13878 useImperativeHandle: function (ref, create, deps) {
13879 currentHookNameInDev = 'useImperativeHandle';
13880 warnInvalidHookAccess();
13881 mountHookTypesDev();
13882 return mountImperativeHandle(ref, create, deps);
13883 },
13884 useLayoutEffect: function (create, deps) {
13885 currentHookNameInDev = 'useLayoutEffect';
13886 warnInvalidHookAccess();
13887 mountHookTypesDev();
13888 return mountLayoutEffect(create, deps);
13889 },
13890 useMemo: function (create, deps) {
13891 currentHookNameInDev = 'useMemo';
13892 warnInvalidHookAccess();
13893 mountHookTypesDev();
13894 var prevDispatcher = ReactCurrentDispatcher$1.current;
13895 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
13896 try {
13897 return mountMemo(create, deps);
13898 } finally {
13899 ReactCurrentDispatcher$1.current = prevDispatcher;
13900 }
13901 },
13902 useReducer: function (reducer, initialArg, init) {
13903 currentHookNameInDev = 'useReducer';
13904 warnInvalidHookAccess();
13905 mountHookTypesDev();
13906 var prevDispatcher = ReactCurrentDispatcher$1.current;
13907 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
13908 try {
13909 return mountReducer(reducer, initialArg, init);
13910 } finally {
13911 ReactCurrentDispatcher$1.current = prevDispatcher;
13912 }
13913 },
13914 useRef: function (initialValue) {
13915 currentHookNameInDev = 'useRef';
13916 warnInvalidHookAccess();
13917 mountHookTypesDev();
13918 return mountRef(initialValue);
13919 },
13920 useState: function (initialState) {
13921 currentHookNameInDev = 'useState';
13922 warnInvalidHookAccess();
13923 mountHookTypesDev();
13924 var prevDispatcher = ReactCurrentDispatcher$1.current;
13925 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
13926 try {
13927 return mountState(initialState);
13928 } finally {
13929 ReactCurrentDispatcher$1.current = prevDispatcher;
13930 }
13931 },
13932 useDebugValue: function (value, formatterFn) {
13933 currentHookNameInDev = 'useDebugValue';
13934 warnInvalidHookAccess();
13935 mountHookTypesDev();
13936 return mountDebugValue(value, formatterFn);
13937 }
13938 };
13939
13940 InvalidNestedHooksDispatcherOnUpdateInDEV = {
13941 readContext: function (context, observedBits) {
13942 warnInvalidContextAccess();
13943 return readContext(context, observedBits);
13944 },
13945 useCallback: function (callback, deps) {
13946 currentHookNameInDev = 'useCallback';
13947 warnInvalidHookAccess();
13948 updateHookTypesDev();
13949 return updateCallback(callback, deps);
13950 },
13951 useContext: function (context, observedBits) {
13952 currentHookNameInDev = 'useContext';
13953 warnInvalidHookAccess();
13954 updateHookTypesDev();
13955 return readContext(context, observedBits);
13956 },
13957 useEffect: function (create, deps) {
13958 currentHookNameInDev = 'useEffect';
13959 warnInvalidHookAccess();
13960 updateHookTypesDev();
13961 return updateEffect(create, deps);
13962 },
13963 useImperativeHandle: function (ref, create, deps) {
13964 currentHookNameInDev = 'useImperativeHandle';
13965 warnInvalidHookAccess();
13966 updateHookTypesDev();
13967 return updateImperativeHandle(ref, create, deps);
13968 },
13969 useLayoutEffect: function (create, deps) {
13970 currentHookNameInDev = 'useLayoutEffect';
13971 warnInvalidHookAccess();
13972 updateHookTypesDev();
13973 return updateLayoutEffect(create, deps);
13974 },
13975 useMemo: function (create, deps) {
13976 currentHookNameInDev = 'useMemo';
13977 warnInvalidHookAccess();
13978 updateHookTypesDev();
13979 var prevDispatcher = ReactCurrentDispatcher$1.current;
13980 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
13981 try {
13982 return updateMemo(create, deps);
13983 } finally {
13984 ReactCurrentDispatcher$1.current = prevDispatcher;
13985 }
13986 },
13987 useReducer: function (reducer, initialArg, init) {
13988 currentHookNameInDev = 'useReducer';
13989 warnInvalidHookAccess();
13990 updateHookTypesDev();
13991 var prevDispatcher = ReactCurrentDispatcher$1.current;
13992 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
13993 try {
13994 return updateReducer(reducer, initialArg, init);
13995 } finally {
13996 ReactCurrentDispatcher$1.current = prevDispatcher;
13997 }
13998 },
13999 useRef: function (initialValue) {
14000 currentHookNameInDev = 'useRef';
14001 warnInvalidHookAccess();
14002 updateHookTypesDev();
14003 return updateRef(initialValue);
14004 },
14005 useState: function (initialState) {
14006 currentHookNameInDev = 'useState';
14007 warnInvalidHookAccess();
14008 updateHookTypesDev();
14009 var prevDispatcher = ReactCurrentDispatcher$1.current;
14010 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
14011 try {
14012 return updateState(initialState);
14013 } finally {
14014 ReactCurrentDispatcher$1.current = prevDispatcher;
14015 }
14016 },
14017 useDebugValue: function (value, formatterFn) {
14018 currentHookNameInDev = 'useDebugValue';
14019 warnInvalidHookAccess();
14020 updateHookTypesDev();
14021 return updateDebugValue(value, formatterFn);
14022 }
14023 };
14024}
14025
14026var commitTime = 0;
14027var profilerStartTime = -1;
14028
14029function getCommitTime() {
14030 return commitTime;
14031}
14032
14033function recordCommitTime() {
14034 if (!enableProfilerTimer) {
14035 return;
14036 }
14037 commitTime = scheduler.unstable_now();
14038}
14039
14040function startProfilerTimer(fiber) {
14041 if (!enableProfilerTimer) {
14042 return;
14043 }
14044
14045 profilerStartTime = scheduler.unstable_now();
14046
14047 if (fiber.actualStartTime < 0) {
14048 fiber.actualStartTime = scheduler.unstable_now();
14049 }
14050}
14051
14052function stopProfilerTimerIfRunning(fiber) {
14053 if (!enableProfilerTimer) {
14054 return;
14055 }
14056 profilerStartTime = -1;
14057}
14058
14059function stopProfilerTimerIfRunningAndRecordDelta(fiber, overrideBaseTime) {
14060 if (!enableProfilerTimer) {
14061 return;
14062 }
14063
14064 if (profilerStartTime >= 0) {
14065 var elapsedTime = scheduler.unstable_now() - profilerStartTime;
14066 fiber.actualDuration += elapsedTime;
14067 if (overrideBaseTime) {
14068 fiber.selfBaseDuration = elapsedTime;
14069 }
14070 profilerStartTime = -1;
14071 }
14072}
14073
14074// The deepest Fiber on the stack involved in a hydration context.
14075// This may have been an insertion or a hydration.
14076var hydrationParentFiber = null;
14077var nextHydratableInstance = null;
14078var isHydrating = false;
14079
14080function enterHydrationState(fiber) {
14081 if (!supportsHydration) {
14082 return false;
14083 }
14084
14085 var parentInstance = fiber.stateNode.containerInfo;
14086 nextHydratableInstance = getFirstHydratableChild(parentInstance);
14087 hydrationParentFiber = fiber;
14088 isHydrating = true;
14089 return true;
14090}
14091
14092function reenterHydrationStateFromDehydratedSuspenseInstance(fiber) {
14093 if (!supportsHydration) {
14094 return false;
14095 }
14096
14097 var suspenseInstance = fiber.stateNode;
14098 nextHydratableInstance = getNextHydratableSibling(suspenseInstance);
14099 popToNextHostParent(fiber);
14100 isHydrating = true;
14101 return true;
14102}
14103
14104function deleteHydratableInstance(returnFiber, instance) {
14105 {
14106 switch (returnFiber.tag) {
14107 case HostRoot:
14108 didNotHydrateContainerInstance(returnFiber.stateNode.containerInfo, instance);
14109 break;
14110 case HostComponent:
14111 didNotHydrateInstance(returnFiber.type, returnFiber.memoizedProps, returnFiber.stateNode, instance);
14112 break;
14113 }
14114 }
14115
14116 var childToDelete = createFiberFromHostInstanceForDeletion();
14117 childToDelete.stateNode = instance;
14118 childToDelete.return = returnFiber;
14119 childToDelete.effectTag = Deletion;
14120
14121 // This might seem like it belongs on progressedFirstDeletion. However,
14122 // these children are not part of the reconciliation list of children.
14123 // Even if we abort and rereconcile the children, that will try to hydrate
14124 // again and the nodes are still in the host tree so these will be
14125 // recreated.
14126 if (returnFiber.lastEffect !== null) {
14127 returnFiber.lastEffect.nextEffect = childToDelete;
14128 returnFiber.lastEffect = childToDelete;
14129 } else {
14130 returnFiber.firstEffect = returnFiber.lastEffect = childToDelete;
14131 }
14132}
14133
14134function insertNonHydratedInstance(returnFiber, fiber) {
14135 fiber.effectTag |= Placement;
14136 {
14137 switch (returnFiber.tag) {
14138 case HostRoot:
14139 {
14140 var parentContainer = returnFiber.stateNode.containerInfo;
14141 switch (fiber.tag) {
14142 case HostComponent:
14143 var type = fiber.type;
14144 var props = fiber.pendingProps;
14145 didNotFindHydratableContainerInstance(parentContainer, type, props);
14146 break;
14147 case HostText:
14148 var text = fiber.pendingProps;
14149 didNotFindHydratableContainerTextInstance(parentContainer, text);
14150 break;
14151 case SuspenseComponent:
14152
14153 break;
14154 }
14155 break;
14156 }
14157 case HostComponent:
14158 {
14159 var parentType = returnFiber.type;
14160 var parentProps = returnFiber.memoizedProps;
14161 var parentInstance = returnFiber.stateNode;
14162 switch (fiber.tag) {
14163 case HostComponent:
14164 var _type = fiber.type;
14165 var _props = fiber.pendingProps;
14166 didNotFindHydratableInstance(parentType, parentProps, parentInstance, _type, _props);
14167 break;
14168 case HostText:
14169 var _text = fiber.pendingProps;
14170 didNotFindHydratableTextInstance(parentType, parentProps, parentInstance, _text);
14171 break;
14172 case SuspenseComponent:
14173 didNotFindHydratableSuspenseInstance(parentType, parentProps, parentInstance);
14174 break;
14175 }
14176 break;
14177 }
14178 default:
14179 return;
14180 }
14181 }
14182}
14183
14184function tryHydrate(fiber, nextInstance) {
14185 switch (fiber.tag) {
14186 case HostComponent:
14187 {
14188 var type = fiber.type;
14189 var props = fiber.pendingProps;
14190 var instance = canHydrateInstance(nextInstance, type, props);
14191 if (instance !== null) {
14192 fiber.stateNode = instance;
14193 return true;
14194 }
14195 return false;
14196 }
14197 case HostText:
14198 {
14199 var text = fiber.pendingProps;
14200 var textInstance = canHydrateTextInstance(nextInstance, text);
14201 if (textInstance !== null) {
14202 fiber.stateNode = textInstance;
14203 return true;
14204 }
14205 return false;
14206 }
14207 case SuspenseComponent:
14208 {
14209 if (enableSuspenseServerRenderer) {
14210 var suspenseInstance = canHydrateSuspenseInstance(nextInstance);
14211 if (suspenseInstance !== null) {
14212 // Downgrade the tag to a dehydrated component until we've hydrated it.
14213 fiber.tag = DehydratedSuspenseComponent;
14214 fiber.stateNode = suspenseInstance;
14215 return true;
14216 }
14217 }
14218 return false;
14219 }
14220 default:
14221 return false;
14222 }
14223}
14224
14225function tryToClaimNextHydratableInstance(fiber) {
14226 if (!isHydrating) {
14227 return;
14228 }
14229 var nextInstance = nextHydratableInstance;
14230 if (!nextInstance) {
14231 // Nothing to hydrate. Make it an insertion.
14232 insertNonHydratedInstance(hydrationParentFiber, fiber);
14233 isHydrating = false;
14234 hydrationParentFiber = fiber;
14235 return;
14236 }
14237 var firstAttemptedInstance = nextInstance;
14238 if (!tryHydrate(fiber, nextInstance)) {
14239 // If we can't hydrate this instance let's try the next one.
14240 // We use this as a heuristic. It's based on intuition and not data so it
14241 // might be flawed or unnecessary.
14242 nextInstance = getNextHydratableSibling(firstAttemptedInstance);
14243 if (!nextInstance || !tryHydrate(fiber, nextInstance)) {
14244 // Nothing to hydrate. Make it an insertion.
14245 insertNonHydratedInstance(hydrationParentFiber, fiber);
14246 isHydrating = false;
14247 hydrationParentFiber = fiber;
14248 return;
14249 }
14250 // We matched the next one, we'll now assume that the first one was
14251 // superfluous and we'll delete it. Since we can't eagerly delete it
14252 // we'll have to schedule a deletion. To do that, this node needs a dummy
14253 // fiber associated with it.
14254 deleteHydratableInstance(hydrationParentFiber, firstAttemptedInstance);
14255 }
14256 hydrationParentFiber = fiber;
14257 nextHydratableInstance = getFirstHydratableChild(nextInstance);
14258}
14259
14260function prepareToHydrateHostInstance(fiber, rootContainerInstance, hostContext) {
14261 if (!supportsHydration) {
14262 invariant(false, 'Expected prepareToHydrateHostInstance() to never be called. This error is likely caused by a bug in React. Please file an issue.');
14263 }
14264
14265 var instance = fiber.stateNode;
14266 var updatePayload = hydrateInstance(instance, fiber.type, fiber.memoizedProps, rootContainerInstance, hostContext, fiber);
14267 // TODO: Type this specific to this type of component.
14268 fiber.updateQueue = updatePayload;
14269 // If the update payload indicates that there is a change or if there
14270 // is a new ref we mark this as an update.
14271 if (updatePayload !== null) {
14272 return true;
14273 }
14274 return false;
14275}
14276
14277function prepareToHydrateHostTextInstance(fiber) {
14278 if (!supportsHydration) {
14279 invariant(false, 'Expected prepareToHydrateHostTextInstance() to never be called. This error is likely caused by a bug in React. Please file an issue.');
14280 }
14281
14282 var textInstance = fiber.stateNode;
14283 var textContent = fiber.memoizedProps;
14284 var shouldUpdate = hydrateTextInstance(textInstance, textContent, fiber);
14285 {
14286 if (shouldUpdate) {
14287 // We assume that prepareToHydrateHostTextInstance is called in a context where the
14288 // hydration parent is the parent host component of this host text.
14289 var returnFiber = hydrationParentFiber;
14290 if (returnFiber !== null) {
14291 switch (returnFiber.tag) {
14292 case HostRoot:
14293 {
14294 var parentContainer = returnFiber.stateNode.containerInfo;
14295 didNotMatchHydratedContainerTextInstance(parentContainer, textInstance, textContent);
14296 break;
14297 }
14298 case HostComponent:
14299 {
14300 var parentType = returnFiber.type;
14301 var parentProps = returnFiber.memoizedProps;
14302 var parentInstance = returnFiber.stateNode;
14303 didNotMatchHydratedTextInstance(parentType, parentProps, parentInstance, textInstance, textContent);
14304 break;
14305 }
14306 }
14307 }
14308 }
14309 }
14310 return shouldUpdate;
14311}
14312
14313function skipPastDehydratedSuspenseInstance(fiber) {
14314 if (!supportsHydration) {
14315 invariant(false, 'Expected skipPastDehydratedSuspenseInstance() to never be called. This error is likely caused by a bug in React. Please file an issue.');
14316 }
14317 var suspenseInstance = fiber.stateNode;
14318 !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;
14319 nextHydratableInstance = getNextHydratableInstanceAfterSuspenseInstance(suspenseInstance);
14320}
14321
14322function popToNextHostParent(fiber) {
14323 var parent = fiber.return;
14324 while (parent !== null && parent.tag !== HostComponent && parent.tag !== HostRoot && parent.tag !== DehydratedSuspenseComponent) {
14325 parent = parent.return;
14326 }
14327 hydrationParentFiber = parent;
14328}
14329
14330function popHydrationState(fiber) {
14331 if (!supportsHydration) {
14332 return false;
14333 }
14334 if (fiber !== hydrationParentFiber) {
14335 // We're deeper than the current hydration context, inside an inserted
14336 // tree.
14337 return false;
14338 }
14339 if (!isHydrating) {
14340 // If we're not currently hydrating but we're in a hydration context, then
14341 // we were an insertion and now need to pop up reenter hydration of our
14342 // siblings.
14343 popToNextHostParent(fiber);
14344 isHydrating = true;
14345 return false;
14346 }
14347
14348 var type = fiber.type;
14349
14350 // If we have any remaining hydratable nodes, we need to delete them now.
14351 // We only do this deeper than head and body since they tend to have random
14352 // other nodes in them. We also ignore components with pure text content in
14353 // side of them.
14354 // TODO: Better heuristic.
14355 if (fiber.tag !== HostComponent || type !== 'head' && type !== 'body' && !shouldSetTextContent(type, fiber.memoizedProps)) {
14356 var nextInstance = nextHydratableInstance;
14357 while (nextInstance) {
14358 deleteHydratableInstance(fiber, nextInstance);
14359 nextInstance = getNextHydratableSibling(nextInstance);
14360 }
14361 }
14362
14363 popToNextHostParent(fiber);
14364 nextHydratableInstance = hydrationParentFiber ? getNextHydratableSibling(fiber.stateNode) : null;
14365 return true;
14366}
14367
14368function resetHydrationState() {
14369 if (!supportsHydration) {
14370 return;
14371 }
14372
14373 hydrationParentFiber = null;
14374 nextHydratableInstance = null;
14375 isHydrating = false;
14376}
14377
14378var ReactCurrentOwner$3 = ReactSharedInternals.ReactCurrentOwner;
14379
14380var didReceiveUpdate = false;
14381
14382var didWarnAboutBadClass = void 0;
14383var didWarnAboutContextTypeOnFunctionComponent = void 0;
14384var didWarnAboutGetDerivedStateOnFunctionComponent = void 0;
14385var didWarnAboutFunctionRefs = void 0;
14386var didWarnAboutReassigningProps = void 0;
14387
14388{
14389 didWarnAboutBadClass = {};
14390 didWarnAboutContextTypeOnFunctionComponent = {};
14391 didWarnAboutGetDerivedStateOnFunctionComponent = {};
14392 didWarnAboutFunctionRefs = {};
14393 didWarnAboutReassigningProps = false;
14394}
14395
14396function reconcileChildren(current$$1, workInProgress, nextChildren, renderExpirationTime) {
14397 if (current$$1 === null) {
14398 // If this is a fresh new component that hasn't been rendered yet, we
14399 // won't update its child set by applying minimal side-effects. Instead,
14400 // we will add them all to the child before it gets rendered. That means
14401 // we can optimize this reconciliation pass by not tracking side-effects.
14402 workInProgress.child = mountChildFibers(workInProgress, null, nextChildren, renderExpirationTime);
14403 } else {
14404 // If the current child is the same as the work in progress, it means that
14405 // we haven't yet started any work on these children. Therefore, we use
14406 // the clone algorithm to create a copy of all the current children.
14407
14408 // If we had any progressed work already, that is invalid at this point so
14409 // let's throw it out.
14410 workInProgress.child = reconcileChildFibers(workInProgress, current$$1.child, nextChildren, renderExpirationTime);
14411 }
14412}
14413
14414function forceUnmountCurrentAndReconcile(current$$1, workInProgress, nextChildren, renderExpirationTime) {
14415 // This function is fork of reconcileChildren. It's used in cases where we
14416 // want to reconcile without matching against the existing set. This has the
14417 // effect of all current children being unmounted; even if the type and key
14418 // are the same, the old child is unmounted and a new child is created.
14419 //
14420 // To do this, we're going to go through the reconcile algorithm twice. In
14421 // the first pass, we schedule a deletion for all the current children by
14422 // passing null.
14423 workInProgress.child = reconcileChildFibers(workInProgress, current$$1.child, null, renderExpirationTime);
14424 // In the second pass, we mount the new children. The trick here is that we
14425 // pass null in place of where we usually pass the current child set. This has
14426 // the effect of remounting all children regardless of whether their their
14427 // identity matches.
14428 workInProgress.child = reconcileChildFibers(workInProgress, null, nextChildren, renderExpirationTime);
14429}
14430
14431function updateForwardRef(current$$1, workInProgress, Component, nextProps, renderExpirationTime) {
14432 // TODO: current can be non-null here even if the component
14433 // hasn't yet mounted. This happens after the first render suspends.
14434 // We'll need to figure out if this is fine or can cause issues.
14435
14436 {
14437 if (workInProgress.type !== workInProgress.elementType) {
14438 // Lazy component props can't be validated in createElement
14439 // because they're only guaranteed to be resolved here.
14440 var innerPropTypes = Component.propTypes;
14441 if (innerPropTypes) {
14442 checkPropTypes(innerPropTypes, nextProps, // Resolved props
14443 'prop', getComponentName(Component), getCurrentFiberStackInDev);
14444 }
14445 }
14446 }
14447
14448 var render = Component.render;
14449 var ref = workInProgress.ref;
14450
14451 // The rest is a fork of updateFunctionComponent
14452 var nextChildren = void 0;
14453 prepareToReadContext(workInProgress, renderExpirationTime);
14454 {
14455 ReactCurrentOwner$3.current = workInProgress;
14456 setCurrentPhase('render');
14457 nextChildren = renderWithHooks(current$$1, workInProgress, render, nextProps, ref, renderExpirationTime);
14458 if (debugRenderPhaseSideEffects || debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) {
14459 // Only double-render components with Hooks
14460 if (workInProgress.memoizedState !== null) {
14461 nextChildren = renderWithHooks(current$$1, workInProgress, render, nextProps, ref, renderExpirationTime);
14462 }
14463 }
14464 setCurrentPhase(null);
14465 }
14466
14467 if (current$$1 !== null && !didReceiveUpdate) {
14468 bailoutHooks(current$$1, workInProgress, renderExpirationTime);
14469 return bailoutOnAlreadyFinishedWork(current$$1, workInProgress, renderExpirationTime);
14470 }
14471
14472 // React DevTools reads this flag.
14473 workInProgress.effectTag |= PerformedWork;
14474 reconcileChildren(current$$1, workInProgress, nextChildren, renderExpirationTime);
14475 return workInProgress.child;
14476}
14477
14478function updateMemoComponent(current$$1, workInProgress, Component, nextProps, updateExpirationTime, renderExpirationTime) {
14479 if (current$$1 === null) {
14480 var type = Component.type;
14481 if (isSimpleFunctionComponent(type) && Component.compare === null &&
14482 // SimpleMemoComponent codepath doesn't resolve outer props either.
14483 Component.defaultProps === undefined) {
14484 // If this is a plain function component without default props,
14485 // and with only the default shallow comparison, we upgrade it
14486 // to a SimpleMemoComponent to allow fast path updates.
14487 workInProgress.tag = SimpleMemoComponent;
14488 workInProgress.type = type;
14489 {
14490 validateFunctionComponentInDev(workInProgress, type);
14491 }
14492 return updateSimpleMemoComponent(current$$1, workInProgress, type, nextProps, updateExpirationTime, renderExpirationTime);
14493 }
14494 {
14495 var innerPropTypes = type.propTypes;
14496 if (innerPropTypes) {
14497 // Inner memo component props aren't currently validated in createElement.
14498 // We could move it there, but we'd still need this for lazy code path.
14499 checkPropTypes(innerPropTypes, nextProps, // Resolved props
14500 'prop', getComponentName(type), getCurrentFiberStackInDev);
14501 }
14502 }
14503 var child = createFiberFromTypeAndProps(Component.type, null, nextProps, null, workInProgress.mode, renderExpirationTime);
14504 child.ref = workInProgress.ref;
14505 child.return = workInProgress;
14506 workInProgress.child = child;
14507 return child;
14508 }
14509 {
14510 var _type = Component.type;
14511 var _innerPropTypes = _type.propTypes;
14512 if (_innerPropTypes) {
14513 // Inner memo component props aren't currently validated in createElement.
14514 // We could move it there, but we'd still need this for lazy code path.
14515 checkPropTypes(_innerPropTypes, nextProps, // Resolved props
14516 'prop', getComponentName(_type), getCurrentFiberStackInDev);
14517 }
14518 }
14519 var currentChild = current$$1.child; // This is always exactly one child
14520 if (updateExpirationTime < renderExpirationTime) {
14521 // This will be the props with resolved defaultProps,
14522 // unlike current.memoizedProps which will be the unresolved ones.
14523 var prevProps = currentChild.memoizedProps;
14524 // Default to shallow comparison
14525 var compare = Component.compare;
14526 compare = compare !== null ? compare : shallowEqual;
14527 if (compare(prevProps, nextProps) && current$$1.ref === workInProgress.ref) {
14528 return bailoutOnAlreadyFinishedWork(current$$1, workInProgress, renderExpirationTime);
14529 }
14530 }
14531 // React DevTools reads this flag.
14532 workInProgress.effectTag |= PerformedWork;
14533 var newChild = createWorkInProgress(currentChild, nextProps, renderExpirationTime);
14534 newChild.ref = workInProgress.ref;
14535 newChild.return = workInProgress;
14536 workInProgress.child = newChild;
14537 return newChild;
14538}
14539
14540function updateSimpleMemoComponent(current$$1, workInProgress, Component, nextProps, updateExpirationTime, renderExpirationTime) {
14541 // TODO: current can be non-null here even if the component
14542 // hasn't yet mounted. This happens when the inner render suspends.
14543 // We'll need to figure out if this is fine or can cause issues.
14544
14545 {
14546 if (workInProgress.type !== workInProgress.elementType) {
14547 // Lazy component props can't be validated in createElement
14548 // because they're only guaranteed to be resolved here.
14549 var outerMemoType = workInProgress.elementType;
14550 if (outerMemoType.$$typeof === REACT_LAZY_TYPE) {
14551 // We warn when you define propTypes on lazy()
14552 // so let's just skip over it to find memo() outer wrapper.
14553 // Inner props for memo are validated later.
14554 outerMemoType = refineResolvedLazyComponent(outerMemoType);
14555 }
14556 var outerPropTypes = outerMemoType && outerMemoType.propTypes;
14557 if (outerPropTypes) {
14558 checkPropTypes(outerPropTypes, nextProps, // Resolved (SimpleMemoComponent has no defaultProps)
14559 'prop', getComponentName(outerMemoType), getCurrentFiberStackInDev);
14560 }
14561 // Inner propTypes will be validated in the function component path.
14562 }
14563 }
14564 if (current$$1 !== null) {
14565 var prevProps = current$$1.memoizedProps;
14566 if (shallowEqual(prevProps, nextProps) && current$$1.ref === workInProgress.ref) {
14567 didReceiveUpdate = false;
14568 if (updateExpirationTime < renderExpirationTime) {
14569 return bailoutOnAlreadyFinishedWork(current$$1, workInProgress, renderExpirationTime);
14570 }
14571 }
14572 }
14573 return updateFunctionComponent(current$$1, workInProgress, Component, nextProps, renderExpirationTime);
14574}
14575
14576function updateFragment(current$$1, workInProgress, renderExpirationTime) {
14577 var nextChildren = workInProgress.pendingProps;
14578 reconcileChildren(current$$1, workInProgress, nextChildren, renderExpirationTime);
14579 return workInProgress.child;
14580}
14581
14582function updateMode(current$$1, workInProgress, renderExpirationTime) {
14583 var nextChildren = workInProgress.pendingProps.children;
14584 reconcileChildren(current$$1, workInProgress, nextChildren, renderExpirationTime);
14585 return workInProgress.child;
14586}
14587
14588function updateProfiler(current$$1, workInProgress, renderExpirationTime) {
14589 if (enableProfilerTimer) {
14590 workInProgress.effectTag |= Update;
14591 }
14592 var nextProps = workInProgress.pendingProps;
14593 var nextChildren = nextProps.children;
14594 reconcileChildren(current$$1, workInProgress, nextChildren, renderExpirationTime);
14595 return workInProgress.child;
14596}
14597
14598function markRef(current$$1, workInProgress) {
14599 var ref = workInProgress.ref;
14600 if (current$$1 === null && ref !== null || current$$1 !== null && current$$1.ref !== ref) {
14601 // Schedule a Ref effect
14602 workInProgress.effectTag |= Ref;
14603 }
14604}
14605
14606function updateFunctionComponent(current$$1, workInProgress, Component, nextProps, renderExpirationTime) {
14607 {
14608 if (workInProgress.type !== workInProgress.elementType) {
14609 // Lazy component props can't be validated in createElement
14610 // because they're only guaranteed to be resolved here.
14611 var innerPropTypes = Component.propTypes;
14612 if (innerPropTypes) {
14613 checkPropTypes(innerPropTypes, nextProps, // Resolved props
14614 'prop', getComponentName(Component), getCurrentFiberStackInDev);
14615 }
14616 }
14617 }
14618
14619 var unmaskedContext = getUnmaskedContext(workInProgress, Component, true);
14620 var context = getMaskedContext(workInProgress, unmaskedContext);
14621
14622 var nextChildren = void 0;
14623 prepareToReadContext(workInProgress, renderExpirationTime);
14624 {
14625 ReactCurrentOwner$3.current = workInProgress;
14626 setCurrentPhase('render');
14627 nextChildren = renderWithHooks(current$$1, workInProgress, Component, nextProps, context, renderExpirationTime);
14628 if (debugRenderPhaseSideEffects || debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) {
14629 // Only double-render components with Hooks
14630 if (workInProgress.memoizedState !== null) {
14631 nextChildren = renderWithHooks(current$$1, workInProgress, Component, nextProps, context, renderExpirationTime);
14632 }
14633 }
14634 setCurrentPhase(null);
14635 }
14636
14637 if (current$$1 !== null && !didReceiveUpdate) {
14638 bailoutHooks(current$$1, workInProgress, renderExpirationTime);
14639 return bailoutOnAlreadyFinishedWork(current$$1, workInProgress, renderExpirationTime);
14640 }
14641
14642 // React DevTools reads this flag.
14643 workInProgress.effectTag |= PerformedWork;
14644 reconcileChildren(current$$1, workInProgress, nextChildren, renderExpirationTime);
14645 return workInProgress.child;
14646}
14647
14648function updateClassComponent(current$$1, workInProgress, Component, nextProps, renderExpirationTime) {
14649 {
14650 if (workInProgress.type !== workInProgress.elementType) {
14651 // Lazy component props can't be validated in createElement
14652 // because they're only guaranteed to be resolved here.
14653 var innerPropTypes = Component.propTypes;
14654 if (innerPropTypes) {
14655 checkPropTypes(innerPropTypes, nextProps, // Resolved props
14656 'prop', getComponentName(Component), getCurrentFiberStackInDev);
14657 }
14658 }
14659 }
14660
14661 // Push context providers early to prevent context stack mismatches.
14662 // During mounting we don't know the child context yet as the instance doesn't exist.
14663 // We will invalidate the child context in finishClassComponent() right after rendering.
14664 var hasContext = void 0;
14665 if (isContextProvider(Component)) {
14666 hasContext = true;
14667 pushContextProvider(workInProgress);
14668 } else {
14669 hasContext = false;
14670 }
14671 prepareToReadContext(workInProgress, renderExpirationTime);
14672
14673 var instance = workInProgress.stateNode;
14674 var shouldUpdate = void 0;
14675 if (instance === null) {
14676 if (current$$1 !== null) {
14677 // An class component without an instance only mounts if it suspended
14678 // inside a non- concurrent tree, in an inconsistent state. We want to
14679 // tree it like a new mount, even though an empty version of it already
14680 // committed. Disconnect the alternate pointers.
14681 current$$1.alternate = null;
14682 workInProgress.alternate = null;
14683 // Since this is conceptually a new fiber, schedule a Placement effect
14684 workInProgress.effectTag |= Placement;
14685 }
14686 // In the initial pass we might need to construct the instance.
14687 constructClassInstance(workInProgress, Component, nextProps, renderExpirationTime);
14688 mountClassInstance(workInProgress, Component, nextProps, renderExpirationTime);
14689 shouldUpdate = true;
14690 } else if (current$$1 === null) {
14691 // In a resume, we'll already have an instance we can reuse.
14692 shouldUpdate = resumeMountClassInstance(workInProgress, Component, nextProps, renderExpirationTime);
14693 } else {
14694 shouldUpdate = updateClassInstance(current$$1, workInProgress, Component, nextProps, renderExpirationTime);
14695 }
14696 var nextUnitOfWork = finishClassComponent(current$$1, workInProgress, Component, shouldUpdate, hasContext, renderExpirationTime);
14697 {
14698 var inst = workInProgress.stateNode;
14699 if (inst.props !== nextProps) {
14700 !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;
14701 didWarnAboutReassigningProps = true;
14702 }
14703 }
14704 return nextUnitOfWork;
14705}
14706
14707function finishClassComponent(current$$1, workInProgress, Component, shouldUpdate, hasContext, renderExpirationTime) {
14708 // Refs should update even if shouldComponentUpdate returns false
14709 markRef(current$$1, workInProgress);
14710
14711 var didCaptureError = (workInProgress.effectTag & DidCapture) !== NoEffect;
14712
14713 if (!shouldUpdate && !didCaptureError) {
14714 // Context providers should defer to sCU for rendering
14715 if (hasContext) {
14716 invalidateContextProvider(workInProgress, Component, false);
14717 }
14718
14719 return bailoutOnAlreadyFinishedWork(current$$1, workInProgress, renderExpirationTime);
14720 }
14721
14722 var instance = workInProgress.stateNode;
14723
14724 // Rerender
14725 ReactCurrentOwner$3.current = workInProgress;
14726 var nextChildren = void 0;
14727 if (didCaptureError && typeof Component.getDerivedStateFromError !== 'function') {
14728 // If we captured an error, but getDerivedStateFrom catch is not defined,
14729 // unmount all the children. componentDidCatch will schedule an update to
14730 // re-render a fallback. This is temporary until we migrate everyone to
14731 // the new API.
14732 // TODO: Warn in a future release.
14733 nextChildren = null;
14734
14735 if (enableProfilerTimer) {
14736 stopProfilerTimerIfRunning(workInProgress);
14737 }
14738 } else {
14739 {
14740 setCurrentPhase('render');
14741 nextChildren = instance.render();
14742 if (debugRenderPhaseSideEffects || debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) {
14743 instance.render();
14744 }
14745 setCurrentPhase(null);
14746 }
14747 }
14748
14749 // React DevTools reads this flag.
14750 workInProgress.effectTag |= PerformedWork;
14751 if (current$$1 !== null && didCaptureError) {
14752 // If we're recovering from an error, reconcile without reusing any of
14753 // the existing children. Conceptually, the normal children and the children
14754 // that are shown on error are two different sets, so we shouldn't reuse
14755 // normal children even if their identities match.
14756 forceUnmountCurrentAndReconcile(current$$1, workInProgress, nextChildren, renderExpirationTime);
14757 } else {
14758 reconcileChildren(current$$1, workInProgress, nextChildren, renderExpirationTime);
14759 }
14760
14761 // Memoize state using the values we just used to render.
14762 // TODO: Restructure so we never read values from the instance.
14763 workInProgress.memoizedState = instance.state;
14764
14765 // The context might have changed so we need to recalculate it.
14766 if (hasContext) {
14767 invalidateContextProvider(workInProgress, Component, true);
14768 }
14769
14770 return workInProgress.child;
14771}
14772
14773function pushHostRootContext(workInProgress) {
14774 var root = workInProgress.stateNode;
14775 if (root.pendingContext) {
14776 pushTopLevelContextObject(workInProgress, root.pendingContext, root.pendingContext !== root.context);
14777 } else if (root.context) {
14778 // Should always be set
14779 pushTopLevelContextObject(workInProgress, root.context, false);
14780 }
14781 pushHostContainer(workInProgress, root.containerInfo);
14782}
14783
14784function updateHostRoot(current$$1, workInProgress, renderExpirationTime) {
14785 pushHostRootContext(workInProgress);
14786 var updateQueue = workInProgress.updateQueue;
14787 !(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;
14788 var nextProps = workInProgress.pendingProps;
14789 var prevState = workInProgress.memoizedState;
14790 var prevChildren = prevState !== null ? prevState.element : null;
14791 processUpdateQueue(workInProgress, updateQueue, nextProps, null, renderExpirationTime);
14792 var nextState = workInProgress.memoizedState;
14793 // Caution: React DevTools currently depends on this property
14794 // being called "element".
14795 var nextChildren = nextState.element;
14796 if (nextChildren === prevChildren) {
14797 // If the state is the same as before, that's a bailout because we had
14798 // no work that expires at this time.
14799 resetHydrationState();
14800 return bailoutOnAlreadyFinishedWork(current$$1, workInProgress, renderExpirationTime);
14801 }
14802 var root = workInProgress.stateNode;
14803 if ((current$$1 === null || current$$1.child === null) && root.hydrate && enterHydrationState(workInProgress)) {
14804 // If we don't have any current children this might be the first pass.
14805 // We always try to hydrate. If this isn't a hydration pass there won't
14806 // be any children to hydrate which is effectively the same thing as
14807 // not hydrating.
14808
14809 // This is a bit of a hack. We track the host root as a placement to
14810 // know that we're currently in a mounting state. That way isMounted
14811 // works as expected. We must reset this before committing.
14812 // TODO: Delete this when we delete isMounted and findDOMNode.
14813 workInProgress.effectTag |= Placement;
14814
14815 // Ensure that children mount into this root without tracking
14816 // side-effects. This ensures that we don't store Placement effects on
14817 // nodes that will be hydrated.
14818 workInProgress.child = mountChildFibers(workInProgress, null, nextChildren, renderExpirationTime);
14819 } else {
14820 // Otherwise reset hydration state in case we aborted and resumed another
14821 // root.
14822 reconcileChildren(current$$1, workInProgress, nextChildren, renderExpirationTime);
14823 resetHydrationState();
14824 }
14825 return workInProgress.child;
14826}
14827
14828function updateHostComponent(current$$1, workInProgress, renderExpirationTime) {
14829 pushHostContext(workInProgress);
14830
14831 if (current$$1 === null) {
14832 tryToClaimNextHydratableInstance(workInProgress);
14833 }
14834
14835 var type = workInProgress.type;
14836 var nextProps = workInProgress.pendingProps;
14837 var prevProps = current$$1 !== null ? current$$1.memoizedProps : null;
14838
14839 var nextChildren = nextProps.children;
14840 var isDirectTextChild = shouldSetTextContent(type, nextProps);
14841
14842 if (isDirectTextChild) {
14843 // We special case a direct text child of a host node. This is a common
14844 // case. We won't handle it as a reified child. We will instead handle
14845 // this in the host environment that also have access to this prop. That
14846 // avoids allocating another HostText fiber and traversing it.
14847 nextChildren = null;
14848 } else if (prevProps !== null && shouldSetTextContent(type, prevProps)) {
14849 // If we're switching from a direct text child to a normal child, or to
14850 // empty, we need to schedule the text content to be reset.
14851 workInProgress.effectTag |= ContentReset;
14852 }
14853
14854 markRef(current$$1, workInProgress);
14855
14856 // Check the host config to see if the children are offscreen/hidden.
14857 if (renderExpirationTime !== Never && workInProgress.mode & ConcurrentMode && shouldDeprioritizeSubtree(type, nextProps)) {
14858 // Schedule this fiber to re-render at offscreen priority. Then bailout.
14859 workInProgress.expirationTime = workInProgress.childExpirationTime = Never;
14860 return null;
14861 }
14862
14863 reconcileChildren(current$$1, workInProgress, nextChildren, renderExpirationTime);
14864 return workInProgress.child;
14865}
14866
14867function updateHostText(current$$1, workInProgress) {
14868 if (current$$1 === null) {
14869 tryToClaimNextHydratableInstance(workInProgress);
14870 }
14871 // Nothing to do here. This is terminal. We'll do the completion step
14872 // immediately after.
14873 return null;
14874}
14875
14876function mountLazyComponent(_current, workInProgress, elementType, updateExpirationTime, renderExpirationTime) {
14877 if (_current !== null) {
14878 // An lazy component only mounts if it suspended inside a non-
14879 // concurrent tree, in an inconsistent state. We want to treat it like
14880 // a new mount, even though an empty version of it already committed.
14881 // Disconnect the alternate pointers.
14882 _current.alternate = null;
14883 workInProgress.alternate = null;
14884 // Since this is conceptually a new fiber, schedule a Placement effect
14885 workInProgress.effectTag |= Placement;
14886 }
14887
14888 var props = workInProgress.pendingProps;
14889 // We can't start a User Timing measurement with correct label yet.
14890 // Cancel and resume right after we know the tag.
14891 cancelWorkTimer(workInProgress);
14892 var Component = readLazyComponentType(elementType);
14893 // Store the unwrapped component in the type.
14894 workInProgress.type = Component;
14895 var resolvedTag = workInProgress.tag = resolveLazyComponentTag(Component);
14896 startWorkTimer(workInProgress);
14897 var resolvedProps = resolveDefaultProps(Component, props);
14898 var child = void 0;
14899 switch (resolvedTag) {
14900 case FunctionComponent:
14901 {
14902 {
14903 validateFunctionComponentInDev(workInProgress, Component);
14904 }
14905 child = updateFunctionComponent(null, workInProgress, Component, resolvedProps, renderExpirationTime);
14906 break;
14907 }
14908 case ClassComponent:
14909 {
14910 child = updateClassComponent(null, workInProgress, Component, resolvedProps, renderExpirationTime);
14911 break;
14912 }
14913 case ForwardRef:
14914 {
14915 child = updateForwardRef(null, workInProgress, Component, resolvedProps, renderExpirationTime);
14916 break;
14917 }
14918 case MemoComponent:
14919 {
14920 {
14921 if (workInProgress.type !== workInProgress.elementType) {
14922 var outerPropTypes = Component.propTypes;
14923 if (outerPropTypes) {
14924 checkPropTypes(outerPropTypes, resolvedProps, // Resolved for outer only
14925 'prop', getComponentName(Component), getCurrentFiberStackInDev);
14926 }
14927 }
14928 }
14929 child = updateMemoComponent(null, workInProgress, Component, resolveDefaultProps(Component.type, resolvedProps), // The inner type can have defaults too
14930 updateExpirationTime, renderExpirationTime);
14931 break;
14932 }
14933 default:
14934 {
14935 var hint = '';
14936 {
14937 if (Component !== null && typeof Component === 'object' && Component.$$typeof === REACT_LAZY_TYPE) {
14938 hint = ' Did you wrap a component in React.lazy() more than once?';
14939 }
14940 }
14941 // This message intentionally doesn't mention ForwardRef or MemoComponent
14942 // because the fact that it's a separate type of work is an
14943 // implementation detail.
14944 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);
14945 }
14946 }
14947 return child;
14948}
14949
14950function mountIncompleteClassComponent(_current, workInProgress, Component, nextProps, renderExpirationTime) {
14951 if (_current !== null) {
14952 // An incomplete component only mounts if it suspended inside a non-
14953 // concurrent tree, in an inconsistent state. We want to treat it like
14954 // a new mount, even though an empty version of it already committed.
14955 // Disconnect the alternate pointers.
14956 _current.alternate = null;
14957 workInProgress.alternate = null;
14958 // Since this is conceptually a new fiber, schedule a Placement effect
14959 workInProgress.effectTag |= Placement;
14960 }
14961
14962 // Promote the fiber to a class and try rendering again.
14963 workInProgress.tag = ClassComponent;
14964
14965 // The rest of this function is a fork of `updateClassComponent`
14966
14967 // Push context providers early to prevent context stack mismatches.
14968 // During mounting we don't know the child context yet as the instance doesn't exist.
14969 // We will invalidate the child context in finishClassComponent() right after rendering.
14970 var hasContext = void 0;
14971 if (isContextProvider(Component)) {
14972 hasContext = true;
14973 pushContextProvider(workInProgress);
14974 } else {
14975 hasContext = false;
14976 }
14977 prepareToReadContext(workInProgress, renderExpirationTime);
14978
14979 constructClassInstance(workInProgress, Component, nextProps, renderExpirationTime);
14980 mountClassInstance(workInProgress, Component, nextProps, renderExpirationTime);
14981
14982 return finishClassComponent(null, workInProgress, Component, true, hasContext, renderExpirationTime);
14983}
14984
14985function mountIndeterminateComponent(_current, workInProgress, Component, renderExpirationTime) {
14986 if (_current !== null) {
14987 // An indeterminate component only mounts if it suspended inside a non-
14988 // concurrent tree, in an inconsistent state. We want to treat it like
14989 // a new mount, even though an empty version of it already committed.
14990 // Disconnect the alternate pointers.
14991 _current.alternate = null;
14992 workInProgress.alternate = null;
14993 // Since this is conceptually a new fiber, schedule a Placement effect
14994 workInProgress.effectTag |= Placement;
14995 }
14996
14997 var props = workInProgress.pendingProps;
14998 var unmaskedContext = getUnmaskedContext(workInProgress, Component, false);
14999 var context = getMaskedContext(workInProgress, unmaskedContext);
15000
15001 prepareToReadContext(workInProgress, renderExpirationTime);
15002
15003 var value = void 0;
15004
15005 {
15006 if (Component.prototype && typeof Component.prototype.render === 'function') {
15007 var componentName = getComponentName(Component) || 'Unknown';
15008
15009 if (!didWarnAboutBadClass[componentName]) {
15010 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);
15011 didWarnAboutBadClass[componentName] = true;
15012 }
15013 }
15014
15015 if (workInProgress.mode & StrictMode) {
15016 ReactStrictModeWarnings.recordLegacyContextWarning(workInProgress, null);
15017 }
15018
15019 ReactCurrentOwner$3.current = workInProgress;
15020 value = renderWithHooks(null, workInProgress, Component, props, context, renderExpirationTime);
15021 }
15022 // React DevTools reads this flag.
15023 workInProgress.effectTag |= PerformedWork;
15024
15025 if (typeof value === 'object' && value !== null && typeof value.render === 'function' && value.$$typeof === undefined) {
15026 // Proceed under the assumption that this is a class instance
15027 workInProgress.tag = ClassComponent;
15028
15029 // Throw out any hooks that were used.
15030 resetHooks();
15031
15032 // Push context providers early to prevent context stack mismatches.
15033 // During mounting we don't know the child context yet as the instance doesn't exist.
15034 // We will invalidate the child context in finishClassComponent() right after rendering.
15035 var hasContext = false;
15036 if (isContextProvider(Component)) {
15037 hasContext = true;
15038 pushContextProvider(workInProgress);
15039 } else {
15040 hasContext = false;
15041 }
15042
15043 workInProgress.memoizedState = value.state !== null && value.state !== undefined ? value.state : null;
15044
15045 var getDerivedStateFromProps = Component.getDerivedStateFromProps;
15046 if (typeof getDerivedStateFromProps === 'function') {
15047 applyDerivedStateFromProps(workInProgress, Component, getDerivedStateFromProps, props);
15048 }
15049
15050 adoptClassInstance(workInProgress, value);
15051 mountClassInstance(workInProgress, Component, props, renderExpirationTime);
15052 return finishClassComponent(null, workInProgress, Component, true, hasContext, renderExpirationTime);
15053 } else {
15054 // Proceed under the assumption that this is a function component
15055 workInProgress.tag = FunctionComponent;
15056 {
15057 if (debugRenderPhaseSideEffects || debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) {
15058 // Only double-render components with Hooks
15059 if (workInProgress.memoizedState !== null) {
15060 value = renderWithHooks(null, workInProgress, Component, props, context, renderExpirationTime);
15061 }
15062 }
15063 }
15064 reconcileChildren(null, workInProgress, value, renderExpirationTime);
15065 {
15066 validateFunctionComponentInDev(workInProgress, Component);
15067 }
15068 return workInProgress.child;
15069 }
15070}
15071
15072function validateFunctionComponentInDev(workInProgress, Component) {
15073 if (Component) {
15074 !!Component.childContextTypes ? warningWithoutStack$1(false, '%s(...): childContextTypes cannot be defined on a function component.', Component.displayName || Component.name || 'Component') : void 0;
15075 }
15076 if (workInProgress.ref !== null) {
15077 var info = '';
15078 var ownerName = getCurrentFiberOwnerNameInDevOrNull();
15079 if (ownerName) {
15080 info += '\n\nCheck the render method of `' + ownerName + '`.';
15081 }
15082
15083 var warningKey = ownerName || workInProgress._debugID || '';
15084 var debugSource = workInProgress._debugSource;
15085 if (debugSource) {
15086 warningKey = debugSource.fileName + ':' + debugSource.lineNumber;
15087 }
15088 if (!didWarnAboutFunctionRefs[warningKey]) {
15089 didWarnAboutFunctionRefs[warningKey] = true;
15090 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);
15091 }
15092 }
15093
15094 if (typeof Component.getDerivedStateFromProps === 'function') {
15095 var componentName = getComponentName(Component) || 'Unknown';
15096
15097 if (!didWarnAboutGetDerivedStateOnFunctionComponent[componentName]) {
15098 warningWithoutStack$1(false, '%s: Function components do not support getDerivedStateFromProps.', componentName);
15099 didWarnAboutGetDerivedStateOnFunctionComponent[componentName] = true;
15100 }
15101 }
15102
15103 if (typeof Component.contextType === 'object' && Component.contextType !== null) {
15104 var _componentName = getComponentName(Component) || 'Unknown';
15105
15106 if (!didWarnAboutContextTypeOnFunctionComponent[_componentName]) {
15107 warningWithoutStack$1(false, '%s: Function components do not support contextType.', _componentName);
15108 didWarnAboutContextTypeOnFunctionComponent[_componentName] = true;
15109 }
15110 }
15111}
15112
15113function updateSuspenseComponent(current$$1, workInProgress, renderExpirationTime) {
15114 var mode = workInProgress.mode;
15115 var nextProps = workInProgress.pendingProps;
15116
15117 // We should attempt to render the primary children unless this boundary
15118 // already suspended during this render (`alreadyCaptured` is true).
15119 var nextState = workInProgress.memoizedState;
15120
15121 var nextDidTimeout = void 0;
15122 if ((workInProgress.effectTag & DidCapture) === NoEffect) {
15123 // This is the first attempt.
15124 nextState = null;
15125 nextDidTimeout = false;
15126 } else {
15127 // Something in this boundary's subtree already suspended. Switch to
15128 // rendering the fallback children.
15129 nextState = {
15130 timedOutAt: nextState !== null ? nextState.timedOutAt : NoWork
15131 };
15132 nextDidTimeout = true;
15133 workInProgress.effectTag &= ~DidCapture;
15134 }
15135
15136 // This next part is a bit confusing. If the children timeout, we switch to
15137 // showing the fallback children in place of the "primary" children.
15138 // However, we don't want to delete the primary children because then their
15139 // state will be lost (both the React state and the host state, e.g.
15140 // uncontrolled form inputs). Instead we keep them mounted and hide them.
15141 // Both the fallback children AND the primary children are rendered at the
15142 // same time. Once the primary children are un-suspended, we can delete
15143 // the fallback children — don't need to preserve their state.
15144 //
15145 // The two sets of children are siblings in the host environment, but
15146 // semantically, for purposes of reconciliation, they are two separate sets.
15147 // So we store them using two fragment fibers.
15148 //
15149 // However, we want to avoid allocating extra fibers for every placeholder.
15150 // They're only necessary when the children time out, because that's the
15151 // only time when both sets are mounted.
15152 //
15153 // So, the extra fragment fibers are only used if the children time out.
15154 // Otherwise, we render the primary children directly. This requires some
15155 // custom reconciliation logic to preserve the state of the primary
15156 // children. It's essentially a very basic form of re-parenting.
15157
15158 // `child` points to the child fiber. In the normal case, this is the first
15159 // fiber of the primary children set. In the timed-out case, it's a
15160 // a fragment fiber containing the primary children.
15161 var child = void 0;
15162 // `next` points to the next fiber React should render. In the normal case,
15163 // it's the same as `child`: the first fiber of the primary children set.
15164 // In the timed-out case, it's a fragment fiber containing the *fallback*
15165 // children -- we skip over the primary children entirely.
15166 var next = void 0;
15167 if (current$$1 === null) {
15168 if (enableSuspenseServerRenderer) {
15169 // If we're currently hydrating, try to hydrate this boundary.
15170 // But only if this has a fallback.
15171 if (nextProps.fallback !== undefined) {
15172 tryToClaimNextHydratableInstance(workInProgress);
15173 // This could've changed the tag if this was a dehydrated suspense component.
15174 if (workInProgress.tag === DehydratedSuspenseComponent) {
15175 return updateDehydratedSuspenseComponent(null, workInProgress, renderExpirationTime);
15176 }
15177 }
15178 }
15179
15180 // This is the initial mount. This branch is pretty simple because there's
15181 // no previous state that needs to be preserved.
15182 if (nextDidTimeout) {
15183 // Mount separate fragments for primary and fallback children.
15184 var nextFallbackChildren = nextProps.fallback;
15185 var primaryChildFragment = createFiberFromFragment(null, mode, NoWork, null);
15186
15187 if ((workInProgress.mode & ConcurrentMode) === NoContext) {
15188 // Outside of concurrent mode, we commit the effects from the
15189 var progressedState = workInProgress.memoizedState;
15190 var progressedPrimaryChild = progressedState !== null ? workInProgress.child.child : workInProgress.child;
15191 primaryChildFragment.child = progressedPrimaryChild;
15192 }
15193
15194 var fallbackChildFragment = createFiberFromFragment(nextFallbackChildren, mode, renderExpirationTime, null);
15195 primaryChildFragment.sibling = fallbackChildFragment;
15196 child = primaryChildFragment;
15197 // Skip the primary children, and continue working on the
15198 // fallback children.
15199 next = fallbackChildFragment;
15200 child.return = next.return = workInProgress;
15201 } else {
15202 // Mount the primary children without an intermediate fragment fiber.
15203 var nextPrimaryChildren = nextProps.children;
15204 child = next = mountChildFibers(workInProgress, null, nextPrimaryChildren, renderExpirationTime);
15205 }
15206 } else {
15207 // This is an update. This branch is more complicated because we need to
15208 // ensure the state of the primary children is preserved.
15209 var prevState = current$$1.memoizedState;
15210 var prevDidTimeout = prevState !== null;
15211 if (prevDidTimeout) {
15212 // The current tree already timed out. That means each child set is
15213 var currentPrimaryChildFragment = current$$1.child;
15214 var currentFallbackChildFragment = currentPrimaryChildFragment.sibling;
15215 if (nextDidTimeout) {
15216 // Still timed out. Reuse the current primary children by cloning
15217 // its fragment. We're going to skip over these entirely.
15218 var _nextFallbackChildren = nextProps.fallback;
15219 var _primaryChildFragment = createWorkInProgress(currentPrimaryChildFragment, currentPrimaryChildFragment.pendingProps, NoWork);
15220
15221 if ((workInProgress.mode & ConcurrentMode) === NoContext) {
15222 // Outside of concurrent mode, we commit the effects from the
15223 var _progressedState = workInProgress.memoizedState;
15224 var _progressedPrimaryChild = _progressedState !== null ? workInProgress.child.child : workInProgress.child;
15225 if (_progressedPrimaryChild !== currentPrimaryChildFragment.child) {
15226 _primaryChildFragment.child = _progressedPrimaryChild;
15227 }
15228 }
15229
15230 // Because primaryChildFragment is a new fiber that we're inserting as the
15231 // parent of a new tree, we need to set its treeBaseDuration.
15232 if (enableProfilerTimer && workInProgress.mode & ProfileMode) {
15233 // treeBaseDuration is the sum of all the child tree base durations.
15234 var treeBaseDuration = 0;
15235 var hiddenChild = _primaryChildFragment.child;
15236 while (hiddenChild !== null) {
15237 treeBaseDuration += hiddenChild.treeBaseDuration;
15238 hiddenChild = hiddenChild.sibling;
15239 }
15240 _primaryChildFragment.treeBaseDuration = treeBaseDuration;
15241 }
15242
15243 // Clone the fallback child fragment, too. These we'll continue
15244 // working on.
15245 var _fallbackChildFragment = _primaryChildFragment.sibling = createWorkInProgress(currentFallbackChildFragment, _nextFallbackChildren, currentFallbackChildFragment.expirationTime);
15246 child = _primaryChildFragment;
15247 _primaryChildFragment.childExpirationTime = NoWork;
15248 // Skip the primary children, and continue working on the
15249 // fallback children.
15250 next = _fallbackChildFragment;
15251 child.return = next.return = workInProgress;
15252 } else {
15253 // No longer suspended. Switch back to showing the primary children,
15254 // and remove the intermediate fragment fiber.
15255 var _nextPrimaryChildren = nextProps.children;
15256 var currentPrimaryChild = currentPrimaryChildFragment.child;
15257 var primaryChild = reconcileChildFibers(workInProgress, currentPrimaryChild, _nextPrimaryChildren, renderExpirationTime);
15258
15259 // If this render doesn't suspend, we need to delete the fallback
15260 // children. Wait until the complete phase, after we've confirmed the
15261 // fallback is no longer needed.
15262 // TODO: Would it be better to store the fallback fragment on
15263 // the stateNode?
15264
15265 // Continue rendering the children, like we normally do.
15266 child = next = primaryChild;
15267 }
15268 } else {
15269 // The current tree has not already timed out. That means the primary
15270 // children are not wrapped in a fragment fiber.
15271 var _currentPrimaryChild = current$$1.child;
15272 if (nextDidTimeout) {
15273 // Timed out. Wrap the children in a fragment fiber to keep them
15274 // separate from the fallback children.
15275 var _nextFallbackChildren2 = nextProps.fallback;
15276 var _primaryChildFragment2 = createFiberFromFragment(
15277 // It shouldn't matter what the pending props are because we aren't
15278 // going to render this fragment.
15279 null, mode, NoWork, null);
15280 _primaryChildFragment2.child = _currentPrimaryChild;
15281
15282 // Even though we're creating a new fiber, there are no new children,
15283 // because we're reusing an already mounted tree. So we don't need to
15284 // schedule a placement.
15285 // primaryChildFragment.effectTag |= Placement;
15286
15287 if ((workInProgress.mode & ConcurrentMode) === NoContext) {
15288 // Outside of concurrent mode, we commit the effects from the
15289 var _progressedState2 = workInProgress.memoizedState;
15290 var _progressedPrimaryChild2 = _progressedState2 !== null ? workInProgress.child.child : workInProgress.child;
15291 _primaryChildFragment2.child = _progressedPrimaryChild2;
15292 }
15293
15294 // Because primaryChildFragment is a new fiber that we're inserting as the
15295 // parent of a new tree, we need to set its treeBaseDuration.
15296 if (enableProfilerTimer && workInProgress.mode & ProfileMode) {
15297 // treeBaseDuration is the sum of all the child tree base durations.
15298 var _treeBaseDuration = 0;
15299 var _hiddenChild = _primaryChildFragment2.child;
15300 while (_hiddenChild !== null) {
15301 _treeBaseDuration += _hiddenChild.treeBaseDuration;
15302 _hiddenChild = _hiddenChild.sibling;
15303 }
15304 _primaryChildFragment2.treeBaseDuration = _treeBaseDuration;
15305 }
15306
15307 // Create a fragment from the fallback children, too.
15308 var _fallbackChildFragment2 = _primaryChildFragment2.sibling = createFiberFromFragment(_nextFallbackChildren2, mode, renderExpirationTime, null);
15309 _fallbackChildFragment2.effectTag |= Placement;
15310 child = _primaryChildFragment2;
15311 _primaryChildFragment2.childExpirationTime = NoWork;
15312 // Skip the primary children, and continue working on the
15313 // fallback children.
15314 next = _fallbackChildFragment2;
15315 child.return = next.return = workInProgress;
15316 } else {
15317 // Still haven't timed out. Continue rendering the children, like we
15318 // normally do.
15319 var _nextPrimaryChildren2 = nextProps.children;
15320 next = child = reconcileChildFibers(workInProgress, _currentPrimaryChild, _nextPrimaryChildren2, renderExpirationTime);
15321 }
15322 }
15323 workInProgress.stateNode = current$$1.stateNode;
15324 }
15325
15326 workInProgress.memoizedState = nextState;
15327 workInProgress.child = child;
15328 return next;
15329}
15330
15331function updateDehydratedSuspenseComponent(current$$1, workInProgress, renderExpirationTime) {
15332 if (current$$1 === null) {
15333 // During the first pass, we'll bail out and not drill into the children.
15334 // Instead, we'll leave the content in place and try to hydrate it later.
15335 workInProgress.expirationTime = Never;
15336 return null;
15337 }
15338 // We use childExpirationTime to indicate that a child might depend on context, so if
15339 // any context has changed, we need to treat is as if the input might have changed.
15340 var hasContextChanged$$1 = current$$1.childExpirationTime >= renderExpirationTime;
15341 if (didReceiveUpdate || hasContextChanged$$1) {
15342 // This boundary has changed since the first render. This means that we are now unable to
15343 // hydrate it. We might still be able to hydrate it using an earlier expiration time but
15344 // during this render we can't. Instead, we're going to delete the whole subtree and
15345 // instead inject a new real Suspense boundary to take its place, which may render content
15346 // or fallback. The real Suspense boundary will suspend for a while so we have some time
15347 // to ensure it can produce real content, but all state and pending events will be lost.
15348
15349 // Detach from the current dehydrated boundary.
15350 current$$1.alternate = null;
15351 workInProgress.alternate = null;
15352
15353 // Insert a deletion in the effect list.
15354 var returnFiber = workInProgress.return;
15355 !(returnFiber !== null) ? invariant(false, 'Suspense boundaries are never on the root. This is probably a bug in React.') : void 0;
15356 var last = returnFiber.lastEffect;
15357 if (last !== null) {
15358 last.nextEffect = current$$1;
15359 returnFiber.lastEffect = current$$1;
15360 } else {
15361 returnFiber.firstEffect = returnFiber.lastEffect = current$$1;
15362 }
15363 current$$1.nextEffect = null;
15364 current$$1.effectTag = Deletion;
15365
15366 // Upgrade this work in progress to a real Suspense component.
15367 workInProgress.tag = SuspenseComponent;
15368 workInProgress.stateNode = null;
15369 workInProgress.memoizedState = null;
15370 // This is now an insertion.
15371 workInProgress.effectTag |= Placement;
15372 // Retry as a real Suspense component.
15373 return updateSuspenseComponent(null, workInProgress, renderExpirationTime);
15374 }
15375 if ((workInProgress.effectTag & DidCapture) === NoEffect) {
15376 // This is the first attempt.
15377 reenterHydrationStateFromDehydratedSuspenseInstance(workInProgress);
15378 var nextProps = workInProgress.pendingProps;
15379 var nextChildren = nextProps.children;
15380 workInProgress.child = mountChildFibers(workInProgress, null, nextChildren, renderExpirationTime);
15381 return workInProgress.child;
15382 } else {
15383 // Something suspended. Leave the existing children in place.
15384 // TODO: In non-concurrent mode, should we commit the nodes we have hydrated so far?
15385 workInProgress.child = null;
15386 return null;
15387 }
15388}
15389
15390function updatePortalComponent(current$$1, workInProgress, renderExpirationTime) {
15391 pushHostContainer(workInProgress, workInProgress.stateNode.containerInfo);
15392 var nextChildren = workInProgress.pendingProps;
15393 if (current$$1 === null) {
15394 // Portals are special because we don't append the children during mount
15395 // but at commit. Therefore we need to track insertions which the normal
15396 // flow doesn't do during mount. This doesn't happen at the root because
15397 // the root always starts with a "current" with a null child.
15398 // TODO: Consider unifying this with how the root works.
15399 workInProgress.child = reconcileChildFibers(workInProgress, null, nextChildren, renderExpirationTime);
15400 } else {
15401 reconcileChildren(current$$1, workInProgress, nextChildren, renderExpirationTime);
15402 }
15403 return workInProgress.child;
15404}
15405
15406function updateContextProvider(current$$1, workInProgress, renderExpirationTime) {
15407 var providerType = workInProgress.type;
15408 var context = providerType._context;
15409
15410 var newProps = workInProgress.pendingProps;
15411 var oldProps = workInProgress.memoizedProps;
15412
15413 var newValue = newProps.value;
15414
15415 {
15416 var providerPropTypes = workInProgress.type.propTypes;
15417
15418 if (providerPropTypes) {
15419 checkPropTypes(providerPropTypes, newProps, 'prop', 'Context.Provider', getCurrentFiberStackInDev);
15420 }
15421 }
15422
15423 pushProvider(workInProgress, newValue);
15424
15425 if (oldProps !== null) {
15426 var oldValue = oldProps.value;
15427 var changedBits = calculateChangedBits(context, newValue, oldValue);
15428 if (changedBits === 0) {
15429 // No change. Bailout early if children are the same.
15430 if (oldProps.children === newProps.children && !hasContextChanged()) {
15431 return bailoutOnAlreadyFinishedWork(current$$1, workInProgress, renderExpirationTime);
15432 }
15433 } else {
15434 // The context value changed. Search for matching consumers and schedule
15435 // them to update.
15436 propagateContextChange(workInProgress, context, changedBits, renderExpirationTime);
15437 }
15438 }
15439
15440 var newChildren = newProps.children;
15441 reconcileChildren(current$$1, workInProgress, newChildren, renderExpirationTime);
15442 return workInProgress.child;
15443}
15444
15445var hasWarnedAboutUsingContextAsConsumer = false;
15446
15447function updateContextConsumer(current$$1, workInProgress, renderExpirationTime) {
15448 var context = workInProgress.type;
15449 // The logic below for Context differs depending on PROD or DEV mode. In
15450 // DEV mode, we create a separate object for Context.Consumer that acts
15451 // like a proxy to Context. This proxy object adds unnecessary code in PROD
15452 // so we use the old behaviour (Context.Consumer references Context) to
15453 // reduce size and overhead. The separate object references context via
15454 // a property called "_context", which also gives us the ability to check
15455 // in DEV mode if this property exists or not and warn if it does not.
15456 {
15457 if (context._context === undefined) {
15458 // This may be because it's a Context (rather than a Consumer).
15459 // Or it may be because it's older React where they're the same thing.
15460 // We only want to warn if we're sure it's a new React.
15461 if (context !== context.Consumer) {
15462 if (!hasWarnedAboutUsingContextAsConsumer) {
15463 hasWarnedAboutUsingContextAsConsumer = true;
15464 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?');
15465 }
15466 }
15467 } else {
15468 context = context._context;
15469 }
15470 }
15471 var newProps = workInProgress.pendingProps;
15472 var render = newProps.children;
15473
15474 {
15475 !(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;
15476 }
15477
15478 prepareToReadContext(workInProgress, renderExpirationTime);
15479 var newValue = readContext(context, newProps.unstable_observedBits);
15480 var newChildren = void 0;
15481 {
15482 ReactCurrentOwner$3.current = workInProgress;
15483 setCurrentPhase('render');
15484 newChildren = render(newValue);
15485 setCurrentPhase(null);
15486 }
15487
15488 // React DevTools reads this flag.
15489 workInProgress.effectTag |= PerformedWork;
15490 reconcileChildren(current$$1, workInProgress, newChildren, renderExpirationTime);
15491 return workInProgress.child;
15492}
15493
15494function markWorkInProgressReceivedUpdate() {
15495 didReceiveUpdate = true;
15496}
15497
15498function bailoutOnAlreadyFinishedWork(current$$1, workInProgress, renderExpirationTime) {
15499 cancelWorkTimer(workInProgress);
15500
15501 if (current$$1 !== null) {
15502 // Reuse previous context list
15503 workInProgress.contextDependencies = current$$1.contextDependencies;
15504 }
15505
15506 if (enableProfilerTimer) {
15507 // Don't update "base" render times for bailouts.
15508 stopProfilerTimerIfRunning(workInProgress);
15509 }
15510
15511 // Check if the children have any pending work.
15512 var childExpirationTime = workInProgress.childExpirationTime;
15513 if (childExpirationTime < renderExpirationTime) {
15514 // The children don't have any work either. We can skip them.
15515 // TODO: Once we add back resuming, we should check if the children are
15516 // a work-in-progress set. If so, we need to transfer their effects.
15517 return null;
15518 } else {
15519 // This fiber doesn't have work, but its subtree does. Clone the child
15520 // fibers and continue.
15521 cloneChildFibers(current$$1, workInProgress);
15522 return workInProgress.child;
15523 }
15524}
15525
15526function beginWork(current$$1, workInProgress, renderExpirationTime) {
15527 var updateExpirationTime = workInProgress.expirationTime;
15528
15529 if (current$$1 !== null) {
15530 var oldProps = current$$1.memoizedProps;
15531 var newProps = workInProgress.pendingProps;
15532
15533 if (oldProps !== newProps || hasContextChanged()) {
15534 // If props or context changed, mark the fiber as having performed work.
15535 // This may be unset if the props are determined to be equal later (memo).
15536 didReceiveUpdate = true;
15537 } else if (updateExpirationTime < renderExpirationTime) {
15538 didReceiveUpdate = false;
15539 // This fiber does not have any pending work. Bailout without entering
15540 // the begin phase. There's still some bookkeeping we that needs to be done
15541 // in this optimized path, mostly pushing stuff onto the stack.
15542 switch (workInProgress.tag) {
15543 case HostRoot:
15544 pushHostRootContext(workInProgress);
15545 resetHydrationState();
15546 break;
15547 case HostComponent:
15548 pushHostContext(workInProgress);
15549 break;
15550 case ClassComponent:
15551 {
15552 var Component = workInProgress.type;
15553 if (isContextProvider(Component)) {
15554 pushContextProvider(workInProgress);
15555 }
15556 break;
15557 }
15558 case HostPortal:
15559 pushHostContainer(workInProgress, workInProgress.stateNode.containerInfo);
15560 break;
15561 case ContextProvider:
15562 {
15563 var newValue = workInProgress.memoizedProps.value;
15564 pushProvider(workInProgress, newValue);
15565 break;
15566 }
15567 case Profiler:
15568 if (enableProfilerTimer) {
15569 workInProgress.effectTag |= Update;
15570 }
15571 break;
15572 case SuspenseComponent:
15573 {
15574 var state = workInProgress.memoizedState;
15575 var didTimeout = state !== null;
15576 if (didTimeout) {
15577 // If this boundary is currently timed out, we need to decide
15578 // whether to retry the primary children, or to skip over it and
15579 // go straight to the fallback. Check the priority of the primary
15580 var primaryChildFragment = workInProgress.child;
15581 var primaryChildExpirationTime = primaryChildFragment.childExpirationTime;
15582 if (primaryChildExpirationTime !== NoWork && primaryChildExpirationTime >= renderExpirationTime) {
15583 // The primary children have pending work. Use the normal path
15584 // to attempt to render the primary children again.
15585 return updateSuspenseComponent(current$$1, workInProgress, renderExpirationTime);
15586 } else {
15587 // The primary children do not have pending work with sufficient
15588 // priority. Bailout.
15589 var child = bailoutOnAlreadyFinishedWork(current$$1, workInProgress, renderExpirationTime);
15590 if (child !== null) {
15591 // The fallback children have pending work. Skip over the
15592 // primary children and work on the fallback.
15593 return child.sibling;
15594 } else {
15595 return null;
15596 }
15597 }
15598 }
15599 break;
15600 }
15601 case DehydratedSuspenseComponent:
15602 {
15603 if (enableSuspenseServerRenderer) {
15604 // We know that this component will suspend again because if it has
15605 // been unsuspended it has committed as a regular Suspense component.
15606 // If it needs to be retried, it should have work scheduled on it.
15607 workInProgress.effectTag |= DidCapture;
15608 break;
15609 }
15610 }
15611 }
15612 return bailoutOnAlreadyFinishedWork(current$$1, workInProgress, renderExpirationTime);
15613 }
15614 } else {
15615 didReceiveUpdate = false;
15616 }
15617
15618 // Before entering the begin phase, clear the expiration time.
15619 workInProgress.expirationTime = NoWork;
15620
15621 switch (workInProgress.tag) {
15622 case IndeterminateComponent:
15623 {
15624 var elementType = workInProgress.elementType;
15625 return mountIndeterminateComponent(current$$1, workInProgress, elementType, renderExpirationTime);
15626 }
15627 case LazyComponent:
15628 {
15629 var _elementType = workInProgress.elementType;
15630 return mountLazyComponent(current$$1, workInProgress, _elementType, updateExpirationTime, renderExpirationTime);
15631 }
15632 case FunctionComponent:
15633 {
15634 var _Component = workInProgress.type;
15635 var unresolvedProps = workInProgress.pendingProps;
15636 var resolvedProps = workInProgress.elementType === _Component ? unresolvedProps : resolveDefaultProps(_Component, unresolvedProps);
15637 return updateFunctionComponent(current$$1, workInProgress, _Component, resolvedProps, renderExpirationTime);
15638 }
15639 case ClassComponent:
15640 {
15641 var _Component2 = workInProgress.type;
15642 var _unresolvedProps = workInProgress.pendingProps;
15643 var _resolvedProps = workInProgress.elementType === _Component2 ? _unresolvedProps : resolveDefaultProps(_Component2, _unresolvedProps);
15644 return updateClassComponent(current$$1, workInProgress, _Component2, _resolvedProps, renderExpirationTime);
15645 }
15646 case HostRoot:
15647 return updateHostRoot(current$$1, workInProgress, renderExpirationTime);
15648 case HostComponent:
15649 return updateHostComponent(current$$1, workInProgress, renderExpirationTime);
15650 case HostText:
15651 return updateHostText(current$$1, workInProgress);
15652 case SuspenseComponent:
15653 return updateSuspenseComponent(current$$1, workInProgress, renderExpirationTime);
15654 case HostPortal:
15655 return updatePortalComponent(current$$1, workInProgress, renderExpirationTime);
15656 case ForwardRef:
15657 {
15658 var type = workInProgress.type;
15659 var _unresolvedProps2 = workInProgress.pendingProps;
15660 var _resolvedProps2 = workInProgress.elementType === type ? _unresolvedProps2 : resolveDefaultProps(type, _unresolvedProps2);
15661 return updateForwardRef(current$$1, workInProgress, type, _resolvedProps2, renderExpirationTime);
15662 }
15663 case Fragment:
15664 return updateFragment(current$$1, workInProgress, renderExpirationTime);
15665 case Mode:
15666 return updateMode(current$$1, workInProgress, renderExpirationTime);
15667 case Profiler:
15668 return updateProfiler(current$$1, workInProgress, renderExpirationTime);
15669 case ContextProvider:
15670 return updateContextProvider(current$$1, workInProgress, renderExpirationTime);
15671 case ContextConsumer:
15672 return updateContextConsumer(current$$1, workInProgress, renderExpirationTime);
15673 case MemoComponent:
15674 {
15675 var _type2 = workInProgress.type;
15676 var _unresolvedProps3 = workInProgress.pendingProps;
15677 // Resolve outer props first, then resolve inner props.
15678 var _resolvedProps3 = resolveDefaultProps(_type2, _unresolvedProps3);
15679 {
15680 if (workInProgress.type !== workInProgress.elementType) {
15681 var outerPropTypes = _type2.propTypes;
15682 if (outerPropTypes) {
15683 checkPropTypes(outerPropTypes, _resolvedProps3, // Resolved for outer only
15684 'prop', getComponentName(_type2), getCurrentFiberStackInDev);
15685 }
15686 }
15687 }
15688 _resolvedProps3 = resolveDefaultProps(_type2.type, _resolvedProps3);
15689 return updateMemoComponent(current$$1, workInProgress, _type2, _resolvedProps3, updateExpirationTime, renderExpirationTime);
15690 }
15691 case SimpleMemoComponent:
15692 {
15693 return updateSimpleMemoComponent(current$$1, workInProgress, workInProgress.type, workInProgress.pendingProps, updateExpirationTime, renderExpirationTime);
15694 }
15695 case IncompleteClassComponent:
15696 {
15697 var _Component3 = workInProgress.type;
15698 var _unresolvedProps4 = workInProgress.pendingProps;
15699 var _resolvedProps4 = workInProgress.elementType === _Component3 ? _unresolvedProps4 : resolveDefaultProps(_Component3, _unresolvedProps4);
15700 return mountIncompleteClassComponent(current$$1, workInProgress, _Component3, _resolvedProps4, renderExpirationTime);
15701 }
15702 case DehydratedSuspenseComponent:
15703 {
15704 if (enableSuspenseServerRenderer) {
15705 return updateDehydratedSuspenseComponent(current$$1, workInProgress, renderExpirationTime);
15706 }
15707 break;
15708 }
15709 }
15710 invariant(false, 'Unknown unit of work tag. This error is likely caused by a bug in React. Please file an issue.');
15711}
15712
15713var valueCursor = createCursor(null);
15714
15715var rendererSigil = void 0;
15716{
15717 // Use this to detect multiple renderers using the same context
15718 rendererSigil = {};
15719}
15720
15721var currentlyRenderingFiber = null;
15722var lastContextDependency = null;
15723var lastContextWithAllBitsObserved = null;
15724
15725var isDisallowedContextReadInDEV = false;
15726
15727function resetContextDependences() {
15728 // This is called right before React yields execution, to ensure `readContext`
15729 // cannot be called outside the render phase.
15730 currentlyRenderingFiber = null;
15731 lastContextDependency = null;
15732 lastContextWithAllBitsObserved = null;
15733 {
15734 isDisallowedContextReadInDEV = false;
15735 }
15736}
15737
15738function enterDisallowedContextReadInDEV() {
15739 {
15740 isDisallowedContextReadInDEV = true;
15741 }
15742}
15743
15744function exitDisallowedContextReadInDEV() {
15745 {
15746 isDisallowedContextReadInDEV = false;
15747 }
15748}
15749
15750function pushProvider(providerFiber, nextValue) {
15751 var context = providerFiber.type._context;
15752
15753 if (isPrimaryRenderer) {
15754 push(valueCursor, context._currentValue, providerFiber);
15755
15756 context._currentValue = nextValue;
15757 {
15758 !(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;
15759 context._currentRenderer = rendererSigil;
15760 }
15761 } else {
15762 push(valueCursor, context._currentValue2, providerFiber);
15763
15764 context._currentValue2 = nextValue;
15765 {
15766 !(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;
15767 context._currentRenderer2 = rendererSigil;
15768 }
15769 }
15770}
15771
15772function popProvider(providerFiber) {
15773 var currentValue = valueCursor.current;
15774
15775 pop(valueCursor, providerFiber);
15776
15777 var context = providerFiber.type._context;
15778 if (isPrimaryRenderer) {
15779 context._currentValue = currentValue;
15780 } else {
15781 context._currentValue2 = currentValue;
15782 }
15783}
15784
15785function calculateChangedBits(context, newValue, oldValue) {
15786 if (is(oldValue, newValue)) {
15787 // No change
15788 return 0;
15789 } else {
15790 var changedBits = typeof context._calculateChangedBits === 'function' ? context._calculateChangedBits(oldValue, newValue) : maxSigned31BitInt;
15791
15792 {
15793 !((changedBits & maxSigned31BitInt) === changedBits) ? warning$1(false, 'calculateChangedBits: Expected the return value to be a ' + '31-bit integer. Instead received: %s', changedBits) : void 0;
15794 }
15795 return changedBits | 0;
15796 }
15797}
15798
15799function scheduleWorkOnParentPath(parent, renderExpirationTime) {
15800 // Update the child expiration time of all the ancestors, including
15801 // the alternates.
15802 var node = parent;
15803 while (node !== null) {
15804 var alternate = node.alternate;
15805 if (node.childExpirationTime < renderExpirationTime) {
15806 node.childExpirationTime = renderExpirationTime;
15807 if (alternate !== null && alternate.childExpirationTime < renderExpirationTime) {
15808 alternate.childExpirationTime = renderExpirationTime;
15809 }
15810 } else if (alternate !== null && alternate.childExpirationTime < renderExpirationTime) {
15811 alternate.childExpirationTime = renderExpirationTime;
15812 } else {
15813 // Neither alternate was updated, which means the rest of the
15814 // ancestor path already has sufficient priority.
15815 break;
15816 }
15817 node = node.return;
15818 }
15819}
15820
15821function propagateContextChange(workInProgress, context, changedBits, renderExpirationTime) {
15822 var fiber = workInProgress.child;
15823 if (fiber !== null) {
15824 // Set the return pointer of the child to the work-in-progress fiber.
15825 fiber.return = workInProgress;
15826 }
15827 while (fiber !== null) {
15828 var nextFiber = void 0;
15829
15830 // Visit this fiber.
15831 var list = fiber.contextDependencies;
15832 if (list !== null) {
15833 nextFiber = fiber.child;
15834
15835 var dependency = list.first;
15836 while (dependency !== null) {
15837 // Check if the context matches.
15838 if (dependency.context === context && (dependency.observedBits & changedBits) !== 0) {
15839 // Match! Schedule an update on this fiber.
15840
15841 if (fiber.tag === ClassComponent) {
15842 // Schedule a force update on the work-in-progress.
15843 var update = createUpdate(renderExpirationTime);
15844 update.tag = ForceUpdate;
15845 // TODO: Because we don't have a work-in-progress, this will add the
15846 // update to the current fiber, too, which means it will persist even if
15847 // this render is thrown away. Since it's a race condition, not sure it's
15848 // worth fixing.
15849 enqueueUpdate(fiber, update);
15850 }
15851
15852 if (fiber.expirationTime < renderExpirationTime) {
15853 fiber.expirationTime = renderExpirationTime;
15854 }
15855 var alternate = fiber.alternate;
15856 if (alternate !== null && alternate.expirationTime < renderExpirationTime) {
15857 alternate.expirationTime = renderExpirationTime;
15858 }
15859
15860 scheduleWorkOnParentPath(fiber.return, renderExpirationTime);
15861
15862 // Mark the expiration time on the list, too.
15863 if (list.expirationTime < renderExpirationTime) {
15864 list.expirationTime = renderExpirationTime;
15865 }
15866
15867 // Since we already found a match, we can stop traversing the
15868 // dependency list.
15869 break;
15870 }
15871 dependency = dependency.next;
15872 }
15873 } else if (fiber.tag === ContextProvider) {
15874 // Don't scan deeper if this is a matching provider
15875 nextFiber = fiber.type === workInProgress.type ? null : fiber.child;
15876 } else if (enableSuspenseServerRenderer && fiber.tag === DehydratedSuspenseComponent) {
15877 // If a dehydrated suspense component is in this subtree, we don't know
15878 // if it will have any context consumers in it. The best we can do is
15879 // mark it as having updates on its children.
15880 if (fiber.expirationTime < renderExpirationTime) {
15881 fiber.expirationTime = renderExpirationTime;
15882 }
15883 var _alternate = fiber.alternate;
15884 if (_alternate !== null && _alternate.expirationTime < renderExpirationTime) {
15885 _alternate.expirationTime = renderExpirationTime;
15886 }
15887 // This is intentionally passing this fiber as the parent
15888 // because we want to schedule this fiber as having work
15889 // on its children. We'll use the childExpirationTime on
15890 // this fiber to indicate that a context has changed.
15891 scheduleWorkOnParentPath(fiber, renderExpirationTime);
15892 nextFiber = fiber.sibling;
15893 } else {
15894 // Traverse down.
15895 nextFiber = fiber.child;
15896 }
15897
15898 if (nextFiber !== null) {
15899 // Set the return pointer of the child to the work-in-progress fiber.
15900 nextFiber.return = fiber;
15901 } else {
15902 // No child. Traverse to next sibling.
15903 nextFiber = fiber;
15904 while (nextFiber !== null) {
15905 if (nextFiber === workInProgress) {
15906 // We're back to the root of this subtree. Exit.
15907 nextFiber = null;
15908 break;
15909 }
15910 var sibling = nextFiber.sibling;
15911 if (sibling !== null) {
15912 // Set the return pointer of the sibling to the work-in-progress fiber.
15913 sibling.return = nextFiber.return;
15914 nextFiber = sibling;
15915 break;
15916 }
15917 // No more siblings. Traverse up.
15918 nextFiber = nextFiber.return;
15919 }
15920 }
15921 fiber = nextFiber;
15922 }
15923}
15924
15925function prepareToReadContext(workInProgress, renderExpirationTime) {
15926 currentlyRenderingFiber = workInProgress;
15927 lastContextDependency = null;
15928 lastContextWithAllBitsObserved = null;
15929
15930 var currentDependencies = workInProgress.contextDependencies;
15931 if (currentDependencies !== null && currentDependencies.expirationTime >= renderExpirationTime) {
15932 // Context list has a pending update. Mark that this fiber performed work.
15933 markWorkInProgressReceivedUpdate();
15934 }
15935
15936 // Reset the work-in-progress list
15937 workInProgress.contextDependencies = null;
15938}
15939
15940function readContext(context, observedBits) {
15941 {
15942 // This warning would fire if you read context inside a Hook like useMemo.
15943 // Unlike the class check below, it's not enforced in production for perf.
15944 !!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;
15945 }
15946
15947 if (lastContextWithAllBitsObserved === context) {
15948 // Nothing to do. We already observe everything in this context.
15949 } else if (observedBits === false || observedBits === 0) {
15950 // Do not observe any updates.
15951 } else {
15952 var resolvedObservedBits = void 0; // Avoid deopting on observable arguments or heterogeneous types.
15953 if (typeof observedBits !== 'number' || observedBits === maxSigned31BitInt) {
15954 // Observe all updates.
15955 lastContextWithAllBitsObserved = context;
15956 resolvedObservedBits = maxSigned31BitInt;
15957 } else {
15958 resolvedObservedBits = observedBits;
15959 }
15960
15961 var contextItem = {
15962 context: context,
15963 observedBits: resolvedObservedBits,
15964 next: null
15965 };
15966
15967 if (lastContextDependency === null) {
15968 !(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;
15969
15970 // This is the first dependency for this component. Create a new list.
15971 lastContextDependency = contextItem;
15972 currentlyRenderingFiber.contextDependencies = {
15973 first: contextItem,
15974 expirationTime: NoWork
15975 };
15976 } else {
15977 // Append a new context item.
15978 lastContextDependency = lastContextDependency.next = contextItem;
15979 }
15980 }
15981 return isPrimaryRenderer ? context._currentValue : context._currentValue2;
15982}
15983
15984// UpdateQueue is a linked list of prioritized updates.
15985//
15986// Like fibers, update queues come in pairs: a current queue, which represents
15987// the visible state of the screen, and a work-in-progress queue, which can be
15988// mutated and processed asynchronously before it is committed — a form of
15989// double buffering. If a work-in-progress render is discarded before finishing,
15990// we create a new work-in-progress by cloning the current queue.
15991//
15992// Both queues share a persistent, singly-linked list structure. To schedule an
15993// update, we append it to the end of both queues. Each queue maintains a
15994// pointer to first update in the persistent list that hasn't been processed.
15995// The work-in-progress pointer always has a position equal to or greater than
15996// the current queue, since we always work on that one. The current queue's
15997// pointer is only updated during the commit phase, when we swap in the
15998// work-in-progress.
15999//
16000// For example:
16001//
16002// Current pointer: A - B - C - D - E - F
16003// Work-in-progress pointer: D - E - F
16004// ^
16005// The work-in-progress queue has
16006// processed more updates than current.
16007//
16008// The reason we append to both queues is because otherwise we might drop
16009// updates without ever processing them. For example, if we only add updates to
16010// the work-in-progress queue, some updates could be lost whenever a work-in
16011// -progress render restarts by cloning from current. Similarly, if we only add
16012// updates to the current queue, the updates will be lost whenever an already
16013// in-progress queue commits and swaps with the current queue. However, by
16014// adding to both queues, we guarantee that the update will be part of the next
16015// work-in-progress. (And because the work-in-progress queue becomes the
16016// current queue once it commits, there's no danger of applying the same
16017// update twice.)
16018//
16019// Prioritization
16020// --------------
16021//
16022// Updates are not sorted by priority, but by insertion; new updates are always
16023// appended to the end of the list.
16024//
16025// The priority is still important, though. When processing the update queue
16026// during the render phase, only the updates with sufficient priority are
16027// included in the result. If we skip an update because it has insufficient
16028// priority, it remains in the queue to be processed later, during a lower
16029// priority render. Crucially, all updates subsequent to a skipped update also
16030// remain in the queue *regardless of their priority*. That means high priority
16031// updates are sometimes processed twice, at two separate priorities. We also
16032// keep track of a base state, that represents the state before the first
16033// update in the queue is applied.
16034//
16035// For example:
16036//
16037// Given a base state of '', and the following queue of updates
16038//
16039// A1 - B2 - C1 - D2
16040//
16041// where the number indicates the priority, and the update is applied to the
16042// previous state by appending a letter, React will process these updates as
16043// two separate renders, one per distinct priority level:
16044//
16045// First render, at priority 1:
16046// Base state: ''
16047// Updates: [A1, C1]
16048// Result state: 'AC'
16049//
16050// Second render, at priority 2:
16051// Base state: 'A' <- The base state does not include C1,
16052// because B2 was skipped.
16053// Updates: [B2, C1, D2] <- C1 was rebased on top of B2
16054// Result state: 'ABCD'
16055//
16056// Because we process updates in insertion order, and rebase high priority
16057// updates when preceding updates are skipped, the final result is deterministic
16058// regardless of priority. Intermediate state may vary according to system
16059// resources, but the final state is always the same.
16060
16061var UpdateState = 0;
16062var ReplaceState = 1;
16063var ForceUpdate = 2;
16064var CaptureUpdate = 3;
16065
16066// Global state that is reset at the beginning of calling `processUpdateQueue`.
16067// It should only be read right after calling `processUpdateQueue`, via
16068// `checkHasForceUpdateAfterProcessing`.
16069var hasForceUpdate = false;
16070
16071var didWarnUpdateInsideUpdate = void 0;
16072var currentlyProcessingQueue = void 0;
16073var resetCurrentlyProcessingQueue = void 0;
16074{
16075 didWarnUpdateInsideUpdate = false;
16076 currentlyProcessingQueue = null;
16077 resetCurrentlyProcessingQueue = function () {
16078 currentlyProcessingQueue = null;
16079 };
16080}
16081
16082function createUpdateQueue(baseState) {
16083 var queue = {
16084 baseState: baseState,
16085 firstUpdate: null,
16086 lastUpdate: null,
16087 firstCapturedUpdate: null,
16088 lastCapturedUpdate: null,
16089 firstEffect: null,
16090 lastEffect: null,
16091 firstCapturedEffect: null,
16092 lastCapturedEffect: null
16093 };
16094 return queue;
16095}
16096
16097function cloneUpdateQueue(currentQueue) {
16098 var queue = {
16099 baseState: currentQueue.baseState,
16100 firstUpdate: currentQueue.firstUpdate,
16101 lastUpdate: currentQueue.lastUpdate,
16102
16103 // TODO: With resuming, if we bail out and resuse the child tree, we should
16104 // keep these effects.
16105 firstCapturedUpdate: null,
16106 lastCapturedUpdate: null,
16107
16108 firstEffect: null,
16109 lastEffect: null,
16110
16111 firstCapturedEffect: null,
16112 lastCapturedEffect: null
16113 };
16114 return queue;
16115}
16116
16117function createUpdate(expirationTime) {
16118 return {
16119 expirationTime: expirationTime,
16120
16121 tag: UpdateState,
16122 payload: null,
16123 callback: null,
16124
16125 next: null,
16126 nextEffect: null
16127 };
16128}
16129
16130function appendUpdateToQueue(queue, update) {
16131 // Append the update to the end of the list.
16132 if (queue.lastUpdate === null) {
16133 // Queue is empty
16134 queue.firstUpdate = queue.lastUpdate = update;
16135 } else {
16136 queue.lastUpdate.next = update;
16137 queue.lastUpdate = update;
16138 }
16139}
16140
16141function enqueueUpdate(fiber, update) {
16142 // Update queues are created lazily.
16143 var alternate = fiber.alternate;
16144 var queue1 = void 0;
16145 var queue2 = void 0;
16146 if (alternate === null) {
16147 // There's only one fiber.
16148 queue1 = fiber.updateQueue;
16149 queue2 = null;
16150 if (queue1 === null) {
16151 queue1 = fiber.updateQueue = createUpdateQueue(fiber.memoizedState);
16152 }
16153 } else {
16154 // There are two owners.
16155 queue1 = fiber.updateQueue;
16156 queue2 = alternate.updateQueue;
16157 if (queue1 === null) {
16158 if (queue2 === null) {
16159 // Neither fiber has an update queue. Create new ones.
16160 queue1 = fiber.updateQueue = createUpdateQueue(fiber.memoizedState);
16161 queue2 = alternate.updateQueue = createUpdateQueue(alternate.memoizedState);
16162 } else {
16163 // Only one fiber has an update queue. Clone to create a new one.
16164 queue1 = fiber.updateQueue = cloneUpdateQueue(queue2);
16165 }
16166 } else {
16167 if (queue2 === null) {
16168 // Only one fiber has an update queue. Clone to create a new one.
16169 queue2 = alternate.updateQueue = cloneUpdateQueue(queue1);
16170 } else {
16171 // Both owners have an update queue.
16172 }
16173 }
16174 }
16175 if (queue2 === null || queue1 === queue2) {
16176 // There's only a single queue.
16177 appendUpdateToQueue(queue1, update);
16178 } else {
16179 // There are two queues. We need to append the update to both queues,
16180 // while accounting for the persistent structure of the list — we don't
16181 // want the same update to be added multiple times.
16182 if (queue1.lastUpdate === null || queue2.lastUpdate === null) {
16183 // One of the queues is not empty. We must add the update to both queues.
16184 appendUpdateToQueue(queue1, update);
16185 appendUpdateToQueue(queue2, update);
16186 } else {
16187 // Both queues are non-empty. The last update is the same in both lists,
16188 // because of structural sharing. So, only append to one of the lists.
16189 appendUpdateToQueue(queue1, update);
16190 // But we still need to update the `lastUpdate` pointer of queue2.
16191 queue2.lastUpdate = update;
16192 }
16193 }
16194
16195 {
16196 if (fiber.tag === ClassComponent && (currentlyProcessingQueue === queue1 || queue2 !== null && currentlyProcessingQueue === queue2) && !didWarnUpdateInsideUpdate) {
16197 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.');
16198 didWarnUpdateInsideUpdate = true;
16199 }
16200 }
16201}
16202
16203function enqueueCapturedUpdate(workInProgress, update) {
16204 // Captured updates go into a separate list, and only on the work-in-
16205 // progress queue.
16206 var workInProgressQueue = workInProgress.updateQueue;
16207 if (workInProgressQueue === null) {
16208 workInProgressQueue = workInProgress.updateQueue = createUpdateQueue(workInProgress.memoizedState);
16209 } else {
16210 // TODO: I put this here rather than createWorkInProgress so that we don't
16211 // clone the queue unnecessarily. There's probably a better way to
16212 // structure this.
16213 workInProgressQueue = ensureWorkInProgressQueueIsAClone(workInProgress, workInProgressQueue);
16214 }
16215
16216 // Append the update to the end of the list.
16217 if (workInProgressQueue.lastCapturedUpdate === null) {
16218 // This is the first render phase update
16219 workInProgressQueue.firstCapturedUpdate = workInProgressQueue.lastCapturedUpdate = update;
16220 } else {
16221 workInProgressQueue.lastCapturedUpdate.next = update;
16222 workInProgressQueue.lastCapturedUpdate = update;
16223 }
16224}
16225
16226function ensureWorkInProgressQueueIsAClone(workInProgress, queue) {
16227 var current = workInProgress.alternate;
16228 if (current !== null) {
16229 // If the work-in-progress queue is equal to the current queue,
16230 // we need to clone it first.
16231 if (queue === current.updateQueue) {
16232 queue = workInProgress.updateQueue = cloneUpdateQueue(queue);
16233 }
16234 }
16235 return queue;
16236}
16237
16238function getStateFromUpdate(workInProgress, queue, update, prevState, nextProps, instance) {
16239 switch (update.tag) {
16240 case ReplaceState:
16241 {
16242 var _payload = update.payload;
16243 if (typeof _payload === 'function') {
16244 // Updater function
16245 {
16246 enterDisallowedContextReadInDEV();
16247 if (debugRenderPhaseSideEffects || debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) {
16248 _payload.call(instance, prevState, nextProps);
16249 }
16250 }
16251 var nextState = _payload.call(instance, prevState, nextProps);
16252 {
16253 exitDisallowedContextReadInDEV();
16254 }
16255 return nextState;
16256 }
16257 // State object
16258 return _payload;
16259 }
16260 case CaptureUpdate:
16261 {
16262 workInProgress.effectTag = workInProgress.effectTag & ~ShouldCapture | DidCapture;
16263 }
16264 // Intentional fallthrough
16265 case UpdateState:
16266 {
16267 var _payload2 = update.payload;
16268 var partialState = void 0;
16269 if (typeof _payload2 === 'function') {
16270 // Updater function
16271 {
16272 enterDisallowedContextReadInDEV();
16273 if (debugRenderPhaseSideEffects || debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) {
16274 _payload2.call(instance, prevState, nextProps);
16275 }
16276 }
16277 partialState = _payload2.call(instance, prevState, nextProps);
16278 {
16279 exitDisallowedContextReadInDEV();
16280 }
16281 } else {
16282 // Partial state object
16283 partialState = _payload2;
16284 }
16285 if (partialState === null || partialState === undefined) {
16286 // Null and undefined are treated as no-ops.
16287 return prevState;
16288 }
16289 // Merge the partial state and the previous state.
16290 return _assign({}, prevState, partialState);
16291 }
16292 case ForceUpdate:
16293 {
16294 hasForceUpdate = true;
16295 return prevState;
16296 }
16297 }
16298 return prevState;
16299}
16300
16301function processUpdateQueue(workInProgress, queue, props, instance, renderExpirationTime) {
16302 hasForceUpdate = false;
16303
16304 queue = ensureWorkInProgressQueueIsAClone(workInProgress, queue);
16305
16306 {
16307 currentlyProcessingQueue = queue;
16308 }
16309
16310 // These values may change as we process the queue.
16311 var newBaseState = queue.baseState;
16312 var newFirstUpdate = null;
16313 var newExpirationTime = NoWork;
16314
16315 // Iterate through the list of updates to compute the result.
16316 var update = queue.firstUpdate;
16317 var resultState = newBaseState;
16318 while (update !== null) {
16319 var updateExpirationTime = update.expirationTime;
16320 if (updateExpirationTime < renderExpirationTime) {
16321 // This update does not have sufficient priority. Skip it.
16322 if (newFirstUpdate === null) {
16323 // This is the first skipped update. It will be the first update in
16324 // the new list.
16325 newFirstUpdate = update;
16326 // Since this is the first update that was skipped, the current result
16327 // is the new base state.
16328 newBaseState = resultState;
16329 }
16330 // Since this update will remain in the list, update the remaining
16331 // expiration time.
16332 if (newExpirationTime < updateExpirationTime) {
16333 newExpirationTime = updateExpirationTime;
16334 }
16335 } else {
16336 // This update does have sufficient priority. Process it and compute
16337 // a new result.
16338 resultState = getStateFromUpdate(workInProgress, queue, update, resultState, props, instance);
16339 var _callback = update.callback;
16340 if (_callback !== null) {
16341 workInProgress.effectTag |= Callback;
16342 // Set this to null, in case it was mutated during an aborted render.
16343 update.nextEffect = null;
16344 if (queue.lastEffect === null) {
16345 queue.firstEffect = queue.lastEffect = update;
16346 } else {
16347 queue.lastEffect.nextEffect = update;
16348 queue.lastEffect = update;
16349 }
16350 }
16351 }
16352 // Continue to the next update.
16353 update = update.next;
16354 }
16355
16356 // Separately, iterate though the list of captured updates.
16357 var newFirstCapturedUpdate = null;
16358 update = queue.firstCapturedUpdate;
16359 while (update !== null) {
16360 var _updateExpirationTime = update.expirationTime;
16361 if (_updateExpirationTime < renderExpirationTime) {
16362 // This update does not have sufficient priority. Skip it.
16363 if (newFirstCapturedUpdate === null) {
16364 // This is the first skipped captured update. It will be the first
16365 // update in the new list.
16366 newFirstCapturedUpdate = update;
16367 // If this is the first update that was skipped, the current result is
16368 // the new base state.
16369 if (newFirstUpdate === null) {
16370 newBaseState = resultState;
16371 }
16372 }
16373 // Since this update will remain in the list, update the remaining
16374 // expiration time.
16375 if (newExpirationTime < _updateExpirationTime) {
16376 newExpirationTime = _updateExpirationTime;
16377 }
16378 } else {
16379 // This update does have sufficient priority. Process it and compute
16380 // a new result.
16381 resultState = getStateFromUpdate(workInProgress, queue, update, resultState, props, instance);
16382 var _callback2 = update.callback;
16383 if (_callback2 !== null) {
16384 workInProgress.effectTag |= Callback;
16385 // Set this to null, in case it was mutated during an aborted render.
16386 update.nextEffect = null;
16387 if (queue.lastCapturedEffect === null) {
16388 queue.firstCapturedEffect = queue.lastCapturedEffect = update;
16389 } else {
16390 queue.lastCapturedEffect.nextEffect = update;
16391 queue.lastCapturedEffect = update;
16392 }
16393 }
16394 }
16395 update = update.next;
16396 }
16397
16398 if (newFirstUpdate === null) {
16399 queue.lastUpdate = null;
16400 }
16401 if (newFirstCapturedUpdate === null) {
16402 queue.lastCapturedUpdate = null;
16403 } else {
16404 workInProgress.effectTag |= Callback;
16405 }
16406 if (newFirstUpdate === null && newFirstCapturedUpdate === null) {
16407 // We processed every update, without skipping. That means the new base
16408 // state is the same as the result state.
16409 newBaseState = resultState;
16410 }
16411
16412 queue.baseState = newBaseState;
16413 queue.firstUpdate = newFirstUpdate;
16414 queue.firstCapturedUpdate = newFirstCapturedUpdate;
16415
16416 // Set the remaining expiration time to be whatever is remaining in the queue.
16417 // This should be fine because the only two other things that contribute to
16418 // expiration time are props and context. We're already in the middle of the
16419 // begin phase by the time we start processing the queue, so we've already
16420 // dealt with the props. Context in components that specify
16421 // shouldComponentUpdate is tricky; but we'll have to account for
16422 // that regardless.
16423 workInProgress.expirationTime = newExpirationTime;
16424 workInProgress.memoizedState = resultState;
16425
16426 {
16427 currentlyProcessingQueue = null;
16428 }
16429}
16430
16431function callCallback(callback, context) {
16432 !(typeof callback === 'function') ? invariant(false, 'Invalid argument passed as callback. Expected a function. Instead received: %s', callback) : void 0;
16433 callback.call(context);
16434}
16435
16436function resetHasForceUpdateBeforeProcessing() {
16437 hasForceUpdate = false;
16438}
16439
16440function checkHasForceUpdateAfterProcessing() {
16441 return hasForceUpdate;
16442}
16443
16444function commitUpdateQueue(finishedWork, finishedQueue, instance, renderExpirationTime) {
16445 // If the finished render included captured updates, and there are still
16446 // lower priority updates left over, we need to keep the captured updates
16447 // in the queue so that they are rebased and not dropped once we process the
16448 // queue again at the lower priority.
16449 if (finishedQueue.firstCapturedUpdate !== null) {
16450 // Join the captured update list to the end of the normal list.
16451 if (finishedQueue.lastUpdate !== null) {
16452 finishedQueue.lastUpdate.next = finishedQueue.firstCapturedUpdate;
16453 finishedQueue.lastUpdate = finishedQueue.lastCapturedUpdate;
16454 }
16455 // Clear the list of captured updates.
16456 finishedQueue.firstCapturedUpdate = finishedQueue.lastCapturedUpdate = null;
16457 }
16458
16459 // Commit the effects
16460 commitUpdateEffects(finishedQueue.firstEffect, instance);
16461 finishedQueue.firstEffect = finishedQueue.lastEffect = null;
16462
16463 commitUpdateEffects(finishedQueue.firstCapturedEffect, instance);
16464 finishedQueue.firstCapturedEffect = finishedQueue.lastCapturedEffect = null;
16465}
16466
16467function commitUpdateEffects(effect, instance) {
16468 while (effect !== null) {
16469 var _callback3 = effect.callback;
16470 if (_callback3 !== null) {
16471 effect.callback = null;
16472 callCallback(_callback3, instance);
16473 }
16474 effect = effect.nextEffect;
16475 }
16476}
16477
16478function createCapturedValue(value, source) {
16479 // If the value is an error, call this function immediately after it is thrown
16480 // so the stack is accurate.
16481 return {
16482 value: value,
16483 source: source,
16484 stack: getStackByFiberInDevAndProd(source)
16485 };
16486}
16487
16488function markUpdate(workInProgress) {
16489 // Tag the fiber with an update effect. This turns a Placement into
16490 // a PlacementAndUpdate.
16491 workInProgress.effectTag |= Update;
16492}
16493
16494function markRef$1(workInProgress) {
16495 workInProgress.effectTag |= Ref;
16496}
16497
16498var appendAllChildren = void 0;
16499var updateHostContainer = void 0;
16500var updateHostComponent$1 = void 0;
16501var updateHostText$1 = void 0;
16502if (supportsMutation) {
16503 // Mutation mode
16504
16505 appendAllChildren = function (parent, workInProgress, needsVisibilityToggle, isHidden) {
16506 // We only have the top Fiber that was created but we need recurse down its
16507 // children to find all the terminal nodes.
16508 var node = workInProgress.child;
16509 while (node !== null) {
16510 if (node.tag === HostComponent || node.tag === HostText) {
16511 appendInitialChild(parent, node.stateNode);
16512 } else if (node.tag === HostPortal) {
16513 // If we have a portal child, then we don't want to traverse
16514 // down its children. Instead, we'll get insertions from each child in
16515 // the portal directly.
16516 } else if (node.child !== null) {
16517 node.child.return = node;
16518 node = node.child;
16519 continue;
16520 }
16521 if (node === workInProgress) {
16522 return;
16523 }
16524 while (node.sibling === null) {
16525 if (node.return === null || node.return === workInProgress) {
16526 return;
16527 }
16528 node = node.return;
16529 }
16530 node.sibling.return = node.return;
16531 node = node.sibling;
16532 }
16533 };
16534
16535 updateHostContainer = function (workInProgress) {
16536 // Noop
16537 };
16538 updateHostComponent$1 = function (current, workInProgress, type, newProps, rootContainerInstance) {
16539 // If we have an alternate, that means this is an update and we need to
16540 // schedule a side-effect to do the updates.
16541 var oldProps = current.memoizedProps;
16542 if (oldProps === newProps) {
16543 // In mutation mode, this is sufficient for a bailout because
16544 // we won't touch this node even if children changed.
16545 return;
16546 }
16547
16548 // If we get updated because one of our children updated, we don't
16549 // have newProps so we'll have to reuse them.
16550 // TODO: Split the update API as separate for the props vs. children.
16551 // Even better would be if children weren't special cased at all tho.
16552 var instance = workInProgress.stateNode;
16553 var currentHostContext = getHostContext();
16554 // TODO: Experiencing an error where oldProps is null. Suggests a host
16555 // component is hitting the resume path. Figure out why. Possibly
16556 // related to `hidden`.
16557 var updatePayload = prepareUpdate(instance, type, oldProps, newProps, rootContainerInstance, currentHostContext);
16558 // TODO: Type this specific to this type of component.
16559 workInProgress.updateQueue = updatePayload;
16560 // If the update payload indicates that there is a change or if there
16561 // is a new ref we mark this as an update. All the work is done in commitWork.
16562 if (updatePayload) {
16563 markUpdate(workInProgress);
16564 }
16565 };
16566 updateHostText$1 = function (current, workInProgress, oldText, newText) {
16567 // If the text differs, mark it as an update. All the work in done in commitWork.
16568 if (oldText !== newText) {
16569 markUpdate(workInProgress);
16570 }
16571 };
16572} else if (supportsPersistence) {
16573 // Persistent host tree mode
16574
16575 appendAllChildren = function (parent, workInProgress, needsVisibilityToggle, isHidden) {
16576 // We only have the top Fiber that was created but we need recurse down its
16577 // children to find all the terminal nodes.
16578 var node = workInProgress.child;
16579 while (node !== null) {
16580 // eslint-disable-next-line no-labels
16581 branches: if (node.tag === HostComponent) {
16582 var instance = node.stateNode;
16583 if (needsVisibilityToggle) {
16584 var props = node.memoizedProps;
16585 var type = node.type;
16586 if (isHidden) {
16587 // This child is inside a timed out tree. Hide it.
16588 instance = cloneHiddenInstance(instance, type, props, node);
16589 } else {
16590 // This child was previously inside a timed out tree. If it was not
16591 // updated during this render, it may need to be unhidden. Clone
16592 // again to be sure.
16593 instance = cloneUnhiddenInstance(instance, type, props, node);
16594 }
16595 node.stateNode = instance;
16596 }
16597 appendInitialChild(parent, instance);
16598 } else if (node.tag === HostText) {
16599 var _instance = node.stateNode;
16600 if (needsVisibilityToggle) {
16601 var text = node.memoizedProps;
16602 var rootContainerInstance = getRootHostContainer();
16603 var currentHostContext = getHostContext();
16604 if (isHidden) {
16605 _instance = createHiddenTextInstance(text, rootContainerInstance, currentHostContext, workInProgress);
16606 } else {
16607 _instance = createTextInstance(text, rootContainerInstance, currentHostContext, workInProgress);
16608 }
16609 node.stateNode = _instance;
16610 }
16611 appendInitialChild(parent, _instance);
16612 } else if (node.tag === HostPortal) {
16613 // If we have a portal child, then we don't want to traverse
16614 // down its children. Instead, we'll get insertions from each child in
16615 // the portal directly.
16616 } else if (node.tag === SuspenseComponent) {
16617 var current = node.alternate;
16618 if (current !== null) {
16619 var oldState = current.memoizedState;
16620 var newState = node.memoizedState;
16621 var oldIsHidden = oldState !== null;
16622 var newIsHidden = newState !== null;
16623 if (oldIsHidden !== newIsHidden) {
16624 // The placeholder either just timed out or switched back to the normal
16625 // children after having previously timed out. Toggle the visibility of
16626 // the direct host children.
16627 var primaryChildParent = newIsHidden ? node.child : node;
16628 if (primaryChildParent !== null) {
16629 appendAllChildren(parent, primaryChildParent, true, newIsHidden);
16630 }
16631 // eslint-disable-next-line no-labels
16632 break branches;
16633 }
16634 }
16635 if (node.child !== null) {
16636 // Continue traversing like normal
16637 node.child.return = node;
16638 node = node.child;
16639 continue;
16640 }
16641 } else if (node.child !== null) {
16642 node.child.return = node;
16643 node = node.child;
16644 continue;
16645 }
16646 // $FlowFixMe This is correct but Flow is confused by the labeled break.
16647 node = node;
16648 if (node === workInProgress) {
16649 return;
16650 }
16651 while (node.sibling === null) {
16652 if (node.return === null || node.return === workInProgress) {
16653 return;
16654 }
16655 node = node.return;
16656 }
16657 node.sibling.return = node.return;
16658 node = node.sibling;
16659 }
16660 };
16661
16662 // An unfortunate fork of appendAllChildren because we have two different parent types.
16663 var appendAllChildrenToContainer = function (containerChildSet, workInProgress, needsVisibilityToggle, isHidden) {
16664 // We only have the top Fiber that was created but we need recurse down its
16665 // children to find all the terminal nodes.
16666 var node = workInProgress.child;
16667 while (node !== null) {
16668 // eslint-disable-next-line no-labels
16669 branches: if (node.tag === HostComponent) {
16670 var instance = node.stateNode;
16671 if (needsVisibilityToggle) {
16672 var props = node.memoizedProps;
16673 var type = node.type;
16674 if (isHidden) {
16675 // This child is inside a timed out tree. Hide it.
16676 instance = cloneHiddenInstance(instance, type, props, node);
16677 } else {
16678 // This child was previously inside a timed out tree. If it was not
16679 // updated during this render, it may need to be unhidden. Clone
16680 // again to be sure.
16681 instance = cloneUnhiddenInstance(instance, type, props, node);
16682 }
16683 node.stateNode = instance;
16684 }
16685 appendChildToContainerChildSet(containerChildSet, instance);
16686 } else if (node.tag === HostText) {
16687 var _instance2 = node.stateNode;
16688 if (needsVisibilityToggle) {
16689 var text = node.memoizedProps;
16690 var rootContainerInstance = getRootHostContainer();
16691 var currentHostContext = getHostContext();
16692 if (isHidden) {
16693 _instance2 = createHiddenTextInstance(text, rootContainerInstance, currentHostContext, workInProgress);
16694 } else {
16695 _instance2 = createTextInstance(text, rootContainerInstance, currentHostContext, workInProgress);
16696 }
16697 node.stateNode = _instance2;
16698 }
16699 appendChildToContainerChildSet(containerChildSet, _instance2);
16700 } else if (node.tag === HostPortal) {
16701 // If we have a portal child, then we don't want to traverse
16702 // down its children. Instead, we'll get insertions from each child in
16703 // the portal directly.
16704 } else if (node.tag === SuspenseComponent) {
16705 var current = node.alternate;
16706 if (current !== null) {
16707 var oldState = current.memoizedState;
16708 var newState = node.memoizedState;
16709 var oldIsHidden = oldState !== null;
16710 var newIsHidden = newState !== null;
16711 if (oldIsHidden !== newIsHidden) {
16712 // The placeholder either just timed out or switched back to the normal
16713 // children after having previously timed out. Toggle the visibility of
16714 // the direct host children.
16715 var primaryChildParent = newIsHidden ? node.child : node;
16716 if (primaryChildParent !== null) {
16717 appendAllChildrenToContainer(containerChildSet, primaryChildParent, true, newIsHidden);
16718 }
16719 // eslint-disable-next-line no-labels
16720 break branches;
16721 }
16722 }
16723 if (node.child !== null) {
16724 // Continue traversing like normal
16725 node.child.return = node;
16726 node = node.child;
16727 continue;
16728 }
16729 } else if (node.child !== null) {
16730 node.child.return = node;
16731 node = node.child;
16732 continue;
16733 }
16734 // $FlowFixMe This is correct but Flow is confused by the labeled break.
16735 node = node;
16736 if (node === workInProgress) {
16737 return;
16738 }
16739 while (node.sibling === null) {
16740 if (node.return === null || node.return === workInProgress) {
16741 return;
16742 }
16743 node = node.return;
16744 }
16745 node.sibling.return = node.return;
16746 node = node.sibling;
16747 }
16748 };
16749 updateHostContainer = function (workInProgress) {
16750 var portalOrRoot = workInProgress.stateNode;
16751 var childrenUnchanged = workInProgress.firstEffect === null;
16752 if (childrenUnchanged) {
16753 // No changes, just reuse the existing instance.
16754 } else {
16755 var container = portalOrRoot.containerInfo;
16756 var newChildSet = createContainerChildSet(container);
16757 // If children might have changed, we have to add them all to the set.
16758 appendAllChildrenToContainer(newChildSet, workInProgress, false, false);
16759 portalOrRoot.pendingChildren = newChildSet;
16760 // Schedule an update on the container to swap out the container.
16761 markUpdate(workInProgress);
16762 finalizeContainerChildren(container, newChildSet);
16763 }
16764 };
16765 updateHostComponent$1 = function (current, workInProgress, type, newProps, rootContainerInstance) {
16766 var currentInstance = current.stateNode;
16767 var oldProps = current.memoizedProps;
16768 // If there are no effects associated with this node, then none of our children had any updates.
16769 // This guarantees that we can reuse all of them.
16770 var childrenUnchanged = workInProgress.firstEffect === null;
16771 if (childrenUnchanged && oldProps === newProps) {
16772 // No changes, just reuse the existing instance.
16773 // Note that this might release a previous clone.
16774 workInProgress.stateNode = currentInstance;
16775 return;
16776 }
16777 var recyclableInstance = workInProgress.stateNode;
16778 var currentHostContext = getHostContext();
16779 var updatePayload = null;
16780 if (oldProps !== newProps) {
16781 updatePayload = prepareUpdate(recyclableInstance, type, oldProps, newProps, rootContainerInstance, currentHostContext);
16782 }
16783 if (childrenUnchanged && updatePayload === null) {
16784 // No changes, just reuse the existing instance.
16785 // Note that this might release a previous clone.
16786 workInProgress.stateNode = currentInstance;
16787 return;
16788 }
16789 var newInstance = cloneInstance(currentInstance, updatePayload, type, oldProps, newProps, workInProgress, childrenUnchanged, recyclableInstance);
16790 if (finalizeInitialChildren(newInstance, type, newProps, rootContainerInstance, currentHostContext)) {
16791 markUpdate(workInProgress);
16792 }
16793 workInProgress.stateNode = newInstance;
16794 if (childrenUnchanged) {
16795 // If there are no other effects in this tree, we need to flag this node as having one.
16796 // Even though we're not going to use it for anything.
16797 // Otherwise parents won't know that there are new children to propagate upwards.
16798 markUpdate(workInProgress);
16799 } else {
16800 // If children might have changed, we have to add them all to the set.
16801 appendAllChildren(newInstance, workInProgress, false, false);
16802 }
16803 };
16804 updateHostText$1 = function (current, workInProgress, oldText, newText) {
16805 if (oldText !== newText) {
16806 // If the text content differs, we'll create a new text instance for it.
16807 var rootContainerInstance = getRootHostContainer();
16808 var currentHostContext = getHostContext();
16809 workInProgress.stateNode = createTextInstance(newText, rootContainerInstance, currentHostContext, workInProgress);
16810 // We'll have to mark it as having an effect, even though we won't use the effect for anything.
16811 // This lets the parents know that at least one of their children has changed.
16812 markUpdate(workInProgress);
16813 }
16814 };
16815} else {
16816 // No host operations
16817 updateHostContainer = function (workInProgress) {
16818 // Noop
16819 };
16820 updateHostComponent$1 = function (current, workInProgress, type, newProps, rootContainerInstance) {
16821 // Noop
16822 };
16823 updateHostText$1 = function (current, workInProgress, oldText, newText) {
16824 // Noop
16825 };
16826}
16827
16828function completeWork(current, workInProgress, renderExpirationTime) {
16829 var newProps = workInProgress.pendingProps;
16830
16831 switch (workInProgress.tag) {
16832 case IndeterminateComponent:
16833 break;
16834 case LazyComponent:
16835 break;
16836 case SimpleMemoComponent:
16837 case FunctionComponent:
16838 break;
16839 case ClassComponent:
16840 {
16841 var Component = workInProgress.type;
16842 if (isContextProvider(Component)) {
16843 popContext(workInProgress);
16844 }
16845 break;
16846 }
16847 case HostRoot:
16848 {
16849 popHostContainer(workInProgress);
16850 popTopLevelContextObject(workInProgress);
16851 var fiberRoot = workInProgress.stateNode;
16852 if (fiberRoot.pendingContext) {
16853 fiberRoot.context = fiberRoot.pendingContext;
16854 fiberRoot.pendingContext = null;
16855 }
16856 if (current === null || current.child === null) {
16857 // If we hydrated, pop so that we can delete any remaining children
16858 // that weren't hydrated.
16859 popHydrationState(workInProgress);
16860 // This resets the hacky state to fix isMounted before committing.
16861 // TODO: Delete this when we delete isMounted and findDOMNode.
16862 workInProgress.effectTag &= ~Placement;
16863 }
16864 updateHostContainer(workInProgress);
16865 break;
16866 }
16867 case HostComponent:
16868 {
16869 popHostContext(workInProgress);
16870 var rootContainerInstance = getRootHostContainer();
16871 var type = workInProgress.type;
16872 if (current !== null && workInProgress.stateNode != null) {
16873 updateHostComponent$1(current, workInProgress, type, newProps, rootContainerInstance);
16874
16875 if (current.ref !== workInProgress.ref) {
16876 markRef$1(workInProgress);
16877 }
16878 } else {
16879 if (!newProps) {
16880 !(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;
16881 // This can happen when we abort work.
16882 break;
16883 }
16884
16885 var currentHostContext = getHostContext();
16886 // TODO: Move createInstance to beginWork and keep it on a context
16887 // "stack" as the parent. Then append children as we go in beginWork
16888 // or completeWork depending on we want to add then top->down or
16889 // bottom->up. Top->down is faster in IE11.
16890 var wasHydrated = popHydrationState(workInProgress);
16891 if (wasHydrated) {
16892 // TODO: Move this and createInstance step into the beginPhase
16893 // to consolidate.
16894 if (prepareToHydrateHostInstance(workInProgress, rootContainerInstance, currentHostContext)) {
16895 // If changes to the hydrated node needs to be applied at the
16896 // commit-phase we mark this as such.
16897 markUpdate(workInProgress);
16898 }
16899 } else {
16900 var instance = createInstance(type, newProps, rootContainerInstance, currentHostContext, workInProgress);
16901
16902 appendAllChildren(instance, workInProgress, false, false);
16903
16904 // Certain renderers require commit-time effects for initial mount.
16905 // (eg DOM renderer supports auto-focus for certain elements).
16906 // Make sure such renderers get scheduled for later work.
16907 if (finalizeInitialChildren(instance, type, newProps, rootContainerInstance, currentHostContext)) {
16908 markUpdate(workInProgress);
16909 }
16910 workInProgress.stateNode = instance;
16911 }
16912
16913 if (workInProgress.ref !== null) {
16914 // If there is a ref on a host node we need to schedule a callback
16915 markRef$1(workInProgress);
16916 }
16917 }
16918 break;
16919 }
16920 case HostText:
16921 {
16922 var newText = newProps;
16923 if (current && workInProgress.stateNode != null) {
16924 var oldText = current.memoizedProps;
16925 // If we have an alternate, that means this is an update and we need
16926 // to schedule a side-effect to do the updates.
16927 updateHostText$1(current, workInProgress, oldText, newText);
16928 } else {
16929 if (typeof newText !== 'string') {
16930 !(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;
16931 // This can happen when we abort work.
16932 }
16933 var _rootContainerInstance = getRootHostContainer();
16934 var _currentHostContext = getHostContext();
16935 var _wasHydrated = popHydrationState(workInProgress);
16936 if (_wasHydrated) {
16937 if (prepareToHydrateHostTextInstance(workInProgress)) {
16938 markUpdate(workInProgress);
16939 }
16940 } else {
16941 workInProgress.stateNode = createTextInstance(newText, _rootContainerInstance, _currentHostContext, workInProgress);
16942 }
16943 }
16944 break;
16945 }
16946 case ForwardRef:
16947 break;
16948 case SuspenseComponent:
16949 {
16950 var nextState = workInProgress.memoizedState;
16951 if ((workInProgress.effectTag & DidCapture) !== NoEffect) {
16952 // Something suspended. Re-render with the fallback children.
16953 workInProgress.expirationTime = renderExpirationTime;
16954 // Do not reset the effect list.
16955 return workInProgress;
16956 }
16957
16958 var nextDidTimeout = nextState !== null;
16959 var prevDidTimeout = current !== null && current.memoizedState !== null;
16960
16961 if (current !== null && !nextDidTimeout && prevDidTimeout) {
16962 // We just switched from the fallback to the normal children. Delete
16963 // the fallback.
16964 // TODO: Would it be better to store the fallback fragment on
16965 var currentFallbackChild = current.child.sibling;
16966 if (currentFallbackChild !== null) {
16967 // Deletions go at the beginning of the return fiber's effect list
16968 var first = workInProgress.firstEffect;
16969 if (first !== null) {
16970 workInProgress.firstEffect = currentFallbackChild;
16971 currentFallbackChild.nextEffect = first;
16972 } else {
16973 workInProgress.firstEffect = workInProgress.lastEffect = currentFallbackChild;
16974 currentFallbackChild.nextEffect = null;
16975 }
16976 currentFallbackChild.effectTag = Deletion;
16977 }
16978 }
16979
16980 if (nextDidTimeout || prevDidTimeout) {
16981 // If the children are hidden, or if they were previous hidden, schedule
16982 // an effect to toggle their visibility. This is also used to attach a
16983 // retry listener to the promise.
16984 workInProgress.effectTag |= Update;
16985 }
16986 break;
16987 }
16988 case Fragment:
16989 break;
16990 case Mode:
16991 break;
16992 case Profiler:
16993 break;
16994 case HostPortal:
16995 popHostContainer(workInProgress);
16996 updateHostContainer(workInProgress);
16997 break;
16998 case ContextProvider:
16999 // Pop provider fiber
17000 popProvider(workInProgress);
17001 break;
17002 case ContextConsumer:
17003 break;
17004 case MemoComponent:
17005 break;
17006 case IncompleteClassComponent:
17007 {
17008 // Same as class component case. I put it down here so that the tags are
17009 // sequential to ensure this switch is compiled to a jump table.
17010 var _Component = workInProgress.type;
17011 if (isContextProvider(_Component)) {
17012 popContext(workInProgress);
17013 }
17014 break;
17015 }
17016 case DehydratedSuspenseComponent:
17017 {
17018 if (enableSuspenseServerRenderer) {
17019 if (current === null) {
17020 var _wasHydrated2 = popHydrationState(workInProgress);
17021 !_wasHydrated2 ? invariant(false, 'A dehydrated suspense component was completed without a hydrated node. This is probably a bug in React.') : void 0;
17022 skipPastDehydratedSuspenseInstance(workInProgress);
17023 } else if ((workInProgress.effectTag & DidCapture) === NoEffect) {
17024 // This boundary did not suspend so it's now hydrated.
17025 // To handle any future suspense cases, we're going to now upgrade it
17026 // to a Suspense component. We detach it from the existing current fiber.
17027 current.alternate = null;
17028 workInProgress.alternate = null;
17029 workInProgress.tag = SuspenseComponent;
17030 workInProgress.memoizedState = null;
17031 workInProgress.stateNode = null;
17032 }
17033 }
17034 break;
17035 }
17036 default:
17037 invariant(false, 'Unknown unit of work tag. This error is likely caused by a bug in React. Please file an issue.');
17038 }
17039
17040 return null;
17041}
17042
17043function shouldCaptureSuspense(workInProgress) {
17044 // In order to capture, the Suspense component must have a fallback prop.
17045 if (workInProgress.memoizedProps.fallback === undefined) {
17046 return false;
17047 }
17048 // If it was the primary children that just suspended, capture and render the
17049 // fallback. Otherwise, don't capture and bubble to the next boundary.
17050 var nextState = workInProgress.memoizedState;
17051 return nextState === null;
17052}
17053
17054// This module is forked in different environments.
17055// By default, return `true` to log errors to the console.
17056// Forks can return `false` if this isn't desirable.
17057function showErrorDialog(capturedError) {
17058 return true;
17059}
17060
17061function logCapturedError(capturedError) {
17062 var logError = showErrorDialog(capturedError);
17063
17064 // Allow injected showErrorDialog() to prevent default console.error logging.
17065 // This enables renderers like ReactNative to better manage redbox behavior.
17066 if (logError === false) {
17067 return;
17068 }
17069
17070 var error = capturedError.error;
17071 {
17072 var componentName = capturedError.componentName,
17073 componentStack = capturedError.componentStack,
17074 errorBoundaryName = capturedError.errorBoundaryName,
17075 errorBoundaryFound = capturedError.errorBoundaryFound,
17076 willRetry = capturedError.willRetry;
17077
17078 // Browsers support silencing uncaught errors by calling
17079 // `preventDefault()` in window `error` handler.
17080 // We record this information as an expando on the error.
17081
17082 if (error != null && error._suppressLogging) {
17083 if (errorBoundaryFound && willRetry) {
17084 // The error is recoverable and was silenced.
17085 // Ignore it and don't print the stack addendum.
17086 // This is handy for testing error boundaries without noise.
17087 return;
17088 }
17089 // The error is fatal. Since the silencing might have
17090 // been accidental, we'll surface it anyway.
17091 // However, the browser would have silenced the original error
17092 // so we'll print it first, and then print the stack addendum.
17093 console.error(error);
17094 // For a more detailed description of this block, see:
17095 // https://github.com/facebook/react/pull/13384
17096 }
17097
17098 var componentNameMessage = componentName ? 'The above error occurred in the <' + componentName + '> component:' : 'The above error occurred in one of your React components:';
17099
17100 var errorBoundaryMessage = void 0;
17101 // errorBoundaryFound check is sufficient; errorBoundaryName check is to satisfy Flow.
17102 if (errorBoundaryFound && errorBoundaryName) {
17103 if (willRetry) {
17104 errorBoundaryMessage = 'React will try to recreate this component tree from scratch ' + ('using the error boundary you provided, ' + errorBoundaryName + '.');
17105 } else {
17106 errorBoundaryMessage = 'This error was initially handled by the error boundary ' + errorBoundaryName + '.\n' + 'Recreating the tree from scratch failed so React will unmount the tree.';
17107 }
17108 } else {
17109 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.';
17110 }
17111 var combinedMessage = '' + componentNameMessage + componentStack + '\n\n' + ('' + errorBoundaryMessage);
17112
17113 // In development, we provide our own message with just the component stack.
17114 // We don't include the original error message and JS stack because the browser
17115 // has already printed it. Even if the application swallows the error, it is still
17116 // displayed by the browser thanks to the DEV-only fake event trick in ReactErrorUtils.
17117 console.error(combinedMessage);
17118 }
17119}
17120
17121var didWarnAboutUndefinedSnapshotBeforeUpdate = null;
17122{
17123 didWarnAboutUndefinedSnapshotBeforeUpdate = new Set();
17124}
17125
17126var PossiblyWeakSet$1 = typeof WeakSet === 'function' ? WeakSet : Set;
17127
17128function logError(boundary, errorInfo) {
17129 var source = errorInfo.source;
17130 var stack = errorInfo.stack;
17131 if (stack === null && source !== null) {
17132 stack = getStackByFiberInDevAndProd(source);
17133 }
17134
17135 var capturedError = {
17136 componentName: source !== null ? getComponentName(source.type) : null,
17137 componentStack: stack !== null ? stack : '',
17138 error: errorInfo.value,
17139 errorBoundary: null,
17140 errorBoundaryName: null,
17141 errorBoundaryFound: false,
17142 willRetry: false
17143 };
17144
17145 if (boundary !== null && boundary.tag === ClassComponent) {
17146 capturedError.errorBoundary = boundary.stateNode;
17147 capturedError.errorBoundaryName = getComponentName(boundary.type);
17148 capturedError.errorBoundaryFound = true;
17149 capturedError.willRetry = true;
17150 }
17151
17152 try {
17153 logCapturedError(capturedError);
17154 } catch (e) {
17155 // This method must not throw, or React internal state will get messed up.
17156 // If console.error is overridden, or logCapturedError() shows a dialog that throws,
17157 // we want to report this error outside of the normal stack as a last resort.
17158 // https://github.com/facebook/react/issues/13188
17159 setTimeout(function () {
17160 throw e;
17161 });
17162 }
17163}
17164
17165var callComponentWillUnmountWithTimer = function (current$$1, instance) {
17166 startPhaseTimer(current$$1, 'componentWillUnmount');
17167 instance.props = current$$1.memoizedProps;
17168 instance.state = current$$1.memoizedState;
17169 instance.componentWillUnmount();
17170 stopPhaseTimer();
17171};
17172
17173// Capture errors so they don't interrupt unmounting.
17174function safelyCallComponentWillUnmount(current$$1, instance) {
17175 {
17176 invokeGuardedCallback(null, callComponentWillUnmountWithTimer, null, current$$1, instance);
17177 if (hasCaughtError()) {
17178 var unmountError = clearCaughtError();
17179 captureCommitPhaseError(current$$1, unmountError);
17180 }
17181 }
17182}
17183
17184function safelyDetachRef(current$$1) {
17185 var ref = current$$1.ref;
17186 if (ref !== null) {
17187 if (typeof ref === 'function') {
17188 {
17189 invokeGuardedCallback(null, ref, null, null);
17190 if (hasCaughtError()) {
17191 var refError = clearCaughtError();
17192 captureCommitPhaseError(current$$1, refError);
17193 }
17194 }
17195 } else {
17196 ref.current = null;
17197 }
17198 }
17199}
17200
17201function safelyCallDestroy(current$$1, destroy) {
17202 {
17203 invokeGuardedCallback(null, destroy, null);
17204 if (hasCaughtError()) {
17205 var error = clearCaughtError();
17206 captureCommitPhaseError(current$$1, error);
17207 }
17208 }
17209}
17210
17211function commitBeforeMutationLifeCycles(current$$1, finishedWork) {
17212 switch (finishedWork.tag) {
17213 case FunctionComponent:
17214 case ForwardRef:
17215 case SimpleMemoComponent:
17216 {
17217 commitHookEffectList(UnmountSnapshot, NoEffect$1, finishedWork);
17218 return;
17219 }
17220 case ClassComponent:
17221 {
17222 if (finishedWork.effectTag & Snapshot) {
17223 if (current$$1 !== null) {
17224 var prevProps = current$$1.memoizedProps;
17225 var prevState = current$$1.memoizedState;
17226 startPhaseTimer(finishedWork, 'getSnapshotBeforeUpdate');
17227 var instance = finishedWork.stateNode;
17228 // We could update instance props and state here,
17229 // but instead we rely on them being set during last render.
17230 // TODO: revisit this when we implement resuming.
17231 {
17232 if (finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps) {
17233 !(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;
17234 !(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;
17235 }
17236 }
17237 var snapshot = instance.getSnapshotBeforeUpdate(finishedWork.elementType === finishedWork.type ? prevProps : resolveDefaultProps(finishedWork.type, prevProps), prevState);
17238 {
17239 var didWarnSet = didWarnAboutUndefinedSnapshotBeforeUpdate;
17240 if (snapshot === undefined && !didWarnSet.has(finishedWork.type)) {
17241 didWarnSet.add(finishedWork.type);
17242 warningWithoutStack$1(false, '%s.getSnapshotBeforeUpdate(): A snapshot value (or null) ' + 'must be returned. You have returned undefined.', getComponentName(finishedWork.type));
17243 }
17244 }
17245 instance.__reactInternalSnapshotBeforeUpdate = snapshot;
17246 stopPhaseTimer();
17247 }
17248 }
17249 return;
17250 }
17251 case HostRoot:
17252 case HostComponent:
17253 case HostText:
17254 case HostPortal:
17255 case IncompleteClassComponent:
17256 // Nothing to do for these component types
17257 return;
17258 default:
17259 {
17260 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.');
17261 }
17262 }
17263}
17264
17265function commitHookEffectList(unmountTag, mountTag, finishedWork) {
17266 var updateQueue = finishedWork.updateQueue;
17267 var lastEffect = updateQueue !== null ? updateQueue.lastEffect : null;
17268 if (lastEffect !== null) {
17269 var firstEffect = lastEffect.next;
17270 var effect = firstEffect;
17271 do {
17272 if ((effect.tag & unmountTag) !== NoEffect$1) {
17273 // Unmount
17274 var destroy = effect.destroy;
17275 effect.destroy = undefined;
17276 if (destroy !== undefined) {
17277 destroy();
17278 }
17279 }
17280 if ((effect.tag & mountTag) !== NoEffect$1) {
17281 // Mount
17282 var create = effect.create;
17283 effect.destroy = create();
17284
17285 {
17286 var _destroy = effect.destroy;
17287 if (_destroy !== undefined && typeof _destroy !== 'function') {
17288 var addendum = void 0;
17289 if (_destroy === null) {
17290 addendum = ' You returned null. If your effect does not require clean ' + 'up, return undefined (or nothing).';
17291 } else if (typeof _destroy.then === 'function') {
17292 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';
17293 } else {
17294 addendum = ' You returned: ' + _destroy;
17295 }
17296 warningWithoutStack$1(false, 'An effect function must not return anything besides a function, ' + 'which is used for clean-up.%s%s', addendum, getStackByFiberInDevAndProd(finishedWork));
17297 }
17298 }
17299 }
17300 effect = effect.next;
17301 } while (effect !== firstEffect);
17302 }
17303}
17304
17305function commitPassiveHookEffects(finishedWork) {
17306 commitHookEffectList(UnmountPassive, NoEffect$1, finishedWork);
17307 commitHookEffectList(NoEffect$1, MountPassive, finishedWork);
17308}
17309
17310function commitLifeCycles(finishedRoot, current$$1, finishedWork, committedExpirationTime) {
17311 switch (finishedWork.tag) {
17312 case FunctionComponent:
17313 case ForwardRef:
17314 case SimpleMemoComponent:
17315 {
17316 commitHookEffectList(UnmountLayout, MountLayout, finishedWork);
17317 break;
17318 }
17319 case ClassComponent:
17320 {
17321 var instance = finishedWork.stateNode;
17322 if (finishedWork.effectTag & Update) {
17323 if (current$$1 === null) {
17324 startPhaseTimer(finishedWork, 'componentDidMount');
17325 // We could update instance props and state here,
17326 // but instead we rely on them being set during last render.
17327 // TODO: revisit this when we implement resuming.
17328 {
17329 if (finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps) {
17330 !(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;
17331 !(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;
17332 }
17333 }
17334 instance.componentDidMount();
17335 stopPhaseTimer();
17336 } else {
17337 var prevProps = finishedWork.elementType === finishedWork.type ? current$$1.memoizedProps : resolveDefaultProps(finishedWork.type, current$$1.memoizedProps);
17338 var prevState = current$$1.memoizedState;
17339 startPhaseTimer(finishedWork, 'componentDidUpdate');
17340 // We could update instance props and state here,
17341 // but instead we rely on them being set during last render.
17342 // TODO: revisit this when we implement resuming.
17343 {
17344 if (finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps) {
17345 !(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;
17346 !(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;
17347 }
17348 }
17349 instance.componentDidUpdate(prevProps, prevState, instance.__reactInternalSnapshotBeforeUpdate);
17350 stopPhaseTimer();
17351 }
17352 }
17353 var updateQueue = finishedWork.updateQueue;
17354 if (updateQueue !== null) {
17355 {
17356 if (finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps) {
17357 !(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;
17358 !(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;
17359 }
17360 }
17361 // We could update instance props and state here,
17362 // but instead we rely on them being set during last render.
17363 // TODO: revisit this when we implement resuming.
17364 commitUpdateQueue(finishedWork, updateQueue, instance, committedExpirationTime);
17365 }
17366 return;
17367 }
17368 case HostRoot:
17369 {
17370 var _updateQueue = finishedWork.updateQueue;
17371 if (_updateQueue !== null) {
17372 var _instance = null;
17373 if (finishedWork.child !== null) {
17374 switch (finishedWork.child.tag) {
17375 case HostComponent:
17376 _instance = getPublicInstance(finishedWork.child.stateNode);
17377 break;
17378 case ClassComponent:
17379 _instance = finishedWork.child.stateNode;
17380 break;
17381 }
17382 }
17383 commitUpdateQueue(finishedWork, _updateQueue, _instance, committedExpirationTime);
17384 }
17385 return;
17386 }
17387 case HostComponent:
17388 {
17389 var _instance2 = finishedWork.stateNode;
17390
17391 // Renderers may schedule work to be done after host components are mounted
17392 // (eg DOM renderer may schedule auto-focus for inputs and form controls).
17393 // These effects should only be committed when components are first mounted,
17394 // aka when there is no current/alternate.
17395 if (current$$1 === null && finishedWork.effectTag & Update) {
17396 var type = finishedWork.type;
17397 var props = finishedWork.memoizedProps;
17398 commitMount(_instance2, type, props, finishedWork);
17399 }
17400
17401 return;
17402 }
17403 case HostText:
17404 {
17405 // We have no life-cycles associated with text.
17406 return;
17407 }
17408 case HostPortal:
17409 {
17410 // We have no life-cycles associated with portals.
17411 return;
17412 }
17413 case Profiler:
17414 {
17415 if (enableProfilerTimer) {
17416 var onRender = finishedWork.memoizedProps.onRender;
17417
17418 if (enableSchedulerTracing) {
17419 onRender(finishedWork.memoizedProps.id, current$$1 === null ? 'mount' : 'update', finishedWork.actualDuration, finishedWork.treeBaseDuration, finishedWork.actualStartTime, getCommitTime(), finishedRoot.memoizedInteractions);
17420 } else {
17421 onRender(finishedWork.memoizedProps.id, current$$1 === null ? 'mount' : 'update', finishedWork.actualDuration, finishedWork.treeBaseDuration, finishedWork.actualStartTime, getCommitTime());
17422 }
17423 }
17424 return;
17425 }
17426 case SuspenseComponent:
17427 break;
17428 case IncompleteClassComponent:
17429 break;
17430 default:
17431 {
17432 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.');
17433 }
17434 }
17435}
17436
17437function hideOrUnhideAllChildren(finishedWork, isHidden) {
17438 if (supportsMutation) {
17439 // We only have the top Fiber that was inserted but we need to recurse down its
17440 var node = finishedWork;
17441 while (true) {
17442 if (node.tag === HostComponent) {
17443 var instance = node.stateNode;
17444 if (isHidden) {
17445 hideInstance(instance);
17446 } else {
17447 unhideInstance(node.stateNode, node.memoizedProps);
17448 }
17449 } else if (node.tag === HostText) {
17450 var _instance3 = node.stateNode;
17451 if (isHidden) {
17452 hideTextInstance(_instance3);
17453 } else {
17454 unhideTextInstance(_instance3, node.memoizedProps);
17455 }
17456 } else if (node.tag === SuspenseComponent && node.memoizedState !== null) {
17457 // Found a nested Suspense component that timed out. Skip over the
17458 var fallbackChildFragment = node.child.sibling;
17459 fallbackChildFragment.return = node;
17460 node = fallbackChildFragment;
17461 continue;
17462 } else if (node.child !== null) {
17463 node.child.return = node;
17464 node = node.child;
17465 continue;
17466 }
17467 if (node === finishedWork) {
17468 return;
17469 }
17470 while (node.sibling === null) {
17471 if (node.return === null || node.return === finishedWork) {
17472 return;
17473 }
17474 node = node.return;
17475 }
17476 node.sibling.return = node.return;
17477 node = node.sibling;
17478 }
17479 }
17480}
17481
17482function commitAttachRef(finishedWork) {
17483 var ref = finishedWork.ref;
17484 if (ref !== null) {
17485 var instance = finishedWork.stateNode;
17486 var instanceToUse = void 0;
17487 switch (finishedWork.tag) {
17488 case HostComponent:
17489 instanceToUse = getPublicInstance(instance);
17490 break;
17491 default:
17492 instanceToUse = instance;
17493 }
17494 if (typeof ref === 'function') {
17495 ref(instanceToUse);
17496 } else {
17497 {
17498 if (!ref.hasOwnProperty('current')) {
17499 warningWithoutStack$1(false, 'Unexpected ref object provided for %s. ' + 'Use either a ref-setter function or React.createRef().%s', getComponentName(finishedWork.type), getStackByFiberInDevAndProd(finishedWork));
17500 }
17501 }
17502
17503 ref.current = instanceToUse;
17504 }
17505 }
17506}
17507
17508function commitDetachRef(current$$1) {
17509 var currentRef = current$$1.ref;
17510 if (currentRef !== null) {
17511 if (typeof currentRef === 'function') {
17512 currentRef(null);
17513 } else {
17514 currentRef.current = null;
17515 }
17516 }
17517}
17518
17519// User-originating errors (lifecycles and refs) should not interrupt
17520// deletion, so don't let them throw. Host-originating errors should
17521// interrupt deletion, so it's okay
17522function commitUnmount(current$$1) {
17523 onCommitUnmount(current$$1);
17524
17525 switch (current$$1.tag) {
17526 case FunctionComponent:
17527 case ForwardRef:
17528 case MemoComponent:
17529 case SimpleMemoComponent:
17530 {
17531 var updateQueue = current$$1.updateQueue;
17532 if (updateQueue !== null) {
17533 var lastEffect = updateQueue.lastEffect;
17534 if (lastEffect !== null) {
17535 var firstEffect = lastEffect.next;
17536 var effect = firstEffect;
17537 do {
17538 var destroy = effect.destroy;
17539 if (destroy !== undefined) {
17540 safelyCallDestroy(current$$1, destroy);
17541 }
17542 effect = effect.next;
17543 } while (effect !== firstEffect);
17544 }
17545 }
17546 break;
17547 }
17548 case ClassComponent:
17549 {
17550 safelyDetachRef(current$$1);
17551 var instance = current$$1.stateNode;
17552 if (typeof instance.componentWillUnmount === 'function') {
17553 safelyCallComponentWillUnmount(current$$1, instance);
17554 }
17555 return;
17556 }
17557 case HostComponent:
17558 {
17559 safelyDetachRef(current$$1);
17560 return;
17561 }
17562 case HostPortal:
17563 {
17564 // TODO: this is recursive.
17565 // We are also not using this parent because
17566 // the portal will get pushed immediately.
17567 if (supportsMutation) {
17568 unmountHostComponents(current$$1);
17569 } else if (supportsPersistence) {
17570 emptyPortalContainer(current$$1);
17571 }
17572 return;
17573 }
17574 }
17575}
17576
17577function commitNestedUnmounts(root) {
17578 // While we're inside a removed host node we don't want to call
17579 // removeChild on the inner nodes because they're removed by the top
17580 // call anyway. We also want to call componentWillUnmount on all
17581 // composites before this host node is removed from the tree. Therefore
17582 var node = root;
17583 while (true) {
17584 commitUnmount(node);
17585 // Visit children because they may contain more composite or host nodes.
17586 // Skip portals because commitUnmount() currently visits them recursively.
17587 if (node.child !== null && (
17588 // If we use mutation we drill down into portals using commitUnmount above.
17589 // If we don't use mutation we drill down into portals here instead.
17590 !supportsMutation || node.tag !== HostPortal)) {
17591 node.child.return = node;
17592 node = node.child;
17593 continue;
17594 }
17595 if (node === root) {
17596 return;
17597 }
17598 while (node.sibling === null) {
17599 if (node.return === null || node.return === root) {
17600 return;
17601 }
17602 node = node.return;
17603 }
17604 node.sibling.return = node.return;
17605 node = node.sibling;
17606 }
17607}
17608
17609function detachFiber(current$$1) {
17610 // Cut off the return pointers to disconnect it from the tree. Ideally, we
17611 // should clear the child pointer of the parent alternate to let this
17612 // get GC:ed but we don't know which for sure which parent is the current
17613 // one so we'll settle for GC:ing the subtree of this child. This child
17614 // itself will be GC:ed when the parent updates the next time.
17615 current$$1.return = null;
17616 current$$1.child = null;
17617 current$$1.memoizedState = null;
17618 current$$1.updateQueue = null;
17619 var alternate = current$$1.alternate;
17620 if (alternate !== null) {
17621 alternate.return = null;
17622 alternate.child = null;
17623 alternate.memoizedState = null;
17624 alternate.updateQueue = null;
17625 }
17626}
17627
17628function emptyPortalContainer(current$$1) {
17629 if (!supportsPersistence) {
17630 return;
17631 }
17632
17633 var portal = current$$1.stateNode;
17634 var containerInfo = portal.containerInfo;
17635
17636 var emptyChildSet = createContainerChildSet(containerInfo);
17637 replaceContainerChildren(containerInfo, emptyChildSet);
17638}
17639
17640function commitContainer(finishedWork) {
17641 if (!supportsPersistence) {
17642 return;
17643 }
17644
17645 switch (finishedWork.tag) {
17646 case ClassComponent:
17647 {
17648 return;
17649 }
17650 case HostComponent:
17651 {
17652 return;
17653 }
17654 case HostText:
17655 {
17656 return;
17657 }
17658 case HostRoot:
17659 case HostPortal:
17660 {
17661 var portalOrRoot = finishedWork.stateNode;
17662 var containerInfo = portalOrRoot.containerInfo,
17663 _pendingChildren = portalOrRoot.pendingChildren;
17664
17665 replaceContainerChildren(containerInfo, _pendingChildren);
17666 return;
17667 }
17668 default:
17669 {
17670 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.');
17671 }
17672 }
17673}
17674
17675function getHostParentFiber(fiber) {
17676 var parent = fiber.return;
17677 while (parent !== null) {
17678 if (isHostParent(parent)) {
17679 return parent;
17680 }
17681 parent = parent.return;
17682 }
17683 invariant(false, 'Expected to find a host parent. This error is likely caused by a bug in React. Please file an issue.');
17684}
17685
17686function isHostParent(fiber) {
17687 return fiber.tag === HostComponent || fiber.tag === HostRoot || fiber.tag === HostPortal;
17688}
17689
17690function getHostSibling(fiber) {
17691 // We're going to search forward into the tree until we find a sibling host
17692 // node. Unfortunately, if multiple insertions are done in a row we have to
17693 // search past them. This leads to exponential search for the next sibling.
17694 var node = fiber;
17695 siblings: while (true) {
17696 // If we didn't find anything, let's try the next sibling.
17697 while (node.sibling === null) {
17698 if (node.return === null || isHostParent(node.return)) {
17699 // If we pop out of the root or hit the parent the fiber we are the
17700 // last sibling.
17701 return null;
17702 }
17703 node = node.return;
17704 }
17705 node.sibling.return = node.return;
17706 node = node.sibling;
17707 while (node.tag !== HostComponent && node.tag !== HostText && node.tag !== DehydratedSuspenseComponent) {
17708 // If it is not host node and, we might have a host node inside it.
17709 // Try to search down until we find one.
17710 if (node.effectTag & Placement) {
17711 // If we don't have a child, try the siblings instead.
17712 continue siblings;
17713 }
17714 // If we don't have a child, try the siblings instead.
17715 // We also skip portals because they are not part of this host tree.
17716 if (node.child === null || node.tag === HostPortal) {
17717 continue siblings;
17718 } else {
17719 node.child.return = node;
17720 node = node.child;
17721 }
17722 }
17723 // Check if this host node is stable or about to be placed.
17724 if (!(node.effectTag & Placement)) {
17725 // Found it!
17726 return node.stateNode;
17727 }
17728 }
17729}
17730
17731function commitPlacement(finishedWork) {
17732 if (!supportsMutation) {
17733 return;
17734 }
17735
17736 // Recursively insert all host nodes into the parent.
17737 var parentFiber = getHostParentFiber(finishedWork);
17738
17739 // Note: these two variables *must* always be updated together.
17740 var parent = void 0;
17741 var isContainer = void 0;
17742
17743 switch (parentFiber.tag) {
17744 case HostComponent:
17745 parent = parentFiber.stateNode;
17746 isContainer = false;
17747 break;
17748 case HostRoot:
17749 parent = parentFiber.stateNode.containerInfo;
17750 isContainer = true;
17751 break;
17752 case HostPortal:
17753 parent = parentFiber.stateNode.containerInfo;
17754 isContainer = true;
17755 break;
17756 default:
17757 invariant(false, 'Invalid host parent fiber. This error is likely caused by a bug in React. Please file an issue.');
17758 }
17759 if (parentFiber.effectTag & ContentReset) {
17760 // Reset the text content of the parent before doing any insertions
17761 resetTextContent(parent);
17762 // Clear ContentReset from the effect tag
17763 parentFiber.effectTag &= ~ContentReset;
17764 }
17765
17766 var before = getHostSibling(finishedWork);
17767 // We only have the top Fiber that was inserted but we need to recurse down its
17768 // children to find all the terminal nodes.
17769 var node = finishedWork;
17770 while (true) {
17771 if (node.tag === HostComponent || node.tag === HostText) {
17772 if (before) {
17773 if (isContainer) {
17774 insertInContainerBefore(parent, node.stateNode, before);
17775 } else {
17776 insertBefore(parent, node.stateNode, before);
17777 }
17778 } else {
17779 if (isContainer) {
17780 appendChildToContainer(parent, node.stateNode);
17781 } else {
17782 appendChild(parent, node.stateNode);
17783 }
17784 }
17785 } else if (node.tag === HostPortal) {
17786 // If the insertion itself is a portal, then we don't want to traverse
17787 // down its children. Instead, we'll get insertions from each child in
17788 // the portal directly.
17789 } else if (node.child !== null) {
17790 node.child.return = node;
17791 node = node.child;
17792 continue;
17793 }
17794 if (node === finishedWork) {
17795 return;
17796 }
17797 while (node.sibling === null) {
17798 if (node.return === null || node.return === finishedWork) {
17799 return;
17800 }
17801 node = node.return;
17802 }
17803 node.sibling.return = node.return;
17804 node = node.sibling;
17805 }
17806}
17807
17808function unmountHostComponents(current$$1) {
17809 // We only have the top Fiber that was deleted but we need to recurse down its
17810 var node = current$$1;
17811
17812 // Each iteration, currentParent is populated with node's host parent if not
17813 // currentParentIsValid.
17814 var currentParentIsValid = false;
17815
17816 // Note: these two variables *must* always be updated together.
17817 var currentParent = void 0;
17818 var currentParentIsContainer = void 0;
17819
17820 while (true) {
17821 if (!currentParentIsValid) {
17822 var parent = node.return;
17823 findParent: while (true) {
17824 !(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;
17825 switch (parent.tag) {
17826 case HostComponent:
17827 currentParent = parent.stateNode;
17828 currentParentIsContainer = false;
17829 break findParent;
17830 case HostRoot:
17831 currentParent = parent.stateNode.containerInfo;
17832 currentParentIsContainer = true;
17833 break findParent;
17834 case HostPortal:
17835 currentParent = parent.stateNode.containerInfo;
17836 currentParentIsContainer = true;
17837 break findParent;
17838 }
17839 parent = parent.return;
17840 }
17841 currentParentIsValid = true;
17842 }
17843
17844 if (node.tag === HostComponent || node.tag === HostText) {
17845 commitNestedUnmounts(node);
17846 // After all the children have unmounted, it is now safe to remove the
17847 // node from the tree.
17848 if (currentParentIsContainer) {
17849 removeChildFromContainer(currentParent, node.stateNode);
17850 } else {
17851 removeChild(currentParent, node.stateNode);
17852 }
17853 // Don't visit children because we already visited them.
17854 } else if (enableSuspenseServerRenderer && node.tag === DehydratedSuspenseComponent) {
17855 // Delete the dehydrated suspense boundary and all of its content.
17856 if (currentParentIsContainer) {
17857 clearSuspenseBoundaryFromContainer(currentParent, node.stateNode);
17858 } else {
17859 clearSuspenseBoundary(currentParent, node.stateNode);
17860 }
17861 } else if (node.tag === HostPortal) {
17862 if (node.child !== null) {
17863 // When we go into a portal, it becomes the parent to remove from.
17864 // We will reassign it back when we pop the portal on the way up.
17865 currentParent = node.stateNode.containerInfo;
17866 currentParentIsContainer = true;
17867 // Visit children because portals might contain host components.
17868 node.child.return = node;
17869 node = node.child;
17870 continue;
17871 }
17872 } else {
17873 commitUnmount(node);
17874 // Visit children because we may find more host components below.
17875 if (node.child !== null) {
17876 node.child.return = node;
17877 node = node.child;
17878 continue;
17879 }
17880 }
17881 if (node === current$$1) {
17882 return;
17883 }
17884 while (node.sibling === null) {
17885 if (node.return === null || node.return === current$$1) {
17886 return;
17887 }
17888 node = node.return;
17889 if (node.tag === HostPortal) {
17890 // When we go out of the portal, we need to restore the parent.
17891 // Since we don't keep a stack of them, we will search for it.
17892 currentParentIsValid = false;
17893 }
17894 }
17895 node.sibling.return = node.return;
17896 node = node.sibling;
17897 }
17898}
17899
17900function commitDeletion(current$$1) {
17901 if (supportsMutation) {
17902 // Recursively delete all host nodes from the parent.
17903 // Detach refs and call componentWillUnmount() on the whole subtree.
17904 unmountHostComponents(current$$1);
17905 } else {
17906 // Detach refs and call componentWillUnmount() on the whole subtree.
17907 commitNestedUnmounts(current$$1);
17908 }
17909 detachFiber(current$$1);
17910}
17911
17912function commitWork(current$$1, finishedWork) {
17913 if (!supportsMutation) {
17914 switch (finishedWork.tag) {
17915 case FunctionComponent:
17916 case ForwardRef:
17917 case MemoComponent:
17918 case SimpleMemoComponent:
17919 {
17920 // Note: We currently never use MountMutation, but useLayout uses
17921 // UnmountMutation.
17922 commitHookEffectList(UnmountMutation, MountMutation, finishedWork);
17923 return;
17924 }
17925 }
17926
17927 commitContainer(finishedWork);
17928 return;
17929 }
17930
17931 switch (finishedWork.tag) {
17932 case FunctionComponent:
17933 case ForwardRef:
17934 case MemoComponent:
17935 case SimpleMemoComponent:
17936 {
17937 // Note: We currently never use MountMutation, but useLayout uses
17938 // UnmountMutation.
17939 commitHookEffectList(UnmountMutation, MountMutation, finishedWork);
17940 return;
17941 }
17942 case ClassComponent:
17943 {
17944 return;
17945 }
17946 case HostComponent:
17947 {
17948 var instance = finishedWork.stateNode;
17949 if (instance != null) {
17950 // Commit the work prepared earlier.
17951 var newProps = finishedWork.memoizedProps;
17952 // For hydration we reuse the update path but we treat the oldProps
17953 // as the newProps. The updatePayload will contain the real change in
17954 // this case.
17955 var oldProps = current$$1 !== null ? current$$1.memoizedProps : newProps;
17956 var type = finishedWork.type;
17957 // TODO: Type the updateQueue to be specific to host components.
17958 var updatePayload = finishedWork.updateQueue;
17959 finishedWork.updateQueue = null;
17960 if (updatePayload !== null) {
17961 commitUpdate(instance, updatePayload, type, oldProps, newProps, finishedWork);
17962 }
17963 }
17964 return;
17965 }
17966 case HostText:
17967 {
17968 !(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;
17969 var textInstance = finishedWork.stateNode;
17970 var newText = finishedWork.memoizedProps;
17971 // For hydration we reuse the update path but we treat the oldProps
17972 // as the newProps. The updatePayload will contain the real change in
17973 // this case.
17974 var oldText = current$$1 !== null ? current$$1.memoizedProps : newText;
17975 commitTextUpdate(textInstance, oldText, newText);
17976 return;
17977 }
17978 case HostRoot:
17979 {
17980 return;
17981 }
17982 case Profiler:
17983 {
17984 return;
17985 }
17986 case SuspenseComponent:
17987 {
17988 var newState = finishedWork.memoizedState;
17989
17990 var newDidTimeout = void 0;
17991 var primaryChildParent = finishedWork;
17992 if (newState === null) {
17993 newDidTimeout = false;
17994 } else {
17995 newDidTimeout = true;
17996 primaryChildParent = finishedWork.child;
17997 if (newState.timedOutAt === NoWork) {
17998 // If the children had not already timed out, record the time.
17999 // This is used to compute the elapsed time during subsequent
18000 // attempts to render the children.
18001 newState.timedOutAt = requestCurrentTime();
18002 }
18003 }
18004
18005 if (primaryChildParent !== null) {
18006 hideOrUnhideAllChildren(primaryChildParent, newDidTimeout);
18007 }
18008
18009 // If this boundary just timed out, then it will have a set of thenables.
18010 // For each thenable, attach a listener so that when it resolves, React
18011 // attempts to re-render the boundary in the primary (pre-timeout) state.
18012 var thenables = finishedWork.updateQueue;
18013 if (thenables !== null) {
18014 finishedWork.updateQueue = null;
18015 var retryCache = finishedWork.stateNode;
18016 if (retryCache === null) {
18017 retryCache = finishedWork.stateNode = new PossiblyWeakSet$1();
18018 }
18019 thenables.forEach(function (thenable) {
18020 // Memoize using the boundary fiber to prevent redundant listeners.
18021 var retry = retryTimedOutBoundary.bind(null, finishedWork, thenable);
18022 if (enableSchedulerTracing) {
18023 retry = tracing.unstable_wrap(retry);
18024 }
18025 if (!retryCache.has(thenable)) {
18026 retryCache.add(thenable);
18027 thenable.then(retry, retry);
18028 }
18029 });
18030 }
18031
18032 return;
18033 }
18034 case IncompleteClassComponent:
18035 {
18036 return;
18037 }
18038 default:
18039 {
18040 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.');
18041 }
18042 }
18043}
18044
18045function commitResetTextContent(current$$1) {
18046 if (!supportsMutation) {
18047 return;
18048 }
18049 resetTextContent(current$$1.stateNode);
18050}
18051
18052var PossiblyWeakSet = typeof WeakSet === 'function' ? WeakSet : Set;
18053var PossiblyWeakMap = typeof WeakMap === 'function' ? WeakMap : Map;
18054
18055function createRootErrorUpdate(fiber, errorInfo, expirationTime) {
18056 var update = createUpdate(expirationTime);
18057 // Unmount the root by rendering null.
18058 update.tag = CaptureUpdate;
18059 // Caution: React DevTools currently depends on this property
18060 // being called "element".
18061 update.payload = { element: null };
18062 var error = errorInfo.value;
18063 update.callback = function () {
18064 onUncaughtError(error);
18065 logError(fiber, errorInfo);
18066 };
18067 return update;
18068}
18069
18070function createClassErrorUpdate(fiber, errorInfo, expirationTime) {
18071 var update = createUpdate(expirationTime);
18072 update.tag = CaptureUpdate;
18073 var getDerivedStateFromError = fiber.type.getDerivedStateFromError;
18074 if (typeof getDerivedStateFromError === 'function') {
18075 var error = errorInfo.value;
18076 update.payload = function () {
18077 return getDerivedStateFromError(error);
18078 };
18079 }
18080
18081 var inst = fiber.stateNode;
18082 if (inst !== null && typeof inst.componentDidCatch === 'function') {
18083 update.callback = function callback() {
18084 if (typeof getDerivedStateFromError !== 'function') {
18085 // To preserve the preexisting retry behavior of error boundaries,
18086 // we keep track of which ones already failed during this batch.
18087 // This gets reset before we yield back to the browser.
18088 // TODO: Warn in strict mode if getDerivedStateFromError is
18089 // not defined.
18090 markLegacyErrorBoundaryAsFailed(this);
18091 }
18092 var error = errorInfo.value;
18093 var stack = errorInfo.stack;
18094 logError(fiber, errorInfo);
18095 this.componentDidCatch(error, {
18096 componentStack: stack !== null ? stack : ''
18097 });
18098 {
18099 if (typeof getDerivedStateFromError !== 'function') {
18100 // If componentDidCatch is the only error boundary method defined,
18101 // then it needs to call setState to recover from errors.
18102 // If no state update is scheduled then the boundary will swallow the error.
18103 !(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;
18104 }
18105 }
18106 };
18107 }
18108 return update;
18109}
18110
18111function attachPingListener(root, renderExpirationTime, thenable) {
18112 // Attach a listener to the promise to "ping" the root and retry. But
18113 // only if one does not already exist for the current render expiration
18114 // time (which acts like a "thread ID" here).
18115 var pingCache = root.pingCache;
18116 var threadIDs = void 0;
18117 if (pingCache === null) {
18118 pingCache = root.pingCache = new PossiblyWeakMap();
18119 threadIDs = new Set();
18120 pingCache.set(thenable, threadIDs);
18121 } else {
18122 threadIDs = pingCache.get(thenable);
18123 if (threadIDs === undefined) {
18124 threadIDs = new Set();
18125 pingCache.set(thenable, threadIDs);
18126 }
18127 }
18128 if (!threadIDs.has(renderExpirationTime)) {
18129 // Memoize using the thread ID to prevent redundant listeners.
18130 threadIDs.add(renderExpirationTime);
18131 var ping = pingSuspendedRoot.bind(null, root, thenable, renderExpirationTime);
18132 if (enableSchedulerTracing) {
18133 ping = tracing.unstable_wrap(ping);
18134 }
18135 thenable.then(ping, ping);
18136 }
18137}
18138
18139function throwException(root, returnFiber, sourceFiber, value, renderExpirationTime) {
18140 // The source fiber did not complete.
18141 sourceFiber.effectTag |= Incomplete;
18142 // Its effect list is no longer valid.
18143 sourceFiber.firstEffect = sourceFiber.lastEffect = null;
18144
18145 if (value !== null && typeof value === 'object' && typeof value.then === 'function') {
18146 // This is a thenable.
18147 var thenable = value;
18148
18149 // Find the earliest timeout threshold of all the placeholders in the
18150 // ancestor path. We could avoid this traversal by storing the thresholds on
18151 // the stack, but we choose not to because we only hit this path if we're
18152 // IO-bound (i.e. if something suspends). Whereas the stack is used even in
18153 // the non-IO- bound case.
18154 var _workInProgress = returnFiber;
18155 var earliestTimeoutMs = -1;
18156 var startTimeMs = -1;
18157 do {
18158 if (_workInProgress.tag === SuspenseComponent) {
18159 var current$$1 = _workInProgress.alternate;
18160 if (current$$1 !== null) {
18161 var currentState = current$$1.memoizedState;
18162 if (currentState !== null) {
18163 // Reached a boundary that already timed out. Do not search
18164 // any further.
18165 var timedOutAt = currentState.timedOutAt;
18166 startTimeMs = expirationTimeToMs(timedOutAt);
18167 // Do not search any further.
18168 break;
18169 }
18170 }
18171 var timeoutPropMs = _workInProgress.pendingProps.maxDuration;
18172 if (typeof timeoutPropMs === 'number') {
18173 if (timeoutPropMs <= 0) {
18174 earliestTimeoutMs = 0;
18175 } else if (earliestTimeoutMs === -1 || timeoutPropMs < earliestTimeoutMs) {
18176 earliestTimeoutMs = timeoutPropMs;
18177 }
18178 }
18179 }
18180 // If there is a DehydratedSuspenseComponent we don't have to do anything because
18181 // if something suspends inside it, we will simply leave that as dehydrated. It
18182 // will never timeout.
18183 _workInProgress = _workInProgress.return;
18184 } while (_workInProgress !== null);
18185
18186 // Schedule the nearest Suspense to re-render the timed out view.
18187 _workInProgress = returnFiber;
18188 do {
18189 if (_workInProgress.tag === SuspenseComponent && shouldCaptureSuspense(_workInProgress)) {
18190 // Found the nearest boundary.
18191
18192 // Stash the promise on the boundary fiber. If the boundary times out, we'll
18193 var thenables = _workInProgress.updateQueue;
18194 if (thenables === null) {
18195 var updateQueue = new Set();
18196 updateQueue.add(thenable);
18197 _workInProgress.updateQueue = updateQueue;
18198 } else {
18199 thenables.add(thenable);
18200 }
18201
18202 // If the boundary is outside of concurrent mode, we should *not*
18203 // suspend the commit. Pretend as if the suspended component rendered
18204 // null and keep rendering. In the commit phase, we'll schedule a
18205 // subsequent synchronous update to re-render the Suspense.
18206 //
18207 // Note: It doesn't matter whether the component that suspended was
18208 // inside a concurrent mode tree. If the Suspense is outside of it, we
18209 // should *not* suspend the commit.
18210 if ((_workInProgress.mode & ConcurrentMode) === NoEffect) {
18211 _workInProgress.effectTag |= DidCapture;
18212
18213 // We're going to commit this fiber even though it didn't complete.
18214 // But we shouldn't call any lifecycle methods or callbacks. Remove
18215 // all lifecycle effect tags.
18216 sourceFiber.effectTag &= ~(LifecycleEffectMask | Incomplete);
18217
18218 if (sourceFiber.tag === ClassComponent) {
18219 var currentSourceFiber = sourceFiber.alternate;
18220 if (currentSourceFiber === null) {
18221 // This is a new mount. Change the tag so it's not mistaken for a
18222 // completed class component. For example, we should not call
18223 // componentWillUnmount if it is deleted.
18224 sourceFiber.tag = IncompleteClassComponent;
18225 } else {
18226 // When we try rendering again, we should not reuse the current fiber,
18227 // since it's known to be in an inconsistent state. Use a force updte to
18228 // prevent a bail out.
18229 var update = createUpdate(Sync);
18230 update.tag = ForceUpdate;
18231 enqueueUpdate(sourceFiber, update);
18232 }
18233 }
18234
18235 // The source fiber did not complete. Mark it with Sync priority to
18236 // indicate that it still has pending work.
18237 sourceFiber.expirationTime = Sync;
18238
18239 // Exit without suspending.
18240 return;
18241 }
18242
18243 // Confirmed that the boundary is in a concurrent mode tree. Continue
18244 // with the normal suspend path.
18245
18246 attachPingListener(root, renderExpirationTime, thenable);
18247
18248 var absoluteTimeoutMs = void 0;
18249 if (earliestTimeoutMs === -1) {
18250 // If no explicit threshold is given, default to an arbitrarily large
18251 // value. The actual size doesn't matter because the threshold for the
18252 // whole tree will be clamped to the expiration time.
18253 absoluteTimeoutMs = maxSigned31BitInt;
18254 } else {
18255 if (startTimeMs === -1) {
18256 // This suspend happened outside of any already timed-out
18257 // placeholders. We don't know exactly when the update was
18258 // scheduled, but we can infer an approximate start time from the
18259 // expiration time. First, find the earliest uncommitted expiration
18260 // time in the tree, including work that is suspended. Then subtract
18261 // the offset used to compute an async update's expiration time.
18262 // This will cause high priority (interactive) work to expire
18263 // earlier than necessary, but we can account for this by adjusting
18264 // for the Just Noticeable Difference.
18265 var earliestExpirationTime = findEarliestOutstandingPriorityLevel(root, renderExpirationTime);
18266 var earliestExpirationTimeMs = expirationTimeToMs(earliestExpirationTime);
18267 startTimeMs = earliestExpirationTimeMs - LOW_PRIORITY_EXPIRATION;
18268 }
18269 absoluteTimeoutMs = startTimeMs + earliestTimeoutMs;
18270 }
18271
18272 // Mark the earliest timeout in the suspended fiber's ancestor path.
18273 // After completing the root, we'll take the largest of all the
18274 // suspended fiber's timeouts and use it to compute a timeout for the
18275 // whole tree.
18276 renderDidSuspend(root, absoluteTimeoutMs, renderExpirationTime);
18277
18278 _workInProgress.effectTag |= ShouldCapture;
18279 _workInProgress.expirationTime = renderExpirationTime;
18280 return;
18281 } else if (enableSuspenseServerRenderer && _workInProgress.tag === DehydratedSuspenseComponent) {
18282 attachPingListener(root, renderExpirationTime, thenable);
18283
18284 // Since we already have a current fiber, we can eagerly add a retry listener.
18285 var retryCache = _workInProgress.memoizedState;
18286 if (retryCache === null) {
18287 retryCache = _workInProgress.memoizedState = new PossiblyWeakSet();
18288 var _current = _workInProgress.alternate;
18289 !_current ? invariant(false, 'A dehydrated suspense boundary must commit before trying to render. This is probably a bug in React.') : void 0;
18290 _current.memoizedState = retryCache;
18291 }
18292 // Memoize using the boundary fiber to prevent redundant listeners.
18293 if (!retryCache.has(thenable)) {
18294 retryCache.add(thenable);
18295 var retry = retryTimedOutBoundary.bind(null, _workInProgress, thenable);
18296 if (enableSchedulerTracing) {
18297 retry = tracing.unstable_wrap(retry);
18298 }
18299 thenable.then(retry, retry);
18300 }
18301 _workInProgress.effectTag |= ShouldCapture;
18302 _workInProgress.expirationTime = renderExpirationTime;
18303 return;
18304 }
18305 // This boundary already captured during this render. Continue to the next
18306 // boundary.
18307 _workInProgress = _workInProgress.return;
18308 } while (_workInProgress !== null);
18309 // No boundary was found. Fallthrough to error mode.
18310 // TODO: Use invariant so the message is stripped in prod?
18311 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));
18312 }
18313
18314 // We didn't find a boundary that could handle this type of exception. Start
18315 // over and traverse parent path again, this time treating the exception
18316 // as an error.
18317 renderDidError();
18318 value = createCapturedValue(value, sourceFiber);
18319 var workInProgress = returnFiber;
18320 do {
18321 switch (workInProgress.tag) {
18322 case HostRoot:
18323 {
18324 var _errorInfo = value;
18325 workInProgress.effectTag |= ShouldCapture;
18326 workInProgress.expirationTime = renderExpirationTime;
18327 var _update = createRootErrorUpdate(workInProgress, _errorInfo, renderExpirationTime);
18328 enqueueCapturedUpdate(workInProgress, _update);
18329 return;
18330 }
18331 case ClassComponent:
18332 // Capture and retry
18333 var errorInfo = value;
18334 var ctor = workInProgress.type;
18335 var instance = workInProgress.stateNode;
18336 if ((workInProgress.effectTag & DidCapture) === NoEffect && (typeof ctor.getDerivedStateFromError === 'function' || instance !== null && typeof instance.componentDidCatch === 'function' && !isAlreadyFailedLegacyErrorBoundary(instance))) {
18337 workInProgress.effectTag |= ShouldCapture;
18338 workInProgress.expirationTime = renderExpirationTime;
18339 // Schedule the error boundary to re-render using updated state
18340 var _update2 = createClassErrorUpdate(workInProgress, errorInfo, renderExpirationTime);
18341 enqueueCapturedUpdate(workInProgress, _update2);
18342 return;
18343 }
18344 break;
18345 default:
18346 break;
18347 }
18348 workInProgress = workInProgress.return;
18349 } while (workInProgress !== null);
18350}
18351
18352function unwindWork(workInProgress, renderExpirationTime) {
18353 switch (workInProgress.tag) {
18354 case ClassComponent:
18355 {
18356 var Component = workInProgress.type;
18357 if (isContextProvider(Component)) {
18358 popContext(workInProgress);
18359 }
18360 var effectTag = workInProgress.effectTag;
18361 if (effectTag & ShouldCapture) {
18362 workInProgress.effectTag = effectTag & ~ShouldCapture | DidCapture;
18363 return workInProgress;
18364 }
18365 return null;
18366 }
18367 case HostRoot:
18368 {
18369 popHostContainer(workInProgress);
18370 popTopLevelContextObject(workInProgress);
18371 var _effectTag = workInProgress.effectTag;
18372 !((_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;
18373 workInProgress.effectTag = _effectTag & ~ShouldCapture | DidCapture;
18374 return workInProgress;
18375 }
18376 case HostComponent:
18377 {
18378 // TODO: popHydrationState
18379 popHostContext(workInProgress);
18380 return null;
18381 }
18382 case SuspenseComponent:
18383 {
18384 var _effectTag2 = workInProgress.effectTag;
18385 if (_effectTag2 & ShouldCapture) {
18386 workInProgress.effectTag = _effectTag2 & ~ShouldCapture | DidCapture;
18387 // Captured a suspense effect. Re-render the boundary.
18388 return workInProgress;
18389 }
18390 return null;
18391 }
18392 case DehydratedSuspenseComponent:
18393 {
18394 if (enableSuspenseServerRenderer) {
18395 // TODO: popHydrationState
18396 var _effectTag3 = workInProgress.effectTag;
18397 if (_effectTag3 & ShouldCapture) {
18398 workInProgress.effectTag = _effectTag3 & ~ShouldCapture | DidCapture;
18399 // Captured a suspense effect. Re-render the boundary.
18400 return workInProgress;
18401 }
18402 }
18403 return null;
18404 }
18405 case HostPortal:
18406 popHostContainer(workInProgress);
18407 return null;
18408 case ContextProvider:
18409 popProvider(workInProgress);
18410 return null;
18411 default:
18412 return null;
18413 }
18414}
18415
18416function unwindInterruptedWork(interruptedWork) {
18417 switch (interruptedWork.tag) {
18418 case ClassComponent:
18419 {
18420 var childContextTypes = interruptedWork.type.childContextTypes;
18421 if (childContextTypes !== null && childContextTypes !== undefined) {
18422 popContext(interruptedWork);
18423 }
18424 break;
18425 }
18426 case HostRoot:
18427 {
18428 popHostContainer(interruptedWork);
18429 popTopLevelContextObject(interruptedWork);
18430 break;
18431 }
18432 case HostComponent:
18433 {
18434 popHostContext(interruptedWork);
18435 break;
18436 }
18437 case HostPortal:
18438 popHostContainer(interruptedWork);
18439 break;
18440 case ContextProvider:
18441 popProvider(interruptedWork);
18442 break;
18443 default:
18444 break;
18445 }
18446}
18447
18448var ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher;
18449var ReactCurrentOwner$2 = ReactSharedInternals.ReactCurrentOwner;
18450
18451
18452var didWarnAboutStateTransition = void 0;
18453var didWarnSetStateChildContext = void 0;
18454var warnAboutUpdateOnUnmounted = void 0;
18455var warnAboutInvalidUpdates = void 0;
18456
18457if (enableSchedulerTracing) {
18458 // Provide explicit error message when production+profiling bundle of e.g. react-dom
18459 // is used with production (non-profiling) bundle of scheduler/tracing
18460 !(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;
18461}
18462
18463{
18464 didWarnAboutStateTransition = false;
18465 didWarnSetStateChildContext = false;
18466 var didWarnStateUpdateForUnmountedComponent = {};
18467
18468 warnAboutUpdateOnUnmounted = function (fiber, isClass) {
18469 // We show the whole stack but dedupe on the top component's name because
18470 // the problematic code almost always lies inside that component.
18471 var componentName = getComponentName(fiber.type) || 'ReactComponent';
18472 if (didWarnStateUpdateForUnmountedComponent[componentName]) {
18473 return;
18474 }
18475 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));
18476 didWarnStateUpdateForUnmountedComponent[componentName] = true;
18477 };
18478
18479 warnAboutInvalidUpdates = function (instance) {
18480 switch (phase) {
18481 case 'getChildContext':
18482 if (didWarnSetStateChildContext) {
18483 return;
18484 }
18485 warningWithoutStack$1(false, 'setState(...): Cannot call setState() inside getChildContext()');
18486 didWarnSetStateChildContext = true;
18487 break;
18488 case 'render':
18489 if (didWarnAboutStateTransition) {
18490 return;
18491 }
18492 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.');
18493 didWarnAboutStateTransition = true;
18494 break;
18495 }
18496 };
18497}
18498
18499// Used to ensure computeUniqueAsyncExpiration is monotonically decreasing.
18500var lastUniqueAsyncExpiration = Sync - 1;
18501
18502var isWorking = false;
18503
18504// The next work in progress fiber that we're currently working on.
18505var nextUnitOfWork = null;
18506var nextRoot = null;
18507// The time at which we're currently rendering work.
18508var nextRenderExpirationTime = NoWork;
18509var nextLatestAbsoluteTimeoutMs = -1;
18510var nextRenderDidError = false;
18511
18512// The next fiber with an effect that we're currently committing.
18513var nextEffect = null;
18514
18515var isCommitting$1 = false;
18516var rootWithPendingPassiveEffects = null;
18517var passiveEffectCallbackHandle = null;
18518var passiveEffectCallback = null;
18519
18520var legacyErrorBoundariesThatAlreadyFailed = null;
18521
18522// Used for performance tracking.
18523var interruptedBy = null;
18524
18525var stashedWorkInProgressProperties = void 0;
18526var replayUnitOfWork = void 0;
18527var mayReplayFailedUnitOfWork = void 0;
18528var isReplayingFailedUnitOfWork = void 0;
18529var originalReplayError = void 0;
18530var rethrowOriginalError = void 0;
18531if (true && replayFailedUnitOfWorkWithInvokeGuardedCallback) {
18532 stashedWorkInProgressProperties = null;
18533 mayReplayFailedUnitOfWork = true;
18534 isReplayingFailedUnitOfWork = false;
18535 originalReplayError = null;
18536 replayUnitOfWork = function (failedUnitOfWork, thrownValue, isYieldy) {
18537 if (thrownValue !== null && typeof thrownValue === 'object' && typeof thrownValue.then === 'function') {
18538 // Don't replay promises. Treat everything else like an error.
18539 // TODO: Need to figure out a different strategy if/when we add
18540 // support for catching other types.
18541 return;
18542 }
18543
18544 // Restore the original state of the work-in-progress
18545 if (stashedWorkInProgressProperties === null) {
18546 // This should never happen. Don't throw because this code is DEV-only.
18547 warningWithoutStack$1(false, 'Could not replay rendering after an error. This is likely a bug in React. ' + 'Please file an issue.');
18548 return;
18549 }
18550 assignFiberPropertiesInDEV(failedUnitOfWork, stashedWorkInProgressProperties);
18551
18552 switch (failedUnitOfWork.tag) {
18553 case HostRoot:
18554 popHostContainer(failedUnitOfWork);
18555 popTopLevelContextObject(failedUnitOfWork);
18556 break;
18557 case HostComponent:
18558 popHostContext(failedUnitOfWork);
18559 break;
18560 case ClassComponent:
18561 {
18562 var Component = failedUnitOfWork.type;
18563 if (isContextProvider(Component)) {
18564 popContext(failedUnitOfWork);
18565 }
18566 break;
18567 }
18568 case HostPortal:
18569 popHostContainer(failedUnitOfWork);
18570 break;
18571 case ContextProvider:
18572 popProvider(failedUnitOfWork);
18573 break;
18574 }
18575 // Replay the begin phase.
18576 isReplayingFailedUnitOfWork = true;
18577 originalReplayError = thrownValue;
18578 invokeGuardedCallback(null, workLoop, null, isYieldy);
18579 isReplayingFailedUnitOfWork = false;
18580 originalReplayError = null;
18581 if (hasCaughtError()) {
18582 var replayError = clearCaughtError();
18583 if (replayError != null && thrownValue != null) {
18584 try {
18585 // Reading the expando property is intentionally
18586 // inside `try` because it might be a getter or Proxy.
18587 if (replayError._suppressLogging) {
18588 // Also suppress logging for the original error.
18589 thrownValue._suppressLogging = true;
18590 }
18591 } catch (inner) {
18592 // Ignore.
18593 }
18594 }
18595 } else {
18596 // If the begin phase did not fail the second time, set this pointer
18597 // back to the original value.
18598 nextUnitOfWork = failedUnitOfWork;
18599 }
18600 };
18601 rethrowOriginalError = function () {
18602 throw originalReplayError;
18603 };
18604}
18605
18606function resetStack() {
18607 if (nextUnitOfWork !== null) {
18608 var interruptedWork = nextUnitOfWork.return;
18609 while (interruptedWork !== null) {
18610 unwindInterruptedWork(interruptedWork);
18611 interruptedWork = interruptedWork.return;
18612 }
18613 }
18614
18615 {
18616 ReactStrictModeWarnings.discardPendingWarnings();
18617 checkThatStackIsEmpty();
18618 }
18619
18620 nextRoot = null;
18621 nextRenderExpirationTime = NoWork;
18622 nextLatestAbsoluteTimeoutMs = -1;
18623 nextRenderDidError = false;
18624 nextUnitOfWork = null;
18625}
18626
18627function commitAllHostEffects() {
18628 while (nextEffect !== null) {
18629 {
18630 setCurrentFiber(nextEffect);
18631 }
18632 recordEffect();
18633
18634 var effectTag = nextEffect.effectTag;
18635
18636 if (effectTag & ContentReset) {
18637 commitResetTextContent(nextEffect);
18638 }
18639
18640 if (effectTag & Ref) {
18641 var current$$1 = nextEffect.alternate;
18642 if (current$$1 !== null) {
18643 commitDetachRef(current$$1);
18644 }
18645 }
18646
18647 // The following switch statement is only concerned about placement,
18648 // updates, and deletions. To avoid needing to add a case for every
18649 // possible bitmap value, we remove the secondary effects from the
18650 // effect tag and switch on that value.
18651 var primaryEffectTag = effectTag & (Placement | Update | Deletion);
18652 switch (primaryEffectTag) {
18653 case Placement:
18654 {
18655 commitPlacement(nextEffect);
18656 // Clear the "placement" from effect tag so that we know that this is inserted, before
18657 // any life-cycles like componentDidMount gets called.
18658 // TODO: findDOMNode doesn't rely on this any more but isMounted
18659 // does and isMounted is deprecated anyway so we should be able
18660 // to kill this.
18661 nextEffect.effectTag &= ~Placement;
18662 break;
18663 }
18664 case PlacementAndUpdate:
18665 {
18666 // Placement
18667 commitPlacement(nextEffect);
18668 // Clear the "placement" from effect tag so that we know that this is inserted, before
18669 // any life-cycles like componentDidMount gets called.
18670 nextEffect.effectTag &= ~Placement;
18671
18672 // Update
18673 var _current = nextEffect.alternate;
18674 commitWork(_current, nextEffect);
18675 break;
18676 }
18677 case Update:
18678 {
18679 var _current2 = nextEffect.alternate;
18680 commitWork(_current2, nextEffect);
18681 break;
18682 }
18683 case Deletion:
18684 {
18685 commitDeletion(nextEffect);
18686 break;
18687 }
18688 }
18689 nextEffect = nextEffect.nextEffect;
18690 }
18691
18692 {
18693 resetCurrentFiber();
18694 }
18695}
18696
18697function commitBeforeMutationLifecycles() {
18698 while (nextEffect !== null) {
18699 {
18700 setCurrentFiber(nextEffect);
18701 }
18702
18703 var effectTag = nextEffect.effectTag;
18704 if (effectTag & Snapshot) {
18705 recordEffect();
18706 var current$$1 = nextEffect.alternate;
18707 commitBeforeMutationLifeCycles(current$$1, nextEffect);
18708 }
18709
18710 nextEffect = nextEffect.nextEffect;
18711 }
18712
18713 {
18714 resetCurrentFiber();
18715 }
18716}
18717
18718function commitAllLifeCycles(finishedRoot, committedExpirationTime) {
18719 {
18720 ReactStrictModeWarnings.flushPendingUnsafeLifecycleWarnings();
18721 ReactStrictModeWarnings.flushLegacyContextWarning();
18722
18723 if (warnAboutDeprecatedLifecycles) {
18724 ReactStrictModeWarnings.flushPendingDeprecationWarnings();
18725 }
18726 }
18727 while (nextEffect !== null) {
18728 {
18729 setCurrentFiber(nextEffect);
18730 }
18731 var effectTag = nextEffect.effectTag;
18732
18733 if (effectTag & (Update | Callback)) {
18734 recordEffect();
18735 var current$$1 = nextEffect.alternate;
18736 commitLifeCycles(finishedRoot, current$$1, nextEffect, committedExpirationTime);
18737 }
18738
18739 if (effectTag & Ref) {
18740 recordEffect();
18741 commitAttachRef(nextEffect);
18742 }
18743
18744 if (effectTag & Passive) {
18745 rootWithPendingPassiveEffects = finishedRoot;
18746 }
18747
18748 nextEffect = nextEffect.nextEffect;
18749 }
18750 {
18751 resetCurrentFiber();
18752 }
18753}
18754
18755function commitPassiveEffects(root, firstEffect) {
18756 rootWithPendingPassiveEffects = null;
18757 passiveEffectCallbackHandle = null;
18758 passiveEffectCallback = null;
18759
18760 // Set this to true to prevent re-entrancy
18761 var previousIsRendering = isRendering;
18762 isRendering = true;
18763
18764 var effect = firstEffect;
18765 do {
18766 {
18767 setCurrentFiber(effect);
18768 }
18769
18770 if (effect.effectTag & Passive) {
18771 var didError = false;
18772 var error = void 0;
18773 {
18774 invokeGuardedCallback(null, commitPassiveHookEffects, null, effect);
18775 if (hasCaughtError()) {
18776 didError = true;
18777 error = clearCaughtError();
18778 }
18779 }
18780 if (didError) {
18781 captureCommitPhaseError(effect, error);
18782 }
18783 }
18784 effect = effect.nextEffect;
18785 } while (effect !== null);
18786 {
18787 resetCurrentFiber();
18788 }
18789
18790 isRendering = previousIsRendering;
18791
18792 // Check if work was scheduled by one of the effects
18793 var rootExpirationTime = root.expirationTime;
18794 if (rootExpirationTime !== NoWork) {
18795 requestWork(root, rootExpirationTime);
18796 }
18797 // Flush any sync work that was scheduled by effects
18798 if (!isBatchingUpdates && !isRendering) {
18799 performSyncWork();
18800 }
18801}
18802
18803function isAlreadyFailedLegacyErrorBoundary(instance) {
18804 return legacyErrorBoundariesThatAlreadyFailed !== null && legacyErrorBoundariesThatAlreadyFailed.has(instance);
18805}
18806
18807function markLegacyErrorBoundaryAsFailed(instance) {
18808 if (legacyErrorBoundariesThatAlreadyFailed === null) {
18809 legacyErrorBoundariesThatAlreadyFailed = new Set([instance]);
18810 } else {
18811 legacyErrorBoundariesThatAlreadyFailed.add(instance);
18812 }
18813}
18814
18815function flushPassiveEffects() {
18816 if (passiveEffectCallbackHandle !== null) {
18817 cancelPassiveEffects(passiveEffectCallbackHandle);
18818 }
18819 if (passiveEffectCallback !== null) {
18820 // We call the scheduled callback instead of commitPassiveEffects directly
18821 // to ensure tracing works correctly.
18822 passiveEffectCallback();
18823 }
18824}
18825
18826function commitRoot(root, finishedWork) {
18827 isWorking = true;
18828 isCommitting$1 = true;
18829 startCommitTimer();
18830
18831 !(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;
18832 var committedExpirationTime = root.pendingCommitExpirationTime;
18833 !(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;
18834 root.pendingCommitExpirationTime = NoWork;
18835
18836 // Update the pending priority levels to account for the work that we are
18837 // about to commit. This needs to happen before calling the lifecycles, since
18838 // they may schedule additional updates.
18839 var updateExpirationTimeBeforeCommit = finishedWork.expirationTime;
18840 var childExpirationTimeBeforeCommit = finishedWork.childExpirationTime;
18841 var earliestRemainingTimeBeforeCommit = childExpirationTimeBeforeCommit > updateExpirationTimeBeforeCommit ? childExpirationTimeBeforeCommit : updateExpirationTimeBeforeCommit;
18842 markCommittedPriorityLevels(root, earliestRemainingTimeBeforeCommit);
18843
18844 var prevInteractions = null;
18845 if (enableSchedulerTracing) {
18846 // Restore any pending interactions at this point,
18847 // So that cascading work triggered during the render phase will be accounted for.
18848 prevInteractions = tracing.__interactionsRef.current;
18849 tracing.__interactionsRef.current = root.memoizedInteractions;
18850 }
18851
18852 // Reset this to null before calling lifecycles
18853 ReactCurrentOwner$2.current = null;
18854
18855 var firstEffect = void 0;
18856 if (finishedWork.effectTag > PerformedWork) {
18857 // A fiber's effect list consists only of its children, not itself. So if
18858 // the root has an effect, we need to add it to the end of the list. The
18859 // resulting list is the set that would belong to the root's parent, if
18860 // it had one; that is, all the effects in the tree including the root.
18861 if (finishedWork.lastEffect !== null) {
18862 finishedWork.lastEffect.nextEffect = finishedWork;
18863 firstEffect = finishedWork.firstEffect;
18864 } else {
18865 firstEffect = finishedWork;
18866 }
18867 } else {
18868 // There is no effect on the root.
18869 firstEffect = finishedWork.firstEffect;
18870 }
18871
18872 prepareForCommit(root.containerInfo);
18873
18874 // Invoke instances of getSnapshotBeforeUpdate before mutation.
18875 nextEffect = firstEffect;
18876 startCommitSnapshotEffectsTimer();
18877 while (nextEffect !== null) {
18878 var didError = false;
18879 var error = void 0;
18880 {
18881 invokeGuardedCallback(null, commitBeforeMutationLifecycles, null);
18882 if (hasCaughtError()) {
18883 didError = true;
18884 error = clearCaughtError();
18885 }
18886 }
18887 if (didError) {
18888 !(nextEffect !== null) ? invariant(false, 'Should have next effect. This error is likely caused by a bug in React. Please file an issue.') : void 0;
18889 captureCommitPhaseError(nextEffect, error);
18890 // Clean-up
18891 if (nextEffect !== null) {
18892 nextEffect = nextEffect.nextEffect;
18893 }
18894 }
18895 }
18896 stopCommitSnapshotEffectsTimer();
18897
18898 if (enableProfilerTimer) {
18899 // Mark the current commit time to be shared by all Profilers in this batch.
18900 // This enables them to be grouped later.
18901 recordCommitTime();
18902 }
18903
18904 // Commit all the side-effects within a tree. We'll do this in two passes.
18905 // The first pass performs all the host insertions, updates, deletions and
18906 // ref unmounts.
18907 nextEffect = firstEffect;
18908 startCommitHostEffectsTimer();
18909 while (nextEffect !== null) {
18910 var _didError = false;
18911 var _error = void 0;
18912 {
18913 invokeGuardedCallback(null, commitAllHostEffects, null);
18914 if (hasCaughtError()) {
18915 _didError = true;
18916 _error = clearCaughtError();
18917 }
18918 }
18919 if (_didError) {
18920 !(nextEffect !== null) ? invariant(false, 'Should have next effect. This error is likely caused by a bug in React. Please file an issue.') : void 0;
18921 captureCommitPhaseError(nextEffect, _error);
18922 // Clean-up
18923 if (nextEffect !== null) {
18924 nextEffect = nextEffect.nextEffect;
18925 }
18926 }
18927 }
18928 stopCommitHostEffectsTimer();
18929
18930 resetAfterCommit(root.containerInfo);
18931
18932 // The work-in-progress tree is now the current tree. This must come after
18933 // the first pass of the commit phase, so that the previous tree is still
18934 // current during componentWillUnmount, but before the second pass, so that
18935 // the finished work is current during componentDidMount/Update.
18936 root.current = finishedWork;
18937
18938 // In the second pass we'll perform all life-cycles and ref callbacks.
18939 // Life-cycles happen as a separate pass so that all placements, updates,
18940 // and deletions in the entire tree have already been invoked.
18941 // This pass also triggers any renderer-specific initial effects.
18942 nextEffect = firstEffect;
18943 startCommitLifeCyclesTimer();
18944 while (nextEffect !== null) {
18945 var _didError2 = false;
18946 var _error2 = void 0;
18947 {
18948 invokeGuardedCallback(null, commitAllLifeCycles, null, root, committedExpirationTime);
18949 if (hasCaughtError()) {
18950 _didError2 = true;
18951 _error2 = clearCaughtError();
18952 }
18953 }
18954 if (_didError2) {
18955 !(nextEffect !== null) ? invariant(false, 'Should have next effect. This error is likely caused by a bug in React. Please file an issue.') : void 0;
18956 captureCommitPhaseError(nextEffect, _error2);
18957 if (nextEffect !== null) {
18958 nextEffect = nextEffect.nextEffect;
18959 }
18960 }
18961 }
18962
18963 if (firstEffect !== null && rootWithPendingPassiveEffects !== null) {
18964 // This commit included a passive effect. These do not need to fire until
18965 // after the next paint. Schedule an callback to fire them in an async
18966 // event. To ensure serial execution, the callback will be flushed early if
18967 // we enter rootWithPendingPassiveEffects commit phase before then.
18968 var callback = commitPassiveEffects.bind(null, root, firstEffect);
18969 if (enableSchedulerTracing) {
18970 // TODO: Avoid this extra callback by mutating the tracing ref directly,
18971 // like we do at the beginning of commitRoot. I've opted not to do that
18972 // here because that code is still in flux.
18973 callback = tracing.unstable_wrap(callback);
18974 }
18975 passiveEffectCallbackHandle = scheduler.unstable_runWithPriority(scheduler.unstable_NormalPriority, function () {
18976 return schedulePassiveEffects(callback);
18977 });
18978 passiveEffectCallback = callback;
18979 }
18980
18981 isCommitting$1 = false;
18982 isWorking = false;
18983 stopCommitLifeCyclesTimer();
18984 stopCommitTimer();
18985 onCommitRoot(finishedWork.stateNode);
18986 if (true && ReactFiberInstrumentation_1.debugTool) {
18987 ReactFiberInstrumentation_1.debugTool.onCommitWork(finishedWork);
18988 }
18989
18990 var updateExpirationTimeAfterCommit = finishedWork.expirationTime;
18991 var childExpirationTimeAfterCommit = finishedWork.childExpirationTime;
18992 var earliestRemainingTimeAfterCommit = childExpirationTimeAfterCommit > updateExpirationTimeAfterCommit ? childExpirationTimeAfterCommit : updateExpirationTimeAfterCommit;
18993 if (earliestRemainingTimeAfterCommit === NoWork) {
18994 // If there's no remaining work, we can clear the set of already failed
18995 // error boundaries.
18996 legacyErrorBoundariesThatAlreadyFailed = null;
18997 }
18998 onCommit(root, earliestRemainingTimeAfterCommit);
18999
19000 if (enableSchedulerTracing) {
19001 tracing.__interactionsRef.current = prevInteractions;
19002
19003 var subscriber = void 0;
19004
19005 try {
19006 subscriber = tracing.__subscriberRef.current;
19007 if (subscriber !== null && root.memoizedInteractions.size > 0) {
19008 var threadID = computeThreadID(committedExpirationTime, root.interactionThreadID);
19009 subscriber.onWorkStopped(root.memoizedInteractions, threadID);
19010 }
19011 } catch (error) {
19012 // It's not safe for commitRoot() to throw.
19013 // Store the error for now and we'll re-throw in finishRendering().
19014 if (!hasUnhandledError) {
19015 hasUnhandledError = true;
19016 unhandledError = error;
19017 }
19018 } finally {
19019 // Clear completed interactions from the pending Map.
19020 // Unless the render was suspended or cascading work was scheduled,
19021 // In which case– leave pending interactions until the subsequent render.
19022 var pendingInteractionMap = root.pendingInteractionMap;
19023 pendingInteractionMap.forEach(function (scheduledInteractions, scheduledExpirationTime) {
19024 // Only decrement the pending interaction count if we're done.
19025 // If there's still work at the current priority,
19026 // That indicates that we are waiting for suspense data.
19027 if (scheduledExpirationTime > earliestRemainingTimeAfterCommit) {
19028 pendingInteractionMap.delete(scheduledExpirationTime);
19029
19030 scheduledInteractions.forEach(function (interaction) {
19031 interaction.__count--;
19032
19033 if (subscriber !== null && interaction.__count === 0) {
19034 try {
19035 subscriber.onInteractionScheduledWorkCompleted(interaction);
19036 } catch (error) {
19037 // It's not safe for commitRoot() to throw.
19038 // Store the error for now and we'll re-throw in finishRendering().
19039 if (!hasUnhandledError) {
19040 hasUnhandledError = true;
19041 unhandledError = error;
19042 }
19043 }
19044 }
19045 });
19046 }
19047 });
19048 }
19049 }
19050}
19051
19052function resetChildExpirationTime(workInProgress, renderTime) {
19053 if (renderTime !== Never && workInProgress.childExpirationTime === Never) {
19054 // The children of this component are hidden. Don't bubble their
19055 // expiration times.
19056 return;
19057 }
19058
19059 var newChildExpirationTime = NoWork;
19060
19061 // Bubble up the earliest expiration time.
19062 if (enableProfilerTimer && workInProgress.mode & ProfileMode) {
19063 // We're in profiling mode.
19064 // Let's use this same traversal to update the render durations.
19065 var actualDuration = workInProgress.actualDuration;
19066 var treeBaseDuration = workInProgress.selfBaseDuration;
19067
19068 // When a fiber is cloned, its actualDuration is reset to 0.
19069 // This value will only be updated if work is done on the fiber (i.e. it doesn't bailout).
19070 // When work is done, it should bubble to the parent's actualDuration.
19071 // If the fiber has not been cloned though, (meaning no work was done),
19072 // Then this value will reflect the amount of time spent working on a previous render.
19073 // In that case it should not bubble.
19074 // We determine whether it was cloned by comparing the child pointer.
19075 var shouldBubbleActualDurations = workInProgress.alternate === null || workInProgress.child !== workInProgress.alternate.child;
19076
19077 var child = workInProgress.child;
19078 while (child !== null) {
19079 var childUpdateExpirationTime = child.expirationTime;
19080 var childChildExpirationTime = child.childExpirationTime;
19081 if (childUpdateExpirationTime > newChildExpirationTime) {
19082 newChildExpirationTime = childUpdateExpirationTime;
19083 }
19084 if (childChildExpirationTime > newChildExpirationTime) {
19085 newChildExpirationTime = childChildExpirationTime;
19086 }
19087 if (shouldBubbleActualDurations) {
19088 actualDuration += child.actualDuration;
19089 }
19090 treeBaseDuration += child.treeBaseDuration;
19091 child = child.sibling;
19092 }
19093 workInProgress.actualDuration = actualDuration;
19094 workInProgress.treeBaseDuration = treeBaseDuration;
19095 } else {
19096 var _child = workInProgress.child;
19097 while (_child !== null) {
19098 var _childUpdateExpirationTime = _child.expirationTime;
19099 var _childChildExpirationTime = _child.childExpirationTime;
19100 if (_childUpdateExpirationTime > newChildExpirationTime) {
19101 newChildExpirationTime = _childUpdateExpirationTime;
19102 }
19103 if (_childChildExpirationTime > newChildExpirationTime) {
19104 newChildExpirationTime = _childChildExpirationTime;
19105 }
19106 _child = _child.sibling;
19107 }
19108 }
19109
19110 workInProgress.childExpirationTime = newChildExpirationTime;
19111}
19112
19113function completeUnitOfWork(workInProgress) {
19114 // Attempt to complete the current unit of work, then move to the
19115 // next sibling. If there are no more siblings, return to the
19116 // parent fiber.
19117 while (true) {
19118 // The current, flushed, state of this fiber is the alternate.
19119 // Ideally nothing should rely on this, but relying on it here
19120 // means that we don't need an additional field on the work in
19121 // progress.
19122 var current$$1 = workInProgress.alternate;
19123 {
19124 setCurrentFiber(workInProgress);
19125 }
19126
19127 var returnFiber = workInProgress.return;
19128 var siblingFiber = workInProgress.sibling;
19129
19130 if ((workInProgress.effectTag & Incomplete) === NoEffect) {
19131 if (true && replayFailedUnitOfWorkWithInvokeGuardedCallback) {
19132 // Don't replay if it fails during completion phase.
19133 mayReplayFailedUnitOfWork = false;
19134 }
19135 // This fiber completed.
19136 // Remember we're completing this unit so we can find a boundary if it fails.
19137 nextUnitOfWork = workInProgress;
19138 if (enableProfilerTimer) {
19139 if (workInProgress.mode & ProfileMode) {
19140 startProfilerTimer(workInProgress);
19141 }
19142 nextUnitOfWork = completeWork(current$$1, workInProgress, nextRenderExpirationTime);
19143 if (workInProgress.mode & ProfileMode) {
19144 // Update render duration assuming we didn't error.
19145 stopProfilerTimerIfRunningAndRecordDelta(workInProgress, false);
19146 }
19147 } else {
19148 nextUnitOfWork = completeWork(current$$1, workInProgress, nextRenderExpirationTime);
19149 }
19150 if (true && replayFailedUnitOfWorkWithInvokeGuardedCallback) {
19151 // We're out of completion phase so replaying is fine now.
19152 mayReplayFailedUnitOfWork = true;
19153 }
19154 stopWorkTimer(workInProgress);
19155 resetChildExpirationTime(workInProgress, nextRenderExpirationTime);
19156 {
19157 resetCurrentFiber();
19158 }
19159
19160 if (nextUnitOfWork !== null) {
19161 // Completing this fiber spawned new work. Work on that next.
19162 return nextUnitOfWork;
19163 }
19164
19165 if (returnFiber !== null &&
19166 // Do not append effects to parents if a sibling failed to complete
19167 (returnFiber.effectTag & Incomplete) === NoEffect) {
19168 // Append all the effects of the subtree and this fiber onto the effect
19169 // list of the parent. The completion order of the children affects the
19170 // side-effect order.
19171 if (returnFiber.firstEffect === null) {
19172 returnFiber.firstEffect = workInProgress.firstEffect;
19173 }
19174 if (workInProgress.lastEffect !== null) {
19175 if (returnFiber.lastEffect !== null) {
19176 returnFiber.lastEffect.nextEffect = workInProgress.firstEffect;
19177 }
19178 returnFiber.lastEffect = workInProgress.lastEffect;
19179 }
19180
19181 // If this fiber had side-effects, we append it AFTER the children's
19182 // side-effects. We can perform certain side-effects earlier if
19183 // needed, by doing multiple passes over the effect list. We don't want
19184 // to schedule our own side-effect on our own list because if end up
19185 // reusing children we'll schedule this effect onto itself since we're
19186 // at the end.
19187 var effectTag = workInProgress.effectTag;
19188 // Skip both NoWork and PerformedWork tags when creating the effect list.
19189 // PerformedWork effect is read by React DevTools but shouldn't be committed.
19190 if (effectTag > PerformedWork) {
19191 if (returnFiber.lastEffect !== null) {
19192 returnFiber.lastEffect.nextEffect = workInProgress;
19193 } else {
19194 returnFiber.firstEffect = workInProgress;
19195 }
19196 returnFiber.lastEffect = workInProgress;
19197 }
19198 }
19199
19200 if (true && ReactFiberInstrumentation_1.debugTool) {
19201 ReactFiberInstrumentation_1.debugTool.onCompleteWork(workInProgress);
19202 }
19203
19204 if (siblingFiber !== null) {
19205 // If there is more work to do in this returnFiber, do that next.
19206 return siblingFiber;
19207 } else if (returnFiber !== null) {
19208 // If there's no more work in this returnFiber. Complete the returnFiber.
19209 workInProgress = returnFiber;
19210 continue;
19211 } else {
19212 // We've reached the root.
19213 return null;
19214 }
19215 } else {
19216 if (enableProfilerTimer && workInProgress.mode & ProfileMode) {
19217 // Record the render duration for the fiber that errored.
19218 stopProfilerTimerIfRunningAndRecordDelta(workInProgress, false);
19219
19220 // Include the time spent working on failed children before continuing.
19221 var actualDuration = workInProgress.actualDuration;
19222 var child = workInProgress.child;
19223 while (child !== null) {
19224 actualDuration += child.actualDuration;
19225 child = child.sibling;
19226 }
19227 workInProgress.actualDuration = actualDuration;
19228 }
19229
19230 // This fiber did not complete because something threw. Pop values off
19231 // the stack without entering the complete phase. If this is a boundary,
19232 // capture values if possible.
19233 var next = unwindWork(workInProgress, nextRenderExpirationTime);
19234 // Because this fiber did not complete, don't reset its expiration time.
19235 if (workInProgress.effectTag & DidCapture) {
19236 // Restarting an error boundary
19237 stopFailedWorkTimer(workInProgress);
19238 } else {
19239 stopWorkTimer(workInProgress);
19240 }
19241
19242 {
19243 resetCurrentFiber();
19244 }
19245
19246 if (next !== null) {
19247 stopWorkTimer(workInProgress);
19248 if (true && ReactFiberInstrumentation_1.debugTool) {
19249 ReactFiberInstrumentation_1.debugTool.onCompleteWork(workInProgress);
19250 }
19251
19252 // If completing this work spawned new work, do that next. We'll come
19253 // back here again.
19254 // Since we're restarting, remove anything that is not a host effect
19255 // from the effect tag.
19256 next.effectTag &= HostEffectMask;
19257 return next;
19258 }
19259
19260 if (returnFiber !== null) {
19261 // Mark the parent fiber as incomplete and clear its effect list.
19262 returnFiber.firstEffect = returnFiber.lastEffect = null;
19263 returnFiber.effectTag |= Incomplete;
19264 }
19265
19266 if (true && ReactFiberInstrumentation_1.debugTool) {
19267 ReactFiberInstrumentation_1.debugTool.onCompleteWork(workInProgress);
19268 }
19269
19270 if (siblingFiber !== null) {
19271 // If there is more work to do in this returnFiber, do that next.
19272 return siblingFiber;
19273 } else if (returnFiber !== null) {
19274 // If there's no more work in this returnFiber. Complete the returnFiber.
19275 workInProgress = returnFiber;
19276 continue;
19277 } else {
19278 return null;
19279 }
19280 }
19281 }
19282
19283 // Without this explicit null return Flow complains of invalid return type
19284 // TODO Remove the above while(true) loop
19285 // eslint-disable-next-line no-unreachable
19286 return null;
19287}
19288
19289function performUnitOfWork(workInProgress) {
19290 // The current, flushed, state of this fiber is the alternate.
19291 // Ideally nothing should rely on this, but relying on it here
19292 // means that we don't need an additional field on the work in
19293 // progress.
19294 var current$$1 = workInProgress.alternate;
19295
19296 // See if beginning this work spawns more work.
19297 startWorkTimer(workInProgress);
19298 {
19299 setCurrentFiber(workInProgress);
19300 }
19301
19302 if (true && replayFailedUnitOfWorkWithInvokeGuardedCallback) {
19303 stashedWorkInProgressProperties = assignFiberPropertiesInDEV(stashedWorkInProgressProperties, workInProgress);
19304 }
19305
19306 var next = void 0;
19307 if (enableProfilerTimer) {
19308 if (workInProgress.mode & ProfileMode) {
19309 startProfilerTimer(workInProgress);
19310 }
19311
19312 next = beginWork(current$$1, workInProgress, nextRenderExpirationTime);
19313 workInProgress.memoizedProps = workInProgress.pendingProps;
19314
19315 if (workInProgress.mode & ProfileMode) {
19316 // Record the render duration assuming we didn't bailout (or error).
19317 stopProfilerTimerIfRunningAndRecordDelta(workInProgress, true);
19318 }
19319 } else {
19320 next = beginWork(current$$1, workInProgress, nextRenderExpirationTime);
19321 workInProgress.memoizedProps = workInProgress.pendingProps;
19322 }
19323
19324 {
19325 resetCurrentFiber();
19326 if (isReplayingFailedUnitOfWork) {
19327 // Currently replaying a failed unit of work. This should be unreachable,
19328 // because the render phase is meant to be idempotent, and it should
19329 // have thrown again. Since it didn't, rethrow the original error, so
19330 // React's internal stack is not misaligned.
19331 rethrowOriginalError();
19332 }
19333 }
19334 if (true && ReactFiberInstrumentation_1.debugTool) {
19335 ReactFiberInstrumentation_1.debugTool.onBeginWork(workInProgress);
19336 }
19337
19338 if (next === null) {
19339 // If this doesn't spawn new work, complete the current work.
19340 next = completeUnitOfWork(workInProgress);
19341 }
19342
19343 ReactCurrentOwner$2.current = null;
19344
19345 return next;
19346}
19347
19348function workLoop(isYieldy) {
19349 if (!isYieldy) {
19350 // Flush work without yielding
19351 while (nextUnitOfWork !== null) {
19352 nextUnitOfWork = performUnitOfWork(nextUnitOfWork);
19353 }
19354 } else {
19355 // Flush asynchronous work until there's a higher priority event
19356 while (nextUnitOfWork !== null && !shouldYieldToRenderer()) {
19357 nextUnitOfWork = performUnitOfWork(nextUnitOfWork);
19358 }
19359 }
19360}
19361
19362function renderRoot(root, isYieldy) {
19363 !!isWorking ? invariant(false, 'renderRoot was called recursively. This error is likely caused by a bug in React. Please file an issue.') : void 0;
19364
19365 flushPassiveEffects();
19366
19367 isWorking = true;
19368 var previousDispatcher = ReactCurrentDispatcher.current;
19369 ReactCurrentDispatcher.current = ContextOnlyDispatcher;
19370
19371 var expirationTime = root.nextExpirationTimeToWorkOn;
19372
19373 // Check if we're starting from a fresh stack, or if we're resuming from
19374 // previously yielded work.
19375 if (expirationTime !== nextRenderExpirationTime || root !== nextRoot || nextUnitOfWork === null) {
19376 // Reset the stack and start working from the root.
19377 resetStack();
19378 nextRoot = root;
19379 nextRenderExpirationTime = expirationTime;
19380 nextUnitOfWork = createWorkInProgress(nextRoot.current, null, nextRenderExpirationTime);
19381 root.pendingCommitExpirationTime = NoWork;
19382
19383 if (enableSchedulerTracing) {
19384 // Determine which interactions this batch of work currently includes,
19385 // So that we can accurately attribute time spent working on it,
19386 var interactions = new Set();
19387 root.pendingInteractionMap.forEach(function (scheduledInteractions, scheduledExpirationTime) {
19388 if (scheduledExpirationTime >= expirationTime) {
19389 scheduledInteractions.forEach(function (interaction) {
19390 return interactions.add(interaction);
19391 });
19392 }
19393 });
19394
19395 // Store the current set of interactions on the FiberRoot for a few reasons:
19396 // We can re-use it in hot functions like renderRoot() without having to recalculate it.
19397 // We will also use it in commitWork() to pass to any Profiler onRender() hooks.
19398 // This also provides DevTools with a way to access it when the onCommitRoot() hook is called.
19399 root.memoizedInteractions = interactions;
19400
19401 if (interactions.size > 0) {
19402 var subscriber = tracing.__subscriberRef.current;
19403 if (subscriber !== null) {
19404 var threadID = computeThreadID(expirationTime, root.interactionThreadID);
19405 try {
19406 subscriber.onWorkStarted(interactions, threadID);
19407 } catch (error) {
19408 // Work thrown by an interaction tracing subscriber should be rethrown,
19409 // But only once it's safe (to avoid leaving the scheduler in an invalid state).
19410 // Store the error for now and we'll re-throw in finishRendering().
19411 if (!hasUnhandledError) {
19412 hasUnhandledError = true;
19413 unhandledError = error;
19414 }
19415 }
19416 }
19417 }
19418 }
19419 }
19420
19421 var prevInteractions = null;
19422 if (enableSchedulerTracing) {
19423 // We're about to start new traced work.
19424 // Restore pending interactions so cascading work triggered during the render phase will be accounted for.
19425 prevInteractions = tracing.__interactionsRef.current;
19426 tracing.__interactionsRef.current = root.memoizedInteractions;
19427 }
19428
19429 var didFatal = false;
19430
19431 startWorkLoopTimer(nextUnitOfWork);
19432
19433 do {
19434 try {
19435 workLoop(isYieldy);
19436 } catch (thrownValue) {
19437 resetContextDependences();
19438 resetHooks();
19439
19440 // Reset in case completion throws.
19441 // This is only used in DEV and when replaying is on.
19442 var mayReplay = void 0;
19443 if (true && replayFailedUnitOfWorkWithInvokeGuardedCallback) {
19444 mayReplay = mayReplayFailedUnitOfWork;
19445 mayReplayFailedUnitOfWork = true;
19446 }
19447
19448 if (nextUnitOfWork === null) {
19449 // This is a fatal error.
19450 didFatal = true;
19451 onUncaughtError(thrownValue);
19452 } else {
19453 if (enableProfilerTimer && nextUnitOfWork.mode & ProfileMode) {
19454 // Record the time spent rendering before an error was thrown.
19455 // This avoids inaccurate Profiler durations in the case of a suspended render.
19456 stopProfilerTimerIfRunningAndRecordDelta(nextUnitOfWork, true);
19457 }
19458
19459 {
19460 // Reset global debug state
19461 // We assume this is defined in DEV
19462 resetCurrentlyProcessingQueue();
19463 }
19464
19465 if (true && replayFailedUnitOfWorkWithInvokeGuardedCallback) {
19466 if (mayReplay) {
19467 var failedUnitOfWork = nextUnitOfWork;
19468 replayUnitOfWork(failedUnitOfWork, thrownValue, isYieldy);
19469 }
19470 }
19471
19472 // TODO: we already know this isn't true in some cases.
19473 // At least this shows a nicer error message until we figure out the cause.
19474 // https://github.com/facebook/react/issues/12449#issuecomment-386727431
19475 !(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;
19476
19477 var sourceFiber = nextUnitOfWork;
19478 var returnFiber = sourceFiber.return;
19479 if (returnFiber === null) {
19480 // This is the root. The root could capture its own errors. However,
19481 // we don't know if it errors before or after we pushed the host
19482 // context. This information is needed to avoid a stack mismatch.
19483 // Because we're not sure, treat this as a fatal error. We could track
19484 // which phase it fails in, but doesn't seem worth it. At least
19485 // for now.
19486 didFatal = true;
19487 onUncaughtError(thrownValue);
19488 } else {
19489 throwException(root, returnFiber, sourceFiber, thrownValue, nextRenderExpirationTime);
19490 nextUnitOfWork = completeUnitOfWork(sourceFiber);
19491 continue;
19492 }
19493 }
19494 }
19495 break;
19496 } while (true);
19497
19498 if (enableSchedulerTracing) {
19499 // Traced work is done for now; restore the previous interactions.
19500 tracing.__interactionsRef.current = prevInteractions;
19501 }
19502
19503 // We're done performing work. Time to clean up.
19504 isWorking = false;
19505 ReactCurrentDispatcher.current = previousDispatcher;
19506 resetContextDependences();
19507 resetHooks();
19508
19509 // Yield back to main thread.
19510 if (didFatal) {
19511 var _didCompleteRoot = false;
19512 stopWorkLoopTimer(interruptedBy, _didCompleteRoot);
19513 interruptedBy = null;
19514 // There was a fatal error.
19515 {
19516 resetStackAfterFatalErrorInDev();
19517 }
19518 // `nextRoot` points to the in-progress root. A non-null value indicates
19519 // that we're in the middle of an async render. Set it to null to indicate
19520 // there's no more work to be done in the current batch.
19521 nextRoot = null;
19522 onFatal(root);
19523 return;
19524 }
19525
19526 if (nextUnitOfWork !== null) {
19527 // There's still remaining async work in this tree, but we ran out of time
19528 // in the current frame. Yield back to the renderer. Unless we're
19529 // interrupted by a higher priority update, we'll continue later from where
19530 // we left off.
19531 var _didCompleteRoot2 = false;
19532 stopWorkLoopTimer(interruptedBy, _didCompleteRoot2);
19533 interruptedBy = null;
19534 onYield(root);
19535 return;
19536 }
19537
19538 // We completed the whole tree.
19539 var didCompleteRoot = true;
19540 stopWorkLoopTimer(interruptedBy, didCompleteRoot);
19541 var rootWorkInProgress = root.current.alternate;
19542 !(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;
19543
19544 // `nextRoot` points to the in-progress root. A non-null value indicates
19545 // that we're in the middle of an async render. Set it to null to indicate
19546 // there's no more work to be done in the current batch.
19547 nextRoot = null;
19548 interruptedBy = null;
19549
19550 if (nextRenderDidError) {
19551 // There was an error
19552 if (hasLowerPriorityWork(root, expirationTime)) {
19553 // There's lower priority work. If so, it may have the effect of fixing
19554 // the exception that was just thrown. Exit without committing. This is
19555 // similar to a suspend, but without a timeout because we're not waiting
19556 // for a promise to resolve. React will restart at the lower
19557 // priority level.
19558 markSuspendedPriorityLevel(root, expirationTime);
19559 var suspendedExpirationTime = expirationTime;
19560 var rootExpirationTime = root.expirationTime;
19561 onSuspend(root, rootWorkInProgress, suspendedExpirationTime, rootExpirationTime, -1 // Indicates no timeout
19562 );
19563 return;
19564 } else if (
19565 // There's no lower priority work, but we're rendering asynchronously.
19566 // Synchronously attempt to render the same level one more time. This is
19567 // similar to a suspend, but without a timeout because we're not waiting
19568 // for a promise to resolve.
19569 !root.didError && isYieldy) {
19570 root.didError = true;
19571 var _suspendedExpirationTime = root.nextExpirationTimeToWorkOn = expirationTime;
19572 var _rootExpirationTime = root.expirationTime = Sync;
19573 onSuspend(root, rootWorkInProgress, _suspendedExpirationTime, _rootExpirationTime, -1 // Indicates no timeout
19574 );
19575 return;
19576 }
19577 }
19578
19579 if (isYieldy && nextLatestAbsoluteTimeoutMs !== -1) {
19580 // The tree was suspended.
19581 var _suspendedExpirationTime2 = expirationTime;
19582 markSuspendedPriorityLevel(root, _suspendedExpirationTime2);
19583
19584 // Find the earliest uncommitted expiration time in the tree, including
19585 // work that is suspended. The timeout threshold cannot be longer than
19586 // the overall expiration.
19587 var earliestExpirationTime = findEarliestOutstandingPriorityLevel(root, expirationTime);
19588 var earliestExpirationTimeMs = expirationTimeToMs(earliestExpirationTime);
19589 if (earliestExpirationTimeMs < nextLatestAbsoluteTimeoutMs) {
19590 nextLatestAbsoluteTimeoutMs = earliestExpirationTimeMs;
19591 }
19592
19593 // Subtract the current time from the absolute timeout to get the number
19594 // of milliseconds until the timeout. In other words, convert an absolute
19595 // timestamp to a relative time. This is the value that is passed
19596 // to `setTimeout`.
19597 var currentTimeMs = expirationTimeToMs(requestCurrentTime());
19598 var msUntilTimeout = nextLatestAbsoluteTimeoutMs - currentTimeMs;
19599 msUntilTimeout = msUntilTimeout < 0 ? 0 : msUntilTimeout;
19600
19601 // TODO: Account for the Just Noticeable Difference
19602
19603 var _rootExpirationTime2 = root.expirationTime;
19604 onSuspend(root, rootWorkInProgress, _suspendedExpirationTime2, _rootExpirationTime2, msUntilTimeout);
19605 return;
19606 }
19607
19608 // Ready to commit.
19609 onComplete(root, rootWorkInProgress, expirationTime);
19610}
19611
19612function captureCommitPhaseError(sourceFiber, value) {
19613 var expirationTime = Sync;
19614 var fiber = sourceFiber.return;
19615 while (fiber !== null) {
19616 switch (fiber.tag) {
19617 case ClassComponent:
19618 var ctor = fiber.type;
19619 var instance = fiber.stateNode;
19620 if (typeof ctor.getDerivedStateFromError === 'function' || typeof instance.componentDidCatch === 'function' && !isAlreadyFailedLegacyErrorBoundary(instance)) {
19621 var errorInfo = createCapturedValue(value, sourceFiber);
19622 var update = createClassErrorUpdate(fiber, errorInfo, expirationTime);
19623 enqueueUpdate(fiber, update);
19624 scheduleWork(fiber, expirationTime);
19625 return;
19626 }
19627 break;
19628 case HostRoot:
19629 {
19630 var _errorInfo = createCapturedValue(value, sourceFiber);
19631 var _update = createRootErrorUpdate(fiber, _errorInfo, expirationTime);
19632 enqueueUpdate(fiber, _update);
19633 scheduleWork(fiber, expirationTime);
19634 return;
19635 }
19636 }
19637 fiber = fiber.return;
19638 }
19639
19640 if (sourceFiber.tag === HostRoot) {
19641 // Error was thrown at the root. There is no parent, so the root
19642 // itself should capture it.
19643 var rootFiber = sourceFiber;
19644 var _errorInfo2 = createCapturedValue(value, rootFiber);
19645 var _update2 = createRootErrorUpdate(rootFiber, _errorInfo2, expirationTime);
19646 enqueueUpdate(rootFiber, _update2);
19647 scheduleWork(rootFiber, expirationTime);
19648 }
19649}
19650
19651function computeThreadID(expirationTime, interactionThreadID) {
19652 // Interaction threads are unique per root and expiration time.
19653 return expirationTime * 1000 + interactionThreadID;
19654}
19655
19656// Creates a unique async expiration time.
19657function computeUniqueAsyncExpiration() {
19658 var currentTime = requestCurrentTime();
19659 var result = computeAsyncExpiration(currentTime);
19660 if (result >= lastUniqueAsyncExpiration) {
19661 // Since we assume the current time monotonically increases, we only hit
19662 // this branch when computeUniqueAsyncExpiration is fired multiple times
19663 // within a 200ms window (or whatever the async bucket size is).
19664 result = lastUniqueAsyncExpiration - 1;
19665 }
19666 lastUniqueAsyncExpiration = result;
19667 return lastUniqueAsyncExpiration;
19668}
19669
19670function computeExpirationForFiber(currentTime, fiber) {
19671 var priorityLevel = scheduler.unstable_getCurrentPriorityLevel();
19672
19673 var expirationTime = void 0;
19674 if ((fiber.mode & ConcurrentMode) === NoContext) {
19675 // Outside of concurrent mode, updates are always synchronous.
19676 expirationTime = Sync;
19677 } else if (isWorking && !isCommitting$1) {
19678 // During render phase, updates expire during as the current render.
19679 expirationTime = nextRenderExpirationTime;
19680 } else {
19681 switch (priorityLevel) {
19682 case scheduler.unstable_ImmediatePriority:
19683 expirationTime = Sync;
19684 break;
19685 case scheduler.unstable_UserBlockingPriority:
19686 expirationTime = computeInteractiveExpiration(currentTime);
19687 break;
19688 case scheduler.unstable_NormalPriority:
19689 // This is a normal, concurrent update
19690 expirationTime = computeAsyncExpiration(currentTime);
19691 break;
19692 case scheduler.unstable_LowPriority:
19693 case scheduler.unstable_IdlePriority:
19694 expirationTime = Never;
19695 break;
19696 default:
19697 invariant(false, 'Unknown priority level. This error is likely caused by a bug in React. Please file an issue.');
19698 }
19699
19700 // If we're in the middle of rendering a tree, do not update at the same
19701 // expiration time that is already rendering.
19702 if (nextRoot !== null && expirationTime === nextRenderExpirationTime) {
19703 expirationTime -= 1;
19704 }
19705 }
19706
19707 // Keep track of the lowest pending interactive expiration time. This
19708 // allows us to synchronously flush all interactive updates
19709 // when needed.
19710 // TODO: Move this to renderer?
19711 if (priorityLevel === scheduler.unstable_UserBlockingPriority && (lowestPriorityPendingInteractiveExpirationTime === NoWork || expirationTime < lowestPriorityPendingInteractiveExpirationTime)) {
19712 lowestPriorityPendingInteractiveExpirationTime = expirationTime;
19713 }
19714
19715 return expirationTime;
19716}
19717
19718function renderDidSuspend(root, absoluteTimeoutMs, suspendedTime) {
19719 // Schedule the timeout.
19720 if (absoluteTimeoutMs >= 0 && nextLatestAbsoluteTimeoutMs < absoluteTimeoutMs) {
19721 nextLatestAbsoluteTimeoutMs = absoluteTimeoutMs;
19722 }
19723}
19724
19725function renderDidError() {
19726 nextRenderDidError = true;
19727}
19728
19729function pingSuspendedRoot(root, thenable, pingTime) {
19730 // A promise that previously suspended React from committing has resolved.
19731 // If React is still suspended, try again at the previous level (pingTime).
19732
19733 var pingCache = root.pingCache;
19734 if (pingCache !== null) {
19735 // The thenable resolved, so we no longer need to memoize, because it will
19736 // never be thrown again.
19737 pingCache.delete(thenable);
19738 }
19739
19740 if (nextRoot !== null && nextRenderExpirationTime === pingTime) {
19741 // Received a ping at the same priority level at which we're currently
19742 // rendering. Restart from the root.
19743 nextRoot = null;
19744 } else {
19745 // Confirm that the root is still suspended at this level. Otherwise exit.
19746 if (isPriorityLevelSuspended(root, pingTime)) {
19747 // Ping at the original level
19748 markPingedPriorityLevel(root, pingTime);
19749 var rootExpirationTime = root.expirationTime;
19750 if (rootExpirationTime !== NoWork) {
19751 requestWork(root, rootExpirationTime);
19752 }
19753 }
19754 }
19755}
19756
19757function retryTimedOutBoundary(boundaryFiber, thenable) {
19758 // The boundary fiber (a Suspense component) previously timed out and was
19759 // rendered in its fallback state. One of the promises that suspended it has
19760 // resolved, which means at least part of the tree was likely unblocked. Try
19761 var retryCache = void 0;
19762 if (enableSuspenseServerRenderer) {
19763 switch (boundaryFiber.tag) {
19764 case SuspenseComponent:
19765 retryCache = boundaryFiber.stateNode;
19766 break;
19767 case DehydratedSuspenseComponent:
19768 retryCache = boundaryFiber.memoizedState;
19769 break;
19770 default:
19771 invariant(false, 'Pinged unknown suspense boundary type. This is probably a bug in React.');
19772 }
19773 } else {
19774 retryCache = boundaryFiber.stateNode;
19775 }
19776 if (retryCache !== null) {
19777 // The thenable resolved, so we no longer need to memoize, because it will
19778 // never be thrown again.
19779 retryCache.delete(thenable);
19780 }
19781
19782 var currentTime = requestCurrentTime();
19783 var retryTime = computeExpirationForFiber(currentTime, boundaryFiber);
19784 var root = scheduleWorkToRoot(boundaryFiber, retryTime);
19785 if (root !== null) {
19786 markPendingPriorityLevel(root, retryTime);
19787 var rootExpirationTime = root.expirationTime;
19788 if (rootExpirationTime !== NoWork) {
19789 requestWork(root, rootExpirationTime);
19790 }
19791 }
19792}
19793
19794function scheduleWorkToRoot(fiber, expirationTime) {
19795 recordScheduleUpdate();
19796
19797 {
19798 if (fiber.tag === ClassComponent) {
19799 var instance = fiber.stateNode;
19800 warnAboutInvalidUpdates(instance);
19801 }
19802 }
19803
19804 // Update the source fiber's expiration time
19805 if (fiber.expirationTime < expirationTime) {
19806 fiber.expirationTime = expirationTime;
19807 }
19808 var alternate = fiber.alternate;
19809 if (alternate !== null && alternate.expirationTime < expirationTime) {
19810 alternate.expirationTime = expirationTime;
19811 }
19812 // Walk the parent path to the root and update the child expiration time.
19813 var node = fiber.return;
19814 var root = null;
19815 if (node === null && fiber.tag === HostRoot) {
19816 root = fiber.stateNode;
19817 } else {
19818 while (node !== null) {
19819 alternate = node.alternate;
19820 if (node.childExpirationTime < expirationTime) {
19821 node.childExpirationTime = expirationTime;
19822 if (alternate !== null && alternate.childExpirationTime < expirationTime) {
19823 alternate.childExpirationTime = expirationTime;
19824 }
19825 } else if (alternate !== null && alternate.childExpirationTime < expirationTime) {
19826 alternate.childExpirationTime = expirationTime;
19827 }
19828 if (node.return === null && node.tag === HostRoot) {
19829 root = node.stateNode;
19830 break;
19831 }
19832 node = node.return;
19833 }
19834 }
19835
19836 if (enableSchedulerTracing) {
19837 if (root !== null) {
19838 var interactions = tracing.__interactionsRef.current;
19839 if (interactions.size > 0) {
19840 var pendingInteractionMap = root.pendingInteractionMap;
19841 var pendingInteractions = pendingInteractionMap.get(expirationTime);
19842 if (pendingInteractions != null) {
19843 interactions.forEach(function (interaction) {
19844 if (!pendingInteractions.has(interaction)) {
19845 // Update the pending async work count for previously unscheduled interaction.
19846 interaction.__count++;
19847 }
19848
19849 pendingInteractions.add(interaction);
19850 });
19851 } else {
19852 pendingInteractionMap.set(expirationTime, new Set(interactions));
19853
19854 // Update the pending async work count for the current interactions.
19855 interactions.forEach(function (interaction) {
19856 interaction.__count++;
19857 });
19858 }
19859
19860 var subscriber = tracing.__subscriberRef.current;
19861 if (subscriber !== null) {
19862 var threadID = computeThreadID(expirationTime, root.interactionThreadID);
19863 subscriber.onWorkScheduled(interactions, threadID);
19864 }
19865 }
19866 }
19867 }
19868 return root;
19869}
19870
19871function warnIfNotCurrentlyBatchingInDev(fiber) {
19872 {
19873 if (isRendering === false && isBatchingUpdates === false) {
19874 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));
19875 }
19876 }
19877}
19878
19879function scheduleWork(fiber, expirationTime) {
19880 var root = scheduleWorkToRoot(fiber, expirationTime);
19881 if (root === null) {
19882 {
19883 switch (fiber.tag) {
19884 case ClassComponent:
19885 warnAboutUpdateOnUnmounted(fiber, true);
19886 break;
19887 case FunctionComponent:
19888 case ForwardRef:
19889 case MemoComponent:
19890 case SimpleMemoComponent:
19891 warnAboutUpdateOnUnmounted(fiber, false);
19892 break;
19893 }
19894 }
19895 return;
19896 }
19897
19898 if (!isWorking && nextRenderExpirationTime !== NoWork && expirationTime > nextRenderExpirationTime) {
19899 // This is an interruption. (Used for performance tracking.)
19900 interruptedBy = fiber;
19901 resetStack();
19902 }
19903 markPendingPriorityLevel(root, expirationTime);
19904 if (
19905 // If we're in the render phase, we don't need to schedule this root
19906 // for an update, because we'll do it before we exit...
19907 !isWorking || isCommitting$1 ||
19908 // ...unless this is a different root than the one we're rendering.
19909 nextRoot !== root) {
19910 var rootExpirationTime = root.expirationTime;
19911 requestWork(root, rootExpirationTime);
19912 }
19913 if (nestedUpdateCount > NESTED_UPDATE_LIMIT) {
19914 // Reset this back to zero so subsequent updates don't throw.
19915 nestedUpdateCount = 0;
19916 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.');
19917 }
19918}
19919
19920function syncUpdates(fn, a, b, c, d) {
19921 return scheduler.unstable_runWithPriority(scheduler.unstable_ImmediatePriority, function () {
19922 return fn(a, b, c, d);
19923 });
19924}
19925
19926// TODO: Everything below this is written as if it has been lifted to the
19927// renderers. I'll do this in a follow-up.
19928
19929// Linked-list of roots
19930var firstScheduledRoot = null;
19931var lastScheduledRoot = null;
19932
19933var callbackExpirationTime = NoWork;
19934var callbackID = void 0;
19935var isRendering = false;
19936var nextFlushedRoot = null;
19937var nextFlushedExpirationTime = NoWork;
19938var lowestPriorityPendingInteractiveExpirationTime = NoWork;
19939var hasUnhandledError = false;
19940var unhandledError = null;
19941
19942var isBatchingUpdates = false;
19943var isUnbatchingUpdates = false;
19944
19945var completedBatches = null;
19946
19947var originalStartTimeMs = scheduler.unstable_now();
19948var currentRendererTime = msToExpirationTime(originalStartTimeMs);
19949var currentSchedulerTime = currentRendererTime;
19950
19951// Use these to prevent an infinite loop of nested updates
19952var NESTED_UPDATE_LIMIT = 50;
19953var nestedUpdateCount = 0;
19954var lastCommittedRootDuringThisBatch = null;
19955
19956function recomputeCurrentRendererTime() {
19957 var currentTimeMs = scheduler.unstable_now() - originalStartTimeMs;
19958 currentRendererTime = msToExpirationTime(currentTimeMs);
19959}
19960
19961function scheduleCallbackWithExpirationTime(root, expirationTime) {
19962 if (callbackExpirationTime !== NoWork) {
19963 // A callback is already scheduled. Check its expiration time (timeout).
19964 if (expirationTime < callbackExpirationTime) {
19965 // Existing callback has sufficient timeout. Exit.
19966 return;
19967 } else {
19968 if (callbackID !== null) {
19969 // Existing callback has insufficient timeout. Cancel and schedule a
19970 // new one.
19971 scheduler.unstable_cancelCallback(callbackID);
19972 }
19973 }
19974 // The request callback timer is already running. Don't start a new one.
19975 } else {
19976 startRequestCallbackTimer();
19977 }
19978
19979 callbackExpirationTime = expirationTime;
19980 var currentMs = scheduler.unstable_now() - originalStartTimeMs;
19981 var expirationTimeMs = expirationTimeToMs(expirationTime);
19982 var timeout = expirationTimeMs - currentMs;
19983 callbackID = scheduler.unstable_scheduleCallback(performAsyncWork, { timeout: timeout });
19984}
19985
19986// For every call to renderRoot, one of onFatal, onComplete, onSuspend, and
19987// onYield is called upon exiting. We use these in lieu of returning a tuple.
19988// I've also chosen not to inline them into renderRoot because these will
19989// eventually be lifted into the renderer.
19990function onFatal(root) {
19991 root.finishedWork = null;
19992}
19993
19994function onComplete(root, finishedWork, expirationTime) {
19995 root.pendingCommitExpirationTime = expirationTime;
19996 root.finishedWork = finishedWork;
19997}
19998
19999function onSuspend(root, finishedWork, suspendedExpirationTime, rootExpirationTime, msUntilTimeout) {
20000 root.expirationTime = rootExpirationTime;
20001 if (msUntilTimeout === 0 && !shouldYieldToRenderer()) {
20002 // Don't wait an additional tick. Commit the tree immediately.
20003 root.pendingCommitExpirationTime = suspendedExpirationTime;
20004 root.finishedWork = finishedWork;
20005 } else if (msUntilTimeout > 0) {
20006 // Wait `msUntilTimeout` milliseconds before committing.
20007 root.timeoutHandle = scheduleTimeout(onTimeout.bind(null, root, finishedWork, suspendedExpirationTime), msUntilTimeout);
20008 }
20009}
20010
20011function onYield(root) {
20012 root.finishedWork = null;
20013}
20014
20015function onTimeout(root, finishedWork, suspendedExpirationTime) {
20016 // The root timed out. Commit it.
20017 root.pendingCommitExpirationTime = suspendedExpirationTime;
20018 root.finishedWork = finishedWork;
20019 // Read the current time before entering the commit phase. We can be
20020 // certain this won't cause tearing related to batching of event updates
20021 // because we're at the top of a timer event.
20022 recomputeCurrentRendererTime();
20023 currentSchedulerTime = currentRendererTime;
20024 flushRoot(root, suspendedExpirationTime);
20025}
20026
20027function onCommit(root, expirationTime) {
20028 root.expirationTime = expirationTime;
20029 root.finishedWork = null;
20030}
20031
20032function requestCurrentTime() {
20033 // requestCurrentTime is called by the scheduler to compute an expiration
20034 // time.
20035 //
20036 // Expiration times are computed by adding to the current time (the start
20037 // time). However, if two updates are scheduled within the same event, we
20038 // should treat their start times as simultaneous, even if the actual clock
20039 // time has advanced between the first and second call.
20040
20041 // In other words, because expiration times determine how updates are batched,
20042 // we want all updates of like priority that occur within the same event to
20043 // receive the same expiration time. Otherwise we get tearing.
20044 //
20045 // We keep track of two separate times: the current "renderer" time and the
20046 // current "scheduler" time. The renderer time can be updated whenever; it
20047 // only exists to minimize the calls performance.now.
20048 //
20049 // But the scheduler time can only be updated if there's no pending work, or
20050 // if we know for certain that we're not in the middle of an event.
20051
20052 if (isRendering) {
20053 // We're already rendering. Return the most recently read time.
20054 return currentSchedulerTime;
20055 }
20056 // Check if there's pending work.
20057 findHighestPriorityRoot();
20058 if (nextFlushedExpirationTime === NoWork || nextFlushedExpirationTime === Never) {
20059 // If there's no pending work, or if the pending work is offscreen, we can
20060 // read the current time without risk of tearing.
20061 recomputeCurrentRendererTime();
20062 currentSchedulerTime = currentRendererTime;
20063 return currentSchedulerTime;
20064 }
20065 // There's already pending work. We might be in the middle of a browser
20066 // event. If we were to read the current time, it could cause multiple updates
20067 // within the same event to receive different expiration times, leading to
20068 // tearing. Return the last read time. During the next idle callback, the
20069 // time will be updated.
20070 return currentSchedulerTime;
20071}
20072
20073// requestWork is called by the scheduler whenever a root receives an update.
20074// It's up to the renderer to call renderRoot at some point in the future.
20075function requestWork(root, expirationTime) {
20076 addRootToSchedule(root, expirationTime);
20077 if (isRendering) {
20078 // Prevent reentrancy. Remaining work will be scheduled at the end of
20079 // the currently rendering batch.
20080 return;
20081 }
20082
20083 if (isBatchingUpdates) {
20084 // Flush work at the end of the batch.
20085 if (isUnbatchingUpdates) {
20086 // ...unless we're inside unbatchedUpdates, in which case we should
20087 // flush it now.
20088 nextFlushedRoot = root;
20089 nextFlushedExpirationTime = Sync;
20090 performWorkOnRoot(root, Sync, false);
20091 }
20092 return;
20093 }
20094
20095 // TODO: Get rid of Sync and use current time?
20096 if (expirationTime === Sync) {
20097 performSyncWork();
20098 } else {
20099 scheduleCallbackWithExpirationTime(root, expirationTime);
20100 }
20101}
20102
20103function addRootToSchedule(root, expirationTime) {
20104 // Add the root to the schedule.
20105 // Check if this root is already part of the schedule.
20106 if (root.nextScheduledRoot === null) {
20107 // This root is not already scheduled. Add it.
20108 root.expirationTime = expirationTime;
20109 if (lastScheduledRoot === null) {
20110 firstScheduledRoot = lastScheduledRoot = root;
20111 root.nextScheduledRoot = root;
20112 } else {
20113 lastScheduledRoot.nextScheduledRoot = root;
20114 lastScheduledRoot = root;
20115 lastScheduledRoot.nextScheduledRoot = firstScheduledRoot;
20116 }
20117 } else {
20118 // This root is already scheduled, but its priority may have increased.
20119 var remainingExpirationTime = root.expirationTime;
20120 if (expirationTime > remainingExpirationTime) {
20121 // Update the priority.
20122 root.expirationTime = expirationTime;
20123 }
20124 }
20125}
20126
20127function findHighestPriorityRoot() {
20128 var highestPriorityWork = NoWork;
20129 var highestPriorityRoot = null;
20130 if (lastScheduledRoot !== null) {
20131 var previousScheduledRoot = lastScheduledRoot;
20132 var root = firstScheduledRoot;
20133 while (root !== null) {
20134 var remainingExpirationTime = root.expirationTime;
20135 if (remainingExpirationTime === NoWork) {
20136 // This root no longer has work. Remove it from the scheduler.
20137
20138 // TODO: This check is redudant, but Flow is confused by the branch
20139 // below where we set lastScheduledRoot to null, even though we break
20140 // from the loop right after.
20141 !(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;
20142 if (root === root.nextScheduledRoot) {
20143 // This is the only root in the list.
20144 root.nextScheduledRoot = null;
20145 firstScheduledRoot = lastScheduledRoot = null;
20146 break;
20147 } else if (root === firstScheduledRoot) {
20148 // This is the first root in the list.
20149 var next = root.nextScheduledRoot;
20150 firstScheduledRoot = next;
20151 lastScheduledRoot.nextScheduledRoot = next;
20152 root.nextScheduledRoot = null;
20153 } else if (root === lastScheduledRoot) {
20154 // This is the last root in the list.
20155 lastScheduledRoot = previousScheduledRoot;
20156 lastScheduledRoot.nextScheduledRoot = firstScheduledRoot;
20157 root.nextScheduledRoot = null;
20158 break;
20159 } else {
20160 previousScheduledRoot.nextScheduledRoot = root.nextScheduledRoot;
20161 root.nextScheduledRoot = null;
20162 }
20163 root = previousScheduledRoot.nextScheduledRoot;
20164 } else {
20165 if (remainingExpirationTime > highestPriorityWork) {
20166 // Update the priority, if it's higher
20167 highestPriorityWork = remainingExpirationTime;
20168 highestPriorityRoot = root;
20169 }
20170 if (root === lastScheduledRoot) {
20171 break;
20172 }
20173 if (highestPriorityWork === Sync) {
20174 // Sync is highest priority by definition so
20175 // we can stop searching.
20176 break;
20177 }
20178 previousScheduledRoot = root;
20179 root = root.nextScheduledRoot;
20180 }
20181 }
20182 }
20183
20184 nextFlushedRoot = highestPriorityRoot;
20185 nextFlushedExpirationTime = highestPriorityWork;
20186}
20187
20188// TODO: This wrapper exists because many of the older tests (the ones that use
20189// flushDeferredPri) rely on the number of times `shouldYield` is called. We
20190// should get rid of it.
20191var didYield = false;
20192function shouldYieldToRenderer() {
20193 if (didYield) {
20194 return true;
20195 }
20196 if (scheduler.unstable_shouldYield()) {
20197 didYield = true;
20198 return true;
20199 }
20200 return false;
20201}
20202
20203function performAsyncWork() {
20204 try {
20205 if (!shouldYieldToRenderer()) {
20206 // The callback timed out. That means at least one update has expired.
20207 // Iterate through the root schedule. If they contain expired work, set
20208 // the next render expiration time to the current time. This has the effect
20209 // of flushing all expired work in a single batch, instead of flushing each
20210 // level one at a time.
20211 if (firstScheduledRoot !== null) {
20212 recomputeCurrentRendererTime();
20213 var root = firstScheduledRoot;
20214 do {
20215 didExpireAtExpirationTime(root, currentRendererTime);
20216 // The root schedule is circular, so this is never null.
20217 root = root.nextScheduledRoot;
20218 } while (root !== firstScheduledRoot);
20219 }
20220 }
20221 performWork(NoWork, true);
20222 } finally {
20223 didYield = false;
20224 }
20225}
20226
20227function performSyncWork() {
20228 performWork(Sync, false);
20229}
20230
20231function performWork(minExpirationTime, isYieldy) {
20232 // Keep working on roots until there's no more work, or until there's a higher
20233 // priority event.
20234 findHighestPriorityRoot();
20235
20236 if (isYieldy) {
20237 recomputeCurrentRendererTime();
20238 currentSchedulerTime = currentRendererTime;
20239
20240 if (enableUserTimingAPI) {
20241 var didExpire = nextFlushedExpirationTime > currentRendererTime;
20242 var timeout = expirationTimeToMs(nextFlushedExpirationTime);
20243 stopRequestCallbackTimer(didExpire, timeout);
20244 }
20245
20246 while (nextFlushedRoot !== null && nextFlushedExpirationTime !== NoWork && minExpirationTime <= nextFlushedExpirationTime && !(didYield && currentRendererTime > nextFlushedExpirationTime)) {
20247 performWorkOnRoot(nextFlushedRoot, nextFlushedExpirationTime, currentRendererTime > nextFlushedExpirationTime);
20248 findHighestPriorityRoot();
20249 recomputeCurrentRendererTime();
20250 currentSchedulerTime = currentRendererTime;
20251 }
20252 } else {
20253 while (nextFlushedRoot !== null && nextFlushedExpirationTime !== NoWork && minExpirationTime <= nextFlushedExpirationTime) {
20254 performWorkOnRoot(nextFlushedRoot, nextFlushedExpirationTime, false);
20255 findHighestPriorityRoot();
20256 }
20257 }
20258
20259 // We're done flushing work. Either we ran out of time in this callback,
20260 // or there's no more work left with sufficient priority.
20261
20262 // If we're inside a callback, set this to false since we just completed it.
20263 if (isYieldy) {
20264 callbackExpirationTime = NoWork;
20265 callbackID = null;
20266 }
20267 // If there's work left over, schedule a new callback.
20268 if (nextFlushedExpirationTime !== NoWork) {
20269 scheduleCallbackWithExpirationTime(nextFlushedRoot, nextFlushedExpirationTime);
20270 }
20271
20272 // Clean-up.
20273 finishRendering();
20274}
20275
20276function flushRoot(root, expirationTime) {
20277 !!isRendering ? invariant(false, 'work.commit(): Cannot commit while already rendering. This likely means you attempted to commit from inside a lifecycle method.') : void 0;
20278 // Perform work on root as if the given expiration time is the current time.
20279 // This has the effect of synchronously flushing all work up to and
20280 // including the given time.
20281 nextFlushedRoot = root;
20282 nextFlushedExpirationTime = expirationTime;
20283 performWorkOnRoot(root, expirationTime, false);
20284 // Flush any sync work that was scheduled by lifecycles
20285 performSyncWork();
20286}
20287
20288function finishRendering() {
20289 nestedUpdateCount = 0;
20290 lastCommittedRootDuringThisBatch = null;
20291
20292 if (completedBatches !== null) {
20293 var batches = completedBatches;
20294 completedBatches = null;
20295 for (var i = 0; i < batches.length; i++) {
20296 var batch = batches[i];
20297 try {
20298 batch._onComplete();
20299 } catch (error) {
20300 if (!hasUnhandledError) {
20301 hasUnhandledError = true;
20302 unhandledError = error;
20303 }
20304 }
20305 }
20306 }
20307
20308 if (hasUnhandledError) {
20309 var error = unhandledError;
20310 unhandledError = null;
20311 hasUnhandledError = false;
20312 throw error;
20313 }
20314}
20315
20316function performWorkOnRoot(root, expirationTime, isYieldy) {
20317 !!isRendering ? invariant(false, 'performWorkOnRoot was called recursively. This error is likely caused by a bug in React. Please file an issue.') : void 0;
20318
20319 isRendering = true;
20320
20321 // Check if this is async work or sync/expired work.
20322 if (!isYieldy) {
20323 // Flush work without yielding.
20324 // TODO: Non-yieldy work does not necessarily imply expired work. A renderer
20325 // may want to perform some work without yielding, but also without
20326 // requiring the root to complete (by triggering placeholders).
20327
20328 var finishedWork = root.finishedWork;
20329 if (finishedWork !== null) {
20330 // This root is already complete. We can commit it.
20331 completeRoot(root, finishedWork, expirationTime);
20332 } else {
20333 root.finishedWork = null;
20334 // If this root previously suspended, clear its existing timeout, since
20335 // we're about to try rendering again.
20336 var timeoutHandle = root.timeoutHandle;
20337 if (timeoutHandle !== noTimeout) {
20338 root.timeoutHandle = noTimeout;
20339 // $FlowFixMe Complains noTimeout is not a TimeoutID, despite the check above
20340 cancelTimeout(timeoutHandle);
20341 }
20342 renderRoot(root, isYieldy);
20343 finishedWork = root.finishedWork;
20344 if (finishedWork !== null) {
20345 // We've completed the root. Commit it.
20346 completeRoot(root, finishedWork, expirationTime);
20347 }
20348 }
20349 } else {
20350 // Flush async work.
20351 var _finishedWork = root.finishedWork;
20352 if (_finishedWork !== null) {
20353 // This root is already complete. We can commit it.
20354 completeRoot(root, _finishedWork, expirationTime);
20355 } else {
20356 root.finishedWork = null;
20357 // If this root previously suspended, clear its existing timeout, since
20358 // we're about to try rendering again.
20359 var _timeoutHandle = root.timeoutHandle;
20360 if (_timeoutHandle !== noTimeout) {
20361 root.timeoutHandle = noTimeout;
20362 // $FlowFixMe Complains noTimeout is not a TimeoutID, despite the check above
20363 cancelTimeout(_timeoutHandle);
20364 }
20365 renderRoot(root, isYieldy);
20366 _finishedWork = root.finishedWork;
20367 if (_finishedWork !== null) {
20368 // We've completed the root. Check the if we should yield one more time
20369 // before committing.
20370 if (!shouldYieldToRenderer()) {
20371 // Still time left. Commit the root.
20372 completeRoot(root, _finishedWork, expirationTime);
20373 } else {
20374 // There's no time left. Mark this root as complete. We'll come
20375 // back and commit it later.
20376 root.finishedWork = _finishedWork;
20377 }
20378 }
20379 }
20380 }
20381
20382 isRendering = false;
20383}
20384
20385function completeRoot(root, finishedWork, expirationTime) {
20386 // Check if there's a batch that matches this expiration time.
20387 var firstBatch = root.firstBatch;
20388 if (firstBatch !== null && firstBatch._expirationTime >= expirationTime) {
20389 if (completedBatches === null) {
20390 completedBatches = [firstBatch];
20391 } else {
20392 completedBatches.push(firstBatch);
20393 }
20394 if (firstBatch._defer) {
20395 // This root is blocked from committing by a batch. Unschedule it until
20396 // we receive another update.
20397 root.finishedWork = finishedWork;
20398 root.expirationTime = NoWork;
20399 return;
20400 }
20401 }
20402
20403 // Commit the root.
20404 root.finishedWork = null;
20405
20406 // Check if this is a nested update (a sync update scheduled during the
20407 // commit phase).
20408 if (root === lastCommittedRootDuringThisBatch) {
20409 // If the next root is the same as the previous root, this is a nested
20410 // update. To prevent an infinite loop, increment the nested update count.
20411 nestedUpdateCount++;
20412 } else {
20413 // Reset whenever we switch roots.
20414 lastCommittedRootDuringThisBatch = root;
20415 nestedUpdateCount = 0;
20416 }
20417 scheduler.unstable_runWithPriority(scheduler.unstable_ImmediatePriority, function () {
20418 commitRoot(root, finishedWork);
20419 });
20420}
20421
20422function onUncaughtError(error) {
20423 !(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;
20424 // Unschedule this root so we don't work on it again until there's
20425 // another update.
20426 nextFlushedRoot.expirationTime = NoWork;
20427 if (!hasUnhandledError) {
20428 hasUnhandledError = true;
20429 unhandledError = error;
20430 }
20431}
20432
20433// TODO: Batching should be implemented at the renderer level, not inside
20434// the reconciler.
20435function batchedUpdates$1(fn, a) {
20436 var previousIsBatchingUpdates = isBatchingUpdates;
20437 isBatchingUpdates = true;
20438 try {
20439 return fn(a);
20440 } finally {
20441 isBatchingUpdates = previousIsBatchingUpdates;
20442 if (!isBatchingUpdates && !isRendering) {
20443 performSyncWork();
20444 }
20445 }
20446}
20447
20448// TODO: Batching should be implemented at the renderer level, not inside
20449// the reconciler.
20450function unbatchedUpdates(fn, a) {
20451 if (isBatchingUpdates && !isUnbatchingUpdates) {
20452 isUnbatchingUpdates = true;
20453 try {
20454 return fn(a);
20455 } finally {
20456 isUnbatchingUpdates = false;
20457 }
20458 }
20459 return fn(a);
20460}
20461
20462// TODO: Batching should be implemented at the renderer level, not within
20463// the reconciler.
20464function flushSync(fn, a) {
20465 !!isRendering ? invariant(false, 'flushSync was called from inside a lifecycle method. It cannot be called when React is already rendering.') : void 0;
20466 var previousIsBatchingUpdates = isBatchingUpdates;
20467 isBatchingUpdates = true;
20468 try {
20469 return syncUpdates(fn, a);
20470 } finally {
20471 isBatchingUpdates = previousIsBatchingUpdates;
20472 performSyncWork();
20473 }
20474}
20475
20476function interactiveUpdates$1(fn, a, b) {
20477 // If there are any pending interactive updates, synchronously flush them.
20478 // This needs to happen before we read any handlers, because the effect of
20479 // the previous event may influence which handlers are called during
20480 // this event.
20481 if (!isBatchingUpdates && !isRendering && lowestPriorityPendingInteractiveExpirationTime !== NoWork) {
20482 // Synchronously flush pending interactive updates.
20483 performWork(lowestPriorityPendingInteractiveExpirationTime, false);
20484 lowestPriorityPendingInteractiveExpirationTime = NoWork;
20485 }
20486 var previousIsBatchingUpdates = isBatchingUpdates;
20487 isBatchingUpdates = true;
20488 try {
20489 return scheduler.unstable_runWithPriority(scheduler.unstable_UserBlockingPriority, function () {
20490 return fn(a, b);
20491 });
20492 } finally {
20493 isBatchingUpdates = previousIsBatchingUpdates;
20494 if (!isBatchingUpdates && !isRendering) {
20495 performSyncWork();
20496 }
20497 }
20498}
20499
20500function flushInteractiveUpdates$1() {
20501 if (!isRendering && lowestPriorityPendingInteractiveExpirationTime !== NoWork) {
20502 // Synchronously flush pending interactive updates.
20503 performWork(lowestPriorityPendingInteractiveExpirationTime, false);
20504 lowestPriorityPendingInteractiveExpirationTime = NoWork;
20505 }
20506}
20507
20508function flushControlled(fn) {
20509 var previousIsBatchingUpdates = isBatchingUpdates;
20510 isBatchingUpdates = true;
20511 try {
20512 syncUpdates(fn);
20513 } finally {
20514 isBatchingUpdates = previousIsBatchingUpdates;
20515 if (!isBatchingUpdates && !isRendering) {
20516 performSyncWork();
20517 }
20518 }
20519}
20520
20521// 0 is PROD, 1 is DEV.
20522// Might add PROFILE later.
20523
20524
20525var didWarnAboutNestedUpdates = void 0;
20526var didWarnAboutFindNodeInStrictMode = void 0;
20527
20528{
20529 didWarnAboutNestedUpdates = false;
20530 didWarnAboutFindNodeInStrictMode = {};
20531}
20532
20533function getContextForSubtree(parentComponent) {
20534 if (!parentComponent) {
20535 return emptyContextObject;
20536 }
20537
20538 var fiber = get(parentComponent);
20539 var parentContext = findCurrentUnmaskedContext(fiber);
20540
20541 if (fiber.tag === ClassComponent) {
20542 var Component = fiber.type;
20543 if (isContextProvider(Component)) {
20544 return processChildContext(fiber, Component, parentContext);
20545 }
20546 }
20547
20548 return parentContext;
20549}
20550
20551function scheduleRootUpdate(current$$1, element, expirationTime, callback) {
20552 {
20553 if (phase === 'render' && current !== null && !didWarnAboutNestedUpdates) {
20554 didWarnAboutNestedUpdates = true;
20555 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');
20556 }
20557 }
20558
20559 var update = createUpdate(expirationTime);
20560 // Caution: React DevTools currently depends on this property
20561 // being called "element".
20562 update.payload = { element: element };
20563
20564 callback = callback === undefined ? null : callback;
20565 if (callback !== null) {
20566 !(typeof callback === 'function') ? warningWithoutStack$1(false, 'render(...): Expected the last optional `callback` argument to be a ' + 'function. Instead received: %s.', callback) : void 0;
20567 update.callback = callback;
20568 }
20569
20570 flushPassiveEffects();
20571 enqueueUpdate(current$$1, update);
20572 scheduleWork(current$$1, expirationTime);
20573
20574 return expirationTime;
20575}
20576
20577function updateContainerAtExpirationTime(element, container, parentComponent, expirationTime, callback) {
20578 // TODO: If this is a nested container, this won't be the root.
20579 var current$$1 = container.current;
20580
20581 {
20582 if (ReactFiberInstrumentation_1.debugTool) {
20583 if (current$$1.alternate === null) {
20584 ReactFiberInstrumentation_1.debugTool.onMountContainer(container);
20585 } else if (element === null) {
20586 ReactFiberInstrumentation_1.debugTool.onUnmountContainer(container);
20587 } else {
20588 ReactFiberInstrumentation_1.debugTool.onUpdateContainer(container);
20589 }
20590 }
20591 }
20592
20593 var context = getContextForSubtree(parentComponent);
20594 if (container.context === null) {
20595 container.context = context;
20596 } else {
20597 container.pendingContext = context;
20598 }
20599
20600 return scheduleRootUpdate(current$$1, element, expirationTime, callback);
20601}
20602
20603function findHostInstance(component) {
20604 var fiber = get(component);
20605 if (fiber === undefined) {
20606 if (typeof component.render === 'function') {
20607 invariant(false, 'Unable to find node on an unmounted component.');
20608 } else {
20609 invariant(false, 'Argument appears to not be a ReactComponent. Keys: %s', Object.keys(component));
20610 }
20611 }
20612 var hostFiber = findCurrentHostFiber(fiber);
20613 if (hostFiber === null) {
20614 return null;
20615 }
20616 return hostFiber.stateNode;
20617}
20618
20619function findHostInstanceWithWarning(component, methodName) {
20620 {
20621 var fiber = get(component);
20622 if (fiber === undefined) {
20623 if (typeof component.render === 'function') {
20624 invariant(false, 'Unable to find node on an unmounted component.');
20625 } else {
20626 invariant(false, 'Argument appears to not be a ReactComponent. Keys: %s', Object.keys(component));
20627 }
20628 }
20629 var hostFiber = findCurrentHostFiber(fiber);
20630 if (hostFiber === null) {
20631 return null;
20632 }
20633 if (hostFiber.mode & StrictMode) {
20634 var componentName = getComponentName(fiber.type) || 'Component';
20635 if (!didWarnAboutFindNodeInStrictMode[componentName]) {
20636 didWarnAboutFindNodeInStrictMode[componentName] = true;
20637 if (fiber.mode & StrictMode) {
20638 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));
20639 } else {
20640 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));
20641 }
20642 }
20643 }
20644 return hostFiber.stateNode;
20645 }
20646 return findHostInstance(component);
20647}
20648
20649function createContainer(containerInfo, isConcurrent, hydrate) {
20650 return createFiberRoot(containerInfo, isConcurrent, hydrate);
20651}
20652
20653function updateContainer(element, container, parentComponent, callback) {
20654 var current$$1 = container.current;
20655 var currentTime = requestCurrentTime();
20656 var expirationTime = computeExpirationForFiber(currentTime, current$$1);
20657 return updateContainerAtExpirationTime(element, container, parentComponent, expirationTime, callback);
20658}
20659
20660function getPublicRootInstance(container) {
20661 var containerFiber = container.current;
20662 if (!containerFiber.child) {
20663 return null;
20664 }
20665 switch (containerFiber.child.tag) {
20666 case HostComponent:
20667 return getPublicInstance(containerFiber.child.stateNode);
20668 default:
20669 return containerFiber.child.stateNode;
20670 }
20671}
20672
20673function findHostInstanceWithNoPortals(fiber) {
20674 var hostFiber = findCurrentHostFiberWithNoPortals(fiber);
20675 if (hostFiber === null) {
20676 return null;
20677 }
20678 return hostFiber.stateNode;
20679}
20680
20681var overrideProps = null;
20682
20683{
20684 var copyWithSetImpl = function (obj, path, idx, value) {
20685 if (idx >= path.length) {
20686 return value;
20687 }
20688 var key = path[idx];
20689 var updated = Array.isArray(obj) ? obj.slice() : _assign({}, obj);
20690 // $FlowFixMe number or string is fine here
20691 updated[key] = copyWithSetImpl(obj[key], path, idx + 1, value);
20692 return updated;
20693 };
20694
20695 var copyWithSet = function (obj, path, value) {
20696 return copyWithSetImpl(obj, path, 0, value);
20697 };
20698
20699 // Support DevTools props for function components, forwardRef, memo, host components, etc.
20700 overrideProps = function (fiber, path, value) {
20701 flushPassiveEffects();
20702 fiber.pendingProps = copyWithSet(fiber.memoizedProps, path, value);
20703 if (fiber.alternate) {
20704 fiber.alternate.pendingProps = fiber.pendingProps;
20705 }
20706 scheduleWork(fiber, Sync);
20707 };
20708}
20709
20710function injectIntoDevTools(devToolsConfig) {
20711 var findFiberByHostInstance = devToolsConfig.findFiberByHostInstance;
20712 var ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher;
20713
20714
20715 return injectInternals(_assign({}, devToolsConfig, {
20716 overrideProps: overrideProps,
20717 currentDispatcherRef: ReactCurrentDispatcher,
20718 findHostInstanceByFiber: function (fiber) {
20719 var hostFiber = findCurrentHostFiber(fiber);
20720 if (hostFiber === null) {
20721 return null;
20722 }
20723 return hostFiber.stateNode;
20724 },
20725 findFiberByHostInstance: function (instance) {
20726 if (!findFiberByHostInstance) {
20727 // Might not be implemented by the renderer.
20728 return null;
20729 }
20730 return findFiberByHostInstance(instance);
20731 }
20732 }));
20733}
20734
20735// This file intentionally does *not* have the Flow annotation.
20736// Don't add it. See `./inline-typed.js` for an explanation.
20737
20738function createPortal$1(children, containerInfo,
20739// TODO: figure out the API for cross-renderer implementation.
20740implementation) {
20741 var key = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null;
20742
20743 return {
20744 // This tag allow us to uniquely identify this as a React Portal
20745 $$typeof: REACT_PORTAL_TYPE,
20746 key: key == null ? null : '' + key,
20747 children: children,
20748 containerInfo: containerInfo,
20749 implementation: implementation
20750 };
20751}
20752
20753// TODO: this is special because it gets imported during build.
20754
20755var ReactVersion = '16.8.6';
20756
20757// TODO: This type is shared between the reconciler and ReactDOM, but will
20758// eventually be lifted out to the renderer.
20759
20760var ReactCurrentOwner = ReactSharedInternals.ReactCurrentOwner;
20761
20762var topLevelUpdateWarnings = void 0;
20763var warnOnInvalidCallback = void 0;
20764var didWarnAboutUnstableCreatePortal = false;
20765
20766{
20767 if (typeof Map !== 'function' ||
20768 // $FlowIssue Flow incorrectly thinks Map has no prototype
20769 Map.prototype == null || typeof Map.prototype.forEach !== 'function' || typeof Set !== 'function' ||
20770 // $FlowIssue Flow incorrectly thinks Set has no prototype
20771 Set.prototype == null || typeof Set.prototype.clear !== 'function' || typeof Set.prototype.forEach !== 'function') {
20772 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');
20773 }
20774
20775 topLevelUpdateWarnings = function (container) {
20776 if (container._reactRootContainer && container.nodeType !== COMMENT_NODE) {
20777 var hostInstance = findHostInstanceWithNoPortals(container._reactRootContainer._internalRoot.current);
20778 if (hostInstance) {
20779 !(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;
20780 }
20781 }
20782
20783 var isRootRenderedBySomeReact = !!container._reactRootContainer;
20784 var rootEl = getReactRootElementInContainer(container);
20785 var hasNonRootReactChild = !!(rootEl && getInstanceFromNode$1(rootEl));
20786
20787 !(!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;
20788
20789 !(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;
20790 };
20791
20792 warnOnInvalidCallback = function (callback, callerName) {
20793 !(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;
20794 };
20795}
20796
20797setRestoreImplementation(restoreControlledState$1);
20798
20799function ReactBatch(root) {
20800 var expirationTime = computeUniqueAsyncExpiration();
20801 this._expirationTime = expirationTime;
20802 this._root = root;
20803 this._next = null;
20804 this._callbacks = null;
20805 this._didComplete = false;
20806 this._hasChildren = false;
20807 this._children = null;
20808 this._defer = true;
20809}
20810ReactBatch.prototype.render = function (children) {
20811 !this._defer ? invariant(false, 'batch.render: Cannot render a batch that already committed.') : void 0;
20812 this._hasChildren = true;
20813 this._children = children;
20814 var internalRoot = this._root._internalRoot;
20815 var expirationTime = this._expirationTime;
20816 var work = new ReactWork();
20817 updateContainerAtExpirationTime(children, internalRoot, null, expirationTime, work._onCommit);
20818 return work;
20819};
20820ReactBatch.prototype.then = function (onComplete) {
20821 if (this._didComplete) {
20822 onComplete();
20823 return;
20824 }
20825 var callbacks = this._callbacks;
20826 if (callbacks === null) {
20827 callbacks = this._callbacks = [];
20828 }
20829 callbacks.push(onComplete);
20830};
20831ReactBatch.prototype.commit = function () {
20832 var internalRoot = this._root._internalRoot;
20833 var firstBatch = internalRoot.firstBatch;
20834 !(this._defer && firstBatch !== null) ? invariant(false, 'batch.commit: Cannot commit a batch multiple times.') : void 0;
20835
20836 if (!this._hasChildren) {
20837 // This batch is empty. Return.
20838 this._next = null;
20839 this._defer = false;
20840 return;
20841 }
20842
20843 var expirationTime = this._expirationTime;
20844
20845 // Ensure this is the first batch in the list.
20846 if (firstBatch !== this) {
20847 // This batch is not the earliest batch. We need to move it to the front.
20848 // Update its expiration time to be the expiration time of the earliest
20849 // batch, so that we can flush it without flushing the other batches.
20850 if (this._hasChildren) {
20851 expirationTime = this._expirationTime = firstBatch._expirationTime;
20852 // Rendering this batch again ensures its children will be the final state
20853 // when we flush (updates are processed in insertion order: last
20854 // update wins).
20855 // TODO: This forces a restart. Should we print a warning?
20856 this.render(this._children);
20857 }
20858
20859 // Remove the batch from the list.
20860 var previous = null;
20861 var batch = firstBatch;
20862 while (batch !== this) {
20863 previous = batch;
20864 batch = batch._next;
20865 }
20866 !(previous !== null) ? invariant(false, 'batch.commit: Cannot commit a batch multiple times.') : void 0;
20867 previous._next = batch._next;
20868
20869 // Add it to the front.
20870 this._next = firstBatch;
20871 firstBatch = internalRoot.firstBatch = this;
20872 }
20873
20874 // Synchronously flush all the work up to this batch's expiration time.
20875 this._defer = false;
20876 flushRoot(internalRoot, expirationTime);
20877
20878 // Pop the batch from the list.
20879 var next = this._next;
20880 this._next = null;
20881 firstBatch = internalRoot.firstBatch = next;
20882
20883 // Append the next earliest batch's children to the update queue.
20884 if (firstBatch !== null && firstBatch._hasChildren) {
20885 firstBatch.render(firstBatch._children);
20886 }
20887};
20888ReactBatch.prototype._onComplete = function () {
20889 if (this._didComplete) {
20890 return;
20891 }
20892 this._didComplete = true;
20893 var callbacks = this._callbacks;
20894 if (callbacks === null) {
20895 return;
20896 }
20897 // TODO: Error handling.
20898 for (var i = 0; i < callbacks.length; i++) {
20899 var _callback = callbacks[i];
20900 _callback();
20901 }
20902};
20903
20904function ReactWork() {
20905 this._callbacks = null;
20906 this._didCommit = false;
20907 // TODO: Avoid need to bind by replacing callbacks in the update queue with
20908 // list of Work objects.
20909 this._onCommit = this._onCommit.bind(this);
20910}
20911ReactWork.prototype.then = function (onCommit) {
20912 if (this._didCommit) {
20913 onCommit();
20914 return;
20915 }
20916 var callbacks = this._callbacks;
20917 if (callbacks === null) {
20918 callbacks = this._callbacks = [];
20919 }
20920 callbacks.push(onCommit);
20921};
20922ReactWork.prototype._onCommit = function () {
20923 if (this._didCommit) {
20924 return;
20925 }
20926 this._didCommit = true;
20927 var callbacks = this._callbacks;
20928 if (callbacks === null) {
20929 return;
20930 }
20931 // TODO: Error handling.
20932 for (var i = 0; i < callbacks.length; i++) {
20933 var _callback2 = callbacks[i];
20934 !(typeof _callback2 === 'function') ? invariant(false, 'Invalid argument passed as callback. Expected a function. Instead received: %s', _callback2) : void 0;
20935 _callback2();
20936 }
20937};
20938
20939function ReactRoot(container, isConcurrent, hydrate) {
20940 var root = createContainer(container, isConcurrent, hydrate);
20941 this._internalRoot = root;
20942}
20943ReactRoot.prototype.render = function (children, callback) {
20944 var root = this._internalRoot;
20945 var work = new ReactWork();
20946 callback = callback === undefined ? null : callback;
20947 {
20948 warnOnInvalidCallback(callback, 'render');
20949 }
20950 if (callback !== null) {
20951 work.then(callback);
20952 }
20953 updateContainer(children, root, null, work._onCommit);
20954 return work;
20955};
20956ReactRoot.prototype.unmount = function (callback) {
20957 var root = this._internalRoot;
20958 var work = new ReactWork();
20959 callback = callback === undefined ? null : callback;
20960 {
20961 warnOnInvalidCallback(callback, 'render');
20962 }
20963 if (callback !== null) {
20964 work.then(callback);
20965 }
20966 updateContainer(null, root, null, work._onCommit);
20967 return work;
20968};
20969ReactRoot.prototype.legacy_renderSubtreeIntoContainer = function (parentComponent, children, callback) {
20970 var root = this._internalRoot;
20971 var work = new ReactWork();
20972 callback = callback === undefined ? null : callback;
20973 {
20974 warnOnInvalidCallback(callback, 'render');
20975 }
20976 if (callback !== null) {
20977 work.then(callback);
20978 }
20979 updateContainer(children, root, parentComponent, work._onCommit);
20980 return work;
20981};
20982ReactRoot.prototype.createBatch = function () {
20983 var batch = new ReactBatch(this);
20984 var expirationTime = batch._expirationTime;
20985
20986 var internalRoot = this._internalRoot;
20987 var firstBatch = internalRoot.firstBatch;
20988 if (firstBatch === null) {
20989 internalRoot.firstBatch = batch;
20990 batch._next = null;
20991 } else {
20992 // Insert sorted by expiration time then insertion order
20993 var insertAfter = null;
20994 var insertBefore = firstBatch;
20995 while (insertBefore !== null && insertBefore._expirationTime >= expirationTime) {
20996 insertAfter = insertBefore;
20997 insertBefore = insertBefore._next;
20998 }
20999 batch._next = insertBefore;
21000 if (insertAfter !== null) {
21001 insertAfter._next = batch;
21002 }
21003 }
21004
21005 return batch;
21006};
21007
21008/**
21009 * True if the supplied DOM node is a valid node element.
21010 *
21011 * @param {?DOMElement} node The candidate DOM node.
21012 * @return {boolean} True if the DOM is a valid DOM node.
21013 * @internal
21014 */
21015function isValidContainer(node) {
21016 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 '));
21017}
21018
21019function getReactRootElementInContainer(container) {
21020 if (!container) {
21021 return null;
21022 }
21023
21024 if (container.nodeType === DOCUMENT_NODE) {
21025 return container.documentElement;
21026 } else {
21027 return container.firstChild;
21028 }
21029}
21030
21031function shouldHydrateDueToLegacyHeuristic(container) {
21032 var rootElement = getReactRootElementInContainer(container);
21033 return !!(rootElement && rootElement.nodeType === ELEMENT_NODE && rootElement.hasAttribute(ROOT_ATTRIBUTE_NAME));
21034}
21035
21036setBatchingImplementation(batchedUpdates$1, interactiveUpdates$1, flushInteractiveUpdates$1);
21037
21038var warnedAboutHydrateAPI = false;
21039
21040function legacyCreateRootFromDOMContainer(container, forceHydrate) {
21041 var shouldHydrate = forceHydrate || shouldHydrateDueToLegacyHeuristic(container);
21042 // First clear any existing content.
21043 if (!shouldHydrate) {
21044 var warned = false;
21045 var rootSibling = void 0;
21046 while (rootSibling = container.lastChild) {
21047 {
21048 if (!warned && rootSibling.nodeType === ELEMENT_NODE && rootSibling.hasAttribute(ROOT_ATTRIBUTE_NAME)) {
21049 warned = true;
21050 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.');
21051 }
21052 }
21053 container.removeChild(rootSibling);
21054 }
21055 }
21056 {
21057 if (shouldHydrate && !forceHydrate && !warnedAboutHydrateAPI) {
21058 warnedAboutHydrateAPI = true;
21059 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.');
21060 }
21061 }
21062 // Legacy roots are not async by default.
21063 var isConcurrent = false;
21064 return new ReactRoot(container, isConcurrent, shouldHydrate);
21065}
21066
21067function legacyRenderSubtreeIntoContainer(parentComponent, children, container, forceHydrate, callback) {
21068 {
21069 topLevelUpdateWarnings(container);
21070 }
21071
21072 // TODO: Without `any` type, Flow says "Property cannot be accessed on any
21073 // member of intersection type." Whyyyyyy.
21074 var root = container._reactRootContainer;
21075 if (!root) {
21076 // Initial mount
21077 root = container._reactRootContainer = legacyCreateRootFromDOMContainer(container, forceHydrate);
21078 if (typeof callback === 'function') {
21079 var originalCallback = callback;
21080 callback = function () {
21081 var instance = getPublicRootInstance(root._internalRoot);
21082 originalCallback.call(instance);
21083 };
21084 }
21085 // Initial mount should not be batched.
21086 unbatchedUpdates(function () {
21087 if (parentComponent != null) {
21088 root.legacy_renderSubtreeIntoContainer(parentComponent, children, callback);
21089 } else {
21090 root.render(children, callback);
21091 }
21092 });
21093 } else {
21094 if (typeof callback === 'function') {
21095 var _originalCallback = callback;
21096 callback = function () {
21097 var instance = getPublicRootInstance(root._internalRoot);
21098 _originalCallback.call(instance);
21099 };
21100 }
21101 // Update
21102 if (parentComponent != null) {
21103 root.legacy_renderSubtreeIntoContainer(parentComponent, children, callback);
21104 } else {
21105 root.render(children, callback);
21106 }
21107 }
21108 return getPublicRootInstance(root._internalRoot);
21109}
21110
21111function createPortal$$1(children, container) {
21112 var key = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
21113
21114 !isValidContainer(container) ? invariant(false, 'Target container is not a DOM element.') : void 0;
21115 // TODO: pass ReactDOM portal implementation as third argument
21116 return createPortal$1(children, container, null, key);
21117}
21118
21119var ReactDOM = {
21120 createPortal: createPortal$$1,
21121
21122 findDOMNode: function (componentOrElement) {
21123 {
21124 var owner = ReactCurrentOwner.current;
21125 if (owner !== null && owner.stateNode !== null) {
21126 var warnedAboutRefsInRender = owner.stateNode._warnedAboutRefsInRender;
21127 !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;
21128 owner.stateNode._warnedAboutRefsInRender = true;
21129 }
21130 }
21131 if (componentOrElement == null) {
21132 return null;
21133 }
21134 if (componentOrElement.nodeType === ELEMENT_NODE) {
21135 return componentOrElement;
21136 }
21137 {
21138 return findHostInstanceWithWarning(componentOrElement, 'findDOMNode');
21139 }
21140 return findHostInstance(componentOrElement);
21141 },
21142 hydrate: function (element, container, callback) {
21143 !isValidContainer(container) ? invariant(false, 'Target container is not a DOM element.') : void 0;
21144 {
21145 !!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;
21146 }
21147 // TODO: throw or warn if we couldn't hydrate?
21148 return legacyRenderSubtreeIntoContainer(null, element, container, true, callback);
21149 },
21150 render: function (element, container, callback) {
21151 !isValidContainer(container) ? invariant(false, 'Target container is not a DOM element.') : void 0;
21152 {
21153 !!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;
21154 }
21155 return legacyRenderSubtreeIntoContainer(null, element, container, false, callback);
21156 },
21157 unstable_renderSubtreeIntoContainer: function (parentComponent, element, containerNode, callback) {
21158 !isValidContainer(containerNode) ? invariant(false, 'Target container is not a DOM element.') : void 0;
21159 !(parentComponent != null && has(parentComponent)) ? invariant(false, 'parentComponent must be a valid React Component') : void 0;
21160 return legacyRenderSubtreeIntoContainer(parentComponent, element, containerNode, false, callback);
21161 },
21162 unmountComponentAtNode: function (container) {
21163 !isValidContainer(container) ? invariant(false, 'unmountComponentAtNode(...): Target container is not a DOM element.') : void 0;
21164
21165 {
21166 !!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;
21167 }
21168
21169 if (container._reactRootContainer) {
21170 {
21171 var rootEl = getReactRootElementInContainer(container);
21172 var renderedByDifferentReact = rootEl && !getInstanceFromNode$1(rootEl);
21173 !!renderedByDifferentReact ? warningWithoutStack$1(false, "unmountComponentAtNode(): The node you're attempting to unmount " + 'was rendered by another copy of React.') : void 0;
21174 }
21175
21176 // Unmount should not be batched.
21177 unbatchedUpdates(function () {
21178 legacyRenderSubtreeIntoContainer(null, null, container, false, function () {
21179 container._reactRootContainer = null;
21180 });
21181 });
21182 // If you call unmountComponentAtNode twice in quick succession, you'll
21183 // get `true` twice. That's probably fine?
21184 return true;
21185 } else {
21186 {
21187 var _rootEl = getReactRootElementInContainer(container);
21188 var hasNonRootReactChild = !!(_rootEl && getInstanceFromNode$1(_rootEl));
21189
21190 // Check if the container itself is a React root node.
21191 var isContainerReactRoot = container.nodeType === ELEMENT_NODE && isValidContainer(container.parentNode) && !!container.parentNode._reactRootContainer;
21192
21193 !!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;
21194 }
21195
21196 return false;
21197 }
21198 },
21199
21200
21201 // Temporary alias since we already shipped React 16 RC with it.
21202 // TODO: remove in React 17.
21203 unstable_createPortal: function () {
21204 if (!didWarnAboutUnstableCreatePortal) {
21205 didWarnAboutUnstableCreatePortal = true;
21206 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.');
21207 }
21208 return createPortal$$1.apply(undefined, arguments);
21209 },
21210
21211
21212 unstable_batchedUpdates: batchedUpdates$1,
21213
21214 unstable_interactiveUpdates: interactiveUpdates$1,
21215
21216 flushSync: flushSync,
21217
21218 unstable_createRoot: createRoot,
21219 unstable_flushControlled: flushControlled,
21220
21221 __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED: {
21222 // Keep in sync with ReactDOMUnstableNativeDependencies.js
21223 // and ReactTestUtils.js. This is an array for better minification.
21224 Events: [getInstanceFromNode$1, getNodeFromInstance$1, getFiberCurrentPropsFromNode$1, injection.injectEventPluginsByName, eventNameDispatchConfigs, accumulateTwoPhaseDispatches, accumulateDirectDispatches, enqueueStateRestore, restoreStateIfNeeded, dispatchEvent, runEventsInBatch]
21225 }
21226};
21227
21228function createRoot(container, options) {
21229 var functionName = enableStableConcurrentModeAPIs ? 'createRoot' : 'unstable_createRoot';
21230 !isValidContainer(container) ? invariant(false, '%s(...): Target container is not a DOM element.', functionName) : void 0;
21231 {
21232 !!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;
21233 container._reactHasBeenPassedToCreateRootDEV = true;
21234 }
21235 var hydrate = options != null && options.hydrate === true;
21236 return new ReactRoot(container, true, hydrate);
21237}
21238
21239if (enableStableConcurrentModeAPIs) {
21240 ReactDOM.createRoot = createRoot;
21241 ReactDOM.unstable_createRoot = undefined;
21242}
21243
21244var foundDevTools = injectIntoDevTools({
21245 findFiberByHostInstance: getClosestInstanceFromNode,
21246 bundleType: 1,
21247 version: ReactVersion,
21248 rendererPackageName: 'react-dom'
21249});
21250
21251{
21252 if (!foundDevTools && canUseDOM && window.top === window.self) {
21253 // If we're in Chrome or Firefox, provide a download link if not installed.
21254 if (navigator.userAgent.indexOf('Chrome') > -1 && navigator.userAgent.indexOf('Edge') === -1 || navigator.userAgent.indexOf('Firefox') > -1) {
21255 var protocol = window.location.protocol;
21256 // Don't warn in exotic cases like chrome-extension://.
21257 if (/^(https?|file):$/.test(protocol)) {
21258 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');
21259 }
21260 }
21261 }
21262}
21263
21264
21265
21266var ReactDOM$2 = Object.freeze({
21267 default: ReactDOM
21268});
21269
21270var ReactDOM$3 = ( ReactDOM$2 && ReactDOM ) || ReactDOM$2;
21271
21272// TODO: decide on the top-level export form.
21273// This is hacky but makes it work with both Rollup and Jest.
21274var reactDom = ReactDOM$3.default || ReactDOM$3;
21275
21276module.exports = reactDom;
21277 })();
21278}