UNPKG

744 kBJavaScriptView Raw
1/** @license React v16.7.0
2 * react-dom.development.js
3 *
4 * Copyright (c) Facebook, Inc. and its affiliates.
5 *
6 * This source code is licensed under the MIT license found in the
7 * LICENSE file in the root directory of this source tree.
8 */
9
10'use strict';
11
12(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.ReactDOM = factory(global.React));
16}(this, (function (React) { 'use strict';
17
18/**
19 * Use invariant() to assert state which your program assumes to be true.
20 *
21 * Provide sprintf-style format (only %s is supported) and arguments
22 * to provide information about what broke and what you were
23 * expecting.
24 *
25 * The invariant message will be stripped in production, but the invariant
26 * will remain to ensure logic does not differ in production.
27 */
28
29var validateFormat = function () {};
30
31{
32 validateFormat = function (format) {
33 if (format === undefined) {
34 throw new Error('invariant requires an error message argument');
35 }
36 };
37}
38
39function invariant(condition, format, a, b, c, d, e, f) {
40 validateFormat(format);
41
42 if (!condition) {
43 var error = void 0;
44 if (format === undefined) {
45 error = new Error('Minified exception occurred; use the non-minified dev environment ' + 'for the full error message and additional helpful warnings.');
46 } else {
47 var args = [a, b, c, d, e, f];
48 var argIndex = 0;
49 error = new Error(format.replace(/%s/g, function () {
50 return args[argIndex++];
51 }));
52 error.name = 'Invariant Violation';
53 }
54
55 error.framesToPop = 1; // we don't care about invariant's own frame
56 throw error;
57 }
58}
59
60// Relying on the `invariant()` implementation lets us
61// preserve the format and params in the www builds.
62
63!React ? invariant(false, 'ReactDOM was loaded before React. Make sure you load the React package before loading ReactDOM.') : void 0;
64
65var invokeGuardedCallbackImpl = function (name, func, context, a, b, c, d, e, f) {
66 var funcArgs = Array.prototype.slice.call(arguments, 3);
67 try {
68 func.apply(context, funcArgs);
69 } catch (error) {
70 this.onError(error);
71 }
72};
73
74{
75 // In DEV mode, we swap out invokeGuardedCallback for a special version
76 // that plays more nicely with the browser's DevTools. The idea is to preserve
77 // "Pause on exceptions" behavior. Because React wraps all user-provided
78 // functions in invokeGuardedCallback, and the production version of
79 // invokeGuardedCallback uses a try-catch, all user exceptions are treated
80 // like caught exceptions, and the DevTools won't pause unless the developer
81 // takes the extra step of enabling pause on caught exceptions. This is
82 // untintuitive, though, because even though React has caught the error, from
83 // the developer's perspective, the error is uncaught.
84 //
85 // To preserve the expected "Pause on exceptions" behavior, we don't use a
86 // try-catch in DEV. Instead, we synchronously dispatch a fake event to a fake
87 // DOM node, and call the user-provided callback from inside an event handler
88 // for that fake event. If the callback throws, the error is "captured" using
89 // a global event handler. But because the error happens in a different
90 // event loop context, it does not interrupt the normal program flow.
91 // Effectively, this gives us try-catch behavior without actually using
92 // try-catch. Neat!
93
94 // Check that the browser supports the APIs we need to implement our special
95 // DEV version of invokeGuardedCallback
96 if (typeof window !== 'undefined' && typeof window.dispatchEvent === 'function' && typeof document !== 'undefined' && typeof document.createEvent === 'function') {
97 var fakeNode = document.createElement('react');
98
99 var invokeGuardedCallbackDev = function (name, func, context, a, b, c, d, e, f) {
100 // If document doesn't exist we know for sure we will crash in this method
101 // when we call document.createEvent(). However this can cause confusing
102 // errors: https://github.com/facebookincubator/create-react-app/issues/3482
103 // So we preemptively throw with a better message instead.
104 !(typeof document !== 'undefined') ? invariant(false, 'The `document` global was defined when React was initialized, but is not defined anymore. This can happen in a test environment if a component schedules an update from an asynchronous callback, but the test has already finished running. To solve this, you can either unmount the component at the end of your test (and ensure that any asynchronous operations get canceled in `componentWillUnmount`), or you can change the test itself to be asynchronous.') : void 0;
105 var evt = document.createEvent('Event');
106
107 // Keeps track of whether the user-provided callback threw an error. We
108 // set this to true at the beginning, then set it to false right after
109 // calling the function. If the function errors, `didError` will never be
110 // set to false. This strategy works even if the browser is flaky and
111 // fails to call our global error handler, because it doesn't rely on
112 // the error event at all.
113 var didError = true;
114
115 // Keeps track of the value of window.event so that we can reset it
116 // during the callback to let user code access window.event in the
117 // browsers that support it.
118 var windowEvent = window.event;
119
120 // Keeps track of the descriptor of window.event to restore it after event
121 // dispatching: https://github.com/facebook/react/issues/13688
122 var windowEventDescriptor = Object.getOwnPropertyDescriptor(window, 'event');
123
124 // Create an event handler for our fake event. We will synchronously
125 // dispatch our fake event using `dispatchEvent`. Inside the handler, we
126 // call the user-provided callback.
127 var funcArgs = Array.prototype.slice.call(arguments, 3);
128 function callCallback() {
129 // We immediately remove the callback from event listeners so that
130 // nested `invokeGuardedCallback` calls do not clash. Otherwise, a
131 // nested call would trigger the fake event handlers of any call higher
132 // in the stack.
133 fakeNode.removeEventListener(evtType, callCallback, false);
134
135 // We check for window.hasOwnProperty('event') to prevent the
136 // window.event assignment in both IE <= 10 as they throw an error
137 // "Member not found" in strict mode, and in Firefox which does not
138 // support window.event.
139 if (typeof window.event !== 'undefined' && window.hasOwnProperty('event')) {
140 window.event = windowEvent;
141 }
142
143 func.apply(context, funcArgs);
144 didError = false;
145 }
146
147 // Create a global error event handler. We use this to capture the value
148 // that was thrown. It's possible that this error handler will fire more
149 // than once; for example, if non-React code also calls `dispatchEvent`
150 // and a handler for that event throws. We should be resilient to most of
151 // those cases. Even if our error event handler fires more than once, the
152 // last error event is always used. If the callback actually does error,
153 // we know that the last error event is the correct one, because it's not
154 // possible for anything else to have happened in between our callback
155 // erroring and the code that follows the `dispatchEvent` call below. If
156 // the callback doesn't error, but the error event was fired, we know to
157 // ignore it because `didError` will be false, as described above.
158 var error = void 0;
159 // Use this to track whether the error event is ever called.
160 var didSetError = false;
161 var isCrossOriginError = false;
162
163 function handleWindowError(event) {
164 error = event.error;
165 didSetError = true;
166 if (error === null && event.colno === 0 && event.lineno === 0) {
167 isCrossOriginError = true;
168 }
169 if (event.defaultPrevented) {
170 // Some other error handler has prevented default.
171 // Browsers silence the error report if this happens.
172 // We'll remember this to later decide whether to log it or not.
173 if (error != null && typeof error === 'object') {
174 try {
175 error._suppressLogging = true;
176 } catch (inner) {
177 // Ignore.
178 }
179 }
180 }
181 }
182
183 // Create a fake event type.
184 var evtType = 'react-' + (name ? name : 'invokeguardedcallback');
185
186 // Attach our event handlers
187 window.addEventListener('error', handleWindowError);
188 fakeNode.addEventListener(evtType, callCallback, false);
189
190 // Synchronously dispatch our fake event. If the user-provided function
191 // errors, it will trigger our global error handler.
192 evt.initEvent(evtType, false, false);
193 fakeNode.dispatchEvent(evt);
194
195 if (windowEventDescriptor) {
196 Object.defineProperty(window, 'event', windowEventDescriptor);
197 }
198
199 if (didError) {
200 if (!didSetError) {
201 // The callback errored, but the error event never fired.
202 error = new Error('An error was thrown inside one of your components, but React ' + "doesn't know what it was. This is likely due to browser " + 'flakiness. React does its best to preserve the "Pause on ' + 'exceptions" behavior of the DevTools, which requires some ' + "DEV-mode only tricks. It's possible that these don't work in " + 'your browser. Try triggering the error in production mode, ' + 'or switching to a modern browser. If you suspect that this is ' + 'actually an issue with React, please file an issue.');
203 } else if (isCrossOriginError) {
204 error = new Error("A cross-origin error was thrown. React doesn't have access to " + 'the actual error object in development. ' + 'See https://fb.me/react-crossorigin-error for more information.');
205 }
206 this.onError(error);
207 }
208
209 // Remove our event listeners
210 window.removeEventListener('error', handleWindowError);
211 };
212
213 invokeGuardedCallbackImpl = invokeGuardedCallbackDev;
214 }
215}
216
217var invokeGuardedCallbackImpl$1 = invokeGuardedCallbackImpl;
218
219// Used by Fiber to simulate a try-catch.
220var hasError = false;
221var caughtError = null;
222
223// Used by event system to capture/rethrow the first error.
224var hasRethrowError = false;
225var rethrowError = null;
226
227var reporter = {
228 onError: function (error) {
229 hasError = true;
230 caughtError = error;
231 }
232};
233
234/**
235 * Call a function while guarding against errors that happens within it.
236 * Returns an error if it throws, otherwise null.
237 *
238 * In production, this is implemented using a try-catch. The reason we don't
239 * use a try-catch directly is so that we can swap out a different
240 * implementation in DEV mode.
241 *
242 * @param {String} name of the guard to use for logging or debugging
243 * @param {Function} func The function to invoke
244 * @param {*} context The context to use when calling the function
245 * @param {...*} args Arguments for function
246 */
247function invokeGuardedCallback(name, func, context, a, b, c, d, e, f) {
248 hasError = false;
249 caughtError = null;
250 invokeGuardedCallbackImpl$1.apply(reporter, arguments);
251}
252
253/**
254 * Same as invokeGuardedCallback, but instead of returning an error, it stores
255 * it in a global so it can be rethrown by `rethrowCaughtError` later.
256 * TODO: See if caughtError and rethrowError can be unified.
257 *
258 * @param {String} name of the guard to use for logging or debugging
259 * @param {Function} func The function to invoke
260 * @param {*} context The context to use when calling the function
261 * @param {...*} args Arguments for function
262 */
263function invokeGuardedCallbackAndCatchFirstError(name, func, context, a, b, c, d, e, f) {
264 invokeGuardedCallback.apply(this, arguments);
265 if (hasError) {
266 var error = clearCaughtError();
267 if (!hasRethrowError) {
268 hasRethrowError = true;
269 rethrowError = error;
270 }
271 }
272}
273
274/**
275 * During execution of guarded functions we will capture the first error which
276 * we will rethrow to be handled by the top level error handler.
277 */
278function rethrowCaughtError() {
279 if (hasRethrowError) {
280 var error = rethrowError;
281 hasRethrowError = false;
282 rethrowError = null;
283 throw error;
284 }
285}
286
287function hasCaughtError() {
288 return hasError;
289}
290
291function clearCaughtError() {
292 if (hasError) {
293 var error = caughtError;
294 hasError = false;
295 caughtError = null;
296 return error;
297 } else {
298 invariant(false, 'clearCaughtError was called but no error was captured. This error is likely caused by a bug in React. Please file an issue.');
299 }
300}
301
302/**
303 * Injectable ordering of event plugins.
304 */
305var eventPluginOrder = null;
306
307/**
308 * Injectable mapping from names to event plugin modules.
309 */
310var namesToPlugins = {};
311
312/**
313 * Recomputes the plugin list using the injected plugins and plugin ordering.
314 *
315 * @private
316 */
317function recomputePluginOrdering() {
318 if (!eventPluginOrder) {
319 // Wait until an `eventPluginOrder` is injected.
320 return;
321 }
322 for (var pluginName in namesToPlugins) {
323 var pluginModule = namesToPlugins[pluginName];
324 var pluginIndex = eventPluginOrder.indexOf(pluginName);
325 !(pluginIndex > -1) ? invariant(false, 'EventPluginRegistry: Cannot inject event plugins that do not exist in the plugin ordering, `%s`.', pluginName) : void 0;
326 if (plugins[pluginIndex]) {
327 continue;
328 }
329 !pluginModule.extractEvents ? invariant(false, 'EventPluginRegistry: Event plugins must implement an `extractEvents` method, but `%s` does not.', pluginName) : void 0;
330 plugins[pluginIndex] = pluginModule;
331 var publishedEvents = pluginModule.eventTypes;
332 for (var eventName in publishedEvents) {
333 !publishEventForPlugin(publishedEvents[eventName], pluginModule, eventName) ? invariant(false, 'EventPluginRegistry: Failed to publish event `%s` for plugin `%s`.', eventName, pluginName) : void 0;
334 }
335 }
336}
337
338/**
339 * Publishes an event so that it can be dispatched by the supplied plugin.
340 *
341 * @param {object} dispatchConfig Dispatch configuration for the event.
342 * @param {object} PluginModule Plugin publishing the event.
343 * @return {boolean} True if the event was successfully published.
344 * @private
345 */
346function publishEventForPlugin(dispatchConfig, pluginModule, eventName) {
347 !!eventNameDispatchConfigs.hasOwnProperty(eventName) ? invariant(false, 'EventPluginHub: More than one plugin attempted to publish the same event name, `%s`.', eventName) : void 0;
348 eventNameDispatchConfigs[eventName] = dispatchConfig;
349
350 var phasedRegistrationNames = dispatchConfig.phasedRegistrationNames;
351 if (phasedRegistrationNames) {
352 for (var phaseName in phasedRegistrationNames) {
353 if (phasedRegistrationNames.hasOwnProperty(phaseName)) {
354 var phasedRegistrationName = phasedRegistrationNames[phaseName];
355 publishRegistrationName(phasedRegistrationName, pluginModule, eventName);
356 }
357 }
358 return true;
359 } else if (dispatchConfig.registrationName) {
360 publishRegistrationName(dispatchConfig.registrationName, pluginModule, eventName);
361 return true;
362 }
363 return false;
364}
365
366/**
367 * Publishes a registration name that is used to identify dispatched events.
368 *
369 * @param {string} registrationName Registration name to add.
370 * @param {object} PluginModule Plugin publishing the event.
371 * @private
372 */
373function publishRegistrationName(registrationName, pluginModule, eventName) {
374 !!registrationNameModules[registrationName] ? invariant(false, 'EventPluginHub: More than one plugin attempted to publish the same registration name, `%s`.', registrationName) : void 0;
375 registrationNameModules[registrationName] = pluginModule;
376 registrationNameDependencies[registrationName] = pluginModule.eventTypes[eventName].dependencies;
377
378 {
379 var lowerCasedName = registrationName.toLowerCase();
380 possibleRegistrationNames[lowerCasedName] = registrationName;
381
382 if (registrationName === 'onDoubleClick') {
383 possibleRegistrationNames.ondblclick = registrationName;
384 }
385 }
386}
387
388/**
389 * Registers plugins so that they can extract and dispatch events.
390 *
391 * @see {EventPluginHub}
392 */
393
394/**
395 * Ordered list of injected plugins.
396 */
397var plugins = [];
398
399/**
400 * Mapping from event name to dispatch config
401 */
402var eventNameDispatchConfigs = {};
403
404/**
405 * Mapping from registration name to plugin module
406 */
407var registrationNameModules = {};
408
409/**
410 * Mapping from registration name to event name
411 */
412var registrationNameDependencies = {};
413
414/**
415 * Mapping from lowercase registration names to the properly cased version,
416 * used to warn in the case of missing event handlers. Available
417 * only in true.
418 * @type {Object}
419 */
420var possibleRegistrationNames = {};
421// Trust the developer to only use possibleRegistrationNames in true
422
423/**
424 * Injects an ordering of plugins (by plugin name). This allows the ordering
425 * to be decoupled from injection of the actual plugins so that ordering is
426 * always deterministic regardless of packaging, on-the-fly injection, etc.
427 *
428 * @param {array} InjectedEventPluginOrder
429 * @internal
430 * @see {EventPluginHub.injection.injectEventPluginOrder}
431 */
432function injectEventPluginOrder(injectedEventPluginOrder) {
433 !!eventPluginOrder ? invariant(false, 'EventPluginRegistry: Cannot inject event plugin ordering more than once. You are likely trying to load more than one copy of React.') : void 0;
434 // Clone the ordering so it cannot be dynamically mutated.
435 eventPluginOrder = Array.prototype.slice.call(injectedEventPluginOrder);
436 recomputePluginOrdering();
437}
438
439/**
440 * Injects plugins to be used by `EventPluginHub`. The plugin names must be
441 * in the ordering injected by `injectEventPluginOrder`.
442 *
443 * Plugins can be injected as part of page initialization or on-the-fly.
444 *
445 * @param {object} injectedNamesToPlugins Map from names to plugin modules.
446 * @internal
447 * @see {EventPluginHub.injection.injectEventPluginsByName}
448 */
449function injectEventPluginsByName(injectedNamesToPlugins) {
450 var isOrderingDirty = false;
451 for (var pluginName in injectedNamesToPlugins) {
452 if (!injectedNamesToPlugins.hasOwnProperty(pluginName)) {
453 continue;
454 }
455 var pluginModule = injectedNamesToPlugins[pluginName];
456 if (!namesToPlugins.hasOwnProperty(pluginName) || namesToPlugins[pluginName] !== pluginModule) {
457 !!namesToPlugins[pluginName] ? invariant(false, 'EventPluginRegistry: Cannot inject two different event plugins using the same name, `%s`.', pluginName) : void 0;
458 namesToPlugins[pluginName] = pluginModule;
459 isOrderingDirty = true;
460 }
461 }
462 if (isOrderingDirty) {
463 recomputePluginOrdering();
464 }
465}
466
467/**
468 * Similar to invariant but only logs a warning if the condition is not met.
469 * This can be used to log issues in development environments in critical
470 * paths. Removing the logging code for production environments will keep the
471 * same logic and follow the same code paths.
472 */
473
474var warningWithoutStack = function () {};
475
476{
477 warningWithoutStack = function (condition, format) {
478 for (var _len = arguments.length, args = Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) {
479 args[_key - 2] = arguments[_key];
480 }
481
482 if (format === undefined) {
483 throw new Error('`warningWithoutStack(condition, format, ...args)` requires a warning ' + 'message argument');
484 }
485 if (args.length > 8) {
486 // Check before the condition to catch violations early.
487 throw new Error('warningWithoutStack() currently supports at most 8 arguments.');
488 }
489 if (condition) {
490 return;
491 }
492 if (typeof console !== 'undefined') {
493 var argsWithFormat = args.map(function (item) {
494 return '' + item;
495 });
496 argsWithFormat.unshift('Warning: ' + format);
497
498 // We intentionally don't use spread (or .apply) directly because it
499 // breaks IE9: https://github.com/facebook/react/issues/13610
500 Function.prototype.apply.call(console.error, console, argsWithFormat);
501 }
502 try {
503 // --- Welcome to debugging React ---
504 // This error was thrown as a convenience so that you can use this stack
505 // to find the callsite that caused this warning to fire.
506 var argIndex = 0;
507 var message = 'Warning: ' + format.replace(/%s/g, function () {
508 return args[argIndex++];
509 });
510 throw new Error(message);
511 } catch (x) {}
512 };
513}
514
515var warningWithoutStack$1 = warningWithoutStack;
516
517var getFiberCurrentPropsFromNode = null;
518var getInstanceFromNode = null;
519var getNodeFromInstance = null;
520
521function setComponentTree(getFiberCurrentPropsFromNodeImpl, getInstanceFromNodeImpl, getNodeFromInstanceImpl) {
522 getFiberCurrentPropsFromNode = getFiberCurrentPropsFromNodeImpl;
523 getInstanceFromNode = getInstanceFromNodeImpl;
524 getNodeFromInstance = getNodeFromInstanceImpl;
525 {
526 !(getNodeFromInstance && getInstanceFromNode) ? warningWithoutStack$1(false, 'EventPluginUtils.setComponentTree(...): Injected ' + 'module is missing getNodeFromInstance or getInstanceFromNode.') : void 0;
527 }
528}
529
530var validateEventDispatches = void 0;
531{
532 validateEventDispatches = function (event) {
533 var dispatchListeners = event._dispatchListeners;
534 var dispatchInstances = event._dispatchInstances;
535
536 var listenersIsArr = Array.isArray(dispatchListeners);
537 var listenersLen = listenersIsArr ? dispatchListeners.length : dispatchListeners ? 1 : 0;
538
539 var instancesIsArr = Array.isArray(dispatchInstances);
540 var instancesLen = instancesIsArr ? dispatchInstances.length : dispatchInstances ? 1 : 0;
541
542 !(instancesIsArr === listenersIsArr && instancesLen === listenersLen) ? warningWithoutStack$1(false, 'EventPluginUtils: Invalid `event`.') : void 0;
543 };
544}
545
546/**
547 * Dispatch the event to the listener.
548 * @param {SyntheticEvent} event SyntheticEvent to handle
549 * @param {function} listener Application-level callback
550 * @param {*} inst Internal component instance
551 */
552function executeDispatch(event, listener, inst) {
553 var type = event.type || 'unknown-event';
554 event.currentTarget = getNodeFromInstance(inst);
555 invokeGuardedCallbackAndCatchFirstError(type, listener, undefined, event);
556 event.currentTarget = null;
557}
558
559/**
560 * Standard/simple iteration through an event's collected dispatches.
561 */
562function executeDispatchesInOrder(event) {
563 var dispatchListeners = event._dispatchListeners;
564 var dispatchInstances = event._dispatchInstances;
565 {
566 validateEventDispatches(event);
567 }
568 if (Array.isArray(dispatchListeners)) {
569 for (var i = 0; i < dispatchListeners.length; i++) {
570 if (event.isPropagationStopped()) {
571 break;
572 }
573 // Listeners and Instances are two parallel arrays that are always in sync.
574 executeDispatch(event, dispatchListeners[i], dispatchInstances[i]);
575 }
576 } else if (dispatchListeners) {
577 executeDispatch(event, dispatchListeners, dispatchInstances);
578 }
579 event._dispatchListeners = null;
580 event._dispatchInstances = null;
581}
582
583/**
584 * @see executeDispatchesInOrderStopAtTrueImpl
585 */
586
587
588/**
589 * Execution of a "direct" dispatch - there must be at most one dispatch
590 * accumulated on the event or it is considered an error. It doesn't really make
591 * sense for an event with multiple dispatches (bubbled) to keep track of the
592 * return values at each dispatch execution, but it does tend to make sense when
593 * dealing with "direct" dispatches.
594 *
595 * @return {*} The return value of executing the single dispatch.
596 */
597
598
599/**
600 * @param {SyntheticEvent} event
601 * @return {boolean} True iff number of dispatches accumulated is greater than 0.
602 */
603
604/**
605 * Accumulates items that must not be null or undefined into the first one. This
606 * is used to conserve memory by avoiding array allocations, and thus sacrifices
607 * API cleanness. Since `current` can be null before being passed in and not
608 * null after this function, make sure to assign it back to `current`:
609 *
610 * `a = accumulateInto(a, b);`
611 *
612 * This API should be sparingly used. Try `accumulate` for something cleaner.
613 *
614 * @return {*|array<*>} An accumulation of items.
615 */
616
617function accumulateInto(current, next) {
618 !(next != null) ? invariant(false, 'accumulateInto(...): Accumulated items must not be null or undefined.') : void 0;
619
620 if (current == null) {
621 return next;
622 }
623
624 // Both are not empty. Warning: Never call x.concat(y) when you are not
625 // certain that x is an Array (x could be a string with concat method).
626 if (Array.isArray(current)) {
627 if (Array.isArray(next)) {
628 current.push.apply(current, next);
629 return current;
630 }
631 current.push(next);
632 return current;
633 }
634
635 if (Array.isArray(next)) {
636 // A bit too dangerous to mutate `next`.
637 return [current].concat(next);
638 }
639
640 return [current, next];
641}
642
643/**
644 * @param {array} arr an "accumulation" of items which is either an Array or
645 * a single item. Useful when paired with the `accumulate` module. This is a
646 * simple utility that allows us to reason about a collection of items, but
647 * handling the case when there is exactly one item (and we do not need to
648 * allocate an array).
649 * @param {function} cb Callback invoked with each element or a collection.
650 * @param {?} [scope] Scope used as `this` in a callback.
651 */
652function forEachAccumulated(arr, cb, scope) {
653 if (Array.isArray(arr)) {
654 arr.forEach(cb, scope);
655 } else if (arr) {
656 cb.call(scope, arr);
657 }
658}
659
660/**
661 * Internal queue of events that have accumulated their dispatches and are
662 * waiting to have their dispatches executed.
663 */
664var eventQueue = null;
665
666/**
667 * Dispatches an event and releases it back into the pool, unless persistent.
668 *
669 * @param {?object} event Synthetic event to be dispatched.
670 * @private
671 */
672var executeDispatchesAndRelease = function (event) {
673 if (event) {
674 executeDispatchesInOrder(event);
675
676 if (!event.isPersistent()) {
677 event.constructor.release(event);
678 }
679 }
680};
681var executeDispatchesAndReleaseTopLevel = function (e) {
682 return executeDispatchesAndRelease(e);
683};
684
685function isInteractive(tag) {
686 return tag === 'button' || tag === 'input' || tag === 'select' || tag === 'textarea';
687}
688
689function shouldPreventMouseEvent(name, type, props) {
690 switch (name) {
691 case 'onClick':
692 case 'onClickCapture':
693 case 'onDoubleClick':
694 case 'onDoubleClickCapture':
695 case 'onMouseDown':
696 case 'onMouseDownCapture':
697 case 'onMouseMove':
698 case 'onMouseMoveCapture':
699 case 'onMouseUp':
700 case 'onMouseUpCapture':
701 return !!(props.disabled && isInteractive(type));
702 default:
703 return false;
704 }
705}
706
707/**
708 * This is a unified interface for event plugins to be installed and configured.
709 *
710 * Event plugins can implement the following properties:
711 *
712 * `extractEvents` {function(string, DOMEventTarget, string, object): *}
713 * Required. When a top-level event is fired, this method is expected to
714 * extract synthetic events that will in turn be queued and dispatched.
715 *
716 * `eventTypes` {object}
717 * Optional, plugins that fire events must publish a mapping of registration
718 * names that are used to register listeners. Values of this mapping must
719 * be objects that contain `registrationName` or `phasedRegistrationNames`.
720 *
721 * `executeDispatch` {function(object, function, string)}
722 * Optional, allows plugins to override how an event gets dispatched. By
723 * default, the listener is simply invoked.
724 *
725 * Each plugin that is injected into `EventsPluginHub` is immediately operable.
726 *
727 * @public
728 */
729
730/**
731 * Methods for injecting dependencies.
732 */
733var injection = {
734 /**
735 * @param {array} InjectedEventPluginOrder
736 * @public
737 */
738 injectEventPluginOrder: injectEventPluginOrder,
739
740 /**
741 * @param {object} injectedNamesToPlugins Map from names to plugin modules.
742 */
743 injectEventPluginsByName: injectEventPluginsByName
744};
745
746/**
747 * @param {object} inst The instance, which is the source of events.
748 * @param {string} registrationName Name of listener (e.g. `onClick`).
749 * @return {?function} The stored callback.
750 */
751function getListener(inst, registrationName) {
752 var listener = void 0;
753
754 // TODO: shouldPreventMouseEvent is DOM-specific and definitely should not
755 // live here; needs to be moved to a better place soon
756 var stateNode = inst.stateNode;
757 if (!stateNode) {
758 // Work in progress (ex: onload events in incremental mode).
759 return null;
760 }
761 var props = getFiberCurrentPropsFromNode(stateNode);
762 if (!props) {
763 // Work in progress.
764 return null;
765 }
766 listener = props[registrationName];
767 if (shouldPreventMouseEvent(registrationName, inst.type, props)) {
768 return null;
769 }
770 !(!listener || typeof listener === 'function') ? invariant(false, 'Expected `%s` listener to be a function, instead got a value of `%s` type.', registrationName, typeof listener) : void 0;
771 return listener;
772}
773
774/**
775 * Allows registered plugins an opportunity to extract events from top-level
776 * native browser events.
777 *
778 * @return {*} An accumulation of synthetic events.
779 * @internal
780 */
781function extractEvents(topLevelType, targetInst, nativeEvent, nativeEventTarget) {
782 var events = null;
783 for (var i = 0; i < plugins.length; i++) {
784 // Not every plugin in the ordering may be loaded at runtime.
785 var possiblePlugin = plugins[i];
786 if (possiblePlugin) {
787 var extractedEvents = possiblePlugin.extractEvents(topLevelType, targetInst, nativeEvent, nativeEventTarget);
788 if (extractedEvents) {
789 events = accumulateInto(events, extractedEvents);
790 }
791 }
792 }
793 return events;
794}
795
796function runEventsInBatch(events) {
797 if (events !== null) {
798 eventQueue = accumulateInto(eventQueue, events);
799 }
800
801 // Set `eventQueue` to null before processing it so that we can tell if more
802 // events get enqueued while processing.
803 var processingEventQueue = eventQueue;
804 eventQueue = null;
805
806 if (!processingEventQueue) {
807 return;
808 }
809
810 forEachAccumulated(processingEventQueue, executeDispatchesAndReleaseTopLevel);
811 !!eventQueue ? invariant(false, 'processEventQueue(): Additional events were enqueued while processing an event queue. Support for this has not yet been implemented.') : void 0;
812 // This would be a good time to rethrow if any of the event handlers threw.
813 rethrowCaughtError();
814}
815
816function runExtractedEventsInBatch(topLevelType, targetInst, nativeEvent, nativeEventTarget) {
817 var events = extractEvents(topLevelType, targetInst, nativeEvent, nativeEventTarget);
818 runEventsInBatch(events);
819}
820
821var FunctionComponent = 0;
822var ClassComponent = 1;
823var IndeterminateComponent = 2; // Before we know whether it is function or class
824var HostRoot = 3; // Root of a host tree. Could be nested inside another node.
825var HostPortal = 4; // A subtree. Could be an entry point to a different renderer.
826var HostComponent = 5;
827var HostText = 6;
828var Fragment = 7;
829var Mode = 8;
830var ContextConsumer = 9;
831var ContextProvider = 10;
832var ForwardRef = 11;
833var Profiler = 12;
834var SuspenseComponent = 13;
835var MemoComponent = 14;
836var SimpleMemoComponent = 15;
837var LazyComponent = 16;
838var IncompleteClassComponent = 17;
839
840var randomKey = Math.random().toString(36).slice(2);
841var internalInstanceKey = '__reactInternalInstance$' + randomKey;
842var internalEventHandlersKey = '__reactEventHandlers$' + randomKey;
843
844function precacheFiberNode(hostInst, node) {
845 node[internalInstanceKey] = hostInst;
846}
847
848/**
849 * Given a DOM node, return the closest ReactDOMComponent or
850 * ReactDOMTextComponent instance ancestor.
851 */
852function getClosestInstanceFromNode(node) {
853 if (node[internalInstanceKey]) {
854 return node[internalInstanceKey];
855 }
856
857 while (!node[internalInstanceKey]) {
858 if (node.parentNode) {
859 node = node.parentNode;
860 } else {
861 // Top of the tree. This node must not be part of a React tree (or is
862 // unmounted, potentially).
863 return null;
864 }
865 }
866
867 var inst = node[internalInstanceKey];
868 if (inst.tag === HostComponent || inst.tag === HostText) {
869 // In Fiber, this will always be the deepest root.
870 return inst;
871 }
872
873 return null;
874}
875
876/**
877 * Given a DOM node, return the ReactDOMComponent or ReactDOMTextComponent
878 * instance, or null if the node was not rendered by this React.
879 */
880function getInstanceFromNode$1(node) {
881 var inst = node[internalInstanceKey];
882 if (inst) {
883 if (inst.tag === HostComponent || inst.tag === HostText) {
884 return inst;
885 } else {
886 return null;
887 }
888 }
889 return null;
890}
891
892/**
893 * Given a ReactDOMComponent or ReactDOMTextComponent, return the corresponding
894 * DOM node.
895 */
896function getNodeFromInstance$1(inst) {
897 if (inst.tag === HostComponent || inst.tag === HostText) {
898 // In Fiber this, is just the state node right now. We assume it will be
899 // a host component or host text.
900 return inst.stateNode;
901 }
902
903 // Without this first invariant, passing a non-DOM-component triggers the next
904 // invariant for a missing parent, which is super confusing.
905 invariant(false, 'getNodeFromInstance: Invalid argument.');
906}
907
908function getFiberCurrentPropsFromNode$1(node) {
909 return node[internalEventHandlersKey] || null;
910}
911
912function updateFiberProps(node, props) {
913 node[internalEventHandlersKey] = props;
914}
915
916function getParent(inst) {
917 do {
918 inst = inst.return;
919 // TODO: If this is a HostRoot we might want to bail out.
920 // That is depending on if we want nested subtrees (layers) to bubble
921 // events to their parent. We could also go through parentNode on the
922 // host node but that wouldn't work for React Native and doesn't let us
923 // do the portal feature.
924 } while (inst && inst.tag !== HostComponent);
925 if (inst) {
926 return inst;
927 }
928 return null;
929}
930
931/**
932 * Return the lowest common ancestor of A and B, or null if they are in
933 * different trees.
934 */
935function getLowestCommonAncestor(instA, instB) {
936 var depthA = 0;
937 for (var tempA = instA; tempA; tempA = getParent(tempA)) {
938 depthA++;
939 }
940 var depthB = 0;
941 for (var tempB = instB; tempB; tempB = getParent(tempB)) {
942 depthB++;
943 }
944
945 // If A is deeper, crawl up.
946 while (depthA - depthB > 0) {
947 instA = getParent(instA);
948 depthA--;
949 }
950
951 // If B is deeper, crawl up.
952 while (depthB - depthA > 0) {
953 instB = getParent(instB);
954 depthB--;
955 }
956
957 // Walk in lockstep until we find a match.
958 var depth = depthA;
959 while (depth--) {
960 if (instA === instB || instA === instB.alternate) {
961 return instA;
962 }
963 instA = getParent(instA);
964 instB = getParent(instB);
965 }
966 return null;
967}
968
969/**
970 * Return if A is an ancestor of B.
971 */
972
973
974/**
975 * Return the parent instance of the passed-in instance.
976 */
977
978
979/**
980 * Simulates the traversal of a two-phase, capture/bubble event dispatch.
981 */
982function traverseTwoPhase(inst, fn, arg) {
983 var path = [];
984 while (inst) {
985 path.push(inst);
986 inst = getParent(inst);
987 }
988 var i = void 0;
989 for (i = path.length; i-- > 0;) {
990 fn(path[i], 'captured', arg);
991 }
992 for (i = 0; i < path.length; i++) {
993 fn(path[i], 'bubbled', arg);
994 }
995}
996
997/**
998 * Traverses the ID hierarchy and invokes the supplied `cb` on any IDs that
999 * should would receive a `mouseEnter` or `mouseLeave` event.
1000 *
1001 * Does not invoke the callback on the nearest common ancestor because nothing
1002 * "entered" or "left" that element.
1003 */
1004function traverseEnterLeave(from, to, fn, argFrom, argTo) {
1005 var common = from && to ? getLowestCommonAncestor(from, to) : null;
1006 var pathFrom = [];
1007 while (true) {
1008 if (!from) {
1009 break;
1010 }
1011 if (from === common) {
1012 break;
1013 }
1014 var alternate = from.alternate;
1015 if (alternate !== null && alternate === common) {
1016 break;
1017 }
1018 pathFrom.push(from);
1019 from = getParent(from);
1020 }
1021 var pathTo = [];
1022 while (true) {
1023 if (!to) {
1024 break;
1025 }
1026 if (to === common) {
1027 break;
1028 }
1029 var _alternate = to.alternate;
1030 if (_alternate !== null && _alternate === common) {
1031 break;
1032 }
1033 pathTo.push(to);
1034 to = getParent(to);
1035 }
1036 for (var i = 0; i < pathFrom.length; i++) {
1037 fn(pathFrom[i], 'bubbled', argFrom);
1038 }
1039 for (var _i = pathTo.length; _i-- > 0;) {
1040 fn(pathTo[_i], 'captured', argTo);
1041 }
1042}
1043
1044/**
1045 * Some event types have a notion of different registration names for different
1046 * "phases" of propagation. This finds listeners by a given phase.
1047 */
1048function listenerAtPhase(inst, event, propagationPhase) {
1049 var registrationName = event.dispatchConfig.phasedRegistrationNames[propagationPhase];
1050 return getListener(inst, registrationName);
1051}
1052
1053/**
1054 * A small set of propagation patterns, each of which will accept a small amount
1055 * of information, and generate a set of "dispatch ready event objects" - which
1056 * are sets of events that have already been annotated with a set of dispatched
1057 * listener functions/ids. The API is designed this way to discourage these
1058 * propagation strategies from actually executing the dispatches, since we
1059 * always want to collect the entire set of dispatches before executing even a
1060 * single one.
1061 */
1062
1063/**
1064 * Tags a `SyntheticEvent` with dispatched listeners. Creating this function
1065 * here, allows us to not have to bind or create functions for each event.
1066 * Mutating the event's members allows us to not have to create a wrapping
1067 * "dispatch" object that pairs the event with the listener.
1068 */
1069function accumulateDirectionalDispatches(inst, phase, event) {
1070 {
1071 !inst ? warningWithoutStack$1(false, 'Dispatching inst must not be null') : void 0;
1072 }
1073 var listener = listenerAtPhase(inst, event, phase);
1074 if (listener) {
1075 event._dispatchListeners = accumulateInto(event._dispatchListeners, listener);
1076 event._dispatchInstances = accumulateInto(event._dispatchInstances, inst);
1077 }
1078}
1079
1080/**
1081 * Collect dispatches (must be entirely collected before dispatching - see unit
1082 * tests). Lazily allocate the array to conserve memory. We must loop through
1083 * each event and perform the traversal for each one. We cannot perform a
1084 * single traversal for the entire collection of events because each event may
1085 * have a different target.
1086 */
1087function accumulateTwoPhaseDispatchesSingle(event) {
1088 if (event && event.dispatchConfig.phasedRegistrationNames) {
1089 traverseTwoPhase(event._targetInst, accumulateDirectionalDispatches, event);
1090 }
1091}
1092
1093/**
1094 * Accumulates without regard to direction, does not look for phased
1095 * registration names. Same as `accumulateDirectDispatchesSingle` but without
1096 * requiring that the `dispatchMarker` be the same as the dispatched ID.
1097 */
1098function accumulateDispatches(inst, ignoredDirection, event) {
1099 if (inst && event && event.dispatchConfig.registrationName) {
1100 var registrationName = event.dispatchConfig.registrationName;
1101 var listener = getListener(inst, registrationName);
1102 if (listener) {
1103 event._dispatchListeners = accumulateInto(event._dispatchListeners, listener);
1104 event._dispatchInstances = accumulateInto(event._dispatchInstances, inst);
1105 }
1106 }
1107}
1108
1109/**
1110 * Accumulates dispatches on an `SyntheticEvent`, but only for the
1111 * `dispatchMarker`.
1112 * @param {SyntheticEvent} event
1113 */
1114function accumulateDirectDispatchesSingle(event) {
1115 if (event && event.dispatchConfig.registrationName) {
1116 accumulateDispatches(event._targetInst, null, event);
1117 }
1118}
1119
1120function accumulateTwoPhaseDispatches(events) {
1121 forEachAccumulated(events, accumulateTwoPhaseDispatchesSingle);
1122}
1123
1124
1125
1126function accumulateEnterLeaveDispatches(leave, enter, from, to) {
1127 traverseEnterLeave(from, to, accumulateDispatches, leave, enter);
1128}
1129
1130function accumulateDirectDispatches(events) {
1131 forEachAccumulated(events, accumulateDirectDispatchesSingle);
1132}
1133
1134var canUseDOM = !!(typeof window !== 'undefined' && window.document && window.document.createElement);
1135
1136// Do not uses the below two methods directly!
1137// Instead use constants exported from DOMTopLevelEventTypes in ReactDOM.
1138// (It is the only module that is allowed to access these methods.)
1139
1140function unsafeCastStringToDOMTopLevelType(topLevelType) {
1141 return topLevelType;
1142}
1143
1144function unsafeCastDOMTopLevelTypeToString(topLevelType) {
1145 return topLevelType;
1146}
1147
1148/**
1149 * Generate a mapping of standard vendor prefixes using the defined style property and event name.
1150 *
1151 * @param {string} styleProp
1152 * @param {string} eventName
1153 * @returns {object}
1154 */
1155function makePrefixMap(styleProp, eventName) {
1156 var prefixes = {};
1157
1158 prefixes[styleProp.toLowerCase()] = eventName.toLowerCase();
1159 prefixes['Webkit' + styleProp] = 'webkit' + eventName;
1160 prefixes['Moz' + styleProp] = 'moz' + eventName;
1161
1162 return prefixes;
1163}
1164
1165/**
1166 * A list of event names to a configurable list of vendor prefixes.
1167 */
1168var vendorPrefixes = {
1169 animationend: makePrefixMap('Animation', 'AnimationEnd'),
1170 animationiteration: makePrefixMap('Animation', 'AnimationIteration'),
1171 animationstart: makePrefixMap('Animation', 'AnimationStart'),
1172 transitionend: makePrefixMap('Transition', 'TransitionEnd')
1173};
1174
1175/**
1176 * Event names that have already been detected and prefixed (if applicable).
1177 */
1178var prefixedEventNames = {};
1179
1180/**
1181 * Element to check for prefixes on.
1182 */
1183var style = {};
1184
1185/**
1186 * Bootstrap if a DOM exists.
1187 */
1188if (canUseDOM) {
1189 style = document.createElement('div').style;
1190
1191 // On some platforms, in particular some releases of Android 4.x,
1192 // the un-prefixed "animation" and "transition" properties are defined on the
1193 // style object but the events that fire will still be prefixed, so we need
1194 // to check if the un-prefixed events are usable, and if not remove them from the map.
1195 if (!('AnimationEvent' in window)) {
1196 delete vendorPrefixes.animationend.animation;
1197 delete vendorPrefixes.animationiteration.animation;
1198 delete vendorPrefixes.animationstart.animation;
1199 }
1200
1201 // Same as above
1202 if (!('TransitionEvent' in window)) {
1203 delete vendorPrefixes.transitionend.transition;
1204 }
1205}
1206
1207/**
1208 * Attempts to determine the correct vendor prefixed event name.
1209 *
1210 * @param {string} eventName
1211 * @returns {string}
1212 */
1213function getVendorPrefixedEventName(eventName) {
1214 if (prefixedEventNames[eventName]) {
1215 return prefixedEventNames[eventName];
1216 } else if (!vendorPrefixes[eventName]) {
1217 return eventName;
1218 }
1219
1220 var prefixMap = vendorPrefixes[eventName];
1221
1222 for (var styleProp in prefixMap) {
1223 if (prefixMap.hasOwnProperty(styleProp) && styleProp in style) {
1224 return prefixedEventNames[eventName] = prefixMap[styleProp];
1225 }
1226 }
1227
1228 return eventName;
1229}
1230
1231/**
1232 * To identify top level events in ReactDOM, we use constants defined by this
1233 * module. This is the only module that uses the unsafe* methods to express
1234 * that the constants actually correspond to the browser event names. This lets
1235 * us save some bundle size by avoiding a top level type -> event name map.
1236 * The rest of ReactDOM code should import top level types from this file.
1237 */
1238var TOP_ABORT = unsafeCastStringToDOMTopLevelType('abort');
1239var TOP_ANIMATION_END = unsafeCastStringToDOMTopLevelType(getVendorPrefixedEventName('animationend'));
1240var TOP_ANIMATION_ITERATION = unsafeCastStringToDOMTopLevelType(getVendorPrefixedEventName('animationiteration'));
1241var TOP_ANIMATION_START = unsafeCastStringToDOMTopLevelType(getVendorPrefixedEventName('animationstart'));
1242var TOP_BLUR = unsafeCastStringToDOMTopLevelType('blur');
1243var TOP_CAN_PLAY = unsafeCastStringToDOMTopLevelType('canplay');
1244var TOP_CAN_PLAY_THROUGH = unsafeCastStringToDOMTopLevelType('canplaythrough');
1245var TOP_CANCEL = unsafeCastStringToDOMTopLevelType('cancel');
1246var TOP_CHANGE = unsafeCastStringToDOMTopLevelType('change');
1247var TOP_CLICK = unsafeCastStringToDOMTopLevelType('click');
1248var TOP_CLOSE = unsafeCastStringToDOMTopLevelType('close');
1249var TOP_COMPOSITION_END = unsafeCastStringToDOMTopLevelType('compositionend');
1250var TOP_COMPOSITION_START = unsafeCastStringToDOMTopLevelType('compositionstart');
1251var TOP_COMPOSITION_UPDATE = unsafeCastStringToDOMTopLevelType('compositionupdate');
1252var TOP_CONTEXT_MENU = unsafeCastStringToDOMTopLevelType('contextmenu');
1253var TOP_COPY = unsafeCastStringToDOMTopLevelType('copy');
1254var TOP_CUT = unsafeCastStringToDOMTopLevelType('cut');
1255var TOP_DOUBLE_CLICK = unsafeCastStringToDOMTopLevelType('dblclick');
1256var TOP_AUX_CLICK = unsafeCastStringToDOMTopLevelType('auxclick');
1257var TOP_DRAG = unsafeCastStringToDOMTopLevelType('drag');
1258var TOP_DRAG_END = unsafeCastStringToDOMTopLevelType('dragend');
1259var TOP_DRAG_ENTER = unsafeCastStringToDOMTopLevelType('dragenter');
1260var TOP_DRAG_EXIT = unsafeCastStringToDOMTopLevelType('dragexit');
1261var TOP_DRAG_LEAVE = unsafeCastStringToDOMTopLevelType('dragleave');
1262var TOP_DRAG_OVER = unsafeCastStringToDOMTopLevelType('dragover');
1263var TOP_DRAG_START = unsafeCastStringToDOMTopLevelType('dragstart');
1264var TOP_DROP = unsafeCastStringToDOMTopLevelType('drop');
1265var TOP_DURATION_CHANGE = unsafeCastStringToDOMTopLevelType('durationchange');
1266var TOP_EMPTIED = unsafeCastStringToDOMTopLevelType('emptied');
1267var TOP_ENCRYPTED = unsafeCastStringToDOMTopLevelType('encrypted');
1268var TOP_ENDED = unsafeCastStringToDOMTopLevelType('ended');
1269var TOP_ERROR = unsafeCastStringToDOMTopLevelType('error');
1270var TOP_FOCUS = unsafeCastStringToDOMTopLevelType('focus');
1271var TOP_GOT_POINTER_CAPTURE = unsafeCastStringToDOMTopLevelType('gotpointercapture');
1272var TOP_INPUT = unsafeCastStringToDOMTopLevelType('input');
1273var TOP_INVALID = unsafeCastStringToDOMTopLevelType('invalid');
1274var TOP_KEY_DOWN = unsafeCastStringToDOMTopLevelType('keydown');
1275var TOP_KEY_PRESS = unsafeCastStringToDOMTopLevelType('keypress');
1276var TOP_KEY_UP = unsafeCastStringToDOMTopLevelType('keyup');
1277var TOP_LOAD = unsafeCastStringToDOMTopLevelType('load');
1278var TOP_LOAD_START = unsafeCastStringToDOMTopLevelType('loadstart');
1279var TOP_LOADED_DATA = unsafeCastStringToDOMTopLevelType('loadeddata');
1280var TOP_LOADED_METADATA = unsafeCastStringToDOMTopLevelType('loadedmetadata');
1281var TOP_LOST_POINTER_CAPTURE = unsafeCastStringToDOMTopLevelType('lostpointercapture');
1282var TOP_MOUSE_DOWN = unsafeCastStringToDOMTopLevelType('mousedown');
1283var TOP_MOUSE_MOVE = unsafeCastStringToDOMTopLevelType('mousemove');
1284var TOP_MOUSE_OUT = unsafeCastStringToDOMTopLevelType('mouseout');
1285var TOP_MOUSE_OVER = unsafeCastStringToDOMTopLevelType('mouseover');
1286var TOP_MOUSE_UP = unsafeCastStringToDOMTopLevelType('mouseup');
1287var TOP_PASTE = unsafeCastStringToDOMTopLevelType('paste');
1288var TOP_PAUSE = unsafeCastStringToDOMTopLevelType('pause');
1289var TOP_PLAY = unsafeCastStringToDOMTopLevelType('play');
1290var TOP_PLAYING = unsafeCastStringToDOMTopLevelType('playing');
1291var TOP_POINTER_CANCEL = unsafeCastStringToDOMTopLevelType('pointercancel');
1292var TOP_POINTER_DOWN = unsafeCastStringToDOMTopLevelType('pointerdown');
1293
1294
1295var TOP_POINTER_MOVE = unsafeCastStringToDOMTopLevelType('pointermove');
1296var TOP_POINTER_OUT = unsafeCastStringToDOMTopLevelType('pointerout');
1297var TOP_POINTER_OVER = unsafeCastStringToDOMTopLevelType('pointerover');
1298var TOP_POINTER_UP = unsafeCastStringToDOMTopLevelType('pointerup');
1299var TOP_PROGRESS = unsafeCastStringToDOMTopLevelType('progress');
1300var TOP_RATE_CHANGE = unsafeCastStringToDOMTopLevelType('ratechange');
1301var TOP_RESET = unsafeCastStringToDOMTopLevelType('reset');
1302var TOP_SCROLL = unsafeCastStringToDOMTopLevelType('scroll');
1303var TOP_SEEKED = unsafeCastStringToDOMTopLevelType('seeked');
1304var TOP_SEEKING = unsafeCastStringToDOMTopLevelType('seeking');
1305var TOP_SELECTION_CHANGE = unsafeCastStringToDOMTopLevelType('selectionchange');
1306var TOP_STALLED = unsafeCastStringToDOMTopLevelType('stalled');
1307var TOP_SUBMIT = unsafeCastStringToDOMTopLevelType('submit');
1308var TOP_SUSPEND = unsafeCastStringToDOMTopLevelType('suspend');
1309var TOP_TEXT_INPUT = unsafeCastStringToDOMTopLevelType('textInput');
1310var TOP_TIME_UPDATE = unsafeCastStringToDOMTopLevelType('timeupdate');
1311var TOP_TOGGLE = unsafeCastStringToDOMTopLevelType('toggle');
1312var TOP_TOUCH_CANCEL = unsafeCastStringToDOMTopLevelType('touchcancel');
1313var TOP_TOUCH_END = unsafeCastStringToDOMTopLevelType('touchend');
1314var TOP_TOUCH_MOVE = unsafeCastStringToDOMTopLevelType('touchmove');
1315var TOP_TOUCH_START = unsafeCastStringToDOMTopLevelType('touchstart');
1316var TOP_TRANSITION_END = unsafeCastStringToDOMTopLevelType(getVendorPrefixedEventName('transitionend'));
1317var TOP_VOLUME_CHANGE = unsafeCastStringToDOMTopLevelType('volumechange');
1318var TOP_WAITING = unsafeCastStringToDOMTopLevelType('waiting');
1319var TOP_WHEEL = unsafeCastStringToDOMTopLevelType('wheel');
1320
1321// List of events that need to be individually attached to media elements.
1322// Note that events in this list will *not* be listened to at the top level
1323// unless they're explicitly whitelisted in `ReactBrowserEventEmitter.listenTo`.
1324var mediaEventTypes = [TOP_ABORT, TOP_CAN_PLAY, TOP_CAN_PLAY_THROUGH, TOP_DURATION_CHANGE, TOP_EMPTIED, TOP_ENCRYPTED, TOP_ENDED, TOP_ERROR, TOP_LOADED_DATA, TOP_LOADED_METADATA, TOP_LOAD_START, TOP_PAUSE, TOP_PLAY, TOP_PLAYING, TOP_PROGRESS, TOP_RATE_CHANGE, TOP_SEEKED, TOP_SEEKING, TOP_STALLED, TOP_SUSPEND, TOP_TIME_UPDATE, TOP_VOLUME_CHANGE, TOP_WAITING];
1325
1326function getRawEventName(topLevelType) {
1327 return unsafeCastDOMTopLevelTypeToString(topLevelType);
1328}
1329
1330/**
1331 * These variables store information about text content of a target node,
1332 * allowing comparison of content before and after a given event.
1333 *
1334 * Identify the node where selection currently begins, then observe
1335 * both its text content and its current position in the DOM. Since the
1336 * browser may natively replace the target node during composition, we can
1337 * use its position to find its replacement.
1338 *
1339 *
1340 */
1341
1342var root = null;
1343var startText = null;
1344var fallbackText = null;
1345
1346function initialize(nativeEventTarget) {
1347 root = nativeEventTarget;
1348 startText = getText();
1349 return true;
1350}
1351
1352function reset() {
1353 root = null;
1354 startText = null;
1355 fallbackText = null;
1356}
1357
1358function getData() {
1359 if (fallbackText) {
1360 return fallbackText;
1361 }
1362
1363 var start = void 0;
1364 var startValue = startText;
1365 var startLength = startValue.length;
1366 var end = void 0;
1367 var endValue = getText();
1368 var endLength = endValue.length;
1369
1370 for (start = 0; start < startLength; start++) {
1371 if (startValue[start] !== endValue[start]) {
1372 break;
1373 }
1374 }
1375
1376 var minEnd = startLength - start;
1377 for (end = 1; end <= minEnd; end++) {
1378 if (startValue[startLength - end] !== endValue[endLength - end]) {
1379 break;
1380 }
1381 }
1382
1383 var sliceTail = end > 1 ? 1 - end : undefined;
1384 fallbackText = endValue.slice(start, sliceTail);
1385 return fallbackText;
1386}
1387
1388function getText() {
1389 if ('value' in root) {
1390 return root.value;
1391 }
1392 return root.textContent;
1393}
1394
1395var ReactInternals = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
1396
1397var _assign = ReactInternals.assign;
1398
1399/* eslint valid-typeof: 0 */
1400
1401var EVENT_POOL_SIZE = 10;
1402
1403/**
1404 * @interface Event
1405 * @see http://www.w3.org/TR/DOM-Level-3-Events/
1406 */
1407var EventInterface = {
1408 type: null,
1409 target: null,
1410 // currentTarget is set when dispatching; no use in copying it here
1411 currentTarget: function () {
1412 return null;
1413 },
1414 eventPhase: null,
1415 bubbles: null,
1416 cancelable: null,
1417 timeStamp: function (event) {
1418 return event.timeStamp || Date.now();
1419 },
1420 defaultPrevented: null,
1421 isTrusted: null
1422};
1423
1424function functionThatReturnsTrue() {
1425 return true;
1426}
1427
1428function functionThatReturnsFalse() {
1429 return false;
1430}
1431
1432/**
1433 * Synthetic events are dispatched by event plugins, typically in response to a
1434 * top-level event delegation handler.
1435 *
1436 * These systems should generally use pooling to reduce the frequency of garbage
1437 * collection. The system should check `isPersistent` to determine whether the
1438 * event should be released into the pool after being dispatched. Users that
1439 * need a persisted event should invoke `persist`.
1440 *
1441 * Synthetic events (and subclasses) implement the DOM Level 3 Events API by
1442 * normalizing browser quirks. Subclasses do not necessarily have to implement a
1443 * DOM interface; custom application-specific events can also subclass this.
1444 *
1445 * @param {object} dispatchConfig Configuration used to dispatch this event.
1446 * @param {*} targetInst Marker identifying the event target.
1447 * @param {object} nativeEvent Native browser event.
1448 * @param {DOMEventTarget} nativeEventTarget Target node.
1449 */
1450function SyntheticEvent(dispatchConfig, targetInst, nativeEvent, nativeEventTarget) {
1451 {
1452 // these have a getter/setter for warnings
1453 delete this.nativeEvent;
1454 delete this.preventDefault;
1455 delete this.stopPropagation;
1456 delete this.isDefaultPrevented;
1457 delete this.isPropagationStopped;
1458 }
1459
1460 this.dispatchConfig = dispatchConfig;
1461 this._targetInst = targetInst;
1462 this.nativeEvent = nativeEvent;
1463
1464 var Interface = this.constructor.Interface;
1465 for (var propName in Interface) {
1466 if (!Interface.hasOwnProperty(propName)) {
1467 continue;
1468 }
1469 {
1470 delete this[propName]; // this has a getter/setter for warnings
1471 }
1472 var normalize = Interface[propName];
1473 if (normalize) {
1474 this[propName] = normalize(nativeEvent);
1475 } else {
1476 if (propName === 'target') {
1477 this.target = nativeEventTarget;
1478 } else {
1479 this[propName] = nativeEvent[propName];
1480 }
1481 }
1482 }
1483
1484 var defaultPrevented = nativeEvent.defaultPrevented != null ? nativeEvent.defaultPrevented : nativeEvent.returnValue === false;
1485 if (defaultPrevented) {
1486 this.isDefaultPrevented = functionThatReturnsTrue;
1487 } else {
1488 this.isDefaultPrevented = functionThatReturnsFalse;
1489 }
1490 this.isPropagationStopped = functionThatReturnsFalse;
1491 return this;
1492}
1493
1494_assign(SyntheticEvent.prototype, {
1495 preventDefault: function () {
1496 this.defaultPrevented = true;
1497 var event = this.nativeEvent;
1498 if (!event) {
1499 return;
1500 }
1501
1502 if (event.preventDefault) {
1503 event.preventDefault();
1504 } else if (typeof event.returnValue !== 'unknown') {
1505 event.returnValue = false;
1506 }
1507 this.isDefaultPrevented = functionThatReturnsTrue;
1508 },
1509
1510 stopPropagation: function () {
1511 var event = this.nativeEvent;
1512 if (!event) {
1513 return;
1514 }
1515
1516 if (event.stopPropagation) {
1517 event.stopPropagation();
1518 } else if (typeof event.cancelBubble !== 'unknown') {
1519 // The ChangeEventPlugin registers a "propertychange" event for
1520 // IE. This event does not support bubbling or cancelling, and
1521 // any references to cancelBubble throw "Member not found". A
1522 // typeof check of "unknown" circumvents this issue (and is also
1523 // IE specific).
1524 event.cancelBubble = true;
1525 }
1526
1527 this.isPropagationStopped = functionThatReturnsTrue;
1528 },
1529
1530 /**
1531 * We release all dispatched `SyntheticEvent`s after each event loop, adding
1532 * them back into the pool. This allows a way to hold onto a reference that
1533 * won't be added back into the pool.
1534 */
1535 persist: function () {
1536 this.isPersistent = functionThatReturnsTrue;
1537 },
1538
1539 /**
1540 * Checks if this event should be released back into the pool.
1541 *
1542 * @return {boolean} True if this should not be released, false otherwise.
1543 */
1544 isPersistent: functionThatReturnsFalse,
1545
1546 /**
1547 * `PooledClass` looks for `destructor` on each instance it releases.
1548 */
1549 destructor: function () {
1550 var Interface = this.constructor.Interface;
1551 for (var propName in Interface) {
1552 {
1553 Object.defineProperty(this, propName, getPooledWarningPropertyDefinition(propName, Interface[propName]));
1554 }
1555 }
1556 this.dispatchConfig = null;
1557 this._targetInst = null;
1558 this.nativeEvent = null;
1559 this.isDefaultPrevented = functionThatReturnsFalse;
1560 this.isPropagationStopped = functionThatReturnsFalse;
1561 this._dispatchListeners = null;
1562 this._dispatchInstances = null;
1563 {
1564 Object.defineProperty(this, 'nativeEvent', getPooledWarningPropertyDefinition('nativeEvent', null));
1565 Object.defineProperty(this, 'isDefaultPrevented', getPooledWarningPropertyDefinition('isDefaultPrevented', functionThatReturnsFalse));
1566 Object.defineProperty(this, 'isPropagationStopped', getPooledWarningPropertyDefinition('isPropagationStopped', functionThatReturnsFalse));
1567 Object.defineProperty(this, 'preventDefault', getPooledWarningPropertyDefinition('preventDefault', function () {}));
1568 Object.defineProperty(this, 'stopPropagation', getPooledWarningPropertyDefinition('stopPropagation', function () {}));
1569 }
1570 }
1571});
1572
1573SyntheticEvent.Interface = EventInterface;
1574
1575/**
1576 * Helper to reduce boilerplate when creating subclasses.
1577 */
1578SyntheticEvent.extend = function (Interface) {
1579 var Super = this;
1580
1581 var E = function () {};
1582 E.prototype = Super.prototype;
1583 var prototype = new E();
1584
1585 function Class() {
1586 return Super.apply(this, arguments);
1587 }
1588 _assign(prototype, Class.prototype);
1589 Class.prototype = prototype;
1590 Class.prototype.constructor = Class;
1591
1592 Class.Interface = _assign({}, Super.Interface, Interface);
1593 Class.extend = Super.extend;
1594 addEventPoolingTo(Class);
1595
1596 return Class;
1597};
1598
1599addEventPoolingTo(SyntheticEvent);
1600
1601/**
1602 * Helper to nullify syntheticEvent instance properties when destructing
1603 *
1604 * @param {String} propName
1605 * @param {?object} getVal
1606 * @return {object} defineProperty object
1607 */
1608function getPooledWarningPropertyDefinition(propName, getVal) {
1609 var isFunction = typeof getVal === 'function';
1610 return {
1611 configurable: true,
1612 set: set,
1613 get: get
1614 };
1615
1616 function set(val) {
1617 var action = isFunction ? 'setting the method' : 'setting the property';
1618 warn(action, 'This is effectively a no-op');
1619 return val;
1620 }
1621
1622 function get() {
1623 var action = isFunction ? 'accessing the method' : 'accessing the property';
1624 var result = isFunction ? 'This is a no-op function' : 'This is set to null';
1625 warn(action, result);
1626 return getVal;
1627 }
1628
1629 function warn(action, result) {
1630 var warningCondition = false;
1631 !warningCondition ? warningWithoutStack$1(false, "This synthetic event is reused for performance reasons. If you're seeing this, " + "you're %s `%s` on a released/nullified synthetic event. %s. " + 'If you must keep the original synthetic event around, use event.persist(). ' + 'See https://fb.me/react-event-pooling for more information.', action, propName, result) : void 0;
1632 }
1633}
1634
1635function getPooledEvent(dispatchConfig, targetInst, nativeEvent, nativeInst) {
1636 var EventConstructor = this;
1637 if (EventConstructor.eventPool.length) {
1638 var instance = EventConstructor.eventPool.pop();
1639 EventConstructor.call(instance, dispatchConfig, targetInst, nativeEvent, nativeInst);
1640 return instance;
1641 }
1642 return new EventConstructor(dispatchConfig, targetInst, nativeEvent, nativeInst);
1643}
1644
1645function releasePooledEvent(event) {
1646 var EventConstructor = this;
1647 !(event instanceof EventConstructor) ? invariant(false, 'Trying to release an event instance into a pool of a different type.') : void 0;
1648 event.destructor();
1649 if (EventConstructor.eventPool.length < EVENT_POOL_SIZE) {
1650 EventConstructor.eventPool.push(event);
1651 }
1652}
1653
1654function addEventPoolingTo(EventConstructor) {
1655 EventConstructor.eventPool = [];
1656 EventConstructor.getPooled = getPooledEvent;
1657 EventConstructor.release = releasePooledEvent;
1658}
1659
1660/**
1661 * @interface Event
1662 * @see http://www.w3.org/TR/DOM-Level-3-Events/#events-compositionevents
1663 */
1664var SyntheticCompositionEvent = SyntheticEvent.extend({
1665 data: null
1666});
1667
1668/**
1669 * @interface Event
1670 * @see http://www.w3.org/TR/2013/WD-DOM-Level-3-Events-20131105
1671 * /#events-inputevents
1672 */
1673var SyntheticInputEvent = SyntheticEvent.extend({
1674 data: null
1675});
1676
1677var END_KEYCODES = [9, 13, 27, 32]; // Tab, Return, Esc, Space
1678var START_KEYCODE = 229;
1679
1680var canUseCompositionEvent = canUseDOM && 'CompositionEvent' in window;
1681
1682var documentMode = null;
1683if (canUseDOM && 'documentMode' in document) {
1684 documentMode = document.documentMode;
1685}
1686
1687// Webkit offers a very useful `textInput` event that can be used to
1688// directly represent `beforeInput`. The IE `textinput` event is not as
1689// useful, so we don't use it.
1690var canUseTextInputEvent = canUseDOM && 'TextEvent' in window && !documentMode;
1691
1692// In IE9+, we have access to composition events, but the data supplied
1693// by the native compositionend event may be incorrect. Japanese ideographic
1694// spaces, for instance (\u3000) are not recorded correctly.
1695var useFallbackCompositionData = canUseDOM && (!canUseCompositionEvent || documentMode && documentMode > 8 && documentMode <= 11);
1696
1697var SPACEBAR_CODE = 32;
1698var SPACEBAR_CHAR = String.fromCharCode(SPACEBAR_CODE);
1699
1700// Events and their corresponding property names.
1701var eventTypes = {
1702 beforeInput: {
1703 phasedRegistrationNames: {
1704 bubbled: 'onBeforeInput',
1705 captured: 'onBeforeInputCapture'
1706 },
1707 dependencies: [TOP_COMPOSITION_END, TOP_KEY_PRESS, TOP_TEXT_INPUT, TOP_PASTE]
1708 },
1709 compositionEnd: {
1710 phasedRegistrationNames: {
1711 bubbled: 'onCompositionEnd',
1712 captured: 'onCompositionEndCapture'
1713 },
1714 dependencies: [TOP_BLUR, TOP_COMPOSITION_END, TOP_KEY_DOWN, TOP_KEY_PRESS, TOP_KEY_UP, TOP_MOUSE_DOWN]
1715 },
1716 compositionStart: {
1717 phasedRegistrationNames: {
1718 bubbled: 'onCompositionStart',
1719 captured: 'onCompositionStartCapture'
1720 },
1721 dependencies: [TOP_BLUR, TOP_COMPOSITION_START, TOP_KEY_DOWN, TOP_KEY_PRESS, TOP_KEY_UP, TOP_MOUSE_DOWN]
1722 },
1723 compositionUpdate: {
1724 phasedRegistrationNames: {
1725 bubbled: 'onCompositionUpdate',
1726 captured: 'onCompositionUpdateCapture'
1727 },
1728 dependencies: [TOP_BLUR, TOP_COMPOSITION_UPDATE, TOP_KEY_DOWN, TOP_KEY_PRESS, TOP_KEY_UP, TOP_MOUSE_DOWN]
1729 }
1730};
1731
1732// Track whether we've ever handled a keypress on the space key.
1733var hasSpaceKeypress = false;
1734
1735/**
1736 * Return whether a native keypress event is assumed to be a command.
1737 * This is required because Firefox fires `keypress` events for key commands
1738 * (cut, copy, select-all, etc.) even though no character is inserted.
1739 */
1740function isKeypressCommand(nativeEvent) {
1741 return (nativeEvent.ctrlKey || nativeEvent.altKey || nativeEvent.metaKey) &&
1742 // ctrlKey && altKey is equivalent to AltGr, and is not a command.
1743 !(nativeEvent.ctrlKey && nativeEvent.altKey);
1744}
1745
1746/**
1747 * Translate native top level events into event types.
1748 *
1749 * @param {string} topLevelType
1750 * @return {object}
1751 */
1752function getCompositionEventType(topLevelType) {
1753 switch (topLevelType) {
1754 case TOP_COMPOSITION_START:
1755 return eventTypes.compositionStart;
1756 case TOP_COMPOSITION_END:
1757 return eventTypes.compositionEnd;
1758 case TOP_COMPOSITION_UPDATE:
1759 return eventTypes.compositionUpdate;
1760 }
1761}
1762
1763/**
1764 * Does our fallback best-guess model think this event signifies that
1765 * composition has begun?
1766 *
1767 * @param {string} topLevelType
1768 * @param {object} nativeEvent
1769 * @return {boolean}
1770 */
1771function isFallbackCompositionStart(topLevelType, nativeEvent) {
1772 return topLevelType === TOP_KEY_DOWN && nativeEvent.keyCode === START_KEYCODE;
1773}
1774
1775/**
1776 * Does our fallback mode think that this event is the end of composition?
1777 *
1778 * @param {string} topLevelType
1779 * @param {object} nativeEvent
1780 * @return {boolean}
1781 */
1782function isFallbackCompositionEnd(topLevelType, nativeEvent) {
1783 switch (topLevelType) {
1784 case TOP_KEY_UP:
1785 // Command keys insert or clear IME input.
1786 return END_KEYCODES.indexOf(nativeEvent.keyCode) !== -1;
1787 case TOP_KEY_DOWN:
1788 // Expect IME keyCode on each keydown. If we get any other
1789 // code we must have exited earlier.
1790 return nativeEvent.keyCode !== START_KEYCODE;
1791 case TOP_KEY_PRESS:
1792 case TOP_MOUSE_DOWN:
1793 case TOP_BLUR:
1794 // Events are not possible without cancelling IME.
1795 return true;
1796 default:
1797 return false;
1798 }
1799}
1800
1801/**
1802 * Google Input Tools provides composition data via a CustomEvent,
1803 * with the `data` property populated in the `detail` object. If this
1804 * is available on the event object, use it. If not, this is a plain
1805 * composition event and we have nothing special to extract.
1806 *
1807 * @param {object} nativeEvent
1808 * @return {?string}
1809 */
1810function getDataFromCustomEvent(nativeEvent) {
1811 var detail = nativeEvent.detail;
1812 if (typeof detail === 'object' && 'data' in detail) {
1813 return detail.data;
1814 }
1815 return null;
1816}
1817
1818/**
1819 * Check if a composition event was triggered by Korean IME.
1820 * Our fallback mode does not work well with IE's Korean IME,
1821 * so just use native composition events when Korean IME is used.
1822 * Although CompositionEvent.locale property is deprecated,
1823 * it is available in IE, where our fallback mode is enabled.
1824 *
1825 * @param {object} nativeEvent
1826 * @return {boolean}
1827 */
1828function isUsingKoreanIME(nativeEvent) {
1829 return nativeEvent.locale === 'ko';
1830}
1831
1832// Track the current IME composition status, if any.
1833var isComposing = false;
1834
1835/**
1836 * @return {?object} A SyntheticCompositionEvent.
1837 */
1838function extractCompositionEvent(topLevelType, targetInst, nativeEvent, nativeEventTarget) {
1839 var eventType = void 0;
1840 var fallbackData = void 0;
1841
1842 if (canUseCompositionEvent) {
1843 eventType = getCompositionEventType(topLevelType);
1844 } else if (!isComposing) {
1845 if (isFallbackCompositionStart(topLevelType, nativeEvent)) {
1846 eventType = eventTypes.compositionStart;
1847 }
1848 } else if (isFallbackCompositionEnd(topLevelType, nativeEvent)) {
1849 eventType = eventTypes.compositionEnd;
1850 }
1851
1852 if (!eventType) {
1853 return null;
1854 }
1855
1856 if (useFallbackCompositionData && !isUsingKoreanIME(nativeEvent)) {
1857 // The current composition is stored statically and must not be
1858 // overwritten while composition continues.
1859 if (!isComposing && eventType === eventTypes.compositionStart) {
1860 isComposing = initialize(nativeEventTarget);
1861 } else if (eventType === eventTypes.compositionEnd) {
1862 if (isComposing) {
1863 fallbackData = getData();
1864 }
1865 }
1866 }
1867
1868 var event = SyntheticCompositionEvent.getPooled(eventType, targetInst, nativeEvent, nativeEventTarget);
1869
1870 if (fallbackData) {
1871 // Inject data generated from fallback path into the synthetic event.
1872 // This matches the property of native CompositionEventInterface.
1873 event.data = fallbackData;
1874 } else {
1875 var customData = getDataFromCustomEvent(nativeEvent);
1876 if (customData !== null) {
1877 event.data = customData;
1878 }
1879 }
1880
1881 accumulateTwoPhaseDispatches(event);
1882 return event;
1883}
1884
1885/**
1886 * @param {TopLevelType} topLevelType Number from `TopLevelType`.
1887 * @param {object} nativeEvent Native browser event.
1888 * @return {?string} The string corresponding to this `beforeInput` event.
1889 */
1890function getNativeBeforeInputChars(topLevelType, nativeEvent) {
1891 switch (topLevelType) {
1892 case TOP_COMPOSITION_END:
1893 return getDataFromCustomEvent(nativeEvent);
1894 case TOP_KEY_PRESS:
1895 /**
1896 * If native `textInput` events are available, our goal is to make
1897 * use of them. However, there is a special case: the spacebar key.
1898 * In Webkit, preventing default on a spacebar `textInput` event
1899 * cancels character insertion, but it *also* causes the browser
1900 * to fall back to its default spacebar behavior of scrolling the
1901 * page.
1902 *
1903 * Tracking at:
1904 * https://code.google.com/p/chromium/issues/detail?id=355103
1905 *
1906 * To avoid this issue, use the keypress event as if no `textInput`
1907 * event is available.
1908 */
1909 var which = nativeEvent.which;
1910 if (which !== SPACEBAR_CODE) {
1911 return null;
1912 }
1913
1914 hasSpaceKeypress = true;
1915 return SPACEBAR_CHAR;
1916
1917 case TOP_TEXT_INPUT:
1918 // Record the characters to be added to the DOM.
1919 var chars = nativeEvent.data;
1920
1921 // If it's a spacebar character, assume that we have already handled
1922 // it at the keypress level and bail immediately. Android Chrome
1923 // doesn't give us keycodes, so we need to ignore it.
1924 if (chars === SPACEBAR_CHAR && hasSpaceKeypress) {
1925 return null;
1926 }
1927
1928 return chars;
1929
1930 default:
1931 // For other native event types, do nothing.
1932 return null;
1933 }
1934}
1935
1936/**
1937 * For browsers that do not provide the `textInput` event, extract the
1938 * appropriate string to use for SyntheticInputEvent.
1939 *
1940 * @param {number} topLevelType Number from `TopLevelEventTypes`.
1941 * @param {object} nativeEvent Native browser event.
1942 * @return {?string} The fallback string for this `beforeInput` event.
1943 */
1944function getFallbackBeforeInputChars(topLevelType, nativeEvent) {
1945 // If we are currently composing (IME) and using a fallback to do so,
1946 // try to extract the composed characters from the fallback object.
1947 // If composition event is available, we extract a string only at
1948 // compositionevent, otherwise extract it at fallback events.
1949 if (isComposing) {
1950 if (topLevelType === TOP_COMPOSITION_END || !canUseCompositionEvent && isFallbackCompositionEnd(topLevelType, nativeEvent)) {
1951 var chars = getData();
1952 reset();
1953 isComposing = false;
1954 return chars;
1955 }
1956 return null;
1957 }
1958
1959 switch (topLevelType) {
1960 case TOP_PASTE:
1961 // If a paste event occurs after a keypress, throw out the input
1962 // chars. Paste events should not lead to BeforeInput events.
1963 return null;
1964 case TOP_KEY_PRESS:
1965 /**
1966 * As of v27, Firefox may fire keypress events even when no character
1967 * will be inserted. A few possibilities:
1968 *
1969 * - `which` is `0`. Arrow keys, Esc key, etc.
1970 *
1971 * - `which` is the pressed key code, but no char is available.
1972 * Ex: 'AltGr + d` in Polish. There is no modified character for
1973 * this key combination and no character is inserted into the
1974 * document, but FF fires the keypress for char code `100` anyway.
1975 * No `input` event will occur.
1976 *
1977 * - `which` is the pressed key code, but a command combination is
1978 * being used. Ex: `Cmd+C`. No character is inserted, and no
1979 * `input` event will occur.
1980 */
1981 if (!isKeypressCommand(nativeEvent)) {
1982 // IE fires the `keypress` event when a user types an emoji via
1983 // Touch keyboard of Windows. In such a case, the `char` property
1984 // holds an emoji character like `\uD83D\uDE0A`. Because its length
1985 // is 2, the property `which` does not represent an emoji correctly.
1986 // In such a case, we directly return the `char` property instead of
1987 // using `which`.
1988 if (nativeEvent.char && nativeEvent.char.length > 1) {
1989 return nativeEvent.char;
1990 } else if (nativeEvent.which) {
1991 return String.fromCharCode(nativeEvent.which);
1992 }
1993 }
1994 return null;
1995 case TOP_COMPOSITION_END:
1996 return useFallbackCompositionData && !isUsingKoreanIME(nativeEvent) ? null : nativeEvent.data;
1997 default:
1998 return null;
1999 }
2000}
2001
2002/**
2003 * Extract a SyntheticInputEvent for `beforeInput`, based on either native
2004 * `textInput` or fallback behavior.
2005 *
2006 * @return {?object} A SyntheticInputEvent.
2007 */
2008function extractBeforeInputEvent(topLevelType, targetInst, nativeEvent, nativeEventTarget) {
2009 var chars = void 0;
2010
2011 if (canUseTextInputEvent) {
2012 chars = getNativeBeforeInputChars(topLevelType, nativeEvent);
2013 } else {
2014 chars = getFallbackBeforeInputChars(topLevelType, nativeEvent);
2015 }
2016
2017 // If no characters are being inserted, no BeforeInput event should
2018 // be fired.
2019 if (!chars) {
2020 return null;
2021 }
2022
2023 var event = SyntheticInputEvent.getPooled(eventTypes.beforeInput, targetInst, nativeEvent, nativeEventTarget);
2024
2025 event.data = chars;
2026 accumulateTwoPhaseDispatches(event);
2027 return event;
2028}
2029
2030/**
2031 * Create an `onBeforeInput` event to match
2032 * http://www.w3.org/TR/2013/WD-DOM-Level-3-Events-20131105/#events-inputevents.
2033 *
2034 * This event plugin is based on the native `textInput` event
2035 * available in Chrome, Safari, Opera, and IE. This event fires after
2036 * `onKeyPress` and `onCompositionEnd`, but before `onInput`.
2037 *
2038 * `beforeInput` is spec'd but not implemented in any browsers, and
2039 * the `input` event does not provide any useful information about what has
2040 * actually been added, contrary to the spec. Thus, `textInput` is the best
2041 * available event to identify the characters that have actually been inserted
2042 * into the target node.
2043 *
2044 * This plugin is also responsible for emitting `composition` events, thus
2045 * allowing us to share composition fallback code for both `beforeInput` and
2046 * `composition` event types.
2047 */
2048var BeforeInputEventPlugin = {
2049 eventTypes: eventTypes,
2050
2051 extractEvents: function (topLevelType, targetInst, nativeEvent, nativeEventTarget) {
2052 var composition = extractCompositionEvent(topLevelType, targetInst, nativeEvent, nativeEventTarget);
2053
2054 var beforeInput = extractBeforeInputEvent(topLevelType, targetInst, nativeEvent, nativeEventTarget);
2055
2056 if (composition === null) {
2057 return beforeInput;
2058 }
2059
2060 if (beforeInput === null) {
2061 return composition;
2062 }
2063
2064 return [composition, beforeInput];
2065 }
2066};
2067
2068// Use to restore controlled state after a change event has fired.
2069
2070var restoreImpl = null;
2071var restoreTarget = null;
2072var restoreQueue = null;
2073
2074function restoreStateOfTarget(target) {
2075 // We perform this translation at the end of the event loop so that we
2076 // always receive the correct fiber here
2077 var internalInstance = getInstanceFromNode(target);
2078 if (!internalInstance) {
2079 // Unmounted
2080 return;
2081 }
2082 !(typeof restoreImpl === 'function') ? invariant(false, 'setRestoreImplementation() needs to be called to handle a target for controlled events. This error is likely caused by a bug in React. Please file an issue.') : void 0;
2083 var props = getFiberCurrentPropsFromNode(internalInstance.stateNode);
2084 restoreImpl(internalInstance.stateNode, internalInstance.type, props);
2085}
2086
2087function setRestoreImplementation(impl) {
2088 restoreImpl = impl;
2089}
2090
2091function enqueueStateRestore(target) {
2092 if (restoreTarget) {
2093 if (restoreQueue) {
2094 restoreQueue.push(target);
2095 } else {
2096 restoreQueue = [target];
2097 }
2098 } else {
2099 restoreTarget = target;
2100 }
2101}
2102
2103function needsStateRestore() {
2104 return restoreTarget !== null || restoreQueue !== null;
2105}
2106
2107function restoreStateIfNeeded() {
2108 if (!restoreTarget) {
2109 return;
2110 }
2111 var target = restoreTarget;
2112 var queuedTargets = restoreQueue;
2113 restoreTarget = null;
2114 restoreQueue = null;
2115
2116 restoreStateOfTarget(target);
2117 if (queuedTargets) {
2118 for (var i = 0; i < queuedTargets.length; i++) {
2119 restoreStateOfTarget(queuedTargets[i]);
2120 }
2121 }
2122}
2123
2124// Used as a way to call batchedUpdates when we don't have a reference to
2125// the renderer. Such as when we're dispatching events or if third party
2126// libraries need to call batchedUpdates. Eventually, this API will go away when
2127// everything is batched by default. We'll then have a similar API to opt-out of
2128// scheduled work and instead do synchronous work.
2129
2130// Defaults
2131var _batchedUpdatesImpl = function (fn, bookkeeping) {
2132 return fn(bookkeeping);
2133};
2134var _interactiveUpdatesImpl = function (fn, a, b) {
2135 return fn(a, b);
2136};
2137var _flushInteractiveUpdatesImpl = function () {};
2138
2139var isBatching = false;
2140function batchedUpdates(fn, bookkeeping) {
2141 if (isBatching) {
2142 // If we are currently inside another batch, we need to wait until it
2143 // fully completes before restoring state.
2144 return fn(bookkeeping);
2145 }
2146 isBatching = true;
2147 try {
2148 return _batchedUpdatesImpl(fn, bookkeeping);
2149 } finally {
2150 // Here we wait until all updates have propagated, which is important
2151 // when using controlled components within layers:
2152 // https://github.com/facebook/react/issues/1698
2153 // Then we restore state of any controlled component.
2154 isBatching = false;
2155 var controlledComponentsHavePendingUpdates = needsStateRestore();
2156 if (controlledComponentsHavePendingUpdates) {
2157 // If a controlled event was fired, we may need to restore the state of
2158 // the DOM node back to the controlled value. This is necessary when React
2159 // bails out of the update without touching the DOM.
2160 _flushInteractiveUpdatesImpl();
2161 restoreStateIfNeeded();
2162 }
2163 }
2164}
2165
2166function interactiveUpdates(fn, a, b) {
2167 return _interactiveUpdatesImpl(fn, a, b);
2168}
2169
2170
2171
2172function setBatchingImplementation(batchedUpdatesImpl, interactiveUpdatesImpl, flushInteractiveUpdatesImpl) {
2173 _batchedUpdatesImpl = batchedUpdatesImpl;
2174 _interactiveUpdatesImpl = interactiveUpdatesImpl;
2175 _flushInteractiveUpdatesImpl = flushInteractiveUpdatesImpl;
2176}
2177
2178/**
2179 * @see http://www.whatwg.org/specs/web-apps/current-work/multipage/the-input-element.html#input-type-attr-summary
2180 */
2181var supportedInputTypes = {
2182 color: true,
2183 date: true,
2184 datetime: true,
2185 'datetime-local': true,
2186 email: true,
2187 month: true,
2188 number: true,
2189 password: true,
2190 range: true,
2191 search: true,
2192 tel: true,
2193 text: true,
2194 time: true,
2195 url: true,
2196 week: true
2197};
2198
2199function isTextInputElement(elem) {
2200 var nodeName = elem && elem.nodeName && elem.nodeName.toLowerCase();
2201
2202 if (nodeName === 'input') {
2203 return !!supportedInputTypes[elem.type];
2204 }
2205
2206 if (nodeName === 'textarea') {
2207 return true;
2208 }
2209
2210 return false;
2211}
2212
2213/**
2214 * HTML nodeType values that represent the type of the node
2215 */
2216
2217var ELEMENT_NODE = 1;
2218var TEXT_NODE = 3;
2219var COMMENT_NODE = 8;
2220var DOCUMENT_NODE = 9;
2221var DOCUMENT_FRAGMENT_NODE = 11;
2222
2223/**
2224 * Gets the target node from a native browser event by accounting for
2225 * inconsistencies in browser DOM APIs.
2226 *
2227 * @param {object} nativeEvent Native browser event.
2228 * @return {DOMEventTarget} Target node.
2229 */
2230function getEventTarget(nativeEvent) {
2231 // Fallback to nativeEvent.srcElement for IE9
2232 // https://github.com/facebook/react/issues/12506
2233 var target = nativeEvent.target || nativeEvent.srcElement || window;
2234
2235 // Normalize SVG <use> element events #4963
2236 if (target.correspondingUseElement) {
2237 target = target.correspondingUseElement;
2238 }
2239
2240 // Safari may fire events on text nodes (Node.TEXT_NODE is 3).
2241 // @see http://www.quirksmode.org/js/events_properties.html
2242 return target.nodeType === TEXT_NODE ? target.parentNode : target;
2243}
2244
2245/**
2246 * Checks if an event is supported in the current execution environment.
2247 *
2248 * NOTE: This will not work correctly for non-generic events such as `change`,
2249 * `reset`, `load`, `error`, and `select`.
2250 *
2251 * Borrows from Modernizr.
2252 *
2253 * @param {string} eventNameSuffix Event name, e.g. "click".
2254 * @return {boolean} True if the event is supported.
2255 * @internal
2256 * @license Modernizr 3.0.0pre (Custom Build) | MIT
2257 */
2258function isEventSupported(eventNameSuffix) {
2259 if (!canUseDOM) {
2260 return false;
2261 }
2262
2263 var eventName = 'on' + eventNameSuffix;
2264 var isSupported = eventName in document;
2265
2266 if (!isSupported) {
2267 var element = document.createElement('div');
2268 element.setAttribute(eventName, 'return;');
2269 isSupported = typeof element[eventName] === 'function';
2270 }
2271
2272 return isSupported;
2273}
2274
2275function isCheckable(elem) {
2276 var type = elem.type;
2277 var nodeName = elem.nodeName;
2278 return nodeName && nodeName.toLowerCase() === 'input' && (type === 'checkbox' || type === 'radio');
2279}
2280
2281function getTracker(node) {
2282 return node._valueTracker;
2283}
2284
2285function detachTracker(node) {
2286 node._valueTracker = null;
2287}
2288
2289function getValueFromNode(node) {
2290 var value = '';
2291 if (!node) {
2292 return value;
2293 }
2294
2295 if (isCheckable(node)) {
2296 value = node.checked ? 'true' : 'false';
2297 } else {
2298 value = node.value;
2299 }
2300
2301 return value;
2302}
2303
2304function trackValueOnNode(node) {
2305 var valueField = isCheckable(node) ? 'checked' : 'value';
2306 var descriptor = Object.getOwnPropertyDescriptor(node.constructor.prototype, valueField);
2307
2308 var currentValue = '' + node[valueField];
2309
2310 // if someone has already defined a value or Safari, then bail
2311 // and don't track value will cause over reporting of changes,
2312 // but it's better then a hard failure
2313 // (needed for certain tests that spyOn input values and Safari)
2314 if (node.hasOwnProperty(valueField) || typeof descriptor === 'undefined' || typeof descriptor.get !== 'function' || typeof descriptor.set !== 'function') {
2315 return;
2316 }
2317 var get = descriptor.get,
2318 set = descriptor.set;
2319
2320 Object.defineProperty(node, valueField, {
2321 configurable: true,
2322 get: function () {
2323 return get.call(this);
2324 },
2325 set: function (value) {
2326 currentValue = '' + value;
2327 set.call(this, value);
2328 }
2329 });
2330 // We could've passed this the first time
2331 // but it triggers a bug in IE11 and Edge 14/15.
2332 // Calling defineProperty() again should be equivalent.
2333 // https://github.com/facebook/react/issues/11768
2334 Object.defineProperty(node, valueField, {
2335 enumerable: descriptor.enumerable
2336 });
2337
2338 var tracker = {
2339 getValue: function () {
2340 return currentValue;
2341 },
2342 setValue: function (value) {
2343 currentValue = '' + value;
2344 },
2345 stopTracking: function () {
2346 detachTracker(node);
2347 delete node[valueField];
2348 }
2349 };
2350 return tracker;
2351}
2352
2353function track(node) {
2354 if (getTracker(node)) {
2355 return;
2356 }
2357
2358 // TODO: Once it's just Fiber we can move this to node._wrapperState
2359 node._valueTracker = trackValueOnNode(node);
2360}
2361
2362function updateValueIfChanged(node) {
2363 if (!node) {
2364 return false;
2365 }
2366
2367 var tracker = getTracker(node);
2368 // if there is no tracker at this point it's unlikely
2369 // that trying again will succeed
2370 if (!tracker) {
2371 return true;
2372 }
2373
2374 var lastValue = tracker.getValue();
2375 var nextValue = getValueFromNode(node);
2376 if (nextValue !== lastValue) {
2377 tracker.setValue(nextValue);
2378 return true;
2379 }
2380 return false;
2381}
2382
2383var ReactSharedInternals = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
2384
2385var BEFORE_SLASH_RE = /^(.*)[\\\/]/;
2386
2387var describeComponentFrame = function (name, source, ownerName) {
2388 var sourceInfo = '';
2389 if (source) {
2390 var path = source.fileName;
2391 var fileName = path.replace(BEFORE_SLASH_RE, '');
2392 {
2393 // In DEV, include code for a common special case:
2394 // prefer "folder/index.js" instead of just "index.js".
2395 if (/^index\./.test(fileName)) {
2396 var match = path.match(BEFORE_SLASH_RE);
2397 if (match) {
2398 var pathBeforeSlash = match[1];
2399 if (pathBeforeSlash) {
2400 var folderName = pathBeforeSlash.replace(BEFORE_SLASH_RE, '');
2401 fileName = folderName + '/' + fileName;
2402 }
2403 }
2404 }
2405 }
2406 sourceInfo = ' (at ' + fileName + ':' + source.lineNumber + ')';
2407 } else if (ownerName) {
2408 sourceInfo = ' (created by ' + ownerName + ')';
2409 }
2410 return '\n in ' + (name || 'Unknown') + sourceInfo;
2411};
2412
2413// The Symbol used to tag the ReactElement-like types. If there is no native Symbol
2414// nor polyfill, then a plain number is used for performance.
2415var hasSymbol = typeof Symbol === 'function' && Symbol.for;
2416
2417var REACT_ELEMENT_TYPE = hasSymbol ? Symbol.for('react.element') : 0xeac7;
2418var REACT_PORTAL_TYPE = hasSymbol ? Symbol.for('react.portal') : 0xeaca;
2419var REACT_FRAGMENT_TYPE = hasSymbol ? Symbol.for('react.fragment') : 0xeacb;
2420var REACT_STRICT_MODE_TYPE = hasSymbol ? Symbol.for('react.strict_mode') : 0xeacc;
2421var REACT_PROFILER_TYPE = hasSymbol ? Symbol.for('react.profiler') : 0xead2;
2422var REACT_PROVIDER_TYPE = hasSymbol ? Symbol.for('react.provider') : 0xeacd;
2423var REACT_CONTEXT_TYPE = hasSymbol ? Symbol.for('react.context') : 0xeace;
2424
2425var REACT_CONCURRENT_MODE_TYPE = hasSymbol ? Symbol.for('react.concurrent_mode') : 0xeacf;
2426var REACT_FORWARD_REF_TYPE = hasSymbol ? Symbol.for('react.forward_ref') : 0xead0;
2427var REACT_SUSPENSE_TYPE = hasSymbol ? Symbol.for('react.suspense') : 0xead1;
2428var REACT_MEMO_TYPE = hasSymbol ? Symbol.for('react.memo') : 0xead3;
2429var REACT_LAZY_TYPE = hasSymbol ? Symbol.for('react.lazy') : 0xead4;
2430
2431var MAYBE_ITERATOR_SYMBOL = typeof Symbol === 'function' && Symbol.iterator;
2432var FAUX_ITERATOR_SYMBOL = '@@iterator';
2433
2434function getIteratorFn(maybeIterable) {
2435 if (maybeIterable === null || typeof maybeIterable !== 'object') {
2436 return null;
2437 }
2438 var maybeIterator = MAYBE_ITERATOR_SYMBOL && maybeIterable[MAYBE_ITERATOR_SYMBOL] || maybeIterable[FAUX_ITERATOR_SYMBOL];
2439 if (typeof maybeIterator === 'function') {
2440 return maybeIterator;
2441 }
2442 return null;
2443}
2444
2445var Pending = 0;
2446var Resolved = 1;
2447var Rejected = 2;
2448
2449function refineResolvedLazyComponent(lazyComponent) {
2450 return lazyComponent._status === Resolved ? lazyComponent._result : null;
2451}
2452
2453function getWrappedName(outerType, innerType, wrapperName) {
2454 var functionName = innerType.displayName || innerType.name || '';
2455 return outerType.displayName || (functionName !== '' ? wrapperName + '(' + functionName + ')' : wrapperName);
2456}
2457
2458function getComponentName(type) {
2459 if (type == null) {
2460 // Host root, text node or just invalid type.
2461 return null;
2462 }
2463 {
2464 if (typeof type.tag === 'number') {
2465 warningWithoutStack$1(false, 'Received an unexpected object in getComponentName(). ' + 'This is likely a bug in React. Please file an issue.');
2466 }
2467 }
2468 if (typeof type === 'function') {
2469 return type.displayName || type.name || null;
2470 }
2471 if (typeof type === 'string') {
2472 return type;
2473 }
2474 switch (type) {
2475 case REACT_CONCURRENT_MODE_TYPE:
2476 return 'ConcurrentMode';
2477 case REACT_FRAGMENT_TYPE:
2478 return 'Fragment';
2479 case REACT_PORTAL_TYPE:
2480 return 'Portal';
2481 case REACT_PROFILER_TYPE:
2482 return 'Profiler';
2483 case REACT_STRICT_MODE_TYPE:
2484 return 'StrictMode';
2485 case REACT_SUSPENSE_TYPE:
2486 return 'Suspense';
2487 }
2488 if (typeof type === 'object') {
2489 switch (type.$$typeof) {
2490 case REACT_CONTEXT_TYPE:
2491 return 'Context.Consumer';
2492 case REACT_PROVIDER_TYPE:
2493 return 'Context.Provider';
2494 case REACT_FORWARD_REF_TYPE:
2495 return getWrappedName(type, type.render, 'ForwardRef');
2496 case REACT_MEMO_TYPE:
2497 return getComponentName(type.type);
2498 case REACT_LAZY_TYPE:
2499 {
2500 var thenable = type;
2501 var resolvedThenable = refineResolvedLazyComponent(thenable);
2502 if (resolvedThenable) {
2503 return getComponentName(resolvedThenable);
2504 }
2505 }
2506 }
2507 }
2508 return null;
2509}
2510
2511var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame;
2512
2513function describeFiber(fiber) {
2514 switch (fiber.tag) {
2515 case HostRoot:
2516 case HostPortal:
2517 case HostText:
2518 case Fragment:
2519 case ContextProvider:
2520 case ContextConsumer:
2521 return '';
2522 default:
2523 var owner = fiber._debugOwner;
2524 var source = fiber._debugSource;
2525 var name = getComponentName(fiber.type);
2526 var ownerName = null;
2527 if (owner) {
2528 ownerName = getComponentName(owner.type);
2529 }
2530 return describeComponentFrame(name, source, ownerName);
2531 }
2532}
2533
2534function getStackByFiberInDevAndProd(workInProgress) {
2535 var info = '';
2536 var node = workInProgress;
2537 do {
2538 info += describeFiber(node);
2539 node = node.return;
2540 } while (node);
2541 return info;
2542}
2543
2544var current = null;
2545var phase = null;
2546
2547function getCurrentFiberOwnerNameInDevOrNull() {
2548 {
2549 if (current === null) {
2550 return null;
2551 }
2552 var owner = current._debugOwner;
2553 if (owner !== null && typeof owner !== 'undefined') {
2554 return getComponentName(owner.type);
2555 }
2556 }
2557 return null;
2558}
2559
2560function getCurrentFiberStackInDev() {
2561 {
2562 if (current === null) {
2563 return '';
2564 }
2565 // Safe because if current fiber exists, we are reconciling,
2566 // and it is guaranteed to be the work-in-progress version.
2567 return getStackByFiberInDevAndProd(current);
2568 }
2569 return '';
2570}
2571
2572function resetCurrentFiber() {
2573 {
2574 ReactDebugCurrentFrame.getCurrentStack = null;
2575 current = null;
2576 phase = null;
2577 }
2578}
2579
2580function setCurrentFiber(fiber) {
2581 {
2582 ReactDebugCurrentFrame.getCurrentStack = getCurrentFiberStackInDev;
2583 current = fiber;
2584 phase = null;
2585 }
2586}
2587
2588function setCurrentPhase(lifeCyclePhase) {
2589 {
2590 phase = lifeCyclePhase;
2591 }
2592}
2593
2594/**
2595 * Similar to invariant but only logs a warning if the condition is not met.
2596 * This can be used to log issues in development environments in critical
2597 * paths. Removing the logging code for production environments will keep the
2598 * same logic and follow the same code paths.
2599 */
2600
2601var warning = warningWithoutStack$1;
2602
2603{
2604 warning = function (condition, format) {
2605 if (condition) {
2606 return;
2607 }
2608 var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame;
2609 var stack = ReactDebugCurrentFrame.getStackAddendum();
2610 // eslint-disable-next-line react-internal/warning-and-invariant-args
2611
2612 for (var _len = arguments.length, args = Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) {
2613 args[_key - 2] = arguments[_key];
2614 }
2615
2616 warningWithoutStack$1.apply(undefined, [false, format + '%s'].concat(args, [stack]));
2617 };
2618}
2619
2620var warning$1 = warning;
2621
2622// A reserved attribute.
2623// It is handled by React separately and shouldn't be written to the DOM.
2624var RESERVED = 0;
2625
2626// A simple string attribute.
2627// Attributes that aren't in the whitelist are presumed to have this type.
2628var STRING = 1;
2629
2630// A string attribute that accepts booleans in React. In HTML, these are called
2631// "enumerated" attributes with "true" and "false" as possible values.
2632// When true, it should be set to a "true" string.
2633// When false, it should be set to a "false" string.
2634var BOOLEANISH_STRING = 2;
2635
2636// A real boolean attribute.
2637// When true, it should be present (set either to an empty string or its name).
2638// When false, it should be omitted.
2639var BOOLEAN = 3;
2640
2641// An attribute that can be used as a flag as well as with a value.
2642// When true, it should be present (set either to an empty string or its name).
2643// When false, it should be omitted.
2644// For any other value, should be present with that value.
2645var OVERLOADED_BOOLEAN = 4;
2646
2647// An attribute that must be numeric or parse as a numeric.
2648// When falsy, it should be removed.
2649var NUMERIC = 5;
2650
2651// An attribute that must be positive numeric or parse as a positive numeric.
2652// When falsy, it should be removed.
2653var POSITIVE_NUMERIC = 6;
2654
2655/* eslint-disable max-len */
2656var ATTRIBUTE_NAME_START_CHAR = ':A-Z_a-z\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02FF\\u0370-\\u037D\\u037F-\\u1FFF\\u200C-\\u200D\\u2070-\\u218F\\u2C00-\\u2FEF\\u3001-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFFD';
2657/* eslint-enable max-len */
2658var ATTRIBUTE_NAME_CHAR = ATTRIBUTE_NAME_START_CHAR + '\\-.0-9\\u00B7\\u0300-\\u036F\\u203F-\\u2040';
2659
2660
2661var ROOT_ATTRIBUTE_NAME = 'data-reactroot';
2662var VALID_ATTRIBUTE_NAME_REGEX = new RegExp('^[' + ATTRIBUTE_NAME_START_CHAR + '][' + ATTRIBUTE_NAME_CHAR + ']*$');
2663
2664var hasOwnProperty = Object.prototype.hasOwnProperty;
2665var illegalAttributeNameCache = {};
2666var validatedAttributeNameCache = {};
2667
2668function isAttributeNameSafe(attributeName) {
2669 if (hasOwnProperty.call(validatedAttributeNameCache, attributeName)) {
2670 return true;
2671 }
2672 if (hasOwnProperty.call(illegalAttributeNameCache, attributeName)) {
2673 return false;
2674 }
2675 if (VALID_ATTRIBUTE_NAME_REGEX.test(attributeName)) {
2676 validatedAttributeNameCache[attributeName] = true;
2677 return true;
2678 }
2679 illegalAttributeNameCache[attributeName] = true;
2680 {
2681 warning$1(false, 'Invalid attribute name: `%s`', attributeName);
2682 }
2683 return false;
2684}
2685
2686function shouldIgnoreAttribute(name, propertyInfo, isCustomComponentTag) {
2687 if (propertyInfo !== null) {
2688 return propertyInfo.type === RESERVED;
2689 }
2690 if (isCustomComponentTag) {
2691 return false;
2692 }
2693 if (name.length > 2 && (name[0] === 'o' || name[0] === 'O') && (name[1] === 'n' || name[1] === 'N')) {
2694 return true;
2695 }
2696 return false;
2697}
2698
2699function shouldRemoveAttributeWithWarning(name, value, propertyInfo, isCustomComponentTag) {
2700 if (propertyInfo !== null && propertyInfo.type === RESERVED) {
2701 return false;
2702 }
2703 switch (typeof value) {
2704 case 'function':
2705 // $FlowIssue symbol is perfectly valid here
2706 case 'symbol':
2707 // eslint-disable-line
2708 return true;
2709 case 'boolean':
2710 {
2711 if (isCustomComponentTag) {
2712 return false;
2713 }
2714 if (propertyInfo !== null) {
2715 return !propertyInfo.acceptsBooleans;
2716 } else {
2717 var prefix = name.toLowerCase().slice(0, 5);
2718 return prefix !== 'data-' && prefix !== 'aria-';
2719 }
2720 }
2721 default:
2722 return false;
2723 }
2724}
2725
2726function shouldRemoveAttribute(name, value, propertyInfo, isCustomComponentTag) {
2727 if (value === null || typeof value === 'undefined') {
2728 return true;
2729 }
2730 if (shouldRemoveAttributeWithWarning(name, value, propertyInfo, isCustomComponentTag)) {
2731 return true;
2732 }
2733 if (isCustomComponentTag) {
2734 return false;
2735 }
2736 if (propertyInfo !== null) {
2737 switch (propertyInfo.type) {
2738 case BOOLEAN:
2739 return !value;
2740 case OVERLOADED_BOOLEAN:
2741 return value === false;
2742 case NUMERIC:
2743 return isNaN(value);
2744 case POSITIVE_NUMERIC:
2745 return isNaN(value) || value < 1;
2746 }
2747 }
2748 return false;
2749}
2750
2751function getPropertyInfo(name) {
2752 return properties.hasOwnProperty(name) ? properties[name] : null;
2753}
2754
2755function PropertyInfoRecord(name, type, mustUseProperty, attributeName, attributeNamespace) {
2756 this.acceptsBooleans = type === BOOLEANISH_STRING || type === BOOLEAN || type === OVERLOADED_BOOLEAN;
2757 this.attributeName = attributeName;
2758 this.attributeNamespace = attributeNamespace;
2759 this.mustUseProperty = mustUseProperty;
2760 this.propertyName = name;
2761 this.type = type;
2762}
2763
2764// When adding attributes to this list, be sure to also add them to
2765// the `possibleStandardNames` module to ensure casing and incorrect
2766// name warnings.
2767var properties = {};
2768
2769// These props are reserved by React. They shouldn't be written to the DOM.
2770['children', 'dangerouslySetInnerHTML',
2771// TODO: This prevents the assignment of defaultValue to regular
2772// elements (not just inputs). Now that ReactDOMInput assigns to the
2773// defaultValue property -- do we need this?
2774'defaultValue', 'defaultChecked', 'innerHTML', 'suppressContentEditableWarning', 'suppressHydrationWarning', 'style'].forEach(function (name) {
2775 properties[name] = new PropertyInfoRecord(name, RESERVED, false, // mustUseProperty
2776 name, // attributeName
2777 null);
2778} // attributeNamespace
2779);
2780
2781// A few React string attributes have a different name.
2782// This is a mapping from React prop names to the attribute names.
2783[['acceptCharset', 'accept-charset'], ['className', 'class'], ['htmlFor', 'for'], ['httpEquiv', 'http-equiv']].forEach(function (_ref) {
2784 var name = _ref[0],
2785 attributeName = _ref[1];
2786
2787 properties[name] = new PropertyInfoRecord(name, STRING, false, // mustUseProperty
2788 attributeName, // attributeName
2789 null);
2790} // attributeNamespace
2791);
2792
2793// These are "enumerated" HTML attributes that accept "true" and "false".
2794// In React, we let users pass `true` and `false` even though technically
2795// these aren't boolean attributes (they are coerced to strings).
2796['contentEditable', 'draggable', 'spellCheck', 'value'].forEach(function (name) {
2797 properties[name] = new PropertyInfoRecord(name, BOOLEANISH_STRING, false, // mustUseProperty
2798 name.toLowerCase(), // attributeName
2799 null);
2800} // attributeNamespace
2801);
2802
2803// These are "enumerated" SVG attributes that accept "true" and "false".
2804// In React, we let users pass `true` and `false` even though technically
2805// these aren't boolean attributes (they are coerced to strings).
2806// Since these are SVG attributes, their attribute names are case-sensitive.
2807['autoReverse', 'externalResourcesRequired', 'focusable', 'preserveAlpha'].forEach(function (name) {
2808 properties[name] = new PropertyInfoRecord(name, BOOLEANISH_STRING, false, // mustUseProperty
2809 name, // attributeName
2810 null);
2811} // attributeNamespace
2812);
2813
2814// These are HTML boolean attributes.
2815['allowFullScreen', 'async',
2816// Note: there is a special case that prevents it from being written to the DOM
2817// on the client side because the browsers are inconsistent. Instead we call focus().
2818'autoFocus', 'autoPlay', 'controls', 'default', 'defer', 'disabled', 'formNoValidate', 'hidden', 'loop', 'noModule', 'noValidate', 'open', 'playsInline', 'readOnly', 'required', 'reversed', 'scoped', 'seamless',
2819// Microdata
2820'itemScope'].forEach(function (name) {
2821 properties[name] = new PropertyInfoRecord(name, BOOLEAN, false, // mustUseProperty
2822 name.toLowerCase(), // attributeName
2823 null);
2824} // attributeNamespace
2825);
2826
2827// These are the few React props that we set as DOM properties
2828// rather than attributes. These are all booleans.
2829['checked',
2830// Note: `option.selected` is not updated if `select.multiple` is
2831// disabled with `removeAttribute`. We have special logic for handling this.
2832'multiple', 'muted', 'selected'].forEach(function (name) {
2833 properties[name] = new PropertyInfoRecord(name, BOOLEAN, true, // mustUseProperty
2834 name, // attributeName
2835 null);
2836} // attributeNamespace
2837);
2838
2839// These are HTML attributes that are "overloaded booleans": they behave like
2840// booleans, but can also accept a string value.
2841['capture', 'download'].forEach(function (name) {
2842 properties[name] = new PropertyInfoRecord(name, OVERLOADED_BOOLEAN, false, // mustUseProperty
2843 name, // attributeName
2844 null);
2845} // attributeNamespace
2846);
2847
2848// These are HTML attributes that must be positive numbers.
2849['cols', 'rows', 'size', 'span'].forEach(function (name) {
2850 properties[name] = new PropertyInfoRecord(name, POSITIVE_NUMERIC, false, // mustUseProperty
2851 name, // attributeName
2852 null);
2853} // attributeNamespace
2854);
2855
2856// These are HTML attributes that must be numbers.
2857['rowSpan', 'start'].forEach(function (name) {
2858 properties[name] = new PropertyInfoRecord(name, NUMERIC, false, // mustUseProperty
2859 name.toLowerCase(), // attributeName
2860 null);
2861} // attributeNamespace
2862);
2863
2864var CAMELIZE = /[\-\:]([a-z])/g;
2865var capitalize = function (token) {
2866 return token[1].toUpperCase();
2867};
2868
2869// This is a list of all SVG attributes that need special casing, namespacing,
2870// or boolean value assignment. Regular attributes that just accept strings
2871// and have the same names are omitted, just like in the HTML whitelist.
2872// Some of these attributes can be hard to find. This list was created by
2873// scrapping the MDN documentation.
2874['accent-height', 'alignment-baseline', 'arabic-form', 'baseline-shift', 'cap-height', 'clip-path', 'clip-rule', 'color-interpolation', 'color-interpolation-filters', 'color-profile', 'color-rendering', 'dominant-baseline', 'enable-background', 'fill-opacity', 'fill-rule', 'flood-color', 'flood-opacity', 'font-family', 'font-size', 'font-size-adjust', 'font-stretch', 'font-style', 'font-variant', 'font-weight', 'glyph-name', 'glyph-orientation-horizontal', 'glyph-orientation-vertical', 'horiz-adv-x', 'horiz-origin-x', 'image-rendering', 'letter-spacing', 'lighting-color', 'marker-end', 'marker-mid', 'marker-start', 'overline-position', 'overline-thickness', 'paint-order', 'panose-1', 'pointer-events', 'rendering-intent', 'shape-rendering', 'stop-color', 'stop-opacity', 'strikethrough-position', 'strikethrough-thickness', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke-width', 'text-anchor', 'text-decoration', 'text-rendering', 'underline-position', 'underline-thickness', 'unicode-bidi', 'unicode-range', 'units-per-em', 'v-alphabetic', 'v-hanging', 'v-ideographic', 'v-mathematical', 'vector-effect', 'vert-adv-y', 'vert-origin-x', 'vert-origin-y', 'word-spacing', 'writing-mode', 'xmlns:xlink', 'x-height'].forEach(function (attributeName) {
2875 var name = attributeName.replace(CAMELIZE, capitalize);
2876 properties[name] = new PropertyInfoRecord(name, STRING, false, // mustUseProperty
2877 attributeName, null);
2878} // attributeNamespace
2879);
2880
2881// String SVG attributes with the xlink namespace.
2882['xlink:actuate', 'xlink:arcrole', 'xlink:href', 'xlink:role', 'xlink:show', 'xlink:title', 'xlink:type'].forEach(function (attributeName) {
2883 var name = attributeName.replace(CAMELIZE, capitalize);
2884 properties[name] = new PropertyInfoRecord(name, STRING, false, // mustUseProperty
2885 attributeName, 'http://www.w3.org/1999/xlink');
2886});
2887
2888// String SVG attributes with the xml namespace.
2889['xml:base', 'xml:lang', 'xml:space'].forEach(function (attributeName) {
2890 var name = attributeName.replace(CAMELIZE, capitalize);
2891 properties[name] = new PropertyInfoRecord(name, STRING, false, // mustUseProperty
2892 attributeName, 'http://www.w3.org/XML/1998/namespace');
2893});
2894
2895// Special case: this attribute exists both in HTML and SVG.
2896// Its "tabindex" attribute name is case-sensitive in SVG so we can't just use
2897// its React `tabIndex` name, like we do for attributes that exist only in HTML.
2898properties.tabIndex = new PropertyInfoRecord('tabIndex', STRING, false, // mustUseProperty
2899'tabindex', // attributeName
2900null);
2901
2902/**
2903 * Get the value for a property on a node. Only used in DEV for SSR validation.
2904 * The "expected" argument is used as a hint of what the expected value is.
2905 * Some properties have multiple equivalent values.
2906 */
2907function getValueForProperty(node, name, expected, propertyInfo) {
2908 {
2909 if (propertyInfo.mustUseProperty) {
2910 var propertyName = propertyInfo.propertyName;
2911
2912 return node[propertyName];
2913 } else {
2914 var attributeName = propertyInfo.attributeName;
2915
2916 var stringValue = null;
2917
2918 if (propertyInfo.type === OVERLOADED_BOOLEAN) {
2919 if (node.hasAttribute(attributeName)) {
2920 var value = node.getAttribute(attributeName);
2921 if (value === '') {
2922 return true;
2923 }
2924 if (shouldRemoveAttribute(name, expected, propertyInfo, false)) {
2925 return value;
2926 }
2927 if (value === '' + expected) {
2928 return expected;
2929 }
2930 return value;
2931 }
2932 } else if (node.hasAttribute(attributeName)) {
2933 if (shouldRemoveAttribute(name, expected, propertyInfo, false)) {
2934 // We had an attribute but shouldn't have had one, so read it
2935 // for the error message.
2936 return node.getAttribute(attributeName);
2937 }
2938 if (propertyInfo.type === BOOLEAN) {
2939 // If this was a boolean, it doesn't matter what the value is
2940 // the fact that we have it is the same as the expected.
2941 return expected;
2942 }
2943 // Even if this property uses a namespace we use getAttribute
2944 // because we assume its namespaced name is the same as our config.
2945 // To use getAttributeNS we need the local name which we don't have
2946 // in our config atm.
2947 stringValue = node.getAttribute(attributeName);
2948 }
2949
2950 if (shouldRemoveAttribute(name, expected, propertyInfo, false)) {
2951 return stringValue === null ? expected : stringValue;
2952 } else if (stringValue === '' + expected) {
2953 return expected;
2954 } else {
2955 return stringValue;
2956 }
2957 }
2958 }
2959}
2960
2961/**
2962 * Get the value for a attribute on a node. Only used in DEV for SSR validation.
2963 * The third argument is used as a hint of what the expected value is. Some
2964 * attributes have multiple equivalent values.
2965 */
2966function getValueForAttribute(node, name, expected) {
2967 {
2968 if (!isAttributeNameSafe(name)) {
2969 return;
2970 }
2971 if (!node.hasAttribute(name)) {
2972 return expected === undefined ? undefined : null;
2973 }
2974 var value = node.getAttribute(name);
2975 if (value === '' + expected) {
2976 return expected;
2977 }
2978 return value;
2979 }
2980}
2981
2982/**
2983 * Sets the value for a property on a node.
2984 *
2985 * @param {DOMElement} node
2986 * @param {string} name
2987 * @param {*} value
2988 */
2989function setValueForProperty(node, name, value, isCustomComponentTag) {
2990 var propertyInfo = getPropertyInfo(name);
2991 if (shouldIgnoreAttribute(name, propertyInfo, isCustomComponentTag)) {
2992 return;
2993 }
2994 if (shouldRemoveAttribute(name, value, propertyInfo, isCustomComponentTag)) {
2995 value = null;
2996 }
2997 // If the prop isn't in the special list, treat it as a simple attribute.
2998 if (isCustomComponentTag || propertyInfo === null) {
2999 if (isAttributeNameSafe(name)) {
3000 var _attributeName = name;
3001 if (value === null) {
3002 node.removeAttribute(_attributeName);
3003 } else {
3004 node.setAttribute(_attributeName, '' + value);
3005 }
3006 }
3007 return;
3008 }
3009 var mustUseProperty = propertyInfo.mustUseProperty;
3010
3011 if (mustUseProperty) {
3012 var propertyName = propertyInfo.propertyName;
3013
3014 if (value === null) {
3015 var type = propertyInfo.type;
3016
3017 node[propertyName] = type === BOOLEAN ? false : '';
3018 } else {
3019 // Contrary to `setAttribute`, object properties are properly
3020 // `toString`ed by IE8/9.
3021 node[propertyName] = value;
3022 }
3023 return;
3024 }
3025 // The rest are treated as attributes with special cases.
3026 var attributeName = propertyInfo.attributeName,
3027 attributeNamespace = propertyInfo.attributeNamespace;
3028
3029 if (value === null) {
3030 node.removeAttribute(attributeName);
3031 } else {
3032 var _type = propertyInfo.type;
3033
3034 var attributeValue = void 0;
3035 if (_type === BOOLEAN || _type === OVERLOADED_BOOLEAN && value === true) {
3036 attributeValue = '';
3037 } else {
3038 // `setAttribute` with objects becomes only `[object]` in IE8/9,
3039 // ('' + value) makes it output the correct toString()-value.
3040 attributeValue = '' + value;
3041 }
3042 if (attributeNamespace) {
3043 node.setAttributeNS(attributeNamespace, attributeName, attributeValue);
3044 } else {
3045 node.setAttribute(attributeName, attributeValue);
3046 }
3047 }
3048}
3049
3050// Flow does not allow string concatenation of most non-string types. To work
3051// around this limitation, we use an opaque type that can only be obtained by
3052// passing the value through getToStringValue first.
3053function toString(value) {
3054 return '' + value;
3055}
3056
3057function getToStringValue(value) {
3058 switch (typeof value) {
3059 case 'boolean':
3060 case 'number':
3061 case 'object':
3062 case 'string':
3063 case 'undefined':
3064 return value;
3065 default:
3066 // function, symbol are assigned as empty strings
3067 return '';
3068 }
3069}
3070
3071/**
3072 * Copyright (c) 2013-present, Facebook, Inc.
3073 *
3074 * This source code is licensed under the MIT license found in the
3075 * LICENSE file in the root directory of this source tree.
3076 */
3077
3078
3079
3080var ReactPropTypesSecret$1 = 'SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED';
3081
3082var ReactPropTypesSecret_1 = ReactPropTypesSecret$1;
3083
3084/**
3085 * Copyright (c) 2013-present, Facebook, Inc.
3086 *
3087 * This source code is licensed under the MIT license found in the
3088 * LICENSE file in the root directory of this source tree.
3089 */
3090
3091
3092
3093var printWarning = function() {};
3094
3095{
3096 var ReactPropTypesSecret = ReactPropTypesSecret_1;
3097 var loggedTypeFailures = {};
3098
3099 printWarning = function(text) {
3100 var message = 'Warning: ' + text;
3101 if (typeof console !== 'undefined') {
3102 console.error(message);
3103 }
3104 try {
3105 // --- Welcome to debugging React ---
3106 // This error was thrown as a convenience so that you can use this stack
3107 // to find the callsite that caused this warning to fire.
3108 throw new Error(message);
3109 } catch (x) {}
3110 };
3111}
3112
3113/**
3114 * Assert that the values match with the type specs.
3115 * Error messages are memorized and will only be shown once.
3116 *
3117 * @param {object} typeSpecs Map of name to a ReactPropType
3118 * @param {object} values Runtime values that need to be type-checked
3119 * @param {string} location e.g. "prop", "context", "child context"
3120 * @param {string} componentName Name of the component for error messages.
3121 * @param {?Function} getStack Returns the component stack.
3122 * @private
3123 */
3124function checkPropTypes(typeSpecs, values, location, componentName, getStack) {
3125 {
3126 for (var typeSpecName in typeSpecs) {
3127 if (typeSpecs.hasOwnProperty(typeSpecName)) {
3128 var error;
3129 // Prop type validation may throw. In case they do, we don't want to
3130 // fail the render phase where it didn't fail before. So we log it.
3131 // After these have been cleaned up, we'll let them throw.
3132 try {
3133 // This is intentionally an invariant that gets caught. It's the same
3134 // behavior as without this statement except with a better message.
3135 if (typeof typeSpecs[typeSpecName] !== 'function') {
3136 var err = Error(
3137 (componentName || 'React class') + ': ' + location + ' type `' + typeSpecName + '` is invalid; ' +
3138 'it must be a function, usually from the `prop-types` package, but received `' + typeof typeSpecs[typeSpecName] + '`.'
3139 );
3140 err.name = 'Invariant Violation';
3141 throw err;
3142 }
3143 error = typeSpecs[typeSpecName](values, typeSpecName, componentName, location, null, ReactPropTypesSecret);
3144 } catch (ex) {
3145 error = ex;
3146 }
3147 if (error && !(error instanceof Error)) {
3148 printWarning(
3149 (componentName || 'React class') + ': type specification of ' +
3150 location + ' `' + typeSpecName + '` is invalid; the type checker ' +
3151 'function must return `null` or an `Error` but returned a ' + typeof error + '. ' +
3152 'You may have forgotten to pass an argument to the type checker ' +
3153 'creator (arrayOf, instanceOf, objectOf, oneOf, oneOfType, and ' +
3154 'shape all require an argument).'
3155 );
3156
3157 }
3158 if (error instanceof Error && !(error.message in loggedTypeFailures)) {
3159 // Only monitor this failure once because there tends to be a lot of the
3160 // same error.
3161 loggedTypeFailures[error.message] = true;
3162
3163 var stack = getStack ? getStack() : '';
3164
3165 printWarning(
3166 'Failed ' + location + ' type: ' + error.message + (stack != null ? stack : '')
3167 );
3168 }
3169 }
3170 }
3171 }
3172}
3173
3174var checkPropTypes_1 = checkPropTypes;
3175
3176var ReactDebugCurrentFrame$1 = null;
3177
3178var ReactControlledValuePropTypes = {
3179 checkPropTypes: null
3180};
3181
3182{
3183 ReactDebugCurrentFrame$1 = ReactSharedInternals.ReactDebugCurrentFrame;
3184
3185 var hasReadOnlyValue = {
3186 button: true,
3187 checkbox: true,
3188 image: true,
3189 hidden: true,
3190 radio: true,
3191 reset: true,
3192 submit: true
3193 };
3194
3195 var propTypes = {
3196 value: function (props, propName, componentName) {
3197 if (hasReadOnlyValue[props.type] || props.onChange || props.readOnly || props.disabled || props[propName] == null) {
3198 return null;
3199 }
3200 return new Error('You provided a `value` prop to a form field without an ' + '`onChange` handler. This will render a read-only field. If ' + 'the field should be mutable use `defaultValue`. Otherwise, ' + 'set either `onChange` or `readOnly`.');
3201 },
3202 checked: function (props, propName, componentName) {
3203 if (props.onChange || props.readOnly || props.disabled || props[propName] == null) {
3204 return null;
3205 }
3206 return new Error('You provided a `checked` prop to a form field without an ' + '`onChange` handler. This will render a read-only field. If ' + 'the field should be mutable use `defaultChecked`. Otherwise, ' + 'set either `onChange` or `readOnly`.');
3207 }
3208 };
3209
3210 /**
3211 * Provide a linked `value` attribute for controlled forms. You should not use
3212 * this outside of the ReactDOM controlled form components.
3213 */
3214 ReactControlledValuePropTypes.checkPropTypes = function (tagName, props) {
3215 checkPropTypes_1(propTypes, props, 'prop', tagName, ReactDebugCurrentFrame$1.getStackAddendum);
3216 };
3217}
3218
3219var enableUserTimingAPI = true;
3220
3221var enableHooks = false;
3222// Helps identify side effects in begin-phase lifecycle hooks and setState reducers:
3223var debugRenderPhaseSideEffects = false;
3224
3225// In some cases, StrictMode should also double-render lifecycles.
3226// This can be confusing for tests though,
3227// And it can be bad for performance in production.
3228// This feature flag can be used to control the behavior:
3229var debugRenderPhaseSideEffectsForStrictMode = true;
3230
3231// To preserve the "Pause on caught exceptions" behavior of the debugger, we
3232// replay the begin phase of a failed component inside invokeGuardedCallback.
3233var replayFailedUnitOfWorkWithInvokeGuardedCallback = true;
3234
3235// Warn about deprecated, async-unsafe lifecycles; relates to RFC #6:
3236var warnAboutDeprecatedLifecycles = false;
3237
3238// Gather advanced timing metrics for Profiler subtrees.
3239var enableProfilerTimer = true;
3240
3241// Trace which interactions trigger each commit.
3242var enableSchedulerTracing = true;
3243
3244// Only used in www builds.
3245 // TODO: true? Here it might just be false.
3246
3247// Only used in www builds.
3248
3249
3250// Only used in www builds.
3251
3252
3253// React Fire: prevent the value and checked attributes from syncing
3254// with their related DOM properties
3255var disableInputAttributeSyncing = false;
3256
3257// These APIs will no longer be "unstable" in the upcoming 16.7 release,
3258// Control this behavior with a flag to support 16.6 minor releases in the meanwhile.
3259var enableStableConcurrentModeAPIs = false;
3260
3261var warnAboutShorthandPropertyCollision = false;
3262
3263// TODO: direct imports like some-package/src/* are bad. Fix me.
3264var didWarnValueDefaultValue = false;
3265var didWarnCheckedDefaultChecked = false;
3266var didWarnControlledToUncontrolled = false;
3267var didWarnUncontrolledToControlled = false;
3268
3269function isControlled(props) {
3270 var usesChecked = props.type === 'checkbox' || props.type === 'radio';
3271 return usesChecked ? props.checked != null : props.value != null;
3272}
3273
3274/**
3275 * Implements an <input> host component that allows setting these optional
3276 * props: `checked`, `value`, `defaultChecked`, and `defaultValue`.
3277 *
3278 * If `checked` or `value` are not supplied (or null/undefined), user actions
3279 * that affect the checked state or value will trigger updates to the element.
3280 *
3281 * If they are supplied (and not null/undefined), the rendered element will not
3282 * trigger updates to the element. Instead, the props must change in order for
3283 * the rendered element to be updated.
3284 *
3285 * The rendered element will be initialized as unchecked (or `defaultChecked`)
3286 * with an empty value (or `defaultValue`).
3287 *
3288 * See http://www.w3.org/TR/2012/WD-html5-20121025/the-input-element.html
3289 */
3290
3291function getHostProps(element, props) {
3292 var node = element;
3293 var checked = props.checked;
3294
3295 var hostProps = _assign({}, props, {
3296 defaultChecked: undefined,
3297 defaultValue: undefined,
3298 value: undefined,
3299 checked: checked != null ? checked : node._wrapperState.initialChecked
3300 });
3301
3302 return hostProps;
3303}
3304
3305function initWrapperState(element, props) {
3306 {
3307 ReactControlledValuePropTypes.checkPropTypes('input', props);
3308
3309 if (props.checked !== undefined && props.defaultChecked !== undefined && !didWarnCheckedDefaultChecked) {
3310 warning$1(false, '%s contains an input of type %s with both checked and defaultChecked props. ' + 'Input elements must be either controlled or uncontrolled ' + '(specify either the checked prop, or the defaultChecked prop, but not ' + 'both). Decide between using a controlled or uncontrolled input ' + 'element and remove one of these props. More info: ' + 'https://fb.me/react-controlled-components', getCurrentFiberOwnerNameInDevOrNull() || 'A component', props.type);
3311 didWarnCheckedDefaultChecked = true;
3312 }
3313 if (props.value !== undefined && props.defaultValue !== undefined && !didWarnValueDefaultValue) {
3314 warning$1(false, '%s contains an input of type %s with both value and defaultValue props. ' + 'Input elements must be either controlled or uncontrolled ' + '(specify either the value prop, or the defaultValue prop, but not ' + 'both). Decide between using a controlled or uncontrolled input ' + 'element and remove one of these props. More info: ' + 'https://fb.me/react-controlled-components', getCurrentFiberOwnerNameInDevOrNull() || 'A component', props.type);
3315 didWarnValueDefaultValue = true;
3316 }
3317 }
3318
3319 var node = element;
3320 var defaultValue = props.defaultValue == null ? '' : props.defaultValue;
3321
3322 node._wrapperState = {
3323 initialChecked: props.checked != null ? props.checked : props.defaultChecked,
3324 initialValue: getToStringValue(props.value != null ? props.value : defaultValue),
3325 controlled: isControlled(props)
3326 };
3327}
3328
3329function updateChecked(element, props) {
3330 var node = element;
3331 var checked = props.checked;
3332 if (checked != null) {
3333 setValueForProperty(node, 'checked', checked, false);
3334 }
3335}
3336
3337function updateWrapper(element, props) {
3338 var node = element;
3339 {
3340 var _controlled = isControlled(props);
3341
3342 if (!node._wrapperState.controlled && _controlled && !didWarnUncontrolledToControlled) {
3343 warning$1(false, 'A component is changing an uncontrolled input of type %s to be controlled. ' + 'Input elements should not switch from uncontrolled to controlled (or vice versa). ' + 'Decide between using a controlled or uncontrolled input ' + 'element for the lifetime of the component. More info: https://fb.me/react-controlled-components', props.type);
3344 didWarnUncontrolledToControlled = true;
3345 }
3346 if (node._wrapperState.controlled && !_controlled && !didWarnControlledToUncontrolled) {
3347 warning$1(false, 'A component is changing a controlled input of type %s to be uncontrolled. ' + 'Input elements should not switch from controlled to uncontrolled (or vice versa). ' + 'Decide between using a controlled or uncontrolled input ' + 'element for the lifetime of the component. More info: https://fb.me/react-controlled-components', props.type);
3348 didWarnControlledToUncontrolled = true;
3349 }
3350 }
3351
3352 updateChecked(element, props);
3353
3354 var value = getToStringValue(props.value);
3355 var type = props.type;
3356
3357 if (value != null) {
3358 if (type === 'number') {
3359 if (value === 0 && node.value === '' ||
3360 // We explicitly want to coerce to number here if possible.
3361 // eslint-disable-next-line
3362 node.value != value) {
3363 node.value = toString(value);
3364 }
3365 } else if (node.value !== toString(value)) {
3366 node.value = toString(value);
3367 }
3368 } else if (type === 'submit' || type === 'reset') {
3369 // Submit/reset inputs need the attribute removed completely to avoid
3370 // blank-text buttons.
3371 node.removeAttribute('value');
3372 return;
3373 }
3374
3375 if (disableInputAttributeSyncing) {
3376 // When not syncing the value attribute, React only assigns a new value
3377 // whenever the defaultValue React prop has changed. When not present,
3378 // React does nothing
3379 if (props.hasOwnProperty('defaultValue')) {
3380 setDefaultValue(node, props.type, getToStringValue(props.defaultValue));
3381 }
3382 } else {
3383 // When syncing the value attribute, the value comes from a cascade of
3384 // properties:
3385 // 1. The value React property
3386 // 2. The defaultValue React property
3387 // 3. Otherwise there should be no change
3388 if (props.hasOwnProperty('value')) {
3389 setDefaultValue(node, props.type, value);
3390 } else if (props.hasOwnProperty('defaultValue')) {
3391 setDefaultValue(node, props.type, getToStringValue(props.defaultValue));
3392 }
3393 }
3394
3395 if (disableInputAttributeSyncing) {
3396 // When not syncing the checked attribute, the attribute is directly
3397 // controllable from the defaultValue React property. It needs to be
3398 // updated as new props come in.
3399 if (props.defaultChecked == null) {
3400 node.removeAttribute('checked');
3401 } else {
3402 node.defaultChecked = !!props.defaultChecked;
3403 }
3404 } else {
3405 // When syncing the checked attribute, it only changes when it needs
3406 // to be removed, such as transitioning from a checkbox into a text input
3407 if (props.checked == null && props.defaultChecked != null) {
3408 node.defaultChecked = !!props.defaultChecked;
3409 }
3410 }
3411}
3412
3413function postMountWrapper(element, props, isHydrating) {
3414 var node = element;
3415
3416 // Do not assign value if it is already set. This prevents user text input
3417 // from being lost during SSR hydration.
3418 if (props.hasOwnProperty('value') || props.hasOwnProperty('defaultValue')) {
3419 var type = props.type;
3420 var isButton = type === 'submit' || type === 'reset';
3421
3422 // Avoid setting value attribute on submit/reset inputs as it overrides the
3423 // default value provided by the browser. See: #12872
3424 if (isButton && (props.value === undefined || props.value === null)) {
3425 return;
3426 }
3427
3428 var _initialValue = toString(node._wrapperState.initialValue);
3429
3430 // Do not assign value if it is already set. This prevents user text input
3431 // from being lost during SSR hydration.
3432 if (!isHydrating) {
3433 if (disableInputAttributeSyncing) {
3434 var value = getToStringValue(props.value);
3435
3436 // When not syncing the value attribute, the value property points
3437 // directly to the React prop. Only assign it if it exists.
3438 if (value != null) {
3439 // Always assign on buttons so that it is possible to assign an
3440 // empty string to clear button text.
3441 //
3442 // Otherwise, do not re-assign the value property if is empty. This
3443 // potentially avoids a DOM write and prevents Firefox (~60.0.1) from
3444 // prematurely marking required inputs as invalid. Equality is compared
3445 // to the current value in case the browser provided value is not an
3446 // empty string.
3447 if (isButton || value !== node.value) {
3448 node.value = toString(value);
3449 }
3450 }
3451 } else {
3452 // When syncing the value attribute, the value property should use
3453 // the wrapperState._initialValue property. This uses:
3454 //
3455 // 1. The value React property when present
3456 // 2. The defaultValue React property when present
3457 // 3. An empty string
3458 if (_initialValue !== node.value) {
3459 node.value = _initialValue;
3460 }
3461 }
3462 }
3463
3464 if (disableInputAttributeSyncing) {
3465 // When not syncing the value attribute, assign the value attribute
3466 // directly from the defaultValue React property (when present)
3467 var defaultValue = getToStringValue(props.defaultValue);
3468 if (defaultValue != null) {
3469 node.defaultValue = toString(defaultValue);
3470 }
3471 } else {
3472 // Otherwise, the value attribute is synchronized to the property,
3473 // so we assign defaultValue to the same thing as the value property
3474 // assignment step above.
3475 node.defaultValue = _initialValue;
3476 }
3477 }
3478
3479 // Normally, we'd just do `node.checked = node.checked` upon initial mount, less this bug
3480 // this is needed to work around a chrome bug where setting defaultChecked
3481 // will sometimes influence the value of checked (even after detachment).
3482 // Reference: https://bugs.chromium.org/p/chromium/issues/detail?id=608416
3483 // We need to temporarily unset name to avoid disrupting radio button groups.
3484 var name = node.name;
3485 if (name !== '') {
3486 node.name = '';
3487 }
3488
3489 if (disableInputAttributeSyncing) {
3490 // When not syncing the checked attribute, the checked property
3491 // never gets assigned. It must be manually set. We don't want
3492 // to do this when hydrating so that existing user input isn't
3493 // modified
3494 if (!isHydrating) {
3495 updateChecked(element, props);
3496 }
3497
3498 // Only assign the checked attribute if it is defined. This saves
3499 // a DOM write when controlling the checked attribute isn't needed
3500 // (text inputs, submit/reset)
3501 if (props.hasOwnProperty('defaultChecked')) {
3502 node.defaultChecked = !node.defaultChecked;
3503 node.defaultChecked = !!props.defaultChecked;
3504 }
3505 } else {
3506 // When syncing the checked attribute, both the checked property and
3507 // attribute are assigned at the same time using defaultChecked. This uses:
3508 //
3509 // 1. The checked React property when present
3510 // 2. The defaultChecked React property when present
3511 // 3. Otherwise, false
3512 node.defaultChecked = !node.defaultChecked;
3513 node.defaultChecked = !!node._wrapperState.initialChecked;
3514 }
3515
3516 if (name !== '') {
3517 node.name = name;
3518 }
3519}
3520
3521function restoreControlledState(element, props) {
3522 var node = element;
3523 updateWrapper(node, props);
3524 updateNamedCousins(node, props);
3525}
3526
3527function updateNamedCousins(rootNode, props) {
3528 var name = props.name;
3529 if (props.type === 'radio' && name != null) {
3530 var queryRoot = rootNode;
3531
3532 while (queryRoot.parentNode) {
3533 queryRoot = queryRoot.parentNode;
3534 }
3535
3536 // If `rootNode.form` was non-null, then we could try `form.elements`,
3537 // but that sometimes behaves strangely in IE8. We could also try using
3538 // `form.getElementsByName`, but that will only return direct children
3539 // and won't include inputs that use the HTML5 `form=` attribute. Since
3540 // the input might not even be in a form. It might not even be in the
3541 // document. Let's just use the local `querySelectorAll` to ensure we don't
3542 // miss anything.
3543 var group = queryRoot.querySelectorAll('input[name=' + JSON.stringify('' + name) + '][type="radio"]');
3544
3545 for (var i = 0; i < group.length; i++) {
3546 var otherNode = group[i];
3547 if (otherNode === rootNode || otherNode.form !== rootNode.form) {
3548 continue;
3549 }
3550 // This will throw if radio buttons rendered by different copies of React
3551 // and the same name are rendered into the same form (same as #1939).
3552 // That's probably okay; we don't support it just as we don't support
3553 // mixing React radio buttons with non-React ones.
3554 var otherProps = getFiberCurrentPropsFromNode$1(otherNode);
3555 !otherProps ? invariant(false, 'ReactDOMInput: Mixing React and non-React radio inputs with the same `name` is not supported.') : void 0;
3556
3557 // We need update the tracked value on the named cousin since the value
3558 // was changed but the input saw no event or value set
3559 updateValueIfChanged(otherNode);
3560
3561 // If this is a controlled radio button group, forcing the input that
3562 // was previously checked to update will cause it to be come re-checked
3563 // as appropriate.
3564 updateWrapper(otherNode, otherProps);
3565 }
3566 }
3567}
3568
3569// In Chrome, assigning defaultValue to certain input types triggers input validation.
3570// For number inputs, the display value loses trailing decimal points. For email inputs,
3571// Chrome raises "The specified value <x> is not a valid email address".
3572//
3573// Here we check to see if the defaultValue has actually changed, avoiding these problems
3574// when the user is inputting text
3575//
3576// https://github.com/facebook/react/issues/7253
3577function setDefaultValue(node, type, value) {
3578 if (
3579 // Focused number inputs synchronize on blur. See ChangeEventPlugin.js
3580 type !== 'number' || node.ownerDocument.activeElement !== node) {
3581 if (value == null) {
3582 node.defaultValue = toString(node._wrapperState.initialValue);
3583 } else if (node.defaultValue !== toString(value)) {
3584 node.defaultValue = toString(value);
3585 }
3586 }
3587}
3588
3589var eventTypes$1 = {
3590 change: {
3591 phasedRegistrationNames: {
3592 bubbled: 'onChange',
3593 captured: 'onChangeCapture'
3594 },
3595 dependencies: [TOP_BLUR, TOP_CHANGE, TOP_CLICK, TOP_FOCUS, TOP_INPUT, TOP_KEY_DOWN, TOP_KEY_UP, TOP_SELECTION_CHANGE]
3596 }
3597};
3598
3599function createAndAccumulateChangeEvent(inst, nativeEvent, target) {
3600 var event = SyntheticEvent.getPooled(eventTypes$1.change, inst, nativeEvent, target);
3601 event.type = 'change';
3602 // Flag this event loop as needing state restore.
3603 enqueueStateRestore(target);
3604 accumulateTwoPhaseDispatches(event);
3605 return event;
3606}
3607/**
3608 * For IE shims
3609 */
3610var activeElement = null;
3611var activeElementInst = null;
3612
3613/**
3614 * SECTION: handle `change` event
3615 */
3616function shouldUseChangeEvent(elem) {
3617 var nodeName = elem.nodeName && elem.nodeName.toLowerCase();
3618 return nodeName === 'select' || nodeName === 'input' && elem.type === 'file';
3619}
3620
3621function manualDispatchChangeEvent(nativeEvent) {
3622 var event = createAndAccumulateChangeEvent(activeElementInst, nativeEvent, getEventTarget(nativeEvent));
3623
3624 // If change and propertychange bubbled, we'd just bind to it like all the
3625 // other events and have it go through ReactBrowserEventEmitter. Since it
3626 // doesn't, we manually listen for the events and so we have to enqueue and
3627 // process the abstract event manually.
3628 //
3629 // Batching is necessary here in order to ensure that all event handlers run
3630 // before the next rerender (including event handlers attached to ancestor
3631 // elements instead of directly on the input). Without this, controlled
3632 // components don't work properly in conjunction with event bubbling because
3633 // the component is rerendered and the value reverted before all the event
3634 // handlers can run. See https://github.com/facebook/react/issues/708.
3635 batchedUpdates(runEventInBatch, event);
3636}
3637
3638function runEventInBatch(event) {
3639 runEventsInBatch(event);
3640}
3641
3642function getInstIfValueChanged(targetInst) {
3643 var targetNode = getNodeFromInstance$1(targetInst);
3644 if (updateValueIfChanged(targetNode)) {
3645 return targetInst;
3646 }
3647}
3648
3649function getTargetInstForChangeEvent(topLevelType, targetInst) {
3650 if (topLevelType === TOP_CHANGE) {
3651 return targetInst;
3652 }
3653}
3654
3655/**
3656 * SECTION: handle `input` event
3657 */
3658var isInputEventSupported = false;
3659if (canUseDOM) {
3660 // IE9 claims to support the input event but fails to trigger it when
3661 // deleting text, so we ignore its input events.
3662 isInputEventSupported = isEventSupported('input') && (!document.documentMode || document.documentMode > 9);
3663}
3664
3665/**
3666 * (For IE <=9) Starts tracking propertychange events on the passed-in element
3667 * and override the value property so that we can distinguish user events from
3668 * value changes in JS.
3669 */
3670function startWatchingForValueChange(target, targetInst) {
3671 activeElement = target;
3672 activeElementInst = targetInst;
3673 activeElement.attachEvent('onpropertychange', handlePropertyChange);
3674}
3675
3676/**
3677 * (For IE <=9) Removes the event listeners from the currently-tracked element,
3678 * if any exists.
3679 */
3680function stopWatchingForValueChange() {
3681 if (!activeElement) {
3682 return;
3683 }
3684 activeElement.detachEvent('onpropertychange', handlePropertyChange);
3685 activeElement = null;
3686 activeElementInst = null;
3687}
3688
3689/**
3690 * (For IE <=9) Handles a propertychange event, sending a `change` event if
3691 * the value of the active element has changed.
3692 */
3693function handlePropertyChange(nativeEvent) {
3694 if (nativeEvent.propertyName !== 'value') {
3695 return;
3696 }
3697 if (getInstIfValueChanged(activeElementInst)) {
3698 manualDispatchChangeEvent(nativeEvent);
3699 }
3700}
3701
3702function handleEventsForInputEventPolyfill(topLevelType, target, targetInst) {
3703 if (topLevelType === TOP_FOCUS) {
3704 // In IE9, propertychange fires for most input events but is buggy and
3705 // doesn't fire when text is deleted, but conveniently, selectionchange
3706 // appears to fire in all of the remaining cases so we catch those and
3707 // forward the event if the value has changed
3708 // In either case, we don't want to call the event handler if the value
3709 // is changed from JS so we redefine a setter for `.value` that updates
3710 // our activeElementValue variable, allowing us to ignore those changes
3711 //
3712 // stopWatching() should be a noop here but we call it just in case we
3713 // missed a blur event somehow.
3714 stopWatchingForValueChange();
3715 startWatchingForValueChange(target, targetInst);
3716 } else if (topLevelType === TOP_BLUR) {
3717 stopWatchingForValueChange();
3718 }
3719}
3720
3721// For IE8 and IE9.
3722function getTargetInstForInputEventPolyfill(topLevelType, targetInst) {
3723 if (topLevelType === TOP_SELECTION_CHANGE || topLevelType === TOP_KEY_UP || topLevelType === TOP_KEY_DOWN) {
3724 // On the selectionchange event, the target is just document which isn't
3725 // helpful for us so just check activeElement instead.
3726 //
3727 // 99% of the time, keydown and keyup aren't necessary. IE8 fails to fire
3728 // propertychange on the first input event after setting `value` from a
3729 // script and fires only keydown, keypress, keyup. Catching keyup usually
3730 // gets it and catching keydown lets us fire an event for the first
3731 // keystroke if user does a key repeat (it'll be a little delayed: right
3732 // before the second keystroke). Other input methods (e.g., paste) seem to
3733 // fire selectionchange normally.
3734 return getInstIfValueChanged(activeElementInst);
3735 }
3736}
3737
3738/**
3739 * SECTION: handle `click` event
3740 */
3741function shouldUseClickEvent(elem) {
3742 // Use the `click` event to detect changes to checkbox and radio inputs.
3743 // This approach works across all browsers, whereas `change` does not fire
3744 // until `blur` in IE8.
3745 var nodeName = elem.nodeName;
3746 return nodeName && nodeName.toLowerCase() === 'input' && (elem.type === 'checkbox' || elem.type === 'radio');
3747}
3748
3749function getTargetInstForClickEvent(topLevelType, targetInst) {
3750 if (topLevelType === TOP_CLICK) {
3751 return getInstIfValueChanged(targetInst);
3752 }
3753}
3754
3755function getTargetInstForInputOrChangeEvent(topLevelType, targetInst) {
3756 if (topLevelType === TOP_INPUT || topLevelType === TOP_CHANGE) {
3757 return getInstIfValueChanged(targetInst);
3758 }
3759}
3760
3761function handleControlledInputBlur(node) {
3762 var state = node._wrapperState;
3763
3764 if (!state || !state.controlled || node.type !== 'number') {
3765 return;
3766 }
3767
3768 if (!disableInputAttributeSyncing) {
3769 // If controlled, assign the value attribute to the current value on blur
3770 setDefaultValue(node, 'number', node.value);
3771 }
3772}
3773
3774/**
3775 * This plugin creates an `onChange` event that normalizes change events
3776 * across form elements. This event fires at a time when it's possible to
3777 * change the element's value without seeing a flicker.
3778 *
3779 * Supported elements are:
3780 * - input (see `isTextInputElement`)
3781 * - textarea
3782 * - select
3783 */
3784var ChangeEventPlugin = {
3785 eventTypes: eventTypes$1,
3786
3787 _isInputEventSupported: isInputEventSupported,
3788
3789 extractEvents: function (topLevelType, targetInst, nativeEvent, nativeEventTarget) {
3790 var targetNode = targetInst ? getNodeFromInstance$1(targetInst) : window;
3791
3792 var getTargetInstFunc = void 0,
3793 handleEventFunc = void 0;
3794 if (shouldUseChangeEvent(targetNode)) {
3795 getTargetInstFunc = getTargetInstForChangeEvent;
3796 } else if (isTextInputElement(targetNode)) {
3797 if (isInputEventSupported) {
3798 getTargetInstFunc = getTargetInstForInputOrChangeEvent;
3799 } else {
3800 getTargetInstFunc = getTargetInstForInputEventPolyfill;
3801 handleEventFunc = handleEventsForInputEventPolyfill;
3802 }
3803 } else if (shouldUseClickEvent(targetNode)) {
3804 getTargetInstFunc = getTargetInstForClickEvent;
3805 }
3806
3807 if (getTargetInstFunc) {
3808 var inst = getTargetInstFunc(topLevelType, targetInst);
3809 if (inst) {
3810 var event = createAndAccumulateChangeEvent(inst, nativeEvent, nativeEventTarget);
3811 return event;
3812 }
3813 }
3814
3815 if (handleEventFunc) {
3816 handleEventFunc(topLevelType, targetNode, targetInst);
3817 }
3818
3819 // When blurring, set the value attribute for number inputs
3820 if (topLevelType === TOP_BLUR) {
3821 handleControlledInputBlur(targetNode);
3822 }
3823 }
3824};
3825
3826/**
3827 * Module that is injectable into `EventPluginHub`, that specifies a
3828 * deterministic ordering of `EventPlugin`s. A convenient way to reason about
3829 * plugins, without having to package every one of them. This is better than
3830 * having plugins be ordered in the same order that they are injected because
3831 * that ordering would be influenced by the packaging order.
3832 * `ResponderEventPlugin` must occur before `SimpleEventPlugin` so that
3833 * preventing default on events is convenient in `SimpleEventPlugin` handlers.
3834 */
3835var DOMEventPluginOrder = ['ResponderEventPlugin', 'SimpleEventPlugin', 'EnterLeaveEventPlugin', 'ChangeEventPlugin', 'SelectEventPlugin', 'BeforeInputEventPlugin'];
3836
3837var SyntheticUIEvent = SyntheticEvent.extend({
3838 view: null,
3839 detail: null
3840});
3841
3842var modifierKeyToProp = {
3843 Alt: 'altKey',
3844 Control: 'ctrlKey',
3845 Meta: 'metaKey',
3846 Shift: 'shiftKey'
3847};
3848
3849// Older browsers (Safari <= 10, iOS Safari <= 10.2) do not support
3850// getModifierState. If getModifierState is not supported, we map it to a set of
3851// modifier keys exposed by the event. In this case, Lock-keys are not supported.
3852/**
3853 * Translation from modifier key to the associated property in the event.
3854 * @see http://www.w3.org/TR/DOM-Level-3-Events/#keys-Modifiers
3855 */
3856
3857function modifierStateGetter(keyArg) {
3858 var syntheticEvent = this;
3859 var nativeEvent = syntheticEvent.nativeEvent;
3860 if (nativeEvent.getModifierState) {
3861 return nativeEvent.getModifierState(keyArg);
3862 }
3863 var keyProp = modifierKeyToProp[keyArg];
3864 return keyProp ? !!nativeEvent[keyProp] : false;
3865}
3866
3867function getEventModifierState(nativeEvent) {
3868 return modifierStateGetter;
3869}
3870
3871var previousScreenX = 0;
3872var previousScreenY = 0;
3873// Use flags to signal movementX/Y has already been set
3874var isMovementXSet = false;
3875var isMovementYSet = false;
3876
3877/**
3878 * @interface MouseEvent
3879 * @see http://www.w3.org/TR/DOM-Level-3-Events/
3880 */
3881var SyntheticMouseEvent = SyntheticUIEvent.extend({
3882 screenX: null,
3883 screenY: null,
3884 clientX: null,
3885 clientY: null,
3886 pageX: null,
3887 pageY: null,
3888 ctrlKey: null,
3889 shiftKey: null,
3890 altKey: null,
3891 metaKey: null,
3892 getModifierState: getEventModifierState,
3893 button: null,
3894 buttons: null,
3895 relatedTarget: function (event) {
3896 return event.relatedTarget || (event.fromElement === event.srcElement ? event.toElement : event.fromElement);
3897 },
3898 movementX: function (event) {
3899 if ('movementX' in event) {
3900 return event.movementX;
3901 }
3902
3903 var screenX = previousScreenX;
3904 previousScreenX = event.screenX;
3905
3906 if (!isMovementXSet) {
3907 isMovementXSet = true;
3908 return 0;
3909 }
3910
3911 return event.type === 'mousemove' ? event.screenX - screenX : 0;
3912 },
3913 movementY: function (event) {
3914 if ('movementY' in event) {
3915 return event.movementY;
3916 }
3917
3918 var screenY = previousScreenY;
3919 previousScreenY = event.screenY;
3920
3921 if (!isMovementYSet) {
3922 isMovementYSet = true;
3923 return 0;
3924 }
3925
3926 return event.type === 'mousemove' ? event.screenY - screenY : 0;
3927 }
3928});
3929
3930/**
3931 * @interface PointerEvent
3932 * @see http://www.w3.org/TR/pointerevents/
3933 */
3934var SyntheticPointerEvent = SyntheticMouseEvent.extend({
3935 pointerId: null,
3936 width: null,
3937 height: null,
3938 pressure: null,
3939 tangentialPressure: null,
3940 tiltX: null,
3941 tiltY: null,
3942 twist: null,
3943 pointerType: null,
3944 isPrimary: null
3945});
3946
3947var eventTypes$2 = {
3948 mouseEnter: {
3949 registrationName: 'onMouseEnter',
3950 dependencies: [TOP_MOUSE_OUT, TOP_MOUSE_OVER]
3951 },
3952 mouseLeave: {
3953 registrationName: 'onMouseLeave',
3954 dependencies: [TOP_MOUSE_OUT, TOP_MOUSE_OVER]
3955 },
3956 pointerEnter: {
3957 registrationName: 'onPointerEnter',
3958 dependencies: [TOP_POINTER_OUT, TOP_POINTER_OVER]
3959 },
3960 pointerLeave: {
3961 registrationName: 'onPointerLeave',
3962 dependencies: [TOP_POINTER_OUT, TOP_POINTER_OVER]
3963 }
3964};
3965
3966var EnterLeaveEventPlugin = {
3967 eventTypes: eventTypes$2,
3968
3969 /**
3970 * For almost every interaction we care about, there will be both a top-level
3971 * `mouseover` and `mouseout` event that occurs. Only use `mouseout` so that
3972 * we do not extract duplicate events. However, moving the mouse into the
3973 * browser from outside will not fire a `mouseout` event. In this case, we use
3974 * the `mouseover` top-level event.
3975 */
3976 extractEvents: function (topLevelType, targetInst, nativeEvent, nativeEventTarget) {
3977 var isOverEvent = topLevelType === TOP_MOUSE_OVER || topLevelType === TOP_POINTER_OVER;
3978 var isOutEvent = topLevelType === TOP_MOUSE_OUT || topLevelType === TOP_POINTER_OUT;
3979
3980 if (isOverEvent && (nativeEvent.relatedTarget || nativeEvent.fromElement)) {
3981 return null;
3982 }
3983
3984 if (!isOutEvent && !isOverEvent) {
3985 // Must not be a mouse or pointer in or out - ignoring.
3986 return null;
3987 }
3988
3989 var win = void 0;
3990 if (nativeEventTarget.window === nativeEventTarget) {
3991 // `nativeEventTarget` is probably a window object.
3992 win = nativeEventTarget;
3993 } else {
3994 // TODO: Figure out why `ownerDocument` is sometimes undefined in IE8.
3995 var doc = nativeEventTarget.ownerDocument;
3996 if (doc) {
3997 win = doc.defaultView || doc.parentWindow;
3998 } else {
3999 win = window;
4000 }
4001 }
4002
4003 var from = void 0;
4004 var to = void 0;
4005 if (isOutEvent) {
4006 from = targetInst;
4007 var related = nativeEvent.relatedTarget || nativeEvent.toElement;
4008 to = related ? getClosestInstanceFromNode(related) : null;
4009 } else {
4010 // Moving to a node from outside the window.
4011 from = null;
4012 to = targetInst;
4013 }
4014
4015 if (from === to) {
4016 // Nothing pertains to our managed components.
4017 return null;
4018 }
4019
4020 var eventInterface = void 0,
4021 leaveEventType = void 0,
4022 enterEventType = void 0,
4023 eventTypePrefix = void 0;
4024
4025 if (topLevelType === TOP_MOUSE_OUT || topLevelType === TOP_MOUSE_OVER) {
4026 eventInterface = SyntheticMouseEvent;
4027 leaveEventType = eventTypes$2.mouseLeave;
4028 enterEventType = eventTypes$2.mouseEnter;
4029 eventTypePrefix = 'mouse';
4030 } else if (topLevelType === TOP_POINTER_OUT || topLevelType === TOP_POINTER_OVER) {
4031 eventInterface = SyntheticPointerEvent;
4032 leaveEventType = eventTypes$2.pointerLeave;
4033 enterEventType = eventTypes$2.pointerEnter;
4034 eventTypePrefix = 'pointer';
4035 }
4036
4037 var fromNode = from == null ? win : getNodeFromInstance$1(from);
4038 var toNode = to == null ? win : getNodeFromInstance$1(to);
4039
4040 var leave = eventInterface.getPooled(leaveEventType, from, nativeEvent, nativeEventTarget);
4041 leave.type = eventTypePrefix + 'leave';
4042 leave.target = fromNode;
4043 leave.relatedTarget = toNode;
4044
4045 var enter = eventInterface.getPooled(enterEventType, to, nativeEvent, nativeEventTarget);
4046 enter.type = eventTypePrefix + 'enter';
4047 enter.target = toNode;
4048 enter.relatedTarget = fromNode;
4049
4050 accumulateEnterLeaveDispatches(leave, enter, from, to);
4051
4052 return [leave, enter];
4053 }
4054};
4055
4056/*eslint-disable no-self-compare */
4057
4058var hasOwnProperty$1 = Object.prototype.hasOwnProperty;
4059
4060/**
4061 * inlined Object.is polyfill to avoid requiring consumers ship their own
4062 * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is
4063 */
4064function is(x, y) {
4065 // SameValue algorithm
4066 if (x === y) {
4067 // Steps 1-5, 7-10
4068 // Steps 6.b-6.e: +0 != -0
4069 // Added the nonzero y check to make Flow happy, but it is redundant
4070 return x !== 0 || y !== 0 || 1 / x === 1 / y;
4071 } else {
4072 // Step 6.a: NaN == NaN
4073 return x !== x && y !== y;
4074 }
4075}
4076
4077/**
4078 * Performs equality by iterating through keys on an object and returning false
4079 * when any key has values which are not strictly equal between the arguments.
4080 * Returns true when the values of all keys are strictly equal.
4081 */
4082function shallowEqual(objA, objB) {
4083 if (is(objA, objB)) {
4084 return true;
4085 }
4086
4087 if (typeof objA !== 'object' || objA === null || typeof objB !== 'object' || objB === null) {
4088 return false;
4089 }
4090
4091 var keysA = Object.keys(objA);
4092 var keysB = Object.keys(objB);
4093
4094 if (keysA.length !== keysB.length) {
4095 return false;
4096 }
4097
4098 // Test for A's keys different from B.
4099 for (var i = 0; i < keysA.length; i++) {
4100 if (!hasOwnProperty$1.call(objB, keysA[i]) || !is(objA[keysA[i]], objB[keysA[i]])) {
4101 return false;
4102 }
4103 }
4104
4105 return true;
4106}
4107
4108/**
4109 * `ReactInstanceMap` maintains a mapping from a public facing stateful
4110 * instance (key) and the internal representation (value). This allows public
4111 * methods to accept the user facing instance as an argument and map them back
4112 * to internal methods.
4113 *
4114 * Note that this module is currently shared and assumed to be stateless.
4115 * If this becomes an actual Map, that will break.
4116 */
4117
4118/**
4119 * This API should be called `delete` but we'd have to make sure to always
4120 * transform these to strings for IE support. When this transform is fully
4121 * supported we can rename it.
4122 */
4123
4124
4125function get(key) {
4126 return key._reactInternalFiber;
4127}
4128
4129function has(key) {
4130 return key._reactInternalFiber !== undefined;
4131}
4132
4133function set(key, value) {
4134 key._reactInternalFiber = value;
4135}
4136
4137// Don't change these two values. They're used by React Dev Tools.
4138var NoEffect = /* */0;
4139var PerformedWork = /* */1;
4140
4141// You can change the rest (and add more).
4142var Placement = /* */2;
4143var Update = /* */4;
4144var PlacementAndUpdate = /* */6;
4145var Deletion = /* */8;
4146var ContentReset = /* */16;
4147var Callback = /* */32;
4148var DidCapture = /* */64;
4149var Ref = /* */128;
4150var Snapshot = /* */256;
4151var Passive = /* */512;
4152
4153// Passive & Update & Callback & Ref & Snapshot
4154var LifecycleEffectMask = /* */932;
4155
4156// Union of all host effects
4157var HostEffectMask = /* */1023;
4158
4159var Incomplete = /* */1024;
4160var ShouldCapture = /* */2048;
4161
4162var ReactCurrentOwner$1 = ReactSharedInternals.ReactCurrentOwner;
4163
4164var MOUNTING = 1;
4165var MOUNTED = 2;
4166var UNMOUNTED = 3;
4167
4168function isFiberMountedImpl(fiber) {
4169 var node = fiber;
4170 if (!fiber.alternate) {
4171 // If there is no alternate, this might be a new tree that isn't inserted
4172 // yet. If it is, then it will have a pending insertion effect on it.
4173 if ((node.effectTag & Placement) !== NoEffect) {
4174 return MOUNTING;
4175 }
4176 while (node.return) {
4177 node = node.return;
4178 if ((node.effectTag & Placement) !== NoEffect) {
4179 return MOUNTING;
4180 }
4181 }
4182 } else {
4183 while (node.return) {
4184 node = node.return;
4185 }
4186 }
4187 if (node.tag === HostRoot) {
4188 // TODO: Check if this was a nested HostRoot when used with
4189 // renderContainerIntoSubtree.
4190 return MOUNTED;
4191 }
4192 // If we didn't hit the root, that means that we're in an disconnected tree
4193 // that has been unmounted.
4194 return UNMOUNTED;
4195}
4196
4197function isFiberMounted(fiber) {
4198 return isFiberMountedImpl(fiber) === MOUNTED;
4199}
4200
4201function isMounted(component) {
4202 {
4203 var owner = ReactCurrentOwner$1.current;
4204 if (owner !== null && owner.tag === ClassComponent) {
4205 var ownerFiber = owner;
4206 var instance = ownerFiber.stateNode;
4207 !instance._warnedAboutRefsInRender ? warningWithoutStack$1(false, '%s is accessing isMounted inside its render() function. ' + 'render() should be a pure function of props and state. It should ' + 'never access something that requires stale data from the previous ' + 'render, such as refs. Move this logic to componentDidMount and ' + 'componentDidUpdate instead.', getComponentName(ownerFiber.type) || 'A component') : void 0;
4208 instance._warnedAboutRefsInRender = true;
4209 }
4210 }
4211
4212 var fiber = get(component);
4213 if (!fiber) {
4214 return false;
4215 }
4216 return isFiberMountedImpl(fiber) === MOUNTED;
4217}
4218
4219function assertIsMounted(fiber) {
4220 !(isFiberMountedImpl(fiber) === MOUNTED) ? invariant(false, 'Unable to find node on an unmounted component.') : void 0;
4221}
4222
4223function findCurrentFiberUsingSlowPath(fiber) {
4224 var alternate = fiber.alternate;
4225 if (!alternate) {
4226 // If there is no alternate, then we only need to check if it is mounted.
4227 var state = isFiberMountedImpl(fiber);
4228 !(state !== UNMOUNTED) ? invariant(false, 'Unable to find node on an unmounted component.') : void 0;
4229 if (state === MOUNTING) {
4230 return null;
4231 }
4232 return fiber;
4233 }
4234 // If we have two possible branches, we'll walk backwards up to the root
4235 // to see what path the root points to. On the way we may hit one of the
4236 // special cases and we'll deal with them.
4237 var a = fiber;
4238 var b = alternate;
4239 while (true) {
4240 var parentA = a.return;
4241 var parentB = parentA ? parentA.alternate : null;
4242 if (!parentA || !parentB) {
4243 // We're at the root.
4244 break;
4245 }
4246
4247 // If both copies of the parent fiber point to the same child, we can
4248 // assume that the child is current. This happens when we bailout on low
4249 // priority: the bailed out fiber's child reuses the current child.
4250 if (parentA.child === parentB.child) {
4251 var child = parentA.child;
4252 while (child) {
4253 if (child === a) {
4254 // We've determined that A is the current branch.
4255 assertIsMounted(parentA);
4256 return fiber;
4257 }
4258 if (child === b) {
4259 // We've determined that B is the current branch.
4260 assertIsMounted(parentA);
4261 return alternate;
4262 }
4263 child = child.sibling;
4264 }
4265 // We should never have an alternate for any mounting node. So the only
4266 // way this could possibly happen is if this was unmounted, if at all.
4267 invariant(false, 'Unable to find node on an unmounted component.');
4268 }
4269
4270 if (a.return !== b.return) {
4271 // The return pointer of A and the return pointer of B point to different
4272 // fibers. We assume that return pointers never criss-cross, so A must
4273 // belong to the child set of A.return, and B must belong to the child
4274 // set of B.return.
4275 a = parentA;
4276 b = parentB;
4277 } else {
4278 // The return pointers point to the same fiber. We'll have to use the
4279 // default, slow path: scan the child sets of each parent alternate to see
4280 // which child belongs to which set.
4281 //
4282 // Search parent A's child set
4283 var didFindChild = false;
4284 var _child = parentA.child;
4285 while (_child) {
4286 if (_child === a) {
4287 didFindChild = true;
4288 a = parentA;
4289 b = parentB;
4290 break;
4291 }
4292 if (_child === b) {
4293 didFindChild = true;
4294 b = parentA;
4295 a = parentB;
4296 break;
4297 }
4298 _child = _child.sibling;
4299 }
4300 if (!didFindChild) {
4301 // Search parent B's child set
4302 _child = parentB.child;
4303 while (_child) {
4304 if (_child === a) {
4305 didFindChild = true;
4306 a = parentB;
4307 b = parentA;
4308 break;
4309 }
4310 if (_child === b) {
4311 didFindChild = true;
4312 b = parentB;
4313 a = parentA;
4314 break;
4315 }
4316 _child = _child.sibling;
4317 }
4318 !didFindChild ? invariant(false, 'Child was not found in either parent set. This indicates a bug in React related to the return pointer. Please file an issue.') : void 0;
4319 }
4320 }
4321
4322 !(a.alternate === b) ? invariant(false, 'Return fibers should always be each others\' alternates. This error is likely caused by a bug in React. Please file an issue.') : void 0;
4323 }
4324 // If the root is not a host container, we're in a disconnected tree. I.e.
4325 // unmounted.
4326 !(a.tag === HostRoot) ? invariant(false, 'Unable to find node on an unmounted component.') : void 0;
4327 if (a.stateNode.current === a) {
4328 // We've determined that A is the current branch.
4329 return fiber;
4330 }
4331 // Otherwise B has to be current branch.
4332 return alternate;
4333}
4334
4335function findCurrentHostFiber(parent) {
4336 var currentParent = findCurrentFiberUsingSlowPath(parent);
4337 if (!currentParent) {
4338 return null;
4339 }
4340
4341 // Next we'll drill down this component to find the first HostComponent/Text.
4342 var node = currentParent;
4343 while (true) {
4344 if (node.tag === HostComponent || node.tag === HostText) {
4345 return node;
4346 } else if (node.child) {
4347 node.child.return = node;
4348 node = node.child;
4349 continue;
4350 }
4351 if (node === currentParent) {
4352 return null;
4353 }
4354 while (!node.sibling) {
4355 if (!node.return || node.return === currentParent) {
4356 return null;
4357 }
4358 node = node.return;
4359 }
4360 node.sibling.return = node.return;
4361 node = node.sibling;
4362 }
4363 // Flow needs the return null here, but ESLint complains about it.
4364 // eslint-disable-next-line no-unreachable
4365 return null;
4366}
4367
4368function findCurrentHostFiberWithNoPortals(parent) {
4369 var currentParent = findCurrentFiberUsingSlowPath(parent);
4370 if (!currentParent) {
4371 return null;
4372 }
4373
4374 // Next we'll drill down this component to find the first HostComponent/Text.
4375 var node = currentParent;
4376 while (true) {
4377 if (node.tag === HostComponent || node.tag === HostText) {
4378 return node;
4379 } else if (node.child && node.tag !== HostPortal) {
4380 node.child.return = node;
4381 node = node.child;
4382 continue;
4383 }
4384 if (node === currentParent) {
4385 return null;
4386 }
4387 while (!node.sibling) {
4388 if (!node.return || node.return === currentParent) {
4389 return null;
4390 }
4391 node = node.return;
4392 }
4393 node.sibling.return = node.return;
4394 node = node.sibling;
4395 }
4396 // Flow needs the return null here, but ESLint complains about it.
4397 // eslint-disable-next-line no-unreachable
4398 return null;
4399}
4400
4401function addEventBubbleListener(element, eventType, listener) {
4402 element.addEventListener(eventType, listener, false);
4403}
4404
4405function addEventCaptureListener(element, eventType, listener) {
4406 element.addEventListener(eventType, listener, true);
4407}
4408
4409/**
4410 * @interface Event
4411 * @see http://www.w3.org/TR/css3-animations/#AnimationEvent-interface
4412 * @see https://developer.mozilla.org/en-US/docs/Web/API/AnimationEvent
4413 */
4414var SyntheticAnimationEvent = SyntheticEvent.extend({
4415 animationName: null,
4416 elapsedTime: null,
4417 pseudoElement: null
4418});
4419
4420/**
4421 * @interface Event
4422 * @see http://www.w3.org/TR/clipboard-apis/
4423 */
4424var SyntheticClipboardEvent = SyntheticEvent.extend({
4425 clipboardData: function (event) {
4426 return 'clipboardData' in event ? event.clipboardData : window.clipboardData;
4427 }
4428});
4429
4430/**
4431 * @interface FocusEvent
4432 * @see http://www.w3.org/TR/DOM-Level-3-Events/
4433 */
4434var SyntheticFocusEvent = SyntheticUIEvent.extend({
4435 relatedTarget: null
4436});
4437
4438/**
4439 * `charCode` represents the actual "character code" and is safe to use with
4440 * `String.fromCharCode`. As such, only keys that correspond to printable
4441 * characters produce a valid `charCode`, the only exception to this is Enter.
4442 * The Tab-key is considered non-printable and does not have a `charCode`,
4443 * presumably because it does not produce a tab-character in browsers.
4444 *
4445 * @param {object} nativeEvent Native browser event.
4446 * @return {number} Normalized `charCode` property.
4447 */
4448function getEventCharCode(nativeEvent) {
4449 var charCode = void 0;
4450 var keyCode = nativeEvent.keyCode;
4451
4452 if ('charCode' in nativeEvent) {
4453 charCode = nativeEvent.charCode;
4454
4455 // FF does not set `charCode` for the Enter-key, check against `keyCode`.
4456 if (charCode === 0 && keyCode === 13) {
4457 charCode = 13;
4458 }
4459 } else {
4460 // IE8 does not implement `charCode`, but `keyCode` has the correct value.
4461 charCode = keyCode;
4462 }
4463
4464 // IE and Edge (on Windows) and Chrome / Safari (on Windows and Linux)
4465 // report Enter as charCode 10 when ctrl is pressed.
4466 if (charCode === 10) {
4467 charCode = 13;
4468 }
4469
4470 // Some non-printable keys are reported in `charCode`/`keyCode`, discard them.
4471 // Must not discard the (non-)printable Enter-key.
4472 if (charCode >= 32 || charCode === 13) {
4473 return charCode;
4474 }
4475
4476 return 0;
4477}
4478
4479/**
4480 * Normalization of deprecated HTML5 `key` values
4481 * @see https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent#Key_names
4482 */
4483var normalizeKey = {
4484 Esc: 'Escape',
4485 Spacebar: ' ',
4486 Left: 'ArrowLeft',
4487 Up: 'ArrowUp',
4488 Right: 'ArrowRight',
4489 Down: 'ArrowDown',
4490 Del: 'Delete',
4491 Win: 'OS',
4492 Menu: 'ContextMenu',
4493 Apps: 'ContextMenu',
4494 Scroll: 'ScrollLock',
4495 MozPrintableKey: 'Unidentified'
4496};
4497
4498/**
4499 * Translation from legacy `keyCode` to HTML5 `key`
4500 * Only special keys supported, all others depend on keyboard layout or browser
4501 * @see https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent#Key_names
4502 */
4503var translateToKey = {
4504 '8': 'Backspace',
4505 '9': 'Tab',
4506 '12': 'Clear',
4507 '13': 'Enter',
4508 '16': 'Shift',
4509 '17': 'Control',
4510 '18': 'Alt',
4511 '19': 'Pause',
4512 '20': 'CapsLock',
4513 '27': 'Escape',
4514 '32': ' ',
4515 '33': 'PageUp',
4516 '34': 'PageDown',
4517 '35': 'End',
4518 '36': 'Home',
4519 '37': 'ArrowLeft',
4520 '38': 'ArrowUp',
4521 '39': 'ArrowRight',
4522 '40': 'ArrowDown',
4523 '45': 'Insert',
4524 '46': 'Delete',
4525 '112': 'F1',
4526 '113': 'F2',
4527 '114': 'F3',
4528 '115': 'F4',
4529 '116': 'F5',
4530 '117': 'F6',
4531 '118': 'F7',
4532 '119': 'F8',
4533 '120': 'F9',
4534 '121': 'F10',
4535 '122': 'F11',
4536 '123': 'F12',
4537 '144': 'NumLock',
4538 '145': 'ScrollLock',
4539 '224': 'Meta'
4540};
4541
4542/**
4543 * @param {object} nativeEvent Native browser event.
4544 * @return {string} Normalized `key` property.
4545 */
4546function getEventKey(nativeEvent) {
4547 if (nativeEvent.key) {
4548 // Normalize inconsistent values reported by browsers due to
4549 // implementations of a working draft specification.
4550
4551 // FireFox implements `key` but returns `MozPrintableKey` for all
4552 // printable characters (normalized to `Unidentified`), ignore it.
4553 var key = normalizeKey[nativeEvent.key] || nativeEvent.key;
4554 if (key !== 'Unidentified') {
4555 return key;
4556 }
4557 }
4558
4559 // Browser does not implement `key`, polyfill as much of it as we can.
4560 if (nativeEvent.type === 'keypress') {
4561 var charCode = getEventCharCode(nativeEvent);
4562
4563 // The enter-key is technically both printable and non-printable and can
4564 // thus be captured by `keypress`, no other non-printable key should.
4565 return charCode === 13 ? 'Enter' : String.fromCharCode(charCode);
4566 }
4567 if (nativeEvent.type === 'keydown' || nativeEvent.type === 'keyup') {
4568 // While user keyboard layout determines the actual meaning of each
4569 // `keyCode` value, almost all function keys have a universal value.
4570 return translateToKey[nativeEvent.keyCode] || 'Unidentified';
4571 }
4572 return '';
4573}
4574
4575/**
4576 * @interface KeyboardEvent
4577 * @see http://www.w3.org/TR/DOM-Level-3-Events/
4578 */
4579var SyntheticKeyboardEvent = SyntheticUIEvent.extend({
4580 key: getEventKey,
4581 location: null,
4582 ctrlKey: null,
4583 shiftKey: null,
4584 altKey: null,
4585 metaKey: null,
4586 repeat: null,
4587 locale: null,
4588 getModifierState: getEventModifierState,
4589 // Legacy Interface
4590 charCode: function (event) {
4591 // `charCode` is the result of a KeyPress event and represents the value of
4592 // the actual printable character.
4593
4594 // KeyPress is deprecated, but its replacement is not yet final and not
4595 // implemented in any major browser. Only KeyPress has charCode.
4596 if (event.type === 'keypress') {
4597 return getEventCharCode(event);
4598 }
4599 return 0;
4600 },
4601 keyCode: function (event) {
4602 // `keyCode` is the result of a KeyDown/Up event and represents the value of
4603 // physical keyboard key.
4604
4605 // The actual meaning of the value depends on the users' keyboard layout
4606 // which cannot be detected. Assuming that it is a US keyboard layout
4607 // provides a surprisingly accurate mapping for US and European users.
4608 // Due to this, it is left to the user to implement at this time.
4609 if (event.type === 'keydown' || event.type === 'keyup') {
4610 return event.keyCode;
4611 }
4612 return 0;
4613 },
4614 which: function (event) {
4615 // `which` is an alias for either `keyCode` or `charCode` depending on the
4616 // type of the event.
4617 if (event.type === 'keypress') {
4618 return getEventCharCode(event);
4619 }
4620 if (event.type === 'keydown' || event.type === 'keyup') {
4621 return event.keyCode;
4622 }
4623 return 0;
4624 }
4625});
4626
4627/**
4628 * @interface DragEvent
4629 * @see http://www.w3.org/TR/DOM-Level-3-Events/
4630 */
4631var SyntheticDragEvent = SyntheticMouseEvent.extend({
4632 dataTransfer: null
4633});
4634
4635/**
4636 * @interface TouchEvent
4637 * @see http://www.w3.org/TR/touch-events/
4638 */
4639var SyntheticTouchEvent = SyntheticUIEvent.extend({
4640 touches: null,
4641 targetTouches: null,
4642 changedTouches: null,
4643 altKey: null,
4644 metaKey: null,
4645 ctrlKey: null,
4646 shiftKey: null,
4647 getModifierState: getEventModifierState
4648});
4649
4650/**
4651 * @interface Event
4652 * @see http://www.w3.org/TR/2009/WD-css3-transitions-20090320/#transition-events-
4653 * @see https://developer.mozilla.org/en-US/docs/Web/API/TransitionEvent
4654 */
4655var SyntheticTransitionEvent = SyntheticEvent.extend({
4656 propertyName: null,
4657 elapsedTime: null,
4658 pseudoElement: null
4659});
4660
4661/**
4662 * @interface WheelEvent
4663 * @see http://www.w3.org/TR/DOM-Level-3-Events/
4664 */
4665var SyntheticWheelEvent = SyntheticMouseEvent.extend({
4666 deltaX: function (event) {
4667 return 'deltaX' in event ? event.deltaX : // Fallback to `wheelDeltaX` for Webkit and normalize (right is positive).
4668 'wheelDeltaX' in event ? -event.wheelDeltaX : 0;
4669 },
4670 deltaY: function (event) {
4671 return 'deltaY' in event ? event.deltaY : // Fallback to `wheelDeltaY` for Webkit and normalize (down is positive).
4672 'wheelDeltaY' in event ? -event.wheelDeltaY : // Fallback to `wheelDelta` for IE<9 and normalize (down is positive).
4673 'wheelDelta' in event ? -event.wheelDelta : 0;
4674 },
4675
4676 deltaZ: null,
4677
4678 // Browsers without "deltaMode" is reporting in raw wheel delta where one
4679 // notch on the scroll is always +/- 120, roughly equivalent to pixels.
4680 // A good approximation of DOM_DELTA_LINE (1) is 5% of viewport size or
4681 // ~40 pixels, for DOM_DELTA_SCREEN (2) it is 87.5% of viewport size.
4682 deltaMode: null
4683});
4684
4685/**
4686 * Turns
4687 * ['abort', ...]
4688 * into
4689 * eventTypes = {
4690 * 'abort': {
4691 * phasedRegistrationNames: {
4692 * bubbled: 'onAbort',
4693 * captured: 'onAbortCapture',
4694 * },
4695 * dependencies: [TOP_ABORT],
4696 * },
4697 * ...
4698 * };
4699 * topLevelEventsToDispatchConfig = new Map([
4700 * [TOP_ABORT, { sameConfig }],
4701 * ]);
4702 */
4703
4704var interactiveEventTypeNames = [[TOP_BLUR, 'blur'], [TOP_CANCEL, 'cancel'], [TOP_CLICK, 'click'], [TOP_CLOSE, 'close'], [TOP_CONTEXT_MENU, 'contextMenu'], [TOP_COPY, 'copy'], [TOP_CUT, 'cut'], [TOP_AUX_CLICK, 'auxClick'], [TOP_DOUBLE_CLICK, 'doubleClick'], [TOP_DRAG_END, 'dragEnd'], [TOP_DRAG_START, 'dragStart'], [TOP_DROP, 'drop'], [TOP_FOCUS, 'focus'], [TOP_INPUT, 'input'], [TOP_INVALID, 'invalid'], [TOP_KEY_DOWN, 'keyDown'], [TOP_KEY_PRESS, 'keyPress'], [TOP_KEY_UP, 'keyUp'], [TOP_MOUSE_DOWN, 'mouseDown'], [TOP_MOUSE_UP, 'mouseUp'], [TOP_PASTE, 'paste'], [TOP_PAUSE, 'pause'], [TOP_PLAY, 'play'], [TOP_POINTER_CANCEL, 'pointerCancel'], [TOP_POINTER_DOWN, 'pointerDown'], [TOP_POINTER_UP, 'pointerUp'], [TOP_RATE_CHANGE, 'rateChange'], [TOP_RESET, 'reset'], [TOP_SEEKED, 'seeked'], [TOP_SUBMIT, 'submit'], [TOP_TOUCH_CANCEL, 'touchCancel'], [TOP_TOUCH_END, 'touchEnd'], [TOP_TOUCH_START, 'touchStart'], [TOP_VOLUME_CHANGE, 'volumeChange']];
4705var nonInteractiveEventTypeNames = [[TOP_ABORT, 'abort'], [TOP_ANIMATION_END, 'animationEnd'], [TOP_ANIMATION_ITERATION, 'animationIteration'], [TOP_ANIMATION_START, 'animationStart'], [TOP_CAN_PLAY, 'canPlay'], [TOP_CAN_PLAY_THROUGH, 'canPlayThrough'], [TOP_DRAG, 'drag'], [TOP_DRAG_ENTER, 'dragEnter'], [TOP_DRAG_EXIT, 'dragExit'], [TOP_DRAG_LEAVE, 'dragLeave'], [TOP_DRAG_OVER, 'dragOver'], [TOP_DURATION_CHANGE, 'durationChange'], [TOP_EMPTIED, 'emptied'], [TOP_ENCRYPTED, 'encrypted'], [TOP_ENDED, 'ended'], [TOP_ERROR, 'error'], [TOP_GOT_POINTER_CAPTURE, 'gotPointerCapture'], [TOP_LOAD, 'load'], [TOP_LOADED_DATA, 'loadedData'], [TOP_LOADED_METADATA, 'loadedMetadata'], [TOP_LOAD_START, 'loadStart'], [TOP_LOST_POINTER_CAPTURE, 'lostPointerCapture'], [TOP_MOUSE_MOVE, 'mouseMove'], [TOP_MOUSE_OUT, 'mouseOut'], [TOP_MOUSE_OVER, 'mouseOver'], [TOP_PLAYING, 'playing'], [TOP_POINTER_MOVE, 'pointerMove'], [TOP_POINTER_OUT, 'pointerOut'], [TOP_POINTER_OVER, 'pointerOver'], [TOP_PROGRESS, 'progress'], [TOP_SCROLL, 'scroll'], [TOP_SEEKING, 'seeking'], [TOP_STALLED, 'stalled'], [TOP_SUSPEND, 'suspend'], [TOP_TIME_UPDATE, 'timeUpdate'], [TOP_TOGGLE, 'toggle'], [TOP_TOUCH_MOVE, 'touchMove'], [TOP_TRANSITION_END, 'transitionEnd'], [TOP_WAITING, 'waiting'], [TOP_WHEEL, 'wheel']];
4706
4707var eventTypes$4 = {};
4708var topLevelEventsToDispatchConfig = {};
4709
4710function addEventTypeNameToConfig(_ref, isInteractive) {
4711 var topEvent = _ref[0],
4712 event = _ref[1];
4713
4714 var capitalizedEvent = event[0].toUpperCase() + event.slice(1);
4715 var onEvent = 'on' + capitalizedEvent;
4716
4717 var type = {
4718 phasedRegistrationNames: {
4719 bubbled: onEvent,
4720 captured: onEvent + 'Capture'
4721 },
4722 dependencies: [topEvent],
4723 isInteractive: isInteractive
4724 };
4725 eventTypes$4[event] = type;
4726 topLevelEventsToDispatchConfig[topEvent] = type;
4727}
4728
4729interactiveEventTypeNames.forEach(function (eventTuple) {
4730 addEventTypeNameToConfig(eventTuple, true);
4731});
4732nonInteractiveEventTypeNames.forEach(function (eventTuple) {
4733 addEventTypeNameToConfig(eventTuple, false);
4734});
4735
4736// Only used in DEV for exhaustiveness validation.
4737var knownHTMLTopLevelTypes = [TOP_ABORT, TOP_CANCEL, TOP_CAN_PLAY, TOP_CAN_PLAY_THROUGH, TOP_CLOSE, TOP_DURATION_CHANGE, TOP_EMPTIED, TOP_ENCRYPTED, TOP_ENDED, TOP_ERROR, TOP_INPUT, TOP_INVALID, TOP_LOAD, TOP_LOADED_DATA, TOP_LOADED_METADATA, TOP_LOAD_START, TOP_PAUSE, TOP_PLAY, TOP_PLAYING, TOP_PROGRESS, TOP_RATE_CHANGE, TOP_RESET, TOP_SEEKED, TOP_SEEKING, TOP_STALLED, TOP_SUBMIT, TOP_SUSPEND, TOP_TIME_UPDATE, TOP_TOGGLE, TOP_VOLUME_CHANGE, TOP_WAITING];
4738
4739var SimpleEventPlugin = {
4740 eventTypes: eventTypes$4,
4741
4742 isInteractiveTopLevelEventType: function (topLevelType) {
4743 var config = topLevelEventsToDispatchConfig[topLevelType];
4744 return config !== undefined && config.isInteractive === true;
4745 },
4746
4747
4748 extractEvents: function (topLevelType, targetInst, nativeEvent, nativeEventTarget) {
4749 var dispatchConfig = topLevelEventsToDispatchConfig[topLevelType];
4750 if (!dispatchConfig) {
4751 return null;
4752 }
4753 var EventConstructor = void 0;
4754 switch (topLevelType) {
4755 case TOP_KEY_PRESS:
4756 // Firefox creates a keypress event for function keys too. This removes
4757 // the unwanted keypress events. Enter is however both printable and
4758 // non-printable. One would expect Tab to be as well (but it isn't).
4759 if (getEventCharCode(nativeEvent) === 0) {
4760 return null;
4761 }
4762 /* falls through */
4763 case TOP_KEY_DOWN:
4764 case TOP_KEY_UP:
4765 EventConstructor = SyntheticKeyboardEvent;
4766 break;
4767 case TOP_BLUR:
4768 case TOP_FOCUS:
4769 EventConstructor = SyntheticFocusEvent;
4770 break;
4771 case TOP_CLICK:
4772 // Firefox creates a click event on right mouse clicks. This removes the
4773 // unwanted click events.
4774 if (nativeEvent.button === 2) {
4775 return null;
4776 }
4777 /* falls through */
4778 case TOP_AUX_CLICK:
4779 case TOP_DOUBLE_CLICK:
4780 case TOP_MOUSE_DOWN:
4781 case TOP_MOUSE_MOVE:
4782 case TOP_MOUSE_UP:
4783 // TODO: Disabled elements should not respond to mouse events
4784 /* falls through */
4785 case TOP_MOUSE_OUT:
4786 case TOP_MOUSE_OVER:
4787 case TOP_CONTEXT_MENU:
4788 EventConstructor = SyntheticMouseEvent;
4789 break;
4790 case TOP_DRAG:
4791 case TOP_DRAG_END:
4792 case TOP_DRAG_ENTER:
4793 case TOP_DRAG_EXIT:
4794 case TOP_DRAG_LEAVE:
4795 case TOP_DRAG_OVER:
4796 case TOP_DRAG_START:
4797 case TOP_DROP:
4798 EventConstructor = SyntheticDragEvent;
4799 break;
4800 case TOP_TOUCH_CANCEL:
4801 case TOP_TOUCH_END:
4802 case TOP_TOUCH_MOVE:
4803 case TOP_TOUCH_START:
4804 EventConstructor = SyntheticTouchEvent;
4805 break;
4806 case TOP_ANIMATION_END:
4807 case TOP_ANIMATION_ITERATION:
4808 case TOP_ANIMATION_START:
4809 EventConstructor = SyntheticAnimationEvent;
4810 break;
4811 case TOP_TRANSITION_END:
4812 EventConstructor = SyntheticTransitionEvent;
4813 break;
4814 case TOP_SCROLL:
4815 EventConstructor = SyntheticUIEvent;
4816 break;
4817 case TOP_WHEEL:
4818 EventConstructor = SyntheticWheelEvent;
4819 break;
4820 case TOP_COPY:
4821 case TOP_CUT:
4822 case TOP_PASTE:
4823 EventConstructor = SyntheticClipboardEvent;
4824 break;
4825 case TOP_GOT_POINTER_CAPTURE:
4826 case TOP_LOST_POINTER_CAPTURE:
4827 case TOP_POINTER_CANCEL:
4828 case TOP_POINTER_DOWN:
4829 case TOP_POINTER_MOVE:
4830 case TOP_POINTER_OUT:
4831 case TOP_POINTER_OVER:
4832 case TOP_POINTER_UP:
4833 EventConstructor = SyntheticPointerEvent;
4834 break;
4835 default:
4836 {
4837 if (knownHTMLTopLevelTypes.indexOf(topLevelType) === -1) {
4838 warningWithoutStack$1(false, 'SimpleEventPlugin: Unhandled event type, `%s`. This warning ' + 'is likely caused by a bug in React. Please file an issue.', topLevelType);
4839 }
4840 }
4841 // HTML Events
4842 // @see http://www.w3.org/TR/html5/index.html#events-0
4843 EventConstructor = SyntheticEvent;
4844 break;
4845 }
4846 var event = EventConstructor.getPooled(dispatchConfig, targetInst, nativeEvent, nativeEventTarget);
4847 accumulateTwoPhaseDispatches(event);
4848 return event;
4849 }
4850};
4851
4852var isInteractiveTopLevelEventType = SimpleEventPlugin.isInteractiveTopLevelEventType;
4853
4854
4855var CALLBACK_BOOKKEEPING_POOL_SIZE = 10;
4856var callbackBookkeepingPool = [];
4857
4858/**
4859 * Find the deepest React component completely containing the root of the
4860 * passed-in instance (for use when entire React trees are nested within each
4861 * other). If React trees are not nested, returns null.
4862 */
4863function findRootContainerNode(inst) {
4864 // TODO: It may be a good idea to cache this to prevent unnecessary DOM
4865 // traversal, but caching is difficult to do correctly without using a
4866 // mutation observer to listen for all DOM changes.
4867 while (inst.return) {
4868 inst = inst.return;
4869 }
4870 if (inst.tag !== HostRoot) {
4871 // This can happen if we're in a detached tree.
4872 return null;
4873 }
4874 return inst.stateNode.containerInfo;
4875}
4876
4877// Used to store ancestor hierarchy in top level callback
4878function getTopLevelCallbackBookKeeping(topLevelType, nativeEvent, targetInst) {
4879 if (callbackBookkeepingPool.length) {
4880 var instance = callbackBookkeepingPool.pop();
4881 instance.topLevelType = topLevelType;
4882 instance.nativeEvent = nativeEvent;
4883 instance.targetInst = targetInst;
4884 return instance;
4885 }
4886 return {
4887 topLevelType: topLevelType,
4888 nativeEvent: nativeEvent,
4889 targetInst: targetInst,
4890 ancestors: []
4891 };
4892}
4893
4894function releaseTopLevelCallbackBookKeeping(instance) {
4895 instance.topLevelType = null;
4896 instance.nativeEvent = null;
4897 instance.targetInst = null;
4898 instance.ancestors.length = 0;
4899 if (callbackBookkeepingPool.length < CALLBACK_BOOKKEEPING_POOL_SIZE) {
4900 callbackBookkeepingPool.push(instance);
4901 }
4902}
4903
4904function handleTopLevel(bookKeeping) {
4905 var targetInst = bookKeeping.targetInst;
4906
4907 // Loop through the hierarchy, in case there's any nested components.
4908 // It's important that we build the array of ancestors before calling any
4909 // event handlers, because event handlers can modify the DOM, leading to
4910 // inconsistencies with ReactMount's node cache. See #1105.
4911 var ancestor = targetInst;
4912 do {
4913 if (!ancestor) {
4914 bookKeeping.ancestors.push(ancestor);
4915 break;
4916 }
4917 var root = findRootContainerNode(ancestor);
4918 if (!root) {
4919 break;
4920 }
4921 bookKeeping.ancestors.push(ancestor);
4922 ancestor = getClosestInstanceFromNode(root);
4923 } while (ancestor);
4924
4925 for (var i = 0; i < bookKeeping.ancestors.length; i++) {
4926 targetInst = bookKeeping.ancestors[i];
4927 runExtractedEventsInBatch(bookKeeping.topLevelType, targetInst, bookKeeping.nativeEvent, getEventTarget(bookKeeping.nativeEvent));
4928 }
4929}
4930
4931// TODO: can we stop exporting these?
4932var _enabled = true;
4933
4934function setEnabled(enabled) {
4935 _enabled = !!enabled;
4936}
4937
4938function isEnabled() {
4939 return _enabled;
4940}
4941
4942/**
4943 * Traps top-level events by using event bubbling.
4944 *
4945 * @param {number} topLevelType Number from `TopLevelEventTypes`.
4946 * @param {object} element Element on which to attach listener.
4947 * @return {?object} An object with a remove function which will forcefully
4948 * remove the listener.
4949 * @internal
4950 */
4951function trapBubbledEvent(topLevelType, element) {
4952 if (!element) {
4953 return null;
4954 }
4955 var dispatch = isInteractiveTopLevelEventType(topLevelType) ? dispatchInteractiveEvent : dispatchEvent;
4956
4957 addEventBubbleListener(element, getRawEventName(topLevelType),
4958 // Check if interactive and wrap in interactiveUpdates
4959 dispatch.bind(null, topLevelType));
4960}
4961
4962/**
4963 * Traps a top-level event by using event capturing.
4964 *
4965 * @param {number} topLevelType Number from `TopLevelEventTypes`.
4966 * @param {object} element Element on which to attach listener.
4967 * @return {?object} An object with a remove function which will forcefully
4968 * remove the listener.
4969 * @internal
4970 */
4971function trapCapturedEvent(topLevelType, element) {
4972 if (!element) {
4973 return null;
4974 }
4975 var dispatch = isInteractiveTopLevelEventType(topLevelType) ? dispatchInteractiveEvent : dispatchEvent;
4976
4977 addEventCaptureListener(element, getRawEventName(topLevelType),
4978 // Check if interactive and wrap in interactiveUpdates
4979 dispatch.bind(null, topLevelType));
4980}
4981
4982function dispatchInteractiveEvent(topLevelType, nativeEvent) {
4983 interactiveUpdates(dispatchEvent, topLevelType, nativeEvent);
4984}
4985
4986function dispatchEvent(topLevelType, nativeEvent) {
4987 if (!_enabled) {
4988 return;
4989 }
4990
4991 var nativeEventTarget = getEventTarget(nativeEvent);
4992 var targetInst = getClosestInstanceFromNode(nativeEventTarget);
4993 if (targetInst !== null && typeof targetInst.tag === 'number' && !isFiberMounted(targetInst)) {
4994 // If we get an event (ex: img onload) before committing that
4995 // component's mount, ignore it for now (that is, treat it as if it was an
4996 // event on a non-React tree). We might also consider queueing events and
4997 // dispatching them after the mount.
4998 targetInst = null;
4999 }
5000
5001 var bookKeeping = getTopLevelCallbackBookKeeping(topLevelType, nativeEvent, targetInst);
5002
5003 try {
5004 // Event queue being processed in the same cycle allows
5005 // `preventDefault`.
5006 batchedUpdates(handleTopLevel, bookKeeping);
5007 } finally {
5008 releaseTopLevelCallbackBookKeeping(bookKeeping);
5009 }
5010}
5011
5012/**
5013 * Summary of `ReactBrowserEventEmitter` event handling:
5014 *
5015 * - Top-level delegation is used to trap most native browser events. This
5016 * may only occur in the main thread and is the responsibility of
5017 * ReactDOMEventListener, which is injected and can therefore support
5018 * pluggable event sources. This is the only work that occurs in the main
5019 * thread.
5020 *
5021 * - We normalize and de-duplicate events to account for browser quirks. This
5022 * may be done in the worker thread.
5023 *
5024 * - Forward these native events (with the associated top-level type used to
5025 * trap it) to `EventPluginHub`, which in turn will ask plugins if they want
5026 * to extract any synthetic events.
5027 *
5028 * - The `EventPluginHub` will then process each event by annotating them with
5029 * "dispatches", a sequence of listeners and IDs that care about that event.
5030 *
5031 * - The `EventPluginHub` then dispatches the events.
5032 *
5033 * Overview of React and the event system:
5034 *
5035 * +------------+ .
5036 * | DOM | .
5037 * +------------+ .
5038 * | .
5039 * v .
5040 * +------------+ .
5041 * | ReactEvent | .
5042 * | Listener | .
5043 * +------------+ . +-----------+
5044 * | . +--------+|SimpleEvent|
5045 * | . | |Plugin |
5046 * +-----|------+ . v +-----------+
5047 * | | | . +--------------+ +------------+
5048 * | +-----------.--->|EventPluginHub| | Event |
5049 * | | . | | +-----------+ | Propagators|
5050 * | ReactEvent | . | | |TapEvent | |------------|
5051 * | Emitter | . | |<---+|Plugin | |other plugin|
5052 * | | . | | +-----------+ | utilities |
5053 * | +-----------.--->| | +------------+
5054 * | | | . +--------------+
5055 * +-----|------+ . ^ +-----------+
5056 * | . | |Enter/Leave|
5057 * + . +-------+|Plugin |
5058 * +-------------+ . +-----------+
5059 * | application | .
5060 * |-------------| .
5061 * | | .
5062 * | | .
5063 * +-------------+ .
5064 * .
5065 * React Core . General Purpose Event Plugin System
5066 */
5067
5068var alreadyListeningTo = {};
5069var reactTopListenersCounter = 0;
5070
5071/**
5072 * To ensure no conflicts with other potential React instances on the page
5073 */
5074var topListenersIDKey = '_reactListenersID' + ('' + Math.random()).slice(2);
5075
5076function getListeningForDocument(mountAt) {
5077 // In IE8, `mountAt` is a host object and doesn't have `hasOwnProperty`
5078 // directly.
5079 if (!Object.prototype.hasOwnProperty.call(mountAt, topListenersIDKey)) {
5080 mountAt[topListenersIDKey] = reactTopListenersCounter++;
5081 alreadyListeningTo[mountAt[topListenersIDKey]] = {};
5082 }
5083 return alreadyListeningTo[mountAt[topListenersIDKey]];
5084}
5085
5086/**
5087 * We listen for bubbled touch events on the document object.
5088 *
5089 * Firefox v8.01 (and possibly others) exhibited strange behavior when
5090 * mounting `onmousemove` events at some node that was not the document
5091 * element. The symptoms were that if your mouse is not moving over something
5092 * contained within that mount point (for example on the background) the
5093 * top-level listeners for `onmousemove` won't be called. However, if you
5094 * register the `mousemove` on the document object, then it will of course
5095 * catch all `mousemove`s. This along with iOS quirks, justifies restricting
5096 * top-level listeners to the document object only, at least for these
5097 * movement types of events and possibly all events.
5098 *
5099 * @see http://www.quirksmode.org/blog/archives/2010/09/click_event_del.html
5100 *
5101 * Also, `keyup`/`keypress`/`keydown` do not bubble to the window on IE, but
5102 * they bubble to document.
5103 *
5104 * @param {string} registrationName Name of listener (e.g. `onClick`).
5105 * @param {object} mountAt Container where to mount the listener
5106 */
5107function listenTo(registrationName, mountAt) {
5108 var isListening = getListeningForDocument(mountAt);
5109 var dependencies = registrationNameDependencies[registrationName];
5110
5111 for (var i = 0; i < dependencies.length; i++) {
5112 var dependency = dependencies[i];
5113 if (!(isListening.hasOwnProperty(dependency) && isListening[dependency])) {
5114 switch (dependency) {
5115 case TOP_SCROLL:
5116 trapCapturedEvent(TOP_SCROLL, mountAt);
5117 break;
5118 case TOP_FOCUS:
5119 case TOP_BLUR:
5120 trapCapturedEvent(TOP_FOCUS, mountAt);
5121 trapCapturedEvent(TOP_BLUR, mountAt);
5122 // We set the flag for a single dependency later in this function,
5123 // but this ensures we mark both as attached rather than just one.
5124 isListening[TOP_BLUR] = true;
5125 isListening[TOP_FOCUS] = true;
5126 break;
5127 case TOP_CANCEL:
5128 case TOP_CLOSE:
5129 if (isEventSupported(getRawEventName(dependency))) {
5130 trapCapturedEvent(dependency, mountAt);
5131 }
5132 break;
5133 case TOP_INVALID:
5134 case TOP_SUBMIT:
5135 case TOP_RESET:
5136 // We listen to them on the target DOM elements.
5137 // Some of them bubble so we don't want them to fire twice.
5138 break;
5139 default:
5140 // By default, listen on the top level to all non-media events.
5141 // Media events don't bubble so adding the listener wouldn't do anything.
5142 var isMediaEvent = mediaEventTypes.indexOf(dependency) !== -1;
5143 if (!isMediaEvent) {
5144 trapBubbledEvent(dependency, mountAt);
5145 }
5146 break;
5147 }
5148 isListening[dependency] = true;
5149 }
5150 }
5151}
5152
5153function isListeningToAllDependencies(registrationName, mountAt) {
5154 var isListening = getListeningForDocument(mountAt);
5155 var dependencies = registrationNameDependencies[registrationName];
5156 for (var i = 0; i < dependencies.length; i++) {
5157 var dependency = dependencies[i];
5158 if (!(isListening.hasOwnProperty(dependency) && isListening[dependency])) {
5159 return false;
5160 }
5161 }
5162 return true;
5163}
5164
5165function getActiveElement(doc) {
5166 doc = doc || (typeof document !== 'undefined' ? document : undefined);
5167 if (typeof doc === 'undefined') {
5168 return null;
5169 }
5170 try {
5171 return doc.activeElement || doc.body;
5172 } catch (e) {
5173 return doc.body;
5174 }
5175}
5176
5177/**
5178 * Given any node return the first leaf node without children.
5179 *
5180 * @param {DOMElement|DOMTextNode} node
5181 * @return {DOMElement|DOMTextNode}
5182 */
5183function getLeafNode(node) {
5184 while (node && node.firstChild) {
5185 node = node.firstChild;
5186 }
5187 return node;
5188}
5189
5190/**
5191 * Get the next sibling within a container. This will walk up the
5192 * DOM if a node's siblings have been exhausted.
5193 *
5194 * @param {DOMElement|DOMTextNode} node
5195 * @return {?DOMElement|DOMTextNode}
5196 */
5197function getSiblingNode(node) {
5198 while (node) {
5199 if (node.nextSibling) {
5200 return node.nextSibling;
5201 }
5202 node = node.parentNode;
5203 }
5204}
5205
5206/**
5207 * Get object describing the nodes which contain characters at offset.
5208 *
5209 * @param {DOMElement|DOMTextNode} root
5210 * @param {number} offset
5211 * @return {?object}
5212 */
5213function getNodeForCharacterOffset(root, offset) {
5214 var node = getLeafNode(root);
5215 var nodeStart = 0;
5216 var nodeEnd = 0;
5217
5218 while (node) {
5219 if (node.nodeType === TEXT_NODE) {
5220 nodeEnd = nodeStart + node.textContent.length;
5221
5222 if (nodeStart <= offset && nodeEnd >= offset) {
5223 return {
5224 node: node,
5225 offset: offset - nodeStart
5226 };
5227 }
5228
5229 nodeStart = nodeEnd;
5230 }
5231
5232 node = getLeafNode(getSiblingNode(node));
5233 }
5234}
5235
5236/**
5237 * @param {DOMElement} outerNode
5238 * @return {?object}
5239 */
5240function getOffsets(outerNode) {
5241 var ownerDocument = outerNode.ownerDocument;
5242
5243 var win = ownerDocument && ownerDocument.defaultView || window;
5244 var selection = win.getSelection && win.getSelection();
5245
5246 if (!selection || selection.rangeCount === 0) {
5247 return null;
5248 }
5249
5250 var anchorNode = selection.anchorNode,
5251 anchorOffset = selection.anchorOffset,
5252 focusNode = selection.focusNode,
5253 focusOffset = selection.focusOffset;
5254
5255 // In Firefox, anchorNode and focusNode can be "anonymous divs", e.g. the
5256 // up/down buttons on an <input type="number">. Anonymous divs do not seem to
5257 // expose properties, triggering a "Permission denied error" if any of its
5258 // properties are accessed. The only seemingly possible way to avoid erroring
5259 // is to access a property that typically works for non-anonymous divs and
5260 // catch any error that may otherwise arise. See
5261 // https://bugzilla.mozilla.org/show_bug.cgi?id=208427
5262
5263 try {
5264 /* eslint-disable no-unused-expressions */
5265 anchorNode.nodeType;
5266 focusNode.nodeType;
5267 /* eslint-enable no-unused-expressions */
5268 } catch (e) {
5269 return null;
5270 }
5271
5272 return getModernOffsetsFromPoints(outerNode, anchorNode, anchorOffset, focusNode, focusOffset);
5273}
5274
5275/**
5276 * Returns {start, end} where `start` is the character/codepoint index of
5277 * (anchorNode, anchorOffset) within the textContent of `outerNode`, and
5278 * `end` is the index of (focusNode, focusOffset).
5279 *
5280 * Returns null if you pass in garbage input but we should probably just crash.
5281 *
5282 * Exported only for testing.
5283 */
5284function getModernOffsetsFromPoints(outerNode, anchorNode, anchorOffset, focusNode, focusOffset) {
5285 var length = 0;
5286 var start = -1;
5287 var end = -1;
5288 var indexWithinAnchor = 0;
5289 var indexWithinFocus = 0;
5290 var node = outerNode;
5291 var parentNode = null;
5292
5293 outer: while (true) {
5294 var next = null;
5295
5296 while (true) {
5297 if (node === anchorNode && (anchorOffset === 0 || node.nodeType === TEXT_NODE)) {
5298 start = length + anchorOffset;
5299 }
5300 if (node === focusNode && (focusOffset === 0 || node.nodeType === TEXT_NODE)) {
5301 end = length + focusOffset;
5302 }
5303
5304 if (node.nodeType === TEXT_NODE) {
5305 length += node.nodeValue.length;
5306 }
5307
5308 if ((next = node.firstChild) === null) {
5309 break;
5310 }
5311 // Moving from `node` to its first child `next`.
5312 parentNode = node;
5313 node = next;
5314 }
5315
5316 while (true) {
5317 if (node === outerNode) {
5318 // If `outerNode` has children, this is always the second time visiting
5319 // it. If it has no children, this is still the first loop, and the only
5320 // valid selection is anchorNode and focusNode both equal to this node
5321 // and both offsets 0, in which case we will have handled above.
5322 break outer;
5323 }
5324 if (parentNode === anchorNode && ++indexWithinAnchor === anchorOffset) {
5325 start = length;
5326 }
5327 if (parentNode === focusNode && ++indexWithinFocus === focusOffset) {
5328 end = length;
5329 }
5330 if ((next = node.nextSibling) !== null) {
5331 break;
5332 }
5333 node = parentNode;
5334 parentNode = node.parentNode;
5335 }
5336
5337 // Moving from `node` to its next sibling `next`.
5338 node = next;
5339 }
5340
5341 if (start === -1 || end === -1) {
5342 // This should never happen. (Would happen if the anchor/focus nodes aren't
5343 // actually inside the passed-in node.)
5344 return null;
5345 }
5346
5347 return {
5348 start: start,
5349 end: end
5350 };
5351}
5352
5353/**
5354 * In modern non-IE browsers, we can support both forward and backward
5355 * selections.
5356 *
5357 * Note: IE10+ supports the Selection object, but it does not support
5358 * the `extend` method, which means that even in modern IE, it's not possible
5359 * to programmatically create a backward selection. Thus, for all IE
5360 * versions, we use the old IE API to create our selections.
5361 *
5362 * @param {DOMElement|DOMTextNode} node
5363 * @param {object} offsets
5364 */
5365function setOffsets(node, offsets) {
5366 var doc = node.ownerDocument || document;
5367 var win = doc && doc.defaultView || window;
5368
5369 // Edge fails with "Object expected" in some scenarios.
5370 // (For instance: TinyMCE editor used in a list component that supports pasting to add more,
5371 // fails when pasting 100+ items)
5372 if (!win.getSelection) {
5373 return;
5374 }
5375
5376 var selection = win.getSelection();
5377 var length = node.textContent.length;
5378 var start = Math.min(offsets.start, length);
5379 var end = offsets.end === undefined ? start : Math.min(offsets.end, length);
5380
5381 // IE 11 uses modern selection, but doesn't support the extend method.
5382 // Flip backward selections, so we can set with a single range.
5383 if (!selection.extend && start > end) {
5384 var temp = end;
5385 end = start;
5386 start = temp;
5387 }
5388
5389 var startMarker = getNodeForCharacterOffset(node, start);
5390 var endMarker = getNodeForCharacterOffset(node, end);
5391
5392 if (startMarker && endMarker) {
5393 if (selection.rangeCount === 1 && selection.anchorNode === startMarker.node && selection.anchorOffset === startMarker.offset && selection.focusNode === endMarker.node && selection.focusOffset === endMarker.offset) {
5394 return;
5395 }
5396 var range = doc.createRange();
5397 range.setStart(startMarker.node, startMarker.offset);
5398 selection.removeAllRanges();
5399
5400 if (start > end) {
5401 selection.addRange(range);
5402 selection.extend(endMarker.node, endMarker.offset);
5403 } else {
5404 range.setEnd(endMarker.node, endMarker.offset);
5405 selection.addRange(range);
5406 }
5407 }
5408}
5409
5410function isTextNode(node) {
5411 return node && node.nodeType === TEXT_NODE;
5412}
5413
5414function containsNode(outerNode, innerNode) {
5415 if (!outerNode || !innerNode) {
5416 return false;
5417 } else if (outerNode === innerNode) {
5418 return true;
5419 } else if (isTextNode(outerNode)) {
5420 return false;
5421 } else if (isTextNode(innerNode)) {
5422 return containsNode(outerNode, innerNode.parentNode);
5423 } else if ('contains' in outerNode) {
5424 return outerNode.contains(innerNode);
5425 } else if (outerNode.compareDocumentPosition) {
5426 return !!(outerNode.compareDocumentPosition(innerNode) & 16);
5427 } else {
5428 return false;
5429 }
5430}
5431
5432function isInDocument(node) {
5433 return node && node.ownerDocument && containsNode(node.ownerDocument.documentElement, node);
5434}
5435
5436function getActiveElementDeep() {
5437 var win = window;
5438 var element = getActiveElement();
5439 while (element instanceof win.HTMLIFrameElement) {
5440 // Accessing the contentDocument of a HTMLIframeElement can cause the browser
5441 // to throw, e.g. if it has a cross-origin src attribute
5442 try {
5443 win = element.contentDocument.defaultView;
5444 } catch (e) {
5445 return element;
5446 }
5447 element = getActiveElement(win.document);
5448 }
5449 return element;
5450}
5451
5452/**
5453 * @ReactInputSelection: React input selection module. Based on Selection.js,
5454 * but modified to be suitable for react and has a couple of bug fixes (doesn't
5455 * assume buttons have range selections allowed).
5456 * Input selection module for React.
5457 */
5458
5459/**
5460 * @hasSelectionCapabilities: we get the element types that support selection
5461 * from https://html.spec.whatwg.org/#do-not-apply, looking at `selectionStart`
5462 * and `selectionEnd` rows.
5463 */
5464function hasSelectionCapabilities(elem) {
5465 var nodeName = elem && elem.nodeName && elem.nodeName.toLowerCase();
5466 return nodeName && (nodeName === 'input' && (elem.type === 'text' || elem.type === 'search' || elem.type === 'tel' || elem.type === 'url' || elem.type === 'password') || nodeName === 'textarea' || elem.contentEditable === 'true');
5467}
5468
5469function getSelectionInformation() {
5470 var focusedElem = getActiveElementDeep();
5471 return {
5472 focusedElem: focusedElem,
5473 selectionRange: hasSelectionCapabilities(focusedElem) ? getSelection$1(focusedElem) : null
5474 };
5475}
5476
5477/**
5478 * @restoreSelection: If any selection information was potentially lost,
5479 * restore it. This is useful when performing operations that could remove dom
5480 * nodes and place them back in, resulting in focus being lost.
5481 */
5482function restoreSelection(priorSelectionInformation) {
5483 var curFocusedElem = getActiveElementDeep();
5484 var priorFocusedElem = priorSelectionInformation.focusedElem;
5485 var priorSelectionRange = priorSelectionInformation.selectionRange;
5486 if (curFocusedElem !== priorFocusedElem && isInDocument(priorFocusedElem)) {
5487 if (priorSelectionRange !== null && hasSelectionCapabilities(priorFocusedElem)) {
5488 setSelection(priorFocusedElem, priorSelectionRange);
5489 }
5490
5491 // Focusing a node can change the scroll position, which is undesirable
5492 var ancestors = [];
5493 var ancestor = priorFocusedElem;
5494 while (ancestor = ancestor.parentNode) {
5495 if (ancestor.nodeType === ELEMENT_NODE) {
5496 ancestors.push({
5497 element: ancestor,
5498 left: ancestor.scrollLeft,
5499 top: ancestor.scrollTop
5500 });
5501 }
5502 }
5503
5504 if (typeof priorFocusedElem.focus === 'function') {
5505 priorFocusedElem.focus();
5506 }
5507
5508 for (var i = 0; i < ancestors.length; i++) {
5509 var info = ancestors[i];
5510 info.element.scrollLeft = info.left;
5511 info.element.scrollTop = info.top;
5512 }
5513 }
5514}
5515
5516/**
5517 * @getSelection: Gets the selection bounds of a focused textarea, input or
5518 * contentEditable node.
5519 * -@input: Look up selection bounds of this input
5520 * -@return {start: selectionStart, end: selectionEnd}
5521 */
5522function getSelection$1(input) {
5523 var selection = void 0;
5524
5525 if ('selectionStart' in input) {
5526 // Modern browser with input or textarea.
5527 selection = {
5528 start: input.selectionStart,
5529 end: input.selectionEnd
5530 };
5531 } else {
5532 // Content editable or old IE textarea.
5533 selection = getOffsets(input);
5534 }
5535
5536 return selection || { start: 0, end: 0 };
5537}
5538
5539/**
5540 * @setSelection: Sets the selection bounds of a textarea or input and focuses
5541 * the input.
5542 * -@input Set selection bounds of this input or textarea
5543 * -@offsets Object of same form that is returned from get*
5544 */
5545function setSelection(input, offsets) {
5546 var start = offsets.start,
5547 end = offsets.end;
5548
5549 if (end === undefined) {
5550 end = start;
5551 }
5552
5553 if ('selectionStart' in input) {
5554 input.selectionStart = start;
5555 input.selectionEnd = Math.min(end, input.value.length);
5556 } else {
5557 setOffsets(input, offsets);
5558 }
5559}
5560
5561var skipSelectionChangeEvent = canUseDOM && 'documentMode' in document && document.documentMode <= 11;
5562
5563var eventTypes$3 = {
5564 select: {
5565 phasedRegistrationNames: {
5566 bubbled: 'onSelect',
5567 captured: 'onSelectCapture'
5568 },
5569 dependencies: [TOP_BLUR, TOP_CONTEXT_MENU, TOP_DRAG_END, TOP_FOCUS, TOP_KEY_DOWN, TOP_KEY_UP, TOP_MOUSE_DOWN, TOP_MOUSE_UP, TOP_SELECTION_CHANGE]
5570 }
5571};
5572
5573var activeElement$1 = null;
5574var activeElementInst$1 = null;
5575var lastSelection = null;
5576var mouseDown = false;
5577
5578/**
5579 * Get an object which is a unique representation of the current selection.
5580 *
5581 * The return value will not be consistent across nodes or browsers, but
5582 * two identical selections on the same node will return identical objects.
5583 *
5584 * @param {DOMElement} node
5585 * @return {object}
5586 */
5587function getSelection(node) {
5588 if ('selectionStart' in node && hasSelectionCapabilities(node)) {
5589 return {
5590 start: node.selectionStart,
5591 end: node.selectionEnd
5592 };
5593 } else {
5594 var win = node.ownerDocument && node.ownerDocument.defaultView || window;
5595 var selection = win.getSelection();
5596 return {
5597 anchorNode: selection.anchorNode,
5598 anchorOffset: selection.anchorOffset,
5599 focusNode: selection.focusNode,
5600 focusOffset: selection.focusOffset
5601 };
5602 }
5603}
5604
5605/**
5606 * Get document associated with the event target.
5607 *
5608 * @param {object} nativeEventTarget
5609 * @return {Document}
5610 */
5611function getEventTargetDocument(eventTarget) {
5612 return eventTarget.window === eventTarget ? eventTarget.document : eventTarget.nodeType === DOCUMENT_NODE ? eventTarget : eventTarget.ownerDocument;
5613}
5614
5615/**
5616 * Poll selection to see whether it's changed.
5617 *
5618 * @param {object} nativeEvent
5619 * @param {object} nativeEventTarget
5620 * @return {?SyntheticEvent}
5621 */
5622function constructSelectEvent(nativeEvent, nativeEventTarget) {
5623 // Ensure we have the right element, and that the user is not dragging a
5624 // selection (this matches native `select` event behavior). In HTML5, select
5625 // fires only on input and textarea thus if there's no focused element we
5626 // won't dispatch.
5627 var doc = getEventTargetDocument(nativeEventTarget);
5628
5629 if (mouseDown || activeElement$1 == null || activeElement$1 !== getActiveElement(doc)) {
5630 return null;
5631 }
5632
5633 // Only fire when selection has actually changed.
5634 var currentSelection = getSelection(activeElement$1);
5635 if (!lastSelection || !shallowEqual(lastSelection, currentSelection)) {
5636 lastSelection = currentSelection;
5637
5638 var syntheticEvent = SyntheticEvent.getPooled(eventTypes$3.select, activeElementInst$1, nativeEvent, nativeEventTarget);
5639
5640 syntheticEvent.type = 'select';
5641 syntheticEvent.target = activeElement$1;
5642
5643 accumulateTwoPhaseDispatches(syntheticEvent);
5644
5645 return syntheticEvent;
5646 }
5647
5648 return null;
5649}
5650
5651/**
5652 * This plugin creates an `onSelect` event that normalizes select events
5653 * across form elements.
5654 *
5655 * Supported elements are:
5656 * - input (see `isTextInputElement`)
5657 * - textarea
5658 * - contentEditable
5659 *
5660 * This differs from native browser implementations in the following ways:
5661 * - Fires on contentEditable fields as well as inputs.
5662 * - Fires for collapsed selection.
5663 * - Fires after user input.
5664 */
5665var SelectEventPlugin = {
5666 eventTypes: eventTypes$3,
5667
5668 extractEvents: function (topLevelType, targetInst, nativeEvent, nativeEventTarget) {
5669 var doc = getEventTargetDocument(nativeEventTarget);
5670 // Track whether all listeners exists for this plugin. If none exist, we do
5671 // not extract events. See #3639.
5672 if (!doc || !isListeningToAllDependencies('onSelect', doc)) {
5673 return null;
5674 }
5675
5676 var targetNode = targetInst ? getNodeFromInstance$1(targetInst) : window;
5677
5678 switch (topLevelType) {
5679 // Track the input node that has focus.
5680 case TOP_FOCUS:
5681 if (isTextInputElement(targetNode) || targetNode.contentEditable === 'true') {
5682 activeElement$1 = targetNode;
5683 activeElementInst$1 = targetInst;
5684 lastSelection = null;
5685 }
5686 break;
5687 case TOP_BLUR:
5688 activeElement$1 = null;
5689 activeElementInst$1 = null;
5690 lastSelection = null;
5691 break;
5692 // Don't fire the event while the user is dragging. This matches the
5693 // semantics of the native select event.
5694 case TOP_MOUSE_DOWN:
5695 mouseDown = true;
5696 break;
5697 case TOP_CONTEXT_MENU:
5698 case TOP_MOUSE_UP:
5699 case TOP_DRAG_END:
5700 mouseDown = false;
5701 return constructSelectEvent(nativeEvent, nativeEventTarget);
5702 // Chrome and IE fire non-standard event when selection is changed (and
5703 // sometimes when it hasn't). IE's event fires out of order with respect
5704 // to key and input events on deletion, so we discard it.
5705 //
5706 // Firefox doesn't support selectionchange, so check selection status
5707 // after each key entry. The selection changes after keydown and before
5708 // keyup, but we check on keydown as well in the case of holding down a
5709 // key, when multiple keydown events are fired but only one keyup is.
5710 // This is also our approach for IE handling, for the reason above.
5711 case TOP_SELECTION_CHANGE:
5712 if (skipSelectionChangeEvent) {
5713 break;
5714 }
5715 // falls through
5716 case TOP_KEY_DOWN:
5717 case TOP_KEY_UP:
5718 return constructSelectEvent(nativeEvent, nativeEventTarget);
5719 }
5720
5721 return null;
5722 }
5723};
5724
5725/**
5726 * Inject modules for resolving DOM hierarchy and plugin ordering.
5727 */
5728injection.injectEventPluginOrder(DOMEventPluginOrder);
5729setComponentTree(getFiberCurrentPropsFromNode$1, getInstanceFromNode$1, getNodeFromInstance$1);
5730
5731/**
5732 * Some important event plugins included by default (without having to require
5733 * them).
5734 */
5735injection.injectEventPluginsByName({
5736 SimpleEventPlugin: SimpleEventPlugin,
5737 EnterLeaveEventPlugin: EnterLeaveEventPlugin,
5738 ChangeEventPlugin: ChangeEventPlugin,
5739 SelectEventPlugin: SelectEventPlugin,
5740 BeforeInputEventPlugin: BeforeInputEventPlugin
5741});
5742
5743var didWarnSelectedSetOnOption = false;
5744var didWarnInvalidChild = false;
5745
5746function flattenChildren(children) {
5747 var content = '';
5748
5749 // Flatten children. We'll warn if they are invalid
5750 // during validateProps() which runs for hydration too.
5751 // Note that this would throw on non-element objects.
5752 // Elements are stringified (which is normally irrelevant
5753 // but matters for <fbt>).
5754 React.Children.forEach(children, function (child) {
5755 if (child == null) {
5756 return;
5757 }
5758 content += child;
5759 // Note: we don't warn about invalid children here.
5760 // Instead, this is done separately below so that
5761 // it happens during the hydration codepath too.
5762 });
5763
5764 return content;
5765}
5766
5767/**
5768 * Implements an <option> host component that warns when `selected` is set.
5769 */
5770
5771function validateProps(element, props) {
5772 {
5773 // This mirrors the codepath above, but runs for hydration too.
5774 // Warn about invalid children here so that client and hydration are consistent.
5775 // TODO: this seems like it could cause a DEV-only throw for hydration
5776 // if children contains a non-element object. We should try to avoid that.
5777 if (typeof props.children === 'object' && props.children !== null) {
5778 React.Children.forEach(props.children, function (child) {
5779 if (child == null) {
5780 return;
5781 }
5782 if (typeof child === 'string' || typeof child === 'number') {
5783 return;
5784 }
5785 if (typeof child.type !== 'string') {
5786 return;
5787 }
5788 if (!didWarnInvalidChild) {
5789 didWarnInvalidChild = true;
5790 warning$1(false, 'Only strings and numbers are supported as <option> children.');
5791 }
5792 });
5793 }
5794
5795 // TODO: Remove support for `selected` in <option>.
5796 if (props.selected != null && !didWarnSelectedSetOnOption) {
5797 warning$1(false, 'Use the `defaultValue` or `value` props on <select> instead of ' + 'setting `selected` on <option>.');
5798 didWarnSelectedSetOnOption = true;
5799 }
5800 }
5801}
5802
5803function postMountWrapper$1(element, props) {
5804 // value="" should make a value attribute (#6219)
5805 if (props.value != null) {
5806 element.setAttribute('value', toString(getToStringValue(props.value)));
5807 }
5808}
5809
5810function getHostProps$1(element, props) {
5811 var hostProps = _assign({ children: undefined }, props);
5812 var content = flattenChildren(props.children);
5813
5814 if (content) {
5815 hostProps.children = content;
5816 }
5817
5818 return hostProps;
5819}
5820
5821// TODO: direct imports like some-package/src/* are bad. Fix me.
5822var didWarnValueDefaultValue$1 = void 0;
5823
5824{
5825 didWarnValueDefaultValue$1 = false;
5826}
5827
5828function getDeclarationErrorAddendum() {
5829 var ownerName = getCurrentFiberOwnerNameInDevOrNull();
5830 if (ownerName) {
5831 return '\n\nCheck the render method of `' + ownerName + '`.';
5832 }
5833 return '';
5834}
5835
5836var valuePropNames = ['value', 'defaultValue'];
5837
5838/**
5839 * Validation function for `value` and `defaultValue`.
5840 */
5841function checkSelectPropTypes(props) {
5842 ReactControlledValuePropTypes.checkPropTypes('select', props);
5843
5844 for (var i = 0; i < valuePropNames.length; i++) {
5845 var propName = valuePropNames[i];
5846 if (props[propName] == null) {
5847 continue;
5848 }
5849 var isArray = Array.isArray(props[propName]);
5850 if (props.multiple && !isArray) {
5851 warning$1(false, 'The `%s` prop supplied to <select> must be an array if ' + '`multiple` is true.%s', propName, getDeclarationErrorAddendum());
5852 } else if (!props.multiple && isArray) {
5853 warning$1(false, 'The `%s` prop supplied to <select> must be a scalar ' + 'value if `multiple` is false.%s', propName, getDeclarationErrorAddendum());
5854 }
5855 }
5856}
5857
5858function updateOptions(node, multiple, propValue, setDefaultSelected) {
5859 var options = node.options;
5860
5861 if (multiple) {
5862 var selectedValues = propValue;
5863 var selectedValue = {};
5864 for (var i = 0; i < selectedValues.length; i++) {
5865 // Prefix to avoid chaos with special keys.
5866 selectedValue['$' + selectedValues[i]] = true;
5867 }
5868 for (var _i = 0; _i < options.length; _i++) {
5869 var selected = selectedValue.hasOwnProperty('$' + options[_i].value);
5870 if (options[_i].selected !== selected) {
5871 options[_i].selected = selected;
5872 }
5873 if (selected && setDefaultSelected) {
5874 options[_i].defaultSelected = true;
5875 }
5876 }
5877 } else {
5878 // Do not set `select.value` as exact behavior isn't consistent across all
5879 // browsers for all cases.
5880 var _selectedValue = toString(getToStringValue(propValue));
5881 var defaultSelected = null;
5882 for (var _i2 = 0; _i2 < options.length; _i2++) {
5883 if (options[_i2].value === _selectedValue) {
5884 options[_i2].selected = true;
5885 if (setDefaultSelected) {
5886 options[_i2].defaultSelected = true;
5887 }
5888 return;
5889 }
5890 if (defaultSelected === null && !options[_i2].disabled) {
5891 defaultSelected = options[_i2];
5892 }
5893 }
5894 if (defaultSelected !== null) {
5895 defaultSelected.selected = true;
5896 }
5897 }
5898}
5899
5900/**
5901 * Implements a <select> host component that allows optionally setting the
5902 * props `value` and `defaultValue`. If `multiple` is false, the prop must be a
5903 * stringable. If `multiple` is true, the prop must be an array of stringables.
5904 *
5905 * If `value` is not supplied (or null/undefined), user actions that change the
5906 * selected option will trigger updates to the rendered options.
5907 *
5908 * If it is supplied (and not null/undefined), the rendered options will not
5909 * update in response to user actions. Instead, the `value` prop must change in
5910 * order for the rendered options to update.
5911 *
5912 * If `defaultValue` is provided, any options with the supplied values will be
5913 * selected.
5914 */
5915
5916function getHostProps$2(element, props) {
5917 return _assign({}, props, {
5918 value: undefined
5919 });
5920}
5921
5922function initWrapperState$1(element, props) {
5923 var node = element;
5924 {
5925 checkSelectPropTypes(props);
5926 }
5927
5928 node._wrapperState = {
5929 wasMultiple: !!props.multiple
5930 };
5931
5932 {
5933 if (props.value !== undefined && props.defaultValue !== undefined && !didWarnValueDefaultValue$1) {
5934 warning$1(false, 'Select elements must be either controlled or uncontrolled ' + '(specify either the value prop, or the defaultValue prop, but not ' + 'both). Decide between using a controlled or uncontrolled select ' + 'element and remove one of these props. More info: ' + 'https://fb.me/react-controlled-components');
5935 didWarnValueDefaultValue$1 = true;
5936 }
5937 }
5938}
5939
5940function postMountWrapper$2(element, props) {
5941 var node = element;
5942 node.multiple = !!props.multiple;
5943 var value = props.value;
5944 if (value != null) {
5945 updateOptions(node, !!props.multiple, value, false);
5946 } else if (props.defaultValue != null) {
5947 updateOptions(node, !!props.multiple, props.defaultValue, true);
5948 }
5949}
5950
5951function postUpdateWrapper(element, props) {
5952 var node = element;
5953 var wasMultiple = node._wrapperState.wasMultiple;
5954 node._wrapperState.wasMultiple = !!props.multiple;
5955
5956 var value = props.value;
5957 if (value != null) {
5958 updateOptions(node, !!props.multiple, value, false);
5959 } else if (wasMultiple !== !!props.multiple) {
5960 // For simplicity, reapply `defaultValue` if `multiple` is toggled.
5961 if (props.defaultValue != null) {
5962 updateOptions(node, !!props.multiple, props.defaultValue, true);
5963 } else {
5964 // Revert the select back to its default unselected state.
5965 updateOptions(node, !!props.multiple, props.multiple ? [] : '', false);
5966 }
5967 }
5968}
5969
5970function restoreControlledState$2(element, props) {
5971 var node = element;
5972 var value = props.value;
5973
5974 if (value != null) {
5975 updateOptions(node, !!props.multiple, value, false);
5976 }
5977}
5978
5979var didWarnValDefaultVal = false;
5980
5981/**
5982 * Implements a <textarea> host component that allows setting `value`, and
5983 * `defaultValue`. This differs from the traditional DOM API because value is
5984 * usually set as PCDATA children.
5985 *
5986 * If `value` is not supplied (or null/undefined), user actions that affect the
5987 * value will trigger updates to the element.
5988 *
5989 * If `value` is supplied (and not null/undefined), the rendered element will
5990 * not trigger updates to the element. Instead, the `value` prop must change in
5991 * order for the rendered element to be updated.
5992 *
5993 * The rendered element will be initialized with an empty value, the prop
5994 * `defaultValue` if specified, or the children content (deprecated).
5995 */
5996
5997function getHostProps$3(element, props) {
5998 var node = element;
5999 !(props.dangerouslySetInnerHTML == null) ? invariant(false, '`dangerouslySetInnerHTML` does not make sense on <textarea>.') : void 0;
6000
6001 // Always set children to the same thing. In IE9, the selection range will
6002 // get reset if `textContent` is mutated. We could add a check in setTextContent
6003 // to only set the value if/when the value differs from the node value (which would
6004 // completely solve this IE9 bug), but Sebastian+Sophie seemed to like this
6005 // solution. The value can be a boolean or object so that's why it's forced
6006 // to be a string.
6007 var hostProps = _assign({}, props, {
6008 value: undefined,
6009 defaultValue: undefined,
6010 children: toString(node._wrapperState.initialValue)
6011 });
6012
6013 return hostProps;
6014}
6015
6016function initWrapperState$2(element, props) {
6017 var node = element;
6018 {
6019 ReactControlledValuePropTypes.checkPropTypes('textarea', props);
6020 if (props.value !== undefined && props.defaultValue !== undefined && !didWarnValDefaultVal) {
6021 warning$1(false, '%s contains a textarea with both value and defaultValue props. ' + 'Textarea elements must be either controlled or uncontrolled ' + '(specify either the value prop, or the defaultValue prop, but not ' + 'both). Decide between using a controlled or uncontrolled textarea ' + 'and remove one of these props. More info: ' + 'https://fb.me/react-controlled-components', getCurrentFiberOwnerNameInDevOrNull() || 'A component');
6022 didWarnValDefaultVal = true;
6023 }
6024 }
6025
6026 var initialValue = props.value;
6027
6028 // Only bother fetching default value if we're going to use it
6029 if (initialValue == null) {
6030 var defaultValue = props.defaultValue;
6031 // TODO (yungsters): Remove support for children content in <textarea>.
6032 var children = props.children;
6033 if (children != null) {
6034 {
6035 warning$1(false, 'Use the `defaultValue` or `value` props instead of setting ' + 'children on <textarea>.');
6036 }
6037 !(defaultValue == null) ? invariant(false, 'If you supply `defaultValue` on a <textarea>, do not pass children.') : void 0;
6038 if (Array.isArray(children)) {
6039 !(children.length <= 1) ? invariant(false, '<textarea> can only have at most one child.') : void 0;
6040 children = children[0];
6041 }
6042
6043 defaultValue = children;
6044 }
6045 if (defaultValue == null) {
6046 defaultValue = '';
6047 }
6048 initialValue = defaultValue;
6049 }
6050
6051 node._wrapperState = {
6052 initialValue: getToStringValue(initialValue)
6053 };
6054}
6055
6056function updateWrapper$1(element, props) {
6057 var node = element;
6058 var value = getToStringValue(props.value);
6059 var defaultValue = getToStringValue(props.defaultValue);
6060 if (value != null) {
6061 // Cast `value` to a string to ensure the value is set correctly. While
6062 // browsers typically do this as necessary, jsdom doesn't.
6063 var newValue = toString(value);
6064 // To avoid side effects (such as losing text selection), only set value if changed
6065 if (newValue !== node.value) {
6066 node.value = newValue;
6067 }
6068 if (props.defaultValue == null && node.defaultValue !== newValue) {
6069 node.defaultValue = newValue;
6070 }
6071 }
6072 if (defaultValue != null) {
6073 node.defaultValue = toString(defaultValue);
6074 }
6075}
6076
6077function postMountWrapper$3(element, props) {
6078 var node = element;
6079 // This is in postMount because we need access to the DOM node, which is not
6080 // available until after the component has mounted.
6081 var textContent = node.textContent;
6082
6083 // Only set node.value if textContent is equal to the expected
6084 // initial value. In IE10/IE11 there is a bug where the placeholder attribute
6085 // will populate textContent as well.
6086 // https://developer.microsoft.com/microsoft-edge/platform/issues/101525/
6087 if (textContent === node._wrapperState.initialValue) {
6088 node.value = textContent;
6089 }
6090}
6091
6092function restoreControlledState$3(element, props) {
6093 // DOM component is still mounted; update
6094 updateWrapper$1(element, props);
6095}
6096
6097var HTML_NAMESPACE$1 = 'http://www.w3.org/1999/xhtml';
6098var MATH_NAMESPACE = 'http://www.w3.org/1998/Math/MathML';
6099var SVG_NAMESPACE = 'http://www.w3.org/2000/svg';
6100
6101var Namespaces = {
6102 html: HTML_NAMESPACE$1,
6103 mathml: MATH_NAMESPACE,
6104 svg: SVG_NAMESPACE
6105};
6106
6107// Assumes there is no parent namespace.
6108function getIntrinsicNamespace(type) {
6109 switch (type) {
6110 case 'svg':
6111 return SVG_NAMESPACE;
6112 case 'math':
6113 return MATH_NAMESPACE;
6114 default:
6115 return HTML_NAMESPACE$1;
6116 }
6117}
6118
6119function getChildNamespace(parentNamespace, type) {
6120 if (parentNamespace == null || parentNamespace === HTML_NAMESPACE$1) {
6121 // No (or default) parent namespace: potential entry point.
6122 return getIntrinsicNamespace(type);
6123 }
6124 if (parentNamespace === SVG_NAMESPACE && type === 'foreignObject') {
6125 // We're leaving SVG.
6126 return HTML_NAMESPACE$1;
6127 }
6128 // By default, pass namespace below.
6129 return parentNamespace;
6130}
6131
6132/* globals MSApp */
6133
6134/**
6135 * Create a function which has 'unsafe' privileges (required by windows8 apps)
6136 */
6137var createMicrosoftUnsafeLocalFunction = function (func) {
6138 if (typeof MSApp !== 'undefined' && MSApp.execUnsafeLocalFunction) {
6139 return function (arg0, arg1, arg2, arg3) {
6140 MSApp.execUnsafeLocalFunction(function () {
6141 return func(arg0, arg1, arg2, arg3);
6142 });
6143 };
6144 } else {
6145 return func;
6146 }
6147};
6148
6149// SVG temp container for IE lacking innerHTML
6150var reusableSVGContainer = void 0;
6151
6152/**
6153 * Set the innerHTML property of a node
6154 *
6155 * @param {DOMElement} node
6156 * @param {string} html
6157 * @internal
6158 */
6159var setInnerHTML = createMicrosoftUnsafeLocalFunction(function (node, html) {
6160 // IE does not have innerHTML for SVG nodes, so instead we inject the
6161 // new markup in a temp node and then move the child nodes across into
6162 // the target node
6163
6164 if (node.namespaceURI === Namespaces.svg && !('innerHTML' in node)) {
6165 reusableSVGContainer = reusableSVGContainer || document.createElement('div');
6166 reusableSVGContainer.innerHTML = '<svg>' + html + '</svg>';
6167 var svgNode = reusableSVGContainer.firstChild;
6168 while (node.firstChild) {
6169 node.removeChild(node.firstChild);
6170 }
6171 while (svgNode.firstChild) {
6172 node.appendChild(svgNode.firstChild);
6173 }
6174 } else {
6175 node.innerHTML = html;
6176 }
6177});
6178
6179/**
6180 * Set the textContent property of a node. For text updates, it's faster
6181 * to set the `nodeValue` of the Text node directly instead of using
6182 * `.textContent` which will remove the existing node and create a new one.
6183 *
6184 * @param {DOMElement} node
6185 * @param {string} text
6186 * @internal
6187 */
6188var setTextContent = function (node, text) {
6189 if (text) {
6190 var firstChild = node.firstChild;
6191
6192 if (firstChild && firstChild === node.lastChild && firstChild.nodeType === TEXT_NODE) {
6193 firstChild.nodeValue = text;
6194 return;
6195 }
6196 }
6197 node.textContent = text;
6198};
6199
6200// List derived from Gecko source code:
6201// https://github.com/mozilla/gecko-dev/blob/4e638efc71/layout/style/test/property_database.js
6202var shorthandToLonghand = {
6203 animation: ['animationDelay', 'animationDirection', 'animationDuration', 'animationFillMode', 'animationIterationCount', 'animationName', 'animationPlayState', 'animationTimingFunction'],
6204 background: ['backgroundAttachment', 'backgroundClip', 'backgroundColor', 'backgroundImage', 'backgroundOrigin', 'backgroundPositionX', 'backgroundPositionY', 'backgroundRepeat', 'backgroundSize'],
6205 backgroundPosition: ['backgroundPositionX', 'backgroundPositionY'],
6206 border: ['borderBottomColor', 'borderBottomStyle', 'borderBottomWidth', 'borderImageOutset', 'borderImageRepeat', 'borderImageSlice', 'borderImageSource', 'borderImageWidth', 'borderLeftColor', 'borderLeftStyle', 'borderLeftWidth', 'borderRightColor', 'borderRightStyle', 'borderRightWidth', 'borderTopColor', 'borderTopStyle', 'borderTopWidth'],
6207 borderBlockEnd: ['borderBlockEndColor', 'borderBlockEndStyle', 'borderBlockEndWidth'],
6208 borderBlockStart: ['borderBlockStartColor', 'borderBlockStartStyle', 'borderBlockStartWidth'],
6209 borderBottom: ['borderBottomColor', 'borderBottomStyle', 'borderBottomWidth'],
6210 borderColor: ['borderBottomColor', 'borderLeftColor', 'borderRightColor', 'borderTopColor'],
6211 borderImage: ['borderImageOutset', 'borderImageRepeat', 'borderImageSlice', 'borderImageSource', 'borderImageWidth'],
6212 borderInlineEnd: ['borderInlineEndColor', 'borderInlineEndStyle', 'borderInlineEndWidth'],
6213 borderInlineStart: ['borderInlineStartColor', 'borderInlineStartStyle', 'borderInlineStartWidth'],
6214 borderLeft: ['borderLeftColor', 'borderLeftStyle', 'borderLeftWidth'],
6215 borderRadius: ['borderBottomLeftRadius', 'borderBottomRightRadius', 'borderTopLeftRadius', 'borderTopRightRadius'],
6216 borderRight: ['borderRightColor', 'borderRightStyle', 'borderRightWidth'],
6217 borderStyle: ['borderBottomStyle', 'borderLeftStyle', 'borderRightStyle', 'borderTopStyle'],
6218 borderTop: ['borderTopColor', 'borderTopStyle', 'borderTopWidth'],
6219 borderWidth: ['borderBottomWidth', 'borderLeftWidth', 'borderRightWidth', 'borderTopWidth'],
6220 columnRule: ['columnRuleColor', 'columnRuleStyle', 'columnRuleWidth'],
6221 columns: ['columnCount', 'columnWidth'],
6222 flex: ['flexBasis', 'flexGrow', 'flexShrink'],
6223 flexFlow: ['flexDirection', 'flexWrap'],
6224 font: ['fontFamily', 'fontFeatureSettings', 'fontKerning', 'fontLanguageOverride', 'fontSize', 'fontSizeAdjust', 'fontStretch', 'fontStyle', 'fontVariant', 'fontVariantAlternates', 'fontVariantCaps', 'fontVariantEastAsian', 'fontVariantLigatures', 'fontVariantNumeric', 'fontVariantPosition', 'fontWeight', 'lineHeight'],
6225 fontVariant: ['fontVariantAlternates', 'fontVariantCaps', 'fontVariantEastAsian', 'fontVariantLigatures', 'fontVariantNumeric', 'fontVariantPosition'],
6226 gap: ['columnGap', 'rowGap'],
6227 grid: ['gridAutoColumns', 'gridAutoFlow', 'gridAutoRows', 'gridTemplateAreas', 'gridTemplateColumns', 'gridTemplateRows'],
6228 gridArea: ['gridColumnEnd', 'gridColumnStart', 'gridRowEnd', 'gridRowStart'],
6229 gridColumn: ['gridColumnEnd', 'gridColumnStart'],
6230 gridColumnGap: ['columnGap'],
6231 gridGap: ['columnGap', 'rowGap'],
6232 gridRow: ['gridRowEnd', 'gridRowStart'],
6233 gridRowGap: ['rowGap'],
6234 gridTemplate: ['gridTemplateAreas', 'gridTemplateColumns', 'gridTemplateRows'],
6235 listStyle: ['listStyleImage', 'listStylePosition', 'listStyleType'],
6236 margin: ['marginBottom', 'marginLeft', 'marginRight', 'marginTop'],
6237 marker: ['markerEnd', 'markerMid', 'markerStart'],
6238 mask: ['maskClip', 'maskComposite', 'maskImage', 'maskMode', 'maskOrigin', 'maskPositionX', 'maskPositionY', 'maskRepeat', 'maskSize'],
6239 maskPosition: ['maskPositionX', 'maskPositionY'],
6240 outline: ['outlineColor', 'outlineStyle', 'outlineWidth'],
6241 overflow: ['overflowX', 'overflowY'],
6242 padding: ['paddingBottom', 'paddingLeft', 'paddingRight', 'paddingTop'],
6243 placeContent: ['alignContent', 'justifyContent'],
6244 placeItems: ['alignItems', 'justifyItems'],
6245 placeSelf: ['alignSelf', 'justifySelf'],
6246 textDecoration: ['textDecorationColor', 'textDecorationLine', 'textDecorationStyle'],
6247 textEmphasis: ['textEmphasisColor', 'textEmphasisStyle'],
6248 transition: ['transitionDelay', 'transitionDuration', 'transitionProperty', 'transitionTimingFunction'],
6249 wordWrap: ['overflowWrap']
6250};
6251
6252/**
6253 * CSS properties which accept numbers but are not in units of "px".
6254 */
6255var isUnitlessNumber = {
6256 animationIterationCount: true,
6257 borderImageOutset: true,
6258 borderImageSlice: true,
6259 borderImageWidth: true,
6260 boxFlex: true,
6261 boxFlexGroup: true,
6262 boxOrdinalGroup: true,
6263 columnCount: true,
6264 columns: true,
6265 flex: true,
6266 flexGrow: true,
6267 flexPositive: true,
6268 flexShrink: true,
6269 flexNegative: true,
6270 flexOrder: true,
6271 gridArea: true,
6272 gridRow: true,
6273 gridRowEnd: true,
6274 gridRowSpan: true,
6275 gridRowStart: true,
6276 gridColumn: true,
6277 gridColumnEnd: true,
6278 gridColumnSpan: true,
6279 gridColumnStart: true,
6280 fontWeight: true,
6281 lineClamp: true,
6282 lineHeight: true,
6283 opacity: true,
6284 order: true,
6285 orphans: true,
6286 tabSize: true,
6287 widows: true,
6288 zIndex: true,
6289 zoom: true,
6290
6291 // SVG-related properties
6292 fillOpacity: true,
6293 floodOpacity: true,
6294 stopOpacity: true,
6295 strokeDasharray: true,
6296 strokeDashoffset: true,
6297 strokeMiterlimit: true,
6298 strokeOpacity: true,
6299 strokeWidth: true
6300};
6301
6302/**
6303 * @param {string} prefix vendor-specific prefix, eg: Webkit
6304 * @param {string} key style name, eg: transitionDuration
6305 * @return {string} style name prefixed with `prefix`, properly camelCased, eg:
6306 * WebkitTransitionDuration
6307 */
6308function prefixKey(prefix, key) {
6309 return prefix + key.charAt(0).toUpperCase() + key.substring(1);
6310}
6311
6312/**
6313 * Support style names that may come passed in prefixed by adding permutations
6314 * of vendor prefixes.
6315 */
6316var prefixes = ['Webkit', 'ms', 'Moz', 'O'];
6317
6318// Using Object.keys here, or else the vanilla for-in loop makes IE8 go into an
6319// infinite loop, because it iterates over the newly added props too.
6320Object.keys(isUnitlessNumber).forEach(function (prop) {
6321 prefixes.forEach(function (prefix) {
6322 isUnitlessNumber[prefixKey(prefix, prop)] = isUnitlessNumber[prop];
6323 });
6324});
6325
6326/**
6327 * Convert a value into the proper css writable value. The style name `name`
6328 * should be logical (no hyphens), as specified
6329 * in `CSSProperty.isUnitlessNumber`.
6330 *
6331 * @param {string} name CSS property name such as `topMargin`.
6332 * @param {*} value CSS property value such as `10px`.
6333 * @return {string} Normalized style value with dimensions applied.
6334 */
6335function dangerousStyleValue(name, value, isCustomProperty) {
6336 // Note that we've removed escapeTextForBrowser() calls here since the
6337 // whole string will be escaped when the attribute is injected into
6338 // the markup. If you provide unsafe user data here they can inject
6339 // arbitrary CSS which may be problematic (I couldn't repro this):
6340 // https://www.owasp.org/index.php/XSS_Filter_Evasion_Cheat_Sheet
6341 // http://www.thespanner.co.uk/2007/11/26/ultimate-xss-css-injection/
6342 // This is not an XSS hole but instead a potential CSS injection issue
6343 // which has lead to a greater discussion about how we're going to
6344 // trust URLs moving forward. See #2115901
6345
6346 var isEmpty = value == null || typeof value === 'boolean' || value === '';
6347 if (isEmpty) {
6348 return '';
6349 }
6350
6351 if (!isCustomProperty && typeof value === 'number' && value !== 0 && !(isUnitlessNumber.hasOwnProperty(name) && isUnitlessNumber[name])) {
6352 return value + 'px'; // Presumes implicit 'px' suffix for unitless numbers
6353 }
6354
6355 return ('' + value).trim();
6356}
6357
6358var uppercasePattern = /([A-Z])/g;
6359var msPattern = /^ms-/;
6360
6361/**
6362 * Hyphenates a camelcased CSS property name, for example:
6363 *
6364 * > hyphenateStyleName('backgroundColor')
6365 * < "background-color"
6366 * > hyphenateStyleName('MozTransition')
6367 * < "-moz-transition"
6368 * > hyphenateStyleName('msTransition')
6369 * < "-ms-transition"
6370 *
6371 * As Modernizr suggests (http://modernizr.com/docs/#prefixed), an `ms` prefix
6372 * is converted to `-ms-`.
6373 */
6374function hyphenateStyleName(name) {
6375 return name.replace(uppercasePattern, '-$1').toLowerCase().replace(msPattern, '-ms-');
6376}
6377
6378var warnValidStyle = function () {};
6379
6380{
6381 // 'msTransform' is correct, but the other prefixes should be capitalized
6382 var badVendoredStyleNamePattern = /^(?:webkit|moz|o)[A-Z]/;
6383 var msPattern$1 = /^-ms-/;
6384 var hyphenPattern = /-(.)/g;
6385
6386 // style values shouldn't contain a semicolon
6387 var badStyleValueWithSemicolonPattern = /;\s*$/;
6388
6389 var warnedStyleNames = {};
6390 var warnedStyleValues = {};
6391 var warnedForNaNValue = false;
6392 var warnedForInfinityValue = false;
6393
6394 var camelize = function (string) {
6395 return string.replace(hyphenPattern, function (_, character) {
6396 return character.toUpperCase();
6397 });
6398 };
6399
6400 var warnHyphenatedStyleName = function (name) {
6401 if (warnedStyleNames.hasOwnProperty(name) && warnedStyleNames[name]) {
6402 return;
6403 }
6404
6405 warnedStyleNames[name] = true;
6406 warning$1(false, 'Unsupported style property %s. Did you mean %s?', name,
6407 // As Andi Smith suggests
6408 // (http://www.andismith.com/blog/2012/02/modernizr-prefixed/), an `-ms` prefix
6409 // is converted to lowercase `ms`.
6410 camelize(name.replace(msPattern$1, 'ms-')));
6411 };
6412
6413 var warnBadVendoredStyleName = function (name) {
6414 if (warnedStyleNames.hasOwnProperty(name) && warnedStyleNames[name]) {
6415 return;
6416 }
6417
6418 warnedStyleNames[name] = true;
6419 warning$1(false, 'Unsupported vendor-prefixed style property %s. Did you mean %s?', name, name.charAt(0).toUpperCase() + name.slice(1));
6420 };
6421
6422 var warnStyleValueWithSemicolon = function (name, value) {
6423 if (warnedStyleValues.hasOwnProperty(value) && warnedStyleValues[value]) {
6424 return;
6425 }
6426
6427 warnedStyleValues[value] = true;
6428 warning$1(false, "Style property values shouldn't contain a semicolon. " + 'Try "%s: %s" instead.', name, value.replace(badStyleValueWithSemicolonPattern, ''));
6429 };
6430
6431 var warnStyleValueIsNaN = function (name, value) {
6432 if (warnedForNaNValue) {
6433 return;
6434 }
6435
6436 warnedForNaNValue = true;
6437 warning$1(false, '`NaN` is an invalid value for the `%s` css style property.', name);
6438 };
6439
6440 var warnStyleValueIsInfinity = function (name, value) {
6441 if (warnedForInfinityValue) {
6442 return;
6443 }
6444
6445 warnedForInfinityValue = true;
6446 warning$1(false, '`Infinity` is an invalid value for the `%s` css style property.', name);
6447 };
6448
6449 warnValidStyle = function (name, value) {
6450 if (name.indexOf('-') > -1) {
6451 warnHyphenatedStyleName(name);
6452 } else if (badVendoredStyleNamePattern.test(name)) {
6453 warnBadVendoredStyleName(name);
6454 } else if (badStyleValueWithSemicolonPattern.test(value)) {
6455 warnStyleValueWithSemicolon(name, value);
6456 }
6457
6458 if (typeof value === 'number') {
6459 if (isNaN(value)) {
6460 warnStyleValueIsNaN(name, value);
6461 } else if (!isFinite(value)) {
6462 warnStyleValueIsInfinity(name, value);
6463 }
6464 }
6465 };
6466}
6467
6468var warnValidStyle$1 = warnValidStyle;
6469
6470/**
6471 * Operations for dealing with CSS properties.
6472 */
6473
6474/**
6475 * This creates a string that is expected to be equivalent to the style
6476 * attribute generated by server-side rendering. It by-passes warnings and
6477 * security checks so it's not safe to use this value for anything other than
6478 * comparison. It is only used in DEV for SSR validation.
6479 */
6480function createDangerousStringForStyles(styles) {
6481 {
6482 var serialized = '';
6483 var delimiter = '';
6484 for (var styleName in styles) {
6485 if (!styles.hasOwnProperty(styleName)) {
6486 continue;
6487 }
6488 var styleValue = styles[styleName];
6489 if (styleValue != null) {
6490 var isCustomProperty = styleName.indexOf('--') === 0;
6491 serialized += delimiter + hyphenateStyleName(styleName) + ':';
6492 serialized += dangerousStyleValue(styleName, styleValue, isCustomProperty);
6493
6494 delimiter = ';';
6495 }
6496 }
6497 return serialized || null;
6498 }
6499}
6500
6501/**
6502 * Sets the value for multiple styles on a node. If a value is specified as
6503 * '' (empty string), the corresponding style property will be unset.
6504 *
6505 * @param {DOMElement} node
6506 * @param {object} styles
6507 */
6508function setValueForStyles(node, styles) {
6509 var style = node.style;
6510 for (var styleName in styles) {
6511 if (!styles.hasOwnProperty(styleName)) {
6512 continue;
6513 }
6514 var isCustomProperty = styleName.indexOf('--') === 0;
6515 {
6516 if (!isCustomProperty) {
6517 warnValidStyle$1(styleName, styles[styleName]);
6518 }
6519 }
6520 var styleValue = dangerousStyleValue(styleName, styles[styleName], isCustomProperty);
6521 if (styleName === 'float') {
6522 styleName = 'cssFloat';
6523 }
6524 if (isCustomProperty) {
6525 style.setProperty(styleName, styleValue);
6526 } else {
6527 style[styleName] = styleValue;
6528 }
6529 }
6530}
6531
6532function isValueEmpty(value) {
6533 return value == null || typeof value === 'boolean' || value === '';
6534}
6535
6536/**
6537 * Given {color: 'red', overflow: 'hidden'} returns {
6538 * color: 'color',
6539 * overflowX: 'overflow',
6540 * overflowY: 'overflow',
6541 * }. This can be read as "the overflowY property was set by the overflow
6542 * shorthand". That is, the values are the property that each was derived from.
6543 */
6544function expandShorthandMap(styles) {
6545 var expanded = {};
6546 for (var key in styles) {
6547 var longhands = shorthandToLonghand[key] || [key];
6548 for (var i = 0; i < longhands.length; i++) {
6549 expanded[longhands[i]] = key;
6550 }
6551 }
6552 return expanded;
6553}
6554
6555/**
6556 * When mixing shorthand and longhand property names, we warn during updates if
6557 * we expect an incorrect result to occur. In particular, we warn for:
6558 *
6559 * Updating a shorthand property (longhand gets overwritten):
6560 * {font: 'foo', fontVariant: 'bar'} -> {font: 'baz', fontVariant: 'bar'}
6561 * becomes .style.font = 'baz'
6562 * Removing a shorthand property (longhand gets lost too):
6563 * {font: 'foo', fontVariant: 'bar'} -> {fontVariant: 'bar'}
6564 * becomes .style.font = ''
6565 * Removing a longhand property (should revert to shorthand; doesn't):
6566 * {font: 'foo', fontVariant: 'bar'} -> {font: 'foo'}
6567 * becomes .style.fontVariant = ''
6568 */
6569function validateShorthandPropertyCollisionInDev(styleUpdates, nextStyles) {
6570 if (!warnAboutShorthandPropertyCollision) {
6571 return;
6572 }
6573
6574 if (!nextStyles) {
6575 return;
6576 }
6577
6578 var expandedUpdates = expandShorthandMap(styleUpdates);
6579 var expandedStyles = expandShorthandMap(nextStyles);
6580 var warnedAbout = {};
6581 for (var key in expandedUpdates) {
6582 var originalKey = expandedUpdates[key];
6583 var correctOriginalKey = expandedStyles[key];
6584 if (correctOriginalKey && originalKey !== correctOriginalKey) {
6585 var warningKey = originalKey + ',' + correctOriginalKey;
6586 if (warnedAbout[warningKey]) {
6587 continue;
6588 }
6589 warnedAbout[warningKey] = true;
6590 warning$1(false, '%s a style property during rerender (%s) when a ' + 'conflicting property is set (%s) can lead to styling bugs. To ' + "avoid this, don't mix shorthand and non-shorthand properties " + 'for the same value; instead, replace the shorthand with ' + 'separate values.', isValueEmpty(styleUpdates[originalKey]) ? 'Removing' : 'Updating', originalKey, correctOriginalKey);
6591 }
6592 }
6593}
6594
6595// For HTML, certain tags should omit their close tag. We keep a whitelist for
6596// those special-case tags.
6597
6598var omittedCloseTags = {
6599 area: true,
6600 base: true,
6601 br: true,
6602 col: true,
6603 embed: true,
6604 hr: true,
6605 img: true,
6606 input: true,
6607 keygen: true,
6608 link: true,
6609 meta: true,
6610 param: true,
6611 source: true,
6612 track: true,
6613 wbr: true
6614 // NOTE: menuitem's close tag should be omitted, but that causes problems.
6615};
6616
6617// For HTML, certain tags cannot have children. This has the same purpose as
6618// `omittedCloseTags` except that `menuitem` should still have its closing tag.
6619
6620var voidElementTags = _assign({
6621 menuitem: true
6622}, omittedCloseTags);
6623
6624// TODO: We can remove this if we add invariantWithStack()
6625// or add stack by default to invariants where possible.
6626var HTML$1 = '__html';
6627
6628var ReactDebugCurrentFrame$2 = null;
6629{
6630 ReactDebugCurrentFrame$2 = ReactSharedInternals.ReactDebugCurrentFrame;
6631}
6632
6633function assertValidProps(tag, props) {
6634 if (!props) {
6635 return;
6636 }
6637 // Note the use of `==` which checks for null or undefined.
6638 if (voidElementTags[tag]) {
6639 !(props.children == null && props.dangerouslySetInnerHTML == null) ? invariant(false, '%s is a void element tag and must neither have `children` nor use `dangerouslySetInnerHTML`.%s', tag, ReactDebugCurrentFrame$2.getStackAddendum()) : void 0;
6640 }
6641 if (props.dangerouslySetInnerHTML != null) {
6642 !(props.children == null) ? invariant(false, 'Can only set one of `children` or `props.dangerouslySetInnerHTML`.') : void 0;
6643 !(typeof props.dangerouslySetInnerHTML === 'object' && HTML$1 in props.dangerouslySetInnerHTML) ? invariant(false, '`props.dangerouslySetInnerHTML` must be in the form `{__html: ...}`. Please visit https://fb.me/react-invariant-dangerously-set-inner-html for more information.') : void 0;
6644 }
6645 {
6646 !(props.suppressContentEditableWarning || !props.contentEditable || props.children == null) ? warning$1(false, 'A component is `contentEditable` and contains `children` managed by ' + 'React. It is now your responsibility to guarantee that none of ' + 'those nodes are unexpectedly modified or duplicated. This is ' + 'probably not intentional.') : void 0;
6647 }
6648 !(props.style == null || typeof props.style === 'object') ? invariant(false, 'The `style` prop expects a mapping from style properties to values, not a string. For example, style={{marginRight: spacing + \'em\'}} when using JSX.%s', ReactDebugCurrentFrame$2.getStackAddendum()) : void 0;
6649}
6650
6651function isCustomComponent(tagName, props) {
6652 if (tagName.indexOf('-') === -1) {
6653 return typeof props.is === 'string';
6654 }
6655 switch (tagName) {
6656 // These are reserved SVG and MathML elements.
6657 // We don't mind this whitelist too much because we expect it to never grow.
6658 // The alternative is to track the namespace in a few places which is convoluted.
6659 // https://w3c.github.io/webcomponents/spec/custom/#custom-elements-core-concepts
6660 case 'annotation-xml':
6661 case 'color-profile':
6662 case 'font-face':
6663 case 'font-face-src':
6664 case 'font-face-uri':
6665 case 'font-face-format':
6666 case 'font-face-name':
6667 case 'missing-glyph':
6668 return false;
6669 default:
6670 return true;
6671 }
6672}
6673
6674// When adding attributes to the HTML or SVG whitelist, be sure to
6675// also add them to this module to ensure casing and incorrect name
6676// warnings.
6677var possibleStandardNames = {
6678 // HTML
6679 accept: 'accept',
6680 acceptcharset: 'acceptCharset',
6681 'accept-charset': 'acceptCharset',
6682 accesskey: 'accessKey',
6683 action: 'action',
6684 allowfullscreen: 'allowFullScreen',
6685 alt: 'alt',
6686 as: 'as',
6687 async: 'async',
6688 autocapitalize: 'autoCapitalize',
6689 autocomplete: 'autoComplete',
6690 autocorrect: 'autoCorrect',
6691 autofocus: 'autoFocus',
6692 autoplay: 'autoPlay',
6693 autosave: 'autoSave',
6694 capture: 'capture',
6695 cellpadding: 'cellPadding',
6696 cellspacing: 'cellSpacing',
6697 challenge: 'challenge',
6698 charset: 'charSet',
6699 checked: 'checked',
6700 children: 'children',
6701 cite: 'cite',
6702 class: 'className',
6703 classid: 'classID',
6704 classname: 'className',
6705 cols: 'cols',
6706 colspan: 'colSpan',
6707 content: 'content',
6708 contenteditable: 'contentEditable',
6709 contextmenu: 'contextMenu',
6710 controls: 'controls',
6711 controlslist: 'controlsList',
6712 coords: 'coords',
6713 crossorigin: 'crossOrigin',
6714 dangerouslysetinnerhtml: 'dangerouslySetInnerHTML',
6715 data: 'data',
6716 datetime: 'dateTime',
6717 default: 'default',
6718 defaultchecked: 'defaultChecked',
6719 defaultvalue: 'defaultValue',
6720 defer: 'defer',
6721 dir: 'dir',
6722 disabled: 'disabled',
6723 download: 'download',
6724 draggable: 'draggable',
6725 enctype: 'encType',
6726 for: 'htmlFor',
6727 form: 'form',
6728 formmethod: 'formMethod',
6729 formaction: 'formAction',
6730 formenctype: 'formEncType',
6731 formnovalidate: 'formNoValidate',
6732 formtarget: 'formTarget',
6733 frameborder: 'frameBorder',
6734 headers: 'headers',
6735 height: 'height',
6736 hidden: 'hidden',
6737 high: 'high',
6738 href: 'href',
6739 hreflang: 'hrefLang',
6740 htmlfor: 'htmlFor',
6741 httpequiv: 'httpEquiv',
6742 'http-equiv': 'httpEquiv',
6743 icon: 'icon',
6744 id: 'id',
6745 innerhtml: 'innerHTML',
6746 inputmode: 'inputMode',
6747 integrity: 'integrity',
6748 is: 'is',
6749 itemid: 'itemID',
6750 itemprop: 'itemProp',
6751 itemref: 'itemRef',
6752 itemscope: 'itemScope',
6753 itemtype: 'itemType',
6754 keyparams: 'keyParams',
6755 keytype: 'keyType',
6756 kind: 'kind',
6757 label: 'label',
6758 lang: 'lang',
6759 list: 'list',
6760 loop: 'loop',
6761 low: 'low',
6762 manifest: 'manifest',
6763 marginwidth: 'marginWidth',
6764 marginheight: 'marginHeight',
6765 max: 'max',
6766 maxlength: 'maxLength',
6767 media: 'media',
6768 mediagroup: 'mediaGroup',
6769 method: 'method',
6770 min: 'min',
6771 minlength: 'minLength',
6772 multiple: 'multiple',
6773 muted: 'muted',
6774 name: 'name',
6775 nomodule: 'noModule',
6776 nonce: 'nonce',
6777 novalidate: 'noValidate',
6778 open: 'open',
6779 optimum: 'optimum',
6780 pattern: 'pattern',
6781 placeholder: 'placeholder',
6782 playsinline: 'playsInline',
6783 poster: 'poster',
6784 preload: 'preload',
6785 profile: 'profile',
6786 radiogroup: 'radioGroup',
6787 readonly: 'readOnly',
6788 referrerpolicy: 'referrerPolicy',
6789 rel: 'rel',
6790 required: 'required',
6791 reversed: 'reversed',
6792 role: 'role',
6793 rows: 'rows',
6794 rowspan: 'rowSpan',
6795 sandbox: 'sandbox',
6796 scope: 'scope',
6797 scoped: 'scoped',
6798 scrolling: 'scrolling',
6799 seamless: 'seamless',
6800 selected: 'selected',
6801 shape: 'shape',
6802 size: 'size',
6803 sizes: 'sizes',
6804 span: 'span',
6805 spellcheck: 'spellCheck',
6806 src: 'src',
6807 srcdoc: 'srcDoc',
6808 srclang: 'srcLang',
6809 srcset: 'srcSet',
6810 start: 'start',
6811 step: 'step',
6812 style: 'style',
6813 summary: 'summary',
6814 tabindex: 'tabIndex',
6815 target: 'target',
6816 title: 'title',
6817 type: 'type',
6818 usemap: 'useMap',
6819 value: 'value',
6820 width: 'width',
6821 wmode: 'wmode',
6822 wrap: 'wrap',
6823
6824 // SVG
6825 about: 'about',
6826 accentheight: 'accentHeight',
6827 'accent-height': 'accentHeight',
6828 accumulate: 'accumulate',
6829 additive: 'additive',
6830 alignmentbaseline: 'alignmentBaseline',
6831 'alignment-baseline': 'alignmentBaseline',
6832 allowreorder: 'allowReorder',
6833 alphabetic: 'alphabetic',
6834 amplitude: 'amplitude',
6835 arabicform: 'arabicForm',
6836 'arabic-form': 'arabicForm',
6837 ascent: 'ascent',
6838 attributename: 'attributeName',
6839 attributetype: 'attributeType',
6840 autoreverse: 'autoReverse',
6841 azimuth: 'azimuth',
6842 basefrequency: 'baseFrequency',
6843 baselineshift: 'baselineShift',
6844 'baseline-shift': 'baselineShift',
6845 baseprofile: 'baseProfile',
6846 bbox: 'bbox',
6847 begin: 'begin',
6848 bias: 'bias',
6849 by: 'by',
6850 calcmode: 'calcMode',
6851 capheight: 'capHeight',
6852 'cap-height': 'capHeight',
6853 clip: 'clip',
6854 clippath: 'clipPath',
6855 'clip-path': 'clipPath',
6856 clippathunits: 'clipPathUnits',
6857 cliprule: 'clipRule',
6858 'clip-rule': 'clipRule',
6859 color: 'color',
6860 colorinterpolation: 'colorInterpolation',
6861 'color-interpolation': 'colorInterpolation',
6862 colorinterpolationfilters: 'colorInterpolationFilters',
6863 'color-interpolation-filters': 'colorInterpolationFilters',
6864 colorprofile: 'colorProfile',
6865 'color-profile': 'colorProfile',
6866 colorrendering: 'colorRendering',
6867 'color-rendering': 'colorRendering',
6868 contentscripttype: 'contentScriptType',
6869 contentstyletype: 'contentStyleType',
6870 cursor: 'cursor',
6871 cx: 'cx',
6872 cy: 'cy',
6873 d: 'd',
6874 datatype: 'datatype',
6875 decelerate: 'decelerate',
6876 descent: 'descent',
6877 diffuseconstant: 'diffuseConstant',
6878 direction: 'direction',
6879 display: 'display',
6880 divisor: 'divisor',
6881 dominantbaseline: 'dominantBaseline',
6882 'dominant-baseline': 'dominantBaseline',
6883 dur: 'dur',
6884 dx: 'dx',
6885 dy: 'dy',
6886 edgemode: 'edgeMode',
6887 elevation: 'elevation',
6888 enablebackground: 'enableBackground',
6889 'enable-background': 'enableBackground',
6890 end: 'end',
6891 exponent: 'exponent',
6892 externalresourcesrequired: 'externalResourcesRequired',
6893 fill: 'fill',
6894 fillopacity: 'fillOpacity',
6895 'fill-opacity': 'fillOpacity',
6896 fillrule: 'fillRule',
6897 'fill-rule': 'fillRule',
6898 filter: 'filter',
6899 filterres: 'filterRes',
6900 filterunits: 'filterUnits',
6901 floodopacity: 'floodOpacity',
6902 'flood-opacity': 'floodOpacity',
6903 floodcolor: 'floodColor',
6904 'flood-color': 'floodColor',
6905 focusable: 'focusable',
6906 fontfamily: 'fontFamily',
6907 'font-family': 'fontFamily',
6908 fontsize: 'fontSize',
6909 'font-size': 'fontSize',
6910 fontsizeadjust: 'fontSizeAdjust',
6911 'font-size-adjust': 'fontSizeAdjust',
6912 fontstretch: 'fontStretch',
6913 'font-stretch': 'fontStretch',
6914 fontstyle: 'fontStyle',
6915 'font-style': 'fontStyle',
6916 fontvariant: 'fontVariant',
6917 'font-variant': 'fontVariant',
6918 fontweight: 'fontWeight',
6919 'font-weight': 'fontWeight',
6920 format: 'format',
6921 from: 'from',
6922 fx: 'fx',
6923 fy: 'fy',
6924 g1: 'g1',
6925 g2: 'g2',
6926 glyphname: 'glyphName',
6927 'glyph-name': 'glyphName',
6928 glyphorientationhorizontal: 'glyphOrientationHorizontal',
6929 'glyph-orientation-horizontal': 'glyphOrientationHorizontal',
6930 glyphorientationvertical: 'glyphOrientationVertical',
6931 'glyph-orientation-vertical': 'glyphOrientationVertical',
6932 glyphref: 'glyphRef',
6933 gradienttransform: 'gradientTransform',
6934 gradientunits: 'gradientUnits',
6935 hanging: 'hanging',
6936 horizadvx: 'horizAdvX',
6937 'horiz-adv-x': 'horizAdvX',
6938 horizoriginx: 'horizOriginX',
6939 'horiz-origin-x': 'horizOriginX',
6940 ideographic: 'ideographic',
6941 imagerendering: 'imageRendering',
6942 'image-rendering': 'imageRendering',
6943 in2: 'in2',
6944 in: 'in',
6945 inlist: 'inlist',
6946 intercept: 'intercept',
6947 k1: 'k1',
6948 k2: 'k2',
6949 k3: 'k3',
6950 k4: 'k4',
6951 k: 'k',
6952 kernelmatrix: 'kernelMatrix',
6953 kernelunitlength: 'kernelUnitLength',
6954 kerning: 'kerning',
6955 keypoints: 'keyPoints',
6956 keysplines: 'keySplines',
6957 keytimes: 'keyTimes',
6958 lengthadjust: 'lengthAdjust',
6959 letterspacing: 'letterSpacing',
6960 'letter-spacing': 'letterSpacing',
6961 lightingcolor: 'lightingColor',
6962 'lighting-color': 'lightingColor',
6963 limitingconeangle: 'limitingConeAngle',
6964 local: 'local',
6965 markerend: 'markerEnd',
6966 'marker-end': 'markerEnd',
6967 markerheight: 'markerHeight',
6968 markermid: 'markerMid',
6969 'marker-mid': 'markerMid',
6970 markerstart: 'markerStart',
6971 'marker-start': 'markerStart',
6972 markerunits: 'markerUnits',
6973 markerwidth: 'markerWidth',
6974 mask: 'mask',
6975 maskcontentunits: 'maskContentUnits',
6976 maskunits: 'maskUnits',
6977 mathematical: 'mathematical',
6978 mode: 'mode',
6979 numoctaves: 'numOctaves',
6980 offset: 'offset',
6981 opacity: 'opacity',
6982 operator: 'operator',
6983 order: 'order',
6984 orient: 'orient',
6985 orientation: 'orientation',
6986 origin: 'origin',
6987 overflow: 'overflow',
6988 overlineposition: 'overlinePosition',
6989 'overline-position': 'overlinePosition',
6990 overlinethickness: 'overlineThickness',
6991 'overline-thickness': 'overlineThickness',
6992 paintorder: 'paintOrder',
6993 'paint-order': 'paintOrder',
6994 panose1: 'panose1',
6995 'panose-1': 'panose1',
6996 pathlength: 'pathLength',
6997 patterncontentunits: 'patternContentUnits',
6998 patterntransform: 'patternTransform',
6999 patternunits: 'patternUnits',
7000 pointerevents: 'pointerEvents',
7001 'pointer-events': 'pointerEvents',
7002 points: 'points',
7003 pointsatx: 'pointsAtX',
7004 pointsaty: 'pointsAtY',
7005 pointsatz: 'pointsAtZ',
7006 prefix: 'prefix',
7007 preservealpha: 'preserveAlpha',
7008 preserveaspectratio: 'preserveAspectRatio',
7009 primitiveunits: 'primitiveUnits',
7010 property: 'property',
7011 r: 'r',
7012 radius: 'radius',
7013 refx: 'refX',
7014 refy: 'refY',
7015 renderingintent: 'renderingIntent',
7016 'rendering-intent': 'renderingIntent',
7017 repeatcount: 'repeatCount',
7018 repeatdur: 'repeatDur',
7019 requiredextensions: 'requiredExtensions',
7020 requiredfeatures: 'requiredFeatures',
7021 resource: 'resource',
7022 restart: 'restart',
7023 result: 'result',
7024 results: 'results',
7025 rotate: 'rotate',
7026 rx: 'rx',
7027 ry: 'ry',
7028 scale: 'scale',
7029 security: 'security',
7030 seed: 'seed',
7031 shaperendering: 'shapeRendering',
7032 'shape-rendering': 'shapeRendering',
7033 slope: 'slope',
7034 spacing: 'spacing',
7035 specularconstant: 'specularConstant',
7036 specularexponent: 'specularExponent',
7037 speed: 'speed',
7038 spreadmethod: 'spreadMethod',
7039 startoffset: 'startOffset',
7040 stddeviation: 'stdDeviation',
7041 stemh: 'stemh',
7042 stemv: 'stemv',
7043 stitchtiles: 'stitchTiles',
7044 stopcolor: 'stopColor',
7045 'stop-color': 'stopColor',
7046 stopopacity: 'stopOpacity',
7047 'stop-opacity': 'stopOpacity',
7048 strikethroughposition: 'strikethroughPosition',
7049 'strikethrough-position': 'strikethroughPosition',
7050 strikethroughthickness: 'strikethroughThickness',
7051 'strikethrough-thickness': 'strikethroughThickness',
7052 string: 'string',
7053 stroke: 'stroke',
7054 strokedasharray: 'strokeDasharray',
7055 'stroke-dasharray': 'strokeDasharray',
7056 strokedashoffset: 'strokeDashoffset',
7057 'stroke-dashoffset': 'strokeDashoffset',
7058 strokelinecap: 'strokeLinecap',
7059 'stroke-linecap': 'strokeLinecap',
7060 strokelinejoin: 'strokeLinejoin',
7061 'stroke-linejoin': 'strokeLinejoin',
7062 strokemiterlimit: 'strokeMiterlimit',
7063 'stroke-miterlimit': 'strokeMiterlimit',
7064 strokewidth: 'strokeWidth',
7065 'stroke-width': 'strokeWidth',
7066 strokeopacity: 'strokeOpacity',
7067 'stroke-opacity': 'strokeOpacity',
7068 suppresscontenteditablewarning: 'suppressContentEditableWarning',
7069 suppresshydrationwarning: 'suppressHydrationWarning',
7070 surfacescale: 'surfaceScale',
7071 systemlanguage: 'systemLanguage',
7072 tablevalues: 'tableValues',
7073 targetx: 'targetX',
7074 targety: 'targetY',
7075 textanchor: 'textAnchor',
7076 'text-anchor': 'textAnchor',
7077 textdecoration: 'textDecoration',
7078 'text-decoration': 'textDecoration',
7079 textlength: 'textLength',
7080 textrendering: 'textRendering',
7081 'text-rendering': 'textRendering',
7082 to: 'to',
7083 transform: 'transform',
7084 typeof: 'typeof',
7085 u1: 'u1',
7086 u2: 'u2',
7087 underlineposition: 'underlinePosition',
7088 'underline-position': 'underlinePosition',
7089 underlinethickness: 'underlineThickness',
7090 'underline-thickness': 'underlineThickness',
7091 unicode: 'unicode',
7092 unicodebidi: 'unicodeBidi',
7093 'unicode-bidi': 'unicodeBidi',
7094 unicoderange: 'unicodeRange',
7095 'unicode-range': 'unicodeRange',
7096 unitsperem: 'unitsPerEm',
7097 'units-per-em': 'unitsPerEm',
7098 unselectable: 'unselectable',
7099 valphabetic: 'vAlphabetic',
7100 'v-alphabetic': 'vAlphabetic',
7101 values: 'values',
7102 vectoreffect: 'vectorEffect',
7103 'vector-effect': 'vectorEffect',
7104 version: 'version',
7105 vertadvy: 'vertAdvY',
7106 'vert-adv-y': 'vertAdvY',
7107 vertoriginx: 'vertOriginX',
7108 'vert-origin-x': 'vertOriginX',
7109 vertoriginy: 'vertOriginY',
7110 'vert-origin-y': 'vertOriginY',
7111 vhanging: 'vHanging',
7112 'v-hanging': 'vHanging',
7113 videographic: 'vIdeographic',
7114 'v-ideographic': 'vIdeographic',
7115 viewbox: 'viewBox',
7116 viewtarget: 'viewTarget',
7117 visibility: 'visibility',
7118 vmathematical: 'vMathematical',
7119 'v-mathematical': 'vMathematical',
7120 vocab: 'vocab',
7121 widths: 'widths',
7122 wordspacing: 'wordSpacing',
7123 'word-spacing': 'wordSpacing',
7124 writingmode: 'writingMode',
7125 'writing-mode': 'writingMode',
7126 x1: 'x1',
7127 x2: 'x2',
7128 x: 'x',
7129 xchannelselector: 'xChannelSelector',
7130 xheight: 'xHeight',
7131 'x-height': 'xHeight',
7132 xlinkactuate: 'xlinkActuate',
7133 'xlink:actuate': 'xlinkActuate',
7134 xlinkarcrole: 'xlinkArcrole',
7135 'xlink:arcrole': 'xlinkArcrole',
7136 xlinkhref: 'xlinkHref',
7137 'xlink:href': 'xlinkHref',
7138 xlinkrole: 'xlinkRole',
7139 'xlink:role': 'xlinkRole',
7140 xlinkshow: 'xlinkShow',
7141 'xlink:show': 'xlinkShow',
7142 xlinktitle: 'xlinkTitle',
7143 'xlink:title': 'xlinkTitle',
7144 xlinktype: 'xlinkType',
7145 'xlink:type': 'xlinkType',
7146 xmlbase: 'xmlBase',
7147 'xml:base': 'xmlBase',
7148 xmllang: 'xmlLang',
7149 'xml:lang': 'xmlLang',
7150 xmlns: 'xmlns',
7151 'xml:space': 'xmlSpace',
7152 xmlnsxlink: 'xmlnsXlink',
7153 'xmlns:xlink': 'xmlnsXlink',
7154 xmlspace: 'xmlSpace',
7155 y1: 'y1',
7156 y2: 'y2',
7157 y: 'y',
7158 ychannelselector: 'yChannelSelector',
7159 z: 'z',
7160 zoomandpan: 'zoomAndPan'
7161};
7162
7163var ariaProperties = {
7164 'aria-current': 0, // state
7165 'aria-details': 0,
7166 'aria-disabled': 0, // state
7167 'aria-hidden': 0, // state
7168 'aria-invalid': 0, // state
7169 'aria-keyshortcuts': 0,
7170 'aria-label': 0,
7171 'aria-roledescription': 0,
7172 // Widget Attributes
7173 'aria-autocomplete': 0,
7174 'aria-checked': 0,
7175 'aria-expanded': 0,
7176 'aria-haspopup': 0,
7177 'aria-level': 0,
7178 'aria-modal': 0,
7179 'aria-multiline': 0,
7180 'aria-multiselectable': 0,
7181 'aria-orientation': 0,
7182 'aria-placeholder': 0,
7183 'aria-pressed': 0,
7184 'aria-readonly': 0,
7185 'aria-required': 0,
7186 'aria-selected': 0,
7187 'aria-sort': 0,
7188 'aria-valuemax': 0,
7189 'aria-valuemin': 0,
7190 'aria-valuenow': 0,
7191 'aria-valuetext': 0,
7192 // Live Region Attributes
7193 'aria-atomic': 0,
7194 'aria-busy': 0,
7195 'aria-live': 0,
7196 'aria-relevant': 0,
7197 // Drag-and-Drop Attributes
7198 'aria-dropeffect': 0,
7199 'aria-grabbed': 0,
7200 // Relationship Attributes
7201 'aria-activedescendant': 0,
7202 'aria-colcount': 0,
7203 'aria-colindex': 0,
7204 'aria-colspan': 0,
7205 'aria-controls': 0,
7206 'aria-describedby': 0,
7207 'aria-errormessage': 0,
7208 'aria-flowto': 0,
7209 'aria-labelledby': 0,
7210 'aria-owns': 0,
7211 'aria-posinset': 0,
7212 'aria-rowcount': 0,
7213 'aria-rowindex': 0,
7214 'aria-rowspan': 0,
7215 'aria-setsize': 0
7216};
7217
7218var warnedProperties = {};
7219var rARIA = new RegExp('^(aria)-[' + ATTRIBUTE_NAME_CHAR + ']*$');
7220var rARIACamel = new RegExp('^(aria)[A-Z][' + ATTRIBUTE_NAME_CHAR + ']*$');
7221
7222var hasOwnProperty$2 = Object.prototype.hasOwnProperty;
7223
7224function validateProperty(tagName, name) {
7225 if (hasOwnProperty$2.call(warnedProperties, name) && warnedProperties[name]) {
7226 return true;
7227 }
7228
7229 if (rARIACamel.test(name)) {
7230 var ariaName = 'aria-' + name.slice(4).toLowerCase();
7231 var correctName = ariaProperties.hasOwnProperty(ariaName) ? ariaName : null;
7232
7233 // If this is an aria-* attribute, but is not listed in the known DOM
7234 // DOM properties, then it is an invalid aria-* attribute.
7235 if (correctName == null) {
7236 warning$1(false, 'Invalid ARIA attribute `%s`. ARIA attributes follow the pattern aria-* and must be lowercase.', name);
7237 warnedProperties[name] = true;
7238 return true;
7239 }
7240 // aria-* attributes should be lowercase; suggest the lowercase version.
7241 if (name !== correctName) {
7242 warning$1(false, 'Invalid ARIA attribute `%s`. Did you mean `%s`?', name, correctName);
7243 warnedProperties[name] = true;
7244 return true;
7245 }
7246 }
7247
7248 if (rARIA.test(name)) {
7249 var lowerCasedName = name.toLowerCase();
7250 var standardName = ariaProperties.hasOwnProperty(lowerCasedName) ? lowerCasedName : null;
7251
7252 // If this is an aria-* attribute, but is not listed in the known DOM
7253 // DOM properties, then it is an invalid aria-* attribute.
7254 if (standardName == null) {
7255 warnedProperties[name] = true;
7256 return false;
7257 }
7258 // aria-* attributes should be lowercase; suggest the lowercase version.
7259 if (name !== standardName) {
7260 warning$1(false, 'Unknown ARIA attribute `%s`. Did you mean `%s`?', name, standardName);
7261 warnedProperties[name] = true;
7262 return true;
7263 }
7264 }
7265
7266 return true;
7267}
7268
7269function warnInvalidARIAProps(type, props) {
7270 var invalidProps = [];
7271
7272 for (var key in props) {
7273 var isValid = validateProperty(type, key);
7274 if (!isValid) {
7275 invalidProps.push(key);
7276 }
7277 }
7278
7279 var unknownPropString = invalidProps.map(function (prop) {
7280 return '`' + prop + '`';
7281 }).join(', ');
7282
7283 if (invalidProps.length === 1) {
7284 warning$1(false, 'Invalid aria prop %s on <%s> tag. ' + 'For details, see https://fb.me/invalid-aria-prop', unknownPropString, type);
7285 } else if (invalidProps.length > 1) {
7286 warning$1(false, 'Invalid aria props %s on <%s> tag. ' + 'For details, see https://fb.me/invalid-aria-prop', unknownPropString, type);
7287 }
7288}
7289
7290function validateProperties(type, props) {
7291 if (isCustomComponent(type, props)) {
7292 return;
7293 }
7294 warnInvalidARIAProps(type, props);
7295}
7296
7297var didWarnValueNull = false;
7298
7299function validateProperties$1(type, props) {
7300 if (type !== 'input' && type !== 'textarea' && type !== 'select') {
7301 return;
7302 }
7303
7304 if (props != null && props.value === null && !didWarnValueNull) {
7305 didWarnValueNull = true;
7306 if (type === 'select' && props.multiple) {
7307 warning$1(false, '`value` prop on `%s` should not be null. ' + 'Consider using an empty array when `multiple` is set to `true` ' + 'to clear the component or `undefined` for uncontrolled components.', type);
7308 } else {
7309 warning$1(false, '`value` prop on `%s` should not be null. ' + 'Consider using an empty string to clear the component or `undefined` ' + 'for uncontrolled components.', type);
7310 }
7311 }
7312}
7313
7314var validateProperty$1 = function () {};
7315
7316{
7317 var warnedProperties$1 = {};
7318 var _hasOwnProperty = Object.prototype.hasOwnProperty;
7319 var EVENT_NAME_REGEX = /^on./;
7320 var INVALID_EVENT_NAME_REGEX = /^on[^A-Z]/;
7321 var rARIA$1 = new RegExp('^(aria)-[' + ATTRIBUTE_NAME_CHAR + ']*$');
7322 var rARIACamel$1 = new RegExp('^(aria)[A-Z][' + ATTRIBUTE_NAME_CHAR + ']*$');
7323
7324 validateProperty$1 = function (tagName, name, value, canUseEventSystem) {
7325 if (_hasOwnProperty.call(warnedProperties$1, name) && warnedProperties$1[name]) {
7326 return true;
7327 }
7328
7329 var lowerCasedName = name.toLowerCase();
7330 if (lowerCasedName === 'onfocusin' || lowerCasedName === 'onfocusout') {
7331 warning$1(false, 'React uses onFocus and onBlur instead of onFocusIn and onFocusOut. ' + 'All React events are normalized to bubble, so onFocusIn and onFocusOut ' + 'are not needed/supported by React.');
7332 warnedProperties$1[name] = true;
7333 return true;
7334 }
7335
7336 // We can't rely on the event system being injected on the server.
7337 if (canUseEventSystem) {
7338 if (registrationNameModules.hasOwnProperty(name)) {
7339 return true;
7340 }
7341 var registrationName = possibleRegistrationNames.hasOwnProperty(lowerCasedName) ? possibleRegistrationNames[lowerCasedName] : null;
7342 if (registrationName != null) {
7343 warning$1(false, 'Invalid event handler property `%s`. Did you mean `%s`?', name, registrationName);
7344 warnedProperties$1[name] = true;
7345 return true;
7346 }
7347 if (EVENT_NAME_REGEX.test(name)) {
7348 warning$1(false, 'Unknown event handler property `%s`. It will be ignored.', name);
7349 warnedProperties$1[name] = true;
7350 return true;
7351 }
7352 } else if (EVENT_NAME_REGEX.test(name)) {
7353 // If no event plugins have been injected, we are in a server environment.
7354 // So we can't tell if the event name is correct for sure, but we can filter
7355 // out known bad ones like `onclick`. We can't suggest a specific replacement though.
7356 if (INVALID_EVENT_NAME_REGEX.test(name)) {
7357 warning$1(false, 'Invalid event handler property `%s`. ' + 'React events use the camelCase naming convention, for example `onClick`.', name);
7358 }
7359 warnedProperties$1[name] = true;
7360 return true;
7361 }
7362
7363 // Let the ARIA attribute hook validate ARIA attributes
7364 if (rARIA$1.test(name) || rARIACamel$1.test(name)) {
7365 return true;
7366 }
7367
7368 if (lowerCasedName === 'innerhtml') {
7369 warning$1(false, 'Directly setting property `innerHTML` is not permitted. ' + 'For more information, lookup documentation on `dangerouslySetInnerHTML`.');
7370 warnedProperties$1[name] = true;
7371 return true;
7372 }
7373
7374 if (lowerCasedName === 'aria') {
7375 warning$1(false, 'The `aria` attribute is reserved for future use in React. ' + 'Pass individual `aria-` attributes instead.');
7376 warnedProperties$1[name] = true;
7377 return true;
7378 }
7379
7380 if (lowerCasedName === 'is' && value !== null && value !== undefined && typeof value !== 'string') {
7381 warning$1(false, 'Received a `%s` for a string attribute `is`. If this is expected, cast ' + 'the value to a string.', typeof value);
7382 warnedProperties$1[name] = true;
7383 return true;
7384 }
7385
7386 if (typeof value === 'number' && isNaN(value)) {
7387 warning$1(false, 'Received NaN for the `%s` attribute. If this is expected, cast ' + 'the value to a string.', name);
7388 warnedProperties$1[name] = true;
7389 return true;
7390 }
7391
7392 var propertyInfo = getPropertyInfo(name);
7393 var isReserved = propertyInfo !== null && propertyInfo.type === RESERVED;
7394
7395 // Known attributes should match the casing specified in the property config.
7396 if (possibleStandardNames.hasOwnProperty(lowerCasedName)) {
7397 var standardName = possibleStandardNames[lowerCasedName];
7398 if (standardName !== name) {
7399 warning$1(false, 'Invalid DOM property `%s`. Did you mean `%s`?', name, standardName);
7400 warnedProperties$1[name] = true;
7401 return true;
7402 }
7403 } else if (!isReserved && name !== lowerCasedName) {
7404 // Unknown attributes should have lowercase casing since that's how they
7405 // will be cased anyway with server rendering.
7406 warning$1(false, 'React does not recognize the `%s` prop on a DOM element. If you ' + 'intentionally want it to appear in the DOM as a custom ' + 'attribute, spell it as lowercase `%s` instead. ' + 'If you accidentally passed it from a parent component, remove ' + 'it from the DOM element.', name, lowerCasedName);
7407 warnedProperties$1[name] = true;
7408 return true;
7409 }
7410
7411 if (typeof value === 'boolean' && shouldRemoveAttributeWithWarning(name, value, propertyInfo, false)) {
7412 if (value) {
7413 warning$1(false, 'Received `%s` for a non-boolean attribute `%s`.\n\n' + 'If you want to write it to the DOM, pass a string instead: ' + '%s="%s" or %s={value.toString()}.', value, name, name, value, name);
7414 } else {
7415 warning$1(false, 'Received `%s` for a non-boolean attribute `%s`.\n\n' + 'If you want to write it to the DOM, pass a string instead: ' + '%s="%s" or %s={value.toString()}.\n\n' + 'If you used to conditionally omit it with %s={condition && value}, ' + 'pass %s={condition ? value : undefined} instead.', value, name, name, value, name, name, name);
7416 }
7417 warnedProperties$1[name] = true;
7418 return true;
7419 }
7420
7421 // Now that we've validated casing, do not validate
7422 // data types for reserved props
7423 if (isReserved) {
7424 return true;
7425 }
7426
7427 // Warn when a known attribute is a bad type
7428 if (shouldRemoveAttributeWithWarning(name, value, propertyInfo, false)) {
7429 warnedProperties$1[name] = true;
7430 return false;
7431 }
7432
7433 // Warn when passing the strings 'false' or 'true' into a boolean prop
7434 if ((value === 'false' || value === 'true') && propertyInfo !== null && propertyInfo.type === BOOLEAN) {
7435 warning$1(false, 'Received the string `%s` for the boolean attribute `%s`. ' + '%s ' + 'Did you mean %s={%s}?', value, name, value === 'false' ? 'The browser will interpret it as a truthy value.' : 'Although this works, it will not work as expected if you pass the string "false".', name, value);
7436 warnedProperties$1[name] = true;
7437 return true;
7438 }
7439
7440 return true;
7441 };
7442}
7443
7444var warnUnknownProperties = function (type, props, canUseEventSystem) {
7445 var unknownProps = [];
7446 for (var key in props) {
7447 var isValid = validateProperty$1(type, key, props[key], canUseEventSystem);
7448 if (!isValid) {
7449 unknownProps.push(key);
7450 }
7451 }
7452
7453 var unknownPropString = unknownProps.map(function (prop) {
7454 return '`' + prop + '`';
7455 }).join(', ');
7456 if (unknownProps.length === 1) {
7457 warning$1(false, 'Invalid value for prop %s on <%s> tag. Either remove it from the element, ' + 'or pass a string or number value to keep it in the DOM. ' + 'For details, see https://fb.me/react-attribute-behavior', unknownPropString, type);
7458 } else if (unknownProps.length > 1) {
7459 warning$1(false, 'Invalid values for props %s on <%s> tag. Either remove them from the element, ' + 'or pass a string or number value to keep them in the DOM. ' + 'For details, see https://fb.me/react-attribute-behavior', unknownPropString, type);
7460 }
7461};
7462
7463function validateProperties$2(type, props, canUseEventSystem) {
7464 if (isCustomComponent(type, props)) {
7465 return;
7466 }
7467 warnUnknownProperties(type, props, canUseEventSystem);
7468}
7469
7470// TODO: direct imports like some-package/src/* are bad. Fix me.
7471var didWarnInvalidHydration = false;
7472var didWarnShadyDOM = false;
7473
7474var DANGEROUSLY_SET_INNER_HTML = 'dangerouslySetInnerHTML';
7475var SUPPRESS_CONTENT_EDITABLE_WARNING = 'suppressContentEditableWarning';
7476var SUPPRESS_HYDRATION_WARNING$1 = 'suppressHydrationWarning';
7477var AUTOFOCUS = 'autoFocus';
7478var CHILDREN = 'children';
7479var STYLE$1 = 'style';
7480var HTML = '__html';
7481
7482var HTML_NAMESPACE = Namespaces.html;
7483
7484
7485var warnedUnknownTags = void 0;
7486var suppressHydrationWarning = void 0;
7487
7488var validatePropertiesInDevelopment = void 0;
7489var warnForTextDifference = void 0;
7490var warnForPropDifference = void 0;
7491var warnForExtraAttributes = void 0;
7492var warnForInvalidEventListener = void 0;
7493var canDiffStyleForHydrationWarning = void 0;
7494
7495var normalizeMarkupForTextOrAttribute = void 0;
7496var normalizeHTML = void 0;
7497
7498{
7499 warnedUnknownTags = {
7500 // Chrome is the only major browser not shipping <time>. But as of July
7501 // 2017 it intends to ship it due to widespread usage. We intentionally
7502 // *don't* warn for <time> even if it's unrecognized by Chrome because
7503 // it soon will be, and many apps have been using it anyway.
7504 time: true,
7505 // There are working polyfills for <dialog>. Let people use it.
7506 dialog: true,
7507 // Electron ships a custom <webview> tag to display external web content in
7508 // an isolated frame and process.
7509 // This tag is not present in non Electron environments such as JSDom which
7510 // is often used for testing purposes.
7511 // @see https://electronjs.org/docs/api/webview-tag
7512 webview: true
7513 };
7514
7515 validatePropertiesInDevelopment = function (type, props) {
7516 validateProperties(type, props);
7517 validateProperties$1(type, props);
7518 validateProperties$2(type, props, /* canUseEventSystem */true);
7519 };
7520
7521 // IE 11 parses & normalizes the style attribute as opposed to other
7522 // browsers. It adds spaces and sorts the properties in some
7523 // non-alphabetical order. Handling that would require sorting CSS
7524 // properties in the client & server versions or applying
7525 // `expectedStyle` to a temporary DOM node to read its `style` attribute
7526 // normalized. Since it only affects IE, we're skipping style warnings
7527 // in that browser completely in favor of doing all that work.
7528 // See https://github.com/facebook/react/issues/11807
7529 canDiffStyleForHydrationWarning = canUseDOM && !document.documentMode;
7530
7531 // HTML parsing normalizes CR and CRLF to LF.
7532 // It also can turn \u0000 into \uFFFD inside attributes.
7533 // https://www.w3.org/TR/html5/single-page.html#preprocessing-the-input-stream
7534 // If we have a mismatch, it might be caused by that.
7535 // We will still patch up in this case but not fire the warning.
7536 var NORMALIZE_NEWLINES_REGEX = /\r\n?/g;
7537 var NORMALIZE_NULL_AND_REPLACEMENT_REGEX = /\u0000|\uFFFD/g;
7538
7539 normalizeMarkupForTextOrAttribute = function (markup) {
7540 var markupString = typeof markup === 'string' ? markup : '' + markup;
7541 return markupString.replace(NORMALIZE_NEWLINES_REGEX, '\n').replace(NORMALIZE_NULL_AND_REPLACEMENT_REGEX, '');
7542 };
7543
7544 warnForTextDifference = function (serverText, clientText) {
7545 if (didWarnInvalidHydration) {
7546 return;
7547 }
7548 var normalizedClientText = normalizeMarkupForTextOrAttribute(clientText);
7549 var normalizedServerText = normalizeMarkupForTextOrAttribute(serverText);
7550 if (normalizedServerText === normalizedClientText) {
7551 return;
7552 }
7553 didWarnInvalidHydration = true;
7554 warningWithoutStack$1(false, 'Text content did not match. Server: "%s" Client: "%s"', normalizedServerText, normalizedClientText);
7555 };
7556
7557 warnForPropDifference = function (propName, serverValue, clientValue) {
7558 if (didWarnInvalidHydration) {
7559 return;
7560 }
7561 var normalizedClientValue = normalizeMarkupForTextOrAttribute(clientValue);
7562 var normalizedServerValue = normalizeMarkupForTextOrAttribute(serverValue);
7563 if (normalizedServerValue === normalizedClientValue) {
7564 return;
7565 }
7566 didWarnInvalidHydration = true;
7567 warningWithoutStack$1(false, 'Prop `%s` did not match. Server: %s Client: %s', propName, JSON.stringify(normalizedServerValue), JSON.stringify(normalizedClientValue));
7568 };
7569
7570 warnForExtraAttributes = function (attributeNames) {
7571 if (didWarnInvalidHydration) {
7572 return;
7573 }
7574 didWarnInvalidHydration = true;
7575 var names = [];
7576 attributeNames.forEach(function (name) {
7577 names.push(name);
7578 });
7579 warningWithoutStack$1(false, 'Extra attributes from the server: %s', names);
7580 };
7581
7582 warnForInvalidEventListener = function (registrationName, listener) {
7583 if (listener === false) {
7584 warning$1(false, 'Expected `%s` listener to be a function, instead got `false`.\n\n' + 'If you used to conditionally omit it with %s={condition && value}, ' + 'pass %s={condition ? value : undefined} instead.', registrationName, registrationName, registrationName);
7585 } else {
7586 warning$1(false, 'Expected `%s` listener to be a function, instead got a value of `%s` type.', registrationName, typeof listener);
7587 }
7588 };
7589
7590 // Parse the HTML and read it back to normalize the HTML string so that it
7591 // can be used for comparison.
7592 normalizeHTML = function (parent, html) {
7593 // We could have created a separate document here to avoid
7594 // re-initializing custom elements if they exist. But this breaks
7595 // how <noscript> is being handled. So we use the same document.
7596 // See the discussion in https://github.com/facebook/react/pull/11157.
7597 var testElement = parent.namespaceURI === HTML_NAMESPACE ? parent.ownerDocument.createElement(parent.tagName) : parent.ownerDocument.createElementNS(parent.namespaceURI, parent.tagName);
7598 testElement.innerHTML = html;
7599 return testElement.innerHTML;
7600 };
7601}
7602
7603function ensureListeningTo(rootContainerElement, registrationName) {
7604 var isDocumentOrFragment = rootContainerElement.nodeType === DOCUMENT_NODE || rootContainerElement.nodeType === DOCUMENT_FRAGMENT_NODE;
7605 var doc = isDocumentOrFragment ? rootContainerElement : rootContainerElement.ownerDocument;
7606 listenTo(registrationName, doc);
7607}
7608
7609function getOwnerDocumentFromRootContainer(rootContainerElement) {
7610 return rootContainerElement.nodeType === DOCUMENT_NODE ? rootContainerElement : rootContainerElement.ownerDocument;
7611}
7612
7613function noop() {}
7614
7615function trapClickOnNonInteractiveElement(node) {
7616 // Mobile Safari does not fire properly bubble click events on
7617 // non-interactive elements, which means delegated click listeners do not
7618 // fire. The workaround for this bug involves attaching an empty click
7619 // listener on the target node.
7620 // http://www.quirksmode.org/blog/archives/2010/09/click_event_del.html
7621 // Just set it using the onclick property so that we don't have to manage any
7622 // bookkeeping for it. Not sure if we need to clear it when the listener is
7623 // removed.
7624 // TODO: Only do this for the relevant Safaris maybe?
7625 node.onclick = noop;
7626}
7627
7628function setInitialDOMProperties(tag, domElement, rootContainerElement, nextProps, isCustomComponentTag) {
7629 for (var propKey in nextProps) {
7630 if (!nextProps.hasOwnProperty(propKey)) {
7631 continue;
7632 }
7633 var nextProp = nextProps[propKey];
7634 if (propKey === STYLE$1) {
7635 {
7636 if (nextProp) {
7637 // Freeze the next style object so that we can assume it won't be
7638 // mutated. We have already warned for this in the past.
7639 Object.freeze(nextProp);
7640 }
7641 }
7642 // Relies on `updateStylesByID` not mutating `styleUpdates`.
7643 setValueForStyles(domElement, nextProp);
7644 } else if (propKey === DANGEROUSLY_SET_INNER_HTML) {
7645 var nextHtml = nextProp ? nextProp[HTML] : undefined;
7646 if (nextHtml != null) {
7647 setInnerHTML(domElement, nextHtml);
7648 }
7649 } else if (propKey === CHILDREN) {
7650 if (typeof nextProp === 'string') {
7651 // Avoid setting initial textContent when the text is empty. In IE11 setting
7652 // textContent on a <textarea> will cause the placeholder to not
7653 // show within the <textarea> until it has been focused and blurred again.
7654 // https://github.com/facebook/react/issues/6731#issuecomment-254874553
7655 var canSetTextContent = tag !== 'textarea' || nextProp !== '';
7656 if (canSetTextContent) {
7657 setTextContent(domElement, nextProp);
7658 }
7659 } else if (typeof nextProp === 'number') {
7660 setTextContent(domElement, '' + nextProp);
7661 }
7662 } else if (propKey === SUPPRESS_CONTENT_EDITABLE_WARNING || propKey === SUPPRESS_HYDRATION_WARNING$1) {
7663 // Noop
7664 } else if (propKey === AUTOFOCUS) {
7665 // We polyfill it separately on the client during commit.
7666 // We could have excluded it in the property list instead of
7667 // adding a special case here, but then it wouldn't be emitted
7668 // on server rendering (but we *do* want to emit it in SSR).
7669 } else if (registrationNameModules.hasOwnProperty(propKey)) {
7670 if (nextProp != null) {
7671 if (true && typeof nextProp !== 'function') {
7672 warnForInvalidEventListener(propKey, nextProp);
7673 }
7674 ensureListeningTo(rootContainerElement, propKey);
7675 }
7676 } else if (nextProp != null) {
7677 setValueForProperty(domElement, propKey, nextProp, isCustomComponentTag);
7678 }
7679 }
7680}
7681
7682function updateDOMProperties(domElement, updatePayload, wasCustomComponentTag, isCustomComponentTag) {
7683 // TODO: Handle wasCustomComponentTag
7684 for (var i = 0; i < updatePayload.length; i += 2) {
7685 var propKey = updatePayload[i];
7686 var propValue = updatePayload[i + 1];
7687 if (propKey === STYLE$1) {
7688 setValueForStyles(domElement, propValue);
7689 } else if (propKey === DANGEROUSLY_SET_INNER_HTML) {
7690 setInnerHTML(domElement, propValue);
7691 } else if (propKey === CHILDREN) {
7692 setTextContent(domElement, propValue);
7693 } else {
7694 setValueForProperty(domElement, propKey, propValue, isCustomComponentTag);
7695 }
7696 }
7697}
7698
7699function createElement(type, props, rootContainerElement, parentNamespace) {
7700 var isCustomComponentTag = void 0;
7701
7702 // We create tags in the namespace of their parent container, except HTML
7703 // tags get no namespace.
7704 var ownerDocument = getOwnerDocumentFromRootContainer(rootContainerElement);
7705 var domElement = void 0;
7706 var namespaceURI = parentNamespace;
7707 if (namespaceURI === HTML_NAMESPACE) {
7708 namespaceURI = getIntrinsicNamespace(type);
7709 }
7710 if (namespaceURI === HTML_NAMESPACE) {
7711 {
7712 isCustomComponentTag = isCustomComponent(type, props);
7713 // Should this check be gated by parent namespace? Not sure we want to
7714 // allow <SVG> or <mATH>.
7715 !(isCustomComponentTag || type === type.toLowerCase()) ? warning$1(false, '<%s /> is using incorrect casing. ' + 'Use PascalCase for React components, ' + 'or lowercase for HTML elements.', type) : void 0;
7716 }
7717
7718 if (type === 'script') {
7719 // Create the script via .innerHTML so its "parser-inserted" flag is
7720 // set to true and it does not execute
7721 var div = ownerDocument.createElement('div');
7722 div.innerHTML = '<script><' + '/script>'; // eslint-disable-line
7723 // This is guaranteed to yield a script element.
7724 var firstChild = div.firstChild;
7725 domElement = div.removeChild(firstChild);
7726 } else if (typeof props.is === 'string') {
7727 // $FlowIssue `createElement` should be updated for Web Components
7728 domElement = ownerDocument.createElement(type, { is: props.is });
7729 } else {
7730 // Separate else branch instead of using `props.is || undefined` above because of a Firefox bug.
7731 // See discussion in https://github.com/facebook/react/pull/6896
7732 // and discussion in https://bugzilla.mozilla.org/show_bug.cgi?id=1276240
7733 domElement = ownerDocument.createElement(type);
7734 // Normally attributes are assigned in `setInitialDOMProperties`, however the `multiple`
7735 // attribute on `select`s needs to be added before `option`s are inserted. This prevents
7736 // a bug where the `select` does not scroll to the correct option because singular
7737 // `select` elements automatically pick the first item.
7738 // See https://github.com/facebook/react/issues/13222
7739 if (type === 'select' && props.multiple) {
7740 var node = domElement;
7741 node.multiple = true;
7742 }
7743 }
7744 } else {
7745 domElement = ownerDocument.createElementNS(namespaceURI, type);
7746 }
7747
7748 {
7749 if (namespaceURI === HTML_NAMESPACE) {
7750 if (!isCustomComponentTag && Object.prototype.toString.call(domElement) === '[object HTMLUnknownElement]' && !Object.prototype.hasOwnProperty.call(warnedUnknownTags, type)) {
7751 warnedUnknownTags[type] = true;
7752 warning$1(false, 'The tag <%s> is unrecognized in this browser. ' + 'If you meant to render a React component, start its name with ' + 'an uppercase letter.', type);
7753 }
7754 }
7755 }
7756
7757 return domElement;
7758}
7759
7760function createTextNode(text, rootContainerElement) {
7761 return getOwnerDocumentFromRootContainer(rootContainerElement).createTextNode(text);
7762}
7763
7764function setInitialProperties(domElement, tag, rawProps, rootContainerElement) {
7765 var isCustomComponentTag = isCustomComponent(tag, rawProps);
7766 {
7767 validatePropertiesInDevelopment(tag, rawProps);
7768 if (isCustomComponentTag && !didWarnShadyDOM && domElement.shadyRoot) {
7769 warning$1(false, '%s is using shady DOM. Using shady DOM with React can ' + 'cause things to break subtly.', getCurrentFiberOwnerNameInDevOrNull() || 'A component');
7770 didWarnShadyDOM = true;
7771 }
7772 }
7773
7774 // TODO: Make sure that we check isMounted before firing any of these events.
7775 var props = void 0;
7776 switch (tag) {
7777 case 'iframe':
7778 case 'object':
7779 trapBubbledEvent(TOP_LOAD, domElement);
7780 props = rawProps;
7781 break;
7782 case 'video':
7783 case 'audio':
7784 // Create listener for each media event
7785 for (var i = 0; i < mediaEventTypes.length; i++) {
7786 trapBubbledEvent(mediaEventTypes[i], domElement);
7787 }
7788 props = rawProps;
7789 break;
7790 case 'source':
7791 trapBubbledEvent(TOP_ERROR, domElement);
7792 props = rawProps;
7793 break;
7794 case 'img':
7795 case 'image':
7796 case 'link':
7797 trapBubbledEvent(TOP_ERROR, domElement);
7798 trapBubbledEvent(TOP_LOAD, domElement);
7799 props = rawProps;
7800 break;
7801 case 'form':
7802 trapBubbledEvent(TOP_RESET, domElement);
7803 trapBubbledEvent(TOP_SUBMIT, domElement);
7804 props = rawProps;
7805 break;
7806 case 'details':
7807 trapBubbledEvent(TOP_TOGGLE, domElement);
7808 props = rawProps;
7809 break;
7810 case 'input':
7811 initWrapperState(domElement, rawProps);
7812 props = getHostProps(domElement, rawProps);
7813 trapBubbledEvent(TOP_INVALID, domElement);
7814 // For controlled components we always need to ensure we're listening
7815 // to onChange. Even if there is no listener.
7816 ensureListeningTo(rootContainerElement, 'onChange');
7817 break;
7818 case 'option':
7819 validateProps(domElement, rawProps);
7820 props = getHostProps$1(domElement, rawProps);
7821 break;
7822 case 'select':
7823 initWrapperState$1(domElement, rawProps);
7824 props = getHostProps$2(domElement, rawProps);
7825 trapBubbledEvent(TOP_INVALID, domElement);
7826 // For controlled components we always need to ensure we're listening
7827 // to onChange. Even if there is no listener.
7828 ensureListeningTo(rootContainerElement, 'onChange');
7829 break;
7830 case 'textarea':
7831 initWrapperState$2(domElement, rawProps);
7832 props = getHostProps$3(domElement, rawProps);
7833 trapBubbledEvent(TOP_INVALID, domElement);
7834 // For controlled components we always need to ensure we're listening
7835 // to onChange. Even if there is no listener.
7836 ensureListeningTo(rootContainerElement, 'onChange');
7837 break;
7838 default:
7839 props = rawProps;
7840 }
7841
7842 assertValidProps(tag, props);
7843
7844 setInitialDOMProperties(tag, domElement, rootContainerElement, props, isCustomComponentTag);
7845
7846 switch (tag) {
7847 case 'input':
7848 // TODO: Make sure we check if this is still unmounted or do any clean
7849 // up necessary since we never stop tracking anymore.
7850 track(domElement);
7851 postMountWrapper(domElement, rawProps, false);
7852 break;
7853 case 'textarea':
7854 // TODO: Make sure we check if this is still unmounted or do any clean
7855 // up necessary since we never stop tracking anymore.
7856 track(domElement);
7857 postMountWrapper$3(domElement, rawProps);
7858 break;
7859 case 'option':
7860 postMountWrapper$1(domElement, rawProps);
7861 break;
7862 case 'select':
7863 postMountWrapper$2(domElement, rawProps);
7864 break;
7865 default:
7866 if (typeof props.onClick === 'function') {
7867 // TODO: This cast may not be sound for SVG, MathML or custom elements.
7868 trapClickOnNonInteractiveElement(domElement);
7869 }
7870 break;
7871 }
7872}
7873
7874// Calculate the diff between the two objects.
7875function diffProperties(domElement, tag, lastRawProps, nextRawProps, rootContainerElement) {
7876 {
7877 validatePropertiesInDevelopment(tag, nextRawProps);
7878 }
7879
7880 var updatePayload = null;
7881
7882 var lastProps = void 0;
7883 var nextProps = void 0;
7884 switch (tag) {
7885 case 'input':
7886 lastProps = getHostProps(domElement, lastRawProps);
7887 nextProps = getHostProps(domElement, nextRawProps);
7888 updatePayload = [];
7889 break;
7890 case 'option':
7891 lastProps = getHostProps$1(domElement, lastRawProps);
7892 nextProps = getHostProps$1(domElement, nextRawProps);
7893 updatePayload = [];
7894 break;
7895 case 'select':
7896 lastProps = getHostProps$2(domElement, lastRawProps);
7897 nextProps = getHostProps$2(domElement, nextRawProps);
7898 updatePayload = [];
7899 break;
7900 case 'textarea':
7901 lastProps = getHostProps$3(domElement, lastRawProps);
7902 nextProps = getHostProps$3(domElement, nextRawProps);
7903 updatePayload = [];
7904 break;
7905 default:
7906 lastProps = lastRawProps;
7907 nextProps = nextRawProps;
7908 if (typeof lastProps.onClick !== 'function' && typeof nextProps.onClick === 'function') {
7909 // TODO: This cast may not be sound for SVG, MathML or custom elements.
7910 trapClickOnNonInteractiveElement(domElement);
7911 }
7912 break;
7913 }
7914
7915 assertValidProps(tag, nextProps);
7916
7917 var propKey = void 0;
7918 var styleName = void 0;
7919 var styleUpdates = null;
7920 for (propKey in lastProps) {
7921 if (nextProps.hasOwnProperty(propKey) || !lastProps.hasOwnProperty(propKey) || lastProps[propKey] == null) {
7922 continue;
7923 }
7924 if (propKey === STYLE$1) {
7925 var lastStyle = lastProps[propKey];
7926 for (styleName in lastStyle) {
7927 if (lastStyle.hasOwnProperty(styleName)) {
7928 if (!styleUpdates) {
7929 styleUpdates = {};
7930 }
7931 styleUpdates[styleName] = '';
7932 }
7933 }
7934 } else if (propKey === DANGEROUSLY_SET_INNER_HTML || propKey === CHILDREN) {
7935 // Noop. This is handled by the clear text mechanism.
7936 } else if (propKey === SUPPRESS_CONTENT_EDITABLE_WARNING || propKey === SUPPRESS_HYDRATION_WARNING$1) {
7937 // Noop
7938 } else if (propKey === AUTOFOCUS) {
7939 // Noop. It doesn't work on updates anyway.
7940 } else if (registrationNameModules.hasOwnProperty(propKey)) {
7941 // This is a special case. If any listener updates we need to ensure
7942 // that the "current" fiber pointer gets updated so we need a commit
7943 // to update this element.
7944 if (!updatePayload) {
7945 updatePayload = [];
7946 }
7947 } else {
7948 // For all other deleted properties we add it to the queue. We use
7949 // the whitelist in the commit phase instead.
7950 (updatePayload = updatePayload || []).push(propKey, null);
7951 }
7952 }
7953 for (propKey in nextProps) {
7954 var nextProp = nextProps[propKey];
7955 var lastProp = lastProps != null ? lastProps[propKey] : undefined;
7956 if (!nextProps.hasOwnProperty(propKey) || nextProp === lastProp || nextProp == null && lastProp == null) {
7957 continue;
7958 }
7959 if (propKey === STYLE$1) {
7960 {
7961 if (nextProp) {
7962 // Freeze the next style object so that we can assume it won't be
7963 // mutated. We have already warned for this in the past.
7964 Object.freeze(nextProp);
7965 }
7966 }
7967 if (lastProp) {
7968 // Unset styles on `lastProp` but not on `nextProp`.
7969 for (styleName in lastProp) {
7970 if (lastProp.hasOwnProperty(styleName) && (!nextProp || !nextProp.hasOwnProperty(styleName))) {
7971 if (!styleUpdates) {
7972 styleUpdates = {};
7973 }
7974 styleUpdates[styleName] = '';
7975 }
7976 }
7977 // Update styles that changed since `lastProp`.
7978 for (styleName in nextProp) {
7979 if (nextProp.hasOwnProperty(styleName) && lastProp[styleName] !== nextProp[styleName]) {
7980 if (!styleUpdates) {
7981 styleUpdates = {};
7982 }
7983 styleUpdates[styleName] = nextProp[styleName];
7984 }
7985 }
7986 } else {
7987 // Relies on `updateStylesByID` not mutating `styleUpdates`.
7988 if (!styleUpdates) {
7989 if (!updatePayload) {
7990 updatePayload = [];
7991 }
7992 updatePayload.push(propKey, styleUpdates);
7993 }
7994 styleUpdates = nextProp;
7995 }
7996 } else if (propKey === DANGEROUSLY_SET_INNER_HTML) {
7997 var nextHtml = nextProp ? nextProp[HTML] : undefined;
7998 var lastHtml = lastProp ? lastProp[HTML] : undefined;
7999 if (nextHtml != null) {
8000 if (lastHtml !== nextHtml) {
8001 (updatePayload = updatePayload || []).push(propKey, '' + nextHtml);
8002 }
8003 } else {
8004 // TODO: It might be too late to clear this if we have children
8005 // inserted already.
8006 }
8007 } else if (propKey === CHILDREN) {
8008 if (lastProp !== nextProp && (typeof nextProp === 'string' || typeof nextProp === 'number')) {
8009 (updatePayload = updatePayload || []).push(propKey, '' + nextProp);
8010 }
8011 } else if (propKey === SUPPRESS_CONTENT_EDITABLE_WARNING || propKey === SUPPRESS_HYDRATION_WARNING$1) {
8012 // Noop
8013 } else if (registrationNameModules.hasOwnProperty(propKey)) {
8014 if (nextProp != null) {
8015 // We eagerly listen to this even though we haven't committed yet.
8016 if (true && typeof nextProp !== 'function') {
8017 warnForInvalidEventListener(propKey, nextProp);
8018 }
8019 ensureListeningTo(rootContainerElement, propKey);
8020 }
8021 if (!updatePayload && lastProp !== nextProp) {
8022 // This is a special case. If any listener updates we need to ensure
8023 // that the "current" props pointer gets updated so we need a commit
8024 // to update this element.
8025 updatePayload = [];
8026 }
8027 } else {
8028 // For any other property we always add it to the queue and then we
8029 // filter it out using the whitelist during the commit.
8030 (updatePayload = updatePayload || []).push(propKey, nextProp);
8031 }
8032 }
8033 if (styleUpdates) {
8034 {
8035 validateShorthandPropertyCollisionInDev(styleUpdates, nextProps[STYLE$1]);
8036 }
8037 (updatePayload = updatePayload || []).push(STYLE$1, styleUpdates);
8038 }
8039 return updatePayload;
8040}
8041
8042// Apply the diff.
8043function updateProperties(domElement, updatePayload, tag, lastRawProps, nextRawProps) {
8044 // Update checked *before* name.
8045 // In the middle of an update, it is possible to have multiple checked.
8046 // When a checked radio tries to change name, browser makes another radio's checked false.
8047 if (tag === 'input' && nextRawProps.type === 'radio' && nextRawProps.name != null) {
8048 updateChecked(domElement, nextRawProps);
8049 }
8050
8051 var wasCustomComponentTag = isCustomComponent(tag, lastRawProps);
8052 var isCustomComponentTag = isCustomComponent(tag, nextRawProps);
8053 // Apply the diff.
8054 updateDOMProperties(domElement, updatePayload, wasCustomComponentTag, isCustomComponentTag);
8055
8056 // TODO: Ensure that an update gets scheduled if any of the special props
8057 // changed.
8058 switch (tag) {
8059 case 'input':
8060 // Update the wrapper around inputs *after* updating props. This has to
8061 // happen after `updateDOMProperties`. Otherwise HTML5 input validations
8062 // raise warnings and prevent the new value from being assigned.
8063 updateWrapper(domElement, nextRawProps);
8064 break;
8065 case 'textarea':
8066 updateWrapper$1(domElement, nextRawProps);
8067 break;
8068 case 'select':
8069 // <select> value update needs to occur after <option> children
8070 // reconciliation
8071 postUpdateWrapper(domElement, nextRawProps);
8072 break;
8073 }
8074}
8075
8076function getPossibleStandardName(propName) {
8077 {
8078 var lowerCasedName = propName.toLowerCase();
8079 if (!possibleStandardNames.hasOwnProperty(lowerCasedName)) {
8080 return null;
8081 }
8082 return possibleStandardNames[lowerCasedName] || null;
8083 }
8084 return null;
8085}
8086
8087function diffHydratedProperties(domElement, tag, rawProps, parentNamespace, rootContainerElement) {
8088 var isCustomComponentTag = void 0;
8089 var extraAttributeNames = void 0;
8090
8091 {
8092 suppressHydrationWarning = rawProps[SUPPRESS_HYDRATION_WARNING$1] === true;
8093 isCustomComponentTag = isCustomComponent(tag, rawProps);
8094 validatePropertiesInDevelopment(tag, rawProps);
8095 if (isCustomComponentTag && !didWarnShadyDOM && domElement.shadyRoot) {
8096 warning$1(false, '%s is using shady DOM. Using shady DOM with React can ' + 'cause things to break subtly.', getCurrentFiberOwnerNameInDevOrNull() || 'A component');
8097 didWarnShadyDOM = true;
8098 }
8099 }
8100
8101 // TODO: Make sure that we check isMounted before firing any of these events.
8102 switch (tag) {
8103 case 'iframe':
8104 case 'object':
8105 trapBubbledEvent(TOP_LOAD, domElement);
8106 break;
8107 case 'video':
8108 case 'audio':
8109 // Create listener for each media event
8110 for (var i = 0; i < mediaEventTypes.length; i++) {
8111 trapBubbledEvent(mediaEventTypes[i], domElement);
8112 }
8113 break;
8114 case 'source':
8115 trapBubbledEvent(TOP_ERROR, domElement);
8116 break;
8117 case 'img':
8118 case 'image':
8119 case 'link':
8120 trapBubbledEvent(TOP_ERROR, domElement);
8121 trapBubbledEvent(TOP_LOAD, domElement);
8122 break;
8123 case 'form':
8124 trapBubbledEvent(TOP_RESET, domElement);
8125 trapBubbledEvent(TOP_SUBMIT, domElement);
8126 break;
8127 case 'details':
8128 trapBubbledEvent(TOP_TOGGLE, domElement);
8129 break;
8130 case 'input':
8131 initWrapperState(domElement, rawProps);
8132 trapBubbledEvent(TOP_INVALID, domElement);
8133 // For controlled components we always need to ensure we're listening
8134 // to onChange. Even if there is no listener.
8135 ensureListeningTo(rootContainerElement, 'onChange');
8136 break;
8137 case 'option':
8138 validateProps(domElement, rawProps);
8139 break;
8140 case 'select':
8141 initWrapperState$1(domElement, rawProps);
8142 trapBubbledEvent(TOP_INVALID, domElement);
8143 // For controlled components we always need to ensure we're listening
8144 // to onChange. Even if there is no listener.
8145 ensureListeningTo(rootContainerElement, 'onChange');
8146 break;
8147 case 'textarea':
8148 initWrapperState$2(domElement, rawProps);
8149 trapBubbledEvent(TOP_INVALID, domElement);
8150 // For controlled components we always need to ensure we're listening
8151 // to onChange. Even if there is no listener.
8152 ensureListeningTo(rootContainerElement, 'onChange');
8153 break;
8154 }
8155
8156 assertValidProps(tag, rawProps);
8157
8158 {
8159 extraAttributeNames = new Set();
8160 var attributes = domElement.attributes;
8161 for (var _i = 0; _i < attributes.length; _i++) {
8162 var name = attributes[_i].name.toLowerCase();
8163 switch (name) {
8164 // Built-in SSR attribute is whitelisted
8165 case 'data-reactroot':
8166 break;
8167 // Controlled attributes are not validated
8168 // TODO: Only ignore them on controlled tags.
8169 case 'value':
8170 break;
8171 case 'checked':
8172 break;
8173 case 'selected':
8174 break;
8175 default:
8176 // Intentionally use the original name.
8177 // See discussion in https://github.com/facebook/react/pull/10676.
8178 extraAttributeNames.add(attributes[_i].name);
8179 }
8180 }
8181 }
8182
8183 var updatePayload = null;
8184 for (var propKey in rawProps) {
8185 if (!rawProps.hasOwnProperty(propKey)) {
8186 continue;
8187 }
8188 var nextProp = rawProps[propKey];
8189 if (propKey === CHILDREN) {
8190 // For text content children we compare against textContent. This
8191 // might match additional HTML that is hidden when we read it using
8192 // textContent. E.g. "foo" will match "f<span>oo</span>" but that still
8193 // satisfies our requirement. Our requirement is not to produce perfect
8194 // HTML and attributes. Ideally we should preserve structure but it's
8195 // ok not to if the visible content is still enough to indicate what
8196 // even listeners these nodes might be wired up to.
8197 // TODO: Warn if there is more than a single textNode as a child.
8198 // TODO: Should we use domElement.firstChild.nodeValue to compare?
8199 if (typeof nextProp === 'string') {
8200 if (domElement.textContent !== nextProp) {
8201 if (true && !suppressHydrationWarning) {
8202 warnForTextDifference(domElement.textContent, nextProp);
8203 }
8204 updatePayload = [CHILDREN, nextProp];
8205 }
8206 } else if (typeof nextProp === 'number') {
8207 if (domElement.textContent !== '' + nextProp) {
8208 if (true && !suppressHydrationWarning) {
8209 warnForTextDifference(domElement.textContent, nextProp);
8210 }
8211 updatePayload = [CHILDREN, '' + nextProp];
8212 }
8213 }
8214 } else if (registrationNameModules.hasOwnProperty(propKey)) {
8215 if (nextProp != null) {
8216 if (true && typeof nextProp !== 'function') {
8217 warnForInvalidEventListener(propKey, nextProp);
8218 }
8219 ensureListeningTo(rootContainerElement, propKey);
8220 }
8221 } else if (true &&
8222 // Convince Flow we've calculated it (it's DEV-only in this method.)
8223 typeof isCustomComponentTag === 'boolean') {
8224 // Validate that the properties correspond to their expected values.
8225 var serverValue = void 0;
8226 var propertyInfo = getPropertyInfo(propKey);
8227 if (suppressHydrationWarning) {
8228 // Don't bother comparing. We're ignoring all these warnings.
8229 } else if (propKey === SUPPRESS_CONTENT_EDITABLE_WARNING || propKey === SUPPRESS_HYDRATION_WARNING$1 ||
8230 // Controlled attributes are not validated
8231 // TODO: Only ignore them on controlled tags.
8232 propKey === 'value' || propKey === 'checked' || propKey === 'selected') {
8233 // Noop
8234 } else if (propKey === DANGEROUSLY_SET_INNER_HTML) {
8235 var serverHTML = domElement.innerHTML;
8236 var nextHtml = nextProp ? nextProp[HTML] : undefined;
8237 var expectedHTML = normalizeHTML(domElement, nextHtml != null ? nextHtml : '');
8238 if (expectedHTML !== serverHTML) {
8239 warnForPropDifference(propKey, serverHTML, expectedHTML);
8240 }
8241 } else if (propKey === STYLE$1) {
8242 // $FlowFixMe - Should be inferred as not undefined.
8243 extraAttributeNames.delete(propKey);
8244
8245 if (canDiffStyleForHydrationWarning) {
8246 var expectedStyle = createDangerousStringForStyles(nextProp);
8247 serverValue = domElement.getAttribute('style');
8248 if (expectedStyle !== serverValue) {
8249 warnForPropDifference(propKey, serverValue, expectedStyle);
8250 }
8251 }
8252 } else if (isCustomComponentTag) {
8253 // $FlowFixMe - Should be inferred as not undefined.
8254 extraAttributeNames.delete(propKey.toLowerCase());
8255 serverValue = getValueForAttribute(domElement, propKey, nextProp);
8256
8257 if (nextProp !== serverValue) {
8258 warnForPropDifference(propKey, serverValue, nextProp);
8259 }
8260 } else if (!shouldIgnoreAttribute(propKey, propertyInfo, isCustomComponentTag) && !shouldRemoveAttribute(propKey, nextProp, propertyInfo, isCustomComponentTag)) {
8261 var isMismatchDueToBadCasing = false;
8262 if (propertyInfo !== null) {
8263 // $FlowFixMe - Should be inferred as not undefined.
8264 extraAttributeNames.delete(propertyInfo.attributeName);
8265 serverValue = getValueForProperty(domElement, propKey, nextProp, propertyInfo);
8266 } else {
8267 var ownNamespace = parentNamespace;
8268 if (ownNamespace === HTML_NAMESPACE) {
8269 ownNamespace = getIntrinsicNamespace(tag);
8270 }
8271 if (ownNamespace === HTML_NAMESPACE) {
8272 // $FlowFixMe - Should be inferred as not undefined.
8273 extraAttributeNames.delete(propKey.toLowerCase());
8274 } else {
8275 var standardName = getPossibleStandardName(propKey);
8276 if (standardName !== null && standardName !== propKey) {
8277 // If an SVG prop is supplied with bad casing, it will
8278 // be successfully parsed from HTML, but will produce a mismatch
8279 // (and would be incorrectly rendered on the client).
8280 // However, we already warn about bad casing elsewhere.
8281 // So we'll skip the misleading extra mismatch warning in this case.
8282 isMismatchDueToBadCasing = true;
8283 // $FlowFixMe - Should be inferred as not undefined.
8284 extraAttributeNames.delete(standardName);
8285 }
8286 // $FlowFixMe - Should be inferred as not undefined.
8287 extraAttributeNames.delete(propKey);
8288 }
8289 serverValue = getValueForAttribute(domElement, propKey, nextProp);
8290 }
8291
8292 if (nextProp !== serverValue && !isMismatchDueToBadCasing) {
8293 warnForPropDifference(propKey, serverValue, nextProp);
8294 }
8295 }
8296 }
8297 }
8298
8299 {
8300 // $FlowFixMe - Should be inferred as not undefined.
8301 if (extraAttributeNames.size > 0 && !suppressHydrationWarning) {
8302 // $FlowFixMe - Should be inferred as not undefined.
8303 warnForExtraAttributes(extraAttributeNames);
8304 }
8305 }
8306
8307 switch (tag) {
8308 case 'input':
8309 // TODO: Make sure we check if this is still unmounted or do any clean
8310 // up necessary since we never stop tracking anymore.
8311 track(domElement);
8312 postMountWrapper(domElement, rawProps, true);
8313 break;
8314 case 'textarea':
8315 // TODO: Make sure we check if this is still unmounted or do any clean
8316 // up necessary since we never stop tracking anymore.
8317 track(domElement);
8318 postMountWrapper$3(domElement, rawProps);
8319 break;
8320 case 'select':
8321 case 'option':
8322 // For input and textarea we current always set the value property at
8323 // post mount to force it to diverge from attributes. However, for
8324 // option and select we don't quite do the same thing and select
8325 // is not resilient to the DOM state changing so we don't do that here.
8326 // TODO: Consider not doing this for input and textarea.
8327 break;
8328 default:
8329 if (typeof rawProps.onClick === 'function') {
8330 // TODO: This cast may not be sound for SVG, MathML or custom elements.
8331 trapClickOnNonInteractiveElement(domElement);
8332 }
8333 break;
8334 }
8335
8336 return updatePayload;
8337}
8338
8339function diffHydratedText(textNode, text) {
8340 var isDifferent = textNode.nodeValue !== text;
8341 return isDifferent;
8342}
8343
8344function warnForUnmatchedText(textNode, text) {
8345 {
8346 warnForTextDifference(textNode.nodeValue, text);
8347 }
8348}
8349
8350function warnForDeletedHydratableElement(parentNode, child) {
8351 {
8352 if (didWarnInvalidHydration) {
8353 return;
8354 }
8355 didWarnInvalidHydration = true;
8356 warningWithoutStack$1(false, 'Did not expect server HTML to contain a <%s> in <%s>.', child.nodeName.toLowerCase(), parentNode.nodeName.toLowerCase());
8357 }
8358}
8359
8360function warnForDeletedHydratableText(parentNode, child) {
8361 {
8362 if (didWarnInvalidHydration) {
8363 return;
8364 }
8365 didWarnInvalidHydration = true;
8366 warningWithoutStack$1(false, 'Did not expect server HTML to contain the text node "%s" in <%s>.', child.nodeValue, parentNode.nodeName.toLowerCase());
8367 }
8368}
8369
8370function warnForInsertedHydratedElement(parentNode, tag, props) {
8371 {
8372 if (didWarnInvalidHydration) {
8373 return;
8374 }
8375 didWarnInvalidHydration = true;
8376 warningWithoutStack$1(false, 'Expected server HTML to contain a matching <%s> in <%s>.', tag, parentNode.nodeName.toLowerCase());
8377 }
8378}
8379
8380function warnForInsertedHydratedText(parentNode, text) {
8381 {
8382 if (text === '') {
8383 // We expect to insert empty text nodes since they're not represented in
8384 // the HTML.
8385 // TODO: Remove this special case if we can just avoid inserting empty
8386 // text nodes.
8387 return;
8388 }
8389 if (didWarnInvalidHydration) {
8390 return;
8391 }
8392 didWarnInvalidHydration = true;
8393 warningWithoutStack$1(false, 'Expected server HTML to contain a matching text node for "%s" in <%s>.', text, parentNode.nodeName.toLowerCase());
8394 }
8395}
8396
8397function restoreControlledState$1(domElement, tag, props) {
8398 switch (tag) {
8399 case 'input':
8400 restoreControlledState(domElement, props);
8401 return;
8402 case 'textarea':
8403 restoreControlledState$3(domElement, props);
8404 return;
8405 case 'select':
8406 restoreControlledState$2(domElement, props);
8407 return;
8408 }
8409}
8410
8411// TODO: direct imports like some-package/src/* are bad. Fix me.
8412var validateDOMNesting = function () {};
8413var updatedAncestorInfo = function () {};
8414
8415{
8416 // This validation code was written based on the HTML5 parsing spec:
8417 // https://html.spec.whatwg.org/multipage/syntax.html#has-an-element-in-scope
8418 //
8419 // Note: this does not catch all invalid nesting, nor does it try to (as it's
8420 // not clear what practical benefit doing so provides); instead, we warn only
8421 // for cases where the parser will give a parse tree differing from what React
8422 // intended. For example, <b><div></div></b> is invalid but we don't warn
8423 // because it still parses correctly; we do warn for other cases like nested
8424 // <p> tags where the beginning of the second element implicitly closes the
8425 // first, causing a confusing mess.
8426
8427 // https://html.spec.whatwg.org/multipage/syntax.html#special
8428 var specialTags = ['address', 'applet', 'area', 'article', 'aside', 'base', 'basefont', 'bgsound', 'blockquote', 'body', 'br', 'button', 'caption', 'center', 'col', 'colgroup', 'dd', 'details', 'dir', 'div', 'dl', 'dt', 'embed', 'fieldset', 'figcaption', 'figure', 'footer', 'form', 'frame', 'frameset', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'head', 'header', 'hgroup', 'hr', 'html', 'iframe', 'img', 'input', 'isindex', 'li', 'link', 'listing', 'main', 'marquee', 'menu', 'menuitem', 'meta', 'nav', 'noembed', 'noframes', 'noscript', 'object', 'ol', 'p', 'param', 'plaintext', 'pre', 'script', 'section', 'select', 'source', 'style', 'summary', 'table', 'tbody', 'td', 'template', 'textarea', 'tfoot', 'th', 'thead', 'title', 'tr', 'track', 'ul', 'wbr', 'xmp'];
8429
8430 // https://html.spec.whatwg.org/multipage/syntax.html#has-an-element-in-scope
8431 var inScopeTags = ['applet', 'caption', 'html', 'table', 'td', 'th', 'marquee', 'object', 'template',
8432
8433 // https://html.spec.whatwg.org/multipage/syntax.html#html-integration-point
8434 // TODO: Distinguish by namespace here -- for <title>, including it here
8435 // errs on the side of fewer warnings
8436 'foreignObject', 'desc', 'title'];
8437
8438 // https://html.spec.whatwg.org/multipage/syntax.html#has-an-element-in-button-scope
8439 var buttonScopeTags = inScopeTags.concat(['button']);
8440
8441 // https://html.spec.whatwg.org/multipage/syntax.html#generate-implied-end-tags
8442 var impliedEndTags = ['dd', 'dt', 'li', 'option', 'optgroup', 'p', 'rp', 'rt'];
8443
8444 var emptyAncestorInfo = {
8445 current: null,
8446
8447 formTag: null,
8448 aTagInScope: null,
8449 buttonTagInScope: null,
8450 nobrTagInScope: null,
8451 pTagInButtonScope: null,
8452
8453 listItemTagAutoclosing: null,
8454 dlItemTagAutoclosing: null
8455 };
8456
8457 updatedAncestorInfo = function (oldInfo, tag) {
8458 var ancestorInfo = _assign({}, oldInfo || emptyAncestorInfo);
8459 var info = { tag: tag };
8460
8461 if (inScopeTags.indexOf(tag) !== -1) {
8462 ancestorInfo.aTagInScope = null;
8463 ancestorInfo.buttonTagInScope = null;
8464 ancestorInfo.nobrTagInScope = null;
8465 }
8466 if (buttonScopeTags.indexOf(tag) !== -1) {
8467 ancestorInfo.pTagInButtonScope = null;
8468 }
8469
8470 // See rules for 'li', 'dd', 'dt' start tags in
8471 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inbody
8472 if (specialTags.indexOf(tag) !== -1 && tag !== 'address' && tag !== 'div' && tag !== 'p') {
8473 ancestorInfo.listItemTagAutoclosing = null;
8474 ancestorInfo.dlItemTagAutoclosing = null;
8475 }
8476
8477 ancestorInfo.current = info;
8478
8479 if (tag === 'form') {
8480 ancestorInfo.formTag = info;
8481 }
8482 if (tag === 'a') {
8483 ancestorInfo.aTagInScope = info;
8484 }
8485 if (tag === 'button') {
8486 ancestorInfo.buttonTagInScope = info;
8487 }
8488 if (tag === 'nobr') {
8489 ancestorInfo.nobrTagInScope = info;
8490 }
8491 if (tag === 'p') {
8492 ancestorInfo.pTagInButtonScope = info;
8493 }
8494 if (tag === 'li') {
8495 ancestorInfo.listItemTagAutoclosing = info;
8496 }
8497 if (tag === 'dd' || tag === 'dt') {
8498 ancestorInfo.dlItemTagAutoclosing = info;
8499 }
8500
8501 return ancestorInfo;
8502 };
8503
8504 /**
8505 * Returns whether
8506 */
8507 var isTagValidWithParent = function (tag, parentTag) {
8508 // First, let's check if we're in an unusual parsing mode...
8509 switch (parentTag) {
8510 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inselect
8511 case 'select':
8512 return tag === 'option' || tag === 'optgroup' || tag === '#text';
8513 case 'optgroup':
8514 return tag === 'option' || tag === '#text';
8515 // Strictly speaking, seeing an <option> doesn't mean we're in a <select>
8516 // but
8517 case 'option':
8518 return tag === '#text';
8519 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intd
8520 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-incaption
8521 // No special behavior since these rules fall back to "in body" mode for
8522 // all except special table nodes which cause bad parsing behavior anyway.
8523
8524 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intr
8525 case 'tr':
8526 return tag === 'th' || tag === 'td' || tag === 'style' || tag === 'script' || tag === 'template';
8527 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intbody
8528 case 'tbody':
8529 case 'thead':
8530 case 'tfoot':
8531 return tag === 'tr' || tag === 'style' || tag === 'script' || tag === 'template';
8532 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-incolgroup
8533 case 'colgroup':
8534 return tag === 'col' || tag === 'template';
8535 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intable
8536 case 'table':
8537 return tag === 'caption' || tag === 'colgroup' || tag === 'tbody' || tag === 'tfoot' || tag === 'thead' || tag === 'style' || tag === 'script' || tag === 'template';
8538 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inhead
8539 case 'head':
8540 return tag === 'base' || tag === 'basefont' || tag === 'bgsound' || tag === 'link' || tag === 'meta' || tag === 'title' || tag === 'noscript' || tag === 'noframes' || tag === 'style' || tag === 'script' || tag === 'template';
8541 // https://html.spec.whatwg.org/multipage/semantics.html#the-html-element
8542 case 'html':
8543 return tag === 'head' || tag === 'body';
8544 case '#document':
8545 return tag === 'html';
8546 }
8547
8548 // Probably in the "in body" parsing mode, so we outlaw only tag combos
8549 // where the parsing rules cause implicit opens or closes to be added.
8550 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inbody
8551 switch (tag) {
8552 case 'h1':
8553 case 'h2':
8554 case 'h3':
8555 case 'h4':
8556 case 'h5':
8557 case 'h6':
8558 return parentTag !== 'h1' && parentTag !== 'h2' && parentTag !== 'h3' && parentTag !== 'h4' && parentTag !== 'h5' && parentTag !== 'h6';
8559
8560 case 'rp':
8561 case 'rt':
8562 return impliedEndTags.indexOf(parentTag) === -1;
8563
8564 case 'body':
8565 case 'caption':
8566 case 'col':
8567 case 'colgroup':
8568 case 'frame':
8569 case 'head':
8570 case 'html':
8571 case 'tbody':
8572 case 'td':
8573 case 'tfoot':
8574 case 'th':
8575 case 'thead':
8576 case 'tr':
8577 // These tags are only valid with a few parents that have special child
8578 // parsing rules -- if we're down here, then none of those matched and
8579 // so we allow it only if we don't know what the parent is, as all other
8580 // cases are invalid.
8581 return parentTag == null;
8582 }
8583
8584 return true;
8585 };
8586
8587 /**
8588 * Returns whether
8589 */
8590 var findInvalidAncestorForTag = function (tag, ancestorInfo) {
8591 switch (tag) {
8592 case 'address':
8593 case 'article':
8594 case 'aside':
8595 case 'blockquote':
8596 case 'center':
8597 case 'details':
8598 case 'dialog':
8599 case 'dir':
8600 case 'div':
8601 case 'dl':
8602 case 'fieldset':
8603 case 'figcaption':
8604 case 'figure':
8605 case 'footer':
8606 case 'header':
8607 case 'hgroup':
8608 case 'main':
8609 case 'menu':
8610 case 'nav':
8611 case 'ol':
8612 case 'p':
8613 case 'section':
8614 case 'summary':
8615 case 'ul':
8616 case 'pre':
8617 case 'listing':
8618 case 'table':
8619 case 'hr':
8620 case 'xmp':
8621 case 'h1':
8622 case 'h2':
8623 case 'h3':
8624 case 'h4':
8625 case 'h5':
8626 case 'h6':
8627 return ancestorInfo.pTagInButtonScope;
8628
8629 case 'form':
8630 return ancestorInfo.formTag || ancestorInfo.pTagInButtonScope;
8631
8632 case 'li':
8633 return ancestorInfo.listItemTagAutoclosing;
8634
8635 case 'dd':
8636 case 'dt':
8637 return ancestorInfo.dlItemTagAutoclosing;
8638
8639 case 'button':
8640 return ancestorInfo.buttonTagInScope;
8641
8642 case 'a':
8643 // Spec says something about storing a list of markers, but it sounds
8644 // equivalent to this check.
8645 return ancestorInfo.aTagInScope;
8646
8647 case 'nobr':
8648 return ancestorInfo.nobrTagInScope;
8649 }
8650
8651 return null;
8652 };
8653
8654 var didWarn = {};
8655
8656 validateDOMNesting = function (childTag, childText, ancestorInfo) {
8657 ancestorInfo = ancestorInfo || emptyAncestorInfo;
8658 var parentInfo = ancestorInfo.current;
8659 var parentTag = parentInfo && parentInfo.tag;
8660
8661 if (childText != null) {
8662 !(childTag == null) ? warningWithoutStack$1(false, 'validateDOMNesting: when childText is passed, childTag should be null') : void 0;
8663 childTag = '#text';
8664 }
8665
8666 var invalidParent = isTagValidWithParent(childTag, parentTag) ? null : parentInfo;
8667 var invalidAncestor = invalidParent ? null : findInvalidAncestorForTag(childTag, ancestorInfo);
8668 var invalidParentOrAncestor = invalidParent || invalidAncestor;
8669 if (!invalidParentOrAncestor) {
8670 return;
8671 }
8672
8673 var ancestorTag = invalidParentOrAncestor.tag;
8674 var addendum = getCurrentFiberStackInDev();
8675
8676 var warnKey = !!invalidParent + '|' + childTag + '|' + ancestorTag + '|' + addendum;
8677 if (didWarn[warnKey]) {
8678 return;
8679 }
8680 didWarn[warnKey] = true;
8681
8682 var tagDisplayName = childTag;
8683 var whitespaceInfo = '';
8684 if (childTag === '#text') {
8685 if (/\S/.test(childText)) {
8686 tagDisplayName = 'Text nodes';
8687 } else {
8688 tagDisplayName = 'Whitespace text nodes';
8689 whitespaceInfo = " Make sure you don't have any extra whitespace between tags on " + 'each line of your source code.';
8690 }
8691 } else {
8692 tagDisplayName = '<' + childTag + '>';
8693 }
8694
8695 if (invalidParent) {
8696 var info = '';
8697 if (ancestorTag === 'table' && childTag === 'tr') {
8698 info += ' Add a <tbody> to your code to match the DOM tree generated by ' + 'the browser.';
8699 }
8700 warningWithoutStack$1(false, 'validateDOMNesting(...): %s cannot appear as a child of <%s>.%s%s%s', tagDisplayName, ancestorTag, whitespaceInfo, info, addendum);
8701 } else {
8702 warningWithoutStack$1(false, 'validateDOMNesting(...): %s cannot appear as a descendant of ' + '<%s>.%s', tagDisplayName, ancestorTag, addendum);
8703 }
8704 };
8705}
8706
8707var ReactInternals$1 = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
8708
8709var _ReactInternals$Sched = ReactInternals$1.Scheduler;
8710var unstable_cancelCallback = _ReactInternals$Sched.unstable_cancelCallback;
8711var unstable_now = _ReactInternals$Sched.unstable_now;
8712var unstable_scheduleCallback = _ReactInternals$Sched.unstable_scheduleCallback;
8713var unstable_shouldYield = _ReactInternals$Sched.unstable_shouldYield;
8714var unstable_getFirstCallbackNode = _ReactInternals$Sched.unstable_getFirstCallbackNode;
8715var unstable_continueExecution = _ReactInternals$Sched.unstable_continueExecution;
8716var unstable_pauseExecution = _ReactInternals$Sched.unstable_pauseExecution;
8717
8718// Renderers that don't support persistence
8719// can re-export everything from this module.
8720
8721function shim() {
8722 invariant(false, 'The current renderer does not support persistence. This error is likely caused by a bug in React. Please file an issue.');
8723}
8724
8725// Persistence (when unsupported)
8726var supportsPersistence = false;
8727var cloneInstance = shim;
8728var createContainerChildSet = shim;
8729var appendChildToContainerChildSet = shim;
8730var finalizeContainerChildren = shim;
8731var replaceContainerChildren = shim;
8732var cloneHiddenInstance = shim;
8733var cloneUnhiddenInstance = shim;
8734var createHiddenTextInstance = shim;
8735
8736var SUPPRESS_HYDRATION_WARNING = void 0;
8737{
8738 SUPPRESS_HYDRATION_WARNING = 'suppressHydrationWarning';
8739}
8740
8741var STYLE = 'style';
8742
8743var eventsEnabled = null;
8744var selectionInformation = null;
8745
8746function shouldAutoFocusHostComponent(type, props) {
8747 switch (type) {
8748 case 'button':
8749 case 'input':
8750 case 'select':
8751 case 'textarea':
8752 return !!props.autoFocus;
8753 }
8754 return false;
8755}
8756
8757function getRootHostContext(rootContainerInstance) {
8758 var type = void 0;
8759 var namespace = void 0;
8760 var nodeType = rootContainerInstance.nodeType;
8761 switch (nodeType) {
8762 case DOCUMENT_NODE:
8763 case DOCUMENT_FRAGMENT_NODE:
8764 {
8765 type = nodeType === DOCUMENT_NODE ? '#document' : '#fragment';
8766 var root = rootContainerInstance.documentElement;
8767 namespace = root ? root.namespaceURI : getChildNamespace(null, '');
8768 break;
8769 }
8770 default:
8771 {
8772 var container = nodeType === COMMENT_NODE ? rootContainerInstance.parentNode : rootContainerInstance;
8773 var ownNamespace = container.namespaceURI || null;
8774 type = container.tagName;
8775 namespace = getChildNamespace(ownNamespace, type);
8776 break;
8777 }
8778 }
8779 {
8780 var validatedTag = type.toLowerCase();
8781 var _ancestorInfo = updatedAncestorInfo(null, validatedTag);
8782 return { namespace: namespace, ancestorInfo: _ancestorInfo };
8783 }
8784 return namespace;
8785}
8786
8787function getChildHostContext(parentHostContext, type, rootContainerInstance) {
8788 {
8789 var parentHostContextDev = parentHostContext;
8790 var _namespace = getChildNamespace(parentHostContextDev.namespace, type);
8791 var _ancestorInfo2 = updatedAncestorInfo(parentHostContextDev.ancestorInfo, type);
8792 return { namespace: _namespace, ancestorInfo: _ancestorInfo2 };
8793 }
8794 var parentNamespace = parentHostContext;
8795 return getChildNamespace(parentNamespace, type);
8796}
8797
8798function getPublicInstance(instance) {
8799 return instance;
8800}
8801
8802function prepareForCommit(containerInfo) {
8803 eventsEnabled = isEnabled();
8804 selectionInformation = getSelectionInformation();
8805 setEnabled(false);
8806}
8807
8808function resetAfterCommit(containerInfo) {
8809 restoreSelection(selectionInformation);
8810 selectionInformation = null;
8811 setEnabled(eventsEnabled);
8812 eventsEnabled = null;
8813}
8814
8815function createInstance(type, props, rootContainerInstance, hostContext, internalInstanceHandle) {
8816 var parentNamespace = void 0;
8817 {
8818 // TODO: take namespace into account when validating.
8819 var hostContextDev = hostContext;
8820 validateDOMNesting(type, null, hostContextDev.ancestorInfo);
8821 if (typeof props.children === 'string' || typeof props.children === 'number') {
8822 var string = '' + props.children;
8823 var ownAncestorInfo = updatedAncestorInfo(hostContextDev.ancestorInfo, type);
8824 validateDOMNesting(null, string, ownAncestorInfo);
8825 }
8826 parentNamespace = hostContextDev.namespace;
8827 }
8828 var domElement = createElement(type, props, rootContainerInstance, parentNamespace);
8829 precacheFiberNode(internalInstanceHandle, domElement);
8830 updateFiberProps(domElement, props);
8831 return domElement;
8832}
8833
8834function appendInitialChild(parentInstance, child) {
8835 parentInstance.appendChild(child);
8836}
8837
8838function finalizeInitialChildren(domElement, type, props, rootContainerInstance, hostContext) {
8839 setInitialProperties(domElement, type, props, rootContainerInstance);
8840 return shouldAutoFocusHostComponent(type, props);
8841}
8842
8843function prepareUpdate(domElement, type, oldProps, newProps, rootContainerInstance, hostContext) {
8844 {
8845 var hostContextDev = hostContext;
8846 if (typeof newProps.children !== typeof oldProps.children && (typeof newProps.children === 'string' || typeof newProps.children === 'number')) {
8847 var string = '' + newProps.children;
8848 var ownAncestorInfo = updatedAncestorInfo(hostContextDev.ancestorInfo, type);
8849 validateDOMNesting(null, string, ownAncestorInfo);
8850 }
8851 }
8852 return diffProperties(domElement, type, oldProps, newProps, rootContainerInstance);
8853}
8854
8855function shouldSetTextContent(type, props) {
8856 return type === 'textarea' || type === 'option' || type === 'noscript' || typeof props.children === 'string' || typeof props.children === 'number' || typeof props.dangerouslySetInnerHTML === 'object' && props.dangerouslySetInnerHTML !== null && props.dangerouslySetInnerHTML.__html != null;
8857}
8858
8859function shouldDeprioritizeSubtree(type, props) {
8860 return !!props.hidden;
8861}
8862
8863function createTextInstance(text, rootContainerInstance, hostContext, internalInstanceHandle) {
8864 {
8865 var hostContextDev = hostContext;
8866 validateDOMNesting(null, text, hostContextDev.ancestorInfo);
8867 }
8868 var textNode = createTextNode(text, rootContainerInstance);
8869 precacheFiberNode(internalInstanceHandle, textNode);
8870 return textNode;
8871}
8872
8873var isPrimaryRenderer = true;
8874// This initialization code may run even on server environments
8875// if a component just imports ReactDOM (e.g. for findDOMNode).
8876// Some environments might not have setTimeout or clearTimeout.
8877var scheduleTimeout = typeof setTimeout === 'function' ? setTimeout : undefined;
8878var cancelTimeout = typeof clearTimeout === 'function' ? clearTimeout : undefined;
8879var noTimeout = -1;
8880
8881// -------------------
8882// Mutation
8883// -------------------
8884
8885var supportsMutation = true;
8886
8887function commitMount(domElement, type, newProps, internalInstanceHandle) {
8888 // Despite the naming that might imply otherwise, this method only
8889 // fires if there is an `Update` effect scheduled during mounting.
8890 // This happens if `finalizeInitialChildren` returns `true` (which it
8891 // does to implement the `autoFocus` attribute on the client). But
8892 // there are also other cases when this might happen (such as patching
8893 // up text content during hydration mismatch). So we'll check this again.
8894 if (shouldAutoFocusHostComponent(type, newProps)) {
8895 domElement.focus();
8896 }
8897}
8898
8899function commitUpdate(domElement, updatePayload, type, oldProps, newProps, internalInstanceHandle) {
8900 // Update the props handle so that we know which props are the ones with
8901 // with current event handlers.
8902 updateFiberProps(domElement, newProps);
8903 // Apply the diff to the DOM node.
8904 updateProperties(domElement, updatePayload, type, oldProps, newProps);
8905}
8906
8907function resetTextContent(domElement) {
8908 setTextContent(domElement, '');
8909}
8910
8911function commitTextUpdate(textInstance, oldText, newText) {
8912 textInstance.nodeValue = newText;
8913}
8914
8915function appendChild(parentInstance, child) {
8916 parentInstance.appendChild(child);
8917}
8918
8919function appendChildToContainer(container, child) {
8920 var parentNode = void 0;
8921 if (container.nodeType === COMMENT_NODE) {
8922 parentNode = container.parentNode;
8923 parentNode.insertBefore(child, container);
8924 } else {
8925 parentNode = container;
8926 parentNode.appendChild(child);
8927 }
8928 // This container might be used for a portal.
8929 // If something inside a portal is clicked, that click should bubble
8930 // through the React tree. However, on Mobile Safari the click would
8931 // never bubble through the *DOM* tree unless an ancestor with onclick
8932 // event exists. So we wouldn't see it and dispatch it.
8933 // This is why we ensure that non React root containers have inline onclick
8934 // defined.
8935 // https://github.com/facebook/react/issues/11918
8936 var reactRootContainer = container._reactRootContainer;
8937 if ((reactRootContainer === null || reactRootContainer === undefined) && parentNode.onclick === null) {
8938 // TODO: This cast may not be sound for SVG, MathML or custom elements.
8939 trapClickOnNonInteractiveElement(parentNode);
8940 }
8941}
8942
8943function insertBefore(parentInstance, child, beforeChild) {
8944 parentInstance.insertBefore(child, beforeChild);
8945}
8946
8947function insertInContainerBefore(container, child, beforeChild) {
8948 if (container.nodeType === COMMENT_NODE) {
8949 container.parentNode.insertBefore(child, beforeChild);
8950 } else {
8951 container.insertBefore(child, beforeChild);
8952 }
8953}
8954
8955function removeChild(parentInstance, child) {
8956 parentInstance.removeChild(child);
8957}
8958
8959function removeChildFromContainer(container, child) {
8960 if (container.nodeType === COMMENT_NODE) {
8961 container.parentNode.removeChild(child);
8962 } else {
8963 container.removeChild(child);
8964 }
8965}
8966
8967function hideInstance(instance) {
8968 // TODO: Does this work for all element types? What about MathML? Should we
8969 // pass host context to this method?
8970 instance = instance;
8971 instance.style.display = 'none';
8972}
8973
8974function hideTextInstance(textInstance) {
8975 textInstance.nodeValue = '';
8976}
8977
8978function unhideInstance(instance, props) {
8979 instance = instance;
8980 var styleProp = props[STYLE];
8981 var display = styleProp !== undefined && styleProp !== null && styleProp.hasOwnProperty('display') ? styleProp.display : null;
8982 instance.style.display = dangerousStyleValue('display', display);
8983}
8984
8985function unhideTextInstance(textInstance, text) {
8986 textInstance.nodeValue = text;
8987}
8988
8989// -------------------
8990// Hydration
8991// -------------------
8992
8993var supportsHydration = true;
8994
8995function canHydrateInstance(instance, type, props) {
8996 if (instance.nodeType !== ELEMENT_NODE || type.toLowerCase() !== instance.nodeName.toLowerCase()) {
8997 return null;
8998 }
8999 // This has now been refined to an element node.
9000 return instance;
9001}
9002
9003function canHydrateTextInstance(instance, text) {
9004 if (text === '' || instance.nodeType !== TEXT_NODE) {
9005 // Empty strings are not parsed by HTML so there won't be a correct match here.
9006 return null;
9007 }
9008 // This has now been refined to a text node.
9009 return instance;
9010}
9011
9012function getNextHydratableSibling(instance) {
9013 var node = instance.nextSibling;
9014 // Skip non-hydratable nodes.
9015 while (node && node.nodeType !== ELEMENT_NODE && node.nodeType !== TEXT_NODE) {
9016 node = node.nextSibling;
9017 }
9018 return node;
9019}
9020
9021function getFirstHydratableChild(parentInstance) {
9022 var next = parentInstance.firstChild;
9023 // Skip non-hydratable nodes.
9024 while (next && next.nodeType !== ELEMENT_NODE && next.nodeType !== TEXT_NODE) {
9025 next = next.nextSibling;
9026 }
9027 return next;
9028}
9029
9030function hydrateInstance(instance, type, props, rootContainerInstance, hostContext, internalInstanceHandle) {
9031 precacheFiberNode(internalInstanceHandle, instance);
9032 // TODO: Possibly defer this until the commit phase where all the events
9033 // get attached.
9034 updateFiberProps(instance, props);
9035 var parentNamespace = void 0;
9036 {
9037 var hostContextDev = hostContext;
9038 parentNamespace = hostContextDev.namespace;
9039 }
9040 return diffHydratedProperties(instance, type, props, parentNamespace, rootContainerInstance);
9041}
9042
9043function hydrateTextInstance(textInstance, text, internalInstanceHandle) {
9044 precacheFiberNode(internalInstanceHandle, textInstance);
9045 return diffHydratedText(textInstance, text);
9046}
9047
9048function didNotMatchHydratedContainerTextInstance(parentContainer, textInstance, text) {
9049 {
9050 warnForUnmatchedText(textInstance, text);
9051 }
9052}
9053
9054function didNotMatchHydratedTextInstance(parentType, parentProps, parentInstance, textInstance, text) {
9055 if (true && parentProps[SUPPRESS_HYDRATION_WARNING] !== true) {
9056 warnForUnmatchedText(textInstance, text);
9057 }
9058}
9059
9060function didNotHydrateContainerInstance(parentContainer, instance) {
9061 {
9062 if (instance.nodeType === ELEMENT_NODE) {
9063 warnForDeletedHydratableElement(parentContainer, instance);
9064 } else {
9065 warnForDeletedHydratableText(parentContainer, instance);
9066 }
9067 }
9068}
9069
9070function didNotHydrateInstance(parentType, parentProps, parentInstance, instance) {
9071 if (true && parentProps[SUPPRESS_HYDRATION_WARNING] !== true) {
9072 if (instance.nodeType === ELEMENT_NODE) {
9073 warnForDeletedHydratableElement(parentInstance, instance);
9074 } else {
9075 warnForDeletedHydratableText(parentInstance, instance);
9076 }
9077 }
9078}
9079
9080function didNotFindHydratableContainerInstance(parentContainer, type, props) {
9081 {
9082 warnForInsertedHydratedElement(parentContainer, type, props);
9083 }
9084}
9085
9086function didNotFindHydratableContainerTextInstance(parentContainer, text) {
9087 {
9088 warnForInsertedHydratedText(parentContainer, text);
9089 }
9090}
9091
9092function didNotFindHydratableInstance(parentType, parentProps, parentInstance, type, props) {
9093 if (true && parentProps[SUPPRESS_HYDRATION_WARNING] !== true) {
9094 warnForInsertedHydratedElement(parentInstance, type, props);
9095 }
9096}
9097
9098function didNotFindHydratableTextInstance(parentType, parentProps, parentInstance, text) {
9099 if (true && parentProps[SUPPRESS_HYDRATION_WARNING] !== true) {
9100 warnForInsertedHydratedText(parentInstance, text);
9101 }
9102}
9103
9104// Prefix measurements so that it's possible to filter them.
9105// Longer prefixes are hard to read in DevTools.
9106var reactEmoji = '\u269B';
9107var warningEmoji = '\u26D4';
9108var supportsUserTiming = typeof performance !== 'undefined' && typeof performance.mark === 'function' && typeof performance.clearMarks === 'function' && typeof performance.measure === 'function' && typeof performance.clearMeasures === 'function';
9109
9110// Keep track of current fiber so that we know the path to unwind on pause.
9111// TODO: this looks the same as nextUnitOfWork in scheduler. Can we unify them?
9112var currentFiber = null;
9113// If we're in the middle of user code, which fiber and method is it?
9114// Reusing `currentFiber` would be confusing for this because user code fiber
9115// can change during commit phase too, but we don't need to unwind it (since
9116// lifecycles in the commit phase don't resemble a tree).
9117var currentPhase = null;
9118var currentPhaseFiber = null;
9119// Did lifecycle hook schedule an update? This is often a performance problem,
9120// so we will keep track of it, and include it in the report.
9121// Track commits caused by cascading updates.
9122var isCommitting = false;
9123var hasScheduledUpdateInCurrentCommit = false;
9124var hasScheduledUpdateInCurrentPhase = false;
9125var commitCountInCurrentWorkLoop = 0;
9126var effectCountInCurrentCommit = 0;
9127var isWaitingForCallback = false;
9128// During commits, we only show a measurement once per method name
9129// to avoid stretch the commit phase with measurement overhead.
9130var labelsInCurrentCommit = new Set();
9131
9132var formatMarkName = function (markName) {
9133 return reactEmoji + ' ' + markName;
9134};
9135
9136var formatLabel = function (label, warning) {
9137 var prefix = warning ? warningEmoji + ' ' : reactEmoji + ' ';
9138 var suffix = warning ? ' Warning: ' + warning : '';
9139 return '' + prefix + label + suffix;
9140};
9141
9142var beginMark = function (markName) {
9143 performance.mark(formatMarkName(markName));
9144};
9145
9146var clearMark = function (markName) {
9147 performance.clearMarks(formatMarkName(markName));
9148};
9149
9150var endMark = function (label, markName, warning) {
9151 var formattedMarkName = formatMarkName(markName);
9152 var formattedLabel = formatLabel(label, warning);
9153 try {
9154 performance.measure(formattedLabel, formattedMarkName);
9155 } catch (err) {}
9156 // If previous mark was missing for some reason, this will throw.
9157 // This could only happen if React crashed in an unexpected place earlier.
9158 // Don't pile on with more errors.
9159
9160 // Clear marks immediately to avoid growing buffer.
9161 performance.clearMarks(formattedMarkName);
9162 performance.clearMeasures(formattedLabel);
9163};
9164
9165var getFiberMarkName = function (label, debugID) {
9166 return label + ' (#' + debugID + ')';
9167};
9168
9169var getFiberLabel = function (componentName, isMounted, phase) {
9170 if (phase === null) {
9171 // These are composite component total time measurements.
9172 return componentName + ' [' + (isMounted ? 'update' : 'mount') + ']';
9173 } else {
9174 // Composite component methods.
9175 return componentName + '.' + phase;
9176 }
9177};
9178
9179var beginFiberMark = function (fiber, phase) {
9180 var componentName = getComponentName(fiber.type) || 'Unknown';
9181 var debugID = fiber._debugID;
9182 var isMounted = fiber.alternate !== null;
9183 var label = getFiberLabel(componentName, isMounted, phase);
9184
9185 if (isCommitting && labelsInCurrentCommit.has(label)) {
9186 // During the commit phase, we don't show duplicate labels because
9187 // there is a fixed overhead for every measurement, and we don't
9188 // want to stretch the commit phase beyond necessary.
9189 return false;
9190 }
9191 labelsInCurrentCommit.add(label);
9192
9193 var markName = getFiberMarkName(label, debugID);
9194 beginMark(markName);
9195 return true;
9196};
9197
9198var clearFiberMark = function (fiber, phase) {
9199 var componentName = getComponentName(fiber.type) || 'Unknown';
9200 var debugID = fiber._debugID;
9201 var isMounted = fiber.alternate !== null;
9202 var label = getFiberLabel(componentName, isMounted, phase);
9203 var markName = getFiberMarkName(label, debugID);
9204 clearMark(markName);
9205};
9206
9207var endFiberMark = function (fiber, phase, warning) {
9208 var componentName = getComponentName(fiber.type) || 'Unknown';
9209 var debugID = fiber._debugID;
9210 var isMounted = fiber.alternate !== null;
9211 var label = getFiberLabel(componentName, isMounted, phase);
9212 var markName = getFiberMarkName(label, debugID);
9213 endMark(label, markName, warning);
9214};
9215
9216var shouldIgnoreFiber = function (fiber) {
9217 // Host components should be skipped in the timeline.
9218 // We could check typeof fiber.type, but does this work with RN?
9219 switch (fiber.tag) {
9220 case HostRoot:
9221 case HostComponent:
9222 case HostText:
9223 case HostPortal:
9224 case Fragment:
9225 case ContextProvider:
9226 case ContextConsumer:
9227 case Mode:
9228 return true;
9229 default:
9230 return false;
9231 }
9232};
9233
9234var clearPendingPhaseMeasurement = function () {
9235 if (currentPhase !== null && currentPhaseFiber !== null) {
9236 clearFiberMark(currentPhaseFiber, currentPhase);
9237 }
9238 currentPhaseFiber = null;
9239 currentPhase = null;
9240 hasScheduledUpdateInCurrentPhase = false;
9241};
9242
9243var pauseTimers = function () {
9244 // Stops all currently active measurements so that they can be resumed
9245 // if we continue in a later deferred loop from the same unit of work.
9246 var fiber = currentFiber;
9247 while (fiber) {
9248 if (fiber._debugIsCurrentlyTiming) {
9249 endFiberMark(fiber, null, null);
9250 }
9251 fiber = fiber.return;
9252 }
9253};
9254
9255var resumeTimersRecursively = function (fiber) {
9256 if (fiber.return !== null) {
9257 resumeTimersRecursively(fiber.return);
9258 }
9259 if (fiber._debugIsCurrentlyTiming) {
9260 beginFiberMark(fiber, null);
9261 }
9262};
9263
9264var resumeTimers = function () {
9265 // Resumes all measurements that were active during the last deferred loop.
9266 if (currentFiber !== null) {
9267 resumeTimersRecursively(currentFiber);
9268 }
9269};
9270
9271function recordEffect() {
9272 if (enableUserTimingAPI) {
9273 effectCountInCurrentCommit++;
9274 }
9275}
9276
9277function recordScheduleUpdate() {
9278 if (enableUserTimingAPI) {
9279 if (isCommitting) {
9280 hasScheduledUpdateInCurrentCommit = true;
9281 }
9282 if (currentPhase !== null && currentPhase !== 'componentWillMount' && currentPhase !== 'componentWillReceiveProps') {
9283 hasScheduledUpdateInCurrentPhase = true;
9284 }
9285 }
9286}
9287
9288function startRequestCallbackTimer() {
9289 if (enableUserTimingAPI) {
9290 if (supportsUserTiming && !isWaitingForCallback) {
9291 isWaitingForCallback = true;
9292 beginMark('(Waiting for async callback...)');
9293 }
9294 }
9295}
9296
9297function stopRequestCallbackTimer(didExpire, expirationTime) {
9298 if (enableUserTimingAPI) {
9299 if (supportsUserTiming) {
9300 isWaitingForCallback = false;
9301 var warning = didExpire ? 'React was blocked by main thread' : null;
9302 endMark('(Waiting for async callback... will force flush in ' + expirationTime + ' ms)', '(Waiting for async callback...)', warning);
9303 }
9304 }
9305}
9306
9307function startWorkTimer(fiber) {
9308 if (enableUserTimingAPI) {
9309 if (!supportsUserTiming || shouldIgnoreFiber(fiber)) {
9310 return;
9311 }
9312 // If we pause, this is the fiber to unwind from.
9313 currentFiber = fiber;
9314 if (!beginFiberMark(fiber, null)) {
9315 return;
9316 }
9317 fiber._debugIsCurrentlyTiming = true;
9318 }
9319}
9320
9321function cancelWorkTimer(fiber) {
9322 if (enableUserTimingAPI) {
9323 if (!supportsUserTiming || shouldIgnoreFiber(fiber)) {
9324 return;
9325 }
9326 // Remember we shouldn't complete measurement for this fiber.
9327 // Otherwise flamechart will be deep even for small updates.
9328 fiber._debugIsCurrentlyTiming = false;
9329 clearFiberMark(fiber, null);
9330 }
9331}
9332
9333function stopWorkTimer(fiber) {
9334 if (enableUserTimingAPI) {
9335 if (!supportsUserTiming || shouldIgnoreFiber(fiber)) {
9336 return;
9337 }
9338 // If we pause, its parent is the fiber to unwind from.
9339 currentFiber = fiber.return;
9340 if (!fiber._debugIsCurrentlyTiming) {
9341 return;
9342 }
9343 fiber._debugIsCurrentlyTiming = false;
9344 endFiberMark(fiber, null, null);
9345 }
9346}
9347
9348function stopFailedWorkTimer(fiber) {
9349 if (enableUserTimingAPI) {
9350 if (!supportsUserTiming || shouldIgnoreFiber(fiber)) {
9351 return;
9352 }
9353 // If we pause, its parent is the fiber to unwind from.
9354 currentFiber = fiber.return;
9355 if (!fiber._debugIsCurrentlyTiming) {
9356 return;
9357 }
9358 fiber._debugIsCurrentlyTiming = false;
9359 var warning = fiber.tag === SuspenseComponent ? 'Rendering was suspended' : 'An error was thrown inside this error boundary';
9360 endFiberMark(fiber, null, warning);
9361 }
9362}
9363
9364function startPhaseTimer(fiber, phase) {
9365 if (enableUserTimingAPI) {
9366 if (!supportsUserTiming) {
9367 return;
9368 }
9369 clearPendingPhaseMeasurement();
9370 if (!beginFiberMark(fiber, phase)) {
9371 return;
9372 }
9373 currentPhaseFiber = fiber;
9374 currentPhase = phase;
9375 }
9376}
9377
9378function stopPhaseTimer() {
9379 if (enableUserTimingAPI) {
9380 if (!supportsUserTiming) {
9381 return;
9382 }
9383 if (currentPhase !== null && currentPhaseFiber !== null) {
9384 var warning = hasScheduledUpdateInCurrentPhase ? 'Scheduled a cascading update' : null;
9385 endFiberMark(currentPhaseFiber, currentPhase, warning);
9386 }
9387 currentPhase = null;
9388 currentPhaseFiber = null;
9389 }
9390}
9391
9392function startWorkLoopTimer(nextUnitOfWork) {
9393 if (enableUserTimingAPI) {
9394 currentFiber = nextUnitOfWork;
9395 if (!supportsUserTiming) {
9396 return;
9397 }
9398 commitCountInCurrentWorkLoop = 0;
9399 // This is top level call.
9400 // Any other measurements are performed within.
9401 beginMark('(React Tree Reconciliation)');
9402 // Resume any measurements that were in progress during the last loop.
9403 resumeTimers();
9404 }
9405}
9406
9407function stopWorkLoopTimer(interruptedBy, didCompleteRoot) {
9408 if (enableUserTimingAPI) {
9409 if (!supportsUserTiming) {
9410 return;
9411 }
9412 var warning = null;
9413 if (interruptedBy !== null) {
9414 if (interruptedBy.tag === HostRoot) {
9415 warning = 'A top-level update interrupted the previous render';
9416 } else {
9417 var componentName = getComponentName(interruptedBy.type) || 'Unknown';
9418 warning = 'An update to ' + componentName + ' interrupted the previous render';
9419 }
9420 } else if (commitCountInCurrentWorkLoop > 1) {
9421 warning = 'There were cascading updates';
9422 }
9423 commitCountInCurrentWorkLoop = 0;
9424 var label = didCompleteRoot ? '(React Tree Reconciliation: Completed Root)' : '(React Tree Reconciliation: Yielded)';
9425 // Pause any measurements until the next loop.
9426 pauseTimers();
9427 endMark(label, '(React Tree Reconciliation)', warning);
9428 }
9429}
9430
9431function startCommitTimer() {
9432 if (enableUserTimingAPI) {
9433 if (!supportsUserTiming) {
9434 return;
9435 }
9436 isCommitting = true;
9437 hasScheduledUpdateInCurrentCommit = false;
9438 labelsInCurrentCommit.clear();
9439 beginMark('(Committing Changes)');
9440 }
9441}
9442
9443function stopCommitTimer() {
9444 if (enableUserTimingAPI) {
9445 if (!supportsUserTiming) {
9446 return;
9447 }
9448
9449 var warning = null;
9450 if (hasScheduledUpdateInCurrentCommit) {
9451 warning = 'Lifecycle hook scheduled a cascading update';
9452 } else if (commitCountInCurrentWorkLoop > 0) {
9453 warning = 'Caused by a cascading update in earlier commit';
9454 }
9455 hasScheduledUpdateInCurrentCommit = false;
9456 commitCountInCurrentWorkLoop++;
9457 isCommitting = false;
9458 labelsInCurrentCommit.clear();
9459
9460 endMark('(Committing Changes)', '(Committing Changes)', warning);
9461 }
9462}
9463
9464function startCommitSnapshotEffectsTimer() {
9465 if (enableUserTimingAPI) {
9466 if (!supportsUserTiming) {
9467 return;
9468 }
9469 effectCountInCurrentCommit = 0;
9470 beginMark('(Committing Snapshot Effects)');
9471 }
9472}
9473
9474function stopCommitSnapshotEffectsTimer() {
9475 if (enableUserTimingAPI) {
9476 if (!supportsUserTiming) {
9477 return;
9478 }
9479 var count = effectCountInCurrentCommit;
9480 effectCountInCurrentCommit = 0;
9481 endMark('(Committing Snapshot Effects: ' + count + ' Total)', '(Committing Snapshot Effects)', null);
9482 }
9483}
9484
9485function startCommitHostEffectsTimer() {
9486 if (enableUserTimingAPI) {
9487 if (!supportsUserTiming) {
9488 return;
9489 }
9490 effectCountInCurrentCommit = 0;
9491 beginMark('(Committing Host Effects)');
9492 }
9493}
9494
9495function stopCommitHostEffectsTimer() {
9496 if (enableUserTimingAPI) {
9497 if (!supportsUserTiming) {
9498 return;
9499 }
9500 var count = effectCountInCurrentCommit;
9501 effectCountInCurrentCommit = 0;
9502 endMark('(Committing Host Effects: ' + count + ' Total)', '(Committing Host Effects)', null);
9503 }
9504}
9505
9506function startCommitLifeCyclesTimer() {
9507 if (enableUserTimingAPI) {
9508 if (!supportsUserTiming) {
9509 return;
9510 }
9511 effectCountInCurrentCommit = 0;
9512 beginMark('(Calling Lifecycle Methods)');
9513 }
9514}
9515
9516function stopCommitLifeCyclesTimer() {
9517 if (enableUserTimingAPI) {
9518 if (!supportsUserTiming) {
9519 return;
9520 }
9521 var count = effectCountInCurrentCommit;
9522 effectCountInCurrentCommit = 0;
9523 endMark('(Calling Lifecycle Methods: ' + count + ' Total)', '(Calling Lifecycle Methods)', null);
9524 }
9525}
9526
9527var valueStack = [];
9528
9529var fiberStack = void 0;
9530
9531{
9532 fiberStack = [];
9533}
9534
9535var index = -1;
9536
9537function createCursor(defaultValue) {
9538 return {
9539 current: defaultValue
9540 };
9541}
9542
9543function pop(cursor, fiber) {
9544 if (index < 0) {
9545 {
9546 warningWithoutStack$1(false, 'Unexpected pop.');
9547 }
9548 return;
9549 }
9550
9551 {
9552 if (fiber !== fiberStack[index]) {
9553 warningWithoutStack$1(false, 'Unexpected Fiber popped.');
9554 }
9555 }
9556
9557 cursor.current = valueStack[index];
9558
9559 valueStack[index] = null;
9560
9561 {
9562 fiberStack[index] = null;
9563 }
9564
9565 index--;
9566}
9567
9568function push(cursor, value, fiber) {
9569 index++;
9570
9571 valueStack[index] = cursor.current;
9572
9573 {
9574 fiberStack[index] = fiber;
9575 }
9576
9577 cursor.current = value;
9578}
9579
9580function checkThatStackIsEmpty() {
9581 {
9582 if (index !== -1) {
9583 warningWithoutStack$1(false, 'Expected an empty stack. Something was not reset properly.');
9584 }
9585 }
9586}
9587
9588function resetStackAfterFatalErrorInDev() {
9589 {
9590 index = -1;
9591 valueStack.length = 0;
9592 fiberStack.length = 0;
9593 }
9594}
9595
9596var warnedAboutMissingGetChildContext = void 0;
9597
9598{
9599 warnedAboutMissingGetChildContext = {};
9600}
9601
9602var emptyContextObject = {};
9603{
9604 Object.freeze(emptyContextObject);
9605}
9606
9607// A cursor to the current merged context object on the stack.
9608var contextStackCursor = createCursor(emptyContextObject);
9609// A cursor to a boolean indicating whether the context has changed.
9610var didPerformWorkStackCursor = createCursor(false);
9611// Keep track of the previous context object that was on the stack.
9612// We use this to get access to the parent context after we have already
9613// pushed the next context provider, and now need to merge their contexts.
9614var previousContext = emptyContextObject;
9615
9616function getUnmaskedContext(workInProgress, Component, didPushOwnContextIfProvider) {
9617 if (didPushOwnContextIfProvider && isContextProvider(Component)) {
9618 // If the fiber is a context provider itself, when we read its context
9619 // we may have already pushed its own child context on the stack. A context
9620 // provider should not "see" its own child context. Therefore we read the
9621 // previous (parent) context instead for a context provider.
9622 return previousContext;
9623 }
9624 return contextStackCursor.current;
9625}
9626
9627function cacheContext(workInProgress, unmaskedContext, maskedContext) {
9628 var instance = workInProgress.stateNode;
9629 instance.__reactInternalMemoizedUnmaskedChildContext = unmaskedContext;
9630 instance.__reactInternalMemoizedMaskedChildContext = maskedContext;
9631}
9632
9633function getMaskedContext(workInProgress, unmaskedContext) {
9634 var type = workInProgress.type;
9635 var contextTypes = type.contextTypes;
9636 if (!contextTypes) {
9637 return emptyContextObject;
9638 }
9639
9640 // Avoid recreating masked context unless unmasked context has changed.
9641 // Failing to do this will result in unnecessary calls to componentWillReceiveProps.
9642 // This may trigger infinite loops if componentWillReceiveProps calls setState.
9643 var instance = workInProgress.stateNode;
9644 if (instance && instance.__reactInternalMemoizedUnmaskedChildContext === unmaskedContext) {
9645 return instance.__reactInternalMemoizedMaskedChildContext;
9646 }
9647
9648 var context = {};
9649 for (var key in contextTypes) {
9650 context[key] = unmaskedContext[key];
9651 }
9652
9653 {
9654 var name = getComponentName(type) || 'Unknown';
9655 checkPropTypes_1(contextTypes, context, 'context', name, getCurrentFiberStackInDev);
9656 }
9657
9658 // Cache unmasked context so we can avoid recreating masked context unless necessary.
9659 // Context is created before the class component is instantiated so check for instance.
9660 if (instance) {
9661 cacheContext(workInProgress, unmaskedContext, context);
9662 }
9663
9664 return context;
9665}
9666
9667function hasContextChanged() {
9668 return didPerformWorkStackCursor.current;
9669}
9670
9671function isContextProvider(type) {
9672 var childContextTypes = type.childContextTypes;
9673 return childContextTypes !== null && childContextTypes !== undefined;
9674}
9675
9676function popContext(fiber) {
9677 pop(didPerformWorkStackCursor, fiber);
9678 pop(contextStackCursor, fiber);
9679}
9680
9681function popTopLevelContextObject(fiber) {
9682 pop(didPerformWorkStackCursor, fiber);
9683 pop(contextStackCursor, fiber);
9684}
9685
9686function pushTopLevelContextObject(fiber, context, didChange) {
9687 !(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;
9688
9689 push(contextStackCursor, context, fiber);
9690 push(didPerformWorkStackCursor, didChange, fiber);
9691}
9692
9693function processChildContext(fiber, type, parentContext) {
9694 var instance = fiber.stateNode;
9695 var childContextTypes = type.childContextTypes;
9696
9697 // TODO (bvaughn) Replace this behavior with an invariant() in the future.
9698 // It has only been added in Fiber to match the (unintentional) behavior in Stack.
9699 if (typeof instance.getChildContext !== 'function') {
9700 {
9701 var componentName = getComponentName(type) || 'Unknown';
9702
9703 if (!warnedAboutMissingGetChildContext[componentName]) {
9704 warnedAboutMissingGetChildContext[componentName] = true;
9705 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);
9706 }
9707 }
9708 return parentContext;
9709 }
9710
9711 var childContext = void 0;
9712 {
9713 setCurrentPhase('getChildContext');
9714 }
9715 startPhaseTimer(fiber, 'getChildContext');
9716 childContext = instance.getChildContext();
9717 stopPhaseTimer();
9718 {
9719 setCurrentPhase(null);
9720 }
9721 for (var contextKey in childContext) {
9722 !(contextKey in childContextTypes) ? invariant(false, '%s.getChildContext(): key "%s" is not defined in childContextTypes.', getComponentName(type) || 'Unknown', contextKey) : void 0;
9723 }
9724 {
9725 var name = getComponentName(type) || 'Unknown';
9726 checkPropTypes_1(childContextTypes, childContext, 'child context', name,
9727 // In practice, there is one case in which we won't get a stack. It's when
9728 // somebody calls unstable_renderSubtreeIntoContainer() and we process
9729 // context from the parent component instance. The stack will be missing
9730 // because it's outside of the reconciliation, and so the pointer has not
9731 // been set. This is rare and doesn't matter. We'll also remove that API.
9732 getCurrentFiberStackInDev);
9733 }
9734
9735 return _assign({}, parentContext, childContext);
9736}
9737
9738function pushContextProvider(workInProgress) {
9739 var instance = workInProgress.stateNode;
9740 // We push the context as early as possible to ensure stack integrity.
9741 // If the instance does not exist yet, we will push null at first,
9742 // and replace it on the stack later when invalidating the context.
9743 var memoizedMergedChildContext = instance && instance.__reactInternalMemoizedMergedChildContext || emptyContextObject;
9744
9745 // Remember the parent context so we can merge with it later.
9746 // Inherit the parent's did-perform-work value to avoid inadvertently blocking updates.
9747 previousContext = contextStackCursor.current;
9748 push(contextStackCursor, memoizedMergedChildContext, workInProgress);
9749 push(didPerformWorkStackCursor, didPerformWorkStackCursor.current, workInProgress);
9750
9751 return true;
9752}
9753
9754function invalidateContextProvider(workInProgress, type, didChange) {
9755 var instance = workInProgress.stateNode;
9756 !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;
9757
9758 if (didChange) {
9759 // Merge parent and own context.
9760 // Skip this if we're not updating due to sCU.
9761 // This avoids unnecessarily recomputing memoized values.
9762 var mergedContext = processChildContext(workInProgress, type, previousContext);
9763 instance.__reactInternalMemoizedMergedChildContext = mergedContext;
9764
9765 // Replace the old (or empty) context with the new one.
9766 // It is important to unwind the context in the reverse order.
9767 pop(didPerformWorkStackCursor, workInProgress);
9768 pop(contextStackCursor, workInProgress);
9769 // Now push the new context and mark that it has changed.
9770 push(contextStackCursor, mergedContext, workInProgress);
9771 push(didPerformWorkStackCursor, didChange, workInProgress);
9772 } else {
9773 pop(didPerformWorkStackCursor, workInProgress);
9774 push(didPerformWorkStackCursor, didChange, workInProgress);
9775 }
9776}
9777
9778function findCurrentUnmaskedContext(fiber) {
9779 // Currently this is only used with renderSubtreeIntoContainer; not sure if it
9780 // makes sense elsewhere
9781 !(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;
9782
9783 var node = fiber;
9784 do {
9785 switch (node.tag) {
9786 case HostRoot:
9787 return node.stateNode.context;
9788 case ClassComponent:
9789 {
9790 var Component = node.type;
9791 if (isContextProvider(Component)) {
9792 return node.stateNode.__reactInternalMemoizedMergedChildContext;
9793 }
9794 break;
9795 }
9796 }
9797 node = node.return;
9798 } while (node !== null);
9799 invariant(false, 'Found unexpected detached subtree parent. This error is likely caused by a bug in React. Please file an issue.');
9800}
9801
9802var onCommitFiberRoot = null;
9803var onCommitFiberUnmount = null;
9804var hasLoggedError = false;
9805
9806function catchErrors(fn) {
9807 return function (arg) {
9808 try {
9809 return fn(arg);
9810 } catch (err) {
9811 if (true && !hasLoggedError) {
9812 hasLoggedError = true;
9813 warningWithoutStack$1(false, 'React DevTools encountered an error: %s', err);
9814 }
9815 }
9816 };
9817}
9818
9819var isDevToolsPresent = typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ !== 'undefined';
9820
9821function injectInternals(internals) {
9822 if (typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ === 'undefined') {
9823 // No DevTools
9824 return false;
9825 }
9826 var hook = __REACT_DEVTOOLS_GLOBAL_HOOK__;
9827 if (hook.isDisabled) {
9828 // This isn't a real property on the hook, but it can be set to opt out
9829 // of DevTools integration and associated warnings and logs.
9830 // https://github.com/facebook/react/issues/3877
9831 return true;
9832 }
9833 if (!hook.supportsFiber) {
9834 {
9835 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');
9836 }
9837 // DevTools exists, even though it doesn't support Fiber.
9838 return true;
9839 }
9840 try {
9841 var rendererID = hook.inject(internals);
9842 // We have successfully injected, so now it is safe to set up hooks.
9843 onCommitFiberRoot = catchErrors(function (root) {
9844 return hook.onCommitFiberRoot(rendererID, root);
9845 });
9846 onCommitFiberUnmount = catchErrors(function (fiber) {
9847 return hook.onCommitFiberUnmount(rendererID, fiber);
9848 });
9849 } catch (err) {
9850 // Catch all errors because it is unsafe to throw during initialization.
9851 {
9852 warningWithoutStack$1(false, 'React DevTools encountered an error: %s.', err);
9853 }
9854 }
9855 // DevTools exists
9856 return true;
9857}
9858
9859function onCommitRoot(root) {
9860 if (typeof onCommitFiberRoot === 'function') {
9861 onCommitFiberRoot(root);
9862 }
9863}
9864
9865function onCommitUnmount(fiber) {
9866 if (typeof onCommitFiberUnmount === 'function') {
9867 onCommitFiberUnmount(fiber);
9868 }
9869}
9870
9871// Max 31 bit integer. The max integer size in V8 for 32-bit systems.
9872// Math.pow(2, 30) - 1
9873// 0b111111111111111111111111111111
9874var maxSigned31BitInt = 1073741823;
9875
9876var NoWork = 0;
9877var Never = 1;
9878var Sync = maxSigned31BitInt;
9879
9880var UNIT_SIZE = 10;
9881var MAGIC_NUMBER_OFFSET = maxSigned31BitInt - 1;
9882
9883// 1 unit of expiration time represents 10ms.
9884function msToExpirationTime(ms) {
9885 // Always add an offset so that we don't clash with the magic number for NoWork.
9886 return MAGIC_NUMBER_OFFSET - (ms / UNIT_SIZE | 0);
9887}
9888
9889function expirationTimeToMs(expirationTime) {
9890 return (MAGIC_NUMBER_OFFSET - expirationTime) * UNIT_SIZE;
9891}
9892
9893function ceiling(num, precision) {
9894 return ((num / precision | 0) + 1) * precision;
9895}
9896
9897function computeExpirationBucket(currentTime, expirationInMs, bucketSizeMs) {
9898 return MAGIC_NUMBER_OFFSET - ceiling(MAGIC_NUMBER_OFFSET - currentTime + expirationInMs / UNIT_SIZE, bucketSizeMs / UNIT_SIZE);
9899}
9900
9901var LOW_PRIORITY_EXPIRATION = 5000;
9902var LOW_PRIORITY_BATCH_SIZE = 250;
9903
9904function computeAsyncExpiration(currentTime) {
9905 return computeExpirationBucket(currentTime, LOW_PRIORITY_EXPIRATION, LOW_PRIORITY_BATCH_SIZE);
9906}
9907
9908// We intentionally set a higher expiration time for interactive updates in
9909// dev than in production.
9910//
9911// If the main thread is being blocked so long that you hit the expiration,
9912// it's a problem that could be solved with better scheduling.
9913//
9914// People will be more likely to notice this and fix it with the long
9915// expiration time in development.
9916//
9917// In production we opt for better UX at the risk of masking scheduling
9918// problems, by expiring fast.
9919var HIGH_PRIORITY_EXPIRATION = 500;
9920var HIGH_PRIORITY_BATCH_SIZE = 100;
9921
9922function computeInteractiveExpiration(currentTime) {
9923 return computeExpirationBucket(currentTime, HIGH_PRIORITY_EXPIRATION, HIGH_PRIORITY_BATCH_SIZE);
9924}
9925
9926var NoContext = 0;
9927var ConcurrentMode = 1;
9928var StrictMode = 2;
9929var ProfileMode = 4;
9930
9931var hasBadMapPolyfill = void 0;
9932
9933{
9934 hasBadMapPolyfill = false;
9935 try {
9936 var nonExtensibleObject = Object.preventExtensions({});
9937 var testMap = new Map([[nonExtensibleObject, null]]);
9938 var testSet = new Set([nonExtensibleObject]);
9939 // This is necessary for Rollup to not consider these unused.
9940 // https://github.com/rollup/rollup/issues/1771
9941 // TODO: we can remove these if Rollup fixes the bug.
9942 testMap.set(0, 0);
9943 testSet.add(0);
9944 } catch (e) {
9945 // TODO: Consider warning about bad polyfills
9946 hasBadMapPolyfill = true;
9947 }
9948}
9949
9950// A Fiber is work on a Component that needs to be done or was done. There can
9951// be more than one per component.
9952
9953
9954var debugCounter = void 0;
9955
9956{
9957 debugCounter = 1;
9958}
9959
9960function FiberNode(tag, pendingProps, key, mode) {
9961 // Instance
9962 this.tag = tag;
9963 this.key = key;
9964 this.elementType = null;
9965 this.type = null;
9966 this.stateNode = null;
9967
9968 // Fiber
9969 this.return = null;
9970 this.child = null;
9971 this.sibling = null;
9972 this.index = 0;
9973
9974 this.ref = null;
9975
9976 this.pendingProps = pendingProps;
9977 this.memoizedProps = null;
9978 this.updateQueue = null;
9979 this.memoizedState = null;
9980 this.firstContextDependency = null;
9981
9982 this.mode = mode;
9983
9984 // Effects
9985 this.effectTag = NoEffect;
9986 this.nextEffect = null;
9987
9988 this.firstEffect = null;
9989 this.lastEffect = null;
9990
9991 this.expirationTime = NoWork;
9992 this.childExpirationTime = NoWork;
9993
9994 this.alternate = null;
9995
9996 if (enableProfilerTimer) {
9997 // Note: The following is done to avoid a v8 performance cliff.
9998 //
9999 // Initializing the fields below to smis and later updating them with
10000 // double values will cause Fibers to end up having separate shapes.
10001 // This behavior/bug has something to do with Object.preventExtension().
10002 // Fortunately this only impacts DEV builds.
10003 // Unfortunately it makes React unusably slow for some applications.
10004 // To work around this, initialize the fields below with doubles.
10005 //
10006 // Learn more about this here:
10007 // https://github.com/facebook/react/issues/14365
10008 // https://bugs.chromium.org/p/v8/issues/detail?id=8538
10009 this.actualDuration = Number.NaN;
10010 this.actualStartTime = Number.NaN;
10011 this.selfBaseDuration = Number.NaN;
10012 this.treeBaseDuration = Number.NaN;
10013
10014 // It's okay to replace the initial doubles with smis after initialization.
10015 // This won't trigger the performance cliff mentioned above,
10016 // and it simplifies other profiler code (including DevTools).
10017 this.actualDuration = 0;
10018 this.actualStartTime = -1;
10019 this.selfBaseDuration = 0;
10020 this.treeBaseDuration = 0;
10021 }
10022
10023 {
10024 this._debugID = debugCounter++;
10025 this._debugSource = null;
10026 this._debugOwner = null;
10027 this._debugIsCurrentlyTiming = false;
10028 if (!hasBadMapPolyfill && typeof Object.preventExtensions === 'function') {
10029 Object.preventExtensions(this);
10030 }
10031 }
10032}
10033
10034// This is a constructor function, rather than a POJO constructor, still
10035// please ensure we do the following:
10036// 1) Nobody should add any instance methods on this. Instance methods can be
10037// more difficult to predict when they get optimized and they are almost
10038// never inlined properly in static compilers.
10039// 2) Nobody should rely on `instanceof Fiber` for type testing. We should
10040// always know when it is a fiber.
10041// 3) We might want to experiment with using numeric keys since they are easier
10042// to optimize in a non-JIT environment.
10043// 4) We can easily go from a constructor to a createFiber object literal if that
10044// is faster.
10045// 5) It should be easy to port this to a C struct and keep a C implementation
10046// compatible.
10047var createFiber = function (tag, pendingProps, key, mode) {
10048 // $FlowFixMe: the shapes are exact here but Flow doesn't like constructors
10049 return new FiberNode(tag, pendingProps, key, mode);
10050};
10051
10052function shouldConstruct(Component) {
10053 var prototype = Component.prototype;
10054 return !!(prototype && prototype.isReactComponent);
10055}
10056
10057function isSimpleFunctionComponent(type) {
10058 return typeof type === 'function' && !shouldConstruct(type) && type.defaultProps === undefined;
10059}
10060
10061function resolveLazyComponentTag(Component) {
10062 if (typeof Component === 'function') {
10063 return shouldConstruct(Component) ? ClassComponent : FunctionComponent;
10064 } else if (Component !== undefined && Component !== null) {
10065 var $$typeof = Component.$$typeof;
10066 if ($$typeof === REACT_FORWARD_REF_TYPE) {
10067 return ForwardRef;
10068 }
10069 if ($$typeof === REACT_MEMO_TYPE) {
10070 return MemoComponent;
10071 }
10072 }
10073 return IndeterminateComponent;
10074}
10075
10076// This is used to create an alternate fiber to do work on.
10077function createWorkInProgress(current, pendingProps, expirationTime) {
10078 var workInProgress = current.alternate;
10079 if (workInProgress === null) {
10080 // We use a double buffering pooling technique because we know that we'll
10081 // only ever need at most two versions of a tree. We pool the "other" unused
10082 // node that we're free to reuse. This is lazily created to avoid allocating
10083 // extra objects for things that are never updated. It also allow us to
10084 // reclaim the extra memory if needed.
10085 workInProgress = createFiber(current.tag, pendingProps, current.key, current.mode);
10086 workInProgress.elementType = current.elementType;
10087 workInProgress.type = current.type;
10088 workInProgress.stateNode = current.stateNode;
10089
10090 {
10091 // DEV-only fields
10092 workInProgress._debugID = current._debugID;
10093 workInProgress._debugSource = current._debugSource;
10094 workInProgress._debugOwner = current._debugOwner;
10095 }
10096
10097 workInProgress.alternate = current;
10098 current.alternate = workInProgress;
10099 } else {
10100 workInProgress.pendingProps = pendingProps;
10101
10102 // We already have an alternate.
10103 // Reset the effect tag.
10104 workInProgress.effectTag = NoEffect;
10105
10106 // The effect list is no longer valid.
10107 workInProgress.nextEffect = null;
10108 workInProgress.firstEffect = null;
10109 workInProgress.lastEffect = null;
10110
10111 if (enableProfilerTimer) {
10112 // We intentionally reset, rather than copy, actualDuration & actualStartTime.
10113 // This prevents time from endlessly accumulating in new commits.
10114 // This has the downside of resetting values for different priority renders,
10115 // But works for yielding (the common case) and should support resuming.
10116 workInProgress.actualDuration = 0;
10117 workInProgress.actualStartTime = -1;
10118 }
10119 }
10120
10121 workInProgress.childExpirationTime = current.childExpirationTime;
10122 workInProgress.expirationTime = current.expirationTime;
10123
10124 workInProgress.child = current.child;
10125 workInProgress.memoizedProps = current.memoizedProps;
10126 workInProgress.memoizedState = current.memoizedState;
10127 workInProgress.updateQueue = current.updateQueue;
10128 workInProgress.firstContextDependency = current.firstContextDependency;
10129
10130 // These will be overridden during the parent's reconciliation
10131 workInProgress.sibling = current.sibling;
10132 workInProgress.index = current.index;
10133 workInProgress.ref = current.ref;
10134
10135 if (enableProfilerTimer) {
10136 workInProgress.selfBaseDuration = current.selfBaseDuration;
10137 workInProgress.treeBaseDuration = current.treeBaseDuration;
10138 }
10139
10140 return workInProgress;
10141}
10142
10143function createHostRootFiber(isConcurrent) {
10144 var mode = isConcurrent ? ConcurrentMode | StrictMode : NoContext;
10145
10146 if (enableProfilerTimer && isDevToolsPresent) {
10147 // Always collect profile timings when DevTools are present.
10148 // This enables DevTools to start capturing timing at any point–
10149 // Without some nodes in the tree having empty base times.
10150 mode |= ProfileMode;
10151 }
10152
10153 return createFiber(HostRoot, null, null, mode);
10154}
10155
10156function createFiberFromTypeAndProps(type, // React$ElementType
10157key, pendingProps, owner, mode, expirationTime) {
10158 var fiber = void 0;
10159
10160 var fiberTag = IndeterminateComponent;
10161 // The resolved type is set if we know what the final type will be. I.e. it's not lazy.
10162 var resolvedType = type;
10163 if (typeof type === 'function') {
10164 if (shouldConstruct(type)) {
10165 fiberTag = ClassComponent;
10166 }
10167 } else if (typeof type === 'string') {
10168 fiberTag = HostComponent;
10169 } else {
10170 getTag: switch (type) {
10171 case REACT_FRAGMENT_TYPE:
10172 return createFiberFromFragment(pendingProps.children, mode, expirationTime, key);
10173 case REACT_CONCURRENT_MODE_TYPE:
10174 return createFiberFromMode(pendingProps, mode | ConcurrentMode | StrictMode, expirationTime, key);
10175 case REACT_STRICT_MODE_TYPE:
10176 return createFiberFromMode(pendingProps, mode | StrictMode, expirationTime, key);
10177 case REACT_PROFILER_TYPE:
10178 return createFiberFromProfiler(pendingProps, mode, expirationTime, key);
10179 case REACT_SUSPENSE_TYPE:
10180 return createFiberFromSuspense(pendingProps, mode, expirationTime, key);
10181 default:
10182 {
10183 if (typeof type === 'object' && type !== null) {
10184 switch (type.$$typeof) {
10185 case REACT_PROVIDER_TYPE:
10186 fiberTag = ContextProvider;
10187 break getTag;
10188 case REACT_CONTEXT_TYPE:
10189 // This is a consumer
10190 fiberTag = ContextConsumer;
10191 break getTag;
10192 case REACT_FORWARD_REF_TYPE:
10193 fiberTag = ForwardRef;
10194 break getTag;
10195 case REACT_MEMO_TYPE:
10196 fiberTag = MemoComponent;
10197 break getTag;
10198 case REACT_LAZY_TYPE:
10199 fiberTag = LazyComponent;
10200 resolvedType = null;
10201 break getTag;
10202 }
10203 }
10204 var info = '';
10205 {
10206 if (type === undefined || typeof type === 'object' && type !== null && Object.keys(type).length === 0) {
10207 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.';
10208 }
10209 var ownerName = owner ? getComponentName(owner.type) : null;
10210 if (ownerName) {
10211 info += '\n\nCheck the render method of `' + ownerName + '`.';
10212 }
10213 }
10214 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);
10215 }
10216 }
10217 }
10218
10219 fiber = createFiber(fiberTag, pendingProps, key, mode);
10220 fiber.elementType = type;
10221 fiber.type = resolvedType;
10222 fiber.expirationTime = expirationTime;
10223
10224 return fiber;
10225}
10226
10227function createFiberFromElement(element, mode, expirationTime) {
10228 var owner = null;
10229 {
10230 owner = element._owner;
10231 }
10232 var type = element.type;
10233 var key = element.key;
10234 var pendingProps = element.props;
10235 var fiber = createFiberFromTypeAndProps(type, key, pendingProps, owner, mode, expirationTime);
10236 {
10237 fiber._debugSource = element._source;
10238 fiber._debugOwner = element._owner;
10239 }
10240 return fiber;
10241}
10242
10243function createFiberFromFragment(elements, mode, expirationTime, key) {
10244 var fiber = createFiber(Fragment, elements, key, mode);
10245 fiber.expirationTime = expirationTime;
10246 return fiber;
10247}
10248
10249function createFiberFromProfiler(pendingProps, mode, expirationTime, key) {
10250 {
10251 if (typeof pendingProps.id !== 'string' || typeof pendingProps.onRender !== 'function') {
10252 warningWithoutStack$1(false, 'Profiler must specify an "id" string and "onRender" function as props');
10253 }
10254 }
10255
10256 var fiber = createFiber(Profiler, pendingProps, key, mode | ProfileMode);
10257 // TODO: The Profiler fiber shouldn't have a type. It has a tag.
10258 fiber.elementType = REACT_PROFILER_TYPE;
10259 fiber.type = REACT_PROFILER_TYPE;
10260 fiber.expirationTime = expirationTime;
10261
10262 return fiber;
10263}
10264
10265function createFiberFromMode(pendingProps, mode, expirationTime, key) {
10266 var fiber = createFiber(Mode, pendingProps, key, mode);
10267
10268 // TODO: The Mode fiber shouldn't have a type. It has a tag.
10269 var type = (mode & ConcurrentMode) === NoContext ? REACT_STRICT_MODE_TYPE : REACT_CONCURRENT_MODE_TYPE;
10270 fiber.elementType = type;
10271 fiber.type = type;
10272
10273 fiber.expirationTime = expirationTime;
10274 return fiber;
10275}
10276
10277function createFiberFromSuspense(pendingProps, mode, expirationTime, key) {
10278 var fiber = createFiber(SuspenseComponent, pendingProps, key, mode);
10279
10280 // TODO: The SuspenseComponent fiber shouldn't have a type. It has a tag.
10281 var type = REACT_SUSPENSE_TYPE;
10282 fiber.elementType = type;
10283 fiber.type = type;
10284
10285 fiber.expirationTime = expirationTime;
10286 return fiber;
10287}
10288
10289function createFiberFromText(content, mode, expirationTime) {
10290 var fiber = createFiber(HostText, content, null, mode);
10291 fiber.expirationTime = expirationTime;
10292 return fiber;
10293}
10294
10295function createFiberFromHostInstanceForDeletion() {
10296 var fiber = createFiber(HostComponent, null, null, NoContext);
10297 // TODO: These should not need a type.
10298 fiber.elementType = 'DELETED';
10299 fiber.type = 'DELETED';
10300 return fiber;
10301}
10302
10303function createFiberFromPortal(portal, mode, expirationTime) {
10304 var pendingProps = portal.children !== null ? portal.children : [];
10305 var fiber = createFiber(HostPortal, pendingProps, portal.key, mode);
10306 fiber.expirationTime = expirationTime;
10307 fiber.stateNode = {
10308 containerInfo: portal.containerInfo,
10309 pendingChildren: null, // Used by persistent updates
10310 implementation: portal.implementation
10311 };
10312 return fiber;
10313}
10314
10315// Used for stashing WIP properties to replay failed work in DEV.
10316function assignFiberPropertiesInDEV(target, source) {
10317 if (target === null) {
10318 // This Fiber's initial properties will always be overwritten.
10319 // We only use a Fiber to ensure the same hidden class so DEV isn't slow.
10320 target = createFiber(IndeterminateComponent, null, null, NoContext);
10321 }
10322
10323 // This is intentionally written as a list of all properties.
10324 // We tried to use Object.assign() instead but this is called in
10325 // the hottest path, and Object.assign() was too slow:
10326 // https://github.com/facebook/react/issues/12502
10327 // This code is DEV-only so size is not a concern.
10328
10329 target.tag = source.tag;
10330 target.key = source.key;
10331 target.elementType = source.elementType;
10332 target.type = source.type;
10333 target.stateNode = source.stateNode;
10334 target.return = source.return;
10335 target.child = source.child;
10336 target.sibling = source.sibling;
10337 target.index = source.index;
10338 target.ref = source.ref;
10339 target.pendingProps = source.pendingProps;
10340 target.memoizedProps = source.memoizedProps;
10341 target.updateQueue = source.updateQueue;
10342 target.memoizedState = source.memoizedState;
10343 target.firstContextDependency = source.firstContextDependency;
10344 target.mode = source.mode;
10345 target.effectTag = source.effectTag;
10346 target.nextEffect = source.nextEffect;
10347 target.firstEffect = source.firstEffect;
10348 target.lastEffect = source.lastEffect;
10349 target.expirationTime = source.expirationTime;
10350 target.childExpirationTime = source.childExpirationTime;
10351 target.alternate = source.alternate;
10352 if (enableProfilerTimer) {
10353 target.actualDuration = source.actualDuration;
10354 target.actualStartTime = source.actualStartTime;
10355 target.selfBaseDuration = source.selfBaseDuration;
10356 target.treeBaseDuration = source.treeBaseDuration;
10357 }
10358 target._debugID = source._debugID;
10359 target._debugSource = source._debugSource;
10360 target._debugOwner = source._debugOwner;
10361 target._debugIsCurrentlyTiming = source._debugIsCurrentlyTiming;
10362 return target;
10363}
10364
10365var ReactInternals$2 = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
10366
10367var _ReactInternals$Sched$1 = ReactInternals$2.SchedulerTracing;
10368var __interactionsRef = _ReactInternals$Sched$1.__interactionsRef;
10369var __subscriberRef = _ReactInternals$Sched$1.__subscriberRef;
10370var unstable_clear = _ReactInternals$Sched$1.unstable_clear;
10371var unstable_getCurrent = _ReactInternals$Sched$1.unstable_getCurrent;
10372var unstable_getThreadID = _ReactInternals$Sched$1.unstable_getThreadID;
10373var unstable_subscribe = _ReactInternals$Sched$1.unstable_subscribe;
10374var unstable_trace = _ReactInternals$Sched$1.unstable_trace;
10375var unstable_unsubscribe = _ReactInternals$Sched$1.unstable_unsubscribe;
10376var unstable_wrap = _ReactInternals$Sched$1.unstable_wrap;
10377
10378// TODO: This should be lifted into the renderer.
10379
10380
10381// The following attributes are only used by interaction tracing builds.
10382// They enable interactions to be associated with their async work,
10383// And expose interaction metadata to the React DevTools Profiler plugin.
10384// Note that these attributes are only defined when the enableSchedulerTracing flag is enabled.
10385
10386
10387// Exported FiberRoot type includes all properties,
10388// To avoid requiring potentially error-prone :any casts throughout the project.
10389// Profiling properties are only safe to access in profiling builds (when enableSchedulerTracing is true).
10390// The types are defined separately within this file to ensure they stay in sync.
10391// (We don't have to use an inline :any cast when enableSchedulerTracing is disabled.)
10392
10393
10394function createFiberRoot(containerInfo, isConcurrent, hydrate) {
10395 // Cyclic construction. This cheats the type system right now because
10396 // stateNode is any.
10397 var uninitializedFiber = createHostRootFiber(isConcurrent);
10398
10399 var root = void 0;
10400 if (enableSchedulerTracing) {
10401 root = {
10402 current: uninitializedFiber,
10403 containerInfo: containerInfo,
10404 pendingChildren: null,
10405
10406 earliestPendingTime: NoWork,
10407 latestPendingTime: NoWork,
10408 earliestSuspendedTime: NoWork,
10409 latestSuspendedTime: NoWork,
10410 latestPingedTime: NoWork,
10411
10412 pingCache: null,
10413
10414 didError: false,
10415
10416 pendingCommitExpirationTime: NoWork,
10417 finishedWork: null,
10418 timeoutHandle: noTimeout,
10419 context: null,
10420 pendingContext: null,
10421 hydrate: hydrate,
10422 nextExpirationTimeToWorkOn: NoWork,
10423 expirationTime: NoWork,
10424 firstBatch: null,
10425 nextScheduledRoot: null,
10426
10427 interactionThreadID: unstable_getThreadID(),
10428 memoizedInteractions: new Set(),
10429 pendingInteractionMap: new Map()
10430 };
10431 } else {
10432 root = {
10433 current: uninitializedFiber,
10434 containerInfo: containerInfo,
10435 pendingChildren: null,
10436
10437 pingCache: null,
10438
10439 earliestPendingTime: NoWork,
10440 latestPendingTime: NoWork,
10441 earliestSuspendedTime: NoWork,
10442 latestSuspendedTime: NoWork,
10443 latestPingedTime: NoWork,
10444
10445 didError: false,
10446
10447 pendingCommitExpirationTime: NoWork,
10448 finishedWork: null,
10449 timeoutHandle: noTimeout,
10450 context: null,
10451 pendingContext: null,
10452 hydrate: hydrate,
10453 nextExpirationTimeToWorkOn: NoWork,
10454 expirationTime: NoWork,
10455 firstBatch: null,
10456 nextScheduledRoot: null
10457 };
10458 }
10459
10460 uninitializedFiber.stateNode = root;
10461
10462 // The reason for the way the Flow types are structured in this file,
10463 // Is to avoid needing :any casts everywhere interaction tracing fields are used.
10464 // Unfortunately that requires an :any cast for non-interaction tracing capable builds.
10465 // $FlowFixMe Remove this :any cast and replace it with something better.
10466 return root;
10467}
10468
10469/**
10470 * Forked from fbjs/warning:
10471 * https://github.com/facebook/fbjs/blob/e66ba20ad5be433eb54423f2b097d829324d9de6/packages/fbjs/src/__forks__/warning.js
10472 *
10473 * Only change is we use console.warn instead of console.error,
10474 * and do nothing when 'console' is not supported.
10475 * This really simplifies the code.
10476 * ---
10477 * Similar to invariant but only logs a warning if the condition is not met.
10478 * This can be used to log issues in development environments in critical
10479 * paths. Removing the logging code for production environments will keep the
10480 * same logic and follow the same code paths.
10481 */
10482
10483var lowPriorityWarning = function () {};
10484
10485{
10486 var printWarning$1 = function (format) {
10487 for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
10488 args[_key - 1] = arguments[_key];
10489 }
10490
10491 var argIndex = 0;
10492 var message = 'Warning: ' + format.replace(/%s/g, function () {
10493 return args[argIndex++];
10494 });
10495 if (typeof console !== 'undefined') {
10496 console.warn(message);
10497 }
10498 try {
10499 // --- Welcome to debugging React ---
10500 // This error was thrown as a convenience so that you can use this stack
10501 // to find the callsite that caused this warning to fire.
10502 throw new Error(message);
10503 } catch (x) {}
10504 };
10505
10506 lowPriorityWarning = function (condition, format) {
10507 if (format === undefined) {
10508 throw new Error('`lowPriorityWarning(condition, format, ...args)` requires a warning ' + 'message argument');
10509 }
10510 if (!condition) {
10511 for (var _len2 = arguments.length, args = Array(_len2 > 2 ? _len2 - 2 : 0), _key2 = 2; _key2 < _len2; _key2++) {
10512 args[_key2 - 2] = arguments[_key2];
10513 }
10514
10515 printWarning$1.apply(undefined, [format].concat(args));
10516 }
10517 };
10518}
10519
10520var lowPriorityWarning$1 = lowPriorityWarning;
10521
10522var ReactStrictModeWarnings = {
10523 discardPendingWarnings: function () {},
10524 flushPendingDeprecationWarnings: function () {},
10525 flushPendingUnsafeLifecycleWarnings: function () {},
10526 recordDeprecationWarnings: function (fiber, instance) {},
10527 recordUnsafeLifecycleWarnings: function (fiber, instance) {},
10528 recordLegacyContextWarning: function (fiber, instance) {},
10529 flushLegacyContextWarning: function () {}
10530};
10531
10532{
10533 var LIFECYCLE_SUGGESTIONS = {
10534 UNSAFE_componentWillMount: 'componentDidMount',
10535 UNSAFE_componentWillReceiveProps: 'static getDerivedStateFromProps',
10536 UNSAFE_componentWillUpdate: 'componentDidUpdate'
10537 };
10538
10539 var pendingComponentWillMountWarnings = [];
10540 var pendingComponentWillReceivePropsWarnings = [];
10541 var pendingComponentWillUpdateWarnings = [];
10542 var pendingUnsafeLifecycleWarnings = new Map();
10543 var pendingLegacyContextWarning = new Map();
10544
10545 // Tracks components we have already warned about.
10546 var didWarnAboutDeprecatedLifecycles = new Set();
10547 var didWarnAboutUnsafeLifecycles = new Set();
10548 var didWarnAboutLegacyContext = new Set();
10549
10550 var setToSortedString = function (set) {
10551 var array = [];
10552 set.forEach(function (value) {
10553 array.push(value);
10554 });
10555 return array.sort().join(', ');
10556 };
10557
10558 ReactStrictModeWarnings.discardPendingWarnings = function () {
10559 pendingComponentWillMountWarnings = [];
10560 pendingComponentWillReceivePropsWarnings = [];
10561 pendingComponentWillUpdateWarnings = [];
10562 pendingUnsafeLifecycleWarnings = new Map();
10563 pendingLegacyContextWarning = new Map();
10564 };
10565
10566 ReactStrictModeWarnings.flushPendingUnsafeLifecycleWarnings = function () {
10567 pendingUnsafeLifecycleWarnings.forEach(function (lifecycleWarningsMap, strictRoot) {
10568 var lifecyclesWarningMesages = [];
10569
10570 Object.keys(lifecycleWarningsMap).forEach(function (lifecycle) {
10571 var lifecycleWarnings = lifecycleWarningsMap[lifecycle];
10572 if (lifecycleWarnings.length > 0) {
10573 var componentNames = new Set();
10574 lifecycleWarnings.forEach(function (fiber) {
10575 componentNames.add(getComponentName(fiber.type) || 'Component');
10576 didWarnAboutUnsafeLifecycles.add(fiber.type);
10577 });
10578
10579 var formatted = lifecycle.replace('UNSAFE_', '');
10580 var suggestion = LIFECYCLE_SUGGESTIONS[lifecycle];
10581 var sortedComponentNames = setToSortedString(componentNames);
10582
10583 lifecyclesWarningMesages.push(formatted + ': Please update the following components to use ' + (suggestion + ' instead: ' + sortedComponentNames));
10584 }
10585 });
10586
10587 if (lifecyclesWarningMesages.length > 0) {
10588 var strictRootComponentStack = getStackByFiberInDevAndProd(strictRoot);
10589
10590 warningWithoutStack$1(false, 'Unsafe lifecycle methods were found within a strict-mode tree:%s' + '\n\n%s' + '\n\nLearn more about this warning here:' + '\nhttps://fb.me/react-strict-mode-warnings', strictRootComponentStack, lifecyclesWarningMesages.join('\n\n'));
10591 }
10592 });
10593
10594 pendingUnsafeLifecycleWarnings = new Map();
10595 };
10596
10597 var findStrictRoot = function (fiber) {
10598 var maybeStrictRoot = null;
10599
10600 var node = fiber;
10601 while (node !== null) {
10602 if (node.mode & StrictMode) {
10603 maybeStrictRoot = node;
10604 }
10605 node = node.return;
10606 }
10607
10608 return maybeStrictRoot;
10609 };
10610
10611 ReactStrictModeWarnings.flushPendingDeprecationWarnings = function () {
10612 if (pendingComponentWillMountWarnings.length > 0) {
10613 var uniqueNames = new Set();
10614 pendingComponentWillMountWarnings.forEach(function (fiber) {
10615 uniqueNames.add(getComponentName(fiber.type) || 'Component');
10616 didWarnAboutDeprecatedLifecycles.add(fiber.type);
10617 });
10618
10619 var sortedNames = setToSortedString(uniqueNames);
10620
10621 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);
10622
10623 pendingComponentWillMountWarnings = [];
10624 }
10625
10626 if (pendingComponentWillReceivePropsWarnings.length > 0) {
10627 var _uniqueNames = new Set();
10628 pendingComponentWillReceivePropsWarnings.forEach(function (fiber) {
10629 _uniqueNames.add(getComponentName(fiber.type) || 'Component');
10630 didWarnAboutDeprecatedLifecycles.add(fiber.type);
10631 });
10632
10633 var _sortedNames = setToSortedString(_uniqueNames);
10634
10635 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);
10636
10637 pendingComponentWillReceivePropsWarnings = [];
10638 }
10639
10640 if (pendingComponentWillUpdateWarnings.length > 0) {
10641 var _uniqueNames2 = new Set();
10642 pendingComponentWillUpdateWarnings.forEach(function (fiber) {
10643 _uniqueNames2.add(getComponentName(fiber.type) || 'Component');
10644 didWarnAboutDeprecatedLifecycles.add(fiber.type);
10645 });
10646
10647 var _sortedNames2 = setToSortedString(_uniqueNames2);
10648
10649 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);
10650
10651 pendingComponentWillUpdateWarnings = [];
10652 }
10653 };
10654
10655 ReactStrictModeWarnings.recordDeprecationWarnings = function (fiber, instance) {
10656 // Dedup strategy: Warn once per component.
10657 if (didWarnAboutDeprecatedLifecycles.has(fiber.type)) {
10658 return;
10659 }
10660
10661 // Don't warn about react-lifecycles-compat polyfilled components.
10662 if (typeof instance.componentWillMount === 'function' && instance.componentWillMount.__suppressDeprecationWarning !== true) {
10663 pendingComponentWillMountWarnings.push(fiber);
10664 }
10665 if (typeof instance.componentWillReceiveProps === 'function' && instance.componentWillReceiveProps.__suppressDeprecationWarning !== true) {
10666 pendingComponentWillReceivePropsWarnings.push(fiber);
10667 }
10668 if (typeof instance.componentWillUpdate === 'function' && instance.componentWillUpdate.__suppressDeprecationWarning !== true) {
10669 pendingComponentWillUpdateWarnings.push(fiber);
10670 }
10671 };
10672
10673 ReactStrictModeWarnings.recordUnsafeLifecycleWarnings = function (fiber, instance) {
10674 var strictRoot = findStrictRoot(fiber);
10675 if (strictRoot === null) {
10676 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.');
10677 return;
10678 }
10679
10680 // Dedup strategy: Warn once per component.
10681 // This is difficult to track any other way since component names
10682 // are often vague and are likely to collide between 3rd party libraries.
10683 // An expand property is probably okay to use here since it's DEV-only,
10684 // and will only be set in the event of serious warnings.
10685 if (didWarnAboutUnsafeLifecycles.has(fiber.type)) {
10686 return;
10687 }
10688
10689 var warningsForRoot = void 0;
10690 if (!pendingUnsafeLifecycleWarnings.has(strictRoot)) {
10691 warningsForRoot = {
10692 UNSAFE_componentWillMount: [],
10693 UNSAFE_componentWillReceiveProps: [],
10694 UNSAFE_componentWillUpdate: []
10695 };
10696
10697 pendingUnsafeLifecycleWarnings.set(strictRoot, warningsForRoot);
10698 } else {
10699 warningsForRoot = pendingUnsafeLifecycleWarnings.get(strictRoot);
10700 }
10701
10702 var unsafeLifecycles = [];
10703 if (typeof instance.componentWillMount === 'function' && instance.componentWillMount.__suppressDeprecationWarning !== true || typeof instance.UNSAFE_componentWillMount === 'function') {
10704 unsafeLifecycles.push('UNSAFE_componentWillMount');
10705 }
10706 if (typeof instance.componentWillReceiveProps === 'function' && instance.componentWillReceiveProps.__suppressDeprecationWarning !== true || typeof instance.UNSAFE_componentWillReceiveProps === 'function') {
10707 unsafeLifecycles.push('UNSAFE_componentWillReceiveProps');
10708 }
10709 if (typeof instance.componentWillUpdate === 'function' && instance.componentWillUpdate.__suppressDeprecationWarning !== true || typeof instance.UNSAFE_componentWillUpdate === 'function') {
10710 unsafeLifecycles.push('UNSAFE_componentWillUpdate');
10711 }
10712
10713 if (unsafeLifecycles.length > 0) {
10714 unsafeLifecycles.forEach(function (lifecycle) {
10715 warningsForRoot[lifecycle].push(fiber);
10716 });
10717 }
10718 };
10719
10720 ReactStrictModeWarnings.recordLegacyContextWarning = function (fiber, instance) {
10721 var strictRoot = findStrictRoot(fiber);
10722 if (strictRoot === null) {
10723 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.');
10724 return;
10725 }
10726
10727 // Dedup strategy: Warn once per component.
10728 if (didWarnAboutLegacyContext.has(fiber.type)) {
10729 return;
10730 }
10731
10732 var warningsForRoot = pendingLegacyContextWarning.get(strictRoot);
10733
10734 if (fiber.type.contextTypes != null || fiber.type.childContextTypes != null || instance !== null && typeof instance.getChildContext === 'function') {
10735 if (warningsForRoot === undefined) {
10736 warningsForRoot = [];
10737 pendingLegacyContextWarning.set(strictRoot, warningsForRoot);
10738 }
10739 warningsForRoot.push(fiber);
10740 }
10741 };
10742
10743 ReactStrictModeWarnings.flushLegacyContextWarning = function () {
10744 pendingLegacyContextWarning.forEach(function (fiberArray, strictRoot) {
10745 var uniqueNames = new Set();
10746 fiberArray.forEach(function (fiber) {
10747 uniqueNames.add(getComponentName(fiber.type) || 'Component');
10748 didWarnAboutLegacyContext.add(fiber.type);
10749 });
10750
10751 var sortedNames = setToSortedString(uniqueNames);
10752 var strictRootComponentStack = getStackByFiberInDevAndProd(strictRoot);
10753
10754 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);
10755 });
10756 };
10757}
10758
10759// This lets us hook into Fiber to debug what it's doing.
10760// See https://github.com/facebook/react/pull/8033.
10761// This is not part of the public API, not even for React DevTools.
10762// You may only inject a debugTool if you work on React Fiber itself.
10763var ReactFiberInstrumentation = {
10764 debugTool: null
10765};
10766
10767var ReactFiberInstrumentation_1 = ReactFiberInstrumentation;
10768
10769// TODO: Offscreen updates should never suspend. However, a promise that
10770// suspended inside an offscreen subtree should be able to ping at the priority
10771// of the outer render.
10772
10773function markPendingPriorityLevel(root, expirationTime) {
10774 // If there's a gap between completing a failed root and retrying it,
10775 // additional updates may be scheduled. Clear `didError`, in case the update
10776 // is sufficient to fix the error.
10777 root.didError = false;
10778
10779 // Update the latest and earliest pending times
10780 var earliestPendingTime = root.earliestPendingTime;
10781 if (earliestPendingTime === NoWork) {
10782 // No other pending updates.
10783 root.earliestPendingTime = root.latestPendingTime = expirationTime;
10784 } else {
10785 if (earliestPendingTime < expirationTime) {
10786 // This is the earliest pending update.
10787 root.earliestPendingTime = expirationTime;
10788 } else {
10789 var latestPendingTime = root.latestPendingTime;
10790 if (latestPendingTime > expirationTime) {
10791 // This is the latest pending update
10792 root.latestPendingTime = expirationTime;
10793 }
10794 }
10795 }
10796 findNextExpirationTimeToWorkOn(expirationTime, root);
10797}
10798
10799function markCommittedPriorityLevels(root, earliestRemainingTime) {
10800 root.didError = false;
10801
10802 if (earliestRemainingTime === NoWork) {
10803 // Fast path. There's no remaining work. Clear everything.
10804 root.earliestPendingTime = NoWork;
10805 root.latestPendingTime = NoWork;
10806 root.earliestSuspendedTime = NoWork;
10807 root.latestSuspendedTime = NoWork;
10808 root.latestPingedTime = NoWork;
10809 findNextExpirationTimeToWorkOn(NoWork, root);
10810 return;
10811 }
10812
10813 if (earliestRemainingTime < root.latestPingedTime) {
10814 root.latestPingedTime = NoWork;
10815 }
10816
10817 // Let's see if the previous latest known pending level was just flushed.
10818 var latestPendingTime = root.latestPendingTime;
10819 if (latestPendingTime !== NoWork) {
10820 if (latestPendingTime > earliestRemainingTime) {
10821 // We've flushed all the known pending levels.
10822 root.earliestPendingTime = root.latestPendingTime = NoWork;
10823 } else {
10824 var earliestPendingTime = root.earliestPendingTime;
10825 if (earliestPendingTime > earliestRemainingTime) {
10826 // We've flushed the earliest known pending level. Set this to the
10827 // latest pending time.
10828 root.earliestPendingTime = root.latestPendingTime;
10829 }
10830 }
10831 }
10832
10833 // Now let's handle the earliest remaining level in the whole tree. We need to
10834 // decide whether to treat it as a pending level or as suspended. Check
10835 // it falls within the range of known suspended levels.
10836
10837 var earliestSuspendedTime = root.earliestSuspendedTime;
10838 if (earliestSuspendedTime === NoWork) {
10839 // There's no suspended work. Treat the earliest remaining level as a
10840 // pending level.
10841 markPendingPriorityLevel(root, earliestRemainingTime);
10842 findNextExpirationTimeToWorkOn(NoWork, root);
10843 return;
10844 }
10845
10846 var latestSuspendedTime = root.latestSuspendedTime;
10847 if (earliestRemainingTime < latestSuspendedTime) {
10848 // The earliest remaining level is later than all the suspended work. That
10849 // means we've flushed all the suspended work.
10850 root.earliestSuspendedTime = NoWork;
10851 root.latestSuspendedTime = NoWork;
10852 root.latestPingedTime = NoWork;
10853
10854 // There's no suspended work. Treat the earliest remaining level as a
10855 // pending level.
10856 markPendingPriorityLevel(root, earliestRemainingTime);
10857 findNextExpirationTimeToWorkOn(NoWork, root);
10858 return;
10859 }
10860
10861 if (earliestRemainingTime > earliestSuspendedTime) {
10862 // The earliest remaining time is earlier than all the suspended work.
10863 // Treat it as a pending update.
10864 markPendingPriorityLevel(root, earliestRemainingTime);
10865 findNextExpirationTimeToWorkOn(NoWork, root);
10866 return;
10867 }
10868
10869 // The earliest remaining time falls within the range of known suspended
10870 // levels. We should treat this as suspended work.
10871 findNextExpirationTimeToWorkOn(NoWork, root);
10872}
10873
10874function hasLowerPriorityWork(root, erroredExpirationTime) {
10875 var latestPendingTime = root.latestPendingTime;
10876 var latestSuspendedTime = root.latestSuspendedTime;
10877 var latestPingedTime = root.latestPingedTime;
10878 return latestPendingTime !== NoWork && latestPendingTime < erroredExpirationTime || latestSuspendedTime !== NoWork && latestSuspendedTime < erroredExpirationTime || latestPingedTime !== NoWork && latestPingedTime < erroredExpirationTime;
10879}
10880
10881function isPriorityLevelSuspended(root, expirationTime) {
10882 var earliestSuspendedTime = root.earliestSuspendedTime;
10883 var latestSuspendedTime = root.latestSuspendedTime;
10884 return earliestSuspendedTime !== NoWork && expirationTime <= earliestSuspendedTime && expirationTime >= latestSuspendedTime;
10885}
10886
10887function markSuspendedPriorityLevel(root, suspendedTime) {
10888 root.didError = false;
10889 clearPing(root, suspendedTime);
10890
10891 // First, check the known pending levels and update them if needed.
10892 var earliestPendingTime = root.earliestPendingTime;
10893 var latestPendingTime = root.latestPendingTime;
10894 if (earliestPendingTime === suspendedTime) {
10895 if (latestPendingTime === suspendedTime) {
10896 // Both known pending levels were suspended. Clear them.
10897 root.earliestPendingTime = root.latestPendingTime = NoWork;
10898 } else {
10899 // The earliest pending level was suspended. Clear by setting it to the
10900 // latest pending level.
10901 root.earliestPendingTime = latestPendingTime;
10902 }
10903 } else if (latestPendingTime === suspendedTime) {
10904 // The latest pending level was suspended. Clear by setting it to the
10905 // latest pending level.
10906 root.latestPendingTime = earliestPendingTime;
10907 }
10908
10909 // Finally, update the known suspended levels.
10910 var earliestSuspendedTime = root.earliestSuspendedTime;
10911 var latestSuspendedTime = root.latestSuspendedTime;
10912 if (earliestSuspendedTime === NoWork) {
10913 // No other suspended levels.
10914 root.earliestSuspendedTime = root.latestSuspendedTime = suspendedTime;
10915 } else {
10916 if (earliestSuspendedTime < suspendedTime) {
10917 // This is the earliest suspended level.
10918 root.earliestSuspendedTime = suspendedTime;
10919 } else if (latestSuspendedTime > suspendedTime) {
10920 // This is the latest suspended level
10921 root.latestSuspendedTime = suspendedTime;
10922 }
10923 }
10924
10925 findNextExpirationTimeToWorkOn(suspendedTime, root);
10926}
10927
10928function markPingedPriorityLevel(root, pingedTime) {
10929 root.didError = false;
10930
10931 // TODO: When we add back resuming, we need to ensure the progressed work
10932 // is thrown out and not reused during the restarted render. One way to
10933 // invalidate the progressed work is to restart at expirationTime + 1.
10934 var latestPingedTime = root.latestPingedTime;
10935 if (latestPingedTime === NoWork || latestPingedTime > pingedTime) {
10936 root.latestPingedTime = pingedTime;
10937 }
10938 findNextExpirationTimeToWorkOn(pingedTime, root);
10939}
10940
10941function clearPing(root, completedTime) {
10942 var latestPingedTime = root.latestPingedTime;
10943 if (latestPingedTime >= completedTime) {
10944 root.latestPingedTime = NoWork;
10945 }
10946}
10947
10948function findEarliestOutstandingPriorityLevel(root, renderExpirationTime) {
10949 var earliestExpirationTime = renderExpirationTime;
10950
10951 var earliestPendingTime = root.earliestPendingTime;
10952 var earliestSuspendedTime = root.earliestSuspendedTime;
10953 if (earliestPendingTime > earliestExpirationTime) {
10954 earliestExpirationTime = earliestPendingTime;
10955 }
10956 if (earliestSuspendedTime > earliestExpirationTime) {
10957 earliestExpirationTime = earliestSuspendedTime;
10958 }
10959 return earliestExpirationTime;
10960}
10961
10962function didExpireAtExpirationTime(root, currentTime) {
10963 var expirationTime = root.expirationTime;
10964 if (expirationTime !== NoWork && currentTime <= expirationTime) {
10965 // The root has expired. Flush all work up to the current time.
10966 root.nextExpirationTimeToWorkOn = currentTime;
10967 }
10968}
10969
10970function findNextExpirationTimeToWorkOn(completedExpirationTime, root) {
10971 var earliestSuspendedTime = root.earliestSuspendedTime;
10972 var latestSuspendedTime = root.latestSuspendedTime;
10973 var earliestPendingTime = root.earliestPendingTime;
10974 var latestPingedTime = root.latestPingedTime;
10975
10976 // Work on the earliest pending time. Failing that, work on the latest
10977 // pinged time.
10978 var nextExpirationTimeToWorkOn = earliestPendingTime !== NoWork ? earliestPendingTime : latestPingedTime;
10979
10980 // If there is no pending or pinged work, check if there's suspended work
10981 // that's lower priority than what we just completed.
10982 if (nextExpirationTimeToWorkOn === NoWork && (completedExpirationTime === NoWork || latestSuspendedTime < completedExpirationTime)) {
10983 // The lowest priority suspended work is the work most likely to be
10984 // committed next. Let's start rendering it again, so that if it times out,
10985 // it's ready to commit.
10986 nextExpirationTimeToWorkOn = latestSuspendedTime;
10987 }
10988
10989 var expirationTime = nextExpirationTimeToWorkOn;
10990 if (expirationTime !== NoWork && earliestSuspendedTime > expirationTime) {
10991 // Expire using the earliest known expiration time.
10992 expirationTime = earliestSuspendedTime;
10993 }
10994
10995 root.nextExpirationTimeToWorkOn = nextExpirationTimeToWorkOn;
10996 root.expirationTime = expirationTime;
10997}
10998
10999// UpdateQueue is a linked list of prioritized updates.
11000//
11001// Like fibers, update queues come in pairs: a current queue, which represents
11002// the visible state of the screen, and a work-in-progress queue, which is
11003// can be mutated and processed asynchronously before it is committed — a form
11004// of double buffering. If a work-in-progress render is discarded before
11005// finishing, we create a new work-in-progress by cloning the current queue.
11006//
11007// Both queues share a persistent, singly-linked list structure. To schedule an
11008// update, we append it to the end of both queues. Each queue maintains a
11009// pointer to first update in the persistent list that hasn't been processed.
11010// The work-in-progress pointer always has a position equal to or greater than
11011// the current queue, since we always work on that one. The current queue's
11012// pointer is only updated during the commit phase, when we swap in the
11013// work-in-progress.
11014//
11015// For example:
11016//
11017// Current pointer: A - B - C - D - E - F
11018// Work-in-progress pointer: D - E - F
11019// ^
11020// The work-in-progress queue has
11021// processed more updates than current.
11022//
11023// The reason we append to both queues is because otherwise we might drop
11024// updates without ever processing them. For example, if we only add updates to
11025// the work-in-progress queue, some updates could be lost whenever a work-in
11026// -progress render restarts by cloning from current. Similarly, if we only add
11027// updates to the current queue, the updates will be lost whenever an already
11028// in-progress queue commits and swaps with the current queue. However, by
11029// adding to both queues, we guarantee that the update will be part of the next
11030// work-in-progress. (And because the work-in-progress queue becomes the
11031// current queue once it commits, there's no danger of applying the same
11032// update twice.)
11033//
11034// Prioritization
11035// --------------
11036//
11037// Updates are not sorted by priority, but by insertion; new updates are always
11038// appended to the end of the list.
11039//
11040// The priority is still important, though. When processing the update queue
11041// during the render phase, only the updates with sufficient priority are
11042// included in the result. If we skip an update because it has insufficient
11043// priority, it remains in the queue to be processed later, during a lower
11044// priority render. Crucially, all updates subsequent to a skipped update also
11045// remain in the queue *regardless of their priority*. That means high priority
11046// updates are sometimes processed twice, at two separate priorities. We also
11047// keep track of a base state, that represents the state before the first
11048// update in the queue is applied.
11049//
11050// For example:
11051//
11052// Given a base state of '', and the following queue of updates
11053//
11054// A1 - B2 - C1 - D2
11055//
11056// where the number indicates the priority, and the update is applied to the
11057// previous state by appending a letter, React will process these updates as
11058// two separate renders, one per distinct priority level:
11059//
11060// First render, at priority 1:
11061// Base state: ''
11062// Updates: [A1, C1]
11063// Result state: 'AC'
11064//
11065// Second render, at priority 2:
11066// Base state: 'A' <- The base state does not include C1,
11067// because B2 was skipped.
11068// Updates: [B2, C1, D2] <- C1 was rebased on top of B2
11069// Result state: 'ABCD'
11070//
11071// Because we process updates in insertion order, and rebase high priority
11072// updates when preceding updates are skipped, the final result is deterministic
11073// regardless of priority. Intermediate state may vary according to system
11074// resources, but the final state is always the same.
11075
11076var UpdateState = 0;
11077var ReplaceState = 1;
11078var ForceUpdate = 2;
11079var CaptureUpdate = 3;
11080
11081// Global state that is reset at the beginning of calling `processUpdateQueue`.
11082// It should only be read right after calling `processUpdateQueue`, via
11083// `checkHasForceUpdateAfterProcessing`.
11084var hasForceUpdate = false;
11085
11086var didWarnUpdateInsideUpdate = void 0;
11087var currentlyProcessingQueue = void 0;
11088var resetCurrentlyProcessingQueue = void 0;
11089{
11090 didWarnUpdateInsideUpdate = false;
11091 currentlyProcessingQueue = null;
11092 resetCurrentlyProcessingQueue = function () {
11093 currentlyProcessingQueue = null;
11094 };
11095}
11096
11097function createUpdateQueue(baseState) {
11098 var queue = {
11099 baseState: baseState,
11100 firstUpdate: null,
11101 lastUpdate: null,
11102 firstCapturedUpdate: null,
11103 lastCapturedUpdate: null,
11104 firstEffect: null,
11105 lastEffect: null,
11106 firstCapturedEffect: null,
11107 lastCapturedEffect: null
11108 };
11109 return queue;
11110}
11111
11112function cloneUpdateQueue(currentQueue) {
11113 var queue = {
11114 baseState: currentQueue.baseState,
11115 firstUpdate: currentQueue.firstUpdate,
11116 lastUpdate: currentQueue.lastUpdate,
11117
11118 // TODO: With resuming, if we bail out and resuse the child tree, we should
11119 // keep these effects.
11120 firstCapturedUpdate: null,
11121 lastCapturedUpdate: null,
11122
11123 firstEffect: null,
11124 lastEffect: null,
11125
11126 firstCapturedEffect: null,
11127 lastCapturedEffect: null
11128 };
11129 return queue;
11130}
11131
11132function createUpdate(expirationTime) {
11133 return {
11134 expirationTime: expirationTime,
11135
11136 tag: UpdateState,
11137 payload: null,
11138 callback: null,
11139
11140 next: null,
11141 nextEffect: null
11142 };
11143}
11144
11145function appendUpdateToQueue(queue, update) {
11146 // Append the update to the end of the list.
11147 if (queue.lastUpdate === null) {
11148 // Queue is empty
11149 queue.firstUpdate = queue.lastUpdate = update;
11150 } else {
11151 queue.lastUpdate.next = update;
11152 queue.lastUpdate = update;
11153 }
11154}
11155
11156function enqueueUpdate(fiber, update) {
11157 // Update queues are created lazily.
11158 var alternate = fiber.alternate;
11159 var queue1 = void 0;
11160 var queue2 = void 0;
11161 if (alternate === null) {
11162 // There's only one fiber.
11163 queue1 = fiber.updateQueue;
11164 queue2 = null;
11165 if (queue1 === null) {
11166 queue1 = fiber.updateQueue = createUpdateQueue(fiber.memoizedState);
11167 }
11168 } else {
11169 // There are two owners.
11170 queue1 = fiber.updateQueue;
11171 queue2 = alternate.updateQueue;
11172 if (queue1 === null) {
11173 if (queue2 === null) {
11174 // Neither fiber has an update queue. Create new ones.
11175 queue1 = fiber.updateQueue = createUpdateQueue(fiber.memoizedState);
11176 queue2 = alternate.updateQueue = createUpdateQueue(alternate.memoizedState);
11177 } else {
11178 // Only one fiber has an update queue. Clone to create a new one.
11179 queue1 = fiber.updateQueue = cloneUpdateQueue(queue2);
11180 }
11181 } else {
11182 if (queue2 === null) {
11183 // Only one fiber has an update queue. Clone to create a new one.
11184 queue2 = alternate.updateQueue = cloneUpdateQueue(queue1);
11185 } else {
11186 // Both owners have an update queue.
11187 }
11188 }
11189 }
11190 if (queue2 === null || queue1 === queue2) {
11191 // There's only a single queue.
11192 appendUpdateToQueue(queue1, update);
11193 } else {
11194 // There are two queues. We need to append the update to both queues,
11195 // while accounting for the persistent structure of the list — we don't
11196 // want the same update to be added multiple times.
11197 if (queue1.lastUpdate === null || queue2.lastUpdate === null) {
11198 // One of the queues is not empty. We must add the update to both queues.
11199 appendUpdateToQueue(queue1, update);
11200 appendUpdateToQueue(queue2, update);
11201 } else {
11202 // Both queues are non-empty. The last update is the same in both lists,
11203 // because of structural sharing. So, only append to one of the lists.
11204 appendUpdateToQueue(queue1, update);
11205 // But we still need to update the `lastUpdate` pointer of queue2.
11206 queue2.lastUpdate = update;
11207 }
11208 }
11209
11210 {
11211 if (fiber.tag === ClassComponent && (currentlyProcessingQueue === queue1 || queue2 !== null && currentlyProcessingQueue === queue2) && !didWarnUpdateInsideUpdate) {
11212 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.');
11213 didWarnUpdateInsideUpdate = true;
11214 }
11215 }
11216}
11217
11218function enqueueCapturedUpdate(workInProgress, update) {
11219 // Captured updates go into a separate list, and only on the work-in-
11220 // progress queue.
11221 var workInProgressQueue = workInProgress.updateQueue;
11222 if (workInProgressQueue === null) {
11223 workInProgressQueue = workInProgress.updateQueue = createUpdateQueue(workInProgress.memoizedState);
11224 } else {
11225 // TODO: I put this here rather than createWorkInProgress so that we don't
11226 // clone the queue unnecessarily. There's probably a better way to
11227 // structure this.
11228 workInProgressQueue = ensureWorkInProgressQueueIsAClone(workInProgress, workInProgressQueue);
11229 }
11230
11231 // Append the update to the end of the list.
11232 if (workInProgressQueue.lastCapturedUpdate === null) {
11233 // This is the first render phase update
11234 workInProgressQueue.firstCapturedUpdate = workInProgressQueue.lastCapturedUpdate = update;
11235 } else {
11236 workInProgressQueue.lastCapturedUpdate.next = update;
11237 workInProgressQueue.lastCapturedUpdate = update;
11238 }
11239}
11240
11241function ensureWorkInProgressQueueIsAClone(workInProgress, queue) {
11242 var current = workInProgress.alternate;
11243 if (current !== null) {
11244 // If the work-in-progress queue is equal to the current queue,
11245 // we need to clone it first.
11246 if (queue === current.updateQueue) {
11247 queue = workInProgress.updateQueue = cloneUpdateQueue(queue);
11248 }
11249 }
11250 return queue;
11251}
11252
11253function getStateFromUpdate(workInProgress, queue, update, prevState, nextProps, instance) {
11254 switch (update.tag) {
11255 case ReplaceState:
11256 {
11257 var _payload = update.payload;
11258 if (typeof _payload === 'function') {
11259 // Updater function
11260 {
11261 if (debugRenderPhaseSideEffects || debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) {
11262 _payload.call(instance, prevState, nextProps);
11263 }
11264 }
11265 return _payload.call(instance, prevState, nextProps);
11266 }
11267 // State object
11268 return _payload;
11269 }
11270 case CaptureUpdate:
11271 {
11272 workInProgress.effectTag = workInProgress.effectTag & ~ShouldCapture | DidCapture;
11273 }
11274 // Intentional fallthrough
11275 case UpdateState:
11276 {
11277 var _payload2 = update.payload;
11278 var partialState = void 0;
11279 if (typeof _payload2 === 'function') {
11280 // Updater function
11281 {
11282 if (debugRenderPhaseSideEffects || debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) {
11283 _payload2.call(instance, prevState, nextProps);
11284 }
11285 }
11286 partialState = _payload2.call(instance, prevState, nextProps);
11287 } else {
11288 // Partial state object
11289 partialState = _payload2;
11290 }
11291 if (partialState === null || partialState === undefined) {
11292 // Null and undefined are treated as no-ops.
11293 return prevState;
11294 }
11295 // Merge the partial state and the previous state.
11296 return _assign({}, prevState, partialState);
11297 }
11298 case ForceUpdate:
11299 {
11300 hasForceUpdate = true;
11301 return prevState;
11302 }
11303 }
11304 return prevState;
11305}
11306
11307function processUpdateQueue(workInProgress, queue, props, instance, renderExpirationTime) {
11308 hasForceUpdate = false;
11309
11310 queue = ensureWorkInProgressQueueIsAClone(workInProgress, queue);
11311
11312 {
11313 currentlyProcessingQueue = queue;
11314 }
11315
11316 // These values may change as we process the queue.
11317 var newBaseState = queue.baseState;
11318 var newFirstUpdate = null;
11319 var newExpirationTime = NoWork;
11320
11321 // Iterate through the list of updates to compute the result.
11322 var update = queue.firstUpdate;
11323 var resultState = newBaseState;
11324 while (update !== null) {
11325 var updateExpirationTime = update.expirationTime;
11326 if (updateExpirationTime < renderExpirationTime) {
11327 // This update does not have sufficient priority. Skip it.
11328 if (newFirstUpdate === null) {
11329 // This is the first skipped update. It will be the first update in
11330 // the new list.
11331 newFirstUpdate = update;
11332 // Since this is the first update that was skipped, the current result
11333 // is the new base state.
11334 newBaseState = resultState;
11335 }
11336 // Since this update will remain in the list, update the remaining
11337 // expiration time.
11338 if (newExpirationTime < updateExpirationTime) {
11339 newExpirationTime = updateExpirationTime;
11340 }
11341 } else {
11342 // This update does have sufficient priority. Process it and compute
11343 // a new result.
11344 resultState = getStateFromUpdate(workInProgress, queue, update, resultState, props, instance);
11345 var _callback = update.callback;
11346 if (_callback !== null) {
11347 workInProgress.effectTag |= Callback;
11348 // Set this to null, in case it was mutated during an aborted render.
11349 update.nextEffect = null;
11350 if (queue.lastEffect === null) {
11351 queue.firstEffect = queue.lastEffect = update;
11352 } else {
11353 queue.lastEffect.nextEffect = update;
11354 queue.lastEffect = update;
11355 }
11356 }
11357 }
11358 // Continue to the next update.
11359 update = update.next;
11360 }
11361
11362 // Separately, iterate though the list of captured updates.
11363 var newFirstCapturedUpdate = null;
11364 update = queue.firstCapturedUpdate;
11365 while (update !== null) {
11366 var _updateExpirationTime = update.expirationTime;
11367 if (_updateExpirationTime < renderExpirationTime) {
11368 // This update does not have sufficient priority. Skip it.
11369 if (newFirstCapturedUpdate === null) {
11370 // This is the first skipped captured update. It will be the first
11371 // update in the new list.
11372 newFirstCapturedUpdate = update;
11373 // If this is the first update that was skipped, the current result is
11374 // the new base state.
11375 if (newFirstUpdate === null) {
11376 newBaseState = resultState;
11377 }
11378 }
11379 // Since this update will remain in the list, update the remaining
11380 // expiration time.
11381 if (newExpirationTime < _updateExpirationTime) {
11382 newExpirationTime = _updateExpirationTime;
11383 }
11384 } else {
11385 // This update does have sufficient priority. Process it and compute
11386 // a new result.
11387 resultState = getStateFromUpdate(workInProgress, queue, update, resultState, props, instance);
11388 var _callback2 = update.callback;
11389 if (_callback2 !== null) {
11390 workInProgress.effectTag |= Callback;
11391 // Set this to null, in case it was mutated during an aborted render.
11392 update.nextEffect = null;
11393 if (queue.lastCapturedEffect === null) {
11394 queue.firstCapturedEffect = queue.lastCapturedEffect = update;
11395 } else {
11396 queue.lastCapturedEffect.nextEffect = update;
11397 queue.lastCapturedEffect = update;
11398 }
11399 }
11400 }
11401 update = update.next;
11402 }
11403
11404 if (newFirstUpdate === null) {
11405 queue.lastUpdate = null;
11406 }
11407 if (newFirstCapturedUpdate === null) {
11408 queue.lastCapturedUpdate = null;
11409 } else {
11410 workInProgress.effectTag |= Callback;
11411 }
11412 if (newFirstUpdate === null && newFirstCapturedUpdate === null) {
11413 // We processed every update, without skipping. That means the new base
11414 // state is the same as the result state.
11415 newBaseState = resultState;
11416 }
11417
11418 queue.baseState = newBaseState;
11419 queue.firstUpdate = newFirstUpdate;
11420 queue.firstCapturedUpdate = newFirstCapturedUpdate;
11421
11422 // Set the remaining expiration time to be whatever is remaining in the queue.
11423 // This should be fine because the only two other things that contribute to
11424 // expiration time are props and context. We're already in the middle of the
11425 // begin phase by the time we start processing the queue, so we've already
11426 // dealt with the props. Context in components that specify
11427 // shouldComponentUpdate is tricky; but we'll have to account for
11428 // that regardless.
11429 workInProgress.expirationTime = newExpirationTime;
11430 workInProgress.memoizedState = resultState;
11431
11432 {
11433 currentlyProcessingQueue = null;
11434 }
11435}
11436
11437function callCallback(callback, context) {
11438 !(typeof callback === 'function') ? invariant(false, 'Invalid argument passed as callback. Expected a function. Instead received: %s', callback) : void 0;
11439 callback.call(context);
11440}
11441
11442function resetHasForceUpdateBeforeProcessing() {
11443 hasForceUpdate = false;
11444}
11445
11446function checkHasForceUpdateAfterProcessing() {
11447 return hasForceUpdate;
11448}
11449
11450function commitUpdateQueue(finishedWork, finishedQueue, instance, renderExpirationTime) {
11451 // If the finished render included captured updates, and there are still
11452 // lower priority updates left over, we need to keep the captured updates
11453 // in the queue so that they are rebased and not dropped once we process the
11454 // queue again at the lower priority.
11455 if (finishedQueue.firstCapturedUpdate !== null) {
11456 // Join the captured update list to the end of the normal list.
11457 if (finishedQueue.lastUpdate !== null) {
11458 finishedQueue.lastUpdate.next = finishedQueue.firstCapturedUpdate;
11459 finishedQueue.lastUpdate = finishedQueue.lastCapturedUpdate;
11460 }
11461 // Clear the list of captured updates.
11462 finishedQueue.firstCapturedUpdate = finishedQueue.lastCapturedUpdate = null;
11463 }
11464
11465 // Commit the effects
11466 commitUpdateEffects(finishedQueue.firstEffect, instance);
11467 finishedQueue.firstEffect = finishedQueue.lastEffect = null;
11468
11469 commitUpdateEffects(finishedQueue.firstCapturedEffect, instance);
11470 finishedQueue.firstCapturedEffect = finishedQueue.lastCapturedEffect = null;
11471}
11472
11473function commitUpdateEffects(effect, instance) {
11474 while (effect !== null) {
11475 var _callback3 = effect.callback;
11476 if (_callback3 !== null) {
11477 effect.callback = null;
11478 callCallback(_callback3, instance);
11479 }
11480 effect = effect.nextEffect;
11481 }
11482}
11483
11484function createCapturedValue(value, source) {
11485 // If the value is an error, call this function immediately after it is thrown
11486 // so the stack is accurate.
11487 return {
11488 value: value,
11489 source: source,
11490 stack: getStackByFiberInDevAndProd(source)
11491 };
11492}
11493
11494var valueCursor = createCursor(null);
11495
11496var rendererSigil = void 0;
11497{
11498 // Use this to detect multiple renderers using the same context
11499 rendererSigil = {};
11500}
11501
11502var currentlyRenderingFiber = null;
11503var lastContextDependency = null;
11504var lastContextWithAllBitsObserved = null;
11505
11506function resetContextDependences() {
11507 // This is called right before React yields execution, to ensure `readContext`
11508 // cannot be called outside the render phase.
11509 currentlyRenderingFiber = null;
11510 lastContextDependency = null;
11511 lastContextWithAllBitsObserved = null;
11512}
11513
11514function pushProvider(providerFiber, nextValue) {
11515 var context = providerFiber.type._context;
11516
11517 if (isPrimaryRenderer) {
11518 push(valueCursor, context._currentValue, providerFiber);
11519
11520 context._currentValue = nextValue;
11521 {
11522 !(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;
11523 context._currentRenderer = rendererSigil;
11524 }
11525 } else {
11526 push(valueCursor, context._currentValue2, providerFiber);
11527
11528 context._currentValue2 = nextValue;
11529 {
11530 !(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;
11531 context._currentRenderer2 = rendererSigil;
11532 }
11533 }
11534}
11535
11536function popProvider(providerFiber) {
11537 var currentValue = valueCursor.current;
11538
11539 pop(valueCursor, providerFiber);
11540
11541 var context = providerFiber.type._context;
11542 if (isPrimaryRenderer) {
11543 context._currentValue = currentValue;
11544 } else {
11545 context._currentValue2 = currentValue;
11546 }
11547}
11548
11549function calculateChangedBits(context, newValue, oldValue) {
11550 // Use Object.is to compare the new context value to the old value. Inlined
11551 // Object.is polyfill.
11552 // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is
11553 if (oldValue === newValue && (oldValue !== 0 || 1 / oldValue === 1 / newValue) || oldValue !== oldValue && newValue !== newValue // eslint-disable-line no-self-compare
11554 ) {
11555 // No change
11556 return 0;
11557 } else {
11558 var changedBits = typeof context._calculateChangedBits === 'function' ? context._calculateChangedBits(oldValue, newValue) : maxSigned31BitInt;
11559
11560 {
11561 !((changedBits & maxSigned31BitInt) === changedBits) ? warning$1(false, 'calculateChangedBits: Expected the return value to be a ' + '31-bit integer. Instead received: %s', changedBits) : void 0;
11562 }
11563 return changedBits | 0;
11564 }
11565}
11566
11567function propagateContextChange(workInProgress, context, changedBits, renderExpirationTime) {
11568 var fiber = workInProgress.child;
11569 if (fiber !== null) {
11570 // Set the return pointer of the child to the work-in-progress fiber.
11571 fiber.return = workInProgress;
11572 }
11573 while (fiber !== null) {
11574 var nextFiber = void 0;
11575
11576 // Visit this fiber.
11577 var dependency = fiber.firstContextDependency;
11578 if (dependency !== null) {
11579 do {
11580 // Check if the context matches.
11581 if (dependency.context === context && (dependency.observedBits & changedBits) !== 0) {
11582 // Match! Schedule an update on this fiber.
11583
11584 if (fiber.tag === ClassComponent) {
11585 // Schedule a force update on the work-in-progress.
11586 var update = createUpdate(renderExpirationTime);
11587 update.tag = ForceUpdate;
11588 // TODO: Because we don't have a work-in-progress, this will add the
11589 // update to the current fiber, too, which means it will persist even if
11590 // this render is thrown away. Since it's a race condition, not sure it's
11591 // worth fixing.
11592 enqueueUpdate(fiber, update);
11593 }
11594
11595 if (fiber.expirationTime < renderExpirationTime) {
11596 fiber.expirationTime = renderExpirationTime;
11597 }
11598 var alternate = fiber.alternate;
11599 if (alternate !== null && alternate.expirationTime < renderExpirationTime) {
11600 alternate.expirationTime = renderExpirationTime;
11601 }
11602 // Update the child expiration time of all the ancestors, including
11603 // the alternates.
11604 var node = fiber.return;
11605 while (node !== null) {
11606 alternate = node.alternate;
11607 if (node.childExpirationTime < renderExpirationTime) {
11608 node.childExpirationTime = renderExpirationTime;
11609 if (alternate !== null && alternate.childExpirationTime < renderExpirationTime) {
11610 alternate.childExpirationTime = renderExpirationTime;
11611 }
11612 } else if (alternate !== null && alternate.childExpirationTime < renderExpirationTime) {
11613 alternate.childExpirationTime = renderExpirationTime;
11614 } else {
11615 // Neither alternate was updated, which means the rest of the
11616 // ancestor path already has sufficient priority.
11617 break;
11618 }
11619 node = node.return;
11620 }
11621 }
11622 nextFiber = fiber.child;
11623 dependency = dependency.next;
11624 } while (dependency !== null);
11625 } else if (fiber.tag === ContextProvider) {
11626 // Don't scan deeper if this is a matching provider
11627 nextFiber = fiber.type === workInProgress.type ? null : fiber.child;
11628 } else {
11629 // Traverse down.
11630 nextFiber = fiber.child;
11631 }
11632
11633 if (nextFiber !== null) {
11634 // Set the return pointer of the child to the work-in-progress fiber.
11635 nextFiber.return = fiber;
11636 } else {
11637 // No child. Traverse to next sibling.
11638 nextFiber = fiber;
11639 while (nextFiber !== null) {
11640 if (nextFiber === workInProgress) {
11641 // We're back to the root of this subtree. Exit.
11642 nextFiber = null;
11643 break;
11644 }
11645 var sibling = nextFiber.sibling;
11646 if (sibling !== null) {
11647 // Set the return pointer of the sibling to the work-in-progress fiber.
11648 sibling.return = nextFiber.return;
11649 nextFiber = sibling;
11650 break;
11651 }
11652 // No more siblings. Traverse up.
11653 nextFiber = nextFiber.return;
11654 }
11655 }
11656 fiber = nextFiber;
11657 }
11658}
11659
11660function prepareToReadContext(workInProgress, renderExpirationTime) {
11661 currentlyRenderingFiber = workInProgress;
11662 lastContextDependency = null;
11663 lastContextWithAllBitsObserved = null;
11664
11665 // Reset the work-in-progress list
11666 workInProgress.firstContextDependency = null;
11667}
11668
11669function readContext(context, observedBits) {
11670 if (lastContextWithAllBitsObserved === context) {
11671 // Nothing to do. We already observe everything in this context.
11672 } else if (observedBits === false || observedBits === 0) {
11673 // Do not observe any updates.
11674 } else {
11675 var resolvedObservedBits = void 0; // Avoid deopting on observable arguments or heterogeneous types.
11676 if (typeof observedBits !== 'number' || observedBits === maxSigned31BitInt) {
11677 // Observe all updates.
11678 lastContextWithAllBitsObserved = context;
11679 resolvedObservedBits = maxSigned31BitInt;
11680 } else {
11681 resolvedObservedBits = observedBits;
11682 }
11683
11684 var contextItem = {
11685 context: context,
11686 observedBits: resolvedObservedBits,
11687 next: null
11688 };
11689
11690 if (lastContextDependency === null) {
11691 !(currentlyRenderingFiber !== null) ? invariant(false, 'Context can only be read while React is rendering, e.g. inside the render method or getDerivedStateFromProps.') : void 0;
11692 // This is the first dependency in the list
11693 currentlyRenderingFiber.firstContextDependency = lastContextDependency = contextItem;
11694 } else {
11695 // Append a new context item.
11696 lastContextDependency = lastContextDependency.next = contextItem;
11697 }
11698 }
11699 return isPrimaryRenderer ? context._currentValue : context._currentValue2;
11700}
11701
11702var NoEffect$1 = /* */0;
11703var UnmountSnapshot = /* */2;
11704var UnmountMutation = /* */4;
11705var MountMutation = /* */8;
11706var UnmountLayout = /* */16;
11707var MountLayout = /* */32;
11708var MountPassive = /* */64;
11709var UnmountPassive = /* */128;
11710
11711function areHookInputsEqual(arr1, arr2) {
11712 // Don't bother comparing lengths in prod because these arrays should be
11713 // passed inline.
11714 {
11715 !(arr1.length === arr2.length) ? warning$1(false, 'Detected a variable number of hook dependencies. The length of the ' + 'dependencies array should be constant between renders.\n\n' + 'Previous: %s\n' + 'Incoming: %s', arr1.join(', '), arr2.join(', ')) : void 0;
11716 }
11717 for (var i = 0; i < arr1.length; i++) {
11718 // Inlined Object.is polyfill.
11719 // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is
11720 var val1 = arr1[i];
11721 var val2 = arr2[i];
11722 if (val1 === val2 && (val1 !== 0 || 1 / val1 === 1 / val2) || val1 !== val1 && val2 !== val2 // eslint-disable-line no-self-compare
11723 ) {
11724 continue;
11725 }
11726 return false;
11727 }
11728 return true;
11729}
11730
11731// These are set right before calling the component.
11732var renderExpirationTime = NoWork;
11733// The work-in-progress fiber. I've named it differently to distinguish it from
11734// the work-in-progress hook.
11735var currentlyRenderingFiber$1 = null;
11736
11737// Hooks are stored as a linked list on the fiber's memoizedState field. The
11738// current hook list is the list that belongs to the current fiber. The
11739// work-in-progress hook list is a new list that will be added to the
11740// work-in-progress fiber.
11741var firstCurrentHook = null;
11742var currentHook = null;
11743var firstWorkInProgressHook = null;
11744var workInProgressHook = null;
11745
11746var remainingExpirationTime = NoWork;
11747var componentUpdateQueue = null;
11748
11749// Updates scheduled during render will trigger an immediate re-render at the
11750// end of the current pass. We can't store these updates on the normal queue,
11751// because if the work is aborted, they should be discarded. Because this is
11752// a relatively rare case, we also don't want to add an additional field to
11753// either the hook or queue object types. So we store them in a lazily create
11754// map of queue -> render-phase updates, which are discarded once the component
11755// completes without re-rendering.
11756
11757// Whether the work-in-progress hook is a re-rendered hook
11758var isReRender = false;
11759// Whether an update was scheduled during the currently executing render pass.
11760var didScheduleRenderPhaseUpdate = false;
11761// Lazily created map of render-phase updates
11762var renderPhaseUpdates = null;
11763// Counter to prevent infinite loops.
11764var numberOfReRenders = 0;
11765var RE_RENDER_LIMIT = 25;
11766
11767function resolveCurrentlyRenderingFiber() {
11768 !(currentlyRenderingFiber$1 !== null) ? invariant(false, 'Hooks can only be called inside the body of a function component.') : void 0;
11769 return currentlyRenderingFiber$1;
11770}
11771
11772function prepareToUseHooks(current, workInProgress, nextRenderExpirationTime) {
11773 if (!enableHooks) {
11774 return;
11775 }
11776 renderExpirationTime = nextRenderExpirationTime;
11777 currentlyRenderingFiber$1 = workInProgress;
11778 firstCurrentHook = current !== null ? current.memoizedState : null;
11779
11780 // The following should have already been reset
11781 // currentHook = null;
11782 // workInProgressHook = null;
11783
11784 // remainingExpirationTime = NoWork;
11785 // componentUpdateQueue = null;
11786
11787 // isReRender = false;
11788 // didScheduleRenderPhaseUpdate = false;
11789 // renderPhaseUpdates = null;
11790 // numberOfReRenders = 0;
11791}
11792
11793function finishHooks(Component, props, children, refOrContext) {
11794 if (!enableHooks) {
11795 return children;
11796 }
11797
11798 // This must be called after every function component to prevent hooks from
11799 // being used in classes.
11800
11801 while (didScheduleRenderPhaseUpdate) {
11802 // Updates were scheduled during the render phase. They are stored in
11803 // the `renderPhaseUpdates` map. Call the component again, reusing the
11804 // work-in-progress hooks and applying the additional updates on top. Keep
11805 // restarting until no more updates are scheduled.
11806 didScheduleRenderPhaseUpdate = false;
11807 numberOfReRenders += 1;
11808
11809 // Start over from the beginning of the list
11810 currentHook = null;
11811 workInProgressHook = null;
11812 componentUpdateQueue = null;
11813
11814 children = Component(props, refOrContext);
11815 }
11816 renderPhaseUpdates = null;
11817 numberOfReRenders = 0;
11818
11819 var renderedWork = currentlyRenderingFiber$1;
11820
11821 renderedWork.memoizedState = firstWorkInProgressHook;
11822 renderedWork.expirationTime = remainingExpirationTime;
11823 renderedWork.updateQueue = componentUpdateQueue;
11824
11825 var didRenderTooFewHooks = currentHook !== null && currentHook.next !== null;
11826
11827 renderExpirationTime = NoWork;
11828 currentlyRenderingFiber$1 = null;
11829
11830 firstCurrentHook = null;
11831 currentHook = null;
11832 firstWorkInProgressHook = null;
11833 workInProgressHook = null;
11834
11835 remainingExpirationTime = NoWork;
11836 componentUpdateQueue = null;
11837
11838 // Always set during createWorkInProgress
11839 // isReRender = false;
11840
11841 // These were reset above
11842 // didScheduleRenderPhaseUpdate = false;
11843 // renderPhaseUpdates = null;
11844 // numberOfReRenders = 0;
11845
11846 !!didRenderTooFewHooks ? invariant(false, 'Rendered fewer hooks than expected. This may be caused by an accidental early return statement.') : void 0;
11847
11848 return children;
11849}
11850
11851function resetHooks() {
11852 if (!enableHooks) {
11853 return;
11854 }
11855
11856 // This is called instead of `finishHooks` if the component throws. It's also
11857 // called inside mountIndeterminateComponent if we determine the component
11858 // is a module-style component.
11859 renderExpirationTime = NoWork;
11860 currentlyRenderingFiber$1 = null;
11861
11862 firstCurrentHook = null;
11863 currentHook = null;
11864 firstWorkInProgressHook = null;
11865 workInProgressHook = null;
11866
11867 remainingExpirationTime = NoWork;
11868 componentUpdateQueue = null;
11869
11870 // Always set during createWorkInProgress
11871 // isReRender = false;
11872
11873 didScheduleRenderPhaseUpdate = false;
11874 renderPhaseUpdates = null;
11875 numberOfReRenders = 0;
11876}
11877
11878function createHook() {
11879 return {
11880 memoizedState: null,
11881
11882 baseState: null,
11883 queue: null,
11884 baseUpdate: null,
11885
11886 next: null
11887 };
11888}
11889
11890function cloneHook(hook) {
11891 return {
11892 memoizedState: hook.memoizedState,
11893
11894 baseState: hook.baseState,
11895 queue: hook.queue,
11896 baseUpdate: hook.baseUpdate,
11897
11898 next: null
11899 };
11900}
11901
11902function createWorkInProgressHook() {
11903 if (workInProgressHook === null) {
11904 // This is the first hook in the list
11905 if (firstWorkInProgressHook === null) {
11906 isReRender = false;
11907 currentHook = firstCurrentHook;
11908 if (currentHook === null) {
11909 // This is a newly mounted hook
11910 workInProgressHook = createHook();
11911 } else {
11912 // Clone the current hook.
11913 workInProgressHook = cloneHook(currentHook);
11914 }
11915 firstWorkInProgressHook = workInProgressHook;
11916 } else {
11917 // There's already a work-in-progress. Reuse it.
11918 isReRender = true;
11919 currentHook = firstCurrentHook;
11920 workInProgressHook = firstWorkInProgressHook;
11921 }
11922 } else {
11923 if (workInProgressHook.next === null) {
11924 isReRender = false;
11925 var hook = void 0;
11926 if (currentHook === null) {
11927 // This is a newly mounted hook
11928 hook = createHook();
11929 } else {
11930 currentHook = currentHook.next;
11931 if (currentHook === null) {
11932 // This is a newly mounted hook
11933 hook = createHook();
11934 } else {
11935 // Clone the current hook.
11936 hook = cloneHook(currentHook);
11937 }
11938 }
11939 // Append to the end of the list
11940 workInProgressHook = workInProgressHook.next = hook;
11941 } else {
11942 // There's already a work-in-progress. Reuse it.
11943 isReRender = true;
11944 workInProgressHook = workInProgressHook.next;
11945 currentHook = currentHook !== null ? currentHook.next : null;
11946 }
11947 }
11948 return workInProgressHook;
11949}
11950
11951function createFunctionComponentUpdateQueue() {
11952 return {
11953 lastEffect: null
11954 };
11955}
11956
11957function basicStateReducer(state, action) {
11958 return typeof action === 'function' ? action(state) : action;
11959}
11960
11961function useContext(context, observedBits) {
11962 // Ensure we're in a function component (class components support only the
11963 // .unstable_read() form)
11964 resolveCurrentlyRenderingFiber();
11965 return readContext(context, observedBits);
11966}
11967
11968function useState(initialState) {
11969 return useReducer(basicStateReducer,
11970 // useReducer has a special case to support lazy useState initializers
11971 initialState);
11972}
11973
11974function useReducer(reducer, initialState, initialAction) {
11975 currentlyRenderingFiber$1 = resolveCurrentlyRenderingFiber();
11976 workInProgressHook = createWorkInProgressHook();
11977 var queue = workInProgressHook.queue;
11978 if (queue !== null) {
11979 // Already have a queue, so this is an update.
11980 if (isReRender) {
11981 // This is a re-render. Apply the new render phase updates to the previous
11982 var _dispatch2 = queue.dispatch;
11983 if (renderPhaseUpdates !== null) {
11984 // Render phase updates are stored in a map of queue -> linked list
11985 var firstRenderPhaseUpdate = renderPhaseUpdates.get(queue);
11986 if (firstRenderPhaseUpdate !== undefined) {
11987 renderPhaseUpdates.delete(queue);
11988 var newState = workInProgressHook.memoizedState;
11989 var update = firstRenderPhaseUpdate;
11990 do {
11991 // Process this render phase update. We don't have to check the
11992 // priority because it will always be the same as the current
11993 // render's.
11994 var _action = update.action;
11995 newState = reducer(newState, _action);
11996 update = update.next;
11997 } while (update !== null);
11998
11999 workInProgressHook.memoizedState = newState;
12000
12001 // Don't persist the state accumlated from the render phase updates to
12002 // the base state unless the queue is empty.
12003 // TODO: Not sure if this is the desired semantics, but it's what we
12004 // do for gDSFP. I can't remember why.
12005 if (workInProgressHook.baseUpdate === queue.last) {
12006 workInProgressHook.baseState = newState;
12007 }
12008
12009 return [newState, _dispatch2];
12010 }
12011 }
12012 return [workInProgressHook.memoizedState, _dispatch2];
12013 }
12014
12015 // The last update in the entire queue
12016 var _last = queue.last;
12017 // The last update that is part of the base state.
12018 var _baseUpdate = workInProgressHook.baseUpdate;
12019
12020 // Find the first unprocessed update.
12021 var first = void 0;
12022 if (_baseUpdate !== null) {
12023 if (_last !== null) {
12024 // For the first update, the queue is a circular linked list where
12025 // `queue.last.next = queue.first`. Once the first update commits, and
12026 // the `baseUpdate` is no longer empty, we can unravel the list.
12027 _last.next = null;
12028 }
12029 first = _baseUpdate.next;
12030 } else {
12031 first = _last !== null ? _last.next : null;
12032 }
12033 if (first !== null) {
12034 var _newState = workInProgressHook.baseState;
12035 var newBaseState = null;
12036 var newBaseUpdate = null;
12037 var prevUpdate = _baseUpdate;
12038 var _update = first;
12039 var didSkip = false;
12040 do {
12041 var updateExpirationTime = _update.expirationTime;
12042 if (updateExpirationTime < renderExpirationTime) {
12043 // Priority is insufficient. Skip this update. If this is the first
12044 // skipped update, the previous update/state is the new base
12045 // update/state.
12046 if (!didSkip) {
12047 didSkip = true;
12048 newBaseUpdate = prevUpdate;
12049 newBaseState = _newState;
12050 }
12051 // Update the remaining priority in the queue.
12052 if (updateExpirationTime > remainingExpirationTime) {
12053 remainingExpirationTime = updateExpirationTime;
12054 }
12055 } else {
12056 // Process this update.
12057 var _action2 = _update.action;
12058 _newState = reducer(_newState, _action2);
12059 }
12060 prevUpdate = _update;
12061 _update = _update.next;
12062 } while (_update !== null && _update !== first);
12063
12064 if (!didSkip) {
12065 newBaseUpdate = prevUpdate;
12066 newBaseState = _newState;
12067 }
12068
12069 workInProgressHook.memoizedState = _newState;
12070 workInProgressHook.baseUpdate = newBaseUpdate;
12071 workInProgressHook.baseState = newBaseState;
12072 }
12073
12074 var _dispatch = queue.dispatch;
12075 return [workInProgressHook.memoizedState, _dispatch];
12076 }
12077
12078 // There's no existing queue, so this is the initial render.
12079 if (reducer === basicStateReducer) {
12080 // Special case for `useState`.
12081 if (typeof initialState === 'function') {
12082 initialState = initialState();
12083 }
12084 } else if (initialAction !== undefined && initialAction !== null) {
12085 initialState = reducer(initialState, initialAction);
12086 }
12087 workInProgressHook.memoizedState = workInProgressHook.baseState = initialState;
12088 queue = workInProgressHook.queue = {
12089 last: null,
12090 dispatch: null
12091 };
12092 var dispatch = queue.dispatch = dispatchAction.bind(null, currentlyRenderingFiber$1, queue);
12093 return [workInProgressHook.memoizedState, dispatch];
12094}
12095
12096function pushEffect(tag, create, destroy, inputs) {
12097 var effect = {
12098 tag: tag,
12099 create: create,
12100 destroy: destroy,
12101 inputs: inputs,
12102 // Circular
12103 next: null
12104 };
12105 if (componentUpdateQueue === null) {
12106 componentUpdateQueue = createFunctionComponentUpdateQueue();
12107 componentUpdateQueue.lastEffect = effect.next = effect;
12108 } else {
12109 var _lastEffect = componentUpdateQueue.lastEffect;
12110 if (_lastEffect === null) {
12111 componentUpdateQueue.lastEffect = effect.next = effect;
12112 } else {
12113 var firstEffect = _lastEffect.next;
12114 _lastEffect.next = effect;
12115 effect.next = firstEffect;
12116 componentUpdateQueue.lastEffect = effect;
12117 }
12118 }
12119 return effect;
12120}
12121
12122function useRef(initialValue) {
12123 currentlyRenderingFiber$1 = resolveCurrentlyRenderingFiber();
12124 workInProgressHook = createWorkInProgressHook();
12125 var ref = void 0;
12126
12127 if (workInProgressHook.memoizedState === null) {
12128 ref = { current: initialValue };
12129 {
12130 Object.seal(ref);
12131 }
12132 workInProgressHook.memoizedState = ref;
12133 } else {
12134 ref = workInProgressHook.memoizedState;
12135 }
12136 return ref;
12137}
12138
12139function useLayoutEffect(create, inputs) {
12140 useEffectImpl(Update, UnmountMutation | MountLayout, create, inputs);
12141}
12142
12143function useEffect(create, inputs) {
12144 useEffectImpl(Update | Passive, UnmountPassive | MountPassive, create, inputs);
12145}
12146
12147function useEffectImpl(fiberEffectTag, hookEffectTag, create, inputs) {
12148 currentlyRenderingFiber$1 = resolveCurrentlyRenderingFiber();
12149 workInProgressHook = createWorkInProgressHook();
12150
12151 var nextInputs = inputs !== undefined && inputs !== null ? inputs : [create];
12152 var destroy = null;
12153 if (currentHook !== null) {
12154 var prevEffect = currentHook.memoizedState;
12155 destroy = prevEffect.destroy;
12156 if (areHookInputsEqual(nextInputs, prevEffect.inputs)) {
12157 pushEffect(NoEffect$1, create, destroy, nextInputs);
12158 return;
12159 }
12160 }
12161
12162 currentlyRenderingFiber$1.effectTag |= fiberEffectTag;
12163 workInProgressHook.memoizedState = pushEffect(hookEffectTag, create, destroy, nextInputs);
12164}
12165
12166function useImperativeMethods(ref, create, inputs) {
12167 // TODO: If inputs are provided, should we skip comparing the ref itself?
12168 var nextInputs = inputs !== null && inputs !== undefined ? inputs.concat([ref]) : [ref, create];
12169
12170 // TODO: I've implemented this on top of useEffect because it's almost the
12171 // same thing, and it would require an equal amount of code. It doesn't seem
12172 // like a common enough use case to justify the additional size.
12173 useLayoutEffect(function () {
12174 if (typeof ref === 'function') {
12175 var refCallback = ref;
12176 var _inst = create();
12177 refCallback(_inst);
12178 return function () {
12179 return refCallback(null);
12180 };
12181 } else if (ref !== null && ref !== undefined) {
12182 var refObject = ref;
12183 var _inst2 = create();
12184 refObject.current = _inst2;
12185 return function () {
12186 refObject.current = null;
12187 };
12188 }
12189 }, nextInputs);
12190}
12191
12192function useCallback(callback, inputs) {
12193 currentlyRenderingFiber$1 = resolveCurrentlyRenderingFiber();
12194 workInProgressHook = createWorkInProgressHook();
12195
12196 var nextInputs = inputs !== undefined && inputs !== null ? inputs : [callback];
12197
12198 var prevState = workInProgressHook.memoizedState;
12199 if (prevState !== null) {
12200 var prevInputs = prevState[1];
12201 if (areHookInputsEqual(nextInputs, prevInputs)) {
12202 return prevState[0];
12203 }
12204 }
12205 workInProgressHook.memoizedState = [callback, nextInputs];
12206 return callback;
12207}
12208
12209function useMemo(nextCreate, inputs) {
12210 currentlyRenderingFiber$1 = resolveCurrentlyRenderingFiber();
12211 workInProgressHook = createWorkInProgressHook();
12212
12213 var nextInputs = inputs !== undefined && inputs !== null ? inputs : [nextCreate];
12214
12215 var prevState = workInProgressHook.memoizedState;
12216 if (prevState !== null) {
12217 var prevInputs = prevState[1];
12218 if (areHookInputsEqual(nextInputs, prevInputs)) {
12219 return prevState[0];
12220 }
12221 }
12222
12223 var nextValue = nextCreate();
12224 workInProgressHook.memoizedState = [nextValue, nextInputs];
12225 return nextValue;
12226}
12227
12228function dispatchAction(fiber, queue, action) {
12229 !(numberOfReRenders < RE_RENDER_LIMIT) ? invariant(false, 'Too many re-renders. React limits the number of renders to prevent an infinite loop.') : void 0;
12230
12231 var alternate = fiber.alternate;
12232 if (fiber === currentlyRenderingFiber$1 || alternate !== null && alternate === currentlyRenderingFiber$1) {
12233 // This is a render phase update. Stash it in a lazily-created map of
12234 // queue -> linked list of updates. After this render pass, we'll restart
12235 // and apply the stashed updates on top of the work-in-progress hook.
12236 didScheduleRenderPhaseUpdate = true;
12237 var update = {
12238 expirationTime: renderExpirationTime,
12239 action: action,
12240 next: null
12241 };
12242 if (renderPhaseUpdates === null) {
12243 renderPhaseUpdates = new Map();
12244 }
12245 var firstRenderPhaseUpdate = renderPhaseUpdates.get(queue);
12246 if (firstRenderPhaseUpdate === undefined) {
12247 renderPhaseUpdates.set(queue, update);
12248 } else {
12249 // Append the update to the end of the list.
12250 var lastRenderPhaseUpdate = firstRenderPhaseUpdate;
12251 while (lastRenderPhaseUpdate.next !== null) {
12252 lastRenderPhaseUpdate = lastRenderPhaseUpdate.next;
12253 }
12254 lastRenderPhaseUpdate.next = update;
12255 }
12256 } else {
12257 var currentTime = requestCurrentTime();
12258 var _expirationTime = computeExpirationForFiber(currentTime, fiber);
12259 var _update2 = {
12260 expirationTime: _expirationTime,
12261 action: action,
12262 next: null
12263 };
12264 flushPassiveEffects();
12265 // Append the update to the end of the list.
12266 var _last2 = queue.last;
12267 if (_last2 === null) {
12268 // This is the first update. Create a circular list.
12269 _update2.next = _update2;
12270 } else {
12271 var first = _last2.next;
12272 if (first !== null) {
12273 // Still circular.
12274 _update2.next = first;
12275 }
12276 _last2.next = _update2;
12277 }
12278 queue.last = _update2;
12279 scheduleWork(fiber, _expirationTime);
12280 }
12281}
12282
12283var NO_CONTEXT = {};
12284
12285var contextStackCursor$1 = createCursor(NO_CONTEXT);
12286var contextFiberStackCursor = createCursor(NO_CONTEXT);
12287var rootInstanceStackCursor = createCursor(NO_CONTEXT);
12288
12289function requiredContext(c) {
12290 !(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;
12291 return c;
12292}
12293
12294function getRootHostContainer() {
12295 var rootInstance = requiredContext(rootInstanceStackCursor.current);
12296 return rootInstance;
12297}
12298
12299function pushHostContainer(fiber, nextRootInstance) {
12300 // Push current root instance onto the stack;
12301 // This allows us to reset root when portals are popped.
12302 push(rootInstanceStackCursor, nextRootInstance, fiber);
12303 // Track the context and the Fiber that provided it.
12304 // This enables us to pop only Fibers that provide unique contexts.
12305 push(contextFiberStackCursor, fiber, fiber);
12306
12307 // Finally, we need to push the host context to the stack.
12308 // However, we can't just call getRootHostContext() and push it because
12309 // we'd have a different number of entries on the stack depending on
12310 // whether getRootHostContext() throws somewhere in renderer code or not.
12311 // So we push an empty value first. This lets us safely unwind on errors.
12312 push(contextStackCursor$1, NO_CONTEXT, fiber);
12313 var nextRootContext = getRootHostContext(nextRootInstance);
12314 // Now that we know this function doesn't throw, replace it.
12315 pop(contextStackCursor$1, fiber);
12316 push(contextStackCursor$1, nextRootContext, fiber);
12317}
12318
12319function popHostContainer(fiber) {
12320 pop(contextStackCursor$1, fiber);
12321 pop(contextFiberStackCursor, fiber);
12322 pop(rootInstanceStackCursor, fiber);
12323}
12324
12325function getHostContext() {
12326 var context = requiredContext(contextStackCursor$1.current);
12327 return context;
12328}
12329
12330function pushHostContext(fiber) {
12331 var rootInstance = requiredContext(rootInstanceStackCursor.current);
12332 var context = requiredContext(contextStackCursor$1.current);
12333 var nextContext = getChildHostContext(context, fiber.type, rootInstance);
12334
12335 // Don't push this Fiber's context unless it's unique.
12336 if (context === nextContext) {
12337 return;
12338 }
12339
12340 // Track the context and the Fiber that provided it.
12341 // This enables us to pop only Fibers that provide unique contexts.
12342 push(contextFiberStackCursor, fiber, fiber);
12343 push(contextStackCursor$1, nextContext, fiber);
12344}
12345
12346function popHostContext(fiber) {
12347 // Do not pop unless this Fiber provided the current context.
12348 // pushHostContext() only pushes Fibers that provide unique contexts.
12349 if (contextFiberStackCursor.current !== fiber) {
12350 return;
12351 }
12352
12353 pop(contextStackCursor$1, fiber);
12354 pop(contextFiberStackCursor, fiber);
12355}
12356
12357var commitTime = 0;
12358var profilerStartTime = -1;
12359
12360function getCommitTime() {
12361 return commitTime;
12362}
12363
12364function recordCommitTime() {
12365 if (!enableProfilerTimer) {
12366 return;
12367 }
12368 commitTime = unstable_now();
12369}
12370
12371function startProfilerTimer(fiber) {
12372 if (!enableProfilerTimer) {
12373 return;
12374 }
12375
12376 profilerStartTime = unstable_now();
12377
12378 if (fiber.actualStartTime < 0) {
12379 fiber.actualStartTime = unstable_now();
12380 }
12381}
12382
12383function stopProfilerTimerIfRunning(fiber) {
12384 if (!enableProfilerTimer) {
12385 return;
12386 }
12387 profilerStartTime = -1;
12388}
12389
12390function stopProfilerTimerIfRunningAndRecordDelta(fiber, overrideBaseTime) {
12391 if (!enableProfilerTimer) {
12392 return;
12393 }
12394
12395 if (profilerStartTime >= 0) {
12396 var elapsedTime = unstable_now() - profilerStartTime;
12397 fiber.actualDuration += elapsedTime;
12398 if (overrideBaseTime) {
12399 fiber.selfBaseDuration = elapsedTime;
12400 }
12401 profilerStartTime = -1;
12402 }
12403}
12404
12405function resolveDefaultProps(Component, baseProps) {
12406 if (Component && Component.defaultProps) {
12407 // Resolve default props. Taken from ReactElement
12408 var props = _assign({}, baseProps);
12409 var defaultProps = Component.defaultProps;
12410 for (var propName in defaultProps) {
12411 if (props[propName] === undefined) {
12412 props[propName] = defaultProps[propName];
12413 }
12414 }
12415 return props;
12416 }
12417 return baseProps;
12418}
12419
12420function readLazyComponentType(lazyComponent) {
12421 var status = lazyComponent._status;
12422 var result = lazyComponent._result;
12423 switch (status) {
12424 case Resolved:
12425 {
12426 var Component = result;
12427 return Component;
12428 }
12429 case Rejected:
12430 {
12431 var error = result;
12432 throw error;
12433 }
12434 case Pending:
12435 {
12436 var thenable = result;
12437 throw thenable;
12438 }
12439 default:
12440 {
12441 lazyComponent._status = Pending;
12442 var ctor = lazyComponent._ctor;
12443 var _thenable = ctor();
12444 _thenable.then(function (moduleObject) {
12445 if (lazyComponent._status === Pending) {
12446 var defaultExport = moduleObject.default;
12447 {
12448 if (defaultExport === undefined) {
12449 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);
12450 }
12451 }
12452 lazyComponent._status = Resolved;
12453 lazyComponent._result = defaultExport;
12454 }
12455 }, function (error) {
12456 if (lazyComponent._status === Pending) {
12457 lazyComponent._status = Rejected;
12458 lazyComponent._result = error;
12459 }
12460 });
12461 lazyComponent._result = _thenable;
12462 throw _thenable;
12463 }
12464 }
12465}
12466
12467var ReactCurrentOwner$4 = ReactSharedInternals.ReactCurrentOwner;
12468
12469function readContext$1(contextType) {
12470 var dispatcher = ReactCurrentOwner$4.currentDispatcher;
12471 return dispatcher.readContext(contextType);
12472}
12473
12474var fakeInternalInstance = {};
12475var isArray$1 = Array.isArray;
12476
12477// React.Component uses a shared frozen object by default.
12478// We'll use it to determine whether we need to initialize legacy refs.
12479var emptyRefsObject = new React.Component().refs;
12480
12481var didWarnAboutStateAssignmentForComponent = void 0;
12482var didWarnAboutUninitializedState = void 0;
12483var didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate = void 0;
12484var didWarnAboutLegacyLifecyclesAndDerivedState = void 0;
12485var didWarnAboutUndefinedDerivedState = void 0;
12486var warnOnUndefinedDerivedState = void 0;
12487var warnOnInvalidCallback$1 = void 0;
12488var didWarnAboutDirectlyAssigningPropsToState = void 0;
12489var didWarnAboutContextTypeAndContextTypes = void 0;
12490var didWarnAboutInvalidateContextType = void 0;
12491
12492{
12493 didWarnAboutStateAssignmentForComponent = new Set();
12494 didWarnAboutUninitializedState = new Set();
12495 didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate = new Set();
12496 didWarnAboutLegacyLifecyclesAndDerivedState = new Set();
12497 didWarnAboutDirectlyAssigningPropsToState = new Set();
12498 didWarnAboutUndefinedDerivedState = new Set();
12499 didWarnAboutContextTypeAndContextTypes = new Set();
12500 didWarnAboutInvalidateContextType = new Set();
12501
12502 var didWarnOnInvalidCallback = new Set();
12503
12504 warnOnInvalidCallback$1 = function (callback, callerName) {
12505 if (callback === null || typeof callback === 'function') {
12506 return;
12507 }
12508 var key = callerName + '_' + callback;
12509 if (!didWarnOnInvalidCallback.has(key)) {
12510 didWarnOnInvalidCallback.add(key);
12511 warningWithoutStack$1(false, '%s(...): Expected the last optional `callback` argument to be a ' + 'function. Instead received: %s.', callerName, callback);
12512 }
12513 };
12514
12515 warnOnUndefinedDerivedState = function (type, partialState) {
12516 if (partialState === undefined) {
12517 var componentName = getComponentName(type) || 'Component';
12518 if (!didWarnAboutUndefinedDerivedState.has(componentName)) {
12519 didWarnAboutUndefinedDerivedState.add(componentName);
12520 warningWithoutStack$1(false, '%s.getDerivedStateFromProps(): A valid state object (or null) must be returned. ' + 'You have returned undefined.', componentName);
12521 }
12522 }
12523 };
12524
12525 // This is so gross but it's at least non-critical and can be removed if
12526 // it causes problems. This is meant to give a nicer error message for
12527 // ReactDOM15.unstable_renderSubtreeIntoContainer(reactDOM16Component,
12528 // ...)) which otherwise throws a "_processChildContext is not a function"
12529 // exception.
12530 Object.defineProperty(fakeInternalInstance, '_processChildContext', {
12531 enumerable: false,
12532 value: function () {
12533 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).');
12534 }
12535 });
12536 Object.freeze(fakeInternalInstance);
12537}
12538
12539function applyDerivedStateFromProps(workInProgress, ctor, getDerivedStateFromProps, nextProps) {
12540 var prevState = workInProgress.memoizedState;
12541
12542 {
12543 if (debugRenderPhaseSideEffects || debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) {
12544 // Invoke the function an extra time to help detect side-effects.
12545 getDerivedStateFromProps(nextProps, prevState);
12546 }
12547 }
12548
12549 var partialState = getDerivedStateFromProps(nextProps, prevState);
12550
12551 {
12552 warnOnUndefinedDerivedState(ctor, partialState);
12553 }
12554 // Merge the partial state and the previous state.
12555 var memoizedState = partialState === null || partialState === undefined ? prevState : _assign({}, prevState, partialState);
12556 workInProgress.memoizedState = memoizedState;
12557
12558 // Once the update queue is empty, persist the derived state onto the
12559 // base state.
12560 var updateQueue = workInProgress.updateQueue;
12561 if (updateQueue !== null && workInProgress.expirationTime === NoWork) {
12562 updateQueue.baseState = memoizedState;
12563 }
12564}
12565
12566var classComponentUpdater = {
12567 isMounted: isMounted,
12568 enqueueSetState: function (inst, payload, callback) {
12569 var fiber = get(inst);
12570 var currentTime = requestCurrentTime();
12571 var expirationTime = computeExpirationForFiber(currentTime, fiber);
12572
12573 var update = createUpdate(expirationTime);
12574 update.payload = payload;
12575 if (callback !== undefined && callback !== null) {
12576 {
12577 warnOnInvalidCallback$1(callback, 'setState');
12578 }
12579 update.callback = callback;
12580 }
12581
12582 flushPassiveEffects();
12583 enqueueUpdate(fiber, update);
12584 scheduleWork(fiber, expirationTime);
12585 },
12586 enqueueReplaceState: function (inst, payload, callback) {
12587 var fiber = get(inst);
12588 var currentTime = requestCurrentTime();
12589 var expirationTime = computeExpirationForFiber(currentTime, fiber);
12590
12591 var update = createUpdate(expirationTime);
12592 update.tag = ReplaceState;
12593 update.payload = payload;
12594
12595 if (callback !== undefined && callback !== null) {
12596 {
12597 warnOnInvalidCallback$1(callback, 'replaceState');
12598 }
12599 update.callback = callback;
12600 }
12601
12602 flushPassiveEffects();
12603 enqueueUpdate(fiber, update);
12604 scheduleWork(fiber, expirationTime);
12605 },
12606 enqueueForceUpdate: function (inst, callback) {
12607 var fiber = get(inst);
12608 var currentTime = requestCurrentTime();
12609 var expirationTime = computeExpirationForFiber(currentTime, fiber);
12610
12611 var update = createUpdate(expirationTime);
12612 update.tag = ForceUpdate;
12613
12614 if (callback !== undefined && callback !== null) {
12615 {
12616 warnOnInvalidCallback$1(callback, 'forceUpdate');
12617 }
12618 update.callback = callback;
12619 }
12620
12621 flushPassiveEffects();
12622 enqueueUpdate(fiber, update);
12623 scheduleWork(fiber, expirationTime);
12624 }
12625};
12626
12627function checkShouldComponentUpdate(workInProgress, ctor, oldProps, newProps, oldState, newState, nextContext) {
12628 var instance = workInProgress.stateNode;
12629 if (typeof instance.shouldComponentUpdate === 'function') {
12630 startPhaseTimer(workInProgress, 'shouldComponentUpdate');
12631 var shouldUpdate = instance.shouldComponentUpdate(newProps, newState, nextContext);
12632 stopPhaseTimer();
12633
12634 {
12635 !(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;
12636 }
12637
12638 return shouldUpdate;
12639 }
12640
12641 if (ctor.prototype && ctor.prototype.isPureReactComponent) {
12642 return !shallowEqual(oldProps, newProps) || !shallowEqual(oldState, newState);
12643 }
12644
12645 return true;
12646}
12647
12648function checkClassInstance(workInProgress, ctor, newProps) {
12649 var instance = workInProgress.stateNode;
12650 {
12651 var name = getComponentName(ctor) || 'Component';
12652 var renderPresent = instance.render;
12653
12654 if (!renderPresent) {
12655 if (ctor.prototype && typeof ctor.prototype.render === 'function') {
12656 warningWithoutStack$1(false, '%s(...): No `render` method found on the returned component ' + 'instance: did you accidentally return an object from the constructor?', name);
12657 } else {
12658 warningWithoutStack$1(false, '%s(...): No `render` method found on the returned component ' + 'instance: you may have forgotten to define `render`.', name);
12659 }
12660 }
12661
12662 var noGetInitialStateOnES6 = !instance.getInitialState || instance.getInitialState.isReactClassApproved || instance.state;
12663 !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;
12664 var noGetDefaultPropsOnES6 = !instance.getDefaultProps || instance.getDefaultProps.isReactClassApproved;
12665 !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;
12666 var noInstancePropTypes = !instance.propTypes;
12667 !noInstancePropTypes ? warningWithoutStack$1(false, 'propTypes was defined as an instance property on %s. Use a static ' + 'property to define propTypes instead.', name) : void 0;
12668 var noInstanceContextType = !instance.contextType;
12669 !noInstanceContextType ? warningWithoutStack$1(false, 'contextType was defined as an instance property on %s. Use a static ' + 'property to define contextType instead.', name) : void 0;
12670 var noInstanceContextTypes = !instance.contextTypes;
12671 !noInstanceContextTypes ? warningWithoutStack$1(false, 'contextTypes was defined as an instance property on %s. Use a static ' + 'property to define contextTypes instead.', name) : void 0;
12672
12673 if (ctor.contextType && ctor.contextTypes && !didWarnAboutContextTypeAndContextTypes.has(ctor)) {
12674 didWarnAboutContextTypeAndContextTypes.add(ctor);
12675 warningWithoutStack$1(false, '%s declares both contextTypes and contextType static properties. ' + 'The legacy contextTypes property will be ignored.', name);
12676 }
12677
12678 var noComponentShouldUpdate = typeof instance.componentShouldUpdate !== 'function';
12679 !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;
12680 if (ctor.prototype && ctor.prototype.isPureReactComponent && typeof instance.shouldComponentUpdate !== 'undefined') {
12681 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');
12682 }
12683 var noComponentDidUnmount = typeof instance.componentDidUnmount !== 'function';
12684 !noComponentDidUnmount ? warningWithoutStack$1(false, '%s has a method called ' + 'componentDidUnmount(). But there is no such lifecycle method. ' + 'Did you mean componentWillUnmount()?', name) : void 0;
12685 var noComponentDidReceiveProps = typeof instance.componentDidReceiveProps !== 'function';
12686 !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;
12687 var noComponentWillRecieveProps = typeof instance.componentWillRecieveProps !== 'function';
12688 !noComponentWillRecieveProps ? warningWithoutStack$1(false, '%s has a method called ' + 'componentWillRecieveProps(). Did you mean componentWillReceiveProps()?', name) : void 0;
12689 var noUnsafeComponentWillRecieveProps = typeof instance.UNSAFE_componentWillRecieveProps !== 'function';
12690 !noUnsafeComponentWillRecieveProps ? warningWithoutStack$1(false, '%s has a method called ' + 'UNSAFE_componentWillRecieveProps(). Did you mean UNSAFE_componentWillReceiveProps()?', name) : void 0;
12691 var hasMutatedProps = instance.props !== newProps;
12692 !(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;
12693 var noInstanceDefaultProps = !instance.defaultProps;
12694 !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;
12695
12696 if (typeof instance.getSnapshotBeforeUpdate === 'function' && typeof instance.componentDidUpdate !== 'function' && !didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate.has(ctor)) {
12697 didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate.add(ctor);
12698 warningWithoutStack$1(false, '%s: getSnapshotBeforeUpdate() should be used with componentDidUpdate(). ' + 'This component defines getSnapshotBeforeUpdate() only.', getComponentName(ctor));
12699 }
12700
12701 var noInstanceGetDerivedStateFromProps = typeof instance.getDerivedStateFromProps !== 'function';
12702 !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;
12703 var noInstanceGetDerivedStateFromCatch = typeof instance.getDerivedStateFromError !== 'function';
12704 !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;
12705 var noStaticGetSnapshotBeforeUpdate = typeof ctor.getSnapshotBeforeUpdate !== 'function';
12706 !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;
12707 var _state = instance.state;
12708 if (_state && (typeof _state !== 'object' || isArray$1(_state))) {
12709 warningWithoutStack$1(false, '%s.state: must be set to an object or null', name);
12710 }
12711 if (typeof instance.getChildContext === 'function') {
12712 !(typeof ctor.childContextTypes === 'object') ? warningWithoutStack$1(false, '%s.getChildContext(): childContextTypes must be defined in order to ' + 'use getChildContext().', name) : void 0;
12713 }
12714 }
12715}
12716
12717function adoptClassInstance(workInProgress, instance) {
12718 instance.updater = classComponentUpdater;
12719 workInProgress.stateNode = instance;
12720 // The instance needs access to the fiber so that it can schedule updates
12721 set(instance, workInProgress);
12722 {
12723 instance._reactInternalInstance = fakeInternalInstance;
12724 }
12725}
12726
12727function constructClassInstance(workInProgress, ctor, props, renderExpirationTime) {
12728 var isLegacyContextConsumer = false;
12729 var unmaskedContext = emptyContextObject;
12730 var context = null;
12731 var contextType = ctor.contextType;
12732 if (typeof contextType === 'object' && contextType !== null) {
12733 {
12734 if (contextType.$$typeof !== REACT_CONTEXT_TYPE && !didWarnAboutInvalidateContextType.has(ctor)) {
12735 didWarnAboutInvalidateContextType.add(ctor);
12736 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');
12737 }
12738 }
12739
12740 context = readContext$1(contextType);
12741 } else {
12742 unmaskedContext = getUnmaskedContext(workInProgress, ctor, true);
12743 var contextTypes = ctor.contextTypes;
12744 isLegacyContextConsumer = contextTypes !== null && contextTypes !== undefined;
12745 context = isLegacyContextConsumer ? getMaskedContext(workInProgress, unmaskedContext) : emptyContextObject;
12746 }
12747
12748 // Instantiate twice to help detect side-effects.
12749 {
12750 if (debugRenderPhaseSideEffects || debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) {
12751 new ctor(props, context); // eslint-disable-line no-new
12752 }
12753 }
12754
12755 var instance = new ctor(props, context);
12756 var state = workInProgress.memoizedState = instance.state !== null && instance.state !== undefined ? instance.state : null;
12757 adoptClassInstance(workInProgress, instance);
12758
12759 {
12760 if (typeof ctor.getDerivedStateFromProps === 'function' && state === null) {
12761 var componentName = getComponentName(ctor) || 'Component';
12762 if (!didWarnAboutUninitializedState.has(componentName)) {
12763 didWarnAboutUninitializedState.add(componentName);
12764 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);
12765 }
12766 }
12767
12768 // If new component APIs are defined, "unsafe" lifecycles won't be called.
12769 // Warn about these lifecycles if they are present.
12770 // Don't warn about react-lifecycles-compat polyfilled methods though.
12771 if (typeof ctor.getDerivedStateFromProps === 'function' || typeof instance.getSnapshotBeforeUpdate === 'function') {
12772 var foundWillMountName = null;
12773 var foundWillReceivePropsName = null;
12774 var foundWillUpdateName = null;
12775 if (typeof instance.componentWillMount === 'function' && instance.componentWillMount.__suppressDeprecationWarning !== true) {
12776 foundWillMountName = 'componentWillMount';
12777 } else if (typeof instance.UNSAFE_componentWillMount === 'function') {
12778 foundWillMountName = 'UNSAFE_componentWillMount';
12779 }
12780 if (typeof instance.componentWillReceiveProps === 'function' && instance.componentWillReceiveProps.__suppressDeprecationWarning !== true) {
12781 foundWillReceivePropsName = 'componentWillReceiveProps';
12782 } else if (typeof instance.UNSAFE_componentWillReceiveProps === 'function') {
12783 foundWillReceivePropsName = 'UNSAFE_componentWillReceiveProps';
12784 }
12785 if (typeof instance.componentWillUpdate === 'function' && instance.componentWillUpdate.__suppressDeprecationWarning !== true) {
12786 foundWillUpdateName = 'componentWillUpdate';
12787 } else if (typeof instance.UNSAFE_componentWillUpdate === 'function') {
12788 foundWillUpdateName = 'UNSAFE_componentWillUpdate';
12789 }
12790 if (foundWillMountName !== null || foundWillReceivePropsName !== null || foundWillUpdateName !== null) {
12791 var _componentName = getComponentName(ctor) || 'Component';
12792 var newApiName = typeof ctor.getDerivedStateFromProps === 'function' ? 'getDerivedStateFromProps()' : 'getSnapshotBeforeUpdate()';
12793 if (!didWarnAboutLegacyLifecyclesAndDerivedState.has(_componentName)) {
12794 didWarnAboutLegacyLifecyclesAndDerivedState.add(_componentName);
12795 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 : '');
12796 }
12797 }
12798 }
12799 }
12800
12801 // Cache unmasked context so we can avoid recreating masked context unless necessary.
12802 // ReactFiberContext usually updates this cache but can't for newly-created instances.
12803 if (isLegacyContextConsumer) {
12804 cacheContext(workInProgress, unmaskedContext, context);
12805 }
12806
12807 return instance;
12808}
12809
12810function callComponentWillMount(workInProgress, instance) {
12811 startPhaseTimer(workInProgress, 'componentWillMount');
12812 var oldState = instance.state;
12813
12814 if (typeof instance.componentWillMount === 'function') {
12815 instance.componentWillMount();
12816 }
12817 if (typeof instance.UNSAFE_componentWillMount === 'function') {
12818 instance.UNSAFE_componentWillMount();
12819 }
12820
12821 stopPhaseTimer();
12822
12823 if (oldState !== instance.state) {
12824 {
12825 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');
12826 }
12827 classComponentUpdater.enqueueReplaceState(instance, instance.state, null);
12828 }
12829}
12830
12831function callComponentWillReceiveProps(workInProgress, instance, newProps, nextContext) {
12832 var oldState = instance.state;
12833 startPhaseTimer(workInProgress, 'componentWillReceiveProps');
12834 if (typeof instance.componentWillReceiveProps === 'function') {
12835 instance.componentWillReceiveProps(newProps, nextContext);
12836 }
12837 if (typeof instance.UNSAFE_componentWillReceiveProps === 'function') {
12838 instance.UNSAFE_componentWillReceiveProps(newProps, nextContext);
12839 }
12840 stopPhaseTimer();
12841
12842 if (instance.state !== oldState) {
12843 {
12844 var componentName = getComponentName(workInProgress.type) || 'Component';
12845 if (!didWarnAboutStateAssignmentForComponent.has(componentName)) {
12846 didWarnAboutStateAssignmentForComponent.add(componentName);
12847 warningWithoutStack$1(false, '%s.componentWillReceiveProps(): Assigning directly to ' + "this.state is deprecated (except inside a component's " + 'constructor). Use setState instead.', componentName);
12848 }
12849 }
12850 classComponentUpdater.enqueueReplaceState(instance, instance.state, null);
12851 }
12852}
12853
12854// Invokes the mount life-cycles on a previously never rendered instance.
12855function mountClassInstance(workInProgress, ctor, newProps, renderExpirationTime) {
12856 {
12857 checkClassInstance(workInProgress, ctor, newProps);
12858 }
12859
12860 var instance = workInProgress.stateNode;
12861 instance.props = newProps;
12862 instance.state = workInProgress.memoizedState;
12863 instance.refs = emptyRefsObject;
12864
12865 var contextType = ctor.contextType;
12866 if (typeof contextType === 'object' && contextType !== null) {
12867 instance.context = readContext$1(contextType);
12868 } else {
12869 var unmaskedContext = getUnmaskedContext(workInProgress, ctor, true);
12870 instance.context = getMaskedContext(workInProgress, unmaskedContext);
12871 }
12872
12873 {
12874 if (instance.state === newProps) {
12875 var componentName = getComponentName(ctor) || 'Component';
12876 if (!didWarnAboutDirectlyAssigningPropsToState.has(componentName)) {
12877 didWarnAboutDirectlyAssigningPropsToState.add(componentName);
12878 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);
12879 }
12880 }
12881
12882 if (workInProgress.mode & StrictMode) {
12883 ReactStrictModeWarnings.recordUnsafeLifecycleWarnings(workInProgress, instance);
12884
12885 ReactStrictModeWarnings.recordLegacyContextWarning(workInProgress, instance);
12886 }
12887
12888 if (warnAboutDeprecatedLifecycles) {
12889 ReactStrictModeWarnings.recordDeprecationWarnings(workInProgress, instance);
12890 }
12891 }
12892
12893 var updateQueue = workInProgress.updateQueue;
12894 if (updateQueue !== null) {
12895 processUpdateQueue(workInProgress, updateQueue, newProps, instance, renderExpirationTime);
12896 instance.state = workInProgress.memoizedState;
12897 }
12898
12899 var getDerivedStateFromProps = ctor.getDerivedStateFromProps;
12900 if (typeof getDerivedStateFromProps === 'function') {
12901 applyDerivedStateFromProps(workInProgress, ctor, getDerivedStateFromProps, newProps);
12902 instance.state = workInProgress.memoizedState;
12903 }
12904
12905 // In order to support react-lifecycles-compat polyfilled components,
12906 // Unsafe lifecycles should not be invoked for components using the new APIs.
12907 if (typeof ctor.getDerivedStateFromProps !== 'function' && typeof instance.getSnapshotBeforeUpdate !== 'function' && (typeof instance.UNSAFE_componentWillMount === 'function' || typeof instance.componentWillMount === 'function')) {
12908 callComponentWillMount(workInProgress, instance);
12909 // If we had additional state updates during this life-cycle, let's
12910 // process them now.
12911 updateQueue = workInProgress.updateQueue;
12912 if (updateQueue !== null) {
12913 processUpdateQueue(workInProgress, updateQueue, newProps, instance, renderExpirationTime);
12914 instance.state = workInProgress.memoizedState;
12915 }
12916 }
12917
12918 if (typeof instance.componentDidMount === 'function') {
12919 workInProgress.effectTag |= Update;
12920 }
12921}
12922
12923function resumeMountClassInstance(workInProgress, ctor, newProps, renderExpirationTime) {
12924 var instance = workInProgress.stateNode;
12925
12926 var oldProps = workInProgress.memoizedProps;
12927 instance.props = oldProps;
12928
12929 var oldContext = instance.context;
12930 var contextType = ctor.contextType;
12931 var nextContext = void 0;
12932 if (typeof contextType === 'object' && contextType !== null) {
12933 nextContext = readContext$1(contextType);
12934 } else {
12935 var nextLegacyUnmaskedContext = getUnmaskedContext(workInProgress, ctor, true);
12936 nextContext = getMaskedContext(workInProgress, nextLegacyUnmaskedContext);
12937 }
12938
12939 var getDerivedStateFromProps = ctor.getDerivedStateFromProps;
12940 var hasNewLifecycles = typeof getDerivedStateFromProps === 'function' || typeof instance.getSnapshotBeforeUpdate === 'function';
12941
12942 // Note: During these life-cycles, instance.props/instance.state are what
12943 // ever the previously attempted to render - not the "current". However,
12944 // during componentDidUpdate we pass the "current" props.
12945
12946 // In order to support react-lifecycles-compat polyfilled components,
12947 // Unsafe lifecycles should not be invoked for components using the new APIs.
12948 if (!hasNewLifecycles && (typeof instance.UNSAFE_componentWillReceiveProps === 'function' || typeof instance.componentWillReceiveProps === 'function')) {
12949 if (oldProps !== newProps || oldContext !== nextContext) {
12950 callComponentWillReceiveProps(workInProgress, instance, newProps, nextContext);
12951 }
12952 }
12953
12954 resetHasForceUpdateBeforeProcessing();
12955
12956 var oldState = workInProgress.memoizedState;
12957 var newState = instance.state = oldState;
12958 var updateQueue = workInProgress.updateQueue;
12959 if (updateQueue !== null) {
12960 processUpdateQueue(workInProgress, updateQueue, newProps, instance, renderExpirationTime);
12961 newState = workInProgress.memoizedState;
12962 }
12963 if (oldProps === newProps && oldState === newState && !hasContextChanged() && !checkHasForceUpdateAfterProcessing()) {
12964 // If an update was already in progress, we should schedule an Update
12965 // effect even though we're bailing out, so that cWU/cDU are called.
12966 if (typeof instance.componentDidMount === 'function') {
12967 workInProgress.effectTag |= Update;
12968 }
12969 return false;
12970 }
12971
12972 if (typeof getDerivedStateFromProps === 'function') {
12973 applyDerivedStateFromProps(workInProgress, ctor, getDerivedStateFromProps, newProps);
12974 newState = workInProgress.memoizedState;
12975 }
12976
12977 var shouldUpdate = checkHasForceUpdateAfterProcessing() || checkShouldComponentUpdate(workInProgress, ctor, oldProps, newProps, oldState, newState, nextContext);
12978
12979 if (shouldUpdate) {
12980 // In order to support react-lifecycles-compat polyfilled components,
12981 // Unsafe lifecycles should not be invoked for components using the new APIs.
12982 if (!hasNewLifecycles && (typeof instance.UNSAFE_componentWillMount === 'function' || typeof instance.componentWillMount === 'function')) {
12983 startPhaseTimer(workInProgress, 'componentWillMount');
12984 if (typeof instance.componentWillMount === 'function') {
12985 instance.componentWillMount();
12986 }
12987 if (typeof instance.UNSAFE_componentWillMount === 'function') {
12988 instance.UNSAFE_componentWillMount();
12989 }
12990 stopPhaseTimer();
12991 }
12992 if (typeof instance.componentDidMount === 'function') {
12993 workInProgress.effectTag |= Update;
12994 }
12995 } else {
12996 // If an update was already in progress, we should schedule an Update
12997 // effect even though we're bailing out, so that cWU/cDU are called.
12998 if (typeof instance.componentDidMount === 'function') {
12999 workInProgress.effectTag |= Update;
13000 }
13001
13002 // If shouldComponentUpdate returned false, we should still update the
13003 // memoized state to indicate that this work can be reused.
13004 workInProgress.memoizedProps = newProps;
13005 workInProgress.memoizedState = newState;
13006 }
13007
13008 // Update the existing instance's state, props, and context pointers even
13009 // if shouldComponentUpdate returns false.
13010 instance.props = newProps;
13011 instance.state = newState;
13012 instance.context = nextContext;
13013
13014 return shouldUpdate;
13015}
13016
13017// Invokes the update life-cycles and returns false if it shouldn't rerender.
13018function updateClassInstance(current, workInProgress, ctor, newProps, renderExpirationTime) {
13019 var instance = workInProgress.stateNode;
13020
13021 var oldProps = workInProgress.memoizedProps;
13022 instance.props = workInProgress.type === workInProgress.elementType ? oldProps : resolveDefaultProps(workInProgress.type, oldProps);
13023
13024 var oldContext = instance.context;
13025 var contextType = ctor.contextType;
13026 var nextContext = void 0;
13027 if (typeof contextType === 'object' && contextType !== null) {
13028 nextContext = readContext$1(contextType);
13029 } else {
13030 var nextUnmaskedContext = getUnmaskedContext(workInProgress, ctor, true);
13031 nextContext = getMaskedContext(workInProgress, nextUnmaskedContext);
13032 }
13033
13034 var getDerivedStateFromProps = ctor.getDerivedStateFromProps;
13035 var hasNewLifecycles = typeof getDerivedStateFromProps === 'function' || typeof instance.getSnapshotBeforeUpdate === 'function';
13036
13037 // Note: During these life-cycles, instance.props/instance.state are what
13038 // ever the previously attempted to render - not the "current". However,
13039 // during componentDidUpdate we pass the "current" props.
13040
13041 // In order to support react-lifecycles-compat polyfilled components,
13042 // Unsafe lifecycles should not be invoked for components using the new APIs.
13043 if (!hasNewLifecycles && (typeof instance.UNSAFE_componentWillReceiveProps === 'function' || typeof instance.componentWillReceiveProps === 'function')) {
13044 if (oldProps !== newProps || oldContext !== nextContext) {
13045 callComponentWillReceiveProps(workInProgress, instance, newProps, nextContext);
13046 }
13047 }
13048
13049 resetHasForceUpdateBeforeProcessing();
13050
13051 var oldState = workInProgress.memoizedState;
13052 var newState = instance.state = oldState;
13053 var updateQueue = workInProgress.updateQueue;
13054 if (updateQueue !== null) {
13055 processUpdateQueue(workInProgress, updateQueue, newProps, instance, renderExpirationTime);
13056 newState = workInProgress.memoizedState;
13057 }
13058
13059 if (oldProps === newProps && oldState === newState && !hasContextChanged() && !checkHasForceUpdateAfterProcessing()) {
13060 // If an update was already in progress, we should schedule an Update
13061 // effect even though we're bailing out, so that cWU/cDU are called.
13062 if (typeof instance.componentDidUpdate === 'function') {
13063 if (oldProps !== current.memoizedProps || oldState !== current.memoizedState) {
13064 workInProgress.effectTag |= Update;
13065 }
13066 }
13067 if (typeof instance.getSnapshotBeforeUpdate === 'function') {
13068 if (oldProps !== current.memoizedProps || oldState !== current.memoizedState) {
13069 workInProgress.effectTag |= Snapshot;
13070 }
13071 }
13072 return false;
13073 }
13074
13075 if (typeof getDerivedStateFromProps === 'function') {
13076 applyDerivedStateFromProps(workInProgress, ctor, getDerivedStateFromProps, newProps);
13077 newState = workInProgress.memoizedState;
13078 }
13079
13080 var shouldUpdate = checkHasForceUpdateAfterProcessing() || checkShouldComponentUpdate(workInProgress, ctor, oldProps, newProps, oldState, newState, nextContext);
13081
13082 if (shouldUpdate) {
13083 // In order to support react-lifecycles-compat polyfilled components,
13084 // Unsafe lifecycles should not be invoked for components using the new APIs.
13085 if (!hasNewLifecycles && (typeof instance.UNSAFE_componentWillUpdate === 'function' || typeof instance.componentWillUpdate === 'function')) {
13086 startPhaseTimer(workInProgress, 'componentWillUpdate');
13087 if (typeof instance.componentWillUpdate === 'function') {
13088 instance.componentWillUpdate(newProps, newState, nextContext);
13089 }
13090 if (typeof instance.UNSAFE_componentWillUpdate === 'function') {
13091 instance.UNSAFE_componentWillUpdate(newProps, newState, nextContext);
13092 }
13093 stopPhaseTimer();
13094 }
13095 if (typeof instance.componentDidUpdate === 'function') {
13096 workInProgress.effectTag |= Update;
13097 }
13098 if (typeof instance.getSnapshotBeforeUpdate === 'function') {
13099 workInProgress.effectTag |= Snapshot;
13100 }
13101 } else {
13102 // If an update was already in progress, we should schedule an Update
13103 // effect even though we're bailing out, so that cWU/cDU are called.
13104 if (typeof instance.componentDidUpdate === 'function') {
13105 if (oldProps !== current.memoizedProps || oldState !== current.memoizedState) {
13106 workInProgress.effectTag |= Update;
13107 }
13108 }
13109 if (typeof instance.getSnapshotBeforeUpdate === 'function') {
13110 if (oldProps !== current.memoizedProps || oldState !== current.memoizedState) {
13111 workInProgress.effectTag |= Snapshot;
13112 }
13113 }
13114
13115 // If shouldComponentUpdate returned false, we should still update the
13116 // memoized props/state to indicate that this work can be reused.
13117 workInProgress.memoizedProps = newProps;
13118 workInProgress.memoizedState = newState;
13119 }
13120
13121 // Update the existing instance's state, props, and context pointers even
13122 // if shouldComponentUpdate returns false.
13123 instance.props = newProps;
13124 instance.state = newState;
13125 instance.context = nextContext;
13126
13127 return shouldUpdate;
13128}
13129
13130var didWarnAboutMaps = void 0;
13131var didWarnAboutGenerators = void 0;
13132var didWarnAboutStringRefInStrictMode = void 0;
13133var ownerHasKeyUseWarning = void 0;
13134var ownerHasFunctionTypeWarning = void 0;
13135var warnForMissingKey = function (child) {};
13136
13137{
13138 didWarnAboutMaps = false;
13139 didWarnAboutGenerators = false;
13140 didWarnAboutStringRefInStrictMode = {};
13141
13142 /**
13143 * Warn if there's no key explicitly set on dynamic arrays of children or
13144 * object keys are not valid. This allows us to keep track of children between
13145 * updates.
13146 */
13147 ownerHasKeyUseWarning = {};
13148 ownerHasFunctionTypeWarning = {};
13149
13150 warnForMissingKey = function (child) {
13151 if (child === null || typeof child !== 'object') {
13152 return;
13153 }
13154 if (!child._store || child._store.validated || child.key != null) {
13155 return;
13156 }
13157 !(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;
13158 child._store.validated = true;
13159
13160 var currentComponentErrorInfo = 'Each child in an array or iterator should have a unique ' + '"key" prop. See https://fb.me/react-warning-keys for ' + 'more information.' + getCurrentFiberStackInDev();
13161 if (ownerHasKeyUseWarning[currentComponentErrorInfo]) {
13162 return;
13163 }
13164 ownerHasKeyUseWarning[currentComponentErrorInfo] = true;
13165
13166 warning$1(false, 'Each child in an array or iterator should have a unique ' + '"key" prop. See https://fb.me/react-warning-keys for ' + 'more information.');
13167 };
13168}
13169
13170var isArray = Array.isArray;
13171
13172function coerceRef(returnFiber, current$$1, element) {
13173 var mixedRef = element.ref;
13174 if (mixedRef !== null && typeof mixedRef !== 'function' && typeof mixedRef !== 'object') {
13175 {
13176 if (returnFiber.mode & StrictMode) {
13177 var componentName = getComponentName(returnFiber.type) || 'Component';
13178 if (!didWarnAboutStringRefInStrictMode[componentName]) {
13179 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));
13180 didWarnAboutStringRefInStrictMode[componentName] = true;
13181 }
13182 }
13183 }
13184
13185 if (element._owner) {
13186 var owner = element._owner;
13187 var inst = void 0;
13188 if (owner) {
13189 var ownerFiber = owner;
13190 !(ownerFiber.tag === ClassComponent) ? invariant(false, 'Function components cannot have refs.') : void 0;
13191 inst = ownerFiber.stateNode;
13192 }
13193 !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;
13194 var stringRef = '' + mixedRef;
13195 // Check if previous string ref matches new string ref
13196 if (current$$1 !== null && current$$1.ref !== null && typeof current$$1.ref === 'function' && current$$1.ref._stringRef === stringRef) {
13197 return current$$1.ref;
13198 }
13199 var ref = function (value) {
13200 var refs = inst.refs;
13201 if (refs === emptyRefsObject) {
13202 // This is a lazy pooled frozen object, so we need to initialize.
13203 refs = inst.refs = {};
13204 }
13205 if (value === null) {
13206 delete refs[stringRef];
13207 } else {
13208 refs[stringRef] = value;
13209 }
13210 };
13211 ref._stringRef = stringRef;
13212 return ref;
13213 } else {
13214 !(typeof mixedRef === 'string') ? invariant(false, 'Expected ref to be a function, a string, an object returned by React.createRef(), or null.') : void 0;
13215 !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;
13216 }
13217 }
13218 return mixedRef;
13219}
13220
13221function throwOnInvalidObjectType(returnFiber, newChild) {
13222 if (returnFiber.type !== 'textarea') {
13223 var addendum = '';
13224 {
13225 addendum = ' If you meant to render a collection of children, use an array ' + 'instead.' + getCurrentFiberStackInDev();
13226 }
13227 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);
13228 }
13229}
13230
13231function warnOnFunctionType() {
13232 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();
13233
13234 if (ownerHasFunctionTypeWarning[currentComponentErrorInfo]) {
13235 return;
13236 }
13237 ownerHasFunctionTypeWarning[currentComponentErrorInfo] = true;
13238
13239 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.');
13240}
13241
13242// This wrapper function exists because I expect to clone the code in each path
13243// to be able to optimize each path individually by branching early. This needs
13244// a compiler or we can do it manually. Helpers that don't need this branching
13245// live outside of this function.
13246function ChildReconciler(shouldTrackSideEffects) {
13247 function deleteChild(returnFiber, childToDelete) {
13248 if (!shouldTrackSideEffects) {
13249 // Noop.
13250 return;
13251 }
13252 // Deletions are added in reversed order so we add it to the front.
13253 // At this point, the return fiber's effect list is empty except for
13254 // deletions, so we can just append the deletion to the list. The remaining
13255 // effects aren't added until the complete phase. Once we implement
13256 // resuming, this may not be true.
13257 var last = returnFiber.lastEffect;
13258 if (last !== null) {
13259 last.nextEffect = childToDelete;
13260 returnFiber.lastEffect = childToDelete;
13261 } else {
13262 returnFiber.firstEffect = returnFiber.lastEffect = childToDelete;
13263 }
13264 childToDelete.nextEffect = null;
13265 childToDelete.effectTag = Deletion;
13266 }
13267
13268 function deleteRemainingChildren(returnFiber, currentFirstChild) {
13269 if (!shouldTrackSideEffects) {
13270 // Noop.
13271 return null;
13272 }
13273
13274 // TODO: For the shouldClone case, this could be micro-optimized a bit by
13275 // assuming that after the first child we've already added everything.
13276 var childToDelete = currentFirstChild;
13277 while (childToDelete !== null) {
13278 deleteChild(returnFiber, childToDelete);
13279 childToDelete = childToDelete.sibling;
13280 }
13281 return null;
13282 }
13283
13284 function mapRemainingChildren(returnFiber, currentFirstChild) {
13285 // Add the remaining children to a temporary map so that we can find them by
13286 // keys quickly. Implicit (null) keys get added to this set with their index
13287 var existingChildren = new Map();
13288
13289 var existingChild = currentFirstChild;
13290 while (existingChild !== null) {
13291 if (existingChild.key !== null) {
13292 existingChildren.set(existingChild.key, existingChild);
13293 } else {
13294 existingChildren.set(existingChild.index, existingChild);
13295 }
13296 existingChild = existingChild.sibling;
13297 }
13298 return existingChildren;
13299 }
13300
13301 function useFiber(fiber, pendingProps, expirationTime) {
13302 // We currently set sibling to null and index to 0 here because it is easy
13303 // to forget to do before returning it. E.g. for the single child case.
13304 var clone = createWorkInProgress(fiber, pendingProps, expirationTime);
13305 clone.index = 0;
13306 clone.sibling = null;
13307 return clone;
13308 }
13309
13310 function placeChild(newFiber, lastPlacedIndex, newIndex) {
13311 newFiber.index = newIndex;
13312 if (!shouldTrackSideEffects) {
13313 // Noop.
13314 return lastPlacedIndex;
13315 }
13316 var current$$1 = newFiber.alternate;
13317 if (current$$1 !== null) {
13318 var oldIndex = current$$1.index;
13319 if (oldIndex < lastPlacedIndex) {
13320 // This is a move.
13321 newFiber.effectTag = Placement;
13322 return lastPlacedIndex;
13323 } else {
13324 // This item can stay in place.
13325 return oldIndex;
13326 }
13327 } else {
13328 // This is an insertion.
13329 newFiber.effectTag = Placement;
13330 return lastPlacedIndex;
13331 }
13332 }
13333
13334 function placeSingleChild(newFiber) {
13335 // This is simpler for the single child case. We only need to do a
13336 // placement for inserting new children.
13337 if (shouldTrackSideEffects && newFiber.alternate === null) {
13338 newFiber.effectTag = Placement;
13339 }
13340 return newFiber;
13341 }
13342
13343 function updateTextNode(returnFiber, current$$1, textContent, expirationTime) {
13344 if (current$$1 === null || current$$1.tag !== HostText) {
13345 // Insert
13346 var created = createFiberFromText(textContent, returnFiber.mode, expirationTime);
13347 created.return = returnFiber;
13348 return created;
13349 } else {
13350 // Update
13351 var existing = useFiber(current$$1, textContent, expirationTime);
13352 existing.return = returnFiber;
13353 return existing;
13354 }
13355 }
13356
13357 function updateElement(returnFiber, current$$1, element, expirationTime) {
13358 if (current$$1 !== null && current$$1.elementType === element.type) {
13359 // Move based on index
13360 var existing = useFiber(current$$1, element.props, expirationTime);
13361 existing.ref = coerceRef(returnFiber, current$$1, element);
13362 existing.return = returnFiber;
13363 {
13364 existing._debugSource = element._source;
13365 existing._debugOwner = element._owner;
13366 }
13367 return existing;
13368 } else {
13369 // Insert
13370 var created = createFiberFromElement(element, returnFiber.mode, expirationTime);
13371 created.ref = coerceRef(returnFiber, current$$1, element);
13372 created.return = returnFiber;
13373 return created;
13374 }
13375 }
13376
13377 function updatePortal(returnFiber, current$$1, portal, expirationTime) {
13378 if (current$$1 === null || current$$1.tag !== HostPortal || current$$1.stateNode.containerInfo !== portal.containerInfo || current$$1.stateNode.implementation !== portal.implementation) {
13379 // Insert
13380 var created = createFiberFromPortal(portal, returnFiber.mode, expirationTime);
13381 created.return = returnFiber;
13382 return created;
13383 } else {
13384 // Update
13385 var existing = useFiber(current$$1, portal.children || [], expirationTime);
13386 existing.return = returnFiber;
13387 return existing;
13388 }
13389 }
13390
13391 function updateFragment(returnFiber, current$$1, fragment, expirationTime, key) {
13392 if (current$$1 === null || current$$1.tag !== Fragment) {
13393 // Insert
13394 var created = createFiberFromFragment(fragment, returnFiber.mode, expirationTime, key);
13395 created.return = returnFiber;
13396 return created;
13397 } else {
13398 // Update
13399 var existing = useFiber(current$$1, fragment, expirationTime);
13400 existing.return = returnFiber;
13401 return existing;
13402 }
13403 }
13404
13405 function createChild(returnFiber, newChild, expirationTime) {
13406 if (typeof newChild === 'string' || typeof newChild === 'number') {
13407 // Text nodes don't have keys. If the previous node is implicitly keyed
13408 // we can continue to replace it without aborting even if it is not a text
13409 // node.
13410 var created = createFiberFromText('' + newChild, returnFiber.mode, expirationTime);
13411 created.return = returnFiber;
13412 return created;
13413 }
13414
13415 if (typeof newChild === 'object' && newChild !== null) {
13416 switch (newChild.$$typeof) {
13417 case REACT_ELEMENT_TYPE:
13418 {
13419 var _created = createFiberFromElement(newChild, returnFiber.mode, expirationTime);
13420 _created.ref = coerceRef(returnFiber, null, newChild);
13421 _created.return = returnFiber;
13422 return _created;
13423 }
13424 case REACT_PORTAL_TYPE:
13425 {
13426 var _created2 = createFiberFromPortal(newChild, returnFiber.mode, expirationTime);
13427 _created2.return = returnFiber;
13428 return _created2;
13429 }
13430 }
13431
13432 if (isArray(newChild) || getIteratorFn(newChild)) {
13433 var _created3 = createFiberFromFragment(newChild, returnFiber.mode, expirationTime, null);
13434 _created3.return = returnFiber;
13435 return _created3;
13436 }
13437
13438 throwOnInvalidObjectType(returnFiber, newChild);
13439 }
13440
13441 {
13442 if (typeof newChild === 'function') {
13443 warnOnFunctionType();
13444 }
13445 }
13446
13447 return null;
13448 }
13449
13450 function updateSlot(returnFiber, oldFiber, newChild, expirationTime) {
13451 // Update the fiber if the keys match, otherwise return null.
13452
13453 var key = oldFiber !== null ? oldFiber.key : null;
13454
13455 if (typeof newChild === 'string' || typeof newChild === 'number') {
13456 // Text nodes don't have keys. If the previous node is implicitly keyed
13457 // we can continue to replace it without aborting even if it is not a text
13458 // node.
13459 if (key !== null) {
13460 return null;
13461 }
13462 return updateTextNode(returnFiber, oldFiber, '' + newChild, expirationTime);
13463 }
13464
13465 if (typeof newChild === 'object' && newChild !== null) {
13466 switch (newChild.$$typeof) {
13467 case REACT_ELEMENT_TYPE:
13468 {
13469 if (newChild.key === key) {
13470 if (newChild.type === REACT_FRAGMENT_TYPE) {
13471 return updateFragment(returnFiber, oldFiber, newChild.props.children, expirationTime, key);
13472 }
13473 return updateElement(returnFiber, oldFiber, newChild, expirationTime);
13474 } else {
13475 return null;
13476 }
13477 }
13478 case REACT_PORTAL_TYPE:
13479 {
13480 if (newChild.key === key) {
13481 return updatePortal(returnFiber, oldFiber, newChild, expirationTime);
13482 } else {
13483 return null;
13484 }
13485 }
13486 }
13487
13488 if (isArray(newChild) || getIteratorFn(newChild)) {
13489 if (key !== null) {
13490 return null;
13491 }
13492
13493 return updateFragment(returnFiber, oldFiber, newChild, expirationTime, null);
13494 }
13495
13496 throwOnInvalidObjectType(returnFiber, newChild);
13497 }
13498
13499 {
13500 if (typeof newChild === 'function') {
13501 warnOnFunctionType();
13502 }
13503 }
13504
13505 return null;
13506 }
13507
13508 function updateFromMap(existingChildren, returnFiber, newIdx, newChild, expirationTime) {
13509 if (typeof newChild === 'string' || typeof newChild === 'number') {
13510 // Text nodes don't have keys, so we neither have to check the old nor
13511 // new node for the key. If both are text nodes, they match.
13512 var matchedFiber = existingChildren.get(newIdx) || null;
13513 return updateTextNode(returnFiber, matchedFiber, '' + newChild, expirationTime);
13514 }
13515
13516 if (typeof newChild === 'object' && newChild !== null) {
13517 switch (newChild.$$typeof) {
13518 case REACT_ELEMENT_TYPE:
13519 {
13520 var _matchedFiber = existingChildren.get(newChild.key === null ? newIdx : newChild.key) || null;
13521 if (newChild.type === REACT_FRAGMENT_TYPE) {
13522 return updateFragment(returnFiber, _matchedFiber, newChild.props.children, expirationTime, newChild.key);
13523 }
13524 return updateElement(returnFiber, _matchedFiber, newChild, expirationTime);
13525 }
13526 case REACT_PORTAL_TYPE:
13527 {
13528 var _matchedFiber2 = existingChildren.get(newChild.key === null ? newIdx : newChild.key) || null;
13529 return updatePortal(returnFiber, _matchedFiber2, newChild, expirationTime);
13530 }
13531 }
13532
13533 if (isArray(newChild) || getIteratorFn(newChild)) {
13534 var _matchedFiber3 = existingChildren.get(newIdx) || null;
13535 return updateFragment(returnFiber, _matchedFiber3, newChild, expirationTime, null);
13536 }
13537
13538 throwOnInvalidObjectType(returnFiber, newChild);
13539 }
13540
13541 {
13542 if (typeof newChild === 'function') {
13543 warnOnFunctionType();
13544 }
13545 }
13546
13547 return null;
13548 }
13549
13550 /**
13551 * Warns if there is a duplicate or missing key
13552 */
13553 function warnOnInvalidKey(child, knownKeys) {
13554 {
13555 if (typeof child !== 'object' || child === null) {
13556 return knownKeys;
13557 }
13558 switch (child.$$typeof) {
13559 case REACT_ELEMENT_TYPE:
13560 case REACT_PORTAL_TYPE:
13561 warnForMissingKey(child);
13562 var key = child.key;
13563 if (typeof key !== 'string') {
13564 break;
13565 }
13566 if (knownKeys === null) {
13567 knownKeys = new Set();
13568 knownKeys.add(key);
13569 break;
13570 }
13571 if (!knownKeys.has(key)) {
13572 knownKeys.add(key);
13573 break;
13574 }
13575 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);
13576 break;
13577 default:
13578 break;
13579 }
13580 }
13581 return knownKeys;
13582 }
13583
13584 function reconcileChildrenArray(returnFiber, currentFirstChild, newChildren, expirationTime) {
13585 // This algorithm can't optimize by searching from boths ends since we
13586 // don't have backpointers on fibers. I'm trying to see how far we can get
13587 // with that model. If it ends up not being worth the tradeoffs, we can
13588 // add it later.
13589
13590 // Even with a two ended optimization, we'd want to optimize for the case
13591 // where there are few changes and brute force the comparison instead of
13592 // going for the Map. It'd like to explore hitting that path first in
13593 // forward-only mode and only go for the Map once we notice that we need
13594 // lots of look ahead. This doesn't handle reversal as well as two ended
13595 // search but that's unusual. Besides, for the two ended optimization to
13596 // work on Iterables, we'd need to copy the whole set.
13597
13598 // In this first iteration, we'll just live with hitting the bad case
13599 // (adding everything to a Map) in for every insert/move.
13600
13601 // If you change this code, also update reconcileChildrenIterator() which
13602 // uses the same algorithm.
13603
13604 {
13605 // First, validate keys.
13606 var knownKeys = null;
13607 for (var i = 0; i < newChildren.length; i++) {
13608 var child = newChildren[i];
13609 knownKeys = warnOnInvalidKey(child, knownKeys);
13610 }
13611 }
13612
13613 var resultingFirstChild = null;
13614 var previousNewFiber = null;
13615
13616 var oldFiber = currentFirstChild;
13617 var lastPlacedIndex = 0;
13618 var newIdx = 0;
13619 var nextOldFiber = null;
13620 for (; oldFiber !== null && newIdx < newChildren.length; newIdx++) {
13621 if (oldFiber.index > newIdx) {
13622 nextOldFiber = oldFiber;
13623 oldFiber = null;
13624 } else {
13625 nextOldFiber = oldFiber.sibling;
13626 }
13627 var newFiber = updateSlot(returnFiber, oldFiber, newChildren[newIdx], expirationTime);
13628 if (newFiber === null) {
13629 // TODO: This breaks on empty slots like null children. That's
13630 // unfortunate because it triggers the slow path all the time. We need
13631 // a better way to communicate whether this was a miss or null,
13632 // boolean, undefined, etc.
13633 if (oldFiber === null) {
13634 oldFiber = nextOldFiber;
13635 }
13636 break;
13637 }
13638 if (shouldTrackSideEffects) {
13639 if (oldFiber && newFiber.alternate === null) {
13640 // We matched the slot, but we didn't reuse the existing fiber, so we
13641 // need to delete the existing child.
13642 deleteChild(returnFiber, oldFiber);
13643 }
13644 }
13645 lastPlacedIndex = placeChild(newFiber, lastPlacedIndex, newIdx);
13646 if (previousNewFiber === null) {
13647 // TODO: Move out of the loop. This only happens for the first run.
13648 resultingFirstChild = newFiber;
13649 } else {
13650 // TODO: Defer siblings if we're not at the right index for this slot.
13651 // I.e. if we had null values before, then we want to defer this
13652 // for each null value. However, we also don't want to call updateSlot
13653 // with the previous one.
13654 previousNewFiber.sibling = newFiber;
13655 }
13656 previousNewFiber = newFiber;
13657 oldFiber = nextOldFiber;
13658 }
13659
13660 if (newIdx === newChildren.length) {
13661 // We've reached the end of the new children. We can delete the rest.
13662 deleteRemainingChildren(returnFiber, oldFiber);
13663 return resultingFirstChild;
13664 }
13665
13666 if (oldFiber === null) {
13667 // If we don't have any more existing children we can choose a fast path
13668 // since the rest will all be insertions.
13669 for (; newIdx < newChildren.length; newIdx++) {
13670 var _newFiber = createChild(returnFiber, newChildren[newIdx], expirationTime);
13671 if (!_newFiber) {
13672 continue;
13673 }
13674 lastPlacedIndex = placeChild(_newFiber, lastPlacedIndex, newIdx);
13675 if (previousNewFiber === null) {
13676 // TODO: Move out of the loop. This only happens for the first run.
13677 resultingFirstChild = _newFiber;
13678 } else {
13679 previousNewFiber.sibling = _newFiber;
13680 }
13681 previousNewFiber = _newFiber;
13682 }
13683 return resultingFirstChild;
13684 }
13685
13686 // Add all children to a key map for quick lookups.
13687 var existingChildren = mapRemainingChildren(returnFiber, oldFiber);
13688
13689 // Keep scanning and use the map to restore deleted items as moves.
13690 for (; newIdx < newChildren.length; newIdx++) {
13691 var _newFiber2 = updateFromMap(existingChildren, returnFiber, newIdx, newChildren[newIdx], expirationTime);
13692 if (_newFiber2) {
13693 if (shouldTrackSideEffects) {
13694 if (_newFiber2.alternate !== null) {
13695 // The new fiber is a work in progress, but if there exists a
13696 // current, that means that we reused the fiber. We need to delete
13697 // it from the child list so that we don't add it to the deletion
13698 // list.
13699 existingChildren.delete(_newFiber2.key === null ? newIdx : _newFiber2.key);
13700 }
13701 }
13702 lastPlacedIndex = placeChild(_newFiber2, lastPlacedIndex, newIdx);
13703 if (previousNewFiber === null) {
13704 resultingFirstChild = _newFiber2;
13705 } else {
13706 previousNewFiber.sibling = _newFiber2;
13707 }
13708 previousNewFiber = _newFiber2;
13709 }
13710 }
13711
13712 if (shouldTrackSideEffects) {
13713 // Any existing children that weren't consumed above were deleted. We need
13714 // to add them to the deletion list.
13715 existingChildren.forEach(function (child) {
13716 return deleteChild(returnFiber, child);
13717 });
13718 }
13719
13720 return resultingFirstChild;
13721 }
13722
13723 function reconcileChildrenIterator(returnFiber, currentFirstChild, newChildrenIterable, expirationTime) {
13724 // This is the same implementation as reconcileChildrenArray(),
13725 // but using the iterator instead.
13726
13727 var iteratorFn = getIteratorFn(newChildrenIterable);
13728 !(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;
13729
13730 {
13731 // We don't support rendering Generators because it's a mutation.
13732 // See https://github.com/facebook/react/issues/12995
13733 if (typeof Symbol === 'function' &&
13734 // $FlowFixMe Flow doesn't know about toStringTag
13735 newChildrenIterable[Symbol.toStringTag] === 'Generator') {
13736 !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;
13737 didWarnAboutGenerators = true;
13738 }
13739
13740 // Warn about using Maps as children
13741 if (newChildrenIterable.entries === iteratorFn) {
13742 !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;
13743 didWarnAboutMaps = true;
13744 }
13745
13746 // First, validate keys.
13747 // We'll get a different iterator later for the main pass.
13748 var _newChildren = iteratorFn.call(newChildrenIterable);
13749 if (_newChildren) {
13750 var knownKeys = null;
13751 var _step = _newChildren.next();
13752 for (; !_step.done; _step = _newChildren.next()) {
13753 var child = _step.value;
13754 knownKeys = warnOnInvalidKey(child, knownKeys);
13755 }
13756 }
13757 }
13758
13759 var newChildren = iteratorFn.call(newChildrenIterable);
13760 !(newChildren != null) ? invariant(false, 'An iterable object provided no iterator.') : void 0;
13761
13762 var resultingFirstChild = null;
13763 var previousNewFiber = null;
13764
13765 var oldFiber = currentFirstChild;
13766 var lastPlacedIndex = 0;
13767 var newIdx = 0;
13768 var nextOldFiber = null;
13769
13770 var step = newChildren.next();
13771 for (; oldFiber !== null && !step.done; newIdx++, step = newChildren.next()) {
13772 if (oldFiber.index > newIdx) {
13773 nextOldFiber = oldFiber;
13774 oldFiber = null;
13775 } else {
13776 nextOldFiber = oldFiber.sibling;
13777 }
13778 var newFiber = updateSlot(returnFiber, oldFiber, step.value, expirationTime);
13779 if (newFiber === null) {
13780 // TODO: This breaks on empty slots like null children. That's
13781 // unfortunate because it triggers the slow path all the time. We need
13782 // a better way to communicate whether this was a miss or null,
13783 // boolean, undefined, etc.
13784 if (!oldFiber) {
13785 oldFiber = nextOldFiber;
13786 }
13787 break;
13788 }
13789 if (shouldTrackSideEffects) {
13790 if (oldFiber && newFiber.alternate === null) {
13791 // We matched the slot, but we didn't reuse the existing fiber, so we
13792 // need to delete the existing child.
13793 deleteChild(returnFiber, oldFiber);
13794 }
13795 }
13796 lastPlacedIndex = placeChild(newFiber, lastPlacedIndex, newIdx);
13797 if (previousNewFiber === null) {
13798 // TODO: Move out of the loop. This only happens for the first run.
13799 resultingFirstChild = newFiber;
13800 } else {
13801 // TODO: Defer siblings if we're not at the right index for this slot.
13802 // I.e. if we had null values before, then we want to defer this
13803 // for each null value. However, we also don't want to call updateSlot
13804 // with the previous one.
13805 previousNewFiber.sibling = newFiber;
13806 }
13807 previousNewFiber = newFiber;
13808 oldFiber = nextOldFiber;
13809 }
13810
13811 if (step.done) {
13812 // We've reached the end of the new children. We can delete the rest.
13813 deleteRemainingChildren(returnFiber, oldFiber);
13814 return resultingFirstChild;
13815 }
13816
13817 if (oldFiber === null) {
13818 // If we don't have any more existing children we can choose a fast path
13819 // since the rest will all be insertions.
13820 for (; !step.done; newIdx++, step = newChildren.next()) {
13821 var _newFiber3 = createChild(returnFiber, step.value, expirationTime);
13822 if (_newFiber3 === null) {
13823 continue;
13824 }
13825 lastPlacedIndex = placeChild(_newFiber3, lastPlacedIndex, newIdx);
13826 if (previousNewFiber === null) {
13827 // TODO: Move out of the loop. This only happens for the first run.
13828 resultingFirstChild = _newFiber3;
13829 } else {
13830 previousNewFiber.sibling = _newFiber3;
13831 }
13832 previousNewFiber = _newFiber3;
13833 }
13834 return resultingFirstChild;
13835 }
13836
13837 // Add all children to a key map for quick lookups.
13838 var existingChildren = mapRemainingChildren(returnFiber, oldFiber);
13839
13840 // Keep scanning and use the map to restore deleted items as moves.
13841 for (; !step.done; newIdx++, step = newChildren.next()) {
13842 var _newFiber4 = updateFromMap(existingChildren, returnFiber, newIdx, step.value, expirationTime);
13843 if (_newFiber4 !== null) {
13844 if (shouldTrackSideEffects) {
13845 if (_newFiber4.alternate !== null) {
13846 // The new fiber is a work in progress, but if there exists a
13847 // current, that means that we reused the fiber. We need to delete
13848 // it from the child list so that we don't add it to the deletion
13849 // list.
13850 existingChildren.delete(_newFiber4.key === null ? newIdx : _newFiber4.key);
13851 }
13852 }
13853 lastPlacedIndex = placeChild(_newFiber4, lastPlacedIndex, newIdx);
13854 if (previousNewFiber === null) {
13855 resultingFirstChild = _newFiber4;
13856 } else {
13857 previousNewFiber.sibling = _newFiber4;
13858 }
13859 previousNewFiber = _newFiber4;
13860 }
13861 }
13862
13863 if (shouldTrackSideEffects) {
13864 // Any existing children that weren't consumed above were deleted. We need
13865 // to add them to the deletion list.
13866 existingChildren.forEach(function (child) {
13867 return deleteChild(returnFiber, child);
13868 });
13869 }
13870
13871 return resultingFirstChild;
13872 }
13873
13874 function reconcileSingleTextNode(returnFiber, currentFirstChild, textContent, expirationTime) {
13875 // There's no need to check for keys on text nodes since we don't have a
13876 // way to define them.
13877 if (currentFirstChild !== null && currentFirstChild.tag === HostText) {
13878 // We already have an existing node so let's just update it and delete
13879 // the rest.
13880 deleteRemainingChildren(returnFiber, currentFirstChild.sibling);
13881 var existing = useFiber(currentFirstChild, textContent, expirationTime);
13882 existing.return = returnFiber;
13883 return existing;
13884 }
13885 // The existing first child is not a text node so we need to create one
13886 // and delete the existing ones.
13887 deleteRemainingChildren(returnFiber, currentFirstChild);
13888 var created = createFiberFromText(textContent, returnFiber.mode, expirationTime);
13889 created.return = returnFiber;
13890 return created;
13891 }
13892
13893 function reconcileSingleElement(returnFiber, currentFirstChild, element, expirationTime) {
13894 var key = element.key;
13895 var child = currentFirstChild;
13896 while (child !== null) {
13897 // TODO: If key === null and child.key === null, then this only applies to
13898 // the first item in the list.
13899 if (child.key === key) {
13900 if (child.tag === Fragment ? element.type === REACT_FRAGMENT_TYPE : child.elementType === element.type) {
13901 deleteRemainingChildren(returnFiber, child.sibling);
13902 var existing = useFiber(child, element.type === REACT_FRAGMENT_TYPE ? element.props.children : element.props, expirationTime);
13903 existing.ref = coerceRef(returnFiber, child, element);
13904 existing.return = returnFiber;
13905 {
13906 existing._debugSource = element._source;
13907 existing._debugOwner = element._owner;
13908 }
13909 return existing;
13910 } else {
13911 deleteRemainingChildren(returnFiber, child);
13912 break;
13913 }
13914 } else {
13915 deleteChild(returnFiber, child);
13916 }
13917 child = child.sibling;
13918 }
13919
13920 if (element.type === REACT_FRAGMENT_TYPE) {
13921 var created = createFiberFromFragment(element.props.children, returnFiber.mode, expirationTime, element.key);
13922 created.return = returnFiber;
13923 return created;
13924 } else {
13925 var _created4 = createFiberFromElement(element, returnFiber.mode, expirationTime);
13926 _created4.ref = coerceRef(returnFiber, currentFirstChild, element);
13927 _created4.return = returnFiber;
13928 return _created4;
13929 }
13930 }
13931
13932 function reconcileSinglePortal(returnFiber, currentFirstChild, portal, expirationTime) {
13933 var key = portal.key;
13934 var child = currentFirstChild;
13935 while (child !== null) {
13936 // TODO: If key === null and child.key === null, then this only applies to
13937 // the first item in the list.
13938 if (child.key === key) {
13939 if (child.tag === HostPortal && child.stateNode.containerInfo === portal.containerInfo && child.stateNode.implementation === portal.implementation) {
13940 deleteRemainingChildren(returnFiber, child.sibling);
13941 var existing = useFiber(child, portal.children || [], expirationTime);
13942 existing.return = returnFiber;
13943 return existing;
13944 } else {
13945 deleteRemainingChildren(returnFiber, child);
13946 break;
13947 }
13948 } else {
13949 deleteChild(returnFiber, child);
13950 }
13951 child = child.sibling;
13952 }
13953
13954 var created = createFiberFromPortal(portal, returnFiber.mode, expirationTime);
13955 created.return = returnFiber;
13956 return created;
13957 }
13958
13959 // This API will tag the children with the side-effect of the reconciliation
13960 // itself. They will be added to the side-effect list as we pass through the
13961 // children and the parent.
13962 function reconcileChildFibers(returnFiber, currentFirstChild, newChild, expirationTime) {
13963 // This function is not recursive.
13964 // If the top level item is an array, we treat it as a set of children,
13965 // not as a fragment. Nested arrays on the other hand will be treated as
13966 // fragment nodes. Recursion happens at the normal flow.
13967
13968 // Handle top level unkeyed fragments as if they were arrays.
13969 // This leads to an ambiguity between <>{[...]}</> and <>...</>.
13970 // We treat the ambiguous cases above the same.
13971 var isUnkeyedTopLevelFragment = typeof newChild === 'object' && newChild !== null && newChild.type === REACT_FRAGMENT_TYPE && newChild.key === null;
13972 if (isUnkeyedTopLevelFragment) {
13973 newChild = newChild.props.children;
13974 }
13975
13976 // Handle object types
13977 var isObject = typeof newChild === 'object' && newChild !== null;
13978
13979 if (isObject) {
13980 switch (newChild.$$typeof) {
13981 case REACT_ELEMENT_TYPE:
13982 return placeSingleChild(reconcileSingleElement(returnFiber, currentFirstChild, newChild, expirationTime));
13983 case REACT_PORTAL_TYPE:
13984 return placeSingleChild(reconcileSinglePortal(returnFiber, currentFirstChild, newChild, expirationTime));
13985 }
13986 }
13987
13988 if (typeof newChild === 'string' || typeof newChild === 'number') {
13989 return placeSingleChild(reconcileSingleTextNode(returnFiber, currentFirstChild, '' + newChild, expirationTime));
13990 }
13991
13992 if (isArray(newChild)) {
13993 return reconcileChildrenArray(returnFiber, currentFirstChild, newChild, expirationTime);
13994 }
13995
13996 if (getIteratorFn(newChild)) {
13997 return reconcileChildrenIterator(returnFiber, currentFirstChild, newChild, expirationTime);
13998 }
13999
14000 if (isObject) {
14001 throwOnInvalidObjectType(returnFiber, newChild);
14002 }
14003
14004 {
14005 if (typeof newChild === 'function') {
14006 warnOnFunctionType();
14007 }
14008 }
14009 if (typeof newChild === 'undefined' && !isUnkeyedTopLevelFragment) {
14010 // If the new child is undefined, and the return fiber is a composite
14011 // component, throw an error. If Fiber return types are disabled,
14012 // we already threw above.
14013 switch (returnFiber.tag) {
14014 case ClassComponent:
14015 {
14016 {
14017 var instance = returnFiber.stateNode;
14018 if (instance.render._isMockFunction) {
14019 // We allow auto-mocks to proceed as if they're returning null.
14020 break;
14021 }
14022 }
14023 }
14024 // Intentionally fall through to the next case, which handles both
14025 // functions and classes
14026 // eslint-disable-next-lined no-fallthrough
14027 case FunctionComponent:
14028 {
14029 var Component = returnFiber.type;
14030 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');
14031 }
14032 }
14033 }
14034
14035 // Remaining cases are all treated as empty.
14036 return deleteRemainingChildren(returnFiber, currentFirstChild);
14037 }
14038
14039 return reconcileChildFibers;
14040}
14041
14042var reconcileChildFibers = ChildReconciler(true);
14043var mountChildFibers = ChildReconciler(false);
14044
14045function cloneChildFibers(current$$1, workInProgress) {
14046 !(current$$1 === null || workInProgress.child === current$$1.child) ? invariant(false, 'Resuming work not yet implemented.') : void 0;
14047
14048 if (workInProgress.child === null) {
14049 return;
14050 }
14051
14052 var currentChild = workInProgress.child;
14053 var newChild = createWorkInProgress(currentChild, currentChild.pendingProps, currentChild.expirationTime);
14054 workInProgress.child = newChild;
14055
14056 newChild.return = workInProgress;
14057 while (currentChild.sibling !== null) {
14058 currentChild = currentChild.sibling;
14059 newChild = newChild.sibling = createWorkInProgress(currentChild, currentChild.pendingProps, currentChild.expirationTime);
14060 newChild.return = workInProgress;
14061 }
14062 newChild.sibling = null;
14063}
14064
14065// The deepest Fiber on the stack involved in a hydration context.
14066// This may have been an insertion or a hydration.
14067var hydrationParentFiber = null;
14068var nextHydratableInstance = null;
14069var isHydrating = false;
14070
14071function enterHydrationState(fiber) {
14072 if (!supportsHydration) {
14073 return false;
14074 }
14075
14076 var parentInstance = fiber.stateNode.containerInfo;
14077 nextHydratableInstance = getFirstHydratableChild(parentInstance);
14078 hydrationParentFiber = fiber;
14079 isHydrating = true;
14080 return true;
14081}
14082
14083function deleteHydratableInstance(returnFiber, instance) {
14084 {
14085 switch (returnFiber.tag) {
14086 case HostRoot:
14087 didNotHydrateContainerInstance(returnFiber.stateNode.containerInfo, instance);
14088 break;
14089 case HostComponent:
14090 didNotHydrateInstance(returnFiber.type, returnFiber.memoizedProps, returnFiber.stateNode, instance);
14091 break;
14092 }
14093 }
14094
14095 var childToDelete = createFiberFromHostInstanceForDeletion();
14096 childToDelete.stateNode = instance;
14097 childToDelete.return = returnFiber;
14098 childToDelete.effectTag = Deletion;
14099
14100 // This might seem like it belongs on progressedFirstDeletion. However,
14101 // these children are not part of the reconciliation list of children.
14102 // Even if we abort and rereconcile the children, that will try to hydrate
14103 // again and the nodes are still in the host tree so these will be
14104 // recreated.
14105 if (returnFiber.lastEffect !== null) {
14106 returnFiber.lastEffect.nextEffect = childToDelete;
14107 returnFiber.lastEffect = childToDelete;
14108 } else {
14109 returnFiber.firstEffect = returnFiber.lastEffect = childToDelete;
14110 }
14111}
14112
14113function insertNonHydratedInstance(returnFiber, fiber) {
14114 fiber.effectTag |= Placement;
14115 {
14116 switch (returnFiber.tag) {
14117 case HostRoot:
14118 {
14119 var parentContainer = returnFiber.stateNode.containerInfo;
14120 switch (fiber.tag) {
14121 case HostComponent:
14122 var type = fiber.type;
14123 var props = fiber.pendingProps;
14124 didNotFindHydratableContainerInstance(parentContainer, type, props);
14125 break;
14126 case HostText:
14127 var text = fiber.pendingProps;
14128 didNotFindHydratableContainerTextInstance(parentContainer, text);
14129 break;
14130 }
14131 break;
14132 }
14133 case HostComponent:
14134 {
14135 var parentType = returnFiber.type;
14136 var parentProps = returnFiber.memoizedProps;
14137 var parentInstance = returnFiber.stateNode;
14138 switch (fiber.tag) {
14139 case HostComponent:
14140 var _type = fiber.type;
14141 var _props = fiber.pendingProps;
14142 didNotFindHydratableInstance(parentType, parentProps, parentInstance, _type, _props);
14143 break;
14144 case HostText:
14145 var _text = fiber.pendingProps;
14146 didNotFindHydratableTextInstance(parentType, parentProps, parentInstance, _text);
14147 break;
14148 }
14149 break;
14150 }
14151 default:
14152 return;
14153 }
14154 }
14155}
14156
14157function tryHydrate(fiber, nextInstance) {
14158 switch (fiber.tag) {
14159 case HostComponent:
14160 {
14161 var type = fiber.type;
14162 var props = fiber.pendingProps;
14163 var instance = canHydrateInstance(nextInstance, type, props);
14164 if (instance !== null) {
14165 fiber.stateNode = instance;
14166 return true;
14167 }
14168 return false;
14169 }
14170 case HostText:
14171 {
14172 var text = fiber.pendingProps;
14173 var textInstance = canHydrateTextInstance(nextInstance, text);
14174 if (textInstance !== null) {
14175 fiber.stateNode = textInstance;
14176 return true;
14177 }
14178 return false;
14179 }
14180 default:
14181 return false;
14182 }
14183}
14184
14185function tryToClaimNextHydratableInstance(fiber) {
14186 if (!isHydrating) {
14187 return;
14188 }
14189 var nextInstance = nextHydratableInstance;
14190 if (!nextInstance) {
14191 // Nothing to hydrate. Make it an insertion.
14192 insertNonHydratedInstance(hydrationParentFiber, fiber);
14193 isHydrating = false;
14194 hydrationParentFiber = fiber;
14195 return;
14196 }
14197 var firstAttemptedInstance = nextInstance;
14198 if (!tryHydrate(fiber, nextInstance)) {
14199 // If we can't hydrate this instance let's try the next one.
14200 // We use this as a heuristic. It's based on intuition and not data so it
14201 // might be flawed or unnecessary.
14202 nextInstance = getNextHydratableSibling(firstAttemptedInstance);
14203 if (!nextInstance || !tryHydrate(fiber, nextInstance)) {
14204 // Nothing to hydrate. Make it an insertion.
14205 insertNonHydratedInstance(hydrationParentFiber, fiber);
14206 isHydrating = false;
14207 hydrationParentFiber = fiber;
14208 return;
14209 }
14210 // We matched the next one, we'll now assume that the first one was
14211 // superfluous and we'll delete it. Since we can't eagerly delete it
14212 // we'll have to schedule a deletion. To do that, this node needs a dummy
14213 // fiber associated with it.
14214 deleteHydratableInstance(hydrationParentFiber, firstAttemptedInstance);
14215 }
14216 hydrationParentFiber = fiber;
14217 nextHydratableInstance = getFirstHydratableChild(nextInstance);
14218}
14219
14220function prepareToHydrateHostInstance(fiber, rootContainerInstance, hostContext) {
14221 if (!supportsHydration) {
14222 invariant(false, 'Expected prepareToHydrateHostInstance() to never be called. This error is likely caused by a bug in React. Please file an issue.');
14223 }
14224
14225 var instance = fiber.stateNode;
14226 var updatePayload = hydrateInstance(instance, fiber.type, fiber.memoizedProps, rootContainerInstance, hostContext, fiber);
14227 // TODO: Type this specific to this type of component.
14228 fiber.updateQueue = updatePayload;
14229 // If the update payload indicates that there is a change or if there
14230 // is a new ref we mark this as an update.
14231 if (updatePayload !== null) {
14232 return true;
14233 }
14234 return false;
14235}
14236
14237function prepareToHydrateHostTextInstance(fiber) {
14238 if (!supportsHydration) {
14239 invariant(false, 'Expected prepareToHydrateHostTextInstance() to never be called. This error is likely caused by a bug in React. Please file an issue.');
14240 }
14241
14242 var textInstance = fiber.stateNode;
14243 var textContent = fiber.memoizedProps;
14244 var shouldUpdate = hydrateTextInstance(textInstance, textContent, fiber);
14245 {
14246 if (shouldUpdate) {
14247 // We assume that prepareToHydrateHostTextInstance is called in a context where the
14248 // hydration parent is the parent host component of this host text.
14249 var returnFiber = hydrationParentFiber;
14250 if (returnFiber !== null) {
14251 switch (returnFiber.tag) {
14252 case HostRoot:
14253 {
14254 var parentContainer = returnFiber.stateNode.containerInfo;
14255 didNotMatchHydratedContainerTextInstance(parentContainer, textInstance, textContent);
14256 break;
14257 }
14258 case HostComponent:
14259 {
14260 var parentType = returnFiber.type;
14261 var parentProps = returnFiber.memoizedProps;
14262 var parentInstance = returnFiber.stateNode;
14263 didNotMatchHydratedTextInstance(parentType, parentProps, parentInstance, textInstance, textContent);
14264 break;
14265 }
14266 }
14267 }
14268 }
14269 }
14270 return shouldUpdate;
14271}
14272
14273function popToNextHostParent(fiber) {
14274 var parent = fiber.return;
14275 while (parent !== null && parent.tag !== HostComponent && parent.tag !== HostRoot) {
14276 parent = parent.return;
14277 }
14278 hydrationParentFiber = parent;
14279}
14280
14281function popHydrationState(fiber) {
14282 if (!supportsHydration) {
14283 return false;
14284 }
14285 if (fiber !== hydrationParentFiber) {
14286 // We're deeper than the current hydration context, inside an inserted
14287 // tree.
14288 return false;
14289 }
14290 if (!isHydrating) {
14291 // If we're not currently hydrating but we're in a hydration context, then
14292 // we were an insertion and now need to pop up reenter hydration of our
14293 // siblings.
14294 popToNextHostParent(fiber);
14295 isHydrating = true;
14296 return false;
14297 }
14298
14299 var type = fiber.type;
14300
14301 // If we have any remaining hydratable nodes, we need to delete them now.
14302 // We only do this deeper than head and body since they tend to have random
14303 // other nodes in them. We also ignore components with pure text content in
14304 // side of them.
14305 // TODO: Better heuristic.
14306 if (fiber.tag !== HostComponent || type !== 'head' && type !== 'body' && !shouldSetTextContent(type, fiber.memoizedProps)) {
14307 var nextInstance = nextHydratableInstance;
14308 while (nextInstance) {
14309 deleteHydratableInstance(fiber, nextInstance);
14310 nextInstance = getNextHydratableSibling(nextInstance);
14311 }
14312 }
14313
14314 popToNextHostParent(fiber);
14315 nextHydratableInstance = hydrationParentFiber ? getNextHydratableSibling(fiber.stateNode) : null;
14316 return true;
14317}
14318
14319function resetHydrationState() {
14320 if (!supportsHydration) {
14321 return;
14322 }
14323
14324 hydrationParentFiber = null;
14325 nextHydratableInstance = null;
14326 isHydrating = false;
14327}
14328
14329var ReactCurrentOwner$3 = ReactSharedInternals.ReactCurrentOwner;
14330
14331var didWarnAboutBadClass = void 0;
14332var didWarnAboutContextTypeOnFunctionComponent = void 0;
14333var didWarnAboutGetDerivedStateOnFunctionComponent = void 0;
14334var didWarnAboutFunctionRefs = void 0;
14335var didWarnAboutReassigningProps = void 0;
14336
14337{
14338 didWarnAboutBadClass = {};
14339 didWarnAboutContextTypeOnFunctionComponent = {};
14340 didWarnAboutGetDerivedStateOnFunctionComponent = {};
14341 didWarnAboutFunctionRefs = {};
14342 didWarnAboutReassigningProps = false;
14343}
14344
14345function reconcileChildren(current$$1, workInProgress, nextChildren, renderExpirationTime) {
14346 if (current$$1 === null) {
14347 // If this is a fresh new component that hasn't been rendered yet, we
14348 // won't update its child set by applying minimal side-effects. Instead,
14349 // we will add them all to the child before it gets rendered. That means
14350 // we can optimize this reconciliation pass by not tracking side-effects.
14351 workInProgress.child = mountChildFibers(workInProgress, null, nextChildren, renderExpirationTime);
14352 } else {
14353 // If the current child is the same as the work in progress, it means that
14354 // we haven't yet started any work on these children. Therefore, we use
14355 // the clone algorithm to create a copy of all the current children.
14356
14357 // If we had any progressed work already, that is invalid at this point so
14358 // let's throw it out.
14359 workInProgress.child = reconcileChildFibers(workInProgress, current$$1.child, nextChildren, renderExpirationTime);
14360 }
14361}
14362
14363function forceUnmountCurrentAndReconcile(current$$1, workInProgress, nextChildren, renderExpirationTime) {
14364 // This function is fork of reconcileChildren. It's used in cases where we
14365 // want to reconcile without matching against the existing set. This has the
14366 // effect of all current children being unmounted; even if the type and key
14367 // are the same, the old child is unmounted and a new child is created.
14368 //
14369 // To do this, we're going to go through the reconcile algorithm twice. In
14370 // the first pass, we schedule a deletion for all the current children by
14371 // passing null.
14372 workInProgress.child = reconcileChildFibers(workInProgress, current$$1.child, null, renderExpirationTime);
14373 // In the second pass, we mount the new children. The trick here is that we
14374 // pass null in place of where we usually pass the current child set. This has
14375 // the effect of remounting all children regardless of whether their their
14376 // identity matches.
14377 workInProgress.child = reconcileChildFibers(workInProgress, null, nextChildren, renderExpirationTime);
14378}
14379
14380function updateForwardRef(current$$1, workInProgress, Component, nextProps, renderExpirationTime) {
14381 {
14382 if (workInProgress.type !== workInProgress.elementType) {
14383 // Lazy component props can't be validated in createElement
14384 // because they're only guaranteed to be resolved here.
14385 var innerPropTypes = Component.propTypes;
14386 if (innerPropTypes) {
14387 checkPropTypes_1(innerPropTypes, nextProps, // Resolved props
14388 'prop', getComponentName(Component), getCurrentFiberStackInDev);
14389 }
14390 }
14391 }
14392
14393 var render = Component.render;
14394 var ref = workInProgress.ref;
14395
14396 // The rest is a fork of updateFunctionComponent
14397 var nextChildren = void 0;
14398 prepareToReadContext(workInProgress, renderExpirationTime);
14399 prepareToUseHooks(current$$1, workInProgress, renderExpirationTime);
14400 {
14401 ReactCurrentOwner$3.current = workInProgress;
14402 setCurrentPhase('render');
14403 nextChildren = render(nextProps, ref);
14404 setCurrentPhase(null);
14405 }
14406 nextChildren = finishHooks(render, nextProps, nextChildren, ref);
14407
14408 // React DevTools reads this flag.
14409 workInProgress.effectTag |= PerformedWork;
14410 reconcileChildren(current$$1, workInProgress, nextChildren, renderExpirationTime);
14411 return workInProgress.child;
14412}
14413
14414function updateMemoComponent(current$$1, workInProgress, Component, nextProps, updateExpirationTime, renderExpirationTime) {
14415 if (current$$1 === null) {
14416 var type = Component.type;
14417 if (isSimpleFunctionComponent(type) && Component.compare === null &&
14418 // SimpleMemoComponent codepath doesn't resolve outer props either.
14419 Component.defaultProps === undefined) {
14420 // If this is a plain function component without default props,
14421 // and with only the default shallow comparison, we upgrade it
14422 // to a SimpleMemoComponent to allow fast path updates.
14423 workInProgress.tag = SimpleMemoComponent;
14424 workInProgress.type = type;
14425 {
14426 validateFunctionComponentInDev(workInProgress, type);
14427 }
14428 return updateSimpleMemoComponent(current$$1, workInProgress, type, nextProps, updateExpirationTime, renderExpirationTime);
14429 }
14430 {
14431 var innerPropTypes = type.propTypes;
14432 if (innerPropTypes) {
14433 // Inner memo component props aren't currently validated in createElement.
14434 // We could move it there, but we'd still need this for lazy code path.
14435 checkPropTypes_1(innerPropTypes, nextProps, // Resolved props
14436 'prop', getComponentName(type), getCurrentFiberStackInDev);
14437 }
14438 }
14439 var child = createFiberFromTypeAndProps(Component.type, null, nextProps, null, workInProgress.mode, renderExpirationTime);
14440 child.ref = workInProgress.ref;
14441 child.return = workInProgress;
14442 workInProgress.child = child;
14443 return child;
14444 }
14445 {
14446 var _type = Component.type;
14447 var _innerPropTypes = _type.propTypes;
14448 if (_innerPropTypes) {
14449 // Inner memo component props aren't currently validated in createElement.
14450 // We could move it there, but we'd still need this for lazy code path.
14451 checkPropTypes_1(_innerPropTypes, nextProps, // Resolved props
14452 'prop', getComponentName(_type), getCurrentFiberStackInDev);
14453 }
14454 }
14455 var currentChild = current$$1.child; // This is always exactly one child
14456 if (updateExpirationTime < renderExpirationTime) {
14457 // This will be the props with resolved defaultProps,
14458 // unlike current.memoizedProps which will be the unresolved ones.
14459 var prevProps = currentChild.memoizedProps;
14460 // Default to shallow comparison
14461 var compare = Component.compare;
14462 compare = compare !== null ? compare : shallowEqual;
14463 if (compare(prevProps, nextProps) && current$$1.ref === workInProgress.ref) {
14464 return bailoutOnAlreadyFinishedWork(current$$1, workInProgress, renderExpirationTime);
14465 }
14466 }
14467 // React DevTools reads this flag.
14468 workInProgress.effectTag |= PerformedWork;
14469 var newChild = createWorkInProgress(currentChild, nextProps, renderExpirationTime);
14470 newChild.ref = workInProgress.ref;
14471 newChild.return = workInProgress;
14472 workInProgress.child = newChild;
14473 return newChild;
14474}
14475
14476function updateSimpleMemoComponent(current$$1, workInProgress, Component, nextProps, updateExpirationTime, renderExpirationTime) {
14477 {
14478 if (workInProgress.type !== workInProgress.elementType) {
14479 // Lazy component props can't be validated in createElement
14480 // because they're only guaranteed to be resolved here.
14481 var outerMemoType = workInProgress.elementType;
14482 if (outerMemoType.$$typeof === REACT_LAZY_TYPE) {
14483 // We warn when you define propTypes on lazy()
14484 // so let's just skip over it to find memo() outer wrapper.
14485 // Inner props for memo are validated later.
14486 outerMemoType = refineResolvedLazyComponent(outerMemoType);
14487 }
14488 var outerPropTypes = outerMemoType && outerMemoType.propTypes;
14489 if (outerPropTypes) {
14490 checkPropTypes_1(outerPropTypes, nextProps, // Resolved (SimpleMemoComponent has no defaultProps)
14491 'prop', getComponentName(outerMemoType), getCurrentFiberStackInDev);
14492 }
14493 // Inner propTypes will be validated in the function component path.
14494 }
14495 }
14496 if (current$$1 !== null && updateExpirationTime < renderExpirationTime) {
14497 var prevProps = current$$1.memoizedProps;
14498 if (shallowEqual(prevProps, nextProps) && current$$1.ref === workInProgress.ref) {
14499 return bailoutOnAlreadyFinishedWork(current$$1, workInProgress, renderExpirationTime);
14500 }
14501 }
14502 return updateFunctionComponent(current$$1, workInProgress, Component, nextProps, renderExpirationTime);
14503}
14504
14505function updateFragment(current$$1, workInProgress, renderExpirationTime) {
14506 var nextChildren = workInProgress.pendingProps;
14507 reconcileChildren(current$$1, workInProgress, nextChildren, renderExpirationTime);
14508 return workInProgress.child;
14509}
14510
14511function updateMode(current$$1, workInProgress, renderExpirationTime) {
14512 var nextChildren = workInProgress.pendingProps.children;
14513 reconcileChildren(current$$1, workInProgress, nextChildren, renderExpirationTime);
14514 return workInProgress.child;
14515}
14516
14517function updateProfiler(current$$1, workInProgress, renderExpirationTime) {
14518 if (enableProfilerTimer) {
14519 workInProgress.effectTag |= Update;
14520 }
14521 var nextProps = workInProgress.pendingProps;
14522 var nextChildren = nextProps.children;
14523 reconcileChildren(current$$1, workInProgress, nextChildren, renderExpirationTime);
14524 return workInProgress.child;
14525}
14526
14527function markRef(current$$1, workInProgress) {
14528 var ref = workInProgress.ref;
14529 if (current$$1 === null && ref !== null || current$$1 !== null && current$$1.ref !== ref) {
14530 // Schedule a Ref effect
14531 workInProgress.effectTag |= Ref;
14532 }
14533}
14534
14535function updateFunctionComponent(current$$1, workInProgress, Component, nextProps, renderExpirationTime) {
14536 {
14537 if (workInProgress.type !== workInProgress.elementType) {
14538 // Lazy component props can't be validated in createElement
14539 // because they're only guaranteed to be resolved here.
14540 var innerPropTypes = Component.propTypes;
14541 if (innerPropTypes) {
14542 checkPropTypes_1(innerPropTypes, nextProps, // Resolved props
14543 'prop', getComponentName(Component), getCurrentFiberStackInDev);
14544 }
14545 }
14546 }
14547
14548 var unmaskedContext = getUnmaskedContext(workInProgress, Component, true);
14549 var context = getMaskedContext(workInProgress, unmaskedContext);
14550
14551 var nextChildren = void 0;
14552 prepareToReadContext(workInProgress, renderExpirationTime);
14553 prepareToUseHooks(current$$1, workInProgress, renderExpirationTime);
14554 {
14555 ReactCurrentOwner$3.current = workInProgress;
14556 setCurrentPhase('render');
14557 nextChildren = Component(nextProps, context);
14558 setCurrentPhase(null);
14559 }
14560 nextChildren = finishHooks(Component, nextProps, nextChildren, context);
14561
14562 // React DevTools reads this flag.
14563 workInProgress.effectTag |= PerformedWork;
14564 reconcileChildren(current$$1, workInProgress, nextChildren, renderExpirationTime);
14565 return workInProgress.child;
14566}
14567
14568function updateClassComponent(current$$1, workInProgress, Component, nextProps, renderExpirationTime) {
14569 {
14570 if (workInProgress.type !== workInProgress.elementType) {
14571 // Lazy component props can't be validated in createElement
14572 // because they're only guaranteed to be resolved here.
14573 var innerPropTypes = Component.propTypes;
14574 if (innerPropTypes) {
14575 checkPropTypes_1(innerPropTypes, nextProps, // Resolved props
14576 'prop', getComponentName(Component), getCurrentFiberStackInDev);
14577 }
14578 }
14579 }
14580
14581 // Push context providers early to prevent context stack mismatches.
14582 // During mounting we don't know the child context yet as the instance doesn't exist.
14583 // We will invalidate the child context in finishClassComponent() right after rendering.
14584 var hasContext = void 0;
14585 if (isContextProvider(Component)) {
14586 hasContext = true;
14587 pushContextProvider(workInProgress);
14588 } else {
14589 hasContext = false;
14590 }
14591 prepareToReadContext(workInProgress, renderExpirationTime);
14592
14593 var instance = workInProgress.stateNode;
14594 var shouldUpdate = void 0;
14595 if (instance === null) {
14596 if (current$$1 !== null) {
14597 // An class component without an instance only mounts if it suspended
14598 // inside a non- concurrent tree, in an inconsistent state. We want to
14599 // tree it like a new mount, even though an empty version of it already
14600 // committed. Disconnect the alternate pointers.
14601 current$$1.alternate = null;
14602 workInProgress.alternate = null;
14603 // Since this is conceptually a new fiber, schedule a Placement effect
14604 workInProgress.effectTag |= Placement;
14605 }
14606 // In the initial pass we might need to construct the instance.
14607 constructClassInstance(workInProgress, Component, nextProps, renderExpirationTime);
14608 mountClassInstance(workInProgress, Component, nextProps, renderExpirationTime);
14609 shouldUpdate = true;
14610 } else if (current$$1 === null) {
14611 // In a resume, we'll already have an instance we can reuse.
14612 shouldUpdate = resumeMountClassInstance(workInProgress, Component, nextProps, renderExpirationTime);
14613 } else {
14614 shouldUpdate = updateClassInstance(current$$1, workInProgress, Component, nextProps, renderExpirationTime);
14615 }
14616 var nextUnitOfWork = finishClassComponent(current$$1, workInProgress, Component, shouldUpdate, hasContext, renderExpirationTime);
14617 {
14618 var inst = workInProgress.stateNode;
14619 if (inst.props !== nextProps) {
14620 !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;
14621 didWarnAboutReassigningProps = true;
14622 }
14623 }
14624 return nextUnitOfWork;
14625}
14626
14627function finishClassComponent(current$$1, workInProgress, Component, shouldUpdate, hasContext, renderExpirationTime) {
14628 // Refs should update even if shouldComponentUpdate returns false
14629 markRef(current$$1, workInProgress);
14630
14631 var didCaptureError = (workInProgress.effectTag & DidCapture) !== NoEffect;
14632
14633 if (!shouldUpdate && !didCaptureError) {
14634 // Context providers should defer to sCU for rendering
14635 if (hasContext) {
14636 invalidateContextProvider(workInProgress, Component, false);
14637 }
14638
14639 return bailoutOnAlreadyFinishedWork(current$$1, workInProgress, renderExpirationTime);
14640 }
14641
14642 var instance = workInProgress.stateNode;
14643
14644 // Rerender
14645 ReactCurrentOwner$3.current = workInProgress;
14646 var nextChildren = void 0;
14647 if (didCaptureError && typeof Component.getDerivedStateFromError !== 'function') {
14648 // If we captured an error, but getDerivedStateFrom catch is not defined,
14649 // unmount all the children. componentDidCatch will schedule an update to
14650 // re-render a fallback. This is temporary until we migrate everyone to
14651 // the new API.
14652 // TODO: Warn in a future release.
14653 nextChildren = null;
14654
14655 if (enableProfilerTimer) {
14656 stopProfilerTimerIfRunning(workInProgress);
14657 }
14658 } else {
14659 {
14660 setCurrentPhase('render');
14661 nextChildren = instance.render();
14662 if (debugRenderPhaseSideEffects || debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) {
14663 instance.render();
14664 }
14665 setCurrentPhase(null);
14666 }
14667 }
14668
14669 // React DevTools reads this flag.
14670 workInProgress.effectTag |= PerformedWork;
14671 if (current$$1 !== null && didCaptureError) {
14672 // If we're recovering from an error, reconcile without reusing any of
14673 // the existing children. Conceptually, the normal children and the children
14674 // that are shown on error are two different sets, so we shouldn't reuse
14675 // normal children even if their identities match.
14676 forceUnmountCurrentAndReconcile(current$$1, workInProgress, nextChildren, renderExpirationTime);
14677 } else {
14678 reconcileChildren(current$$1, workInProgress, nextChildren, renderExpirationTime);
14679 }
14680
14681 // Memoize state using the values we just used to render.
14682 // TODO: Restructure so we never read values from the instance.
14683 workInProgress.memoizedState = instance.state;
14684
14685 // The context might have changed so we need to recalculate it.
14686 if (hasContext) {
14687 invalidateContextProvider(workInProgress, Component, true);
14688 }
14689
14690 return workInProgress.child;
14691}
14692
14693function pushHostRootContext(workInProgress) {
14694 var root = workInProgress.stateNode;
14695 if (root.pendingContext) {
14696 pushTopLevelContextObject(workInProgress, root.pendingContext, root.pendingContext !== root.context);
14697 } else if (root.context) {
14698 // Should always be set
14699 pushTopLevelContextObject(workInProgress, root.context, false);
14700 }
14701 pushHostContainer(workInProgress, root.containerInfo);
14702}
14703
14704function updateHostRoot(current$$1, workInProgress, renderExpirationTime) {
14705 pushHostRootContext(workInProgress);
14706 var updateQueue = workInProgress.updateQueue;
14707 !(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;
14708 var nextProps = workInProgress.pendingProps;
14709 var prevState = workInProgress.memoizedState;
14710 var prevChildren = prevState !== null ? prevState.element : null;
14711 processUpdateQueue(workInProgress, updateQueue, nextProps, null, renderExpirationTime);
14712 var nextState = workInProgress.memoizedState;
14713 // Caution: React DevTools currently depends on this property
14714 // being called "element".
14715 var nextChildren = nextState.element;
14716 if (nextChildren === prevChildren) {
14717 // If the state is the same as before, that's a bailout because we had
14718 // no work that expires at this time.
14719 resetHydrationState();
14720 return bailoutOnAlreadyFinishedWork(current$$1, workInProgress, renderExpirationTime);
14721 }
14722 var root = workInProgress.stateNode;
14723 if ((current$$1 === null || current$$1.child === null) && root.hydrate && enterHydrationState(workInProgress)) {
14724 // If we don't have any current children this might be the first pass.
14725 // We always try to hydrate. If this isn't a hydration pass there won't
14726 // be any children to hydrate which is effectively the same thing as
14727 // not hydrating.
14728
14729 // This is a bit of a hack. We track the host root as a placement to
14730 // know that we're currently in a mounting state. That way isMounted
14731 // works as expected. We must reset this before committing.
14732 // TODO: Delete this when we delete isMounted and findDOMNode.
14733 workInProgress.effectTag |= Placement;
14734
14735 // Ensure that children mount into this root without tracking
14736 // side-effects. This ensures that we don't store Placement effects on
14737 // nodes that will be hydrated.
14738 workInProgress.child = mountChildFibers(workInProgress, null, nextChildren, renderExpirationTime);
14739 } else {
14740 // Otherwise reset hydration state in case we aborted and resumed another
14741 // root.
14742 reconcileChildren(current$$1, workInProgress, nextChildren, renderExpirationTime);
14743 resetHydrationState();
14744 }
14745 return workInProgress.child;
14746}
14747
14748function updateHostComponent(current$$1, workInProgress, renderExpirationTime) {
14749 pushHostContext(workInProgress);
14750
14751 if (current$$1 === null) {
14752 tryToClaimNextHydratableInstance(workInProgress);
14753 }
14754
14755 var type = workInProgress.type;
14756 var nextProps = workInProgress.pendingProps;
14757 var prevProps = current$$1 !== null ? current$$1.memoizedProps : null;
14758
14759 var nextChildren = nextProps.children;
14760 var isDirectTextChild = shouldSetTextContent(type, nextProps);
14761
14762 if (isDirectTextChild) {
14763 // We special case a direct text child of a host node. This is a common
14764 // case. We won't handle it as a reified child. We will instead handle
14765 // this in the host environment that also have access to this prop. That
14766 // avoids allocating another HostText fiber and traversing it.
14767 nextChildren = null;
14768 } else if (prevProps !== null && shouldSetTextContent(type, prevProps)) {
14769 // If we're switching from a direct text child to a normal child, or to
14770 // empty, we need to schedule the text content to be reset.
14771 workInProgress.effectTag |= ContentReset;
14772 }
14773
14774 markRef(current$$1, workInProgress);
14775
14776 // Check the host config to see if the children are offscreen/hidden.
14777 if (renderExpirationTime !== Never && workInProgress.mode & ConcurrentMode && shouldDeprioritizeSubtree(type, nextProps)) {
14778 // Schedule this fiber to re-render at offscreen priority. Then bailout.
14779 workInProgress.expirationTime = Never;
14780 return null;
14781 }
14782
14783 reconcileChildren(current$$1, workInProgress, nextChildren, renderExpirationTime);
14784 return workInProgress.child;
14785}
14786
14787function updateHostText(current$$1, workInProgress) {
14788 if (current$$1 === null) {
14789 tryToClaimNextHydratableInstance(workInProgress);
14790 }
14791 // Nothing to do here. This is terminal. We'll do the completion step
14792 // immediately after.
14793 return null;
14794}
14795
14796function mountLazyComponent(_current, workInProgress, elementType, updateExpirationTime, renderExpirationTime) {
14797 if (_current !== null) {
14798 // An lazy component only mounts if it suspended inside a non-
14799 // concurrent tree, in an inconsistent state. We want to treat it like
14800 // a new mount, even though an empty version of it already committed.
14801 // Disconnect the alternate pointers.
14802 _current.alternate = null;
14803 workInProgress.alternate = null;
14804 // Since this is conceptually a new fiber, schedule a Placement effect
14805 workInProgress.effectTag |= Placement;
14806 }
14807
14808 var props = workInProgress.pendingProps;
14809 // We can't start a User Timing measurement with correct label yet.
14810 // Cancel and resume right after we know the tag.
14811 cancelWorkTimer(workInProgress);
14812 var Component = readLazyComponentType(elementType);
14813 // Store the unwrapped component in the type.
14814 workInProgress.type = Component;
14815 var resolvedTag = workInProgress.tag = resolveLazyComponentTag(Component);
14816 startWorkTimer(workInProgress);
14817 var resolvedProps = resolveDefaultProps(Component, props);
14818 var child = void 0;
14819 switch (resolvedTag) {
14820 case FunctionComponent:
14821 {
14822 child = updateFunctionComponent(null, workInProgress, Component, resolvedProps, renderExpirationTime);
14823 break;
14824 }
14825 case ClassComponent:
14826 {
14827 child = updateClassComponent(null, workInProgress, Component, resolvedProps, renderExpirationTime);
14828 break;
14829 }
14830 case ForwardRef:
14831 {
14832 child = updateForwardRef(null, workInProgress, Component, resolvedProps, renderExpirationTime);
14833 break;
14834 }
14835 case MemoComponent:
14836 {
14837 {
14838 if (workInProgress.type !== workInProgress.elementType) {
14839 var outerPropTypes = Component.propTypes;
14840 if (outerPropTypes) {
14841 checkPropTypes_1(outerPropTypes, resolvedProps, // Resolved for outer only
14842 'prop', getComponentName(Component), getCurrentFiberStackInDev);
14843 }
14844 }
14845 }
14846 child = updateMemoComponent(null, workInProgress, Component, resolveDefaultProps(Component.type, resolvedProps), // The inner type can have defaults too
14847 updateExpirationTime, renderExpirationTime);
14848 break;
14849 }
14850 default:
14851 {
14852 var hint = '';
14853 {
14854 if (Component !== null && typeof Component === 'object' && Component.$$typeof === REACT_LAZY_TYPE) {
14855 hint = ' Did you wrap a component in React.lazy() more than once?';
14856 }
14857 }
14858 // This message intentionally doesn't mention ForwardRef or MemoComponent
14859 // because the fact that it's a separate type of work is an
14860 // implementation detail.
14861 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);
14862 }
14863 }
14864 return child;
14865}
14866
14867function mountIncompleteClassComponent(_current, workInProgress, Component, nextProps, renderExpirationTime) {
14868 if (_current !== null) {
14869 // An incomplete component only mounts if it suspended inside a non-
14870 // concurrent tree, in an inconsistent state. We want to treat it like
14871 // a new mount, even though an empty version of it already committed.
14872 // Disconnect the alternate pointers.
14873 _current.alternate = null;
14874 workInProgress.alternate = null;
14875 // Since this is conceptually a new fiber, schedule a Placement effect
14876 workInProgress.effectTag |= Placement;
14877 }
14878
14879 // Promote the fiber to a class and try rendering again.
14880 workInProgress.tag = ClassComponent;
14881
14882 // The rest of this function is a fork of `updateClassComponent`
14883
14884 // Push context providers early to prevent context stack mismatches.
14885 // During mounting we don't know the child context yet as the instance doesn't exist.
14886 // We will invalidate the child context in finishClassComponent() right after rendering.
14887 var hasContext = void 0;
14888 if (isContextProvider(Component)) {
14889 hasContext = true;
14890 pushContextProvider(workInProgress);
14891 } else {
14892 hasContext = false;
14893 }
14894 prepareToReadContext(workInProgress, renderExpirationTime);
14895
14896 constructClassInstance(workInProgress, Component, nextProps, renderExpirationTime);
14897 mountClassInstance(workInProgress, Component, nextProps, renderExpirationTime);
14898
14899 return finishClassComponent(null, workInProgress, Component, true, hasContext, renderExpirationTime);
14900}
14901
14902function mountIndeterminateComponent(_current, workInProgress, Component, renderExpirationTime) {
14903 if (_current !== null) {
14904 // An indeterminate component only mounts if it suspended inside a non-
14905 // concurrent tree, in an inconsistent state. We want to treat it like
14906 // a new mount, even though an empty version of it already committed.
14907 // Disconnect the alternate pointers.
14908 _current.alternate = null;
14909 workInProgress.alternate = null;
14910 // Since this is conceptually a new fiber, schedule a Placement effect
14911 workInProgress.effectTag |= Placement;
14912 }
14913
14914 var props = workInProgress.pendingProps;
14915 var unmaskedContext = getUnmaskedContext(workInProgress, Component, false);
14916 var context = getMaskedContext(workInProgress, unmaskedContext);
14917
14918 prepareToReadContext(workInProgress, renderExpirationTime);
14919 prepareToUseHooks(null, workInProgress, renderExpirationTime);
14920
14921 var value = void 0;
14922
14923 {
14924 if (Component.prototype && typeof Component.prototype.render === 'function') {
14925 var componentName = getComponentName(Component) || 'Unknown';
14926
14927 if (!didWarnAboutBadClass[componentName]) {
14928 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);
14929 didWarnAboutBadClass[componentName] = true;
14930 }
14931 }
14932
14933 if (workInProgress.mode & StrictMode) {
14934 ReactStrictModeWarnings.recordLegacyContextWarning(workInProgress, null);
14935 }
14936
14937 ReactCurrentOwner$3.current = workInProgress;
14938 value = Component(props, context);
14939 }
14940 // React DevTools reads this flag.
14941 workInProgress.effectTag |= PerformedWork;
14942
14943 if (typeof value === 'object' && value !== null && typeof value.render === 'function' && value.$$typeof === undefined) {
14944 // Proceed under the assumption that this is a class instance
14945 workInProgress.tag = ClassComponent;
14946
14947 // Throw out any hooks that were used.
14948 resetHooks();
14949
14950 // Push context providers early to prevent context stack mismatches.
14951 // During mounting we don't know the child context yet as the instance doesn't exist.
14952 // We will invalidate the child context in finishClassComponent() right after rendering.
14953 var hasContext = false;
14954 if (isContextProvider(Component)) {
14955 hasContext = true;
14956 pushContextProvider(workInProgress);
14957 } else {
14958 hasContext = false;
14959 }
14960
14961 workInProgress.memoizedState = value.state !== null && value.state !== undefined ? value.state : null;
14962
14963 var getDerivedStateFromProps = Component.getDerivedStateFromProps;
14964 if (typeof getDerivedStateFromProps === 'function') {
14965 applyDerivedStateFromProps(workInProgress, Component, getDerivedStateFromProps, props);
14966 }
14967
14968 adoptClassInstance(workInProgress, value);
14969 mountClassInstance(workInProgress, Component, props, renderExpirationTime);
14970 return finishClassComponent(null, workInProgress, Component, true, hasContext, renderExpirationTime);
14971 } else {
14972 // Proceed under the assumption that this is a function component
14973 workInProgress.tag = FunctionComponent;
14974 value = finishHooks(Component, props, value, context);
14975 reconcileChildren(null, workInProgress, value, renderExpirationTime);
14976 {
14977 validateFunctionComponentInDev(workInProgress, Component);
14978 }
14979 return workInProgress.child;
14980 }
14981}
14982
14983function validateFunctionComponentInDev(workInProgress, Component) {
14984 if (Component) {
14985 !!Component.childContextTypes ? warningWithoutStack$1(false, '%s(...): childContextTypes cannot be defined on a function component.', Component.displayName || Component.name || 'Component') : void 0;
14986 }
14987 if (workInProgress.ref !== null) {
14988 var info = '';
14989 var ownerName = getCurrentFiberOwnerNameInDevOrNull();
14990 if (ownerName) {
14991 info += '\n\nCheck the render method of `' + ownerName + '`.';
14992 }
14993
14994 var warningKey = ownerName || workInProgress._debugID || '';
14995 var debugSource = workInProgress._debugSource;
14996 if (debugSource) {
14997 warningKey = debugSource.fileName + ':' + debugSource.lineNumber;
14998 }
14999 if (!didWarnAboutFunctionRefs[warningKey]) {
15000 didWarnAboutFunctionRefs[warningKey] = true;
15001 warning$1(false, 'Function components cannot be given refs. ' + 'Attempts to access this ref will fail.%s', info);
15002 }
15003 }
15004
15005 if (typeof Component.getDerivedStateFromProps === 'function') {
15006 var componentName = getComponentName(Component) || 'Unknown';
15007
15008 if (!didWarnAboutGetDerivedStateOnFunctionComponent[componentName]) {
15009 warningWithoutStack$1(false, '%s: Function components do not support getDerivedStateFromProps.', componentName);
15010 didWarnAboutGetDerivedStateOnFunctionComponent[componentName] = true;
15011 }
15012 }
15013
15014 if (typeof Component.contextType === 'object' && Component.contextType !== null) {
15015 var _componentName = getComponentName(Component) || 'Unknown';
15016
15017 if (!didWarnAboutContextTypeOnFunctionComponent[_componentName]) {
15018 warningWithoutStack$1(false, '%s: Function components do not support contextType.', _componentName);
15019 didWarnAboutContextTypeOnFunctionComponent[_componentName] = true;
15020 }
15021 }
15022}
15023
15024function updateSuspenseComponent(current$$1, workInProgress, renderExpirationTime) {
15025 var mode = workInProgress.mode;
15026 var nextProps = workInProgress.pendingProps;
15027
15028 // We should attempt to render the primary children unless this boundary
15029 // already suspended during this render (`alreadyCaptured` is true).
15030 var nextState = workInProgress.memoizedState;
15031
15032 var nextDidTimeout = void 0;
15033 if ((workInProgress.effectTag & DidCapture) === NoEffect) {
15034 // This is the first attempt.
15035 nextState = null;
15036 nextDidTimeout = false;
15037 } else {
15038 // Something in this boundary's subtree already suspended. Switch to
15039 // rendering the fallback children.
15040 nextState = {
15041 timedOutAt: nextState !== null ? nextState.timedOutAt : NoWork
15042 };
15043 nextDidTimeout = true;
15044 workInProgress.effectTag &= ~DidCapture;
15045 }
15046
15047 // This next part is a bit confusing. If the children timeout, we switch to
15048 // showing the fallback children in place of the "primary" children.
15049 // However, we don't want to delete the primary children because then their
15050 // state will be lost (both the React state and the host state, e.g.
15051 // uncontrolled form inputs). Instead we keep them mounted and hide them.
15052 // Both the fallback children AND the primary children are rendered at the
15053 // same time. Once the primary children are un-suspended, we can delete
15054 // the fallback children — don't need to preserve their state.
15055 //
15056 // The two sets of children are siblings in the host environment, but
15057 // semantically, for purposes of reconciliation, they are two separate sets.
15058 // So we store them using two fragment fibers.
15059 //
15060 // However, we want to avoid allocating extra fibers for every placeholder.
15061 // They're only necessary when the children time out, because that's the
15062 // only time when both sets are mounted.
15063 //
15064 // So, the extra fragment fibers are only used if the children time out.
15065 // Otherwise, we render the primary children directly. This requires some
15066 // custom reconciliation logic to preserve the state of the primary
15067 // children. It's essentially a very basic form of re-parenting.
15068
15069 // `child` points to the child fiber. In the normal case, this is the first
15070 // fiber of the primary children set. In the timed-out case, it's a
15071 // a fragment fiber containing the primary children.
15072 var child = void 0;
15073 // `next` points to the next fiber React should render. In the normal case,
15074 // it's the same as `child`: the first fiber of the primary children set.
15075 // In the timed-out case, it's a fragment fiber containing the *fallback*
15076 // children -- we skip over the primary children entirely.
15077 var next = void 0;
15078 if (current$$1 === null) {
15079 // This is the initial mount. This branch is pretty simple because there's
15080 // no previous state that needs to be preserved.
15081 if (nextDidTimeout) {
15082 // Mount separate fragments for primary and fallback children.
15083 var nextFallbackChildren = nextProps.fallback;
15084 var primaryChildFragment = createFiberFromFragment(null, mode, NoWork, null);
15085
15086 if ((workInProgress.mode & ConcurrentMode) === NoContext) {
15087 // Outside of concurrent mode, we commit the effects from the
15088 var progressedState = workInProgress.memoizedState;
15089 var progressedPrimaryChild = progressedState !== null ? workInProgress.child.child : workInProgress.child;
15090 primaryChildFragment.child = progressedPrimaryChild;
15091 }
15092
15093 var fallbackChildFragment = createFiberFromFragment(nextFallbackChildren, mode, renderExpirationTime, null);
15094 primaryChildFragment.sibling = fallbackChildFragment;
15095 child = primaryChildFragment;
15096 // Skip the primary children, and continue working on the
15097 // fallback children.
15098 next = fallbackChildFragment;
15099 child.return = next.return = workInProgress;
15100 } else {
15101 // Mount the primary children without an intermediate fragment fiber.
15102 var nextPrimaryChildren = nextProps.children;
15103 child = next = mountChildFibers(workInProgress, null, nextPrimaryChildren, renderExpirationTime);
15104 }
15105 } else {
15106 // This is an update. This branch is more complicated because we need to
15107 // ensure the state of the primary children is preserved.
15108 var prevState = current$$1.memoizedState;
15109 var prevDidTimeout = prevState !== null;
15110 if (prevDidTimeout) {
15111 // The current tree already timed out. That means each child set is
15112 var currentPrimaryChildFragment = current$$1.child;
15113 var currentFallbackChildFragment = currentPrimaryChildFragment.sibling;
15114 if (nextDidTimeout) {
15115 // Still timed out. Reuse the current primary children by cloning
15116 // its fragment. We're going to skip over these entirely.
15117 var _nextFallbackChildren = nextProps.fallback;
15118 var _primaryChildFragment = createWorkInProgress(currentPrimaryChildFragment, currentPrimaryChildFragment.pendingProps, NoWork);
15119
15120 if ((workInProgress.mode & ConcurrentMode) === NoContext) {
15121 // Outside of concurrent mode, we commit the effects from the
15122 var _progressedState = workInProgress.memoizedState;
15123 var _progressedPrimaryChild = _progressedState !== null ? workInProgress.child.child : workInProgress.child;
15124 if (_progressedPrimaryChild !== currentPrimaryChildFragment.child) {
15125 _primaryChildFragment.child = _progressedPrimaryChild;
15126 }
15127 }
15128
15129 // Because primaryChildFragment is a new fiber that we're inserting as the
15130 // parent of a new tree, we need to set its treeBaseDuration.
15131 if (enableProfilerTimer && workInProgress.mode & ProfileMode) {
15132 // treeBaseDuration is the sum of all the child tree base durations.
15133 var treeBaseDuration = 0;
15134 var hiddenChild = _primaryChildFragment.child;
15135 while (hiddenChild !== null) {
15136 treeBaseDuration += hiddenChild.treeBaseDuration;
15137 hiddenChild = hiddenChild.sibling;
15138 }
15139 _primaryChildFragment.treeBaseDuration = treeBaseDuration;
15140 }
15141
15142 // Clone the fallback child fragment, too. These we'll continue
15143 // working on.
15144 var _fallbackChildFragment = _primaryChildFragment.sibling = createWorkInProgress(currentFallbackChildFragment, _nextFallbackChildren, currentFallbackChildFragment.expirationTime);
15145 child = _primaryChildFragment;
15146 _primaryChildFragment.childExpirationTime = NoWork;
15147 // Skip the primary children, and continue working on the
15148 // fallback children.
15149 next = _fallbackChildFragment;
15150 child.return = next.return = workInProgress;
15151 } else {
15152 // No longer suspended. Switch back to showing the primary children,
15153 // and remove the intermediate fragment fiber.
15154 var _nextPrimaryChildren = nextProps.children;
15155 var currentPrimaryChild = currentPrimaryChildFragment.child;
15156 var primaryChild = reconcileChildFibers(workInProgress, currentPrimaryChild, _nextPrimaryChildren, renderExpirationTime);
15157
15158 // If this render doesn't suspend, we need to delete the fallback
15159 // children. Wait until the complete phase, after we've confirmed the
15160 // fallback is no longer needed.
15161 // TODO: Would it be better to store the fallback fragment on
15162 // the stateNode?
15163
15164 // Continue rendering the children, like we normally do.
15165 child = next = primaryChild;
15166 }
15167 } else {
15168 // The current tree has not already timed out. That means the primary
15169 // children are not wrapped in a fragment fiber.
15170 var _currentPrimaryChild = current$$1.child;
15171 if (nextDidTimeout) {
15172 // Timed out. Wrap the children in a fragment fiber to keep them
15173 // separate from the fallback children.
15174 var _nextFallbackChildren2 = nextProps.fallback;
15175 var _primaryChildFragment2 = createFiberFromFragment(
15176 // It shouldn't matter what the pending props are because we aren't
15177 // going to render this fragment.
15178 null, mode, NoWork, null);
15179 _primaryChildFragment2.child = _currentPrimaryChild;
15180
15181 // Even though we're creating a new fiber, there are no new children,
15182 // because we're reusing an already mounted tree. So we don't need to
15183 // schedule a placement.
15184 // primaryChildFragment.effectTag |= Placement;
15185
15186 if ((workInProgress.mode & ConcurrentMode) === NoContext) {
15187 // Outside of concurrent mode, we commit the effects from the
15188 var _progressedState2 = workInProgress.memoizedState;
15189 var _progressedPrimaryChild2 = _progressedState2 !== null ? workInProgress.child.child : workInProgress.child;
15190 _primaryChildFragment2.child = _progressedPrimaryChild2;
15191 }
15192
15193 // Because primaryChildFragment is a new fiber that we're inserting as the
15194 // parent of a new tree, we need to set its treeBaseDuration.
15195 if (enableProfilerTimer && workInProgress.mode & ProfileMode) {
15196 // treeBaseDuration is the sum of all the child tree base durations.
15197 var _treeBaseDuration = 0;
15198 var _hiddenChild = _primaryChildFragment2.child;
15199 while (_hiddenChild !== null) {
15200 _treeBaseDuration += _hiddenChild.treeBaseDuration;
15201 _hiddenChild = _hiddenChild.sibling;
15202 }
15203 _primaryChildFragment2.treeBaseDuration = _treeBaseDuration;
15204 }
15205
15206 // Create a fragment from the fallback children, too.
15207 var _fallbackChildFragment2 = _primaryChildFragment2.sibling = createFiberFromFragment(_nextFallbackChildren2, mode, renderExpirationTime, null);
15208 _fallbackChildFragment2.effectTag |= Placement;
15209 child = _primaryChildFragment2;
15210 _primaryChildFragment2.childExpirationTime = NoWork;
15211 // Skip the primary children, and continue working on the
15212 // fallback children.
15213 next = _fallbackChildFragment2;
15214 child.return = next.return = workInProgress;
15215 } else {
15216 // Still haven't timed out. Continue rendering the children, like we
15217 // normally do.
15218 var _nextPrimaryChildren2 = nextProps.children;
15219 next = child = reconcileChildFibers(workInProgress, _currentPrimaryChild, _nextPrimaryChildren2, renderExpirationTime);
15220 }
15221 }
15222 workInProgress.stateNode = current$$1.stateNode;
15223 }
15224
15225 workInProgress.memoizedState = nextState;
15226 workInProgress.child = child;
15227 return next;
15228}
15229
15230function updatePortalComponent(current$$1, workInProgress, renderExpirationTime) {
15231 pushHostContainer(workInProgress, workInProgress.stateNode.containerInfo);
15232 var nextChildren = workInProgress.pendingProps;
15233 if (current$$1 === null) {
15234 // Portals are special because we don't append the children during mount
15235 // but at commit. Therefore we need to track insertions which the normal
15236 // flow doesn't do during mount. This doesn't happen at the root because
15237 // the root always starts with a "current" with a null child.
15238 // TODO: Consider unifying this with how the root works.
15239 workInProgress.child = reconcileChildFibers(workInProgress, null, nextChildren, renderExpirationTime);
15240 } else {
15241 reconcileChildren(current$$1, workInProgress, nextChildren, renderExpirationTime);
15242 }
15243 return workInProgress.child;
15244}
15245
15246function updateContextProvider(current$$1, workInProgress, renderExpirationTime) {
15247 var providerType = workInProgress.type;
15248 var context = providerType._context;
15249
15250 var newProps = workInProgress.pendingProps;
15251 var oldProps = workInProgress.memoizedProps;
15252
15253 var newValue = newProps.value;
15254
15255 {
15256 var providerPropTypes = workInProgress.type.propTypes;
15257
15258 if (providerPropTypes) {
15259 checkPropTypes_1(providerPropTypes, newProps, 'prop', 'Context.Provider', getCurrentFiberStackInDev);
15260 }
15261 }
15262
15263 pushProvider(workInProgress, newValue);
15264
15265 if (oldProps !== null) {
15266 var oldValue = oldProps.value;
15267 var changedBits = calculateChangedBits(context, newValue, oldValue);
15268 if (changedBits === 0) {
15269 // No change. Bailout early if children are the same.
15270 if (oldProps.children === newProps.children && !hasContextChanged()) {
15271 return bailoutOnAlreadyFinishedWork(current$$1, workInProgress, renderExpirationTime);
15272 }
15273 } else {
15274 // The context value changed. Search for matching consumers and schedule
15275 // them to update.
15276 propagateContextChange(workInProgress, context, changedBits, renderExpirationTime);
15277 }
15278 }
15279
15280 var newChildren = newProps.children;
15281 reconcileChildren(current$$1, workInProgress, newChildren, renderExpirationTime);
15282 return workInProgress.child;
15283}
15284
15285var hasWarnedAboutUsingContextAsConsumer = false;
15286
15287function updateContextConsumer(current$$1, workInProgress, renderExpirationTime) {
15288 var context = workInProgress.type;
15289 // The logic below for Context differs depending on PROD or DEV mode. In
15290 // DEV mode, we create a separate object for Context.Consumer that acts
15291 // like a proxy to Context. This proxy object adds unnecessary code in PROD
15292 // so we use the old behaviour (Context.Consumer references Context) to
15293 // reduce size and overhead. The separate object references context via
15294 // a property called "_context", which also gives us the ability to check
15295 // in DEV mode if this property exists or not and warn if it does not.
15296 {
15297 if (context._context === undefined) {
15298 // This may be because it's a Context (rather than a Consumer).
15299 // Or it may be because it's older React where they're the same thing.
15300 // We only want to warn if we're sure it's a new React.
15301 if (context !== context.Consumer) {
15302 if (!hasWarnedAboutUsingContextAsConsumer) {
15303 hasWarnedAboutUsingContextAsConsumer = true;
15304 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?');
15305 }
15306 }
15307 } else {
15308 context = context._context;
15309 }
15310 }
15311 var newProps = workInProgress.pendingProps;
15312 var render = newProps.children;
15313
15314 {
15315 !(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;
15316 }
15317
15318 prepareToReadContext(workInProgress, renderExpirationTime);
15319 var newValue = readContext(context, newProps.unstable_observedBits);
15320 var newChildren = void 0;
15321 {
15322 ReactCurrentOwner$3.current = workInProgress;
15323 setCurrentPhase('render');
15324 newChildren = render(newValue);
15325 setCurrentPhase(null);
15326 }
15327
15328 // React DevTools reads this flag.
15329 workInProgress.effectTag |= PerformedWork;
15330 reconcileChildren(current$$1, workInProgress, newChildren, renderExpirationTime);
15331 return workInProgress.child;
15332}
15333
15334function bailoutOnAlreadyFinishedWork(current$$1, workInProgress, renderExpirationTime) {
15335 cancelWorkTimer(workInProgress);
15336
15337 if (current$$1 !== null) {
15338 // Reuse previous context list
15339 workInProgress.firstContextDependency = current$$1.firstContextDependency;
15340 }
15341
15342 if (enableProfilerTimer) {
15343 // Don't update "base" render times for bailouts.
15344 stopProfilerTimerIfRunning(workInProgress);
15345 }
15346
15347 // Check if the children have any pending work.
15348 var childExpirationTime = workInProgress.childExpirationTime;
15349 if (childExpirationTime < renderExpirationTime) {
15350 // The children don't have any work either. We can skip them.
15351 // TODO: Once we add back resuming, we should check if the children are
15352 // a work-in-progress set. If so, we need to transfer their effects.
15353 return null;
15354 } else {
15355 // This fiber doesn't have work, but its subtree does. Clone the child
15356 // fibers and continue.
15357 cloneChildFibers(current$$1, workInProgress);
15358 return workInProgress.child;
15359 }
15360}
15361
15362function beginWork(current$$1, workInProgress, renderExpirationTime) {
15363 var updateExpirationTime = workInProgress.expirationTime;
15364
15365 if (current$$1 !== null) {
15366 var oldProps = current$$1.memoizedProps;
15367 var newProps = workInProgress.pendingProps;
15368 if (oldProps === newProps && !hasContextChanged() && updateExpirationTime < renderExpirationTime) {
15369 // This fiber does not have any pending work. Bailout without entering
15370 // the begin phase. There's still some bookkeeping we that needs to be done
15371 // in this optimized path, mostly pushing stuff onto the stack.
15372 switch (workInProgress.tag) {
15373 case HostRoot:
15374 pushHostRootContext(workInProgress);
15375 resetHydrationState();
15376 break;
15377 case HostComponent:
15378 pushHostContext(workInProgress);
15379 break;
15380 case ClassComponent:
15381 {
15382 var Component = workInProgress.type;
15383 if (isContextProvider(Component)) {
15384 pushContextProvider(workInProgress);
15385 }
15386 break;
15387 }
15388 case HostPortal:
15389 pushHostContainer(workInProgress, workInProgress.stateNode.containerInfo);
15390 break;
15391 case ContextProvider:
15392 {
15393 var newValue = workInProgress.memoizedProps.value;
15394 pushProvider(workInProgress, newValue);
15395 break;
15396 }
15397 case Profiler:
15398 if (enableProfilerTimer) {
15399 workInProgress.effectTag |= Update;
15400 }
15401 break;
15402 case SuspenseComponent:
15403 {
15404 var state = workInProgress.memoizedState;
15405 var didTimeout = state !== null;
15406 if (didTimeout) {
15407 // If this boundary is currently timed out, we need to decide
15408 // whether to retry the primary children, or to skip over it and
15409 // go straight to the fallback. Check the priority of the primary
15410 var primaryChildFragment = workInProgress.child;
15411 var primaryChildExpirationTime = primaryChildFragment.childExpirationTime;
15412 if (primaryChildExpirationTime !== NoWork && primaryChildExpirationTime >= renderExpirationTime) {
15413 // The primary children have pending work. Use the normal path
15414 // to attempt to render the primary children again.
15415 return updateSuspenseComponent(current$$1, workInProgress, renderExpirationTime);
15416 } else {
15417 // The primary children do not have pending work with sufficient
15418 // priority. Bailout.
15419 var child = bailoutOnAlreadyFinishedWork(current$$1, workInProgress, renderExpirationTime);
15420 if (child !== null) {
15421 // The fallback children have pending work. Skip over the
15422 // primary children and work on the fallback.
15423 return child.sibling;
15424 } else {
15425 return null;
15426 }
15427 }
15428 }
15429 break;
15430 }
15431 }
15432 return bailoutOnAlreadyFinishedWork(current$$1, workInProgress, renderExpirationTime);
15433 }
15434 }
15435
15436 // Before entering the begin phase, clear the expiration time.
15437 workInProgress.expirationTime = NoWork;
15438
15439 switch (workInProgress.tag) {
15440 case IndeterminateComponent:
15441 {
15442 var elementType = workInProgress.elementType;
15443 return mountIndeterminateComponent(current$$1, workInProgress, elementType, renderExpirationTime);
15444 }
15445 case LazyComponent:
15446 {
15447 var _elementType = workInProgress.elementType;
15448 return mountLazyComponent(current$$1, workInProgress, _elementType, updateExpirationTime, renderExpirationTime);
15449 }
15450 case FunctionComponent:
15451 {
15452 var _Component = workInProgress.type;
15453 var unresolvedProps = workInProgress.pendingProps;
15454 var resolvedProps = workInProgress.elementType === _Component ? unresolvedProps : resolveDefaultProps(_Component, unresolvedProps);
15455 return updateFunctionComponent(current$$1, workInProgress, _Component, resolvedProps, renderExpirationTime);
15456 }
15457 case ClassComponent:
15458 {
15459 var _Component2 = workInProgress.type;
15460 var _unresolvedProps = workInProgress.pendingProps;
15461 var _resolvedProps = workInProgress.elementType === _Component2 ? _unresolvedProps : resolveDefaultProps(_Component2, _unresolvedProps);
15462 return updateClassComponent(current$$1, workInProgress, _Component2, _resolvedProps, renderExpirationTime);
15463 }
15464 case HostRoot:
15465 return updateHostRoot(current$$1, workInProgress, renderExpirationTime);
15466 case HostComponent:
15467 return updateHostComponent(current$$1, workInProgress, renderExpirationTime);
15468 case HostText:
15469 return updateHostText(current$$1, workInProgress);
15470 case SuspenseComponent:
15471 return updateSuspenseComponent(current$$1, workInProgress, renderExpirationTime);
15472 case HostPortal:
15473 return updatePortalComponent(current$$1, workInProgress, renderExpirationTime);
15474 case ForwardRef:
15475 {
15476 var type = workInProgress.type;
15477 var _unresolvedProps2 = workInProgress.pendingProps;
15478 var _resolvedProps2 = workInProgress.elementType === type ? _unresolvedProps2 : resolveDefaultProps(type, _unresolvedProps2);
15479 return updateForwardRef(current$$1, workInProgress, type, _resolvedProps2, renderExpirationTime);
15480 }
15481 case Fragment:
15482 return updateFragment(current$$1, workInProgress, renderExpirationTime);
15483 case Mode:
15484 return updateMode(current$$1, workInProgress, renderExpirationTime);
15485 case Profiler:
15486 return updateProfiler(current$$1, workInProgress, renderExpirationTime);
15487 case ContextProvider:
15488 return updateContextProvider(current$$1, workInProgress, renderExpirationTime);
15489 case ContextConsumer:
15490 return updateContextConsumer(current$$1, workInProgress, renderExpirationTime);
15491 case MemoComponent:
15492 {
15493 var _type2 = workInProgress.type;
15494 var _unresolvedProps3 = workInProgress.pendingProps;
15495 // Resolve outer props first, then resolve inner props.
15496 var _resolvedProps3 = resolveDefaultProps(_type2, _unresolvedProps3);
15497 {
15498 if (workInProgress.type !== workInProgress.elementType) {
15499 var outerPropTypes = _type2.propTypes;
15500 if (outerPropTypes) {
15501 checkPropTypes_1(outerPropTypes, _resolvedProps3, // Resolved for outer only
15502 'prop', getComponentName(_type2), getCurrentFiberStackInDev);
15503 }
15504 }
15505 }
15506 _resolvedProps3 = resolveDefaultProps(_type2.type, _resolvedProps3);
15507 return updateMemoComponent(current$$1, workInProgress, _type2, _resolvedProps3, updateExpirationTime, renderExpirationTime);
15508 }
15509 case SimpleMemoComponent:
15510 {
15511 return updateSimpleMemoComponent(current$$1, workInProgress, workInProgress.type, workInProgress.pendingProps, updateExpirationTime, renderExpirationTime);
15512 }
15513 case IncompleteClassComponent:
15514 {
15515 var _Component3 = workInProgress.type;
15516 var _unresolvedProps4 = workInProgress.pendingProps;
15517 var _resolvedProps4 = workInProgress.elementType === _Component3 ? _unresolvedProps4 : resolveDefaultProps(_Component3, _unresolvedProps4);
15518 return mountIncompleteClassComponent(current$$1, workInProgress, _Component3, _resolvedProps4, renderExpirationTime);
15519 }
15520 default:
15521 invariant(false, 'Unknown unit of work tag. This error is likely caused by a bug in React. Please file an issue.');
15522 }
15523}
15524
15525function markUpdate(workInProgress) {
15526 // Tag the fiber with an update effect. This turns a Placement into
15527 // a PlacementAndUpdate.
15528 workInProgress.effectTag |= Update;
15529}
15530
15531function markRef$1(workInProgress) {
15532 workInProgress.effectTag |= Ref;
15533}
15534
15535var appendAllChildren = void 0;
15536var updateHostContainer = void 0;
15537var updateHostComponent$1 = void 0;
15538var updateHostText$1 = void 0;
15539if (supportsMutation) {
15540 // Mutation mode
15541
15542 appendAllChildren = function (parent, workInProgress, needsVisibilityToggle, isHidden) {
15543 // We only have the top Fiber that was created but we need recurse down its
15544 // children to find all the terminal nodes.
15545 var node = workInProgress.child;
15546 while (node !== null) {
15547 if (node.tag === HostComponent || node.tag === HostText) {
15548 appendInitialChild(parent, node.stateNode);
15549 } else if (node.tag === HostPortal) {
15550 // If we have a portal child, then we don't want to traverse
15551 // down its children. Instead, we'll get insertions from each child in
15552 // the portal directly.
15553 } else if (node.child !== null) {
15554 node.child.return = node;
15555 node = node.child;
15556 continue;
15557 }
15558 if (node === workInProgress) {
15559 return;
15560 }
15561 while (node.sibling === null) {
15562 if (node.return === null || node.return === workInProgress) {
15563 return;
15564 }
15565 node = node.return;
15566 }
15567 node.sibling.return = node.return;
15568 node = node.sibling;
15569 }
15570 };
15571
15572 updateHostContainer = function (workInProgress) {
15573 // Noop
15574 };
15575 updateHostComponent$1 = function (current, workInProgress, type, newProps, rootContainerInstance) {
15576 // If we have an alternate, that means this is an update and we need to
15577 // schedule a side-effect to do the updates.
15578 var oldProps = current.memoizedProps;
15579 if (oldProps === newProps) {
15580 // In mutation mode, this is sufficient for a bailout because
15581 // we won't touch this node even if children changed.
15582 return;
15583 }
15584
15585 // If we get updated because one of our children updated, we don't
15586 // have newProps so we'll have to reuse them.
15587 // TODO: Split the update API as separate for the props vs. children.
15588 // Even better would be if children weren't special cased at all tho.
15589 var instance = workInProgress.stateNode;
15590 var currentHostContext = getHostContext();
15591 // TODO: Experiencing an error where oldProps is null. Suggests a host
15592 // component is hitting the resume path. Figure out why. Possibly
15593 // related to `hidden`.
15594 var updatePayload = prepareUpdate(instance, type, oldProps, newProps, rootContainerInstance, currentHostContext);
15595 // TODO: Type this specific to this type of component.
15596 workInProgress.updateQueue = updatePayload;
15597 // If the update payload indicates that there is a change or if there
15598 // is a new ref we mark this as an update. All the work is done in commitWork.
15599 if (updatePayload) {
15600 markUpdate(workInProgress);
15601 }
15602 };
15603 updateHostText$1 = function (current, workInProgress, oldText, newText) {
15604 // If the text differs, mark it as an update. All the work in done in commitWork.
15605 if (oldText !== newText) {
15606 markUpdate(workInProgress);
15607 }
15608 };
15609} else if (supportsPersistence) {
15610 // Persistent host tree mode
15611
15612 appendAllChildren = function (parent, workInProgress, needsVisibilityToggle, isHidden) {
15613 // We only have the top Fiber that was created but we need recurse down its
15614 // children to find all the terminal nodes.
15615 var node = workInProgress.child;
15616 while (node !== null) {
15617 // eslint-disable-next-line no-labels
15618 branches: if (node.tag === HostComponent) {
15619 var instance = node.stateNode;
15620 if (needsVisibilityToggle) {
15621 var props = node.memoizedProps;
15622 var type = node.type;
15623 if (isHidden) {
15624 // This child is inside a timed out tree. Hide it.
15625 instance = cloneHiddenInstance(instance, type, props, node);
15626 } else {
15627 // This child was previously inside a timed out tree. If it was not
15628 // updated during this render, it may need to be unhidden. Clone
15629 // again to be sure.
15630 instance = cloneUnhiddenInstance(instance, type, props, node);
15631 }
15632 node.stateNode = instance;
15633 }
15634 appendInitialChild(parent, instance);
15635 } else if (node.tag === HostText) {
15636 var _instance = node.stateNode;
15637 if (needsVisibilityToggle) {
15638 var text = node.memoizedProps;
15639 var rootContainerInstance = getRootHostContainer();
15640 var currentHostContext = getHostContext();
15641 if (isHidden) {
15642 _instance = createHiddenTextInstance(text, rootContainerInstance, currentHostContext, workInProgress);
15643 } else {
15644 _instance = createTextInstance(text, rootContainerInstance, currentHostContext, workInProgress);
15645 }
15646 node.stateNode = _instance;
15647 }
15648 appendInitialChild(parent, _instance);
15649 } else if (node.tag === HostPortal) {
15650 // If we have a portal child, then we don't want to traverse
15651 // down its children. Instead, we'll get insertions from each child in
15652 // the portal directly.
15653 } else if (node.tag === SuspenseComponent) {
15654 var current = node.alternate;
15655 if (current !== null) {
15656 var oldState = current.memoizedState;
15657 var newState = node.memoizedState;
15658 var oldIsHidden = oldState !== null;
15659 var newIsHidden = newState !== null;
15660 if (oldIsHidden !== newIsHidden) {
15661 // The placeholder either just timed out or switched back to the normal
15662 // children after having previously timed out. Toggle the visibility of
15663 // the direct host children.
15664 var primaryChildParent = newIsHidden ? node.child : node;
15665 if (primaryChildParent !== null) {
15666 appendAllChildren(parent, primaryChildParent, true, newIsHidden);
15667 }
15668 // eslint-disable-next-line no-labels
15669 break branches;
15670 }
15671 }
15672 if (node.child !== null) {
15673 // Continue traversing like normal
15674 node.child.return = node;
15675 node = node.child;
15676 continue;
15677 }
15678 } else if (node.child !== null) {
15679 node.child.return = node;
15680 node = node.child;
15681 continue;
15682 }
15683 // $FlowFixMe This is correct but Flow is confused by the labeled break.
15684 node = node;
15685 if (node === workInProgress) {
15686 return;
15687 }
15688 while (node.sibling === null) {
15689 if (node.return === null || node.return === workInProgress) {
15690 return;
15691 }
15692 node = node.return;
15693 }
15694 node.sibling.return = node.return;
15695 node = node.sibling;
15696 }
15697 };
15698
15699 // An unfortunate fork of appendAllChildren because we have two different parent types.
15700 var appendAllChildrenToContainer = function (containerChildSet, workInProgress, needsVisibilityToggle, isHidden) {
15701 // We only have the top Fiber that was created but we need recurse down its
15702 // children to find all the terminal nodes.
15703 var node = workInProgress.child;
15704 while (node !== null) {
15705 // eslint-disable-next-line no-labels
15706 branches: if (node.tag === HostComponent) {
15707 var instance = node.stateNode;
15708 if (needsVisibilityToggle) {
15709 var props = node.memoizedProps;
15710 var type = node.type;
15711 if (isHidden) {
15712 // This child is inside a timed out tree. Hide it.
15713 instance = cloneHiddenInstance(instance, type, props, node);
15714 } else {
15715 // This child was previously inside a timed out tree. If it was not
15716 // updated during this render, it may need to be unhidden. Clone
15717 // again to be sure.
15718 instance = cloneUnhiddenInstance(instance, type, props, node);
15719 }
15720 node.stateNode = instance;
15721 }
15722 appendChildToContainerChildSet(containerChildSet, instance);
15723 } else if (node.tag === HostText) {
15724 var _instance2 = node.stateNode;
15725 if (needsVisibilityToggle) {
15726 var text = node.memoizedProps;
15727 var rootContainerInstance = getRootHostContainer();
15728 var currentHostContext = getHostContext();
15729 if (isHidden) {
15730 _instance2 = createHiddenTextInstance(text, rootContainerInstance, currentHostContext, workInProgress);
15731 } else {
15732 _instance2 = createTextInstance(text, rootContainerInstance, currentHostContext, workInProgress);
15733 }
15734 node.stateNode = _instance2;
15735 }
15736 appendChildToContainerChildSet(containerChildSet, _instance2);
15737 } else if (node.tag === HostPortal) {
15738 // If we have a portal child, then we don't want to traverse
15739 // down its children. Instead, we'll get insertions from each child in
15740 // the portal directly.
15741 } else if (node.tag === SuspenseComponent) {
15742 var current = node.alternate;
15743 if (current !== null) {
15744 var oldState = current.memoizedState;
15745 var newState = node.memoizedState;
15746 var oldIsHidden = oldState !== null;
15747 var newIsHidden = newState !== null;
15748 if (oldIsHidden !== newIsHidden) {
15749 // The placeholder either just timed out or switched back to the normal
15750 // children after having previously timed out. Toggle the visibility of
15751 // the direct host children.
15752 var primaryChildParent = newIsHidden ? node.child : node;
15753 if (primaryChildParent !== null) {
15754 appendAllChildrenToContainer(containerChildSet, primaryChildParent, true, newIsHidden);
15755 }
15756 // eslint-disable-next-line no-labels
15757 break branches;
15758 }
15759 }
15760 if (node.child !== null) {
15761 // Continue traversing like normal
15762 node.child.return = node;
15763 node = node.child;
15764 continue;
15765 }
15766 } else if (node.child !== null) {
15767 node.child.return = node;
15768 node = node.child;
15769 continue;
15770 }
15771 // $FlowFixMe This is correct but Flow is confused by the labeled break.
15772 node = node;
15773 if (node === workInProgress) {
15774 return;
15775 }
15776 while (node.sibling === null) {
15777 if (node.return === null || node.return === workInProgress) {
15778 return;
15779 }
15780 node = node.return;
15781 }
15782 node.sibling.return = node.return;
15783 node = node.sibling;
15784 }
15785 };
15786 updateHostContainer = function (workInProgress) {
15787 var portalOrRoot = workInProgress.stateNode;
15788 var childrenUnchanged = workInProgress.firstEffect === null;
15789 if (childrenUnchanged) {
15790 // No changes, just reuse the existing instance.
15791 } else {
15792 var container = portalOrRoot.containerInfo;
15793 var newChildSet = createContainerChildSet(container);
15794 // If children might have changed, we have to add them all to the set.
15795 appendAllChildrenToContainer(newChildSet, workInProgress, false, false);
15796 portalOrRoot.pendingChildren = newChildSet;
15797 // Schedule an update on the container to swap out the container.
15798 markUpdate(workInProgress);
15799 finalizeContainerChildren(container, newChildSet);
15800 }
15801 };
15802 updateHostComponent$1 = function (current, workInProgress, type, newProps, rootContainerInstance) {
15803 var currentInstance = current.stateNode;
15804 var oldProps = current.memoizedProps;
15805 // If there are no effects associated with this node, then none of our children had any updates.
15806 // This guarantees that we can reuse all of them.
15807 var childrenUnchanged = workInProgress.firstEffect === null;
15808 if (childrenUnchanged && oldProps === newProps) {
15809 // No changes, just reuse the existing instance.
15810 // Note that this might release a previous clone.
15811 workInProgress.stateNode = currentInstance;
15812 return;
15813 }
15814 var recyclableInstance = workInProgress.stateNode;
15815 var currentHostContext = getHostContext();
15816 var updatePayload = null;
15817 if (oldProps !== newProps) {
15818 updatePayload = prepareUpdate(recyclableInstance, type, oldProps, newProps, rootContainerInstance, currentHostContext);
15819 }
15820 if (childrenUnchanged && updatePayload === null) {
15821 // No changes, just reuse the existing instance.
15822 // Note that this might release a previous clone.
15823 workInProgress.stateNode = currentInstance;
15824 return;
15825 }
15826 var newInstance = cloneInstance(currentInstance, updatePayload, type, oldProps, newProps, workInProgress, childrenUnchanged, recyclableInstance);
15827 if (finalizeInitialChildren(newInstance, type, newProps, rootContainerInstance, currentHostContext)) {
15828 markUpdate(workInProgress);
15829 }
15830 workInProgress.stateNode = newInstance;
15831 if (childrenUnchanged) {
15832 // If there are no other effects in this tree, we need to flag this node as having one.
15833 // Even though we're not going to use it for anything.
15834 // Otherwise parents won't know that there are new children to propagate upwards.
15835 markUpdate(workInProgress);
15836 } else {
15837 // If children might have changed, we have to add them all to the set.
15838 appendAllChildren(newInstance, workInProgress, false, false);
15839 }
15840 };
15841 updateHostText$1 = function (current, workInProgress, oldText, newText) {
15842 if (oldText !== newText) {
15843 // If the text content differs, we'll create a new text instance for it.
15844 var rootContainerInstance = getRootHostContainer();
15845 var currentHostContext = getHostContext();
15846 workInProgress.stateNode = createTextInstance(newText, rootContainerInstance, currentHostContext, workInProgress);
15847 // We'll have to mark it as having an effect, even though we won't use the effect for anything.
15848 // This lets the parents know that at least one of their children has changed.
15849 markUpdate(workInProgress);
15850 }
15851 };
15852} else {
15853 // No host operations
15854 updateHostContainer = function (workInProgress) {
15855 // Noop
15856 };
15857 updateHostComponent$1 = function (current, workInProgress, type, newProps, rootContainerInstance) {
15858 // Noop
15859 };
15860 updateHostText$1 = function (current, workInProgress, oldText, newText) {
15861 // Noop
15862 };
15863}
15864
15865function completeWork(current, workInProgress, renderExpirationTime) {
15866 var newProps = workInProgress.pendingProps;
15867
15868 switch (workInProgress.tag) {
15869 case IndeterminateComponent:
15870 break;
15871 case LazyComponent:
15872 break;
15873 case SimpleMemoComponent:
15874 case FunctionComponent:
15875 break;
15876 case ClassComponent:
15877 {
15878 var Component = workInProgress.type;
15879 if (isContextProvider(Component)) {
15880 popContext(workInProgress);
15881 }
15882 break;
15883 }
15884 case HostRoot:
15885 {
15886 popHostContainer(workInProgress);
15887 popTopLevelContextObject(workInProgress);
15888 var fiberRoot = workInProgress.stateNode;
15889 if (fiberRoot.pendingContext) {
15890 fiberRoot.context = fiberRoot.pendingContext;
15891 fiberRoot.pendingContext = null;
15892 }
15893 if (current === null || current.child === null) {
15894 // If we hydrated, pop so that we can delete any remaining children
15895 // that weren't hydrated.
15896 popHydrationState(workInProgress);
15897 // This resets the hacky state to fix isMounted before committing.
15898 // TODO: Delete this when we delete isMounted and findDOMNode.
15899 workInProgress.effectTag &= ~Placement;
15900 }
15901 updateHostContainer(workInProgress);
15902 break;
15903 }
15904 case HostComponent:
15905 {
15906 popHostContext(workInProgress);
15907 var rootContainerInstance = getRootHostContainer();
15908 var type = workInProgress.type;
15909 if (current !== null && workInProgress.stateNode != null) {
15910 updateHostComponent$1(current, workInProgress, type, newProps, rootContainerInstance);
15911
15912 if (current.ref !== workInProgress.ref) {
15913 markRef$1(workInProgress);
15914 }
15915 } else {
15916 if (!newProps) {
15917 !(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;
15918 // This can happen when we abort work.
15919 break;
15920 }
15921
15922 var currentHostContext = getHostContext();
15923 // TODO: Move createInstance to beginWork and keep it on a context
15924 // "stack" as the parent. Then append children as we go in beginWork
15925 // or completeWork depending on we want to add then top->down or
15926 // bottom->up. Top->down is faster in IE11.
15927 var wasHydrated = popHydrationState(workInProgress);
15928 if (wasHydrated) {
15929 // TODO: Move this and createInstance step into the beginPhase
15930 // to consolidate.
15931 if (prepareToHydrateHostInstance(workInProgress, rootContainerInstance, currentHostContext)) {
15932 // If changes to the hydrated node needs to be applied at the
15933 // commit-phase we mark this as such.
15934 markUpdate(workInProgress);
15935 }
15936 } else {
15937 var instance = createInstance(type, newProps, rootContainerInstance, currentHostContext, workInProgress);
15938
15939 appendAllChildren(instance, workInProgress, false, false);
15940
15941 // Certain renderers require commit-time effects for initial mount.
15942 // (eg DOM renderer supports auto-focus for certain elements).
15943 // Make sure such renderers get scheduled for later work.
15944 if (finalizeInitialChildren(instance, type, newProps, rootContainerInstance, currentHostContext)) {
15945 markUpdate(workInProgress);
15946 }
15947 workInProgress.stateNode = instance;
15948 }
15949
15950 if (workInProgress.ref !== null) {
15951 // If there is a ref on a host node we need to schedule a callback
15952 markRef$1(workInProgress);
15953 }
15954 }
15955 break;
15956 }
15957 case HostText:
15958 {
15959 var newText = newProps;
15960 if (current && workInProgress.stateNode != null) {
15961 var oldText = current.memoizedProps;
15962 // If we have an alternate, that means this is an update and we need
15963 // to schedule a side-effect to do the updates.
15964 updateHostText$1(current, workInProgress, oldText, newText);
15965 } else {
15966 if (typeof newText !== 'string') {
15967 !(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;
15968 // This can happen when we abort work.
15969 }
15970 var _rootContainerInstance = getRootHostContainer();
15971 var _currentHostContext = getHostContext();
15972 var _wasHydrated = popHydrationState(workInProgress);
15973 if (_wasHydrated) {
15974 if (prepareToHydrateHostTextInstance(workInProgress)) {
15975 markUpdate(workInProgress);
15976 }
15977 } else {
15978 workInProgress.stateNode = createTextInstance(newText, _rootContainerInstance, _currentHostContext, workInProgress);
15979 }
15980 }
15981 break;
15982 }
15983 case ForwardRef:
15984 break;
15985 case SuspenseComponent:
15986 {
15987 var nextState = workInProgress.memoizedState;
15988 if ((workInProgress.effectTag & DidCapture) !== NoEffect) {
15989 // Something suspended. Re-render with the fallback children.
15990 workInProgress.expirationTime = renderExpirationTime;
15991 // Do not reset the effect list.
15992 return workInProgress;
15993 }
15994
15995 var nextDidTimeout = nextState !== null;
15996 var prevDidTimeout = current !== null && current.memoizedState !== null;
15997
15998 if (current !== null && !nextDidTimeout && prevDidTimeout) {
15999 // We just switched from the fallback to the normal children. Delete
16000 // the fallback.
16001 // TODO: Would it be better to store the fallback fragment on
16002 var currentFallbackChild = current.child.sibling;
16003 if (currentFallbackChild !== null) {
16004 // Deletions go at the beginning of the return fiber's effect list
16005 var first = workInProgress.firstEffect;
16006 if (first !== null) {
16007 workInProgress.firstEffect = currentFallbackChild;
16008 currentFallbackChild.nextEffect = first;
16009 } else {
16010 workInProgress.firstEffect = workInProgress.lastEffect = currentFallbackChild;
16011 currentFallbackChild.nextEffect = null;
16012 }
16013 currentFallbackChild.effectTag = Deletion;
16014 }
16015 }
16016
16017 // The children either timed out after previously being visible, or
16018 // were restored after previously being hidden. Schedule an effect
16019 // to update their visiblity.
16020 if (
16021 //
16022 nextDidTimeout !== prevDidTimeout ||
16023 // Outside concurrent mode, the primary children commit in an
16024 // inconsistent state, even if they are hidden. So if they are hidden,
16025 // we need to schedule an effect to re-hide them, just in case.
16026 (workInProgress.effectTag & ConcurrentMode) === NoContext && nextDidTimeout) {
16027 workInProgress.effectTag |= Update;
16028 }
16029 break;
16030 }
16031 case Fragment:
16032 break;
16033 case Mode:
16034 break;
16035 case Profiler:
16036 break;
16037 case HostPortal:
16038 popHostContainer(workInProgress);
16039 updateHostContainer(workInProgress);
16040 break;
16041 case ContextProvider:
16042 // Pop provider fiber
16043 popProvider(workInProgress);
16044 break;
16045 case ContextConsumer:
16046 break;
16047 case MemoComponent:
16048 break;
16049 case IncompleteClassComponent:
16050 {
16051 // Same as class component case. I put it down here so that the tags are
16052 // sequential to ensure this switch is compiled to a jump table.
16053 var _Component = workInProgress.type;
16054 if (isContextProvider(_Component)) {
16055 popContext(workInProgress);
16056 }
16057 break;
16058 }
16059 default:
16060 invariant(false, 'Unknown unit of work tag. This error is likely caused by a bug in React. Please file an issue.');
16061 }
16062
16063 return null;
16064}
16065
16066function shouldCaptureSuspense(workInProgress) {
16067 // In order to capture, the Suspense component must have a fallback prop.
16068 if (workInProgress.memoizedProps.fallback === undefined) {
16069 return false;
16070 }
16071 // If it was the primary children that just suspended, capture and render the
16072 // fallback. Otherwise, don't capture and bubble to the next boundary.
16073 var nextState = workInProgress.memoizedState;
16074 return nextState === null;
16075}
16076
16077// This module is forked in different environments.
16078// By default, return `true` to log errors to the console.
16079// Forks can return `false` if this isn't desirable.
16080function showErrorDialog(capturedError) {
16081 return true;
16082}
16083
16084function logCapturedError(capturedError) {
16085 var logError = showErrorDialog(capturedError);
16086
16087 // Allow injected showErrorDialog() to prevent default console.error logging.
16088 // This enables renderers like ReactNative to better manage redbox behavior.
16089 if (logError === false) {
16090 return;
16091 }
16092
16093 var error = capturedError.error;
16094 {
16095 var componentName = capturedError.componentName,
16096 componentStack = capturedError.componentStack,
16097 errorBoundaryName = capturedError.errorBoundaryName,
16098 errorBoundaryFound = capturedError.errorBoundaryFound,
16099 willRetry = capturedError.willRetry;
16100
16101 // Browsers support silencing uncaught errors by calling
16102 // `preventDefault()` in window `error` handler.
16103 // We record this information as an expando on the error.
16104
16105 if (error != null && error._suppressLogging) {
16106 if (errorBoundaryFound && willRetry) {
16107 // The error is recoverable and was silenced.
16108 // Ignore it and don't print the stack addendum.
16109 // This is handy for testing error boundaries without noise.
16110 return;
16111 }
16112 // The error is fatal. Since the silencing might have
16113 // been accidental, we'll surface it anyway.
16114 // However, the browser would have silenced the original error
16115 // so we'll print it first, and then print the stack addendum.
16116 console.error(error);
16117 // For a more detailed description of this block, see:
16118 // https://github.com/facebook/react/pull/13384
16119 }
16120
16121 var componentNameMessage = componentName ? 'The above error occurred in the <' + componentName + '> component:' : 'The above error occurred in one of your React components:';
16122
16123 var errorBoundaryMessage = void 0;
16124 // errorBoundaryFound check is sufficient; errorBoundaryName check is to satisfy Flow.
16125 if (errorBoundaryFound && errorBoundaryName) {
16126 if (willRetry) {
16127 errorBoundaryMessage = 'React will try to recreate this component tree from scratch ' + ('using the error boundary you provided, ' + errorBoundaryName + '.');
16128 } else {
16129 errorBoundaryMessage = 'This error was initially handled by the error boundary ' + errorBoundaryName + '.\n' + 'Recreating the tree from scratch failed so React will unmount the tree.';
16130 }
16131 } else {
16132 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.';
16133 }
16134 var combinedMessage = '' + componentNameMessage + componentStack + '\n\n' + ('' + errorBoundaryMessage);
16135
16136 // In development, we provide our own message with just the component stack.
16137 // We don't include the original error message and JS stack because the browser
16138 // has already printed it. Even if the application swallows the error, it is still
16139 // displayed by the browser thanks to the DEV-only fake event trick in ReactErrorUtils.
16140 console.error(combinedMessage);
16141 }
16142}
16143
16144var didWarnAboutUndefinedSnapshotBeforeUpdate = null;
16145{
16146 didWarnAboutUndefinedSnapshotBeforeUpdate = new Set();
16147}
16148
16149var PossiblyWeakSet = typeof WeakSet === 'function' ? WeakSet : Set;
16150
16151function logError(boundary, errorInfo) {
16152 var source = errorInfo.source;
16153 var stack = errorInfo.stack;
16154 if (stack === null && source !== null) {
16155 stack = getStackByFiberInDevAndProd(source);
16156 }
16157
16158 var capturedError = {
16159 componentName: source !== null ? getComponentName(source.type) : null,
16160 componentStack: stack !== null ? stack : '',
16161 error: errorInfo.value,
16162 errorBoundary: null,
16163 errorBoundaryName: null,
16164 errorBoundaryFound: false,
16165 willRetry: false
16166 };
16167
16168 if (boundary !== null && boundary.tag === ClassComponent) {
16169 capturedError.errorBoundary = boundary.stateNode;
16170 capturedError.errorBoundaryName = getComponentName(boundary.type);
16171 capturedError.errorBoundaryFound = true;
16172 capturedError.willRetry = true;
16173 }
16174
16175 try {
16176 logCapturedError(capturedError);
16177 } catch (e) {
16178 // This method must not throw, or React internal state will get messed up.
16179 // If console.error is overridden, or logCapturedError() shows a dialog that throws,
16180 // we want to report this error outside of the normal stack as a last resort.
16181 // https://github.com/facebook/react/issues/13188
16182 setTimeout(function () {
16183 throw e;
16184 });
16185 }
16186}
16187
16188var callComponentWillUnmountWithTimer = function (current$$1, instance) {
16189 startPhaseTimer(current$$1, 'componentWillUnmount');
16190 instance.props = current$$1.memoizedProps;
16191 instance.state = current$$1.memoizedState;
16192 instance.componentWillUnmount();
16193 stopPhaseTimer();
16194};
16195
16196// Capture errors so they don't interrupt unmounting.
16197function safelyCallComponentWillUnmount(current$$1, instance) {
16198 {
16199 invokeGuardedCallback(null, callComponentWillUnmountWithTimer, null, current$$1, instance);
16200 if (hasCaughtError()) {
16201 var unmountError = clearCaughtError();
16202 captureCommitPhaseError(current$$1, unmountError);
16203 }
16204 }
16205}
16206
16207function safelyDetachRef(current$$1) {
16208 var ref = current$$1.ref;
16209 if (ref !== null) {
16210 if (typeof ref === 'function') {
16211 {
16212 invokeGuardedCallback(null, ref, null, null);
16213 if (hasCaughtError()) {
16214 var refError = clearCaughtError();
16215 captureCommitPhaseError(current$$1, refError);
16216 }
16217 }
16218 } else {
16219 ref.current = null;
16220 }
16221 }
16222}
16223
16224function safelyCallDestroy(current$$1, destroy) {
16225 {
16226 invokeGuardedCallback(null, destroy, null);
16227 if (hasCaughtError()) {
16228 var error = clearCaughtError();
16229 captureCommitPhaseError(current$$1, error);
16230 }
16231 }
16232}
16233
16234function commitBeforeMutationLifeCycles(current$$1, finishedWork) {
16235 switch (finishedWork.tag) {
16236 case FunctionComponent:
16237 case ForwardRef:
16238 case SimpleMemoComponent:
16239 {
16240 commitHookEffectList(UnmountSnapshot, NoEffect$1, finishedWork);
16241 return;
16242 }
16243 case ClassComponent:
16244 {
16245 if (finishedWork.effectTag & Snapshot) {
16246 if (current$$1 !== null) {
16247 var prevProps = current$$1.memoizedProps;
16248 var prevState = current$$1.memoizedState;
16249 startPhaseTimer(finishedWork, 'getSnapshotBeforeUpdate');
16250 var instance = finishedWork.stateNode;
16251 // We could update instance props and state here,
16252 // but instead we rely on them being set during last render.
16253 // TODO: revisit this when we implement resuming.
16254 {
16255 if (finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps) {
16256 !(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;
16257 !(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;
16258 }
16259 }
16260 var snapshot = instance.getSnapshotBeforeUpdate(finishedWork.elementType === finishedWork.type ? prevProps : resolveDefaultProps(finishedWork.type, prevProps), prevState);
16261 {
16262 var didWarnSet = didWarnAboutUndefinedSnapshotBeforeUpdate;
16263 if (snapshot === undefined && !didWarnSet.has(finishedWork.type)) {
16264 didWarnSet.add(finishedWork.type);
16265 warningWithoutStack$1(false, '%s.getSnapshotBeforeUpdate(): A snapshot value (or null) ' + 'must be returned. You have returned undefined.', getComponentName(finishedWork.type));
16266 }
16267 }
16268 instance.__reactInternalSnapshotBeforeUpdate = snapshot;
16269 stopPhaseTimer();
16270 }
16271 }
16272 return;
16273 }
16274 case HostRoot:
16275 case HostComponent:
16276 case HostText:
16277 case HostPortal:
16278 case IncompleteClassComponent:
16279 // Nothing to do for these component types
16280 return;
16281 default:
16282 {
16283 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.');
16284 }
16285 }
16286}
16287
16288function commitHookEffectList(unmountTag, mountTag, finishedWork) {
16289 if (!enableHooks) {
16290 return;
16291 }
16292 var updateQueue = finishedWork.updateQueue;
16293 var lastEffect = updateQueue !== null ? updateQueue.lastEffect : null;
16294 if (lastEffect !== null) {
16295 var firstEffect = lastEffect.next;
16296 var effect = firstEffect;
16297 do {
16298 if ((effect.tag & unmountTag) !== NoEffect$1) {
16299 // Unmount
16300 var destroy = effect.destroy;
16301 effect.destroy = null;
16302 if (destroy !== null) {
16303 destroy();
16304 }
16305 }
16306 if ((effect.tag & mountTag) !== NoEffect$1) {
16307 // Mount
16308 var create = effect.create;
16309 var _destroy = create();
16310 if (typeof _destroy !== 'function') {
16311 {
16312 if (_destroy !== null && _destroy !== undefined) {
16313 warningWithoutStack$1(false, 'useEffect function must return a cleanup function or ' + 'nothing.%s%s', typeof _destroy.then === 'function' ? '\n\nIt looks like you wrote useEffect(async () => ...) or returned a Promise. ' + 'Instead, you may write an async function separately ' + 'and then call it from inside the effect:\n\n' + 'async function fetchComment(commentId) {\n' + ' // You can await here\n' + '}\n\n' + 'useEffect(() => {\n' + ' fetchComment(commentId);\n' + '}, [commentId]);\n\n' + 'In the future, React will provide a more idiomatic solution for data fetching ' + "that doesn't involve writing effects manually." : '', getStackByFiberInDevAndProd(finishedWork));
16314 }
16315 }
16316 _destroy = null;
16317 }
16318 effect.destroy = _destroy;
16319 }
16320 effect = effect.next;
16321 } while (effect !== firstEffect);
16322 }
16323}
16324
16325function commitPassiveHookEffects(finishedWork) {
16326 commitHookEffectList(UnmountPassive, NoEffect$1, finishedWork);
16327 commitHookEffectList(NoEffect$1, MountPassive, finishedWork);
16328}
16329
16330function commitLifeCycles(finishedRoot, current$$1, finishedWork, committedExpirationTime) {
16331 switch (finishedWork.tag) {
16332 case FunctionComponent:
16333 case ForwardRef:
16334 case SimpleMemoComponent:
16335 {
16336 commitHookEffectList(UnmountLayout, MountLayout, finishedWork);
16337 break;
16338 }
16339 case ClassComponent:
16340 {
16341 var instance = finishedWork.stateNode;
16342 if (finishedWork.effectTag & Update) {
16343 if (current$$1 === null) {
16344 startPhaseTimer(finishedWork, 'componentDidMount');
16345 // We could update instance props and state here,
16346 // but instead we rely on them being set during last render.
16347 // TODO: revisit this when we implement resuming.
16348 {
16349 if (finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps) {
16350 !(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;
16351 !(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;
16352 }
16353 }
16354 instance.componentDidMount();
16355 stopPhaseTimer();
16356 } else {
16357 var prevProps = finishedWork.elementType === finishedWork.type ? current$$1.memoizedProps : resolveDefaultProps(finishedWork.type, current$$1.memoizedProps);
16358 var prevState = current$$1.memoizedState;
16359 startPhaseTimer(finishedWork, 'componentDidUpdate');
16360 // We could update instance props and state here,
16361 // but instead we rely on them being set during last render.
16362 // TODO: revisit this when we implement resuming.
16363 {
16364 if (finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps) {
16365 !(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;
16366 !(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;
16367 }
16368 }
16369 instance.componentDidUpdate(prevProps, prevState, instance.__reactInternalSnapshotBeforeUpdate);
16370 stopPhaseTimer();
16371 }
16372 }
16373 var updateQueue = finishedWork.updateQueue;
16374 if (updateQueue !== null) {
16375 {
16376 if (finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps) {
16377 !(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;
16378 !(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;
16379 }
16380 }
16381 // We could update instance props and state here,
16382 // but instead we rely on them being set during last render.
16383 // TODO: revisit this when we implement resuming.
16384 commitUpdateQueue(finishedWork, updateQueue, instance, committedExpirationTime);
16385 }
16386 return;
16387 }
16388 case HostRoot:
16389 {
16390 var _updateQueue = finishedWork.updateQueue;
16391 if (_updateQueue !== null) {
16392 var _instance = null;
16393 if (finishedWork.child !== null) {
16394 switch (finishedWork.child.tag) {
16395 case HostComponent:
16396 _instance = getPublicInstance(finishedWork.child.stateNode);
16397 break;
16398 case ClassComponent:
16399 _instance = finishedWork.child.stateNode;
16400 break;
16401 }
16402 }
16403 commitUpdateQueue(finishedWork, _updateQueue, _instance, committedExpirationTime);
16404 }
16405 return;
16406 }
16407 case HostComponent:
16408 {
16409 var _instance2 = finishedWork.stateNode;
16410
16411 // Renderers may schedule work to be done after host components are mounted
16412 // (eg DOM renderer may schedule auto-focus for inputs and form controls).
16413 // These effects should only be committed when components are first mounted,
16414 // aka when there is no current/alternate.
16415 if (current$$1 === null && finishedWork.effectTag & Update) {
16416 var type = finishedWork.type;
16417 var props = finishedWork.memoizedProps;
16418 commitMount(_instance2, type, props, finishedWork);
16419 }
16420
16421 return;
16422 }
16423 case HostText:
16424 {
16425 // We have no life-cycles associated with text.
16426 return;
16427 }
16428 case HostPortal:
16429 {
16430 // We have no life-cycles associated with portals.
16431 return;
16432 }
16433 case Profiler:
16434 {
16435 if (enableProfilerTimer) {
16436 var onRender = finishedWork.memoizedProps.onRender;
16437
16438 if (enableSchedulerTracing) {
16439 onRender(finishedWork.memoizedProps.id, current$$1 === null ? 'mount' : 'update', finishedWork.actualDuration, finishedWork.treeBaseDuration, finishedWork.actualStartTime, getCommitTime(), finishedRoot.memoizedInteractions);
16440 } else {
16441 onRender(finishedWork.memoizedProps.id, current$$1 === null ? 'mount' : 'update', finishedWork.actualDuration, finishedWork.treeBaseDuration, finishedWork.actualStartTime, getCommitTime());
16442 }
16443 }
16444 return;
16445 }
16446 case SuspenseComponent:
16447 break;
16448 case IncompleteClassComponent:
16449 break;
16450 default:
16451 {
16452 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.');
16453 }
16454 }
16455}
16456
16457function hideOrUnhideAllChildren(finishedWork, isHidden) {
16458 if (supportsMutation) {
16459 // We only have the top Fiber that was inserted but we need recurse down its
16460 var node = finishedWork;
16461 while (true) {
16462 if (node.tag === HostComponent) {
16463 var instance = node.stateNode;
16464 if (isHidden) {
16465 hideInstance(instance);
16466 } else {
16467 unhideInstance(node.stateNode, node.memoizedProps);
16468 }
16469 } else if (node.tag === HostText) {
16470 var _instance3 = node.stateNode;
16471 if (isHidden) {
16472 hideTextInstance(_instance3);
16473 } else {
16474 unhideTextInstance(_instance3, node.memoizedProps);
16475 }
16476 } else if (node.tag === SuspenseComponent && node.memoizedState !== null) {
16477 // Found a nested Suspense component that timed out. Skip over the
16478 var fallbackChildFragment = node.child.sibling;
16479 fallbackChildFragment.return = node;
16480 node = fallbackChildFragment;
16481 continue;
16482 } else if (node.child !== null) {
16483 node.child.return = node;
16484 node = node.child;
16485 continue;
16486 }
16487 if (node === finishedWork) {
16488 return;
16489 }
16490 while (node.sibling === null) {
16491 if (node.return === null || node.return === finishedWork) {
16492 return;
16493 }
16494 node = node.return;
16495 }
16496 node.sibling.return = node.return;
16497 node = node.sibling;
16498 }
16499 }
16500}
16501
16502function commitAttachRef(finishedWork) {
16503 var ref = finishedWork.ref;
16504 if (ref !== null) {
16505 var instance = finishedWork.stateNode;
16506 var instanceToUse = void 0;
16507 switch (finishedWork.tag) {
16508 case HostComponent:
16509 instanceToUse = getPublicInstance(instance);
16510 break;
16511 default:
16512 instanceToUse = instance;
16513 }
16514 if (typeof ref === 'function') {
16515 ref(instanceToUse);
16516 } else {
16517 {
16518 if (!ref.hasOwnProperty('current')) {
16519 warningWithoutStack$1(false, 'Unexpected ref object provided for %s. ' + 'Use either a ref-setter function or React.createRef().%s', getComponentName(finishedWork.type), getStackByFiberInDevAndProd(finishedWork));
16520 }
16521 }
16522
16523 ref.current = instanceToUse;
16524 }
16525 }
16526}
16527
16528function commitDetachRef(current$$1) {
16529 var currentRef = current$$1.ref;
16530 if (currentRef !== null) {
16531 if (typeof currentRef === 'function') {
16532 currentRef(null);
16533 } else {
16534 currentRef.current = null;
16535 }
16536 }
16537}
16538
16539// User-originating errors (lifecycles and refs) should not interrupt
16540// deletion, so don't let them throw. Host-originating errors should
16541// interrupt deletion, so it's okay
16542function commitUnmount(current$$1) {
16543 onCommitUnmount(current$$1);
16544
16545 switch (current$$1.tag) {
16546 case FunctionComponent:
16547 case ForwardRef:
16548 case MemoComponent:
16549 case SimpleMemoComponent:
16550 {
16551 var updateQueue = current$$1.updateQueue;
16552 if (updateQueue !== null) {
16553 var lastEffect = updateQueue.lastEffect;
16554 if (lastEffect !== null) {
16555 var firstEffect = lastEffect.next;
16556 var effect = firstEffect;
16557 do {
16558 var destroy = effect.destroy;
16559 if (destroy !== null) {
16560 safelyCallDestroy(current$$1, destroy);
16561 }
16562 effect = effect.next;
16563 } while (effect !== firstEffect);
16564 }
16565 }
16566 break;
16567 }
16568 case ClassComponent:
16569 {
16570 safelyDetachRef(current$$1);
16571 var instance = current$$1.stateNode;
16572 if (typeof instance.componentWillUnmount === 'function') {
16573 safelyCallComponentWillUnmount(current$$1, instance);
16574 }
16575 return;
16576 }
16577 case HostComponent:
16578 {
16579 safelyDetachRef(current$$1);
16580 return;
16581 }
16582 case HostPortal:
16583 {
16584 // TODO: this is recursive.
16585 // We are also not using this parent because
16586 // the portal will get pushed immediately.
16587 if (supportsMutation) {
16588 unmountHostComponents(current$$1);
16589 } else if (supportsPersistence) {
16590 emptyPortalContainer(current$$1);
16591 }
16592 return;
16593 }
16594 }
16595}
16596
16597function commitNestedUnmounts(root) {
16598 // While we're inside a removed host node we don't want to call
16599 // removeChild on the inner nodes because they're removed by the top
16600 // call anyway. We also want to call componentWillUnmount on all
16601 // composites before this host node is removed from the tree. Therefore
16602 var node = root;
16603 while (true) {
16604 commitUnmount(node);
16605 // Visit children because they may contain more composite or host nodes.
16606 // Skip portals because commitUnmount() currently visits them recursively.
16607 if (node.child !== null && (
16608 // If we use mutation we drill down into portals using commitUnmount above.
16609 // If we don't use mutation we drill down into portals here instead.
16610 !supportsMutation || node.tag !== HostPortal)) {
16611 node.child.return = node;
16612 node = node.child;
16613 continue;
16614 }
16615 if (node === root) {
16616 return;
16617 }
16618 while (node.sibling === null) {
16619 if (node.return === null || node.return === root) {
16620 return;
16621 }
16622 node = node.return;
16623 }
16624 node.sibling.return = node.return;
16625 node = node.sibling;
16626 }
16627}
16628
16629function detachFiber(current$$1) {
16630 // Cut off the return pointers to disconnect it from the tree. Ideally, we
16631 // should clear the child pointer of the parent alternate to let this
16632 // get GC:ed but we don't know which for sure which parent is the current
16633 // one so we'll settle for GC:ing the subtree of this child. This child
16634 // itself will be GC:ed when the parent updates the next time.
16635 current$$1.return = null;
16636 current$$1.child = null;
16637 current$$1.memoizedState = null;
16638 current$$1.updateQueue = null;
16639 var alternate = current$$1.alternate;
16640 if (alternate !== null) {
16641 alternate.return = null;
16642 alternate.child = null;
16643 alternate.memoizedState = null;
16644 alternate.updateQueue = null;
16645 }
16646}
16647
16648function emptyPortalContainer(current$$1) {
16649 if (!supportsPersistence) {
16650 return;
16651 }
16652
16653 var portal = current$$1.stateNode;
16654 var containerInfo = portal.containerInfo;
16655
16656 var emptyChildSet = createContainerChildSet(containerInfo);
16657 replaceContainerChildren(containerInfo, emptyChildSet);
16658}
16659
16660function commitContainer(finishedWork) {
16661 if (!supportsPersistence) {
16662 return;
16663 }
16664
16665 switch (finishedWork.tag) {
16666 case ClassComponent:
16667 {
16668 return;
16669 }
16670 case HostComponent:
16671 {
16672 return;
16673 }
16674 case HostText:
16675 {
16676 return;
16677 }
16678 case HostRoot:
16679 case HostPortal:
16680 {
16681 var portalOrRoot = finishedWork.stateNode;
16682 var containerInfo = portalOrRoot.containerInfo,
16683 _pendingChildren = portalOrRoot.pendingChildren;
16684
16685 replaceContainerChildren(containerInfo, _pendingChildren);
16686 return;
16687 }
16688 default:
16689 {
16690 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.');
16691 }
16692 }
16693}
16694
16695function getHostParentFiber(fiber) {
16696 var parent = fiber.return;
16697 while (parent !== null) {
16698 if (isHostParent(parent)) {
16699 return parent;
16700 }
16701 parent = parent.return;
16702 }
16703 invariant(false, 'Expected to find a host parent. This error is likely caused by a bug in React. Please file an issue.');
16704}
16705
16706function isHostParent(fiber) {
16707 return fiber.tag === HostComponent || fiber.tag === HostRoot || fiber.tag === HostPortal;
16708}
16709
16710function getHostSibling(fiber) {
16711 // We're going to search forward into the tree until we find a sibling host
16712 // node. Unfortunately, if multiple insertions are done in a row we have to
16713 // search past them. This leads to exponential search for the next sibling.
16714 var node = fiber;
16715 siblings: while (true) {
16716 // If we didn't find anything, let's try the next sibling.
16717 while (node.sibling === null) {
16718 if (node.return === null || isHostParent(node.return)) {
16719 // If we pop out of the root or hit the parent the fiber we are the
16720 // last sibling.
16721 return null;
16722 }
16723 node = node.return;
16724 }
16725 node.sibling.return = node.return;
16726 node = node.sibling;
16727 while (node.tag !== HostComponent && node.tag !== HostText) {
16728 // If it is not host node and, we might have a host node inside it.
16729 // Try to search down until we find one.
16730 if (node.effectTag & Placement) {
16731 // If we don't have a child, try the siblings instead.
16732 continue siblings;
16733 }
16734 // If we don't have a child, try the siblings instead.
16735 // We also skip portals because they are not part of this host tree.
16736 if (node.child === null || node.tag === HostPortal) {
16737 continue siblings;
16738 } else {
16739 node.child.return = node;
16740 node = node.child;
16741 }
16742 }
16743 // Check if this host node is stable or about to be placed.
16744 if (!(node.effectTag & Placement)) {
16745 // Found it!
16746 return node.stateNode;
16747 }
16748 }
16749}
16750
16751function commitPlacement(finishedWork) {
16752 if (!supportsMutation) {
16753 return;
16754 }
16755
16756 // Recursively insert all host nodes into the parent.
16757 var parentFiber = getHostParentFiber(finishedWork);
16758
16759 // Note: these two variables *must* always be updated together.
16760 var parent = void 0;
16761 var isContainer = void 0;
16762
16763 switch (parentFiber.tag) {
16764 case HostComponent:
16765 parent = parentFiber.stateNode;
16766 isContainer = false;
16767 break;
16768 case HostRoot:
16769 parent = parentFiber.stateNode.containerInfo;
16770 isContainer = true;
16771 break;
16772 case HostPortal:
16773 parent = parentFiber.stateNode.containerInfo;
16774 isContainer = true;
16775 break;
16776 default:
16777 invariant(false, 'Invalid host parent fiber. This error is likely caused by a bug in React. Please file an issue.');
16778 }
16779 if (parentFiber.effectTag & ContentReset) {
16780 // Reset the text content of the parent before doing any insertions
16781 resetTextContent(parent);
16782 // Clear ContentReset from the effect tag
16783 parentFiber.effectTag &= ~ContentReset;
16784 }
16785
16786 var before = getHostSibling(finishedWork);
16787 // We only have the top Fiber that was inserted but we need recurse down its
16788 // children to find all the terminal nodes.
16789 var node = finishedWork;
16790 while (true) {
16791 if (node.tag === HostComponent || node.tag === HostText) {
16792 if (before) {
16793 if (isContainer) {
16794 insertInContainerBefore(parent, node.stateNode, before);
16795 } else {
16796 insertBefore(parent, node.stateNode, before);
16797 }
16798 } else {
16799 if (isContainer) {
16800 appendChildToContainer(parent, node.stateNode);
16801 } else {
16802 appendChild(parent, node.stateNode);
16803 }
16804 }
16805 } else if (node.tag === HostPortal) {
16806 // If the insertion itself is a portal, then we don't want to traverse
16807 // down its children. Instead, we'll get insertions from each child in
16808 // the portal directly.
16809 } else if (node.child !== null) {
16810 node.child.return = node;
16811 node = node.child;
16812 continue;
16813 }
16814 if (node === finishedWork) {
16815 return;
16816 }
16817 while (node.sibling === null) {
16818 if (node.return === null || node.return === finishedWork) {
16819 return;
16820 }
16821 node = node.return;
16822 }
16823 node.sibling.return = node.return;
16824 node = node.sibling;
16825 }
16826}
16827
16828function unmountHostComponents(current$$1) {
16829 // We only have the top Fiber that was deleted but we need recurse down its
16830 var node = current$$1;
16831
16832 // Each iteration, currentParent is populated with node's host parent if not
16833 // currentParentIsValid.
16834 var currentParentIsValid = false;
16835
16836 // Note: these two variables *must* always be updated together.
16837 var currentParent = void 0;
16838 var currentParentIsContainer = void 0;
16839
16840 while (true) {
16841 if (!currentParentIsValid) {
16842 var parent = node.return;
16843 findParent: while (true) {
16844 !(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;
16845 switch (parent.tag) {
16846 case HostComponent:
16847 currentParent = parent.stateNode;
16848 currentParentIsContainer = false;
16849 break findParent;
16850 case HostRoot:
16851 currentParent = parent.stateNode.containerInfo;
16852 currentParentIsContainer = true;
16853 break findParent;
16854 case HostPortal:
16855 currentParent = parent.stateNode.containerInfo;
16856 currentParentIsContainer = true;
16857 break findParent;
16858 }
16859 parent = parent.return;
16860 }
16861 currentParentIsValid = true;
16862 }
16863
16864 if (node.tag === HostComponent || node.tag === HostText) {
16865 commitNestedUnmounts(node);
16866 // After all the children have unmounted, it is now safe to remove the
16867 // node from the tree.
16868 if (currentParentIsContainer) {
16869 removeChildFromContainer(currentParent, node.stateNode);
16870 } else {
16871 removeChild(currentParent, node.stateNode);
16872 }
16873 // Don't visit children because we already visited them.
16874 } else if (node.tag === HostPortal) {
16875 // When we go into a portal, it becomes the parent to remove from.
16876 // We will reassign it back when we pop the portal on the way up.
16877 currentParent = node.stateNode.containerInfo;
16878 currentParentIsContainer = true;
16879 // Visit children because portals might contain host components.
16880 if (node.child !== null) {
16881 node.child.return = node;
16882 node = node.child;
16883 continue;
16884 }
16885 } else {
16886 commitUnmount(node);
16887 // Visit children because we may find more host components below.
16888 if (node.child !== null) {
16889 node.child.return = node;
16890 node = node.child;
16891 continue;
16892 }
16893 }
16894 if (node === current$$1) {
16895 return;
16896 }
16897 while (node.sibling === null) {
16898 if (node.return === null || node.return === current$$1) {
16899 return;
16900 }
16901 node = node.return;
16902 if (node.tag === HostPortal) {
16903 // When we go out of the portal, we need to restore the parent.
16904 // Since we don't keep a stack of them, we will search for it.
16905 currentParentIsValid = false;
16906 }
16907 }
16908 node.sibling.return = node.return;
16909 node = node.sibling;
16910 }
16911}
16912
16913function commitDeletion(current$$1) {
16914 if (supportsMutation) {
16915 // Recursively delete all host nodes from the parent.
16916 // Detach refs and call componentWillUnmount() on the whole subtree.
16917 unmountHostComponents(current$$1);
16918 } else {
16919 // Detach refs and call componentWillUnmount() on the whole subtree.
16920 commitNestedUnmounts(current$$1);
16921 }
16922 detachFiber(current$$1);
16923}
16924
16925function commitWork(current$$1, finishedWork) {
16926 if (!supportsMutation) {
16927 switch (finishedWork.tag) {
16928 case FunctionComponent:
16929 case ForwardRef:
16930 case MemoComponent:
16931 case SimpleMemoComponent:
16932 {
16933 // Note: We currently never use MountMutation, but useLayout uses
16934 // UnmountMutation.
16935 commitHookEffectList(UnmountMutation, MountMutation, finishedWork);
16936 return;
16937 }
16938 }
16939
16940 commitContainer(finishedWork);
16941 return;
16942 }
16943
16944 switch (finishedWork.tag) {
16945 case FunctionComponent:
16946 case ForwardRef:
16947 case MemoComponent:
16948 case SimpleMemoComponent:
16949 {
16950 // Note: We currently never use MountMutation, but useLayout uses
16951 // UnmountMutation.
16952 commitHookEffectList(UnmountMutation, MountMutation, finishedWork);
16953 return;
16954 }
16955 case ClassComponent:
16956 {
16957 return;
16958 }
16959 case HostComponent:
16960 {
16961 var instance = finishedWork.stateNode;
16962 if (instance != null) {
16963 // Commit the work prepared earlier.
16964 var newProps = finishedWork.memoizedProps;
16965 // For hydration we reuse the update path but we treat the oldProps
16966 // as the newProps. The updatePayload will contain the real change in
16967 // this case.
16968 var oldProps = current$$1 !== null ? current$$1.memoizedProps : newProps;
16969 var type = finishedWork.type;
16970 // TODO: Type the updateQueue to be specific to host components.
16971 var updatePayload = finishedWork.updateQueue;
16972 finishedWork.updateQueue = null;
16973 if (updatePayload !== null) {
16974 commitUpdate(instance, updatePayload, type, oldProps, newProps, finishedWork);
16975 }
16976 }
16977 return;
16978 }
16979 case HostText:
16980 {
16981 !(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;
16982 var textInstance = finishedWork.stateNode;
16983 var newText = finishedWork.memoizedProps;
16984 // For hydration we reuse the update path but we treat the oldProps
16985 // as the newProps. The updatePayload will contain the real change in
16986 // this case.
16987 var oldText = current$$1 !== null ? current$$1.memoizedProps : newText;
16988 commitTextUpdate(textInstance, oldText, newText);
16989 return;
16990 }
16991 case HostRoot:
16992 {
16993 return;
16994 }
16995 case Profiler:
16996 {
16997 return;
16998 }
16999 case SuspenseComponent:
17000 {
17001 var newState = finishedWork.memoizedState;
17002
17003 var newDidTimeout = void 0;
17004 var primaryChildParent = finishedWork;
17005 if (newState === null) {
17006 newDidTimeout = false;
17007 } else {
17008 newDidTimeout = true;
17009 primaryChildParent = finishedWork.child;
17010 if (newState.timedOutAt === NoWork) {
17011 // If the children had not already timed out, record the time.
17012 // This is used to compute the elapsed time during subsequent
17013 // attempts to render the children.
17014 newState.timedOutAt = requestCurrentTime();
17015 }
17016 }
17017
17018 if (primaryChildParent !== null) {
17019 hideOrUnhideAllChildren(primaryChildParent, newDidTimeout);
17020 }
17021
17022 // If this boundary just timed out, then it will have a set of thenables.
17023 // For each thenable, attach a listener so that when it resolves, React
17024 // attempts to re-render the boundary in the primary (pre-timeout) state.
17025 var thenables = finishedWork.updateQueue;
17026 if (thenables !== null) {
17027 finishedWork.updateQueue = null;
17028 var retryCache = finishedWork.stateNode;
17029 if (retryCache === null) {
17030 retryCache = finishedWork.stateNode = new PossiblyWeakSet();
17031 }
17032 thenables.forEach(function (thenable) {
17033 // Memoize using the boundary fiber to prevent redundant listeners.
17034 var retry = retryTimedOutBoundary.bind(null, finishedWork, thenable);
17035 if (enableSchedulerTracing) {
17036 retry = unstable_wrap(retry);
17037 }
17038 if (!retryCache.has(thenable)) {
17039 retryCache.add(thenable);
17040 thenable.then(retry, retry);
17041 }
17042 });
17043 }
17044
17045 return;
17046 }
17047 case IncompleteClassComponent:
17048 {
17049 return;
17050 }
17051 default:
17052 {
17053 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.');
17054 }
17055 }
17056}
17057
17058function commitResetTextContent(current$$1) {
17059 if (!supportsMutation) {
17060 return;
17061 }
17062 resetTextContent(current$$1.stateNode);
17063}
17064
17065var PossiblyWeakMap = typeof WeakMap === 'function' ? WeakMap : Map;
17066
17067function createRootErrorUpdate(fiber, errorInfo, expirationTime) {
17068 var update = createUpdate(expirationTime);
17069 // Unmount the root by rendering null.
17070 update.tag = CaptureUpdate;
17071 // Caution: React DevTools currently depends on this property
17072 // being called "element".
17073 update.payload = { element: null };
17074 var error = errorInfo.value;
17075 update.callback = function () {
17076 onUncaughtError(error);
17077 logError(fiber, errorInfo);
17078 };
17079 return update;
17080}
17081
17082function createClassErrorUpdate(fiber, errorInfo, expirationTime) {
17083 var update = createUpdate(expirationTime);
17084 update.tag = CaptureUpdate;
17085 var getDerivedStateFromError = fiber.type.getDerivedStateFromError;
17086 if (typeof getDerivedStateFromError === 'function') {
17087 var error = errorInfo.value;
17088 update.payload = function () {
17089 return getDerivedStateFromError(error);
17090 };
17091 }
17092
17093 var inst = fiber.stateNode;
17094 if (inst !== null && typeof inst.componentDidCatch === 'function') {
17095 update.callback = function callback() {
17096 if (typeof getDerivedStateFromError !== 'function') {
17097 // To preserve the preexisting retry behavior of error boundaries,
17098 // we keep track of which ones already failed during this batch.
17099 // This gets reset before we yield back to the browser.
17100 // TODO: Warn in strict mode if getDerivedStateFromError is
17101 // not defined.
17102 markLegacyErrorBoundaryAsFailed(this);
17103 }
17104 var error = errorInfo.value;
17105 var stack = errorInfo.stack;
17106 logError(fiber, errorInfo);
17107 this.componentDidCatch(error, {
17108 componentStack: stack !== null ? stack : ''
17109 });
17110 {
17111 if (typeof getDerivedStateFromError !== 'function') {
17112 // If componentDidCatch is the only error boundary method defined,
17113 // then it needs to call setState to recover from errors.
17114 // If no state update is scheduled then the boundary will swallow the error.
17115 !(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;
17116 }
17117 }
17118 };
17119 }
17120 return update;
17121}
17122
17123function throwException(root, returnFiber, sourceFiber, value, renderExpirationTime) {
17124 // The source fiber did not complete.
17125 sourceFiber.effectTag |= Incomplete;
17126 // Its effect list is no longer valid.
17127 sourceFiber.firstEffect = sourceFiber.lastEffect = null;
17128
17129 if (value !== null && typeof value === 'object' && typeof value.then === 'function') {
17130 // This is a thenable.
17131 var thenable = value;
17132
17133 // Find the earliest timeout threshold of all the placeholders in the
17134 // ancestor path. We could avoid this traversal by storing the thresholds on
17135 // the stack, but we choose not to because we only hit this path if we're
17136 // IO-bound (i.e. if something suspends). Whereas the stack is used even in
17137 // the non-IO- bound case.
17138 var _workInProgress = returnFiber;
17139 var earliestTimeoutMs = -1;
17140 var startTimeMs = -1;
17141 do {
17142 if (_workInProgress.tag === SuspenseComponent) {
17143 var current$$1 = _workInProgress.alternate;
17144 if (current$$1 !== null) {
17145 var currentState = current$$1.memoizedState;
17146 if (currentState !== null) {
17147 // Reached a boundary that already timed out. Do not search
17148 // any further.
17149 var timedOutAt = currentState.timedOutAt;
17150 startTimeMs = expirationTimeToMs(timedOutAt);
17151 // Do not search any further.
17152 break;
17153 }
17154 }
17155 var timeoutPropMs = _workInProgress.pendingProps.maxDuration;
17156 if (typeof timeoutPropMs === 'number') {
17157 if (timeoutPropMs <= 0) {
17158 earliestTimeoutMs = 0;
17159 } else if (earliestTimeoutMs === -1 || timeoutPropMs < earliestTimeoutMs) {
17160 earliestTimeoutMs = timeoutPropMs;
17161 }
17162 }
17163 }
17164 _workInProgress = _workInProgress.return;
17165 } while (_workInProgress !== null);
17166
17167 // Schedule the nearest Suspense to re-render the timed out view.
17168 _workInProgress = returnFiber;
17169 do {
17170 if (_workInProgress.tag === SuspenseComponent && shouldCaptureSuspense(_workInProgress)) {
17171 // Found the nearest boundary.
17172
17173 // Stash the promise on the boundary fiber. If the boundary times out, we'll
17174 var thenables = _workInProgress.updateQueue;
17175 if (thenables === null) {
17176 _workInProgress.updateQueue = new Set([thenable]);
17177 } else {
17178 thenables.add(thenable);
17179 }
17180
17181 // If the boundary is outside of concurrent mode, we should *not*
17182 // suspend the commit. Pretend as if the suspended component rendered
17183 // null and keep rendering. In the commit phase, we'll schedule a
17184 // subsequent synchronous update to re-render the Suspense.
17185 //
17186 // Note: It doesn't matter whether the component that suspended was
17187 // inside a concurrent mode tree. If the Suspense is outside of it, we
17188 // should *not* suspend the commit.
17189 if ((_workInProgress.mode & ConcurrentMode) === NoEffect) {
17190 _workInProgress.effectTag |= DidCapture;
17191
17192 // We're going to commit this fiber even though it didn't complete.
17193 // But we shouldn't call any lifecycle methods or callbacks. Remove
17194 // all lifecycle effect tags.
17195 sourceFiber.effectTag &= ~(LifecycleEffectMask | Incomplete);
17196
17197 if (sourceFiber.tag === ClassComponent) {
17198 var currentSourceFiber = sourceFiber.alternate;
17199 if (currentSourceFiber === null) {
17200 // This is a new mount. Change the tag so it's not mistaken for a
17201 // completed class component. For example, we should not call
17202 // componentWillUnmount if it is deleted.
17203 sourceFiber.tag = IncompleteClassComponent;
17204 } else {
17205 // When we try rendering again, we should not reuse the current fiber,
17206 // since it's known to be in an inconsistent state. Use a force updte to
17207 // prevent a bail out.
17208 var update = createUpdate(Sync);
17209 update.tag = ForceUpdate;
17210 enqueueUpdate(sourceFiber, update);
17211 }
17212 }
17213
17214 // The source fiber did not complete. Mark it with Sync priority to
17215 // indicate that it still has pending work.
17216 sourceFiber.expirationTime = Sync;
17217
17218 // Exit without suspending.
17219 return;
17220 }
17221
17222 // Confirmed that the boundary is in a concurrent mode tree. Continue
17223 // with the normal suspend path.
17224
17225 // Attach a listener to the promise to "ping" the root and retry. But
17226 // only if one does not already exist for the current render expiration
17227 // time (which acts like a "thread ID" here).
17228 var pingCache = root.pingCache;
17229 var threadIDs = void 0;
17230 if (pingCache === null) {
17231 pingCache = root.pingCache = new PossiblyWeakMap();
17232 threadIDs = new Set();
17233 pingCache.set(thenable, threadIDs);
17234 } else {
17235 threadIDs = pingCache.get(thenable);
17236 if (threadIDs === undefined) {
17237 threadIDs = new Set();
17238 pingCache.set(thenable, threadIDs);
17239 }
17240 }
17241 if (!threadIDs.has(renderExpirationTime)) {
17242 // Memoize using the thread ID to prevent redundant listeners.
17243 threadIDs.add(renderExpirationTime);
17244 var ping = pingSuspendedRoot.bind(null, root, thenable, renderExpirationTime);
17245 if (enableSchedulerTracing) {
17246 ping = unstable_wrap(ping);
17247 }
17248 thenable.then(ping, ping);
17249 }
17250
17251 var absoluteTimeoutMs = void 0;
17252 if (earliestTimeoutMs === -1) {
17253 // If no explicit threshold is given, default to an abitrarily large
17254 // value. The actual size doesn't matter because the threshold for the
17255 // whole tree will be clamped to the expiration time.
17256 absoluteTimeoutMs = maxSigned31BitInt;
17257 } else {
17258 if (startTimeMs === -1) {
17259 // This suspend happened outside of any already timed-out
17260 // placeholders. We don't know exactly when the update was
17261 // scheduled, but we can infer an approximate start time from the
17262 // expiration time. First, find the earliest uncommitted expiration
17263 // time in the tree, including work that is suspended. Then subtract
17264 // the offset used to compute an async update's expiration time.
17265 // This will cause high priority (interactive) work to expire
17266 // earlier than necessary, but we can account for this by adjusting
17267 // for the Just Noticeable Difference.
17268 var earliestExpirationTime = findEarliestOutstandingPriorityLevel(root, renderExpirationTime);
17269 var earliestExpirationTimeMs = expirationTimeToMs(earliestExpirationTime);
17270 startTimeMs = earliestExpirationTimeMs - LOW_PRIORITY_EXPIRATION;
17271 }
17272 absoluteTimeoutMs = startTimeMs + earliestTimeoutMs;
17273 }
17274
17275 // Mark the earliest timeout in the suspended fiber's ancestor path.
17276 // After completing the root, we'll take the largest of all the
17277 // suspended fiber's timeouts and use it to compute a timeout for the
17278 // whole tree.
17279 renderDidSuspend(root, absoluteTimeoutMs, renderExpirationTime);
17280
17281 _workInProgress.effectTag |= ShouldCapture;
17282 _workInProgress.expirationTime = renderExpirationTime;
17283 return;
17284 }
17285 // This boundary already captured during this render. Continue to the next
17286 // boundary.
17287 _workInProgress = _workInProgress.return;
17288 } while (_workInProgress !== null);
17289 // No boundary was found. Fallthrough to error mode.
17290 // TODO: Use invariant so the message is stripped in prod?
17291 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));
17292 }
17293
17294 // We didn't find a boundary that could handle this type of exception. Start
17295 // over and traverse parent path again, this time treating the exception
17296 // as an error.
17297 renderDidError();
17298 value = createCapturedValue(value, sourceFiber);
17299 var workInProgress = returnFiber;
17300 do {
17301 switch (workInProgress.tag) {
17302 case HostRoot:
17303 {
17304 var _errorInfo = value;
17305 workInProgress.effectTag |= ShouldCapture;
17306 workInProgress.expirationTime = renderExpirationTime;
17307 var _update = createRootErrorUpdate(workInProgress, _errorInfo, renderExpirationTime);
17308 enqueueCapturedUpdate(workInProgress, _update);
17309 return;
17310 }
17311 case ClassComponent:
17312 // Capture and retry
17313 var errorInfo = value;
17314 var ctor = workInProgress.type;
17315 var instance = workInProgress.stateNode;
17316 if ((workInProgress.effectTag & DidCapture) === NoEffect && (typeof ctor.getDerivedStateFromError === 'function' || instance !== null && typeof instance.componentDidCatch === 'function' && !isAlreadyFailedLegacyErrorBoundary(instance))) {
17317 workInProgress.effectTag |= ShouldCapture;
17318 workInProgress.expirationTime = renderExpirationTime;
17319 // Schedule the error boundary to re-render using updated state
17320 var _update2 = createClassErrorUpdate(workInProgress, errorInfo, renderExpirationTime);
17321 enqueueCapturedUpdate(workInProgress, _update2);
17322 return;
17323 }
17324 break;
17325 default:
17326 break;
17327 }
17328 workInProgress = workInProgress.return;
17329 } while (workInProgress !== null);
17330}
17331
17332function unwindWork(workInProgress, renderExpirationTime) {
17333 switch (workInProgress.tag) {
17334 case ClassComponent:
17335 {
17336 var Component = workInProgress.type;
17337 if (isContextProvider(Component)) {
17338 popContext(workInProgress);
17339 }
17340 var effectTag = workInProgress.effectTag;
17341 if (effectTag & ShouldCapture) {
17342 workInProgress.effectTag = effectTag & ~ShouldCapture | DidCapture;
17343 return workInProgress;
17344 }
17345 return null;
17346 }
17347 case HostRoot:
17348 {
17349 popHostContainer(workInProgress);
17350 popTopLevelContextObject(workInProgress);
17351 var _effectTag = workInProgress.effectTag;
17352 !((_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;
17353 workInProgress.effectTag = _effectTag & ~ShouldCapture | DidCapture;
17354 return workInProgress;
17355 }
17356 case HostComponent:
17357 {
17358 popHostContext(workInProgress);
17359 return null;
17360 }
17361 case SuspenseComponent:
17362 {
17363 var _effectTag2 = workInProgress.effectTag;
17364 if (_effectTag2 & ShouldCapture) {
17365 workInProgress.effectTag = _effectTag2 & ~ShouldCapture | DidCapture;
17366 // Captured a suspense effect. Re-render the boundary.
17367 return workInProgress;
17368 }
17369 return null;
17370 }
17371 case HostPortal:
17372 popHostContainer(workInProgress);
17373 return null;
17374 case ContextProvider:
17375 popProvider(workInProgress);
17376 return null;
17377 default:
17378 return null;
17379 }
17380}
17381
17382function unwindInterruptedWork(interruptedWork) {
17383 switch (interruptedWork.tag) {
17384 case ClassComponent:
17385 {
17386 var childContextTypes = interruptedWork.type.childContextTypes;
17387 if (childContextTypes !== null && childContextTypes !== undefined) {
17388 popContext(interruptedWork);
17389 }
17390 break;
17391 }
17392 case HostRoot:
17393 {
17394 popHostContainer(interruptedWork);
17395 popTopLevelContextObject(interruptedWork);
17396 break;
17397 }
17398 case HostComponent:
17399 {
17400 popHostContext(interruptedWork);
17401 break;
17402 }
17403 case HostPortal:
17404 popHostContainer(interruptedWork);
17405 break;
17406 case ContextProvider:
17407 popProvider(interruptedWork);
17408 break;
17409 default:
17410 break;
17411 }
17412}
17413
17414var Dispatcher = {
17415 readContext: readContext,
17416 useCallback: useCallback,
17417 useContext: useContext,
17418 useEffect: useEffect,
17419 useImperativeMethods: useImperativeMethods,
17420 useLayoutEffect: useLayoutEffect,
17421 useMemo: useMemo,
17422 useReducer: useReducer,
17423 useRef: useRef,
17424 useState: useState
17425};
17426var DispatcherWithoutHooks = {
17427 readContext: readContext
17428};
17429
17430var ReactCurrentOwner$2 = ReactSharedInternals.ReactCurrentOwner;
17431
17432
17433var didWarnAboutStateTransition = void 0;
17434var didWarnSetStateChildContext = void 0;
17435var warnAboutUpdateOnUnmounted = void 0;
17436var warnAboutInvalidUpdates = void 0;
17437
17438if (enableSchedulerTracing) {
17439 // Provide explicit error message when production+profiling bundle of e.g. react-dom
17440 // is used with production (non-profiling) bundle of scheduler/tracing
17441 !(__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;
17442}
17443
17444{
17445 didWarnAboutStateTransition = false;
17446 didWarnSetStateChildContext = false;
17447 var didWarnStateUpdateForUnmountedComponent = {};
17448
17449 warnAboutUpdateOnUnmounted = function (fiber, isClass) {
17450 // We show the whole stack but dedupe on the top component's name because
17451 // the problematic code almost always lies inside that component.
17452 var componentName = getComponentName(fiber.type) || 'ReactComponent';
17453 if (didWarnStateUpdateForUnmountedComponent[componentName]) {
17454 return;
17455 }
17456 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));
17457 didWarnStateUpdateForUnmountedComponent[componentName] = true;
17458 };
17459
17460 warnAboutInvalidUpdates = function (instance) {
17461 switch (phase) {
17462 case 'getChildContext':
17463 if (didWarnSetStateChildContext) {
17464 return;
17465 }
17466 warningWithoutStack$1(false, 'setState(...): Cannot call setState() inside getChildContext()');
17467 didWarnSetStateChildContext = true;
17468 break;
17469 case 'render':
17470 if (didWarnAboutStateTransition) {
17471 return;
17472 }
17473 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.');
17474 didWarnAboutStateTransition = true;
17475 break;
17476 }
17477 };
17478}
17479
17480// Used to ensure computeUniqueAsyncExpiration is monotonically decreasing.
17481var lastUniqueAsyncExpiration = Sync - 1;
17482
17483// Represents the expiration time that incoming updates should use. (If this
17484// is NoWork, use the default strategy: async updates in async mode, sync
17485// updates in sync mode.)
17486var expirationContext = NoWork;
17487
17488var isWorking = false;
17489
17490// The next work in progress fiber that we're currently working on.
17491var nextUnitOfWork = null;
17492var nextRoot = null;
17493// The time at which we're currently rendering work.
17494var nextRenderExpirationTime = NoWork;
17495var nextLatestAbsoluteTimeoutMs = -1;
17496var nextRenderDidError = false;
17497
17498// The next fiber with an effect that we're currently committing.
17499var nextEffect = null;
17500
17501var isCommitting$1 = false;
17502var rootWithPendingPassiveEffects = null;
17503var passiveEffectCallbackHandle = null;
17504var passiveEffectCallback = null;
17505
17506var legacyErrorBoundariesThatAlreadyFailed = null;
17507
17508// Used for performance tracking.
17509var interruptedBy = null;
17510
17511var stashedWorkInProgressProperties = void 0;
17512var replayUnitOfWork = void 0;
17513var mayReplayFailedUnitOfWork = void 0;
17514var isReplayingFailedUnitOfWork = void 0;
17515var originalReplayError = void 0;
17516var rethrowOriginalError = void 0;
17517if (true && replayFailedUnitOfWorkWithInvokeGuardedCallback) {
17518 stashedWorkInProgressProperties = null;
17519 mayReplayFailedUnitOfWork = true;
17520 isReplayingFailedUnitOfWork = false;
17521 originalReplayError = null;
17522 replayUnitOfWork = function (failedUnitOfWork, thrownValue, isYieldy) {
17523 if (thrownValue !== null && typeof thrownValue === 'object' && typeof thrownValue.then === 'function') {
17524 // Don't replay promises. Treat everything else like an error.
17525 // TODO: Need to figure out a different strategy if/when we add
17526 // support for catching other types.
17527 return;
17528 }
17529
17530 // Restore the original state of the work-in-progress
17531 if (stashedWorkInProgressProperties === null) {
17532 // This should never happen. Don't throw because this code is DEV-only.
17533 warningWithoutStack$1(false, 'Could not replay rendering after an error. This is likely a bug in React. ' + 'Please file an issue.');
17534 return;
17535 }
17536 assignFiberPropertiesInDEV(failedUnitOfWork, stashedWorkInProgressProperties);
17537
17538 switch (failedUnitOfWork.tag) {
17539 case HostRoot:
17540 popHostContainer(failedUnitOfWork);
17541 popTopLevelContextObject(failedUnitOfWork);
17542 break;
17543 case HostComponent:
17544 popHostContext(failedUnitOfWork);
17545 break;
17546 case ClassComponent:
17547 {
17548 var Component = failedUnitOfWork.type;
17549 if (isContextProvider(Component)) {
17550 popContext(failedUnitOfWork);
17551 }
17552 break;
17553 }
17554 case HostPortal:
17555 popHostContainer(failedUnitOfWork);
17556 break;
17557 case ContextProvider:
17558 popProvider(failedUnitOfWork);
17559 break;
17560 }
17561 // Replay the begin phase.
17562 isReplayingFailedUnitOfWork = true;
17563 originalReplayError = thrownValue;
17564 invokeGuardedCallback(null, workLoop, null, isYieldy);
17565 isReplayingFailedUnitOfWork = false;
17566 originalReplayError = null;
17567 if (hasCaughtError()) {
17568 var replayError = clearCaughtError();
17569 if (replayError != null && thrownValue != null) {
17570 try {
17571 // Reading the expando property is intentionally
17572 // inside `try` because it might be a getter or Proxy.
17573 if (replayError._suppressLogging) {
17574 // Also suppress logging for the original error.
17575 thrownValue._suppressLogging = true;
17576 }
17577 } catch (inner) {
17578 // Ignore.
17579 }
17580 }
17581 } else {
17582 // If the begin phase did not fail the second time, set this pointer
17583 // back to the original value.
17584 nextUnitOfWork = failedUnitOfWork;
17585 }
17586 };
17587 rethrowOriginalError = function () {
17588 throw originalReplayError;
17589 };
17590}
17591
17592function resetStack() {
17593 if (nextUnitOfWork !== null) {
17594 var interruptedWork = nextUnitOfWork.return;
17595 while (interruptedWork !== null) {
17596 unwindInterruptedWork(interruptedWork);
17597 interruptedWork = interruptedWork.return;
17598 }
17599 }
17600
17601 {
17602 ReactStrictModeWarnings.discardPendingWarnings();
17603 checkThatStackIsEmpty();
17604 }
17605
17606 nextRoot = null;
17607 nextRenderExpirationTime = NoWork;
17608 nextLatestAbsoluteTimeoutMs = -1;
17609 nextRenderDidError = false;
17610 nextUnitOfWork = null;
17611}
17612
17613function commitAllHostEffects() {
17614 while (nextEffect !== null) {
17615 {
17616 setCurrentFiber(nextEffect);
17617 }
17618 recordEffect();
17619
17620 var effectTag = nextEffect.effectTag;
17621
17622 if (effectTag & ContentReset) {
17623 commitResetTextContent(nextEffect);
17624 }
17625
17626 if (effectTag & Ref) {
17627 var current$$1 = nextEffect.alternate;
17628 if (current$$1 !== null) {
17629 commitDetachRef(current$$1);
17630 }
17631 }
17632
17633 // The following switch statement is only concerned about placement,
17634 // updates, and deletions. To avoid needing to add a case for every
17635 // possible bitmap value, we remove the secondary effects from the
17636 // effect tag and switch on that value.
17637 var primaryEffectTag = effectTag & (Placement | Update | Deletion);
17638 switch (primaryEffectTag) {
17639 case Placement:
17640 {
17641 commitPlacement(nextEffect);
17642 // Clear the "placement" from effect tag so that we know that this is inserted, before
17643 // any life-cycles like componentDidMount gets called.
17644 // TODO: findDOMNode doesn't rely on this any more but isMounted
17645 // does and isMounted is deprecated anyway so we should be able
17646 // to kill this.
17647 nextEffect.effectTag &= ~Placement;
17648 break;
17649 }
17650 case PlacementAndUpdate:
17651 {
17652 // Placement
17653 commitPlacement(nextEffect);
17654 // Clear the "placement" from effect tag so that we know that this is inserted, before
17655 // any life-cycles like componentDidMount gets called.
17656 nextEffect.effectTag &= ~Placement;
17657
17658 // Update
17659 var _current = nextEffect.alternate;
17660 commitWork(_current, nextEffect);
17661 break;
17662 }
17663 case Update:
17664 {
17665 var _current2 = nextEffect.alternate;
17666 commitWork(_current2, nextEffect);
17667 break;
17668 }
17669 case Deletion:
17670 {
17671 commitDeletion(nextEffect);
17672 break;
17673 }
17674 }
17675 nextEffect = nextEffect.nextEffect;
17676 }
17677
17678 {
17679 resetCurrentFiber();
17680 }
17681}
17682
17683function commitBeforeMutationLifecycles() {
17684 while (nextEffect !== null) {
17685 {
17686 setCurrentFiber(nextEffect);
17687 }
17688
17689 var effectTag = nextEffect.effectTag;
17690 if (effectTag & Snapshot) {
17691 recordEffect();
17692 var current$$1 = nextEffect.alternate;
17693 commitBeforeMutationLifeCycles(current$$1, nextEffect);
17694 }
17695
17696 nextEffect = nextEffect.nextEffect;
17697 }
17698
17699 {
17700 resetCurrentFiber();
17701 }
17702}
17703
17704function commitAllLifeCycles(finishedRoot, committedExpirationTime) {
17705 {
17706 ReactStrictModeWarnings.flushPendingUnsafeLifecycleWarnings();
17707 ReactStrictModeWarnings.flushLegacyContextWarning();
17708
17709 if (warnAboutDeprecatedLifecycles) {
17710 ReactStrictModeWarnings.flushPendingDeprecationWarnings();
17711 }
17712 }
17713 while (nextEffect !== null) {
17714 var effectTag = nextEffect.effectTag;
17715
17716 if (effectTag & (Update | Callback)) {
17717 recordEffect();
17718 var current$$1 = nextEffect.alternate;
17719 commitLifeCycles(finishedRoot, current$$1, nextEffect, committedExpirationTime);
17720 }
17721
17722 if (effectTag & Ref) {
17723 recordEffect();
17724 commitAttachRef(nextEffect);
17725 }
17726
17727 if (enableHooks && effectTag & Passive) {
17728 rootWithPendingPassiveEffects = finishedRoot;
17729 }
17730
17731 nextEffect = nextEffect.nextEffect;
17732 }
17733}
17734
17735function commitPassiveEffects(root, firstEffect) {
17736 rootWithPendingPassiveEffects = null;
17737 passiveEffectCallbackHandle = null;
17738 passiveEffectCallback = null;
17739
17740 // Set this to true to prevent re-entrancy
17741 var previousIsRendering = isRendering;
17742 isRendering = true;
17743
17744 var effect = firstEffect;
17745 do {
17746 if (effect.effectTag & Passive) {
17747 var didError = false;
17748 var error = void 0;
17749 {
17750 invokeGuardedCallback(null, commitPassiveHookEffects, null, effect);
17751 if (hasCaughtError()) {
17752 didError = true;
17753 error = clearCaughtError();
17754 }
17755 }
17756 if (didError) {
17757 captureCommitPhaseError(effect, error);
17758 }
17759 }
17760 effect = effect.nextEffect;
17761 } while (effect !== null);
17762
17763 isRendering = previousIsRendering;
17764
17765 // Check if work was scheduled by one of the effects
17766 var rootExpirationTime = root.expirationTime;
17767 if (rootExpirationTime !== NoWork) {
17768 requestWork(root, rootExpirationTime);
17769 }
17770}
17771
17772function isAlreadyFailedLegacyErrorBoundary(instance) {
17773 return legacyErrorBoundariesThatAlreadyFailed !== null && legacyErrorBoundariesThatAlreadyFailed.has(instance);
17774}
17775
17776function markLegacyErrorBoundaryAsFailed(instance) {
17777 if (legacyErrorBoundariesThatAlreadyFailed === null) {
17778 legacyErrorBoundariesThatAlreadyFailed = new Set([instance]);
17779 } else {
17780 legacyErrorBoundariesThatAlreadyFailed.add(instance);
17781 }
17782}
17783
17784function flushPassiveEffects() {
17785 if (passiveEffectCallback !== null) {
17786 unstable_cancelCallback(passiveEffectCallbackHandle);
17787 // We call the scheduled callback instead of commitPassiveEffects directly
17788 // to ensure tracing works correctly.
17789 passiveEffectCallback();
17790 }
17791}
17792
17793function commitRoot(root, finishedWork) {
17794 isWorking = true;
17795 isCommitting$1 = true;
17796 startCommitTimer();
17797
17798 !(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;
17799 var committedExpirationTime = root.pendingCommitExpirationTime;
17800 !(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;
17801 root.pendingCommitExpirationTime = NoWork;
17802
17803 // Update the pending priority levels to account for the work that we are
17804 // about to commit. This needs to happen before calling the lifecycles, since
17805 // they may schedule additional updates.
17806 var updateExpirationTimeBeforeCommit = finishedWork.expirationTime;
17807 var childExpirationTimeBeforeCommit = finishedWork.childExpirationTime;
17808 var earliestRemainingTimeBeforeCommit = childExpirationTimeBeforeCommit > updateExpirationTimeBeforeCommit ? childExpirationTimeBeforeCommit : updateExpirationTimeBeforeCommit;
17809 markCommittedPriorityLevels(root, earliestRemainingTimeBeforeCommit);
17810
17811 var prevInteractions = null;
17812 if (enableSchedulerTracing) {
17813 // Restore any pending interactions at this point,
17814 // So that cascading work triggered during the render phase will be accounted for.
17815 prevInteractions = __interactionsRef.current;
17816 __interactionsRef.current = root.memoizedInteractions;
17817 }
17818
17819 // Reset this to null before calling lifecycles
17820 ReactCurrentOwner$2.current = null;
17821
17822 var firstEffect = void 0;
17823 if (finishedWork.effectTag > PerformedWork) {
17824 // A fiber's effect list consists only of its children, not itself. So if
17825 // the root has an effect, we need to add it to the end of the list. The
17826 // resulting list is the set that would belong to the root's parent, if
17827 // it had one; that is, all the effects in the tree including the root.
17828 if (finishedWork.lastEffect !== null) {
17829 finishedWork.lastEffect.nextEffect = finishedWork;
17830 firstEffect = finishedWork.firstEffect;
17831 } else {
17832 firstEffect = finishedWork;
17833 }
17834 } else {
17835 // There is no effect on the root.
17836 firstEffect = finishedWork.firstEffect;
17837 }
17838
17839 prepareForCommit(root.containerInfo);
17840
17841 // Invoke instances of getSnapshotBeforeUpdate before mutation.
17842 nextEffect = firstEffect;
17843 startCommitSnapshotEffectsTimer();
17844 while (nextEffect !== null) {
17845 var didError = false;
17846 var error = void 0;
17847 {
17848 invokeGuardedCallback(null, commitBeforeMutationLifecycles, null);
17849 if (hasCaughtError()) {
17850 didError = true;
17851 error = clearCaughtError();
17852 }
17853 }
17854 if (didError) {
17855 !(nextEffect !== null) ? invariant(false, 'Should have next effect. This error is likely caused by a bug in React. Please file an issue.') : void 0;
17856 captureCommitPhaseError(nextEffect, error);
17857 // Clean-up
17858 if (nextEffect !== null) {
17859 nextEffect = nextEffect.nextEffect;
17860 }
17861 }
17862 }
17863 stopCommitSnapshotEffectsTimer();
17864
17865 if (enableProfilerTimer) {
17866 // Mark the current commit time to be shared by all Profilers in this batch.
17867 // This enables them to be grouped later.
17868 recordCommitTime();
17869 }
17870
17871 // Commit all the side-effects within a tree. We'll do this in two passes.
17872 // The first pass performs all the host insertions, updates, deletions and
17873 // ref unmounts.
17874 nextEffect = firstEffect;
17875 startCommitHostEffectsTimer();
17876 while (nextEffect !== null) {
17877 var _didError = false;
17878 var _error = void 0;
17879 {
17880 invokeGuardedCallback(null, commitAllHostEffects, null);
17881 if (hasCaughtError()) {
17882 _didError = true;
17883 _error = clearCaughtError();
17884 }
17885 }
17886 if (_didError) {
17887 !(nextEffect !== null) ? invariant(false, 'Should have next effect. This error is likely caused by a bug in React. Please file an issue.') : void 0;
17888 captureCommitPhaseError(nextEffect, _error);
17889 // Clean-up
17890 if (nextEffect !== null) {
17891 nextEffect = nextEffect.nextEffect;
17892 }
17893 }
17894 }
17895 stopCommitHostEffectsTimer();
17896
17897 resetAfterCommit(root.containerInfo);
17898
17899 // The work-in-progress tree is now the current tree. This must come after
17900 // the first pass of the commit phase, so that the previous tree is still
17901 // current during componentWillUnmount, but before the second pass, so that
17902 // the finished work is current during componentDidMount/Update.
17903 root.current = finishedWork;
17904
17905 // In the second pass we'll perform all life-cycles and ref callbacks.
17906 // Life-cycles happen as a separate pass so that all placements, updates,
17907 // and deletions in the entire tree have already been invoked.
17908 // This pass also triggers any renderer-specific initial effects.
17909 nextEffect = firstEffect;
17910 startCommitLifeCyclesTimer();
17911 while (nextEffect !== null) {
17912 var _didError2 = false;
17913 var _error2 = void 0;
17914 {
17915 invokeGuardedCallback(null, commitAllLifeCycles, null, root, committedExpirationTime);
17916 if (hasCaughtError()) {
17917 _didError2 = true;
17918 _error2 = clearCaughtError();
17919 }
17920 }
17921 if (_didError2) {
17922 !(nextEffect !== null) ? invariant(false, 'Should have next effect. This error is likely caused by a bug in React. Please file an issue.') : void 0;
17923 captureCommitPhaseError(nextEffect, _error2);
17924 if (nextEffect !== null) {
17925 nextEffect = nextEffect.nextEffect;
17926 }
17927 }
17928 }
17929
17930 if (enableHooks && firstEffect !== null && rootWithPendingPassiveEffects !== null) {
17931 // This commit included a passive effect. These do not need to fire until
17932 // after the next paint. Schedule an callback to fire them in an async
17933 // event. To ensure serial execution, the callback will be flushed early if
17934 // we enter rootWithPendingPassiveEffects commit phase before then.
17935 var callback = commitPassiveEffects.bind(null, root, firstEffect);
17936 if (enableSchedulerTracing) {
17937 // TODO: Avoid this extra callback by mutating the tracing ref directly,
17938 // like we do at the beginning of commitRoot. I've opted not to do that
17939 // here because that code is still in flux.
17940 callback = unstable_wrap(callback);
17941 }
17942 passiveEffectCallbackHandle = unstable_scheduleCallback(callback);
17943 passiveEffectCallback = callback;
17944 }
17945
17946 isCommitting$1 = false;
17947 isWorking = false;
17948 stopCommitLifeCyclesTimer();
17949 stopCommitTimer();
17950 onCommitRoot(finishedWork.stateNode);
17951 if (true && ReactFiberInstrumentation_1.debugTool) {
17952 ReactFiberInstrumentation_1.debugTool.onCommitWork(finishedWork);
17953 }
17954
17955 var updateExpirationTimeAfterCommit = finishedWork.expirationTime;
17956 var childExpirationTimeAfterCommit = finishedWork.childExpirationTime;
17957 var earliestRemainingTimeAfterCommit = childExpirationTimeAfterCommit > updateExpirationTimeAfterCommit ? childExpirationTimeAfterCommit : updateExpirationTimeAfterCommit;
17958 if (earliestRemainingTimeAfterCommit === NoWork) {
17959 // If there's no remaining work, we can clear the set of already failed
17960 // error boundaries.
17961 legacyErrorBoundariesThatAlreadyFailed = null;
17962 }
17963 onCommit(root, earliestRemainingTimeAfterCommit);
17964
17965 if (enableSchedulerTracing) {
17966 __interactionsRef.current = prevInteractions;
17967
17968 var subscriber = void 0;
17969
17970 try {
17971 subscriber = __subscriberRef.current;
17972 if (subscriber !== null && root.memoizedInteractions.size > 0) {
17973 var threadID = computeThreadID(committedExpirationTime, root.interactionThreadID);
17974 subscriber.onWorkStopped(root.memoizedInteractions, threadID);
17975 }
17976 } catch (error) {
17977 // It's not safe for commitRoot() to throw.
17978 // Store the error for now and we'll re-throw in finishRendering().
17979 if (!hasUnhandledError) {
17980 hasUnhandledError = true;
17981 unhandledError = error;
17982 }
17983 } finally {
17984 // Clear completed interactions from the pending Map.
17985 // Unless the render was suspended or cascading work was scheduled,
17986 // In which case– leave pending interactions until the subsequent render.
17987 var pendingInteractionMap = root.pendingInteractionMap;
17988 pendingInteractionMap.forEach(function (scheduledInteractions, scheduledExpirationTime) {
17989 // Only decrement the pending interaction count if we're done.
17990 // If there's still work at the current priority,
17991 // That indicates that we are waiting for suspense data.
17992 if (scheduledExpirationTime > earliestRemainingTimeAfterCommit) {
17993 pendingInteractionMap.delete(scheduledExpirationTime);
17994
17995 scheduledInteractions.forEach(function (interaction) {
17996 interaction.__count--;
17997
17998 if (subscriber !== null && interaction.__count === 0) {
17999 try {
18000 subscriber.onInteractionScheduledWorkCompleted(interaction);
18001 } catch (error) {
18002 // It's not safe for commitRoot() to throw.
18003 // Store the error for now and we'll re-throw in finishRendering().
18004 if (!hasUnhandledError) {
18005 hasUnhandledError = true;
18006 unhandledError = error;
18007 }
18008 }
18009 }
18010 });
18011 }
18012 });
18013 }
18014 }
18015}
18016
18017function resetChildExpirationTime(workInProgress, renderTime) {
18018 if (renderTime !== Never && workInProgress.childExpirationTime === Never) {
18019 // The children of this component are hidden. Don't bubble their
18020 // expiration times.
18021 return;
18022 }
18023
18024 var newChildExpirationTime = NoWork;
18025
18026 // Bubble up the earliest expiration time.
18027 if (enableProfilerTimer && workInProgress.mode & ProfileMode) {
18028 // We're in profiling mode.
18029 // Let's use this same traversal to update the render durations.
18030 var actualDuration = workInProgress.actualDuration;
18031 var treeBaseDuration = workInProgress.selfBaseDuration;
18032
18033 // When a fiber is cloned, its actualDuration is reset to 0.
18034 // This value will only be updated if work is done on the fiber (i.e. it doesn't bailout).
18035 // When work is done, it should bubble to the parent's actualDuration.
18036 // If the fiber has not been cloned though, (meaning no work was done),
18037 // Then this value will reflect the amount of time spent working on a previous render.
18038 // In that case it should not bubble.
18039 // We determine whether it was cloned by comparing the child pointer.
18040 var shouldBubbleActualDurations = workInProgress.alternate === null || workInProgress.child !== workInProgress.alternate.child;
18041
18042 var child = workInProgress.child;
18043 while (child !== null) {
18044 var childUpdateExpirationTime = child.expirationTime;
18045 var childChildExpirationTime = child.childExpirationTime;
18046 if (childUpdateExpirationTime > newChildExpirationTime) {
18047 newChildExpirationTime = childUpdateExpirationTime;
18048 }
18049 if (childChildExpirationTime > newChildExpirationTime) {
18050 newChildExpirationTime = childChildExpirationTime;
18051 }
18052 if (shouldBubbleActualDurations) {
18053 actualDuration += child.actualDuration;
18054 }
18055 treeBaseDuration += child.treeBaseDuration;
18056 child = child.sibling;
18057 }
18058 workInProgress.actualDuration = actualDuration;
18059 workInProgress.treeBaseDuration = treeBaseDuration;
18060 } else {
18061 var _child = workInProgress.child;
18062 while (_child !== null) {
18063 var _childUpdateExpirationTime = _child.expirationTime;
18064 var _childChildExpirationTime = _child.childExpirationTime;
18065 if (_childUpdateExpirationTime > newChildExpirationTime) {
18066 newChildExpirationTime = _childUpdateExpirationTime;
18067 }
18068 if (_childChildExpirationTime > newChildExpirationTime) {
18069 newChildExpirationTime = _childChildExpirationTime;
18070 }
18071 _child = _child.sibling;
18072 }
18073 }
18074
18075 workInProgress.childExpirationTime = newChildExpirationTime;
18076}
18077
18078function completeUnitOfWork(workInProgress) {
18079 // Attempt to complete the current unit of work, then move to the
18080 // next sibling. If there are no more siblings, return to the
18081 // parent fiber.
18082 while (true) {
18083 // The current, flushed, state of this fiber is the alternate.
18084 // Ideally nothing should rely on this, but relying on it here
18085 // means that we don't need an additional field on the work in
18086 // progress.
18087 var current$$1 = workInProgress.alternate;
18088 {
18089 setCurrentFiber(workInProgress);
18090 }
18091
18092 var returnFiber = workInProgress.return;
18093 var siblingFiber = workInProgress.sibling;
18094
18095 if ((workInProgress.effectTag & Incomplete) === NoEffect) {
18096 if (true && replayFailedUnitOfWorkWithInvokeGuardedCallback) {
18097 // Don't replay if it fails during completion phase.
18098 mayReplayFailedUnitOfWork = false;
18099 }
18100 // This fiber completed.
18101 // Remember we're completing this unit so we can find a boundary if it fails.
18102 nextUnitOfWork = workInProgress;
18103 if (enableProfilerTimer) {
18104 if (workInProgress.mode & ProfileMode) {
18105 startProfilerTimer(workInProgress);
18106 }
18107 nextUnitOfWork = completeWork(current$$1, workInProgress, nextRenderExpirationTime);
18108 if (workInProgress.mode & ProfileMode) {
18109 // Update render duration assuming we didn't error.
18110 stopProfilerTimerIfRunningAndRecordDelta(workInProgress, false);
18111 }
18112 } else {
18113 nextUnitOfWork = completeWork(current$$1, workInProgress, nextRenderExpirationTime);
18114 }
18115 if (true && replayFailedUnitOfWorkWithInvokeGuardedCallback) {
18116 // We're out of completion phase so replaying is fine now.
18117 mayReplayFailedUnitOfWork = true;
18118 }
18119 stopWorkTimer(workInProgress);
18120 resetChildExpirationTime(workInProgress, nextRenderExpirationTime);
18121 {
18122 resetCurrentFiber();
18123 }
18124
18125 if (nextUnitOfWork !== null) {
18126 // Completing this fiber spawned new work. Work on that next.
18127 return nextUnitOfWork;
18128 }
18129
18130 if (returnFiber !== null &&
18131 // Do not append effects to parents if a sibling failed to complete
18132 (returnFiber.effectTag & Incomplete) === NoEffect) {
18133 // Append all the effects of the subtree and this fiber onto the effect
18134 // list of the parent. The completion order of the children affects the
18135 // side-effect order.
18136 if (returnFiber.firstEffect === null) {
18137 returnFiber.firstEffect = workInProgress.firstEffect;
18138 }
18139 if (workInProgress.lastEffect !== null) {
18140 if (returnFiber.lastEffect !== null) {
18141 returnFiber.lastEffect.nextEffect = workInProgress.firstEffect;
18142 }
18143 returnFiber.lastEffect = workInProgress.lastEffect;
18144 }
18145
18146 // If this fiber had side-effects, we append it AFTER the children's
18147 // side-effects. We can perform certain side-effects earlier if
18148 // needed, by doing multiple passes over the effect list. We don't want
18149 // to schedule our own side-effect on our own list because if end up
18150 // reusing children we'll schedule this effect onto itself since we're
18151 // at the end.
18152 var effectTag = workInProgress.effectTag;
18153 // Skip both NoWork and PerformedWork tags when creating the effect list.
18154 // PerformedWork effect is read by React DevTools but shouldn't be committed.
18155 if (effectTag > PerformedWork) {
18156 if (returnFiber.lastEffect !== null) {
18157 returnFiber.lastEffect.nextEffect = workInProgress;
18158 } else {
18159 returnFiber.firstEffect = workInProgress;
18160 }
18161 returnFiber.lastEffect = workInProgress;
18162 }
18163 }
18164
18165 if (true && ReactFiberInstrumentation_1.debugTool) {
18166 ReactFiberInstrumentation_1.debugTool.onCompleteWork(workInProgress);
18167 }
18168
18169 if (siblingFiber !== null) {
18170 // If there is more work to do in this returnFiber, do that next.
18171 return siblingFiber;
18172 } else if (returnFiber !== null) {
18173 // If there's no more work in this returnFiber. Complete the returnFiber.
18174 workInProgress = returnFiber;
18175 continue;
18176 } else {
18177 // We've reached the root.
18178 return null;
18179 }
18180 } else {
18181 if (enableProfilerTimer && workInProgress.mode & ProfileMode) {
18182 // Record the render duration for the fiber that errored.
18183 stopProfilerTimerIfRunningAndRecordDelta(workInProgress, false);
18184
18185 // Include the time spent working on failed children before continuing.
18186 var actualDuration = workInProgress.actualDuration;
18187 var child = workInProgress.child;
18188 while (child !== null) {
18189 actualDuration += child.actualDuration;
18190 child = child.sibling;
18191 }
18192 workInProgress.actualDuration = actualDuration;
18193 }
18194
18195 // This fiber did not complete because something threw. Pop values off
18196 // the stack without entering the complete phase. If this is a boundary,
18197 // capture values if possible.
18198 var next = unwindWork(workInProgress, nextRenderExpirationTime);
18199 // Because this fiber did not complete, don't reset its expiration time.
18200 if (workInProgress.effectTag & DidCapture) {
18201 // Restarting an error boundary
18202 stopFailedWorkTimer(workInProgress);
18203 } else {
18204 stopWorkTimer(workInProgress);
18205 }
18206
18207 {
18208 resetCurrentFiber();
18209 }
18210
18211 if (next !== null) {
18212 stopWorkTimer(workInProgress);
18213 if (true && ReactFiberInstrumentation_1.debugTool) {
18214 ReactFiberInstrumentation_1.debugTool.onCompleteWork(workInProgress);
18215 }
18216
18217 // If completing this work spawned new work, do that next. We'll come
18218 // back here again.
18219 // Since we're restarting, remove anything that is not a host effect
18220 // from the effect tag.
18221 next.effectTag &= HostEffectMask;
18222 return next;
18223 }
18224
18225 if (returnFiber !== null) {
18226 // Mark the parent fiber as incomplete and clear its effect list.
18227 returnFiber.firstEffect = returnFiber.lastEffect = null;
18228 returnFiber.effectTag |= Incomplete;
18229 }
18230
18231 if (true && ReactFiberInstrumentation_1.debugTool) {
18232 ReactFiberInstrumentation_1.debugTool.onCompleteWork(workInProgress);
18233 }
18234
18235 if (siblingFiber !== null) {
18236 // If there is more work to do in this returnFiber, do that next.
18237 return siblingFiber;
18238 } else if (returnFiber !== null) {
18239 // If there's no more work in this returnFiber. Complete the returnFiber.
18240 workInProgress = returnFiber;
18241 continue;
18242 } else {
18243 return null;
18244 }
18245 }
18246 }
18247
18248 // Without this explicit null return Flow complains of invalid return type
18249 // TODO Remove the above while(true) loop
18250 // eslint-disable-next-line no-unreachable
18251 return null;
18252}
18253
18254function performUnitOfWork(workInProgress) {
18255 // The current, flushed, state of this fiber is the alternate.
18256 // Ideally nothing should rely on this, but relying on it here
18257 // means that we don't need an additional field on the work in
18258 // progress.
18259 var current$$1 = workInProgress.alternate;
18260
18261 // See if beginning this work spawns more work.
18262 startWorkTimer(workInProgress);
18263 {
18264 setCurrentFiber(workInProgress);
18265 }
18266
18267 if (true && replayFailedUnitOfWorkWithInvokeGuardedCallback) {
18268 stashedWorkInProgressProperties = assignFiberPropertiesInDEV(stashedWorkInProgressProperties, workInProgress);
18269 }
18270
18271 var next = void 0;
18272 if (enableProfilerTimer) {
18273 if (workInProgress.mode & ProfileMode) {
18274 startProfilerTimer(workInProgress);
18275 }
18276
18277 next = beginWork(current$$1, workInProgress, nextRenderExpirationTime);
18278 workInProgress.memoizedProps = workInProgress.pendingProps;
18279
18280 if (workInProgress.mode & ProfileMode) {
18281 // Record the render duration assuming we didn't bailout (or error).
18282 stopProfilerTimerIfRunningAndRecordDelta(workInProgress, true);
18283 }
18284 } else {
18285 next = beginWork(current$$1, workInProgress, nextRenderExpirationTime);
18286 workInProgress.memoizedProps = workInProgress.pendingProps;
18287 }
18288
18289 {
18290 resetCurrentFiber();
18291 if (isReplayingFailedUnitOfWork) {
18292 // Currently replaying a failed unit of work. This should be unreachable,
18293 // because the render phase is meant to be idempotent, and it should
18294 // have thrown again. Since it didn't, rethrow the original error, so
18295 // React's internal stack is not misaligned.
18296 rethrowOriginalError();
18297 }
18298 }
18299 if (true && ReactFiberInstrumentation_1.debugTool) {
18300 ReactFiberInstrumentation_1.debugTool.onBeginWork(workInProgress);
18301 }
18302
18303 if (next === null) {
18304 // If this doesn't spawn new work, complete the current work.
18305 next = completeUnitOfWork(workInProgress);
18306 }
18307
18308 ReactCurrentOwner$2.current = null;
18309
18310 return next;
18311}
18312
18313function workLoop(isYieldy) {
18314 if (!isYieldy) {
18315 // Flush work without yielding
18316 while (nextUnitOfWork !== null) {
18317 nextUnitOfWork = performUnitOfWork(nextUnitOfWork);
18318 }
18319 } else {
18320 // Flush asynchronous work until there's a higher priority event
18321 while (nextUnitOfWork !== null && !shouldYieldToRenderer()) {
18322 nextUnitOfWork = performUnitOfWork(nextUnitOfWork);
18323 }
18324 }
18325}
18326
18327function renderRoot(root, isYieldy) {
18328 !!isWorking ? invariant(false, 'renderRoot was called recursively. This error is likely caused by a bug in React. Please file an issue.') : void 0;
18329
18330 flushPassiveEffects();
18331
18332 isWorking = true;
18333 if (enableHooks) {
18334 ReactCurrentOwner$2.currentDispatcher = Dispatcher;
18335 } else {
18336 ReactCurrentOwner$2.currentDispatcher = DispatcherWithoutHooks;
18337 }
18338
18339 var expirationTime = root.nextExpirationTimeToWorkOn;
18340
18341 // Check if we're starting from a fresh stack, or if we're resuming from
18342 // previously yielded work.
18343 if (expirationTime !== nextRenderExpirationTime || root !== nextRoot || nextUnitOfWork === null) {
18344 // Reset the stack and start working from the root.
18345 resetStack();
18346 nextRoot = root;
18347 nextRenderExpirationTime = expirationTime;
18348 nextUnitOfWork = createWorkInProgress(nextRoot.current, null, nextRenderExpirationTime);
18349 root.pendingCommitExpirationTime = NoWork;
18350
18351 if (enableSchedulerTracing) {
18352 // Determine which interactions this batch of work currently includes,
18353 // So that we can accurately attribute time spent working on it,
18354 var interactions = new Set();
18355 root.pendingInteractionMap.forEach(function (scheduledInteractions, scheduledExpirationTime) {
18356 if (scheduledExpirationTime >= expirationTime) {
18357 scheduledInteractions.forEach(function (interaction) {
18358 return interactions.add(interaction);
18359 });
18360 }
18361 });
18362
18363 // Store the current set of interactions on the FiberRoot for a few reasons:
18364 // We can re-use it in hot functions like renderRoot() without having to recalculate it.
18365 // We will also use it in commitWork() to pass to any Profiler onRender() hooks.
18366 // This also provides DevTools with a way to access it when the onCommitRoot() hook is called.
18367 root.memoizedInteractions = interactions;
18368
18369 if (interactions.size > 0) {
18370 var subscriber = __subscriberRef.current;
18371 if (subscriber !== null) {
18372 var threadID = computeThreadID(expirationTime, root.interactionThreadID);
18373 try {
18374 subscriber.onWorkStarted(interactions, threadID);
18375 } catch (error) {
18376 // Work thrown by an interaction tracing subscriber should be rethrown,
18377 // But only once it's safe (to avoid leaveing the scheduler in an invalid state).
18378 // Store the error for now and we'll re-throw in finishRendering().
18379 if (!hasUnhandledError) {
18380 hasUnhandledError = true;
18381 unhandledError = error;
18382 }
18383 }
18384 }
18385 }
18386 }
18387 }
18388
18389 var prevInteractions = null;
18390 if (enableSchedulerTracing) {
18391 // We're about to start new traced work.
18392 // Restore pending interactions so cascading work triggered during the render phase will be accounted for.
18393 prevInteractions = __interactionsRef.current;
18394 __interactionsRef.current = root.memoizedInteractions;
18395 }
18396
18397 var didFatal = false;
18398
18399 startWorkLoopTimer(nextUnitOfWork);
18400
18401 do {
18402 try {
18403 workLoop(isYieldy);
18404 } catch (thrownValue) {
18405 resetContextDependences();
18406 resetHooks();
18407
18408 // Reset in case completion throws.
18409 // This is only used in DEV and when replaying is on.
18410 var mayReplay = void 0;
18411 if (true && replayFailedUnitOfWorkWithInvokeGuardedCallback) {
18412 mayReplay = mayReplayFailedUnitOfWork;
18413 mayReplayFailedUnitOfWork = true;
18414 }
18415
18416 if (nextUnitOfWork === null) {
18417 // This is a fatal error.
18418 didFatal = true;
18419 onUncaughtError(thrownValue);
18420 } else {
18421 if (enableProfilerTimer && nextUnitOfWork.mode & ProfileMode) {
18422 // Record the time spent rendering before an error was thrown.
18423 // This avoids inaccurate Profiler durations in the case of a suspended render.
18424 stopProfilerTimerIfRunningAndRecordDelta(nextUnitOfWork, true);
18425 }
18426
18427 {
18428 // Reset global debug state
18429 // We assume this is defined in DEV
18430 resetCurrentlyProcessingQueue();
18431 }
18432
18433 if (true && replayFailedUnitOfWorkWithInvokeGuardedCallback) {
18434 if (mayReplay) {
18435 var failedUnitOfWork = nextUnitOfWork;
18436 replayUnitOfWork(failedUnitOfWork, thrownValue, isYieldy);
18437 }
18438 }
18439
18440 // TODO: we already know this isn't true in some cases.
18441 // At least this shows a nicer error message until we figure out the cause.
18442 // https://github.com/facebook/react/issues/12449#issuecomment-386727431
18443 !(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;
18444
18445 var sourceFiber = nextUnitOfWork;
18446 var returnFiber = sourceFiber.return;
18447 if (returnFiber === null) {
18448 // This is the root. The root could capture its own errors. However,
18449 // we don't know if it errors before or after we pushed the host
18450 // context. This information is needed to avoid a stack mismatch.
18451 // Because we're not sure, treat this as a fatal error. We could track
18452 // which phase it fails in, but doesn't seem worth it. At least
18453 // for now.
18454 didFatal = true;
18455 onUncaughtError(thrownValue);
18456 } else {
18457 throwException(root, returnFiber, sourceFiber, thrownValue, nextRenderExpirationTime);
18458 nextUnitOfWork = completeUnitOfWork(sourceFiber);
18459 continue;
18460 }
18461 }
18462 }
18463 break;
18464 } while (true);
18465
18466 if (enableSchedulerTracing) {
18467 // Traced work is done for now; restore the previous interactions.
18468 __interactionsRef.current = prevInteractions;
18469 }
18470
18471 // We're done performing work. Time to clean up.
18472 isWorking = false;
18473 ReactCurrentOwner$2.currentDispatcher = null;
18474 resetContextDependences();
18475 resetHooks();
18476
18477 // Yield back to main thread.
18478 if (didFatal) {
18479 var _didCompleteRoot = false;
18480 stopWorkLoopTimer(interruptedBy, _didCompleteRoot);
18481 interruptedBy = null;
18482 // There was a fatal error.
18483 {
18484 resetStackAfterFatalErrorInDev();
18485 }
18486 // `nextRoot` points to the in-progress root. A non-null value indicates
18487 // that we're in the middle of an async render. Set it to null to indicate
18488 // there's no more work to be done in the current batch.
18489 nextRoot = null;
18490 onFatal(root);
18491 return;
18492 }
18493
18494 if (nextUnitOfWork !== null) {
18495 // There's still remaining async work in this tree, but we ran out of time
18496 // in the current frame. Yield back to the renderer. Unless we're
18497 // interrupted by a higher priority update, we'll continue later from where
18498 // we left off.
18499 var _didCompleteRoot2 = false;
18500 stopWorkLoopTimer(interruptedBy, _didCompleteRoot2);
18501 interruptedBy = null;
18502 onYield(root);
18503 return;
18504 }
18505
18506 // We completed the whole tree.
18507 var didCompleteRoot = true;
18508 stopWorkLoopTimer(interruptedBy, didCompleteRoot);
18509 var rootWorkInProgress = root.current.alternate;
18510 !(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;
18511
18512 // `nextRoot` points to the in-progress root. A non-null value indicates
18513 // that we're in the middle of an async render. Set it to null to indicate
18514 // there's no more work to be done in the current batch.
18515 nextRoot = null;
18516 interruptedBy = null;
18517
18518 if (nextRenderDidError) {
18519 // There was an error
18520 if (hasLowerPriorityWork(root, expirationTime)) {
18521 // There's lower priority work. If so, it may have the effect of fixing
18522 // the exception that was just thrown. Exit without committing. This is
18523 // similar to a suspend, but without a timeout because we're not waiting
18524 // for a promise to resolve. React will restart at the lower
18525 // priority level.
18526 markSuspendedPriorityLevel(root, expirationTime);
18527 var suspendedExpirationTime = expirationTime;
18528 var rootExpirationTime = root.expirationTime;
18529 onSuspend(root, rootWorkInProgress, suspendedExpirationTime, rootExpirationTime, -1 // Indicates no timeout
18530 );
18531 return;
18532 } else if (
18533 // There's no lower priority work, but we're rendering asynchronously.
18534 // Synchronsouly attempt to render the same level one more time. This is
18535 // similar to a suspend, but without a timeout because we're not waiting
18536 // for a promise to resolve.
18537 !root.didError && isYieldy) {
18538 root.didError = true;
18539 var _suspendedExpirationTime = root.nextExpirationTimeToWorkOn = expirationTime;
18540 var _rootExpirationTime = root.expirationTime = Sync;
18541 onSuspend(root, rootWorkInProgress, _suspendedExpirationTime, _rootExpirationTime, -1 // Indicates no timeout
18542 );
18543 return;
18544 }
18545 }
18546
18547 if (isYieldy && nextLatestAbsoluteTimeoutMs !== -1) {
18548 // The tree was suspended.
18549 var _suspendedExpirationTime2 = expirationTime;
18550 markSuspendedPriorityLevel(root, _suspendedExpirationTime2);
18551
18552 // Find the earliest uncommitted expiration time in the tree, including
18553 // work that is suspended. The timeout threshold cannot be longer than
18554 // the overall expiration.
18555 var earliestExpirationTime = findEarliestOutstandingPriorityLevel(root, expirationTime);
18556 var earliestExpirationTimeMs = expirationTimeToMs(earliestExpirationTime);
18557 if (earliestExpirationTimeMs < nextLatestAbsoluteTimeoutMs) {
18558 nextLatestAbsoluteTimeoutMs = earliestExpirationTimeMs;
18559 }
18560
18561 // Subtract the current time from the absolute timeout to get the number
18562 // of milliseconds until the timeout. In other words, convert an absolute
18563 // timestamp to a relative time. This is the value that is passed
18564 // to `setTimeout`.
18565 var currentTimeMs = expirationTimeToMs(requestCurrentTime());
18566 var msUntilTimeout = nextLatestAbsoluteTimeoutMs - currentTimeMs;
18567 msUntilTimeout = msUntilTimeout < 0 ? 0 : msUntilTimeout;
18568
18569 // TODO: Account for the Just Noticeable Difference
18570
18571 var _rootExpirationTime2 = root.expirationTime;
18572 onSuspend(root, rootWorkInProgress, _suspendedExpirationTime2, _rootExpirationTime2, msUntilTimeout);
18573 return;
18574 }
18575
18576 // Ready to commit.
18577 onComplete(root, rootWorkInProgress, expirationTime);
18578}
18579
18580function captureCommitPhaseError(sourceFiber, value) {
18581 var expirationTime = Sync;
18582 var fiber = sourceFiber.return;
18583 while (fiber !== null) {
18584 switch (fiber.tag) {
18585 case ClassComponent:
18586 var ctor = fiber.type;
18587 var instance = fiber.stateNode;
18588 if (typeof ctor.getDerivedStateFromError === 'function' || typeof instance.componentDidCatch === 'function' && !isAlreadyFailedLegacyErrorBoundary(instance)) {
18589 var errorInfo = createCapturedValue(value, sourceFiber);
18590 var update = createClassErrorUpdate(fiber, errorInfo, expirationTime);
18591 enqueueUpdate(fiber, update);
18592 scheduleWork(fiber, expirationTime);
18593 return;
18594 }
18595 break;
18596 case HostRoot:
18597 {
18598 var _errorInfo = createCapturedValue(value, sourceFiber);
18599 var _update = createRootErrorUpdate(fiber, _errorInfo, expirationTime);
18600 enqueueUpdate(fiber, _update);
18601 scheduleWork(fiber, expirationTime);
18602 return;
18603 }
18604 }
18605 fiber = fiber.return;
18606 }
18607
18608 if (sourceFiber.tag === HostRoot) {
18609 // Error was thrown at the root. There is no parent, so the root
18610 // itself should capture it.
18611 var rootFiber = sourceFiber;
18612 var _errorInfo2 = createCapturedValue(value, rootFiber);
18613 var _update2 = createRootErrorUpdate(rootFiber, _errorInfo2, expirationTime);
18614 enqueueUpdate(rootFiber, _update2);
18615 scheduleWork(rootFiber, expirationTime);
18616 }
18617}
18618
18619function computeThreadID(expirationTime, interactionThreadID) {
18620 // Interaction threads are unique per root and expiration time.
18621 return expirationTime * 1000 + interactionThreadID;
18622}
18623
18624// Creates a unique async expiration time.
18625function computeUniqueAsyncExpiration() {
18626 var currentTime = requestCurrentTime();
18627 var result = computeAsyncExpiration(currentTime);
18628 if (result >= lastUniqueAsyncExpiration) {
18629 // Since we assume the current time monotonically increases, we only hit
18630 // this branch when computeUniqueAsyncExpiration is fired multiple times
18631 // within a 200ms window (or whatever the async bucket size is).
18632 result = lastUniqueAsyncExpiration - 1;
18633 }
18634 lastUniqueAsyncExpiration = result;
18635 return lastUniqueAsyncExpiration;
18636}
18637
18638function computeExpirationForFiber(currentTime, fiber) {
18639 var expirationTime = void 0;
18640 if (expirationContext !== NoWork) {
18641 // An explicit expiration context was set;
18642 expirationTime = expirationContext;
18643 } else if (isWorking) {
18644 if (isCommitting$1) {
18645 // Updates that occur during the commit phase should have sync priority
18646 // by default.
18647 expirationTime = Sync;
18648 } else {
18649 // Updates during the render phase should expire at the same time as
18650 // the work that is being rendered.
18651 expirationTime = nextRenderExpirationTime;
18652 }
18653 } else {
18654 // No explicit expiration context was set, and we're not currently
18655 // performing work. Calculate a new expiration time.
18656 if (fiber.mode & ConcurrentMode) {
18657 if (isBatchingInteractiveUpdates) {
18658 // This is an interactive update
18659 expirationTime = computeInteractiveExpiration(currentTime);
18660 } else {
18661 // This is an async update
18662 expirationTime = computeAsyncExpiration(currentTime);
18663 }
18664 // If we're in the middle of rendering a tree, do not update at the same
18665 // expiration time that is already rendering.
18666 if (nextRoot !== null && expirationTime === nextRenderExpirationTime) {
18667 expirationTime -= 1;
18668 }
18669 } else {
18670 // This is a sync update
18671 expirationTime = Sync;
18672 }
18673 }
18674 if (isBatchingInteractiveUpdates) {
18675 // This is an interactive update. Keep track of the lowest pending
18676 // interactive expiration time. This allows us to synchronously flush
18677 // all interactive updates when needed.
18678 if (lowestPriorityPendingInteractiveExpirationTime === NoWork || expirationTime < lowestPriorityPendingInteractiveExpirationTime) {
18679 lowestPriorityPendingInteractiveExpirationTime = expirationTime;
18680 }
18681 }
18682 return expirationTime;
18683}
18684
18685function renderDidSuspend(root, absoluteTimeoutMs, suspendedTime) {
18686 // Schedule the timeout.
18687 if (absoluteTimeoutMs >= 0 && nextLatestAbsoluteTimeoutMs < absoluteTimeoutMs) {
18688 nextLatestAbsoluteTimeoutMs = absoluteTimeoutMs;
18689 }
18690}
18691
18692function renderDidError() {
18693 nextRenderDidError = true;
18694}
18695
18696function pingSuspendedRoot(root, thenable, pingTime) {
18697 // A promise that previously suspended React from committing has resolved.
18698 // If React is still suspended, try again at the previous level (pingTime).
18699
18700 var pingCache = root.pingCache;
18701 if (pingCache !== null) {
18702 // The thenable resolved, so we no longer need to memoize, because it will
18703 // never be thrown again.
18704 pingCache.delete(thenable);
18705 }
18706
18707 if (nextRoot !== null && nextRenderExpirationTime === pingTime) {
18708 // Received a ping at the same priority level at which we're currently
18709 // rendering. Restart from the root.
18710 nextRoot = null;
18711 } else {
18712 // Confirm that the root is still suspended at this level. Otherwise exit.
18713 if (isPriorityLevelSuspended(root, pingTime)) {
18714 // Ping at the original level
18715 markPingedPriorityLevel(root, pingTime);
18716 var rootExpirationTime = root.expirationTime;
18717 if (rootExpirationTime !== NoWork) {
18718 requestWork(root, rootExpirationTime);
18719 }
18720 }
18721 }
18722}
18723
18724function retryTimedOutBoundary(boundaryFiber, thenable) {
18725 // The boundary fiber (a Suspense component) previously timed out and was
18726 // rendered in its fallback state. One of the promises that suspended it has
18727 // resolved, which means at least part of the tree was likely unblocked. Try
18728 var retryCache = boundaryFiber.stateNode;
18729 if (retryCache !== null) {
18730 // The thenable resolved, so we no longer need to memoize, because it will
18731 // never be thrown again.
18732 retryCache.delete(thenable);
18733 }
18734
18735 var currentTime = requestCurrentTime();
18736 var retryTime = computeExpirationForFiber(currentTime, boundaryFiber);
18737 var root = scheduleWorkToRoot(boundaryFiber, retryTime);
18738 if (root !== null) {
18739 markPendingPriorityLevel(root, retryTime);
18740 var rootExpirationTime = root.expirationTime;
18741 if (rootExpirationTime !== NoWork) {
18742 requestWork(root, rootExpirationTime);
18743 }
18744 }
18745}
18746
18747function scheduleWorkToRoot(fiber, expirationTime) {
18748 recordScheduleUpdate();
18749
18750 {
18751 if (fiber.tag === ClassComponent) {
18752 var instance = fiber.stateNode;
18753 warnAboutInvalidUpdates(instance);
18754 }
18755 }
18756
18757 // Update the source fiber's expiration time
18758 if (fiber.expirationTime < expirationTime) {
18759 fiber.expirationTime = expirationTime;
18760 }
18761 var alternate = fiber.alternate;
18762 if (alternate !== null && alternate.expirationTime < expirationTime) {
18763 alternate.expirationTime = expirationTime;
18764 }
18765 // Walk the parent path to the root and update the child expiration time.
18766 var node = fiber.return;
18767 var root = null;
18768 if (node === null && fiber.tag === HostRoot) {
18769 root = fiber.stateNode;
18770 } else {
18771 while (node !== null) {
18772 alternate = node.alternate;
18773 if (node.childExpirationTime < expirationTime) {
18774 node.childExpirationTime = expirationTime;
18775 if (alternate !== null && alternate.childExpirationTime < expirationTime) {
18776 alternate.childExpirationTime = expirationTime;
18777 }
18778 } else if (alternate !== null && alternate.childExpirationTime < expirationTime) {
18779 alternate.childExpirationTime = expirationTime;
18780 }
18781 if (node.return === null && node.tag === HostRoot) {
18782 root = node.stateNode;
18783 break;
18784 }
18785 node = node.return;
18786 }
18787 }
18788
18789 if (enableSchedulerTracing) {
18790 if (root !== null) {
18791 var interactions = __interactionsRef.current;
18792 if (interactions.size > 0) {
18793 var pendingInteractionMap = root.pendingInteractionMap;
18794 var pendingInteractions = pendingInteractionMap.get(expirationTime);
18795 if (pendingInteractions != null) {
18796 interactions.forEach(function (interaction) {
18797 if (!pendingInteractions.has(interaction)) {
18798 // Update the pending async work count for previously unscheduled interaction.
18799 interaction.__count++;
18800 }
18801
18802 pendingInteractions.add(interaction);
18803 });
18804 } else {
18805 pendingInteractionMap.set(expirationTime, new Set(interactions));
18806
18807 // Update the pending async work count for the current interactions.
18808 interactions.forEach(function (interaction) {
18809 interaction.__count++;
18810 });
18811 }
18812
18813 var subscriber = __subscriberRef.current;
18814 if (subscriber !== null) {
18815 var threadID = computeThreadID(expirationTime, root.interactionThreadID);
18816 subscriber.onWorkScheduled(interactions, threadID);
18817 }
18818 }
18819 }
18820 }
18821 return root;
18822}
18823
18824function scheduleWork(fiber, expirationTime) {
18825 var root = scheduleWorkToRoot(fiber, expirationTime);
18826 if (root === null) {
18827 {
18828 switch (fiber.tag) {
18829 case ClassComponent:
18830 warnAboutUpdateOnUnmounted(fiber, true);
18831 break;
18832 case FunctionComponent:
18833 case ForwardRef:
18834 case MemoComponent:
18835 case SimpleMemoComponent:
18836 warnAboutUpdateOnUnmounted(fiber, false);
18837 break;
18838 }
18839 }
18840 return;
18841 }
18842
18843 if (!isWorking && nextRenderExpirationTime !== NoWork && expirationTime > nextRenderExpirationTime) {
18844 // This is an interruption. (Used for performance tracking.)
18845 interruptedBy = fiber;
18846 resetStack();
18847 }
18848 markPendingPriorityLevel(root, expirationTime);
18849 if (
18850 // If we're in the render phase, we don't need to schedule this root
18851 // for an update, because we'll do it before we exit...
18852 !isWorking || isCommitting$1 ||
18853 // ...unless this is a different root than the one we're rendering.
18854 nextRoot !== root) {
18855 var rootExpirationTime = root.expirationTime;
18856 requestWork(root, rootExpirationTime);
18857 }
18858 if (nestedUpdateCount > NESTED_UPDATE_LIMIT) {
18859 // Reset this back to zero so subsequent updates don't throw.
18860 nestedUpdateCount = 0;
18861 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.');
18862 }
18863}
18864
18865function syncUpdates(fn, a, b, c, d) {
18866 var previousExpirationContext = expirationContext;
18867 expirationContext = Sync;
18868 try {
18869 return fn(a, b, c, d);
18870 } finally {
18871 expirationContext = previousExpirationContext;
18872 }
18873}
18874
18875// TODO: Everything below this is written as if it has been lifted to the
18876// renderers. I'll do this in a follow-up.
18877
18878// Linked-list of roots
18879var firstScheduledRoot = null;
18880var lastScheduledRoot = null;
18881
18882var callbackExpirationTime = NoWork;
18883var callbackID = void 0;
18884var isRendering = false;
18885var nextFlushedRoot = null;
18886var nextFlushedExpirationTime = NoWork;
18887var lowestPriorityPendingInteractiveExpirationTime = NoWork;
18888var hasUnhandledError = false;
18889var unhandledError = null;
18890
18891var isBatchingUpdates = false;
18892var isUnbatchingUpdates = false;
18893var isBatchingInteractiveUpdates = false;
18894
18895var completedBatches = null;
18896
18897var originalStartTimeMs = unstable_now();
18898var currentRendererTime = msToExpirationTime(originalStartTimeMs);
18899var currentSchedulerTime = currentRendererTime;
18900
18901// Use these to prevent an infinite loop of nested updates
18902var NESTED_UPDATE_LIMIT = 50;
18903var nestedUpdateCount = 0;
18904var lastCommittedRootDuringThisBatch = null;
18905
18906function recomputeCurrentRendererTime() {
18907 var currentTimeMs = unstable_now() - originalStartTimeMs;
18908 currentRendererTime = msToExpirationTime(currentTimeMs);
18909}
18910
18911function scheduleCallbackWithExpirationTime(root, expirationTime) {
18912 if (callbackExpirationTime !== NoWork) {
18913 // A callback is already scheduled. Check its expiration time (timeout).
18914 if (expirationTime < callbackExpirationTime) {
18915 // Existing callback has sufficient timeout. Exit.
18916 return;
18917 } else {
18918 if (callbackID !== null) {
18919 // Existing callback has insufficient timeout. Cancel and schedule a
18920 // new one.
18921 unstable_cancelCallback(callbackID);
18922 }
18923 }
18924 // The request callback timer is already running. Don't start a new one.
18925 } else {
18926 startRequestCallbackTimer();
18927 }
18928
18929 callbackExpirationTime = expirationTime;
18930 var currentMs = unstable_now() - originalStartTimeMs;
18931 var expirationTimeMs = expirationTimeToMs(expirationTime);
18932 var timeout = expirationTimeMs - currentMs;
18933 callbackID = unstable_scheduleCallback(performAsyncWork, { timeout: timeout });
18934}
18935
18936// For every call to renderRoot, one of onFatal, onComplete, onSuspend, and
18937// onYield is called upon exiting. We use these in lieu of returning a tuple.
18938// I've also chosen not to inline them into renderRoot because these will
18939// eventually be lifted into the renderer.
18940function onFatal(root) {
18941 root.finishedWork = null;
18942}
18943
18944function onComplete(root, finishedWork, expirationTime) {
18945 root.pendingCommitExpirationTime = expirationTime;
18946 root.finishedWork = finishedWork;
18947}
18948
18949function onSuspend(root, finishedWork, suspendedExpirationTime, rootExpirationTime, msUntilTimeout) {
18950 root.expirationTime = rootExpirationTime;
18951 if (msUntilTimeout === 0 && !shouldYieldToRenderer()) {
18952 // Don't wait an additional tick. Commit the tree immediately.
18953 root.pendingCommitExpirationTime = suspendedExpirationTime;
18954 root.finishedWork = finishedWork;
18955 } else if (msUntilTimeout > 0) {
18956 // Wait `msUntilTimeout` milliseconds before committing.
18957 root.timeoutHandle = scheduleTimeout(onTimeout.bind(null, root, finishedWork, suspendedExpirationTime), msUntilTimeout);
18958 }
18959}
18960
18961function onYield(root) {
18962 root.finishedWork = null;
18963}
18964
18965function onTimeout(root, finishedWork, suspendedExpirationTime) {
18966 // The root timed out. Commit it.
18967 root.pendingCommitExpirationTime = suspendedExpirationTime;
18968 root.finishedWork = finishedWork;
18969 // Read the current time before entering the commit phase. We can be
18970 // certain this won't cause tearing related to batching of event updates
18971 // because we're at the top of a timer event.
18972 recomputeCurrentRendererTime();
18973 currentSchedulerTime = currentRendererTime;
18974 flushRoot(root, suspendedExpirationTime);
18975}
18976
18977function onCommit(root, expirationTime) {
18978 root.expirationTime = expirationTime;
18979 root.finishedWork = null;
18980}
18981
18982function requestCurrentTime() {
18983 // requestCurrentTime is called by the scheduler to compute an expiration
18984 // time.
18985 //
18986 // Expiration times are computed by adding to the current time (the start
18987 // time). However, if two updates are scheduled within the same event, we
18988 // should treat their start times as simultaneous, even if the actual clock
18989 // time has advanced between the first and second call.
18990
18991 // In other words, because expiration times determine how updates are batched,
18992 // we want all updates of like priority that occur within the same event to
18993 // receive the same expiration time. Otherwise we get tearing.
18994 //
18995 // We keep track of two separate times: the current "renderer" time and the
18996 // current "scheduler" time. The renderer time can be updated whenever; it
18997 // only exists to minimize the calls performance.now.
18998 //
18999 // But the scheduler time can only be updated if there's no pending work, or
19000 // if we know for certain that we're not in the middle of an event.
19001
19002 if (isRendering) {
19003 // We're already rendering. Return the most recently read time.
19004 return currentSchedulerTime;
19005 }
19006 // Check if there's pending work.
19007 findHighestPriorityRoot();
19008 if (nextFlushedExpirationTime === NoWork || nextFlushedExpirationTime === Never) {
19009 // If there's no pending work, or if the pending work is offscreen, we can
19010 // read the current time without risk of tearing.
19011 recomputeCurrentRendererTime();
19012 currentSchedulerTime = currentRendererTime;
19013 return currentSchedulerTime;
19014 }
19015 // There's already pending work. We might be in the middle of a browser
19016 // event. If we were to read the current time, it could cause multiple updates
19017 // within the same event to receive different expiration times, leading to
19018 // tearing. Return the last read time. During the next idle callback, the
19019 // time will be updated.
19020 return currentSchedulerTime;
19021}
19022
19023// requestWork is called by the scheduler whenever a root receives an update.
19024// It's up to the renderer to call renderRoot at some point in the future.
19025function requestWork(root, expirationTime) {
19026 addRootToSchedule(root, expirationTime);
19027 if (isRendering) {
19028 // Prevent reentrancy. Remaining work will be scheduled at the end of
19029 // the currently rendering batch.
19030 return;
19031 }
19032
19033 if (isBatchingUpdates) {
19034 // Flush work at the end of the batch.
19035 if (isUnbatchingUpdates) {
19036 // ...unless we're inside unbatchedUpdates, in which case we should
19037 // flush it now.
19038 nextFlushedRoot = root;
19039 nextFlushedExpirationTime = Sync;
19040 performWorkOnRoot(root, Sync, false);
19041 }
19042 return;
19043 }
19044
19045 // TODO: Get rid of Sync and use current time?
19046 if (expirationTime === Sync) {
19047 performSyncWork();
19048 } else {
19049 scheduleCallbackWithExpirationTime(root, expirationTime);
19050 }
19051}
19052
19053function addRootToSchedule(root, expirationTime) {
19054 // Add the root to the schedule.
19055 // Check if this root is already part of the schedule.
19056 if (root.nextScheduledRoot === null) {
19057 // This root is not already scheduled. Add it.
19058 root.expirationTime = expirationTime;
19059 if (lastScheduledRoot === null) {
19060 firstScheduledRoot = lastScheduledRoot = root;
19061 root.nextScheduledRoot = root;
19062 } else {
19063 lastScheduledRoot.nextScheduledRoot = root;
19064 lastScheduledRoot = root;
19065 lastScheduledRoot.nextScheduledRoot = firstScheduledRoot;
19066 }
19067 } else {
19068 // This root is already scheduled, but its priority may have increased.
19069 var remainingExpirationTime = root.expirationTime;
19070 if (expirationTime > remainingExpirationTime) {
19071 // Update the priority.
19072 root.expirationTime = expirationTime;
19073 }
19074 }
19075}
19076
19077function findHighestPriorityRoot() {
19078 var highestPriorityWork = NoWork;
19079 var highestPriorityRoot = null;
19080 if (lastScheduledRoot !== null) {
19081 var previousScheduledRoot = lastScheduledRoot;
19082 var root = firstScheduledRoot;
19083 while (root !== null) {
19084 var remainingExpirationTime = root.expirationTime;
19085 if (remainingExpirationTime === NoWork) {
19086 // This root no longer has work. Remove it from the scheduler.
19087
19088 // TODO: This check is redudant, but Flow is confused by the branch
19089 // below where we set lastScheduledRoot to null, even though we break
19090 // from the loop right after.
19091 !(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;
19092 if (root === root.nextScheduledRoot) {
19093 // This is the only root in the list.
19094 root.nextScheduledRoot = null;
19095 firstScheduledRoot = lastScheduledRoot = null;
19096 break;
19097 } else if (root === firstScheduledRoot) {
19098 // This is the first root in the list.
19099 var next = root.nextScheduledRoot;
19100 firstScheduledRoot = next;
19101 lastScheduledRoot.nextScheduledRoot = next;
19102 root.nextScheduledRoot = null;
19103 } else if (root === lastScheduledRoot) {
19104 // This is the last root in the list.
19105 lastScheduledRoot = previousScheduledRoot;
19106 lastScheduledRoot.nextScheduledRoot = firstScheduledRoot;
19107 root.nextScheduledRoot = null;
19108 break;
19109 } else {
19110 previousScheduledRoot.nextScheduledRoot = root.nextScheduledRoot;
19111 root.nextScheduledRoot = null;
19112 }
19113 root = previousScheduledRoot.nextScheduledRoot;
19114 } else {
19115 if (remainingExpirationTime > highestPriorityWork) {
19116 // Update the priority, if it's higher
19117 highestPriorityWork = remainingExpirationTime;
19118 highestPriorityRoot = root;
19119 }
19120 if (root === lastScheduledRoot) {
19121 break;
19122 }
19123 if (highestPriorityWork === Sync) {
19124 // Sync is highest priority by definition so
19125 // we can stop searching.
19126 break;
19127 }
19128 previousScheduledRoot = root;
19129 root = root.nextScheduledRoot;
19130 }
19131 }
19132 }
19133
19134 nextFlushedRoot = highestPriorityRoot;
19135 nextFlushedExpirationTime = highestPriorityWork;
19136}
19137
19138// TODO: This wrapper exists because many of the older tests (the ones that use
19139// flushDeferredPri) rely on the number of times `shouldYield` is called. We
19140// should get rid of it.
19141var didYield = false;
19142function shouldYieldToRenderer() {
19143 if (didYield) {
19144 return true;
19145 }
19146 if (unstable_shouldYield()) {
19147 didYield = true;
19148 return true;
19149 }
19150 return false;
19151}
19152
19153function performAsyncWork() {
19154 try {
19155 if (!shouldYieldToRenderer()) {
19156 // The callback timed out. That means at least one update has expired.
19157 // Iterate through the root schedule. If they contain expired work, set
19158 // the next render expiration time to the current time. This has the effect
19159 // of flushing all expired work in a single batch, instead of flushing each
19160 // level one at a time.
19161 if (firstScheduledRoot !== null) {
19162 recomputeCurrentRendererTime();
19163 var root = firstScheduledRoot;
19164 do {
19165 didExpireAtExpirationTime(root, currentRendererTime);
19166 // The root schedule is circular, so this is never null.
19167 root = root.nextScheduledRoot;
19168 } while (root !== firstScheduledRoot);
19169 }
19170 }
19171 performWork(NoWork, true);
19172 } finally {
19173 didYield = false;
19174 }
19175}
19176
19177function performSyncWork() {
19178 performWork(Sync, false);
19179}
19180
19181function performWork(minExpirationTime, isYieldy) {
19182 // Keep working on roots until there's no more work, or until there's a higher
19183 // priority event.
19184 findHighestPriorityRoot();
19185
19186 if (isYieldy) {
19187 recomputeCurrentRendererTime();
19188 currentSchedulerTime = currentRendererTime;
19189
19190 if (enableUserTimingAPI) {
19191 var didExpire = nextFlushedExpirationTime > currentRendererTime;
19192 var timeout = expirationTimeToMs(nextFlushedExpirationTime);
19193 stopRequestCallbackTimer(didExpire, timeout);
19194 }
19195
19196 while (nextFlushedRoot !== null && nextFlushedExpirationTime !== NoWork && minExpirationTime <= nextFlushedExpirationTime && !(didYield && currentRendererTime > nextFlushedExpirationTime)) {
19197 performWorkOnRoot(nextFlushedRoot, nextFlushedExpirationTime, currentRendererTime > nextFlushedExpirationTime);
19198 findHighestPriorityRoot();
19199 recomputeCurrentRendererTime();
19200 currentSchedulerTime = currentRendererTime;
19201 }
19202 } else {
19203 while (nextFlushedRoot !== null && nextFlushedExpirationTime !== NoWork && minExpirationTime <= nextFlushedExpirationTime) {
19204 performWorkOnRoot(nextFlushedRoot, nextFlushedExpirationTime, false);
19205 findHighestPriorityRoot();
19206 }
19207 }
19208
19209 // We're done flushing work. Either we ran out of time in this callback,
19210 // or there's no more work left with sufficient priority.
19211
19212 // If we're inside a callback, set this to false since we just completed it.
19213 if (isYieldy) {
19214 callbackExpirationTime = NoWork;
19215 callbackID = null;
19216 }
19217 // If there's work left over, schedule a new callback.
19218 if (nextFlushedExpirationTime !== NoWork) {
19219 scheduleCallbackWithExpirationTime(nextFlushedRoot, nextFlushedExpirationTime);
19220 }
19221
19222 // Clean-up.
19223 finishRendering();
19224}
19225
19226function flushRoot(root, expirationTime) {
19227 !!isRendering ? invariant(false, 'work.commit(): Cannot commit while already rendering. This likely means you attempted to commit from inside a lifecycle method.') : void 0;
19228 // Perform work on root as if the given expiration time is the current time.
19229 // This has the effect of synchronously flushing all work up to and
19230 // including the given time.
19231 nextFlushedRoot = root;
19232 nextFlushedExpirationTime = expirationTime;
19233 performWorkOnRoot(root, expirationTime, false);
19234 // Flush any sync work that was scheduled by lifecycles
19235 performSyncWork();
19236}
19237
19238function finishRendering() {
19239 nestedUpdateCount = 0;
19240 lastCommittedRootDuringThisBatch = null;
19241
19242 if (completedBatches !== null) {
19243 var batches = completedBatches;
19244 completedBatches = null;
19245 for (var i = 0; i < batches.length; i++) {
19246 var batch = batches[i];
19247 try {
19248 batch._onComplete();
19249 } catch (error) {
19250 if (!hasUnhandledError) {
19251 hasUnhandledError = true;
19252 unhandledError = error;
19253 }
19254 }
19255 }
19256 }
19257
19258 if (hasUnhandledError) {
19259 var error = unhandledError;
19260 unhandledError = null;
19261 hasUnhandledError = false;
19262 throw error;
19263 }
19264}
19265
19266function performWorkOnRoot(root, expirationTime, isYieldy) {
19267 !!isRendering ? invariant(false, 'performWorkOnRoot was called recursively. This error is likely caused by a bug in React. Please file an issue.') : void 0;
19268
19269 isRendering = true;
19270
19271 // Check if this is async work or sync/expired work.
19272 if (!isYieldy) {
19273 // Flush work without yielding.
19274 // TODO: Non-yieldy work does not necessarily imply expired work. A renderer
19275 // may want to perform some work without yielding, but also without
19276 // requiring the root to complete (by triggering placeholders).
19277
19278 var finishedWork = root.finishedWork;
19279 if (finishedWork !== null) {
19280 // This root is already complete. We can commit it.
19281 completeRoot(root, finishedWork, expirationTime);
19282 } else {
19283 root.finishedWork = null;
19284 // If this root previously suspended, clear its existing timeout, since
19285 // we're about to try rendering again.
19286 var timeoutHandle = root.timeoutHandle;
19287 if (timeoutHandle !== noTimeout) {
19288 root.timeoutHandle = noTimeout;
19289 // $FlowFixMe Complains noTimeout is not a TimeoutID, despite the check above
19290 cancelTimeout(timeoutHandle);
19291 }
19292 renderRoot(root, isYieldy);
19293 finishedWork = root.finishedWork;
19294 if (finishedWork !== null) {
19295 // We've completed the root. Commit it.
19296 completeRoot(root, finishedWork, expirationTime);
19297 }
19298 }
19299 } else {
19300 // Flush async work.
19301 var _finishedWork = root.finishedWork;
19302 if (_finishedWork !== null) {
19303 // This root is already complete. We can commit it.
19304 completeRoot(root, _finishedWork, expirationTime);
19305 } else {
19306 root.finishedWork = null;
19307 // If this root previously suspended, clear its existing timeout, since
19308 // we're about to try rendering again.
19309 var _timeoutHandle = root.timeoutHandle;
19310 if (_timeoutHandle !== noTimeout) {
19311 root.timeoutHandle = noTimeout;
19312 // $FlowFixMe Complains noTimeout is not a TimeoutID, despite the check above
19313 cancelTimeout(_timeoutHandle);
19314 }
19315 renderRoot(root, isYieldy);
19316 _finishedWork = root.finishedWork;
19317 if (_finishedWork !== null) {
19318 // We've completed the root. Check the if we should yield one more time
19319 // before committing.
19320 if (!shouldYieldToRenderer()) {
19321 // Still time left. Commit the root.
19322 completeRoot(root, _finishedWork, expirationTime);
19323 } else {
19324 // There's no time left. Mark this root as complete. We'll come
19325 // back and commit it later.
19326 root.finishedWork = _finishedWork;
19327 }
19328 }
19329 }
19330 }
19331
19332 isRendering = false;
19333}
19334
19335function completeRoot(root, finishedWork, expirationTime) {
19336 // Check if there's a batch that matches this expiration time.
19337 var firstBatch = root.firstBatch;
19338 if (firstBatch !== null && firstBatch._expirationTime >= expirationTime) {
19339 if (completedBatches === null) {
19340 completedBatches = [firstBatch];
19341 } else {
19342 completedBatches.push(firstBatch);
19343 }
19344 if (firstBatch._defer) {
19345 // This root is blocked from committing by a batch. Unschedule it until
19346 // we receive another update.
19347 root.finishedWork = finishedWork;
19348 root.expirationTime = NoWork;
19349 return;
19350 }
19351 }
19352
19353 // Commit the root.
19354 root.finishedWork = null;
19355
19356 // Check if this is a nested update (a sync update scheduled during the
19357 // commit phase).
19358 if (root === lastCommittedRootDuringThisBatch) {
19359 // If the next root is the same as the previous root, this is a nested
19360 // update. To prevent an infinite loop, increment the nested update count.
19361 nestedUpdateCount++;
19362 } else {
19363 // Reset whenever we switch roots.
19364 lastCommittedRootDuringThisBatch = root;
19365 nestedUpdateCount = 0;
19366 }
19367 commitRoot(root, finishedWork);
19368}
19369
19370function onUncaughtError(error) {
19371 !(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;
19372 // Unschedule this root so we don't work on it again until there's
19373 // another update.
19374 nextFlushedRoot.expirationTime = NoWork;
19375 if (!hasUnhandledError) {
19376 hasUnhandledError = true;
19377 unhandledError = error;
19378 }
19379}
19380
19381// TODO: Batching should be implemented at the renderer level, not inside
19382// the reconciler.
19383function batchedUpdates$1(fn, a) {
19384 var previousIsBatchingUpdates = isBatchingUpdates;
19385 isBatchingUpdates = true;
19386 try {
19387 return fn(a);
19388 } finally {
19389 isBatchingUpdates = previousIsBatchingUpdates;
19390 if (!isBatchingUpdates && !isRendering) {
19391 performSyncWork();
19392 }
19393 }
19394}
19395
19396// TODO: Batching should be implemented at the renderer level, not inside
19397// the reconciler.
19398function unbatchedUpdates(fn, a) {
19399 if (isBatchingUpdates && !isUnbatchingUpdates) {
19400 isUnbatchingUpdates = true;
19401 try {
19402 return fn(a);
19403 } finally {
19404 isUnbatchingUpdates = false;
19405 }
19406 }
19407 return fn(a);
19408}
19409
19410// TODO: Batching should be implemented at the renderer level, not within
19411// the reconciler.
19412function flushSync(fn, a) {
19413 !!isRendering ? invariant(false, 'flushSync was called from inside a lifecycle method. It cannot be called when React is already rendering.') : void 0;
19414 var previousIsBatchingUpdates = isBatchingUpdates;
19415 isBatchingUpdates = true;
19416 try {
19417 return syncUpdates(fn, a);
19418 } finally {
19419 isBatchingUpdates = previousIsBatchingUpdates;
19420 performSyncWork();
19421 }
19422}
19423
19424function interactiveUpdates$1(fn, a, b) {
19425 if (isBatchingInteractiveUpdates) {
19426 return fn(a, b);
19427 }
19428 // If there are any pending interactive updates, synchronously flush them.
19429 // This needs to happen before we read any handlers, because the effect of
19430 // the previous event may influence which handlers are called during
19431 // this event.
19432 if (!isBatchingUpdates && !isRendering && lowestPriorityPendingInteractiveExpirationTime !== NoWork) {
19433 // Synchronously flush pending interactive updates.
19434 performWork(lowestPriorityPendingInteractiveExpirationTime, false);
19435 lowestPriorityPendingInteractiveExpirationTime = NoWork;
19436 }
19437 var previousIsBatchingInteractiveUpdates = isBatchingInteractiveUpdates;
19438 var previousIsBatchingUpdates = isBatchingUpdates;
19439 isBatchingInteractiveUpdates = true;
19440 isBatchingUpdates = true;
19441 try {
19442 return fn(a, b);
19443 } finally {
19444 isBatchingInteractiveUpdates = previousIsBatchingInteractiveUpdates;
19445 isBatchingUpdates = previousIsBatchingUpdates;
19446 if (!isBatchingUpdates && !isRendering) {
19447 performSyncWork();
19448 }
19449 }
19450}
19451
19452function flushInteractiveUpdates$1() {
19453 if (!isRendering && lowestPriorityPendingInteractiveExpirationTime !== NoWork) {
19454 // Synchronously flush pending interactive updates.
19455 performWork(lowestPriorityPendingInteractiveExpirationTime, false);
19456 lowestPriorityPendingInteractiveExpirationTime = NoWork;
19457 }
19458}
19459
19460function flushControlled(fn) {
19461 var previousIsBatchingUpdates = isBatchingUpdates;
19462 isBatchingUpdates = true;
19463 try {
19464 syncUpdates(fn);
19465 } finally {
19466 isBatchingUpdates = previousIsBatchingUpdates;
19467 if (!isBatchingUpdates && !isRendering) {
19468 performSyncWork();
19469 }
19470 }
19471}
19472
19473// 0 is PROD, 1 is DEV.
19474// Might add PROFILE later.
19475
19476
19477var didWarnAboutNestedUpdates = void 0;
19478var didWarnAboutFindNodeInStrictMode = void 0;
19479
19480{
19481 didWarnAboutNestedUpdates = false;
19482 didWarnAboutFindNodeInStrictMode = {};
19483}
19484
19485function getContextForSubtree(parentComponent) {
19486 if (!parentComponent) {
19487 return emptyContextObject;
19488 }
19489
19490 var fiber = get(parentComponent);
19491 var parentContext = findCurrentUnmaskedContext(fiber);
19492
19493 if (fiber.tag === ClassComponent) {
19494 var Component = fiber.type;
19495 if (isContextProvider(Component)) {
19496 return processChildContext(fiber, Component, parentContext);
19497 }
19498 }
19499
19500 return parentContext;
19501}
19502
19503function scheduleRootUpdate(current$$1, element, expirationTime, callback) {
19504 {
19505 if (phase === 'render' && current !== null && !didWarnAboutNestedUpdates) {
19506 didWarnAboutNestedUpdates = true;
19507 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');
19508 }
19509 }
19510
19511 var update = createUpdate(expirationTime);
19512 // Caution: React DevTools currently depends on this property
19513 // being called "element".
19514 update.payload = { element: element };
19515
19516 callback = callback === undefined ? null : callback;
19517 if (callback !== null) {
19518 !(typeof callback === 'function') ? warningWithoutStack$1(false, 'render(...): Expected the last optional `callback` argument to be a ' + 'function. Instead received: %s.', callback) : void 0;
19519 update.callback = callback;
19520 }
19521
19522 flushPassiveEffects();
19523 enqueueUpdate(current$$1, update);
19524 scheduleWork(current$$1, expirationTime);
19525
19526 return expirationTime;
19527}
19528
19529function updateContainerAtExpirationTime(element, container, parentComponent, expirationTime, callback) {
19530 // TODO: If this is a nested container, this won't be the root.
19531 var current$$1 = container.current;
19532
19533 {
19534 if (ReactFiberInstrumentation_1.debugTool) {
19535 if (current$$1.alternate === null) {
19536 ReactFiberInstrumentation_1.debugTool.onMountContainer(container);
19537 } else if (element === null) {
19538 ReactFiberInstrumentation_1.debugTool.onUnmountContainer(container);
19539 } else {
19540 ReactFiberInstrumentation_1.debugTool.onUpdateContainer(container);
19541 }
19542 }
19543 }
19544
19545 var context = getContextForSubtree(parentComponent);
19546 if (container.context === null) {
19547 container.context = context;
19548 } else {
19549 container.pendingContext = context;
19550 }
19551
19552 return scheduleRootUpdate(current$$1, element, expirationTime, callback);
19553}
19554
19555function findHostInstance(component) {
19556 var fiber = get(component);
19557 if (fiber === undefined) {
19558 if (typeof component.render === 'function') {
19559 invariant(false, 'Unable to find node on an unmounted component.');
19560 } else {
19561 invariant(false, 'Argument appears to not be a ReactComponent. Keys: %s', Object.keys(component));
19562 }
19563 }
19564 var hostFiber = findCurrentHostFiber(fiber);
19565 if (hostFiber === null) {
19566 return null;
19567 }
19568 return hostFiber.stateNode;
19569}
19570
19571function findHostInstanceWithWarning(component, methodName) {
19572 {
19573 var fiber = get(component);
19574 if (fiber === undefined) {
19575 if (typeof component.render === 'function') {
19576 invariant(false, 'Unable to find node on an unmounted component.');
19577 } else {
19578 invariant(false, 'Argument appears to not be a ReactComponent. Keys: %s', Object.keys(component));
19579 }
19580 }
19581 var hostFiber = findCurrentHostFiber(fiber);
19582 if (hostFiber === null) {
19583 return null;
19584 }
19585 if (hostFiber.mode & StrictMode) {
19586 var componentName = getComponentName(fiber.type) || 'Component';
19587 if (!didWarnAboutFindNodeInStrictMode[componentName]) {
19588 didWarnAboutFindNodeInStrictMode[componentName] = true;
19589 if (fiber.mode & StrictMode) {
19590 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));
19591 } else {
19592 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));
19593 }
19594 }
19595 }
19596 return hostFiber.stateNode;
19597 }
19598 return findHostInstance(component);
19599}
19600
19601function createContainer(containerInfo, isConcurrent, hydrate) {
19602 return createFiberRoot(containerInfo, isConcurrent, hydrate);
19603}
19604
19605function updateContainer(element, container, parentComponent, callback) {
19606 var current$$1 = container.current;
19607 var currentTime = requestCurrentTime();
19608 var expirationTime = computeExpirationForFiber(currentTime, current$$1);
19609 return updateContainerAtExpirationTime(element, container, parentComponent, expirationTime, callback);
19610}
19611
19612function getPublicRootInstance(container) {
19613 var containerFiber = container.current;
19614 if (!containerFiber.child) {
19615 return null;
19616 }
19617 switch (containerFiber.child.tag) {
19618 case HostComponent:
19619 return getPublicInstance(containerFiber.child.stateNode);
19620 default:
19621 return containerFiber.child.stateNode;
19622 }
19623}
19624
19625function findHostInstanceWithNoPortals(fiber) {
19626 var hostFiber = findCurrentHostFiberWithNoPortals(fiber);
19627 if (hostFiber === null) {
19628 return null;
19629 }
19630 return hostFiber.stateNode;
19631}
19632
19633var overrideProps = null;
19634
19635{
19636 var copyWithSetImpl = function (obj, path, idx, value) {
19637 if (idx >= path.length) {
19638 return value;
19639 }
19640 var key = path[idx];
19641 var updated = Array.isArray(obj) ? obj.slice() : _assign({}, obj);
19642 // $FlowFixMe number or string is fine here
19643 updated[key] = copyWithSetImpl(obj[key], path, idx + 1, value);
19644 return updated;
19645 };
19646
19647 var copyWithSet = function (obj, path, value) {
19648 return copyWithSetImpl(obj, path, 0, value);
19649 };
19650
19651 // Support DevTools props for function components, forwardRef, memo, host components, etc.
19652 overrideProps = function (fiber, path, value) {
19653 flushPassiveEffects();
19654 fiber.pendingProps = copyWithSet(fiber.memoizedProps, path, value);
19655 if (fiber.alternate) {
19656 fiber.alternate.pendingProps = fiber.pendingProps;
19657 }
19658 scheduleWork(fiber, Sync);
19659 };
19660}
19661
19662function injectIntoDevTools(devToolsConfig) {
19663 var findFiberByHostInstance = devToolsConfig.findFiberByHostInstance;
19664
19665 return injectInternals(_assign({}, devToolsConfig, {
19666 overrideProps: overrideProps,
19667 findHostInstanceByFiber: function (fiber) {
19668 var hostFiber = findCurrentHostFiber(fiber);
19669 if (hostFiber === null) {
19670 return null;
19671 }
19672 return hostFiber.stateNode;
19673 },
19674 findFiberByHostInstance: function (instance) {
19675 if (!findFiberByHostInstance) {
19676 // Might not be implemented by the renderer.
19677 return null;
19678 }
19679 return findFiberByHostInstance(instance);
19680 }
19681 }));
19682}
19683
19684// This file intentionally does *not* have the Flow annotation.
19685// Don't add it. See `./inline-typed.js` for an explanation.
19686
19687function createPortal$1(children, containerInfo,
19688// TODO: figure out the API for cross-renderer implementation.
19689implementation) {
19690 var key = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null;
19691
19692 return {
19693 // This tag allow us to uniquely identify this as a React Portal
19694 $$typeof: REACT_PORTAL_TYPE,
19695 key: key == null ? null : '' + key,
19696 children: children,
19697 containerInfo: containerInfo,
19698 implementation: implementation
19699 };
19700}
19701
19702// TODO: this is special because it gets imported during build.
19703
19704var ReactVersion = '16.7.0';
19705
19706// TODO: This type is shared between the reconciler and ReactDOM, but will
19707// eventually be lifted out to the renderer.
19708var ReactCurrentOwner = ReactSharedInternals.ReactCurrentOwner;
19709
19710var topLevelUpdateWarnings = void 0;
19711var warnOnInvalidCallback = void 0;
19712var didWarnAboutUnstableCreatePortal = false;
19713
19714{
19715 if (typeof Map !== 'function' ||
19716 // $FlowIssue Flow incorrectly thinks Map has no prototype
19717 Map.prototype == null || typeof Map.prototype.forEach !== 'function' || typeof Set !== 'function' ||
19718 // $FlowIssue Flow incorrectly thinks Set has no prototype
19719 Set.prototype == null || typeof Set.prototype.clear !== 'function' || typeof Set.prototype.forEach !== 'function') {
19720 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');
19721 }
19722
19723 topLevelUpdateWarnings = function (container) {
19724 if (container._reactRootContainer && container.nodeType !== COMMENT_NODE) {
19725 var hostInstance = findHostInstanceWithNoPortals(container._reactRootContainer._internalRoot.current);
19726 if (hostInstance) {
19727 !(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;
19728 }
19729 }
19730
19731 var isRootRenderedBySomeReact = !!container._reactRootContainer;
19732 var rootEl = getReactRootElementInContainer(container);
19733 var hasNonRootReactChild = !!(rootEl && getInstanceFromNode$1(rootEl));
19734
19735 !(!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;
19736
19737 !(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;
19738 };
19739
19740 warnOnInvalidCallback = function (callback, callerName) {
19741 !(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;
19742 };
19743}
19744
19745setRestoreImplementation(restoreControlledState$1);
19746
19747function ReactBatch(root) {
19748 var expirationTime = computeUniqueAsyncExpiration();
19749 this._expirationTime = expirationTime;
19750 this._root = root;
19751 this._next = null;
19752 this._callbacks = null;
19753 this._didComplete = false;
19754 this._hasChildren = false;
19755 this._children = null;
19756 this._defer = true;
19757}
19758ReactBatch.prototype.render = function (children) {
19759 !this._defer ? invariant(false, 'batch.render: Cannot render a batch that already committed.') : void 0;
19760 this._hasChildren = true;
19761 this._children = children;
19762 var internalRoot = this._root._internalRoot;
19763 var expirationTime = this._expirationTime;
19764 var work = new ReactWork();
19765 updateContainerAtExpirationTime(children, internalRoot, null, expirationTime, work._onCommit);
19766 return work;
19767};
19768ReactBatch.prototype.then = function (onComplete) {
19769 if (this._didComplete) {
19770 onComplete();
19771 return;
19772 }
19773 var callbacks = this._callbacks;
19774 if (callbacks === null) {
19775 callbacks = this._callbacks = [];
19776 }
19777 callbacks.push(onComplete);
19778};
19779ReactBatch.prototype.commit = function () {
19780 var internalRoot = this._root._internalRoot;
19781 var firstBatch = internalRoot.firstBatch;
19782 !(this._defer && firstBatch !== null) ? invariant(false, 'batch.commit: Cannot commit a batch multiple times.') : void 0;
19783
19784 if (!this._hasChildren) {
19785 // This batch is empty. Return.
19786 this._next = null;
19787 this._defer = false;
19788 return;
19789 }
19790
19791 var expirationTime = this._expirationTime;
19792
19793 // Ensure this is the first batch in the list.
19794 if (firstBatch !== this) {
19795 // This batch is not the earliest batch. We need to move it to the front.
19796 // Update its expiration time to be the expiration time of the earliest
19797 // batch, so that we can flush it without flushing the other batches.
19798 if (this._hasChildren) {
19799 expirationTime = this._expirationTime = firstBatch._expirationTime;
19800 // Rendering this batch again ensures its children will be the final state
19801 // when we flush (updates are processed in insertion order: last
19802 // update wins).
19803 // TODO: This forces a restart. Should we print a warning?
19804 this.render(this._children);
19805 }
19806
19807 // Remove the batch from the list.
19808 var previous = null;
19809 var batch = firstBatch;
19810 while (batch !== this) {
19811 previous = batch;
19812 batch = batch._next;
19813 }
19814 !(previous !== null) ? invariant(false, 'batch.commit: Cannot commit a batch multiple times.') : void 0;
19815 previous._next = batch._next;
19816
19817 // Add it to the front.
19818 this._next = firstBatch;
19819 firstBatch = internalRoot.firstBatch = this;
19820 }
19821
19822 // Synchronously flush all the work up to this batch's expiration time.
19823 this._defer = false;
19824 flushRoot(internalRoot, expirationTime);
19825
19826 // Pop the batch from the list.
19827 var next = this._next;
19828 this._next = null;
19829 firstBatch = internalRoot.firstBatch = next;
19830
19831 // Append the next earliest batch's children to the update queue.
19832 if (firstBatch !== null && firstBatch._hasChildren) {
19833 firstBatch.render(firstBatch._children);
19834 }
19835};
19836ReactBatch.prototype._onComplete = function () {
19837 if (this._didComplete) {
19838 return;
19839 }
19840 this._didComplete = true;
19841 var callbacks = this._callbacks;
19842 if (callbacks === null) {
19843 return;
19844 }
19845 // TODO: Error handling.
19846 for (var i = 0; i < callbacks.length; i++) {
19847 var _callback = callbacks[i];
19848 _callback();
19849 }
19850};
19851
19852function ReactWork() {
19853 this._callbacks = null;
19854 this._didCommit = false;
19855 // TODO: Avoid need to bind by replacing callbacks in the update queue with
19856 // list of Work objects.
19857 this._onCommit = this._onCommit.bind(this);
19858}
19859ReactWork.prototype.then = function (onCommit) {
19860 if (this._didCommit) {
19861 onCommit();
19862 return;
19863 }
19864 var callbacks = this._callbacks;
19865 if (callbacks === null) {
19866 callbacks = this._callbacks = [];
19867 }
19868 callbacks.push(onCommit);
19869};
19870ReactWork.prototype._onCommit = function () {
19871 if (this._didCommit) {
19872 return;
19873 }
19874 this._didCommit = true;
19875 var callbacks = this._callbacks;
19876 if (callbacks === null) {
19877 return;
19878 }
19879 // TODO: Error handling.
19880 for (var i = 0; i < callbacks.length; i++) {
19881 var _callback2 = callbacks[i];
19882 !(typeof _callback2 === 'function') ? invariant(false, 'Invalid argument passed as callback. Expected a function. Instead received: %s', _callback2) : void 0;
19883 _callback2();
19884 }
19885};
19886
19887function ReactRoot(container, isConcurrent, hydrate) {
19888 var root = createContainer(container, isConcurrent, hydrate);
19889 this._internalRoot = root;
19890}
19891ReactRoot.prototype.render = function (children, callback) {
19892 var root = this._internalRoot;
19893 var work = new ReactWork();
19894 callback = callback === undefined ? null : callback;
19895 {
19896 warnOnInvalidCallback(callback, 'render');
19897 }
19898 if (callback !== null) {
19899 work.then(callback);
19900 }
19901 updateContainer(children, root, null, work._onCommit);
19902 return work;
19903};
19904ReactRoot.prototype.unmount = function (callback) {
19905 var root = this._internalRoot;
19906 var work = new ReactWork();
19907 callback = callback === undefined ? null : callback;
19908 {
19909 warnOnInvalidCallback(callback, 'render');
19910 }
19911 if (callback !== null) {
19912 work.then(callback);
19913 }
19914 updateContainer(null, root, null, work._onCommit);
19915 return work;
19916};
19917ReactRoot.prototype.legacy_renderSubtreeIntoContainer = function (parentComponent, children, callback) {
19918 var root = this._internalRoot;
19919 var work = new ReactWork();
19920 callback = callback === undefined ? null : callback;
19921 {
19922 warnOnInvalidCallback(callback, 'render');
19923 }
19924 if (callback !== null) {
19925 work.then(callback);
19926 }
19927 updateContainer(children, root, parentComponent, work._onCommit);
19928 return work;
19929};
19930ReactRoot.prototype.createBatch = function () {
19931 var batch = new ReactBatch(this);
19932 var expirationTime = batch._expirationTime;
19933
19934 var internalRoot = this._internalRoot;
19935 var firstBatch = internalRoot.firstBatch;
19936 if (firstBatch === null) {
19937 internalRoot.firstBatch = batch;
19938 batch._next = null;
19939 } else {
19940 // Insert sorted by expiration time then insertion order
19941 var insertAfter = null;
19942 var insertBefore = firstBatch;
19943 while (insertBefore !== null && insertBefore._expirationTime >= expirationTime) {
19944 insertAfter = insertBefore;
19945 insertBefore = insertBefore._next;
19946 }
19947 batch._next = insertBefore;
19948 if (insertAfter !== null) {
19949 insertAfter._next = batch;
19950 }
19951 }
19952
19953 return batch;
19954};
19955
19956/**
19957 * True if the supplied DOM node is a valid node element.
19958 *
19959 * @param {?DOMElement} node The candidate DOM node.
19960 * @return {boolean} True if the DOM is a valid DOM node.
19961 * @internal
19962 */
19963function isValidContainer(node) {
19964 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 '));
19965}
19966
19967function getReactRootElementInContainer(container) {
19968 if (!container) {
19969 return null;
19970 }
19971
19972 if (container.nodeType === DOCUMENT_NODE) {
19973 return container.documentElement;
19974 } else {
19975 return container.firstChild;
19976 }
19977}
19978
19979function shouldHydrateDueToLegacyHeuristic(container) {
19980 var rootElement = getReactRootElementInContainer(container);
19981 return !!(rootElement && rootElement.nodeType === ELEMENT_NODE && rootElement.hasAttribute(ROOT_ATTRIBUTE_NAME));
19982}
19983
19984setBatchingImplementation(batchedUpdates$1, interactiveUpdates$1, flushInteractiveUpdates$1);
19985
19986var warnedAboutHydrateAPI = false;
19987
19988function legacyCreateRootFromDOMContainer(container, forceHydrate) {
19989 var shouldHydrate = forceHydrate || shouldHydrateDueToLegacyHeuristic(container);
19990 // First clear any existing content.
19991 if (!shouldHydrate) {
19992 var warned = false;
19993 var rootSibling = void 0;
19994 while (rootSibling = container.lastChild) {
19995 {
19996 if (!warned && rootSibling.nodeType === ELEMENT_NODE && rootSibling.hasAttribute(ROOT_ATTRIBUTE_NAME)) {
19997 warned = true;
19998 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.');
19999 }
20000 }
20001 container.removeChild(rootSibling);
20002 }
20003 }
20004 {
20005 if (shouldHydrate && !forceHydrate && !warnedAboutHydrateAPI) {
20006 warnedAboutHydrateAPI = true;
20007 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.');
20008 }
20009 }
20010 // Legacy roots are not async by default.
20011 var isConcurrent = false;
20012 return new ReactRoot(container, isConcurrent, shouldHydrate);
20013}
20014
20015function legacyRenderSubtreeIntoContainer(parentComponent, children, container, forceHydrate, callback) {
20016 // TODO: Ensure all entry points contain this check
20017 !isValidContainer(container) ? invariant(false, 'Target container is not a DOM element.') : void 0;
20018
20019 {
20020 topLevelUpdateWarnings(container);
20021 }
20022
20023 // TODO: Without `any` type, Flow says "Property cannot be accessed on any
20024 // member of intersection type." Whyyyyyy.
20025 var root = container._reactRootContainer;
20026 if (!root) {
20027 // Initial mount
20028 root = container._reactRootContainer = legacyCreateRootFromDOMContainer(container, forceHydrate);
20029 if (typeof callback === 'function') {
20030 var originalCallback = callback;
20031 callback = function () {
20032 var instance = getPublicRootInstance(root._internalRoot);
20033 originalCallback.call(instance);
20034 };
20035 }
20036 // Initial mount should not be batched.
20037 unbatchedUpdates(function () {
20038 if (parentComponent != null) {
20039 root.legacy_renderSubtreeIntoContainer(parentComponent, children, callback);
20040 } else {
20041 root.render(children, callback);
20042 }
20043 });
20044 } else {
20045 if (typeof callback === 'function') {
20046 var _originalCallback = callback;
20047 callback = function () {
20048 var instance = getPublicRootInstance(root._internalRoot);
20049 _originalCallback.call(instance);
20050 };
20051 }
20052 // Update
20053 if (parentComponent != null) {
20054 root.legacy_renderSubtreeIntoContainer(parentComponent, children, callback);
20055 } else {
20056 root.render(children, callback);
20057 }
20058 }
20059 return getPublicRootInstance(root._internalRoot);
20060}
20061
20062function createPortal$$1(children, container) {
20063 var key = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
20064
20065 !isValidContainer(container) ? invariant(false, 'Target container is not a DOM element.') : void 0;
20066 // TODO: pass ReactDOM portal implementation as third argument
20067 return createPortal$1(children, container, null, key);
20068}
20069
20070var ReactDOM = {
20071 createPortal: createPortal$$1,
20072
20073 findDOMNode: function (componentOrElement) {
20074 {
20075 var owner = ReactCurrentOwner.current;
20076 if (owner !== null && owner.stateNode !== null) {
20077 var warnedAboutRefsInRender = owner.stateNode._warnedAboutRefsInRender;
20078 !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;
20079 owner.stateNode._warnedAboutRefsInRender = true;
20080 }
20081 }
20082 if (componentOrElement == null) {
20083 return null;
20084 }
20085 if (componentOrElement.nodeType === ELEMENT_NODE) {
20086 return componentOrElement;
20087 }
20088 {
20089 return findHostInstanceWithWarning(componentOrElement, 'findDOMNode');
20090 }
20091 return findHostInstance(componentOrElement);
20092 },
20093 hydrate: function (element, container, callback) {
20094 // TODO: throw or warn if we couldn't hydrate?
20095 return legacyRenderSubtreeIntoContainer(null, element, container, true, callback);
20096 },
20097 render: function (element, container, callback) {
20098 return legacyRenderSubtreeIntoContainer(null, element, container, false, callback);
20099 },
20100 unstable_renderSubtreeIntoContainer: function (parentComponent, element, containerNode, callback) {
20101 !(parentComponent != null && has(parentComponent)) ? invariant(false, 'parentComponent must be a valid React Component') : void 0;
20102 return legacyRenderSubtreeIntoContainer(parentComponent, element, containerNode, false, callback);
20103 },
20104 unmountComponentAtNode: function (container) {
20105 !isValidContainer(container) ? invariant(false, 'unmountComponentAtNode(...): Target container is not a DOM element.') : void 0;
20106
20107 if (container._reactRootContainer) {
20108 {
20109 var rootEl = getReactRootElementInContainer(container);
20110 var renderedByDifferentReact = rootEl && !getInstanceFromNode$1(rootEl);
20111 !!renderedByDifferentReact ? warningWithoutStack$1(false, "unmountComponentAtNode(): The node you're attempting to unmount " + 'was rendered by another copy of React.') : void 0;
20112 }
20113
20114 // Unmount should not be batched.
20115 unbatchedUpdates(function () {
20116 legacyRenderSubtreeIntoContainer(null, null, container, false, function () {
20117 container._reactRootContainer = null;
20118 });
20119 });
20120 // If you call unmountComponentAtNode twice in quick succession, you'll
20121 // get `true` twice. That's probably fine?
20122 return true;
20123 } else {
20124 {
20125 var _rootEl = getReactRootElementInContainer(container);
20126 var hasNonRootReactChild = !!(_rootEl && getInstanceFromNode$1(_rootEl));
20127
20128 // Check if the container itself is a React root node.
20129 var isContainerReactRoot = container.nodeType === ELEMENT_NODE && isValidContainer(container.parentNode) && !!container.parentNode._reactRootContainer;
20130
20131 !!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;
20132 }
20133
20134 return false;
20135 }
20136 },
20137
20138
20139 // Temporary alias since we already shipped React 16 RC with it.
20140 // TODO: remove in React 17.
20141 unstable_createPortal: function () {
20142 if (!didWarnAboutUnstableCreatePortal) {
20143 didWarnAboutUnstableCreatePortal = true;
20144 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.');
20145 }
20146 return createPortal$$1.apply(undefined, arguments);
20147 },
20148
20149
20150 unstable_batchedUpdates: batchedUpdates$1,
20151
20152 unstable_interactiveUpdates: interactiveUpdates$1,
20153
20154 flushSync: flushSync,
20155
20156 unstable_createRoot: createRoot,
20157 unstable_flushControlled: flushControlled,
20158
20159 __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED: {
20160 // Keep in sync with ReactDOMUnstableNativeDependencies.js
20161 // and ReactTestUtils.js. This is an array for better minification.
20162 Events: [getInstanceFromNode$1, getNodeFromInstance$1, getFiberCurrentPropsFromNode$1, injection.injectEventPluginsByName, eventNameDispatchConfigs, accumulateTwoPhaseDispatches, accumulateDirectDispatches, enqueueStateRestore, restoreStateIfNeeded, dispatchEvent, runEventsInBatch]
20163 }
20164};
20165
20166function createRoot(container, options) {
20167 var functionName = enableStableConcurrentModeAPIs ? 'createRoot' : 'unstable_createRoot';
20168 !isValidContainer(container) ? invariant(false, '%s(...): Target container is not a DOM element.', functionName) : void 0;
20169 var hydrate = options != null && options.hydrate === true;
20170 return new ReactRoot(container, true, hydrate);
20171}
20172
20173if (enableStableConcurrentModeAPIs) {
20174 ReactDOM.createRoot = createRoot;
20175 ReactDOM.unstable_createRoot = undefined;
20176}
20177
20178var foundDevTools = injectIntoDevTools({
20179 findFiberByHostInstance: getClosestInstanceFromNode,
20180 bundleType: 1,
20181 version: ReactVersion,
20182 rendererPackageName: 'react-dom'
20183});
20184
20185{
20186 if (!foundDevTools && canUseDOM && window.top === window.self) {
20187 // If we're in Chrome or Firefox, provide a download link if not installed.
20188 if (navigator.userAgent.indexOf('Chrome') > -1 && navigator.userAgent.indexOf('Edge') === -1 || navigator.userAgent.indexOf('Firefox') > -1) {
20189 var protocol = window.location.protocol;
20190 // Don't warn in exotic cases like chrome-extension://.
20191 if (/^(https?|file):$/.test(protocol)) {
20192 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');
20193 }
20194 }
20195 }
20196}
20197
20198
20199
20200var ReactDOM$2 = Object.freeze({
20201 default: ReactDOM
20202});
20203
20204var ReactDOM$3 = ( ReactDOM$2 && ReactDOM ) || ReactDOM$2;
20205
20206// TODO: decide on the top-level export form.
20207// This is hacky but makes it work with both Rollup and Jest.
20208var reactDom = ReactDOM$3.default || ReactDOM$3;
20209
20210return reactDom;
20211
20212})));