UNPKG

744 kBJavaScriptView Raw
1/** @license React v16.7.0
2 * react-dom-unstable-fire.development.js
3 *
4 * Copyright (c) Facebook, Inc. and its affiliates.
5 *
6 * This source code is licensed under the MIT license found in the
7 * LICENSE file in the root directory of this source tree.
8 */
9
10'use strict';
11
12(function (global, factory) {
13 typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('react')) :
14 typeof define === 'function' && define.amd ? define(['react'], factory) :
15 (global.ReactFire = factory(global.React));
16}(this, (function (React) { 'use strict';
17
18/**
19 * Use invariant() to assert state which your program assumes to be true.
20 *
21 * Provide sprintf-style format (only %s is supported) and arguments
22 * to provide information about what broke and what you were
23 * expecting.
24 *
25 * The invariant message will be stripped in production, but the invariant
26 * will remain to ensure logic does not differ in production.
27 */
28
29var validateFormat = function () {};
30
31{
32 validateFormat = function (format) {
33 if (format === undefined) {
34 throw new Error('invariant requires an error message argument');
35 }
36 };
37}
38
39function invariant(condition, format, a, b, c, d, e, f) {
40 validateFormat(format);
41
42 if (!condition) {
43 var error = void 0;
44 if (format === undefined) {
45 error = new Error('Minified exception occurred; use the non-minified dev environment ' + 'for the full error message and additional helpful warnings.');
46 } else {
47 var args = [a, b, c, d, e, f];
48 var argIndex = 0;
49 error = new Error(format.replace(/%s/g, function () {
50 return args[argIndex++];
51 }));
52 error.name = 'Invariant Violation';
53 }
54
55 error.framesToPop = 1; // we don't care about invariant's own frame
56 throw error;
57 }
58}
59
60// Relying on the `invariant()` implementation lets us
61// preserve the format and params in the www builds.
62
63!React ? invariant(false, 'ReactDOM was loaded before React. Make sure you load the React package before loading ReactDOM.') : void 0;
64
65var invokeGuardedCallbackImpl = function (name, func, context, a, b, c, d, e, f) {
66 var funcArgs = Array.prototype.slice.call(arguments, 3);
67 try {
68 func.apply(context, funcArgs);
69 } catch (error) {
70 this.onError(error);
71 }
72};
73
74{
75 // In DEV mode, we swap out invokeGuardedCallback for a special version
76 // that plays more nicely with the browser's DevTools. The idea is to preserve
77 // "Pause on exceptions" behavior. Because React wraps all user-provided
78 // functions in invokeGuardedCallback, and the production version of
79 // invokeGuardedCallback uses a try-catch, all user exceptions are treated
80 // like caught exceptions, and the DevTools won't pause unless the developer
81 // takes the extra step of enabling pause on caught exceptions. This is
82 // untintuitive, though, because even though React has caught the error, from
83 // the developer's perspective, the error is uncaught.
84 //
85 // To preserve the expected "Pause on exceptions" behavior, we don't use a
86 // try-catch in DEV. Instead, we synchronously dispatch a fake event to a fake
87 // DOM node, and call the user-provided callback from inside an event handler
88 // for that fake event. If the callback throws, the error is "captured" using
89 // a global event handler. But because the error happens in a different
90 // event loop context, it does not interrupt the normal program flow.
91 // Effectively, this gives us try-catch behavior without actually using
92 // try-catch. Neat!
93
94 // Check that the browser supports the APIs we need to implement our special
95 // DEV version of invokeGuardedCallback
96 if (typeof window !== 'undefined' && typeof window.dispatchEvent === 'function' && typeof document !== 'undefined' && typeof document.createEvent === 'function') {
97 var fakeNode = document.createElement('react');
98
99 var invokeGuardedCallbackDev = function (name, func, context, a, b, c, d, e, f) {
100 // If document doesn't exist we know for sure we will crash in this method
101 // when we call document.createEvent(). However this can cause confusing
102 // errors: https://github.com/facebookincubator/create-react-app/issues/3482
103 // So we preemptively throw with a better message instead.
104 !(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;
105 var evt = document.createEvent('Event');
106
107 // Keeps track of whether the user-provided callback threw an error. We
108 // set this to true at the beginning, then set it to false right after
109 // calling the function. If the function errors, `didError` will never be
110 // set to false. This strategy works even if the browser is flaky and
111 // fails to call our global error handler, because it doesn't rely on
112 // the error event at all.
113 var didError = true;
114
115 // Keeps track of the value of window.event so that we can reset it
116 // during the callback to let user code access window.event in the
117 // browsers that support it.
118 var windowEvent = window.event;
119
120 // Keeps track of the descriptor of window.event to restore it after event
121 // dispatching: https://github.com/facebook/react/issues/13688
122 var windowEventDescriptor = Object.getOwnPropertyDescriptor(window, 'event');
123
124 // Create an event handler for our fake event. We will synchronously
125 // dispatch our fake event using `dispatchEvent`. Inside the handler, we
126 // call the user-provided callback.
127 var funcArgs = Array.prototype.slice.call(arguments, 3);
128 function callCallback() {
129 // We immediately remove the callback from event listeners so that
130 // nested `invokeGuardedCallback` calls do not clash. Otherwise, a
131 // nested call would trigger the fake event handlers of any call higher
132 // in the stack.
133 fakeNode.removeEventListener(evtType, callCallback, false);
134
135 // We check for window.hasOwnProperty('event') to prevent the
136 // window.event assignment in both IE <= 10 as they throw an error
137 // "Member not found" in strict mode, and in Firefox which does not
138 // support window.event.
139 if (typeof window.event !== 'undefined' && window.hasOwnProperty('event')) {
140 window.event = windowEvent;
141 }
142
143 func.apply(context, funcArgs);
144 didError = false;
145 }
146
147 // Create a global error event handler. We use this to capture the value
148 // that was thrown. It's possible that this error handler will fire more
149 // than once; for example, if non-React code also calls `dispatchEvent`
150 // and a handler for that event throws. We should be resilient to most of
151 // those cases. Even if our error event handler fires more than once, the
152 // last error event is always used. If the callback actually does error,
153 // we know that the last error event is the correct one, because it's not
154 // possible for anything else to have happened in between our callback
155 // erroring and the code that follows the `dispatchEvent` call below. If
156 // the callback doesn't error, but the error event was fired, we know to
157 // ignore it because `didError` will be false, as described above.
158 var error = void 0;
159 // Use this to track whether the error event is ever called.
160 var didSetError = false;
161 var isCrossOriginError = false;
162
163 function handleWindowError(event) {
164 error = event.error;
165 didSetError = true;
166 if (error === null && event.colno === 0 && event.lineno === 0) {
167 isCrossOriginError = true;
168 }
169 if (event.defaultPrevented) {
170 // Some other error handler has prevented default.
171 // Browsers silence the error report if this happens.
172 // We'll remember this to later decide whether to log it or not.
173 if (error != null && typeof error === 'object') {
174 try {
175 error._suppressLogging = true;
176 } catch (inner) {
177 // Ignore.
178 }
179 }
180 }
181 }
182
183 // Create a fake event type.
184 var evtType = 'react-' + (name ? name : 'invokeguardedcallback');
185
186 // Attach our event handlers
187 window.addEventListener('error', handleWindowError);
188 fakeNode.addEventListener(evtType, callCallback, false);
189
190 // Synchronously dispatch our fake event. If the user-provided function
191 // errors, it will trigger our global error handler.
192 evt.initEvent(evtType, false, false);
193 fakeNode.dispatchEvent(evt);
194
195 if (windowEventDescriptor) {
196 Object.defineProperty(window, 'event', windowEventDescriptor);
197 }
198
199 if (didError) {
200 if (!didSetError) {
201 // The callback errored, but the error event never fired.
202 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.');
203 } else if (isCrossOriginError) {
204 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.');
205 }
206 this.onError(error);
207 }
208
209 // Remove our event listeners
210 window.removeEventListener('error', handleWindowError);
211 };
212
213 invokeGuardedCallbackImpl = invokeGuardedCallbackDev;
214 }
215}
216
217var invokeGuardedCallbackImpl$1 = invokeGuardedCallbackImpl;
218
219// Used by Fiber to simulate a try-catch.
220var hasError = false;
221var caughtError = null;
222
223// Used by event system to capture/rethrow the first error.
224var hasRethrowError = false;
225var rethrowError = null;
226
227var reporter = {
228 onError: function (error) {
229 hasError = true;
230 caughtError = error;
231 }
232};
233
234/**
235 * Call a function while guarding against errors that happens within it.
236 * Returns an error if it throws, otherwise null.
237 *
238 * In production, this is implemented using a try-catch. The reason we don't
239 * use a try-catch directly is so that we can swap out a different
240 * implementation in DEV mode.
241 *
242 * @param {String} name of the guard to use for logging or debugging
243 * @param {Function} func The function to invoke
244 * @param {*} context The context to use when calling the function
245 * @param {...*} args Arguments for function
246 */
247function invokeGuardedCallback(name, func, context, a, b, c, d, e, f) {
248 hasError = false;
249 caughtError = null;
250 invokeGuardedCallbackImpl$1.apply(reporter, arguments);
251}
252
253/**
254 * Same as invokeGuardedCallback, but instead of returning an error, it stores
255 * it in a global so it can be rethrown by `rethrowCaughtError` later.
256 * TODO: See if caughtError and rethrowError can be unified.
257 *
258 * @param {String} name of the guard to use for logging or debugging
259 * @param {Function} func The function to invoke
260 * @param {*} context The context to use when calling the function
261 * @param {...*} args Arguments for function
262 */
263function invokeGuardedCallbackAndCatchFirstError(name, func, context, a, b, c, d, e, f) {
264 invokeGuardedCallback.apply(this, arguments);
265 if (hasError) {
266 var error = clearCaughtError();
267 if (!hasRethrowError) {
268 hasRethrowError = true;
269 rethrowError = error;
270 }
271 }
272}
273
274/**
275 * During execution of guarded functions we will capture the first error which
276 * we will rethrow to be handled by the top level error handler.
277 */
278function rethrowCaughtError() {
279 if (hasRethrowError) {
280 var error = rethrowError;
281 hasRethrowError = false;
282 rethrowError = null;
283 throw error;
284 }
285}
286
287function hasCaughtError() {
288 return hasError;
289}
290
291function clearCaughtError() {
292 if (hasError) {
293 var error = caughtError;
294 hasError = false;
295 caughtError = null;
296 return error;
297 } else {
298 invariant(false, 'clearCaughtError was called but no error was captured. This error is likely caused by a bug in React. Please file an issue.');
299 }
300}
301
302/**
303 * Injectable ordering of event plugins.
304 */
305var eventPluginOrder = null;
306
307/**
308 * Injectable mapping from names to event plugin modules.
309 */
310var namesToPlugins = {};
311
312/**
313 * Recomputes the plugin list using the injected plugins and plugin ordering.
314 *
315 * @private
316 */
317function recomputePluginOrdering() {
318 if (!eventPluginOrder) {
319 // Wait until an `eventPluginOrder` is injected.
320 return;
321 }
322 for (var pluginName in namesToPlugins) {
323 var pluginModule = namesToPlugins[pluginName];
324 var pluginIndex = eventPluginOrder.indexOf(pluginName);
325 !(pluginIndex > -1) ? invariant(false, 'EventPluginRegistry: Cannot inject event plugins that do not exist in the plugin ordering, `%s`.', pluginName) : void 0;
326 if (plugins[pluginIndex]) {
327 continue;
328 }
329 !pluginModule.extractEvents ? invariant(false, 'EventPluginRegistry: Event plugins must implement an `extractEvents` method, but `%s` does not.', pluginName) : void 0;
330 plugins[pluginIndex] = pluginModule;
331 var publishedEvents = pluginModule.eventTypes;
332 for (var eventName in publishedEvents) {
333 !publishEventForPlugin(publishedEvents[eventName], pluginModule, eventName) ? invariant(false, 'EventPluginRegistry: Failed to publish event `%s` for plugin `%s`.', eventName, pluginName) : void 0;
334 }
335 }
336}
337
338/**
339 * Publishes an event so that it can be dispatched by the supplied plugin.
340 *
341 * @param {object} dispatchConfig Dispatch configuration for the event.
342 * @param {object} PluginModule Plugin publishing the event.
343 * @return {boolean} True if the event was successfully published.
344 * @private
345 */
346function publishEventForPlugin(dispatchConfig, pluginModule, eventName) {
347 !!eventNameDispatchConfigs.hasOwnProperty(eventName) ? invariant(false, 'EventPluginHub: More than one plugin attempted to publish the same event name, `%s`.', eventName) : void 0;
348 eventNameDispatchConfigs[eventName] = dispatchConfig;
349
350 var phasedRegistrationNames = dispatchConfig.phasedRegistrationNames;
351 if (phasedRegistrationNames) {
352 for (var phaseName in phasedRegistrationNames) {
353 if (phasedRegistrationNames.hasOwnProperty(phaseName)) {
354 var phasedRegistrationName = phasedRegistrationNames[phaseName];
355 publishRegistrationName(phasedRegistrationName, pluginModule, eventName);
356 }
357 }
358 return true;
359 } else if (dispatchConfig.registrationName) {
360 publishRegistrationName(dispatchConfig.registrationName, pluginModule, eventName);
361 return true;
362 }
363 return false;
364}
365
366/**
367 * Publishes a registration name that is used to identify dispatched events.
368 *
369 * @param {string} registrationName Registration name to add.
370 * @param {object} PluginModule Plugin publishing the event.
371 * @private
372 */
373function publishRegistrationName(registrationName, pluginModule, eventName) {
374 !!registrationNameModules[registrationName] ? invariant(false, 'EventPluginHub: More than one plugin attempted to publish the same registration name, `%s`.', registrationName) : void 0;
375 registrationNameModules[registrationName] = pluginModule;
376 registrationNameDependencies[registrationName] = pluginModule.eventTypes[eventName].dependencies;
377
378 {
379 var lowerCasedName = registrationName.toLowerCase();
380 possibleRegistrationNames[lowerCasedName] = registrationName;
381
382 if (registrationName === 'onDoubleClick') {
383 possibleRegistrationNames.ondblclick = registrationName;
384 }
385 }
386}
387
388/**
389 * Registers plugins so that they can extract and dispatch events.
390 *
391 * @see {EventPluginHub}
392 */
393
394/**
395 * Ordered list of injected plugins.
396 */
397var plugins = [];
398
399/**
400 * Mapping from event name to dispatch config
401 */
402var eventNameDispatchConfigs = {};
403
404/**
405 * Mapping from registration name to plugin module
406 */
407var registrationNameModules = {};
408
409/**
410 * Mapping from registration name to event name
411 */
412var registrationNameDependencies = {};
413
414/**
415 * Mapping from lowercase registration names to the properly cased version,
416 * used to warn in the case of missing event handlers. Available
417 * only in true.
418 * @type {Object}
419 */
420var possibleRegistrationNames = {};
421// Trust the developer to only use possibleRegistrationNames in true
422
423/**
424 * Injects an ordering of plugins (by plugin name). This allows the ordering
425 * to be decoupled from injection of the actual plugins so that ordering is
426 * always deterministic regardless of packaging, on-the-fly injection, etc.
427 *
428 * @param {array} InjectedEventPluginOrder
429 * @internal
430 * @see {EventPluginHub.injection.injectEventPluginOrder}
431 */
432function injectEventPluginOrder(injectedEventPluginOrder) {
433 !!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;
434 // Clone the ordering so it cannot be dynamically mutated.
435 eventPluginOrder = Array.prototype.slice.call(injectedEventPluginOrder);
436 recomputePluginOrdering();
437}
438
439/**
440 * Injects plugins to be used by `EventPluginHub`. The plugin names must be
441 * in the ordering injected by `injectEventPluginOrder`.
442 *
443 * Plugins can be injected as part of page initialization or on-the-fly.
444 *
445 * @param {object} injectedNamesToPlugins Map from names to plugin modules.
446 * @internal
447 * @see {EventPluginHub.injection.injectEventPluginsByName}
448 */
449function injectEventPluginsByName(injectedNamesToPlugins) {
450 var isOrderingDirty = false;
451 for (var pluginName in injectedNamesToPlugins) {
452 if (!injectedNamesToPlugins.hasOwnProperty(pluginName)) {
453 continue;
454 }
455 var pluginModule = injectedNamesToPlugins[pluginName];
456 if (!namesToPlugins.hasOwnProperty(pluginName) || namesToPlugins[pluginName] !== pluginModule) {
457 !!namesToPlugins[pluginName] ? invariant(false, 'EventPluginRegistry: Cannot inject two different event plugins using the same name, `%s`.', pluginName) : void 0;
458 namesToPlugins[pluginName] = pluginModule;
459 isOrderingDirty = true;
460 }
461 }
462 if (isOrderingDirty) {
463 recomputePluginOrdering();
464 }
465}
466
467/**
468 * Similar to invariant but only logs a warning if the condition is not met.
469 * This can be used to log issues in development environments in critical
470 * paths. Removing the logging code for production environments will keep the
471 * same logic and follow the same code paths.
472 */
473
474var warningWithoutStack = function () {};
475
476{
477 warningWithoutStack = function (condition, format) {
478 for (var _len = arguments.length, args = Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) {
479 args[_key - 2] = arguments[_key];
480 }
481
482 if (format === undefined) {
483 throw new Error('`warningWithoutStack(condition, format, ...args)` requires a warning ' + 'message argument');
484 }
485 if (args.length > 8) {
486 // Check before the condition to catch violations early.
487 throw new Error('warningWithoutStack() currently supports at most 8 arguments.');
488 }
489 if (condition) {
490 return;
491 }
492 if (typeof console !== 'undefined') {
493 var argsWithFormat = args.map(function (item) {
494 return '' + item;
495 });
496 argsWithFormat.unshift('Warning: ' + format);
497
498 // We intentionally don't use spread (or .apply) directly because it
499 // breaks IE9: https://github.com/facebook/react/issues/13610
500 Function.prototype.apply.call(console.error, console, argsWithFormat);
501 }
502 try {
503 // --- Welcome to debugging React ---
504 // This error was thrown as a convenience so that you can use this stack
505 // to find the callsite that caused this warning to fire.
506 var argIndex = 0;
507 var message = 'Warning: ' + format.replace(/%s/g, function () {
508 return args[argIndex++];
509 });
510 throw new Error(message);
511 } catch (x) {}
512 };
513}
514
515var warningWithoutStack$1 = warningWithoutStack;
516
517var getFiberCurrentPropsFromNode = null;
518var getInstanceFromNode = null;
519var getNodeFromInstance = null;
520
521function setComponentTree(getFiberCurrentPropsFromNodeImpl, getInstanceFromNodeImpl, getNodeFromInstanceImpl) {
522 getFiberCurrentPropsFromNode = getFiberCurrentPropsFromNodeImpl;
523 getInstanceFromNode = getInstanceFromNodeImpl;
524 getNodeFromInstance = getNodeFromInstanceImpl;
525 {
526 !(getNodeFromInstance && getInstanceFromNode) ? warningWithoutStack$1(false, 'EventPluginUtils.setComponentTree(...): Injected ' + 'module is missing getNodeFromInstance or getInstanceFromNode.') : void 0;
527 }
528}
529
530var validateEventDispatches = void 0;
531{
532 validateEventDispatches = function (event) {
533 var dispatchListeners = event._dispatchListeners;
534 var dispatchInstances = event._dispatchInstances;
535
536 var listenersIsArr = Array.isArray(dispatchListeners);
537 var listenersLen = listenersIsArr ? dispatchListeners.length : dispatchListeners ? 1 : 0;
538
539 var instancesIsArr = Array.isArray(dispatchInstances);
540 var instancesLen = instancesIsArr ? dispatchInstances.length : dispatchInstances ? 1 : 0;
541
542 !(instancesIsArr === listenersIsArr && instancesLen === listenersLen) ? warningWithoutStack$1(false, 'EventPluginUtils: Invalid `event`.') : void 0;
543 };
544}
545
546/**
547 * Dispatch the event to the listener.
548 * @param {SyntheticEvent} event SyntheticEvent to handle
549 * @param {function} listener Application-level callback
550 * @param {*} inst Internal component instance
551 */
552function executeDispatch(event, listener, inst) {
553 var type = event.type || 'unknown-event';
554 event.currentTarget = getNodeFromInstance(inst);
555 invokeGuardedCallbackAndCatchFirstError(type, listener, undefined, event);
556 event.currentTarget = null;
557}
558
559/**
560 * Standard/simple iteration through an event's collected dispatches.
561 */
562function executeDispatchesInOrder(event) {
563 var dispatchListeners = event._dispatchListeners;
564 var dispatchInstances = event._dispatchInstances;
565 {
566 validateEventDispatches(event);
567 }
568 if (Array.isArray(dispatchListeners)) {
569 for (var i = 0; i < dispatchListeners.length; i++) {
570 if (event.isPropagationStopped()) {
571 break;
572 }
573 // Listeners and Instances are two parallel arrays that are always in sync.
574 executeDispatch(event, dispatchListeners[i], dispatchInstances[i]);
575 }
576 } else if (dispatchListeners) {
577 executeDispatch(event, dispatchListeners, dispatchInstances);
578 }
579 event._dispatchListeners = null;
580 event._dispatchInstances = null;
581}
582
583/**
584 * @see executeDispatchesInOrderStopAtTrueImpl
585 */
586
587
588/**
589 * Execution of a "direct" dispatch - there must be at most one dispatch
590 * accumulated on the event or it is considered an error. It doesn't really make
591 * sense for an event with multiple dispatches (bubbled) to keep track of the
592 * return values at each dispatch execution, but it does tend to make sense when
593 * dealing with "direct" dispatches.
594 *
595 * @return {*} The return value of executing the single dispatch.
596 */
597
598
599/**
600 * @param {SyntheticEvent} event
601 * @return {boolean} True iff number of dispatches accumulated is greater than 0.
602 */
603
604/**
605 * Accumulates items that must not be null or undefined into the first one. This
606 * is used to conserve memory by avoiding array allocations, and thus sacrifices
607 * API cleanness. Since `current` can be null before being passed in and not
608 * null after this function, make sure to assign it back to `current`:
609 *
610 * `a = accumulateInto(a, b);`
611 *
612 * This API should be sparingly used. Try `accumulate` for something cleaner.
613 *
614 * @return {*|array<*>} An accumulation of items.
615 */
616
617function accumulateInto(current, next) {
618 !(next != null) ? invariant(false, 'accumulateInto(...): Accumulated items must not be null or undefined.') : void 0;
619
620 if (current == null) {
621 return next;
622 }
623
624 // Both are not empty. Warning: Never call x.concat(y) when you are not
625 // certain that x is an Array (x could be a string with concat method).
626 if (Array.isArray(current)) {
627 if (Array.isArray(next)) {
628 current.push.apply(current, next);
629 return current;
630 }
631 current.push(next);
632 return current;
633 }
634
635 if (Array.isArray(next)) {
636 // A bit too dangerous to mutate `next`.
637 return [current].concat(next);
638 }
639
640 return [current, next];
641}
642
643/**
644 * @param {array} arr an "accumulation" of items which is either an Array or
645 * a single item. Useful when paired with the `accumulate` module. This is a
646 * simple utility that allows us to reason about a collection of items, but
647 * handling the case when there is exactly one item (and we do not need to
648 * allocate an array).
649 * @param {function} cb Callback invoked with each element or a collection.
650 * @param {?} [scope] Scope used as `this` in a callback.
651 */
652function forEachAccumulated(arr, cb, scope) {
653 if (Array.isArray(arr)) {
654 arr.forEach(cb, scope);
655 } else if (arr) {
656 cb.call(scope, arr);
657 }
658}
659
660/**
661 * Internal queue of events that have accumulated their dispatches and are
662 * waiting to have their dispatches executed.
663 */
664var eventQueue = null;
665
666/**
667 * Dispatches an event and releases it back into the pool, unless persistent.
668 *
669 * @param {?object} event Synthetic event to be dispatched.
670 * @private
671 */
672var executeDispatchesAndRelease = function (event) {
673 if (event) {
674 executeDispatchesInOrder(event);
675
676 if (!event.isPersistent()) {
677 event.constructor.release(event);
678 }
679 }
680};
681var executeDispatchesAndReleaseTopLevel = function (e) {
682 return executeDispatchesAndRelease(e);
683};
684
685function isInteractive(tag) {
686 return tag === 'button' || tag === 'input' || tag === 'select' || tag === 'textarea';
687}
688
689function shouldPreventMouseEvent(name, type, props) {
690 switch (name) {
691 case 'onClick':
692 case 'onClickCapture':
693 case 'onDoubleClick':
694 case 'onDoubleClickCapture':
695 case 'onMouseDown':
696 case 'onMouseDownCapture':
697 case 'onMouseMove':
698 case 'onMouseMoveCapture':
699 case 'onMouseUp':
700 case 'onMouseUpCapture':
701 return !!(props.disabled && isInteractive(type));
702 default:
703 return false;
704 }
705}
706
707/**
708 * This is a unified interface for event plugins to be installed and configured.
709 *
710 * Event plugins can implement the following properties:
711 *
712 * `extractEvents` {function(string, DOMEventTarget, string, object): *}
713 * Required. When a top-level event is fired, this method is expected to
714 * extract synthetic events that will in turn be queued and dispatched.
715 *
716 * `eventTypes` {object}
717 * Optional, plugins that fire events must publish a mapping of registration
718 * names that are used to register listeners. Values of this mapping must
719 * be objects that contain `registrationName` or `phasedRegistrationNames`.
720 *
721 * `executeDispatch` {function(object, function, string)}
722 * Optional, allows plugins to override how an event gets dispatched. By
723 * default, the listener is simply invoked.
724 *
725 * Each plugin that is injected into `EventsPluginHub` is immediately operable.
726 *
727 * @public
728 */
729
730/**
731 * Methods for injecting dependencies.
732 */
733var injection = {
734 /**
735 * @param {array} InjectedEventPluginOrder
736 * @public
737 */
738 injectEventPluginOrder: injectEventPluginOrder,
739
740 /**
741 * @param {object} injectedNamesToPlugins Map from names to plugin modules.
742 */
743 injectEventPluginsByName: injectEventPluginsByName
744};
745
746/**
747 * @param {object} inst The instance, which is the source of events.
748 * @param {string} registrationName Name of listener (e.g. `onClick`).
749 * @return {?function} The stored callback.
750 */
751function getListener(inst, registrationName) {
752 var listener = void 0;
753
754 // TODO: shouldPreventMouseEvent is DOM-specific and definitely should not
755 // live here; needs to be moved to a better place soon
756 var stateNode = inst.stateNode;
757 if (!stateNode) {
758 // Work in progress (ex: onload events in incremental mode).
759 return null;
760 }
761 var props = getFiberCurrentPropsFromNode(stateNode);
762 if (!props) {
763 // Work in progress.
764 return null;
765 }
766 listener = props[registrationName];
767 if (shouldPreventMouseEvent(registrationName, inst.type, props)) {
768 return null;
769 }
770 !(!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;
771 return listener;
772}
773
774/**
775 * Allows registered plugins an opportunity to extract events from top-level
776 * native browser events.
777 *
778 * @return {*} An accumulation of synthetic events.
779 * @internal
780 */
781function extractEvents(topLevelType, targetInst, nativeEvent, nativeEventTarget) {
782 var events = null;
783 for (var i = 0; i < plugins.length; i++) {
784 // Not every plugin in the ordering may be loaded at runtime.
785 var possiblePlugin = plugins[i];
786 if (possiblePlugin) {
787 var extractedEvents = possiblePlugin.extractEvents(topLevelType, targetInst, nativeEvent, nativeEventTarget);
788 if (extractedEvents) {
789 events = accumulateInto(events, extractedEvents);
790 }
791 }
792 }
793 return events;
794}
795
796function runEventsInBatch(events) {
797 if (events !== null) {
798 eventQueue = accumulateInto(eventQueue, events);
799 }
800
801 // Set `eventQueue` to null before processing it so that we can tell if more
802 // events get enqueued while processing.
803 var processingEventQueue = eventQueue;
804 eventQueue = null;
805
806 if (!processingEventQueue) {
807 return;
808 }
809
810 forEachAccumulated(processingEventQueue, executeDispatchesAndReleaseTopLevel);
811 !!eventQueue ? invariant(false, 'processEventQueue(): Additional events were enqueued while processing an event queue. Support for this has not yet been implemented.') : void 0;
812 // This would be a good time to rethrow if any of the event handlers threw.
813 rethrowCaughtError();
814}
815
816function runExtractedEventsInBatch(topLevelType, targetInst, nativeEvent, nativeEventTarget) {
817 var events = extractEvents(topLevelType, targetInst, nativeEvent, nativeEventTarget);
818 runEventsInBatch(events);
819}
820
821var FunctionComponent = 0;
822var ClassComponent = 1;
823var IndeterminateComponent = 2; // Before we know whether it is function or class
824var HostRoot = 3; // Root of a host tree. Could be nested inside another node.
825var HostPortal = 4; // A subtree. Could be an entry point to a different renderer.
826var HostComponent = 5;
827var HostText = 6;
828var Fragment = 7;
829var Mode = 8;
830var ContextConsumer = 9;
831var ContextProvider = 10;
832var ForwardRef = 11;
833var Profiler = 12;
834var SuspenseComponent = 13;
835var MemoComponent = 14;
836var SimpleMemoComponent = 15;
837var LazyComponent = 16;
838var IncompleteClassComponent = 17;
839
840var randomKey = Math.random().toString(36).slice(2);
841var internalInstanceKey = '__reactInternalInstance$' + randomKey;
842var internalEventHandlersKey = '__reactEventHandlers$' + randomKey;
843
844function precacheFiberNode(hostInst, node) {
845 node[internalInstanceKey] = hostInst;
846}
847
848/**
849 * Given a DOM node, return the closest ReactDOMComponent or
850 * ReactDOMTextComponent instance ancestor.
851 */
852function getClosestInstanceFromNode(node) {
853 if (node[internalInstanceKey]) {
854 return node[internalInstanceKey];
855 }
856
857 while (!node[internalInstanceKey]) {
858 if (node.parentNode) {
859 node = node.parentNode;
860 } else {
861 // Top of the tree. This node must not be part of a React tree (or is
862 // unmounted, potentially).
863 return null;
864 }
865 }
866
867 var inst = node[internalInstanceKey];
868 if (inst.tag === HostComponent || inst.tag === HostText) {
869 // In Fiber, this will always be the deepest root.
870 return inst;
871 }
872
873 return null;
874}
875
876/**
877 * Given a DOM node, return the ReactDOMComponent or ReactDOMTextComponent
878 * instance, or null if the node was not rendered by this React.
879 */
880function getInstanceFromNode$1(node) {
881 var inst = node[internalInstanceKey];
882 if (inst) {
883 if (inst.tag === HostComponent || inst.tag === HostText) {
884 return inst;
885 } else {
886 return null;
887 }
888 }
889 return null;
890}
891
892/**
893 * Given a ReactDOMComponent or ReactDOMTextComponent, return the corresponding
894 * DOM node.
895 */
896function getNodeFromInstance$1(inst) {
897 if (inst.tag === HostComponent || inst.tag === HostText) {
898 // In Fiber this, is just the state node right now. We assume it will be
899 // a host component or host text.
900 return inst.stateNode;
901 }
902
903 // Without this first invariant, passing a non-DOM-component triggers the next
904 // invariant for a missing parent, which is super confusing.
905 invariant(false, 'getNodeFromInstance: Invalid argument.');
906}
907
908function getFiberCurrentPropsFromNode$1(node) {
909 return node[internalEventHandlersKey] || null;
910}
911
912function updateFiberProps(node, props) {
913 node[internalEventHandlersKey] = props;
914}
915
916function getParent(inst) {
917 do {
918 inst = inst.return;
919 // TODO: If this is a HostRoot we might want to bail out.
920 // That is depending on if we want nested subtrees (layers) to bubble
921 // events to their parent. We could also go through parentNode on the
922 // host node but that wouldn't work for React Native and doesn't let us
923 // do the portal feature.
924 } while (inst && inst.tag !== HostComponent);
925 if (inst) {
926 return inst;
927 }
928 return null;
929}
930
931/**
932 * Return the lowest common ancestor of A and B, or null if they are in
933 * different trees.
934 */
935function getLowestCommonAncestor(instA, instB) {
936 var depthA = 0;
937 for (var tempA = instA; tempA; tempA = getParent(tempA)) {
938 depthA++;
939 }
940 var depthB = 0;
941 for (var tempB = instB; tempB; tempB = getParent(tempB)) {
942 depthB++;
943 }
944
945 // If A is deeper, crawl up.
946 while (depthA - depthB > 0) {
947 instA = getParent(instA);
948 depthA--;
949 }
950
951 // If B is deeper, crawl up.
952 while (depthB - depthA > 0) {
953 instB = getParent(instB);
954 depthB--;
955 }
956
957 // Walk in lockstep until we find a match.
958 var depth = depthA;
959 while (depth--) {
960 if (instA === instB || instA === instB.alternate) {
961 return instA;
962 }
963 instA = getParent(instA);
964 instB = getParent(instB);
965 }
966 return null;
967}
968
969/**
970 * Return if A is an ancestor of B.
971 */
972
973
974/**
975 * Return the parent instance of the passed-in instance.
976 */
977
978
979/**
980 * Simulates the traversal of a two-phase, capture/bubble event dispatch.
981 */
982function traverseTwoPhase(inst, fn, arg) {
983 var path = [];
984 while (inst) {
985 path.push(inst);
986 inst = getParent(inst);
987 }
988 var i = void 0;
989 for (i = path.length; i-- > 0;) {
990 fn(path[i], 'captured', arg);
991 }
992 for (i = 0; i < path.length; i++) {
993 fn(path[i], 'bubbled', arg);
994 }
995}
996
997/**
998 * Traverses the ID hierarchy and invokes the supplied `cb` on any IDs that
999 * should would receive a `mouseEnter` or `mouseLeave` event.
1000 *
1001 * Does not invoke the callback on the nearest common ancestor because nothing
1002 * "entered" or "left" that element.
1003 */
1004function traverseEnterLeave(from, to, fn, argFrom, argTo) {
1005 var common = from && to ? getLowestCommonAncestor(from, to) : null;
1006 var pathFrom = [];
1007 while (true) {
1008 if (!from) {
1009 break;
1010 }
1011 if (from === common) {
1012 break;
1013 }
1014 var alternate = from.alternate;
1015 if (alternate !== null && alternate === common) {
1016 break;
1017 }
1018 pathFrom.push(from);
1019 from = getParent(from);
1020 }
1021 var pathTo = [];
1022 while (true) {
1023 if (!to) {
1024 break;
1025 }
1026 if (to === common) {
1027 break;
1028 }
1029 var _alternate = to.alternate;
1030 if (_alternate !== null && _alternate === common) {
1031 break;
1032 }
1033 pathTo.push(to);
1034 to = getParent(to);
1035 }
1036 for (var i = 0; i < pathFrom.length; i++) {
1037 fn(pathFrom[i], 'bubbled', argFrom);
1038 }
1039 for (var _i = pathTo.length; _i-- > 0;) {
1040 fn(pathTo[_i], 'captured', argTo);
1041 }
1042}
1043
1044/**
1045 * Some event types have a notion of different registration names for different
1046 * "phases" of propagation. This finds listeners by a given phase.
1047 */
1048function listenerAtPhase(inst, event, propagationPhase) {
1049 var registrationName = event.dispatchConfig.phasedRegistrationNames[propagationPhase];
1050 return getListener(inst, registrationName);
1051}
1052
1053/**
1054 * A small set of propagation patterns, each of which will accept a small amount
1055 * of information, and generate a set of "dispatch ready event objects" - which
1056 * are sets of events that have already been annotated with a set of dispatched
1057 * listener functions/ids. The API is designed this way to discourage these
1058 * propagation strategies from actually executing the dispatches, since we
1059 * always want to collect the entire set of dispatches before executing even a
1060 * single one.
1061 */
1062
1063/**
1064 * Tags a `SyntheticEvent` with dispatched listeners. Creating this function
1065 * here, allows us to not have to bind or create functions for each event.
1066 * Mutating the event's members allows us to not have to create a wrapping
1067 * "dispatch" object that pairs the event with the listener.
1068 */
1069function accumulateDirectionalDispatches(inst, phase, event) {
1070 {
1071 !inst ? warningWithoutStack$1(false, 'Dispatching inst must not be null') : void 0;
1072 }
1073 var listener = listenerAtPhase(inst, event, phase);
1074 if (listener) {
1075 event._dispatchListeners = accumulateInto(event._dispatchListeners, listener);
1076 event._dispatchInstances = accumulateInto(event._dispatchInstances, inst);
1077 }
1078}
1079
1080/**
1081 * Collect dispatches (must be entirely collected before dispatching - see unit
1082 * tests). Lazily allocate the array to conserve memory. We must loop through
1083 * each event and perform the traversal for each one. We cannot perform a
1084 * single traversal for the entire collection of events because each event may
1085 * have a different target.
1086 */
1087function accumulateTwoPhaseDispatchesSingle(event) {
1088 if (event && event.dispatchConfig.phasedRegistrationNames) {
1089 traverseTwoPhase(event._targetInst, accumulateDirectionalDispatches, event);
1090 }
1091}
1092
1093/**
1094 * Accumulates without regard to direction, does not look for phased
1095 * registration names. Same as `accumulateDirectDispatchesSingle` but without
1096 * requiring that the `dispatchMarker` be the same as the dispatched ID.
1097 */
1098function accumulateDispatches(inst, ignoredDirection, event) {
1099 if (inst && event && event.dispatchConfig.registrationName) {
1100 var registrationName = event.dispatchConfig.registrationName;
1101 var listener = getListener(inst, registrationName);
1102 if (listener) {
1103 event._dispatchListeners = accumulateInto(event._dispatchListeners, listener);
1104 event._dispatchInstances = accumulateInto(event._dispatchInstances, inst);
1105 }
1106 }
1107}
1108
1109/**
1110 * Accumulates dispatches on an `SyntheticEvent`, but only for the
1111 * `dispatchMarker`.
1112 * @param {SyntheticEvent} event
1113 */
1114function accumulateDirectDispatchesSingle(event) {
1115 if (event && event.dispatchConfig.registrationName) {
1116 accumulateDispatches(event._targetInst, null, event);
1117 }
1118}
1119
1120function accumulateTwoPhaseDispatches(events) {
1121 forEachAccumulated(events, accumulateTwoPhaseDispatchesSingle);
1122}
1123
1124
1125
1126function accumulateEnterLeaveDispatches(leave, enter, from, to) {
1127 traverseEnterLeave(from, to, accumulateDispatches, leave, enter);
1128}
1129
1130function accumulateDirectDispatches(events) {
1131 forEachAccumulated(events, accumulateDirectDispatchesSingle);
1132}
1133
1134var canUseDOM = !!(typeof window !== 'undefined' && window.document && window.document.createElement);
1135
1136// Do not uses the below two methods directly!
1137// Instead use constants exported from DOMTopLevelEventTypes in ReactDOM.
1138// (It is the only module that is allowed to access these methods.)
1139
1140function unsafeCastStringToDOMTopLevelType(topLevelType) {
1141 return topLevelType;
1142}
1143
1144function unsafeCastDOMTopLevelTypeToString(topLevelType) {
1145 return topLevelType;
1146}
1147
1148/**
1149 * Generate a mapping of standard vendor prefixes using the defined style property and event name.
1150 *
1151 * @param {string} styleProp
1152 * @param {string} eventName
1153 * @returns {object}
1154 */
1155function makePrefixMap(styleProp, eventName) {
1156 var prefixes = {};
1157
1158 prefixes[styleProp.toLowerCase()] = eventName.toLowerCase();
1159 prefixes['Webkit' + styleProp] = 'webkit' + eventName;
1160 prefixes['Moz' + styleProp] = 'moz' + eventName;
1161
1162 return prefixes;
1163}
1164
1165/**
1166 * A list of event names to a configurable list of vendor prefixes.
1167 */
1168var vendorPrefixes = {
1169 animationend: makePrefixMap('Animation', 'AnimationEnd'),
1170 animationiteration: makePrefixMap('Animation', 'AnimationIteration'),
1171 animationstart: makePrefixMap('Animation', 'AnimationStart'),
1172 transitionend: makePrefixMap('Transition', 'TransitionEnd')
1173};
1174
1175/**
1176 * Event names that have already been detected and prefixed (if applicable).
1177 */
1178var prefixedEventNames = {};
1179
1180/**
1181 * Element to check for prefixes on.
1182 */
1183var style = {};
1184
1185/**
1186 * Bootstrap if a DOM exists.
1187 */
1188if (canUseDOM) {
1189 style = document.createElement('div').style;
1190
1191 // On some platforms, in particular some releases of Android 4.x,
1192 // the un-prefixed "animation" and "transition" properties are defined on the
1193 // style object but the events that fire will still be prefixed, so we need
1194 // to check if the un-prefixed events are usable, and if not remove them from the map.
1195 if (!('AnimationEvent' in window)) {
1196 delete vendorPrefixes.animationend.animation;
1197 delete vendorPrefixes.animationiteration.animation;
1198 delete vendorPrefixes.animationstart.animation;
1199 }
1200
1201 // Same as above
1202 if (!('TransitionEvent' in window)) {
1203 delete vendorPrefixes.transitionend.transition;
1204 }
1205}
1206
1207/**
1208 * Attempts to determine the correct vendor prefixed event name.
1209 *
1210 * @param {string} eventName
1211 * @returns {string}
1212 */
1213function getVendorPrefixedEventName(eventName) {
1214 if (prefixedEventNames[eventName]) {
1215 return prefixedEventNames[eventName];
1216 } else if (!vendorPrefixes[eventName]) {
1217 return eventName;
1218 }
1219
1220 var prefixMap = vendorPrefixes[eventName];
1221
1222 for (var styleProp in prefixMap) {
1223 if (prefixMap.hasOwnProperty(styleProp) && styleProp in style) {
1224 return prefixedEventNames[eventName] = prefixMap[styleProp];
1225 }
1226 }
1227
1228 return eventName;
1229}
1230
1231/**
1232 * To identify top level events in ReactDOM, we use constants defined by this
1233 * module. This is the only module that uses the unsafe* methods to express
1234 * that the constants actually correspond to the browser event names. This lets
1235 * us save some bundle size by avoiding a top level type -> event name map.
1236 * The rest of ReactDOM code should import top level types from this file.
1237 */
1238var TOP_ABORT = unsafeCastStringToDOMTopLevelType('abort');
1239var TOP_ANIMATION_END = unsafeCastStringToDOMTopLevelType(getVendorPrefixedEventName('animationend'));
1240var TOP_ANIMATION_ITERATION = unsafeCastStringToDOMTopLevelType(getVendorPrefixedEventName('animationiteration'));
1241var TOP_ANIMATION_START = unsafeCastStringToDOMTopLevelType(getVendorPrefixedEventName('animationstart'));
1242var TOP_BLUR = unsafeCastStringToDOMTopLevelType('blur');
1243var TOP_CAN_PLAY = unsafeCastStringToDOMTopLevelType('canplay');
1244var TOP_CAN_PLAY_THROUGH = unsafeCastStringToDOMTopLevelType('canplaythrough');
1245var TOP_CANCEL = unsafeCastStringToDOMTopLevelType('cancel');
1246var TOP_CHANGE = unsafeCastStringToDOMTopLevelType('change');
1247var TOP_CLICK = unsafeCastStringToDOMTopLevelType('click');
1248var TOP_CLOSE = unsafeCastStringToDOMTopLevelType('close');
1249var TOP_COMPOSITION_END = unsafeCastStringToDOMTopLevelType('compositionend');
1250var TOP_COMPOSITION_START = unsafeCastStringToDOMTopLevelType('compositionstart');
1251var TOP_COMPOSITION_UPDATE = unsafeCastStringToDOMTopLevelType('compositionupdate');
1252var TOP_CONTEXT_MENU = unsafeCastStringToDOMTopLevelType('contextmenu');
1253var TOP_COPY = unsafeCastStringToDOMTopLevelType('copy');
1254var TOP_CUT = unsafeCastStringToDOMTopLevelType('cut');
1255var TOP_DOUBLE_CLICK = unsafeCastStringToDOMTopLevelType('dblclick');
1256var TOP_AUX_CLICK = unsafeCastStringToDOMTopLevelType('auxclick');
1257var TOP_DRAG = unsafeCastStringToDOMTopLevelType('drag');
1258var TOP_DRAG_END = unsafeCastStringToDOMTopLevelType('dragend');
1259var TOP_DRAG_ENTER = unsafeCastStringToDOMTopLevelType('dragenter');
1260var TOP_DRAG_EXIT = unsafeCastStringToDOMTopLevelType('dragexit');
1261var TOP_DRAG_LEAVE = unsafeCastStringToDOMTopLevelType('dragleave');
1262var TOP_DRAG_OVER = unsafeCastStringToDOMTopLevelType('dragover');
1263var TOP_DRAG_START = unsafeCastStringToDOMTopLevelType('dragstart');
1264var TOP_DROP = unsafeCastStringToDOMTopLevelType('drop');
1265var TOP_DURATION_CHANGE = unsafeCastStringToDOMTopLevelType('durationchange');
1266var TOP_EMPTIED = unsafeCastStringToDOMTopLevelType('emptied');
1267var TOP_ENCRYPTED = unsafeCastStringToDOMTopLevelType('encrypted');
1268var TOP_ENDED = unsafeCastStringToDOMTopLevelType('ended');
1269var TOP_ERROR = unsafeCastStringToDOMTopLevelType('error');
1270var TOP_FOCUS = unsafeCastStringToDOMTopLevelType('focus');
1271var TOP_GOT_POINTER_CAPTURE = unsafeCastStringToDOMTopLevelType('gotpointercapture');
1272var TOP_INPUT = unsafeCastStringToDOMTopLevelType('input');
1273var TOP_INVALID = unsafeCastStringToDOMTopLevelType('invalid');
1274var TOP_KEY_DOWN = unsafeCastStringToDOMTopLevelType('keydown');
1275var TOP_KEY_PRESS = unsafeCastStringToDOMTopLevelType('keypress');
1276var TOP_KEY_UP = unsafeCastStringToDOMTopLevelType('keyup');
1277var TOP_LOAD = unsafeCastStringToDOMTopLevelType('load');
1278var TOP_LOAD_START = unsafeCastStringToDOMTopLevelType('loadstart');
1279var TOP_LOADED_DATA = unsafeCastStringToDOMTopLevelType('loadeddata');
1280var TOP_LOADED_METADATA = unsafeCastStringToDOMTopLevelType('loadedmetadata');
1281var TOP_LOST_POINTER_CAPTURE = unsafeCastStringToDOMTopLevelType('lostpointercapture');
1282var TOP_MOUSE_DOWN = unsafeCastStringToDOMTopLevelType('mousedown');
1283var TOP_MOUSE_MOVE = unsafeCastStringToDOMTopLevelType('mousemove');
1284var TOP_MOUSE_OUT = unsafeCastStringToDOMTopLevelType('mouseout');
1285var TOP_MOUSE_OVER = unsafeCastStringToDOMTopLevelType('mouseover');
1286var TOP_MOUSE_UP = unsafeCastStringToDOMTopLevelType('mouseup');
1287var TOP_PASTE = unsafeCastStringToDOMTopLevelType('paste');
1288var TOP_PAUSE = unsafeCastStringToDOMTopLevelType('pause');
1289var TOP_PLAY = unsafeCastStringToDOMTopLevelType('play');
1290var TOP_PLAYING = unsafeCastStringToDOMTopLevelType('playing');
1291var TOP_POINTER_CANCEL = unsafeCastStringToDOMTopLevelType('pointercancel');
1292var TOP_POINTER_DOWN = unsafeCastStringToDOMTopLevelType('pointerdown');
1293
1294
1295var TOP_POINTER_MOVE = unsafeCastStringToDOMTopLevelType('pointermove');
1296var TOP_POINTER_OUT = unsafeCastStringToDOMTopLevelType('pointerout');
1297var TOP_POINTER_OVER = unsafeCastStringToDOMTopLevelType('pointerover');
1298var TOP_POINTER_UP = unsafeCastStringToDOMTopLevelType('pointerup');
1299var TOP_PROGRESS = unsafeCastStringToDOMTopLevelType('progress');
1300var TOP_RATE_CHANGE = unsafeCastStringToDOMTopLevelType('ratechange');
1301var TOP_RESET = unsafeCastStringToDOMTopLevelType('reset');
1302var TOP_SCROLL = unsafeCastStringToDOMTopLevelType('scroll');
1303var TOP_SEEKED = unsafeCastStringToDOMTopLevelType('seeked');
1304var TOP_SEEKING = unsafeCastStringToDOMTopLevelType('seeking');
1305var TOP_SELECTION_CHANGE = unsafeCastStringToDOMTopLevelType('selectionchange');
1306var TOP_STALLED = unsafeCastStringToDOMTopLevelType('stalled');
1307var TOP_SUBMIT = unsafeCastStringToDOMTopLevelType('submit');
1308var TOP_SUSPEND = unsafeCastStringToDOMTopLevelType('suspend');
1309var TOP_TEXT_INPUT = unsafeCastStringToDOMTopLevelType('textInput');
1310var TOP_TIME_UPDATE = unsafeCastStringToDOMTopLevelType('timeupdate');
1311var TOP_TOGGLE = unsafeCastStringToDOMTopLevelType('toggle');
1312var TOP_TOUCH_CANCEL = unsafeCastStringToDOMTopLevelType('touchcancel');
1313var TOP_TOUCH_END = unsafeCastStringToDOMTopLevelType('touchend');
1314var TOP_TOUCH_MOVE = unsafeCastStringToDOMTopLevelType('touchmove');
1315var TOP_TOUCH_START = unsafeCastStringToDOMTopLevelType('touchstart');
1316var TOP_TRANSITION_END = unsafeCastStringToDOMTopLevelType(getVendorPrefixedEventName('transitionend'));
1317var TOP_VOLUME_CHANGE = unsafeCastStringToDOMTopLevelType('volumechange');
1318var TOP_WAITING = unsafeCastStringToDOMTopLevelType('waiting');
1319var TOP_WHEEL = unsafeCastStringToDOMTopLevelType('wheel');
1320
1321// List of events that need to be individually attached to media elements.
1322// Note that events in this list will *not* be listened to at the top level
1323// unless they're explicitly whitelisted in `ReactBrowserEventEmitter.listenTo`.
1324var 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];
1325
1326function getRawEventName(topLevelType) {
1327 return unsafeCastDOMTopLevelTypeToString(topLevelType);
1328}
1329
1330/**
1331 * These variables store information about text content of a target node,
1332 * allowing comparison of content before and after a given event.
1333 *
1334 * Identify the node where selection currently begins, then observe
1335 * both its text content and its current position in the DOM. Since the
1336 * browser may natively replace the target node during composition, we can
1337 * use its position to find its replacement.
1338 *
1339 *
1340 */
1341
1342var root = null;
1343var startText = null;
1344var fallbackText = null;
1345
1346function initialize(nativeEventTarget) {
1347 root = nativeEventTarget;
1348 startText = getText();
1349 return true;
1350}
1351
1352function reset() {
1353 root = null;
1354 startText = null;
1355 fallbackText = null;
1356}
1357
1358function getData() {
1359 if (fallbackText) {
1360 return fallbackText;
1361 }
1362
1363 var start = void 0;
1364 var startValue = startText;
1365 var startLength = startValue.length;
1366 var end = void 0;
1367 var endValue = getText();
1368 var endLength = endValue.length;
1369
1370 for (start = 0; start < startLength; start++) {
1371 if (startValue[start] !== endValue[start]) {
1372 break;
1373 }
1374 }
1375
1376 var minEnd = startLength - start;
1377 for (end = 1; end <= minEnd; end++) {
1378 if (startValue[startLength - end] !== endValue[endLength - end]) {
1379 break;
1380 }
1381 }
1382
1383 var sliceTail = end > 1 ? 1 - end : undefined;
1384 fallbackText = endValue.slice(start, sliceTail);
1385 return fallbackText;
1386}
1387
1388function getText() {
1389 if ('value' in root) {
1390 return root.value;
1391 }
1392 return root.textContent;
1393}
1394
1395var ReactInternals = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
1396
1397var _assign = ReactInternals.assign;
1398
1399/* eslint valid-typeof: 0 */
1400
1401var EVENT_POOL_SIZE = 10;
1402
1403/**
1404 * @interface Event
1405 * @see http://www.w3.org/TR/DOM-Level-3-Events/
1406 */
1407var EventInterface = {
1408 type: null,
1409 target: null,
1410 // currentTarget is set when dispatching; no use in copying it here
1411 currentTarget: function () {
1412 return null;
1413 },
1414 eventPhase: null,
1415 bubbles: null,
1416 cancelable: null,
1417 timeStamp: function (event) {
1418 return event.timeStamp || Date.now();
1419 },
1420 defaultPrevented: null,
1421 isTrusted: null
1422};
1423
1424function functionThatReturnsTrue() {
1425 return true;
1426}
1427
1428function functionThatReturnsFalse() {
1429 return false;
1430}
1431
1432/**
1433 * Synthetic events are dispatched by event plugins, typically in response to a
1434 * top-level event delegation handler.
1435 *
1436 * These systems should generally use pooling to reduce the frequency of garbage
1437 * collection. The system should check `isPersistent` to determine whether the
1438 * event should be released into the pool after being dispatched. Users that
1439 * need a persisted event should invoke `persist`.
1440 *
1441 * Synthetic events (and subclasses) implement the DOM Level 3 Events API by
1442 * normalizing browser quirks. Subclasses do not necessarily have to implement a
1443 * DOM interface; custom application-specific events can also subclass this.
1444 *
1445 * @param {object} dispatchConfig Configuration used to dispatch this event.
1446 * @param {*} targetInst Marker identifying the event target.
1447 * @param {object} nativeEvent Native browser event.
1448 * @param {DOMEventTarget} nativeEventTarget Target node.
1449 */
1450function SyntheticEvent(dispatchConfig, targetInst, nativeEvent, nativeEventTarget) {
1451 {
1452 // these have a getter/setter for warnings
1453 delete this.nativeEvent;
1454 delete this.preventDefault;
1455 delete this.stopPropagation;
1456 delete this.isDefaultPrevented;
1457 delete this.isPropagationStopped;
1458 }
1459
1460 this.dispatchConfig = dispatchConfig;
1461 this._targetInst = targetInst;
1462 this.nativeEvent = nativeEvent;
1463
1464 var Interface = this.constructor.Interface;
1465 for (var propName in Interface) {
1466 if (!Interface.hasOwnProperty(propName)) {
1467 continue;
1468 }
1469 {
1470 delete this[propName]; // this has a getter/setter for warnings
1471 }
1472 var normalize = Interface[propName];
1473 if (normalize) {
1474 this[propName] = normalize(nativeEvent);
1475 } else {
1476 if (propName === 'target') {
1477 this.target = nativeEventTarget;
1478 } else {
1479 this[propName] = nativeEvent[propName];
1480 }
1481 }
1482 }
1483
1484 var defaultPrevented = nativeEvent.defaultPrevented != null ? nativeEvent.defaultPrevented : nativeEvent.returnValue === false;
1485 if (defaultPrevented) {
1486 this.isDefaultPrevented = functionThatReturnsTrue;
1487 } else {
1488 this.isDefaultPrevented = functionThatReturnsFalse;
1489 }
1490 this.isPropagationStopped = functionThatReturnsFalse;
1491 return this;
1492}
1493
1494_assign(SyntheticEvent.prototype, {
1495 preventDefault: function () {
1496 this.defaultPrevented = true;
1497 var event = this.nativeEvent;
1498 if (!event) {
1499 return;
1500 }
1501
1502 if (event.preventDefault) {
1503 event.preventDefault();
1504 } else if (typeof event.returnValue !== 'unknown') {
1505 event.returnValue = false;
1506 }
1507 this.isDefaultPrevented = functionThatReturnsTrue;
1508 },
1509
1510 stopPropagation: function () {
1511 var event = this.nativeEvent;
1512 if (!event) {
1513 return;
1514 }
1515
1516 if (event.stopPropagation) {
1517 event.stopPropagation();
1518 } else if (typeof event.cancelBubble !== 'unknown') {
1519 // The ChangeEventPlugin registers a "propertychange" event for
1520 // IE. This event does not support bubbling or cancelling, and
1521 // any references to cancelBubble throw "Member not found". A
1522 // typeof check of "unknown" circumvents this issue (and is also
1523 // IE specific).
1524 event.cancelBubble = true;
1525 }
1526
1527 this.isPropagationStopped = functionThatReturnsTrue;
1528 },
1529
1530 /**
1531 * We release all dispatched `SyntheticEvent`s after each event loop, adding
1532 * them back into the pool. This allows a way to hold onto a reference that
1533 * won't be added back into the pool.
1534 */
1535 persist: function () {
1536 this.isPersistent = functionThatReturnsTrue;
1537 },
1538
1539 /**
1540 * Checks if this event should be released back into the pool.
1541 *
1542 * @return {boolean} True if this should not be released, false otherwise.
1543 */
1544 isPersistent: functionThatReturnsFalse,
1545
1546 /**
1547 * `PooledClass` looks for `destructor` on each instance it releases.
1548 */
1549 destructor: function () {
1550 var Interface = this.constructor.Interface;
1551 for (var propName in Interface) {
1552 {
1553 Object.defineProperty(this, propName, getPooledWarningPropertyDefinition(propName, Interface[propName]));
1554 }
1555 }
1556 this.dispatchConfig = null;
1557 this._targetInst = null;
1558 this.nativeEvent = null;
1559 this.isDefaultPrevented = functionThatReturnsFalse;
1560 this.isPropagationStopped = functionThatReturnsFalse;
1561 this._dispatchListeners = null;
1562 this._dispatchInstances = null;
1563 {
1564 Object.defineProperty(this, 'nativeEvent', getPooledWarningPropertyDefinition('nativeEvent', null));
1565 Object.defineProperty(this, 'isDefaultPrevented', getPooledWarningPropertyDefinition('isDefaultPrevented', functionThatReturnsFalse));
1566 Object.defineProperty(this, 'isPropagationStopped', getPooledWarningPropertyDefinition('isPropagationStopped', functionThatReturnsFalse));
1567 Object.defineProperty(this, 'preventDefault', getPooledWarningPropertyDefinition('preventDefault', function () {}));
1568 Object.defineProperty(this, 'stopPropagation', getPooledWarningPropertyDefinition('stopPropagation', function () {}));
1569 }
1570 }
1571});
1572
1573SyntheticEvent.Interface = EventInterface;
1574
1575/**
1576 * Helper to reduce boilerplate when creating subclasses.
1577 */
1578SyntheticEvent.extend = function (Interface) {
1579 var Super = this;
1580
1581 var E = function () {};
1582 E.prototype = Super.prototype;
1583 var prototype = new E();
1584
1585 function Class() {
1586 return Super.apply(this, arguments);
1587 }
1588 _assign(prototype, Class.prototype);
1589 Class.prototype = prototype;
1590 Class.prototype.constructor = Class;
1591
1592 Class.Interface = _assign({}, Super.Interface, Interface);
1593 Class.extend = Super.extend;
1594 addEventPoolingTo(Class);
1595
1596 return Class;
1597};
1598
1599addEventPoolingTo(SyntheticEvent);
1600
1601/**
1602 * Helper to nullify syntheticEvent instance properties when destructing
1603 *
1604 * @param {String} propName
1605 * @param {?object} getVal
1606 * @return {object} defineProperty object
1607 */
1608function getPooledWarningPropertyDefinition(propName, getVal) {
1609 var isFunction = typeof getVal === 'function';
1610 return {
1611 configurable: true,
1612 set: set,
1613 get: get
1614 };
1615
1616 function set(val) {
1617 var action = isFunction ? 'setting the method' : 'setting the property';
1618 warn(action, 'This is effectively a no-op');
1619 return val;
1620 }
1621
1622 function get() {
1623 var action = isFunction ? 'accessing the method' : 'accessing the property';
1624 var result = isFunction ? 'This is a no-op function' : 'This is set to null';
1625 warn(action, result);
1626 return getVal;
1627 }
1628
1629 function warn(action, result) {
1630 var warningCondition = false;
1631 !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;
1632 }
1633}
1634
1635function getPooledEvent(dispatchConfig, targetInst, nativeEvent, nativeInst) {
1636 var EventConstructor = this;
1637 if (EventConstructor.eventPool.length) {
1638 var instance = EventConstructor.eventPool.pop();
1639 EventConstructor.call(instance, dispatchConfig, targetInst, nativeEvent, nativeInst);
1640 return instance;
1641 }
1642 return new EventConstructor(dispatchConfig, targetInst, nativeEvent, nativeInst);
1643}
1644
1645function releasePooledEvent(event) {
1646 var EventConstructor = this;
1647 !(event instanceof EventConstructor) ? invariant(false, 'Trying to release an event instance into a pool of a different type.') : void 0;
1648 event.destructor();
1649 if (EventConstructor.eventPool.length < EVENT_POOL_SIZE) {
1650 EventConstructor.eventPool.push(event);
1651 }
1652}
1653
1654function addEventPoolingTo(EventConstructor) {
1655 EventConstructor.eventPool = [];
1656 EventConstructor.getPooled = getPooledEvent;
1657 EventConstructor.release = releasePooledEvent;
1658}
1659
1660/**
1661 * @interface Event
1662 * @see http://www.w3.org/TR/DOM-Level-3-Events/#events-compositionevents
1663 */
1664var SyntheticCompositionEvent = SyntheticEvent.extend({
1665 data: null
1666});
1667
1668/**
1669 * @interface Event
1670 * @see http://www.w3.org/TR/2013/WD-DOM-Level-3-Events-20131105
1671 * /#events-inputevents
1672 */
1673var SyntheticInputEvent = SyntheticEvent.extend({
1674 data: null
1675});
1676
1677var END_KEYCODES = [9, 13, 27, 32]; // Tab, Return, Esc, Space
1678var START_KEYCODE = 229;
1679
1680var canUseCompositionEvent = canUseDOM && 'CompositionEvent' in window;
1681
1682var documentMode = null;
1683if (canUseDOM && 'documentMode' in document) {
1684 documentMode = document.documentMode;
1685}
1686
1687// Webkit offers a very useful `textInput` event that can be used to
1688// directly represent `beforeInput`. The IE `textinput` event is not as
1689// useful, so we don't use it.
1690var canUseTextInputEvent = canUseDOM && 'TextEvent' in window && !documentMode;
1691
1692// In IE9+, we have access to composition events, but the data supplied
1693// by the native compositionend event may be incorrect. Japanese ideographic
1694// spaces, for instance (\u3000) are not recorded correctly.
1695var useFallbackCompositionData = canUseDOM && (!canUseCompositionEvent || documentMode && documentMode > 8 && documentMode <= 11);
1696
1697var SPACEBAR_CODE = 32;
1698var SPACEBAR_CHAR = String.fromCharCode(SPACEBAR_CODE);
1699
1700// Events and their corresponding property names.
1701var eventTypes = {
1702 beforeInput: {
1703 phasedRegistrationNames: {
1704 bubbled: 'onBeforeInput',
1705 captured: 'onBeforeInputCapture'
1706 },
1707 dependencies: [TOP_COMPOSITION_END, TOP_KEY_PRESS, TOP_TEXT_INPUT, TOP_PASTE]
1708 },
1709 compositionEnd: {
1710 phasedRegistrationNames: {
1711 bubbled: 'onCompositionEnd',
1712 captured: 'onCompositionEndCapture'
1713 },
1714 dependencies: [TOP_BLUR, TOP_COMPOSITION_END, TOP_KEY_DOWN, TOP_KEY_PRESS, TOP_KEY_UP, TOP_MOUSE_DOWN]
1715 },
1716 compositionStart: {
1717 phasedRegistrationNames: {
1718 bubbled: 'onCompositionStart',
1719 captured: 'onCompositionStartCapture'
1720 },
1721 dependencies: [TOP_BLUR, TOP_COMPOSITION_START, TOP_KEY_DOWN, TOP_KEY_PRESS, TOP_KEY_UP, TOP_MOUSE_DOWN]
1722 },
1723 compositionUpdate: {
1724 phasedRegistrationNames: {
1725 bubbled: 'onCompositionUpdate',
1726 captured: 'onCompositionUpdateCapture'
1727 },
1728 dependencies: [TOP_BLUR, TOP_COMPOSITION_UPDATE, TOP_KEY_DOWN, TOP_KEY_PRESS, TOP_KEY_UP, TOP_MOUSE_DOWN]
1729 }
1730};
1731
1732// Track whether we've ever handled a keypress on the space key.
1733var hasSpaceKeypress = false;
1734
1735/**
1736 * Return whether a native keypress event is assumed to be a command.
1737 * This is required because Firefox fires `keypress` events for key commands
1738 * (cut, copy, select-all, etc.) even though no character is inserted.
1739 */
1740function isKeypressCommand(nativeEvent) {
1741 return (nativeEvent.ctrlKey || nativeEvent.altKey || nativeEvent.metaKey) &&
1742 // ctrlKey && altKey is equivalent to AltGr, and is not a command.
1743 !(nativeEvent.ctrlKey && nativeEvent.altKey);
1744}
1745
1746/**
1747 * Translate native top level events into event types.
1748 *
1749 * @param {string} topLevelType
1750 * @return {object}
1751 */
1752function getCompositionEventType(topLevelType) {
1753 switch (topLevelType) {
1754 case TOP_COMPOSITION_START:
1755 return eventTypes.compositionStart;
1756 case TOP_COMPOSITION_END:
1757 return eventTypes.compositionEnd;
1758 case TOP_COMPOSITION_UPDATE:
1759 return eventTypes.compositionUpdate;
1760 }
1761}
1762
1763/**
1764 * Does our fallback best-guess model think this event signifies that
1765 * composition has begun?
1766 *
1767 * @param {string} topLevelType
1768 * @param {object} nativeEvent
1769 * @return {boolean}
1770 */
1771function isFallbackCompositionStart(topLevelType, nativeEvent) {
1772 return topLevelType === TOP_KEY_DOWN && nativeEvent.keyCode === START_KEYCODE;
1773}
1774
1775/**
1776 * Does our fallback mode think that this event is the end of composition?
1777 *
1778 * @param {string} topLevelType
1779 * @param {object} nativeEvent
1780 * @return {boolean}
1781 */
1782function isFallbackCompositionEnd(topLevelType, nativeEvent) {
1783 switch (topLevelType) {
1784 case TOP_KEY_UP:
1785 // Command keys insert or clear IME input.
1786 return END_KEYCODES.indexOf(nativeEvent.keyCode) !== -1;
1787 case TOP_KEY_DOWN:
1788 // Expect IME keyCode on each keydown. If we get any other
1789 // code we must have exited earlier.
1790 return nativeEvent.keyCode !== START_KEYCODE;
1791 case TOP_KEY_PRESS:
1792 case TOP_MOUSE_DOWN:
1793 case TOP_BLUR:
1794 // Events are not possible without cancelling IME.
1795 return true;
1796 default:
1797 return false;
1798 }
1799}
1800
1801/**
1802 * Google Input Tools provides composition data via a CustomEvent,
1803 * with the `data` property populated in the `detail` object. If this
1804 * is available on the event object, use it. If not, this is a plain
1805 * composition event and we have nothing special to extract.
1806 *
1807 * @param {object} nativeEvent
1808 * @return {?string}
1809 */
1810function getDataFromCustomEvent(nativeEvent) {
1811 var detail = nativeEvent.detail;
1812 if (typeof detail === 'object' && 'data' in detail) {
1813 return detail.data;
1814 }
1815 return null;
1816}
1817
1818/**
1819 * Check if a composition event was triggered by Korean IME.
1820 * Our fallback mode does not work well with IE's Korean IME,
1821 * so just use native composition events when Korean IME is used.
1822 * Although CompositionEvent.locale property is deprecated,
1823 * it is available in IE, where our fallback mode is enabled.
1824 *
1825 * @param {object} nativeEvent
1826 * @return {boolean}
1827 */
1828function isUsingKoreanIME(nativeEvent) {
1829 return nativeEvent.locale === 'ko';
1830}
1831
1832// Track the current IME composition status, if any.
1833var isComposing = false;
1834
1835/**
1836 * @return {?object} A SyntheticCompositionEvent.
1837 */
1838function extractCompositionEvent(topLevelType, targetInst, nativeEvent, nativeEventTarget) {
1839 var eventType = void 0;
1840 var fallbackData = void 0;
1841
1842 if (canUseCompositionEvent) {
1843 eventType = getCompositionEventType(topLevelType);
1844 } else if (!isComposing) {
1845 if (isFallbackCompositionStart(topLevelType, nativeEvent)) {
1846 eventType = eventTypes.compositionStart;
1847 }
1848 } else if (isFallbackCompositionEnd(topLevelType, nativeEvent)) {
1849 eventType = eventTypes.compositionEnd;
1850 }
1851
1852 if (!eventType) {
1853 return null;
1854 }
1855
1856 if (useFallbackCompositionData && !isUsingKoreanIME(nativeEvent)) {
1857 // The current composition is stored statically and must not be
1858 // overwritten while composition continues.
1859 if (!isComposing && eventType === eventTypes.compositionStart) {
1860 isComposing = initialize(nativeEventTarget);
1861 } else if (eventType === eventTypes.compositionEnd) {
1862 if (isComposing) {
1863 fallbackData = getData();
1864 }
1865 }
1866 }
1867
1868 var event = SyntheticCompositionEvent.getPooled(eventType, targetInst, nativeEvent, nativeEventTarget);
1869
1870 if (fallbackData) {
1871 // Inject data generated from fallback path into the synthetic event.
1872 // This matches the property of native CompositionEventInterface.
1873 event.data = fallbackData;
1874 } else {
1875 var customData = getDataFromCustomEvent(nativeEvent);
1876 if (customData !== null) {
1877 event.data = customData;
1878 }
1879 }
1880
1881 accumulateTwoPhaseDispatches(event);
1882 return event;
1883}
1884
1885/**
1886 * @param {TopLevelType} topLevelType Number from `TopLevelType`.
1887 * @param {object} nativeEvent Native browser event.
1888 * @return {?string} The string corresponding to this `beforeInput` event.
1889 */
1890function getNativeBeforeInputChars(topLevelType, nativeEvent) {
1891 switch (topLevelType) {
1892 case TOP_COMPOSITION_END:
1893 return getDataFromCustomEvent(nativeEvent);
1894 case TOP_KEY_PRESS:
1895 /**
1896 * If native `textInput` events are available, our goal is to make
1897 * use of them. However, there is a special case: the spacebar key.
1898 * In Webkit, preventing default on a spacebar `textInput` event
1899 * cancels character insertion, but it *also* causes the browser
1900 * to fall back to its default spacebar behavior of scrolling the
1901 * page.
1902 *
1903 * Tracking at:
1904 * https://code.google.com/p/chromium/issues/detail?id=355103
1905 *
1906 * To avoid this issue, use the keypress event as if no `textInput`
1907 * event is available.
1908 */
1909 var which = nativeEvent.which;
1910 if (which !== SPACEBAR_CODE) {
1911 return null;
1912 }
1913
1914 hasSpaceKeypress = true;
1915 return SPACEBAR_CHAR;
1916
1917 case TOP_TEXT_INPUT:
1918 // Record the characters to be added to the DOM.
1919 var chars = nativeEvent.data;
1920
1921 // If it's a spacebar character, assume that we have already handled
1922 // it at the keypress level and bail immediately. Android Chrome
1923 // doesn't give us keycodes, so we need to ignore it.
1924 if (chars === SPACEBAR_CHAR && hasSpaceKeypress) {
1925 return null;
1926 }
1927
1928 return chars;
1929
1930 default:
1931 // For other native event types, do nothing.
1932 return null;
1933 }
1934}
1935
1936/**
1937 * For browsers that do not provide the `textInput` event, extract the
1938 * appropriate string to use for SyntheticInputEvent.
1939 *
1940 * @param {number} topLevelType Number from `TopLevelEventTypes`.
1941 * @param {object} nativeEvent Native browser event.
1942 * @return {?string} The fallback string for this `beforeInput` event.
1943 */
1944function getFallbackBeforeInputChars(topLevelType, nativeEvent) {
1945 // If we are currently composing (IME) and using a fallback to do so,
1946 // try to extract the composed characters from the fallback object.
1947 // If composition event is available, we extract a string only at
1948 // compositionevent, otherwise extract it at fallback events.
1949 if (isComposing) {
1950 if (topLevelType === TOP_COMPOSITION_END || !canUseCompositionEvent && isFallbackCompositionEnd(topLevelType, nativeEvent)) {
1951 var chars = getData();
1952 reset();
1953 isComposing = false;
1954 return chars;
1955 }
1956 return null;
1957 }
1958
1959 switch (topLevelType) {
1960 case TOP_PASTE:
1961 // If a paste event occurs after a keypress, throw out the input
1962 // chars. Paste events should not lead to BeforeInput events.
1963 return null;
1964 case TOP_KEY_PRESS:
1965 /**
1966 * As of v27, Firefox may fire keypress events even when no character
1967 * will be inserted. A few possibilities:
1968 *
1969 * - `which` is `0`. Arrow keys, Esc key, etc.
1970 *
1971 * - `which` is the pressed key code, but no char is available.
1972 * Ex: 'AltGr + d` in Polish. There is no modified character for
1973 * this key combination and no character is inserted into the
1974 * document, but FF fires the keypress for char code `100` anyway.
1975 * No `input` event will occur.
1976 *
1977 * - `which` is the pressed key code, but a command combination is
1978 * being used. Ex: `Cmd+C`. No character is inserted, and no
1979 * `input` event will occur.
1980 */
1981 if (!isKeypressCommand(nativeEvent)) {
1982 // IE fires the `keypress` event when a user types an emoji via
1983 // Touch keyboard of Windows. In such a case, the `char` property
1984 // holds an emoji character like `\uD83D\uDE0A`. Because its length
1985 // is 2, the property `which` does not represent an emoji correctly.
1986 // In such a case, we directly return the `char` property instead of
1987 // using `which`.
1988 if (nativeEvent.char && nativeEvent.char.length > 1) {
1989 return nativeEvent.char;
1990 } else if (nativeEvent.which) {
1991 return String.fromCharCode(nativeEvent.which);
1992 }
1993 }
1994 return null;
1995 case TOP_COMPOSITION_END:
1996 return useFallbackCompositionData && !isUsingKoreanIME(nativeEvent) ? null : nativeEvent.data;
1997 default:
1998 return null;
1999 }
2000}
2001
2002/**
2003 * Extract a SyntheticInputEvent for `beforeInput`, based on either native
2004 * `textInput` or fallback behavior.
2005 *
2006 * @return {?object} A SyntheticInputEvent.
2007 */
2008function extractBeforeInputEvent(topLevelType, targetInst, nativeEvent, nativeEventTarget) {
2009 var chars = void 0;
2010
2011 if (canUseTextInputEvent) {
2012 chars = getNativeBeforeInputChars(topLevelType, nativeEvent);
2013 } else {
2014 chars = getFallbackBeforeInputChars(topLevelType, nativeEvent);
2015 }
2016
2017 // If no characters are being inserted, no BeforeInput event should
2018 // be fired.
2019 if (!chars) {
2020 return null;
2021 }
2022
2023 var event = SyntheticInputEvent.getPooled(eventTypes.beforeInput, targetInst, nativeEvent, nativeEventTarget);
2024
2025 event.data = chars;
2026 accumulateTwoPhaseDispatches(event);
2027 return event;
2028}
2029
2030/**
2031 * Create an `onBeforeInput` event to match
2032 * http://www.w3.org/TR/2013/WD-DOM-Level-3-Events-20131105/#events-inputevents.
2033 *
2034 * This event plugin is based on the native `textInput` event
2035 * available in Chrome, Safari, Opera, and IE. This event fires after
2036 * `onKeyPress` and `onCompositionEnd`, but before `onInput`.
2037 *
2038 * `beforeInput` is spec'd but not implemented in any browsers, and
2039 * the `input` event does not provide any useful information about what has
2040 * actually been added, contrary to the spec. Thus, `textInput` is the best
2041 * available event to identify the characters that have actually been inserted
2042 * into the target node.
2043 *
2044 * This plugin is also responsible for emitting `composition` events, thus
2045 * allowing us to share composition fallback code for both `beforeInput` and
2046 * `composition` event types.
2047 */
2048var BeforeInputEventPlugin = {
2049 eventTypes: eventTypes,
2050
2051 extractEvents: function (topLevelType, targetInst, nativeEvent, nativeEventTarget) {
2052 var composition = extractCompositionEvent(topLevelType, targetInst, nativeEvent, nativeEventTarget);
2053
2054 var beforeInput = extractBeforeInputEvent(topLevelType, targetInst, nativeEvent, nativeEventTarget);
2055
2056 if (composition === null) {
2057 return beforeInput;
2058 }
2059
2060 if (beforeInput === null) {
2061 return composition;
2062 }
2063
2064 return [composition, beforeInput];
2065 }
2066};
2067
2068// Use to restore controlled state after a change event has fired.
2069
2070var restoreImpl = null;
2071var restoreTarget = null;
2072var restoreQueue = null;
2073
2074function restoreStateOfTarget(target) {
2075 // We perform this translation at the end of the event loop so that we
2076 // always receive the correct fiber here
2077 var internalInstance = getInstanceFromNode(target);
2078 if (!internalInstance) {
2079 // Unmounted
2080 return;
2081 }
2082 !(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;
2083 var props = getFiberCurrentPropsFromNode(internalInstance.stateNode);
2084 restoreImpl(internalInstance.stateNode, internalInstance.type, props);
2085}
2086
2087function setRestoreImplementation(impl) {
2088 restoreImpl = impl;
2089}
2090
2091function enqueueStateRestore(target) {
2092 if (restoreTarget) {
2093 if (restoreQueue) {
2094 restoreQueue.push(target);
2095 } else {
2096 restoreQueue = [target];
2097 }
2098 } else {
2099 restoreTarget = target;
2100 }
2101}
2102
2103function needsStateRestore() {
2104 return restoreTarget !== null || restoreQueue !== null;
2105}
2106
2107function restoreStateIfNeeded() {
2108 if (!restoreTarget) {
2109 return;
2110 }
2111 var target = restoreTarget;
2112 var queuedTargets = restoreQueue;
2113 restoreTarget = null;
2114 restoreQueue = null;
2115
2116 restoreStateOfTarget(target);
2117 if (queuedTargets) {
2118 for (var i = 0; i < queuedTargets.length; i++) {
2119 restoreStateOfTarget(queuedTargets[i]);
2120 }
2121 }
2122}
2123
2124// Used as a way to call batchedUpdates when we don't have a reference to
2125// the renderer. Such as when we're dispatching events or if third party
2126// libraries need to call batchedUpdates. Eventually, this API will go away when
2127// everything is batched by default. We'll then have a similar API to opt-out of
2128// scheduled work and instead do synchronous work.
2129
2130// Defaults
2131var _batchedUpdatesImpl = function (fn, bookkeeping) {
2132 return fn(bookkeeping);
2133};
2134var _interactiveUpdatesImpl = function (fn, a, b) {
2135 return fn(a, b);
2136};
2137var _flushInteractiveUpdatesImpl = function () {};
2138
2139var isBatching = false;
2140function batchedUpdates(fn, bookkeeping) {
2141 if (isBatching) {
2142 // If we are currently inside another batch, we need to wait until it
2143 // fully completes before restoring state.
2144 return fn(bookkeeping);
2145 }
2146 isBatching = true;
2147 try {
2148 return _batchedUpdatesImpl(fn, bookkeeping);
2149 } finally {
2150 // Here we wait until all updates have propagated, which is important
2151 // when using controlled components within layers:
2152 // https://github.com/facebook/react/issues/1698
2153 // Then we restore state of any controlled component.
2154 isBatching = false;
2155 var controlledComponentsHavePendingUpdates = needsStateRestore();
2156 if (controlledComponentsHavePendingUpdates) {
2157 // If a controlled event was fired, we may need to restore the state of
2158 // the DOM node back to the controlled value. This is necessary when React
2159 // bails out of the update without touching the DOM.
2160 _flushInteractiveUpdatesImpl();
2161 restoreStateIfNeeded();
2162 }
2163 }
2164}
2165
2166function interactiveUpdates(fn, a, b) {
2167 return _interactiveUpdatesImpl(fn, a, b);
2168}
2169
2170
2171
2172function setBatchingImplementation(batchedUpdatesImpl, interactiveUpdatesImpl, flushInteractiveUpdatesImpl) {
2173 _batchedUpdatesImpl = batchedUpdatesImpl;
2174 _interactiveUpdatesImpl = interactiveUpdatesImpl;
2175 _flushInteractiveUpdatesImpl = flushInteractiveUpdatesImpl;
2176}
2177
2178/**
2179 * @see http://www.whatwg.org/specs/web-apps/current-work/multipage/the-input-element.html#input-type-attr-summary
2180 */
2181var supportedInputTypes = {
2182 color: true,
2183 date: true,
2184 datetime: true,
2185 'datetime-local': true,
2186 email: true,
2187 month: true,
2188 number: true,
2189 password: true,
2190 range: true,
2191 search: true,
2192 tel: true,
2193 text: true,
2194 time: true,
2195 url: true,
2196 week: true
2197};
2198
2199function isTextInputElement(elem) {
2200 var nodeName = elem && elem.nodeName && elem.nodeName.toLowerCase();
2201
2202 if (nodeName === 'input') {
2203 return !!supportedInputTypes[elem.type];
2204 }
2205
2206 if (nodeName === 'textarea') {
2207 return true;
2208 }
2209
2210 return false;
2211}
2212
2213/**
2214 * HTML nodeType values that represent the type of the node
2215 */
2216
2217var ELEMENT_NODE = 1;
2218var TEXT_NODE = 3;
2219var COMMENT_NODE = 8;
2220var DOCUMENT_NODE = 9;
2221var DOCUMENT_FRAGMENT_NODE = 11;
2222
2223/**
2224 * Gets the target node from a native browser event by accounting for
2225 * inconsistencies in browser DOM APIs.
2226 *
2227 * @param {object} nativeEvent Native browser event.
2228 * @return {DOMEventTarget} Target node.
2229 */
2230function getEventTarget(nativeEvent) {
2231 // Fallback to nativeEvent.srcElement for IE9
2232 // https://github.com/facebook/react/issues/12506
2233 var target = nativeEvent.target || nativeEvent.srcElement || window;
2234
2235 // Normalize SVG <use> element events #4963
2236 if (target.correspondingUseElement) {
2237 target = target.correspondingUseElement;
2238 }
2239
2240 // Safari may fire events on text nodes (Node.TEXT_NODE is 3).
2241 // @see http://www.quirksmode.org/js/events_properties.html
2242 return target.nodeType === TEXT_NODE ? target.parentNode : target;
2243}
2244
2245/**
2246 * Checks if an event is supported in the current execution environment.
2247 *
2248 * NOTE: This will not work correctly for non-generic events such as `change`,
2249 * `reset`, `load`, `error`, and `select`.
2250 *
2251 * Borrows from Modernizr.
2252 *
2253 * @param {string} eventNameSuffix Event name, e.g. "click".
2254 * @return {boolean} True if the event is supported.
2255 * @internal
2256 * @license Modernizr 3.0.0pre (Custom Build) | MIT
2257 */
2258function isEventSupported(eventNameSuffix) {
2259 if (!canUseDOM) {
2260 return false;
2261 }
2262
2263 var eventName = 'on' + eventNameSuffix;
2264 var isSupported = eventName in document;
2265
2266 if (!isSupported) {
2267 var element = document.createElement('div');
2268 element.setAttribute(eventName, 'return;');
2269 isSupported = typeof element[eventName] === 'function';
2270 }
2271
2272 return isSupported;
2273}
2274
2275function isCheckable(elem) {
2276 var type = elem.type;
2277 var nodeName = elem.nodeName;
2278 return nodeName && nodeName.toLowerCase() === 'input' && (type === 'checkbox' || type === 'radio');
2279}
2280
2281function getTracker(node) {
2282 return node._valueTracker;
2283}
2284
2285function detachTracker(node) {
2286 node._valueTracker = null;
2287}
2288
2289function getValueFromNode(node) {
2290 var value = '';
2291 if (!node) {
2292 return value;
2293 }
2294
2295 if (isCheckable(node)) {
2296 value = node.checked ? 'true' : 'false';
2297 } else {
2298 value = node.value;
2299 }
2300
2301 return value;
2302}
2303
2304function trackValueOnNode(node) {
2305 var valueField = isCheckable(node) ? 'checked' : 'value';
2306 var descriptor = Object.getOwnPropertyDescriptor(node.constructor.prototype, valueField);
2307
2308 var currentValue = '' + node[valueField];
2309
2310 // if someone has already defined a value or Safari, then bail
2311 // and don't track value will cause over reporting of changes,
2312 // but it's better then a hard failure
2313 // (needed for certain tests that spyOn input values and Safari)
2314 if (node.hasOwnProperty(valueField) || typeof descriptor === 'undefined' || typeof descriptor.get !== 'function' || typeof descriptor.set !== 'function') {
2315 return;
2316 }
2317 var get = descriptor.get,
2318 set = descriptor.set;
2319
2320 Object.defineProperty(node, valueField, {
2321 configurable: true,
2322 get: function () {
2323 return get.call(this);
2324 },
2325 set: function (value) {
2326 currentValue = '' + value;
2327 set.call(this, value);
2328 }
2329 });
2330 // We could've passed this the first time
2331 // but it triggers a bug in IE11 and Edge 14/15.
2332 // Calling defineProperty() again should be equivalent.
2333 // https://github.com/facebook/react/issues/11768
2334 Object.defineProperty(node, valueField, {
2335 enumerable: descriptor.enumerable
2336 });
2337
2338 var tracker = {
2339 getValue: function () {
2340 return currentValue;
2341 },
2342 setValue: function (value) {
2343 currentValue = '' + value;
2344 },
2345 stopTracking: function () {
2346 detachTracker(node);
2347 delete node[valueField];
2348 }
2349 };
2350 return tracker;
2351}
2352
2353function track(node) {
2354 if (getTracker(node)) {
2355 return;
2356 }
2357
2358 // TODO: Once it's just Fiber we can move this to node._wrapperState
2359 node._valueTracker = trackValueOnNode(node);
2360}
2361
2362function updateValueIfChanged(node) {
2363 if (!node) {
2364 return false;
2365 }
2366
2367 var tracker = getTracker(node);
2368 // if there is no tracker at this point it's unlikely
2369 // that trying again will succeed
2370 if (!tracker) {
2371 return true;
2372 }
2373
2374 var lastValue = tracker.getValue();
2375 var nextValue = getValueFromNode(node);
2376 if (nextValue !== lastValue) {
2377 tracker.setValue(nextValue);
2378 return true;
2379 }
2380 return false;
2381}
2382
2383var ReactSharedInternals = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
2384
2385var BEFORE_SLASH_RE = /^(.*)[\\\/]/;
2386
2387var describeComponentFrame = function (name, source, ownerName) {
2388 var sourceInfo = '';
2389 if (source) {
2390 var path = source.fileName;
2391 var fileName = path.replace(BEFORE_SLASH_RE, '');
2392 {
2393 // In DEV, include code for a common special case:
2394 // prefer "folder/index.js" instead of just "index.js".
2395 if (/^index\./.test(fileName)) {
2396 var match = path.match(BEFORE_SLASH_RE);
2397 if (match) {
2398 var pathBeforeSlash = match[1];
2399 if (pathBeforeSlash) {
2400 var folderName = pathBeforeSlash.replace(BEFORE_SLASH_RE, '');
2401 fileName = folderName + '/' + fileName;
2402 }
2403 }
2404 }
2405 }
2406 sourceInfo = ' (at ' + fileName + ':' + source.lineNumber + ')';
2407 } else if (ownerName) {
2408 sourceInfo = ' (created by ' + ownerName + ')';
2409 }
2410 return '\n in ' + (name || 'Unknown') + sourceInfo;
2411};
2412
2413// The Symbol used to tag the ReactElement-like types. If there is no native Symbol
2414// nor polyfill, then a plain number is used for performance.
2415var hasSymbol = typeof Symbol === 'function' && Symbol.for;
2416
2417var REACT_ELEMENT_TYPE = hasSymbol ? Symbol.for('react.element') : 0xeac7;
2418var REACT_PORTAL_TYPE = hasSymbol ? Symbol.for('react.portal') : 0xeaca;
2419var REACT_FRAGMENT_TYPE = hasSymbol ? Symbol.for('react.fragment') : 0xeacb;
2420var REACT_STRICT_MODE_TYPE = hasSymbol ? Symbol.for('react.strict_mode') : 0xeacc;
2421var REACT_PROFILER_TYPE = hasSymbol ? Symbol.for('react.profiler') : 0xead2;
2422var REACT_PROVIDER_TYPE = hasSymbol ? Symbol.for('react.provider') : 0xeacd;
2423var REACT_CONTEXT_TYPE = hasSymbol ? Symbol.for('react.context') : 0xeace;
2424
2425var REACT_CONCURRENT_MODE_TYPE = hasSymbol ? Symbol.for('react.concurrent_mode') : 0xeacf;
2426var REACT_FORWARD_REF_TYPE = hasSymbol ? Symbol.for('react.forward_ref') : 0xead0;
2427var REACT_SUSPENSE_TYPE = hasSymbol ? Symbol.for('react.suspense') : 0xead1;
2428var REACT_MEMO_TYPE = hasSymbol ? Symbol.for('react.memo') : 0xead3;
2429var REACT_LAZY_TYPE = hasSymbol ? Symbol.for('react.lazy') : 0xead4;
2430
2431var MAYBE_ITERATOR_SYMBOL = typeof Symbol === 'function' && Symbol.iterator;
2432var FAUX_ITERATOR_SYMBOL = '@@iterator';
2433
2434function getIteratorFn(maybeIterable) {
2435 if (maybeIterable === null || typeof maybeIterable !== 'object') {
2436 return null;
2437 }
2438 var maybeIterator = MAYBE_ITERATOR_SYMBOL && maybeIterable[MAYBE_ITERATOR_SYMBOL] || maybeIterable[FAUX_ITERATOR_SYMBOL];
2439 if (typeof maybeIterator === 'function') {
2440 return maybeIterator;
2441 }
2442 return null;
2443}
2444
2445var Pending = 0;
2446var Resolved = 1;
2447var Rejected = 2;
2448
2449function refineResolvedLazyComponent(lazyComponent) {
2450 return lazyComponent._status === Resolved ? lazyComponent._result : null;
2451}
2452
2453function getWrappedName(outerType, innerType, wrapperName) {
2454 var functionName = innerType.displayName || innerType.name || '';
2455 return outerType.displayName || (functionName !== '' ? wrapperName + '(' + functionName + ')' : wrapperName);
2456}
2457
2458function getComponentName(type) {
2459 if (type == null) {
2460 // Host root, text node or just invalid type.
2461 return null;
2462 }
2463 {
2464 if (typeof type.tag === 'number') {
2465 warningWithoutStack$1(false, 'Received an unexpected object in getComponentName(). ' + 'This is likely a bug in React. Please file an issue.');
2466 }
2467 }
2468 if (typeof type === 'function') {
2469 return type.displayName || type.name || null;
2470 }
2471 if (typeof type === 'string') {
2472 return type;
2473 }
2474 switch (type) {
2475 case REACT_CONCURRENT_MODE_TYPE:
2476 return 'ConcurrentMode';
2477 case REACT_FRAGMENT_TYPE:
2478 return 'Fragment';
2479 case REACT_PORTAL_TYPE:
2480 return 'Portal';
2481 case REACT_PROFILER_TYPE:
2482 return 'Profiler';
2483 case REACT_STRICT_MODE_TYPE:
2484 return 'StrictMode';
2485 case REACT_SUSPENSE_TYPE:
2486 return 'Suspense';
2487 }
2488 if (typeof type === 'object') {
2489 switch (type.$$typeof) {
2490 case REACT_CONTEXT_TYPE:
2491 return 'Context.Consumer';
2492 case REACT_PROVIDER_TYPE:
2493 return 'Context.Provider';
2494 case REACT_FORWARD_REF_TYPE:
2495 return getWrappedName(type, type.render, 'ForwardRef');
2496 case REACT_MEMO_TYPE:
2497 return getComponentName(type.type);
2498 case REACT_LAZY_TYPE:
2499 {
2500 var thenable = type;
2501 var resolvedThenable = refineResolvedLazyComponent(thenable);
2502 if (resolvedThenable) {
2503 return getComponentName(resolvedThenable);
2504 }
2505 }
2506 }
2507 }
2508 return null;
2509}
2510
2511var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame;
2512
2513function describeFiber(fiber) {
2514 switch (fiber.tag) {
2515 case HostRoot:
2516 case HostPortal:
2517 case HostText:
2518 case Fragment:
2519 case ContextProvider:
2520 case ContextConsumer:
2521 return '';
2522 default:
2523 var owner = fiber._debugOwner;
2524 var source = fiber._debugSource;
2525 var name = getComponentName(fiber.type);
2526 var ownerName = null;
2527 if (owner) {
2528 ownerName = getComponentName(owner.type);
2529 }
2530 return describeComponentFrame(name, source, ownerName);
2531 }
2532}
2533
2534function getStackByFiberInDevAndProd(workInProgress) {
2535 var info = '';
2536 var node = workInProgress;
2537 do {
2538 info += describeFiber(node);
2539 node = node.return;
2540 } while (node);
2541 return info;
2542}
2543
2544var current = null;
2545var phase = null;
2546
2547function getCurrentFiberOwnerNameInDevOrNull() {
2548 {
2549 if (current === null) {
2550 return null;
2551 }
2552 var owner = current._debugOwner;
2553 if (owner !== null && typeof owner !== 'undefined') {
2554 return getComponentName(owner.type);
2555 }
2556 }
2557 return null;
2558}
2559
2560function getCurrentFiberStackInDev() {
2561 {
2562 if (current === null) {
2563 return '';
2564 }
2565 // Safe because if current fiber exists, we are reconciling,
2566 // and it is guaranteed to be the work-in-progress version.
2567 return getStackByFiberInDevAndProd(current);
2568 }
2569 return '';
2570}
2571
2572function resetCurrentFiber() {
2573 {
2574 ReactDebugCurrentFrame.getCurrentStack = null;
2575 current = null;
2576 phase = null;
2577 }
2578}
2579
2580function setCurrentFiber(fiber) {
2581 {
2582 ReactDebugCurrentFrame.getCurrentStack = getCurrentFiberStackInDev;
2583 current = fiber;
2584 phase = null;
2585 }
2586}
2587
2588function setCurrentPhase(lifeCyclePhase) {
2589 {
2590 phase = lifeCyclePhase;
2591 }
2592}
2593
2594/**
2595 * Similar to invariant but only logs a warning if the condition is not met.
2596 * This can be used to log issues in development environments in critical
2597 * paths. Removing the logging code for production environments will keep the
2598 * same logic and follow the same code paths.
2599 */
2600
2601var warning = warningWithoutStack$1;
2602
2603{
2604 warning = function (condition, format) {
2605 if (condition) {
2606 return;
2607 }
2608 var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame;
2609 var stack = ReactDebugCurrentFrame.getStackAddendum();
2610 // eslint-disable-next-line react-internal/warning-and-invariant-args
2611
2612 for (var _len = arguments.length, args = Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) {
2613 args[_key - 2] = arguments[_key];
2614 }
2615
2616 warningWithoutStack$1.apply(undefined, [false, format + '%s'].concat(args, [stack]));
2617 };
2618}
2619
2620var warning$1 = warning;
2621
2622// A reserved attribute.
2623// It is handled by React separately and shouldn't be written to the DOM.
2624var RESERVED = 0;
2625
2626// A simple string attribute.
2627// Attributes that aren't in the whitelist are presumed to have this type.
2628var STRING = 1;
2629
2630// A string attribute that accepts booleans in React. In HTML, these are called
2631// "enumerated" attributes with "true" and "false" as possible values.
2632// When true, it should be set to a "true" string.
2633// When false, it should be set to a "false" string.
2634var BOOLEANISH_STRING = 2;
2635
2636// A real boolean attribute.
2637// When true, it should be present (set either to an empty string or its name).
2638// When false, it should be omitted.
2639var BOOLEAN = 3;
2640
2641// An attribute that can be used as a flag as well as with a value.
2642// When true, it should be present (set either to an empty string or its name).
2643// When false, it should be omitted.
2644// For any other value, should be present with that value.
2645var OVERLOADED_BOOLEAN = 4;
2646
2647// An attribute that must be numeric or parse as a numeric.
2648// When falsy, it should be removed.
2649var NUMERIC = 5;
2650
2651// An attribute that must be positive numeric or parse as a positive numeric.
2652// When falsy, it should be removed.
2653var POSITIVE_NUMERIC = 6;
2654
2655/* eslint-disable max-len */
2656var 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';
2657/* eslint-enable max-len */
2658var ATTRIBUTE_NAME_CHAR = ATTRIBUTE_NAME_START_CHAR + '\\-.0-9\\u00B7\\u0300-\\u036F\\u203F-\\u2040';
2659
2660
2661var ROOT_ATTRIBUTE_NAME = 'data-reactroot';
2662var VALID_ATTRIBUTE_NAME_REGEX = new RegExp('^[' + ATTRIBUTE_NAME_START_CHAR + '][' + ATTRIBUTE_NAME_CHAR + ']*$');
2663
2664var hasOwnProperty = Object.prototype.hasOwnProperty;
2665var illegalAttributeNameCache = {};
2666var validatedAttributeNameCache = {};
2667
2668function isAttributeNameSafe(attributeName) {
2669 if (hasOwnProperty.call(validatedAttributeNameCache, attributeName)) {
2670 return true;
2671 }
2672 if (hasOwnProperty.call(illegalAttributeNameCache, attributeName)) {
2673 return false;
2674 }
2675 if (VALID_ATTRIBUTE_NAME_REGEX.test(attributeName)) {
2676 validatedAttributeNameCache[attributeName] = true;
2677 return true;
2678 }
2679 illegalAttributeNameCache[attributeName] = true;
2680 {
2681 warning$1(false, 'Invalid attribute name: `%s`', attributeName);
2682 }
2683 return false;
2684}
2685
2686function shouldIgnoreAttribute(name, propertyInfo, isCustomComponentTag) {
2687 if (propertyInfo !== null) {
2688 return propertyInfo.type === RESERVED;
2689 }
2690 if (isCustomComponentTag) {
2691 return false;
2692 }
2693 if (name.length > 2 && (name[0] === 'o' || name[0] === 'O') && (name[1] === 'n' || name[1] === 'N')) {
2694 return true;
2695 }
2696 return false;
2697}
2698
2699function shouldRemoveAttributeWithWarning(name, value, propertyInfo, isCustomComponentTag) {
2700 if (propertyInfo !== null && propertyInfo.type === RESERVED) {
2701 return false;
2702 }
2703 switch (typeof value) {
2704 case 'function':
2705 // $FlowIssue symbol is perfectly valid here
2706 case 'symbol':
2707 // eslint-disable-line
2708 return true;
2709 case 'boolean':
2710 {
2711 if (isCustomComponentTag) {
2712 return false;
2713 }
2714 if (propertyInfo !== null) {
2715 return !propertyInfo.acceptsBooleans;
2716 } else {
2717 var prefix = name.toLowerCase().slice(0, 5);
2718 return prefix !== 'data-' && prefix !== 'aria-';
2719 }
2720 }
2721 default:
2722 return false;
2723 }
2724}
2725
2726function shouldRemoveAttribute(name, value, propertyInfo, isCustomComponentTag) {
2727 if (value === null || typeof value === 'undefined') {
2728 return true;
2729 }
2730 if (shouldRemoveAttributeWithWarning(name, value, propertyInfo, isCustomComponentTag)) {
2731 return true;
2732 }
2733 if (isCustomComponentTag) {
2734 return false;
2735 }
2736 if (propertyInfo !== null) {
2737 switch (propertyInfo.type) {
2738 case BOOLEAN:
2739 return !value;
2740 case OVERLOADED_BOOLEAN:
2741 return value === false;
2742 case NUMERIC:
2743 return isNaN(value);
2744 case POSITIVE_NUMERIC:
2745 return isNaN(value) || value < 1;
2746 }
2747 }
2748 return false;
2749}
2750
2751function getPropertyInfo(name) {
2752 return properties.hasOwnProperty(name) ? properties[name] : null;
2753}
2754
2755function PropertyInfoRecord(name, type, mustUseProperty, attributeName, attributeNamespace) {
2756 this.acceptsBooleans = type === BOOLEANISH_STRING || type === BOOLEAN || type === OVERLOADED_BOOLEAN;
2757 this.attributeName = attributeName;
2758 this.attributeNamespace = attributeNamespace;
2759 this.mustUseProperty = mustUseProperty;
2760 this.propertyName = name;
2761 this.type = type;
2762}
2763
2764// When adding attributes to this list, be sure to also add them to
2765// the `possibleStandardNames` module to ensure casing and incorrect
2766// name warnings.
2767var properties = {};
2768
2769// These props are reserved by React. They shouldn't be written to the DOM.
2770['children', 'dangerouslySetInnerHTML',
2771// TODO: This prevents the assignment of defaultValue to regular
2772// elements (not just inputs). Now that ReactDOMInput assigns to the
2773// defaultValue property -- do we need this?
2774'defaultValue', 'defaultChecked', 'innerHTML', 'suppressContentEditableWarning', 'suppressHydrationWarning', 'style'].forEach(function (name) {
2775 properties[name] = new PropertyInfoRecord(name, RESERVED, false, // mustUseProperty
2776 name, // attributeName
2777 null);
2778} // attributeNamespace
2779);
2780
2781// A few React string attributes have a different name.
2782// This is a mapping from React prop names to the attribute names.
2783[['acceptCharset', 'accept-charset'], ['className', 'class'], ['htmlFor', 'for'], ['httpEquiv', 'http-equiv']].forEach(function (_ref) {
2784 var name = _ref[0],
2785 attributeName = _ref[1];
2786
2787 properties[name] = new PropertyInfoRecord(name, STRING, false, // mustUseProperty
2788 attributeName, // attributeName
2789 null);
2790} // attributeNamespace
2791);
2792
2793// These are "enumerated" HTML attributes that accept "true" and "false".
2794// In React, we let users pass `true` and `false` even though technically
2795// these aren't boolean attributes (they are coerced to strings).
2796['contentEditable', 'draggable', 'spellCheck', 'value'].forEach(function (name) {
2797 properties[name] = new PropertyInfoRecord(name, BOOLEANISH_STRING, false, // mustUseProperty
2798 name.toLowerCase(), // attributeName
2799 null);
2800} // attributeNamespace
2801);
2802
2803// These are "enumerated" SVG attributes that accept "true" and "false".
2804// In React, we let users pass `true` and `false` even though technically
2805// these aren't boolean attributes (they are coerced to strings).
2806// Since these are SVG attributes, their attribute names are case-sensitive.
2807['autoReverse', 'externalResourcesRequired', 'focusable', 'preserveAlpha'].forEach(function (name) {
2808 properties[name] = new PropertyInfoRecord(name, BOOLEANISH_STRING, false, // mustUseProperty
2809 name, // attributeName
2810 null);
2811} // attributeNamespace
2812);
2813
2814// These are HTML boolean attributes.
2815['allowFullScreen', 'async',
2816// Note: there is a special case that prevents it from being written to the DOM
2817// on the client side because the browsers are inconsistent. Instead we call focus().
2818'autoFocus', 'autoPlay', 'controls', 'default', 'defer', 'disabled', 'formNoValidate', 'hidden', 'loop', 'noModule', 'noValidate', 'open', 'playsInline', 'readOnly', 'required', 'reversed', 'scoped', 'seamless',
2819// Microdata
2820'itemScope'].forEach(function (name) {
2821 properties[name] = new PropertyInfoRecord(name, BOOLEAN, false, // mustUseProperty
2822 name.toLowerCase(), // attributeName
2823 null);
2824} // attributeNamespace
2825);
2826
2827// These are the few React props that we set as DOM properties
2828// rather than attributes. These are all booleans.
2829['checked',
2830// Note: `option.selected` is not updated if `select.multiple` is
2831// disabled with `removeAttribute`. We have special logic for handling this.
2832'multiple', 'muted', 'selected'].forEach(function (name) {
2833 properties[name] = new PropertyInfoRecord(name, BOOLEAN, true, // mustUseProperty
2834 name, // attributeName
2835 null);
2836} // attributeNamespace
2837);
2838
2839// These are HTML attributes that are "overloaded booleans": they behave like
2840// booleans, but can also accept a string value.
2841['capture', 'download'].forEach(function (name) {
2842 properties[name] = new PropertyInfoRecord(name, OVERLOADED_BOOLEAN, false, // mustUseProperty
2843 name, // attributeName
2844 null);
2845} // attributeNamespace
2846);
2847
2848// These are HTML attributes that must be positive numbers.
2849['cols', 'rows', 'size', 'span'].forEach(function (name) {
2850 properties[name] = new PropertyInfoRecord(name, POSITIVE_NUMERIC, false, // mustUseProperty
2851 name, // attributeName
2852 null);
2853} // attributeNamespace
2854);
2855
2856// These are HTML attributes that must be numbers.
2857['rowSpan', 'start'].forEach(function (name) {
2858 properties[name] = new PropertyInfoRecord(name, NUMERIC, false, // mustUseProperty
2859 name.toLowerCase(), // attributeName
2860 null);
2861} // attributeNamespace
2862);
2863
2864var CAMELIZE = /[\-\:]([a-z])/g;
2865var capitalize = function (token) {
2866 return token[1].toUpperCase();
2867};
2868
2869// This is a list of all SVG attributes that need special casing, namespacing,
2870// or boolean value assignment. Regular attributes that just accept strings
2871// and have the same names are omitted, just like in the HTML whitelist.
2872// Some of these attributes can be hard to find. This list was created by
2873// scrapping the MDN documentation.
2874['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) {
2875 var name = attributeName.replace(CAMELIZE, capitalize);
2876 properties[name] = new PropertyInfoRecord(name, STRING, false, // mustUseProperty
2877 attributeName, null);
2878} // attributeNamespace
2879);
2880
2881// String SVG attributes with the xlink namespace.
2882['xlink:actuate', 'xlink:arcrole', 'xlink:href', 'xlink:role', 'xlink:show', 'xlink:title', 'xlink:type'].forEach(function (attributeName) {
2883 var name = attributeName.replace(CAMELIZE, capitalize);
2884 properties[name] = new PropertyInfoRecord(name, STRING, false, // mustUseProperty
2885 attributeName, 'http://www.w3.org/1999/xlink');
2886});
2887
2888// String SVG attributes with the xml namespace.
2889['xml:base', 'xml:lang', 'xml:space'].forEach(function (attributeName) {
2890 var name = attributeName.replace(CAMELIZE, capitalize);
2891 properties[name] = new PropertyInfoRecord(name, STRING, false, // mustUseProperty
2892 attributeName, 'http://www.w3.org/XML/1998/namespace');
2893});
2894
2895// Special case: this attribute exists both in HTML and SVG.
2896// Its "tabindex" attribute name is case-sensitive in SVG so we can't just use
2897// its React `tabIndex` name, like we do for attributes that exist only in HTML.
2898properties.tabIndex = new PropertyInfoRecord('tabIndex', STRING, false, // mustUseProperty
2899'tabindex', // attributeName
2900null);
2901
2902/**
2903 * Get the value for a property on a node. Only used in DEV for SSR validation.
2904 * The "expected" argument is used as a hint of what the expected value is.
2905 * Some properties have multiple equivalent values.
2906 */
2907function getValueForProperty(node, name, expected, propertyInfo) {
2908 {
2909 if (propertyInfo.mustUseProperty) {
2910 var propertyName = propertyInfo.propertyName;
2911
2912 return node[propertyName];
2913 } else {
2914 var attributeName = propertyInfo.attributeName;
2915
2916 var stringValue = null;
2917
2918 if (propertyInfo.type === OVERLOADED_BOOLEAN) {
2919 if (node.hasAttribute(attributeName)) {
2920 var value = node.getAttribute(attributeName);
2921 if (value === '') {
2922 return true;
2923 }
2924 if (shouldRemoveAttribute(name, expected, propertyInfo, false)) {
2925 return value;
2926 }
2927 if (value === '' + expected) {
2928 return expected;
2929 }
2930 return value;
2931 }
2932 } else if (node.hasAttribute(attributeName)) {
2933 if (shouldRemoveAttribute(name, expected, propertyInfo, false)) {
2934 // We had an attribute but shouldn't have had one, so read it
2935 // for the error message.
2936 return node.getAttribute(attributeName);
2937 }
2938 if (propertyInfo.type === BOOLEAN) {
2939 // If this was a boolean, it doesn't matter what the value is
2940 // the fact that we have it is the same as the expected.
2941 return expected;
2942 }
2943 // Even if this property uses a namespace we use getAttribute
2944 // because we assume its namespaced name is the same as our config.
2945 // To use getAttributeNS we need the local name which we don't have
2946 // in our config atm.
2947 stringValue = node.getAttribute(attributeName);
2948 }
2949
2950 if (shouldRemoveAttribute(name, expected, propertyInfo, false)) {
2951 return stringValue === null ? expected : stringValue;
2952 } else if (stringValue === '' + expected) {
2953 return expected;
2954 } else {
2955 return stringValue;
2956 }
2957 }
2958 }
2959}
2960
2961/**
2962 * Get the value for a attribute on a node. Only used in DEV for SSR validation.
2963 * The third argument is used as a hint of what the expected value is. Some
2964 * attributes have multiple equivalent values.
2965 */
2966function getValueForAttribute(node, name, expected) {
2967 {
2968 if (!isAttributeNameSafe(name)) {
2969 return;
2970 }
2971 if (!node.hasAttribute(name)) {
2972 return expected === undefined ? undefined : null;
2973 }
2974 var value = node.getAttribute(name);
2975 if (value === '' + expected) {
2976 return expected;
2977 }
2978 return value;
2979 }
2980}
2981
2982/**
2983 * Sets the value for a property on a node.
2984 *
2985 * @param {DOMElement} node
2986 * @param {string} name
2987 * @param {*} value
2988 */
2989function setValueForProperty(node, name, value, isCustomComponentTag) {
2990 var propertyInfo = getPropertyInfo(name);
2991 if (shouldIgnoreAttribute(name, propertyInfo, isCustomComponentTag)) {
2992 return;
2993 }
2994 if (shouldRemoveAttribute(name, value, propertyInfo, isCustomComponentTag)) {
2995 value = null;
2996 }
2997 // If the prop isn't in the special list, treat it as a simple attribute.
2998 if (isCustomComponentTag || propertyInfo === null) {
2999 if (isAttributeNameSafe(name)) {
3000 var _attributeName = name;
3001 if (value === null) {
3002 node.removeAttribute(_attributeName);
3003 } else {
3004 node.setAttribute(_attributeName, '' + value);
3005 }
3006 }
3007 return;
3008 }
3009 var mustUseProperty = propertyInfo.mustUseProperty;
3010
3011 if (mustUseProperty) {
3012 var propertyName = propertyInfo.propertyName;
3013
3014 if (value === null) {
3015 var type = propertyInfo.type;
3016
3017 node[propertyName] = type === BOOLEAN ? false : '';
3018 } else {
3019 // Contrary to `setAttribute`, object properties are properly
3020 // `toString`ed by IE8/9.
3021 node[propertyName] = value;
3022 }
3023 return;
3024 }
3025 // The rest are treated as attributes with special cases.
3026 var attributeName = propertyInfo.attributeName,
3027 attributeNamespace = propertyInfo.attributeNamespace;
3028
3029 if (value === null) {
3030 node.removeAttribute(attributeName);
3031 } else {
3032 var _type = propertyInfo.type;
3033
3034 var attributeValue = void 0;
3035 if (_type === BOOLEAN || _type === OVERLOADED_BOOLEAN && value === true) {
3036 attributeValue = '';
3037 } else {
3038 // `setAttribute` with objects becomes only `[object]` in IE8/9,
3039 // ('' + value) makes it output the correct toString()-value.
3040 attributeValue = '' + value;
3041 }
3042 if (attributeNamespace) {
3043 node.setAttributeNS(attributeNamespace, attributeName, attributeValue);
3044 } else {
3045 node.setAttribute(attributeName, attributeValue);
3046 }
3047 }
3048}
3049
3050// Flow does not allow string concatenation of most non-string types. To work
3051// around this limitation, we use an opaque type that can only be obtained by
3052// passing the value through getToStringValue first.
3053function toString(value) {
3054 return '' + value;
3055}
3056
3057function getToStringValue(value) {
3058 switch (typeof value) {
3059 case 'boolean':
3060 case 'number':
3061 case 'object':
3062 case 'string':
3063 case 'undefined':
3064 return value;
3065 default:
3066 // function, symbol are assigned as empty strings
3067 return '';
3068 }
3069}
3070
3071/**
3072 * Copyright (c) 2013-present, Facebook, Inc.
3073 *
3074 * This source code is licensed under the MIT license found in the
3075 * LICENSE file in the root directory of this source tree.
3076 */
3077
3078
3079
3080var ReactPropTypesSecret$1 = 'SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED';
3081
3082var ReactPropTypesSecret_1 = ReactPropTypesSecret$1;
3083
3084/**
3085 * Copyright (c) 2013-present, Facebook, Inc.
3086 *
3087 * This source code is licensed under the MIT license found in the
3088 * LICENSE file in the root directory of this source tree.
3089 */
3090
3091
3092
3093var printWarning = function() {};
3094
3095{
3096 var ReactPropTypesSecret = ReactPropTypesSecret_1;
3097 var loggedTypeFailures = {};
3098
3099 printWarning = function(text) {
3100 var message = 'Warning: ' + text;
3101 if (typeof console !== 'undefined') {
3102 console.error(message);
3103 }
3104 try {
3105 // --- Welcome to debugging React ---
3106 // This error was thrown as a convenience so that you can use this stack
3107 // to find the callsite that caused this warning to fire.
3108 throw new Error(message);
3109 } catch (x) {}
3110 };
3111}
3112
3113/**
3114 * Assert that the values match with the type specs.
3115 * Error messages are memorized and will only be shown once.
3116 *
3117 * @param {object} typeSpecs Map of name to a ReactPropType
3118 * @param {object} values Runtime values that need to be type-checked
3119 * @param {string} location e.g. "prop", "context", "child context"
3120 * @param {string} componentName Name of the component for error messages.
3121 * @param {?Function} getStack Returns the component stack.
3122 * @private
3123 */
3124function checkPropTypes(typeSpecs, values, location, componentName, getStack) {
3125 {
3126 for (var typeSpecName in typeSpecs) {
3127 if (typeSpecs.hasOwnProperty(typeSpecName)) {
3128 var error;
3129 // Prop type validation may throw. In case they do, we don't want to
3130 // fail the render phase where it didn't fail before. So we log it.
3131 // After these have been cleaned up, we'll let them throw.
3132 try {
3133 // This is intentionally an invariant that gets caught. It's the same
3134 // behavior as without this statement except with a better message.
3135 if (typeof typeSpecs[typeSpecName] !== 'function') {
3136 var err = Error(
3137 (componentName || 'React class') + ': ' + location + ' type `' + typeSpecName + '` is invalid; ' +
3138 'it must be a function, usually from the `prop-types` package, but received `' + typeof typeSpecs[typeSpecName] + '`.'
3139 );
3140 err.name = 'Invariant Violation';
3141 throw err;
3142 }
3143 error = typeSpecs[typeSpecName](values, typeSpecName, componentName, location, null, ReactPropTypesSecret);
3144 } catch (ex) {
3145 error = ex;
3146 }
3147 if (error && !(error instanceof Error)) {
3148 printWarning(
3149 (componentName || 'React class') + ': type specification of ' +
3150 location + ' `' + typeSpecName + '` is invalid; the type checker ' +
3151 'function must return `null` or an `Error` but returned a ' + typeof error + '. ' +
3152 'You may have forgotten to pass an argument to the type checker ' +
3153 'creator (arrayOf, instanceOf, objectOf, oneOf, oneOfType, and ' +
3154 'shape all require an argument).'
3155 );
3156
3157 }
3158 if (error instanceof Error && !(error.message in loggedTypeFailures)) {
3159 // Only monitor this failure once because there tends to be a lot of the
3160 // same error.
3161 loggedTypeFailures[error.message] = true;
3162
3163 var stack = getStack ? getStack() : '';
3164
3165 printWarning(
3166 'Failed ' + location + ' type: ' + error.message + (stack != null ? stack : '')
3167 );
3168 }
3169 }
3170 }
3171 }
3172}
3173
3174var checkPropTypes_1 = checkPropTypes;
3175
3176var ReactDebugCurrentFrame$1 = null;
3177
3178var ReactControlledValuePropTypes = {
3179 checkPropTypes: null
3180};
3181
3182{
3183 ReactDebugCurrentFrame$1 = ReactSharedInternals.ReactDebugCurrentFrame;
3184
3185 var hasReadOnlyValue = {
3186 button: true,
3187 checkbox: true,
3188 image: true,
3189 hidden: true,
3190 radio: true,
3191 reset: true,
3192 submit: true
3193 };
3194
3195 var propTypes = {
3196 value: function (props, propName, componentName) {
3197 if (hasReadOnlyValue[props.type] || props.onChange || props.readOnly || props.disabled || props[propName] == null) {
3198 return null;
3199 }
3200 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`.');
3201 },
3202 checked: function (props, propName, componentName) {
3203 if (props.onChange || props.readOnly || props.disabled || props[propName] == null) {
3204 return null;
3205 }
3206 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`.');
3207 }
3208 };
3209
3210 /**
3211 * Provide a linked `value` attribute for controlled forms. You should not use
3212 * this outside of the ReactDOM controlled form components.
3213 */
3214 ReactControlledValuePropTypes.checkPropTypes = function (tagName, props) {
3215 checkPropTypes_1(propTypes, props, 'prop', tagName, ReactDebugCurrentFrame$1.getStackAddendum);
3216 };
3217}
3218
3219var enableUserTimingAPI = true;
3220
3221var enableHooks = false;
3222// Helps identify side effects in begin-phase lifecycle hooks and setState reducers:
3223var debugRenderPhaseSideEffects = false;
3224
3225// In some cases, StrictMode should also double-render lifecycles.
3226// This can be confusing for tests though,
3227// And it can be bad for performance in production.
3228// This feature flag can be used to control the behavior:
3229var debugRenderPhaseSideEffectsForStrictMode = true;
3230
3231// To preserve the "Pause on caught exceptions" behavior of the debugger, we
3232// replay the begin phase of a failed component inside invokeGuardedCallback.
3233var replayFailedUnitOfWorkWithInvokeGuardedCallback = true;
3234
3235// Warn about deprecated, async-unsafe lifecycles; relates to RFC #6:
3236var warnAboutDeprecatedLifecycles = false;
3237
3238// Gather advanced timing metrics for Profiler subtrees.
3239var enableProfilerTimer = true;
3240
3241// Trace which interactions trigger each commit.
3242var enableSchedulerTracing = true;
3243
3244// Only used in www builds.
3245 // TODO: true? Here it might just be false.
3246
3247// Only used in www builds.
3248
3249
3250// Only used in www builds.
3251
3252
3253// React Fire: prevent the value and checked attributes from syncing
3254// with their related DOM properties
3255var disableInputAttributeSyncing = false;
3256
3257// These APIs will no longer be "unstable" in the upcoming 16.7 release,
3258// Control this behavior with a flag to support 16.6 minor releases in the meanwhile.
3259var enableStableConcurrentModeAPIs = false;
3260
3261var warnAboutShorthandPropertyCollision = false;
3262
3263// TODO: direct imports like some-package/src/* are bad. Fix me.
3264var didWarnValueDefaultValue = false;
3265var didWarnCheckedDefaultChecked = false;
3266var didWarnControlledToUncontrolled = false;
3267var didWarnUncontrolledToControlled = false;
3268
3269function isControlled(props) {
3270 var usesChecked = props.type === 'checkbox' || props.type === 'radio';
3271 return usesChecked ? props.checked != null : props.value != null;
3272}
3273
3274/**
3275 * Implements an <input> host component that allows setting these optional
3276 * props: `checked`, `value`, `defaultChecked`, and `defaultValue`.
3277 *
3278 * If `checked` or `value` are not supplied (or null/undefined), user actions
3279 * that affect the checked state or value will trigger updates to the element.
3280 *
3281 * If they are supplied (and not null/undefined), the rendered element will not
3282 * trigger updates to the element. Instead, the props must change in order for
3283 * the rendered element to be updated.
3284 *
3285 * The rendered element will be initialized as unchecked (or `defaultChecked`)
3286 * with an empty value (or `defaultValue`).
3287 *
3288 * See http://www.w3.org/TR/2012/WD-html5-20121025/the-input-element.html
3289 */
3290
3291function getHostProps(element, props) {
3292 var node = element;
3293 var checked = props.checked;
3294
3295 var hostProps = _assign({}, props, {
3296 defaultChecked: undefined,
3297 defaultValue: undefined,
3298 value: undefined,
3299 checked: checked != null ? checked : node._wrapperState.initialChecked
3300 });
3301
3302 return hostProps;
3303}
3304
3305function initWrapperState(element, props) {
3306 {
3307 ReactControlledValuePropTypes.checkPropTypes('input', props);
3308
3309 if (props.checked !== undefined && props.defaultChecked !== undefined && !didWarnCheckedDefaultChecked) {
3310 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);
3311 didWarnCheckedDefaultChecked = true;
3312 }
3313 if (props.value !== undefined && props.defaultValue !== undefined && !didWarnValueDefaultValue) {
3314 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);
3315 didWarnValueDefaultValue = true;
3316 }
3317 }
3318
3319 var node = element;
3320 var defaultValue = props.defaultValue == null ? '' : props.defaultValue;
3321
3322 node._wrapperState = {
3323 initialChecked: props.checked != null ? props.checked : props.defaultChecked,
3324 initialValue: getToStringValue(props.value != null ? props.value : defaultValue),
3325 controlled: isControlled(props)
3326 };
3327}
3328
3329function updateChecked(element, props) {
3330 var node = element;
3331 var checked = props.checked;
3332 if (checked != null) {
3333 setValueForProperty(node, 'checked', checked, false);
3334 }
3335}
3336
3337function updateWrapper(element, props) {
3338 var node = element;
3339 {
3340 var _controlled = isControlled(props);
3341
3342 if (!node._wrapperState.controlled && _controlled && !didWarnUncontrolledToControlled) {
3343 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);
3344 didWarnUncontrolledToControlled = true;
3345 }
3346 if (node._wrapperState.controlled && !_controlled && !didWarnControlledToUncontrolled) {
3347 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);
3348 didWarnControlledToUncontrolled = true;
3349 }
3350 }
3351
3352 updateChecked(element, props);
3353
3354 var value = getToStringValue(props.value);
3355 var type = props.type;
3356
3357 if (value != null) {
3358 if (type === 'number') {
3359 if (value === 0 && node.value === '' ||
3360 // We explicitly want to coerce to number here if possible.
3361 // eslint-disable-next-line
3362 node.value != value) {
3363 node.value = toString(value);
3364 }
3365 } else if (node.value !== toString(value)) {
3366 node.value = toString(value);
3367 }
3368 } else if (type === 'submit' || type === 'reset') {
3369 // Submit/reset inputs need the attribute removed completely to avoid
3370 // blank-text buttons.
3371 node.removeAttribute('value');
3372 return;
3373 }
3374
3375 if (disableInputAttributeSyncing) {
3376 // When not syncing the value attribute, React only assigns a new value
3377 // whenever the defaultValue React prop has changed. When not present,
3378 // React does nothing
3379 if (props.hasOwnProperty('defaultValue')) {
3380 setDefaultValue(node, props.type, getToStringValue(props.defaultValue));
3381 }
3382 } else {
3383 // When syncing the value attribute, the value comes from a cascade of
3384 // properties:
3385 // 1. The value React property
3386 // 2. The defaultValue React property
3387 // 3. Otherwise there should be no change
3388 if (props.hasOwnProperty('value')) {
3389 setDefaultValue(node, props.type, value);
3390 } else if (props.hasOwnProperty('defaultValue')) {
3391 setDefaultValue(node, props.type, getToStringValue(props.defaultValue));
3392 }
3393 }
3394
3395 if (disableInputAttributeSyncing) {
3396 // When not syncing the checked attribute, the attribute is directly
3397 // controllable from the defaultValue React property. It needs to be
3398 // updated as new props come in.
3399 if (props.defaultChecked == null) {
3400 node.removeAttribute('checked');
3401 } else {
3402 node.defaultChecked = !!props.defaultChecked;
3403 }
3404 } else {
3405 // When syncing the checked attribute, it only changes when it needs
3406 // to be removed, such as transitioning from a checkbox into a text input
3407 if (props.checked == null && props.defaultChecked != null) {
3408 node.defaultChecked = !!props.defaultChecked;
3409 }
3410 }
3411}
3412
3413function postMountWrapper(element, props, isHydrating) {
3414 var node = element;
3415
3416 // Do not assign value if it is already set. This prevents user text input
3417 // from being lost during SSR hydration.
3418 if (props.hasOwnProperty('value') || props.hasOwnProperty('defaultValue')) {
3419 var type = props.type;
3420 var isButton = type === 'submit' || type === 'reset';
3421
3422 // Avoid setting value attribute on submit/reset inputs as it overrides the
3423 // default value provided by the browser. See: #12872
3424 if (isButton && (props.value === undefined || props.value === null)) {
3425 return;
3426 }
3427
3428 var _initialValue = toString(node._wrapperState.initialValue);
3429
3430 // Do not assign value if it is already set. This prevents user text input
3431 // from being lost during SSR hydration.
3432 if (!isHydrating) {
3433 if (disableInputAttributeSyncing) {
3434 var value = getToStringValue(props.value);
3435
3436 // When not syncing the value attribute, the value property points
3437 // directly to the React prop. Only assign it if it exists.
3438 if (value != null) {
3439 // Always assign on buttons so that it is possible to assign an
3440 // empty string to clear button text.
3441 //
3442 // Otherwise, do not re-assign the value property if is empty. This
3443 // potentially avoids a DOM write and prevents Firefox (~60.0.1) from
3444 // prematurely marking required inputs as invalid. Equality is compared
3445 // to the current value in case the browser provided value is not an
3446 // empty string.
3447 if (isButton || value !== node.value) {
3448 node.value = toString(value);
3449 }
3450 }
3451 } else {
3452 // When syncing the value attribute, the value property should use
3453 // the wrapperState._initialValue property. This uses:
3454 //
3455 // 1. The value React property when present
3456 // 2. The defaultValue React property when present
3457 // 3. An empty string
3458 if (_initialValue !== node.value) {
3459 node.value = _initialValue;
3460 }
3461 }
3462 }
3463
3464 if (disableInputAttributeSyncing) {
3465 // When not syncing the value attribute, assign the value attribute
3466 // directly from the defaultValue React property (when present)
3467 var defaultValue = getToStringValue(props.defaultValue);
3468 if (defaultValue != null) {
3469 node.defaultValue = toString(defaultValue);
3470 }
3471 } else {
3472 // Otherwise, the value attribute is synchronized to the property,
3473 // so we assign defaultValue to the same thing as the value property
3474 // assignment step above.
3475 node.defaultValue = _initialValue;
3476 }
3477 }
3478
3479 // Normally, we'd just do `node.checked = node.checked` upon initial mount, less this bug
3480 // this is needed to work around a chrome bug where setting defaultChecked
3481 // will sometimes influence the value of checked (even after detachment).
3482 // Reference: https://bugs.chromium.org/p/chromium/issues/detail?id=608416
3483 // We need to temporarily unset name to avoid disrupting radio button groups.
3484 var name = node.name;
3485 if (name !== '') {
3486 node.name = '';
3487 }
3488
3489 if (disableInputAttributeSyncing) {
3490 // When not syncing the checked attribute, the checked property
3491 // never gets assigned. It must be manually set. We don't want
3492 // to do this when hydrating so that existing user input isn't
3493 // modified
3494 if (!isHydrating) {
3495 updateChecked(element, props);
3496 }
3497
3498 // Only assign the checked attribute if it is defined. This saves
3499 // a DOM write when controlling the checked attribute isn't needed
3500 // (text inputs, submit/reset)
3501 if (props.hasOwnProperty('defaultChecked')) {
3502 node.defaultChecked = !node.defaultChecked;
3503 node.defaultChecked = !!props.defaultChecked;
3504 }
3505 } else {
3506 // When syncing the checked attribute, both the checked property and
3507 // attribute are assigned at the same time using defaultChecked. This uses:
3508 //
3509 // 1. The checked React property when present
3510 // 2. The defaultChecked React property when present
3511 // 3. Otherwise, false
3512 node.defaultChecked = !node.defaultChecked;
3513 node.defaultChecked = !!node._wrapperState.initialChecked;
3514 }
3515
3516 if (name !== '') {
3517 node.name = name;
3518 }
3519}
3520
3521function restoreControlledState(element, props) {
3522 var node = element;
3523 updateWrapper(node, props);
3524 updateNamedCousins(node, props);
3525}
3526
3527function updateNamedCousins(rootNode, props) {
3528 var name = props.name;
3529 if (props.type === 'radio' && name != null) {
3530 var queryRoot = rootNode;
3531
3532 while (queryRoot.parentNode) {
3533 queryRoot = queryRoot.parentNode;
3534 }
3535
3536 // If `rootNode.form` was non-null, then we could try `form.elements`,
3537 // but that sometimes behaves strangely in IE8. We could also try using
3538 // `form.getElementsByName`, but that will only return direct children
3539 // and won't include inputs that use the HTML5 `form=` attribute. Since
3540 // the input might not even be in a form. It might not even be in the
3541 // document. Let's just use the local `querySelectorAll` to ensure we don't
3542 // miss anything.
3543 var group = queryRoot.querySelectorAll('input[name=' + JSON.stringify('' + name) + '][type="radio"]');
3544
3545 for (var i = 0; i < group.length; i++) {
3546 var otherNode = group[i];
3547 if (otherNode === rootNode || otherNode.form !== rootNode.form) {
3548 continue;
3549 }
3550 // This will throw if radio buttons rendered by different copies of React
3551 // and the same name are rendered into the same form (same as #1939).
3552 // That's probably okay; we don't support it just as we don't support
3553 // mixing React radio buttons with non-React ones.
3554 var otherProps = getFiberCurrentPropsFromNode$1(otherNode);
3555 !otherProps ? invariant(false, 'ReactDOMInput: Mixing React and non-React radio inputs with the same `name` is not supported.') : void 0;
3556
3557 // We need update the tracked value on the named cousin since the value
3558 // was changed but the input saw no event or value set
3559 updateValueIfChanged(otherNode);
3560
3561 // If this is a controlled radio button group, forcing the input that
3562 // was previously checked to update will cause it to be come re-checked
3563 // as appropriate.
3564 updateWrapper(otherNode, otherProps);
3565 }
3566 }
3567}
3568
3569// In Chrome, assigning defaultValue to certain input types triggers input validation.
3570// For number inputs, the display value loses trailing decimal points. For email inputs,
3571// Chrome raises "The specified value <x> is not a valid email address".
3572//
3573// Here we check to see if the defaultValue has actually changed, avoiding these problems
3574// when the user is inputting text
3575//
3576// https://github.com/facebook/react/issues/7253
3577function setDefaultValue(node, type, value) {
3578 if (
3579 // Focused number inputs synchronize on blur. See ChangeEventPlugin.js
3580 type !== 'number' || node.ownerDocument.activeElement !== node) {
3581 if (value == null) {
3582 node.defaultValue = toString(node._wrapperState.initialValue);
3583 } else if (node.defaultValue !== toString(value)) {
3584 node.defaultValue = toString(value);
3585 }
3586 }
3587}
3588
3589var eventTypes$1 = {
3590 change: {
3591 phasedRegistrationNames: {
3592 bubbled: 'onChange',
3593 captured: 'onChangeCapture'
3594 },
3595 dependencies: [TOP_BLUR, TOP_CHANGE, TOP_CLICK, TOP_FOCUS, TOP_INPUT, TOP_KEY_DOWN, TOP_KEY_UP, TOP_SELECTION_CHANGE]
3596 }
3597};
3598
3599function createAndAccumulateChangeEvent(inst, nativeEvent, target) {
3600 var event = SyntheticEvent.getPooled(eventTypes$1.change, inst, nativeEvent, target);
3601 event.type = 'change';
3602 // Flag this event loop as needing state restore.
3603 enqueueStateRestore(target);
3604 accumulateTwoPhaseDispatches(event);
3605 return event;
3606}
3607/**
3608 * For IE shims
3609 */
3610var activeElement = null;
3611var activeElementInst = null;
3612
3613/**
3614 * SECTION: handle `change` event
3615 */
3616function shouldUseChangeEvent(elem) {
3617 var nodeName = elem.nodeName && elem.nodeName.toLowerCase();
3618 return nodeName === 'select' || nodeName === 'input' && elem.type === 'file';
3619}
3620
3621function manualDispatchChangeEvent(nativeEvent) {
3622 var event = createAndAccumulateChangeEvent(activeElementInst, nativeEvent, getEventTarget(nativeEvent));
3623
3624 // If change and propertychange bubbled, we'd just bind to it like all the
3625 // other events and have it go through ReactBrowserEventEmitter. Since it
3626 // doesn't, we manually listen for the events and so we have to enqueue and
3627 // process the abstract event manually.
3628 //
3629 // Batching is necessary here in order to ensure that all event handlers run
3630 // before the next rerender (including event handlers attached to ancestor
3631 // elements instead of directly on the input). Without this, controlled
3632 // components don't work properly in conjunction with event bubbling because
3633 // the component is rerendered and the value reverted before all the event
3634 // handlers can run. See https://github.com/facebook/react/issues/708.
3635 batchedUpdates(runEventInBatch, event);
3636}
3637
3638function runEventInBatch(event) {
3639 runEventsInBatch(event);
3640}
3641
3642function getInstIfValueChanged(targetInst) {
3643 var targetNode = getNodeFromInstance$1(targetInst);
3644 if (updateValueIfChanged(targetNode)) {
3645 return targetInst;
3646 }
3647}
3648
3649function getTargetInstForChangeEvent(topLevelType, targetInst) {
3650 if (topLevelType === TOP_CHANGE) {
3651 return targetInst;
3652 }
3653}
3654
3655/**
3656 * SECTION: handle `input` event
3657 */
3658var isInputEventSupported = false;
3659if (canUseDOM) {
3660 // IE9 claims to support the input event but fails to trigger it when
3661 // deleting text, so we ignore its input events.
3662 isInputEventSupported = isEventSupported('input') && (!document.documentMode || document.documentMode > 9);
3663}
3664
3665/**
3666 * (For IE <=9) Starts tracking propertychange events on the passed-in element
3667 * and override the value property so that we can distinguish user events from
3668 * value changes in JS.
3669 */
3670function startWatchingForValueChange(target, targetInst) {
3671 activeElement = target;
3672 activeElementInst = targetInst;
3673 activeElement.attachEvent('onpropertychange', handlePropertyChange);
3674}
3675
3676/**
3677 * (For IE <=9) Removes the event listeners from the currently-tracked element,
3678 * if any exists.
3679 */
3680function stopWatchingForValueChange() {
3681 if (!activeElement) {
3682 return;
3683 }
3684 activeElement.detachEvent('onpropertychange', handlePropertyChange);
3685 activeElement = null;
3686 activeElementInst = null;
3687}
3688
3689/**
3690 * (For IE <=9) Handles a propertychange event, sending a `change` event if
3691 * the value of the active element has changed.
3692 */
3693function handlePropertyChange(nativeEvent) {
3694 if (nativeEvent.propertyName !== 'value') {
3695 return;
3696 }
3697 if (getInstIfValueChanged(activeElementInst)) {
3698 manualDispatchChangeEvent(nativeEvent);
3699 }
3700}
3701
3702function handleEventsForInputEventPolyfill(topLevelType, target, targetInst) {
3703 if (topLevelType === TOP_FOCUS) {
3704 // In IE9, propertychange fires for most input events but is buggy and
3705 // doesn't fire when text is deleted, but conveniently, selectionchange
3706 // appears to fire in all of the remaining cases so we catch those and
3707 // forward the event if the value has changed
3708 // In either case, we don't want to call the event handler if the value
3709 // is changed from JS so we redefine a setter for `.value` that updates
3710 // our activeElementValue variable, allowing us to ignore those changes
3711 //
3712 // stopWatching() should be a noop here but we call it just in case we
3713 // missed a blur event somehow.
3714 stopWatchingForValueChange();
3715 startWatchingForValueChange(target, targetInst);
3716 } else if (topLevelType === TOP_BLUR) {
3717 stopWatchingForValueChange();
3718 }
3719}
3720
3721// For IE8 and IE9.
3722function getTargetInstForInputEventPolyfill(topLevelType, targetInst) {
3723 if (topLevelType === TOP_SELECTION_CHANGE || topLevelType === TOP_KEY_UP || topLevelType === TOP_KEY_DOWN) {
3724 // On the selectionchange event, the target is just document which isn't
3725 // helpful for us so just check activeElement instead.
3726 //
3727 // 99% of the time, keydown and keyup aren't necessary. IE8 fails to fire
3728 // propertychange on the first input event after setting `value` from a
3729 // script and fires only keydown, keypress, keyup. Catching keyup usually
3730 // gets it and catching keydown lets us fire an event for the first
3731 // keystroke if user does a key repeat (it'll be a little delayed: right
3732 // before the second keystroke). Other input methods (e.g., paste) seem to
3733 // fire selectionchange normally.
3734 return getInstIfValueChanged(activeElementInst);
3735 }
3736}
3737
3738/**
3739 * SECTION: handle `click` event
3740 */
3741function shouldUseClickEvent(elem) {
3742 // Use the `click` event to detect changes to checkbox and radio inputs.
3743 // This approach works across all browsers, whereas `change` does not fire
3744 // until `blur` in IE8.
3745 var nodeName = elem.nodeName;
3746 return nodeName && nodeName.toLowerCase() === 'input' && (elem.type === 'checkbox' || elem.type === 'radio');
3747}
3748
3749function getTargetInstForClickEvent(topLevelType, targetInst) {
3750 if (topLevelType === TOP_CLICK) {
3751 return getInstIfValueChanged(targetInst);
3752 }
3753}
3754
3755function getTargetInstForInputOrChangeEvent(topLevelType, targetInst) {
3756 if (topLevelType === TOP_INPUT || topLevelType === TOP_CHANGE) {
3757 return getInstIfValueChanged(targetInst);
3758 }
3759}
3760
3761function handleControlledInputBlur(node) {
3762 var state = node._wrapperState;
3763
3764 if (!state || !state.controlled || node.type !== 'number') {
3765 return;
3766 }
3767
3768 if (!disableInputAttributeSyncing) {
3769 // If controlled, assign the value attribute to the current value on blur
3770 setDefaultValue(node, 'number', node.value);
3771 }
3772}
3773
3774/**
3775 * This plugin creates an `onChange` event that normalizes change events
3776 * across form elements. This event fires at a time when it's possible to
3777 * change the element's value without seeing a flicker.
3778 *
3779 * Supported elements are:
3780 * - input (see `isTextInputElement`)
3781 * - textarea
3782 * - select
3783 */
3784var ChangeEventPlugin = {
3785 eventTypes: eventTypes$1,
3786
3787 _isInputEventSupported: isInputEventSupported,
3788
3789 extractEvents: function (topLevelType, targetInst, nativeEvent, nativeEventTarget) {
3790 var targetNode = targetInst ? getNodeFromInstance$1(targetInst) : window;
3791
3792 var getTargetInstFunc = void 0,
3793 handleEventFunc = void 0;
3794 if (shouldUseChangeEvent(targetNode)) {
3795 getTargetInstFunc = getTargetInstForChangeEvent;
3796 } else if (isTextInputElement(targetNode)) {
3797 if (isInputEventSupported) {
3798 getTargetInstFunc = getTargetInstForInputOrChangeEvent;
3799 } else {
3800 getTargetInstFunc = getTargetInstForInputEventPolyfill;
3801 handleEventFunc = handleEventsForInputEventPolyfill;
3802 }
3803 } else if (shouldUseClickEvent(targetNode)) {
3804 getTargetInstFunc = getTargetInstForClickEvent;
3805 }
3806
3807 if (getTargetInstFunc) {
3808 var inst = getTargetInstFunc(topLevelType, targetInst);
3809 if (inst) {
3810 var event = createAndAccumulateChangeEvent(inst, nativeEvent, nativeEventTarget);
3811 return event;
3812 }
3813 }
3814
3815 if (handleEventFunc) {
3816 handleEventFunc(topLevelType, targetNode, targetInst);
3817 }
3818
3819 // When blurring, set the value attribute for number inputs
3820 if (topLevelType === TOP_BLUR) {
3821 handleControlledInputBlur(targetNode);
3822 }
3823 }
3824};
3825
3826/**
3827 * Module that is injectable into `EventPluginHub`, that specifies a
3828 * deterministic ordering of `EventPlugin`s. A convenient way to reason about
3829 * plugins, without having to package every one of them. This is better than
3830 * having plugins be ordered in the same order that they are injected because
3831 * that ordering would be influenced by the packaging order.
3832 * `ResponderEventPlugin` must occur before `SimpleEventPlugin` so that
3833 * preventing default on events is convenient in `SimpleEventPlugin` handlers.
3834 */
3835var DOMEventPluginOrder = ['ResponderEventPlugin', 'SimpleEventPlugin', 'EnterLeaveEventPlugin', 'ChangeEventPlugin', 'SelectEventPlugin', 'BeforeInputEventPlugin'];
3836
3837var SyntheticUIEvent = SyntheticEvent.extend({
3838 view: null,
3839 detail: null
3840});
3841
3842var modifierKeyToProp = {
3843 Alt: 'altKey',
3844 Control: 'ctrlKey',
3845 Meta: 'metaKey',
3846 Shift: 'shiftKey'
3847};
3848
3849// Older browsers (Safari <= 10, iOS Safari <= 10.2) do not support
3850// getModifierState. If getModifierState is not supported, we map it to a set of
3851// modifier keys exposed by the event. In this case, Lock-keys are not supported.
3852/**
3853 * Translation from modifier key to the associated property in the event.
3854 * @see http://www.w3.org/TR/DOM-Level-3-Events/#keys-Modifiers
3855 */
3856
3857function modifierStateGetter(keyArg) {
3858 var syntheticEvent = this;
3859 var nativeEvent = syntheticEvent.nativeEvent;
3860 if (nativeEvent.getModifierState) {
3861 return nativeEvent.getModifierState(keyArg);
3862 }
3863 var keyProp = modifierKeyToProp[keyArg];
3864 return keyProp ? !!nativeEvent[keyProp] : false;
3865}
3866
3867function getEventModifierState(nativeEvent) {
3868 return modifierStateGetter;
3869}
3870
3871var previousScreenX = 0;
3872var previousScreenY = 0;
3873// Use flags to signal movementX/Y has already been set
3874var isMovementXSet = false;
3875var isMovementYSet = false;
3876
3877/**
3878 * @interface MouseEvent
3879 * @see http://www.w3.org/TR/DOM-Level-3-Events/
3880 */
3881var SyntheticMouseEvent = SyntheticUIEvent.extend({
3882 screenX: null,
3883 screenY: null,
3884 clientX: null,
3885 clientY: null,
3886 pageX: null,
3887 pageY: null,
3888 ctrlKey: null,
3889 shiftKey: null,
3890 altKey: null,
3891 metaKey: null,
3892 getModifierState: getEventModifierState,
3893 button: null,
3894 buttons: null,
3895 relatedTarget: function (event) {
3896 return event.relatedTarget || (event.fromElement === event.srcElement ? event.toElement : event.fromElement);
3897 },
3898 movementX: function (event) {
3899 if ('movementX' in event) {
3900 return event.movementX;
3901 }
3902
3903 var screenX = previousScreenX;
3904 previousScreenX = event.screenX;
3905
3906 if (!isMovementXSet) {
3907 isMovementXSet = true;
3908 return 0;
3909 }
3910
3911 return event.type === 'mousemove' ? event.screenX - screenX : 0;
3912 },
3913 movementY: function (event) {
3914 if ('movementY' in event) {
3915 return event.movementY;
3916 }
3917
3918 var screenY = previousScreenY;
3919 previousScreenY = event.screenY;
3920
3921 if (!isMovementYSet) {
3922 isMovementYSet = true;
3923 return 0;
3924 }
3925
3926 return event.type === 'mousemove' ? event.screenY - screenY : 0;
3927 }
3928});
3929
3930/**
3931 * @interface PointerEvent
3932 * @see http://www.w3.org/TR/pointerevents/
3933 */
3934var SyntheticPointerEvent = SyntheticMouseEvent.extend({
3935 pointerId: null,
3936 width: null,
3937 height: null,
3938 pressure: null,
3939 tangentialPressure: null,
3940 tiltX: null,
3941 tiltY: null,
3942 twist: null,
3943 pointerType: null,
3944 isPrimary: null
3945});
3946
3947var eventTypes$2 = {
3948 mouseEnter: {
3949 registrationName: 'onMouseEnter',
3950 dependencies: [TOP_MOUSE_OUT, TOP_MOUSE_OVER]
3951 },
3952 mouseLeave: {
3953 registrationName: 'onMouseLeave',
3954 dependencies: [TOP_MOUSE_OUT, TOP_MOUSE_OVER]
3955 },
3956 pointerEnter: {
3957 registrationName: 'onPointerEnter',
3958 dependencies: [TOP_POINTER_OUT, TOP_POINTER_OVER]
3959 },
3960 pointerLeave: {
3961 registrationName: 'onPointerLeave',
3962 dependencies: [TOP_POINTER_OUT, TOP_POINTER_OVER]
3963 }
3964};
3965
3966var EnterLeaveEventPlugin = {
3967 eventTypes: eventTypes$2,
3968
3969 /**
3970 * For almost every interaction we care about, there will be both a top-level
3971 * `mouseover` and `mouseout` event that occurs. Only use `mouseout` so that
3972 * we do not extract duplicate events. However, moving the mouse into the
3973 * browser from outside will not fire a `mouseout` event. In this case, we use
3974 * the `mouseover` top-level event.
3975 */
3976 extractEvents: function (topLevelType, targetInst, nativeEvent, nativeEventTarget) {
3977 var isOverEvent = topLevelType === TOP_MOUSE_OVER || topLevelType === TOP_POINTER_OVER;
3978 var isOutEvent = topLevelType === TOP_MOUSE_OUT || topLevelType === TOP_POINTER_OUT;
3979
3980 if (isOverEvent && (nativeEvent.relatedTarget || nativeEvent.fromElement)) {
3981 return null;
3982 }
3983
3984 if (!isOutEvent && !isOverEvent) {
3985 // Must not be a mouse or pointer in or out - ignoring.
3986 return null;
3987 }
3988
3989 var win = void 0;
3990 if (nativeEventTarget.window === nativeEventTarget) {
3991 // `nativeEventTarget` is probably a window object.
3992 win = nativeEventTarget;
3993 } else {
3994 // TODO: Figure out why `ownerDocument` is sometimes undefined in IE8.
3995 var doc = nativeEventTarget.ownerDocument;
3996 if (doc) {
3997 win = doc.defaultView || doc.parentWindow;
3998 } else {
3999 win = window;
4000 }
4001 }
4002
4003 var from = void 0;
4004 var to = void 0;
4005 if (isOutEvent) {
4006 from = targetInst;
4007 var related = nativeEvent.relatedTarget || nativeEvent.toElement;
4008 to = related ? getClosestInstanceFromNode(related) : null;
4009 } else {
4010 // Moving to a node from outside the window.
4011 from = null;
4012 to = targetInst;
4013 }
4014
4015 if (from === to) {
4016 // Nothing pertains to our managed components.
4017 return null;
4018 }
4019
4020 var eventInterface = void 0,
4021 leaveEventType = void 0,
4022 enterEventType = void 0,
4023 eventTypePrefix = void 0;
4024
4025 if (topLevelType === TOP_MOUSE_OUT || topLevelType === TOP_MOUSE_OVER) {
4026 eventInterface = SyntheticMouseEvent;
4027 leaveEventType = eventTypes$2.mouseLeave;
4028 enterEventType = eventTypes$2.mouseEnter;
4029 eventTypePrefix = 'mouse';
4030 } else if (topLevelType === TOP_POINTER_OUT || topLevelType === TOP_POINTER_OVER) {
4031 eventInterface = SyntheticPointerEvent;
4032 leaveEventType = eventTypes$2.pointerLeave;
4033 enterEventType = eventTypes$2.pointerEnter;
4034 eventTypePrefix = 'pointer';
4035 }
4036
4037 var fromNode = from == null ? win : getNodeFromInstance$1(from);
4038 var toNode = to == null ? win : getNodeFromInstance$1(to);
4039
4040 var leave = eventInterface.getPooled(leaveEventType, from, nativeEvent, nativeEventTarget);
4041 leave.type = eventTypePrefix + 'leave';
4042 leave.target = fromNode;
4043 leave.relatedTarget = toNode;
4044
4045 var enter = eventInterface.getPooled(enterEventType, to, nativeEvent, nativeEventTarget);
4046 enter.type = eventTypePrefix + 'enter';
4047 enter.target = toNode;
4048 enter.relatedTarget = fromNode;
4049
4050 accumulateEnterLeaveDispatches(leave, enter, from, to);
4051
4052 return [leave, enter];
4053 }
4054};
4055
4056/*eslint-disable no-self-compare */
4057
4058var hasOwnProperty$1 = Object.prototype.hasOwnProperty;
4059
4060/**
4061 * inlined Object.is polyfill to avoid requiring consumers ship their own
4062 * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is
4063 */
4064function is(x, y) {
4065 // SameValue algorithm
4066 if (x === y) {
4067 // Steps 1-5, 7-10
4068 // Steps 6.b-6.e: +0 != -0
4069 // Added the nonzero y check to make Flow happy, but it is redundant
4070 return x !== 0 || y !== 0 || 1 / x === 1 / y;
4071 } else {
4072 // Step 6.a: NaN == NaN
4073 return x !== x && y !== y;
4074 }
4075}
4076
4077/**
4078 * Performs equality by iterating through keys on an object and returning false
4079 * when any key has values which are not strictly equal between the arguments.
4080 * Returns true when the values of all keys are strictly equal.
4081 */
4082function shallowEqual(objA, objB) {
4083 if (is(objA, objB)) {
4084 return true;
4085 }
4086
4087 if (typeof objA !== 'object' || objA === null || typeof objB !== 'object' || objB === null) {
4088 return false;
4089 }
4090
4091 var keysA = Object.keys(objA);
4092 var keysB = Object.keys(objB);
4093
4094 if (keysA.length !== keysB.length) {
4095 return false;
4096 }
4097
4098 // Test for A's keys different from B.
4099 for (var i = 0; i < keysA.length; i++) {
4100 if (!hasOwnProperty$1.call(objB, keysA[i]) || !is(objA[keysA[i]], objB[keysA[i]])) {
4101 return false;
4102 }
4103 }
4104
4105 return true;
4106}
4107
4108/**
4109 * `ReactInstanceMap` maintains a mapping from a public facing stateful
4110 * instance (key) and the internal representation (value). This allows public
4111 * methods to accept the user facing instance as an argument and map them back
4112 * to internal methods.
4113 *
4114 * Note that this module is currently shared and assumed to be stateless.
4115 * If this becomes an actual Map, that will break.
4116 */
4117
4118/**
4119 * This API should be called `delete` but we'd have to make sure to always
4120 * transform these to strings for IE support. When this transform is fully
4121 * supported we can rename it.
4122 */
4123
4124
4125function get(key) {
4126 return key._reactInternalFiber;
4127}
4128
4129function has(key) {
4130 return key._reactInternalFiber !== undefined;
4131}
4132
4133function set(key, value) {
4134 key._reactInternalFiber = value;
4135}
4136
4137// Don't change these two values. They're used by React Dev Tools.
4138var NoEffect = /* */0;
4139var PerformedWork = /* */1;
4140
4141// You can change the rest (and add more).
4142var Placement = /* */2;
4143var Update = /* */4;
4144var PlacementAndUpdate = /* */6;
4145var Deletion = /* */8;
4146var ContentReset = /* */16;
4147var Callback = /* */32;
4148var DidCapture = /* */64;
4149var Ref = /* */128;
4150var Snapshot = /* */256;
4151var Passive = /* */512;
4152
4153// Passive & Update & Callback & Ref & Snapshot
4154var LifecycleEffectMask = /* */932;
4155
4156// Union of all host effects
4157var HostEffectMask = /* */1023;
4158
4159var Incomplete = /* */1024;
4160var ShouldCapture = /* */2048;
4161
4162var ReactCurrentOwner$1 = ReactSharedInternals.ReactCurrentOwner;
4163
4164var MOUNTING = 1;
4165var MOUNTED = 2;
4166var UNMOUNTED = 3;
4167
4168function isFiberMountedImpl(fiber) {
4169 var node = fiber;
4170 if (!fiber.alternate) {
4171 // If there is no alternate, this might be a new tree that isn't inserted
4172 // yet. If it is, then it will have a pending insertion effect on it.
4173 if ((node.effectTag & Placement) !== NoEffect) {
4174 return MOUNTING;
4175 }
4176 while (node.return) {
4177 node = node.return;
4178 if ((node.effectTag & Placement) !== NoEffect) {
4179 return MOUNTING;
4180 }
4181 }
4182 } else {
4183 while (node.return) {
4184 node = node.return;
4185 }
4186 }
4187 if (node.tag === HostRoot) {
4188 // TODO: Check if this was a nested HostRoot when used with
4189 // renderContainerIntoSubtree.
4190 return MOUNTED;
4191 }
4192 // If we didn't hit the root, that means that we're in an disconnected tree
4193 // that has been unmounted.
4194 return UNMOUNTED;
4195}
4196
4197function isFiberMounted(fiber) {
4198 return isFiberMountedImpl(fiber) === MOUNTED;
4199}
4200
4201function isMounted(component) {
4202 {
4203 var owner = ReactCurrentOwner$1.current;
4204 if (owner !== null && owner.tag === ClassComponent) {
4205 var ownerFiber = owner;
4206 var instance = ownerFiber.stateNode;
4207 !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;
4208 instance._warnedAboutRefsInRender = true;
4209 }
4210 }
4211
4212 var fiber = get(component);
4213 if (!fiber) {
4214 return false;
4215 }
4216 return isFiberMountedImpl(fiber) === MOUNTED;
4217}
4218
4219function assertIsMounted(fiber) {
4220 !(isFiberMountedImpl(fiber) === MOUNTED) ? invariant(false, 'Unable to find node on an unmounted component.') : void 0;
4221}
4222
4223function findCurrentFiberUsingSlowPath(fiber) {
4224 var alternate = fiber.alternate;
4225 if (!alternate) {
4226 // If there is no alternate, then we only need to check if it is mounted.
4227 var state = isFiberMountedImpl(fiber);
4228 !(state !== UNMOUNTED) ? invariant(false, 'Unable to find node on an unmounted component.') : void 0;
4229 if (state === MOUNTING) {
4230 return null;
4231 }
4232 return fiber;
4233 }
4234 // If we have two possible branches, we'll walk backwards up to the root
4235 // to see what path the root points to. On the way we may hit one of the
4236 // special cases and we'll deal with them.
4237 var a = fiber;
4238 var b = alternate;
4239 while (true) {
4240 var parentA = a.return;
4241 var parentB = parentA ? parentA.alternate : null;
4242 if (!parentA || !parentB) {
4243 // We're at the root.
4244 break;
4245 }
4246
4247 // If both copies of the parent fiber point to the same child, we can
4248 // assume that the child is current. This happens when we bailout on low
4249 // priority: the bailed out fiber's child reuses the current child.
4250 if (parentA.child === parentB.child) {
4251 var child = parentA.child;
4252 while (child) {
4253 if (child === a) {
4254 // We've determined that A is the current branch.
4255 assertIsMounted(parentA);
4256 return fiber;
4257 }
4258 if (child === b) {
4259 // We've determined that B is the current branch.
4260 assertIsMounted(parentA);
4261 return alternate;
4262 }
4263 child = child.sibling;
4264 }
4265 // We should never have an alternate for any mounting node. So the only
4266 // way this could possibly happen is if this was unmounted, if at all.
4267 invariant(false, 'Unable to find node on an unmounted component.');
4268 }
4269
4270 if (a.return !== b.return) {
4271 // The return pointer of A and the return pointer of B point to different
4272 // fibers. We assume that return pointers never criss-cross, so A must
4273 // belong to the child set of A.return, and B must belong to the child
4274 // set of B.return.
4275 a = parentA;
4276 b = parentB;
4277 } else {
4278 // The return pointers point to the same fiber. We'll have to use the
4279 // default, slow path: scan the child sets of each parent alternate to see
4280 // which child belongs to which set.
4281 //
4282 // Search parent A's child set
4283 var didFindChild = false;
4284 var _child = parentA.child;
4285 while (_child) {
4286 if (_child === a) {
4287 didFindChild = true;
4288 a = parentA;
4289 b = parentB;
4290 break;
4291 }
4292 if (_child === b) {
4293 didFindChild = true;
4294 b = parentA;
4295 a = parentB;
4296 break;
4297 }
4298 _child = _child.sibling;
4299 }
4300 if (!didFindChild) {
4301 // Search parent B's child set
4302 _child = parentB.child;
4303 while (_child) {
4304 if (_child === a) {
4305 didFindChild = true;
4306 a = parentB;
4307 b = parentA;
4308 break;
4309 }
4310 if (_child === b) {
4311 didFindChild = true;
4312 b = parentB;
4313 a = parentA;
4314 break;
4315 }
4316 _child = _child.sibling;
4317 }
4318 !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;
4319 }
4320 }
4321
4322 !(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;
4323 }
4324 // If the root is not a host container, we're in a disconnected tree. I.e.
4325 // unmounted.
4326 !(a.tag === HostRoot) ? invariant(false, 'Unable to find node on an unmounted component.') : void 0;
4327 if (a.stateNode.current === a) {
4328 // We've determined that A is the current branch.
4329 return fiber;
4330 }
4331 // Otherwise B has to be current branch.
4332 return alternate;
4333}
4334
4335function findCurrentHostFiber(parent) {
4336 var currentParent = findCurrentFiberUsingSlowPath(parent);
4337 if (!currentParent) {
4338 return null;
4339 }
4340
4341 // Next we'll drill down this component to find the first HostComponent/Text.
4342 var node = currentParent;
4343 while (true) {
4344 if (node.tag === HostComponent || node.tag === HostText) {
4345 return node;
4346 } else if (node.child) {
4347 node.child.return = node;
4348 node = node.child;
4349 continue;
4350 }
4351 if (node === currentParent) {
4352 return null;
4353 }
4354 while (!node.sibling) {
4355 if (!node.return || node.return === currentParent) {
4356 return null;
4357 }
4358 node = node.return;
4359 }
4360 node.sibling.return = node.return;
4361 node = node.sibling;
4362 }
4363 // Flow needs the return null here, but ESLint complains about it.
4364 // eslint-disable-next-line no-unreachable
4365 return null;
4366}
4367
4368function findCurrentHostFiberWithNoPortals(parent) {
4369 var currentParent = findCurrentFiberUsingSlowPath(parent);
4370 if (!currentParent) {
4371 return null;
4372 }
4373
4374 // Next we'll drill down this component to find the first HostComponent/Text.
4375 var node = currentParent;
4376 while (true) {
4377 if (node.tag === HostComponent || node.tag === HostText) {
4378 return node;
4379 } else if (node.child && node.tag !== HostPortal) {
4380 node.child.return = node;
4381 node = node.child;
4382 continue;
4383 }
4384 if (node === currentParent) {
4385 return null;
4386 }
4387 while (!node.sibling) {
4388 if (!node.return || node.return === currentParent) {
4389 return null;
4390 }
4391 node = node.return;
4392 }
4393 node.sibling.return = node.return;
4394 node = node.sibling;
4395 }
4396 // Flow needs the return null here, but ESLint complains about it.
4397 // eslint-disable-next-line no-unreachable
4398 return null;
4399}
4400
4401function addEventBubbleListener(element, eventType, listener) {
4402 element.addEventListener(eventType, listener, false);
4403}
4404
4405function addEventCaptureListener(element, eventType, listener) {
4406 element.addEventListener(eventType, listener, true);
4407}
4408
4409/**
4410 * @interface Event
4411 * @see http://www.w3.org/TR/css3-animations/#AnimationEvent-interface
4412 * @see https://developer.mozilla.org/en-US/docs/Web/API/AnimationEvent
4413 */
4414var SyntheticAnimationEvent = SyntheticEvent.extend({
4415 animationName: null,
4416 elapsedTime: null,
4417 pseudoElement: null
4418});
4419
4420/**
4421 * @interface Event
4422 * @see http://www.w3.org/TR/clipboard-apis/
4423 */
4424var SyntheticClipboardEvent = SyntheticEvent.extend({
4425 clipboardData: function (event) {
4426 return 'clipboardData' in event ? event.clipboardData : window.clipboardData;
4427 }
4428});
4429
4430/**
4431 * @interface FocusEvent
4432 * @see http://www.w3.org/TR/DOM-Level-3-Events/
4433 */
4434var SyntheticFocusEvent = SyntheticUIEvent.extend({
4435 relatedTarget: null
4436});
4437
4438/**
4439 * `charCode` represents the actual "character code" and is safe to use with
4440 * `String.fromCharCode`. As such, only keys that correspond to printable
4441 * characters produce a valid `charCode`, the only exception to this is Enter.
4442 * The Tab-key is considered non-printable and does not have a `charCode`,
4443 * presumably because it does not produce a tab-character in browsers.
4444 *
4445 * @param {object} nativeEvent Native browser event.
4446 * @return {number} Normalized `charCode` property.
4447 */
4448function getEventCharCode(nativeEvent) {
4449 var charCode = void 0;
4450 var keyCode = nativeEvent.keyCode;
4451
4452 if ('charCode' in nativeEvent) {
4453 charCode = nativeEvent.charCode;
4454
4455 // FF does not set `charCode` for the Enter-key, check against `keyCode`.
4456 if (charCode === 0 && keyCode === 13) {
4457 charCode = 13;
4458 }
4459 } else {
4460 // IE8 does not implement `charCode`, but `keyCode` has the correct value.
4461 charCode = keyCode;
4462 }
4463
4464 // IE and Edge (on Windows) and Chrome / Safari (on Windows and Linux)
4465 // report Enter as charCode 10 when ctrl is pressed.
4466 if (charCode === 10) {
4467 charCode = 13;
4468 }
4469
4470 // Some non-printable keys are reported in `charCode`/`keyCode`, discard them.
4471 // Must not discard the (non-)printable Enter-key.
4472 if (charCode >= 32 || charCode === 13) {
4473 return charCode;
4474 }
4475
4476 return 0;
4477}
4478
4479/**
4480 * Normalization of deprecated HTML5 `key` values
4481 * @see https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent#Key_names
4482 */
4483var normalizeKey = {
4484 Esc: 'Escape',
4485 Spacebar: ' ',
4486 Left: 'ArrowLeft',
4487 Up: 'ArrowUp',
4488 Right: 'ArrowRight',
4489 Down: 'ArrowDown',
4490 Del: 'Delete',
4491 Win: 'OS',
4492 Menu: 'ContextMenu',
4493 Apps: 'ContextMenu',
4494 Scroll: 'ScrollLock',
4495 MozPrintableKey: 'Unidentified'
4496};
4497
4498/**
4499 * Translation from legacy `keyCode` to HTML5 `key`
4500 * Only special keys supported, all others depend on keyboard layout or browser
4501 * @see https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent#Key_names
4502 */
4503var translateToKey = {
4504 '8': 'Backspace',
4505 '9': 'Tab',
4506 '12': 'Clear',
4507 '13': 'Enter',
4508 '16': 'Shift',
4509 '17': 'Control',
4510 '18': 'Alt',
4511 '19': 'Pause',
4512 '20': 'CapsLock',
4513 '27': 'Escape',
4514 '32': ' ',
4515 '33': 'PageUp',
4516 '34': 'PageDown',
4517 '35': 'End',
4518 '36': 'Home',
4519 '37': 'ArrowLeft',
4520 '38': 'ArrowUp',
4521 '39': 'ArrowRight',
4522 '40': 'ArrowDown',
4523 '45': 'Insert',
4524 '46': 'Delete',
4525 '112': 'F1',
4526 '113': 'F2',
4527 '114': 'F3',
4528 '115': 'F4',
4529 '116': 'F5',
4530 '117': 'F6',
4531 '118': 'F7',
4532 '119': 'F8',
4533 '120': 'F9',
4534 '121': 'F10',
4535 '122': 'F11',
4536 '123': 'F12',
4537 '144': 'NumLock',
4538 '145': 'ScrollLock',
4539 '224': 'Meta'
4540};
4541
4542/**
4543 * @param {object} nativeEvent Native browser event.
4544 * @return {string} Normalized `key` property.
4545 */
4546function getEventKey(nativeEvent) {
4547 if (nativeEvent.key) {
4548 // Normalize inconsistent values reported by browsers due to
4549 // implementations of a working draft specification.
4550
4551 // FireFox implements `key` but returns `MozPrintableKey` for all
4552 // printable characters (normalized to `Unidentified`), ignore it.
4553 var key = normalizeKey[nativeEvent.key] || nativeEvent.key;
4554 if (key !== 'Unidentified') {
4555 return key;
4556 }
4557 }
4558
4559 // Browser does not implement `key`, polyfill as much of it as we can.
4560 if (nativeEvent.type === 'keypress') {
4561 var charCode = getEventCharCode(nativeEvent);
4562
4563 // The enter-key is technically both printable and non-printable and can
4564 // thus be captured by `keypress`, no other non-printable key should.
4565 return charCode === 13 ? 'Enter' : String.fromCharCode(charCode);
4566 }
4567 if (nativeEvent.type === 'keydown' || nativeEvent.type === 'keyup') {
4568 // While user keyboard layout determines the actual meaning of each
4569 // `keyCode` value, almost all function keys have a universal value.
4570 return translateToKey[nativeEvent.keyCode] || 'Unidentified';
4571 }
4572 return '';
4573}
4574
4575/**
4576 * @interface KeyboardEvent
4577 * @see http://www.w3.org/TR/DOM-Level-3-Events/
4578 */
4579var SyntheticKeyboardEvent = SyntheticUIEvent.extend({
4580 key: getEventKey,
4581 location: null,
4582 ctrlKey: null,
4583 shiftKey: null,
4584 altKey: null,
4585 metaKey: null,
4586 repeat: null,
4587 locale: null,
4588 getModifierState: getEventModifierState,
4589 // Legacy Interface
4590 charCode: function (event) {
4591 // `charCode` is the result of a KeyPress event and represents the value of
4592 // the actual printable character.
4593
4594 // KeyPress is deprecated, but its replacement is not yet final and not
4595 // implemented in any major browser. Only KeyPress has charCode.
4596 if (event.type === 'keypress') {
4597 return getEventCharCode(event);
4598 }
4599 return 0;
4600 },
4601 keyCode: function (event) {
4602 // `keyCode` is the result of a KeyDown/Up event and represents the value of
4603 // physical keyboard key.
4604
4605 // The actual meaning of the value depends on the users' keyboard layout
4606 // which cannot be detected. Assuming that it is a US keyboard layout
4607 // provides a surprisingly accurate mapping for US and European users.
4608 // Due to this, it is left to the user to implement at this time.
4609 if (event.type === 'keydown' || event.type === 'keyup') {
4610 return event.keyCode;
4611 }
4612 return 0;
4613 },
4614 which: function (event) {
4615 // `which` is an alias for either `keyCode` or `charCode` depending on the
4616 // type of the event.
4617 if (event.type === 'keypress') {
4618 return getEventCharCode(event);
4619 }
4620 if (event.type === 'keydown' || event.type === 'keyup') {
4621 return event.keyCode;
4622 }
4623 return 0;
4624 }
4625});
4626
4627/**
4628 * @interface DragEvent
4629 * @see http://www.w3.org/TR/DOM-Level-3-Events/
4630 */
4631var SyntheticDragEvent = SyntheticMouseEvent.extend({
4632 dataTransfer: null
4633});
4634
4635/**
4636 * @interface TouchEvent
4637 * @see http://www.w3.org/TR/touch-events/
4638 */
4639var SyntheticTouchEvent = SyntheticUIEvent.extend({
4640 touches: null,
4641 targetTouches: null,
4642 changedTouches: null,
4643 altKey: null,
4644 metaKey: null,
4645 ctrlKey: null,
4646 shiftKey: null,
4647 getModifierState: getEventModifierState
4648});
4649
4650/**
4651 * @interface Event
4652 * @see http://www.w3.org/TR/2009/WD-css3-transitions-20090320/#transition-events-
4653 * @see https://developer.mozilla.org/en-US/docs/Web/API/TransitionEvent
4654 */
4655var SyntheticTransitionEvent = SyntheticEvent.extend({
4656 propertyName: null,
4657 elapsedTime: null,
4658 pseudoElement: null
4659});
4660
4661/**
4662 * @interface WheelEvent
4663 * @see http://www.w3.org/TR/DOM-Level-3-Events/
4664 */
4665var SyntheticWheelEvent = SyntheticMouseEvent.extend({
4666 deltaX: function (event) {
4667 return 'deltaX' in event ? event.deltaX : // Fallback to `wheelDeltaX` for Webkit and normalize (right is positive).
4668 'wheelDeltaX' in event ? -event.wheelDeltaX : 0;
4669 },
4670 deltaY: function (event) {
4671 return 'deltaY' in event ? event.deltaY : // Fallback to `wheelDeltaY` for Webkit and normalize (down is positive).
4672 'wheelDeltaY' in event ? -event.wheelDeltaY : // Fallback to `wheelDelta` for IE<9 and normalize (down is positive).
4673 'wheelDelta' in event ? -event.wheelDelta : 0;
4674 },
4675
4676 deltaZ: null,
4677
4678 // Browsers without "deltaMode" is reporting in raw wheel delta where one
4679 // notch on the scroll is always +/- 120, roughly equivalent to pixels.
4680 // A good approximation of DOM_DELTA_LINE (1) is 5% of viewport size or
4681 // ~40 pixels, for DOM_DELTA_SCREEN (2) it is 87.5% of viewport size.
4682 deltaMode: null
4683});
4684
4685/**
4686 * Turns
4687 * ['abort', ...]
4688 * into
4689 * eventTypes = {
4690 * 'abort': {
4691 * phasedRegistrationNames: {
4692 * bubbled: 'onAbort',
4693 * captured: 'onAbortCapture',
4694 * },
4695 * dependencies: [TOP_ABORT],
4696 * },
4697 * ...
4698 * };
4699 * topLevelEventsToDispatchConfig = new Map([
4700 * [TOP_ABORT, { sameConfig }],
4701 * ]);
4702 */
4703
4704var 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']];
4705var 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']];
4706
4707var eventTypes$4 = {};
4708var topLevelEventsToDispatchConfig = {};
4709
4710function addEventTypeNameToConfig(_ref, isInteractive) {
4711 var topEvent = _ref[0],
4712 event = _ref[1];
4713
4714 var capitalizedEvent = event[0].toUpperCase() + event.slice(1);
4715 var onEvent = 'on' + capitalizedEvent;
4716
4717 var type = {
4718 phasedRegistrationNames: {
4719 bubbled: onEvent,
4720 captured: onEvent + 'Capture'
4721 },
4722 dependencies: [topEvent],
4723 isInteractive: isInteractive
4724 };
4725 eventTypes$4[event] = type;
4726 topLevelEventsToDispatchConfig[topEvent] = type;
4727}
4728
4729interactiveEventTypeNames.forEach(function (eventTuple) {
4730 addEventTypeNameToConfig(eventTuple, true);
4731});
4732nonInteractiveEventTypeNames.forEach(function (eventTuple) {
4733 addEventTypeNameToConfig(eventTuple, false);
4734});
4735
4736// Only used in DEV for exhaustiveness validation.
4737var 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];
4738
4739var SimpleEventPlugin = {
4740 eventTypes: eventTypes$4,
4741
4742 isInteractiveTopLevelEventType: function (topLevelType) {
4743 var config = topLevelEventsToDispatchConfig[topLevelType];
4744 return config !== undefined && config.isInteractive === true;
4745 },
4746
4747
4748 extractEvents: function (topLevelType, targetInst, nativeEvent, nativeEventTarget) {
4749 var dispatchConfig = topLevelEventsToDispatchConfig[topLevelType];
4750 if (!dispatchConfig) {
4751 return null;
4752 }
4753 var EventConstructor = void 0;
4754 switch (topLevelType) {
4755 case TOP_KEY_PRESS:
4756 // Firefox creates a keypress event for function keys too. This removes
4757 // the unwanted keypress events. Enter is however both printable and
4758 // non-printable. One would expect Tab to be as well (but it isn't).
4759 if (getEventCharCode(nativeEvent) === 0) {
4760 return null;
4761 }
4762 /* falls through */
4763 case TOP_KEY_DOWN:
4764 case TOP_KEY_UP:
4765 EventConstructor = SyntheticKeyboardEvent;
4766 break;
4767 case TOP_BLUR:
4768 case TOP_FOCUS:
4769 EventConstructor = SyntheticFocusEvent;
4770 break;
4771 case TOP_CLICK:
4772 // Firefox creates a click event on right mouse clicks. This removes the
4773 // unwanted click events.
4774 if (nativeEvent.button === 2) {
4775 return null;
4776 }
4777 /* falls through */
4778 case TOP_AUX_CLICK:
4779 case TOP_DOUBLE_CLICK:
4780 case TOP_MOUSE_DOWN:
4781 case TOP_MOUSE_MOVE:
4782 case TOP_MOUSE_UP:
4783 // TODO: Disabled elements should not respond to mouse events
4784 /* falls through */
4785 case TOP_MOUSE_OUT:
4786 case TOP_MOUSE_OVER:
4787 case TOP_CONTEXT_MENU:
4788 EventConstructor = SyntheticMouseEvent;
4789 break;
4790 case TOP_DRAG:
4791 case TOP_DRAG_END:
4792 case TOP_DRAG_ENTER:
4793 case TOP_DRAG_EXIT:
4794 case TOP_DRAG_LEAVE:
4795 case TOP_DRAG_OVER:
4796 case TOP_DRAG_START:
4797 case TOP_DROP:
4798 EventConstructor = SyntheticDragEvent;
4799 break;
4800 case TOP_TOUCH_CANCEL:
4801 case TOP_TOUCH_END:
4802 case TOP_TOUCH_MOVE:
4803 case TOP_TOUCH_START:
4804 EventConstructor = SyntheticTouchEvent;
4805 break;
4806 case TOP_ANIMATION_END:
4807 case TOP_ANIMATION_ITERATION:
4808 case TOP_ANIMATION_START:
4809 EventConstructor = SyntheticAnimationEvent;
4810 break;
4811 case TOP_TRANSITION_END:
4812 EventConstructor = SyntheticTransitionEvent;
4813 break;
4814 case TOP_SCROLL:
4815 EventConstructor = SyntheticUIEvent;
4816 break;
4817 case TOP_WHEEL:
4818 EventConstructor = SyntheticWheelEvent;
4819 break;
4820 case TOP_COPY:
4821 case TOP_CUT:
4822 case TOP_PASTE:
4823 EventConstructor = SyntheticClipboardEvent;
4824 break;
4825 case TOP_GOT_POINTER_CAPTURE:
4826 case TOP_LOST_POINTER_CAPTURE:
4827 case TOP_POINTER_CANCEL:
4828 case TOP_POINTER_DOWN:
4829 case TOP_POINTER_MOVE:
4830 case TOP_POINTER_OUT:
4831 case TOP_POINTER_OVER:
4832 case TOP_POINTER_UP:
4833 EventConstructor = SyntheticPointerEvent;
4834 break;
4835 default:
4836 {
4837 if (knownHTMLTopLevelTypes.indexOf(topLevelType) === -1) {
4838 warningWithoutStack$1(false, 'SimpleEventPlugin: Unhandled event type, `%s`. This warning ' + 'is likely caused by a bug in React. Please file an issue.', topLevelType);
4839 }
4840 }
4841 // HTML Events
4842 // @see http://www.w3.org/TR/html5/index.html#events-0
4843 EventConstructor = SyntheticEvent;
4844 break;
4845 }
4846 var event = EventConstructor.getPooled(dispatchConfig, targetInst, nativeEvent, nativeEventTarget);
4847 accumulateTwoPhaseDispatches(event);
4848 return event;
4849 }
4850};
4851
4852var isInteractiveTopLevelEventType = SimpleEventPlugin.isInteractiveTopLevelEventType;
4853
4854
4855var CALLBACK_BOOKKEEPING_POOL_SIZE = 10;
4856var callbackBookkeepingPool = [];
4857
4858/**
4859 * Find the deepest React component completely containing the root of the
4860 * passed-in instance (for use when entire React trees are nested within each
4861 * other). If React trees are not nested, returns null.
4862 */
4863function findRootContainerNode(inst) {
4864 // TODO: It may be a good idea to cache this to prevent unnecessary DOM
4865 // traversal, but caching is difficult to do correctly without using a
4866 // mutation observer to listen for all DOM changes.
4867 while (inst.return) {
4868 inst = inst.return;
4869 }
4870 if (inst.tag !== HostRoot) {
4871 // This can happen if we're in a detached tree.
4872 return null;
4873 }
4874 return inst.stateNode.containerInfo;
4875}
4876
4877// Used to store ancestor hierarchy in top level callback
4878function getTopLevelCallbackBookKeeping(topLevelType, nativeEvent, targetInst) {
4879 if (callbackBookkeepingPool.length) {
4880 var instance = callbackBookkeepingPool.pop();
4881 instance.topLevelType = topLevelType;
4882 instance.nativeEvent = nativeEvent;
4883 instance.targetInst = targetInst;
4884 return instance;
4885 }
4886 return {
4887 topLevelType: topLevelType,
4888 nativeEvent: nativeEvent,
4889 targetInst: targetInst,
4890 ancestors: []
4891 };
4892}
4893
4894function releaseTopLevelCallbackBookKeeping(instance) {
4895 instance.topLevelType = null;
4896 instance.nativeEvent = null;
4897 instance.targetInst = null;
4898 instance.ancestors.length = 0;
4899 if (callbackBookkeepingPool.length < CALLBACK_BOOKKEEPING_POOL_SIZE) {
4900 callbackBookkeepingPool.push(instance);
4901 }
4902}
4903
4904function handleTopLevel(bookKeeping) {
4905 var targetInst = bookKeeping.targetInst;
4906
4907 // Loop through the hierarchy, in case there's any nested components.
4908 // It's important that we build the array of ancestors before calling any
4909 // event handlers, because event handlers can modify the DOM, leading to
4910 // inconsistencies with ReactMount's node cache. See #1105.
4911 var ancestor = targetInst;
4912 do {
4913 if (!ancestor) {
4914 bookKeeping.ancestors.push(ancestor);
4915 break;
4916 }
4917 var root = findRootContainerNode(ancestor);
4918 if (!root) {
4919 break;
4920 }
4921 bookKeeping.ancestors.push(ancestor);
4922 ancestor = getClosestInstanceFromNode(root);
4923 } while (ancestor);
4924
4925 for (var i = 0; i < bookKeeping.ancestors.length; i++) {
4926 targetInst = bookKeeping.ancestors[i];
4927 runExtractedEventsInBatch(bookKeeping.topLevelType, targetInst, bookKeeping.nativeEvent, getEventTarget(bookKeeping.nativeEvent));
4928 }
4929}
4930
4931// TODO: can we stop exporting these?
4932var _enabled = true;
4933
4934function setEnabled(enabled) {
4935 _enabled = !!enabled;
4936}
4937
4938function isEnabled() {
4939 return _enabled;
4940}
4941
4942/**
4943 * Traps top-level events by using event bubbling.
4944 *
4945 * @param {number} topLevelType Number from `TopLevelEventTypes`.
4946 * @param {object} element Element on which to attach listener.
4947 * @return {?object} An object with a remove function which will forcefully
4948 * remove the listener.
4949 * @internal
4950 */
4951function trapBubbledEvent(topLevelType, element) {
4952 if (!element) {
4953 return null;
4954 }
4955 var dispatch = isInteractiveTopLevelEventType(topLevelType) ? dispatchInteractiveEvent : dispatchEvent;
4956
4957 addEventBubbleListener(element, getRawEventName(topLevelType),
4958 // Check if interactive and wrap in interactiveUpdates
4959 dispatch.bind(null, topLevelType));
4960}
4961
4962/**
4963 * Traps a top-level event by using event capturing.
4964 *
4965 * @param {number} topLevelType Number from `TopLevelEventTypes`.
4966 * @param {object} element Element on which to attach listener.
4967 * @return {?object} An object with a remove function which will forcefully
4968 * remove the listener.
4969 * @internal
4970 */
4971function trapCapturedEvent(topLevelType, element) {
4972 if (!element) {
4973 return null;
4974 }
4975 var dispatch = isInteractiveTopLevelEventType(topLevelType) ? dispatchInteractiveEvent : dispatchEvent;
4976
4977 addEventCaptureListener(element, getRawEventName(topLevelType),
4978 // Check if interactive and wrap in interactiveUpdates
4979 dispatch.bind(null, topLevelType));
4980}
4981
4982function dispatchInteractiveEvent(topLevelType, nativeEvent) {
4983 interactiveUpdates(dispatchEvent, topLevelType, nativeEvent);
4984}
4985
4986function dispatchEvent(topLevelType, nativeEvent) {
4987 if (!_enabled) {
4988 return;
4989 }
4990
4991 var nativeEventTarget = getEventTarget(nativeEvent);
4992 var targetInst = getClosestInstanceFromNode(nativeEventTarget);
4993 if (targetInst !== null && typeof targetInst.tag === 'number' && !isFiberMounted(targetInst)) {
4994 // If we get an event (ex: img onload) before committing that
4995 // component's mount, ignore it for now (that is, treat it as if it was an
4996 // event on a non-React tree). We might also consider queueing events and
4997 // dispatching them after the mount.
4998 targetInst = null;
4999 }
5000
5001 var bookKeeping = getTopLevelCallbackBookKeeping(topLevelType, nativeEvent, targetInst);
5002
5003 try {
5004 // Event queue being processed in the same cycle allows
5005 // `preventDefault`.
5006 batchedUpdates(handleTopLevel, bookKeeping);
5007 } finally {
5008 releaseTopLevelCallbackBookKeeping(bookKeeping);
5009 }
5010}
5011
5012/**
5013 * Summary of `ReactBrowserEventEmitter` event handling:
5014 *
5015 * - Top-level delegation is used to trap most native browser events. This
5016 * may only occur in the main thread and is the responsibility of
5017 * ReactDOMEventListener, which is injected and can therefore support
5018 * pluggable event sources. This is the only work that occurs in the main
5019 * thread.
5020 *
5021 * - We normalize and de-duplicate events to account for browser quirks. This
5022 * may be done in the worker thread.
5023 *
5024 * - Forward these native events (with the associated top-level type used to
5025 * trap it) to `EventPluginHub`, which in turn will ask plugins if they want
5026 * to extract any synthetic events.
5027 *
5028 * - The `EventPluginHub` will then process each event by annotating them with
5029 * "dispatches", a sequence of listeners and IDs that care about that event.
5030 *
5031 * - The `EventPluginHub` then dispatches the events.
5032 *
5033 * Overview of React and the event system:
5034 *
5035 * +------------+ .
5036 * | DOM | .
5037 * +------------+ .
5038 * | .
5039 * v .
5040 * +------------+ .
5041 * | ReactEvent | .
5042 * | Listener | .
5043 * +------------+ . +-----------+
5044 * | . +--------+|SimpleEvent|
5045 * | . | |Plugin |
5046 * +-----|------+ . v +-----------+
5047 * | | | . +--------------+ +------------+
5048 * | +-----------.--->|EventPluginHub| | Event |
5049 * | | . | | +-----------+ | Propagators|
5050 * | ReactEvent | . | | |TapEvent | |------------|
5051 * | Emitter | . | |<---+|Plugin | |other plugin|
5052 * | | . | | +-----------+ | utilities |
5053 * | +-----------.--->| | +------------+
5054 * | | | . +--------------+
5055 * +-----|------+ . ^ +-----------+
5056 * | . | |Enter/Leave|
5057 * + . +-------+|Plugin |
5058 * +-------------+ . +-----------+
5059 * | application | .
5060 * |-------------| .
5061 * | | .
5062 * | | .
5063 * +-------------+ .
5064 * .
5065 * React Core . General Purpose Event Plugin System
5066 */
5067
5068var alreadyListeningTo = {};
5069var reactTopListenersCounter = 0;
5070
5071/**
5072 * To ensure no conflicts with other potential React instances on the page
5073 */
5074var topListenersIDKey = '_reactListenersID' + ('' + Math.random()).slice(2);
5075
5076function getListeningForDocument(mountAt) {
5077 // In IE8, `mountAt` is a host object and doesn't have `hasOwnProperty`
5078 // directly.
5079 if (!Object.prototype.hasOwnProperty.call(mountAt, topListenersIDKey)) {
5080 mountAt[topListenersIDKey] = reactTopListenersCounter++;
5081 alreadyListeningTo[mountAt[topListenersIDKey]] = {};
5082 }
5083 return alreadyListeningTo[mountAt[topListenersIDKey]];
5084}
5085
5086/**
5087 * We listen for bubbled touch events on the document object.
5088 *
5089 * Firefox v8.01 (and possibly others) exhibited strange behavior when
5090 * mounting `onmousemove` events at some node that was not the document
5091 * element. The symptoms were that if your mouse is not moving over something
5092 * contained within that mount point (for example on the background) the
5093 * top-level listeners for `onmousemove` won't be called. However, if you
5094 * register the `mousemove` on the document object, then it will of course
5095 * catch all `mousemove`s. This along with iOS quirks, justifies restricting
5096 * top-level listeners to the document object only, at least for these
5097 * movement types of events and possibly all events.
5098 *
5099 * @see http://www.quirksmode.org/blog/archives/2010/09/click_event_del.html
5100 *
5101 * Also, `keyup`/`keypress`/`keydown` do not bubble to the window on IE, but
5102 * they bubble to document.
5103 *
5104 * @param {string} registrationName Name of listener (e.g. `onClick`).
5105 * @param {object} mountAt Container where to mount the listener
5106 */
5107function listenTo(registrationName, mountAt) {
5108 var isListening = getListeningForDocument(mountAt);
5109 var dependencies = registrationNameDependencies[registrationName];
5110
5111 for (var i = 0; i < dependencies.length; i++) {
5112 var dependency = dependencies[i];
5113 if (!(isListening.hasOwnProperty(dependency) && isListening[dependency])) {
5114 switch (dependency) {
5115 case TOP_SCROLL:
5116 trapCapturedEvent(TOP_SCROLL, mountAt);
5117 break;
5118 case TOP_FOCUS:
5119 case TOP_BLUR:
5120 trapCapturedEvent(TOP_FOCUS, mountAt);
5121 trapCapturedEvent(TOP_BLUR, mountAt);
5122 // We set the flag for a single dependency later in this function,
5123 // but this ensures we mark both as attached rather than just one.
5124 isListening[TOP_BLUR] = true;
5125 isListening[TOP_FOCUS] = true;
5126 break;
5127 case TOP_CANCEL:
5128 case TOP_CLOSE:
5129 if (isEventSupported(getRawEventName(dependency))) {
5130 trapCapturedEvent(dependency, mountAt);
5131 }
5132 break;
5133 case TOP_INVALID:
5134 case TOP_SUBMIT:
5135 case TOP_RESET:
5136 // We listen to them on the target DOM elements.
5137 // Some of them bubble so we don't want them to fire twice.
5138 break;
5139 default:
5140 // By default, listen on the top level to all non-media events.
5141 // Media events don't bubble so adding the listener wouldn't do anything.
5142 var isMediaEvent = mediaEventTypes.indexOf(dependency) !== -1;
5143 if (!isMediaEvent) {
5144 trapBubbledEvent(dependency, mountAt);
5145 }
5146 break;
5147 }
5148 isListening[dependency] = true;
5149 }
5150 }
5151}
5152
5153function isListeningToAllDependencies(registrationName, mountAt) {
5154 var isListening = getListeningForDocument(mountAt);
5155 var dependencies = registrationNameDependencies[registrationName];
5156 for (var i = 0; i < dependencies.length; i++) {
5157 var dependency = dependencies[i];
5158 if (!(isListening.hasOwnProperty(dependency) && isListening[dependency])) {
5159 return false;
5160 }
5161 }
5162 return true;
5163}
5164
5165function getActiveElement(doc) {
5166 doc = doc || (typeof document !== 'undefined' ? document : undefined);
5167 if (typeof doc === 'undefined') {
5168 return null;
5169 }
5170 try {
5171 return doc.activeElement || doc.body;
5172 } catch (e) {
5173 return doc.body;
5174 }
5175}
5176
5177/**
5178 * Given any node return the first leaf node without children.
5179 *
5180 * @param {DOMElement|DOMTextNode} node
5181 * @return {DOMElement|DOMTextNode}
5182 */
5183function getLeafNode(node) {
5184 while (node && node.firstChild) {
5185 node = node.firstChild;
5186 }
5187 return node;
5188}
5189
5190/**
5191 * Get the next sibling within a container. This will walk up the
5192 * DOM if a node's siblings have been exhausted.
5193 *
5194 * @param {DOMElement|DOMTextNode} node
5195 * @return {?DOMElement|DOMTextNode}
5196 */
5197function getSiblingNode(node) {
5198 while (node) {
5199 if (node.nextSibling) {
5200 return node.nextSibling;
5201 }
5202 node = node.parentNode;
5203 }
5204}
5205
5206/**
5207 * Get object describing the nodes which contain characters at offset.
5208 *
5209 * @param {DOMElement|DOMTextNode} root
5210 * @param {number} offset
5211 * @return {?object}
5212 */
5213function getNodeForCharacterOffset(root, offset) {
5214 var node = getLeafNode(root);
5215 var nodeStart = 0;
5216 var nodeEnd = 0;
5217
5218 while (node) {
5219 if (node.nodeType === TEXT_NODE) {
5220 nodeEnd = nodeStart + node.textContent.length;
5221
5222 if (nodeStart <= offset && nodeEnd >= offset) {
5223 return {
5224 node: node,
5225 offset: offset - nodeStart
5226 };
5227 }
5228
5229 nodeStart = nodeEnd;
5230 }
5231
5232 node = getLeafNode(getSiblingNode(node));
5233 }
5234}
5235
5236/**
5237 * @param {DOMElement} outerNode
5238 * @return {?object}
5239 */
5240function getOffsets(outerNode) {
5241 var ownerDocument = outerNode.ownerDocument;
5242
5243 var win = ownerDocument && ownerDocument.defaultView || window;
5244 var selection = win.getSelection && win.getSelection();
5245
5246 if (!selection || selection.rangeCount === 0) {
5247 return null;
5248 }
5249
5250 var anchorNode = selection.anchorNode,
5251 anchorOffset = selection.anchorOffset,
5252 focusNode = selection.focusNode,
5253 focusOffset = selection.focusOffset;
5254
5255 // In Firefox, anchorNode and focusNode can be "anonymous divs", e.g. the
5256 // up/down buttons on an <input type="number">. Anonymous divs do not seem to
5257 // expose properties, triggering a "Permission denied error" if any of its
5258 // properties are accessed. The only seemingly possible way to avoid erroring
5259 // is to access a property that typically works for non-anonymous divs and
5260 // catch any error that may otherwise arise. See
5261 // https://bugzilla.mozilla.org/show_bug.cgi?id=208427
5262
5263 try {
5264 /* eslint-disable no-unused-expressions */
5265 anchorNode.nodeType;
5266 focusNode.nodeType;
5267 /* eslint-enable no-unused-expressions */
5268 } catch (e) {
5269 return null;
5270 }
5271
5272 return getModernOffsetsFromPoints(outerNode, anchorNode, anchorOffset, focusNode, focusOffset);
5273}
5274
5275/**
5276 * Returns {start, end} where `start` is the character/codepoint index of
5277 * (anchorNode, anchorOffset) within the textContent of `outerNode`, and
5278 * `end` is the index of (focusNode, focusOffset).
5279 *
5280 * Returns null if you pass in garbage input but we should probably just crash.
5281 *
5282 * Exported only for testing.
5283 */
5284function getModernOffsetsFromPoints(outerNode, anchorNode, anchorOffset, focusNode, focusOffset) {
5285 var length = 0;
5286 var start = -1;
5287 var end = -1;
5288 var indexWithinAnchor = 0;
5289 var indexWithinFocus = 0;
5290 var node = outerNode;
5291 var parentNode = null;
5292
5293 outer: while (true) {
5294 var next = null;
5295
5296 while (true) {
5297 if (node === anchorNode && (anchorOffset === 0 || node.nodeType === TEXT_NODE)) {
5298 start = length + anchorOffset;
5299 }
5300 if (node === focusNode && (focusOffset === 0 || node.nodeType === TEXT_NODE)) {
5301 end = length + focusOffset;
5302 }
5303
5304 if (node.nodeType === TEXT_NODE) {
5305 length += node.nodeValue.length;
5306 }
5307
5308 if ((next = node.firstChild) === null) {
5309 break;
5310 }
5311 // Moving from `node` to its first child `next`.
5312 parentNode = node;
5313 node = next;
5314 }
5315
5316 while (true) {
5317 if (node === outerNode) {
5318 // If `outerNode` has children, this is always the second time visiting
5319 // it. If it has no children, this is still the first loop, and the only
5320 // valid selection is anchorNode and focusNode both equal to this node
5321 // and both offsets 0, in which case we will have handled above.
5322 break outer;
5323 }
5324 if (parentNode === anchorNode && ++indexWithinAnchor === anchorOffset) {
5325 start = length;
5326 }
5327 if (parentNode === focusNode && ++indexWithinFocus === focusOffset) {
5328 end = length;
5329 }
5330 if ((next = node.nextSibling) !== null) {
5331 break;
5332 }
5333 node = parentNode;
5334 parentNode = node.parentNode;
5335 }
5336
5337 // Moving from `node` to its next sibling `next`.
5338 node = next;
5339 }
5340
5341 if (start === -1 || end === -1) {
5342 // This should never happen. (Would happen if the anchor/focus nodes aren't
5343 // actually inside the passed-in node.)
5344 return null;
5345 }
5346
5347 return {
5348 start: start,
5349 end: end
5350 };
5351}
5352
5353/**
5354 * In modern non-IE browsers, we can support both forward and backward
5355 * selections.
5356 *
5357 * Note: IE10+ supports the Selection object, but it does not support
5358 * the `extend` method, which means that even in modern IE, it's not possible
5359 * to programmatically create a backward selection. Thus, for all IE
5360 * versions, we use the old IE API to create our selections.
5361 *
5362 * @param {DOMElement|DOMTextNode} node
5363 * @param {object} offsets
5364 */
5365function setOffsets(node, offsets) {
5366 var doc = node.ownerDocument || document;
5367 var win = doc && doc.defaultView || window;
5368
5369 // Edge fails with "Object expected" in some scenarios.
5370 // (For instance: TinyMCE editor used in a list component that supports pasting to add more,
5371 // fails when pasting 100+ items)
5372 if (!win.getSelection) {
5373 return;
5374 }
5375
5376 var selection = win.getSelection();
5377 var length = node.textContent.length;
5378 var start = Math.min(offsets.start, length);
5379 var end = offsets.end === undefined ? start : Math.min(offsets.end, length);
5380
5381 // IE 11 uses modern selection, but doesn't support the extend method.
5382 // Flip backward selections, so we can set with a single range.
5383 if (!selection.extend && start > end) {
5384 var temp = end;
5385 end = start;
5386 start = temp;
5387 }
5388
5389 var startMarker = getNodeForCharacterOffset(node, start);
5390 var endMarker = getNodeForCharacterOffset(node, end);
5391
5392 if (startMarker && endMarker) {
5393 if (selection.rangeCount === 1 && selection.anchorNode === startMarker.node && selection.anchorOffset === startMarker.offset && selection.focusNode === endMarker.node && selection.focusOffset === endMarker.offset) {
5394 return;
5395 }
5396 var range = doc.createRange();
5397 range.setStart(startMarker.node, startMarker.offset);
5398 selection.removeAllRanges();
5399
5400 if (start > end) {
5401 selection.addRange(range);
5402 selection.extend(endMarker.node, endMarker.offset);
5403 } else {
5404 range.setEnd(endMarker.node, endMarker.offset);
5405 selection.addRange(range);
5406 }
5407 }
5408}
5409
5410function isTextNode(node) {
5411 return node && node.nodeType === TEXT_NODE;
5412}
5413
5414function containsNode(outerNode, innerNode) {
5415 if (!outerNode || !innerNode) {
5416 return false;
5417 } else if (outerNode === innerNode) {
5418 return true;
5419 } else if (isTextNode(outerNode)) {
5420 return false;
5421 } else if (isTextNode(innerNode)) {
5422 return containsNode(outerNode, innerNode.parentNode);
5423 } else if ('contains' in outerNode) {
5424 return outerNode.contains(innerNode);
5425 } else if (outerNode.compareDocumentPosition) {
5426 return !!(outerNode.compareDocumentPosition(innerNode) & 16);
5427 } else {
5428 return false;
5429 }
5430}
5431
5432function isInDocument(node) {
5433 return node && node.ownerDocument && containsNode(node.ownerDocument.documentElement, node);
5434}
5435
5436function getActiveElementDeep() {
5437 var win = window;
5438 var element = getActiveElement();
5439 while (element instanceof win.HTMLIFrameElement) {
5440 // Accessing the contentDocument of a HTMLIframeElement can cause the browser
5441 // to throw, e.g. if it has a cross-origin src attribute
5442 try {
5443 win = element.contentDocument.defaultView;
5444 } catch (e) {
5445 return element;
5446 }
5447 element = getActiveElement(win.document);
5448 }
5449 return element;
5450}
5451
5452/**
5453 * @ReactInputSelection: React input selection module. Based on Selection.js,
5454 * but modified to be suitable for react and has a couple of bug fixes (doesn't
5455 * assume buttons have range selections allowed).
5456 * Input selection module for React.
5457 */
5458
5459/**
5460 * @hasSelectionCapabilities: we get the element types that support selection
5461 * from https://html.spec.whatwg.org/#do-not-apply, looking at `selectionStart`
5462 * and `selectionEnd` rows.
5463 */
5464function hasSelectionCapabilities(elem) {
5465 var nodeName = elem && elem.nodeName && elem.nodeName.toLowerCase();
5466 return nodeName && (nodeName === 'input' && (elem.type === 'text' || elem.type === 'search' || elem.type === 'tel' || elem.type === 'url' || elem.type === 'password') || nodeName === 'textarea' || elem.contentEditable === 'true');
5467}
5468
5469function getSelectionInformation() {
5470 var focusedElem = getActiveElementDeep();
5471 return {
5472 focusedElem: focusedElem,
5473 selectionRange: hasSelectionCapabilities(focusedElem) ? getSelection$1(focusedElem) : null
5474 };
5475}
5476
5477/**
5478 * @restoreSelection: If any selection information was potentially lost,
5479 * restore it. This is useful when performing operations that could remove dom
5480 * nodes and place them back in, resulting in focus being lost.
5481 */
5482function restoreSelection(priorSelectionInformation) {
5483 var curFocusedElem = getActiveElementDeep();
5484 var priorFocusedElem = priorSelectionInformation.focusedElem;
5485 var priorSelectionRange = priorSelectionInformation.selectionRange;
5486 if (curFocusedElem !== priorFocusedElem && isInDocument(priorFocusedElem)) {
5487 if (priorSelectionRange !== null && hasSelectionCapabilities(priorFocusedElem)) {
5488 setSelection(priorFocusedElem, priorSelectionRange);
5489 }
5490
5491 // Focusing a node can change the scroll position, which is undesirable
5492 var ancestors = [];
5493 var ancestor = priorFocusedElem;
5494 while (ancestor = ancestor.parentNode) {
5495 if (ancestor.nodeType === ELEMENT_NODE) {
5496 ancestors.push({
5497 element: ancestor,
5498 left: ancestor.scrollLeft,
5499 top: ancestor.scrollTop
5500 });
5501 }
5502 }
5503
5504 if (typeof priorFocusedElem.focus === 'function') {
5505 priorFocusedElem.focus();
5506 }
5507
5508 for (var i = 0; i < ancestors.length; i++) {
5509 var info = ancestors[i];
5510 info.element.scrollLeft = info.left;
5511 info.element.scrollTop = info.top;
5512 }
5513 }
5514}
5515
5516/**
5517 * @getSelection: Gets the selection bounds of a focused textarea, input or
5518 * contentEditable node.
5519 * -@input: Look up selection bounds of this input
5520 * -@return {start: selectionStart, end: selectionEnd}
5521 */
5522function getSelection$1(input) {
5523 var selection = void 0;
5524
5525 if ('selectionStart' in input) {
5526 // Modern browser with input or textarea.
5527 selection = {
5528 start: input.selectionStart,
5529 end: input.selectionEnd
5530 };
5531 } else {
5532 // Content editable or old IE textarea.
5533 selection = getOffsets(input);
5534 }
5535
5536 return selection || { start: 0, end: 0 };
5537}
5538
5539/**
5540 * @setSelection: Sets the selection bounds of a textarea or input and focuses
5541 * the input.
5542 * -@input Set selection bounds of this input or textarea
5543 * -@offsets Object of same form that is returned from get*
5544 */
5545function setSelection(input, offsets) {
5546 var start = offsets.start,
5547 end = offsets.end;
5548
5549 if (end === undefined) {
5550 end = start;
5551 }
5552
5553 if ('selectionStart' in input) {
5554 input.selectionStart = start;
5555 input.selectionEnd = Math.min(end, input.value.length);
5556 } else {
5557 setOffsets(input, offsets);
5558 }
5559}
5560
5561var skipSelectionChangeEvent = canUseDOM && 'documentMode' in document && document.documentMode <= 11;
5562
5563var eventTypes$3 = {
5564 select: {
5565 phasedRegistrationNames: {
5566 bubbled: 'onSelect',
5567 captured: 'onSelectCapture'
5568 },
5569 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]
5570 }
5571};
5572
5573var activeElement$1 = null;
5574var activeElementInst$1 = null;
5575var lastSelection = null;
5576var mouseDown = false;
5577
5578/**
5579 * Get an object which is a unique representation of the current selection.
5580 *
5581 * The return value will not be consistent across nodes or browsers, but
5582 * two identical selections on the same node will return identical objects.
5583 *
5584 * @param {DOMElement} node
5585 * @return {object}
5586 */
5587function getSelection(node) {
5588 if ('selectionStart' in node && hasSelectionCapabilities(node)) {
5589 return {
5590 start: node.selectionStart,
5591 end: node.selectionEnd
5592 };
5593 } else {
5594 var win = node.ownerDocument && node.ownerDocument.defaultView || window;
5595 var selection = win.getSelection();
5596 return {
5597 anchorNode: selection.anchorNode,
5598 anchorOffset: selection.anchorOffset,
5599 focusNode: selection.focusNode,
5600 focusOffset: selection.focusOffset
5601 };
5602 }
5603}
5604
5605/**
5606 * Get document associated with the event target.
5607 *
5608 * @param {object} nativeEventTarget
5609 * @return {Document}
5610 */
5611function getEventTargetDocument(eventTarget) {
5612 return eventTarget.window === eventTarget ? eventTarget.document : eventTarget.nodeType === DOCUMENT_NODE ? eventTarget : eventTarget.ownerDocument;
5613}
5614
5615/**
5616 * Poll selection to see whether it's changed.
5617 *
5618 * @param {object} nativeEvent
5619 * @param {object} nativeEventTarget
5620 * @return {?SyntheticEvent}
5621 */
5622function constructSelectEvent(nativeEvent, nativeEventTarget) {
5623 // Ensure we have the right element, and that the user is not dragging a
5624 // selection (this matches native `select` event behavior). In HTML5, select
5625 // fires only on input and textarea thus if there's no focused element we
5626 // won't dispatch.
5627 var doc = getEventTargetDocument(nativeEventTarget);
5628
5629 if (mouseDown || activeElement$1 == null || activeElement$1 !== getActiveElement(doc)) {
5630 return null;
5631 }
5632
5633 // Only fire when selection has actually changed.
5634 var currentSelection = getSelection(activeElement$1);
5635 if (!lastSelection || !shallowEqual(lastSelection, currentSelection)) {
5636 lastSelection = currentSelection;
5637
5638 var syntheticEvent = SyntheticEvent.getPooled(eventTypes$3.select, activeElementInst$1, nativeEvent, nativeEventTarget);
5639
5640 syntheticEvent.type = 'select';
5641 syntheticEvent.target = activeElement$1;
5642
5643 accumulateTwoPhaseDispatches(syntheticEvent);
5644
5645 return syntheticEvent;
5646 }
5647
5648 return null;
5649}
5650
5651/**
5652 * This plugin creates an `onSelect` event that normalizes select events
5653 * across form elements.
5654 *
5655 * Supported elements are:
5656 * - input (see `isTextInputElement`)
5657 * - textarea
5658 * - contentEditable
5659 *
5660 * This differs from native browser implementations in the following ways:
5661 * - Fires on contentEditable fields as well as inputs.
5662 * - Fires for collapsed selection.
5663 * - Fires after user input.
5664 */
5665var SelectEventPlugin = {
5666 eventTypes: eventTypes$3,
5667
5668 extractEvents: function (topLevelType, targetInst, nativeEvent, nativeEventTarget) {
5669 var doc = getEventTargetDocument(nativeEventTarget);
5670 // Track whether all listeners exists for this plugin. If none exist, we do
5671 // not extract events. See #3639.
5672 if (!doc || !isListeningToAllDependencies('onSelect', doc)) {
5673 return null;
5674 }
5675
5676 var targetNode = targetInst ? getNodeFromInstance$1(targetInst) : window;
5677
5678 switch (topLevelType) {
5679 // Track the input node that has focus.
5680 case TOP_FOCUS:
5681 if (isTextInputElement(targetNode) || targetNode.contentEditable === 'true') {
5682 activeElement$1 = targetNode;
5683 activeElementInst$1 = targetInst;
5684 lastSelection = null;
5685 }
5686 break;
5687 case TOP_BLUR:
5688 activeElement$1 = null;
5689 activeElementInst$1 = null;
5690 lastSelection = null;
5691 break;
5692 // Don't fire the event while the user is dragging. This matches the
5693 // semantics of the native select event.
5694 case TOP_MOUSE_DOWN:
5695 mouseDown = true;
5696 break;
5697 case TOP_CONTEXT_MENU:
5698 case TOP_MOUSE_UP:
5699 case TOP_DRAG_END:
5700 mouseDown = false;
5701 return constructSelectEvent(nativeEvent, nativeEventTarget);
5702 // Chrome and IE fire non-standard event when selection is changed (and
5703 // sometimes when it hasn't). IE's event fires out of order with respect
5704 // to key and input events on deletion, so we discard it.
5705 //
5706 // Firefox doesn't support selectionchange, so check selection status
5707 // after each key entry. The selection changes after keydown and before
5708 // keyup, but we check on keydown as well in the case of holding down a
5709 // key, when multiple keydown events are fired but only one keyup is.
5710 // This is also our approach for IE handling, for the reason above.
5711 case TOP_SELECTION_CHANGE:
5712 if (skipSelectionChangeEvent) {
5713 break;
5714 }
5715 // falls through
5716 case TOP_KEY_DOWN:
5717 case TOP_KEY_UP:
5718 return constructSelectEvent(nativeEvent, nativeEventTarget);
5719 }
5720
5721 return null;
5722 }
5723};
5724
5725/**
5726 * Inject modules for resolving DOM hierarchy and plugin ordering.
5727 */
5728injection.injectEventPluginOrder(DOMEventPluginOrder);
5729setComponentTree(getFiberCurrentPropsFromNode$1, getInstanceFromNode$1, getNodeFromInstance$1);
5730
5731/**
5732 * Some important event plugins included by default (without having to require
5733 * them).
5734 */
5735injection.injectEventPluginsByName({
5736 SimpleEventPlugin: SimpleEventPlugin,
5737 EnterLeaveEventPlugin: EnterLeaveEventPlugin,
5738 ChangeEventPlugin: ChangeEventPlugin,
5739 SelectEventPlugin: SelectEventPlugin,
5740 BeforeInputEventPlugin: BeforeInputEventPlugin
5741});
5742
5743var didWarnSelectedSetOnOption = false;
5744var didWarnInvalidChild = false;
5745
5746function flattenChildren(children) {
5747 var content = '';
5748
5749 // Flatten children. We'll warn if they are invalid
5750 // during validateProps() which runs for hydration too.
5751 // Note that this would throw on non-element objects.
5752 // Elements are stringified (which is normally irrelevant
5753 // but matters for <fbt>).
5754 React.Children.forEach(children, function (child) {
5755 if (child == null) {
5756 return;
5757 }
5758 content += child;
5759 // Note: we don't warn about invalid children here.
5760 // Instead, this is done separately below so that
5761 // it happens during the hydration codepath too.
5762 });
5763
5764 return content;
5765}
5766
5767/**
5768 * Implements an <option> host component that warns when `selected` is set.
5769 */
5770
5771function validateProps(element, props) {
5772 {
5773 // This mirrors the codepath above, but runs for hydration too.
5774 // Warn about invalid children here so that client and hydration are consistent.
5775 // TODO: this seems like it could cause a DEV-only throw for hydration
5776 // if children contains a non-element object. We should try to avoid that.
5777 if (typeof props.children === 'object' && props.children !== null) {
5778 React.Children.forEach(props.children, function (child) {
5779 if (child == null) {
5780 return;
5781 }
5782 if (typeof child === 'string' || typeof child === 'number') {
5783 return;
5784 }
5785 if (typeof child.type !== 'string') {
5786 return;
5787 }
5788 if (!didWarnInvalidChild) {
5789 didWarnInvalidChild = true;
5790 warning$1(false, 'Only strings and numbers are supported as <option> children.');
5791 }
5792 });
5793 }
5794
5795 // TODO: Remove support for `selected` in <option>.
5796 if (props.selected != null && !didWarnSelectedSetOnOption) {
5797 warning$1(false, 'Use the `defaultValue` or `value` props on <select> instead of ' + 'setting `selected` on <option>.');
5798 didWarnSelectedSetOnOption = true;
5799 }
5800 }
5801}
5802
5803function postMountWrapper$1(element, props) {
5804 // value="" should make a value attribute (#6219)
5805 if (props.value != null) {
5806 element.setAttribute('value', toString(getToStringValue(props.value)));
5807 }
5808}
5809
5810function getHostProps$1(element, props) {
5811 var hostProps = _assign({ children: undefined }, props);
5812 var content = flattenChildren(props.children);
5813
5814 if (content) {
5815 hostProps.children = content;
5816 }
5817
5818 return hostProps;
5819}
5820
5821// TODO: direct imports like some-package/src/* are bad. Fix me.
5822var didWarnValueDefaultValue$1 = void 0;
5823
5824{
5825 didWarnValueDefaultValue$1 = false;
5826}
5827
5828function getDeclarationErrorAddendum() {
5829 var ownerName = getCurrentFiberOwnerNameInDevOrNull();
5830 if (ownerName) {
5831 return '\n\nCheck the render method of `' + ownerName + '`.';
5832 }
5833 return '';
5834}
5835
5836var valuePropNames = ['value', 'defaultValue'];
5837
5838/**
5839 * Validation function for `value` and `defaultValue`.
5840 */
5841function checkSelectPropTypes(props) {
5842 ReactControlledValuePropTypes.checkPropTypes('select', props);
5843
5844 for (var i = 0; i < valuePropNames.length; i++) {
5845 var propName = valuePropNames[i];
5846 if (props[propName] == null) {
5847 continue;
5848 }
5849 var isArray = Array.isArray(props[propName]);
5850 if (props.multiple && !isArray) {
5851 warning$1(false, 'The `%s` prop supplied to <select> must be an array if ' + '`multiple` is true.%s', propName, getDeclarationErrorAddendum());
5852 } else if (!props.multiple && isArray) {
5853 warning$1(false, 'The `%s` prop supplied to <select> must be a scalar ' + 'value if `multiple` is false.%s', propName, getDeclarationErrorAddendum());
5854 }
5855 }
5856}
5857
5858function updateOptions(node, multiple, propValue, setDefaultSelected) {
5859 var options = node.options;
5860
5861 if (multiple) {
5862 var selectedValues = propValue;
5863 var selectedValue = {};
5864 for (var i = 0; i < selectedValues.length; i++) {
5865 // Prefix to avoid chaos with special keys.
5866 selectedValue['$' + selectedValues[i]] = true;
5867 }
5868 for (var _i = 0; _i < options.length; _i++) {
5869 var selected = selectedValue.hasOwnProperty('$' + options[_i].value);
5870 if (options[_i].selected !== selected) {
5871 options[_i].selected = selected;
5872 }
5873 if (selected && setDefaultSelected) {
5874 options[_i].defaultSelected = true;
5875 }
5876 }
5877 } else {
5878 // Do not set `select.value` as exact behavior isn't consistent across all
5879 // browsers for all cases.
5880 var _selectedValue = toString(getToStringValue(propValue));
5881 var defaultSelected = null;
5882 for (var _i2 = 0; _i2 < options.length; _i2++) {
5883 if (options[_i2].value === _selectedValue) {
5884 options[_i2].selected = true;
5885 if (setDefaultSelected) {
5886 options[_i2].defaultSelected = true;
5887 }
5888 return;
5889 }
5890 if (defaultSelected === null && !options[_i2].disabled) {
5891 defaultSelected = options[_i2];
5892 }
5893 }
5894 if (defaultSelected !== null) {
5895 defaultSelected.selected = true;
5896 }
5897 }
5898}
5899
5900/**
5901 * Implements a <select> host component that allows optionally setting the
5902 * props `value` and `defaultValue`. If `multiple` is false, the prop must be a
5903 * stringable. If `multiple` is true, the prop must be an array of stringables.
5904 *
5905 * If `value` is not supplied (or null/undefined), user actions that change the
5906 * selected option will trigger updates to the rendered options.
5907 *
5908 * If it is supplied (and not null/undefined), the rendered options will not
5909 * update in response to user actions. Instead, the `value` prop must change in
5910 * order for the rendered options to update.
5911 *
5912 * If `defaultValue` is provided, any options with the supplied values will be
5913 * selected.
5914 */
5915
5916function getHostProps$2(element, props) {
5917 return _assign({}, props, {
5918 value: undefined
5919 });
5920}
5921
5922function initWrapperState$1(element, props) {
5923 var node = element;
5924 {
5925 checkSelectPropTypes(props);
5926 }
5927
5928 node._wrapperState = {
5929 wasMultiple: !!props.multiple
5930 };
5931
5932 {
5933 if (props.value !== undefined && props.defaultValue !== undefined && !didWarnValueDefaultValue$1) {
5934 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');
5935 didWarnValueDefaultValue$1 = true;
5936 }
5937 }
5938}
5939
5940function postMountWrapper$2(element, props) {
5941 var node = element;
5942 node.multiple = !!props.multiple;
5943 var value = props.value;
5944 if (value != null) {
5945 updateOptions(node, !!props.multiple, value, false);
5946 } else if (props.defaultValue != null) {
5947 updateOptions(node, !!props.multiple, props.defaultValue, true);
5948 }
5949}
5950
5951function postUpdateWrapper(element, props) {
5952 var node = element;
5953 var wasMultiple = node._wrapperState.wasMultiple;
5954 node._wrapperState.wasMultiple = !!props.multiple;
5955
5956 var value = props.value;
5957 if (value != null) {
5958 updateOptions(node, !!props.multiple, value, false);
5959 } else if (wasMultiple !== !!props.multiple) {
5960 // For simplicity, reapply `defaultValue` if `multiple` is toggled.
5961 if (props.defaultValue != null) {
5962 updateOptions(node, !!props.multiple, props.defaultValue, true);
5963 } else {
5964 // Revert the select back to its default unselected state.
5965 updateOptions(node, !!props.multiple, props.multiple ? [] : '', false);
5966 }
5967 }
5968}
5969
5970function restoreControlledState$2(element, props) {
5971 var node = element;
5972 var value = props.value;
5973
5974 if (value != null) {
5975 updateOptions(node, !!props.multiple, value, false);
5976 }
5977}
5978
5979var didWarnValDefaultVal = false;
5980
5981/**
5982 * Implements a <textarea> host component that allows setting `value`, and
5983 * `defaultValue`. This differs from the traditional DOM API because value is
5984 * usually set as PCDATA children.
5985 *
5986 * If `value` is not supplied (or null/undefined), user actions that affect the
5987 * value will trigger updates to the element.
5988 *
5989 * If `value` is supplied (and not null/undefined), the rendered element will
5990 * not trigger updates to the element. Instead, the `value` prop must change in
5991 * order for the rendered element to be updated.
5992 *
5993 * The rendered element will be initialized with an empty value, the prop
5994 * `defaultValue` if specified, or the children content (deprecated).
5995 */
5996
5997function getHostProps$3(element, props) {
5998 var node = element;
5999 !(props.dangerouslySetInnerHTML == null) ? invariant(false, '`dangerouslySetInnerHTML` does not make sense on <textarea>.') : void 0;
6000
6001 // Always set children to the same thing. In IE9, the selection range will
6002 // get reset if `textContent` is mutated. We could add a check in setTextContent
6003 // to only set the value if/when the value differs from the node value (which would
6004 // completely solve this IE9 bug), but Sebastian+Sophie seemed to like this
6005 // solution. The value can be a boolean or object so that's why it's forced
6006 // to be a string.
6007 var hostProps = _assign({}, props, {
6008 value: undefined,
6009 defaultValue: undefined,
6010 children: toString(node._wrapperState.initialValue)
6011 });
6012
6013 return hostProps;
6014}
6015
6016function initWrapperState$2(element, props) {
6017 var node = element;
6018 {
6019 ReactControlledValuePropTypes.checkPropTypes('textarea', props);
6020 if (props.value !== undefined && props.defaultValue !== undefined && !didWarnValDefaultVal) {
6021 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');
6022 didWarnValDefaultVal = true;
6023 }
6024 }
6025
6026 var initialValue = props.value;
6027
6028 // Only bother fetching default value if we're going to use it
6029 if (initialValue == null) {
6030 var defaultValue = props.defaultValue;
6031 // TODO (yungsters): Remove support for children content in <textarea>.
6032 var children = props.children;
6033 if (children != null) {
6034 {
6035 warning$1(false, 'Use the `defaultValue` or `value` props instead of setting ' + 'children on <textarea>.');
6036 }
6037 !(defaultValue == null) ? invariant(false, 'If you supply `defaultValue` on a <textarea>, do not pass children.') : void 0;
6038 if (Array.isArray(children)) {
6039 !(children.length <= 1) ? invariant(false, '<textarea> can only have at most one child.') : void 0;
6040 children = children[0];
6041 }
6042
6043 defaultValue = children;
6044 }
6045 if (defaultValue == null) {
6046 defaultValue = '';
6047 }
6048 initialValue = defaultValue;
6049 }
6050
6051 node._wrapperState = {
6052 initialValue: getToStringValue(initialValue)
6053 };
6054}
6055
6056function updateWrapper$1(element, props) {
6057 var node = element;
6058 var value = getToStringValue(props.value);
6059 var defaultValue = getToStringValue(props.defaultValue);
6060 if (value != null) {
6061 // Cast `value` to a string to ensure the value is set correctly. While
6062 // browsers typically do this as necessary, jsdom doesn't.
6063 var newValue = toString(value);
6064 // To avoid side effects (such as losing text selection), only set value if changed
6065 if (newValue !== node.value) {
6066 node.value = newValue;
6067 }
6068 if (props.defaultValue == null && node.defaultValue !== newValue) {
6069 node.defaultValue = newValue;
6070 }
6071 }
6072 if (defaultValue != null) {
6073 node.defaultValue = toString(defaultValue);
6074 }
6075}
6076
6077function postMountWrapper$3(element, props) {
6078 var node = element;
6079 // This is in postMount because we need access to the DOM node, which is not
6080 // available until after the component has mounted.
6081 var textContent = node.textContent;
6082
6083 // Only set node.value if textContent is equal to the expected
6084 // initial value. In IE10/IE11 there is a bug where the placeholder attribute
6085 // will populate textContent as well.
6086 // https://developer.microsoft.com/microsoft-edge/platform/issues/101525/
6087 if (textContent === node._wrapperState.initialValue) {
6088 node.value = textContent;
6089 }
6090}
6091
6092function restoreControlledState$3(element, props) {
6093 // DOM component is still mounted; update
6094 updateWrapper$1(element, props);
6095}
6096
6097var HTML_NAMESPACE$1 = 'http://www.w3.org/1999/xhtml';
6098var MATH_NAMESPACE = 'http://www.w3.org/1998/Math/MathML';
6099var SVG_NAMESPACE = 'http://www.w3.org/2000/svg';
6100
6101var Namespaces = {
6102 html: HTML_NAMESPACE$1,
6103 mathml: MATH_NAMESPACE,
6104 svg: SVG_NAMESPACE
6105};
6106
6107// Assumes there is no parent namespace.
6108function getIntrinsicNamespace(type) {
6109 switch (type) {
6110 case 'svg':
6111 return SVG_NAMESPACE;
6112 case 'math':
6113 return MATH_NAMESPACE;
6114 default:
6115 return HTML_NAMESPACE$1;
6116 }
6117}
6118
6119function getChildNamespace(parentNamespace, type) {
6120 if (parentNamespace == null || parentNamespace === HTML_NAMESPACE$1) {
6121 // No (or default) parent namespace: potential entry point.
6122 return getIntrinsicNamespace(type);
6123 }
6124 if (parentNamespace === SVG_NAMESPACE && type === 'foreignObject') {
6125 // We're leaving SVG.
6126 return HTML_NAMESPACE$1;
6127 }
6128 // By default, pass namespace below.
6129 return parentNamespace;
6130}
6131
6132/* globals MSApp */
6133
6134/**
6135 * Create a function which has 'unsafe' privileges (required by windows8 apps)
6136 */
6137var createMicrosoftUnsafeLocalFunction = function (func) {
6138 if (typeof MSApp !== 'undefined' && MSApp.execUnsafeLocalFunction) {
6139 return function (arg0, arg1, arg2, arg3) {
6140 MSApp.execUnsafeLocalFunction(function () {
6141 return func(arg0, arg1, arg2, arg3);
6142 });
6143 };
6144 } else {
6145 return func;
6146 }
6147};
6148
6149// SVG temp container for IE lacking innerHTML
6150var reusableSVGContainer = void 0;
6151
6152/**
6153 * Set the innerHTML property of a node
6154 *
6155 * @param {DOMElement} node
6156 * @param {string} html
6157 * @internal
6158 */
6159var setInnerHTML = createMicrosoftUnsafeLocalFunction(function (node, html) {
6160 // IE does not have innerHTML for SVG nodes, so instead we inject the
6161 // new markup in a temp node and then move the child nodes across into
6162 // the target node
6163
6164 if (node.namespaceURI === Namespaces.svg && !('innerHTML' in node)) {
6165 reusableSVGContainer = reusableSVGContainer || document.createElement('div');
6166 reusableSVGContainer.innerHTML = '<svg>' + html + '</svg>';
6167 var svgNode = reusableSVGContainer.firstChild;
6168 while (node.firstChild) {
6169 node.removeChild(node.firstChild);
6170 }
6171 while (svgNode.firstChild) {
6172 node.appendChild(svgNode.firstChild);
6173 }
6174 } else {
6175 node.innerHTML = html;
6176 }
6177});
6178
6179/**
6180 * Set the textContent property of a node. For text updates, it's faster
6181 * to set the `nodeValue` of the Text node directly instead of using
6182 * `.textContent` which will remove the existing node and create a new one.
6183 *
6184 * @param {DOMElement} node
6185 * @param {string} text
6186 * @internal
6187 */
6188var setTextContent = function (node, text) {
6189 if (text) {
6190 var firstChild = node.firstChild;
6191
6192 if (firstChild && firstChild === node.lastChild && firstChild.nodeType === TEXT_NODE) {
6193 firstChild.nodeValue = text;
6194 return;
6195 }
6196 }
6197 node.textContent = text;
6198};
6199
6200// List derived from Gecko source code:
6201// https://github.com/mozilla/gecko-dev/blob/4e638efc71/layout/style/test/property_database.js
6202var shorthandToLonghand = {
6203 animation: ['animationDelay', 'animationDirection', 'animationDuration', 'animationFillMode', 'animationIterationCount', 'animationName', 'animationPlayState', 'animationTimingFunction'],
6204 background: ['backgroundAttachment', 'backgroundClip', 'backgroundColor', 'backgroundImage', 'backgroundOrigin', 'backgroundPositionX', 'backgroundPositionY', 'backgroundRepeat', 'backgroundSize'],
6205 backgroundPosition: ['backgroundPositionX', 'backgroundPositionY'],
6206 border: ['borderBottomColor', 'borderBottomStyle', 'borderBottomWidth', 'borderImageOutset', 'borderImageRepeat', 'borderImageSlice', 'borderImageSource', 'borderImageWidth', 'borderLeftColor', 'borderLeftStyle', 'borderLeftWidth', 'borderRightColor', 'borderRightStyle', 'borderRightWidth', 'borderTopColor', 'borderTopStyle', 'borderTopWidth'],
6207 borderBlockEnd: ['borderBlockEndColor', 'borderBlockEndStyle', 'borderBlockEndWidth'],
6208 borderBlockStart: ['borderBlockStartColor', 'borderBlockStartStyle', 'borderBlockStartWidth'],
6209 borderBottom: ['borderBottomColor', 'borderBottomStyle', 'borderBottomWidth'],
6210 borderColor: ['borderBottomColor', 'borderLeftColor', 'borderRightColor', 'borderTopColor'],
6211 borderImage: ['borderImageOutset', 'borderImageRepeat', 'borderImageSlice', 'borderImageSource', 'borderImageWidth'],
6212 borderInlineEnd: ['borderInlineEndColor', 'borderInlineEndStyle', 'borderInlineEndWidth'],
6213 borderInlineStart: ['borderInlineStartColor', 'borderInlineStartStyle', 'borderInlineStartWidth'],
6214 borderLeft: ['borderLeftColor', 'borderLeftStyle', 'borderLeftWidth'],
6215 borderRadius: ['borderBottomLeftRadius', 'borderBottomRightRadius', 'borderTopLeftRadius', 'borderTopRightRadius'],
6216 borderRight: ['borderRightColor', 'borderRightStyle', 'borderRightWidth'],
6217 borderStyle: ['borderBottomStyle', 'borderLeftStyle', 'borderRightStyle', 'borderTopStyle'],
6218 borderTop: ['borderTopColor', 'borderTopStyle', 'borderTopWidth'],
6219 borderWidth: ['borderBottomWidth', 'borderLeftWidth', 'borderRightWidth', 'borderTopWidth'],
6220 columnRule: ['columnRuleColor', 'columnRuleStyle', 'columnRuleWidth'],
6221 columns: ['columnCount', 'columnWidth'],
6222 flex: ['flexBasis', 'flexGrow', 'flexShrink'],
6223 flexFlow: ['flexDirection', 'flexWrap'],
6224 font: ['fontFamily', 'fontFeatureSettings', 'fontKerning', 'fontLanguageOverride', 'fontSize', 'fontSizeAdjust', 'fontStretch', 'fontStyle', 'fontVariant', 'fontVariantAlternates', 'fontVariantCaps', 'fontVariantEastAsian', 'fontVariantLigatures', 'fontVariantNumeric', 'fontVariantPosition', 'fontWeight', 'lineHeight'],
6225 fontVariant: ['fontVariantAlternates', 'fontVariantCaps', 'fontVariantEastAsian', 'fontVariantLigatures', 'fontVariantNumeric', 'fontVariantPosition'],
6226 gap: ['columnGap', 'rowGap'],
6227 grid: ['gridAutoColumns', 'gridAutoFlow', 'gridAutoRows', 'gridTemplateAreas', 'gridTemplateColumns', 'gridTemplateRows'],
6228 gridArea: ['gridColumnEnd', 'gridColumnStart', 'gridRowEnd', 'gridRowStart'],
6229 gridColumn: ['gridColumnEnd', 'gridColumnStart'],
6230 gridColumnGap: ['columnGap'],
6231 gridGap: ['columnGap', 'rowGap'],
6232 gridRow: ['gridRowEnd', 'gridRowStart'],
6233 gridRowGap: ['rowGap'],
6234 gridTemplate: ['gridTemplateAreas', 'gridTemplateColumns', 'gridTemplateRows'],
6235 listStyle: ['listStyleImage', 'listStylePosition', 'listStyleType'],
6236 margin: ['marginBottom', 'marginLeft', 'marginRight', 'marginTop'],
6237 marker: ['markerEnd', 'markerMid', 'markerStart'],
6238 mask: ['maskClip', 'maskComposite', 'maskImage', 'maskMode', 'maskOrigin', 'maskPositionX', 'maskPositionY', 'maskRepeat', 'maskSize'],
6239 maskPosition: ['maskPositionX', 'maskPositionY'],
6240 outline: ['outlineColor', 'outlineStyle', 'outlineWidth'],
6241 overflow: ['overflowX', 'overflowY'],
6242 padding: ['paddingBottom', 'paddingLeft', 'paddingRight', 'paddingTop'],
6243 placeContent: ['alignContent', 'justifyContent'],
6244 placeItems: ['alignItems', 'justifyItems'],
6245 placeSelf: ['alignSelf', 'justifySelf'],
6246 textDecoration: ['textDecorationColor', 'textDecorationLine', 'textDecorationStyle'],
6247 textEmphasis: ['textEmphasisColor', 'textEmphasisStyle'],
6248 transition: ['transitionDelay', 'transitionDuration', 'transitionProperty', 'transitionTimingFunction'],
6249 wordWrap: ['overflowWrap']
6250};
6251
6252/**
6253 * CSS properties which accept numbers but are not in units of "px".
6254 */
6255var isUnitlessNumber = {
6256 animationIterationCount: true,
6257 borderImageOutset: true,
6258 borderImageSlice: true,
6259 borderImageWidth: true,
6260 boxFlex: true,
6261 boxFlexGroup: true,
6262 boxOrdinalGroup: true,
6263 columnCount: true,
6264 columns: true,
6265 flex: true,
6266 flexGrow: true,
6267 flexPositive: true,
6268 flexShrink: true,
6269 flexNegative: true,
6270 flexOrder: true,
6271 gridArea: true,
6272 gridRow: true,
6273 gridRowEnd: true,
6274 gridRowSpan: true,
6275 gridRowStart: true,
6276 gridColumn: true,
6277 gridColumnEnd: true,
6278 gridColumnSpan: true,
6279 gridColumnStart: true,
6280 fontWeight: true,
6281 lineClamp: true,
6282 lineHeight: true,
6283 opacity: true,
6284 order: true,
6285 orphans: true,
6286 tabSize: true,
6287 widows: true,
6288 zIndex: true,
6289 zoom: true,
6290
6291 // SVG-related properties
6292 fillOpacity: true,
6293 floodOpacity: true,
6294 stopOpacity: true,
6295 strokeDasharray: true,
6296 strokeDashoffset: true,
6297 strokeMiterlimit: true,
6298 strokeOpacity: true,
6299 strokeWidth: true
6300};
6301
6302/**
6303 * @param {string} prefix vendor-specific prefix, eg: Webkit
6304 * @param {string} key style name, eg: transitionDuration
6305 * @return {string} style name prefixed with `prefix`, properly camelCased, eg:
6306 * WebkitTransitionDuration
6307 */
6308function prefixKey(prefix, key) {
6309 return prefix + key.charAt(0).toUpperCase() + key.substring(1);
6310}
6311
6312/**
6313 * Support style names that may come passed in prefixed by adding permutations
6314 * of vendor prefixes.
6315 */
6316var prefixes = ['Webkit', 'ms', 'Moz', 'O'];
6317
6318// Using Object.keys here, or else the vanilla for-in loop makes IE8 go into an
6319// infinite loop, because it iterates over the newly added props too.
6320Object.keys(isUnitlessNumber).forEach(function (prop) {
6321 prefixes.forEach(function (prefix) {
6322 isUnitlessNumber[prefixKey(prefix, prop)] = isUnitlessNumber[prop];
6323 });
6324});
6325
6326/**
6327 * Convert a value into the proper css writable value. The style name `name`
6328 * should be logical (no hyphens), as specified
6329 * in `CSSProperty.isUnitlessNumber`.
6330 *
6331 * @param {string} name CSS property name such as `topMargin`.
6332 * @param {*} value CSS property value such as `10px`.
6333 * @return {string} Normalized style value with dimensions applied.
6334 */
6335function dangerousStyleValue(name, value, isCustomProperty) {
6336 // Note that we've removed escapeTextForBrowser() calls here since the
6337 // whole string will be escaped when the attribute is injected into
6338 // the markup. If you provide unsafe user data here they can inject
6339 // arbitrary CSS which may be problematic (I couldn't repro this):
6340 // https://www.owasp.org/index.php/XSS_Filter_Evasion_Cheat_Sheet
6341 // http://www.thespanner.co.uk/2007/11/26/ultimate-xss-css-injection/
6342 // This is not an XSS hole but instead a potential CSS injection issue
6343 // which has lead to a greater discussion about how we're going to
6344 // trust URLs moving forward. See #2115901
6345
6346 var isEmpty = value == null || typeof value === 'boolean' || value === '';
6347 if (isEmpty) {
6348 return '';
6349 }
6350
6351 if (!isCustomProperty && typeof value === 'number' && value !== 0 && !(isUnitlessNumber.hasOwnProperty(name) && isUnitlessNumber[name])) {
6352 return value + 'px'; // Presumes implicit 'px' suffix for unitless numbers
6353 }
6354
6355 return ('' + value).trim();
6356}
6357
6358var uppercasePattern = /([A-Z])/g;
6359var msPattern = /^ms-/;
6360
6361/**
6362 * Hyphenates a camelcased CSS property name, for example:
6363 *
6364 * > hyphenateStyleName('backgroundColor')
6365 * < "background-color"
6366 * > hyphenateStyleName('MozTransition')
6367 * < "-moz-transition"
6368 * > hyphenateStyleName('msTransition')
6369 * < "-ms-transition"
6370 *
6371 * As Modernizr suggests (http://modernizr.com/docs/#prefixed), an `ms` prefix
6372 * is converted to `-ms-`.
6373 */
6374function hyphenateStyleName(name) {
6375 return name.replace(uppercasePattern, '-$1').toLowerCase().replace(msPattern, '-ms-');
6376}
6377
6378var warnValidStyle = function () {};
6379
6380{
6381 // 'msTransform' is correct, but the other prefixes should be capitalized
6382 var badVendoredStyleNamePattern = /^(?:webkit|moz|o)[A-Z]/;
6383 var msPattern$1 = /^-ms-/;
6384 var hyphenPattern = /-(.)/g;
6385
6386 // style values shouldn't contain a semicolon
6387 var badStyleValueWithSemicolonPattern = /;\s*$/;
6388
6389 var warnedStyleNames = {};
6390 var warnedStyleValues = {};
6391 var warnedForNaNValue = false;
6392 var warnedForInfinityValue = false;
6393
6394 var camelize = function (string) {
6395 return string.replace(hyphenPattern, function (_, character) {
6396 return character.toUpperCase();
6397 });
6398 };
6399
6400 var warnHyphenatedStyleName = function (name) {
6401 if (warnedStyleNames.hasOwnProperty(name) && warnedStyleNames[name]) {
6402 return;
6403 }
6404
6405 warnedStyleNames[name] = true;
6406 warning$1(false, 'Unsupported style property %s. Did you mean %s?', name,
6407 // As Andi Smith suggests
6408 // (http://www.andismith.com/blog/2012/02/modernizr-prefixed/), an `-ms` prefix
6409 // is converted to lowercase `ms`.
6410 camelize(name.replace(msPattern$1, 'ms-')));
6411 };
6412
6413 var warnBadVendoredStyleName = function (name) {
6414 if (warnedStyleNames.hasOwnProperty(name) && warnedStyleNames[name]) {
6415 return;
6416 }
6417
6418 warnedStyleNames[name] = true;
6419 warning$1(false, 'Unsupported vendor-prefixed style property %s. Did you mean %s?', name, name.charAt(0).toUpperCase() + name.slice(1));
6420 };
6421
6422 var warnStyleValueWithSemicolon = function (name, value) {
6423 if (warnedStyleValues.hasOwnProperty(value) && warnedStyleValues[value]) {
6424 return;
6425 }
6426
6427 warnedStyleValues[value] = true;
6428 warning$1(false, "Style property values shouldn't contain a semicolon. " + 'Try "%s: %s" instead.', name, value.replace(badStyleValueWithSemicolonPattern, ''));
6429 };
6430
6431 var warnStyleValueIsNaN = function (name, value) {
6432 if (warnedForNaNValue) {
6433 return;
6434 }
6435
6436 warnedForNaNValue = true;
6437 warning$1(false, '`NaN` is an invalid value for the `%s` css style property.', name);
6438 };
6439
6440 var warnStyleValueIsInfinity = function (name, value) {
6441 if (warnedForInfinityValue) {
6442 return;
6443 }
6444
6445 warnedForInfinityValue = true;
6446 warning$1(false, '`Infinity` is an invalid value for the `%s` css style property.', name);
6447 };
6448
6449 warnValidStyle = function (name, value) {
6450 if (name.indexOf('-') > -1) {
6451 warnHyphenatedStyleName(name);
6452 } else if (badVendoredStyleNamePattern.test(name)) {
6453 warnBadVendoredStyleName(name);
6454 } else if (badStyleValueWithSemicolonPattern.test(value)) {
6455 warnStyleValueWithSemicolon(name, value);
6456 }
6457
6458 if (typeof value === 'number') {
6459 if (isNaN(value)) {
6460 warnStyleValueIsNaN(name, value);
6461 } else if (!isFinite(value)) {
6462 warnStyleValueIsInfinity(name, value);
6463 }
6464 }
6465 };
6466}
6467
6468var warnValidStyle$1 = warnValidStyle;
6469
6470/**
6471 * Operations for dealing with CSS properties.
6472 */
6473
6474/**
6475 * This creates a string that is expected to be equivalent to the style
6476 * attribute generated by server-side rendering. It by-passes warnings and
6477 * security checks so it's not safe to use this value for anything other than
6478 * comparison. It is only used in DEV for SSR validation.
6479 */
6480function createDangerousStringForStyles(styles) {
6481 {
6482 var serialized = '';
6483 var delimiter = '';
6484 for (var styleName in styles) {
6485 if (!styles.hasOwnProperty(styleName)) {
6486 continue;
6487 }
6488 var styleValue = styles[styleName];
6489 if (styleValue != null) {
6490 var isCustomProperty = styleName.indexOf('--') === 0;
6491 serialized += delimiter + hyphenateStyleName(styleName) + ':';
6492 serialized += dangerousStyleValue(styleName, styleValue, isCustomProperty);
6493
6494 delimiter = ';';
6495 }
6496 }
6497 return serialized || null;
6498 }
6499}
6500
6501/**
6502 * Sets the value for multiple styles on a node. If a value is specified as
6503 * '' (empty string), the corresponding style property will be unset.
6504 *
6505 * @param {DOMElement} node
6506 * @param {object} styles
6507 */
6508function setValueForStyles(node, styles) {
6509 var style = node.style;
6510 for (var styleName in styles) {
6511 if (!styles.hasOwnProperty(styleName)) {
6512 continue;
6513 }
6514 var isCustomProperty = styleName.indexOf('--') === 0;
6515 {
6516 if (!isCustomProperty) {
6517 warnValidStyle$1(styleName, styles[styleName]);
6518 }
6519 }
6520 var styleValue = dangerousStyleValue(styleName, styles[styleName], isCustomProperty);
6521 if (styleName === 'float') {
6522 styleName = 'cssFloat';
6523 }
6524 if (isCustomProperty) {
6525 style.setProperty(styleName, styleValue);
6526 } else {
6527 style[styleName] = styleValue;
6528 }
6529 }
6530}
6531
6532function isValueEmpty(value) {
6533 return value == null || typeof value === 'boolean' || value === '';
6534}
6535
6536/**
6537 * Given {color: 'red', overflow: 'hidden'} returns {
6538 * color: 'color',
6539 * overflowX: 'overflow',
6540 * overflowY: 'overflow',
6541 * }. This can be read as "the overflowY property was set by the overflow
6542 * shorthand". That is, the values are the property that each was derived from.
6543 */
6544function expandShorthandMap(styles) {
6545 var expanded = {};
6546 for (var key in styles) {
6547 var longhands = shorthandToLonghand[key] || [key];
6548 for (var i = 0; i < longhands.length; i++) {
6549 expanded[longhands[i]] = key;
6550 }
6551 }
6552 return expanded;
6553}
6554
6555/**
6556 * When mixing shorthand and longhand property names, we warn during updates if
6557 * we expect an incorrect result to occur. In particular, we warn for:
6558 *
6559 * Updating a shorthand property (longhand gets overwritten):
6560 * {font: 'foo', fontVariant: 'bar'} -> {font: 'baz', fontVariant: 'bar'}
6561 * becomes .style.font = 'baz'
6562 * Removing a shorthand property (longhand gets lost too):
6563 * {font: 'foo', fontVariant: 'bar'} -> {fontVariant: 'bar'}
6564 * becomes .style.font = ''
6565 * Removing a longhand property (should revert to shorthand; doesn't):
6566 * {font: 'foo', fontVariant: 'bar'} -> {font: 'foo'}
6567 * becomes .style.fontVariant = ''
6568 */
6569function validateShorthandPropertyCollisionInDev(styleUpdates, nextStyles) {
6570 if (!warnAboutShorthandPropertyCollision) {
6571 return;
6572 }
6573
6574 if (!nextStyles) {
6575 return;
6576 }
6577
6578 var expandedUpdates = expandShorthandMap(styleUpdates);
6579 var expandedStyles = expandShorthandMap(nextStyles);
6580 var warnedAbout = {};
6581 for (var key in expandedUpdates) {
6582 var originalKey = expandedUpdates[key];
6583 var correctOriginalKey = expandedStyles[key];
6584 if (correctOriginalKey && originalKey !== correctOriginalKey) {
6585 var warningKey = originalKey + ',' + correctOriginalKey;
6586 if (warnedAbout[warningKey]) {
6587 continue;
6588 }
6589 warnedAbout[warningKey] = true;
6590 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);
6591 }
6592 }
6593}
6594
6595// For HTML, certain tags should omit their close tag. We keep a whitelist for
6596// those special-case tags.
6597
6598var omittedCloseTags = {
6599 area: true,
6600 base: true,
6601 br: true,
6602 col: true,
6603 embed: true,
6604 hr: true,
6605 img: true,
6606 input: true,
6607 keygen: true,
6608 link: true,
6609 meta: true,
6610 param: true,
6611 source: true,
6612 track: true,
6613 wbr: true
6614 // NOTE: menuitem's close tag should be omitted, but that causes problems.
6615};
6616
6617// For HTML, certain tags cannot have children. This has the same purpose as
6618// `omittedCloseTags` except that `menuitem` should still have its closing tag.
6619
6620var voidElementTags = _assign({
6621 menuitem: true
6622}, omittedCloseTags);
6623
6624// TODO: We can remove this if we add invariantWithStack()
6625// or add stack by default to invariants where possible.
6626var HTML$1 = '__html';
6627
6628var ReactDebugCurrentFrame$2 = null;
6629{
6630 ReactDebugCurrentFrame$2 = ReactSharedInternals.ReactDebugCurrentFrame;
6631}
6632
6633function assertValidProps(tag, props) {
6634 if (!props) {
6635 return;
6636 }
6637 // Note the use of `==` which checks for null or undefined.
6638 if (voidElementTags[tag]) {
6639 !(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;
6640 }
6641 if (props.dangerouslySetInnerHTML != null) {
6642 !(props.children == null) ? invariant(false, 'Can only set one of `children` or `props.dangerouslySetInnerHTML`.') : void 0;
6643 !(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;
6644 }
6645 {
6646 !(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;
6647 }
6648 !(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;
6649}
6650
6651function isCustomComponent(tagName, props) {
6652 if (tagName.indexOf('-') === -1) {
6653 return typeof props.is === 'string';
6654 }
6655 switch (tagName) {
6656 // These are reserved SVG and MathML elements.
6657 // We don't mind this whitelist too much because we expect it to never grow.
6658 // The alternative is to track the namespace in a few places which is convoluted.
6659 // https://w3c.github.io/webcomponents/spec/custom/#custom-elements-core-concepts
6660 case 'annotation-xml':
6661 case 'color-profile':
6662 case 'font-face':
6663 case 'font-face-src':
6664 case 'font-face-uri':
6665 case 'font-face-format':
6666 case 'font-face-name':
6667 case 'missing-glyph':
6668 return false;
6669 default:
6670 return true;
6671 }
6672}
6673
6674// When adding attributes to the HTML or SVG whitelist, be sure to
6675// also add them to this module to ensure casing and incorrect name
6676// warnings.
6677var possibleStandardNames = {
6678 // HTML
6679 accept: 'accept',
6680 acceptcharset: 'acceptCharset',
6681 'accept-charset': 'acceptCharset',
6682 accesskey: 'accessKey',
6683 action: 'action',
6684 allowfullscreen: 'allowFullScreen',
6685 alt: 'alt',
6686 as: 'as',
6687 async: 'async',
6688 autocapitalize: 'autoCapitalize',
6689 autocomplete: 'autoComplete',
6690 autocorrect: 'autoCorrect',
6691 autofocus: 'autoFocus',
6692 autoplay: 'autoPlay',
6693 autosave: 'autoSave',
6694 capture: 'capture',
6695 cellpadding: 'cellPadding',
6696 cellspacing: 'cellSpacing',
6697 challenge: 'challenge',
6698 charset: 'charSet',
6699 checked: 'checked',
6700 children: 'children',
6701 cite: 'cite',
6702 class: 'className',
6703 classid: 'classID',
6704 classname: 'className',
6705 cols: 'cols',
6706 colspan: 'colSpan',
6707 content: 'content',
6708 contenteditable: 'contentEditable',
6709 contextmenu: 'contextMenu',
6710 controls: 'controls',
6711 controlslist: 'controlsList',
6712 coords: 'coords',
6713 crossorigin: 'crossOrigin',
6714 dangerouslysetinnerhtml: 'dangerouslySetInnerHTML',
6715 data: 'data',
6716 datetime: 'dateTime',
6717 default: 'default',
6718 defaultchecked: 'defaultChecked',
6719 defaultvalue: 'defaultValue',
6720 defer: 'defer',
6721 dir: 'dir',
6722 disabled: 'disabled',
6723 download: 'download',
6724 draggable: 'draggable',
6725 enctype: 'encType',
6726 for: 'htmlFor',
6727 form: 'form',
6728 formmethod: 'formMethod',
6729 formaction: 'formAction',
6730 formenctype: 'formEncType',
6731 formnovalidate: 'formNoValidate',
6732 formtarget: 'formTarget',
6733 frameborder: 'frameBorder',
6734 headers: 'headers',
6735 height: 'height',
6736 hidden: 'hidden',
6737 high: 'high',
6738 href: 'href',
6739 hreflang: 'hrefLang',
6740 htmlfor: 'htmlFor',
6741 httpequiv: 'httpEquiv',
6742 'http-equiv': 'httpEquiv',
6743 icon: 'icon',
6744 id: 'id',
6745 innerhtml: 'innerHTML',
6746 inputmode: 'inputMode',
6747 integrity: 'integrity',
6748 is: 'is',
6749 itemid: 'itemID',
6750 itemprop: 'itemProp',
6751 itemref: 'itemRef',
6752 itemscope: 'itemScope',
6753 itemtype: 'itemType',
6754 keyparams: 'keyParams',
6755 keytype: 'keyType',
6756 kind: 'kind',
6757 label: 'label',
6758 lang: 'lang',
6759 list: 'list',
6760 loop: 'loop',
6761 low: 'low',
6762 manifest: 'manifest',
6763 marginwidth: 'marginWidth',
6764 marginheight: 'marginHeight',
6765 max: 'max',
6766 maxlength: 'maxLength',
6767 media: 'media',
6768 mediagroup: 'mediaGroup',
6769 method: 'method',
6770 min: 'min',
6771 minlength: 'minLength',
6772 multiple: 'multiple',
6773 muted: 'muted',
6774 name: 'name',
6775 nomodule: 'noModule',
6776 nonce: 'nonce',
6777 novalidate: 'noValidate',
6778 open: 'open',
6779 optimum: 'optimum',
6780 pattern: 'pattern',
6781 placeholder: 'placeholder',
6782 playsinline: 'playsInline',
6783 poster: 'poster',
6784 preload: 'preload',
6785 profile: 'profile',
6786 radiogroup: 'radioGroup',
6787 readonly: 'readOnly',
6788 referrerpolicy: 'referrerPolicy',
6789 rel: 'rel',
6790 required: 'required',
6791 reversed: 'reversed',
6792 role: 'role',
6793 rows: 'rows',
6794 rowspan: 'rowSpan',
6795 sandbox: 'sandbox',
6796 scope: 'scope',
6797 scoped: 'scoped',
6798 scrolling: 'scrolling',
6799 seamless: 'seamless',
6800 selected: 'selected',
6801 shape: 'shape',
6802 size: 'size',
6803 sizes: 'sizes',
6804 span: 'span',
6805 spellcheck: 'spellCheck',
6806 src: 'src',
6807 srcdoc: 'srcDoc',
6808 srclang: 'srcLang',
6809 srcset: 'srcSet',
6810 start: 'start',
6811 step: 'step',
6812 style: 'style',
6813 summary: 'summary',
6814 tabindex: 'tabIndex',
6815 target: 'target',
6816 title: 'title',
6817 type: 'type',
6818 usemap: 'useMap',
6819 value: 'value',
6820 width: 'width',
6821 wmode: 'wmode',
6822 wrap: 'wrap',
6823
6824 // SVG
6825 about: 'about',
6826 accentheight: 'accentHeight',
6827 'accent-height': 'accentHeight',
6828 accumulate: 'accumulate',
6829 additive: 'additive',
6830 alignmentbaseline: 'alignmentBaseline',
6831 'alignment-baseline': 'alignmentBaseline',
6832 allowreorder: 'allowReorder',
6833 alphabetic: 'alphabetic',
6834 amplitude: 'amplitude',
6835 arabicform: 'arabicForm',
6836 'arabic-form': 'arabicForm',
6837 ascent: 'ascent',
6838 attributename: 'attributeName',
6839 attributetype: 'attributeType',
6840 autoreverse: 'autoReverse',
6841 azimuth: 'azimuth',
6842 basefrequency: 'baseFrequency',
6843 baselineshift: 'baselineShift',
6844 'baseline-shift': 'baselineShift',
6845 baseprofile: 'baseProfile',
6846 bbox: 'bbox',
6847 begin: 'begin',
6848 bias: 'bias',
6849 by: 'by',
6850 calcmode: 'calcMode',
6851 capheight: 'capHeight',
6852 'cap-height': 'capHeight',
6853 clip: 'clip',
6854 clippath: 'clipPath',
6855 'clip-path': 'clipPath',
6856 clippathunits: 'clipPathUnits',
6857 cliprule: 'clipRule',
6858 'clip-rule': 'clipRule',
6859 color: 'color',
6860 colorinterpolation: 'colorInterpolation',
6861 'color-interpolation': 'colorInterpolation',
6862 colorinterpolationfilters: 'colorInterpolationFilters',
6863 'color-interpolation-filters': 'colorInterpolationFilters',
6864 colorprofile: 'colorProfile',
6865 'color-profile': 'colorProfile',
6866 colorrendering: 'colorRendering',
6867 'color-rendering': 'colorRendering',
6868 contentscripttype: 'contentScriptType',
6869 contentstyletype: 'contentStyleType',
6870 cursor: 'cursor',
6871 cx: 'cx',
6872 cy: 'cy',
6873 d: 'd',
6874 datatype: 'datatype',
6875 decelerate: 'decelerate',
6876 descent: 'descent',
6877 diffuseconstant: 'diffuseConstant',
6878 direction: 'direction',
6879 display: 'display',
6880 divisor: 'divisor',
6881 dominantbaseline: 'dominantBaseline',
6882 'dominant-baseline': 'dominantBaseline',
6883 dur: 'dur',
6884 dx: 'dx',
6885 dy: 'dy',
6886 edgemode: 'edgeMode',
6887 elevation: 'elevation',
6888 enablebackground: 'enableBackground',
6889 'enable-background': 'enableBackground',
6890 end: 'end',
6891 exponent: 'exponent',
6892 externalresourcesrequired: 'externalResourcesRequired',
6893 fill: 'fill',
6894 fillopacity: 'fillOpacity',
6895 'fill-opacity': 'fillOpacity',
6896 fillrule: 'fillRule',
6897 'fill-rule': 'fillRule',
6898 filter: 'filter',
6899 filterres: 'filterRes',
6900 filterunits: 'filterUnits',
6901 floodopacity: 'floodOpacity',
6902 'flood-opacity': 'floodOpacity',
6903 floodcolor: 'floodColor',
6904 'flood-color': 'floodColor',
6905 focusable: 'focusable',
6906 fontfamily: 'fontFamily',
6907 'font-family': 'fontFamily',
6908 fontsize: 'fontSize',
6909 'font-size': 'fontSize',
6910 fontsizeadjust: 'fontSizeAdjust',
6911 'font-size-adjust': 'fontSizeAdjust',
6912 fontstretch: 'fontStretch',
6913 'font-stretch': 'fontStretch',
6914 fontstyle: 'fontStyle',
6915 'font-style': 'fontStyle',
6916 fontvariant: 'fontVariant',
6917 'font-variant': 'fontVariant',
6918 fontweight: 'fontWeight',
6919 'font-weight': 'fontWeight',
6920 format: 'format',
6921 from: 'from',
6922 fx: 'fx',
6923 fy: 'fy',
6924 g1: 'g1',
6925 g2: 'g2',
6926 glyphname: 'glyphName',
6927 'glyph-name': 'glyphName',
6928 glyphorientationhorizontal: 'glyphOrientationHorizontal',
6929 'glyph-orientation-horizontal': 'glyphOrientationHorizontal',
6930 glyphorientationvertical: 'glyphOrientationVertical',
6931 'glyph-orientation-vertical': 'glyphOrientationVertical',
6932 glyphref: 'glyphRef',
6933 gradienttransform: 'gradientTransform',
6934 gradientunits: 'gradientUnits',
6935 hanging: 'hanging',
6936 horizadvx: 'horizAdvX',
6937 'horiz-adv-x': 'horizAdvX',
6938 horizoriginx: 'horizOriginX',
6939 'horiz-origin-x': 'horizOriginX',
6940 ideographic: 'ideographic',
6941 imagerendering: 'imageRendering',
6942 'image-rendering': 'imageRendering',
6943 in2: 'in2',
6944 in: 'in',
6945 inlist: 'inlist',
6946 intercept: 'intercept',
6947 k1: 'k1',
6948 k2: 'k2',
6949 k3: 'k3',
6950 k4: 'k4',
6951 k: 'k',
6952 kernelmatrix: 'kernelMatrix',
6953 kernelunitlength: 'kernelUnitLength',
6954 kerning: 'kerning',
6955 keypoints: 'keyPoints',
6956 keysplines: 'keySplines',
6957 keytimes: 'keyTimes',
6958 lengthadjust: 'lengthAdjust',
6959 letterspacing: 'letterSpacing',
6960 'letter-spacing': 'letterSpacing',
6961 lightingcolor: 'lightingColor',
6962 'lighting-color': 'lightingColor',
6963 limitingconeangle: 'limitingConeAngle',
6964 local: 'local',
6965 markerend: 'markerEnd',
6966 'marker-end': 'markerEnd',
6967 markerheight: 'markerHeight',
6968 markermid: 'markerMid',
6969 'marker-mid': 'markerMid',
6970 markerstart: 'markerStart',
6971 'marker-start': 'markerStart',
6972 markerunits: 'markerUnits',
6973 markerwidth: 'markerWidth',
6974 mask: 'mask',
6975 maskcontentunits: 'maskContentUnits',
6976 maskunits: 'maskUnits',
6977 mathematical: 'mathematical',
6978 mode: 'mode',
6979 numoctaves: 'numOctaves',
6980 offset: 'offset',
6981 opacity: 'opacity',
6982 operator: 'operator',
6983 order: 'order',
6984 orient: 'orient',
6985 orientation: 'orientation',
6986 origin: 'origin',
6987 overflow: 'overflow',
6988 overlineposition: 'overlinePosition',
6989 'overline-position': 'overlinePosition',
6990 overlinethickness: 'overlineThickness',
6991 'overline-thickness': 'overlineThickness',
6992 paintorder: 'paintOrder',
6993 'paint-order': 'paintOrder',
6994 panose1: 'panose1',
6995 'panose-1': 'panose1',
6996 pathlength: 'pathLength',
6997 patterncontentunits: 'patternContentUnits',
6998 patterntransform: 'patternTransform',
6999 patternunits: 'patternUnits',
7000 pointerevents: 'pointerEvents',
7001 'pointer-events': 'pointerEvents',
7002 points: 'points',
7003 pointsatx: 'pointsAtX',
7004 pointsaty: 'pointsAtY',
7005 pointsatz: 'pointsAtZ',
7006 prefix: 'prefix',
7007 preservealpha: 'preserveAlpha',
7008 preserveaspectratio: 'preserveAspectRatio',
7009 primitiveunits: 'primitiveUnits',
7010 property: 'property',
7011 r: 'r',
7012 radius: 'radius',
7013 refx: 'refX',
7014 refy: 'refY',
7015 renderingintent: 'renderingIntent',
7016 'rendering-intent': 'renderingIntent',
7017 repeatcount: 'repeatCount',
7018 repeatdur: 'repeatDur',
7019 requiredextensions: 'requiredExtensions',
7020 requiredfeatures: 'requiredFeatures',
7021 resource: 'resource',
7022 restart: 'restart',
7023 result: 'result',
7024 results: 'results',
7025 rotate: 'rotate',
7026 rx: 'rx',
7027 ry: 'ry',
7028 scale: 'scale',
7029 security: 'security',
7030 seed: 'seed',
7031 shaperendering: 'shapeRendering',
7032 'shape-rendering': 'shapeRendering',
7033 slope: 'slope',
7034 spacing: 'spacing',
7035 specularconstant: 'specularConstant',
7036 specularexponent: 'specularExponent',
7037 speed: 'speed',
7038 spreadmethod: 'spreadMethod',
7039 startoffset: 'startOffset',
7040 stddeviation: 'stdDeviation',
7041 stemh: 'stemh',
7042 stemv: 'stemv',
7043 stitchtiles: 'stitchTiles',
7044 stopcolor: 'stopColor',
7045 'stop-color': 'stopColor',
7046 stopopacity: 'stopOpacity',
7047 'stop-opacity': 'stopOpacity',
7048 strikethroughposition: 'strikethroughPosition',
7049 'strikethrough-position': 'strikethroughPosition',
7050 strikethroughthickness: 'strikethroughThickness',
7051 'strikethrough-thickness': 'strikethroughThickness',
7052 string: 'string',
7053 stroke: 'stroke',
7054 strokedasharray: 'strokeDasharray',
7055 'stroke-dasharray': 'strokeDasharray',
7056 strokedashoffset: 'strokeDashoffset',
7057 'stroke-dashoffset': 'strokeDashoffset',
7058 strokelinecap: 'strokeLinecap',
7059 'stroke-linecap': 'strokeLinecap',
7060 strokelinejoin: 'strokeLinejoin',
7061 'stroke-linejoin': 'strokeLinejoin',
7062 strokemiterlimit: 'strokeMiterlimit',
7063 'stroke-miterlimit': 'strokeMiterlimit',
7064 strokewidth: 'strokeWidth',
7065 'stroke-width': 'strokeWidth',
7066 strokeopacity: 'strokeOpacity',
7067 'stroke-opacity': 'strokeOpacity',
7068 suppresscontenteditablewarning: 'suppressContentEditableWarning',
7069 suppresshydrationwarning: 'suppressHydrationWarning',
7070 surfacescale: 'surfaceScale',
7071 systemlanguage: 'systemLanguage',
7072 tablevalues: 'tableValues',
7073 targetx: 'targetX',
7074 targety: 'targetY',
7075 textanchor: 'textAnchor',
7076 'text-anchor': 'textAnchor',
7077 textdecoration: 'textDecoration',
7078 'text-decoration': 'textDecoration',
7079 textlength: 'textLength',
7080 textrendering: 'textRendering',
7081 'text-rendering': 'textRendering',
7082 to: 'to',
7083 transform: 'transform',
7084 typeof: 'typeof',
7085 u1: 'u1',
7086 u2: 'u2',
7087 underlineposition: 'underlinePosition',
7088 'underline-position': 'underlinePosition',
7089 underlinethickness: 'underlineThickness',
7090 'underline-thickness': 'underlineThickness',
7091 unicode: 'unicode',
7092 unicodebidi: 'unicodeBidi',
7093 'unicode-bidi': 'unicodeBidi',
7094 unicoderange: 'unicodeRange',
7095 'unicode-range': 'unicodeRange',
7096 unitsperem: 'unitsPerEm',
7097 'units-per-em': 'unitsPerEm',
7098 unselectable: 'unselectable',
7099 valphabetic: 'vAlphabetic',
7100 'v-alphabetic': 'vAlphabetic',
7101 values: 'values',
7102 vectoreffect: 'vectorEffect',
7103 'vector-effect': 'vectorEffect',
7104 version: 'version',
7105 vertadvy: 'vertAdvY',
7106 'vert-adv-y': 'vertAdvY',
7107 vertoriginx: 'vertOriginX',
7108 'vert-origin-x': 'vertOriginX',
7109 vertoriginy: 'vertOriginY',
7110 'vert-origin-y': 'vertOriginY',
7111 vhanging: 'vHanging',
7112 'v-hanging': 'vHanging',
7113 videographic: 'vIdeographic',
7114 'v-ideographic': 'vIdeographic',
7115 viewbox: 'viewBox',
7116 viewtarget: 'viewTarget',
7117 visibility: 'visibility',
7118 vmathematical: 'vMathematical',
7119 'v-mathematical': 'vMathematical',
7120 vocab: 'vocab',
7121 widths: 'widths',
7122 wordspacing: 'wordSpacing',
7123 'word-spacing': 'wordSpacing',
7124 writingmode: 'writingMode',
7125 'writing-mode': 'writingMode',
7126 x1: 'x1',
7127 x2: 'x2',
7128 x: 'x',
7129 xchannelselector: 'xChannelSelector',
7130 xheight: 'xHeight',
7131 'x-height': 'xHeight',
7132 xlinkactuate: 'xlinkActuate',
7133 'xlink:actuate': 'xlinkActuate',
7134 xlinkarcrole: 'xlinkArcrole',
7135 'xlink:arcrole': 'xlinkArcrole',
7136 xlinkhref: 'xlinkHref',
7137 'xlink:href': 'xlinkHref',
7138 xlinkrole: 'xlinkRole',
7139 'xlink:role': 'xlinkRole',
7140 xlinkshow: 'xlinkShow',
7141 'xlink:show': 'xlinkShow',
7142 xlinktitle: 'xlinkTitle',
7143 'xlink:title': 'xlinkTitle',
7144 xlinktype: 'xlinkType',
7145 'xlink:type': 'xlinkType',
7146 xmlbase: 'xmlBase',
7147 'xml:base': 'xmlBase',
7148 xmllang: 'xmlLang',
7149 'xml:lang': 'xmlLang',
7150 xmlns: 'xmlns',
7151 'xml:space': 'xmlSpace',
7152 xmlnsxlink: 'xmlnsXlink',
7153 'xmlns:xlink': 'xmlnsXlink',
7154 xmlspace: 'xmlSpace',
7155 y1: 'y1',
7156 y2: 'y2',
7157 y: 'y',
7158 ychannelselector: 'yChannelSelector',
7159 z: 'z',
7160 zoomandpan: 'zoomAndPan'
7161};
7162
7163var ariaProperties = {
7164 'aria-current': 0, // state
7165 'aria-details': 0,
7166 'aria-disabled': 0, // state
7167 'aria-hidden': 0, // state
7168 'aria-invalid': 0, // state
7169 'aria-keyshortcuts': 0,
7170 'aria-label': 0,
7171 'aria-roledescription': 0,
7172 // Widget Attributes
7173 'aria-autocomplete': 0,
7174 'aria-checked': 0,
7175 'aria-expanded': 0,
7176 'aria-haspopup': 0,
7177 'aria-level': 0,
7178 'aria-modal': 0,
7179 'aria-multiline': 0,
7180 'aria-multiselectable': 0,
7181 'aria-orientation': 0,
7182 'aria-placeholder': 0,
7183 'aria-pressed': 0,
7184 'aria-readonly': 0,
7185 'aria-required': 0,
7186 'aria-selected': 0,
7187 'aria-sort': 0,
7188 'aria-valuemax': 0,
7189 'aria-valuemin': 0,
7190 'aria-valuenow': 0,
7191 'aria-valuetext': 0,
7192 // Live Region Attributes
7193 'aria-atomic': 0,
7194 'aria-busy': 0,
7195 'aria-live': 0,
7196 'aria-relevant': 0,
7197 // Drag-and-Drop Attributes
7198 'aria-dropeffect': 0,
7199 'aria-grabbed': 0,
7200 // Relationship Attributes
7201 'aria-activedescendant': 0,
7202 'aria-colcount': 0,
7203 'aria-colindex': 0,
7204 'aria-colspan': 0,
7205 'aria-controls': 0,
7206 'aria-describedby': 0,
7207 'aria-errormessage': 0,
7208 'aria-flowto': 0,
7209 'aria-labelledby': 0,
7210 'aria-owns': 0,
7211 'aria-posinset': 0,
7212 'aria-rowcount': 0,
7213 'aria-rowindex': 0,
7214 'aria-rowspan': 0,
7215 'aria-setsize': 0
7216};
7217
7218var warnedProperties = {};
7219var rARIA = new RegExp('^(aria)-[' + ATTRIBUTE_NAME_CHAR + ']*$');
7220var rARIACamel = new RegExp('^(aria)[A-Z][' + ATTRIBUTE_NAME_CHAR + ']*$');
7221
7222var hasOwnProperty$2 = Object.prototype.hasOwnProperty;
7223
7224function validateProperty(tagName, name) {
7225 if (hasOwnProperty$2.call(warnedProperties, name) && warnedProperties[name]) {
7226 return true;
7227 }
7228
7229 if (rARIACamel.test(name)) {
7230 var ariaName = 'aria-' + name.slice(4).toLowerCase();
7231 var correctName = ariaProperties.hasOwnProperty(ariaName) ? ariaName : null;
7232
7233 // If this is an aria-* attribute, but is not listed in the known DOM
7234 // DOM properties, then it is an invalid aria-* attribute.
7235 if (correctName == null) {
7236 warning$1(false, 'Invalid ARIA attribute `%s`. ARIA attributes follow the pattern aria-* and must be lowercase.', name);
7237 warnedProperties[name] = true;
7238 return true;
7239 }
7240 // aria-* attributes should be lowercase; suggest the lowercase version.
7241 if (name !== correctName) {
7242 warning$1(false, 'Invalid ARIA attribute `%s`. Did you mean `%s`?', name, correctName);
7243 warnedProperties[name] = true;
7244 return true;
7245 }
7246 }
7247
7248 if (rARIA.test(name)) {
7249 var lowerCasedName = name.toLowerCase();
7250 var standardName = ariaProperties.hasOwnProperty(lowerCasedName) ? lowerCasedName : null;
7251
7252 // If this is an aria-* attribute, but is not listed in the known DOM
7253 // DOM properties, then it is an invalid aria-* attribute.
7254 if (standardName == null) {
7255 warnedProperties[name] = true;
7256 return false;
7257 }
7258 // aria-* attributes should be lowercase; suggest the lowercase version.
7259 if (name !== standardName) {
7260 warning$1(false, 'Unknown ARIA attribute `%s`. Did you mean `%s`?', name, standardName);
7261 warnedProperties[name] = true;
7262 return true;
7263 }
7264 }
7265
7266 return true;
7267}
7268
7269function warnInvalidARIAProps(type, props) {
7270 var invalidProps = [];
7271
7272 for (var key in props) {
7273 var isValid = validateProperty(type, key);
7274 if (!isValid) {
7275 invalidProps.push(key);
7276 }
7277 }
7278
7279 var unknownPropString = invalidProps.map(function (prop) {
7280 return '`' + prop + '`';
7281 }).join(', ');
7282
7283 if (invalidProps.length === 1) {
7284 warning$1(false, 'Invalid aria prop %s on <%s> tag. ' + 'For details, see https://fb.me/invalid-aria-prop', unknownPropString, type);
7285 } else if (invalidProps.length > 1) {
7286 warning$1(false, 'Invalid aria props %s on <%s> tag. ' + 'For details, see https://fb.me/invalid-aria-prop', unknownPropString, type);
7287 }
7288}
7289
7290function validateProperties(type, props) {
7291 if (isCustomComponent(type, props)) {
7292 return;
7293 }
7294 warnInvalidARIAProps(type, props);
7295}
7296
7297var didWarnValueNull = false;
7298
7299function validateProperties$1(type, props) {
7300 if (type !== 'input' && type !== 'textarea' && type !== 'select') {
7301 return;
7302 }
7303
7304 if (props != null && props.value === null && !didWarnValueNull) {
7305 didWarnValueNull = true;
7306 if (type === 'select' && props.multiple) {
7307 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);
7308 } else {
7309 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);
7310 }
7311 }
7312}
7313
7314var validateProperty$1 = function () {};
7315
7316{
7317 var warnedProperties$1 = {};
7318 var _hasOwnProperty = Object.prototype.hasOwnProperty;
7319 var EVENT_NAME_REGEX = /^on./;
7320 var INVALID_EVENT_NAME_REGEX = /^on[^A-Z]/;
7321 var rARIA$1 = new RegExp('^(aria)-[' + ATTRIBUTE_NAME_CHAR + ']*$');
7322 var rARIACamel$1 = new RegExp('^(aria)[A-Z][' + ATTRIBUTE_NAME_CHAR + ']*$');
7323
7324 validateProperty$1 = function (tagName, name, value, canUseEventSystem) {
7325 if (_hasOwnProperty.call(warnedProperties$1, name) && warnedProperties$1[name]) {
7326 return true;
7327 }
7328
7329 var lowerCasedName = name.toLowerCase();
7330 if (lowerCasedName === 'onfocusin' || lowerCasedName === 'onfocusout') {
7331 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.');
7332 warnedProperties$1[name] = true;
7333 return true;
7334 }
7335
7336 // We can't rely on the event system being injected on the server.
7337 if (canUseEventSystem) {
7338 if (registrationNameModules.hasOwnProperty(name)) {
7339 return true;
7340 }
7341 var registrationName = possibleRegistrationNames.hasOwnProperty(lowerCasedName) ? possibleRegistrationNames[lowerCasedName] : null;
7342 if (registrationName != null) {
7343 warning$1(false, 'Invalid event handler property `%s`. Did you mean `%s`?', name, registrationName);
7344 warnedProperties$1[name] = true;
7345 return true;
7346 }
7347 if (EVENT_NAME_REGEX.test(name)) {
7348 warning$1(false, 'Unknown event handler property `%s`. It will be ignored.', name);
7349 warnedProperties$1[name] = true;
7350 return true;
7351 }
7352 } else if (EVENT_NAME_REGEX.test(name)) {
7353 // If no event plugins have been injected, we are in a server environment.
7354 // So we can't tell if the event name is correct for sure, but we can filter
7355 // out known bad ones like `onclick`. We can't suggest a specific replacement though.
7356 if (INVALID_EVENT_NAME_REGEX.test(name)) {
7357 warning$1(false, 'Invalid event handler property `%s`. ' + 'React events use the camelCase naming convention, for example `onClick`.', name);
7358 }
7359 warnedProperties$1[name] = true;
7360 return true;
7361 }
7362
7363 // Let the ARIA attribute hook validate ARIA attributes
7364 if (rARIA$1.test(name) || rARIACamel$1.test(name)) {
7365 return true;
7366 }
7367
7368 if (lowerCasedName === 'innerhtml') {
7369 warning$1(false, 'Directly setting property `innerHTML` is not permitted. ' + 'For more information, lookup documentation on `dangerouslySetInnerHTML`.');
7370 warnedProperties$1[name] = true;
7371 return true;
7372 }
7373
7374 if (lowerCasedName === 'aria') {
7375 warning$1(false, 'The `aria` attribute is reserved for future use in React. ' + 'Pass individual `aria-` attributes instead.');
7376 warnedProperties$1[name] = true;
7377 return true;
7378 }
7379
7380 if (lowerCasedName === 'is' && value !== null && value !== undefined && typeof value !== 'string') {
7381 warning$1(false, 'Received a `%s` for a string attribute `is`. If this is expected, cast ' + 'the value to a string.', typeof value);
7382 warnedProperties$1[name] = true;
7383 return true;
7384 }
7385
7386 if (typeof value === 'number' && isNaN(value)) {
7387 warning$1(false, 'Received NaN for the `%s` attribute. If this is expected, cast ' + 'the value to a string.', name);
7388 warnedProperties$1[name] = true;
7389 return true;
7390 }
7391
7392 var propertyInfo = getPropertyInfo(name);
7393 var isReserved = propertyInfo !== null && propertyInfo.type === RESERVED;
7394
7395 // Known attributes should match the casing specified in the property config.
7396 if (possibleStandardNames.hasOwnProperty(lowerCasedName)) {
7397 var standardName = possibleStandardNames[lowerCasedName];
7398 if (standardName !== name) {
7399 warning$1(false, 'Invalid DOM property `%s`. Did you mean `%s`?', name, standardName);
7400 warnedProperties$1[name] = true;
7401 return true;
7402 }
7403 } else if (!isReserved && name !== lowerCasedName) {
7404 // Unknown attributes should have lowercase casing since that's how they
7405 // will be cased anyway with server rendering.
7406 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);
7407 warnedProperties$1[name] = true;
7408 return true;
7409 }
7410
7411 if (typeof value === 'boolean' && shouldRemoveAttributeWithWarning(name, value, propertyInfo, false)) {
7412 if (value) {
7413 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);
7414 } else {
7415 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);
7416 }
7417 warnedProperties$1[name] = true;
7418 return true;
7419 }
7420
7421 // Now that we've validated casing, do not validate
7422 // data types for reserved props
7423 if (isReserved) {
7424 return true;
7425 }
7426
7427 // Warn when a known attribute is a bad type
7428 if (shouldRemoveAttributeWithWarning(name, value, propertyInfo, false)) {
7429 warnedProperties$1[name] = true;
7430 return false;
7431 }
7432
7433 // Warn when passing the strings 'false' or 'true' into a boolean prop
7434 if ((value === 'false' || value === 'true') && propertyInfo !== null && propertyInfo.type === BOOLEAN) {
7435 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);
7436 warnedProperties$1[name] = true;
7437 return true;
7438 }
7439
7440 return true;
7441 };
7442}
7443
7444var warnUnknownProperties = function (type, props, canUseEventSystem) {
7445 var unknownProps = [];
7446 for (var key in props) {
7447 var isValid = validateProperty$1(type, key, props[key], canUseEventSystem);
7448 if (!isValid) {
7449 unknownProps.push(key);
7450 }
7451 }
7452
7453 var unknownPropString = unknownProps.map(function (prop) {
7454 return '`' + prop + '`';
7455 }).join(', ');
7456 if (unknownProps.length === 1) {
7457 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);
7458 } else if (unknownProps.length > 1) {
7459 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);
7460 }
7461};
7462
7463function validateProperties$2(type, props, canUseEventSystem) {
7464 if (isCustomComponent(type, props)) {
7465 return;
7466 }
7467 warnUnknownProperties(type, props, canUseEventSystem);
7468}
7469
7470// TODO: direct imports like some-package/src/* are bad. Fix me.
7471var didWarnInvalidHydration = false;
7472var didWarnShadyDOM = false;
7473
7474var DANGEROUSLY_SET_INNER_HTML = 'dangerouslySetInnerHTML';
7475var SUPPRESS_CONTENT_EDITABLE_WARNING = 'suppressContentEditableWarning';
7476var SUPPRESS_HYDRATION_WARNING$1 = 'suppressHydrationWarning';
7477var AUTOFOCUS = 'autoFocus';
7478var CHILDREN = 'children';
7479var STYLE$1 = 'style';
7480var HTML = '__html';
7481
7482var HTML_NAMESPACE = Namespaces.html;
7483
7484
7485var warnedUnknownTags = void 0;
7486var suppressHydrationWarning = void 0;
7487
7488var validatePropertiesInDevelopment = void 0;
7489var warnForTextDifference = void 0;
7490var warnForPropDifference = void 0;
7491var warnForExtraAttributes = void 0;
7492var warnForInvalidEventListener = void 0;
7493var canDiffStyleForHydrationWarning = void 0;
7494
7495var normalizeMarkupForTextOrAttribute = void 0;
7496var normalizeHTML = void 0;
7497
7498{
7499 warnedUnknownTags = {
7500 // Chrome is the only major browser not shipping <time>. But as of July
7501 // 2017 it intends to ship it due to widespread usage. We intentionally
7502 // *don't* warn for <time> even if it's unrecognized by Chrome because
7503 // it soon will be, and many apps have been using it anyway.
7504 time: true,
7505 // There are working polyfills for <dialog>. Let people use it.
7506 dialog: true,
7507 // Electron ships a custom <webview> tag to display external web content in
7508 // an isolated frame and process.
7509 // This tag is not present in non Electron environments such as JSDom which
7510 // is often used for testing purposes.
7511 // @see https://electronjs.org/docs/api/webview-tag
7512 webview: true
7513 };
7514
7515 validatePropertiesInDevelopment = function (type, props) {
7516 validateProperties(type, props);
7517 validateProperties$1(type, props);
7518 validateProperties$2(type, props, /* canUseEventSystem */true);
7519 };
7520
7521 // IE 11 parses & normalizes the style attribute as opposed to other
7522 // browsers. It adds spaces and sorts the properties in some
7523 // non-alphabetical order. Handling that would require sorting CSS
7524 // properties in the client & server versions or applying
7525 // `expectedStyle` to a temporary DOM node to read its `style` attribute
7526 // normalized. Since it only affects IE, we're skipping style warnings
7527 // in that browser completely in favor of doing all that work.
7528 // See https://github.com/facebook/react/issues/11807
7529 canDiffStyleForHydrationWarning = canUseDOM && !document.documentMode;
7530
7531 // HTML parsing normalizes CR and CRLF to LF.
7532 // It also can turn \u0000 into \uFFFD inside attributes.
7533 // https://www.w3.org/TR/html5/single-page.html#preprocessing-the-input-stream
7534 // If we have a mismatch, it might be caused by that.
7535 // We will still patch up in this case but not fire the warning.
7536 var NORMALIZE_NEWLINES_REGEX = /\r\n?/g;
7537 var NORMALIZE_NULL_AND_REPLACEMENT_REGEX = /\u0000|\uFFFD/g;
7538
7539 normalizeMarkupForTextOrAttribute = function (markup) {
7540 var markupString = typeof markup === 'string' ? markup : '' + markup;
7541 return markupString.replace(NORMALIZE_NEWLINES_REGEX, '\n').replace(NORMALIZE_NULL_AND_REPLACEMENT_REGEX, '');
7542 };
7543
7544 warnForTextDifference = function (serverText, clientText) {
7545 if (didWarnInvalidHydration) {
7546 return;
7547 }
7548 var normalizedClientText = normalizeMarkupForTextOrAttribute(clientText);
7549 var normalizedServerText = normalizeMarkupForTextOrAttribute(serverText);
7550 if (normalizedServerText === normalizedClientText) {
7551 return;
7552 }
7553 didWarnInvalidHydration = true;
7554 warningWithoutStack$1(false, 'Text content did not match. Server: "%s" Client: "%s"', normalizedServerText, normalizedClientText);
7555 };
7556
7557 warnForPropDifference = function (propName, serverValue, clientValue) {
7558 if (didWarnInvalidHydration) {
7559 return;
7560 }
7561 var normalizedClientValue = normalizeMarkupForTextOrAttribute(clientValue);
7562 var normalizedServerValue = normalizeMarkupForTextOrAttribute(serverValue);
7563 if (normalizedServerValue === normalizedClientValue) {
7564 return;
7565 }
7566 didWarnInvalidHydration = true;
7567 warningWithoutStack$1(false, 'Prop `%s` did not match. Server: %s Client: %s', propName, JSON.stringify(normalizedServerValue), JSON.stringify(normalizedClientValue));
7568 };
7569
7570 warnForExtraAttributes = function (attributeNames) {
7571 if (didWarnInvalidHydration) {
7572 return;
7573 }
7574 didWarnInvalidHydration = true;
7575 var names = [];
7576 attributeNames.forEach(function (name) {
7577 names.push(name);
7578 });
7579 warningWithoutStack$1(false, 'Extra attributes from the server: %s', names);
7580 };
7581
7582 warnForInvalidEventListener = function (registrationName, listener) {
7583 if (listener === false) {
7584 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);
7585 } else {
7586 warning$1(false, 'Expected `%s` listener to be a function, instead got a value of `%s` type.', registrationName, typeof listener);
7587 }
7588 };
7589
7590 // Parse the HTML and read it back to normalize the HTML string so that it
7591 // can be used for comparison.
7592 normalizeHTML = function (parent, html) {
7593 // We could have created a separate document here to avoid
7594 // re-initializing custom elements if they exist. But this breaks
7595 // how <noscript> is being handled. So we use the same document.
7596 // See the discussion in https://github.com/facebook/react/pull/11157.
7597 var testElement = parent.namespaceURI === HTML_NAMESPACE ? parent.ownerDocument.createElement(parent.tagName) : parent.ownerDocument.createElementNS(parent.namespaceURI, parent.tagName);
7598 testElement.innerHTML = html;
7599 return testElement.innerHTML;
7600 };
7601}
7602
7603function ensureListeningTo(rootContainerElement, registrationName) {
7604 var isDocumentOrFragment = rootContainerElement.nodeType === DOCUMENT_NODE || rootContainerElement.nodeType === DOCUMENT_FRAGMENT_NODE;
7605 var doc = isDocumentOrFragment ? rootContainerElement : rootContainerElement.ownerDocument;
7606 listenTo(registrationName, doc);
7607}
7608
7609function getOwnerDocumentFromRootContainer(rootContainerElement) {
7610 return rootContainerElement.nodeType === DOCUMENT_NODE ? rootContainerElement : rootContainerElement.ownerDocument;
7611}
7612
7613function noop() {}
7614
7615function trapClickOnNonInteractiveElement(node) {
7616 // Mobile Safari does not fire properly bubble click events on
7617 // non-interactive elements, which means delegated click listeners do not
7618 // fire. The workaround for this bug involves attaching an empty click
7619 // listener on the target node.
7620 // http://www.quirksmode.org/blog/archives/2010/09/click_event_del.html
7621 // Just set it using the onclick property so that we don't have to manage any
7622 // bookkeeping for it. Not sure if we need to clear it when the listener is
7623 // removed.
7624 // TODO: Only do this for the relevant Safaris maybe?
7625 node.onclick = noop;
7626}
7627
7628function setInitialDOMProperties(tag, domElement, rootContainerElement, nextProps, isCustomComponentTag) {
7629 for (var propKey in nextProps) {
7630 if (!nextProps.hasOwnProperty(propKey)) {
7631 continue;
7632 }
7633 var nextProp = nextProps[propKey];
7634 if (propKey === STYLE$1) {
7635 {
7636 if (nextProp) {
7637 // Freeze the next style object so that we can assume it won't be
7638 // mutated. We have already warned for this in the past.
7639 Object.freeze(nextProp);
7640 }
7641 }
7642 // Relies on `updateStylesByID` not mutating `styleUpdates`.
7643 setValueForStyles(domElement, nextProp);
7644 } else if (propKey === DANGEROUSLY_SET_INNER_HTML) {
7645 var nextHtml = nextProp ? nextProp[HTML] : undefined;
7646 if (nextHtml != null) {
7647 setInnerHTML(domElement, nextHtml);
7648 }
7649 } else if (propKey === CHILDREN) {
7650 if (typeof nextProp === 'string') {
7651 // Avoid setting initial textContent when the text is empty. In IE11 setting
7652 // textContent on a <textarea> will cause the placeholder to not
7653 // show within the <textarea> until it has been focused and blurred again.
7654 // https://github.com/facebook/react/issues/6731#issuecomment-254874553
7655 var canSetTextContent = tag !== 'textarea' || nextProp !== '';
7656 if (canSetTextContent) {
7657 setTextContent(domElement, nextProp);
7658 }
7659 } else if (typeof nextProp === 'number') {
7660 setTextContent(domElement, '' + nextProp);
7661 }
7662 } else if (propKey === SUPPRESS_CONTENT_EDITABLE_WARNING || propKey === SUPPRESS_HYDRATION_WARNING$1) {
7663 // Noop
7664 } else if (propKey === AUTOFOCUS) {
7665 // We polyfill it separately on the client during commit.
7666 // We could have excluded it in the property list instead of
7667 // adding a special case here, but then it wouldn't be emitted
7668 // on server rendering (but we *do* want to emit it in SSR).
7669 } else if (registrationNameModules.hasOwnProperty(propKey)) {
7670 if (nextProp != null) {
7671 if (true && typeof nextProp !== 'function') {
7672 warnForInvalidEventListener(propKey, nextProp);
7673 }
7674 ensureListeningTo(rootContainerElement, propKey);
7675 }
7676 } else if (nextProp != null) {
7677 setValueForProperty(domElement, propKey, nextProp, isCustomComponentTag);
7678 }
7679 }
7680}
7681
7682function updateDOMProperties(domElement, updatePayload, wasCustomComponentTag, isCustomComponentTag) {
7683 // TODO: Handle wasCustomComponentTag
7684 for (var i = 0; i < updatePayload.length; i += 2) {
7685 var propKey = updatePayload[i];
7686 var propValue = updatePayload[i + 1];
7687 if (propKey === STYLE$1) {
7688 setValueForStyles(domElement, propValue);
7689 } else if (propKey === DANGEROUSLY_SET_INNER_HTML) {
7690 setInnerHTML(domElement, propValue);
7691 } else if (propKey === CHILDREN) {
7692 setTextContent(domElement, propValue);
7693 } else {
7694 setValueForProperty(domElement, propKey, propValue, isCustomComponentTag);
7695 }
7696 }
7697}
7698
7699function createElement(type, props, rootContainerElement, parentNamespace) {
7700 var isCustomComponentTag = void 0;
7701
7702 // We create tags in the namespace of their parent container, except HTML
7703 // tags get no namespace.
7704 var ownerDocument = getOwnerDocumentFromRootContainer(rootContainerElement);
7705 var domElement = void 0;
7706 var namespaceURI = parentNamespace;
7707 if (namespaceURI === HTML_NAMESPACE) {
7708 namespaceURI = getIntrinsicNamespace(type);
7709 }
7710 if (namespaceURI === HTML_NAMESPACE) {
7711 {
7712 isCustomComponentTag = isCustomComponent(type, props);
7713 // Should this check be gated by parent namespace? Not sure we want to
7714 // allow <SVG> or <mATH>.
7715 !(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;
7716 }
7717
7718 if (type === 'script') {
7719 // Create the script via .innerHTML so its "parser-inserted" flag is
7720 // set to true and it does not execute
7721 var div = ownerDocument.createElement('div');
7722 div.innerHTML = '<script><' + '/script>'; // eslint-disable-line
7723 // This is guaranteed to yield a script element.
7724 var firstChild = div.firstChild;
7725 domElement = div.removeChild(firstChild);
7726 } else if (typeof props.is === 'string') {
7727 // $FlowIssue `createElement` should be updated for Web Components
7728 domElement = ownerDocument.createElement(type, { is: props.is });
7729 } else {
7730 // Separate else branch instead of using `props.is || undefined` above because of a Firefox bug.
7731 // See discussion in https://github.com/facebook/react/pull/6896
7732 // and discussion in https://bugzilla.mozilla.org/show_bug.cgi?id=1276240
7733 domElement = ownerDocument.createElement(type);
7734 // Normally attributes are assigned in `setInitialDOMProperties`, however the `multiple`
7735 // attribute on `select`s needs to be added before `option`s are inserted. This prevents
7736 // a bug where the `select` does not scroll to the correct option because singular
7737 // `select` elements automatically pick the first item.
7738 // See https://github.com/facebook/react/issues/13222
7739 if (type === 'select' && props.multiple) {
7740 var node = domElement;
7741 node.multiple = true;
7742 }
7743 }
7744 } else {
7745 domElement = ownerDocument.createElementNS(namespaceURI, type);
7746 }
7747
7748 {
7749 if (namespaceURI === HTML_NAMESPACE) {
7750 if (!isCustomComponentTag && Object.prototype.toString.call(domElement) === '[object HTMLUnknownElement]' && !Object.prototype.hasOwnProperty.call(warnedUnknownTags, type)) {
7751 warnedUnknownTags[type] = true;
7752 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);
7753 }
7754 }
7755 }
7756
7757 return domElement;
7758}
7759
7760function createTextNode(text, rootContainerElement) {
7761 return getOwnerDocumentFromRootContainer(rootContainerElement).createTextNode(text);
7762}
7763
7764function setInitialProperties(domElement, tag, rawProps, rootContainerElement) {
7765 var isCustomComponentTag = isCustomComponent(tag, rawProps);
7766 {
7767 validatePropertiesInDevelopment(tag, rawProps);
7768 if (isCustomComponentTag && !didWarnShadyDOM && domElement.shadyRoot) {
7769 warning$1(false, '%s is using shady DOM. Using shady DOM with React can ' + 'cause things to break subtly.', getCurrentFiberOwnerNameInDevOrNull() || 'A component');
7770 didWarnShadyDOM = true;
7771 }
7772 }
7773
7774 // TODO: Make sure that we check isMounted before firing any of these events.
7775 var props = void 0;
7776 switch (tag) {
7777 case 'iframe':
7778 case 'object':
7779 trapBubbledEvent(TOP_LOAD, domElement);
7780 props = rawProps;
7781 break;
7782 case 'video':
7783 case 'audio':
7784 // Create listener for each media event
7785 for (var i = 0; i < mediaEventTypes.length; i++) {
7786 trapBubbledEvent(mediaEventTypes[i], domElement);
7787 }
7788 props = rawProps;
7789 break;
7790 case 'source':
7791 trapBubbledEvent(TOP_ERROR, domElement);
7792 props = rawProps;
7793 break;
7794 case 'img':
7795 case 'image':
7796 case 'link':
7797 trapBubbledEvent(TOP_ERROR, domElement);
7798 trapBubbledEvent(TOP_LOAD, domElement);
7799 props = rawProps;
7800 break;
7801 case 'form':
7802 trapBubbledEvent(TOP_RESET, domElement);
7803 trapBubbledEvent(TOP_SUBMIT, domElement);
7804 props = rawProps;
7805 break;
7806 case 'details':
7807 trapBubbledEvent(TOP_TOGGLE, domElement);
7808 props = rawProps;
7809 break;
7810 case 'input':
7811 initWrapperState(domElement, rawProps);
7812 props = getHostProps(domElement, rawProps);
7813 trapBubbledEvent(TOP_INVALID, domElement);
7814 // For controlled components we always need to ensure we're listening
7815 // to onChange. Even if there is no listener.
7816 ensureListeningTo(rootContainerElement, 'onChange');
7817 break;
7818 case 'option':
7819 validateProps(domElement, rawProps);
7820 props = getHostProps$1(domElement, rawProps);
7821 break;
7822 case 'select':
7823 initWrapperState$1(domElement, rawProps);
7824 props = getHostProps$2(domElement, rawProps);
7825 trapBubbledEvent(TOP_INVALID, domElement);
7826 // For controlled components we always need to ensure we're listening
7827 // to onChange. Even if there is no listener.
7828 ensureListeningTo(rootContainerElement, 'onChange');
7829 break;
7830 case 'textarea':
7831 initWrapperState$2(domElement, rawProps);
7832 props = getHostProps$3(domElement, rawProps);
7833 trapBubbledEvent(TOP_INVALID, domElement);
7834 // For controlled components we always need to ensure we're listening
7835 // to onChange. Even if there is no listener.
7836 ensureListeningTo(rootContainerElement, 'onChange');
7837 break;
7838 default:
7839 props = rawProps;
7840 }
7841
7842 assertValidProps(tag, props);
7843
7844 setInitialDOMProperties(tag, domElement, rootContainerElement, props, isCustomComponentTag);
7845
7846 switch (tag) {
7847 case 'input':
7848 // TODO: Make sure we check if this is still unmounted or do any clean
7849 // up necessary since we never stop tracking anymore.
7850 track(domElement);
7851 postMountWrapper(domElement, rawProps, false);
7852 break;
7853 case 'textarea':
7854 // TODO: Make sure we check if this is still unmounted or do any clean
7855 // up necessary since we never stop tracking anymore.
7856 track(domElement);
7857 postMountWrapper$3(domElement, rawProps);
7858 break;
7859 case 'option':
7860 postMountWrapper$1(domElement, rawProps);
7861 break;
7862 case 'select':
7863 postMountWrapper$2(domElement, rawProps);
7864 break;
7865 default:
7866 if (typeof props.onClick === 'function') {
7867 // TODO: This cast may not be sound for SVG, MathML or custom elements.
7868 trapClickOnNonInteractiveElement(domElement);
7869 }
7870 break;
7871 }
7872}
7873
7874// Calculate the diff between the two objects.
7875function diffProperties(domElement, tag, lastRawProps, nextRawProps, rootContainerElement) {
7876 {
7877 validatePropertiesInDevelopment(tag, nextRawProps);
7878 }
7879
7880 var updatePayload = null;
7881
7882 var lastProps = void 0;
7883 var nextProps = void 0;
7884 switch (tag) {
7885 case 'input':
7886 lastProps = getHostProps(domElement, lastRawProps);
7887 nextProps = getHostProps(domElement, nextRawProps);
7888 updatePayload = [];
7889 break;
7890 case 'option':
7891 lastProps = getHostProps$1(domElement, lastRawProps);
7892 nextProps = getHostProps$1(domElement, nextRawProps);
7893 updatePayload = [];
7894 break;
7895 case 'select':
7896 lastProps = getHostProps$2(domElement, lastRawProps);
7897 nextProps = getHostProps$2(domElement, nextRawProps);
7898 updatePayload = [];
7899 break;
7900 case 'textarea':
7901 lastProps = getHostProps$3(domElement, lastRawProps);
7902 nextProps = getHostProps$3(domElement, nextRawProps);
7903 updatePayload = [];
7904 break;
7905 default:
7906 lastProps = lastRawProps;
7907 nextProps = nextRawProps;
7908 if (typeof lastProps.onClick !== 'function' && typeof nextProps.onClick === 'function') {
7909 // TODO: This cast may not be sound for SVG, MathML or custom elements.
7910 trapClickOnNonInteractiveElement(domElement);
7911 }
7912 break;
7913 }
7914
7915 assertValidProps(tag, nextProps);
7916
7917 var propKey = void 0;
7918 var styleName = void 0;
7919 var styleUpdates = null;
7920 for (propKey in lastProps) {
7921 if (nextProps.hasOwnProperty(propKey) || !lastProps.hasOwnProperty(propKey) || lastProps[propKey] == null) {
7922 continue;
7923 }
7924 if (propKey === STYLE$1) {
7925 var lastStyle = lastProps[propKey];
7926 for (styleName in lastStyle) {
7927 if (lastStyle.hasOwnProperty(styleName)) {
7928 if (!styleUpdates) {
7929 styleUpdates = {};
7930 }
7931 styleUpdates[styleName] = '';
7932 }
7933 }
7934 } else if (propKey === DANGEROUSLY_SET_INNER_HTML || propKey === CHILDREN) {
7935 // Noop. This is handled by the clear text mechanism.
7936 } else if (propKey === SUPPRESS_CONTENT_EDITABLE_WARNING || propKey === SUPPRESS_HYDRATION_WARNING$1) {
7937 // Noop
7938 } else if (propKey === AUTOFOCUS) {
7939 // Noop. It doesn't work on updates anyway.
7940 } else if (registrationNameModules.hasOwnProperty(propKey)) {
7941 // This is a special case. If any listener updates we need to ensure
7942 // that the "current" fiber pointer gets updated so we need a commit
7943 // to update this element.
7944 if (!updatePayload) {
7945 updatePayload = [];
7946 }
7947 } else {
7948 // For all other deleted properties we add it to the queue. We use
7949 // the whitelist in the commit phase instead.
7950 (updatePayload = updatePayload || []).push(propKey, null);
7951 }
7952 }
7953 for (propKey in nextProps) {
7954 var nextProp = nextProps[propKey];
7955 var lastProp = lastProps != null ? lastProps[propKey] : undefined;
7956 if (!nextProps.hasOwnProperty(propKey) || nextProp === lastProp || nextProp == null && lastProp == null) {
7957 continue;
7958 }
7959 if (propKey === STYLE$1) {
7960 {
7961 if (nextProp) {
7962 // Freeze the next style object so that we can assume it won't be
7963 // mutated. We have already warned for this in the past.
7964 Object.freeze(nextProp);
7965 }
7966 }
7967 if (lastProp) {
7968 // Unset styles on `lastProp` but not on `nextProp`.
7969 for (styleName in lastProp) {
7970 if (lastProp.hasOwnProperty(styleName) && (!nextProp || !nextProp.hasOwnProperty(styleName))) {
7971 if (!styleUpdates) {
7972 styleUpdates = {};
7973 }
7974 styleUpdates[styleName] = '';
7975 }
7976 }
7977 // Update styles that changed since `lastProp`.
7978 for (styleName in nextProp) {
7979 if (nextProp.hasOwnProperty(styleName) && lastProp[styleName] !== nextProp[styleName]) {
7980 if (!styleUpdates) {
7981 styleUpdates = {};
7982 }
7983 styleUpdates[styleName] = nextProp[styleName];
7984 }
7985 }
7986 } else {
7987 // Relies on `updateStylesByID` not mutating `styleUpdates`.
7988 if (!styleUpdates) {
7989 if (!updatePayload) {
7990 updatePayload = [];
7991 }
7992 updatePayload.push(propKey, styleUpdates);
7993 }
7994 styleUpdates = nextProp;
7995 }
7996 } else if (propKey === DANGEROUSLY_SET_INNER_HTML) {
7997 var nextHtml = nextProp ? nextProp[HTML] : undefined;
7998 var lastHtml = lastProp ? lastProp[HTML] : undefined;
7999 if (nextHtml != null) {
8000 if (lastHtml !== nextHtml) {
8001 (updatePayload = updatePayload || []).push(propKey, '' + nextHtml);
8002 }
8003 } else {
8004 // TODO: It might be too late to clear this if we have children
8005 // inserted already.
8006 }
8007 } else if (propKey === CHILDREN) {
8008 if (lastProp !== nextProp && (typeof nextProp === 'string' || typeof nextProp === 'number')) {
8009 (updatePayload = updatePayload || []).push(propKey, '' + nextProp);
8010 }
8011 } else if (propKey === SUPPRESS_CONTENT_EDITABLE_WARNING || propKey === SUPPRESS_HYDRATION_WARNING$1) {
8012 // Noop
8013 } else if (registrationNameModules.hasOwnProperty(propKey)) {
8014 if (nextProp != null) {
8015 // We eagerly listen to this even though we haven't committed yet.
8016 if (true && typeof nextProp !== 'function') {
8017 warnForInvalidEventListener(propKey, nextProp);
8018 }
8019 ensureListeningTo(rootContainerElement, propKey);
8020 }
8021 if (!updatePayload && lastProp !== nextProp) {
8022 // This is a special case. If any listener updates we need to ensure
8023 // that the "current" props pointer gets updated so we need a commit
8024 // to update this element.
8025 updatePayload = [];
8026 }
8027 } else {
8028 // For any other property we always add it to the queue and then we
8029 // filter it out using the whitelist during the commit.
8030 (updatePayload = updatePayload || []).push(propKey, nextProp);
8031 }
8032 }
8033 if (styleUpdates) {
8034 {
8035 validateShorthandPropertyCollisionInDev(styleUpdates, nextProps[STYLE$1]);
8036 }
8037 (updatePayload = updatePayload || []).push(STYLE$1, styleUpdates);
8038 }
8039 return updatePayload;
8040}
8041
8042// Apply the diff.
8043function updateProperties(domElement, updatePayload, tag, lastRawProps, nextRawProps) {
8044 // Update checked *before* name.
8045 // In the middle of an update, it is possible to have multiple checked.
8046 // When a checked radio tries to change name, browser makes another radio's checked false.
8047 if (tag === 'input' && nextRawProps.type === 'radio' && nextRawProps.name != null) {
8048 updateChecked(domElement, nextRawProps);
8049 }
8050
8051 var wasCustomComponentTag = isCustomComponent(tag, lastRawProps);
8052 var isCustomComponentTag = isCustomComponent(tag, nextRawProps);
8053 // Apply the diff.
8054 updateDOMProperties(domElement, updatePayload, wasCustomComponentTag, isCustomComponentTag);
8055
8056 // TODO: Ensure that an update gets scheduled if any of the special props
8057 // changed.
8058 switch (tag) {
8059 case 'input':
8060 // Update the wrapper around inputs *after* updating props. This has to
8061 // happen after `updateDOMProperties`. Otherwise HTML5 input validations
8062 // raise warnings and prevent the new value from being assigned.
8063 updateWrapper(domElement, nextRawProps);
8064 break;
8065 case 'textarea':
8066 updateWrapper$1(domElement, nextRawProps);
8067 break;
8068 case 'select':
8069 // <select> value update needs to occur after <option> children
8070 // reconciliation
8071 postUpdateWrapper(domElement, nextRawProps);
8072 break;
8073 }
8074}
8075
8076function getPossibleStandardName(propName) {
8077 {
8078 var lowerCasedName = propName.toLowerCase();
8079 if (!possibleStandardNames.hasOwnProperty(lowerCasedName)) {
8080 return null;
8081 }
8082 return possibleStandardNames[lowerCasedName] || null;
8083 }
8084 return null;
8085}
8086
8087function diffHydratedProperties(domElement, tag, rawProps, parentNamespace, rootContainerElement) {
8088 var isCustomComponentTag = void 0;
8089 var extraAttributeNames = void 0;
8090
8091 {
8092 suppressHydrationWarning = rawProps[SUPPRESS_HYDRATION_WARNING$1] === true;
8093 isCustomComponentTag = isCustomComponent(tag, rawProps);
8094 validatePropertiesInDevelopment(tag, rawProps);
8095 if (isCustomComponentTag && !didWarnShadyDOM && domElement.shadyRoot) {
8096 warning$1(false, '%s is using shady DOM. Using shady DOM with React can ' + 'cause things to break subtly.', getCurrentFiberOwnerNameInDevOrNull() || 'A component');
8097 didWarnShadyDOM = true;
8098 }
8099 }
8100
8101 // TODO: Make sure that we check isMounted before firing any of these events.
8102 switch (tag) {
8103 case 'iframe':
8104 case 'object':
8105 trapBubbledEvent(TOP_LOAD, domElement);
8106 break;
8107 case 'video':
8108 case 'audio':
8109 // Create listener for each media event
8110 for (var i = 0; i < mediaEventTypes.length; i++) {
8111 trapBubbledEvent(mediaEventTypes[i], domElement);
8112 }
8113 break;
8114 case 'source':
8115 trapBubbledEvent(TOP_ERROR, domElement);
8116 break;
8117 case 'img':
8118 case 'image':
8119 case 'link':
8120 trapBubbledEvent(TOP_ERROR, domElement);
8121 trapBubbledEvent(TOP_LOAD, domElement);
8122 break;
8123 case 'form':
8124 trapBubbledEvent(TOP_RESET, domElement);
8125 trapBubbledEvent(TOP_SUBMIT, domElement);
8126 break;
8127 case 'details':
8128 trapBubbledEvent(TOP_TOGGLE, domElement);
8129 break;
8130 case 'input':
8131 initWrapperState(domElement, rawProps);
8132 trapBubbledEvent(TOP_INVALID, domElement);
8133 // For controlled components we always need to ensure we're listening
8134 // to onChange. Even if there is no listener.
8135 ensureListeningTo(rootContainerElement, 'onChange');
8136 break;
8137 case 'option':
8138 validateProps(domElement, rawProps);
8139 break;
8140 case 'select':
8141 initWrapperState$1(domElement, rawProps);
8142 trapBubbledEvent(TOP_INVALID, domElement);
8143 // For controlled components we always need to ensure we're listening
8144 // to onChange. Even if there is no listener.
8145 ensureListeningTo(rootContainerElement, 'onChange');
8146 break;
8147 case 'textarea':
8148 initWrapperState$2(domElement, rawProps);
8149 trapBubbledEvent(TOP_INVALID, domElement);
8150 // For controlled components we always need to ensure we're listening
8151 // to onChange. Even if there is no listener.
8152 ensureListeningTo(rootContainerElement, 'onChange');
8153 break;
8154 }
8155
8156 assertValidProps(tag, rawProps);
8157
8158 {
8159 extraAttributeNames = new Set();
8160 var attributes = domElement.attributes;
8161 for (var _i = 0; _i < attributes.length; _i++) {
8162 var name = attributes[_i].name.toLowerCase();
8163 switch (name) {
8164 // Built-in SSR attribute is whitelisted
8165 case 'data-reactroot':
8166 break;
8167 // Controlled attributes are not validated
8168 // TODO: Only ignore them on controlled tags.
8169 case 'value':
8170 break;
8171 case 'checked':
8172 break;
8173 case 'selected':
8174 break;
8175 default:
8176 // Intentionally use the original name.
8177 // See discussion in https://github.com/facebook/react/pull/10676.
8178 extraAttributeNames.add(attributes[_i].name);
8179 }
8180 }
8181 }
8182
8183 var updatePayload = null;
8184 for (var propKey in rawProps) {
8185 if (!rawProps.hasOwnProperty(propKey)) {
8186 continue;
8187 }
8188 var nextProp = rawProps[propKey];
8189 if (propKey === CHILDREN) {
8190 // For text content children we compare against textContent. This
8191 // might match additional HTML that is hidden when we read it using
8192 // textContent. E.g. "foo" will match "f<span>oo</span>" but that still
8193 // satisfies our requirement. Our requirement is not to produce perfect
8194 // HTML and attributes. Ideally we should preserve structure but it's
8195 // ok not to if the visible content is still enough to indicate what
8196 // even listeners these nodes might be wired up to.
8197 // TODO: Warn if there is more than a single textNode as a child.
8198 // TODO: Should we use domElement.firstChild.nodeValue to compare?
8199 if (typeof nextProp === 'string') {
8200 if (domElement.textContent !== nextProp) {
8201 if (true && !suppressHydrationWarning) {
8202 warnForTextDifference(domElement.textContent, nextProp);
8203 }
8204 updatePayload = [CHILDREN, nextProp];
8205 }
8206 } else if (typeof nextProp === 'number') {
8207 if (domElement.textContent !== '' + nextProp) {
8208 if (true && !suppressHydrationWarning) {
8209 warnForTextDifference(domElement.textContent, nextProp);
8210 }
8211 updatePayload = [CHILDREN, '' + nextProp];
8212 }
8213 }
8214 } else if (registrationNameModules.hasOwnProperty(propKey)) {
8215 if (nextProp != null) {
8216 if (true && typeof nextProp !== 'function') {
8217 warnForInvalidEventListener(propKey, nextProp);
8218 }
8219 ensureListeningTo(rootContainerElement, propKey);
8220 }
8221 } else if (true &&
8222 // Convince Flow we've calculated it (it's DEV-only in this method.)
8223 typeof isCustomComponentTag === 'boolean') {
8224 // Validate that the properties correspond to their expected values.
8225 var serverValue = void 0;
8226 var propertyInfo = getPropertyInfo(propKey);
8227 if (suppressHydrationWarning) {
8228 // Don't bother comparing. We're ignoring all these warnings.
8229 } else if (propKey === SUPPRESS_CONTENT_EDITABLE_WARNING || propKey === SUPPRESS_HYDRATION_WARNING$1 ||
8230 // Controlled attributes are not validated
8231 // TODO: Only ignore them on controlled tags.
8232 propKey === 'value' || propKey === 'checked' || propKey === 'selected') {
8233 // Noop
8234 } else if (propKey === DANGEROUSLY_SET_INNER_HTML) {
8235 var serverHTML = domElement.innerHTML;
8236 var nextHtml = nextProp ? nextProp[HTML] : undefined;
8237 var expectedHTML = normalizeHTML(domElement, nextHtml != null ? nextHtml : '');
8238 if (expectedHTML !== serverHTML) {
8239 warnForPropDifference(propKey, serverHTML, expectedHTML);
8240 }
8241 } else if (propKey === STYLE$1) {
8242 // $FlowFixMe - Should be inferred as not undefined.
8243 extraAttributeNames.delete(propKey);
8244
8245 if (canDiffStyleForHydrationWarning) {
8246 var expectedStyle = createDangerousStringForStyles(nextProp);
8247 serverValue = domElement.getAttribute('style');
8248 if (expectedStyle !== serverValue) {
8249 warnForPropDifference(propKey, serverValue, expectedStyle);
8250 }
8251 }
8252 } else if (isCustomComponentTag) {
8253 // $FlowFixMe - Should be inferred as not undefined.
8254 extraAttributeNames.delete(propKey.toLowerCase());
8255 serverValue = getValueForAttribute(domElement, propKey, nextProp);
8256
8257 if (nextProp !== serverValue) {
8258 warnForPropDifference(propKey, serverValue, nextProp);
8259 }
8260 } else if (!shouldIgnoreAttribute(propKey, propertyInfo, isCustomComponentTag) && !shouldRemoveAttribute(propKey, nextProp, propertyInfo, isCustomComponentTag)) {
8261 var isMismatchDueToBadCasing = false;
8262 if (propertyInfo !== null) {
8263 // $FlowFixMe - Should be inferred as not undefined.
8264 extraAttributeNames.delete(propertyInfo.attributeName);
8265 serverValue = getValueForProperty(domElement, propKey, nextProp, propertyInfo);
8266 } else {
8267 var ownNamespace = parentNamespace;
8268 if (ownNamespace === HTML_NAMESPACE) {
8269 ownNamespace = getIntrinsicNamespace(tag);
8270 }
8271 if (ownNamespace === HTML_NAMESPACE) {
8272 // $FlowFixMe - Should be inferred as not undefined.
8273 extraAttributeNames.delete(propKey.toLowerCase());
8274 } else {
8275 var standardName = getPossibleStandardName(propKey);
8276 if (standardName !== null && standardName !== propKey) {
8277 // If an SVG prop is supplied with bad casing, it will
8278 // be successfully parsed from HTML, but will produce a mismatch
8279 // (and would be incorrectly rendered on the client).
8280 // However, we already warn about bad casing elsewhere.
8281 // So we'll skip the misleading extra mismatch warning in this case.
8282 isMismatchDueToBadCasing = true;
8283 // $FlowFixMe - Should be inferred as not undefined.
8284 extraAttributeNames.delete(standardName);
8285 }
8286 // $FlowFixMe - Should be inferred as not undefined.
8287 extraAttributeNames.delete(propKey);
8288 }
8289 serverValue = getValueForAttribute(domElement, propKey, nextProp);
8290 }
8291
8292 if (nextProp !== serverValue && !isMismatchDueToBadCasing) {
8293 warnForPropDifference(propKey, serverValue, nextProp);
8294 }
8295 }
8296 }
8297 }
8298
8299 {
8300 // $FlowFixMe - Should be inferred as not undefined.
8301 if (extraAttributeNames.size > 0 && !suppressHydrationWarning) {
8302 // $FlowFixMe - Should be inferred as not undefined.
8303 warnForExtraAttributes(extraAttributeNames);
8304 }
8305 }
8306
8307 switch (tag) {
8308 case 'input':
8309 // TODO: Make sure we check if this is still unmounted or do any clean
8310 // up necessary since we never stop tracking anymore.
8311 track(domElement);
8312 postMountWrapper(domElement, rawProps, true);
8313 break;
8314 case 'textarea':
8315 // TODO: Make sure we check if this is still unmounted or do any clean
8316 // up necessary since we never stop tracking anymore.
8317 track(domElement);
8318 postMountWrapper$3(domElement, rawProps);
8319 break;
8320 case 'select':
8321 case 'option':
8322 // For input and textarea we current always set the value property at
8323 // post mount to force it to diverge from attributes. However, for
8324 // option and select we don't quite do the same thing and select
8325 // is not resilient to the DOM state changing so we don't do that here.
8326 // TODO: Consider not doing this for input and textarea.
8327 break;
8328 default:
8329 if (typeof rawProps.onClick === 'function') {
8330 // TODO: This cast may not be sound for SVG, MathML or custom elements.
8331 trapClickOnNonInteractiveElement(domElement);
8332 }
8333 break;
8334 }
8335
8336 return updatePayload;
8337}
8338
8339function diffHydratedText(textNode, text) {
8340 var isDifferent = textNode.nodeValue !== text;
8341 return isDifferent;
8342}
8343
8344function warnForUnmatchedText(textNode, text) {
8345 {
8346 warnForTextDifference(textNode.nodeValue, text);
8347 }
8348}
8349
8350function warnForDeletedHydratableElement(parentNode, child) {
8351 {
8352 if (didWarnInvalidHydration) {
8353 return;
8354 }
8355 didWarnInvalidHydration = true;
8356 warningWithoutStack$1(false, 'Did not expect server HTML to contain a <%s> in <%s>.', child.nodeName.toLowerCase(), parentNode.nodeName.toLowerCase());
8357 }
8358}
8359
8360function warnForDeletedHydratableText(parentNode, child) {
8361 {
8362 if (didWarnInvalidHydration) {
8363 return;
8364 }
8365 didWarnInvalidHydration = true;
8366 warningWithoutStack$1(false, 'Did not expect server HTML to contain the text node "%s" in <%s>.', child.nodeValue, parentNode.nodeName.toLowerCase());
8367 }
8368}
8369
8370function warnForInsertedHydratedElement(parentNode, tag, props) {
8371 {
8372 if (didWarnInvalidHydration) {
8373 return;
8374 }
8375 didWarnInvalidHydration = true;
8376 warningWithoutStack$1(false, 'Expected server HTML to contain a matching <%s> in <%s>.', tag, parentNode.nodeName.toLowerCase());
8377 }
8378}
8379
8380function warnForInsertedHydratedText(parentNode, text) {
8381 {
8382 if (text === '') {
8383 // We expect to insert empty text nodes since they're not represented in
8384 // the HTML.
8385 // TODO: Remove this special case if we can just avoid inserting empty
8386 // text nodes.
8387 return;
8388 }
8389 if (didWarnInvalidHydration) {
8390 return;
8391 }
8392 didWarnInvalidHydration = true;
8393 warningWithoutStack$1(false, 'Expected server HTML to contain a matching text node for "%s" in <%s>.', text, parentNode.nodeName.toLowerCase());
8394 }
8395}
8396
8397function restoreControlledState$1(domElement, tag, props) {
8398 switch (tag) {
8399 case 'input':
8400 restoreControlledState(domElement, props);
8401 return;
8402 case 'textarea':
8403 restoreControlledState$3(domElement, props);
8404 return;
8405 case 'select':
8406 restoreControlledState$2(domElement, props);
8407 return;
8408 }
8409}
8410
8411// TODO: direct imports like some-package/src/* are bad. Fix me.
8412var validateDOMNesting = function () {};
8413var updatedAncestorInfo = function () {};
8414
8415{
8416 // This validation code was written based on the HTML5 parsing spec:
8417 // https://html.spec.whatwg.org/multipage/syntax.html#has-an-element-in-scope
8418 //
8419 // Note: this does not catch all invalid nesting, nor does it try to (as it's
8420 // not clear what practical benefit doing so provides); instead, we warn only
8421 // for cases where the parser will give a parse tree differing from what React
8422 // intended. For example, <b><div></div></b> is invalid but we don't warn
8423 // because it still parses correctly; we do warn for other cases like nested
8424 // <p> tags where the beginning of the second element implicitly closes the
8425 // first, causing a confusing mess.
8426
8427 // https://html.spec.whatwg.org/multipage/syntax.html#special
8428 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'];
8429
8430 // https://html.spec.whatwg.org/multipage/syntax.html#has-an-element-in-scope
8431 var inScopeTags = ['applet', 'caption', 'html', 'table', 'td', 'th', 'marquee', 'object', 'template',
8432
8433 // https://html.spec.whatwg.org/multipage/syntax.html#html-integration-point
8434 // TODO: Distinguish by namespace here -- for <title>, including it here
8435 // errs on the side of fewer warnings
8436 'foreignObject', 'desc', 'title'];
8437
8438 // https://html.spec.whatwg.org/multipage/syntax.html#has-an-element-in-button-scope
8439 var buttonScopeTags = inScopeTags.concat(['button']);
8440
8441 // https://html.spec.whatwg.org/multipage/syntax.html#generate-implied-end-tags
8442 var impliedEndTags = ['dd', 'dt', 'li', 'option', 'optgroup', 'p', 'rp', 'rt'];
8443
8444 var emptyAncestorInfo = {
8445 current: null,
8446
8447 formTag: null,
8448 aTagInScope: null,
8449 buttonTagInScope: null,
8450 nobrTagInScope: null,
8451 pTagInButtonScope: null,
8452
8453 listItemTagAutoclosing: null,
8454 dlItemTagAutoclosing: null
8455 };
8456
8457 updatedAncestorInfo = function (oldInfo, tag) {
8458 var ancestorInfo = _assign({}, oldInfo || emptyAncestorInfo);
8459 var info = { tag: tag };
8460
8461 if (inScopeTags.indexOf(tag) !== -1) {
8462 ancestorInfo.aTagInScope = null;
8463 ancestorInfo.buttonTagInScope = null;
8464 ancestorInfo.nobrTagInScope = null;
8465 }
8466 if (buttonScopeTags.indexOf(tag) !== -1) {
8467 ancestorInfo.pTagInButtonScope = null;
8468 }
8469
8470 // See rules for 'li', 'dd', 'dt' start tags in
8471 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inbody
8472 if (specialTags.indexOf(tag) !== -1 && tag !== 'address' && tag !== 'div' && tag !== 'p') {
8473 ancestorInfo.listItemTagAutoclosing = null;
8474 ancestorInfo.dlItemTagAutoclosing = null;
8475 }
8476
8477 ancestorInfo.current = info;
8478
8479 if (tag === 'form') {
8480 ancestorInfo.formTag = info;
8481 }
8482 if (tag === 'a') {
8483 ancestorInfo.aTagInScope = info;
8484 }
8485 if (tag === 'button') {
8486 ancestorInfo.buttonTagInScope = info;
8487 }
8488 if (tag === 'nobr') {
8489 ancestorInfo.nobrTagInScope = info;
8490 }
8491 if (tag === 'p') {
8492 ancestorInfo.pTagInButtonScope = info;
8493 }
8494 if (tag === 'li') {
8495 ancestorInfo.listItemTagAutoclosing = info;
8496 }
8497 if (tag === 'dd' || tag === 'dt') {
8498 ancestorInfo.dlItemTagAutoclosing = info;
8499 }
8500
8501 return ancestorInfo;
8502 };
8503
8504 /**
8505 * Returns whether
8506 */
8507 var isTagValidWithParent = function (tag, parentTag) {
8508 // First, let's check if we're in an unusual parsing mode...
8509 switch (parentTag) {
8510 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inselect
8511 case 'select':
8512 return tag === 'option' || tag === 'optgroup' || tag === '#text';
8513 case 'optgroup':
8514 return tag === 'option' || tag === '#text';
8515 // Strictly speaking, seeing an <option> doesn't mean we're in a <select>
8516 // but
8517 case 'option':
8518 return tag === '#text';
8519 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intd
8520 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-incaption
8521 // No special behavior since these rules fall back to "in body" mode for
8522 // all except special table nodes which cause bad parsing behavior anyway.
8523
8524 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intr
8525 case 'tr':
8526 return tag === 'th' || tag === 'td' || tag === 'style' || tag === 'script' || tag === 'template';
8527 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intbody
8528 case 'tbody':
8529 case 'thead':
8530 case 'tfoot':
8531 return tag === 'tr' || tag === 'style' || tag === 'script' || tag === 'template';
8532 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-incolgroup
8533 case 'colgroup':
8534 return tag === 'col' || tag === 'template';
8535 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intable
8536 case 'table':
8537 return tag === 'caption' || tag === 'colgroup' || tag === 'tbody' || tag === 'tfoot' || tag === 'thead' || tag === 'style' || tag === 'script' || tag === 'template';
8538 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inhead
8539 case 'head':
8540 return tag === 'base' || tag === 'basefont' || tag === 'bgsound' || tag === 'link' || tag === 'meta' || tag === 'title' || tag === 'noscript' || tag === 'noframes' || tag === 'style' || tag === 'script' || tag === 'template';
8541 // https://html.spec.whatwg.org/multipage/semantics.html#the-html-element
8542 case 'html':
8543 return tag === 'head' || tag === 'body';
8544 case '#document':
8545 return tag === 'html';
8546 }
8547
8548 // Probably in the "in body" parsing mode, so we outlaw only tag combos
8549 // where the parsing rules cause implicit opens or closes to be added.
8550 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inbody
8551 switch (tag) {
8552 case 'h1':
8553 case 'h2':
8554 case 'h3':
8555 case 'h4':
8556 case 'h5':
8557 case 'h6':
8558 return parentTag !== 'h1' && parentTag !== 'h2' && parentTag !== 'h3' && parentTag !== 'h4' && parentTag !== 'h5' && parentTag !== 'h6';
8559
8560 case 'rp':
8561 case 'rt':
8562 return impliedEndTags.indexOf(parentTag) === -1;
8563
8564 case 'body':
8565 case 'caption':
8566 case 'col':
8567 case 'colgroup':
8568 case 'frame':
8569 case 'head':
8570 case 'html':
8571 case 'tbody':
8572 case 'td':
8573 case 'tfoot':
8574 case 'th':
8575 case 'thead':
8576 case 'tr':
8577 // These tags are only valid with a few parents that have special child
8578 // parsing rules -- if we're down here, then none of those matched and
8579 // so we allow it only if we don't know what the parent is, as all other
8580 // cases are invalid.
8581 return parentTag == null;
8582 }
8583
8584 return true;
8585 };
8586
8587 /**
8588 * Returns whether
8589 */
8590 var findInvalidAncestorForTag = function (tag, ancestorInfo) {
8591 switch (tag) {
8592 case 'address':
8593 case 'article':
8594 case 'aside':
8595 case 'blockquote':
8596 case 'center':
8597 case 'details':
8598 case 'dialog':
8599 case 'dir':
8600 case 'div':
8601 case 'dl':
8602 case 'fieldset':
8603 case 'figcaption':
8604 case 'figure':
8605 case 'footer':
8606 case 'header':
8607 case 'hgroup':
8608 case 'main':
8609 case 'menu':
8610 case 'nav':
8611 case 'ol':
8612 case 'p':
8613 case 'section':
8614 case 'summary':
8615 case 'ul':
8616 case 'pre':
8617 case 'listing':
8618 case 'table':
8619 case 'hr':
8620 case 'xmp':
8621 case 'h1':
8622 case 'h2':
8623 case 'h3':
8624 case 'h4':
8625 case 'h5':
8626 case 'h6':
8627 return ancestorInfo.pTagInButtonScope;
8628
8629 case 'form':
8630 return ancestorInfo.formTag || ancestorInfo.pTagInButtonScope;
8631
8632 case 'li':
8633 return ancestorInfo.listItemTagAutoclosing;
8634
8635 case 'dd':
8636 case 'dt':
8637 return ancestorInfo.dlItemTagAutoclosing;
8638
8639 case 'button':
8640 return ancestorInfo.buttonTagInScope;
8641
8642 case 'a':
8643 // Spec says something about storing a list of markers, but it sounds
8644 // equivalent to this check.
8645 return ancestorInfo.aTagInScope;
8646
8647 case 'nobr':
8648 return ancestorInfo.nobrTagInScope;
8649 }
8650
8651 return null;
8652 };
8653
8654 var didWarn = {};
8655
8656 validateDOMNesting = function (childTag, childText, ancestorInfo) {
8657 ancestorInfo = ancestorInfo || emptyAncestorInfo;
8658 var parentInfo = ancestorInfo.current;
8659 var parentTag = parentInfo && parentInfo.tag;
8660
8661 if (childText != null) {
8662 !(childTag == null) ? warningWithoutStack$1(false, 'validateDOMNesting: when childText is passed, childTag should be null') : void 0;
8663 childTag = '#text';
8664 }
8665
8666 var invalidParent = isTagValidWithParent(childTag, parentTag) ? null : parentInfo;
8667 var invalidAncestor = invalidParent ? null : findInvalidAncestorForTag(childTag, ancestorInfo);
8668 var invalidParentOrAncestor = invalidParent || invalidAncestor;
8669 if (!invalidParentOrAncestor) {
8670 return;
8671 }
8672
8673 var ancestorTag = invalidParentOrAncestor.tag;
8674 var addendum = getCurrentFiberStackInDev();
8675
8676 var warnKey = !!invalidParent + '|' + childTag + '|' + ancestorTag + '|' + addendum;
8677 if (didWarn[warnKey]) {
8678 return;
8679 }
8680 didWarn[warnKey] = true;
8681
8682 var tagDisplayName = childTag;
8683 var whitespaceInfo = '';
8684 if (childTag === '#text') {
8685 if (/\S/.test(childText)) {
8686 tagDisplayName = 'Text nodes';
8687 } else {
8688 tagDisplayName = 'Whitespace text nodes';
8689 whitespaceInfo = " Make sure you don't have any extra whitespace between tags on " + 'each line of your source code.';
8690 }
8691 } else {
8692 tagDisplayName = '<' + childTag + '>';
8693 }
8694
8695 if (invalidParent) {
8696 var info = '';
8697 if (ancestorTag === 'table' && childTag === 'tr') {
8698 info += ' Add a <tbody> to your code to match the DOM tree generated by ' + 'the browser.';
8699 }
8700 warningWithoutStack$1(false, 'validateDOMNesting(...): %s cannot appear as a child of <%s>.%s%s%s', tagDisplayName, ancestorTag, whitespaceInfo, info, addendum);
8701 } else {
8702 warningWithoutStack$1(false, 'validateDOMNesting(...): %s cannot appear as a descendant of ' + '<%s>.%s', tagDisplayName, ancestorTag, addendum);
8703 }
8704 };
8705}
8706
8707var ReactInternals$1 = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
8708
8709var _ReactInternals$Sched = ReactInternals$1.Scheduler;
8710var unstable_cancelCallback = _ReactInternals$Sched.unstable_cancelCallback;
8711var unstable_now = _ReactInternals$Sched.unstable_now;
8712var unstable_scheduleCallback = _ReactInternals$Sched.unstable_scheduleCallback;
8713var unstable_shouldYield = _ReactInternals$Sched.unstable_shouldYield;
8714var unstable_getFirstCallbackNode = _ReactInternals$Sched.unstable_getFirstCallbackNode;
8715var unstable_continueExecution = _ReactInternals$Sched.unstable_continueExecution;
8716var unstable_pauseExecution = _ReactInternals$Sched.unstable_pauseExecution;
8717
8718// Renderers that don't support persistence
8719// can re-export everything from this module.
8720
8721function shim() {
8722 invariant(false, 'The current renderer does not support persistence. This error is likely caused by a bug in React. Please file an issue.');
8723}
8724
8725// Persistence (when unsupported)
8726var supportsPersistence = false;
8727var cloneInstance = shim;
8728var createContainerChildSet = shim;
8729var appendChildToContainerChildSet = shim;
8730var finalizeContainerChildren = shim;
8731var replaceContainerChildren = shim;
8732var cloneHiddenInstance = shim;
8733var cloneUnhiddenInstance = shim;
8734var createHiddenTextInstance = shim;
8735
8736var SUPPRESS_HYDRATION_WARNING = void 0;
8737{
8738 SUPPRESS_HYDRATION_WARNING = 'suppressHydrationWarning';
8739}
8740
8741var STYLE = 'style';
8742
8743var eventsEnabled = null;
8744var selectionInformation = null;
8745
8746function shouldAutoFocusHostComponent(type, props) {
8747 switch (type) {
8748 case 'button':
8749 case 'input':
8750 case 'select':
8751 case 'textarea':
8752 return !!props.autoFocus;
8753 }
8754 return false;
8755}
8756
8757function getRootHostContext(rootContainerInstance) {
8758 var type = void 0;
8759 var namespace = void 0;
8760 var nodeType = rootContainerInstance.nodeType;
8761 switch (nodeType) {
8762 case DOCUMENT_NODE:
8763 case DOCUMENT_FRAGMENT_NODE:
8764 {
8765 type = nodeType === DOCUMENT_NODE ? '#document' : '#fragment';
8766 var root = rootContainerInstance.documentElement;
8767 namespace = root ? root.namespaceURI : getChildNamespace(null, '');
8768 break;
8769 }
8770 default:
8771 {
8772 var container = nodeType === COMMENT_NODE ? rootContainerInstance.parentNode : rootContainerInstance;
8773 var ownNamespace = container.namespaceURI || null;
8774 type = container.tagName;
8775 namespace = getChildNamespace(ownNamespace, type);
8776 break;
8777 }
8778 }
8779 {
8780 var validatedTag = type.toLowerCase();
8781 var _ancestorInfo = updatedAncestorInfo(null, validatedTag);
8782 return { namespace: namespace, ancestorInfo: _ancestorInfo };
8783 }
8784 return namespace;
8785}
8786
8787function getChildHostContext(parentHostContext, type, rootContainerInstance) {
8788 {
8789 var parentHostContextDev = parentHostContext;
8790 var _namespace = getChildNamespace(parentHostContextDev.namespace, type);
8791 var _ancestorInfo2 = updatedAncestorInfo(parentHostContextDev.ancestorInfo, type);
8792 return { namespace: _namespace, ancestorInfo: _ancestorInfo2 };
8793 }
8794 var parentNamespace = parentHostContext;
8795 return getChildNamespace(parentNamespace, type);
8796}
8797
8798function getPublicInstance(instance) {
8799 return instance;
8800}
8801
8802function prepareForCommit(containerInfo) {
8803 eventsEnabled = isEnabled();
8804 selectionInformation = getSelectionInformation();
8805 setEnabled(false);
8806}
8807
8808function resetAfterCommit(containerInfo) {
8809 restoreSelection(selectionInformation);
8810 selectionInformation = null;
8811 setEnabled(eventsEnabled);
8812 eventsEnabled = null;
8813}
8814
8815function createInstance(type, props, rootContainerInstance, hostContext, internalInstanceHandle) {
8816 var parentNamespace = void 0;
8817 {
8818 // TODO: take namespace into account when validating.
8819 var hostContextDev = hostContext;
8820 validateDOMNesting(type, null, hostContextDev.ancestorInfo);
8821 if (typeof props.children === 'string' || typeof props.children === 'number') {
8822 var string = '' + props.children;
8823 var ownAncestorInfo = updatedAncestorInfo(hostContextDev.ancestorInfo, type);
8824 validateDOMNesting(null, string, ownAncestorInfo);
8825 }
8826 parentNamespace = hostContextDev.namespace;
8827 }
8828 var domElement = createElement(type, props, rootContainerInstance, parentNamespace);
8829 precacheFiberNode(internalInstanceHandle, domElement);
8830 updateFiberProps(domElement, props);
8831 return domElement;
8832}
8833
8834function appendInitialChild(parentInstance, child) {
8835 parentInstance.appendChild(child);
8836}
8837
8838function finalizeInitialChildren(domElement, type, props, rootContainerInstance, hostContext) {
8839 setInitialProperties(domElement, type, props, rootContainerInstance);
8840 return shouldAutoFocusHostComponent(type, props);
8841}
8842
8843function prepareUpdate(domElement, type, oldProps, newProps, rootContainerInstance, hostContext) {
8844 {
8845 var hostContextDev = hostContext;
8846 if (typeof newProps.children !== typeof oldProps.children && (typeof newProps.children === 'string' || typeof newProps.children === 'number')) {
8847 var string = '' + newProps.children;
8848 var ownAncestorInfo = updatedAncestorInfo(hostContextDev.ancestorInfo, type);
8849 validateDOMNesting(null, string, ownAncestorInfo);
8850 }
8851 }
8852 return diffProperties(domElement, type, oldProps, newProps, rootContainerInstance);
8853}
8854
8855function shouldSetTextContent(type, props) {
8856 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;
8857}
8858
8859function shouldDeprioritizeSubtree(type, props) {
8860 return !!props.hidden;
8861}
8862
8863function createTextInstance(text, rootContainerInstance, hostContext, internalInstanceHandle) {
8864 {
8865 var hostContextDev = hostContext;
8866 validateDOMNesting(null, text, hostContextDev.ancestorInfo);
8867 }
8868 var textNode = createTextNode(text, rootContainerInstance);
8869 precacheFiberNode(internalInstanceHandle, textNode);
8870 return textNode;
8871}
8872
8873var isPrimaryRenderer = true;
8874// This initialization code may run even on server environments
8875// if a component just imports ReactDOM (e.g. for findDOMNode).
8876// Some environments might not have setTimeout or clearTimeout.
8877var scheduleTimeout = typeof setTimeout === 'function' ? setTimeout : undefined;
8878var cancelTimeout = typeof clearTimeout === 'function' ? clearTimeout : undefined;
8879var noTimeout = -1;
8880
8881// -------------------
8882// Mutation
8883// -------------------
8884
8885var supportsMutation = true;
8886
8887function commitMount(domElement, type, newProps, internalInstanceHandle) {
8888 // Despite the naming that might imply otherwise, this method only
8889 // fires if there is an `Update` effect scheduled during mounting.
8890 // This happens if `finalizeInitialChildren` returns `true` (which it
8891 // does to implement the `autoFocus` attribute on the client). But
8892 // there are also other cases when this might happen (such as patching
8893 // up text content during hydration mismatch). So we'll check this again.
8894 if (shouldAutoFocusHostComponent(type, newProps)) {
8895 domElement.focus();
8896 }
8897}
8898
8899function commitUpdate(domElement, updatePayload, type, oldProps, newProps, internalInstanceHandle) {
8900 // Update the props handle so that we know which props are the ones with
8901 // with current event handlers.
8902 updateFiberProps(domElement, newProps);
8903 // Apply the diff to the DOM node.
8904 updateProperties(domElement, updatePayload, type, oldProps, newProps);
8905}
8906
8907function resetTextContent(domElement) {
8908 setTextContent(domElement, '');
8909}
8910
8911function commitTextUpdate(textInstance, oldText, newText) {
8912 textInstance.nodeValue = newText;
8913}
8914
8915function appendChild(parentInstance, child) {
8916 parentInstance.appendChild(child);
8917}
8918
8919function appendChildToContainer(container, child) {
8920 var parentNode = void 0;
8921 if (container.nodeType === COMMENT_NODE) {
8922 parentNode = container.parentNode;
8923 parentNode.insertBefore(child, container);
8924 } else {
8925 parentNode = container;
8926 parentNode.appendChild(child);
8927 }
8928 // This container might be used for a portal.
8929 // If something inside a portal is clicked, that click should bubble
8930 // through the React tree. However, on Mobile Safari the click would
8931 // never bubble through the *DOM* tree unless an ancestor with onclick
8932 // event exists. So we wouldn't see it and dispatch it.
8933 // This is why we ensure that non React root containers have inline onclick
8934 // defined.
8935 // https://github.com/facebook/react/issues/11918
8936 var reactRootContainer = container._reactRootContainer;
8937 if ((reactRootContainer === null || reactRootContainer === undefined) && parentNode.onclick === null) {
8938 // TODO: This cast may not be sound for SVG, MathML or custom elements.
8939 trapClickOnNonInteractiveElement(parentNode);
8940 }
8941}
8942
8943function insertBefore(parentInstance, child, beforeChild) {
8944 parentInstance.insertBefore(child, beforeChild);
8945}
8946
8947function insertInContainerBefore(container, child, beforeChild) {
8948 if (container.nodeType === COMMENT_NODE) {
8949 container.parentNode.insertBefore(child, beforeChild);
8950 } else {
8951 container.insertBefore(child, beforeChild);
8952 }
8953}
8954
8955function removeChild(parentInstance, child) {
8956 parentInstance.removeChild(child);
8957}
8958
8959function removeChildFromContainer(container, child) {
8960 if (container.nodeType === COMMENT_NODE) {
8961 container.parentNode.removeChild(child);
8962 } else {
8963 container.removeChild(child);
8964 }
8965}
8966
8967function hideInstance(instance) {
8968 // TODO: Does this work for all element types? What about MathML? Should we
8969 // pass host context to this method?
8970 instance = instance;
8971 instance.style.display = 'none';
8972}
8973
8974function hideTextInstance(textInstance) {
8975 textInstance.nodeValue = '';
8976}
8977
8978function unhideInstance(instance, props) {
8979 instance = instance;
8980 var styleProp = props[STYLE];
8981 var display = styleProp !== undefined && styleProp !== null && styleProp.hasOwnProperty('display') ? styleProp.display : null;
8982 instance.style.display = dangerousStyleValue('display', display);
8983}
8984
8985function unhideTextInstance(textInstance, text) {
8986 textInstance.nodeValue = text;
8987}
8988
8989// -------------------
8990// Hydration
8991// -------------------
8992
8993var supportsHydration = true;
8994
8995function canHydrateInstance(instance, type, props) {
8996 if (instance.nodeType !== ELEMENT_NODE || type.toLowerCase() !== instance.nodeName.toLowerCase()) {
8997 return null;
8998 }
8999 // This has now been refined to an element node.
9000 return instance;
9001}
9002
9003function canHydrateTextInstance(instance, text) {
9004 if (text === '' || instance.nodeType !== TEXT_NODE) {
9005 // Empty strings are not parsed by HTML so there won't be a correct match here.
9006 return null;
9007 }
9008 // This has now been refined to a text node.
9009 return instance;
9010}
9011
9012function getNextHydratableSibling(instance) {
9013 var node = instance.nextSibling;
9014 // Skip non-hydratable nodes.
9015 while (node && node.nodeType !== ELEMENT_NODE && node.nodeType !== TEXT_NODE) {
9016 node = node.nextSibling;
9017 }
9018 return node;
9019}
9020
9021function getFirstHydratableChild(parentInstance) {
9022 var next = parentInstance.firstChild;
9023 // Skip non-hydratable nodes.
9024 while (next && next.nodeType !== ELEMENT_NODE && next.nodeType !== TEXT_NODE) {
9025 next = next.nextSibling;
9026 }
9027 return next;
9028}
9029
9030function hydrateInstance(instance, type, props, rootContainerInstance, hostContext, internalInstanceHandle) {
9031 precacheFiberNode(internalInstanceHandle, instance);
9032 // TODO: Possibly defer this until the commit phase where all the events
9033 // get attached.
9034 updateFiberProps(instance, props);
9035 var parentNamespace = void 0;
9036 {
9037 var hostContextDev = hostContext;
9038 parentNamespace = hostContextDev.namespace;
9039 }
9040 return diffHydratedProperties(instance, type, props, parentNamespace, rootContainerInstance);
9041}
9042
9043function hydrateTextInstance(textInstance, text, internalInstanceHandle) {
9044 precacheFiberNode(internalInstanceHandle, textInstance);
9045 return diffHydratedText(textInstance, text);
9046}
9047
9048function didNotMatchHydratedContainerTextInstance(parentContainer, textInstance, text) {
9049 {
9050 warnForUnmatchedText(textInstance, text);
9051 }
9052}
9053
9054function didNotMatchHydratedTextInstance(parentType, parentProps, parentInstance, textInstance, text) {
9055 if (true && parentProps[SUPPRESS_HYDRATION_WARNING] !== true) {
9056 warnForUnmatchedText(textInstance, text);
9057 }
9058}
9059
9060function didNotHydrateContainerInstance(parentContainer, instance) {
9061 {
9062 if (instance.nodeType === ELEMENT_NODE) {
9063 warnForDeletedHydratableElement(parentContainer, instance);
9064 } else {
9065 warnForDeletedHydratableText(parentContainer, instance);
9066 }
9067 }
9068}
9069
9070function didNotHydrateInstance(parentType, parentProps, parentInstance, instance) {
9071 if (true && parentProps[SUPPRESS_HYDRATION_WARNING] !== true) {
9072 if (instance.nodeType === ELEMENT_NODE) {
9073 warnForDeletedHydratableElement(parentInstance, instance);
9074 } else {
9075 warnForDeletedHydratableText(parentInstance, instance);
9076 }
9077 }
9078}
9079
9080function didNotFindHydratableContainerInstance(parentContainer, type, props) {
9081 {
9082 warnForInsertedHydratedElement(parentContainer, type, props);
9083 }
9084}
9085
9086function didNotFindHydratableContainerTextInstance(parentContainer, text) {
9087 {
9088 warnForInsertedHydratedText(parentContainer, text);
9089 }
9090}
9091
9092function didNotFindHydratableInstance(parentType, parentProps, parentInstance, type, props) {
9093 if (true && parentProps[SUPPRESS_HYDRATION_WARNING] !== true) {
9094 warnForInsertedHydratedElement(parentInstance, type, props);
9095 }
9096}
9097
9098function didNotFindHydratableTextInstance(parentType, parentProps, parentInstance, text) {
9099 if (true && parentProps[SUPPRESS_HYDRATION_WARNING] !== true) {
9100 warnForInsertedHydratedText(parentInstance, text);
9101 }
9102}
9103
9104// This is just to get the setup running.
9105// TODO: real implementation.
9106// console.log('Hello from Fire host config.');
9107
9108// Prefix measurements so that it's possible to filter them.
9109// Longer prefixes are hard to read in DevTools.
9110var reactEmoji = '\u269B';
9111var warningEmoji = '\u26D4';
9112var supportsUserTiming = typeof performance !== 'undefined' && typeof performance.mark === 'function' && typeof performance.clearMarks === 'function' && typeof performance.measure === 'function' && typeof performance.clearMeasures === 'function';
9113
9114// Keep track of current fiber so that we know the path to unwind on pause.
9115// TODO: this looks the same as nextUnitOfWork in scheduler. Can we unify them?
9116var currentFiber = null;
9117// If we're in the middle of user code, which fiber and method is it?
9118// Reusing `currentFiber` would be confusing for this because user code fiber
9119// can change during commit phase too, but we don't need to unwind it (since
9120// lifecycles in the commit phase don't resemble a tree).
9121var currentPhase = null;
9122var currentPhaseFiber = null;
9123// Did lifecycle hook schedule an update? This is often a performance problem,
9124// so we will keep track of it, and include it in the report.
9125// Track commits caused by cascading updates.
9126var isCommitting = false;
9127var hasScheduledUpdateInCurrentCommit = false;
9128var hasScheduledUpdateInCurrentPhase = false;
9129var commitCountInCurrentWorkLoop = 0;
9130var effectCountInCurrentCommit = 0;
9131var isWaitingForCallback = false;
9132// During commits, we only show a measurement once per method name
9133// to avoid stretch the commit phase with measurement overhead.
9134var labelsInCurrentCommit = new Set();
9135
9136var formatMarkName = function (markName) {
9137 return reactEmoji + ' ' + markName;
9138};
9139
9140var formatLabel = function (label, warning) {
9141 var prefix = warning ? warningEmoji + ' ' : reactEmoji + ' ';
9142 var suffix = warning ? ' Warning: ' + warning : '';
9143 return '' + prefix + label + suffix;
9144};
9145
9146var beginMark = function (markName) {
9147 performance.mark(formatMarkName(markName));
9148};
9149
9150var clearMark = function (markName) {
9151 performance.clearMarks(formatMarkName(markName));
9152};
9153
9154var endMark = function (label, markName, warning) {
9155 var formattedMarkName = formatMarkName(markName);
9156 var formattedLabel = formatLabel(label, warning);
9157 try {
9158 performance.measure(formattedLabel, formattedMarkName);
9159 } catch (err) {}
9160 // If previous mark was missing for some reason, this will throw.
9161 // This could only happen if React crashed in an unexpected place earlier.
9162 // Don't pile on with more errors.
9163
9164 // Clear marks immediately to avoid growing buffer.
9165 performance.clearMarks(formattedMarkName);
9166 performance.clearMeasures(formattedLabel);
9167};
9168
9169var getFiberMarkName = function (label, debugID) {
9170 return label + ' (#' + debugID + ')';
9171};
9172
9173var getFiberLabel = function (componentName, isMounted, phase) {
9174 if (phase === null) {
9175 // These are composite component total time measurements.
9176 return componentName + ' [' + (isMounted ? 'update' : 'mount') + ']';
9177 } else {
9178 // Composite component methods.
9179 return componentName + '.' + phase;
9180 }
9181};
9182
9183var beginFiberMark = function (fiber, phase) {
9184 var componentName = getComponentName(fiber.type) || 'Unknown';
9185 var debugID = fiber._debugID;
9186 var isMounted = fiber.alternate !== null;
9187 var label = getFiberLabel(componentName, isMounted, phase);
9188
9189 if (isCommitting && labelsInCurrentCommit.has(label)) {
9190 // During the commit phase, we don't show duplicate labels because
9191 // there is a fixed overhead for every measurement, and we don't
9192 // want to stretch the commit phase beyond necessary.
9193 return false;
9194 }
9195 labelsInCurrentCommit.add(label);
9196
9197 var markName = getFiberMarkName(label, debugID);
9198 beginMark(markName);
9199 return true;
9200};
9201
9202var clearFiberMark = function (fiber, phase) {
9203 var componentName = getComponentName(fiber.type) || 'Unknown';
9204 var debugID = fiber._debugID;
9205 var isMounted = fiber.alternate !== null;
9206 var label = getFiberLabel(componentName, isMounted, phase);
9207 var markName = getFiberMarkName(label, debugID);
9208 clearMark(markName);
9209};
9210
9211var endFiberMark = function (fiber, phase, warning) {
9212 var componentName = getComponentName(fiber.type) || 'Unknown';
9213 var debugID = fiber._debugID;
9214 var isMounted = fiber.alternate !== null;
9215 var label = getFiberLabel(componentName, isMounted, phase);
9216 var markName = getFiberMarkName(label, debugID);
9217 endMark(label, markName, warning);
9218};
9219
9220var shouldIgnoreFiber = function (fiber) {
9221 // Host components should be skipped in the timeline.
9222 // We could check typeof fiber.type, but does this work with RN?
9223 switch (fiber.tag) {
9224 case HostRoot:
9225 case HostComponent:
9226 case HostText:
9227 case HostPortal:
9228 case Fragment:
9229 case ContextProvider:
9230 case ContextConsumer:
9231 case Mode:
9232 return true;
9233 default:
9234 return false;
9235 }
9236};
9237
9238var clearPendingPhaseMeasurement = function () {
9239 if (currentPhase !== null && currentPhaseFiber !== null) {
9240 clearFiberMark(currentPhaseFiber, currentPhase);
9241 }
9242 currentPhaseFiber = null;
9243 currentPhase = null;
9244 hasScheduledUpdateInCurrentPhase = false;
9245};
9246
9247var pauseTimers = function () {
9248 // Stops all currently active measurements so that they can be resumed
9249 // if we continue in a later deferred loop from the same unit of work.
9250 var fiber = currentFiber;
9251 while (fiber) {
9252 if (fiber._debugIsCurrentlyTiming) {
9253 endFiberMark(fiber, null, null);
9254 }
9255 fiber = fiber.return;
9256 }
9257};
9258
9259var resumeTimersRecursively = function (fiber) {
9260 if (fiber.return !== null) {
9261 resumeTimersRecursively(fiber.return);
9262 }
9263 if (fiber._debugIsCurrentlyTiming) {
9264 beginFiberMark(fiber, null);
9265 }
9266};
9267
9268var resumeTimers = function () {
9269 // Resumes all measurements that were active during the last deferred loop.
9270 if (currentFiber !== null) {
9271 resumeTimersRecursively(currentFiber);
9272 }
9273};
9274
9275function recordEffect() {
9276 if (enableUserTimingAPI) {
9277 effectCountInCurrentCommit++;
9278 }
9279}
9280
9281function recordScheduleUpdate() {
9282 if (enableUserTimingAPI) {
9283 if (isCommitting) {
9284 hasScheduledUpdateInCurrentCommit = true;
9285 }
9286 if (currentPhase !== null && currentPhase !== 'componentWillMount' && currentPhase !== 'componentWillReceiveProps') {
9287 hasScheduledUpdateInCurrentPhase = true;
9288 }
9289 }
9290}
9291
9292function startRequestCallbackTimer() {
9293 if (enableUserTimingAPI) {
9294 if (supportsUserTiming && !isWaitingForCallback) {
9295 isWaitingForCallback = true;
9296 beginMark('(Waiting for async callback...)');
9297 }
9298 }
9299}
9300
9301function stopRequestCallbackTimer(didExpire, expirationTime) {
9302 if (enableUserTimingAPI) {
9303 if (supportsUserTiming) {
9304 isWaitingForCallback = false;
9305 var warning = didExpire ? 'React was blocked by main thread' : null;
9306 endMark('(Waiting for async callback... will force flush in ' + expirationTime + ' ms)', '(Waiting for async callback...)', warning);
9307 }
9308 }
9309}
9310
9311function startWorkTimer(fiber) {
9312 if (enableUserTimingAPI) {
9313 if (!supportsUserTiming || shouldIgnoreFiber(fiber)) {
9314 return;
9315 }
9316 // If we pause, this is the fiber to unwind from.
9317 currentFiber = fiber;
9318 if (!beginFiberMark(fiber, null)) {
9319 return;
9320 }
9321 fiber._debugIsCurrentlyTiming = true;
9322 }
9323}
9324
9325function cancelWorkTimer(fiber) {
9326 if (enableUserTimingAPI) {
9327 if (!supportsUserTiming || shouldIgnoreFiber(fiber)) {
9328 return;
9329 }
9330 // Remember we shouldn't complete measurement for this fiber.
9331 // Otherwise flamechart will be deep even for small updates.
9332 fiber._debugIsCurrentlyTiming = false;
9333 clearFiberMark(fiber, null);
9334 }
9335}
9336
9337function stopWorkTimer(fiber) {
9338 if (enableUserTimingAPI) {
9339 if (!supportsUserTiming || shouldIgnoreFiber(fiber)) {
9340 return;
9341 }
9342 // If we pause, its parent is the fiber to unwind from.
9343 currentFiber = fiber.return;
9344 if (!fiber._debugIsCurrentlyTiming) {
9345 return;
9346 }
9347 fiber._debugIsCurrentlyTiming = false;
9348 endFiberMark(fiber, null, null);
9349 }
9350}
9351
9352function stopFailedWorkTimer(fiber) {
9353 if (enableUserTimingAPI) {
9354 if (!supportsUserTiming || shouldIgnoreFiber(fiber)) {
9355 return;
9356 }
9357 // If we pause, its parent is the fiber to unwind from.
9358 currentFiber = fiber.return;
9359 if (!fiber._debugIsCurrentlyTiming) {
9360 return;
9361 }
9362 fiber._debugIsCurrentlyTiming = false;
9363 var warning = fiber.tag === SuspenseComponent ? 'Rendering was suspended' : 'An error was thrown inside this error boundary';
9364 endFiberMark(fiber, null, warning);
9365 }
9366}
9367
9368function startPhaseTimer(fiber, phase) {
9369 if (enableUserTimingAPI) {
9370 if (!supportsUserTiming) {
9371 return;
9372 }
9373 clearPendingPhaseMeasurement();
9374 if (!beginFiberMark(fiber, phase)) {
9375 return;
9376 }
9377 currentPhaseFiber = fiber;
9378 currentPhase = phase;
9379 }
9380}
9381
9382function stopPhaseTimer() {
9383 if (enableUserTimingAPI) {
9384 if (!supportsUserTiming) {
9385 return;
9386 }
9387 if (currentPhase !== null && currentPhaseFiber !== null) {
9388 var warning = hasScheduledUpdateInCurrentPhase ? 'Scheduled a cascading update' : null;
9389 endFiberMark(currentPhaseFiber, currentPhase, warning);
9390 }
9391 currentPhase = null;
9392 currentPhaseFiber = null;
9393 }
9394}
9395
9396function startWorkLoopTimer(nextUnitOfWork) {
9397 if (enableUserTimingAPI) {
9398 currentFiber = nextUnitOfWork;
9399 if (!supportsUserTiming) {
9400 return;
9401 }
9402 commitCountInCurrentWorkLoop = 0;
9403 // This is top level call.
9404 // Any other measurements are performed within.
9405 beginMark('(React Tree Reconciliation)');
9406 // Resume any measurements that were in progress during the last loop.
9407 resumeTimers();
9408 }
9409}
9410
9411function stopWorkLoopTimer(interruptedBy, didCompleteRoot) {
9412 if (enableUserTimingAPI) {
9413 if (!supportsUserTiming) {
9414 return;
9415 }
9416 var warning = null;
9417 if (interruptedBy !== null) {
9418 if (interruptedBy.tag === HostRoot) {
9419 warning = 'A top-level update interrupted the previous render';
9420 } else {
9421 var componentName = getComponentName(interruptedBy.type) || 'Unknown';
9422 warning = 'An update to ' + componentName + ' interrupted the previous render';
9423 }
9424 } else if (commitCountInCurrentWorkLoop > 1) {
9425 warning = 'There were cascading updates';
9426 }
9427 commitCountInCurrentWorkLoop = 0;
9428 var label = didCompleteRoot ? '(React Tree Reconciliation: Completed Root)' : '(React Tree Reconciliation: Yielded)';
9429 // Pause any measurements until the next loop.
9430 pauseTimers();
9431 endMark(label, '(React Tree Reconciliation)', warning);
9432 }
9433}
9434
9435function startCommitTimer() {
9436 if (enableUserTimingAPI) {
9437 if (!supportsUserTiming) {
9438 return;
9439 }
9440 isCommitting = true;
9441 hasScheduledUpdateInCurrentCommit = false;
9442 labelsInCurrentCommit.clear();
9443 beginMark('(Committing Changes)');
9444 }
9445}
9446
9447function stopCommitTimer() {
9448 if (enableUserTimingAPI) {
9449 if (!supportsUserTiming) {
9450 return;
9451 }
9452
9453 var warning = null;
9454 if (hasScheduledUpdateInCurrentCommit) {
9455 warning = 'Lifecycle hook scheduled a cascading update';
9456 } else if (commitCountInCurrentWorkLoop > 0) {
9457 warning = 'Caused by a cascading update in earlier commit';
9458 }
9459 hasScheduledUpdateInCurrentCommit = false;
9460 commitCountInCurrentWorkLoop++;
9461 isCommitting = false;
9462 labelsInCurrentCommit.clear();
9463
9464 endMark('(Committing Changes)', '(Committing Changes)', warning);
9465 }
9466}
9467
9468function startCommitSnapshotEffectsTimer() {
9469 if (enableUserTimingAPI) {
9470 if (!supportsUserTiming) {
9471 return;
9472 }
9473 effectCountInCurrentCommit = 0;
9474 beginMark('(Committing Snapshot Effects)');
9475 }
9476}
9477
9478function stopCommitSnapshotEffectsTimer() {
9479 if (enableUserTimingAPI) {
9480 if (!supportsUserTiming) {
9481 return;
9482 }
9483 var count = effectCountInCurrentCommit;
9484 effectCountInCurrentCommit = 0;
9485 endMark('(Committing Snapshot Effects: ' + count + ' Total)', '(Committing Snapshot Effects)', null);
9486 }
9487}
9488
9489function startCommitHostEffectsTimer() {
9490 if (enableUserTimingAPI) {
9491 if (!supportsUserTiming) {
9492 return;
9493 }
9494 effectCountInCurrentCommit = 0;
9495 beginMark('(Committing Host Effects)');
9496 }
9497}
9498
9499function stopCommitHostEffectsTimer() {
9500 if (enableUserTimingAPI) {
9501 if (!supportsUserTiming) {
9502 return;
9503 }
9504 var count = effectCountInCurrentCommit;
9505 effectCountInCurrentCommit = 0;
9506 endMark('(Committing Host Effects: ' + count + ' Total)', '(Committing Host Effects)', null);
9507 }
9508}
9509
9510function startCommitLifeCyclesTimer() {
9511 if (enableUserTimingAPI) {
9512 if (!supportsUserTiming) {
9513 return;
9514 }
9515 effectCountInCurrentCommit = 0;
9516 beginMark('(Calling Lifecycle Methods)');
9517 }
9518}
9519
9520function stopCommitLifeCyclesTimer() {
9521 if (enableUserTimingAPI) {
9522 if (!supportsUserTiming) {
9523 return;
9524 }
9525 var count = effectCountInCurrentCommit;
9526 effectCountInCurrentCommit = 0;
9527 endMark('(Calling Lifecycle Methods: ' + count + ' Total)', '(Calling Lifecycle Methods)', null);
9528 }
9529}
9530
9531var valueStack = [];
9532
9533var fiberStack = void 0;
9534
9535{
9536 fiberStack = [];
9537}
9538
9539var index = -1;
9540
9541function createCursor(defaultValue) {
9542 return {
9543 current: defaultValue
9544 };
9545}
9546
9547function pop(cursor, fiber) {
9548 if (index < 0) {
9549 {
9550 warningWithoutStack$1(false, 'Unexpected pop.');
9551 }
9552 return;
9553 }
9554
9555 {
9556 if (fiber !== fiberStack[index]) {
9557 warningWithoutStack$1(false, 'Unexpected Fiber popped.');
9558 }
9559 }
9560
9561 cursor.current = valueStack[index];
9562
9563 valueStack[index] = null;
9564
9565 {
9566 fiberStack[index] = null;
9567 }
9568
9569 index--;
9570}
9571
9572function push(cursor, value, fiber) {
9573 index++;
9574
9575 valueStack[index] = cursor.current;
9576
9577 {
9578 fiberStack[index] = fiber;
9579 }
9580
9581 cursor.current = value;
9582}
9583
9584function checkThatStackIsEmpty() {
9585 {
9586 if (index !== -1) {
9587 warningWithoutStack$1(false, 'Expected an empty stack. Something was not reset properly.');
9588 }
9589 }
9590}
9591
9592function resetStackAfterFatalErrorInDev() {
9593 {
9594 index = -1;
9595 valueStack.length = 0;
9596 fiberStack.length = 0;
9597 }
9598}
9599
9600var warnedAboutMissingGetChildContext = void 0;
9601
9602{
9603 warnedAboutMissingGetChildContext = {};
9604}
9605
9606var emptyContextObject = {};
9607{
9608 Object.freeze(emptyContextObject);
9609}
9610
9611// A cursor to the current merged context object on the stack.
9612var contextStackCursor = createCursor(emptyContextObject);
9613// A cursor to a boolean indicating whether the context has changed.
9614var didPerformWorkStackCursor = createCursor(false);
9615// Keep track of the previous context object that was on the stack.
9616// We use this to get access to the parent context after we have already
9617// pushed the next context provider, and now need to merge their contexts.
9618var previousContext = emptyContextObject;
9619
9620function getUnmaskedContext(workInProgress, Component, didPushOwnContextIfProvider) {
9621 if (didPushOwnContextIfProvider && isContextProvider(Component)) {
9622 // If the fiber is a context provider itself, when we read its context
9623 // we may have already pushed its own child context on the stack. A context
9624 // provider should not "see" its own child context. Therefore we read the
9625 // previous (parent) context instead for a context provider.
9626 return previousContext;
9627 }
9628 return contextStackCursor.current;
9629}
9630
9631function cacheContext(workInProgress, unmaskedContext, maskedContext) {
9632 var instance = workInProgress.stateNode;
9633 instance.__reactInternalMemoizedUnmaskedChildContext = unmaskedContext;
9634 instance.__reactInternalMemoizedMaskedChildContext = maskedContext;
9635}
9636
9637function getMaskedContext(workInProgress, unmaskedContext) {
9638 var type = workInProgress.type;
9639 var contextTypes = type.contextTypes;
9640 if (!contextTypes) {
9641 return emptyContextObject;
9642 }
9643
9644 // Avoid recreating masked context unless unmasked context has changed.
9645 // Failing to do this will result in unnecessary calls to componentWillReceiveProps.
9646 // This may trigger infinite loops if componentWillReceiveProps calls setState.
9647 var instance = workInProgress.stateNode;
9648 if (instance && instance.__reactInternalMemoizedUnmaskedChildContext === unmaskedContext) {
9649 return instance.__reactInternalMemoizedMaskedChildContext;
9650 }
9651
9652 var context = {};
9653 for (var key in contextTypes) {
9654 context[key] = unmaskedContext[key];
9655 }
9656
9657 {
9658 var name = getComponentName(type) || 'Unknown';
9659 checkPropTypes_1(contextTypes, context, 'context', name, getCurrentFiberStackInDev);
9660 }
9661
9662 // Cache unmasked context so we can avoid recreating masked context unless necessary.
9663 // Context is created before the class component is instantiated so check for instance.
9664 if (instance) {
9665 cacheContext(workInProgress, unmaskedContext, context);
9666 }
9667
9668 return context;
9669}
9670
9671function hasContextChanged() {
9672 return didPerformWorkStackCursor.current;
9673}
9674
9675function isContextProvider(type) {
9676 var childContextTypes = type.childContextTypes;
9677 return childContextTypes !== null && childContextTypes !== undefined;
9678}
9679
9680function popContext(fiber) {
9681 pop(didPerformWorkStackCursor, fiber);
9682 pop(contextStackCursor, fiber);
9683}
9684
9685function popTopLevelContextObject(fiber) {
9686 pop(didPerformWorkStackCursor, fiber);
9687 pop(contextStackCursor, fiber);
9688}
9689
9690function pushTopLevelContextObject(fiber, context, didChange) {
9691 !(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;
9692
9693 push(contextStackCursor, context, fiber);
9694 push(didPerformWorkStackCursor, didChange, fiber);
9695}
9696
9697function processChildContext(fiber, type, parentContext) {
9698 var instance = fiber.stateNode;
9699 var childContextTypes = type.childContextTypes;
9700
9701 // TODO (bvaughn) Replace this behavior with an invariant() in the future.
9702 // It has only been added in Fiber to match the (unintentional) behavior in Stack.
9703 if (typeof instance.getChildContext !== 'function') {
9704 {
9705 var componentName = getComponentName(type) || 'Unknown';
9706
9707 if (!warnedAboutMissingGetChildContext[componentName]) {
9708 warnedAboutMissingGetChildContext[componentName] = true;
9709 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);
9710 }
9711 }
9712 return parentContext;
9713 }
9714
9715 var childContext = void 0;
9716 {
9717 setCurrentPhase('getChildContext');
9718 }
9719 startPhaseTimer(fiber, 'getChildContext');
9720 childContext = instance.getChildContext();
9721 stopPhaseTimer();
9722 {
9723 setCurrentPhase(null);
9724 }
9725 for (var contextKey in childContext) {
9726 !(contextKey in childContextTypes) ? invariant(false, '%s.getChildContext(): key "%s" is not defined in childContextTypes.', getComponentName(type) || 'Unknown', contextKey) : void 0;
9727 }
9728 {
9729 var name = getComponentName(type) || 'Unknown';
9730 checkPropTypes_1(childContextTypes, childContext, 'child context', name,
9731 // In practice, there is one case in which we won't get a stack. It's when
9732 // somebody calls unstable_renderSubtreeIntoContainer() and we process
9733 // context from the parent component instance. The stack will be missing
9734 // because it's outside of the reconciliation, and so the pointer has not
9735 // been set. This is rare and doesn't matter. We'll also remove that API.
9736 getCurrentFiberStackInDev);
9737 }
9738
9739 return _assign({}, parentContext, childContext);
9740}
9741
9742function pushContextProvider(workInProgress) {
9743 var instance = workInProgress.stateNode;
9744 // We push the context as early as possible to ensure stack integrity.
9745 // If the instance does not exist yet, we will push null at first,
9746 // and replace it on the stack later when invalidating the context.
9747 var memoizedMergedChildContext = instance && instance.__reactInternalMemoizedMergedChildContext || emptyContextObject;
9748
9749 // Remember the parent context so we can merge with it later.
9750 // Inherit the parent's did-perform-work value to avoid inadvertently blocking updates.
9751 previousContext = contextStackCursor.current;
9752 push(contextStackCursor, memoizedMergedChildContext, workInProgress);
9753 push(didPerformWorkStackCursor, didPerformWorkStackCursor.current, workInProgress);
9754
9755 return true;
9756}
9757
9758function invalidateContextProvider(workInProgress, type, didChange) {
9759 var instance = workInProgress.stateNode;
9760 !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;
9761
9762 if (didChange) {
9763 // Merge parent and own context.
9764 // Skip this if we're not updating due to sCU.
9765 // This avoids unnecessarily recomputing memoized values.
9766 var mergedContext = processChildContext(workInProgress, type, previousContext);
9767 instance.__reactInternalMemoizedMergedChildContext = mergedContext;
9768
9769 // Replace the old (or empty) context with the new one.
9770 // It is important to unwind the context in the reverse order.
9771 pop(didPerformWorkStackCursor, workInProgress);
9772 pop(contextStackCursor, workInProgress);
9773 // Now push the new context and mark that it has changed.
9774 push(contextStackCursor, mergedContext, workInProgress);
9775 push(didPerformWorkStackCursor, didChange, workInProgress);
9776 } else {
9777 pop(didPerformWorkStackCursor, workInProgress);
9778 push(didPerformWorkStackCursor, didChange, workInProgress);
9779 }
9780}
9781
9782function findCurrentUnmaskedContext(fiber) {
9783 // Currently this is only used with renderSubtreeIntoContainer; not sure if it
9784 // makes sense elsewhere
9785 !(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;
9786
9787 var node = fiber;
9788 do {
9789 switch (node.tag) {
9790 case HostRoot:
9791 return node.stateNode.context;
9792 case ClassComponent:
9793 {
9794 var Component = node.type;
9795 if (isContextProvider(Component)) {
9796 return node.stateNode.__reactInternalMemoizedMergedChildContext;
9797 }
9798 break;
9799 }
9800 }
9801 node = node.return;
9802 } while (node !== null);
9803 invariant(false, 'Found unexpected detached subtree parent. This error is likely caused by a bug in React. Please file an issue.');
9804}
9805
9806var onCommitFiberRoot = null;
9807var onCommitFiberUnmount = null;
9808var hasLoggedError = false;
9809
9810function catchErrors(fn) {
9811 return function (arg) {
9812 try {
9813 return fn(arg);
9814 } catch (err) {
9815 if (true && !hasLoggedError) {
9816 hasLoggedError = true;
9817 warningWithoutStack$1(false, 'React DevTools encountered an error: %s', err);
9818 }
9819 }
9820 };
9821}
9822
9823var isDevToolsPresent = typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ !== 'undefined';
9824
9825function injectInternals(internals) {
9826 if (typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ === 'undefined') {
9827 // No DevTools
9828 return false;
9829 }
9830 var hook = __REACT_DEVTOOLS_GLOBAL_HOOK__;
9831 if (hook.isDisabled) {
9832 // This isn't a real property on the hook, but it can be set to opt out
9833 // of DevTools integration and associated warnings and logs.
9834 // https://github.com/facebook/react/issues/3877
9835 return true;
9836 }
9837 if (!hook.supportsFiber) {
9838 {
9839 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');
9840 }
9841 // DevTools exists, even though it doesn't support Fiber.
9842 return true;
9843 }
9844 try {
9845 var rendererID = hook.inject(internals);
9846 // We have successfully injected, so now it is safe to set up hooks.
9847 onCommitFiberRoot = catchErrors(function (root) {
9848 return hook.onCommitFiberRoot(rendererID, root);
9849 });
9850 onCommitFiberUnmount = catchErrors(function (fiber) {
9851 return hook.onCommitFiberUnmount(rendererID, fiber);
9852 });
9853 } catch (err) {
9854 // Catch all errors because it is unsafe to throw during initialization.
9855 {
9856 warningWithoutStack$1(false, 'React DevTools encountered an error: %s.', err);
9857 }
9858 }
9859 // DevTools exists
9860 return true;
9861}
9862
9863function onCommitRoot(root) {
9864 if (typeof onCommitFiberRoot === 'function') {
9865 onCommitFiberRoot(root);
9866 }
9867}
9868
9869function onCommitUnmount(fiber) {
9870 if (typeof onCommitFiberUnmount === 'function') {
9871 onCommitFiberUnmount(fiber);
9872 }
9873}
9874
9875// Max 31 bit integer. The max integer size in V8 for 32-bit systems.
9876// Math.pow(2, 30) - 1
9877// 0b111111111111111111111111111111
9878var maxSigned31BitInt = 1073741823;
9879
9880var NoWork = 0;
9881var Never = 1;
9882var Sync = maxSigned31BitInt;
9883
9884var UNIT_SIZE = 10;
9885var MAGIC_NUMBER_OFFSET = maxSigned31BitInt - 1;
9886
9887// 1 unit of expiration time represents 10ms.
9888function msToExpirationTime(ms) {
9889 // Always add an offset so that we don't clash with the magic number for NoWork.
9890 return MAGIC_NUMBER_OFFSET - (ms / UNIT_SIZE | 0);
9891}
9892
9893function expirationTimeToMs(expirationTime) {
9894 return (MAGIC_NUMBER_OFFSET - expirationTime) * UNIT_SIZE;
9895}
9896
9897function ceiling(num, precision) {
9898 return ((num / precision | 0) + 1) * precision;
9899}
9900
9901function computeExpirationBucket(currentTime, expirationInMs, bucketSizeMs) {
9902 return MAGIC_NUMBER_OFFSET - ceiling(MAGIC_NUMBER_OFFSET - currentTime + expirationInMs / UNIT_SIZE, bucketSizeMs / UNIT_SIZE);
9903}
9904
9905var LOW_PRIORITY_EXPIRATION = 5000;
9906var LOW_PRIORITY_BATCH_SIZE = 250;
9907
9908function computeAsyncExpiration(currentTime) {
9909 return computeExpirationBucket(currentTime, LOW_PRIORITY_EXPIRATION, LOW_PRIORITY_BATCH_SIZE);
9910}
9911
9912// We intentionally set a higher expiration time for interactive updates in
9913// dev than in production.
9914//
9915// If the main thread is being blocked so long that you hit the expiration,
9916// it's a problem that could be solved with better scheduling.
9917//
9918// People will be more likely to notice this and fix it with the long
9919// expiration time in development.
9920//
9921// In production we opt for better UX at the risk of masking scheduling
9922// problems, by expiring fast.
9923var HIGH_PRIORITY_EXPIRATION = 500;
9924var HIGH_PRIORITY_BATCH_SIZE = 100;
9925
9926function computeInteractiveExpiration(currentTime) {
9927 return computeExpirationBucket(currentTime, HIGH_PRIORITY_EXPIRATION, HIGH_PRIORITY_BATCH_SIZE);
9928}
9929
9930var NoContext = 0;
9931var ConcurrentMode = 1;
9932var StrictMode = 2;
9933var ProfileMode = 4;
9934
9935var hasBadMapPolyfill = void 0;
9936
9937{
9938 hasBadMapPolyfill = false;
9939 try {
9940 var nonExtensibleObject = Object.preventExtensions({});
9941 var testMap = new Map([[nonExtensibleObject, null]]);
9942 var testSet = new Set([nonExtensibleObject]);
9943 // This is necessary for Rollup to not consider these unused.
9944 // https://github.com/rollup/rollup/issues/1771
9945 // TODO: we can remove these if Rollup fixes the bug.
9946 testMap.set(0, 0);
9947 testSet.add(0);
9948 } catch (e) {
9949 // TODO: Consider warning about bad polyfills
9950 hasBadMapPolyfill = true;
9951 }
9952}
9953
9954// A Fiber is work on a Component that needs to be done or was done. There can
9955// be more than one per component.
9956
9957
9958var debugCounter = void 0;
9959
9960{
9961 debugCounter = 1;
9962}
9963
9964function FiberNode(tag, pendingProps, key, mode) {
9965 // Instance
9966 this.tag = tag;
9967 this.key = key;
9968 this.elementType = null;
9969 this.type = null;
9970 this.stateNode = null;
9971
9972 // Fiber
9973 this.return = null;
9974 this.child = null;
9975 this.sibling = null;
9976 this.index = 0;
9977
9978 this.ref = null;
9979
9980 this.pendingProps = pendingProps;
9981 this.memoizedProps = null;
9982 this.updateQueue = null;
9983 this.memoizedState = null;
9984 this.firstContextDependency = null;
9985
9986 this.mode = mode;
9987
9988 // Effects
9989 this.effectTag = NoEffect;
9990 this.nextEffect = null;
9991
9992 this.firstEffect = null;
9993 this.lastEffect = null;
9994
9995 this.expirationTime = NoWork;
9996 this.childExpirationTime = NoWork;
9997
9998 this.alternate = null;
9999
10000 if (enableProfilerTimer) {
10001 // Note: The following is done to avoid a v8 performance cliff.
10002 //
10003 // Initializing the fields below to smis and later updating them with
10004 // double values will cause Fibers to end up having separate shapes.
10005 // This behavior/bug has something to do with Object.preventExtension().
10006 // Fortunately this only impacts DEV builds.
10007 // Unfortunately it makes React unusably slow for some applications.
10008 // To work around this, initialize the fields below with doubles.
10009 //
10010 // Learn more about this here:
10011 // https://github.com/facebook/react/issues/14365
10012 // https://bugs.chromium.org/p/v8/issues/detail?id=8538
10013 this.actualDuration = Number.NaN;
10014 this.actualStartTime = Number.NaN;
10015 this.selfBaseDuration = Number.NaN;
10016 this.treeBaseDuration = Number.NaN;
10017
10018 // It's okay to replace the initial doubles with smis after initialization.
10019 // This won't trigger the performance cliff mentioned above,
10020 // and it simplifies other profiler code (including DevTools).
10021 this.actualDuration = 0;
10022 this.actualStartTime = -1;
10023 this.selfBaseDuration = 0;
10024 this.treeBaseDuration = 0;
10025 }
10026
10027 {
10028 this._debugID = debugCounter++;
10029 this._debugSource = null;
10030 this._debugOwner = null;
10031 this._debugIsCurrentlyTiming = false;
10032 if (!hasBadMapPolyfill && typeof Object.preventExtensions === 'function') {
10033 Object.preventExtensions(this);
10034 }
10035 }
10036}
10037
10038// This is a constructor function, rather than a POJO constructor, still
10039// please ensure we do the following:
10040// 1) Nobody should add any instance methods on this. Instance methods can be
10041// more difficult to predict when they get optimized and they are almost
10042// never inlined properly in static compilers.
10043// 2) Nobody should rely on `instanceof Fiber` for type testing. We should
10044// always know when it is a fiber.
10045// 3) We might want to experiment with using numeric keys since they are easier
10046// to optimize in a non-JIT environment.
10047// 4) We can easily go from a constructor to a createFiber object literal if that
10048// is faster.
10049// 5) It should be easy to port this to a C struct and keep a C implementation
10050// compatible.
10051var createFiber = function (tag, pendingProps, key, mode) {
10052 // $FlowFixMe: the shapes are exact here but Flow doesn't like constructors
10053 return new FiberNode(tag, pendingProps, key, mode);
10054};
10055
10056function shouldConstruct(Component) {
10057 var prototype = Component.prototype;
10058 return !!(prototype && prototype.isReactComponent);
10059}
10060
10061function isSimpleFunctionComponent(type) {
10062 return typeof type === 'function' && !shouldConstruct(type) && type.defaultProps === undefined;
10063}
10064
10065function resolveLazyComponentTag(Component) {
10066 if (typeof Component === 'function') {
10067 return shouldConstruct(Component) ? ClassComponent : FunctionComponent;
10068 } else if (Component !== undefined && Component !== null) {
10069 var $$typeof = Component.$$typeof;
10070 if ($$typeof === REACT_FORWARD_REF_TYPE) {
10071 return ForwardRef;
10072 }
10073 if ($$typeof === REACT_MEMO_TYPE) {
10074 return MemoComponent;
10075 }
10076 }
10077 return IndeterminateComponent;
10078}
10079
10080// This is used to create an alternate fiber to do work on.
10081function createWorkInProgress(current, pendingProps, expirationTime) {
10082 var workInProgress = current.alternate;
10083 if (workInProgress === null) {
10084 // We use a double buffering pooling technique because we know that we'll
10085 // only ever need at most two versions of a tree. We pool the "other" unused
10086 // node that we're free to reuse. This is lazily created to avoid allocating
10087 // extra objects for things that are never updated. It also allow us to
10088 // reclaim the extra memory if needed.
10089 workInProgress = createFiber(current.tag, pendingProps, current.key, current.mode);
10090 workInProgress.elementType = current.elementType;
10091 workInProgress.type = current.type;
10092 workInProgress.stateNode = current.stateNode;
10093
10094 {
10095 // DEV-only fields
10096 workInProgress._debugID = current._debugID;
10097 workInProgress._debugSource = current._debugSource;
10098 workInProgress._debugOwner = current._debugOwner;
10099 }
10100
10101 workInProgress.alternate = current;
10102 current.alternate = workInProgress;
10103 } else {
10104 workInProgress.pendingProps = pendingProps;
10105
10106 // We already have an alternate.
10107 // Reset the effect tag.
10108 workInProgress.effectTag = NoEffect;
10109
10110 // The effect list is no longer valid.
10111 workInProgress.nextEffect = null;
10112 workInProgress.firstEffect = null;
10113 workInProgress.lastEffect = null;
10114
10115 if (enableProfilerTimer) {
10116 // We intentionally reset, rather than copy, actualDuration & actualStartTime.
10117 // This prevents time from endlessly accumulating in new commits.
10118 // This has the downside of resetting values for different priority renders,
10119 // But works for yielding (the common case) and should support resuming.
10120 workInProgress.actualDuration = 0;
10121 workInProgress.actualStartTime = -1;
10122 }
10123 }
10124
10125 workInProgress.childExpirationTime = current.childExpirationTime;
10126 workInProgress.expirationTime = current.expirationTime;
10127
10128 workInProgress.child = current.child;
10129 workInProgress.memoizedProps = current.memoizedProps;
10130 workInProgress.memoizedState = current.memoizedState;
10131 workInProgress.updateQueue = current.updateQueue;
10132 workInProgress.firstContextDependency = current.firstContextDependency;
10133
10134 // These will be overridden during the parent's reconciliation
10135 workInProgress.sibling = current.sibling;
10136 workInProgress.index = current.index;
10137 workInProgress.ref = current.ref;
10138
10139 if (enableProfilerTimer) {
10140 workInProgress.selfBaseDuration = current.selfBaseDuration;
10141 workInProgress.treeBaseDuration = current.treeBaseDuration;
10142 }
10143
10144 return workInProgress;
10145}
10146
10147function createHostRootFiber(isConcurrent) {
10148 var mode = isConcurrent ? ConcurrentMode | StrictMode : NoContext;
10149
10150 if (enableProfilerTimer && isDevToolsPresent) {
10151 // Always collect profile timings when DevTools are present.
10152 // This enables DevTools to start capturing timing at any point–
10153 // Without some nodes in the tree having empty base times.
10154 mode |= ProfileMode;
10155 }
10156
10157 return createFiber(HostRoot, null, null, mode);
10158}
10159
10160function createFiberFromTypeAndProps(type, // React$ElementType
10161key, pendingProps, owner, mode, expirationTime) {
10162 var fiber = void 0;
10163
10164 var fiberTag = IndeterminateComponent;
10165 // The resolved type is set if we know what the final type will be. I.e. it's not lazy.
10166 var resolvedType = type;
10167 if (typeof type === 'function') {
10168 if (shouldConstruct(type)) {
10169 fiberTag = ClassComponent;
10170 }
10171 } else if (typeof type === 'string') {
10172 fiberTag = HostComponent;
10173 } else {
10174 getTag: switch (type) {
10175 case REACT_FRAGMENT_TYPE:
10176 return createFiberFromFragment(pendingProps.children, mode, expirationTime, key);
10177 case REACT_CONCURRENT_MODE_TYPE:
10178 return createFiberFromMode(pendingProps, mode | ConcurrentMode | StrictMode, expirationTime, key);
10179 case REACT_STRICT_MODE_TYPE:
10180 return createFiberFromMode(pendingProps, mode | StrictMode, expirationTime, key);
10181 case REACT_PROFILER_TYPE:
10182 return createFiberFromProfiler(pendingProps, mode, expirationTime, key);
10183 case REACT_SUSPENSE_TYPE:
10184 return createFiberFromSuspense(pendingProps, mode, expirationTime, key);
10185 default:
10186 {
10187 if (typeof type === 'object' && type !== null) {
10188 switch (type.$$typeof) {
10189 case REACT_PROVIDER_TYPE:
10190 fiberTag = ContextProvider;
10191 break getTag;
10192 case REACT_CONTEXT_TYPE:
10193 // This is a consumer
10194 fiberTag = ContextConsumer;
10195 break getTag;
10196 case REACT_FORWARD_REF_TYPE:
10197 fiberTag = ForwardRef;
10198 break getTag;
10199 case REACT_MEMO_TYPE:
10200 fiberTag = MemoComponent;
10201 break getTag;
10202 case REACT_LAZY_TYPE:
10203 fiberTag = LazyComponent;
10204 resolvedType = null;
10205 break getTag;
10206 }
10207 }
10208 var info = '';
10209 {
10210 if (type === undefined || typeof type === 'object' && type !== null && Object.keys(type).length === 0) {
10211 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.';
10212 }
10213 var ownerName = owner ? getComponentName(owner.type) : null;
10214 if (ownerName) {
10215 info += '\n\nCheck the render method of `' + ownerName + '`.';
10216 }
10217 }
10218 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);
10219 }
10220 }
10221 }
10222
10223 fiber = createFiber(fiberTag, pendingProps, key, mode);
10224 fiber.elementType = type;
10225 fiber.type = resolvedType;
10226 fiber.expirationTime = expirationTime;
10227
10228 return fiber;
10229}
10230
10231function createFiberFromElement(element, mode, expirationTime) {
10232 var owner = null;
10233 {
10234 owner = element._owner;
10235 }
10236 var type = element.type;
10237 var key = element.key;
10238 var pendingProps = element.props;
10239 var fiber = createFiberFromTypeAndProps(type, key, pendingProps, owner, mode, expirationTime);
10240 {
10241 fiber._debugSource = element._source;
10242 fiber._debugOwner = element._owner;
10243 }
10244 return fiber;
10245}
10246
10247function createFiberFromFragment(elements, mode, expirationTime, key) {
10248 var fiber = createFiber(Fragment, elements, key, mode);
10249 fiber.expirationTime = expirationTime;
10250 return fiber;
10251}
10252
10253function createFiberFromProfiler(pendingProps, mode, expirationTime, key) {
10254 {
10255 if (typeof pendingProps.id !== 'string' || typeof pendingProps.onRender !== 'function') {
10256 warningWithoutStack$1(false, 'Profiler must specify an "id" string and "onRender" function as props');
10257 }
10258 }
10259
10260 var fiber = createFiber(Profiler, pendingProps, key, mode | ProfileMode);
10261 // TODO: The Profiler fiber shouldn't have a type. It has a tag.
10262 fiber.elementType = REACT_PROFILER_TYPE;
10263 fiber.type = REACT_PROFILER_TYPE;
10264 fiber.expirationTime = expirationTime;
10265
10266 return fiber;
10267}
10268
10269function createFiberFromMode(pendingProps, mode, expirationTime, key) {
10270 var fiber = createFiber(Mode, pendingProps, key, mode);
10271
10272 // TODO: The Mode fiber shouldn't have a type. It has a tag.
10273 var type = (mode & ConcurrentMode) === NoContext ? REACT_STRICT_MODE_TYPE : REACT_CONCURRENT_MODE_TYPE;
10274 fiber.elementType = type;
10275 fiber.type = type;
10276
10277 fiber.expirationTime = expirationTime;
10278 return fiber;
10279}
10280
10281function createFiberFromSuspense(pendingProps, mode, expirationTime, key) {
10282 var fiber = createFiber(SuspenseComponent, pendingProps, key, mode);
10283
10284 // TODO: The SuspenseComponent fiber shouldn't have a type. It has a tag.
10285 var type = REACT_SUSPENSE_TYPE;
10286 fiber.elementType = type;
10287 fiber.type = type;
10288
10289 fiber.expirationTime = expirationTime;
10290 return fiber;
10291}
10292
10293function createFiberFromText(content, mode, expirationTime) {
10294 var fiber = createFiber(HostText, content, null, mode);
10295 fiber.expirationTime = expirationTime;
10296 return fiber;
10297}
10298
10299function createFiberFromHostInstanceForDeletion() {
10300 var fiber = createFiber(HostComponent, null, null, NoContext);
10301 // TODO: These should not need a type.
10302 fiber.elementType = 'DELETED';
10303 fiber.type = 'DELETED';
10304 return fiber;
10305}
10306
10307function createFiberFromPortal(portal, mode, expirationTime) {
10308 var pendingProps = portal.children !== null ? portal.children : [];
10309 var fiber = createFiber(HostPortal, pendingProps, portal.key, mode);
10310 fiber.expirationTime = expirationTime;
10311 fiber.stateNode = {
10312 containerInfo: portal.containerInfo,
10313 pendingChildren: null, // Used by persistent updates
10314 implementation: portal.implementation
10315 };
10316 return fiber;
10317}
10318
10319// Used for stashing WIP properties to replay failed work in DEV.
10320function assignFiberPropertiesInDEV(target, source) {
10321 if (target === null) {
10322 // This Fiber's initial properties will always be overwritten.
10323 // We only use a Fiber to ensure the same hidden class so DEV isn't slow.
10324 target = createFiber(IndeterminateComponent, null, null, NoContext);
10325 }
10326
10327 // This is intentionally written as a list of all properties.
10328 // We tried to use Object.assign() instead but this is called in
10329 // the hottest path, and Object.assign() was too slow:
10330 // https://github.com/facebook/react/issues/12502
10331 // This code is DEV-only so size is not a concern.
10332
10333 target.tag = source.tag;
10334 target.key = source.key;
10335 target.elementType = source.elementType;
10336 target.type = source.type;
10337 target.stateNode = source.stateNode;
10338 target.return = source.return;
10339 target.child = source.child;
10340 target.sibling = source.sibling;
10341 target.index = source.index;
10342 target.ref = source.ref;
10343 target.pendingProps = source.pendingProps;
10344 target.memoizedProps = source.memoizedProps;
10345 target.updateQueue = source.updateQueue;
10346 target.memoizedState = source.memoizedState;
10347 target.firstContextDependency = source.firstContextDependency;
10348 target.mode = source.mode;
10349 target.effectTag = source.effectTag;
10350 target.nextEffect = source.nextEffect;
10351 target.firstEffect = source.firstEffect;
10352 target.lastEffect = source.lastEffect;
10353 target.expirationTime = source.expirationTime;
10354 target.childExpirationTime = source.childExpirationTime;
10355 target.alternate = source.alternate;
10356 if (enableProfilerTimer) {
10357 target.actualDuration = source.actualDuration;
10358 target.actualStartTime = source.actualStartTime;
10359 target.selfBaseDuration = source.selfBaseDuration;
10360 target.treeBaseDuration = source.treeBaseDuration;
10361 }
10362 target._debugID = source._debugID;
10363 target._debugSource = source._debugSource;
10364 target._debugOwner = source._debugOwner;
10365 target._debugIsCurrentlyTiming = source._debugIsCurrentlyTiming;
10366 return target;
10367}
10368
10369var ReactInternals$2 = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
10370
10371var _ReactInternals$Sched$1 = ReactInternals$2.SchedulerTracing;
10372var __interactionsRef = _ReactInternals$Sched$1.__interactionsRef;
10373var __subscriberRef = _ReactInternals$Sched$1.__subscriberRef;
10374var unstable_clear = _ReactInternals$Sched$1.unstable_clear;
10375var unstable_getCurrent = _ReactInternals$Sched$1.unstable_getCurrent;
10376var unstable_getThreadID = _ReactInternals$Sched$1.unstable_getThreadID;
10377var unstable_subscribe = _ReactInternals$Sched$1.unstable_subscribe;
10378var unstable_trace = _ReactInternals$Sched$1.unstable_trace;
10379var unstable_unsubscribe = _ReactInternals$Sched$1.unstable_unsubscribe;
10380var unstable_wrap = _ReactInternals$Sched$1.unstable_wrap;
10381
10382// TODO: This should be lifted into the renderer.
10383
10384
10385// The following attributes are only used by interaction tracing builds.
10386// They enable interactions to be associated with their async work,
10387// And expose interaction metadata to the React DevTools Profiler plugin.
10388// Note that these attributes are only defined when the enableSchedulerTracing flag is enabled.
10389
10390
10391// Exported FiberRoot type includes all properties,
10392// To avoid requiring potentially error-prone :any casts throughout the project.
10393// Profiling properties are only safe to access in profiling builds (when enableSchedulerTracing is true).
10394// The types are defined separately within this file to ensure they stay in sync.
10395// (We don't have to use an inline :any cast when enableSchedulerTracing is disabled.)
10396
10397
10398function createFiberRoot(containerInfo, isConcurrent, hydrate) {
10399 // Cyclic construction. This cheats the type system right now because
10400 // stateNode is any.
10401 var uninitializedFiber = createHostRootFiber(isConcurrent);
10402
10403 var root = void 0;
10404 if (enableSchedulerTracing) {
10405 root = {
10406 current: uninitializedFiber,
10407 containerInfo: containerInfo,
10408 pendingChildren: null,
10409
10410 earliestPendingTime: NoWork,
10411 latestPendingTime: NoWork,
10412 earliestSuspendedTime: NoWork,
10413 latestSuspendedTime: NoWork,
10414 latestPingedTime: NoWork,
10415
10416 pingCache: null,
10417
10418 didError: false,
10419
10420 pendingCommitExpirationTime: NoWork,
10421 finishedWork: null,
10422 timeoutHandle: noTimeout,
10423 context: null,
10424 pendingContext: null,
10425 hydrate: hydrate,
10426 nextExpirationTimeToWorkOn: NoWork,
10427 expirationTime: NoWork,
10428 firstBatch: null,
10429 nextScheduledRoot: null,
10430
10431 interactionThreadID: unstable_getThreadID(),
10432 memoizedInteractions: new Set(),
10433 pendingInteractionMap: new Map()
10434 };
10435 } else {
10436 root = {
10437 current: uninitializedFiber,
10438 containerInfo: containerInfo,
10439 pendingChildren: null,
10440
10441 pingCache: null,
10442
10443 earliestPendingTime: NoWork,
10444 latestPendingTime: NoWork,
10445 earliestSuspendedTime: NoWork,
10446 latestSuspendedTime: NoWork,
10447 latestPingedTime: NoWork,
10448
10449 didError: false,
10450
10451 pendingCommitExpirationTime: NoWork,
10452 finishedWork: null,
10453 timeoutHandle: noTimeout,
10454 context: null,
10455 pendingContext: null,
10456 hydrate: hydrate,
10457 nextExpirationTimeToWorkOn: NoWork,
10458 expirationTime: NoWork,
10459 firstBatch: null,
10460 nextScheduledRoot: null
10461 };
10462 }
10463
10464 uninitializedFiber.stateNode = root;
10465
10466 // The reason for the way the Flow types are structured in this file,
10467 // Is to avoid needing :any casts everywhere interaction tracing fields are used.
10468 // Unfortunately that requires an :any cast for non-interaction tracing capable builds.
10469 // $FlowFixMe Remove this :any cast and replace it with something better.
10470 return root;
10471}
10472
10473/**
10474 * Forked from fbjs/warning:
10475 * https://github.com/facebook/fbjs/blob/e66ba20ad5be433eb54423f2b097d829324d9de6/packages/fbjs/src/__forks__/warning.js
10476 *
10477 * Only change is we use console.warn instead of console.error,
10478 * and do nothing when 'console' is not supported.
10479 * This really simplifies the code.
10480 * ---
10481 * Similar to invariant but only logs a warning if the condition is not met.
10482 * This can be used to log issues in development environments in critical
10483 * paths. Removing the logging code for production environments will keep the
10484 * same logic and follow the same code paths.
10485 */
10486
10487var lowPriorityWarning = function () {};
10488
10489{
10490 var printWarning$1 = function (format) {
10491 for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
10492 args[_key - 1] = arguments[_key];
10493 }
10494
10495 var argIndex = 0;
10496 var message = 'Warning: ' + format.replace(/%s/g, function () {
10497 return args[argIndex++];
10498 });
10499 if (typeof console !== 'undefined') {
10500 console.warn(message);
10501 }
10502 try {
10503 // --- Welcome to debugging React ---
10504 // This error was thrown as a convenience so that you can use this stack
10505 // to find the callsite that caused this warning to fire.
10506 throw new Error(message);
10507 } catch (x) {}
10508 };
10509
10510 lowPriorityWarning = function (condition, format) {
10511 if (format === undefined) {
10512 throw new Error('`lowPriorityWarning(condition, format, ...args)` requires a warning ' + 'message argument');
10513 }
10514 if (!condition) {
10515 for (var _len2 = arguments.length, args = Array(_len2 > 2 ? _len2 - 2 : 0), _key2 = 2; _key2 < _len2; _key2++) {
10516 args[_key2 - 2] = arguments[_key2];
10517 }
10518
10519 printWarning$1.apply(undefined, [format].concat(args));
10520 }
10521 };
10522}
10523
10524var lowPriorityWarning$1 = lowPriorityWarning;
10525
10526var ReactStrictModeWarnings = {
10527 discardPendingWarnings: function () {},
10528 flushPendingDeprecationWarnings: function () {},
10529 flushPendingUnsafeLifecycleWarnings: function () {},
10530 recordDeprecationWarnings: function (fiber, instance) {},
10531 recordUnsafeLifecycleWarnings: function (fiber, instance) {},
10532 recordLegacyContextWarning: function (fiber, instance) {},
10533 flushLegacyContextWarning: function () {}
10534};
10535
10536{
10537 var LIFECYCLE_SUGGESTIONS = {
10538 UNSAFE_componentWillMount: 'componentDidMount',
10539 UNSAFE_componentWillReceiveProps: 'static getDerivedStateFromProps',
10540 UNSAFE_componentWillUpdate: 'componentDidUpdate'
10541 };
10542
10543 var pendingComponentWillMountWarnings = [];
10544 var pendingComponentWillReceivePropsWarnings = [];
10545 var pendingComponentWillUpdateWarnings = [];
10546 var pendingUnsafeLifecycleWarnings = new Map();
10547 var pendingLegacyContextWarning = new Map();
10548
10549 // Tracks components we have already warned about.
10550 var didWarnAboutDeprecatedLifecycles = new Set();
10551 var didWarnAboutUnsafeLifecycles = new Set();
10552 var didWarnAboutLegacyContext = new Set();
10553
10554 var setToSortedString = function (set) {
10555 var array = [];
10556 set.forEach(function (value) {
10557 array.push(value);
10558 });
10559 return array.sort().join(', ');
10560 };
10561
10562 ReactStrictModeWarnings.discardPendingWarnings = function () {
10563 pendingComponentWillMountWarnings = [];
10564 pendingComponentWillReceivePropsWarnings = [];
10565 pendingComponentWillUpdateWarnings = [];
10566 pendingUnsafeLifecycleWarnings = new Map();
10567 pendingLegacyContextWarning = new Map();
10568 };
10569
10570 ReactStrictModeWarnings.flushPendingUnsafeLifecycleWarnings = function () {
10571 pendingUnsafeLifecycleWarnings.forEach(function (lifecycleWarningsMap, strictRoot) {
10572 var lifecyclesWarningMesages = [];
10573
10574 Object.keys(lifecycleWarningsMap).forEach(function (lifecycle) {
10575 var lifecycleWarnings = lifecycleWarningsMap[lifecycle];
10576 if (lifecycleWarnings.length > 0) {
10577 var componentNames = new Set();
10578 lifecycleWarnings.forEach(function (fiber) {
10579 componentNames.add(getComponentName(fiber.type) || 'Component');
10580 didWarnAboutUnsafeLifecycles.add(fiber.type);
10581 });
10582
10583 var formatted = lifecycle.replace('UNSAFE_', '');
10584 var suggestion = LIFECYCLE_SUGGESTIONS[lifecycle];
10585 var sortedComponentNames = setToSortedString(componentNames);
10586
10587 lifecyclesWarningMesages.push(formatted + ': Please update the following components to use ' + (suggestion + ' instead: ' + sortedComponentNames));
10588 }
10589 });
10590
10591 if (lifecyclesWarningMesages.length > 0) {
10592 var strictRootComponentStack = getStackByFiberInDevAndProd(strictRoot);
10593
10594 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, lifecyclesWarningMesages.join('\n\n'));
10595 }
10596 });
10597
10598 pendingUnsafeLifecycleWarnings = new Map();
10599 };
10600
10601 var findStrictRoot = function (fiber) {
10602 var maybeStrictRoot = null;
10603
10604 var node = fiber;
10605 while (node !== null) {
10606 if (node.mode & StrictMode) {
10607 maybeStrictRoot = node;
10608 }
10609 node = node.return;
10610 }
10611
10612 return maybeStrictRoot;
10613 };
10614
10615 ReactStrictModeWarnings.flushPendingDeprecationWarnings = function () {
10616 if (pendingComponentWillMountWarnings.length > 0) {
10617 var uniqueNames = new Set();
10618 pendingComponentWillMountWarnings.forEach(function (fiber) {
10619 uniqueNames.add(getComponentName(fiber.type) || 'Component');
10620 didWarnAboutDeprecatedLifecycles.add(fiber.type);
10621 });
10622
10623 var sortedNames = setToSortedString(uniqueNames);
10624
10625 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);
10626
10627 pendingComponentWillMountWarnings = [];
10628 }
10629
10630 if (pendingComponentWillReceivePropsWarnings.length > 0) {
10631 var _uniqueNames = new Set();
10632 pendingComponentWillReceivePropsWarnings.forEach(function (fiber) {
10633 _uniqueNames.add(getComponentName(fiber.type) || 'Component');
10634 didWarnAboutDeprecatedLifecycles.add(fiber.type);
10635 });
10636
10637 var _sortedNames = setToSortedString(_uniqueNames);
10638
10639 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);
10640
10641 pendingComponentWillReceivePropsWarnings = [];
10642 }
10643
10644 if (pendingComponentWillUpdateWarnings.length > 0) {
10645 var _uniqueNames2 = new Set();
10646 pendingComponentWillUpdateWarnings.forEach(function (fiber) {
10647 _uniqueNames2.add(getComponentName(fiber.type) || 'Component');
10648 didWarnAboutDeprecatedLifecycles.add(fiber.type);
10649 });
10650
10651 var _sortedNames2 = setToSortedString(_uniqueNames2);
10652
10653 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);
10654
10655 pendingComponentWillUpdateWarnings = [];
10656 }
10657 };
10658
10659 ReactStrictModeWarnings.recordDeprecationWarnings = function (fiber, instance) {
10660 // Dedup strategy: Warn once per component.
10661 if (didWarnAboutDeprecatedLifecycles.has(fiber.type)) {
10662 return;
10663 }
10664
10665 // Don't warn about react-lifecycles-compat polyfilled components.
10666 if (typeof instance.componentWillMount === 'function' && instance.componentWillMount.__suppressDeprecationWarning !== true) {
10667 pendingComponentWillMountWarnings.push(fiber);
10668 }
10669 if (typeof instance.componentWillReceiveProps === 'function' && instance.componentWillReceiveProps.__suppressDeprecationWarning !== true) {
10670 pendingComponentWillReceivePropsWarnings.push(fiber);
10671 }
10672 if (typeof instance.componentWillUpdate === 'function' && instance.componentWillUpdate.__suppressDeprecationWarning !== true) {
10673 pendingComponentWillUpdateWarnings.push(fiber);
10674 }
10675 };
10676
10677 ReactStrictModeWarnings.recordUnsafeLifecycleWarnings = function (fiber, instance) {
10678 var strictRoot = findStrictRoot(fiber);
10679 if (strictRoot === null) {
10680 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.');
10681 return;
10682 }
10683
10684 // Dedup strategy: Warn once per component.
10685 // This is difficult to track any other way since component names
10686 // are often vague and are likely to collide between 3rd party libraries.
10687 // An expand property is probably okay to use here since it's DEV-only,
10688 // and will only be set in the event of serious warnings.
10689 if (didWarnAboutUnsafeLifecycles.has(fiber.type)) {
10690 return;
10691 }
10692
10693 var warningsForRoot = void 0;
10694 if (!pendingUnsafeLifecycleWarnings.has(strictRoot)) {
10695 warningsForRoot = {
10696 UNSAFE_componentWillMount: [],
10697 UNSAFE_componentWillReceiveProps: [],
10698 UNSAFE_componentWillUpdate: []
10699 };
10700
10701 pendingUnsafeLifecycleWarnings.set(strictRoot, warningsForRoot);
10702 } else {
10703 warningsForRoot = pendingUnsafeLifecycleWarnings.get(strictRoot);
10704 }
10705
10706 var unsafeLifecycles = [];
10707 if (typeof instance.componentWillMount === 'function' && instance.componentWillMount.__suppressDeprecationWarning !== true || typeof instance.UNSAFE_componentWillMount === 'function') {
10708 unsafeLifecycles.push('UNSAFE_componentWillMount');
10709 }
10710 if (typeof instance.componentWillReceiveProps === 'function' && instance.componentWillReceiveProps.__suppressDeprecationWarning !== true || typeof instance.UNSAFE_componentWillReceiveProps === 'function') {
10711 unsafeLifecycles.push('UNSAFE_componentWillReceiveProps');
10712 }
10713 if (typeof instance.componentWillUpdate === 'function' && instance.componentWillUpdate.__suppressDeprecationWarning !== true || typeof instance.UNSAFE_componentWillUpdate === 'function') {
10714 unsafeLifecycles.push('UNSAFE_componentWillUpdate');
10715 }
10716
10717 if (unsafeLifecycles.length > 0) {
10718 unsafeLifecycles.forEach(function (lifecycle) {
10719 warningsForRoot[lifecycle].push(fiber);
10720 });
10721 }
10722 };
10723
10724 ReactStrictModeWarnings.recordLegacyContextWarning = function (fiber, instance) {
10725 var strictRoot = findStrictRoot(fiber);
10726 if (strictRoot === null) {
10727 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.');
10728 return;
10729 }
10730
10731 // Dedup strategy: Warn once per component.
10732 if (didWarnAboutLegacyContext.has(fiber.type)) {
10733 return;
10734 }
10735
10736 var warningsForRoot = pendingLegacyContextWarning.get(strictRoot);
10737
10738 if (fiber.type.contextTypes != null || fiber.type.childContextTypes != null || instance !== null && typeof instance.getChildContext === 'function') {
10739 if (warningsForRoot === undefined) {
10740 warningsForRoot = [];
10741 pendingLegacyContextWarning.set(strictRoot, warningsForRoot);
10742 }
10743 warningsForRoot.push(fiber);
10744 }
10745 };
10746
10747 ReactStrictModeWarnings.flushLegacyContextWarning = function () {
10748 pendingLegacyContextWarning.forEach(function (fiberArray, strictRoot) {
10749 var uniqueNames = new Set();
10750 fiberArray.forEach(function (fiber) {
10751 uniqueNames.add(getComponentName(fiber.type) || 'Component');
10752 didWarnAboutLegacyContext.add(fiber.type);
10753 });
10754
10755 var sortedNames = setToSortedString(uniqueNames);
10756 var strictRootComponentStack = getStackByFiberInDevAndProd(strictRoot);
10757
10758 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);
10759 });
10760 };
10761}
10762
10763// This lets us hook into Fiber to debug what it's doing.
10764// See https://github.com/facebook/react/pull/8033.
10765// This is not part of the public API, not even for React DevTools.
10766// You may only inject a debugTool if you work on React Fiber itself.
10767var ReactFiberInstrumentation = {
10768 debugTool: null
10769};
10770
10771var ReactFiberInstrumentation_1 = ReactFiberInstrumentation;
10772
10773// TODO: Offscreen updates should never suspend. However, a promise that
10774// suspended inside an offscreen subtree should be able to ping at the priority
10775// of the outer render.
10776
10777function markPendingPriorityLevel(root, expirationTime) {
10778 // If there's a gap between completing a failed root and retrying it,
10779 // additional updates may be scheduled. Clear `didError`, in case the update
10780 // is sufficient to fix the error.
10781 root.didError = false;
10782
10783 // Update the latest and earliest pending times
10784 var earliestPendingTime = root.earliestPendingTime;
10785 if (earliestPendingTime === NoWork) {
10786 // No other pending updates.
10787 root.earliestPendingTime = root.latestPendingTime = expirationTime;
10788 } else {
10789 if (earliestPendingTime < expirationTime) {
10790 // This is the earliest pending update.
10791 root.earliestPendingTime = expirationTime;
10792 } else {
10793 var latestPendingTime = root.latestPendingTime;
10794 if (latestPendingTime > expirationTime) {
10795 // This is the latest pending update
10796 root.latestPendingTime = expirationTime;
10797 }
10798 }
10799 }
10800 findNextExpirationTimeToWorkOn(expirationTime, root);
10801}
10802
10803function markCommittedPriorityLevels(root, earliestRemainingTime) {
10804 root.didError = false;
10805
10806 if (earliestRemainingTime === NoWork) {
10807 // Fast path. There's no remaining work. Clear everything.
10808 root.earliestPendingTime = NoWork;
10809 root.latestPendingTime = NoWork;
10810 root.earliestSuspendedTime = NoWork;
10811 root.latestSuspendedTime = NoWork;
10812 root.latestPingedTime = NoWork;
10813 findNextExpirationTimeToWorkOn(NoWork, root);
10814 return;
10815 }
10816
10817 if (earliestRemainingTime < root.latestPingedTime) {
10818 root.latestPingedTime = NoWork;
10819 }
10820
10821 // Let's see if the previous latest known pending level was just flushed.
10822 var latestPendingTime = root.latestPendingTime;
10823 if (latestPendingTime !== NoWork) {
10824 if (latestPendingTime > earliestRemainingTime) {
10825 // We've flushed all the known pending levels.
10826 root.earliestPendingTime = root.latestPendingTime = NoWork;
10827 } else {
10828 var earliestPendingTime = root.earliestPendingTime;
10829 if (earliestPendingTime > earliestRemainingTime) {
10830 // We've flushed the earliest known pending level. Set this to the
10831 // latest pending time.
10832 root.earliestPendingTime = root.latestPendingTime;
10833 }
10834 }
10835 }
10836
10837 // Now let's handle the earliest remaining level in the whole tree. We need to
10838 // decide whether to treat it as a pending level or as suspended. Check
10839 // it falls within the range of known suspended levels.
10840
10841 var earliestSuspendedTime = root.earliestSuspendedTime;
10842 if (earliestSuspendedTime === NoWork) {
10843 // There's no suspended work. Treat the earliest remaining level as a
10844 // pending level.
10845 markPendingPriorityLevel(root, earliestRemainingTime);
10846 findNextExpirationTimeToWorkOn(NoWork, root);
10847 return;
10848 }
10849
10850 var latestSuspendedTime = root.latestSuspendedTime;
10851 if (earliestRemainingTime < latestSuspendedTime) {
10852 // The earliest remaining level is later than all the suspended work. That
10853 // means we've flushed all the suspended work.
10854 root.earliestSuspendedTime = NoWork;
10855 root.latestSuspendedTime = NoWork;
10856 root.latestPingedTime = NoWork;
10857
10858 // There's no suspended work. Treat the earliest remaining level as a
10859 // pending level.
10860 markPendingPriorityLevel(root, earliestRemainingTime);
10861 findNextExpirationTimeToWorkOn(NoWork, root);
10862 return;
10863 }
10864
10865 if (earliestRemainingTime > earliestSuspendedTime) {
10866 // The earliest remaining time is earlier than all the suspended work.
10867 // Treat it as a pending update.
10868 markPendingPriorityLevel(root, earliestRemainingTime);
10869 findNextExpirationTimeToWorkOn(NoWork, root);
10870 return;
10871 }
10872
10873 // The earliest remaining time falls within the range of known suspended
10874 // levels. We should treat this as suspended work.
10875 findNextExpirationTimeToWorkOn(NoWork, root);
10876}
10877
10878function hasLowerPriorityWork(root, erroredExpirationTime) {
10879 var latestPendingTime = root.latestPendingTime;
10880 var latestSuspendedTime = root.latestSuspendedTime;
10881 var latestPingedTime = root.latestPingedTime;
10882 return latestPendingTime !== NoWork && latestPendingTime < erroredExpirationTime || latestSuspendedTime !== NoWork && latestSuspendedTime < erroredExpirationTime || latestPingedTime !== NoWork && latestPingedTime < erroredExpirationTime;
10883}
10884
10885function isPriorityLevelSuspended(root, expirationTime) {
10886 var earliestSuspendedTime = root.earliestSuspendedTime;
10887 var latestSuspendedTime = root.latestSuspendedTime;
10888 return earliestSuspendedTime !== NoWork && expirationTime <= earliestSuspendedTime && expirationTime >= latestSuspendedTime;
10889}
10890
10891function markSuspendedPriorityLevel(root, suspendedTime) {
10892 root.didError = false;
10893 clearPing(root, suspendedTime);
10894
10895 // First, check the known pending levels and update them if needed.
10896 var earliestPendingTime = root.earliestPendingTime;
10897 var latestPendingTime = root.latestPendingTime;
10898 if (earliestPendingTime === suspendedTime) {
10899 if (latestPendingTime === suspendedTime) {
10900 // Both known pending levels were suspended. Clear them.
10901 root.earliestPendingTime = root.latestPendingTime = NoWork;
10902 } else {
10903 // The earliest pending level was suspended. Clear by setting it to the
10904 // latest pending level.
10905 root.earliestPendingTime = latestPendingTime;
10906 }
10907 } else if (latestPendingTime === suspendedTime) {
10908 // The latest pending level was suspended. Clear by setting it to the
10909 // latest pending level.
10910 root.latestPendingTime = earliestPendingTime;
10911 }
10912
10913 // Finally, update the known suspended levels.
10914 var earliestSuspendedTime = root.earliestSuspendedTime;
10915 var latestSuspendedTime = root.latestSuspendedTime;
10916 if (earliestSuspendedTime === NoWork) {
10917 // No other suspended levels.
10918 root.earliestSuspendedTime = root.latestSuspendedTime = suspendedTime;
10919 } else {
10920 if (earliestSuspendedTime < suspendedTime) {
10921 // This is the earliest suspended level.
10922 root.earliestSuspendedTime = suspendedTime;
10923 } else if (latestSuspendedTime > suspendedTime) {
10924 // This is the latest suspended level
10925 root.latestSuspendedTime = suspendedTime;
10926 }
10927 }
10928
10929 findNextExpirationTimeToWorkOn(suspendedTime, root);
10930}
10931
10932function markPingedPriorityLevel(root, pingedTime) {
10933 root.didError = false;
10934
10935 // TODO: When we add back resuming, we need to ensure the progressed work
10936 // is thrown out and not reused during the restarted render. One way to
10937 // invalidate the progressed work is to restart at expirationTime + 1.
10938 var latestPingedTime = root.latestPingedTime;
10939 if (latestPingedTime === NoWork || latestPingedTime > pingedTime) {
10940 root.latestPingedTime = pingedTime;
10941 }
10942 findNextExpirationTimeToWorkOn(pingedTime, root);
10943}
10944
10945function clearPing(root, completedTime) {
10946 var latestPingedTime = root.latestPingedTime;
10947 if (latestPingedTime >= completedTime) {
10948 root.latestPingedTime = NoWork;
10949 }
10950}
10951
10952function findEarliestOutstandingPriorityLevel(root, renderExpirationTime) {
10953 var earliestExpirationTime = renderExpirationTime;
10954
10955 var earliestPendingTime = root.earliestPendingTime;
10956 var earliestSuspendedTime = root.earliestSuspendedTime;
10957 if (earliestPendingTime > earliestExpirationTime) {
10958 earliestExpirationTime = earliestPendingTime;
10959 }
10960 if (earliestSuspendedTime > earliestExpirationTime) {
10961 earliestExpirationTime = earliestSuspendedTime;
10962 }
10963 return earliestExpirationTime;
10964}
10965
10966function didExpireAtExpirationTime(root, currentTime) {
10967 var expirationTime = root.expirationTime;
10968 if (expirationTime !== NoWork && currentTime <= expirationTime) {
10969 // The root has expired. Flush all work up to the current time.
10970 root.nextExpirationTimeToWorkOn = currentTime;
10971 }
10972}
10973
10974function findNextExpirationTimeToWorkOn(completedExpirationTime, root) {
10975 var earliestSuspendedTime = root.earliestSuspendedTime;
10976 var latestSuspendedTime = root.latestSuspendedTime;
10977 var earliestPendingTime = root.earliestPendingTime;
10978 var latestPingedTime = root.latestPingedTime;
10979
10980 // Work on the earliest pending time. Failing that, work on the latest
10981 // pinged time.
10982 var nextExpirationTimeToWorkOn = earliestPendingTime !== NoWork ? earliestPendingTime : latestPingedTime;
10983
10984 // If there is no pending or pinged work, check if there's suspended work
10985 // that's lower priority than what we just completed.
10986 if (nextExpirationTimeToWorkOn === NoWork && (completedExpirationTime === NoWork || latestSuspendedTime < completedExpirationTime)) {
10987 // The lowest priority suspended work is the work most likely to be
10988 // committed next. Let's start rendering it again, so that if it times out,
10989 // it's ready to commit.
10990 nextExpirationTimeToWorkOn = latestSuspendedTime;
10991 }
10992
10993 var expirationTime = nextExpirationTimeToWorkOn;
10994 if (expirationTime !== NoWork && earliestSuspendedTime > expirationTime) {
10995 // Expire using the earliest known expiration time.
10996 expirationTime = earliestSuspendedTime;
10997 }
10998
10999 root.nextExpirationTimeToWorkOn = nextExpirationTimeToWorkOn;
11000 root.expirationTime = expirationTime;
11001}
11002
11003// UpdateQueue is a linked list of prioritized updates.
11004//
11005// Like fibers, update queues come in pairs: a current queue, which represents
11006// the visible state of the screen, and a work-in-progress queue, which is
11007// can be mutated and processed asynchronously before it is committed — a form
11008// of double buffering. If a work-in-progress render is discarded before
11009// finishing, we create a new work-in-progress by cloning the current queue.
11010//
11011// Both queues share a persistent, singly-linked list structure. To schedule an
11012// update, we append it to the end of both queues. Each queue maintains a
11013// pointer to first update in the persistent list that hasn't been processed.
11014// The work-in-progress pointer always has a position equal to or greater than
11015// the current queue, since we always work on that one. The current queue's
11016// pointer is only updated during the commit phase, when we swap in the
11017// work-in-progress.
11018//
11019// For example:
11020//
11021// Current pointer: A - B - C - D - E - F
11022// Work-in-progress pointer: D - E - F
11023// ^
11024// The work-in-progress queue has
11025// processed more updates than current.
11026//
11027// The reason we append to both queues is because otherwise we might drop
11028// updates without ever processing them. For example, if we only add updates to
11029// the work-in-progress queue, some updates could be lost whenever a work-in
11030// -progress render restarts by cloning from current. Similarly, if we only add
11031// updates to the current queue, the updates will be lost whenever an already
11032// in-progress queue commits and swaps with the current queue. However, by
11033// adding to both queues, we guarantee that the update will be part of the next
11034// work-in-progress. (And because the work-in-progress queue becomes the
11035// current queue once it commits, there's no danger of applying the same
11036// update twice.)
11037//
11038// Prioritization
11039// --------------
11040//
11041// Updates are not sorted by priority, but by insertion; new updates are always
11042// appended to the end of the list.
11043//
11044// The priority is still important, though. When processing the update queue
11045// during the render phase, only the updates with sufficient priority are
11046// included in the result. If we skip an update because it has insufficient
11047// priority, it remains in the queue to be processed later, during a lower
11048// priority render. Crucially, all updates subsequent to a skipped update also
11049// remain in the queue *regardless of their priority*. That means high priority
11050// updates are sometimes processed twice, at two separate priorities. We also
11051// keep track of a base state, that represents the state before the first
11052// update in the queue is applied.
11053//
11054// For example:
11055//
11056// Given a base state of '', and the following queue of updates
11057//
11058// A1 - B2 - C1 - D2
11059//
11060// where the number indicates the priority, and the update is applied to the
11061// previous state by appending a letter, React will process these updates as
11062// two separate renders, one per distinct priority level:
11063//
11064// First render, at priority 1:
11065// Base state: ''
11066// Updates: [A1, C1]
11067// Result state: 'AC'
11068//
11069// Second render, at priority 2:
11070// Base state: 'A' <- The base state does not include C1,
11071// because B2 was skipped.
11072// Updates: [B2, C1, D2] <- C1 was rebased on top of B2
11073// Result state: 'ABCD'
11074//
11075// Because we process updates in insertion order, and rebase high priority
11076// updates when preceding updates are skipped, the final result is deterministic
11077// regardless of priority. Intermediate state may vary according to system
11078// resources, but the final state is always the same.
11079
11080var UpdateState = 0;
11081var ReplaceState = 1;
11082var ForceUpdate = 2;
11083var CaptureUpdate = 3;
11084
11085// Global state that is reset at the beginning of calling `processUpdateQueue`.
11086// It should only be read right after calling `processUpdateQueue`, via
11087// `checkHasForceUpdateAfterProcessing`.
11088var hasForceUpdate = false;
11089
11090var didWarnUpdateInsideUpdate = void 0;
11091var currentlyProcessingQueue = void 0;
11092var resetCurrentlyProcessingQueue = void 0;
11093{
11094 didWarnUpdateInsideUpdate = false;
11095 currentlyProcessingQueue = null;
11096 resetCurrentlyProcessingQueue = function () {
11097 currentlyProcessingQueue = null;
11098 };
11099}
11100
11101function createUpdateQueue(baseState) {
11102 var queue = {
11103 baseState: baseState,
11104 firstUpdate: null,
11105 lastUpdate: null,
11106 firstCapturedUpdate: null,
11107 lastCapturedUpdate: null,
11108 firstEffect: null,
11109 lastEffect: null,
11110 firstCapturedEffect: null,
11111 lastCapturedEffect: null
11112 };
11113 return queue;
11114}
11115
11116function cloneUpdateQueue(currentQueue) {
11117 var queue = {
11118 baseState: currentQueue.baseState,
11119 firstUpdate: currentQueue.firstUpdate,
11120 lastUpdate: currentQueue.lastUpdate,
11121
11122 // TODO: With resuming, if we bail out and resuse the child tree, we should
11123 // keep these effects.
11124 firstCapturedUpdate: null,
11125 lastCapturedUpdate: null,
11126
11127 firstEffect: null,
11128 lastEffect: null,
11129
11130 firstCapturedEffect: null,
11131 lastCapturedEffect: null
11132 };
11133 return queue;
11134}
11135
11136function createUpdate(expirationTime) {
11137 return {
11138 expirationTime: expirationTime,
11139
11140 tag: UpdateState,
11141 payload: null,
11142 callback: null,
11143
11144 next: null,
11145 nextEffect: null
11146 };
11147}
11148
11149function appendUpdateToQueue(queue, update) {
11150 // Append the update to the end of the list.
11151 if (queue.lastUpdate === null) {
11152 // Queue is empty
11153 queue.firstUpdate = queue.lastUpdate = update;
11154 } else {
11155 queue.lastUpdate.next = update;
11156 queue.lastUpdate = update;
11157 }
11158}
11159
11160function enqueueUpdate(fiber, update) {
11161 // Update queues are created lazily.
11162 var alternate = fiber.alternate;
11163 var queue1 = void 0;
11164 var queue2 = void 0;
11165 if (alternate === null) {
11166 // There's only one fiber.
11167 queue1 = fiber.updateQueue;
11168 queue2 = null;
11169 if (queue1 === null) {
11170 queue1 = fiber.updateQueue = createUpdateQueue(fiber.memoizedState);
11171 }
11172 } else {
11173 // There are two owners.
11174 queue1 = fiber.updateQueue;
11175 queue2 = alternate.updateQueue;
11176 if (queue1 === null) {
11177 if (queue2 === null) {
11178 // Neither fiber has an update queue. Create new ones.
11179 queue1 = fiber.updateQueue = createUpdateQueue(fiber.memoizedState);
11180 queue2 = alternate.updateQueue = createUpdateQueue(alternate.memoizedState);
11181 } else {
11182 // Only one fiber has an update queue. Clone to create a new one.
11183 queue1 = fiber.updateQueue = cloneUpdateQueue(queue2);
11184 }
11185 } else {
11186 if (queue2 === null) {
11187 // Only one fiber has an update queue. Clone to create a new one.
11188 queue2 = alternate.updateQueue = cloneUpdateQueue(queue1);
11189 } else {
11190 // Both owners have an update queue.
11191 }
11192 }
11193 }
11194 if (queue2 === null || queue1 === queue2) {
11195 // There's only a single queue.
11196 appendUpdateToQueue(queue1, update);
11197 } else {
11198 // There are two queues. We need to append the update to both queues,
11199 // while accounting for the persistent structure of the list — we don't
11200 // want the same update to be added multiple times.
11201 if (queue1.lastUpdate === null || queue2.lastUpdate === null) {
11202 // One of the queues is not empty. We must add the update to both queues.
11203 appendUpdateToQueue(queue1, update);
11204 appendUpdateToQueue(queue2, update);
11205 } else {
11206 // Both queues are non-empty. The last update is the same in both lists,
11207 // because of structural sharing. So, only append to one of the lists.
11208 appendUpdateToQueue(queue1, update);
11209 // But we still need to update the `lastUpdate` pointer of queue2.
11210 queue2.lastUpdate = update;
11211 }
11212 }
11213
11214 {
11215 if (fiber.tag === ClassComponent && (currentlyProcessingQueue === queue1 || queue2 !== null && currentlyProcessingQueue === queue2) && !didWarnUpdateInsideUpdate) {
11216 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.');
11217 didWarnUpdateInsideUpdate = true;
11218 }
11219 }
11220}
11221
11222function enqueueCapturedUpdate(workInProgress, update) {
11223 // Captured updates go into a separate list, and only on the work-in-
11224 // progress queue.
11225 var workInProgressQueue = workInProgress.updateQueue;
11226 if (workInProgressQueue === null) {
11227 workInProgressQueue = workInProgress.updateQueue = createUpdateQueue(workInProgress.memoizedState);
11228 } else {
11229 // TODO: I put this here rather than createWorkInProgress so that we don't
11230 // clone the queue unnecessarily. There's probably a better way to
11231 // structure this.
11232 workInProgressQueue = ensureWorkInProgressQueueIsAClone(workInProgress, workInProgressQueue);
11233 }
11234
11235 // Append the update to the end of the list.
11236 if (workInProgressQueue.lastCapturedUpdate === null) {
11237 // This is the first render phase update
11238 workInProgressQueue.firstCapturedUpdate = workInProgressQueue.lastCapturedUpdate = update;
11239 } else {
11240 workInProgressQueue.lastCapturedUpdate.next = update;
11241 workInProgressQueue.lastCapturedUpdate = update;
11242 }
11243}
11244
11245function ensureWorkInProgressQueueIsAClone(workInProgress, queue) {
11246 var current = workInProgress.alternate;
11247 if (current !== null) {
11248 // If the work-in-progress queue is equal to the current queue,
11249 // we need to clone it first.
11250 if (queue === current.updateQueue) {
11251 queue = workInProgress.updateQueue = cloneUpdateQueue(queue);
11252 }
11253 }
11254 return queue;
11255}
11256
11257function getStateFromUpdate(workInProgress, queue, update, prevState, nextProps, instance) {
11258 switch (update.tag) {
11259 case ReplaceState:
11260 {
11261 var _payload = update.payload;
11262 if (typeof _payload === 'function') {
11263 // Updater function
11264 {
11265 if (debugRenderPhaseSideEffects || debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) {
11266 _payload.call(instance, prevState, nextProps);
11267 }
11268 }
11269 return _payload.call(instance, prevState, nextProps);
11270 }
11271 // State object
11272 return _payload;
11273 }
11274 case CaptureUpdate:
11275 {
11276 workInProgress.effectTag = workInProgress.effectTag & ~ShouldCapture | DidCapture;
11277 }
11278 // Intentional fallthrough
11279 case UpdateState:
11280 {
11281 var _payload2 = update.payload;
11282 var partialState = void 0;
11283 if (typeof _payload2 === 'function') {
11284 // Updater function
11285 {
11286 if (debugRenderPhaseSideEffects || debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) {
11287 _payload2.call(instance, prevState, nextProps);
11288 }
11289 }
11290 partialState = _payload2.call(instance, prevState, nextProps);
11291 } else {
11292 // Partial state object
11293 partialState = _payload2;
11294 }
11295 if (partialState === null || partialState === undefined) {
11296 // Null and undefined are treated as no-ops.
11297 return prevState;
11298 }
11299 // Merge the partial state and the previous state.
11300 return _assign({}, prevState, partialState);
11301 }
11302 case ForceUpdate:
11303 {
11304 hasForceUpdate = true;
11305 return prevState;
11306 }
11307 }
11308 return prevState;
11309}
11310
11311function processUpdateQueue(workInProgress, queue, props, instance, renderExpirationTime) {
11312 hasForceUpdate = false;
11313
11314 queue = ensureWorkInProgressQueueIsAClone(workInProgress, queue);
11315
11316 {
11317 currentlyProcessingQueue = queue;
11318 }
11319
11320 // These values may change as we process the queue.
11321 var newBaseState = queue.baseState;
11322 var newFirstUpdate = null;
11323 var newExpirationTime = NoWork;
11324
11325 // Iterate through the list of updates to compute the result.
11326 var update = queue.firstUpdate;
11327 var resultState = newBaseState;
11328 while (update !== null) {
11329 var updateExpirationTime = update.expirationTime;
11330 if (updateExpirationTime < renderExpirationTime) {
11331 // This update does not have sufficient priority. Skip it.
11332 if (newFirstUpdate === null) {
11333 // This is the first skipped update. It will be the first update in
11334 // the new list.
11335 newFirstUpdate = update;
11336 // Since this is the first update that was skipped, the current result
11337 // is the new base state.
11338 newBaseState = resultState;
11339 }
11340 // Since this update will remain in the list, update the remaining
11341 // expiration time.
11342 if (newExpirationTime < updateExpirationTime) {
11343 newExpirationTime = updateExpirationTime;
11344 }
11345 } else {
11346 // This update does have sufficient priority. Process it and compute
11347 // a new result.
11348 resultState = getStateFromUpdate(workInProgress, queue, update, resultState, props, instance);
11349 var _callback = update.callback;
11350 if (_callback !== null) {
11351 workInProgress.effectTag |= Callback;
11352 // Set this to null, in case it was mutated during an aborted render.
11353 update.nextEffect = null;
11354 if (queue.lastEffect === null) {
11355 queue.firstEffect = queue.lastEffect = update;
11356 } else {
11357 queue.lastEffect.nextEffect = update;
11358 queue.lastEffect = update;
11359 }
11360 }
11361 }
11362 // Continue to the next update.
11363 update = update.next;
11364 }
11365
11366 // Separately, iterate though the list of captured updates.
11367 var newFirstCapturedUpdate = null;
11368 update = queue.firstCapturedUpdate;
11369 while (update !== null) {
11370 var _updateExpirationTime = update.expirationTime;
11371 if (_updateExpirationTime < renderExpirationTime) {
11372 // This update does not have sufficient priority. Skip it.
11373 if (newFirstCapturedUpdate === null) {
11374 // This is the first skipped captured update. It will be the first
11375 // update in the new list.
11376 newFirstCapturedUpdate = update;
11377 // If this is the first update that was skipped, the current result is
11378 // the new base state.
11379 if (newFirstUpdate === null) {
11380 newBaseState = resultState;
11381 }
11382 }
11383 // Since this update will remain in the list, update the remaining
11384 // expiration time.
11385 if (newExpirationTime < _updateExpirationTime) {
11386 newExpirationTime = _updateExpirationTime;
11387 }
11388 } else {
11389 // This update does have sufficient priority. Process it and compute
11390 // a new result.
11391 resultState = getStateFromUpdate(workInProgress, queue, update, resultState, props, instance);
11392 var _callback2 = update.callback;
11393 if (_callback2 !== null) {
11394 workInProgress.effectTag |= Callback;
11395 // Set this to null, in case it was mutated during an aborted render.
11396 update.nextEffect = null;
11397 if (queue.lastCapturedEffect === null) {
11398 queue.firstCapturedEffect = queue.lastCapturedEffect = update;
11399 } else {
11400 queue.lastCapturedEffect.nextEffect = update;
11401 queue.lastCapturedEffect = update;
11402 }
11403 }
11404 }
11405 update = update.next;
11406 }
11407
11408 if (newFirstUpdate === null) {
11409 queue.lastUpdate = null;
11410 }
11411 if (newFirstCapturedUpdate === null) {
11412 queue.lastCapturedUpdate = null;
11413 } else {
11414 workInProgress.effectTag |= Callback;
11415 }
11416 if (newFirstUpdate === null && newFirstCapturedUpdate === null) {
11417 // We processed every update, without skipping. That means the new base
11418 // state is the same as the result state.
11419 newBaseState = resultState;
11420 }
11421
11422 queue.baseState = newBaseState;
11423 queue.firstUpdate = newFirstUpdate;
11424 queue.firstCapturedUpdate = newFirstCapturedUpdate;
11425
11426 // Set the remaining expiration time to be whatever is remaining in the queue.
11427 // This should be fine because the only two other things that contribute to
11428 // expiration time are props and context. We're already in the middle of the
11429 // begin phase by the time we start processing the queue, so we've already
11430 // dealt with the props. Context in components that specify
11431 // shouldComponentUpdate is tricky; but we'll have to account for
11432 // that regardless.
11433 workInProgress.expirationTime = newExpirationTime;
11434 workInProgress.memoizedState = resultState;
11435
11436 {
11437 currentlyProcessingQueue = null;
11438 }
11439}
11440
11441function callCallback(callback, context) {
11442 !(typeof callback === 'function') ? invariant(false, 'Invalid argument passed as callback. Expected a function. Instead received: %s', callback) : void 0;
11443 callback.call(context);
11444}
11445
11446function resetHasForceUpdateBeforeProcessing() {
11447 hasForceUpdate = false;
11448}
11449
11450function checkHasForceUpdateAfterProcessing() {
11451 return hasForceUpdate;
11452}
11453
11454function commitUpdateQueue(finishedWork, finishedQueue, instance, renderExpirationTime) {
11455 // If the finished render included captured updates, and there are still
11456 // lower priority updates left over, we need to keep the captured updates
11457 // in the queue so that they are rebased and not dropped once we process the
11458 // queue again at the lower priority.
11459 if (finishedQueue.firstCapturedUpdate !== null) {
11460 // Join the captured update list to the end of the normal list.
11461 if (finishedQueue.lastUpdate !== null) {
11462 finishedQueue.lastUpdate.next = finishedQueue.firstCapturedUpdate;
11463 finishedQueue.lastUpdate = finishedQueue.lastCapturedUpdate;
11464 }
11465 // Clear the list of captured updates.
11466 finishedQueue.firstCapturedUpdate = finishedQueue.lastCapturedUpdate = null;
11467 }
11468
11469 // Commit the effects
11470 commitUpdateEffects(finishedQueue.firstEffect, instance);
11471 finishedQueue.firstEffect = finishedQueue.lastEffect = null;
11472
11473 commitUpdateEffects(finishedQueue.firstCapturedEffect, instance);
11474 finishedQueue.firstCapturedEffect = finishedQueue.lastCapturedEffect = null;
11475}
11476
11477function commitUpdateEffects(effect, instance) {
11478 while (effect !== null) {
11479 var _callback3 = effect.callback;
11480 if (_callback3 !== null) {
11481 effect.callback = null;
11482 callCallback(_callback3, instance);
11483 }
11484 effect = effect.nextEffect;
11485 }
11486}
11487
11488function createCapturedValue(value, source) {
11489 // If the value is an error, call this function immediately after it is thrown
11490 // so the stack is accurate.
11491 return {
11492 value: value,
11493 source: source,
11494 stack: getStackByFiberInDevAndProd(source)
11495 };
11496}
11497
11498var valueCursor = createCursor(null);
11499
11500var rendererSigil = void 0;
11501{
11502 // Use this to detect multiple renderers using the same context
11503 rendererSigil = {};
11504}
11505
11506var currentlyRenderingFiber = null;
11507var lastContextDependency = null;
11508var lastContextWithAllBitsObserved = null;
11509
11510function resetContextDependences() {
11511 // This is called right before React yields execution, to ensure `readContext`
11512 // cannot be called outside the render phase.
11513 currentlyRenderingFiber = null;
11514 lastContextDependency = null;
11515 lastContextWithAllBitsObserved = null;
11516}
11517
11518function pushProvider(providerFiber, nextValue) {
11519 var context = providerFiber.type._context;
11520
11521 if (isPrimaryRenderer) {
11522 push(valueCursor, context._currentValue, providerFiber);
11523
11524 context._currentValue = nextValue;
11525 {
11526 !(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;
11527 context._currentRenderer = rendererSigil;
11528 }
11529 } else {
11530 push(valueCursor, context._currentValue2, providerFiber);
11531
11532 context._currentValue2 = nextValue;
11533 {
11534 !(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;
11535 context._currentRenderer2 = rendererSigil;
11536 }
11537 }
11538}
11539
11540function popProvider(providerFiber) {
11541 var currentValue = valueCursor.current;
11542
11543 pop(valueCursor, providerFiber);
11544
11545 var context = providerFiber.type._context;
11546 if (isPrimaryRenderer) {
11547 context._currentValue = currentValue;
11548 } else {
11549 context._currentValue2 = currentValue;
11550 }
11551}
11552
11553function calculateChangedBits(context, newValue, oldValue) {
11554 // Use Object.is to compare the new context value to the old value. Inlined
11555 // Object.is polyfill.
11556 // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is
11557 if (oldValue === newValue && (oldValue !== 0 || 1 / oldValue === 1 / newValue) || oldValue !== oldValue && newValue !== newValue // eslint-disable-line no-self-compare
11558 ) {
11559 // No change
11560 return 0;
11561 } else {
11562 var changedBits = typeof context._calculateChangedBits === 'function' ? context._calculateChangedBits(oldValue, newValue) : maxSigned31BitInt;
11563
11564 {
11565 !((changedBits & maxSigned31BitInt) === changedBits) ? warning$1(false, 'calculateChangedBits: Expected the return value to be a ' + '31-bit integer. Instead received: %s', changedBits) : void 0;
11566 }
11567 return changedBits | 0;
11568 }
11569}
11570
11571function propagateContextChange(workInProgress, context, changedBits, renderExpirationTime) {
11572 var fiber = workInProgress.child;
11573 if (fiber !== null) {
11574 // Set the return pointer of the child to the work-in-progress fiber.
11575 fiber.return = workInProgress;
11576 }
11577 while (fiber !== null) {
11578 var nextFiber = void 0;
11579
11580 // Visit this fiber.
11581 var dependency = fiber.firstContextDependency;
11582 if (dependency !== null) {
11583 do {
11584 // Check if the context matches.
11585 if (dependency.context === context && (dependency.observedBits & changedBits) !== 0) {
11586 // Match! Schedule an update on this fiber.
11587
11588 if (fiber.tag === ClassComponent) {
11589 // Schedule a force update on the work-in-progress.
11590 var update = createUpdate(renderExpirationTime);
11591 update.tag = ForceUpdate;
11592 // TODO: Because we don't have a work-in-progress, this will add the
11593 // update to the current fiber, too, which means it will persist even if
11594 // this render is thrown away. Since it's a race condition, not sure it's
11595 // worth fixing.
11596 enqueueUpdate(fiber, update);
11597 }
11598
11599 if (fiber.expirationTime < renderExpirationTime) {
11600 fiber.expirationTime = renderExpirationTime;
11601 }
11602 var alternate = fiber.alternate;
11603 if (alternate !== null && alternate.expirationTime < renderExpirationTime) {
11604 alternate.expirationTime = renderExpirationTime;
11605 }
11606 // Update the child expiration time of all the ancestors, including
11607 // the alternates.
11608 var node = fiber.return;
11609 while (node !== null) {
11610 alternate = node.alternate;
11611 if (node.childExpirationTime < renderExpirationTime) {
11612 node.childExpirationTime = renderExpirationTime;
11613 if (alternate !== null && alternate.childExpirationTime < renderExpirationTime) {
11614 alternate.childExpirationTime = renderExpirationTime;
11615 }
11616 } else if (alternate !== null && alternate.childExpirationTime < renderExpirationTime) {
11617 alternate.childExpirationTime = renderExpirationTime;
11618 } else {
11619 // Neither alternate was updated, which means the rest of the
11620 // ancestor path already has sufficient priority.
11621 break;
11622 }
11623 node = node.return;
11624 }
11625 }
11626 nextFiber = fiber.child;
11627 dependency = dependency.next;
11628 } while (dependency !== null);
11629 } else if (fiber.tag === ContextProvider) {
11630 // Don't scan deeper if this is a matching provider
11631 nextFiber = fiber.type === workInProgress.type ? null : fiber.child;
11632 } else {
11633 // Traverse down.
11634 nextFiber = fiber.child;
11635 }
11636
11637 if (nextFiber !== null) {
11638 // Set the return pointer of the child to the work-in-progress fiber.
11639 nextFiber.return = fiber;
11640 } else {
11641 // No child. Traverse to next sibling.
11642 nextFiber = fiber;
11643 while (nextFiber !== null) {
11644 if (nextFiber === workInProgress) {
11645 // We're back to the root of this subtree. Exit.
11646 nextFiber = null;
11647 break;
11648 }
11649 var sibling = nextFiber.sibling;
11650 if (sibling !== null) {
11651 // Set the return pointer of the sibling to the work-in-progress fiber.
11652 sibling.return = nextFiber.return;
11653 nextFiber = sibling;
11654 break;
11655 }
11656 // No more siblings. Traverse up.
11657 nextFiber = nextFiber.return;
11658 }
11659 }
11660 fiber = nextFiber;
11661 }
11662}
11663
11664function prepareToReadContext(workInProgress, renderExpirationTime) {
11665 currentlyRenderingFiber = workInProgress;
11666 lastContextDependency = null;
11667 lastContextWithAllBitsObserved = null;
11668
11669 // Reset the work-in-progress list
11670 workInProgress.firstContextDependency = null;
11671}
11672
11673function readContext(context, observedBits) {
11674 if (lastContextWithAllBitsObserved === context) {
11675 // Nothing to do. We already observe everything in this context.
11676 } else if (observedBits === false || observedBits === 0) {
11677 // Do not observe any updates.
11678 } else {
11679 var resolvedObservedBits = void 0; // Avoid deopting on observable arguments or heterogeneous types.
11680 if (typeof observedBits !== 'number' || observedBits === maxSigned31BitInt) {
11681 // Observe all updates.
11682 lastContextWithAllBitsObserved = context;
11683 resolvedObservedBits = maxSigned31BitInt;
11684 } else {
11685 resolvedObservedBits = observedBits;
11686 }
11687
11688 var contextItem = {
11689 context: context,
11690 observedBits: resolvedObservedBits,
11691 next: null
11692 };
11693
11694 if (lastContextDependency === null) {
11695 !(currentlyRenderingFiber !== null) ? invariant(false, 'Context can only be read while React is rendering, e.g. inside the render method or getDerivedStateFromProps.') : void 0;
11696 // This is the first dependency in the list
11697 currentlyRenderingFiber.firstContextDependency = lastContextDependency = contextItem;
11698 } else {
11699 // Append a new context item.
11700 lastContextDependency = lastContextDependency.next = contextItem;
11701 }
11702 }
11703 return isPrimaryRenderer ? context._currentValue : context._currentValue2;
11704}
11705
11706var NoEffect$1 = /* */0;
11707var UnmountSnapshot = /* */2;
11708var UnmountMutation = /* */4;
11709var MountMutation = /* */8;
11710var UnmountLayout = /* */16;
11711var MountLayout = /* */32;
11712var MountPassive = /* */64;
11713var UnmountPassive = /* */128;
11714
11715function areHookInputsEqual(arr1, arr2) {
11716 // Don't bother comparing lengths in prod because these arrays should be
11717 // passed inline.
11718 {
11719 !(arr1.length === arr2.length) ? warning$1(false, 'Detected a variable number of hook dependencies. The length of the ' + 'dependencies array should be constant between renders.\n\n' + 'Previous: %s\n' + 'Incoming: %s', arr1.join(', '), arr2.join(', ')) : void 0;
11720 }
11721 for (var i = 0; i < arr1.length; i++) {
11722 // Inlined Object.is polyfill.
11723 // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is
11724 var val1 = arr1[i];
11725 var val2 = arr2[i];
11726 if (val1 === val2 && (val1 !== 0 || 1 / val1 === 1 / val2) || val1 !== val1 && val2 !== val2 // eslint-disable-line no-self-compare
11727 ) {
11728 continue;
11729 }
11730 return false;
11731 }
11732 return true;
11733}
11734
11735// These are set right before calling the component.
11736var renderExpirationTime = NoWork;
11737// The work-in-progress fiber. I've named it differently to distinguish it from
11738// the work-in-progress hook.
11739var currentlyRenderingFiber$1 = null;
11740
11741// Hooks are stored as a linked list on the fiber's memoizedState field. The
11742// current hook list is the list that belongs to the current fiber. The
11743// work-in-progress hook list is a new list that will be added to the
11744// work-in-progress fiber.
11745var firstCurrentHook = null;
11746var currentHook = null;
11747var firstWorkInProgressHook = null;
11748var workInProgressHook = null;
11749
11750var remainingExpirationTime = NoWork;
11751var componentUpdateQueue = null;
11752
11753// Updates scheduled during render will trigger an immediate re-render at the
11754// end of the current pass. We can't store these updates on the normal queue,
11755// because if the work is aborted, they should be discarded. Because this is
11756// a relatively rare case, we also don't want to add an additional field to
11757// either the hook or queue object types. So we store them in a lazily create
11758// map of queue -> render-phase updates, which are discarded once the component
11759// completes without re-rendering.
11760
11761// Whether the work-in-progress hook is a re-rendered hook
11762var isReRender = false;
11763// Whether an update was scheduled during the currently executing render pass.
11764var didScheduleRenderPhaseUpdate = false;
11765// Lazily created map of render-phase updates
11766var renderPhaseUpdates = null;
11767// Counter to prevent infinite loops.
11768var numberOfReRenders = 0;
11769var RE_RENDER_LIMIT = 25;
11770
11771function resolveCurrentlyRenderingFiber() {
11772 !(currentlyRenderingFiber$1 !== null) ? invariant(false, 'Hooks can only be called inside the body of a function component.') : void 0;
11773 return currentlyRenderingFiber$1;
11774}
11775
11776function prepareToUseHooks(current, workInProgress, nextRenderExpirationTime) {
11777 if (!enableHooks) {
11778 return;
11779 }
11780 renderExpirationTime = nextRenderExpirationTime;
11781 currentlyRenderingFiber$1 = workInProgress;
11782 firstCurrentHook = current !== null ? current.memoizedState : null;
11783
11784 // The following should have already been reset
11785 // currentHook = null;
11786 // workInProgressHook = null;
11787
11788 // remainingExpirationTime = NoWork;
11789 // componentUpdateQueue = null;
11790
11791 // isReRender = false;
11792 // didScheduleRenderPhaseUpdate = false;
11793 // renderPhaseUpdates = null;
11794 // numberOfReRenders = 0;
11795}
11796
11797function finishHooks(Component, props, children, refOrContext) {
11798 if (!enableHooks) {
11799 return children;
11800 }
11801
11802 // This must be called after every function component to prevent hooks from
11803 // being used in classes.
11804
11805 while (didScheduleRenderPhaseUpdate) {
11806 // Updates were scheduled during the render phase. They are stored in
11807 // the `renderPhaseUpdates` map. Call the component again, reusing the
11808 // work-in-progress hooks and applying the additional updates on top. Keep
11809 // restarting until no more updates are scheduled.
11810 didScheduleRenderPhaseUpdate = false;
11811 numberOfReRenders += 1;
11812
11813 // Start over from the beginning of the list
11814 currentHook = null;
11815 workInProgressHook = null;
11816 componentUpdateQueue = null;
11817
11818 children = Component(props, refOrContext);
11819 }
11820 renderPhaseUpdates = null;
11821 numberOfReRenders = 0;
11822
11823 var renderedWork = currentlyRenderingFiber$1;
11824
11825 renderedWork.memoizedState = firstWorkInProgressHook;
11826 renderedWork.expirationTime = remainingExpirationTime;
11827 renderedWork.updateQueue = componentUpdateQueue;
11828
11829 var didRenderTooFewHooks = currentHook !== null && currentHook.next !== null;
11830
11831 renderExpirationTime = NoWork;
11832 currentlyRenderingFiber$1 = null;
11833
11834 firstCurrentHook = null;
11835 currentHook = null;
11836 firstWorkInProgressHook = null;
11837 workInProgressHook = null;
11838
11839 remainingExpirationTime = NoWork;
11840 componentUpdateQueue = null;
11841
11842 // Always set during createWorkInProgress
11843 // isReRender = false;
11844
11845 // These were reset above
11846 // didScheduleRenderPhaseUpdate = false;
11847 // renderPhaseUpdates = null;
11848 // numberOfReRenders = 0;
11849
11850 !!didRenderTooFewHooks ? invariant(false, 'Rendered fewer hooks than expected. This may be caused by an accidental early return statement.') : void 0;
11851
11852 return children;
11853}
11854
11855function resetHooks() {
11856 if (!enableHooks) {
11857 return;
11858 }
11859
11860 // This is called instead of `finishHooks` if the component throws. It's also
11861 // called inside mountIndeterminateComponent if we determine the component
11862 // is a module-style component.
11863 renderExpirationTime = NoWork;
11864 currentlyRenderingFiber$1 = null;
11865
11866 firstCurrentHook = null;
11867 currentHook = null;
11868 firstWorkInProgressHook = null;
11869 workInProgressHook = null;
11870
11871 remainingExpirationTime = NoWork;
11872 componentUpdateQueue = null;
11873
11874 // Always set during createWorkInProgress
11875 // isReRender = false;
11876
11877 didScheduleRenderPhaseUpdate = false;
11878 renderPhaseUpdates = null;
11879 numberOfReRenders = 0;
11880}
11881
11882function createHook() {
11883 return {
11884 memoizedState: null,
11885
11886 baseState: null,
11887 queue: null,
11888 baseUpdate: null,
11889
11890 next: null
11891 };
11892}
11893
11894function cloneHook(hook) {
11895 return {
11896 memoizedState: hook.memoizedState,
11897
11898 baseState: hook.baseState,
11899 queue: hook.queue,
11900 baseUpdate: hook.baseUpdate,
11901
11902 next: null
11903 };
11904}
11905
11906function createWorkInProgressHook() {
11907 if (workInProgressHook === null) {
11908 // This is the first hook in the list
11909 if (firstWorkInProgressHook === null) {
11910 isReRender = false;
11911 currentHook = firstCurrentHook;
11912 if (currentHook === null) {
11913 // This is a newly mounted hook
11914 workInProgressHook = createHook();
11915 } else {
11916 // Clone the current hook.
11917 workInProgressHook = cloneHook(currentHook);
11918 }
11919 firstWorkInProgressHook = workInProgressHook;
11920 } else {
11921 // There's already a work-in-progress. Reuse it.
11922 isReRender = true;
11923 currentHook = firstCurrentHook;
11924 workInProgressHook = firstWorkInProgressHook;
11925 }
11926 } else {
11927 if (workInProgressHook.next === null) {
11928 isReRender = false;
11929 var hook = void 0;
11930 if (currentHook === null) {
11931 // This is a newly mounted hook
11932 hook = createHook();
11933 } else {
11934 currentHook = currentHook.next;
11935 if (currentHook === null) {
11936 // This is a newly mounted hook
11937 hook = createHook();
11938 } else {
11939 // Clone the current hook.
11940 hook = cloneHook(currentHook);
11941 }
11942 }
11943 // Append to the end of the list
11944 workInProgressHook = workInProgressHook.next = hook;
11945 } else {
11946 // There's already a work-in-progress. Reuse it.
11947 isReRender = true;
11948 workInProgressHook = workInProgressHook.next;
11949 currentHook = currentHook !== null ? currentHook.next : null;
11950 }
11951 }
11952 return workInProgressHook;
11953}
11954
11955function createFunctionComponentUpdateQueue() {
11956 return {
11957 lastEffect: null
11958 };
11959}
11960
11961function basicStateReducer(state, action) {
11962 return typeof action === 'function' ? action(state) : action;
11963}
11964
11965function useContext(context, observedBits) {
11966 // Ensure we're in a function component (class components support only the
11967 // .unstable_read() form)
11968 resolveCurrentlyRenderingFiber();
11969 return readContext(context, observedBits);
11970}
11971
11972function useState(initialState) {
11973 return useReducer(basicStateReducer,
11974 // useReducer has a special case to support lazy useState initializers
11975 initialState);
11976}
11977
11978function useReducer(reducer, initialState, initialAction) {
11979 currentlyRenderingFiber$1 = resolveCurrentlyRenderingFiber();
11980 workInProgressHook = createWorkInProgressHook();
11981 var queue = workInProgressHook.queue;
11982 if (queue !== null) {
11983 // Already have a queue, so this is an update.
11984 if (isReRender) {
11985 // This is a re-render. Apply the new render phase updates to the previous
11986 var _dispatch2 = queue.dispatch;
11987 if (renderPhaseUpdates !== null) {
11988 // Render phase updates are stored in a map of queue -> linked list
11989 var firstRenderPhaseUpdate = renderPhaseUpdates.get(queue);
11990 if (firstRenderPhaseUpdate !== undefined) {
11991 renderPhaseUpdates.delete(queue);
11992 var newState = workInProgressHook.memoizedState;
11993 var update = firstRenderPhaseUpdate;
11994 do {
11995 // Process this render phase update. We don't have to check the
11996 // priority because it will always be the same as the current
11997 // render's.
11998 var _action = update.action;
11999 newState = reducer(newState, _action);
12000 update = update.next;
12001 } while (update !== null);
12002
12003 workInProgressHook.memoizedState = newState;
12004
12005 // Don't persist the state accumlated from the render phase updates to
12006 // the base state unless the queue is empty.
12007 // TODO: Not sure if this is the desired semantics, but it's what we
12008 // do for gDSFP. I can't remember why.
12009 if (workInProgressHook.baseUpdate === queue.last) {
12010 workInProgressHook.baseState = newState;
12011 }
12012
12013 return [newState, _dispatch2];
12014 }
12015 }
12016 return [workInProgressHook.memoizedState, _dispatch2];
12017 }
12018
12019 // The last update in the entire queue
12020 var _last = queue.last;
12021 // The last update that is part of the base state.
12022 var _baseUpdate = workInProgressHook.baseUpdate;
12023
12024 // Find the first unprocessed update.
12025 var first = void 0;
12026 if (_baseUpdate !== null) {
12027 if (_last !== null) {
12028 // For the first update, the queue is a circular linked list where
12029 // `queue.last.next = queue.first`. Once the first update commits, and
12030 // the `baseUpdate` is no longer empty, we can unravel the list.
12031 _last.next = null;
12032 }
12033 first = _baseUpdate.next;
12034 } else {
12035 first = _last !== null ? _last.next : null;
12036 }
12037 if (first !== null) {
12038 var _newState = workInProgressHook.baseState;
12039 var newBaseState = null;
12040 var newBaseUpdate = null;
12041 var prevUpdate = _baseUpdate;
12042 var _update = first;
12043 var didSkip = false;
12044 do {
12045 var updateExpirationTime = _update.expirationTime;
12046 if (updateExpirationTime < renderExpirationTime) {
12047 // Priority is insufficient. Skip this update. If this is the first
12048 // skipped update, the previous update/state is the new base
12049 // update/state.
12050 if (!didSkip) {
12051 didSkip = true;
12052 newBaseUpdate = prevUpdate;
12053 newBaseState = _newState;
12054 }
12055 // Update the remaining priority in the queue.
12056 if (updateExpirationTime > remainingExpirationTime) {
12057 remainingExpirationTime = updateExpirationTime;
12058 }
12059 } else {
12060 // Process this update.
12061 var _action2 = _update.action;
12062 _newState = reducer(_newState, _action2);
12063 }
12064 prevUpdate = _update;
12065 _update = _update.next;
12066 } while (_update !== null && _update !== first);
12067
12068 if (!didSkip) {
12069 newBaseUpdate = prevUpdate;
12070 newBaseState = _newState;
12071 }
12072
12073 workInProgressHook.memoizedState = _newState;
12074 workInProgressHook.baseUpdate = newBaseUpdate;
12075 workInProgressHook.baseState = newBaseState;
12076 }
12077
12078 var _dispatch = queue.dispatch;
12079 return [workInProgressHook.memoizedState, _dispatch];
12080 }
12081
12082 // There's no existing queue, so this is the initial render.
12083 if (reducer === basicStateReducer) {
12084 // Special case for `useState`.
12085 if (typeof initialState === 'function') {
12086 initialState = initialState();
12087 }
12088 } else if (initialAction !== undefined && initialAction !== null) {
12089 initialState = reducer(initialState, initialAction);
12090 }
12091 workInProgressHook.memoizedState = workInProgressHook.baseState = initialState;
12092 queue = workInProgressHook.queue = {
12093 last: null,
12094 dispatch: null
12095 };
12096 var dispatch = queue.dispatch = dispatchAction.bind(null, currentlyRenderingFiber$1, queue);
12097 return [workInProgressHook.memoizedState, dispatch];
12098}
12099
12100function pushEffect(tag, create, destroy, inputs) {
12101 var effect = {
12102 tag: tag,
12103 create: create,
12104 destroy: destroy,
12105 inputs: inputs,
12106 // Circular
12107 next: null
12108 };
12109 if (componentUpdateQueue === null) {
12110 componentUpdateQueue = createFunctionComponentUpdateQueue();
12111 componentUpdateQueue.lastEffect = effect.next = effect;
12112 } else {
12113 var _lastEffect = componentUpdateQueue.lastEffect;
12114 if (_lastEffect === null) {
12115 componentUpdateQueue.lastEffect = effect.next = effect;
12116 } else {
12117 var firstEffect = _lastEffect.next;
12118 _lastEffect.next = effect;
12119 effect.next = firstEffect;
12120 componentUpdateQueue.lastEffect = effect;
12121 }
12122 }
12123 return effect;
12124}
12125
12126function useRef(initialValue) {
12127 currentlyRenderingFiber$1 = resolveCurrentlyRenderingFiber();
12128 workInProgressHook = createWorkInProgressHook();
12129 var ref = void 0;
12130
12131 if (workInProgressHook.memoizedState === null) {
12132 ref = { current: initialValue };
12133 {
12134 Object.seal(ref);
12135 }
12136 workInProgressHook.memoizedState = ref;
12137 } else {
12138 ref = workInProgressHook.memoizedState;
12139 }
12140 return ref;
12141}
12142
12143function useLayoutEffect(create, inputs) {
12144 useEffectImpl(Update, UnmountMutation | MountLayout, create, inputs);
12145}
12146
12147function useEffect(create, inputs) {
12148 useEffectImpl(Update | Passive, UnmountPassive | MountPassive, create, inputs);
12149}
12150
12151function useEffectImpl(fiberEffectTag, hookEffectTag, create, inputs) {
12152 currentlyRenderingFiber$1 = resolveCurrentlyRenderingFiber();
12153 workInProgressHook = createWorkInProgressHook();
12154
12155 var nextInputs = inputs !== undefined && inputs !== null ? inputs : [create];
12156 var destroy = null;
12157 if (currentHook !== null) {
12158 var prevEffect = currentHook.memoizedState;
12159 destroy = prevEffect.destroy;
12160 if (areHookInputsEqual(nextInputs, prevEffect.inputs)) {
12161 pushEffect(NoEffect$1, create, destroy, nextInputs);
12162 return;
12163 }
12164 }
12165
12166 currentlyRenderingFiber$1.effectTag |= fiberEffectTag;
12167 workInProgressHook.memoizedState = pushEffect(hookEffectTag, create, destroy, nextInputs);
12168}
12169
12170function useImperativeMethods(ref, create, inputs) {
12171 // TODO: If inputs are provided, should we skip comparing the ref itself?
12172 var nextInputs = inputs !== null && inputs !== undefined ? inputs.concat([ref]) : [ref, create];
12173
12174 // TODO: I've implemented this on top of useEffect because it's almost the
12175 // same thing, and it would require an equal amount of code. It doesn't seem
12176 // like a common enough use case to justify the additional size.
12177 useLayoutEffect(function () {
12178 if (typeof ref === 'function') {
12179 var refCallback = ref;
12180 var _inst = create();
12181 refCallback(_inst);
12182 return function () {
12183 return refCallback(null);
12184 };
12185 } else if (ref !== null && ref !== undefined) {
12186 var refObject = ref;
12187 var _inst2 = create();
12188 refObject.current = _inst2;
12189 return function () {
12190 refObject.current = null;
12191 };
12192 }
12193 }, nextInputs);
12194}
12195
12196function useCallback(callback, inputs) {
12197 currentlyRenderingFiber$1 = resolveCurrentlyRenderingFiber();
12198 workInProgressHook = createWorkInProgressHook();
12199
12200 var nextInputs = inputs !== undefined && inputs !== null ? inputs : [callback];
12201
12202 var prevState = workInProgressHook.memoizedState;
12203 if (prevState !== null) {
12204 var prevInputs = prevState[1];
12205 if (areHookInputsEqual(nextInputs, prevInputs)) {
12206 return prevState[0];
12207 }
12208 }
12209 workInProgressHook.memoizedState = [callback, nextInputs];
12210 return callback;
12211}
12212
12213function useMemo(nextCreate, inputs) {
12214 currentlyRenderingFiber$1 = resolveCurrentlyRenderingFiber();
12215 workInProgressHook = createWorkInProgressHook();
12216
12217 var nextInputs = inputs !== undefined && inputs !== null ? inputs : [nextCreate];
12218
12219 var prevState = workInProgressHook.memoizedState;
12220 if (prevState !== null) {
12221 var prevInputs = prevState[1];
12222 if (areHookInputsEqual(nextInputs, prevInputs)) {
12223 return prevState[0];
12224 }
12225 }
12226
12227 var nextValue = nextCreate();
12228 workInProgressHook.memoizedState = [nextValue, nextInputs];
12229 return nextValue;
12230}
12231
12232function dispatchAction(fiber, queue, action) {
12233 !(numberOfReRenders < RE_RENDER_LIMIT) ? invariant(false, 'Too many re-renders. React limits the number of renders to prevent an infinite loop.') : void 0;
12234
12235 var alternate = fiber.alternate;
12236 if (fiber === currentlyRenderingFiber$1 || alternate !== null && alternate === currentlyRenderingFiber$1) {
12237 // This is a render phase update. Stash it in a lazily-created map of
12238 // queue -> linked list of updates. After this render pass, we'll restart
12239 // and apply the stashed updates on top of the work-in-progress hook.
12240 didScheduleRenderPhaseUpdate = true;
12241 var update = {
12242 expirationTime: renderExpirationTime,
12243 action: action,
12244 next: null
12245 };
12246 if (renderPhaseUpdates === null) {
12247 renderPhaseUpdates = new Map();
12248 }
12249 var firstRenderPhaseUpdate = renderPhaseUpdates.get(queue);
12250 if (firstRenderPhaseUpdate === undefined) {
12251 renderPhaseUpdates.set(queue, update);
12252 } else {
12253 // Append the update to the end of the list.
12254 var lastRenderPhaseUpdate = firstRenderPhaseUpdate;
12255 while (lastRenderPhaseUpdate.next !== null) {
12256 lastRenderPhaseUpdate = lastRenderPhaseUpdate.next;
12257 }
12258 lastRenderPhaseUpdate.next = update;
12259 }
12260 } else {
12261 var currentTime = requestCurrentTime();
12262 var _expirationTime = computeExpirationForFiber(currentTime, fiber);
12263 var _update2 = {
12264 expirationTime: _expirationTime,
12265 action: action,
12266 next: null
12267 };
12268 flushPassiveEffects();
12269 // Append the update to the end of the list.
12270 var _last2 = queue.last;
12271 if (_last2 === null) {
12272 // This is the first update. Create a circular list.
12273 _update2.next = _update2;
12274 } else {
12275 var first = _last2.next;
12276 if (first !== null) {
12277 // Still circular.
12278 _update2.next = first;
12279 }
12280 _last2.next = _update2;
12281 }
12282 queue.last = _update2;
12283 scheduleWork(fiber, _expirationTime);
12284 }
12285}
12286
12287var NO_CONTEXT = {};
12288
12289var contextStackCursor$1 = createCursor(NO_CONTEXT);
12290var contextFiberStackCursor = createCursor(NO_CONTEXT);
12291var rootInstanceStackCursor = createCursor(NO_CONTEXT);
12292
12293function requiredContext(c) {
12294 !(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;
12295 return c;
12296}
12297
12298function getRootHostContainer() {
12299 var rootInstance = requiredContext(rootInstanceStackCursor.current);
12300 return rootInstance;
12301}
12302
12303function pushHostContainer(fiber, nextRootInstance) {
12304 // Push current root instance onto the stack;
12305 // This allows us to reset root when portals are popped.
12306 push(rootInstanceStackCursor, nextRootInstance, fiber);
12307 // Track the context and the Fiber that provided it.
12308 // This enables us to pop only Fibers that provide unique contexts.
12309 push(contextFiberStackCursor, fiber, fiber);
12310
12311 // Finally, we need to push the host context to the stack.
12312 // However, we can't just call getRootHostContext() and push it because
12313 // we'd have a different number of entries on the stack depending on
12314 // whether getRootHostContext() throws somewhere in renderer code or not.
12315 // So we push an empty value first. This lets us safely unwind on errors.
12316 push(contextStackCursor$1, NO_CONTEXT, fiber);
12317 var nextRootContext = getRootHostContext(nextRootInstance);
12318 // Now that we know this function doesn't throw, replace it.
12319 pop(contextStackCursor$1, fiber);
12320 push(contextStackCursor$1, nextRootContext, fiber);
12321}
12322
12323function popHostContainer(fiber) {
12324 pop(contextStackCursor$1, fiber);
12325 pop(contextFiberStackCursor, fiber);
12326 pop(rootInstanceStackCursor, fiber);
12327}
12328
12329function getHostContext() {
12330 var context = requiredContext(contextStackCursor$1.current);
12331 return context;
12332}
12333
12334function pushHostContext(fiber) {
12335 var rootInstance = requiredContext(rootInstanceStackCursor.current);
12336 var context = requiredContext(contextStackCursor$1.current);
12337 var nextContext = getChildHostContext(context, fiber.type, rootInstance);
12338
12339 // Don't push this Fiber's context unless it's unique.
12340 if (context === nextContext) {
12341 return;
12342 }
12343
12344 // Track the context and the Fiber that provided it.
12345 // This enables us to pop only Fibers that provide unique contexts.
12346 push(contextFiberStackCursor, fiber, fiber);
12347 push(contextStackCursor$1, nextContext, fiber);
12348}
12349
12350function popHostContext(fiber) {
12351 // Do not pop unless this Fiber provided the current context.
12352 // pushHostContext() only pushes Fibers that provide unique contexts.
12353 if (contextFiberStackCursor.current !== fiber) {
12354 return;
12355 }
12356
12357 pop(contextStackCursor$1, fiber);
12358 pop(contextFiberStackCursor, fiber);
12359}
12360
12361var commitTime = 0;
12362var profilerStartTime = -1;
12363
12364function getCommitTime() {
12365 return commitTime;
12366}
12367
12368function recordCommitTime() {
12369 if (!enableProfilerTimer) {
12370 return;
12371 }
12372 commitTime = unstable_now();
12373}
12374
12375function startProfilerTimer(fiber) {
12376 if (!enableProfilerTimer) {
12377 return;
12378 }
12379
12380 profilerStartTime = unstable_now();
12381
12382 if (fiber.actualStartTime < 0) {
12383 fiber.actualStartTime = unstable_now();
12384 }
12385}
12386
12387function stopProfilerTimerIfRunning(fiber) {
12388 if (!enableProfilerTimer) {
12389 return;
12390 }
12391 profilerStartTime = -1;
12392}
12393
12394function stopProfilerTimerIfRunningAndRecordDelta(fiber, overrideBaseTime) {
12395 if (!enableProfilerTimer) {
12396 return;
12397 }
12398
12399 if (profilerStartTime >= 0) {
12400 var elapsedTime = unstable_now() - profilerStartTime;
12401 fiber.actualDuration += elapsedTime;
12402 if (overrideBaseTime) {
12403 fiber.selfBaseDuration = elapsedTime;
12404 }
12405 profilerStartTime = -1;
12406 }
12407}
12408
12409function resolveDefaultProps(Component, baseProps) {
12410 if (Component && Component.defaultProps) {
12411 // Resolve default props. Taken from ReactElement
12412 var props = _assign({}, baseProps);
12413 var defaultProps = Component.defaultProps;
12414 for (var propName in defaultProps) {
12415 if (props[propName] === undefined) {
12416 props[propName] = defaultProps[propName];
12417 }
12418 }
12419 return props;
12420 }
12421 return baseProps;
12422}
12423
12424function readLazyComponentType(lazyComponent) {
12425 var status = lazyComponent._status;
12426 var result = lazyComponent._result;
12427 switch (status) {
12428 case Resolved:
12429 {
12430 var Component = result;
12431 return Component;
12432 }
12433 case Rejected:
12434 {
12435 var error = result;
12436 throw error;
12437 }
12438 case Pending:
12439 {
12440 var thenable = result;
12441 throw thenable;
12442 }
12443 default:
12444 {
12445 lazyComponent._status = Pending;
12446 var ctor = lazyComponent._ctor;
12447 var _thenable = ctor();
12448 _thenable.then(function (moduleObject) {
12449 if (lazyComponent._status === Pending) {
12450 var defaultExport = moduleObject.default;
12451 {
12452 if (defaultExport === undefined) {
12453 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);
12454 }
12455 }
12456 lazyComponent._status = Resolved;
12457 lazyComponent._result = defaultExport;
12458 }
12459 }, function (error) {
12460 if (lazyComponent._status === Pending) {
12461 lazyComponent._status = Rejected;
12462 lazyComponent._result = error;
12463 }
12464 });
12465 lazyComponent._result = _thenable;
12466 throw _thenable;
12467 }
12468 }
12469}
12470
12471var ReactCurrentOwner$4 = ReactSharedInternals.ReactCurrentOwner;
12472
12473function readContext$1(contextType) {
12474 var dispatcher = ReactCurrentOwner$4.currentDispatcher;
12475 return dispatcher.readContext(contextType);
12476}
12477
12478var fakeInternalInstance = {};
12479var isArray$1 = Array.isArray;
12480
12481// React.Component uses a shared frozen object by default.
12482// We'll use it to determine whether we need to initialize legacy refs.
12483var emptyRefsObject = new React.Component().refs;
12484
12485var didWarnAboutStateAssignmentForComponent = void 0;
12486var didWarnAboutUninitializedState = void 0;
12487var didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate = void 0;
12488var didWarnAboutLegacyLifecyclesAndDerivedState = void 0;
12489var didWarnAboutUndefinedDerivedState = void 0;
12490var warnOnUndefinedDerivedState = void 0;
12491var warnOnInvalidCallback$1 = void 0;
12492var didWarnAboutDirectlyAssigningPropsToState = void 0;
12493var didWarnAboutContextTypeAndContextTypes = void 0;
12494var didWarnAboutInvalidateContextType = void 0;
12495
12496{
12497 didWarnAboutStateAssignmentForComponent = new Set();
12498 didWarnAboutUninitializedState = new Set();
12499 didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate = new Set();
12500 didWarnAboutLegacyLifecyclesAndDerivedState = new Set();
12501 didWarnAboutDirectlyAssigningPropsToState = new Set();
12502 didWarnAboutUndefinedDerivedState = new Set();
12503 didWarnAboutContextTypeAndContextTypes = new Set();
12504 didWarnAboutInvalidateContextType = new Set();
12505
12506 var didWarnOnInvalidCallback = new Set();
12507
12508 warnOnInvalidCallback$1 = function (callback, callerName) {
12509 if (callback === null || typeof callback === 'function') {
12510 return;
12511 }
12512 var key = callerName + '_' + callback;
12513 if (!didWarnOnInvalidCallback.has(key)) {
12514 didWarnOnInvalidCallback.add(key);
12515 warningWithoutStack$1(false, '%s(...): Expected the last optional `callback` argument to be a ' + 'function. Instead received: %s.', callerName, callback);
12516 }
12517 };
12518
12519 warnOnUndefinedDerivedState = function (type, partialState) {
12520 if (partialState === undefined) {
12521 var componentName = getComponentName(type) || 'Component';
12522 if (!didWarnAboutUndefinedDerivedState.has(componentName)) {
12523 didWarnAboutUndefinedDerivedState.add(componentName);
12524 warningWithoutStack$1(false, '%s.getDerivedStateFromProps(): A valid state object (or null) must be returned. ' + 'You have returned undefined.', componentName);
12525 }
12526 }
12527 };
12528
12529 // This is so gross but it's at least non-critical and can be removed if
12530 // it causes problems. This is meant to give a nicer error message for
12531 // ReactDOM15.unstable_renderSubtreeIntoContainer(reactDOM16Component,
12532 // ...)) which otherwise throws a "_processChildContext is not a function"
12533 // exception.
12534 Object.defineProperty(fakeInternalInstance, '_processChildContext', {
12535 enumerable: false,
12536 value: function () {
12537 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).');
12538 }
12539 });
12540 Object.freeze(fakeInternalInstance);
12541}
12542
12543function applyDerivedStateFromProps(workInProgress, ctor, getDerivedStateFromProps, nextProps) {
12544 var prevState = workInProgress.memoizedState;
12545
12546 {
12547 if (debugRenderPhaseSideEffects || debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) {
12548 // Invoke the function an extra time to help detect side-effects.
12549 getDerivedStateFromProps(nextProps, prevState);
12550 }
12551 }
12552
12553 var partialState = getDerivedStateFromProps(nextProps, prevState);
12554
12555 {
12556 warnOnUndefinedDerivedState(ctor, partialState);
12557 }
12558 // Merge the partial state and the previous state.
12559 var memoizedState = partialState === null || partialState === undefined ? prevState : _assign({}, prevState, partialState);
12560 workInProgress.memoizedState = memoizedState;
12561
12562 // Once the update queue is empty, persist the derived state onto the
12563 // base state.
12564 var updateQueue = workInProgress.updateQueue;
12565 if (updateQueue !== null && workInProgress.expirationTime === NoWork) {
12566 updateQueue.baseState = memoizedState;
12567 }
12568}
12569
12570var classComponentUpdater = {
12571 isMounted: isMounted,
12572 enqueueSetState: function (inst, payload, callback) {
12573 var fiber = get(inst);
12574 var currentTime = requestCurrentTime();
12575 var expirationTime = computeExpirationForFiber(currentTime, fiber);
12576
12577 var update = createUpdate(expirationTime);
12578 update.payload = payload;
12579 if (callback !== undefined && callback !== null) {
12580 {
12581 warnOnInvalidCallback$1(callback, 'setState');
12582 }
12583 update.callback = callback;
12584 }
12585
12586 flushPassiveEffects();
12587 enqueueUpdate(fiber, update);
12588 scheduleWork(fiber, expirationTime);
12589 },
12590 enqueueReplaceState: function (inst, payload, callback) {
12591 var fiber = get(inst);
12592 var currentTime = requestCurrentTime();
12593 var expirationTime = computeExpirationForFiber(currentTime, fiber);
12594
12595 var update = createUpdate(expirationTime);
12596 update.tag = ReplaceState;
12597 update.payload = payload;
12598
12599 if (callback !== undefined && callback !== null) {
12600 {
12601 warnOnInvalidCallback$1(callback, 'replaceState');
12602 }
12603 update.callback = callback;
12604 }
12605
12606 flushPassiveEffects();
12607 enqueueUpdate(fiber, update);
12608 scheduleWork(fiber, expirationTime);
12609 },
12610 enqueueForceUpdate: function (inst, callback) {
12611 var fiber = get(inst);
12612 var currentTime = requestCurrentTime();
12613 var expirationTime = computeExpirationForFiber(currentTime, fiber);
12614
12615 var update = createUpdate(expirationTime);
12616 update.tag = ForceUpdate;
12617
12618 if (callback !== undefined && callback !== null) {
12619 {
12620 warnOnInvalidCallback$1(callback, 'forceUpdate');
12621 }
12622 update.callback = callback;
12623 }
12624
12625 flushPassiveEffects();
12626 enqueueUpdate(fiber, update);
12627 scheduleWork(fiber, expirationTime);
12628 }
12629};
12630
12631function checkShouldComponentUpdate(workInProgress, ctor, oldProps, newProps, oldState, newState, nextContext) {
12632 var instance = workInProgress.stateNode;
12633 if (typeof instance.shouldComponentUpdate === 'function') {
12634 startPhaseTimer(workInProgress, 'shouldComponentUpdate');
12635 var shouldUpdate = instance.shouldComponentUpdate(newProps, newState, nextContext);
12636 stopPhaseTimer();
12637
12638 {
12639 !(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;
12640 }
12641
12642 return shouldUpdate;
12643 }
12644
12645 if (ctor.prototype && ctor.prototype.isPureReactComponent) {
12646 return !shallowEqual(oldProps, newProps) || !shallowEqual(oldState, newState);
12647 }
12648
12649 return true;
12650}
12651
12652function checkClassInstance(workInProgress, ctor, newProps) {
12653 var instance = workInProgress.stateNode;
12654 {
12655 var name = getComponentName(ctor) || 'Component';
12656 var renderPresent = instance.render;
12657
12658 if (!renderPresent) {
12659 if (ctor.prototype && typeof ctor.prototype.render === 'function') {
12660 warningWithoutStack$1(false, '%s(...): No `render` method found on the returned component ' + 'instance: did you accidentally return an object from the constructor?', name);
12661 } else {
12662 warningWithoutStack$1(false, '%s(...): No `render` method found on the returned component ' + 'instance: you may have forgotten to define `render`.', name);
12663 }
12664 }
12665
12666 var noGetInitialStateOnES6 = !instance.getInitialState || instance.getInitialState.isReactClassApproved || instance.state;
12667 !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;
12668 var noGetDefaultPropsOnES6 = !instance.getDefaultProps || instance.getDefaultProps.isReactClassApproved;
12669 !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;
12670 var noInstancePropTypes = !instance.propTypes;
12671 !noInstancePropTypes ? warningWithoutStack$1(false, 'propTypes was defined as an instance property on %s. Use a static ' + 'property to define propTypes instead.', name) : void 0;
12672 var noInstanceContextType = !instance.contextType;
12673 !noInstanceContextType ? warningWithoutStack$1(false, 'contextType was defined as an instance property on %s. Use a static ' + 'property to define contextType instead.', name) : void 0;
12674 var noInstanceContextTypes = !instance.contextTypes;
12675 !noInstanceContextTypes ? warningWithoutStack$1(false, 'contextTypes was defined as an instance property on %s. Use a static ' + 'property to define contextTypes instead.', name) : void 0;
12676
12677 if (ctor.contextType && ctor.contextTypes && !didWarnAboutContextTypeAndContextTypes.has(ctor)) {
12678 didWarnAboutContextTypeAndContextTypes.add(ctor);
12679 warningWithoutStack$1(false, '%s declares both contextTypes and contextType static properties. ' + 'The legacy contextTypes property will be ignored.', name);
12680 }
12681
12682 var noComponentShouldUpdate = typeof instance.componentShouldUpdate !== 'function';
12683 !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;
12684 if (ctor.prototype && ctor.prototype.isPureReactComponent && typeof instance.shouldComponentUpdate !== 'undefined') {
12685 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');
12686 }
12687 var noComponentDidUnmount = typeof instance.componentDidUnmount !== 'function';
12688 !noComponentDidUnmount ? warningWithoutStack$1(false, '%s has a method called ' + 'componentDidUnmount(). But there is no such lifecycle method. ' + 'Did you mean componentWillUnmount()?', name) : void 0;
12689 var noComponentDidReceiveProps = typeof instance.componentDidReceiveProps !== 'function';
12690 !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;
12691 var noComponentWillRecieveProps = typeof instance.componentWillRecieveProps !== 'function';
12692 !noComponentWillRecieveProps ? warningWithoutStack$1(false, '%s has a method called ' + 'componentWillRecieveProps(). Did you mean componentWillReceiveProps()?', name) : void 0;
12693 var noUnsafeComponentWillRecieveProps = typeof instance.UNSAFE_componentWillRecieveProps !== 'function';
12694 !noUnsafeComponentWillRecieveProps ? warningWithoutStack$1(false, '%s has a method called ' + 'UNSAFE_componentWillRecieveProps(). Did you mean UNSAFE_componentWillReceiveProps()?', name) : void 0;
12695 var hasMutatedProps = instance.props !== newProps;
12696 !(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;
12697 var noInstanceDefaultProps = !instance.defaultProps;
12698 !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;
12699
12700 if (typeof instance.getSnapshotBeforeUpdate === 'function' && typeof instance.componentDidUpdate !== 'function' && !didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate.has(ctor)) {
12701 didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate.add(ctor);
12702 warningWithoutStack$1(false, '%s: getSnapshotBeforeUpdate() should be used with componentDidUpdate(). ' + 'This component defines getSnapshotBeforeUpdate() only.', getComponentName(ctor));
12703 }
12704
12705 var noInstanceGetDerivedStateFromProps = typeof instance.getDerivedStateFromProps !== 'function';
12706 !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;
12707 var noInstanceGetDerivedStateFromCatch = typeof instance.getDerivedStateFromError !== 'function';
12708 !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;
12709 var noStaticGetSnapshotBeforeUpdate = typeof ctor.getSnapshotBeforeUpdate !== 'function';
12710 !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;
12711 var _state = instance.state;
12712 if (_state && (typeof _state !== 'object' || isArray$1(_state))) {
12713 warningWithoutStack$1(false, '%s.state: must be set to an object or null', name);
12714 }
12715 if (typeof instance.getChildContext === 'function') {
12716 !(typeof ctor.childContextTypes === 'object') ? warningWithoutStack$1(false, '%s.getChildContext(): childContextTypes must be defined in order to ' + 'use getChildContext().', name) : void 0;
12717 }
12718 }
12719}
12720
12721function adoptClassInstance(workInProgress, instance) {
12722 instance.updater = classComponentUpdater;
12723 workInProgress.stateNode = instance;
12724 // The instance needs access to the fiber so that it can schedule updates
12725 set(instance, workInProgress);
12726 {
12727 instance._reactInternalInstance = fakeInternalInstance;
12728 }
12729}
12730
12731function constructClassInstance(workInProgress, ctor, props, renderExpirationTime) {
12732 var isLegacyContextConsumer = false;
12733 var unmaskedContext = emptyContextObject;
12734 var context = null;
12735 var contextType = ctor.contextType;
12736 if (typeof contextType === 'object' && contextType !== null) {
12737 {
12738 if (contextType.$$typeof !== REACT_CONTEXT_TYPE && !didWarnAboutInvalidateContextType.has(ctor)) {
12739 didWarnAboutInvalidateContextType.add(ctor);
12740 warningWithoutStack$1(false, '%s defines an invalid contextType. ' + 'contextType should point to the Context object returned by React.createContext(). ' + 'Did you accidentally pass the Context.Provider instead?', getComponentName(ctor) || 'Component');
12741 }
12742 }
12743
12744 context = readContext$1(contextType);
12745 } else {
12746 unmaskedContext = getUnmaskedContext(workInProgress, ctor, true);
12747 var contextTypes = ctor.contextTypes;
12748 isLegacyContextConsumer = contextTypes !== null && contextTypes !== undefined;
12749 context = isLegacyContextConsumer ? getMaskedContext(workInProgress, unmaskedContext) : emptyContextObject;
12750 }
12751
12752 // Instantiate twice to help detect side-effects.
12753 {
12754 if (debugRenderPhaseSideEffects || debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) {
12755 new ctor(props, context); // eslint-disable-line no-new
12756 }
12757 }
12758
12759 var instance = new ctor(props, context);
12760 var state = workInProgress.memoizedState = instance.state !== null && instance.state !== undefined ? instance.state : null;
12761 adoptClassInstance(workInProgress, instance);
12762
12763 {
12764 if (typeof ctor.getDerivedStateFromProps === 'function' && state === null) {
12765 var componentName = getComponentName(ctor) || 'Component';
12766 if (!didWarnAboutUninitializedState.has(componentName)) {
12767 didWarnAboutUninitializedState.add(componentName);
12768 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);
12769 }
12770 }
12771
12772 // If new component APIs are defined, "unsafe" lifecycles won't be called.
12773 // Warn about these lifecycles if they are present.
12774 // Don't warn about react-lifecycles-compat polyfilled methods though.
12775 if (typeof ctor.getDerivedStateFromProps === 'function' || typeof instance.getSnapshotBeforeUpdate === 'function') {
12776 var foundWillMountName = null;
12777 var foundWillReceivePropsName = null;
12778 var foundWillUpdateName = null;
12779 if (typeof instance.componentWillMount === 'function' && instance.componentWillMount.__suppressDeprecationWarning !== true) {
12780 foundWillMountName = 'componentWillMount';
12781 } else if (typeof instance.UNSAFE_componentWillMount === 'function') {
12782 foundWillMountName = 'UNSAFE_componentWillMount';
12783 }
12784 if (typeof instance.componentWillReceiveProps === 'function' && instance.componentWillReceiveProps.__suppressDeprecationWarning !== true) {
12785 foundWillReceivePropsName = 'componentWillReceiveProps';
12786 } else if (typeof instance.UNSAFE_componentWillReceiveProps === 'function') {
12787 foundWillReceivePropsName = 'UNSAFE_componentWillReceiveProps';
12788 }
12789 if (typeof instance.componentWillUpdate === 'function' && instance.componentWillUpdate.__suppressDeprecationWarning !== true) {
12790 foundWillUpdateName = 'componentWillUpdate';
12791 } else if (typeof instance.UNSAFE_componentWillUpdate === 'function') {
12792 foundWillUpdateName = 'UNSAFE_componentWillUpdate';
12793 }
12794 if (foundWillMountName !== null || foundWillReceivePropsName !== null || foundWillUpdateName !== null) {
12795 var _componentName = getComponentName(ctor) || 'Component';
12796 var newApiName = typeof ctor.getDerivedStateFromProps === 'function' ? 'getDerivedStateFromProps()' : 'getSnapshotBeforeUpdate()';
12797 if (!didWarnAboutLegacyLifecyclesAndDerivedState.has(_componentName)) {
12798 didWarnAboutLegacyLifecyclesAndDerivedState.add(_componentName);
12799 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 : '');
12800 }
12801 }
12802 }
12803 }
12804
12805 // Cache unmasked context so we can avoid recreating masked context unless necessary.
12806 // ReactFiberContext usually updates this cache but can't for newly-created instances.
12807 if (isLegacyContextConsumer) {
12808 cacheContext(workInProgress, unmaskedContext, context);
12809 }
12810
12811 return instance;
12812}
12813
12814function callComponentWillMount(workInProgress, instance) {
12815 startPhaseTimer(workInProgress, 'componentWillMount');
12816 var oldState = instance.state;
12817
12818 if (typeof instance.componentWillMount === 'function') {
12819 instance.componentWillMount();
12820 }
12821 if (typeof instance.UNSAFE_componentWillMount === 'function') {
12822 instance.UNSAFE_componentWillMount();
12823 }
12824
12825 stopPhaseTimer();
12826
12827 if (oldState !== instance.state) {
12828 {
12829 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');
12830 }
12831 classComponentUpdater.enqueueReplaceState(instance, instance.state, null);
12832 }
12833}
12834
12835function callComponentWillReceiveProps(workInProgress, instance, newProps, nextContext) {
12836 var oldState = instance.state;
12837 startPhaseTimer(workInProgress, 'componentWillReceiveProps');
12838 if (typeof instance.componentWillReceiveProps === 'function') {
12839 instance.componentWillReceiveProps(newProps, nextContext);
12840 }
12841 if (typeof instance.UNSAFE_componentWillReceiveProps === 'function') {
12842 instance.UNSAFE_componentWillReceiveProps(newProps, nextContext);
12843 }
12844 stopPhaseTimer();
12845
12846 if (instance.state !== oldState) {
12847 {
12848 var componentName = getComponentName(workInProgress.type) || 'Component';
12849 if (!didWarnAboutStateAssignmentForComponent.has(componentName)) {
12850 didWarnAboutStateAssignmentForComponent.add(componentName);
12851 warningWithoutStack$1(false, '%s.componentWillReceiveProps(): Assigning directly to ' + "this.state is deprecated (except inside a component's " + 'constructor). Use setState instead.', componentName);
12852 }
12853 }
12854 classComponentUpdater.enqueueReplaceState(instance, instance.state, null);
12855 }
12856}
12857
12858// Invokes the mount life-cycles on a previously never rendered instance.
12859function mountClassInstance(workInProgress, ctor, newProps, renderExpirationTime) {
12860 {
12861 checkClassInstance(workInProgress, ctor, newProps);
12862 }
12863
12864 var instance = workInProgress.stateNode;
12865 instance.props = newProps;
12866 instance.state = workInProgress.memoizedState;
12867 instance.refs = emptyRefsObject;
12868
12869 var contextType = ctor.contextType;
12870 if (typeof contextType === 'object' && contextType !== null) {
12871 instance.context = readContext$1(contextType);
12872 } else {
12873 var unmaskedContext = getUnmaskedContext(workInProgress, ctor, true);
12874 instance.context = getMaskedContext(workInProgress, unmaskedContext);
12875 }
12876
12877 {
12878 if (instance.state === newProps) {
12879 var componentName = getComponentName(ctor) || 'Component';
12880 if (!didWarnAboutDirectlyAssigningPropsToState.has(componentName)) {
12881 didWarnAboutDirectlyAssigningPropsToState.add(componentName);
12882 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);
12883 }
12884 }
12885
12886 if (workInProgress.mode & StrictMode) {
12887 ReactStrictModeWarnings.recordUnsafeLifecycleWarnings(workInProgress, instance);
12888
12889 ReactStrictModeWarnings.recordLegacyContextWarning(workInProgress, instance);
12890 }
12891
12892 if (warnAboutDeprecatedLifecycles) {
12893 ReactStrictModeWarnings.recordDeprecationWarnings(workInProgress, instance);
12894 }
12895 }
12896
12897 var updateQueue = workInProgress.updateQueue;
12898 if (updateQueue !== null) {
12899 processUpdateQueue(workInProgress, updateQueue, newProps, instance, renderExpirationTime);
12900 instance.state = workInProgress.memoizedState;
12901 }
12902
12903 var getDerivedStateFromProps = ctor.getDerivedStateFromProps;
12904 if (typeof getDerivedStateFromProps === 'function') {
12905 applyDerivedStateFromProps(workInProgress, ctor, getDerivedStateFromProps, newProps);
12906 instance.state = workInProgress.memoizedState;
12907 }
12908
12909 // In order to support react-lifecycles-compat polyfilled components,
12910 // Unsafe lifecycles should not be invoked for components using the new APIs.
12911 if (typeof ctor.getDerivedStateFromProps !== 'function' && typeof instance.getSnapshotBeforeUpdate !== 'function' && (typeof instance.UNSAFE_componentWillMount === 'function' || typeof instance.componentWillMount === 'function')) {
12912 callComponentWillMount(workInProgress, instance);
12913 // If we had additional state updates during this life-cycle, let's
12914 // process them now.
12915 updateQueue = workInProgress.updateQueue;
12916 if (updateQueue !== null) {
12917 processUpdateQueue(workInProgress, updateQueue, newProps, instance, renderExpirationTime);
12918 instance.state = workInProgress.memoizedState;
12919 }
12920 }
12921
12922 if (typeof instance.componentDidMount === 'function') {
12923 workInProgress.effectTag |= Update;
12924 }
12925}
12926
12927function resumeMountClassInstance(workInProgress, ctor, newProps, renderExpirationTime) {
12928 var instance = workInProgress.stateNode;
12929
12930 var oldProps = workInProgress.memoizedProps;
12931 instance.props = oldProps;
12932
12933 var oldContext = instance.context;
12934 var contextType = ctor.contextType;
12935 var nextContext = void 0;
12936 if (typeof contextType === 'object' && contextType !== null) {
12937 nextContext = readContext$1(contextType);
12938 } else {
12939 var nextLegacyUnmaskedContext = getUnmaskedContext(workInProgress, ctor, true);
12940 nextContext = getMaskedContext(workInProgress, nextLegacyUnmaskedContext);
12941 }
12942
12943 var getDerivedStateFromProps = ctor.getDerivedStateFromProps;
12944 var hasNewLifecycles = typeof getDerivedStateFromProps === 'function' || typeof instance.getSnapshotBeforeUpdate === 'function';
12945
12946 // Note: During these life-cycles, instance.props/instance.state are what
12947 // ever the previously attempted to render - not the "current". However,
12948 // during componentDidUpdate we pass the "current" props.
12949
12950 // In order to support react-lifecycles-compat polyfilled components,
12951 // Unsafe lifecycles should not be invoked for components using the new APIs.
12952 if (!hasNewLifecycles && (typeof instance.UNSAFE_componentWillReceiveProps === 'function' || typeof instance.componentWillReceiveProps === 'function')) {
12953 if (oldProps !== newProps || oldContext !== nextContext) {
12954 callComponentWillReceiveProps(workInProgress, instance, newProps, nextContext);
12955 }
12956 }
12957
12958 resetHasForceUpdateBeforeProcessing();
12959
12960 var oldState = workInProgress.memoizedState;
12961 var newState = instance.state = oldState;
12962 var updateQueue = workInProgress.updateQueue;
12963 if (updateQueue !== null) {
12964 processUpdateQueue(workInProgress, updateQueue, newProps, instance, renderExpirationTime);
12965 newState = workInProgress.memoizedState;
12966 }
12967 if (oldProps === newProps && oldState === newState && !hasContextChanged() && !checkHasForceUpdateAfterProcessing()) {
12968 // If an update was already in progress, we should schedule an Update
12969 // effect even though we're bailing out, so that cWU/cDU are called.
12970 if (typeof instance.componentDidMount === 'function') {
12971 workInProgress.effectTag |= Update;
12972 }
12973 return false;
12974 }
12975
12976 if (typeof getDerivedStateFromProps === 'function') {
12977 applyDerivedStateFromProps(workInProgress, ctor, getDerivedStateFromProps, newProps);
12978 newState = workInProgress.memoizedState;
12979 }
12980
12981 var shouldUpdate = checkHasForceUpdateAfterProcessing() || checkShouldComponentUpdate(workInProgress, ctor, oldProps, newProps, oldState, newState, nextContext);
12982
12983 if (shouldUpdate) {
12984 // In order to support react-lifecycles-compat polyfilled components,
12985 // Unsafe lifecycles should not be invoked for components using the new APIs.
12986 if (!hasNewLifecycles && (typeof instance.UNSAFE_componentWillMount === 'function' || typeof instance.componentWillMount === 'function')) {
12987 startPhaseTimer(workInProgress, 'componentWillMount');
12988 if (typeof instance.componentWillMount === 'function') {
12989 instance.componentWillMount();
12990 }
12991 if (typeof instance.UNSAFE_componentWillMount === 'function') {
12992 instance.UNSAFE_componentWillMount();
12993 }
12994 stopPhaseTimer();
12995 }
12996 if (typeof instance.componentDidMount === 'function') {
12997 workInProgress.effectTag |= Update;
12998 }
12999 } else {
13000 // If an update was already in progress, we should schedule an Update
13001 // effect even though we're bailing out, so that cWU/cDU are called.
13002 if (typeof instance.componentDidMount === 'function') {
13003 workInProgress.effectTag |= Update;
13004 }
13005
13006 // If shouldComponentUpdate returned false, we should still update the
13007 // memoized state to indicate that this work can be reused.
13008 workInProgress.memoizedProps = newProps;
13009 workInProgress.memoizedState = newState;
13010 }
13011
13012 // Update the existing instance's state, props, and context pointers even
13013 // if shouldComponentUpdate returns false.
13014 instance.props = newProps;
13015 instance.state = newState;
13016 instance.context = nextContext;
13017
13018 return shouldUpdate;
13019}
13020
13021// Invokes the update life-cycles and returns false if it shouldn't rerender.
13022function updateClassInstance(current, workInProgress, ctor, newProps, renderExpirationTime) {
13023 var instance = workInProgress.stateNode;
13024
13025 var oldProps = workInProgress.memoizedProps;
13026 instance.props = workInProgress.type === workInProgress.elementType ? oldProps : resolveDefaultProps(workInProgress.type, oldProps);
13027
13028 var oldContext = instance.context;
13029 var contextType = ctor.contextType;
13030 var nextContext = void 0;
13031 if (typeof contextType === 'object' && contextType !== null) {
13032 nextContext = readContext$1(contextType);
13033 } else {
13034 var nextUnmaskedContext = getUnmaskedContext(workInProgress, ctor, true);
13035 nextContext = getMaskedContext(workInProgress, nextUnmaskedContext);
13036 }
13037
13038 var getDerivedStateFromProps = ctor.getDerivedStateFromProps;
13039 var hasNewLifecycles = typeof getDerivedStateFromProps === 'function' || typeof instance.getSnapshotBeforeUpdate === 'function';
13040
13041 // Note: During these life-cycles, instance.props/instance.state are what
13042 // ever the previously attempted to render - not the "current". However,
13043 // during componentDidUpdate we pass the "current" props.
13044
13045 // In order to support react-lifecycles-compat polyfilled components,
13046 // Unsafe lifecycles should not be invoked for components using the new APIs.
13047 if (!hasNewLifecycles && (typeof instance.UNSAFE_componentWillReceiveProps === 'function' || typeof instance.componentWillReceiveProps === 'function')) {
13048 if (oldProps !== newProps || oldContext !== nextContext) {
13049 callComponentWillReceiveProps(workInProgress, instance, newProps, nextContext);
13050 }
13051 }
13052
13053 resetHasForceUpdateBeforeProcessing();
13054
13055 var oldState = workInProgress.memoizedState;
13056 var newState = instance.state = oldState;
13057 var updateQueue = workInProgress.updateQueue;
13058 if (updateQueue !== null) {
13059 processUpdateQueue(workInProgress, updateQueue, newProps, instance, renderExpirationTime);
13060 newState = workInProgress.memoizedState;
13061 }
13062
13063 if (oldProps === newProps && oldState === newState && !hasContextChanged() && !checkHasForceUpdateAfterProcessing()) {
13064 // If an update was already in progress, we should schedule an Update
13065 // effect even though we're bailing out, so that cWU/cDU are called.
13066 if (typeof instance.componentDidUpdate === 'function') {
13067 if (oldProps !== current.memoizedProps || oldState !== current.memoizedState) {
13068 workInProgress.effectTag |= Update;
13069 }
13070 }
13071 if (typeof instance.getSnapshotBeforeUpdate === 'function') {
13072 if (oldProps !== current.memoizedProps || oldState !== current.memoizedState) {
13073 workInProgress.effectTag |= Snapshot;
13074 }
13075 }
13076 return false;
13077 }
13078
13079 if (typeof getDerivedStateFromProps === 'function') {
13080 applyDerivedStateFromProps(workInProgress, ctor, getDerivedStateFromProps, newProps);
13081 newState = workInProgress.memoizedState;
13082 }
13083
13084 var shouldUpdate = checkHasForceUpdateAfterProcessing() || checkShouldComponentUpdate(workInProgress, ctor, oldProps, newProps, oldState, newState, nextContext);
13085
13086 if (shouldUpdate) {
13087 // In order to support react-lifecycles-compat polyfilled components,
13088 // Unsafe lifecycles should not be invoked for components using the new APIs.
13089 if (!hasNewLifecycles && (typeof instance.UNSAFE_componentWillUpdate === 'function' || typeof instance.componentWillUpdate === 'function')) {
13090 startPhaseTimer(workInProgress, 'componentWillUpdate');
13091 if (typeof instance.componentWillUpdate === 'function') {
13092 instance.componentWillUpdate(newProps, newState, nextContext);
13093 }
13094 if (typeof instance.UNSAFE_componentWillUpdate === 'function') {
13095 instance.UNSAFE_componentWillUpdate(newProps, newState, nextContext);
13096 }
13097 stopPhaseTimer();
13098 }
13099 if (typeof instance.componentDidUpdate === 'function') {
13100 workInProgress.effectTag |= Update;
13101 }
13102 if (typeof instance.getSnapshotBeforeUpdate === 'function') {
13103 workInProgress.effectTag |= Snapshot;
13104 }
13105 } else {
13106 // If an update was already in progress, we should schedule an Update
13107 // effect even though we're bailing out, so that cWU/cDU are called.
13108 if (typeof instance.componentDidUpdate === 'function') {
13109 if (oldProps !== current.memoizedProps || oldState !== current.memoizedState) {
13110 workInProgress.effectTag |= Update;
13111 }
13112 }
13113 if (typeof instance.getSnapshotBeforeUpdate === 'function') {
13114 if (oldProps !== current.memoizedProps || oldState !== current.memoizedState) {
13115 workInProgress.effectTag |= Snapshot;
13116 }
13117 }
13118
13119 // If shouldComponentUpdate returned false, we should still update the
13120 // memoized props/state to indicate that this work can be reused.
13121 workInProgress.memoizedProps = newProps;
13122 workInProgress.memoizedState = newState;
13123 }
13124
13125 // Update the existing instance's state, props, and context pointers even
13126 // if shouldComponentUpdate returns false.
13127 instance.props = newProps;
13128 instance.state = newState;
13129 instance.context = nextContext;
13130
13131 return shouldUpdate;
13132}
13133
13134var didWarnAboutMaps = void 0;
13135var didWarnAboutGenerators = void 0;
13136var didWarnAboutStringRefInStrictMode = void 0;
13137var ownerHasKeyUseWarning = void 0;
13138var ownerHasFunctionTypeWarning = void 0;
13139var warnForMissingKey = function (child) {};
13140
13141{
13142 didWarnAboutMaps = false;
13143 didWarnAboutGenerators = false;
13144 didWarnAboutStringRefInStrictMode = {};
13145
13146 /**
13147 * Warn if there's no key explicitly set on dynamic arrays of children or
13148 * object keys are not valid. This allows us to keep track of children between
13149 * updates.
13150 */
13151 ownerHasKeyUseWarning = {};
13152 ownerHasFunctionTypeWarning = {};
13153
13154 warnForMissingKey = function (child) {
13155 if (child === null || typeof child !== 'object') {
13156 return;
13157 }
13158 if (!child._store || child._store.validated || child.key != null) {
13159 return;
13160 }
13161 !(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;
13162 child._store.validated = true;
13163
13164 var currentComponentErrorInfo = 'Each child in an array or iterator should have a unique ' + '"key" prop. See https://fb.me/react-warning-keys for ' + 'more information.' + getCurrentFiberStackInDev();
13165 if (ownerHasKeyUseWarning[currentComponentErrorInfo]) {
13166 return;
13167 }
13168 ownerHasKeyUseWarning[currentComponentErrorInfo] = true;
13169
13170 warning$1(false, 'Each child in an array or iterator should have a unique ' + '"key" prop. See https://fb.me/react-warning-keys for ' + 'more information.');
13171 };
13172}
13173
13174var isArray = Array.isArray;
13175
13176function coerceRef(returnFiber, current$$1, element) {
13177 var mixedRef = element.ref;
13178 if (mixedRef !== null && typeof mixedRef !== 'function' && typeof mixedRef !== 'object') {
13179 {
13180 if (returnFiber.mode & StrictMode) {
13181 var componentName = getComponentName(returnFiber.type) || 'Component';
13182 if (!didWarnAboutStringRefInStrictMode[componentName]) {
13183 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));
13184 didWarnAboutStringRefInStrictMode[componentName] = true;
13185 }
13186 }
13187 }
13188
13189 if (element._owner) {
13190 var owner = element._owner;
13191 var inst = void 0;
13192 if (owner) {
13193 var ownerFiber = owner;
13194 !(ownerFiber.tag === ClassComponent) ? invariant(false, 'Function components cannot have refs.') : void 0;
13195 inst = ownerFiber.stateNode;
13196 }
13197 !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;
13198 var stringRef = '' + mixedRef;
13199 // Check if previous string ref matches new string ref
13200 if (current$$1 !== null && current$$1.ref !== null && typeof current$$1.ref === 'function' && current$$1.ref._stringRef === stringRef) {
13201 return current$$1.ref;
13202 }
13203 var ref = function (value) {
13204 var refs = inst.refs;
13205 if (refs === emptyRefsObject) {
13206 // This is a lazy pooled frozen object, so we need to initialize.
13207 refs = inst.refs = {};
13208 }
13209 if (value === null) {
13210 delete refs[stringRef];
13211 } else {
13212 refs[stringRef] = value;
13213 }
13214 };
13215 ref._stringRef = stringRef;
13216 return ref;
13217 } else {
13218 !(typeof mixedRef === 'string') ? invariant(false, 'Expected ref to be a function, a string, an object returned by React.createRef(), or null.') : void 0;
13219 !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;
13220 }
13221 }
13222 return mixedRef;
13223}
13224
13225function throwOnInvalidObjectType(returnFiber, newChild) {
13226 if (returnFiber.type !== 'textarea') {
13227 var addendum = '';
13228 {
13229 addendum = ' If you meant to render a collection of children, use an array ' + 'instead.' + getCurrentFiberStackInDev();
13230 }
13231 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);
13232 }
13233}
13234
13235function warnOnFunctionType() {
13236 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();
13237
13238 if (ownerHasFunctionTypeWarning[currentComponentErrorInfo]) {
13239 return;
13240 }
13241 ownerHasFunctionTypeWarning[currentComponentErrorInfo] = true;
13242
13243 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.');
13244}
13245
13246// This wrapper function exists because I expect to clone the code in each path
13247// to be able to optimize each path individually by branching early. This needs
13248// a compiler or we can do it manually. Helpers that don't need this branching
13249// live outside of this function.
13250function ChildReconciler(shouldTrackSideEffects) {
13251 function deleteChild(returnFiber, childToDelete) {
13252 if (!shouldTrackSideEffects) {
13253 // Noop.
13254 return;
13255 }
13256 // Deletions are added in reversed order so we add it to the front.
13257 // At this point, the return fiber's effect list is empty except for
13258 // deletions, so we can just append the deletion to the list. The remaining
13259 // effects aren't added until the complete phase. Once we implement
13260 // resuming, this may not be true.
13261 var last = returnFiber.lastEffect;
13262 if (last !== null) {
13263 last.nextEffect = childToDelete;
13264 returnFiber.lastEffect = childToDelete;
13265 } else {
13266 returnFiber.firstEffect = returnFiber.lastEffect = childToDelete;
13267 }
13268 childToDelete.nextEffect = null;
13269 childToDelete.effectTag = Deletion;
13270 }
13271
13272 function deleteRemainingChildren(returnFiber, currentFirstChild) {
13273 if (!shouldTrackSideEffects) {
13274 // Noop.
13275 return null;
13276 }
13277
13278 // TODO: For the shouldClone case, this could be micro-optimized a bit by
13279 // assuming that after the first child we've already added everything.
13280 var childToDelete = currentFirstChild;
13281 while (childToDelete !== null) {
13282 deleteChild(returnFiber, childToDelete);
13283 childToDelete = childToDelete.sibling;
13284 }
13285 return null;
13286 }
13287
13288 function mapRemainingChildren(returnFiber, currentFirstChild) {
13289 // Add the remaining children to a temporary map so that we can find them by
13290 // keys quickly. Implicit (null) keys get added to this set with their index
13291 var existingChildren = new Map();
13292
13293 var existingChild = currentFirstChild;
13294 while (existingChild !== null) {
13295 if (existingChild.key !== null) {
13296 existingChildren.set(existingChild.key, existingChild);
13297 } else {
13298 existingChildren.set(existingChild.index, existingChild);
13299 }
13300 existingChild = existingChild.sibling;
13301 }
13302 return existingChildren;
13303 }
13304
13305 function useFiber(fiber, pendingProps, expirationTime) {
13306 // We currently set sibling to null and index to 0 here because it is easy
13307 // to forget to do before returning it. E.g. for the single child case.
13308 var clone = createWorkInProgress(fiber, pendingProps, expirationTime);
13309 clone.index = 0;
13310 clone.sibling = null;
13311 return clone;
13312 }
13313
13314 function placeChild(newFiber, lastPlacedIndex, newIndex) {
13315 newFiber.index = newIndex;
13316 if (!shouldTrackSideEffects) {
13317 // Noop.
13318 return lastPlacedIndex;
13319 }
13320 var current$$1 = newFiber.alternate;
13321 if (current$$1 !== null) {
13322 var oldIndex = current$$1.index;
13323 if (oldIndex < lastPlacedIndex) {
13324 // This is a move.
13325 newFiber.effectTag = Placement;
13326 return lastPlacedIndex;
13327 } else {
13328 // This item can stay in place.
13329 return oldIndex;
13330 }
13331 } else {
13332 // This is an insertion.
13333 newFiber.effectTag = Placement;
13334 return lastPlacedIndex;
13335 }
13336 }
13337
13338 function placeSingleChild(newFiber) {
13339 // This is simpler for the single child case. We only need to do a
13340 // placement for inserting new children.
13341 if (shouldTrackSideEffects && newFiber.alternate === null) {
13342 newFiber.effectTag = Placement;
13343 }
13344 return newFiber;
13345 }
13346
13347 function updateTextNode(returnFiber, current$$1, textContent, expirationTime) {
13348 if (current$$1 === null || current$$1.tag !== HostText) {
13349 // Insert
13350 var created = createFiberFromText(textContent, returnFiber.mode, expirationTime);
13351 created.return = returnFiber;
13352 return created;
13353 } else {
13354 // Update
13355 var existing = useFiber(current$$1, textContent, expirationTime);
13356 existing.return = returnFiber;
13357 return existing;
13358 }
13359 }
13360
13361 function updateElement(returnFiber, current$$1, element, expirationTime) {
13362 if (current$$1 !== null && current$$1.elementType === element.type) {
13363 // Move based on index
13364 var existing = useFiber(current$$1, element.props, expirationTime);
13365 existing.ref = coerceRef(returnFiber, current$$1, element);
13366 existing.return = returnFiber;
13367 {
13368 existing._debugSource = element._source;
13369 existing._debugOwner = element._owner;
13370 }
13371 return existing;
13372 } else {
13373 // Insert
13374 var created = createFiberFromElement(element, returnFiber.mode, expirationTime);
13375 created.ref = coerceRef(returnFiber, current$$1, element);
13376 created.return = returnFiber;
13377 return created;
13378 }
13379 }
13380
13381 function updatePortal(returnFiber, current$$1, portal, expirationTime) {
13382 if (current$$1 === null || current$$1.tag !== HostPortal || current$$1.stateNode.containerInfo !== portal.containerInfo || current$$1.stateNode.implementation !== portal.implementation) {
13383 // Insert
13384 var created = createFiberFromPortal(portal, returnFiber.mode, expirationTime);
13385 created.return = returnFiber;
13386 return created;
13387 } else {
13388 // Update
13389 var existing = useFiber(current$$1, portal.children || [], expirationTime);
13390 existing.return = returnFiber;
13391 return existing;
13392 }
13393 }
13394
13395 function updateFragment(returnFiber, current$$1, fragment, expirationTime, key) {
13396 if (current$$1 === null || current$$1.tag !== Fragment) {
13397 // Insert
13398 var created = createFiberFromFragment(fragment, returnFiber.mode, expirationTime, key);
13399 created.return = returnFiber;
13400 return created;
13401 } else {
13402 // Update
13403 var existing = useFiber(current$$1, fragment, expirationTime);
13404 existing.return = returnFiber;
13405 return existing;
13406 }
13407 }
13408
13409 function createChild(returnFiber, newChild, expirationTime) {
13410 if (typeof newChild === 'string' || typeof newChild === 'number') {
13411 // Text nodes don't have keys. If the previous node is implicitly keyed
13412 // we can continue to replace it without aborting even if it is not a text
13413 // node.
13414 var created = createFiberFromText('' + newChild, returnFiber.mode, expirationTime);
13415 created.return = returnFiber;
13416 return created;
13417 }
13418
13419 if (typeof newChild === 'object' && newChild !== null) {
13420 switch (newChild.$$typeof) {
13421 case REACT_ELEMENT_TYPE:
13422 {
13423 var _created = createFiberFromElement(newChild, returnFiber.mode, expirationTime);
13424 _created.ref = coerceRef(returnFiber, null, newChild);
13425 _created.return = returnFiber;
13426 return _created;
13427 }
13428 case REACT_PORTAL_TYPE:
13429 {
13430 var _created2 = createFiberFromPortal(newChild, returnFiber.mode, expirationTime);
13431 _created2.return = returnFiber;
13432 return _created2;
13433 }
13434 }
13435
13436 if (isArray(newChild) || getIteratorFn(newChild)) {
13437 var _created3 = createFiberFromFragment(newChild, returnFiber.mode, expirationTime, null);
13438 _created3.return = returnFiber;
13439 return _created3;
13440 }
13441
13442 throwOnInvalidObjectType(returnFiber, newChild);
13443 }
13444
13445 {
13446 if (typeof newChild === 'function') {
13447 warnOnFunctionType();
13448 }
13449 }
13450
13451 return null;
13452 }
13453
13454 function updateSlot(returnFiber, oldFiber, newChild, expirationTime) {
13455 // Update the fiber if the keys match, otherwise return null.
13456
13457 var key = oldFiber !== null ? oldFiber.key : null;
13458
13459 if (typeof newChild === 'string' || typeof newChild === 'number') {
13460 // Text nodes don't have keys. If the previous node is implicitly keyed
13461 // we can continue to replace it without aborting even if it is not a text
13462 // node.
13463 if (key !== null) {
13464 return null;
13465 }
13466 return updateTextNode(returnFiber, oldFiber, '' + newChild, expirationTime);
13467 }
13468
13469 if (typeof newChild === 'object' && newChild !== null) {
13470 switch (newChild.$$typeof) {
13471 case REACT_ELEMENT_TYPE:
13472 {
13473 if (newChild.key === key) {
13474 if (newChild.type === REACT_FRAGMENT_TYPE) {
13475 return updateFragment(returnFiber, oldFiber, newChild.props.children, expirationTime, key);
13476 }
13477 return updateElement(returnFiber, oldFiber, newChild, expirationTime);
13478 } else {
13479 return null;
13480 }
13481 }
13482 case REACT_PORTAL_TYPE:
13483 {
13484 if (newChild.key === key) {
13485 return updatePortal(returnFiber, oldFiber, newChild, expirationTime);
13486 } else {
13487 return null;
13488 }
13489 }
13490 }
13491
13492 if (isArray(newChild) || getIteratorFn(newChild)) {
13493 if (key !== null) {
13494 return null;
13495 }
13496
13497 return updateFragment(returnFiber, oldFiber, newChild, expirationTime, null);
13498 }
13499
13500 throwOnInvalidObjectType(returnFiber, newChild);
13501 }
13502
13503 {
13504 if (typeof newChild === 'function') {
13505 warnOnFunctionType();
13506 }
13507 }
13508
13509 return null;
13510 }
13511
13512 function updateFromMap(existingChildren, returnFiber, newIdx, newChild, expirationTime) {
13513 if (typeof newChild === 'string' || typeof newChild === 'number') {
13514 // Text nodes don't have keys, so we neither have to check the old nor
13515 // new node for the key. If both are text nodes, they match.
13516 var matchedFiber = existingChildren.get(newIdx) || null;
13517 return updateTextNode(returnFiber, matchedFiber, '' + newChild, expirationTime);
13518 }
13519
13520 if (typeof newChild === 'object' && newChild !== null) {
13521 switch (newChild.$$typeof) {
13522 case REACT_ELEMENT_TYPE:
13523 {
13524 var _matchedFiber = existingChildren.get(newChild.key === null ? newIdx : newChild.key) || null;
13525 if (newChild.type === REACT_FRAGMENT_TYPE) {
13526 return updateFragment(returnFiber, _matchedFiber, newChild.props.children, expirationTime, newChild.key);
13527 }
13528 return updateElement(returnFiber, _matchedFiber, newChild, expirationTime);
13529 }
13530 case REACT_PORTAL_TYPE:
13531 {
13532 var _matchedFiber2 = existingChildren.get(newChild.key === null ? newIdx : newChild.key) || null;
13533 return updatePortal(returnFiber, _matchedFiber2, newChild, expirationTime);
13534 }
13535 }
13536
13537 if (isArray(newChild) || getIteratorFn(newChild)) {
13538 var _matchedFiber3 = existingChildren.get(newIdx) || null;
13539 return updateFragment(returnFiber, _matchedFiber3, newChild, expirationTime, null);
13540 }
13541
13542 throwOnInvalidObjectType(returnFiber, newChild);
13543 }
13544
13545 {
13546 if (typeof newChild === 'function') {
13547 warnOnFunctionType();
13548 }
13549 }
13550
13551 return null;
13552 }
13553
13554 /**
13555 * Warns if there is a duplicate or missing key
13556 */
13557 function warnOnInvalidKey(child, knownKeys) {
13558 {
13559 if (typeof child !== 'object' || child === null) {
13560 return knownKeys;
13561 }
13562 switch (child.$$typeof) {
13563 case REACT_ELEMENT_TYPE:
13564 case REACT_PORTAL_TYPE:
13565 warnForMissingKey(child);
13566 var key = child.key;
13567 if (typeof key !== 'string') {
13568 break;
13569 }
13570 if (knownKeys === null) {
13571 knownKeys = new Set();
13572 knownKeys.add(key);
13573 break;
13574 }
13575 if (!knownKeys.has(key)) {
13576 knownKeys.add(key);
13577 break;
13578 }
13579 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);
13580 break;
13581 default:
13582 break;
13583 }
13584 }
13585 return knownKeys;
13586 }
13587
13588 function reconcileChildrenArray(returnFiber, currentFirstChild, newChildren, expirationTime) {
13589 // This algorithm can't optimize by searching from boths ends since we
13590 // don't have backpointers on fibers. I'm trying to see how far we can get
13591 // with that model. If it ends up not being worth the tradeoffs, we can
13592 // add it later.
13593
13594 // Even with a two ended optimization, we'd want to optimize for the case
13595 // where there are few changes and brute force the comparison instead of
13596 // going for the Map. It'd like to explore hitting that path first in
13597 // forward-only mode and only go for the Map once we notice that we need
13598 // lots of look ahead. This doesn't handle reversal as well as two ended
13599 // search but that's unusual. Besides, for the two ended optimization to
13600 // work on Iterables, we'd need to copy the whole set.
13601
13602 // In this first iteration, we'll just live with hitting the bad case
13603 // (adding everything to a Map) in for every insert/move.
13604
13605 // If you change this code, also update reconcileChildrenIterator() which
13606 // uses the same algorithm.
13607
13608 {
13609 // First, validate keys.
13610 var knownKeys = null;
13611 for (var i = 0; i < newChildren.length; i++) {
13612 var child = newChildren[i];
13613 knownKeys = warnOnInvalidKey(child, knownKeys);
13614 }
13615 }
13616
13617 var resultingFirstChild = null;
13618 var previousNewFiber = null;
13619
13620 var oldFiber = currentFirstChild;
13621 var lastPlacedIndex = 0;
13622 var newIdx = 0;
13623 var nextOldFiber = null;
13624 for (; oldFiber !== null && newIdx < newChildren.length; newIdx++) {
13625 if (oldFiber.index > newIdx) {
13626 nextOldFiber = oldFiber;
13627 oldFiber = null;
13628 } else {
13629 nextOldFiber = oldFiber.sibling;
13630 }
13631 var newFiber = updateSlot(returnFiber, oldFiber, newChildren[newIdx], expirationTime);
13632 if (newFiber === null) {
13633 // TODO: This breaks on empty slots like null children. That's
13634 // unfortunate because it triggers the slow path all the time. We need
13635 // a better way to communicate whether this was a miss or null,
13636 // boolean, undefined, etc.
13637 if (oldFiber === null) {
13638 oldFiber = nextOldFiber;
13639 }
13640 break;
13641 }
13642 if (shouldTrackSideEffects) {
13643 if (oldFiber && newFiber.alternate === null) {
13644 // We matched the slot, but we didn't reuse the existing fiber, so we
13645 // need to delete the existing child.
13646 deleteChild(returnFiber, oldFiber);
13647 }
13648 }
13649 lastPlacedIndex = placeChild(newFiber, lastPlacedIndex, newIdx);
13650 if (previousNewFiber === null) {
13651 // TODO: Move out of the loop. This only happens for the first run.
13652 resultingFirstChild = newFiber;
13653 } else {
13654 // TODO: Defer siblings if we're not at the right index for this slot.
13655 // I.e. if we had null values before, then we want to defer this
13656 // for each null value. However, we also don't want to call updateSlot
13657 // with the previous one.
13658 previousNewFiber.sibling = newFiber;
13659 }
13660 previousNewFiber = newFiber;
13661 oldFiber = nextOldFiber;
13662 }
13663
13664 if (newIdx === newChildren.length) {
13665 // We've reached the end of the new children. We can delete the rest.
13666 deleteRemainingChildren(returnFiber, oldFiber);
13667 return resultingFirstChild;
13668 }
13669
13670 if (oldFiber === null) {
13671 // If we don't have any more existing children we can choose a fast path
13672 // since the rest will all be insertions.
13673 for (; newIdx < newChildren.length; newIdx++) {
13674 var _newFiber = createChild(returnFiber, newChildren[newIdx], expirationTime);
13675 if (!_newFiber) {
13676 continue;
13677 }
13678 lastPlacedIndex = placeChild(_newFiber, lastPlacedIndex, newIdx);
13679 if (previousNewFiber === null) {
13680 // TODO: Move out of the loop. This only happens for the first run.
13681 resultingFirstChild = _newFiber;
13682 } else {
13683 previousNewFiber.sibling = _newFiber;
13684 }
13685 previousNewFiber = _newFiber;
13686 }
13687 return resultingFirstChild;
13688 }
13689
13690 // Add all children to a key map for quick lookups.
13691 var existingChildren = mapRemainingChildren(returnFiber, oldFiber);
13692
13693 // Keep scanning and use the map to restore deleted items as moves.
13694 for (; newIdx < newChildren.length; newIdx++) {
13695 var _newFiber2 = updateFromMap(existingChildren, returnFiber, newIdx, newChildren[newIdx], expirationTime);
13696 if (_newFiber2) {
13697 if (shouldTrackSideEffects) {
13698 if (_newFiber2.alternate !== null) {
13699 // The new fiber is a work in progress, but if there exists a
13700 // current, that means that we reused the fiber. We need to delete
13701 // it from the child list so that we don't add it to the deletion
13702 // list.
13703 existingChildren.delete(_newFiber2.key === null ? newIdx : _newFiber2.key);
13704 }
13705 }
13706 lastPlacedIndex = placeChild(_newFiber2, lastPlacedIndex, newIdx);
13707 if (previousNewFiber === null) {
13708 resultingFirstChild = _newFiber2;
13709 } else {
13710 previousNewFiber.sibling = _newFiber2;
13711 }
13712 previousNewFiber = _newFiber2;
13713 }
13714 }
13715
13716 if (shouldTrackSideEffects) {
13717 // Any existing children that weren't consumed above were deleted. We need
13718 // to add them to the deletion list.
13719 existingChildren.forEach(function (child) {
13720 return deleteChild(returnFiber, child);
13721 });
13722 }
13723
13724 return resultingFirstChild;
13725 }
13726
13727 function reconcileChildrenIterator(returnFiber, currentFirstChild, newChildrenIterable, expirationTime) {
13728 // This is the same implementation as reconcileChildrenArray(),
13729 // but using the iterator instead.
13730
13731 var iteratorFn = getIteratorFn(newChildrenIterable);
13732 !(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;
13733
13734 {
13735 // We don't support rendering Generators because it's a mutation.
13736 // See https://github.com/facebook/react/issues/12995
13737 if (typeof Symbol === 'function' &&
13738 // $FlowFixMe Flow doesn't know about toStringTag
13739 newChildrenIterable[Symbol.toStringTag] === 'Generator') {
13740 !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;
13741 didWarnAboutGenerators = true;
13742 }
13743
13744 // Warn about using Maps as children
13745 if (newChildrenIterable.entries === iteratorFn) {
13746 !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;
13747 didWarnAboutMaps = true;
13748 }
13749
13750 // First, validate keys.
13751 // We'll get a different iterator later for the main pass.
13752 var _newChildren = iteratorFn.call(newChildrenIterable);
13753 if (_newChildren) {
13754 var knownKeys = null;
13755 var _step = _newChildren.next();
13756 for (; !_step.done; _step = _newChildren.next()) {
13757 var child = _step.value;
13758 knownKeys = warnOnInvalidKey(child, knownKeys);
13759 }
13760 }
13761 }
13762
13763 var newChildren = iteratorFn.call(newChildrenIterable);
13764 !(newChildren != null) ? invariant(false, 'An iterable object provided no iterator.') : void 0;
13765
13766 var resultingFirstChild = null;
13767 var previousNewFiber = null;
13768
13769 var oldFiber = currentFirstChild;
13770 var lastPlacedIndex = 0;
13771 var newIdx = 0;
13772 var nextOldFiber = null;
13773
13774 var step = newChildren.next();
13775 for (; oldFiber !== null && !step.done; newIdx++, step = newChildren.next()) {
13776 if (oldFiber.index > newIdx) {
13777 nextOldFiber = oldFiber;
13778 oldFiber = null;
13779 } else {
13780 nextOldFiber = oldFiber.sibling;
13781 }
13782 var newFiber = updateSlot(returnFiber, oldFiber, step.value, expirationTime);
13783 if (newFiber === null) {
13784 // TODO: This breaks on empty slots like null children. That's
13785 // unfortunate because it triggers the slow path all the time. We need
13786 // a better way to communicate whether this was a miss or null,
13787 // boolean, undefined, etc.
13788 if (!oldFiber) {
13789 oldFiber = nextOldFiber;
13790 }
13791 break;
13792 }
13793 if (shouldTrackSideEffects) {
13794 if (oldFiber && newFiber.alternate === null) {
13795 // We matched the slot, but we didn't reuse the existing fiber, so we
13796 // need to delete the existing child.
13797 deleteChild(returnFiber, oldFiber);
13798 }
13799 }
13800 lastPlacedIndex = placeChild(newFiber, lastPlacedIndex, newIdx);
13801 if (previousNewFiber === null) {
13802 // TODO: Move out of the loop. This only happens for the first run.
13803 resultingFirstChild = newFiber;
13804 } else {
13805 // TODO: Defer siblings if we're not at the right index for this slot.
13806 // I.e. if we had null values before, then we want to defer this
13807 // for each null value. However, we also don't want to call updateSlot
13808 // with the previous one.
13809 previousNewFiber.sibling = newFiber;
13810 }
13811 previousNewFiber = newFiber;
13812 oldFiber = nextOldFiber;
13813 }
13814
13815 if (step.done) {
13816 // We've reached the end of the new children. We can delete the rest.
13817 deleteRemainingChildren(returnFiber, oldFiber);
13818 return resultingFirstChild;
13819 }
13820
13821 if (oldFiber === null) {
13822 // If we don't have any more existing children we can choose a fast path
13823 // since the rest will all be insertions.
13824 for (; !step.done; newIdx++, step = newChildren.next()) {
13825 var _newFiber3 = createChild(returnFiber, step.value, expirationTime);
13826 if (_newFiber3 === null) {
13827 continue;
13828 }
13829 lastPlacedIndex = placeChild(_newFiber3, lastPlacedIndex, newIdx);
13830 if (previousNewFiber === null) {
13831 // TODO: Move out of the loop. This only happens for the first run.
13832 resultingFirstChild = _newFiber3;
13833 } else {
13834 previousNewFiber.sibling = _newFiber3;
13835 }
13836 previousNewFiber = _newFiber3;
13837 }
13838 return resultingFirstChild;
13839 }
13840
13841 // Add all children to a key map for quick lookups.
13842 var existingChildren = mapRemainingChildren(returnFiber, oldFiber);
13843
13844 // Keep scanning and use the map to restore deleted items as moves.
13845 for (; !step.done; newIdx++, step = newChildren.next()) {
13846 var _newFiber4 = updateFromMap(existingChildren, returnFiber, newIdx, step.value, expirationTime);
13847 if (_newFiber4 !== null) {
13848 if (shouldTrackSideEffects) {
13849 if (_newFiber4.alternate !== null) {
13850 // The new fiber is a work in progress, but if there exists a
13851 // current, that means that we reused the fiber. We need to delete
13852 // it from the child list so that we don't add it to the deletion
13853 // list.
13854 existingChildren.delete(_newFiber4.key === null ? newIdx : _newFiber4.key);
13855 }
13856 }
13857 lastPlacedIndex = placeChild(_newFiber4, lastPlacedIndex, newIdx);
13858 if (previousNewFiber === null) {
13859 resultingFirstChild = _newFiber4;
13860 } else {
13861 previousNewFiber.sibling = _newFiber4;
13862 }
13863 previousNewFiber = _newFiber4;
13864 }
13865 }
13866
13867 if (shouldTrackSideEffects) {
13868 // Any existing children that weren't consumed above were deleted. We need
13869 // to add them to the deletion list.
13870 existingChildren.forEach(function (child) {
13871 return deleteChild(returnFiber, child);
13872 });
13873 }
13874
13875 return resultingFirstChild;
13876 }
13877
13878 function reconcileSingleTextNode(returnFiber, currentFirstChild, textContent, expirationTime) {
13879 // There's no need to check for keys on text nodes since we don't have a
13880 // way to define them.
13881 if (currentFirstChild !== null && currentFirstChild.tag === HostText) {
13882 // We already have an existing node so let's just update it and delete
13883 // the rest.
13884 deleteRemainingChildren(returnFiber, currentFirstChild.sibling);
13885 var existing = useFiber(currentFirstChild, textContent, expirationTime);
13886 existing.return = returnFiber;
13887 return existing;
13888 }
13889 // The existing first child is not a text node so we need to create one
13890 // and delete the existing ones.
13891 deleteRemainingChildren(returnFiber, currentFirstChild);
13892 var created = createFiberFromText(textContent, returnFiber.mode, expirationTime);
13893 created.return = returnFiber;
13894 return created;
13895 }
13896
13897 function reconcileSingleElement(returnFiber, currentFirstChild, element, expirationTime) {
13898 var key = element.key;
13899 var child = currentFirstChild;
13900 while (child !== null) {
13901 // TODO: If key === null and child.key === null, then this only applies to
13902 // the first item in the list.
13903 if (child.key === key) {
13904 if (child.tag === Fragment ? element.type === REACT_FRAGMENT_TYPE : child.elementType === element.type) {
13905 deleteRemainingChildren(returnFiber, child.sibling);
13906 var existing = useFiber(child, element.type === REACT_FRAGMENT_TYPE ? element.props.children : element.props, expirationTime);
13907 existing.ref = coerceRef(returnFiber, child, element);
13908 existing.return = returnFiber;
13909 {
13910 existing._debugSource = element._source;
13911 existing._debugOwner = element._owner;
13912 }
13913 return existing;
13914 } else {
13915 deleteRemainingChildren(returnFiber, child);
13916 break;
13917 }
13918 } else {
13919 deleteChild(returnFiber, child);
13920 }
13921 child = child.sibling;
13922 }
13923
13924 if (element.type === REACT_FRAGMENT_TYPE) {
13925 var created = createFiberFromFragment(element.props.children, returnFiber.mode, expirationTime, element.key);
13926 created.return = returnFiber;
13927 return created;
13928 } else {
13929 var _created4 = createFiberFromElement(element, returnFiber.mode, expirationTime);
13930 _created4.ref = coerceRef(returnFiber, currentFirstChild, element);
13931 _created4.return = returnFiber;
13932 return _created4;
13933 }
13934 }
13935
13936 function reconcileSinglePortal(returnFiber, currentFirstChild, portal, expirationTime) {
13937 var key = portal.key;
13938 var child = currentFirstChild;
13939 while (child !== null) {
13940 // TODO: If key === null and child.key === null, then this only applies to
13941 // the first item in the list.
13942 if (child.key === key) {
13943 if (child.tag === HostPortal && child.stateNode.containerInfo === portal.containerInfo && child.stateNode.implementation === portal.implementation) {
13944 deleteRemainingChildren(returnFiber, child.sibling);
13945 var existing = useFiber(child, portal.children || [], expirationTime);
13946 existing.return = returnFiber;
13947 return existing;
13948 } else {
13949 deleteRemainingChildren(returnFiber, child);
13950 break;
13951 }
13952 } else {
13953 deleteChild(returnFiber, child);
13954 }
13955 child = child.sibling;
13956 }
13957
13958 var created = createFiberFromPortal(portal, returnFiber.mode, expirationTime);
13959 created.return = returnFiber;
13960 return created;
13961 }
13962
13963 // This API will tag the children with the side-effect of the reconciliation
13964 // itself. They will be added to the side-effect list as we pass through the
13965 // children and the parent.
13966 function reconcileChildFibers(returnFiber, currentFirstChild, newChild, expirationTime) {
13967 // This function is not recursive.
13968 // If the top level item is an array, we treat it as a set of children,
13969 // not as a fragment. Nested arrays on the other hand will be treated as
13970 // fragment nodes. Recursion happens at the normal flow.
13971
13972 // Handle top level unkeyed fragments as if they were arrays.
13973 // This leads to an ambiguity between <>{[...]}</> and <>...</>.
13974 // We treat the ambiguous cases above the same.
13975 var isUnkeyedTopLevelFragment = typeof newChild === 'object' && newChild !== null && newChild.type === REACT_FRAGMENT_TYPE && newChild.key === null;
13976 if (isUnkeyedTopLevelFragment) {
13977 newChild = newChild.props.children;
13978 }
13979
13980 // Handle object types
13981 var isObject = typeof newChild === 'object' && newChild !== null;
13982
13983 if (isObject) {
13984 switch (newChild.$$typeof) {
13985 case REACT_ELEMENT_TYPE:
13986 return placeSingleChild(reconcileSingleElement(returnFiber, currentFirstChild, newChild, expirationTime));
13987 case REACT_PORTAL_TYPE:
13988 return placeSingleChild(reconcileSinglePortal(returnFiber, currentFirstChild, newChild, expirationTime));
13989 }
13990 }
13991
13992 if (typeof newChild === 'string' || typeof newChild === 'number') {
13993 return placeSingleChild(reconcileSingleTextNode(returnFiber, currentFirstChild, '' + newChild, expirationTime));
13994 }
13995
13996 if (isArray(newChild)) {
13997 return reconcileChildrenArray(returnFiber, currentFirstChild, newChild, expirationTime);
13998 }
13999
14000 if (getIteratorFn(newChild)) {
14001 return reconcileChildrenIterator(returnFiber, currentFirstChild, newChild, expirationTime);
14002 }
14003
14004 if (isObject) {
14005 throwOnInvalidObjectType(returnFiber, newChild);
14006 }
14007
14008 {
14009 if (typeof newChild === 'function') {
14010 warnOnFunctionType();
14011 }
14012 }
14013 if (typeof newChild === 'undefined' && !isUnkeyedTopLevelFragment) {
14014 // If the new child is undefined, and the return fiber is a composite
14015 // component, throw an error. If Fiber return types are disabled,
14016 // we already threw above.
14017 switch (returnFiber.tag) {
14018 case ClassComponent:
14019 {
14020 {
14021 var instance = returnFiber.stateNode;
14022 if (instance.render._isMockFunction) {
14023 // We allow auto-mocks to proceed as if they're returning null.
14024 break;
14025 }
14026 }
14027 }
14028 // Intentionally fall through to the next case, which handles both
14029 // functions and classes
14030 // eslint-disable-next-lined no-fallthrough
14031 case FunctionComponent:
14032 {
14033 var Component = returnFiber.type;
14034 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');
14035 }
14036 }
14037 }
14038
14039 // Remaining cases are all treated as empty.
14040 return deleteRemainingChildren(returnFiber, currentFirstChild);
14041 }
14042
14043 return reconcileChildFibers;
14044}
14045
14046var reconcileChildFibers = ChildReconciler(true);
14047var mountChildFibers = ChildReconciler(false);
14048
14049function cloneChildFibers(current$$1, workInProgress) {
14050 !(current$$1 === null || workInProgress.child === current$$1.child) ? invariant(false, 'Resuming work not yet implemented.') : void 0;
14051
14052 if (workInProgress.child === null) {
14053 return;
14054 }
14055
14056 var currentChild = workInProgress.child;
14057 var newChild = createWorkInProgress(currentChild, currentChild.pendingProps, currentChild.expirationTime);
14058 workInProgress.child = newChild;
14059
14060 newChild.return = workInProgress;
14061 while (currentChild.sibling !== null) {
14062 currentChild = currentChild.sibling;
14063 newChild = newChild.sibling = createWorkInProgress(currentChild, currentChild.pendingProps, currentChild.expirationTime);
14064 newChild.return = workInProgress;
14065 }
14066 newChild.sibling = null;
14067}
14068
14069// The deepest Fiber on the stack involved in a hydration context.
14070// This may have been an insertion or a hydration.
14071var hydrationParentFiber = null;
14072var nextHydratableInstance = null;
14073var isHydrating = false;
14074
14075function enterHydrationState(fiber) {
14076 if (!supportsHydration) {
14077 return false;
14078 }
14079
14080 var parentInstance = fiber.stateNode.containerInfo;
14081 nextHydratableInstance = getFirstHydratableChild(parentInstance);
14082 hydrationParentFiber = fiber;
14083 isHydrating = true;
14084 return true;
14085}
14086
14087function deleteHydratableInstance(returnFiber, instance) {
14088 {
14089 switch (returnFiber.tag) {
14090 case HostRoot:
14091 didNotHydrateContainerInstance(returnFiber.stateNode.containerInfo, instance);
14092 break;
14093 case HostComponent:
14094 didNotHydrateInstance(returnFiber.type, returnFiber.memoizedProps, returnFiber.stateNode, instance);
14095 break;
14096 }
14097 }
14098
14099 var childToDelete = createFiberFromHostInstanceForDeletion();
14100 childToDelete.stateNode = instance;
14101 childToDelete.return = returnFiber;
14102 childToDelete.effectTag = Deletion;
14103
14104 // This might seem like it belongs on progressedFirstDeletion. However,
14105 // these children are not part of the reconciliation list of children.
14106 // Even if we abort and rereconcile the children, that will try to hydrate
14107 // again and the nodes are still in the host tree so these will be
14108 // recreated.
14109 if (returnFiber.lastEffect !== null) {
14110 returnFiber.lastEffect.nextEffect = childToDelete;
14111 returnFiber.lastEffect = childToDelete;
14112 } else {
14113 returnFiber.firstEffect = returnFiber.lastEffect = childToDelete;
14114 }
14115}
14116
14117function insertNonHydratedInstance(returnFiber, fiber) {
14118 fiber.effectTag |= Placement;
14119 {
14120 switch (returnFiber.tag) {
14121 case HostRoot:
14122 {
14123 var parentContainer = returnFiber.stateNode.containerInfo;
14124 switch (fiber.tag) {
14125 case HostComponent:
14126 var type = fiber.type;
14127 var props = fiber.pendingProps;
14128 didNotFindHydratableContainerInstance(parentContainer, type, props);
14129 break;
14130 case HostText:
14131 var text = fiber.pendingProps;
14132 didNotFindHydratableContainerTextInstance(parentContainer, text);
14133 break;
14134 }
14135 break;
14136 }
14137 case HostComponent:
14138 {
14139 var parentType = returnFiber.type;
14140 var parentProps = returnFiber.memoizedProps;
14141 var parentInstance = returnFiber.stateNode;
14142 switch (fiber.tag) {
14143 case HostComponent:
14144 var _type = fiber.type;
14145 var _props = fiber.pendingProps;
14146 didNotFindHydratableInstance(parentType, parentProps, parentInstance, _type, _props);
14147 break;
14148 case HostText:
14149 var _text = fiber.pendingProps;
14150 didNotFindHydratableTextInstance(parentType, parentProps, parentInstance, _text);
14151 break;
14152 }
14153 break;
14154 }
14155 default:
14156 return;
14157 }
14158 }
14159}
14160
14161function tryHydrate(fiber, nextInstance) {
14162 switch (fiber.tag) {
14163 case HostComponent:
14164 {
14165 var type = fiber.type;
14166 var props = fiber.pendingProps;
14167 var instance = canHydrateInstance(nextInstance, type, props);
14168 if (instance !== null) {
14169 fiber.stateNode = instance;
14170 return true;
14171 }
14172 return false;
14173 }
14174 case HostText:
14175 {
14176 var text = fiber.pendingProps;
14177 var textInstance = canHydrateTextInstance(nextInstance, text);
14178 if (textInstance !== null) {
14179 fiber.stateNode = textInstance;
14180 return true;
14181 }
14182 return false;
14183 }
14184 default:
14185 return false;
14186 }
14187}
14188
14189function tryToClaimNextHydratableInstance(fiber) {
14190 if (!isHydrating) {
14191 return;
14192 }
14193 var nextInstance = nextHydratableInstance;
14194 if (!nextInstance) {
14195 // Nothing to hydrate. Make it an insertion.
14196 insertNonHydratedInstance(hydrationParentFiber, fiber);
14197 isHydrating = false;
14198 hydrationParentFiber = fiber;
14199 return;
14200 }
14201 var firstAttemptedInstance = nextInstance;
14202 if (!tryHydrate(fiber, nextInstance)) {
14203 // If we can't hydrate this instance let's try the next one.
14204 // We use this as a heuristic. It's based on intuition and not data so it
14205 // might be flawed or unnecessary.
14206 nextInstance = getNextHydratableSibling(firstAttemptedInstance);
14207 if (!nextInstance || !tryHydrate(fiber, nextInstance)) {
14208 // Nothing to hydrate. Make it an insertion.
14209 insertNonHydratedInstance(hydrationParentFiber, fiber);
14210 isHydrating = false;
14211 hydrationParentFiber = fiber;
14212 return;
14213 }
14214 // We matched the next one, we'll now assume that the first one was
14215 // superfluous and we'll delete it. Since we can't eagerly delete it
14216 // we'll have to schedule a deletion. To do that, this node needs a dummy
14217 // fiber associated with it.
14218 deleteHydratableInstance(hydrationParentFiber, firstAttemptedInstance);
14219 }
14220 hydrationParentFiber = fiber;
14221 nextHydratableInstance = getFirstHydratableChild(nextInstance);
14222}
14223
14224function prepareToHydrateHostInstance(fiber, rootContainerInstance, hostContext) {
14225 if (!supportsHydration) {
14226 invariant(false, 'Expected prepareToHydrateHostInstance() to never be called. This error is likely caused by a bug in React. Please file an issue.');
14227 }
14228
14229 var instance = fiber.stateNode;
14230 var updatePayload = hydrateInstance(instance, fiber.type, fiber.memoizedProps, rootContainerInstance, hostContext, fiber);
14231 // TODO: Type this specific to this type of component.
14232 fiber.updateQueue = updatePayload;
14233 // If the update payload indicates that there is a change or if there
14234 // is a new ref we mark this as an update.
14235 if (updatePayload !== null) {
14236 return true;
14237 }
14238 return false;
14239}
14240
14241function prepareToHydrateHostTextInstance(fiber) {
14242 if (!supportsHydration) {
14243 invariant(false, 'Expected prepareToHydrateHostTextInstance() to never be called. This error is likely caused by a bug in React. Please file an issue.');
14244 }
14245
14246 var textInstance = fiber.stateNode;
14247 var textContent = fiber.memoizedProps;
14248 var shouldUpdate = hydrateTextInstance(textInstance, textContent, fiber);
14249 {
14250 if (shouldUpdate) {
14251 // We assume that prepareToHydrateHostTextInstance is called in a context where the
14252 // hydration parent is the parent host component of this host text.
14253 var returnFiber = hydrationParentFiber;
14254 if (returnFiber !== null) {
14255 switch (returnFiber.tag) {
14256 case HostRoot:
14257 {
14258 var parentContainer = returnFiber.stateNode.containerInfo;
14259 didNotMatchHydratedContainerTextInstance(parentContainer, textInstance, textContent);
14260 break;
14261 }
14262 case HostComponent:
14263 {
14264 var parentType = returnFiber.type;
14265 var parentProps = returnFiber.memoizedProps;
14266 var parentInstance = returnFiber.stateNode;
14267 didNotMatchHydratedTextInstance(parentType, parentProps, parentInstance, textInstance, textContent);
14268 break;
14269 }
14270 }
14271 }
14272 }
14273 }
14274 return shouldUpdate;
14275}
14276
14277function popToNextHostParent(fiber) {
14278 var parent = fiber.return;
14279 while (parent !== null && parent.tag !== HostComponent && parent.tag !== HostRoot) {
14280 parent = parent.return;
14281 }
14282 hydrationParentFiber = parent;
14283}
14284
14285function popHydrationState(fiber) {
14286 if (!supportsHydration) {
14287 return false;
14288 }
14289 if (fiber !== hydrationParentFiber) {
14290 // We're deeper than the current hydration context, inside an inserted
14291 // tree.
14292 return false;
14293 }
14294 if (!isHydrating) {
14295 // If we're not currently hydrating but we're in a hydration context, then
14296 // we were an insertion and now need to pop up reenter hydration of our
14297 // siblings.
14298 popToNextHostParent(fiber);
14299 isHydrating = true;
14300 return false;
14301 }
14302
14303 var type = fiber.type;
14304
14305 // If we have any remaining hydratable nodes, we need to delete them now.
14306 // We only do this deeper than head and body since they tend to have random
14307 // other nodes in them. We also ignore components with pure text content in
14308 // side of them.
14309 // TODO: Better heuristic.
14310 if (fiber.tag !== HostComponent || type !== 'head' && type !== 'body' && !shouldSetTextContent(type, fiber.memoizedProps)) {
14311 var nextInstance = nextHydratableInstance;
14312 while (nextInstance) {
14313 deleteHydratableInstance(fiber, nextInstance);
14314 nextInstance = getNextHydratableSibling(nextInstance);
14315 }
14316 }
14317
14318 popToNextHostParent(fiber);
14319 nextHydratableInstance = hydrationParentFiber ? getNextHydratableSibling(fiber.stateNode) : null;
14320 return true;
14321}
14322
14323function resetHydrationState() {
14324 if (!supportsHydration) {
14325 return;
14326 }
14327
14328 hydrationParentFiber = null;
14329 nextHydratableInstance = null;
14330 isHydrating = false;
14331}
14332
14333var ReactCurrentOwner$3 = ReactSharedInternals.ReactCurrentOwner;
14334
14335var didWarnAboutBadClass = void 0;
14336var didWarnAboutContextTypeOnFunctionComponent = void 0;
14337var didWarnAboutGetDerivedStateOnFunctionComponent = void 0;
14338var didWarnAboutFunctionRefs = void 0;
14339var didWarnAboutReassigningProps = void 0;
14340
14341{
14342 didWarnAboutBadClass = {};
14343 didWarnAboutContextTypeOnFunctionComponent = {};
14344 didWarnAboutGetDerivedStateOnFunctionComponent = {};
14345 didWarnAboutFunctionRefs = {};
14346 didWarnAboutReassigningProps = false;
14347}
14348
14349function reconcileChildren(current$$1, workInProgress, nextChildren, renderExpirationTime) {
14350 if (current$$1 === null) {
14351 // If this is a fresh new component that hasn't been rendered yet, we
14352 // won't update its child set by applying minimal side-effects. Instead,
14353 // we will add them all to the child before it gets rendered. That means
14354 // we can optimize this reconciliation pass by not tracking side-effects.
14355 workInProgress.child = mountChildFibers(workInProgress, null, nextChildren, renderExpirationTime);
14356 } else {
14357 // If the current child is the same as the work in progress, it means that
14358 // we haven't yet started any work on these children. Therefore, we use
14359 // the clone algorithm to create a copy of all the current children.
14360
14361 // If we had any progressed work already, that is invalid at this point so
14362 // let's throw it out.
14363 workInProgress.child = reconcileChildFibers(workInProgress, current$$1.child, nextChildren, renderExpirationTime);
14364 }
14365}
14366
14367function forceUnmountCurrentAndReconcile(current$$1, workInProgress, nextChildren, renderExpirationTime) {
14368 // This function is fork of reconcileChildren. It's used in cases where we
14369 // want to reconcile without matching against the existing set. This has the
14370 // effect of all current children being unmounted; even if the type and key
14371 // are the same, the old child is unmounted and a new child is created.
14372 //
14373 // To do this, we're going to go through the reconcile algorithm twice. In
14374 // the first pass, we schedule a deletion for all the current children by
14375 // passing null.
14376 workInProgress.child = reconcileChildFibers(workInProgress, current$$1.child, null, renderExpirationTime);
14377 // In the second pass, we mount the new children. The trick here is that we
14378 // pass null in place of where we usually pass the current child set. This has
14379 // the effect of remounting all children regardless of whether their their
14380 // identity matches.
14381 workInProgress.child = reconcileChildFibers(workInProgress, null, nextChildren, renderExpirationTime);
14382}
14383
14384function updateForwardRef(current$$1, workInProgress, Component, nextProps, renderExpirationTime) {
14385 {
14386 if (workInProgress.type !== workInProgress.elementType) {
14387 // Lazy component props can't be validated in createElement
14388 // because they're only guaranteed to be resolved here.
14389 var innerPropTypes = Component.propTypes;
14390 if (innerPropTypes) {
14391 checkPropTypes_1(innerPropTypes, nextProps, // Resolved props
14392 'prop', getComponentName(Component), getCurrentFiberStackInDev);
14393 }
14394 }
14395 }
14396
14397 var render = Component.render;
14398 var ref = workInProgress.ref;
14399
14400 // The rest is a fork of updateFunctionComponent
14401 var nextChildren = void 0;
14402 prepareToReadContext(workInProgress, renderExpirationTime);
14403 prepareToUseHooks(current$$1, workInProgress, renderExpirationTime);
14404 {
14405 ReactCurrentOwner$3.current = workInProgress;
14406 setCurrentPhase('render');
14407 nextChildren = render(nextProps, ref);
14408 setCurrentPhase(null);
14409 }
14410 nextChildren = finishHooks(render, nextProps, nextChildren, ref);
14411
14412 // React DevTools reads this flag.
14413 workInProgress.effectTag |= PerformedWork;
14414 reconcileChildren(current$$1, workInProgress, nextChildren, renderExpirationTime);
14415 return workInProgress.child;
14416}
14417
14418function updateMemoComponent(current$$1, workInProgress, Component, nextProps, updateExpirationTime, renderExpirationTime) {
14419 if (current$$1 === null) {
14420 var type = Component.type;
14421 if (isSimpleFunctionComponent(type) && Component.compare === null &&
14422 // SimpleMemoComponent codepath doesn't resolve outer props either.
14423 Component.defaultProps === undefined) {
14424 // If this is a plain function component without default props,
14425 // and with only the default shallow comparison, we upgrade it
14426 // to a SimpleMemoComponent to allow fast path updates.
14427 workInProgress.tag = SimpleMemoComponent;
14428 workInProgress.type = type;
14429 {
14430 validateFunctionComponentInDev(workInProgress, type);
14431 }
14432 return updateSimpleMemoComponent(current$$1, workInProgress, type, nextProps, updateExpirationTime, renderExpirationTime);
14433 }
14434 {
14435 var innerPropTypes = type.propTypes;
14436 if (innerPropTypes) {
14437 // Inner memo component props aren't currently validated in createElement.
14438 // We could move it there, but we'd still need this for lazy code path.
14439 checkPropTypes_1(innerPropTypes, nextProps, // Resolved props
14440 'prop', getComponentName(type), getCurrentFiberStackInDev);
14441 }
14442 }
14443 var child = createFiberFromTypeAndProps(Component.type, null, nextProps, null, workInProgress.mode, renderExpirationTime);
14444 child.ref = workInProgress.ref;
14445 child.return = workInProgress;
14446 workInProgress.child = child;
14447 return child;
14448 }
14449 {
14450 var _type = Component.type;
14451 var _innerPropTypes = _type.propTypes;
14452 if (_innerPropTypes) {
14453 // Inner memo component props aren't currently validated in createElement.
14454 // We could move it there, but we'd still need this for lazy code path.
14455 checkPropTypes_1(_innerPropTypes, nextProps, // Resolved props
14456 'prop', getComponentName(_type), getCurrentFiberStackInDev);
14457 }
14458 }
14459 var currentChild = current$$1.child; // This is always exactly one child
14460 if (updateExpirationTime < renderExpirationTime) {
14461 // This will be the props with resolved defaultProps,
14462 // unlike current.memoizedProps which will be the unresolved ones.
14463 var prevProps = currentChild.memoizedProps;
14464 // Default to shallow comparison
14465 var compare = Component.compare;
14466 compare = compare !== null ? compare : shallowEqual;
14467 if (compare(prevProps, nextProps) && current$$1.ref === workInProgress.ref) {
14468 return bailoutOnAlreadyFinishedWork(current$$1, workInProgress, renderExpirationTime);
14469 }
14470 }
14471 // React DevTools reads this flag.
14472 workInProgress.effectTag |= PerformedWork;
14473 var newChild = createWorkInProgress(currentChild, nextProps, renderExpirationTime);
14474 newChild.ref = workInProgress.ref;
14475 newChild.return = workInProgress;
14476 workInProgress.child = newChild;
14477 return newChild;
14478}
14479
14480function updateSimpleMemoComponent(current$$1, workInProgress, Component, nextProps, updateExpirationTime, renderExpirationTime) {
14481 {
14482 if (workInProgress.type !== workInProgress.elementType) {
14483 // Lazy component props can't be validated in createElement
14484 // because they're only guaranteed to be resolved here.
14485 var outerMemoType = workInProgress.elementType;
14486 if (outerMemoType.$$typeof === REACT_LAZY_TYPE) {
14487 // We warn when you define propTypes on lazy()
14488 // so let's just skip over it to find memo() outer wrapper.
14489 // Inner props for memo are validated later.
14490 outerMemoType = refineResolvedLazyComponent(outerMemoType);
14491 }
14492 var outerPropTypes = outerMemoType && outerMemoType.propTypes;
14493 if (outerPropTypes) {
14494 checkPropTypes_1(outerPropTypes, nextProps, // Resolved (SimpleMemoComponent has no defaultProps)
14495 'prop', getComponentName(outerMemoType), getCurrentFiberStackInDev);
14496 }
14497 // Inner propTypes will be validated in the function component path.
14498 }
14499 }
14500 if (current$$1 !== null && updateExpirationTime < renderExpirationTime) {
14501 var prevProps = current$$1.memoizedProps;
14502 if (shallowEqual(prevProps, nextProps) && current$$1.ref === workInProgress.ref) {
14503 return bailoutOnAlreadyFinishedWork(current$$1, workInProgress, renderExpirationTime);
14504 }
14505 }
14506 return updateFunctionComponent(current$$1, workInProgress, Component, nextProps, renderExpirationTime);
14507}
14508
14509function updateFragment(current$$1, workInProgress, renderExpirationTime) {
14510 var nextChildren = workInProgress.pendingProps;
14511 reconcileChildren(current$$1, workInProgress, nextChildren, renderExpirationTime);
14512 return workInProgress.child;
14513}
14514
14515function updateMode(current$$1, workInProgress, renderExpirationTime) {
14516 var nextChildren = workInProgress.pendingProps.children;
14517 reconcileChildren(current$$1, workInProgress, nextChildren, renderExpirationTime);
14518 return workInProgress.child;
14519}
14520
14521function updateProfiler(current$$1, workInProgress, renderExpirationTime) {
14522 if (enableProfilerTimer) {
14523 workInProgress.effectTag |= Update;
14524 }
14525 var nextProps = workInProgress.pendingProps;
14526 var nextChildren = nextProps.children;
14527 reconcileChildren(current$$1, workInProgress, nextChildren, renderExpirationTime);
14528 return workInProgress.child;
14529}
14530
14531function markRef(current$$1, workInProgress) {
14532 var ref = workInProgress.ref;
14533 if (current$$1 === null && ref !== null || current$$1 !== null && current$$1.ref !== ref) {
14534 // Schedule a Ref effect
14535 workInProgress.effectTag |= Ref;
14536 }
14537}
14538
14539function updateFunctionComponent(current$$1, workInProgress, Component, nextProps, renderExpirationTime) {
14540 {
14541 if (workInProgress.type !== workInProgress.elementType) {
14542 // Lazy component props can't be validated in createElement
14543 // because they're only guaranteed to be resolved here.
14544 var innerPropTypes = Component.propTypes;
14545 if (innerPropTypes) {
14546 checkPropTypes_1(innerPropTypes, nextProps, // Resolved props
14547 'prop', getComponentName(Component), getCurrentFiberStackInDev);
14548 }
14549 }
14550 }
14551
14552 var unmaskedContext = getUnmaskedContext(workInProgress, Component, true);
14553 var context = getMaskedContext(workInProgress, unmaskedContext);
14554
14555 var nextChildren = void 0;
14556 prepareToReadContext(workInProgress, renderExpirationTime);
14557 prepareToUseHooks(current$$1, workInProgress, renderExpirationTime);
14558 {
14559 ReactCurrentOwner$3.current = workInProgress;
14560 setCurrentPhase('render');
14561 nextChildren = Component(nextProps, context);
14562 setCurrentPhase(null);
14563 }
14564 nextChildren = finishHooks(Component, nextProps, nextChildren, context);
14565
14566 // React DevTools reads this flag.
14567 workInProgress.effectTag |= PerformedWork;
14568 reconcileChildren(current$$1, workInProgress, nextChildren, renderExpirationTime);
14569 return workInProgress.child;
14570}
14571
14572function updateClassComponent(current$$1, workInProgress, Component, nextProps, renderExpirationTime) {
14573 {
14574 if (workInProgress.type !== workInProgress.elementType) {
14575 // Lazy component props can't be validated in createElement
14576 // because they're only guaranteed to be resolved here.
14577 var innerPropTypes = Component.propTypes;
14578 if (innerPropTypes) {
14579 checkPropTypes_1(innerPropTypes, nextProps, // Resolved props
14580 'prop', getComponentName(Component), getCurrentFiberStackInDev);
14581 }
14582 }
14583 }
14584
14585 // Push context providers early to prevent context stack mismatches.
14586 // During mounting we don't know the child context yet as the instance doesn't exist.
14587 // We will invalidate the child context in finishClassComponent() right after rendering.
14588 var hasContext = void 0;
14589 if (isContextProvider(Component)) {
14590 hasContext = true;
14591 pushContextProvider(workInProgress);
14592 } else {
14593 hasContext = false;
14594 }
14595 prepareToReadContext(workInProgress, renderExpirationTime);
14596
14597 var instance = workInProgress.stateNode;
14598 var shouldUpdate = void 0;
14599 if (instance === null) {
14600 if (current$$1 !== null) {
14601 // An class component without an instance only mounts if it suspended
14602 // inside a non- concurrent tree, in an inconsistent state. We want to
14603 // tree it like a new mount, even though an empty version of it already
14604 // committed. Disconnect the alternate pointers.
14605 current$$1.alternate = null;
14606 workInProgress.alternate = null;
14607 // Since this is conceptually a new fiber, schedule a Placement effect
14608 workInProgress.effectTag |= Placement;
14609 }
14610 // In the initial pass we might need to construct the instance.
14611 constructClassInstance(workInProgress, Component, nextProps, renderExpirationTime);
14612 mountClassInstance(workInProgress, Component, nextProps, renderExpirationTime);
14613 shouldUpdate = true;
14614 } else if (current$$1 === null) {
14615 // In a resume, we'll already have an instance we can reuse.
14616 shouldUpdate = resumeMountClassInstance(workInProgress, Component, nextProps, renderExpirationTime);
14617 } else {
14618 shouldUpdate = updateClassInstance(current$$1, workInProgress, Component, nextProps, renderExpirationTime);
14619 }
14620 var nextUnitOfWork = finishClassComponent(current$$1, workInProgress, Component, shouldUpdate, hasContext, renderExpirationTime);
14621 {
14622 var inst = workInProgress.stateNode;
14623 if (inst.props !== nextProps) {
14624 !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;
14625 didWarnAboutReassigningProps = true;
14626 }
14627 }
14628 return nextUnitOfWork;
14629}
14630
14631function finishClassComponent(current$$1, workInProgress, Component, shouldUpdate, hasContext, renderExpirationTime) {
14632 // Refs should update even if shouldComponentUpdate returns false
14633 markRef(current$$1, workInProgress);
14634
14635 var didCaptureError = (workInProgress.effectTag & DidCapture) !== NoEffect;
14636
14637 if (!shouldUpdate && !didCaptureError) {
14638 // Context providers should defer to sCU for rendering
14639 if (hasContext) {
14640 invalidateContextProvider(workInProgress, Component, false);
14641 }
14642
14643 return bailoutOnAlreadyFinishedWork(current$$1, workInProgress, renderExpirationTime);
14644 }
14645
14646 var instance = workInProgress.stateNode;
14647
14648 // Rerender
14649 ReactCurrentOwner$3.current = workInProgress;
14650 var nextChildren = void 0;
14651 if (didCaptureError && typeof Component.getDerivedStateFromError !== 'function') {
14652 // If we captured an error, but getDerivedStateFrom catch is not defined,
14653 // unmount all the children. componentDidCatch will schedule an update to
14654 // re-render a fallback. This is temporary until we migrate everyone to
14655 // the new API.
14656 // TODO: Warn in a future release.
14657 nextChildren = null;
14658
14659 if (enableProfilerTimer) {
14660 stopProfilerTimerIfRunning(workInProgress);
14661 }
14662 } else {
14663 {
14664 setCurrentPhase('render');
14665 nextChildren = instance.render();
14666 if (debugRenderPhaseSideEffects || debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) {
14667 instance.render();
14668 }
14669 setCurrentPhase(null);
14670 }
14671 }
14672
14673 // React DevTools reads this flag.
14674 workInProgress.effectTag |= PerformedWork;
14675 if (current$$1 !== null && didCaptureError) {
14676 // If we're recovering from an error, reconcile without reusing any of
14677 // the existing children. Conceptually, the normal children and the children
14678 // that are shown on error are two different sets, so we shouldn't reuse
14679 // normal children even if their identities match.
14680 forceUnmountCurrentAndReconcile(current$$1, workInProgress, nextChildren, renderExpirationTime);
14681 } else {
14682 reconcileChildren(current$$1, workInProgress, nextChildren, renderExpirationTime);
14683 }
14684
14685 // Memoize state using the values we just used to render.
14686 // TODO: Restructure so we never read values from the instance.
14687 workInProgress.memoizedState = instance.state;
14688
14689 // The context might have changed so we need to recalculate it.
14690 if (hasContext) {
14691 invalidateContextProvider(workInProgress, Component, true);
14692 }
14693
14694 return workInProgress.child;
14695}
14696
14697function pushHostRootContext(workInProgress) {
14698 var root = workInProgress.stateNode;
14699 if (root.pendingContext) {
14700 pushTopLevelContextObject(workInProgress, root.pendingContext, root.pendingContext !== root.context);
14701 } else if (root.context) {
14702 // Should always be set
14703 pushTopLevelContextObject(workInProgress, root.context, false);
14704 }
14705 pushHostContainer(workInProgress, root.containerInfo);
14706}
14707
14708function updateHostRoot(current$$1, workInProgress, renderExpirationTime) {
14709 pushHostRootContext(workInProgress);
14710 var updateQueue = workInProgress.updateQueue;
14711 !(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;
14712 var nextProps = workInProgress.pendingProps;
14713 var prevState = workInProgress.memoizedState;
14714 var prevChildren = prevState !== null ? prevState.element : null;
14715 processUpdateQueue(workInProgress, updateQueue, nextProps, null, renderExpirationTime);
14716 var nextState = workInProgress.memoizedState;
14717 // Caution: React DevTools currently depends on this property
14718 // being called "element".
14719 var nextChildren = nextState.element;
14720 if (nextChildren === prevChildren) {
14721 // If the state is the same as before, that's a bailout because we had
14722 // no work that expires at this time.
14723 resetHydrationState();
14724 return bailoutOnAlreadyFinishedWork(current$$1, workInProgress, renderExpirationTime);
14725 }
14726 var root = workInProgress.stateNode;
14727 if ((current$$1 === null || current$$1.child === null) && root.hydrate && enterHydrationState(workInProgress)) {
14728 // If we don't have any current children this might be the first pass.
14729 // We always try to hydrate. If this isn't a hydration pass there won't
14730 // be any children to hydrate which is effectively the same thing as
14731 // not hydrating.
14732
14733 // This is a bit of a hack. We track the host root as a placement to
14734 // know that we're currently in a mounting state. That way isMounted
14735 // works as expected. We must reset this before committing.
14736 // TODO: Delete this when we delete isMounted and findDOMNode.
14737 workInProgress.effectTag |= Placement;
14738
14739 // Ensure that children mount into this root without tracking
14740 // side-effects. This ensures that we don't store Placement effects on
14741 // nodes that will be hydrated.
14742 workInProgress.child = mountChildFibers(workInProgress, null, nextChildren, renderExpirationTime);
14743 } else {
14744 // Otherwise reset hydration state in case we aborted and resumed another
14745 // root.
14746 reconcileChildren(current$$1, workInProgress, nextChildren, renderExpirationTime);
14747 resetHydrationState();
14748 }
14749 return workInProgress.child;
14750}
14751
14752function updateHostComponent(current$$1, workInProgress, renderExpirationTime) {
14753 pushHostContext(workInProgress);
14754
14755 if (current$$1 === null) {
14756 tryToClaimNextHydratableInstance(workInProgress);
14757 }
14758
14759 var type = workInProgress.type;
14760 var nextProps = workInProgress.pendingProps;
14761 var prevProps = current$$1 !== null ? current$$1.memoizedProps : null;
14762
14763 var nextChildren = nextProps.children;
14764 var isDirectTextChild = shouldSetTextContent(type, nextProps);
14765
14766 if (isDirectTextChild) {
14767 // We special case a direct text child of a host node. This is a common
14768 // case. We won't handle it as a reified child. We will instead handle
14769 // this in the host environment that also have access to this prop. That
14770 // avoids allocating another HostText fiber and traversing it.
14771 nextChildren = null;
14772 } else if (prevProps !== null && shouldSetTextContent(type, prevProps)) {
14773 // If we're switching from a direct text child to a normal child, or to
14774 // empty, we need to schedule the text content to be reset.
14775 workInProgress.effectTag |= ContentReset;
14776 }
14777
14778 markRef(current$$1, workInProgress);
14779
14780 // Check the host config to see if the children are offscreen/hidden.
14781 if (renderExpirationTime !== Never && workInProgress.mode & ConcurrentMode && shouldDeprioritizeSubtree(type, nextProps)) {
14782 // Schedule this fiber to re-render at offscreen priority. Then bailout.
14783 workInProgress.expirationTime = Never;
14784 return null;
14785 }
14786
14787 reconcileChildren(current$$1, workInProgress, nextChildren, renderExpirationTime);
14788 return workInProgress.child;
14789}
14790
14791function updateHostText(current$$1, workInProgress) {
14792 if (current$$1 === null) {
14793 tryToClaimNextHydratableInstance(workInProgress);
14794 }
14795 // Nothing to do here. This is terminal. We'll do the completion step
14796 // immediately after.
14797 return null;
14798}
14799
14800function mountLazyComponent(_current, workInProgress, elementType, updateExpirationTime, renderExpirationTime) {
14801 if (_current !== null) {
14802 // An lazy component only mounts if it suspended inside a non-
14803 // concurrent tree, in an inconsistent state. We want to treat it like
14804 // a new mount, even though an empty version of it already committed.
14805 // Disconnect the alternate pointers.
14806 _current.alternate = null;
14807 workInProgress.alternate = null;
14808 // Since this is conceptually a new fiber, schedule a Placement effect
14809 workInProgress.effectTag |= Placement;
14810 }
14811
14812 var props = workInProgress.pendingProps;
14813 // We can't start a User Timing measurement with correct label yet.
14814 // Cancel and resume right after we know the tag.
14815 cancelWorkTimer(workInProgress);
14816 var Component = readLazyComponentType(elementType);
14817 // Store the unwrapped component in the type.
14818 workInProgress.type = Component;
14819 var resolvedTag = workInProgress.tag = resolveLazyComponentTag(Component);
14820 startWorkTimer(workInProgress);
14821 var resolvedProps = resolveDefaultProps(Component, props);
14822 var child = void 0;
14823 switch (resolvedTag) {
14824 case FunctionComponent:
14825 {
14826 child = updateFunctionComponent(null, workInProgress, Component, resolvedProps, renderExpirationTime);
14827 break;
14828 }
14829 case ClassComponent:
14830 {
14831 child = updateClassComponent(null, workInProgress, Component, resolvedProps, renderExpirationTime);
14832 break;
14833 }
14834 case ForwardRef:
14835 {
14836 child = updateForwardRef(null, workInProgress, Component, resolvedProps, renderExpirationTime);
14837 break;
14838 }
14839 case MemoComponent:
14840 {
14841 {
14842 if (workInProgress.type !== workInProgress.elementType) {
14843 var outerPropTypes = Component.propTypes;
14844 if (outerPropTypes) {
14845 checkPropTypes_1(outerPropTypes, resolvedProps, // Resolved for outer only
14846 'prop', getComponentName(Component), getCurrentFiberStackInDev);
14847 }
14848 }
14849 }
14850 child = updateMemoComponent(null, workInProgress, Component, resolveDefaultProps(Component.type, resolvedProps), // The inner type can have defaults too
14851 updateExpirationTime, renderExpirationTime);
14852 break;
14853 }
14854 default:
14855 {
14856 var hint = '';
14857 {
14858 if (Component !== null && typeof Component === 'object' && Component.$$typeof === REACT_LAZY_TYPE) {
14859 hint = ' Did you wrap a component in React.lazy() more than once?';
14860 }
14861 }
14862 // This message intentionally doesn't mention ForwardRef or MemoComponent
14863 // because the fact that it's a separate type of work is an
14864 // implementation detail.
14865 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);
14866 }
14867 }
14868 return child;
14869}
14870
14871function mountIncompleteClassComponent(_current, workInProgress, Component, nextProps, renderExpirationTime) {
14872 if (_current !== null) {
14873 // An incomplete component only mounts if it suspended inside a non-
14874 // concurrent tree, in an inconsistent state. We want to treat it like
14875 // a new mount, even though an empty version of it already committed.
14876 // Disconnect the alternate pointers.
14877 _current.alternate = null;
14878 workInProgress.alternate = null;
14879 // Since this is conceptually a new fiber, schedule a Placement effect
14880 workInProgress.effectTag |= Placement;
14881 }
14882
14883 // Promote the fiber to a class and try rendering again.
14884 workInProgress.tag = ClassComponent;
14885
14886 // The rest of this function is a fork of `updateClassComponent`
14887
14888 // Push context providers early to prevent context stack mismatches.
14889 // During mounting we don't know the child context yet as the instance doesn't exist.
14890 // We will invalidate the child context in finishClassComponent() right after rendering.
14891 var hasContext = void 0;
14892 if (isContextProvider(Component)) {
14893 hasContext = true;
14894 pushContextProvider(workInProgress);
14895 } else {
14896 hasContext = false;
14897 }
14898 prepareToReadContext(workInProgress, renderExpirationTime);
14899
14900 constructClassInstance(workInProgress, Component, nextProps, renderExpirationTime);
14901 mountClassInstance(workInProgress, Component, nextProps, renderExpirationTime);
14902
14903 return finishClassComponent(null, workInProgress, Component, true, hasContext, renderExpirationTime);
14904}
14905
14906function mountIndeterminateComponent(_current, workInProgress, Component, renderExpirationTime) {
14907 if (_current !== null) {
14908 // An indeterminate component only mounts if it suspended inside a non-
14909 // concurrent tree, in an inconsistent state. We want to treat it like
14910 // a new mount, even though an empty version of it already committed.
14911 // Disconnect the alternate pointers.
14912 _current.alternate = null;
14913 workInProgress.alternate = null;
14914 // Since this is conceptually a new fiber, schedule a Placement effect
14915 workInProgress.effectTag |= Placement;
14916 }
14917
14918 var props = workInProgress.pendingProps;
14919 var unmaskedContext = getUnmaskedContext(workInProgress, Component, false);
14920 var context = getMaskedContext(workInProgress, unmaskedContext);
14921
14922 prepareToReadContext(workInProgress, renderExpirationTime);
14923 prepareToUseHooks(null, workInProgress, renderExpirationTime);
14924
14925 var value = void 0;
14926
14927 {
14928 if (Component.prototype && typeof Component.prototype.render === 'function') {
14929 var componentName = getComponentName(Component) || 'Unknown';
14930
14931 if (!didWarnAboutBadClass[componentName]) {
14932 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);
14933 didWarnAboutBadClass[componentName] = true;
14934 }
14935 }
14936
14937 if (workInProgress.mode & StrictMode) {
14938 ReactStrictModeWarnings.recordLegacyContextWarning(workInProgress, null);
14939 }
14940
14941 ReactCurrentOwner$3.current = workInProgress;
14942 value = Component(props, context);
14943 }
14944 // React DevTools reads this flag.
14945 workInProgress.effectTag |= PerformedWork;
14946
14947 if (typeof value === 'object' && value !== null && typeof value.render === 'function' && value.$$typeof === undefined) {
14948 // Proceed under the assumption that this is a class instance
14949 workInProgress.tag = ClassComponent;
14950
14951 // Throw out any hooks that were used.
14952 resetHooks();
14953
14954 // Push context providers early to prevent context stack mismatches.
14955 // During mounting we don't know the child context yet as the instance doesn't exist.
14956 // We will invalidate the child context in finishClassComponent() right after rendering.
14957 var hasContext = false;
14958 if (isContextProvider(Component)) {
14959 hasContext = true;
14960 pushContextProvider(workInProgress);
14961 } else {
14962 hasContext = false;
14963 }
14964
14965 workInProgress.memoizedState = value.state !== null && value.state !== undefined ? value.state : null;
14966
14967 var getDerivedStateFromProps = Component.getDerivedStateFromProps;
14968 if (typeof getDerivedStateFromProps === 'function') {
14969 applyDerivedStateFromProps(workInProgress, Component, getDerivedStateFromProps, props);
14970 }
14971
14972 adoptClassInstance(workInProgress, value);
14973 mountClassInstance(workInProgress, Component, props, renderExpirationTime);
14974 return finishClassComponent(null, workInProgress, Component, true, hasContext, renderExpirationTime);
14975 } else {
14976 // Proceed under the assumption that this is a function component
14977 workInProgress.tag = FunctionComponent;
14978 value = finishHooks(Component, props, value, context);
14979 reconcileChildren(null, workInProgress, value, renderExpirationTime);
14980 {
14981 validateFunctionComponentInDev(workInProgress, Component);
14982 }
14983 return workInProgress.child;
14984 }
14985}
14986
14987function validateFunctionComponentInDev(workInProgress, Component) {
14988 if (Component) {
14989 !!Component.childContextTypes ? warningWithoutStack$1(false, '%s(...): childContextTypes cannot be defined on a function component.', Component.displayName || Component.name || 'Component') : void 0;
14990 }
14991 if (workInProgress.ref !== null) {
14992 var info = '';
14993 var ownerName = getCurrentFiberOwnerNameInDevOrNull();
14994 if (ownerName) {
14995 info += '\n\nCheck the render method of `' + ownerName + '`.';
14996 }
14997
14998 var warningKey = ownerName || workInProgress._debugID || '';
14999 var debugSource = workInProgress._debugSource;
15000 if (debugSource) {
15001 warningKey = debugSource.fileName + ':' + debugSource.lineNumber;
15002 }
15003 if (!didWarnAboutFunctionRefs[warningKey]) {
15004 didWarnAboutFunctionRefs[warningKey] = true;
15005 warning$1(false, 'Function components cannot be given refs. ' + 'Attempts to access this ref will fail.%s', info);
15006 }
15007 }
15008
15009 if (typeof Component.getDerivedStateFromProps === 'function') {
15010 var componentName = getComponentName(Component) || 'Unknown';
15011
15012 if (!didWarnAboutGetDerivedStateOnFunctionComponent[componentName]) {
15013 warningWithoutStack$1(false, '%s: Function components do not support getDerivedStateFromProps.', componentName);
15014 didWarnAboutGetDerivedStateOnFunctionComponent[componentName] = true;
15015 }
15016 }
15017
15018 if (typeof Component.contextType === 'object' && Component.contextType !== null) {
15019 var _componentName = getComponentName(Component) || 'Unknown';
15020
15021 if (!didWarnAboutContextTypeOnFunctionComponent[_componentName]) {
15022 warningWithoutStack$1(false, '%s: Function components do not support contextType.', _componentName);
15023 didWarnAboutContextTypeOnFunctionComponent[_componentName] = true;
15024 }
15025 }
15026}
15027
15028function updateSuspenseComponent(current$$1, workInProgress, renderExpirationTime) {
15029 var mode = workInProgress.mode;
15030 var nextProps = workInProgress.pendingProps;
15031
15032 // We should attempt to render the primary children unless this boundary
15033 // already suspended during this render (`alreadyCaptured` is true).
15034 var nextState = workInProgress.memoizedState;
15035
15036 var nextDidTimeout = void 0;
15037 if ((workInProgress.effectTag & DidCapture) === NoEffect) {
15038 // This is the first attempt.
15039 nextState = null;
15040 nextDidTimeout = false;
15041 } else {
15042 // Something in this boundary's subtree already suspended. Switch to
15043 // rendering the fallback children.
15044 nextState = {
15045 timedOutAt: nextState !== null ? nextState.timedOutAt : NoWork
15046 };
15047 nextDidTimeout = true;
15048 workInProgress.effectTag &= ~DidCapture;
15049 }
15050
15051 // This next part is a bit confusing. If the children timeout, we switch to
15052 // showing the fallback children in place of the "primary" children.
15053 // However, we don't want to delete the primary children because then their
15054 // state will be lost (both the React state and the host state, e.g.
15055 // uncontrolled form inputs). Instead we keep them mounted and hide them.
15056 // Both the fallback children AND the primary children are rendered at the
15057 // same time. Once the primary children are un-suspended, we can delete
15058 // the fallback children — don't need to preserve their state.
15059 //
15060 // The two sets of children are siblings in the host environment, but
15061 // semantically, for purposes of reconciliation, they are two separate sets.
15062 // So we store them using two fragment fibers.
15063 //
15064 // However, we want to avoid allocating extra fibers for every placeholder.
15065 // They're only necessary when the children time out, because that's the
15066 // only time when both sets are mounted.
15067 //
15068 // So, the extra fragment fibers are only used if the children time out.
15069 // Otherwise, we render the primary children directly. This requires some
15070 // custom reconciliation logic to preserve the state of the primary
15071 // children. It's essentially a very basic form of re-parenting.
15072
15073 // `child` points to the child fiber. In the normal case, this is the first
15074 // fiber of the primary children set. In the timed-out case, it's a
15075 // a fragment fiber containing the primary children.
15076 var child = void 0;
15077 // `next` points to the next fiber React should render. In the normal case,
15078 // it's the same as `child`: the first fiber of the primary children set.
15079 // In the timed-out case, it's a fragment fiber containing the *fallback*
15080 // children -- we skip over the primary children entirely.
15081 var next = void 0;
15082 if (current$$1 === null) {
15083 // This is the initial mount. This branch is pretty simple because there's
15084 // no previous state that needs to be preserved.
15085 if (nextDidTimeout) {
15086 // Mount separate fragments for primary and fallback children.
15087 var nextFallbackChildren = nextProps.fallback;
15088 var primaryChildFragment = createFiberFromFragment(null, mode, NoWork, null);
15089
15090 if ((workInProgress.mode & ConcurrentMode) === NoContext) {
15091 // Outside of concurrent mode, we commit the effects from the
15092 var progressedState = workInProgress.memoizedState;
15093 var progressedPrimaryChild = progressedState !== null ? workInProgress.child.child : workInProgress.child;
15094 primaryChildFragment.child = progressedPrimaryChild;
15095 }
15096
15097 var fallbackChildFragment = createFiberFromFragment(nextFallbackChildren, mode, renderExpirationTime, null);
15098 primaryChildFragment.sibling = fallbackChildFragment;
15099 child = primaryChildFragment;
15100 // Skip the primary children, and continue working on the
15101 // fallback children.
15102 next = fallbackChildFragment;
15103 child.return = next.return = workInProgress;
15104 } else {
15105 // Mount the primary children without an intermediate fragment fiber.
15106 var nextPrimaryChildren = nextProps.children;
15107 child = next = mountChildFibers(workInProgress, null, nextPrimaryChildren, renderExpirationTime);
15108 }
15109 } else {
15110 // This is an update. This branch is more complicated because we need to
15111 // ensure the state of the primary children is preserved.
15112 var prevState = current$$1.memoizedState;
15113 var prevDidTimeout = prevState !== null;
15114 if (prevDidTimeout) {
15115 // The current tree already timed out. That means each child set is
15116 var currentPrimaryChildFragment = current$$1.child;
15117 var currentFallbackChildFragment = currentPrimaryChildFragment.sibling;
15118 if (nextDidTimeout) {
15119 // Still timed out. Reuse the current primary children by cloning
15120 // its fragment. We're going to skip over these entirely.
15121 var _nextFallbackChildren = nextProps.fallback;
15122 var _primaryChildFragment = createWorkInProgress(currentPrimaryChildFragment, currentPrimaryChildFragment.pendingProps, NoWork);
15123
15124 if ((workInProgress.mode & ConcurrentMode) === NoContext) {
15125 // Outside of concurrent mode, we commit the effects from the
15126 var _progressedState = workInProgress.memoizedState;
15127 var _progressedPrimaryChild = _progressedState !== null ? workInProgress.child.child : workInProgress.child;
15128 if (_progressedPrimaryChild !== currentPrimaryChildFragment.child) {
15129 _primaryChildFragment.child = _progressedPrimaryChild;
15130 }
15131 }
15132
15133 // Because primaryChildFragment is a new fiber that we're inserting as the
15134 // parent of a new tree, we need to set its treeBaseDuration.
15135 if (enableProfilerTimer && workInProgress.mode & ProfileMode) {
15136 // treeBaseDuration is the sum of all the child tree base durations.
15137 var treeBaseDuration = 0;
15138 var hiddenChild = _primaryChildFragment.child;
15139 while (hiddenChild !== null) {
15140 treeBaseDuration += hiddenChild.treeBaseDuration;
15141 hiddenChild = hiddenChild.sibling;
15142 }
15143 _primaryChildFragment.treeBaseDuration = treeBaseDuration;
15144 }
15145
15146 // Clone the fallback child fragment, too. These we'll continue
15147 // working on.
15148 var _fallbackChildFragment = _primaryChildFragment.sibling = createWorkInProgress(currentFallbackChildFragment, _nextFallbackChildren, currentFallbackChildFragment.expirationTime);
15149 child = _primaryChildFragment;
15150 _primaryChildFragment.childExpirationTime = NoWork;
15151 // Skip the primary children, and continue working on the
15152 // fallback children.
15153 next = _fallbackChildFragment;
15154 child.return = next.return = workInProgress;
15155 } else {
15156 // No longer suspended. Switch back to showing the primary children,
15157 // and remove the intermediate fragment fiber.
15158 var _nextPrimaryChildren = nextProps.children;
15159 var currentPrimaryChild = currentPrimaryChildFragment.child;
15160 var primaryChild = reconcileChildFibers(workInProgress, currentPrimaryChild, _nextPrimaryChildren, renderExpirationTime);
15161
15162 // If this render doesn't suspend, we need to delete the fallback
15163 // children. Wait until the complete phase, after we've confirmed the
15164 // fallback is no longer needed.
15165 // TODO: Would it be better to store the fallback fragment on
15166 // the stateNode?
15167
15168 // Continue rendering the children, like we normally do.
15169 child = next = primaryChild;
15170 }
15171 } else {
15172 // The current tree has not already timed out. That means the primary
15173 // children are not wrapped in a fragment fiber.
15174 var _currentPrimaryChild = current$$1.child;
15175 if (nextDidTimeout) {
15176 // Timed out. Wrap the children in a fragment fiber to keep them
15177 // separate from the fallback children.
15178 var _nextFallbackChildren2 = nextProps.fallback;
15179 var _primaryChildFragment2 = createFiberFromFragment(
15180 // It shouldn't matter what the pending props are because we aren't
15181 // going to render this fragment.
15182 null, mode, NoWork, null);
15183 _primaryChildFragment2.child = _currentPrimaryChild;
15184
15185 // Even though we're creating a new fiber, there are no new children,
15186 // because we're reusing an already mounted tree. So we don't need to
15187 // schedule a placement.
15188 // primaryChildFragment.effectTag |= Placement;
15189
15190 if ((workInProgress.mode & ConcurrentMode) === NoContext) {
15191 // Outside of concurrent mode, we commit the effects from the
15192 var _progressedState2 = workInProgress.memoizedState;
15193 var _progressedPrimaryChild2 = _progressedState2 !== null ? workInProgress.child.child : workInProgress.child;
15194 _primaryChildFragment2.child = _progressedPrimaryChild2;
15195 }
15196
15197 // Because primaryChildFragment is a new fiber that we're inserting as the
15198 // parent of a new tree, we need to set its treeBaseDuration.
15199 if (enableProfilerTimer && workInProgress.mode & ProfileMode) {
15200 // treeBaseDuration is the sum of all the child tree base durations.
15201 var _treeBaseDuration = 0;
15202 var _hiddenChild = _primaryChildFragment2.child;
15203 while (_hiddenChild !== null) {
15204 _treeBaseDuration += _hiddenChild.treeBaseDuration;
15205 _hiddenChild = _hiddenChild.sibling;
15206 }
15207 _primaryChildFragment2.treeBaseDuration = _treeBaseDuration;
15208 }
15209
15210 // Create a fragment from the fallback children, too.
15211 var _fallbackChildFragment2 = _primaryChildFragment2.sibling = createFiberFromFragment(_nextFallbackChildren2, mode, renderExpirationTime, null);
15212 _fallbackChildFragment2.effectTag |= Placement;
15213 child = _primaryChildFragment2;
15214 _primaryChildFragment2.childExpirationTime = NoWork;
15215 // Skip the primary children, and continue working on the
15216 // fallback children.
15217 next = _fallbackChildFragment2;
15218 child.return = next.return = workInProgress;
15219 } else {
15220 // Still haven't timed out. Continue rendering the children, like we
15221 // normally do.
15222 var _nextPrimaryChildren2 = nextProps.children;
15223 next = child = reconcileChildFibers(workInProgress, _currentPrimaryChild, _nextPrimaryChildren2, renderExpirationTime);
15224 }
15225 }
15226 workInProgress.stateNode = current$$1.stateNode;
15227 }
15228
15229 workInProgress.memoizedState = nextState;
15230 workInProgress.child = child;
15231 return next;
15232}
15233
15234function updatePortalComponent(current$$1, workInProgress, renderExpirationTime) {
15235 pushHostContainer(workInProgress, workInProgress.stateNode.containerInfo);
15236 var nextChildren = workInProgress.pendingProps;
15237 if (current$$1 === null) {
15238 // Portals are special because we don't append the children during mount
15239 // but at commit. Therefore we need to track insertions which the normal
15240 // flow doesn't do during mount. This doesn't happen at the root because
15241 // the root always starts with a "current" with a null child.
15242 // TODO: Consider unifying this with how the root works.
15243 workInProgress.child = reconcileChildFibers(workInProgress, null, nextChildren, renderExpirationTime);
15244 } else {
15245 reconcileChildren(current$$1, workInProgress, nextChildren, renderExpirationTime);
15246 }
15247 return workInProgress.child;
15248}
15249
15250function updateContextProvider(current$$1, workInProgress, renderExpirationTime) {
15251 var providerType = workInProgress.type;
15252 var context = providerType._context;
15253
15254 var newProps = workInProgress.pendingProps;
15255 var oldProps = workInProgress.memoizedProps;
15256
15257 var newValue = newProps.value;
15258
15259 {
15260 var providerPropTypes = workInProgress.type.propTypes;
15261
15262 if (providerPropTypes) {
15263 checkPropTypes_1(providerPropTypes, newProps, 'prop', 'Context.Provider', getCurrentFiberStackInDev);
15264 }
15265 }
15266
15267 pushProvider(workInProgress, newValue);
15268
15269 if (oldProps !== null) {
15270 var oldValue = oldProps.value;
15271 var changedBits = calculateChangedBits(context, newValue, oldValue);
15272 if (changedBits === 0) {
15273 // No change. Bailout early if children are the same.
15274 if (oldProps.children === newProps.children && !hasContextChanged()) {
15275 return bailoutOnAlreadyFinishedWork(current$$1, workInProgress, renderExpirationTime);
15276 }
15277 } else {
15278 // The context value changed. Search for matching consumers and schedule
15279 // them to update.
15280 propagateContextChange(workInProgress, context, changedBits, renderExpirationTime);
15281 }
15282 }
15283
15284 var newChildren = newProps.children;
15285 reconcileChildren(current$$1, workInProgress, newChildren, renderExpirationTime);
15286 return workInProgress.child;
15287}
15288
15289var hasWarnedAboutUsingContextAsConsumer = false;
15290
15291function updateContextConsumer(current$$1, workInProgress, renderExpirationTime) {
15292 var context = workInProgress.type;
15293 // The logic below for Context differs depending on PROD or DEV mode. In
15294 // DEV mode, we create a separate object for Context.Consumer that acts
15295 // like a proxy to Context. This proxy object adds unnecessary code in PROD
15296 // so we use the old behaviour (Context.Consumer references Context) to
15297 // reduce size and overhead. The separate object references context via
15298 // a property called "_context", which also gives us the ability to check
15299 // in DEV mode if this property exists or not and warn if it does not.
15300 {
15301 if (context._context === undefined) {
15302 // This may be because it's a Context (rather than a Consumer).
15303 // Or it may be because it's older React where they're the same thing.
15304 // We only want to warn if we're sure it's a new React.
15305 if (context !== context.Consumer) {
15306 if (!hasWarnedAboutUsingContextAsConsumer) {
15307 hasWarnedAboutUsingContextAsConsumer = true;
15308 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?');
15309 }
15310 }
15311 } else {
15312 context = context._context;
15313 }
15314 }
15315 var newProps = workInProgress.pendingProps;
15316 var render = newProps.children;
15317
15318 {
15319 !(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;
15320 }
15321
15322 prepareToReadContext(workInProgress, renderExpirationTime);
15323 var newValue = readContext(context, newProps.unstable_observedBits);
15324 var newChildren = void 0;
15325 {
15326 ReactCurrentOwner$3.current = workInProgress;
15327 setCurrentPhase('render');
15328 newChildren = render(newValue);
15329 setCurrentPhase(null);
15330 }
15331
15332 // React DevTools reads this flag.
15333 workInProgress.effectTag |= PerformedWork;
15334 reconcileChildren(current$$1, workInProgress, newChildren, renderExpirationTime);
15335 return workInProgress.child;
15336}
15337
15338function bailoutOnAlreadyFinishedWork(current$$1, workInProgress, renderExpirationTime) {
15339 cancelWorkTimer(workInProgress);
15340
15341 if (current$$1 !== null) {
15342 // Reuse previous context list
15343 workInProgress.firstContextDependency = current$$1.firstContextDependency;
15344 }
15345
15346 if (enableProfilerTimer) {
15347 // Don't update "base" render times for bailouts.
15348 stopProfilerTimerIfRunning(workInProgress);
15349 }
15350
15351 // Check if the children have any pending work.
15352 var childExpirationTime = workInProgress.childExpirationTime;
15353 if (childExpirationTime < renderExpirationTime) {
15354 // The children don't have any work either. We can skip them.
15355 // TODO: Once we add back resuming, we should check if the children are
15356 // a work-in-progress set. If so, we need to transfer their effects.
15357 return null;
15358 } else {
15359 // This fiber doesn't have work, but its subtree does. Clone the child
15360 // fibers and continue.
15361 cloneChildFibers(current$$1, workInProgress);
15362 return workInProgress.child;
15363 }
15364}
15365
15366function beginWork(current$$1, workInProgress, renderExpirationTime) {
15367 var updateExpirationTime = workInProgress.expirationTime;
15368
15369 if (current$$1 !== null) {
15370 var oldProps = current$$1.memoizedProps;
15371 var newProps = workInProgress.pendingProps;
15372 if (oldProps === newProps && !hasContextChanged() && updateExpirationTime < renderExpirationTime) {
15373 // This fiber does not have any pending work. Bailout without entering
15374 // the begin phase. There's still some bookkeeping we that needs to be done
15375 // in this optimized path, mostly pushing stuff onto the stack.
15376 switch (workInProgress.tag) {
15377 case HostRoot:
15378 pushHostRootContext(workInProgress);
15379 resetHydrationState();
15380 break;
15381 case HostComponent:
15382 pushHostContext(workInProgress);
15383 break;
15384 case ClassComponent:
15385 {
15386 var Component = workInProgress.type;
15387 if (isContextProvider(Component)) {
15388 pushContextProvider(workInProgress);
15389 }
15390 break;
15391 }
15392 case HostPortal:
15393 pushHostContainer(workInProgress, workInProgress.stateNode.containerInfo);
15394 break;
15395 case ContextProvider:
15396 {
15397 var newValue = workInProgress.memoizedProps.value;
15398 pushProvider(workInProgress, newValue);
15399 break;
15400 }
15401 case Profiler:
15402 if (enableProfilerTimer) {
15403 workInProgress.effectTag |= Update;
15404 }
15405 break;
15406 case SuspenseComponent:
15407 {
15408 var state = workInProgress.memoizedState;
15409 var didTimeout = state !== null;
15410 if (didTimeout) {
15411 // If this boundary is currently timed out, we need to decide
15412 // whether to retry the primary children, or to skip over it and
15413 // go straight to the fallback. Check the priority of the primary
15414 var primaryChildFragment = workInProgress.child;
15415 var primaryChildExpirationTime = primaryChildFragment.childExpirationTime;
15416 if (primaryChildExpirationTime !== NoWork && primaryChildExpirationTime >= renderExpirationTime) {
15417 // The primary children have pending work. Use the normal path
15418 // to attempt to render the primary children again.
15419 return updateSuspenseComponent(current$$1, workInProgress, renderExpirationTime);
15420 } else {
15421 // The primary children do not have pending work with sufficient
15422 // priority. Bailout.
15423 var child = bailoutOnAlreadyFinishedWork(current$$1, workInProgress, renderExpirationTime);
15424 if (child !== null) {
15425 // The fallback children have pending work. Skip over the
15426 // primary children and work on the fallback.
15427 return child.sibling;
15428 } else {
15429 return null;
15430 }
15431 }
15432 }
15433 break;
15434 }
15435 }
15436 return bailoutOnAlreadyFinishedWork(current$$1, workInProgress, renderExpirationTime);
15437 }
15438 }
15439
15440 // Before entering the begin phase, clear the expiration time.
15441 workInProgress.expirationTime = NoWork;
15442
15443 switch (workInProgress.tag) {
15444 case IndeterminateComponent:
15445 {
15446 var elementType = workInProgress.elementType;
15447 return mountIndeterminateComponent(current$$1, workInProgress, elementType, renderExpirationTime);
15448 }
15449 case LazyComponent:
15450 {
15451 var _elementType = workInProgress.elementType;
15452 return mountLazyComponent(current$$1, workInProgress, _elementType, updateExpirationTime, renderExpirationTime);
15453 }
15454 case FunctionComponent:
15455 {
15456 var _Component = workInProgress.type;
15457 var unresolvedProps = workInProgress.pendingProps;
15458 var resolvedProps = workInProgress.elementType === _Component ? unresolvedProps : resolveDefaultProps(_Component, unresolvedProps);
15459 return updateFunctionComponent(current$$1, workInProgress, _Component, resolvedProps, renderExpirationTime);
15460 }
15461 case ClassComponent:
15462 {
15463 var _Component2 = workInProgress.type;
15464 var _unresolvedProps = workInProgress.pendingProps;
15465 var _resolvedProps = workInProgress.elementType === _Component2 ? _unresolvedProps : resolveDefaultProps(_Component2, _unresolvedProps);
15466 return updateClassComponent(current$$1, workInProgress, _Component2, _resolvedProps, renderExpirationTime);
15467 }
15468 case HostRoot:
15469 return updateHostRoot(current$$1, workInProgress, renderExpirationTime);
15470 case HostComponent:
15471 return updateHostComponent(current$$1, workInProgress, renderExpirationTime);
15472 case HostText:
15473 return updateHostText(current$$1, workInProgress);
15474 case SuspenseComponent:
15475 return updateSuspenseComponent(current$$1, workInProgress, renderExpirationTime);
15476 case HostPortal:
15477 return updatePortalComponent(current$$1, workInProgress, renderExpirationTime);
15478 case ForwardRef:
15479 {
15480 var type = workInProgress.type;
15481 var _unresolvedProps2 = workInProgress.pendingProps;
15482 var _resolvedProps2 = workInProgress.elementType === type ? _unresolvedProps2 : resolveDefaultProps(type, _unresolvedProps2);
15483 return updateForwardRef(current$$1, workInProgress, type, _resolvedProps2, renderExpirationTime);
15484 }
15485 case Fragment:
15486 return updateFragment(current$$1, workInProgress, renderExpirationTime);
15487 case Mode:
15488 return updateMode(current$$1, workInProgress, renderExpirationTime);
15489 case Profiler:
15490 return updateProfiler(current$$1, workInProgress, renderExpirationTime);
15491 case ContextProvider:
15492 return updateContextProvider(current$$1, workInProgress, renderExpirationTime);
15493 case ContextConsumer:
15494 return updateContextConsumer(current$$1, workInProgress, renderExpirationTime);
15495 case MemoComponent:
15496 {
15497 var _type2 = workInProgress.type;
15498 var _unresolvedProps3 = workInProgress.pendingProps;
15499 // Resolve outer props first, then resolve inner props.
15500 var _resolvedProps3 = resolveDefaultProps(_type2, _unresolvedProps3);
15501 {
15502 if (workInProgress.type !== workInProgress.elementType) {
15503 var outerPropTypes = _type2.propTypes;
15504 if (outerPropTypes) {
15505 checkPropTypes_1(outerPropTypes, _resolvedProps3, // Resolved for outer only
15506 'prop', getComponentName(_type2), getCurrentFiberStackInDev);
15507 }
15508 }
15509 }
15510 _resolvedProps3 = resolveDefaultProps(_type2.type, _resolvedProps3);
15511 return updateMemoComponent(current$$1, workInProgress, _type2, _resolvedProps3, updateExpirationTime, renderExpirationTime);
15512 }
15513 case SimpleMemoComponent:
15514 {
15515 return updateSimpleMemoComponent(current$$1, workInProgress, workInProgress.type, workInProgress.pendingProps, updateExpirationTime, renderExpirationTime);
15516 }
15517 case IncompleteClassComponent:
15518 {
15519 var _Component3 = workInProgress.type;
15520 var _unresolvedProps4 = workInProgress.pendingProps;
15521 var _resolvedProps4 = workInProgress.elementType === _Component3 ? _unresolvedProps4 : resolveDefaultProps(_Component3, _unresolvedProps4);
15522 return mountIncompleteClassComponent(current$$1, workInProgress, _Component3, _resolvedProps4, renderExpirationTime);
15523 }
15524 default:
15525 invariant(false, 'Unknown unit of work tag. This error is likely caused by a bug in React. Please file an issue.');
15526 }
15527}
15528
15529function markUpdate(workInProgress) {
15530 // Tag the fiber with an update effect. This turns a Placement into
15531 // a PlacementAndUpdate.
15532 workInProgress.effectTag |= Update;
15533}
15534
15535function markRef$1(workInProgress) {
15536 workInProgress.effectTag |= Ref;
15537}
15538
15539var appendAllChildren = void 0;
15540var updateHostContainer = void 0;
15541var updateHostComponent$1 = void 0;
15542var updateHostText$1 = void 0;
15543if (supportsMutation) {
15544 // Mutation mode
15545
15546 appendAllChildren = function (parent, workInProgress, needsVisibilityToggle, isHidden) {
15547 // We only have the top Fiber that was created but we need recurse down its
15548 // children to find all the terminal nodes.
15549 var node = workInProgress.child;
15550 while (node !== null) {
15551 if (node.tag === HostComponent || node.tag === HostText) {
15552 appendInitialChild(parent, node.stateNode);
15553 } else if (node.tag === HostPortal) {
15554 // If we have a portal child, then we don't want to traverse
15555 // down its children. Instead, we'll get insertions from each child in
15556 // the portal directly.
15557 } else if (node.child !== null) {
15558 node.child.return = node;
15559 node = node.child;
15560 continue;
15561 }
15562 if (node === workInProgress) {
15563 return;
15564 }
15565 while (node.sibling === null) {
15566 if (node.return === null || node.return === workInProgress) {
15567 return;
15568 }
15569 node = node.return;
15570 }
15571 node.sibling.return = node.return;
15572 node = node.sibling;
15573 }
15574 };
15575
15576 updateHostContainer = function (workInProgress) {
15577 // Noop
15578 };
15579 updateHostComponent$1 = function (current, workInProgress, type, newProps, rootContainerInstance) {
15580 // If we have an alternate, that means this is an update and we need to
15581 // schedule a side-effect to do the updates.
15582 var oldProps = current.memoizedProps;
15583 if (oldProps === newProps) {
15584 // In mutation mode, this is sufficient for a bailout because
15585 // we won't touch this node even if children changed.
15586 return;
15587 }
15588
15589 // If we get updated because one of our children updated, we don't
15590 // have newProps so we'll have to reuse them.
15591 // TODO: Split the update API as separate for the props vs. children.
15592 // Even better would be if children weren't special cased at all tho.
15593 var instance = workInProgress.stateNode;
15594 var currentHostContext = getHostContext();
15595 // TODO: Experiencing an error where oldProps is null. Suggests a host
15596 // component is hitting the resume path. Figure out why. Possibly
15597 // related to `hidden`.
15598 var updatePayload = prepareUpdate(instance, type, oldProps, newProps, rootContainerInstance, currentHostContext);
15599 // TODO: Type this specific to this type of component.
15600 workInProgress.updateQueue = updatePayload;
15601 // If the update payload indicates that there is a change or if there
15602 // is a new ref we mark this as an update. All the work is done in commitWork.
15603 if (updatePayload) {
15604 markUpdate(workInProgress);
15605 }
15606 };
15607 updateHostText$1 = function (current, workInProgress, oldText, newText) {
15608 // If the text differs, mark it as an update. All the work in done in commitWork.
15609 if (oldText !== newText) {
15610 markUpdate(workInProgress);
15611 }
15612 };
15613} else if (supportsPersistence) {
15614 // Persistent host tree mode
15615
15616 appendAllChildren = function (parent, workInProgress, needsVisibilityToggle, isHidden) {
15617 // We only have the top Fiber that was created but we need recurse down its
15618 // children to find all the terminal nodes.
15619 var node = workInProgress.child;
15620 while (node !== null) {
15621 // eslint-disable-next-line no-labels
15622 branches: if (node.tag === HostComponent) {
15623 var instance = node.stateNode;
15624 if (needsVisibilityToggle) {
15625 var props = node.memoizedProps;
15626 var type = node.type;
15627 if (isHidden) {
15628 // This child is inside a timed out tree. Hide it.
15629 instance = cloneHiddenInstance(instance, type, props, node);
15630 } else {
15631 // This child was previously inside a timed out tree. If it was not
15632 // updated during this render, it may need to be unhidden. Clone
15633 // again to be sure.
15634 instance = cloneUnhiddenInstance(instance, type, props, node);
15635 }
15636 node.stateNode = instance;
15637 }
15638 appendInitialChild(parent, instance);
15639 } else if (node.tag === HostText) {
15640 var _instance = node.stateNode;
15641 if (needsVisibilityToggle) {
15642 var text = node.memoizedProps;
15643 var rootContainerInstance = getRootHostContainer();
15644 var currentHostContext = getHostContext();
15645 if (isHidden) {
15646 _instance = createHiddenTextInstance(text, rootContainerInstance, currentHostContext, workInProgress);
15647 } else {
15648 _instance = createTextInstance(text, rootContainerInstance, currentHostContext, workInProgress);
15649 }
15650 node.stateNode = _instance;
15651 }
15652 appendInitialChild(parent, _instance);
15653 } else if (node.tag === HostPortal) {
15654 // If we have a portal child, then we don't want to traverse
15655 // down its children. Instead, we'll get insertions from each child in
15656 // the portal directly.
15657 } else if (node.tag === SuspenseComponent) {
15658 var current = node.alternate;
15659 if (current !== null) {
15660 var oldState = current.memoizedState;
15661 var newState = node.memoizedState;
15662 var oldIsHidden = oldState !== null;
15663 var newIsHidden = newState !== null;
15664 if (oldIsHidden !== newIsHidden) {
15665 // The placeholder either just timed out or switched back to the normal
15666 // children after having previously timed out. Toggle the visibility of
15667 // the direct host children.
15668 var primaryChildParent = newIsHidden ? node.child : node;
15669 if (primaryChildParent !== null) {
15670 appendAllChildren(parent, primaryChildParent, true, newIsHidden);
15671 }
15672 // eslint-disable-next-line no-labels
15673 break branches;
15674 }
15675 }
15676 if (node.child !== null) {
15677 // Continue traversing like normal
15678 node.child.return = node;
15679 node = node.child;
15680 continue;
15681 }
15682 } else if (node.child !== null) {
15683 node.child.return = node;
15684 node = node.child;
15685 continue;
15686 }
15687 // $FlowFixMe This is correct but Flow is confused by the labeled break.
15688 node = node;
15689 if (node === workInProgress) {
15690 return;
15691 }
15692 while (node.sibling === null) {
15693 if (node.return === null || node.return === workInProgress) {
15694 return;
15695 }
15696 node = node.return;
15697 }
15698 node.sibling.return = node.return;
15699 node = node.sibling;
15700 }
15701 };
15702
15703 // An unfortunate fork of appendAllChildren because we have two different parent types.
15704 var appendAllChildrenToContainer = function (containerChildSet, workInProgress, needsVisibilityToggle, isHidden) {
15705 // We only have the top Fiber that was created but we need recurse down its
15706 // children to find all the terminal nodes.
15707 var node = workInProgress.child;
15708 while (node !== null) {
15709 // eslint-disable-next-line no-labels
15710 branches: if (node.tag === HostComponent) {
15711 var instance = node.stateNode;
15712 if (needsVisibilityToggle) {
15713 var props = node.memoizedProps;
15714 var type = node.type;
15715 if (isHidden) {
15716 // This child is inside a timed out tree. Hide it.
15717 instance = cloneHiddenInstance(instance, type, props, node);
15718 } else {
15719 // This child was previously inside a timed out tree. If it was not
15720 // updated during this render, it may need to be unhidden. Clone
15721 // again to be sure.
15722 instance = cloneUnhiddenInstance(instance, type, props, node);
15723 }
15724 node.stateNode = instance;
15725 }
15726 appendChildToContainerChildSet(containerChildSet, instance);
15727 } else if (node.tag === HostText) {
15728 var _instance2 = node.stateNode;
15729 if (needsVisibilityToggle) {
15730 var text = node.memoizedProps;
15731 var rootContainerInstance = getRootHostContainer();
15732 var currentHostContext = getHostContext();
15733 if (isHidden) {
15734 _instance2 = createHiddenTextInstance(text, rootContainerInstance, currentHostContext, workInProgress);
15735 } else {
15736 _instance2 = createTextInstance(text, rootContainerInstance, currentHostContext, workInProgress);
15737 }
15738 node.stateNode = _instance2;
15739 }
15740 appendChildToContainerChildSet(containerChildSet, _instance2);
15741 } else if (node.tag === HostPortal) {
15742 // If we have a portal child, then we don't want to traverse
15743 // down its children. Instead, we'll get insertions from each child in
15744 // the portal directly.
15745 } else if (node.tag === SuspenseComponent) {
15746 var current = node.alternate;
15747 if (current !== null) {
15748 var oldState = current.memoizedState;
15749 var newState = node.memoizedState;
15750 var oldIsHidden = oldState !== null;
15751 var newIsHidden = newState !== null;
15752 if (oldIsHidden !== newIsHidden) {
15753 // The placeholder either just timed out or switched back to the normal
15754 // children after having previously timed out. Toggle the visibility of
15755 // the direct host children.
15756 var primaryChildParent = newIsHidden ? node.child : node;
15757 if (primaryChildParent !== null) {
15758 appendAllChildrenToContainer(containerChildSet, primaryChildParent, true, newIsHidden);
15759 }
15760 // eslint-disable-next-line no-labels
15761 break branches;
15762 }
15763 }
15764 if (node.child !== null) {
15765 // Continue traversing like normal
15766 node.child.return = node;
15767 node = node.child;
15768 continue;
15769 }
15770 } else if (node.child !== null) {
15771 node.child.return = node;
15772 node = node.child;
15773 continue;
15774 }
15775 // $FlowFixMe This is correct but Flow is confused by the labeled break.
15776 node = node;
15777 if (node === workInProgress) {
15778 return;
15779 }
15780 while (node.sibling === null) {
15781 if (node.return === null || node.return === workInProgress) {
15782 return;
15783 }
15784 node = node.return;
15785 }
15786 node.sibling.return = node.return;
15787 node = node.sibling;
15788 }
15789 };
15790 updateHostContainer = function (workInProgress) {
15791 var portalOrRoot = workInProgress.stateNode;
15792 var childrenUnchanged = workInProgress.firstEffect === null;
15793 if (childrenUnchanged) {
15794 // No changes, just reuse the existing instance.
15795 } else {
15796 var container = portalOrRoot.containerInfo;
15797 var newChildSet = createContainerChildSet(container);
15798 // If children might have changed, we have to add them all to the set.
15799 appendAllChildrenToContainer(newChildSet, workInProgress, false, false);
15800 portalOrRoot.pendingChildren = newChildSet;
15801 // Schedule an update on the container to swap out the container.
15802 markUpdate(workInProgress);
15803 finalizeContainerChildren(container, newChildSet);
15804 }
15805 };
15806 updateHostComponent$1 = function (current, workInProgress, type, newProps, rootContainerInstance) {
15807 var currentInstance = current.stateNode;
15808 var oldProps = current.memoizedProps;
15809 // If there are no effects associated with this node, then none of our children had any updates.
15810 // This guarantees that we can reuse all of them.
15811 var childrenUnchanged = workInProgress.firstEffect === null;
15812 if (childrenUnchanged && oldProps === newProps) {
15813 // No changes, just reuse the existing instance.
15814 // Note that this might release a previous clone.
15815 workInProgress.stateNode = currentInstance;
15816 return;
15817 }
15818 var recyclableInstance = workInProgress.stateNode;
15819 var currentHostContext = getHostContext();
15820 var updatePayload = null;
15821 if (oldProps !== newProps) {
15822 updatePayload = prepareUpdate(recyclableInstance, type, oldProps, newProps, rootContainerInstance, currentHostContext);
15823 }
15824 if (childrenUnchanged && updatePayload === null) {
15825 // No changes, just reuse the existing instance.
15826 // Note that this might release a previous clone.
15827 workInProgress.stateNode = currentInstance;
15828 return;
15829 }
15830 var newInstance = cloneInstance(currentInstance, updatePayload, type, oldProps, newProps, workInProgress, childrenUnchanged, recyclableInstance);
15831 if (finalizeInitialChildren(newInstance, type, newProps, rootContainerInstance, currentHostContext)) {
15832 markUpdate(workInProgress);
15833 }
15834 workInProgress.stateNode = newInstance;
15835 if (childrenUnchanged) {
15836 // If there are no other effects in this tree, we need to flag this node as having one.
15837 // Even though we're not going to use it for anything.
15838 // Otherwise parents won't know that there are new children to propagate upwards.
15839 markUpdate(workInProgress);
15840 } else {
15841 // If children might have changed, we have to add them all to the set.
15842 appendAllChildren(newInstance, workInProgress, false, false);
15843 }
15844 };
15845 updateHostText$1 = function (current, workInProgress, oldText, newText) {
15846 if (oldText !== newText) {
15847 // If the text content differs, we'll create a new text instance for it.
15848 var rootContainerInstance = getRootHostContainer();
15849 var currentHostContext = getHostContext();
15850 workInProgress.stateNode = createTextInstance(newText, rootContainerInstance, currentHostContext, workInProgress);
15851 // We'll have to mark it as having an effect, even though we won't use the effect for anything.
15852 // This lets the parents know that at least one of their children has changed.
15853 markUpdate(workInProgress);
15854 }
15855 };
15856} else {
15857 // No host operations
15858 updateHostContainer = function (workInProgress) {
15859 // Noop
15860 };
15861 updateHostComponent$1 = function (current, workInProgress, type, newProps, rootContainerInstance) {
15862 // Noop
15863 };
15864 updateHostText$1 = function (current, workInProgress, oldText, newText) {
15865 // Noop
15866 };
15867}
15868
15869function completeWork(current, workInProgress, renderExpirationTime) {
15870 var newProps = workInProgress.pendingProps;
15871
15872 switch (workInProgress.tag) {
15873 case IndeterminateComponent:
15874 break;
15875 case LazyComponent:
15876 break;
15877 case SimpleMemoComponent:
15878 case FunctionComponent:
15879 break;
15880 case ClassComponent:
15881 {
15882 var Component = workInProgress.type;
15883 if (isContextProvider(Component)) {
15884 popContext(workInProgress);
15885 }
15886 break;
15887 }
15888 case HostRoot:
15889 {
15890 popHostContainer(workInProgress);
15891 popTopLevelContextObject(workInProgress);
15892 var fiberRoot = workInProgress.stateNode;
15893 if (fiberRoot.pendingContext) {
15894 fiberRoot.context = fiberRoot.pendingContext;
15895 fiberRoot.pendingContext = null;
15896 }
15897 if (current === null || current.child === null) {
15898 // If we hydrated, pop so that we can delete any remaining children
15899 // that weren't hydrated.
15900 popHydrationState(workInProgress);
15901 // This resets the hacky state to fix isMounted before committing.
15902 // TODO: Delete this when we delete isMounted and findDOMNode.
15903 workInProgress.effectTag &= ~Placement;
15904 }
15905 updateHostContainer(workInProgress);
15906 break;
15907 }
15908 case HostComponent:
15909 {
15910 popHostContext(workInProgress);
15911 var rootContainerInstance = getRootHostContainer();
15912 var type = workInProgress.type;
15913 if (current !== null && workInProgress.stateNode != null) {
15914 updateHostComponent$1(current, workInProgress, type, newProps, rootContainerInstance);
15915
15916 if (current.ref !== workInProgress.ref) {
15917 markRef$1(workInProgress);
15918 }
15919 } else {
15920 if (!newProps) {
15921 !(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;
15922 // This can happen when we abort work.
15923 break;
15924 }
15925
15926 var currentHostContext = getHostContext();
15927 // TODO: Move createInstance to beginWork and keep it on a context
15928 // "stack" as the parent. Then append children as we go in beginWork
15929 // or completeWork depending on we want to add then top->down or
15930 // bottom->up. Top->down is faster in IE11.
15931 var wasHydrated = popHydrationState(workInProgress);
15932 if (wasHydrated) {
15933 // TODO: Move this and createInstance step into the beginPhase
15934 // to consolidate.
15935 if (prepareToHydrateHostInstance(workInProgress, rootContainerInstance, currentHostContext)) {
15936 // If changes to the hydrated node needs to be applied at the
15937 // commit-phase we mark this as such.
15938 markUpdate(workInProgress);
15939 }
15940 } else {
15941 var instance = createInstance(type, newProps, rootContainerInstance, currentHostContext, workInProgress);
15942
15943 appendAllChildren(instance, workInProgress, false, false);
15944
15945 // Certain renderers require commit-time effects for initial mount.
15946 // (eg DOM renderer supports auto-focus for certain elements).
15947 // Make sure such renderers get scheduled for later work.
15948 if (finalizeInitialChildren(instance, type, newProps, rootContainerInstance, currentHostContext)) {
15949 markUpdate(workInProgress);
15950 }
15951 workInProgress.stateNode = instance;
15952 }
15953
15954 if (workInProgress.ref !== null) {
15955 // If there is a ref on a host node we need to schedule a callback
15956 markRef$1(workInProgress);
15957 }
15958 }
15959 break;
15960 }
15961 case HostText:
15962 {
15963 var newText = newProps;
15964 if (current && workInProgress.stateNode != null) {
15965 var oldText = current.memoizedProps;
15966 // If we have an alternate, that means this is an update and we need
15967 // to schedule a side-effect to do the updates.
15968 updateHostText$1(current, workInProgress, oldText, newText);
15969 } else {
15970 if (typeof newText !== 'string') {
15971 !(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;
15972 // This can happen when we abort work.
15973 }
15974 var _rootContainerInstance = getRootHostContainer();
15975 var _currentHostContext = getHostContext();
15976 var _wasHydrated = popHydrationState(workInProgress);
15977 if (_wasHydrated) {
15978 if (prepareToHydrateHostTextInstance(workInProgress)) {
15979 markUpdate(workInProgress);
15980 }
15981 } else {
15982 workInProgress.stateNode = createTextInstance(newText, _rootContainerInstance, _currentHostContext, workInProgress);
15983 }
15984 }
15985 break;
15986 }
15987 case ForwardRef:
15988 break;
15989 case SuspenseComponent:
15990 {
15991 var nextState = workInProgress.memoizedState;
15992 if ((workInProgress.effectTag & DidCapture) !== NoEffect) {
15993 // Something suspended. Re-render with the fallback children.
15994 workInProgress.expirationTime = renderExpirationTime;
15995 // Do not reset the effect list.
15996 return workInProgress;
15997 }
15998
15999 var nextDidTimeout = nextState !== null;
16000 var prevDidTimeout = current !== null && current.memoizedState !== null;
16001
16002 if (current !== null && !nextDidTimeout && prevDidTimeout) {
16003 // We just switched from the fallback to the normal children. Delete
16004 // the fallback.
16005 // TODO: Would it be better to store the fallback fragment on
16006 var currentFallbackChild = current.child.sibling;
16007 if (currentFallbackChild !== null) {
16008 // Deletions go at the beginning of the return fiber's effect list
16009 var first = workInProgress.firstEffect;
16010 if (first !== null) {
16011 workInProgress.firstEffect = currentFallbackChild;
16012 currentFallbackChild.nextEffect = first;
16013 } else {
16014 workInProgress.firstEffect = workInProgress.lastEffect = currentFallbackChild;
16015 currentFallbackChild.nextEffect = null;
16016 }
16017 currentFallbackChild.effectTag = Deletion;
16018 }
16019 }
16020
16021 // The children either timed out after previously being visible, or
16022 // were restored after previously being hidden. Schedule an effect
16023 // to update their visiblity.
16024 if (
16025 //
16026 nextDidTimeout !== prevDidTimeout ||
16027 // Outside concurrent mode, the primary children commit in an
16028 // inconsistent state, even if they are hidden. So if they are hidden,
16029 // we need to schedule an effect to re-hide them, just in case.
16030 (workInProgress.effectTag & ConcurrentMode) === NoContext && nextDidTimeout) {
16031 workInProgress.effectTag |= Update;
16032 }
16033 break;
16034 }
16035 case Fragment:
16036 break;
16037 case Mode:
16038 break;
16039 case Profiler:
16040 break;
16041 case HostPortal:
16042 popHostContainer(workInProgress);
16043 updateHostContainer(workInProgress);
16044 break;
16045 case ContextProvider:
16046 // Pop provider fiber
16047 popProvider(workInProgress);
16048 break;
16049 case ContextConsumer:
16050 break;
16051 case MemoComponent:
16052 break;
16053 case IncompleteClassComponent:
16054 {
16055 // Same as class component case. I put it down here so that the tags are
16056 // sequential to ensure this switch is compiled to a jump table.
16057 var _Component = workInProgress.type;
16058 if (isContextProvider(_Component)) {
16059 popContext(workInProgress);
16060 }
16061 break;
16062 }
16063 default:
16064 invariant(false, 'Unknown unit of work tag. This error is likely caused by a bug in React. Please file an issue.');
16065 }
16066
16067 return null;
16068}
16069
16070function shouldCaptureSuspense(workInProgress) {
16071 // In order to capture, the Suspense component must have a fallback prop.
16072 if (workInProgress.memoizedProps.fallback === undefined) {
16073 return false;
16074 }
16075 // If it was the primary children that just suspended, capture and render the
16076 // fallback. Otherwise, don't capture and bubble to the next boundary.
16077 var nextState = workInProgress.memoizedState;
16078 return nextState === null;
16079}
16080
16081// This module is forked in different environments.
16082// By default, return `true` to log errors to the console.
16083// Forks can return `false` if this isn't desirable.
16084function showErrorDialog(capturedError) {
16085 return true;
16086}
16087
16088function logCapturedError(capturedError) {
16089 var logError = showErrorDialog(capturedError);
16090
16091 // Allow injected showErrorDialog() to prevent default console.error logging.
16092 // This enables renderers like ReactNative to better manage redbox behavior.
16093 if (logError === false) {
16094 return;
16095 }
16096
16097 var error = capturedError.error;
16098 {
16099 var componentName = capturedError.componentName,
16100 componentStack = capturedError.componentStack,
16101 errorBoundaryName = capturedError.errorBoundaryName,
16102 errorBoundaryFound = capturedError.errorBoundaryFound,
16103 willRetry = capturedError.willRetry;
16104
16105 // Browsers support silencing uncaught errors by calling
16106 // `preventDefault()` in window `error` handler.
16107 // We record this information as an expando on the error.
16108
16109 if (error != null && error._suppressLogging) {
16110 if (errorBoundaryFound && willRetry) {
16111 // The error is recoverable and was silenced.
16112 // Ignore it and don't print the stack addendum.
16113 // This is handy for testing error boundaries without noise.
16114 return;
16115 }
16116 // The error is fatal. Since the silencing might have
16117 // been accidental, we'll surface it anyway.
16118 // However, the browser would have silenced the original error
16119 // so we'll print it first, and then print the stack addendum.
16120 console.error(error);
16121 // For a more detailed description of this block, see:
16122 // https://github.com/facebook/react/pull/13384
16123 }
16124
16125 var componentNameMessage = componentName ? 'The above error occurred in the <' + componentName + '> component:' : 'The above error occurred in one of your React components:';
16126
16127 var errorBoundaryMessage = void 0;
16128 // errorBoundaryFound check is sufficient; errorBoundaryName check is to satisfy Flow.
16129 if (errorBoundaryFound && errorBoundaryName) {
16130 if (willRetry) {
16131 errorBoundaryMessage = 'React will try to recreate this component tree from scratch ' + ('using the error boundary you provided, ' + errorBoundaryName + '.');
16132 } else {
16133 errorBoundaryMessage = 'This error was initially handled by the error boundary ' + errorBoundaryName + '.\n' + 'Recreating the tree from scratch failed so React will unmount the tree.';
16134 }
16135 } else {
16136 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.';
16137 }
16138 var combinedMessage = '' + componentNameMessage + componentStack + '\n\n' + ('' + errorBoundaryMessage);
16139
16140 // In development, we provide our own message with just the component stack.
16141 // We don't include the original error message and JS stack because the browser
16142 // has already printed it. Even if the application swallows the error, it is still
16143 // displayed by the browser thanks to the DEV-only fake event trick in ReactErrorUtils.
16144 console.error(combinedMessage);
16145 }
16146}
16147
16148var didWarnAboutUndefinedSnapshotBeforeUpdate = null;
16149{
16150 didWarnAboutUndefinedSnapshotBeforeUpdate = new Set();
16151}
16152
16153var PossiblyWeakSet = typeof WeakSet === 'function' ? WeakSet : Set;
16154
16155function logError(boundary, errorInfo) {
16156 var source = errorInfo.source;
16157 var stack = errorInfo.stack;
16158 if (stack === null && source !== null) {
16159 stack = getStackByFiberInDevAndProd(source);
16160 }
16161
16162 var capturedError = {
16163 componentName: source !== null ? getComponentName(source.type) : null,
16164 componentStack: stack !== null ? stack : '',
16165 error: errorInfo.value,
16166 errorBoundary: null,
16167 errorBoundaryName: null,
16168 errorBoundaryFound: false,
16169 willRetry: false
16170 };
16171
16172 if (boundary !== null && boundary.tag === ClassComponent) {
16173 capturedError.errorBoundary = boundary.stateNode;
16174 capturedError.errorBoundaryName = getComponentName(boundary.type);
16175 capturedError.errorBoundaryFound = true;
16176 capturedError.willRetry = true;
16177 }
16178
16179 try {
16180 logCapturedError(capturedError);
16181 } catch (e) {
16182 // This method must not throw, or React internal state will get messed up.
16183 // If console.error is overridden, or logCapturedError() shows a dialog that throws,
16184 // we want to report this error outside of the normal stack as a last resort.
16185 // https://github.com/facebook/react/issues/13188
16186 setTimeout(function () {
16187 throw e;
16188 });
16189 }
16190}
16191
16192var callComponentWillUnmountWithTimer = function (current$$1, instance) {
16193 startPhaseTimer(current$$1, 'componentWillUnmount');
16194 instance.props = current$$1.memoizedProps;
16195 instance.state = current$$1.memoizedState;
16196 instance.componentWillUnmount();
16197 stopPhaseTimer();
16198};
16199
16200// Capture errors so they don't interrupt unmounting.
16201function safelyCallComponentWillUnmount(current$$1, instance) {
16202 {
16203 invokeGuardedCallback(null, callComponentWillUnmountWithTimer, null, current$$1, instance);
16204 if (hasCaughtError()) {
16205 var unmountError = clearCaughtError();
16206 captureCommitPhaseError(current$$1, unmountError);
16207 }
16208 }
16209}
16210
16211function safelyDetachRef(current$$1) {
16212 var ref = current$$1.ref;
16213 if (ref !== null) {
16214 if (typeof ref === 'function') {
16215 {
16216 invokeGuardedCallback(null, ref, null, null);
16217 if (hasCaughtError()) {
16218 var refError = clearCaughtError();
16219 captureCommitPhaseError(current$$1, refError);
16220 }
16221 }
16222 } else {
16223 ref.current = null;
16224 }
16225 }
16226}
16227
16228function safelyCallDestroy(current$$1, destroy) {
16229 {
16230 invokeGuardedCallback(null, destroy, null);
16231 if (hasCaughtError()) {
16232 var error = clearCaughtError();
16233 captureCommitPhaseError(current$$1, error);
16234 }
16235 }
16236}
16237
16238function commitBeforeMutationLifeCycles(current$$1, finishedWork) {
16239 switch (finishedWork.tag) {
16240 case FunctionComponent:
16241 case ForwardRef:
16242 case SimpleMemoComponent:
16243 {
16244 commitHookEffectList(UnmountSnapshot, NoEffect$1, finishedWork);
16245 return;
16246 }
16247 case ClassComponent:
16248 {
16249 if (finishedWork.effectTag & Snapshot) {
16250 if (current$$1 !== null) {
16251 var prevProps = current$$1.memoizedProps;
16252 var prevState = current$$1.memoizedState;
16253 startPhaseTimer(finishedWork, 'getSnapshotBeforeUpdate');
16254 var instance = finishedWork.stateNode;
16255 // We could update instance props and state here,
16256 // but instead we rely on them being set during last render.
16257 // TODO: revisit this when we implement resuming.
16258 {
16259 if (finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps) {
16260 !(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;
16261 !(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;
16262 }
16263 }
16264 var snapshot = instance.getSnapshotBeforeUpdate(finishedWork.elementType === finishedWork.type ? prevProps : resolveDefaultProps(finishedWork.type, prevProps), prevState);
16265 {
16266 var didWarnSet = didWarnAboutUndefinedSnapshotBeforeUpdate;
16267 if (snapshot === undefined && !didWarnSet.has(finishedWork.type)) {
16268 didWarnSet.add(finishedWork.type);
16269 warningWithoutStack$1(false, '%s.getSnapshotBeforeUpdate(): A snapshot value (or null) ' + 'must be returned. You have returned undefined.', getComponentName(finishedWork.type));
16270 }
16271 }
16272 instance.__reactInternalSnapshotBeforeUpdate = snapshot;
16273 stopPhaseTimer();
16274 }
16275 }
16276 return;
16277 }
16278 case HostRoot:
16279 case HostComponent:
16280 case HostText:
16281 case HostPortal:
16282 case IncompleteClassComponent:
16283 // Nothing to do for these component types
16284 return;
16285 default:
16286 {
16287 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.');
16288 }
16289 }
16290}
16291
16292function commitHookEffectList(unmountTag, mountTag, finishedWork) {
16293 if (!enableHooks) {
16294 return;
16295 }
16296 var updateQueue = finishedWork.updateQueue;
16297 var lastEffect = updateQueue !== null ? updateQueue.lastEffect : null;
16298 if (lastEffect !== null) {
16299 var firstEffect = lastEffect.next;
16300 var effect = firstEffect;
16301 do {
16302 if ((effect.tag & unmountTag) !== NoEffect$1) {
16303 // Unmount
16304 var destroy = effect.destroy;
16305 effect.destroy = null;
16306 if (destroy !== null) {
16307 destroy();
16308 }
16309 }
16310 if ((effect.tag & mountTag) !== NoEffect$1) {
16311 // Mount
16312 var create = effect.create;
16313 var _destroy = create();
16314 if (typeof _destroy !== 'function') {
16315 {
16316 if (_destroy !== null && _destroy !== undefined) {
16317 warningWithoutStack$1(false, 'useEffect function must return a cleanup function or ' + 'nothing.%s%s', typeof _destroy.then === 'function' ? '\n\nIt looks like you wrote useEffect(async () => ...) or returned a Promise. ' + 'Instead, you may write an async function separately ' + 'and then call it from inside the effect:\n\n' + 'async function fetchComment(commentId) {\n' + ' // You can await here\n' + '}\n\n' + 'useEffect(() => {\n' + ' fetchComment(commentId);\n' + '}, [commentId]);\n\n' + 'In the future, React will provide a more idiomatic solution for data fetching ' + "that doesn't involve writing effects manually." : '', getStackByFiberInDevAndProd(finishedWork));
16318 }
16319 }
16320 _destroy = null;
16321 }
16322 effect.destroy = _destroy;
16323 }
16324 effect = effect.next;
16325 } while (effect !== firstEffect);
16326 }
16327}
16328
16329function commitPassiveHookEffects(finishedWork) {
16330 commitHookEffectList(UnmountPassive, NoEffect$1, finishedWork);
16331 commitHookEffectList(NoEffect$1, MountPassive, finishedWork);
16332}
16333
16334function commitLifeCycles(finishedRoot, current$$1, finishedWork, committedExpirationTime) {
16335 switch (finishedWork.tag) {
16336 case FunctionComponent:
16337 case ForwardRef:
16338 case SimpleMemoComponent:
16339 {
16340 commitHookEffectList(UnmountLayout, MountLayout, finishedWork);
16341 break;
16342 }
16343 case ClassComponent:
16344 {
16345 var instance = finishedWork.stateNode;
16346 if (finishedWork.effectTag & Update) {
16347 if (current$$1 === null) {
16348 startPhaseTimer(finishedWork, 'componentDidMount');
16349 // We could update instance props and state here,
16350 // but instead we rely on them being set during last render.
16351 // TODO: revisit this when we implement resuming.
16352 {
16353 if (finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps) {
16354 !(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;
16355 !(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;
16356 }
16357 }
16358 instance.componentDidMount();
16359 stopPhaseTimer();
16360 } else {
16361 var prevProps = finishedWork.elementType === finishedWork.type ? current$$1.memoizedProps : resolveDefaultProps(finishedWork.type, current$$1.memoizedProps);
16362 var prevState = current$$1.memoizedState;
16363 startPhaseTimer(finishedWork, 'componentDidUpdate');
16364 // We could update instance props and state here,
16365 // but instead we rely on them being set during last render.
16366 // TODO: revisit this when we implement resuming.
16367 {
16368 if (finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps) {
16369 !(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;
16370 !(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;
16371 }
16372 }
16373 instance.componentDidUpdate(prevProps, prevState, instance.__reactInternalSnapshotBeforeUpdate);
16374 stopPhaseTimer();
16375 }
16376 }
16377 var updateQueue = finishedWork.updateQueue;
16378 if (updateQueue !== null) {
16379 {
16380 if (finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps) {
16381 !(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;
16382 !(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;
16383 }
16384 }
16385 // We could update instance props and state here,
16386 // but instead we rely on them being set during last render.
16387 // TODO: revisit this when we implement resuming.
16388 commitUpdateQueue(finishedWork, updateQueue, instance, committedExpirationTime);
16389 }
16390 return;
16391 }
16392 case HostRoot:
16393 {
16394 var _updateQueue = finishedWork.updateQueue;
16395 if (_updateQueue !== null) {
16396 var _instance = null;
16397 if (finishedWork.child !== null) {
16398 switch (finishedWork.child.tag) {
16399 case HostComponent:
16400 _instance = getPublicInstance(finishedWork.child.stateNode);
16401 break;
16402 case ClassComponent:
16403 _instance = finishedWork.child.stateNode;
16404 break;
16405 }
16406 }
16407 commitUpdateQueue(finishedWork, _updateQueue, _instance, committedExpirationTime);
16408 }
16409 return;
16410 }
16411 case HostComponent:
16412 {
16413 var _instance2 = finishedWork.stateNode;
16414
16415 // Renderers may schedule work to be done after host components are mounted
16416 // (eg DOM renderer may schedule auto-focus for inputs and form controls).
16417 // These effects should only be committed when components are first mounted,
16418 // aka when there is no current/alternate.
16419 if (current$$1 === null && finishedWork.effectTag & Update) {
16420 var type = finishedWork.type;
16421 var props = finishedWork.memoizedProps;
16422 commitMount(_instance2, type, props, finishedWork);
16423 }
16424
16425 return;
16426 }
16427 case HostText:
16428 {
16429 // We have no life-cycles associated with text.
16430 return;
16431 }
16432 case HostPortal:
16433 {
16434 // We have no life-cycles associated with portals.
16435 return;
16436 }
16437 case Profiler:
16438 {
16439 if (enableProfilerTimer) {
16440 var onRender = finishedWork.memoizedProps.onRender;
16441
16442 if (enableSchedulerTracing) {
16443 onRender(finishedWork.memoizedProps.id, current$$1 === null ? 'mount' : 'update', finishedWork.actualDuration, finishedWork.treeBaseDuration, finishedWork.actualStartTime, getCommitTime(), finishedRoot.memoizedInteractions);
16444 } else {
16445 onRender(finishedWork.memoizedProps.id, current$$1 === null ? 'mount' : 'update', finishedWork.actualDuration, finishedWork.treeBaseDuration, finishedWork.actualStartTime, getCommitTime());
16446 }
16447 }
16448 return;
16449 }
16450 case SuspenseComponent:
16451 break;
16452 case IncompleteClassComponent:
16453 break;
16454 default:
16455 {
16456 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.');
16457 }
16458 }
16459}
16460
16461function hideOrUnhideAllChildren(finishedWork, isHidden) {
16462 if (supportsMutation) {
16463 // We only have the top Fiber that was inserted but we need recurse down its
16464 var node = finishedWork;
16465 while (true) {
16466 if (node.tag === HostComponent) {
16467 var instance = node.stateNode;
16468 if (isHidden) {
16469 hideInstance(instance);
16470 } else {
16471 unhideInstance(node.stateNode, node.memoizedProps);
16472 }
16473 } else if (node.tag === HostText) {
16474 var _instance3 = node.stateNode;
16475 if (isHidden) {
16476 hideTextInstance(_instance3);
16477 } else {
16478 unhideTextInstance(_instance3, node.memoizedProps);
16479 }
16480 } else if (node.tag === SuspenseComponent && node.memoizedState !== null) {
16481 // Found a nested Suspense component that timed out. Skip over the
16482 var fallbackChildFragment = node.child.sibling;
16483 fallbackChildFragment.return = node;
16484 node = fallbackChildFragment;
16485 continue;
16486 } else if (node.child !== null) {
16487 node.child.return = node;
16488 node = node.child;
16489 continue;
16490 }
16491 if (node === finishedWork) {
16492 return;
16493 }
16494 while (node.sibling === null) {
16495 if (node.return === null || node.return === finishedWork) {
16496 return;
16497 }
16498 node = node.return;
16499 }
16500 node.sibling.return = node.return;
16501 node = node.sibling;
16502 }
16503 }
16504}
16505
16506function commitAttachRef(finishedWork) {
16507 var ref = finishedWork.ref;
16508 if (ref !== null) {
16509 var instance = finishedWork.stateNode;
16510 var instanceToUse = void 0;
16511 switch (finishedWork.tag) {
16512 case HostComponent:
16513 instanceToUse = getPublicInstance(instance);
16514 break;
16515 default:
16516 instanceToUse = instance;
16517 }
16518 if (typeof ref === 'function') {
16519 ref(instanceToUse);
16520 } else {
16521 {
16522 if (!ref.hasOwnProperty('current')) {
16523 warningWithoutStack$1(false, 'Unexpected ref object provided for %s. ' + 'Use either a ref-setter function or React.createRef().%s', getComponentName(finishedWork.type), getStackByFiberInDevAndProd(finishedWork));
16524 }
16525 }
16526
16527 ref.current = instanceToUse;
16528 }
16529 }
16530}
16531
16532function commitDetachRef(current$$1) {
16533 var currentRef = current$$1.ref;
16534 if (currentRef !== null) {
16535 if (typeof currentRef === 'function') {
16536 currentRef(null);
16537 } else {
16538 currentRef.current = null;
16539 }
16540 }
16541}
16542
16543// User-originating errors (lifecycles and refs) should not interrupt
16544// deletion, so don't let them throw. Host-originating errors should
16545// interrupt deletion, so it's okay
16546function commitUnmount(current$$1) {
16547 onCommitUnmount(current$$1);
16548
16549 switch (current$$1.tag) {
16550 case FunctionComponent:
16551 case ForwardRef:
16552 case MemoComponent:
16553 case SimpleMemoComponent:
16554 {
16555 var updateQueue = current$$1.updateQueue;
16556 if (updateQueue !== null) {
16557 var lastEffect = updateQueue.lastEffect;
16558 if (lastEffect !== null) {
16559 var firstEffect = lastEffect.next;
16560 var effect = firstEffect;
16561 do {
16562 var destroy = effect.destroy;
16563 if (destroy !== null) {
16564 safelyCallDestroy(current$$1, destroy);
16565 }
16566 effect = effect.next;
16567 } while (effect !== firstEffect);
16568 }
16569 }
16570 break;
16571 }
16572 case ClassComponent:
16573 {
16574 safelyDetachRef(current$$1);
16575 var instance = current$$1.stateNode;
16576 if (typeof instance.componentWillUnmount === 'function') {
16577 safelyCallComponentWillUnmount(current$$1, instance);
16578 }
16579 return;
16580 }
16581 case HostComponent:
16582 {
16583 safelyDetachRef(current$$1);
16584 return;
16585 }
16586 case HostPortal:
16587 {
16588 // TODO: this is recursive.
16589 // We are also not using this parent because
16590 // the portal will get pushed immediately.
16591 if (supportsMutation) {
16592 unmountHostComponents(current$$1);
16593 } else if (supportsPersistence) {
16594 emptyPortalContainer(current$$1);
16595 }
16596 return;
16597 }
16598 }
16599}
16600
16601function commitNestedUnmounts(root) {
16602 // While we're inside a removed host node we don't want to call
16603 // removeChild on the inner nodes because they're removed by the top
16604 // call anyway. We also want to call componentWillUnmount on all
16605 // composites before this host node is removed from the tree. Therefore
16606 var node = root;
16607 while (true) {
16608 commitUnmount(node);
16609 // Visit children because they may contain more composite or host nodes.
16610 // Skip portals because commitUnmount() currently visits them recursively.
16611 if (node.child !== null && (
16612 // If we use mutation we drill down into portals using commitUnmount above.
16613 // If we don't use mutation we drill down into portals here instead.
16614 !supportsMutation || node.tag !== HostPortal)) {
16615 node.child.return = node;
16616 node = node.child;
16617 continue;
16618 }
16619 if (node === root) {
16620 return;
16621 }
16622 while (node.sibling === null) {
16623 if (node.return === null || node.return === root) {
16624 return;
16625 }
16626 node = node.return;
16627 }
16628 node.sibling.return = node.return;
16629 node = node.sibling;
16630 }
16631}
16632
16633function detachFiber(current$$1) {
16634 // Cut off the return pointers to disconnect it from the tree. Ideally, we
16635 // should clear the child pointer of the parent alternate to let this
16636 // get GC:ed but we don't know which for sure which parent is the current
16637 // one so we'll settle for GC:ing the subtree of this child. This child
16638 // itself will be GC:ed when the parent updates the next time.
16639 current$$1.return = null;
16640 current$$1.child = null;
16641 current$$1.memoizedState = null;
16642 current$$1.updateQueue = null;
16643 var alternate = current$$1.alternate;
16644 if (alternate !== null) {
16645 alternate.return = null;
16646 alternate.child = null;
16647 alternate.memoizedState = null;
16648 alternate.updateQueue = null;
16649 }
16650}
16651
16652function emptyPortalContainer(current$$1) {
16653 if (!supportsPersistence) {
16654 return;
16655 }
16656
16657 var portal = current$$1.stateNode;
16658 var containerInfo = portal.containerInfo;
16659
16660 var emptyChildSet = createContainerChildSet(containerInfo);
16661 replaceContainerChildren(containerInfo, emptyChildSet);
16662}
16663
16664function commitContainer(finishedWork) {
16665 if (!supportsPersistence) {
16666 return;
16667 }
16668
16669 switch (finishedWork.tag) {
16670 case ClassComponent:
16671 {
16672 return;
16673 }
16674 case HostComponent:
16675 {
16676 return;
16677 }
16678 case HostText:
16679 {
16680 return;
16681 }
16682 case HostRoot:
16683 case HostPortal:
16684 {
16685 var portalOrRoot = finishedWork.stateNode;
16686 var containerInfo = portalOrRoot.containerInfo,
16687 _pendingChildren = portalOrRoot.pendingChildren;
16688
16689 replaceContainerChildren(containerInfo, _pendingChildren);
16690 return;
16691 }
16692 default:
16693 {
16694 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.');
16695 }
16696 }
16697}
16698
16699function getHostParentFiber(fiber) {
16700 var parent = fiber.return;
16701 while (parent !== null) {
16702 if (isHostParent(parent)) {
16703 return parent;
16704 }
16705 parent = parent.return;
16706 }
16707 invariant(false, 'Expected to find a host parent. This error is likely caused by a bug in React. Please file an issue.');
16708}
16709
16710function isHostParent(fiber) {
16711 return fiber.tag === HostComponent || fiber.tag === HostRoot || fiber.tag === HostPortal;
16712}
16713
16714function getHostSibling(fiber) {
16715 // We're going to search forward into the tree until we find a sibling host
16716 // node. Unfortunately, if multiple insertions are done in a row we have to
16717 // search past them. This leads to exponential search for the next sibling.
16718 var node = fiber;
16719 siblings: while (true) {
16720 // If we didn't find anything, let's try the next sibling.
16721 while (node.sibling === null) {
16722 if (node.return === null || isHostParent(node.return)) {
16723 // If we pop out of the root or hit the parent the fiber we are the
16724 // last sibling.
16725 return null;
16726 }
16727 node = node.return;
16728 }
16729 node.sibling.return = node.return;
16730 node = node.sibling;
16731 while (node.tag !== HostComponent && node.tag !== HostText) {
16732 // If it is not host node and, we might have a host node inside it.
16733 // Try to search down until we find one.
16734 if (node.effectTag & Placement) {
16735 // If we don't have a child, try the siblings instead.
16736 continue siblings;
16737 }
16738 // If we don't have a child, try the siblings instead.
16739 // We also skip portals because they are not part of this host tree.
16740 if (node.child === null || node.tag === HostPortal) {
16741 continue siblings;
16742 } else {
16743 node.child.return = node;
16744 node = node.child;
16745 }
16746 }
16747 // Check if this host node is stable or about to be placed.
16748 if (!(node.effectTag & Placement)) {
16749 // Found it!
16750 return node.stateNode;
16751 }
16752 }
16753}
16754
16755function commitPlacement(finishedWork) {
16756 if (!supportsMutation) {
16757 return;
16758 }
16759
16760 // Recursively insert all host nodes into the parent.
16761 var parentFiber = getHostParentFiber(finishedWork);
16762
16763 // Note: these two variables *must* always be updated together.
16764 var parent = void 0;
16765 var isContainer = void 0;
16766
16767 switch (parentFiber.tag) {
16768 case HostComponent:
16769 parent = parentFiber.stateNode;
16770 isContainer = false;
16771 break;
16772 case HostRoot:
16773 parent = parentFiber.stateNode.containerInfo;
16774 isContainer = true;
16775 break;
16776 case HostPortal:
16777 parent = parentFiber.stateNode.containerInfo;
16778 isContainer = true;
16779 break;
16780 default:
16781 invariant(false, 'Invalid host parent fiber. This error is likely caused by a bug in React. Please file an issue.');
16782 }
16783 if (parentFiber.effectTag & ContentReset) {
16784 // Reset the text content of the parent before doing any insertions
16785 resetTextContent(parent);
16786 // Clear ContentReset from the effect tag
16787 parentFiber.effectTag &= ~ContentReset;
16788 }
16789
16790 var before = getHostSibling(finishedWork);
16791 // We only have the top Fiber that was inserted but we need recurse down its
16792 // children to find all the terminal nodes.
16793 var node = finishedWork;
16794 while (true) {
16795 if (node.tag === HostComponent || node.tag === HostText) {
16796 if (before) {
16797 if (isContainer) {
16798 insertInContainerBefore(parent, node.stateNode, before);
16799 } else {
16800 insertBefore(parent, node.stateNode, before);
16801 }
16802 } else {
16803 if (isContainer) {
16804 appendChildToContainer(parent, node.stateNode);
16805 } else {
16806 appendChild(parent, node.stateNode);
16807 }
16808 }
16809 } else if (node.tag === HostPortal) {
16810 // If the insertion itself is a portal, then we don't want to traverse
16811 // down its children. Instead, we'll get insertions from each child in
16812 // the portal directly.
16813 } else if (node.child !== null) {
16814 node.child.return = node;
16815 node = node.child;
16816 continue;
16817 }
16818 if (node === finishedWork) {
16819 return;
16820 }
16821 while (node.sibling === null) {
16822 if (node.return === null || node.return === finishedWork) {
16823 return;
16824 }
16825 node = node.return;
16826 }
16827 node.sibling.return = node.return;
16828 node = node.sibling;
16829 }
16830}
16831
16832function unmountHostComponents(current$$1) {
16833 // We only have the top Fiber that was deleted but we need recurse down its
16834 var node = current$$1;
16835
16836 // Each iteration, currentParent is populated with node's host parent if not
16837 // currentParentIsValid.
16838 var currentParentIsValid = false;
16839
16840 // Note: these two variables *must* always be updated together.
16841 var currentParent = void 0;
16842 var currentParentIsContainer = void 0;
16843
16844 while (true) {
16845 if (!currentParentIsValid) {
16846 var parent = node.return;
16847 findParent: while (true) {
16848 !(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;
16849 switch (parent.tag) {
16850 case HostComponent:
16851 currentParent = parent.stateNode;
16852 currentParentIsContainer = false;
16853 break findParent;
16854 case HostRoot:
16855 currentParent = parent.stateNode.containerInfo;
16856 currentParentIsContainer = true;
16857 break findParent;
16858 case HostPortal:
16859 currentParent = parent.stateNode.containerInfo;
16860 currentParentIsContainer = true;
16861 break findParent;
16862 }
16863 parent = parent.return;
16864 }
16865 currentParentIsValid = true;
16866 }
16867
16868 if (node.tag === HostComponent || node.tag === HostText) {
16869 commitNestedUnmounts(node);
16870 // After all the children have unmounted, it is now safe to remove the
16871 // node from the tree.
16872 if (currentParentIsContainer) {
16873 removeChildFromContainer(currentParent, node.stateNode);
16874 } else {
16875 removeChild(currentParent, node.stateNode);
16876 }
16877 // Don't visit children because we already visited them.
16878 } else if (node.tag === HostPortal) {
16879 // When we go into a portal, it becomes the parent to remove from.
16880 // We will reassign it back when we pop the portal on the way up.
16881 currentParent = node.stateNode.containerInfo;
16882 currentParentIsContainer = true;
16883 // Visit children because portals might contain host components.
16884 if (node.child !== null) {
16885 node.child.return = node;
16886 node = node.child;
16887 continue;
16888 }
16889 } else {
16890 commitUnmount(node);
16891 // Visit children because we may find more host components below.
16892 if (node.child !== null) {
16893 node.child.return = node;
16894 node = node.child;
16895 continue;
16896 }
16897 }
16898 if (node === current$$1) {
16899 return;
16900 }
16901 while (node.sibling === null) {
16902 if (node.return === null || node.return === current$$1) {
16903 return;
16904 }
16905 node = node.return;
16906 if (node.tag === HostPortal) {
16907 // When we go out of the portal, we need to restore the parent.
16908 // Since we don't keep a stack of them, we will search for it.
16909 currentParentIsValid = false;
16910 }
16911 }
16912 node.sibling.return = node.return;
16913 node = node.sibling;
16914 }
16915}
16916
16917function commitDeletion(current$$1) {
16918 if (supportsMutation) {
16919 // Recursively delete all host nodes from the parent.
16920 // Detach refs and call componentWillUnmount() on the whole subtree.
16921 unmountHostComponents(current$$1);
16922 } else {
16923 // Detach refs and call componentWillUnmount() on the whole subtree.
16924 commitNestedUnmounts(current$$1);
16925 }
16926 detachFiber(current$$1);
16927}
16928
16929function commitWork(current$$1, finishedWork) {
16930 if (!supportsMutation) {
16931 switch (finishedWork.tag) {
16932 case FunctionComponent:
16933 case ForwardRef:
16934 case MemoComponent:
16935 case SimpleMemoComponent:
16936 {
16937 // Note: We currently never use MountMutation, but useLayout uses
16938 // UnmountMutation.
16939 commitHookEffectList(UnmountMutation, MountMutation, finishedWork);
16940 return;
16941 }
16942 }
16943
16944 commitContainer(finishedWork);
16945 return;
16946 }
16947
16948 switch (finishedWork.tag) {
16949 case FunctionComponent:
16950 case ForwardRef:
16951 case MemoComponent:
16952 case SimpleMemoComponent:
16953 {
16954 // Note: We currently never use MountMutation, but useLayout uses
16955 // UnmountMutation.
16956 commitHookEffectList(UnmountMutation, MountMutation, finishedWork);
16957 return;
16958 }
16959 case ClassComponent:
16960 {
16961 return;
16962 }
16963 case HostComponent:
16964 {
16965 var instance = finishedWork.stateNode;
16966 if (instance != null) {
16967 // Commit the work prepared earlier.
16968 var newProps = finishedWork.memoizedProps;
16969 // For hydration we reuse the update path but we treat the oldProps
16970 // as the newProps. The updatePayload will contain the real change in
16971 // this case.
16972 var oldProps = current$$1 !== null ? current$$1.memoizedProps : newProps;
16973 var type = finishedWork.type;
16974 // TODO: Type the updateQueue to be specific to host components.
16975 var updatePayload = finishedWork.updateQueue;
16976 finishedWork.updateQueue = null;
16977 if (updatePayload !== null) {
16978 commitUpdate(instance, updatePayload, type, oldProps, newProps, finishedWork);
16979 }
16980 }
16981 return;
16982 }
16983 case HostText:
16984 {
16985 !(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;
16986 var textInstance = finishedWork.stateNode;
16987 var newText = finishedWork.memoizedProps;
16988 // For hydration we reuse the update path but we treat the oldProps
16989 // as the newProps. The updatePayload will contain the real change in
16990 // this case.
16991 var oldText = current$$1 !== null ? current$$1.memoizedProps : newText;
16992 commitTextUpdate(textInstance, oldText, newText);
16993 return;
16994 }
16995 case HostRoot:
16996 {
16997 return;
16998 }
16999 case Profiler:
17000 {
17001 return;
17002 }
17003 case SuspenseComponent:
17004 {
17005 var newState = finishedWork.memoizedState;
17006
17007 var newDidTimeout = void 0;
17008 var primaryChildParent = finishedWork;
17009 if (newState === null) {
17010 newDidTimeout = false;
17011 } else {
17012 newDidTimeout = true;
17013 primaryChildParent = finishedWork.child;
17014 if (newState.timedOutAt === NoWork) {
17015 // If the children had not already timed out, record the time.
17016 // This is used to compute the elapsed time during subsequent
17017 // attempts to render the children.
17018 newState.timedOutAt = requestCurrentTime();
17019 }
17020 }
17021
17022 if (primaryChildParent !== null) {
17023 hideOrUnhideAllChildren(primaryChildParent, newDidTimeout);
17024 }
17025
17026 // If this boundary just timed out, then it will have a set of thenables.
17027 // For each thenable, attach a listener so that when it resolves, React
17028 // attempts to re-render the boundary in the primary (pre-timeout) state.
17029 var thenables = finishedWork.updateQueue;
17030 if (thenables !== null) {
17031 finishedWork.updateQueue = null;
17032 var retryCache = finishedWork.stateNode;
17033 if (retryCache === null) {
17034 retryCache = finishedWork.stateNode = new PossiblyWeakSet();
17035 }
17036 thenables.forEach(function (thenable) {
17037 // Memoize using the boundary fiber to prevent redundant listeners.
17038 var retry = retryTimedOutBoundary.bind(null, finishedWork, thenable);
17039 if (enableSchedulerTracing) {
17040 retry = unstable_wrap(retry);
17041 }
17042 if (!retryCache.has(thenable)) {
17043 retryCache.add(thenable);
17044 thenable.then(retry, retry);
17045 }
17046 });
17047 }
17048
17049 return;
17050 }
17051 case IncompleteClassComponent:
17052 {
17053 return;
17054 }
17055 default:
17056 {
17057 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.');
17058 }
17059 }
17060}
17061
17062function commitResetTextContent(current$$1) {
17063 if (!supportsMutation) {
17064 return;
17065 }
17066 resetTextContent(current$$1.stateNode);
17067}
17068
17069var PossiblyWeakMap = typeof WeakMap === 'function' ? WeakMap : Map;
17070
17071function createRootErrorUpdate(fiber, errorInfo, expirationTime) {
17072 var update = createUpdate(expirationTime);
17073 // Unmount the root by rendering null.
17074 update.tag = CaptureUpdate;
17075 // Caution: React DevTools currently depends on this property
17076 // being called "element".
17077 update.payload = { element: null };
17078 var error = errorInfo.value;
17079 update.callback = function () {
17080 onUncaughtError(error);
17081 logError(fiber, errorInfo);
17082 };
17083 return update;
17084}
17085
17086function createClassErrorUpdate(fiber, errorInfo, expirationTime) {
17087 var update = createUpdate(expirationTime);
17088 update.tag = CaptureUpdate;
17089 var getDerivedStateFromError = fiber.type.getDerivedStateFromError;
17090 if (typeof getDerivedStateFromError === 'function') {
17091 var error = errorInfo.value;
17092 update.payload = function () {
17093 return getDerivedStateFromError(error);
17094 };
17095 }
17096
17097 var inst = fiber.stateNode;
17098 if (inst !== null && typeof inst.componentDidCatch === 'function') {
17099 update.callback = function callback() {
17100 if (typeof getDerivedStateFromError !== 'function') {
17101 // To preserve the preexisting retry behavior of error boundaries,
17102 // we keep track of which ones already failed during this batch.
17103 // This gets reset before we yield back to the browser.
17104 // TODO: Warn in strict mode if getDerivedStateFromError is
17105 // not defined.
17106 markLegacyErrorBoundaryAsFailed(this);
17107 }
17108 var error = errorInfo.value;
17109 var stack = errorInfo.stack;
17110 logError(fiber, errorInfo);
17111 this.componentDidCatch(error, {
17112 componentStack: stack !== null ? stack : ''
17113 });
17114 {
17115 if (typeof getDerivedStateFromError !== 'function') {
17116 // If componentDidCatch is the only error boundary method defined,
17117 // then it needs to call setState to recover from errors.
17118 // If no state update is scheduled then the boundary will swallow the error.
17119 !(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;
17120 }
17121 }
17122 };
17123 }
17124 return update;
17125}
17126
17127function throwException(root, returnFiber, sourceFiber, value, renderExpirationTime) {
17128 // The source fiber did not complete.
17129 sourceFiber.effectTag |= Incomplete;
17130 // Its effect list is no longer valid.
17131 sourceFiber.firstEffect = sourceFiber.lastEffect = null;
17132
17133 if (value !== null && typeof value === 'object' && typeof value.then === 'function') {
17134 // This is a thenable.
17135 var thenable = value;
17136
17137 // Find the earliest timeout threshold of all the placeholders in the
17138 // ancestor path. We could avoid this traversal by storing the thresholds on
17139 // the stack, but we choose not to because we only hit this path if we're
17140 // IO-bound (i.e. if something suspends). Whereas the stack is used even in
17141 // the non-IO- bound case.
17142 var _workInProgress = returnFiber;
17143 var earliestTimeoutMs = -1;
17144 var startTimeMs = -1;
17145 do {
17146 if (_workInProgress.tag === SuspenseComponent) {
17147 var current$$1 = _workInProgress.alternate;
17148 if (current$$1 !== null) {
17149 var currentState = current$$1.memoizedState;
17150 if (currentState !== null) {
17151 // Reached a boundary that already timed out. Do not search
17152 // any further.
17153 var timedOutAt = currentState.timedOutAt;
17154 startTimeMs = expirationTimeToMs(timedOutAt);
17155 // Do not search any further.
17156 break;
17157 }
17158 }
17159 var timeoutPropMs = _workInProgress.pendingProps.maxDuration;
17160 if (typeof timeoutPropMs === 'number') {
17161 if (timeoutPropMs <= 0) {
17162 earliestTimeoutMs = 0;
17163 } else if (earliestTimeoutMs === -1 || timeoutPropMs < earliestTimeoutMs) {
17164 earliestTimeoutMs = timeoutPropMs;
17165 }
17166 }
17167 }
17168 _workInProgress = _workInProgress.return;
17169 } while (_workInProgress !== null);
17170
17171 // Schedule the nearest Suspense to re-render the timed out view.
17172 _workInProgress = returnFiber;
17173 do {
17174 if (_workInProgress.tag === SuspenseComponent && shouldCaptureSuspense(_workInProgress)) {
17175 // Found the nearest boundary.
17176
17177 // Stash the promise on the boundary fiber. If the boundary times out, we'll
17178 var thenables = _workInProgress.updateQueue;
17179 if (thenables === null) {
17180 _workInProgress.updateQueue = new Set([thenable]);
17181 } else {
17182 thenables.add(thenable);
17183 }
17184
17185 // If the boundary is outside of concurrent mode, we should *not*
17186 // suspend the commit. Pretend as if the suspended component rendered
17187 // null and keep rendering. In the commit phase, we'll schedule a
17188 // subsequent synchronous update to re-render the Suspense.
17189 //
17190 // Note: It doesn't matter whether the component that suspended was
17191 // inside a concurrent mode tree. If the Suspense is outside of it, we
17192 // should *not* suspend the commit.
17193 if ((_workInProgress.mode & ConcurrentMode) === NoEffect) {
17194 _workInProgress.effectTag |= DidCapture;
17195
17196 // We're going to commit this fiber even though it didn't complete.
17197 // But we shouldn't call any lifecycle methods or callbacks. Remove
17198 // all lifecycle effect tags.
17199 sourceFiber.effectTag &= ~(LifecycleEffectMask | Incomplete);
17200
17201 if (sourceFiber.tag === ClassComponent) {
17202 var currentSourceFiber = sourceFiber.alternate;
17203 if (currentSourceFiber === null) {
17204 // This is a new mount. Change the tag so it's not mistaken for a
17205 // completed class component. For example, we should not call
17206 // componentWillUnmount if it is deleted.
17207 sourceFiber.tag = IncompleteClassComponent;
17208 } else {
17209 // When we try rendering again, we should not reuse the current fiber,
17210 // since it's known to be in an inconsistent state. Use a force updte to
17211 // prevent a bail out.
17212 var update = createUpdate(Sync);
17213 update.tag = ForceUpdate;
17214 enqueueUpdate(sourceFiber, update);
17215 }
17216 }
17217
17218 // The source fiber did not complete. Mark it with Sync priority to
17219 // indicate that it still has pending work.
17220 sourceFiber.expirationTime = Sync;
17221
17222 // Exit without suspending.
17223 return;
17224 }
17225
17226 // Confirmed that the boundary is in a concurrent mode tree. Continue
17227 // with the normal suspend path.
17228
17229 // Attach a listener to the promise to "ping" the root and retry. But
17230 // only if one does not already exist for the current render expiration
17231 // time (which acts like a "thread ID" here).
17232 var pingCache = root.pingCache;
17233 var threadIDs = void 0;
17234 if (pingCache === null) {
17235 pingCache = root.pingCache = new PossiblyWeakMap();
17236 threadIDs = new Set();
17237 pingCache.set(thenable, threadIDs);
17238 } else {
17239 threadIDs = pingCache.get(thenable);
17240 if (threadIDs === undefined) {
17241 threadIDs = new Set();
17242 pingCache.set(thenable, threadIDs);
17243 }
17244 }
17245 if (!threadIDs.has(renderExpirationTime)) {
17246 // Memoize using the thread ID to prevent redundant listeners.
17247 threadIDs.add(renderExpirationTime);
17248 var ping = pingSuspendedRoot.bind(null, root, thenable, renderExpirationTime);
17249 if (enableSchedulerTracing) {
17250 ping = unstable_wrap(ping);
17251 }
17252 thenable.then(ping, ping);
17253 }
17254
17255 var absoluteTimeoutMs = void 0;
17256 if (earliestTimeoutMs === -1) {
17257 // If no explicit threshold is given, default to an abitrarily large
17258 // value. The actual size doesn't matter because the threshold for the
17259 // whole tree will be clamped to the expiration time.
17260 absoluteTimeoutMs = maxSigned31BitInt;
17261 } else {
17262 if (startTimeMs === -1) {
17263 // This suspend happened outside of any already timed-out
17264 // placeholders. We don't know exactly when the update was
17265 // scheduled, but we can infer an approximate start time from the
17266 // expiration time. First, find the earliest uncommitted expiration
17267 // time in the tree, including work that is suspended. Then subtract
17268 // the offset used to compute an async update's expiration time.
17269 // This will cause high priority (interactive) work to expire
17270 // earlier than necessary, but we can account for this by adjusting
17271 // for the Just Noticeable Difference.
17272 var earliestExpirationTime = findEarliestOutstandingPriorityLevel(root, renderExpirationTime);
17273 var earliestExpirationTimeMs = expirationTimeToMs(earliestExpirationTime);
17274 startTimeMs = earliestExpirationTimeMs - LOW_PRIORITY_EXPIRATION;
17275 }
17276 absoluteTimeoutMs = startTimeMs + earliestTimeoutMs;
17277 }
17278
17279 // Mark the earliest timeout in the suspended fiber's ancestor path.
17280 // After completing the root, we'll take the largest of all the
17281 // suspended fiber's timeouts and use it to compute a timeout for the
17282 // whole tree.
17283 renderDidSuspend(root, absoluteTimeoutMs, renderExpirationTime);
17284
17285 _workInProgress.effectTag |= ShouldCapture;
17286 _workInProgress.expirationTime = renderExpirationTime;
17287 return;
17288 }
17289 // This boundary already captured during this render. Continue to the next
17290 // boundary.
17291 _workInProgress = _workInProgress.return;
17292 } while (_workInProgress !== null);
17293 // No boundary was found. Fallthrough to error mode.
17294 // TODO: Use invariant so the message is stripped in prod?
17295 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));
17296 }
17297
17298 // We didn't find a boundary that could handle this type of exception. Start
17299 // over and traverse parent path again, this time treating the exception
17300 // as an error.
17301 renderDidError();
17302 value = createCapturedValue(value, sourceFiber);
17303 var workInProgress = returnFiber;
17304 do {
17305 switch (workInProgress.tag) {
17306 case HostRoot:
17307 {
17308 var _errorInfo = value;
17309 workInProgress.effectTag |= ShouldCapture;
17310 workInProgress.expirationTime = renderExpirationTime;
17311 var _update = createRootErrorUpdate(workInProgress, _errorInfo, renderExpirationTime);
17312 enqueueCapturedUpdate(workInProgress, _update);
17313 return;
17314 }
17315 case ClassComponent:
17316 // Capture and retry
17317 var errorInfo = value;
17318 var ctor = workInProgress.type;
17319 var instance = workInProgress.stateNode;
17320 if ((workInProgress.effectTag & DidCapture) === NoEffect && (typeof ctor.getDerivedStateFromError === 'function' || instance !== null && typeof instance.componentDidCatch === 'function' && !isAlreadyFailedLegacyErrorBoundary(instance))) {
17321 workInProgress.effectTag |= ShouldCapture;
17322 workInProgress.expirationTime = renderExpirationTime;
17323 // Schedule the error boundary to re-render using updated state
17324 var _update2 = createClassErrorUpdate(workInProgress, errorInfo, renderExpirationTime);
17325 enqueueCapturedUpdate(workInProgress, _update2);
17326 return;
17327 }
17328 break;
17329 default:
17330 break;
17331 }
17332 workInProgress = workInProgress.return;
17333 } while (workInProgress !== null);
17334}
17335
17336function unwindWork(workInProgress, renderExpirationTime) {
17337 switch (workInProgress.tag) {
17338 case ClassComponent:
17339 {
17340 var Component = workInProgress.type;
17341 if (isContextProvider(Component)) {
17342 popContext(workInProgress);
17343 }
17344 var effectTag = workInProgress.effectTag;
17345 if (effectTag & ShouldCapture) {
17346 workInProgress.effectTag = effectTag & ~ShouldCapture | DidCapture;
17347 return workInProgress;
17348 }
17349 return null;
17350 }
17351 case HostRoot:
17352 {
17353 popHostContainer(workInProgress);
17354 popTopLevelContextObject(workInProgress);
17355 var _effectTag = workInProgress.effectTag;
17356 !((_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;
17357 workInProgress.effectTag = _effectTag & ~ShouldCapture | DidCapture;
17358 return workInProgress;
17359 }
17360 case HostComponent:
17361 {
17362 popHostContext(workInProgress);
17363 return null;
17364 }
17365 case SuspenseComponent:
17366 {
17367 var _effectTag2 = workInProgress.effectTag;
17368 if (_effectTag2 & ShouldCapture) {
17369 workInProgress.effectTag = _effectTag2 & ~ShouldCapture | DidCapture;
17370 // Captured a suspense effect. Re-render the boundary.
17371 return workInProgress;
17372 }
17373 return null;
17374 }
17375 case HostPortal:
17376 popHostContainer(workInProgress);
17377 return null;
17378 case ContextProvider:
17379 popProvider(workInProgress);
17380 return null;
17381 default:
17382 return null;
17383 }
17384}
17385
17386function unwindInterruptedWork(interruptedWork) {
17387 switch (interruptedWork.tag) {
17388 case ClassComponent:
17389 {
17390 var childContextTypes = interruptedWork.type.childContextTypes;
17391 if (childContextTypes !== null && childContextTypes !== undefined) {
17392 popContext(interruptedWork);
17393 }
17394 break;
17395 }
17396 case HostRoot:
17397 {
17398 popHostContainer(interruptedWork);
17399 popTopLevelContextObject(interruptedWork);
17400 break;
17401 }
17402 case HostComponent:
17403 {
17404 popHostContext(interruptedWork);
17405 break;
17406 }
17407 case HostPortal:
17408 popHostContainer(interruptedWork);
17409 break;
17410 case ContextProvider:
17411 popProvider(interruptedWork);
17412 break;
17413 default:
17414 break;
17415 }
17416}
17417
17418var Dispatcher = {
17419 readContext: readContext,
17420 useCallback: useCallback,
17421 useContext: useContext,
17422 useEffect: useEffect,
17423 useImperativeMethods: useImperativeMethods,
17424 useLayoutEffect: useLayoutEffect,
17425 useMemo: useMemo,
17426 useReducer: useReducer,
17427 useRef: useRef,
17428 useState: useState
17429};
17430var DispatcherWithoutHooks = {
17431 readContext: readContext
17432};
17433
17434var ReactCurrentOwner$2 = ReactSharedInternals.ReactCurrentOwner;
17435
17436
17437var didWarnAboutStateTransition = void 0;
17438var didWarnSetStateChildContext = void 0;
17439var warnAboutUpdateOnUnmounted = void 0;
17440var warnAboutInvalidUpdates = void 0;
17441
17442if (enableSchedulerTracing) {
17443 // Provide explicit error message when production+profiling bundle of e.g. react-dom
17444 // is used with production (non-profiling) bundle of scheduler/tracing
17445 !(__interactionsRef != null && __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;
17446}
17447
17448{
17449 didWarnAboutStateTransition = false;
17450 didWarnSetStateChildContext = false;
17451 var didWarnStateUpdateForUnmountedComponent = {};
17452
17453 warnAboutUpdateOnUnmounted = function (fiber, isClass) {
17454 // We show the whole stack but dedupe on the top component's name because
17455 // the problematic code almost always lies inside that component.
17456 var componentName = getComponentName(fiber.type) || 'ReactComponent';
17457 if (didWarnStateUpdateForUnmountedComponent[componentName]) {
17458 return;
17459 }
17460 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));
17461 didWarnStateUpdateForUnmountedComponent[componentName] = true;
17462 };
17463
17464 warnAboutInvalidUpdates = function (instance) {
17465 switch (phase) {
17466 case 'getChildContext':
17467 if (didWarnSetStateChildContext) {
17468 return;
17469 }
17470 warningWithoutStack$1(false, 'setState(...): Cannot call setState() inside getChildContext()');
17471 didWarnSetStateChildContext = true;
17472 break;
17473 case 'render':
17474 if (didWarnAboutStateTransition) {
17475 return;
17476 }
17477 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.');
17478 didWarnAboutStateTransition = true;
17479 break;
17480 }
17481 };
17482}
17483
17484// Used to ensure computeUniqueAsyncExpiration is monotonically decreasing.
17485var lastUniqueAsyncExpiration = Sync - 1;
17486
17487// Represents the expiration time that incoming updates should use. (If this
17488// is NoWork, use the default strategy: async updates in async mode, sync
17489// updates in sync mode.)
17490var expirationContext = NoWork;
17491
17492var isWorking = false;
17493
17494// The next work in progress fiber that we're currently working on.
17495var nextUnitOfWork = null;
17496var nextRoot = null;
17497// The time at which we're currently rendering work.
17498var nextRenderExpirationTime = NoWork;
17499var nextLatestAbsoluteTimeoutMs = -1;
17500var nextRenderDidError = false;
17501
17502// The next fiber with an effect that we're currently committing.
17503var nextEffect = null;
17504
17505var isCommitting$1 = false;
17506var rootWithPendingPassiveEffects = null;
17507var passiveEffectCallbackHandle = null;
17508var passiveEffectCallback = null;
17509
17510var legacyErrorBoundariesThatAlreadyFailed = null;
17511
17512// Used for performance tracking.
17513var interruptedBy = null;
17514
17515var stashedWorkInProgressProperties = void 0;
17516var replayUnitOfWork = void 0;
17517var mayReplayFailedUnitOfWork = void 0;
17518var isReplayingFailedUnitOfWork = void 0;
17519var originalReplayError = void 0;
17520var rethrowOriginalError = void 0;
17521if (true && replayFailedUnitOfWorkWithInvokeGuardedCallback) {
17522 stashedWorkInProgressProperties = null;
17523 mayReplayFailedUnitOfWork = true;
17524 isReplayingFailedUnitOfWork = false;
17525 originalReplayError = null;
17526 replayUnitOfWork = function (failedUnitOfWork, thrownValue, isYieldy) {
17527 if (thrownValue !== null && typeof thrownValue === 'object' && typeof thrownValue.then === 'function') {
17528 // Don't replay promises. Treat everything else like an error.
17529 // TODO: Need to figure out a different strategy if/when we add
17530 // support for catching other types.
17531 return;
17532 }
17533
17534 // Restore the original state of the work-in-progress
17535 if (stashedWorkInProgressProperties === null) {
17536 // This should never happen. Don't throw because this code is DEV-only.
17537 warningWithoutStack$1(false, 'Could not replay rendering after an error. This is likely a bug in React. ' + 'Please file an issue.');
17538 return;
17539 }
17540 assignFiberPropertiesInDEV(failedUnitOfWork, stashedWorkInProgressProperties);
17541
17542 switch (failedUnitOfWork.tag) {
17543 case HostRoot:
17544 popHostContainer(failedUnitOfWork);
17545 popTopLevelContextObject(failedUnitOfWork);
17546 break;
17547 case HostComponent:
17548 popHostContext(failedUnitOfWork);
17549 break;
17550 case ClassComponent:
17551 {
17552 var Component = failedUnitOfWork.type;
17553 if (isContextProvider(Component)) {
17554 popContext(failedUnitOfWork);
17555 }
17556 break;
17557 }
17558 case HostPortal:
17559 popHostContainer(failedUnitOfWork);
17560 break;
17561 case ContextProvider:
17562 popProvider(failedUnitOfWork);
17563 break;
17564 }
17565 // Replay the begin phase.
17566 isReplayingFailedUnitOfWork = true;
17567 originalReplayError = thrownValue;
17568 invokeGuardedCallback(null, workLoop, null, isYieldy);
17569 isReplayingFailedUnitOfWork = false;
17570 originalReplayError = null;
17571 if (hasCaughtError()) {
17572 var replayError = clearCaughtError();
17573 if (replayError != null && thrownValue != null) {
17574 try {
17575 // Reading the expando property is intentionally
17576 // inside `try` because it might be a getter or Proxy.
17577 if (replayError._suppressLogging) {
17578 // Also suppress logging for the original error.
17579 thrownValue._suppressLogging = true;
17580 }
17581 } catch (inner) {
17582 // Ignore.
17583 }
17584 }
17585 } else {
17586 // If the begin phase did not fail the second time, set this pointer
17587 // back to the original value.
17588 nextUnitOfWork = failedUnitOfWork;
17589 }
17590 };
17591 rethrowOriginalError = function () {
17592 throw originalReplayError;
17593 };
17594}
17595
17596function resetStack() {
17597 if (nextUnitOfWork !== null) {
17598 var interruptedWork = nextUnitOfWork.return;
17599 while (interruptedWork !== null) {
17600 unwindInterruptedWork(interruptedWork);
17601 interruptedWork = interruptedWork.return;
17602 }
17603 }
17604
17605 {
17606 ReactStrictModeWarnings.discardPendingWarnings();
17607 checkThatStackIsEmpty();
17608 }
17609
17610 nextRoot = null;
17611 nextRenderExpirationTime = NoWork;
17612 nextLatestAbsoluteTimeoutMs = -1;
17613 nextRenderDidError = false;
17614 nextUnitOfWork = null;
17615}
17616
17617function commitAllHostEffects() {
17618 while (nextEffect !== null) {
17619 {
17620 setCurrentFiber(nextEffect);
17621 }
17622 recordEffect();
17623
17624 var effectTag = nextEffect.effectTag;
17625
17626 if (effectTag & ContentReset) {
17627 commitResetTextContent(nextEffect);
17628 }
17629
17630 if (effectTag & Ref) {
17631 var current$$1 = nextEffect.alternate;
17632 if (current$$1 !== null) {
17633 commitDetachRef(current$$1);
17634 }
17635 }
17636
17637 // The following switch statement is only concerned about placement,
17638 // updates, and deletions. To avoid needing to add a case for every
17639 // possible bitmap value, we remove the secondary effects from the
17640 // effect tag and switch on that value.
17641 var primaryEffectTag = effectTag & (Placement | Update | Deletion);
17642 switch (primaryEffectTag) {
17643 case Placement:
17644 {
17645 commitPlacement(nextEffect);
17646 // Clear the "placement" from effect tag so that we know that this is inserted, before
17647 // any life-cycles like componentDidMount gets called.
17648 // TODO: findDOMNode doesn't rely on this any more but isMounted
17649 // does and isMounted is deprecated anyway so we should be able
17650 // to kill this.
17651 nextEffect.effectTag &= ~Placement;
17652 break;
17653 }
17654 case PlacementAndUpdate:
17655 {
17656 // Placement
17657 commitPlacement(nextEffect);
17658 // Clear the "placement" from effect tag so that we know that this is inserted, before
17659 // any life-cycles like componentDidMount gets called.
17660 nextEffect.effectTag &= ~Placement;
17661
17662 // Update
17663 var _current = nextEffect.alternate;
17664 commitWork(_current, nextEffect);
17665 break;
17666 }
17667 case Update:
17668 {
17669 var _current2 = nextEffect.alternate;
17670 commitWork(_current2, nextEffect);
17671 break;
17672 }
17673 case Deletion:
17674 {
17675 commitDeletion(nextEffect);
17676 break;
17677 }
17678 }
17679 nextEffect = nextEffect.nextEffect;
17680 }
17681
17682 {
17683 resetCurrentFiber();
17684 }
17685}
17686
17687function commitBeforeMutationLifecycles() {
17688 while (nextEffect !== null) {
17689 {
17690 setCurrentFiber(nextEffect);
17691 }
17692
17693 var effectTag = nextEffect.effectTag;
17694 if (effectTag & Snapshot) {
17695 recordEffect();
17696 var current$$1 = nextEffect.alternate;
17697 commitBeforeMutationLifeCycles(current$$1, nextEffect);
17698 }
17699
17700 nextEffect = nextEffect.nextEffect;
17701 }
17702
17703 {
17704 resetCurrentFiber();
17705 }
17706}
17707
17708function commitAllLifeCycles(finishedRoot, committedExpirationTime) {
17709 {
17710 ReactStrictModeWarnings.flushPendingUnsafeLifecycleWarnings();
17711 ReactStrictModeWarnings.flushLegacyContextWarning();
17712
17713 if (warnAboutDeprecatedLifecycles) {
17714 ReactStrictModeWarnings.flushPendingDeprecationWarnings();
17715 }
17716 }
17717 while (nextEffect !== null) {
17718 var effectTag = nextEffect.effectTag;
17719
17720 if (effectTag & (Update | Callback)) {
17721 recordEffect();
17722 var current$$1 = nextEffect.alternate;
17723 commitLifeCycles(finishedRoot, current$$1, nextEffect, committedExpirationTime);
17724 }
17725
17726 if (effectTag & Ref) {
17727 recordEffect();
17728 commitAttachRef(nextEffect);
17729 }
17730
17731 if (enableHooks && effectTag & Passive) {
17732 rootWithPendingPassiveEffects = finishedRoot;
17733 }
17734
17735 nextEffect = nextEffect.nextEffect;
17736 }
17737}
17738
17739function commitPassiveEffects(root, firstEffect) {
17740 rootWithPendingPassiveEffects = null;
17741 passiveEffectCallbackHandle = null;
17742 passiveEffectCallback = null;
17743
17744 // Set this to true to prevent re-entrancy
17745 var previousIsRendering = isRendering;
17746 isRendering = true;
17747
17748 var effect = firstEffect;
17749 do {
17750 if (effect.effectTag & Passive) {
17751 var didError = false;
17752 var error = void 0;
17753 {
17754 invokeGuardedCallback(null, commitPassiveHookEffects, null, effect);
17755 if (hasCaughtError()) {
17756 didError = true;
17757 error = clearCaughtError();
17758 }
17759 }
17760 if (didError) {
17761 captureCommitPhaseError(effect, error);
17762 }
17763 }
17764 effect = effect.nextEffect;
17765 } while (effect !== null);
17766
17767 isRendering = previousIsRendering;
17768
17769 // Check if work was scheduled by one of the effects
17770 var rootExpirationTime = root.expirationTime;
17771 if (rootExpirationTime !== NoWork) {
17772 requestWork(root, rootExpirationTime);
17773 }
17774}
17775
17776function isAlreadyFailedLegacyErrorBoundary(instance) {
17777 return legacyErrorBoundariesThatAlreadyFailed !== null && legacyErrorBoundariesThatAlreadyFailed.has(instance);
17778}
17779
17780function markLegacyErrorBoundaryAsFailed(instance) {
17781 if (legacyErrorBoundariesThatAlreadyFailed === null) {
17782 legacyErrorBoundariesThatAlreadyFailed = new Set([instance]);
17783 } else {
17784 legacyErrorBoundariesThatAlreadyFailed.add(instance);
17785 }
17786}
17787
17788function flushPassiveEffects() {
17789 if (passiveEffectCallback !== null) {
17790 unstable_cancelCallback(passiveEffectCallbackHandle);
17791 // We call the scheduled callback instead of commitPassiveEffects directly
17792 // to ensure tracing works correctly.
17793 passiveEffectCallback();
17794 }
17795}
17796
17797function commitRoot(root, finishedWork) {
17798 isWorking = true;
17799 isCommitting$1 = true;
17800 startCommitTimer();
17801
17802 !(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;
17803 var committedExpirationTime = root.pendingCommitExpirationTime;
17804 !(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;
17805 root.pendingCommitExpirationTime = NoWork;
17806
17807 // Update the pending priority levels to account for the work that we are
17808 // about to commit. This needs to happen before calling the lifecycles, since
17809 // they may schedule additional updates.
17810 var updateExpirationTimeBeforeCommit = finishedWork.expirationTime;
17811 var childExpirationTimeBeforeCommit = finishedWork.childExpirationTime;
17812 var earliestRemainingTimeBeforeCommit = childExpirationTimeBeforeCommit > updateExpirationTimeBeforeCommit ? childExpirationTimeBeforeCommit : updateExpirationTimeBeforeCommit;
17813 markCommittedPriorityLevels(root, earliestRemainingTimeBeforeCommit);
17814
17815 var prevInteractions = null;
17816 if (enableSchedulerTracing) {
17817 // Restore any pending interactions at this point,
17818 // So that cascading work triggered during the render phase will be accounted for.
17819 prevInteractions = __interactionsRef.current;
17820 __interactionsRef.current = root.memoizedInteractions;
17821 }
17822
17823 // Reset this to null before calling lifecycles
17824 ReactCurrentOwner$2.current = null;
17825
17826 var firstEffect = void 0;
17827 if (finishedWork.effectTag > PerformedWork) {
17828 // A fiber's effect list consists only of its children, not itself. So if
17829 // the root has an effect, we need to add it to the end of the list. The
17830 // resulting list is the set that would belong to the root's parent, if
17831 // it had one; that is, all the effects in the tree including the root.
17832 if (finishedWork.lastEffect !== null) {
17833 finishedWork.lastEffect.nextEffect = finishedWork;
17834 firstEffect = finishedWork.firstEffect;
17835 } else {
17836 firstEffect = finishedWork;
17837 }
17838 } else {
17839 // There is no effect on the root.
17840 firstEffect = finishedWork.firstEffect;
17841 }
17842
17843 prepareForCommit(root.containerInfo);
17844
17845 // Invoke instances of getSnapshotBeforeUpdate before mutation.
17846 nextEffect = firstEffect;
17847 startCommitSnapshotEffectsTimer();
17848 while (nextEffect !== null) {
17849 var didError = false;
17850 var error = void 0;
17851 {
17852 invokeGuardedCallback(null, commitBeforeMutationLifecycles, null);
17853 if (hasCaughtError()) {
17854 didError = true;
17855 error = clearCaughtError();
17856 }
17857 }
17858 if (didError) {
17859 !(nextEffect !== null) ? invariant(false, 'Should have next effect. This error is likely caused by a bug in React. Please file an issue.') : void 0;
17860 captureCommitPhaseError(nextEffect, error);
17861 // Clean-up
17862 if (nextEffect !== null) {
17863 nextEffect = nextEffect.nextEffect;
17864 }
17865 }
17866 }
17867 stopCommitSnapshotEffectsTimer();
17868
17869 if (enableProfilerTimer) {
17870 // Mark the current commit time to be shared by all Profilers in this batch.
17871 // This enables them to be grouped later.
17872 recordCommitTime();
17873 }
17874
17875 // Commit all the side-effects within a tree. We'll do this in two passes.
17876 // The first pass performs all the host insertions, updates, deletions and
17877 // ref unmounts.
17878 nextEffect = firstEffect;
17879 startCommitHostEffectsTimer();
17880 while (nextEffect !== null) {
17881 var _didError = false;
17882 var _error = void 0;
17883 {
17884 invokeGuardedCallback(null, commitAllHostEffects, null);
17885 if (hasCaughtError()) {
17886 _didError = true;
17887 _error = clearCaughtError();
17888 }
17889 }
17890 if (_didError) {
17891 !(nextEffect !== null) ? invariant(false, 'Should have next effect. This error is likely caused by a bug in React. Please file an issue.') : void 0;
17892 captureCommitPhaseError(nextEffect, _error);
17893 // Clean-up
17894 if (nextEffect !== null) {
17895 nextEffect = nextEffect.nextEffect;
17896 }
17897 }
17898 }
17899 stopCommitHostEffectsTimer();
17900
17901 resetAfterCommit(root.containerInfo);
17902
17903 // The work-in-progress tree is now the current tree. This must come after
17904 // the first pass of the commit phase, so that the previous tree is still
17905 // current during componentWillUnmount, but before the second pass, so that
17906 // the finished work is current during componentDidMount/Update.
17907 root.current = finishedWork;
17908
17909 // In the second pass we'll perform all life-cycles and ref callbacks.
17910 // Life-cycles happen as a separate pass so that all placements, updates,
17911 // and deletions in the entire tree have already been invoked.
17912 // This pass also triggers any renderer-specific initial effects.
17913 nextEffect = firstEffect;
17914 startCommitLifeCyclesTimer();
17915 while (nextEffect !== null) {
17916 var _didError2 = false;
17917 var _error2 = void 0;
17918 {
17919 invokeGuardedCallback(null, commitAllLifeCycles, null, root, committedExpirationTime);
17920 if (hasCaughtError()) {
17921 _didError2 = true;
17922 _error2 = clearCaughtError();
17923 }
17924 }
17925 if (_didError2) {
17926 !(nextEffect !== null) ? invariant(false, 'Should have next effect. This error is likely caused by a bug in React. Please file an issue.') : void 0;
17927 captureCommitPhaseError(nextEffect, _error2);
17928 if (nextEffect !== null) {
17929 nextEffect = nextEffect.nextEffect;
17930 }
17931 }
17932 }
17933
17934 if (enableHooks && firstEffect !== null && rootWithPendingPassiveEffects !== null) {
17935 // This commit included a passive effect. These do not need to fire until
17936 // after the next paint. Schedule an callback to fire them in an async
17937 // event. To ensure serial execution, the callback will be flushed early if
17938 // we enter rootWithPendingPassiveEffects commit phase before then.
17939 var callback = commitPassiveEffects.bind(null, root, firstEffect);
17940 if (enableSchedulerTracing) {
17941 // TODO: Avoid this extra callback by mutating the tracing ref directly,
17942 // like we do at the beginning of commitRoot. I've opted not to do that
17943 // here because that code is still in flux.
17944 callback = unstable_wrap(callback);
17945 }
17946 passiveEffectCallbackHandle = unstable_scheduleCallback(callback);
17947 passiveEffectCallback = callback;
17948 }
17949
17950 isCommitting$1 = false;
17951 isWorking = false;
17952 stopCommitLifeCyclesTimer();
17953 stopCommitTimer();
17954 onCommitRoot(finishedWork.stateNode);
17955 if (true && ReactFiberInstrumentation_1.debugTool) {
17956 ReactFiberInstrumentation_1.debugTool.onCommitWork(finishedWork);
17957 }
17958
17959 var updateExpirationTimeAfterCommit = finishedWork.expirationTime;
17960 var childExpirationTimeAfterCommit = finishedWork.childExpirationTime;
17961 var earliestRemainingTimeAfterCommit = childExpirationTimeAfterCommit > updateExpirationTimeAfterCommit ? childExpirationTimeAfterCommit : updateExpirationTimeAfterCommit;
17962 if (earliestRemainingTimeAfterCommit === NoWork) {
17963 // If there's no remaining work, we can clear the set of already failed
17964 // error boundaries.
17965 legacyErrorBoundariesThatAlreadyFailed = null;
17966 }
17967 onCommit(root, earliestRemainingTimeAfterCommit);
17968
17969 if (enableSchedulerTracing) {
17970 __interactionsRef.current = prevInteractions;
17971
17972 var subscriber = void 0;
17973
17974 try {
17975 subscriber = __subscriberRef.current;
17976 if (subscriber !== null && root.memoizedInteractions.size > 0) {
17977 var threadID = computeThreadID(committedExpirationTime, root.interactionThreadID);
17978 subscriber.onWorkStopped(root.memoizedInteractions, threadID);
17979 }
17980 } catch (error) {
17981 // It's not safe for commitRoot() to throw.
17982 // Store the error for now and we'll re-throw in finishRendering().
17983 if (!hasUnhandledError) {
17984 hasUnhandledError = true;
17985 unhandledError = error;
17986 }
17987 } finally {
17988 // Clear completed interactions from the pending Map.
17989 // Unless the render was suspended or cascading work was scheduled,
17990 // In which case– leave pending interactions until the subsequent render.
17991 var pendingInteractionMap = root.pendingInteractionMap;
17992 pendingInteractionMap.forEach(function (scheduledInteractions, scheduledExpirationTime) {
17993 // Only decrement the pending interaction count if we're done.
17994 // If there's still work at the current priority,
17995 // That indicates that we are waiting for suspense data.
17996 if (scheduledExpirationTime > earliestRemainingTimeAfterCommit) {
17997 pendingInteractionMap.delete(scheduledExpirationTime);
17998
17999 scheduledInteractions.forEach(function (interaction) {
18000 interaction.__count--;
18001
18002 if (subscriber !== null && interaction.__count === 0) {
18003 try {
18004 subscriber.onInteractionScheduledWorkCompleted(interaction);
18005 } catch (error) {
18006 // It's not safe for commitRoot() to throw.
18007 // Store the error for now and we'll re-throw in finishRendering().
18008 if (!hasUnhandledError) {
18009 hasUnhandledError = true;
18010 unhandledError = error;
18011 }
18012 }
18013 }
18014 });
18015 }
18016 });
18017 }
18018 }
18019}
18020
18021function resetChildExpirationTime(workInProgress, renderTime) {
18022 if (renderTime !== Never && workInProgress.childExpirationTime === Never) {
18023 // The children of this component are hidden. Don't bubble their
18024 // expiration times.
18025 return;
18026 }
18027
18028 var newChildExpirationTime = NoWork;
18029
18030 // Bubble up the earliest expiration time.
18031 if (enableProfilerTimer && workInProgress.mode & ProfileMode) {
18032 // We're in profiling mode.
18033 // Let's use this same traversal to update the render durations.
18034 var actualDuration = workInProgress.actualDuration;
18035 var treeBaseDuration = workInProgress.selfBaseDuration;
18036
18037 // When a fiber is cloned, its actualDuration is reset to 0.
18038 // This value will only be updated if work is done on the fiber (i.e. it doesn't bailout).
18039 // When work is done, it should bubble to the parent's actualDuration.
18040 // If the fiber has not been cloned though, (meaning no work was done),
18041 // Then this value will reflect the amount of time spent working on a previous render.
18042 // In that case it should not bubble.
18043 // We determine whether it was cloned by comparing the child pointer.
18044 var shouldBubbleActualDurations = workInProgress.alternate === null || workInProgress.child !== workInProgress.alternate.child;
18045
18046 var child = workInProgress.child;
18047 while (child !== null) {
18048 var childUpdateExpirationTime = child.expirationTime;
18049 var childChildExpirationTime = child.childExpirationTime;
18050 if (childUpdateExpirationTime > newChildExpirationTime) {
18051 newChildExpirationTime = childUpdateExpirationTime;
18052 }
18053 if (childChildExpirationTime > newChildExpirationTime) {
18054 newChildExpirationTime = childChildExpirationTime;
18055 }
18056 if (shouldBubbleActualDurations) {
18057 actualDuration += child.actualDuration;
18058 }
18059 treeBaseDuration += child.treeBaseDuration;
18060 child = child.sibling;
18061 }
18062 workInProgress.actualDuration = actualDuration;
18063 workInProgress.treeBaseDuration = treeBaseDuration;
18064 } else {
18065 var _child = workInProgress.child;
18066 while (_child !== null) {
18067 var _childUpdateExpirationTime = _child.expirationTime;
18068 var _childChildExpirationTime = _child.childExpirationTime;
18069 if (_childUpdateExpirationTime > newChildExpirationTime) {
18070 newChildExpirationTime = _childUpdateExpirationTime;
18071 }
18072 if (_childChildExpirationTime > newChildExpirationTime) {
18073 newChildExpirationTime = _childChildExpirationTime;
18074 }
18075 _child = _child.sibling;
18076 }
18077 }
18078
18079 workInProgress.childExpirationTime = newChildExpirationTime;
18080}
18081
18082function completeUnitOfWork(workInProgress) {
18083 // Attempt to complete the current unit of work, then move to the
18084 // next sibling. If there are no more siblings, return to the
18085 // parent fiber.
18086 while (true) {
18087 // The current, flushed, state of this fiber is the alternate.
18088 // Ideally nothing should rely on this, but relying on it here
18089 // means that we don't need an additional field on the work in
18090 // progress.
18091 var current$$1 = workInProgress.alternate;
18092 {
18093 setCurrentFiber(workInProgress);
18094 }
18095
18096 var returnFiber = workInProgress.return;
18097 var siblingFiber = workInProgress.sibling;
18098
18099 if ((workInProgress.effectTag & Incomplete) === NoEffect) {
18100 if (true && replayFailedUnitOfWorkWithInvokeGuardedCallback) {
18101 // Don't replay if it fails during completion phase.
18102 mayReplayFailedUnitOfWork = false;
18103 }
18104 // This fiber completed.
18105 // Remember we're completing this unit so we can find a boundary if it fails.
18106 nextUnitOfWork = workInProgress;
18107 if (enableProfilerTimer) {
18108 if (workInProgress.mode & ProfileMode) {
18109 startProfilerTimer(workInProgress);
18110 }
18111 nextUnitOfWork = completeWork(current$$1, workInProgress, nextRenderExpirationTime);
18112 if (workInProgress.mode & ProfileMode) {
18113 // Update render duration assuming we didn't error.
18114 stopProfilerTimerIfRunningAndRecordDelta(workInProgress, false);
18115 }
18116 } else {
18117 nextUnitOfWork = completeWork(current$$1, workInProgress, nextRenderExpirationTime);
18118 }
18119 if (true && replayFailedUnitOfWorkWithInvokeGuardedCallback) {
18120 // We're out of completion phase so replaying is fine now.
18121 mayReplayFailedUnitOfWork = true;
18122 }
18123 stopWorkTimer(workInProgress);
18124 resetChildExpirationTime(workInProgress, nextRenderExpirationTime);
18125 {
18126 resetCurrentFiber();
18127 }
18128
18129 if (nextUnitOfWork !== null) {
18130 // Completing this fiber spawned new work. Work on that next.
18131 return nextUnitOfWork;
18132 }
18133
18134 if (returnFiber !== null &&
18135 // Do not append effects to parents if a sibling failed to complete
18136 (returnFiber.effectTag & Incomplete) === NoEffect) {
18137 // Append all the effects of the subtree and this fiber onto the effect
18138 // list of the parent. The completion order of the children affects the
18139 // side-effect order.
18140 if (returnFiber.firstEffect === null) {
18141 returnFiber.firstEffect = workInProgress.firstEffect;
18142 }
18143 if (workInProgress.lastEffect !== null) {
18144 if (returnFiber.lastEffect !== null) {
18145 returnFiber.lastEffect.nextEffect = workInProgress.firstEffect;
18146 }
18147 returnFiber.lastEffect = workInProgress.lastEffect;
18148 }
18149
18150 // If this fiber had side-effects, we append it AFTER the children's
18151 // side-effects. We can perform certain side-effects earlier if
18152 // needed, by doing multiple passes over the effect list. We don't want
18153 // to schedule our own side-effect on our own list because if end up
18154 // reusing children we'll schedule this effect onto itself since we're
18155 // at the end.
18156 var effectTag = workInProgress.effectTag;
18157 // Skip both NoWork and PerformedWork tags when creating the effect list.
18158 // PerformedWork effect is read by React DevTools but shouldn't be committed.
18159 if (effectTag > PerformedWork) {
18160 if (returnFiber.lastEffect !== null) {
18161 returnFiber.lastEffect.nextEffect = workInProgress;
18162 } else {
18163 returnFiber.firstEffect = workInProgress;
18164 }
18165 returnFiber.lastEffect = workInProgress;
18166 }
18167 }
18168
18169 if (true && ReactFiberInstrumentation_1.debugTool) {
18170 ReactFiberInstrumentation_1.debugTool.onCompleteWork(workInProgress);
18171 }
18172
18173 if (siblingFiber !== null) {
18174 // If there is more work to do in this returnFiber, do that next.
18175 return siblingFiber;
18176 } else if (returnFiber !== null) {
18177 // If there's no more work in this returnFiber. Complete the returnFiber.
18178 workInProgress = returnFiber;
18179 continue;
18180 } else {
18181 // We've reached the root.
18182 return null;
18183 }
18184 } else {
18185 if (enableProfilerTimer && workInProgress.mode & ProfileMode) {
18186 // Record the render duration for the fiber that errored.
18187 stopProfilerTimerIfRunningAndRecordDelta(workInProgress, false);
18188
18189 // Include the time spent working on failed children before continuing.
18190 var actualDuration = workInProgress.actualDuration;
18191 var child = workInProgress.child;
18192 while (child !== null) {
18193 actualDuration += child.actualDuration;
18194 child = child.sibling;
18195 }
18196 workInProgress.actualDuration = actualDuration;
18197 }
18198
18199 // This fiber did not complete because something threw. Pop values off
18200 // the stack without entering the complete phase. If this is a boundary,
18201 // capture values if possible.
18202 var next = unwindWork(workInProgress, nextRenderExpirationTime);
18203 // Because this fiber did not complete, don't reset its expiration time.
18204 if (workInProgress.effectTag & DidCapture) {
18205 // Restarting an error boundary
18206 stopFailedWorkTimer(workInProgress);
18207 } else {
18208 stopWorkTimer(workInProgress);
18209 }
18210
18211 {
18212 resetCurrentFiber();
18213 }
18214
18215 if (next !== null) {
18216 stopWorkTimer(workInProgress);
18217 if (true && ReactFiberInstrumentation_1.debugTool) {
18218 ReactFiberInstrumentation_1.debugTool.onCompleteWork(workInProgress);
18219 }
18220
18221 // If completing this work spawned new work, do that next. We'll come
18222 // back here again.
18223 // Since we're restarting, remove anything that is not a host effect
18224 // from the effect tag.
18225 next.effectTag &= HostEffectMask;
18226 return next;
18227 }
18228
18229 if (returnFiber !== null) {
18230 // Mark the parent fiber as incomplete and clear its effect list.
18231 returnFiber.firstEffect = returnFiber.lastEffect = null;
18232 returnFiber.effectTag |= Incomplete;
18233 }
18234
18235 if (true && ReactFiberInstrumentation_1.debugTool) {
18236 ReactFiberInstrumentation_1.debugTool.onCompleteWork(workInProgress);
18237 }
18238
18239 if (siblingFiber !== null) {
18240 // If there is more work to do in this returnFiber, do that next.
18241 return siblingFiber;
18242 } else if (returnFiber !== null) {
18243 // If there's no more work in this returnFiber. Complete the returnFiber.
18244 workInProgress = returnFiber;
18245 continue;
18246 } else {
18247 return null;
18248 }
18249 }
18250 }
18251
18252 // Without this explicit null return Flow complains of invalid return type
18253 // TODO Remove the above while(true) loop
18254 // eslint-disable-next-line no-unreachable
18255 return null;
18256}
18257
18258function performUnitOfWork(workInProgress) {
18259 // The current, flushed, state of this fiber is the alternate.
18260 // Ideally nothing should rely on this, but relying on it here
18261 // means that we don't need an additional field on the work in
18262 // progress.
18263 var current$$1 = workInProgress.alternate;
18264
18265 // See if beginning this work spawns more work.
18266 startWorkTimer(workInProgress);
18267 {
18268 setCurrentFiber(workInProgress);
18269 }
18270
18271 if (true && replayFailedUnitOfWorkWithInvokeGuardedCallback) {
18272 stashedWorkInProgressProperties = assignFiberPropertiesInDEV(stashedWorkInProgressProperties, workInProgress);
18273 }
18274
18275 var next = void 0;
18276 if (enableProfilerTimer) {
18277 if (workInProgress.mode & ProfileMode) {
18278 startProfilerTimer(workInProgress);
18279 }
18280
18281 next = beginWork(current$$1, workInProgress, nextRenderExpirationTime);
18282 workInProgress.memoizedProps = workInProgress.pendingProps;
18283
18284 if (workInProgress.mode & ProfileMode) {
18285 // Record the render duration assuming we didn't bailout (or error).
18286 stopProfilerTimerIfRunningAndRecordDelta(workInProgress, true);
18287 }
18288 } else {
18289 next = beginWork(current$$1, workInProgress, nextRenderExpirationTime);
18290 workInProgress.memoizedProps = workInProgress.pendingProps;
18291 }
18292
18293 {
18294 resetCurrentFiber();
18295 if (isReplayingFailedUnitOfWork) {
18296 // Currently replaying a failed unit of work. This should be unreachable,
18297 // because the render phase is meant to be idempotent, and it should
18298 // have thrown again. Since it didn't, rethrow the original error, so
18299 // React's internal stack is not misaligned.
18300 rethrowOriginalError();
18301 }
18302 }
18303 if (true && ReactFiberInstrumentation_1.debugTool) {
18304 ReactFiberInstrumentation_1.debugTool.onBeginWork(workInProgress);
18305 }
18306
18307 if (next === null) {
18308 // If this doesn't spawn new work, complete the current work.
18309 next = completeUnitOfWork(workInProgress);
18310 }
18311
18312 ReactCurrentOwner$2.current = null;
18313
18314 return next;
18315}
18316
18317function workLoop(isYieldy) {
18318 if (!isYieldy) {
18319 // Flush work without yielding
18320 while (nextUnitOfWork !== null) {
18321 nextUnitOfWork = performUnitOfWork(nextUnitOfWork);
18322 }
18323 } else {
18324 // Flush asynchronous work until there's a higher priority event
18325 while (nextUnitOfWork !== null && !shouldYieldToRenderer()) {
18326 nextUnitOfWork = performUnitOfWork(nextUnitOfWork);
18327 }
18328 }
18329}
18330
18331function renderRoot(root, isYieldy) {
18332 !!isWorking ? invariant(false, 'renderRoot was called recursively. This error is likely caused by a bug in React. Please file an issue.') : void 0;
18333
18334 flushPassiveEffects();
18335
18336 isWorking = true;
18337 if (enableHooks) {
18338 ReactCurrentOwner$2.currentDispatcher = Dispatcher;
18339 } else {
18340 ReactCurrentOwner$2.currentDispatcher = DispatcherWithoutHooks;
18341 }
18342
18343 var expirationTime = root.nextExpirationTimeToWorkOn;
18344
18345 // Check if we're starting from a fresh stack, or if we're resuming from
18346 // previously yielded work.
18347 if (expirationTime !== nextRenderExpirationTime || root !== nextRoot || nextUnitOfWork === null) {
18348 // Reset the stack and start working from the root.
18349 resetStack();
18350 nextRoot = root;
18351 nextRenderExpirationTime = expirationTime;
18352 nextUnitOfWork = createWorkInProgress(nextRoot.current, null, nextRenderExpirationTime);
18353 root.pendingCommitExpirationTime = NoWork;
18354
18355 if (enableSchedulerTracing) {
18356 // Determine which interactions this batch of work currently includes,
18357 // So that we can accurately attribute time spent working on it,
18358 var interactions = new Set();
18359 root.pendingInteractionMap.forEach(function (scheduledInteractions, scheduledExpirationTime) {
18360 if (scheduledExpirationTime >= expirationTime) {
18361 scheduledInteractions.forEach(function (interaction) {
18362 return interactions.add(interaction);
18363 });
18364 }
18365 });
18366
18367 // Store the current set of interactions on the FiberRoot for a few reasons:
18368 // We can re-use it in hot functions like renderRoot() without having to recalculate it.
18369 // We will also use it in commitWork() to pass to any Profiler onRender() hooks.
18370 // This also provides DevTools with a way to access it when the onCommitRoot() hook is called.
18371 root.memoizedInteractions = interactions;
18372
18373 if (interactions.size > 0) {
18374 var subscriber = __subscriberRef.current;
18375 if (subscriber !== null) {
18376 var threadID = computeThreadID(expirationTime, root.interactionThreadID);
18377 try {
18378 subscriber.onWorkStarted(interactions, threadID);
18379 } catch (error) {
18380 // Work thrown by an interaction tracing subscriber should be rethrown,
18381 // But only once it's safe (to avoid leaveing the scheduler in an invalid state).
18382 // Store the error for now and we'll re-throw in finishRendering().
18383 if (!hasUnhandledError) {
18384 hasUnhandledError = true;
18385 unhandledError = error;
18386 }
18387 }
18388 }
18389 }
18390 }
18391 }
18392
18393 var prevInteractions = null;
18394 if (enableSchedulerTracing) {
18395 // We're about to start new traced work.
18396 // Restore pending interactions so cascading work triggered during the render phase will be accounted for.
18397 prevInteractions = __interactionsRef.current;
18398 __interactionsRef.current = root.memoizedInteractions;
18399 }
18400
18401 var didFatal = false;
18402
18403 startWorkLoopTimer(nextUnitOfWork);
18404
18405 do {
18406 try {
18407 workLoop(isYieldy);
18408 } catch (thrownValue) {
18409 resetContextDependences();
18410 resetHooks();
18411
18412 // Reset in case completion throws.
18413 // This is only used in DEV and when replaying is on.
18414 var mayReplay = void 0;
18415 if (true && replayFailedUnitOfWorkWithInvokeGuardedCallback) {
18416 mayReplay = mayReplayFailedUnitOfWork;
18417 mayReplayFailedUnitOfWork = true;
18418 }
18419
18420 if (nextUnitOfWork === null) {
18421 // This is a fatal error.
18422 didFatal = true;
18423 onUncaughtError(thrownValue);
18424 } else {
18425 if (enableProfilerTimer && nextUnitOfWork.mode & ProfileMode) {
18426 // Record the time spent rendering before an error was thrown.
18427 // This avoids inaccurate Profiler durations in the case of a suspended render.
18428 stopProfilerTimerIfRunningAndRecordDelta(nextUnitOfWork, true);
18429 }
18430
18431 {
18432 // Reset global debug state
18433 // We assume this is defined in DEV
18434 resetCurrentlyProcessingQueue();
18435 }
18436
18437 if (true && replayFailedUnitOfWorkWithInvokeGuardedCallback) {
18438 if (mayReplay) {
18439 var failedUnitOfWork = nextUnitOfWork;
18440 replayUnitOfWork(failedUnitOfWork, thrownValue, isYieldy);
18441 }
18442 }
18443
18444 // TODO: we already know this isn't true in some cases.
18445 // At least this shows a nicer error message until we figure out the cause.
18446 // https://github.com/facebook/react/issues/12449#issuecomment-386727431
18447 !(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;
18448
18449 var sourceFiber = nextUnitOfWork;
18450 var returnFiber = sourceFiber.return;
18451 if (returnFiber === null) {
18452 // This is the root. The root could capture its own errors. However,
18453 // we don't know if it errors before or after we pushed the host
18454 // context. This information is needed to avoid a stack mismatch.
18455 // Because we're not sure, treat this as a fatal error. We could track
18456 // which phase it fails in, but doesn't seem worth it. At least
18457 // for now.
18458 didFatal = true;
18459 onUncaughtError(thrownValue);
18460 } else {
18461 throwException(root, returnFiber, sourceFiber, thrownValue, nextRenderExpirationTime);
18462 nextUnitOfWork = completeUnitOfWork(sourceFiber);
18463 continue;
18464 }
18465 }
18466 }
18467 break;
18468 } while (true);
18469
18470 if (enableSchedulerTracing) {
18471 // Traced work is done for now; restore the previous interactions.
18472 __interactionsRef.current = prevInteractions;
18473 }
18474
18475 // We're done performing work. Time to clean up.
18476 isWorking = false;
18477 ReactCurrentOwner$2.currentDispatcher = null;
18478 resetContextDependences();
18479 resetHooks();
18480
18481 // Yield back to main thread.
18482 if (didFatal) {
18483 var _didCompleteRoot = false;
18484 stopWorkLoopTimer(interruptedBy, _didCompleteRoot);
18485 interruptedBy = null;
18486 // There was a fatal error.
18487 {
18488 resetStackAfterFatalErrorInDev();
18489 }
18490 // `nextRoot` points to the in-progress root. A non-null value indicates
18491 // that we're in the middle of an async render. Set it to null to indicate
18492 // there's no more work to be done in the current batch.
18493 nextRoot = null;
18494 onFatal(root);
18495 return;
18496 }
18497
18498 if (nextUnitOfWork !== null) {
18499 // There's still remaining async work in this tree, but we ran out of time
18500 // in the current frame. Yield back to the renderer. Unless we're
18501 // interrupted by a higher priority update, we'll continue later from where
18502 // we left off.
18503 var _didCompleteRoot2 = false;
18504 stopWorkLoopTimer(interruptedBy, _didCompleteRoot2);
18505 interruptedBy = null;
18506 onYield(root);
18507 return;
18508 }
18509
18510 // We completed the whole tree.
18511 var didCompleteRoot = true;
18512 stopWorkLoopTimer(interruptedBy, didCompleteRoot);
18513 var rootWorkInProgress = root.current.alternate;
18514 !(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;
18515
18516 // `nextRoot` points to the in-progress root. A non-null value indicates
18517 // that we're in the middle of an async render. Set it to null to indicate
18518 // there's no more work to be done in the current batch.
18519 nextRoot = null;
18520 interruptedBy = null;
18521
18522 if (nextRenderDidError) {
18523 // There was an error
18524 if (hasLowerPriorityWork(root, expirationTime)) {
18525 // There's lower priority work. If so, it may have the effect of fixing
18526 // the exception that was just thrown. Exit without committing. This is
18527 // similar to a suspend, but without a timeout because we're not waiting
18528 // for a promise to resolve. React will restart at the lower
18529 // priority level.
18530 markSuspendedPriorityLevel(root, expirationTime);
18531 var suspendedExpirationTime = expirationTime;
18532 var rootExpirationTime = root.expirationTime;
18533 onSuspend(root, rootWorkInProgress, suspendedExpirationTime, rootExpirationTime, -1 // Indicates no timeout
18534 );
18535 return;
18536 } else if (
18537 // There's no lower priority work, but we're rendering asynchronously.
18538 // Synchronsouly attempt to render the same level one more time. This is
18539 // similar to a suspend, but without a timeout because we're not waiting
18540 // for a promise to resolve.
18541 !root.didError && isYieldy) {
18542 root.didError = true;
18543 var _suspendedExpirationTime = root.nextExpirationTimeToWorkOn = expirationTime;
18544 var _rootExpirationTime = root.expirationTime = Sync;
18545 onSuspend(root, rootWorkInProgress, _suspendedExpirationTime, _rootExpirationTime, -1 // Indicates no timeout
18546 );
18547 return;
18548 }
18549 }
18550
18551 if (isYieldy && nextLatestAbsoluteTimeoutMs !== -1) {
18552 // The tree was suspended.
18553 var _suspendedExpirationTime2 = expirationTime;
18554 markSuspendedPriorityLevel(root, _suspendedExpirationTime2);
18555
18556 // Find the earliest uncommitted expiration time in the tree, including
18557 // work that is suspended. The timeout threshold cannot be longer than
18558 // the overall expiration.
18559 var earliestExpirationTime = findEarliestOutstandingPriorityLevel(root, expirationTime);
18560 var earliestExpirationTimeMs = expirationTimeToMs(earliestExpirationTime);
18561 if (earliestExpirationTimeMs < nextLatestAbsoluteTimeoutMs) {
18562 nextLatestAbsoluteTimeoutMs = earliestExpirationTimeMs;
18563 }
18564
18565 // Subtract the current time from the absolute timeout to get the number
18566 // of milliseconds until the timeout. In other words, convert an absolute
18567 // timestamp to a relative time. This is the value that is passed
18568 // to `setTimeout`.
18569 var currentTimeMs = expirationTimeToMs(requestCurrentTime());
18570 var msUntilTimeout = nextLatestAbsoluteTimeoutMs - currentTimeMs;
18571 msUntilTimeout = msUntilTimeout < 0 ? 0 : msUntilTimeout;
18572
18573 // TODO: Account for the Just Noticeable Difference
18574
18575 var _rootExpirationTime2 = root.expirationTime;
18576 onSuspend(root, rootWorkInProgress, _suspendedExpirationTime2, _rootExpirationTime2, msUntilTimeout);
18577 return;
18578 }
18579
18580 // Ready to commit.
18581 onComplete(root, rootWorkInProgress, expirationTime);
18582}
18583
18584function captureCommitPhaseError(sourceFiber, value) {
18585 var expirationTime = Sync;
18586 var fiber = sourceFiber.return;
18587 while (fiber !== null) {
18588 switch (fiber.tag) {
18589 case ClassComponent:
18590 var ctor = fiber.type;
18591 var instance = fiber.stateNode;
18592 if (typeof ctor.getDerivedStateFromError === 'function' || typeof instance.componentDidCatch === 'function' && !isAlreadyFailedLegacyErrorBoundary(instance)) {
18593 var errorInfo = createCapturedValue(value, sourceFiber);
18594 var update = createClassErrorUpdate(fiber, errorInfo, expirationTime);
18595 enqueueUpdate(fiber, update);
18596 scheduleWork(fiber, expirationTime);
18597 return;
18598 }
18599 break;
18600 case HostRoot:
18601 {
18602 var _errorInfo = createCapturedValue(value, sourceFiber);
18603 var _update = createRootErrorUpdate(fiber, _errorInfo, expirationTime);
18604 enqueueUpdate(fiber, _update);
18605 scheduleWork(fiber, expirationTime);
18606 return;
18607 }
18608 }
18609 fiber = fiber.return;
18610 }
18611
18612 if (sourceFiber.tag === HostRoot) {
18613 // Error was thrown at the root. There is no parent, so the root
18614 // itself should capture it.
18615 var rootFiber = sourceFiber;
18616 var _errorInfo2 = createCapturedValue(value, rootFiber);
18617 var _update2 = createRootErrorUpdate(rootFiber, _errorInfo2, expirationTime);
18618 enqueueUpdate(rootFiber, _update2);
18619 scheduleWork(rootFiber, expirationTime);
18620 }
18621}
18622
18623function computeThreadID(expirationTime, interactionThreadID) {
18624 // Interaction threads are unique per root and expiration time.
18625 return expirationTime * 1000 + interactionThreadID;
18626}
18627
18628// Creates a unique async expiration time.
18629function computeUniqueAsyncExpiration() {
18630 var currentTime = requestCurrentTime();
18631 var result = computeAsyncExpiration(currentTime);
18632 if (result >= lastUniqueAsyncExpiration) {
18633 // Since we assume the current time monotonically increases, we only hit
18634 // this branch when computeUniqueAsyncExpiration is fired multiple times
18635 // within a 200ms window (or whatever the async bucket size is).
18636 result = lastUniqueAsyncExpiration - 1;
18637 }
18638 lastUniqueAsyncExpiration = result;
18639 return lastUniqueAsyncExpiration;
18640}
18641
18642function computeExpirationForFiber(currentTime, fiber) {
18643 var expirationTime = void 0;
18644 if (expirationContext !== NoWork) {
18645 // An explicit expiration context was set;
18646 expirationTime = expirationContext;
18647 } else if (isWorking) {
18648 if (isCommitting$1) {
18649 // Updates that occur during the commit phase should have sync priority
18650 // by default.
18651 expirationTime = Sync;
18652 } else {
18653 // Updates during the render phase should expire at the same time as
18654 // the work that is being rendered.
18655 expirationTime = nextRenderExpirationTime;
18656 }
18657 } else {
18658 // No explicit expiration context was set, and we're not currently
18659 // performing work. Calculate a new expiration time.
18660 if (fiber.mode & ConcurrentMode) {
18661 if (isBatchingInteractiveUpdates) {
18662 // This is an interactive update
18663 expirationTime = computeInteractiveExpiration(currentTime);
18664 } else {
18665 // This is an async update
18666 expirationTime = computeAsyncExpiration(currentTime);
18667 }
18668 // If we're in the middle of rendering a tree, do not update at the same
18669 // expiration time that is already rendering.
18670 if (nextRoot !== null && expirationTime === nextRenderExpirationTime) {
18671 expirationTime -= 1;
18672 }
18673 } else {
18674 // This is a sync update
18675 expirationTime = Sync;
18676 }
18677 }
18678 if (isBatchingInteractiveUpdates) {
18679 // This is an interactive update. Keep track of the lowest pending
18680 // interactive expiration time. This allows us to synchronously flush
18681 // all interactive updates when needed.
18682 if (lowestPriorityPendingInteractiveExpirationTime === NoWork || expirationTime < lowestPriorityPendingInteractiveExpirationTime) {
18683 lowestPriorityPendingInteractiveExpirationTime = expirationTime;
18684 }
18685 }
18686 return expirationTime;
18687}
18688
18689function renderDidSuspend(root, absoluteTimeoutMs, suspendedTime) {
18690 // Schedule the timeout.
18691 if (absoluteTimeoutMs >= 0 && nextLatestAbsoluteTimeoutMs < absoluteTimeoutMs) {
18692 nextLatestAbsoluteTimeoutMs = absoluteTimeoutMs;
18693 }
18694}
18695
18696function renderDidError() {
18697 nextRenderDidError = true;
18698}
18699
18700function pingSuspendedRoot(root, thenable, pingTime) {
18701 // A promise that previously suspended React from committing has resolved.
18702 // If React is still suspended, try again at the previous level (pingTime).
18703
18704 var pingCache = root.pingCache;
18705 if (pingCache !== null) {
18706 // The thenable resolved, so we no longer need to memoize, because it will
18707 // never be thrown again.
18708 pingCache.delete(thenable);
18709 }
18710
18711 if (nextRoot !== null && nextRenderExpirationTime === pingTime) {
18712 // Received a ping at the same priority level at which we're currently
18713 // rendering. Restart from the root.
18714 nextRoot = null;
18715 } else {
18716 // Confirm that the root is still suspended at this level. Otherwise exit.
18717 if (isPriorityLevelSuspended(root, pingTime)) {
18718 // Ping at the original level
18719 markPingedPriorityLevel(root, pingTime);
18720 var rootExpirationTime = root.expirationTime;
18721 if (rootExpirationTime !== NoWork) {
18722 requestWork(root, rootExpirationTime);
18723 }
18724 }
18725 }
18726}
18727
18728function retryTimedOutBoundary(boundaryFiber, thenable) {
18729 // The boundary fiber (a Suspense component) previously timed out and was
18730 // rendered in its fallback state. One of the promises that suspended it has
18731 // resolved, which means at least part of the tree was likely unblocked. Try
18732 var retryCache = boundaryFiber.stateNode;
18733 if (retryCache !== null) {
18734 // The thenable resolved, so we no longer need to memoize, because it will
18735 // never be thrown again.
18736 retryCache.delete(thenable);
18737 }
18738
18739 var currentTime = requestCurrentTime();
18740 var retryTime = computeExpirationForFiber(currentTime, boundaryFiber);
18741 var root = scheduleWorkToRoot(boundaryFiber, retryTime);
18742 if (root !== null) {
18743 markPendingPriorityLevel(root, retryTime);
18744 var rootExpirationTime = root.expirationTime;
18745 if (rootExpirationTime !== NoWork) {
18746 requestWork(root, rootExpirationTime);
18747 }
18748 }
18749}
18750
18751function scheduleWorkToRoot(fiber, expirationTime) {
18752 recordScheduleUpdate();
18753
18754 {
18755 if (fiber.tag === ClassComponent) {
18756 var instance = fiber.stateNode;
18757 warnAboutInvalidUpdates(instance);
18758 }
18759 }
18760
18761 // Update the source fiber's expiration time
18762 if (fiber.expirationTime < expirationTime) {
18763 fiber.expirationTime = expirationTime;
18764 }
18765 var alternate = fiber.alternate;
18766 if (alternate !== null && alternate.expirationTime < expirationTime) {
18767 alternate.expirationTime = expirationTime;
18768 }
18769 // Walk the parent path to the root and update the child expiration time.
18770 var node = fiber.return;
18771 var root = null;
18772 if (node === null && fiber.tag === HostRoot) {
18773 root = fiber.stateNode;
18774 } else {
18775 while (node !== null) {
18776 alternate = node.alternate;
18777 if (node.childExpirationTime < expirationTime) {
18778 node.childExpirationTime = expirationTime;
18779 if (alternate !== null && alternate.childExpirationTime < expirationTime) {
18780 alternate.childExpirationTime = expirationTime;
18781 }
18782 } else if (alternate !== null && alternate.childExpirationTime < expirationTime) {
18783 alternate.childExpirationTime = expirationTime;
18784 }
18785 if (node.return === null && node.tag === HostRoot) {
18786 root = node.stateNode;
18787 break;
18788 }
18789 node = node.return;
18790 }
18791 }
18792
18793 if (enableSchedulerTracing) {
18794 if (root !== null) {
18795 var interactions = __interactionsRef.current;
18796 if (interactions.size > 0) {
18797 var pendingInteractionMap = root.pendingInteractionMap;
18798 var pendingInteractions = pendingInteractionMap.get(expirationTime);
18799 if (pendingInteractions != null) {
18800 interactions.forEach(function (interaction) {
18801 if (!pendingInteractions.has(interaction)) {
18802 // Update the pending async work count for previously unscheduled interaction.
18803 interaction.__count++;
18804 }
18805
18806 pendingInteractions.add(interaction);
18807 });
18808 } else {
18809 pendingInteractionMap.set(expirationTime, new Set(interactions));
18810
18811 // Update the pending async work count for the current interactions.
18812 interactions.forEach(function (interaction) {
18813 interaction.__count++;
18814 });
18815 }
18816
18817 var subscriber = __subscriberRef.current;
18818 if (subscriber !== null) {
18819 var threadID = computeThreadID(expirationTime, root.interactionThreadID);
18820 subscriber.onWorkScheduled(interactions, threadID);
18821 }
18822 }
18823 }
18824 }
18825 return root;
18826}
18827
18828function scheduleWork(fiber, expirationTime) {
18829 var root = scheduleWorkToRoot(fiber, expirationTime);
18830 if (root === null) {
18831 {
18832 switch (fiber.tag) {
18833 case ClassComponent:
18834 warnAboutUpdateOnUnmounted(fiber, true);
18835 break;
18836 case FunctionComponent:
18837 case ForwardRef:
18838 case MemoComponent:
18839 case SimpleMemoComponent:
18840 warnAboutUpdateOnUnmounted(fiber, false);
18841 break;
18842 }
18843 }
18844 return;
18845 }
18846
18847 if (!isWorking && nextRenderExpirationTime !== NoWork && expirationTime > nextRenderExpirationTime) {
18848 // This is an interruption. (Used for performance tracking.)
18849 interruptedBy = fiber;
18850 resetStack();
18851 }
18852 markPendingPriorityLevel(root, expirationTime);
18853 if (
18854 // If we're in the render phase, we don't need to schedule this root
18855 // for an update, because we'll do it before we exit...
18856 !isWorking || isCommitting$1 ||
18857 // ...unless this is a different root than the one we're rendering.
18858 nextRoot !== root) {
18859 var rootExpirationTime = root.expirationTime;
18860 requestWork(root, rootExpirationTime);
18861 }
18862 if (nestedUpdateCount > NESTED_UPDATE_LIMIT) {
18863 // Reset this back to zero so subsequent updates don't throw.
18864 nestedUpdateCount = 0;
18865 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.');
18866 }
18867}
18868
18869function syncUpdates(fn, a, b, c, d) {
18870 var previousExpirationContext = expirationContext;
18871 expirationContext = Sync;
18872 try {
18873 return fn(a, b, c, d);
18874 } finally {
18875 expirationContext = previousExpirationContext;
18876 }
18877}
18878
18879// TODO: Everything below this is written as if it has been lifted to the
18880// renderers. I'll do this in a follow-up.
18881
18882// Linked-list of roots
18883var firstScheduledRoot = null;
18884var lastScheduledRoot = null;
18885
18886var callbackExpirationTime = NoWork;
18887var callbackID = void 0;
18888var isRendering = false;
18889var nextFlushedRoot = null;
18890var nextFlushedExpirationTime = NoWork;
18891var lowestPriorityPendingInteractiveExpirationTime = NoWork;
18892var hasUnhandledError = false;
18893var unhandledError = null;
18894
18895var isBatchingUpdates = false;
18896var isUnbatchingUpdates = false;
18897var isBatchingInteractiveUpdates = false;
18898
18899var completedBatches = null;
18900
18901var originalStartTimeMs = unstable_now();
18902var currentRendererTime = msToExpirationTime(originalStartTimeMs);
18903var currentSchedulerTime = currentRendererTime;
18904
18905// Use these to prevent an infinite loop of nested updates
18906var NESTED_UPDATE_LIMIT = 50;
18907var nestedUpdateCount = 0;
18908var lastCommittedRootDuringThisBatch = null;
18909
18910function recomputeCurrentRendererTime() {
18911 var currentTimeMs = unstable_now() - originalStartTimeMs;
18912 currentRendererTime = msToExpirationTime(currentTimeMs);
18913}
18914
18915function scheduleCallbackWithExpirationTime(root, expirationTime) {
18916 if (callbackExpirationTime !== NoWork) {
18917 // A callback is already scheduled. Check its expiration time (timeout).
18918 if (expirationTime < callbackExpirationTime) {
18919 // Existing callback has sufficient timeout. Exit.
18920 return;
18921 } else {
18922 if (callbackID !== null) {
18923 // Existing callback has insufficient timeout. Cancel and schedule a
18924 // new one.
18925 unstable_cancelCallback(callbackID);
18926 }
18927 }
18928 // The request callback timer is already running. Don't start a new one.
18929 } else {
18930 startRequestCallbackTimer();
18931 }
18932
18933 callbackExpirationTime = expirationTime;
18934 var currentMs = unstable_now() - originalStartTimeMs;
18935 var expirationTimeMs = expirationTimeToMs(expirationTime);
18936 var timeout = expirationTimeMs - currentMs;
18937 callbackID = unstable_scheduleCallback(performAsyncWork, { timeout: timeout });
18938}
18939
18940// For every call to renderRoot, one of onFatal, onComplete, onSuspend, and
18941// onYield is called upon exiting. We use these in lieu of returning a tuple.
18942// I've also chosen not to inline them into renderRoot because these will
18943// eventually be lifted into the renderer.
18944function onFatal(root) {
18945 root.finishedWork = null;
18946}
18947
18948function onComplete(root, finishedWork, expirationTime) {
18949 root.pendingCommitExpirationTime = expirationTime;
18950 root.finishedWork = finishedWork;
18951}
18952
18953function onSuspend(root, finishedWork, suspendedExpirationTime, rootExpirationTime, msUntilTimeout) {
18954 root.expirationTime = rootExpirationTime;
18955 if (msUntilTimeout === 0 && !shouldYieldToRenderer()) {
18956 // Don't wait an additional tick. Commit the tree immediately.
18957 root.pendingCommitExpirationTime = suspendedExpirationTime;
18958 root.finishedWork = finishedWork;
18959 } else if (msUntilTimeout > 0) {
18960 // Wait `msUntilTimeout` milliseconds before committing.
18961 root.timeoutHandle = scheduleTimeout(onTimeout.bind(null, root, finishedWork, suspendedExpirationTime), msUntilTimeout);
18962 }
18963}
18964
18965function onYield(root) {
18966 root.finishedWork = null;
18967}
18968
18969function onTimeout(root, finishedWork, suspendedExpirationTime) {
18970 // The root timed out. Commit it.
18971 root.pendingCommitExpirationTime = suspendedExpirationTime;
18972 root.finishedWork = finishedWork;
18973 // Read the current time before entering the commit phase. We can be
18974 // certain this won't cause tearing related to batching of event updates
18975 // because we're at the top of a timer event.
18976 recomputeCurrentRendererTime();
18977 currentSchedulerTime = currentRendererTime;
18978 flushRoot(root, suspendedExpirationTime);
18979}
18980
18981function onCommit(root, expirationTime) {
18982 root.expirationTime = expirationTime;
18983 root.finishedWork = null;
18984}
18985
18986function requestCurrentTime() {
18987 // requestCurrentTime is called by the scheduler to compute an expiration
18988 // time.
18989 //
18990 // Expiration times are computed by adding to the current time (the start
18991 // time). However, if two updates are scheduled within the same event, we
18992 // should treat their start times as simultaneous, even if the actual clock
18993 // time has advanced between the first and second call.
18994
18995 // In other words, because expiration times determine how updates are batched,
18996 // we want all updates of like priority that occur within the same event to
18997 // receive the same expiration time. Otherwise we get tearing.
18998 //
18999 // We keep track of two separate times: the current "renderer" time and the
19000 // current "scheduler" time. The renderer time can be updated whenever; it
19001 // only exists to minimize the calls performance.now.
19002 //
19003 // But the scheduler time can only be updated if there's no pending work, or
19004 // if we know for certain that we're not in the middle of an event.
19005
19006 if (isRendering) {
19007 // We're already rendering. Return the most recently read time.
19008 return currentSchedulerTime;
19009 }
19010 // Check if there's pending work.
19011 findHighestPriorityRoot();
19012 if (nextFlushedExpirationTime === NoWork || nextFlushedExpirationTime === Never) {
19013 // If there's no pending work, or if the pending work is offscreen, we can
19014 // read the current time without risk of tearing.
19015 recomputeCurrentRendererTime();
19016 currentSchedulerTime = currentRendererTime;
19017 return currentSchedulerTime;
19018 }
19019 // There's already pending work. We might be in the middle of a browser
19020 // event. If we were to read the current time, it could cause multiple updates
19021 // within the same event to receive different expiration times, leading to
19022 // tearing. Return the last read time. During the next idle callback, the
19023 // time will be updated.
19024 return currentSchedulerTime;
19025}
19026
19027// requestWork is called by the scheduler whenever a root receives an update.
19028// It's up to the renderer to call renderRoot at some point in the future.
19029function requestWork(root, expirationTime) {
19030 addRootToSchedule(root, expirationTime);
19031 if (isRendering) {
19032 // Prevent reentrancy. Remaining work will be scheduled at the end of
19033 // the currently rendering batch.
19034 return;
19035 }
19036
19037 if (isBatchingUpdates) {
19038 // Flush work at the end of the batch.
19039 if (isUnbatchingUpdates) {
19040 // ...unless we're inside unbatchedUpdates, in which case we should
19041 // flush it now.
19042 nextFlushedRoot = root;
19043 nextFlushedExpirationTime = Sync;
19044 performWorkOnRoot(root, Sync, false);
19045 }
19046 return;
19047 }
19048
19049 // TODO: Get rid of Sync and use current time?
19050 if (expirationTime === Sync) {
19051 performSyncWork();
19052 } else {
19053 scheduleCallbackWithExpirationTime(root, expirationTime);
19054 }
19055}
19056
19057function addRootToSchedule(root, expirationTime) {
19058 // Add the root to the schedule.
19059 // Check if this root is already part of the schedule.
19060 if (root.nextScheduledRoot === null) {
19061 // This root is not already scheduled. Add it.
19062 root.expirationTime = expirationTime;
19063 if (lastScheduledRoot === null) {
19064 firstScheduledRoot = lastScheduledRoot = root;
19065 root.nextScheduledRoot = root;
19066 } else {
19067 lastScheduledRoot.nextScheduledRoot = root;
19068 lastScheduledRoot = root;
19069 lastScheduledRoot.nextScheduledRoot = firstScheduledRoot;
19070 }
19071 } else {
19072 // This root is already scheduled, but its priority may have increased.
19073 var remainingExpirationTime = root.expirationTime;
19074 if (expirationTime > remainingExpirationTime) {
19075 // Update the priority.
19076 root.expirationTime = expirationTime;
19077 }
19078 }
19079}
19080
19081function findHighestPriorityRoot() {
19082 var highestPriorityWork = NoWork;
19083 var highestPriorityRoot = null;
19084 if (lastScheduledRoot !== null) {
19085 var previousScheduledRoot = lastScheduledRoot;
19086 var root = firstScheduledRoot;
19087 while (root !== null) {
19088 var remainingExpirationTime = root.expirationTime;
19089 if (remainingExpirationTime === NoWork) {
19090 // This root no longer has work. Remove it from the scheduler.
19091
19092 // TODO: This check is redudant, but Flow is confused by the branch
19093 // below where we set lastScheduledRoot to null, even though we break
19094 // from the loop right after.
19095 !(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;
19096 if (root === root.nextScheduledRoot) {
19097 // This is the only root in the list.
19098 root.nextScheduledRoot = null;
19099 firstScheduledRoot = lastScheduledRoot = null;
19100 break;
19101 } else if (root === firstScheduledRoot) {
19102 // This is the first root in the list.
19103 var next = root.nextScheduledRoot;
19104 firstScheduledRoot = next;
19105 lastScheduledRoot.nextScheduledRoot = next;
19106 root.nextScheduledRoot = null;
19107 } else if (root === lastScheduledRoot) {
19108 // This is the last root in the list.
19109 lastScheduledRoot = previousScheduledRoot;
19110 lastScheduledRoot.nextScheduledRoot = firstScheduledRoot;
19111 root.nextScheduledRoot = null;
19112 break;
19113 } else {
19114 previousScheduledRoot.nextScheduledRoot = root.nextScheduledRoot;
19115 root.nextScheduledRoot = null;
19116 }
19117 root = previousScheduledRoot.nextScheduledRoot;
19118 } else {
19119 if (remainingExpirationTime > highestPriorityWork) {
19120 // Update the priority, if it's higher
19121 highestPriorityWork = remainingExpirationTime;
19122 highestPriorityRoot = root;
19123 }
19124 if (root === lastScheduledRoot) {
19125 break;
19126 }
19127 if (highestPriorityWork === Sync) {
19128 // Sync is highest priority by definition so
19129 // we can stop searching.
19130 break;
19131 }
19132 previousScheduledRoot = root;
19133 root = root.nextScheduledRoot;
19134 }
19135 }
19136 }
19137
19138 nextFlushedRoot = highestPriorityRoot;
19139 nextFlushedExpirationTime = highestPriorityWork;
19140}
19141
19142// TODO: This wrapper exists because many of the older tests (the ones that use
19143// flushDeferredPri) rely on the number of times `shouldYield` is called. We
19144// should get rid of it.
19145var didYield = false;
19146function shouldYieldToRenderer() {
19147 if (didYield) {
19148 return true;
19149 }
19150 if (unstable_shouldYield()) {
19151 didYield = true;
19152 return true;
19153 }
19154 return false;
19155}
19156
19157function performAsyncWork() {
19158 try {
19159 if (!shouldYieldToRenderer()) {
19160 // The callback timed out. That means at least one update has expired.
19161 // Iterate through the root schedule. If they contain expired work, set
19162 // the next render expiration time to the current time. This has the effect
19163 // of flushing all expired work in a single batch, instead of flushing each
19164 // level one at a time.
19165 if (firstScheduledRoot !== null) {
19166 recomputeCurrentRendererTime();
19167 var root = firstScheduledRoot;
19168 do {
19169 didExpireAtExpirationTime(root, currentRendererTime);
19170 // The root schedule is circular, so this is never null.
19171 root = root.nextScheduledRoot;
19172 } while (root !== firstScheduledRoot);
19173 }
19174 }
19175 performWork(NoWork, true);
19176 } finally {
19177 didYield = false;
19178 }
19179}
19180
19181function performSyncWork() {
19182 performWork(Sync, false);
19183}
19184
19185function performWork(minExpirationTime, isYieldy) {
19186 // Keep working on roots until there's no more work, or until there's a higher
19187 // priority event.
19188 findHighestPriorityRoot();
19189
19190 if (isYieldy) {
19191 recomputeCurrentRendererTime();
19192 currentSchedulerTime = currentRendererTime;
19193
19194 if (enableUserTimingAPI) {
19195 var didExpire = nextFlushedExpirationTime > currentRendererTime;
19196 var timeout = expirationTimeToMs(nextFlushedExpirationTime);
19197 stopRequestCallbackTimer(didExpire, timeout);
19198 }
19199
19200 while (nextFlushedRoot !== null && nextFlushedExpirationTime !== NoWork && minExpirationTime <= nextFlushedExpirationTime && !(didYield && currentRendererTime > nextFlushedExpirationTime)) {
19201 performWorkOnRoot(nextFlushedRoot, nextFlushedExpirationTime, currentRendererTime > nextFlushedExpirationTime);
19202 findHighestPriorityRoot();
19203 recomputeCurrentRendererTime();
19204 currentSchedulerTime = currentRendererTime;
19205 }
19206 } else {
19207 while (nextFlushedRoot !== null && nextFlushedExpirationTime !== NoWork && minExpirationTime <= nextFlushedExpirationTime) {
19208 performWorkOnRoot(nextFlushedRoot, nextFlushedExpirationTime, false);
19209 findHighestPriorityRoot();
19210 }
19211 }
19212
19213 // We're done flushing work. Either we ran out of time in this callback,
19214 // or there's no more work left with sufficient priority.
19215
19216 // If we're inside a callback, set this to false since we just completed it.
19217 if (isYieldy) {
19218 callbackExpirationTime = NoWork;
19219 callbackID = null;
19220 }
19221 // If there's work left over, schedule a new callback.
19222 if (nextFlushedExpirationTime !== NoWork) {
19223 scheduleCallbackWithExpirationTime(nextFlushedRoot, nextFlushedExpirationTime);
19224 }
19225
19226 // Clean-up.
19227 finishRendering();
19228}
19229
19230function flushRoot(root, expirationTime) {
19231 !!isRendering ? invariant(false, 'work.commit(): Cannot commit while already rendering. This likely means you attempted to commit from inside a lifecycle method.') : void 0;
19232 // Perform work on root as if the given expiration time is the current time.
19233 // This has the effect of synchronously flushing all work up to and
19234 // including the given time.
19235 nextFlushedRoot = root;
19236 nextFlushedExpirationTime = expirationTime;
19237 performWorkOnRoot(root, expirationTime, false);
19238 // Flush any sync work that was scheduled by lifecycles
19239 performSyncWork();
19240}
19241
19242function finishRendering() {
19243 nestedUpdateCount = 0;
19244 lastCommittedRootDuringThisBatch = null;
19245
19246 if (completedBatches !== null) {
19247 var batches = completedBatches;
19248 completedBatches = null;
19249 for (var i = 0; i < batches.length; i++) {
19250 var batch = batches[i];
19251 try {
19252 batch._onComplete();
19253 } catch (error) {
19254 if (!hasUnhandledError) {
19255 hasUnhandledError = true;
19256 unhandledError = error;
19257 }
19258 }
19259 }
19260 }
19261
19262 if (hasUnhandledError) {
19263 var error = unhandledError;
19264 unhandledError = null;
19265 hasUnhandledError = false;
19266 throw error;
19267 }
19268}
19269
19270function performWorkOnRoot(root, expirationTime, isYieldy) {
19271 !!isRendering ? invariant(false, 'performWorkOnRoot was called recursively. This error is likely caused by a bug in React. Please file an issue.') : void 0;
19272
19273 isRendering = true;
19274
19275 // Check if this is async work or sync/expired work.
19276 if (!isYieldy) {
19277 // Flush work without yielding.
19278 // TODO: Non-yieldy work does not necessarily imply expired work. A renderer
19279 // may want to perform some work without yielding, but also without
19280 // requiring the root to complete (by triggering placeholders).
19281
19282 var finishedWork = root.finishedWork;
19283 if (finishedWork !== null) {
19284 // This root is already complete. We can commit it.
19285 completeRoot(root, finishedWork, expirationTime);
19286 } else {
19287 root.finishedWork = null;
19288 // If this root previously suspended, clear its existing timeout, since
19289 // we're about to try rendering again.
19290 var timeoutHandle = root.timeoutHandle;
19291 if (timeoutHandle !== noTimeout) {
19292 root.timeoutHandle = noTimeout;
19293 // $FlowFixMe Complains noTimeout is not a TimeoutID, despite the check above
19294 cancelTimeout(timeoutHandle);
19295 }
19296 renderRoot(root, isYieldy);
19297 finishedWork = root.finishedWork;
19298 if (finishedWork !== null) {
19299 // We've completed the root. Commit it.
19300 completeRoot(root, finishedWork, expirationTime);
19301 }
19302 }
19303 } else {
19304 // Flush async work.
19305 var _finishedWork = root.finishedWork;
19306 if (_finishedWork !== null) {
19307 // This root is already complete. We can commit it.
19308 completeRoot(root, _finishedWork, expirationTime);
19309 } else {
19310 root.finishedWork = null;
19311 // If this root previously suspended, clear its existing timeout, since
19312 // we're about to try rendering again.
19313 var _timeoutHandle = root.timeoutHandle;
19314 if (_timeoutHandle !== noTimeout) {
19315 root.timeoutHandle = noTimeout;
19316 // $FlowFixMe Complains noTimeout is not a TimeoutID, despite the check above
19317 cancelTimeout(_timeoutHandle);
19318 }
19319 renderRoot(root, isYieldy);
19320 _finishedWork = root.finishedWork;
19321 if (_finishedWork !== null) {
19322 // We've completed the root. Check the if we should yield one more time
19323 // before committing.
19324 if (!shouldYieldToRenderer()) {
19325 // Still time left. Commit the root.
19326 completeRoot(root, _finishedWork, expirationTime);
19327 } else {
19328 // There's no time left. Mark this root as complete. We'll come
19329 // back and commit it later.
19330 root.finishedWork = _finishedWork;
19331 }
19332 }
19333 }
19334 }
19335
19336 isRendering = false;
19337}
19338
19339function completeRoot(root, finishedWork, expirationTime) {
19340 // Check if there's a batch that matches this expiration time.
19341 var firstBatch = root.firstBatch;
19342 if (firstBatch !== null && firstBatch._expirationTime >= expirationTime) {
19343 if (completedBatches === null) {
19344 completedBatches = [firstBatch];
19345 } else {
19346 completedBatches.push(firstBatch);
19347 }
19348 if (firstBatch._defer) {
19349 // This root is blocked from committing by a batch. Unschedule it until
19350 // we receive another update.
19351 root.finishedWork = finishedWork;
19352 root.expirationTime = NoWork;
19353 return;
19354 }
19355 }
19356
19357 // Commit the root.
19358 root.finishedWork = null;
19359
19360 // Check if this is a nested update (a sync update scheduled during the
19361 // commit phase).
19362 if (root === lastCommittedRootDuringThisBatch) {
19363 // If the next root is the same as the previous root, this is a nested
19364 // update. To prevent an infinite loop, increment the nested update count.
19365 nestedUpdateCount++;
19366 } else {
19367 // Reset whenever we switch roots.
19368 lastCommittedRootDuringThisBatch = root;
19369 nestedUpdateCount = 0;
19370 }
19371 commitRoot(root, finishedWork);
19372}
19373
19374function onUncaughtError(error) {
19375 !(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;
19376 // Unschedule this root so we don't work on it again until there's
19377 // another update.
19378 nextFlushedRoot.expirationTime = NoWork;
19379 if (!hasUnhandledError) {
19380 hasUnhandledError = true;
19381 unhandledError = error;
19382 }
19383}
19384
19385// TODO: Batching should be implemented at the renderer level, not inside
19386// the reconciler.
19387function batchedUpdates$1(fn, a) {
19388 var previousIsBatchingUpdates = isBatchingUpdates;
19389 isBatchingUpdates = true;
19390 try {
19391 return fn(a);
19392 } finally {
19393 isBatchingUpdates = previousIsBatchingUpdates;
19394 if (!isBatchingUpdates && !isRendering) {
19395 performSyncWork();
19396 }
19397 }
19398}
19399
19400// TODO: Batching should be implemented at the renderer level, not inside
19401// the reconciler.
19402function unbatchedUpdates(fn, a) {
19403 if (isBatchingUpdates && !isUnbatchingUpdates) {
19404 isUnbatchingUpdates = true;
19405 try {
19406 return fn(a);
19407 } finally {
19408 isUnbatchingUpdates = false;
19409 }
19410 }
19411 return fn(a);
19412}
19413
19414// TODO: Batching should be implemented at the renderer level, not within
19415// the reconciler.
19416function flushSync(fn, a) {
19417 !!isRendering ? invariant(false, 'flushSync was called from inside a lifecycle method. It cannot be called when React is already rendering.') : void 0;
19418 var previousIsBatchingUpdates = isBatchingUpdates;
19419 isBatchingUpdates = true;
19420 try {
19421 return syncUpdates(fn, a);
19422 } finally {
19423 isBatchingUpdates = previousIsBatchingUpdates;
19424 performSyncWork();
19425 }
19426}
19427
19428function interactiveUpdates$1(fn, a, b) {
19429 if (isBatchingInteractiveUpdates) {
19430 return fn(a, b);
19431 }
19432 // If there are any pending interactive updates, synchronously flush them.
19433 // This needs to happen before we read any handlers, because the effect of
19434 // the previous event may influence which handlers are called during
19435 // this event.
19436 if (!isBatchingUpdates && !isRendering && lowestPriorityPendingInteractiveExpirationTime !== NoWork) {
19437 // Synchronously flush pending interactive updates.
19438 performWork(lowestPriorityPendingInteractiveExpirationTime, false);
19439 lowestPriorityPendingInteractiveExpirationTime = NoWork;
19440 }
19441 var previousIsBatchingInteractiveUpdates = isBatchingInteractiveUpdates;
19442 var previousIsBatchingUpdates = isBatchingUpdates;
19443 isBatchingInteractiveUpdates = true;
19444 isBatchingUpdates = true;
19445 try {
19446 return fn(a, b);
19447 } finally {
19448 isBatchingInteractiveUpdates = previousIsBatchingInteractiveUpdates;
19449 isBatchingUpdates = previousIsBatchingUpdates;
19450 if (!isBatchingUpdates && !isRendering) {
19451 performSyncWork();
19452 }
19453 }
19454}
19455
19456function flushInteractiveUpdates$1() {
19457 if (!isRendering && lowestPriorityPendingInteractiveExpirationTime !== NoWork) {
19458 // Synchronously flush pending interactive updates.
19459 performWork(lowestPriorityPendingInteractiveExpirationTime, false);
19460 lowestPriorityPendingInteractiveExpirationTime = NoWork;
19461 }
19462}
19463
19464function flushControlled(fn) {
19465 var previousIsBatchingUpdates = isBatchingUpdates;
19466 isBatchingUpdates = true;
19467 try {
19468 syncUpdates(fn);
19469 } finally {
19470 isBatchingUpdates = previousIsBatchingUpdates;
19471 if (!isBatchingUpdates && !isRendering) {
19472 performSyncWork();
19473 }
19474 }
19475}
19476
19477// 0 is PROD, 1 is DEV.
19478// Might add PROFILE later.
19479
19480
19481var didWarnAboutNestedUpdates = void 0;
19482var didWarnAboutFindNodeInStrictMode = void 0;
19483
19484{
19485 didWarnAboutNestedUpdates = false;
19486 didWarnAboutFindNodeInStrictMode = {};
19487}
19488
19489function getContextForSubtree(parentComponent) {
19490 if (!parentComponent) {
19491 return emptyContextObject;
19492 }
19493
19494 var fiber = get(parentComponent);
19495 var parentContext = findCurrentUnmaskedContext(fiber);
19496
19497 if (fiber.tag === ClassComponent) {
19498 var Component = fiber.type;
19499 if (isContextProvider(Component)) {
19500 return processChildContext(fiber, Component, parentContext);
19501 }
19502 }
19503
19504 return parentContext;
19505}
19506
19507function scheduleRootUpdate(current$$1, element, expirationTime, callback) {
19508 {
19509 if (phase === 'render' && current !== null && !didWarnAboutNestedUpdates) {
19510 didWarnAboutNestedUpdates = true;
19511 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');
19512 }
19513 }
19514
19515 var update = createUpdate(expirationTime);
19516 // Caution: React DevTools currently depends on this property
19517 // being called "element".
19518 update.payload = { element: element };
19519
19520 callback = callback === undefined ? null : callback;
19521 if (callback !== null) {
19522 !(typeof callback === 'function') ? warningWithoutStack$1(false, 'render(...): Expected the last optional `callback` argument to be a ' + 'function. Instead received: %s.', callback) : void 0;
19523 update.callback = callback;
19524 }
19525
19526 flushPassiveEffects();
19527 enqueueUpdate(current$$1, update);
19528 scheduleWork(current$$1, expirationTime);
19529
19530 return expirationTime;
19531}
19532
19533function updateContainerAtExpirationTime(element, container, parentComponent, expirationTime, callback) {
19534 // TODO: If this is a nested container, this won't be the root.
19535 var current$$1 = container.current;
19536
19537 {
19538 if (ReactFiberInstrumentation_1.debugTool) {
19539 if (current$$1.alternate === null) {
19540 ReactFiberInstrumentation_1.debugTool.onMountContainer(container);
19541 } else if (element === null) {
19542 ReactFiberInstrumentation_1.debugTool.onUnmountContainer(container);
19543 } else {
19544 ReactFiberInstrumentation_1.debugTool.onUpdateContainer(container);
19545 }
19546 }
19547 }
19548
19549 var context = getContextForSubtree(parentComponent);
19550 if (container.context === null) {
19551 container.context = context;
19552 } else {
19553 container.pendingContext = context;
19554 }
19555
19556 return scheduleRootUpdate(current$$1, element, expirationTime, callback);
19557}
19558
19559function findHostInstance(component) {
19560 var fiber = get(component);
19561 if (fiber === undefined) {
19562 if (typeof component.render === 'function') {
19563 invariant(false, 'Unable to find node on an unmounted component.');
19564 } else {
19565 invariant(false, 'Argument appears to not be a ReactComponent. Keys: %s', Object.keys(component));
19566 }
19567 }
19568 var hostFiber = findCurrentHostFiber(fiber);
19569 if (hostFiber === null) {
19570 return null;
19571 }
19572 return hostFiber.stateNode;
19573}
19574
19575function findHostInstanceWithWarning(component, methodName) {
19576 {
19577 var fiber = get(component);
19578 if (fiber === undefined) {
19579 if (typeof component.render === 'function') {
19580 invariant(false, 'Unable to find node on an unmounted component.');
19581 } else {
19582 invariant(false, 'Argument appears to not be a ReactComponent. Keys: %s', Object.keys(component));
19583 }
19584 }
19585 var hostFiber = findCurrentHostFiber(fiber);
19586 if (hostFiber === null) {
19587 return null;
19588 }
19589 if (hostFiber.mode & StrictMode) {
19590 var componentName = getComponentName(fiber.type) || 'Component';
19591 if (!didWarnAboutFindNodeInStrictMode[componentName]) {
19592 didWarnAboutFindNodeInStrictMode[componentName] = true;
19593 if (fiber.mode & StrictMode) {
19594 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));
19595 } else {
19596 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));
19597 }
19598 }
19599 }
19600 return hostFiber.stateNode;
19601 }
19602 return findHostInstance(component);
19603}
19604
19605function createContainer(containerInfo, isConcurrent, hydrate) {
19606 return createFiberRoot(containerInfo, isConcurrent, hydrate);
19607}
19608
19609function updateContainer(element, container, parentComponent, callback) {
19610 var current$$1 = container.current;
19611 var currentTime = requestCurrentTime();
19612 var expirationTime = computeExpirationForFiber(currentTime, current$$1);
19613 return updateContainerAtExpirationTime(element, container, parentComponent, expirationTime, callback);
19614}
19615
19616function getPublicRootInstance(container) {
19617 var containerFiber = container.current;
19618 if (!containerFiber.child) {
19619 return null;
19620 }
19621 switch (containerFiber.child.tag) {
19622 case HostComponent:
19623 return getPublicInstance(containerFiber.child.stateNode);
19624 default:
19625 return containerFiber.child.stateNode;
19626 }
19627}
19628
19629function findHostInstanceWithNoPortals(fiber) {
19630 var hostFiber = findCurrentHostFiberWithNoPortals(fiber);
19631 if (hostFiber === null) {
19632 return null;
19633 }
19634 return hostFiber.stateNode;
19635}
19636
19637var overrideProps = null;
19638
19639{
19640 var copyWithSetImpl = function (obj, path, idx, value) {
19641 if (idx >= path.length) {
19642 return value;
19643 }
19644 var key = path[idx];
19645 var updated = Array.isArray(obj) ? obj.slice() : _assign({}, obj);
19646 // $FlowFixMe number or string is fine here
19647 updated[key] = copyWithSetImpl(obj[key], path, idx + 1, value);
19648 return updated;
19649 };
19650
19651 var copyWithSet = function (obj, path, value) {
19652 return copyWithSetImpl(obj, path, 0, value);
19653 };
19654
19655 // Support DevTools props for function components, forwardRef, memo, host components, etc.
19656 overrideProps = function (fiber, path, value) {
19657 flushPassiveEffects();
19658 fiber.pendingProps = copyWithSet(fiber.memoizedProps, path, value);
19659 if (fiber.alternate) {
19660 fiber.alternate.pendingProps = fiber.pendingProps;
19661 }
19662 scheduleWork(fiber, Sync);
19663 };
19664}
19665
19666function injectIntoDevTools(devToolsConfig) {
19667 var findFiberByHostInstance = devToolsConfig.findFiberByHostInstance;
19668
19669 return injectInternals(_assign({}, devToolsConfig, {
19670 overrideProps: overrideProps,
19671 findHostInstanceByFiber: function (fiber) {
19672 var hostFiber = findCurrentHostFiber(fiber);
19673 if (hostFiber === null) {
19674 return null;
19675 }
19676 return hostFiber.stateNode;
19677 },
19678 findFiberByHostInstance: function (instance) {
19679 if (!findFiberByHostInstance) {
19680 // Might not be implemented by the renderer.
19681 return null;
19682 }
19683 return findFiberByHostInstance(instance);
19684 }
19685 }));
19686}
19687
19688// This file intentionally does *not* have the Flow annotation.
19689// Don't add it. See `./inline-typed.js` for an explanation.
19690
19691function createPortal$1(children, containerInfo,
19692// TODO: figure out the API for cross-renderer implementation.
19693implementation) {
19694 var key = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null;
19695
19696 return {
19697 // This tag allow us to uniquely identify this as a React Portal
19698 $$typeof: REACT_PORTAL_TYPE,
19699 key: key == null ? null : '' + key,
19700 children: children,
19701 containerInfo: containerInfo,
19702 implementation: implementation
19703 };
19704}
19705
19706// TODO: this is special because it gets imported during build.
19707
19708var ReactVersion = '16.7.0';
19709
19710// TODO: This type is shared between the reconciler and ReactDOM, but will
19711// eventually be lifted out to the renderer.
19712// and a different host config import (react-reconciler/inline.fire).
19713// TODO: real implementation.
19714// console.log('Hello from Fire entry point.');
19715
19716var ReactCurrentOwner = ReactSharedInternals.ReactCurrentOwner;
19717
19718var topLevelUpdateWarnings = void 0;
19719var warnOnInvalidCallback = void 0;
19720var didWarnAboutUnstableCreatePortal = false;
19721
19722{
19723 if (typeof Map !== 'function' ||
19724 // $FlowIssue Flow incorrectly thinks Map has no prototype
19725 Map.prototype == null || typeof Map.prototype.forEach !== 'function' || typeof Set !== 'function' ||
19726 // $FlowIssue Flow incorrectly thinks Set has no prototype
19727 Set.prototype == null || typeof Set.prototype.clear !== 'function' || typeof Set.prototype.forEach !== 'function') {
19728 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');
19729 }
19730
19731 topLevelUpdateWarnings = function (container) {
19732 if (container._reactRootContainer && container.nodeType !== COMMENT_NODE) {
19733 var hostInstance = findHostInstanceWithNoPortals(container._reactRootContainer._internalRoot.current);
19734 if (hostInstance) {
19735 !(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;
19736 }
19737 }
19738
19739 var isRootRenderedBySomeReact = !!container._reactRootContainer;
19740 var rootEl = getReactRootElementInContainer(container);
19741 var hasNonRootReactChild = !!(rootEl && getInstanceFromNode$1(rootEl));
19742
19743 !(!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;
19744
19745 !(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;
19746 };
19747
19748 warnOnInvalidCallback = function (callback, callerName) {
19749 !(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;
19750 };
19751}
19752
19753setRestoreImplementation(restoreControlledState$1);
19754
19755function ReactBatch(root) {
19756 var expirationTime = computeUniqueAsyncExpiration();
19757 this._expirationTime = expirationTime;
19758 this._root = root;
19759 this._next = null;
19760 this._callbacks = null;
19761 this._didComplete = false;
19762 this._hasChildren = false;
19763 this._children = null;
19764 this._defer = true;
19765}
19766ReactBatch.prototype.render = function (children) {
19767 !this._defer ? invariant(false, 'batch.render: Cannot render a batch that already committed.') : void 0;
19768 this._hasChildren = true;
19769 this._children = children;
19770 var internalRoot = this._root._internalRoot;
19771 var expirationTime = this._expirationTime;
19772 var work = new ReactWork();
19773 updateContainerAtExpirationTime(children, internalRoot, null, expirationTime, work._onCommit);
19774 return work;
19775};
19776ReactBatch.prototype.then = function (onComplete) {
19777 if (this._didComplete) {
19778 onComplete();
19779 return;
19780 }
19781 var callbacks = this._callbacks;
19782 if (callbacks === null) {
19783 callbacks = this._callbacks = [];
19784 }
19785 callbacks.push(onComplete);
19786};
19787ReactBatch.prototype.commit = function () {
19788 var internalRoot = this._root._internalRoot;
19789 var firstBatch = internalRoot.firstBatch;
19790 !(this._defer && firstBatch !== null) ? invariant(false, 'batch.commit: Cannot commit a batch multiple times.') : void 0;
19791
19792 if (!this._hasChildren) {
19793 // This batch is empty. Return.
19794 this._next = null;
19795 this._defer = false;
19796 return;
19797 }
19798
19799 var expirationTime = this._expirationTime;
19800
19801 // Ensure this is the first batch in the list.
19802 if (firstBatch !== this) {
19803 // This batch is not the earliest batch. We need to move it to the front.
19804 // Update its expiration time to be the expiration time of the earliest
19805 // batch, so that we can flush it without flushing the other batches.
19806 if (this._hasChildren) {
19807 expirationTime = this._expirationTime = firstBatch._expirationTime;
19808 // Rendering this batch again ensures its children will be the final state
19809 // when we flush (updates are processed in insertion order: last
19810 // update wins).
19811 // TODO: This forces a restart. Should we print a warning?
19812 this.render(this._children);
19813 }
19814
19815 // Remove the batch from the list.
19816 var previous = null;
19817 var batch = firstBatch;
19818 while (batch !== this) {
19819 previous = batch;
19820 batch = batch._next;
19821 }
19822 !(previous !== null) ? invariant(false, 'batch.commit: Cannot commit a batch multiple times.') : void 0;
19823 previous._next = batch._next;
19824
19825 // Add it to the front.
19826 this._next = firstBatch;
19827 firstBatch = internalRoot.firstBatch = this;
19828 }
19829
19830 // Synchronously flush all the work up to this batch's expiration time.
19831 this._defer = false;
19832 flushRoot(internalRoot, expirationTime);
19833
19834 // Pop the batch from the list.
19835 var next = this._next;
19836 this._next = null;
19837 firstBatch = internalRoot.firstBatch = next;
19838
19839 // Append the next earliest batch's children to the update queue.
19840 if (firstBatch !== null && firstBatch._hasChildren) {
19841 firstBatch.render(firstBatch._children);
19842 }
19843};
19844ReactBatch.prototype._onComplete = function () {
19845 if (this._didComplete) {
19846 return;
19847 }
19848 this._didComplete = true;
19849 var callbacks = this._callbacks;
19850 if (callbacks === null) {
19851 return;
19852 }
19853 // TODO: Error handling.
19854 for (var i = 0; i < callbacks.length; i++) {
19855 var _callback = callbacks[i];
19856 _callback();
19857 }
19858};
19859
19860function ReactWork() {
19861 this._callbacks = null;
19862 this._didCommit = false;
19863 // TODO: Avoid need to bind by replacing callbacks in the update queue with
19864 // list of Work objects.
19865 this._onCommit = this._onCommit.bind(this);
19866}
19867ReactWork.prototype.then = function (onCommit) {
19868 if (this._didCommit) {
19869 onCommit();
19870 return;
19871 }
19872 var callbacks = this._callbacks;
19873 if (callbacks === null) {
19874 callbacks = this._callbacks = [];
19875 }
19876 callbacks.push(onCommit);
19877};
19878ReactWork.prototype._onCommit = function () {
19879 if (this._didCommit) {
19880 return;
19881 }
19882 this._didCommit = true;
19883 var callbacks = this._callbacks;
19884 if (callbacks === null) {
19885 return;
19886 }
19887 // TODO: Error handling.
19888 for (var i = 0; i < callbacks.length; i++) {
19889 var _callback2 = callbacks[i];
19890 !(typeof _callback2 === 'function') ? invariant(false, 'Invalid argument passed as callback. Expected a function. Instead received: %s', _callback2) : void 0;
19891 _callback2();
19892 }
19893};
19894
19895function ReactRoot(container, isConcurrent, hydrate) {
19896 var root = createContainer(container, isConcurrent, hydrate);
19897 this._internalRoot = root;
19898}
19899ReactRoot.prototype.render = function (children, callback) {
19900 var root = this._internalRoot;
19901 var work = new ReactWork();
19902 callback = callback === undefined ? null : callback;
19903 {
19904 warnOnInvalidCallback(callback, 'render');
19905 }
19906 if (callback !== null) {
19907 work.then(callback);
19908 }
19909 updateContainer(children, root, null, work._onCommit);
19910 return work;
19911};
19912ReactRoot.prototype.unmount = function (callback) {
19913 var root = this._internalRoot;
19914 var work = new ReactWork();
19915 callback = callback === undefined ? null : callback;
19916 {
19917 warnOnInvalidCallback(callback, 'render');
19918 }
19919 if (callback !== null) {
19920 work.then(callback);
19921 }
19922 updateContainer(null, root, null, work._onCommit);
19923 return work;
19924};
19925ReactRoot.prototype.legacy_renderSubtreeIntoContainer = function (parentComponent, children, callback) {
19926 var root = this._internalRoot;
19927 var work = new ReactWork();
19928 callback = callback === undefined ? null : callback;
19929 {
19930 warnOnInvalidCallback(callback, 'render');
19931 }
19932 if (callback !== null) {
19933 work.then(callback);
19934 }
19935 updateContainer(children, root, parentComponent, work._onCommit);
19936 return work;
19937};
19938ReactRoot.prototype.createBatch = function () {
19939 var batch = new ReactBatch(this);
19940 var expirationTime = batch._expirationTime;
19941
19942 var internalRoot = this._internalRoot;
19943 var firstBatch = internalRoot.firstBatch;
19944 if (firstBatch === null) {
19945 internalRoot.firstBatch = batch;
19946 batch._next = null;
19947 } else {
19948 // Insert sorted by expiration time then insertion order
19949 var insertAfter = null;
19950 var insertBefore = firstBatch;
19951 while (insertBefore !== null && insertBefore._expirationTime >= expirationTime) {
19952 insertAfter = insertBefore;
19953 insertBefore = insertBefore._next;
19954 }
19955 batch._next = insertBefore;
19956 if (insertAfter !== null) {
19957 insertAfter._next = batch;
19958 }
19959 }
19960
19961 return batch;
19962};
19963
19964/**
19965 * True if the supplied DOM node is a valid node element.
19966 *
19967 * @param {?DOMElement} node The candidate DOM node.
19968 * @return {boolean} True if the DOM is a valid DOM node.
19969 * @internal
19970 */
19971function isValidContainer(node) {
19972 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 '));
19973}
19974
19975function getReactRootElementInContainer(container) {
19976 if (!container) {
19977 return null;
19978 }
19979
19980 if (container.nodeType === DOCUMENT_NODE) {
19981 return container.documentElement;
19982 } else {
19983 return container.firstChild;
19984 }
19985}
19986
19987function shouldHydrateDueToLegacyHeuristic(container) {
19988 var rootElement = getReactRootElementInContainer(container);
19989 return !!(rootElement && rootElement.nodeType === ELEMENT_NODE && rootElement.hasAttribute(ROOT_ATTRIBUTE_NAME));
19990}
19991
19992setBatchingImplementation(batchedUpdates$1, interactiveUpdates$1, flushInteractiveUpdates$1);
19993
19994var warnedAboutHydrateAPI = false;
19995
19996function legacyCreateRootFromDOMContainer(container, forceHydrate) {
19997 var shouldHydrate = forceHydrate || shouldHydrateDueToLegacyHeuristic(container);
19998 // First clear any existing content.
19999 if (!shouldHydrate) {
20000 var warned = false;
20001 var rootSibling = void 0;
20002 while (rootSibling = container.lastChild) {
20003 {
20004 if (!warned && rootSibling.nodeType === ELEMENT_NODE && rootSibling.hasAttribute(ROOT_ATTRIBUTE_NAME)) {
20005 warned = true;
20006 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.');
20007 }
20008 }
20009 container.removeChild(rootSibling);
20010 }
20011 }
20012 {
20013 if (shouldHydrate && !forceHydrate && !warnedAboutHydrateAPI) {
20014 warnedAboutHydrateAPI = true;
20015 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.');
20016 }
20017 }
20018 // Legacy roots are not async by default.
20019 var isConcurrent = false;
20020 return new ReactRoot(container, isConcurrent, shouldHydrate);
20021}
20022
20023function legacyRenderSubtreeIntoContainer(parentComponent, children, container, forceHydrate, callback) {
20024 // TODO: Ensure all entry points contain this check
20025 !isValidContainer(container) ? invariant(false, 'Target container is not a DOM element.') : void 0;
20026
20027 {
20028 topLevelUpdateWarnings(container);
20029 }
20030
20031 // TODO: Without `any` type, Flow says "Property cannot be accessed on any
20032 // member of intersection type." Whyyyyyy.
20033 var root = container._reactRootContainer;
20034 if (!root) {
20035 // Initial mount
20036 root = container._reactRootContainer = legacyCreateRootFromDOMContainer(container, forceHydrate);
20037 if (typeof callback === 'function') {
20038 var originalCallback = callback;
20039 callback = function () {
20040 var instance = getPublicRootInstance(root._internalRoot);
20041 originalCallback.call(instance);
20042 };
20043 }
20044 // Initial mount should not be batched.
20045 unbatchedUpdates(function () {
20046 if (parentComponent != null) {
20047 root.legacy_renderSubtreeIntoContainer(parentComponent, children, callback);
20048 } else {
20049 root.render(children, callback);
20050 }
20051 });
20052 } else {
20053 if (typeof callback === 'function') {
20054 var _originalCallback = callback;
20055 callback = function () {
20056 var instance = getPublicRootInstance(root._internalRoot);
20057 _originalCallback.call(instance);
20058 };
20059 }
20060 // Update
20061 if (parentComponent != null) {
20062 root.legacy_renderSubtreeIntoContainer(parentComponent, children, callback);
20063 } else {
20064 root.render(children, callback);
20065 }
20066 }
20067 return getPublicRootInstance(root._internalRoot);
20068}
20069
20070function createPortal$$1(children, container) {
20071 var key = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
20072
20073 !isValidContainer(container) ? invariant(false, 'Target container is not a DOM element.') : void 0;
20074 // TODO: pass ReactDOM portal implementation as third argument
20075 return createPortal$1(children, container, null, key);
20076}
20077
20078var ReactDOM = {
20079 createPortal: createPortal$$1,
20080
20081 findDOMNode: function (componentOrElement) {
20082 {
20083 var owner = ReactCurrentOwner.current;
20084 if (owner !== null && owner.stateNode !== null) {
20085 var warnedAboutRefsInRender = owner.stateNode._warnedAboutRefsInRender;
20086 !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;
20087 owner.stateNode._warnedAboutRefsInRender = true;
20088 }
20089 }
20090 if (componentOrElement == null) {
20091 return null;
20092 }
20093 if (componentOrElement.nodeType === ELEMENT_NODE) {
20094 return componentOrElement;
20095 }
20096 {
20097 return findHostInstanceWithWarning(componentOrElement, 'findDOMNode');
20098 }
20099 return findHostInstance(componentOrElement);
20100 },
20101 hydrate: function (element, container, callback) {
20102 // TODO: throw or warn if we couldn't hydrate?
20103 return legacyRenderSubtreeIntoContainer(null, element, container, true, callback);
20104 },
20105 render: function (element, container, callback) {
20106 return legacyRenderSubtreeIntoContainer(null, element, container, false, callback);
20107 },
20108 unstable_renderSubtreeIntoContainer: function (parentComponent, element, containerNode, callback) {
20109 !(parentComponent != null && has(parentComponent)) ? invariant(false, 'parentComponent must be a valid React Component') : void 0;
20110 return legacyRenderSubtreeIntoContainer(parentComponent, element, containerNode, false, callback);
20111 },
20112 unmountComponentAtNode: function (container) {
20113 !isValidContainer(container) ? invariant(false, 'unmountComponentAtNode(...): Target container is not a DOM element.') : void 0;
20114
20115 if (container._reactRootContainer) {
20116 {
20117 var rootEl = getReactRootElementInContainer(container);
20118 var renderedByDifferentReact = rootEl && !getInstanceFromNode$1(rootEl);
20119 !!renderedByDifferentReact ? warningWithoutStack$1(false, "unmountComponentAtNode(): The node you're attempting to unmount " + 'was rendered by another copy of React.') : void 0;
20120 }
20121
20122 // Unmount should not be batched.
20123 unbatchedUpdates(function () {
20124 legacyRenderSubtreeIntoContainer(null, null, container, false, function () {
20125 container._reactRootContainer = null;
20126 });
20127 });
20128 // If you call unmountComponentAtNode twice in quick succession, you'll
20129 // get `true` twice. That's probably fine?
20130 return true;
20131 } else {
20132 {
20133 var _rootEl = getReactRootElementInContainer(container);
20134 var hasNonRootReactChild = !!(_rootEl && getInstanceFromNode$1(_rootEl));
20135
20136 // Check if the container itself is a React root node.
20137 var isContainerReactRoot = container.nodeType === ELEMENT_NODE && isValidContainer(container.parentNode) && !!container.parentNode._reactRootContainer;
20138
20139 !!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;
20140 }
20141
20142 return false;
20143 }
20144 },
20145
20146
20147 // Temporary alias since we already shipped React 16 RC with it.
20148 // TODO: remove in React 17.
20149 unstable_createPortal: function () {
20150 if (!didWarnAboutUnstableCreatePortal) {
20151 didWarnAboutUnstableCreatePortal = true;
20152 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.');
20153 }
20154 return createPortal$$1.apply(undefined, arguments);
20155 },
20156
20157
20158 unstable_batchedUpdates: batchedUpdates$1,
20159
20160 unstable_interactiveUpdates: interactiveUpdates$1,
20161
20162 flushSync: flushSync,
20163
20164 unstable_createRoot: createRoot,
20165 unstable_flushControlled: flushControlled,
20166
20167 __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED: {
20168 // Keep in sync with ReactDOMUnstableNativeDependencies.js
20169 // and ReactTestUtils.js. This is an array for better minification.
20170 Events: [getInstanceFromNode$1, getNodeFromInstance$1, getFiberCurrentPropsFromNode$1, injection.injectEventPluginsByName, eventNameDispatchConfigs, accumulateTwoPhaseDispatches, accumulateDirectDispatches, enqueueStateRestore, restoreStateIfNeeded, dispatchEvent, runEventsInBatch]
20171 }
20172};
20173
20174function createRoot(container, options) {
20175 var functionName = enableStableConcurrentModeAPIs ? 'createRoot' : 'unstable_createRoot';
20176 !isValidContainer(container) ? invariant(false, '%s(...): Target container is not a DOM element.', functionName) : void 0;
20177 var hydrate = options != null && options.hydrate === true;
20178 return new ReactRoot(container, true, hydrate);
20179}
20180
20181if (enableStableConcurrentModeAPIs) {
20182 ReactDOM.createRoot = createRoot;
20183 ReactDOM.unstable_createRoot = undefined;
20184}
20185
20186var foundDevTools = injectIntoDevTools({
20187 findFiberByHostInstance: getClosestInstanceFromNode,
20188 bundleType: 1,
20189 version: ReactVersion,
20190 rendererPackageName: 'react-dom'
20191});
20192
20193{
20194 if (!foundDevTools && canUseDOM && window.top === window.self) {
20195 // If we're in Chrome or Firefox, provide a download link if not installed.
20196 if (navigator.userAgent.indexOf('Chrome') > -1 && navigator.userAgent.indexOf('Edge') === -1 || navigator.userAgent.indexOf('Firefox') > -1) {
20197 var protocol = window.location.protocol;
20198 // Don't warn in exotic cases like chrome-extension://.
20199 if (/^(https?|file):$/.test(protocol)) {
20200 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');
20201 }
20202 }
20203 }
20204}
20205
20206
20207
20208var ReactFire = Object.freeze({
20209 default: ReactDOM
20210});
20211
20212var ReactFire$1 = ( ReactFire && ReactDOM ) || ReactFire;
20213
20214// TODO: decide on the top-level export form.
20215// This is hacky but makes it work with both Rollup and Jest.
20216var unstableFire = ReactFire$1.default || ReactFire$1;
20217
20218return unstableFire;
20219
20220})));