UNPKG

770 kBJavaScriptView Raw
1/** @license React v16.8.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
3221// Helps identify side effects in begin-phase lifecycle hooks and setState reducers:
3222var debugRenderPhaseSideEffects = false;
3223
3224// In some cases, StrictMode should also double-render lifecycles.
3225// This can be confusing for tests though,
3226// And it can be bad for performance in production.
3227// This feature flag can be used to control the behavior:
3228var debugRenderPhaseSideEffectsForStrictMode = true;
3229
3230// To preserve the "Pause on caught exceptions" behavior of the debugger, we
3231// replay the begin phase of a failed component inside invokeGuardedCallback.
3232var replayFailedUnitOfWorkWithInvokeGuardedCallback = true;
3233
3234// Warn about deprecated, async-unsafe lifecycles; relates to RFC #6:
3235var warnAboutDeprecatedLifecycles = false;
3236
3237// Gather advanced timing metrics for Profiler subtrees.
3238var enableProfilerTimer = true;
3239
3240// Trace which interactions trigger each commit.
3241var enableSchedulerTracing = true;
3242
3243// Only used in www builds.
3244 // TODO: true? Here it might just be false.
3245
3246// Only used in www builds.
3247
3248
3249// Only used in www builds.
3250
3251
3252// React Fire: prevent the value and checked attributes from syncing
3253// with their related DOM properties
3254var disableInputAttributeSyncing = false;
3255
3256// These APIs will no longer be "unstable" in the upcoming 16.7 release,
3257// Control this behavior with a flag to support 16.6 minor releases in the meanwhile.
3258var enableStableConcurrentModeAPIs = false;
3259
3260var warnAboutShorthandPropertyCollision = false;
3261
3262// TODO: direct imports like some-package/src/* are bad. Fix me.
3263var didWarnValueDefaultValue = false;
3264var didWarnCheckedDefaultChecked = false;
3265var didWarnControlledToUncontrolled = false;
3266var didWarnUncontrolledToControlled = false;
3267
3268function isControlled(props) {
3269 var usesChecked = props.type === 'checkbox' || props.type === 'radio';
3270 return usesChecked ? props.checked != null : props.value != null;
3271}
3272
3273/**
3274 * Implements an <input> host component that allows setting these optional
3275 * props: `checked`, `value`, `defaultChecked`, and `defaultValue`.
3276 *
3277 * If `checked` or `value` are not supplied (or null/undefined), user actions
3278 * that affect the checked state or value will trigger updates to the element.
3279 *
3280 * If they are supplied (and not null/undefined), the rendered element will not
3281 * trigger updates to the element. Instead, the props must change in order for
3282 * the rendered element to be updated.
3283 *
3284 * The rendered element will be initialized as unchecked (or `defaultChecked`)
3285 * with an empty value (or `defaultValue`).
3286 *
3287 * See http://www.w3.org/TR/2012/WD-html5-20121025/the-input-element.html
3288 */
3289
3290function getHostProps(element, props) {
3291 var node = element;
3292 var checked = props.checked;
3293
3294 var hostProps = _assign({}, props, {
3295 defaultChecked: undefined,
3296 defaultValue: undefined,
3297 value: undefined,
3298 checked: checked != null ? checked : node._wrapperState.initialChecked
3299 });
3300
3301 return hostProps;
3302}
3303
3304function initWrapperState(element, props) {
3305 {
3306 ReactControlledValuePropTypes.checkPropTypes('input', props);
3307
3308 if (props.checked !== undefined && props.defaultChecked !== undefined && !didWarnCheckedDefaultChecked) {
3309 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);
3310 didWarnCheckedDefaultChecked = true;
3311 }
3312 if (props.value !== undefined && props.defaultValue !== undefined && !didWarnValueDefaultValue) {
3313 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);
3314 didWarnValueDefaultValue = true;
3315 }
3316 }
3317
3318 var node = element;
3319 var defaultValue = props.defaultValue == null ? '' : props.defaultValue;
3320
3321 node._wrapperState = {
3322 initialChecked: props.checked != null ? props.checked : props.defaultChecked,
3323 initialValue: getToStringValue(props.value != null ? props.value : defaultValue),
3324 controlled: isControlled(props)
3325 };
3326}
3327
3328function updateChecked(element, props) {
3329 var node = element;
3330 var checked = props.checked;
3331 if (checked != null) {
3332 setValueForProperty(node, 'checked', checked, false);
3333 }
3334}
3335
3336function updateWrapper(element, props) {
3337 var node = element;
3338 {
3339 var _controlled = isControlled(props);
3340
3341 if (!node._wrapperState.controlled && _controlled && !didWarnUncontrolledToControlled) {
3342 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);
3343 didWarnUncontrolledToControlled = true;
3344 }
3345 if (node._wrapperState.controlled && !_controlled && !didWarnControlledToUncontrolled) {
3346 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);
3347 didWarnControlledToUncontrolled = true;
3348 }
3349 }
3350
3351 updateChecked(element, props);
3352
3353 var value = getToStringValue(props.value);
3354 var type = props.type;
3355
3356 if (value != null) {
3357 if (type === 'number') {
3358 if (value === 0 && node.value === '' ||
3359 // We explicitly want to coerce to number here if possible.
3360 // eslint-disable-next-line
3361 node.value != value) {
3362 node.value = toString(value);
3363 }
3364 } else if (node.value !== toString(value)) {
3365 node.value = toString(value);
3366 }
3367 } else if (type === 'submit' || type === 'reset') {
3368 // Submit/reset inputs need the attribute removed completely to avoid
3369 // blank-text buttons.
3370 node.removeAttribute('value');
3371 return;
3372 }
3373
3374 if (disableInputAttributeSyncing) {
3375 // When not syncing the value attribute, React only assigns a new value
3376 // whenever the defaultValue React prop has changed. When not present,
3377 // React does nothing
3378 if (props.hasOwnProperty('defaultValue')) {
3379 setDefaultValue(node, props.type, getToStringValue(props.defaultValue));
3380 }
3381 } else {
3382 // When syncing the value attribute, the value comes from a cascade of
3383 // properties:
3384 // 1. The value React property
3385 // 2. The defaultValue React property
3386 // 3. Otherwise there should be no change
3387 if (props.hasOwnProperty('value')) {
3388 setDefaultValue(node, props.type, value);
3389 } else if (props.hasOwnProperty('defaultValue')) {
3390 setDefaultValue(node, props.type, getToStringValue(props.defaultValue));
3391 }
3392 }
3393
3394 if (disableInputAttributeSyncing) {
3395 // When not syncing the checked attribute, the attribute is directly
3396 // controllable from the defaultValue React property. It needs to be
3397 // updated as new props come in.
3398 if (props.defaultChecked == null) {
3399 node.removeAttribute('checked');
3400 } else {
3401 node.defaultChecked = !!props.defaultChecked;
3402 }
3403 } else {
3404 // When syncing the checked attribute, it only changes when it needs
3405 // to be removed, such as transitioning from a checkbox into a text input
3406 if (props.checked == null && props.defaultChecked != null) {
3407 node.defaultChecked = !!props.defaultChecked;
3408 }
3409 }
3410}
3411
3412function postMountWrapper(element, props, isHydrating) {
3413 var node = element;
3414
3415 // Do not assign value if it is already set. This prevents user text input
3416 // from being lost during SSR hydration.
3417 if (props.hasOwnProperty('value') || props.hasOwnProperty('defaultValue')) {
3418 var type = props.type;
3419 var isButton = type === 'submit' || type === 'reset';
3420
3421 // Avoid setting value attribute on submit/reset inputs as it overrides the
3422 // default value provided by the browser. See: #12872
3423 if (isButton && (props.value === undefined || props.value === null)) {
3424 return;
3425 }
3426
3427 var _initialValue = toString(node._wrapperState.initialValue);
3428
3429 // Do not assign value if it is already set. This prevents user text input
3430 // from being lost during SSR hydration.
3431 if (!isHydrating) {
3432 if (disableInputAttributeSyncing) {
3433 var value = getToStringValue(props.value);
3434
3435 // When not syncing the value attribute, the value property points
3436 // directly to the React prop. Only assign it if it exists.
3437 if (value != null) {
3438 // Always assign on buttons so that it is possible to assign an
3439 // empty string to clear button text.
3440 //
3441 // Otherwise, do not re-assign the value property if is empty. This
3442 // potentially avoids a DOM write and prevents Firefox (~60.0.1) from
3443 // prematurely marking required inputs as invalid. Equality is compared
3444 // to the current value in case the browser provided value is not an
3445 // empty string.
3446 if (isButton || value !== node.value) {
3447 node.value = toString(value);
3448 }
3449 }
3450 } else {
3451 // When syncing the value attribute, the value property should use
3452 // the wrapperState._initialValue property. This uses:
3453 //
3454 // 1. The value React property when present
3455 // 2. The defaultValue React property when present
3456 // 3. An empty string
3457 if (_initialValue !== node.value) {
3458 node.value = _initialValue;
3459 }
3460 }
3461 }
3462
3463 if (disableInputAttributeSyncing) {
3464 // When not syncing the value attribute, assign the value attribute
3465 // directly from the defaultValue React property (when present)
3466 var defaultValue = getToStringValue(props.defaultValue);
3467 if (defaultValue != null) {
3468 node.defaultValue = toString(defaultValue);
3469 }
3470 } else {
3471 // Otherwise, the value attribute is synchronized to the property,
3472 // so we assign defaultValue to the same thing as the value property
3473 // assignment step above.
3474 node.defaultValue = _initialValue;
3475 }
3476 }
3477
3478 // Normally, we'd just do `node.checked = node.checked` upon initial mount, less this bug
3479 // this is needed to work around a chrome bug where setting defaultChecked
3480 // will sometimes influence the value of checked (even after detachment).
3481 // Reference: https://bugs.chromium.org/p/chromium/issues/detail?id=608416
3482 // We need to temporarily unset name to avoid disrupting radio button groups.
3483 var name = node.name;
3484 if (name !== '') {
3485 node.name = '';
3486 }
3487
3488 if (disableInputAttributeSyncing) {
3489 // When not syncing the checked attribute, the checked property
3490 // never gets assigned. It must be manually set. We don't want
3491 // to do this when hydrating so that existing user input isn't
3492 // modified
3493 if (!isHydrating) {
3494 updateChecked(element, props);
3495 }
3496
3497 // Only assign the checked attribute if it is defined. This saves
3498 // a DOM write when controlling the checked attribute isn't needed
3499 // (text inputs, submit/reset)
3500 if (props.hasOwnProperty('defaultChecked')) {
3501 node.defaultChecked = !node.defaultChecked;
3502 node.defaultChecked = !!props.defaultChecked;
3503 }
3504 } else {
3505 // When syncing the checked attribute, both the checked property and
3506 // attribute are assigned at the same time using defaultChecked. This uses:
3507 //
3508 // 1. The checked React property when present
3509 // 2. The defaultChecked React property when present
3510 // 3. Otherwise, false
3511 node.defaultChecked = !node.defaultChecked;
3512 node.defaultChecked = !!node._wrapperState.initialChecked;
3513 }
3514
3515 if (name !== '') {
3516 node.name = name;
3517 }
3518}
3519
3520function restoreControlledState(element, props) {
3521 var node = element;
3522 updateWrapper(node, props);
3523 updateNamedCousins(node, props);
3524}
3525
3526function updateNamedCousins(rootNode, props) {
3527 var name = props.name;
3528 if (props.type === 'radio' && name != null) {
3529 var queryRoot = rootNode;
3530
3531 while (queryRoot.parentNode) {
3532 queryRoot = queryRoot.parentNode;
3533 }
3534
3535 // If `rootNode.form` was non-null, then we could try `form.elements`,
3536 // but that sometimes behaves strangely in IE8. We could also try using
3537 // `form.getElementsByName`, but that will only return direct children
3538 // and won't include inputs that use the HTML5 `form=` attribute. Since
3539 // the input might not even be in a form. It might not even be in the
3540 // document. Let's just use the local `querySelectorAll` to ensure we don't
3541 // miss anything.
3542 var group = queryRoot.querySelectorAll('input[name=' + JSON.stringify('' + name) + '][type="radio"]');
3543
3544 for (var i = 0; i < group.length; i++) {
3545 var otherNode = group[i];
3546 if (otherNode === rootNode || otherNode.form !== rootNode.form) {
3547 continue;
3548 }
3549 // This will throw if radio buttons rendered by different copies of React
3550 // and the same name are rendered into the same form (same as #1939).
3551 // That's probably okay; we don't support it just as we don't support
3552 // mixing React radio buttons with non-React ones.
3553 var otherProps = getFiberCurrentPropsFromNode$1(otherNode);
3554 !otherProps ? invariant(false, 'ReactDOMInput: Mixing React and non-React radio inputs with the same `name` is not supported.') : void 0;
3555
3556 // We need update the tracked value on the named cousin since the value
3557 // was changed but the input saw no event or value set
3558 updateValueIfChanged(otherNode);
3559
3560 // If this is a controlled radio button group, forcing the input that
3561 // was previously checked to update will cause it to be come re-checked
3562 // as appropriate.
3563 updateWrapper(otherNode, otherProps);
3564 }
3565 }
3566}
3567
3568// In Chrome, assigning defaultValue to certain input types triggers input validation.
3569// For number inputs, the display value loses trailing decimal points. For email inputs,
3570// Chrome raises "The specified value <x> is not a valid email address".
3571//
3572// Here we check to see if the defaultValue has actually changed, avoiding these problems
3573// when the user is inputting text
3574//
3575// https://github.com/facebook/react/issues/7253
3576function setDefaultValue(node, type, value) {
3577 if (
3578 // Focused number inputs synchronize on blur. See ChangeEventPlugin.js
3579 type !== 'number' || node.ownerDocument.activeElement !== node) {
3580 if (value == null) {
3581 node.defaultValue = toString(node._wrapperState.initialValue);
3582 } else if (node.defaultValue !== toString(value)) {
3583 node.defaultValue = toString(value);
3584 }
3585 }
3586}
3587
3588var eventTypes$1 = {
3589 change: {
3590 phasedRegistrationNames: {
3591 bubbled: 'onChange',
3592 captured: 'onChangeCapture'
3593 },
3594 dependencies: [TOP_BLUR, TOP_CHANGE, TOP_CLICK, TOP_FOCUS, TOP_INPUT, TOP_KEY_DOWN, TOP_KEY_UP, TOP_SELECTION_CHANGE]
3595 }
3596};
3597
3598function createAndAccumulateChangeEvent(inst, nativeEvent, target) {
3599 var event = SyntheticEvent.getPooled(eventTypes$1.change, inst, nativeEvent, target);
3600 event.type = 'change';
3601 // Flag this event loop as needing state restore.
3602 enqueueStateRestore(target);
3603 accumulateTwoPhaseDispatches(event);
3604 return event;
3605}
3606/**
3607 * For IE shims
3608 */
3609var activeElement = null;
3610var activeElementInst = null;
3611
3612/**
3613 * SECTION: handle `change` event
3614 */
3615function shouldUseChangeEvent(elem) {
3616 var nodeName = elem.nodeName && elem.nodeName.toLowerCase();
3617 return nodeName === 'select' || nodeName === 'input' && elem.type === 'file';
3618}
3619
3620function manualDispatchChangeEvent(nativeEvent) {
3621 var event = createAndAccumulateChangeEvent(activeElementInst, nativeEvent, getEventTarget(nativeEvent));
3622
3623 // If change and propertychange bubbled, we'd just bind to it like all the
3624 // other events and have it go through ReactBrowserEventEmitter. Since it
3625 // doesn't, we manually listen for the events and so we have to enqueue and
3626 // process the abstract event manually.
3627 //
3628 // Batching is necessary here in order to ensure that all event handlers run
3629 // before the next rerender (including event handlers attached to ancestor
3630 // elements instead of directly on the input). Without this, controlled
3631 // components don't work properly in conjunction with event bubbling because
3632 // the component is rerendered and the value reverted before all the event
3633 // handlers can run. See https://github.com/facebook/react/issues/708.
3634 batchedUpdates(runEventInBatch, event);
3635}
3636
3637function runEventInBatch(event) {
3638 runEventsInBatch(event);
3639}
3640
3641function getInstIfValueChanged(targetInst) {
3642 var targetNode = getNodeFromInstance$1(targetInst);
3643 if (updateValueIfChanged(targetNode)) {
3644 return targetInst;
3645 }
3646}
3647
3648function getTargetInstForChangeEvent(topLevelType, targetInst) {
3649 if (topLevelType === TOP_CHANGE) {
3650 return targetInst;
3651 }
3652}
3653
3654/**
3655 * SECTION: handle `input` event
3656 */
3657var isInputEventSupported = false;
3658if (canUseDOM) {
3659 // IE9 claims to support the input event but fails to trigger it when
3660 // deleting text, so we ignore its input events.
3661 isInputEventSupported = isEventSupported('input') && (!document.documentMode || document.documentMode > 9);
3662}
3663
3664/**
3665 * (For IE <=9) Starts tracking propertychange events on the passed-in element
3666 * and override the value property so that we can distinguish user events from
3667 * value changes in JS.
3668 */
3669function startWatchingForValueChange(target, targetInst) {
3670 activeElement = target;
3671 activeElementInst = targetInst;
3672 activeElement.attachEvent('onpropertychange', handlePropertyChange);
3673}
3674
3675/**
3676 * (For IE <=9) Removes the event listeners from the currently-tracked element,
3677 * if any exists.
3678 */
3679function stopWatchingForValueChange() {
3680 if (!activeElement) {
3681 return;
3682 }
3683 activeElement.detachEvent('onpropertychange', handlePropertyChange);
3684 activeElement = null;
3685 activeElementInst = null;
3686}
3687
3688/**
3689 * (For IE <=9) Handles a propertychange event, sending a `change` event if
3690 * the value of the active element has changed.
3691 */
3692function handlePropertyChange(nativeEvent) {
3693 if (nativeEvent.propertyName !== 'value') {
3694 return;
3695 }
3696 if (getInstIfValueChanged(activeElementInst)) {
3697 manualDispatchChangeEvent(nativeEvent);
3698 }
3699}
3700
3701function handleEventsForInputEventPolyfill(topLevelType, target, targetInst) {
3702 if (topLevelType === TOP_FOCUS) {
3703 // In IE9, propertychange fires for most input events but is buggy and
3704 // doesn't fire when text is deleted, but conveniently, selectionchange
3705 // appears to fire in all of the remaining cases so we catch those and
3706 // forward the event if the value has changed
3707 // In either case, we don't want to call the event handler if the value
3708 // is changed from JS so we redefine a setter for `.value` that updates
3709 // our activeElementValue variable, allowing us to ignore those changes
3710 //
3711 // stopWatching() should be a noop here but we call it just in case we
3712 // missed a blur event somehow.
3713 stopWatchingForValueChange();
3714 startWatchingForValueChange(target, targetInst);
3715 } else if (topLevelType === TOP_BLUR) {
3716 stopWatchingForValueChange();
3717 }
3718}
3719
3720// For IE8 and IE9.
3721function getTargetInstForInputEventPolyfill(topLevelType, targetInst) {
3722 if (topLevelType === TOP_SELECTION_CHANGE || topLevelType === TOP_KEY_UP || topLevelType === TOP_KEY_DOWN) {
3723 // On the selectionchange event, the target is just document which isn't
3724 // helpful for us so just check activeElement instead.
3725 //
3726 // 99% of the time, keydown and keyup aren't necessary. IE8 fails to fire
3727 // propertychange on the first input event after setting `value` from a
3728 // script and fires only keydown, keypress, keyup. Catching keyup usually
3729 // gets it and catching keydown lets us fire an event for the first
3730 // keystroke if user does a key repeat (it'll be a little delayed: right
3731 // before the second keystroke). Other input methods (e.g., paste) seem to
3732 // fire selectionchange normally.
3733 return getInstIfValueChanged(activeElementInst);
3734 }
3735}
3736
3737/**
3738 * SECTION: handle `click` event
3739 */
3740function shouldUseClickEvent(elem) {
3741 // Use the `click` event to detect changes to checkbox and radio inputs.
3742 // This approach works across all browsers, whereas `change` does not fire
3743 // until `blur` in IE8.
3744 var nodeName = elem.nodeName;
3745 return nodeName && nodeName.toLowerCase() === 'input' && (elem.type === 'checkbox' || elem.type === 'radio');
3746}
3747
3748function getTargetInstForClickEvent(topLevelType, targetInst) {
3749 if (topLevelType === TOP_CLICK) {
3750 return getInstIfValueChanged(targetInst);
3751 }
3752}
3753
3754function getTargetInstForInputOrChangeEvent(topLevelType, targetInst) {
3755 if (topLevelType === TOP_INPUT || topLevelType === TOP_CHANGE) {
3756 return getInstIfValueChanged(targetInst);
3757 }
3758}
3759
3760function handleControlledInputBlur(node) {
3761 var state = node._wrapperState;
3762
3763 if (!state || !state.controlled || node.type !== 'number') {
3764 return;
3765 }
3766
3767 if (!disableInputAttributeSyncing) {
3768 // If controlled, assign the value attribute to the current value on blur
3769 setDefaultValue(node, 'number', node.value);
3770 }
3771}
3772
3773/**
3774 * This plugin creates an `onChange` event that normalizes change events
3775 * across form elements. This event fires at a time when it's possible to
3776 * change the element's value without seeing a flicker.
3777 *
3778 * Supported elements are:
3779 * - input (see `isTextInputElement`)
3780 * - textarea
3781 * - select
3782 */
3783var ChangeEventPlugin = {
3784 eventTypes: eventTypes$1,
3785
3786 _isInputEventSupported: isInputEventSupported,
3787
3788 extractEvents: function (topLevelType, targetInst, nativeEvent, nativeEventTarget) {
3789 var targetNode = targetInst ? getNodeFromInstance$1(targetInst) : window;
3790
3791 var getTargetInstFunc = void 0,
3792 handleEventFunc = void 0;
3793 if (shouldUseChangeEvent(targetNode)) {
3794 getTargetInstFunc = getTargetInstForChangeEvent;
3795 } else if (isTextInputElement(targetNode)) {
3796 if (isInputEventSupported) {
3797 getTargetInstFunc = getTargetInstForInputOrChangeEvent;
3798 } else {
3799 getTargetInstFunc = getTargetInstForInputEventPolyfill;
3800 handleEventFunc = handleEventsForInputEventPolyfill;
3801 }
3802 } else if (shouldUseClickEvent(targetNode)) {
3803 getTargetInstFunc = getTargetInstForClickEvent;
3804 }
3805
3806 if (getTargetInstFunc) {
3807 var inst = getTargetInstFunc(topLevelType, targetInst);
3808 if (inst) {
3809 var event = createAndAccumulateChangeEvent(inst, nativeEvent, nativeEventTarget);
3810 return event;
3811 }
3812 }
3813
3814 if (handleEventFunc) {
3815 handleEventFunc(topLevelType, targetNode, targetInst);
3816 }
3817
3818 // When blurring, set the value attribute for number inputs
3819 if (topLevelType === TOP_BLUR) {
3820 handleControlledInputBlur(targetNode);
3821 }
3822 }
3823};
3824
3825/**
3826 * Module that is injectable into `EventPluginHub`, that specifies a
3827 * deterministic ordering of `EventPlugin`s. A convenient way to reason about
3828 * plugins, without having to package every one of them. This is better than
3829 * having plugins be ordered in the same order that they are injected because
3830 * that ordering would be influenced by the packaging order.
3831 * `ResponderEventPlugin` must occur before `SimpleEventPlugin` so that
3832 * preventing default on events is convenient in `SimpleEventPlugin` handlers.
3833 */
3834var DOMEventPluginOrder = ['ResponderEventPlugin', 'SimpleEventPlugin', 'EnterLeaveEventPlugin', 'ChangeEventPlugin', 'SelectEventPlugin', 'BeforeInputEventPlugin'];
3835
3836var SyntheticUIEvent = SyntheticEvent.extend({
3837 view: null,
3838 detail: null
3839});
3840
3841var modifierKeyToProp = {
3842 Alt: 'altKey',
3843 Control: 'ctrlKey',
3844 Meta: 'metaKey',
3845 Shift: 'shiftKey'
3846};
3847
3848// Older browsers (Safari <= 10, iOS Safari <= 10.2) do not support
3849// getModifierState. If getModifierState is not supported, we map it to a set of
3850// modifier keys exposed by the event. In this case, Lock-keys are not supported.
3851/**
3852 * Translation from modifier key to the associated property in the event.
3853 * @see http://www.w3.org/TR/DOM-Level-3-Events/#keys-Modifiers
3854 */
3855
3856function modifierStateGetter(keyArg) {
3857 var syntheticEvent = this;
3858 var nativeEvent = syntheticEvent.nativeEvent;
3859 if (nativeEvent.getModifierState) {
3860 return nativeEvent.getModifierState(keyArg);
3861 }
3862 var keyProp = modifierKeyToProp[keyArg];
3863 return keyProp ? !!nativeEvent[keyProp] : false;
3864}
3865
3866function getEventModifierState(nativeEvent) {
3867 return modifierStateGetter;
3868}
3869
3870var previousScreenX = 0;
3871var previousScreenY = 0;
3872// Use flags to signal movementX/Y has already been set
3873var isMovementXSet = false;
3874var isMovementYSet = false;
3875
3876/**
3877 * @interface MouseEvent
3878 * @see http://www.w3.org/TR/DOM-Level-3-Events/
3879 */
3880var SyntheticMouseEvent = SyntheticUIEvent.extend({
3881 screenX: null,
3882 screenY: null,
3883 clientX: null,
3884 clientY: null,
3885 pageX: null,
3886 pageY: null,
3887 ctrlKey: null,
3888 shiftKey: null,
3889 altKey: null,
3890 metaKey: null,
3891 getModifierState: getEventModifierState,
3892 button: null,
3893 buttons: null,
3894 relatedTarget: function (event) {
3895 return event.relatedTarget || (event.fromElement === event.srcElement ? event.toElement : event.fromElement);
3896 },
3897 movementX: function (event) {
3898 if ('movementX' in event) {
3899 return event.movementX;
3900 }
3901
3902 var screenX = previousScreenX;
3903 previousScreenX = event.screenX;
3904
3905 if (!isMovementXSet) {
3906 isMovementXSet = true;
3907 return 0;
3908 }
3909
3910 return event.type === 'mousemove' ? event.screenX - screenX : 0;
3911 },
3912 movementY: function (event) {
3913 if ('movementY' in event) {
3914 return event.movementY;
3915 }
3916
3917 var screenY = previousScreenY;
3918 previousScreenY = event.screenY;
3919
3920 if (!isMovementYSet) {
3921 isMovementYSet = true;
3922 return 0;
3923 }
3924
3925 return event.type === 'mousemove' ? event.screenY - screenY : 0;
3926 }
3927});
3928
3929/**
3930 * @interface PointerEvent
3931 * @see http://www.w3.org/TR/pointerevents/
3932 */
3933var SyntheticPointerEvent = SyntheticMouseEvent.extend({
3934 pointerId: null,
3935 width: null,
3936 height: null,
3937 pressure: null,
3938 tangentialPressure: null,
3939 tiltX: null,
3940 tiltY: null,
3941 twist: null,
3942 pointerType: null,
3943 isPrimary: null
3944});
3945
3946var eventTypes$2 = {
3947 mouseEnter: {
3948 registrationName: 'onMouseEnter',
3949 dependencies: [TOP_MOUSE_OUT, TOP_MOUSE_OVER]
3950 },
3951 mouseLeave: {
3952 registrationName: 'onMouseLeave',
3953 dependencies: [TOP_MOUSE_OUT, TOP_MOUSE_OVER]
3954 },
3955 pointerEnter: {
3956 registrationName: 'onPointerEnter',
3957 dependencies: [TOP_POINTER_OUT, TOP_POINTER_OVER]
3958 },
3959 pointerLeave: {
3960 registrationName: 'onPointerLeave',
3961 dependencies: [TOP_POINTER_OUT, TOP_POINTER_OVER]
3962 }
3963};
3964
3965var EnterLeaveEventPlugin = {
3966 eventTypes: eventTypes$2,
3967
3968 /**
3969 * For almost every interaction we care about, there will be both a top-level
3970 * `mouseover` and `mouseout` event that occurs. Only use `mouseout` so that
3971 * we do not extract duplicate events. However, moving the mouse into the
3972 * browser from outside will not fire a `mouseout` event. In this case, we use
3973 * the `mouseover` top-level event.
3974 */
3975 extractEvents: function (topLevelType, targetInst, nativeEvent, nativeEventTarget) {
3976 var isOverEvent = topLevelType === TOP_MOUSE_OVER || topLevelType === TOP_POINTER_OVER;
3977 var isOutEvent = topLevelType === TOP_MOUSE_OUT || topLevelType === TOP_POINTER_OUT;
3978
3979 if (isOverEvent && (nativeEvent.relatedTarget || nativeEvent.fromElement)) {
3980 return null;
3981 }
3982
3983 if (!isOutEvent && !isOverEvent) {
3984 // Must not be a mouse or pointer in or out - ignoring.
3985 return null;
3986 }
3987
3988 var win = void 0;
3989 if (nativeEventTarget.window === nativeEventTarget) {
3990 // `nativeEventTarget` is probably a window object.
3991 win = nativeEventTarget;
3992 } else {
3993 // TODO: Figure out why `ownerDocument` is sometimes undefined in IE8.
3994 var doc = nativeEventTarget.ownerDocument;
3995 if (doc) {
3996 win = doc.defaultView || doc.parentWindow;
3997 } else {
3998 win = window;
3999 }
4000 }
4001
4002 var from = void 0;
4003 var to = void 0;
4004 if (isOutEvent) {
4005 from = targetInst;
4006 var related = nativeEvent.relatedTarget || nativeEvent.toElement;
4007 to = related ? getClosestInstanceFromNode(related) : null;
4008 } else {
4009 // Moving to a node from outside the window.
4010 from = null;
4011 to = targetInst;
4012 }
4013
4014 if (from === to) {
4015 // Nothing pertains to our managed components.
4016 return null;
4017 }
4018
4019 var eventInterface = void 0,
4020 leaveEventType = void 0,
4021 enterEventType = void 0,
4022 eventTypePrefix = void 0;
4023
4024 if (topLevelType === TOP_MOUSE_OUT || topLevelType === TOP_MOUSE_OVER) {
4025 eventInterface = SyntheticMouseEvent;
4026 leaveEventType = eventTypes$2.mouseLeave;
4027 enterEventType = eventTypes$2.mouseEnter;
4028 eventTypePrefix = 'mouse';
4029 } else if (topLevelType === TOP_POINTER_OUT || topLevelType === TOP_POINTER_OVER) {
4030 eventInterface = SyntheticPointerEvent;
4031 leaveEventType = eventTypes$2.pointerLeave;
4032 enterEventType = eventTypes$2.pointerEnter;
4033 eventTypePrefix = 'pointer';
4034 }
4035
4036 var fromNode = from == null ? win : getNodeFromInstance$1(from);
4037 var toNode = to == null ? win : getNodeFromInstance$1(to);
4038
4039 var leave = eventInterface.getPooled(leaveEventType, from, nativeEvent, nativeEventTarget);
4040 leave.type = eventTypePrefix + 'leave';
4041 leave.target = fromNode;
4042 leave.relatedTarget = toNode;
4043
4044 var enter = eventInterface.getPooled(enterEventType, to, nativeEvent, nativeEventTarget);
4045 enter.type = eventTypePrefix + 'enter';
4046 enter.target = toNode;
4047 enter.relatedTarget = fromNode;
4048
4049 accumulateEnterLeaveDispatches(leave, enter, from, to);
4050
4051 return [leave, enter];
4052 }
4053};
4054
4055/**
4056 * inlined Object.is polyfill to avoid requiring consumers ship their own
4057 * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is
4058 */
4059function is(x, y) {
4060 return x === y && (x !== 0 || 1 / x === 1 / y) || x !== x && y !== y // eslint-disable-line no-self-compare
4061 ;
4062}
4063
4064var hasOwnProperty$1 = Object.prototype.hasOwnProperty;
4065
4066/**
4067 * Performs equality by iterating through keys on an object and returning false
4068 * when any key has values which are not strictly equal between the arguments.
4069 * Returns true when the values of all keys are strictly equal.
4070 */
4071function shallowEqual(objA, objB) {
4072 if (is(objA, objB)) {
4073 return true;
4074 }
4075
4076 if (typeof objA !== 'object' || objA === null || typeof objB !== 'object' || objB === null) {
4077 return false;
4078 }
4079
4080 var keysA = Object.keys(objA);
4081 var keysB = Object.keys(objB);
4082
4083 if (keysA.length !== keysB.length) {
4084 return false;
4085 }
4086
4087 // Test for A's keys different from B.
4088 for (var i = 0; i < keysA.length; i++) {
4089 if (!hasOwnProperty$1.call(objB, keysA[i]) || !is(objA[keysA[i]], objB[keysA[i]])) {
4090 return false;
4091 }
4092 }
4093
4094 return true;
4095}
4096
4097/**
4098 * `ReactInstanceMap` maintains a mapping from a public facing stateful
4099 * instance (key) and the internal representation (value). This allows public
4100 * methods to accept the user facing instance as an argument and map them back
4101 * to internal methods.
4102 *
4103 * Note that this module is currently shared and assumed to be stateless.
4104 * If this becomes an actual Map, that will break.
4105 */
4106
4107/**
4108 * This API should be called `delete` but we'd have to make sure to always
4109 * transform these to strings for IE support. When this transform is fully
4110 * supported we can rename it.
4111 */
4112
4113
4114function get(key) {
4115 return key._reactInternalFiber;
4116}
4117
4118function has(key) {
4119 return key._reactInternalFiber !== undefined;
4120}
4121
4122function set(key, value) {
4123 key._reactInternalFiber = value;
4124}
4125
4126// Don't change these two values. They're used by React Dev Tools.
4127var NoEffect = /* */0;
4128var PerformedWork = /* */1;
4129
4130// You can change the rest (and add more).
4131var Placement = /* */2;
4132var Update = /* */4;
4133var PlacementAndUpdate = /* */6;
4134var Deletion = /* */8;
4135var ContentReset = /* */16;
4136var Callback = /* */32;
4137var DidCapture = /* */64;
4138var Ref = /* */128;
4139var Snapshot = /* */256;
4140var Passive = /* */512;
4141
4142// Passive & Update & Callback & Ref & Snapshot
4143var LifecycleEffectMask = /* */932;
4144
4145// Union of all host effects
4146var HostEffectMask = /* */1023;
4147
4148var Incomplete = /* */1024;
4149var ShouldCapture = /* */2048;
4150
4151var ReactCurrentOwner$1 = ReactSharedInternals.ReactCurrentOwner;
4152
4153var MOUNTING = 1;
4154var MOUNTED = 2;
4155var UNMOUNTED = 3;
4156
4157function isFiberMountedImpl(fiber) {
4158 var node = fiber;
4159 if (!fiber.alternate) {
4160 // If there is no alternate, this might be a new tree that isn't inserted
4161 // yet. If it is, then it will have a pending insertion effect on it.
4162 if ((node.effectTag & Placement) !== NoEffect) {
4163 return MOUNTING;
4164 }
4165 while (node.return) {
4166 node = node.return;
4167 if ((node.effectTag & Placement) !== NoEffect) {
4168 return MOUNTING;
4169 }
4170 }
4171 } else {
4172 while (node.return) {
4173 node = node.return;
4174 }
4175 }
4176 if (node.tag === HostRoot) {
4177 // TODO: Check if this was a nested HostRoot when used with
4178 // renderContainerIntoSubtree.
4179 return MOUNTED;
4180 }
4181 // If we didn't hit the root, that means that we're in an disconnected tree
4182 // that has been unmounted.
4183 return UNMOUNTED;
4184}
4185
4186function isFiberMounted(fiber) {
4187 return isFiberMountedImpl(fiber) === MOUNTED;
4188}
4189
4190function isMounted(component) {
4191 {
4192 var owner = ReactCurrentOwner$1.current;
4193 if (owner !== null && owner.tag === ClassComponent) {
4194 var ownerFiber = owner;
4195 var instance = ownerFiber.stateNode;
4196 !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;
4197 instance._warnedAboutRefsInRender = true;
4198 }
4199 }
4200
4201 var fiber = get(component);
4202 if (!fiber) {
4203 return false;
4204 }
4205 return isFiberMountedImpl(fiber) === MOUNTED;
4206}
4207
4208function assertIsMounted(fiber) {
4209 !(isFiberMountedImpl(fiber) === MOUNTED) ? invariant(false, 'Unable to find node on an unmounted component.') : void 0;
4210}
4211
4212function findCurrentFiberUsingSlowPath(fiber) {
4213 var alternate = fiber.alternate;
4214 if (!alternate) {
4215 // If there is no alternate, then we only need to check if it is mounted.
4216 var state = isFiberMountedImpl(fiber);
4217 !(state !== UNMOUNTED) ? invariant(false, 'Unable to find node on an unmounted component.') : void 0;
4218 if (state === MOUNTING) {
4219 return null;
4220 }
4221 return fiber;
4222 }
4223 // If we have two possible branches, we'll walk backwards up to the root
4224 // to see what path the root points to. On the way we may hit one of the
4225 // special cases and we'll deal with them.
4226 var a = fiber;
4227 var b = alternate;
4228 while (true) {
4229 var parentA = a.return;
4230 var parentB = parentA ? parentA.alternate : null;
4231 if (!parentA || !parentB) {
4232 // We're at the root.
4233 break;
4234 }
4235
4236 // If both copies of the parent fiber point to the same child, we can
4237 // assume that the child is current. This happens when we bailout on low
4238 // priority: the bailed out fiber's child reuses the current child.
4239 if (parentA.child === parentB.child) {
4240 var child = parentA.child;
4241 while (child) {
4242 if (child === a) {
4243 // We've determined that A is the current branch.
4244 assertIsMounted(parentA);
4245 return fiber;
4246 }
4247 if (child === b) {
4248 // We've determined that B is the current branch.
4249 assertIsMounted(parentA);
4250 return alternate;
4251 }
4252 child = child.sibling;
4253 }
4254 // We should never have an alternate for any mounting node. So the only
4255 // way this could possibly happen is if this was unmounted, if at all.
4256 invariant(false, 'Unable to find node on an unmounted component.');
4257 }
4258
4259 if (a.return !== b.return) {
4260 // The return pointer of A and the return pointer of B point to different
4261 // fibers. We assume that return pointers never criss-cross, so A must
4262 // belong to the child set of A.return, and B must belong to the child
4263 // set of B.return.
4264 a = parentA;
4265 b = parentB;
4266 } else {
4267 // The return pointers point to the same fiber. We'll have to use the
4268 // default, slow path: scan the child sets of each parent alternate to see
4269 // which child belongs to which set.
4270 //
4271 // Search parent A's child set
4272 var didFindChild = false;
4273 var _child = parentA.child;
4274 while (_child) {
4275 if (_child === a) {
4276 didFindChild = true;
4277 a = parentA;
4278 b = parentB;
4279 break;
4280 }
4281 if (_child === b) {
4282 didFindChild = true;
4283 b = parentA;
4284 a = parentB;
4285 break;
4286 }
4287 _child = _child.sibling;
4288 }
4289 if (!didFindChild) {
4290 // Search parent B's child set
4291 _child = parentB.child;
4292 while (_child) {
4293 if (_child === a) {
4294 didFindChild = true;
4295 a = parentB;
4296 b = parentA;
4297 break;
4298 }
4299 if (_child === b) {
4300 didFindChild = true;
4301 b = parentB;
4302 a = parentA;
4303 break;
4304 }
4305 _child = _child.sibling;
4306 }
4307 !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;
4308 }
4309 }
4310
4311 !(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;
4312 }
4313 // If the root is not a host container, we're in a disconnected tree. I.e.
4314 // unmounted.
4315 !(a.tag === HostRoot) ? invariant(false, 'Unable to find node on an unmounted component.') : void 0;
4316 if (a.stateNode.current === a) {
4317 // We've determined that A is the current branch.
4318 return fiber;
4319 }
4320 // Otherwise B has to be current branch.
4321 return alternate;
4322}
4323
4324function findCurrentHostFiber(parent) {
4325 var currentParent = findCurrentFiberUsingSlowPath(parent);
4326 if (!currentParent) {
4327 return null;
4328 }
4329
4330 // Next we'll drill down this component to find the first HostComponent/Text.
4331 var node = currentParent;
4332 while (true) {
4333 if (node.tag === HostComponent || node.tag === HostText) {
4334 return node;
4335 } else if (node.child) {
4336 node.child.return = node;
4337 node = node.child;
4338 continue;
4339 }
4340 if (node === currentParent) {
4341 return null;
4342 }
4343 while (!node.sibling) {
4344 if (!node.return || node.return === currentParent) {
4345 return null;
4346 }
4347 node = node.return;
4348 }
4349 node.sibling.return = node.return;
4350 node = node.sibling;
4351 }
4352 // Flow needs the return null here, but ESLint complains about it.
4353 // eslint-disable-next-line no-unreachable
4354 return null;
4355}
4356
4357function findCurrentHostFiberWithNoPortals(parent) {
4358 var currentParent = findCurrentFiberUsingSlowPath(parent);
4359 if (!currentParent) {
4360 return null;
4361 }
4362
4363 // Next we'll drill down this component to find the first HostComponent/Text.
4364 var node = currentParent;
4365 while (true) {
4366 if (node.tag === HostComponent || node.tag === HostText) {
4367 return node;
4368 } else if (node.child && node.tag !== HostPortal) {
4369 node.child.return = node;
4370 node = node.child;
4371 continue;
4372 }
4373 if (node === currentParent) {
4374 return null;
4375 }
4376 while (!node.sibling) {
4377 if (!node.return || node.return === currentParent) {
4378 return null;
4379 }
4380 node = node.return;
4381 }
4382 node.sibling.return = node.return;
4383 node = node.sibling;
4384 }
4385 // Flow needs the return null here, but ESLint complains about it.
4386 // eslint-disable-next-line no-unreachable
4387 return null;
4388}
4389
4390function addEventBubbleListener(element, eventType, listener) {
4391 element.addEventListener(eventType, listener, false);
4392}
4393
4394function addEventCaptureListener(element, eventType, listener) {
4395 element.addEventListener(eventType, listener, true);
4396}
4397
4398/**
4399 * @interface Event
4400 * @see http://www.w3.org/TR/css3-animations/#AnimationEvent-interface
4401 * @see https://developer.mozilla.org/en-US/docs/Web/API/AnimationEvent
4402 */
4403var SyntheticAnimationEvent = SyntheticEvent.extend({
4404 animationName: null,
4405 elapsedTime: null,
4406 pseudoElement: null
4407});
4408
4409/**
4410 * @interface Event
4411 * @see http://www.w3.org/TR/clipboard-apis/
4412 */
4413var SyntheticClipboardEvent = SyntheticEvent.extend({
4414 clipboardData: function (event) {
4415 return 'clipboardData' in event ? event.clipboardData : window.clipboardData;
4416 }
4417});
4418
4419/**
4420 * @interface FocusEvent
4421 * @see http://www.w3.org/TR/DOM-Level-3-Events/
4422 */
4423var SyntheticFocusEvent = SyntheticUIEvent.extend({
4424 relatedTarget: null
4425});
4426
4427/**
4428 * `charCode` represents the actual "character code" and is safe to use with
4429 * `String.fromCharCode`. As such, only keys that correspond to printable
4430 * characters produce a valid `charCode`, the only exception to this is Enter.
4431 * The Tab-key is considered non-printable and does not have a `charCode`,
4432 * presumably because it does not produce a tab-character in browsers.
4433 *
4434 * @param {object} nativeEvent Native browser event.
4435 * @return {number} Normalized `charCode` property.
4436 */
4437function getEventCharCode(nativeEvent) {
4438 var charCode = void 0;
4439 var keyCode = nativeEvent.keyCode;
4440
4441 if ('charCode' in nativeEvent) {
4442 charCode = nativeEvent.charCode;
4443
4444 // FF does not set `charCode` for the Enter-key, check against `keyCode`.
4445 if (charCode === 0 && keyCode === 13) {
4446 charCode = 13;
4447 }
4448 } else {
4449 // IE8 does not implement `charCode`, but `keyCode` has the correct value.
4450 charCode = keyCode;
4451 }
4452
4453 // IE and Edge (on Windows) and Chrome / Safari (on Windows and Linux)
4454 // report Enter as charCode 10 when ctrl is pressed.
4455 if (charCode === 10) {
4456 charCode = 13;
4457 }
4458
4459 // Some non-printable keys are reported in `charCode`/`keyCode`, discard them.
4460 // Must not discard the (non-)printable Enter-key.
4461 if (charCode >= 32 || charCode === 13) {
4462 return charCode;
4463 }
4464
4465 return 0;
4466}
4467
4468/**
4469 * Normalization of deprecated HTML5 `key` values
4470 * @see https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent#Key_names
4471 */
4472var normalizeKey = {
4473 Esc: 'Escape',
4474 Spacebar: ' ',
4475 Left: 'ArrowLeft',
4476 Up: 'ArrowUp',
4477 Right: 'ArrowRight',
4478 Down: 'ArrowDown',
4479 Del: 'Delete',
4480 Win: 'OS',
4481 Menu: 'ContextMenu',
4482 Apps: 'ContextMenu',
4483 Scroll: 'ScrollLock',
4484 MozPrintableKey: 'Unidentified'
4485};
4486
4487/**
4488 * Translation from legacy `keyCode` to HTML5 `key`
4489 * Only special keys supported, all others depend on keyboard layout or browser
4490 * @see https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent#Key_names
4491 */
4492var translateToKey = {
4493 '8': 'Backspace',
4494 '9': 'Tab',
4495 '12': 'Clear',
4496 '13': 'Enter',
4497 '16': 'Shift',
4498 '17': 'Control',
4499 '18': 'Alt',
4500 '19': 'Pause',
4501 '20': 'CapsLock',
4502 '27': 'Escape',
4503 '32': ' ',
4504 '33': 'PageUp',
4505 '34': 'PageDown',
4506 '35': 'End',
4507 '36': 'Home',
4508 '37': 'ArrowLeft',
4509 '38': 'ArrowUp',
4510 '39': 'ArrowRight',
4511 '40': 'ArrowDown',
4512 '45': 'Insert',
4513 '46': 'Delete',
4514 '112': 'F1',
4515 '113': 'F2',
4516 '114': 'F3',
4517 '115': 'F4',
4518 '116': 'F5',
4519 '117': 'F6',
4520 '118': 'F7',
4521 '119': 'F8',
4522 '120': 'F9',
4523 '121': 'F10',
4524 '122': 'F11',
4525 '123': 'F12',
4526 '144': 'NumLock',
4527 '145': 'ScrollLock',
4528 '224': 'Meta'
4529};
4530
4531/**
4532 * @param {object} nativeEvent Native browser event.
4533 * @return {string} Normalized `key` property.
4534 */
4535function getEventKey(nativeEvent) {
4536 if (nativeEvent.key) {
4537 // Normalize inconsistent values reported by browsers due to
4538 // implementations of a working draft specification.
4539
4540 // FireFox implements `key` but returns `MozPrintableKey` for all
4541 // printable characters (normalized to `Unidentified`), ignore it.
4542 var key = normalizeKey[nativeEvent.key] || nativeEvent.key;
4543 if (key !== 'Unidentified') {
4544 return key;
4545 }
4546 }
4547
4548 // Browser does not implement `key`, polyfill as much of it as we can.
4549 if (nativeEvent.type === 'keypress') {
4550 var charCode = getEventCharCode(nativeEvent);
4551
4552 // The enter-key is technically both printable and non-printable and can
4553 // thus be captured by `keypress`, no other non-printable key should.
4554 return charCode === 13 ? 'Enter' : String.fromCharCode(charCode);
4555 }
4556 if (nativeEvent.type === 'keydown' || nativeEvent.type === 'keyup') {
4557 // While user keyboard layout determines the actual meaning of each
4558 // `keyCode` value, almost all function keys have a universal value.
4559 return translateToKey[nativeEvent.keyCode] || 'Unidentified';
4560 }
4561 return '';
4562}
4563
4564/**
4565 * @interface KeyboardEvent
4566 * @see http://www.w3.org/TR/DOM-Level-3-Events/
4567 */
4568var SyntheticKeyboardEvent = SyntheticUIEvent.extend({
4569 key: getEventKey,
4570 location: null,
4571 ctrlKey: null,
4572 shiftKey: null,
4573 altKey: null,
4574 metaKey: null,
4575 repeat: null,
4576 locale: null,
4577 getModifierState: getEventModifierState,
4578 // Legacy Interface
4579 charCode: function (event) {
4580 // `charCode` is the result of a KeyPress event and represents the value of
4581 // the actual printable character.
4582
4583 // KeyPress is deprecated, but its replacement is not yet final and not
4584 // implemented in any major browser. Only KeyPress has charCode.
4585 if (event.type === 'keypress') {
4586 return getEventCharCode(event);
4587 }
4588 return 0;
4589 },
4590 keyCode: function (event) {
4591 // `keyCode` is the result of a KeyDown/Up event and represents the value of
4592 // physical keyboard key.
4593
4594 // The actual meaning of the value depends on the users' keyboard layout
4595 // which cannot be detected. Assuming that it is a US keyboard layout
4596 // provides a surprisingly accurate mapping for US and European users.
4597 // Due to this, it is left to the user to implement at this time.
4598 if (event.type === 'keydown' || event.type === 'keyup') {
4599 return event.keyCode;
4600 }
4601 return 0;
4602 },
4603 which: function (event) {
4604 // `which` is an alias for either `keyCode` or `charCode` depending on the
4605 // type of the event.
4606 if (event.type === 'keypress') {
4607 return getEventCharCode(event);
4608 }
4609 if (event.type === 'keydown' || event.type === 'keyup') {
4610 return event.keyCode;
4611 }
4612 return 0;
4613 }
4614});
4615
4616/**
4617 * @interface DragEvent
4618 * @see http://www.w3.org/TR/DOM-Level-3-Events/
4619 */
4620var SyntheticDragEvent = SyntheticMouseEvent.extend({
4621 dataTransfer: null
4622});
4623
4624/**
4625 * @interface TouchEvent
4626 * @see http://www.w3.org/TR/touch-events/
4627 */
4628var SyntheticTouchEvent = SyntheticUIEvent.extend({
4629 touches: null,
4630 targetTouches: null,
4631 changedTouches: null,
4632 altKey: null,
4633 metaKey: null,
4634 ctrlKey: null,
4635 shiftKey: null,
4636 getModifierState: getEventModifierState
4637});
4638
4639/**
4640 * @interface Event
4641 * @see http://www.w3.org/TR/2009/WD-css3-transitions-20090320/#transition-events-
4642 * @see https://developer.mozilla.org/en-US/docs/Web/API/TransitionEvent
4643 */
4644var SyntheticTransitionEvent = SyntheticEvent.extend({
4645 propertyName: null,
4646 elapsedTime: null,
4647 pseudoElement: null
4648});
4649
4650/**
4651 * @interface WheelEvent
4652 * @see http://www.w3.org/TR/DOM-Level-3-Events/
4653 */
4654var SyntheticWheelEvent = SyntheticMouseEvent.extend({
4655 deltaX: function (event) {
4656 return 'deltaX' in event ? event.deltaX : // Fallback to `wheelDeltaX` for Webkit and normalize (right is positive).
4657 'wheelDeltaX' in event ? -event.wheelDeltaX : 0;
4658 },
4659 deltaY: function (event) {
4660 return 'deltaY' in event ? event.deltaY : // Fallback to `wheelDeltaY` for Webkit and normalize (down is positive).
4661 'wheelDeltaY' in event ? -event.wheelDeltaY : // Fallback to `wheelDelta` for IE<9 and normalize (down is positive).
4662 'wheelDelta' in event ? -event.wheelDelta : 0;
4663 },
4664
4665 deltaZ: null,
4666
4667 // Browsers without "deltaMode" is reporting in raw wheel delta where one
4668 // notch on the scroll is always +/- 120, roughly equivalent to pixels.
4669 // A good approximation of DOM_DELTA_LINE (1) is 5% of viewport size or
4670 // ~40 pixels, for DOM_DELTA_SCREEN (2) it is 87.5% of viewport size.
4671 deltaMode: null
4672});
4673
4674/**
4675 * Turns
4676 * ['abort', ...]
4677 * into
4678 * eventTypes = {
4679 * 'abort': {
4680 * phasedRegistrationNames: {
4681 * bubbled: 'onAbort',
4682 * captured: 'onAbortCapture',
4683 * },
4684 * dependencies: [TOP_ABORT],
4685 * },
4686 * ...
4687 * };
4688 * topLevelEventsToDispatchConfig = new Map([
4689 * [TOP_ABORT, { sameConfig }],
4690 * ]);
4691 */
4692
4693var 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']];
4694var 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']];
4695
4696var eventTypes$4 = {};
4697var topLevelEventsToDispatchConfig = {};
4698
4699function addEventTypeNameToConfig(_ref, isInteractive) {
4700 var topEvent = _ref[0],
4701 event = _ref[1];
4702
4703 var capitalizedEvent = event[0].toUpperCase() + event.slice(1);
4704 var onEvent = 'on' + capitalizedEvent;
4705
4706 var type = {
4707 phasedRegistrationNames: {
4708 bubbled: onEvent,
4709 captured: onEvent + 'Capture'
4710 },
4711 dependencies: [topEvent],
4712 isInteractive: isInteractive
4713 };
4714 eventTypes$4[event] = type;
4715 topLevelEventsToDispatchConfig[topEvent] = type;
4716}
4717
4718interactiveEventTypeNames.forEach(function (eventTuple) {
4719 addEventTypeNameToConfig(eventTuple, true);
4720});
4721nonInteractiveEventTypeNames.forEach(function (eventTuple) {
4722 addEventTypeNameToConfig(eventTuple, false);
4723});
4724
4725// Only used in DEV for exhaustiveness validation.
4726var 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];
4727
4728var SimpleEventPlugin = {
4729 eventTypes: eventTypes$4,
4730
4731 isInteractiveTopLevelEventType: function (topLevelType) {
4732 var config = topLevelEventsToDispatchConfig[topLevelType];
4733 return config !== undefined && config.isInteractive === true;
4734 },
4735
4736
4737 extractEvents: function (topLevelType, targetInst, nativeEvent, nativeEventTarget) {
4738 var dispatchConfig = topLevelEventsToDispatchConfig[topLevelType];
4739 if (!dispatchConfig) {
4740 return null;
4741 }
4742 var EventConstructor = void 0;
4743 switch (topLevelType) {
4744 case TOP_KEY_PRESS:
4745 // Firefox creates a keypress event for function keys too. This removes
4746 // the unwanted keypress events. Enter is however both printable and
4747 // non-printable. One would expect Tab to be as well (but it isn't).
4748 if (getEventCharCode(nativeEvent) === 0) {
4749 return null;
4750 }
4751 /* falls through */
4752 case TOP_KEY_DOWN:
4753 case TOP_KEY_UP:
4754 EventConstructor = SyntheticKeyboardEvent;
4755 break;
4756 case TOP_BLUR:
4757 case TOP_FOCUS:
4758 EventConstructor = SyntheticFocusEvent;
4759 break;
4760 case TOP_CLICK:
4761 // Firefox creates a click event on right mouse clicks. This removes the
4762 // unwanted click events.
4763 if (nativeEvent.button === 2) {
4764 return null;
4765 }
4766 /* falls through */
4767 case TOP_AUX_CLICK:
4768 case TOP_DOUBLE_CLICK:
4769 case TOP_MOUSE_DOWN:
4770 case TOP_MOUSE_MOVE:
4771 case TOP_MOUSE_UP:
4772 // TODO: Disabled elements should not respond to mouse events
4773 /* falls through */
4774 case TOP_MOUSE_OUT:
4775 case TOP_MOUSE_OVER:
4776 case TOP_CONTEXT_MENU:
4777 EventConstructor = SyntheticMouseEvent;
4778 break;
4779 case TOP_DRAG:
4780 case TOP_DRAG_END:
4781 case TOP_DRAG_ENTER:
4782 case TOP_DRAG_EXIT:
4783 case TOP_DRAG_LEAVE:
4784 case TOP_DRAG_OVER:
4785 case TOP_DRAG_START:
4786 case TOP_DROP:
4787 EventConstructor = SyntheticDragEvent;
4788 break;
4789 case TOP_TOUCH_CANCEL:
4790 case TOP_TOUCH_END:
4791 case TOP_TOUCH_MOVE:
4792 case TOP_TOUCH_START:
4793 EventConstructor = SyntheticTouchEvent;
4794 break;
4795 case TOP_ANIMATION_END:
4796 case TOP_ANIMATION_ITERATION:
4797 case TOP_ANIMATION_START:
4798 EventConstructor = SyntheticAnimationEvent;
4799 break;
4800 case TOP_TRANSITION_END:
4801 EventConstructor = SyntheticTransitionEvent;
4802 break;
4803 case TOP_SCROLL:
4804 EventConstructor = SyntheticUIEvent;
4805 break;
4806 case TOP_WHEEL:
4807 EventConstructor = SyntheticWheelEvent;
4808 break;
4809 case TOP_COPY:
4810 case TOP_CUT:
4811 case TOP_PASTE:
4812 EventConstructor = SyntheticClipboardEvent;
4813 break;
4814 case TOP_GOT_POINTER_CAPTURE:
4815 case TOP_LOST_POINTER_CAPTURE:
4816 case TOP_POINTER_CANCEL:
4817 case TOP_POINTER_DOWN:
4818 case TOP_POINTER_MOVE:
4819 case TOP_POINTER_OUT:
4820 case TOP_POINTER_OVER:
4821 case TOP_POINTER_UP:
4822 EventConstructor = SyntheticPointerEvent;
4823 break;
4824 default:
4825 {
4826 if (knownHTMLTopLevelTypes.indexOf(topLevelType) === -1) {
4827 warningWithoutStack$1(false, 'SimpleEventPlugin: Unhandled event type, `%s`. This warning ' + 'is likely caused by a bug in React. Please file an issue.', topLevelType);
4828 }
4829 }
4830 // HTML Events
4831 // @see http://www.w3.org/TR/html5/index.html#events-0
4832 EventConstructor = SyntheticEvent;
4833 break;
4834 }
4835 var event = EventConstructor.getPooled(dispatchConfig, targetInst, nativeEvent, nativeEventTarget);
4836 accumulateTwoPhaseDispatches(event);
4837 return event;
4838 }
4839};
4840
4841var isInteractiveTopLevelEventType = SimpleEventPlugin.isInteractiveTopLevelEventType;
4842
4843
4844var CALLBACK_BOOKKEEPING_POOL_SIZE = 10;
4845var callbackBookkeepingPool = [];
4846
4847/**
4848 * Find the deepest React component completely containing the root of the
4849 * passed-in instance (for use when entire React trees are nested within each
4850 * other). If React trees are not nested, returns null.
4851 */
4852function findRootContainerNode(inst) {
4853 // TODO: It may be a good idea to cache this to prevent unnecessary DOM
4854 // traversal, but caching is difficult to do correctly without using a
4855 // mutation observer to listen for all DOM changes.
4856 while (inst.return) {
4857 inst = inst.return;
4858 }
4859 if (inst.tag !== HostRoot) {
4860 // This can happen if we're in a detached tree.
4861 return null;
4862 }
4863 return inst.stateNode.containerInfo;
4864}
4865
4866// Used to store ancestor hierarchy in top level callback
4867function getTopLevelCallbackBookKeeping(topLevelType, nativeEvent, targetInst) {
4868 if (callbackBookkeepingPool.length) {
4869 var instance = callbackBookkeepingPool.pop();
4870 instance.topLevelType = topLevelType;
4871 instance.nativeEvent = nativeEvent;
4872 instance.targetInst = targetInst;
4873 return instance;
4874 }
4875 return {
4876 topLevelType: topLevelType,
4877 nativeEvent: nativeEvent,
4878 targetInst: targetInst,
4879 ancestors: []
4880 };
4881}
4882
4883function releaseTopLevelCallbackBookKeeping(instance) {
4884 instance.topLevelType = null;
4885 instance.nativeEvent = null;
4886 instance.targetInst = null;
4887 instance.ancestors.length = 0;
4888 if (callbackBookkeepingPool.length < CALLBACK_BOOKKEEPING_POOL_SIZE) {
4889 callbackBookkeepingPool.push(instance);
4890 }
4891}
4892
4893function handleTopLevel(bookKeeping) {
4894 var targetInst = bookKeeping.targetInst;
4895
4896 // Loop through the hierarchy, in case there's any nested components.
4897 // It's important that we build the array of ancestors before calling any
4898 // event handlers, because event handlers can modify the DOM, leading to
4899 // inconsistencies with ReactMount's node cache. See #1105.
4900 var ancestor = targetInst;
4901 do {
4902 if (!ancestor) {
4903 bookKeeping.ancestors.push(ancestor);
4904 break;
4905 }
4906 var root = findRootContainerNode(ancestor);
4907 if (!root) {
4908 break;
4909 }
4910 bookKeeping.ancestors.push(ancestor);
4911 ancestor = getClosestInstanceFromNode(root);
4912 } while (ancestor);
4913
4914 for (var i = 0; i < bookKeeping.ancestors.length; i++) {
4915 targetInst = bookKeeping.ancestors[i];
4916 runExtractedEventsInBatch(bookKeeping.topLevelType, targetInst, bookKeeping.nativeEvent, getEventTarget(bookKeeping.nativeEvent));
4917 }
4918}
4919
4920// TODO: can we stop exporting these?
4921var _enabled = true;
4922
4923function setEnabled(enabled) {
4924 _enabled = !!enabled;
4925}
4926
4927function isEnabled() {
4928 return _enabled;
4929}
4930
4931/**
4932 * Traps top-level events by using event bubbling.
4933 *
4934 * @param {number} topLevelType Number from `TopLevelEventTypes`.
4935 * @param {object} element Element on which to attach listener.
4936 * @return {?object} An object with a remove function which will forcefully
4937 * remove the listener.
4938 * @internal
4939 */
4940function trapBubbledEvent(topLevelType, element) {
4941 if (!element) {
4942 return null;
4943 }
4944 var dispatch = isInteractiveTopLevelEventType(topLevelType) ? dispatchInteractiveEvent : dispatchEvent;
4945
4946 addEventBubbleListener(element, getRawEventName(topLevelType),
4947 // Check if interactive and wrap in interactiveUpdates
4948 dispatch.bind(null, topLevelType));
4949}
4950
4951/**
4952 * Traps a top-level event by using event capturing.
4953 *
4954 * @param {number} topLevelType Number from `TopLevelEventTypes`.
4955 * @param {object} element Element on which to attach listener.
4956 * @return {?object} An object with a remove function which will forcefully
4957 * remove the listener.
4958 * @internal
4959 */
4960function trapCapturedEvent(topLevelType, element) {
4961 if (!element) {
4962 return null;
4963 }
4964 var dispatch = isInteractiveTopLevelEventType(topLevelType) ? dispatchInteractiveEvent : dispatchEvent;
4965
4966 addEventCaptureListener(element, getRawEventName(topLevelType),
4967 // Check if interactive and wrap in interactiveUpdates
4968 dispatch.bind(null, topLevelType));
4969}
4970
4971function dispatchInteractiveEvent(topLevelType, nativeEvent) {
4972 interactiveUpdates(dispatchEvent, topLevelType, nativeEvent);
4973}
4974
4975function dispatchEvent(topLevelType, nativeEvent) {
4976 if (!_enabled) {
4977 return;
4978 }
4979
4980 var nativeEventTarget = getEventTarget(nativeEvent);
4981 var targetInst = getClosestInstanceFromNode(nativeEventTarget);
4982 if (targetInst !== null && typeof targetInst.tag === 'number' && !isFiberMounted(targetInst)) {
4983 // If we get an event (ex: img onload) before committing that
4984 // component's mount, ignore it for now (that is, treat it as if it was an
4985 // event on a non-React tree). We might also consider queueing events and
4986 // dispatching them after the mount.
4987 targetInst = null;
4988 }
4989
4990 var bookKeeping = getTopLevelCallbackBookKeeping(topLevelType, nativeEvent, targetInst);
4991
4992 try {
4993 // Event queue being processed in the same cycle allows
4994 // `preventDefault`.
4995 batchedUpdates(handleTopLevel, bookKeeping);
4996 } finally {
4997 releaseTopLevelCallbackBookKeeping(bookKeeping);
4998 }
4999}
5000
5001/**
5002 * Summary of `ReactBrowserEventEmitter` event handling:
5003 *
5004 * - Top-level delegation is used to trap most native browser events. This
5005 * may only occur in the main thread and is the responsibility of
5006 * ReactDOMEventListener, which is injected and can therefore support
5007 * pluggable event sources. This is the only work that occurs in the main
5008 * thread.
5009 *
5010 * - We normalize and de-duplicate events to account for browser quirks. This
5011 * may be done in the worker thread.
5012 *
5013 * - Forward these native events (with the associated top-level type used to
5014 * trap it) to `EventPluginHub`, which in turn will ask plugins if they want
5015 * to extract any synthetic events.
5016 *
5017 * - The `EventPluginHub` will then process each event by annotating them with
5018 * "dispatches", a sequence of listeners and IDs that care about that event.
5019 *
5020 * - The `EventPluginHub` then dispatches the events.
5021 *
5022 * Overview of React and the event system:
5023 *
5024 * +------------+ .
5025 * | DOM | .
5026 * +------------+ .
5027 * | .
5028 * v .
5029 * +------------+ .
5030 * | ReactEvent | .
5031 * | Listener | .
5032 * +------------+ . +-----------+
5033 * | . +--------+|SimpleEvent|
5034 * | . | |Plugin |
5035 * +-----|------+ . v +-----------+
5036 * | | | . +--------------+ +------------+
5037 * | +-----------.--->|EventPluginHub| | Event |
5038 * | | . | | +-----------+ | Propagators|
5039 * | ReactEvent | . | | |TapEvent | |------------|
5040 * | Emitter | . | |<---+|Plugin | |other plugin|
5041 * | | . | | +-----------+ | utilities |
5042 * | +-----------.--->| | +------------+
5043 * | | | . +--------------+
5044 * +-----|------+ . ^ +-----------+
5045 * | . | |Enter/Leave|
5046 * + . +-------+|Plugin |
5047 * +-------------+ . +-----------+
5048 * | application | .
5049 * |-------------| .
5050 * | | .
5051 * | | .
5052 * +-------------+ .
5053 * .
5054 * React Core . General Purpose Event Plugin System
5055 */
5056
5057var alreadyListeningTo = {};
5058var reactTopListenersCounter = 0;
5059
5060/**
5061 * To ensure no conflicts with other potential React instances on the page
5062 */
5063var topListenersIDKey = '_reactListenersID' + ('' + Math.random()).slice(2);
5064
5065function getListeningForDocument(mountAt) {
5066 // In IE8, `mountAt` is a host object and doesn't have `hasOwnProperty`
5067 // directly.
5068 if (!Object.prototype.hasOwnProperty.call(mountAt, topListenersIDKey)) {
5069 mountAt[topListenersIDKey] = reactTopListenersCounter++;
5070 alreadyListeningTo[mountAt[topListenersIDKey]] = {};
5071 }
5072 return alreadyListeningTo[mountAt[topListenersIDKey]];
5073}
5074
5075/**
5076 * We listen for bubbled touch events on the document object.
5077 *
5078 * Firefox v8.01 (and possibly others) exhibited strange behavior when
5079 * mounting `onmousemove` events at some node that was not the document
5080 * element. The symptoms were that if your mouse is not moving over something
5081 * contained within that mount point (for example on the background) the
5082 * top-level listeners for `onmousemove` won't be called. However, if you
5083 * register the `mousemove` on the document object, then it will of course
5084 * catch all `mousemove`s. This along with iOS quirks, justifies restricting
5085 * top-level listeners to the document object only, at least for these
5086 * movement types of events and possibly all events.
5087 *
5088 * @see http://www.quirksmode.org/blog/archives/2010/09/click_event_del.html
5089 *
5090 * Also, `keyup`/`keypress`/`keydown` do not bubble to the window on IE, but
5091 * they bubble to document.
5092 *
5093 * @param {string} registrationName Name of listener (e.g. `onClick`).
5094 * @param {object} mountAt Container where to mount the listener
5095 */
5096function listenTo(registrationName, mountAt) {
5097 var isListening = getListeningForDocument(mountAt);
5098 var dependencies = registrationNameDependencies[registrationName];
5099
5100 for (var i = 0; i < dependencies.length; i++) {
5101 var dependency = dependencies[i];
5102 if (!(isListening.hasOwnProperty(dependency) && isListening[dependency])) {
5103 switch (dependency) {
5104 case TOP_SCROLL:
5105 trapCapturedEvent(TOP_SCROLL, mountAt);
5106 break;
5107 case TOP_FOCUS:
5108 case TOP_BLUR:
5109 trapCapturedEvent(TOP_FOCUS, mountAt);
5110 trapCapturedEvent(TOP_BLUR, mountAt);
5111 // We set the flag for a single dependency later in this function,
5112 // but this ensures we mark both as attached rather than just one.
5113 isListening[TOP_BLUR] = true;
5114 isListening[TOP_FOCUS] = true;
5115 break;
5116 case TOP_CANCEL:
5117 case TOP_CLOSE:
5118 if (isEventSupported(getRawEventName(dependency))) {
5119 trapCapturedEvent(dependency, mountAt);
5120 }
5121 break;
5122 case TOP_INVALID:
5123 case TOP_SUBMIT:
5124 case TOP_RESET:
5125 // We listen to them on the target DOM elements.
5126 // Some of them bubble so we don't want them to fire twice.
5127 break;
5128 default:
5129 // By default, listen on the top level to all non-media events.
5130 // Media events don't bubble so adding the listener wouldn't do anything.
5131 var isMediaEvent = mediaEventTypes.indexOf(dependency) !== -1;
5132 if (!isMediaEvent) {
5133 trapBubbledEvent(dependency, mountAt);
5134 }
5135 break;
5136 }
5137 isListening[dependency] = true;
5138 }
5139 }
5140}
5141
5142function isListeningToAllDependencies(registrationName, mountAt) {
5143 var isListening = getListeningForDocument(mountAt);
5144 var dependencies = registrationNameDependencies[registrationName];
5145 for (var i = 0; i < dependencies.length; i++) {
5146 var dependency = dependencies[i];
5147 if (!(isListening.hasOwnProperty(dependency) && isListening[dependency])) {
5148 return false;
5149 }
5150 }
5151 return true;
5152}
5153
5154function getActiveElement(doc) {
5155 doc = doc || (typeof document !== 'undefined' ? document : undefined);
5156 if (typeof doc === 'undefined') {
5157 return null;
5158 }
5159 try {
5160 return doc.activeElement || doc.body;
5161 } catch (e) {
5162 return doc.body;
5163 }
5164}
5165
5166/**
5167 * Given any node return the first leaf node without children.
5168 *
5169 * @param {DOMElement|DOMTextNode} node
5170 * @return {DOMElement|DOMTextNode}
5171 */
5172function getLeafNode(node) {
5173 while (node && node.firstChild) {
5174 node = node.firstChild;
5175 }
5176 return node;
5177}
5178
5179/**
5180 * Get the next sibling within a container. This will walk up the
5181 * DOM if a node's siblings have been exhausted.
5182 *
5183 * @param {DOMElement|DOMTextNode} node
5184 * @return {?DOMElement|DOMTextNode}
5185 */
5186function getSiblingNode(node) {
5187 while (node) {
5188 if (node.nextSibling) {
5189 return node.nextSibling;
5190 }
5191 node = node.parentNode;
5192 }
5193}
5194
5195/**
5196 * Get object describing the nodes which contain characters at offset.
5197 *
5198 * @param {DOMElement|DOMTextNode} root
5199 * @param {number} offset
5200 * @return {?object}
5201 */
5202function getNodeForCharacterOffset(root, offset) {
5203 var node = getLeafNode(root);
5204 var nodeStart = 0;
5205 var nodeEnd = 0;
5206
5207 while (node) {
5208 if (node.nodeType === TEXT_NODE) {
5209 nodeEnd = nodeStart + node.textContent.length;
5210
5211 if (nodeStart <= offset && nodeEnd >= offset) {
5212 return {
5213 node: node,
5214 offset: offset - nodeStart
5215 };
5216 }
5217
5218 nodeStart = nodeEnd;
5219 }
5220
5221 node = getLeafNode(getSiblingNode(node));
5222 }
5223}
5224
5225/**
5226 * @param {DOMElement} outerNode
5227 * @return {?object}
5228 */
5229function getOffsets(outerNode) {
5230 var ownerDocument = outerNode.ownerDocument;
5231
5232 var win = ownerDocument && ownerDocument.defaultView || window;
5233 var selection = win.getSelection && win.getSelection();
5234
5235 if (!selection || selection.rangeCount === 0) {
5236 return null;
5237 }
5238
5239 var anchorNode = selection.anchorNode,
5240 anchorOffset = selection.anchorOffset,
5241 focusNode = selection.focusNode,
5242 focusOffset = selection.focusOffset;
5243
5244 // In Firefox, anchorNode and focusNode can be "anonymous divs", e.g. the
5245 // up/down buttons on an <input type="number">. Anonymous divs do not seem to
5246 // expose properties, triggering a "Permission denied error" if any of its
5247 // properties are accessed. The only seemingly possible way to avoid erroring
5248 // is to access a property that typically works for non-anonymous divs and
5249 // catch any error that may otherwise arise. See
5250 // https://bugzilla.mozilla.org/show_bug.cgi?id=208427
5251
5252 try {
5253 /* eslint-disable no-unused-expressions */
5254 anchorNode.nodeType;
5255 focusNode.nodeType;
5256 /* eslint-enable no-unused-expressions */
5257 } catch (e) {
5258 return null;
5259 }
5260
5261 return getModernOffsetsFromPoints(outerNode, anchorNode, anchorOffset, focusNode, focusOffset);
5262}
5263
5264/**
5265 * Returns {start, end} where `start` is the character/codepoint index of
5266 * (anchorNode, anchorOffset) within the textContent of `outerNode`, and
5267 * `end` is the index of (focusNode, focusOffset).
5268 *
5269 * Returns null if you pass in garbage input but we should probably just crash.
5270 *
5271 * Exported only for testing.
5272 */
5273function getModernOffsetsFromPoints(outerNode, anchorNode, anchorOffset, focusNode, focusOffset) {
5274 var length = 0;
5275 var start = -1;
5276 var end = -1;
5277 var indexWithinAnchor = 0;
5278 var indexWithinFocus = 0;
5279 var node = outerNode;
5280 var parentNode = null;
5281
5282 outer: while (true) {
5283 var next = null;
5284
5285 while (true) {
5286 if (node === anchorNode && (anchorOffset === 0 || node.nodeType === TEXT_NODE)) {
5287 start = length + anchorOffset;
5288 }
5289 if (node === focusNode && (focusOffset === 0 || node.nodeType === TEXT_NODE)) {
5290 end = length + focusOffset;
5291 }
5292
5293 if (node.nodeType === TEXT_NODE) {
5294 length += node.nodeValue.length;
5295 }
5296
5297 if ((next = node.firstChild) === null) {
5298 break;
5299 }
5300 // Moving from `node` to its first child `next`.
5301 parentNode = node;
5302 node = next;
5303 }
5304
5305 while (true) {
5306 if (node === outerNode) {
5307 // If `outerNode` has children, this is always the second time visiting
5308 // it. If it has no children, this is still the first loop, and the only
5309 // valid selection is anchorNode and focusNode both equal to this node
5310 // and both offsets 0, in which case we will have handled above.
5311 break outer;
5312 }
5313 if (parentNode === anchorNode && ++indexWithinAnchor === anchorOffset) {
5314 start = length;
5315 }
5316 if (parentNode === focusNode && ++indexWithinFocus === focusOffset) {
5317 end = length;
5318 }
5319 if ((next = node.nextSibling) !== null) {
5320 break;
5321 }
5322 node = parentNode;
5323 parentNode = node.parentNode;
5324 }
5325
5326 // Moving from `node` to its next sibling `next`.
5327 node = next;
5328 }
5329
5330 if (start === -1 || end === -1) {
5331 // This should never happen. (Would happen if the anchor/focus nodes aren't
5332 // actually inside the passed-in node.)
5333 return null;
5334 }
5335
5336 return {
5337 start: start,
5338 end: end
5339 };
5340}
5341
5342/**
5343 * In modern non-IE browsers, we can support both forward and backward
5344 * selections.
5345 *
5346 * Note: IE10+ supports the Selection object, but it does not support
5347 * the `extend` method, which means that even in modern IE, it's not possible
5348 * to programmatically create a backward selection. Thus, for all IE
5349 * versions, we use the old IE API to create our selections.
5350 *
5351 * @param {DOMElement|DOMTextNode} node
5352 * @param {object} offsets
5353 */
5354function setOffsets(node, offsets) {
5355 var doc = node.ownerDocument || document;
5356 var win = doc && doc.defaultView || window;
5357
5358 // Edge fails with "Object expected" in some scenarios.
5359 // (For instance: TinyMCE editor used in a list component that supports pasting to add more,
5360 // fails when pasting 100+ items)
5361 if (!win.getSelection) {
5362 return;
5363 }
5364
5365 var selection = win.getSelection();
5366 var length = node.textContent.length;
5367 var start = Math.min(offsets.start, length);
5368 var end = offsets.end === undefined ? start : Math.min(offsets.end, length);
5369
5370 // IE 11 uses modern selection, but doesn't support the extend method.
5371 // Flip backward selections, so we can set with a single range.
5372 if (!selection.extend && start > end) {
5373 var temp = end;
5374 end = start;
5375 start = temp;
5376 }
5377
5378 var startMarker = getNodeForCharacterOffset(node, start);
5379 var endMarker = getNodeForCharacterOffset(node, end);
5380
5381 if (startMarker && endMarker) {
5382 if (selection.rangeCount === 1 && selection.anchorNode === startMarker.node && selection.anchorOffset === startMarker.offset && selection.focusNode === endMarker.node && selection.focusOffset === endMarker.offset) {
5383 return;
5384 }
5385 var range = doc.createRange();
5386 range.setStart(startMarker.node, startMarker.offset);
5387 selection.removeAllRanges();
5388
5389 if (start > end) {
5390 selection.addRange(range);
5391 selection.extend(endMarker.node, endMarker.offset);
5392 } else {
5393 range.setEnd(endMarker.node, endMarker.offset);
5394 selection.addRange(range);
5395 }
5396 }
5397}
5398
5399function isTextNode(node) {
5400 return node && node.nodeType === TEXT_NODE;
5401}
5402
5403function containsNode(outerNode, innerNode) {
5404 if (!outerNode || !innerNode) {
5405 return false;
5406 } else if (outerNode === innerNode) {
5407 return true;
5408 } else if (isTextNode(outerNode)) {
5409 return false;
5410 } else if (isTextNode(innerNode)) {
5411 return containsNode(outerNode, innerNode.parentNode);
5412 } else if ('contains' in outerNode) {
5413 return outerNode.contains(innerNode);
5414 } else if (outerNode.compareDocumentPosition) {
5415 return !!(outerNode.compareDocumentPosition(innerNode) & 16);
5416 } else {
5417 return false;
5418 }
5419}
5420
5421function isInDocument(node) {
5422 return node && node.ownerDocument && containsNode(node.ownerDocument.documentElement, node);
5423}
5424
5425function getActiveElementDeep() {
5426 var win = window;
5427 var element = getActiveElement();
5428 while (element instanceof win.HTMLIFrameElement) {
5429 // Accessing the contentDocument of a HTMLIframeElement can cause the browser
5430 // to throw, e.g. if it has a cross-origin src attribute
5431 try {
5432 win = element.contentDocument.defaultView;
5433 } catch (e) {
5434 return element;
5435 }
5436 element = getActiveElement(win.document);
5437 }
5438 return element;
5439}
5440
5441/**
5442 * @ReactInputSelection: React input selection module. Based on Selection.js,
5443 * but modified to be suitable for react and has a couple of bug fixes (doesn't
5444 * assume buttons have range selections allowed).
5445 * Input selection module for React.
5446 */
5447
5448/**
5449 * @hasSelectionCapabilities: we get the element types that support selection
5450 * from https://html.spec.whatwg.org/#do-not-apply, looking at `selectionStart`
5451 * and `selectionEnd` rows.
5452 */
5453function hasSelectionCapabilities(elem) {
5454 var nodeName = elem && elem.nodeName && elem.nodeName.toLowerCase();
5455 return nodeName && (nodeName === 'input' && (elem.type === 'text' || elem.type === 'search' || elem.type === 'tel' || elem.type === 'url' || elem.type === 'password') || nodeName === 'textarea' || elem.contentEditable === 'true');
5456}
5457
5458function getSelectionInformation() {
5459 var focusedElem = getActiveElementDeep();
5460 return {
5461 focusedElem: focusedElem,
5462 selectionRange: hasSelectionCapabilities(focusedElem) ? getSelection$1(focusedElem) : null
5463 };
5464}
5465
5466/**
5467 * @restoreSelection: If any selection information was potentially lost,
5468 * restore it. This is useful when performing operations that could remove dom
5469 * nodes and place them back in, resulting in focus being lost.
5470 */
5471function restoreSelection(priorSelectionInformation) {
5472 var curFocusedElem = getActiveElementDeep();
5473 var priorFocusedElem = priorSelectionInformation.focusedElem;
5474 var priorSelectionRange = priorSelectionInformation.selectionRange;
5475 if (curFocusedElem !== priorFocusedElem && isInDocument(priorFocusedElem)) {
5476 if (priorSelectionRange !== null && hasSelectionCapabilities(priorFocusedElem)) {
5477 setSelection(priorFocusedElem, priorSelectionRange);
5478 }
5479
5480 // Focusing a node can change the scroll position, which is undesirable
5481 var ancestors = [];
5482 var ancestor = priorFocusedElem;
5483 while (ancestor = ancestor.parentNode) {
5484 if (ancestor.nodeType === ELEMENT_NODE) {
5485 ancestors.push({
5486 element: ancestor,
5487 left: ancestor.scrollLeft,
5488 top: ancestor.scrollTop
5489 });
5490 }
5491 }
5492
5493 if (typeof priorFocusedElem.focus === 'function') {
5494 priorFocusedElem.focus();
5495 }
5496
5497 for (var i = 0; i < ancestors.length; i++) {
5498 var info = ancestors[i];
5499 info.element.scrollLeft = info.left;
5500 info.element.scrollTop = info.top;
5501 }
5502 }
5503}
5504
5505/**
5506 * @getSelection: Gets the selection bounds of a focused textarea, input or
5507 * contentEditable node.
5508 * -@input: Look up selection bounds of this input
5509 * -@return {start: selectionStart, end: selectionEnd}
5510 */
5511function getSelection$1(input) {
5512 var selection = void 0;
5513
5514 if ('selectionStart' in input) {
5515 // Modern browser with input or textarea.
5516 selection = {
5517 start: input.selectionStart,
5518 end: input.selectionEnd
5519 };
5520 } else {
5521 // Content editable or old IE textarea.
5522 selection = getOffsets(input);
5523 }
5524
5525 return selection || { start: 0, end: 0 };
5526}
5527
5528/**
5529 * @setSelection: Sets the selection bounds of a textarea or input and focuses
5530 * the input.
5531 * -@input Set selection bounds of this input or textarea
5532 * -@offsets Object of same form that is returned from get*
5533 */
5534function setSelection(input, offsets) {
5535 var start = offsets.start,
5536 end = offsets.end;
5537
5538 if (end === undefined) {
5539 end = start;
5540 }
5541
5542 if ('selectionStart' in input) {
5543 input.selectionStart = start;
5544 input.selectionEnd = Math.min(end, input.value.length);
5545 } else {
5546 setOffsets(input, offsets);
5547 }
5548}
5549
5550var skipSelectionChangeEvent = canUseDOM && 'documentMode' in document && document.documentMode <= 11;
5551
5552var eventTypes$3 = {
5553 select: {
5554 phasedRegistrationNames: {
5555 bubbled: 'onSelect',
5556 captured: 'onSelectCapture'
5557 },
5558 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]
5559 }
5560};
5561
5562var activeElement$1 = null;
5563var activeElementInst$1 = null;
5564var lastSelection = null;
5565var mouseDown = false;
5566
5567/**
5568 * Get an object which is a unique representation of the current selection.
5569 *
5570 * The return value will not be consistent across nodes or browsers, but
5571 * two identical selections on the same node will return identical objects.
5572 *
5573 * @param {DOMElement} node
5574 * @return {object}
5575 */
5576function getSelection(node) {
5577 if ('selectionStart' in node && hasSelectionCapabilities(node)) {
5578 return {
5579 start: node.selectionStart,
5580 end: node.selectionEnd
5581 };
5582 } else {
5583 var win = node.ownerDocument && node.ownerDocument.defaultView || window;
5584 var selection = win.getSelection();
5585 return {
5586 anchorNode: selection.anchorNode,
5587 anchorOffset: selection.anchorOffset,
5588 focusNode: selection.focusNode,
5589 focusOffset: selection.focusOffset
5590 };
5591 }
5592}
5593
5594/**
5595 * Get document associated with the event target.
5596 *
5597 * @param {object} nativeEventTarget
5598 * @return {Document}
5599 */
5600function getEventTargetDocument(eventTarget) {
5601 return eventTarget.window === eventTarget ? eventTarget.document : eventTarget.nodeType === DOCUMENT_NODE ? eventTarget : eventTarget.ownerDocument;
5602}
5603
5604/**
5605 * Poll selection to see whether it's changed.
5606 *
5607 * @param {object} nativeEvent
5608 * @param {object} nativeEventTarget
5609 * @return {?SyntheticEvent}
5610 */
5611function constructSelectEvent(nativeEvent, nativeEventTarget) {
5612 // Ensure we have the right element, and that the user is not dragging a
5613 // selection (this matches native `select` event behavior). In HTML5, select
5614 // fires only on input and textarea thus if there's no focused element we
5615 // won't dispatch.
5616 var doc = getEventTargetDocument(nativeEventTarget);
5617
5618 if (mouseDown || activeElement$1 == null || activeElement$1 !== getActiveElement(doc)) {
5619 return null;
5620 }
5621
5622 // Only fire when selection has actually changed.
5623 var currentSelection = getSelection(activeElement$1);
5624 if (!lastSelection || !shallowEqual(lastSelection, currentSelection)) {
5625 lastSelection = currentSelection;
5626
5627 var syntheticEvent = SyntheticEvent.getPooled(eventTypes$3.select, activeElementInst$1, nativeEvent, nativeEventTarget);
5628
5629 syntheticEvent.type = 'select';
5630 syntheticEvent.target = activeElement$1;
5631
5632 accumulateTwoPhaseDispatches(syntheticEvent);
5633
5634 return syntheticEvent;
5635 }
5636
5637 return null;
5638}
5639
5640/**
5641 * This plugin creates an `onSelect` event that normalizes select events
5642 * across form elements.
5643 *
5644 * Supported elements are:
5645 * - input (see `isTextInputElement`)
5646 * - textarea
5647 * - contentEditable
5648 *
5649 * This differs from native browser implementations in the following ways:
5650 * - Fires on contentEditable fields as well as inputs.
5651 * - Fires for collapsed selection.
5652 * - Fires after user input.
5653 */
5654var SelectEventPlugin = {
5655 eventTypes: eventTypes$3,
5656
5657 extractEvents: function (topLevelType, targetInst, nativeEvent, nativeEventTarget) {
5658 var doc = getEventTargetDocument(nativeEventTarget);
5659 // Track whether all listeners exists for this plugin. If none exist, we do
5660 // not extract events. See #3639.
5661 if (!doc || !isListeningToAllDependencies('onSelect', doc)) {
5662 return null;
5663 }
5664
5665 var targetNode = targetInst ? getNodeFromInstance$1(targetInst) : window;
5666
5667 switch (topLevelType) {
5668 // Track the input node that has focus.
5669 case TOP_FOCUS:
5670 if (isTextInputElement(targetNode) || targetNode.contentEditable === 'true') {
5671 activeElement$1 = targetNode;
5672 activeElementInst$1 = targetInst;
5673 lastSelection = null;
5674 }
5675 break;
5676 case TOP_BLUR:
5677 activeElement$1 = null;
5678 activeElementInst$1 = null;
5679 lastSelection = null;
5680 break;
5681 // Don't fire the event while the user is dragging. This matches the
5682 // semantics of the native select event.
5683 case TOP_MOUSE_DOWN:
5684 mouseDown = true;
5685 break;
5686 case TOP_CONTEXT_MENU:
5687 case TOP_MOUSE_UP:
5688 case TOP_DRAG_END:
5689 mouseDown = false;
5690 return constructSelectEvent(nativeEvent, nativeEventTarget);
5691 // Chrome and IE fire non-standard event when selection is changed (and
5692 // sometimes when it hasn't). IE's event fires out of order with respect
5693 // to key and input events on deletion, so we discard it.
5694 //
5695 // Firefox doesn't support selectionchange, so check selection status
5696 // after each key entry. The selection changes after keydown and before
5697 // keyup, but we check on keydown as well in the case of holding down a
5698 // key, when multiple keydown events are fired but only one keyup is.
5699 // This is also our approach for IE handling, for the reason above.
5700 case TOP_SELECTION_CHANGE:
5701 if (skipSelectionChangeEvent) {
5702 break;
5703 }
5704 // falls through
5705 case TOP_KEY_DOWN:
5706 case TOP_KEY_UP:
5707 return constructSelectEvent(nativeEvent, nativeEventTarget);
5708 }
5709
5710 return null;
5711 }
5712};
5713
5714/**
5715 * Inject modules for resolving DOM hierarchy and plugin ordering.
5716 */
5717injection.injectEventPluginOrder(DOMEventPluginOrder);
5718setComponentTree(getFiberCurrentPropsFromNode$1, getInstanceFromNode$1, getNodeFromInstance$1);
5719
5720/**
5721 * Some important event plugins included by default (without having to require
5722 * them).
5723 */
5724injection.injectEventPluginsByName({
5725 SimpleEventPlugin: SimpleEventPlugin,
5726 EnterLeaveEventPlugin: EnterLeaveEventPlugin,
5727 ChangeEventPlugin: ChangeEventPlugin,
5728 SelectEventPlugin: SelectEventPlugin,
5729 BeforeInputEventPlugin: BeforeInputEventPlugin
5730});
5731
5732var didWarnSelectedSetOnOption = false;
5733var didWarnInvalidChild = false;
5734
5735function flattenChildren(children) {
5736 var content = '';
5737
5738 // Flatten children. We'll warn if they are invalid
5739 // during validateProps() which runs for hydration too.
5740 // Note that this would throw on non-element objects.
5741 // Elements are stringified (which is normally irrelevant
5742 // but matters for <fbt>).
5743 React.Children.forEach(children, function (child) {
5744 if (child == null) {
5745 return;
5746 }
5747 content += child;
5748 // Note: we don't warn about invalid children here.
5749 // Instead, this is done separately below so that
5750 // it happens during the hydration codepath too.
5751 });
5752
5753 return content;
5754}
5755
5756/**
5757 * Implements an <option> host component that warns when `selected` is set.
5758 */
5759
5760function validateProps(element, props) {
5761 {
5762 // This mirrors the codepath above, but runs for hydration too.
5763 // Warn about invalid children here so that client and hydration are consistent.
5764 // TODO: this seems like it could cause a DEV-only throw for hydration
5765 // if children contains a non-element object. We should try to avoid that.
5766 if (typeof props.children === 'object' && props.children !== null) {
5767 React.Children.forEach(props.children, function (child) {
5768 if (child == null) {
5769 return;
5770 }
5771 if (typeof child === 'string' || typeof child === 'number') {
5772 return;
5773 }
5774 if (typeof child.type !== 'string') {
5775 return;
5776 }
5777 if (!didWarnInvalidChild) {
5778 didWarnInvalidChild = true;
5779 warning$1(false, 'Only strings and numbers are supported as <option> children.');
5780 }
5781 });
5782 }
5783
5784 // TODO: Remove support for `selected` in <option>.
5785 if (props.selected != null && !didWarnSelectedSetOnOption) {
5786 warning$1(false, 'Use the `defaultValue` or `value` props on <select> instead of ' + 'setting `selected` on <option>.');
5787 didWarnSelectedSetOnOption = true;
5788 }
5789 }
5790}
5791
5792function postMountWrapper$1(element, props) {
5793 // value="" should make a value attribute (#6219)
5794 if (props.value != null) {
5795 element.setAttribute('value', toString(getToStringValue(props.value)));
5796 }
5797}
5798
5799function getHostProps$1(element, props) {
5800 var hostProps = _assign({ children: undefined }, props);
5801 var content = flattenChildren(props.children);
5802
5803 if (content) {
5804 hostProps.children = content;
5805 }
5806
5807 return hostProps;
5808}
5809
5810// TODO: direct imports like some-package/src/* are bad. Fix me.
5811var didWarnValueDefaultValue$1 = void 0;
5812
5813{
5814 didWarnValueDefaultValue$1 = false;
5815}
5816
5817function getDeclarationErrorAddendum() {
5818 var ownerName = getCurrentFiberOwnerNameInDevOrNull();
5819 if (ownerName) {
5820 return '\n\nCheck the render method of `' + ownerName + '`.';
5821 }
5822 return '';
5823}
5824
5825var valuePropNames = ['value', 'defaultValue'];
5826
5827/**
5828 * Validation function for `value` and `defaultValue`.
5829 */
5830function checkSelectPropTypes(props) {
5831 ReactControlledValuePropTypes.checkPropTypes('select', props);
5832
5833 for (var i = 0; i < valuePropNames.length; i++) {
5834 var propName = valuePropNames[i];
5835 if (props[propName] == null) {
5836 continue;
5837 }
5838 var isArray = Array.isArray(props[propName]);
5839 if (props.multiple && !isArray) {
5840 warning$1(false, 'The `%s` prop supplied to <select> must be an array if ' + '`multiple` is true.%s', propName, getDeclarationErrorAddendum());
5841 } else if (!props.multiple && isArray) {
5842 warning$1(false, 'The `%s` prop supplied to <select> must be a scalar ' + 'value if `multiple` is false.%s', propName, getDeclarationErrorAddendum());
5843 }
5844 }
5845}
5846
5847function updateOptions(node, multiple, propValue, setDefaultSelected) {
5848 var options = node.options;
5849
5850 if (multiple) {
5851 var selectedValues = propValue;
5852 var selectedValue = {};
5853 for (var i = 0; i < selectedValues.length; i++) {
5854 // Prefix to avoid chaos with special keys.
5855 selectedValue['$' + selectedValues[i]] = true;
5856 }
5857 for (var _i = 0; _i < options.length; _i++) {
5858 var selected = selectedValue.hasOwnProperty('$' + options[_i].value);
5859 if (options[_i].selected !== selected) {
5860 options[_i].selected = selected;
5861 }
5862 if (selected && setDefaultSelected) {
5863 options[_i].defaultSelected = true;
5864 }
5865 }
5866 } else {
5867 // Do not set `select.value` as exact behavior isn't consistent across all
5868 // browsers for all cases.
5869 var _selectedValue = toString(getToStringValue(propValue));
5870 var defaultSelected = null;
5871 for (var _i2 = 0; _i2 < options.length; _i2++) {
5872 if (options[_i2].value === _selectedValue) {
5873 options[_i2].selected = true;
5874 if (setDefaultSelected) {
5875 options[_i2].defaultSelected = true;
5876 }
5877 return;
5878 }
5879 if (defaultSelected === null && !options[_i2].disabled) {
5880 defaultSelected = options[_i2];
5881 }
5882 }
5883 if (defaultSelected !== null) {
5884 defaultSelected.selected = true;
5885 }
5886 }
5887}
5888
5889/**
5890 * Implements a <select> host component that allows optionally setting the
5891 * props `value` and `defaultValue`. If `multiple` is false, the prop must be a
5892 * stringable. If `multiple` is true, the prop must be an array of stringables.
5893 *
5894 * If `value` is not supplied (or null/undefined), user actions that change the
5895 * selected option will trigger updates to the rendered options.
5896 *
5897 * If it is supplied (and not null/undefined), the rendered options will not
5898 * update in response to user actions. Instead, the `value` prop must change in
5899 * order for the rendered options to update.
5900 *
5901 * If `defaultValue` is provided, any options with the supplied values will be
5902 * selected.
5903 */
5904
5905function getHostProps$2(element, props) {
5906 return _assign({}, props, {
5907 value: undefined
5908 });
5909}
5910
5911function initWrapperState$1(element, props) {
5912 var node = element;
5913 {
5914 checkSelectPropTypes(props);
5915 }
5916
5917 node._wrapperState = {
5918 wasMultiple: !!props.multiple
5919 };
5920
5921 {
5922 if (props.value !== undefined && props.defaultValue !== undefined && !didWarnValueDefaultValue$1) {
5923 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');
5924 didWarnValueDefaultValue$1 = true;
5925 }
5926 }
5927}
5928
5929function postMountWrapper$2(element, props) {
5930 var node = element;
5931 node.multiple = !!props.multiple;
5932 var value = props.value;
5933 if (value != null) {
5934 updateOptions(node, !!props.multiple, value, false);
5935 } else if (props.defaultValue != null) {
5936 updateOptions(node, !!props.multiple, props.defaultValue, true);
5937 }
5938}
5939
5940function postUpdateWrapper(element, props) {
5941 var node = element;
5942 var wasMultiple = node._wrapperState.wasMultiple;
5943 node._wrapperState.wasMultiple = !!props.multiple;
5944
5945 var value = props.value;
5946 if (value != null) {
5947 updateOptions(node, !!props.multiple, value, false);
5948 } else if (wasMultiple !== !!props.multiple) {
5949 // For simplicity, reapply `defaultValue` if `multiple` is toggled.
5950 if (props.defaultValue != null) {
5951 updateOptions(node, !!props.multiple, props.defaultValue, true);
5952 } else {
5953 // Revert the select back to its default unselected state.
5954 updateOptions(node, !!props.multiple, props.multiple ? [] : '', false);
5955 }
5956 }
5957}
5958
5959function restoreControlledState$2(element, props) {
5960 var node = element;
5961 var value = props.value;
5962
5963 if (value != null) {
5964 updateOptions(node, !!props.multiple, value, false);
5965 }
5966}
5967
5968var didWarnValDefaultVal = false;
5969
5970/**
5971 * Implements a <textarea> host component that allows setting `value`, and
5972 * `defaultValue`. This differs from the traditional DOM API because value is
5973 * usually set as PCDATA children.
5974 *
5975 * If `value` is not supplied (or null/undefined), user actions that affect the
5976 * value will trigger updates to the element.
5977 *
5978 * If `value` is supplied (and not null/undefined), the rendered element will
5979 * not trigger updates to the element. Instead, the `value` prop must change in
5980 * order for the rendered element to be updated.
5981 *
5982 * The rendered element will be initialized with an empty value, the prop
5983 * `defaultValue` if specified, or the children content (deprecated).
5984 */
5985
5986function getHostProps$3(element, props) {
5987 var node = element;
5988 !(props.dangerouslySetInnerHTML == null) ? invariant(false, '`dangerouslySetInnerHTML` does not make sense on <textarea>.') : void 0;
5989
5990 // Always set children to the same thing. In IE9, the selection range will
5991 // get reset if `textContent` is mutated. We could add a check in setTextContent
5992 // to only set the value if/when the value differs from the node value (which would
5993 // completely solve this IE9 bug), but Sebastian+Sophie seemed to like this
5994 // solution. The value can be a boolean or object so that's why it's forced
5995 // to be a string.
5996 var hostProps = _assign({}, props, {
5997 value: undefined,
5998 defaultValue: undefined,
5999 children: toString(node._wrapperState.initialValue)
6000 });
6001
6002 return hostProps;
6003}
6004
6005function initWrapperState$2(element, props) {
6006 var node = element;
6007 {
6008 ReactControlledValuePropTypes.checkPropTypes('textarea', props);
6009 if (props.value !== undefined && props.defaultValue !== undefined && !didWarnValDefaultVal) {
6010 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');
6011 didWarnValDefaultVal = true;
6012 }
6013 }
6014
6015 var initialValue = props.value;
6016
6017 // Only bother fetching default value if we're going to use it
6018 if (initialValue == null) {
6019 var defaultValue = props.defaultValue;
6020 // TODO (yungsters): Remove support for children content in <textarea>.
6021 var children = props.children;
6022 if (children != null) {
6023 {
6024 warning$1(false, 'Use the `defaultValue` or `value` props instead of setting ' + 'children on <textarea>.');
6025 }
6026 !(defaultValue == null) ? invariant(false, 'If you supply `defaultValue` on a <textarea>, do not pass children.') : void 0;
6027 if (Array.isArray(children)) {
6028 !(children.length <= 1) ? invariant(false, '<textarea> can only have at most one child.') : void 0;
6029 children = children[0];
6030 }
6031
6032 defaultValue = children;
6033 }
6034 if (defaultValue == null) {
6035 defaultValue = '';
6036 }
6037 initialValue = defaultValue;
6038 }
6039
6040 node._wrapperState = {
6041 initialValue: getToStringValue(initialValue)
6042 };
6043}
6044
6045function updateWrapper$1(element, props) {
6046 var node = element;
6047 var value = getToStringValue(props.value);
6048 var defaultValue = getToStringValue(props.defaultValue);
6049 if (value != null) {
6050 // Cast `value` to a string to ensure the value is set correctly. While
6051 // browsers typically do this as necessary, jsdom doesn't.
6052 var newValue = toString(value);
6053 // To avoid side effects (such as losing text selection), only set value if changed
6054 if (newValue !== node.value) {
6055 node.value = newValue;
6056 }
6057 if (props.defaultValue == null && node.defaultValue !== newValue) {
6058 node.defaultValue = newValue;
6059 }
6060 }
6061 if (defaultValue != null) {
6062 node.defaultValue = toString(defaultValue);
6063 }
6064}
6065
6066function postMountWrapper$3(element, props) {
6067 var node = element;
6068 // This is in postMount because we need access to the DOM node, which is not
6069 // available until after the component has mounted.
6070 var textContent = node.textContent;
6071
6072 // Only set node.value if textContent is equal to the expected
6073 // initial value. In IE10/IE11 there is a bug where the placeholder attribute
6074 // will populate textContent as well.
6075 // https://developer.microsoft.com/microsoft-edge/platform/issues/101525/
6076 if (textContent === node._wrapperState.initialValue) {
6077 node.value = textContent;
6078 }
6079}
6080
6081function restoreControlledState$3(element, props) {
6082 // DOM component is still mounted; update
6083 updateWrapper$1(element, props);
6084}
6085
6086var HTML_NAMESPACE$1 = 'http://www.w3.org/1999/xhtml';
6087var MATH_NAMESPACE = 'http://www.w3.org/1998/Math/MathML';
6088var SVG_NAMESPACE = 'http://www.w3.org/2000/svg';
6089
6090var Namespaces = {
6091 html: HTML_NAMESPACE$1,
6092 mathml: MATH_NAMESPACE,
6093 svg: SVG_NAMESPACE
6094};
6095
6096// Assumes there is no parent namespace.
6097function getIntrinsicNamespace(type) {
6098 switch (type) {
6099 case 'svg':
6100 return SVG_NAMESPACE;
6101 case 'math':
6102 return MATH_NAMESPACE;
6103 default:
6104 return HTML_NAMESPACE$1;
6105 }
6106}
6107
6108function getChildNamespace(parentNamespace, type) {
6109 if (parentNamespace == null || parentNamespace === HTML_NAMESPACE$1) {
6110 // No (or default) parent namespace: potential entry point.
6111 return getIntrinsicNamespace(type);
6112 }
6113 if (parentNamespace === SVG_NAMESPACE && type === 'foreignObject') {
6114 // We're leaving SVG.
6115 return HTML_NAMESPACE$1;
6116 }
6117 // By default, pass namespace below.
6118 return parentNamespace;
6119}
6120
6121/* globals MSApp */
6122
6123/**
6124 * Create a function which has 'unsafe' privileges (required by windows8 apps)
6125 */
6126var createMicrosoftUnsafeLocalFunction = function (func) {
6127 if (typeof MSApp !== 'undefined' && MSApp.execUnsafeLocalFunction) {
6128 return function (arg0, arg1, arg2, arg3) {
6129 MSApp.execUnsafeLocalFunction(function () {
6130 return func(arg0, arg1, arg2, arg3);
6131 });
6132 };
6133 } else {
6134 return func;
6135 }
6136};
6137
6138// SVG temp container for IE lacking innerHTML
6139var reusableSVGContainer = void 0;
6140
6141/**
6142 * Set the innerHTML property of a node
6143 *
6144 * @param {DOMElement} node
6145 * @param {string} html
6146 * @internal
6147 */
6148var setInnerHTML = createMicrosoftUnsafeLocalFunction(function (node, html) {
6149 // IE does not have innerHTML for SVG nodes, so instead we inject the
6150 // new markup in a temp node and then move the child nodes across into
6151 // the target node
6152
6153 if (node.namespaceURI === Namespaces.svg && !('innerHTML' in node)) {
6154 reusableSVGContainer = reusableSVGContainer || document.createElement('div');
6155 reusableSVGContainer.innerHTML = '<svg>' + html + '</svg>';
6156 var svgNode = reusableSVGContainer.firstChild;
6157 while (node.firstChild) {
6158 node.removeChild(node.firstChild);
6159 }
6160 while (svgNode.firstChild) {
6161 node.appendChild(svgNode.firstChild);
6162 }
6163 } else {
6164 node.innerHTML = html;
6165 }
6166});
6167
6168/**
6169 * Set the textContent property of a node. For text updates, it's faster
6170 * to set the `nodeValue` of the Text node directly instead of using
6171 * `.textContent` which will remove the existing node and create a new one.
6172 *
6173 * @param {DOMElement} node
6174 * @param {string} text
6175 * @internal
6176 */
6177var setTextContent = function (node, text) {
6178 if (text) {
6179 var firstChild = node.firstChild;
6180
6181 if (firstChild && firstChild === node.lastChild && firstChild.nodeType === TEXT_NODE) {
6182 firstChild.nodeValue = text;
6183 return;
6184 }
6185 }
6186 node.textContent = text;
6187};
6188
6189// List derived from Gecko source code:
6190// https://github.com/mozilla/gecko-dev/blob/4e638efc71/layout/style/test/property_database.js
6191var shorthandToLonghand = {
6192 animation: ['animationDelay', 'animationDirection', 'animationDuration', 'animationFillMode', 'animationIterationCount', 'animationName', 'animationPlayState', 'animationTimingFunction'],
6193 background: ['backgroundAttachment', 'backgroundClip', 'backgroundColor', 'backgroundImage', 'backgroundOrigin', 'backgroundPositionX', 'backgroundPositionY', 'backgroundRepeat', 'backgroundSize'],
6194 backgroundPosition: ['backgroundPositionX', 'backgroundPositionY'],
6195 border: ['borderBottomColor', 'borderBottomStyle', 'borderBottomWidth', 'borderImageOutset', 'borderImageRepeat', 'borderImageSlice', 'borderImageSource', 'borderImageWidth', 'borderLeftColor', 'borderLeftStyle', 'borderLeftWidth', 'borderRightColor', 'borderRightStyle', 'borderRightWidth', 'borderTopColor', 'borderTopStyle', 'borderTopWidth'],
6196 borderBlockEnd: ['borderBlockEndColor', 'borderBlockEndStyle', 'borderBlockEndWidth'],
6197 borderBlockStart: ['borderBlockStartColor', 'borderBlockStartStyle', 'borderBlockStartWidth'],
6198 borderBottom: ['borderBottomColor', 'borderBottomStyle', 'borderBottomWidth'],
6199 borderColor: ['borderBottomColor', 'borderLeftColor', 'borderRightColor', 'borderTopColor'],
6200 borderImage: ['borderImageOutset', 'borderImageRepeat', 'borderImageSlice', 'borderImageSource', 'borderImageWidth'],
6201 borderInlineEnd: ['borderInlineEndColor', 'borderInlineEndStyle', 'borderInlineEndWidth'],
6202 borderInlineStart: ['borderInlineStartColor', 'borderInlineStartStyle', 'borderInlineStartWidth'],
6203 borderLeft: ['borderLeftColor', 'borderLeftStyle', 'borderLeftWidth'],
6204 borderRadius: ['borderBottomLeftRadius', 'borderBottomRightRadius', 'borderTopLeftRadius', 'borderTopRightRadius'],
6205 borderRight: ['borderRightColor', 'borderRightStyle', 'borderRightWidth'],
6206 borderStyle: ['borderBottomStyle', 'borderLeftStyle', 'borderRightStyle', 'borderTopStyle'],
6207 borderTop: ['borderTopColor', 'borderTopStyle', 'borderTopWidth'],
6208 borderWidth: ['borderBottomWidth', 'borderLeftWidth', 'borderRightWidth', 'borderTopWidth'],
6209 columnRule: ['columnRuleColor', 'columnRuleStyle', 'columnRuleWidth'],
6210 columns: ['columnCount', 'columnWidth'],
6211 flex: ['flexBasis', 'flexGrow', 'flexShrink'],
6212 flexFlow: ['flexDirection', 'flexWrap'],
6213 font: ['fontFamily', 'fontFeatureSettings', 'fontKerning', 'fontLanguageOverride', 'fontSize', 'fontSizeAdjust', 'fontStretch', 'fontStyle', 'fontVariant', 'fontVariantAlternates', 'fontVariantCaps', 'fontVariantEastAsian', 'fontVariantLigatures', 'fontVariantNumeric', 'fontVariantPosition', 'fontWeight', 'lineHeight'],
6214 fontVariant: ['fontVariantAlternates', 'fontVariantCaps', 'fontVariantEastAsian', 'fontVariantLigatures', 'fontVariantNumeric', 'fontVariantPosition'],
6215 gap: ['columnGap', 'rowGap'],
6216 grid: ['gridAutoColumns', 'gridAutoFlow', 'gridAutoRows', 'gridTemplateAreas', 'gridTemplateColumns', 'gridTemplateRows'],
6217 gridArea: ['gridColumnEnd', 'gridColumnStart', 'gridRowEnd', 'gridRowStart'],
6218 gridColumn: ['gridColumnEnd', 'gridColumnStart'],
6219 gridColumnGap: ['columnGap'],
6220 gridGap: ['columnGap', 'rowGap'],
6221 gridRow: ['gridRowEnd', 'gridRowStart'],
6222 gridRowGap: ['rowGap'],
6223 gridTemplate: ['gridTemplateAreas', 'gridTemplateColumns', 'gridTemplateRows'],
6224 listStyle: ['listStyleImage', 'listStylePosition', 'listStyleType'],
6225 margin: ['marginBottom', 'marginLeft', 'marginRight', 'marginTop'],
6226 marker: ['markerEnd', 'markerMid', 'markerStart'],
6227 mask: ['maskClip', 'maskComposite', 'maskImage', 'maskMode', 'maskOrigin', 'maskPositionX', 'maskPositionY', 'maskRepeat', 'maskSize'],
6228 maskPosition: ['maskPositionX', 'maskPositionY'],
6229 outline: ['outlineColor', 'outlineStyle', 'outlineWidth'],
6230 overflow: ['overflowX', 'overflowY'],
6231 padding: ['paddingBottom', 'paddingLeft', 'paddingRight', 'paddingTop'],
6232 placeContent: ['alignContent', 'justifyContent'],
6233 placeItems: ['alignItems', 'justifyItems'],
6234 placeSelf: ['alignSelf', 'justifySelf'],
6235 textDecoration: ['textDecorationColor', 'textDecorationLine', 'textDecorationStyle'],
6236 textEmphasis: ['textEmphasisColor', 'textEmphasisStyle'],
6237 transition: ['transitionDelay', 'transitionDuration', 'transitionProperty', 'transitionTimingFunction'],
6238 wordWrap: ['overflowWrap']
6239};
6240
6241/**
6242 * CSS properties which accept numbers but are not in units of "px".
6243 */
6244var isUnitlessNumber = {
6245 animationIterationCount: true,
6246 borderImageOutset: true,
6247 borderImageSlice: true,
6248 borderImageWidth: true,
6249 boxFlex: true,
6250 boxFlexGroup: true,
6251 boxOrdinalGroup: true,
6252 columnCount: true,
6253 columns: true,
6254 flex: true,
6255 flexGrow: true,
6256 flexPositive: true,
6257 flexShrink: true,
6258 flexNegative: true,
6259 flexOrder: true,
6260 gridArea: true,
6261 gridRow: true,
6262 gridRowEnd: true,
6263 gridRowSpan: true,
6264 gridRowStart: true,
6265 gridColumn: true,
6266 gridColumnEnd: true,
6267 gridColumnSpan: true,
6268 gridColumnStart: true,
6269 fontWeight: true,
6270 lineClamp: true,
6271 lineHeight: true,
6272 opacity: true,
6273 order: true,
6274 orphans: true,
6275 tabSize: true,
6276 widows: true,
6277 zIndex: true,
6278 zoom: true,
6279
6280 // SVG-related properties
6281 fillOpacity: true,
6282 floodOpacity: true,
6283 stopOpacity: true,
6284 strokeDasharray: true,
6285 strokeDashoffset: true,
6286 strokeMiterlimit: true,
6287 strokeOpacity: true,
6288 strokeWidth: true
6289};
6290
6291/**
6292 * @param {string} prefix vendor-specific prefix, eg: Webkit
6293 * @param {string} key style name, eg: transitionDuration
6294 * @return {string} style name prefixed with `prefix`, properly camelCased, eg:
6295 * WebkitTransitionDuration
6296 */
6297function prefixKey(prefix, key) {
6298 return prefix + key.charAt(0).toUpperCase() + key.substring(1);
6299}
6300
6301/**
6302 * Support style names that may come passed in prefixed by adding permutations
6303 * of vendor prefixes.
6304 */
6305var prefixes = ['Webkit', 'ms', 'Moz', 'O'];
6306
6307// Using Object.keys here, or else the vanilla for-in loop makes IE8 go into an
6308// infinite loop, because it iterates over the newly added props too.
6309Object.keys(isUnitlessNumber).forEach(function (prop) {
6310 prefixes.forEach(function (prefix) {
6311 isUnitlessNumber[prefixKey(prefix, prop)] = isUnitlessNumber[prop];
6312 });
6313});
6314
6315/**
6316 * Convert a value into the proper css writable value. The style name `name`
6317 * should be logical (no hyphens), as specified
6318 * in `CSSProperty.isUnitlessNumber`.
6319 *
6320 * @param {string} name CSS property name such as `topMargin`.
6321 * @param {*} value CSS property value such as `10px`.
6322 * @return {string} Normalized style value with dimensions applied.
6323 */
6324function dangerousStyleValue(name, value, isCustomProperty) {
6325 // Note that we've removed escapeTextForBrowser() calls here since the
6326 // whole string will be escaped when the attribute is injected into
6327 // the markup. If you provide unsafe user data here they can inject
6328 // arbitrary CSS which may be problematic (I couldn't repro this):
6329 // https://www.owasp.org/index.php/XSS_Filter_Evasion_Cheat_Sheet
6330 // http://www.thespanner.co.uk/2007/11/26/ultimate-xss-css-injection/
6331 // This is not an XSS hole but instead a potential CSS injection issue
6332 // which has lead to a greater discussion about how we're going to
6333 // trust URLs moving forward. See #2115901
6334
6335 var isEmpty = value == null || typeof value === 'boolean' || value === '';
6336 if (isEmpty) {
6337 return '';
6338 }
6339
6340 if (!isCustomProperty && typeof value === 'number' && value !== 0 && !(isUnitlessNumber.hasOwnProperty(name) && isUnitlessNumber[name])) {
6341 return value + 'px'; // Presumes implicit 'px' suffix for unitless numbers
6342 }
6343
6344 return ('' + value).trim();
6345}
6346
6347var uppercasePattern = /([A-Z])/g;
6348var msPattern = /^ms-/;
6349
6350/**
6351 * Hyphenates a camelcased CSS property name, for example:
6352 *
6353 * > hyphenateStyleName('backgroundColor')
6354 * < "background-color"
6355 * > hyphenateStyleName('MozTransition')
6356 * < "-moz-transition"
6357 * > hyphenateStyleName('msTransition')
6358 * < "-ms-transition"
6359 *
6360 * As Modernizr suggests (http://modernizr.com/docs/#prefixed), an `ms` prefix
6361 * is converted to `-ms-`.
6362 */
6363function hyphenateStyleName(name) {
6364 return name.replace(uppercasePattern, '-$1').toLowerCase().replace(msPattern, '-ms-');
6365}
6366
6367var warnValidStyle = function () {};
6368
6369{
6370 // 'msTransform' is correct, but the other prefixes should be capitalized
6371 var badVendoredStyleNamePattern = /^(?:webkit|moz|o)[A-Z]/;
6372 var msPattern$1 = /^-ms-/;
6373 var hyphenPattern = /-(.)/g;
6374
6375 // style values shouldn't contain a semicolon
6376 var badStyleValueWithSemicolonPattern = /;\s*$/;
6377
6378 var warnedStyleNames = {};
6379 var warnedStyleValues = {};
6380 var warnedForNaNValue = false;
6381 var warnedForInfinityValue = false;
6382
6383 var camelize = function (string) {
6384 return string.replace(hyphenPattern, function (_, character) {
6385 return character.toUpperCase();
6386 });
6387 };
6388
6389 var warnHyphenatedStyleName = function (name) {
6390 if (warnedStyleNames.hasOwnProperty(name) && warnedStyleNames[name]) {
6391 return;
6392 }
6393
6394 warnedStyleNames[name] = true;
6395 warning$1(false, 'Unsupported style property %s. Did you mean %s?', name,
6396 // As Andi Smith suggests
6397 // (http://www.andismith.com/blog/2012/02/modernizr-prefixed/), an `-ms` prefix
6398 // is converted to lowercase `ms`.
6399 camelize(name.replace(msPattern$1, 'ms-')));
6400 };
6401
6402 var warnBadVendoredStyleName = function (name) {
6403 if (warnedStyleNames.hasOwnProperty(name) && warnedStyleNames[name]) {
6404 return;
6405 }
6406
6407 warnedStyleNames[name] = true;
6408 warning$1(false, 'Unsupported vendor-prefixed style property %s. Did you mean %s?', name, name.charAt(0).toUpperCase() + name.slice(1));
6409 };
6410
6411 var warnStyleValueWithSemicolon = function (name, value) {
6412 if (warnedStyleValues.hasOwnProperty(value) && warnedStyleValues[value]) {
6413 return;
6414 }
6415
6416 warnedStyleValues[value] = true;
6417 warning$1(false, "Style property values shouldn't contain a semicolon. " + 'Try "%s: %s" instead.', name, value.replace(badStyleValueWithSemicolonPattern, ''));
6418 };
6419
6420 var warnStyleValueIsNaN = function (name, value) {
6421 if (warnedForNaNValue) {
6422 return;
6423 }
6424
6425 warnedForNaNValue = true;
6426 warning$1(false, '`NaN` is an invalid value for the `%s` css style property.', name);
6427 };
6428
6429 var warnStyleValueIsInfinity = function (name, value) {
6430 if (warnedForInfinityValue) {
6431 return;
6432 }
6433
6434 warnedForInfinityValue = true;
6435 warning$1(false, '`Infinity` is an invalid value for the `%s` css style property.', name);
6436 };
6437
6438 warnValidStyle = function (name, value) {
6439 if (name.indexOf('-') > -1) {
6440 warnHyphenatedStyleName(name);
6441 } else if (badVendoredStyleNamePattern.test(name)) {
6442 warnBadVendoredStyleName(name);
6443 } else if (badStyleValueWithSemicolonPattern.test(value)) {
6444 warnStyleValueWithSemicolon(name, value);
6445 }
6446
6447 if (typeof value === 'number') {
6448 if (isNaN(value)) {
6449 warnStyleValueIsNaN(name, value);
6450 } else if (!isFinite(value)) {
6451 warnStyleValueIsInfinity(name, value);
6452 }
6453 }
6454 };
6455}
6456
6457var warnValidStyle$1 = warnValidStyle;
6458
6459/**
6460 * Operations for dealing with CSS properties.
6461 */
6462
6463/**
6464 * This creates a string that is expected to be equivalent to the style
6465 * attribute generated by server-side rendering. It by-passes warnings and
6466 * security checks so it's not safe to use this value for anything other than
6467 * comparison. It is only used in DEV for SSR validation.
6468 */
6469function createDangerousStringForStyles(styles) {
6470 {
6471 var serialized = '';
6472 var delimiter = '';
6473 for (var styleName in styles) {
6474 if (!styles.hasOwnProperty(styleName)) {
6475 continue;
6476 }
6477 var styleValue = styles[styleName];
6478 if (styleValue != null) {
6479 var isCustomProperty = styleName.indexOf('--') === 0;
6480 serialized += delimiter + hyphenateStyleName(styleName) + ':';
6481 serialized += dangerousStyleValue(styleName, styleValue, isCustomProperty);
6482
6483 delimiter = ';';
6484 }
6485 }
6486 return serialized || null;
6487 }
6488}
6489
6490/**
6491 * Sets the value for multiple styles on a node. If a value is specified as
6492 * '' (empty string), the corresponding style property will be unset.
6493 *
6494 * @param {DOMElement} node
6495 * @param {object} styles
6496 */
6497function setValueForStyles(node, styles) {
6498 var style = node.style;
6499 for (var styleName in styles) {
6500 if (!styles.hasOwnProperty(styleName)) {
6501 continue;
6502 }
6503 var isCustomProperty = styleName.indexOf('--') === 0;
6504 {
6505 if (!isCustomProperty) {
6506 warnValidStyle$1(styleName, styles[styleName]);
6507 }
6508 }
6509 var styleValue = dangerousStyleValue(styleName, styles[styleName], isCustomProperty);
6510 if (styleName === 'float') {
6511 styleName = 'cssFloat';
6512 }
6513 if (isCustomProperty) {
6514 style.setProperty(styleName, styleValue);
6515 } else {
6516 style[styleName] = styleValue;
6517 }
6518 }
6519}
6520
6521function isValueEmpty(value) {
6522 return value == null || typeof value === 'boolean' || value === '';
6523}
6524
6525/**
6526 * Given {color: 'red', overflow: 'hidden'} returns {
6527 * color: 'color',
6528 * overflowX: 'overflow',
6529 * overflowY: 'overflow',
6530 * }. This can be read as "the overflowY property was set by the overflow
6531 * shorthand". That is, the values are the property that each was derived from.
6532 */
6533function expandShorthandMap(styles) {
6534 var expanded = {};
6535 for (var key in styles) {
6536 var longhands = shorthandToLonghand[key] || [key];
6537 for (var i = 0; i < longhands.length; i++) {
6538 expanded[longhands[i]] = key;
6539 }
6540 }
6541 return expanded;
6542}
6543
6544/**
6545 * When mixing shorthand and longhand property names, we warn during updates if
6546 * we expect an incorrect result to occur. In particular, we warn for:
6547 *
6548 * Updating a shorthand property (longhand gets overwritten):
6549 * {font: 'foo', fontVariant: 'bar'} -> {font: 'baz', fontVariant: 'bar'}
6550 * becomes .style.font = 'baz'
6551 * Removing a shorthand property (longhand gets lost too):
6552 * {font: 'foo', fontVariant: 'bar'} -> {fontVariant: 'bar'}
6553 * becomes .style.font = ''
6554 * Removing a longhand property (should revert to shorthand; doesn't):
6555 * {font: 'foo', fontVariant: 'bar'} -> {font: 'foo'}
6556 * becomes .style.fontVariant = ''
6557 */
6558function validateShorthandPropertyCollisionInDev(styleUpdates, nextStyles) {
6559 if (!warnAboutShorthandPropertyCollision) {
6560 return;
6561 }
6562
6563 if (!nextStyles) {
6564 return;
6565 }
6566
6567 var expandedUpdates = expandShorthandMap(styleUpdates);
6568 var expandedStyles = expandShorthandMap(nextStyles);
6569 var warnedAbout = {};
6570 for (var key in expandedUpdates) {
6571 var originalKey = expandedUpdates[key];
6572 var correctOriginalKey = expandedStyles[key];
6573 if (correctOriginalKey && originalKey !== correctOriginalKey) {
6574 var warningKey = originalKey + ',' + correctOriginalKey;
6575 if (warnedAbout[warningKey]) {
6576 continue;
6577 }
6578 warnedAbout[warningKey] = true;
6579 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);
6580 }
6581 }
6582}
6583
6584// For HTML, certain tags should omit their close tag. We keep a whitelist for
6585// those special-case tags.
6586
6587var omittedCloseTags = {
6588 area: true,
6589 base: true,
6590 br: true,
6591 col: true,
6592 embed: true,
6593 hr: true,
6594 img: true,
6595 input: true,
6596 keygen: true,
6597 link: true,
6598 meta: true,
6599 param: true,
6600 source: true,
6601 track: true,
6602 wbr: true
6603 // NOTE: menuitem's close tag should be omitted, but that causes problems.
6604};
6605
6606// For HTML, certain tags cannot have children. This has the same purpose as
6607// `omittedCloseTags` except that `menuitem` should still have its closing tag.
6608
6609var voidElementTags = _assign({
6610 menuitem: true
6611}, omittedCloseTags);
6612
6613// TODO: We can remove this if we add invariantWithStack()
6614// or add stack by default to invariants where possible.
6615var HTML$1 = '__html';
6616
6617var ReactDebugCurrentFrame$2 = null;
6618{
6619 ReactDebugCurrentFrame$2 = ReactSharedInternals.ReactDebugCurrentFrame;
6620}
6621
6622function assertValidProps(tag, props) {
6623 if (!props) {
6624 return;
6625 }
6626 // Note the use of `==` which checks for null or undefined.
6627 if (voidElementTags[tag]) {
6628 !(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;
6629 }
6630 if (props.dangerouslySetInnerHTML != null) {
6631 !(props.children == null) ? invariant(false, 'Can only set one of `children` or `props.dangerouslySetInnerHTML`.') : void 0;
6632 !(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;
6633 }
6634 {
6635 !(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;
6636 }
6637 !(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;
6638}
6639
6640function isCustomComponent(tagName, props) {
6641 if (tagName.indexOf('-') === -1) {
6642 return typeof props.is === 'string';
6643 }
6644 switch (tagName) {
6645 // These are reserved SVG and MathML elements.
6646 // We don't mind this whitelist too much because we expect it to never grow.
6647 // The alternative is to track the namespace in a few places which is convoluted.
6648 // https://w3c.github.io/webcomponents/spec/custom/#custom-elements-core-concepts
6649 case 'annotation-xml':
6650 case 'color-profile':
6651 case 'font-face':
6652 case 'font-face-src':
6653 case 'font-face-uri':
6654 case 'font-face-format':
6655 case 'font-face-name':
6656 case 'missing-glyph':
6657 return false;
6658 default:
6659 return true;
6660 }
6661}
6662
6663// When adding attributes to the HTML or SVG whitelist, be sure to
6664// also add them to this module to ensure casing and incorrect name
6665// warnings.
6666var possibleStandardNames = {
6667 // HTML
6668 accept: 'accept',
6669 acceptcharset: 'acceptCharset',
6670 'accept-charset': 'acceptCharset',
6671 accesskey: 'accessKey',
6672 action: 'action',
6673 allowfullscreen: 'allowFullScreen',
6674 alt: 'alt',
6675 as: 'as',
6676 async: 'async',
6677 autocapitalize: 'autoCapitalize',
6678 autocomplete: 'autoComplete',
6679 autocorrect: 'autoCorrect',
6680 autofocus: 'autoFocus',
6681 autoplay: 'autoPlay',
6682 autosave: 'autoSave',
6683 capture: 'capture',
6684 cellpadding: 'cellPadding',
6685 cellspacing: 'cellSpacing',
6686 challenge: 'challenge',
6687 charset: 'charSet',
6688 checked: 'checked',
6689 children: 'children',
6690 cite: 'cite',
6691 class: 'className',
6692 classid: 'classID',
6693 classname: 'className',
6694 cols: 'cols',
6695 colspan: 'colSpan',
6696 content: 'content',
6697 contenteditable: 'contentEditable',
6698 contextmenu: 'contextMenu',
6699 controls: 'controls',
6700 controlslist: 'controlsList',
6701 coords: 'coords',
6702 crossorigin: 'crossOrigin',
6703 dangerouslysetinnerhtml: 'dangerouslySetInnerHTML',
6704 data: 'data',
6705 datetime: 'dateTime',
6706 default: 'default',
6707 defaultchecked: 'defaultChecked',
6708 defaultvalue: 'defaultValue',
6709 defer: 'defer',
6710 dir: 'dir',
6711 disabled: 'disabled',
6712 download: 'download',
6713 draggable: 'draggable',
6714 enctype: 'encType',
6715 for: 'htmlFor',
6716 form: 'form',
6717 formmethod: 'formMethod',
6718 formaction: 'formAction',
6719 formenctype: 'formEncType',
6720 formnovalidate: 'formNoValidate',
6721 formtarget: 'formTarget',
6722 frameborder: 'frameBorder',
6723 headers: 'headers',
6724 height: 'height',
6725 hidden: 'hidden',
6726 high: 'high',
6727 href: 'href',
6728 hreflang: 'hrefLang',
6729 htmlfor: 'htmlFor',
6730 httpequiv: 'httpEquiv',
6731 'http-equiv': 'httpEquiv',
6732 icon: 'icon',
6733 id: 'id',
6734 innerhtml: 'innerHTML',
6735 inputmode: 'inputMode',
6736 integrity: 'integrity',
6737 is: 'is',
6738 itemid: 'itemID',
6739 itemprop: 'itemProp',
6740 itemref: 'itemRef',
6741 itemscope: 'itemScope',
6742 itemtype: 'itemType',
6743 keyparams: 'keyParams',
6744 keytype: 'keyType',
6745 kind: 'kind',
6746 label: 'label',
6747 lang: 'lang',
6748 list: 'list',
6749 loop: 'loop',
6750 low: 'low',
6751 manifest: 'manifest',
6752 marginwidth: 'marginWidth',
6753 marginheight: 'marginHeight',
6754 max: 'max',
6755 maxlength: 'maxLength',
6756 media: 'media',
6757 mediagroup: 'mediaGroup',
6758 method: 'method',
6759 min: 'min',
6760 minlength: 'minLength',
6761 multiple: 'multiple',
6762 muted: 'muted',
6763 name: 'name',
6764 nomodule: 'noModule',
6765 nonce: 'nonce',
6766 novalidate: 'noValidate',
6767 open: 'open',
6768 optimum: 'optimum',
6769 pattern: 'pattern',
6770 placeholder: 'placeholder',
6771 playsinline: 'playsInline',
6772 poster: 'poster',
6773 preload: 'preload',
6774 profile: 'profile',
6775 radiogroup: 'radioGroup',
6776 readonly: 'readOnly',
6777 referrerpolicy: 'referrerPolicy',
6778 rel: 'rel',
6779 required: 'required',
6780 reversed: 'reversed',
6781 role: 'role',
6782 rows: 'rows',
6783 rowspan: 'rowSpan',
6784 sandbox: 'sandbox',
6785 scope: 'scope',
6786 scoped: 'scoped',
6787 scrolling: 'scrolling',
6788 seamless: 'seamless',
6789 selected: 'selected',
6790 shape: 'shape',
6791 size: 'size',
6792 sizes: 'sizes',
6793 span: 'span',
6794 spellcheck: 'spellCheck',
6795 src: 'src',
6796 srcdoc: 'srcDoc',
6797 srclang: 'srcLang',
6798 srcset: 'srcSet',
6799 start: 'start',
6800 step: 'step',
6801 style: 'style',
6802 summary: 'summary',
6803 tabindex: 'tabIndex',
6804 target: 'target',
6805 title: 'title',
6806 type: 'type',
6807 usemap: 'useMap',
6808 value: 'value',
6809 width: 'width',
6810 wmode: 'wmode',
6811 wrap: 'wrap',
6812
6813 // SVG
6814 about: 'about',
6815 accentheight: 'accentHeight',
6816 'accent-height': 'accentHeight',
6817 accumulate: 'accumulate',
6818 additive: 'additive',
6819 alignmentbaseline: 'alignmentBaseline',
6820 'alignment-baseline': 'alignmentBaseline',
6821 allowreorder: 'allowReorder',
6822 alphabetic: 'alphabetic',
6823 amplitude: 'amplitude',
6824 arabicform: 'arabicForm',
6825 'arabic-form': 'arabicForm',
6826 ascent: 'ascent',
6827 attributename: 'attributeName',
6828 attributetype: 'attributeType',
6829 autoreverse: 'autoReverse',
6830 azimuth: 'azimuth',
6831 basefrequency: 'baseFrequency',
6832 baselineshift: 'baselineShift',
6833 'baseline-shift': 'baselineShift',
6834 baseprofile: 'baseProfile',
6835 bbox: 'bbox',
6836 begin: 'begin',
6837 bias: 'bias',
6838 by: 'by',
6839 calcmode: 'calcMode',
6840 capheight: 'capHeight',
6841 'cap-height': 'capHeight',
6842 clip: 'clip',
6843 clippath: 'clipPath',
6844 'clip-path': 'clipPath',
6845 clippathunits: 'clipPathUnits',
6846 cliprule: 'clipRule',
6847 'clip-rule': 'clipRule',
6848 color: 'color',
6849 colorinterpolation: 'colorInterpolation',
6850 'color-interpolation': 'colorInterpolation',
6851 colorinterpolationfilters: 'colorInterpolationFilters',
6852 'color-interpolation-filters': 'colorInterpolationFilters',
6853 colorprofile: 'colorProfile',
6854 'color-profile': 'colorProfile',
6855 colorrendering: 'colorRendering',
6856 'color-rendering': 'colorRendering',
6857 contentscripttype: 'contentScriptType',
6858 contentstyletype: 'contentStyleType',
6859 cursor: 'cursor',
6860 cx: 'cx',
6861 cy: 'cy',
6862 d: 'd',
6863 datatype: 'datatype',
6864 decelerate: 'decelerate',
6865 descent: 'descent',
6866 diffuseconstant: 'diffuseConstant',
6867 direction: 'direction',
6868 display: 'display',
6869 divisor: 'divisor',
6870 dominantbaseline: 'dominantBaseline',
6871 'dominant-baseline': 'dominantBaseline',
6872 dur: 'dur',
6873 dx: 'dx',
6874 dy: 'dy',
6875 edgemode: 'edgeMode',
6876 elevation: 'elevation',
6877 enablebackground: 'enableBackground',
6878 'enable-background': 'enableBackground',
6879 end: 'end',
6880 exponent: 'exponent',
6881 externalresourcesrequired: 'externalResourcesRequired',
6882 fill: 'fill',
6883 fillopacity: 'fillOpacity',
6884 'fill-opacity': 'fillOpacity',
6885 fillrule: 'fillRule',
6886 'fill-rule': 'fillRule',
6887 filter: 'filter',
6888 filterres: 'filterRes',
6889 filterunits: 'filterUnits',
6890 floodopacity: 'floodOpacity',
6891 'flood-opacity': 'floodOpacity',
6892 floodcolor: 'floodColor',
6893 'flood-color': 'floodColor',
6894 focusable: 'focusable',
6895 fontfamily: 'fontFamily',
6896 'font-family': 'fontFamily',
6897 fontsize: 'fontSize',
6898 'font-size': 'fontSize',
6899 fontsizeadjust: 'fontSizeAdjust',
6900 'font-size-adjust': 'fontSizeAdjust',
6901 fontstretch: 'fontStretch',
6902 'font-stretch': 'fontStretch',
6903 fontstyle: 'fontStyle',
6904 'font-style': 'fontStyle',
6905 fontvariant: 'fontVariant',
6906 'font-variant': 'fontVariant',
6907 fontweight: 'fontWeight',
6908 'font-weight': 'fontWeight',
6909 format: 'format',
6910 from: 'from',
6911 fx: 'fx',
6912 fy: 'fy',
6913 g1: 'g1',
6914 g2: 'g2',
6915 glyphname: 'glyphName',
6916 'glyph-name': 'glyphName',
6917 glyphorientationhorizontal: 'glyphOrientationHorizontal',
6918 'glyph-orientation-horizontal': 'glyphOrientationHorizontal',
6919 glyphorientationvertical: 'glyphOrientationVertical',
6920 'glyph-orientation-vertical': 'glyphOrientationVertical',
6921 glyphref: 'glyphRef',
6922 gradienttransform: 'gradientTransform',
6923 gradientunits: 'gradientUnits',
6924 hanging: 'hanging',
6925 horizadvx: 'horizAdvX',
6926 'horiz-adv-x': 'horizAdvX',
6927 horizoriginx: 'horizOriginX',
6928 'horiz-origin-x': 'horizOriginX',
6929 ideographic: 'ideographic',
6930 imagerendering: 'imageRendering',
6931 'image-rendering': 'imageRendering',
6932 in2: 'in2',
6933 in: 'in',
6934 inlist: 'inlist',
6935 intercept: 'intercept',
6936 k1: 'k1',
6937 k2: 'k2',
6938 k3: 'k3',
6939 k4: 'k4',
6940 k: 'k',
6941 kernelmatrix: 'kernelMatrix',
6942 kernelunitlength: 'kernelUnitLength',
6943 kerning: 'kerning',
6944 keypoints: 'keyPoints',
6945 keysplines: 'keySplines',
6946 keytimes: 'keyTimes',
6947 lengthadjust: 'lengthAdjust',
6948 letterspacing: 'letterSpacing',
6949 'letter-spacing': 'letterSpacing',
6950 lightingcolor: 'lightingColor',
6951 'lighting-color': 'lightingColor',
6952 limitingconeangle: 'limitingConeAngle',
6953 local: 'local',
6954 markerend: 'markerEnd',
6955 'marker-end': 'markerEnd',
6956 markerheight: 'markerHeight',
6957 markermid: 'markerMid',
6958 'marker-mid': 'markerMid',
6959 markerstart: 'markerStart',
6960 'marker-start': 'markerStart',
6961 markerunits: 'markerUnits',
6962 markerwidth: 'markerWidth',
6963 mask: 'mask',
6964 maskcontentunits: 'maskContentUnits',
6965 maskunits: 'maskUnits',
6966 mathematical: 'mathematical',
6967 mode: 'mode',
6968 numoctaves: 'numOctaves',
6969 offset: 'offset',
6970 opacity: 'opacity',
6971 operator: 'operator',
6972 order: 'order',
6973 orient: 'orient',
6974 orientation: 'orientation',
6975 origin: 'origin',
6976 overflow: 'overflow',
6977 overlineposition: 'overlinePosition',
6978 'overline-position': 'overlinePosition',
6979 overlinethickness: 'overlineThickness',
6980 'overline-thickness': 'overlineThickness',
6981 paintorder: 'paintOrder',
6982 'paint-order': 'paintOrder',
6983 panose1: 'panose1',
6984 'panose-1': 'panose1',
6985 pathlength: 'pathLength',
6986 patterncontentunits: 'patternContentUnits',
6987 patterntransform: 'patternTransform',
6988 patternunits: 'patternUnits',
6989 pointerevents: 'pointerEvents',
6990 'pointer-events': 'pointerEvents',
6991 points: 'points',
6992 pointsatx: 'pointsAtX',
6993 pointsaty: 'pointsAtY',
6994 pointsatz: 'pointsAtZ',
6995 prefix: 'prefix',
6996 preservealpha: 'preserveAlpha',
6997 preserveaspectratio: 'preserveAspectRatio',
6998 primitiveunits: 'primitiveUnits',
6999 property: 'property',
7000 r: 'r',
7001 radius: 'radius',
7002 refx: 'refX',
7003 refy: 'refY',
7004 renderingintent: 'renderingIntent',
7005 'rendering-intent': 'renderingIntent',
7006 repeatcount: 'repeatCount',
7007 repeatdur: 'repeatDur',
7008 requiredextensions: 'requiredExtensions',
7009 requiredfeatures: 'requiredFeatures',
7010 resource: 'resource',
7011 restart: 'restart',
7012 result: 'result',
7013 results: 'results',
7014 rotate: 'rotate',
7015 rx: 'rx',
7016 ry: 'ry',
7017 scale: 'scale',
7018 security: 'security',
7019 seed: 'seed',
7020 shaperendering: 'shapeRendering',
7021 'shape-rendering': 'shapeRendering',
7022 slope: 'slope',
7023 spacing: 'spacing',
7024 specularconstant: 'specularConstant',
7025 specularexponent: 'specularExponent',
7026 speed: 'speed',
7027 spreadmethod: 'spreadMethod',
7028 startoffset: 'startOffset',
7029 stddeviation: 'stdDeviation',
7030 stemh: 'stemh',
7031 stemv: 'stemv',
7032 stitchtiles: 'stitchTiles',
7033 stopcolor: 'stopColor',
7034 'stop-color': 'stopColor',
7035 stopopacity: 'stopOpacity',
7036 'stop-opacity': 'stopOpacity',
7037 strikethroughposition: 'strikethroughPosition',
7038 'strikethrough-position': 'strikethroughPosition',
7039 strikethroughthickness: 'strikethroughThickness',
7040 'strikethrough-thickness': 'strikethroughThickness',
7041 string: 'string',
7042 stroke: 'stroke',
7043 strokedasharray: 'strokeDasharray',
7044 'stroke-dasharray': 'strokeDasharray',
7045 strokedashoffset: 'strokeDashoffset',
7046 'stroke-dashoffset': 'strokeDashoffset',
7047 strokelinecap: 'strokeLinecap',
7048 'stroke-linecap': 'strokeLinecap',
7049 strokelinejoin: 'strokeLinejoin',
7050 'stroke-linejoin': 'strokeLinejoin',
7051 strokemiterlimit: 'strokeMiterlimit',
7052 'stroke-miterlimit': 'strokeMiterlimit',
7053 strokewidth: 'strokeWidth',
7054 'stroke-width': 'strokeWidth',
7055 strokeopacity: 'strokeOpacity',
7056 'stroke-opacity': 'strokeOpacity',
7057 suppresscontenteditablewarning: 'suppressContentEditableWarning',
7058 suppresshydrationwarning: 'suppressHydrationWarning',
7059 surfacescale: 'surfaceScale',
7060 systemlanguage: 'systemLanguage',
7061 tablevalues: 'tableValues',
7062 targetx: 'targetX',
7063 targety: 'targetY',
7064 textanchor: 'textAnchor',
7065 'text-anchor': 'textAnchor',
7066 textdecoration: 'textDecoration',
7067 'text-decoration': 'textDecoration',
7068 textlength: 'textLength',
7069 textrendering: 'textRendering',
7070 'text-rendering': 'textRendering',
7071 to: 'to',
7072 transform: 'transform',
7073 typeof: 'typeof',
7074 u1: 'u1',
7075 u2: 'u2',
7076 underlineposition: 'underlinePosition',
7077 'underline-position': 'underlinePosition',
7078 underlinethickness: 'underlineThickness',
7079 'underline-thickness': 'underlineThickness',
7080 unicode: 'unicode',
7081 unicodebidi: 'unicodeBidi',
7082 'unicode-bidi': 'unicodeBidi',
7083 unicoderange: 'unicodeRange',
7084 'unicode-range': 'unicodeRange',
7085 unitsperem: 'unitsPerEm',
7086 'units-per-em': 'unitsPerEm',
7087 unselectable: 'unselectable',
7088 valphabetic: 'vAlphabetic',
7089 'v-alphabetic': 'vAlphabetic',
7090 values: 'values',
7091 vectoreffect: 'vectorEffect',
7092 'vector-effect': 'vectorEffect',
7093 version: 'version',
7094 vertadvy: 'vertAdvY',
7095 'vert-adv-y': 'vertAdvY',
7096 vertoriginx: 'vertOriginX',
7097 'vert-origin-x': 'vertOriginX',
7098 vertoriginy: 'vertOriginY',
7099 'vert-origin-y': 'vertOriginY',
7100 vhanging: 'vHanging',
7101 'v-hanging': 'vHanging',
7102 videographic: 'vIdeographic',
7103 'v-ideographic': 'vIdeographic',
7104 viewbox: 'viewBox',
7105 viewtarget: 'viewTarget',
7106 visibility: 'visibility',
7107 vmathematical: 'vMathematical',
7108 'v-mathematical': 'vMathematical',
7109 vocab: 'vocab',
7110 widths: 'widths',
7111 wordspacing: 'wordSpacing',
7112 'word-spacing': 'wordSpacing',
7113 writingmode: 'writingMode',
7114 'writing-mode': 'writingMode',
7115 x1: 'x1',
7116 x2: 'x2',
7117 x: 'x',
7118 xchannelselector: 'xChannelSelector',
7119 xheight: 'xHeight',
7120 'x-height': 'xHeight',
7121 xlinkactuate: 'xlinkActuate',
7122 'xlink:actuate': 'xlinkActuate',
7123 xlinkarcrole: 'xlinkArcrole',
7124 'xlink:arcrole': 'xlinkArcrole',
7125 xlinkhref: 'xlinkHref',
7126 'xlink:href': 'xlinkHref',
7127 xlinkrole: 'xlinkRole',
7128 'xlink:role': 'xlinkRole',
7129 xlinkshow: 'xlinkShow',
7130 'xlink:show': 'xlinkShow',
7131 xlinktitle: 'xlinkTitle',
7132 'xlink:title': 'xlinkTitle',
7133 xlinktype: 'xlinkType',
7134 'xlink:type': 'xlinkType',
7135 xmlbase: 'xmlBase',
7136 'xml:base': 'xmlBase',
7137 xmllang: 'xmlLang',
7138 'xml:lang': 'xmlLang',
7139 xmlns: 'xmlns',
7140 'xml:space': 'xmlSpace',
7141 xmlnsxlink: 'xmlnsXlink',
7142 'xmlns:xlink': 'xmlnsXlink',
7143 xmlspace: 'xmlSpace',
7144 y1: 'y1',
7145 y2: 'y2',
7146 y: 'y',
7147 ychannelselector: 'yChannelSelector',
7148 z: 'z',
7149 zoomandpan: 'zoomAndPan'
7150};
7151
7152var ariaProperties = {
7153 'aria-current': 0, // state
7154 'aria-details': 0,
7155 'aria-disabled': 0, // state
7156 'aria-hidden': 0, // state
7157 'aria-invalid': 0, // state
7158 'aria-keyshortcuts': 0,
7159 'aria-label': 0,
7160 'aria-roledescription': 0,
7161 // Widget Attributes
7162 'aria-autocomplete': 0,
7163 'aria-checked': 0,
7164 'aria-expanded': 0,
7165 'aria-haspopup': 0,
7166 'aria-level': 0,
7167 'aria-modal': 0,
7168 'aria-multiline': 0,
7169 'aria-multiselectable': 0,
7170 'aria-orientation': 0,
7171 'aria-placeholder': 0,
7172 'aria-pressed': 0,
7173 'aria-readonly': 0,
7174 'aria-required': 0,
7175 'aria-selected': 0,
7176 'aria-sort': 0,
7177 'aria-valuemax': 0,
7178 'aria-valuemin': 0,
7179 'aria-valuenow': 0,
7180 'aria-valuetext': 0,
7181 // Live Region Attributes
7182 'aria-atomic': 0,
7183 'aria-busy': 0,
7184 'aria-live': 0,
7185 'aria-relevant': 0,
7186 // Drag-and-Drop Attributes
7187 'aria-dropeffect': 0,
7188 'aria-grabbed': 0,
7189 // Relationship Attributes
7190 'aria-activedescendant': 0,
7191 'aria-colcount': 0,
7192 'aria-colindex': 0,
7193 'aria-colspan': 0,
7194 'aria-controls': 0,
7195 'aria-describedby': 0,
7196 'aria-errormessage': 0,
7197 'aria-flowto': 0,
7198 'aria-labelledby': 0,
7199 'aria-owns': 0,
7200 'aria-posinset': 0,
7201 'aria-rowcount': 0,
7202 'aria-rowindex': 0,
7203 'aria-rowspan': 0,
7204 'aria-setsize': 0
7205};
7206
7207var warnedProperties = {};
7208var rARIA = new RegExp('^(aria)-[' + ATTRIBUTE_NAME_CHAR + ']*$');
7209var rARIACamel = new RegExp('^(aria)[A-Z][' + ATTRIBUTE_NAME_CHAR + ']*$');
7210
7211var hasOwnProperty$2 = Object.prototype.hasOwnProperty;
7212
7213function validateProperty(tagName, name) {
7214 if (hasOwnProperty$2.call(warnedProperties, name) && warnedProperties[name]) {
7215 return true;
7216 }
7217
7218 if (rARIACamel.test(name)) {
7219 var ariaName = 'aria-' + name.slice(4).toLowerCase();
7220 var correctName = ariaProperties.hasOwnProperty(ariaName) ? ariaName : null;
7221
7222 // If this is an aria-* attribute, but is not listed in the known DOM
7223 // DOM properties, then it is an invalid aria-* attribute.
7224 if (correctName == null) {
7225 warning$1(false, 'Invalid ARIA attribute `%s`. ARIA attributes follow the pattern aria-* and must be lowercase.', name);
7226 warnedProperties[name] = true;
7227 return true;
7228 }
7229 // aria-* attributes should be lowercase; suggest the lowercase version.
7230 if (name !== correctName) {
7231 warning$1(false, 'Invalid ARIA attribute `%s`. Did you mean `%s`?', name, correctName);
7232 warnedProperties[name] = true;
7233 return true;
7234 }
7235 }
7236
7237 if (rARIA.test(name)) {
7238 var lowerCasedName = name.toLowerCase();
7239 var standardName = ariaProperties.hasOwnProperty(lowerCasedName) ? lowerCasedName : null;
7240
7241 // If this is an aria-* attribute, but is not listed in the known DOM
7242 // DOM properties, then it is an invalid aria-* attribute.
7243 if (standardName == null) {
7244 warnedProperties[name] = true;
7245 return false;
7246 }
7247 // aria-* attributes should be lowercase; suggest the lowercase version.
7248 if (name !== standardName) {
7249 warning$1(false, 'Unknown ARIA attribute `%s`. Did you mean `%s`?', name, standardName);
7250 warnedProperties[name] = true;
7251 return true;
7252 }
7253 }
7254
7255 return true;
7256}
7257
7258function warnInvalidARIAProps(type, props) {
7259 var invalidProps = [];
7260
7261 for (var key in props) {
7262 var isValid = validateProperty(type, key);
7263 if (!isValid) {
7264 invalidProps.push(key);
7265 }
7266 }
7267
7268 var unknownPropString = invalidProps.map(function (prop) {
7269 return '`' + prop + '`';
7270 }).join(', ');
7271
7272 if (invalidProps.length === 1) {
7273 warning$1(false, 'Invalid aria prop %s on <%s> tag. ' + 'For details, see https://fb.me/invalid-aria-prop', unknownPropString, type);
7274 } else if (invalidProps.length > 1) {
7275 warning$1(false, 'Invalid aria props %s on <%s> tag. ' + 'For details, see https://fb.me/invalid-aria-prop', unknownPropString, type);
7276 }
7277}
7278
7279function validateProperties(type, props) {
7280 if (isCustomComponent(type, props)) {
7281 return;
7282 }
7283 warnInvalidARIAProps(type, props);
7284}
7285
7286var didWarnValueNull = false;
7287
7288function validateProperties$1(type, props) {
7289 if (type !== 'input' && type !== 'textarea' && type !== 'select') {
7290 return;
7291 }
7292
7293 if (props != null && props.value === null && !didWarnValueNull) {
7294 didWarnValueNull = true;
7295 if (type === 'select' && props.multiple) {
7296 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);
7297 } else {
7298 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);
7299 }
7300 }
7301}
7302
7303var validateProperty$1 = function () {};
7304
7305{
7306 var warnedProperties$1 = {};
7307 var _hasOwnProperty = Object.prototype.hasOwnProperty;
7308 var EVENT_NAME_REGEX = /^on./;
7309 var INVALID_EVENT_NAME_REGEX = /^on[^A-Z]/;
7310 var rARIA$1 = new RegExp('^(aria)-[' + ATTRIBUTE_NAME_CHAR + ']*$');
7311 var rARIACamel$1 = new RegExp('^(aria)[A-Z][' + ATTRIBUTE_NAME_CHAR + ']*$');
7312
7313 validateProperty$1 = function (tagName, name, value, canUseEventSystem) {
7314 if (_hasOwnProperty.call(warnedProperties$1, name) && warnedProperties$1[name]) {
7315 return true;
7316 }
7317
7318 var lowerCasedName = name.toLowerCase();
7319 if (lowerCasedName === 'onfocusin' || lowerCasedName === 'onfocusout') {
7320 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.');
7321 warnedProperties$1[name] = true;
7322 return true;
7323 }
7324
7325 // We can't rely on the event system being injected on the server.
7326 if (canUseEventSystem) {
7327 if (registrationNameModules.hasOwnProperty(name)) {
7328 return true;
7329 }
7330 var registrationName = possibleRegistrationNames.hasOwnProperty(lowerCasedName) ? possibleRegistrationNames[lowerCasedName] : null;
7331 if (registrationName != null) {
7332 warning$1(false, 'Invalid event handler property `%s`. Did you mean `%s`?', name, registrationName);
7333 warnedProperties$1[name] = true;
7334 return true;
7335 }
7336 if (EVENT_NAME_REGEX.test(name)) {
7337 warning$1(false, 'Unknown event handler property `%s`. It will be ignored.', name);
7338 warnedProperties$1[name] = true;
7339 return true;
7340 }
7341 } else if (EVENT_NAME_REGEX.test(name)) {
7342 // If no event plugins have been injected, we are in a server environment.
7343 // So we can't tell if the event name is correct for sure, but we can filter
7344 // out known bad ones like `onclick`. We can't suggest a specific replacement though.
7345 if (INVALID_EVENT_NAME_REGEX.test(name)) {
7346 warning$1(false, 'Invalid event handler property `%s`. ' + 'React events use the camelCase naming convention, for example `onClick`.', name);
7347 }
7348 warnedProperties$1[name] = true;
7349 return true;
7350 }
7351
7352 // Let the ARIA attribute hook validate ARIA attributes
7353 if (rARIA$1.test(name) || rARIACamel$1.test(name)) {
7354 return true;
7355 }
7356
7357 if (lowerCasedName === 'innerhtml') {
7358 warning$1(false, 'Directly setting property `innerHTML` is not permitted. ' + 'For more information, lookup documentation on `dangerouslySetInnerHTML`.');
7359 warnedProperties$1[name] = true;
7360 return true;
7361 }
7362
7363 if (lowerCasedName === 'aria') {
7364 warning$1(false, 'The `aria` attribute is reserved for future use in React. ' + 'Pass individual `aria-` attributes instead.');
7365 warnedProperties$1[name] = true;
7366 return true;
7367 }
7368
7369 if (lowerCasedName === 'is' && value !== null && value !== undefined && typeof value !== 'string') {
7370 warning$1(false, 'Received a `%s` for a string attribute `is`. If this is expected, cast ' + 'the value to a string.', typeof value);
7371 warnedProperties$1[name] = true;
7372 return true;
7373 }
7374
7375 if (typeof value === 'number' && isNaN(value)) {
7376 warning$1(false, 'Received NaN for the `%s` attribute. If this is expected, cast ' + 'the value to a string.', name);
7377 warnedProperties$1[name] = true;
7378 return true;
7379 }
7380
7381 var propertyInfo = getPropertyInfo(name);
7382 var isReserved = propertyInfo !== null && propertyInfo.type === RESERVED;
7383
7384 // Known attributes should match the casing specified in the property config.
7385 if (possibleStandardNames.hasOwnProperty(lowerCasedName)) {
7386 var standardName = possibleStandardNames[lowerCasedName];
7387 if (standardName !== name) {
7388 warning$1(false, 'Invalid DOM property `%s`. Did you mean `%s`?', name, standardName);
7389 warnedProperties$1[name] = true;
7390 return true;
7391 }
7392 } else if (!isReserved && name !== lowerCasedName) {
7393 // Unknown attributes should have lowercase casing since that's how they
7394 // will be cased anyway with server rendering.
7395 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);
7396 warnedProperties$1[name] = true;
7397 return true;
7398 }
7399
7400 if (typeof value === 'boolean' && shouldRemoveAttributeWithWarning(name, value, propertyInfo, false)) {
7401 if (value) {
7402 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);
7403 } else {
7404 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);
7405 }
7406 warnedProperties$1[name] = true;
7407 return true;
7408 }
7409
7410 // Now that we've validated casing, do not validate
7411 // data types for reserved props
7412 if (isReserved) {
7413 return true;
7414 }
7415
7416 // Warn when a known attribute is a bad type
7417 if (shouldRemoveAttributeWithWarning(name, value, propertyInfo, false)) {
7418 warnedProperties$1[name] = true;
7419 return false;
7420 }
7421
7422 // Warn when passing the strings 'false' or 'true' into a boolean prop
7423 if ((value === 'false' || value === 'true') && propertyInfo !== null && propertyInfo.type === BOOLEAN) {
7424 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);
7425 warnedProperties$1[name] = true;
7426 return true;
7427 }
7428
7429 return true;
7430 };
7431}
7432
7433var warnUnknownProperties = function (type, props, canUseEventSystem) {
7434 var unknownProps = [];
7435 for (var key in props) {
7436 var isValid = validateProperty$1(type, key, props[key], canUseEventSystem);
7437 if (!isValid) {
7438 unknownProps.push(key);
7439 }
7440 }
7441
7442 var unknownPropString = unknownProps.map(function (prop) {
7443 return '`' + prop + '`';
7444 }).join(', ');
7445 if (unknownProps.length === 1) {
7446 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);
7447 } else if (unknownProps.length > 1) {
7448 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);
7449 }
7450};
7451
7452function validateProperties$2(type, props, canUseEventSystem) {
7453 if (isCustomComponent(type, props)) {
7454 return;
7455 }
7456 warnUnknownProperties(type, props, canUseEventSystem);
7457}
7458
7459// TODO: direct imports like some-package/src/* are bad. Fix me.
7460var didWarnInvalidHydration = false;
7461var didWarnShadyDOM = false;
7462
7463var DANGEROUSLY_SET_INNER_HTML = 'dangerouslySetInnerHTML';
7464var SUPPRESS_CONTENT_EDITABLE_WARNING = 'suppressContentEditableWarning';
7465var SUPPRESS_HYDRATION_WARNING$1 = 'suppressHydrationWarning';
7466var AUTOFOCUS = 'autoFocus';
7467var CHILDREN = 'children';
7468var STYLE$1 = 'style';
7469var HTML = '__html';
7470
7471var HTML_NAMESPACE = Namespaces.html;
7472
7473
7474var warnedUnknownTags = void 0;
7475var suppressHydrationWarning = void 0;
7476
7477var validatePropertiesInDevelopment = void 0;
7478var warnForTextDifference = void 0;
7479var warnForPropDifference = void 0;
7480var warnForExtraAttributes = void 0;
7481var warnForInvalidEventListener = void 0;
7482var canDiffStyleForHydrationWarning = void 0;
7483
7484var normalizeMarkupForTextOrAttribute = void 0;
7485var normalizeHTML = void 0;
7486
7487{
7488 warnedUnknownTags = {
7489 // Chrome is the only major browser not shipping <time>. But as of July
7490 // 2017 it intends to ship it due to widespread usage. We intentionally
7491 // *don't* warn for <time> even if it's unrecognized by Chrome because
7492 // it soon will be, and many apps have been using it anyway.
7493 time: true,
7494 // There are working polyfills for <dialog>. Let people use it.
7495 dialog: true,
7496 // Electron ships a custom <webview> tag to display external web content in
7497 // an isolated frame and process.
7498 // This tag is not present in non Electron environments such as JSDom which
7499 // is often used for testing purposes.
7500 // @see https://electronjs.org/docs/api/webview-tag
7501 webview: true
7502 };
7503
7504 validatePropertiesInDevelopment = function (type, props) {
7505 validateProperties(type, props);
7506 validateProperties$1(type, props);
7507 validateProperties$2(type, props, /* canUseEventSystem */true);
7508 };
7509
7510 // IE 11 parses & normalizes the style attribute as opposed to other
7511 // browsers. It adds spaces and sorts the properties in some
7512 // non-alphabetical order. Handling that would require sorting CSS
7513 // properties in the client & server versions or applying
7514 // `expectedStyle` to a temporary DOM node to read its `style` attribute
7515 // normalized. Since it only affects IE, we're skipping style warnings
7516 // in that browser completely in favor of doing all that work.
7517 // See https://github.com/facebook/react/issues/11807
7518 canDiffStyleForHydrationWarning = canUseDOM && !document.documentMode;
7519
7520 // HTML parsing normalizes CR and CRLF to LF.
7521 // It also can turn \u0000 into \uFFFD inside attributes.
7522 // https://www.w3.org/TR/html5/single-page.html#preprocessing-the-input-stream
7523 // If we have a mismatch, it might be caused by that.
7524 // We will still patch up in this case but not fire the warning.
7525 var NORMALIZE_NEWLINES_REGEX = /\r\n?/g;
7526 var NORMALIZE_NULL_AND_REPLACEMENT_REGEX = /\u0000|\uFFFD/g;
7527
7528 normalizeMarkupForTextOrAttribute = function (markup) {
7529 var markupString = typeof markup === 'string' ? markup : '' + markup;
7530 return markupString.replace(NORMALIZE_NEWLINES_REGEX, '\n').replace(NORMALIZE_NULL_AND_REPLACEMENT_REGEX, '');
7531 };
7532
7533 warnForTextDifference = function (serverText, clientText) {
7534 if (didWarnInvalidHydration) {
7535 return;
7536 }
7537 var normalizedClientText = normalizeMarkupForTextOrAttribute(clientText);
7538 var normalizedServerText = normalizeMarkupForTextOrAttribute(serverText);
7539 if (normalizedServerText === normalizedClientText) {
7540 return;
7541 }
7542 didWarnInvalidHydration = true;
7543 warningWithoutStack$1(false, 'Text content did not match. Server: "%s" Client: "%s"', normalizedServerText, normalizedClientText);
7544 };
7545
7546 warnForPropDifference = function (propName, serverValue, clientValue) {
7547 if (didWarnInvalidHydration) {
7548 return;
7549 }
7550 var normalizedClientValue = normalizeMarkupForTextOrAttribute(clientValue);
7551 var normalizedServerValue = normalizeMarkupForTextOrAttribute(serverValue);
7552 if (normalizedServerValue === normalizedClientValue) {
7553 return;
7554 }
7555 didWarnInvalidHydration = true;
7556 warningWithoutStack$1(false, 'Prop `%s` did not match. Server: %s Client: %s', propName, JSON.stringify(normalizedServerValue), JSON.stringify(normalizedClientValue));
7557 };
7558
7559 warnForExtraAttributes = function (attributeNames) {
7560 if (didWarnInvalidHydration) {
7561 return;
7562 }
7563 didWarnInvalidHydration = true;
7564 var names = [];
7565 attributeNames.forEach(function (name) {
7566 names.push(name);
7567 });
7568 warningWithoutStack$1(false, 'Extra attributes from the server: %s', names);
7569 };
7570
7571 warnForInvalidEventListener = function (registrationName, listener) {
7572 if (listener === false) {
7573 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);
7574 } else {
7575 warning$1(false, 'Expected `%s` listener to be a function, instead got a value of `%s` type.', registrationName, typeof listener);
7576 }
7577 };
7578
7579 // Parse the HTML and read it back to normalize the HTML string so that it
7580 // can be used for comparison.
7581 normalizeHTML = function (parent, html) {
7582 // We could have created a separate document here to avoid
7583 // re-initializing custom elements if they exist. But this breaks
7584 // how <noscript> is being handled. So we use the same document.
7585 // See the discussion in https://github.com/facebook/react/pull/11157.
7586 var testElement = parent.namespaceURI === HTML_NAMESPACE ? parent.ownerDocument.createElement(parent.tagName) : parent.ownerDocument.createElementNS(parent.namespaceURI, parent.tagName);
7587 testElement.innerHTML = html;
7588 return testElement.innerHTML;
7589 };
7590}
7591
7592function ensureListeningTo(rootContainerElement, registrationName) {
7593 var isDocumentOrFragment = rootContainerElement.nodeType === DOCUMENT_NODE || rootContainerElement.nodeType === DOCUMENT_FRAGMENT_NODE;
7594 var doc = isDocumentOrFragment ? rootContainerElement : rootContainerElement.ownerDocument;
7595 listenTo(registrationName, doc);
7596}
7597
7598function getOwnerDocumentFromRootContainer(rootContainerElement) {
7599 return rootContainerElement.nodeType === DOCUMENT_NODE ? rootContainerElement : rootContainerElement.ownerDocument;
7600}
7601
7602function noop() {}
7603
7604function trapClickOnNonInteractiveElement(node) {
7605 // Mobile Safari does not fire properly bubble click events on
7606 // non-interactive elements, which means delegated click listeners do not
7607 // fire. The workaround for this bug involves attaching an empty click
7608 // listener on the target node.
7609 // http://www.quirksmode.org/blog/archives/2010/09/click_event_del.html
7610 // Just set it using the onclick property so that we don't have to manage any
7611 // bookkeeping for it. Not sure if we need to clear it when the listener is
7612 // removed.
7613 // TODO: Only do this for the relevant Safaris maybe?
7614 node.onclick = noop;
7615}
7616
7617function setInitialDOMProperties(tag, domElement, rootContainerElement, nextProps, isCustomComponentTag) {
7618 for (var propKey in nextProps) {
7619 if (!nextProps.hasOwnProperty(propKey)) {
7620 continue;
7621 }
7622 var nextProp = nextProps[propKey];
7623 if (propKey === STYLE$1) {
7624 {
7625 if (nextProp) {
7626 // Freeze the next style object so that we can assume it won't be
7627 // mutated. We have already warned for this in the past.
7628 Object.freeze(nextProp);
7629 }
7630 }
7631 // Relies on `updateStylesByID` not mutating `styleUpdates`.
7632 setValueForStyles(domElement, nextProp);
7633 } else if (propKey === DANGEROUSLY_SET_INNER_HTML) {
7634 var nextHtml = nextProp ? nextProp[HTML] : undefined;
7635 if (nextHtml != null) {
7636 setInnerHTML(domElement, nextHtml);
7637 }
7638 } else if (propKey === CHILDREN) {
7639 if (typeof nextProp === 'string') {
7640 // Avoid setting initial textContent when the text is empty. In IE11 setting
7641 // textContent on a <textarea> will cause the placeholder to not
7642 // show within the <textarea> until it has been focused and blurred again.
7643 // https://github.com/facebook/react/issues/6731#issuecomment-254874553
7644 var canSetTextContent = tag !== 'textarea' || nextProp !== '';
7645 if (canSetTextContent) {
7646 setTextContent(domElement, nextProp);
7647 }
7648 } else if (typeof nextProp === 'number') {
7649 setTextContent(domElement, '' + nextProp);
7650 }
7651 } else if (propKey === SUPPRESS_CONTENT_EDITABLE_WARNING || propKey === SUPPRESS_HYDRATION_WARNING$1) {
7652 // Noop
7653 } else if (propKey === AUTOFOCUS) {
7654 // We polyfill it separately on the client during commit.
7655 // We could have excluded it in the property list instead of
7656 // adding a special case here, but then it wouldn't be emitted
7657 // on server rendering (but we *do* want to emit it in SSR).
7658 } else if (registrationNameModules.hasOwnProperty(propKey)) {
7659 if (nextProp != null) {
7660 if (true && typeof nextProp !== 'function') {
7661 warnForInvalidEventListener(propKey, nextProp);
7662 }
7663 ensureListeningTo(rootContainerElement, propKey);
7664 }
7665 } else if (nextProp != null) {
7666 setValueForProperty(domElement, propKey, nextProp, isCustomComponentTag);
7667 }
7668 }
7669}
7670
7671function updateDOMProperties(domElement, updatePayload, wasCustomComponentTag, isCustomComponentTag) {
7672 // TODO: Handle wasCustomComponentTag
7673 for (var i = 0; i < updatePayload.length; i += 2) {
7674 var propKey = updatePayload[i];
7675 var propValue = updatePayload[i + 1];
7676 if (propKey === STYLE$1) {
7677 setValueForStyles(domElement, propValue);
7678 } else if (propKey === DANGEROUSLY_SET_INNER_HTML) {
7679 setInnerHTML(domElement, propValue);
7680 } else if (propKey === CHILDREN) {
7681 setTextContent(domElement, propValue);
7682 } else {
7683 setValueForProperty(domElement, propKey, propValue, isCustomComponentTag);
7684 }
7685 }
7686}
7687
7688function createElement(type, props, rootContainerElement, parentNamespace) {
7689 var isCustomComponentTag = void 0;
7690
7691 // We create tags in the namespace of their parent container, except HTML
7692 // tags get no namespace.
7693 var ownerDocument = getOwnerDocumentFromRootContainer(rootContainerElement);
7694 var domElement = void 0;
7695 var namespaceURI = parentNamespace;
7696 if (namespaceURI === HTML_NAMESPACE) {
7697 namespaceURI = getIntrinsicNamespace(type);
7698 }
7699 if (namespaceURI === HTML_NAMESPACE) {
7700 {
7701 isCustomComponentTag = isCustomComponent(type, props);
7702 // Should this check be gated by parent namespace? Not sure we want to
7703 // allow <SVG> or <mATH>.
7704 !(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;
7705 }
7706
7707 if (type === 'script') {
7708 // Create the script via .innerHTML so its "parser-inserted" flag is
7709 // set to true and it does not execute
7710 var div = ownerDocument.createElement('div');
7711 div.innerHTML = '<script><' + '/script>'; // eslint-disable-line
7712 // This is guaranteed to yield a script element.
7713 var firstChild = div.firstChild;
7714 domElement = div.removeChild(firstChild);
7715 } else if (typeof props.is === 'string') {
7716 // $FlowIssue `createElement` should be updated for Web Components
7717 domElement = ownerDocument.createElement(type, { is: props.is });
7718 } else {
7719 // Separate else branch instead of using `props.is || undefined` above because of a Firefox bug.
7720 // See discussion in https://github.com/facebook/react/pull/6896
7721 // and discussion in https://bugzilla.mozilla.org/show_bug.cgi?id=1276240
7722 domElement = ownerDocument.createElement(type);
7723 // Normally attributes are assigned in `setInitialDOMProperties`, however the `multiple`
7724 // attribute on `select`s needs to be added before `option`s are inserted. This prevents
7725 // a bug where the `select` does not scroll to the correct option because singular
7726 // `select` elements automatically pick the first item.
7727 // See https://github.com/facebook/react/issues/13222
7728 if (type === 'select' && props.multiple) {
7729 var node = domElement;
7730 node.multiple = true;
7731 }
7732 }
7733 } else {
7734 domElement = ownerDocument.createElementNS(namespaceURI, type);
7735 }
7736
7737 {
7738 if (namespaceURI === HTML_NAMESPACE) {
7739 if (!isCustomComponentTag && Object.prototype.toString.call(domElement) === '[object HTMLUnknownElement]' && !Object.prototype.hasOwnProperty.call(warnedUnknownTags, type)) {
7740 warnedUnknownTags[type] = true;
7741 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);
7742 }
7743 }
7744 }
7745
7746 return domElement;
7747}
7748
7749function createTextNode(text, rootContainerElement) {
7750 return getOwnerDocumentFromRootContainer(rootContainerElement).createTextNode(text);
7751}
7752
7753function setInitialProperties(domElement, tag, rawProps, rootContainerElement) {
7754 var isCustomComponentTag = isCustomComponent(tag, rawProps);
7755 {
7756 validatePropertiesInDevelopment(tag, rawProps);
7757 if (isCustomComponentTag && !didWarnShadyDOM && domElement.shadyRoot) {
7758 warning$1(false, '%s is using shady DOM. Using shady DOM with React can ' + 'cause things to break subtly.', getCurrentFiberOwnerNameInDevOrNull() || 'A component');
7759 didWarnShadyDOM = true;
7760 }
7761 }
7762
7763 // TODO: Make sure that we check isMounted before firing any of these events.
7764 var props = void 0;
7765 switch (tag) {
7766 case 'iframe':
7767 case 'object':
7768 trapBubbledEvent(TOP_LOAD, domElement);
7769 props = rawProps;
7770 break;
7771 case 'video':
7772 case 'audio':
7773 // Create listener for each media event
7774 for (var i = 0; i < mediaEventTypes.length; i++) {
7775 trapBubbledEvent(mediaEventTypes[i], domElement);
7776 }
7777 props = rawProps;
7778 break;
7779 case 'source':
7780 trapBubbledEvent(TOP_ERROR, domElement);
7781 props = rawProps;
7782 break;
7783 case 'img':
7784 case 'image':
7785 case 'link':
7786 trapBubbledEvent(TOP_ERROR, domElement);
7787 trapBubbledEvent(TOP_LOAD, domElement);
7788 props = rawProps;
7789 break;
7790 case 'form':
7791 trapBubbledEvent(TOP_RESET, domElement);
7792 trapBubbledEvent(TOP_SUBMIT, domElement);
7793 props = rawProps;
7794 break;
7795 case 'details':
7796 trapBubbledEvent(TOP_TOGGLE, domElement);
7797 props = rawProps;
7798 break;
7799 case 'input':
7800 initWrapperState(domElement, rawProps);
7801 props = getHostProps(domElement, rawProps);
7802 trapBubbledEvent(TOP_INVALID, domElement);
7803 // For controlled components we always need to ensure we're listening
7804 // to onChange. Even if there is no listener.
7805 ensureListeningTo(rootContainerElement, 'onChange');
7806 break;
7807 case 'option':
7808 validateProps(domElement, rawProps);
7809 props = getHostProps$1(domElement, rawProps);
7810 break;
7811 case 'select':
7812 initWrapperState$1(domElement, rawProps);
7813 props = getHostProps$2(domElement, rawProps);
7814 trapBubbledEvent(TOP_INVALID, domElement);
7815 // For controlled components we always need to ensure we're listening
7816 // to onChange. Even if there is no listener.
7817 ensureListeningTo(rootContainerElement, 'onChange');
7818 break;
7819 case 'textarea':
7820 initWrapperState$2(domElement, rawProps);
7821 props = getHostProps$3(domElement, rawProps);
7822 trapBubbledEvent(TOP_INVALID, domElement);
7823 // For controlled components we always need to ensure we're listening
7824 // to onChange. Even if there is no listener.
7825 ensureListeningTo(rootContainerElement, 'onChange');
7826 break;
7827 default:
7828 props = rawProps;
7829 }
7830
7831 assertValidProps(tag, props);
7832
7833 setInitialDOMProperties(tag, domElement, rootContainerElement, props, isCustomComponentTag);
7834
7835 switch (tag) {
7836 case 'input':
7837 // TODO: Make sure we check if this is still unmounted or do any clean
7838 // up necessary since we never stop tracking anymore.
7839 track(domElement);
7840 postMountWrapper(domElement, rawProps, false);
7841 break;
7842 case 'textarea':
7843 // TODO: Make sure we check if this is still unmounted or do any clean
7844 // up necessary since we never stop tracking anymore.
7845 track(domElement);
7846 postMountWrapper$3(domElement, rawProps);
7847 break;
7848 case 'option':
7849 postMountWrapper$1(domElement, rawProps);
7850 break;
7851 case 'select':
7852 postMountWrapper$2(domElement, rawProps);
7853 break;
7854 default:
7855 if (typeof props.onClick === 'function') {
7856 // TODO: This cast may not be sound for SVG, MathML or custom elements.
7857 trapClickOnNonInteractiveElement(domElement);
7858 }
7859 break;
7860 }
7861}
7862
7863// Calculate the diff between the two objects.
7864function diffProperties(domElement, tag, lastRawProps, nextRawProps, rootContainerElement) {
7865 {
7866 validatePropertiesInDevelopment(tag, nextRawProps);
7867 }
7868
7869 var updatePayload = null;
7870
7871 var lastProps = void 0;
7872 var nextProps = void 0;
7873 switch (tag) {
7874 case 'input':
7875 lastProps = getHostProps(domElement, lastRawProps);
7876 nextProps = getHostProps(domElement, nextRawProps);
7877 updatePayload = [];
7878 break;
7879 case 'option':
7880 lastProps = getHostProps$1(domElement, lastRawProps);
7881 nextProps = getHostProps$1(domElement, nextRawProps);
7882 updatePayload = [];
7883 break;
7884 case 'select':
7885 lastProps = getHostProps$2(domElement, lastRawProps);
7886 nextProps = getHostProps$2(domElement, nextRawProps);
7887 updatePayload = [];
7888 break;
7889 case 'textarea':
7890 lastProps = getHostProps$3(domElement, lastRawProps);
7891 nextProps = getHostProps$3(domElement, nextRawProps);
7892 updatePayload = [];
7893 break;
7894 default:
7895 lastProps = lastRawProps;
7896 nextProps = nextRawProps;
7897 if (typeof lastProps.onClick !== 'function' && typeof nextProps.onClick === 'function') {
7898 // TODO: This cast may not be sound for SVG, MathML or custom elements.
7899 trapClickOnNonInteractiveElement(domElement);
7900 }
7901 break;
7902 }
7903
7904 assertValidProps(tag, nextProps);
7905
7906 var propKey = void 0;
7907 var styleName = void 0;
7908 var styleUpdates = null;
7909 for (propKey in lastProps) {
7910 if (nextProps.hasOwnProperty(propKey) || !lastProps.hasOwnProperty(propKey) || lastProps[propKey] == null) {
7911 continue;
7912 }
7913 if (propKey === STYLE$1) {
7914 var lastStyle = lastProps[propKey];
7915 for (styleName in lastStyle) {
7916 if (lastStyle.hasOwnProperty(styleName)) {
7917 if (!styleUpdates) {
7918 styleUpdates = {};
7919 }
7920 styleUpdates[styleName] = '';
7921 }
7922 }
7923 } else if (propKey === DANGEROUSLY_SET_INNER_HTML || propKey === CHILDREN) {
7924 // Noop. This is handled by the clear text mechanism.
7925 } else if (propKey === SUPPRESS_CONTENT_EDITABLE_WARNING || propKey === SUPPRESS_HYDRATION_WARNING$1) {
7926 // Noop
7927 } else if (propKey === AUTOFOCUS) {
7928 // Noop. It doesn't work on updates anyway.
7929 } else if (registrationNameModules.hasOwnProperty(propKey)) {
7930 // This is a special case. If any listener updates we need to ensure
7931 // that the "current" fiber pointer gets updated so we need a commit
7932 // to update this element.
7933 if (!updatePayload) {
7934 updatePayload = [];
7935 }
7936 } else {
7937 // For all other deleted properties we add it to the queue. We use
7938 // the whitelist in the commit phase instead.
7939 (updatePayload = updatePayload || []).push(propKey, null);
7940 }
7941 }
7942 for (propKey in nextProps) {
7943 var nextProp = nextProps[propKey];
7944 var lastProp = lastProps != null ? lastProps[propKey] : undefined;
7945 if (!nextProps.hasOwnProperty(propKey) || nextProp === lastProp || nextProp == null && lastProp == null) {
7946 continue;
7947 }
7948 if (propKey === STYLE$1) {
7949 {
7950 if (nextProp) {
7951 // Freeze the next style object so that we can assume it won't be
7952 // mutated. We have already warned for this in the past.
7953 Object.freeze(nextProp);
7954 }
7955 }
7956 if (lastProp) {
7957 // Unset styles on `lastProp` but not on `nextProp`.
7958 for (styleName in lastProp) {
7959 if (lastProp.hasOwnProperty(styleName) && (!nextProp || !nextProp.hasOwnProperty(styleName))) {
7960 if (!styleUpdates) {
7961 styleUpdates = {};
7962 }
7963 styleUpdates[styleName] = '';
7964 }
7965 }
7966 // Update styles that changed since `lastProp`.
7967 for (styleName in nextProp) {
7968 if (nextProp.hasOwnProperty(styleName) && lastProp[styleName] !== nextProp[styleName]) {
7969 if (!styleUpdates) {
7970 styleUpdates = {};
7971 }
7972 styleUpdates[styleName] = nextProp[styleName];
7973 }
7974 }
7975 } else {
7976 // Relies on `updateStylesByID` not mutating `styleUpdates`.
7977 if (!styleUpdates) {
7978 if (!updatePayload) {
7979 updatePayload = [];
7980 }
7981 updatePayload.push(propKey, styleUpdates);
7982 }
7983 styleUpdates = nextProp;
7984 }
7985 } else if (propKey === DANGEROUSLY_SET_INNER_HTML) {
7986 var nextHtml = nextProp ? nextProp[HTML] : undefined;
7987 var lastHtml = lastProp ? lastProp[HTML] : undefined;
7988 if (nextHtml != null) {
7989 if (lastHtml !== nextHtml) {
7990 (updatePayload = updatePayload || []).push(propKey, '' + nextHtml);
7991 }
7992 } else {
7993 // TODO: It might be too late to clear this if we have children
7994 // inserted already.
7995 }
7996 } else if (propKey === CHILDREN) {
7997 if (lastProp !== nextProp && (typeof nextProp === 'string' || typeof nextProp === 'number')) {
7998 (updatePayload = updatePayload || []).push(propKey, '' + nextProp);
7999 }
8000 } else if (propKey === SUPPRESS_CONTENT_EDITABLE_WARNING || propKey === SUPPRESS_HYDRATION_WARNING$1) {
8001 // Noop
8002 } else if (registrationNameModules.hasOwnProperty(propKey)) {
8003 if (nextProp != null) {
8004 // We eagerly listen to this even though we haven't committed yet.
8005 if (true && typeof nextProp !== 'function') {
8006 warnForInvalidEventListener(propKey, nextProp);
8007 }
8008 ensureListeningTo(rootContainerElement, propKey);
8009 }
8010 if (!updatePayload && lastProp !== nextProp) {
8011 // This is a special case. If any listener updates we need to ensure
8012 // that the "current" props pointer gets updated so we need a commit
8013 // to update this element.
8014 updatePayload = [];
8015 }
8016 } else {
8017 // For any other property we always add it to the queue and then we
8018 // filter it out using the whitelist during the commit.
8019 (updatePayload = updatePayload || []).push(propKey, nextProp);
8020 }
8021 }
8022 if (styleUpdates) {
8023 {
8024 validateShorthandPropertyCollisionInDev(styleUpdates, nextProps[STYLE$1]);
8025 }
8026 (updatePayload = updatePayload || []).push(STYLE$1, styleUpdates);
8027 }
8028 return updatePayload;
8029}
8030
8031// Apply the diff.
8032function updateProperties(domElement, updatePayload, tag, lastRawProps, nextRawProps) {
8033 // Update checked *before* name.
8034 // In the middle of an update, it is possible to have multiple checked.
8035 // When a checked radio tries to change name, browser makes another radio's checked false.
8036 if (tag === 'input' && nextRawProps.type === 'radio' && nextRawProps.name != null) {
8037 updateChecked(domElement, nextRawProps);
8038 }
8039
8040 var wasCustomComponentTag = isCustomComponent(tag, lastRawProps);
8041 var isCustomComponentTag = isCustomComponent(tag, nextRawProps);
8042 // Apply the diff.
8043 updateDOMProperties(domElement, updatePayload, wasCustomComponentTag, isCustomComponentTag);
8044
8045 // TODO: Ensure that an update gets scheduled if any of the special props
8046 // changed.
8047 switch (tag) {
8048 case 'input':
8049 // Update the wrapper around inputs *after* updating props. This has to
8050 // happen after `updateDOMProperties`. Otherwise HTML5 input validations
8051 // raise warnings and prevent the new value from being assigned.
8052 updateWrapper(domElement, nextRawProps);
8053 break;
8054 case 'textarea':
8055 updateWrapper$1(domElement, nextRawProps);
8056 break;
8057 case 'select':
8058 // <select> value update needs to occur after <option> children
8059 // reconciliation
8060 postUpdateWrapper(domElement, nextRawProps);
8061 break;
8062 }
8063}
8064
8065function getPossibleStandardName(propName) {
8066 {
8067 var lowerCasedName = propName.toLowerCase();
8068 if (!possibleStandardNames.hasOwnProperty(lowerCasedName)) {
8069 return null;
8070 }
8071 return possibleStandardNames[lowerCasedName] || null;
8072 }
8073 return null;
8074}
8075
8076function diffHydratedProperties(domElement, tag, rawProps, parentNamespace, rootContainerElement) {
8077 var isCustomComponentTag = void 0;
8078 var extraAttributeNames = void 0;
8079
8080 {
8081 suppressHydrationWarning = rawProps[SUPPRESS_HYDRATION_WARNING$1] === true;
8082 isCustomComponentTag = isCustomComponent(tag, rawProps);
8083 validatePropertiesInDevelopment(tag, rawProps);
8084 if (isCustomComponentTag && !didWarnShadyDOM && domElement.shadyRoot) {
8085 warning$1(false, '%s is using shady DOM. Using shady DOM with React can ' + 'cause things to break subtly.', getCurrentFiberOwnerNameInDevOrNull() || 'A component');
8086 didWarnShadyDOM = true;
8087 }
8088 }
8089
8090 // TODO: Make sure that we check isMounted before firing any of these events.
8091 switch (tag) {
8092 case 'iframe':
8093 case 'object':
8094 trapBubbledEvent(TOP_LOAD, domElement);
8095 break;
8096 case 'video':
8097 case 'audio':
8098 // Create listener for each media event
8099 for (var i = 0; i < mediaEventTypes.length; i++) {
8100 trapBubbledEvent(mediaEventTypes[i], domElement);
8101 }
8102 break;
8103 case 'source':
8104 trapBubbledEvent(TOP_ERROR, domElement);
8105 break;
8106 case 'img':
8107 case 'image':
8108 case 'link':
8109 trapBubbledEvent(TOP_ERROR, domElement);
8110 trapBubbledEvent(TOP_LOAD, domElement);
8111 break;
8112 case 'form':
8113 trapBubbledEvent(TOP_RESET, domElement);
8114 trapBubbledEvent(TOP_SUBMIT, domElement);
8115 break;
8116 case 'details':
8117 trapBubbledEvent(TOP_TOGGLE, domElement);
8118 break;
8119 case 'input':
8120 initWrapperState(domElement, rawProps);
8121 trapBubbledEvent(TOP_INVALID, domElement);
8122 // For controlled components we always need to ensure we're listening
8123 // to onChange. Even if there is no listener.
8124 ensureListeningTo(rootContainerElement, 'onChange');
8125 break;
8126 case 'option':
8127 validateProps(domElement, rawProps);
8128 break;
8129 case 'select':
8130 initWrapperState$1(domElement, rawProps);
8131 trapBubbledEvent(TOP_INVALID, domElement);
8132 // For controlled components we always need to ensure we're listening
8133 // to onChange. Even if there is no listener.
8134 ensureListeningTo(rootContainerElement, 'onChange');
8135 break;
8136 case 'textarea':
8137 initWrapperState$2(domElement, rawProps);
8138 trapBubbledEvent(TOP_INVALID, domElement);
8139 // For controlled components we always need to ensure we're listening
8140 // to onChange. Even if there is no listener.
8141 ensureListeningTo(rootContainerElement, 'onChange');
8142 break;
8143 }
8144
8145 assertValidProps(tag, rawProps);
8146
8147 {
8148 extraAttributeNames = new Set();
8149 var attributes = domElement.attributes;
8150 for (var _i = 0; _i < attributes.length; _i++) {
8151 var name = attributes[_i].name.toLowerCase();
8152 switch (name) {
8153 // Built-in SSR attribute is whitelisted
8154 case 'data-reactroot':
8155 break;
8156 // Controlled attributes are not validated
8157 // TODO: Only ignore them on controlled tags.
8158 case 'value':
8159 break;
8160 case 'checked':
8161 break;
8162 case 'selected':
8163 break;
8164 default:
8165 // Intentionally use the original name.
8166 // See discussion in https://github.com/facebook/react/pull/10676.
8167 extraAttributeNames.add(attributes[_i].name);
8168 }
8169 }
8170 }
8171
8172 var updatePayload = null;
8173 for (var propKey in rawProps) {
8174 if (!rawProps.hasOwnProperty(propKey)) {
8175 continue;
8176 }
8177 var nextProp = rawProps[propKey];
8178 if (propKey === CHILDREN) {
8179 // For text content children we compare against textContent. This
8180 // might match additional HTML that is hidden when we read it using
8181 // textContent. E.g. "foo" will match "f<span>oo</span>" but that still
8182 // satisfies our requirement. Our requirement is not to produce perfect
8183 // HTML and attributes. Ideally we should preserve structure but it's
8184 // ok not to if the visible content is still enough to indicate what
8185 // even listeners these nodes might be wired up to.
8186 // TODO: Warn if there is more than a single textNode as a child.
8187 // TODO: Should we use domElement.firstChild.nodeValue to compare?
8188 if (typeof nextProp === 'string') {
8189 if (domElement.textContent !== nextProp) {
8190 if (true && !suppressHydrationWarning) {
8191 warnForTextDifference(domElement.textContent, nextProp);
8192 }
8193 updatePayload = [CHILDREN, nextProp];
8194 }
8195 } else if (typeof nextProp === 'number') {
8196 if (domElement.textContent !== '' + nextProp) {
8197 if (true && !suppressHydrationWarning) {
8198 warnForTextDifference(domElement.textContent, nextProp);
8199 }
8200 updatePayload = [CHILDREN, '' + nextProp];
8201 }
8202 }
8203 } else if (registrationNameModules.hasOwnProperty(propKey)) {
8204 if (nextProp != null) {
8205 if (true && typeof nextProp !== 'function') {
8206 warnForInvalidEventListener(propKey, nextProp);
8207 }
8208 ensureListeningTo(rootContainerElement, propKey);
8209 }
8210 } else if (true &&
8211 // Convince Flow we've calculated it (it's DEV-only in this method.)
8212 typeof isCustomComponentTag === 'boolean') {
8213 // Validate that the properties correspond to their expected values.
8214 var serverValue = void 0;
8215 var propertyInfo = getPropertyInfo(propKey);
8216 if (suppressHydrationWarning) {
8217 // Don't bother comparing. We're ignoring all these warnings.
8218 } else if (propKey === SUPPRESS_CONTENT_EDITABLE_WARNING || propKey === SUPPRESS_HYDRATION_WARNING$1 ||
8219 // Controlled attributes are not validated
8220 // TODO: Only ignore them on controlled tags.
8221 propKey === 'value' || propKey === 'checked' || propKey === 'selected') {
8222 // Noop
8223 } else if (propKey === DANGEROUSLY_SET_INNER_HTML) {
8224 var serverHTML = domElement.innerHTML;
8225 var nextHtml = nextProp ? nextProp[HTML] : undefined;
8226 var expectedHTML = normalizeHTML(domElement, nextHtml != null ? nextHtml : '');
8227 if (expectedHTML !== serverHTML) {
8228 warnForPropDifference(propKey, serverHTML, expectedHTML);
8229 }
8230 } else if (propKey === STYLE$1) {
8231 // $FlowFixMe - Should be inferred as not undefined.
8232 extraAttributeNames.delete(propKey);
8233
8234 if (canDiffStyleForHydrationWarning) {
8235 var expectedStyle = createDangerousStringForStyles(nextProp);
8236 serverValue = domElement.getAttribute('style');
8237 if (expectedStyle !== serverValue) {
8238 warnForPropDifference(propKey, serverValue, expectedStyle);
8239 }
8240 }
8241 } else if (isCustomComponentTag) {
8242 // $FlowFixMe - Should be inferred as not undefined.
8243 extraAttributeNames.delete(propKey.toLowerCase());
8244 serverValue = getValueForAttribute(domElement, propKey, nextProp);
8245
8246 if (nextProp !== serverValue) {
8247 warnForPropDifference(propKey, serverValue, nextProp);
8248 }
8249 } else if (!shouldIgnoreAttribute(propKey, propertyInfo, isCustomComponentTag) && !shouldRemoveAttribute(propKey, nextProp, propertyInfo, isCustomComponentTag)) {
8250 var isMismatchDueToBadCasing = false;
8251 if (propertyInfo !== null) {
8252 // $FlowFixMe - Should be inferred as not undefined.
8253 extraAttributeNames.delete(propertyInfo.attributeName);
8254 serverValue = getValueForProperty(domElement, propKey, nextProp, propertyInfo);
8255 } else {
8256 var ownNamespace = parentNamespace;
8257 if (ownNamespace === HTML_NAMESPACE) {
8258 ownNamespace = getIntrinsicNamespace(tag);
8259 }
8260 if (ownNamespace === HTML_NAMESPACE) {
8261 // $FlowFixMe - Should be inferred as not undefined.
8262 extraAttributeNames.delete(propKey.toLowerCase());
8263 } else {
8264 var standardName = getPossibleStandardName(propKey);
8265 if (standardName !== null && standardName !== propKey) {
8266 // If an SVG prop is supplied with bad casing, it will
8267 // be successfully parsed from HTML, but will produce a mismatch
8268 // (and would be incorrectly rendered on the client).
8269 // However, we already warn about bad casing elsewhere.
8270 // So we'll skip the misleading extra mismatch warning in this case.
8271 isMismatchDueToBadCasing = true;
8272 // $FlowFixMe - Should be inferred as not undefined.
8273 extraAttributeNames.delete(standardName);
8274 }
8275 // $FlowFixMe - Should be inferred as not undefined.
8276 extraAttributeNames.delete(propKey);
8277 }
8278 serverValue = getValueForAttribute(domElement, propKey, nextProp);
8279 }
8280
8281 if (nextProp !== serverValue && !isMismatchDueToBadCasing) {
8282 warnForPropDifference(propKey, serverValue, nextProp);
8283 }
8284 }
8285 }
8286 }
8287
8288 {
8289 // $FlowFixMe - Should be inferred as not undefined.
8290 if (extraAttributeNames.size > 0 && !suppressHydrationWarning) {
8291 // $FlowFixMe - Should be inferred as not undefined.
8292 warnForExtraAttributes(extraAttributeNames);
8293 }
8294 }
8295
8296 switch (tag) {
8297 case 'input':
8298 // TODO: Make sure we check if this is still unmounted or do any clean
8299 // up necessary since we never stop tracking anymore.
8300 track(domElement);
8301 postMountWrapper(domElement, rawProps, true);
8302 break;
8303 case 'textarea':
8304 // TODO: Make sure we check if this is still unmounted or do any clean
8305 // up necessary since we never stop tracking anymore.
8306 track(domElement);
8307 postMountWrapper$3(domElement, rawProps);
8308 break;
8309 case 'select':
8310 case 'option':
8311 // For input and textarea we current always set the value property at
8312 // post mount to force it to diverge from attributes. However, for
8313 // option and select we don't quite do the same thing and select
8314 // is not resilient to the DOM state changing so we don't do that here.
8315 // TODO: Consider not doing this for input and textarea.
8316 break;
8317 default:
8318 if (typeof rawProps.onClick === 'function') {
8319 // TODO: This cast may not be sound for SVG, MathML or custom elements.
8320 trapClickOnNonInteractiveElement(domElement);
8321 }
8322 break;
8323 }
8324
8325 return updatePayload;
8326}
8327
8328function diffHydratedText(textNode, text) {
8329 var isDifferent = textNode.nodeValue !== text;
8330 return isDifferent;
8331}
8332
8333function warnForUnmatchedText(textNode, text) {
8334 {
8335 warnForTextDifference(textNode.nodeValue, text);
8336 }
8337}
8338
8339function warnForDeletedHydratableElement(parentNode, child) {
8340 {
8341 if (didWarnInvalidHydration) {
8342 return;
8343 }
8344 didWarnInvalidHydration = true;
8345 warningWithoutStack$1(false, 'Did not expect server HTML to contain a <%s> in <%s>.', child.nodeName.toLowerCase(), parentNode.nodeName.toLowerCase());
8346 }
8347}
8348
8349function warnForDeletedHydratableText(parentNode, child) {
8350 {
8351 if (didWarnInvalidHydration) {
8352 return;
8353 }
8354 didWarnInvalidHydration = true;
8355 warningWithoutStack$1(false, 'Did not expect server HTML to contain the text node "%s" in <%s>.', child.nodeValue, parentNode.nodeName.toLowerCase());
8356 }
8357}
8358
8359function warnForInsertedHydratedElement(parentNode, tag, props) {
8360 {
8361 if (didWarnInvalidHydration) {
8362 return;
8363 }
8364 didWarnInvalidHydration = true;
8365 warningWithoutStack$1(false, 'Expected server HTML to contain a matching <%s> in <%s>.', tag, parentNode.nodeName.toLowerCase());
8366 }
8367}
8368
8369function warnForInsertedHydratedText(parentNode, text) {
8370 {
8371 if (text === '') {
8372 // We expect to insert empty text nodes since they're not represented in
8373 // the HTML.
8374 // TODO: Remove this special case if we can just avoid inserting empty
8375 // text nodes.
8376 return;
8377 }
8378 if (didWarnInvalidHydration) {
8379 return;
8380 }
8381 didWarnInvalidHydration = true;
8382 warningWithoutStack$1(false, 'Expected server HTML to contain a matching text node for "%s" in <%s>.', text, parentNode.nodeName.toLowerCase());
8383 }
8384}
8385
8386function restoreControlledState$1(domElement, tag, props) {
8387 switch (tag) {
8388 case 'input':
8389 restoreControlledState(domElement, props);
8390 return;
8391 case 'textarea':
8392 restoreControlledState$3(domElement, props);
8393 return;
8394 case 'select':
8395 restoreControlledState$2(domElement, props);
8396 return;
8397 }
8398}
8399
8400// TODO: direct imports like some-package/src/* are bad. Fix me.
8401var validateDOMNesting = function () {};
8402var updatedAncestorInfo = function () {};
8403
8404{
8405 // This validation code was written based on the HTML5 parsing spec:
8406 // https://html.spec.whatwg.org/multipage/syntax.html#has-an-element-in-scope
8407 //
8408 // Note: this does not catch all invalid nesting, nor does it try to (as it's
8409 // not clear what practical benefit doing so provides); instead, we warn only
8410 // for cases where the parser will give a parse tree differing from what React
8411 // intended. For example, <b><div></div></b> is invalid but we don't warn
8412 // because it still parses correctly; we do warn for other cases like nested
8413 // <p> tags where the beginning of the second element implicitly closes the
8414 // first, causing a confusing mess.
8415
8416 // https://html.spec.whatwg.org/multipage/syntax.html#special
8417 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'];
8418
8419 // https://html.spec.whatwg.org/multipage/syntax.html#has-an-element-in-scope
8420 var inScopeTags = ['applet', 'caption', 'html', 'table', 'td', 'th', 'marquee', 'object', 'template',
8421
8422 // https://html.spec.whatwg.org/multipage/syntax.html#html-integration-point
8423 // TODO: Distinguish by namespace here -- for <title>, including it here
8424 // errs on the side of fewer warnings
8425 'foreignObject', 'desc', 'title'];
8426
8427 // https://html.spec.whatwg.org/multipage/syntax.html#has-an-element-in-button-scope
8428 var buttonScopeTags = inScopeTags.concat(['button']);
8429
8430 // https://html.spec.whatwg.org/multipage/syntax.html#generate-implied-end-tags
8431 var impliedEndTags = ['dd', 'dt', 'li', 'option', 'optgroup', 'p', 'rp', 'rt'];
8432
8433 var emptyAncestorInfo = {
8434 current: null,
8435
8436 formTag: null,
8437 aTagInScope: null,
8438 buttonTagInScope: null,
8439 nobrTagInScope: null,
8440 pTagInButtonScope: null,
8441
8442 listItemTagAutoclosing: null,
8443 dlItemTagAutoclosing: null
8444 };
8445
8446 updatedAncestorInfo = function (oldInfo, tag) {
8447 var ancestorInfo = _assign({}, oldInfo || emptyAncestorInfo);
8448 var info = { tag: tag };
8449
8450 if (inScopeTags.indexOf(tag) !== -1) {
8451 ancestorInfo.aTagInScope = null;
8452 ancestorInfo.buttonTagInScope = null;
8453 ancestorInfo.nobrTagInScope = null;
8454 }
8455 if (buttonScopeTags.indexOf(tag) !== -1) {
8456 ancestorInfo.pTagInButtonScope = null;
8457 }
8458
8459 // See rules for 'li', 'dd', 'dt' start tags in
8460 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inbody
8461 if (specialTags.indexOf(tag) !== -1 && tag !== 'address' && tag !== 'div' && tag !== 'p') {
8462 ancestorInfo.listItemTagAutoclosing = null;
8463 ancestorInfo.dlItemTagAutoclosing = null;
8464 }
8465
8466 ancestorInfo.current = info;
8467
8468 if (tag === 'form') {
8469 ancestorInfo.formTag = info;
8470 }
8471 if (tag === 'a') {
8472 ancestorInfo.aTagInScope = info;
8473 }
8474 if (tag === 'button') {
8475 ancestorInfo.buttonTagInScope = info;
8476 }
8477 if (tag === 'nobr') {
8478 ancestorInfo.nobrTagInScope = info;
8479 }
8480 if (tag === 'p') {
8481 ancestorInfo.pTagInButtonScope = info;
8482 }
8483 if (tag === 'li') {
8484 ancestorInfo.listItemTagAutoclosing = info;
8485 }
8486 if (tag === 'dd' || tag === 'dt') {
8487 ancestorInfo.dlItemTagAutoclosing = info;
8488 }
8489
8490 return ancestorInfo;
8491 };
8492
8493 /**
8494 * Returns whether
8495 */
8496 var isTagValidWithParent = function (tag, parentTag) {
8497 // First, let's check if we're in an unusual parsing mode...
8498 switch (parentTag) {
8499 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inselect
8500 case 'select':
8501 return tag === 'option' || tag === 'optgroup' || tag === '#text';
8502 case 'optgroup':
8503 return tag === 'option' || tag === '#text';
8504 // Strictly speaking, seeing an <option> doesn't mean we're in a <select>
8505 // but
8506 case 'option':
8507 return tag === '#text';
8508 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intd
8509 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-incaption
8510 // No special behavior since these rules fall back to "in body" mode for
8511 // all except special table nodes which cause bad parsing behavior anyway.
8512
8513 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intr
8514 case 'tr':
8515 return tag === 'th' || tag === 'td' || tag === 'style' || tag === 'script' || tag === 'template';
8516 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intbody
8517 case 'tbody':
8518 case 'thead':
8519 case 'tfoot':
8520 return tag === 'tr' || tag === 'style' || tag === 'script' || tag === 'template';
8521 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-incolgroup
8522 case 'colgroup':
8523 return tag === 'col' || tag === 'template';
8524 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intable
8525 case 'table':
8526 return tag === 'caption' || tag === 'colgroup' || tag === 'tbody' || tag === 'tfoot' || tag === 'thead' || tag === 'style' || tag === 'script' || tag === 'template';
8527 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inhead
8528 case 'head':
8529 return tag === 'base' || tag === 'basefont' || tag === 'bgsound' || tag === 'link' || tag === 'meta' || tag === 'title' || tag === 'noscript' || tag === 'noframes' || tag === 'style' || tag === 'script' || tag === 'template';
8530 // https://html.spec.whatwg.org/multipage/semantics.html#the-html-element
8531 case 'html':
8532 return tag === 'head' || tag === 'body';
8533 case '#document':
8534 return tag === 'html';
8535 }
8536
8537 // Probably in the "in body" parsing mode, so we outlaw only tag combos
8538 // where the parsing rules cause implicit opens or closes to be added.
8539 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inbody
8540 switch (tag) {
8541 case 'h1':
8542 case 'h2':
8543 case 'h3':
8544 case 'h4':
8545 case 'h5':
8546 case 'h6':
8547 return parentTag !== 'h1' && parentTag !== 'h2' && parentTag !== 'h3' && parentTag !== 'h4' && parentTag !== 'h5' && parentTag !== 'h6';
8548
8549 case 'rp':
8550 case 'rt':
8551 return impliedEndTags.indexOf(parentTag) === -1;
8552
8553 case 'body':
8554 case 'caption':
8555 case 'col':
8556 case 'colgroup':
8557 case 'frame':
8558 case 'head':
8559 case 'html':
8560 case 'tbody':
8561 case 'td':
8562 case 'tfoot':
8563 case 'th':
8564 case 'thead':
8565 case 'tr':
8566 // These tags are only valid with a few parents that have special child
8567 // parsing rules -- if we're down here, then none of those matched and
8568 // so we allow it only if we don't know what the parent is, as all other
8569 // cases are invalid.
8570 return parentTag == null;
8571 }
8572
8573 return true;
8574 };
8575
8576 /**
8577 * Returns whether
8578 */
8579 var findInvalidAncestorForTag = function (tag, ancestorInfo) {
8580 switch (tag) {
8581 case 'address':
8582 case 'article':
8583 case 'aside':
8584 case 'blockquote':
8585 case 'center':
8586 case 'details':
8587 case 'dialog':
8588 case 'dir':
8589 case 'div':
8590 case 'dl':
8591 case 'fieldset':
8592 case 'figcaption':
8593 case 'figure':
8594 case 'footer':
8595 case 'header':
8596 case 'hgroup':
8597 case 'main':
8598 case 'menu':
8599 case 'nav':
8600 case 'ol':
8601 case 'p':
8602 case 'section':
8603 case 'summary':
8604 case 'ul':
8605 case 'pre':
8606 case 'listing':
8607 case 'table':
8608 case 'hr':
8609 case 'xmp':
8610 case 'h1':
8611 case 'h2':
8612 case 'h3':
8613 case 'h4':
8614 case 'h5':
8615 case 'h6':
8616 return ancestorInfo.pTagInButtonScope;
8617
8618 case 'form':
8619 return ancestorInfo.formTag || ancestorInfo.pTagInButtonScope;
8620
8621 case 'li':
8622 return ancestorInfo.listItemTagAutoclosing;
8623
8624 case 'dd':
8625 case 'dt':
8626 return ancestorInfo.dlItemTagAutoclosing;
8627
8628 case 'button':
8629 return ancestorInfo.buttonTagInScope;
8630
8631 case 'a':
8632 // Spec says something about storing a list of markers, but it sounds
8633 // equivalent to this check.
8634 return ancestorInfo.aTagInScope;
8635
8636 case 'nobr':
8637 return ancestorInfo.nobrTagInScope;
8638 }
8639
8640 return null;
8641 };
8642
8643 var didWarn = {};
8644
8645 validateDOMNesting = function (childTag, childText, ancestorInfo) {
8646 ancestorInfo = ancestorInfo || emptyAncestorInfo;
8647 var parentInfo = ancestorInfo.current;
8648 var parentTag = parentInfo && parentInfo.tag;
8649
8650 if (childText != null) {
8651 !(childTag == null) ? warningWithoutStack$1(false, 'validateDOMNesting: when childText is passed, childTag should be null') : void 0;
8652 childTag = '#text';
8653 }
8654
8655 var invalidParent = isTagValidWithParent(childTag, parentTag) ? null : parentInfo;
8656 var invalidAncestor = invalidParent ? null : findInvalidAncestorForTag(childTag, ancestorInfo);
8657 var invalidParentOrAncestor = invalidParent || invalidAncestor;
8658 if (!invalidParentOrAncestor) {
8659 return;
8660 }
8661
8662 var ancestorTag = invalidParentOrAncestor.tag;
8663 var addendum = getCurrentFiberStackInDev();
8664
8665 var warnKey = !!invalidParent + '|' + childTag + '|' + ancestorTag + '|' + addendum;
8666 if (didWarn[warnKey]) {
8667 return;
8668 }
8669 didWarn[warnKey] = true;
8670
8671 var tagDisplayName = childTag;
8672 var whitespaceInfo = '';
8673 if (childTag === '#text') {
8674 if (/\S/.test(childText)) {
8675 tagDisplayName = 'Text nodes';
8676 } else {
8677 tagDisplayName = 'Whitespace text nodes';
8678 whitespaceInfo = " Make sure you don't have any extra whitespace between tags on " + 'each line of your source code.';
8679 }
8680 } else {
8681 tagDisplayName = '<' + childTag + '>';
8682 }
8683
8684 if (invalidParent) {
8685 var info = '';
8686 if (ancestorTag === 'table' && childTag === 'tr') {
8687 info += ' Add a <tbody> to your code to match the DOM tree generated by ' + 'the browser.';
8688 }
8689 warningWithoutStack$1(false, 'validateDOMNesting(...): %s cannot appear as a child of <%s>.%s%s%s', tagDisplayName, ancestorTag, whitespaceInfo, info, addendum);
8690 } else {
8691 warningWithoutStack$1(false, 'validateDOMNesting(...): %s cannot appear as a descendant of ' + '<%s>.%s', tagDisplayName, ancestorTag, addendum);
8692 }
8693 };
8694}
8695
8696var ReactInternals$1 = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
8697
8698var _ReactInternals$Sched = ReactInternals$1.Scheduler;
8699var unstable_cancelCallback = _ReactInternals$Sched.unstable_cancelCallback;
8700var unstable_now = _ReactInternals$Sched.unstable_now;
8701var unstable_scheduleCallback = _ReactInternals$Sched.unstable_scheduleCallback;
8702var unstable_shouldYield = _ReactInternals$Sched.unstable_shouldYield;
8703var unstable_getFirstCallbackNode = _ReactInternals$Sched.unstable_getFirstCallbackNode;
8704var unstable_continueExecution = _ReactInternals$Sched.unstable_continueExecution;
8705var unstable_pauseExecution = _ReactInternals$Sched.unstable_pauseExecution;
8706
8707// Renderers that don't support persistence
8708// can re-export everything from this module.
8709
8710function shim() {
8711 invariant(false, 'The current renderer does not support persistence. This error is likely caused by a bug in React. Please file an issue.');
8712}
8713
8714// Persistence (when unsupported)
8715var supportsPersistence = false;
8716var cloneInstance = shim;
8717var createContainerChildSet = shim;
8718var appendChildToContainerChildSet = shim;
8719var finalizeContainerChildren = shim;
8720var replaceContainerChildren = shim;
8721var cloneHiddenInstance = shim;
8722var cloneUnhiddenInstance = shim;
8723var createHiddenTextInstance = shim;
8724
8725var SUPPRESS_HYDRATION_WARNING = void 0;
8726{
8727 SUPPRESS_HYDRATION_WARNING = 'suppressHydrationWarning';
8728}
8729
8730var STYLE = 'style';
8731
8732var eventsEnabled = null;
8733var selectionInformation = null;
8734
8735function shouldAutoFocusHostComponent(type, props) {
8736 switch (type) {
8737 case 'button':
8738 case 'input':
8739 case 'select':
8740 case 'textarea':
8741 return !!props.autoFocus;
8742 }
8743 return false;
8744}
8745
8746function getRootHostContext(rootContainerInstance) {
8747 var type = void 0;
8748 var namespace = void 0;
8749 var nodeType = rootContainerInstance.nodeType;
8750 switch (nodeType) {
8751 case DOCUMENT_NODE:
8752 case DOCUMENT_FRAGMENT_NODE:
8753 {
8754 type = nodeType === DOCUMENT_NODE ? '#document' : '#fragment';
8755 var root = rootContainerInstance.documentElement;
8756 namespace = root ? root.namespaceURI : getChildNamespace(null, '');
8757 break;
8758 }
8759 default:
8760 {
8761 var container = nodeType === COMMENT_NODE ? rootContainerInstance.parentNode : rootContainerInstance;
8762 var ownNamespace = container.namespaceURI || null;
8763 type = container.tagName;
8764 namespace = getChildNamespace(ownNamespace, type);
8765 break;
8766 }
8767 }
8768 {
8769 var validatedTag = type.toLowerCase();
8770 var _ancestorInfo = updatedAncestorInfo(null, validatedTag);
8771 return { namespace: namespace, ancestorInfo: _ancestorInfo };
8772 }
8773 return namespace;
8774}
8775
8776function getChildHostContext(parentHostContext, type, rootContainerInstance) {
8777 {
8778 var parentHostContextDev = parentHostContext;
8779 var _namespace = getChildNamespace(parentHostContextDev.namespace, type);
8780 var _ancestorInfo2 = updatedAncestorInfo(parentHostContextDev.ancestorInfo, type);
8781 return { namespace: _namespace, ancestorInfo: _ancestorInfo2 };
8782 }
8783 var parentNamespace = parentHostContext;
8784 return getChildNamespace(parentNamespace, type);
8785}
8786
8787function getPublicInstance(instance) {
8788 return instance;
8789}
8790
8791function prepareForCommit(containerInfo) {
8792 eventsEnabled = isEnabled();
8793 selectionInformation = getSelectionInformation();
8794 setEnabled(false);
8795}
8796
8797function resetAfterCommit(containerInfo) {
8798 restoreSelection(selectionInformation);
8799 selectionInformation = null;
8800 setEnabled(eventsEnabled);
8801 eventsEnabled = null;
8802}
8803
8804function createInstance(type, props, rootContainerInstance, hostContext, internalInstanceHandle) {
8805 var parentNamespace = void 0;
8806 {
8807 // TODO: take namespace into account when validating.
8808 var hostContextDev = hostContext;
8809 validateDOMNesting(type, null, hostContextDev.ancestorInfo);
8810 if (typeof props.children === 'string' || typeof props.children === 'number') {
8811 var string = '' + props.children;
8812 var ownAncestorInfo = updatedAncestorInfo(hostContextDev.ancestorInfo, type);
8813 validateDOMNesting(null, string, ownAncestorInfo);
8814 }
8815 parentNamespace = hostContextDev.namespace;
8816 }
8817 var domElement = createElement(type, props, rootContainerInstance, parentNamespace);
8818 precacheFiberNode(internalInstanceHandle, domElement);
8819 updateFiberProps(domElement, props);
8820 return domElement;
8821}
8822
8823function appendInitialChild(parentInstance, child) {
8824 parentInstance.appendChild(child);
8825}
8826
8827function finalizeInitialChildren(domElement, type, props, rootContainerInstance, hostContext) {
8828 setInitialProperties(domElement, type, props, rootContainerInstance);
8829 return shouldAutoFocusHostComponent(type, props);
8830}
8831
8832function prepareUpdate(domElement, type, oldProps, newProps, rootContainerInstance, hostContext) {
8833 {
8834 var hostContextDev = hostContext;
8835 if (typeof newProps.children !== typeof oldProps.children && (typeof newProps.children === 'string' || typeof newProps.children === 'number')) {
8836 var string = '' + newProps.children;
8837 var ownAncestorInfo = updatedAncestorInfo(hostContextDev.ancestorInfo, type);
8838 validateDOMNesting(null, string, ownAncestorInfo);
8839 }
8840 }
8841 return diffProperties(domElement, type, oldProps, newProps, rootContainerInstance);
8842}
8843
8844function shouldSetTextContent(type, props) {
8845 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;
8846}
8847
8848function shouldDeprioritizeSubtree(type, props) {
8849 return !!props.hidden;
8850}
8851
8852function createTextInstance(text, rootContainerInstance, hostContext, internalInstanceHandle) {
8853 {
8854 var hostContextDev = hostContext;
8855 validateDOMNesting(null, text, hostContextDev.ancestorInfo);
8856 }
8857 var textNode = createTextNode(text, rootContainerInstance);
8858 precacheFiberNode(internalInstanceHandle, textNode);
8859 return textNode;
8860}
8861
8862var isPrimaryRenderer = true;
8863// This initialization code may run even on server environments
8864// if a component just imports ReactDOM (e.g. for findDOMNode).
8865// Some environments might not have setTimeout or clearTimeout.
8866var scheduleTimeout = typeof setTimeout === 'function' ? setTimeout : undefined;
8867var cancelTimeout = typeof clearTimeout === 'function' ? clearTimeout : undefined;
8868var noTimeout = -1;
8869var schedulePassiveEffects = unstable_scheduleCallback;
8870var cancelPassiveEffects = unstable_cancelCallback;
8871
8872// -------------------
8873// Mutation
8874// -------------------
8875
8876var supportsMutation = true;
8877
8878function commitMount(domElement, type, newProps, internalInstanceHandle) {
8879 // Despite the naming that might imply otherwise, this method only
8880 // fires if there is an `Update` effect scheduled during mounting.
8881 // This happens if `finalizeInitialChildren` returns `true` (which it
8882 // does to implement the `autoFocus` attribute on the client). But
8883 // there are also other cases when this might happen (such as patching
8884 // up text content during hydration mismatch). So we'll check this again.
8885 if (shouldAutoFocusHostComponent(type, newProps)) {
8886 domElement.focus();
8887 }
8888}
8889
8890function commitUpdate(domElement, updatePayload, type, oldProps, newProps, internalInstanceHandle) {
8891 // Update the props handle so that we know which props are the ones with
8892 // with current event handlers.
8893 updateFiberProps(domElement, newProps);
8894 // Apply the diff to the DOM node.
8895 updateProperties(domElement, updatePayload, type, oldProps, newProps);
8896}
8897
8898function resetTextContent(domElement) {
8899 setTextContent(domElement, '');
8900}
8901
8902function commitTextUpdate(textInstance, oldText, newText) {
8903 textInstance.nodeValue = newText;
8904}
8905
8906function appendChild(parentInstance, child) {
8907 parentInstance.appendChild(child);
8908}
8909
8910function appendChildToContainer(container, child) {
8911 var parentNode = void 0;
8912 if (container.nodeType === COMMENT_NODE) {
8913 parentNode = container.parentNode;
8914 parentNode.insertBefore(child, container);
8915 } else {
8916 parentNode = container;
8917 parentNode.appendChild(child);
8918 }
8919 // This container might be used for a portal.
8920 // If something inside a portal is clicked, that click should bubble
8921 // through the React tree. However, on Mobile Safari the click would
8922 // never bubble through the *DOM* tree unless an ancestor with onclick
8923 // event exists. So we wouldn't see it and dispatch it.
8924 // This is why we ensure that non React root containers have inline onclick
8925 // defined.
8926 // https://github.com/facebook/react/issues/11918
8927 var reactRootContainer = container._reactRootContainer;
8928 if ((reactRootContainer === null || reactRootContainer === undefined) && parentNode.onclick === null) {
8929 // TODO: This cast may not be sound for SVG, MathML or custom elements.
8930 trapClickOnNonInteractiveElement(parentNode);
8931 }
8932}
8933
8934function insertBefore(parentInstance, child, beforeChild) {
8935 parentInstance.insertBefore(child, beforeChild);
8936}
8937
8938function insertInContainerBefore(container, child, beforeChild) {
8939 if (container.nodeType === COMMENT_NODE) {
8940 container.parentNode.insertBefore(child, beforeChild);
8941 } else {
8942 container.insertBefore(child, beforeChild);
8943 }
8944}
8945
8946function removeChild(parentInstance, child) {
8947 parentInstance.removeChild(child);
8948}
8949
8950function removeChildFromContainer(container, child) {
8951 if (container.nodeType === COMMENT_NODE) {
8952 container.parentNode.removeChild(child);
8953 } else {
8954 container.removeChild(child);
8955 }
8956}
8957
8958function hideInstance(instance) {
8959 // TODO: Does this work for all element types? What about MathML? Should we
8960 // pass host context to this method?
8961 instance = instance;
8962 instance.style.display = 'none';
8963}
8964
8965function hideTextInstance(textInstance) {
8966 textInstance.nodeValue = '';
8967}
8968
8969function unhideInstance(instance, props) {
8970 instance = instance;
8971 var styleProp = props[STYLE];
8972 var display = styleProp !== undefined && styleProp !== null && styleProp.hasOwnProperty('display') ? styleProp.display : null;
8973 instance.style.display = dangerousStyleValue('display', display);
8974}
8975
8976function unhideTextInstance(textInstance, text) {
8977 textInstance.nodeValue = text;
8978}
8979
8980// -------------------
8981// Hydration
8982// -------------------
8983
8984var supportsHydration = true;
8985
8986function canHydrateInstance(instance, type, props) {
8987 if (instance.nodeType !== ELEMENT_NODE || type.toLowerCase() !== instance.nodeName.toLowerCase()) {
8988 return null;
8989 }
8990 // This has now been refined to an element node.
8991 return instance;
8992}
8993
8994function canHydrateTextInstance(instance, text) {
8995 if (text === '' || instance.nodeType !== TEXT_NODE) {
8996 // Empty strings are not parsed by HTML so there won't be a correct match here.
8997 return null;
8998 }
8999 // This has now been refined to a text node.
9000 return instance;
9001}
9002
9003function getNextHydratableSibling(instance) {
9004 var node = instance.nextSibling;
9005 // Skip non-hydratable nodes.
9006 while (node && node.nodeType !== ELEMENT_NODE && node.nodeType !== TEXT_NODE) {
9007 node = node.nextSibling;
9008 }
9009 return node;
9010}
9011
9012function getFirstHydratableChild(parentInstance) {
9013 var next = parentInstance.firstChild;
9014 // Skip non-hydratable nodes.
9015 while (next && next.nodeType !== ELEMENT_NODE && next.nodeType !== TEXT_NODE) {
9016 next = next.nextSibling;
9017 }
9018 return next;
9019}
9020
9021function hydrateInstance(instance, type, props, rootContainerInstance, hostContext, internalInstanceHandle) {
9022 precacheFiberNode(internalInstanceHandle, instance);
9023 // TODO: Possibly defer this until the commit phase where all the events
9024 // get attached.
9025 updateFiberProps(instance, props);
9026 var parentNamespace = void 0;
9027 {
9028 var hostContextDev = hostContext;
9029 parentNamespace = hostContextDev.namespace;
9030 }
9031 return diffHydratedProperties(instance, type, props, parentNamespace, rootContainerInstance);
9032}
9033
9034function hydrateTextInstance(textInstance, text, internalInstanceHandle) {
9035 precacheFiberNode(internalInstanceHandle, textInstance);
9036 return diffHydratedText(textInstance, text);
9037}
9038
9039function didNotMatchHydratedContainerTextInstance(parentContainer, textInstance, text) {
9040 {
9041 warnForUnmatchedText(textInstance, text);
9042 }
9043}
9044
9045function didNotMatchHydratedTextInstance(parentType, parentProps, parentInstance, textInstance, text) {
9046 if (true && parentProps[SUPPRESS_HYDRATION_WARNING] !== true) {
9047 warnForUnmatchedText(textInstance, text);
9048 }
9049}
9050
9051function didNotHydrateContainerInstance(parentContainer, instance) {
9052 {
9053 if (instance.nodeType === ELEMENT_NODE) {
9054 warnForDeletedHydratableElement(parentContainer, instance);
9055 } else {
9056 warnForDeletedHydratableText(parentContainer, instance);
9057 }
9058 }
9059}
9060
9061function didNotHydrateInstance(parentType, parentProps, parentInstance, instance) {
9062 if (true && parentProps[SUPPRESS_HYDRATION_WARNING] !== true) {
9063 if (instance.nodeType === ELEMENT_NODE) {
9064 warnForDeletedHydratableElement(parentInstance, instance);
9065 } else {
9066 warnForDeletedHydratableText(parentInstance, instance);
9067 }
9068 }
9069}
9070
9071function didNotFindHydratableContainerInstance(parentContainer, type, props) {
9072 {
9073 warnForInsertedHydratedElement(parentContainer, type, props);
9074 }
9075}
9076
9077function didNotFindHydratableContainerTextInstance(parentContainer, text) {
9078 {
9079 warnForInsertedHydratedText(parentContainer, text);
9080 }
9081}
9082
9083function didNotFindHydratableInstance(parentType, parentProps, parentInstance, type, props) {
9084 if (true && parentProps[SUPPRESS_HYDRATION_WARNING] !== true) {
9085 warnForInsertedHydratedElement(parentInstance, type, props);
9086 }
9087}
9088
9089function didNotFindHydratableTextInstance(parentType, parentProps, parentInstance, text) {
9090 if (true && parentProps[SUPPRESS_HYDRATION_WARNING] !== true) {
9091 warnForInsertedHydratedText(parentInstance, text);
9092 }
9093}
9094
9095// This is just to get the setup running.
9096// TODO: real implementation.
9097// console.log('Hello from Fire host config.');
9098
9099// Prefix measurements so that it's possible to filter them.
9100// Longer prefixes are hard to read in DevTools.
9101var reactEmoji = '\u269B';
9102var warningEmoji = '\u26D4';
9103var supportsUserTiming = typeof performance !== 'undefined' && typeof performance.mark === 'function' && typeof performance.clearMarks === 'function' && typeof performance.measure === 'function' && typeof performance.clearMeasures === 'function';
9104
9105// Keep track of current fiber so that we know the path to unwind on pause.
9106// TODO: this looks the same as nextUnitOfWork in scheduler. Can we unify them?
9107var currentFiber = null;
9108// If we're in the middle of user code, which fiber and method is it?
9109// Reusing `currentFiber` would be confusing for this because user code fiber
9110// can change during commit phase too, but we don't need to unwind it (since
9111// lifecycles in the commit phase don't resemble a tree).
9112var currentPhase = null;
9113var currentPhaseFiber = null;
9114// Did lifecycle hook schedule an update? This is often a performance problem,
9115// so we will keep track of it, and include it in the report.
9116// Track commits caused by cascading updates.
9117var isCommitting = false;
9118var hasScheduledUpdateInCurrentCommit = false;
9119var hasScheduledUpdateInCurrentPhase = false;
9120var commitCountInCurrentWorkLoop = 0;
9121var effectCountInCurrentCommit = 0;
9122var isWaitingForCallback = false;
9123// During commits, we only show a measurement once per method name
9124// to avoid stretch the commit phase with measurement overhead.
9125var labelsInCurrentCommit = new Set();
9126
9127var formatMarkName = function (markName) {
9128 return reactEmoji + ' ' + markName;
9129};
9130
9131var formatLabel = function (label, warning) {
9132 var prefix = warning ? warningEmoji + ' ' : reactEmoji + ' ';
9133 var suffix = warning ? ' Warning: ' + warning : '';
9134 return '' + prefix + label + suffix;
9135};
9136
9137var beginMark = function (markName) {
9138 performance.mark(formatMarkName(markName));
9139};
9140
9141var clearMark = function (markName) {
9142 performance.clearMarks(formatMarkName(markName));
9143};
9144
9145var endMark = function (label, markName, warning) {
9146 var formattedMarkName = formatMarkName(markName);
9147 var formattedLabel = formatLabel(label, warning);
9148 try {
9149 performance.measure(formattedLabel, formattedMarkName);
9150 } catch (err) {}
9151 // If previous mark was missing for some reason, this will throw.
9152 // This could only happen if React crashed in an unexpected place earlier.
9153 // Don't pile on with more errors.
9154
9155 // Clear marks immediately to avoid growing buffer.
9156 performance.clearMarks(formattedMarkName);
9157 performance.clearMeasures(formattedLabel);
9158};
9159
9160var getFiberMarkName = function (label, debugID) {
9161 return label + ' (#' + debugID + ')';
9162};
9163
9164var getFiberLabel = function (componentName, isMounted, phase) {
9165 if (phase === null) {
9166 // These are composite component total time measurements.
9167 return componentName + ' [' + (isMounted ? 'update' : 'mount') + ']';
9168 } else {
9169 // Composite component methods.
9170 return componentName + '.' + phase;
9171 }
9172};
9173
9174var beginFiberMark = function (fiber, phase) {
9175 var componentName = getComponentName(fiber.type) || 'Unknown';
9176 var debugID = fiber._debugID;
9177 var isMounted = fiber.alternate !== null;
9178 var label = getFiberLabel(componentName, isMounted, phase);
9179
9180 if (isCommitting && labelsInCurrentCommit.has(label)) {
9181 // During the commit phase, we don't show duplicate labels because
9182 // there is a fixed overhead for every measurement, and we don't
9183 // want to stretch the commit phase beyond necessary.
9184 return false;
9185 }
9186 labelsInCurrentCommit.add(label);
9187
9188 var markName = getFiberMarkName(label, debugID);
9189 beginMark(markName);
9190 return true;
9191};
9192
9193var clearFiberMark = function (fiber, phase) {
9194 var componentName = getComponentName(fiber.type) || 'Unknown';
9195 var debugID = fiber._debugID;
9196 var isMounted = fiber.alternate !== null;
9197 var label = getFiberLabel(componentName, isMounted, phase);
9198 var markName = getFiberMarkName(label, debugID);
9199 clearMark(markName);
9200};
9201
9202var endFiberMark = function (fiber, phase, warning) {
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 endMark(label, markName, warning);
9209};
9210
9211var shouldIgnoreFiber = function (fiber) {
9212 // Host components should be skipped in the timeline.
9213 // We could check typeof fiber.type, but does this work with RN?
9214 switch (fiber.tag) {
9215 case HostRoot:
9216 case HostComponent:
9217 case HostText:
9218 case HostPortal:
9219 case Fragment:
9220 case ContextProvider:
9221 case ContextConsumer:
9222 case Mode:
9223 return true;
9224 default:
9225 return false;
9226 }
9227};
9228
9229var clearPendingPhaseMeasurement = function () {
9230 if (currentPhase !== null && currentPhaseFiber !== null) {
9231 clearFiberMark(currentPhaseFiber, currentPhase);
9232 }
9233 currentPhaseFiber = null;
9234 currentPhase = null;
9235 hasScheduledUpdateInCurrentPhase = false;
9236};
9237
9238var pauseTimers = function () {
9239 // Stops all currently active measurements so that they can be resumed
9240 // if we continue in a later deferred loop from the same unit of work.
9241 var fiber = currentFiber;
9242 while (fiber) {
9243 if (fiber._debugIsCurrentlyTiming) {
9244 endFiberMark(fiber, null, null);
9245 }
9246 fiber = fiber.return;
9247 }
9248};
9249
9250var resumeTimersRecursively = function (fiber) {
9251 if (fiber.return !== null) {
9252 resumeTimersRecursively(fiber.return);
9253 }
9254 if (fiber._debugIsCurrentlyTiming) {
9255 beginFiberMark(fiber, null);
9256 }
9257};
9258
9259var resumeTimers = function () {
9260 // Resumes all measurements that were active during the last deferred loop.
9261 if (currentFiber !== null) {
9262 resumeTimersRecursively(currentFiber);
9263 }
9264};
9265
9266function recordEffect() {
9267 if (enableUserTimingAPI) {
9268 effectCountInCurrentCommit++;
9269 }
9270}
9271
9272function recordScheduleUpdate() {
9273 if (enableUserTimingAPI) {
9274 if (isCommitting) {
9275 hasScheduledUpdateInCurrentCommit = true;
9276 }
9277 if (currentPhase !== null && currentPhase !== 'componentWillMount' && currentPhase !== 'componentWillReceiveProps') {
9278 hasScheduledUpdateInCurrentPhase = true;
9279 }
9280 }
9281}
9282
9283function startRequestCallbackTimer() {
9284 if (enableUserTimingAPI) {
9285 if (supportsUserTiming && !isWaitingForCallback) {
9286 isWaitingForCallback = true;
9287 beginMark('(Waiting for async callback...)');
9288 }
9289 }
9290}
9291
9292function stopRequestCallbackTimer(didExpire, expirationTime) {
9293 if (enableUserTimingAPI) {
9294 if (supportsUserTiming) {
9295 isWaitingForCallback = false;
9296 var warning = didExpire ? 'React was blocked by main thread' : null;
9297 endMark('(Waiting for async callback... will force flush in ' + expirationTime + ' ms)', '(Waiting for async callback...)', warning);
9298 }
9299 }
9300}
9301
9302function startWorkTimer(fiber) {
9303 if (enableUserTimingAPI) {
9304 if (!supportsUserTiming || shouldIgnoreFiber(fiber)) {
9305 return;
9306 }
9307 // If we pause, this is the fiber to unwind from.
9308 currentFiber = fiber;
9309 if (!beginFiberMark(fiber, null)) {
9310 return;
9311 }
9312 fiber._debugIsCurrentlyTiming = true;
9313 }
9314}
9315
9316function cancelWorkTimer(fiber) {
9317 if (enableUserTimingAPI) {
9318 if (!supportsUserTiming || shouldIgnoreFiber(fiber)) {
9319 return;
9320 }
9321 // Remember we shouldn't complete measurement for this fiber.
9322 // Otherwise flamechart will be deep even for small updates.
9323 fiber._debugIsCurrentlyTiming = false;
9324 clearFiberMark(fiber, null);
9325 }
9326}
9327
9328function stopWorkTimer(fiber) {
9329 if (enableUserTimingAPI) {
9330 if (!supportsUserTiming || shouldIgnoreFiber(fiber)) {
9331 return;
9332 }
9333 // If we pause, its parent is the fiber to unwind from.
9334 currentFiber = fiber.return;
9335 if (!fiber._debugIsCurrentlyTiming) {
9336 return;
9337 }
9338 fiber._debugIsCurrentlyTiming = false;
9339 endFiberMark(fiber, null, null);
9340 }
9341}
9342
9343function stopFailedWorkTimer(fiber) {
9344 if (enableUserTimingAPI) {
9345 if (!supportsUserTiming || shouldIgnoreFiber(fiber)) {
9346 return;
9347 }
9348 // If we pause, its parent is the fiber to unwind from.
9349 currentFiber = fiber.return;
9350 if (!fiber._debugIsCurrentlyTiming) {
9351 return;
9352 }
9353 fiber._debugIsCurrentlyTiming = false;
9354 var warning = fiber.tag === SuspenseComponent ? 'Rendering was suspended' : 'An error was thrown inside this error boundary';
9355 endFiberMark(fiber, null, warning);
9356 }
9357}
9358
9359function startPhaseTimer(fiber, phase) {
9360 if (enableUserTimingAPI) {
9361 if (!supportsUserTiming) {
9362 return;
9363 }
9364 clearPendingPhaseMeasurement();
9365 if (!beginFiberMark(fiber, phase)) {
9366 return;
9367 }
9368 currentPhaseFiber = fiber;
9369 currentPhase = phase;
9370 }
9371}
9372
9373function stopPhaseTimer() {
9374 if (enableUserTimingAPI) {
9375 if (!supportsUserTiming) {
9376 return;
9377 }
9378 if (currentPhase !== null && currentPhaseFiber !== null) {
9379 var warning = hasScheduledUpdateInCurrentPhase ? 'Scheduled a cascading update' : null;
9380 endFiberMark(currentPhaseFiber, currentPhase, warning);
9381 }
9382 currentPhase = null;
9383 currentPhaseFiber = null;
9384 }
9385}
9386
9387function startWorkLoopTimer(nextUnitOfWork) {
9388 if (enableUserTimingAPI) {
9389 currentFiber = nextUnitOfWork;
9390 if (!supportsUserTiming) {
9391 return;
9392 }
9393 commitCountInCurrentWorkLoop = 0;
9394 // This is top level call.
9395 // Any other measurements are performed within.
9396 beginMark('(React Tree Reconciliation)');
9397 // Resume any measurements that were in progress during the last loop.
9398 resumeTimers();
9399 }
9400}
9401
9402function stopWorkLoopTimer(interruptedBy, didCompleteRoot) {
9403 if (enableUserTimingAPI) {
9404 if (!supportsUserTiming) {
9405 return;
9406 }
9407 var warning = null;
9408 if (interruptedBy !== null) {
9409 if (interruptedBy.tag === HostRoot) {
9410 warning = 'A top-level update interrupted the previous render';
9411 } else {
9412 var componentName = getComponentName(interruptedBy.type) || 'Unknown';
9413 warning = 'An update to ' + componentName + ' interrupted the previous render';
9414 }
9415 } else if (commitCountInCurrentWorkLoop > 1) {
9416 warning = 'There were cascading updates';
9417 }
9418 commitCountInCurrentWorkLoop = 0;
9419 var label = didCompleteRoot ? '(React Tree Reconciliation: Completed Root)' : '(React Tree Reconciliation: Yielded)';
9420 // Pause any measurements until the next loop.
9421 pauseTimers();
9422 endMark(label, '(React Tree Reconciliation)', warning);
9423 }
9424}
9425
9426function startCommitTimer() {
9427 if (enableUserTimingAPI) {
9428 if (!supportsUserTiming) {
9429 return;
9430 }
9431 isCommitting = true;
9432 hasScheduledUpdateInCurrentCommit = false;
9433 labelsInCurrentCommit.clear();
9434 beginMark('(Committing Changes)');
9435 }
9436}
9437
9438function stopCommitTimer() {
9439 if (enableUserTimingAPI) {
9440 if (!supportsUserTiming) {
9441 return;
9442 }
9443
9444 var warning = null;
9445 if (hasScheduledUpdateInCurrentCommit) {
9446 warning = 'Lifecycle hook scheduled a cascading update';
9447 } else if (commitCountInCurrentWorkLoop > 0) {
9448 warning = 'Caused by a cascading update in earlier commit';
9449 }
9450 hasScheduledUpdateInCurrentCommit = false;
9451 commitCountInCurrentWorkLoop++;
9452 isCommitting = false;
9453 labelsInCurrentCommit.clear();
9454
9455 endMark('(Committing Changes)', '(Committing Changes)', warning);
9456 }
9457}
9458
9459function startCommitSnapshotEffectsTimer() {
9460 if (enableUserTimingAPI) {
9461 if (!supportsUserTiming) {
9462 return;
9463 }
9464 effectCountInCurrentCommit = 0;
9465 beginMark('(Committing Snapshot Effects)');
9466 }
9467}
9468
9469function stopCommitSnapshotEffectsTimer() {
9470 if (enableUserTimingAPI) {
9471 if (!supportsUserTiming) {
9472 return;
9473 }
9474 var count = effectCountInCurrentCommit;
9475 effectCountInCurrentCommit = 0;
9476 endMark('(Committing Snapshot Effects: ' + count + ' Total)', '(Committing Snapshot Effects)', null);
9477 }
9478}
9479
9480function startCommitHostEffectsTimer() {
9481 if (enableUserTimingAPI) {
9482 if (!supportsUserTiming) {
9483 return;
9484 }
9485 effectCountInCurrentCommit = 0;
9486 beginMark('(Committing Host Effects)');
9487 }
9488}
9489
9490function stopCommitHostEffectsTimer() {
9491 if (enableUserTimingAPI) {
9492 if (!supportsUserTiming) {
9493 return;
9494 }
9495 var count = effectCountInCurrentCommit;
9496 effectCountInCurrentCommit = 0;
9497 endMark('(Committing Host Effects: ' + count + ' Total)', '(Committing Host Effects)', null);
9498 }
9499}
9500
9501function startCommitLifeCyclesTimer() {
9502 if (enableUserTimingAPI) {
9503 if (!supportsUserTiming) {
9504 return;
9505 }
9506 effectCountInCurrentCommit = 0;
9507 beginMark('(Calling Lifecycle Methods)');
9508 }
9509}
9510
9511function stopCommitLifeCyclesTimer() {
9512 if (enableUserTimingAPI) {
9513 if (!supportsUserTiming) {
9514 return;
9515 }
9516 var count = effectCountInCurrentCommit;
9517 effectCountInCurrentCommit = 0;
9518 endMark('(Calling Lifecycle Methods: ' + count + ' Total)', '(Calling Lifecycle Methods)', null);
9519 }
9520}
9521
9522var valueStack = [];
9523
9524var fiberStack = void 0;
9525
9526{
9527 fiberStack = [];
9528}
9529
9530var index = -1;
9531
9532function createCursor(defaultValue) {
9533 return {
9534 current: defaultValue
9535 };
9536}
9537
9538function pop(cursor, fiber) {
9539 if (index < 0) {
9540 {
9541 warningWithoutStack$1(false, 'Unexpected pop.');
9542 }
9543 return;
9544 }
9545
9546 {
9547 if (fiber !== fiberStack[index]) {
9548 warningWithoutStack$1(false, 'Unexpected Fiber popped.');
9549 }
9550 }
9551
9552 cursor.current = valueStack[index];
9553
9554 valueStack[index] = null;
9555
9556 {
9557 fiberStack[index] = null;
9558 }
9559
9560 index--;
9561}
9562
9563function push(cursor, value, fiber) {
9564 index++;
9565
9566 valueStack[index] = cursor.current;
9567
9568 {
9569 fiberStack[index] = fiber;
9570 }
9571
9572 cursor.current = value;
9573}
9574
9575function checkThatStackIsEmpty() {
9576 {
9577 if (index !== -1) {
9578 warningWithoutStack$1(false, 'Expected an empty stack. Something was not reset properly.');
9579 }
9580 }
9581}
9582
9583function resetStackAfterFatalErrorInDev() {
9584 {
9585 index = -1;
9586 valueStack.length = 0;
9587 fiberStack.length = 0;
9588 }
9589}
9590
9591var warnedAboutMissingGetChildContext = void 0;
9592
9593{
9594 warnedAboutMissingGetChildContext = {};
9595}
9596
9597var emptyContextObject = {};
9598{
9599 Object.freeze(emptyContextObject);
9600}
9601
9602// A cursor to the current merged context object on the stack.
9603var contextStackCursor = createCursor(emptyContextObject);
9604// A cursor to a boolean indicating whether the context has changed.
9605var didPerformWorkStackCursor = createCursor(false);
9606// Keep track of the previous context object that was on the stack.
9607// We use this to get access to the parent context after we have already
9608// pushed the next context provider, and now need to merge their contexts.
9609var previousContext = emptyContextObject;
9610
9611function getUnmaskedContext(workInProgress, Component, didPushOwnContextIfProvider) {
9612 if (didPushOwnContextIfProvider && isContextProvider(Component)) {
9613 // If the fiber is a context provider itself, when we read its context
9614 // we may have already pushed its own child context on the stack. A context
9615 // provider should not "see" its own child context. Therefore we read the
9616 // previous (parent) context instead for a context provider.
9617 return previousContext;
9618 }
9619 return contextStackCursor.current;
9620}
9621
9622function cacheContext(workInProgress, unmaskedContext, maskedContext) {
9623 var instance = workInProgress.stateNode;
9624 instance.__reactInternalMemoizedUnmaskedChildContext = unmaskedContext;
9625 instance.__reactInternalMemoizedMaskedChildContext = maskedContext;
9626}
9627
9628function getMaskedContext(workInProgress, unmaskedContext) {
9629 var type = workInProgress.type;
9630 var contextTypes = type.contextTypes;
9631 if (!contextTypes) {
9632 return emptyContextObject;
9633 }
9634
9635 // Avoid recreating masked context unless unmasked context has changed.
9636 // Failing to do this will result in unnecessary calls to componentWillReceiveProps.
9637 // This may trigger infinite loops if componentWillReceiveProps calls setState.
9638 var instance = workInProgress.stateNode;
9639 if (instance && instance.__reactInternalMemoizedUnmaskedChildContext === unmaskedContext) {
9640 return instance.__reactInternalMemoizedMaskedChildContext;
9641 }
9642
9643 var context = {};
9644 for (var key in contextTypes) {
9645 context[key] = unmaskedContext[key];
9646 }
9647
9648 {
9649 var name = getComponentName(type) || 'Unknown';
9650 checkPropTypes_1(contextTypes, context, 'context', name, getCurrentFiberStackInDev);
9651 }
9652
9653 // Cache unmasked context so we can avoid recreating masked context unless necessary.
9654 // Context is created before the class component is instantiated so check for instance.
9655 if (instance) {
9656 cacheContext(workInProgress, unmaskedContext, context);
9657 }
9658
9659 return context;
9660}
9661
9662function hasContextChanged() {
9663 return didPerformWorkStackCursor.current;
9664}
9665
9666function isContextProvider(type) {
9667 var childContextTypes = type.childContextTypes;
9668 return childContextTypes !== null && childContextTypes !== undefined;
9669}
9670
9671function popContext(fiber) {
9672 pop(didPerformWorkStackCursor, fiber);
9673 pop(contextStackCursor, fiber);
9674}
9675
9676function popTopLevelContextObject(fiber) {
9677 pop(didPerformWorkStackCursor, fiber);
9678 pop(contextStackCursor, fiber);
9679}
9680
9681function pushTopLevelContextObject(fiber, context, didChange) {
9682 !(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;
9683
9684 push(contextStackCursor, context, fiber);
9685 push(didPerformWorkStackCursor, didChange, fiber);
9686}
9687
9688function processChildContext(fiber, type, parentContext) {
9689 var instance = fiber.stateNode;
9690 var childContextTypes = type.childContextTypes;
9691
9692 // TODO (bvaughn) Replace this behavior with an invariant() in the future.
9693 // It has only been added in Fiber to match the (unintentional) behavior in Stack.
9694 if (typeof instance.getChildContext !== 'function') {
9695 {
9696 var componentName = getComponentName(type) || 'Unknown';
9697
9698 if (!warnedAboutMissingGetChildContext[componentName]) {
9699 warnedAboutMissingGetChildContext[componentName] = true;
9700 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);
9701 }
9702 }
9703 return parentContext;
9704 }
9705
9706 var childContext = void 0;
9707 {
9708 setCurrentPhase('getChildContext');
9709 }
9710 startPhaseTimer(fiber, 'getChildContext');
9711 childContext = instance.getChildContext();
9712 stopPhaseTimer();
9713 {
9714 setCurrentPhase(null);
9715 }
9716 for (var contextKey in childContext) {
9717 !(contextKey in childContextTypes) ? invariant(false, '%s.getChildContext(): key "%s" is not defined in childContextTypes.', getComponentName(type) || 'Unknown', contextKey) : void 0;
9718 }
9719 {
9720 var name = getComponentName(type) || 'Unknown';
9721 checkPropTypes_1(childContextTypes, childContext, 'child context', name,
9722 // In practice, there is one case in which we won't get a stack. It's when
9723 // somebody calls unstable_renderSubtreeIntoContainer() and we process
9724 // context from the parent component instance. The stack will be missing
9725 // because it's outside of the reconciliation, and so the pointer has not
9726 // been set. This is rare and doesn't matter. We'll also remove that API.
9727 getCurrentFiberStackInDev);
9728 }
9729
9730 return _assign({}, parentContext, childContext);
9731}
9732
9733function pushContextProvider(workInProgress) {
9734 var instance = workInProgress.stateNode;
9735 // We push the context as early as possible to ensure stack integrity.
9736 // If the instance does not exist yet, we will push null at first,
9737 // and replace it on the stack later when invalidating the context.
9738 var memoizedMergedChildContext = instance && instance.__reactInternalMemoizedMergedChildContext || emptyContextObject;
9739
9740 // Remember the parent context so we can merge with it later.
9741 // Inherit the parent's did-perform-work value to avoid inadvertently blocking updates.
9742 previousContext = contextStackCursor.current;
9743 push(contextStackCursor, memoizedMergedChildContext, workInProgress);
9744 push(didPerformWorkStackCursor, didPerformWorkStackCursor.current, workInProgress);
9745
9746 return true;
9747}
9748
9749function invalidateContextProvider(workInProgress, type, didChange) {
9750 var instance = workInProgress.stateNode;
9751 !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;
9752
9753 if (didChange) {
9754 // Merge parent and own context.
9755 // Skip this if we're not updating due to sCU.
9756 // This avoids unnecessarily recomputing memoized values.
9757 var mergedContext = processChildContext(workInProgress, type, previousContext);
9758 instance.__reactInternalMemoizedMergedChildContext = mergedContext;
9759
9760 // Replace the old (or empty) context with the new one.
9761 // It is important to unwind the context in the reverse order.
9762 pop(didPerformWorkStackCursor, workInProgress);
9763 pop(contextStackCursor, workInProgress);
9764 // Now push the new context and mark that it has changed.
9765 push(contextStackCursor, mergedContext, workInProgress);
9766 push(didPerformWorkStackCursor, didChange, workInProgress);
9767 } else {
9768 pop(didPerformWorkStackCursor, workInProgress);
9769 push(didPerformWorkStackCursor, didChange, workInProgress);
9770 }
9771}
9772
9773function findCurrentUnmaskedContext(fiber) {
9774 // Currently this is only used with renderSubtreeIntoContainer; not sure if it
9775 // makes sense elsewhere
9776 !(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;
9777
9778 var node = fiber;
9779 do {
9780 switch (node.tag) {
9781 case HostRoot:
9782 return node.stateNode.context;
9783 case ClassComponent:
9784 {
9785 var Component = node.type;
9786 if (isContextProvider(Component)) {
9787 return node.stateNode.__reactInternalMemoizedMergedChildContext;
9788 }
9789 break;
9790 }
9791 }
9792 node = node.return;
9793 } while (node !== null);
9794 invariant(false, 'Found unexpected detached subtree parent. This error is likely caused by a bug in React. Please file an issue.');
9795}
9796
9797var onCommitFiberRoot = null;
9798var onCommitFiberUnmount = null;
9799var hasLoggedError = false;
9800
9801function catchErrors(fn) {
9802 return function (arg) {
9803 try {
9804 return fn(arg);
9805 } catch (err) {
9806 if (true && !hasLoggedError) {
9807 hasLoggedError = true;
9808 warningWithoutStack$1(false, 'React DevTools encountered an error: %s', err);
9809 }
9810 }
9811 };
9812}
9813
9814var isDevToolsPresent = typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ !== 'undefined';
9815
9816function injectInternals(internals) {
9817 if (typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ === 'undefined') {
9818 // No DevTools
9819 return false;
9820 }
9821 var hook = __REACT_DEVTOOLS_GLOBAL_HOOK__;
9822 if (hook.isDisabled) {
9823 // This isn't a real property on the hook, but it can be set to opt out
9824 // of DevTools integration and associated warnings and logs.
9825 // https://github.com/facebook/react/issues/3877
9826 return true;
9827 }
9828 if (!hook.supportsFiber) {
9829 {
9830 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');
9831 }
9832 // DevTools exists, even though it doesn't support Fiber.
9833 return true;
9834 }
9835 try {
9836 var rendererID = hook.inject(internals);
9837 // We have successfully injected, so now it is safe to set up hooks.
9838 onCommitFiberRoot = catchErrors(function (root) {
9839 return hook.onCommitFiberRoot(rendererID, root);
9840 });
9841 onCommitFiberUnmount = catchErrors(function (fiber) {
9842 return hook.onCommitFiberUnmount(rendererID, fiber);
9843 });
9844 } catch (err) {
9845 // Catch all errors because it is unsafe to throw during initialization.
9846 {
9847 warningWithoutStack$1(false, 'React DevTools encountered an error: %s.', err);
9848 }
9849 }
9850 // DevTools exists
9851 return true;
9852}
9853
9854function onCommitRoot(root) {
9855 if (typeof onCommitFiberRoot === 'function') {
9856 onCommitFiberRoot(root);
9857 }
9858}
9859
9860function onCommitUnmount(fiber) {
9861 if (typeof onCommitFiberUnmount === 'function') {
9862 onCommitFiberUnmount(fiber);
9863 }
9864}
9865
9866// Max 31 bit integer. The max integer size in V8 for 32-bit systems.
9867// Math.pow(2, 30) - 1
9868// 0b111111111111111111111111111111
9869var maxSigned31BitInt = 1073741823;
9870
9871var NoWork = 0;
9872var Never = 1;
9873var Sync = maxSigned31BitInt;
9874
9875var UNIT_SIZE = 10;
9876var MAGIC_NUMBER_OFFSET = maxSigned31BitInt - 1;
9877
9878// 1 unit of expiration time represents 10ms.
9879function msToExpirationTime(ms) {
9880 // Always add an offset so that we don't clash with the magic number for NoWork.
9881 return MAGIC_NUMBER_OFFSET - (ms / UNIT_SIZE | 0);
9882}
9883
9884function expirationTimeToMs(expirationTime) {
9885 return (MAGIC_NUMBER_OFFSET - expirationTime) * UNIT_SIZE;
9886}
9887
9888function ceiling(num, precision) {
9889 return ((num / precision | 0) + 1) * precision;
9890}
9891
9892function computeExpirationBucket(currentTime, expirationInMs, bucketSizeMs) {
9893 return MAGIC_NUMBER_OFFSET - ceiling(MAGIC_NUMBER_OFFSET - currentTime + expirationInMs / UNIT_SIZE, bucketSizeMs / UNIT_SIZE);
9894}
9895
9896var LOW_PRIORITY_EXPIRATION = 5000;
9897var LOW_PRIORITY_BATCH_SIZE = 250;
9898
9899function computeAsyncExpiration(currentTime) {
9900 return computeExpirationBucket(currentTime, LOW_PRIORITY_EXPIRATION, LOW_PRIORITY_BATCH_SIZE);
9901}
9902
9903// We intentionally set a higher expiration time for interactive updates in
9904// dev than in production.
9905//
9906// If the main thread is being blocked so long that you hit the expiration,
9907// it's a problem that could be solved with better scheduling.
9908//
9909// People will be more likely to notice this and fix it with the long
9910// expiration time in development.
9911//
9912// In production we opt for better UX at the risk of masking scheduling
9913// problems, by expiring fast.
9914var HIGH_PRIORITY_EXPIRATION = 500;
9915var HIGH_PRIORITY_BATCH_SIZE = 100;
9916
9917function computeInteractiveExpiration(currentTime) {
9918 return computeExpirationBucket(currentTime, HIGH_PRIORITY_EXPIRATION, HIGH_PRIORITY_BATCH_SIZE);
9919}
9920
9921var NoContext = 0;
9922var ConcurrentMode = 1;
9923var StrictMode = 2;
9924var ProfileMode = 4;
9925
9926var hasBadMapPolyfill = void 0;
9927
9928{
9929 hasBadMapPolyfill = false;
9930 try {
9931 var nonExtensibleObject = Object.preventExtensions({});
9932 var testMap = new Map([[nonExtensibleObject, null]]);
9933 var testSet = new Set([nonExtensibleObject]);
9934 // This is necessary for Rollup to not consider these unused.
9935 // https://github.com/rollup/rollup/issues/1771
9936 // TODO: we can remove these if Rollup fixes the bug.
9937 testMap.set(0, 0);
9938 testSet.add(0);
9939 } catch (e) {
9940 // TODO: Consider warning about bad polyfills
9941 hasBadMapPolyfill = true;
9942 }
9943}
9944
9945// A Fiber is work on a Component that needs to be done or was done. There can
9946// be more than one per component.
9947
9948
9949var debugCounter = void 0;
9950
9951{
9952 debugCounter = 1;
9953}
9954
9955function FiberNode(tag, pendingProps, key, mode) {
9956 // Instance
9957 this.tag = tag;
9958 this.key = key;
9959 this.elementType = null;
9960 this.type = null;
9961 this.stateNode = null;
9962
9963 // Fiber
9964 this.return = null;
9965 this.child = null;
9966 this.sibling = null;
9967 this.index = 0;
9968
9969 this.ref = null;
9970
9971 this.pendingProps = pendingProps;
9972 this.memoizedProps = null;
9973 this.updateQueue = null;
9974 this.memoizedState = null;
9975 this.contextDependencies = null;
9976
9977 this.mode = mode;
9978
9979 // Effects
9980 this.effectTag = NoEffect;
9981 this.nextEffect = null;
9982
9983 this.firstEffect = null;
9984 this.lastEffect = null;
9985
9986 this.expirationTime = NoWork;
9987 this.childExpirationTime = NoWork;
9988
9989 this.alternate = null;
9990
9991 if (enableProfilerTimer) {
9992 // Note: The following is done to avoid a v8 performance cliff.
9993 //
9994 // Initializing the fields below to smis and later updating them with
9995 // double values will cause Fibers to end up having separate shapes.
9996 // This behavior/bug has something to do with Object.preventExtension().
9997 // Fortunately this only impacts DEV builds.
9998 // Unfortunately it makes React unusably slow for some applications.
9999 // To work around this, initialize the fields below with doubles.
10000 //
10001 // Learn more about this here:
10002 // https://github.com/facebook/react/issues/14365
10003 // https://bugs.chromium.org/p/v8/issues/detail?id=8538
10004 this.actualDuration = Number.NaN;
10005 this.actualStartTime = Number.NaN;
10006 this.selfBaseDuration = Number.NaN;
10007 this.treeBaseDuration = Number.NaN;
10008
10009 // It's okay to replace the initial doubles with smis after initialization.
10010 // This won't trigger the performance cliff mentioned above,
10011 // and it simplifies other profiler code (including DevTools).
10012 this.actualDuration = 0;
10013 this.actualStartTime = -1;
10014 this.selfBaseDuration = 0;
10015 this.treeBaseDuration = 0;
10016 }
10017
10018 {
10019 this._debugID = debugCounter++;
10020 this._debugSource = null;
10021 this._debugOwner = null;
10022 this._debugIsCurrentlyTiming = false;
10023 if (!hasBadMapPolyfill && typeof Object.preventExtensions === 'function') {
10024 Object.preventExtensions(this);
10025 }
10026 }
10027}
10028
10029// This is a constructor function, rather than a POJO constructor, still
10030// please ensure we do the following:
10031// 1) Nobody should add any instance methods on this. Instance methods can be
10032// more difficult to predict when they get optimized and they are almost
10033// never inlined properly in static compilers.
10034// 2) Nobody should rely on `instanceof Fiber` for type testing. We should
10035// always know when it is a fiber.
10036// 3) We might want to experiment with using numeric keys since they are easier
10037// to optimize in a non-JIT environment.
10038// 4) We can easily go from a constructor to a createFiber object literal if that
10039// is faster.
10040// 5) It should be easy to port this to a C struct and keep a C implementation
10041// compatible.
10042var createFiber = function (tag, pendingProps, key, mode) {
10043 // $FlowFixMe: the shapes are exact here but Flow doesn't like constructors
10044 return new FiberNode(tag, pendingProps, key, mode);
10045};
10046
10047function shouldConstruct(Component) {
10048 var prototype = Component.prototype;
10049 return !!(prototype && prototype.isReactComponent);
10050}
10051
10052function isSimpleFunctionComponent(type) {
10053 return typeof type === 'function' && !shouldConstruct(type) && type.defaultProps === undefined;
10054}
10055
10056function resolveLazyComponentTag(Component) {
10057 if (typeof Component === 'function') {
10058 return shouldConstruct(Component) ? ClassComponent : FunctionComponent;
10059 } else if (Component !== undefined && Component !== null) {
10060 var $$typeof = Component.$$typeof;
10061 if ($$typeof === REACT_FORWARD_REF_TYPE) {
10062 return ForwardRef;
10063 }
10064 if ($$typeof === REACT_MEMO_TYPE) {
10065 return MemoComponent;
10066 }
10067 }
10068 return IndeterminateComponent;
10069}
10070
10071// This is used to create an alternate fiber to do work on.
10072function createWorkInProgress(current, pendingProps, expirationTime) {
10073 var workInProgress = current.alternate;
10074 if (workInProgress === null) {
10075 // We use a double buffering pooling technique because we know that we'll
10076 // only ever need at most two versions of a tree. We pool the "other" unused
10077 // node that we're free to reuse. This is lazily created to avoid allocating
10078 // extra objects for things that are never updated. It also allow us to
10079 // reclaim the extra memory if needed.
10080 workInProgress = createFiber(current.tag, pendingProps, current.key, current.mode);
10081 workInProgress.elementType = current.elementType;
10082 workInProgress.type = current.type;
10083 workInProgress.stateNode = current.stateNode;
10084
10085 {
10086 // DEV-only fields
10087 workInProgress._debugID = current._debugID;
10088 workInProgress._debugSource = current._debugSource;
10089 workInProgress._debugOwner = current._debugOwner;
10090 }
10091
10092 workInProgress.alternate = current;
10093 current.alternate = workInProgress;
10094 } else {
10095 workInProgress.pendingProps = pendingProps;
10096
10097 // We already have an alternate.
10098 // Reset the effect tag.
10099 workInProgress.effectTag = NoEffect;
10100
10101 // The effect list is no longer valid.
10102 workInProgress.nextEffect = null;
10103 workInProgress.firstEffect = null;
10104 workInProgress.lastEffect = null;
10105
10106 if (enableProfilerTimer) {
10107 // We intentionally reset, rather than copy, actualDuration & actualStartTime.
10108 // This prevents time from endlessly accumulating in new commits.
10109 // This has the downside of resetting values for different priority renders,
10110 // But works for yielding (the common case) and should support resuming.
10111 workInProgress.actualDuration = 0;
10112 workInProgress.actualStartTime = -1;
10113 }
10114 }
10115
10116 workInProgress.childExpirationTime = current.childExpirationTime;
10117 workInProgress.expirationTime = current.expirationTime;
10118
10119 workInProgress.child = current.child;
10120 workInProgress.memoizedProps = current.memoizedProps;
10121 workInProgress.memoizedState = current.memoizedState;
10122 workInProgress.updateQueue = current.updateQueue;
10123 workInProgress.contextDependencies = current.contextDependencies;
10124
10125 // These will be overridden during the parent's reconciliation
10126 workInProgress.sibling = current.sibling;
10127 workInProgress.index = current.index;
10128 workInProgress.ref = current.ref;
10129
10130 if (enableProfilerTimer) {
10131 workInProgress.selfBaseDuration = current.selfBaseDuration;
10132 workInProgress.treeBaseDuration = current.treeBaseDuration;
10133 }
10134
10135 return workInProgress;
10136}
10137
10138function createHostRootFiber(isConcurrent) {
10139 var mode = isConcurrent ? ConcurrentMode | StrictMode : NoContext;
10140
10141 if (enableProfilerTimer && isDevToolsPresent) {
10142 // Always collect profile timings when DevTools are present.
10143 // This enables DevTools to start capturing timing at any point–
10144 // Without some nodes in the tree having empty base times.
10145 mode |= ProfileMode;
10146 }
10147
10148 return createFiber(HostRoot, null, null, mode);
10149}
10150
10151function createFiberFromTypeAndProps(type, // React$ElementType
10152key, pendingProps, owner, mode, expirationTime) {
10153 var fiber = void 0;
10154
10155 var fiberTag = IndeterminateComponent;
10156 // The resolved type is set if we know what the final type will be. I.e. it's not lazy.
10157 var resolvedType = type;
10158 if (typeof type === 'function') {
10159 if (shouldConstruct(type)) {
10160 fiberTag = ClassComponent;
10161 }
10162 } else if (typeof type === 'string') {
10163 fiberTag = HostComponent;
10164 } else {
10165 getTag: switch (type) {
10166 case REACT_FRAGMENT_TYPE:
10167 return createFiberFromFragment(pendingProps.children, mode, expirationTime, key);
10168 case REACT_CONCURRENT_MODE_TYPE:
10169 return createFiberFromMode(pendingProps, mode | ConcurrentMode | StrictMode, expirationTime, key);
10170 case REACT_STRICT_MODE_TYPE:
10171 return createFiberFromMode(pendingProps, mode | StrictMode, expirationTime, key);
10172 case REACT_PROFILER_TYPE:
10173 return createFiberFromProfiler(pendingProps, mode, expirationTime, key);
10174 case REACT_SUSPENSE_TYPE:
10175 return createFiberFromSuspense(pendingProps, mode, expirationTime, key);
10176 default:
10177 {
10178 if (typeof type === 'object' && type !== null) {
10179 switch (type.$$typeof) {
10180 case REACT_PROVIDER_TYPE:
10181 fiberTag = ContextProvider;
10182 break getTag;
10183 case REACT_CONTEXT_TYPE:
10184 // This is a consumer
10185 fiberTag = ContextConsumer;
10186 break getTag;
10187 case REACT_FORWARD_REF_TYPE:
10188 fiberTag = ForwardRef;
10189 break getTag;
10190 case REACT_MEMO_TYPE:
10191 fiberTag = MemoComponent;
10192 break getTag;
10193 case REACT_LAZY_TYPE:
10194 fiberTag = LazyComponent;
10195 resolvedType = null;
10196 break getTag;
10197 }
10198 }
10199 var info = '';
10200 {
10201 if (type === undefined || typeof type === 'object' && type !== null && Object.keys(type).length === 0) {
10202 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.';
10203 }
10204 var ownerName = owner ? getComponentName(owner.type) : null;
10205 if (ownerName) {
10206 info += '\n\nCheck the render method of `' + ownerName + '`.';
10207 }
10208 }
10209 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);
10210 }
10211 }
10212 }
10213
10214 fiber = createFiber(fiberTag, pendingProps, key, mode);
10215 fiber.elementType = type;
10216 fiber.type = resolvedType;
10217 fiber.expirationTime = expirationTime;
10218
10219 return fiber;
10220}
10221
10222function createFiberFromElement(element, mode, expirationTime) {
10223 var owner = null;
10224 {
10225 owner = element._owner;
10226 }
10227 var type = element.type;
10228 var key = element.key;
10229 var pendingProps = element.props;
10230 var fiber = createFiberFromTypeAndProps(type, key, pendingProps, owner, mode, expirationTime);
10231 {
10232 fiber._debugSource = element._source;
10233 fiber._debugOwner = element._owner;
10234 }
10235 return fiber;
10236}
10237
10238function createFiberFromFragment(elements, mode, expirationTime, key) {
10239 var fiber = createFiber(Fragment, elements, key, mode);
10240 fiber.expirationTime = expirationTime;
10241 return fiber;
10242}
10243
10244function createFiberFromProfiler(pendingProps, mode, expirationTime, key) {
10245 {
10246 if (typeof pendingProps.id !== 'string' || typeof pendingProps.onRender !== 'function') {
10247 warningWithoutStack$1(false, 'Profiler must specify an "id" string and "onRender" function as props');
10248 }
10249 }
10250
10251 var fiber = createFiber(Profiler, pendingProps, key, mode | ProfileMode);
10252 // TODO: The Profiler fiber shouldn't have a type. It has a tag.
10253 fiber.elementType = REACT_PROFILER_TYPE;
10254 fiber.type = REACT_PROFILER_TYPE;
10255 fiber.expirationTime = expirationTime;
10256
10257 return fiber;
10258}
10259
10260function createFiberFromMode(pendingProps, mode, expirationTime, key) {
10261 var fiber = createFiber(Mode, pendingProps, key, mode);
10262
10263 // TODO: The Mode fiber shouldn't have a type. It has a tag.
10264 var type = (mode & ConcurrentMode) === NoContext ? REACT_STRICT_MODE_TYPE : REACT_CONCURRENT_MODE_TYPE;
10265 fiber.elementType = type;
10266 fiber.type = type;
10267
10268 fiber.expirationTime = expirationTime;
10269 return fiber;
10270}
10271
10272function createFiberFromSuspense(pendingProps, mode, expirationTime, key) {
10273 var fiber = createFiber(SuspenseComponent, pendingProps, key, mode);
10274
10275 // TODO: The SuspenseComponent fiber shouldn't have a type. It has a tag.
10276 var type = REACT_SUSPENSE_TYPE;
10277 fiber.elementType = type;
10278 fiber.type = type;
10279
10280 fiber.expirationTime = expirationTime;
10281 return fiber;
10282}
10283
10284function createFiberFromText(content, mode, expirationTime) {
10285 var fiber = createFiber(HostText, content, null, mode);
10286 fiber.expirationTime = expirationTime;
10287 return fiber;
10288}
10289
10290function createFiberFromHostInstanceForDeletion() {
10291 var fiber = createFiber(HostComponent, null, null, NoContext);
10292 // TODO: These should not need a type.
10293 fiber.elementType = 'DELETED';
10294 fiber.type = 'DELETED';
10295 return fiber;
10296}
10297
10298function createFiberFromPortal(portal, mode, expirationTime) {
10299 var pendingProps = portal.children !== null ? portal.children : [];
10300 var fiber = createFiber(HostPortal, pendingProps, portal.key, mode);
10301 fiber.expirationTime = expirationTime;
10302 fiber.stateNode = {
10303 containerInfo: portal.containerInfo,
10304 pendingChildren: null, // Used by persistent updates
10305 implementation: portal.implementation
10306 };
10307 return fiber;
10308}
10309
10310// Used for stashing WIP properties to replay failed work in DEV.
10311function assignFiberPropertiesInDEV(target, source) {
10312 if (target === null) {
10313 // This Fiber's initial properties will always be overwritten.
10314 // We only use a Fiber to ensure the same hidden class so DEV isn't slow.
10315 target = createFiber(IndeterminateComponent, null, null, NoContext);
10316 }
10317
10318 // This is intentionally written as a list of all properties.
10319 // We tried to use Object.assign() instead but this is called in
10320 // the hottest path, and Object.assign() was too slow:
10321 // https://github.com/facebook/react/issues/12502
10322 // This code is DEV-only so size is not a concern.
10323
10324 target.tag = source.tag;
10325 target.key = source.key;
10326 target.elementType = source.elementType;
10327 target.type = source.type;
10328 target.stateNode = source.stateNode;
10329 target.return = source.return;
10330 target.child = source.child;
10331 target.sibling = source.sibling;
10332 target.index = source.index;
10333 target.ref = source.ref;
10334 target.pendingProps = source.pendingProps;
10335 target.memoizedProps = source.memoizedProps;
10336 target.updateQueue = source.updateQueue;
10337 target.memoizedState = source.memoizedState;
10338 target.contextDependencies = source.contextDependencies;
10339 target.mode = source.mode;
10340 target.effectTag = source.effectTag;
10341 target.nextEffect = source.nextEffect;
10342 target.firstEffect = source.firstEffect;
10343 target.lastEffect = source.lastEffect;
10344 target.expirationTime = source.expirationTime;
10345 target.childExpirationTime = source.childExpirationTime;
10346 target.alternate = source.alternate;
10347 if (enableProfilerTimer) {
10348 target.actualDuration = source.actualDuration;
10349 target.actualStartTime = source.actualStartTime;
10350 target.selfBaseDuration = source.selfBaseDuration;
10351 target.treeBaseDuration = source.treeBaseDuration;
10352 }
10353 target._debugID = source._debugID;
10354 target._debugSource = source._debugSource;
10355 target._debugOwner = source._debugOwner;
10356 target._debugIsCurrentlyTiming = source._debugIsCurrentlyTiming;
10357 return target;
10358}
10359
10360var ReactInternals$2 = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
10361
10362var _ReactInternals$Sched$1 = ReactInternals$2.SchedulerTracing;
10363var __interactionsRef = _ReactInternals$Sched$1.__interactionsRef;
10364var __subscriberRef = _ReactInternals$Sched$1.__subscriberRef;
10365var unstable_clear = _ReactInternals$Sched$1.unstable_clear;
10366var unstable_getCurrent = _ReactInternals$Sched$1.unstable_getCurrent;
10367var unstable_getThreadID = _ReactInternals$Sched$1.unstable_getThreadID;
10368var unstable_subscribe = _ReactInternals$Sched$1.unstable_subscribe;
10369var unstable_trace = _ReactInternals$Sched$1.unstable_trace;
10370var unstable_unsubscribe = _ReactInternals$Sched$1.unstable_unsubscribe;
10371var unstable_wrap = _ReactInternals$Sched$1.unstable_wrap;
10372
10373// TODO: This should be lifted into the renderer.
10374
10375
10376// The following attributes are only used by interaction tracing builds.
10377// They enable interactions to be associated with their async work,
10378// And expose interaction metadata to the React DevTools Profiler plugin.
10379// Note that these attributes are only defined when the enableSchedulerTracing flag is enabled.
10380
10381
10382// Exported FiberRoot type includes all properties,
10383// To avoid requiring potentially error-prone :any casts throughout the project.
10384// Profiling properties are only safe to access in profiling builds (when enableSchedulerTracing is true).
10385// The types are defined separately within this file to ensure they stay in sync.
10386// (We don't have to use an inline :any cast when enableSchedulerTracing is disabled.)
10387
10388
10389function createFiberRoot(containerInfo, isConcurrent, hydrate) {
10390 // Cyclic construction. This cheats the type system right now because
10391 // stateNode is any.
10392 var uninitializedFiber = createHostRootFiber(isConcurrent);
10393
10394 var root = void 0;
10395 if (enableSchedulerTracing) {
10396 root = {
10397 current: uninitializedFiber,
10398 containerInfo: containerInfo,
10399 pendingChildren: null,
10400
10401 earliestPendingTime: NoWork,
10402 latestPendingTime: NoWork,
10403 earliestSuspendedTime: NoWork,
10404 latestSuspendedTime: NoWork,
10405 latestPingedTime: NoWork,
10406
10407 pingCache: null,
10408
10409 didError: false,
10410
10411 pendingCommitExpirationTime: NoWork,
10412 finishedWork: null,
10413 timeoutHandle: noTimeout,
10414 context: null,
10415 pendingContext: null,
10416 hydrate: hydrate,
10417 nextExpirationTimeToWorkOn: NoWork,
10418 expirationTime: NoWork,
10419 firstBatch: null,
10420 nextScheduledRoot: null,
10421
10422 interactionThreadID: unstable_getThreadID(),
10423 memoizedInteractions: new Set(),
10424 pendingInteractionMap: new Map()
10425 };
10426 } else {
10427 root = {
10428 current: uninitializedFiber,
10429 containerInfo: containerInfo,
10430 pendingChildren: null,
10431
10432 pingCache: null,
10433
10434 earliestPendingTime: NoWork,
10435 latestPendingTime: NoWork,
10436 earliestSuspendedTime: NoWork,
10437 latestSuspendedTime: NoWork,
10438 latestPingedTime: NoWork,
10439
10440 didError: false,
10441
10442 pendingCommitExpirationTime: NoWork,
10443 finishedWork: null,
10444 timeoutHandle: noTimeout,
10445 context: null,
10446 pendingContext: null,
10447 hydrate: hydrate,
10448 nextExpirationTimeToWorkOn: NoWork,
10449 expirationTime: NoWork,
10450 firstBatch: null,
10451 nextScheduledRoot: null
10452 };
10453 }
10454
10455 uninitializedFiber.stateNode = root;
10456
10457 // The reason for the way the Flow types are structured in this file,
10458 // Is to avoid needing :any casts everywhere interaction tracing fields are used.
10459 // Unfortunately that requires an :any cast for non-interaction tracing capable builds.
10460 // $FlowFixMe Remove this :any cast and replace it with something better.
10461 return root;
10462}
10463
10464/**
10465 * Forked from fbjs/warning:
10466 * https://github.com/facebook/fbjs/blob/e66ba20ad5be433eb54423f2b097d829324d9de6/packages/fbjs/src/__forks__/warning.js
10467 *
10468 * Only change is we use console.warn instead of console.error,
10469 * and do nothing when 'console' is not supported.
10470 * This really simplifies the code.
10471 * ---
10472 * Similar to invariant but only logs a warning if the condition is not met.
10473 * This can be used to log issues in development environments in critical
10474 * paths. Removing the logging code for production environments will keep the
10475 * same logic and follow the same code paths.
10476 */
10477
10478var lowPriorityWarning = function () {};
10479
10480{
10481 var printWarning$1 = function (format) {
10482 for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
10483 args[_key - 1] = arguments[_key];
10484 }
10485
10486 var argIndex = 0;
10487 var message = 'Warning: ' + format.replace(/%s/g, function () {
10488 return args[argIndex++];
10489 });
10490 if (typeof console !== 'undefined') {
10491 console.warn(message);
10492 }
10493 try {
10494 // --- Welcome to debugging React ---
10495 // This error was thrown as a convenience so that you can use this stack
10496 // to find the callsite that caused this warning to fire.
10497 throw new Error(message);
10498 } catch (x) {}
10499 };
10500
10501 lowPriorityWarning = function (condition, format) {
10502 if (format === undefined) {
10503 throw new Error('`lowPriorityWarning(condition, format, ...args)` requires a warning ' + 'message argument');
10504 }
10505 if (!condition) {
10506 for (var _len2 = arguments.length, args = Array(_len2 > 2 ? _len2 - 2 : 0), _key2 = 2; _key2 < _len2; _key2++) {
10507 args[_key2 - 2] = arguments[_key2];
10508 }
10509
10510 printWarning$1.apply(undefined, [format].concat(args));
10511 }
10512 };
10513}
10514
10515var lowPriorityWarning$1 = lowPriorityWarning;
10516
10517var ReactStrictModeWarnings = {
10518 discardPendingWarnings: function () {},
10519 flushPendingDeprecationWarnings: function () {},
10520 flushPendingUnsafeLifecycleWarnings: function () {},
10521 recordDeprecationWarnings: function (fiber, instance) {},
10522 recordUnsafeLifecycleWarnings: function (fiber, instance) {},
10523 recordLegacyContextWarning: function (fiber, instance) {},
10524 flushLegacyContextWarning: function () {}
10525};
10526
10527{
10528 var LIFECYCLE_SUGGESTIONS = {
10529 UNSAFE_componentWillMount: 'componentDidMount',
10530 UNSAFE_componentWillReceiveProps: 'static getDerivedStateFromProps',
10531 UNSAFE_componentWillUpdate: 'componentDidUpdate'
10532 };
10533
10534 var pendingComponentWillMountWarnings = [];
10535 var pendingComponentWillReceivePropsWarnings = [];
10536 var pendingComponentWillUpdateWarnings = [];
10537 var pendingUnsafeLifecycleWarnings = new Map();
10538 var pendingLegacyContextWarning = new Map();
10539
10540 // Tracks components we have already warned about.
10541 var didWarnAboutDeprecatedLifecycles = new Set();
10542 var didWarnAboutUnsafeLifecycles = new Set();
10543 var didWarnAboutLegacyContext = new Set();
10544
10545 var setToSortedString = function (set) {
10546 var array = [];
10547 set.forEach(function (value) {
10548 array.push(value);
10549 });
10550 return array.sort().join(', ');
10551 };
10552
10553 ReactStrictModeWarnings.discardPendingWarnings = function () {
10554 pendingComponentWillMountWarnings = [];
10555 pendingComponentWillReceivePropsWarnings = [];
10556 pendingComponentWillUpdateWarnings = [];
10557 pendingUnsafeLifecycleWarnings = new Map();
10558 pendingLegacyContextWarning = new Map();
10559 };
10560
10561 ReactStrictModeWarnings.flushPendingUnsafeLifecycleWarnings = function () {
10562 pendingUnsafeLifecycleWarnings.forEach(function (lifecycleWarningsMap, strictRoot) {
10563 var lifecyclesWarningMessages = [];
10564
10565 Object.keys(lifecycleWarningsMap).forEach(function (lifecycle) {
10566 var lifecycleWarnings = lifecycleWarningsMap[lifecycle];
10567 if (lifecycleWarnings.length > 0) {
10568 var componentNames = new Set();
10569 lifecycleWarnings.forEach(function (fiber) {
10570 componentNames.add(getComponentName(fiber.type) || 'Component');
10571 didWarnAboutUnsafeLifecycles.add(fiber.type);
10572 });
10573
10574 var formatted = lifecycle.replace('UNSAFE_', '');
10575 var suggestion = LIFECYCLE_SUGGESTIONS[lifecycle];
10576 var sortedComponentNames = setToSortedString(componentNames);
10577
10578 lifecyclesWarningMessages.push(formatted + ': Please update the following components to use ' + (suggestion + ' instead: ' + sortedComponentNames));
10579 }
10580 });
10581
10582 if (lifecyclesWarningMessages.length > 0) {
10583 var strictRootComponentStack = getStackByFiberInDevAndProd(strictRoot);
10584
10585 warningWithoutStack$1(false, 'Unsafe lifecycle methods were found within a strict-mode tree:%s' + '\n\n%s' + '\n\nLearn more about this warning here:' + '\nhttps://fb.me/react-strict-mode-warnings', strictRootComponentStack, lifecyclesWarningMessages.join('\n\n'));
10586 }
10587 });
10588
10589 pendingUnsafeLifecycleWarnings = new Map();
10590 };
10591
10592 var findStrictRoot = function (fiber) {
10593 var maybeStrictRoot = null;
10594
10595 var node = fiber;
10596 while (node !== null) {
10597 if (node.mode & StrictMode) {
10598 maybeStrictRoot = node;
10599 }
10600 node = node.return;
10601 }
10602
10603 return maybeStrictRoot;
10604 };
10605
10606 ReactStrictModeWarnings.flushPendingDeprecationWarnings = function () {
10607 if (pendingComponentWillMountWarnings.length > 0) {
10608 var uniqueNames = new Set();
10609 pendingComponentWillMountWarnings.forEach(function (fiber) {
10610 uniqueNames.add(getComponentName(fiber.type) || 'Component');
10611 didWarnAboutDeprecatedLifecycles.add(fiber.type);
10612 });
10613
10614 var sortedNames = setToSortedString(uniqueNames);
10615
10616 lowPriorityWarning$1(false, 'componentWillMount is deprecated and will be removed in the next major version. ' + 'Use componentDidMount instead. As a temporary workaround, ' + 'you can rename to UNSAFE_componentWillMount.' + '\n\nPlease update the following components: %s' + '\n\nLearn more about this warning here:' + '\nhttps://fb.me/react-async-component-lifecycle-hooks', sortedNames);
10617
10618 pendingComponentWillMountWarnings = [];
10619 }
10620
10621 if (pendingComponentWillReceivePropsWarnings.length > 0) {
10622 var _uniqueNames = new Set();
10623 pendingComponentWillReceivePropsWarnings.forEach(function (fiber) {
10624 _uniqueNames.add(getComponentName(fiber.type) || 'Component');
10625 didWarnAboutDeprecatedLifecycles.add(fiber.type);
10626 });
10627
10628 var _sortedNames = setToSortedString(_uniqueNames);
10629
10630 lowPriorityWarning$1(false, 'componentWillReceiveProps is deprecated and will be removed in the next major version. ' + 'Use static getDerivedStateFromProps instead.' + '\n\nPlease update the following components: %s' + '\n\nLearn more about this warning here:' + '\nhttps://fb.me/react-async-component-lifecycle-hooks', _sortedNames);
10631
10632 pendingComponentWillReceivePropsWarnings = [];
10633 }
10634
10635 if (pendingComponentWillUpdateWarnings.length > 0) {
10636 var _uniqueNames2 = new Set();
10637 pendingComponentWillUpdateWarnings.forEach(function (fiber) {
10638 _uniqueNames2.add(getComponentName(fiber.type) || 'Component');
10639 didWarnAboutDeprecatedLifecycles.add(fiber.type);
10640 });
10641
10642 var _sortedNames2 = setToSortedString(_uniqueNames2);
10643
10644 lowPriorityWarning$1(false, 'componentWillUpdate is deprecated and will be removed in the next major version. ' + 'Use componentDidUpdate instead. As a temporary workaround, ' + 'you can rename to UNSAFE_componentWillUpdate.' + '\n\nPlease update the following components: %s' + '\n\nLearn more about this warning here:' + '\nhttps://fb.me/react-async-component-lifecycle-hooks', _sortedNames2);
10645
10646 pendingComponentWillUpdateWarnings = [];
10647 }
10648 };
10649
10650 ReactStrictModeWarnings.recordDeprecationWarnings = function (fiber, instance) {
10651 // Dedup strategy: Warn once per component.
10652 if (didWarnAboutDeprecatedLifecycles.has(fiber.type)) {
10653 return;
10654 }
10655
10656 // Don't warn about react-lifecycles-compat polyfilled components.
10657 if (typeof instance.componentWillMount === 'function' && instance.componentWillMount.__suppressDeprecationWarning !== true) {
10658 pendingComponentWillMountWarnings.push(fiber);
10659 }
10660 if (typeof instance.componentWillReceiveProps === 'function' && instance.componentWillReceiveProps.__suppressDeprecationWarning !== true) {
10661 pendingComponentWillReceivePropsWarnings.push(fiber);
10662 }
10663 if (typeof instance.componentWillUpdate === 'function' && instance.componentWillUpdate.__suppressDeprecationWarning !== true) {
10664 pendingComponentWillUpdateWarnings.push(fiber);
10665 }
10666 };
10667
10668 ReactStrictModeWarnings.recordUnsafeLifecycleWarnings = function (fiber, instance) {
10669 var strictRoot = findStrictRoot(fiber);
10670 if (strictRoot === null) {
10671 warningWithoutStack$1(false, 'Expected to find a StrictMode component in a strict mode tree. ' + 'This error is likely caused by a bug in React. Please file an issue.');
10672 return;
10673 }
10674
10675 // Dedup strategy: Warn once per component.
10676 // This is difficult to track any other way since component names
10677 // are often vague and are likely to collide between 3rd party libraries.
10678 // An expand property is probably okay to use here since it's DEV-only,
10679 // and will only be set in the event of serious warnings.
10680 if (didWarnAboutUnsafeLifecycles.has(fiber.type)) {
10681 return;
10682 }
10683
10684 var warningsForRoot = void 0;
10685 if (!pendingUnsafeLifecycleWarnings.has(strictRoot)) {
10686 warningsForRoot = {
10687 UNSAFE_componentWillMount: [],
10688 UNSAFE_componentWillReceiveProps: [],
10689 UNSAFE_componentWillUpdate: []
10690 };
10691
10692 pendingUnsafeLifecycleWarnings.set(strictRoot, warningsForRoot);
10693 } else {
10694 warningsForRoot = pendingUnsafeLifecycleWarnings.get(strictRoot);
10695 }
10696
10697 var unsafeLifecycles = [];
10698 if (typeof instance.componentWillMount === 'function' && instance.componentWillMount.__suppressDeprecationWarning !== true || typeof instance.UNSAFE_componentWillMount === 'function') {
10699 unsafeLifecycles.push('UNSAFE_componentWillMount');
10700 }
10701 if (typeof instance.componentWillReceiveProps === 'function' && instance.componentWillReceiveProps.__suppressDeprecationWarning !== true || typeof instance.UNSAFE_componentWillReceiveProps === 'function') {
10702 unsafeLifecycles.push('UNSAFE_componentWillReceiveProps');
10703 }
10704 if (typeof instance.componentWillUpdate === 'function' && instance.componentWillUpdate.__suppressDeprecationWarning !== true || typeof instance.UNSAFE_componentWillUpdate === 'function') {
10705 unsafeLifecycles.push('UNSAFE_componentWillUpdate');
10706 }
10707
10708 if (unsafeLifecycles.length > 0) {
10709 unsafeLifecycles.forEach(function (lifecycle) {
10710 warningsForRoot[lifecycle].push(fiber);
10711 });
10712 }
10713 };
10714
10715 ReactStrictModeWarnings.recordLegacyContextWarning = function (fiber, instance) {
10716 var strictRoot = findStrictRoot(fiber);
10717 if (strictRoot === null) {
10718 warningWithoutStack$1(false, 'Expected to find a StrictMode component in a strict mode tree. ' + 'This error is likely caused by a bug in React. Please file an issue.');
10719 return;
10720 }
10721
10722 // Dedup strategy: Warn once per component.
10723 if (didWarnAboutLegacyContext.has(fiber.type)) {
10724 return;
10725 }
10726
10727 var warningsForRoot = pendingLegacyContextWarning.get(strictRoot);
10728
10729 if (fiber.type.contextTypes != null || fiber.type.childContextTypes != null || instance !== null && typeof instance.getChildContext === 'function') {
10730 if (warningsForRoot === undefined) {
10731 warningsForRoot = [];
10732 pendingLegacyContextWarning.set(strictRoot, warningsForRoot);
10733 }
10734 warningsForRoot.push(fiber);
10735 }
10736 };
10737
10738 ReactStrictModeWarnings.flushLegacyContextWarning = function () {
10739 pendingLegacyContextWarning.forEach(function (fiberArray, strictRoot) {
10740 var uniqueNames = new Set();
10741 fiberArray.forEach(function (fiber) {
10742 uniqueNames.add(getComponentName(fiber.type) || 'Component');
10743 didWarnAboutLegacyContext.add(fiber.type);
10744 });
10745
10746 var sortedNames = setToSortedString(uniqueNames);
10747 var strictRootComponentStack = getStackByFiberInDevAndProd(strictRoot);
10748
10749 warningWithoutStack$1(false, 'Legacy context API has been detected within a strict-mode tree: %s' + '\n\nPlease update the following components: %s' + '\n\nLearn more about this warning here:' + '\nhttps://fb.me/react-strict-mode-warnings', strictRootComponentStack, sortedNames);
10750 });
10751 };
10752}
10753
10754// This lets us hook into Fiber to debug what it's doing.
10755// See https://github.com/facebook/react/pull/8033.
10756// This is not part of the public API, not even for React DevTools.
10757// You may only inject a debugTool if you work on React Fiber itself.
10758var ReactFiberInstrumentation = {
10759 debugTool: null
10760};
10761
10762var ReactFiberInstrumentation_1 = ReactFiberInstrumentation;
10763
10764// TODO: Offscreen updates should never suspend. However, a promise that
10765// suspended inside an offscreen subtree should be able to ping at the priority
10766// of the outer render.
10767
10768function markPendingPriorityLevel(root, expirationTime) {
10769 // If there's a gap between completing a failed root and retrying it,
10770 // additional updates may be scheduled. Clear `didError`, in case the update
10771 // is sufficient to fix the error.
10772 root.didError = false;
10773
10774 // Update the latest and earliest pending times
10775 var earliestPendingTime = root.earliestPendingTime;
10776 if (earliestPendingTime === NoWork) {
10777 // No other pending updates.
10778 root.earliestPendingTime = root.latestPendingTime = expirationTime;
10779 } else {
10780 if (earliestPendingTime < expirationTime) {
10781 // This is the earliest pending update.
10782 root.earliestPendingTime = expirationTime;
10783 } else {
10784 var latestPendingTime = root.latestPendingTime;
10785 if (latestPendingTime > expirationTime) {
10786 // This is the latest pending update
10787 root.latestPendingTime = expirationTime;
10788 }
10789 }
10790 }
10791 findNextExpirationTimeToWorkOn(expirationTime, root);
10792}
10793
10794function markCommittedPriorityLevels(root, earliestRemainingTime) {
10795 root.didError = false;
10796
10797 if (earliestRemainingTime === NoWork) {
10798 // Fast path. There's no remaining work. Clear everything.
10799 root.earliestPendingTime = NoWork;
10800 root.latestPendingTime = NoWork;
10801 root.earliestSuspendedTime = NoWork;
10802 root.latestSuspendedTime = NoWork;
10803 root.latestPingedTime = NoWork;
10804 findNextExpirationTimeToWorkOn(NoWork, root);
10805 return;
10806 }
10807
10808 if (earliestRemainingTime < root.latestPingedTime) {
10809 root.latestPingedTime = NoWork;
10810 }
10811
10812 // Let's see if the previous latest known pending level was just flushed.
10813 var latestPendingTime = root.latestPendingTime;
10814 if (latestPendingTime !== NoWork) {
10815 if (latestPendingTime > earliestRemainingTime) {
10816 // We've flushed all the known pending levels.
10817 root.earliestPendingTime = root.latestPendingTime = NoWork;
10818 } else {
10819 var earliestPendingTime = root.earliestPendingTime;
10820 if (earliestPendingTime > earliestRemainingTime) {
10821 // We've flushed the earliest known pending level. Set this to the
10822 // latest pending time.
10823 root.earliestPendingTime = root.latestPendingTime;
10824 }
10825 }
10826 }
10827
10828 // Now let's handle the earliest remaining level in the whole tree. We need to
10829 // decide whether to treat it as a pending level or as suspended. Check
10830 // it falls within the range of known suspended levels.
10831
10832 var earliestSuspendedTime = root.earliestSuspendedTime;
10833 if (earliestSuspendedTime === NoWork) {
10834 // There's no suspended work. Treat the earliest remaining level as a
10835 // pending level.
10836 markPendingPriorityLevel(root, earliestRemainingTime);
10837 findNextExpirationTimeToWorkOn(NoWork, root);
10838 return;
10839 }
10840
10841 var latestSuspendedTime = root.latestSuspendedTime;
10842 if (earliestRemainingTime < latestSuspendedTime) {
10843 // The earliest remaining level is later than all the suspended work. That
10844 // means we've flushed all the suspended work.
10845 root.earliestSuspendedTime = NoWork;
10846 root.latestSuspendedTime = NoWork;
10847 root.latestPingedTime = NoWork;
10848
10849 // There's no suspended work. Treat the earliest remaining level as a
10850 // pending level.
10851 markPendingPriorityLevel(root, earliestRemainingTime);
10852 findNextExpirationTimeToWorkOn(NoWork, root);
10853 return;
10854 }
10855
10856 if (earliestRemainingTime > earliestSuspendedTime) {
10857 // The earliest remaining time is earlier than all the suspended work.
10858 // Treat it as a pending update.
10859 markPendingPriorityLevel(root, earliestRemainingTime);
10860 findNextExpirationTimeToWorkOn(NoWork, root);
10861 return;
10862 }
10863
10864 // The earliest remaining time falls within the range of known suspended
10865 // levels. We should treat this as suspended work.
10866 findNextExpirationTimeToWorkOn(NoWork, root);
10867}
10868
10869function hasLowerPriorityWork(root, erroredExpirationTime) {
10870 var latestPendingTime = root.latestPendingTime;
10871 var latestSuspendedTime = root.latestSuspendedTime;
10872 var latestPingedTime = root.latestPingedTime;
10873 return latestPendingTime !== NoWork && latestPendingTime < erroredExpirationTime || latestSuspendedTime !== NoWork && latestSuspendedTime < erroredExpirationTime || latestPingedTime !== NoWork && latestPingedTime < erroredExpirationTime;
10874}
10875
10876function isPriorityLevelSuspended(root, expirationTime) {
10877 var earliestSuspendedTime = root.earliestSuspendedTime;
10878 var latestSuspendedTime = root.latestSuspendedTime;
10879 return earliestSuspendedTime !== NoWork && expirationTime <= earliestSuspendedTime && expirationTime >= latestSuspendedTime;
10880}
10881
10882function markSuspendedPriorityLevel(root, suspendedTime) {
10883 root.didError = false;
10884 clearPing(root, suspendedTime);
10885
10886 // First, check the known pending levels and update them if needed.
10887 var earliestPendingTime = root.earliestPendingTime;
10888 var latestPendingTime = root.latestPendingTime;
10889 if (earliestPendingTime === suspendedTime) {
10890 if (latestPendingTime === suspendedTime) {
10891 // Both known pending levels were suspended. Clear them.
10892 root.earliestPendingTime = root.latestPendingTime = NoWork;
10893 } else {
10894 // The earliest pending level was suspended. Clear by setting it to the
10895 // latest pending level.
10896 root.earliestPendingTime = latestPendingTime;
10897 }
10898 } else if (latestPendingTime === suspendedTime) {
10899 // The latest pending level was suspended. Clear by setting it to the
10900 // latest pending level.
10901 root.latestPendingTime = earliestPendingTime;
10902 }
10903
10904 // Finally, update the known suspended levels.
10905 var earliestSuspendedTime = root.earliestSuspendedTime;
10906 var latestSuspendedTime = root.latestSuspendedTime;
10907 if (earliestSuspendedTime === NoWork) {
10908 // No other suspended levels.
10909 root.earliestSuspendedTime = root.latestSuspendedTime = suspendedTime;
10910 } else {
10911 if (earliestSuspendedTime < suspendedTime) {
10912 // This is the earliest suspended level.
10913 root.earliestSuspendedTime = suspendedTime;
10914 } else if (latestSuspendedTime > suspendedTime) {
10915 // This is the latest suspended level
10916 root.latestSuspendedTime = suspendedTime;
10917 }
10918 }
10919
10920 findNextExpirationTimeToWorkOn(suspendedTime, root);
10921}
10922
10923function markPingedPriorityLevel(root, pingedTime) {
10924 root.didError = false;
10925
10926 // TODO: When we add back resuming, we need to ensure the progressed work
10927 // is thrown out and not reused during the restarted render. One way to
10928 // invalidate the progressed work is to restart at expirationTime + 1.
10929 var latestPingedTime = root.latestPingedTime;
10930 if (latestPingedTime === NoWork || latestPingedTime > pingedTime) {
10931 root.latestPingedTime = pingedTime;
10932 }
10933 findNextExpirationTimeToWorkOn(pingedTime, root);
10934}
10935
10936function clearPing(root, completedTime) {
10937 var latestPingedTime = root.latestPingedTime;
10938 if (latestPingedTime >= completedTime) {
10939 root.latestPingedTime = NoWork;
10940 }
10941}
10942
10943function findEarliestOutstandingPriorityLevel(root, renderExpirationTime) {
10944 var earliestExpirationTime = renderExpirationTime;
10945
10946 var earliestPendingTime = root.earliestPendingTime;
10947 var earliestSuspendedTime = root.earliestSuspendedTime;
10948 if (earliestPendingTime > earliestExpirationTime) {
10949 earliestExpirationTime = earliestPendingTime;
10950 }
10951 if (earliestSuspendedTime > earliestExpirationTime) {
10952 earliestExpirationTime = earliestSuspendedTime;
10953 }
10954 return earliestExpirationTime;
10955}
10956
10957function didExpireAtExpirationTime(root, currentTime) {
10958 var expirationTime = root.expirationTime;
10959 if (expirationTime !== NoWork && currentTime <= expirationTime) {
10960 // The root has expired. Flush all work up to the current time.
10961 root.nextExpirationTimeToWorkOn = currentTime;
10962 }
10963}
10964
10965function findNextExpirationTimeToWorkOn(completedExpirationTime, root) {
10966 var earliestSuspendedTime = root.earliestSuspendedTime;
10967 var latestSuspendedTime = root.latestSuspendedTime;
10968 var earliestPendingTime = root.earliestPendingTime;
10969 var latestPingedTime = root.latestPingedTime;
10970
10971 // Work on the earliest pending time. Failing that, work on the latest
10972 // pinged time.
10973 var nextExpirationTimeToWorkOn = earliestPendingTime !== NoWork ? earliestPendingTime : latestPingedTime;
10974
10975 // If there is no pending or pinged work, check if there's suspended work
10976 // that's lower priority than what we just completed.
10977 if (nextExpirationTimeToWorkOn === NoWork && (completedExpirationTime === NoWork || latestSuspendedTime < completedExpirationTime)) {
10978 // The lowest priority suspended work is the work most likely to be
10979 // committed next. Let's start rendering it again, so that if it times out,
10980 // it's ready to commit.
10981 nextExpirationTimeToWorkOn = latestSuspendedTime;
10982 }
10983
10984 var expirationTime = nextExpirationTimeToWorkOn;
10985 if (expirationTime !== NoWork && earliestSuspendedTime > expirationTime) {
10986 // Expire using the earliest known expiration time.
10987 expirationTime = earliestSuspendedTime;
10988 }
10989
10990 root.nextExpirationTimeToWorkOn = nextExpirationTimeToWorkOn;
10991 root.expirationTime = expirationTime;
10992}
10993
10994function resolveDefaultProps(Component, baseProps) {
10995 if (Component && Component.defaultProps) {
10996 // Resolve default props. Taken from ReactElement
10997 var props = _assign({}, baseProps);
10998 var defaultProps = Component.defaultProps;
10999 for (var propName in defaultProps) {
11000 if (props[propName] === undefined) {
11001 props[propName] = defaultProps[propName];
11002 }
11003 }
11004 return props;
11005 }
11006 return baseProps;
11007}
11008
11009function readLazyComponentType(lazyComponent) {
11010 var status = lazyComponent._status;
11011 var result = lazyComponent._result;
11012 switch (status) {
11013 case Resolved:
11014 {
11015 var Component = result;
11016 return Component;
11017 }
11018 case Rejected:
11019 {
11020 var error = result;
11021 throw error;
11022 }
11023 case Pending:
11024 {
11025 var thenable = result;
11026 throw thenable;
11027 }
11028 default:
11029 {
11030 lazyComponent._status = Pending;
11031 var ctor = lazyComponent._ctor;
11032 var _thenable = ctor();
11033 _thenable.then(function (moduleObject) {
11034 if (lazyComponent._status === Pending) {
11035 var defaultExport = moduleObject.default;
11036 {
11037 if (defaultExport === undefined) {
11038 warning$1(false, 'lazy: Expected the result of a dynamic import() call. ' + 'Instead received: %s\n\nYour code should look like: \n ' + "const MyComponent = lazy(() => import('./MyComponent'))", moduleObject);
11039 }
11040 }
11041 lazyComponent._status = Resolved;
11042 lazyComponent._result = defaultExport;
11043 }
11044 }, function (error) {
11045 if (lazyComponent._status === Pending) {
11046 lazyComponent._status = Rejected;
11047 lazyComponent._result = error;
11048 }
11049 });
11050 // Handle synchronous thenables.
11051 switch (lazyComponent._status) {
11052 case Resolved:
11053 return lazyComponent._result;
11054 case Rejected:
11055 throw lazyComponent._result;
11056 }
11057 lazyComponent._result = _thenable;
11058 throw _thenable;
11059 }
11060 }
11061}
11062
11063var fakeInternalInstance = {};
11064var isArray$1 = Array.isArray;
11065
11066// React.Component uses a shared frozen object by default.
11067// We'll use it to determine whether we need to initialize legacy refs.
11068var emptyRefsObject = new React.Component().refs;
11069
11070var didWarnAboutStateAssignmentForComponent = void 0;
11071var didWarnAboutUninitializedState = void 0;
11072var didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate = void 0;
11073var didWarnAboutLegacyLifecyclesAndDerivedState = void 0;
11074var didWarnAboutUndefinedDerivedState = void 0;
11075var warnOnUndefinedDerivedState = void 0;
11076var warnOnInvalidCallback$1 = void 0;
11077var didWarnAboutDirectlyAssigningPropsToState = void 0;
11078var didWarnAboutContextTypeAndContextTypes = void 0;
11079var didWarnAboutInvalidateContextType = void 0;
11080
11081{
11082 didWarnAboutStateAssignmentForComponent = new Set();
11083 didWarnAboutUninitializedState = new Set();
11084 didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate = new Set();
11085 didWarnAboutLegacyLifecyclesAndDerivedState = new Set();
11086 didWarnAboutDirectlyAssigningPropsToState = new Set();
11087 didWarnAboutUndefinedDerivedState = new Set();
11088 didWarnAboutContextTypeAndContextTypes = new Set();
11089 didWarnAboutInvalidateContextType = new Set();
11090
11091 var didWarnOnInvalidCallback = new Set();
11092
11093 warnOnInvalidCallback$1 = function (callback, callerName) {
11094 if (callback === null || typeof callback === 'function') {
11095 return;
11096 }
11097 var key = callerName + '_' + callback;
11098 if (!didWarnOnInvalidCallback.has(key)) {
11099 didWarnOnInvalidCallback.add(key);
11100 warningWithoutStack$1(false, '%s(...): Expected the last optional `callback` argument to be a ' + 'function. Instead received: %s.', callerName, callback);
11101 }
11102 };
11103
11104 warnOnUndefinedDerivedState = function (type, partialState) {
11105 if (partialState === undefined) {
11106 var componentName = getComponentName(type) || 'Component';
11107 if (!didWarnAboutUndefinedDerivedState.has(componentName)) {
11108 didWarnAboutUndefinedDerivedState.add(componentName);
11109 warningWithoutStack$1(false, '%s.getDerivedStateFromProps(): A valid state object (or null) must be returned. ' + 'You have returned undefined.', componentName);
11110 }
11111 }
11112 };
11113
11114 // This is so gross but it's at least non-critical and can be removed if
11115 // it causes problems. This is meant to give a nicer error message for
11116 // ReactDOM15.unstable_renderSubtreeIntoContainer(reactDOM16Component,
11117 // ...)) which otherwise throws a "_processChildContext is not a function"
11118 // exception.
11119 Object.defineProperty(fakeInternalInstance, '_processChildContext', {
11120 enumerable: false,
11121 value: function () {
11122 invariant(false, '_processChildContext is not available in React 16+. This likely means you have multiple copies of React and are attempting to nest a React 15 tree inside a React 16 tree using unstable_renderSubtreeIntoContainer, which isn\'t supported. Try to make sure you have only one copy of React (and ideally, switch to ReactDOM.createPortal).');
11123 }
11124 });
11125 Object.freeze(fakeInternalInstance);
11126}
11127
11128function applyDerivedStateFromProps(workInProgress, ctor, getDerivedStateFromProps, nextProps) {
11129 var prevState = workInProgress.memoizedState;
11130
11131 {
11132 if (debugRenderPhaseSideEffects || debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) {
11133 // Invoke the function an extra time to help detect side-effects.
11134 getDerivedStateFromProps(nextProps, prevState);
11135 }
11136 }
11137
11138 var partialState = getDerivedStateFromProps(nextProps, prevState);
11139
11140 {
11141 warnOnUndefinedDerivedState(ctor, partialState);
11142 }
11143 // Merge the partial state and the previous state.
11144 var memoizedState = partialState === null || partialState === undefined ? prevState : _assign({}, prevState, partialState);
11145 workInProgress.memoizedState = memoizedState;
11146
11147 // Once the update queue is empty, persist the derived state onto the
11148 // base state.
11149 var updateQueue = workInProgress.updateQueue;
11150 if (updateQueue !== null && workInProgress.expirationTime === NoWork) {
11151 updateQueue.baseState = memoizedState;
11152 }
11153}
11154
11155var classComponentUpdater = {
11156 isMounted: isMounted,
11157 enqueueSetState: function (inst, payload, callback) {
11158 var fiber = get(inst);
11159 var currentTime = requestCurrentTime();
11160 var expirationTime = computeExpirationForFiber(currentTime, fiber);
11161
11162 var update = createUpdate(expirationTime);
11163 update.payload = payload;
11164 if (callback !== undefined && callback !== null) {
11165 {
11166 warnOnInvalidCallback$1(callback, 'setState');
11167 }
11168 update.callback = callback;
11169 }
11170
11171 flushPassiveEffects();
11172 enqueueUpdate(fiber, update);
11173 scheduleWork(fiber, expirationTime);
11174 },
11175 enqueueReplaceState: function (inst, payload, callback) {
11176 var fiber = get(inst);
11177 var currentTime = requestCurrentTime();
11178 var expirationTime = computeExpirationForFiber(currentTime, fiber);
11179
11180 var update = createUpdate(expirationTime);
11181 update.tag = ReplaceState;
11182 update.payload = payload;
11183
11184 if (callback !== undefined && callback !== null) {
11185 {
11186 warnOnInvalidCallback$1(callback, 'replaceState');
11187 }
11188 update.callback = callback;
11189 }
11190
11191 flushPassiveEffects();
11192 enqueueUpdate(fiber, update);
11193 scheduleWork(fiber, expirationTime);
11194 },
11195 enqueueForceUpdate: function (inst, callback) {
11196 var fiber = get(inst);
11197 var currentTime = requestCurrentTime();
11198 var expirationTime = computeExpirationForFiber(currentTime, fiber);
11199
11200 var update = createUpdate(expirationTime);
11201 update.tag = ForceUpdate;
11202
11203 if (callback !== undefined && callback !== null) {
11204 {
11205 warnOnInvalidCallback$1(callback, 'forceUpdate');
11206 }
11207 update.callback = callback;
11208 }
11209
11210 flushPassiveEffects();
11211 enqueueUpdate(fiber, update);
11212 scheduleWork(fiber, expirationTime);
11213 }
11214};
11215
11216function checkShouldComponentUpdate(workInProgress, ctor, oldProps, newProps, oldState, newState, nextContext) {
11217 var instance = workInProgress.stateNode;
11218 if (typeof instance.shouldComponentUpdate === 'function') {
11219 startPhaseTimer(workInProgress, 'shouldComponentUpdate');
11220 var shouldUpdate = instance.shouldComponentUpdate(newProps, newState, nextContext);
11221 stopPhaseTimer();
11222
11223 {
11224 !(shouldUpdate !== undefined) ? warningWithoutStack$1(false, '%s.shouldComponentUpdate(): Returned undefined instead of a ' + 'boolean value. Make sure to return true or false.', getComponentName(ctor) || 'Component') : void 0;
11225 }
11226
11227 return shouldUpdate;
11228 }
11229
11230 if (ctor.prototype && ctor.prototype.isPureReactComponent) {
11231 return !shallowEqual(oldProps, newProps) || !shallowEqual(oldState, newState);
11232 }
11233
11234 return true;
11235}
11236
11237function checkClassInstance(workInProgress, ctor, newProps) {
11238 var instance = workInProgress.stateNode;
11239 {
11240 var name = getComponentName(ctor) || 'Component';
11241 var renderPresent = instance.render;
11242
11243 if (!renderPresent) {
11244 if (ctor.prototype && typeof ctor.prototype.render === 'function') {
11245 warningWithoutStack$1(false, '%s(...): No `render` method found on the returned component ' + 'instance: did you accidentally return an object from the constructor?', name);
11246 } else {
11247 warningWithoutStack$1(false, '%s(...): No `render` method found on the returned component ' + 'instance: you may have forgotten to define `render`.', name);
11248 }
11249 }
11250
11251 var noGetInitialStateOnES6 = !instance.getInitialState || instance.getInitialState.isReactClassApproved || instance.state;
11252 !noGetInitialStateOnES6 ? warningWithoutStack$1(false, 'getInitialState was defined on %s, a plain JavaScript class. ' + 'This is only supported for classes created using React.createClass. ' + 'Did you mean to define a state property instead?', name) : void 0;
11253 var noGetDefaultPropsOnES6 = !instance.getDefaultProps || instance.getDefaultProps.isReactClassApproved;
11254 !noGetDefaultPropsOnES6 ? warningWithoutStack$1(false, 'getDefaultProps was defined on %s, a plain JavaScript class. ' + 'This is only supported for classes created using React.createClass. ' + 'Use a static property to define defaultProps instead.', name) : void 0;
11255 var noInstancePropTypes = !instance.propTypes;
11256 !noInstancePropTypes ? warningWithoutStack$1(false, 'propTypes was defined as an instance property on %s. Use a static ' + 'property to define propTypes instead.', name) : void 0;
11257 var noInstanceContextType = !instance.contextType;
11258 !noInstanceContextType ? warningWithoutStack$1(false, 'contextType was defined as an instance property on %s. Use a static ' + 'property to define contextType instead.', name) : void 0;
11259 var noInstanceContextTypes = !instance.contextTypes;
11260 !noInstanceContextTypes ? warningWithoutStack$1(false, 'contextTypes was defined as an instance property on %s. Use a static ' + 'property to define contextTypes instead.', name) : void 0;
11261
11262 if (ctor.contextType && ctor.contextTypes && !didWarnAboutContextTypeAndContextTypes.has(ctor)) {
11263 didWarnAboutContextTypeAndContextTypes.add(ctor);
11264 warningWithoutStack$1(false, '%s declares both contextTypes and contextType static properties. ' + 'The legacy contextTypes property will be ignored.', name);
11265 }
11266
11267 var noComponentShouldUpdate = typeof instance.componentShouldUpdate !== 'function';
11268 !noComponentShouldUpdate ? warningWithoutStack$1(false, '%s has a method called ' + 'componentShouldUpdate(). Did you mean shouldComponentUpdate()? ' + 'The name is phrased as a question because the function is ' + 'expected to return a value.', name) : void 0;
11269 if (ctor.prototype && ctor.prototype.isPureReactComponent && typeof instance.shouldComponentUpdate !== 'undefined') {
11270 warningWithoutStack$1(false, '%s has a method called shouldComponentUpdate(). ' + 'shouldComponentUpdate should not be used when extending React.PureComponent. ' + 'Please extend React.Component if shouldComponentUpdate is used.', getComponentName(ctor) || 'A pure component');
11271 }
11272 var noComponentDidUnmount = typeof instance.componentDidUnmount !== 'function';
11273 !noComponentDidUnmount ? warningWithoutStack$1(false, '%s has a method called ' + 'componentDidUnmount(). But there is no such lifecycle method. ' + 'Did you mean componentWillUnmount()?', name) : void 0;
11274 var noComponentDidReceiveProps = typeof instance.componentDidReceiveProps !== 'function';
11275 !noComponentDidReceiveProps ? warningWithoutStack$1(false, '%s has a method called ' + 'componentDidReceiveProps(). But there is no such lifecycle method. ' + 'If you meant to update the state in response to changing props, ' + 'use componentWillReceiveProps(). If you meant to fetch data or ' + 'run side-effects or mutations after React has updated the UI, use componentDidUpdate().', name) : void 0;
11276 var noComponentWillRecieveProps = typeof instance.componentWillRecieveProps !== 'function';
11277 !noComponentWillRecieveProps ? warningWithoutStack$1(false, '%s has a method called ' + 'componentWillRecieveProps(). Did you mean componentWillReceiveProps()?', name) : void 0;
11278 var noUnsafeComponentWillRecieveProps = typeof instance.UNSAFE_componentWillRecieveProps !== 'function';
11279 !noUnsafeComponentWillRecieveProps ? warningWithoutStack$1(false, '%s has a method called ' + 'UNSAFE_componentWillRecieveProps(). Did you mean UNSAFE_componentWillReceiveProps()?', name) : void 0;
11280 var hasMutatedProps = instance.props !== newProps;
11281 !(instance.props === undefined || !hasMutatedProps) ? warningWithoutStack$1(false, '%s(...): When calling super() in `%s`, make sure to pass ' + "up the same props that your component's constructor was passed.", name, name) : void 0;
11282 var noInstanceDefaultProps = !instance.defaultProps;
11283 !noInstanceDefaultProps ? warningWithoutStack$1(false, 'Setting defaultProps as an instance property on %s is not supported and will be ignored.' + ' Instead, define defaultProps as a static property on %s.', name, name) : void 0;
11284
11285 if (typeof instance.getSnapshotBeforeUpdate === 'function' && typeof instance.componentDidUpdate !== 'function' && !didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate.has(ctor)) {
11286 didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate.add(ctor);
11287 warningWithoutStack$1(false, '%s: getSnapshotBeforeUpdate() should be used with componentDidUpdate(). ' + 'This component defines getSnapshotBeforeUpdate() only.', getComponentName(ctor));
11288 }
11289
11290 var noInstanceGetDerivedStateFromProps = typeof instance.getDerivedStateFromProps !== 'function';
11291 !noInstanceGetDerivedStateFromProps ? warningWithoutStack$1(false, '%s: getDerivedStateFromProps() is defined as an instance method ' + 'and will be ignored. Instead, declare it as a static method.', name) : void 0;
11292 var noInstanceGetDerivedStateFromCatch = typeof instance.getDerivedStateFromError !== 'function';
11293 !noInstanceGetDerivedStateFromCatch ? warningWithoutStack$1(false, '%s: getDerivedStateFromError() is defined as an instance method ' + 'and will be ignored. Instead, declare it as a static method.', name) : void 0;
11294 var noStaticGetSnapshotBeforeUpdate = typeof ctor.getSnapshotBeforeUpdate !== 'function';
11295 !noStaticGetSnapshotBeforeUpdate ? warningWithoutStack$1(false, '%s: getSnapshotBeforeUpdate() is defined as a static method ' + 'and will be ignored. Instead, declare it as an instance method.', name) : void 0;
11296 var _state = instance.state;
11297 if (_state && (typeof _state !== 'object' || isArray$1(_state))) {
11298 warningWithoutStack$1(false, '%s.state: must be set to an object or null', name);
11299 }
11300 if (typeof instance.getChildContext === 'function') {
11301 !(typeof ctor.childContextTypes === 'object') ? warningWithoutStack$1(false, '%s.getChildContext(): childContextTypes must be defined in order to ' + 'use getChildContext().', name) : void 0;
11302 }
11303 }
11304}
11305
11306function adoptClassInstance(workInProgress, instance) {
11307 instance.updater = classComponentUpdater;
11308 workInProgress.stateNode = instance;
11309 // The instance needs access to the fiber so that it can schedule updates
11310 set(instance, workInProgress);
11311 {
11312 instance._reactInternalInstance = fakeInternalInstance;
11313 }
11314}
11315
11316function constructClassInstance(workInProgress, ctor, props, renderExpirationTime) {
11317 var isLegacyContextConsumer = false;
11318 var unmaskedContext = emptyContextObject;
11319 var context = null;
11320 var contextType = ctor.contextType;
11321 if (typeof contextType === 'object' && contextType !== null) {
11322 {
11323 if (contextType.$$typeof !== REACT_CONTEXT_TYPE && !didWarnAboutInvalidateContextType.has(ctor)) {
11324 didWarnAboutInvalidateContextType.add(ctor);
11325 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');
11326 }
11327 }
11328
11329 context = readContext(contextType);
11330 } else {
11331 unmaskedContext = getUnmaskedContext(workInProgress, ctor, true);
11332 var contextTypes = ctor.contextTypes;
11333 isLegacyContextConsumer = contextTypes !== null && contextTypes !== undefined;
11334 context = isLegacyContextConsumer ? getMaskedContext(workInProgress, unmaskedContext) : emptyContextObject;
11335 }
11336
11337 // Instantiate twice to help detect side-effects.
11338 {
11339 if (debugRenderPhaseSideEffects || debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) {
11340 new ctor(props, context); // eslint-disable-line no-new
11341 }
11342 }
11343
11344 var instance = new ctor(props, context);
11345 var state = workInProgress.memoizedState = instance.state !== null && instance.state !== undefined ? instance.state : null;
11346 adoptClassInstance(workInProgress, instance);
11347
11348 {
11349 if (typeof ctor.getDerivedStateFromProps === 'function' && state === null) {
11350 var componentName = getComponentName(ctor) || 'Component';
11351 if (!didWarnAboutUninitializedState.has(componentName)) {
11352 didWarnAboutUninitializedState.add(componentName);
11353 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);
11354 }
11355 }
11356
11357 // If new component APIs are defined, "unsafe" lifecycles won't be called.
11358 // Warn about these lifecycles if they are present.
11359 // Don't warn about react-lifecycles-compat polyfilled methods though.
11360 if (typeof ctor.getDerivedStateFromProps === 'function' || typeof instance.getSnapshotBeforeUpdate === 'function') {
11361 var foundWillMountName = null;
11362 var foundWillReceivePropsName = null;
11363 var foundWillUpdateName = null;
11364 if (typeof instance.componentWillMount === 'function' && instance.componentWillMount.__suppressDeprecationWarning !== true) {
11365 foundWillMountName = 'componentWillMount';
11366 } else if (typeof instance.UNSAFE_componentWillMount === 'function') {
11367 foundWillMountName = 'UNSAFE_componentWillMount';
11368 }
11369 if (typeof instance.componentWillReceiveProps === 'function' && instance.componentWillReceiveProps.__suppressDeprecationWarning !== true) {
11370 foundWillReceivePropsName = 'componentWillReceiveProps';
11371 } else if (typeof instance.UNSAFE_componentWillReceiveProps === 'function') {
11372 foundWillReceivePropsName = 'UNSAFE_componentWillReceiveProps';
11373 }
11374 if (typeof instance.componentWillUpdate === 'function' && instance.componentWillUpdate.__suppressDeprecationWarning !== true) {
11375 foundWillUpdateName = 'componentWillUpdate';
11376 } else if (typeof instance.UNSAFE_componentWillUpdate === 'function') {
11377 foundWillUpdateName = 'UNSAFE_componentWillUpdate';
11378 }
11379 if (foundWillMountName !== null || foundWillReceivePropsName !== null || foundWillUpdateName !== null) {
11380 var _componentName = getComponentName(ctor) || 'Component';
11381 var newApiName = typeof ctor.getDerivedStateFromProps === 'function' ? 'getDerivedStateFromProps()' : 'getSnapshotBeforeUpdate()';
11382 if (!didWarnAboutLegacyLifecyclesAndDerivedState.has(_componentName)) {
11383 didWarnAboutLegacyLifecyclesAndDerivedState.add(_componentName);
11384 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 : '');
11385 }
11386 }
11387 }
11388 }
11389
11390 // Cache unmasked context so we can avoid recreating masked context unless necessary.
11391 // ReactFiberContext usually updates this cache but can't for newly-created instances.
11392 if (isLegacyContextConsumer) {
11393 cacheContext(workInProgress, unmaskedContext, context);
11394 }
11395
11396 return instance;
11397}
11398
11399function callComponentWillMount(workInProgress, instance) {
11400 startPhaseTimer(workInProgress, 'componentWillMount');
11401 var oldState = instance.state;
11402
11403 if (typeof instance.componentWillMount === 'function') {
11404 instance.componentWillMount();
11405 }
11406 if (typeof instance.UNSAFE_componentWillMount === 'function') {
11407 instance.UNSAFE_componentWillMount();
11408 }
11409
11410 stopPhaseTimer();
11411
11412 if (oldState !== instance.state) {
11413 {
11414 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');
11415 }
11416 classComponentUpdater.enqueueReplaceState(instance, instance.state, null);
11417 }
11418}
11419
11420function callComponentWillReceiveProps(workInProgress, instance, newProps, nextContext) {
11421 var oldState = instance.state;
11422 startPhaseTimer(workInProgress, 'componentWillReceiveProps');
11423 if (typeof instance.componentWillReceiveProps === 'function') {
11424 instance.componentWillReceiveProps(newProps, nextContext);
11425 }
11426 if (typeof instance.UNSAFE_componentWillReceiveProps === 'function') {
11427 instance.UNSAFE_componentWillReceiveProps(newProps, nextContext);
11428 }
11429 stopPhaseTimer();
11430
11431 if (instance.state !== oldState) {
11432 {
11433 var componentName = getComponentName(workInProgress.type) || 'Component';
11434 if (!didWarnAboutStateAssignmentForComponent.has(componentName)) {
11435 didWarnAboutStateAssignmentForComponent.add(componentName);
11436 warningWithoutStack$1(false, '%s.componentWillReceiveProps(): Assigning directly to ' + "this.state is deprecated (except inside a component's " + 'constructor). Use setState instead.', componentName);
11437 }
11438 }
11439 classComponentUpdater.enqueueReplaceState(instance, instance.state, null);
11440 }
11441}
11442
11443// Invokes the mount life-cycles on a previously never rendered instance.
11444function mountClassInstance(workInProgress, ctor, newProps, renderExpirationTime) {
11445 {
11446 checkClassInstance(workInProgress, ctor, newProps);
11447 }
11448
11449 var instance = workInProgress.stateNode;
11450 instance.props = newProps;
11451 instance.state = workInProgress.memoizedState;
11452 instance.refs = emptyRefsObject;
11453
11454 var contextType = ctor.contextType;
11455 if (typeof contextType === 'object' && contextType !== null) {
11456 instance.context = readContext(contextType);
11457 } else {
11458 var unmaskedContext = getUnmaskedContext(workInProgress, ctor, true);
11459 instance.context = getMaskedContext(workInProgress, unmaskedContext);
11460 }
11461
11462 {
11463 if (instance.state === newProps) {
11464 var componentName = getComponentName(ctor) || 'Component';
11465 if (!didWarnAboutDirectlyAssigningPropsToState.has(componentName)) {
11466 didWarnAboutDirectlyAssigningPropsToState.add(componentName);
11467 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);
11468 }
11469 }
11470
11471 if (workInProgress.mode & StrictMode) {
11472 ReactStrictModeWarnings.recordUnsafeLifecycleWarnings(workInProgress, instance);
11473
11474 ReactStrictModeWarnings.recordLegacyContextWarning(workInProgress, instance);
11475 }
11476
11477 if (warnAboutDeprecatedLifecycles) {
11478 ReactStrictModeWarnings.recordDeprecationWarnings(workInProgress, instance);
11479 }
11480 }
11481
11482 var updateQueue = workInProgress.updateQueue;
11483 if (updateQueue !== null) {
11484 processUpdateQueue(workInProgress, updateQueue, newProps, instance, renderExpirationTime);
11485 instance.state = workInProgress.memoizedState;
11486 }
11487
11488 var getDerivedStateFromProps = ctor.getDerivedStateFromProps;
11489 if (typeof getDerivedStateFromProps === 'function') {
11490 applyDerivedStateFromProps(workInProgress, ctor, getDerivedStateFromProps, newProps);
11491 instance.state = workInProgress.memoizedState;
11492 }
11493
11494 // In order to support react-lifecycles-compat polyfilled components,
11495 // Unsafe lifecycles should not be invoked for components using the new APIs.
11496 if (typeof ctor.getDerivedStateFromProps !== 'function' && typeof instance.getSnapshotBeforeUpdate !== 'function' && (typeof instance.UNSAFE_componentWillMount === 'function' || typeof instance.componentWillMount === 'function')) {
11497 callComponentWillMount(workInProgress, instance);
11498 // If we had additional state updates during this life-cycle, let's
11499 // process them now.
11500 updateQueue = workInProgress.updateQueue;
11501 if (updateQueue !== null) {
11502 processUpdateQueue(workInProgress, updateQueue, newProps, instance, renderExpirationTime);
11503 instance.state = workInProgress.memoizedState;
11504 }
11505 }
11506
11507 if (typeof instance.componentDidMount === 'function') {
11508 workInProgress.effectTag |= Update;
11509 }
11510}
11511
11512function resumeMountClassInstance(workInProgress, ctor, newProps, renderExpirationTime) {
11513 var instance = workInProgress.stateNode;
11514
11515 var oldProps = workInProgress.memoizedProps;
11516 instance.props = oldProps;
11517
11518 var oldContext = instance.context;
11519 var contextType = ctor.contextType;
11520 var nextContext = void 0;
11521 if (typeof contextType === 'object' && contextType !== null) {
11522 nextContext = readContext(contextType);
11523 } else {
11524 var nextLegacyUnmaskedContext = getUnmaskedContext(workInProgress, ctor, true);
11525 nextContext = getMaskedContext(workInProgress, nextLegacyUnmaskedContext);
11526 }
11527
11528 var getDerivedStateFromProps = ctor.getDerivedStateFromProps;
11529 var hasNewLifecycles = typeof getDerivedStateFromProps === 'function' || typeof instance.getSnapshotBeforeUpdate === 'function';
11530
11531 // Note: During these life-cycles, instance.props/instance.state are what
11532 // ever the previously attempted to render - not the "current". However,
11533 // during componentDidUpdate we pass the "current" props.
11534
11535 // In order to support react-lifecycles-compat polyfilled components,
11536 // Unsafe lifecycles should not be invoked for components using the new APIs.
11537 if (!hasNewLifecycles && (typeof instance.UNSAFE_componentWillReceiveProps === 'function' || typeof instance.componentWillReceiveProps === 'function')) {
11538 if (oldProps !== newProps || oldContext !== nextContext) {
11539 callComponentWillReceiveProps(workInProgress, instance, newProps, nextContext);
11540 }
11541 }
11542
11543 resetHasForceUpdateBeforeProcessing();
11544
11545 var oldState = workInProgress.memoizedState;
11546 var newState = instance.state = oldState;
11547 var updateQueue = workInProgress.updateQueue;
11548 if (updateQueue !== null) {
11549 processUpdateQueue(workInProgress, updateQueue, newProps, instance, renderExpirationTime);
11550 newState = workInProgress.memoizedState;
11551 }
11552 if (oldProps === newProps && oldState === newState && !hasContextChanged() && !checkHasForceUpdateAfterProcessing()) {
11553 // If an update was already in progress, we should schedule an Update
11554 // effect even though we're bailing out, so that cWU/cDU are called.
11555 if (typeof instance.componentDidMount === 'function') {
11556 workInProgress.effectTag |= Update;
11557 }
11558 return false;
11559 }
11560
11561 if (typeof getDerivedStateFromProps === 'function') {
11562 applyDerivedStateFromProps(workInProgress, ctor, getDerivedStateFromProps, newProps);
11563 newState = workInProgress.memoizedState;
11564 }
11565
11566 var shouldUpdate = checkHasForceUpdateAfterProcessing() || checkShouldComponentUpdate(workInProgress, ctor, oldProps, newProps, oldState, newState, nextContext);
11567
11568 if (shouldUpdate) {
11569 // In order to support react-lifecycles-compat polyfilled components,
11570 // Unsafe lifecycles should not be invoked for components using the new APIs.
11571 if (!hasNewLifecycles && (typeof instance.UNSAFE_componentWillMount === 'function' || typeof instance.componentWillMount === 'function')) {
11572 startPhaseTimer(workInProgress, 'componentWillMount');
11573 if (typeof instance.componentWillMount === 'function') {
11574 instance.componentWillMount();
11575 }
11576 if (typeof instance.UNSAFE_componentWillMount === 'function') {
11577 instance.UNSAFE_componentWillMount();
11578 }
11579 stopPhaseTimer();
11580 }
11581 if (typeof instance.componentDidMount === 'function') {
11582 workInProgress.effectTag |= Update;
11583 }
11584 } else {
11585 // If an update was already in progress, we should schedule an Update
11586 // effect even though we're bailing out, so that cWU/cDU are called.
11587 if (typeof instance.componentDidMount === 'function') {
11588 workInProgress.effectTag |= Update;
11589 }
11590
11591 // If shouldComponentUpdate returned false, we should still update the
11592 // memoized state to indicate that this work can be reused.
11593 workInProgress.memoizedProps = newProps;
11594 workInProgress.memoizedState = newState;
11595 }
11596
11597 // Update the existing instance's state, props, and context pointers even
11598 // if shouldComponentUpdate returns false.
11599 instance.props = newProps;
11600 instance.state = newState;
11601 instance.context = nextContext;
11602
11603 return shouldUpdate;
11604}
11605
11606// Invokes the update life-cycles and returns false if it shouldn't rerender.
11607function updateClassInstance(current, workInProgress, ctor, newProps, renderExpirationTime) {
11608 var instance = workInProgress.stateNode;
11609
11610 var oldProps = workInProgress.memoizedProps;
11611 instance.props = workInProgress.type === workInProgress.elementType ? oldProps : resolveDefaultProps(workInProgress.type, oldProps);
11612
11613 var oldContext = instance.context;
11614 var contextType = ctor.contextType;
11615 var nextContext = void 0;
11616 if (typeof contextType === 'object' && contextType !== null) {
11617 nextContext = readContext(contextType);
11618 } else {
11619 var nextUnmaskedContext = getUnmaskedContext(workInProgress, ctor, true);
11620 nextContext = getMaskedContext(workInProgress, nextUnmaskedContext);
11621 }
11622
11623 var getDerivedStateFromProps = ctor.getDerivedStateFromProps;
11624 var hasNewLifecycles = typeof getDerivedStateFromProps === 'function' || typeof instance.getSnapshotBeforeUpdate === 'function';
11625
11626 // Note: During these life-cycles, instance.props/instance.state are what
11627 // ever the previously attempted to render - not the "current". However,
11628 // during componentDidUpdate we pass the "current" props.
11629
11630 // In order to support react-lifecycles-compat polyfilled components,
11631 // Unsafe lifecycles should not be invoked for components using the new APIs.
11632 if (!hasNewLifecycles && (typeof instance.UNSAFE_componentWillReceiveProps === 'function' || typeof instance.componentWillReceiveProps === 'function')) {
11633 if (oldProps !== newProps || oldContext !== nextContext) {
11634 callComponentWillReceiveProps(workInProgress, instance, newProps, nextContext);
11635 }
11636 }
11637
11638 resetHasForceUpdateBeforeProcessing();
11639
11640 var oldState = workInProgress.memoizedState;
11641 var newState = instance.state = oldState;
11642 var updateQueue = workInProgress.updateQueue;
11643 if (updateQueue !== null) {
11644 processUpdateQueue(workInProgress, updateQueue, newProps, instance, renderExpirationTime);
11645 newState = workInProgress.memoizedState;
11646 }
11647
11648 if (oldProps === newProps && oldState === newState && !hasContextChanged() && !checkHasForceUpdateAfterProcessing()) {
11649 // If an update was already in progress, we should schedule an Update
11650 // effect even though we're bailing out, so that cWU/cDU are called.
11651 if (typeof instance.componentDidUpdate === 'function') {
11652 if (oldProps !== current.memoizedProps || oldState !== current.memoizedState) {
11653 workInProgress.effectTag |= Update;
11654 }
11655 }
11656 if (typeof instance.getSnapshotBeforeUpdate === 'function') {
11657 if (oldProps !== current.memoizedProps || oldState !== current.memoizedState) {
11658 workInProgress.effectTag |= Snapshot;
11659 }
11660 }
11661 return false;
11662 }
11663
11664 if (typeof getDerivedStateFromProps === 'function') {
11665 applyDerivedStateFromProps(workInProgress, ctor, getDerivedStateFromProps, newProps);
11666 newState = workInProgress.memoizedState;
11667 }
11668
11669 var shouldUpdate = checkHasForceUpdateAfterProcessing() || checkShouldComponentUpdate(workInProgress, ctor, oldProps, newProps, oldState, newState, nextContext);
11670
11671 if (shouldUpdate) {
11672 // In order to support react-lifecycles-compat polyfilled components,
11673 // Unsafe lifecycles should not be invoked for components using the new APIs.
11674 if (!hasNewLifecycles && (typeof instance.UNSAFE_componentWillUpdate === 'function' || typeof instance.componentWillUpdate === 'function')) {
11675 startPhaseTimer(workInProgress, 'componentWillUpdate');
11676 if (typeof instance.componentWillUpdate === 'function') {
11677 instance.componentWillUpdate(newProps, newState, nextContext);
11678 }
11679 if (typeof instance.UNSAFE_componentWillUpdate === 'function') {
11680 instance.UNSAFE_componentWillUpdate(newProps, newState, nextContext);
11681 }
11682 stopPhaseTimer();
11683 }
11684 if (typeof instance.componentDidUpdate === 'function') {
11685 workInProgress.effectTag |= Update;
11686 }
11687 if (typeof instance.getSnapshotBeforeUpdate === 'function') {
11688 workInProgress.effectTag |= Snapshot;
11689 }
11690 } else {
11691 // If an update was already in progress, we should schedule an Update
11692 // effect even though we're bailing out, so that cWU/cDU are called.
11693 if (typeof instance.componentDidUpdate === 'function') {
11694 if (oldProps !== current.memoizedProps || oldState !== current.memoizedState) {
11695 workInProgress.effectTag |= Update;
11696 }
11697 }
11698 if (typeof instance.getSnapshotBeforeUpdate === 'function') {
11699 if (oldProps !== current.memoizedProps || oldState !== current.memoizedState) {
11700 workInProgress.effectTag |= Snapshot;
11701 }
11702 }
11703
11704 // If shouldComponentUpdate returned false, we should still update the
11705 // memoized props/state to indicate that this work can be reused.
11706 workInProgress.memoizedProps = newProps;
11707 workInProgress.memoizedState = newState;
11708 }
11709
11710 // Update the existing instance's state, props, and context pointers even
11711 // if shouldComponentUpdate returns false.
11712 instance.props = newProps;
11713 instance.state = newState;
11714 instance.context = nextContext;
11715
11716 return shouldUpdate;
11717}
11718
11719var didWarnAboutMaps = void 0;
11720var didWarnAboutGenerators = void 0;
11721var didWarnAboutStringRefInStrictMode = void 0;
11722var ownerHasKeyUseWarning = void 0;
11723var ownerHasFunctionTypeWarning = void 0;
11724var warnForMissingKey = function (child) {};
11725
11726{
11727 didWarnAboutMaps = false;
11728 didWarnAboutGenerators = false;
11729 didWarnAboutStringRefInStrictMode = {};
11730
11731 /**
11732 * Warn if there's no key explicitly set on dynamic arrays of children or
11733 * object keys are not valid. This allows us to keep track of children between
11734 * updates.
11735 */
11736 ownerHasKeyUseWarning = {};
11737 ownerHasFunctionTypeWarning = {};
11738
11739 warnForMissingKey = function (child) {
11740 if (child === null || typeof child !== 'object') {
11741 return;
11742 }
11743 if (!child._store || child._store.validated || child.key != null) {
11744 return;
11745 }
11746 !(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;
11747 child._store.validated = true;
11748
11749 var currentComponentErrorInfo = 'Each child in a list should have a unique ' + '"key" prop. See https://fb.me/react-warning-keys for ' + 'more information.' + getCurrentFiberStackInDev();
11750 if (ownerHasKeyUseWarning[currentComponentErrorInfo]) {
11751 return;
11752 }
11753 ownerHasKeyUseWarning[currentComponentErrorInfo] = true;
11754
11755 warning$1(false, 'Each child in a list should have a unique ' + '"key" prop. See https://fb.me/react-warning-keys for ' + 'more information.');
11756 };
11757}
11758
11759var isArray = Array.isArray;
11760
11761function coerceRef(returnFiber, current$$1, element) {
11762 var mixedRef = element.ref;
11763 if (mixedRef !== null && typeof mixedRef !== 'function' && typeof mixedRef !== 'object') {
11764 {
11765 if (returnFiber.mode & StrictMode) {
11766 var componentName = getComponentName(returnFiber.type) || 'Component';
11767 if (!didWarnAboutStringRefInStrictMode[componentName]) {
11768 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));
11769 didWarnAboutStringRefInStrictMode[componentName] = true;
11770 }
11771 }
11772 }
11773
11774 if (element._owner) {
11775 var owner = element._owner;
11776 var inst = void 0;
11777 if (owner) {
11778 var ownerFiber = owner;
11779 !(ownerFiber.tag === ClassComponent) ? invariant(false, 'Function components cannot have refs. Did you mean to use React.forwardRef()?') : void 0;
11780 inst = ownerFiber.stateNode;
11781 }
11782 !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;
11783 var stringRef = '' + mixedRef;
11784 // Check if previous string ref matches new string ref
11785 if (current$$1 !== null && current$$1.ref !== null && typeof current$$1.ref === 'function' && current$$1.ref._stringRef === stringRef) {
11786 return current$$1.ref;
11787 }
11788 var ref = function (value) {
11789 var refs = inst.refs;
11790 if (refs === emptyRefsObject) {
11791 // This is a lazy pooled frozen object, so we need to initialize.
11792 refs = inst.refs = {};
11793 }
11794 if (value === null) {
11795 delete refs[stringRef];
11796 } else {
11797 refs[stringRef] = value;
11798 }
11799 };
11800 ref._stringRef = stringRef;
11801 return ref;
11802 } else {
11803 !(typeof mixedRef === 'string') ? invariant(false, 'Expected ref to be a function, a string, an object returned by React.createRef(), or null.') : void 0;
11804 !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;
11805 }
11806 }
11807 return mixedRef;
11808}
11809
11810function throwOnInvalidObjectType(returnFiber, newChild) {
11811 if (returnFiber.type !== 'textarea') {
11812 var addendum = '';
11813 {
11814 addendum = ' If you meant to render a collection of children, use an array ' + 'instead.' + getCurrentFiberStackInDev();
11815 }
11816 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);
11817 }
11818}
11819
11820function warnOnFunctionType() {
11821 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();
11822
11823 if (ownerHasFunctionTypeWarning[currentComponentErrorInfo]) {
11824 return;
11825 }
11826 ownerHasFunctionTypeWarning[currentComponentErrorInfo] = true;
11827
11828 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.');
11829}
11830
11831// This wrapper function exists because I expect to clone the code in each path
11832// to be able to optimize each path individually by branching early. This needs
11833// a compiler or we can do it manually. Helpers that don't need this branching
11834// live outside of this function.
11835function ChildReconciler(shouldTrackSideEffects) {
11836 function deleteChild(returnFiber, childToDelete) {
11837 if (!shouldTrackSideEffects) {
11838 // Noop.
11839 return;
11840 }
11841 // Deletions are added in reversed order so we add it to the front.
11842 // At this point, the return fiber's effect list is empty except for
11843 // deletions, so we can just append the deletion to the list. The remaining
11844 // effects aren't added until the complete phase. Once we implement
11845 // resuming, this may not be true.
11846 var last = returnFiber.lastEffect;
11847 if (last !== null) {
11848 last.nextEffect = childToDelete;
11849 returnFiber.lastEffect = childToDelete;
11850 } else {
11851 returnFiber.firstEffect = returnFiber.lastEffect = childToDelete;
11852 }
11853 childToDelete.nextEffect = null;
11854 childToDelete.effectTag = Deletion;
11855 }
11856
11857 function deleteRemainingChildren(returnFiber, currentFirstChild) {
11858 if (!shouldTrackSideEffects) {
11859 // Noop.
11860 return null;
11861 }
11862
11863 // TODO: For the shouldClone case, this could be micro-optimized a bit by
11864 // assuming that after the first child we've already added everything.
11865 var childToDelete = currentFirstChild;
11866 while (childToDelete !== null) {
11867 deleteChild(returnFiber, childToDelete);
11868 childToDelete = childToDelete.sibling;
11869 }
11870 return null;
11871 }
11872
11873 function mapRemainingChildren(returnFiber, currentFirstChild) {
11874 // Add the remaining children to a temporary map so that we can find them by
11875 // keys quickly. Implicit (null) keys get added to this set with their index
11876 var existingChildren = new Map();
11877
11878 var existingChild = currentFirstChild;
11879 while (existingChild !== null) {
11880 if (existingChild.key !== null) {
11881 existingChildren.set(existingChild.key, existingChild);
11882 } else {
11883 existingChildren.set(existingChild.index, existingChild);
11884 }
11885 existingChild = existingChild.sibling;
11886 }
11887 return existingChildren;
11888 }
11889
11890 function useFiber(fiber, pendingProps, expirationTime) {
11891 // We currently set sibling to null and index to 0 here because it is easy
11892 // to forget to do before returning it. E.g. for the single child case.
11893 var clone = createWorkInProgress(fiber, pendingProps, expirationTime);
11894 clone.index = 0;
11895 clone.sibling = null;
11896 return clone;
11897 }
11898
11899 function placeChild(newFiber, lastPlacedIndex, newIndex) {
11900 newFiber.index = newIndex;
11901 if (!shouldTrackSideEffects) {
11902 // Noop.
11903 return lastPlacedIndex;
11904 }
11905 var current$$1 = newFiber.alternate;
11906 if (current$$1 !== null) {
11907 var oldIndex = current$$1.index;
11908 if (oldIndex < lastPlacedIndex) {
11909 // This is a move.
11910 newFiber.effectTag = Placement;
11911 return lastPlacedIndex;
11912 } else {
11913 // This item can stay in place.
11914 return oldIndex;
11915 }
11916 } else {
11917 // This is an insertion.
11918 newFiber.effectTag = Placement;
11919 return lastPlacedIndex;
11920 }
11921 }
11922
11923 function placeSingleChild(newFiber) {
11924 // This is simpler for the single child case. We only need to do a
11925 // placement for inserting new children.
11926 if (shouldTrackSideEffects && newFiber.alternate === null) {
11927 newFiber.effectTag = Placement;
11928 }
11929 return newFiber;
11930 }
11931
11932 function updateTextNode(returnFiber, current$$1, textContent, expirationTime) {
11933 if (current$$1 === null || current$$1.tag !== HostText) {
11934 // Insert
11935 var created = createFiberFromText(textContent, returnFiber.mode, expirationTime);
11936 created.return = returnFiber;
11937 return created;
11938 } else {
11939 // Update
11940 var existing = useFiber(current$$1, textContent, expirationTime);
11941 existing.return = returnFiber;
11942 return existing;
11943 }
11944 }
11945
11946 function updateElement(returnFiber, current$$1, element, expirationTime) {
11947 if (current$$1 !== null && current$$1.elementType === element.type) {
11948 // Move based on index
11949 var existing = useFiber(current$$1, element.props, expirationTime);
11950 existing.ref = coerceRef(returnFiber, current$$1, element);
11951 existing.return = returnFiber;
11952 {
11953 existing._debugSource = element._source;
11954 existing._debugOwner = element._owner;
11955 }
11956 return existing;
11957 } else {
11958 // Insert
11959 var created = createFiberFromElement(element, returnFiber.mode, expirationTime);
11960 created.ref = coerceRef(returnFiber, current$$1, element);
11961 created.return = returnFiber;
11962 return created;
11963 }
11964 }
11965
11966 function updatePortal(returnFiber, current$$1, portal, expirationTime) {
11967 if (current$$1 === null || current$$1.tag !== HostPortal || current$$1.stateNode.containerInfo !== portal.containerInfo || current$$1.stateNode.implementation !== portal.implementation) {
11968 // Insert
11969 var created = createFiberFromPortal(portal, returnFiber.mode, expirationTime);
11970 created.return = returnFiber;
11971 return created;
11972 } else {
11973 // Update
11974 var existing = useFiber(current$$1, portal.children || [], expirationTime);
11975 existing.return = returnFiber;
11976 return existing;
11977 }
11978 }
11979
11980 function updateFragment(returnFiber, current$$1, fragment, expirationTime, key) {
11981 if (current$$1 === null || current$$1.tag !== Fragment) {
11982 // Insert
11983 var created = createFiberFromFragment(fragment, returnFiber.mode, expirationTime, key);
11984 created.return = returnFiber;
11985 return created;
11986 } else {
11987 // Update
11988 var existing = useFiber(current$$1, fragment, expirationTime);
11989 existing.return = returnFiber;
11990 return existing;
11991 }
11992 }
11993
11994 function createChild(returnFiber, newChild, expirationTime) {
11995 if (typeof newChild === 'string' || typeof newChild === 'number') {
11996 // Text nodes don't have keys. If the previous node is implicitly keyed
11997 // we can continue to replace it without aborting even if it is not a text
11998 // node.
11999 var created = createFiberFromText('' + newChild, returnFiber.mode, expirationTime);
12000 created.return = returnFiber;
12001 return created;
12002 }
12003
12004 if (typeof newChild === 'object' && newChild !== null) {
12005 switch (newChild.$$typeof) {
12006 case REACT_ELEMENT_TYPE:
12007 {
12008 var _created = createFiberFromElement(newChild, returnFiber.mode, expirationTime);
12009 _created.ref = coerceRef(returnFiber, null, newChild);
12010 _created.return = returnFiber;
12011 return _created;
12012 }
12013 case REACT_PORTAL_TYPE:
12014 {
12015 var _created2 = createFiberFromPortal(newChild, returnFiber.mode, expirationTime);
12016 _created2.return = returnFiber;
12017 return _created2;
12018 }
12019 }
12020
12021 if (isArray(newChild) || getIteratorFn(newChild)) {
12022 var _created3 = createFiberFromFragment(newChild, returnFiber.mode, expirationTime, null);
12023 _created3.return = returnFiber;
12024 return _created3;
12025 }
12026
12027 throwOnInvalidObjectType(returnFiber, newChild);
12028 }
12029
12030 {
12031 if (typeof newChild === 'function') {
12032 warnOnFunctionType();
12033 }
12034 }
12035
12036 return null;
12037 }
12038
12039 function updateSlot(returnFiber, oldFiber, newChild, expirationTime) {
12040 // Update the fiber if the keys match, otherwise return null.
12041
12042 var key = oldFiber !== null ? oldFiber.key : null;
12043
12044 if (typeof newChild === 'string' || typeof newChild === 'number') {
12045 // Text nodes don't have keys. If the previous node is implicitly keyed
12046 // we can continue to replace it without aborting even if it is not a text
12047 // node.
12048 if (key !== null) {
12049 return null;
12050 }
12051 return updateTextNode(returnFiber, oldFiber, '' + newChild, expirationTime);
12052 }
12053
12054 if (typeof newChild === 'object' && newChild !== null) {
12055 switch (newChild.$$typeof) {
12056 case REACT_ELEMENT_TYPE:
12057 {
12058 if (newChild.key === key) {
12059 if (newChild.type === REACT_FRAGMENT_TYPE) {
12060 return updateFragment(returnFiber, oldFiber, newChild.props.children, expirationTime, key);
12061 }
12062 return updateElement(returnFiber, oldFiber, newChild, expirationTime);
12063 } else {
12064 return null;
12065 }
12066 }
12067 case REACT_PORTAL_TYPE:
12068 {
12069 if (newChild.key === key) {
12070 return updatePortal(returnFiber, oldFiber, newChild, expirationTime);
12071 } else {
12072 return null;
12073 }
12074 }
12075 }
12076
12077 if (isArray(newChild) || getIteratorFn(newChild)) {
12078 if (key !== null) {
12079 return null;
12080 }
12081
12082 return updateFragment(returnFiber, oldFiber, newChild, expirationTime, null);
12083 }
12084
12085 throwOnInvalidObjectType(returnFiber, newChild);
12086 }
12087
12088 {
12089 if (typeof newChild === 'function') {
12090 warnOnFunctionType();
12091 }
12092 }
12093
12094 return null;
12095 }
12096
12097 function updateFromMap(existingChildren, returnFiber, newIdx, newChild, expirationTime) {
12098 if (typeof newChild === 'string' || typeof newChild === 'number') {
12099 // Text nodes don't have keys, so we neither have to check the old nor
12100 // new node for the key. If both are text nodes, they match.
12101 var matchedFiber = existingChildren.get(newIdx) || null;
12102 return updateTextNode(returnFiber, matchedFiber, '' + newChild, expirationTime);
12103 }
12104
12105 if (typeof newChild === 'object' && newChild !== null) {
12106 switch (newChild.$$typeof) {
12107 case REACT_ELEMENT_TYPE:
12108 {
12109 var _matchedFiber = existingChildren.get(newChild.key === null ? newIdx : newChild.key) || null;
12110 if (newChild.type === REACT_FRAGMENT_TYPE) {
12111 return updateFragment(returnFiber, _matchedFiber, newChild.props.children, expirationTime, newChild.key);
12112 }
12113 return updateElement(returnFiber, _matchedFiber, newChild, expirationTime);
12114 }
12115 case REACT_PORTAL_TYPE:
12116 {
12117 var _matchedFiber2 = existingChildren.get(newChild.key === null ? newIdx : newChild.key) || null;
12118 return updatePortal(returnFiber, _matchedFiber2, newChild, expirationTime);
12119 }
12120 }
12121
12122 if (isArray(newChild) || getIteratorFn(newChild)) {
12123 var _matchedFiber3 = existingChildren.get(newIdx) || null;
12124 return updateFragment(returnFiber, _matchedFiber3, newChild, expirationTime, null);
12125 }
12126
12127 throwOnInvalidObjectType(returnFiber, newChild);
12128 }
12129
12130 {
12131 if (typeof newChild === 'function') {
12132 warnOnFunctionType();
12133 }
12134 }
12135
12136 return null;
12137 }
12138
12139 /**
12140 * Warns if there is a duplicate or missing key
12141 */
12142 function warnOnInvalidKey(child, knownKeys) {
12143 {
12144 if (typeof child !== 'object' || child === null) {
12145 return knownKeys;
12146 }
12147 switch (child.$$typeof) {
12148 case REACT_ELEMENT_TYPE:
12149 case REACT_PORTAL_TYPE:
12150 warnForMissingKey(child);
12151 var key = child.key;
12152 if (typeof key !== 'string') {
12153 break;
12154 }
12155 if (knownKeys === null) {
12156 knownKeys = new Set();
12157 knownKeys.add(key);
12158 break;
12159 }
12160 if (!knownKeys.has(key)) {
12161 knownKeys.add(key);
12162 break;
12163 }
12164 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);
12165 break;
12166 default:
12167 break;
12168 }
12169 }
12170 return knownKeys;
12171 }
12172
12173 function reconcileChildrenArray(returnFiber, currentFirstChild, newChildren, expirationTime) {
12174 // This algorithm can't optimize by searching from boths ends since we
12175 // don't have backpointers on fibers. I'm trying to see how far we can get
12176 // with that model. If it ends up not being worth the tradeoffs, we can
12177 // add it later.
12178
12179 // Even with a two ended optimization, we'd want to optimize for the case
12180 // where there are few changes and brute force the comparison instead of
12181 // going for the Map. It'd like to explore hitting that path first in
12182 // forward-only mode and only go for the Map once we notice that we need
12183 // lots of look ahead. This doesn't handle reversal as well as two ended
12184 // search but that's unusual. Besides, for the two ended optimization to
12185 // work on Iterables, we'd need to copy the whole set.
12186
12187 // In this first iteration, we'll just live with hitting the bad case
12188 // (adding everything to a Map) in for every insert/move.
12189
12190 // If you change this code, also update reconcileChildrenIterator() which
12191 // uses the same algorithm.
12192
12193 {
12194 // First, validate keys.
12195 var knownKeys = null;
12196 for (var i = 0; i < newChildren.length; i++) {
12197 var child = newChildren[i];
12198 knownKeys = warnOnInvalidKey(child, knownKeys);
12199 }
12200 }
12201
12202 var resultingFirstChild = null;
12203 var previousNewFiber = null;
12204
12205 var oldFiber = currentFirstChild;
12206 var lastPlacedIndex = 0;
12207 var newIdx = 0;
12208 var nextOldFiber = null;
12209 for (; oldFiber !== null && newIdx < newChildren.length; newIdx++) {
12210 if (oldFiber.index > newIdx) {
12211 nextOldFiber = oldFiber;
12212 oldFiber = null;
12213 } else {
12214 nextOldFiber = oldFiber.sibling;
12215 }
12216 var newFiber = updateSlot(returnFiber, oldFiber, newChildren[newIdx], expirationTime);
12217 if (newFiber === null) {
12218 // TODO: This breaks on empty slots like null children. That's
12219 // unfortunate because it triggers the slow path all the time. We need
12220 // a better way to communicate whether this was a miss or null,
12221 // boolean, undefined, etc.
12222 if (oldFiber === null) {
12223 oldFiber = nextOldFiber;
12224 }
12225 break;
12226 }
12227 if (shouldTrackSideEffects) {
12228 if (oldFiber && newFiber.alternate === null) {
12229 // We matched the slot, but we didn't reuse the existing fiber, so we
12230 // need to delete the existing child.
12231 deleteChild(returnFiber, oldFiber);
12232 }
12233 }
12234 lastPlacedIndex = placeChild(newFiber, lastPlacedIndex, newIdx);
12235 if (previousNewFiber === null) {
12236 // TODO: Move out of the loop. This only happens for the first run.
12237 resultingFirstChild = newFiber;
12238 } else {
12239 // TODO: Defer siblings if we're not at the right index for this slot.
12240 // I.e. if we had null values before, then we want to defer this
12241 // for each null value. However, we also don't want to call updateSlot
12242 // with the previous one.
12243 previousNewFiber.sibling = newFiber;
12244 }
12245 previousNewFiber = newFiber;
12246 oldFiber = nextOldFiber;
12247 }
12248
12249 if (newIdx === newChildren.length) {
12250 // We've reached the end of the new children. We can delete the rest.
12251 deleteRemainingChildren(returnFiber, oldFiber);
12252 return resultingFirstChild;
12253 }
12254
12255 if (oldFiber === null) {
12256 // If we don't have any more existing children we can choose a fast path
12257 // since the rest will all be insertions.
12258 for (; newIdx < newChildren.length; newIdx++) {
12259 var _newFiber = createChild(returnFiber, newChildren[newIdx], expirationTime);
12260 if (!_newFiber) {
12261 continue;
12262 }
12263 lastPlacedIndex = placeChild(_newFiber, lastPlacedIndex, newIdx);
12264 if (previousNewFiber === null) {
12265 // TODO: Move out of the loop. This only happens for the first run.
12266 resultingFirstChild = _newFiber;
12267 } else {
12268 previousNewFiber.sibling = _newFiber;
12269 }
12270 previousNewFiber = _newFiber;
12271 }
12272 return resultingFirstChild;
12273 }
12274
12275 // Add all children to a key map for quick lookups.
12276 var existingChildren = mapRemainingChildren(returnFiber, oldFiber);
12277
12278 // Keep scanning and use the map to restore deleted items as moves.
12279 for (; newIdx < newChildren.length; newIdx++) {
12280 var _newFiber2 = updateFromMap(existingChildren, returnFiber, newIdx, newChildren[newIdx], expirationTime);
12281 if (_newFiber2) {
12282 if (shouldTrackSideEffects) {
12283 if (_newFiber2.alternate !== null) {
12284 // The new fiber is a work in progress, but if there exists a
12285 // current, that means that we reused the fiber. We need to delete
12286 // it from the child list so that we don't add it to the deletion
12287 // list.
12288 existingChildren.delete(_newFiber2.key === null ? newIdx : _newFiber2.key);
12289 }
12290 }
12291 lastPlacedIndex = placeChild(_newFiber2, lastPlacedIndex, newIdx);
12292 if (previousNewFiber === null) {
12293 resultingFirstChild = _newFiber2;
12294 } else {
12295 previousNewFiber.sibling = _newFiber2;
12296 }
12297 previousNewFiber = _newFiber2;
12298 }
12299 }
12300
12301 if (shouldTrackSideEffects) {
12302 // Any existing children that weren't consumed above were deleted. We need
12303 // to add them to the deletion list.
12304 existingChildren.forEach(function (child) {
12305 return deleteChild(returnFiber, child);
12306 });
12307 }
12308
12309 return resultingFirstChild;
12310 }
12311
12312 function reconcileChildrenIterator(returnFiber, currentFirstChild, newChildrenIterable, expirationTime) {
12313 // This is the same implementation as reconcileChildrenArray(),
12314 // but using the iterator instead.
12315
12316 var iteratorFn = getIteratorFn(newChildrenIterable);
12317 !(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;
12318
12319 {
12320 // We don't support rendering Generators because it's a mutation.
12321 // See https://github.com/facebook/react/issues/12995
12322 if (typeof Symbol === 'function' &&
12323 // $FlowFixMe Flow doesn't know about toStringTag
12324 newChildrenIterable[Symbol.toStringTag] === 'Generator') {
12325 !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;
12326 didWarnAboutGenerators = true;
12327 }
12328
12329 // Warn about using Maps as children
12330 if (newChildrenIterable.entries === iteratorFn) {
12331 !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;
12332 didWarnAboutMaps = true;
12333 }
12334
12335 // First, validate keys.
12336 // We'll get a different iterator later for the main pass.
12337 var _newChildren = iteratorFn.call(newChildrenIterable);
12338 if (_newChildren) {
12339 var knownKeys = null;
12340 var _step = _newChildren.next();
12341 for (; !_step.done; _step = _newChildren.next()) {
12342 var child = _step.value;
12343 knownKeys = warnOnInvalidKey(child, knownKeys);
12344 }
12345 }
12346 }
12347
12348 var newChildren = iteratorFn.call(newChildrenIterable);
12349 !(newChildren != null) ? invariant(false, 'An iterable object provided no iterator.') : void 0;
12350
12351 var resultingFirstChild = null;
12352 var previousNewFiber = null;
12353
12354 var oldFiber = currentFirstChild;
12355 var lastPlacedIndex = 0;
12356 var newIdx = 0;
12357 var nextOldFiber = null;
12358
12359 var step = newChildren.next();
12360 for (; oldFiber !== null && !step.done; newIdx++, step = newChildren.next()) {
12361 if (oldFiber.index > newIdx) {
12362 nextOldFiber = oldFiber;
12363 oldFiber = null;
12364 } else {
12365 nextOldFiber = oldFiber.sibling;
12366 }
12367 var newFiber = updateSlot(returnFiber, oldFiber, step.value, expirationTime);
12368 if (newFiber === null) {
12369 // TODO: This breaks on empty slots like null children. That's
12370 // unfortunate because it triggers the slow path all the time. We need
12371 // a better way to communicate whether this was a miss or null,
12372 // boolean, undefined, etc.
12373 if (!oldFiber) {
12374 oldFiber = nextOldFiber;
12375 }
12376 break;
12377 }
12378 if (shouldTrackSideEffects) {
12379 if (oldFiber && newFiber.alternate === null) {
12380 // We matched the slot, but we didn't reuse the existing fiber, so we
12381 // need to delete the existing child.
12382 deleteChild(returnFiber, oldFiber);
12383 }
12384 }
12385 lastPlacedIndex = placeChild(newFiber, lastPlacedIndex, newIdx);
12386 if (previousNewFiber === null) {
12387 // TODO: Move out of the loop. This only happens for the first run.
12388 resultingFirstChild = newFiber;
12389 } else {
12390 // TODO: Defer siblings if we're not at the right index for this slot.
12391 // I.e. if we had null values before, then we want to defer this
12392 // for each null value. However, we also don't want to call updateSlot
12393 // with the previous one.
12394 previousNewFiber.sibling = newFiber;
12395 }
12396 previousNewFiber = newFiber;
12397 oldFiber = nextOldFiber;
12398 }
12399
12400 if (step.done) {
12401 // We've reached the end of the new children. We can delete the rest.
12402 deleteRemainingChildren(returnFiber, oldFiber);
12403 return resultingFirstChild;
12404 }
12405
12406 if (oldFiber === null) {
12407 // If we don't have any more existing children we can choose a fast path
12408 // since the rest will all be insertions.
12409 for (; !step.done; newIdx++, step = newChildren.next()) {
12410 var _newFiber3 = createChild(returnFiber, step.value, expirationTime);
12411 if (_newFiber3 === null) {
12412 continue;
12413 }
12414 lastPlacedIndex = placeChild(_newFiber3, lastPlacedIndex, newIdx);
12415 if (previousNewFiber === null) {
12416 // TODO: Move out of the loop. This only happens for the first run.
12417 resultingFirstChild = _newFiber3;
12418 } else {
12419 previousNewFiber.sibling = _newFiber3;
12420 }
12421 previousNewFiber = _newFiber3;
12422 }
12423 return resultingFirstChild;
12424 }
12425
12426 // Add all children to a key map for quick lookups.
12427 var existingChildren = mapRemainingChildren(returnFiber, oldFiber);
12428
12429 // Keep scanning and use the map to restore deleted items as moves.
12430 for (; !step.done; newIdx++, step = newChildren.next()) {
12431 var _newFiber4 = updateFromMap(existingChildren, returnFiber, newIdx, step.value, expirationTime);
12432 if (_newFiber4 !== null) {
12433 if (shouldTrackSideEffects) {
12434 if (_newFiber4.alternate !== null) {
12435 // The new fiber is a work in progress, but if there exists a
12436 // current, that means that we reused the fiber. We need to delete
12437 // it from the child list so that we don't add it to the deletion
12438 // list.
12439 existingChildren.delete(_newFiber4.key === null ? newIdx : _newFiber4.key);
12440 }
12441 }
12442 lastPlacedIndex = placeChild(_newFiber4, lastPlacedIndex, newIdx);
12443 if (previousNewFiber === null) {
12444 resultingFirstChild = _newFiber4;
12445 } else {
12446 previousNewFiber.sibling = _newFiber4;
12447 }
12448 previousNewFiber = _newFiber4;
12449 }
12450 }
12451
12452 if (shouldTrackSideEffects) {
12453 // Any existing children that weren't consumed above were deleted. We need
12454 // to add them to the deletion list.
12455 existingChildren.forEach(function (child) {
12456 return deleteChild(returnFiber, child);
12457 });
12458 }
12459
12460 return resultingFirstChild;
12461 }
12462
12463 function reconcileSingleTextNode(returnFiber, currentFirstChild, textContent, expirationTime) {
12464 // There's no need to check for keys on text nodes since we don't have a
12465 // way to define them.
12466 if (currentFirstChild !== null && currentFirstChild.tag === HostText) {
12467 // We already have an existing node so let's just update it and delete
12468 // the rest.
12469 deleteRemainingChildren(returnFiber, currentFirstChild.sibling);
12470 var existing = useFiber(currentFirstChild, textContent, expirationTime);
12471 existing.return = returnFiber;
12472 return existing;
12473 }
12474 // The existing first child is not a text node so we need to create one
12475 // and delete the existing ones.
12476 deleteRemainingChildren(returnFiber, currentFirstChild);
12477 var created = createFiberFromText(textContent, returnFiber.mode, expirationTime);
12478 created.return = returnFiber;
12479 return created;
12480 }
12481
12482 function reconcileSingleElement(returnFiber, currentFirstChild, element, expirationTime) {
12483 var key = element.key;
12484 var child = currentFirstChild;
12485 while (child !== null) {
12486 // TODO: If key === null and child.key === null, then this only applies to
12487 // the first item in the list.
12488 if (child.key === key) {
12489 if (child.tag === Fragment ? element.type === REACT_FRAGMENT_TYPE : child.elementType === element.type) {
12490 deleteRemainingChildren(returnFiber, child.sibling);
12491 var existing = useFiber(child, element.type === REACT_FRAGMENT_TYPE ? element.props.children : element.props, expirationTime);
12492 existing.ref = coerceRef(returnFiber, child, element);
12493 existing.return = returnFiber;
12494 {
12495 existing._debugSource = element._source;
12496 existing._debugOwner = element._owner;
12497 }
12498 return existing;
12499 } else {
12500 deleteRemainingChildren(returnFiber, child);
12501 break;
12502 }
12503 } else {
12504 deleteChild(returnFiber, child);
12505 }
12506 child = child.sibling;
12507 }
12508
12509 if (element.type === REACT_FRAGMENT_TYPE) {
12510 var created = createFiberFromFragment(element.props.children, returnFiber.mode, expirationTime, element.key);
12511 created.return = returnFiber;
12512 return created;
12513 } else {
12514 var _created4 = createFiberFromElement(element, returnFiber.mode, expirationTime);
12515 _created4.ref = coerceRef(returnFiber, currentFirstChild, element);
12516 _created4.return = returnFiber;
12517 return _created4;
12518 }
12519 }
12520
12521 function reconcileSinglePortal(returnFiber, currentFirstChild, portal, expirationTime) {
12522 var key = portal.key;
12523 var child = currentFirstChild;
12524 while (child !== null) {
12525 // TODO: If key === null and child.key === null, then this only applies to
12526 // the first item in the list.
12527 if (child.key === key) {
12528 if (child.tag === HostPortal && child.stateNode.containerInfo === portal.containerInfo && child.stateNode.implementation === portal.implementation) {
12529 deleteRemainingChildren(returnFiber, child.sibling);
12530 var existing = useFiber(child, portal.children || [], expirationTime);
12531 existing.return = returnFiber;
12532 return existing;
12533 } else {
12534 deleteRemainingChildren(returnFiber, child);
12535 break;
12536 }
12537 } else {
12538 deleteChild(returnFiber, child);
12539 }
12540 child = child.sibling;
12541 }
12542
12543 var created = createFiberFromPortal(portal, returnFiber.mode, expirationTime);
12544 created.return = returnFiber;
12545 return created;
12546 }
12547
12548 // This API will tag the children with the side-effect of the reconciliation
12549 // itself. They will be added to the side-effect list as we pass through the
12550 // children and the parent.
12551 function reconcileChildFibers(returnFiber, currentFirstChild, newChild, expirationTime) {
12552 // This function is not recursive.
12553 // If the top level item is an array, we treat it as a set of children,
12554 // not as a fragment. Nested arrays on the other hand will be treated as
12555 // fragment nodes. Recursion happens at the normal flow.
12556
12557 // Handle top level unkeyed fragments as if they were arrays.
12558 // This leads to an ambiguity between <>{[...]}</> and <>...</>.
12559 // We treat the ambiguous cases above the same.
12560 var isUnkeyedTopLevelFragment = typeof newChild === 'object' && newChild !== null && newChild.type === REACT_FRAGMENT_TYPE && newChild.key === null;
12561 if (isUnkeyedTopLevelFragment) {
12562 newChild = newChild.props.children;
12563 }
12564
12565 // Handle object types
12566 var isObject = typeof newChild === 'object' && newChild !== null;
12567
12568 if (isObject) {
12569 switch (newChild.$$typeof) {
12570 case REACT_ELEMENT_TYPE:
12571 return placeSingleChild(reconcileSingleElement(returnFiber, currentFirstChild, newChild, expirationTime));
12572 case REACT_PORTAL_TYPE:
12573 return placeSingleChild(reconcileSinglePortal(returnFiber, currentFirstChild, newChild, expirationTime));
12574 }
12575 }
12576
12577 if (typeof newChild === 'string' || typeof newChild === 'number') {
12578 return placeSingleChild(reconcileSingleTextNode(returnFiber, currentFirstChild, '' + newChild, expirationTime));
12579 }
12580
12581 if (isArray(newChild)) {
12582 return reconcileChildrenArray(returnFiber, currentFirstChild, newChild, expirationTime);
12583 }
12584
12585 if (getIteratorFn(newChild)) {
12586 return reconcileChildrenIterator(returnFiber, currentFirstChild, newChild, expirationTime);
12587 }
12588
12589 if (isObject) {
12590 throwOnInvalidObjectType(returnFiber, newChild);
12591 }
12592
12593 {
12594 if (typeof newChild === 'function') {
12595 warnOnFunctionType();
12596 }
12597 }
12598 if (typeof newChild === 'undefined' && !isUnkeyedTopLevelFragment) {
12599 // If the new child is undefined, and the return fiber is a composite
12600 // component, throw an error. If Fiber return types are disabled,
12601 // we already threw above.
12602 switch (returnFiber.tag) {
12603 case ClassComponent:
12604 {
12605 {
12606 var instance = returnFiber.stateNode;
12607 if (instance.render._isMockFunction) {
12608 // We allow auto-mocks to proceed as if they're returning null.
12609 break;
12610 }
12611 }
12612 }
12613 // Intentionally fall through to the next case, which handles both
12614 // functions and classes
12615 // eslint-disable-next-lined no-fallthrough
12616 case FunctionComponent:
12617 {
12618 var Component = returnFiber.type;
12619 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');
12620 }
12621 }
12622 }
12623
12624 // Remaining cases are all treated as empty.
12625 return deleteRemainingChildren(returnFiber, currentFirstChild);
12626 }
12627
12628 return reconcileChildFibers;
12629}
12630
12631var reconcileChildFibers = ChildReconciler(true);
12632var mountChildFibers = ChildReconciler(false);
12633
12634function cloneChildFibers(current$$1, workInProgress) {
12635 !(current$$1 === null || workInProgress.child === current$$1.child) ? invariant(false, 'Resuming work not yet implemented.') : void 0;
12636
12637 if (workInProgress.child === null) {
12638 return;
12639 }
12640
12641 var currentChild = workInProgress.child;
12642 var newChild = createWorkInProgress(currentChild, currentChild.pendingProps, currentChild.expirationTime);
12643 workInProgress.child = newChild;
12644
12645 newChild.return = workInProgress;
12646 while (currentChild.sibling !== null) {
12647 currentChild = currentChild.sibling;
12648 newChild = newChild.sibling = createWorkInProgress(currentChild, currentChild.pendingProps, currentChild.expirationTime);
12649 newChild.return = workInProgress;
12650 }
12651 newChild.sibling = null;
12652}
12653
12654var NO_CONTEXT = {};
12655
12656var contextStackCursor$1 = createCursor(NO_CONTEXT);
12657var contextFiberStackCursor = createCursor(NO_CONTEXT);
12658var rootInstanceStackCursor = createCursor(NO_CONTEXT);
12659
12660function requiredContext(c) {
12661 !(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;
12662 return c;
12663}
12664
12665function getRootHostContainer() {
12666 var rootInstance = requiredContext(rootInstanceStackCursor.current);
12667 return rootInstance;
12668}
12669
12670function pushHostContainer(fiber, nextRootInstance) {
12671 // Push current root instance onto the stack;
12672 // This allows us to reset root when portals are popped.
12673 push(rootInstanceStackCursor, nextRootInstance, fiber);
12674 // Track the context and the Fiber that provided it.
12675 // This enables us to pop only Fibers that provide unique contexts.
12676 push(contextFiberStackCursor, fiber, fiber);
12677
12678 // Finally, we need to push the host context to the stack.
12679 // However, we can't just call getRootHostContext() and push it because
12680 // we'd have a different number of entries on the stack depending on
12681 // whether getRootHostContext() throws somewhere in renderer code or not.
12682 // So we push an empty value first. This lets us safely unwind on errors.
12683 push(contextStackCursor$1, NO_CONTEXT, fiber);
12684 var nextRootContext = getRootHostContext(nextRootInstance);
12685 // Now that we know this function doesn't throw, replace it.
12686 pop(contextStackCursor$1, fiber);
12687 push(contextStackCursor$1, nextRootContext, fiber);
12688}
12689
12690function popHostContainer(fiber) {
12691 pop(contextStackCursor$1, fiber);
12692 pop(contextFiberStackCursor, fiber);
12693 pop(rootInstanceStackCursor, fiber);
12694}
12695
12696function getHostContext() {
12697 var context = requiredContext(contextStackCursor$1.current);
12698 return context;
12699}
12700
12701function pushHostContext(fiber) {
12702 var rootInstance = requiredContext(rootInstanceStackCursor.current);
12703 var context = requiredContext(contextStackCursor$1.current);
12704 var nextContext = getChildHostContext(context, fiber.type, rootInstance);
12705
12706 // Don't push this Fiber's context unless it's unique.
12707 if (context === nextContext) {
12708 return;
12709 }
12710
12711 // Track the context and the Fiber that provided it.
12712 // This enables us to pop only Fibers that provide unique contexts.
12713 push(contextFiberStackCursor, fiber, fiber);
12714 push(contextStackCursor$1, nextContext, fiber);
12715}
12716
12717function popHostContext(fiber) {
12718 // Do not pop unless this Fiber provided the current context.
12719 // pushHostContext() only pushes Fibers that provide unique contexts.
12720 if (contextFiberStackCursor.current !== fiber) {
12721 return;
12722 }
12723
12724 pop(contextStackCursor$1, fiber);
12725 pop(contextFiberStackCursor, fiber);
12726}
12727
12728var NoEffect$1 = /* */0;
12729var UnmountSnapshot = /* */2;
12730var UnmountMutation = /* */4;
12731var MountMutation = /* */8;
12732var UnmountLayout = /* */16;
12733var MountLayout = /* */32;
12734var MountPassive = /* */64;
12735var UnmountPassive = /* */128;
12736
12737var ReactCurrentDispatcher$1 = ReactSharedInternals.ReactCurrentDispatcher;
12738
12739
12740var didWarnAboutMismatchedHooksForComponent = void 0;
12741{
12742 didWarnAboutMismatchedHooksForComponent = new Set();
12743}
12744
12745// These are set right before calling the component.
12746var renderExpirationTime = NoWork;
12747// The work-in-progress fiber. I've named it differently to distinguish it from
12748// the work-in-progress hook.
12749var currentlyRenderingFiber$1 = null;
12750
12751// Hooks are stored as a linked list on the fiber's memoizedState field. The
12752// current hook list is the list that belongs to the current fiber. The
12753// work-in-progress hook list is a new list that will be added to the
12754// work-in-progress fiber.
12755var firstCurrentHook = null;
12756var currentHook = null;
12757var nextCurrentHook = null;
12758var firstWorkInProgressHook = null;
12759var workInProgressHook = null;
12760var nextWorkInProgressHook = null;
12761
12762var remainingExpirationTime = NoWork;
12763var componentUpdateQueue = null;
12764var sideEffectTag = 0;
12765
12766// Updates scheduled during render will trigger an immediate re-render at the
12767// end of the current pass. We can't store these updates on the normal queue,
12768// because if the work is aborted, they should be discarded. Because this is
12769// a relatively rare case, we also don't want to add an additional field to
12770// either the hook or queue object types. So we store them in a lazily create
12771// map of queue -> render-phase updates, which are discarded once the component
12772// completes without re-rendering.
12773
12774// Whether an update was scheduled during the currently executing render pass.
12775var didScheduleRenderPhaseUpdate = false;
12776// Lazily created map of render-phase updates
12777var renderPhaseUpdates = null;
12778// Counter to prevent infinite loops.
12779var numberOfReRenders = 0;
12780var RE_RENDER_LIMIT = 25;
12781
12782// In DEV, this is the name of the currently executing primitive hook
12783var currentHookNameInDev = null;
12784
12785function warnOnHookMismatchInDev() {
12786 {
12787 var componentName = getComponentName(currentlyRenderingFiber$1.type);
12788 if (!didWarnAboutMismatchedHooksForComponent.has(componentName)) {
12789 didWarnAboutMismatchedHooksForComponent.add(componentName);
12790
12791 var secondColumnStart = 22;
12792
12793 var table = '';
12794 var prevHook = firstCurrentHook;
12795 var nextHook = firstWorkInProgressHook;
12796 var n = 1;
12797 while (prevHook !== null && nextHook !== null) {
12798 var oldHookName = prevHook._debugType;
12799 var newHookName = nextHook._debugType;
12800
12801 var row = n + '. ' + oldHookName;
12802
12803 // Extra space so second column lines up
12804 // lol @ IE not supporting String#repeat
12805 while (row.length < secondColumnStart) {
12806 row += ' ';
12807 }
12808
12809 row += newHookName + '\n';
12810
12811 table += row;
12812 prevHook = prevHook.next;
12813 nextHook = nextHook.next;
12814 n++;
12815 }
12816
12817 warning$1(false, 'React has detected a change in the order of Hooks called by %s. ' + 'This will lead to bugs and errors if not fixed. ' + 'For more information, read the Rules of Hooks: https://fb.me/rules-of-hooks\n\n' + ' Previous render Next render\n' + ' -------------------------------\n' + '%s' + ' ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n', componentName, table);
12818 }
12819 }
12820}
12821
12822function throwInvalidHookError() {
12823 invariant(false, 'Hooks can only be called inside the body of a function component. (https://fb.me/react-invalid-hook-call)');
12824}
12825
12826function areHookInputsEqual(nextDeps, prevDeps) {
12827 if (prevDeps === null) {
12828 {
12829 warning$1(false, '%s received a final argument during this render, but not during ' + 'the previous render. Even though the final argument is optional, ' + 'its type cannot change between renders.', currentHookNameInDev);
12830 }
12831 return false;
12832 }
12833
12834 {
12835 // Don't bother comparing lengths in prod because these arrays should be
12836 // passed inline.
12837 if (nextDeps.length !== prevDeps.length) {
12838 warning$1(false, 'The final argument passed to %s changed size between renders. The ' + 'order and size of this array must remain constant.\n\n' + 'Previous: %s\n' + 'Incoming: %s', currentHookNameInDev, '[' + nextDeps.join(', ') + ']', '[' + prevDeps.join(', ') + ']');
12839 }
12840 }
12841 for (var i = 0; i < prevDeps.length && i < nextDeps.length; i++) {
12842 if (is(nextDeps[i], prevDeps[i])) {
12843 continue;
12844 }
12845 return false;
12846 }
12847 return true;
12848}
12849
12850function renderWithHooks(current, workInProgress, Component, props, refOrContext, nextRenderExpirationTime) {
12851 renderExpirationTime = nextRenderExpirationTime;
12852 currentlyRenderingFiber$1 = workInProgress;
12853 firstCurrentHook = nextCurrentHook = current !== null ? current.memoizedState : null;
12854
12855 // The following should have already been reset
12856 // currentHook = null;
12857 // workInProgressHook = null;
12858
12859 // remainingExpirationTime = NoWork;
12860 // componentUpdateQueue = null;
12861
12862 // didScheduleRenderPhaseUpdate = false;
12863 // renderPhaseUpdates = null;
12864 // numberOfReRenders = 0;
12865 // sideEffectTag = 0;
12866
12867 {
12868 ReactCurrentDispatcher$1.current = nextCurrentHook === null ? HooksDispatcherOnMountInDEV : HooksDispatcherOnUpdateInDEV;
12869 }
12870
12871 var children = Component(props, refOrContext);
12872
12873 if (didScheduleRenderPhaseUpdate) {
12874 do {
12875 didScheduleRenderPhaseUpdate = false;
12876 numberOfReRenders += 1;
12877
12878 // Start over from the beginning of the list
12879 firstCurrentHook = nextCurrentHook = current !== null ? current.memoizedState : null;
12880 nextWorkInProgressHook = firstWorkInProgressHook;
12881
12882 currentHook = null;
12883 workInProgressHook = null;
12884 componentUpdateQueue = null;
12885
12886 ReactCurrentDispatcher$1.current = HooksDispatcherOnUpdateInDEV;
12887
12888 children = Component(props, refOrContext);
12889 } while (didScheduleRenderPhaseUpdate);
12890
12891 renderPhaseUpdates = null;
12892 numberOfReRenders = 0;
12893 }
12894
12895 {
12896 currentHookNameInDev = null;
12897 }
12898
12899 // We can assume the previous dispatcher is always this one, since we set it
12900 // at the beginning of the render phase and there's no re-entrancy.
12901 ReactCurrentDispatcher$1.current = ContextOnlyDispatcher;
12902
12903 var renderedWork = currentlyRenderingFiber$1;
12904
12905 renderedWork.memoizedState = firstWorkInProgressHook;
12906 renderedWork.expirationTime = remainingExpirationTime;
12907 renderedWork.updateQueue = componentUpdateQueue;
12908 renderedWork.effectTag |= sideEffectTag;
12909
12910 var didRenderTooFewHooks = currentHook !== null && currentHook.next !== null;
12911
12912 renderExpirationTime = NoWork;
12913 currentlyRenderingFiber$1 = null;
12914
12915 firstCurrentHook = null;
12916 currentHook = null;
12917 nextCurrentHook = null;
12918 firstWorkInProgressHook = null;
12919 workInProgressHook = null;
12920 nextWorkInProgressHook = null;
12921
12922 remainingExpirationTime = NoWork;
12923 componentUpdateQueue = null;
12924 sideEffectTag = 0;
12925
12926 // These were reset above
12927 // didScheduleRenderPhaseUpdate = false;
12928 // renderPhaseUpdates = null;
12929 // numberOfReRenders = 0;
12930
12931 !!didRenderTooFewHooks ? invariant(false, 'Rendered fewer hooks than expected. This may be caused by an accidental early return statement.') : void 0;
12932
12933 return children;
12934}
12935
12936function bailoutHooks(current, workInProgress, expirationTime) {
12937 workInProgress.updateQueue = current.updateQueue;
12938 workInProgress.effectTag &= ~(Passive | Update);
12939 if (current.expirationTime <= expirationTime) {
12940 current.expirationTime = NoWork;
12941 }
12942}
12943
12944function resetHooks() {
12945 // We can assume the previous dispatcher is always this one, since we set it
12946 // at the beginning of the render phase and there's no re-entrancy.
12947 ReactCurrentDispatcher$1.current = ContextOnlyDispatcher;
12948
12949 // This is used to reset the state of this module when a component throws.
12950 // It's also called inside mountIndeterminateComponent if we determine the
12951 // component is a module-style component.
12952 renderExpirationTime = NoWork;
12953 currentlyRenderingFiber$1 = null;
12954
12955 firstCurrentHook = null;
12956 currentHook = null;
12957 nextCurrentHook = null;
12958 firstWorkInProgressHook = null;
12959 workInProgressHook = null;
12960 nextWorkInProgressHook = null;
12961
12962 remainingExpirationTime = NoWork;
12963 componentUpdateQueue = null;
12964 sideEffectTag = 0;
12965
12966 {
12967 currentHookNameInDev = null;
12968 }
12969
12970 didScheduleRenderPhaseUpdate = false;
12971 renderPhaseUpdates = null;
12972 numberOfReRenders = 0;
12973}
12974
12975function mountWorkInProgressHook() {
12976 var hook = {
12977 memoizedState: null,
12978
12979 baseState: null,
12980 queue: null,
12981 baseUpdate: null,
12982
12983 next: null
12984 };
12985
12986 {
12987 hook._debugType = currentHookNameInDev;
12988 if (currentlyRenderingFiber$1 !== null && currentlyRenderingFiber$1.alternate !== null) {
12989 warning$1(false, '%s: Rendered more hooks than during the previous render. This is ' + 'not currently supported and may lead to unexpected behavior.', getComponentName(currentlyRenderingFiber$1.type));
12990 }
12991 }
12992 if (workInProgressHook === null) {
12993 // This is the first hook in the list
12994 firstWorkInProgressHook = workInProgressHook = hook;
12995 } else {
12996 // Append to the end of the list
12997 workInProgressHook = workInProgressHook.next = hook;
12998 }
12999 return workInProgressHook;
13000}
13001
13002function updateWorkInProgressHook() {
13003 // This function is used both for updates and for re-renders triggered by a
13004 // render phase update. It assumes there is either a current hook we can
13005 // clone, or a work-in-progress hook from a previous render pass that we can
13006 // use as a base. When we reach the end of the base list, we must switch to
13007 // the dispatcher used for mounts.
13008 if (nextWorkInProgressHook !== null) {
13009 // There's already a work-in-progress. Reuse it.
13010 workInProgressHook = nextWorkInProgressHook;
13011 nextWorkInProgressHook = workInProgressHook.next;
13012
13013 currentHook = nextCurrentHook;
13014 nextCurrentHook = currentHook !== null ? currentHook.next : null;
13015 } else {
13016 // Clone from the current hook.
13017 !(nextCurrentHook !== null) ? invariant(false, 'Rendered more hooks than during the previous render.') : void 0;
13018 currentHook = nextCurrentHook;
13019
13020 var newHook = {
13021 memoizedState: currentHook.memoizedState,
13022
13023 baseState: currentHook.baseState,
13024 queue: currentHook.queue,
13025 baseUpdate: currentHook.baseUpdate,
13026
13027 next: null
13028 };
13029
13030 if (workInProgressHook === null) {
13031 // This is the first hook in the list.
13032 workInProgressHook = firstWorkInProgressHook = newHook;
13033 } else {
13034 // Append to the end of the list.
13035 workInProgressHook = workInProgressHook.next = newHook;
13036 }
13037 nextCurrentHook = currentHook.next;
13038
13039 {
13040 newHook._debugType = currentHookNameInDev;
13041 if (currentHookNameInDev !== currentHook._debugType) {
13042 warnOnHookMismatchInDev();
13043 }
13044 }
13045 }
13046 return workInProgressHook;
13047}
13048
13049function createFunctionComponentUpdateQueue() {
13050 return {
13051 lastEffect: null
13052 };
13053}
13054
13055function basicStateReducer(state, action) {
13056 return typeof action === 'function' ? action(state) : action;
13057}
13058
13059function mountContext(context, observedBits) {
13060 {
13061 mountWorkInProgressHook();
13062 }
13063 return readContext(context, observedBits);
13064}
13065
13066function updateContext(context, observedBits) {
13067 {
13068 updateWorkInProgressHook();
13069 }
13070 return readContext(context, observedBits);
13071}
13072
13073function mountReducer(reducer, initialArg, init) {
13074 var hook = mountWorkInProgressHook();
13075 var initialState = void 0;
13076 if (init !== undefined) {
13077 initialState = init(initialArg);
13078 } else {
13079 initialState = initialArg;
13080 }
13081 hook.memoizedState = hook.baseState = initialState;
13082 var queue = hook.queue = {
13083 last: null,
13084 dispatch: null,
13085 eagerReducer: reducer,
13086 eagerState: initialState
13087 };
13088 var dispatch = queue.dispatch = dispatchAction.bind(null,
13089 // Flow doesn't know this is non-null, but we do.
13090 currentlyRenderingFiber$1, queue);
13091 return [hook.memoizedState, dispatch];
13092}
13093
13094function updateReducer(reducer, initialArg, init) {
13095 var hook = updateWorkInProgressHook();
13096 var queue = hook.queue;
13097 !(queue !== null) ? invariant(false, 'Should have a queue. This is likely a bug in React. Please file an issue.') : void 0;
13098
13099 if (numberOfReRenders > 0) {
13100 // This is a re-render. Apply the new render phase updates to the previous
13101 var _dispatch = queue.dispatch;
13102 if (renderPhaseUpdates !== null) {
13103 // Render phase updates are stored in a map of queue -> linked list
13104 var firstRenderPhaseUpdate = renderPhaseUpdates.get(queue);
13105 if (firstRenderPhaseUpdate !== undefined) {
13106 renderPhaseUpdates.delete(queue);
13107 var newState = hook.memoizedState;
13108 var update = firstRenderPhaseUpdate;
13109 do {
13110 // Process this render phase update. We don't have to check the
13111 // priority because it will always be the same as the current
13112 // render's.
13113 var _action = update.action;
13114 newState = reducer(newState, _action);
13115 update = update.next;
13116 } while (update !== null);
13117
13118 // Mark that the fiber performed work, but only if the new state is
13119 // different from the current state.
13120 if (!is(newState, hook.memoizedState)) {
13121 markWorkInProgressReceivedUpdate();
13122 }
13123
13124 hook.memoizedState = newState;
13125
13126 // Don't persist the state accumlated from the render phase updates to
13127 // the base state unless the queue is empty.
13128 // TODO: Not sure if this is the desired semantics, but it's what we
13129 // do for gDSFP. I can't remember why.
13130 if (hook.baseUpdate === queue.last) {
13131 hook.baseState = newState;
13132 }
13133
13134 return [newState, _dispatch];
13135 }
13136 }
13137 return [hook.memoizedState, _dispatch];
13138 }
13139
13140 // The last update in the entire queue
13141 var last = queue.last;
13142 // The last update that is part of the base state.
13143 var baseUpdate = hook.baseUpdate;
13144 var baseState = hook.baseState;
13145
13146 // Find the first unprocessed update.
13147 var first = void 0;
13148 if (baseUpdate !== null) {
13149 if (last !== null) {
13150 // For the first update, the queue is a circular linked list where
13151 // `queue.last.next = queue.first`. Once the first update commits, and
13152 // the `baseUpdate` is no longer empty, we can unravel the list.
13153 last.next = null;
13154 }
13155 first = baseUpdate.next;
13156 } else {
13157 first = last !== null ? last.next : null;
13158 }
13159 if (first !== null) {
13160 var _newState = baseState;
13161 var newBaseState = null;
13162 var newBaseUpdate = null;
13163 var prevUpdate = baseUpdate;
13164 var _update = first;
13165 var didSkip = false;
13166 do {
13167 var updateExpirationTime = _update.expirationTime;
13168 if (updateExpirationTime < renderExpirationTime) {
13169 // Priority is insufficient. Skip this update. If this is the first
13170 // skipped update, the previous update/state is the new base
13171 // update/state.
13172 if (!didSkip) {
13173 didSkip = true;
13174 newBaseUpdate = prevUpdate;
13175 newBaseState = _newState;
13176 }
13177 // Update the remaining priority in the queue.
13178 if (updateExpirationTime > remainingExpirationTime) {
13179 remainingExpirationTime = updateExpirationTime;
13180 }
13181 } else {
13182 // Process this update.
13183 if (_update.eagerReducer === reducer) {
13184 // If this update was processed eagerly, and its reducer matches the
13185 // current reducer, we can use the eagerly computed state.
13186 _newState = _update.eagerState;
13187 } else {
13188 var _action2 = _update.action;
13189 _newState = reducer(_newState, _action2);
13190 }
13191 }
13192 prevUpdate = _update;
13193 _update = _update.next;
13194 } while (_update !== null && _update !== first);
13195
13196 if (!didSkip) {
13197 newBaseUpdate = prevUpdate;
13198 newBaseState = _newState;
13199 }
13200
13201 // Mark that the fiber performed work, but only if the new state is
13202 // different from the current state.
13203 if (!is(_newState, hook.memoizedState)) {
13204 markWorkInProgressReceivedUpdate();
13205 }
13206
13207 hook.memoizedState = _newState;
13208 hook.baseUpdate = newBaseUpdate;
13209 hook.baseState = newBaseState;
13210
13211 queue.eagerReducer = reducer;
13212 queue.eagerState = _newState;
13213 }
13214
13215 var dispatch = queue.dispatch;
13216 return [hook.memoizedState, dispatch];
13217}
13218
13219function mountState(initialState) {
13220 var hook = mountWorkInProgressHook();
13221 if (typeof initialState === 'function') {
13222 initialState = initialState();
13223 }
13224 hook.memoizedState = hook.baseState = initialState;
13225 var queue = hook.queue = {
13226 last: null,
13227 dispatch: null,
13228 eagerReducer: basicStateReducer,
13229 eagerState: initialState
13230 };
13231 var dispatch = queue.dispatch = dispatchAction.bind(null,
13232 // Flow doesn't know this is non-null, but we do.
13233 currentlyRenderingFiber$1, queue);
13234 return [hook.memoizedState, dispatch];
13235}
13236
13237function updateState(initialState) {
13238 return updateReducer(basicStateReducer, initialState);
13239}
13240
13241function pushEffect(tag, create, destroy, deps) {
13242 var effect = {
13243 tag: tag,
13244 create: create,
13245 destroy: destroy,
13246 deps: deps,
13247 // Circular
13248 next: null
13249 };
13250 if (componentUpdateQueue === null) {
13251 componentUpdateQueue = createFunctionComponentUpdateQueue();
13252 componentUpdateQueue.lastEffect = effect.next = effect;
13253 } else {
13254 var _lastEffect = componentUpdateQueue.lastEffect;
13255 if (_lastEffect === null) {
13256 componentUpdateQueue.lastEffect = effect.next = effect;
13257 } else {
13258 var firstEffect = _lastEffect.next;
13259 _lastEffect.next = effect;
13260 effect.next = firstEffect;
13261 componentUpdateQueue.lastEffect = effect;
13262 }
13263 }
13264 return effect;
13265}
13266
13267function mountRef(initialValue) {
13268 var hook = mountWorkInProgressHook();
13269 var ref = { current: initialValue };
13270 {
13271 Object.seal(ref);
13272 }
13273 hook.memoizedState = ref;
13274 return ref;
13275}
13276
13277function updateRef(initialValue) {
13278 var hook = updateWorkInProgressHook();
13279 return hook.memoizedState;
13280}
13281
13282function mountEffectImpl(fiberEffectTag, hookEffectTag, create, deps) {
13283 var hook = mountWorkInProgressHook();
13284 var nextDeps = deps === undefined ? null : deps;
13285 sideEffectTag |= fiberEffectTag;
13286 hook.memoizedState = pushEffect(hookEffectTag, create, undefined, nextDeps);
13287}
13288
13289function updateEffectImpl(fiberEffectTag, hookEffectTag, create, deps) {
13290 var hook = updateWorkInProgressHook();
13291 var nextDeps = deps === undefined ? null : deps;
13292 var destroy = undefined;
13293
13294 if (currentHook !== null) {
13295 var prevEffect = currentHook.memoizedState;
13296 destroy = prevEffect.destroy;
13297 if (nextDeps !== null) {
13298 var prevDeps = prevEffect.deps;
13299 if (areHookInputsEqual(nextDeps, prevDeps)) {
13300 pushEffect(NoEffect$1, create, destroy, nextDeps);
13301 return;
13302 }
13303 }
13304 }
13305
13306 sideEffectTag |= fiberEffectTag;
13307 hook.memoizedState = pushEffect(hookEffectTag, create, destroy, nextDeps);
13308}
13309
13310function mountEffect(create, deps) {
13311 return mountEffectImpl(Update | Passive, UnmountPassive | MountPassive, create, deps);
13312}
13313
13314function updateEffect(create, deps) {
13315 return updateEffectImpl(Update | Passive, UnmountPassive | MountPassive, create, deps);
13316}
13317
13318function mountLayoutEffect(create, deps) {
13319 return mountEffectImpl(Update, UnmountMutation | MountLayout, create, deps);
13320}
13321
13322function updateLayoutEffect(create, deps) {
13323 return updateEffectImpl(Update, UnmountMutation | MountLayout, create, deps);
13324}
13325
13326function imperativeHandleEffect(create, ref) {
13327 if (typeof ref === 'function') {
13328 var refCallback = ref;
13329 var _inst = create();
13330 refCallback(_inst);
13331 return function () {
13332 refCallback(null);
13333 };
13334 } else if (ref !== null && ref !== undefined) {
13335 var refObject = ref;
13336 {
13337 !refObject.hasOwnProperty('current') ? warning$1(false, 'Expected useImperativeHandle() first argument to either be a ' + 'ref callback or React.createRef() object. Instead received: %s.', 'an object with keys {' + Object.keys(refObject).join(', ') + '}') : void 0;
13338 }
13339 var _inst2 = create();
13340 refObject.current = _inst2;
13341 return function () {
13342 refObject.current = null;
13343 };
13344 }
13345}
13346
13347function mountImperativeHandle(ref, create, deps) {
13348 {
13349 !(typeof create === 'function') ? warning$1(false, 'Expected useImperativeHandle() second argument to be a function ' + 'that creates a handle. Instead received: %s.', create !== null ? typeof create : 'null') : void 0;
13350 }
13351
13352 // TODO: If deps are provided, should we skip comparing the ref itself?
13353 var effectDeps = deps !== null && deps !== undefined ? deps.concat([ref]) : [ref];
13354
13355 return mountEffectImpl(Update, UnmountMutation | MountLayout, imperativeHandleEffect.bind(null, create, ref), effectDeps);
13356}
13357
13358function updateImperativeHandle(ref, create, deps) {
13359 {
13360 !(typeof create === 'function') ? warning$1(false, 'Expected useImperativeHandle() second argument to be a function ' + 'that creates a handle. Instead received: %s.', create !== null ? typeof create : 'null') : void 0;
13361 }
13362
13363 // TODO: If deps are provided, should we skip comparing the ref itself?
13364 var effectDeps = deps !== null && deps !== undefined ? deps.concat([ref]) : [ref];
13365
13366 return updateEffectImpl(Update, UnmountMutation | MountLayout, imperativeHandleEffect.bind(null, create, ref), effectDeps);
13367}
13368
13369function mountDebugValue(value, formatterFn) {
13370 // This hook is normally a no-op.
13371 // The react-debug-hooks package injects its own implementation
13372 // so that e.g. DevTools can display custom hook values.
13373}
13374
13375var updateDebugValue = mountDebugValue;
13376
13377function mountCallback(callback, deps) {
13378 var hook = mountWorkInProgressHook();
13379 var nextDeps = deps === undefined ? null : deps;
13380 hook.memoizedState = [callback, nextDeps];
13381 return callback;
13382}
13383
13384function updateCallback(callback, deps) {
13385 var hook = updateWorkInProgressHook();
13386 var nextDeps = deps === undefined ? null : deps;
13387 var prevState = hook.memoizedState;
13388 if (prevState !== null) {
13389 if (nextDeps !== null) {
13390 var prevDeps = prevState[1];
13391 if (areHookInputsEqual(nextDeps, prevDeps)) {
13392 return prevState[0];
13393 }
13394 }
13395 }
13396 hook.memoizedState = [callback, nextDeps];
13397 return callback;
13398}
13399
13400function mountMemo(nextCreate, deps) {
13401 var hook = mountWorkInProgressHook();
13402 var nextDeps = deps === undefined ? null : deps;
13403 var nextValue = nextCreate();
13404 hook.memoizedState = [nextValue, nextDeps];
13405 return nextValue;
13406}
13407
13408function updateMemo(nextCreate, deps) {
13409 var hook = updateWorkInProgressHook();
13410 var nextDeps = deps === undefined ? null : deps;
13411 var prevState = hook.memoizedState;
13412 if (prevState !== null) {
13413 // Assume these are defined. If they're not, areHookInputsEqual will warn.
13414 if (nextDeps !== null) {
13415 var prevDeps = prevState[1];
13416 if (areHookInputsEqual(nextDeps, prevDeps)) {
13417 return prevState[0];
13418 }
13419 }
13420 }
13421 var nextValue = nextCreate();
13422 hook.memoizedState = [nextValue, nextDeps];
13423 return nextValue;
13424}
13425
13426// in a test-like environment, we want to warn if dispatchAction()
13427// is called outside of a batchedUpdates/TestUtils.act(...) call.
13428var shouldWarnForUnbatchedSetState = false;
13429
13430{
13431 // jest isnt' a 'global', it's just exposed to tests via a wrapped function
13432 // further, this isn't a test file, so flow doesn't recognize the symbol. So...
13433 // $FlowExpectedError - because requirements don't give a damn about your type sigs.
13434 if ('undefined' !== typeof jest) {
13435 shouldWarnForUnbatchedSetState = true;
13436 }
13437}
13438
13439function dispatchAction(fiber, queue, action) {
13440 !(numberOfReRenders < RE_RENDER_LIMIT) ? invariant(false, 'Too many re-renders. React limits the number of renders to prevent an infinite loop.') : void 0;
13441
13442 {
13443 !(arguments.length <= 3) ? warning$1(false, "State updates from the useState() and useReducer() Hooks don't support the " + 'second callback argument. To execute a side effect after ' + 'rendering, declare it in the component body with useEffect().') : void 0;
13444 }
13445
13446 var alternate = fiber.alternate;
13447 if (fiber === currentlyRenderingFiber$1 || alternate !== null && alternate === currentlyRenderingFiber$1) {
13448 // This is a render phase update. Stash it in a lazily-created map of
13449 // queue -> linked list of updates. After this render pass, we'll restart
13450 // and apply the stashed updates on top of the work-in-progress hook.
13451 didScheduleRenderPhaseUpdate = true;
13452 var update = {
13453 expirationTime: renderExpirationTime,
13454 action: action,
13455 eagerReducer: null,
13456 eagerState: null,
13457 next: null
13458 };
13459 if (renderPhaseUpdates === null) {
13460 renderPhaseUpdates = new Map();
13461 }
13462 var firstRenderPhaseUpdate = renderPhaseUpdates.get(queue);
13463 if (firstRenderPhaseUpdate === undefined) {
13464 renderPhaseUpdates.set(queue, update);
13465 } else {
13466 // Append the update to the end of the list.
13467 var lastRenderPhaseUpdate = firstRenderPhaseUpdate;
13468 while (lastRenderPhaseUpdate.next !== null) {
13469 lastRenderPhaseUpdate = lastRenderPhaseUpdate.next;
13470 }
13471 lastRenderPhaseUpdate.next = update;
13472 }
13473 } else {
13474 flushPassiveEffects();
13475
13476 var currentTime = requestCurrentTime();
13477 var _expirationTime = computeExpirationForFiber(currentTime, fiber);
13478
13479 var _update2 = {
13480 expirationTime: _expirationTime,
13481 action: action,
13482 eagerReducer: null,
13483 eagerState: null,
13484 next: null
13485 };
13486
13487 // Append the update to the end of the list.
13488 var _last = queue.last;
13489 if (_last === null) {
13490 // This is the first update. Create a circular list.
13491 _update2.next = _update2;
13492 } else {
13493 var first = _last.next;
13494 if (first !== null) {
13495 // Still circular.
13496 _update2.next = first;
13497 }
13498 _last.next = _update2;
13499 }
13500 queue.last = _update2;
13501
13502 if (fiber.expirationTime === NoWork && (alternate === null || alternate.expirationTime === NoWork)) {
13503 // The queue is currently empty, which means we can eagerly compute the
13504 // next state before entering the render phase. If the new state is the
13505 // same as the current state, we may be able to bail out entirely.
13506 var _eagerReducer = queue.eagerReducer;
13507 if (_eagerReducer !== null) {
13508 var prevDispatcher = void 0;
13509 {
13510 prevDispatcher = ReactCurrentDispatcher$1.current;
13511 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
13512 }
13513 try {
13514 var currentState = queue.eagerState;
13515 var _eagerState = _eagerReducer(currentState, action);
13516 // Stash the eagerly computed state, and the reducer used to compute
13517 // it, on the update object. If the reducer hasn't changed by the
13518 // time we enter the render phase, then the eager state can be used
13519 // without calling the reducer again.
13520 _update2.eagerReducer = _eagerReducer;
13521 _update2.eagerState = _eagerState;
13522 if (is(_eagerState, currentState)) {
13523 // Fast path. We can bail out without scheduling React to re-render.
13524 // It's still possible that we'll need to rebase this update later,
13525 // if the component re-renders for a different reason and by that
13526 // time the reducer has changed.
13527 return;
13528 }
13529 } catch (error) {
13530 // Suppress the error. It will throw again in the render phase.
13531 } finally {
13532 {
13533 ReactCurrentDispatcher$1.current = prevDispatcher;
13534 }
13535 }
13536 }
13537 }
13538 {
13539 if (shouldWarnForUnbatchedSetState === true) {
13540 warnIfNotCurrentlyBatchingInDev(fiber);
13541 }
13542 }
13543 scheduleWork(fiber, _expirationTime);
13544 }
13545}
13546
13547var ContextOnlyDispatcher = {
13548 readContext: readContext,
13549
13550 useCallback: throwInvalidHookError,
13551 useContext: throwInvalidHookError,
13552 useEffect: throwInvalidHookError,
13553 useImperativeHandle: throwInvalidHookError,
13554 useLayoutEffect: throwInvalidHookError,
13555 useMemo: throwInvalidHookError,
13556 useReducer: throwInvalidHookError,
13557 useRef: throwInvalidHookError,
13558 useState: throwInvalidHookError,
13559 useDebugValue: throwInvalidHookError
13560};
13561
13562var HooksDispatcherOnMountInDEV = null;
13563var HooksDispatcherOnUpdateInDEV = null;
13564var InvalidNestedHooksDispatcherOnMountInDEV = null;
13565var InvalidNestedHooksDispatcherOnUpdateInDEV = null;
13566
13567{
13568 var warnInvalidContextAccess = function () {
13569 warning$1(false, 'Context can only be read while React is rendering. ' + 'In classes, you can read it in the render method or getDerivedStateFromProps. ' + 'In function components, you can read it directly in the function body, but not ' + 'inside Hooks like useReducer() or useMemo().');
13570 };
13571
13572 var warnInvalidHookAccess = function () {
13573 warning$1(false, 'Do not call Hooks inside useEffect(...), useMemo(...), or other built-in Hooks. ' + 'You can only call Hooks at the top level of your React function. ' + 'For more information, see ' + 'https://fb.me/rules-of-hooks');
13574 };
13575
13576 HooksDispatcherOnMountInDEV = {
13577 readContext: function (context, observedBits) {
13578 return readContext(context, observedBits);
13579 },
13580 useCallback: function (callback, deps) {
13581 currentHookNameInDev = 'useCallback';
13582 return mountCallback(callback, deps);
13583 },
13584 useContext: function (context, observedBits) {
13585 currentHookNameInDev = 'useContext';
13586 return mountContext(context, observedBits);
13587 },
13588 useEffect: function (create, deps) {
13589 currentHookNameInDev = 'useEffect';
13590 return mountEffect(create, deps);
13591 },
13592 useImperativeHandle: function (ref, create, deps) {
13593 currentHookNameInDev = 'useImperativeHandle';
13594 return mountImperativeHandle(ref, create, deps);
13595 },
13596 useLayoutEffect: function (create, deps) {
13597 currentHookNameInDev = 'useLayoutEffect';
13598 return mountLayoutEffect(create, deps);
13599 },
13600 useMemo: function (create, deps) {
13601 currentHookNameInDev = 'useMemo';
13602 var prevDispatcher = ReactCurrentDispatcher$1.current;
13603 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
13604 try {
13605 return mountMemo(create, deps);
13606 } finally {
13607 ReactCurrentDispatcher$1.current = prevDispatcher;
13608 }
13609 },
13610 useReducer: function (reducer, initialArg, init) {
13611 currentHookNameInDev = 'useReducer';
13612 var prevDispatcher = ReactCurrentDispatcher$1.current;
13613 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
13614 try {
13615 return mountReducer(reducer, initialArg, init);
13616 } finally {
13617 ReactCurrentDispatcher$1.current = prevDispatcher;
13618 }
13619 },
13620 useRef: function (initialValue) {
13621 currentHookNameInDev = 'useRef';
13622 return mountRef(initialValue);
13623 },
13624 useState: function (initialState) {
13625 currentHookNameInDev = 'useState';
13626 var prevDispatcher = ReactCurrentDispatcher$1.current;
13627 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
13628 try {
13629 return mountState(initialState);
13630 } finally {
13631 ReactCurrentDispatcher$1.current = prevDispatcher;
13632 }
13633 },
13634 useDebugValue: function (value, formatterFn) {
13635 currentHookNameInDev = 'useDebugValue';
13636 return mountDebugValue(value, formatterFn);
13637 }
13638 };
13639
13640 HooksDispatcherOnUpdateInDEV = {
13641 readContext: function (context, observedBits) {
13642 return readContext(context, observedBits);
13643 },
13644 useCallback: function (callback, deps) {
13645 currentHookNameInDev = 'useCallback';
13646 return updateCallback(callback, deps);
13647 },
13648 useContext: function (context, observedBits) {
13649 currentHookNameInDev = 'useContext';
13650 return updateContext(context, observedBits);
13651 },
13652 useEffect: function (create, deps) {
13653 currentHookNameInDev = 'useEffect';
13654 return updateEffect(create, deps);
13655 },
13656 useImperativeHandle: function (ref, create, deps) {
13657 currentHookNameInDev = 'useImperativeHandle';
13658 return updateImperativeHandle(ref, create, deps);
13659 },
13660 useLayoutEffect: function (create, deps) {
13661 currentHookNameInDev = 'useLayoutEffect';
13662 return updateLayoutEffect(create, deps);
13663 },
13664 useMemo: function (create, deps) {
13665 currentHookNameInDev = 'useMemo';
13666 var prevDispatcher = ReactCurrentDispatcher$1.current;
13667 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
13668 try {
13669 return updateMemo(create, deps);
13670 } finally {
13671 ReactCurrentDispatcher$1.current = prevDispatcher;
13672 }
13673 },
13674 useReducer: function (reducer, initialArg, init) {
13675 currentHookNameInDev = 'useReducer';
13676 var prevDispatcher = ReactCurrentDispatcher$1.current;
13677 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
13678 try {
13679 return updateReducer(reducer, initialArg, init);
13680 } finally {
13681 ReactCurrentDispatcher$1.current = prevDispatcher;
13682 }
13683 },
13684 useRef: function (initialValue) {
13685 currentHookNameInDev = 'useRef';
13686 return updateRef(initialValue);
13687 },
13688 useState: function (initialState) {
13689 currentHookNameInDev = 'useState';
13690 var prevDispatcher = ReactCurrentDispatcher$1.current;
13691 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
13692 try {
13693 return updateState(initialState);
13694 } finally {
13695 ReactCurrentDispatcher$1.current = prevDispatcher;
13696 }
13697 },
13698 useDebugValue: function (value, formatterFn) {
13699 currentHookNameInDev = 'useDebugValue';
13700 return updateDebugValue(value, formatterFn);
13701 }
13702 };
13703
13704 InvalidNestedHooksDispatcherOnMountInDEV = {
13705 readContext: function (context, observedBits) {
13706 warnInvalidContextAccess();
13707 return readContext(context, observedBits);
13708 },
13709 useCallback: function (callback, deps) {
13710 currentHookNameInDev = 'useCallback';
13711 warnInvalidHookAccess();
13712 return mountCallback(callback, deps);
13713 },
13714 useContext: function (context, observedBits) {
13715 currentHookNameInDev = 'useContext';
13716 warnInvalidHookAccess();
13717 return mountContext(context, observedBits);
13718 },
13719 useEffect: function (create, deps) {
13720 currentHookNameInDev = 'useEffect';
13721 warnInvalidHookAccess();
13722 return mountEffect(create, deps);
13723 },
13724 useImperativeHandle: function (ref, create, deps) {
13725 currentHookNameInDev = 'useImperativeHandle';
13726 warnInvalidHookAccess();
13727 return mountImperativeHandle(ref, create, deps);
13728 },
13729 useLayoutEffect: function (create, deps) {
13730 currentHookNameInDev = 'useLayoutEffect';
13731 warnInvalidHookAccess();
13732 return mountLayoutEffect(create, deps);
13733 },
13734 useMemo: function (create, deps) {
13735 currentHookNameInDev = 'useMemo';
13736 warnInvalidHookAccess();
13737 var prevDispatcher = ReactCurrentDispatcher$1.current;
13738 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
13739 try {
13740 return mountMemo(create, deps);
13741 } finally {
13742 ReactCurrentDispatcher$1.current = prevDispatcher;
13743 }
13744 },
13745 useReducer: function (reducer, initialArg, init) {
13746 currentHookNameInDev = 'useReducer';
13747 warnInvalidHookAccess();
13748 var prevDispatcher = ReactCurrentDispatcher$1.current;
13749 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
13750 try {
13751 return mountReducer(reducer, initialArg, init);
13752 } finally {
13753 ReactCurrentDispatcher$1.current = prevDispatcher;
13754 }
13755 },
13756 useRef: function (initialValue) {
13757 currentHookNameInDev = 'useRef';
13758 warnInvalidHookAccess();
13759 return mountRef(initialValue);
13760 },
13761 useState: function (initialState) {
13762 currentHookNameInDev = 'useState';
13763 warnInvalidHookAccess();
13764 var prevDispatcher = ReactCurrentDispatcher$1.current;
13765 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
13766 try {
13767 return mountState(initialState);
13768 } finally {
13769 ReactCurrentDispatcher$1.current = prevDispatcher;
13770 }
13771 },
13772 useDebugValue: function (value, formatterFn) {
13773 currentHookNameInDev = 'useDebugValue';
13774 warnInvalidHookAccess();
13775 return mountDebugValue(value, formatterFn);
13776 }
13777 };
13778
13779 InvalidNestedHooksDispatcherOnUpdateInDEV = {
13780 readContext: function (context, observedBits) {
13781 warnInvalidContextAccess();
13782 return readContext(context, observedBits);
13783 },
13784 useCallback: function (callback, deps) {
13785 currentHookNameInDev = 'useCallback';
13786 warnInvalidHookAccess();
13787 return updateCallback(callback, deps);
13788 },
13789 useContext: function (context, observedBits) {
13790 currentHookNameInDev = 'useContext';
13791 warnInvalidHookAccess();
13792 return updateContext(context, observedBits);
13793 },
13794 useEffect: function (create, deps) {
13795 currentHookNameInDev = 'useEffect';
13796 warnInvalidHookAccess();
13797 return updateEffect(create, deps);
13798 },
13799 useImperativeHandle: function (ref, create, deps) {
13800 currentHookNameInDev = 'useImperativeHandle';
13801 warnInvalidHookAccess();
13802 return updateImperativeHandle(ref, create, deps);
13803 },
13804 useLayoutEffect: function (create, deps) {
13805 currentHookNameInDev = 'useLayoutEffect';
13806 warnInvalidHookAccess();
13807 return updateLayoutEffect(create, deps);
13808 },
13809 useMemo: function (create, deps) {
13810 currentHookNameInDev = 'useMemo';
13811 warnInvalidHookAccess();
13812 var prevDispatcher = ReactCurrentDispatcher$1.current;
13813 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
13814 try {
13815 return updateMemo(create, deps);
13816 } finally {
13817 ReactCurrentDispatcher$1.current = prevDispatcher;
13818 }
13819 },
13820 useReducer: function (reducer, initialArg, init) {
13821 currentHookNameInDev = 'useReducer';
13822 warnInvalidHookAccess();
13823 var prevDispatcher = ReactCurrentDispatcher$1.current;
13824 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
13825 try {
13826 return updateReducer(reducer, initialArg, init);
13827 } finally {
13828 ReactCurrentDispatcher$1.current = prevDispatcher;
13829 }
13830 },
13831 useRef: function (initialValue) {
13832 currentHookNameInDev = 'useRef';
13833 warnInvalidHookAccess();
13834 return updateRef(initialValue);
13835 },
13836 useState: function (initialState) {
13837 currentHookNameInDev = 'useState';
13838 warnInvalidHookAccess();
13839 var prevDispatcher = ReactCurrentDispatcher$1.current;
13840 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
13841 try {
13842 return updateState(initialState);
13843 } finally {
13844 ReactCurrentDispatcher$1.current = prevDispatcher;
13845 }
13846 },
13847 useDebugValue: function (value, formatterFn) {
13848 currentHookNameInDev = 'useDebugValue';
13849 warnInvalidHookAccess();
13850 return updateDebugValue(value, formatterFn);
13851 }
13852 };
13853}
13854
13855var commitTime = 0;
13856var profilerStartTime = -1;
13857
13858function getCommitTime() {
13859 return commitTime;
13860}
13861
13862function recordCommitTime() {
13863 if (!enableProfilerTimer) {
13864 return;
13865 }
13866 commitTime = unstable_now();
13867}
13868
13869function startProfilerTimer(fiber) {
13870 if (!enableProfilerTimer) {
13871 return;
13872 }
13873
13874 profilerStartTime = unstable_now();
13875
13876 if (fiber.actualStartTime < 0) {
13877 fiber.actualStartTime = unstable_now();
13878 }
13879}
13880
13881function stopProfilerTimerIfRunning(fiber) {
13882 if (!enableProfilerTimer) {
13883 return;
13884 }
13885 profilerStartTime = -1;
13886}
13887
13888function stopProfilerTimerIfRunningAndRecordDelta(fiber, overrideBaseTime) {
13889 if (!enableProfilerTimer) {
13890 return;
13891 }
13892
13893 if (profilerStartTime >= 0) {
13894 var elapsedTime = unstable_now() - profilerStartTime;
13895 fiber.actualDuration += elapsedTime;
13896 if (overrideBaseTime) {
13897 fiber.selfBaseDuration = elapsedTime;
13898 }
13899 profilerStartTime = -1;
13900 }
13901}
13902
13903// The deepest Fiber on the stack involved in a hydration context.
13904// This may have been an insertion or a hydration.
13905var hydrationParentFiber = null;
13906var nextHydratableInstance = null;
13907var isHydrating = false;
13908
13909function enterHydrationState(fiber) {
13910 if (!supportsHydration) {
13911 return false;
13912 }
13913
13914 var parentInstance = fiber.stateNode.containerInfo;
13915 nextHydratableInstance = getFirstHydratableChild(parentInstance);
13916 hydrationParentFiber = fiber;
13917 isHydrating = true;
13918 return true;
13919}
13920
13921function deleteHydratableInstance(returnFiber, instance) {
13922 {
13923 switch (returnFiber.tag) {
13924 case HostRoot:
13925 didNotHydrateContainerInstance(returnFiber.stateNode.containerInfo, instance);
13926 break;
13927 case HostComponent:
13928 didNotHydrateInstance(returnFiber.type, returnFiber.memoizedProps, returnFiber.stateNode, instance);
13929 break;
13930 }
13931 }
13932
13933 var childToDelete = createFiberFromHostInstanceForDeletion();
13934 childToDelete.stateNode = instance;
13935 childToDelete.return = returnFiber;
13936 childToDelete.effectTag = Deletion;
13937
13938 // This might seem like it belongs on progressedFirstDeletion. However,
13939 // these children are not part of the reconciliation list of children.
13940 // Even if we abort and rereconcile the children, that will try to hydrate
13941 // again and the nodes are still in the host tree so these will be
13942 // recreated.
13943 if (returnFiber.lastEffect !== null) {
13944 returnFiber.lastEffect.nextEffect = childToDelete;
13945 returnFiber.lastEffect = childToDelete;
13946 } else {
13947 returnFiber.firstEffect = returnFiber.lastEffect = childToDelete;
13948 }
13949}
13950
13951function insertNonHydratedInstance(returnFiber, fiber) {
13952 fiber.effectTag |= Placement;
13953 {
13954 switch (returnFiber.tag) {
13955 case HostRoot:
13956 {
13957 var parentContainer = returnFiber.stateNode.containerInfo;
13958 switch (fiber.tag) {
13959 case HostComponent:
13960 var type = fiber.type;
13961 var props = fiber.pendingProps;
13962 didNotFindHydratableContainerInstance(parentContainer, type, props);
13963 break;
13964 case HostText:
13965 var text = fiber.pendingProps;
13966 didNotFindHydratableContainerTextInstance(parentContainer, text);
13967 break;
13968 }
13969 break;
13970 }
13971 case HostComponent:
13972 {
13973 var parentType = returnFiber.type;
13974 var parentProps = returnFiber.memoizedProps;
13975 var parentInstance = returnFiber.stateNode;
13976 switch (fiber.tag) {
13977 case HostComponent:
13978 var _type = fiber.type;
13979 var _props = fiber.pendingProps;
13980 didNotFindHydratableInstance(parentType, parentProps, parentInstance, _type, _props);
13981 break;
13982 case HostText:
13983 var _text = fiber.pendingProps;
13984 didNotFindHydratableTextInstance(parentType, parentProps, parentInstance, _text);
13985 break;
13986 }
13987 break;
13988 }
13989 default:
13990 return;
13991 }
13992 }
13993}
13994
13995function tryHydrate(fiber, nextInstance) {
13996 switch (fiber.tag) {
13997 case HostComponent:
13998 {
13999 var type = fiber.type;
14000 var props = fiber.pendingProps;
14001 var instance = canHydrateInstance(nextInstance, type, props);
14002 if (instance !== null) {
14003 fiber.stateNode = instance;
14004 return true;
14005 }
14006 return false;
14007 }
14008 case HostText:
14009 {
14010 var text = fiber.pendingProps;
14011 var textInstance = canHydrateTextInstance(nextInstance, text);
14012 if (textInstance !== null) {
14013 fiber.stateNode = textInstance;
14014 return true;
14015 }
14016 return false;
14017 }
14018 default:
14019 return false;
14020 }
14021}
14022
14023function tryToClaimNextHydratableInstance(fiber) {
14024 if (!isHydrating) {
14025 return;
14026 }
14027 var nextInstance = nextHydratableInstance;
14028 if (!nextInstance) {
14029 // Nothing to hydrate. Make it an insertion.
14030 insertNonHydratedInstance(hydrationParentFiber, fiber);
14031 isHydrating = false;
14032 hydrationParentFiber = fiber;
14033 return;
14034 }
14035 var firstAttemptedInstance = nextInstance;
14036 if (!tryHydrate(fiber, nextInstance)) {
14037 // If we can't hydrate this instance let's try the next one.
14038 // We use this as a heuristic. It's based on intuition and not data so it
14039 // might be flawed or unnecessary.
14040 nextInstance = getNextHydratableSibling(firstAttemptedInstance);
14041 if (!nextInstance || !tryHydrate(fiber, nextInstance)) {
14042 // Nothing to hydrate. Make it an insertion.
14043 insertNonHydratedInstance(hydrationParentFiber, fiber);
14044 isHydrating = false;
14045 hydrationParentFiber = fiber;
14046 return;
14047 }
14048 // We matched the next one, we'll now assume that the first one was
14049 // superfluous and we'll delete it. Since we can't eagerly delete it
14050 // we'll have to schedule a deletion. To do that, this node needs a dummy
14051 // fiber associated with it.
14052 deleteHydratableInstance(hydrationParentFiber, firstAttemptedInstance);
14053 }
14054 hydrationParentFiber = fiber;
14055 nextHydratableInstance = getFirstHydratableChild(nextInstance);
14056}
14057
14058function prepareToHydrateHostInstance(fiber, rootContainerInstance, hostContext) {
14059 if (!supportsHydration) {
14060 invariant(false, 'Expected prepareToHydrateHostInstance() to never be called. This error is likely caused by a bug in React. Please file an issue.');
14061 }
14062
14063 var instance = fiber.stateNode;
14064 var updatePayload = hydrateInstance(instance, fiber.type, fiber.memoizedProps, rootContainerInstance, hostContext, fiber);
14065 // TODO: Type this specific to this type of component.
14066 fiber.updateQueue = updatePayload;
14067 // If the update payload indicates that there is a change or if there
14068 // is a new ref we mark this as an update.
14069 if (updatePayload !== null) {
14070 return true;
14071 }
14072 return false;
14073}
14074
14075function prepareToHydrateHostTextInstance(fiber) {
14076 if (!supportsHydration) {
14077 invariant(false, 'Expected prepareToHydrateHostTextInstance() to never be called. This error is likely caused by a bug in React. Please file an issue.');
14078 }
14079
14080 var textInstance = fiber.stateNode;
14081 var textContent = fiber.memoizedProps;
14082 var shouldUpdate = hydrateTextInstance(textInstance, textContent, fiber);
14083 {
14084 if (shouldUpdate) {
14085 // We assume that prepareToHydrateHostTextInstance is called in a context where the
14086 // hydration parent is the parent host component of this host text.
14087 var returnFiber = hydrationParentFiber;
14088 if (returnFiber !== null) {
14089 switch (returnFiber.tag) {
14090 case HostRoot:
14091 {
14092 var parentContainer = returnFiber.stateNode.containerInfo;
14093 didNotMatchHydratedContainerTextInstance(parentContainer, textInstance, textContent);
14094 break;
14095 }
14096 case HostComponent:
14097 {
14098 var parentType = returnFiber.type;
14099 var parentProps = returnFiber.memoizedProps;
14100 var parentInstance = returnFiber.stateNode;
14101 didNotMatchHydratedTextInstance(parentType, parentProps, parentInstance, textInstance, textContent);
14102 break;
14103 }
14104 }
14105 }
14106 }
14107 }
14108 return shouldUpdate;
14109}
14110
14111function popToNextHostParent(fiber) {
14112 var parent = fiber.return;
14113 while (parent !== null && parent.tag !== HostComponent && parent.tag !== HostRoot) {
14114 parent = parent.return;
14115 }
14116 hydrationParentFiber = parent;
14117}
14118
14119function popHydrationState(fiber) {
14120 if (!supportsHydration) {
14121 return false;
14122 }
14123 if (fiber !== hydrationParentFiber) {
14124 // We're deeper than the current hydration context, inside an inserted
14125 // tree.
14126 return false;
14127 }
14128 if (!isHydrating) {
14129 // If we're not currently hydrating but we're in a hydration context, then
14130 // we were an insertion and now need to pop up reenter hydration of our
14131 // siblings.
14132 popToNextHostParent(fiber);
14133 isHydrating = true;
14134 return false;
14135 }
14136
14137 var type = fiber.type;
14138
14139 // If we have any remaining hydratable nodes, we need to delete them now.
14140 // We only do this deeper than head and body since they tend to have random
14141 // other nodes in them. We also ignore components with pure text content in
14142 // side of them.
14143 // TODO: Better heuristic.
14144 if (fiber.tag !== HostComponent || type !== 'head' && type !== 'body' && !shouldSetTextContent(type, fiber.memoizedProps)) {
14145 var nextInstance = nextHydratableInstance;
14146 while (nextInstance) {
14147 deleteHydratableInstance(fiber, nextInstance);
14148 nextInstance = getNextHydratableSibling(nextInstance);
14149 }
14150 }
14151
14152 popToNextHostParent(fiber);
14153 nextHydratableInstance = hydrationParentFiber ? getNextHydratableSibling(fiber.stateNode) : null;
14154 return true;
14155}
14156
14157function resetHydrationState() {
14158 if (!supportsHydration) {
14159 return;
14160 }
14161
14162 hydrationParentFiber = null;
14163 nextHydratableInstance = null;
14164 isHydrating = false;
14165}
14166
14167var ReactCurrentOwner$3 = ReactSharedInternals.ReactCurrentOwner;
14168
14169var didReceiveUpdate = false;
14170
14171var didWarnAboutBadClass = void 0;
14172var didWarnAboutContextTypeOnFunctionComponent = void 0;
14173var didWarnAboutGetDerivedStateOnFunctionComponent = void 0;
14174var didWarnAboutFunctionRefs = void 0;
14175var didWarnAboutReassigningProps = void 0;
14176
14177{
14178 didWarnAboutBadClass = {};
14179 didWarnAboutContextTypeOnFunctionComponent = {};
14180 didWarnAboutGetDerivedStateOnFunctionComponent = {};
14181 didWarnAboutFunctionRefs = {};
14182 didWarnAboutReassigningProps = false;
14183}
14184
14185function reconcileChildren(current$$1, workInProgress, nextChildren, renderExpirationTime) {
14186 if (current$$1 === null) {
14187 // If this is a fresh new component that hasn't been rendered yet, we
14188 // won't update its child set by applying minimal side-effects. Instead,
14189 // we will add them all to the child before it gets rendered. That means
14190 // we can optimize this reconciliation pass by not tracking side-effects.
14191 workInProgress.child = mountChildFibers(workInProgress, null, nextChildren, renderExpirationTime);
14192 } else {
14193 // If the current child is the same as the work in progress, it means that
14194 // we haven't yet started any work on these children. Therefore, we use
14195 // the clone algorithm to create a copy of all the current children.
14196
14197 // If we had any progressed work already, that is invalid at this point so
14198 // let's throw it out.
14199 workInProgress.child = reconcileChildFibers(workInProgress, current$$1.child, nextChildren, renderExpirationTime);
14200 }
14201}
14202
14203function forceUnmountCurrentAndReconcile(current$$1, workInProgress, nextChildren, renderExpirationTime) {
14204 // This function is fork of reconcileChildren. It's used in cases where we
14205 // want to reconcile without matching against the existing set. This has the
14206 // effect of all current children being unmounted; even if the type and key
14207 // are the same, the old child is unmounted and a new child is created.
14208 //
14209 // To do this, we're going to go through the reconcile algorithm twice. In
14210 // the first pass, we schedule a deletion for all the current children by
14211 // passing null.
14212 workInProgress.child = reconcileChildFibers(workInProgress, current$$1.child, null, renderExpirationTime);
14213 // In the second pass, we mount the new children. The trick here is that we
14214 // pass null in place of where we usually pass the current child set. This has
14215 // the effect of remounting all children regardless of whether their their
14216 // identity matches.
14217 workInProgress.child = reconcileChildFibers(workInProgress, null, nextChildren, renderExpirationTime);
14218}
14219
14220function updateForwardRef(current$$1, workInProgress, Component, nextProps, renderExpirationTime) {
14221 {
14222 if (workInProgress.type !== workInProgress.elementType) {
14223 // Lazy component props can't be validated in createElement
14224 // because they're only guaranteed to be resolved here.
14225 var innerPropTypes = Component.propTypes;
14226 if (innerPropTypes) {
14227 checkPropTypes_1(innerPropTypes, nextProps, // Resolved props
14228 'prop', getComponentName(Component), getCurrentFiberStackInDev);
14229 }
14230 }
14231 }
14232
14233 var render = Component.render;
14234 var ref = workInProgress.ref;
14235
14236 // The rest is a fork of updateFunctionComponent
14237 var nextChildren = void 0;
14238 prepareToReadContext(workInProgress, renderExpirationTime);
14239 {
14240 ReactCurrentOwner$3.current = workInProgress;
14241 setCurrentPhase('render');
14242 nextChildren = renderWithHooks(current$$1, workInProgress, render, nextProps, ref, renderExpirationTime);
14243 if (debugRenderPhaseSideEffects || debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) {
14244 // Only double-render components with Hooks
14245 if (workInProgress.memoizedState !== null) {
14246 nextChildren = renderWithHooks(current$$1, workInProgress, render, nextProps, ref, renderExpirationTime);
14247 }
14248 }
14249 setCurrentPhase(null);
14250 }
14251
14252 if (current$$1 !== null && !didReceiveUpdate) {
14253 bailoutHooks(current$$1, workInProgress, renderExpirationTime);
14254 return bailoutOnAlreadyFinishedWork(current$$1, workInProgress, renderExpirationTime);
14255 }
14256
14257 // React DevTools reads this flag.
14258 workInProgress.effectTag |= PerformedWork;
14259 reconcileChildren(current$$1, workInProgress, nextChildren, renderExpirationTime);
14260 return workInProgress.child;
14261}
14262
14263function updateMemoComponent(current$$1, workInProgress, Component, nextProps, updateExpirationTime, renderExpirationTime) {
14264 if (current$$1 === null) {
14265 var type = Component.type;
14266 if (isSimpleFunctionComponent(type) && Component.compare === null &&
14267 // SimpleMemoComponent codepath doesn't resolve outer props either.
14268 Component.defaultProps === undefined) {
14269 // If this is a plain function component without default props,
14270 // and with only the default shallow comparison, we upgrade it
14271 // to a SimpleMemoComponent to allow fast path updates.
14272 workInProgress.tag = SimpleMemoComponent;
14273 workInProgress.type = type;
14274 {
14275 validateFunctionComponentInDev(workInProgress, type);
14276 }
14277 return updateSimpleMemoComponent(current$$1, workInProgress, type, nextProps, updateExpirationTime, renderExpirationTime);
14278 }
14279 {
14280 var innerPropTypes = type.propTypes;
14281 if (innerPropTypes) {
14282 // Inner memo component props aren't currently validated in createElement.
14283 // We could move it there, but we'd still need this for lazy code path.
14284 checkPropTypes_1(innerPropTypes, nextProps, // Resolved props
14285 'prop', getComponentName(type), getCurrentFiberStackInDev);
14286 }
14287 }
14288 var child = createFiberFromTypeAndProps(Component.type, null, nextProps, null, workInProgress.mode, renderExpirationTime);
14289 child.ref = workInProgress.ref;
14290 child.return = workInProgress;
14291 workInProgress.child = child;
14292 return child;
14293 }
14294 {
14295 var _type = Component.type;
14296 var _innerPropTypes = _type.propTypes;
14297 if (_innerPropTypes) {
14298 // Inner memo component props aren't currently validated in createElement.
14299 // We could move it there, but we'd still need this for lazy code path.
14300 checkPropTypes_1(_innerPropTypes, nextProps, // Resolved props
14301 'prop', getComponentName(_type), getCurrentFiberStackInDev);
14302 }
14303 }
14304 var currentChild = current$$1.child; // This is always exactly one child
14305 if (updateExpirationTime < renderExpirationTime) {
14306 // This will be the props with resolved defaultProps,
14307 // unlike current.memoizedProps which will be the unresolved ones.
14308 var prevProps = currentChild.memoizedProps;
14309 // Default to shallow comparison
14310 var compare = Component.compare;
14311 compare = compare !== null ? compare : shallowEqual;
14312 if (compare(prevProps, nextProps) && current$$1.ref === workInProgress.ref) {
14313 return bailoutOnAlreadyFinishedWork(current$$1, workInProgress, renderExpirationTime);
14314 }
14315 }
14316 // React DevTools reads this flag.
14317 workInProgress.effectTag |= PerformedWork;
14318 var newChild = createWorkInProgress(currentChild, nextProps, renderExpirationTime);
14319 newChild.ref = workInProgress.ref;
14320 newChild.return = workInProgress;
14321 workInProgress.child = newChild;
14322 return newChild;
14323}
14324
14325function updateSimpleMemoComponent(current$$1, workInProgress, Component, nextProps, updateExpirationTime, renderExpirationTime) {
14326 {
14327 if (workInProgress.type !== workInProgress.elementType) {
14328 // Lazy component props can't be validated in createElement
14329 // because they're only guaranteed to be resolved here.
14330 var outerMemoType = workInProgress.elementType;
14331 if (outerMemoType.$$typeof === REACT_LAZY_TYPE) {
14332 // We warn when you define propTypes on lazy()
14333 // so let's just skip over it to find memo() outer wrapper.
14334 // Inner props for memo are validated later.
14335 outerMemoType = refineResolvedLazyComponent(outerMemoType);
14336 }
14337 var outerPropTypes = outerMemoType && outerMemoType.propTypes;
14338 if (outerPropTypes) {
14339 checkPropTypes_1(outerPropTypes, nextProps, // Resolved (SimpleMemoComponent has no defaultProps)
14340 'prop', getComponentName(outerMemoType), getCurrentFiberStackInDev);
14341 }
14342 // Inner propTypes will be validated in the function component path.
14343 }
14344 }
14345 if (current$$1 !== null) {
14346 var prevProps = current$$1.memoizedProps;
14347 if (shallowEqual(prevProps, nextProps) && current$$1.ref === workInProgress.ref) {
14348 didReceiveUpdate = false;
14349 if (updateExpirationTime < renderExpirationTime) {
14350 return bailoutOnAlreadyFinishedWork(current$$1, workInProgress, renderExpirationTime);
14351 }
14352 }
14353 }
14354 return updateFunctionComponent(current$$1, workInProgress, Component, nextProps, renderExpirationTime);
14355}
14356
14357function updateFragment(current$$1, workInProgress, renderExpirationTime) {
14358 var nextChildren = workInProgress.pendingProps;
14359 reconcileChildren(current$$1, workInProgress, nextChildren, renderExpirationTime);
14360 return workInProgress.child;
14361}
14362
14363function updateMode(current$$1, workInProgress, renderExpirationTime) {
14364 var nextChildren = workInProgress.pendingProps.children;
14365 reconcileChildren(current$$1, workInProgress, nextChildren, renderExpirationTime);
14366 return workInProgress.child;
14367}
14368
14369function updateProfiler(current$$1, workInProgress, renderExpirationTime) {
14370 if (enableProfilerTimer) {
14371 workInProgress.effectTag |= Update;
14372 }
14373 var nextProps = workInProgress.pendingProps;
14374 var nextChildren = nextProps.children;
14375 reconcileChildren(current$$1, workInProgress, nextChildren, renderExpirationTime);
14376 return workInProgress.child;
14377}
14378
14379function markRef(current$$1, workInProgress) {
14380 var ref = workInProgress.ref;
14381 if (current$$1 === null && ref !== null || current$$1 !== null && current$$1.ref !== ref) {
14382 // Schedule a Ref effect
14383 workInProgress.effectTag |= Ref;
14384 }
14385}
14386
14387function updateFunctionComponent(current$$1, workInProgress, Component, nextProps, renderExpirationTime) {
14388 {
14389 if (workInProgress.type !== workInProgress.elementType) {
14390 // Lazy component props can't be validated in createElement
14391 // because they're only guaranteed to be resolved here.
14392 var innerPropTypes = Component.propTypes;
14393 if (innerPropTypes) {
14394 checkPropTypes_1(innerPropTypes, nextProps, // Resolved props
14395 'prop', getComponentName(Component), getCurrentFiberStackInDev);
14396 }
14397 }
14398 }
14399
14400 var unmaskedContext = getUnmaskedContext(workInProgress, Component, true);
14401 var context = getMaskedContext(workInProgress, unmaskedContext);
14402
14403 var nextChildren = void 0;
14404 prepareToReadContext(workInProgress, renderExpirationTime);
14405 {
14406 ReactCurrentOwner$3.current = workInProgress;
14407 setCurrentPhase('render');
14408 nextChildren = renderWithHooks(current$$1, workInProgress, Component, nextProps, context, renderExpirationTime);
14409 if (debugRenderPhaseSideEffects || debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) {
14410 // Only double-render components with Hooks
14411 if (workInProgress.memoizedState !== null) {
14412 nextChildren = renderWithHooks(current$$1, workInProgress, Component, nextProps, context, renderExpirationTime);
14413 }
14414 }
14415 setCurrentPhase(null);
14416 }
14417
14418 if (current$$1 !== null && !didReceiveUpdate) {
14419 bailoutHooks(current$$1, workInProgress, renderExpirationTime);
14420 return bailoutOnAlreadyFinishedWork(current$$1, workInProgress, renderExpirationTime);
14421 }
14422
14423 // React DevTools reads this flag.
14424 workInProgress.effectTag |= PerformedWork;
14425 reconcileChildren(current$$1, workInProgress, nextChildren, renderExpirationTime);
14426 return workInProgress.child;
14427}
14428
14429function updateClassComponent(current$$1, workInProgress, Component, nextProps, renderExpirationTime) {
14430 {
14431 if (workInProgress.type !== workInProgress.elementType) {
14432 // Lazy component props can't be validated in createElement
14433 // because they're only guaranteed to be resolved here.
14434 var innerPropTypes = Component.propTypes;
14435 if (innerPropTypes) {
14436 checkPropTypes_1(innerPropTypes, nextProps, // Resolved props
14437 'prop', getComponentName(Component), getCurrentFiberStackInDev);
14438 }
14439 }
14440 }
14441
14442 // Push context providers early to prevent context stack mismatches.
14443 // During mounting we don't know the child context yet as the instance doesn't exist.
14444 // We will invalidate the child context in finishClassComponent() right after rendering.
14445 var hasContext = void 0;
14446 if (isContextProvider(Component)) {
14447 hasContext = true;
14448 pushContextProvider(workInProgress);
14449 } else {
14450 hasContext = false;
14451 }
14452 prepareToReadContext(workInProgress, renderExpirationTime);
14453
14454 var instance = workInProgress.stateNode;
14455 var shouldUpdate = void 0;
14456 if (instance === null) {
14457 if (current$$1 !== null) {
14458 // An class component without an instance only mounts if it suspended
14459 // inside a non- concurrent tree, in an inconsistent state. We want to
14460 // tree it like a new mount, even though an empty version of it already
14461 // committed. Disconnect the alternate pointers.
14462 current$$1.alternate = null;
14463 workInProgress.alternate = null;
14464 // Since this is conceptually a new fiber, schedule a Placement effect
14465 workInProgress.effectTag |= Placement;
14466 }
14467 // In the initial pass we might need to construct the instance.
14468 constructClassInstance(workInProgress, Component, nextProps, renderExpirationTime);
14469 mountClassInstance(workInProgress, Component, nextProps, renderExpirationTime);
14470 shouldUpdate = true;
14471 } else if (current$$1 === null) {
14472 // In a resume, we'll already have an instance we can reuse.
14473 shouldUpdate = resumeMountClassInstance(workInProgress, Component, nextProps, renderExpirationTime);
14474 } else {
14475 shouldUpdate = updateClassInstance(current$$1, workInProgress, Component, nextProps, renderExpirationTime);
14476 }
14477 var nextUnitOfWork = finishClassComponent(current$$1, workInProgress, Component, shouldUpdate, hasContext, renderExpirationTime);
14478 {
14479 var inst = workInProgress.stateNode;
14480 if (inst.props !== nextProps) {
14481 !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;
14482 didWarnAboutReassigningProps = true;
14483 }
14484 }
14485 return nextUnitOfWork;
14486}
14487
14488function finishClassComponent(current$$1, workInProgress, Component, shouldUpdate, hasContext, renderExpirationTime) {
14489 // Refs should update even if shouldComponentUpdate returns false
14490 markRef(current$$1, workInProgress);
14491
14492 var didCaptureError = (workInProgress.effectTag & DidCapture) !== NoEffect;
14493
14494 if (!shouldUpdate && !didCaptureError) {
14495 // Context providers should defer to sCU for rendering
14496 if (hasContext) {
14497 invalidateContextProvider(workInProgress, Component, false);
14498 }
14499
14500 return bailoutOnAlreadyFinishedWork(current$$1, workInProgress, renderExpirationTime);
14501 }
14502
14503 var instance = workInProgress.stateNode;
14504
14505 // Rerender
14506 ReactCurrentOwner$3.current = workInProgress;
14507 var nextChildren = void 0;
14508 if (didCaptureError && typeof Component.getDerivedStateFromError !== 'function') {
14509 // If we captured an error, but getDerivedStateFrom catch is not defined,
14510 // unmount all the children. componentDidCatch will schedule an update to
14511 // re-render a fallback. This is temporary until we migrate everyone to
14512 // the new API.
14513 // TODO: Warn in a future release.
14514 nextChildren = null;
14515
14516 if (enableProfilerTimer) {
14517 stopProfilerTimerIfRunning(workInProgress);
14518 }
14519 } else {
14520 {
14521 setCurrentPhase('render');
14522 nextChildren = instance.render();
14523 if (debugRenderPhaseSideEffects || debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) {
14524 instance.render();
14525 }
14526 setCurrentPhase(null);
14527 }
14528 }
14529
14530 // React DevTools reads this flag.
14531 workInProgress.effectTag |= PerformedWork;
14532 if (current$$1 !== null && didCaptureError) {
14533 // If we're recovering from an error, reconcile without reusing any of
14534 // the existing children. Conceptually, the normal children and the children
14535 // that are shown on error are two different sets, so we shouldn't reuse
14536 // normal children even if their identities match.
14537 forceUnmountCurrentAndReconcile(current$$1, workInProgress, nextChildren, renderExpirationTime);
14538 } else {
14539 reconcileChildren(current$$1, workInProgress, nextChildren, renderExpirationTime);
14540 }
14541
14542 // Memoize state using the values we just used to render.
14543 // TODO: Restructure so we never read values from the instance.
14544 workInProgress.memoizedState = instance.state;
14545
14546 // The context might have changed so we need to recalculate it.
14547 if (hasContext) {
14548 invalidateContextProvider(workInProgress, Component, true);
14549 }
14550
14551 return workInProgress.child;
14552}
14553
14554function pushHostRootContext(workInProgress) {
14555 var root = workInProgress.stateNode;
14556 if (root.pendingContext) {
14557 pushTopLevelContextObject(workInProgress, root.pendingContext, root.pendingContext !== root.context);
14558 } else if (root.context) {
14559 // Should always be set
14560 pushTopLevelContextObject(workInProgress, root.context, false);
14561 }
14562 pushHostContainer(workInProgress, root.containerInfo);
14563}
14564
14565function updateHostRoot(current$$1, workInProgress, renderExpirationTime) {
14566 pushHostRootContext(workInProgress);
14567 var updateQueue = workInProgress.updateQueue;
14568 !(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;
14569 var nextProps = workInProgress.pendingProps;
14570 var prevState = workInProgress.memoizedState;
14571 var prevChildren = prevState !== null ? prevState.element : null;
14572 processUpdateQueue(workInProgress, updateQueue, nextProps, null, renderExpirationTime);
14573 var nextState = workInProgress.memoizedState;
14574 // Caution: React DevTools currently depends on this property
14575 // being called "element".
14576 var nextChildren = nextState.element;
14577 if (nextChildren === prevChildren) {
14578 // If the state is the same as before, that's a bailout because we had
14579 // no work that expires at this time.
14580 resetHydrationState();
14581 return bailoutOnAlreadyFinishedWork(current$$1, workInProgress, renderExpirationTime);
14582 }
14583 var root = workInProgress.stateNode;
14584 if ((current$$1 === null || current$$1.child === null) && root.hydrate && enterHydrationState(workInProgress)) {
14585 // If we don't have any current children this might be the first pass.
14586 // We always try to hydrate. If this isn't a hydration pass there won't
14587 // be any children to hydrate which is effectively the same thing as
14588 // not hydrating.
14589
14590 // This is a bit of a hack. We track the host root as a placement to
14591 // know that we're currently in a mounting state. That way isMounted
14592 // works as expected. We must reset this before committing.
14593 // TODO: Delete this when we delete isMounted and findDOMNode.
14594 workInProgress.effectTag |= Placement;
14595
14596 // Ensure that children mount into this root without tracking
14597 // side-effects. This ensures that we don't store Placement effects on
14598 // nodes that will be hydrated.
14599 workInProgress.child = mountChildFibers(workInProgress, null, nextChildren, renderExpirationTime);
14600 } else {
14601 // Otherwise reset hydration state in case we aborted and resumed another
14602 // root.
14603 reconcileChildren(current$$1, workInProgress, nextChildren, renderExpirationTime);
14604 resetHydrationState();
14605 }
14606 return workInProgress.child;
14607}
14608
14609function updateHostComponent(current$$1, workInProgress, renderExpirationTime) {
14610 pushHostContext(workInProgress);
14611
14612 if (current$$1 === null) {
14613 tryToClaimNextHydratableInstance(workInProgress);
14614 }
14615
14616 var type = workInProgress.type;
14617 var nextProps = workInProgress.pendingProps;
14618 var prevProps = current$$1 !== null ? current$$1.memoizedProps : null;
14619
14620 var nextChildren = nextProps.children;
14621 var isDirectTextChild = shouldSetTextContent(type, nextProps);
14622
14623 if (isDirectTextChild) {
14624 // We special case a direct text child of a host node. This is a common
14625 // case. We won't handle it as a reified child. We will instead handle
14626 // this in the host environment that also have access to this prop. That
14627 // avoids allocating another HostText fiber and traversing it.
14628 nextChildren = null;
14629 } else if (prevProps !== null && shouldSetTextContent(type, prevProps)) {
14630 // If we're switching from a direct text child to a normal child, or to
14631 // empty, we need to schedule the text content to be reset.
14632 workInProgress.effectTag |= ContentReset;
14633 }
14634
14635 markRef(current$$1, workInProgress);
14636
14637 // Check the host config to see if the children are offscreen/hidden.
14638 if (renderExpirationTime !== Never && workInProgress.mode & ConcurrentMode && shouldDeprioritizeSubtree(type, nextProps)) {
14639 // Schedule this fiber to re-render at offscreen priority. Then bailout.
14640 workInProgress.expirationTime = workInProgress.childExpirationTime = Never;
14641 return null;
14642 }
14643
14644 reconcileChildren(current$$1, workInProgress, nextChildren, renderExpirationTime);
14645 return workInProgress.child;
14646}
14647
14648function updateHostText(current$$1, workInProgress) {
14649 if (current$$1 === null) {
14650 tryToClaimNextHydratableInstance(workInProgress);
14651 }
14652 // Nothing to do here. This is terminal. We'll do the completion step
14653 // immediately after.
14654 return null;
14655}
14656
14657function mountLazyComponent(_current, workInProgress, elementType, updateExpirationTime, renderExpirationTime) {
14658 if (_current !== null) {
14659 // An lazy component only mounts if it suspended inside a non-
14660 // concurrent tree, in an inconsistent state. We want to treat it like
14661 // a new mount, even though an empty version of it already committed.
14662 // Disconnect the alternate pointers.
14663 _current.alternate = null;
14664 workInProgress.alternate = null;
14665 // Since this is conceptually a new fiber, schedule a Placement effect
14666 workInProgress.effectTag |= Placement;
14667 }
14668
14669 var props = workInProgress.pendingProps;
14670 // We can't start a User Timing measurement with correct label yet.
14671 // Cancel and resume right after we know the tag.
14672 cancelWorkTimer(workInProgress);
14673 var Component = readLazyComponentType(elementType);
14674 // Store the unwrapped component in the type.
14675 workInProgress.type = Component;
14676 var resolvedTag = workInProgress.tag = resolveLazyComponentTag(Component);
14677 startWorkTimer(workInProgress);
14678 var resolvedProps = resolveDefaultProps(Component, props);
14679 var child = void 0;
14680 switch (resolvedTag) {
14681 case FunctionComponent:
14682 {
14683 {
14684 validateFunctionComponentInDev(workInProgress, Component);
14685 }
14686 child = updateFunctionComponent(null, workInProgress, Component, resolvedProps, renderExpirationTime);
14687 break;
14688 }
14689 case ClassComponent:
14690 {
14691 child = updateClassComponent(null, workInProgress, Component, resolvedProps, renderExpirationTime);
14692 break;
14693 }
14694 case ForwardRef:
14695 {
14696 child = updateForwardRef(null, workInProgress, Component, resolvedProps, renderExpirationTime);
14697 break;
14698 }
14699 case MemoComponent:
14700 {
14701 {
14702 if (workInProgress.type !== workInProgress.elementType) {
14703 var outerPropTypes = Component.propTypes;
14704 if (outerPropTypes) {
14705 checkPropTypes_1(outerPropTypes, resolvedProps, // Resolved for outer only
14706 'prop', getComponentName(Component), getCurrentFiberStackInDev);
14707 }
14708 }
14709 }
14710 child = updateMemoComponent(null, workInProgress, Component, resolveDefaultProps(Component.type, resolvedProps), // The inner type can have defaults too
14711 updateExpirationTime, renderExpirationTime);
14712 break;
14713 }
14714 default:
14715 {
14716 var hint = '';
14717 {
14718 if (Component !== null && typeof Component === 'object' && Component.$$typeof === REACT_LAZY_TYPE) {
14719 hint = ' Did you wrap a component in React.lazy() more than once?';
14720 }
14721 }
14722 // This message intentionally doesn't mention ForwardRef or MemoComponent
14723 // because the fact that it's a separate type of work is an
14724 // implementation detail.
14725 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);
14726 }
14727 }
14728 return child;
14729}
14730
14731function mountIncompleteClassComponent(_current, workInProgress, Component, nextProps, renderExpirationTime) {
14732 if (_current !== null) {
14733 // An incomplete component only mounts if it suspended inside a non-
14734 // concurrent tree, in an inconsistent state. We want to treat it like
14735 // a new mount, even though an empty version of it already committed.
14736 // Disconnect the alternate pointers.
14737 _current.alternate = null;
14738 workInProgress.alternate = null;
14739 // Since this is conceptually a new fiber, schedule a Placement effect
14740 workInProgress.effectTag |= Placement;
14741 }
14742
14743 // Promote the fiber to a class and try rendering again.
14744 workInProgress.tag = ClassComponent;
14745
14746 // The rest of this function is a fork of `updateClassComponent`
14747
14748 // Push context providers early to prevent context stack mismatches.
14749 // During mounting we don't know the child context yet as the instance doesn't exist.
14750 // We will invalidate the child context in finishClassComponent() right after rendering.
14751 var hasContext = void 0;
14752 if (isContextProvider(Component)) {
14753 hasContext = true;
14754 pushContextProvider(workInProgress);
14755 } else {
14756 hasContext = false;
14757 }
14758 prepareToReadContext(workInProgress, renderExpirationTime);
14759
14760 constructClassInstance(workInProgress, Component, nextProps, renderExpirationTime);
14761 mountClassInstance(workInProgress, Component, nextProps, renderExpirationTime);
14762
14763 return finishClassComponent(null, workInProgress, Component, true, hasContext, renderExpirationTime);
14764}
14765
14766function mountIndeterminateComponent(_current, workInProgress, Component, renderExpirationTime) {
14767 if (_current !== null) {
14768 // An indeterminate component only mounts if it suspended inside a non-
14769 // concurrent tree, in an inconsistent state. We want to treat it like
14770 // a new mount, even though an empty version of it already committed.
14771 // Disconnect the alternate pointers.
14772 _current.alternate = null;
14773 workInProgress.alternate = null;
14774 // Since this is conceptually a new fiber, schedule a Placement effect
14775 workInProgress.effectTag |= Placement;
14776 }
14777
14778 var props = workInProgress.pendingProps;
14779 var unmaskedContext = getUnmaskedContext(workInProgress, Component, false);
14780 var context = getMaskedContext(workInProgress, unmaskedContext);
14781
14782 prepareToReadContext(workInProgress, renderExpirationTime);
14783
14784 var value = void 0;
14785
14786 {
14787 if (Component.prototype && typeof Component.prototype.render === 'function') {
14788 var componentName = getComponentName(Component) || 'Unknown';
14789
14790 if (!didWarnAboutBadClass[componentName]) {
14791 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);
14792 didWarnAboutBadClass[componentName] = true;
14793 }
14794 }
14795
14796 if (workInProgress.mode & StrictMode) {
14797 ReactStrictModeWarnings.recordLegacyContextWarning(workInProgress, null);
14798 }
14799
14800 ReactCurrentOwner$3.current = workInProgress;
14801 value = renderWithHooks(null, workInProgress, Component, props, context, renderExpirationTime);
14802 }
14803 // React DevTools reads this flag.
14804 workInProgress.effectTag |= PerformedWork;
14805
14806 if (typeof value === 'object' && value !== null && typeof value.render === 'function' && value.$$typeof === undefined) {
14807 // Proceed under the assumption that this is a class instance
14808 workInProgress.tag = ClassComponent;
14809
14810 // Throw out any hooks that were used.
14811 resetHooks();
14812
14813 // Push context providers early to prevent context stack mismatches.
14814 // During mounting we don't know the child context yet as the instance doesn't exist.
14815 // We will invalidate the child context in finishClassComponent() right after rendering.
14816 var hasContext = false;
14817 if (isContextProvider(Component)) {
14818 hasContext = true;
14819 pushContextProvider(workInProgress);
14820 } else {
14821 hasContext = false;
14822 }
14823
14824 workInProgress.memoizedState = value.state !== null && value.state !== undefined ? value.state : null;
14825
14826 var getDerivedStateFromProps = Component.getDerivedStateFromProps;
14827 if (typeof getDerivedStateFromProps === 'function') {
14828 applyDerivedStateFromProps(workInProgress, Component, getDerivedStateFromProps, props);
14829 }
14830
14831 adoptClassInstance(workInProgress, value);
14832 mountClassInstance(workInProgress, Component, props, renderExpirationTime);
14833 return finishClassComponent(null, workInProgress, Component, true, hasContext, renderExpirationTime);
14834 } else {
14835 // Proceed under the assumption that this is a function component
14836 workInProgress.tag = FunctionComponent;
14837 {
14838 if (debugRenderPhaseSideEffects || debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) {
14839 // Only double-render components with Hooks
14840 if (workInProgress.memoizedState !== null) {
14841 value = renderWithHooks(null, workInProgress, Component, props, context, renderExpirationTime);
14842 }
14843 }
14844 }
14845 reconcileChildren(null, workInProgress, value, renderExpirationTime);
14846 {
14847 validateFunctionComponentInDev(workInProgress, Component);
14848 }
14849 return workInProgress.child;
14850 }
14851}
14852
14853function validateFunctionComponentInDev(workInProgress, Component) {
14854 if (Component) {
14855 !!Component.childContextTypes ? warningWithoutStack$1(false, '%s(...): childContextTypes cannot be defined on a function component.', Component.displayName || Component.name || 'Component') : void 0;
14856 }
14857 if (workInProgress.ref !== null) {
14858 var info = '';
14859 var ownerName = getCurrentFiberOwnerNameInDevOrNull();
14860 if (ownerName) {
14861 info += '\n\nCheck the render method of `' + ownerName + '`.';
14862 }
14863
14864 var warningKey = ownerName || workInProgress._debugID || '';
14865 var debugSource = workInProgress._debugSource;
14866 if (debugSource) {
14867 warningKey = debugSource.fileName + ':' + debugSource.lineNumber;
14868 }
14869 if (!didWarnAboutFunctionRefs[warningKey]) {
14870 didWarnAboutFunctionRefs[warningKey] = true;
14871 warning$1(false, 'Function components cannot be given refs. ' + 'Attempts to access this ref will fail. ' + 'Did you mean to use React.forwardRef()?%s', info);
14872 }
14873 }
14874
14875 if (typeof Component.getDerivedStateFromProps === 'function') {
14876 var componentName = getComponentName(Component) || 'Unknown';
14877
14878 if (!didWarnAboutGetDerivedStateOnFunctionComponent[componentName]) {
14879 warningWithoutStack$1(false, '%s: Function components do not support getDerivedStateFromProps.', componentName);
14880 didWarnAboutGetDerivedStateOnFunctionComponent[componentName] = true;
14881 }
14882 }
14883
14884 if (typeof Component.contextType === 'object' && Component.contextType !== null) {
14885 var _componentName = getComponentName(Component) || 'Unknown';
14886
14887 if (!didWarnAboutContextTypeOnFunctionComponent[_componentName]) {
14888 warningWithoutStack$1(false, '%s: Function components do not support contextType.', _componentName);
14889 didWarnAboutContextTypeOnFunctionComponent[_componentName] = true;
14890 }
14891 }
14892}
14893
14894function updateSuspenseComponent(current$$1, workInProgress, renderExpirationTime) {
14895 var mode = workInProgress.mode;
14896 var nextProps = workInProgress.pendingProps;
14897
14898 // We should attempt to render the primary children unless this boundary
14899 // already suspended during this render (`alreadyCaptured` is true).
14900 var nextState = workInProgress.memoizedState;
14901
14902 var nextDidTimeout = void 0;
14903 if ((workInProgress.effectTag & DidCapture) === NoEffect) {
14904 // This is the first attempt.
14905 nextState = null;
14906 nextDidTimeout = false;
14907 } else {
14908 // Something in this boundary's subtree already suspended. Switch to
14909 // rendering the fallback children.
14910 nextState = {
14911 timedOutAt: nextState !== null ? nextState.timedOutAt : NoWork
14912 };
14913 nextDidTimeout = true;
14914 workInProgress.effectTag &= ~DidCapture;
14915 }
14916
14917 // This next part is a bit confusing. If the children timeout, we switch to
14918 // showing the fallback children in place of the "primary" children.
14919 // However, we don't want to delete the primary children because then their
14920 // state will be lost (both the React state and the host state, e.g.
14921 // uncontrolled form inputs). Instead we keep them mounted and hide them.
14922 // Both the fallback children AND the primary children are rendered at the
14923 // same time. Once the primary children are un-suspended, we can delete
14924 // the fallback children — don't need to preserve their state.
14925 //
14926 // The two sets of children are siblings in the host environment, but
14927 // semantically, for purposes of reconciliation, they are two separate sets.
14928 // So we store them using two fragment fibers.
14929 //
14930 // However, we want to avoid allocating extra fibers for every placeholder.
14931 // They're only necessary when the children time out, because that's the
14932 // only time when both sets are mounted.
14933 //
14934 // So, the extra fragment fibers are only used if the children time out.
14935 // Otherwise, we render the primary children directly. This requires some
14936 // custom reconciliation logic to preserve the state of the primary
14937 // children. It's essentially a very basic form of re-parenting.
14938
14939 // `child` points to the child fiber. In the normal case, this is the first
14940 // fiber of the primary children set. In the timed-out case, it's a
14941 // a fragment fiber containing the primary children.
14942 var child = void 0;
14943 // `next` points to the next fiber React should render. In the normal case,
14944 // it's the same as `child`: the first fiber of the primary children set.
14945 // In the timed-out case, it's a fragment fiber containing the *fallback*
14946 // children -- we skip over the primary children entirely.
14947 var next = void 0;
14948 if (current$$1 === null) {
14949 // This is the initial mount. This branch is pretty simple because there's
14950 // no previous state that needs to be preserved.
14951 if (nextDidTimeout) {
14952 // Mount separate fragments for primary and fallback children.
14953 var nextFallbackChildren = nextProps.fallback;
14954 var primaryChildFragment = createFiberFromFragment(null, mode, NoWork, null);
14955
14956 if ((workInProgress.mode & ConcurrentMode) === NoContext) {
14957 // Outside of concurrent mode, we commit the effects from the
14958 var progressedState = workInProgress.memoizedState;
14959 var progressedPrimaryChild = progressedState !== null ? workInProgress.child.child : workInProgress.child;
14960 primaryChildFragment.child = progressedPrimaryChild;
14961 }
14962
14963 var fallbackChildFragment = createFiberFromFragment(nextFallbackChildren, mode, renderExpirationTime, null);
14964 primaryChildFragment.sibling = fallbackChildFragment;
14965 child = primaryChildFragment;
14966 // Skip the primary children, and continue working on the
14967 // fallback children.
14968 next = fallbackChildFragment;
14969 child.return = next.return = workInProgress;
14970 } else {
14971 // Mount the primary children without an intermediate fragment fiber.
14972 var nextPrimaryChildren = nextProps.children;
14973 child = next = mountChildFibers(workInProgress, null, nextPrimaryChildren, renderExpirationTime);
14974 }
14975 } else {
14976 // This is an update. This branch is more complicated because we need to
14977 // ensure the state of the primary children is preserved.
14978 var prevState = current$$1.memoizedState;
14979 var prevDidTimeout = prevState !== null;
14980 if (prevDidTimeout) {
14981 // The current tree already timed out. That means each child set is
14982 var currentPrimaryChildFragment = current$$1.child;
14983 var currentFallbackChildFragment = currentPrimaryChildFragment.sibling;
14984 if (nextDidTimeout) {
14985 // Still timed out. Reuse the current primary children by cloning
14986 // its fragment. We're going to skip over these entirely.
14987 var _nextFallbackChildren = nextProps.fallback;
14988 var _primaryChildFragment = createWorkInProgress(currentPrimaryChildFragment, currentPrimaryChildFragment.pendingProps, NoWork);
14989
14990 if ((workInProgress.mode & ConcurrentMode) === NoContext) {
14991 // Outside of concurrent mode, we commit the effects from the
14992 var _progressedState = workInProgress.memoizedState;
14993 var _progressedPrimaryChild = _progressedState !== null ? workInProgress.child.child : workInProgress.child;
14994 if (_progressedPrimaryChild !== currentPrimaryChildFragment.child) {
14995 _primaryChildFragment.child = _progressedPrimaryChild;
14996 }
14997 }
14998
14999 // Because primaryChildFragment is a new fiber that we're inserting as the
15000 // parent of a new tree, we need to set its treeBaseDuration.
15001 if (enableProfilerTimer && workInProgress.mode & ProfileMode) {
15002 // treeBaseDuration is the sum of all the child tree base durations.
15003 var treeBaseDuration = 0;
15004 var hiddenChild = _primaryChildFragment.child;
15005 while (hiddenChild !== null) {
15006 treeBaseDuration += hiddenChild.treeBaseDuration;
15007 hiddenChild = hiddenChild.sibling;
15008 }
15009 _primaryChildFragment.treeBaseDuration = treeBaseDuration;
15010 }
15011
15012 // Clone the fallback child fragment, too. These we'll continue
15013 // working on.
15014 var _fallbackChildFragment = _primaryChildFragment.sibling = createWorkInProgress(currentFallbackChildFragment, _nextFallbackChildren, currentFallbackChildFragment.expirationTime);
15015 child = _primaryChildFragment;
15016 _primaryChildFragment.childExpirationTime = NoWork;
15017 // Skip the primary children, and continue working on the
15018 // fallback children.
15019 next = _fallbackChildFragment;
15020 child.return = next.return = workInProgress;
15021 } else {
15022 // No longer suspended. Switch back to showing the primary children,
15023 // and remove the intermediate fragment fiber.
15024 var _nextPrimaryChildren = nextProps.children;
15025 var currentPrimaryChild = currentPrimaryChildFragment.child;
15026 var primaryChild = reconcileChildFibers(workInProgress, currentPrimaryChild, _nextPrimaryChildren, renderExpirationTime);
15027
15028 // If this render doesn't suspend, we need to delete the fallback
15029 // children. Wait until the complete phase, after we've confirmed the
15030 // fallback is no longer needed.
15031 // TODO: Would it be better to store the fallback fragment on
15032 // the stateNode?
15033
15034 // Continue rendering the children, like we normally do.
15035 child = next = primaryChild;
15036 }
15037 } else {
15038 // The current tree has not already timed out. That means the primary
15039 // children are not wrapped in a fragment fiber.
15040 var _currentPrimaryChild = current$$1.child;
15041 if (nextDidTimeout) {
15042 // Timed out. Wrap the children in a fragment fiber to keep them
15043 // separate from the fallback children.
15044 var _nextFallbackChildren2 = nextProps.fallback;
15045 var _primaryChildFragment2 = createFiberFromFragment(
15046 // It shouldn't matter what the pending props are because we aren't
15047 // going to render this fragment.
15048 null, mode, NoWork, null);
15049 _primaryChildFragment2.child = _currentPrimaryChild;
15050
15051 // Even though we're creating a new fiber, there are no new children,
15052 // because we're reusing an already mounted tree. So we don't need to
15053 // schedule a placement.
15054 // primaryChildFragment.effectTag |= Placement;
15055
15056 if ((workInProgress.mode & ConcurrentMode) === NoContext) {
15057 // Outside of concurrent mode, we commit the effects from the
15058 var _progressedState2 = workInProgress.memoizedState;
15059 var _progressedPrimaryChild2 = _progressedState2 !== null ? workInProgress.child.child : workInProgress.child;
15060 _primaryChildFragment2.child = _progressedPrimaryChild2;
15061 }
15062
15063 // Because primaryChildFragment is a new fiber that we're inserting as the
15064 // parent of a new tree, we need to set its treeBaseDuration.
15065 if (enableProfilerTimer && workInProgress.mode & ProfileMode) {
15066 // treeBaseDuration is the sum of all the child tree base durations.
15067 var _treeBaseDuration = 0;
15068 var _hiddenChild = _primaryChildFragment2.child;
15069 while (_hiddenChild !== null) {
15070 _treeBaseDuration += _hiddenChild.treeBaseDuration;
15071 _hiddenChild = _hiddenChild.sibling;
15072 }
15073 _primaryChildFragment2.treeBaseDuration = _treeBaseDuration;
15074 }
15075
15076 // Create a fragment from the fallback children, too.
15077 var _fallbackChildFragment2 = _primaryChildFragment2.sibling = createFiberFromFragment(_nextFallbackChildren2, mode, renderExpirationTime, null);
15078 _fallbackChildFragment2.effectTag |= Placement;
15079 child = _primaryChildFragment2;
15080 _primaryChildFragment2.childExpirationTime = NoWork;
15081 // Skip the primary children, and continue working on the
15082 // fallback children.
15083 next = _fallbackChildFragment2;
15084 child.return = next.return = workInProgress;
15085 } else {
15086 // Still haven't timed out. Continue rendering the children, like we
15087 // normally do.
15088 var _nextPrimaryChildren2 = nextProps.children;
15089 next = child = reconcileChildFibers(workInProgress, _currentPrimaryChild, _nextPrimaryChildren2, renderExpirationTime);
15090 }
15091 }
15092 workInProgress.stateNode = current$$1.stateNode;
15093 }
15094
15095 workInProgress.memoizedState = nextState;
15096 workInProgress.child = child;
15097 return next;
15098}
15099
15100function updatePortalComponent(current$$1, workInProgress, renderExpirationTime) {
15101 pushHostContainer(workInProgress, workInProgress.stateNode.containerInfo);
15102 var nextChildren = workInProgress.pendingProps;
15103 if (current$$1 === null) {
15104 // Portals are special because we don't append the children during mount
15105 // but at commit. Therefore we need to track insertions which the normal
15106 // flow doesn't do during mount. This doesn't happen at the root because
15107 // the root always starts with a "current" with a null child.
15108 // TODO: Consider unifying this with how the root works.
15109 workInProgress.child = reconcileChildFibers(workInProgress, null, nextChildren, renderExpirationTime);
15110 } else {
15111 reconcileChildren(current$$1, workInProgress, nextChildren, renderExpirationTime);
15112 }
15113 return workInProgress.child;
15114}
15115
15116function updateContextProvider(current$$1, workInProgress, renderExpirationTime) {
15117 var providerType = workInProgress.type;
15118 var context = providerType._context;
15119
15120 var newProps = workInProgress.pendingProps;
15121 var oldProps = workInProgress.memoizedProps;
15122
15123 var newValue = newProps.value;
15124
15125 {
15126 var providerPropTypes = workInProgress.type.propTypes;
15127
15128 if (providerPropTypes) {
15129 checkPropTypes_1(providerPropTypes, newProps, 'prop', 'Context.Provider', getCurrentFiberStackInDev);
15130 }
15131 }
15132
15133 pushProvider(workInProgress, newValue);
15134
15135 if (oldProps !== null) {
15136 var oldValue = oldProps.value;
15137 var changedBits = calculateChangedBits(context, newValue, oldValue);
15138 if (changedBits === 0) {
15139 // No change. Bailout early if children are the same.
15140 if (oldProps.children === newProps.children && !hasContextChanged()) {
15141 return bailoutOnAlreadyFinishedWork(current$$1, workInProgress, renderExpirationTime);
15142 }
15143 } else {
15144 // The context value changed. Search for matching consumers and schedule
15145 // them to update.
15146 propagateContextChange(workInProgress, context, changedBits, renderExpirationTime);
15147 }
15148 }
15149
15150 var newChildren = newProps.children;
15151 reconcileChildren(current$$1, workInProgress, newChildren, renderExpirationTime);
15152 return workInProgress.child;
15153}
15154
15155var hasWarnedAboutUsingContextAsConsumer = false;
15156
15157function updateContextConsumer(current$$1, workInProgress, renderExpirationTime) {
15158 var context = workInProgress.type;
15159 // The logic below for Context differs depending on PROD or DEV mode. In
15160 // DEV mode, we create a separate object for Context.Consumer that acts
15161 // like a proxy to Context. This proxy object adds unnecessary code in PROD
15162 // so we use the old behaviour (Context.Consumer references Context) to
15163 // reduce size and overhead. The separate object references context via
15164 // a property called "_context", which also gives us the ability to check
15165 // in DEV mode if this property exists or not and warn if it does not.
15166 {
15167 if (context._context === undefined) {
15168 // This may be because it's a Context (rather than a Consumer).
15169 // Or it may be because it's older React where they're the same thing.
15170 // We only want to warn if we're sure it's a new React.
15171 if (context !== context.Consumer) {
15172 if (!hasWarnedAboutUsingContextAsConsumer) {
15173 hasWarnedAboutUsingContextAsConsumer = true;
15174 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?');
15175 }
15176 }
15177 } else {
15178 context = context._context;
15179 }
15180 }
15181 var newProps = workInProgress.pendingProps;
15182 var render = newProps.children;
15183
15184 {
15185 !(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;
15186 }
15187
15188 prepareToReadContext(workInProgress, renderExpirationTime);
15189 var newValue = readContext(context, newProps.unstable_observedBits);
15190 var newChildren = void 0;
15191 {
15192 ReactCurrentOwner$3.current = workInProgress;
15193 setCurrentPhase('render');
15194 newChildren = render(newValue);
15195 setCurrentPhase(null);
15196 }
15197
15198 // React DevTools reads this flag.
15199 workInProgress.effectTag |= PerformedWork;
15200 reconcileChildren(current$$1, workInProgress, newChildren, renderExpirationTime);
15201 return workInProgress.child;
15202}
15203
15204function markWorkInProgressReceivedUpdate() {
15205 didReceiveUpdate = true;
15206}
15207
15208function bailoutOnAlreadyFinishedWork(current$$1, workInProgress, renderExpirationTime) {
15209 cancelWorkTimer(workInProgress);
15210
15211 if (current$$1 !== null) {
15212 // Reuse previous context list
15213 workInProgress.contextDependencies = current$$1.contextDependencies;
15214 }
15215
15216 if (enableProfilerTimer) {
15217 // Don't update "base" render times for bailouts.
15218 stopProfilerTimerIfRunning(workInProgress);
15219 }
15220
15221 // Check if the children have any pending work.
15222 var childExpirationTime = workInProgress.childExpirationTime;
15223 if (childExpirationTime < renderExpirationTime) {
15224 // The children don't have any work either. We can skip them.
15225 // TODO: Once we add back resuming, we should check if the children are
15226 // a work-in-progress set. If so, we need to transfer their effects.
15227 return null;
15228 } else {
15229 // This fiber doesn't have work, but its subtree does. Clone the child
15230 // fibers and continue.
15231 cloneChildFibers(current$$1, workInProgress);
15232 return workInProgress.child;
15233 }
15234}
15235
15236function beginWork(current$$1, workInProgress, renderExpirationTime) {
15237 var updateExpirationTime = workInProgress.expirationTime;
15238
15239 if (current$$1 !== null) {
15240 var oldProps = current$$1.memoizedProps;
15241 var newProps = workInProgress.pendingProps;
15242
15243 if (oldProps !== newProps || hasContextChanged()) {
15244 // If props or context changed, mark the fiber as having performed work.
15245 // This may be unset if the props are determined to be equal later (memo).
15246 didReceiveUpdate = true;
15247 } else if (updateExpirationTime < renderExpirationTime) {
15248 didReceiveUpdate = false;
15249 // This fiber does not have any pending work. Bailout without entering
15250 // the begin phase. There's still some bookkeeping we that needs to be done
15251 // in this optimized path, mostly pushing stuff onto the stack.
15252 switch (workInProgress.tag) {
15253 case HostRoot:
15254 pushHostRootContext(workInProgress);
15255 resetHydrationState();
15256 break;
15257 case HostComponent:
15258 pushHostContext(workInProgress);
15259 break;
15260 case ClassComponent:
15261 {
15262 var Component = workInProgress.type;
15263 if (isContextProvider(Component)) {
15264 pushContextProvider(workInProgress);
15265 }
15266 break;
15267 }
15268 case HostPortal:
15269 pushHostContainer(workInProgress, workInProgress.stateNode.containerInfo);
15270 break;
15271 case ContextProvider:
15272 {
15273 var newValue = workInProgress.memoizedProps.value;
15274 pushProvider(workInProgress, newValue);
15275 break;
15276 }
15277 case Profiler:
15278 if (enableProfilerTimer) {
15279 workInProgress.effectTag |= Update;
15280 }
15281 break;
15282 case SuspenseComponent:
15283 {
15284 var state = workInProgress.memoizedState;
15285 var didTimeout = state !== null;
15286 if (didTimeout) {
15287 // If this boundary is currently timed out, we need to decide
15288 // whether to retry the primary children, or to skip over it and
15289 // go straight to the fallback. Check the priority of the primary
15290 var primaryChildFragment = workInProgress.child;
15291 var primaryChildExpirationTime = primaryChildFragment.childExpirationTime;
15292 if (primaryChildExpirationTime !== NoWork && primaryChildExpirationTime >= renderExpirationTime) {
15293 // The primary children have pending work. Use the normal path
15294 // to attempt to render the primary children again.
15295 return updateSuspenseComponent(current$$1, workInProgress, renderExpirationTime);
15296 } else {
15297 // The primary children do not have pending work with sufficient
15298 // priority. Bailout.
15299 var child = bailoutOnAlreadyFinishedWork(current$$1, workInProgress, renderExpirationTime);
15300 if (child !== null) {
15301 // The fallback children have pending work. Skip over the
15302 // primary children and work on the fallback.
15303 return child.sibling;
15304 } else {
15305 return null;
15306 }
15307 }
15308 }
15309 break;
15310 }
15311 }
15312 return bailoutOnAlreadyFinishedWork(current$$1, workInProgress, renderExpirationTime);
15313 }
15314 } else {
15315 didReceiveUpdate = false;
15316 }
15317
15318 // Before entering the begin phase, clear the expiration time.
15319 workInProgress.expirationTime = NoWork;
15320
15321 switch (workInProgress.tag) {
15322 case IndeterminateComponent:
15323 {
15324 var elementType = workInProgress.elementType;
15325 return mountIndeterminateComponent(current$$1, workInProgress, elementType, renderExpirationTime);
15326 }
15327 case LazyComponent:
15328 {
15329 var _elementType = workInProgress.elementType;
15330 return mountLazyComponent(current$$1, workInProgress, _elementType, updateExpirationTime, renderExpirationTime);
15331 }
15332 case FunctionComponent:
15333 {
15334 var _Component = workInProgress.type;
15335 var unresolvedProps = workInProgress.pendingProps;
15336 var resolvedProps = workInProgress.elementType === _Component ? unresolvedProps : resolveDefaultProps(_Component, unresolvedProps);
15337 return updateFunctionComponent(current$$1, workInProgress, _Component, resolvedProps, renderExpirationTime);
15338 }
15339 case ClassComponent:
15340 {
15341 var _Component2 = workInProgress.type;
15342 var _unresolvedProps = workInProgress.pendingProps;
15343 var _resolvedProps = workInProgress.elementType === _Component2 ? _unresolvedProps : resolveDefaultProps(_Component2, _unresolvedProps);
15344 return updateClassComponent(current$$1, workInProgress, _Component2, _resolvedProps, renderExpirationTime);
15345 }
15346 case HostRoot:
15347 return updateHostRoot(current$$1, workInProgress, renderExpirationTime);
15348 case HostComponent:
15349 return updateHostComponent(current$$1, workInProgress, renderExpirationTime);
15350 case HostText:
15351 return updateHostText(current$$1, workInProgress);
15352 case SuspenseComponent:
15353 return updateSuspenseComponent(current$$1, workInProgress, renderExpirationTime);
15354 case HostPortal:
15355 return updatePortalComponent(current$$1, workInProgress, renderExpirationTime);
15356 case ForwardRef:
15357 {
15358 var type = workInProgress.type;
15359 var _unresolvedProps2 = workInProgress.pendingProps;
15360 var _resolvedProps2 = workInProgress.elementType === type ? _unresolvedProps2 : resolveDefaultProps(type, _unresolvedProps2);
15361 return updateForwardRef(current$$1, workInProgress, type, _resolvedProps2, renderExpirationTime);
15362 }
15363 case Fragment:
15364 return updateFragment(current$$1, workInProgress, renderExpirationTime);
15365 case Mode:
15366 return updateMode(current$$1, workInProgress, renderExpirationTime);
15367 case Profiler:
15368 return updateProfiler(current$$1, workInProgress, renderExpirationTime);
15369 case ContextProvider:
15370 return updateContextProvider(current$$1, workInProgress, renderExpirationTime);
15371 case ContextConsumer:
15372 return updateContextConsumer(current$$1, workInProgress, renderExpirationTime);
15373 case MemoComponent:
15374 {
15375 var _type2 = workInProgress.type;
15376 var _unresolvedProps3 = workInProgress.pendingProps;
15377 // Resolve outer props first, then resolve inner props.
15378 var _resolvedProps3 = resolveDefaultProps(_type2, _unresolvedProps3);
15379 {
15380 if (workInProgress.type !== workInProgress.elementType) {
15381 var outerPropTypes = _type2.propTypes;
15382 if (outerPropTypes) {
15383 checkPropTypes_1(outerPropTypes, _resolvedProps3, // Resolved for outer only
15384 'prop', getComponentName(_type2), getCurrentFiberStackInDev);
15385 }
15386 }
15387 }
15388 _resolvedProps3 = resolveDefaultProps(_type2.type, _resolvedProps3);
15389 return updateMemoComponent(current$$1, workInProgress, _type2, _resolvedProps3, updateExpirationTime, renderExpirationTime);
15390 }
15391 case SimpleMemoComponent:
15392 {
15393 return updateSimpleMemoComponent(current$$1, workInProgress, workInProgress.type, workInProgress.pendingProps, updateExpirationTime, renderExpirationTime);
15394 }
15395 case IncompleteClassComponent:
15396 {
15397 var _Component3 = workInProgress.type;
15398 var _unresolvedProps4 = workInProgress.pendingProps;
15399 var _resolvedProps4 = workInProgress.elementType === _Component3 ? _unresolvedProps4 : resolveDefaultProps(_Component3, _unresolvedProps4);
15400 return mountIncompleteClassComponent(current$$1, workInProgress, _Component3, _resolvedProps4, renderExpirationTime);
15401 }
15402 default:
15403 invariant(false, 'Unknown unit of work tag. This error is likely caused by a bug in React. Please file an issue.');
15404 }
15405}
15406
15407var valueCursor = createCursor(null);
15408
15409var rendererSigil = void 0;
15410{
15411 // Use this to detect multiple renderers using the same context
15412 rendererSigil = {};
15413}
15414
15415var currentlyRenderingFiber = null;
15416var lastContextDependency = null;
15417var lastContextWithAllBitsObserved = null;
15418
15419var isDisallowedContextReadInDEV = false;
15420
15421function resetContextDependences() {
15422 // This is called right before React yields execution, to ensure `readContext`
15423 // cannot be called outside the render phase.
15424 currentlyRenderingFiber = null;
15425 lastContextDependency = null;
15426 lastContextWithAllBitsObserved = null;
15427 {
15428 isDisallowedContextReadInDEV = false;
15429 }
15430}
15431
15432function enterDisallowedContextReadInDEV() {
15433 {
15434 isDisallowedContextReadInDEV = true;
15435 }
15436}
15437
15438function exitDisallowedContextReadInDEV() {
15439 {
15440 isDisallowedContextReadInDEV = false;
15441 }
15442}
15443
15444function pushProvider(providerFiber, nextValue) {
15445 var context = providerFiber.type._context;
15446
15447 if (isPrimaryRenderer) {
15448 push(valueCursor, context._currentValue, providerFiber);
15449
15450 context._currentValue = nextValue;
15451 {
15452 !(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;
15453 context._currentRenderer = rendererSigil;
15454 }
15455 } else {
15456 push(valueCursor, context._currentValue2, providerFiber);
15457
15458 context._currentValue2 = nextValue;
15459 {
15460 !(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;
15461 context._currentRenderer2 = rendererSigil;
15462 }
15463 }
15464}
15465
15466function popProvider(providerFiber) {
15467 var currentValue = valueCursor.current;
15468
15469 pop(valueCursor, providerFiber);
15470
15471 var context = providerFiber.type._context;
15472 if (isPrimaryRenderer) {
15473 context._currentValue = currentValue;
15474 } else {
15475 context._currentValue2 = currentValue;
15476 }
15477}
15478
15479function calculateChangedBits(context, newValue, oldValue) {
15480 if (is(oldValue, newValue)) {
15481 // No change
15482 return 0;
15483 } else {
15484 var changedBits = typeof context._calculateChangedBits === 'function' ? context._calculateChangedBits(oldValue, newValue) : maxSigned31BitInt;
15485
15486 {
15487 !((changedBits & maxSigned31BitInt) === changedBits) ? warning$1(false, 'calculateChangedBits: Expected the return value to be a ' + '31-bit integer. Instead received: %s', changedBits) : void 0;
15488 }
15489 return changedBits | 0;
15490 }
15491}
15492
15493function propagateContextChange(workInProgress, context, changedBits, renderExpirationTime) {
15494 var fiber = workInProgress.child;
15495 if (fiber !== null) {
15496 // Set the return pointer of the child to the work-in-progress fiber.
15497 fiber.return = workInProgress;
15498 }
15499 while (fiber !== null) {
15500 var nextFiber = void 0;
15501
15502 // Visit this fiber.
15503 var list = fiber.contextDependencies;
15504 if (list !== null) {
15505 nextFiber = fiber.child;
15506
15507 var dependency = list.first;
15508 while (dependency !== null) {
15509 // Check if the context matches.
15510 if (dependency.context === context && (dependency.observedBits & changedBits) !== 0) {
15511 // Match! Schedule an update on this fiber.
15512
15513 if (fiber.tag === ClassComponent) {
15514 // Schedule a force update on the work-in-progress.
15515 var update = createUpdate(renderExpirationTime);
15516 update.tag = ForceUpdate;
15517 // TODO: Because we don't have a work-in-progress, this will add the
15518 // update to the current fiber, too, which means it will persist even if
15519 // this render is thrown away. Since it's a race condition, not sure it's
15520 // worth fixing.
15521 enqueueUpdate(fiber, update);
15522 }
15523
15524 if (fiber.expirationTime < renderExpirationTime) {
15525 fiber.expirationTime = renderExpirationTime;
15526 }
15527 var alternate = fiber.alternate;
15528 if (alternate !== null && alternate.expirationTime < renderExpirationTime) {
15529 alternate.expirationTime = renderExpirationTime;
15530 }
15531 // Update the child expiration time of all the ancestors, including
15532 // the alternates.
15533 var node = fiber.return;
15534 while (node !== null) {
15535 alternate = node.alternate;
15536 if (node.childExpirationTime < renderExpirationTime) {
15537 node.childExpirationTime = renderExpirationTime;
15538 if (alternate !== null && alternate.childExpirationTime < renderExpirationTime) {
15539 alternate.childExpirationTime = renderExpirationTime;
15540 }
15541 } else if (alternate !== null && alternate.childExpirationTime < renderExpirationTime) {
15542 alternate.childExpirationTime = renderExpirationTime;
15543 } else {
15544 // Neither alternate was updated, which means the rest of the
15545 // ancestor path already has sufficient priority.
15546 break;
15547 }
15548 node = node.return;
15549 }
15550
15551 // Mark the expiration time on the list, too.
15552 if (list.expirationTime < renderExpirationTime) {
15553 list.expirationTime = renderExpirationTime;
15554 }
15555
15556 // Since we already found a match, we can stop traversing the
15557 // dependency list.
15558 break;
15559 }
15560 dependency = dependency.next;
15561 }
15562 } else if (fiber.tag === ContextProvider) {
15563 // Don't scan deeper if this is a matching provider
15564 nextFiber = fiber.type === workInProgress.type ? null : fiber.child;
15565 } else {
15566 // Traverse down.
15567 nextFiber = fiber.child;
15568 }
15569
15570 if (nextFiber !== null) {
15571 // Set the return pointer of the child to the work-in-progress fiber.
15572 nextFiber.return = fiber;
15573 } else {
15574 // No child. Traverse to next sibling.
15575 nextFiber = fiber;
15576 while (nextFiber !== null) {
15577 if (nextFiber === workInProgress) {
15578 // We're back to the root of this subtree. Exit.
15579 nextFiber = null;
15580 break;
15581 }
15582 var sibling = nextFiber.sibling;
15583 if (sibling !== null) {
15584 // Set the return pointer of the sibling to the work-in-progress fiber.
15585 sibling.return = nextFiber.return;
15586 nextFiber = sibling;
15587 break;
15588 }
15589 // No more siblings. Traverse up.
15590 nextFiber = nextFiber.return;
15591 }
15592 }
15593 fiber = nextFiber;
15594 }
15595}
15596
15597function prepareToReadContext(workInProgress, renderExpirationTime) {
15598 currentlyRenderingFiber = workInProgress;
15599 lastContextDependency = null;
15600 lastContextWithAllBitsObserved = null;
15601
15602 var currentDependencies = workInProgress.contextDependencies;
15603 if (currentDependencies !== null && currentDependencies.expirationTime >= renderExpirationTime) {
15604 // Context list has a pending update. Mark that this fiber performed work.
15605 markWorkInProgressReceivedUpdate();
15606 }
15607
15608 // Reset the work-in-progress list
15609 workInProgress.contextDependencies = null;
15610}
15611
15612function readContext(context, observedBits) {
15613 {
15614 // This warning would fire if you read context inside a Hook like useMemo.
15615 // Unlike the class check below, it's not enforced in production for perf.
15616 !!isDisallowedContextReadInDEV ? warning$1(false, 'Context can only be read while React is rendering. ' + 'In classes, you can read it in the render method or getDerivedStateFromProps. ' + 'In function components, you can read it directly in the function body, but not ' + 'inside Hooks like useReducer() or useMemo().') : void 0;
15617 }
15618
15619 if (lastContextWithAllBitsObserved === context) {
15620 // Nothing to do. We already observe everything in this context.
15621 } else if (observedBits === false || observedBits === 0) {
15622 // Do not observe any updates.
15623 } else {
15624 var resolvedObservedBits = void 0; // Avoid deopting on observable arguments or heterogeneous types.
15625 if (typeof observedBits !== 'number' || observedBits === maxSigned31BitInt) {
15626 // Observe all updates.
15627 lastContextWithAllBitsObserved = context;
15628 resolvedObservedBits = maxSigned31BitInt;
15629 } else {
15630 resolvedObservedBits = observedBits;
15631 }
15632
15633 var contextItem = {
15634 context: context,
15635 observedBits: resolvedObservedBits,
15636 next: null
15637 };
15638
15639 if (lastContextDependency === null) {
15640 !(currentlyRenderingFiber !== null) ? invariant(false, 'Context can only be read while React is rendering. In classes, you can read it in the render method or getDerivedStateFromProps. In function components, you can read it directly in the function body, but not inside Hooks like useReducer() or useMemo().') : void 0;
15641
15642 // This is the first dependency for this component. Create a new list.
15643 lastContextDependency = contextItem;
15644 currentlyRenderingFiber.contextDependencies = {
15645 first: contextItem,
15646 expirationTime: NoWork
15647 };
15648 } else {
15649 // Append a new context item.
15650 lastContextDependency = lastContextDependency.next = contextItem;
15651 }
15652 }
15653 return isPrimaryRenderer ? context._currentValue : context._currentValue2;
15654}
15655
15656// UpdateQueue is a linked list of prioritized updates.
15657//
15658// Like fibers, update queues come in pairs: a current queue, which represents
15659// the visible state of the screen, and a work-in-progress queue, which can be
15660// mutated and processed asynchronously before it is committed — a form of
15661// double buffering. If a work-in-progress render is discarded before finishing,
15662// we create a new work-in-progress by cloning the current queue.
15663//
15664// Both queues share a persistent, singly-linked list structure. To schedule an
15665// update, we append it to the end of both queues. Each queue maintains a
15666// pointer to first update in the persistent list that hasn't been processed.
15667// The work-in-progress pointer always has a position equal to or greater than
15668// the current queue, since we always work on that one. The current queue's
15669// pointer is only updated during the commit phase, when we swap in the
15670// work-in-progress.
15671//
15672// For example:
15673//
15674// Current pointer: A - B - C - D - E - F
15675// Work-in-progress pointer: D - E - F
15676// ^
15677// The work-in-progress queue has
15678// processed more updates than current.
15679//
15680// The reason we append to both queues is because otherwise we might drop
15681// updates without ever processing them. For example, if we only add updates to
15682// the work-in-progress queue, some updates could be lost whenever a work-in
15683// -progress render restarts by cloning from current. Similarly, if we only add
15684// updates to the current queue, the updates will be lost whenever an already
15685// in-progress queue commits and swaps with the current queue. However, by
15686// adding to both queues, we guarantee that the update will be part of the next
15687// work-in-progress. (And because the work-in-progress queue becomes the
15688// current queue once it commits, there's no danger of applying the same
15689// update twice.)
15690//
15691// Prioritization
15692// --------------
15693//
15694// Updates are not sorted by priority, but by insertion; new updates are always
15695// appended to the end of the list.
15696//
15697// The priority is still important, though. When processing the update queue
15698// during the render phase, only the updates with sufficient priority are
15699// included in the result. If we skip an update because it has insufficient
15700// priority, it remains in the queue to be processed later, during a lower
15701// priority render. Crucially, all updates subsequent to a skipped update also
15702// remain in the queue *regardless of their priority*. That means high priority
15703// updates are sometimes processed twice, at two separate priorities. We also
15704// keep track of a base state, that represents the state before the first
15705// update in the queue is applied.
15706//
15707// For example:
15708//
15709// Given a base state of '', and the following queue of updates
15710//
15711// A1 - B2 - C1 - D2
15712//
15713// where the number indicates the priority, and the update is applied to the
15714// previous state by appending a letter, React will process these updates as
15715// two separate renders, one per distinct priority level:
15716//
15717// First render, at priority 1:
15718// Base state: ''
15719// Updates: [A1, C1]
15720// Result state: 'AC'
15721//
15722// Second render, at priority 2:
15723// Base state: 'A' <- The base state does not include C1,
15724// because B2 was skipped.
15725// Updates: [B2, C1, D2] <- C1 was rebased on top of B2
15726// Result state: 'ABCD'
15727//
15728// Because we process updates in insertion order, and rebase high priority
15729// updates when preceding updates are skipped, the final result is deterministic
15730// regardless of priority. Intermediate state may vary according to system
15731// resources, but the final state is always the same.
15732
15733var UpdateState = 0;
15734var ReplaceState = 1;
15735var ForceUpdate = 2;
15736var CaptureUpdate = 3;
15737
15738// Global state that is reset at the beginning of calling `processUpdateQueue`.
15739// It should only be read right after calling `processUpdateQueue`, via
15740// `checkHasForceUpdateAfterProcessing`.
15741var hasForceUpdate = false;
15742
15743var didWarnUpdateInsideUpdate = void 0;
15744var currentlyProcessingQueue = void 0;
15745var resetCurrentlyProcessingQueue = void 0;
15746{
15747 didWarnUpdateInsideUpdate = false;
15748 currentlyProcessingQueue = null;
15749 resetCurrentlyProcessingQueue = function () {
15750 currentlyProcessingQueue = null;
15751 };
15752}
15753
15754function createUpdateQueue(baseState) {
15755 var queue = {
15756 baseState: baseState,
15757 firstUpdate: null,
15758 lastUpdate: null,
15759 firstCapturedUpdate: null,
15760 lastCapturedUpdate: null,
15761 firstEffect: null,
15762 lastEffect: null,
15763 firstCapturedEffect: null,
15764 lastCapturedEffect: null
15765 };
15766 return queue;
15767}
15768
15769function cloneUpdateQueue(currentQueue) {
15770 var queue = {
15771 baseState: currentQueue.baseState,
15772 firstUpdate: currentQueue.firstUpdate,
15773 lastUpdate: currentQueue.lastUpdate,
15774
15775 // TODO: With resuming, if we bail out and resuse the child tree, we should
15776 // keep these effects.
15777 firstCapturedUpdate: null,
15778 lastCapturedUpdate: null,
15779
15780 firstEffect: null,
15781 lastEffect: null,
15782
15783 firstCapturedEffect: null,
15784 lastCapturedEffect: null
15785 };
15786 return queue;
15787}
15788
15789function createUpdate(expirationTime) {
15790 return {
15791 expirationTime: expirationTime,
15792
15793 tag: UpdateState,
15794 payload: null,
15795 callback: null,
15796
15797 next: null,
15798 nextEffect: null
15799 };
15800}
15801
15802function appendUpdateToQueue(queue, update) {
15803 // Append the update to the end of the list.
15804 if (queue.lastUpdate === null) {
15805 // Queue is empty
15806 queue.firstUpdate = queue.lastUpdate = update;
15807 } else {
15808 queue.lastUpdate.next = update;
15809 queue.lastUpdate = update;
15810 }
15811}
15812
15813function enqueueUpdate(fiber, update) {
15814 // Update queues are created lazily.
15815 var alternate = fiber.alternate;
15816 var queue1 = void 0;
15817 var queue2 = void 0;
15818 if (alternate === null) {
15819 // There's only one fiber.
15820 queue1 = fiber.updateQueue;
15821 queue2 = null;
15822 if (queue1 === null) {
15823 queue1 = fiber.updateQueue = createUpdateQueue(fiber.memoizedState);
15824 }
15825 } else {
15826 // There are two owners.
15827 queue1 = fiber.updateQueue;
15828 queue2 = alternate.updateQueue;
15829 if (queue1 === null) {
15830 if (queue2 === null) {
15831 // Neither fiber has an update queue. Create new ones.
15832 queue1 = fiber.updateQueue = createUpdateQueue(fiber.memoizedState);
15833 queue2 = alternate.updateQueue = createUpdateQueue(alternate.memoizedState);
15834 } else {
15835 // Only one fiber has an update queue. Clone to create a new one.
15836 queue1 = fiber.updateQueue = cloneUpdateQueue(queue2);
15837 }
15838 } else {
15839 if (queue2 === null) {
15840 // Only one fiber has an update queue. Clone to create a new one.
15841 queue2 = alternate.updateQueue = cloneUpdateQueue(queue1);
15842 } else {
15843 // Both owners have an update queue.
15844 }
15845 }
15846 }
15847 if (queue2 === null || queue1 === queue2) {
15848 // There's only a single queue.
15849 appendUpdateToQueue(queue1, update);
15850 } else {
15851 // There are two queues. We need to append the update to both queues,
15852 // while accounting for the persistent structure of the list — we don't
15853 // want the same update to be added multiple times.
15854 if (queue1.lastUpdate === null || queue2.lastUpdate === null) {
15855 // One of the queues is not empty. We must add the update to both queues.
15856 appendUpdateToQueue(queue1, update);
15857 appendUpdateToQueue(queue2, update);
15858 } else {
15859 // Both queues are non-empty. The last update is the same in both lists,
15860 // because of structural sharing. So, only append to one of the lists.
15861 appendUpdateToQueue(queue1, update);
15862 // But we still need to update the `lastUpdate` pointer of queue2.
15863 queue2.lastUpdate = update;
15864 }
15865 }
15866
15867 {
15868 if (fiber.tag === ClassComponent && (currentlyProcessingQueue === queue1 || queue2 !== null && currentlyProcessingQueue === queue2) && !didWarnUpdateInsideUpdate) {
15869 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.');
15870 didWarnUpdateInsideUpdate = true;
15871 }
15872 }
15873}
15874
15875function enqueueCapturedUpdate(workInProgress, update) {
15876 // Captured updates go into a separate list, and only on the work-in-
15877 // progress queue.
15878 var workInProgressQueue = workInProgress.updateQueue;
15879 if (workInProgressQueue === null) {
15880 workInProgressQueue = workInProgress.updateQueue = createUpdateQueue(workInProgress.memoizedState);
15881 } else {
15882 // TODO: I put this here rather than createWorkInProgress so that we don't
15883 // clone the queue unnecessarily. There's probably a better way to
15884 // structure this.
15885 workInProgressQueue = ensureWorkInProgressQueueIsAClone(workInProgress, workInProgressQueue);
15886 }
15887
15888 // Append the update to the end of the list.
15889 if (workInProgressQueue.lastCapturedUpdate === null) {
15890 // This is the first render phase update
15891 workInProgressQueue.firstCapturedUpdate = workInProgressQueue.lastCapturedUpdate = update;
15892 } else {
15893 workInProgressQueue.lastCapturedUpdate.next = update;
15894 workInProgressQueue.lastCapturedUpdate = update;
15895 }
15896}
15897
15898function ensureWorkInProgressQueueIsAClone(workInProgress, queue) {
15899 var current = workInProgress.alternate;
15900 if (current !== null) {
15901 // If the work-in-progress queue is equal to the current queue,
15902 // we need to clone it first.
15903 if (queue === current.updateQueue) {
15904 queue = workInProgress.updateQueue = cloneUpdateQueue(queue);
15905 }
15906 }
15907 return queue;
15908}
15909
15910function getStateFromUpdate(workInProgress, queue, update, prevState, nextProps, instance) {
15911 switch (update.tag) {
15912 case ReplaceState:
15913 {
15914 var _payload = update.payload;
15915 if (typeof _payload === 'function') {
15916 // Updater function
15917 {
15918 enterDisallowedContextReadInDEV();
15919 if (debugRenderPhaseSideEffects || debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) {
15920 _payload.call(instance, prevState, nextProps);
15921 }
15922 }
15923 var nextState = _payload.call(instance, prevState, nextProps);
15924 {
15925 exitDisallowedContextReadInDEV();
15926 }
15927 return nextState;
15928 }
15929 // State object
15930 return _payload;
15931 }
15932 case CaptureUpdate:
15933 {
15934 workInProgress.effectTag = workInProgress.effectTag & ~ShouldCapture | DidCapture;
15935 }
15936 // Intentional fallthrough
15937 case UpdateState:
15938 {
15939 var _payload2 = update.payload;
15940 var partialState = void 0;
15941 if (typeof _payload2 === 'function') {
15942 // Updater function
15943 {
15944 enterDisallowedContextReadInDEV();
15945 if (debugRenderPhaseSideEffects || debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) {
15946 _payload2.call(instance, prevState, nextProps);
15947 }
15948 }
15949 partialState = _payload2.call(instance, prevState, nextProps);
15950 {
15951 exitDisallowedContextReadInDEV();
15952 }
15953 } else {
15954 // Partial state object
15955 partialState = _payload2;
15956 }
15957 if (partialState === null || partialState === undefined) {
15958 // Null and undefined are treated as no-ops.
15959 return prevState;
15960 }
15961 // Merge the partial state and the previous state.
15962 return _assign({}, prevState, partialState);
15963 }
15964 case ForceUpdate:
15965 {
15966 hasForceUpdate = true;
15967 return prevState;
15968 }
15969 }
15970 return prevState;
15971}
15972
15973function processUpdateQueue(workInProgress, queue, props, instance, renderExpirationTime) {
15974 hasForceUpdate = false;
15975
15976 queue = ensureWorkInProgressQueueIsAClone(workInProgress, queue);
15977
15978 {
15979 currentlyProcessingQueue = queue;
15980 }
15981
15982 // These values may change as we process the queue.
15983 var newBaseState = queue.baseState;
15984 var newFirstUpdate = null;
15985 var newExpirationTime = NoWork;
15986
15987 // Iterate through the list of updates to compute the result.
15988 var update = queue.firstUpdate;
15989 var resultState = newBaseState;
15990 while (update !== null) {
15991 var updateExpirationTime = update.expirationTime;
15992 if (updateExpirationTime < renderExpirationTime) {
15993 // This update does not have sufficient priority. Skip it.
15994 if (newFirstUpdate === null) {
15995 // This is the first skipped update. It will be the first update in
15996 // the new list.
15997 newFirstUpdate = update;
15998 // Since this is the first update that was skipped, the current result
15999 // is the new base state.
16000 newBaseState = resultState;
16001 }
16002 // Since this update will remain in the list, update the remaining
16003 // expiration time.
16004 if (newExpirationTime < updateExpirationTime) {
16005 newExpirationTime = updateExpirationTime;
16006 }
16007 } else {
16008 // This update does have sufficient priority. Process it and compute
16009 // a new result.
16010 resultState = getStateFromUpdate(workInProgress, queue, update, resultState, props, instance);
16011 var _callback = update.callback;
16012 if (_callback !== null) {
16013 workInProgress.effectTag |= Callback;
16014 // Set this to null, in case it was mutated during an aborted render.
16015 update.nextEffect = null;
16016 if (queue.lastEffect === null) {
16017 queue.firstEffect = queue.lastEffect = update;
16018 } else {
16019 queue.lastEffect.nextEffect = update;
16020 queue.lastEffect = update;
16021 }
16022 }
16023 }
16024 // Continue to the next update.
16025 update = update.next;
16026 }
16027
16028 // Separately, iterate though the list of captured updates.
16029 var newFirstCapturedUpdate = null;
16030 update = queue.firstCapturedUpdate;
16031 while (update !== null) {
16032 var _updateExpirationTime = update.expirationTime;
16033 if (_updateExpirationTime < renderExpirationTime) {
16034 // This update does not have sufficient priority. Skip it.
16035 if (newFirstCapturedUpdate === null) {
16036 // This is the first skipped captured update. It will be the first
16037 // update in the new list.
16038 newFirstCapturedUpdate = update;
16039 // If this is the first update that was skipped, the current result is
16040 // the new base state.
16041 if (newFirstUpdate === null) {
16042 newBaseState = resultState;
16043 }
16044 }
16045 // Since this update will remain in the list, update the remaining
16046 // expiration time.
16047 if (newExpirationTime < _updateExpirationTime) {
16048 newExpirationTime = _updateExpirationTime;
16049 }
16050 } else {
16051 // This update does have sufficient priority. Process it and compute
16052 // a new result.
16053 resultState = getStateFromUpdate(workInProgress, queue, update, resultState, props, instance);
16054 var _callback2 = update.callback;
16055 if (_callback2 !== null) {
16056 workInProgress.effectTag |= Callback;
16057 // Set this to null, in case it was mutated during an aborted render.
16058 update.nextEffect = null;
16059 if (queue.lastCapturedEffect === null) {
16060 queue.firstCapturedEffect = queue.lastCapturedEffect = update;
16061 } else {
16062 queue.lastCapturedEffect.nextEffect = update;
16063 queue.lastCapturedEffect = update;
16064 }
16065 }
16066 }
16067 update = update.next;
16068 }
16069
16070 if (newFirstUpdate === null) {
16071 queue.lastUpdate = null;
16072 }
16073 if (newFirstCapturedUpdate === null) {
16074 queue.lastCapturedUpdate = null;
16075 } else {
16076 workInProgress.effectTag |= Callback;
16077 }
16078 if (newFirstUpdate === null && newFirstCapturedUpdate === null) {
16079 // We processed every update, without skipping. That means the new base
16080 // state is the same as the result state.
16081 newBaseState = resultState;
16082 }
16083
16084 queue.baseState = newBaseState;
16085 queue.firstUpdate = newFirstUpdate;
16086 queue.firstCapturedUpdate = newFirstCapturedUpdate;
16087
16088 // Set the remaining expiration time to be whatever is remaining in the queue.
16089 // This should be fine because the only two other things that contribute to
16090 // expiration time are props and context. We're already in the middle of the
16091 // begin phase by the time we start processing the queue, so we've already
16092 // dealt with the props. Context in components that specify
16093 // shouldComponentUpdate is tricky; but we'll have to account for
16094 // that regardless.
16095 workInProgress.expirationTime = newExpirationTime;
16096 workInProgress.memoizedState = resultState;
16097
16098 {
16099 currentlyProcessingQueue = null;
16100 }
16101}
16102
16103function callCallback(callback, context) {
16104 !(typeof callback === 'function') ? invariant(false, 'Invalid argument passed as callback. Expected a function. Instead received: %s', callback) : void 0;
16105 callback.call(context);
16106}
16107
16108function resetHasForceUpdateBeforeProcessing() {
16109 hasForceUpdate = false;
16110}
16111
16112function checkHasForceUpdateAfterProcessing() {
16113 return hasForceUpdate;
16114}
16115
16116function commitUpdateQueue(finishedWork, finishedQueue, instance, renderExpirationTime) {
16117 // If the finished render included captured updates, and there are still
16118 // lower priority updates left over, we need to keep the captured updates
16119 // in the queue so that they are rebased and not dropped once we process the
16120 // queue again at the lower priority.
16121 if (finishedQueue.firstCapturedUpdate !== null) {
16122 // Join the captured update list to the end of the normal list.
16123 if (finishedQueue.lastUpdate !== null) {
16124 finishedQueue.lastUpdate.next = finishedQueue.firstCapturedUpdate;
16125 finishedQueue.lastUpdate = finishedQueue.lastCapturedUpdate;
16126 }
16127 // Clear the list of captured updates.
16128 finishedQueue.firstCapturedUpdate = finishedQueue.lastCapturedUpdate = null;
16129 }
16130
16131 // Commit the effects
16132 commitUpdateEffects(finishedQueue.firstEffect, instance);
16133 finishedQueue.firstEffect = finishedQueue.lastEffect = null;
16134
16135 commitUpdateEffects(finishedQueue.firstCapturedEffect, instance);
16136 finishedQueue.firstCapturedEffect = finishedQueue.lastCapturedEffect = null;
16137}
16138
16139function commitUpdateEffects(effect, instance) {
16140 while (effect !== null) {
16141 var _callback3 = effect.callback;
16142 if (_callback3 !== null) {
16143 effect.callback = null;
16144 callCallback(_callback3, instance);
16145 }
16146 effect = effect.nextEffect;
16147 }
16148}
16149
16150function createCapturedValue(value, source) {
16151 // If the value is an error, call this function immediately after it is thrown
16152 // so the stack is accurate.
16153 return {
16154 value: value,
16155 source: source,
16156 stack: getStackByFiberInDevAndProd(source)
16157 };
16158}
16159
16160function markUpdate(workInProgress) {
16161 // Tag the fiber with an update effect. This turns a Placement into
16162 // a PlacementAndUpdate.
16163 workInProgress.effectTag |= Update;
16164}
16165
16166function markRef$1(workInProgress) {
16167 workInProgress.effectTag |= Ref;
16168}
16169
16170var appendAllChildren = void 0;
16171var updateHostContainer = void 0;
16172var updateHostComponent$1 = void 0;
16173var updateHostText$1 = void 0;
16174if (supportsMutation) {
16175 // Mutation mode
16176
16177 appendAllChildren = function (parent, workInProgress, needsVisibilityToggle, isHidden) {
16178 // We only have the top Fiber that was created but we need recurse down its
16179 // children to find all the terminal nodes.
16180 var node = workInProgress.child;
16181 while (node !== null) {
16182 if (node.tag === HostComponent || node.tag === HostText) {
16183 appendInitialChild(parent, node.stateNode);
16184 } else if (node.tag === HostPortal) {
16185 // If we have a portal child, then we don't want to traverse
16186 // down its children. Instead, we'll get insertions from each child in
16187 // the portal directly.
16188 } else if (node.child !== null) {
16189 node.child.return = node;
16190 node = node.child;
16191 continue;
16192 }
16193 if (node === workInProgress) {
16194 return;
16195 }
16196 while (node.sibling === null) {
16197 if (node.return === null || node.return === workInProgress) {
16198 return;
16199 }
16200 node = node.return;
16201 }
16202 node.sibling.return = node.return;
16203 node = node.sibling;
16204 }
16205 };
16206
16207 updateHostContainer = function (workInProgress) {
16208 // Noop
16209 };
16210 updateHostComponent$1 = function (current, workInProgress, type, newProps, rootContainerInstance) {
16211 // If we have an alternate, that means this is an update and we need to
16212 // schedule a side-effect to do the updates.
16213 var oldProps = current.memoizedProps;
16214 if (oldProps === newProps) {
16215 // In mutation mode, this is sufficient for a bailout because
16216 // we won't touch this node even if children changed.
16217 return;
16218 }
16219
16220 // If we get updated because one of our children updated, we don't
16221 // have newProps so we'll have to reuse them.
16222 // TODO: Split the update API as separate for the props vs. children.
16223 // Even better would be if children weren't special cased at all tho.
16224 var instance = workInProgress.stateNode;
16225 var currentHostContext = getHostContext();
16226 // TODO: Experiencing an error where oldProps is null. Suggests a host
16227 // component is hitting the resume path. Figure out why. Possibly
16228 // related to `hidden`.
16229 var updatePayload = prepareUpdate(instance, type, oldProps, newProps, rootContainerInstance, currentHostContext);
16230 // TODO: Type this specific to this type of component.
16231 workInProgress.updateQueue = updatePayload;
16232 // If the update payload indicates that there is a change or if there
16233 // is a new ref we mark this as an update. All the work is done in commitWork.
16234 if (updatePayload) {
16235 markUpdate(workInProgress);
16236 }
16237 };
16238 updateHostText$1 = function (current, workInProgress, oldText, newText) {
16239 // If the text differs, mark it as an update. All the work in done in commitWork.
16240 if (oldText !== newText) {
16241 markUpdate(workInProgress);
16242 }
16243 };
16244} else if (supportsPersistence) {
16245 // Persistent host tree mode
16246
16247 appendAllChildren = function (parent, workInProgress, needsVisibilityToggle, isHidden) {
16248 // We only have the top Fiber that was created but we need recurse down its
16249 // children to find all the terminal nodes.
16250 var node = workInProgress.child;
16251 while (node !== null) {
16252 // eslint-disable-next-line no-labels
16253 branches: if (node.tag === HostComponent) {
16254 var instance = node.stateNode;
16255 if (needsVisibilityToggle) {
16256 var props = node.memoizedProps;
16257 var type = node.type;
16258 if (isHidden) {
16259 // This child is inside a timed out tree. Hide it.
16260 instance = cloneHiddenInstance(instance, type, props, node);
16261 } else {
16262 // This child was previously inside a timed out tree. If it was not
16263 // updated during this render, it may need to be unhidden. Clone
16264 // again to be sure.
16265 instance = cloneUnhiddenInstance(instance, type, props, node);
16266 }
16267 node.stateNode = instance;
16268 }
16269 appendInitialChild(parent, instance);
16270 } else if (node.tag === HostText) {
16271 var _instance = node.stateNode;
16272 if (needsVisibilityToggle) {
16273 var text = node.memoizedProps;
16274 var rootContainerInstance = getRootHostContainer();
16275 var currentHostContext = getHostContext();
16276 if (isHidden) {
16277 _instance = createHiddenTextInstance(text, rootContainerInstance, currentHostContext, workInProgress);
16278 } else {
16279 _instance = createTextInstance(text, rootContainerInstance, currentHostContext, workInProgress);
16280 }
16281 node.stateNode = _instance;
16282 }
16283 appendInitialChild(parent, _instance);
16284 } else if (node.tag === HostPortal) {
16285 // If we have a portal child, then we don't want to traverse
16286 // down its children. Instead, we'll get insertions from each child in
16287 // the portal directly.
16288 } else if (node.tag === SuspenseComponent) {
16289 var current = node.alternate;
16290 if (current !== null) {
16291 var oldState = current.memoizedState;
16292 var newState = node.memoizedState;
16293 var oldIsHidden = oldState !== null;
16294 var newIsHidden = newState !== null;
16295 if (oldIsHidden !== newIsHidden) {
16296 // The placeholder either just timed out or switched back to the normal
16297 // children after having previously timed out. Toggle the visibility of
16298 // the direct host children.
16299 var primaryChildParent = newIsHidden ? node.child : node;
16300 if (primaryChildParent !== null) {
16301 appendAllChildren(parent, primaryChildParent, true, newIsHidden);
16302 }
16303 // eslint-disable-next-line no-labels
16304 break branches;
16305 }
16306 }
16307 if (node.child !== null) {
16308 // Continue traversing like normal
16309 node.child.return = node;
16310 node = node.child;
16311 continue;
16312 }
16313 } else if (node.child !== null) {
16314 node.child.return = node;
16315 node = node.child;
16316 continue;
16317 }
16318 // $FlowFixMe This is correct but Flow is confused by the labeled break.
16319 node = node;
16320 if (node === workInProgress) {
16321 return;
16322 }
16323 while (node.sibling === null) {
16324 if (node.return === null || node.return === workInProgress) {
16325 return;
16326 }
16327 node = node.return;
16328 }
16329 node.sibling.return = node.return;
16330 node = node.sibling;
16331 }
16332 };
16333
16334 // An unfortunate fork of appendAllChildren because we have two different parent types.
16335 var appendAllChildrenToContainer = function (containerChildSet, workInProgress, needsVisibilityToggle, isHidden) {
16336 // We only have the top Fiber that was created but we need recurse down its
16337 // children to find all the terminal nodes.
16338 var node = workInProgress.child;
16339 while (node !== null) {
16340 // eslint-disable-next-line no-labels
16341 branches: if (node.tag === HostComponent) {
16342 var instance = node.stateNode;
16343 if (needsVisibilityToggle) {
16344 var props = node.memoizedProps;
16345 var type = node.type;
16346 if (isHidden) {
16347 // This child is inside a timed out tree. Hide it.
16348 instance = cloneHiddenInstance(instance, type, props, node);
16349 } else {
16350 // This child was previously inside a timed out tree. If it was not
16351 // updated during this render, it may need to be unhidden. Clone
16352 // again to be sure.
16353 instance = cloneUnhiddenInstance(instance, type, props, node);
16354 }
16355 node.stateNode = instance;
16356 }
16357 appendChildToContainerChildSet(containerChildSet, instance);
16358 } else if (node.tag === HostText) {
16359 var _instance2 = node.stateNode;
16360 if (needsVisibilityToggle) {
16361 var text = node.memoizedProps;
16362 var rootContainerInstance = getRootHostContainer();
16363 var currentHostContext = getHostContext();
16364 if (isHidden) {
16365 _instance2 = createHiddenTextInstance(text, rootContainerInstance, currentHostContext, workInProgress);
16366 } else {
16367 _instance2 = createTextInstance(text, rootContainerInstance, currentHostContext, workInProgress);
16368 }
16369 node.stateNode = _instance2;
16370 }
16371 appendChildToContainerChildSet(containerChildSet, _instance2);
16372 } else if (node.tag === HostPortal) {
16373 // If we have a portal child, then we don't want to traverse
16374 // down its children. Instead, we'll get insertions from each child in
16375 // the portal directly.
16376 } else if (node.tag === SuspenseComponent) {
16377 var current = node.alternate;
16378 if (current !== null) {
16379 var oldState = current.memoizedState;
16380 var newState = node.memoizedState;
16381 var oldIsHidden = oldState !== null;
16382 var newIsHidden = newState !== null;
16383 if (oldIsHidden !== newIsHidden) {
16384 // The placeholder either just timed out or switched back to the normal
16385 // children after having previously timed out. Toggle the visibility of
16386 // the direct host children.
16387 var primaryChildParent = newIsHidden ? node.child : node;
16388 if (primaryChildParent !== null) {
16389 appendAllChildrenToContainer(containerChildSet, primaryChildParent, true, newIsHidden);
16390 }
16391 // eslint-disable-next-line no-labels
16392 break branches;
16393 }
16394 }
16395 if (node.child !== null) {
16396 // Continue traversing like normal
16397 node.child.return = node;
16398 node = node.child;
16399 continue;
16400 }
16401 } else if (node.child !== null) {
16402 node.child.return = node;
16403 node = node.child;
16404 continue;
16405 }
16406 // $FlowFixMe This is correct but Flow is confused by the labeled break.
16407 node = node;
16408 if (node === workInProgress) {
16409 return;
16410 }
16411 while (node.sibling === null) {
16412 if (node.return === null || node.return === workInProgress) {
16413 return;
16414 }
16415 node = node.return;
16416 }
16417 node.sibling.return = node.return;
16418 node = node.sibling;
16419 }
16420 };
16421 updateHostContainer = function (workInProgress) {
16422 var portalOrRoot = workInProgress.stateNode;
16423 var childrenUnchanged = workInProgress.firstEffect === null;
16424 if (childrenUnchanged) {
16425 // No changes, just reuse the existing instance.
16426 } else {
16427 var container = portalOrRoot.containerInfo;
16428 var newChildSet = createContainerChildSet(container);
16429 // If children might have changed, we have to add them all to the set.
16430 appendAllChildrenToContainer(newChildSet, workInProgress, false, false);
16431 portalOrRoot.pendingChildren = newChildSet;
16432 // Schedule an update on the container to swap out the container.
16433 markUpdate(workInProgress);
16434 finalizeContainerChildren(container, newChildSet);
16435 }
16436 };
16437 updateHostComponent$1 = function (current, workInProgress, type, newProps, rootContainerInstance) {
16438 var currentInstance = current.stateNode;
16439 var oldProps = current.memoizedProps;
16440 // If there are no effects associated with this node, then none of our children had any updates.
16441 // This guarantees that we can reuse all of them.
16442 var childrenUnchanged = workInProgress.firstEffect === null;
16443 if (childrenUnchanged && oldProps === newProps) {
16444 // No changes, just reuse the existing instance.
16445 // Note that this might release a previous clone.
16446 workInProgress.stateNode = currentInstance;
16447 return;
16448 }
16449 var recyclableInstance = workInProgress.stateNode;
16450 var currentHostContext = getHostContext();
16451 var updatePayload = null;
16452 if (oldProps !== newProps) {
16453 updatePayload = prepareUpdate(recyclableInstance, type, oldProps, newProps, rootContainerInstance, currentHostContext);
16454 }
16455 if (childrenUnchanged && updatePayload === null) {
16456 // No changes, just reuse the existing instance.
16457 // Note that this might release a previous clone.
16458 workInProgress.stateNode = currentInstance;
16459 return;
16460 }
16461 var newInstance = cloneInstance(currentInstance, updatePayload, type, oldProps, newProps, workInProgress, childrenUnchanged, recyclableInstance);
16462 if (finalizeInitialChildren(newInstance, type, newProps, rootContainerInstance, currentHostContext)) {
16463 markUpdate(workInProgress);
16464 }
16465 workInProgress.stateNode = newInstance;
16466 if (childrenUnchanged) {
16467 // If there are no other effects in this tree, we need to flag this node as having one.
16468 // Even though we're not going to use it for anything.
16469 // Otherwise parents won't know that there are new children to propagate upwards.
16470 markUpdate(workInProgress);
16471 } else {
16472 // If children might have changed, we have to add them all to the set.
16473 appendAllChildren(newInstance, workInProgress, false, false);
16474 }
16475 };
16476 updateHostText$1 = function (current, workInProgress, oldText, newText) {
16477 if (oldText !== newText) {
16478 // If the text content differs, we'll create a new text instance for it.
16479 var rootContainerInstance = getRootHostContainer();
16480 var currentHostContext = getHostContext();
16481 workInProgress.stateNode = createTextInstance(newText, rootContainerInstance, currentHostContext, workInProgress);
16482 // We'll have to mark it as having an effect, even though we won't use the effect for anything.
16483 // This lets the parents know that at least one of their children has changed.
16484 markUpdate(workInProgress);
16485 }
16486 };
16487} else {
16488 // No host operations
16489 updateHostContainer = function (workInProgress) {
16490 // Noop
16491 };
16492 updateHostComponent$1 = function (current, workInProgress, type, newProps, rootContainerInstance) {
16493 // Noop
16494 };
16495 updateHostText$1 = function (current, workInProgress, oldText, newText) {
16496 // Noop
16497 };
16498}
16499
16500function completeWork(current, workInProgress, renderExpirationTime) {
16501 var newProps = workInProgress.pendingProps;
16502
16503 switch (workInProgress.tag) {
16504 case IndeterminateComponent:
16505 break;
16506 case LazyComponent:
16507 break;
16508 case SimpleMemoComponent:
16509 case FunctionComponent:
16510 break;
16511 case ClassComponent:
16512 {
16513 var Component = workInProgress.type;
16514 if (isContextProvider(Component)) {
16515 popContext(workInProgress);
16516 }
16517 break;
16518 }
16519 case HostRoot:
16520 {
16521 popHostContainer(workInProgress);
16522 popTopLevelContextObject(workInProgress);
16523 var fiberRoot = workInProgress.stateNode;
16524 if (fiberRoot.pendingContext) {
16525 fiberRoot.context = fiberRoot.pendingContext;
16526 fiberRoot.pendingContext = null;
16527 }
16528 if (current === null || current.child === null) {
16529 // If we hydrated, pop so that we can delete any remaining children
16530 // that weren't hydrated.
16531 popHydrationState(workInProgress);
16532 // This resets the hacky state to fix isMounted before committing.
16533 // TODO: Delete this when we delete isMounted and findDOMNode.
16534 workInProgress.effectTag &= ~Placement;
16535 }
16536 updateHostContainer(workInProgress);
16537 break;
16538 }
16539 case HostComponent:
16540 {
16541 popHostContext(workInProgress);
16542 var rootContainerInstance = getRootHostContainer();
16543 var type = workInProgress.type;
16544 if (current !== null && workInProgress.stateNode != null) {
16545 updateHostComponent$1(current, workInProgress, type, newProps, rootContainerInstance);
16546
16547 if (current.ref !== workInProgress.ref) {
16548 markRef$1(workInProgress);
16549 }
16550 } else {
16551 if (!newProps) {
16552 !(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;
16553 // This can happen when we abort work.
16554 break;
16555 }
16556
16557 var currentHostContext = getHostContext();
16558 // TODO: Move createInstance to beginWork and keep it on a context
16559 // "stack" as the parent. Then append children as we go in beginWork
16560 // or completeWork depending on we want to add then top->down or
16561 // bottom->up. Top->down is faster in IE11.
16562 var wasHydrated = popHydrationState(workInProgress);
16563 if (wasHydrated) {
16564 // TODO: Move this and createInstance step into the beginPhase
16565 // to consolidate.
16566 if (prepareToHydrateHostInstance(workInProgress, rootContainerInstance, currentHostContext)) {
16567 // If changes to the hydrated node needs to be applied at the
16568 // commit-phase we mark this as such.
16569 markUpdate(workInProgress);
16570 }
16571 } else {
16572 var instance = createInstance(type, newProps, rootContainerInstance, currentHostContext, workInProgress);
16573
16574 appendAllChildren(instance, workInProgress, false, false);
16575
16576 // Certain renderers require commit-time effects for initial mount.
16577 // (eg DOM renderer supports auto-focus for certain elements).
16578 // Make sure such renderers get scheduled for later work.
16579 if (finalizeInitialChildren(instance, type, newProps, rootContainerInstance, currentHostContext)) {
16580 markUpdate(workInProgress);
16581 }
16582 workInProgress.stateNode = instance;
16583 }
16584
16585 if (workInProgress.ref !== null) {
16586 // If there is a ref on a host node we need to schedule a callback
16587 markRef$1(workInProgress);
16588 }
16589 }
16590 break;
16591 }
16592 case HostText:
16593 {
16594 var newText = newProps;
16595 if (current && workInProgress.stateNode != null) {
16596 var oldText = current.memoizedProps;
16597 // If we have an alternate, that means this is an update and we need
16598 // to schedule a side-effect to do the updates.
16599 updateHostText$1(current, workInProgress, oldText, newText);
16600 } else {
16601 if (typeof newText !== 'string') {
16602 !(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;
16603 // This can happen when we abort work.
16604 }
16605 var _rootContainerInstance = getRootHostContainer();
16606 var _currentHostContext = getHostContext();
16607 var _wasHydrated = popHydrationState(workInProgress);
16608 if (_wasHydrated) {
16609 if (prepareToHydrateHostTextInstance(workInProgress)) {
16610 markUpdate(workInProgress);
16611 }
16612 } else {
16613 workInProgress.stateNode = createTextInstance(newText, _rootContainerInstance, _currentHostContext, workInProgress);
16614 }
16615 }
16616 break;
16617 }
16618 case ForwardRef:
16619 break;
16620 case SuspenseComponent:
16621 {
16622 var nextState = workInProgress.memoizedState;
16623 if ((workInProgress.effectTag & DidCapture) !== NoEffect) {
16624 // Something suspended. Re-render with the fallback children.
16625 workInProgress.expirationTime = renderExpirationTime;
16626 // Do not reset the effect list.
16627 return workInProgress;
16628 }
16629
16630 var nextDidTimeout = nextState !== null;
16631 var prevDidTimeout = current !== null && current.memoizedState !== null;
16632
16633 if (current !== null && !nextDidTimeout && prevDidTimeout) {
16634 // We just switched from the fallback to the normal children. Delete
16635 // the fallback.
16636 // TODO: Would it be better to store the fallback fragment on
16637 var currentFallbackChild = current.child.sibling;
16638 if (currentFallbackChild !== null) {
16639 // Deletions go at the beginning of the return fiber's effect list
16640 var first = workInProgress.firstEffect;
16641 if (first !== null) {
16642 workInProgress.firstEffect = currentFallbackChild;
16643 currentFallbackChild.nextEffect = first;
16644 } else {
16645 workInProgress.firstEffect = workInProgress.lastEffect = currentFallbackChild;
16646 currentFallbackChild.nextEffect = null;
16647 }
16648 currentFallbackChild.effectTag = Deletion;
16649 }
16650 }
16651
16652 if (nextDidTimeout || prevDidTimeout) {
16653 // If the children are hidden, or if they were previous hidden, schedule
16654 // an effect to toggle their visibility. This is also used to attach a
16655 // retry listener to the promise.
16656 workInProgress.effectTag |= Update;
16657 }
16658 break;
16659 }
16660 case Fragment:
16661 break;
16662 case Mode:
16663 break;
16664 case Profiler:
16665 break;
16666 case HostPortal:
16667 popHostContainer(workInProgress);
16668 updateHostContainer(workInProgress);
16669 break;
16670 case ContextProvider:
16671 // Pop provider fiber
16672 popProvider(workInProgress);
16673 break;
16674 case ContextConsumer:
16675 break;
16676 case MemoComponent:
16677 break;
16678 case IncompleteClassComponent:
16679 {
16680 // Same as class component case. I put it down here so that the tags are
16681 // sequential to ensure this switch is compiled to a jump table.
16682 var _Component = workInProgress.type;
16683 if (isContextProvider(_Component)) {
16684 popContext(workInProgress);
16685 }
16686 break;
16687 }
16688 default:
16689 invariant(false, 'Unknown unit of work tag. This error is likely caused by a bug in React. Please file an issue.');
16690 }
16691
16692 return null;
16693}
16694
16695function shouldCaptureSuspense(workInProgress) {
16696 // In order to capture, the Suspense component must have a fallback prop.
16697 if (workInProgress.memoizedProps.fallback === undefined) {
16698 return false;
16699 }
16700 // If it was the primary children that just suspended, capture and render the
16701 // fallback. Otherwise, don't capture and bubble to the next boundary.
16702 var nextState = workInProgress.memoizedState;
16703 return nextState === null;
16704}
16705
16706// This module is forked in different environments.
16707// By default, return `true` to log errors to the console.
16708// Forks can return `false` if this isn't desirable.
16709function showErrorDialog(capturedError) {
16710 return true;
16711}
16712
16713function logCapturedError(capturedError) {
16714 var logError = showErrorDialog(capturedError);
16715
16716 // Allow injected showErrorDialog() to prevent default console.error logging.
16717 // This enables renderers like ReactNative to better manage redbox behavior.
16718 if (logError === false) {
16719 return;
16720 }
16721
16722 var error = capturedError.error;
16723 {
16724 var componentName = capturedError.componentName,
16725 componentStack = capturedError.componentStack,
16726 errorBoundaryName = capturedError.errorBoundaryName,
16727 errorBoundaryFound = capturedError.errorBoundaryFound,
16728 willRetry = capturedError.willRetry;
16729
16730 // Browsers support silencing uncaught errors by calling
16731 // `preventDefault()` in window `error` handler.
16732 // We record this information as an expando on the error.
16733
16734 if (error != null && error._suppressLogging) {
16735 if (errorBoundaryFound && willRetry) {
16736 // The error is recoverable and was silenced.
16737 // Ignore it and don't print the stack addendum.
16738 // This is handy for testing error boundaries without noise.
16739 return;
16740 }
16741 // The error is fatal. Since the silencing might have
16742 // been accidental, we'll surface it anyway.
16743 // However, the browser would have silenced the original error
16744 // so we'll print it first, and then print the stack addendum.
16745 console.error(error);
16746 // For a more detailed description of this block, see:
16747 // https://github.com/facebook/react/pull/13384
16748 }
16749
16750 var componentNameMessage = componentName ? 'The above error occurred in the <' + componentName + '> component:' : 'The above error occurred in one of your React components:';
16751
16752 var errorBoundaryMessage = void 0;
16753 // errorBoundaryFound check is sufficient; errorBoundaryName check is to satisfy Flow.
16754 if (errorBoundaryFound && errorBoundaryName) {
16755 if (willRetry) {
16756 errorBoundaryMessage = 'React will try to recreate this component tree from scratch ' + ('using the error boundary you provided, ' + errorBoundaryName + '.');
16757 } else {
16758 errorBoundaryMessage = 'This error was initially handled by the error boundary ' + errorBoundaryName + '.\n' + 'Recreating the tree from scratch failed so React will unmount the tree.';
16759 }
16760 } else {
16761 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.';
16762 }
16763 var combinedMessage = '' + componentNameMessage + componentStack + '\n\n' + ('' + errorBoundaryMessage);
16764
16765 // In development, we provide our own message with just the component stack.
16766 // We don't include the original error message and JS stack because the browser
16767 // has already printed it. Even if the application swallows the error, it is still
16768 // displayed by the browser thanks to the DEV-only fake event trick in ReactErrorUtils.
16769 console.error(combinedMessage);
16770 }
16771}
16772
16773var didWarnAboutUndefinedSnapshotBeforeUpdate = null;
16774{
16775 didWarnAboutUndefinedSnapshotBeforeUpdate = new Set();
16776}
16777
16778var PossiblyWeakSet = typeof WeakSet === 'function' ? WeakSet : Set;
16779
16780function logError(boundary, errorInfo) {
16781 var source = errorInfo.source;
16782 var stack = errorInfo.stack;
16783 if (stack === null && source !== null) {
16784 stack = getStackByFiberInDevAndProd(source);
16785 }
16786
16787 var capturedError = {
16788 componentName: source !== null ? getComponentName(source.type) : null,
16789 componentStack: stack !== null ? stack : '',
16790 error: errorInfo.value,
16791 errorBoundary: null,
16792 errorBoundaryName: null,
16793 errorBoundaryFound: false,
16794 willRetry: false
16795 };
16796
16797 if (boundary !== null && boundary.tag === ClassComponent) {
16798 capturedError.errorBoundary = boundary.stateNode;
16799 capturedError.errorBoundaryName = getComponentName(boundary.type);
16800 capturedError.errorBoundaryFound = true;
16801 capturedError.willRetry = true;
16802 }
16803
16804 try {
16805 logCapturedError(capturedError);
16806 } catch (e) {
16807 // This method must not throw, or React internal state will get messed up.
16808 // If console.error is overridden, or logCapturedError() shows a dialog that throws,
16809 // we want to report this error outside of the normal stack as a last resort.
16810 // https://github.com/facebook/react/issues/13188
16811 setTimeout(function () {
16812 throw e;
16813 });
16814 }
16815}
16816
16817var callComponentWillUnmountWithTimer = function (current$$1, instance) {
16818 startPhaseTimer(current$$1, 'componentWillUnmount');
16819 instance.props = current$$1.memoizedProps;
16820 instance.state = current$$1.memoizedState;
16821 instance.componentWillUnmount();
16822 stopPhaseTimer();
16823};
16824
16825// Capture errors so they don't interrupt unmounting.
16826function safelyCallComponentWillUnmount(current$$1, instance) {
16827 {
16828 invokeGuardedCallback(null, callComponentWillUnmountWithTimer, null, current$$1, instance);
16829 if (hasCaughtError()) {
16830 var unmountError = clearCaughtError();
16831 captureCommitPhaseError(current$$1, unmountError);
16832 }
16833 }
16834}
16835
16836function safelyDetachRef(current$$1) {
16837 var ref = current$$1.ref;
16838 if (ref !== null) {
16839 if (typeof ref === 'function') {
16840 {
16841 invokeGuardedCallback(null, ref, null, null);
16842 if (hasCaughtError()) {
16843 var refError = clearCaughtError();
16844 captureCommitPhaseError(current$$1, refError);
16845 }
16846 }
16847 } else {
16848 ref.current = null;
16849 }
16850 }
16851}
16852
16853function safelyCallDestroy(current$$1, destroy) {
16854 {
16855 invokeGuardedCallback(null, destroy, null);
16856 if (hasCaughtError()) {
16857 var error = clearCaughtError();
16858 captureCommitPhaseError(current$$1, error);
16859 }
16860 }
16861}
16862
16863function commitBeforeMutationLifeCycles(current$$1, finishedWork) {
16864 switch (finishedWork.tag) {
16865 case FunctionComponent:
16866 case ForwardRef:
16867 case SimpleMemoComponent:
16868 {
16869 commitHookEffectList(UnmountSnapshot, NoEffect$1, finishedWork);
16870 return;
16871 }
16872 case ClassComponent:
16873 {
16874 if (finishedWork.effectTag & Snapshot) {
16875 if (current$$1 !== null) {
16876 var prevProps = current$$1.memoizedProps;
16877 var prevState = current$$1.memoizedState;
16878 startPhaseTimer(finishedWork, 'getSnapshotBeforeUpdate');
16879 var instance = finishedWork.stateNode;
16880 // We could update instance props and state here,
16881 // but instead we rely on them being set during last render.
16882 // TODO: revisit this when we implement resuming.
16883 {
16884 if (finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps) {
16885 !(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;
16886 !(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;
16887 }
16888 }
16889 var snapshot = instance.getSnapshotBeforeUpdate(finishedWork.elementType === finishedWork.type ? prevProps : resolveDefaultProps(finishedWork.type, prevProps), prevState);
16890 {
16891 var didWarnSet = didWarnAboutUndefinedSnapshotBeforeUpdate;
16892 if (snapshot === undefined && !didWarnSet.has(finishedWork.type)) {
16893 didWarnSet.add(finishedWork.type);
16894 warningWithoutStack$1(false, '%s.getSnapshotBeforeUpdate(): A snapshot value (or null) ' + 'must be returned. You have returned undefined.', getComponentName(finishedWork.type));
16895 }
16896 }
16897 instance.__reactInternalSnapshotBeforeUpdate = snapshot;
16898 stopPhaseTimer();
16899 }
16900 }
16901 return;
16902 }
16903 case HostRoot:
16904 case HostComponent:
16905 case HostText:
16906 case HostPortal:
16907 case IncompleteClassComponent:
16908 // Nothing to do for these component types
16909 return;
16910 default:
16911 {
16912 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.');
16913 }
16914 }
16915}
16916
16917function commitHookEffectList(unmountTag, mountTag, finishedWork) {
16918 var updateQueue = finishedWork.updateQueue;
16919 var lastEffect = updateQueue !== null ? updateQueue.lastEffect : null;
16920 if (lastEffect !== null) {
16921 var firstEffect = lastEffect.next;
16922 var effect = firstEffect;
16923 do {
16924 if ((effect.tag & unmountTag) !== NoEffect$1) {
16925 // Unmount
16926 var destroy = effect.destroy;
16927 effect.destroy = undefined;
16928 if (destroy !== undefined) {
16929 destroy();
16930 }
16931 }
16932 if ((effect.tag & mountTag) !== NoEffect$1) {
16933 // Mount
16934 var create = effect.create;
16935 effect.destroy = create();
16936
16937 {
16938 var _destroy = effect.destroy;
16939 if (_destroy !== undefined && typeof _destroy !== 'function') {
16940 var addendum = void 0;
16941 if (_destroy === null) {
16942 addendum = ' You returned null. If your effect does not require clean ' + 'up, return undefined (or nothing).';
16943 } else if (typeof _destroy.then === 'function') {
16944 addendum = '\n\nIt looks like you wrote useEffect(async () => ...) or returned a Promise. ' + 'Instead, you may write an async function separately ' + 'and then call it from inside the effect:\n\n' + 'async function fetchComment(commentId) {\n' + ' // You can await here\n' + '}\n\n' + 'useEffect(() => {\n' + ' fetchComment(commentId);\n' + '}, [commentId]);\n\n' + 'In the future, React will provide a more idiomatic solution for data fetching ' + "that doesn't involve writing effects manually.";
16945 } else {
16946 addendum = ' You returned: ' + _destroy;
16947 }
16948 warningWithoutStack$1(false, 'An Effect function must not return anything besides a function, ' + 'which is used for clean-up.%s%s', addendum, getStackByFiberInDevAndProd(finishedWork));
16949 }
16950 }
16951 }
16952 effect = effect.next;
16953 } while (effect !== firstEffect);
16954 }
16955}
16956
16957function commitPassiveHookEffects(finishedWork) {
16958 commitHookEffectList(UnmountPassive, NoEffect$1, finishedWork);
16959 commitHookEffectList(NoEffect$1, MountPassive, finishedWork);
16960}
16961
16962function commitLifeCycles(finishedRoot, current$$1, finishedWork, committedExpirationTime) {
16963 switch (finishedWork.tag) {
16964 case FunctionComponent:
16965 case ForwardRef:
16966 case SimpleMemoComponent:
16967 {
16968 commitHookEffectList(UnmountLayout, MountLayout, finishedWork);
16969 break;
16970 }
16971 case ClassComponent:
16972 {
16973 var instance = finishedWork.stateNode;
16974 if (finishedWork.effectTag & Update) {
16975 if (current$$1 === null) {
16976 startPhaseTimer(finishedWork, 'componentDidMount');
16977 // We could update instance props and state here,
16978 // but instead we rely on them being set during last render.
16979 // TODO: revisit this when we implement resuming.
16980 {
16981 if (finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps) {
16982 !(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;
16983 !(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;
16984 }
16985 }
16986 instance.componentDidMount();
16987 stopPhaseTimer();
16988 } else {
16989 var prevProps = finishedWork.elementType === finishedWork.type ? current$$1.memoizedProps : resolveDefaultProps(finishedWork.type, current$$1.memoizedProps);
16990 var prevState = current$$1.memoizedState;
16991 startPhaseTimer(finishedWork, 'componentDidUpdate');
16992 // We could update instance props and state here,
16993 // but instead we rely on them being set during last render.
16994 // TODO: revisit this when we implement resuming.
16995 {
16996 if (finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps) {
16997 !(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;
16998 !(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;
16999 }
17000 }
17001 instance.componentDidUpdate(prevProps, prevState, instance.__reactInternalSnapshotBeforeUpdate);
17002 stopPhaseTimer();
17003 }
17004 }
17005 var updateQueue = finishedWork.updateQueue;
17006 if (updateQueue !== null) {
17007 {
17008 if (finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps) {
17009 !(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;
17010 !(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;
17011 }
17012 }
17013 // We could update instance props and state here,
17014 // but instead we rely on them being set during last render.
17015 // TODO: revisit this when we implement resuming.
17016 commitUpdateQueue(finishedWork, updateQueue, instance, committedExpirationTime);
17017 }
17018 return;
17019 }
17020 case HostRoot:
17021 {
17022 var _updateQueue = finishedWork.updateQueue;
17023 if (_updateQueue !== null) {
17024 var _instance = null;
17025 if (finishedWork.child !== null) {
17026 switch (finishedWork.child.tag) {
17027 case HostComponent:
17028 _instance = getPublicInstance(finishedWork.child.stateNode);
17029 break;
17030 case ClassComponent:
17031 _instance = finishedWork.child.stateNode;
17032 break;
17033 }
17034 }
17035 commitUpdateQueue(finishedWork, _updateQueue, _instance, committedExpirationTime);
17036 }
17037 return;
17038 }
17039 case HostComponent:
17040 {
17041 var _instance2 = finishedWork.stateNode;
17042
17043 // Renderers may schedule work to be done after host components are mounted
17044 // (eg DOM renderer may schedule auto-focus for inputs and form controls).
17045 // These effects should only be committed when components are first mounted,
17046 // aka when there is no current/alternate.
17047 if (current$$1 === null && finishedWork.effectTag & Update) {
17048 var type = finishedWork.type;
17049 var props = finishedWork.memoizedProps;
17050 commitMount(_instance2, type, props, finishedWork);
17051 }
17052
17053 return;
17054 }
17055 case HostText:
17056 {
17057 // We have no life-cycles associated with text.
17058 return;
17059 }
17060 case HostPortal:
17061 {
17062 // We have no life-cycles associated with portals.
17063 return;
17064 }
17065 case Profiler:
17066 {
17067 if (enableProfilerTimer) {
17068 var onRender = finishedWork.memoizedProps.onRender;
17069
17070 if (enableSchedulerTracing) {
17071 onRender(finishedWork.memoizedProps.id, current$$1 === null ? 'mount' : 'update', finishedWork.actualDuration, finishedWork.treeBaseDuration, finishedWork.actualStartTime, getCommitTime(), finishedRoot.memoizedInteractions);
17072 } else {
17073 onRender(finishedWork.memoizedProps.id, current$$1 === null ? 'mount' : 'update', finishedWork.actualDuration, finishedWork.treeBaseDuration, finishedWork.actualStartTime, getCommitTime());
17074 }
17075 }
17076 return;
17077 }
17078 case SuspenseComponent:
17079 break;
17080 case IncompleteClassComponent:
17081 break;
17082 default:
17083 {
17084 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.');
17085 }
17086 }
17087}
17088
17089function hideOrUnhideAllChildren(finishedWork, isHidden) {
17090 if (supportsMutation) {
17091 // We only have the top Fiber that was inserted but we need recurse down its
17092 var node = finishedWork;
17093 while (true) {
17094 if (node.tag === HostComponent) {
17095 var instance = node.stateNode;
17096 if (isHidden) {
17097 hideInstance(instance);
17098 } else {
17099 unhideInstance(node.stateNode, node.memoizedProps);
17100 }
17101 } else if (node.tag === HostText) {
17102 var _instance3 = node.stateNode;
17103 if (isHidden) {
17104 hideTextInstance(_instance3);
17105 } else {
17106 unhideTextInstance(_instance3, node.memoizedProps);
17107 }
17108 } else if (node.tag === SuspenseComponent && node.memoizedState !== null) {
17109 // Found a nested Suspense component that timed out. Skip over the
17110 var fallbackChildFragment = node.child.sibling;
17111 fallbackChildFragment.return = node;
17112 node = fallbackChildFragment;
17113 continue;
17114 } else if (node.child !== null) {
17115 node.child.return = node;
17116 node = node.child;
17117 continue;
17118 }
17119 if (node === finishedWork) {
17120 return;
17121 }
17122 while (node.sibling === null) {
17123 if (node.return === null || node.return === finishedWork) {
17124 return;
17125 }
17126 node = node.return;
17127 }
17128 node.sibling.return = node.return;
17129 node = node.sibling;
17130 }
17131 }
17132}
17133
17134function commitAttachRef(finishedWork) {
17135 var ref = finishedWork.ref;
17136 if (ref !== null) {
17137 var instance = finishedWork.stateNode;
17138 var instanceToUse = void 0;
17139 switch (finishedWork.tag) {
17140 case HostComponent:
17141 instanceToUse = getPublicInstance(instance);
17142 break;
17143 default:
17144 instanceToUse = instance;
17145 }
17146 if (typeof ref === 'function') {
17147 ref(instanceToUse);
17148 } else {
17149 {
17150 if (!ref.hasOwnProperty('current')) {
17151 warningWithoutStack$1(false, 'Unexpected ref object provided for %s. ' + 'Use either a ref-setter function or React.createRef().%s', getComponentName(finishedWork.type), getStackByFiberInDevAndProd(finishedWork));
17152 }
17153 }
17154
17155 ref.current = instanceToUse;
17156 }
17157 }
17158}
17159
17160function commitDetachRef(current$$1) {
17161 var currentRef = current$$1.ref;
17162 if (currentRef !== null) {
17163 if (typeof currentRef === 'function') {
17164 currentRef(null);
17165 } else {
17166 currentRef.current = null;
17167 }
17168 }
17169}
17170
17171// User-originating errors (lifecycles and refs) should not interrupt
17172// deletion, so don't let them throw. Host-originating errors should
17173// interrupt deletion, so it's okay
17174function commitUnmount(current$$1) {
17175 onCommitUnmount(current$$1);
17176
17177 switch (current$$1.tag) {
17178 case FunctionComponent:
17179 case ForwardRef:
17180 case MemoComponent:
17181 case SimpleMemoComponent:
17182 {
17183 var updateQueue = current$$1.updateQueue;
17184 if (updateQueue !== null) {
17185 var lastEffect = updateQueue.lastEffect;
17186 if (lastEffect !== null) {
17187 var firstEffect = lastEffect.next;
17188 var effect = firstEffect;
17189 do {
17190 var destroy = effect.destroy;
17191 if (destroy !== undefined) {
17192 safelyCallDestroy(current$$1, destroy);
17193 }
17194 effect = effect.next;
17195 } while (effect !== firstEffect);
17196 }
17197 }
17198 break;
17199 }
17200 case ClassComponent:
17201 {
17202 safelyDetachRef(current$$1);
17203 var instance = current$$1.stateNode;
17204 if (typeof instance.componentWillUnmount === 'function') {
17205 safelyCallComponentWillUnmount(current$$1, instance);
17206 }
17207 return;
17208 }
17209 case HostComponent:
17210 {
17211 safelyDetachRef(current$$1);
17212 return;
17213 }
17214 case HostPortal:
17215 {
17216 // TODO: this is recursive.
17217 // We are also not using this parent because
17218 // the portal will get pushed immediately.
17219 if (supportsMutation) {
17220 unmountHostComponents(current$$1);
17221 } else if (supportsPersistence) {
17222 emptyPortalContainer(current$$1);
17223 }
17224 return;
17225 }
17226 }
17227}
17228
17229function commitNestedUnmounts(root) {
17230 // While we're inside a removed host node we don't want to call
17231 // removeChild on the inner nodes because they're removed by the top
17232 // call anyway. We also want to call componentWillUnmount on all
17233 // composites before this host node is removed from the tree. Therefore
17234 var node = root;
17235 while (true) {
17236 commitUnmount(node);
17237 // Visit children because they may contain more composite or host nodes.
17238 // Skip portals because commitUnmount() currently visits them recursively.
17239 if (node.child !== null && (
17240 // If we use mutation we drill down into portals using commitUnmount above.
17241 // If we don't use mutation we drill down into portals here instead.
17242 !supportsMutation || node.tag !== HostPortal)) {
17243 node.child.return = node;
17244 node = node.child;
17245 continue;
17246 }
17247 if (node === root) {
17248 return;
17249 }
17250 while (node.sibling === null) {
17251 if (node.return === null || node.return === root) {
17252 return;
17253 }
17254 node = node.return;
17255 }
17256 node.sibling.return = node.return;
17257 node = node.sibling;
17258 }
17259}
17260
17261function detachFiber(current$$1) {
17262 // Cut off the return pointers to disconnect it from the tree. Ideally, we
17263 // should clear the child pointer of the parent alternate to let this
17264 // get GC:ed but we don't know which for sure which parent is the current
17265 // one so we'll settle for GC:ing the subtree of this child. This child
17266 // itself will be GC:ed when the parent updates the next time.
17267 current$$1.return = null;
17268 current$$1.child = null;
17269 current$$1.memoizedState = null;
17270 current$$1.updateQueue = null;
17271 var alternate = current$$1.alternate;
17272 if (alternate !== null) {
17273 alternate.return = null;
17274 alternate.child = null;
17275 alternate.memoizedState = null;
17276 alternate.updateQueue = null;
17277 }
17278}
17279
17280function emptyPortalContainer(current$$1) {
17281 if (!supportsPersistence) {
17282 return;
17283 }
17284
17285 var portal = current$$1.stateNode;
17286 var containerInfo = portal.containerInfo;
17287
17288 var emptyChildSet = createContainerChildSet(containerInfo);
17289 replaceContainerChildren(containerInfo, emptyChildSet);
17290}
17291
17292function commitContainer(finishedWork) {
17293 if (!supportsPersistence) {
17294 return;
17295 }
17296
17297 switch (finishedWork.tag) {
17298 case ClassComponent:
17299 {
17300 return;
17301 }
17302 case HostComponent:
17303 {
17304 return;
17305 }
17306 case HostText:
17307 {
17308 return;
17309 }
17310 case HostRoot:
17311 case HostPortal:
17312 {
17313 var portalOrRoot = finishedWork.stateNode;
17314 var containerInfo = portalOrRoot.containerInfo,
17315 _pendingChildren = portalOrRoot.pendingChildren;
17316
17317 replaceContainerChildren(containerInfo, _pendingChildren);
17318 return;
17319 }
17320 default:
17321 {
17322 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.');
17323 }
17324 }
17325}
17326
17327function getHostParentFiber(fiber) {
17328 var parent = fiber.return;
17329 while (parent !== null) {
17330 if (isHostParent(parent)) {
17331 return parent;
17332 }
17333 parent = parent.return;
17334 }
17335 invariant(false, 'Expected to find a host parent. This error is likely caused by a bug in React. Please file an issue.');
17336}
17337
17338function isHostParent(fiber) {
17339 return fiber.tag === HostComponent || fiber.tag === HostRoot || fiber.tag === HostPortal;
17340}
17341
17342function getHostSibling(fiber) {
17343 // We're going to search forward into the tree until we find a sibling host
17344 // node. Unfortunately, if multiple insertions are done in a row we have to
17345 // search past them. This leads to exponential search for the next sibling.
17346 var node = fiber;
17347 siblings: while (true) {
17348 // If we didn't find anything, let's try the next sibling.
17349 while (node.sibling === null) {
17350 if (node.return === null || isHostParent(node.return)) {
17351 // If we pop out of the root or hit the parent the fiber we are the
17352 // last sibling.
17353 return null;
17354 }
17355 node = node.return;
17356 }
17357 node.sibling.return = node.return;
17358 node = node.sibling;
17359 while (node.tag !== HostComponent && node.tag !== HostText) {
17360 // If it is not host node and, we might have a host node inside it.
17361 // Try to search down until we find one.
17362 if (node.effectTag & Placement) {
17363 // If we don't have a child, try the siblings instead.
17364 continue siblings;
17365 }
17366 // If we don't have a child, try the siblings instead.
17367 // We also skip portals because they are not part of this host tree.
17368 if (node.child === null || node.tag === HostPortal) {
17369 continue siblings;
17370 } else {
17371 node.child.return = node;
17372 node = node.child;
17373 }
17374 }
17375 // Check if this host node is stable or about to be placed.
17376 if (!(node.effectTag & Placement)) {
17377 // Found it!
17378 return node.stateNode;
17379 }
17380 }
17381}
17382
17383function commitPlacement(finishedWork) {
17384 if (!supportsMutation) {
17385 return;
17386 }
17387
17388 // Recursively insert all host nodes into the parent.
17389 var parentFiber = getHostParentFiber(finishedWork);
17390
17391 // Note: these two variables *must* always be updated together.
17392 var parent = void 0;
17393 var isContainer = void 0;
17394
17395 switch (parentFiber.tag) {
17396 case HostComponent:
17397 parent = parentFiber.stateNode;
17398 isContainer = false;
17399 break;
17400 case HostRoot:
17401 parent = parentFiber.stateNode.containerInfo;
17402 isContainer = true;
17403 break;
17404 case HostPortal:
17405 parent = parentFiber.stateNode.containerInfo;
17406 isContainer = true;
17407 break;
17408 default:
17409 invariant(false, 'Invalid host parent fiber. This error is likely caused by a bug in React. Please file an issue.');
17410 }
17411 if (parentFiber.effectTag & ContentReset) {
17412 // Reset the text content of the parent before doing any insertions
17413 resetTextContent(parent);
17414 // Clear ContentReset from the effect tag
17415 parentFiber.effectTag &= ~ContentReset;
17416 }
17417
17418 var before = getHostSibling(finishedWork);
17419 // We only have the top Fiber that was inserted but we need recurse down its
17420 // children to find all the terminal nodes.
17421 var node = finishedWork;
17422 while (true) {
17423 if (node.tag === HostComponent || node.tag === HostText) {
17424 if (before) {
17425 if (isContainer) {
17426 insertInContainerBefore(parent, node.stateNode, before);
17427 } else {
17428 insertBefore(parent, node.stateNode, before);
17429 }
17430 } else {
17431 if (isContainer) {
17432 appendChildToContainer(parent, node.stateNode);
17433 } else {
17434 appendChild(parent, node.stateNode);
17435 }
17436 }
17437 } else if (node.tag === HostPortal) {
17438 // If the insertion itself is a portal, then we don't want to traverse
17439 // down its children. Instead, we'll get insertions from each child in
17440 // the portal directly.
17441 } else if (node.child !== null) {
17442 node.child.return = node;
17443 node = node.child;
17444 continue;
17445 }
17446 if (node === finishedWork) {
17447 return;
17448 }
17449 while (node.sibling === null) {
17450 if (node.return === null || node.return === finishedWork) {
17451 return;
17452 }
17453 node = node.return;
17454 }
17455 node.sibling.return = node.return;
17456 node = node.sibling;
17457 }
17458}
17459
17460function unmountHostComponents(current$$1) {
17461 // We only have the top Fiber that was deleted but we need recurse down its
17462 var node = current$$1;
17463
17464 // Each iteration, currentParent is populated with node's host parent if not
17465 // currentParentIsValid.
17466 var currentParentIsValid = false;
17467
17468 // Note: these two variables *must* always be updated together.
17469 var currentParent = void 0;
17470 var currentParentIsContainer = void 0;
17471
17472 while (true) {
17473 if (!currentParentIsValid) {
17474 var parent = node.return;
17475 findParent: while (true) {
17476 !(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;
17477 switch (parent.tag) {
17478 case HostComponent:
17479 currentParent = parent.stateNode;
17480 currentParentIsContainer = false;
17481 break findParent;
17482 case HostRoot:
17483 currentParent = parent.stateNode.containerInfo;
17484 currentParentIsContainer = true;
17485 break findParent;
17486 case HostPortal:
17487 currentParent = parent.stateNode.containerInfo;
17488 currentParentIsContainer = true;
17489 break findParent;
17490 }
17491 parent = parent.return;
17492 }
17493 currentParentIsValid = true;
17494 }
17495
17496 if (node.tag === HostComponent || node.tag === HostText) {
17497 commitNestedUnmounts(node);
17498 // After all the children have unmounted, it is now safe to remove the
17499 // node from the tree.
17500 if (currentParentIsContainer) {
17501 removeChildFromContainer(currentParent, node.stateNode);
17502 } else {
17503 removeChild(currentParent, node.stateNode);
17504 }
17505 // Don't visit children because we already visited them.
17506 } else if (node.tag === HostPortal) {
17507 // When we go into a portal, it becomes the parent to remove from.
17508 // We will reassign it back when we pop the portal on the way up.
17509 currentParent = node.stateNode.containerInfo;
17510 currentParentIsContainer = true;
17511 // Visit children because portals might contain host components.
17512 if (node.child !== null) {
17513 node.child.return = node;
17514 node = node.child;
17515 continue;
17516 }
17517 } else {
17518 commitUnmount(node);
17519 // Visit children because we may find more host components below.
17520 if (node.child !== null) {
17521 node.child.return = node;
17522 node = node.child;
17523 continue;
17524 }
17525 }
17526 if (node === current$$1) {
17527 return;
17528 }
17529 while (node.sibling === null) {
17530 if (node.return === null || node.return === current$$1) {
17531 return;
17532 }
17533 node = node.return;
17534 if (node.tag === HostPortal) {
17535 // When we go out of the portal, we need to restore the parent.
17536 // Since we don't keep a stack of them, we will search for it.
17537 currentParentIsValid = false;
17538 }
17539 }
17540 node.sibling.return = node.return;
17541 node = node.sibling;
17542 }
17543}
17544
17545function commitDeletion(current$$1) {
17546 if (supportsMutation) {
17547 // Recursively delete all host nodes from the parent.
17548 // Detach refs and call componentWillUnmount() on the whole subtree.
17549 unmountHostComponents(current$$1);
17550 } else {
17551 // Detach refs and call componentWillUnmount() on the whole subtree.
17552 commitNestedUnmounts(current$$1);
17553 }
17554 detachFiber(current$$1);
17555}
17556
17557function commitWork(current$$1, finishedWork) {
17558 if (!supportsMutation) {
17559 switch (finishedWork.tag) {
17560 case FunctionComponent:
17561 case ForwardRef:
17562 case MemoComponent:
17563 case SimpleMemoComponent:
17564 {
17565 // Note: We currently never use MountMutation, but useLayout uses
17566 // UnmountMutation.
17567 commitHookEffectList(UnmountMutation, MountMutation, finishedWork);
17568 return;
17569 }
17570 }
17571
17572 commitContainer(finishedWork);
17573 return;
17574 }
17575
17576 switch (finishedWork.tag) {
17577 case FunctionComponent:
17578 case ForwardRef:
17579 case MemoComponent:
17580 case SimpleMemoComponent:
17581 {
17582 // Note: We currently never use MountMutation, but useLayout uses
17583 // UnmountMutation.
17584 commitHookEffectList(UnmountMutation, MountMutation, finishedWork);
17585 return;
17586 }
17587 case ClassComponent:
17588 {
17589 return;
17590 }
17591 case HostComponent:
17592 {
17593 var instance = finishedWork.stateNode;
17594 if (instance != null) {
17595 // Commit the work prepared earlier.
17596 var newProps = finishedWork.memoizedProps;
17597 // For hydration we reuse the update path but we treat the oldProps
17598 // as the newProps. The updatePayload will contain the real change in
17599 // this case.
17600 var oldProps = current$$1 !== null ? current$$1.memoizedProps : newProps;
17601 var type = finishedWork.type;
17602 // TODO: Type the updateQueue to be specific to host components.
17603 var updatePayload = finishedWork.updateQueue;
17604 finishedWork.updateQueue = null;
17605 if (updatePayload !== null) {
17606 commitUpdate(instance, updatePayload, type, oldProps, newProps, finishedWork);
17607 }
17608 }
17609 return;
17610 }
17611 case HostText:
17612 {
17613 !(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;
17614 var textInstance = finishedWork.stateNode;
17615 var newText = finishedWork.memoizedProps;
17616 // For hydration we reuse the update path but we treat the oldProps
17617 // as the newProps. The updatePayload will contain the real change in
17618 // this case.
17619 var oldText = current$$1 !== null ? current$$1.memoizedProps : newText;
17620 commitTextUpdate(textInstance, oldText, newText);
17621 return;
17622 }
17623 case HostRoot:
17624 {
17625 return;
17626 }
17627 case Profiler:
17628 {
17629 return;
17630 }
17631 case SuspenseComponent:
17632 {
17633 var newState = finishedWork.memoizedState;
17634
17635 var newDidTimeout = void 0;
17636 var primaryChildParent = finishedWork;
17637 if (newState === null) {
17638 newDidTimeout = false;
17639 } else {
17640 newDidTimeout = true;
17641 primaryChildParent = finishedWork.child;
17642 if (newState.timedOutAt === NoWork) {
17643 // If the children had not already timed out, record the time.
17644 // This is used to compute the elapsed time during subsequent
17645 // attempts to render the children.
17646 newState.timedOutAt = requestCurrentTime();
17647 }
17648 }
17649
17650 if (primaryChildParent !== null) {
17651 hideOrUnhideAllChildren(primaryChildParent, newDidTimeout);
17652 }
17653
17654 // If this boundary just timed out, then it will have a set of thenables.
17655 // For each thenable, attach a listener so that when it resolves, React
17656 // attempts to re-render the boundary in the primary (pre-timeout) state.
17657 var thenables = finishedWork.updateQueue;
17658 if (thenables !== null) {
17659 finishedWork.updateQueue = null;
17660 var retryCache = finishedWork.stateNode;
17661 if (retryCache === null) {
17662 retryCache = finishedWork.stateNode = new PossiblyWeakSet();
17663 }
17664 thenables.forEach(function (thenable) {
17665 // Memoize using the boundary fiber to prevent redundant listeners.
17666 var retry = retryTimedOutBoundary.bind(null, finishedWork, thenable);
17667 if (enableSchedulerTracing) {
17668 retry = unstable_wrap(retry);
17669 }
17670 if (!retryCache.has(thenable)) {
17671 retryCache.add(thenable);
17672 thenable.then(retry, retry);
17673 }
17674 });
17675 }
17676
17677 return;
17678 }
17679 case IncompleteClassComponent:
17680 {
17681 return;
17682 }
17683 default:
17684 {
17685 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.');
17686 }
17687 }
17688}
17689
17690function commitResetTextContent(current$$1) {
17691 if (!supportsMutation) {
17692 return;
17693 }
17694 resetTextContent(current$$1.stateNode);
17695}
17696
17697var PossiblyWeakMap = typeof WeakMap === 'function' ? WeakMap : Map;
17698
17699function createRootErrorUpdate(fiber, errorInfo, expirationTime) {
17700 var update = createUpdate(expirationTime);
17701 // Unmount the root by rendering null.
17702 update.tag = CaptureUpdate;
17703 // Caution: React DevTools currently depends on this property
17704 // being called "element".
17705 update.payload = { element: null };
17706 var error = errorInfo.value;
17707 update.callback = function () {
17708 onUncaughtError(error);
17709 logError(fiber, errorInfo);
17710 };
17711 return update;
17712}
17713
17714function createClassErrorUpdate(fiber, errorInfo, expirationTime) {
17715 var update = createUpdate(expirationTime);
17716 update.tag = CaptureUpdate;
17717 var getDerivedStateFromError = fiber.type.getDerivedStateFromError;
17718 if (typeof getDerivedStateFromError === 'function') {
17719 var error = errorInfo.value;
17720 update.payload = function () {
17721 return getDerivedStateFromError(error);
17722 };
17723 }
17724
17725 var inst = fiber.stateNode;
17726 if (inst !== null && typeof inst.componentDidCatch === 'function') {
17727 update.callback = function callback() {
17728 if (typeof getDerivedStateFromError !== 'function') {
17729 // To preserve the preexisting retry behavior of error boundaries,
17730 // we keep track of which ones already failed during this batch.
17731 // This gets reset before we yield back to the browser.
17732 // TODO: Warn in strict mode if getDerivedStateFromError is
17733 // not defined.
17734 markLegacyErrorBoundaryAsFailed(this);
17735 }
17736 var error = errorInfo.value;
17737 var stack = errorInfo.stack;
17738 logError(fiber, errorInfo);
17739 this.componentDidCatch(error, {
17740 componentStack: stack !== null ? stack : ''
17741 });
17742 {
17743 if (typeof getDerivedStateFromError !== 'function') {
17744 // If componentDidCatch is the only error boundary method defined,
17745 // then it needs to call setState to recover from errors.
17746 // If no state update is scheduled then the boundary will swallow the error.
17747 !(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;
17748 }
17749 }
17750 };
17751 }
17752 return update;
17753}
17754
17755function throwException(root, returnFiber, sourceFiber, value, renderExpirationTime) {
17756 // The source fiber did not complete.
17757 sourceFiber.effectTag |= Incomplete;
17758 // Its effect list is no longer valid.
17759 sourceFiber.firstEffect = sourceFiber.lastEffect = null;
17760
17761 if (value !== null && typeof value === 'object' && typeof value.then === 'function') {
17762 // This is a thenable.
17763 var thenable = value;
17764
17765 // Find the earliest timeout threshold of all the placeholders in the
17766 // ancestor path. We could avoid this traversal by storing the thresholds on
17767 // the stack, but we choose not to because we only hit this path if we're
17768 // IO-bound (i.e. if something suspends). Whereas the stack is used even in
17769 // the non-IO- bound case.
17770 var _workInProgress = returnFiber;
17771 var earliestTimeoutMs = -1;
17772 var startTimeMs = -1;
17773 do {
17774 if (_workInProgress.tag === SuspenseComponent) {
17775 var current$$1 = _workInProgress.alternate;
17776 if (current$$1 !== null) {
17777 var currentState = current$$1.memoizedState;
17778 if (currentState !== null) {
17779 // Reached a boundary that already timed out. Do not search
17780 // any further.
17781 var timedOutAt = currentState.timedOutAt;
17782 startTimeMs = expirationTimeToMs(timedOutAt);
17783 // Do not search any further.
17784 break;
17785 }
17786 }
17787 var timeoutPropMs = _workInProgress.pendingProps.maxDuration;
17788 if (typeof timeoutPropMs === 'number') {
17789 if (timeoutPropMs <= 0) {
17790 earliestTimeoutMs = 0;
17791 } else if (earliestTimeoutMs === -1 || timeoutPropMs < earliestTimeoutMs) {
17792 earliestTimeoutMs = timeoutPropMs;
17793 }
17794 }
17795 }
17796 _workInProgress = _workInProgress.return;
17797 } while (_workInProgress !== null);
17798
17799 // Schedule the nearest Suspense to re-render the timed out view.
17800 _workInProgress = returnFiber;
17801 do {
17802 if (_workInProgress.tag === SuspenseComponent && shouldCaptureSuspense(_workInProgress)) {
17803 // Found the nearest boundary.
17804
17805 // Stash the promise on the boundary fiber. If the boundary times out, we'll
17806 var thenables = _workInProgress.updateQueue;
17807 if (thenables === null) {
17808 var updateQueue = new Set();
17809 updateQueue.add(thenable);
17810 _workInProgress.updateQueue = updateQueue;
17811 } else {
17812 thenables.add(thenable);
17813 }
17814
17815 // If the boundary is outside of concurrent mode, we should *not*
17816 // suspend the commit. Pretend as if the suspended component rendered
17817 // null and keep rendering. In the commit phase, we'll schedule a
17818 // subsequent synchronous update to re-render the Suspense.
17819 //
17820 // Note: It doesn't matter whether the component that suspended was
17821 // inside a concurrent mode tree. If the Suspense is outside of it, we
17822 // should *not* suspend the commit.
17823 if ((_workInProgress.mode & ConcurrentMode) === NoEffect) {
17824 _workInProgress.effectTag |= DidCapture;
17825
17826 // We're going to commit this fiber even though it didn't complete.
17827 // But we shouldn't call any lifecycle methods or callbacks. Remove
17828 // all lifecycle effect tags.
17829 sourceFiber.effectTag &= ~(LifecycleEffectMask | Incomplete);
17830
17831 if (sourceFiber.tag === ClassComponent) {
17832 var currentSourceFiber = sourceFiber.alternate;
17833 if (currentSourceFiber === null) {
17834 // This is a new mount. Change the tag so it's not mistaken for a
17835 // completed class component. For example, we should not call
17836 // componentWillUnmount if it is deleted.
17837 sourceFiber.tag = IncompleteClassComponent;
17838 } else {
17839 // When we try rendering again, we should not reuse the current fiber,
17840 // since it's known to be in an inconsistent state. Use a force updte to
17841 // prevent a bail out.
17842 var update = createUpdate(Sync);
17843 update.tag = ForceUpdate;
17844 enqueueUpdate(sourceFiber, update);
17845 }
17846 }
17847
17848 // The source fiber did not complete. Mark it with Sync priority to
17849 // indicate that it still has pending work.
17850 sourceFiber.expirationTime = Sync;
17851
17852 // Exit without suspending.
17853 return;
17854 }
17855
17856 // Confirmed that the boundary is in a concurrent mode tree. Continue
17857 // with the normal suspend path.
17858
17859 // Attach a listener to the promise to "ping" the root and retry. But
17860 // only if one does not already exist for the current render expiration
17861 // time (which acts like a "thread ID" here).
17862 var pingCache = root.pingCache;
17863 var threadIDs = void 0;
17864 if (pingCache === null) {
17865 pingCache = root.pingCache = new PossiblyWeakMap();
17866 threadIDs = new Set();
17867 pingCache.set(thenable, threadIDs);
17868 } else {
17869 threadIDs = pingCache.get(thenable);
17870 if (threadIDs === undefined) {
17871 threadIDs = new Set();
17872 pingCache.set(thenable, threadIDs);
17873 }
17874 }
17875 if (!threadIDs.has(renderExpirationTime)) {
17876 // Memoize using the thread ID to prevent redundant listeners.
17877 threadIDs.add(renderExpirationTime);
17878 var ping = pingSuspendedRoot.bind(null, root, thenable, renderExpirationTime);
17879 if (enableSchedulerTracing) {
17880 ping = unstable_wrap(ping);
17881 }
17882 thenable.then(ping, ping);
17883 }
17884
17885 var absoluteTimeoutMs = void 0;
17886 if (earliestTimeoutMs === -1) {
17887 // If no explicit threshold is given, default to an arbitrarily large
17888 // value. The actual size doesn't matter because the threshold for the
17889 // whole tree will be clamped to the expiration time.
17890 absoluteTimeoutMs = maxSigned31BitInt;
17891 } else {
17892 if (startTimeMs === -1) {
17893 // This suspend happened outside of any already timed-out
17894 // placeholders. We don't know exactly when the update was
17895 // scheduled, but we can infer an approximate start time from the
17896 // expiration time. First, find the earliest uncommitted expiration
17897 // time in the tree, including work that is suspended. Then subtract
17898 // the offset used to compute an async update's expiration time.
17899 // This will cause high priority (interactive) work to expire
17900 // earlier than necessary, but we can account for this by adjusting
17901 // for the Just Noticeable Difference.
17902 var earliestExpirationTime = findEarliestOutstandingPriorityLevel(root, renderExpirationTime);
17903 var earliestExpirationTimeMs = expirationTimeToMs(earliestExpirationTime);
17904 startTimeMs = earliestExpirationTimeMs - LOW_PRIORITY_EXPIRATION;
17905 }
17906 absoluteTimeoutMs = startTimeMs + earliestTimeoutMs;
17907 }
17908
17909 // Mark the earliest timeout in the suspended fiber's ancestor path.
17910 // After completing the root, we'll take the largest of all the
17911 // suspended fiber's timeouts and use it to compute a timeout for the
17912 // whole tree.
17913 renderDidSuspend(root, absoluteTimeoutMs, renderExpirationTime);
17914
17915 _workInProgress.effectTag |= ShouldCapture;
17916 _workInProgress.expirationTime = renderExpirationTime;
17917 return;
17918 }
17919 // This boundary already captured during this render. Continue to the next
17920 // boundary.
17921 _workInProgress = _workInProgress.return;
17922 } while (_workInProgress !== null);
17923 // No boundary was found. Fallthrough to error mode.
17924 // TODO: Use invariant so the message is stripped in prod?
17925 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));
17926 }
17927
17928 // We didn't find a boundary that could handle this type of exception. Start
17929 // over and traverse parent path again, this time treating the exception
17930 // as an error.
17931 renderDidError();
17932 value = createCapturedValue(value, sourceFiber);
17933 var workInProgress = returnFiber;
17934 do {
17935 switch (workInProgress.tag) {
17936 case HostRoot:
17937 {
17938 var _errorInfo = value;
17939 workInProgress.effectTag |= ShouldCapture;
17940 workInProgress.expirationTime = renderExpirationTime;
17941 var _update = createRootErrorUpdate(workInProgress, _errorInfo, renderExpirationTime);
17942 enqueueCapturedUpdate(workInProgress, _update);
17943 return;
17944 }
17945 case ClassComponent:
17946 // Capture and retry
17947 var errorInfo = value;
17948 var ctor = workInProgress.type;
17949 var instance = workInProgress.stateNode;
17950 if ((workInProgress.effectTag & DidCapture) === NoEffect && (typeof ctor.getDerivedStateFromError === 'function' || instance !== null && typeof instance.componentDidCatch === 'function' && !isAlreadyFailedLegacyErrorBoundary(instance))) {
17951 workInProgress.effectTag |= ShouldCapture;
17952 workInProgress.expirationTime = renderExpirationTime;
17953 // Schedule the error boundary to re-render using updated state
17954 var _update2 = createClassErrorUpdate(workInProgress, errorInfo, renderExpirationTime);
17955 enqueueCapturedUpdate(workInProgress, _update2);
17956 return;
17957 }
17958 break;
17959 default:
17960 break;
17961 }
17962 workInProgress = workInProgress.return;
17963 } while (workInProgress !== null);
17964}
17965
17966function unwindWork(workInProgress, renderExpirationTime) {
17967 switch (workInProgress.tag) {
17968 case ClassComponent:
17969 {
17970 var Component = workInProgress.type;
17971 if (isContextProvider(Component)) {
17972 popContext(workInProgress);
17973 }
17974 var effectTag = workInProgress.effectTag;
17975 if (effectTag & ShouldCapture) {
17976 workInProgress.effectTag = effectTag & ~ShouldCapture | DidCapture;
17977 return workInProgress;
17978 }
17979 return null;
17980 }
17981 case HostRoot:
17982 {
17983 popHostContainer(workInProgress);
17984 popTopLevelContextObject(workInProgress);
17985 var _effectTag = workInProgress.effectTag;
17986 !((_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;
17987 workInProgress.effectTag = _effectTag & ~ShouldCapture | DidCapture;
17988 return workInProgress;
17989 }
17990 case HostComponent:
17991 {
17992 popHostContext(workInProgress);
17993 return null;
17994 }
17995 case SuspenseComponent:
17996 {
17997 var _effectTag2 = workInProgress.effectTag;
17998 if (_effectTag2 & ShouldCapture) {
17999 workInProgress.effectTag = _effectTag2 & ~ShouldCapture | DidCapture;
18000 // Captured a suspense effect. Re-render the boundary.
18001 return workInProgress;
18002 }
18003 return null;
18004 }
18005 case HostPortal:
18006 popHostContainer(workInProgress);
18007 return null;
18008 case ContextProvider:
18009 popProvider(workInProgress);
18010 return null;
18011 default:
18012 return null;
18013 }
18014}
18015
18016function unwindInterruptedWork(interruptedWork) {
18017 switch (interruptedWork.tag) {
18018 case ClassComponent:
18019 {
18020 var childContextTypes = interruptedWork.type.childContextTypes;
18021 if (childContextTypes !== null && childContextTypes !== undefined) {
18022 popContext(interruptedWork);
18023 }
18024 break;
18025 }
18026 case HostRoot:
18027 {
18028 popHostContainer(interruptedWork);
18029 popTopLevelContextObject(interruptedWork);
18030 break;
18031 }
18032 case HostComponent:
18033 {
18034 popHostContext(interruptedWork);
18035 break;
18036 }
18037 case HostPortal:
18038 popHostContainer(interruptedWork);
18039 break;
18040 case ContextProvider:
18041 popProvider(interruptedWork);
18042 break;
18043 default:
18044 break;
18045 }
18046}
18047
18048var ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher;
18049var ReactCurrentOwner$2 = ReactSharedInternals.ReactCurrentOwner;
18050
18051
18052var didWarnAboutStateTransition = void 0;
18053var didWarnSetStateChildContext = void 0;
18054var warnAboutUpdateOnUnmounted = void 0;
18055var warnAboutInvalidUpdates = void 0;
18056
18057if (enableSchedulerTracing) {
18058 // Provide explicit error message when production+profiling bundle of e.g. react-dom
18059 // is used with production (non-profiling) bundle of scheduler/tracing
18060 !(__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;
18061}
18062
18063{
18064 didWarnAboutStateTransition = false;
18065 didWarnSetStateChildContext = false;
18066 var didWarnStateUpdateForUnmountedComponent = {};
18067
18068 warnAboutUpdateOnUnmounted = function (fiber, isClass) {
18069 // We show the whole stack but dedupe on the top component's name because
18070 // the problematic code almost always lies inside that component.
18071 var componentName = getComponentName(fiber.type) || 'ReactComponent';
18072 if (didWarnStateUpdateForUnmountedComponent[componentName]) {
18073 return;
18074 }
18075 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));
18076 didWarnStateUpdateForUnmountedComponent[componentName] = true;
18077 };
18078
18079 warnAboutInvalidUpdates = function (instance) {
18080 switch (phase) {
18081 case 'getChildContext':
18082 if (didWarnSetStateChildContext) {
18083 return;
18084 }
18085 warningWithoutStack$1(false, 'setState(...): Cannot call setState() inside getChildContext()');
18086 didWarnSetStateChildContext = true;
18087 break;
18088 case 'render':
18089 if (didWarnAboutStateTransition) {
18090 return;
18091 }
18092 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.');
18093 didWarnAboutStateTransition = true;
18094 break;
18095 }
18096 };
18097}
18098
18099// Used to ensure computeUniqueAsyncExpiration is monotonically decreasing.
18100var lastUniqueAsyncExpiration = Sync - 1;
18101
18102// Represents the expiration time that incoming updates should use. (If this
18103// is NoWork, use the default strategy: async updates in async mode, sync
18104// updates in sync mode.)
18105var expirationContext = NoWork;
18106
18107var isWorking = false;
18108
18109// The next work in progress fiber that we're currently working on.
18110var nextUnitOfWork = null;
18111var nextRoot = null;
18112// The time at which we're currently rendering work.
18113var nextRenderExpirationTime = NoWork;
18114var nextLatestAbsoluteTimeoutMs = -1;
18115var nextRenderDidError = false;
18116
18117// The next fiber with an effect that we're currently committing.
18118var nextEffect = null;
18119
18120var isCommitting$1 = false;
18121var rootWithPendingPassiveEffects = null;
18122var passiveEffectCallbackHandle = null;
18123var passiveEffectCallback = null;
18124
18125var legacyErrorBoundariesThatAlreadyFailed = null;
18126
18127// Used for performance tracking.
18128var interruptedBy = null;
18129
18130var stashedWorkInProgressProperties = void 0;
18131var replayUnitOfWork = void 0;
18132var mayReplayFailedUnitOfWork = void 0;
18133var isReplayingFailedUnitOfWork = void 0;
18134var originalReplayError = void 0;
18135var rethrowOriginalError = void 0;
18136if (true && replayFailedUnitOfWorkWithInvokeGuardedCallback) {
18137 stashedWorkInProgressProperties = null;
18138 mayReplayFailedUnitOfWork = true;
18139 isReplayingFailedUnitOfWork = false;
18140 originalReplayError = null;
18141 replayUnitOfWork = function (failedUnitOfWork, thrownValue, isYieldy) {
18142 if (thrownValue !== null && typeof thrownValue === 'object' && typeof thrownValue.then === 'function') {
18143 // Don't replay promises. Treat everything else like an error.
18144 // TODO: Need to figure out a different strategy if/when we add
18145 // support for catching other types.
18146 return;
18147 }
18148
18149 // Restore the original state of the work-in-progress
18150 if (stashedWorkInProgressProperties === null) {
18151 // This should never happen. Don't throw because this code is DEV-only.
18152 warningWithoutStack$1(false, 'Could not replay rendering after an error. This is likely a bug in React. ' + 'Please file an issue.');
18153 return;
18154 }
18155 assignFiberPropertiesInDEV(failedUnitOfWork, stashedWorkInProgressProperties);
18156
18157 switch (failedUnitOfWork.tag) {
18158 case HostRoot:
18159 popHostContainer(failedUnitOfWork);
18160 popTopLevelContextObject(failedUnitOfWork);
18161 break;
18162 case HostComponent:
18163 popHostContext(failedUnitOfWork);
18164 break;
18165 case ClassComponent:
18166 {
18167 var Component = failedUnitOfWork.type;
18168 if (isContextProvider(Component)) {
18169 popContext(failedUnitOfWork);
18170 }
18171 break;
18172 }
18173 case HostPortal:
18174 popHostContainer(failedUnitOfWork);
18175 break;
18176 case ContextProvider:
18177 popProvider(failedUnitOfWork);
18178 break;
18179 }
18180 // Replay the begin phase.
18181 isReplayingFailedUnitOfWork = true;
18182 originalReplayError = thrownValue;
18183 invokeGuardedCallback(null, workLoop, null, isYieldy);
18184 isReplayingFailedUnitOfWork = false;
18185 originalReplayError = null;
18186 if (hasCaughtError()) {
18187 var replayError = clearCaughtError();
18188 if (replayError != null && thrownValue != null) {
18189 try {
18190 // Reading the expando property is intentionally
18191 // inside `try` because it might be a getter or Proxy.
18192 if (replayError._suppressLogging) {
18193 // Also suppress logging for the original error.
18194 thrownValue._suppressLogging = true;
18195 }
18196 } catch (inner) {
18197 // Ignore.
18198 }
18199 }
18200 } else {
18201 // If the begin phase did not fail the second time, set this pointer
18202 // back to the original value.
18203 nextUnitOfWork = failedUnitOfWork;
18204 }
18205 };
18206 rethrowOriginalError = function () {
18207 throw originalReplayError;
18208 };
18209}
18210
18211function resetStack() {
18212 if (nextUnitOfWork !== null) {
18213 var interruptedWork = nextUnitOfWork.return;
18214 while (interruptedWork !== null) {
18215 unwindInterruptedWork(interruptedWork);
18216 interruptedWork = interruptedWork.return;
18217 }
18218 }
18219
18220 {
18221 ReactStrictModeWarnings.discardPendingWarnings();
18222 checkThatStackIsEmpty();
18223 }
18224
18225 nextRoot = null;
18226 nextRenderExpirationTime = NoWork;
18227 nextLatestAbsoluteTimeoutMs = -1;
18228 nextRenderDidError = false;
18229 nextUnitOfWork = null;
18230}
18231
18232function commitAllHostEffects() {
18233 while (nextEffect !== null) {
18234 {
18235 setCurrentFiber(nextEffect);
18236 }
18237 recordEffect();
18238
18239 var effectTag = nextEffect.effectTag;
18240
18241 if (effectTag & ContentReset) {
18242 commitResetTextContent(nextEffect);
18243 }
18244
18245 if (effectTag & Ref) {
18246 var current$$1 = nextEffect.alternate;
18247 if (current$$1 !== null) {
18248 commitDetachRef(current$$1);
18249 }
18250 }
18251
18252 // The following switch statement is only concerned about placement,
18253 // updates, and deletions. To avoid needing to add a case for every
18254 // possible bitmap value, we remove the secondary effects from the
18255 // effect tag and switch on that value.
18256 var primaryEffectTag = effectTag & (Placement | Update | Deletion);
18257 switch (primaryEffectTag) {
18258 case Placement:
18259 {
18260 commitPlacement(nextEffect);
18261 // Clear the "placement" from effect tag so that we know that this is inserted, before
18262 // any life-cycles like componentDidMount gets called.
18263 // TODO: findDOMNode doesn't rely on this any more but isMounted
18264 // does and isMounted is deprecated anyway so we should be able
18265 // to kill this.
18266 nextEffect.effectTag &= ~Placement;
18267 break;
18268 }
18269 case PlacementAndUpdate:
18270 {
18271 // Placement
18272 commitPlacement(nextEffect);
18273 // Clear the "placement" from effect tag so that we know that this is inserted, before
18274 // any life-cycles like componentDidMount gets called.
18275 nextEffect.effectTag &= ~Placement;
18276
18277 // Update
18278 var _current = nextEffect.alternate;
18279 commitWork(_current, nextEffect);
18280 break;
18281 }
18282 case Update:
18283 {
18284 var _current2 = nextEffect.alternate;
18285 commitWork(_current2, nextEffect);
18286 break;
18287 }
18288 case Deletion:
18289 {
18290 commitDeletion(nextEffect);
18291 break;
18292 }
18293 }
18294 nextEffect = nextEffect.nextEffect;
18295 }
18296
18297 {
18298 resetCurrentFiber();
18299 }
18300}
18301
18302function commitBeforeMutationLifecycles() {
18303 while (nextEffect !== null) {
18304 {
18305 setCurrentFiber(nextEffect);
18306 }
18307
18308 var effectTag = nextEffect.effectTag;
18309 if (effectTag & Snapshot) {
18310 recordEffect();
18311 var current$$1 = nextEffect.alternate;
18312 commitBeforeMutationLifeCycles(current$$1, nextEffect);
18313 }
18314
18315 nextEffect = nextEffect.nextEffect;
18316 }
18317
18318 {
18319 resetCurrentFiber();
18320 }
18321}
18322
18323function commitAllLifeCycles(finishedRoot, committedExpirationTime) {
18324 {
18325 ReactStrictModeWarnings.flushPendingUnsafeLifecycleWarnings();
18326 ReactStrictModeWarnings.flushLegacyContextWarning();
18327
18328 if (warnAboutDeprecatedLifecycles) {
18329 ReactStrictModeWarnings.flushPendingDeprecationWarnings();
18330 }
18331 }
18332 while (nextEffect !== null) {
18333 {
18334 setCurrentFiber(nextEffect);
18335 }
18336 var effectTag = nextEffect.effectTag;
18337
18338 if (effectTag & (Update | Callback)) {
18339 recordEffect();
18340 var current$$1 = nextEffect.alternate;
18341 commitLifeCycles(finishedRoot, current$$1, nextEffect, committedExpirationTime);
18342 }
18343
18344 if (effectTag & Ref) {
18345 recordEffect();
18346 commitAttachRef(nextEffect);
18347 }
18348
18349 if (effectTag & Passive) {
18350 rootWithPendingPassiveEffects = finishedRoot;
18351 }
18352
18353 nextEffect = nextEffect.nextEffect;
18354 }
18355 {
18356 resetCurrentFiber();
18357 }
18358}
18359
18360function commitPassiveEffects(root, firstEffect) {
18361 rootWithPendingPassiveEffects = null;
18362 passiveEffectCallbackHandle = null;
18363 passiveEffectCallback = null;
18364
18365 // Set this to true to prevent re-entrancy
18366 var previousIsRendering = isRendering;
18367 isRendering = true;
18368
18369 var effect = firstEffect;
18370 do {
18371 {
18372 setCurrentFiber(effect);
18373 }
18374
18375 if (effect.effectTag & Passive) {
18376 var didError = false;
18377 var error = void 0;
18378 {
18379 invokeGuardedCallback(null, commitPassiveHookEffects, null, effect);
18380 if (hasCaughtError()) {
18381 didError = true;
18382 error = clearCaughtError();
18383 }
18384 }
18385 if (didError) {
18386 captureCommitPhaseError(effect, error);
18387 }
18388 }
18389 effect = effect.nextEffect;
18390 } while (effect !== null);
18391 {
18392 resetCurrentFiber();
18393 }
18394
18395 isRendering = previousIsRendering;
18396
18397 // Check if work was scheduled by one of the effects
18398 var rootExpirationTime = root.expirationTime;
18399 if (rootExpirationTime !== NoWork) {
18400 requestWork(root, rootExpirationTime);
18401 }
18402}
18403
18404function isAlreadyFailedLegacyErrorBoundary(instance) {
18405 return legacyErrorBoundariesThatAlreadyFailed !== null && legacyErrorBoundariesThatAlreadyFailed.has(instance);
18406}
18407
18408function markLegacyErrorBoundaryAsFailed(instance) {
18409 if (legacyErrorBoundariesThatAlreadyFailed === null) {
18410 legacyErrorBoundariesThatAlreadyFailed = new Set([instance]);
18411 } else {
18412 legacyErrorBoundariesThatAlreadyFailed.add(instance);
18413 }
18414}
18415
18416function flushPassiveEffects() {
18417 if (passiveEffectCallbackHandle !== null) {
18418 cancelPassiveEffects(passiveEffectCallbackHandle);
18419 }
18420 if (passiveEffectCallback !== null) {
18421 // We call the scheduled callback instead of commitPassiveEffects directly
18422 // to ensure tracing works correctly.
18423 passiveEffectCallback();
18424 }
18425}
18426
18427function commitRoot(root, finishedWork) {
18428 isWorking = true;
18429 isCommitting$1 = true;
18430 startCommitTimer();
18431
18432 !(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;
18433 var committedExpirationTime = root.pendingCommitExpirationTime;
18434 !(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;
18435 root.pendingCommitExpirationTime = NoWork;
18436
18437 // Update the pending priority levels to account for the work that we are
18438 // about to commit. This needs to happen before calling the lifecycles, since
18439 // they may schedule additional updates.
18440 var updateExpirationTimeBeforeCommit = finishedWork.expirationTime;
18441 var childExpirationTimeBeforeCommit = finishedWork.childExpirationTime;
18442 var earliestRemainingTimeBeforeCommit = childExpirationTimeBeforeCommit > updateExpirationTimeBeforeCommit ? childExpirationTimeBeforeCommit : updateExpirationTimeBeforeCommit;
18443 markCommittedPriorityLevels(root, earliestRemainingTimeBeforeCommit);
18444
18445 var prevInteractions = null;
18446 if (enableSchedulerTracing) {
18447 // Restore any pending interactions at this point,
18448 // So that cascading work triggered during the render phase will be accounted for.
18449 prevInteractions = __interactionsRef.current;
18450 __interactionsRef.current = root.memoizedInteractions;
18451 }
18452
18453 // Reset this to null before calling lifecycles
18454 ReactCurrentOwner$2.current = null;
18455
18456 var firstEffect = void 0;
18457 if (finishedWork.effectTag > PerformedWork) {
18458 // A fiber's effect list consists only of its children, not itself. So if
18459 // the root has an effect, we need to add it to the end of the list. The
18460 // resulting list is the set that would belong to the root's parent, if
18461 // it had one; that is, all the effects in the tree including the root.
18462 if (finishedWork.lastEffect !== null) {
18463 finishedWork.lastEffect.nextEffect = finishedWork;
18464 firstEffect = finishedWork.firstEffect;
18465 } else {
18466 firstEffect = finishedWork;
18467 }
18468 } else {
18469 // There is no effect on the root.
18470 firstEffect = finishedWork.firstEffect;
18471 }
18472
18473 prepareForCommit(root.containerInfo);
18474
18475 // Invoke instances of getSnapshotBeforeUpdate before mutation.
18476 nextEffect = firstEffect;
18477 startCommitSnapshotEffectsTimer();
18478 while (nextEffect !== null) {
18479 var didError = false;
18480 var error = void 0;
18481 {
18482 invokeGuardedCallback(null, commitBeforeMutationLifecycles, null);
18483 if (hasCaughtError()) {
18484 didError = true;
18485 error = clearCaughtError();
18486 }
18487 }
18488 if (didError) {
18489 !(nextEffect !== null) ? invariant(false, 'Should have next effect. This error is likely caused by a bug in React. Please file an issue.') : void 0;
18490 captureCommitPhaseError(nextEffect, error);
18491 // Clean-up
18492 if (nextEffect !== null) {
18493 nextEffect = nextEffect.nextEffect;
18494 }
18495 }
18496 }
18497 stopCommitSnapshotEffectsTimer();
18498
18499 if (enableProfilerTimer) {
18500 // Mark the current commit time to be shared by all Profilers in this batch.
18501 // This enables them to be grouped later.
18502 recordCommitTime();
18503 }
18504
18505 // Commit all the side-effects within a tree. We'll do this in two passes.
18506 // The first pass performs all the host insertions, updates, deletions and
18507 // ref unmounts.
18508 nextEffect = firstEffect;
18509 startCommitHostEffectsTimer();
18510 while (nextEffect !== null) {
18511 var _didError = false;
18512 var _error = void 0;
18513 {
18514 invokeGuardedCallback(null, commitAllHostEffects, null);
18515 if (hasCaughtError()) {
18516 _didError = true;
18517 _error = clearCaughtError();
18518 }
18519 }
18520 if (_didError) {
18521 !(nextEffect !== null) ? invariant(false, 'Should have next effect. This error is likely caused by a bug in React. Please file an issue.') : void 0;
18522 captureCommitPhaseError(nextEffect, _error);
18523 // Clean-up
18524 if (nextEffect !== null) {
18525 nextEffect = nextEffect.nextEffect;
18526 }
18527 }
18528 }
18529 stopCommitHostEffectsTimer();
18530
18531 resetAfterCommit(root.containerInfo);
18532
18533 // The work-in-progress tree is now the current tree. This must come after
18534 // the first pass of the commit phase, so that the previous tree is still
18535 // current during componentWillUnmount, but before the second pass, so that
18536 // the finished work is current during componentDidMount/Update.
18537 root.current = finishedWork;
18538
18539 // In the second pass we'll perform all life-cycles and ref callbacks.
18540 // Life-cycles happen as a separate pass so that all placements, updates,
18541 // and deletions in the entire tree have already been invoked.
18542 // This pass also triggers any renderer-specific initial effects.
18543 nextEffect = firstEffect;
18544 startCommitLifeCyclesTimer();
18545 while (nextEffect !== null) {
18546 var _didError2 = false;
18547 var _error2 = void 0;
18548 {
18549 invokeGuardedCallback(null, commitAllLifeCycles, null, root, committedExpirationTime);
18550 if (hasCaughtError()) {
18551 _didError2 = true;
18552 _error2 = clearCaughtError();
18553 }
18554 }
18555 if (_didError2) {
18556 !(nextEffect !== null) ? invariant(false, 'Should have next effect. This error is likely caused by a bug in React. Please file an issue.') : void 0;
18557 captureCommitPhaseError(nextEffect, _error2);
18558 if (nextEffect !== null) {
18559 nextEffect = nextEffect.nextEffect;
18560 }
18561 }
18562 }
18563
18564 if (firstEffect !== null && rootWithPendingPassiveEffects !== null) {
18565 // This commit included a passive effect. These do not need to fire until
18566 // after the next paint. Schedule an callback to fire them in an async
18567 // event. To ensure serial execution, the callback will be flushed early if
18568 // we enter rootWithPendingPassiveEffects commit phase before then.
18569 var callback = commitPassiveEffects.bind(null, root, firstEffect);
18570 if (enableSchedulerTracing) {
18571 // TODO: Avoid this extra callback by mutating the tracing ref directly,
18572 // like we do at the beginning of commitRoot. I've opted not to do that
18573 // here because that code is still in flux.
18574 callback = unstable_wrap(callback);
18575 }
18576 passiveEffectCallbackHandle = schedulePassiveEffects(callback);
18577 passiveEffectCallback = callback;
18578 }
18579
18580 isCommitting$1 = false;
18581 isWorking = false;
18582 stopCommitLifeCyclesTimer();
18583 stopCommitTimer();
18584 onCommitRoot(finishedWork.stateNode);
18585 if (true && ReactFiberInstrumentation_1.debugTool) {
18586 ReactFiberInstrumentation_1.debugTool.onCommitWork(finishedWork);
18587 }
18588
18589 var updateExpirationTimeAfterCommit = finishedWork.expirationTime;
18590 var childExpirationTimeAfterCommit = finishedWork.childExpirationTime;
18591 var earliestRemainingTimeAfterCommit = childExpirationTimeAfterCommit > updateExpirationTimeAfterCommit ? childExpirationTimeAfterCommit : updateExpirationTimeAfterCommit;
18592 if (earliestRemainingTimeAfterCommit === NoWork) {
18593 // If there's no remaining work, we can clear the set of already failed
18594 // error boundaries.
18595 legacyErrorBoundariesThatAlreadyFailed = null;
18596 }
18597 onCommit(root, earliestRemainingTimeAfterCommit);
18598
18599 if (enableSchedulerTracing) {
18600 __interactionsRef.current = prevInteractions;
18601
18602 var subscriber = void 0;
18603
18604 try {
18605 subscriber = __subscriberRef.current;
18606 if (subscriber !== null && root.memoizedInteractions.size > 0) {
18607 var threadID = computeThreadID(committedExpirationTime, root.interactionThreadID);
18608 subscriber.onWorkStopped(root.memoizedInteractions, threadID);
18609 }
18610 } catch (error) {
18611 // It's not safe for commitRoot() to throw.
18612 // Store the error for now and we'll re-throw in finishRendering().
18613 if (!hasUnhandledError) {
18614 hasUnhandledError = true;
18615 unhandledError = error;
18616 }
18617 } finally {
18618 // Clear completed interactions from the pending Map.
18619 // Unless the render was suspended or cascading work was scheduled,
18620 // In which case– leave pending interactions until the subsequent render.
18621 var pendingInteractionMap = root.pendingInteractionMap;
18622 pendingInteractionMap.forEach(function (scheduledInteractions, scheduledExpirationTime) {
18623 // Only decrement the pending interaction count if we're done.
18624 // If there's still work at the current priority,
18625 // That indicates that we are waiting for suspense data.
18626 if (scheduledExpirationTime > earliestRemainingTimeAfterCommit) {
18627 pendingInteractionMap.delete(scheduledExpirationTime);
18628
18629 scheduledInteractions.forEach(function (interaction) {
18630 interaction.__count--;
18631
18632 if (subscriber !== null && interaction.__count === 0) {
18633 try {
18634 subscriber.onInteractionScheduledWorkCompleted(interaction);
18635 } catch (error) {
18636 // It's not safe for commitRoot() to throw.
18637 // Store the error for now and we'll re-throw in finishRendering().
18638 if (!hasUnhandledError) {
18639 hasUnhandledError = true;
18640 unhandledError = error;
18641 }
18642 }
18643 }
18644 });
18645 }
18646 });
18647 }
18648 }
18649}
18650
18651function resetChildExpirationTime(workInProgress, renderTime) {
18652 if (renderTime !== Never && workInProgress.childExpirationTime === Never) {
18653 // The children of this component are hidden. Don't bubble their
18654 // expiration times.
18655 return;
18656 }
18657
18658 var newChildExpirationTime = NoWork;
18659
18660 // Bubble up the earliest expiration time.
18661 if (enableProfilerTimer && workInProgress.mode & ProfileMode) {
18662 // We're in profiling mode.
18663 // Let's use this same traversal to update the render durations.
18664 var actualDuration = workInProgress.actualDuration;
18665 var treeBaseDuration = workInProgress.selfBaseDuration;
18666
18667 // When a fiber is cloned, its actualDuration is reset to 0.
18668 // This value will only be updated if work is done on the fiber (i.e. it doesn't bailout).
18669 // When work is done, it should bubble to the parent's actualDuration.
18670 // If the fiber has not been cloned though, (meaning no work was done),
18671 // Then this value will reflect the amount of time spent working on a previous render.
18672 // In that case it should not bubble.
18673 // We determine whether it was cloned by comparing the child pointer.
18674 var shouldBubbleActualDurations = workInProgress.alternate === null || workInProgress.child !== workInProgress.alternate.child;
18675
18676 var child = workInProgress.child;
18677 while (child !== null) {
18678 var childUpdateExpirationTime = child.expirationTime;
18679 var childChildExpirationTime = child.childExpirationTime;
18680 if (childUpdateExpirationTime > newChildExpirationTime) {
18681 newChildExpirationTime = childUpdateExpirationTime;
18682 }
18683 if (childChildExpirationTime > newChildExpirationTime) {
18684 newChildExpirationTime = childChildExpirationTime;
18685 }
18686 if (shouldBubbleActualDurations) {
18687 actualDuration += child.actualDuration;
18688 }
18689 treeBaseDuration += child.treeBaseDuration;
18690 child = child.sibling;
18691 }
18692 workInProgress.actualDuration = actualDuration;
18693 workInProgress.treeBaseDuration = treeBaseDuration;
18694 } else {
18695 var _child = workInProgress.child;
18696 while (_child !== null) {
18697 var _childUpdateExpirationTime = _child.expirationTime;
18698 var _childChildExpirationTime = _child.childExpirationTime;
18699 if (_childUpdateExpirationTime > newChildExpirationTime) {
18700 newChildExpirationTime = _childUpdateExpirationTime;
18701 }
18702 if (_childChildExpirationTime > newChildExpirationTime) {
18703 newChildExpirationTime = _childChildExpirationTime;
18704 }
18705 _child = _child.sibling;
18706 }
18707 }
18708
18709 workInProgress.childExpirationTime = newChildExpirationTime;
18710}
18711
18712function completeUnitOfWork(workInProgress) {
18713 // Attempt to complete the current unit of work, then move to the
18714 // next sibling. If there are no more siblings, return to the
18715 // parent fiber.
18716 while (true) {
18717 // The current, flushed, state of this fiber is the alternate.
18718 // Ideally nothing should rely on this, but relying on it here
18719 // means that we don't need an additional field on the work in
18720 // progress.
18721 var current$$1 = workInProgress.alternate;
18722 {
18723 setCurrentFiber(workInProgress);
18724 }
18725
18726 var returnFiber = workInProgress.return;
18727 var siblingFiber = workInProgress.sibling;
18728
18729 if ((workInProgress.effectTag & Incomplete) === NoEffect) {
18730 if (true && replayFailedUnitOfWorkWithInvokeGuardedCallback) {
18731 // Don't replay if it fails during completion phase.
18732 mayReplayFailedUnitOfWork = false;
18733 }
18734 // This fiber completed.
18735 // Remember we're completing this unit so we can find a boundary if it fails.
18736 nextUnitOfWork = workInProgress;
18737 if (enableProfilerTimer) {
18738 if (workInProgress.mode & ProfileMode) {
18739 startProfilerTimer(workInProgress);
18740 }
18741 nextUnitOfWork = completeWork(current$$1, workInProgress, nextRenderExpirationTime);
18742 if (workInProgress.mode & ProfileMode) {
18743 // Update render duration assuming we didn't error.
18744 stopProfilerTimerIfRunningAndRecordDelta(workInProgress, false);
18745 }
18746 } else {
18747 nextUnitOfWork = completeWork(current$$1, workInProgress, nextRenderExpirationTime);
18748 }
18749 if (true && replayFailedUnitOfWorkWithInvokeGuardedCallback) {
18750 // We're out of completion phase so replaying is fine now.
18751 mayReplayFailedUnitOfWork = true;
18752 }
18753 stopWorkTimer(workInProgress);
18754 resetChildExpirationTime(workInProgress, nextRenderExpirationTime);
18755 {
18756 resetCurrentFiber();
18757 }
18758
18759 if (nextUnitOfWork !== null) {
18760 // Completing this fiber spawned new work. Work on that next.
18761 return nextUnitOfWork;
18762 }
18763
18764 if (returnFiber !== null &&
18765 // Do not append effects to parents if a sibling failed to complete
18766 (returnFiber.effectTag & Incomplete) === NoEffect) {
18767 // Append all the effects of the subtree and this fiber onto the effect
18768 // list of the parent. The completion order of the children affects the
18769 // side-effect order.
18770 if (returnFiber.firstEffect === null) {
18771 returnFiber.firstEffect = workInProgress.firstEffect;
18772 }
18773 if (workInProgress.lastEffect !== null) {
18774 if (returnFiber.lastEffect !== null) {
18775 returnFiber.lastEffect.nextEffect = workInProgress.firstEffect;
18776 }
18777 returnFiber.lastEffect = workInProgress.lastEffect;
18778 }
18779
18780 // If this fiber had side-effects, we append it AFTER the children's
18781 // side-effects. We can perform certain side-effects earlier if
18782 // needed, by doing multiple passes over the effect list. We don't want
18783 // to schedule our own side-effect on our own list because if end up
18784 // reusing children we'll schedule this effect onto itself since we're
18785 // at the end.
18786 var effectTag = workInProgress.effectTag;
18787 // Skip both NoWork and PerformedWork tags when creating the effect list.
18788 // PerformedWork effect is read by React DevTools but shouldn't be committed.
18789 if (effectTag > PerformedWork) {
18790 if (returnFiber.lastEffect !== null) {
18791 returnFiber.lastEffect.nextEffect = workInProgress;
18792 } else {
18793 returnFiber.firstEffect = workInProgress;
18794 }
18795 returnFiber.lastEffect = workInProgress;
18796 }
18797 }
18798
18799 if (true && ReactFiberInstrumentation_1.debugTool) {
18800 ReactFiberInstrumentation_1.debugTool.onCompleteWork(workInProgress);
18801 }
18802
18803 if (siblingFiber !== null) {
18804 // If there is more work to do in this returnFiber, do that next.
18805 return siblingFiber;
18806 } else if (returnFiber !== null) {
18807 // If there's no more work in this returnFiber. Complete the returnFiber.
18808 workInProgress = returnFiber;
18809 continue;
18810 } else {
18811 // We've reached the root.
18812 return null;
18813 }
18814 } else {
18815 if (enableProfilerTimer && workInProgress.mode & ProfileMode) {
18816 // Record the render duration for the fiber that errored.
18817 stopProfilerTimerIfRunningAndRecordDelta(workInProgress, false);
18818
18819 // Include the time spent working on failed children before continuing.
18820 var actualDuration = workInProgress.actualDuration;
18821 var child = workInProgress.child;
18822 while (child !== null) {
18823 actualDuration += child.actualDuration;
18824 child = child.sibling;
18825 }
18826 workInProgress.actualDuration = actualDuration;
18827 }
18828
18829 // This fiber did not complete because something threw. Pop values off
18830 // the stack without entering the complete phase. If this is a boundary,
18831 // capture values if possible.
18832 var next = unwindWork(workInProgress, nextRenderExpirationTime);
18833 // Because this fiber did not complete, don't reset its expiration time.
18834 if (workInProgress.effectTag & DidCapture) {
18835 // Restarting an error boundary
18836 stopFailedWorkTimer(workInProgress);
18837 } else {
18838 stopWorkTimer(workInProgress);
18839 }
18840
18841 {
18842 resetCurrentFiber();
18843 }
18844
18845 if (next !== null) {
18846 stopWorkTimer(workInProgress);
18847 if (true && ReactFiberInstrumentation_1.debugTool) {
18848 ReactFiberInstrumentation_1.debugTool.onCompleteWork(workInProgress);
18849 }
18850
18851 // If completing this work spawned new work, do that next. We'll come
18852 // back here again.
18853 // Since we're restarting, remove anything that is not a host effect
18854 // from the effect tag.
18855 next.effectTag &= HostEffectMask;
18856 return next;
18857 }
18858
18859 if (returnFiber !== null) {
18860 // Mark the parent fiber as incomplete and clear its effect list.
18861 returnFiber.firstEffect = returnFiber.lastEffect = null;
18862 returnFiber.effectTag |= Incomplete;
18863 }
18864
18865 if (true && ReactFiberInstrumentation_1.debugTool) {
18866 ReactFiberInstrumentation_1.debugTool.onCompleteWork(workInProgress);
18867 }
18868
18869 if (siblingFiber !== null) {
18870 // If there is more work to do in this returnFiber, do that next.
18871 return siblingFiber;
18872 } else if (returnFiber !== null) {
18873 // If there's no more work in this returnFiber. Complete the returnFiber.
18874 workInProgress = returnFiber;
18875 continue;
18876 } else {
18877 return null;
18878 }
18879 }
18880 }
18881
18882 // Without this explicit null return Flow complains of invalid return type
18883 // TODO Remove the above while(true) loop
18884 // eslint-disable-next-line no-unreachable
18885 return null;
18886}
18887
18888function performUnitOfWork(workInProgress) {
18889 // The current, flushed, state of this fiber is the alternate.
18890 // Ideally nothing should rely on this, but relying on it here
18891 // means that we don't need an additional field on the work in
18892 // progress.
18893 var current$$1 = workInProgress.alternate;
18894
18895 // See if beginning this work spawns more work.
18896 startWorkTimer(workInProgress);
18897 {
18898 setCurrentFiber(workInProgress);
18899 }
18900
18901 if (true && replayFailedUnitOfWorkWithInvokeGuardedCallback) {
18902 stashedWorkInProgressProperties = assignFiberPropertiesInDEV(stashedWorkInProgressProperties, workInProgress);
18903 }
18904
18905 var next = void 0;
18906 if (enableProfilerTimer) {
18907 if (workInProgress.mode & ProfileMode) {
18908 startProfilerTimer(workInProgress);
18909 }
18910
18911 next = beginWork(current$$1, workInProgress, nextRenderExpirationTime);
18912 workInProgress.memoizedProps = workInProgress.pendingProps;
18913
18914 if (workInProgress.mode & ProfileMode) {
18915 // Record the render duration assuming we didn't bailout (or error).
18916 stopProfilerTimerIfRunningAndRecordDelta(workInProgress, true);
18917 }
18918 } else {
18919 next = beginWork(current$$1, workInProgress, nextRenderExpirationTime);
18920 workInProgress.memoizedProps = workInProgress.pendingProps;
18921 }
18922
18923 {
18924 resetCurrentFiber();
18925 if (isReplayingFailedUnitOfWork) {
18926 // Currently replaying a failed unit of work. This should be unreachable,
18927 // because the render phase is meant to be idempotent, and it should
18928 // have thrown again. Since it didn't, rethrow the original error, so
18929 // React's internal stack is not misaligned.
18930 rethrowOriginalError();
18931 }
18932 }
18933 if (true && ReactFiberInstrumentation_1.debugTool) {
18934 ReactFiberInstrumentation_1.debugTool.onBeginWork(workInProgress);
18935 }
18936
18937 if (next === null) {
18938 // If this doesn't spawn new work, complete the current work.
18939 next = completeUnitOfWork(workInProgress);
18940 }
18941
18942 ReactCurrentOwner$2.current = null;
18943
18944 return next;
18945}
18946
18947function workLoop(isYieldy) {
18948 if (!isYieldy) {
18949 // Flush work without yielding
18950 while (nextUnitOfWork !== null) {
18951 nextUnitOfWork = performUnitOfWork(nextUnitOfWork);
18952 }
18953 } else {
18954 // Flush asynchronous work until there's a higher priority event
18955 while (nextUnitOfWork !== null && !shouldYieldToRenderer()) {
18956 nextUnitOfWork = performUnitOfWork(nextUnitOfWork);
18957 }
18958 }
18959}
18960
18961function renderRoot(root, isYieldy) {
18962 !!isWorking ? invariant(false, 'renderRoot was called recursively. This error is likely caused by a bug in React. Please file an issue.') : void 0;
18963
18964 flushPassiveEffects();
18965
18966 isWorking = true;
18967 var previousDispatcher = ReactCurrentDispatcher.current;
18968 ReactCurrentDispatcher.current = ContextOnlyDispatcher;
18969
18970 var expirationTime = root.nextExpirationTimeToWorkOn;
18971
18972 // Check if we're starting from a fresh stack, or if we're resuming from
18973 // previously yielded work.
18974 if (expirationTime !== nextRenderExpirationTime || root !== nextRoot || nextUnitOfWork === null) {
18975 // Reset the stack and start working from the root.
18976 resetStack();
18977 nextRoot = root;
18978 nextRenderExpirationTime = expirationTime;
18979 nextUnitOfWork = createWorkInProgress(nextRoot.current, null, nextRenderExpirationTime);
18980 root.pendingCommitExpirationTime = NoWork;
18981
18982 if (enableSchedulerTracing) {
18983 // Determine which interactions this batch of work currently includes,
18984 // So that we can accurately attribute time spent working on it,
18985 var interactions = new Set();
18986 root.pendingInteractionMap.forEach(function (scheduledInteractions, scheduledExpirationTime) {
18987 if (scheduledExpirationTime >= expirationTime) {
18988 scheduledInteractions.forEach(function (interaction) {
18989 return interactions.add(interaction);
18990 });
18991 }
18992 });
18993
18994 // Store the current set of interactions on the FiberRoot for a few reasons:
18995 // We can re-use it in hot functions like renderRoot() without having to recalculate it.
18996 // We will also use it in commitWork() to pass to any Profiler onRender() hooks.
18997 // This also provides DevTools with a way to access it when the onCommitRoot() hook is called.
18998 root.memoizedInteractions = interactions;
18999
19000 if (interactions.size > 0) {
19001 var subscriber = __subscriberRef.current;
19002 if (subscriber !== null) {
19003 var threadID = computeThreadID(expirationTime, root.interactionThreadID);
19004 try {
19005 subscriber.onWorkStarted(interactions, threadID);
19006 } catch (error) {
19007 // Work thrown by an interaction tracing subscriber should be rethrown,
19008 // But only once it's safe (to avoid leaving the scheduler in an invalid state).
19009 // Store the error for now and we'll re-throw in finishRendering().
19010 if (!hasUnhandledError) {
19011 hasUnhandledError = true;
19012 unhandledError = error;
19013 }
19014 }
19015 }
19016 }
19017 }
19018 }
19019
19020 var prevInteractions = null;
19021 if (enableSchedulerTracing) {
19022 // We're about to start new traced work.
19023 // Restore pending interactions so cascading work triggered during the render phase will be accounted for.
19024 prevInteractions = __interactionsRef.current;
19025 __interactionsRef.current = root.memoizedInteractions;
19026 }
19027
19028 var didFatal = false;
19029
19030 startWorkLoopTimer(nextUnitOfWork);
19031
19032 do {
19033 try {
19034 workLoop(isYieldy);
19035 } catch (thrownValue) {
19036 resetContextDependences();
19037 resetHooks();
19038
19039 // Reset in case completion throws.
19040 // This is only used in DEV and when replaying is on.
19041 var mayReplay = void 0;
19042 if (true && replayFailedUnitOfWorkWithInvokeGuardedCallback) {
19043 mayReplay = mayReplayFailedUnitOfWork;
19044 mayReplayFailedUnitOfWork = true;
19045 }
19046
19047 if (nextUnitOfWork === null) {
19048 // This is a fatal error.
19049 didFatal = true;
19050 onUncaughtError(thrownValue);
19051 } else {
19052 if (enableProfilerTimer && nextUnitOfWork.mode & ProfileMode) {
19053 // Record the time spent rendering before an error was thrown.
19054 // This avoids inaccurate Profiler durations in the case of a suspended render.
19055 stopProfilerTimerIfRunningAndRecordDelta(nextUnitOfWork, true);
19056 }
19057
19058 {
19059 // Reset global debug state
19060 // We assume this is defined in DEV
19061 resetCurrentlyProcessingQueue();
19062 }
19063
19064 if (true && replayFailedUnitOfWorkWithInvokeGuardedCallback) {
19065 if (mayReplay) {
19066 var failedUnitOfWork = nextUnitOfWork;
19067 replayUnitOfWork(failedUnitOfWork, thrownValue, isYieldy);
19068 }
19069 }
19070
19071 // TODO: we already know this isn't true in some cases.
19072 // At least this shows a nicer error message until we figure out the cause.
19073 // https://github.com/facebook/react/issues/12449#issuecomment-386727431
19074 !(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;
19075
19076 var sourceFiber = nextUnitOfWork;
19077 var returnFiber = sourceFiber.return;
19078 if (returnFiber === null) {
19079 // This is the root. The root could capture its own errors. However,
19080 // we don't know if it errors before or after we pushed the host
19081 // context. This information is needed to avoid a stack mismatch.
19082 // Because we're not sure, treat this as a fatal error. We could track
19083 // which phase it fails in, but doesn't seem worth it. At least
19084 // for now.
19085 didFatal = true;
19086 onUncaughtError(thrownValue);
19087 } else {
19088 throwException(root, returnFiber, sourceFiber, thrownValue, nextRenderExpirationTime);
19089 nextUnitOfWork = completeUnitOfWork(sourceFiber);
19090 continue;
19091 }
19092 }
19093 }
19094 break;
19095 } while (true);
19096
19097 if (enableSchedulerTracing) {
19098 // Traced work is done for now; restore the previous interactions.
19099 __interactionsRef.current = prevInteractions;
19100 }
19101
19102 // We're done performing work. Time to clean up.
19103 isWorking = false;
19104 ReactCurrentDispatcher.current = previousDispatcher;
19105 resetContextDependences();
19106 resetHooks();
19107
19108 // Yield back to main thread.
19109 if (didFatal) {
19110 var _didCompleteRoot = false;
19111 stopWorkLoopTimer(interruptedBy, _didCompleteRoot);
19112 interruptedBy = null;
19113 // There was a fatal error.
19114 {
19115 resetStackAfterFatalErrorInDev();
19116 }
19117 // `nextRoot` points to the in-progress root. A non-null value indicates
19118 // that we're in the middle of an async render. Set it to null to indicate
19119 // there's no more work to be done in the current batch.
19120 nextRoot = null;
19121 onFatal(root);
19122 return;
19123 }
19124
19125 if (nextUnitOfWork !== null) {
19126 // There's still remaining async work in this tree, but we ran out of time
19127 // in the current frame. Yield back to the renderer. Unless we're
19128 // interrupted by a higher priority update, we'll continue later from where
19129 // we left off.
19130 var _didCompleteRoot2 = false;
19131 stopWorkLoopTimer(interruptedBy, _didCompleteRoot2);
19132 interruptedBy = null;
19133 onYield(root);
19134 return;
19135 }
19136
19137 // We completed the whole tree.
19138 var didCompleteRoot = true;
19139 stopWorkLoopTimer(interruptedBy, didCompleteRoot);
19140 var rootWorkInProgress = root.current.alternate;
19141 !(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;
19142
19143 // `nextRoot` points to the in-progress root. A non-null value indicates
19144 // that we're in the middle of an async render. Set it to null to indicate
19145 // there's no more work to be done in the current batch.
19146 nextRoot = null;
19147 interruptedBy = null;
19148
19149 if (nextRenderDidError) {
19150 // There was an error
19151 if (hasLowerPriorityWork(root, expirationTime)) {
19152 // There's lower priority work. If so, it may have the effect of fixing
19153 // the exception that was just thrown. Exit without committing. This is
19154 // similar to a suspend, but without a timeout because we're not waiting
19155 // for a promise to resolve. React will restart at the lower
19156 // priority level.
19157 markSuspendedPriorityLevel(root, expirationTime);
19158 var suspendedExpirationTime = expirationTime;
19159 var rootExpirationTime = root.expirationTime;
19160 onSuspend(root, rootWorkInProgress, suspendedExpirationTime, rootExpirationTime, -1 // Indicates no timeout
19161 );
19162 return;
19163 } else if (
19164 // There's no lower priority work, but we're rendering asynchronously.
19165 // Synchronsouly attempt to render the same level one more time. This is
19166 // similar to a suspend, but without a timeout because we're not waiting
19167 // for a promise to resolve.
19168 !root.didError && isYieldy) {
19169 root.didError = true;
19170 var _suspendedExpirationTime = root.nextExpirationTimeToWorkOn = expirationTime;
19171 var _rootExpirationTime = root.expirationTime = Sync;
19172 onSuspend(root, rootWorkInProgress, _suspendedExpirationTime, _rootExpirationTime, -1 // Indicates no timeout
19173 );
19174 return;
19175 }
19176 }
19177
19178 if (isYieldy && nextLatestAbsoluteTimeoutMs !== -1) {
19179 // The tree was suspended.
19180 var _suspendedExpirationTime2 = expirationTime;
19181 markSuspendedPriorityLevel(root, _suspendedExpirationTime2);
19182
19183 // Find the earliest uncommitted expiration time in the tree, including
19184 // work that is suspended. The timeout threshold cannot be longer than
19185 // the overall expiration.
19186 var earliestExpirationTime = findEarliestOutstandingPriorityLevel(root, expirationTime);
19187 var earliestExpirationTimeMs = expirationTimeToMs(earliestExpirationTime);
19188 if (earliestExpirationTimeMs < nextLatestAbsoluteTimeoutMs) {
19189 nextLatestAbsoluteTimeoutMs = earliestExpirationTimeMs;
19190 }
19191
19192 // Subtract the current time from the absolute timeout to get the number
19193 // of milliseconds until the timeout. In other words, convert an absolute
19194 // timestamp to a relative time. This is the value that is passed
19195 // to `setTimeout`.
19196 var currentTimeMs = expirationTimeToMs(requestCurrentTime());
19197 var msUntilTimeout = nextLatestAbsoluteTimeoutMs - currentTimeMs;
19198 msUntilTimeout = msUntilTimeout < 0 ? 0 : msUntilTimeout;
19199
19200 // TODO: Account for the Just Noticeable Difference
19201
19202 var _rootExpirationTime2 = root.expirationTime;
19203 onSuspend(root, rootWorkInProgress, _suspendedExpirationTime2, _rootExpirationTime2, msUntilTimeout);
19204 return;
19205 }
19206
19207 // Ready to commit.
19208 onComplete(root, rootWorkInProgress, expirationTime);
19209}
19210
19211function captureCommitPhaseError(sourceFiber, value) {
19212 var expirationTime = Sync;
19213 var fiber = sourceFiber.return;
19214 while (fiber !== null) {
19215 switch (fiber.tag) {
19216 case ClassComponent:
19217 var ctor = fiber.type;
19218 var instance = fiber.stateNode;
19219 if (typeof ctor.getDerivedStateFromError === 'function' || typeof instance.componentDidCatch === 'function' && !isAlreadyFailedLegacyErrorBoundary(instance)) {
19220 var errorInfo = createCapturedValue(value, sourceFiber);
19221 var update = createClassErrorUpdate(fiber, errorInfo, expirationTime);
19222 enqueueUpdate(fiber, update);
19223 scheduleWork(fiber, expirationTime);
19224 return;
19225 }
19226 break;
19227 case HostRoot:
19228 {
19229 var _errorInfo = createCapturedValue(value, sourceFiber);
19230 var _update = createRootErrorUpdate(fiber, _errorInfo, expirationTime);
19231 enqueueUpdate(fiber, _update);
19232 scheduleWork(fiber, expirationTime);
19233 return;
19234 }
19235 }
19236 fiber = fiber.return;
19237 }
19238
19239 if (sourceFiber.tag === HostRoot) {
19240 // Error was thrown at the root. There is no parent, so the root
19241 // itself should capture it.
19242 var rootFiber = sourceFiber;
19243 var _errorInfo2 = createCapturedValue(value, rootFiber);
19244 var _update2 = createRootErrorUpdate(rootFiber, _errorInfo2, expirationTime);
19245 enqueueUpdate(rootFiber, _update2);
19246 scheduleWork(rootFiber, expirationTime);
19247 }
19248}
19249
19250function computeThreadID(expirationTime, interactionThreadID) {
19251 // Interaction threads are unique per root and expiration time.
19252 return expirationTime * 1000 + interactionThreadID;
19253}
19254
19255// Creates a unique async expiration time.
19256function computeUniqueAsyncExpiration() {
19257 var currentTime = requestCurrentTime();
19258 var result = computeAsyncExpiration(currentTime);
19259 if (result >= lastUniqueAsyncExpiration) {
19260 // Since we assume the current time monotonically increases, we only hit
19261 // this branch when computeUniqueAsyncExpiration is fired multiple times
19262 // within a 200ms window (or whatever the async bucket size is).
19263 result = lastUniqueAsyncExpiration - 1;
19264 }
19265 lastUniqueAsyncExpiration = result;
19266 return lastUniqueAsyncExpiration;
19267}
19268
19269function computeExpirationForFiber(currentTime, fiber) {
19270 var expirationTime = void 0;
19271 if (expirationContext !== NoWork) {
19272 // An explicit expiration context was set;
19273 expirationTime = expirationContext;
19274 } else if (isWorking) {
19275 if (isCommitting$1) {
19276 // Updates that occur during the commit phase should have sync priority
19277 // by default.
19278 expirationTime = Sync;
19279 } else {
19280 // Updates during the render phase should expire at the same time as
19281 // the work that is being rendered.
19282 expirationTime = nextRenderExpirationTime;
19283 }
19284 } else {
19285 // No explicit expiration context was set, and we're not currently
19286 // performing work. Calculate a new expiration time.
19287 if (fiber.mode & ConcurrentMode) {
19288 if (isBatchingInteractiveUpdates) {
19289 // This is an interactive update
19290 expirationTime = computeInteractiveExpiration(currentTime);
19291 } else {
19292 // This is an async update
19293 expirationTime = computeAsyncExpiration(currentTime);
19294 }
19295 // If we're in the middle of rendering a tree, do not update at the same
19296 // expiration time that is already rendering.
19297 if (nextRoot !== null && expirationTime === nextRenderExpirationTime) {
19298 expirationTime -= 1;
19299 }
19300 } else {
19301 // This is a sync update
19302 expirationTime = Sync;
19303 }
19304 }
19305 if (isBatchingInteractiveUpdates) {
19306 // This is an interactive update. Keep track of the lowest pending
19307 // interactive expiration time. This allows us to synchronously flush
19308 // all interactive updates when needed.
19309 if (lowestPriorityPendingInteractiveExpirationTime === NoWork || expirationTime < lowestPriorityPendingInteractiveExpirationTime) {
19310 lowestPriorityPendingInteractiveExpirationTime = expirationTime;
19311 }
19312 }
19313 return expirationTime;
19314}
19315
19316function renderDidSuspend(root, absoluteTimeoutMs, suspendedTime) {
19317 // Schedule the timeout.
19318 if (absoluteTimeoutMs >= 0 && nextLatestAbsoluteTimeoutMs < absoluteTimeoutMs) {
19319 nextLatestAbsoluteTimeoutMs = absoluteTimeoutMs;
19320 }
19321}
19322
19323function renderDidError() {
19324 nextRenderDidError = true;
19325}
19326
19327function pingSuspendedRoot(root, thenable, pingTime) {
19328 // A promise that previously suspended React from committing has resolved.
19329 // If React is still suspended, try again at the previous level (pingTime).
19330
19331 var pingCache = root.pingCache;
19332 if (pingCache !== null) {
19333 // The thenable resolved, so we no longer need to memoize, because it will
19334 // never be thrown again.
19335 pingCache.delete(thenable);
19336 }
19337
19338 if (nextRoot !== null && nextRenderExpirationTime === pingTime) {
19339 // Received a ping at the same priority level at which we're currently
19340 // rendering. Restart from the root.
19341 nextRoot = null;
19342 } else {
19343 // Confirm that the root is still suspended at this level. Otherwise exit.
19344 if (isPriorityLevelSuspended(root, pingTime)) {
19345 // Ping at the original level
19346 markPingedPriorityLevel(root, pingTime);
19347 var rootExpirationTime = root.expirationTime;
19348 if (rootExpirationTime !== NoWork) {
19349 requestWork(root, rootExpirationTime);
19350 }
19351 }
19352 }
19353}
19354
19355function retryTimedOutBoundary(boundaryFiber, thenable) {
19356 // The boundary fiber (a Suspense component) previously timed out and was
19357 // rendered in its fallback state. One of the promises that suspended it has
19358 // resolved, which means at least part of the tree was likely unblocked. Try
19359 var retryCache = boundaryFiber.stateNode;
19360 if (retryCache !== null) {
19361 // The thenable resolved, so we no longer need to memoize, because it will
19362 // never be thrown again.
19363 retryCache.delete(thenable);
19364 }
19365
19366 var currentTime = requestCurrentTime();
19367 var retryTime = computeExpirationForFiber(currentTime, boundaryFiber);
19368 var root = scheduleWorkToRoot(boundaryFiber, retryTime);
19369 if (root !== null) {
19370 markPendingPriorityLevel(root, retryTime);
19371 var rootExpirationTime = root.expirationTime;
19372 if (rootExpirationTime !== NoWork) {
19373 requestWork(root, rootExpirationTime);
19374 }
19375 }
19376}
19377
19378function scheduleWorkToRoot(fiber, expirationTime) {
19379 recordScheduleUpdate();
19380
19381 {
19382 if (fiber.tag === ClassComponent) {
19383 var instance = fiber.stateNode;
19384 warnAboutInvalidUpdates(instance);
19385 }
19386 }
19387
19388 // Update the source fiber's expiration time
19389 if (fiber.expirationTime < expirationTime) {
19390 fiber.expirationTime = expirationTime;
19391 }
19392 var alternate = fiber.alternate;
19393 if (alternate !== null && alternate.expirationTime < expirationTime) {
19394 alternate.expirationTime = expirationTime;
19395 }
19396 // Walk the parent path to the root and update the child expiration time.
19397 var node = fiber.return;
19398 var root = null;
19399 if (node === null && fiber.tag === HostRoot) {
19400 root = fiber.stateNode;
19401 } else {
19402 while (node !== null) {
19403 alternate = node.alternate;
19404 if (node.childExpirationTime < expirationTime) {
19405 node.childExpirationTime = expirationTime;
19406 if (alternate !== null && alternate.childExpirationTime < expirationTime) {
19407 alternate.childExpirationTime = expirationTime;
19408 }
19409 } else if (alternate !== null && alternate.childExpirationTime < expirationTime) {
19410 alternate.childExpirationTime = expirationTime;
19411 }
19412 if (node.return === null && node.tag === HostRoot) {
19413 root = node.stateNode;
19414 break;
19415 }
19416 node = node.return;
19417 }
19418 }
19419
19420 if (enableSchedulerTracing) {
19421 if (root !== null) {
19422 var interactions = __interactionsRef.current;
19423 if (interactions.size > 0) {
19424 var pendingInteractionMap = root.pendingInteractionMap;
19425 var pendingInteractions = pendingInteractionMap.get(expirationTime);
19426 if (pendingInteractions != null) {
19427 interactions.forEach(function (interaction) {
19428 if (!pendingInteractions.has(interaction)) {
19429 // Update the pending async work count for previously unscheduled interaction.
19430 interaction.__count++;
19431 }
19432
19433 pendingInteractions.add(interaction);
19434 });
19435 } else {
19436 pendingInteractionMap.set(expirationTime, new Set(interactions));
19437
19438 // Update the pending async work count for the current interactions.
19439 interactions.forEach(function (interaction) {
19440 interaction.__count++;
19441 });
19442 }
19443
19444 var subscriber = __subscriberRef.current;
19445 if (subscriber !== null) {
19446 var threadID = computeThreadID(expirationTime, root.interactionThreadID);
19447 subscriber.onWorkScheduled(interactions, threadID);
19448 }
19449 }
19450 }
19451 }
19452 return root;
19453}
19454
19455function warnIfNotCurrentlyBatchingInDev(fiber) {
19456 {
19457 if (isRendering === false && isBatchingUpdates === false) {
19458 warningWithoutStack$1(false, 'An update to %s inside a test was not wrapped in act(...).\n\n' + 'When testing, code that causes React state updates should be wrapped into act(...):\n\n' + 'act(() => {\n' + ' /* fire events that update state */\n' + '});\n' + '/* assert on the output */\n\n' + "This ensures that you're testing the behavior the user would see in the browser." + ' Learn more at https://fb.me/react-wrap-tests-with-act', getComponentName(fiber.type));
19459 }
19460 }
19461}
19462
19463function scheduleWork(fiber, expirationTime) {
19464 var root = scheduleWorkToRoot(fiber, expirationTime);
19465 if (root === null) {
19466 {
19467 switch (fiber.tag) {
19468 case ClassComponent:
19469 warnAboutUpdateOnUnmounted(fiber, true);
19470 break;
19471 case FunctionComponent:
19472 case ForwardRef:
19473 case MemoComponent:
19474 case SimpleMemoComponent:
19475 warnAboutUpdateOnUnmounted(fiber, false);
19476 break;
19477 }
19478 }
19479 return;
19480 }
19481
19482 if (!isWorking && nextRenderExpirationTime !== NoWork && expirationTime > nextRenderExpirationTime) {
19483 // This is an interruption. (Used for performance tracking.)
19484 interruptedBy = fiber;
19485 resetStack();
19486 }
19487 markPendingPriorityLevel(root, expirationTime);
19488 if (
19489 // If we're in the render phase, we don't need to schedule this root
19490 // for an update, because we'll do it before we exit...
19491 !isWorking || isCommitting$1 ||
19492 // ...unless this is a different root than the one we're rendering.
19493 nextRoot !== root) {
19494 var rootExpirationTime = root.expirationTime;
19495 requestWork(root, rootExpirationTime);
19496 }
19497 if (nestedUpdateCount > NESTED_UPDATE_LIMIT) {
19498 // Reset this back to zero so subsequent updates don't throw.
19499 nestedUpdateCount = 0;
19500 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.');
19501 }
19502}
19503
19504function syncUpdates(fn, a, b, c, d) {
19505 var previousExpirationContext = expirationContext;
19506 expirationContext = Sync;
19507 try {
19508 return fn(a, b, c, d);
19509 } finally {
19510 expirationContext = previousExpirationContext;
19511 }
19512}
19513
19514// TODO: Everything below this is written as if it has been lifted to the
19515// renderers. I'll do this in a follow-up.
19516
19517// Linked-list of roots
19518var firstScheduledRoot = null;
19519var lastScheduledRoot = null;
19520
19521var callbackExpirationTime = NoWork;
19522var callbackID = void 0;
19523var isRendering = false;
19524var nextFlushedRoot = null;
19525var nextFlushedExpirationTime = NoWork;
19526var lowestPriorityPendingInteractiveExpirationTime = NoWork;
19527var hasUnhandledError = false;
19528var unhandledError = null;
19529
19530var isBatchingUpdates = false;
19531var isUnbatchingUpdates = false;
19532var isBatchingInteractiveUpdates = false;
19533
19534var completedBatches = null;
19535
19536var originalStartTimeMs = unstable_now();
19537var currentRendererTime = msToExpirationTime(originalStartTimeMs);
19538var currentSchedulerTime = currentRendererTime;
19539
19540// Use these to prevent an infinite loop of nested updates
19541var NESTED_UPDATE_LIMIT = 50;
19542var nestedUpdateCount = 0;
19543var lastCommittedRootDuringThisBatch = null;
19544
19545function recomputeCurrentRendererTime() {
19546 var currentTimeMs = unstable_now() - originalStartTimeMs;
19547 currentRendererTime = msToExpirationTime(currentTimeMs);
19548}
19549
19550function scheduleCallbackWithExpirationTime(root, expirationTime) {
19551 if (callbackExpirationTime !== NoWork) {
19552 // A callback is already scheduled. Check its expiration time (timeout).
19553 if (expirationTime < callbackExpirationTime) {
19554 // Existing callback has sufficient timeout. Exit.
19555 return;
19556 } else {
19557 if (callbackID !== null) {
19558 // Existing callback has insufficient timeout. Cancel and schedule a
19559 // new one.
19560 unstable_cancelCallback(callbackID);
19561 }
19562 }
19563 // The request callback timer is already running. Don't start a new one.
19564 } else {
19565 startRequestCallbackTimer();
19566 }
19567
19568 callbackExpirationTime = expirationTime;
19569 var currentMs = unstable_now() - originalStartTimeMs;
19570 var expirationTimeMs = expirationTimeToMs(expirationTime);
19571 var timeout = expirationTimeMs - currentMs;
19572 callbackID = unstable_scheduleCallback(performAsyncWork, { timeout: timeout });
19573}
19574
19575// For every call to renderRoot, one of onFatal, onComplete, onSuspend, and
19576// onYield is called upon exiting. We use these in lieu of returning a tuple.
19577// I've also chosen not to inline them into renderRoot because these will
19578// eventually be lifted into the renderer.
19579function onFatal(root) {
19580 root.finishedWork = null;
19581}
19582
19583function onComplete(root, finishedWork, expirationTime) {
19584 root.pendingCommitExpirationTime = expirationTime;
19585 root.finishedWork = finishedWork;
19586}
19587
19588function onSuspend(root, finishedWork, suspendedExpirationTime, rootExpirationTime, msUntilTimeout) {
19589 root.expirationTime = rootExpirationTime;
19590 if (msUntilTimeout === 0 && !shouldYieldToRenderer()) {
19591 // Don't wait an additional tick. Commit the tree immediately.
19592 root.pendingCommitExpirationTime = suspendedExpirationTime;
19593 root.finishedWork = finishedWork;
19594 } else if (msUntilTimeout > 0) {
19595 // Wait `msUntilTimeout` milliseconds before committing.
19596 root.timeoutHandle = scheduleTimeout(onTimeout.bind(null, root, finishedWork, suspendedExpirationTime), msUntilTimeout);
19597 }
19598}
19599
19600function onYield(root) {
19601 root.finishedWork = null;
19602}
19603
19604function onTimeout(root, finishedWork, suspendedExpirationTime) {
19605 // The root timed out. Commit it.
19606 root.pendingCommitExpirationTime = suspendedExpirationTime;
19607 root.finishedWork = finishedWork;
19608 // Read the current time before entering the commit phase. We can be
19609 // certain this won't cause tearing related to batching of event updates
19610 // because we're at the top of a timer event.
19611 recomputeCurrentRendererTime();
19612 currentSchedulerTime = currentRendererTime;
19613 flushRoot(root, suspendedExpirationTime);
19614}
19615
19616function onCommit(root, expirationTime) {
19617 root.expirationTime = expirationTime;
19618 root.finishedWork = null;
19619}
19620
19621function requestCurrentTime() {
19622 // requestCurrentTime is called by the scheduler to compute an expiration
19623 // time.
19624 //
19625 // Expiration times are computed by adding to the current time (the start
19626 // time). However, if two updates are scheduled within the same event, we
19627 // should treat their start times as simultaneous, even if the actual clock
19628 // time has advanced between the first and second call.
19629
19630 // In other words, because expiration times determine how updates are batched,
19631 // we want all updates of like priority that occur within the same event to
19632 // receive the same expiration time. Otherwise we get tearing.
19633 //
19634 // We keep track of two separate times: the current "renderer" time and the
19635 // current "scheduler" time. The renderer time can be updated whenever; it
19636 // only exists to minimize the calls performance.now.
19637 //
19638 // But the scheduler time can only be updated if there's no pending work, or
19639 // if we know for certain that we're not in the middle of an event.
19640
19641 if (isRendering) {
19642 // We're already rendering. Return the most recently read time.
19643 return currentSchedulerTime;
19644 }
19645 // Check if there's pending work.
19646 findHighestPriorityRoot();
19647 if (nextFlushedExpirationTime === NoWork || nextFlushedExpirationTime === Never) {
19648 // If there's no pending work, or if the pending work is offscreen, we can
19649 // read the current time without risk of tearing.
19650 recomputeCurrentRendererTime();
19651 currentSchedulerTime = currentRendererTime;
19652 return currentSchedulerTime;
19653 }
19654 // There's already pending work. We might be in the middle of a browser
19655 // event. If we were to read the current time, it could cause multiple updates
19656 // within the same event to receive different expiration times, leading to
19657 // tearing. Return the last read time. During the next idle callback, the
19658 // time will be updated.
19659 return currentSchedulerTime;
19660}
19661
19662// requestWork is called by the scheduler whenever a root receives an update.
19663// It's up to the renderer to call renderRoot at some point in the future.
19664function requestWork(root, expirationTime) {
19665 addRootToSchedule(root, expirationTime);
19666 if (isRendering) {
19667 // Prevent reentrancy. Remaining work will be scheduled at the end of
19668 // the currently rendering batch.
19669 return;
19670 }
19671
19672 if (isBatchingUpdates) {
19673 // Flush work at the end of the batch.
19674 if (isUnbatchingUpdates) {
19675 // ...unless we're inside unbatchedUpdates, in which case we should
19676 // flush it now.
19677 nextFlushedRoot = root;
19678 nextFlushedExpirationTime = Sync;
19679 performWorkOnRoot(root, Sync, false);
19680 }
19681 return;
19682 }
19683
19684 // TODO: Get rid of Sync and use current time?
19685 if (expirationTime === Sync) {
19686 performSyncWork();
19687 } else {
19688 scheduleCallbackWithExpirationTime(root, expirationTime);
19689 }
19690}
19691
19692function addRootToSchedule(root, expirationTime) {
19693 // Add the root to the schedule.
19694 // Check if this root is already part of the schedule.
19695 if (root.nextScheduledRoot === null) {
19696 // This root is not already scheduled. Add it.
19697 root.expirationTime = expirationTime;
19698 if (lastScheduledRoot === null) {
19699 firstScheduledRoot = lastScheduledRoot = root;
19700 root.nextScheduledRoot = root;
19701 } else {
19702 lastScheduledRoot.nextScheduledRoot = root;
19703 lastScheduledRoot = root;
19704 lastScheduledRoot.nextScheduledRoot = firstScheduledRoot;
19705 }
19706 } else {
19707 // This root is already scheduled, but its priority may have increased.
19708 var remainingExpirationTime = root.expirationTime;
19709 if (expirationTime > remainingExpirationTime) {
19710 // Update the priority.
19711 root.expirationTime = expirationTime;
19712 }
19713 }
19714}
19715
19716function findHighestPriorityRoot() {
19717 var highestPriorityWork = NoWork;
19718 var highestPriorityRoot = null;
19719 if (lastScheduledRoot !== null) {
19720 var previousScheduledRoot = lastScheduledRoot;
19721 var root = firstScheduledRoot;
19722 while (root !== null) {
19723 var remainingExpirationTime = root.expirationTime;
19724 if (remainingExpirationTime === NoWork) {
19725 // This root no longer has work. Remove it from the scheduler.
19726
19727 // TODO: This check is redudant, but Flow is confused by the branch
19728 // below where we set lastScheduledRoot to null, even though we break
19729 // from the loop right after.
19730 !(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;
19731 if (root === root.nextScheduledRoot) {
19732 // This is the only root in the list.
19733 root.nextScheduledRoot = null;
19734 firstScheduledRoot = lastScheduledRoot = null;
19735 break;
19736 } else if (root === firstScheduledRoot) {
19737 // This is the first root in the list.
19738 var next = root.nextScheduledRoot;
19739 firstScheduledRoot = next;
19740 lastScheduledRoot.nextScheduledRoot = next;
19741 root.nextScheduledRoot = null;
19742 } else if (root === lastScheduledRoot) {
19743 // This is the last root in the list.
19744 lastScheduledRoot = previousScheduledRoot;
19745 lastScheduledRoot.nextScheduledRoot = firstScheduledRoot;
19746 root.nextScheduledRoot = null;
19747 break;
19748 } else {
19749 previousScheduledRoot.nextScheduledRoot = root.nextScheduledRoot;
19750 root.nextScheduledRoot = null;
19751 }
19752 root = previousScheduledRoot.nextScheduledRoot;
19753 } else {
19754 if (remainingExpirationTime > highestPriorityWork) {
19755 // Update the priority, if it's higher
19756 highestPriorityWork = remainingExpirationTime;
19757 highestPriorityRoot = root;
19758 }
19759 if (root === lastScheduledRoot) {
19760 break;
19761 }
19762 if (highestPriorityWork === Sync) {
19763 // Sync is highest priority by definition so
19764 // we can stop searching.
19765 break;
19766 }
19767 previousScheduledRoot = root;
19768 root = root.nextScheduledRoot;
19769 }
19770 }
19771 }
19772
19773 nextFlushedRoot = highestPriorityRoot;
19774 nextFlushedExpirationTime = highestPriorityWork;
19775}
19776
19777// TODO: This wrapper exists because many of the older tests (the ones that use
19778// flushDeferredPri) rely on the number of times `shouldYield` is called. We
19779// should get rid of it.
19780var didYield = false;
19781function shouldYieldToRenderer() {
19782 if (didYield) {
19783 return true;
19784 }
19785 if (unstable_shouldYield()) {
19786 didYield = true;
19787 return true;
19788 }
19789 return false;
19790}
19791
19792function performAsyncWork() {
19793 try {
19794 if (!shouldYieldToRenderer()) {
19795 // The callback timed out. That means at least one update has expired.
19796 // Iterate through the root schedule. If they contain expired work, set
19797 // the next render expiration time to the current time. This has the effect
19798 // of flushing all expired work in a single batch, instead of flushing each
19799 // level one at a time.
19800 if (firstScheduledRoot !== null) {
19801 recomputeCurrentRendererTime();
19802 var root = firstScheduledRoot;
19803 do {
19804 didExpireAtExpirationTime(root, currentRendererTime);
19805 // The root schedule is circular, so this is never null.
19806 root = root.nextScheduledRoot;
19807 } while (root !== firstScheduledRoot);
19808 }
19809 }
19810 performWork(NoWork, true);
19811 } finally {
19812 didYield = false;
19813 }
19814}
19815
19816function performSyncWork() {
19817 performWork(Sync, false);
19818}
19819
19820function performWork(minExpirationTime, isYieldy) {
19821 // Keep working on roots until there's no more work, or until there's a higher
19822 // priority event.
19823 findHighestPriorityRoot();
19824
19825 if (isYieldy) {
19826 recomputeCurrentRendererTime();
19827 currentSchedulerTime = currentRendererTime;
19828
19829 if (enableUserTimingAPI) {
19830 var didExpire = nextFlushedExpirationTime > currentRendererTime;
19831 var timeout = expirationTimeToMs(nextFlushedExpirationTime);
19832 stopRequestCallbackTimer(didExpire, timeout);
19833 }
19834
19835 while (nextFlushedRoot !== null && nextFlushedExpirationTime !== NoWork && minExpirationTime <= nextFlushedExpirationTime && !(didYield && currentRendererTime > nextFlushedExpirationTime)) {
19836 performWorkOnRoot(nextFlushedRoot, nextFlushedExpirationTime, currentRendererTime > nextFlushedExpirationTime);
19837 findHighestPriorityRoot();
19838 recomputeCurrentRendererTime();
19839 currentSchedulerTime = currentRendererTime;
19840 }
19841 } else {
19842 while (nextFlushedRoot !== null && nextFlushedExpirationTime !== NoWork && minExpirationTime <= nextFlushedExpirationTime) {
19843 performWorkOnRoot(nextFlushedRoot, nextFlushedExpirationTime, false);
19844 findHighestPriorityRoot();
19845 }
19846 }
19847
19848 // We're done flushing work. Either we ran out of time in this callback,
19849 // or there's no more work left with sufficient priority.
19850
19851 // If we're inside a callback, set this to false since we just completed it.
19852 if (isYieldy) {
19853 callbackExpirationTime = NoWork;
19854 callbackID = null;
19855 }
19856 // If there's work left over, schedule a new callback.
19857 if (nextFlushedExpirationTime !== NoWork) {
19858 scheduleCallbackWithExpirationTime(nextFlushedRoot, nextFlushedExpirationTime);
19859 }
19860
19861 // Clean-up.
19862 finishRendering();
19863}
19864
19865function flushRoot(root, expirationTime) {
19866 !!isRendering ? invariant(false, 'work.commit(): Cannot commit while already rendering. This likely means you attempted to commit from inside a lifecycle method.') : void 0;
19867 // Perform work on root as if the given expiration time is the current time.
19868 // This has the effect of synchronously flushing all work up to and
19869 // including the given time.
19870 nextFlushedRoot = root;
19871 nextFlushedExpirationTime = expirationTime;
19872 performWorkOnRoot(root, expirationTime, false);
19873 // Flush any sync work that was scheduled by lifecycles
19874 performSyncWork();
19875}
19876
19877function finishRendering() {
19878 nestedUpdateCount = 0;
19879 lastCommittedRootDuringThisBatch = null;
19880
19881 if (completedBatches !== null) {
19882 var batches = completedBatches;
19883 completedBatches = null;
19884 for (var i = 0; i < batches.length; i++) {
19885 var batch = batches[i];
19886 try {
19887 batch._onComplete();
19888 } catch (error) {
19889 if (!hasUnhandledError) {
19890 hasUnhandledError = true;
19891 unhandledError = error;
19892 }
19893 }
19894 }
19895 }
19896
19897 if (hasUnhandledError) {
19898 var error = unhandledError;
19899 unhandledError = null;
19900 hasUnhandledError = false;
19901 throw error;
19902 }
19903}
19904
19905function performWorkOnRoot(root, expirationTime, isYieldy) {
19906 !!isRendering ? invariant(false, 'performWorkOnRoot was called recursively. This error is likely caused by a bug in React. Please file an issue.') : void 0;
19907
19908 isRendering = true;
19909
19910 // Check if this is async work or sync/expired work.
19911 if (!isYieldy) {
19912 // Flush work without yielding.
19913 // TODO: Non-yieldy work does not necessarily imply expired work. A renderer
19914 // may want to perform some work without yielding, but also without
19915 // requiring the root to complete (by triggering placeholders).
19916
19917 var finishedWork = root.finishedWork;
19918 if (finishedWork !== null) {
19919 // This root is already complete. We can commit it.
19920 completeRoot(root, finishedWork, expirationTime);
19921 } else {
19922 root.finishedWork = null;
19923 // If this root previously suspended, clear its existing timeout, since
19924 // we're about to try rendering again.
19925 var timeoutHandle = root.timeoutHandle;
19926 if (timeoutHandle !== noTimeout) {
19927 root.timeoutHandle = noTimeout;
19928 // $FlowFixMe Complains noTimeout is not a TimeoutID, despite the check above
19929 cancelTimeout(timeoutHandle);
19930 }
19931 renderRoot(root, isYieldy);
19932 finishedWork = root.finishedWork;
19933 if (finishedWork !== null) {
19934 // We've completed the root. Commit it.
19935 completeRoot(root, finishedWork, expirationTime);
19936 }
19937 }
19938 } else {
19939 // Flush async work.
19940 var _finishedWork = root.finishedWork;
19941 if (_finishedWork !== null) {
19942 // This root is already complete. We can commit it.
19943 completeRoot(root, _finishedWork, expirationTime);
19944 } else {
19945 root.finishedWork = null;
19946 // If this root previously suspended, clear its existing timeout, since
19947 // we're about to try rendering again.
19948 var _timeoutHandle = root.timeoutHandle;
19949 if (_timeoutHandle !== noTimeout) {
19950 root.timeoutHandle = noTimeout;
19951 // $FlowFixMe Complains noTimeout is not a TimeoutID, despite the check above
19952 cancelTimeout(_timeoutHandle);
19953 }
19954 renderRoot(root, isYieldy);
19955 _finishedWork = root.finishedWork;
19956 if (_finishedWork !== null) {
19957 // We've completed the root. Check the if we should yield one more time
19958 // before committing.
19959 if (!shouldYieldToRenderer()) {
19960 // Still time left. Commit the root.
19961 completeRoot(root, _finishedWork, expirationTime);
19962 } else {
19963 // There's no time left. Mark this root as complete. We'll come
19964 // back and commit it later.
19965 root.finishedWork = _finishedWork;
19966 }
19967 }
19968 }
19969 }
19970
19971 isRendering = false;
19972}
19973
19974function completeRoot(root, finishedWork, expirationTime) {
19975 // Check if there's a batch that matches this expiration time.
19976 var firstBatch = root.firstBatch;
19977 if (firstBatch !== null && firstBatch._expirationTime >= expirationTime) {
19978 if (completedBatches === null) {
19979 completedBatches = [firstBatch];
19980 } else {
19981 completedBatches.push(firstBatch);
19982 }
19983 if (firstBatch._defer) {
19984 // This root is blocked from committing by a batch. Unschedule it until
19985 // we receive another update.
19986 root.finishedWork = finishedWork;
19987 root.expirationTime = NoWork;
19988 return;
19989 }
19990 }
19991
19992 // Commit the root.
19993 root.finishedWork = null;
19994
19995 // Check if this is a nested update (a sync update scheduled during the
19996 // commit phase).
19997 if (root === lastCommittedRootDuringThisBatch) {
19998 // If the next root is the same as the previous root, this is a nested
19999 // update. To prevent an infinite loop, increment the nested update count.
20000 nestedUpdateCount++;
20001 } else {
20002 // Reset whenever we switch roots.
20003 lastCommittedRootDuringThisBatch = root;
20004 nestedUpdateCount = 0;
20005 }
20006 commitRoot(root, finishedWork);
20007}
20008
20009function onUncaughtError(error) {
20010 !(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;
20011 // Unschedule this root so we don't work on it again until there's
20012 // another update.
20013 nextFlushedRoot.expirationTime = NoWork;
20014 if (!hasUnhandledError) {
20015 hasUnhandledError = true;
20016 unhandledError = error;
20017 }
20018}
20019
20020// TODO: Batching should be implemented at the renderer level, not inside
20021// the reconciler.
20022function batchedUpdates$1(fn, a) {
20023 var previousIsBatchingUpdates = isBatchingUpdates;
20024 isBatchingUpdates = true;
20025 try {
20026 return fn(a);
20027 } finally {
20028 isBatchingUpdates = previousIsBatchingUpdates;
20029 if (!isBatchingUpdates && !isRendering) {
20030 performSyncWork();
20031 }
20032 }
20033}
20034
20035// TODO: Batching should be implemented at the renderer level, not inside
20036// the reconciler.
20037function unbatchedUpdates(fn, a) {
20038 if (isBatchingUpdates && !isUnbatchingUpdates) {
20039 isUnbatchingUpdates = true;
20040 try {
20041 return fn(a);
20042 } finally {
20043 isUnbatchingUpdates = false;
20044 }
20045 }
20046 return fn(a);
20047}
20048
20049// TODO: Batching should be implemented at the renderer level, not within
20050// the reconciler.
20051function flushSync(fn, a) {
20052 !!isRendering ? invariant(false, 'flushSync was called from inside a lifecycle method. It cannot be called when React is already rendering.') : void 0;
20053 var previousIsBatchingUpdates = isBatchingUpdates;
20054 isBatchingUpdates = true;
20055 try {
20056 return syncUpdates(fn, a);
20057 } finally {
20058 isBatchingUpdates = previousIsBatchingUpdates;
20059 performSyncWork();
20060 }
20061}
20062
20063function interactiveUpdates$1(fn, a, b) {
20064 if (isBatchingInteractiveUpdates) {
20065 return fn(a, b);
20066 }
20067 // If there are any pending interactive updates, synchronously flush them.
20068 // This needs to happen before we read any handlers, because the effect of
20069 // the previous event may influence which handlers are called during
20070 // this event.
20071 if (!isBatchingUpdates && !isRendering && lowestPriorityPendingInteractiveExpirationTime !== NoWork) {
20072 // Synchronously flush pending interactive updates.
20073 performWork(lowestPriorityPendingInteractiveExpirationTime, false);
20074 lowestPriorityPendingInteractiveExpirationTime = NoWork;
20075 }
20076 var previousIsBatchingInteractiveUpdates = isBatchingInteractiveUpdates;
20077 var previousIsBatchingUpdates = isBatchingUpdates;
20078 isBatchingInteractiveUpdates = true;
20079 isBatchingUpdates = true;
20080 try {
20081 return fn(a, b);
20082 } finally {
20083 isBatchingInteractiveUpdates = previousIsBatchingInteractiveUpdates;
20084 isBatchingUpdates = previousIsBatchingUpdates;
20085 if (!isBatchingUpdates && !isRendering) {
20086 performSyncWork();
20087 }
20088 }
20089}
20090
20091function flushInteractiveUpdates$1() {
20092 if (!isRendering && lowestPriorityPendingInteractiveExpirationTime !== NoWork) {
20093 // Synchronously flush pending interactive updates.
20094 performWork(lowestPriorityPendingInteractiveExpirationTime, false);
20095 lowestPriorityPendingInteractiveExpirationTime = NoWork;
20096 }
20097}
20098
20099function flushControlled(fn) {
20100 var previousIsBatchingUpdates = isBatchingUpdates;
20101 isBatchingUpdates = true;
20102 try {
20103 syncUpdates(fn);
20104 } finally {
20105 isBatchingUpdates = previousIsBatchingUpdates;
20106 if (!isBatchingUpdates && !isRendering) {
20107 performSyncWork();
20108 }
20109 }
20110}
20111
20112// 0 is PROD, 1 is DEV.
20113// Might add PROFILE later.
20114
20115
20116var didWarnAboutNestedUpdates = void 0;
20117var didWarnAboutFindNodeInStrictMode = void 0;
20118
20119{
20120 didWarnAboutNestedUpdates = false;
20121 didWarnAboutFindNodeInStrictMode = {};
20122}
20123
20124function getContextForSubtree(parentComponent) {
20125 if (!parentComponent) {
20126 return emptyContextObject;
20127 }
20128
20129 var fiber = get(parentComponent);
20130 var parentContext = findCurrentUnmaskedContext(fiber);
20131
20132 if (fiber.tag === ClassComponent) {
20133 var Component = fiber.type;
20134 if (isContextProvider(Component)) {
20135 return processChildContext(fiber, Component, parentContext);
20136 }
20137 }
20138
20139 return parentContext;
20140}
20141
20142function scheduleRootUpdate(current$$1, element, expirationTime, callback) {
20143 {
20144 if (phase === 'render' && current !== null && !didWarnAboutNestedUpdates) {
20145 didWarnAboutNestedUpdates = true;
20146 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');
20147 }
20148 }
20149
20150 var update = createUpdate(expirationTime);
20151 // Caution: React DevTools currently depends on this property
20152 // being called "element".
20153 update.payload = { element: element };
20154
20155 callback = callback === undefined ? null : callback;
20156 if (callback !== null) {
20157 !(typeof callback === 'function') ? warningWithoutStack$1(false, 'render(...): Expected the last optional `callback` argument to be a ' + 'function. Instead received: %s.', callback) : void 0;
20158 update.callback = callback;
20159 }
20160
20161 flushPassiveEffects();
20162 enqueueUpdate(current$$1, update);
20163 scheduleWork(current$$1, expirationTime);
20164
20165 return expirationTime;
20166}
20167
20168function updateContainerAtExpirationTime(element, container, parentComponent, expirationTime, callback) {
20169 // TODO: If this is a nested container, this won't be the root.
20170 var current$$1 = container.current;
20171
20172 {
20173 if (ReactFiberInstrumentation_1.debugTool) {
20174 if (current$$1.alternate === null) {
20175 ReactFiberInstrumentation_1.debugTool.onMountContainer(container);
20176 } else if (element === null) {
20177 ReactFiberInstrumentation_1.debugTool.onUnmountContainer(container);
20178 } else {
20179 ReactFiberInstrumentation_1.debugTool.onUpdateContainer(container);
20180 }
20181 }
20182 }
20183
20184 var context = getContextForSubtree(parentComponent);
20185 if (container.context === null) {
20186 container.context = context;
20187 } else {
20188 container.pendingContext = context;
20189 }
20190
20191 return scheduleRootUpdate(current$$1, element, expirationTime, callback);
20192}
20193
20194function findHostInstance(component) {
20195 var fiber = get(component);
20196 if (fiber === undefined) {
20197 if (typeof component.render === 'function') {
20198 invariant(false, 'Unable to find node on an unmounted component.');
20199 } else {
20200 invariant(false, 'Argument appears to not be a ReactComponent. Keys: %s', Object.keys(component));
20201 }
20202 }
20203 var hostFiber = findCurrentHostFiber(fiber);
20204 if (hostFiber === null) {
20205 return null;
20206 }
20207 return hostFiber.stateNode;
20208}
20209
20210function findHostInstanceWithWarning(component, methodName) {
20211 {
20212 var fiber = get(component);
20213 if (fiber === undefined) {
20214 if (typeof component.render === 'function') {
20215 invariant(false, 'Unable to find node on an unmounted component.');
20216 } else {
20217 invariant(false, 'Argument appears to not be a ReactComponent. Keys: %s', Object.keys(component));
20218 }
20219 }
20220 var hostFiber = findCurrentHostFiber(fiber);
20221 if (hostFiber === null) {
20222 return null;
20223 }
20224 if (hostFiber.mode & StrictMode) {
20225 var componentName = getComponentName(fiber.type) || 'Component';
20226 if (!didWarnAboutFindNodeInStrictMode[componentName]) {
20227 didWarnAboutFindNodeInStrictMode[componentName] = true;
20228 if (fiber.mode & StrictMode) {
20229 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));
20230 } else {
20231 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));
20232 }
20233 }
20234 }
20235 return hostFiber.stateNode;
20236 }
20237 return findHostInstance(component);
20238}
20239
20240function createContainer(containerInfo, isConcurrent, hydrate) {
20241 return createFiberRoot(containerInfo, isConcurrent, hydrate);
20242}
20243
20244function updateContainer(element, container, parentComponent, callback) {
20245 var current$$1 = container.current;
20246 var currentTime = requestCurrentTime();
20247 var expirationTime = computeExpirationForFiber(currentTime, current$$1);
20248 return updateContainerAtExpirationTime(element, container, parentComponent, expirationTime, callback);
20249}
20250
20251function getPublicRootInstance(container) {
20252 var containerFiber = container.current;
20253 if (!containerFiber.child) {
20254 return null;
20255 }
20256 switch (containerFiber.child.tag) {
20257 case HostComponent:
20258 return getPublicInstance(containerFiber.child.stateNode);
20259 default:
20260 return containerFiber.child.stateNode;
20261 }
20262}
20263
20264function findHostInstanceWithNoPortals(fiber) {
20265 var hostFiber = findCurrentHostFiberWithNoPortals(fiber);
20266 if (hostFiber === null) {
20267 return null;
20268 }
20269 return hostFiber.stateNode;
20270}
20271
20272var overrideProps = null;
20273
20274{
20275 var copyWithSetImpl = function (obj, path, idx, value) {
20276 if (idx >= path.length) {
20277 return value;
20278 }
20279 var key = path[idx];
20280 var updated = Array.isArray(obj) ? obj.slice() : _assign({}, obj);
20281 // $FlowFixMe number or string is fine here
20282 updated[key] = copyWithSetImpl(obj[key], path, idx + 1, value);
20283 return updated;
20284 };
20285
20286 var copyWithSet = function (obj, path, value) {
20287 return copyWithSetImpl(obj, path, 0, value);
20288 };
20289
20290 // Support DevTools props for function components, forwardRef, memo, host components, etc.
20291 overrideProps = function (fiber, path, value) {
20292 flushPassiveEffects();
20293 fiber.pendingProps = copyWithSet(fiber.memoizedProps, path, value);
20294 if (fiber.alternate) {
20295 fiber.alternate.pendingProps = fiber.pendingProps;
20296 }
20297 scheduleWork(fiber, Sync);
20298 };
20299}
20300
20301function injectIntoDevTools(devToolsConfig) {
20302 var findFiberByHostInstance = devToolsConfig.findFiberByHostInstance;
20303 var ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher;
20304
20305
20306 return injectInternals(_assign({}, devToolsConfig, {
20307 overrideProps: overrideProps,
20308 currentDispatcherRef: ReactCurrentDispatcher,
20309 findHostInstanceByFiber: function (fiber) {
20310 var hostFiber = findCurrentHostFiber(fiber);
20311 if (hostFiber === null) {
20312 return null;
20313 }
20314 return hostFiber.stateNode;
20315 },
20316 findFiberByHostInstance: function (instance) {
20317 if (!findFiberByHostInstance) {
20318 // Might not be implemented by the renderer.
20319 return null;
20320 }
20321 return findFiberByHostInstance(instance);
20322 }
20323 }));
20324}
20325
20326// This file intentionally does *not* have the Flow annotation.
20327// Don't add it. See `./inline-typed.js` for an explanation.
20328
20329function createPortal$1(children, containerInfo,
20330// TODO: figure out the API for cross-renderer implementation.
20331implementation) {
20332 var key = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null;
20333
20334 return {
20335 // This tag allow us to uniquely identify this as a React Portal
20336 $$typeof: REACT_PORTAL_TYPE,
20337 key: key == null ? null : '' + key,
20338 children: children,
20339 containerInfo: containerInfo,
20340 implementation: implementation
20341 };
20342}
20343
20344// TODO: this is special because it gets imported during build.
20345
20346var ReactVersion = '16.8.0';
20347
20348// This file is copy paste from ReactDOM with adjusted paths
20349// and a different host config import (react-reconciler/inline.fire).
20350// TODO: real implementation.
20351// console.log('Hello from Fire entry point.');
20352
20353// TODO: This type is shared between the reconciler and ReactDOM, but will
20354// eventually be lifted out to the renderer.
20355
20356var ReactCurrentOwner = ReactSharedInternals.ReactCurrentOwner;
20357
20358var topLevelUpdateWarnings = void 0;
20359var warnOnInvalidCallback = void 0;
20360var didWarnAboutUnstableCreatePortal = false;
20361
20362{
20363 if (typeof Map !== 'function' ||
20364 // $FlowIssue Flow incorrectly thinks Map has no prototype
20365 Map.prototype == null || typeof Map.prototype.forEach !== 'function' || typeof Set !== 'function' ||
20366 // $FlowIssue Flow incorrectly thinks Set has no prototype
20367 Set.prototype == null || typeof Set.prototype.clear !== 'function' || typeof Set.prototype.forEach !== 'function') {
20368 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');
20369 }
20370
20371 topLevelUpdateWarnings = function (container) {
20372 if (container._reactRootContainer && container.nodeType !== COMMENT_NODE) {
20373 var hostInstance = findHostInstanceWithNoPortals(container._reactRootContainer._internalRoot.current);
20374 if (hostInstance) {
20375 !(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;
20376 }
20377 }
20378
20379 var isRootRenderedBySomeReact = !!container._reactRootContainer;
20380 var rootEl = getReactRootElementInContainer(container);
20381 var hasNonRootReactChild = !!(rootEl && getInstanceFromNode$1(rootEl));
20382
20383 !(!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;
20384
20385 !(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;
20386 };
20387
20388 warnOnInvalidCallback = function (callback, callerName) {
20389 !(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;
20390 };
20391}
20392
20393setRestoreImplementation(restoreControlledState$1);
20394
20395function ReactBatch(root) {
20396 var expirationTime = computeUniqueAsyncExpiration();
20397 this._expirationTime = expirationTime;
20398 this._root = root;
20399 this._next = null;
20400 this._callbacks = null;
20401 this._didComplete = false;
20402 this._hasChildren = false;
20403 this._children = null;
20404 this._defer = true;
20405}
20406ReactBatch.prototype.render = function (children) {
20407 !this._defer ? invariant(false, 'batch.render: Cannot render a batch that already committed.') : void 0;
20408 this._hasChildren = true;
20409 this._children = children;
20410 var internalRoot = this._root._internalRoot;
20411 var expirationTime = this._expirationTime;
20412 var work = new ReactWork();
20413 updateContainerAtExpirationTime(children, internalRoot, null, expirationTime, work._onCommit);
20414 return work;
20415};
20416ReactBatch.prototype.then = function (onComplete) {
20417 if (this._didComplete) {
20418 onComplete();
20419 return;
20420 }
20421 var callbacks = this._callbacks;
20422 if (callbacks === null) {
20423 callbacks = this._callbacks = [];
20424 }
20425 callbacks.push(onComplete);
20426};
20427ReactBatch.prototype.commit = function () {
20428 var internalRoot = this._root._internalRoot;
20429 var firstBatch = internalRoot.firstBatch;
20430 !(this._defer && firstBatch !== null) ? invariant(false, 'batch.commit: Cannot commit a batch multiple times.') : void 0;
20431
20432 if (!this._hasChildren) {
20433 // This batch is empty. Return.
20434 this._next = null;
20435 this._defer = false;
20436 return;
20437 }
20438
20439 var expirationTime = this._expirationTime;
20440
20441 // Ensure this is the first batch in the list.
20442 if (firstBatch !== this) {
20443 // This batch is not the earliest batch. We need to move it to the front.
20444 // Update its expiration time to be the expiration time of the earliest
20445 // batch, so that we can flush it without flushing the other batches.
20446 if (this._hasChildren) {
20447 expirationTime = this._expirationTime = firstBatch._expirationTime;
20448 // Rendering this batch again ensures its children will be the final state
20449 // when we flush (updates are processed in insertion order: last
20450 // update wins).
20451 // TODO: This forces a restart. Should we print a warning?
20452 this.render(this._children);
20453 }
20454
20455 // Remove the batch from the list.
20456 var previous = null;
20457 var batch = firstBatch;
20458 while (batch !== this) {
20459 previous = batch;
20460 batch = batch._next;
20461 }
20462 !(previous !== null) ? invariant(false, 'batch.commit: Cannot commit a batch multiple times.') : void 0;
20463 previous._next = batch._next;
20464
20465 // Add it to the front.
20466 this._next = firstBatch;
20467 firstBatch = internalRoot.firstBatch = this;
20468 }
20469
20470 // Synchronously flush all the work up to this batch's expiration time.
20471 this._defer = false;
20472 flushRoot(internalRoot, expirationTime);
20473
20474 // Pop the batch from the list.
20475 var next = this._next;
20476 this._next = null;
20477 firstBatch = internalRoot.firstBatch = next;
20478
20479 // Append the next earliest batch's children to the update queue.
20480 if (firstBatch !== null && firstBatch._hasChildren) {
20481 firstBatch.render(firstBatch._children);
20482 }
20483};
20484ReactBatch.prototype._onComplete = function () {
20485 if (this._didComplete) {
20486 return;
20487 }
20488 this._didComplete = true;
20489 var callbacks = this._callbacks;
20490 if (callbacks === null) {
20491 return;
20492 }
20493 // TODO: Error handling.
20494 for (var i = 0; i < callbacks.length; i++) {
20495 var _callback = callbacks[i];
20496 _callback();
20497 }
20498};
20499
20500function ReactWork() {
20501 this._callbacks = null;
20502 this._didCommit = false;
20503 // TODO: Avoid need to bind by replacing callbacks in the update queue with
20504 // list of Work objects.
20505 this._onCommit = this._onCommit.bind(this);
20506}
20507ReactWork.prototype.then = function (onCommit) {
20508 if (this._didCommit) {
20509 onCommit();
20510 return;
20511 }
20512 var callbacks = this._callbacks;
20513 if (callbacks === null) {
20514 callbacks = this._callbacks = [];
20515 }
20516 callbacks.push(onCommit);
20517};
20518ReactWork.prototype._onCommit = function () {
20519 if (this._didCommit) {
20520 return;
20521 }
20522 this._didCommit = true;
20523 var callbacks = this._callbacks;
20524 if (callbacks === null) {
20525 return;
20526 }
20527 // TODO: Error handling.
20528 for (var i = 0; i < callbacks.length; i++) {
20529 var _callback2 = callbacks[i];
20530 !(typeof _callback2 === 'function') ? invariant(false, 'Invalid argument passed as callback. Expected a function. Instead received: %s', _callback2) : void 0;
20531 _callback2();
20532 }
20533};
20534
20535function ReactRoot(container, isConcurrent, hydrate) {
20536 var root = createContainer(container, isConcurrent, hydrate);
20537 this._internalRoot = root;
20538}
20539ReactRoot.prototype.render = function (children, callback) {
20540 var root = this._internalRoot;
20541 var work = new ReactWork();
20542 callback = callback === undefined ? null : callback;
20543 {
20544 warnOnInvalidCallback(callback, 'render');
20545 }
20546 if (callback !== null) {
20547 work.then(callback);
20548 }
20549 updateContainer(children, root, null, work._onCommit);
20550 return work;
20551};
20552ReactRoot.prototype.unmount = function (callback) {
20553 var root = this._internalRoot;
20554 var work = new ReactWork();
20555 callback = callback === undefined ? null : callback;
20556 {
20557 warnOnInvalidCallback(callback, 'render');
20558 }
20559 if (callback !== null) {
20560 work.then(callback);
20561 }
20562 updateContainer(null, root, null, work._onCommit);
20563 return work;
20564};
20565ReactRoot.prototype.legacy_renderSubtreeIntoContainer = function (parentComponent, children, callback) {
20566 var root = this._internalRoot;
20567 var work = new ReactWork();
20568 callback = callback === undefined ? null : callback;
20569 {
20570 warnOnInvalidCallback(callback, 'render');
20571 }
20572 if (callback !== null) {
20573 work.then(callback);
20574 }
20575 updateContainer(children, root, parentComponent, work._onCommit);
20576 return work;
20577};
20578ReactRoot.prototype.createBatch = function () {
20579 var batch = new ReactBatch(this);
20580 var expirationTime = batch._expirationTime;
20581
20582 var internalRoot = this._internalRoot;
20583 var firstBatch = internalRoot.firstBatch;
20584 if (firstBatch === null) {
20585 internalRoot.firstBatch = batch;
20586 batch._next = null;
20587 } else {
20588 // Insert sorted by expiration time then insertion order
20589 var insertAfter = null;
20590 var insertBefore = firstBatch;
20591 while (insertBefore !== null && insertBefore._expirationTime >= expirationTime) {
20592 insertAfter = insertBefore;
20593 insertBefore = insertBefore._next;
20594 }
20595 batch._next = insertBefore;
20596 if (insertAfter !== null) {
20597 insertAfter._next = batch;
20598 }
20599 }
20600
20601 return batch;
20602};
20603
20604/**
20605 * True if the supplied DOM node is a valid node element.
20606 *
20607 * @param {?DOMElement} node The candidate DOM node.
20608 * @return {boolean} True if the DOM is a valid DOM node.
20609 * @internal
20610 */
20611function isValidContainer(node) {
20612 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 '));
20613}
20614
20615function getReactRootElementInContainer(container) {
20616 if (!container) {
20617 return null;
20618 }
20619
20620 if (container.nodeType === DOCUMENT_NODE) {
20621 return container.documentElement;
20622 } else {
20623 return container.firstChild;
20624 }
20625}
20626
20627function shouldHydrateDueToLegacyHeuristic(container) {
20628 var rootElement = getReactRootElementInContainer(container);
20629 return !!(rootElement && rootElement.nodeType === ELEMENT_NODE && rootElement.hasAttribute(ROOT_ATTRIBUTE_NAME));
20630}
20631
20632setBatchingImplementation(batchedUpdates$1, interactiveUpdates$1, flushInteractiveUpdates$1);
20633
20634var warnedAboutHydrateAPI = false;
20635
20636function legacyCreateRootFromDOMContainer(container, forceHydrate) {
20637 var shouldHydrate = forceHydrate || shouldHydrateDueToLegacyHeuristic(container);
20638 // First clear any existing content.
20639 if (!shouldHydrate) {
20640 var warned = false;
20641 var rootSibling = void 0;
20642 while (rootSibling = container.lastChild) {
20643 {
20644 if (!warned && rootSibling.nodeType === ELEMENT_NODE && rootSibling.hasAttribute(ROOT_ATTRIBUTE_NAME)) {
20645 warned = true;
20646 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.');
20647 }
20648 }
20649 container.removeChild(rootSibling);
20650 }
20651 }
20652 {
20653 if (shouldHydrate && !forceHydrate && !warnedAboutHydrateAPI) {
20654 warnedAboutHydrateAPI = true;
20655 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.');
20656 }
20657 }
20658 // Legacy roots are not async by default.
20659 var isConcurrent = false;
20660 return new ReactRoot(container, isConcurrent, shouldHydrate);
20661}
20662
20663function legacyRenderSubtreeIntoContainer(parentComponent, children, container, forceHydrate, callback) {
20664 {
20665 topLevelUpdateWarnings(container);
20666 }
20667
20668 // TODO: Without `any` type, Flow says "Property cannot be accessed on any
20669 // member of intersection type." Whyyyyyy.
20670 var root = container._reactRootContainer;
20671 if (!root) {
20672 // Initial mount
20673 root = container._reactRootContainer = legacyCreateRootFromDOMContainer(container, forceHydrate);
20674 if (typeof callback === 'function') {
20675 var originalCallback = callback;
20676 callback = function () {
20677 var instance = getPublicRootInstance(root._internalRoot);
20678 originalCallback.call(instance);
20679 };
20680 }
20681 // Initial mount should not be batched.
20682 unbatchedUpdates(function () {
20683 if (parentComponent != null) {
20684 root.legacy_renderSubtreeIntoContainer(parentComponent, children, callback);
20685 } else {
20686 root.render(children, callback);
20687 }
20688 });
20689 } else {
20690 if (typeof callback === 'function') {
20691 var _originalCallback = callback;
20692 callback = function () {
20693 var instance = getPublicRootInstance(root._internalRoot);
20694 _originalCallback.call(instance);
20695 };
20696 }
20697 // Update
20698 if (parentComponent != null) {
20699 root.legacy_renderSubtreeIntoContainer(parentComponent, children, callback);
20700 } else {
20701 root.render(children, callback);
20702 }
20703 }
20704 return getPublicRootInstance(root._internalRoot);
20705}
20706
20707function createPortal$$1(children, container) {
20708 var key = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
20709
20710 !isValidContainer(container) ? invariant(false, 'Target container is not a DOM element.') : void 0;
20711 // TODO: pass ReactDOM portal implementation as third argument
20712 return createPortal$1(children, container, null, key);
20713}
20714
20715var ReactDOM = {
20716 createPortal: createPortal$$1,
20717
20718 findDOMNode: function (componentOrElement) {
20719 {
20720 var owner = ReactCurrentOwner.current;
20721 if (owner !== null && owner.stateNode !== null) {
20722 var warnedAboutRefsInRender = owner.stateNode._warnedAboutRefsInRender;
20723 !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;
20724 owner.stateNode._warnedAboutRefsInRender = true;
20725 }
20726 }
20727 if (componentOrElement == null) {
20728 return null;
20729 }
20730 if (componentOrElement.nodeType === ELEMENT_NODE) {
20731 return componentOrElement;
20732 }
20733 {
20734 return findHostInstanceWithWarning(componentOrElement, 'findDOMNode');
20735 }
20736 return findHostInstance(componentOrElement);
20737 },
20738 hydrate: function (element, container, callback) {
20739 !isValidContainer(container) ? invariant(false, 'Target container is not a DOM element.') : void 0;
20740 {
20741 !!container._reactHasBeenPassedToCreateRootDEV ? warningWithoutStack$1(false, 'You are calling ReactDOM.hydrate() on a container that was previously ' + 'passed to ReactDOM.%s(). This is not supported. ' + 'Did you mean to call root.render(element, {hydrate: true})?', enableStableConcurrentModeAPIs ? 'createRoot' : 'unstable_createRoot') : void 0;
20742 }
20743 // TODO: throw or warn if we couldn't hydrate?
20744 return legacyRenderSubtreeIntoContainer(null, element, container, true, callback);
20745 },
20746 render: function (element, container, callback) {
20747 !isValidContainer(container) ? invariant(false, 'Target container is not a DOM element.') : void 0;
20748 {
20749 !!container._reactHasBeenPassedToCreateRootDEV ? warningWithoutStack$1(false, 'You are calling ReactDOM.render() on a container that was previously ' + 'passed to ReactDOM.%s(). This is not supported. ' + 'Did you mean to call root.render(element)?', enableStableConcurrentModeAPIs ? 'createRoot' : 'unstable_createRoot') : void 0;
20750 }
20751 return legacyRenderSubtreeIntoContainer(null, element, container, false, callback);
20752 },
20753 unstable_renderSubtreeIntoContainer: function (parentComponent, element, containerNode, callback) {
20754 !isValidContainer(containerNode) ? invariant(false, 'Target container is not a DOM element.') : void 0;
20755 !(parentComponent != null && has(parentComponent)) ? invariant(false, 'parentComponent must be a valid React Component') : void 0;
20756 return legacyRenderSubtreeIntoContainer(parentComponent, element, containerNode, false, callback);
20757 },
20758 unmountComponentAtNode: function (container) {
20759 !isValidContainer(container) ? invariant(false, 'unmountComponentAtNode(...): Target container is not a DOM element.') : void 0;
20760
20761 {
20762 !!container._reactHasBeenPassedToCreateRootDEV ? warningWithoutStack$1(false, 'You are calling ReactDOM.unmountComponentAtNode() on a container that was previously ' + 'passed to ReactDOM.%s(). This is not supported. Did you mean to call root.unmount()?', enableStableConcurrentModeAPIs ? 'createRoot' : 'unstable_createRoot') : void 0;
20763 }
20764
20765 if (container._reactRootContainer) {
20766 {
20767 var rootEl = getReactRootElementInContainer(container);
20768 var renderedByDifferentReact = rootEl && !getInstanceFromNode$1(rootEl);
20769 !!renderedByDifferentReact ? warningWithoutStack$1(false, "unmountComponentAtNode(): The node you're attempting to unmount " + 'was rendered by another copy of React.') : void 0;
20770 }
20771
20772 // Unmount should not be batched.
20773 unbatchedUpdates(function () {
20774 legacyRenderSubtreeIntoContainer(null, null, container, false, function () {
20775 container._reactRootContainer = null;
20776 });
20777 });
20778 // If you call unmountComponentAtNode twice in quick succession, you'll
20779 // get `true` twice. That's probably fine?
20780 return true;
20781 } else {
20782 {
20783 var _rootEl = getReactRootElementInContainer(container);
20784 var hasNonRootReactChild = !!(_rootEl && getInstanceFromNode$1(_rootEl));
20785
20786 // Check if the container itself is a React root node.
20787 var isContainerReactRoot = container.nodeType === ELEMENT_NODE && isValidContainer(container.parentNode) && !!container.parentNode._reactRootContainer;
20788
20789 !!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;
20790 }
20791
20792 return false;
20793 }
20794 },
20795
20796
20797 // Temporary alias since we already shipped React 16 RC with it.
20798 // TODO: remove in React 17.
20799 unstable_createPortal: function () {
20800 if (!didWarnAboutUnstableCreatePortal) {
20801 didWarnAboutUnstableCreatePortal = true;
20802 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.');
20803 }
20804 return createPortal$$1.apply(undefined, arguments);
20805 },
20806
20807
20808 unstable_batchedUpdates: batchedUpdates$1,
20809
20810 unstable_interactiveUpdates: interactiveUpdates$1,
20811
20812 flushSync: flushSync,
20813
20814 unstable_createRoot: createRoot,
20815 unstable_flushControlled: flushControlled,
20816
20817 __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED: {
20818 // Keep in sync with ReactDOMUnstableNativeDependencies.js
20819 // and ReactTestUtils.js. This is an array for better minification.
20820 Events: [getInstanceFromNode$1, getNodeFromInstance$1, getFiberCurrentPropsFromNode$1, injection.injectEventPluginsByName, eventNameDispatchConfigs, accumulateTwoPhaseDispatches, accumulateDirectDispatches, enqueueStateRestore, restoreStateIfNeeded, dispatchEvent, runEventsInBatch]
20821 }
20822};
20823
20824function createRoot(container, options) {
20825 var functionName = enableStableConcurrentModeAPIs ? 'createRoot' : 'unstable_createRoot';
20826 !isValidContainer(container) ? invariant(false, '%s(...): Target container is not a DOM element.', functionName) : void 0;
20827 {
20828 !!container._reactRootContainer ? warningWithoutStack$1(false, 'You are calling ReactDOM.%s() on a container that was previously ' + 'passed to ReactDOM.render(). This is not supported.', enableStableConcurrentModeAPIs ? 'createRoot' : 'unstable_createRoot') : void 0;
20829 container._reactHasBeenPassedToCreateRootDEV = true;
20830 }
20831 var hydrate = options != null && options.hydrate === true;
20832 return new ReactRoot(container, true, hydrate);
20833}
20834
20835if (enableStableConcurrentModeAPIs) {
20836 ReactDOM.createRoot = createRoot;
20837 ReactDOM.unstable_createRoot = undefined;
20838}
20839
20840var foundDevTools = injectIntoDevTools({
20841 findFiberByHostInstance: getClosestInstanceFromNode,
20842 bundleType: 1,
20843 version: ReactVersion,
20844 rendererPackageName: 'react-dom'
20845});
20846
20847{
20848 if (!foundDevTools && canUseDOM && window.top === window.self) {
20849 // If we're in Chrome or Firefox, provide a download link if not installed.
20850 if (navigator.userAgent.indexOf('Chrome') > -1 && navigator.userAgent.indexOf('Edge') === -1 || navigator.userAgent.indexOf('Firefox') > -1) {
20851 var protocol = window.location.protocol;
20852 // Don't warn in exotic cases like chrome-extension://.
20853 if (/^(https?|file):$/.test(protocol)) {
20854 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');
20855 }
20856 }
20857 }
20858}
20859
20860
20861
20862var ReactFire = Object.freeze({
20863 default: ReactDOM
20864});
20865
20866var ReactFire$1 = ( ReactFire && ReactDOM ) || ReactFire;
20867
20868// TODO: decide on the top-level export form.
20869// This is hacky but makes it work with both Rollup and Jest.
20870var unstableFire = ReactFire$1.default || ReactFire$1;
20871
20872return unstableFire;
20873
20874})));