UNPKG

925 kBJavaScriptView Raw
1/** @license React v16.9.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
13
14if (process.env.NODE_ENV !== "production") {
15 (function() {
16'use strict';
17
18var React = require('react');
19var _assign = require('object-assign');
20var checkPropTypes = require('prop-types/checkPropTypes');
21var Scheduler = require('scheduler');
22var tracing = require('scheduler/tracing');
23
24// Do not require this module directly! Use normal `invariant` calls with
25// template literal strings. The messages will be converted to ReactError during
26// build, and in production they will be minified.
27
28// Do not require this module directly! Use normal `invariant` calls with
29// template literal strings. The messages will be converted to ReactError during
30// build, and in production they will be minified.
31
32function ReactError(error) {
33 error.name = 'Invariant Violation';
34 return error;
35}
36
37/**
38 * Use invariant() to assert state which your program assumes to be true.
39 *
40 * Provide sprintf-style format (only %s is supported) and arguments
41 * to provide information about what broke and what you were
42 * expecting.
43 *
44 * The invariant message will be stripped in production, but the invariant
45 * will remain to ensure logic does not differ in production.
46 */
47
48(function () {
49 if (!React) {
50 {
51 throw ReactError(Error('ReactDOM was loaded before React. Make sure you load the React package before loading ReactDOM.'));
52 }
53 }
54})();
55
56/**
57 * Injectable ordering of event plugins.
58 */
59var eventPluginOrder = null;
60
61/**
62 * Injectable mapping from names to event plugin modules.
63 */
64var namesToPlugins = {};
65
66/**
67 * Recomputes the plugin list using the injected plugins and plugin ordering.
68 *
69 * @private
70 */
71function recomputePluginOrdering() {
72 if (!eventPluginOrder) {
73 // Wait until an `eventPluginOrder` is injected.
74 return;
75 }
76 for (var pluginName in namesToPlugins) {
77 var pluginModule = namesToPlugins[pluginName];
78 var pluginIndex = eventPluginOrder.indexOf(pluginName);
79 (function () {
80 if (!(pluginIndex > -1)) {
81 {
82 throw ReactError(Error('EventPluginRegistry: Cannot inject event plugins that do not exist in the plugin ordering, `' + pluginName + '`.'));
83 }
84 }
85 })();
86 if (plugins[pluginIndex]) {
87 continue;
88 }
89 (function () {
90 if (!pluginModule.extractEvents) {
91 {
92 throw ReactError(Error('EventPluginRegistry: Event plugins must implement an `extractEvents` method, but `' + pluginName + '` does not.'));
93 }
94 }
95 })();
96 plugins[pluginIndex] = pluginModule;
97 var publishedEvents = pluginModule.eventTypes;
98 for (var eventName in publishedEvents) {
99 (function () {
100 if (!publishEventForPlugin(publishedEvents[eventName], pluginModule, eventName)) {
101 {
102 throw ReactError(Error('EventPluginRegistry: Failed to publish event `' + eventName + '` for plugin `' + pluginName + '`.'));
103 }
104 }
105 })();
106 }
107 }
108}
109
110/**
111 * Publishes an event so that it can be dispatched by the supplied plugin.
112 *
113 * @param {object} dispatchConfig Dispatch configuration for the event.
114 * @param {object} PluginModule Plugin publishing the event.
115 * @return {boolean} True if the event was successfully published.
116 * @private
117 */
118function publishEventForPlugin(dispatchConfig, pluginModule, eventName) {
119 (function () {
120 if (!!eventNameDispatchConfigs.hasOwnProperty(eventName)) {
121 {
122 throw ReactError(Error('EventPluginHub: More than one plugin attempted to publish the same event name, `' + eventName + '`.'));
123 }
124 }
125 })();
126 eventNameDispatchConfigs[eventName] = dispatchConfig;
127
128 var phasedRegistrationNames = dispatchConfig.phasedRegistrationNames;
129 if (phasedRegistrationNames) {
130 for (var phaseName in phasedRegistrationNames) {
131 if (phasedRegistrationNames.hasOwnProperty(phaseName)) {
132 var phasedRegistrationName = phasedRegistrationNames[phaseName];
133 publishRegistrationName(phasedRegistrationName, pluginModule, eventName);
134 }
135 }
136 return true;
137 } else if (dispatchConfig.registrationName) {
138 publishRegistrationName(dispatchConfig.registrationName, pluginModule, eventName);
139 return true;
140 }
141 return false;
142}
143
144/**
145 * Publishes a registration name that is used to identify dispatched events.
146 *
147 * @param {string} registrationName Registration name to add.
148 * @param {object} PluginModule Plugin publishing the event.
149 * @private
150 */
151function publishRegistrationName(registrationName, pluginModule, eventName) {
152 (function () {
153 if (!!registrationNameModules[registrationName]) {
154 {
155 throw ReactError(Error('EventPluginHub: More than one plugin attempted to publish the same registration name, `' + registrationName + '`.'));
156 }
157 }
158 })();
159 registrationNameModules[registrationName] = pluginModule;
160 registrationNameDependencies[registrationName] = pluginModule.eventTypes[eventName].dependencies;
161
162 {
163 var lowerCasedName = registrationName.toLowerCase();
164 possibleRegistrationNames[lowerCasedName] = registrationName;
165
166 if (registrationName === 'onDoubleClick') {
167 possibleRegistrationNames.ondblclick = registrationName;
168 }
169 }
170}
171
172/**
173 * Registers plugins so that they can extract and dispatch events.
174 *
175 * @see {EventPluginHub}
176 */
177
178/**
179 * Ordered list of injected plugins.
180 */
181var plugins = [];
182
183/**
184 * Mapping from event name to dispatch config
185 */
186var eventNameDispatchConfigs = {};
187
188/**
189 * Mapping from registration name to plugin module
190 */
191var registrationNameModules = {};
192
193/**
194 * Mapping from registration name to event name
195 */
196var registrationNameDependencies = {};
197
198/**
199 * Mapping from lowercase registration names to the properly cased version,
200 * used to warn in the case of missing event handlers. Available
201 * only in true.
202 * @type {Object}
203 */
204var possibleRegistrationNames = {};
205// Trust the developer to only use possibleRegistrationNames in true
206
207/**
208 * Injects an ordering of plugins (by plugin name). This allows the ordering
209 * to be decoupled from injection of the actual plugins so that ordering is
210 * always deterministic regardless of packaging, on-the-fly injection, etc.
211 *
212 * @param {array} InjectedEventPluginOrder
213 * @internal
214 * @see {EventPluginHub.injection.injectEventPluginOrder}
215 */
216function injectEventPluginOrder(injectedEventPluginOrder) {
217 (function () {
218 if (!!eventPluginOrder) {
219 {
220 throw ReactError(Error('EventPluginRegistry: Cannot inject event plugin ordering more than once. You are likely trying to load more than one copy of React.'));
221 }
222 }
223 })();
224 // Clone the ordering so it cannot be dynamically mutated.
225 eventPluginOrder = Array.prototype.slice.call(injectedEventPluginOrder);
226 recomputePluginOrdering();
227}
228
229/**
230 * Injects plugins to be used by `EventPluginHub`. The plugin names must be
231 * in the ordering injected by `injectEventPluginOrder`.
232 *
233 * Plugins can be injected as part of page initialization or on-the-fly.
234 *
235 * @param {object} injectedNamesToPlugins Map from names to plugin modules.
236 * @internal
237 * @see {EventPluginHub.injection.injectEventPluginsByName}
238 */
239function injectEventPluginsByName(injectedNamesToPlugins) {
240 var isOrderingDirty = false;
241 for (var pluginName in injectedNamesToPlugins) {
242 if (!injectedNamesToPlugins.hasOwnProperty(pluginName)) {
243 continue;
244 }
245 var pluginModule = injectedNamesToPlugins[pluginName];
246 if (!namesToPlugins.hasOwnProperty(pluginName) || namesToPlugins[pluginName] !== pluginModule) {
247 (function () {
248 if (!!namesToPlugins[pluginName]) {
249 {
250 throw ReactError(Error('EventPluginRegistry: Cannot inject two different event plugins using the same name, `' + pluginName + '`.'));
251 }
252 }
253 })();
254 namesToPlugins[pluginName] = pluginModule;
255 isOrderingDirty = true;
256 }
257 }
258 if (isOrderingDirty) {
259 recomputePluginOrdering();
260 }
261}
262
263var invokeGuardedCallbackImpl = function (name, func, context, a, b, c, d, e, f) {
264 var funcArgs = Array.prototype.slice.call(arguments, 3);
265 try {
266 func.apply(context, funcArgs);
267 } catch (error) {
268 this.onError(error);
269 }
270};
271
272{
273 // In DEV mode, we swap out invokeGuardedCallback for a special version
274 // that plays more nicely with the browser's DevTools. The idea is to preserve
275 // "Pause on exceptions" behavior. Because React wraps all user-provided
276 // functions in invokeGuardedCallback, and the production version of
277 // invokeGuardedCallback uses a try-catch, all user exceptions are treated
278 // like caught exceptions, and the DevTools won't pause unless the developer
279 // takes the extra step of enabling pause on caught exceptions. This is
280 // unintuitive, though, because even though React has caught the error, from
281 // the developer's perspective, the error is uncaught.
282 //
283 // To preserve the expected "Pause on exceptions" behavior, we don't use a
284 // try-catch in DEV. Instead, we synchronously dispatch a fake event to a fake
285 // DOM node, and call the user-provided callback from inside an event handler
286 // for that fake event. If the callback throws, the error is "captured" using
287 // a global event handler. But because the error happens in a different
288 // event loop context, it does not interrupt the normal program flow.
289 // Effectively, this gives us try-catch behavior without actually using
290 // try-catch. Neat!
291
292 // Check that the browser supports the APIs we need to implement our special
293 // DEV version of invokeGuardedCallback
294 if (typeof window !== 'undefined' && typeof window.dispatchEvent === 'function' && typeof document !== 'undefined' && typeof document.createEvent === 'function') {
295 var fakeNode = document.createElement('react');
296
297 var invokeGuardedCallbackDev = function (name, func, context, a, b, c, d, e, f) {
298 // If document doesn't exist we know for sure we will crash in this method
299 // when we call document.createEvent(). However this can cause confusing
300 // errors: https://github.com/facebookincubator/create-react-app/issues/3482
301 // So we preemptively throw with a better message instead.
302 (function () {
303 if (!(typeof document !== 'undefined')) {
304 {
305 throw ReactError(Error('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.'));
306 }
307 }
308 })();
309 var evt = document.createEvent('Event');
310
311 // Keeps track of whether the user-provided callback threw an error. We
312 // set this to true at the beginning, then set it to false right after
313 // calling the function. If the function errors, `didError` will never be
314 // set to false. This strategy works even if the browser is flaky and
315 // fails to call our global error handler, because it doesn't rely on
316 // the error event at all.
317 var didError = true;
318
319 // Keeps track of the value of window.event so that we can reset it
320 // during the callback to let user code access window.event in the
321 // browsers that support it.
322 var windowEvent = window.event;
323
324 // Keeps track of the descriptor of window.event to restore it after event
325 // dispatching: https://github.com/facebook/react/issues/13688
326 var windowEventDescriptor = Object.getOwnPropertyDescriptor(window, 'event');
327
328 // Create an event handler for our fake event. We will synchronously
329 // dispatch our fake event using `dispatchEvent`. Inside the handler, we
330 // call the user-provided callback.
331 var funcArgs = Array.prototype.slice.call(arguments, 3);
332 function callCallback() {
333 // We immediately remove the callback from event listeners so that
334 // nested `invokeGuardedCallback` calls do not clash. Otherwise, a
335 // nested call would trigger the fake event handlers of any call higher
336 // in the stack.
337 fakeNode.removeEventListener(evtType, callCallback, false);
338
339 // We check for window.hasOwnProperty('event') to prevent the
340 // window.event assignment in both IE <= 10 as they throw an error
341 // "Member not found" in strict mode, and in Firefox which does not
342 // support window.event.
343 if (typeof window.event !== 'undefined' && window.hasOwnProperty('event')) {
344 window.event = windowEvent;
345 }
346
347 func.apply(context, funcArgs);
348 didError = false;
349 }
350
351 // Create a global error event handler. We use this to capture the value
352 // that was thrown. It's possible that this error handler will fire more
353 // than once; for example, if non-React code also calls `dispatchEvent`
354 // and a handler for that event throws. We should be resilient to most of
355 // those cases. Even if our error event handler fires more than once, the
356 // last error event is always used. If the callback actually does error,
357 // we know that the last error event is the correct one, because it's not
358 // possible for anything else to have happened in between our callback
359 // erroring and the code that follows the `dispatchEvent` call below. If
360 // the callback doesn't error, but the error event was fired, we know to
361 // ignore it because `didError` will be false, as described above.
362 var error = void 0;
363 // Use this to track whether the error event is ever called.
364 var didSetError = false;
365 var isCrossOriginError = false;
366
367 function handleWindowError(event) {
368 error = event.error;
369 didSetError = true;
370 if (error === null && event.colno === 0 && event.lineno === 0) {
371 isCrossOriginError = true;
372 }
373 if (event.defaultPrevented) {
374 // Some other error handler has prevented default.
375 // Browsers silence the error report if this happens.
376 // We'll remember this to later decide whether to log it or not.
377 if (error != null && typeof error === 'object') {
378 try {
379 error._suppressLogging = true;
380 } catch (inner) {
381 // Ignore.
382 }
383 }
384 }
385 }
386
387 // Create a fake event type.
388 var evtType = 'react-' + (name ? name : 'invokeguardedcallback');
389
390 // Attach our event handlers
391 window.addEventListener('error', handleWindowError);
392 fakeNode.addEventListener(evtType, callCallback, false);
393
394 // Synchronously dispatch our fake event. If the user-provided function
395 // errors, it will trigger our global error handler.
396 evt.initEvent(evtType, false, false);
397 fakeNode.dispatchEvent(evt);
398
399 if (windowEventDescriptor) {
400 Object.defineProperty(window, 'event', windowEventDescriptor);
401 }
402
403 if (didError) {
404 if (!didSetError) {
405 // The callback errored, but the error event never fired.
406 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.');
407 } else if (isCrossOriginError) {
408 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.');
409 }
410 this.onError(error);
411 }
412
413 // Remove our event listeners
414 window.removeEventListener('error', handleWindowError);
415 };
416
417 invokeGuardedCallbackImpl = invokeGuardedCallbackDev;
418 }
419}
420
421var invokeGuardedCallbackImpl$1 = invokeGuardedCallbackImpl;
422
423// Used by Fiber to simulate a try-catch.
424var hasError = false;
425var caughtError = null;
426
427// Used by event system to capture/rethrow the first error.
428var hasRethrowError = false;
429var rethrowError = null;
430
431var reporter = {
432 onError: function (error) {
433 hasError = true;
434 caughtError = error;
435 }
436};
437
438/**
439 * Call a function while guarding against errors that happens within it.
440 * Returns an error if it throws, otherwise null.
441 *
442 * In production, this is implemented using a try-catch. The reason we don't
443 * use a try-catch directly is so that we can swap out a different
444 * implementation in DEV mode.
445 *
446 * @param {String} name of the guard to use for logging or debugging
447 * @param {Function} func The function to invoke
448 * @param {*} context The context to use when calling the function
449 * @param {...*} args Arguments for function
450 */
451function invokeGuardedCallback(name, func, context, a, b, c, d, e, f) {
452 hasError = false;
453 caughtError = null;
454 invokeGuardedCallbackImpl$1.apply(reporter, arguments);
455}
456
457/**
458 * Same as invokeGuardedCallback, but instead of returning an error, it stores
459 * it in a global so it can be rethrown by `rethrowCaughtError` later.
460 * TODO: See if caughtError and rethrowError can be unified.
461 *
462 * @param {String} name of the guard to use for logging or debugging
463 * @param {Function} func The function to invoke
464 * @param {*} context The context to use when calling the function
465 * @param {...*} args Arguments for function
466 */
467function invokeGuardedCallbackAndCatchFirstError(name, func, context, a, b, c, d, e, f) {
468 invokeGuardedCallback.apply(this, arguments);
469 if (hasError) {
470 var error = clearCaughtError();
471 if (!hasRethrowError) {
472 hasRethrowError = true;
473 rethrowError = error;
474 }
475 }
476}
477
478/**
479 * During execution of guarded functions we will capture the first error which
480 * we will rethrow to be handled by the top level error handler.
481 */
482function rethrowCaughtError() {
483 if (hasRethrowError) {
484 var error = rethrowError;
485 hasRethrowError = false;
486 rethrowError = null;
487 throw error;
488 }
489}
490
491function hasCaughtError() {
492 return hasError;
493}
494
495function clearCaughtError() {
496 if (hasError) {
497 var error = caughtError;
498 hasError = false;
499 caughtError = null;
500 return error;
501 } else {
502 (function () {
503 {
504 {
505 throw ReactError(Error('clearCaughtError was called but no error was captured. This error is likely caused by a bug in React. Please file an issue.'));
506 }
507 }
508 })();
509 }
510}
511
512/**
513 * Similar to invariant but only logs a warning if the condition is not met.
514 * This can be used to log issues in development environments in critical
515 * paths. Removing the logging code for production environments will keep the
516 * same logic and follow the same code paths.
517 */
518
519var warningWithoutStack = function () {};
520
521{
522 warningWithoutStack = function (condition, format) {
523 for (var _len = arguments.length, args = Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) {
524 args[_key - 2] = arguments[_key];
525 }
526
527 if (format === undefined) {
528 throw new Error('`warningWithoutStack(condition, format, ...args)` requires a warning ' + 'message argument');
529 }
530 if (args.length > 8) {
531 // Check before the condition to catch violations early.
532 throw new Error('warningWithoutStack() currently supports at most 8 arguments.');
533 }
534 if (condition) {
535 return;
536 }
537 if (typeof console !== 'undefined') {
538 var argsWithFormat = args.map(function (item) {
539 return '' + item;
540 });
541 argsWithFormat.unshift('Warning: ' + format);
542
543 // We intentionally don't use spread (or .apply) directly because it
544 // breaks IE9: https://github.com/facebook/react/issues/13610
545 Function.prototype.apply.call(console.error, console, argsWithFormat);
546 }
547 try {
548 // --- Welcome to debugging React ---
549 // This error was thrown as a convenience so that you can use this stack
550 // to find the callsite that caused this warning to fire.
551 var argIndex = 0;
552 var message = 'Warning: ' + format.replace(/%s/g, function () {
553 return args[argIndex++];
554 });
555 throw new Error(message);
556 } catch (x) {}
557 };
558}
559
560var warningWithoutStack$1 = warningWithoutStack;
561
562var getFiberCurrentPropsFromNode = null;
563var getInstanceFromNode = null;
564var getNodeFromInstance = null;
565
566function setComponentTree(getFiberCurrentPropsFromNodeImpl, getInstanceFromNodeImpl, getNodeFromInstanceImpl) {
567 getFiberCurrentPropsFromNode = getFiberCurrentPropsFromNodeImpl;
568 getInstanceFromNode = getInstanceFromNodeImpl;
569 getNodeFromInstance = getNodeFromInstanceImpl;
570 {
571 !(getNodeFromInstance && getInstanceFromNode) ? warningWithoutStack$1(false, 'EventPluginUtils.setComponentTree(...): Injected ' + 'module is missing getNodeFromInstance or getInstanceFromNode.') : void 0;
572 }
573}
574
575var validateEventDispatches = void 0;
576{
577 validateEventDispatches = function (event) {
578 var dispatchListeners = event._dispatchListeners;
579 var dispatchInstances = event._dispatchInstances;
580
581 var listenersIsArr = Array.isArray(dispatchListeners);
582 var listenersLen = listenersIsArr ? dispatchListeners.length : dispatchListeners ? 1 : 0;
583
584 var instancesIsArr = Array.isArray(dispatchInstances);
585 var instancesLen = instancesIsArr ? dispatchInstances.length : dispatchInstances ? 1 : 0;
586
587 !(instancesIsArr === listenersIsArr && instancesLen === listenersLen) ? warningWithoutStack$1(false, 'EventPluginUtils: Invalid `event`.') : void 0;
588 };
589}
590
591/**
592 * Dispatch the event to the listener.
593 * @param {SyntheticEvent} event SyntheticEvent to handle
594 * @param {function} listener Application-level callback
595 * @param {*} inst Internal component instance
596 */
597function executeDispatch(event, listener, inst) {
598 var type = event.type || 'unknown-event';
599 event.currentTarget = getNodeFromInstance(inst);
600 invokeGuardedCallbackAndCatchFirstError(type, listener, undefined, event);
601 event.currentTarget = null;
602}
603
604/**
605 * Standard/simple iteration through an event's collected dispatches.
606 */
607function executeDispatchesInOrder(event) {
608 var dispatchListeners = event._dispatchListeners;
609 var dispatchInstances = event._dispatchInstances;
610 {
611 validateEventDispatches(event);
612 }
613 if (Array.isArray(dispatchListeners)) {
614 for (var i = 0; i < dispatchListeners.length; i++) {
615 if (event.isPropagationStopped()) {
616 break;
617 }
618 // Listeners and Instances are two parallel arrays that are always in sync.
619 executeDispatch(event, dispatchListeners[i], dispatchInstances[i]);
620 }
621 } else if (dispatchListeners) {
622 executeDispatch(event, dispatchListeners, dispatchInstances);
623 }
624 event._dispatchListeners = null;
625 event._dispatchInstances = null;
626}
627
628/**
629 * @see executeDispatchesInOrderStopAtTrueImpl
630 */
631
632
633/**
634 * Execution of a "direct" dispatch - there must be at most one dispatch
635 * accumulated on the event or it is considered an error. It doesn't really make
636 * sense for an event with multiple dispatches (bubbled) to keep track of the
637 * return values at each dispatch execution, but it does tend to make sense when
638 * dealing with "direct" dispatches.
639 *
640 * @return {*} The return value of executing the single dispatch.
641 */
642
643
644/**
645 * @param {SyntheticEvent} event
646 * @return {boolean} True iff number of dispatches accumulated is greater than 0.
647 */
648
649/**
650 * Accumulates items that must not be null or undefined into the first one. This
651 * is used to conserve memory by avoiding array allocations, and thus sacrifices
652 * API cleanness. Since `current` can be null before being passed in and not
653 * null after this function, make sure to assign it back to `current`:
654 *
655 * `a = accumulateInto(a, b);`
656 *
657 * This API should be sparingly used. Try `accumulate` for something cleaner.
658 *
659 * @return {*|array<*>} An accumulation of items.
660 */
661
662function accumulateInto(current, next) {
663 (function () {
664 if (!(next != null)) {
665 {
666 throw ReactError(Error('accumulateInto(...): Accumulated items must not be null or undefined.'));
667 }
668 }
669 })();
670
671 if (current == null) {
672 return next;
673 }
674
675 // Both are not empty. Warning: Never call x.concat(y) when you are not
676 // certain that x is an Array (x could be a string with concat method).
677 if (Array.isArray(current)) {
678 if (Array.isArray(next)) {
679 current.push.apply(current, next);
680 return current;
681 }
682 current.push(next);
683 return current;
684 }
685
686 if (Array.isArray(next)) {
687 // A bit too dangerous to mutate `next`.
688 return [current].concat(next);
689 }
690
691 return [current, next];
692}
693
694/**
695 * @param {array} arr an "accumulation" of items which is either an Array or
696 * a single item. Useful when paired with the `accumulate` module. This is a
697 * simple utility that allows us to reason about a collection of items, but
698 * handling the case when there is exactly one item (and we do not need to
699 * allocate an array).
700 * @param {function} cb Callback invoked with each element or a collection.
701 * @param {?} [scope] Scope used as `this` in a callback.
702 */
703function forEachAccumulated(arr, cb, scope) {
704 if (Array.isArray(arr)) {
705 arr.forEach(cb, scope);
706 } else if (arr) {
707 cb.call(scope, arr);
708 }
709}
710
711/**
712 * Internal queue of events that have accumulated their dispatches and are
713 * waiting to have their dispatches executed.
714 */
715var eventQueue = null;
716
717/**
718 * Dispatches an event and releases it back into the pool, unless persistent.
719 *
720 * @param {?object} event Synthetic event to be dispatched.
721 * @private
722 */
723var executeDispatchesAndRelease = function (event) {
724 if (event) {
725 executeDispatchesInOrder(event);
726
727 if (!event.isPersistent()) {
728 event.constructor.release(event);
729 }
730 }
731};
732var executeDispatchesAndReleaseTopLevel = function (e) {
733 return executeDispatchesAndRelease(e);
734};
735
736function runEventsInBatch(events) {
737 if (events !== null) {
738 eventQueue = accumulateInto(eventQueue, events);
739 }
740
741 // Set `eventQueue` to null before processing it so that we can tell if more
742 // events get enqueued while processing.
743 var processingEventQueue = eventQueue;
744 eventQueue = null;
745
746 if (!processingEventQueue) {
747 return;
748 }
749
750 forEachAccumulated(processingEventQueue, executeDispatchesAndReleaseTopLevel);
751 (function () {
752 if (!!eventQueue) {
753 {
754 throw ReactError(Error('processEventQueue(): Additional events were enqueued while processing an event queue. Support for this has not yet been implemented.'));
755 }
756 }
757 })();
758 // This would be a good time to rethrow if any of the event handlers threw.
759 rethrowCaughtError();
760}
761
762function isInteractive(tag) {
763 return tag === 'button' || tag === 'input' || tag === 'select' || tag === 'textarea';
764}
765
766function shouldPreventMouseEvent(name, type, props) {
767 switch (name) {
768 case 'onClick':
769 case 'onClickCapture':
770 case 'onDoubleClick':
771 case 'onDoubleClickCapture':
772 case 'onMouseDown':
773 case 'onMouseDownCapture':
774 case 'onMouseMove':
775 case 'onMouseMoveCapture':
776 case 'onMouseUp':
777 case 'onMouseUpCapture':
778 return !!(props.disabled && isInteractive(type));
779 default:
780 return false;
781 }
782}
783
784/**
785 * This is a unified interface for event plugins to be installed and configured.
786 *
787 * Event plugins can implement the following properties:
788 *
789 * `extractEvents` {function(string, DOMEventTarget, string, object): *}
790 * Required. When a top-level event is fired, this method is expected to
791 * extract synthetic events that will in turn be queued and dispatched.
792 *
793 * `eventTypes` {object}
794 * Optional, plugins that fire events must publish a mapping of registration
795 * names that are used to register listeners. Values of this mapping must
796 * be objects that contain `registrationName` or `phasedRegistrationNames`.
797 *
798 * `executeDispatch` {function(object, function, string)}
799 * Optional, allows plugins to override how an event gets dispatched. By
800 * default, the listener is simply invoked.
801 *
802 * Each plugin that is injected into `EventsPluginHub` is immediately operable.
803 *
804 * @public
805 */
806
807/**
808 * Methods for injecting dependencies.
809 */
810var injection = {
811 /**
812 * @param {array} InjectedEventPluginOrder
813 * @public
814 */
815 injectEventPluginOrder: injectEventPluginOrder,
816
817 /**
818 * @param {object} injectedNamesToPlugins Map from names to plugin modules.
819 */
820 injectEventPluginsByName: injectEventPluginsByName
821};
822
823/**
824 * @param {object} inst The instance, which is the source of events.
825 * @param {string} registrationName Name of listener (e.g. `onClick`).
826 * @return {?function} The stored callback.
827 */
828function getListener(inst, registrationName) {
829 var listener = void 0;
830
831 // TODO: shouldPreventMouseEvent is DOM-specific and definitely should not
832 // live here; needs to be moved to a better place soon
833 var stateNode = inst.stateNode;
834 if (!stateNode) {
835 // Work in progress (ex: onload events in incremental mode).
836 return null;
837 }
838 var props = getFiberCurrentPropsFromNode(stateNode);
839 if (!props) {
840 // Work in progress.
841 return null;
842 }
843 listener = props[registrationName];
844 if (shouldPreventMouseEvent(registrationName, inst.type, props)) {
845 return null;
846 }
847 (function () {
848 if (!(!listener || typeof listener === 'function')) {
849 {
850 throw ReactError(Error('Expected `' + registrationName + '` listener to be a function, instead got a value of `' + typeof listener + '` type.'));
851 }
852 }
853 })();
854 return listener;
855}
856
857/**
858 * Allows registered plugins an opportunity to extract events from top-level
859 * native browser events.
860 *
861 * @return {*} An accumulation of synthetic events.
862 * @internal
863 */
864function extractPluginEvents(topLevelType, targetInst, nativeEvent, nativeEventTarget) {
865 var events = null;
866 for (var i = 0; i < plugins.length; i++) {
867 // Not every plugin in the ordering may be loaded at runtime.
868 var possiblePlugin = plugins[i];
869 if (possiblePlugin) {
870 var extractedEvents = possiblePlugin.extractEvents(topLevelType, targetInst, nativeEvent, nativeEventTarget);
871 if (extractedEvents) {
872 events = accumulateInto(events, extractedEvents);
873 }
874 }
875 }
876 return events;
877}
878
879function runExtractedPluginEventsInBatch(topLevelType, targetInst, nativeEvent, nativeEventTarget) {
880 var events = extractPluginEvents(topLevelType, targetInst, nativeEvent, nativeEventTarget);
881 runEventsInBatch(events);
882}
883
884var FunctionComponent = 0;
885var ClassComponent = 1;
886var IndeterminateComponent = 2; // Before we know whether it is function or class
887var HostRoot = 3; // Root of a host tree. Could be nested inside another node.
888var HostPortal = 4; // A subtree. Could be an entry point to a different renderer.
889var HostComponent = 5;
890var HostText = 6;
891var Fragment = 7;
892var Mode = 8;
893var ContextConsumer = 9;
894var ContextProvider = 10;
895var ForwardRef = 11;
896var Profiler = 12;
897var SuspenseComponent = 13;
898var MemoComponent = 14;
899var SimpleMemoComponent = 15;
900var LazyComponent = 16;
901var IncompleteClassComponent = 17;
902var DehydratedSuspenseComponent = 18;
903var SuspenseListComponent = 19;
904var FundamentalComponent = 20;
905
906var randomKey = Math.random().toString(36).slice(2);
907var internalInstanceKey = '__reactInternalInstance$' + randomKey;
908var internalEventHandlersKey = '__reactEventHandlers$' + randomKey;
909
910function precacheFiberNode(hostInst, node) {
911 node[internalInstanceKey] = hostInst;
912}
913
914/**
915 * Given a DOM node, return the closest ReactDOMComponent or
916 * ReactDOMTextComponent instance ancestor.
917 */
918function getClosestInstanceFromNode(node) {
919 if (node[internalInstanceKey]) {
920 return node[internalInstanceKey];
921 }
922
923 while (!node[internalInstanceKey]) {
924 if (node.parentNode) {
925 node = node.parentNode;
926 } else {
927 // Top of the tree. This node must not be part of a React tree (or is
928 // unmounted, potentially).
929 return null;
930 }
931 }
932
933 var inst = node[internalInstanceKey];
934 if (inst.tag === HostComponent || inst.tag === HostText) {
935 // In Fiber, this will always be the deepest root.
936 return inst;
937 }
938
939 return null;
940}
941
942/**
943 * Given a DOM node, return the ReactDOMComponent or ReactDOMTextComponent
944 * instance, or null if the node was not rendered by this React.
945 */
946function getInstanceFromNode$1(node) {
947 var inst = node[internalInstanceKey];
948 if (inst) {
949 if (inst.tag === HostComponent || inst.tag === HostText) {
950 return inst;
951 } else {
952 return null;
953 }
954 }
955 return null;
956}
957
958/**
959 * Given a ReactDOMComponent or ReactDOMTextComponent, return the corresponding
960 * DOM node.
961 */
962function getNodeFromInstance$1(inst) {
963 if (inst.tag === HostComponent || inst.tag === HostText) {
964 // In Fiber this, is just the state node right now. We assume it will be
965 // a host component or host text.
966 return inst.stateNode;
967 }
968
969 // Without this first invariant, passing a non-DOM-component triggers the next
970 // invariant for a missing parent, which is super confusing.
971 (function () {
972 {
973 {
974 throw ReactError(Error('getNodeFromInstance: Invalid argument.'));
975 }
976 }
977 })();
978}
979
980function getFiberCurrentPropsFromNode$1(node) {
981 return node[internalEventHandlersKey] || null;
982}
983
984function updateFiberProps(node, props) {
985 node[internalEventHandlersKey] = props;
986}
987
988function getParent(inst) {
989 do {
990 inst = inst.return;
991 // TODO: If this is a HostRoot we might want to bail out.
992 // That is depending on if we want nested subtrees (layers) to bubble
993 // events to their parent. We could also go through parentNode on the
994 // host node but that wouldn't work for React Native and doesn't let us
995 // do the portal feature.
996 } while (inst && inst.tag !== HostComponent);
997 if (inst) {
998 return inst;
999 }
1000 return null;
1001}
1002
1003/**
1004 * Return the lowest common ancestor of A and B, or null if they are in
1005 * different trees.
1006 */
1007function getLowestCommonAncestor(instA, instB) {
1008 var depthA = 0;
1009 for (var tempA = instA; tempA; tempA = getParent(tempA)) {
1010 depthA++;
1011 }
1012 var depthB = 0;
1013 for (var tempB = instB; tempB; tempB = getParent(tempB)) {
1014 depthB++;
1015 }
1016
1017 // If A is deeper, crawl up.
1018 while (depthA - depthB > 0) {
1019 instA = getParent(instA);
1020 depthA--;
1021 }
1022
1023 // If B is deeper, crawl up.
1024 while (depthB - depthA > 0) {
1025 instB = getParent(instB);
1026 depthB--;
1027 }
1028
1029 // Walk in lockstep until we find a match.
1030 var depth = depthA;
1031 while (depth--) {
1032 if (instA === instB || instA === instB.alternate) {
1033 return instA;
1034 }
1035 instA = getParent(instA);
1036 instB = getParent(instB);
1037 }
1038 return null;
1039}
1040
1041/**
1042 * Return if A is an ancestor of B.
1043 */
1044
1045
1046/**
1047 * Return the parent instance of the passed-in instance.
1048 */
1049
1050
1051/**
1052 * Simulates the traversal of a two-phase, capture/bubble event dispatch.
1053 */
1054function traverseTwoPhase(inst, fn, arg) {
1055 var path = [];
1056 while (inst) {
1057 path.push(inst);
1058 inst = getParent(inst);
1059 }
1060 var i = void 0;
1061 for (i = path.length; i-- > 0;) {
1062 fn(path[i], 'captured', arg);
1063 }
1064 for (i = 0; i < path.length; i++) {
1065 fn(path[i], 'bubbled', arg);
1066 }
1067}
1068
1069/**
1070 * Traverses the ID hierarchy and invokes the supplied `cb` on any IDs that
1071 * should would receive a `mouseEnter` or `mouseLeave` event.
1072 *
1073 * Does not invoke the callback on the nearest common ancestor because nothing
1074 * "entered" or "left" that element.
1075 */
1076function traverseEnterLeave(from, to, fn, argFrom, argTo) {
1077 var common = from && to ? getLowestCommonAncestor(from, to) : null;
1078 var pathFrom = [];
1079 while (true) {
1080 if (!from) {
1081 break;
1082 }
1083 if (from === common) {
1084 break;
1085 }
1086 var alternate = from.alternate;
1087 if (alternate !== null && alternate === common) {
1088 break;
1089 }
1090 pathFrom.push(from);
1091 from = getParent(from);
1092 }
1093 var pathTo = [];
1094 while (true) {
1095 if (!to) {
1096 break;
1097 }
1098 if (to === common) {
1099 break;
1100 }
1101 var _alternate = to.alternate;
1102 if (_alternate !== null && _alternate === common) {
1103 break;
1104 }
1105 pathTo.push(to);
1106 to = getParent(to);
1107 }
1108 for (var i = 0; i < pathFrom.length; i++) {
1109 fn(pathFrom[i], 'bubbled', argFrom);
1110 }
1111 for (var _i = pathTo.length; _i-- > 0;) {
1112 fn(pathTo[_i], 'captured', argTo);
1113 }
1114}
1115
1116/**
1117 * Some event types have a notion of different registration names for different
1118 * "phases" of propagation. This finds listeners by a given phase.
1119 */
1120function listenerAtPhase(inst, event, propagationPhase) {
1121 var registrationName = event.dispatchConfig.phasedRegistrationNames[propagationPhase];
1122 return getListener(inst, registrationName);
1123}
1124
1125/**
1126 * A small set of propagation patterns, each of which will accept a small amount
1127 * of information, and generate a set of "dispatch ready event objects" - which
1128 * are sets of events that have already been annotated with a set of dispatched
1129 * listener functions/ids. The API is designed this way to discourage these
1130 * propagation strategies from actually executing the dispatches, since we
1131 * always want to collect the entire set of dispatches before executing even a
1132 * single one.
1133 */
1134
1135/**
1136 * Tags a `SyntheticEvent` with dispatched listeners. Creating this function
1137 * here, allows us to not have to bind or create functions for each event.
1138 * Mutating the event's members allows us to not have to create a wrapping
1139 * "dispatch" object that pairs the event with the listener.
1140 */
1141function accumulateDirectionalDispatches(inst, phase, event) {
1142 {
1143 !inst ? warningWithoutStack$1(false, 'Dispatching inst must not be null') : void 0;
1144 }
1145 var listener = listenerAtPhase(inst, event, phase);
1146 if (listener) {
1147 event._dispatchListeners = accumulateInto(event._dispatchListeners, listener);
1148 event._dispatchInstances = accumulateInto(event._dispatchInstances, inst);
1149 }
1150}
1151
1152/**
1153 * Collect dispatches (must be entirely collected before dispatching - see unit
1154 * tests). Lazily allocate the array to conserve memory. We must loop through
1155 * each event and perform the traversal for each one. We cannot perform a
1156 * single traversal for the entire collection of events because each event may
1157 * have a different target.
1158 */
1159function accumulateTwoPhaseDispatchesSingle(event) {
1160 if (event && event.dispatchConfig.phasedRegistrationNames) {
1161 traverseTwoPhase(event._targetInst, accumulateDirectionalDispatches, event);
1162 }
1163}
1164
1165/**
1166 * Accumulates without regard to direction, does not look for phased
1167 * registration names. Same as `accumulateDirectDispatchesSingle` but without
1168 * requiring that the `dispatchMarker` be the same as the dispatched ID.
1169 */
1170function accumulateDispatches(inst, ignoredDirection, event) {
1171 if (inst && event && event.dispatchConfig.registrationName) {
1172 var registrationName = event.dispatchConfig.registrationName;
1173 var listener = getListener(inst, registrationName);
1174 if (listener) {
1175 event._dispatchListeners = accumulateInto(event._dispatchListeners, listener);
1176 event._dispatchInstances = accumulateInto(event._dispatchInstances, inst);
1177 }
1178 }
1179}
1180
1181/**
1182 * Accumulates dispatches on an `SyntheticEvent`, but only for the
1183 * `dispatchMarker`.
1184 * @param {SyntheticEvent} event
1185 */
1186function accumulateDirectDispatchesSingle(event) {
1187 if (event && event.dispatchConfig.registrationName) {
1188 accumulateDispatches(event._targetInst, null, event);
1189 }
1190}
1191
1192function accumulateTwoPhaseDispatches(events) {
1193 forEachAccumulated(events, accumulateTwoPhaseDispatchesSingle);
1194}
1195
1196
1197
1198function accumulateEnterLeaveDispatches(leave, enter, from, to) {
1199 traverseEnterLeave(from, to, accumulateDispatches, leave, enter);
1200}
1201
1202function accumulateDirectDispatches(events) {
1203 forEachAccumulated(events, accumulateDirectDispatchesSingle);
1204}
1205
1206var canUseDOM = !!(typeof window !== 'undefined' && typeof window.document !== 'undefined' && typeof window.document.createElement !== 'undefined');
1207
1208// Do not use the below two methods directly!
1209// Instead use constants exported from DOMTopLevelEventTypes in ReactDOM.
1210// (It is the only module that is allowed to access these methods.)
1211
1212function unsafeCastStringToDOMTopLevelType(topLevelType) {
1213 return topLevelType;
1214}
1215
1216function unsafeCastDOMTopLevelTypeToString(topLevelType) {
1217 return topLevelType;
1218}
1219
1220/**
1221 * Generate a mapping of standard vendor prefixes using the defined style property and event name.
1222 *
1223 * @param {string} styleProp
1224 * @param {string} eventName
1225 * @returns {object}
1226 */
1227function makePrefixMap(styleProp, eventName) {
1228 var prefixes = {};
1229
1230 prefixes[styleProp.toLowerCase()] = eventName.toLowerCase();
1231 prefixes['Webkit' + styleProp] = 'webkit' + eventName;
1232 prefixes['Moz' + styleProp] = 'moz' + eventName;
1233
1234 return prefixes;
1235}
1236
1237/**
1238 * A list of event names to a configurable list of vendor prefixes.
1239 */
1240var vendorPrefixes = {
1241 animationend: makePrefixMap('Animation', 'AnimationEnd'),
1242 animationiteration: makePrefixMap('Animation', 'AnimationIteration'),
1243 animationstart: makePrefixMap('Animation', 'AnimationStart'),
1244 transitionend: makePrefixMap('Transition', 'TransitionEnd')
1245};
1246
1247/**
1248 * Event names that have already been detected and prefixed (if applicable).
1249 */
1250var prefixedEventNames = {};
1251
1252/**
1253 * Element to check for prefixes on.
1254 */
1255var style = {};
1256
1257/**
1258 * Bootstrap if a DOM exists.
1259 */
1260if (canUseDOM) {
1261 style = document.createElement('div').style;
1262
1263 // On some platforms, in particular some releases of Android 4.x,
1264 // the un-prefixed "animation" and "transition" properties are defined on the
1265 // style object but the events that fire will still be prefixed, so we need
1266 // to check if the un-prefixed events are usable, and if not remove them from the map.
1267 if (!('AnimationEvent' in window)) {
1268 delete vendorPrefixes.animationend.animation;
1269 delete vendorPrefixes.animationiteration.animation;
1270 delete vendorPrefixes.animationstart.animation;
1271 }
1272
1273 // Same as above
1274 if (!('TransitionEvent' in window)) {
1275 delete vendorPrefixes.transitionend.transition;
1276 }
1277}
1278
1279/**
1280 * Attempts to determine the correct vendor prefixed event name.
1281 *
1282 * @param {string} eventName
1283 * @returns {string}
1284 */
1285function getVendorPrefixedEventName(eventName) {
1286 if (prefixedEventNames[eventName]) {
1287 return prefixedEventNames[eventName];
1288 } else if (!vendorPrefixes[eventName]) {
1289 return eventName;
1290 }
1291
1292 var prefixMap = vendorPrefixes[eventName];
1293
1294 for (var styleProp in prefixMap) {
1295 if (prefixMap.hasOwnProperty(styleProp) && styleProp in style) {
1296 return prefixedEventNames[eventName] = prefixMap[styleProp];
1297 }
1298 }
1299
1300 return eventName;
1301}
1302
1303/**
1304 * To identify top level events in ReactDOM, we use constants defined by this
1305 * module. This is the only module that uses the unsafe* methods to express
1306 * that the constants actually correspond to the browser event names. This lets
1307 * us save some bundle size by avoiding a top level type -> event name map.
1308 * The rest of ReactDOM code should import top level types from this file.
1309 */
1310var TOP_ABORT = unsafeCastStringToDOMTopLevelType('abort');
1311var TOP_ANIMATION_END = unsafeCastStringToDOMTopLevelType(getVendorPrefixedEventName('animationend'));
1312var TOP_ANIMATION_ITERATION = unsafeCastStringToDOMTopLevelType(getVendorPrefixedEventName('animationiteration'));
1313var TOP_ANIMATION_START = unsafeCastStringToDOMTopLevelType(getVendorPrefixedEventName('animationstart'));
1314var TOP_BLUR = unsafeCastStringToDOMTopLevelType('blur');
1315var TOP_CAN_PLAY = unsafeCastStringToDOMTopLevelType('canplay');
1316var TOP_CAN_PLAY_THROUGH = unsafeCastStringToDOMTopLevelType('canplaythrough');
1317var TOP_CANCEL = unsafeCastStringToDOMTopLevelType('cancel');
1318var TOP_CHANGE = unsafeCastStringToDOMTopLevelType('change');
1319var TOP_CLICK = unsafeCastStringToDOMTopLevelType('click');
1320var TOP_CLOSE = unsafeCastStringToDOMTopLevelType('close');
1321var TOP_COMPOSITION_END = unsafeCastStringToDOMTopLevelType('compositionend');
1322var TOP_COMPOSITION_START = unsafeCastStringToDOMTopLevelType('compositionstart');
1323var TOP_COMPOSITION_UPDATE = unsafeCastStringToDOMTopLevelType('compositionupdate');
1324var TOP_CONTEXT_MENU = unsafeCastStringToDOMTopLevelType('contextmenu');
1325var TOP_COPY = unsafeCastStringToDOMTopLevelType('copy');
1326var TOP_CUT = unsafeCastStringToDOMTopLevelType('cut');
1327var TOP_DOUBLE_CLICK = unsafeCastStringToDOMTopLevelType('dblclick');
1328var TOP_AUX_CLICK = unsafeCastStringToDOMTopLevelType('auxclick');
1329var TOP_DRAG = unsafeCastStringToDOMTopLevelType('drag');
1330var TOP_DRAG_END = unsafeCastStringToDOMTopLevelType('dragend');
1331var TOP_DRAG_ENTER = unsafeCastStringToDOMTopLevelType('dragenter');
1332var TOP_DRAG_EXIT = unsafeCastStringToDOMTopLevelType('dragexit');
1333var TOP_DRAG_LEAVE = unsafeCastStringToDOMTopLevelType('dragleave');
1334var TOP_DRAG_OVER = unsafeCastStringToDOMTopLevelType('dragover');
1335var TOP_DRAG_START = unsafeCastStringToDOMTopLevelType('dragstart');
1336var TOP_DROP = unsafeCastStringToDOMTopLevelType('drop');
1337var TOP_DURATION_CHANGE = unsafeCastStringToDOMTopLevelType('durationchange');
1338var TOP_EMPTIED = unsafeCastStringToDOMTopLevelType('emptied');
1339var TOP_ENCRYPTED = unsafeCastStringToDOMTopLevelType('encrypted');
1340var TOP_ENDED = unsafeCastStringToDOMTopLevelType('ended');
1341var TOP_ERROR = unsafeCastStringToDOMTopLevelType('error');
1342var TOP_FOCUS = unsafeCastStringToDOMTopLevelType('focus');
1343var TOP_GOT_POINTER_CAPTURE = unsafeCastStringToDOMTopLevelType('gotpointercapture');
1344var TOP_INPUT = unsafeCastStringToDOMTopLevelType('input');
1345var TOP_INVALID = unsafeCastStringToDOMTopLevelType('invalid');
1346var TOP_KEY_DOWN = unsafeCastStringToDOMTopLevelType('keydown');
1347var TOP_KEY_PRESS = unsafeCastStringToDOMTopLevelType('keypress');
1348var TOP_KEY_UP = unsafeCastStringToDOMTopLevelType('keyup');
1349var TOP_LOAD = unsafeCastStringToDOMTopLevelType('load');
1350var TOP_LOAD_START = unsafeCastStringToDOMTopLevelType('loadstart');
1351var TOP_LOADED_DATA = unsafeCastStringToDOMTopLevelType('loadeddata');
1352var TOP_LOADED_METADATA = unsafeCastStringToDOMTopLevelType('loadedmetadata');
1353var TOP_LOST_POINTER_CAPTURE = unsafeCastStringToDOMTopLevelType('lostpointercapture');
1354var TOP_MOUSE_DOWN = unsafeCastStringToDOMTopLevelType('mousedown');
1355var TOP_MOUSE_MOVE = unsafeCastStringToDOMTopLevelType('mousemove');
1356var TOP_MOUSE_OUT = unsafeCastStringToDOMTopLevelType('mouseout');
1357var TOP_MOUSE_OVER = unsafeCastStringToDOMTopLevelType('mouseover');
1358var TOP_MOUSE_UP = unsafeCastStringToDOMTopLevelType('mouseup');
1359var TOP_PASTE = unsafeCastStringToDOMTopLevelType('paste');
1360var TOP_PAUSE = unsafeCastStringToDOMTopLevelType('pause');
1361var TOP_PLAY = unsafeCastStringToDOMTopLevelType('play');
1362var TOP_PLAYING = unsafeCastStringToDOMTopLevelType('playing');
1363var TOP_POINTER_CANCEL = unsafeCastStringToDOMTopLevelType('pointercancel');
1364var TOP_POINTER_DOWN = unsafeCastStringToDOMTopLevelType('pointerdown');
1365
1366
1367var TOP_POINTER_MOVE = unsafeCastStringToDOMTopLevelType('pointermove');
1368var TOP_POINTER_OUT = unsafeCastStringToDOMTopLevelType('pointerout');
1369var TOP_POINTER_OVER = unsafeCastStringToDOMTopLevelType('pointerover');
1370var TOP_POINTER_UP = unsafeCastStringToDOMTopLevelType('pointerup');
1371var TOP_PROGRESS = unsafeCastStringToDOMTopLevelType('progress');
1372var TOP_RATE_CHANGE = unsafeCastStringToDOMTopLevelType('ratechange');
1373var TOP_RESET = unsafeCastStringToDOMTopLevelType('reset');
1374var TOP_SCROLL = unsafeCastStringToDOMTopLevelType('scroll');
1375var TOP_SEEKED = unsafeCastStringToDOMTopLevelType('seeked');
1376var TOP_SEEKING = unsafeCastStringToDOMTopLevelType('seeking');
1377var TOP_SELECTION_CHANGE = unsafeCastStringToDOMTopLevelType('selectionchange');
1378var TOP_STALLED = unsafeCastStringToDOMTopLevelType('stalled');
1379var TOP_SUBMIT = unsafeCastStringToDOMTopLevelType('submit');
1380var TOP_SUSPEND = unsafeCastStringToDOMTopLevelType('suspend');
1381var TOP_TEXT_INPUT = unsafeCastStringToDOMTopLevelType('textInput');
1382var TOP_TIME_UPDATE = unsafeCastStringToDOMTopLevelType('timeupdate');
1383var TOP_TOGGLE = unsafeCastStringToDOMTopLevelType('toggle');
1384var TOP_TOUCH_CANCEL = unsafeCastStringToDOMTopLevelType('touchcancel');
1385var TOP_TOUCH_END = unsafeCastStringToDOMTopLevelType('touchend');
1386var TOP_TOUCH_MOVE = unsafeCastStringToDOMTopLevelType('touchmove');
1387var TOP_TOUCH_START = unsafeCastStringToDOMTopLevelType('touchstart');
1388var TOP_TRANSITION_END = unsafeCastStringToDOMTopLevelType(getVendorPrefixedEventName('transitionend'));
1389var TOP_VOLUME_CHANGE = unsafeCastStringToDOMTopLevelType('volumechange');
1390var TOP_WAITING = unsafeCastStringToDOMTopLevelType('waiting');
1391var TOP_WHEEL = unsafeCastStringToDOMTopLevelType('wheel');
1392
1393// List of events that need to be individually attached to media elements.
1394// Note that events in this list will *not* be listened to at the top level
1395// unless they're explicitly whitelisted in `ReactBrowserEventEmitter.listenTo`.
1396var 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];
1397
1398function getRawEventName(topLevelType) {
1399 return unsafeCastDOMTopLevelTypeToString(topLevelType);
1400}
1401
1402/**
1403 * These variables store information about text content of a target node,
1404 * allowing comparison of content before and after a given event.
1405 *
1406 * Identify the node where selection currently begins, then observe
1407 * both its text content and its current position in the DOM. Since the
1408 * browser may natively replace the target node during composition, we can
1409 * use its position to find its replacement.
1410 *
1411 *
1412 */
1413
1414var root = null;
1415var startText = null;
1416var fallbackText = null;
1417
1418function initialize(nativeEventTarget) {
1419 root = nativeEventTarget;
1420 startText = getText();
1421 return true;
1422}
1423
1424function reset() {
1425 root = null;
1426 startText = null;
1427 fallbackText = null;
1428}
1429
1430function getData() {
1431 if (fallbackText) {
1432 return fallbackText;
1433 }
1434
1435 var start = void 0;
1436 var startValue = startText;
1437 var startLength = startValue.length;
1438 var end = void 0;
1439 var endValue = getText();
1440 var endLength = endValue.length;
1441
1442 for (start = 0; start < startLength; start++) {
1443 if (startValue[start] !== endValue[start]) {
1444 break;
1445 }
1446 }
1447
1448 var minEnd = startLength - start;
1449 for (end = 1; end <= minEnd; end++) {
1450 if (startValue[startLength - end] !== endValue[endLength - end]) {
1451 break;
1452 }
1453 }
1454
1455 var sliceTail = end > 1 ? 1 - end : undefined;
1456 fallbackText = endValue.slice(start, sliceTail);
1457 return fallbackText;
1458}
1459
1460function getText() {
1461 if ('value' in root) {
1462 return root.value;
1463 }
1464 return root.textContent;
1465}
1466
1467/* eslint valid-typeof: 0 */
1468
1469var EVENT_POOL_SIZE = 10;
1470
1471/**
1472 * @interface Event
1473 * @see http://www.w3.org/TR/DOM-Level-3-Events/
1474 */
1475var EventInterface = {
1476 type: null,
1477 target: null,
1478 // currentTarget is set when dispatching; no use in copying it here
1479 currentTarget: function () {
1480 return null;
1481 },
1482 eventPhase: null,
1483 bubbles: null,
1484 cancelable: null,
1485 timeStamp: function (event) {
1486 return event.timeStamp || Date.now();
1487 },
1488 defaultPrevented: null,
1489 isTrusted: null
1490};
1491
1492function functionThatReturnsTrue() {
1493 return true;
1494}
1495
1496function functionThatReturnsFalse() {
1497 return false;
1498}
1499
1500/**
1501 * Synthetic events are dispatched by event plugins, typically in response to a
1502 * top-level event delegation handler.
1503 *
1504 * These systems should generally use pooling to reduce the frequency of garbage
1505 * collection. The system should check `isPersistent` to determine whether the
1506 * event should be released into the pool after being dispatched. Users that
1507 * need a persisted event should invoke `persist`.
1508 *
1509 * Synthetic events (and subclasses) implement the DOM Level 3 Events API by
1510 * normalizing browser quirks. Subclasses do not necessarily have to implement a
1511 * DOM interface; custom application-specific events can also subclass this.
1512 *
1513 * @param {object} dispatchConfig Configuration used to dispatch this event.
1514 * @param {*} targetInst Marker identifying the event target.
1515 * @param {object} nativeEvent Native browser event.
1516 * @param {DOMEventTarget} nativeEventTarget Target node.
1517 */
1518function SyntheticEvent(dispatchConfig, targetInst, nativeEvent, nativeEventTarget) {
1519 {
1520 // these have a getter/setter for warnings
1521 delete this.nativeEvent;
1522 delete this.preventDefault;
1523 delete this.stopPropagation;
1524 delete this.isDefaultPrevented;
1525 delete this.isPropagationStopped;
1526 }
1527
1528 this.dispatchConfig = dispatchConfig;
1529 this._targetInst = targetInst;
1530 this.nativeEvent = nativeEvent;
1531
1532 var Interface = this.constructor.Interface;
1533 for (var propName in Interface) {
1534 if (!Interface.hasOwnProperty(propName)) {
1535 continue;
1536 }
1537 {
1538 delete this[propName]; // this has a getter/setter for warnings
1539 }
1540 var normalize = Interface[propName];
1541 if (normalize) {
1542 this[propName] = normalize(nativeEvent);
1543 } else {
1544 if (propName === 'target') {
1545 this.target = nativeEventTarget;
1546 } else {
1547 this[propName] = nativeEvent[propName];
1548 }
1549 }
1550 }
1551
1552 var defaultPrevented = nativeEvent.defaultPrevented != null ? nativeEvent.defaultPrevented : nativeEvent.returnValue === false;
1553 if (defaultPrevented) {
1554 this.isDefaultPrevented = functionThatReturnsTrue;
1555 } else {
1556 this.isDefaultPrevented = functionThatReturnsFalse;
1557 }
1558 this.isPropagationStopped = functionThatReturnsFalse;
1559 return this;
1560}
1561
1562_assign(SyntheticEvent.prototype, {
1563 preventDefault: function () {
1564 this.defaultPrevented = true;
1565 var event = this.nativeEvent;
1566 if (!event) {
1567 return;
1568 }
1569
1570 if (event.preventDefault) {
1571 event.preventDefault();
1572 } else if (typeof event.returnValue !== 'unknown') {
1573 event.returnValue = false;
1574 }
1575 this.isDefaultPrevented = functionThatReturnsTrue;
1576 },
1577
1578 stopPropagation: function () {
1579 var event = this.nativeEvent;
1580 if (!event) {
1581 return;
1582 }
1583
1584 if (event.stopPropagation) {
1585 event.stopPropagation();
1586 } else if (typeof event.cancelBubble !== 'unknown') {
1587 // The ChangeEventPlugin registers a "propertychange" event for
1588 // IE. This event does not support bubbling or cancelling, and
1589 // any references to cancelBubble throw "Member not found". A
1590 // typeof check of "unknown" circumvents this issue (and is also
1591 // IE specific).
1592 event.cancelBubble = true;
1593 }
1594
1595 this.isPropagationStopped = functionThatReturnsTrue;
1596 },
1597
1598 /**
1599 * We release all dispatched `SyntheticEvent`s after each event loop, adding
1600 * them back into the pool. This allows a way to hold onto a reference that
1601 * won't be added back into the pool.
1602 */
1603 persist: function () {
1604 this.isPersistent = functionThatReturnsTrue;
1605 },
1606
1607 /**
1608 * Checks if this event should be released back into the pool.
1609 *
1610 * @return {boolean} True if this should not be released, false otherwise.
1611 */
1612 isPersistent: functionThatReturnsFalse,
1613
1614 /**
1615 * `PooledClass` looks for `destructor` on each instance it releases.
1616 */
1617 destructor: function () {
1618 var Interface = this.constructor.Interface;
1619 for (var propName in Interface) {
1620 {
1621 Object.defineProperty(this, propName, getPooledWarningPropertyDefinition(propName, Interface[propName]));
1622 }
1623 }
1624 this.dispatchConfig = null;
1625 this._targetInst = null;
1626 this.nativeEvent = null;
1627 this.isDefaultPrevented = functionThatReturnsFalse;
1628 this.isPropagationStopped = functionThatReturnsFalse;
1629 this._dispatchListeners = null;
1630 this._dispatchInstances = null;
1631 {
1632 Object.defineProperty(this, 'nativeEvent', getPooledWarningPropertyDefinition('nativeEvent', null));
1633 Object.defineProperty(this, 'isDefaultPrevented', getPooledWarningPropertyDefinition('isDefaultPrevented', functionThatReturnsFalse));
1634 Object.defineProperty(this, 'isPropagationStopped', getPooledWarningPropertyDefinition('isPropagationStopped', functionThatReturnsFalse));
1635 Object.defineProperty(this, 'preventDefault', getPooledWarningPropertyDefinition('preventDefault', function () {}));
1636 Object.defineProperty(this, 'stopPropagation', getPooledWarningPropertyDefinition('stopPropagation', function () {}));
1637 }
1638 }
1639});
1640
1641SyntheticEvent.Interface = EventInterface;
1642
1643/**
1644 * Helper to reduce boilerplate when creating subclasses.
1645 */
1646SyntheticEvent.extend = function (Interface) {
1647 var Super = this;
1648
1649 var E = function () {};
1650 E.prototype = Super.prototype;
1651 var prototype = new E();
1652
1653 function Class() {
1654 return Super.apply(this, arguments);
1655 }
1656 _assign(prototype, Class.prototype);
1657 Class.prototype = prototype;
1658 Class.prototype.constructor = Class;
1659
1660 Class.Interface = _assign({}, Super.Interface, Interface);
1661 Class.extend = Super.extend;
1662 addEventPoolingTo(Class);
1663
1664 return Class;
1665};
1666
1667addEventPoolingTo(SyntheticEvent);
1668
1669/**
1670 * Helper to nullify syntheticEvent instance properties when destructing
1671 *
1672 * @param {String} propName
1673 * @param {?object} getVal
1674 * @return {object} defineProperty object
1675 */
1676function getPooledWarningPropertyDefinition(propName, getVal) {
1677 var isFunction = typeof getVal === 'function';
1678 return {
1679 configurable: true,
1680 set: set,
1681 get: get
1682 };
1683
1684 function set(val) {
1685 var action = isFunction ? 'setting the method' : 'setting the property';
1686 warn(action, 'This is effectively a no-op');
1687 return val;
1688 }
1689
1690 function get() {
1691 var action = isFunction ? 'accessing the method' : 'accessing the property';
1692 var result = isFunction ? 'This is a no-op function' : 'This is set to null';
1693 warn(action, result);
1694 return getVal;
1695 }
1696
1697 function warn(action, result) {
1698 var warningCondition = false;
1699 !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;
1700 }
1701}
1702
1703function getPooledEvent(dispatchConfig, targetInst, nativeEvent, nativeInst) {
1704 var EventConstructor = this;
1705 if (EventConstructor.eventPool.length) {
1706 var instance = EventConstructor.eventPool.pop();
1707 EventConstructor.call(instance, dispatchConfig, targetInst, nativeEvent, nativeInst);
1708 return instance;
1709 }
1710 return new EventConstructor(dispatchConfig, targetInst, nativeEvent, nativeInst);
1711}
1712
1713function releasePooledEvent(event) {
1714 var EventConstructor = this;
1715 (function () {
1716 if (!(event instanceof EventConstructor)) {
1717 {
1718 throw ReactError(Error('Trying to release an event instance into a pool of a different type.'));
1719 }
1720 }
1721 })();
1722 event.destructor();
1723 if (EventConstructor.eventPool.length < EVENT_POOL_SIZE) {
1724 EventConstructor.eventPool.push(event);
1725 }
1726}
1727
1728function addEventPoolingTo(EventConstructor) {
1729 EventConstructor.eventPool = [];
1730 EventConstructor.getPooled = getPooledEvent;
1731 EventConstructor.release = releasePooledEvent;
1732}
1733
1734/**
1735 * @interface Event
1736 * @see http://www.w3.org/TR/DOM-Level-3-Events/#events-compositionevents
1737 */
1738var SyntheticCompositionEvent = SyntheticEvent.extend({
1739 data: null
1740});
1741
1742/**
1743 * @interface Event
1744 * @see http://www.w3.org/TR/2013/WD-DOM-Level-3-Events-20131105
1745 * /#events-inputevents
1746 */
1747var SyntheticInputEvent = SyntheticEvent.extend({
1748 data: null
1749});
1750
1751var END_KEYCODES = [9, 13, 27, 32]; // Tab, Return, Esc, Space
1752var START_KEYCODE = 229;
1753
1754var canUseCompositionEvent = canUseDOM && 'CompositionEvent' in window;
1755
1756var documentMode = null;
1757if (canUseDOM && 'documentMode' in document) {
1758 documentMode = document.documentMode;
1759}
1760
1761// Webkit offers a very useful `textInput` event that can be used to
1762// directly represent `beforeInput`. The IE `textinput` event is not as
1763// useful, so we don't use it.
1764var canUseTextInputEvent = canUseDOM && 'TextEvent' in window && !documentMode;
1765
1766// In IE9+, we have access to composition events, but the data supplied
1767// by the native compositionend event may be incorrect. Japanese ideographic
1768// spaces, for instance (\u3000) are not recorded correctly.
1769var useFallbackCompositionData = canUseDOM && (!canUseCompositionEvent || documentMode && documentMode > 8 && documentMode <= 11);
1770
1771var SPACEBAR_CODE = 32;
1772var SPACEBAR_CHAR = String.fromCharCode(SPACEBAR_CODE);
1773
1774// Events and their corresponding property names.
1775var eventTypes = {
1776 beforeInput: {
1777 phasedRegistrationNames: {
1778 bubbled: 'onBeforeInput',
1779 captured: 'onBeforeInputCapture'
1780 },
1781 dependencies: [TOP_COMPOSITION_END, TOP_KEY_PRESS, TOP_TEXT_INPUT, TOP_PASTE]
1782 },
1783 compositionEnd: {
1784 phasedRegistrationNames: {
1785 bubbled: 'onCompositionEnd',
1786 captured: 'onCompositionEndCapture'
1787 },
1788 dependencies: [TOP_BLUR, TOP_COMPOSITION_END, TOP_KEY_DOWN, TOP_KEY_PRESS, TOP_KEY_UP, TOP_MOUSE_DOWN]
1789 },
1790 compositionStart: {
1791 phasedRegistrationNames: {
1792 bubbled: 'onCompositionStart',
1793 captured: 'onCompositionStartCapture'
1794 },
1795 dependencies: [TOP_BLUR, TOP_COMPOSITION_START, TOP_KEY_DOWN, TOP_KEY_PRESS, TOP_KEY_UP, TOP_MOUSE_DOWN]
1796 },
1797 compositionUpdate: {
1798 phasedRegistrationNames: {
1799 bubbled: 'onCompositionUpdate',
1800 captured: 'onCompositionUpdateCapture'
1801 },
1802 dependencies: [TOP_BLUR, TOP_COMPOSITION_UPDATE, TOP_KEY_DOWN, TOP_KEY_PRESS, TOP_KEY_UP, TOP_MOUSE_DOWN]
1803 }
1804};
1805
1806// Track whether we've ever handled a keypress on the space key.
1807var hasSpaceKeypress = false;
1808
1809/**
1810 * Return whether a native keypress event is assumed to be a command.
1811 * This is required because Firefox fires `keypress` events for key commands
1812 * (cut, copy, select-all, etc.) even though no character is inserted.
1813 */
1814function isKeypressCommand(nativeEvent) {
1815 return (nativeEvent.ctrlKey || nativeEvent.altKey || nativeEvent.metaKey) &&
1816 // ctrlKey && altKey is equivalent to AltGr, and is not a command.
1817 !(nativeEvent.ctrlKey && nativeEvent.altKey);
1818}
1819
1820/**
1821 * Translate native top level events into event types.
1822 *
1823 * @param {string} topLevelType
1824 * @return {object}
1825 */
1826function getCompositionEventType(topLevelType) {
1827 switch (topLevelType) {
1828 case TOP_COMPOSITION_START:
1829 return eventTypes.compositionStart;
1830 case TOP_COMPOSITION_END:
1831 return eventTypes.compositionEnd;
1832 case TOP_COMPOSITION_UPDATE:
1833 return eventTypes.compositionUpdate;
1834 }
1835}
1836
1837/**
1838 * Does our fallback best-guess model think this event signifies that
1839 * composition has begun?
1840 *
1841 * @param {string} topLevelType
1842 * @param {object} nativeEvent
1843 * @return {boolean}
1844 */
1845function isFallbackCompositionStart(topLevelType, nativeEvent) {
1846 return topLevelType === TOP_KEY_DOWN && nativeEvent.keyCode === START_KEYCODE;
1847}
1848
1849/**
1850 * Does our fallback mode think that this event is the end of composition?
1851 *
1852 * @param {string} topLevelType
1853 * @param {object} nativeEvent
1854 * @return {boolean}
1855 */
1856function isFallbackCompositionEnd(topLevelType, nativeEvent) {
1857 switch (topLevelType) {
1858 case TOP_KEY_UP:
1859 // Command keys insert or clear IME input.
1860 return END_KEYCODES.indexOf(nativeEvent.keyCode) !== -1;
1861 case TOP_KEY_DOWN:
1862 // Expect IME keyCode on each keydown. If we get any other
1863 // code we must have exited earlier.
1864 return nativeEvent.keyCode !== START_KEYCODE;
1865 case TOP_KEY_PRESS:
1866 case TOP_MOUSE_DOWN:
1867 case TOP_BLUR:
1868 // Events are not possible without cancelling IME.
1869 return true;
1870 default:
1871 return false;
1872 }
1873}
1874
1875/**
1876 * Google Input Tools provides composition data via a CustomEvent,
1877 * with the `data` property populated in the `detail` object. If this
1878 * is available on the event object, use it. If not, this is a plain
1879 * composition event and we have nothing special to extract.
1880 *
1881 * @param {object} nativeEvent
1882 * @return {?string}
1883 */
1884function getDataFromCustomEvent(nativeEvent) {
1885 var detail = nativeEvent.detail;
1886 if (typeof detail === 'object' && 'data' in detail) {
1887 return detail.data;
1888 }
1889 return null;
1890}
1891
1892/**
1893 * Check if a composition event was triggered by Korean IME.
1894 * Our fallback mode does not work well with IE's Korean IME,
1895 * so just use native composition events when Korean IME is used.
1896 * Although CompositionEvent.locale property is deprecated,
1897 * it is available in IE, where our fallback mode is enabled.
1898 *
1899 * @param {object} nativeEvent
1900 * @return {boolean}
1901 */
1902function isUsingKoreanIME(nativeEvent) {
1903 return nativeEvent.locale === 'ko';
1904}
1905
1906// Track the current IME composition status, if any.
1907var isComposing = false;
1908
1909/**
1910 * @return {?object} A SyntheticCompositionEvent.
1911 */
1912function extractCompositionEvent(topLevelType, targetInst, nativeEvent, nativeEventTarget) {
1913 var eventType = void 0;
1914 var fallbackData = void 0;
1915
1916 if (canUseCompositionEvent) {
1917 eventType = getCompositionEventType(topLevelType);
1918 } else if (!isComposing) {
1919 if (isFallbackCompositionStart(topLevelType, nativeEvent)) {
1920 eventType = eventTypes.compositionStart;
1921 }
1922 } else if (isFallbackCompositionEnd(topLevelType, nativeEvent)) {
1923 eventType = eventTypes.compositionEnd;
1924 }
1925
1926 if (!eventType) {
1927 return null;
1928 }
1929
1930 if (useFallbackCompositionData && !isUsingKoreanIME(nativeEvent)) {
1931 // The current composition is stored statically and must not be
1932 // overwritten while composition continues.
1933 if (!isComposing && eventType === eventTypes.compositionStart) {
1934 isComposing = initialize(nativeEventTarget);
1935 } else if (eventType === eventTypes.compositionEnd) {
1936 if (isComposing) {
1937 fallbackData = getData();
1938 }
1939 }
1940 }
1941
1942 var event = SyntheticCompositionEvent.getPooled(eventType, targetInst, nativeEvent, nativeEventTarget);
1943
1944 if (fallbackData) {
1945 // Inject data generated from fallback path into the synthetic event.
1946 // This matches the property of native CompositionEventInterface.
1947 event.data = fallbackData;
1948 } else {
1949 var customData = getDataFromCustomEvent(nativeEvent);
1950 if (customData !== null) {
1951 event.data = customData;
1952 }
1953 }
1954
1955 accumulateTwoPhaseDispatches(event);
1956 return event;
1957}
1958
1959/**
1960 * @param {TopLevelType} topLevelType Number from `TopLevelType`.
1961 * @param {object} nativeEvent Native browser event.
1962 * @return {?string} The string corresponding to this `beforeInput` event.
1963 */
1964function getNativeBeforeInputChars(topLevelType, nativeEvent) {
1965 switch (topLevelType) {
1966 case TOP_COMPOSITION_END:
1967 return getDataFromCustomEvent(nativeEvent);
1968 case TOP_KEY_PRESS:
1969 /**
1970 * If native `textInput` events are available, our goal is to make
1971 * use of them. However, there is a special case: the spacebar key.
1972 * In Webkit, preventing default on a spacebar `textInput` event
1973 * cancels character insertion, but it *also* causes the browser
1974 * to fall back to its default spacebar behavior of scrolling the
1975 * page.
1976 *
1977 * Tracking at:
1978 * https://code.google.com/p/chromium/issues/detail?id=355103
1979 *
1980 * To avoid this issue, use the keypress event as if no `textInput`
1981 * event is available.
1982 */
1983 var which = nativeEvent.which;
1984 if (which !== SPACEBAR_CODE) {
1985 return null;
1986 }
1987
1988 hasSpaceKeypress = true;
1989 return SPACEBAR_CHAR;
1990
1991 case TOP_TEXT_INPUT:
1992 // Record the characters to be added to the DOM.
1993 var chars = nativeEvent.data;
1994
1995 // If it's a spacebar character, assume that we have already handled
1996 // it at the keypress level and bail immediately. Android Chrome
1997 // doesn't give us keycodes, so we need to ignore it.
1998 if (chars === SPACEBAR_CHAR && hasSpaceKeypress) {
1999 return null;
2000 }
2001
2002 return chars;
2003
2004 default:
2005 // For other native event types, do nothing.
2006 return null;
2007 }
2008}
2009
2010/**
2011 * For browsers that do not provide the `textInput` event, extract the
2012 * appropriate string to use for SyntheticInputEvent.
2013 *
2014 * @param {number} topLevelType Number from `TopLevelEventTypes`.
2015 * @param {object} nativeEvent Native browser event.
2016 * @return {?string} The fallback string for this `beforeInput` event.
2017 */
2018function getFallbackBeforeInputChars(topLevelType, nativeEvent) {
2019 // If we are currently composing (IME) and using a fallback to do so,
2020 // try to extract the composed characters from the fallback object.
2021 // If composition event is available, we extract a string only at
2022 // compositionevent, otherwise extract it at fallback events.
2023 if (isComposing) {
2024 if (topLevelType === TOP_COMPOSITION_END || !canUseCompositionEvent && isFallbackCompositionEnd(topLevelType, nativeEvent)) {
2025 var chars = getData();
2026 reset();
2027 isComposing = false;
2028 return chars;
2029 }
2030 return null;
2031 }
2032
2033 switch (topLevelType) {
2034 case TOP_PASTE:
2035 // If a paste event occurs after a keypress, throw out the input
2036 // chars. Paste events should not lead to BeforeInput events.
2037 return null;
2038 case TOP_KEY_PRESS:
2039 /**
2040 * As of v27, Firefox may fire keypress events even when no character
2041 * will be inserted. A few possibilities:
2042 *
2043 * - `which` is `0`. Arrow keys, Esc key, etc.
2044 *
2045 * - `which` is the pressed key code, but no char is available.
2046 * Ex: 'AltGr + d` in Polish. There is no modified character for
2047 * this key combination and no character is inserted into the
2048 * document, but FF fires the keypress for char code `100` anyway.
2049 * No `input` event will occur.
2050 *
2051 * - `which` is the pressed key code, but a command combination is
2052 * being used. Ex: `Cmd+C`. No character is inserted, and no
2053 * `input` event will occur.
2054 */
2055 if (!isKeypressCommand(nativeEvent)) {
2056 // IE fires the `keypress` event when a user types an emoji via
2057 // Touch keyboard of Windows. In such a case, the `char` property
2058 // holds an emoji character like `\uD83D\uDE0A`. Because its length
2059 // is 2, the property `which` does not represent an emoji correctly.
2060 // In such a case, we directly return the `char` property instead of
2061 // using `which`.
2062 if (nativeEvent.char && nativeEvent.char.length > 1) {
2063 return nativeEvent.char;
2064 } else if (nativeEvent.which) {
2065 return String.fromCharCode(nativeEvent.which);
2066 }
2067 }
2068 return null;
2069 case TOP_COMPOSITION_END:
2070 return useFallbackCompositionData && !isUsingKoreanIME(nativeEvent) ? null : nativeEvent.data;
2071 default:
2072 return null;
2073 }
2074}
2075
2076/**
2077 * Extract a SyntheticInputEvent for `beforeInput`, based on either native
2078 * `textInput` or fallback behavior.
2079 *
2080 * @return {?object} A SyntheticInputEvent.
2081 */
2082function extractBeforeInputEvent(topLevelType, targetInst, nativeEvent, nativeEventTarget) {
2083 var chars = void 0;
2084
2085 if (canUseTextInputEvent) {
2086 chars = getNativeBeforeInputChars(topLevelType, nativeEvent);
2087 } else {
2088 chars = getFallbackBeforeInputChars(topLevelType, nativeEvent);
2089 }
2090
2091 // If no characters are being inserted, no BeforeInput event should
2092 // be fired.
2093 if (!chars) {
2094 return null;
2095 }
2096
2097 var event = SyntheticInputEvent.getPooled(eventTypes.beforeInput, targetInst, nativeEvent, nativeEventTarget);
2098
2099 event.data = chars;
2100 accumulateTwoPhaseDispatches(event);
2101 return event;
2102}
2103
2104/**
2105 * Create an `onBeforeInput` event to match
2106 * http://www.w3.org/TR/2013/WD-DOM-Level-3-Events-20131105/#events-inputevents.
2107 *
2108 * This event plugin is based on the native `textInput` event
2109 * available in Chrome, Safari, Opera, and IE. This event fires after
2110 * `onKeyPress` and `onCompositionEnd`, but before `onInput`.
2111 *
2112 * `beforeInput` is spec'd but not implemented in any browsers, and
2113 * the `input` event does not provide any useful information about what has
2114 * actually been added, contrary to the spec. Thus, `textInput` is the best
2115 * available event to identify the characters that have actually been inserted
2116 * into the target node.
2117 *
2118 * This plugin is also responsible for emitting `composition` events, thus
2119 * allowing us to share composition fallback code for both `beforeInput` and
2120 * `composition` event types.
2121 */
2122var BeforeInputEventPlugin = {
2123 eventTypes: eventTypes,
2124
2125 extractEvents: function (topLevelType, targetInst, nativeEvent, nativeEventTarget) {
2126 var composition = extractCompositionEvent(topLevelType, targetInst, nativeEvent, nativeEventTarget);
2127
2128 var beforeInput = extractBeforeInputEvent(topLevelType, targetInst, nativeEvent, nativeEventTarget);
2129
2130 if (composition === null) {
2131 return beforeInput;
2132 }
2133
2134 if (beforeInput === null) {
2135 return composition;
2136 }
2137
2138 return [composition, beforeInput];
2139 }
2140};
2141
2142// Use to restore controlled state after a change event has fired.
2143
2144var restoreImpl = null;
2145var restoreTarget = null;
2146var restoreQueue = null;
2147
2148function restoreStateOfTarget(target) {
2149 // We perform this translation at the end of the event loop so that we
2150 // always receive the correct fiber here
2151 var internalInstance = getInstanceFromNode(target);
2152 if (!internalInstance) {
2153 // Unmounted
2154 return;
2155 }
2156 (function () {
2157 if (!(typeof restoreImpl === 'function')) {
2158 {
2159 throw ReactError(Error('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.'));
2160 }
2161 }
2162 })();
2163 var props = getFiberCurrentPropsFromNode(internalInstance.stateNode);
2164 restoreImpl(internalInstance.stateNode, internalInstance.type, props);
2165}
2166
2167function setRestoreImplementation(impl) {
2168 restoreImpl = impl;
2169}
2170
2171function enqueueStateRestore(target) {
2172 if (restoreTarget) {
2173 if (restoreQueue) {
2174 restoreQueue.push(target);
2175 } else {
2176 restoreQueue = [target];
2177 }
2178 } else {
2179 restoreTarget = target;
2180 }
2181}
2182
2183function needsStateRestore() {
2184 return restoreTarget !== null || restoreQueue !== null;
2185}
2186
2187function restoreStateIfNeeded() {
2188 if (!restoreTarget) {
2189 return;
2190 }
2191 var target = restoreTarget;
2192 var queuedTargets = restoreQueue;
2193 restoreTarget = null;
2194 restoreQueue = null;
2195
2196 restoreStateOfTarget(target);
2197 if (queuedTargets) {
2198 for (var i = 0; i < queuedTargets.length; i++) {
2199 restoreStateOfTarget(queuedTargets[i]);
2200 }
2201 }
2202}
2203
2204var enableUserTimingAPI = true;
2205
2206// Helps identify side effects in begin-phase lifecycle hooks and setState reducers:
2207var debugRenderPhaseSideEffects = false;
2208
2209// In some cases, StrictMode should also double-render lifecycles.
2210// This can be confusing for tests though,
2211// And it can be bad for performance in production.
2212// This feature flag can be used to control the behavior:
2213var debugRenderPhaseSideEffectsForStrictMode = true;
2214
2215// To preserve the "Pause on caught exceptions" behavior of the debugger, we
2216// replay the begin phase of a failed component inside invokeGuardedCallback.
2217var replayFailedUnitOfWorkWithInvokeGuardedCallback = true;
2218
2219// Warn about deprecated, async-unsafe lifecycles; relates to RFC #6:
2220var warnAboutDeprecatedLifecycles = true;
2221
2222// Gather advanced timing metrics for Profiler subtrees.
2223var enableProfilerTimer = true;
2224
2225// Trace which interactions trigger each commit.
2226var enableSchedulerTracing = true;
2227
2228// Only used in www builds.
2229var enableSuspenseServerRenderer = false; // TODO: true? Here it might just be false.
2230
2231// Only used in www builds.
2232
2233
2234// Only used in www builds.
2235
2236
2237// Disable javascript: URL strings in href for XSS protection.
2238var disableJavaScriptURLs = false;
2239
2240// React Fire: prevent the value and checked attributes from syncing
2241// with their related DOM properties
2242var disableInputAttributeSyncing = false;
2243
2244// These APIs will no longer be "unstable" in the upcoming 16.7 release,
2245// Control this behavior with a flag to support 16.6 minor releases in the meanwhile.
2246var enableStableConcurrentModeAPIs = false;
2247
2248var warnAboutShorthandPropertyCollision = false;
2249
2250// See https://github.com/react-native-community/discussions-and-proposals/issues/72 for more information
2251// This is a flag so we can fix warnings in RN core before turning it on
2252
2253
2254// Experimental React Flare event system and event components support.
2255var enableFlareAPI = false;
2256
2257// Experimental Host Component support.
2258var enableFundamentalAPI = false;
2259
2260// New API for JSX transforms to target - https://github.com/reactjs/rfcs/pull/107
2261
2262
2263// We will enforce mocking scheduler with scheduler/unstable_mock at some point. (v17?)
2264// Till then, we warn about the missing mock, but still fallback to a sync mode compatible version
2265var warnAboutUnmockedScheduler = false;
2266// Temporary flag to revert the fix in #15650
2267var revertPassiveEffectsChange = false;
2268
2269// For tests, we flush suspense fallbacks in an act scope;
2270// *except* in some of our own tests, where we test incremental loading states.
2271var flushSuspenseFallbacksInTests = true;
2272
2273// Changes priority of some events like mousemove to user-blocking priority,
2274// but without making them discrete. The flag exists in case it causes
2275// starvation problems.
2276var enableUserBlockingEvents = false;
2277
2278// Add a callback property to suspense to notify which promises are currently
2279// in the update queue. This allows reporting and tracing of what is causing
2280// the user to see a loading state.
2281var enableSuspenseCallback = false;
2282
2283// Part of the simplification of React.createElement so we can eventually move
2284// from React.createElement to React.jsx
2285// https://github.com/reactjs/rfcs/blob/createlement-rfc/text/0000-create-element-changes.md
2286var warnAboutDefaultPropsOnFunctionComponents = false;
2287
2288var disableLegacyContext = false;
2289
2290var disableSchedulerTimeoutBasedOnReactExpirationTime = false;
2291
2292// Used as a way to call batchedUpdates when we don't have a reference to
2293// the renderer. Such as when we're dispatching events or if third party
2294// libraries need to call batchedUpdates. Eventually, this API will go away when
2295// everything is batched by default. We'll then have a similar API to opt-out of
2296// scheduled work and instead do synchronous work.
2297
2298// Defaults
2299var batchedUpdatesImpl = function (fn, bookkeeping) {
2300 return fn(bookkeeping);
2301};
2302var discreteUpdatesImpl = function (fn, a, b, c) {
2303 return fn(a, b, c);
2304};
2305var flushDiscreteUpdatesImpl = function () {};
2306var batchedEventUpdatesImpl = batchedUpdatesImpl;
2307
2308var isInsideEventHandler = false;
2309
2310function finishEventHandler() {
2311 // Here we wait until all updates have propagated, which is important
2312 // when using controlled components within layers:
2313 // https://github.com/facebook/react/issues/1698
2314 // Then we restore state of any controlled component.
2315 var controlledComponentsHavePendingUpdates = needsStateRestore();
2316 if (controlledComponentsHavePendingUpdates) {
2317 // If a controlled event was fired, we may need to restore the state of
2318 // the DOM node back to the controlled value. This is necessary when React
2319 // bails out of the update without touching the DOM.
2320 flushDiscreteUpdatesImpl();
2321 restoreStateIfNeeded();
2322 }
2323}
2324
2325function batchedUpdates(fn, bookkeeping) {
2326 if (isInsideEventHandler) {
2327 // If we are currently inside another batch, we need to wait until it
2328 // fully completes before restoring state.
2329 return fn(bookkeeping);
2330 }
2331 isInsideEventHandler = true;
2332 try {
2333 return batchedUpdatesImpl(fn, bookkeeping);
2334 } finally {
2335 isInsideEventHandler = false;
2336 finishEventHandler();
2337 }
2338}
2339
2340function batchedEventUpdates(fn, a, b) {
2341 if (isInsideEventHandler) {
2342 // If we are currently inside another batch, we need to wait until it
2343 // fully completes before restoring state.
2344 return fn(a, b);
2345 }
2346 isInsideEventHandler = true;
2347 try {
2348 return batchedEventUpdatesImpl(fn, a, b);
2349 } finally {
2350 isInsideEventHandler = false;
2351 finishEventHandler();
2352 }
2353}
2354
2355function discreteUpdates(fn, a, b, c) {
2356 var prevIsInsideEventHandler = isInsideEventHandler;
2357 isInsideEventHandler = true;
2358 try {
2359 return discreteUpdatesImpl(fn, a, b, c);
2360 } finally {
2361 isInsideEventHandler = prevIsInsideEventHandler;
2362 if (!isInsideEventHandler) {
2363 finishEventHandler();
2364 }
2365 }
2366}
2367
2368var lastFlushedEventTimeStamp = 0;
2369function flushDiscreteUpdatesIfNeeded(timeStamp) {
2370 // event.timeStamp isn't overly reliable due to inconsistencies in
2371 // how different browsers have historically provided the time stamp.
2372 // Some browsers provide high-resolution time stamps for all events,
2373 // some provide low-resolution time stamps for all events. FF < 52
2374 // even mixes both time stamps together. Some browsers even report
2375 // negative time stamps or time stamps that are 0 (iOS9) in some cases.
2376 // Given we are only comparing two time stamps with equality (!==),
2377 // we are safe from the resolution differences. If the time stamp is 0
2378 // we bail-out of preventing the flush, which can affect semantics,
2379 // such as if an earlier flush removes or adds event listeners that
2380 // are fired in the subsequent flush. However, this is the same
2381 // behaviour as we had before this change, so the risks are low.
2382 if (!isInsideEventHandler && (!enableFlareAPI || timeStamp === 0 || lastFlushedEventTimeStamp !== timeStamp)) {
2383 lastFlushedEventTimeStamp = timeStamp;
2384 flushDiscreteUpdatesImpl();
2385 }
2386}
2387
2388function setBatchingImplementation(_batchedUpdatesImpl, _discreteUpdatesImpl, _flushDiscreteUpdatesImpl, _batchedEventUpdatesImpl) {
2389 batchedUpdatesImpl = _batchedUpdatesImpl;
2390 discreteUpdatesImpl = _discreteUpdatesImpl;
2391 flushDiscreteUpdatesImpl = _flushDiscreteUpdatesImpl;
2392 batchedEventUpdatesImpl = _batchedEventUpdatesImpl;
2393}
2394
2395/**
2396 * @see http://www.whatwg.org/specs/web-apps/current-work/multipage/the-input-element.html#input-type-attr-summary
2397 */
2398var supportedInputTypes = {
2399 color: true,
2400 date: true,
2401 datetime: true,
2402 'datetime-local': true,
2403 email: true,
2404 month: true,
2405 number: true,
2406 password: true,
2407 range: true,
2408 search: true,
2409 tel: true,
2410 text: true,
2411 time: true,
2412 url: true,
2413 week: true
2414};
2415
2416function isTextInputElement(elem) {
2417 var nodeName = elem && elem.nodeName && elem.nodeName.toLowerCase();
2418
2419 if (nodeName === 'input') {
2420 return !!supportedInputTypes[elem.type];
2421 }
2422
2423 if (nodeName === 'textarea') {
2424 return true;
2425 }
2426
2427 return false;
2428}
2429
2430/**
2431 * HTML nodeType values that represent the type of the node
2432 */
2433
2434var ELEMENT_NODE = 1;
2435var TEXT_NODE = 3;
2436var COMMENT_NODE = 8;
2437var DOCUMENT_NODE = 9;
2438var DOCUMENT_FRAGMENT_NODE = 11;
2439
2440/**
2441 * Gets the target node from a native browser event by accounting for
2442 * inconsistencies in browser DOM APIs.
2443 *
2444 * @param {object} nativeEvent Native browser event.
2445 * @return {DOMEventTarget} Target node.
2446 */
2447function getEventTarget(nativeEvent) {
2448 // Fallback to nativeEvent.srcElement for IE9
2449 // https://github.com/facebook/react/issues/12506
2450 var target = nativeEvent.target || nativeEvent.srcElement || window;
2451
2452 // Normalize SVG <use> element events #4963
2453 if (target.correspondingUseElement) {
2454 target = target.correspondingUseElement;
2455 }
2456
2457 // Safari may fire events on text nodes (Node.TEXT_NODE is 3).
2458 // @see http://www.quirksmode.org/js/events_properties.html
2459 return target.nodeType === TEXT_NODE ? target.parentNode : target;
2460}
2461
2462/**
2463 * Checks if an event is supported in the current execution environment.
2464 *
2465 * NOTE: This will not work correctly for non-generic events such as `change`,
2466 * `reset`, `load`, `error`, and `select`.
2467 *
2468 * Borrows from Modernizr.
2469 *
2470 * @param {string} eventNameSuffix Event name, e.g. "click".
2471 * @return {boolean} True if the event is supported.
2472 * @internal
2473 * @license Modernizr 3.0.0pre (Custom Build) | MIT
2474 */
2475function isEventSupported(eventNameSuffix) {
2476 if (!canUseDOM) {
2477 return false;
2478 }
2479
2480 var eventName = 'on' + eventNameSuffix;
2481 var isSupported = eventName in document;
2482
2483 if (!isSupported) {
2484 var element = document.createElement('div');
2485 element.setAttribute(eventName, 'return;');
2486 isSupported = typeof element[eventName] === 'function';
2487 }
2488
2489 return isSupported;
2490}
2491
2492function isCheckable(elem) {
2493 var type = elem.type;
2494 var nodeName = elem.nodeName;
2495 return nodeName && nodeName.toLowerCase() === 'input' && (type === 'checkbox' || type === 'radio');
2496}
2497
2498function getTracker(node) {
2499 return node._valueTracker;
2500}
2501
2502function detachTracker(node) {
2503 node._valueTracker = null;
2504}
2505
2506function getValueFromNode(node) {
2507 var value = '';
2508 if (!node) {
2509 return value;
2510 }
2511
2512 if (isCheckable(node)) {
2513 value = node.checked ? 'true' : 'false';
2514 } else {
2515 value = node.value;
2516 }
2517
2518 return value;
2519}
2520
2521function trackValueOnNode(node) {
2522 var valueField = isCheckable(node) ? 'checked' : 'value';
2523 var descriptor = Object.getOwnPropertyDescriptor(node.constructor.prototype, valueField);
2524
2525 var currentValue = '' + node[valueField];
2526
2527 // if someone has already defined a value or Safari, then bail
2528 // and don't track value will cause over reporting of changes,
2529 // but it's better then a hard failure
2530 // (needed for certain tests that spyOn input values and Safari)
2531 if (node.hasOwnProperty(valueField) || typeof descriptor === 'undefined' || typeof descriptor.get !== 'function' || typeof descriptor.set !== 'function') {
2532 return;
2533 }
2534 var get = descriptor.get,
2535 set = descriptor.set;
2536
2537 Object.defineProperty(node, valueField, {
2538 configurable: true,
2539 get: function () {
2540 return get.call(this);
2541 },
2542 set: function (value) {
2543 currentValue = '' + value;
2544 set.call(this, value);
2545 }
2546 });
2547 // We could've passed this the first time
2548 // but it triggers a bug in IE11 and Edge 14/15.
2549 // Calling defineProperty() again should be equivalent.
2550 // https://github.com/facebook/react/issues/11768
2551 Object.defineProperty(node, valueField, {
2552 enumerable: descriptor.enumerable
2553 });
2554
2555 var tracker = {
2556 getValue: function () {
2557 return currentValue;
2558 },
2559 setValue: function (value) {
2560 currentValue = '' + value;
2561 },
2562 stopTracking: function () {
2563 detachTracker(node);
2564 delete node[valueField];
2565 }
2566 };
2567 return tracker;
2568}
2569
2570function track(node) {
2571 if (getTracker(node)) {
2572 return;
2573 }
2574
2575 // TODO: Once it's just Fiber we can move this to node._wrapperState
2576 node._valueTracker = trackValueOnNode(node);
2577}
2578
2579function updateValueIfChanged(node) {
2580 if (!node) {
2581 return false;
2582 }
2583
2584 var tracker = getTracker(node);
2585 // if there is no tracker at this point it's unlikely
2586 // that trying again will succeed
2587 if (!tracker) {
2588 return true;
2589 }
2590
2591 var lastValue = tracker.getValue();
2592 var nextValue = getValueFromNode(node);
2593 if (nextValue !== lastValue) {
2594 tracker.setValue(nextValue);
2595 return true;
2596 }
2597 return false;
2598}
2599
2600var ReactSharedInternals = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
2601
2602// Prevent newer renderers from RTE when used with older react package versions.
2603// Current owner and dispatcher used to share the same ref,
2604// but PR #14548 split them out to better support the react-debug-tools package.
2605if (!ReactSharedInternals.hasOwnProperty('ReactCurrentDispatcher')) {
2606 ReactSharedInternals.ReactCurrentDispatcher = {
2607 current: null
2608 };
2609}
2610if (!ReactSharedInternals.hasOwnProperty('ReactCurrentBatchConfig')) {
2611 ReactSharedInternals.ReactCurrentBatchConfig = {
2612 suspense: null
2613 };
2614}
2615
2616var BEFORE_SLASH_RE = /^(.*)[\\\/]/;
2617
2618var describeComponentFrame = function (name, source, ownerName) {
2619 var sourceInfo = '';
2620 if (source) {
2621 var path = source.fileName;
2622 var fileName = path.replace(BEFORE_SLASH_RE, '');
2623 {
2624 // In DEV, include code for a common special case:
2625 // prefer "folder/index.js" instead of just "index.js".
2626 if (/^index\./.test(fileName)) {
2627 var match = path.match(BEFORE_SLASH_RE);
2628 if (match) {
2629 var pathBeforeSlash = match[1];
2630 if (pathBeforeSlash) {
2631 var folderName = pathBeforeSlash.replace(BEFORE_SLASH_RE, '');
2632 fileName = folderName + '/' + fileName;
2633 }
2634 }
2635 }
2636 }
2637 sourceInfo = ' (at ' + fileName + ':' + source.lineNumber + ')';
2638 } else if (ownerName) {
2639 sourceInfo = ' (created by ' + ownerName + ')';
2640 }
2641 return '\n in ' + (name || 'Unknown') + sourceInfo;
2642};
2643
2644// The Symbol used to tag the ReactElement-like types. If there is no native Symbol
2645// nor polyfill, then a plain number is used for performance.
2646var hasSymbol = typeof Symbol === 'function' && Symbol.for;
2647
2648var REACT_ELEMENT_TYPE = hasSymbol ? Symbol.for('react.element') : 0xeac7;
2649var REACT_PORTAL_TYPE = hasSymbol ? Symbol.for('react.portal') : 0xeaca;
2650var REACT_FRAGMENT_TYPE = hasSymbol ? Symbol.for('react.fragment') : 0xeacb;
2651var REACT_STRICT_MODE_TYPE = hasSymbol ? Symbol.for('react.strict_mode') : 0xeacc;
2652var REACT_PROFILER_TYPE = hasSymbol ? Symbol.for('react.profiler') : 0xead2;
2653var REACT_PROVIDER_TYPE = hasSymbol ? Symbol.for('react.provider') : 0xeacd;
2654var REACT_CONTEXT_TYPE = hasSymbol ? Symbol.for('react.context') : 0xeace;
2655// TODO: We don't use AsyncMode or ConcurrentMode anymore. They were temporary
2656// (unstable) APIs that have been removed. Can we remove the symbols?
2657
2658var REACT_CONCURRENT_MODE_TYPE = hasSymbol ? Symbol.for('react.concurrent_mode') : 0xeacf;
2659var REACT_FORWARD_REF_TYPE = hasSymbol ? Symbol.for('react.forward_ref') : 0xead0;
2660var REACT_SUSPENSE_TYPE = hasSymbol ? Symbol.for('react.suspense') : 0xead1;
2661var REACT_SUSPENSE_LIST_TYPE = hasSymbol ? Symbol.for('react.suspense_list') : 0xead8;
2662var REACT_MEMO_TYPE = hasSymbol ? Symbol.for('react.memo') : 0xead3;
2663var REACT_LAZY_TYPE = hasSymbol ? Symbol.for('react.lazy') : 0xead4;
2664var REACT_FUNDAMENTAL_TYPE = hasSymbol ? Symbol.for('react.fundamental') : 0xead5;
2665var REACT_RESPONDER_TYPE = hasSymbol ? Symbol.for('react.responder') : 0xead6;
2666
2667var MAYBE_ITERATOR_SYMBOL = typeof Symbol === 'function' && Symbol.iterator;
2668var FAUX_ITERATOR_SYMBOL = '@@iterator';
2669
2670function getIteratorFn(maybeIterable) {
2671 if (maybeIterable === null || typeof maybeIterable !== 'object') {
2672 return null;
2673 }
2674 var maybeIterator = MAYBE_ITERATOR_SYMBOL && maybeIterable[MAYBE_ITERATOR_SYMBOL] || maybeIterable[FAUX_ITERATOR_SYMBOL];
2675 if (typeof maybeIterator === 'function') {
2676 return maybeIterator;
2677 }
2678 return null;
2679}
2680
2681var Pending = 0;
2682var Resolved = 1;
2683var Rejected = 2;
2684
2685function refineResolvedLazyComponent(lazyComponent) {
2686 return lazyComponent._status === Resolved ? lazyComponent._result : null;
2687}
2688
2689function getWrappedName(outerType, innerType, wrapperName) {
2690 var functionName = innerType.displayName || innerType.name || '';
2691 return outerType.displayName || (functionName !== '' ? wrapperName + '(' + functionName + ')' : wrapperName);
2692}
2693
2694function getComponentName(type) {
2695 if (type == null) {
2696 // Host root, text node or just invalid type.
2697 return null;
2698 }
2699 {
2700 if (typeof type.tag === 'number') {
2701 warningWithoutStack$1(false, 'Received an unexpected object in getComponentName(). ' + 'This is likely a bug in React. Please file an issue.');
2702 }
2703 }
2704 if (typeof type === 'function') {
2705 return type.displayName || type.name || null;
2706 }
2707 if (typeof type === 'string') {
2708 return type;
2709 }
2710 switch (type) {
2711 case REACT_FRAGMENT_TYPE:
2712 return 'Fragment';
2713 case REACT_PORTAL_TYPE:
2714 return 'Portal';
2715 case REACT_PROFILER_TYPE:
2716 return 'Profiler';
2717 case REACT_STRICT_MODE_TYPE:
2718 return 'StrictMode';
2719 case REACT_SUSPENSE_TYPE:
2720 return 'Suspense';
2721 case REACT_SUSPENSE_LIST_TYPE:
2722 return 'SuspenseList';
2723 }
2724 if (typeof type === 'object') {
2725 switch (type.$$typeof) {
2726 case REACT_CONTEXT_TYPE:
2727 return 'Context.Consumer';
2728 case REACT_PROVIDER_TYPE:
2729 return 'Context.Provider';
2730 case REACT_FORWARD_REF_TYPE:
2731 return getWrappedName(type, type.render, 'ForwardRef');
2732 case REACT_MEMO_TYPE:
2733 return getComponentName(type.type);
2734 case REACT_LAZY_TYPE:
2735 {
2736 var thenable = type;
2737 var resolvedThenable = refineResolvedLazyComponent(thenable);
2738 if (resolvedThenable) {
2739 return getComponentName(resolvedThenable);
2740 }
2741 break;
2742 }
2743 }
2744 }
2745 return null;
2746}
2747
2748var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame;
2749
2750function describeFiber(fiber) {
2751 switch (fiber.tag) {
2752 case HostRoot:
2753 case HostPortal:
2754 case HostText:
2755 case Fragment:
2756 case ContextProvider:
2757 case ContextConsumer:
2758 return '';
2759 default:
2760 var owner = fiber._debugOwner;
2761 var source = fiber._debugSource;
2762 var name = getComponentName(fiber.type);
2763 var ownerName = null;
2764 if (owner) {
2765 ownerName = getComponentName(owner.type);
2766 }
2767 return describeComponentFrame(name, source, ownerName);
2768 }
2769}
2770
2771function getStackByFiberInDevAndProd(workInProgress) {
2772 var info = '';
2773 var node = workInProgress;
2774 do {
2775 info += describeFiber(node);
2776 node = node.return;
2777 } while (node);
2778 return info;
2779}
2780
2781var current = null;
2782var phase = null;
2783
2784function getCurrentFiberOwnerNameInDevOrNull() {
2785 {
2786 if (current === null) {
2787 return null;
2788 }
2789 var owner = current._debugOwner;
2790 if (owner !== null && typeof owner !== 'undefined') {
2791 return getComponentName(owner.type);
2792 }
2793 }
2794 return null;
2795}
2796
2797function getCurrentFiberStackInDev() {
2798 {
2799 if (current === null) {
2800 return '';
2801 }
2802 // Safe because if current fiber exists, we are reconciling,
2803 // and it is guaranteed to be the work-in-progress version.
2804 return getStackByFiberInDevAndProd(current);
2805 }
2806 return '';
2807}
2808
2809function resetCurrentFiber() {
2810 {
2811 ReactDebugCurrentFrame.getCurrentStack = null;
2812 current = null;
2813 phase = null;
2814 }
2815}
2816
2817function setCurrentFiber(fiber) {
2818 {
2819 ReactDebugCurrentFrame.getCurrentStack = getCurrentFiberStackInDev;
2820 current = fiber;
2821 phase = null;
2822 }
2823}
2824
2825function setCurrentPhase(lifeCyclePhase) {
2826 {
2827 phase = lifeCyclePhase;
2828 }
2829}
2830
2831/**
2832 * Similar to invariant but only logs a warning if the condition is not met.
2833 * This can be used to log issues in development environments in critical
2834 * paths. Removing the logging code for production environments will keep the
2835 * same logic and follow the same code paths.
2836 */
2837
2838var warning = warningWithoutStack$1;
2839
2840{
2841 warning = function (condition, format) {
2842 if (condition) {
2843 return;
2844 }
2845 var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame;
2846 var stack = ReactDebugCurrentFrame.getStackAddendum();
2847 // eslint-disable-next-line react-internal/warning-and-invariant-args
2848
2849 for (var _len = arguments.length, args = Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) {
2850 args[_key - 2] = arguments[_key];
2851 }
2852
2853 warningWithoutStack$1.apply(undefined, [false, format + '%s'].concat(args, [stack]));
2854 };
2855}
2856
2857var warning$1 = warning;
2858
2859// A reserved attribute.
2860// It is handled by React separately and shouldn't be written to the DOM.
2861var RESERVED = 0;
2862
2863// A simple string attribute.
2864// Attributes that aren't in the whitelist are presumed to have this type.
2865var STRING = 1;
2866
2867// A string attribute that accepts booleans in React. In HTML, these are called
2868// "enumerated" attributes with "true" and "false" as possible values.
2869// When true, it should be set to a "true" string.
2870// When false, it should be set to a "false" string.
2871var BOOLEANISH_STRING = 2;
2872
2873// A real boolean attribute.
2874// When true, it should be present (set either to an empty string or its name).
2875// When false, it should be omitted.
2876var BOOLEAN = 3;
2877
2878// An attribute that can be used as a flag as well as with a value.
2879// When true, it should be present (set either to an empty string or its name).
2880// When false, it should be omitted.
2881// For any other value, should be present with that value.
2882var OVERLOADED_BOOLEAN = 4;
2883
2884// An attribute that must be numeric or parse as a numeric.
2885// When falsy, it should be removed.
2886var NUMERIC = 5;
2887
2888// An attribute that must be positive numeric or parse as a positive numeric.
2889// When falsy, it should be removed.
2890var POSITIVE_NUMERIC = 6;
2891
2892/* eslint-disable max-len */
2893var 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';
2894/* eslint-enable max-len */
2895var ATTRIBUTE_NAME_CHAR = ATTRIBUTE_NAME_START_CHAR + '\\-.0-9\\u00B7\\u0300-\\u036F\\u203F-\\u2040';
2896
2897
2898var ROOT_ATTRIBUTE_NAME = 'data-reactroot';
2899var VALID_ATTRIBUTE_NAME_REGEX = new RegExp('^[' + ATTRIBUTE_NAME_START_CHAR + '][' + ATTRIBUTE_NAME_CHAR + ']*$');
2900
2901var hasOwnProperty = Object.prototype.hasOwnProperty;
2902var illegalAttributeNameCache = {};
2903var validatedAttributeNameCache = {};
2904
2905function isAttributeNameSafe(attributeName) {
2906 if (hasOwnProperty.call(validatedAttributeNameCache, attributeName)) {
2907 return true;
2908 }
2909 if (hasOwnProperty.call(illegalAttributeNameCache, attributeName)) {
2910 return false;
2911 }
2912 if (VALID_ATTRIBUTE_NAME_REGEX.test(attributeName)) {
2913 validatedAttributeNameCache[attributeName] = true;
2914 return true;
2915 }
2916 illegalAttributeNameCache[attributeName] = true;
2917 {
2918 warning$1(false, 'Invalid attribute name: `%s`', attributeName);
2919 }
2920 return false;
2921}
2922
2923function shouldIgnoreAttribute(name, propertyInfo, isCustomComponentTag) {
2924 if (propertyInfo !== null) {
2925 return propertyInfo.type === RESERVED;
2926 }
2927 if (isCustomComponentTag) {
2928 return false;
2929 }
2930 if (name.length > 2 && (name[0] === 'o' || name[0] === 'O') && (name[1] === 'n' || name[1] === 'N')) {
2931 return true;
2932 }
2933 return false;
2934}
2935
2936function shouldRemoveAttributeWithWarning(name, value, propertyInfo, isCustomComponentTag) {
2937 if (propertyInfo !== null && propertyInfo.type === RESERVED) {
2938 return false;
2939 }
2940 switch (typeof value) {
2941 case 'function':
2942 // $FlowIssue symbol is perfectly valid here
2943 case 'symbol':
2944 // eslint-disable-line
2945 return true;
2946 case 'boolean':
2947 {
2948 if (isCustomComponentTag) {
2949 return false;
2950 }
2951 if (propertyInfo !== null) {
2952 return !propertyInfo.acceptsBooleans;
2953 } else {
2954 var prefix = name.toLowerCase().slice(0, 5);
2955 return prefix !== 'data-' && prefix !== 'aria-';
2956 }
2957 }
2958 default:
2959 return false;
2960 }
2961}
2962
2963function shouldRemoveAttribute(name, value, propertyInfo, isCustomComponentTag) {
2964 if (value === null || typeof value === 'undefined') {
2965 return true;
2966 }
2967 if (shouldRemoveAttributeWithWarning(name, value, propertyInfo, isCustomComponentTag)) {
2968 return true;
2969 }
2970 if (isCustomComponentTag) {
2971 return false;
2972 }
2973 if (propertyInfo !== null) {
2974 switch (propertyInfo.type) {
2975 case BOOLEAN:
2976 return !value;
2977 case OVERLOADED_BOOLEAN:
2978 return value === false;
2979 case NUMERIC:
2980 return isNaN(value);
2981 case POSITIVE_NUMERIC:
2982 return isNaN(value) || value < 1;
2983 }
2984 }
2985 return false;
2986}
2987
2988function getPropertyInfo(name) {
2989 return properties.hasOwnProperty(name) ? properties[name] : null;
2990}
2991
2992function PropertyInfoRecord(name, type, mustUseProperty, attributeName, attributeNamespace, sanitizeURL) {
2993 this.acceptsBooleans = type === BOOLEANISH_STRING || type === BOOLEAN || type === OVERLOADED_BOOLEAN;
2994 this.attributeName = attributeName;
2995 this.attributeNamespace = attributeNamespace;
2996 this.mustUseProperty = mustUseProperty;
2997 this.propertyName = name;
2998 this.type = type;
2999 this.sanitizeURL = sanitizeURL;
3000}
3001
3002// When adding attributes to this list, be sure to also add them to
3003// the `possibleStandardNames` module to ensure casing and incorrect
3004// name warnings.
3005var properties = {};
3006
3007// These props are reserved by React. They shouldn't be written to the DOM.
3008['children', 'dangerouslySetInnerHTML',
3009// TODO: This prevents the assignment of defaultValue to regular
3010// elements (not just inputs). Now that ReactDOMInput assigns to the
3011// defaultValue property -- do we need this?
3012'defaultValue', 'defaultChecked', 'innerHTML', 'suppressContentEditableWarning', 'suppressHydrationWarning', 'style'].forEach(function (name) {
3013 properties[name] = new PropertyInfoRecord(name, RESERVED, false, // mustUseProperty
3014 name, // attributeName
3015 null, // attributeNamespace
3016 false);
3017} // sanitizeURL
3018);
3019
3020// A few React string attributes have a different name.
3021// This is a mapping from React prop names to the attribute names.
3022[['acceptCharset', 'accept-charset'], ['className', 'class'], ['htmlFor', 'for'], ['httpEquiv', 'http-equiv']].forEach(function (_ref) {
3023 var name = _ref[0],
3024 attributeName = _ref[1];
3025
3026 properties[name] = new PropertyInfoRecord(name, STRING, false, // mustUseProperty
3027 attributeName, // attributeName
3028 null, // attributeNamespace
3029 false);
3030} // sanitizeURL
3031);
3032
3033// These are "enumerated" HTML attributes that accept "true" and "false".
3034// In React, we let users pass `true` and `false` even though technically
3035// these aren't boolean attributes (they are coerced to strings).
3036['contentEditable', 'draggable', 'spellCheck', 'value'].forEach(function (name) {
3037 properties[name] = new PropertyInfoRecord(name, BOOLEANISH_STRING, false, // mustUseProperty
3038 name.toLowerCase(), // attributeName
3039 null, // attributeNamespace
3040 false);
3041} // sanitizeURL
3042);
3043
3044// These are "enumerated" SVG attributes that accept "true" and "false".
3045// In React, we let users pass `true` and `false` even though technically
3046// these aren't boolean attributes (they are coerced to strings).
3047// Since these are SVG attributes, their attribute names are case-sensitive.
3048['autoReverse', 'externalResourcesRequired', 'focusable', 'preserveAlpha'].forEach(function (name) {
3049 properties[name] = new PropertyInfoRecord(name, BOOLEANISH_STRING, false, // mustUseProperty
3050 name, // attributeName
3051 null, // attributeNamespace
3052 false);
3053} // sanitizeURL
3054);
3055
3056// These are HTML boolean attributes.
3057['allowFullScreen', 'async',
3058// Note: there is a special case that prevents it from being written to the DOM
3059// on the client side because the browsers are inconsistent. Instead we call focus().
3060'autoFocus', 'autoPlay', 'controls', 'default', 'defer', 'disabled', 'disablePictureInPicture', 'formNoValidate', 'hidden', 'loop', 'noModule', 'noValidate', 'open', 'playsInline', 'readOnly', 'required', 'reversed', 'scoped', 'seamless',
3061// Microdata
3062'itemScope'].forEach(function (name) {
3063 properties[name] = new PropertyInfoRecord(name, BOOLEAN, false, // mustUseProperty
3064 name.toLowerCase(), // attributeName
3065 null, // attributeNamespace
3066 false);
3067} // sanitizeURL
3068);
3069
3070// These are the few React props that we set as DOM properties
3071// rather than attributes. These are all booleans.
3072['checked',
3073// Note: `option.selected` is not updated if `select.multiple` is
3074// disabled with `removeAttribute`. We have special logic for handling this.
3075'multiple', 'muted', 'selected'].forEach(function (name) {
3076 properties[name] = new PropertyInfoRecord(name, BOOLEAN, true, // mustUseProperty
3077 name, // attributeName
3078 null, // attributeNamespace
3079 false);
3080} // sanitizeURL
3081);
3082
3083// These are HTML attributes that are "overloaded booleans": they behave like
3084// booleans, but can also accept a string value.
3085['capture', 'download'].forEach(function (name) {
3086 properties[name] = new PropertyInfoRecord(name, OVERLOADED_BOOLEAN, false, // mustUseProperty
3087 name, // attributeName
3088 null, // attributeNamespace
3089 false);
3090} // sanitizeURL
3091);
3092
3093// These are HTML attributes that must be positive numbers.
3094['cols', 'rows', 'size', 'span'].forEach(function (name) {
3095 properties[name] = new PropertyInfoRecord(name, POSITIVE_NUMERIC, false, // mustUseProperty
3096 name, // attributeName
3097 null, // attributeNamespace
3098 false);
3099} // sanitizeURL
3100);
3101
3102// These are HTML attributes that must be numbers.
3103['rowSpan', 'start'].forEach(function (name) {
3104 properties[name] = new PropertyInfoRecord(name, NUMERIC, false, // mustUseProperty
3105 name.toLowerCase(), // attributeName
3106 null, // attributeNamespace
3107 false);
3108} // sanitizeURL
3109);
3110
3111var CAMELIZE = /[\-\:]([a-z])/g;
3112var capitalize = function (token) {
3113 return token[1].toUpperCase();
3114};
3115
3116// This is a list of all SVG attributes that need special casing, namespacing,
3117// or boolean value assignment. Regular attributes that just accept strings
3118// and have the same names are omitted, just like in the HTML whitelist.
3119// Some of these attributes can be hard to find. This list was created by
3120// scrapping the MDN documentation.
3121['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) {
3122 var name = attributeName.replace(CAMELIZE, capitalize);
3123 properties[name] = new PropertyInfoRecord(name, STRING, false, // mustUseProperty
3124 attributeName, null, // attributeNamespace
3125 false);
3126} // sanitizeURL
3127);
3128
3129// String SVG attributes with the xlink namespace.
3130['xlink:actuate', 'xlink:arcrole', 'xlink:role', 'xlink:show', 'xlink:title', 'xlink:type'].forEach(function (attributeName) {
3131 var name = attributeName.replace(CAMELIZE, capitalize);
3132 properties[name] = new PropertyInfoRecord(name, STRING, false, // mustUseProperty
3133 attributeName, 'http://www.w3.org/1999/xlink', false);
3134} // sanitizeURL
3135);
3136
3137// String SVG attributes with the xml namespace.
3138['xml:base', 'xml:lang', 'xml:space'].forEach(function (attributeName) {
3139 var name = attributeName.replace(CAMELIZE, capitalize);
3140 properties[name] = new PropertyInfoRecord(name, STRING, false, // mustUseProperty
3141 attributeName, 'http://www.w3.org/XML/1998/namespace', false);
3142} // sanitizeURL
3143);
3144
3145// These attribute exists both in HTML and SVG.
3146// The attribute name is case-sensitive in SVG so we can't just use
3147// the React name like we do for attributes that exist only in HTML.
3148['tabIndex', 'crossOrigin'].forEach(function (attributeName) {
3149 properties[attributeName] = new PropertyInfoRecord(attributeName, STRING, false, // mustUseProperty
3150 attributeName.toLowerCase(), // attributeName
3151 null, // attributeNamespace
3152 false);
3153} // sanitizeURL
3154);
3155
3156// These attributes accept URLs. These must not allow javascript: URLS.
3157// These will also need to accept Trusted Types object in the future.
3158var xlinkHref = 'xlinkHref';
3159properties[xlinkHref] = new PropertyInfoRecord('xlinkHref', STRING, false, // mustUseProperty
3160'xlink:href', 'http://www.w3.org/1999/xlink', true);
3161
3162['src', 'href', 'action', 'formAction'].forEach(function (attributeName) {
3163 properties[attributeName] = new PropertyInfoRecord(attributeName, STRING, false, // mustUseProperty
3164 attributeName.toLowerCase(), // attributeName
3165 null, // attributeNamespace
3166 true);
3167} // sanitizeURL
3168);
3169
3170var ReactDebugCurrentFrame$1 = null;
3171{
3172 ReactDebugCurrentFrame$1 = ReactSharedInternals.ReactDebugCurrentFrame;
3173}
3174
3175// A javascript: URL can contain leading C0 control or \u0020 SPACE,
3176// and any newline or tab are filtered out as if they're not part of the URL.
3177// https://url.spec.whatwg.org/#url-parsing
3178// Tab or newline are defined as \r\n\t:
3179// https://infra.spec.whatwg.org/#ascii-tab-or-newline
3180// A C0 control is a code point in the range \u0000 NULL to \u001F
3181// INFORMATION SEPARATOR ONE, inclusive:
3182// https://infra.spec.whatwg.org/#c0-control-or-space
3183
3184/* eslint-disable max-len */
3185var isJavaScriptProtocol = /^[\u0000-\u001F ]*j[\r\n\t]*a[\r\n\t]*v[\r\n\t]*a[\r\n\t]*s[\r\n\t]*c[\r\n\t]*r[\r\n\t]*i[\r\n\t]*p[\r\n\t]*t[\r\n\t]*\:/i;
3186
3187var didWarn = false;
3188
3189function sanitizeURL(url) {
3190 if (disableJavaScriptURLs) {
3191 (function () {
3192 if (!!isJavaScriptProtocol.test(url)) {
3193 {
3194 throw ReactError(Error('React has blocked a javascript: URL as a security precaution.' + (ReactDebugCurrentFrame$1.getStackAddendum())));
3195 }
3196 }
3197 })();
3198 } else if (true && !didWarn && isJavaScriptProtocol.test(url)) {
3199 didWarn = true;
3200 warning$1(false, 'A future version of React will block javascript: URLs as a security precaution. ' + 'Use event handlers instead if you can. If you need to generate unsafe HTML try ' + 'using dangerouslySetInnerHTML instead. React was passed %s.', JSON.stringify(url));
3201 }
3202}
3203
3204/**
3205 * Get the value for a property on a node. Only used in DEV for SSR validation.
3206 * The "expected" argument is used as a hint of what the expected value is.
3207 * Some properties have multiple equivalent values.
3208 */
3209function getValueForProperty(node, name, expected, propertyInfo) {
3210 {
3211 if (propertyInfo.mustUseProperty) {
3212 var propertyName = propertyInfo.propertyName;
3213
3214 return node[propertyName];
3215 } else {
3216 if (!disableJavaScriptURLs && propertyInfo.sanitizeURL) {
3217 // If we haven't fully disabled javascript: URLs, and if
3218 // the hydration is successful of a javascript: URL, we
3219 // still want to warn on the client.
3220 sanitizeURL('' + expected);
3221 }
3222
3223 var attributeName = propertyInfo.attributeName;
3224
3225 var stringValue = null;
3226
3227 if (propertyInfo.type === OVERLOADED_BOOLEAN) {
3228 if (node.hasAttribute(attributeName)) {
3229 var value = node.getAttribute(attributeName);
3230 if (value === '') {
3231 return true;
3232 }
3233 if (shouldRemoveAttribute(name, expected, propertyInfo, false)) {
3234 return value;
3235 }
3236 if (value === '' + expected) {
3237 return expected;
3238 }
3239 return value;
3240 }
3241 } else if (node.hasAttribute(attributeName)) {
3242 if (shouldRemoveAttribute(name, expected, propertyInfo, false)) {
3243 // We had an attribute but shouldn't have had one, so read it
3244 // for the error message.
3245 return node.getAttribute(attributeName);
3246 }
3247 if (propertyInfo.type === BOOLEAN) {
3248 // If this was a boolean, it doesn't matter what the value is
3249 // the fact that we have it is the same as the expected.
3250 return expected;
3251 }
3252 // Even if this property uses a namespace we use getAttribute
3253 // because we assume its namespaced name is the same as our config.
3254 // To use getAttributeNS we need the local name which we don't have
3255 // in our config atm.
3256 stringValue = node.getAttribute(attributeName);
3257 }
3258
3259 if (shouldRemoveAttribute(name, expected, propertyInfo, false)) {
3260 return stringValue === null ? expected : stringValue;
3261 } else if (stringValue === '' + expected) {
3262 return expected;
3263 } else {
3264 return stringValue;
3265 }
3266 }
3267 }
3268}
3269
3270/**
3271 * Get the value for a attribute on a node. Only used in DEV for SSR validation.
3272 * The third argument is used as a hint of what the expected value is. Some
3273 * attributes have multiple equivalent values.
3274 */
3275function getValueForAttribute(node, name, expected) {
3276 {
3277 if (!isAttributeNameSafe(name)) {
3278 return;
3279 }
3280 if (!node.hasAttribute(name)) {
3281 return expected === undefined ? undefined : null;
3282 }
3283 var value = node.getAttribute(name);
3284 if (value === '' + expected) {
3285 return expected;
3286 }
3287 return value;
3288 }
3289}
3290
3291/**
3292 * Sets the value for a property on a node.
3293 *
3294 * @param {DOMElement} node
3295 * @param {string} name
3296 * @param {*} value
3297 */
3298function setValueForProperty(node, name, value, isCustomComponentTag) {
3299 var propertyInfo = getPropertyInfo(name);
3300 if (shouldIgnoreAttribute(name, propertyInfo, isCustomComponentTag)) {
3301 return;
3302 }
3303 if (shouldRemoveAttribute(name, value, propertyInfo, isCustomComponentTag)) {
3304 value = null;
3305 }
3306 // If the prop isn't in the special list, treat it as a simple attribute.
3307 if (isCustomComponentTag || propertyInfo === null) {
3308 if (isAttributeNameSafe(name)) {
3309 var _attributeName = name;
3310 if (value === null) {
3311 node.removeAttribute(_attributeName);
3312 } else {
3313 node.setAttribute(_attributeName, '' + value);
3314 }
3315 }
3316 return;
3317 }
3318 var mustUseProperty = propertyInfo.mustUseProperty;
3319
3320 if (mustUseProperty) {
3321 var propertyName = propertyInfo.propertyName;
3322
3323 if (value === null) {
3324 var type = propertyInfo.type;
3325
3326 node[propertyName] = type === BOOLEAN ? false : '';
3327 } else {
3328 // Contrary to `setAttribute`, object properties are properly
3329 // `toString`ed by IE8/9.
3330 node[propertyName] = value;
3331 }
3332 return;
3333 }
3334 // The rest are treated as attributes with special cases.
3335 var attributeName = propertyInfo.attributeName,
3336 attributeNamespace = propertyInfo.attributeNamespace;
3337
3338 if (value === null) {
3339 node.removeAttribute(attributeName);
3340 } else {
3341 var _type = propertyInfo.type;
3342
3343 var attributeValue = void 0;
3344 if (_type === BOOLEAN || _type === OVERLOADED_BOOLEAN && value === true) {
3345 attributeValue = '';
3346 } else {
3347 // `setAttribute` with objects becomes only `[object]` in IE8/9,
3348 // ('' + value) makes it output the correct toString()-value.
3349 attributeValue = '' + value;
3350 if (propertyInfo.sanitizeURL) {
3351 sanitizeURL(attributeValue);
3352 }
3353 }
3354 if (attributeNamespace) {
3355 node.setAttributeNS(attributeNamespace, attributeName, attributeValue);
3356 } else {
3357 node.setAttribute(attributeName, attributeValue);
3358 }
3359 }
3360}
3361
3362// Flow does not allow string concatenation of most non-string types. To work
3363// around this limitation, we use an opaque type that can only be obtained by
3364// passing the value through getToStringValue first.
3365function toString(value) {
3366 return '' + value;
3367}
3368
3369function getToStringValue(value) {
3370 switch (typeof value) {
3371 case 'boolean':
3372 case 'number':
3373 case 'object':
3374 case 'string':
3375 case 'undefined':
3376 return value;
3377 default:
3378 // function, symbol are assigned as empty strings
3379 return '';
3380 }
3381}
3382
3383var ReactDebugCurrentFrame$2 = null;
3384
3385var ReactControlledValuePropTypes = {
3386 checkPropTypes: null
3387};
3388
3389{
3390 ReactDebugCurrentFrame$2 = ReactSharedInternals.ReactDebugCurrentFrame;
3391
3392 var hasReadOnlyValue = {
3393 button: true,
3394 checkbox: true,
3395 image: true,
3396 hidden: true,
3397 radio: true,
3398 reset: true,
3399 submit: true
3400 };
3401
3402 var propTypes = {
3403 value: function (props, propName, componentName) {
3404 if (hasReadOnlyValue[props.type] || props.onChange || props.readOnly || props.disabled || props[propName] == null || enableFlareAPI && props.listeners) {
3405 return null;
3406 }
3407 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`.');
3408 },
3409 checked: function (props, propName, componentName) {
3410 if (props.onChange || props.readOnly || props.disabled || props[propName] == null || enableFlareAPI && props.listeners) {
3411 return null;
3412 }
3413 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`.');
3414 }
3415 };
3416
3417 /**
3418 * Provide a linked `value` attribute for controlled forms. You should not use
3419 * this outside of the ReactDOM controlled form components.
3420 */
3421 ReactControlledValuePropTypes.checkPropTypes = function (tagName, props) {
3422 checkPropTypes(propTypes, props, 'prop', tagName, ReactDebugCurrentFrame$2.getStackAddendum);
3423 };
3424}
3425
3426// TODO: direct imports like some-package/src/* are bad. Fix me.
3427var didWarnValueDefaultValue = false;
3428var didWarnCheckedDefaultChecked = false;
3429var didWarnControlledToUncontrolled = false;
3430var didWarnUncontrolledToControlled = false;
3431
3432function isControlled(props) {
3433 var usesChecked = props.type === 'checkbox' || props.type === 'radio';
3434 return usesChecked ? props.checked != null : props.value != null;
3435}
3436
3437/**
3438 * Implements an <input> host component that allows setting these optional
3439 * props: `checked`, `value`, `defaultChecked`, and `defaultValue`.
3440 *
3441 * If `checked` or `value` are not supplied (or null/undefined), user actions
3442 * that affect the checked state or value will trigger updates to the element.
3443 *
3444 * If they are supplied (and not null/undefined), the rendered element will not
3445 * trigger updates to the element. Instead, the props must change in order for
3446 * the rendered element to be updated.
3447 *
3448 * The rendered element will be initialized as unchecked (or `defaultChecked`)
3449 * with an empty value (or `defaultValue`).
3450 *
3451 * See http://www.w3.org/TR/2012/WD-html5-20121025/the-input-element.html
3452 */
3453
3454function getHostProps(element, props) {
3455 var node = element;
3456 var checked = props.checked;
3457
3458 var hostProps = _assign({}, props, {
3459 defaultChecked: undefined,
3460 defaultValue: undefined,
3461 value: undefined,
3462 checked: checked != null ? checked : node._wrapperState.initialChecked
3463 });
3464
3465 return hostProps;
3466}
3467
3468function initWrapperState(element, props) {
3469 {
3470 ReactControlledValuePropTypes.checkPropTypes('input', props);
3471
3472 if (props.checked !== undefined && props.defaultChecked !== undefined && !didWarnCheckedDefaultChecked) {
3473 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);
3474 didWarnCheckedDefaultChecked = true;
3475 }
3476 if (props.value !== undefined && props.defaultValue !== undefined && !didWarnValueDefaultValue) {
3477 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);
3478 didWarnValueDefaultValue = true;
3479 }
3480 }
3481
3482 var node = element;
3483 var defaultValue = props.defaultValue == null ? '' : props.defaultValue;
3484
3485 node._wrapperState = {
3486 initialChecked: props.checked != null ? props.checked : props.defaultChecked,
3487 initialValue: getToStringValue(props.value != null ? props.value : defaultValue),
3488 controlled: isControlled(props)
3489 };
3490}
3491
3492function updateChecked(element, props) {
3493 var node = element;
3494 var checked = props.checked;
3495 if (checked != null) {
3496 setValueForProperty(node, 'checked', checked, false);
3497 }
3498}
3499
3500function updateWrapper(element, props) {
3501 var node = element;
3502 {
3503 var _controlled = isControlled(props);
3504
3505 if (!node._wrapperState.controlled && _controlled && !didWarnUncontrolledToControlled) {
3506 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);
3507 didWarnUncontrolledToControlled = true;
3508 }
3509 if (node._wrapperState.controlled && !_controlled && !didWarnControlledToUncontrolled) {
3510 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);
3511 didWarnControlledToUncontrolled = true;
3512 }
3513 }
3514
3515 updateChecked(element, props);
3516
3517 var value = getToStringValue(props.value);
3518 var type = props.type;
3519
3520 if (value != null) {
3521 if (type === 'number') {
3522 if (value === 0 && node.value === '' ||
3523 // We explicitly want to coerce to number here if possible.
3524 // eslint-disable-next-line
3525 node.value != value) {
3526 node.value = toString(value);
3527 }
3528 } else if (node.value !== toString(value)) {
3529 node.value = toString(value);
3530 }
3531 } else if (type === 'submit' || type === 'reset') {
3532 // Submit/reset inputs need the attribute removed completely to avoid
3533 // blank-text buttons.
3534 node.removeAttribute('value');
3535 return;
3536 }
3537
3538 if (disableInputAttributeSyncing) {
3539 // When not syncing the value attribute, React only assigns a new value
3540 // whenever the defaultValue React prop has changed. When not present,
3541 // React does nothing
3542 if (props.hasOwnProperty('defaultValue')) {
3543 setDefaultValue(node, props.type, getToStringValue(props.defaultValue));
3544 }
3545 } else {
3546 // When syncing the value attribute, the value comes from a cascade of
3547 // properties:
3548 // 1. The value React property
3549 // 2. The defaultValue React property
3550 // 3. Otherwise there should be no change
3551 if (props.hasOwnProperty('value')) {
3552 setDefaultValue(node, props.type, value);
3553 } else if (props.hasOwnProperty('defaultValue')) {
3554 setDefaultValue(node, props.type, getToStringValue(props.defaultValue));
3555 }
3556 }
3557
3558 if (disableInputAttributeSyncing) {
3559 // When not syncing the checked attribute, the attribute is directly
3560 // controllable from the defaultValue React property. It needs to be
3561 // updated as new props come in.
3562 if (props.defaultChecked == null) {
3563 node.removeAttribute('checked');
3564 } else {
3565 node.defaultChecked = !!props.defaultChecked;
3566 }
3567 } else {
3568 // When syncing the checked attribute, it only changes when it needs
3569 // to be removed, such as transitioning from a checkbox into a text input
3570 if (props.checked == null && props.defaultChecked != null) {
3571 node.defaultChecked = !!props.defaultChecked;
3572 }
3573 }
3574}
3575
3576function postMountWrapper(element, props, isHydrating) {
3577 var node = element;
3578
3579 // Do not assign value if it is already set. This prevents user text input
3580 // from being lost during SSR hydration.
3581 if (props.hasOwnProperty('value') || props.hasOwnProperty('defaultValue')) {
3582 var type = props.type;
3583 var isButton = type === 'submit' || type === 'reset';
3584
3585 // Avoid setting value attribute on submit/reset inputs as it overrides the
3586 // default value provided by the browser. See: #12872
3587 if (isButton && (props.value === undefined || props.value === null)) {
3588 return;
3589 }
3590
3591 var _initialValue = toString(node._wrapperState.initialValue);
3592
3593 // Do not assign value if it is already set. This prevents user text input
3594 // from being lost during SSR hydration.
3595 if (!isHydrating) {
3596 if (disableInputAttributeSyncing) {
3597 var value = getToStringValue(props.value);
3598
3599 // When not syncing the value attribute, the value property points
3600 // directly to the React prop. Only assign it if it exists.
3601 if (value != null) {
3602 // Always assign on buttons so that it is possible to assign an
3603 // empty string to clear button text.
3604 //
3605 // Otherwise, do not re-assign the value property if is empty. This
3606 // potentially avoids a DOM write and prevents Firefox (~60.0.1) from
3607 // prematurely marking required inputs as invalid. Equality is compared
3608 // to the current value in case the browser provided value is not an
3609 // empty string.
3610 if (isButton || value !== node.value) {
3611 node.value = toString(value);
3612 }
3613 }
3614 } else {
3615 // When syncing the value attribute, the value property should use
3616 // the wrapperState._initialValue property. This uses:
3617 //
3618 // 1. The value React property when present
3619 // 2. The defaultValue React property when present
3620 // 3. An empty string
3621 if (_initialValue !== node.value) {
3622 node.value = _initialValue;
3623 }
3624 }
3625 }
3626
3627 if (disableInputAttributeSyncing) {
3628 // When not syncing the value attribute, assign the value attribute
3629 // directly from the defaultValue React property (when present)
3630 var defaultValue = getToStringValue(props.defaultValue);
3631 if (defaultValue != null) {
3632 node.defaultValue = toString(defaultValue);
3633 }
3634 } else {
3635 // Otherwise, the value attribute is synchronized to the property,
3636 // so we assign defaultValue to the same thing as the value property
3637 // assignment step above.
3638 node.defaultValue = _initialValue;
3639 }
3640 }
3641
3642 // Normally, we'd just do `node.checked = node.checked` upon initial mount, less this bug
3643 // this is needed to work around a chrome bug where setting defaultChecked
3644 // will sometimes influence the value of checked (even after detachment).
3645 // Reference: https://bugs.chromium.org/p/chromium/issues/detail?id=608416
3646 // We need to temporarily unset name to avoid disrupting radio button groups.
3647 var name = node.name;
3648 if (name !== '') {
3649 node.name = '';
3650 }
3651
3652 if (disableInputAttributeSyncing) {
3653 // When not syncing the checked attribute, the checked property
3654 // never gets assigned. It must be manually set. We don't want
3655 // to do this when hydrating so that existing user input isn't
3656 // modified
3657 if (!isHydrating) {
3658 updateChecked(element, props);
3659 }
3660
3661 // Only assign the checked attribute if it is defined. This saves
3662 // a DOM write when controlling the checked attribute isn't needed
3663 // (text inputs, submit/reset)
3664 if (props.hasOwnProperty('defaultChecked')) {
3665 node.defaultChecked = !node.defaultChecked;
3666 node.defaultChecked = !!props.defaultChecked;
3667 }
3668 } else {
3669 // When syncing the checked attribute, both the checked property and
3670 // attribute are assigned at the same time using defaultChecked. This uses:
3671 //
3672 // 1. The checked React property when present
3673 // 2. The defaultChecked React property when present
3674 // 3. Otherwise, false
3675 node.defaultChecked = !node.defaultChecked;
3676 node.defaultChecked = !!node._wrapperState.initialChecked;
3677 }
3678
3679 if (name !== '') {
3680 node.name = name;
3681 }
3682}
3683
3684function restoreControlledState(element, props) {
3685 var node = element;
3686 updateWrapper(node, props);
3687 updateNamedCousins(node, props);
3688}
3689
3690function updateNamedCousins(rootNode, props) {
3691 var name = props.name;
3692 if (props.type === 'radio' && name != null) {
3693 var queryRoot = rootNode;
3694
3695 while (queryRoot.parentNode) {
3696 queryRoot = queryRoot.parentNode;
3697 }
3698
3699 // If `rootNode.form` was non-null, then we could try `form.elements`,
3700 // but that sometimes behaves strangely in IE8. We could also try using
3701 // `form.getElementsByName`, but that will only return direct children
3702 // and won't include inputs that use the HTML5 `form=` attribute. Since
3703 // the input might not even be in a form. It might not even be in the
3704 // document. Let's just use the local `querySelectorAll` to ensure we don't
3705 // miss anything.
3706 var group = queryRoot.querySelectorAll('input[name=' + JSON.stringify('' + name) + '][type="radio"]');
3707
3708 for (var i = 0; i < group.length; i++) {
3709 var otherNode = group[i];
3710 if (otherNode === rootNode || otherNode.form !== rootNode.form) {
3711 continue;
3712 }
3713 // This will throw if radio buttons rendered by different copies of React
3714 // and the same name are rendered into the same form (same as #1939).
3715 // That's probably okay; we don't support it just as we don't support
3716 // mixing React radio buttons with non-React ones.
3717 var otherProps = getFiberCurrentPropsFromNode$1(otherNode);
3718 (function () {
3719 if (!otherProps) {
3720 {
3721 throw ReactError(Error('ReactDOMInput: Mixing React and non-React radio inputs with the same `name` is not supported.'));
3722 }
3723 }
3724 })();
3725
3726 // We need update the tracked value on the named cousin since the value
3727 // was changed but the input saw no event or value set
3728 updateValueIfChanged(otherNode);
3729
3730 // If this is a controlled radio button group, forcing the input that
3731 // was previously checked to update will cause it to be come re-checked
3732 // as appropriate.
3733 updateWrapper(otherNode, otherProps);
3734 }
3735 }
3736}
3737
3738// In Chrome, assigning defaultValue to certain input types triggers input validation.
3739// For number inputs, the display value loses trailing decimal points. For email inputs,
3740// Chrome raises "The specified value <x> is not a valid email address".
3741//
3742// Here we check to see if the defaultValue has actually changed, avoiding these problems
3743// when the user is inputting text
3744//
3745// https://github.com/facebook/react/issues/7253
3746function setDefaultValue(node, type, value) {
3747 if (
3748 // Focused number inputs synchronize on blur. See ChangeEventPlugin.js
3749 type !== 'number' || node.ownerDocument.activeElement !== node) {
3750 if (value == null) {
3751 node.defaultValue = toString(node._wrapperState.initialValue);
3752 } else if (node.defaultValue !== toString(value)) {
3753 node.defaultValue = toString(value);
3754 }
3755 }
3756}
3757
3758var eventTypes$1 = {
3759 change: {
3760 phasedRegistrationNames: {
3761 bubbled: 'onChange',
3762 captured: 'onChangeCapture'
3763 },
3764 dependencies: [TOP_BLUR, TOP_CHANGE, TOP_CLICK, TOP_FOCUS, TOP_INPUT, TOP_KEY_DOWN, TOP_KEY_UP, TOP_SELECTION_CHANGE]
3765 }
3766};
3767
3768function createAndAccumulateChangeEvent(inst, nativeEvent, target) {
3769 var event = SyntheticEvent.getPooled(eventTypes$1.change, inst, nativeEvent, target);
3770 event.type = 'change';
3771 // Flag this event loop as needing state restore.
3772 enqueueStateRestore(target);
3773 accumulateTwoPhaseDispatches(event);
3774 return event;
3775}
3776/**
3777 * For IE shims
3778 */
3779var activeElement = null;
3780var activeElementInst = null;
3781
3782/**
3783 * SECTION: handle `change` event
3784 */
3785function shouldUseChangeEvent(elem) {
3786 var nodeName = elem.nodeName && elem.nodeName.toLowerCase();
3787 return nodeName === 'select' || nodeName === 'input' && elem.type === 'file';
3788}
3789
3790function manualDispatchChangeEvent(nativeEvent) {
3791 var event = createAndAccumulateChangeEvent(activeElementInst, nativeEvent, getEventTarget(nativeEvent));
3792
3793 // If change and propertychange bubbled, we'd just bind to it like all the
3794 // other events and have it go through ReactBrowserEventEmitter. Since it
3795 // doesn't, we manually listen for the events and so we have to enqueue and
3796 // process the abstract event manually.
3797 //
3798 // Batching is necessary here in order to ensure that all event handlers run
3799 // before the next rerender (including event handlers attached to ancestor
3800 // elements instead of directly on the input). Without this, controlled
3801 // components don't work properly in conjunction with event bubbling because
3802 // the component is rerendered and the value reverted before all the event
3803 // handlers can run. See https://github.com/facebook/react/issues/708.
3804 batchedUpdates(runEventInBatch, event);
3805}
3806
3807function runEventInBatch(event) {
3808 runEventsInBatch(event);
3809}
3810
3811function getInstIfValueChanged(targetInst) {
3812 var targetNode = getNodeFromInstance$1(targetInst);
3813 if (updateValueIfChanged(targetNode)) {
3814 return targetInst;
3815 }
3816}
3817
3818function getTargetInstForChangeEvent(topLevelType, targetInst) {
3819 if (topLevelType === TOP_CHANGE) {
3820 return targetInst;
3821 }
3822}
3823
3824/**
3825 * SECTION: handle `input` event
3826 */
3827var isInputEventSupported = false;
3828if (canUseDOM) {
3829 // IE9 claims to support the input event but fails to trigger it when
3830 // deleting text, so we ignore its input events.
3831 isInputEventSupported = isEventSupported('input') && (!document.documentMode || document.documentMode > 9);
3832}
3833
3834/**
3835 * (For IE <=9) Starts tracking propertychange events on the passed-in element
3836 * and override the value property so that we can distinguish user events from
3837 * value changes in JS.
3838 */
3839function startWatchingForValueChange(target, targetInst) {
3840 activeElement = target;
3841 activeElementInst = targetInst;
3842 activeElement.attachEvent('onpropertychange', handlePropertyChange);
3843}
3844
3845/**
3846 * (For IE <=9) Removes the event listeners from the currently-tracked element,
3847 * if any exists.
3848 */
3849function stopWatchingForValueChange() {
3850 if (!activeElement) {
3851 return;
3852 }
3853 activeElement.detachEvent('onpropertychange', handlePropertyChange);
3854 activeElement = null;
3855 activeElementInst = null;
3856}
3857
3858/**
3859 * (For IE <=9) Handles a propertychange event, sending a `change` event if
3860 * the value of the active element has changed.
3861 */
3862function handlePropertyChange(nativeEvent) {
3863 if (nativeEvent.propertyName !== 'value') {
3864 return;
3865 }
3866 if (getInstIfValueChanged(activeElementInst)) {
3867 manualDispatchChangeEvent(nativeEvent);
3868 }
3869}
3870
3871function handleEventsForInputEventPolyfill(topLevelType, target, targetInst) {
3872 if (topLevelType === TOP_FOCUS) {
3873 // In IE9, propertychange fires for most input events but is buggy and
3874 // doesn't fire when text is deleted, but conveniently, selectionchange
3875 // appears to fire in all of the remaining cases so we catch those and
3876 // forward the event if the value has changed
3877 // In either case, we don't want to call the event handler if the value
3878 // is changed from JS so we redefine a setter for `.value` that updates
3879 // our activeElementValue variable, allowing us to ignore those changes
3880 //
3881 // stopWatching() should be a noop here but we call it just in case we
3882 // missed a blur event somehow.
3883 stopWatchingForValueChange();
3884 startWatchingForValueChange(target, targetInst);
3885 } else if (topLevelType === TOP_BLUR) {
3886 stopWatchingForValueChange();
3887 }
3888}
3889
3890// For IE8 and IE9.
3891function getTargetInstForInputEventPolyfill(topLevelType, targetInst) {
3892 if (topLevelType === TOP_SELECTION_CHANGE || topLevelType === TOP_KEY_UP || topLevelType === TOP_KEY_DOWN) {
3893 // On the selectionchange event, the target is just document which isn't
3894 // helpful for us so just check activeElement instead.
3895 //
3896 // 99% of the time, keydown and keyup aren't necessary. IE8 fails to fire
3897 // propertychange on the first input event after setting `value` from a
3898 // script and fires only keydown, keypress, keyup. Catching keyup usually
3899 // gets it and catching keydown lets us fire an event for the first
3900 // keystroke if user does a key repeat (it'll be a little delayed: right
3901 // before the second keystroke). Other input methods (e.g., paste) seem to
3902 // fire selectionchange normally.
3903 return getInstIfValueChanged(activeElementInst);
3904 }
3905}
3906
3907/**
3908 * SECTION: handle `click` event
3909 */
3910function shouldUseClickEvent(elem) {
3911 // Use the `click` event to detect changes to checkbox and radio inputs.
3912 // This approach works across all browsers, whereas `change` does not fire
3913 // until `blur` in IE8.
3914 var nodeName = elem.nodeName;
3915 return nodeName && nodeName.toLowerCase() === 'input' && (elem.type === 'checkbox' || elem.type === 'radio');
3916}
3917
3918function getTargetInstForClickEvent(topLevelType, targetInst) {
3919 if (topLevelType === TOP_CLICK) {
3920 return getInstIfValueChanged(targetInst);
3921 }
3922}
3923
3924function getTargetInstForInputOrChangeEvent(topLevelType, targetInst) {
3925 if (topLevelType === TOP_INPUT || topLevelType === TOP_CHANGE) {
3926 return getInstIfValueChanged(targetInst);
3927 }
3928}
3929
3930function handleControlledInputBlur(node) {
3931 var state = node._wrapperState;
3932
3933 if (!state || !state.controlled || node.type !== 'number') {
3934 return;
3935 }
3936
3937 if (!disableInputAttributeSyncing) {
3938 // If controlled, assign the value attribute to the current value on blur
3939 setDefaultValue(node, 'number', node.value);
3940 }
3941}
3942
3943/**
3944 * This plugin creates an `onChange` event that normalizes change events
3945 * across form elements. This event fires at a time when it's possible to
3946 * change the element's value without seeing a flicker.
3947 *
3948 * Supported elements are:
3949 * - input (see `isTextInputElement`)
3950 * - textarea
3951 * - select
3952 */
3953var ChangeEventPlugin = {
3954 eventTypes: eventTypes$1,
3955
3956 _isInputEventSupported: isInputEventSupported,
3957
3958 extractEvents: function (topLevelType, targetInst, nativeEvent, nativeEventTarget) {
3959 var targetNode = targetInst ? getNodeFromInstance$1(targetInst) : window;
3960
3961 var getTargetInstFunc = void 0,
3962 handleEventFunc = void 0;
3963 if (shouldUseChangeEvent(targetNode)) {
3964 getTargetInstFunc = getTargetInstForChangeEvent;
3965 } else if (isTextInputElement(targetNode)) {
3966 if (isInputEventSupported) {
3967 getTargetInstFunc = getTargetInstForInputOrChangeEvent;
3968 } else {
3969 getTargetInstFunc = getTargetInstForInputEventPolyfill;
3970 handleEventFunc = handleEventsForInputEventPolyfill;
3971 }
3972 } else if (shouldUseClickEvent(targetNode)) {
3973 getTargetInstFunc = getTargetInstForClickEvent;
3974 }
3975
3976 if (getTargetInstFunc) {
3977 var inst = getTargetInstFunc(topLevelType, targetInst);
3978 if (inst) {
3979 var event = createAndAccumulateChangeEvent(inst, nativeEvent, nativeEventTarget);
3980 return event;
3981 }
3982 }
3983
3984 if (handleEventFunc) {
3985 handleEventFunc(topLevelType, targetNode, targetInst);
3986 }
3987
3988 // When blurring, set the value attribute for number inputs
3989 if (topLevelType === TOP_BLUR) {
3990 handleControlledInputBlur(targetNode);
3991 }
3992 }
3993};
3994
3995/**
3996 * Module that is injectable into `EventPluginHub`, that specifies a
3997 * deterministic ordering of `EventPlugin`s. A convenient way to reason about
3998 * plugins, without having to package every one of them. This is better than
3999 * having plugins be ordered in the same order that they are injected because
4000 * that ordering would be influenced by the packaging order.
4001 * `ResponderEventPlugin` must occur before `SimpleEventPlugin` so that
4002 * preventing default on events is convenient in `SimpleEventPlugin` handlers.
4003 */
4004var DOMEventPluginOrder = ['ResponderEventPlugin', 'SimpleEventPlugin', 'EnterLeaveEventPlugin', 'ChangeEventPlugin', 'SelectEventPlugin', 'BeforeInputEventPlugin'];
4005
4006var SyntheticUIEvent = SyntheticEvent.extend({
4007 view: null,
4008 detail: null
4009});
4010
4011var modifierKeyToProp = {
4012 Alt: 'altKey',
4013 Control: 'ctrlKey',
4014 Meta: 'metaKey',
4015 Shift: 'shiftKey'
4016};
4017
4018// Older browsers (Safari <= 10, iOS Safari <= 10.2) do not support
4019// getModifierState. If getModifierState is not supported, we map it to a set of
4020// modifier keys exposed by the event. In this case, Lock-keys are not supported.
4021/**
4022 * Translation from modifier key to the associated property in the event.
4023 * @see http://www.w3.org/TR/DOM-Level-3-Events/#keys-Modifiers
4024 */
4025
4026function modifierStateGetter(keyArg) {
4027 var syntheticEvent = this;
4028 var nativeEvent = syntheticEvent.nativeEvent;
4029 if (nativeEvent.getModifierState) {
4030 return nativeEvent.getModifierState(keyArg);
4031 }
4032 var keyProp = modifierKeyToProp[keyArg];
4033 return keyProp ? !!nativeEvent[keyProp] : false;
4034}
4035
4036function getEventModifierState(nativeEvent) {
4037 return modifierStateGetter;
4038}
4039
4040var previousScreenX = 0;
4041var previousScreenY = 0;
4042// Use flags to signal movementX/Y has already been set
4043var isMovementXSet = false;
4044var isMovementYSet = false;
4045
4046/**
4047 * @interface MouseEvent
4048 * @see http://www.w3.org/TR/DOM-Level-3-Events/
4049 */
4050var SyntheticMouseEvent = SyntheticUIEvent.extend({
4051 screenX: null,
4052 screenY: null,
4053 clientX: null,
4054 clientY: null,
4055 pageX: null,
4056 pageY: null,
4057 ctrlKey: null,
4058 shiftKey: null,
4059 altKey: null,
4060 metaKey: null,
4061 getModifierState: getEventModifierState,
4062 button: null,
4063 buttons: null,
4064 relatedTarget: function (event) {
4065 return event.relatedTarget || (event.fromElement === event.srcElement ? event.toElement : event.fromElement);
4066 },
4067 movementX: function (event) {
4068 if ('movementX' in event) {
4069 return event.movementX;
4070 }
4071
4072 var screenX = previousScreenX;
4073 previousScreenX = event.screenX;
4074
4075 if (!isMovementXSet) {
4076 isMovementXSet = true;
4077 return 0;
4078 }
4079
4080 return event.type === 'mousemove' ? event.screenX - screenX : 0;
4081 },
4082 movementY: function (event) {
4083 if ('movementY' in event) {
4084 return event.movementY;
4085 }
4086
4087 var screenY = previousScreenY;
4088 previousScreenY = event.screenY;
4089
4090 if (!isMovementYSet) {
4091 isMovementYSet = true;
4092 return 0;
4093 }
4094
4095 return event.type === 'mousemove' ? event.screenY - screenY : 0;
4096 }
4097});
4098
4099/**
4100 * @interface PointerEvent
4101 * @see http://www.w3.org/TR/pointerevents/
4102 */
4103var SyntheticPointerEvent = SyntheticMouseEvent.extend({
4104 pointerId: null,
4105 width: null,
4106 height: null,
4107 pressure: null,
4108 tangentialPressure: null,
4109 tiltX: null,
4110 tiltY: null,
4111 twist: null,
4112 pointerType: null,
4113 isPrimary: null
4114});
4115
4116var eventTypes$2 = {
4117 mouseEnter: {
4118 registrationName: 'onMouseEnter',
4119 dependencies: [TOP_MOUSE_OUT, TOP_MOUSE_OVER]
4120 },
4121 mouseLeave: {
4122 registrationName: 'onMouseLeave',
4123 dependencies: [TOP_MOUSE_OUT, TOP_MOUSE_OVER]
4124 },
4125 pointerEnter: {
4126 registrationName: 'onPointerEnter',
4127 dependencies: [TOP_POINTER_OUT, TOP_POINTER_OVER]
4128 },
4129 pointerLeave: {
4130 registrationName: 'onPointerLeave',
4131 dependencies: [TOP_POINTER_OUT, TOP_POINTER_OVER]
4132 }
4133};
4134
4135var EnterLeaveEventPlugin = {
4136 eventTypes: eventTypes$2,
4137
4138 /**
4139 * For almost every interaction we care about, there will be both a top-level
4140 * `mouseover` and `mouseout` event that occurs. Only use `mouseout` so that
4141 * we do not extract duplicate events. However, moving the mouse into the
4142 * browser from outside will not fire a `mouseout` event. In this case, we use
4143 * the `mouseover` top-level event.
4144 */
4145 extractEvents: function (topLevelType, targetInst, nativeEvent, nativeEventTarget) {
4146 var isOverEvent = topLevelType === TOP_MOUSE_OVER || topLevelType === TOP_POINTER_OVER;
4147 var isOutEvent = topLevelType === TOP_MOUSE_OUT || topLevelType === TOP_POINTER_OUT;
4148
4149 if (isOverEvent && (nativeEvent.relatedTarget || nativeEvent.fromElement)) {
4150 return null;
4151 }
4152
4153 if (!isOutEvent && !isOverEvent) {
4154 // Must not be a mouse or pointer in or out - ignoring.
4155 return null;
4156 }
4157
4158 var win = void 0;
4159 if (nativeEventTarget.window === nativeEventTarget) {
4160 // `nativeEventTarget` is probably a window object.
4161 win = nativeEventTarget;
4162 } else {
4163 // TODO: Figure out why `ownerDocument` is sometimes undefined in IE8.
4164 var doc = nativeEventTarget.ownerDocument;
4165 if (doc) {
4166 win = doc.defaultView || doc.parentWindow;
4167 } else {
4168 win = window;
4169 }
4170 }
4171
4172 var from = void 0;
4173 var to = void 0;
4174 if (isOutEvent) {
4175 from = targetInst;
4176 var related = nativeEvent.relatedTarget || nativeEvent.toElement;
4177 to = related ? getClosestInstanceFromNode(related) : null;
4178 } else {
4179 // Moving to a node from outside the window.
4180 from = null;
4181 to = targetInst;
4182 }
4183
4184 if (from === to) {
4185 // Nothing pertains to our managed components.
4186 return null;
4187 }
4188
4189 var eventInterface = void 0,
4190 leaveEventType = void 0,
4191 enterEventType = void 0,
4192 eventTypePrefix = void 0;
4193
4194 if (topLevelType === TOP_MOUSE_OUT || topLevelType === TOP_MOUSE_OVER) {
4195 eventInterface = SyntheticMouseEvent;
4196 leaveEventType = eventTypes$2.mouseLeave;
4197 enterEventType = eventTypes$2.mouseEnter;
4198 eventTypePrefix = 'mouse';
4199 } else if (topLevelType === TOP_POINTER_OUT || topLevelType === TOP_POINTER_OVER) {
4200 eventInterface = SyntheticPointerEvent;
4201 leaveEventType = eventTypes$2.pointerLeave;
4202 enterEventType = eventTypes$2.pointerEnter;
4203 eventTypePrefix = 'pointer';
4204 }
4205
4206 var fromNode = from == null ? win : getNodeFromInstance$1(from);
4207 var toNode = to == null ? win : getNodeFromInstance$1(to);
4208
4209 var leave = eventInterface.getPooled(leaveEventType, from, nativeEvent, nativeEventTarget);
4210 leave.type = eventTypePrefix + 'leave';
4211 leave.target = fromNode;
4212 leave.relatedTarget = toNode;
4213
4214 var enter = eventInterface.getPooled(enterEventType, to, nativeEvent, nativeEventTarget);
4215 enter.type = eventTypePrefix + 'enter';
4216 enter.target = toNode;
4217 enter.relatedTarget = fromNode;
4218
4219 accumulateEnterLeaveDispatches(leave, enter, from, to);
4220
4221 return [leave, enter];
4222 }
4223};
4224
4225/**
4226 * inlined Object.is polyfill to avoid requiring consumers ship their own
4227 * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is
4228 */
4229function is(x, y) {
4230 return x === y && (x !== 0 || 1 / x === 1 / y) || x !== x && y !== y // eslint-disable-line no-self-compare
4231 ;
4232}
4233
4234var hasOwnProperty$1 = Object.prototype.hasOwnProperty;
4235
4236/**
4237 * Performs equality by iterating through keys on an object and returning false
4238 * when any key has values which are not strictly equal between the arguments.
4239 * Returns true when the values of all keys are strictly equal.
4240 */
4241function shallowEqual(objA, objB) {
4242 if (is(objA, objB)) {
4243 return true;
4244 }
4245
4246 if (typeof objA !== 'object' || objA === null || typeof objB !== 'object' || objB === null) {
4247 return false;
4248 }
4249
4250 var keysA = Object.keys(objA);
4251 var keysB = Object.keys(objB);
4252
4253 if (keysA.length !== keysB.length) {
4254 return false;
4255 }
4256
4257 // Test for A's keys different from B.
4258 for (var i = 0; i < keysA.length; i++) {
4259 if (!hasOwnProperty$1.call(objB, keysA[i]) || !is(objA[keysA[i]], objB[keysA[i]])) {
4260 return false;
4261 }
4262 }
4263
4264 return true;
4265}
4266
4267var PLUGIN_EVENT_SYSTEM = 1;
4268var RESPONDER_EVENT_SYSTEM = 1 << 1;
4269var IS_PASSIVE = 1 << 2;
4270var IS_ACTIVE = 1 << 3;
4271var PASSIVE_NOT_SUPPORTED = 1 << 4;
4272
4273function createResponderListener(responder, props) {
4274 var eventResponderListener = {
4275 responder: responder,
4276 props: props
4277 };
4278 {
4279 Object.freeze(eventResponderListener);
4280 }
4281 return eventResponderListener;
4282}
4283
4284function isFiberSuspenseAndTimedOut(fiber) {
4285 return fiber.tag === SuspenseComponent && fiber.memoizedState !== null;
4286}
4287
4288function getSuspenseFallbackChild(fiber) {
4289 return fiber.child.sibling.child;
4290}
4291
4292
4293
4294
4295
4296function createResponderInstance(responder, responderProps, responderState, target, fiber) {
4297 return {
4298 fiber: fiber,
4299 props: responderProps,
4300 responder: responder,
4301 rootEventTypes: null,
4302 state: responderState,
4303 target: target
4304 };
4305}
4306
4307var DiscreteEvent = 0;
4308var UserBlockingEvent = 1;
4309var ContinuousEvent = 2;
4310
4311// Intentionally not named imports because Rollup would use dynamic dispatch for
4312// CommonJS interop named imports.
4313var UserBlockingPriority$1 = Scheduler.unstable_UserBlockingPriority;
4314var runWithPriority$1 = Scheduler.unstable_runWithPriority;
4315
4316
4317var listenToResponderEventTypesImpl = void 0;
4318
4319function setListenToResponderEventTypes(_listenToResponderEventTypesImpl) {
4320 listenToResponderEventTypesImpl = _listenToResponderEventTypesImpl;
4321}
4322
4323var activeTimeouts = new Map();
4324var rootEventTypesToEventResponderInstances = new Map();
4325var ownershipChangeListeners = new Set();
4326
4327var globalOwner = null;
4328
4329var currentTimeStamp = 0;
4330var currentTimers = new Map();
4331var currentInstance = null;
4332var currentEventQueue = null;
4333var currentEventQueuePriority = ContinuousEvent;
4334var currentTimerIDCounter = 0;
4335var currentDocument = null;
4336
4337var eventResponderContext = {
4338 dispatchEvent: function (eventValue, eventListener, eventPriority) {
4339 validateResponderContext();
4340 validateEventValue(eventValue);
4341 if (eventPriority < currentEventQueuePriority) {
4342 currentEventQueuePriority = eventPriority;
4343 }
4344 currentEventQueue.push(createEventQueueItem(eventValue, eventListener));
4345 },
4346 isTargetWithinResponder: function (target) {
4347 validateResponderContext();
4348 if (target != null) {
4349 var fiber = getClosestInstanceFromNode(target);
4350 var responderFiber = currentInstance.fiber;
4351
4352 while (fiber !== null) {
4353 if (fiber === responderFiber || fiber.alternate === responderFiber) {
4354 return true;
4355 }
4356 fiber = fiber.return;
4357 }
4358 }
4359 return false;
4360 },
4361 isTargetWithinResponderScope: function (target) {
4362 validateResponderContext();
4363 var componentInstance = currentInstance;
4364 var responder = componentInstance.responder;
4365
4366 if (target != null) {
4367 var fiber = getClosestInstanceFromNode(target);
4368 var responderFiber = currentInstance.fiber;
4369
4370 while (fiber !== null) {
4371 if (fiber === responderFiber || fiber.alternate === responderFiber) {
4372 return true;
4373 }
4374 if (doesFiberHaveResponder(fiber, responder)) {
4375 return false;
4376 }
4377 fiber = fiber.return;
4378 }
4379 }
4380 return false;
4381 },
4382 isTargetWithinNode: function (childTarget, parentTarget) {
4383 validateResponderContext();
4384 var childFiber = getClosestInstanceFromNode(childTarget);
4385 var parentFiber = getClosestInstanceFromNode(parentTarget);
4386 var parentAlternateFiber = parentFiber.alternate;
4387
4388 var node = childFiber;
4389 while (node !== null) {
4390 if (node === parentFiber || node === parentAlternateFiber) {
4391 return true;
4392 }
4393 node = node.return;
4394 }
4395 return false;
4396 },
4397 addRootEventTypes: function (rootEventTypes) {
4398 validateResponderContext();
4399 var activeDocument = getActiveDocument();
4400 listenToResponderEventTypesImpl(rootEventTypes, activeDocument);
4401 for (var i = 0; i < rootEventTypes.length; i++) {
4402 var rootEventType = rootEventTypes[i];
4403 var eventResponderInstance = currentInstance;
4404 registerRootEventType(rootEventType, eventResponderInstance);
4405 }
4406 },
4407 removeRootEventTypes: function (rootEventTypes) {
4408 validateResponderContext();
4409 for (var i = 0; i < rootEventTypes.length; i++) {
4410 var rootEventType = rootEventTypes[i];
4411 var rootEventResponders = rootEventTypesToEventResponderInstances.get(rootEventType);
4412 var rootEventTypesSet = currentInstance.rootEventTypes;
4413 if (rootEventTypesSet !== null) {
4414 rootEventTypesSet.delete(rootEventType);
4415 }
4416 if (rootEventResponders !== undefined) {
4417 rootEventResponders.delete(currentInstance);
4418 }
4419 }
4420 },
4421 hasOwnership: function () {
4422 validateResponderContext();
4423 return globalOwner === currentInstance;
4424 },
4425 requestGlobalOwnership: function () {
4426 validateResponderContext();
4427 if (globalOwner !== null) {
4428 return false;
4429 }
4430 globalOwner = currentInstance;
4431 triggerOwnershipListeners();
4432 return true;
4433 },
4434 releaseOwnership: function () {
4435 validateResponderContext();
4436 return releaseOwnershipForEventResponderInstance(currentInstance);
4437 },
4438 setTimeout: function (func, delay) {
4439 validateResponderContext();
4440 if (currentTimers === null) {
4441 currentTimers = new Map();
4442 }
4443 var timeout = currentTimers.get(delay);
4444
4445 var timerId = currentTimerIDCounter++;
4446 if (timeout === undefined) {
4447 var _timers = new Map();
4448 var _id = setTimeout(function () {
4449 processTimers(_timers, delay);
4450 }, delay);
4451 timeout = {
4452 id: _id,
4453 timers: _timers
4454 };
4455 currentTimers.set(delay, timeout);
4456 }
4457 timeout.timers.set(timerId, {
4458 instance: currentInstance,
4459 func: func,
4460 id: timerId,
4461 timeStamp: currentTimeStamp
4462 });
4463 activeTimeouts.set(timerId, timeout);
4464 return timerId;
4465 },
4466 clearTimeout: function (timerId) {
4467 validateResponderContext();
4468 var timeout = activeTimeouts.get(timerId);
4469
4470 if (timeout !== undefined) {
4471 var _timers2 = timeout.timers;
4472 _timers2.delete(timerId);
4473 if (_timers2.size === 0) {
4474 clearTimeout(timeout.id);
4475 }
4476 }
4477 },
4478 getFocusableElementsInScope: function (deep) {
4479 validateResponderContext();
4480 var focusableElements = [];
4481 var eventResponderInstance = currentInstance;
4482 var currentResponder = eventResponderInstance.responder;
4483 var focusScopeFiber = eventResponderInstance.fiber;
4484 if (deep) {
4485 var deepNode = focusScopeFiber.return;
4486 while (deepNode !== null) {
4487 if (doesFiberHaveResponder(deepNode, currentResponder)) {
4488 focusScopeFiber = deepNode;
4489 }
4490 deepNode = deepNode.return;
4491 }
4492 }
4493 var child = focusScopeFiber.child;
4494
4495 if (child !== null) {
4496 collectFocusableElements(child, focusableElements);
4497 }
4498 return focusableElements;
4499 },
4500
4501 getActiveDocument: getActiveDocument,
4502 objectAssign: _assign,
4503 getTimeStamp: function () {
4504 validateResponderContext();
4505 return currentTimeStamp;
4506 },
4507 isTargetWithinHostComponent: function (target, elementType) {
4508 validateResponderContext();
4509 var fiber = getClosestInstanceFromNode(target);
4510
4511 while (fiber !== null) {
4512 if (fiber.tag === HostComponent && fiber.type === elementType) {
4513 return true;
4514 }
4515 fiber = fiber.return;
4516 }
4517 return false;
4518 },
4519
4520 enqueueStateRestore: enqueueStateRestore
4521};
4522
4523function validateEventValue(eventValue) {
4524 if (typeof eventValue === 'object' && eventValue !== null) {
4525 var target = eventValue.target,
4526 type = eventValue.type,
4527 _timeStamp = eventValue.timeStamp;
4528
4529
4530 if (target == null || type == null || _timeStamp == null) {
4531 throw new Error('context.dispatchEvent: "target", "timeStamp", and "type" fields on event object are required.');
4532 }
4533 var showWarning = function (name) {
4534 {
4535 warning$1(false, '%s is not available on event objects created from event responder modules (React Flare). ' + 'Try wrapping in a conditional, i.e. `if (event.type !== "press") { event.%s }`', name, name);
4536 }
4537 };
4538 eventValue.preventDefault = function () {
4539 {
4540 showWarning('preventDefault()');
4541 }
4542 };
4543 eventValue.stopPropagation = function () {
4544 {
4545 showWarning('stopPropagation()');
4546 }
4547 };
4548 eventValue.isDefaultPrevented = function () {
4549 {
4550 showWarning('isDefaultPrevented()');
4551 }
4552 };
4553 eventValue.isPropagationStopped = function () {
4554 {
4555 showWarning('isPropagationStopped()');
4556 }
4557 };
4558 // $FlowFixMe: we don't need value, Flow thinks we do
4559 Object.defineProperty(eventValue, 'nativeEvent', {
4560 get: function () {
4561 {
4562 showWarning('nativeEvent');
4563 }
4564 }
4565 });
4566 }
4567}
4568
4569function collectFocusableElements(node, focusableElements) {
4570 if (isFiberSuspenseAndTimedOut(node)) {
4571 var fallbackChild = getSuspenseFallbackChild(node);
4572 if (fallbackChild !== null) {
4573 collectFocusableElements(fallbackChild, focusableElements);
4574 }
4575 } else {
4576 if (isFiberHostComponentFocusable(node)) {
4577 focusableElements.push(node.stateNode);
4578 } else {
4579 var child = node.child;
4580
4581 if (child !== null) {
4582 collectFocusableElements(child, focusableElements);
4583 }
4584 }
4585 }
4586 var sibling = node.sibling;
4587
4588 if (sibling !== null) {
4589 collectFocusableElements(sibling, focusableElements);
4590 }
4591}
4592
4593function createEventQueueItem(value, listener) {
4594 return {
4595 value: value,
4596 listener: listener
4597 };
4598}
4599
4600function doesFiberHaveResponder(fiber, responder) {
4601 if (fiber.tag === HostComponent) {
4602 var dependencies = fiber.dependencies;
4603 if (dependencies !== null) {
4604 var respondersMap = dependencies.responders;
4605 if (respondersMap !== null && respondersMap.has(responder)) {
4606 return true;
4607 }
4608 }
4609 }
4610 return false;
4611}
4612
4613function getActiveDocument() {
4614 return currentDocument;
4615}
4616
4617function releaseOwnershipForEventResponderInstance(eventResponderInstance) {
4618 if (globalOwner === eventResponderInstance) {
4619 globalOwner = null;
4620 triggerOwnershipListeners();
4621 return true;
4622 }
4623 return false;
4624}
4625
4626function isFiberHostComponentFocusable(fiber) {
4627 if (fiber.tag !== HostComponent) {
4628 return false;
4629 }
4630 var type = fiber.type,
4631 memoizedProps = fiber.memoizedProps;
4632
4633 if (memoizedProps.tabIndex === -1 || memoizedProps.disabled) {
4634 return false;
4635 }
4636 if (memoizedProps.tabIndex === 0 || memoizedProps.contentEditable === true) {
4637 return true;
4638 }
4639 if (type === 'a' || type === 'area') {
4640 return !!memoizedProps.href && memoizedProps.rel !== 'ignore';
4641 }
4642 if (type === 'input') {
4643 return memoizedProps.type !== 'hidden' && memoizedProps.type !== 'file';
4644 }
4645 return type === 'button' || type === 'textarea' || type === 'object' || type === 'select' || type === 'iframe' || type === 'embed';
4646}
4647
4648function processTimers(timers, delay) {
4649 var timersArr = Array.from(timers.values());
4650 currentEventQueuePriority = ContinuousEvent;
4651 try {
4652 for (var i = 0; i < timersArr.length; i++) {
4653 var _timersArr$i = timersArr[i],
4654 _instance = _timersArr$i.instance,
4655 _func = _timersArr$i.func,
4656 _id2 = _timersArr$i.id,
4657 _timeStamp2 = _timersArr$i.timeStamp;
4658
4659 currentInstance = _instance;
4660 currentEventQueue = [];
4661 currentTimeStamp = _timeStamp2 + delay;
4662 try {
4663 _func();
4664 } finally {
4665 activeTimeouts.delete(_id2);
4666 }
4667 }
4668 processEventQueue();
4669 } finally {
4670 currentTimers = null;
4671 currentInstance = null;
4672 currentEventQueue = null;
4673 currentTimeStamp = 0;
4674 }
4675}
4676
4677function createDOMResponderEvent(topLevelType, nativeEvent, nativeEventTarget, passive, passiveSupported) {
4678 var _ref = nativeEvent,
4679 pointerType = _ref.pointerType;
4680
4681 var eventPointerType = '';
4682 var pointerId = null;
4683
4684 if (pointerType !== undefined) {
4685 eventPointerType = pointerType;
4686 pointerId = nativeEvent.pointerId;
4687 } else if (nativeEvent.key !== undefined) {
4688 eventPointerType = 'keyboard';
4689 } else if (nativeEvent.button !== undefined) {
4690 eventPointerType = 'mouse';
4691 } else if (nativeEvent.changedTouches !== undefined) {
4692 eventPointerType = 'touch';
4693 }
4694
4695 return {
4696 nativeEvent: nativeEvent,
4697 passive: passive,
4698 passiveSupported: passiveSupported,
4699 pointerId: pointerId,
4700 pointerType: eventPointerType,
4701 responderTarget: null,
4702 target: nativeEventTarget,
4703 type: topLevelType
4704 };
4705}
4706
4707function processEvents(eventQueue) {
4708 for (var i = 0, length = eventQueue.length; i < length; i++) {
4709 var _eventQueue$i = eventQueue[i],
4710 _value = _eventQueue$i.value,
4711 _listener = _eventQueue$i.listener;
4712
4713 var type = typeof _value === 'object' && _value !== null ? _value.type : '';
4714 invokeGuardedCallbackAndCatchFirstError(type, _listener, undefined, _value);
4715 }
4716}
4717
4718function processEventQueue() {
4719 var eventQueue = currentEventQueue;
4720 if (eventQueue.length === 0) {
4721 return;
4722 }
4723 switch (currentEventQueuePriority) {
4724 case DiscreteEvent:
4725 {
4726 flushDiscreteUpdatesIfNeeded(currentTimeStamp);
4727 discreteUpdates(function () {
4728 batchedEventUpdates(processEvents, eventQueue);
4729 });
4730 break;
4731 }
4732 case UserBlockingEvent:
4733 {
4734 if (enableUserBlockingEvents) {
4735 runWithPriority$1(UserBlockingPriority$1, batchedEventUpdates.bind(null, processEvents, eventQueue));
4736 } else {
4737 batchedEventUpdates(processEvents, eventQueue);
4738 }
4739 break;
4740 }
4741 case ContinuousEvent:
4742 {
4743 batchedEventUpdates(processEvents, eventQueue);
4744 break;
4745 }
4746 }
4747}
4748
4749function responderEventTypesContainType(eventTypes, type) {
4750 for (var i = 0, len = eventTypes.length; i < len; i++) {
4751 if (eventTypes[i] === type) {
4752 return true;
4753 }
4754 }
4755 return false;
4756}
4757
4758function validateResponderTargetEventTypes(eventType, responder) {
4759 var targetEventTypes = responder.targetEventTypes;
4760 // Validate the target event type exists on the responder
4761
4762 if (targetEventTypes !== null) {
4763 return responderEventTypesContainType(targetEventTypes, eventType);
4764 }
4765 return false;
4766}
4767
4768function validateOwnership(responderInstance) {
4769 return globalOwner === null || globalOwner === responderInstance;
4770}
4771
4772function traverseAndHandleEventResponderInstances(topLevelType, targetFiber, nativeEvent, nativeEventTarget, eventSystemFlags) {
4773 var isPassiveEvent = (eventSystemFlags & IS_PASSIVE) !== 0;
4774 var isPassiveSupported = (eventSystemFlags & PASSIVE_NOT_SUPPORTED) === 0;
4775 var isPassive = isPassiveEvent || !isPassiveSupported;
4776 var eventType = isPassive ? topLevelType : topLevelType + '_active';
4777
4778 // Trigger event responders in this order:
4779 // - Bubble target responder phase
4780 // - Root responder phase
4781
4782 var visitedResponders = new Set();
4783 var responderEvent = createDOMResponderEvent(topLevelType, nativeEvent, nativeEventTarget, isPassiveEvent, isPassiveSupported);
4784 var node = targetFiber;
4785 while (node !== null) {
4786 var _node = node,
4787 dependencies = _node.dependencies,
4788 tag = _node.tag;
4789
4790 if (tag === HostComponent && dependencies !== null) {
4791 var respondersMap = dependencies.responders;
4792 if (respondersMap !== null) {
4793 var responderInstances = Array.from(respondersMap.values());
4794 for (var i = 0, length = responderInstances.length; i < length; i++) {
4795 var responderInstance = responderInstances[i];
4796
4797 if (validateOwnership(responderInstance)) {
4798 var props = responderInstance.props,
4799 responder = responderInstance.responder,
4800 state = responderInstance.state,
4801 target = responderInstance.target;
4802
4803 if (!visitedResponders.has(responder) && validateResponderTargetEventTypes(eventType, responder)) {
4804 visitedResponders.add(responder);
4805 var onEvent = responder.onEvent;
4806 if (onEvent !== null) {
4807 currentInstance = responderInstance;
4808 responderEvent.responderTarget = target;
4809 onEvent(responderEvent, eventResponderContext, props, state);
4810 }
4811 }
4812 }
4813 }
4814 }
4815 }
4816 node = node.return;
4817 }
4818 // Root phase
4819 var rootEventResponderInstances = rootEventTypesToEventResponderInstances.get(eventType);
4820 if (rootEventResponderInstances !== undefined) {
4821 var _responderInstances = Array.from(rootEventResponderInstances);
4822
4823 for (var _i = 0; _i < _responderInstances.length; _i++) {
4824 var _responderInstance = _responderInstances[_i];
4825 if (!validateOwnership(_responderInstance)) {
4826 continue;
4827 }
4828 var _props = _responderInstance.props,
4829 _responder = _responderInstance.responder,
4830 _state = _responderInstance.state,
4831 _target = _responderInstance.target;
4832
4833 var onRootEvent = _responder.onRootEvent;
4834 if (onRootEvent !== null) {
4835 currentInstance = _responderInstance;
4836 responderEvent.responderTarget = _target;
4837 onRootEvent(responderEvent, eventResponderContext, _props, _state);
4838 }
4839 }
4840 }
4841}
4842
4843function triggerOwnershipListeners() {
4844 var listeningInstances = Array.from(ownershipChangeListeners);
4845 var previousInstance = currentInstance;
4846 var previousEventQueuePriority = currentEventQueuePriority;
4847 var previousEventQueue = currentEventQueue;
4848 try {
4849 for (var i = 0; i < listeningInstances.length; i++) {
4850 var _instance2 = listeningInstances[i];
4851 var props = _instance2.props,
4852 responder = _instance2.responder,
4853 state = _instance2.state;
4854
4855 currentInstance = _instance2;
4856 currentEventQueuePriority = ContinuousEvent;
4857 currentEventQueue = [];
4858 var onOwnershipChange = responder.onOwnershipChange;
4859 if (onOwnershipChange !== null) {
4860 onOwnershipChange(eventResponderContext, props, state);
4861 }
4862 }
4863 processEventQueue();
4864 } finally {
4865 currentInstance = previousInstance;
4866 currentEventQueue = previousEventQueue;
4867 currentEventQueuePriority = previousEventQueuePriority;
4868 }
4869}
4870
4871function mountEventResponder(responder, responderInstance, props, state) {
4872 if (responder.onOwnershipChange !== null) {
4873 ownershipChangeListeners.add(responderInstance);
4874 }
4875 var onMount = responder.onMount;
4876 if (onMount !== null) {
4877 currentEventQueuePriority = ContinuousEvent;
4878 currentInstance = responderInstance;
4879 currentEventQueue = [];
4880 try {
4881 onMount(eventResponderContext, props, state);
4882 processEventQueue();
4883 } finally {
4884 currentEventQueue = null;
4885 currentInstance = null;
4886 currentTimers = null;
4887 }
4888 }
4889}
4890
4891function unmountEventResponder(responderInstance) {
4892 var responder = responderInstance.responder;
4893 var onUnmount = responder.onUnmount;
4894 if (onUnmount !== null) {
4895 var props = responderInstance.props,
4896 state = responderInstance.state;
4897
4898 currentEventQueue = [];
4899 currentEventQueuePriority = ContinuousEvent;
4900 currentInstance = responderInstance;
4901 try {
4902 onUnmount(eventResponderContext, props, state);
4903 processEventQueue();
4904 } finally {
4905 currentEventQueue = null;
4906 currentInstance = null;
4907 currentTimers = null;
4908 }
4909 }
4910 releaseOwnershipForEventResponderInstance(responderInstance);
4911 if (responder.onOwnershipChange !== null) {
4912 ownershipChangeListeners.delete(responderInstance);
4913 }
4914 var rootEventTypesSet = responderInstance.rootEventTypes;
4915 if (rootEventTypesSet !== null) {
4916 var rootEventTypes = Array.from(rootEventTypesSet);
4917
4918 for (var i = 0; i < rootEventTypes.length; i++) {
4919 var topLevelEventType = rootEventTypes[i];
4920 var rootEventResponderInstances = rootEventTypesToEventResponderInstances.get(topLevelEventType);
4921 if (rootEventResponderInstances !== undefined) {
4922 rootEventResponderInstances.delete(responderInstance);
4923 }
4924 }
4925 }
4926}
4927
4928function validateResponderContext() {
4929 (function () {
4930 if (!(currentInstance !== null)) {
4931 {
4932 throw ReactError(Error('An event responder context was used outside of an event cycle. Use context.setTimeout() to use asynchronous responder context outside of event cycle .'));
4933 }
4934 }
4935 })();
4936}
4937
4938function dispatchEventForResponderEventSystem(topLevelType, targetFiber, nativeEvent, nativeEventTarget, eventSystemFlags) {
4939 if (enableFlareAPI) {
4940 var previousEventQueue = currentEventQueue;
4941 var previousInstance = currentInstance;
4942 var previousTimers = currentTimers;
4943 var previousTimeStamp = currentTimeStamp;
4944 var previousDocument = currentDocument;
4945 var previousEventQueuePriority = currentEventQueuePriority;
4946 currentTimers = null;
4947 currentEventQueue = [];
4948 currentEventQueuePriority = ContinuousEvent;
4949 // nodeType 9 is DOCUMENT_NODE
4950 currentDocument = nativeEventTarget.nodeType === 9 ? nativeEventTarget : nativeEventTarget.ownerDocument;
4951 // We might want to control timeStamp another way here
4952 currentTimeStamp = nativeEvent.timeStamp;
4953 try {
4954 traverseAndHandleEventResponderInstances(topLevelType, targetFiber, nativeEvent, nativeEventTarget, eventSystemFlags);
4955 processEventQueue();
4956 } finally {
4957 currentTimers = previousTimers;
4958 currentInstance = previousInstance;
4959 currentEventQueue = previousEventQueue;
4960 currentTimeStamp = previousTimeStamp;
4961 currentDocument = previousDocument;
4962 currentEventQueuePriority = previousEventQueuePriority;
4963 }
4964 }
4965}
4966
4967function addRootEventTypesForResponderInstance(responderInstance, rootEventTypes) {
4968 for (var i = 0; i < rootEventTypes.length; i++) {
4969 var rootEventType = rootEventTypes[i];
4970 registerRootEventType(rootEventType, responderInstance);
4971 }
4972}
4973
4974function registerRootEventType(rootEventType, eventResponderInstance) {
4975 var rootEventResponderInstances = rootEventTypesToEventResponderInstances.get(rootEventType);
4976 if (rootEventResponderInstances === undefined) {
4977 rootEventResponderInstances = new Set();
4978 rootEventTypesToEventResponderInstances.set(rootEventType, rootEventResponderInstances);
4979 }
4980 var rootEventTypesSet = eventResponderInstance.rootEventTypes;
4981 if (rootEventTypesSet === null) {
4982 rootEventTypesSet = eventResponderInstance.rootEventTypes = new Set();
4983 }
4984 (function () {
4985 if (!!rootEventTypesSet.has(rootEventType)) {
4986 {
4987 throw ReactError(Error('addRootEventTypes() found a duplicate root event type of "' + rootEventType + '". This might be because the event type exists in the event responder "rootEventTypes" array or because of a previous addRootEventTypes() using this root event type.'));
4988 }
4989 }
4990 })();
4991 rootEventTypesSet.add(rootEventType);
4992 rootEventResponderInstances.add(eventResponderInstance);
4993}
4994
4995/**
4996 * `ReactInstanceMap` maintains a mapping from a public facing stateful
4997 * instance (key) and the internal representation (value). This allows public
4998 * methods to accept the user facing instance as an argument and map them back
4999 * to internal methods.
5000 *
5001 * Note that this module is currently shared and assumed to be stateless.
5002 * If this becomes an actual Map, that will break.
5003 */
5004
5005/**
5006 * This API should be called `delete` but we'd have to make sure to always
5007 * transform these to strings for IE support. When this transform is fully
5008 * supported we can rename it.
5009 */
5010
5011
5012function get(key) {
5013 return key._reactInternalFiber;
5014}
5015
5016function has(key) {
5017 return key._reactInternalFiber !== undefined;
5018}
5019
5020function set(key, value) {
5021 key._reactInternalFiber = value;
5022}
5023
5024// Don't change these two values. They're used by React Dev Tools.
5025var NoEffect = /* */0;
5026var PerformedWork = /* */1;
5027
5028// You can change the rest (and add more).
5029var Placement = /* */2;
5030var Update = /* */4;
5031var PlacementAndUpdate = /* */6;
5032var Deletion = /* */8;
5033var ContentReset = /* */16;
5034var Callback = /* */32;
5035var DidCapture = /* */64;
5036var Ref = /* */128;
5037var Snapshot = /* */256;
5038var Passive = /* */512;
5039
5040// Passive & Update & Callback & Ref & Snapshot
5041var LifecycleEffectMask = /* */932;
5042
5043// Union of all host effects
5044var HostEffectMask = /* */1023;
5045
5046var Incomplete = /* */1024;
5047var ShouldCapture = /* */2048;
5048
5049var ReactCurrentOwner$1 = ReactSharedInternals.ReactCurrentOwner;
5050
5051var MOUNTING = 1;
5052var MOUNTED = 2;
5053var UNMOUNTED = 3;
5054
5055function isFiberMountedImpl(fiber) {
5056 var node = fiber;
5057 if (!fiber.alternate) {
5058 // If there is no alternate, this might be a new tree that isn't inserted
5059 // yet. If it is, then it will have a pending insertion effect on it.
5060 if ((node.effectTag & Placement) !== NoEffect) {
5061 return MOUNTING;
5062 }
5063 while (node.return) {
5064 node = node.return;
5065 if ((node.effectTag & Placement) !== NoEffect) {
5066 return MOUNTING;
5067 }
5068 }
5069 } else {
5070 while (node.return) {
5071 node = node.return;
5072 }
5073 }
5074 if (node.tag === HostRoot) {
5075 // TODO: Check if this was a nested HostRoot when used with
5076 // renderContainerIntoSubtree.
5077 return MOUNTED;
5078 }
5079 // If we didn't hit the root, that means that we're in an disconnected tree
5080 // that has been unmounted.
5081 return UNMOUNTED;
5082}
5083
5084function isFiberMounted(fiber) {
5085 return isFiberMountedImpl(fiber) === MOUNTED;
5086}
5087
5088function isMounted(component) {
5089 {
5090 var owner = ReactCurrentOwner$1.current;
5091 if (owner !== null && owner.tag === ClassComponent) {
5092 var ownerFiber = owner;
5093 var instance = ownerFiber.stateNode;
5094 !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;
5095 instance._warnedAboutRefsInRender = true;
5096 }
5097 }
5098
5099 var fiber = get(component);
5100 if (!fiber) {
5101 return false;
5102 }
5103 return isFiberMountedImpl(fiber) === MOUNTED;
5104}
5105
5106function assertIsMounted(fiber) {
5107 (function () {
5108 if (!(isFiberMountedImpl(fiber) === MOUNTED)) {
5109 {
5110 throw ReactError(Error('Unable to find node on an unmounted component.'));
5111 }
5112 }
5113 })();
5114}
5115
5116function findCurrentFiberUsingSlowPath(fiber) {
5117 var alternate = fiber.alternate;
5118 if (!alternate) {
5119 // If there is no alternate, then we only need to check if it is mounted.
5120 var state = isFiberMountedImpl(fiber);
5121 (function () {
5122 if (!(state !== UNMOUNTED)) {
5123 {
5124 throw ReactError(Error('Unable to find node on an unmounted component.'));
5125 }
5126 }
5127 })();
5128 if (state === MOUNTING) {
5129 return null;
5130 }
5131 return fiber;
5132 }
5133 // If we have two possible branches, we'll walk backwards up to the root
5134 // to see what path the root points to. On the way we may hit one of the
5135 // special cases and we'll deal with them.
5136 var a = fiber;
5137 var b = alternate;
5138 while (true) {
5139 var parentA = a.return;
5140 if (parentA === null) {
5141 // We're at the root.
5142 break;
5143 }
5144 var parentB = parentA.alternate;
5145 if (parentB === null) {
5146 // There is no alternate. This is an unusual case. Currently, it only
5147 // happens when a Suspense component is hidden. An extra fragment fiber
5148 // is inserted in between the Suspense fiber and its children. Skip
5149 // over this extra fragment fiber and proceed to the next parent.
5150 var nextParent = parentA.return;
5151 if (nextParent !== null) {
5152 a = b = nextParent;
5153 continue;
5154 }
5155 // If there's no parent, we're at the root.
5156 break;
5157 }
5158
5159 // If both copies of the parent fiber point to the same child, we can
5160 // assume that the child is current. This happens when we bailout on low
5161 // priority: the bailed out fiber's child reuses the current child.
5162 if (parentA.child === parentB.child) {
5163 var child = parentA.child;
5164 while (child) {
5165 if (child === a) {
5166 // We've determined that A is the current branch.
5167 assertIsMounted(parentA);
5168 return fiber;
5169 }
5170 if (child === b) {
5171 // We've determined that B is the current branch.
5172 assertIsMounted(parentA);
5173 return alternate;
5174 }
5175 child = child.sibling;
5176 }
5177 // We should never have an alternate for any mounting node. So the only
5178 // way this could possibly happen is if this was unmounted, if at all.
5179 (function () {
5180 {
5181 {
5182 throw ReactError(Error('Unable to find node on an unmounted component.'));
5183 }
5184 }
5185 })();
5186 }
5187
5188 if (a.return !== b.return) {
5189 // The return pointer of A and the return pointer of B point to different
5190 // fibers. We assume that return pointers never criss-cross, so A must
5191 // belong to the child set of A.return, and B must belong to the child
5192 // set of B.return.
5193 a = parentA;
5194 b = parentB;
5195 } else {
5196 // The return pointers point to the same fiber. We'll have to use the
5197 // default, slow path: scan the child sets of each parent alternate to see
5198 // which child belongs to which set.
5199 //
5200 // Search parent A's child set
5201 var didFindChild = false;
5202 var _child = parentA.child;
5203 while (_child) {
5204 if (_child === a) {
5205 didFindChild = true;
5206 a = parentA;
5207 b = parentB;
5208 break;
5209 }
5210 if (_child === b) {
5211 didFindChild = true;
5212 b = parentA;
5213 a = parentB;
5214 break;
5215 }
5216 _child = _child.sibling;
5217 }
5218 if (!didFindChild) {
5219 // Search parent B's child set
5220 _child = parentB.child;
5221 while (_child) {
5222 if (_child === a) {
5223 didFindChild = true;
5224 a = parentB;
5225 b = parentA;
5226 break;
5227 }
5228 if (_child === b) {
5229 didFindChild = true;
5230 b = parentB;
5231 a = parentA;
5232 break;
5233 }
5234 _child = _child.sibling;
5235 }
5236 (function () {
5237 if (!didFindChild) {
5238 {
5239 throw ReactError(Error('Child was not found in either parent set. This indicates a bug in React related to the return pointer. Please file an issue.'));
5240 }
5241 }
5242 })();
5243 }
5244 }
5245
5246 (function () {
5247 if (!(a.alternate === b)) {
5248 {
5249 throw ReactError(Error('Return fibers should always be each others\' alternates. This error is likely caused by a bug in React. Please file an issue.'));
5250 }
5251 }
5252 })();
5253 }
5254 // If the root is not a host container, we're in a disconnected tree. I.e.
5255 // unmounted.
5256 (function () {
5257 if (!(a.tag === HostRoot)) {
5258 {
5259 throw ReactError(Error('Unable to find node on an unmounted component.'));
5260 }
5261 }
5262 })();
5263 if (a.stateNode.current === a) {
5264 // We've determined that A is the current branch.
5265 return fiber;
5266 }
5267 // Otherwise B has to be current branch.
5268 return alternate;
5269}
5270
5271function findCurrentHostFiber(parent) {
5272 var currentParent = findCurrentFiberUsingSlowPath(parent);
5273 if (!currentParent) {
5274 return null;
5275 }
5276
5277 // Next we'll drill down this component to find the first HostComponent/Text.
5278 var node = currentParent;
5279 while (true) {
5280 if (node.tag === HostComponent || node.tag === HostText) {
5281 return node;
5282 } else if (node.child) {
5283 node.child.return = node;
5284 node = node.child;
5285 continue;
5286 }
5287 if (node === currentParent) {
5288 return null;
5289 }
5290 while (!node.sibling) {
5291 if (!node.return || node.return === currentParent) {
5292 return null;
5293 }
5294 node = node.return;
5295 }
5296 node.sibling.return = node.return;
5297 node = node.sibling;
5298 }
5299 // Flow needs the return null here, but ESLint complains about it.
5300 // eslint-disable-next-line no-unreachable
5301 return null;
5302}
5303
5304function findCurrentHostFiberWithNoPortals(parent) {
5305 var currentParent = findCurrentFiberUsingSlowPath(parent);
5306 if (!currentParent) {
5307 return null;
5308 }
5309
5310 // Next we'll drill down this component to find the first HostComponent/Text.
5311 var node = currentParent;
5312 while (true) {
5313 if (node.tag === HostComponent || node.tag === HostText || node.tag === FundamentalComponent) {
5314 return node;
5315 } else if (node.child && node.tag !== HostPortal) {
5316 node.child.return = node;
5317 node = node.child;
5318 continue;
5319 }
5320 if (node === currentParent) {
5321 return null;
5322 }
5323 while (!node.sibling) {
5324 if (!node.return || node.return === currentParent) {
5325 return null;
5326 }
5327 node = node.return;
5328 }
5329 node.sibling.return = node.return;
5330 node = node.sibling;
5331 }
5332 // Flow needs the return null here, but ESLint complains about it.
5333 // eslint-disable-next-line no-unreachable
5334 return null;
5335}
5336
5337function addEventBubbleListener(element, eventType, listener) {
5338 element.addEventListener(eventType, listener, false);
5339}
5340
5341function addEventCaptureListener(element, eventType, listener) {
5342 element.addEventListener(eventType, listener, true);
5343}
5344
5345function addEventCaptureListenerWithPassiveFlag(element, eventType, listener, passive) {
5346 element.addEventListener(eventType, listener, {
5347 capture: true,
5348 passive: passive
5349 });
5350}
5351
5352/**
5353 * @interface Event
5354 * @see http://www.w3.org/TR/css3-animations/#AnimationEvent-interface
5355 * @see https://developer.mozilla.org/en-US/docs/Web/API/AnimationEvent
5356 */
5357var SyntheticAnimationEvent = SyntheticEvent.extend({
5358 animationName: null,
5359 elapsedTime: null,
5360 pseudoElement: null
5361});
5362
5363/**
5364 * @interface Event
5365 * @see http://www.w3.org/TR/clipboard-apis/
5366 */
5367var SyntheticClipboardEvent = SyntheticEvent.extend({
5368 clipboardData: function (event) {
5369 return 'clipboardData' in event ? event.clipboardData : window.clipboardData;
5370 }
5371});
5372
5373/**
5374 * @interface FocusEvent
5375 * @see http://www.w3.org/TR/DOM-Level-3-Events/
5376 */
5377var SyntheticFocusEvent = SyntheticUIEvent.extend({
5378 relatedTarget: null
5379});
5380
5381/**
5382 * `charCode` represents the actual "character code" and is safe to use with
5383 * `String.fromCharCode`. As such, only keys that correspond to printable
5384 * characters produce a valid `charCode`, the only exception to this is Enter.
5385 * The Tab-key is considered non-printable and does not have a `charCode`,
5386 * presumably because it does not produce a tab-character in browsers.
5387 *
5388 * @param {object} nativeEvent Native browser event.
5389 * @return {number} Normalized `charCode` property.
5390 */
5391function getEventCharCode(nativeEvent) {
5392 var charCode = void 0;
5393 var keyCode = nativeEvent.keyCode;
5394
5395 if ('charCode' in nativeEvent) {
5396 charCode = nativeEvent.charCode;
5397
5398 // FF does not set `charCode` for the Enter-key, check against `keyCode`.
5399 if (charCode === 0 && keyCode === 13) {
5400 charCode = 13;
5401 }
5402 } else {
5403 // IE8 does not implement `charCode`, but `keyCode` has the correct value.
5404 charCode = keyCode;
5405 }
5406
5407 // IE and Edge (on Windows) and Chrome / Safari (on Windows and Linux)
5408 // report Enter as charCode 10 when ctrl is pressed.
5409 if (charCode === 10) {
5410 charCode = 13;
5411 }
5412
5413 // Some non-printable keys are reported in `charCode`/`keyCode`, discard them.
5414 // Must not discard the (non-)printable Enter-key.
5415 if (charCode >= 32 || charCode === 13) {
5416 return charCode;
5417 }
5418
5419 return 0;
5420}
5421
5422/**
5423 * Normalization of deprecated HTML5 `key` values
5424 * @see https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent#Key_names
5425 */
5426var normalizeKey = {
5427 Esc: 'Escape',
5428 Spacebar: ' ',
5429 Left: 'ArrowLeft',
5430 Up: 'ArrowUp',
5431 Right: 'ArrowRight',
5432 Down: 'ArrowDown',
5433 Del: 'Delete',
5434 Win: 'OS',
5435 Menu: 'ContextMenu',
5436 Apps: 'ContextMenu',
5437 Scroll: 'ScrollLock',
5438 MozPrintableKey: 'Unidentified'
5439};
5440
5441/**
5442 * Translation from legacy `keyCode` to HTML5 `key`
5443 * Only special keys supported, all others depend on keyboard layout or browser
5444 * @see https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent#Key_names
5445 */
5446var translateToKey = {
5447 '8': 'Backspace',
5448 '9': 'Tab',
5449 '12': 'Clear',
5450 '13': 'Enter',
5451 '16': 'Shift',
5452 '17': 'Control',
5453 '18': 'Alt',
5454 '19': 'Pause',
5455 '20': 'CapsLock',
5456 '27': 'Escape',
5457 '32': ' ',
5458 '33': 'PageUp',
5459 '34': 'PageDown',
5460 '35': 'End',
5461 '36': 'Home',
5462 '37': 'ArrowLeft',
5463 '38': 'ArrowUp',
5464 '39': 'ArrowRight',
5465 '40': 'ArrowDown',
5466 '45': 'Insert',
5467 '46': 'Delete',
5468 '112': 'F1',
5469 '113': 'F2',
5470 '114': 'F3',
5471 '115': 'F4',
5472 '116': 'F5',
5473 '117': 'F6',
5474 '118': 'F7',
5475 '119': 'F8',
5476 '120': 'F9',
5477 '121': 'F10',
5478 '122': 'F11',
5479 '123': 'F12',
5480 '144': 'NumLock',
5481 '145': 'ScrollLock',
5482 '224': 'Meta'
5483};
5484
5485/**
5486 * @param {object} nativeEvent Native browser event.
5487 * @return {string} Normalized `key` property.
5488 */
5489function getEventKey(nativeEvent) {
5490 if (nativeEvent.key) {
5491 // Normalize inconsistent values reported by browsers due to
5492 // implementations of a working draft specification.
5493
5494 // FireFox implements `key` but returns `MozPrintableKey` for all
5495 // printable characters (normalized to `Unidentified`), ignore it.
5496 var key = normalizeKey[nativeEvent.key] || nativeEvent.key;
5497 if (key !== 'Unidentified') {
5498 return key;
5499 }
5500 }
5501
5502 // Browser does not implement `key`, polyfill as much of it as we can.
5503 if (nativeEvent.type === 'keypress') {
5504 var charCode = getEventCharCode(nativeEvent);
5505
5506 // The enter-key is technically both printable and non-printable and can
5507 // thus be captured by `keypress`, no other non-printable key should.
5508 return charCode === 13 ? 'Enter' : String.fromCharCode(charCode);
5509 }
5510 if (nativeEvent.type === 'keydown' || nativeEvent.type === 'keyup') {
5511 // While user keyboard layout determines the actual meaning of each
5512 // `keyCode` value, almost all function keys have a universal value.
5513 return translateToKey[nativeEvent.keyCode] || 'Unidentified';
5514 }
5515 return '';
5516}
5517
5518/**
5519 * @interface KeyboardEvent
5520 * @see http://www.w3.org/TR/DOM-Level-3-Events/
5521 */
5522var SyntheticKeyboardEvent = SyntheticUIEvent.extend({
5523 key: getEventKey,
5524 location: null,
5525 ctrlKey: null,
5526 shiftKey: null,
5527 altKey: null,
5528 metaKey: null,
5529 repeat: null,
5530 locale: null,
5531 getModifierState: getEventModifierState,
5532 // Legacy Interface
5533 charCode: function (event) {
5534 // `charCode` is the result of a KeyPress event and represents the value of
5535 // the actual printable character.
5536
5537 // KeyPress is deprecated, but its replacement is not yet final and not
5538 // implemented in any major browser. Only KeyPress has charCode.
5539 if (event.type === 'keypress') {
5540 return getEventCharCode(event);
5541 }
5542 return 0;
5543 },
5544 keyCode: function (event) {
5545 // `keyCode` is the result of a KeyDown/Up event and represents the value of
5546 // physical keyboard key.
5547
5548 // The actual meaning of the value depends on the users' keyboard layout
5549 // which cannot be detected. Assuming that it is a US keyboard layout
5550 // provides a surprisingly accurate mapping for US and European users.
5551 // Due to this, it is left to the user to implement at this time.
5552 if (event.type === 'keydown' || event.type === 'keyup') {
5553 return event.keyCode;
5554 }
5555 return 0;
5556 },
5557 which: function (event) {
5558 // `which` is an alias for either `keyCode` or `charCode` depending on the
5559 // type of the event.
5560 if (event.type === 'keypress') {
5561 return getEventCharCode(event);
5562 }
5563 if (event.type === 'keydown' || event.type === 'keyup') {
5564 return event.keyCode;
5565 }
5566 return 0;
5567 }
5568});
5569
5570/**
5571 * @interface DragEvent
5572 * @see http://www.w3.org/TR/DOM-Level-3-Events/
5573 */
5574var SyntheticDragEvent = SyntheticMouseEvent.extend({
5575 dataTransfer: null
5576});
5577
5578/**
5579 * @interface TouchEvent
5580 * @see http://www.w3.org/TR/touch-events/
5581 */
5582var SyntheticTouchEvent = SyntheticUIEvent.extend({
5583 touches: null,
5584 targetTouches: null,
5585 changedTouches: null,
5586 altKey: null,
5587 metaKey: null,
5588 ctrlKey: null,
5589 shiftKey: null,
5590 getModifierState: getEventModifierState
5591});
5592
5593/**
5594 * @interface Event
5595 * @see http://www.w3.org/TR/2009/WD-css3-transitions-20090320/#transition-events-
5596 * @see https://developer.mozilla.org/en-US/docs/Web/API/TransitionEvent
5597 */
5598var SyntheticTransitionEvent = SyntheticEvent.extend({
5599 propertyName: null,
5600 elapsedTime: null,
5601 pseudoElement: null
5602});
5603
5604/**
5605 * @interface WheelEvent
5606 * @see http://www.w3.org/TR/DOM-Level-3-Events/
5607 */
5608var SyntheticWheelEvent = SyntheticMouseEvent.extend({
5609 deltaX: function (event) {
5610 return 'deltaX' in event ? event.deltaX : // Fallback to `wheelDeltaX` for Webkit and normalize (right is positive).
5611 'wheelDeltaX' in event ? -event.wheelDeltaX : 0;
5612 },
5613 deltaY: function (event) {
5614 return 'deltaY' in event ? event.deltaY : // Fallback to `wheelDeltaY` for Webkit and normalize (down is positive).
5615 'wheelDeltaY' in event ? -event.wheelDeltaY : // Fallback to `wheelDelta` for IE<9 and normalize (down is positive).
5616 'wheelDelta' in event ? -event.wheelDelta : 0;
5617 },
5618
5619 deltaZ: null,
5620
5621 // Browsers without "deltaMode" is reporting in raw wheel delta where one
5622 // notch on the scroll is always +/- 120, roughly equivalent to pixels.
5623 // A good approximation of DOM_DELTA_LINE (1) is 5% of viewport size or
5624 // ~40 pixels, for DOM_DELTA_SCREEN (2) it is 87.5% of viewport size.
5625 deltaMode: null
5626});
5627
5628/**
5629 * Turns
5630 * ['abort', ...]
5631 * into
5632 * eventTypes = {
5633 * 'abort': {
5634 * phasedRegistrationNames: {
5635 * bubbled: 'onAbort',
5636 * captured: 'onAbortCapture',
5637 * },
5638 * dependencies: [TOP_ABORT],
5639 * },
5640 * ...
5641 * };
5642 * topLevelEventsToDispatchConfig = new Map([
5643 * [TOP_ABORT, { sameConfig }],
5644 * ]);
5645 */
5646
5647var eventTuples = [
5648// Discrete events
5649[TOP_BLUR, 'blur', DiscreteEvent], [TOP_CANCEL, 'cancel', DiscreteEvent], [TOP_CLICK, 'click', DiscreteEvent], [TOP_CLOSE, 'close', DiscreteEvent], [TOP_CONTEXT_MENU, 'contextMenu', DiscreteEvent], [TOP_COPY, 'copy', DiscreteEvent], [TOP_CUT, 'cut', DiscreteEvent], [TOP_AUX_CLICK, 'auxClick', DiscreteEvent], [TOP_DOUBLE_CLICK, 'doubleClick', DiscreteEvent], [TOP_DRAG_END, 'dragEnd', DiscreteEvent], [TOP_DRAG_START, 'dragStart', DiscreteEvent], [TOP_DROP, 'drop', DiscreteEvent], [TOP_FOCUS, 'focus', DiscreteEvent], [TOP_INPUT, 'input', DiscreteEvent], [TOP_INVALID, 'invalid', DiscreteEvent], [TOP_KEY_DOWN, 'keyDown', DiscreteEvent], [TOP_KEY_PRESS, 'keyPress', DiscreteEvent], [TOP_KEY_UP, 'keyUp', DiscreteEvent], [TOP_MOUSE_DOWN, 'mouseDown', DiscreteEvent], [TOP_MOUSE_UP, 'mouseUp', DiscreteEvent], [TOP_PASTE, 'paste', DiscreteEvent], [TOP_PAUSE, 'pause', DiscreteEvent], [TOP_PLAY, 'play', DiscreteEvent], [TOP_POINTER_CANCEL, 'pointerCancel', DiscreteEvent], [TOP_POINTER_DOWN, 'pointerDown', DiscreteEvent], [TOP_POINTER_UP, 'pointerUp', DiscreteEvent], [TOP_RATE_CHANGE, 'rateChange', DiscreteEvent], [TOP_RESET, 'reset', DiscreteEvent], [TOP_SEEKED, 'seeked', DiscreteEvent], [TOP_SUBMIT, 'submit', DiscreteEvent], [TOP_TOUCH_CANCEL, 'touchCancel', DiscreteEvent], [TOP_TOUCH_END, 'touchEnd', DiscreteEvent], [TOP_TOUCH_START, 'touchStart', DiscreteEvent], [TOP_VOLUME_CHANGE, 'volumeChange', DiscreteEvent],
5650
5651// User-blocking events
5652[TOP_DRAG, 'drag', UserBlockingEvent], [TOP_DRAG_ENTER, 'dragEnter', UserBlockingEvent], [TOP_DRAG_EXIT, 'dragExit', UserBlockingEvent], [TOP_DRAG_LEAVE, 'dragLeave', UserBlockingEvent], [TOP_DRAG_OVER, 'dragOver', UserBlockingEvent], [TOP_MOUSE_MOVE, 'mouseMove', UserBlockingEvent], [TOP_MOUSE_OUT, 'mouseOut', UserBlockingEvent], [TOP_MOUSE_OVER, 'mouseOver', UserBlockingEvent], [TOP_POINTER_MOVE, 'pointerMove', UserBlockingEvent], [TOP_POINTER_OUT, 'pointerOut', UserBlockingEvent], [TOP_POINTER_OVER, 'pointerOver', UserBlockingEvent], [TOP_SCROLL, 'scroll', UserBlockingEvent], [TOP_TOGGLE, 'toggle', UserBlockingEvent], [TOP_TOUCH_MOVE, 'touchMove', UserBlockingEvent], [TOP_WHEEL, 'wheel', UserBlockingEvent],
5653
5654// Continuous events
5655[TOP_ABORT, 'abort', ContinuousEvent], [TOP_ANIMATION_END, 'animationEnd', ContinuousEvent], [TOP_ANIMATION_ITERATION, 'animationIteration', ContinuousEvent], [TOP_ANIMATION_START, 'animationStart', ContinuousEvent], [TOP_CAN_PLAY, 'canPlay', ContinuousEvent], [TOP_CAN_PLAY_THROUGH, 'canPlayThrough', ContinuousEvent], [TOP_DURATION_CHANGE, 'durationChange', ContinuousEvent], [TOP_EMPTIED, 'emptied', ContinuousEvent], [TOP_ENCRYPTED, 'encrypted', ContinuousEvent], [TOP_ENDED, 'ended', ContinuousEvent], [TOP_ERROR, 'error', ContinuousEvent], [TOP_GOT_POINTER_CAPTURE, 'gotPointerCapture', ContinuousEvent], [TOP_LOAD, 'load', ContinuousEvent], [TOP_LOADED_DATA, 'loadedData', ContinuousEvent], [TOP_LOADED_METADATA, 'loadedMetadata', ContinuousEvent], [TOP_LOAD_START, 'loadStart', ContinuousEvent], [TOP_LOST_POINTER_CAPTURE, 'lostPointerCapture', ContinuousEvent], [TOP_PLAYING, 'playing', ContinuousEvent], [TOP_PROGRESS, 'progress', ContinuousEvent], [TOP_SEEKING, 'seeking', ContinuousEvent], [TOP_STALLED, 'stalled', ContinuousEvent], [TOP_SUSPEND, 'suspend', ContinuousEvent], [TOP_TIME_UPDATE, 'timeUpdate', ContinuousEvent], [TOP_TRANSITION_END, 'transitionEnd', ContinuousEvent], [TOP_WAITING, 'waiting', ContinuousEvent]];
5656
5657var eventTypes$4 = {};
5658var topLevelEventsToDispatchConfig = {};
5659
5660for (var i = 0; i < eventTuples.length; i++) {
5661 var eventTuple = eventTuples[i];
5662 var topEvent = eventTuple[0];
5663 var event = eventTuple[1];
5664 var eventPriority = eventTuple[2];
5665
5666 var capitalizedEvent = event[0].toUpperCase() + event.slice(1);
5667 var onEvent = 'on' + capitalizedEvent;
5668
5669 var config = {
5670 phasedRegistrationNames: {
5671 bubbled: onEvent,
5672 captured: onEvent + 'Capture'
5673 },
5674 dependencies: [topEvent],
5675 eventPriority: eventPriority
5676 };
5677 eventTypes$4[event] = config;
5678 topLevelEventsToDispatchConfig[topEvent] = config;
5679}
5680
5681// Only used in DEV for exhaustiveness validation.
5682var 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];
5683
5684var SimpleEventPlugin = {
5685 eventTypes: eventTypes$4,
5686
5687 getEventPriority: function (topLevelType) {
5688 var config = topLevelEventsToDispatchConfig[topLevelType];
5689 return config !== undefined ? config.eventPriority : ContinuousEvent;
5690 },
5691
5692
5693 extractEvents: function (topLevelType, targetInst, nativeEvent, nativeEventTarget) {
5694 var dispatchConfig = topLevelEventsToDispatchConfig[topLevelType];
5695 if (!dispatchConfig) {
5696 return null;
5697 }
5698 var EventConstructor = void 0;
5699 switch (topLevelType) {
5700 case TOP_KEY_PRESS:
5701 // Firefox creates a keypress event for function keys too. This removes
5702 // the unwanted keypress events. Enter is however both printable and
5703 // non-printable. One would expect Tab to be as well (but it isn't).
5704 if (getEventCharCode(nativeEvent) === 0) {
5705 return null;
5706 }
5707 /* falls through */
5708 case TOP_KEY_DOWN:
5709 case TOP_KEY_UP:
5710 EventConstructor = SyntheticKeyboardEvent;
5711 break;
5712 case TOP_BLUR:
5713 case TOP_FOCUS:
5714 EventConstructor = SyntheticFocusEvent;
5715 break;
5716 case TOP_CLICK:
5717 // Firefox creates a click event on right mouse clicks. This removes the
5718 // unwanted click events.
5719 if (nativeEvent.button === 2) {
5720 return null;
5721 }
5722 /* falls through */
5723 case TOP_AUX_CLICK:
5724 case TOP_DOUBLE_CLICK:
5725 case TOP_MOUSE_DOWN:
5726 case TOP_MOUSE_MOVE:
5727 case TOP_MOUSE_UP:
5728 // TODO: Disabled elements should not respond to mouse events
5729 /* falls through */
5730 case TOP_MOUSE_OUT:
5731 case TOP_MOUSE_OVER:
5732 case TOP_CONTEXT_MENU:
5733 EventConstructor = SyntheticMouseEvent;
5734 break;
5735 case TOP_DRAG:
5736 case TOP_DRAG_END:
5737 case TOP_DRAG_ENTER:
5738 case TOP_DRAG_EXIT:
5739 case TOP_DRAG_LEAVE:
5740 case TOP_DRAG_OVER:
5741 case TOP_DRAG_START:
5742 case TOP_DROP:
5743 EventConstructor = SyntheticDragEvent;
5744 break;
5745 case TOP_TOUCH_CANCEL:
5746 case TOP_TOUCH_END:
5747 case TOP_TOUCH_MOVE:
5748 case TOP_TOUCH_START:
5749 EventConstructor = SyntheticTouchEvent;
5750 break;
5751 case TOP_ANIMATION_END:
5752 case TOP_ANIMATION_ITERATION:
5753 case TOP_ANIMATION_START:
5754 EventConstructor = SyntheticAnimationEvent;
5755 break;
5756 case TOP_TRANSITION_END:
5757 EventConstructor = SyntheticTransitionEvent;
5758 break;
5759 case TOP_SCROLL:
5760 EventConstructor = SyntheticUIEvent;
5761 break;
5762 case TOP_WHEEL:
5763 EventConstructor = SyntheticWheelEvent;
5764 break;
5765 case TOP_COPY:
5766 case TOP_CUT:
5767 case TOP_PASTE:
5768 EventConstructor = SyntheticClipboardEvent;
5769 break;
5770 case TOP_GOT_POINTER_CAPTURE:
5771 case TOP_LOST_POINTER_CAPTURE:
5772 case TOP_POINTER_CANCEL:
5773 case TOP_POINTER_DOWN:
5774 case TOP_POINTER_MOVE:
5775 case TOP_POINTER_OUT:
5776 case TOP_POINTER_OVER:
5777 case TOP_POINTER_UP:
5778 EventConstructor = SyntheticPointerEvent;
5779 break;
5780 default:
5781 {
5782 if (knownHTMLTopLevelTypes.indexOf(topLevelType) === -1) {
5783 warningWithoutStack$1(false, 'SimpleEventPlugin: Unhandled event type, `%s`. This warning ' + 'is likely caused by a bug in React. Please file an issue.', topLevelType);
5784 }
5785 }
5786 // HTML Events
5787 // @see http://www.w3.org/TR/html5/index.html#events-0
5788 EventConstructor = SyntheticEvent;
5789 break;
5790 }
5791 var event = EventConstructor.getPooled(dispatchConfig, targetInst, nativeEvent, nativeEventTarget);
5792 accumulateTwoPhaseDispatches(event);
5793 return event;
5794 }
5795};
5796
5797var passiveBrowserEventsSupported = false;
5798
5799// Check if browser support events with passive listeners
5800// https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener#Safely_detecting_option_support
5801if (enableFlareAPI && canUseDOM) {
5802 try {
5803 var options = {};
5804 // $FlowFixMe: Ignore Flow complaining about needing a value
5805 Object.defineProperty(options, 'passive', {
5806 get: function () {
5807 passiveBrowserEventsSupported = true;
5808 }
5809 });
5810 window.addEventListener('test', options, options);
5811 window.removeEventListener('test', options, options);
5812 } catch (e) {
5813 passiveBrowserEventsSupported = false;
5814 }
5815}
5816
5817// Intentionally not named imports because Rollup would use dynamic dispatch for
5818// CommonJS interop named imports.
5819var UserBlockingPriority = Scheduler.unstable_UserBlockingPriority;
5820var runWithPriority = Scheduler.unstable_runWithPriority;
5821var getEventPriority = SimpleEventPlugin.getEventPriority;
5822
5823
5824var CALLBACK_BOOKKEEPING_POOL_SIZE = 10;
5825var callbackBookkeepingPool = [];
5826
5827/**
5828 * Find the deepest React component completely containing the root of the
5829 * passed-in instance (for use when entire React trees are nested within each
5830 * other). If React trees are not nested, returns null.
5831 */
5832function findRootContainerNode(inst) {
5833 // TODO: It may be a good idea to cache this to prevent unnecessary DOM
5834 // traversal, but caching is difficult to do correctly without using a
5835 // mutation observer to listen for all DOM changes.
5836 while (inst.return) {
5837 inst = inst.return;
5838 }
5839 if (inst.tag !== HostRoot) {
5840 // This can happen if we're in a detached tree.
5841 return null;
5842 }
5843 return inst.stateNode.containerInfo;
5844}
5845
5846// Used to store ancestor hierarchy in top level callback
5847function getTopLevelCallbackBookKeeping(topLevelType, nativeEvent, targetInst) {
5848 if (callbackBookkeepingPool.length) {
5849 var instance = callbackBookkeepingPool.pop();
5850 instance.topLevelType = topLevelType;
5851 instance.nativeEvent = nativeEvent;
5852 instance.targetInst = targetInst;
5853 return instance;
5854 }
5855 return {
5856 topLevelType: topLevelType,
5857 nativeEvent: nativeEvent,
5858 targetInst: targetInst,
5859 ancestors: []
5860 };
5861}
5862
5863function releaseTopLevelCallbackBookKeeping(instance) {
5864 instance.topLevelType = null;
5865 instance.nativeEvent = null;
5866 instance.targetInst = null;
5867 instance.ancestors.length = 0;
5868 if (callbackBookkeepingPool.length < CALLBACK_BOOKKEEPING_POOL_SIZE) {
5869 callbackBookkeepingPool.push(instance);
5870 }
5871}
5872
5873function handleTopLevel(bookKeeping) {
5874 var targetInst = bookKeeping.targetInst;
5875
5876 // Loop through the hierarchy, in case there's any nested components.
5877 // It's important that we build the array of ancestors before calling any
5878 // event handlers, because event handlers can modify the DOM, leading to
5879 // inconsistencies with ReactMount's node cache. See #1105.
5880 var ancestor = targetInst;
5881 do {
5882 if (!ancestor) {
5883 var _ancestors = bookKeeping.ancestors;
5884 _ancestors.push(ancestor);
5885 break;
5886 }
5887 var root = findRootContainerNode(ancestor);
5888 if (!root) {
5889 break;
5890 }
5891 bookKeeping.ancestors.push(ancestor);
5892 ancestor = getClosestInstanceFromNode(root);
5893 } while (ancestor);
5894
5895 for (var i = 0; i < bookKeeping.ancestors.length; i++) {
5896 targetInst = bookKeeping.ancestors[i];
5897 var eventTarget = getEventTarget(bookKeeping.nativeEvent);
5898 var _topLevelType = bookKeeping.topLevelType;
5899 var _nativeEvent = bookKeeping.nativeEvent;
5900
5901 runExtractedPluginEventsInBatch(_topLevelType, targetInst, _nativeEvent, eventTarget);
5902 }
5903}
5904
5905// TODO: can we stop exporting these?
5906var _enabled = true;
5907
5908function setEnabled(enabled) {
5909 _enabled = !!enabled;
5910}
5911
5912function isEnabled() {
5913 return _enabled;
5914}
5915
5916function trapBubbledEvent(topLevelType, element) {
5917 trapEventForPluginEventSystem(element, topLevelType, false);
5918}
5919
5920function trapCapturedEvent(topLevelType, element) {
5921 trapEventForPluginEventSystem(element, topLevelType, true);
5922}
5923
5924function trapEventForResponderEventSystem(element, topLevelType, passive) {
5925 if (enableFlareAPI) {
5926 var rawEventName = getRawEventName(topLevelType);
5927 var eventFlags = RESPONDER_EVENT_SYSTEM;
5928
5929 // If passive option is not supported, then the event will be
5930 // active and not passive, but we flag it as using not being
5931 // supported too. This way the responder event plugins know,
5932 // and can provide polyfills if needed.
5933 if (passive) {
5934 if (passiveBrowserEventsSupported) {
5935 eventFlags |= IS_PASSIVE;
5936 } else {
5937 eventFlags |= IS_ACTIVE;
5938 eventFlags |= PASSIVE_NOT_SUPPORTED;
5939 passive = false;
5940 }
5941 } else {
5942 eventFlags |= IS_ACTIVE;
5943 }
5944 // Check if interactive and wrap in discreteUpdates
5945 var listener = dispatchEvent.bind(null, topLevelType, eventFlags);
5946 if (passiveBrowserEventsSupported) {
5947 addEventCaptureListenerWithPassiveFlag(element, rawEventName, listener, passive);
5948 } else {
5949 addEventCaptureListener(element, rawEventName, listener);
5950 }
5951 }
5952}
5953
5954function trapEventForPluginEventSystem(element, topLevelType, capture) {
5955 var listener = void 0;
5956 switch (getEventPriority(topLevelType)) {
5957 case DiscreteEvent:
5958 listener = dispatchDiscreteEvent.bind(null, topLevelType, PLUGIN_EVENT_SYSTEM);
5959 break;
5960 case UserBlockingEvent:
5961 listener = dispatchUserBlockingUpdate.bind(null, topLevelType, PLUGIN_EVENT_SYSTEM);
5962 break;
5963 case ContinuousEvent:
5964 default:
5965 listener = dispatchEvent.bind(null, topLevelType, PLUGIN_EVENT_SYSTEM);
5966 break;
5967 }
5968
5969 var rawEventName = getRawEventName(topLevelType);
5970 if (capture) {
5971 addEventCaptureListener(element, rawEventName, listener);
5972 } else {
5973 addEventBubbleListener(element, rawEventName, listener);
5974 }
5975}
5976
5977function dispatchDiscreteEvent(topLevelType, eventSystemFlags, nativeEvent) {
5978 flushDiscreteUpdatesIfNeeded(nativeEvent.timeStamp);
5979 discreteUpdates(dispatchEvent, topLevelType, eventSystemFlags, nativeEvent);
5980}
5981
5982function dispatchUserBlockingUpdate(topLevelType, eventSystemFlags, nativeEvent) {
5983 if (enableUserBlockingEvents) {
5984 runWithPriority(UserBlockingPriority, dispatchEvent.bind(null, topLevelType, eventSystemFlags, nativeEvent));
5985 } else {
5986 dispatchEvent(topLevelType, eventSystemFlags, nativeEvent);
5987 }
5988}
5989
5990function dispatchEventForPluginEventSystem(topLevelType, eventSystemFlags, nativeEvent, targetInst) {
5991 var bookKeeping = getTopLevelCallbackBookKeeping(topLevelType, nativeEvent, targetInst);
5992
5993 try {
5994 // Event queue being processed in the same cycle allows
5995 // `preventDefault`.
5996 batchedEventUpdates(handleTopLevel, bookKeeping);
5997 } finally {
5998 releaseTopLevelCallbackBookKeeping(bookKeeping);
5999 }
6000}
6001
6002function dispatchEvent(topLevelType, eventSystemFlags, nativeEvent) {
6003 if (!_enabled) {
6004 return;
6005 }
6006 var nativeEventTarget = getEventTarget(nativeEvent);
6007 var targetInst = getClosestInstanceFromNode(nativeEventTarget);
6008
6009 if (targetInst !== null && typeof targetInst.tag === 'number' && !isFiberMounted(targetInst)) {
6010 // If we get an event (ex: img onload) before committing that
6011 // component's mount, ignore it for now (that is, treat it as if it was an
6012 // event on a non-React tree). We might also consider queueing events and
6013 // dispatching them after the mount.
6014 targetInst = null;
6015 }
6016
6017 if (enableFlareAPI) {
6018 if (eventSystemFlags === PLUGIN_EVENT_SYSTEM) {
6019 dispatchEventForPluginEventSystem(topLevelType, eventSystemFlags, nativeEvent, targetInst);
6020 } else {
6021 // React Flare event system
6022 dispatchEventForResponderEventSystem(topLevelType, targetInst, nativeEvent, nativeEventTarget, eventSystemFlags);
6023 }
6024 } else {
6025 dispatchEventForPluginEventSystem(topLevelType, eventSystemFlags, nativeEvent, targetInst);
6026 }
6027}
6028
6029/**
6030 * Summary of `ReactBrowserEventEmitter` event handling:
6031 *
6032 * - Top-level delegation is used to trap most native browser events. This
6033 * may only occur in the main thread and is the responsibility of
6034 * ReactDOMEventListener, which is injected and can therefore support
6035 * pluggable event sources. This is the only work that occurs in the main
6036 * thread.
6037 *
6038 * - We normalize and de-duplicate events to account for browser quirks. This
6039 * may be done in the worker thread.
6040 *
6041 * - Forward these native events (with the associated top-level type used to
6042 * trap it) to `EventPluginHub`, which in turn will ask plugins if they want
6043 * to extract any synthetic events.
6044 *
6045 * - The `EventPluginHub` will then process each event by annotating them with
6046 * "dispatches", a sequence of listeners and IDs that care about that event.
6047 *
6048 * - The `EventPluginHub` then dispatches the events.
6049 *
6050 * Overview of React and the event system:
6051 *
6052 * +------------+ .
6053 * | DOM | .
6054 * +------------+ .
6055 * | .
6056 * v .
6057 * +------------+ .
6058 * | ReactEvent | .
6059 * | Listener | .
6060 * +------------+ . +-----------+
6061 * | . +--------+|SimpleEvent|
6062 * | . | |Plugin |
6063 * +-----|------+ . v +-----------+
6064 * | | | . +--------------+ +------------+
6065 * | +-----------.--->|EventPluginHub| | Event |
6066 * | | . | | +-----------+ | Propagators|
6067 * | ReactEvent | . | | |TapEvent | |------------|
6068 * | Emitter | . | |<---+|Plugin | |other plugin|
6069 * | | . | | +-----------+ | utilities |
6070 * | +-----------.--->| | +------------+
6071 * | | | . +--------------+
6072 * +-----|------+ . ^ +-----------+
6073 * | . | |Enter/Leave|
6074 * + . +-------+|Plugin |
6075 * +-------------+ . +-----------+
6076 * | application | .
6077 * |-------------| .
6078 * | | .
6079 * | | .
6080 * +-------------+ .
6081 * .
6082 * React Core . General Purpose Event Plugin System
6083 */
6084
6085var PossiblyWeakMap = typeof WeakMap === 'function' ? WeakMap : Map;
6086var elementListeningSets = new PossiblyWeakMap();
6087
6088function getListeningSetForElement(element) {
6089 var listeningSet = elementListeningSets.get(element);
6090 if (listeningSet === undefined) {
6091 listeningSet = new Set();
6092 elementListeningSets.set(element, listeningSet);
6093 }
6094 return listeningSet;
6095}
6096
6097/**
6098 * We listen for bubbled touch events on the document object.
6099 *
6100 * Firefox v8.01 (and possibly others) exhibited strange behavior when
6101 * mounting `onmousemove` events at some node that was not the document
6102 * element. The symptoms were that if your mouse is not moving over something
6103 * contained within that mount point (for example on the background) the
6104 * top-level listeners for `onmousemove` won't be called. However, if you
6105 * register the `mousemove` on the document object, then it will of course
6106 * catch all `mousemove`s. This along with iOS quirks, justifies restricting
6107 * top-level listeners to the document object only, at least for these
6108 * movement types of events and possibly all events.
6109 *
6110 * @see http://www.quirksmode.org/blog/archives/2010/09/click_event_del.html
6111 *
6112 * Also, `keyup`/`keypress`/`keydown` do not bubble to the window on IE, but
6113 * they bubble to document.
6114 *
6115 * @param {string} registrationName Name of listener (e.g. `onClick`).
6116 * @param {object} mountAt Container where to mount the listener
6117 */
6118function listenTo(registrationName, mountAt) {
6119 var listeningSet = getListeningSetForElement(mountAt);
6120 var dependencies = registrationNameDependencies[registrationName];
6121
6122 for (var i = 0; i < dependencies.length; i++) {
6123 var dependency = dependencies[i];
6124 if (!listeningSet.has(dependency)) {
6125 switch (dependency) {
6126 case TOP_SCROLL:
6127 trapCapturedEvent(TOP_SCROLL, mountAt);
6128 break;
6129 case TOP_FOCUS:
6130 case TOP_BLUR:
6131 trapCapturedEvent(TOP_FOCUS, mountAt);
6132 trapCapturedEvent(TOP_BLUR, mountAt);
6133 // We set the flag for a single dependency later in this function,
6134 // but this ensures we mark both as attached rather than just one.
6135 listeningSet.add(TOP_BLUR);
6136 listeningSet.add(TOP_FOCUS);
6137 break;
6138 case TOP_CANCEL:
6139 case TOP_CLOSE:
6140 if (isEventSupported(getRawEventName(dependency))) {
6141 trapCapturedEvent(dependency, mountAt);
6142 }
6143 break;
6144 case TOP_INVALID:
6145 case TOP_SUBMIT:
6146 case TOP_RESET:
6147 // We listen to them on the target DOM elements.
6148 // Some of them bubble so we don't want them to fire twice.
6149 break;
6150 default:
6151 // By default, listen on the top level to all non-media events.
6152 // Media events don't bubble so adding the listener wouldn't do anything.
6153 var isMediaEvent = mediaEventTypes.indexOf(dependency) !== -1;
6154 if (!isMediaEvent) {
6155 trapBubbledEvent(dependency, mountAt);
6156 }
6157 break;
6158 }
6159 listeningSet.add(dependency);
6160 }
6161 }
6162}
6163
6164function isListeningToAllDependencies(registrationName, mountAt) {
6165 var listeningSet = getListeningSetForElement(mountAt);
6166 var dependencies = registrationNameDependencies[registrationName];
6167
6168 for (var i = 0; i < dependencies.length; i++) {
6169 var dependency = dependencies[i];
6170 if (!listeningSet.has(dependency)) {
6171 return false;
6172 }
6173 }
6174 return true;
6175}
6176
6177function getActiveElement(doc) {
6178 doc = doc || (typeof document !== 'undefined' ? document : undefined);
6179 if (typeof doc === 'undefined') {
6180 return null;
6181 }
6182 try {
6183 return doc.activeElement || doc.body;
6184 } catch (e) {
6185 return doc.body;
6186 }
6187}
6188
6189/**
6190 * Given any node return the first leaf node without children.
6191 *
6192 * @param {DOMElement|DOMTextNode} node
6193 * @return {DOMElement|DOMTextNode}
6194 */
6195function getLeafNode(node) {
6196 while (node && node.firstChild) {
6197 node = node.firstChild;
6198 }
6199 return node;
6200}
6201
6202/**
6203 * Get the next sibling within a container. This will walk up the
6204 * DOM if a node's siblings have been exhausted.
6205 *
6206 * @param {DOMElement|DOMTextNode} node
6207 * @return {?DOMElement|DOMTextNode}
6208 */
6209function getSiblingNode(node) {
6210 while (node) {
6211 if (node.nextSibling) {
6212 return node.nextSibling;
6213 }
6214 node = node.parentNode;
6215 }
6216}
6217
6218/**
6219 * Get object describing the nodes which contain characters at offset.
6220 *
6221 * @param {DOMElement|DOMTextNode} root
6222 * @param {number} offset
6223 * @return {?object}
6224 */
6225function getNodeForCharacterOffset(root, offset) {
6226 var node = getLeafNode(root);
6227 var nodeStart = 0;
6228 var nodeEnd = 0;
6229
6230 while (node) {
6231 if (node.nodeType === TEXT_NODE) {
6232 nodeEnd = nodeStart + node.textContent.length;
6233
6234 if (nodeStart <= offset && nodeEnd >= offset) {
6235 return {
6236 node: node,
6237 offset: offset - nodeStart
6238 };
6239 }
6240
6241 nodeStart = nodeEnd;
6242 }
6243
6244 node = getLeafNode(getSiblingNode(node));
6245 }
6246}
6247
6248/**
6249 * @param {DOMElement} outerNode
6250 * @return {?object}
6251 */
6252function getOffsets(outerNode) {
6253 var ownerDocument = outerNode.ownerDocument;
6254
6255 var win = ownerDocument && ownerDocument.defaultView || window;
6256 var selection = win.getSelection && win.getSelection();
6257
6258 if (!selection || selection.rangeCount === 0) {
6259 return null;
6260 }
6261
6262 var anchorNode = selection.anchorNode,
6263 anchorOffset = selection.anchorOffset,
6264 focusNode = selection.focusNode,
6265 focusOffset = selection.focusOffset;
6266
6267 // In Firefox, anchorNode and focusNode can be "anonymous divs", e.g. the
6268 // up/down buttons on an <input type="number">. Anonymous divs do not seem to
6269 // expose properties, triggering a "Permission denied error" if any of its
6270 // properties are accessed. The only seemingly possible way to avoid erroring
6271 // is to access a property that typically works for non-anonymous divs and
6272 // catch any error that may otherwise arise. See
6273 // https://bugzilla.mozilla.org/show_bug.cgi?id=208427
6274
6275 try {
6276 /* eslint-disable no-unused-expressions */
6277 anchorNode.nodeType;
6278 focusNode.nodeType;
6279 /* eslint-enable no-unused-expressions */
6280 } catch (e) {
6281 return null;
6282 }
6283
6284 return getModernOffsetsFromPoints(outerNode, anchorNode, anchorOffset, focusNode, focusOffset);
6285}
6286
6287/**
6288 * Returns {start, end} where `start` is the character/codepoint index of
6289 * (anchorNode, anchorOffset) within the textContent of `outerNode`, and
6290 * `end` is the index of (focusNode, focusOffset).
6291 *
6292 * Returns null if you pass in garbage input but we should probably just crash.
6293 *
6294 * Exported only for testing.
6295 */
6296function getModernOffsetsFromPoints(outerNode, anchorNode, anchorOffset, focusNode, focusOffset) {
6297 var length = 0;
6298 var start = -1;
6299 var end = -1;
6300 var indexWithinAnchor = 0;
6301 var indexWithinFocus = 0;
6302 var node = outerNode;
6303 var parentNode = null;
6304
6305 outer: while (true) {
6306 var next = null;
6307
6308 while (true) {
6309 if (node === anchorNode && (anchorOffset === 0 || node.nodeType === TEXT_NODE)) {
6310 start = length + anchorOffset;
6311 }
6312 if (node === focusNode && (focusOffset === 0 || node.nodeType === TEXT_NODE)) {
6313 end = length + focusOffset;
6314 }
6315
6316 if (node.nodeType === TEXT_NODE) {
6317 length += node.nodeValue.length;
6318 }
6319
6320 if ((next = node.firstChild) === null) {
6321 break;
6322 }
6323 // Moving from `node` to its first child `next`.
6324 parentNode = node;
6325 node = next;
6326 }
6327
6328 while (true) {
6329 if (node === outerNode) {
6330 // If `outerNode` has children, this is always the second time visiting
6331 // it. If it has no children, this is still the first loop, and the only
6332 // valid selection is anchorNode and focusNode both equal to this node
6333 // and both offsets 0, in which case we will have handled above.
6334 break outer;
6335 }
6336 if (parentNode === anchorNode && ++indexWithinAnchor === anchorOffset) {
6337 start = length;
6338 }
6339 if (parentNode === focusNode && ++indexWithinFocus === focusOffset) {
6340 end = length;
6341 }
6342 if ((next = node.nextSibling) !== null) {
6343 break;
6344 }
6345 node = parentNode;
6346 parentNode = node.parentNode;
6347 }
6348
6349 // Moving from `node` to its next sibling `next`.
6350 node = next;
6351 }
6352
6353 if (start === -1 || end === -1) {
6354 // This should never happen. (Would happen if the anchor/focus nodes aren't
6355 // actually inside the passed-in node.)
6356 return null;
6357 }
6358
6359 return {
6360 start: start,
6361 end: end
6362 };
6363}
6364
6365/**
6366 * In modern non-IE browsers, we can support both forward and backward
6367 * selections.
6368 *
6369 * Note: IE10+ supports the Selection object, but it does not support
6370 * the `extend` method, which means that even in modern IE, it's not possible
6371 * to programmatically create a backward selection. Thus, for all IE
6372 * versions, we use the old IE API to create our selections.
6373 *
6374 * @param {DOMElement|DOMTextNode} node
6375 * @param {object} offsets
6376 */
6377function setOffsets(node, offsets) {
6378 var doc = node.ownerDocument || document;
6379 var win = doc && doc.defaultView || window;
6380
6381 // Edge fails with "Object expected" in some scenarios.
6382 // (For instance: TinyMCE editor used in a list component that supports pasting to add more,
6383 // fails when pasting 100+ items)
6384 if (!win.getSelection) {
6385 return;
6386 }
6387
6388 var selection = win.getSelection();
6389 var length = node.textContent.length;
6390 var start = Math.min(offsets.start, length);
6391 var end = offsets.end === undefined ? start : Math.min(offsets.end, length);
6392
6393 // IE 11 uses modern selection, but doesn't support the extend method.
6394 // Flip backward selections, so we can set with a single range.
6395 if (!selection.extend && start > end) {
6396 var temp = end;
6397 end = start;
6398 start = temp;
6399 }
6400
6401 var startMarker = getNodeForCharacterOffset(node, start);
6402 var endMarker = getNodeForCharacterOffset(node, end);
6403
6404 if (startMarker && endMarker) {
6405 if (selection.rangeCount === 1 && selection.anchorNode === startMarker.node && selection.anchorOffset === startMarker.offset && selection.focusNode === endMarker.node && selection.focusOffset === endMarker.offset) {
6406 return;
6407 }
6408 var range = doc.createRange();
6409 range.setStart(startMarker.node, startMarker.offset);
6410 selection.removeAllRanges();
6411
6412 if (start > end) {
6413 selection.addRange(range);
6414 selection.extend(endMarker.node, endMarker.offset);
6415 } else {
6416 range.setEnd(endMarker.node, endMarker.offset);
6417 selection.addRange(range);
6418 }
6419 }
6420}
6421
6422function isTextNode(node) {
6423 return node && node.nodeType === TEXT_NODE;
6424}
6425
6426function containsNode(outerNode, innerNode) {
6427 if (!outerNode || !innerNode) {
6428 return false;
6429 } else if (outerNode === innerNode) {
6430 return true;
6431 } else if (isTextNode(outerNode)) {
6432 return false;
6433 } else if (isTextNode(innerNode)) {
6434 return containsNode(outerNode, innerNode.parentNode);
6435 } else if ('contains' in outerNode) {
6436 return outerNode.contains(innerNode);
6437 } else if (outerNode.compareDocumentPosition) {
6438 return !!(outerNode.compareDocumentPosition(innerNode) & 16);
6439 } else {
6440 return false;
6441 }
6442}
6443
6444function isInDocument(node) {
6445 return node && node.ownerDocument && containsNode(node.ownerDocument.documentElement, node);
6446}
6447
6448function isSameOriginFrame(iframe) {
6449 try {
6450 // Accessing the contentDocument of a HTMLIframeElement can cause the browser
6451 // to throw, e.g. if it has a cross-origin src attribute.
6452 // Safari will show an error in the console when the access results in "Blocked a frame with origin". e.g:
6453 // iframe.contentDocument.defaultView;
6454 // A safety way is to access one of the cross origin properties: Window or Location
6455 // Which might result in "SecurityError" DOM Exception and it is compatible to Safari.
6456 // https://html.spec.whatwg.org/multipage/browsers.html#integration-with-idl
6457
6458 return typeof iframe.contentWindow.location.href === 'string';
6459 } catch (err) {
6460 return false;
6461 }
6462}
6463
6464function getActiveElementDeep() {
6465 var win = window;
6466 var element = getActiveElement();
6467 while (element instanceof win.HTMLIFrameElement) {
6468 if (isSameOriginFrame(element)) {
6469 win = element.contentWindow;
6470 } else {
6471 return element;
6472 }
6473 element = getActiveElement(win.document);
6474 }
6475 return element;
6476}
6477
6478/**
6479 * @ReactInputSelection: React input selection module. Based on Selection.js,
6480 * but modified to be suitable for react and has a couple of bug fixes (doesn't
6481 * assume buttons have range selections allowed).
6482 * Input selection module for React.
6483 */
6484
6485/**
6486 * @hasSelectionCapabilities: we get the element types that support selection
6487 * from https://html.spec.whatwg.org/#do-not-apply, looking at `selectionStart`
6488 * and `selectionEnd` rows.
6489 */
6490function hasSelectionCapabilities(elem) {
6491 var nodeName = elem && elem.nodeName && elem.nodeName.toLowerCase();
6492 return nodeName && (nodeName === 'input' && (elem.type === 'text' || elem.type === 'search' || elem.type === 'tel' || elem.type === 'url' || elem.type === 'password') || nodeName === 'textarea' || elem.contentEditable === 'true');
6493}
6494
6495function getSelectionInformation() {
6496 var focusedElem = getActiveElementDeep();
6497 return {
6498 focusedElem: focusedElem,
6499 selectionRange: hasSelectionCapabilities(focusedElem) ? getSelection$1(focusedElem) : null
6500 };
6501}
6502
6503/**
6504 * @restoreSelection: If any selection information was potentially lost,
6505 * restore it. This is useful when performing operations that could remove dom
6506 * nodes and place them back in, resulting in focus being lost.
6507 */
6508function restoreSelection(priorSelectionInformation) {
6509 var curFocusedElem = getActiveElementDeep();
6510 var priorFocusedElem = priorSelectionInformation.focusedElem;
6511 var priorSelectionRange = priorSelectionInformation.selectionRange;
6512 if (curFocusedElem !== priorFocusedElem && isInDocument(priorFocusedElem)) {
6513 if (priorSelectionRange !== null && hasSelectionCapabilities(priorFocusedElem)) {
6514 setSelection(priorFocusedElem, priorSelectionRange);
6515 }
6516
6517 // Focusing a node can change the scroll position, which is undesirable
6518 var ancestors = [];
6519 var ancestor = priorFocusedElem;
6520 while (ancestor = ancestor.parentNode) {
6521 if (ancestor.nodeType === ELEMENT_NODE) {
6522 ancestors.push({
6523 element: ancestor,
6524 left: ancestor.scrollLeft,
6525 top: ancestor.scrollTop
6526 });
6527 }
6528 }
6529
6530 if (typeof priorFocusedElem.focus === 'function') {
6531 priorFocusedElem.focus();
6532 }
6533
6534 for (var i = 0; i < ancestors.length; i++) {
6535 var info = ancestors[i];
6536 info.element.scrollLeft = info.left;
6537 info.element.scrollTop = info.top;
6538 }
6539 }
6540}
6541
6542/**
6543 * @getSelection: Gets the selection bounds of a focused textarea, input or
6544 * contentEditable node.
6545 * -@input: Look up selection bounds of this input
6546 * -@return {start: selectionStart, end: selectionEnd}
6547 */
6548function getSelection$1(input) {
6549 var selection = void 0;
6550
6551 if ('selectionStart' in input) {
6552 // Modern browser with input or textarea.
6553 selection = {
6554 start: input.selectionStart,
6555 end: input.selectionEnd
6556 };
6557 } else {
6558 // Content editable or old IE textarea.
6559 selection = getOffsets(input);
6560 }
6561
6562 return selection || { start: 0, end: 0 };
6563}
6564
6565/**
6566 * @setSelection: Sets the selection bounds of a textarea or input and focuses
6567 * the input.
6568 * -@input Set selection bounds of this input or textarea
6569 * -@offsets Object of same form that is returned from get*
6570 */
6571function setSelection(input, offsets) {
6572 var start = offsets.start,
6573 end = offsets.end;
6574
6575 if (end === undefined) {
6576 end = start;
6577 }
6578
6579 if ('selectionStart' in input) {
6580 input.selectionStart = start;
6581 input.selectionEnd = Math.min(end, input.value.length);
6582 } else {
6583 setOffsets(input, offsets);
6584 }
6585}
6586
6587var skipSelectionChangeEvent = canUseDOM && 'documentMode' in document && document.documentMode <= 11;
6588
6589var eventTypes$3 = {
6590 select: {
6591 phasedRegistrationNames: {
6592 bubbled: 'onSelect',
6593 captured: 'onSelectCapture'
6594 },
6595 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]
6596 }
6597};
6598
6599var activeElement$1 = null;
6600var activeElementInst$1 = null;
6601var lastSelection = null;
6602var mouseDown = false;
6603
6604/**
6605 * Get an object which is a unique representation of the current selection.
6606 *
6607 * The return value will not be consistent across nodes or browsers, but
6608 * two identical selections on the same node will return identical objects.
6609 *
6610 * @param {DOMElement} node
6611 * @return {object}
6612 */
6613function getSelection(node) {
6614 if ('selectionStart' in node && hasSelectionCapabilities(node)) {
6615 return {
6616 start: node.selectionStart,
6617 end: node.selectionEnd
6618 };
6619 } else {
6620 var win = node.ownerDocument && node.ownerDocument.defaultView || window;
6621 var selection = win.getSelection();
6622 return {
6623 anchorNode: selection.anchorNode,
6624 anchorOffset: selection.anchorOffset,
6625 focusNode: selection.focusNode,
6626 focusOffset: selection.focusOffset
6627 };
6628 }
6629}
6630
6631/**
6632 * Get document associated with the event target.
6633 *
6634 * @param {object} nativeEventTarget
6635 * @return {Document}
6636 */
6637function getEventTargetDocument(eventTarget) {
6638 return eventTarget.window === eventTarget ? eventTarget.document : eventTarget.nodeType === DOCUMENT_NODE ? eventTarget : eventTarget.ownerDocument;
6639}
6640
6641/**
6642 * Poll selection to see whether it's changed.
6643 *
6644 * @param {object} nativeEvent
6645 * @param {object} nativeEventTarget
6646 * @return {?SyntheticEvent}
6647 */
6648function constructSelectEvent(nativeEvent, nativeEventTarget) {
6649 // Ensure we have the right element, and that the user is not dragging a
6650 // selection (this matches native `select` event behavior). In HTML5, select
6651 // fires only on input and textarea thus if there's no focused element we
6652 // won't dispatch.
6653 var doc = getEventTargetDocument(nativeEventTarget);
6654
6655 if (mouseDown || activeElement$1 == null || activeElement$1 !== getActiveElement(doc)) {
6656 return null;
6657 }
6658
6659 // Only fire when selection has actually changed.
6660 var currentSelection = getSelection(activeElement$1);
6661 if (!lastSelection || !shallowEqual(lastSelection, currentSelection)) {
6662 lastSelection = currentSelection;
6663
6664 var syntheticEvent = SyntheticEvent.getPooled(eventTypes$3.select, activeElementInst$1, nativeEvent, nativeEventTarget);
6665
6666 syntheticEvent.type = 'select';
6667 syntheticEvent.target = activeElement$1;
6668
6669 accumulateTwoPhaseDispatches(syntheticEvent);
6670
6671 return syntheticEvent;
6672 }
6673
6674 return null;
6675}
6676
6677/**
6678 * This plugin creates an `onSelect` event that normalizes select events
6679 * across form elements.
6680 *
6681 * Supported elements are:
6682 * - input (see `isTextInputElement`)
6683 * - textarea
6684 * - contentEditable
6685 *
6686 * This differs from native browser implementations in the following ways:
6687 * - Fires on contentEditable fields as well as inputs.
6688 * - Fires for collapsed selection.
6689 * - Fires after user input.
6690 */
6691var SelectEventPlugin = {
6692 eventTypes: eventTypes$3,
6693
6694 extractEvents: function (topLevelType, targetInst, nativeEvent, nativeEventTarget) {
6695 var doc = getEventTargetDocument(nativeEventTarget);
6696 // Track whether all listeners exists for this plugin. If none exist, we do
6697 // not extract events. See #3639.
6698 if (!doc || !isListeningToAllDependencies('onSelect', doc)) {
6699 return null;
6700 }
6701
6702 var targetNode = targetInst ? getNodeFromInstance$1(targetInst) : window;
6703
6704 switch (topLevelType) {
6705 // Track the input node that has focus.
6706 case TOP_FOCUS:
6707 if (isTextInputElement(targetNode) || targetNode.contentEditable === 'true') {
6708 activeElement$1 = targetNode;
6709 activeElementInst$1 = targetInst;
6710 lastSelection = null;
6711 }
6712 break;
6713 case TOP_BLUR:
6714 activeElement$1 = null;
6715 activeElementInst$1 = null;
6716 lastSelection = null;
6717 break;
6718 // Don't fire the event while the user is dragging. This matches the
6719 // semantics of the native select event.
6720 case TOP_MOUSE_DOWN:
6721 mouseDown = true;
6722 break;
6723 case TOP_CONTEXT_MENU:
6724 case TOP_MOUSE_UP:
6725 case TOP_DRAG_END:
6726 mouseDown = false;
6727 return constructSelectEvent(nativeEvent, nativeEventTarget);
6728 // Chrome and IE fire non-standard event when selection is changed (and
6729 // sometimes when it hasn't). IE's event fires out of order with respect
6730 // to key and input events on deletion, so we discard it.
6731 //
6732 // Firefox doesn't support selectionchange, so check selection status
6733 // after each key entry. The selection changes after keydown and before
6734 // keyup, but we check on keydown as well in the case of holding down a
6735 // key, when multiple keydown events are fired but only one keyup is.
6736 // This is also our approach for IE handling, for the reason above.
6737 case TOP_SELECTION_CHANGE:
6738 if (skipSelectionChangeEvent) {
6739 break;
6740 }
6741 // falls through
6742 case TOP_KEY_DOWN:
6743 case TOP_KEY_UP:
6744 return constructSelectEvent(nativeEvent, nativeEventTarget);
6745 }
6746
6747 return null;
6748 }
6749};
6750
6751/**
6752 * Inject modules for resolving DOM hierarchy and plugin ordering.
6753 */
6754injection.injectEventPluginOrder(DOMEventPluginOrder);
6755setComponentTree(getFiberCurrentPropsFromNode$1, getInstanceFromNode$1, getNodeFromInstance$1);
6756
6757/**
6758 * Some important event plugins included by default (without having to require
6759 * them).
6760 */
6761injection.injectEventPluginsByName({
6762 SimpleEventPlugin: SimpleEventPlugin,
6763 EnterLeaveEventPlugin: EnterLeaveEventPlugin,
6764 ChangeEventPlugin: ChangeEventPlugin,
6765 SelectEventPlugin: SelectEventPlugin,
6766 BeforeInputEventPlugin: BeforeInputEventPlugin
6767});
6768
6769function endsWith(subject, search) {
6770 var length = subject.length;
6771 return subject.substring(length - search.length, length) === search;
6772}
6773
6774var didWarnSelectedSetOnOption = false;
6775var didWarnInvalidChild = false;
6776
6777function flattenChildren(children) {
6778 var content = '';
6779
6780 // Flatten children. We'll warn if they are invalid
6781 // during validateProps() which runs for hydration too.
6782 // Note that this would throw on non-element objects.
6783 // Elements are stringified (which is normally irrelevant
6784 // but matters for <fbt>).
6785 React.Children.forEach(children, function (child) {
6786 if (child == null) {
6787 return;
6788 }
6789 content += child;
6790 // Note: we don't warn about invalid children here.
6791 // Instead, this is done separately below so that
6792 // it happens during the hydration codepath too.
6793 });
6794
6795 return content;
6796}
6797
6798/**
6799 * Implements an <option> host component that warns when `selected` is set.
6800 */
6801
6802function validateProps(element, props) {
6803 {
6804 // This mirrors the codepath above, but runs for hydration too.
6805 // Warn about invalid children here so that client and hydration are consistent.
6806 // TODO: this seems like it could cause a DEV-only throw for hydration
6807 // if children contains a non-element object. We should try to avoid that.
6808 if (typeof props.children === 'object' && props.children !== null) {
6809 React.Children.forEach(props.children, function (child) {
6810 if (child == null) {
6811 return;
6812 }
6813 if (typeof child === 'string' || typeof child === 'number') {
6814 return;
6815 }
6816 if (typeof child.type !== 'string') {
6817 return;
6818 }
6819 if (!didWarnInvalidChild) {
6820 didWarnInvalidChild = true;
6821 warning$1(false, 'Only strings and numbers are supported as <option> children.');
6822 }
6823 });
6824 }
6825
6826 // TODO: Remove support for `selected` in <option>.
6827 if (props.selected != null && !didWarnSelectedSetOnOption) {
6828 warning$1(false, 'Use the `defaultValue` or `value` props on <select> instead of ' + 'setting `selected` on <option>.');
6829 didWarnSelectedSetOnOption = true;
6830 }
6831 }
6832}
6833
6834function postMountWrapper$1(element, props) {
6835 // value="" should make a value attribute (#6219)
6836 if (props.value != null) {
6837 element.setAttribute('value', toString(getToStringValue(props.value)));
6838 }
6839}
6840
6841function getHostProps$1(element, props) {
6842 var hostProps = _assign({ children: undefined }, props);
6843 var content = flattenChildren(props.children);
6844
6845 if (content) {
6846 hostProps.children = content;
6847 }
6848
6849 return hostProps;
6850}
6851
6852// TODO: direct imports like some-package/src/* are bad. Fix me.
6853var didWarnValueDefaultValue$1 = void 0;
6854
6855{
6856 didWarnValueDefaultValue$1 = false;
6857}
6858
6859function getDeclarationErrorAddendum() {
6860 var ownerName = getCurrentFiberOwnerNameInDevOrNull();
6861 if (ownerName) {
6862 return '\n\nCheck the render method of `' + ownerName + '`.';
6863 }
6864 return '';
6865}
6866
6867var valuePropNames = ['value', 'defaultValue'];
6868
6869/**
6870 * Validation function for `value` and `defaultValue`.
6871 */
6872function checkSelectPropTypes(props) {
6873 ReactControlledValuePropTypes.checkPropTypes('select', props);
6874
6875 for (var i = 0; i < valuePropNames.length; i++) {
6876 var propName = valuePropNames[i];
6877 if (props[propName] == null) {
6878 continue;
6879 }
6880 var isArray = Array.isArray(props[propName]);
6881 if (props.multiple && !isArray) {
6882 warning$1(false, 'The `%s` prop supplied to <select> must be an array if ' + '`multiple` is true.%s', propName, getDeclarationErrorAddendum());
6883 } else if (!props.multiple && isArray) {
6884 warning$1(false, 'The `%s` prop supplied to <select> must be a scalar ' + 'value if `multiple` is false.%s', propName, getDeclarationErrorAddendum());
6885 }
6886 }
6887}
6888
6889function updateOptions(node, multiple, propValue, setDefaultSelected) {
6890 var options = node.options;
6891
6892 if (multiple) {
6893 var selectedValues = propValue;
6894 var selectedValue = {};
6895 for (var i = 0; i < selectedValues.length; i++) {
6896 // Prefix to avoid chaos with special keys.
6897 selectedValue['$' + selectedValues[i]] = true;
6898 }
6899 for (var _i = 0; _i < options.length; _i++) {
6900 var selected = selectedValue.hasOwnProperty('$' + options[_i].value);
6901 if (options[_i].selected !== selected) {
6902 options[_i].selected = selected;
6903 }
6904 if (selected && setDefaultSelected) {
6905 options[_i].defaultSelected = true;
6906 }
6907 }
6908 } else {
6909 // Do not set `select.value` as exact behavior isn't consistent across all
6910 // browsers for all cases.
6911 var _selectedValue = toString(getToStringValue(propValue));
6912 var defaultSelected = null;
6913 for (var _i2 = 0; _i2 < options.length; _i2++) {
6914 if (options[_i2].value === _selectedValue) {
6915 options[_i2].selected = true;
6916 if (setDefaultSelected) {
6917 options[_i2].defaultSelected = true;
6918 }
6919 return;
6920 }
6921 if (defaultSelected === null && !options[_i2].disabled) {
6922 defaultSelected = options[_i2];
6923 }
6924 }
6925 if (defaultSelected !== null) {
6926 defaultSelected.selected = true;
6927 }
6928 }
6929}
6930
6931/**
6932 * Implements a <select> host component that allows optionally setting the
6933 * props `value` and `defaultValue`. If `multiple` is false, the prop must be a
6934 * stringable. If `multiple` is true, the prop must be an array of stringables.
6935 *
6936 * If `value` is not supplied (or null/undefined), user actions that change the
6937 * selected option will trigger updates to the rendered options.
6938 *
6939 * If it is supplied (and not null/undefined), the rendered options will not
6940 * update in response to user actions. Instead, the `value` prop must change in
6941 * order for the rendered options to update.
6942 *
6943 * If `defaultValue` is provided, any options with the supplied values will be
6944 * selected.
6945 */
6946
6947function getHostProps$2(element, props) {
6948 return _assign({}, props, {
6949 value: undefined
6950 });
6951}
6952
6953function initWrapperState$1(element, props) {
6954 var node = element;
6955 {
6956 checkSelectPropTypes(props);
6957 }
6958
6959 node._wrapperState = {
6960 wasMultiple: !!props.multiple
6961 };
6962
6963 {
6964 if (props.value !== undefined && props.defaultValue !== undefined && !didWarnValueDefaultValue$1) {
6965 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');
6966 didWarnValueDefaultValue$1 = true;
6967 }
6968 }
6969}
6970
6971function postMountWrapper$2(element, props) {
6972 var node = element;
6973 node.multiple = !!props.multiple;
6974 var value = props.value;
6975 if (value != null) {
6976 updateOptions(node, !!props.multiple, value, false);
6977 } else if (props.defaultValue != null) {
6978 updateOptions(node, !!props.multiple, props.defaultValue, true);
6979 }
6980}
6981
6982function postUpdateWrapper(element, props) {
6983 var node = element;
6984 var wasMultiple = node._wrapperState.wasMultiple;
6985 node._wrapperState.wasMultiple = !!props.multiple;
6986
6987 var value = props.value;
6988 if (value != null) {
6989 updateOptions(node, !!props.multiple, value, false);
6990 } else if (wasMultiple !== !!props.multiple) {
6991 // For simplicity, reapply `defaultValue` if `multiple` is toggled.
6992 if (props.defaultValue != null) {
6993 updateOptions(node, !!props.multiple, props.defaultValue, true);
6994 } else {
6995 // Revert the select back to its default unselected state.
6996 updateOptions(node, !!props.multiple, props.multiple ? [] : '', false);
6997 }
6998 }
6999}
7000
7001function restoreControlledState$2(element, props) {
7002 var node = element;
7003 var value = props.value;
7004
7005 if (value != null) {
7006 updateOptions(node, !!props.multiple, value, false);
7007 }
7008}
7009
7010var didWarnValDefaultVal = false;
7011
7012/**
7013 * Implements a <textarea> host component that allows setting `value`, and
7014 * `defaultValue`. This differs from the traditional DOM API because value is
7015 * usually set as PCDATA children.
7016 *
7017 * If `value` is not supplied (or null/undefined), user actions that affect the
7018 * value will trigger updates to the element.
7019 *
7020 * If `value` is supplied (and not null/undefined), the rendered element will
7021 * not trigger updates to the element. Instead, the `value` prop must change in
7022 * order for the rendered element to be updated.
7023 *
7024 * The rendered element will be initialized with an empty value, the prop
7025 * `defaultValue` if specified, or the children content (deprecated).
7026 */
7027
7028function getHostProps$3(element, props) {
7029 var node = element;
7030 (function () {
7031 if (!(props.dangerouslySetInnerHTML == null)) {
7032 {
7033 throw ReactError(Error('`dangerouslySetInnerHTML` does not make sense on <textarea>.'));
7034 }
7035 }
7036 })();
7037
7038 // Always set children to the same thing. In IE9, the selection range will
7039 // get reset if `textContent` is mutated. We could add a check in setTextContent
7040 // to only set the value if/when the value differs from the node value (which would
7041 // completely solve this IE9 bug), but Sebastian+Sophie seemed to like this
7042 // solution. The value can be a boolean or object so that's why it's forced
7043 // to be a string.
7044 var hostProps = _assign({}, props, {
7045 value: undefined,
7046 defaultValue: undefined,
7047 children: toString(node._wrapperState.initialValue)
7048 });
7049
7050 return hostProps;
7051}
7052
7053function initWrapperState$2(element, props) {
7054 var node = element;
7055 {
7056 ReactControlledValuePropTypes.checkPropTypes('textarea', props);
7057 if (props.value !== undefined && props.defaultValue !== undefined && !didWarnValDefaultVal) {
7058 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');
7059 didWarnValDefaultVal = true;
7060 }
7061 }
7062
7063 var initialValue = props.value;
7064
7065 // Only bother fetching default value if we're going to use it
7066 if (initialValue == null) {
7067 var defaultValue = props.defaultValue;
7068 // TODO (yungsters): Remove support for children content in <textarea>.
7069 var children = props.children;
7070 if (children != null) {
7071 {
7072 warning$1(false, 'Use the `defaultValue` or `value` props instead of setting ' + 'children on <textarea>.');
7073 }
7074 (function () {
7075 if (!(defaultValue == null)) {
7076 {
7077 throw ReactError(Error('If you supply `defaultValue` on a <textarea>, do not pass children.'));
7078 }
7079 }
7080 })();
7081 if (Array.isArray(children)) {
7082 (function () {
7083 if (!(children.length <= 1)) {
7084 {
7085 throw ReactError(Error('<textarea> can only have at most one child.'));
7086 }
7087 }
7088 })();
7089 children = children[0];
7090 }
7091
7092 defaultValue = children;
7093 }
7094 if (defaultValue == null) {
7095 defaultValue = '';
7096 }
7097 initialValue = defaultValue;
7098 }
7099
7100 node._wrapperState = {
7101 initialValue: getToStringValue(initialValue)
7102 };
7103}
7104
7105function updateWrapper$1(element, props) {
7106 var node = element;
7107 var value = getToStringValue(props.value);
7108 var defaultValue = getToStringValue(props.defaultValue);
7109 if (value != null) {
7110 // Cast `value` to a string to ensure the value is set correctly. While
7111 // browsers typically do this as necessary, jsdom doesn't.
7112 var newValue = toString(value);
7113 // To avoid side effects (such as losing text selection), only set value if changed
7114 if (newValue !== node.value) {
7115 node.value = newValue;
7116 }
7117 if (props.defaultValue == null && node.defaultValue !== newValue) {
7118 node.defaultValue = newValue;
7119 }
7120 }
7121 if (defaultValue != null) {
7122 node.defaultValue = toString(defaultValue);
7123 }
7124}
7125
7126function postMountWrapper$3(element, props) {
7127 var node = element;
7128 // This is in postMount because we need access to the DOM node, which is not
7129 // available until after the component has mounted.
7130 var textContent = node.textContent;
7131
7132 // Only set node.value if textContent is equal to the expected
7133 // initial value. In IE10/IE11 there is a bug where the placeholder attribute
7134 // will populate textContent as well.
7135 // https://developer.microsoft.com/microsoft-edge/platform/issues/101525/
7136 if (textContent === node._wrapperState.initialValue) {
7137 node.value = textContent;
7138 }
7139}
7140
7141function restoreControlledState$3(element, props) {
7142 // DOM component is still mounted; update
7143 updateWrapper$1(element, props);
7144}
7145
7146var HTML_NAMESPACE$1 = 'http://www.w3.org/1999/xhtml';
7147var MATH_NAMESPACE = 'http://www.w3.org/1998/Math/MathML';
7148var SVG_NAMESPACE = 'http://www.w3.org/2000/svg';
7149
7150var Namespaces = {
7151 html: HTML_NAMESPACE$1,
7152 mathml: MATH_NAMESPACE,
7153 svg: SVG_NAMESPACE
7154};
7155
7156// Assumes there is no parent namespace.
7157function getIntrinsicNamespace(type) {
7158 switch (type) {
7159 case 'svg':
7160 return SVG_NAMESPACE;
7161 case 'math':
7162 return MATH_NAMESPACE;
7163 default:
7164 return HTML_NAMESPACE$1;
7165 }
7166}
7167
7168function getChildNamespace(parentNamespace, type) {
7169 if (parentNamespace == null || parentNamespace === HTML_NAMESPACE$1) {
7170 // No (or default) parent namespace: potential entry point.
7171 return getIntrinsicNamespace(type);
7172 }
7173 if (parentNamespace === SVG_NAMESPACE && type === 'foreignObject') {
7174 // We're leaving SVG.
7175 return HTML_NAMESPACE$1;
7176 }
7177 // By default, pass namespace below.
7178 return parentNamespace;
7179}
7180
7181/* globals MSApp */
7182
7183/**
7184 * Create a function which has 'unsafe' privileges (required by windows8 apps)
7185 */
7186var createMicrosoftUnsafeLocalFunction = function (func) {
7187 if (typeof MSApp !== 'undefined' && MSApp.execUnsafeLocalFunction) {
7188 return function (arg0, arg1, arg2, arg3) {
7189 MSApp.execUnsafeLocalFunction(function () {
7190 return func(arg0, arg1, arg2, arg3);
7191 });
7192 };
7193 } else {
7194 return func;
7195 }
7196};
7197
7198// SVG temp container for IE lacking innerHTML
7199var reusableSVGContainer = void 0;
7200
7201/**
7202 * Set the innerHTML property of a node
7203 *
7204 * @param {DOMElement} node
7205 * @param {string} html
7206 * @internal
7207 */
7208var setInnerHTML = createMicrosoftUnsafeLocalFunction(function (node, html) {
7209 // IE does not have innerHTML for SVG nodes, so instead we inject the
7210 // new markup in a temp node and then move the child nodes across into
7211 // the target node
7212
7213 if (node.namespaceURI === Namespaces.svg && !('innerHTML' in node)) {
7214 reusableSVGContainer = reusableSVGContainer || document.createElement('div');
7215 reusableSVGContainer.innerHTML = '<svg>' + html + '</svg>';
7216 var svgNode = reusableSVGContainer.firstChild;
7217 while (node.firstChild) {
7218 node.removeChild(node.firstChild);
7219 }
7220 while (svgNode.firstChild) {
7221 node.appendChild(svgNode.firstChild);
7222 }
7223 } else {
7224 node.innerHTML = html;
7225 }
7226});
7227
7228/**
7229 * Set the textContent property of a node. For text updates, it's faster
7230 * to set the `nodeValue` of the Text node directly instead of using
7231 * `.textContent` which will remove the existing node and create a new one.
7232 *
7233 * @param {DOMElement} node
7234 * @param {string} text
7235 * @internal
7236 */
7237var setTextContent = function (node, text) {
7238 if (text) {
7239 var firstChild = node.firstChild;
7240
7241 if (firstChild && firstChild === node.lastChild && firstChild.nodeType === TEXT_NODE) {
7242 firstChild.nodeValue = text;
7243 return;
7244 }
7245 }
7246 node.textContent = text;
7247};
7248
7249// List derived from Gecko source code:
7250// https://github.com/mozilla/gecko-dev/blob/4e638efc71/layout/style/test/property_database.js
7251var shorthandToLonghand = {
7252 animation: ['animationDelay', 'animationDirection', 'animationDuration', 'animationFillMode', 'animationIterationCount', 'animationName', 'animationPlayState', 'animationTimingFunction'],
7253 background: ['backgroundAttachment', 'backgroundClip', 'backgroundColor', 'backgroundImage', 'backgroundOrigin', 'backgroundPositionX', 'backgroundPositionY', 'backgroundRepeat', 'backgroundSize'],
7254 backgroundPosition: ['backgroundPositionX', 'backgroundPositionY'],
7255 border: ['borderBottomColor', 'borderBottomStyle', 'borderBottomWidth', 'borderImageOutset', 'borderImageRepeat', 'borderImageSlice', 'borderImageSource', 'borderImageWidth', 'borderLeftColor', 'borderLeftStyle', 'borderLeftWidth', 'borderRightColor', 'borderRightStyle', 'borderRightWidth', 'borderTopColor', 'borderTopStyle', 'borderTopWidth'],
7256 borderBlockEnd: ['borderBlockEndColor', 'borderBlockEndStyle', 'borderBlockEndWidth'],
7257 borderBlockStart: ['borderBlockStartColor', 'borderBlockStartStyle', 'borderBlockStartWidth'],
7258 borderBottom: ['borderBottomColor', 'borderBottomStyle', 'borderBottomWidth'],
7259 borderColor: ['borderBottomColor', 'borderLeftColor', 'borderRightColor', 'borderTopColor'],
7260 borderImage: ['borderImageOutset', 'borderImageRepeat', 'borderImageSlice', 'borderImageSource', 'borderImageWidth'],
7261 borderInlineEnd: ['borderInlineEndColor', 'borderInlineEndStyle', 'borderInlineEndWidth'],
7262 borderInlineStart: ['borderInlineStartColor', 'borderInlineStartStyle', 'borderInlineStartWidth'],
7263 borderLeft: ['borderLeftColor', 'borderLeftStyle', 'borderLeftWidth'],
7264 borderRadius: ['borderBottomLeftRadius', 'borderBottomRightRadius', 'borderTopLeftRadius', 'borderTopRightRadius'],
7265 borderRight: ['borderRightColor', 'borderRightStyle', 'borderRightWidth'],
7266 borderStyle: ['borderBottomStyle', 'borderLeftStyle', 'borderRightStyle', 'borderTopStyle'],
7267 borderTop: ['borderTopColor', 'borderTopStyle', 'borderTopWidth'],
7268 borderWidth: ['borderBottomWidth', 'borderLeftWidth', 'borderRightWidth', 'borderTopWidth'],
7269 columnRule: ['columnRuleColor', 'columnRuleStyle', 'columnRuleWidth'],
7270 columns: ['columnCount', 'columnWidth'],
7271 flex: ['flexBasis', 'flexGrow', 'flexShrink'],
7272 flexFlow: ['flexDirection', 'flexWrap'],
7273 font: ['fontFamily', 'fontFeatureSettings', 'fontKerning', 'fontLanguageOverride', 'fontSize', 'fontSizeAdjust', 'fontStretch', 'fontStyle', 'fontVariant', 'fontVariantAlternates', 'fontVariantCaps', 'fontVariantEastAsian', 'fontVariantLigatures', 'fontVariantNumeric', 'fontVariantPosition', 'fontWeight', 'lineHeight'],
7274 fontVariant: ['fontVariantAlternates', 'fontVariantCaps', 'fontVariantEastAsian', 'fontVariantLigatures', 'fontVariantNumeric', 'fontVariantPosition'],
7275 gap: ['columnGap', 'rowGap'],
7276 grid: ['gridAutoColumns', 'gridAutoFlow', 'gridAutoRows', 'gridTemplateAreas', 'gridTemplateColumns', 'gridTemplateRows'],
7277 gridArea: ['gridColumnEnd', 'gridColumnStart', 'gridRowEnd', 'gridRowStart'],
7278 gridColumn: ['gridColumnEnd', 'gridColumnStart'],
7279 gridColumnGap: ['columnGap'],
7280 gridGap: ['columnGap', 'rowGap'],
7281 gridRow: ['gridRowEnd', 'gridRowStart'],
7282 gridRowGap: ['rowGap'],
7283 gridTemplate: ['gridTemplateAreas', 'gridTemplateColumns', 'gridTemplateRows'],
7284 listStyle: ['listStyleImage', 'listStylePosition', 'listStyleType'],
7285 margin: ['marginBottom', 'marginLeft', 'marginRight', 'marginTop'],
7286 marker: ['markerEnd', 'markerMid', 'markerStart'],
7287 mask: ['maskClip', 'maskComposite', 'maskImage', 'maskMode', 'maskOrigin', 'maskPositionX', 'maskPositionY', 'maskRepeat', 'maskSize'],
7288 maskPosition: ['maskPositionX', 'maskPositionY'],
7289 outline: ['outlineColor', 'outlineStyle', 'outlineWidth'],
7290 overflow: ['overflowX', 'overflowY'],
7291 padding: ['paddingBottom', 'paddingLeft', 'paddingRight', 'paddingTop'],
7292 placeContent: ['alignContent', 'justifyContent'],
7293 placeItems: ['alignItems', 'justifyItems'],
7294 placeSelf: ['alignSelf', 'justifySelf'],
7295 textDecoration: ['textDecorationColor', 'textDecorationLine', 'textDecorationStyle'],
7296 textEmphasis: ['textEmphasisColor', 'textEmphasisStyle'],
7297 transition: ['transitionDelay', 'transitionDuration', 'transitionProperty', 'transitionTimingFunction'],
7298 wordWrap: ['overflowWrap']
7299};
7300
7301/**
7302 * CSS properties which accept numbers but are not in units of "px".
7303 */
7304var isUnitlessNumber = {
7305 animationIterationCount: true,
7306 borderImageOutset: true,
7307 borderImageSlice: true,
7308 borderImageWidth: true,
7309 boxFlex: true,
7310 boxFlexGroup: true,
7311 boxOrdinalGroup: true,
7312 columnCount: true,
7313 columns: true,
7314 flex: true,
7315 flexGrow: true,
7316 flexPositive: true,
7317 flexShrink: true,
7318 flexNegative: true,
7319 flexOrder: true,
7320 gridArea: true,
7321 gridRow: true,
7322 gridRowEnd: true,
7323 gridRowSpan: true,
7324 gridRowStart: true,
7325 gridColumn: true,
7326 gridColumnEnd: true,
7327 gridColumnSpan: true,
7328 gridColumnStart: true,
7329 fontWeight: true,
7330 lineClamp: true,
7331 lineHeight: true,
7332 opacity: true,
7333 order: true,
7334 orphans: true,
7335 tabSize: true,
7336 widows: true,
7337 zIndex: true,
7338 zoom: true,
7339
7340 // SVG-related properties
7341 fillOpacity: true,
7342 floodOpacity: true,
7343 stopOpacity: true,
7344 strokeDasharray: true,
7345 strokeDashoffset: true,
7346 strokeMiterlimit: true,
7347 strokeOpacity: true,
7348 strokeWidth: true
7349};
7350
7351/**
7352 * @param {string} prefix vendor-specific prefix, eg: Webkit
7353 * @param {string} key style name, eg: transitionDuration
7354 * @return {string} style name prefixed with `prefix`, properly camelCased, eg:
7355 * WebkitTransitionDuration
7356 */
7357function prefixKey(prefix, key) {
7358 return prefix + key.charAt(0).toUpperCase() + key.substring(1);
7359}
7360
7361/**
7362 * Support style names that may come passed in prefixed by adding permutations
7363 * of vendor prefixes.
7364 */
7365var prefixes = ['Webkit', 'ms', 'Moz', 'O'];
7366
7367// Using Object.keys here, or else the vanilla for-in loop makes IE8 go into an
7368// infinite loop, because it iterates over the newly added props too.
7369Object.keys(isUnitlessNumber).forEach(function (prop) {
7370 prefixes.forEach(function (prefix) {
7371 isUnitlessNumber[prefixKey(prefix, prop)] = isUnitlessNumber[prop];
7372 });
7373});
7374
7375/**
7376 * Convert a value into the proper css writable value. The style name `name`
7377 * should be logical (no hyphens), as specified
7378 * in `CSSProperty.isUnitlessNumber`.
7379 *
7380 * @param {string} name CSS property name such as `topMargin`.
7381 * @param {*} value CSS property value such as `10px`.
7382 * @return {string} Normalized style value with dimensions applied.
7383 */
7384function dangerousStyleValue(name, value, isCustomProperty) {
7385 // Note that we've removed escapeTextForBrowser() calls here since the
7386 // whole string will be escaped when the attribute is injected into
7387 // the markup. If you provide unsafe user data here they can inject
7388 // arbitrary CSS which may be problematic (I couldn't repro this):
7389 // https://www.owasp.org/index.php/XSS_Filter_Evasion_Cheat_Sheet
7390 // http://www.thespanner.co.uk/2007/11/26/ultimate-xss-css-injection/
7391 // This is not an XSS hole but instead a potential CSS injection issue
7392 // which has lead to a greater discussion about how we're going to
7393 // trust URLs moving forward. See #2115901
7394
7395 var isEmpty = value == null || typeof value === 'boolean' || value === '';
7396 if (isEmpty) {
7397 return '';
7398 }
7399
7400 if (!isCustomProperty && typeof value === 'number' && value !== 0 && !(isUnitlessNumber.hasOwnProperty(name) && isUnitlessNumber[name])) {
7401 return value + 'px'; // Presumes implicit 'px' suffix for unitless numbers
7402 }
7403
7404 return ('' + value).trim();
7405}
7406
7407var uppercasePattern = /([A-Z])/g;
7408var msPattern = /^ms-/;
7409
7410/**
7411 * Hyphenates a camelcased CSS property name, for example:
7412 *
7413 * > hyphenateStyleName('backgroundColor')
7414 * < "background-color"
7415 * > hyphenateStyleName('MozTransition')
7416 * < "-moz-transition"
7417 * > hyphenateStyleName('msTransition')
7418 * < "-ms-transition"
7419 *
7420 * As Modernizr suggests (http://modernizr.com/docs/#prefixed), an `ms` prefix
7421 * is converted to `-ms-`.
7422 */
7423function hyphenateStyleName(name) {
7424 return name.replace(uppercasePattern, '-$1').toLowerCase().replace(msPattern, '-ms-');
7425}
7426
7427var warnValidStyle = function () {};
7428
7429{
7430 // 'msTransform' is correct, but the other prefixes should be capitalized
7431 var badVendoredStyleNamePattern = /^(?:webkit|moz|o)[A-Z]/;
7432 var msPattern$1 = /^-ms-/;
7433 var hyphenPattern = /-(.)/g;
7434
7435 // style values shouldn't contain a semicolon
7436 var badStyleValueWithSemicolonPattern = /;\s*$/;
7437
7438 var warnedStyleNames = {};
7439 var warnedStyleValues = {};
7440 var warnedForNaNValue = false;
7441 var warnedForInfinityValue = false;
7442
7443 var camelize = function (string) {
7444 return string.replace(hyphenPattern, function (_, character) {
7445 return character.toUpperCase();
7446 });
7447 };
7448
7449 var warnHyphenatedStyleName = function (name) {
7450 if (warnedStyleNames.hasOwnProperty(name) && warnedStyleNames[name]) {
7451 return;
7452 }
7453
7454 warnedStyleNames[name] = true;
7455 warning$1(false, 'Unsupported style property %s. Did you mean %s?', name,
7456 // As Andi Smith suggests
7457 // (http://www.andismith.com/blog/2012/02/modernizr-prefixed/), an `-ms` prefix
7458 // is converted to lowercase `ms`.
7459 camelize(name.replace(msPattern$1, 'ms-')));
7460 };
7461
7462 var warnBadVendoredStyleName = function (name) {
7463 if (warnedStyleNames.hasOwnProperty(name) && warnedStyleNames[name]) {
7464 return;
7465 }
7466
7467 warnedStyleNames[name] = true;
7468 warning$1(false, 'Unsupported vendor-prefixed style property %s. Did you mean %s?', name, name.charAt(0).toUpperCase() + name.slice(1));
7469 };
7470
7471 var warnStyleValueWithSemicolon = function (name, value) {
7472 if (warnedStyleValues.hasOwnProperty(value) && warnedStyleValues[value]) {
7473 return;
7474 }
7475
7476 warnedStyleValues[value] = true;
7477 warning$1(false, "Style property values shouldn't contain a semicolon. " + 'Try "%s: %s" instead.', name, value.replace(badStyleValueWithSemicolonPattern, ''));
7478 };
7479
7480 var warnStyleValueIsNaN = function (name, value) {
7481 if (warnedForNaNValue) {
7482 return;
7483 }
7484
7485 warnedForNaNValue = true;
7486 warning$1(false, '`NaN` is an invalid value for the `%s` css style property.', name);
7487 };
7488
7489 var warnStyleValueIsInfinity = function (name, value) {
7490 if (warnedForInfinityValue) {
7491 return;
7492 }
7493
7494 warnedForInfinityValue = true;
7495 warning$1(false, '`Infinity` is an invalid value for the `%s` css style property.', name);
7496 };
7497
7498 warnValidStyle = function (name, value) {
7499 if (name.indexOf('-') > -1) {
7500 warnHyphenatedStyleName(name);
7501 } else if (badVendoredStyleNamePattern.test(name)) {
7502 warnBadVendoredStyleName(name);
7503 } else if (badStyleValueWithSemicolonPattern.test(value)) {
7504 warnStyleValueWithSemicolon(name, value);
7505 }
7506
7507 if (typeof value === 'number') {
7508 if (isNaN(value)) {
7509 warnStyleValueIsNaN(name, value);
7510 } else if (!isFinite(value)) {
7511 warnStyleValueIsInfinity(name, value);
7512 }
7513 }
7514 };
7515}
7516
7517var warnValidStyle$1 = warnValidStyle;
7518
7519/**
7520 * Operations for dealing with CSS properties.
7521 */
7522
7523/**
7524 * This creates a string that is expected to be equivalent to the style
7525 * attribute generated by server-side rendering. It by-passes warnings and
7526 * security checks so it's not safe to use this value for anything other than
7527 * comparison. It is only used in DEV for SSR validation.
7528 */
7529function createDangerousStringForStyles(styles) {
7530 {
7531 var serialized = '';
7532 var delimiter = '';
7533 for (var styleName in styles) {
7534 if (!styles.hasOwnProperty(styleName)) {
7535 continue;
7536 }
7537 var styleValue = styles[styleName];
7538 if (styleValue != null) {
7539 var isCustomProperty = styleName.indexOf('--') === 0;
7540 serialized += delimiter + (isCustomProperty ? styleName : hyphenateStyleName(styleName)) + ':';
7541 serialized += dangerousStyleValue(styleName, styleValue, isCustomProperty);
7542
7543 delimiter = ';';
7544 }
7545 }
7546 return serialized || null;
7547 }
7548}
7549
7550/**
7551 * Sets the value for multiple styles on a node. If a value is specified as
7552 * '' (empty string), the corresponding style property will be unset.
7553 *
7554 * @param {DOMElement} node
7555 * @param {object} styles
7556 */
7557function setValueForStyles(node, styles) {
7558 var style = node.style;
7559 for (var styleName in styles) {
7560 if (!styles.hasOwnProperty(styleName)) {
7561 continue;
7562 }
7563 var isCustomProperty = styleName.indexOf('--') === 0;
7564 {
7565 if (!isCustomProperty) {
7566 warnValidStyle$1(styleName, styles[styleName]);
7567 }
7568 }
7569 var styleValue = dangerousStyleValue(styleName, styles[styleName], isCustomProperty);
7570 if (styleName === 'float') {
7571 styleName = 'cssFloat';
7572 }
7573 if (isCustomProperty) {
7574 style.setProperty(styleName, styleValue);
7575 } else {
7576 style[styleName] = styleValue;
7577 }
7578 }
7579}
7580
7581function isValueEmpty(value) {
7582 return value == null || typeof value === 'boolean' || value === '';
7583}
7584
7585/**
7586 * Given {color: 'red', overflow: 'hidden'} returns {
7587 * color: 'color',
7588 * overflowX: 'overflow',
7589 * overflowY: 'overflow',
7590 * }. This can be read as "the overflowY property was set by the overflow
7591 * shorthand". That is, the values are the property that each was derived from.
7592 */
7593function expandShorthandMap(styles) {
7594 var expanded = {};
7595 for (var key in styles) {
7596 var longhands = shorthandToLonghand[key] || [key];
7597 for (var i = 0; i < longhands.length; i++) {
7598 expanded[longhands[i]] = key;
7599 }
7600 }
7601 return expanded;
7602}
7603
7604/**
7605 * When mixing shorthand and longhand property names, we warn during updates if
7606 * we expect an incorrect result to occur. In particular, we warn for:
7607 *
7608 * Updating a shorthand property (longhand gets overwritten):
7609 * {font: 'foo', fontVariant: 'bar'} -> {font: 'baz', fontVariant: 'bar'}
7610 * becomes .style.font = 'baz'
7611 * Removing a shorthand property (longhand gets lost too):
7612 * {font: 'foo', fontVariant: 'bar'} -> {fontVariant: 'bar'}
7613 * becomes .style.font = ''
7614 * Removing a longhand property (should revert to shorthand; doesn't):
7615 * {font: 'foo', fontVariant: 'bar'} -> {font: 'foo'}
7616 * becomes .style.fontVariant = ''
7617 */
7618function validateShorthandPropertyCollisionInDev(styleUpdates, nextStyles) {
7619 if (!warnAboutShorthandPropertyCollision) {
7620 return;
7621 }
7622
7623 if (!nextStyles) {
7624 return;
7625 }
7626
7627 var expandedUpdates = expandShorthandMap(styleUpdates);
7628 var expandedStyles = expandShorthandMap(nextStyles);
7629 var warnedAbout = {};
7630 for (var key in expandedUpdates) {
7631 var originalKey = expandedUpdates[key];
7632 var correctOriginalKey = expandedStyles[key];
7633 if (correctOriginalKey && originalKey !== correctOriginalKey) {
7634 var warningKey = originalKey + ',' + correctOriginalKey;
7635 if (warnedAbout[warningKey]) {
7636 continue;
7637 }
7638 warnedAbout[warningKey] = true;
7639 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);
7640 }
7641 }
7642}
7643
7644// For HTML, certain tags should omit their close tag. We keep a whitelist for
7645// those special-case tags.
7646
7647var omittedCloseTags = {
7648 area: true,
7649 base: true,
7650 br: true,
7651 col: true,
7652 embed: true,
7653 hr: true,
7654 img: true,
7655 input: true,
7656 keygen: true,
7657 link: true,
7658 meta: true,
7659 param: true,
7660 source: true,
7661 track: true,
7662 wbr: true
7663 // NOTE: menuitem's close tag should be omitted, but that causes problems.
7664};
7665
7666// For HTML, certain tags cannot have children. This has the same purpose as
7667// `omittedCloseTags` except that `menuitem` should still have its closing tag.
7668
7669var voidElementTags = _assign({
7670 menuitem: true
7671}, omittedCloseTags);
7672
7673// TODO: We can remove this if we add invariantWithStack()
7674// or add stack by default to invariants where possible.
7675var HTML$1 = '__html';
7676
7677var ReactDebugCurrentFrame$3 = null;
7678{
7679 ReactDebugCurrentFrame$3 = ReactSharedInternals.ReactDebugCurrentFrame;
7680}
7681
7682function assertValidProps(tag, props) {
7683 if (!props) {
7684 return;
7685 }
7686 // Note the use of `==` which checks for null or undefined.
7687 if (voidElementTags[tag]) {
7688 (function () {
7689 if (!(props.children == null && props.dangerouslySetInnerHTML == null)) {
7690 {
7691 throw ReactError(Error(tag + ' is a void element tag and must neither have `children` nor use `dangerouslySetInnerHTML`.' + (ReactDebugCurrentFrame$3.getStackAddendum())));
7692 }
7693 }
7694 })();
7695 }
7696 if (props.dangerouslySetInnerHTML != null) {
7697 (function () {
7698 if (!(props.children == null)) {
7699 {
7700 throw ReactError(Error('Can only set one of `children` or `props.dangerouslySetInnerHTML`.'));
7701 }
7702 }
7703 })();
7704 (function () {
7705 if (!(typeof props.dangerouslySetInnerHTML === 'object' && HTML$1 in props.dangerouslySetInnerHTML)) {
7706 {
7707 throw ReactError(Error('`props.dangerouslySetInnerHTML` must be in the form `{__html: ...}`. Please visit https://fb.me/react-invariant-dangerously-set-inner-html for more information.'));
7708 }
7709 }
7710 })();
7711 }
7712 {
7713 !(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;
7714 }
7715 (function () {
7716 if (!(props.style == null || typeof props.style === 'object')) {
7717 {
7718 throw ReactError(Error('The `style` prop expects a mapping from style properties to values, not a string. For example, style={{marginRight: spacing + \'em\'}} when using JSX.' + (ReactDebugCurrentFrame$3.getStackAddendum())));
7719 }
7720 }
7721 })();
7722}
7723
7724function isCustomComponent(tagName, props) {
7725 if (tagName.indexOf('-') === -1) {
7726 return typeof props.is === 'string';
7727 }
7728 switch (tagName) {
7729 // These are reserved SVG and MathML elements.
7730 // We don't mind this whitelist too much because we expect it to never grow.
7731 // The alternative is to track the namespace in a few places which is convoluted.
7732 // https://w3c.github.io/webcomponents/spec/custom/#custom-elements-core-concepts
7733 case 'annotation-xml':
7734 case 'color-profile':
7735 case 'font-face':
7736 case 'font-face-src':
7737 case 'font-face-uri':
7738 case 'font-face-format':
7739 case 'font-face-name':
7740 case 'missing-glyph':
7741 return false;
7742 default:
7743 return true;
7744 }
7745}
7746
7747// When adding attributes to the HTML or SVG whitelist, be sure to
7748// also add them to this module to ensure casing and incorrect name
7749// warnings.
7750var possibleStandardNames = {
7751 // HTML
7752 accept: 'accept',
7753 acceptcharset: 'acceptCharset',
7754 'accept-charset': 'acceptCharset',
7755 accesskey: 'accessKey',
7756 action: 'action',
7757 allowfullscreen: 'allowFullScreen',
7758 alt: 'alt',
7759 as: 'as',
7760 async: 'async',
7761 autocapitalize: 'autoCapitalize',
7762 autocomplete: 'autoComplete',
7763 autocorrect: 'autoCorrect',
7764 autofocus: 'autoFocus',
7765 autoplay: 'autoPlay',
7766 autosave: 'autoSave',
7767 capture: 'capture',
7768 cellpadding: 'cellPadding',
7769 cellspacing: 'cellSpacing',
7770 challenge: 'challenge',
7771 charset: 'charSet',
7772 checked: 'checked',
7773 children: 'children',
7774 cite: 'cite',
7775 class: 'className',
7776 classid: 'classID',
7777 classname: 'className',
7778 cols: 'cols',
7779 colspan: 'colSpan',
7780 content: 'content',
7781 contenteditable: 'contentEditable',
7782 contextmenu: 'contextMenu',
7783 controls: 'controls',
7784 controlslist: 'controlsList',
7785 coords: 'coords',
7786 crossorigin: 'crossOrigin',
7787 dangerouslysetinnerhtml: 'dangerouslySetInnerHTML',
7788 data: 'data',
7789 datetime: 'dateTime',
7790 default: 'default',
7791 defaultchecked: 'defaultChecked',
7792 defaultvalue: 'defaultValue',
7793 defer: 'defer',
7794 dir: 'dir',
7795 disabled: 'disabled',
7796 disablepictureinpicture: 'disablePictureInPicture',
7797 download: 'download',
7798 draggable: 'draggable',
7799 enctype: 'encType',
7800 for: 'htmlFor',
7801 form: 'form',
7802 formmethod: 'formMethod',
7803 formaction: 'formAction',
7804 formenctype: 'formEncType',
7805 formnovalidate: 'formNoValidate',
7806 formtarget: 'formTarget',
7807 frameborder: 'frameBorder',
7808 headers: 'headers',
7809 height: 'height',
7810 hidden: 'hidden',
7811 high: 'high',
7812 href: 'href',
7813 hreflang: 'hrefLang',
7814 htmlfor: 'htmlFor',
7815 httpequiv: 'httpEquiv',
7816 'http-equiv': 'httpEquiv',
7817 icon: 'icon',
7818 id: 'id',
7819 innerhtml: 'innerHTML',
7820 inputmode: 'inputMode',
7821 integrity: 'integrity',
7822 is: 'is',
7823 itemid: 'itemID',
7824 itemprop: 'itemProp',
7825 itemref: 'itemRef',
7826 itemscope: 'itemScope',
7827 itemtype: 'itemType',
7828 keyparams: 'keyParams',
7829 keytype: 'keyType',
7830 kind: 'kind',
7831 label: 'label',
7832 lang: 'lang',
7833 list: 'list',
7834 loop: 'loop',
7835 low: 'low',
7836 manifest: 'manifest',
7837 marginwidth: 'marginWidth',
7838 marginheight: 'marginHeight',
7839 max: 'max',
7840 maxlength: 'maxLength',
7841 media: 'media',
7842 mediagroup: 'mediaGroup',
7843 method: 'method',
7844 min: 'min',
7845 minlength: 'minLength',
7846 multiple: 'multiple',
7847 muted: 'muted',
7848 name: 'name',
7849 nomodule: 'noModule',
7850 nonce: 'nonce',
7851 novalidate: 'noValidate',
7852 open: 'open',
7853 optimum: 'optimum',
7854 pattern: 'pattern',
7855 placeholder: 'placeholder',
7856 playsinline: 'playsInline',
7857 poster: 'poster',
7858 preload: 'preload',
7859 profile: 'profile',
7860 radiogroup: 'radioGroup',
7861 readonly: 'readOnly',
7862 referrerpolicy: 'referrerPolicy',
7863 rel: 'rel',
7864 required: 'required',
7865 reversed: 'reversed',
7866 role: 'role',
7867 rows: 'rows',
7868 rowspan: 'rowSpan',
7869 sandbox: 'sandbox',
7870 scope: 'scope',
7871 scoped: 'scoped',
7872 scrolling: 'scrolling',
7873 seamless: 'seamless',
7874 selected: 'selected',
7875 shape: 'shape',
7876 size: 'size',
7877 sizes: 'sizes',
7878 span: 'span',
7879 spellcheck: 'spellCheck',
7880 src: 'src',
7881 srcdoc: 'srcDoc',
7882 srclang: 'srcLang',
7883 srcset: 'srcSet',
7884 start: 'start',
7885 step: 'step',
7886 style: 'style',
7887 summary: 'summary',
7888 tabindex: 'tabIndex',
7889 target: 'target',
7890 title: 'title',
7891 type: 'type',
7892 usemap: 'useMap',
7893 value: 'value',
7894 width: 'width',
7895 wmode: 'wmode',
7896 wrap: 'wrap',
7897
7898 // SVG
7899 about: 'about',
7900 accentheight: 'accentHeight',
7901 'accent-height': 'accentHeight',
7902 accumulate: 'accumulate',
7903 additive: 'additive',
7904 alignmentbaseline: 'alignmentBaseline',
7905 'alignment-baseline': 'alignmentBaseline',
7906 allowreorder: 'allowReorder',
7907 alphabetic: 'alphabetic',
7908 amplitude: 'amplitude',
7909 arabicform: 'arabicForm',
7910 'arabic-form': 'arabicForm',
7911 ascent: 'ascent',
7912 attributename: 'attributeName',
7913 attributetype: 'attributeType',
7914 autoreverse: 'autoReverse',
7915 azimuth: 'azimuth',
7916 basefrequency: 'baseFrequency',
7917 baselineshift: 'baselineShift',
7918 'baseline-shift': 'baselineShift',
7919 baseprofile: 'baseProfile',
7920 bbox: 'bbox',
7921 begin: 'begin',
7922 bias: 'bias',
7923 by: 'by',
7924 calcmode: 'calcMode',
7925 capheight: 'capHeight',
7926 'cap-height': 'capHeight',
7927 clip: 'clip',
7928 clippath: 'clipPath',
7929 'clip-path': 'clipPath',
7930 clippathunits: 'clipPathUnits',
7931 cliprule: 'clipRule',
7932 'clip-rule': 'clipRule',
7933 color: 'color',
7934 colorinterpolation: 'colorInterpolation',
7935 'color-interpolation': 'colorInterpolation',
7936 colorinterpolationfilters: 'colorInterpolationFilters',
7937 'color-interpolation-filters': 'colorInterpolationFilters',
7938 colorprofile: 'colorProfile',
7939 'color-profile': 'colorProfile',
7940 colorrendering: 'colorRendering',
7941 'color-rendering': 'colorRendering',
7942 contentscripttype: 'contentScriptType',
7943 contentstyletype: 'contentStyleType',
7944 cursor: 'cursor',
7945 cx: 'cx',
7946 cy: 'cy',
7947 d: 'd',
7948 datatype: 'datatype',
7949 decelerate: 'decelerate',
7950 descent: 'descent',
7951 diffuseconstant: 'diffuseConstant',
7952 direction: 'direction',
7953 display: 'display',
7954 divisor: 'divisor',
7955 dominantbaseline: 'dominantBaseline',
7956 'dominant-baseline': 'dominantBaseline',
7957 dur: 'dur',
7958 dx: 'dx',
7959 dy: 'dy',
7960 edgemode: 'edgeMode',
7961 elevation: 'elevation',
7962 enablebackground: 'enableBackground',
7963 'enable-background': 'enableBackground',
7964 end: 'end',
7965 exponent: 'exponent',
7966 externalresourcesrequired: 'externalResourcesRequired',
7967 fill: 'fill',
7968 fillopacity: 'fillOpacity',
7969 'fill-opacity': 'fillOpacity',
7970 fillrule: 'fillRule',
7971 'fill-rule': 'fillRule',
7972 filter: 'filter',
7973 filterres: 'filterRes',
7974 filterunits: 'filterUnits',
7975 floodopacity: 'floodOpacity',
7976 'flood-opacity': 'floodOpacity',
7977 floodcolor: 'floodColor',
7978 'flood-color': 'floodColor',
7979 focusable: 'focusable',
7980 fontfamily: 'fontFamily',
7981 'font-family': 'fontFamily',
7982 fontsize: 'fontSize',
7983 'font-size': 'fontSize',
7984 fontsizeadjust: 'fontSizeAdjust',
7985 'font-size-adjust': 'fontSizeAdjust',
7986 fontstretch: 'fontStretch',
7987 'font-stretch': 'fontStretch',
7988 fontstyle: 'fontStyle',
7989 'font-style': 'fontStyle',
7990 fontvariant: 'fontVariant',
7991 'font-variant': 'fontVariant',
7992 fontweight: 'fontWeight',
7993 'font-weight': 'fontWeight',
7994 format: 'format',
7995 from: 'from',
7996 fx: 'fx',
7997 fy: 'fy',
7998 g1: 'g1',
7999 g2: 'g2',
8000 glyphname: 'glyphName',
8001 'glyph-name': 'glyphName',
8002 glyphorientationhorizontal: 'glyphOrientationHorizontal',
8003 'glyph-orientation-horizontal': 'glyphOrientationHorizontal',
8004 glyphorientationvertical: 'glyphOrientationVertical',
8005 'glyph-orientation-vertical': 'glyphOrientationVertical',
8006 glyphref: 'glyphRef',
8007 gradienttransform: 'gradientTransform',
8008 gradientunits: 'gradientUnits',
8009 hanging: 'hanging',
8010 horizadvx: 'horizAdvX',
8011 'horiz-adv-x': 'horizAdvX',
8012 horizoriginx: 'horizOriginX',
8013 'horiz-origin-x': 'horizOriginX',
8014 ideographic: 'ideographic',
8015 imagerendering: 'imageRendering',
8016 'image-rendering': 'imageRendering',
8017 in2: 'in2',
8018 in: 'in',
8019 inlist: 'inlist',
8020 intercept: 'intercept',
8021 k1: 'k1',
8022 k2: 'k2',
8023 k3: 'k3',
8024 k4: 'k4',
8025 k: 'k',
8026 kernelmatrix: 'kernelMatrix',
8027 kernelunitlength: 'kernelUnitLength',
8028 kerning: 'kerning',
8029 keypoints: 'keyPoints',
8030 keysplines: 'keySplines',
8031 keytimes: 'keyTimes',
8032 lengthadjust: 'lengthAdjust',
8033 letterspacing: 'letterSpacing',
8034 'letter-spacing': 'letterSpacing',
8035 lightingcolor: 'lightingColor',
8036 'lighting-color': 'lightingColor',
8037 limitingconeangle: 'limitingConeAngle',
8038 local: 'local',
8039 markerend: 'markerEnd',
8040 'marker-end': 'markerEnd',
8041 markerheight: 'markerHeight',
8042 markermid: 'markerMid',
8043 'marker-mid': 'markerMid',
8044 markerstart: 'markerStart',
8045 'marker-start': 'markerStart',
8046 markerunits: 'markerUnits',
8047 markerwidth: 'markerWidth',
8048 mask: 'mask',
8049 maskcontentunits: 'maskContentUnits',
8050 maskunits: 'maskUnits',
8051 mathematical: 'mathematical',
8052 mode: 'mode',
8053 numoctaves: 'numOctaves',
8054 offset: 'offset',
8055 opacity: 'opacity',
8056 operator: 'operator',
8057 order: 'order',
8058 orient: 'orient',
8059 orientation: 'orientation',
8060 origin: 'origin',
8061 overflow: 'overflow',
8062 overlineposition: 'overlinePosition',
8063 'overline-position': 'overlinePosition',
8064 overlinethickness: 'overlineThickness',
8065 'overline-thickness': 'overlineThickness',
8066 paintorder: 'paintOrder',
8067 'paint-order': 'paintOrder',
8068 panose1: 'panose1',
8069 'panose-1': 'panose1',
8070 pathlength: 'pathLength',
8071 patterncontentunits: 'patternContentUnits',
8072 patterntransform: 'patternTransform',
8073 patternunits: 'patternUnits',
8074 pointerevents: 'pointerEvents',
8075 'pointer-events': 'pointerEvents',
8076 points: 'points',
8077 pointsatx: 'pointsAtX',
8078 pointsaty: 'pointsAtY',
8079 pointsatz: 'pointsAtZ',
8080 prefix: 'prefix',
8081 preservealpha: 'preserveAlpha',
8082 preserveaspectratio: 'preserveAspectRatio',
8083 primitiveunits: 'primitiveUnits',
8084 property: 'property',
8085 r: 'r',
8086 radius: 'radius',
8087 refx: 'refX',
8088 refy: 'refY',
8089 renderingintent: 'renderingIntent',
8090 'rendering-intent': 'renderingIntent',
8091 repeatcount: 'repeatCount',
8092 repeatdur: 'repeatDur',
8093 requiredextensions: 'requiredExtensions',
8094 requiredfeatures: 'requiredFeatures',
8095 resource: 'resource',
8096 restart: 'restart',
8097 result: 'result',
8098 results: 'results',
8099 rotate: 'rotate',
8100 rx: 'rx',
8101 ry: 'ry',
8102 scale: 'scale',
8103 security: 'security',
8104 seed: 'seed',
8105 shaperendering: 'shapeRendering',
8106 'shape-rendering': 'shapeRendering',
8107 slope: 'slope',
8108 spacing: 'spacing',
8109 specularconstant: 'specularConstant',
8110 specularexponent: 'specularExponent',
8111 speed: 'speed',
8112 spreadmethod: 'spreadMethod',
8113 startoffset: 'startOffset',
8114 stddeviation: 'stdDeviation',
8115 stemh: 'stemh',
8116 stemv: 'stemv',
8117 stitchtiles: 'stitchTiles',
8118 stopcolor: 'stopColor',
8119 'stop-color': 'stopColor',
8120 stopopacity: 'stopOpacity',
8121 'stop-opacity': 'stopOpacity',
8122 strikethroughposition: 'strikethroughPosition',
8123 'strikethrough-position': 'strikethroughPosition',
8124 strikethroughthickness: 'strikethroughThickness',
8125 'strikethrough-thickness': 'strikethroughThickness',
8126 string: 'string',
8127 stroke: 'stroke',
8128 strokedasharray: 'strokeDasharray',
8129 'stroke-dasharray': 'strokeDasharray',
8130 strokedashoffset: 'strokeDashoffset',
8131 'stroke-dashoffset': 'strokeDashoffset',
8132 strokelinecap: 'strokeLinecap',
8133 'stroke-linecap': 'strokeLinecap',
8134 strokelinejoin: 'strokeLinejoin',
8135 'stroke-linejoin': 'strokeLinejoin',
8136 strokemiterlimit: 'strokeMiterlimit',
8137 'stroke-miterlimit': 'strokeMiterlimit',
8138 strokewidth: 'strokeWidth',
8139 'stroke-width': 'strokeWidth',
8140 strokeopacity: 'strokeOpacity',
8141 'stroke-opacity': 'strokeOpacity',
8142 suppresscontenteditablewarning: 'suppressContentEditableWarning',
8143 suppresshydrationwarning: 'suppressHydrationWarning',
8144 surfacescale: 'surfaceScale',
8145 systemlanguage: 'systemLanguage',
8146 tablevalues: 'tableValues',
8147 targetx: 'targetX',
8148 targety: 'targetY',
8149 textanchor: 'textAnchor',
8150 'text-anchor': 'textAnchor',
8151 textdecoration: 'textDecoration',
8152 'text-decoration': 'textDecoration',
8153 textlength: 'textLength',
8154 textrendering: 'textRendering',
8155 'text-rendering': 'textRendering',
8156 to: 'to',
8157 transform: 'transform',
8158 typeof: 'typeof',
8159 u1: 'u1',
8160 u2: 'u2',
8161 underlineposition: 'underlinePosition',
8162 'underline-position': 'underlinePosition',
8163 underlinethickness: 'underlineThickness',
8164 'underline-thickness': 'underlineThickness',
8165 unicode: 'unicode',
8166 unicodebidi: 'unicodeBidi',
8167 'unicode-bidi': 'unicodeBidi',
8168 unicoderange: 'unicodeRange',
8169 'unicode-range': 'unicodeRange',
8170 unitsperem: 'unitsPerEm',
8171 'units-per-em': 'unitsPerEm',
8172 unselectable: 'unselectable',
8173 valphabetic: 'vAlphabetic',
8174 'v-alphabetic': 'vAlphabetic',
8175 values: 'values',
8176 vectoreffect: 'vectorEffect',
8177 'vector-effect': 'vectorEffect',
8178 version: 'version',
8179 vertadvy: 'vertAdvY',
8180 'vert-adv-y': 'vertAdvY',
8181 vertoriginx: 'vertOriginX',
8182 'vert-origin-x': 'vertOriginX',
8183 vertoriginy: 'vertOriginY',
8184 'vert-origin-y': 'vertOriginY',
8185 vhanging: 'vHanging',
8186 'v-hanging': 'vHanging',
8187 videographic: 'vIdeographic',
8188 'v-ideographic': 'vIdeographic',
8189 viewbox: 'viewBox',
8190 viewtarget: 'viewTarget',
8191 visibility: 'visibility',
8192 vmathematical: 'vMathematical',
8193 'v-mathematical': 'vMathematical',
8194 vocab: 'vocab',
8195 widths: 'widths',
8196 wordspacing: 'wordSpacing',
8197 'word-spacing': 'wordSpacing',
8198 writingmode: 'writingMode',
8199 'writing-mode': 'writingMode',
8200 x1: 'x1',
8201 x2: 'x2',
8202 x: 'x',
8203 xchannelselector: 'xChannelSelector',
8204 xheight: 'xHeight',
8205 'x-height': 'xHeight',
8206 xlinkactuate: 'xlinkActuate',
8207 'xlink:actuate': 'xlinkActuate',
8208 xlinkarcrole: 'xlinkArcrole',
8209 'xlink:arcrole': 'xlinkArcrole',
8210 xlinkhref: 'xlinkHref',
8211 'xlink:href': 'xlinkHref',
8212 xlinkrole: 'xlinkRole',
8213 'xlink:role': 'xlinkRole',
8214 xlinkshow: 'xlinkShow',
8215 'xlink:show': 'xlinkShow',
8216 xlinktitle: 'xlinkTitle',
8217 'xlink:title': 'xlinkTitle',
8218 xlinktype: 'xlinkType',
8219 'xlink:type': 'xlinkType',
8220 xmlbase: 'xmlBase',
8221 'xml:base': 'xmlBase',
8222 xmllang: 'xmlLang',
8223 'xml:lang': 'xmlLang',
8224 xmlns: 'xmlns',
8225 'xml:space': 'xmlSpace',
8226 xmlnsxlink: 'xmlnsXlink',
8227 'xmlns:xlink': 'xmlnsXlink',
8228 xmlspace: 'xmlSpace',
8229 y1: 'y1',
8230 y2: 'y2',
8231 y: 'y',
8232 ychannelselector: 'yChannelSelector',
8233 z: 'z',
8234 zoomandpan: 'zoomAndPan'
8235};
8236
8237var ariaProperties = {
8238 'aria-current': 0, // state
8239 'aria-details': 0,
8240 'aria-disabled': 0, // state
8241 'aria-hidden': 0, // state
8242 'aria-invalid': 0, // state
8243 'aria-keyshortcuts': 0,
8244 'aria-label': 0,
8245 'aria-roledescription': 0,
8246 // Widget Attributes
8247 'aria-autocomplete': 0,
8248 'aria-checked': 0,
8249 'aria-expanded': 0,
8250 'aria-haspopup': 0,
8251 'aria-level': 0,
8252 'aria-modal': 0,
8253 'aria-multiline': 0,
8254 'aria-multiselectable': 0,
8255 'aria-orientation': 0,
8256 'aria-placeholder': 0,
8257 'aria-pressed': 0,
8258 'aria-readonly': 0,
8259 'aria-required': 0,
8260 'aria-selected': 0,
8261 'aria-sort': 0,
8262 'aria-valuemax': 0,
8263 'aria-valuemin': 0,
8264 'aria-valuenow': 0,
8265 'aria-valuetext': 0,
8266 // Live Region Attributes
8267 'aria-atomic': 0,
8268 'aria-busy': 0,
8269 'aria-live': 0,
8270 'aria-relevant': 0,
8271 // Drag-and-Drop Attributes
8272 'aria-dropeffect': 0,
8273 'aria-grabbed': 0,
8274 // Relationship Attributes
8275 'aria-activedescendant': 0,
8276 'aria-colcount': 0,
8277 'aria-colindex': 0,
8278 'aria-colspan': 0,
8279 'aria-controls': 0,
8280 'aria-describedby': 0,
8281 'aria-errormessage': 0,
8282 'aria-flowto': 0,
8283 'aria-labelledby': 0,
8284 'aria-owns': 0,
8285 'aria-posinset': 0,
8286 'aria-rowcount': 0,
8287 'aria-rowindex': 0,
8288 'aria-rowspan': 0,
8289 'aria-setsize': 0
8290};
8291
8292var warnedProperties = {};
8293var rARIA = new RegExp('^(aria)-[' + ATTRIBUTE_NAME_CHAR + ']*$');
8294var rARIACamel = new RegExp('^(aria)[A-Z][' + ATTRIBUTE_NAME_CHAR + ']*$');
8295
8296var hasOwnProperty$2 = Object.prototype.hasOwnProperty;
8297
8298function validateProperty(tagName, name) {
8299 if (hasOwnProperty$2.call(warnedProperties, name) && warnedProperties[name]) {
8300 return true;
8301 }
8302
8303 if (rARIACamel.test(name)) {
8304 var ariaName = 'aria-' + name.slice(4).toLowerCase();
8305 var correctName = ariaProperties.hasOwnProperty(ariaName) ? ariaName : null;
8306
8307 // If this is an aria-* attribute, but is not listed in the known DOM
8308 // DOM properties, then it is an invalid aria-* attribute.
8309 if (correctName == null) {
8310 warning$1(false, 'Invalid ARIA attribute `%s`. ARIA attributes follow the pattern aria-* and must be lowercase.', name);
8311 warnedProperties[name] = true;
8312 return true;
8313 }
8314 // aria-* attributes should be lowercase; suggest the lowercase version.
8315 if (name !== correctName) {
8316 warning$1(false, 'Invalid ARIA attribute `%s`. Did you mean `%s`?', name, correctName);
8317 warnedProperties[name] = true;
8318 return true;
8319 }
8320 }
8321
8322 if (rARIA.test(name)) {
8323 var lowerCasedName = name.toLowerCase();
8324 var standardName = ariaProperties.hasOwnProperty(lowerCasedName) ? lowerCasedName : null;
8325
8326 // If this is an aria-* attribute, but is not listed in the known DOM
8327 // DOM properties, then it is an invalid aria-* attribute.
8328 if (standardName == null) {
8329 warnedProperties[name] = true;
8330 return false;
8331 }
8332 // aria-* attributes should be lowercase; suggest the lowercase version.
8333 if (name !== standardName) {
8334 warning$1(false, 'Unknown ARIA attribute `%s`. Did you mean `%s`?', name, standardName);
8335 warnedProperties[name] = true;
8336 return true;
8337 }
8338 }
8339
8340 return true;
8341}
8342
8343function warnInvalidARIAProps(type, props) {
8344 var invalidProps = [];
8345
8346 for (var key in props) {
8347 var isValid = validateProperty(type, key);
8348 if (!isValid) {
8349 invalidProps.push(key);
8350 }
8351 }
8352
8353 var unknownPropString = invalidProps.map(function (prop) {
8354 return '`' + prop + '`';
8355 }).join(', ');
8356
8357 if (invalidProps.length === 1) {
8358 warning$1(false, 'Invalid aria prop %s on <%s> tag. ' + 'For details, see https://fb.me/invalid-aria-prop', unknownPropString, type);
8359 } else if (invalidProps.length > 1) {
8360 warning$1(false, 'Invalid aria props %s on <%s> tag. ' + 'For details, see https://fb.me/invalid-aria-prop', unknownPropString, type);
8361 }
8362}
8363
8364function validateProperties(type, props) {
8365 if (isCustomComponent(type, props)) {
8366 return;
8367 }
8368 warnInvalidARIAProps(type, props);
8369}
8370
8371var didWarnValueNull = false;
8372
8373function validateProperties$1(type, props) {
8374 if (type !== 'input' && type !== 'textarea' && type !== 'select') {
8375 return;
8376 }
8377
8378 if (props != null && props.value === null && !didWarnValueNull) {
8379 didWarnValueNull = true;
8380 if (type === 'select' && props.multiple) {
8381 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);
8382 } else {
8383 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);
8384 }
8385 }
8386}
8387
8388var validateProperty$1 = function () {};
8389
8390{
8391 var warnedProperties$1 = {};
8392 var _hasOwnProperty = Object.prototype.hasOwnProperty;
8393 var EVENT_NAME_REGEX = /^on./;
8394 var INVALID_EVENT_NAME_REGEX = /^on[^A-Z]/;
8395 var rARIA$1 = new RegExp('^(aria)-[' + ATTRIBUTE_NAME_CHAR + ']*$');
8396 var rARIACamel$1 = new RegExp('^(aria)[A-Z][' + ATTRIBUTE_NAME_CHAR + ']*$');
8397
8398 validateProperty$1 = function (tagName, name, value, canUseEventSystem) {
8399 if (_hasOwnProperty.call(warnedProperties$1, name) && warnedProperties$1[name]) {
8400 return true;
8401 }
8402
8403 var lowerCasedName = name.toLowerCase();
8404 if (lowerCasedName === 'onfocusin' || lowerCasedName === 'onfocusout') {
8405 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.');
8406 warnedProperties$1[name] = true;
8407 return true;
8408 }
8409
8410 // We can't rely on the event system being injected on the server.
8411 if (canUseEventSystem) {
8412 if (registrationNameModules.hasOwnProperty(name)) {
8413 return true;
8414 }
8415 var registrationName = possibleRegistrationNames.hasOwnProperty(lowerCasedName) ? possibleRegistrationNames[lowerCasedName] : null;
8416 if (registrationName != null) {
8417 warning$1(false, 'Invalid event handler property `%s`. Did you mean `%s`?', name, registrationName);
8418 warnedProperties$1[name] = true;
8419 return true;
8420 }
8421 if (EVENT_NAME_REGEX.test(name)) {
8422 warning$1(false, 'Unknown event handler property `%s`. It will be ignored.', name);
8423 warnedProperties$1[name] = true;
8424 return true;
8425 }
8426 } else if (EVENT_NAME_REGEX.test(name)) {
8427 // If no event plugins have been injected, we are in a server environment.
8428 // So we can't tell if the event name is correct for sure, but we can filter
8429 // out known bad ones like `onclick`. We can't suggest a specific replacement though.
8430 if (INVALID_EVENT_NAME_REGEX.test(name)) {
8431 warning$1(false, 'Invalid event handler property `%s`. ' + 'React events use the camelCase naming convention, for example `onClick`.', name);
8432 }
8433 warnedProperties$1[name] = true;
8434 return true;
8435 }
8436
8437 // Let the ARIA attribute hook validate ARIA attributes
8438 if (rARIA$1.test(name) || rARIACamel$1.test(name)) {
8439 return true;
8440 }
8441
8442 if (lowerCasedName === 'innerhtml') {
8443 warning$1(false, 'Directly setting property `innerHTML` is not permitted. ' + 'For more information, lookup documentation on `dangerouslySetInnerHTML`.');
8444 warnedProperties$1[name] = true;
8445 return true;
8446 }
8447
8448 if (lowerCasedName === 'aria') {
8449 warning$1(false, 'The `aria` attribute is reserved for future use in React. ' + 'Pass individual `aria-` attributes instead.');
8450 warnedProperties$1[name] = true;
8451 return true;
8452 }
8453
8454 if (lowerCasedName === 'is' && value !== null && value !== undefined && typeof value !== 'string') {
8455 warning$1(false, 'Received a `%s` for a string attribute `is`. If this is expected, cast ' + 'the value to a string.', typeof value);
8456 warnedProperties$1[name] = true;
8457 return true;
8458 }
8459
8460 if (typeof value === 'number' && isNaN(value)) {
8461 warning$1(false, 'Received NaN for the `%s` attribute. If this is expected, cast ' + 'the value to a string.', name);
8462 warnedProperties$1[name] = true;
8463 return true;
8464 }
8465
8466 var propertyInfo = getPropertyInfo(name);
8467 var isReserved = propertyInfo !== null && propertyInfo.type === RESERVED;
8468
8469 // Known attributes should match the casing specified in the property config.
8470 if (possibleStandardNames.hasOwnProperty(lowerCasedName)) {
8471 var standardName = possibleStandardNames[lowerCasedName];
8472 if (standardName !== name) {
8473 warning$1(false, 'Invalid DOM property `%s`. Did you mean `%s`?', name, standardName);
8474 warnedProperties$1[name] = true;
8475 return true;
8476 }
8477 } else if (!isReserved && name !== lowerCasedName) {
8478 // Unknown attributes should have lowercase casing since that's how they
8479 // will be cased anyway with server rendering.
8480 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);
8481 warnedProperties$1[name] = true;
8482 return true;
8483 }
8484
8485 if (typeof value === 'boolean' && shouldRemoveAttributeWithWarning(name, value, propertyInfo, false)) {
8486 if (value) {
8487 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);
8488 } else {
8489 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);
8490 }
8491 warnedProperties$1[name] = true;
8492 return true;
8493 }
8494
8495 // Now that we've validated casing, do not validate
8496 // data types for reserved props
8497 if (isReserved) {
8498 return true;
8499 }
8500
8501 // Warn when a known attribute is a bad type
8502 if (shouldRemoveAttributeWithWarning(name, value, propertyInfo, false)) {
8503 warnedProperties$1[name] = true;
8504 return false;
8505 }
8506
8507 // Warn when passing the strings 'false' or 'true' into a boolean prop
8508 if ((value === 'false' || value === 'true') && propertyInfo !== null && propertyInfo.type === BOOLEAN) {
8509 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);
8510 warnedProperties$1[name] = true;
8511 return true;
8512 }
8513
8514 return true;
8515 };
8516}
8517
8518var warnUnknownProperties = function (type, props, canUseEventSystem) {
8519 var unknownProps = [];
8520 for (var key in props) {
8521 var isValid = validateProperty$1(type, key, props[key], canUseEventSystem);
8522 if (!isValid) {
8523 unknownProps.push(key);
8524 }
8525 }
8526
8527 var unknownPropString = unknownProps.map(function (prop) {
8528 return '`' + prop + '`';
8529 }).join(', ');
8530 if (unknownProps.length === 1) {
8531 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);
8532 } else if (unknownProps.length > 1) {
8533 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);
8534 }
8535};
8536
8537function validateProperties$2(type, props, canUseEventSystem) {
8538 if (isCustomComponent(type, props)) {
8539 return;
8540 }
8541 warnUnknownProperties(type, props, canUseEventSystem);
8542}
8543
8544// TODO: direct imports like some-package/src/* are bad. Fix me.
8545var didWarnInvalidHydration = false;
8546var didWarnShadyDOM = false;
8547
8548var DANGEROUSLY_SET_INNER_HTML = 'dangerouslySetInnerHTML';
8549var SUPPRESS_CONTENT_EDITABLE_WARNING = 'suppressContentEditableWarning';
8550var SUPPRESS_HYDRATION_WARNING$1 = 'suppressHydrationWarning';
8551var AUTOFOCUS = 'autoFocus';
8552var CHILDREN = 'children';
8553var STYLE$1 = 'style';
8554var HTML = '__html';
8555var LISTENERS = 'listeners';
8556
8557var HTML_NAMESPACE = Namespaces.html;
8558
8559
8560var warnedUnknownTags = void 0;
8561var suppressHydrationWarning = void 0;
8562
8563var validatePropertiesInDevelopment = void 0;
8564var warnForTextDifference = void 0;
8565var warnForPropDifference = void 0;
8566var warnForExtraAttributes = void 0;
8567var warnForInvalidEventListener = void 0;
8568var canDiffStyleForHydrationWarning = void 0;
8569
8570var normalizeMarkupForTextOrAttribute = void 0;
8571var normalizeHTML = void 0;
8572
8573{
8574 warnedUnknownTags = {
8575 // Chrome is the only major browser not shipping <time>. But as of July
8576 // 2017 it intends to ship it due to widespread usage. We intentionally
8577 // *don't* warn for <time> even if it's unrecognized by Chrome because
8578 // it soon will be, and many apps have been using it anyway.
8579 time: true,
8580 // There are working polyfills for <dialog>. Let people use it.
8581 dialog: true,
8582 // Electron ships a custom <webview> tag to display external web content in
8583 // an isolated frame and process.
8584 // This tag is not present in non Electron environments such as JSDom which
8585 // is often used for testing purposes.
8586 // @see https://electronjs.org/docs/api/webview-tag
8587 webview: true
8588 };
8589
8590 validatePropertiesInDevelopment = function (type, props) {
8591 validateProperties(type, props);
8592 validateProperties$1(type, props);
8593 validateProperties$2(type, props, /* canUseEventSystem */true);
8594 };
8595
8596 // IE 11 parses & normalizes the style attribute as opposed to other
8597 // browsers. It adds spaces and sorts the properties in some
8598 // non-alphabetical order. Handling that would require sorting CSS
8599 // properties in the client & server versions or applying
8600 // `expectedStyle` to a temporary DOM node to read its `style` attribute
8601 // normalized. Since it only affects IE, we're skipping style warnings
8602 // in that browser completely in favor of doing all that work.
8603 // See https://github.com/facebook/react/issues/11807
8604 canDiffStyleForHydrationWarning = canUseDOM && !document.documentMode;
8605
8606 // HTML parsing normalizes CR and CRLF to LF.
8607 // It also can turn \u0000 into \uFFFD inside attributes.
8608 // https://www.w3.org/TR/html5/single-page.html#preprocessing-the-input-stream
8609 // If we have a mismatch, it might be caused by that.
8610 // We will still patch up in this case but not fire the warning.
8611 var NORMALIZE_NEWLINES_REGEX = /\r\n?/g;
8612 var NORMALIZE_NULL_AND_REPLACEMENT_REGEX = /\u0000|\uFFFD/g;
8613
8614 normalizeMarkupForTextOrAttribute = function (markup) {
8615 var markupString = typeof markup === 'string' ? markup : '' + markup;
8616 return markupString.replace(NORMALIZE_NEWLINES_REGEX, '\n').replace(NORMALIZE_NULL_AND_REPLACEMENT_REGEX, '');
8617 };
8618
8619 warnForTextDifference = function (serverText, clientText) {
8620 if (didWarnInvalidHydration) {
8621 return;
8622 }
8623 var normalizedClientText = normalizeMarkupForTextOrAttribute(clientText);
8624 var normalizedServerText = normalizeMarkupForTextOrAttribute(serverText);
8625 if (normalizedServerText === normalizedClientText) {
8626 return;
8627 }
8628 didWarnInvalidHydration = true;
8629 warningWithoutStack$1(false, 'Text content did not match. Server: "%s" Client: "%s"', normalizedServerText, normalizedClientText);
8630 };
8631
8632 warnForPropDifference = function (propName, serverValue, clientValue) {
8633 if (didWarnInvalidHydration) {
8634 return;
8635 }
8636 var normalizedClientValue = normalizeMarkupForTextOrAttribute(clientValue);
8637 var normalizedServerValue = normalizeMarkupForTextOrAttribute(serverValue);
8638 if (normalizedServerValue === normalizedClientValue) {
8639 return;
8640 }
8641 didWarnInvalidHydration = true;
8642 warningWithoutStack$1(false, 'Prop `%s` did not match. Server: %s Client: %s', propName, JSON.stringify(normalizedServerValue), JSON.stringify(normalizedClientValue));
8643 };
8644
8645 warnForExtraAttributes = function (attributeNames) {
8646 if (didWarnInvalidHydration) {
8647 return;
8648 }
8649 didWarnInvalidHydration = true;
8650 var names = [];
8651 attributeNames.forEach(function (name) {
8652 names.push(name);
8653 });
8654 warningWithoutStack$1(false, 'Extra attributes from the server: %s', names);
8655 };
8656
8657 warnForInvalidEventListener = function (registrationName, listener) {
8658 if (listener === false) {
8659 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);
8660 } else {
8661 warning$1(false, 'Expected `%s` listener to be a function, instead got a value of `%s` type.', registrationName, typeof listener);
8662 }
8663 };
8664
8665 // Parse the HTML and read it back to normalize the HTML string so that it
8666 // can be used for comparison.
8667 normalizeHTML = function (parent, html) {
8668 // We could have created a separate document here to avoid
8669 // re-initializing custom elements if they exist. But this breaks
8670 // how <noscript> is being handled. So we use the same document.
8671 // See the discussion in https://github.com/facebook/react/pull/11157.
8672 var testElement = parent.namespaceURI === HTML_NAMESPACE ? parent.ownerDocument.createElement(parent.tagName) : parent.ownerDocument.createElementNS(parent.namespaceURI, parent.tagName);
8673 testElement.innerHTML = html;
8674 return testElement.innerHTML;
8675 };
8676}
8677
8678function ensureListeningTo(rootContainerElement, registrationName) {
8679 var isDocumentOrFragment = rootContainerElement.nodeType === DOCUMENT_NODE || rootContainerElement.nodeType === DOCUMENT_FRAGMENT_NODE;
8680 var doc = isDocumentOrFragment ? rootContainerElement : rootContainerElement.ownerDocument;
8681 listenTo(registrationName, doc);
8682}
8683
8684function getOwnerDocumentFromRootContainer(rootContainerElement) {
8685 return rootContainerElement.nodeType === DOCUMENT_NODE ? rootContainerElement : rootContainerElement.ownerDocument;
8686}
8687
8688function noop() {}
8689
8690function trapClickOnNonInteractiveElement(node) {
8691 // Mobile Safari does not fire properly bubble click events on
8692 // non-interactive elements, which means delegated click listeners do not
8693 // fire. The workaround for this bug involves attaching an empty click
8694 // listener on the target node.
8695 // http://www.quirksmode.org/blog/archives/2010/09/click_event_del.html
8696 // Just set it using the onclick property so that we don't have to manage any
8697 // bookkeeping for it. Not sure if we need to clear it when the listener is
8698 // removed.
8699 // TODO: Only do this for the relevant Safaris maybe?
8700 node.onclick = noop;
8701}
8702
8703function setInitialDOMProperties(tag, domElement, rootContainerElement, nextProps, isCustomComponentTag) {
8704 for (var propKey in nextProps) {
8705 if (!nextProps.hasOwnProperty(propKey)) {
8706 continue;
8707 }
8708 var nextProp = nextProps[propKey];
8709 if (propKey === STYLE$1) {
8710 {
8711 if (nextProp) {
8712 // Freeze the next style object so that we can assume it won't be
8713 // mutated. We have already warned for this in the past.
8714 Object.freeze(nextProp);
8715 }
8716 }
8717 // Relies on `updateStylesByID` not mutating `styleUpdates`.
8718 setValueForStyles(domElement, nextProp);
8719 } else if (propKey === DANGEROUSLY_SET_INNER_HTML) {
8720 var nextHtml = nextProp ? nextProp[HTML] : undefined;
8721 if (nextHtml != null) {
8722 setInnerHTML(domElement, nextHtml);
8723 }
8724 } else if (propKey === CHILDREN) {
8725 if (typeof nextProp === 'string') {
8726 // Avoid setting initial textContent when the text is empty. In IE11 setting
8727 // textContent on a <textarea> will cause the placeholder to not
8728 // show within the <textarea> until it has been focused and blurred again.
8729 // https://github.com/facebook/react/issues/6731#issuecomment-254874553
8730 var canSetTextContent = tag !== 'textarea' || nextProp !== '';
8731 if (canSetTextContent) {
8732 setTextContent(domElement, nextProp);
8733 }
8734 } else if (typeof nextProp === 'number') {
8735 setTextContent(domElement, '' + nextProp);
8736 }
8737 } else if (enableFlareAPI && propKey === LISTENERS || propKey === SUPPRESS_CONTENT_EDITABLE_WARNING || propKey === SUPPRESS_HYDRATION_WARNING$1) {
8738 // Noop
8739 } else if (propKey === AUTOFOCUS) {
8740 // We polyfill it separately on the client during commit.
8741 // We could have excluded it in the property list instead of
8742 // adding a special case here, but then it wouldn't be emitted
8743 // on server rendering (but we *do* want to emit it in SSR).
8744 } else if (registrationNameModules.hasOwnProperty(propKey)) {
8745 if (nextProp != null) {
8746 if (true && typeof nextProp !== 'function') {
8747 warnForInvalidEventListener(propKey, nextProp);
8748 }
8749 ensureListeningTo(rootContainerElement, propKey);
8750 }
8751 } else if (nextProp != null) {
8752 setValueForProperty(domElement, propKey, nextProp, isCustomComponentTag);
8753 }
8754 }
8755}
8756
8757function updateDOMProperties(domElement, updatePayload, wasCustomComponentTag, isCustomComponentTag) {
8758 // TODO: Handle wasCustomComponentTag
8759 for (var i = 0; i < updatePayload.length; i += 2) {
8760 var propKey = updatePayload[i];
8761 var propValue = updatePayload[i + 1];
8762 if (propKey === STYLE$1) {
8763 setValueForStyles(domElement, propValue);
8764 } else if (propKey === DANGEROUSLY_SET_INNER_HTML) {
8765 setInnerHTML(domElement, propValue);
8766 } else if (propKey === CHILDREN) {
8767 setTextContent(domElement, propValue);
8768 } else {
8769 setValueForProperty(domElement, propKey, propValue, isCustomComponentTag);
8770 }
8771 }
8772}
8773
8774function createElement(type, props, rootContainerElement, parentNamespace) {
8775 var isCustomComponentTag = void 0;
8776
8777 // We create tags in the namespace of their parent container, except HTML
8778 // tags get no namespace.
8779 var ownerDocument = getOwnerDocumentFromRootContainer(rootContainerElement);
8780 var domElement = void 0;
8781 var namespaceURI = parentNamespace;
8782 if (namespaceURI === HTML_NAMESPACE) {
8783 namespaceURI = getIntrinsicNamespace(type);
8784 }
8785 if (namespaceURI === HTML_NAMESPACE) {
8786 {
8787 isCustomComponentTag = isCustomComponent(type, props);
8788 // Should this check be gated by parent namespace? Not sure we want to
8789 // allow <SVG> or <mATH>.
8790 !(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;
8791 }
8792
8793 if (type === 'script') {
8794 // Create the script via .innerHTML so its "parser-inserted" flag is
8795 // set to true and it does not execute
8796 var div = ownerDocument.createElement('div');
8797 div.innerHTML = '<script><' + '/script>'; // eslint-disable-line
8798 // This is guaranteed to yield a script element.
8799 var firstChild = div.firstChild;
8800 domElement = div.removeChild(firstChild);
8801 } else if (typeof props.is === 'string') {
8802 // $FlowIssue `createElement` should be updated for Web Components
8803 domElement = ownerDocument.createElement(type, { is: props.is });
8804 } else {
8805 // Separate else branch instead of using `props.is || undefined` above because of a Firefox bug.
8806 // See discussion in https://github.com/facebook/react/pull/6896
8807 // and discussion in https://bugzilla.mozilla.org/show_bug.cgi?id=1276240
8808 domElement = ownerDocument.createElement(type);
8809 // Normally attributes are assigned in `setInitialDOMProperties`, however the `multiple` and `size`
8810 // attributes on `select`s needs to be added before `option`s are inserted.
8811 // This prevents:
8812 // - a bug where the `select` does not scroll to the correct option because singular
8813 // `select` elements automatically pick the first item #13222
8814 // - a bug where the `select` set the first item as selected despite the `size` attribute #14239
8815 // See https://github.com/facebook/react/issues/13222
8816 // and https://github.com/facebook/react/issues/14239
8817 if (type === 'select') {
8818 var node = domElement;
8819 if (props.multiple) {
8820 node.multiple = true;
8821 } else if (props.size) {
8822 // Setting a size greater than 1 causes a select to behave like `multiple=true`, where
8823 // it is possible that no option is selected.
8824 //
8825 // This is only necessary when a select in "single selection mode".
8826 node.size = props.size;
8827 }
8828 }
8829 }
8830 } else {
8831 domElement = ownerDocument.createElementNS(namespaceURI, type);
8832 }
8833
8834 {
8835 if (namespaceURI === HTML_NAMESPACE) {
8836 if (!isCustomComponentTag && Object.prototype.toString.call(domElement) === '[object HTMLUnknownElement]' && !Object.prototype.hasOwnProperty.call(warnedUnknownTags, type)) {
8837 warnedUnknownTags[type] = true;
8838 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);
8839 }
8840 }
8841 }
8842
8843 return domElement;
8844}
8845
8846function createTextNode(text, rootContainerElement) {
8847 return getOwnerDocumentFromRootContainer(rootContainerElement).createTextNode(text);
8848}
8849
8850function setInitialProperties(domElement, tag, rawProps, rootContainerElement) {
8851 var isCustomComponentTag = isCustomComponent(tag, rawProps);
8852 {
8853 validatePropertiesInDevelopment(tag, rawProps);
8854 if (isCustomComponentTag && !didWarnShadyDOM && domElement.shadyRoot) {
8855 warning$1(false, '%s is using shady DOM. Using shady DOM with React can ' + 'cause things to break subtly.', getCurrentFiberOwnerNameInDevOrNull() || 'A component');
8856 didWarnShadyDOM = true;
8857 }
8858 }
8859
8860 // TODO: Make sure that we check isMounted before firing any of these events.
8861 var props = void 0;
8862 switch (tag) {
8863 case 'iframe':
8864 case 'object':
8865 case 'embed':
8866 trapBubbledEvent(TOP_LOAD, domElement);
8867 props = rawProps;
8868 break;
8869 case 'video':
8870 case 'audio':
8871 // Create listener for each media event
8872 for (var i = 0; i < mediaEventTypes.length; i++) {
8873 trapBubbledEvent(mediaEventTypes[i], domElement);
8874 }
8875 props = rawProps;
8876 break;
8877 case 'source':
8878 trapBubbledEvent(TOP_ERROR, domElement);
8879 props = rawProps;
8880 break;
8881 case 'img':
8882 case 'image':
8883 case 'link':
8884 trapBubbledEvent(TOP_ERROR, domElement);
8885 trapBubbledEvent(TOP_LOAD, domElement);
8886 props = rawProps;
8887 break;
8888 case 'form':
8889 trapBubbledEvent(TOP_RESET, domElement);
8890 trapBubbledEvent(TOP_SUBMIT, domElement);
8891 props = rawProps;
8892 break;
8893 case 'details':
8894 trapBubbledEvent(TOP_TOGGLE, domElement);
8895 props = rawProps;
8896 break;
8897 case 'input':
8898 initWrapperState(domElement, rawProps);
8899 props = getHostProps(domElement, rawProps);
8900 trapBubbledEvent(TOP_INVALID, domElement);
8901 // For controlled components we always need to ensure we're listening
8902 // to onChange. Even if there is no listener.
8903 ensureListeningTo(rootContainerElement, 'onChange');
8904 break;
8905 case 'option':
8906 validateProps(domElement, rawProps);
8907 props = getHostProps$1(domElement, rawProps);
8908 break;
8909 case 'select':
8910 initWrapperState$1(domElement, rawProps);
8911 props = getHostProps$2(domElement, rawProps);
8912 trapBubbledEvent(TOP_INVALID, domElement);
8913 // For controlled components we always need to ensure we're listening
8914 // to onChange. Even if there is no listener.
8915 ensureListeningTo(rootContainerElement, 'onChange');
8916 break;
8917 case 'textarea':
8918 initWrapperState$2(domElement, rawProps);
8919 props = getHostProps$3(domElement, rawProps);
8920 trapBubbledEvent(TOP_INVALID, domElement);
8921 // For controlled components we always need to ensure we're listening
8922 // to onChange. Even if there is no listener.
8923 ensureListeningTo(rootContainerElement, 'onChange');
8924 break;
8925 default:
8926 props = rawProps;
8927 }
8928
8929 assertValidProps(tag, props);
8930
8931 setInitialDOMProperties(tag, domElement, rootContainerElement, props, isCustomComponentTag);
8932
8933 switch (tag) {
8934 case 'input':
8935 // TODO: Make sure we check if this is still unmounted or do any clean
8936 // up necessary since we never stop tracking anymore.
8937 track(domElement);
8938 postMountWrapper(domElement, rawProps, false);
8939 break;
8940 case 'textarea':
8941 // TODO: Make sure we check if this is still unmounted or do any clean
8942 // up necessary since we never stop tracking anymore.
8943 track(domElement);
8944 postMountWrapper$3(domElement, rawProps);
8945 break;
8946 case 'option':
8947 postMountWrapper$1(domElement, rawProps);
8948 break;
8949 case 'select':
8950 postMountWrapper$2(domElement, rawProps);
8951 break;
8952 default:
8953 if (typeof props.onClick === 'function') {
8954 // TODO: This cast may not be sound for SVG, MathML or custom elements.
8955 trapClickOnNonInteractiveElement(domElement);
8956 }
8957 break;
8958 }
8959}
8960
8961// Calculate the diff between the two objects.
8962function diffProperties(domElement, tag, lastRawProps, nextRawProps, rootContainerElement) {
8963 {
8964 validatePropertiesInDevelopment(tag, nextRawProps);
8965 }
8966
8967 var updatePayload = null;
8968
8969 var lastProps = void 0;
8970 var nextProps = void 0;
8971 switch (tag) {
8972 case 'input':
8973 lastProps = getHostProps(domElement, lastRawProps);
8974 nextProps = getHostProps(domElement, nextRawProps);
8975 updatePayload = [];
8976 break;
8977 case 'option':
8978 lastProps = getHostProps$1(domElement, lastRawProps);
8979 nextProps = getHostProps$1(domElement, nextRawProps);
8980 updatePayload = [];
8981 break;
8982 case 'select':
8983 lastProps = getHostProps$2(domElement, lastRawProps);
8984 nextProps = getHostProps$2(domElement, nextRawProps);
8985 updatePayload = [];
8986 break;
8987 case 'textarea':
8988 lastProps = getHostProps$3(domElement, lastRawProps);
8989 nextProps = getHostProps$3(domElement, nextRawProps);
8990 updatePayload = [];
8991 break;
8992 default:
8993 lastProps = lastRawProps;
8994 nextProps = nextRawProps;
8995 if (typeof lastProps.onClick !== 'function' && typeof nextProps.onClick === 'function') {
8996 // TODO: This cast may not be sound for SVG, MathML or custom elements.
8997 trapClickOnNonInteractiveElement(domElement);
8998 }
8999 break;
9000 }
9001
9002 assertValidProps(tag, nextProps);
9003
9004 var propKey = void 0;
9005 var styleName = void 0;
9006 var styleUpdates = null;
9007 for (propKey in lastProps) {
9008 if (nextProps.hasOwnProperty(propKey) || !lastProps.hasOwnProperty(propKey) || lastProps[propKey] == null) {
9009 continue;
9010 }
9011 if (propKey === STYLE$1) {
9012 var lastStyle = lastProps[propKey];
9013 for (styleName in lastStyle) {
9014 if (lastStyle.hasOwnProperty(styleName)) {
9015 if (!styleUpdates) {
9016 styleUpdates = {};
9017 }
9018 styleUpdates[styleName] = '';
9019 }
9020 }
9021 } else if (propKey === DANGEROUSLY_SET_INNER_HTML || propKey === CHILDREN) {
9022 // Noop. This is handled by the clear text mechanism.
9023 } else if (enableFlareAPI && propKey === LISTENERS || propKey === SUPPRESS_CONTENT_EDITABLE_WARNING || propKey === SUPPRESS_HYDRATION_WARNING$1) {
9024 // Noop
9025 } else if (propKey === AUTOFOCUS) {
9026 // Noop. It doesn't work on updates anyway.
9027 } else if (registrationNameModules.hasOwnProperty(propKey)) {
9028 // This is a special case. If any listener updates we need to ensure
9029 // that the "current" fiber pointer gets updated so we need a commit
9030 // to update this element.
9031 if (!updatePayload) {
9032 updatePayload = [];
9033 }
9034 } else {
9035 // For all other deleted properties we add it to the queue. We use
9036 // the whitelist in the commit phase instead.
9037 (updatePayload = updatePayload || []).push(propKey, null);
9038 }
9039 }
9040 for (propKey in nextProps) {
9041 var nextProp = nextProps[propKey];
9042 var lastProp = lastProps != null ? lastProps[propKey] : undefined;
9043 if (!nextProps.hasOwnProperty(propKey) || nextProp === lastProp || nextProp == null && lastProp == null) {
9044 continue;
9045 }
9046 if (propKey === STYLE$1) {
9047 {
9048 if (nextProp) {
9049 // Freeze the next style object so that we can assume it won't be
9050 // mutated. We have already warned for this in the past.
9051 Object.freeze(nextProp);
9052 }
9053 }
9054 if (lastProp) {
9055 // Unset styles on `lastProp` but not on `nextProp`.
9056 for (styleName in lastProp) {
9057 if (lastProp.hasOwnProperty(styleName) && (!nextProp || !nextProp.hasOwnProperty(styleName))) {
9058 if (!styleUpdates) {
9059 styleUpdates = {};
9060 }
9061 styleUpdates[styleName] = '';
9062 }
9063 }
9064 // Update styles that changed since `lastProp`.
9065 for (styleName in nextProp) {
9066 if (nextProp.hasOwnProperty(styleName) && lastProp[styleName] !== nextProp[styleName]) {
9067 if (!styleUpdates) {
9068 styleUpdates = {};
9069 }
9070 styleUpdates[styleName] = nextProp[styleName];
9071 }
9072 }
9073 } else {
9074 // Relies on `updateStylesByID` not mutating `styleUpdates`.
9075 if (!styleUpdates) {
9076 if (!updatePayload) {
9077 updatePayload = [];
9078 }
9079 updatePayload.push(propKey, styleUpdates);
9080 }
9081 styleUpdates = nextProp;
9082 }
9083 } else if (propKey === DANGEROUSLY_SET_INNER_HTML) {
9084 var nextHtml = nextProp ? nextProp[HTML] : undefined;
9085 var lastHtml = lastProp ? lastProp[HTML] : undefined;
9086 if (nextHtml != null) {
9087 if (lastHtml !== nextHtml) {
9088 (updatePayload = updatePayload || []).push(propKey, '' + nextHtml);
9089 }
9090 } else {
9091 // TODO: It might be too late to clear this if we have children
9092 // inserted already.
9093 }
9094 } else if (propKey === CHILDREN) {
9095 if (lastProp !== nextProp && (typeof nextProp === 'string' || typeof nextProp === 'number')) {
9096 (updatePayload = updatePayload || []).push(propKey, '' + nextProp);
9097 }
9098 } else if (enableFlareAPI && propKey === LISTENERS || propKey === SUPPRESS_CONTENT_EDITABLE_WARNING || propKey === SUPPRESS_HYDRATION_WARNING$1) {
9099 // Noop
9100 } else if (registrationNameModules.hasOwnProperty(propKey)) {
9101 if (nextProp != null) {
9102 // We eagerly listen to this even though we haven't committed yet.
9103 if (true && typeof nextProp !== 'function') {
9104 warnForInvalidEventListener(propKey, nextProp);
9105 }
9106 ensureListeningTo(rootContainerElement, propKey);
9107 }
9108 if (!updatePayload && lastProp !== nextProp) {
9109 // This is a special case. If any listener updates we need to ensure
9110 // that the "current" props pointer gets updated so we need a commit
9111 // to update this element.
9112 updatePayload = [];
9113 }
9114 } else {
9115 // For any other property we always add it to the queue and then we
9116 // filter it out using the whitelist during the commit.
9117 (updatePayload = updatePayload || []).push(propKey, nextProp);
9118 }
9119 }
9120 if (styleUpdates) {
9121 {
9122 validateShorthandPropertyCollisionInDev(styleUpdates, nextProps[STYLE$1]);
9123 }
9124 (updatePayload = updatePayload || []).push(STYLE$1, styleUpdates);
9125 }
9126 return updatePayload;
9127}
9128
9129// Apply the diff.
9130function updateProperties(domElement, updatePayload, tag, lastRawProps, nextRawProps) {
9131 // Update checked *before* name.
9132 // In the middle of an update, it is possible to have multiple checked.
9133 // When a checked radio tries to change name, browser makes another radio's checked false.
9134 if (tag === 'input' && nextRawProps.type === 'radio' && nextRawProps.name != null) {
9135 updateChecked(domElement, nextRawProps);
9136 }
9137
9138 var wasCustomComponentTag = isCustomComponent(tag, lastRawProps);
9139 var isCustomComponentTag = isCustomComponent(tag, nextRawProps);
9140 // Apply the diff.
9141 updateDOMProperties(domElement, updatePayload, wasCustomComponentTag, isCustomComponentTag);
9142
9143 // TODO: Ensure that an update gets scheduled if any of the special props
9144 // changed.
9145 switch (tag) {
9146 case 'input':
9147 // Update the wrapper around inputs *after* updating props. This has to
9148 // happen after `updateDOMProperties`. Otherwise HTML5 input validations
9149 // raise warnings and prevent the new value from being assigned.
9150 updateWrapper(domElement, nextRawProps);
9151 break;
9152 case 'textarea':
9153 updateWrapper$1(domElement, nextRawProps);
9154 break;
9155 case 'select':
9156 // <select> value update needs to occur after <option> children
9157 // reconciliation
9158 postUpdateWrapper(domElement, nextRawProps);
9159 break;
9160 }
9161}
9162
9163function getPossibleStandardName(propName) {
9164 {
9165 var lowerCasedName = propName.toLowerCase();
9166 if (!possibleStandardNames.hasOwnProperty(lowerCasedName)) {
9167 return null;
9168 }
9169 return possibleStandardNames[lowerCasedName] || null;
9170 }
9171 return null;
9172}
9173
9174function diffHydratedProperties(domElement, tag, rawProps, parentNamespace, rootContainerElement) {
9175 var isCustomComponentTag = void 0;
9176 var extraAttributeNames = void 0;
9177
9178 {
9179 suppressHydrationWarning = rawProps[SUPPRESS_HYDRATION_WARNING$1] === true;
9180 isCustomComponentTag = isCustomComponent(tag, rawProps);
9181 validatePropertiesInDevelopment(tag, rawProps);
9182 if (isCustomComponentTag && !didWarnShadyDOM && domElement.shadyRoot) {
9183 warning$1(false, '%s is using shady DOM. Using shady DOM with React can ' + 'cause things to break subtly.', getCurrentFiberOwnerNameInDevOrNull() || 'A component');
9184 didWarnShadyDOM = true;
9185 }
9186 }
9187
9188 // TODO: Make sure that we check isMounted before firing any of these events.
9189 switch (tag) {
9190 case 'iframe':
9191 case 'object':
9192 case 'embed':
9193 trapBubbledEvent(TOP_LOAD, domElement);
9194 break;
9195 case 'video':
9196 case 'audio':
9197 // Create listener for each media event
9198 for (var i = 0; i < mediaEventTypes.length; i++) {
9199 trapBubbledEvent(mediaEventTypes[i], domElement);
9200 }
9201 break;
9202 case 'source':
9203 trapBubbledEvent(TOP_ERROR, domElement);
9204 break;
9205 case 'img':
9206 case 'image':
9207 case 'link':
9208 trapBubbledEvent(TOP_ERROR, domElement);
9209 trapBubbledEvent(TOP_LOAD, domElement);
9210 break;
9211 case 'form':
9212 trapBubbledEvent(TOP_RESET, domElement);
9213 trapBubbledEvent(TOP_SUBMIT, domElement);
9214 break;
9215 case 'details':
9216 trapBubbledEvent(TOP_TOGGLE, domElement);
9217 break;
9218 case 'input':
9219 initWrapperState(domElement, rawProps);
9220 trapBubbledEvent(TOP_INVALID, domElement);
9221 // For controlled components we always need to ensure we're listening
9222 // to onChange. Even if there is no listener.
9223 ensureListeningTo(rootContainerElement, 'onChange');
9224 break;
9225 case 'option':
9226 validateProps(domElement, rawProps);
9227 break;
9228 case 'select':
9229 initWrapperState$1(domElement, rawProps);
9230 trapBubbledEvent(TOP_INVALID, domElement);
9231 // For controlled components we always need to ensure we're listening
9232 // to onChange. Even if there is no listener.
9233 ensureListeningTo(rootContainerElement, 'onChange');
9234 break;
9235 case 'textarea':
9236 initWrapperState$2(domElement, rawProps);
9237 trapBubbledEvent(TOP_INVALID, domElement);
9238 // For controlled components we always need to ensure we're listening
9239 // to onChange. Even if there is no listener.
9240 ensureListeningTo(rootContainerElement, 'onChange');
9241 break;
9242 }
9243
9244 assertValidProps(tag, rawProps);
9245
9246 {
9247 extraAttributeNames = new Set();
9248 var attributes = domElement.attributes;
9249 for (var _i = 0; _i < attributes.length; _i++) {
9250 var name = attributes[_i].name.toLowerCase();
9251 switch (name) {
9252 // Built-in SSR attribute is whitelisted
9253 case 'data-reactroot':
9254 break;
9255 // Controlled attributes are not validated
9256 // TODO: Only ignore them on controlled tags.
9257 case 'value':
9258 break;
9259 case 'checked':
9260 break;
9261 case 'selected':
9262 break;
9263 default:
9264 // Intentionally use the original name.
9265 // See discussion in https://github.com/facebook/react/pull/10676.
9266 extraAttributeNames.add(attributes[_i].name);
9267 }
9268 }
9269 }
9270
9271 var updatePayload = null;
9272 for (var propKey in rawProps) {
9273 if (!rawProps.hasOwnProperty(propKey)) {
9274 continue;
9275 }
9276 var nextProp = rawProps[propKey];
9277 if (propKey === CHILDREN) {
9278 // For text content children we compare against textContent. This
9279 // might match additional HTML that is hidden when we read it using
9280 // textContent. E.g. "foo" will match "f<span>oo</span>" but that still
9281 // satisfies our requirement. Our requirement is not to produce perfect
9282 // HTML and attributes. Ideally we should preserve structure but it's
9283 // ok not to if the visible content is still enough to indicate what
9284 // even listeners these nodes might be wired up to.
9285 // TODO: Warn if there is more than a single textNode as a child.
9286 // TODO: Should we use domElement.firstChild.nodeValue to compare?
9287 if (typeof nextProp === 'string') {
9288 if (domElement.textContent !== nextProp) {
9289 if (true && !suppressHydrationWarning) {
9290 warnForTextDifference(domElement.textContent, nextProp);
9291 }
9292 updatePayload = [CHILDREN, nextProp];
9293 }
9294 } else if (typeof nextProp === 'number') {
9295 if (domElement.textContent !== '' + nextProp) {
9296 if (true && !suppressHydrationWarning) {
9297 warnForTextDifference(domElement.textContent, nextProp);
9298 }
9299 updatePayload = [CHILDREN, '' + nextProp];
9300 }
9301 }
9302 } else if (registrationNameModules.hasOwnProperty(propKey)) {
9303 if (nextProp != null) {
9304 if (true && typeof nextProp !== 'function') {
9305 warnForInvalidEventListener(propKey, nextProp);
9306 }
9307 ensureListeningTo(rootContainerElement, propKey);
9308 }
9309 } else if (true &&
9310 // Convince Flow we've calculated it (it's DEV-only in this method.)
9311 typeof isCustomComponentTag === 'boolean') {
9312 // Validate that the properties correspond to their expected values.
9313 var serverValue = void 0;
9314 var propertyInfo = getPropertyInfo(propKey);
9315 if (suppressHydrationWarning) {
9316 // Don't bother comparing. We're ignoring all these warnings.
9317 } else if (enableFlareAPI && propKey === LISTENERS || propKey === SUPPRESS_CONTENT_EDITABLE_WARNING || propKey === SUPPRESS_HYDRATION_WARNING$1 ||
9318 // Controlled attributes are not validated
9319 // TODO: Only ignore them on controlled tags.
9320 propKey === 'value' || propKey === 'checked' || propKey === 'selected') {
9321 // Noop
9322 } else if (propKey === DANGEROUSLY_SET_INNER_HTML) {
9323 var serverHTML = domElement.innerHTML;
9324 var nextHtml = nextProp ? nextProp[HTML] : undefined;
9325 var expectedHTML = normalizeHTML(domElement, nextHtml != null ? nextHtml : '');
9326 if (expectedHTML !== serverHTML) {
9327 warnForPropDifference(propKey, serverHTML, expectedHTML);
9328 }
9329 } else if (propKey === STYLE$1) {
9330 // $FlowFixMe - Should be inferred as not undefined.
9331 extraAttributeNames.delete(propKey);
9332
9333 if (canDiffStyleForHydrationWarning) {
9334 var expectedStyle = createDangerousStringForStyles(nextProp);
9335 serverValue = domElement.getAttribute('style');
9336 if (expectedStyle !== serverValue) {
9337 warnForPropDifference(propKey, serverValue, expectedStyle);
9338 }
9339 }
9340 } else if (isCustomComponentTag) {
9341 // $FlowFixMe - Should be inferred as not undefined.
9342 extraAttributeNames.delete(propKey.toLowerCase());
9343 serverValue = getValueForAttribute(domElement, propKey, nextProp);
9344
9345 if (nextProp !== serverValue) {
9346 warnForPropDifference(propKey, serverValue, nextProp);
9347 }
9348 } else if (!shouldIgnoreAttribute(propKey, propertyInfo, isCustomComponentTag) && !shouldRemoveAttribute(propKey, nextProp, propertyInfo, isCustomComponentTag)) {
9349 var isMismatchDueToBadCasing = false;
9350 if (propertyInfo !== null) {
9351 // $FlowFixMe - Should be inferred as not undefined.
9352 extraAttributeNames.delete(propertyInfo.attributeName);
9353 serverValue = getValueForProperty(domElement, propKey, nextProp, propertyInfo);
9354 } else {
9355 var ownNamespace = parentNamespace;
9356 if (ownNamespace === HTML_NAMESPACE) {
9357 ownNamespace = getIntrinsicNamespace(tag);
9358 }
9359 if (ownNamespace === HTML_NAMESPACE) {
9360 // $FlowFixMe - Should be inferred as not undefined.
9361 extraAttributeNames.delete(propKey.toLowerCase());
9362 } else {
9363 var standardName = getPossibleStandardName(propKey);
9364 if (standardName !== null && standardName !== propKey) {
9365 // If an SVG prop is supplied with bad casing, it will
9366 // be successfully parsed from HTML, but will produce a mismatch
9367 // (and would be incorrectly rendered on the client).
9368 // However, we already warn about bad casing elsewhere.
9369 // So we'll skip the misleading extra mismatch warning in this case.
9370 isMismatchDueToBadCasing = true;
9371 // $FlowFixMe - Should be inferred as not undefined.
9372 extraAttributeNames.delete(standardName);
9373 }
9374 // $FlowFixMe - Should be inferred as not undefined.
9375 extraAttributeNames.delete(propKey);
9376 }
9377 serverValue = getValueForAttribute(domElement, propKey, nextProp);
9378 }
9379
9380 if (nextProp !== serverValue && !isMismatchDueToBadCasing) {
9381 warnForPropDifference(propKey, serverValue, nextProp);
9382 }
9383 }
9384 }
9385 }
9386
9387 {
9388 // $FlowFixMe - Should be inferred as not undefined.
9389 if (extraAttributeNames.size > 0 && !suppressHydrationWarning) {
9390 // $FlowFixMe - Should be inferred as not undefined.
9391 warnForExtraAttributes(extraAttributeNames);
9392 }
9393 }
9394
9395 switch (tag) {
9396 case 'input':
9397 // TODO: Make sure we check if this is still unmounted or do any clean
9398 // up necessary since we never stop tracking anymore.
9399 track(domElement);
9400 postMountWrapper(domElement, rawProps, true);
9401 break;
9402 case 'textarea':
9403 // TODO: Make sure we check if this is still unmounted or do any clean
9404 // up necessary since we never stop tracking anymore.
9405 track(domElement);
9406 postMountWrapper$3(domElement, rawProps);
9407 break;
9408 case 'select':
9409 case 'option':
9410 // For input and textarea we current always set the value property at
9411 // post mount to force it to diverge from attributes. However, for
9412 // option and select we don't quite do the same thing and select
9413 // is not resilient to the DOM state changing so we don't do that here.
9414 // TODO: Consider not doing this for input and textarea.
9415 break;
9416 default:
9417 if (typeof rawProps.onClick === 'function') {
9418 // TODO: This cast may not be sound for SVG, MathML or custom elements.
9419 trapClickOnNonInteractiveElement(domElement);
9420 }
9421 break;
9422 }
9423
9424 return updatePayload;
9425}
9426
9427function diffHydratedText(textNode, text) {
9428 var isDifferent = textNode.nodeValue !== text;
9429 return isDifferent;
9430}
9431
9432function warnForUnmatchedText(textNode, text) {
9433 {
9434 warnForTextDifference(textNode.nodeValue, text);
9435 }
9436}
9437
9438function warnForDeletedHydratableElement(parentNode, child) {
9439 {
9440 if (didWarnInvalidHydration) {
9441 return;
9442 }
9443 didWarnInvalidHydration = true;
9444 warningWithoutStack$1(false, 'Did not expect server HTML to contain a <%s> in <%s>.', child.nodeName.toLowerCase(), parentNode.nodeName.toLowerCase());
9445 }
9446}
9447
9448function warnForDeletedHydratableText(parentNode, child) {
9449 {
9450 if (didWarnInvalidHydration) {
9451 return;
9452 }
9453 didWarnInvalidHydration = true;
9454 warningWithoutStack$1(false, 'Did not expect server HTML to contain the text node "%s" in <%s>.', child.nodeValue, parentNode.nodeName.toLowerCase());
9455 }
9456}
9457
9458function warnForInsertedHydratedElement(parentNode, tag, props) {
9459 {
9460 if (didWarnInvalidHydration) {
9461 return;
9462 }
9463 didWarnInvalidHydration = true;
9464 warningWithoutStack$1(false, 'Expected server HTML to contain a matching <%s> in <%s>.', tag, parentNode.nodeName.toLowerCase());
9465 }
9466}
9467
9468function warnForInsertedHydratedText(parentNode, text) {
9469 {
9470 if (text === '') {
9471 // We expect to insert empty text nodes since they're not represented in
9472 // the HTML.
9473 // TODO: Remove this special case if we can just avoid inserting empty
9474 // text nodes.
9475 return;
9476 }
9477 if (didWarnInvalidHydration) {
9478 return;
9479 }
9480 didWarnInvalidHydration = true;
9481 warningWithoutStack$1(false, 'Expected server HTML to contain a matching text node for "%s" in <%s>.', text, parentNode.nodeName.toLowerCase());
9482 }
9483}
9484
9485function restoreControlledState$1(domElement, tag, props) {
9486 switch (tag) {
9487 case 'input':
9488 restoreControlledState(domElement, props);
9489 return;
9490 case 'textarea':
9491 restoreControlledState$3(domElement, props);
9492 return;
9493 case 'select':
9494 restoreControlledState$2(domElement, props);
9495 return;
9496 }
9497}
9498
9499function listenToEventResponderEventTypes(eventTypes, element) {
9500 if (enableFlareAPI) {
9501 // Get the listening Set for this element. We use this to track
9502 // what events we're listening to.
9503 var listeningSet = getListeningSetForElement(element);
9504
9505 // Go through each target event type of the event responder
9506 for (var i = 0, length = eventTypes.length; i < length; ++i) {
9507 var eventType = eventTypes[i];
9508 var isPassive = !endsWith(eventType, '_active');
9509 var eventKey = isPassive ? eventType + '_passive' : eventType;
9510 var targetEventType = isPassive ? eventType : eventType.substring(0, eventType.length - 7);
9511 if (!listeningSet.has(eventKey)) {
9512 trapEventForResponderEventSystem(element, targetEventType, isPassive);
9513 listeningSet.add(eventKey);
9514 }
9515 }
9516 }
9517}
9518
9519// We can remove this once the event API is stable and out of a flag
9520if (enableFlareAPI) {
9521 setListenToResponderEventTypes(listenToEventResponderEventTypes);
9522}
9523
9524// TODO: direct imports like some-package/src/* are bad. Fix me.
9525var validateDOMNesting = function () {};
9526var updatedAncestorInfo = function () {};
9527
9528{
9529 // This validation code was written based on the HTML5 parsing spec:
9530 // https://html.spec.whatwg.org/multipage/syntax.html#has-an-element-in-scope
9531 //
9532 // Note: this does not catch all invalid nesting, nor does it try to (as it's
9533 // not clear what practical benefit doing so provides); instead, we warn only
9534 // for cases where the parser will give a parse tree differing from what React
9535 // intended. For example, <b><div></div></b> is invalid but we don't warn
9536 // because it still parses correctly; we do warn for other cases like nested
9537 // <p> tags where the beginning of the second element implicitly closes the
9538 // first, causing a confusing mess.
9539
9540 // https://html.spec.whatwg.org/multipage/syntax.html#special
9541 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'];
9542
9543 // https://html.spec.whatwg.org/multipage/syntax.html#has-an-element-in-scope
9544 var inScopeTags = ['applet', 'caption', 'html', 'table', 'td', 'th', 'marquee', 'object', 'template',
9545
9546 // https://html.spec.whatwg.org/multipage/syntax.html#html-integration-point
9547 // TODO: Distinguish by namespace here -- for <title>, including it here
9548 // errs on the side of fewer warnings
9549 'foreignObject', 'desc', 'title'];
9550
9551 // https://html.spec.whatwg.org/multipage/syntax.html#has-an-element-in-button-scope
9552 var buttonScopeTags = inScopeTags.concat(['button']);
9553
9554 // https://html.spec.whatwg.org/multipage/syntax.html#generate-implied-end-tags
9555 var impliedEndTags = ['dd', 'dt', 'li', 'option', 'optgroup', 'p', 'rp', 'rt'];
9556
9557 var emptyAncestorInfo = {
9558 current: null,
9559
9560 formTag: null,
9561 aTagInScope: null,
9562 buttonTagInScope: null,
9563 nobrTagInScope: null,
9564 pTagInButtonScope: null,
9565
9566 listItemTagAutoclosing: null,
9567 dlItemTagAutoclosing: null
9568 };
9569
9570 updatedAncestorInfo = function (oldInfo, tag) {
9571 var ancestorInfo = _assign({}, oldInfo || emptyAncestorInfo);
9572 var info = { tag: tag };
9573
9574 if (inScopeTags.indexOf(tag) !== -1) {
9575 ancestorInfo.aTagInScope = null;
9576 ancestorInfo.buttonTagInScope = null;
9577 ancestorInfo.nobrTagInScope = null;
9578 }
9579 if (buttonScopeTags.indexOf(tag) !== -1) {
9580 ancestorInfo.pTagInButtonScope = null;
9581 }
9582
9583 // See rules for 'li', 'dd', 'dt' start tags in
9584 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inbody
9585 if (specialTags.indexOf(tag) !== -1 && tag !== 'address' && tag !== 'div' && tag !== 'p') {
9586 ancestorInfo.listItemTagAutoclosing = null;
9587 ancestorInfo.dlItemTagAutoclosing = null;
9588 }
9589
9590 ancestorInfo.current = info;
9591
9592 if (tag === 'form') {
9593 ancestorInfo.formTag = info;
9594 }
9595 if (tag === 'a') {
9596 ancestorInfo.aTagInScope = info;
9597 }
9598 if (tag === 'button') {
9599 ancestorInfo.buttonTagInScope = info;
9600 }
9601 if (tag === 'nobr') {
9602 ancestorInfo.nobrTagInScope = info;
9603 }
9604 if (tag === 'p') {
9605 ancestorInfo.pTagInButtonScope = info;
9606 }
9607 if (tag === 'li') {
9608 ancestorInfo.listItemTagAutoclosing = info;
9609 }
9610 if (tag === 'dd' || tag === 'dt') {
9611 ancestorInfo.dlItemTagAutoclosing = info;
9612 }
9613
9614 return ancestorInfo;
9615 };
9616
9617 /**
9618 * Returns whether
9619 */
9620 var isTagValidWithParent = function (tag, parentTag) {
9621 // First, let's check if we're in an unusual parsing mode...
9622 switch (parentTag) {
9623 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inselect
9624 case 'select':
9625 return tag === 'option' || tag === 'optgroup' || tag === '#text';
9626 case 'optgroup':
9627 return tag === 'option' || tag === '#text';
9628 // Strictly speaking, seeing an <option> doesn't mean we're in a <select>
9629 // but
9630 case 'option':
9631 return tag === '#text';
9632 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intd
9633 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-incaption
9634 // No special behavior since these rules fall back to "in body" mode for
9635 // all except special table nodes which cause bad parsing behavior anyway.
9636
9637 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intr
9638 case 'tr':
9639 return tag === 'th' || tag === 'td' || tag === 'style' || tag === 'script' || tag === 'template';
9640 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intbody
9641 case 'tbody':
9642 case 'thead':
9643 case 'tfoot':
9644 return tag === 'tr' || tag === 'style' || tag === 'script' || tag === 'template';
9645 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-incolgroup
9646 case 'colgroup':
9647 return tag === 'col' || tag === 'template';
9648 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intable
9649 case 'table':
9650 return tag === 'caption' || tag === 'colgroup' || tag === 'tbody' || tag === 'tfoot' || tag === 'thead' || tag === 'style' || tag === 'script' || tag === 'template';
9651 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inhead
9652 case 'head':
9653 return tag === 'base' || tag === 'basefont' || tag === 'bgsound' || tag === 'link' || tag === 'meta' || tag === 'title' || tag === 'noscript' || tag === 'noframes' || tag === 'style' || tag === 'script' || tag === 'template';
9654 // https://html.spec.whatwg.org/multipage/semantics.html#the-html-element
9655 case 'html':
9656 return tag === 'head' || tag === 'body' || tag === 'frameset';
9657 case 'frameset':
9658 return tag === 'frame';
9659 case '#document':
9660 return tag === 'html';
9661 }
9662
9663 // Probably in the "in body" parsing mode, so we outlaw only tag combos
9664 // where the parsing rules cause implicit opens or closes to be added.
9665 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inbody
9666 switch (tag) {
9667 case 'h1':
9668 case 'h2':
9669 case 'h3':
9670 case 'h4':
9671 case 'h5':
9672 case 'h6':
9673 return parentTag !== 'h1' && parentTag !== 'h2' && parentTag !== 'h3' && parentTag !== 'h4' && parentTag !== 'h5' && parentTag !== 'h6';
9674
9675 case 'rp':
9676 case 'rt':
9677 return impliedEndTags.indexOf(parentTag) === -1;
9678
9679 case 'body':
9680 case 'caption':
9681 case 'col':
9682 case 'colgroup':
9683 case 'frameset':
9684 case 'frame':
9685 case 'head':
9686 case 'html':
9687 case 'tbody':
9688 case 'td':
9689 case 'tfoot':
9690 case 'th':
9691 case 'thead':
9692 case 'tr':
9693 // These tags are only valid with a few parents that have special child
9694 // parsing rules -- if we're down here, then none of those matched and
9695 // so we allow it only if we don't know what the parent is, as all other
9696 // cases are invalid.
9697 return parentTag == null;
9698 }
9699
9700 return true;
9701 };
9702
9703 /**
9704 * Returns whether
9705 */
9706 var findInvalidAncestorForTag = function (tag, ancestorInfo) {
9707 switch (tag) {
9708 case 'address':
9709 case 'article':
9710 case 'aside':
9711 case 'blockquote':
9712 case 'center':
9713 case 'details':
9714 case 'dialog':
9715 case 'dir':
9716 case 'div':
9717 case 'dl':
9718 case 'fieldset':
9719 case 'figcaption':
9720 case 'figure':
9721 case 'footer':
9722 case 'header':
9723 case 'hgroup':
9724 case 'main':
9725 case 'menu':
9726 case 'nav':
9727 case 'ol':
9728 case 'p':
9729 case 'section':
9730 case 'summary':
9731 case 'ul':
9732 case 'pre':
9733 case 'listing':
9734 case 'table':
9735 case 'hr':
9736 case 'xmp':
9737 case 'h1':
9738 case 'h2':
9739 case 'h3':
9740 case 'h4':
9741 case 'h5':
9742 case 'h6':
9743 return ancestorInfo.pTagInButtonScope;
9744
9745 case 'form':
9746 return ancestorInfo.formTag || ancestorInfo.pTagInButtonScope;
9747
9748 case 'li':
9749 return ancestorInfo.listItemTagAutoclosing;
9750
9751 case 'dd':
9752 case 'dt':
9753 return ancestorInfo.dlItemTagAutoclosing;
9754
9755 case 'button':
9756 return ancestorInfo.buttonTagInScope;
9757
9758 case 'a':
9759 // Spec says something about storing a list of markers, but it sounds
9760 // equivalent to this check.
9761 return ancestorInfo.aTagInScope;
9762
9763 case 'nobr':
9764 return ancestorInfo.nobrTagInScope;
9765 }
9766
9767 return null;
9768 };
9769
9770 var didWarn$1 = {};
9771
9772 validateDOMNesting = function (childTag, childText, ancestorInfo) {
9773 ancestorInfo = ancestorInfo || emptyAncestorInfo;
9774 var parentInfo = ancestorInfo.current;
9775 var parentTag = parentInfo && parentInfo.tag;
9776
9777 if (childText != null) {
9778 !(childTag == null) ? warningWithoutStack$1(false, 'validateDOMNesting: when childText is passed, childTag should be null') : void 0;
9779 childTag = '#text';
9780 }
9781
9782 var invalidParent = isTagValidWithParent(childTag, parentTag) ? null : parentInfo;
9783 var invalidAncestor = invalidParent ? null : findInvalidAncestorForTag(childTag, ancestorInfo);
9784 var invalidParentOrAncestor = invalidParent || invalidAncestor;
9785 if (!invalidParentOrAncestor) {
9786 return;
9787 }
9788
9789 var ancestorTag = invalidParentOrAncestor.tag;
9790 var addendum = getCurrentFiberStackInDev();
9791
9792 var warnKey = !!invalidParent + '|' + childTag + '|' + ancestorTag + '|' + addendum;
9793 if (didWarn$1[warnKey]) {
9794 return;
9795 }
9796 didWarn$1[warnKey] = true;
9797
9798 var tagDisplayName = childTag;
9799 var whitespaceInfo = '';
9800 if (childTag === '#text') {
9801 if (/\S/.test(childText)) {
9802 tagDisplayName = 'Text nodes';
9803 } else {
9804 tagDisplayName = 'Whitespace text nodes';
9805 whitespaceInfo = " Make sure you don't have any extra whitespace between tags on " + 'each line of your source code.';
9806 }
9807 } else {
9808 tagDisplayName = '<' + childTag + '>';
9809 }
9810
9811 if (invalidParent) {
9812 var info = '';
9813 if (ancestorTag === 'table' && childTag === 'tr') {
9814 info += ' Add a <tbody> to your code to match the DOM tree generated by ' + 'the browser.';
9815 }
9816 warningWithoutStack$1(false, 'validateDOMNesting(...): %s cannot appear as a child of <%s>.%s%s%s', tagDisplayName, ancestorTag, whitespaceInfo, info, addendum);
9817 } else {
9818 warningWithoutStack$1(false, 'validateDOMNesting(...): %s cannot appear as a descendant of ' + '<%s>.%s', tagDisplayName, ancestorTag, addendum);
9819 }
9820 };
9821}
9822
9823// Renderers that don't support persistence
9824// can re-export everything from this module.
9825
9826function shim() {
9827 (function () {
9828 {
9829 {
9830 throw ReactError(Error('The current renderer does not support persistence. This error is likely caused by a bug in React. Please file an issue.'));
9831 }
9832 }
9833 })();
9834}
9835
9836// Persistence (when unsupported)
9837var supportsPersistence = false;
9838var cloneInstance = shim;
9839var cloneFundamentalInstance = shim;
9840var createContainerChildSet = shim;
9841var appendChildToContainerChildSet = shim;
9842var finalizeContainerChildren = shim;
9843var replaceContainerChildren = shim;
9844var cloneHiddenInstance = shim;
9845var cloneHiddenTextInstance = shim;
9846
9847var SUPPRESS_HYDRATION_WARNING = void 0;
9848{
9849 SUPPRESS_HYDRATION_WARNING = 'suppressHydrationWarning';
9850}
9851
9852var SUSPENSE_START_DATA = '$';
9853var SUSPENSE_END_DATA = '/$';
9854var SUSPENSE_PENDING_START_DATA = '$?';
9855var SUSPENSE_FALLBACK_START_DATA = '$!';
9856
9857var STYLE = 'style';
9858
9859var eventsEnabled = null;
9860var selectionInformation = null;
9861
9862function shouldAutoFocusHostComponent(type, props) {
9863 switch (type) {
9864 case 'button':
9865 case 'input':
9866 case 'select':
9867 case 'textarea':
9868 return !!props.autoFocus;
9869 }
9870 return false;
9871}
9872
9873function getRootHostContext(rootContainerInstance) {
9874 var type = void 0;
9875 var namespace = void 0;
9876 var nodeType = rootContainerInstance.nodeType;
9877 switch (nodeType) {
9878 case DOCUMENT_NODE:
9879 case DOCUMENT_FRAGMENT_NODE:
9880 {
9881 type = nodeType === DOCUMENT_NODE ? '#document' : '#fragment';
9882 var root = rootContainerInstance.documentElement;
9883 namespace = root ? root.namespaceURI : getChildNamespace(null, '');
9884 break;
9885 }
9886 default:
9887 {
9888 var container = nodeType === COMMENT_NODE ? rootContainerInstance.parentNode : rootContainerInstance;
9889 var ownNamespace = container.namespaceURI || null;
9890 type = container.tagName;
9891 namespace = getChildNamespace(ownNamespace, type);
9892 break;
9893 }
9894 }
9895 {
9896 var validatedTag = type.toLowerCase();
9897 var _ancestorInfo = updatedAncestorInfo(null, validatedTag);
9898 return { namespace: namespace, ancestorInfo: _ancestorInfo };
9899 }
9900 return namespace;
9901}
9902
9903function getChildHostContext(parentHostContext, type, rootContainerInstance) {
9904 {
9905 var parentHostContextDev = parentHostContext;
9906 var _namespace = getChildNamespace(parentHostContextDev.namespace, type);
9907 var _ancestorInfo2 = updatedAncestorInfo(parentHostContextDev.ancestorInfo, type);
9908 return { namespace: _namespace, ancestorInfo: _ancestorInfo2 };
9909 }
9910 var parentNamespace = parentHostContext;
9911 return getChildNamespace(parentNamespace, type);
9912}
9913
9914function getPublicInstance(instance) {
9915 return instance;
9916}
9917
9918function prepareForCommit(containerInfo) {
9919 eventsEnabled = isEnabled();
9920 selectionInformation = getSelectionInformation();
9921 setEnabled(false);
9922}
9923
9924function resetAfterCommit(containerInfo) {
9925 restoreSelection(selectionInformation);
9926 selectionInformation = null;
9927 setEnabled(eventsEnabled);
9928 eventsEnabled = null;
9929}
9930
9931function createInstance(type, props, rootContainerInstance, hostContext, internalInstanceHandle) {
9932 var parentNamespace = void 0;
9933 {
9934 // TODO: take namespace into account when validating.
9935 var hostContextDev = hostContext;
9936 validateDOMNesting(type, null, hostContextDev.ancestorInfo);
9937 if (typeof props.children === 'string' || typeof props.children === 'number') {
9938 var string = '' + props.children;
9939 var ownAncestorInfo = updatedAncestorInfo(hostContextDev.ancestorInfo, type);
9940 validateDOMNesting(null, string, ownAncestorInfo);
9941 }
9942 parentNamespace = hostContextDev.namespace;
9943 }
9944 var domElement = createElement(type, props, rootContainerInstance, parentNamespace);
9945 precacheFiberNode(internalInstanceHandle, domElement);
9946 updateFiberProps(domElement, props);
9947 return domElement;
9948}
9949
9950function appendInitialChild(parentInstance, child) {
9951 parentInstance.appendChild(child);
9952}
9953
9954function finalizeInitialChildren(domElement, type, props, rootContainerInstance, hostContext) {
9955 setInitialProperties(domElement, type, props, rootContainerInstance);
9956 return shouldAutoFocusHostComponent(type, props);
9957}
9958
9959function prepareUpdate(domElement, type, oldProps, newProps, rootContainerInstance, hostContext) {
9960 {
9961 var hostContextDev = hostContext;
9962 if (typeof newProps.children !== typeof oldProps.children && (typeof newProps.children === 'string' || typeof newProps.children === 'number')) {
9963 var string = '' + newProps.children;
9964 var ownAncestorInfo = updatedAncestorInfo(hostContextDev.ancestorInfo, type);
9965 validateDOMNesting(null, string, ownAncestorInfo);
9966 }
9967 }
9968 return diffProperties(domElement, type, oldProps, newProps, rootContainerInstance);
9969}
9970
9971function shouldSetTextContent(type, props) {
9972 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;
9973}
9974
9975function shouldDeprioritizeSubtree(type, props) {
9976 return !!props.hidden;
9977}
9978
9979function createTextInstance(text, rootContainerInstance, hostContext, internalInstanceHandle) {
9980 {
9981 var hostContextDev = hostContext;
9982 validateDOMNesting(null, text, hostContextDev.ancestorInfo);
9983 }
9984 var textNode = createTextNode(text, rootContainerInstance);
9985 precacheFiberNode(internalInstanceHandle, textNode);
9986 return textNode;
9987}
9988
9989var isPrimaryRenderer = true;
9990var warnsIfNotActing = true;
9991// This initialization code may run even on server environments
9992// if a component just imports ReactDOM (e.g. for findDOMNode).
9993// Some environments might not have setTimeout or clearTimeout.
9994var scheduleTimeout = typeof setTimeout === 'function' ? setTimeout : undefined;
9995var cancelTimeout = typeof clearTimeout === 'function' ? clearTimeout : undefined;
9996var noTimeout = -1;
9997
9998// -------------------
9999// Mutation
10000// -------------------
10001
10002var supportsMutation = true;
10003
10004function commitMount(domElement, type, newProps, internalInstanceHandle) {
10005 // Despite the naming that might imply otherwise, this method only
10006 // fires if there is an `Update` effect scheduled during mounting.
10007 // This happens if `finalizeInitialChildren` returns `true` (which it
10008 // does to implement the `autoFocus` attribute on the client). But
10009 // there are also other cases when this might happen (such as patching
10010 // up text content during hydration mismatch). So we'll check this again.
10011 if (shouldAutoFocusHostComponent(type, newProps)) {
10012 domElement.focus();
10013 }
10014}
10015
10016function commitUpdate(domElement, updatePayload, type, oldProps, newProps, internalInstanceHandle) {
10017 // Update the props handle so that we know which props are the ones with
10018 // with current event handlers.
10019 updateFiberProps(domElement, newProps);
10020 // Apply the diff to the DOM node.
10021 updateProperties(domElement, updatePayload, type, oldProps, newProps);
10022}
10023
10024function resetTextContent(domElement) {
10025 setTextContent(domElement, '');
10026}
10027
10028function commitTextUpdate(textInstance, oldText, newText) {
10029 textInstance.nodeValue = newText;
10030}
10031
10032function appendChild(parentInstance, child) {
10033 parentInstance.appendChild(child);
10034}
10035
10036function appendChildToContainer(container, child) {
10037 var parentNode = void 0;
10038 if (container.nodeType === COMMENT_NODE) {
10039 parentNode = container.parentNode;
10040 parentNode.insertBefore(child, container);
10041 } else {
10042 parentNode = container;
10043 parentNode.appendChild(child);
10044 }
10045 // This container might be used for a portal.
10046 // If something inside a portal is clicked, that click should bubble
10047 // through the React tree. However, on Mobile Safari the click would
10048 // never bubble through the *DOM* tree unless an ancestor with onclick
10049 // event exists. So we wouldn't see it and dispatch it.
10050 // This is why we ensure that non React root containers have inline onclick
10051 // defined.
10052 // https://github.com/facebook/react/issues/11918
10053 var reactRootContainer = container._reactRootContainer;
10054 if ((reactRootContainer === null || reactRootContainer === undefined) && parentNode.onclick === null) {
10055 // TODO: This cast may not be sound for SVG, MathML or custom elements.
10056 trapClickOnNonInteractiveElement(parentNode);
10057 }
10058}
10059
10060function insertBefore(parentInstance, child, beforeChild) {
10061 parentInstance.insertBefore(child, beforeChild);
10062}
10063
10064function insertInContainerBefore(container, child, beforeChild) {
10065 if (container.nodeType === COMMENT_NODE) {
10066 container.parentNode.insertBefore(child, beforeChild);
10067 } else {
10068 container.insertBefore(child, beforeChild);
10069 }
10070}
10071
10072function removeChild(parentInstance, child) {
10073 parentInstance.removeChild(child);
10074}
10075
10076function removeChildFromContainer(container, child) {
10077 if (container.nodeType === COMMENT_NODE) {
10078 container.parentNode.removeChild(child);
10079 } else {
10080 container.removeChild(child);
10081 }
10082}
10083
10084function clearSuspenseBoundary(parentInstance, suspenseInstance) {
10085 var node = suspenseInstance;
10086 // Delete all nodes within this suspense boundary.
10087 // There might be nested nodes so we need to keep track of how
10088 // deep we are and only break out when we're back on top.
10089 var depth = 0;
10090 do {
10091 var nextNode = node.nextSibling;
10092 parentInstance.removeChild(node);
10093 if (nextNode && nextNode.nodeType === COMMENT_NODE) {
10094 var data = nextNode.data;
10095 if (data === SUSPENSE_END_DATA) {
10096 if (depth === 0) {
10097 parentInstance.removeChild(nextNode);
10098 return;
10099 } else {
10100 depth--;
10101 }
10102 } else if (data === SUSPENSE_START_DATA || data === SUSPENSE_PENDING_START_DATA || data === SUSPENSE_FALLBACK_START_DATA) {
10103 depth++;
10104 }
10105 }
10106 node = nextNode;
10107 } while (node);
10108 // TODO: Warn, we didn't find the end comment boundary.
10109}
10110
10111function clearSuspenseBoundaryFromContainer(container, suspenseInstance) {
10112 if (container.nodeType === COMMENT_NODE) {
10113 clearSuspenseBoundary(container.parentNode, suspenseInstance);
10114 } else if (container.nodeType === ELEMENT_NODE) {
10115 clearSuspenseBoundary(container, suspenseInstance);
10116 } else {
10117 // Document nodes should never contain suspense boundaries.
10118 }
10119}
10120
10121function hideInstance(instance) {
10122 // TODO: Does this work for all element types? What about MathML? Should we
10123 // pass host context to this method?
10124 instance = instance;
10125 var style = instance.style;
10126 if (typeof style.setProperty === 'function') {
10127 style.setProperty('display', 'none', 'important');
10128 } else {
10129 style.display = 'none';
10130 }
10131}
10132
10133function hideTextInstance(textInstance) {
10134 textInstance.nodeValue = '';
10135}
10136
10137function unhideInstance(instance, props) {
10138 instance = instance;
10139 var styleProp = props[STYLE];
10140 var display = styleProp !== undefined && styleProp !== null && styleProp.hasOwnProperty('display') ? styleProp.display : null;
10141 instance.style.display = dangerousStyleValue('display', display);
10142}
10143
10144function unhideTextInstance(textInstance, text) {
10145 textInstance.nodeValue = text;
10146}
10147
10148// -------------------
10149// Hydration
10150// -------------------
10151
10152var supportsHydration = true;
10153
10154function canHydrateInstance(instance, type, props) {
10155 if (instance.nodeType !== ELEMENT_NODE || type.toLowerCase() !== instance.nodeName.toLowerCase()) {
10156 return null;
10157 }
10158 // This has now been refined to an element node.
10159 return instance;
10160}
10161
10162function canHydrateTextInstance(instance, text) {
10163 if (text === '' || instance.nodeType !== TEXT_NODE) {
10164 // Empty strings are not parsed by HTML so there won't be a correct match here.
10165 return null;
10166 }
10167 // This has now been refined to a text node.
10168 return instance;
10169}
10170
10171function canHydrateSuspenseInstance(instance) {
10172 if (instance.nodeType !== COMMENT_NODE) {
10173 // Empty strings are not parsed by HTML so there won't be a correct match here.
10174 return null;
10175 }
10176 // This has now been refined to a suspense node.
10177 return instance;
10178}
10179
10180function isSuspenseInstancePending(instance) {
10181 return instance.data === SUSPENSE_PENDING_START_DATA;
10182}
10183
10184function isSuspenseInstanceFallback(instance) {
10185 return instance.data === SUSPENSE_FALLBACK_START_DATA;
10186}
10187
10188function registerSuspenseInstanceRetry(instance, callback) {
10189 instance._reactRetry = callback;
10190}
10191
10192function getNextHydratable(node) {
10193 // Skip non-hydratable nodes.
10194 for (; node != null; node = node.nextSibling) {
10195 var nodeType = node.nodeType;
10196 if (nodeType === ELEMENT_NODE || nodeType === TEXT_NODE) {
10197 break;
10198 }
10199 if (enableSuspenseServerRenderer) {
10200 if (nodeType === COMMENT_NODE) {
10201 break;
10202 }
10203 var nodeData = node.data;
10204 if (nodeData === SUSPENSE_START_DATA || nodeData === SUSPENSE_FALLBACK_START_DATA || nodeData === SUSPENSE_PENDING_START_DATA) {
10205 break;
10206 }
10207 }
10208 }
10209 return node;
10210}
10211
10212function getNextHydratableSibling(instance) {
10213 return getNextHydratable(instance.nextSibling);
10214}
10215
10216function getFirstHydratableChild(parentInstance) {
10217 return getNextHydratable(parentInstance.firstChild);
10218}
10219
10220function hydrateInstance(instance, type, props, rootContainerInstance, hostContext, internalInstanceHandle) {
10221 precacheFiberNode(internalInstanceHandle, instance);
10222 // TODO: Possibly defer this until the commit phase where all the events
10223 // get attached.
10224 updateFiberProps(instance, props);
10225 var parentNamespace = void 0;
10226 {
10227 var hostContextDev = hostContext;
10228 parentNamespace = hostContextDev.namespace;
10229 }
10230 return diffHydratedProperties(instance, type, props, parentNamespace, rootContainerInstance);
10231}
10232
10233function hydrateTextInstance(textInstance, text, internalInstanceHandle) {
10234 precacheFiberNode(internalInstanceHandle, textInstance);
10235 return diffHydratedText(textInstance, text);
10236}
10237
10238function getNextHydratableInstanceAfterSuspenseInstance(suspenseInstance) {
10239 var node = suspenseInstance.nextSibling;
10240 // Skip past all nodes within this suspense boundary.
10241 // There might be nested nodes so we need to keep track of how
10242 // deep we are and only break out when we're back on top.
10243 var depth = 0;
10244 while (node) {
10245 if (node.nodeType === COMMENT_NODE) {
10246 var data = node.data;
10247 if (data === SUSPENSE_END_DATA) {
10248 if (depth === 0) {
10249 return getNextHydratableSibling(node);
10250 } else {
10251 depth--;
10252 }
10253 } else if (data === SUSPENSE_START_DATA) {
10254 depth++;
10255 }
10256 }
10257 node = node.nextSibling;
10258 }
10259 // TODO: Warn, we didn't find the end comment boundary.
10260 return null;
10261}
10262
10263function didNotMatchHydratedContainerTextInstance(parentContainer, textInstance, text) {
10264 {
10265 warnForUnmatchedText(textInstance, text);
10266 }
10267}
10268
10269function didNotMatchHydratedTextInstance(parentType, parentProps, parentInstance, textInstance, text) {
10270 if (true && parentProps[SUPPRESS_HYDRATION_WARNING] !== true) {
10271 warnForUnmatchedText(textInstance, text);
10272 }
10273}
10274
10275function didNotHydrateContainerInstance(parentContainer, instance) {
10276 {
10277 if (instance.nodeType === ELEMENT_NODE) {
10278 warnForDeletedHydratableElement(parentContainer, instance);
10279 } else if (instance.nodeType === COMMENT_NODE) {
10280 // TODO: warnForDeletedHydratableSuspenseBoundary
10281 } else {
10282 warnForDeletedHydratableText(parentContainer, instance);
10283 }
10284 }
10285}
10286
10287function didNotHydrateInstance(parentType, parentProps, parentInstance, instance) {
10288 if (true && parentProps[SUPPRESS_HYDRATION_WARNING] !== true) {
10289 if (instance.nodeType === ELEMENT_NODE) {
10290 warnForDeletedHydratableElement(parentInstance, instance);
10291 } else if (instance.nodeType === COMMENT_NODE) {
10292 // TODO: warnForDeletedHydratableSuspenseBoundary
10293 } else {
10294 warnForDeletedHydratableText(parentInstance, instance);
10295 }
10296 }
10297}
10298
10299function didNotFindHydratableContainerInstance(parentContainer, type, props) {
10300 {
10301 warnForInsertedHydratedElement(parentContainer, type, props);
10302 }
10303}
10304
10305function didNotFindHydratableContainerTextInstance(parentContainer, text) {
10306 {
10307 warnForInsertedHydratedText(parentContainer, text);
10308 }
10309}
10310
10311
10312
10313function didNotFindHydratableInstance(parentType, parentProps, parentInstance, type, props) {
10314 if (true && parentProps[SUPPRESS_HYDRATION_WARNING] !== true) {
10315 warnForInsertedHydratedElement(parentInstance, type, props);
10316 }
10317}
10318
10319function didNotFindHydratableTextInstance(parentType, parentProps, parentInstance, text) {
10320 if (true && parentProps[SUPPRESS_HYDRATION_WARNING] !== true) {
10321 warnForInsertedHydratedText(parentInstance, text);
10322 }
10323}
10324
10325function didNotFindHydratableSuspenseInstance(parentType, parentProps, parentInstance) {
10326 if (true && parentProps[SUPPRESS_HYDRATION_WARNING] !== true) {
10327 // TODO: warnForInsertedHydratedSuspense(parentInstance);
10328 }
10329}
10330
10331function mountResponderInstance(responder, responderInstance, responderProps, responderState, instance, rootContainerInstance) {
10332 // Listen to events
10333 var doc = rootContainerInstance.ownerDocument;
10334 var documentBody = doc.body || doc;
10335 var _ref = responder,
10336 rootEventTypes = _ref.rootEventTypes,
10337 targetEventTypes = _ref.targetEventTypes;
10338
10339 if (targetEventTypes !== null) {
10340 listenToEventResponderEventTypes(targetEventTypes, documentBody);
10341 }
10342 if (rootEventTypes !== null) {
10343 addRootEventTypesForResponderInstance(responderInstance, rootEventTypes);
10344 listenToEventResponderEventTypes(rootEventTypes, documentBody);
10345 }
10346 mountEventResponder(responder, responderInstance, responderProps, responderState);
10347 return responderInstance;
10348}
10349
10350function unmountResponderInstance(responderInstance) {
10351 if (enableFlareAPI) {
10352 // TODO stop listening to targetEventTypes
10353 unmountEventResponder(responderInstance);
10354 }
10355}
10356
10357function getFundamentalComponentInstance(fundamentalInstance) {
10358 if (enableFundamentalAPI) {
10359 var currentFiber = fundamentalInstance.currentFiber,
10360 impl = fundamentalInstance.impl,
10361 _props = fundamentalInstance.props,
10362 state = fundamentalInstance.state;
10363
10364 var instance = impl.getInstance(null, _props, state);
10365 precacheFiberNode(currentFiber, instance);
10366 return instance;
10367 }
10368 // Because of the flag above, this gets around the Flow error;
10369 return null;
10370}
10371
10372function mountFundamentalComponent(fundamentalInstance) {
10373 if (enableFundamentalAPI) {
10374 var impl = fundamentalInstance.impl,
10375 instance = fundamentalInstance.instance,
10376 _props2 = fundamentalInstance.props,
10377 state = fundamentalInstance.state;
10378
10379 var onMount = impl.onMount;
10380 if (onMount !== undefined) {
10381 onMount(null, instance, _props2, state);
10382 }
10383 }
10384}
10385
10386function shouldUpdateFundamentalComponent(fundamentalInstance) {
10387 if (enableFundamentalAPI) {
10388 var impl = fundamentalInstance.impl,
10389 prevProps = fundamentalInstance.prevProps,
10390 _props3 = fundamentalInstance.props,
10391 state = fundamentalInstance.state;
10392
10393 var shouldUpdate = impl.shouldUpdate;
10394 if (shouldUpdate !== undefined) {
10395 return shouldUpdate(null, prevProps, _props3, state);
10396 }
10397 }
10398 return true;
10399}
10400
10401function updateFundamentalComponent(fundamentalInstance) {
10402 if (enableFundamentalAPI) {
10403 var impl = fundamentalInstance.impl,
10404 instance = fundamentalInstance.instance,
10405 prevProps = fundamentalInstance.prevProps,
10406 _props4 = fundamentalInstance.props,
10407 state = fundamentalInstance.state;
10408
10409 var onUpdate = impl.onUpdate;
10410 if (onUpdate !== undefined) {
10411 onUpdate(null, instance, prevProps, _props4, state);
10412 }
10413 }
10414}
10415
10416function unmountFundamentalComponent(fundamentalInstance) {
10417 if (enableFundamentalAPI) {
10418 var impl = fundamentalInstance.impl,
10419 instance = fundamentalInstance.instance,
10420 _props5 = fundamentalInstance.props,
10421 state = fundamentalInstance.state;
10422
10423 var onUnmount = impl.onUnmount;
10424 if (onUnmount !== undefined) {
10425 onUnmount(null, instance, _props5, state);
10426 }
10427 }
10428}
10429
10430// Prefix measurements so that it's possible to filter them.
10431// Longer prefixes are hard to read in DevTools.
10432var reactEmoji = '\u269B';
10433var warningEmoji = '\u26D4';
10434var supportsUserTiming = typeof performance !== 'undefined' && typeof performance.mark === 'function' && typeof performance.clearMarks === 'function' && typeof performance.measure === 'function' && typeof performance.clearMeasures === 'function';
10435
10436// Keep track of current fiber so that we know the path to unwind on pause.
10437// TODO: this looks the same as nextUnitOfWork in scheduler. Can we unify them?
10438var currentFiber = null;
10439// If we're in the middle of user code, which fiber and method is it?
10440// Reusing `currentFiber` would be confusing for this because user code fiber
10441// can change during commit phase too, but we don't need to unwind it (since
10442// lifecycles in the commit phase don't resemble a tree).
10443var currentPhase = null;
10444var currentPhaseFiber = null;
10445// Did lifecycle hook schedule an update? This is often a performance problem,
10446// so we will keep track of it, and include it in the report.
10447// Track commits caused by cascading updates.
10448var isCommitting = false;
10449var hasScheduledUpdateInCurrentCommit = false;
10450var hasScheduledUpdateInCurrentPhase = false;
10451var commitCountInCurrentWorkLoop = 0;
10452var effectCountInCurrentCommit = 0;
10453var isWaitingForCallback = false;
10454// During commits, we only show a measurement once per method name
10455// to avoid stretch the commit phase with measurement overhead.
10456var labelsInCurrentCommit = new Set();
10457
10458var formatMarkName = function (markName) {
10459 return reactEmoji + ' ' + markName;
10460};
10461
10462var formatLabel = function (label, warning) {
10463 var prefix = warning ? warningEmoji + ' ' : reactEmoji + ' ';
10464 var suffix = warning ? ' Warning: ' + warning : '';
10465 return '' + prefix + label + suffix;
10466};
10467
10468var beginMark = function (markName) {
10469 performance.mark(formatMarkName(markName));
10470};
10471
10472var clearMark = function (markName) {
10473 performance.clearMarks(formatMarkName(markName));
10474};
10475
10476var endMark = function (label, markName, warning) {
10477 var formattedMarkName = formatMarkName(markName);
10478 var formattedLabel = formatLabel(label, warning);
10479 try {
10480 performance.measure(formattedLabel, formattedMarkName);
10481 } catch (err) {}
10482 // If previous mark was missing for some reason, this will throw.
10483 // This could only happen if React crashed in an unexpected place earlier.
10484 // Don't pile on with more errors.
10485
10486 // Clear marks immediately to avoid growing buffer.
10487 performance.clearMarks(formattedMarkName);
10488 performance.clearMeasures(formattedLabel);
10489};
10490
10491var getFiberMarkName = function (label, debugID) {
10492 return label + ' (#' + debugID + ')';
10493};
10494
10495var getFiberLabel = function (componentName, isMounted, phase) {
10496 if (phase === null) {
10497 // These are composite component total time measurements.
10498 return componentName + ' [' + (isMounted ? 'update' : 'mount') + ']';
10499 } else {
10500 // Composite component methods.
10501 return componentName + '.' + phase;
10502 }
10503};
10504
10505var beginFiberMark = function (fiber, phase) {
10506 var componentName = getComponentName(fiber.type) || 'Unknown';
10507 var debugID = fiber._debugID;
10508 var isMounted = fiber.alternate !== null;
10509 var label = getFiberLabel(componentName, isMounted, phase);
10510
10511 if (isCommitting && labelsInCurrentCommit.has(label)) {
10512 // During the commit phase, we don't show duplicate labels because
10513 // there is a fixed overhead for every measurement, and we don't
10514 // want to stretch the commit phase beyond necessary.
10515 return false;
10516 }
10517 labelsInCurrentCommit.add(label);
10518
10519 var markName = getFiberMarkName(label, debugID);
10520 beginMark(markName);
10521 return true;
10522};
10523
10524var clearFiberMark = function (fiber, phase) {
10525 var componentName = getComponentName(fiber.type) || 'Unknown';
10526 var debugID = fiber._debugID;
10527 var isMounted = fiber.alternate !== null;
10528 var label = getFiberLabel(componentName, isMounted, phase);
10529 var markName = getFiberMarkName(label, debugID);
10530 clearMark(markName);
10531};
10532
10533var endFiberMark = function (fiber, phase, warning) {
10534 var componentName = getComponentName(fiber.type) || 'Unknown';
10535 var debugID = fiber._debugID;
10536 var isMounted = fiber.alternate !== null;
10537 var label = getFiberLabel(componentName, isMounted, phase);
10538 var markName = getFiberMarkName(label, debugID);
10539 endMark(label, markName, warning);
10540};
10541
10542var shouldIgnoreFiber = function (fiber) {
10543 // Host components should be skipped in the timeline.
10544 // We could check typeof fiber.type, but does this work with RN?
10545 switch (fiber.tag) {
10546 case HostRoot:
10547 case HostComponent:
10548 case HostText:
10549 case HostPortal:
10550 case Fragment:
10551 case ContextProvider:
10552 case ContextConsumer:
10553 case Mode:
10554 return true;
10555 default:
10556 return false;
10557 }
10558};
10559
10560var clearPendingPhaseMeasurement = function () {
10561 if (currentPhase !== null && currentPhaseFiber !== null) {
10562 clearFiberMark(currentPhaseFiber, currentPhase);
10563 }
10564 currentPhaseFiber = null;
10565 currentPhase = null;
10566 hasScheduledUpdateInCurrentPhase = false;
10567};
10568
10569var pauseTimers = function () {
10570 // Stops all currently active measurements so that they can be resumed
10571 // if we continue in a later deferred loop from the same unit of work.
10572 var fiber = currentFiber;
10573 while (fiber) {
10574 if (fiber._debugIsCurrentlyTiming) {
10575 endFiberMark(fiber, null, null);
10576 }
10577 fiber = fiber.return;
10578 }
10579};
10580
10581var resumeTimersRecursively = function (fiber) {
10582 if (fiber.return !== null) {
10583 resumeTimersRecursively(fiber.return);
10584 }
10585 if (fiber._debugIsCurrentlyTiming) {
10586 beginFiberMark(fiber, null);
10587 }
10588};
10589
10590var resumeTimers = function () {
10591 // Resumes all measurements that were active during the last deferred loop.
10592 if (currentFiber !== null) {
10593 resumeTimersRecursively(currentFiber);
10594 }
10595};
10596
10597function recordEffect() {
10598 if (enableUserTimingAPI) {
10599 effectCountInCurrentCommit++;
10600 }
10601}
10602
10603function recordScheduleUpdate() {
10604 if (enableUserTimingAPI) {
10605 if (isCommitting) {
10606 hasScheduledUpdateInCurrentCommit = true;
10607 }
10608 if (currentPhase !== null && currentPhase !== 'componentWillMount' && currentPhase !== 'componentWillReceiveProps') {
10609 hasScheduledUpdateInCurrentPhase = true;
10610 }
10611 }
10612}
10613
10614function startRequestCallbackTimer() {
10615 if (enableUserTimingAPI) {
10616 if (supportsUserTiming && !isWaitingForCallback) {
10617 isWaitingForCallback = true;
10618 beginMark('(Waiting for async callback...)');
10619 }
10620 }
10621}
10622
10623function stopRequestCallbackTimer(didExpire) {
10624 if (enableUserTimingAPI) {
10625 if (supportsUserTiming) {
10626 isWaitingForCallback = false;
10627 var warning = didExpire ? 'Update expired; will flush synchronously' : null;
10628 endMark('(Waiting for async callback...)', '(Waiting for async callback...)', warning);
10629 }
10630 }
10631}
10632
10633function startWorkTimer(fiber) {
10634 if (enableUserTimingAPI) {
10635 if (!supportsUserTiming || shouldIgnoreFiber(fiber)) {
10636 return;
10637 }
10638 // If we pause, this is the fiber to unwind from.
10639 currentFiber = fiber;
10640 if (!beginFiberMark(fiber, null)) {
10641 return;
10642 }
10643 fiber._debugIsCurrentlyTiming = true;
10644 }
10645}
10646
10647function cancelWorkTimer(fiber) {
10648 if (enableUserTimingAPI) {
10649 if (!supportsUserTiming || shouldIgnoreFiber(fiber)) {
10650 return;
10651 }
10652 // Remember we shouldn't complete measurement for this fiber.
10653 // Otherwise flamechart will be deep even for small updates.
10654 fiber._debugIsCurrentlyTiming = false;
10655 clearFiberMark(fiber, null);
10656 }
10657}
10658
10659function stopWorkTimer(fiber) {
10660 if (enableUserTimingAPI) {
10661 if (!supportsUserTiming || shouldIgnoreFiber(fiber)) {
10662 return;
10663 }
10664 // If we pause, its parent is the fiber to unwind from.
10665 currentFiber = fiber.return;
10666 if (!fiber._debugIsCurrentlyTiming) {
10667 return;
10668 }
10669 fiber._debugIsCurrentlyTiming = false;
10670 endFiberMark(fiber, null, null);
10671 }
10672}
10673
10674function stopFailedWorkTimer(fiber) {
10675 if (enableUserTimingAPI) {
10676 if (!supportsUserTiming || shouldIgnoreFiber(fiber)) {
10677 return;
10678 }
10679 // If we pause, its parent is the fiber to unwind from.
10680 currentFiber = fiber.return;
10681 if (!fiber._debugIsCurrentlyTiming) {
10682 return;
10683 }
10684 fiber._debugIsCurrentlyTiming = false;
10685 var warning = fiber.tag === SuspenseComponent || fiber.tag === DehydratedSuspenseComponent ? 'Rendering was suspended' : 'An error was thrown inside this error boundary';
10686 endFiberMark(fiber, null, warning);
10687 }
10688}
10689
10690function startPhaseTimer(fiber, phase) {
10691 if (enableUserTimingAPI) {
10692 if (!supportsUserTiming) {
10693 return;
10694 }
10695 clearPendingPhaseMeasurement();
10696 if (!beginFiberMark(fiber, phase)) {
10697 return;
10698 }
10699 currentPhaseFiber = fiber;
10700 currentPhase = phase;
10701 }
10702}
10703
10704function stopPhaseTimer() {
10705 if (enableUserTimingAPI) {
10706 if (!supportsUserTiming) {
10707 return;
10708 }
10709 if (currentPhase !== null && currentPhaseFiber !== null) {
10710 var warning = hasScheduledUpdateInCurrentPhase ? 'Scheduled a cascading update' : null;
10711 endFiberMark(currentPhaseFiber, currentPhase, warning);
10712 }
10713 currentPhase = null;
10714 currentPhaseFiber = null;
10715 }
10716}
10717
10718function startWorkLoopTimer(nextUnitOfWork) {
10719 if (enableUserTimingAPI) {
10720 currentFiber = nextUnitOfWork;
10721 if (!supportsUserTiming) {
10722 return;
10723 }
10724 commitCountInCurrentWorkLoop = 0;
10725 // This is top level call.
10726 // Any other measurements are performed within.
10727 beginMark('(React Tree Reconciliation)');
10728 // Resume any measurements that were in progress during the last loop.
10729 resumeTimers();
10730 }
10731}
10732
10733function stopWorkLoopTimer(interruptedBy, didCompleteRoot) {
10734 if (enableUserTimingAPI) {
10735 if (!supportsUserTiming) {
10736 return;
10737 }
10738 var warning = null;
10739 if (interruptedBy !== null) {
10740 if (interruptedBy.tag === HostRoot) {
10741 warning = 'A top-level update interrupted the previous render';
10742 } else {
10743 var componentName = getComponentName(interruptedBy.type) || 'Unknown';
10744 warning = 'An update to ' + componentName + ' interrupted the previous render';
10745 }
10746 } else if (commitCountInCurrentWorkLoop > 1) {
10747 warning = 'There were cascading updates';
10748 }
10749 commitCountInCurrentWorkLoop = 0;
10750 var label = didCompleteRoot ? '(React Tree Reconciliation: Completed Root)' : '(React Tree Reconciliation: Yielded)';
10751 // Pause any measurements until the next loop.
10752 pauseTimers();
10753 endMark(label, '(React Tree Reconciliation)', warning);
10754 }
10755}
10756
10757function startCommitTimer() {
10758 if (enableUserTimingAPI) {
10759 if (!supportsUserTiming) {
10760 return;
10761 }
10762 isCommitting = true;
10763 hasScheduledUpdateInCurrentCommit = false;
10764 labelsInCurrentCommit.clear();
10765 beginMark('(Committing Changes)');
10766 }
10767}
10768
10769function stopCommitTimer() {
10770 if (enableUserTimingAPI) {
10771 if (!supportsUserTiming) {
10772 return;
10773 }
10774
10775 var warning = null;
10776 if (hasScheduledUpdateInCurrentCommit) {
10777 warning = 'Lifecycle hook scheduled a cascading update';
10778 } else if (commitCountInCurrentWorkLoop > 0) {
10779 warning = 'Caused by a cascading update in earlier commit';
10780 }
10781 hasScheduledUpdateInCurrentCommit = false;
10782 commitCountInCurrentWorkLoop++;
10783 isCommitting = false;
10784 labelsInCurrentCommit.clear();
10785
10786 endMark('(Committing Changes)', '(Committing Changes)', warning);
10787 }
10788}
10789
10790function startCommitSnapshotEffectsTimer() {
10791 if (enableUserTimingAPI) {
10792 if (!supportsUserTiming) {
10793 return;
10794 }
10795 effectCountInCurrentCommit = 0;
10796 beginMark('(Committing Snapshot Effects)');
10797 }
10798}
10799
10800function stopCommitSnapshotEffectsTimer() {
10801 if (enableUserTimingAPI) {
10802 if (!supportsUserTiming) {
10803 return;
10804 }
10805 var count = effectCountInCurrentCommit;
10806 effectCountInCurrentCommit = 0;
10807 endMark('(Committing Snapshot Effects: ' + count + ' Total)', '(Committing Snapshot Effects)', null);
10808 }
10809}
10810
10811function startCommitHostEffectsTimer() {
10812 if (enableUserTimingAPI) {
10813 if (!supportsUserTiming) {
10814 return;
10815 }
10816 effectCountInCurrentCommit = 0;
10817 beginMark('(Committing Host Effects)');
10818 }
10819}
10820
10821function stopCommitHostEffectsTimer() {
10822 if (enableUserTimingAPI) {
10823 if (!supportsUserTiming) {
10824 return;
10825 }
10826 var count = effectCountInCurrentCommit;
10827 effectCountInCurrentCommit = 0;
10828 endMark('(Committing Host Effects: ' + count + ' Total)', '(Committing Host Effects)', null);
10829 }
10830}
10831
10832function startCommitLifeCyclesTimer() {
10833 if (enableUserTimingAPI) {
10834 if (!supportsUserTiming) {
10835 return;
10836 }
10837 effectCountInCurrentCommit = 0;
10838 beginMark('(Calling Lifecycle Methods)');
10839 }
10840}
10841
10842function stopCommitLifeCyclesTimer() {
10843 if (enableUserTimingAPI) {
10844 if (!supportsUserTiming) {
10845 return;
10846 }
10847 var count = effectCountInCurrentCommit;
10848 effectCountInCurrentCommit = 0;
10849 endMark('(Calling Lifecycle Methods: ' + count + ' Total)', '(Calling Lifecycle Methods)', null);
10850 }
10851}
10852
10853var valueStack = [];
10854
10855var fiberStack = void 0;
10856
10857{
10858 fiberStack = [];
10859}
10860
10861var index = -1;
10862
10863function createCursor(defaultValue) {
10864 return {
10865 current: defaultValue
10866 };
10867}
10868
10869function pop(cursor, fiber) {
10870 if (index < 0) {
10871 {
10872 warningWithoutStack$1(false, 'Unexpected pop.');
10873 }
10874 return;
10875 }
10876
10877 {
10878 if (fiber !== fiberStack[index]) {
10879 warningWithoutStack$1(false, 'Unexpected Fiber popped.');
10880 }
10881 }
10882
10883 cursor.current = valueStack[index];
10884
10885 valueStack[index] = null;
10886
10887 {
10888 fiberStack[index] = null;
10889 }
10890
10891 index--;
10892}
10893
10894function push(cursor, value, fiber) {
10895 index++;
10896
10897 valueStack[index] = cursor.current;
10898
10899 {
10900 fiberStack[index] = fiber;
10901 }
10902
10903 cursor.current = value;
10904}
10905
10906var warnedAboutMissingGetChildContext = void 0;
10907
10908{
10909 warnedAboutMissingGetChildContext = {};
10910}
10911
10912var emptyContextObject = {};
10913{
10914 Object.freeze(emptyContextObject);
10915}
10916
10917// A cursor to the current merged context object on the stack.
10918var contextStackCursor = createCursor(emptyContextObject);
10919// A cursor to a boolean indicating whether the context has changed.
10920var didPerformWorkStackCursor = createCursor(false);
10921// Keep track of the previous context object that was on the stack.
10922// We use this to get access to the parent context after we have already
10923// pushed the next context provider, and now need to merge their contexts.
10924var previousContext = emptyContextObject;
10925
10926function getUnmaskedContext(workInProgress, Component, didPushOwnContextIfProvider) {
10927 if (disableLegacyContext) {
10928 return emptyContextObject;
10929 } else {
10930 if (didPushOwnContextIfProvider && isContextProvider(Component)) {
10931 // If the fiber is a context provider itself, when we read its context
10932 // we may have already pushed its own child context on the stack. A context
10933 // provider should not "see" its own child context. Therefore we read the
10934 // previous (parent) context instead for a context provider.
10935 return previousContext;
10936 }
10937 return contextStackCursor.current;
10938 }
10939}
10940
10941function cacheContext(workInProgress, unmaskedContext, maskedContext) {
10942 if (disableLegacyContext) {
10943 return;
10944 } else {
10945 var instance = workInProgress.stateNode;
10946 instance.__reactInternalMemoizedUnmaskedChildContext = unmaskedContext;
10947 instance.__reactInternalMemoizedMaskedChildContext = maskedContext;
10948 }
10949}
10950
10951function getMaskedContext(workInProgress, unmaskedContext) {
10952 if (disableLegacyContext) {
10953 return emptyContextObject;
10954 } else {
10955 var type = workInProgress.type;
10956 var contextTypes = type.contextTypes;
10957 if (!contextTypes) {
10958 return emptyContextObject;
10959 }
10960
10961 // Avoid recreating masked context unless unmasked context has changed.
10962 // Failing to do this will result in unnecessary calls to componentWillReceiveProps.
10963 // This may trigger infinite loops if componentWillReceiveProps calls setState.
10964 var instance = workInProgress.stateNode;
10965 if (instance && instance.__reactInternalMemoizedUnmaskedChildContext === unmaskedContext) {
10966 return instance.__reactInternalMemoizedMaskedChildContext;
10967 }
10968
10969 var context = {};
10970 for (var key in contextTypes) {
10971 context[key] = unmaskedContext[key];
10972 }
10973
10974 {
10975 var name = getComponentName(type) || 'Unknown';
10976 checkPropTypes(contextTypes, context, 'context', name, getCurrentFiberStackInDev);
10977 }
10978
10979 // Cache unmasked context so we can avoid recreating masked context unless necessary.
10980 // Context is created before the class component is instantiated so check for instance.
10981 if (instance) {
10982 cacheContext(workInProgress, unmaskedContext, context);
10983 }
10984
10985 return context;
10986 }
10987}
10988
10989function hasContextChanged() {
10990 if (disableLegacyContext) {
10991 return false;
10992 } else {
10993 return didPerformWorkStackCursor.current;
10994 }
10995}
10996
10997function isContextProvider(type) {
10998 if (disableLegacyContext) {
10999 return false;
11000 } else {
11001 var childContextTypes = type.childContextTypes;
11002 return childContextTypes !== null && childContextTypes !== undefined;
11003 }
11004}
11005
11006function popContext(fiber) {
11007 if (disableLegacyContext) {
11008 return;
11009 } else {
11010 pop(didPerformWorkStackCursor, fiber);
11011 pop(contextStackCursor, fiber);
11012 }
11013}
11014
11015function popTopLevelContextObject(fiber) {
11016 if (disableLegacyContext) {
11017 return;
11018 } else {
11019 pop(didPerformWorkStackCursor, fiber);
11020 pop(contextStackCursor, fiber);
11021 }
11022}
11023
11024function pushTopLevelContextObject(fiber, context, didChange) {
11025 if (disableLegacyContext) {
11026 return;
11027 } else {
11028 (function () {
11029 if (!(contextStackCursor.current === emptyContextObject)) {
11030 {
11031 throw ReactError(Error('Unexpected context found on stack. This error is likely caused by a bug in React. Please file an issue.'));
11032 }
11033 }
11034 })();
11035
11036 push(contextStackCursor, context, fiber);
11037 push(didPerformWorkStackCursor, didChange, fiber);
11038 }
11039}
11040
11041function processChildContext(fiber, type, parentContext) {
11042 if (disableLegacyContext) {
11043 return parentContext;
11044 } else {
11045 var instance = fiber.stateNode;
11046 var childContextTypes = type.childContextTypes;
11047
11048 // TODO (bvaughn) Replace this behavior with an invariant() in the future.
11049 // It has only been added in Fiber to match the (unintentional) behavior in Stack.
11050 if (typeof instance.getChildContext !== 'function') {
11051 {
11052 var componentName = getComponentName(type) || 'Unknown';
11053
11054 if (!warnedAboutMissingGetChildContext[componentName]) {
11055 warnedAboutMissingGetChildContext[componentName] = true;
11056 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);
11057 }
11058 }
11059 return parentContext;
11060 }
11061
11062 var childContext = void 0;
11063 {
11064 setCurrentPhase('getChildContext');
11065 }
11066 startPhaseTimer(fiber, 'getChildContext');
11067 childContext = instance.getChildContext();
11068 stopPhaseTimer();
11069 {
11070 setCurrentPhase(null);
11071 }
11072 for (var contextKey in childContext) {
11073 (function () {
11074 if (!(contextKey in childContextTypes)) {
11075 {
11076 throw ReactError(Error((getComponentName(type) || 'Unknown') + '.getChildContext(): key "' + contextKey + '" is not defined in childContextTypes.'));
11077 }
11078 }
11079 })();
11080 }
11081 {
11082 var name = getComponentName(type) || 'Unknown';
11083 checkPropTypes(childContextTypes, childContext, 'child context', name,
11084 // In practice, there is one case in which we won't get a stack. It's when
11085 // somebody calls unstable_renderSubtreeIntoContainer() and we process
11086 // context from the parent component instance. The stack will be missing
11087 // because it's outside of the reconciliation, and so the pointer has not
11088 // been set. This is rare and doesn't matter. We'll also remove that API.
11089 getCurrentFiberStackInDev);
11090 }
11091
11092 return _assign({}, parentContext, childContext);
11093 }
11094}
11095
11096function pushContextProvider(workInProgress) {
11097 if (disableLegacyContext) {
11098 return false;
11099 } else {
11100 var instance = workInProgress.stateNode;
11101 // We push the context as early as possible to ensure stack integrity.
11102 // If the instance does not exist yet, we will push null at first,
11103 // and replace it on the stack later when invalidating the context.
11104 var memoizedMergedChildContext = instance && instance.__reactInternalMemoizedMergedChildContext || emptyContextObject;
11105
11106 // Remember the parent context so we can merge with it later.
11107 // Inherit the parent's did-perform-work value to avoid inadvertently blocking updates.
11108 previousContext = contextStackCursor.current;
11109 push(contextStackCursor, memoizedMergedChildContext, workInProgress);
11110 push(didPerformWorkStackCursor, didPerformWorkStackCursor.current, workInProgress);
11111
11112 return true;
11113 }
11114}
11115
11116function invalidateContextProvider(workInProgress, type, didChange) {
11117 if (disableLegacyContext) {
11118 return;
11119 } else {
11120 var instance = workInProgress.stateNode;
11121 (function () {
11122 if (!instance) {
11123 {
11124 throw ReactError(Error('Expected to have an instance by this point. This error is likely caused by a bug in React. Please file an issue.'));
11125 }
11126 }
11127 })();
11128
11129 if (didChange) {
11130 // Merge parent and own context.
11131 // Skip this if we're not updating due to sCU.
11132 // This avoids unnecessarily recomputing memoized values.
11133 var mergedContext = processChildContext(workInProgress, type, previousContext);
11134 instance.__reactInternalMemoizedMergedChildContext = mergedContext;
11135
11136 // Replace the old (or empty) context with the new one.
11137 // It is important to unwind the context in the reverse order.
11138 pop(didPerformWorkStackCursor, workInProgress);
11139 pop(contextStackCursor, workInProgress);
11140 // Now push the new context and mark that it has changed.
11141 push(contextStackCursor, mergedContext, workInProgress);
11142 push(didPerformWorkStackCursor, didChange, workInProgress);
11143 } else {
11144 pop(didPerformWorkStackCursor, workInProgress);
11145 push(didPerformWorkStackCursor, didChange, workInProgress);
11146 }
11147 }
11148}
11149
11150function findCurrentUnmaskedContext(fiber) {
11151 if (disableLegacyContext) {
11152 return emptyContextObject;
11153 } else {
11154 // Currently this is only used with renderSubtreeIntoContainer; not sure if it
11155 // makes sense elsewhere
11156 (function () {
11157 if (!(isFiberMounted(fiber) && fiber.tag === ClassComponent)) {
11158 {
11159 throw ReactError(Error('Expected subtree parent to be a mounted class component. This error is likely caused by a bug in React. Please file an issue.'));
11160 }
11161 }
11162 })();
11163
11164 var node = fiber;
11165 do {
11166 switch (node.tag) {
11167 case HostRoot:
11168 return node.stateNode.context;
11169 case ClassComponent:
11170 {
11171 var Component = node.type;
11172 if (isContextProvider(Component)) {
11173 return node.stateNode.__reactInternalMemoizedMergedChildContext;
11174 }
11175 break;
11176 }
11177 }
11178 node = node.return;
11179 } while (node !== null);
11180 (function () {
11181 {
11182 {
11183 throw ReactError(Error('Found unexpected detached subtree parent. This error is likely caused by a bug in React. Please file an issue.'));
11184 }
11185 }
11186 })();
11187 }
11188}
11189
11190var LegacyRoot = 0;
11191var BatchedRoot = 1;
11192var ConcurrentRoot = 2;
11193
11194// Intentionally not named imports because Rollup would use dynamic dispatch for
11195// CommonJS interop named imports.
11196var Scheduler_runWithPriority = Scheduler.unstable_runWithPriority;
11197var Scheduler_scheduleCallback = Scheduler.unstable_scheduleCallback;
11198var Scheduler_cancelCallback = Scheduler.unstable_cancelCallback;
11199var Scheduler_shouldYield = Scheduler.unstable_shouldYield;
11200var Scheduler_requestPaint = Scheduler.unstable_requestPaint;
11201var Scheduler_now = Scheduler.unstable_now;
11202var Scheduler_getCurrentPriorityLevel = Scheduler.unstable_getCurrentPriorityLevel;
11203var Scheduler_ImmediatePriority = Scheduler.unstable_ImmediatePriority;
11204var Scheduler_UserBlockingPriority = Scheduler.unstable_UserBlockingPriority;
11205var Scheduler_NormalPriority = Scheduler.unstable_NormalPriority;
11206var Scheduler_LowPriority = Scheduler.unstable_LowPriority;
11207var Scheduler_IdlePriority = Scheduler.unstable_IdlePriority;
11208
11209
11210if (enableSchedulerTracing) {
11211 // Provide explicit error message when production+profiling bundle of e.g.
11212 // react-dom is used with production (non-profiling) bundle of
11213 // scheduler/tracing
11214 (function () {
11215 if (!(tracing.__interactionsRef != null && tracing.__interactionsRef.current != null)) {
11216 {
11217 throw ReactError(Error('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'));
11218 }
11219 }
11220 })();
11221}
11222
11223var fakeCallbackNode = {};
11224
11225// Except for NoPriority, these correspond to Scheduler priorities. We use
11226// ascending numbers so we can compare them like numbers. They start at 90 to
11227// avoid clashing with Scheduler's priorities.
11228var ImmediatePriority = 99;
11229var UserBlockingPriority$2 = 98;
11230var NormalPriority = 97;
11231var LowPriority = 96;
11232var IdlePriority = 95;
11233// NoPriority is the absence of priority. Also React-only.
11234var NoPriority = 90;
11235
11236var shouldYield = Scheduler_shouldYield;
11237var requestPaint =
11238// Fall back gracefully if we're running an older version of Scheduler.
11239Scheduler_requestPaint !== undefined ? Scheduler_requestPaint : function () {};
11240
11241var syncQueue = null;
11242var immediateQueueCallbackNode = null;
11243var isFlushingSyncQueue = false;
11244var initialTimeMs = Scheduler_now();
11245
11246// If the initial timestamp is reasonably small, use Scheduler's `now` directly.
11247// This will be the case for modern browsers that support `performance.now`. In
11248// older browsers, Scheduler falls back to `Date.now`, which returns a Unix
11249// timestamp. In that case, subtract the module initialization time to simulate
11250// the behavior of performance.now and keep our times small enough to fit
11251// within 32 bits.
11252// TODO: Consider lifting this into Scheduler.
11253var now = initialTimeMs < 10000 ? Scheduler_now : function () {
11254 return Scheduler_now() - initialTimeMs;
11255};
11256
11257function getCurrentPriorityLevel() {
11258 switch (Scheduler_getCurrentPriorityLevel()) {
11259 case Scheduler_ImmediatePriority:
11260 return ImmediatePriority;
11261 case Scheduler_UserBlockingPriority:
11262 return UserBlockingPriority$2;
11263 case Scheduler_NormalPriority:
11264 return NormalPriority;
11265 case Scheduler_LowPriority:
11266 return LowPriority;
11267 case Scheduler_IdlePriority:
11268 return IdlePriority;
11269 default:
11270 (function () {
11271 {
11272 {
11273 throw ReactError(Error('Unknown priority level.'));
11274 }
11275 }
11276 })();
11277 }
11278}
11279
11280function reactPriorityToSchedulerPriority(reactPriorityLevel) {
11281 switch (reactPriorityLevel) {
11282 case ImmediatePriority:
11283 return Scheduler_ImmediatePriority;
11284 case UserBlockingPriority$2:
11285 return Scheduler_UserBlockingPriority;
11286 case NormalPriority:
11287 return Scheduler_NormalPriority;
11288 case LowPriority:
11289 return Scheduler_LowPriority;
11290 case IdlePriority:
11291 return Scheduler_IdlePriority;
11292 default:
11293 (function () {
11294 {
11295 {
11296 throw ReactError(Error('Unknown priority level.'));
11297 }
11298 }
11299 })();
11300 }
11301}
11302
11303function runWithPriority$2(reactPriorityLevel, fn) {
11304 var priorityLevel = reactPriorityToSchedulerPriority(reactPriorityLevel);
11305 return Scheduler_runWithPriority(priorityLevel, fn);
11306}
11307
11308function scheduleCallback(reactPriorityLevel, callback, options) {
11309 var priorityLevel = reactPriorityToSchedulerPriority(reactPriorityLevel);
11310 return Scheduler_scheduleCallback(priorityLevel, callback, options);
11311}
11312
11313function scheduleSyncCallback(callback) {
11314 // Push this callback into an internal queue. We'll flush these either in
11315 // the next tick, or earlier if something calls `flushSyncCallbackQueue`.
11316 if (syncQueue === null) {
11317 syncQueue = [callback];
11318 // Flush the queue in the next tick, at the earliest.
11319 immediateQueueCallbackNode = Scheduler_scheduleCallback(Scheduler_ImmediatePriority, flushSyncCallbackQueueImpl);
11320 } else {
11321 // Push onto existing queue. Don't need to schedule a callback because
11322 // we already scheduled one when we created the queue.
11323 syncQueue.push(callback);
11324 }
11325 return fakeCallbackNode;
11326}
11327
11328function cancelCallback(callbackNode) {
11329 if (callbackNode !== fakeCallbackNode) {
11330 Scheduler_cancelCallback(callbackNode);
11331 }
11332}
11333
11334function flushSyncCallbackQueue() {
11335 if (immediateQueueCallbackNode !== null) {
11336 Scheduler_cancelCallback(immediateQueueCallbackNode);
11337 }
11338 flushSyncCallbackQueueImpl();
11339}
11340
11341function flushSyncCallbackQueueImpl() {
11342 if (!isFlushingSyncQueue && syncQueue !== null) {
11343 // Prevent re-entrancy.
11344 isFlushingSyncQueue = true;
11345 var i = 0;
11346 try {
11347 var _isSync = true;
11348 var queue = syncQueue;
11349 runWithPriority$2(ImmediatePriority, function () {
11350 for (; i < queue.length; i++) {
11351 var callback = queue[i];
11352 do {
11353 callback = callback(_isSync);
11354 } while (callback !== null);
11355 }
11356 });
11357 syncQueue = null;
11358 } catch (error) {
11359 // If something throws, leave the remaining callbacks on the queue.
11360 if (syncQueue !== null) {
11361 syncQueue = syncQueue.slice(i + 1);
11362 }
11363 // Resume flushing in the next tick
11364 Scheduler_scheduleCallback(Scheduler_ImmediatePriority, flushSyncCallbackQueue);
11365 throw error;
11366 } finally {
11367 isFlushingSyncQueue = false;
11368 }
11369 }
11370}
11371
11372var NoMode = 0;
11373var StrictMode = 1;
11374// TODO: Remove BatchedMode and ConcurrentMode by reading from the root
11375// tag instead
11376var BatchedMode = 2;
11377var ConcurrentMode = 4;
11378var ProfileMode = 8;
11379
11380// Max 31 bit integer. The max integer size in V8 for 32-bit systems.
11381// Math.pow(2, 30) - 1
11382// 0b111111111111111111111111111111
11383var MAX_SIGNED_31_BIT_INT = 1073741823;
11384
11385var NoWork = 0;
11386var Never = 1;
11387var Sync = MAX_SIGNED_31_BIT_INT;
11388var Batched = Sync - 1;
11389
11390var UNIT_SIZE = 10;
11391var MAGIC_NUMBER_OFFSET = Batched - 1;
11392
11393// 1 unit of expiration time represents 10ms.
11394function msToExpirationTime(ms) {
11395 // Always add an offset so that we don't clash with the magic number for NoWork.
11396 return MAGIC_NUMBER_OFFSET - (ms / UNIT_SIZE | 0);
11397}
11398
11399function expirationTimeToMs(expirationTime) {
11400 return (MAGIC_NUMBER_OFFSET - expirationTime) * UNIT_SIZE;
11401}
11402
11403function ceiling(num, precision) {
11404 return ((num / precision | 0) + 1) * precision;
11405}
11406
11407function computeExpirationBucket(currentTime, expirationInMs, bucketSizeMs) {
11408 return MAGIC_NUMBER_OFFSET - ceiling(MAGIC_NUMBER_OFFSET - currentTime + expirationInMs / UNIT_SIZE, bucketSizeMs / UNIT_SIZE);
11409}
11410
11411// TODO: This corresponds to Scheduler's NormalPriority, not LowPriority. Update
11412// the names to reflect.
11413var LOW_PRIORITY_EXPIRATION = 5000;
11414var LOW_PRIORITY_BATCH_SIZE = 250;
11415
11416function computeAsyncExpiration(currentTime) {
11417 return computeExpirationBucket(currentTime, LOW_PRIORITY_EXPIRATION, LOW_PRIORITY_BATCH_SIZE);
11418}
11419
11420function computeSuspenseExpiration(currentTime, timeoutMs) {
11421 // TODO: Should we warn if timeoutMs is lower than the normal pri expiration time?
11422 return computeExpirationBucket(currentTime, timeoutMs, LOW_PRIORITY_BATCH_SIZE);
11423}
11424
11425// We intentionally set a higher expiration time for interactive updates in
11426// dev than in production.
11427//
11428// If the main thread is being blocked so long that you hit the expiration,
11429// it's a problem that could be solved with better scheduling.
11430//
11431// People will be more likely to notice this and fix it with the long
11432// expiration time in development.
11433//
11434// In production we opt for better UX at the risk of masking scheduling
11435// problems, by expiring fast.
11436var HIGH_PRIORITY_EXPIRATION = 500;
11437var HIGH_PRIORITY_BATCH_SIZE = 100;
11438
11439function computeInteractiveExpiration(currentTime) {
11440 return computeExpirationBucket(currentTime, HIGH_PRIORITY_EXPIRATION, HIGH_PRIORITY_BATCH_SIZE);
11441}
11442
11443function inferPriorityFromExpirationTime(currentTime, expirationTime) {
11444 if (expirationTime === Sync) {
11445 return ImmediatePriority;
11446 }
11447 if (expirationTime === Never) {
11448 return IdlePriority;
11449 }
11450 var msUntil = expirationTimeToMs(expirationTime) - expirationTimeToMs(currentTime);
11451 if (msUntil <= 0) {
11452 return ImmediatePriority;
11453 }
11454 if (msUntil <= HIGH_PRIORITY_EXPIRATION + HIGH_PRIORITY_BATCH_SIZE) {
11455 return UserBlockingPriority$2;
11456 }
11457 if (msUntil <= LOW_PRIORITY_EXPIRATION + LOW_PRIORITY_BATCH_SIZE) {
11458 return NormalPriority;
11459 }
11460
11461 // TODO: Handle LowPriority
11462
11463 // Assume anything lower has idle priority
11464 return IdlePriority;
11465}
11466
11467/**
11468 * Forked from fbjs/warning:
11469 * https://github.com/facebook/fbjs/blob/e66ba20ad5be433eb54423f2b097d829324d9de6/packages/fbjs/src/__forks__/warning.js
11470 *
11471 * Only change is we use console.warn instead of console.error,
11472 * and do nothing when 'console' is not supported.
11473 * This really simplifies the code.
11474 * ---
11475 * Similar to invariant but only logs a warning if the condition is not met.
11476 * This can be used to log issues in development environments in critical
11477 * paths. Removing the logging code for production environments will keep the
11478 * same logic and follow the same code paths.
11479 */
11480
11481var lowPriorityWarning = function () {};
11482
11483{
11484 var printWarning = function (format) {
11485 for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
11486 args[_key - 1] = arguments[_key];
11487 }
11488
11489 var argIndex = 0;
11490 var message = 'Warning: ' + format.replace(/%s/g, function () {
11491 return args[argIndex++];
11492 });
11493 if (typeof console !== 'undefined') {
11494 console.warn(message);
11495 }
11496 try {
11497 // --- Welcome to debugging React ---
11498 // This error was thrown as a convenience so that you can use this stack
11499 // to find the callsite that caused this warning to fire.
11500 throw new Error(message);
11501 } catch (x) {}
11502 };
11503
11504 lowPriorityWarning = function (condition, format) {
11505 if (format === undefined) {
11506 throw new Error('`lowPriorityWarning(condition, format, ...args)` requires a warning ' + 'message argument');
11507 }
11508 if (!condition) {
11509 for (var _len2 = arguments.length, args = Array(_len2 > 2 ? _len2 - 2 : 0), _key2 = 2; _key2 < _len2; _key2++) {
11510 args[_key2 - 2] = arguments[_key2];
11511 }
11512
11513 printWarning.apply(undefined, [format].concat(args));
11514 }
11515 };
11516}
11517
11518var lowPriorityWarning$1 = lowPriorityWarning;
11519
11520var ReactStrictModeWarnings = {
11521 recordUnsafeLifecycleWarnings: function (fiber, instance) {},
11522 flushPendingUnsafeLifecycleWarnings: function () {},
11523 recordLegacyContextWarning: function (fiber, instance) {},
11524 flushLegacyContextWarning: function () {},
11525 discardPendingWarnings: function () {}
11526};
11527
11528{
11529 var findStrictRoot = function (fiber) {
11530 var maybeStrictRoot = null;
11531
11532 var node = fiber;
11533 while (node !== null) {
11534 if (node.mode & StrictMode) {
11535 maybeStrictRoot = node;
11536 }
11537 node = node.return;
11538 }
11539
11540 return maybeStrictRoot;
11541 };
11542
11543 var setToSortedString = function (set) {
11544 var array = [];
11545 set.forEach(function (value) {
11546 array.push(value);
11547 });
11548 return array.sort().join(', ');
11549 };
11550
11551 var pendingComponentWillMountWarnings = [];
11552 var pendingUNSAFE_ComponentWillMountWarnings = [];
11553 var pendingComponentWillReceivePropsWarnings = [];
11554 var pendingUNSAFE_ComponentWillReceivePropsWarnings = [];
11555 var pendingComponentWillUpdateWarnings = [];
11556 var pendingUNSAFE_ComponentWillUpdateWarnings = [];
11557
11558 // Tracks components we have already warned about.
11559 var didWarnAboutUnsafeLifecycles = new Set();
11560
11561 ReactStrictModeWarnings.recordUnsafeLifecycleWarnings = function (fiber, instance) {
11562 // Dedup strategy: Warn once per component.
11563 if (didWarnAboutUnsafeLifecycles.has(fiber.type)) {
11564 return;
11565 }
11566
11567 if (typeof instance.componentWillMount === 'function' &&
11568 // Don't warn about react-lifecycles-compat polyfilled components.
11569 instance.componentWillMount.__suppressDeprecationWarning !== true) {
11570 pendingComponentWillMountWarnings.push(fiber);
11571 }
11572
11573 if (fiber.mode & StrictMode && typeof instance.UNSAFE_componentWillMount === 'function') {
11574 pendingUNSAFE_ComponentWillMountWarnings.push(fiber);
11575 }
11576
11577 if (typeof instance.componentWillReceiveProps === 'function' && instance.componentWillReceiveProps.__suppressDeprecationWarning !== true) {
11578 pendingComponentWillReceivePropsWarnings.push(fiber);
11579 }
11580
11581 if (fiber.mode & StrictMode && typeof instance.UNSAFE_componentWillReceiveProps === 'function') {
11582 pendingUNSAFE_ComponentWillReceivePropsWarnings.push(fiber);
11583 }
11584
11585 if (typeof instance.componentWillUpdate === 'function' && instance.componentWillUpdate.__suppressDeprecationWarning !== true) {
11586 pendingComponentWillUpdateWarnings.push(fiber);
11587 }
11588
11589 if (fiber.mode & StrictMode && typeof instance.UNSAFE_componentWillUpdate === 'function') {
11590 pendingUNSAFE_ComponentWillUpdateWarnings.push(fiber);
11591 }
11592 };
11593
11594 ReactStrictModeWarnings.flushPendingUnsafeLifecycleWarnings = function () {
11595 // We do an initial pass to gather component names
11596 var componentWillMountUniqueNames = new Set();
11597 if (pendingComponentWillMountWarnings.length > 0) {
11598 pendingComponentWillMountWarnings.forEach(function (fiber) {
11599 componentWillMountUniqueNames.add(getComponentName(fiber.type) || 'Component');
11600 didWarnAboutUnsafeLifecycles.add(fiber.type);
11601 });
11602 pendingComponentWillMountWarnings = [];
11603 }
11604
11605 var UNSAFE_componentWillMountUniqueNames = new Set();
11606 if (pendingUNSAFE_ComponentWillMountWarnings.length > 0) {
11607 pendingUNSAFE_ComponentWillMountWarnings.forEach(function (fiber) {
11608 UNSAFE_componentWillMountUniqueNames.add(getComponentName(fiber.type) || 'Component');
11609 didWarnAboutUnsafeLifecycles.add(fiber.type);
11610 });
11611 pendingUNSAFE_ComponentWillMountWarnings = [];
11612 }
11613
11614 var componentWillReceivePropsUniqueNames = new Set();
11615 if (pendingComponentWillReceivePropsWarnings.length > 0) {
11616 pendingComponentWillReceivePropsWarnings.forEach(function (fiber) {
11617 componentWillReceivePropsUniqueNames.add(getComponentName(fiber.type) || 'Component');
11618 didWarnAboutUnsafeLifecycles.add(fiber.type);
11619 });
11620
11621 pendingComponentWillReceivePropsWarnings = [];
11622 }
11623
11624 var UNSAFE_componentWillReceivePropsUniqueNames = new Set();
11625 if (pendingUNSAFE_ComponentWillReceivePropsWarnings.length > 0) {
11626 pendingUNSAFE_ComponentWillReceivePropsWarnings.forEach(function (fiber) {
11627 UNSAFE_componentWillReceivePropsUniqueNames.add(getComponentName(fiber.type) || 'Component');
11628 didWarnAboutUnsafeLifecycles.add(fiber.type);
11629 });
11630
11631 pendingUNSAFE_ComponentWillReceivePropsWarnings = [];
11632 }
11633
11634 var componentWillUpdateUniqueNames = new Set();
11635 if (pendingComponentWillUpdateWarnings.length > 0) {
11636 pendingComponentWillUpdateWarnings.forEach(function (fiber) {
11637 componentWillUpdateUniqueNames.add(getComponentName(fiber.type) || 'Component');
11638 didWarnAboutUnsafeLifecycles.add(fiber.type);
11639 });
11640
11641 pendingComponentWillUpdateWarnings = [];
11642 }
11643
11644 var UNSAFE_componentWillUpdateUniqueNames = new Set();
11645 if (pendingUNSAFE_ComponentWillUpdateWarnings.length > 0) {
11646 pendingUNSAFE_ComponentWillUpdateWarnings.forEach(function (fiber) {
11647 UNSAFE_componentWillUpdateUniqueNames.add(getComponentName(fiber.type) || 'Component');
11648 didWarnAboutUnsafeLifecycles.add(fiber.type);
11649 });
11650
11651 pendingUNSAFE_ComponentWillUpdateWarnings = [];
11652 }
11653
11654 // Finally, we flush all the warnings
11655 // UNSAFE_ ones before the deprecated ones, since they'll be 'louder'
11656 if (UNSAFE_componentWillMountUniqueNames.size > 0) {
11657 var sortedNames = setToSortedString(UNSAFE_componentWillMountUniqueNames);
11658 warningWithoutStack$1(false, 'Using UNSAFE_componentWillMount in strict mode is not recommended and may indicate bugs in your code. ' + 'See https://fb.me/react-async-component-lifecycle-hooks for details.\n\n' + '* Move code with side effects to componentDidMount, and set initial state in the constructor.\n' + '\nPlease update the following components: %s', sortedNames);
11659 }
11660
11661 if (UNSAFE_componentWillReceivePropsUniqueNames.size > 0) {
11662 var _sortedNames = setToSortedString(UNSAFE_componentWillReceivePropsUniqueNames);
11663 warningWithoutStack$1(false, 'Using UNSAFE_componentWillReceiveProps in strict mode is not recommended ' + 'and may indicate bugs in your code. ' + 'See https://fb.me/react-async-component-lifecycle-hooks for details.\n\n' + '* Move data fetching code or side effects to componentDidUpdate.\n' + "* If you're updating state whenever props change, " + 'refactor your code to use memoization techniques or move it to ' + 'static getDerivedStateFromProps. Learn more at: https://fb.me/react-derived-state\n' + '\nPlease update the following components: %s', _sortedNames);
11664 }
11665
11666 if (UNSAFE_componentWillUpdateUniqueNames.size > 0) {
11667 var _sortedNames2 = setToSortedString(UNSAFE_componentWillUpdateUniqueNames);
11668 warningWithoutStack$1(false, 'Using UNSAFE_componentWillUpdate in strict mode is not recommended ' + 'and may indicate bugs in your code. ' + 'See https://fb.me/react-async-component-lifecycle-hooks for details.\n\n' + '* Move data fetching code or side effects to componentDidUpdate.\n' + '\nPlease update the following components: %s', _sortedNames2);
11669 }
11670
11671 if (componentWillMountUniqueNames.size > 0) {
11672 var _sortedNames3 = setToSortedString(componentWillMountUniqueNames);
11673
11674 lowPriorityWarning$1(false, 'componentWillMount has been renamed, and is not recommended for use. ' + 'See https://fb.me/react-async-component-lifecycle-hooks for details.\n\n' + '* Move code with side effects to componentDidMount, and set initial state in the constructor.\n' + '* Rename componentWillMount to UNSAFE_componentWillMount to suppress ' + 'this warning in non-strict mode. In React 17.x, only the UNSAFE_ name will work. ' + 'To rename all deprecated lifecycles to their new names, you can run ' + '`npx react-codemod rename-unsafe-lifecycles` in your project source folder.\n' + '\nPlease update the following components: %s', _sortedNames3);
11675 }
11676
11677 if (componentWillReceivePropsUniqueNames.size > 0) {
11678 var _sortedNames4 = setToSortedString(componentWillReceivePropsUniqueNames);
11679
11680 lowPriorityWarning$1(false, 'componentWillReceiveProps has been renamed, and is not recommended for use. ' + 'See https://fb.me/react-async-component-lifecycle-hooks for details.\n\n' + '* Move data fetching code or side effects to componentDidUpdate.\n' + "* If you're updating state whenever props change, refactor your " + 'code to use memoization techniques or move it to ' + 'static getDerivedStateFromProps. Learn more at: https://fb.me/react-derived-state\n' + '* Rename componentWillReceiveProps to UNSAFE_componentWillReceiveProps to suppress ' + 'this warning in non-strict mode. In React 17.x, only the UNSAFE_ name will work. ' + 'To rename all deprecated lifecycles to their new names, you can run ' + '`npx react-codemod rename-unsafe-lifecycles` in your project source folder.\n' + '\nPlease update the following components: %s', _sortedNames4);
11681 }
11682
11683 if (componentWillUpdateUniqueNames.size > 0) {
11684 var _sortedNames5 = setToSortedString(componentWillUpdateUniqueNames);
11685
11686 lowPriorityWarning$1(false, 'componentWillUpdate has been renamed, and is not recommended for use. ' + 'See https://fb.me/react-async-component-lifecycle-hooks for details.\n\n' + '* Move data fetching code or side effects to componentDidUpdate.\n' + '* Rename componentWillUpdate to UNSAFE_componentWillUpdate to suppress ' + 'this warning in non-strict mode. In React 17.x, only the UNSAFE_ name will work. ' + 'To rename all deprecated lifecycles to their new names, you can run ' + '`npx react-codemod rename-unsafe-lifecycles` in your project source folder.\n' + '\nPlease update the following components: %s', _sortedNames5);
11687 }
11688 };
11689
11690 var pendingLegacyContextWarning = new Map();
11691
11692 // Tracks components we have already warned about.
11693 var didWarnAboutLegacyContext = new Set();
11694
11695 ReactStrictModeWarnings.recordLegacyContextWarning = function (fiber, instance) {
11696 var strictRoot = findStrictRoot(fiber);
11697 if (strictRoot === null) {
11698 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.');
11699 return;
11700 }
11701
11702 // Dedup strategy: Warn once per component.
11703 if (didWarnAboutLegacyContext.has(fiber.type)) {
11704 return;
11705 }
11706
11707 var warningsForRoot = pendingLegacyContextWarning.get(strictRoot);
11708
11709 if (fiber.type.contextTypes != null || fiber.type.childContextTypes != null || instance !== null && typeof instance.getChildContext === 'function') {
11710 if (warningsForRoot === undefined) {
11711 warningsForRoot = [];
11712 pendingLegacyContextWarning.set(strictRoot, warningsForRoot);
11713 }
11714 warningsForRoot.push(fiber);
11715 }
11716 };
11717
11718 ReactStrictModeWarnings.flushLegacyContextWarning = function () {
11719 pendingLegacyContextWarning.forEach(function (fiberArray, strictRoot) {
11720 var uniqueNames = new Set();
11721 fiberArray.forEach(function (fiber) {
11722 uniqueNames.add(getComponentName(fiber.type) || 'Component');
11723 didWarnAboutLegacyContext.add(fiber.type);
11724 });
11725
11726 var sortedNames = setToSortedString(uniqueNames);
11727 var strictRootComponentStack = getStackByFiberInDevAndProd(strictRoot);
11728
11729 warningWithoutStack$1(false, 'Legacy context API has been detected within a strict-mode tree: %s' + '\n\nThe old API will be supported in all 16.x releases, but applications ' + 'using it should migrate to the new version.' + '\n\nPlease update the following components: %s' + '\n\nLearn more about this warning here:' + '\nhttps://fb.me/react-legacy-context', strictRootComponentStack, sortedNames);
11730 });
11731 };
11732
11733 ReactStrictModeWarnings.discardPendingWarnings = function () {
11734 pendingComponentWillMountWarnings = [];
11735 pendingUNSAFE_ComponentWillMountWarnings = [];
11736 pendingComponentWillReceivePropsWarnings = [];
11737 pendingUNSAFE_ComponentWillReceivePropsWarnings = [];
11738 pendingComponentWillUpdateWarnings = [];
11739 pendingUNSAFE_ComponentWillUpdateWarnings = [];
11740 pendingLegacyContextWarning = new Map();
11741 };
11742}
11743
11744// Resolves type to a family.
11745
11746
11747// Used by React Refresh runtime through DevTools Global Hook.
11748
11749
11750var resolveFamily = null;
11751// $FlowFixMe Flow gets confused by a WeakSet feature check below.
11752var failedBoundaries = null;
11753
11754var setRefreshHandler = function (handler) {
11755 {
11756 resolveFamily = handler;
11757 }
11758};
11759
11760function resolveFunctionForHotReloading(type) {
11761 {
11762 if (resolveFamily === null) {
11763 // Hot reloading is disabled.
11764 return type;
11765 }
11766 var family = resolveFamily(type);
11767 if (family === undefined) {
11768 return type;
11769 }
11770 // Use the latest known implementation.
11771 return family.current;
11772 }
11773}
11774
11775function resolveClassForHotReloading(type) {
11776 // No implementation differences.
11777 return resolveFunctionForHotReloading(type);
11778}
11779
11780function resolveForwardRefForHotReloading(type) {
11781 {
11782 if (resolveFamily === null) {
11783 // Hot reloading is disabled.
11784 return type;
11785 }
11786 var family = resolveFamily(type);
11787 if (family === undefined) {
11788 // Check if we're dealing with a real forwardRef. Don't want to crash early.
11789 if (type !== null && type !== undefined && typeof type.render === 'function') {
11790 // ForwardRef is special because its resolved .type is an object,
11791 // but it's possible that we only have its inner render function in the map.
11792 // If that inner render function is different, we'll build a new forwardRef type.
11793 var currentRender = resolveFunctionForHotReloading(type.render);
11794 if (type.render !== currentRender) {
11795 var syntheticType = {
11796 $$typeof: REACT_FORWARD_REF_TYPE,
11797 render: currentRender
11798 };
11799 if (type.displayName !== undefined) {
11800 syntheticType.displayName = type.displayName;
11801 }
11802 return syntheticType;
11803 }
11804 }
11805 return type;
11806 }
11807 // Use the latest known implementation.
11808 return family.current;
11809 }
11810}
11811
11812function isCompatibleFamilyForHotReloading(fiber, element) {
11813 {
11814 if (resolveFamily === null) {
11815 // Hot reloading is disabled.
11816 return false;
11817 }
11818
11819 var prevType = fiber.elementType;
11820 var nextType = element.type;
11821
11822 // If we got here, we know types aren't === equal.
11823 var needsCompareFamilies = false;
11824
11825 var $$typeofNextType = typeof nextType === 'object' && nextType !== null ? nextType.$$typeof : null;
11826
11827 switch (fiber.tag) {
11828 case ClassComponent:
11829 {
11830 if (typeof nextType === 'function') {
11831 needsCompareFamilies = true;
11832 }
11833 break;
11834 }
11835 case FunctionComponent:
11836 {
11837 if (typeof nextType === 'function') {
11838 needsCompareFamilies = true;
11839 } else if ($$typeofNextType === REACT_LAZY_TYPE) {
11840 // We don't know the inner type yet.
11841 // We're going to assume that the lazy inner type is stable,
11842 // and so it is sufficient to avoid reconciling it away.
11843 // We're not going to unwrap or actually use the new lazy type.
11844 needsCompareFamilies = true;
11845 }
11846 break;
11847 }
11848 case ForwardRef:
11849 {
11850 if ($$typeofNextType === REACT_FORWARD_REF_TYPE) {
11851 needsCompareFamilies = true;
11852 } else if ($$typeofNextType === REACT_LAZY_TYPE) {
11853 needsCompareFamilies = true;
11854 }
11855 break;
11856 }
11857 case MemoComponent:
11858 case SimpleMemoComponent:
11859 {
11860 if ($$typeofNextType === REACT_MEMO_TYPE) {
11861 // TODO: if it was but can no longer be simple,
11862 // we shouldn't set this.
11863 needsCompareFamilies = true;
11864 } else if ($$typeofNextType === REACT_LAZY_TYPE) {
11865 needsCompareFamilies = true;
11866 }
11867 break;
11868 }
11869 default:
11870 return false;
11871 }
11872
11873 // Check if both types have a family and it's the same one.
11874 if (needsCompareFamilies) {
11875 // Note: memo() and forwardRef() we'll compare outer rather than inner type.
11876 // This means both of them need to be registered to preserve state.
11877 // If we unwrapped and compared the inner types for wrappers instead,
11878 // then we would risk falsely saying two separate memo(Foo)
11879 // calls are equivalent because they wrap the same Foo function.
11880 var prevFamily = resolveFamily(prevType);
11881 if (prevFamily !== undefined && prevFamily === resolveFamily(nextType)) {
11882 return true;
11883 }
11884 }
11885 return false;
11886 }
11887}
11888
11889function markFailedErrorBoundaryForHotReloading(fiber) {
11890 {
11891 if (resolveFamily === null) {
11892 // Hot reloading is disabled.
11893 return;
11894 }
11895 if (typeof WeakSet !== 'function') {
11896 return;
11897 }
11898 if (failedBoundaries === null) {
11899 failedBoundaries = new WeakSet();
11900 }
11901 failedBoundaries.add(fiber);
11902 }
11903}
11904
11905var scheduleRefresh = function (root, update) {
11906 {
11907 if (resolveFamily === null) {
11908 // Hot reloading is disabled.
11909 return;
11910 }
11911 var _staleFamilies = update.staleFamilies,
11912 _updatedFamilies = update.updatedFamilies;
11913
11914 flushPassiveEffects();
11915 flushSync(function () {
11916 scheduleFibersWithFamiliesRecursively(root.current, _updatedFamilies, _staleFamilies);
11917 });
11918 }
11919};
11920
11921var scheduleRoot = function (root, element) {
11922 {
11923 if (root.context !== emptyContextObject) {
11924 // Super edge case: root has a legacy _renderSubtree context
11925 // but we don't know the parentComponent so we can't pass it.
11926 // Just ignore. We'll delete this with _renderSubtree code path later.
11927 return;
11928 }
11929 flushPassiveEffects();
11930 updateContainerAtExpirationTime(element, root, null, Sync, null);
11931 }
11932};
11933
11934function scheduleFibersWithFamiliesRecursively(fiber, updatedFamilies, staleFamilies) {
11935 {
11936 var alternate = fiber.alternate,
11937 child = fiber.child,
11938 sibling = fiber.sibling,
11939 tag = fiber.tag,
11940 type = fiber.type;
11941
11942
11943 var candidateType = null;
11944 switch (tag) {
11945 case FunctionComponent:
11946 case SimpleMemoComponent:
11947 case ClassComponent:
11948 candidateType = type;
11949 break;
11950 case ForwardRef:
11951 candidateType = type.render;
11952 break;
11953 default:
11954 break;
11955 }
11956
11957 if (resolveFamily === null) {
11958 throw new Error('Expected resolveFamily to be set during hot reload.');
11959 }
11960
11961 var needsRender = false;
11962 var needsRemount = false;
11963 if (candidateType !== null) {
11964 var family = resolveFamily(candidateType);
11965 if (family !== undefined) {
11966 if (staleFamilies.has(family)) {
11967 needsRemount = true;
11968 } else if (updatedFamilies.has(family)) {
11969 needsRender = true;
11970 }
11971 }
11972 }
11973 if (failedBoundaries !== null) {
11974 if (failedBoundaries.has(fiber) || alternate !== null && failedBoundaries.has(alternate)) {
11975 needsRemount = true;
11976 }
11977 }
11978
11979 if (needsRemount) {
11980 fiber._debugNeedsRemount = true;
11981 }
11982 if (needsRemount || needsRender) {
11983 scheduleWork(fiber, Sync);
11984 }
11985 if (child !== null && !needsRemount) {
11986 scheduleFibersWithFamiliesRecursively(child, updatedFamilies, staleFamilies);
11987 }
11988 if (sibling !== null) {
11989 scheduleFibersWithFamiliesRecursively(sibling, updatedFamilies, staleFamilies);
11990 }
11991 }
11992}
11993
11994var findHostInstancesForRefresh = function (root, families) {
11995 {
11996 var hostInstances = new Set();
11997 var types = new Set(families.map(function (family) {
11998 return family.current;
11999 }));
12000 findHostInstancesForMatchingFibersRecursively(root.current, types, hostInstances);
12001 return hostInstances;
12002 }
12003};
12004
12005function findHostInstancesForMatchingFibersRecursively(fiber, types, hostInstances) {
12006 {
12007 var child = fiber.child,
12008 sibling = fiber.sibling,
12009 tag = fiber.tag,
12010 type = fiber.type;
12011
12012
12013 var candidateType = null;
12014 switch (tag) {
12015 case FunctionComponent:
12016 case SimpleMemoComponent:
12017 case ClassComponent:
12018 candidateType = type;
12019 break;
12020 case ForwardRef:
12021 candidateType = type.render;
12022 break;
12023 default:
12024 break;
12025 }
12026
12027 var didMatch = false;
12028 if (candidateType !== null) {
12029 if (types.has(candidateType)) {
12030 didMatch = true;
12031 }
12032 }
12033
12034 if (didMatch) {
12035 // We have a match. This only drills down to the closest host components.
12036 // There's no need to search deeper because for the purpose of giving
12037 // visual feedback, "flashing" outermost parent rectangles is sufficient.
12038 findHostInstancesForFiberShallowly(fiber, hostInstances);
12039 } else {
12040 // If there's no match, maybe there will be one further down in the child tree.
12041 if (child !== null) {
12042 findHostInstancesForMatchingFibersRecursively(child, types, hostInstances);
12043 }
12044 }
12045
12046 if (sibling !== null) {
12047 findHostInstancesForMatchingFibersRecursively(sibling, types, hostInstances);
12048 }
12049 }
12050}
12051
12052function findHostInstancesForFiberShallowly(fiber, hostInstances) {
12053 {
12054 var foundHostInstances = findChildHostInstancesForFiberShallowly(fiber, hostInstances);
12055 if (foundHostInstances) {
12056 return;
12057 }
12058 // If we didn't find any host children, fallback to closest host parent.
12059 var node = fiber;
12060 while (true) {
12061 switch (node.tag) {
12062 case HostComponent:
12063 hostInstances.add(node.stateNode);
12064 return;
12065 case HostPortal:
12066 hostInstances.add(node.stateNode.containerInfo);
12067 return;
12068 case HostRoot:
12069 hostInstances.add(node.stateNode.containerInfo);
12070 return;
12071 }
12072 if (node.return === null) {
12073 throw new Error('Expected to reach root first.');
12074 }
12075 node = node.return;
12076 }
12077 }
12078}
12079
12080function findChildHostInstancesForFiberShallowly(fiber, hostInstances) {
12081 {
12082 var node = fiber;
12083 var foundHostInstances = false;
12084 while (true) {
12085 if (node.tag === HostComponent) {
12086 // We got a match.
12087 foundHostInstances = true;
12088 hostInstances.add(node.stateNode);
12089 // There may still be more, so keep searching.
12090 } else if (node.child !== null) {
12091 node.child.return = node;
12092 node = node.child;
12093 continue;
12094 }
12095 if (node === fiber) {
12096 return foundHostInstances;
12097 }
12098 while (node.sibling === null) {
12099 if (node.return === null || node.return === fiber) {
12100 return foundHostInstances;
12101 }
12102 node = node.return;
12103 }
12104 node.sibling.return = node.return;
12105 node = node.sibling;
12106 }
12107 }
12108 return false;
12109}
12110
12111function resolveDefaultProps(Component, baseProps) {
12112 if (Component && Component.defaultProps) {
12113 // Resolve default props. Taken from ReactElement
12114 var props = _assign({}, baseProps);
12115 var defaultProps = Component.defaultProps;
12116 for (var propName in defaultProps) {
12117 if (props[propName] === undefined) {
12118 props[propName] = defaultProps[propName];
12119 }
12120 }
12121 return props;
12122 }
12123 return baseProps;
12124}
12125
12126function readLazyComponentType(lazyComponent) {
12127 var status = lazyComponent._status;
12128 var result = lazyComponent._result;
12129 switch (status) {
12130 case Resolved:
12131 {
12132 var Component = result;
12133 return Component;
12134 }
12135 case Rejected:
12136 {
12137 var error = result;
12138 throw error;
12139 }
12140 case Pending:
12141 {
12142 var thenable = result;
12143 throw thenable;
12144 }
12145 default:
12146 {
12147 lazyComponent._status = Pending;
12148 var ctor = lazyComponent._ctor;
12149 var _thenable = ctor();
12150 _thenable.then(function (moduleObject) {
12151 if (lazyComponent._status === Pending) {
12152 var defaultExport = moduleObject.default;
12153 {
12154 if (defaultExport === undefined) {
12155 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);
12156 }
12157 }
12158 lazyComponent._status = Resolved;
12159 lazyComponent._result = defaultExport;
12160 }
12161 }, function (error) {
12162 if (lazyComponent._status === Pending) {
12163 lazyComponent._status = Rejected;
12164 lazyComponent._result = error;
12165 }
12166 });
12167 // Handle synchronous thenables.
12168 switch (lazyComponent._status) {
12169 case Resolved:
12170 return lazyComponent._result;
12171 case Rejected:
12172 throw lazyComponent._result;
12173 }
12174 lazyComponent._result = _thenable;
12175 throw _thenable;
12176 }
12177 }
12178}
12179
12180var valueCursor = createCursor(null);
12181
12182var rendererSigil = void 0;
12183{
12184 // Use this to detect multiple renderers using the same context
12185 rendererSigil = {};
12186}
12187
12188var currentlyRenderingFiber = null;
12189var lastContextDependency = null;
12190var lastContextWithAllBitsObserved = null;
12191
12192var isDisallowedContextReadInDEV = false;
12193
12194function resetContextDependencies() {
12195 // This is called right before React yields execution, to ensure `readContext`
12196 // cannot be called outside the render phase.
12197 currentlyRenderingFiber = null;
12198 lastContextDependency = null;
12199 lastContextWithAllBitsObserved = null;
12200 {
12201 isDisallowedContextReadInDEV = false;
12202 }
12203}
12204
12205function enterDisallowedContextReadInDEV() {
12206 {
12207 isDisallowedContextReadInDEV = true;
12208 }
12209}
12210
12211function exitDisallowedContextReadInDEV() {
12212 {
12213 isDisallowedContextReadInDEV = false;
12214 }
12215}
12216
12217function pushProvider(providerFiber, nextValue) {
12218 var context = providerFiber.type._context;
12219
12220 if (isPrimaryRenderer) {
12221 push(valueCursor, context._currentValue, providerFiber);
12222
12223 context._currentValue = nextValue;
12224 {
12225 !(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;
12226 context._currentRenderer = rendererSigil;
12227 }
12228 } else {
12229 push(valueCursor, context._currentValue2, providerFiber);
12230
12231 context._currentValue2 = nextValue;
12232 {
12233 !(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;
12234 context._currentRenderer2 = rendererSigil;
12235 }
12236 }
12237}
12238
12239function popProvider(providerFiber) {
12240 var currentValue = valueCursor.current;
12241
12242 pop(valueCursor, providerFiber);
12243
12244 var context = providerFiber.type._context;
12245 if (isPrimaryRenderer) {
12246 context._currentValue = currentValue;
12247 } else {
12248 context._currentValue2 = currentValue;
12249 }
12250}
12251
12252function calculateChangedBits(context, newValue, oldValue) {
12253 if (is(oldValue, newValue)) {
12254 // No change
12255 return 0;
12256 } else {
12257 var changedBits = typeof context._calculateChangedBits === 'function' ? context._calculateChangedBits(oldValue, newValue) : MAX_SIGNED_31_BIT_INT;
12258
12259 {
12260 !((changedBits & MAX_SIGNED_31_BIT_INT) === changedBits) ? warning$1(false, 'calculateChangedBits: Expected the return value to be a ' + '31-bit integer. Instead received: %s', changedBits) : void 0;
12261 }
12262 return changedBits | 0;
12263 }
12264}
12265
12266function scheduleWorkOnParentPath(parent, renderExpirationTime) {
12267 // Update the child expiration time of all the ancestors, including
12268 // the alternates.
12269 var node = parent;
12270 while (node !== null) {
12271 var alternate = node.alternate;
12272 if (node.childExpirationTime < renderExpirationTime) {
12273 node.childExpirationTime = renderExpirationTime;
12274 if (alternate !== null && alternate.childExpirationTime < renderExpirationTime) {
12275 alternate.childExpirationTime = renderExpirationTime;
12276 }
12277 } else if (alternate !== null && alternate.childExpirationTime < renderExpirationTime) {
12278 alternate.childExpirationTime = renderExpirationTime;
12279 } else {
12280 // Neither alternate was updated, which means the rest of the
12281 // ancestor path already has sufficient priority.
12282 break;
12283 }
12284 node = node.return;
12285 }
12286}
12287
12288function propagateContextChange(workInProgress, context, changedBits, renderExpirationTime) {
12289 var fiber = workInProgress.child;
12290 if (fiber !== null) {
12291 // Set the return pointer of the child to the work-in-progress fiber.
12292 fiber.return = workInProgress;
12293 }
12294 while (fiber !== null) {
12295 var nextFiber = void 0;
12296
12297 // Visit this fiber.
12298 var list = fiber.dependencies;
12299 if (list !== null) {
12300 nextFiber = fiber.child;
12301
12302 var dependency = list.firstContext;
12303 while (dependency !== null) {
12304 // Check if the context matches.
12305 if (dependency.context === context && (dependency.observedBits & changedBits) !== 0) {
12306 // Match! Schedule an update on this fiber.
12307
12308 if (fiber.tag === ClassComponent) {
12309 // Schedule a force update on the work-in-progress.
12310 var update = createUpdate(renderExpirationTime, null);
12311 update.tag = ForceUpdate;
12312 // TODO: Because we don't have a work-in-progress, this will add the
12313 // update to the current fiber, too, which means it will persist even if
12314 // this render is thrown away. Since it's a race condition, not sure it's
12315 // worth fixing.
12316 enqueueUpdate(fiber, update);
12317 }
12318
12319 if (fiber.expirationTime < renderExpirationTime) {
12320 fiber.expirationTime = renderExpirationTime;
12321 }
12322 var alternate = fiber.alternate;
12323 if (alternate !== null && alternate.expirationTime < renderExpirationTime) {
12324 alternate.expirationTime = renderExpirationTime;
12325 }
12326
12327 scheduleWorkOnParentPath(fiber.return, renderExpirationTime);
12328
12329 // Mark the expiration time on the list, too.
12330 if (list.expirationTime < renderExpirationTime) {
12331 list.expirationTime = renderExpirationTime;
12332 }
12333
12334 // Since we already found a match, we can stop traversing the
12335 // dependency list.
12336 break;
12337 }
12338 dependency = dependency.next;
12339 }
12340 } else if (fiber.tag === ContextProvider) {
12341 // Don't scan deeper if this is a matching provider
12342 nextFiber = fiber.type === workInProgress.type ? null : fiber.child;
12343 } else if (enableSuspenseServerRenderer && fiber.tag === DehydratedSuspenseComponent) {
12344 // If a dehydrated suspense component is in this subtree, we don't know
12345 // if it will have any context consumers in it. The best we can do is
12346 // mark it as having updates on its children.
12347 if (fiber.expirationTime < renderExpirationTime) {
12348 fiber.expirationTime = renderExpirationTime;
12349 }
12350 var _alternate = fiber.alternate;
12351 if (_alternate !== null && _alternate.expirationTime < renderExpirationTime) {
12352 _alternate.expirationTime = renderExpirationTime;
12353 }
12354 // This is intentionally passing this fiber as the parent
12355 // because we want to schedule this fiber as having work
12356 // on its children. We'll use the childExpirationTime on
12357 // this fiber to indicate that a context has changed.
12358 scheduleWorkOnParentPath(fiber, renderExpirationTime);
12359 nextFiber = fiber.sibling;
12360 } else {
12361 // Traverse down.
12362 nextFiber = fiber.child;
12363 }
12364
12365 if (nextFiber !== null) {
12366 // Set the return pointer of the child to the work-in-progress fiber.
12367 nextFiber.return = fiber;
12368 } else {
12369 // No child. Traverse to next sibling.
12370 nextFiber = fiber;
12371 while (nextFiber !== null) {
12372 if (nextFiber === workInProgress) {
12373 // We're back to the root of this subtree. Exit.
12374 nextFiber = null;
12375 break;
12376 }
12377 var sibling = nextFiber.sibling;
12378 if (sibling !== null) {
12379 // Set the return pointer of the sibling to the work-in-progress fiber.
12380 sibling.return = nextFiber.return;
12381 nextFiber = sibling;
12382 break;
12383 }
12384 // No more siblings. Traverse up.
12385 nextFiber = nextFiber.return;
12386 }
12387 }
12388 fiber = nextFiber;
12389 }
12390}
12391
12392function prepareToReadContext(workInProgress, renderExpirationTime) {
12393 currentlyRenderingFiber = workInProgress;
12394 lastContextDependency = null;
12395 lastContextWithAllBitsObserved = null;
12396
12397 var dependencies = workInProgress.dependencies;
12398 if (dependencies !== null) {
12399 var firstContext = dependencies.firstContext;
12400 if (firstContext !== null) {
12401 if (dependencies.expirationTime >= renderExpirationTime) {
12402 // Context list has a pending update. Mark that this fiber performed work.
12403 markWorkInProgressReceivedUpdate();
12404 }
12405 // Reset the work-in-progress list
12406 dependencies.firstContext = null;
12407 }
12408 }
12409}
12410
12411function readContext(context, observedBits) {
12412 {
12413 // This warning would fire if you read context inside a Hook like useMemo.
12414 // Unlike the class check below, it's not enforced in production for perf.
12415 !!isDisallowedContextReadInDEV ? warning$1(false, 'Context can only be read while React is rendering. ' + 'In classes, you can read it in the render method or getDerivedStateFromProps. ' + 'In function components, you can read it directly in the function body, but not ' + 'inside Hooks like useReducer() or useMemo().') : void 0;
12416 }
12417
12418 if (lastContextWithAllBitsObserved === context) {
12419 // Nothing to do. We already observe everything in this context.
12420 } else if (observedBits === false || observedBits === 0) {
12421 // Do not observe any updates.
12422 } else {
12423 var resolvedObservedBits = void 0; // Avoid deopting on observable arguments or heterogeneous types.
12424 if (typeof observedBits !== 'number' || observedBits === MAX_SIGNED_31_BIT_INT) {
12425 // Observe all updates.
12426 lastContextWithAllBitsObserved = context;
12427 resolvedObservedBits = MAX_SIGNED_31_BIT_INT;
12428 } else {
12429 resolvedObservedBits = observedBits;
12430 }
12431
12432 var contextItem = {
12433 context: context,
12434 observedBits: resolvedObservedBits,
12435 next: null
12436 };
12437
12438 if (lastContextDependency === null) {
12439 (function () {
12440 if (!(currentlyRenderingFiber !== null)) {
12441 {
12442 throw ReactError(Error('Context can only be read while React is rendering. In classes, you can read it in the render method or getDerivedStateFromProps. In function components, you can read it directly in the function body, but not inside Hooks like useReducer() or useMemo().'));
12443 }
12444 }
12445 })();
12446
12447 // This is the first dependency for this component. Create a new list.
12448 lastContextDependency = contextItem;
12449 currentlyRenderingFiber.dependencies = {
12450 expirationTime: NoWork,
12451 firstContext: contextItem,
12452 responders: null
12453 };
12454 } else {
12455 // Append a new context item.
12456 lastContextDependency = lastContextDependency.next = contextItem;
12457 }
12458 }
12459 return isPrimaryRenderer ? context._currentValue : context._currentValue2;
12460}
12461
12462// UpdateQueue is a linked list of prioritized updates.
12463//
12464// Like fibers, update queues come in pairs: a current queue, which represents
12465// the visible state of the screen, and a work-in-progress queue, which can be
12466// mutated and processed asynchronously before it is committed — a form of
12467// double buffering. If a work-in-progress render is discarded before finishing,
12468// we create a new work-in-progress by cloning the current queue.
12469//
12470// Both queues share a persistent, singly-linked list structure. To schedule an
12471// update, we append it to the end of both queues. Each queue maintains a
12472// pointer to first update in the persistent list that hasn't been processed.
12473// The work-in-progress pointer always has a position equal to or greater than
12474// the current queue, since we always work on that one. The current queue's
12475// pointer is only updated during the commit phase, when we swap in the
12476// work-in-progress.
12477//
12478// For example:
12479//
12480// Current pointer: A - B - C - D - E - F
12481// Work-in-progress pointer: D - E - F
12482// ^
12483// The work-in-progress queue has
12484// processed more updates than current.
12485//
12486// The reason we append to both queues is because otherwise we might drop
12487// updates without ever processing them. For example, if we only add updates to
12488// the work-in-progress queue, some updates could be lost whenever a work-in
12489// -progress render restarts by cloning from current. Similarly, if we only add
12490// updates to the current queue, the updates will be lost whenever an already
12491// in-progress queue commits and swaps with the current queue. However, by
12492// adding to both queues, we guarantee that the update will be part of the next
12493// work-in-progress. (And because the work-in-progress queue becomes the
12494// current queue once it commits, there's no danger of applying the same
12495// update twice.)
12496//
12497// Prioritization
12498// --------------
12499//
12500// Updates are not sorted by priority, but by insertion; new updates are always
12501// appended to the end of the list.
12502//
12503// The priority is still important, though. When processing the update queue
12504// during the render phase, only the updates with sufficient priority are
12505// included in the result. If we skip an update because it has insufficient
12506// priority, it remains in the queue to be processed later, during a lower
12507// priority render. Crucially, all updates subsequent to a skipped update also
12508// remain in the queue *regardless of their priority*. That means high priority
12509// updates are sometimes processed twice, at two separate priorities. We also
12510// keep track of a base state, that represents the state before the first
12511// update in the queue is applied.
12512//
12513// For example:
12514//
12515// Given a base state of '', and the following queue of updates
12516//
12517// A1 - B2 - C1 - D2
12518//
12519// where the number indicates the priority, and the update is applied to the
12520// previous state by appending a letter, React will process these updates as
12521// two separate renders, one per distinct priority level:
12522//
12523// First render, at priority 1:
12524// Base state: ''
12525// Updates: [A1, C1]
12526// Result state: 'AC'
12527//
12528// Second render, at priority 2:
12529// Base state: 'A' <- The base state does not include C1,
12530// because B2 was skipped.
12531// Updates: [B2, C1, D2] <- C1 was rebased on top of B2
12532// Result state: 'ABCD'
12533//
12534// Because we process updates in insertion order, and rebase high priority
12535// updates when preceding updates are skipped, the final result is deterministic
12536// regardless of priority. Intermediate state may vary according to system
12537// resources, but the final state is always the same.
12538
12539var UpdateState = 0;
12540var ReplaceState = 1;
12541var ForceUpdate = 2;
12542var CaptureUpdate = 3;
12543
12544// Global state that is reset at the beginning of calling `processUpdateQueue`.
12545// It should only be read right after calling `processUpdateQueue`, via
12546// `checkHasForceUpdateAfterProcessing`.
12547var hasForceUpdate = false;
12548
12549var didWarnUpdateInsideUpdate = void 0;
12550var currentlyProcessingQueue = void 0;
12551
12552{
12553 didWarnUpdateInsideUpdate = false;
12554 currentlyProcessingQueue = null;
12555
12556}
12557
12558function createUpdateQueue(baseState) {
12559 var queue = {
12560 baseState: baseState,
12561 firstUpdate: null,
12562 lastUpdate: null,
12563 firstCapturedUpdate: null,
12564 lastCapturedUpdate: null,
12565 firstEffect: null,
12566 lastEffect: null,
12567 firstCapturedEffect: null,
12568 lastCapturedEffect: null
12569 };
12570 return queue;
12571}
12572
12573function cloneUpdateQueue(currentQueue) {
12574 var queue = {
12575 baseState: currentQueue.baseState,
12576 firstUpdate: currentQueue.firstUpdate,
12577 lastUpdate: currentQueue.lastUpdate,
12578
12579 // TODO: With resuming, if we bail out and resuse the child tree, we should
12580 // keep these effects.
12581 firstCapturedUpdate: null,
12582 lastCapturedUpdate: null,
12583
12584 firstEffect: null,
12585 lastEffect: null,
12586
12587 firstCapturedEffect: null,
12588 lastCapturedEffect: null
12589 };
12590 return queue;
12591}
12592
12593function createUpdate(expirationTime, suspenseConfig) {
12594 var update = {
12595 expirationTime: expirationTime,
12596 suspenseConfig: suspenseConfig,
12597
12598 tag: UpdateState,
12599 payload: null,
12600 callback: null,
12601
12602 next: null,
12603 nextEffect: null
12604 };
12605 {
12606 update.priority = getCurrentPriorityLevel();
12607 }
12608 return update;
12609}
12610
12611function appendUpdateToQueue(queue, update) {
12612 // Append the update to the end of the list.
12613 if (queue.lastUpdate === null) {
12614 // Queue is empty
12615 queue.firstUpdate = queue.lastUpdate = update;
12616 } else {
12617 queue.lastUpdate.next = update;
12618 queue.lastUpdate = update;
12619 }
12620}
12621
12622function enqueueUpdate(fiber, update) {
12623 // Update queues are created lazily.
12624 var alternate = fiber.alternate;
12625 var queue1 = void 0;
12626 var queue2 = void 0;
12627 if (alternate === null) {
12628 // There's only one fiber.
12629 queue1 = fiber.updateQueue;
12630 queue2 = null;
12631 if (queue1 === null) {
12632 queue1 = fiber.updateQueue = createUpdateQueue(fiber.memoizedState);
12633 }
12634 } else {
12635 // There are two owners.
12636 queue1 = fiber.updateQueue;
12637 queue2 = alternate.updateQueue;
12638 if (queue1 === null) {
12639 if (queue2 === null) {
12640 // Neither fiber has an update queue. Create new ones.
12641 queue1 = fiber.updateQueue = createUpdateQueue(fiber.memoizedState);
12642 queue2 = alternate.updateQueue = createUpdateQueue(alternate.memoizedState);
12643 } else {
12644 // Only one fiber has an update queue. Clone to create a new one.
12645 queue1 = fiber.updateQueue = cloneUpdateQueue(queue2);
12646 }
12647 } else {
12648 if (queue2 === null) {
12649 // Only one fiber has an update queue. Clone to create a new one.
12650 queue2 = alternate.updateQueue = cloneUpdateQueue(queue1);
12651 } else {
12652 // Both owners have an update queue.
12653 }
12654 }
12655 }
12656 if (queue2 === null || queue1 === queue2) {
12657 // There's only a single queue.
12658 appendUpdateToQueue(queue1, update);
12659 } else {
12660 // There are two queues. We need to append the update to both queues,
12661 // while accounting for the persistent structure of the list — we don't
12662 // want the same update to be added multiple times.
12663 if (queue1.lastUpdate === null || queue2.lastUpdate === null) {
12664 // One of the queues is not empty. We must add the update to both queues.
12665 appendUpdateToQueue(queue1, update);
12666 appendUpdateToQueue(queue2, update);
12667 } else {
12668 // Both queues are non-empty. The last update is the same in both lists,
12669 // because of structural sharing. So, only append to one of the lists.
12670 appendUpdateToQueue(queue1, update);
12671 // But we still need to update the `lastUpdate` pointer of queue2.
12672 queue2.lastUpdate = update;
12673 }
12674 }
12675
12676 {
12677 if (fiber.tag === ClassComponent && (currentlyProcessingQueue === queue1 || queue2 !== null && currentlyProcessingQueue === queue2) && !didWarnUpdateInsideUpdate) {
12678 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.');
12679 didWarnUpdateInsideUpdate = true;
12680 }
12681 }
12682}
12683
12684function enqueueCapturedUpdate(workInProgress, update) {
12685 // Captured updates go into a separate list, and only on the work-in-
12686 // progress queue.
12687 var workInProgressQueue = workInProgress.updateQueue;
12688 if (workInProgressQueue === null) {
12689 workInProgressQueue = workInProgress.updateQueue = createUpdateQueue(workInProgress.memoizedState);
12690 } else {
12691 // TODO: I put this here rather than createWorkInProgress so that we don't
12692 // clone the queue unnecessarily. There's probably a better way to
12693 // structure this.
12694 workInProgressQueue = ensureWorkInProgressQueueIsAClone(workInProgress, workInProgressQueue);
12695 }
12696
12697 // Append the update to the end of the list.
12698 if (workInProgressQueue.lastCapturedUpdate === null) {
12699 // This is the first render phase update
12700 workInProgressQueue.firstCapturedUpdate = workInProgressQueue.lastCapturedUpdate = update;
12701 } else {
12702 workInProgressQueue.lastCapturedUpdate.next = update;
12703 workInProgressQueue.lastCapturedUpdate = update;
12704 }
12705}
12706
12707function ensureWorkInProgressQueueIsAClone(workInProgress, queue) {
12708 var current = workInProgress.alternate;
12709 if (current !== null) {
12710 // If the work-in-progress queue is equal to the current queue,
12711 // we need to clone it first.
12712 if (queue === current.updateQueue) {
12713 queue = workInProgress.updateQueue = cloneUpdateQueue(queue);
12714 }
12715 }
12716 return queue;
12717}
12718
12719function getStateFromUpdate(workInProgress, queue, update, prevState, nextProps, instance) {
12720 switch (update.tag) {
12721 case ReplaceState:
12722 {
12723 var _payload = update.payload;
12724 if (typeof _payload === 'function') {
12725 // Updater function
12726 {
12727 enterDisallowedContextReadInDEV();
12728 if (debugRenderPhaseSideEffects || debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) {
12729 _payload.call(instance, prevState, nextProps);
12730 }
12731 }
12732 var nextState = _payload.call(instance, prevState, nextProps);
12733 {
12734 exitDisallowedContextReadInDEV();
12735 }
12736 return nextState;
12737 }
12738 // State object
12739 return _payload;
12740 }
12741 case CaptureUpdate:
12742 {
12743 workInProgress.effectTag = workInProgress.effectTag & ~ShouldCapture | DidCapture;
12744 }
12745 // Intentional fallthrough
12746 case UpdateState:
12747 {
12748 var _payload2 = update.payload;
12749 var partialState = void 0;
12750 if (typeof _payload2 === 'function') {
12751 // Updater function
12752 {
12753 enterDisallowedContextReadInDEV();
12754 if (debugRenderPhaseSideEffects || debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) {
12755 _payload2.call(instance, prevState, nextProps);
12756 }
12757 }
12758 partialState = _payload2.call(instance, prevState, nextProps);
12759 {
12760 exitDisallowedContextReadInDEV();
12761 }
12762 } else {
12763 // Partial state object
12764 partialState = _payload2;
12765 }
12766 if (partialState === null || partialState === undefined) {
12767 // Null and undefined are treated as no-ops.
12768 return prevState;
12769 }
12770 // Merge the partial state and the previous state.
12771 return _assign({}, prevState, partialState);
12772 }
12773 case ForceUpdate:
12774 {
12775 hasForceUpdate = true;
12776 return prevState;
12777 }
12778 }
12779 return prevState;
12780}
12781
12782function processUpdateQueue(workInProgress, queue, props, instance, renderExpirationTime) {
12783 hasForceUpdate = false;
12784
12785 queue = ensureWorkInProgressQueueIsAClone(workInProgress, queue);
12786
12787 {
12788 currentlyProcessingQueue = queue;
12789 }
12790
12791 // These values may change as we process the queue.
12792 var newBaseState = queue.baseState;
12793 var newFirstUpdate = null;
12794 var newExpirationTime = NoWork;
12795
12796 // Iterate through the list of updates to compute the result.
12797 var update = queue.firstUpdate;
12798 var resultState = newBaseState;
12799 while (update !== null) {
12800 var updateExpirationTime = update.expirationTime;
12801 if (updateExpirationTime < renderExpirationTime) {
12802 // This update does not have sufficient priority. Skip it.
12803 if (newFirstUpdate === null) {
12804 // This is the first skipped update. It will be the first update in
12805 // the new list.
12806 newFirstUpdate = update;
12807 // Since this is the first update that was skipped, the current result
12808 // is the new base state.
12809 newBaseState = resultState;
12810 }
12811 // Since this update will remain in the list, update the remaining
12812 // expiration time.
12813 if (newExpirationTime < updateExpirationTime) {
12814 newExpirationTime = updateExpirationTime;
12815 }
12816 } else {
12817 // This update does have sufficient priority.
12818
12819 // Mark the event time of this update as relevant to this render pass.
12820 // TODO: This should ideally use the true event time of this update rather than
12821 // its priority which is a derived and not reverseable value.
12822 // TODO: We should skip this update if it was already committed but currently
12823 // we have no way of detecting the difference between a committed and suspended
12824 // update here.
12825 markRenderEventTimeAndConfig(updateExpirationTime, update.suspenseConfig);
12826
12827 // Process it and compute a new result.
12828 resultState = getStateFromUpdate(workInProgress, queue, update, resultState, props, instance);
12829 var _callback = update.callback;
12830 if (_callback !== null) {
12831 workInProgress.effectTag |= Callback;
12832 // Set this to null, in case it was mutated during an aborted render.
12833 update.nextEffect = null;
12834 if (queue.lastEffect === null) {
12835 queue.firstEffect = queue.lastEffect = update;
12836 } else {
12837 queue.lastEffect.nextEffect = update;
12838 queue.lastEffect = update;
12839 }
12840 }
12841 }
12842 // Continue to the next update.
12843 update = update.next;
12844 }
12845
12846 // Separately, iterate though the list of captured updates.
12847 var newFirstCapturedUpdate = null;
12848 update = queue.firstCapturedUpdate;
12849 while (update !== null) {
12850 var _updateExpirationTime = update.expirationTime;
12851 if (_updateExpirationTime < renderExpirationTime) {
12852 // This update does not have sufficient priority. Skip it.
12853 if (newFirstCapturedUpdate === null) {
12854 // This is the first skipped captured update. It will be the first
12855 // update in the new list.
12856 newFirstCapturedUpdate = update;
12857 // If this is the first update that was skipped, the current result is
12858 // the new base state.
12859 if (newFirstUpdate === null) {
12860 newBaseState = resultState;
12861 }
12862 }
12863 // Since this update will remain in the list, update the remaining
12864 // expiration time.
12865 if (newExpirationTime < _updateExpirationTime) {
12866 newExpirationTime = _updateExpirationTime;
12867 }
12868 } else {
12869 // This update does have sufficient priority. Process it and compute
12870 // a new result.
12871 resultState = getStateFromUpdate(workInProgress, queue, update, resultState, props, instance);
12872 var _callback2 = update.callback;
12873 if (_callback2 !== null) {
12874 workInProgress.effectTag |= Callback;
12875 // Set this to null, in case it was mutated during an aborted render.
12876 update.nextEffect = null;
12877 if (queue.lastCapturedEffect === null) {
12878 queue.firstCapturedEffect = queue.lastCapturedEffect = update;
12879 } else {
12880 queue.lastCapturedEffect.nextEffect = update;
12881 queue.lastCapturedEffect = update;
12882 }
12883 }
12884 }
12885 update = update.next;
12886 }
12887
12888 if (newFirstUpdate === null) {
12889 queue.lastUpdate = null;
12890 }
12891 if (newFirstCapturedUpdate === null) {
12892 queue.lastCapturedUpdate = null;
12893 } else {
12894 workInProgress.effectTag |= Callback;
12895 }
12896 if (newFirstUpdate === null && newFirstCapturedUpdate === null) {
12897 // We processed every update, without skipping. That means the new base
12898 // state is the same as the result state.
12899 newBaseState = resultState;
12900 }
12901
12902 queue.baseState = newBaseState;
12903 queue.firstUpdate = newFirstUpdate;
12904 queue.firstCapturedUpdate = newFirstCapturedUpdate;
12905
12906 // Set the remaining expiration time to be whatever is remaining in the queue.
12907 // This should be fine because the only two other things that contribute to
12908 // expiration time are props and context. We're already in the middle of the
12909 // begin phase by the time we start processing the queue, so we've already
12910 // dealt with the props. Context in components that specify
12911 // shouldComponentUpdate is tricky; but we'll have to account for
12912 // that regardless.
12913 workInProgress.expirationTime = newExpirationTime;
12914 workInProgress.memoizedState = resultState;
12915
12916 {
12917 currentlyProcessingQueue = null;
12918 }
12919}
12920
12921function callCallback(callback, context) {
12922 (function () {
12923 if (!(typeof callback === 'function')) {
12924 {
12925 throw ReactError(Error('Invalid argument passed as callback. Expected a function. Instead received: ' + callback));
12926 }
12927 }
12928 })();
12929 callback.call(context);
12930}
12931
12932function resetHasForceUpdateBeforeProcessing() {
12933 hasForceUpdate = false;
12934}
12935
12936function checkHasForceUpdateAfterProcessing() {
12937 return hasForceUpdate;
12938}
12939
12940function commitUpdateQueue(finishedWork, finishedQueue, instance, renderExpirationTime) {
12941 // If the finished render included captured updates, and there are still
12942 // lower priority updates left over, we need to keep the captured updates
12943 // in the queue so that they are rebased and not dropped once we process the
12944 // queue again at the lower priority.
12945 if (finishedQueue.firstCapturedUpdate !== null) {
12946 // Join the captured update list to the end of the normal list.
12947 if (finishedQueue.lastUpdate !== null) {
12948 finishedQueue.lastUpdate.next = finishedQueue.firstCapturedUpdate;
12949 finishedQueue.lastUpdate = finishedQueue.lastCapturedUpdate;
12950 }
12951 // Clear the list of captured updates.
12952 finishedQueue.firstCapturedUpdate = finishedQueue.lastCapturedUpdate = null;
12953 }
12954
12955 // Commit the effects
12956 commitUpdateEffects(finishedQueue.firstEffect, instance);
12957 finishedQueue.firstEffect = finishedQueue.lastEffect = null;
12958
12959 commitUpdateEffects(finishedQueue.firstCapturedEffect, instance);
12960 finishedQueue.firstCapturedEffect = finishedQueue.lastCapturedEffect = null;
12961}
12962
12963function commitUpdateEffects(effect, instance) {
12964 while (effect !== null) {
12965 var _callback3 = effect.callback;
12966 if (_callback3 !== null) {
12967 effect.callback = null;
12968 callCallback(_callback3, instance);
12969 }
12970 effect = effect.nextEffect;
12971 }
12972}
12973
12974var ReactCurrentBatchConfig = ReactSharedInternals.ReactCurrentBatchConfig;
12975
12976
12977function requestCurrentSuspenseConfig() {
12978 return ReactCurrentBatchConfig.suspense;
12979}
12980
12981var fakeInternalInstance = {};
12982var isArray$1 = Array.isArray;
12983
12984// React.Component uses a shared frozen object by default.
12985// We'll use it to determine whether we need to initialize legacy refs.
12986var emptyRefsObject = new React.Component().refs;
12987
12988var didWarnAboutStateAssignmentForComponent = void 0;
12989var didWarnAboutUninitializedState = void 0;
12990var didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate = void 0;
12991var didWarnAboutLegacyLifecyclesAndDerivedState = void 0;
12992var didWarnAboutUndefinedDerivedState = void 0;
12993var warnOnUndefinedDerivedState = void 0;
12994var warnOnInvalidCallback$1 = void 0;
12995var didWarnAboutDirectlyAssigningPropsToState = void 0;
12996var didWarnAboutContextTypeAndContextTypes = void 0;
12997var didWarnAboutInvalidateContextType = void 0;
12998
12999{
13000 didWarnAboutStateAssignmentForComponent = new Set();
13001 didWarnAboutUninitializedState = new Set();
13002 didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate = new Set();
13003 didWarnAboutLegacyLifecyclesAndDerivedState = new Set();
13004 didWarnAboutDirectlyAssigningPropsToState = new Set();
13005 didWarnAboutUndefinedDerivedState = new Set();
13006 didWarnAboutContextTypeAndContextTypes = new Set();
13007 didWarnAboutInvalidateContextType = new Set();
13008
13009 var didWarnOnInvalidCallback = new Set();
13010
13011 warnOnInvalidCallback$1 = function (callback, callerName) {
13012 if (callback === null || typeof callback === 'function') {
13013 return;
13014 }
13015 var key = callerName + '_' + callback;
13016 if (!didWarnOnInvalidCallback.has(key)) {
13017 didWarnOnInvalidCallback.add(key);
13018 warningWithoutStack$1(false, '%s(...): Expected the last optional `callback` argument to be a ' + 'function. Instead received: %s.', callerName, callback);
13019 }
13020 };
13021
13022 warnOnUndefinedDerivedState = function (type, partialState) {
13023 if (partialState === undefined) {
13024 var componentName = getComponentName(type) || 'Component';
13025 if (!didWarnAboutUndefinedDerivedState.has(componentName)) {
13026 didWarnAboutUndefinedDerivedState.add(componentName);
13027 warningWithoutStack$1(false, '%s.getDerivedStateFromProps(): A valid state object (or null) must be returned. ' + 'You have returned undefined.', componentName);
13028 }
13029 }
13030 };
13031
13032 // This is so gross but it's at least non-critical and can be removed if
13033 // it causes problems. This is meant to give a nicer error message for
13034 // ReactDOM15.unstable_renderSubtreeIntoContainer(reactDOM16Component,
13035 // ...)) which otherwise throws a "_processChildContext is not a function"
13036 // exception.
13037 Object.defineProperty(fakeInternalInstance, '_processChildContext', {
13038 enumerable: false,
13039 value: function () {
13040 (function () {
13041 {
13042 {
13043 throw ReactError(Error('_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).'));
13044 }
13045 }
13046 })();
13047 }
13048 });
13049 Object.freeze(fakeInternalInstance);
13050}
13051
13052function applyDerivedStateFromProps(workInProgress, ctor, getDerivedStateFromProps, nextProps) {
13053 var prevState = workInProgress.memoizedState;
13054
13055 {
13056 if (debugRenderPhaseSideEffects || debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) {
13057 // Invoke the function an extra time to help detect side-effects.
13058 getDerivedStateFromProps(nextProps, prevState);
13059 }
13060 }
13061
13062 var partialState = getDerivedStateFromProps(nextProps, prevState);
13063
13064 {
13065 warnOnUndefinedDerivedState(ctor, partialState);
13066 }
13067 // Merge the partial state and the previous state.
13068 var memoizedState = partialState === null || partialState === undefined ? prevState : _assign({}, prevState, partialState);
13069 workInProgress.memoizedState = memoizedState;
13070
13071 // Once the update queue is empty, persist the derived state onto the
13072 // base state.
13073 var updateQueue = workInProgress.updateQueue;
13074 if (updateQueue !== null && workInProgress.expirationTime === NoWork) {
13075 updateQueue.baseState = memoizedState;
13076 }
13077}
13078
13079var classComponentUpdater = {
13080 isMounted: isMounted,
13081 enqueueSetState: function (inst, payload, callback) {
13082 var fiber = get(inst);
13083 var currentTime = requestCurrentTime();
13084 var suspenseConfig = requestCurrentSuspenseConfig();
13085 var expirationTime = computeExpirationForFiber(currentTime, fiber, suspenseConfig);
13086
13087 var update = createUpdate(expirationTime, suspenseConfig);
13088 update.payload = payload;
13089 if (callback !== undefined && callback !== null) {
13090 {
13091 warnOnInvalidCallback$1(callback, 'setState');
13092 }
13093 update.callback = callback;
13094 }
13095
13096 if (revertPassiveEffectsChange) {
13097 flushPassiveEffects();
13098 }
13099 enqueueUpdate(fiber, update);
13100 scheduleWork(fiber, expirationTime);
13101 },
13102 enqueueReplaceState: function (inst, payload, callback) {
13103 var fiber = get(inst);
13104 var currentTime = requestCurrentTime();
13105 var suspenseConfig = requestCurrentSuspenseConfig();
13106 var expirationTime = computeExpirationForFiber(currentTime, fiber, suspenseConfig);
13107
13108 var update = createUpdate(expirationTime, suspenseConfig);
13109 update.tag = ReplaceState;
13110 update.payload = payload;
13111
13112 if (callback !== undefined && callback !== null) {
13113 {
13114 warnOnInvalidCallback$1(callback, 'replaceState');
13115 }
13116 update.callback = callback;
13117 }
13118
13119 if (revertPassiveEffectsChange) {
13120 flushPassiveEffects();
13121 }
13122 enqueueUpdate(fiber, update);
13123 scheduleWork(fiber, expirationTime);
13124 },
13125 enqueueForceUpdate: function (inst, callback) {
13126 var fiber = get(inst);
13127 var currentTime = requestCurrentTime();
13128 var suspenseConfig = requestCurrentSuspenseConfig();
13129 var expirationTime = computeExpirationForFiber(currentTime, fiber, suspenseConfig);
13130
13131 var update = createUpdate(expirationTime, suspenseConfig);
13132 update.tag = ForceUpdate;
13133
13134 if (callback !== undefined && callback !== null) {
13135 {
13136 warnOnInvalidCallback$1(callback, 'forceUpdate');
13137 }
13138 update.callback = callback;
13139 }
13140
13141 if (revertPassiveEffectsChange) {
13142 flushPassiveEffects();
13143 }
13144 enqueueUpdate(fiber, update);
13145 scheduleWork(fiber, expirationTime);
13146 }
13147};
13148
13149function checkShouldComponentUpdate(workInProgress, ctor, oldProps, newProps, oldState, newState, nextContext) {
13150 var instance = workInProgress.stateNode;
13151 if (typeof instance.shouldComponentUpdate === 'function') {
13152 startPhaseTimer(workInProgress, 'shouldComponentUpdate');
13153 var shouldUpdate = instance.shouldComponentUpdate(newProps, newState, nextContext);
13154 stopPhaseTimer();
13155
13156 {
13157 !(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;
13158 }
13159
13160 return shouldUpdate;
13161 }
13162
13163 if (ctor.prototype && ctor.prototype.isPureReactComponent) {
13164 return !shallowEqual(oldProps, newProps) || !shallowEqual(oldState, newState);
13165 }
13166
13167 return true;
13168}
13169
13170function checkClassInstance(workInProgress, ctor, newProps) {
13171 var instance = workInProgress.stateNode;
13172 {
13173 var name = getComponentName(ctor) || 'Component';
13174 var renderPresent = instance.render;
13175
13176 if (!renderPresent) {
13177 if (ctor.prototype && typeof ctor.prototype.render === 'function') {
13178 warningWithoutStack$1(false, '%s(...): No `render` method found on the returned component ' + 'instance: did you accidentally return an object from the constructor?', name);
13179 } else {
13180 warningWithoutStack$1(false, '%s(...): No `render` method found on the returned component ' + 'instance: you may have forgotten to define `render`.', name);
13181 }
13182 }
13183
13184 var noGetInitialStateOnES6 = !instance.getInitialState || instance.getInitialState.isReactClassApproved || instance.state;
13185 !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;
13186 var noGetDefaultPropsOnES6 = !instance.getDefaultProps || instance.getDefaultProps.isReactClassApproved;
13187 !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;
13188 var noInstancePropTypes = !instance.propTypes;
13189 !noInstancePropTypes ? warningWithoutStack$1(false, 'propTypes was defined as an instance property on %s. Use a static ' + 'property to define propTypes instead.', name) : void 0;
13190 var noInstanceContextType = !instance.contextType;
13191 !noInstanceContextType ? warningWithoutStack$1(false, 'contextType was defined as an instance property on %s. Use a static ' + 'property to define contextType instead.', name) : void 0;
13192
13193 if (disableLegacyContext) {
13194 if (ctor.childContextTypes) {
13195 warningWithoutStack$1(false, '%s uses the legacy childContextTypes API which is no longer supported. ' + 'Use React.createContext() instead.', name);
13196 }
13197 if (ctor.contextTypes) {
13198 warningWithoutStack$1(false, '%s uses the legacy contextTypes API which is no longer supported. ' + 'Use React.createContext() with static contextType instead.', name);
13199 }
13200 } else {
13201 var noInstanceContextTypes = !instance.contextTypes;
13202 !noInstanceContextTypes ? warningWithoutStack$1(false, 'contextTypes was defined as an instance property on %s. Use a static ' + 'property to define contextTypes instead.', name) : void 0;
13203
13204 if (ctor.contextType && ctor.contextTypes && !didWarnAboutContextTypeAndContextTypes.has(ctor)) {
13205 didWarnAboutContextTypeAndContextTypes.add(ctor);
13206 warningWithoutStack$1(false, '%s declares both contextTypes and contextType static properties. ' + 'The legacy contextTypes property will be ignored.', name);
13207 }
13208 }
13209
13210 var noComponentShouldUpdate = typeof instance.componentShouldUpdate !== 'function';
13211 !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;
13212 if (ctor.prototype && ctor.prototype.isPureReactComponent && typeof instance.shouldComponentUpdate !== 'undefined') {
13213 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');
13214 }
13215 var noComponentDidUnmount = typeof instance.componentDidUnmount !== 'function';
13216 !noComponentDidUnmount ? warningWithoutStack$1(false, '%s has a method called ' + 'componentDidUnmount(). But there is no such lifecycle method. ' + 'Did you mean componentWillUnmount()?', name) : void 0;
13217 var noComponentDidReceiveProps = typeof instance.componentDidReceiveProps !== 'function';
13218 !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;
13219 var noComponentWillRecieveProps = typeof instance.componentWillRecieveProps !== 'function';
13220 !noComponentWillRecieveProps ? warningWithoutStack$1(false, '%s has a method called ' + 'componentWillRecieveProps(). Did you mean componentWillReceiveProps()?', name) : void 0;
13221 var noUnsafeComponentWillRecieveProps = typeof instance.UNSAFE_componentWillRecieveProps !== 'function';
13222 !noUnsafeComponentWillRecieveProps ? warningWithoutStack$1(false, '%s has a method called ' + 'UNSAFE_componentWillRecieveProps(). Did you mean UNSAFE_componentWillReceiveProps()?', name) : void 0;
13223 var hasMutatedProps = instance.props !== newProps;
13224 !(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;
13225 var noInstanceDefaultProps = !instance.defaultProps;
13226 !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;
13227
13228 if (typeof instance.getSnapshotBeforeUpdate === 'function' && typeof instance.componentDidUpdate !== 'function' && !didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate.has(ctor)) {
13229 didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate.add(ctor);
13230 warningWithoutStack$1(false, '%s: getSnapshotBeforeUpdate() should be used with componentDidUpdate(). ' + 'This component defines getSnapshotBeforeUpdate() only.', getComponentName(ctor));
13231 }
13232
13233 var noInstanceGetDerivedStateFromProps = typeof instance.getDerivedStateFromProps !== 'function';
13234 !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;
13235 var noInstanceGetDerivedStateFromCatch = typeof instance.getDerivedStateFromError !== 'function';
13236 !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;
13237 var noStaticGetSnapshotBeforeUpdate = typeof ctor.getSnapshotBeforeUpdate !== 'function';
13238 !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;
13239 var _state = instance.state;
13240 if (_state && (typeof _state !== 'object' || isArray$1(_state))) {
13241 warningWithoutStack$1(false, '%s.state: must be set to an object or null', name);
13242 }
13243 if (typeof instance.getChildContext === 'function') {
13244 !(typeof ctor.childContextTypes === 'object') ? warningWithoutStack$1(false, '%s.getChildContext(): childContextTypes must be defined in order to ' + 'use getChildContext().', name) : void 0;
13245 }
13246 }
13247}
13248
13249function adoptClassInstance(workInProgress, instance) {
13250 instance.updater = classComponentUpdater;
13251 workInProgress.stateNode = instance;
13252 // The instance needs access to the fiber so that it can schedule updates
13253 set(instance, workInProgress);
13254 {
13255 instance._reactInternalInstance = fakeInternalInstance;
13256 }
13257}
13258
13259function constructClassInstance(workInProgress, ctor, props, renderExpirationTime) {
13260 var isLegacyContextConsumer = false;
13261 var unmaskedContext = emptyContextObject;
13262 var context = emptyContextObject;
13263 var contextType = ctor.contextType;
13264
13265 {
13266 if ('contextType' in ctor) {
13267 var isValid =
13268 // Allow null for conditional declaration
13269 contextType === null || contextType !== undefined && contextType.$$typeof === REACT_CONTEXT_TYPE && contextType._context === undefined; // Not a <Context.Consumer>
13270
13271 if (!isValid && !didWarnAboutInvalidateContextType.has(ctor)) {
13272 didWarnAboutInvalidateContextType.add(ctor);
13273
13274 var addendum = '';
13275 if (contextType === undefined) {
13276 addendum = ' However, it is set to undefined. ' + 'This can be caused by a typo or by mixing up named and default imports. ' + 'This can also happen due to a circular dependency, so ' + 'try moving the createContext() call to a separate file.';
13277 } else if (typeof contextType !== 'object') {
13278 addendum = ' However, it is set to a ' + typeof contextType + '.';
13279 } else if (contextType.$$typeof === REACT_PROVIDER_TYPE) {
13280 addendum = ' Did you accidentally pass the Context.Provider instead?';
13281 } else if (contextType._context !== undefined) {
13282 // <Context.Consumer>
13283 addendum = ' Did you accidentally pass the Context.Consumer instead?';
13284 } else {
13285 addendum = ' However, it is set to an object with keys {' + Object.keys(contextType).join(', ') + '}.';
13286 }
13287 warningWithoutStack$1(false, '%s defines an invalid contextType. ' + 'contextType should point to the Context object returned by React.createContext().%s', getComponentName(ctor) || 'Component', addendum);
13288 }
13289 }
13290 }
13291
13292 if (typeof contextType === 'object' && contextType !== null) {
13293 context = readContext(contextType);
13294 } else if (!disableLegacyContext) {
13295 unmaskedContext = getUnmaskedContext(workInProgress, ctor, true);
13296 var contextTypes = ctor.contextTypes;
13297 isLegacyContextConsumer = contextTypes !== null && contextTypes !== undefined;
13298 context = isLegacyContextConsumer ? getMaskedContext(workInProgress, unmaskedContext) : emptyContextObject;
13299 }
13300
13301 // Instantiate twice to help detect side-effects.
13302 {
13303 if (debugRenderPhaseSideEffects || debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) {
13304 new ctor(props, context); // eslint-disable-line no-new
13305 }
13306 }
13307
13308 var instance = new ctor(props, context);
13309 var state = workInProgress.memoizedState = instance.state !== null && instance.state !== undefined ? instance.state : null;
13310 adoptClassInstance(workInProgress, instance);
13311
13312 {
13313 if (typeof ctor.getDerivedStateFromProps === 'function' && state === null) {
13314 var componentName = getComponentName(ctor) || 'Component';
13315 if (!didWarnAboutUninitializedState.has(componentName)) {
13316 didWarnAboutUninitializedState.add(componentName);
13317 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);
13318 }
13319 }
13320
13321 // If new component APIs are defined, "unsafe" lifecycles won't be called.
13322 // Warn about these lifecycles if they are present.
13323 // Don't warn about react-lifecycles-compat polyfilled methods though.
13324 if (typeof ctor.getDerivedStateFromProps === 'function' || typeof instance.getSnapshotBeforeUpdate === 'function') {
13325 var foundWillMountName = null;
13326 var foundWillReceivePropsName = null;
13327 var foundWillUpdateName = null;
13328 if (typeof instance.componentWillMount === 'function' && instance.componentWillMount.__suppressDeprecationWarning !== true) {
13329 foundWillMountName = 'componentWillMount';
13330 } else if (typeof instance.UNSAFE_componentWillMount === 'function') {
13331 foundWillMountName = 'UNSAFE_componentWillMount';
13332 }
13333 if (typeof instance.componentWillReceiveProps === 'function' && instance.componentWillReceiveProps.__suppressDeprecationWarning !== true) {
13334 foundWillReceivePropsName = 'componentWillReceiveProps';
13335 } else if (typeof instance.UNSAFE_componentWillReceiveProps === 'function') {
13336 foundWillReceivePropsName = 'UNSAFE_componentWillReceiveProps';
13337 }
13338 if (typeof instance.componentWillUpdate === 'function' && instance.componentWillUpdate.__suppressDeprecationWarning !== true) {
13339 foundWillUpdateName = 'componentWillUpdate';
13340 } else if (typeof instance.UNSAFE_componentWillUpdate === 'function') {
13341 foundWillUpdateName = 'UNSAFE_componentWillUpdate';
13342 }
13343 if (foundWillMountName !== null || foundWillReceivePropsName !== null || foundWillUpdateName !== null) {
13344 var _componentName = getComponentName(ctor) || 'Component';
13345 var newApiName = typeof ctor.getDerivedStateFromProps === 'function' ? 'getDerivedStateFromProps()' : 'getSnapshotBeforeUpdate()';
13346 if (!didWarnAboutLegacyLifecyclesAndDerivedState.has(_componentName)) {
13347 didWarnAboutLegacyLifecyclesAndDerivedState.add(_componentName);
13348 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 : '');
13349 }
13350 }
13351 }
13352 }
13353
13354 // Cache unmasked context so we can avoid recreating masked context unless necessary.
13355 // ReactFiberContext usually updates this cache but can't for newly-created instances.
13356 if (isLegacyContextConsumer) {
13357 cacheContext(workInProgress, unmaskedContext, context);
13358 }
13359
13360 return instance;
13361}
13362
13363function callComponentWillMount(workInProgress, instance) {
13364 startPhaseTimer(workInProgress, 'componentWillMount');
13365 var oldState = instance.state;
13366
13367 if (typeof instance.componentWillMount === 'function') {
13368 instance.componentWillMount();
13369 }
13370 if (typeof instance.UNSAFE_componentWillMount === 'function') {
13371 instance.UNSAFE_componentWillMount();
13372 }
13373
13374 stopPhaseTimer();
13375
13376 if (oldState !== instance.state) {
13377 {
13378 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');
13379 }
13380 classComponentUpdater.enqueueReplaceState(instance, instance.state, null);
13381 }
13382}
13383
13384function callComponentWillReceiveProps(workInProgress, instance, newProps, nextContext) {
13385 var oldState = instance.state;
13386 startPhaseTimer(workInProgress, 'componentWillReceiveProps');
13387 if (typeof instance.componentWillReceiveProps === 'function') {
13388 instance.componentWillReceiveProps(newProps, nextContext);
13389 }
13390 if (typeof instance.UNSAFE_componentWillReceiveProps === 'function') {
13391 instance.UNSAFE_componentWillReceiveProps(newProps, nextContext);
13392 }
13393 stopPhaseTimer();
13394
13395 if (instance.state !== oldState) {
13396 {
13397 var componentName = getComponentName(workInProgress.type) || 'Component';
13398 if (!didWarnAboutStateAssignmentForComponent.has(componentName)) {
13399 didWarnAboutStateAssignmentForComponent.add(componentName);
13400 warningWithoutStack$1(false, '%s.componentWillReceiveProps(): Assigning directly to ' + "this.state is deprecated (except inside a component's " + 'constructor). Use setState instead.', componentName);
13401 }
13402 }
13403 classComponentUpdater.enqueueReplaceState(instance, instance.state, null);
13404 }
13405}
13406
13407// Invokes the mount life-cycles on a previously never rendered instance.
13408function mountClassInstance(workInProgress, ctor, newProps, renderExpirationTime) {
13409 {
13410 checkClassInstance(workInProgress, ctor, newProps);
13411 }
13412
13413 var instance = workInProgress.stateNode;
13414 instance.props = newProps;
13415 instance.state = workInProgress.memoizedState;
13416 instance.refs = emptyRefsObject;
13417
13418 var contextType = ctor.contextType;
13419 if (typeof contextType === 'object' && contextType !== null) {
13420 instance.context = readContext(contextType);
13421 } else if (disableLegacyContext) {
13422 instance.context = emptyContextObject;
13423 } else {
13424 var unmaskedContext = getUnmaskedContext(workInProgress, ctor, true);
13425 instance.context = getMaskedContext(workInProgress, unmaskedContext);
13426 }
13427
13428 {
13429 if (instance.state === newProps) {
13430 var componentName = getComponentName(ctor) || 'Component';
13431 if (!didWarnAboutDirectlyAssigningPropsToState.has(componentName)) {
13432 didWarnAboutDirectlyAssigningPropsToState.add(componentName);
13433 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);
13434 }
13435 }
13436
13437 if (workInProgress.mode & StrictMode) {
13438 ReactStrictModeWarnings.recordLegacyContextWarning(workInProgress, instance);
13439 }
13440
13441 if (warnAboutDeprecatedLifecycles) {
13442 ReactStrictModeWarnings.recordUnsafeLifecycleWarnings(workInProgress, instance);
13443 }
13444 }
13445
13446 var updateQueue = workInProgress.updateQueue;
13447 if (updateQueue !== null) {
13448 processUpdateQueue(workInProgress, updateQueue, newProps, instance, renderExpirationTime);
13449 instance.state = workInProgress.memoizedState;
13450 }
13451
13452 var getDerivedStateFromProps = ctor.getDerivedStateFromProps;
13453 if (typeof getDerivedStateFromProps === 'function') {
13454 applyDerivedStateFromProps(workInProgress, ctor, getDerivedStateFromProps, newProps);
13455 instance.state = workInProgress.memoizedState;
13456 }
13457
13458 // In order to support react-lifecycles-compat polyfilled components,
13459 // Unsafe lifecycles should not be invoked for components using the new APIs.
13460 if (typeof ctor.getDerivedStateFromProps !== 'function' && typeof instance.getSnapshotBeforeUpdate !== 'function' && (typeof instance.UNSAFE_componentWillMount === 'function' || typeof instance.componentWillMount === 'function')) {
13461 callComponentWillMount(workInProgress, instance);
13462 // If we had additional state updates during this life-cycle, let's
13463 // process them now.
13464 updateQueue = workInProgress.updateQueue;
13465 if (updateQueue !== null) {
13466 processUpdateQueue(workInProgress, updateQueue, newProps, instance, renderExpirationTime);
13467 instance.state = workInProgress.memoizedState;
13468 }
13469 }
13470
13471 if (typeof instance.componentDidMount === 'function') {
13472 workInProgress.effectTag |= Update;
13473 }
13474}
13475
13476function resumeMountClassInstance(workInProgress, ctor, newProps, renderExpirationTime) {
13477 var instance = workInProgress.stateNode;
13478
13479 var oldProps = workInProgress.memoizedProps;
13480 instance.props = oldProps;
13481
13482 var oldContext = instance.context;
13483 var contextType = ctor.contextType;
13484 var nextContext = emptyContextObject;
13485 if (typeof contextType === 'object' && contextType !== null) {
13486 nextContext = readContext(contextType);
13487 } else if (!disableLegacyContext) {
13488 var nextLegacyUnmaskedContext = getUnmaskedContext(workInProgress, ctor, true);
13489 nextContext = getMaskedContext(workInProgress, nextLegacyUnmaskedContext);
13490 }
13491
13492 var getDerivedStateFromProps = ctor.getDerivedStateFromProps;
13493 var hasNewLifecycles = typeof getDerivedStateFromProps === 'function' || typeof instance.getSnapshotBeforeUpdate === 'function';
13494
13495 // Note: During these life-cycles, instance.props/instance.state are what
13496 // ever the previously attempted to render - not the "current". However,
13497 // during componentDidUpdate we pass the "current" props.
13498
13499 // In order to support react-lifecycles-compat polyfilled components,
13500 // Unsafe lifecycles should not be invoked for components using the new APIs.
13501 if (!hasNewLifecycles && (typeof instance.UNSAFE_componentWillReceiveProps === 'function' || typeof instance.componentWillReceiveProps === 'function')) {
13502 if (oldProps !== newProps || oldContext !== nextContext) {
13503 callComponentWillReceiveProps(workInProgress, instance, newProps, nextContext);
13504 }
13505 }
13506
13507 resetHasForceUpdateBeforeProcessing();
13508
13509 var oldState = workInProgress.memoizedState;
13510 var newState = instance.state = oldState;
13511 var updateQueue = workInProgress.updateQueue;
13512 if (updateQueue !== null) {
13513 processUpdateQueue(workInProgress, updateQueue, newProps, instance, renderExpirationTime);
13514 newState = workInProgress.memoizedState;
13515 }
13516 if (oldProps === newProps && oldState === newState && !hasContextChanged() && !checkHasForceUpdateAfterProcessing()) {
13517 // If an update was already in progress, we should schedule an Update
13518 // effect even though we're bailing out, so that cWU/cDU are called.
13519 if (typeof instance.componentDidMount === 'function') {
13520 workInProgress.effectTag |= Update;
13521 }
13522 return false;
13523 }
13524
13525 if (typeof getDerivedStateFromProps === 'function') {
13526 applyDerivedStateFromProps(workInProgress, ctor, getDerivedStateFromProps, newProps);
13527 newState = workInProgress.memoizedState;
13528 }
13529
13530 var shouldUpdate = checkHasForceUpdateAfterProcessing() || checkShouldComponentUpdate(workInProgress, ctor, oldProps, newProps, oldState, newState, nextContext);
13531
13532 if (shouldUpdate) {
13533 // In order to support react-lifecycles-compat polyfilled components,
13534 // Unsafe lifecycles should not be invoked for components using the new APIs.
13535 if (!hasNewLifecycles && (typeof instance.UNSAFE_componentWillMount === 'function' || typeof instance.componentWillMount === 'function')) {
13536 startPhaseTimer(workInProgress, 'componentWillMount');
13537 if (typeof instance.componentWillMount === 'function') {
13538 instance.componentWillMount();
13539 }
13540 if (typeof instance.UNSAFE_componentWillMount === 'function') {
13541 instance.UNSAFE_componentWillMount();
13542 }
13543 stopPhaseTimer();
13544 }
13545 if (typeof instance.componentDidMount === 'function') {
13546 workInProgress.effectTag |= Update;
13547 }
13548 } else {
13549 // If an update was already in progress, we should schedule an Update
13550 // effect even though we're bailing out, so that cWU/cDU are called.
13551 if (typeof instance.componentDidMount === 'function') {
13552 workInProgress.effectTag |= Update;
13553 }
13554
13555 // If shouldComponentUpdate returned false, we should still update the
13556 // memoized state to indicate that this work can be reused.
13557 workInProgress.memoizedProps = newProps;
13558 workInProgress.memoizedState = newState;
13559 }
13560
13561 // Update the existing instance's state, props, and context pointers even
13562 // if shouldComponentUpdate returns false.
13563 instance.props = newProps;
13564 instance.state = newState;
13565 instance.context = nextContext;
13566
13567 return shouldUpdate;
13568}
13569
13570// Invokes the update life-cycles and returns false if it shouldn't rerender.
13571function updateClassInstance(current, workInProgress, ctor, newProps, renderExpirationTime) {
13572 var instance = workInProgress.stateNode;
13573
13574 var oldProps = workInProgress.memoizedProps;
13575 instance.props = workInProgress.type === workInProgress.elementType ? oldProps : resolveDefaultProps(workInProgress.type, oldProps);
13576
13577 var oldContext = instance.context;
13578 var contextType = ctor.contextType;
13579 var nextContext = emptyContextObject;
13580 if (typeof contextType === 'object' && contextType !== null) {
13581 nextContext = readContext(contextType);
13582 } else if (!disableLegacyContext) {
13583 var nextUnmaskedContext = getUnmaskedContext(workInProgress, ctor, true);
13584 nextContext = getMaskedContext(workInProgress, nextUnmaskedContext);
13585 }
13586
13587 var getDerivedStateFromProps = ctor.getDerivedStateFromProps;
13588 var hasNewLifecycles = typeof getDerivedStateFromProps === 'function' || typeof instance.getSnapshotBeforeUpdate === 'function';
13589
13590 // Note: During these life-cycles, instance.props/instance.state are what
13591 // ever the previously attempted to render - not the "current". However,
13592 // during componentDidUpdate we pass the "current" props.
13593
13594 // In order to support react-lifecycles-compat polyfilled components,
13595 // Unsafe lifecycles should not be invoked for components using the new APIs.
13596 if (!hasNewLifecycles && (typeof instance.UNSAFE_componentWillReceiveProps === 'function' || typeof instance.componentWillReceiveProps === 'function')) {
13597 if (oldProps !== newProps || oldContext !== nextContext) {
13598 callComponentWillReceiveProps(workInProgress, instance, newProps, nextContext);
13599 }
13600 }
13601
13602 resetHasForceUpdateBeforeProcessing();
13603
13604 var oldState = workInProgress.memoizedState;
13605 var newState = instance.state = oldState;
13606 var updateQueue = workInProgress.updateQueue;
13607 if (updateQueue !== null) {
13608 processUpdateQueue(workInProgress, updateQueue, newProps, instance, renderExpirationTime);
13609 newState = workInProgress.memoizedState;
13610 }
13611
13612 if (oldProps === newProps && oldState === newState && !hasContextChanged() && !checkHasForceUpdateAfterProcessing()) {
13613 // If an update was already in progress, we should schedule an Update
13614 // effect even though we're bailing out, so that cWU/cDU are called.
13615 if (typeof instance.componentDidUpdate === 'function') {
13616 if (oldProps !== current.memoizedProps || oldState !== current.memoizedState) {
13617 workInProgress.effectTag |= Update;
13618 }
13619 }
13620 if (typeof instance.getSnapshotBeforeUpdate === 'function') {
13621 if (oldProps !== current.memoizedProps || oldState !== current.memoizedState) {
13622 workInProgress.effectTag |= Snapshot;
13623 }
13624 }
13625 return false;
13626 }
13627
13628 if (typeof getDerivedStateFromProps === 'function') {
13629 applyDerivedStateFromProps(workInProgress, ctor, getDerivedStateFromProps, newProps);
13630 newState = workInProgress.memoizedState;
13631 }
13632
13633 var shouldUpdate = checkHasForceUpdateAfterProcessing() || checkShouldComponentUpdate(workInProgress, ctor, oldProps, newProps, oldState, newState, nextContext);
13634
13635 if (shouldUpdate) {
13636 // In order to support react-lifecycles-compat polyfilled components,
13637 // Unsafe lifecycles should not be invoked for components using the new APIs.
13638 if (!hasNewLifecycles && (typeof instance.UNSAFE_componentWillUpdate === 'function' || typeof instance.componentWillUpdate === 'function')) {
13639 startPhaseTimer(workInProgress, 'componentWillUpdate');
13640 if (typeof instance.componentWillUpdate === 'function') {
13641 instance.componentWillUpdate(newProps, newState, nextContext);
13642 }
13643 if (typeof instance.UNSAFE_componentWillUpdate === 'function') {
13644 instance.UNSAFE_componentWillUpdate(newProps, newState, nextContext);
13645 }
13646 stopPhaseTimer();
13647 }
13648 if (typeof instance.componentDidUpdate === 'function') {
13649 workInProgress.effectTag |= Update;
13650 }
13651 if (typeof instance.getSnapshotBeforeUpdate === 'function') {
13652 workInProgress.effectTag |= Snapshot;
13653 }
13654 } else {
13655 // If an update was already in progress, we should schedule an Update
13656 // effect even though we're bailing out, so that cWU/cDU are called.
13657 if (typeof instance.componentDidUpdate === 'function') {
13658 if (oldProps !== current.memoizedProps || oldState !== current.memoizedState) {
13659 workInProgress.effectTag |= Update;
13660 }
13661 }
13662 if (typeof instance.getSnapshotBeforeUpdate === 'function') {
13663 if (oldProps !== current.memoizedProps || oldState !== current.memoizedState) {
13664 workInProgress.effectTag |= Snapshot;
13665 }
13666 }
13667
13668 // If shouldComponentUpdate returned false, we should still update the
13669 // memoized props/state to indicate that this work can be reused.
13670 workInProgress.memoizedProps = newProps;
13671 workInProgress.memoizedState = newState;
13672 }
13673
13674 // Update the existing instance's state, props, and context pointers even
13675 // if shouldComponentUpdate returns false.
13676 instance.props = newProps;
13677 instance.state = newState;
13678 instance.context = nextContext;
13679
13680 return shouldUpdate;
13681}
13682
13683var didWarnAboutMaps = void 0;
13684var didWarnAboutGenerators = void 0;
13685var didWarnAboutStringRefInStrictMode = void 0;
13686var ownerHasKeyUseWarning = void 0;
13687var ownerHasFunctionTypeWarning = void 0;
13688var warnForMissingKey = function (child) {};
13689
13690{
13691 didWarnAboutMaps = false;
13692 didWarnAboutGenerators = false;
13693 didWarnAboutStringRefInStrictMode = {};
13694
13695 /**
13696 * Warn if there's no key explicitly set on dynamic arrays of children or
13697 * object keys are not valid. This allows us to keep track of children between
13698 * updates.
13699 */
13700 ownerHasKeyUseWarning = {};
13701 ownerHasFunctionTypeWarning = {};
13702
13703 warnForMissingKey = function (child) {
13704 if (child === null || typeof child !== 'object') {
13705 return;
13706 }
13707 if (!child._store || child._store.validated || child.key != null) {
13708 return;
13709 }
13710 (function () {
13711 if (!(typeof child._store === 'object')) {
13712 {
13713 throw ReactError(Error('React Component in warnForMissingKey should have a _store. This error is likely caused by a bug in React. Please file an issue.'));
13714 }
13715 }
13716 })();
13717 child._store.validated = true;
13718
13719 var currentComponentErrorInfo = 'Each child in a list should have a unique ' + '"key" prop. See https://fb.me/react-warning-keys for ' + 'more information.' + getCurrentFiberStackInDev();
13720 if (ownerHasKeyUseWarning[currentComponentErrorInfo]) {
13721 return;
13722 }
13723 ownerHasKeyUseWarning[currentComponentErrorInfo] = true;
13724
13725 warning$1(false, 'Each child in a list should have a unique ' + '"key" prop. See https://fb.me/react-warning-keys for ' + 'more information.');
13726 };
13727}
13728
13729var isArray = Array.isArray;
13730
13731function coerceRef(returnFiber, current$$1, element) {
13732 var mixedRef = element.ref;
13733 if (mixedRef !== null && typeof mixedRef !== 'function' && typeof mixedRef !== 'object') {
13734 {
13735 if (returnFiber.mode & StrictMode) {
13736 var componentName = getComponentName(returnFiber.type) || 'Component';
13737 if (!didWarnAboutStringRefInStrictMode[componentName]) {
13738 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));
13739 didWarnAboutStringRefInStrictMode[componentName] = true;
13740 }
13741 }
13742 }
13743
13744 if (element._owner) {
13745 var owner = element._owner;
13746 var inst = void 0;
13747 if (owner) {
13748 var ownerFiber = owner;
13749 (function () {
13750 if (!(ownerFiber.tag === ClassComponent)) {
13751 {
13752 throw ReactError(Error('Function components cannot have refs. Did you mean to use React.forwardRef()?'));
13753 }
13754 }
13755 })();
13756 inst = ownerFiber.stateNode;
13757 }
13758 (function () {
13759 if (!inst) {
13760 {
13761 throw ReactError(Error('Missing owner for string ref ' + mixedRef + '. This error is likely caused by a bug in React. Please file an issue.'));
13762 }
13763 }
13764 })();
13765 var stringRef = '' + mixedRef;
13766 // Check if previous string ref matches new string ref
13767 if (current$$1 !== null && current$$1.ref !== null && typeof current$$1.ref === 'function' && current$$1.ref._stringRef === stringRef) {
13768 return current$$1.ref;
13769 }
13770 var ref = function (value) {
13771 var refs = inst.refs;
13772 if (refs === emptyRefsObject) {
13773 // This is a lazy pooled frozen object, so we need to initialize.
13774 refs = inst.refs = {};
13775 }
13776 if (value === null) {
13777 delete refs[stringRef];
13778 } else {
13779 refs[stringRef] = value;
13780 }
13781 };
13782 ref._stringRef = stringRef;
13783 return ref;
13784 } else {
13785 (function () {
13786 if (!(typeof mixedRef === 'string')) {
13787 {
13788 throw ReactError(Error('Expected ref to be a function, a string, an object returned by React.createRef(), or null.'));
13789 }
13790 }
13791 })();
13792 (function () {
13793 if (!element._owner) {
13794 {
13795 throw ReactError(Error('Element ref was specified as a string (' + mixedRef + ') 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.'));
13796 }
13797 }
13798 })();
13799 }
13800 }
13801 return mixedRef;
13802}
13803
13804function throwOnInvalidObjectType(returnFiber, newChild) {
13805 if (returnFiber.type !== 'textarea') {
13806 var addendum = '';
13807 {
13808 addendum = ' If you meant to render a collection of children, use an array ' + 'instead.' + getCurrentFiberStackInDev();
13809 }
13810 (function () {
13811 {
13812 {
13813 throw ReactError(Error('Objects are not valid as a React child (found: ' + (Object.prototype.toString.call(newChild) === '[object Object]' ? 'object with keys {' + Object.keys(newChild).join(', ') + '}' : newChild) + ').' + addendum));
13814 }
13815 }
13816 })();
13817 }
13818}
13819
13820function warnOnFunctionType() {
13821 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();
13822
13823 if (ownerHasFunctionTypeWarning[currentComponentErrorInfo]) {
13824 return;
13825 }
13826 ownerHasFunctionTypeWarning[currentComponentErrorInfo] = true;
13827
13828 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.');
13829}
13830
13831// This wrapper function exists because I expect to clone the code in each path
13832// to be able to optimize each path individually by branching early. This needs
13833// a compiler or we can do it manually. Helpers that don't need this branching
13834// live outside of this function.
13835function ChildReconciler(shouldTrackSideEffects) {
13836 function deleteChild(returnFiber, childToDelete) {
13837 if (!shouldTrackSideEffects) {
13838 // Noop.
13839 return;
13840 }
13841 // Deletions are added in reversed order so we add it to the front.
13842 // At this point, the return fiber's effect list is empty except for
13843 // deletions, so we can just append the deletion to the list. The remaining
13844 // effects aren't added until the complete phase. Once we implement
13845 // resuming, this may not be true.
13846 var last = returnFiber.lastEffect;
13847 if (last !== null) {
13848 last.nextEffect = childToDelete;
13849 returnFiber.lastEffect = childToDelete;
13850 } else {
13851 returnFiber.firstEffect = returnFiber.lastEffect = childToDelete;
13852 }
13853 childToDelete.nextEffect = null;
13854 childToDelete.effectTag = Deletion;
13855 }
13856
13857 function deleteRemainingChildren(returnFiber, currentFirstChild) {
13858 if (!shouldTrackSideEffects) {
13859 // Noop.
13860 return null;
13861 }
13862
13863 // TODO: For the shouldClone case, this could be micro-optimized a bit by
13864 // assuming that after the first child we've already added everything.
13865 var childToDelete = currentFirstChild;
13866 while (childToDelete !== null) {
13867 deleteChild(returnFiber, childToDelete);
13868 childToDelete = childToDelete.sibling;
13869 }
13870 return null;
13871 }
13872
13873 function mapRemainingChildren(returnFiber, currentFirstChild) {
13874 // Add the remaining children to a temporary map so that we can find them by
13875 // keys quickly. Implicit (null) keys get added to this set with their index
13876 var existingChildren = new Map();
13877
13878 var existingChild = currentFirstChild;
13879 while (existingChild !== null) {
13880 if (existingChild.key !== null) {
13881 existingChildren.set(existingChild.key, existingChild);
13882 } else {
13883 existingChildren.set(existingChild.index, existingChild);
13884 }
13885 existingChild = existingChild.sibling;
13886 }
13887 return existingChildren;
13888 }
13889
13890 function useFiber(fiber, pendingProps, expirationTime) {
13891 // We currently set sibling to null and index to 0 here because it is easy
13892 // to forget to do before returning it. E.g. for the single child case.
13893 var clone = createWorkInProgress(fiber, pendingProps, expirationTime);
13894 clone.index = 0;
13895 clone.sibling = null;
13896 return clone;
13897 }
13898
13899 function placeChild(newFiber, lastPlacedIndex, newIndex) {
13900 newFiber.index = newIndex;
13901 if (!shouldTrackSideEffects) {
13902 // Noop.
13903 return lastPlacedIndex;
13904 }
13905 var current$$1 = newFiber.alternate;
13906 if (current$$1 !== null) {
13907 var oldIndex = current$$1.index;
13908 if (oldIndex < lastPlacedIndex) {
13909 // This is a move.
13910 newFiber.effectTag = Placement;
13911 return lastPlacedIndex;
13912 } else {
13913 // This item can stay in place.
13914 return oldIndex;
13915 }
13916 } else {
13917 // This is an insertion.
13918 newFiber.effectTag = Placement;
13919 return lastPlacedIndex;
13920 }
13921 }
13922
13923 function placeSingleChild(newFiber) {
13924 // This is simpler for the single child case. We only need to do a
13925 // placement for inserting new children.
13926 if (shouldTrackSideEffects && newFiber.alternate === null) {
13927 newFiber.effectTag = Placement;
13928 }
13929 return newFiber;
13930 }
13931
13932 function updateTextNode(returnFiber, current$$1, textContent, expirationTime) {
13933 if (current$$1 === null || current$$1.tag !== HostText) {
13934 // Insert
13935 var created = createFiberFromText(textContent, returnFiber.mode, expirationTime);
13936 created.return = returnFiber;
13937 return created;
13938 } else {
13939 // Update
13940 var existing = useFiber(current$$1, textContent, expirationTime);
13941 existing.return = returnFiber;
13942 return existing;
13943 }
13944 }
13945
13946 function updateElement(returnFiber, current$$1, element, expirationTime) {
13947 if (current$$1 !== null && (current$$1.elementType === element.type || (
13948 // Keep this check inline so it only runs on the false path:
13949 isCompatibleFamilyForHotReloading(current$$1, element)))) {
13950 // Move based on index
13951 var existing = useFiber(current$$1, element.props, expirationTime);
13952 existing.ref = coerceRef(returnFiber, current$$1, element);
13953 existing.return = returnFiber;
13954 {
13955 existing._debugSource = element._source;
13956 existing._debugOwner = element._owner;
13957 }
13958 return existing;
13959 } else {
13960 // Insert
13961 var created = createFiberFromElement(element, returnFiber.mode, expirationTime);
13962 created.ref = coerceRef(returnFiber, current$$1, element);
13963 created.return = returnFiber;
13964 return created;
13965 }
13966 }
13967
13968 function updatePortal(returnFiber, current$$1, portal, expirationTime) {
13969 if (current$$1 === null || current$$1.tag !== HostPortal || current$$1.stateNode.containerInfo !== portal.containerInfo || current$$1.stateNode.implementation !== portal.implementation) {
13970 // Insert
13971 var created = createFiberFromPortal(portal, returnFiber.mode, expirationTime);
13972 created.return = returnFiber;
13973 return created;
13974 } else {
13975 // Update
13976 var existing = useFiber(current$$1, portal.children || [], expirationTime);
13977 existing.return = returnFiber;
13978 return existing;
13979 }
13980 }
13981
13982 function updateFragment(returnFiber, current$$1, fragment, expirationTime, key) {
13983 if (current$$1 === null || current$$1.tag !== Fragment) {
13984 // Insert
13985 var created = createFiberFromFragment(fragment, returnFiber.mode, expirationTime, key);
13986 created.return = returnFiber;
13987 return created;
13988 } else {
13989 // Update
13990 var existing = useFiber(current$$1, fragment, expirationTime);
13991 existing.return = returnFiber;
13992 return existing;
13993 }
13994 }
13995
13996 function createChild(returnFiber, newChild, expirationTime) {
13997 if (typeof newChild === 'string' || typeof newChild === 'number') {
13998 // Text nodes don't have keys. If the previous node is implicitly keyed
13999 // we can continue to replace it without aborting even if it is not a text
14000 // node.
14001 var created = createFiberFromText('' + newChild, returnFiber.mode, expirationTime);
14002 created.return = returnFiber;
14003 return created;
14004 }
14005
14006 if (typeof newChild === 'object' && newChild !== null) {
14007 switch (newChild.$$typeof) {
14008 case REACT_ELEMENT_TYPE:
14009 {
14010 var _created = createFiberFromElement(newChild, returnFiber.mode, expirationTime);
14011 _created.ref = coerceRef(returnFiber, null, newChild);
14012 _created.return = returnFiber;
14013 return _created;
14014 }
14015 case REACT_PORTAL_TYPE:
14016 {
14017 var _created2 = createFiberFromPortal(newChild, returnFiber.mode, expirationTime);
14018 _created2.return = returnFiber;
14019 return _created2;
14020 }
14021 }
14022
14023 if (isArray(newChild) || getIteratorFn(newChild)) {
14024 var _created3 = createFiberFromFragment(newChild, returnFiber.mode, expirationTime, null);
14025 _created3.return = returnFiber;
14026 return _created3;
14027 }
14028
14029 throwOnInvalidObjectType(returnFiber, newChild);
14030 }
14031
14032 {
14033 if (typeof newChild === 'function') {
14034 warnOnFunctionType();
14035 }
14036 }
14037
14038 return null;
14039 }
14040
14041 function updateSlot(returnFiber, oldFiber, newChild, expirationTime) {
14042 // Update the fiber if the keys match, otherwise return null.
14043
14044 var key = oldFiber !== null ? oldFiber.key : null;
14045
14046 if (typeof newChild === 'string' || typeof newChild === 'number') {
14047 // Text nodes don't have keys. If the previous node is implicitly keyed
14048 // we can continue to replace it without aborting even if it is not a text
14049 // node.
14050 if (key !== null) {
14051 return null;
14052 }
14053 return updateTextNode(returnFiber, oldFiber, '' + newChild, expirationTime);
14054 }
14055
14056 if (typeof newChild === 'object' && newChild !== null) {
14057 switch (newChild.$$typeof) {
14058 case REACT_ELEMENT_TYPE:
14059 {
14060 if (newChild.key === key) {
14061 if (newChild.type === REACT_FRAGMENT_TYPE) {
14062 return updateFragment(returnFiber, oldFiber, newChild.props.children, expirationTime, key);
14063 }
14064 return updateElement(returnFiber, oldFiber, newChild, expirationTime);
14065 } else {
14066 return null;
14067 }
14068 }
14069 case REACT_PORTAL_TYPE:
14070 {
14071 if (newChild.key === key) {
14072 return updatePortal(returnFiber, oldFiber, newChild, expirationTime);
14073 } else {
14074 return null;
14075 }
14076 }
14077 }
14078
14079 if (isArray(newChild) || getIteratorFn(newChild)) {
14080 if (key !== null) {
14081 return null;
14082 }
14083
14084 return updateFragment(returnFiber, oldFiber, newChild, expirationTime, null);
14085 }
14086
14087 throwOnInvalidObjectType(returnFiber, newChild);
14088 }
14089
14090 {
14091 if (typeof newChild === 'function') {
14092 warnOnFunctionType();
14093 }
14094 }
14095
14096 return null;
14097 }
14098
14099 function updateFromMap(existingChildren, returnFiber, newIdx, newChild, expirationTime) {
14100 if (typeof newChild === 'string' || typeof newChild === 'number') {
14101 // Text nodes don't have keys, so we neither have to check the old nor
14102 // new node for the key. If both are text nodes, they match.
14103 var matchedFiber = existingChildren.get(newIdx) || null;
14104 return updateTextNode(returnFiber, matchedFiber, '' + newChild, expirationTime);
14105 }
14106
14107 if (typeof newChild === 'object' && newChild !== null) {
14108 switch (newChild.$$typeof) {
14109 case REACT_ELEMENT_TYPE:
14110 {
14111 var _matchedFiber = existingChildren.get(newChild.key === null ? newIdx : newChild.key) || null;
14112 if (newChild.type === REACT_FRAGMENT_TYPE) {
14113 return updateFragment(returnFiber, _matchedFiber, newChild.props.children, expirationTime, newChild.key);
14114 }
14115 return updateElement(returnFiber, _matchedFiber, newChild, expirationTime);
14116 }
14117 case REACT_PORTAL_TYPE:
14118 {
14119 var _matchedFiber2 = existingChildren.get(newChild.key === null ? newIdx : newChild.key) || null;
14120 return updatePortal(returnFiber, _matchedFiber2, newChild, expirationTime);
14121 }
14122 }
14123
14124 if (isArray(newChild) || getIteratorFn(newChild)) {
14125 var _matchedFiber3 = existingChildren.get(newIdx) || null;
14126 return updateFragment(returnFiber, _matchedFiber3, newChild, expirationTime, null);
14127 }
14128
14129 throwOnInvalidObjectType(returnFiber, newChild);
14130 }
14131
14132 {
14133 if (typeof newChild === 'function') {
14134 warnOnFunctionType();
14135 }
14136 }
14137
14138 return null;
14139 }
14140
14141 /**
14142 * Warns if there is a duplicate or missing key
14143 */
14144 function warnOnInvalidKey(child, knownKeys) {
14145 {
14146 if (typeof child !== 'object' || child === null) {
14147 return knownKeys;
14148 }
14149 switch (child.$$typeof) {
14150 case REACT_ELEMENT_TYPE:
14151 case REACT_PORTAL_TYPE:
14152 warnForMissingKey(child);
14153 var key = child.key;
14154 if (typeof key !== 'string') {
14155 break;
14156 }
14157 if (knownKeys === null) {
14158 knownKeys = new Set();
14159 knownKeys.add(key);
14160 break;
14161 }
14162 if (!knownKeys.has(key)) {
14163 knownKeys.add(key);
14164 break;
14165 }
14166 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);
14167 break;
14168 default:
14169 break;
14170 }
14171 }
14172 return knownKeys;
14173 }
14174
14175 function reconcileChildrenArray(returnFiber, currentFirstChild, newChildren, expirationTime) {
14176 // This algorithm can't optimize by searching from both ends since we
14177 // don't have backpointers on fibers. I'm trying to see how far we can get
14178 // with that model. If it ends up not being worth the tradeoffs, we can
14179 // add it later.
14180
14181 // Even with a two ended optimization, we'd want to optimize for the case
14182 // where there are few changes and brute force the comparison instead of
14183 // going for the Map. It'd like to explore hitting that path first in
14184 // forward-only mode and only go for the Map once we notice that we need
14185 // lots of look ahead. This doesn't handle reversal as well as two ended
14186 // search but that's unusual. Besides, for the two ended optimization to
14187 // work on Iterables, we'd need to copy the whole set.
14188
14189 // In this first iteration, we'll just live with hitting the bad case
14190 // (adding everything to a Map) in for every insert/move.
14191
14192 // If you change this code, also update reconcileChildrenIterator() which
14193 // uses the same algorithm.
14194
14195 {
14196 // First, validate keys.
14197 var knownKeys = null;
14198 for (var i = 0; i < newChildren.length; i++) {
14199 var child = newChildren[i];
14200 knownKeys = warnOnInvalidKey(child, knownKeys);
14201 }
14202 }
14203
14204 var resultingFirstChild = null;
14205 var previousNewFiber = null;
14206
14207 var oldFiber = currentFirstChild;
14208 var lastPlacedIndex = 0;
14209 var newIdx = 0;
14210 var nextOldFiber = null;
14211 for (; oldFiber !== null && newIdx < newChildren.length; newIdx++) {
14212 if (oldFiber.index > newIdx) {
14213 nextOldFiber = oldFiber;
14214 oldFiber = null;
14215 } else {
14216 nextOldFiber = oldFiber.sibling;
14217 }
14218 var newFiber = updateSlot(returnFiber, oldFiber, newChildren[newIdx], expirationTime);
14219 if (newFiber === null) {
14220 // TODO: This breaks on empty slots like null children. That's
14221 // unfortunate because it triggers the slow path all the time. We need
14222 // a better way to communicate whether this was a miss or null,
14223 // boolean, undefined, etc.
14224 if (oldFiber === null) {
14225 oldFiber = nextOldFiber;
14226 }
14227 break;
14228 }
14229 if (shouldTrackSideEffects) {
14230 if (oldFiber && newFiber.alternate === null) {
14231 // We matched the slot, but we didn't reuse the existing fiber, so we
14232 // need to delete the existing child.
14233 deleteChild(returnFiber, oldFiber);
14234 }
14235 }
14236 lastPlacedIndex = placeChild(newFiber, lastPlacedIndex, newIdx);
14237 if (previousNewFiber === null) {
14238 // TODO: Move out of the loop. This only happens for the first run.
14239 resultingFirstChild = newFiber;
14240 } else {
14241 // TODO: Defer siblings if we're not at the right index for this slot.
14242 // I.e. if we had null values before, then we want to defer this
14243 // for each null value. However, we also don't want to call updateSlot
14244 // with the previous one.
14245 previousNewFiber.sibling = newFiber;
14246 }
14247 previousNewFiber = newFiber;
14248 oldFiber = nextOldFiber;
14249 }
14250
14251 if (newIdx === newChildren.length) {
14252 // We've reached the end of the new children. We can delete the rest.
14253 deleteRemainingChildren(returnFiber, oldFiber);
14254 return resultingFirstChild;
14255 }
14256
14257 if (oldFiber === null) {
14258 // If we don't have any more existing children we can choose a fast path
14259 // since the rest will all be insertions.
14260 for (; newIdx < newChildren.length; newIdx++) {
14261 var _newFiber = createChild(returnFiber, newChildren[newIdx], expirationTime);
14262 if (_newFiber === null) {
14263 continue;
14264 }
14265 lastPlacedIndex = placeChild(_newFiber, lastPlacedIndex, newIdx);
14266 if (previousNewFiber === null) {
14267 // TODO: Move out of the loop. This only happens for the first run.
14268 resultingFirstChild = _newFiber;
14269 } else {
14270 previousNewFiber.sibling = _newFiber;
14271 }
14272 previousNewFiber = _newFiber;
14273 }
14274 return resultingFirstChild;
14275 }
14276
14277 // Add all children to a key map for quick lookups.
14278 var existingChildren = mapRemainingChildren(returnFiber, oldFiber);
14279
14280 // Keep scanning and use the map to restore deleted items as moves.
14281 for (; newIdx < newChildren.length; newIdx++) {
14282 var _newFiber2 = updateFromMap(existingChildren, returnFiber, newIdx, newChildren[newIdx], expirationTime);
14283 if (_newFiber2 !== null) {
14284 if (shouldTrackSideEffects) {
14285 if (_newFiber2.alternate !== null) {
14286 // The new fiber is a work in progress, but if there exists a
14287 // current, that means that we reused the fiber. We need to delete
14288 // it from the child list so that we don't add it to the deletion
14289 // list.
14290 existingChildren.delete(_newFiber2.key === null ? newIdx : _newFiber2.key);
14291 }
14292 }
14293 lastPlacedIndex = placeChild(_newFiber2, lastPlacedIndex, newIdx);
14294 if (previousNewFiber === null) {
14295 resultingFirstChild = _newFiber2;
14296 } else {
14297 previousNewFiber.sibling = _newFiber2;
14298 }
14299 previousNewFiber = _newFiber2;
14300 }
14301 }
14302
14303 if (shouldTrackSideEffects) {
14304 // Any existing children that weren't consumed above were deleted. We need
14305 // to add them to the deletion list.
14306 existingChildren.forEach(function (child) {
14307 return deleteChild(returnFiber, child);
14308 });
14309 }
14310
14311 return resultingFirstChild;
14312 }
14313
14314 function reconcileChildrenIterator(returnFiber, currentFirstChild, newChildrenIterable, expirationTime) {
14315 // This is the same implementation as reconcileChildrenArray(),
14316 // but using the iterator instead.
14317
14318 var iteratorFn = getIteratorFn(newChildrenIterable);
14319 (function () {
14320 if (!(typeof iteratorFn === 'function')) {
14321 {
14322 throw ReactError(Error('An object is not an iterable. This error is likely caused by a bug in React. Please file an issue.'));
14323 }
14324 }
14325 })();
14326
14327 {
14328 // We don't support rendering Generators because it's a mutation.
14329 // See https://github.com/facebook/react/issues/12995
14330 if (typeof Symbol === 'function' &&
14331 // $FlowFixMe Flow doesn't know about toStringTag
14332 newChildrenIterable[Symbol.toStringTag] === 'Generator') {
14333 !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;
14334 didWarnAboutGenerators = true;
14335 }
14336
14337 // Warn about using Maps as children
14338 if (newChildrenIterable.entries === iteratorFn) {
14339 !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;
14340 didWarnAboutMaps = true;
14341 }
14342
14343 // First, validate keys.
14344 // We'll get a different iterator later for the main pass.
14345 var _newChildren = iteratorFn.call(newChildrenIterable);
14346 if (_newChildren) {
14347 var knownKeys = null;
14348 var _step = _newChildren.next();
14349 for (; !_step.done; _step = _newChildren.next()) {
14350 var child = _step.value;
14351 knownKeys = warnOnInvalidKey(child, knownKeys);
14352 }
14353 }
14354 }
14355
14356 var newChildren = iteratorFn.call(newChildrenIterable);
14357 (function () {
14358 if (!(newChildren != null)) {
14359 {
14360 throw ReactError(Error('An iterable object provided no iterator.'));
14361 }
14362 }
14363 })();
14364
14365 var resultingFirstChild = null;
14366 var previousNewFiber = null;
14367
14368 var oldFiber = currentFirstChild;
14369 var lastPlacedIndex = 0;
14370 var newIdx = 0;
14371 var nextOldFiber = null;
14372
14373 var step = newChildren.next();
14374 for (; oldFiber !== null && !step.done; newIdx++, step = newChildren.next()) {
14375 if (oldFiber.index > newIdx) {
14376 nextOldFiber = oldFiber;
14377 oldFiber = null;
14378 } else {
14379 nextOldFiber = oldFiber.sibling;
14380 }
14381 var newFiber = updateSlot(returnFiber, oldFiber, step.value, expirationTime);
14382 if (newFiber === null) {
14383 // TODO: This breaks on empty slots like null children. That's
14384 // unfortunate because it triggers the slow path all the time. We need
14385 // a better way to communicate whether this was a miss or null,
14386 // boolean, undefined, etc.
14387 if (oldFiber === null) {
14388 oldFiber = nextOldFiber;
14389 }
14390 break;
14391 }
14392 if (shouldTrackSideEffects) {
14393 if (oldFiber && newFiber.alternate === null) {
14394 // We matched the slot, but we didn't reuse the existing fiber, so we
14395 // need to delete the existing child.
14396 deleteChild(returnFiber, oldFiber);
14397 }
14398 }
14399 lastPlacedIndex = placeChild(newFiber, lastPlacedIndex, newIdx);
14400 if (previousNewFiber === null) {
14401 // TODO: Move out of the loop. This only happens for the first run.
14402 resultingFirstChild = newFiber;
14403 } else {
14404 // TODO: Defer siblings if we're not at the right index for this slot.
14405 // I.e. if we had null values before, then we want to defer this
14406 // for each null value. However, we also don't want to call updateSlot
14407 // with the previous one.
14408 previousNewFiber.sibling = newFiber;
14409 }
14410 previousNewFiber = newFiber;
14411 oldFiber = nextOldFiber;
14412 }
14413
14414 if (step.done) {
14415 // We've reached the end of the new children. We can delete the rest.
14416 deleteRemainingChildren(returnFiber, oldFiber);
14417 return resultingFirstChild;
14418 }
14419
14420 if (oldFiber === null) {
14421 // If we don't have any more existing children we can choose a fast path
14422 // since the rest will all be insertions.
14423 for (; !step.done; newIdx++, step = newChildren.next()) {
14424 var _newFiber3 = createChild(returnFiber, step.value, expirationTime);
14425 if (_newFiber3 === null) {
14426 continue;
14427 }
14428 lastPlacedIndex = placeChild(_newFiber3, lastPlacedIndex, newIdx);
14429 if (previousNewFiber === null) {
14430 // TODO: Move out of the loop. This only happens for the first run.
14431 resultingFirstChild = _newFiber3;
14432 } else {
14433 previousNewFiber.sibling = _newFiber3;
14434 }
14435 previousNewFiber = _newFiber3;
14436 }
14437 return resultingFirstChild;
14438 }
14439
14440 // Add all children to a key map for quick lookups.
14441 var existingChildren = mapRemainingChildren(returnFiber, oldFiber);
14442
14443 // Keep scanning and use the map to restore deleted items as moves.
14444 for (; !step.done; newIdx++, step = newChildren.next()) {
14445 var _newFiber4 = updateFromMap(existingChildren, returnFiber, newIdx, step.value, expirationTime);
14446 if (_newFiber4 !== null) {
14447 if (shouldTrackSideEffects) {
14448 if (_newFiber4.alternate !== null) {
14449 // The new fiber is a work in progress, but if there exists a
14450 // current, that means that we reused the fiber. We need to delete
14451 // it from the child list so that we don't add it to the deletion
14452 // list.
14453 existingChildren.delete(_newFiber4.key === null ? newIdx : _newFiber4.key);
14454 }
14455 }
14456 lastPlacedIndex = placeChild(_newFiber4, lastPlacedIndex, newIdx);
14457 if (previousNewFiber === null) {
14458 resultingFirstChild = _newFiber4;
14459 } else {
14460 previousNewFiber.sibling = _newFiber4;
14461 }
14462 previousNewFiber = _newFiber4;
14463 }
14464 }
14465
14466 if (shouldTrackSideEffects) {
14467 // Any existing children that weren't consumed above were deleted. We need
14468 // to add them to the deletion list.
14469 existingChildren.forEach(function (child) {
14470 return deleteChild(returnFiber, child);
14471 });
14472 }
14473
14474 return resultingFirstChild;
14475 }
14476
14477 function reconcileSingleTextNode(returnFiber, currentFirstChild, textContent, expirationTime) {
14478 // There's no need to check for keys on text nodes since we don't have a
14479 // way to define them.
14480 if (currentFirstChild !== null && currentFirstChild.tag === HostText) {
14481 // We already have an existing node so let's just update it and delete
14482 // the rest.
14483 deleteRemainingChildren(returnFiber, currentFirstChild.sibling);
14484 var existing = useFiber(currentFirstChild, textContent, expirationTime);
14485 existing.return = returnFiber;
14486 return existing;
14487 }
14488 // The existing first child is not a text node so we need to create one
14489 // and delete the existing ones.
14490 deleteRemainingChildren(returnFiber, currentFirstChild);
14491 var created = createFiberFromText(textContent, returnFiber.mode, expirationTime);
14492 created.return = returnFiber;
14493 return created;
14494 }
14495
14496 function reconcileSingleElement(returnFiber, currentFirstChild, element, expirationTime) {
14497 var key = element.key;
14498 var child = currentFirstChild;
14499 while (child !== null) {
14500 // TODO: If key === null and child.key === null, then this only applies to
14501 // the first item in the list.
14502 if (child.key === key) {
14503 if (child.tag === Fragment ? element.type === REACT_FRAGMENT_TYPE : child.elementType === element.type || (
14504 // Keep this check inline so it only runs on the false path:
14505 isCompatibleFamilyForHotReloading(child, element))) {
14506 deleteRemainingChildren(returnFiber, child.sibling);
14507 var existing = useFiber(child, element.type === REACT_FRAGMENT_TYPE ? element.props.children : element.props, expirationTime);
14508 existing.ref = coerceRef(returnFiber, child, element);
14509 existing.return = returnFiber;
14510 {
14511 existing._debugSource = element._source;
14512 existing._debugOwner = element._owner;
14513 }
14514 return existing;
14515 } else {
14516 deleteRemainingChildren(returnFiber, child);
14517 break;
14518 }
14519 } else {
14520 deleteChild(returnFiber, child);
14521 }
14522 child = child.sibling;
14523 }
14524
14525 if (element.type === REACT_FRAGMENT_TYPE) {
14526 var created = createFiberFromFragment(element.props.children, returnFiber.mode, expirationTime, element.key);
14527 created.return = returnFiber;
14528 return created;
14529 } else {
14530 var _created4 = createFiberFromElement(element, returnFiber.mode, expirationTime);
14531 _created4.ref = coerceRef(returnFiber, currentFirstChild, element);
14532 _created4.return = returnFiber;
14533 return _created4;
14534 }
14535 }
14536
14537 function reconcileSinglePortal(returnFiber, currentFirstChild, portal, expirationTime) {
14538 var key = portal.key;
14539 var child = currentFirstChild;
14540 while (child !== null) {
14541 // TODO: If key === null and child.key === null, then this only applies to
14542 // the first item in the list.
14543 if (child.key === key) {
14544 if (child.tag === HostPortal && child.stateNode.containerInfo === portal.containerInfo && child.stateNode.implementation === portal.implementation) {
14545 deleteRemainingChildren(returnFiber, child.sibling);
14546 var existing = useFiber(child, portal.children || [], expirationTime);
14547 existing.return = returnFiber;
14548 return existing;
14549 } else {
14550 deleteRemainingChildren(returnFiber, child);
14551 break;
14552 }
14553 } else {
14554 deleteChild(returnFiber, child);
14555 }
14556 child = child.sibling;
14557 }
14558
14559 var created = createFiberFromPortal(portal, returnFiber.mode, expirationTime);
14560 created.return = returnFiber;
14561 return created;
14562 }
14563
14564 // This API will tag the children with the side-effect of the reconciliation
14565 // itself. They will be added to the side-effect list as we pass through the
14566 // children and the parent.
14567 function reconcileChildFibers(returnFiber, currentFirstChild, newChild, expirationTime) {
14568 // This function is not recursive.
14569 // If the top level item is an array, we treat it as a set of children,
14570 // not as a fragment. Nested arrays on the other hand will be treated as
14571 // fragment nodes. Recursion happens at the normal flow.
14572
14573 // Handle top level unkeyed fragments as if they were arrays.
14574 // This leads to an ambiguity between <>{[...]}</> and <>...</>.
14575 // We treat the ambiguous cases above the same.
14576 var isUnkeyedTopLevelFragment = typeof newChild === 'object' && newChild !== null && newChild.type === REACT_FRAGMENT_TYPE && newChild.key === null;
14577 if (isUnkeyedTopLevelFragment) {
14578 newChild = newChild.props.children;
14579 }
14580
14581 // Handle object types
14582 var isObject = typeof newChild === 'object' && newChild !== null;
14583
14584 if (isObject) {
14585 switch (newChild.$$typeof) {
14586 case REACT_ELEMENT_TYPE:
14587 return placeSingleChild(reconcileSingleElement(returnFiber, currentFirstChild, newChild, expirationTime));
14588 case REACT_PORTAL_TYPE:
14589 return placeSingleChild(reconcileSinglePortal(returnFiber, currentFirstChild, newChild, expirationTime));
14590 }
14591 }
14592
14593 if (typeof newChild === 'string' || typeof newChild === 'number') {
14594 return placeSingleChild(reconcileSingleTextNode(returnFiber, currentFirstChild, '' + newChild, expirationTime));
14595 }
14596
14597 if (isArray(newChild)) {
14598 return reconcileChildrenArray(returnFiber, currentFirstChild, newChild, expirationTime);
14599 }
14600
14601 if (getIteratorFn(newChild)) {
14602 return reconcileChildrenIterator(returnFiber, currentFirstChild, newChild, expirationTime);
14603 }
14604
14605 if (isObject) {
14606 throwOnInvalidObjectType(returnFiber, newChild);
14607 }
14608
14609 {
14610 if (typeof newChild === 'function') {
14611 warnOnFunctionType();
14612 }
14613 }
14614 if (typeof newChild === 'undefined' && !isUnkeyedTopLevelFragment) {
14615 // If the new child is undefined, and the return fiber is a composite
14616 // component, throw an error. If Fiber return types are disabled,
14617 // we already threw above.
14618 switch (returnFiber.tag) {
14619 case ClassComponent:
14620 {
14621 {
14622 var instance = returnFiber.stateNode;
14623 if (instance.render._isMockFunction) {
14624 // We allow auto-mocks to proceed as if they're returning null.
14625 break;
14626 }
14627 }
14628 }
14629 // Intentionally fall through to the next case, which handles both
14630 // functions and classes
14631 // eslint-disable-next-lined no-fallthrough
14632 case FunctionComponent:
14633 {
14634 var Component = returnFiber.type;
14635 (function () {
14636 {
14637 {
14638 throw ReactError(Error((Component.displayName || Component.name || 'Component') + '(...): Nothing was returned from render. This usually means a return statement is missing. Or, to render nothing, return null.'));
14639 }
14640 }
14641 })();
14642 }
14643 }
14644 }
14645
14646 // Remaining cases are all treated as empty.
14647 return deleteRemainingChildren(returnFiber, currentFirstChild);
14648 }
14649
14650 return reconcileChildFibers;
14651}
14652
14653var reconcileChildFibers = ChildReconciler(true);
14654var mountChildFibers = ChildReconciler(false);
14655
14656function cloneChildFibers(current$$1, workInProgress) {
14657 (function () {
14658 if (!(current$$1 === null || workInProgress.child === current$$1.child)) {
14659 {
14660 throw ReactError(Error('Resuming work not yet implemented.'));
14661 }
14662 }
14663 })();
14664
14665 if (workInProgress.child === null) {
14666 return;
14667 }
14668
14669 var currentChild = workInProgress.child;
14670 var newChild = createWorkInProgress(currentChild, currentChild.pendingProps, currentChild.expirationTime);
14671 workInProgress.child = newChild;
14672
14673 newChild.return = workInProgress;
14674 while (currentChild.sibling !== null) {
14675 currentChild = currentChild.sibling;
14676 newChild = newChild.sibling = createWorkInProgress(currentChild, currentChild.pendingProps, currentChild.expirationTime);
14677 newChild.return = workInProgress;
14678 }
14679 newChild.sibling = null;
14680}
14681
14682// Reset a workInProgress child set to prepare it for a second pass.
14683function resetChildFibers(workInProgress, renderExpirationTime) {
14684 var child = workInProgress.child;
14685 while (child !== null) {
14686 resetWorkInProgress(child, renderExpirationTime);
14687 child = child.sibling;
14688 }
14689}
14690
14691var NO_CONTEXT = {};
14692
14693var contextStackCursor$1 = createCursor(NO_CONTEXT);
14694var contextFiberStackCursor = createCursor(NO_CONTEXT);
14695var rootInstanceStackCursor = createCursor(NO_CONTEXT);
14696
14697function requiredContext(c) {
14698 (function () {
14699 if (!(c !== NO_CONTEXT)) {
14700 {
14701 throw ReactError(Error('Expected host context to exist. This error is likely caused by a bug in React. Please file an issue.'));
14702 }
14703 }
14704 })();
14705 return c;
14706}
14707
14708function getRootHostContainer() {
14709 var rootInstance = requiredContext(rootInstanceStackCursor.current);
14710 return rootInstance;
14711}
14712
14713function pushHostContainer(fiber, nextRootInstance) {
14714 // Push current root instance onto the stack;
14715 // This allows us to reset root when portals are popped.
14716 push(rootInstanceStackCursor, nextRootInstance, fiber);
14717 // Track the context and the Fiber that provided it.
14718 // This enables us to pop only Fibers that provide unique contexts.
14719 push(contextFiberStackCursor, fiber, fiber);
14720
14721 // Finally, we need to push the host context to the stack.
14722 // However, we can't just call getRootHostContext() and push it because
14723 // we'd have a different number of entries on the stack depending on
14724 // whether getRootHostContext() throws somewhere in renderer code or not.
14725 // So we push an empty value first. This lets us safely unwind on errors.
14726 push(contextStackCursor$1, NO_CONTEXT, fiber);
14727 var nextRootContext = getRootHostContext(nextRootInstance);
14728 // Now that we know this function doesn't throw, replace it.
14729 pop(contextStackCursor$1, fiber);
14730 push(contextStackCursor$1, nextRootContext, fiber);
14731}
14732
14733function popHostContainer(fiber) {
14734 pop(contextStackCursor$1, fiber);
14735 pop(contextFiberStackCursor, fiber);
14736 pop(rootInstanceStackCursor, fiber);
14737}
14738
14739function getHostContext() {
14740 var context = requiredContext(contextStackCursor$1.current);
14741 return context;
14742}
14743
14744function pushHostContext(fiber) {
14745 var rootInstance = requiredContext(rootInstanceStackCursor.current);
14746 var context = requiredContext(contextStackCursor$1.current);
14747 var nextContext = getChildHostContext(context, fiber.type, rootInstance);
14748
14749 // Don't push this Fiber's context unless it's unique.
14750 if (context === nextContext) {
14751 return;
14752 }
14753
14754 // Track the context and the Fiber that provided it.
14755 // This enables us to pop only Fibers that provide unique contexts.
14756 push(contextFiberStackCursor, fiber, fiber);
14757 push(contextStackCursor$1, nextContext, fiber);
14758}
14759
14760function popHostContext(fiber) {
14761 // Do not pop unless this Fiber provided the current context.
14762 // pushHostContext() only pushes Fibers that provide unique contexts.
14763 if (contextFiberStackCursor.current !== fiber) {
14764 return;
14765 }
14766
14767 pop(contextStackCursor$1, fiber);
14768 pop(contextFiberStackCursor, fiber);
14769}
14770
14771var DefaultSuspenseContext = 0;
14772
14773// The Suspense Context is split into two parts. The lower bits is
14774// inherited deeply down the subtree. The upper bits only affect
14775// this immediate suspense boundary and gets reset each new
14776// boundary or suspense list.
14777var SubtreeSuspenseContextMask = 1;
14778
14779// Subtree Flags:
14780
14781// InvisibleParentSuspenseContext indicates that one of our parent Suspense
14782// boundaries is not currently showing visible main content.
14783// Either because it is already showing a fallback or is not mounted at all.
14784// We can use this to determine if it is desirable to trigger a fallback at
14785// the parent. If not, then we might need to trigger undesirable boundaries
14786// and/or suspend the commit to avoid hiding the parent content.
14787var InvisibleParentSuspenseContext = 1;
14788
14789// Shallow Flags:
14790
14791// ForceSuspenseFallback can be used by SuspenseList to force newly added
14792// items into their fallback state during one of the render passes.
14793var ForceSuspenseFallback = 2;
14794
14795var suspenseStackCursor = createCursor(DefaultSuspenseContext);
14796
14797function hasSuspenseContext(parentContext, flag) {
14798 return (parentContext & flag) !== 0;
14799}
14800
14801function setDefaultShallowSuspenseContext(parentContext) {
14802 return parentContext & SubtreeSuspenseContextMask;
14803}
14804
14805function setShallowSuspenseContext(parentContext, shallowContext) {
14806 return parentContext & SubtreeSuspenseContextMask | shallowContext;
14807}
14808
14809function addSubtreeSuspenseContext(parentContext, subtreeContext) {
14810 return parentContext | subtreeContext;
14811}
14812
14813function pushSuspenseContext(fiber, newContext) {
14814 push(suspenseStackCursor, newContext, fiber);
14815}
14816
14817function popSuspenseContext(fiber) {
14818 pop(suspenseStackCursor, fiber);
14819}
14820
14821// TODO: This is now an empty object. Should we switch this to a boolean?
14822// Alternatively we can make this use an effect tag similar to SuspenseList.
14823
14824
14825function shouldCaptureSuspense(workInProgress, hasInvisibleParent) {
14826 // If it was the primary children that just suspended, capture and render the
14827 var nextState = workInProgress.memoizedState;
14828 if (nextState !== null) {
14829 return false;
14830 }
14831 var props = workInProgress.memoizedProps;
14832 // In order to capture, the Suspense component must have a fallback prop.
14833 if (props.fallback === undefined) {
14834 return false;
14835 }
14836 // Regular boundaries always capture.
14837 if (props.unstable_avoidThisFallback !== true) {
14838 return true;
14839 }
14840 // If it's a boundary we should avoid, then we prefer to bubble up to the
14841 // parent boundary if it is currently invisible.
14842 if (hasInvisibleParent) {
14843 return false;
14844 }
14845 // If the parent is not able to handle it, we must handle it.
14846 return true;
14847}
14848
14849function findFirstSuspended(row) {
14850 var node = row;
14851 while (node !== null) {
14852 if (node.tag === SuspenseComponent) {
14853 var state = node.memoizedState;
14854 if (state !== null) {
14855 return node;
14856 }
14857 } else if (node.tag === SuspenseListComponent &&
14858 // revealOrder undefined can't be trusted because it don't
14859 // keep track of whether it suspended or not.
14860 node.memoizedProps.revealOrder !== undefined) {
14861 var didSuspend = (node.effectTag & DidCapture) !== NoEffect;
14862 if (didSuspend) {
14863 return node;
14864 }
14865 } else if (node.child !== null) {
14866 node.child.return = node;
14867 node = node.child;
14868 continue;
14869 }
14870 if (node === row) {
14871 return null;
14872 }
14873 while (node.sibling === null) {
14874 if (node.return === null || node.return === row) {
14875 return null;
14876 }
14877 node = node.return;
14878 }
14879 node.sibling.return = node.return;
14880 node = node.sibling;
14881 }
14882 return null;
14883}
14884
14885var NoEffect$1 = /* */0;
14886var UnmountSnapshot = /* */2;
14887var UnmountMutation = /* */4;
14888var MountMutation = /* */8;
14889var UnmountLayout = /* */16;
14890var MountLayout = /* */32;
14891var MountPassive = /* */64;
14892var UnmountPassive = /* */128;
14893
14894var ReactCurrentDispatcher$1 = ReactSharedInternals.ReactCurrentDispatcher;
14895
14896
14897var didWarnAboutMismatchedHooksForComponent = void 0;
14898{
14899 didWarnAboutMismatchedHooksForComponent = new Set();
14900}
14901
14902// These are set right before calling the component.
14903var renderExpirationTime$1 = NoWork;
14904// The work-in-progress fiber. I've named it differently to distinguish it from
14905// the work-in-progress hook.
14906var currentlyRenderingFiber$1 = null;
14907
14908// Hooks are stored as a linked list on the fiber's memoizedState field. The
14909// current hook list is the list that belongs to the current fiber. The
14910// work-in-progress hook list is a new list that will be added to the
14911// work-in-progress fiber.
14912var currentHook = null;
14913var nextCurrentHook = null;
14914var firstWorkInProgressHook = null;
14915var workInProgressHook = null;
14916var nextWorkInProgressHook = null;
14917
14918var remainingExpirationTime = NoWork;
14919var componentUpdateQueue = null;
14920var sideEffectTag = 0;
14921
14922// Updates scheduled during render will trigger an immediate re-render at the
14923// end of the current pass. We can't store these updates on the normal queue,
14924// because if the work is aborted, they should be discarded. Because this is
14925// a relatively rare case, we also don't want to add an additional field to
14926// either the hook or queue object types. So we store them in a lazily create
14927// map of queue -> render-phase updates, which are discarded once the component
14928// completes without re-rendering.
14929
14930// Whether an update was scheduled during the currently executing render pass.
14931var didScheduleRenderPhaseUpdate = false;
14932// Lazily created map of render-phase updates
14933var renderPhaseUpdates = null;
14934// Counter to prevent infinite loops.
14935var numberOfReRenders = 0;
14936var RE_RENDER_LIMIT = 25;
14937
14938// In DEV, this is the name of the currently executing primitive hook
14939var currentHookNameInDev = null;
14940
14941// In DEV, this list ensures that hooks are called in the same order between renders.
14942// The list stores the order of hooks used during the initial render (mount).
14943// Subsequent renders (updates) reference this list.
14944var hookTypesDev = null;
14945var hookTypesUpdateIndexDev = -1;
14946
14947// In DEV, this tracks whether currently rendering component needs to ignore
14948// the dependencies for Hooks that need them (e.g. useEffect or useMemo).
14949// When true, such Hooks will always be "remounted". Only used during hot reload.
14950var ignorePreviousDependencies = false;
14951
14952function mountHookTypesDev() {
14953 {
14954 var hookName = currentHookNameInDev;
14955
14956 if (hookTypesDev === null) {
14957 hookTypesDev = [hookName];
14958 } else {
14959 hookTypesDev.push(hookName);
14960 }
14961 }
14962}
14963
14964function updateHookTypesDev() {
14965 {
14966 var hookName = currentHookNameInDev;
14967
14968 if (hookTypesDev !== null) {
14969 hookTypesUpdateIndexDev++;
14970 if (hookTypesDev[hookTypesUpdateIndexDev] !== hookName) {
14971 warnOnHookMismatchInDev(hookName);
14972 }
14973 }
14974 }
14975}
14976
14977function checkDepsAreArrayDev(deps) {
14978 {
14979 if (deps !== undefined && deps !== null && !Array.isArray(deps)) {
14980 // Verify deps, but only on mount to avoid extra checks.
14981 // It's unlikely their type would change as usually you define them inline.
14982 warning$1(false, '%s received a final argument that is not an array (instead, received `%s`). When ' + 'specified, the final argument must be an array.', currentHookNameInDev, typeof deps);
14983 }
14984 }
14985}
14986
14987function warnOnHookMismatchInDev(currentHookName) {
14988 {
14989 var componentName = getComponentName(currentlyRenderingFiber$1.type);
14990 if (!didWarnAboutMismatchedHooksForComponent.has(componentName)) {
14991 didWarnAboutMismatchedHooksForComponent.add(componentName);
14992
14993 if (hookTypesDev !== null) {
14994 var table = '';
14995
14996 var secondColumnStart = 30;
14997
14998 for (var i = 0; i <= hookTypesUpdateIndexDev; i++) {
14999 var oldHookName = hookTypesDev[i];
15000 var newHookName = i === hookTypesUpdateIndexDev ? currentHookName : oldHookName;
15001
15002 var row = i + 1 + '. ' + oldHookName;
15003
15004 // Extra space so second column lines up
15005 // lol @ IE not supporting String#repeat
15006 while (row.length < secondColumnStart) {
15007 row += ' ';
15008 }
15009
15010 row += newHookName + '\n';
15011
15012 table += row;
15013 }
15014
15015 warning$1(false, 'React has detected a change in the order of Hooks called by %s. ' + 'This will lead to bugs and errors if not fixed. ' + 'For more information, read the Rules of Hooks: https://fb.me/rules-of-hooks\n\n' + ' Previous render Next render\n' + ' ------------------------------------------------------\n' + '%s' + ' ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n', componentName, table);
15016 }
15017 }
15018 }
15019}
15020
15021function throwInvalidHookError() {
15022 (function () {
15023 {
15024 {
15025 throw ReactError(Error('Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:\n1. You might have mismatching versions of React and the renderer (such as React DOM)\n2. You might be breaking the Rules of Hooks\n3. You might have more than one copy of React in the same app\nSee https://fb.me/react-invalid-hook-call for tips about how to debug and fix this problem.'));
15026 }
15027 }
15028 })();
15029}
15030
15031function areHookInputsEqual(nextDeps, prevDeps) {
15032 {
15033 if (ignorePreviousDependencies) {
15034 // Only true when this component is being hot reloaded.
15035 return false;
15036 }
15037 }
15038
15039 if (prevDeps === null) {
15040 {
15041 warning$1(false, '%s received a final argument during this render, but not during ' + 'the previous render. Even though the final argument is optional, ' + 'its type cannot change between renders.', currentHookNameInDev);
15042 }
15043 return false;
15044 }
15045
15046 {
15047 // Don't bother comparing lengths in prod because these arrays should be
15048 // passed inline.
15049 if (nextDeps.length !== prevDeps.length) {
15050 warning$1(false, 'The final argument passed to %s changed size between renders. The ' + 'order and size of this array must remain constant.\n\n' + 'Previous: %s\n' + 'Incoming: %s', currentHookNameInDev, '[' + prevDeps.join(', ') + ']', '[' + nextDeps.join(', ') + ']');
15051 }
15052 }
15053 for (var i = 0; i < prevDeps.length && i < nextDeps.length; i++) {
15054 if (is(nextDeps[i], prevDeps[i])) {
15055 continue;
15056 }
15057 return false;
15058 }
15059 return true;
15060}
15061
15062function renderWithHooks(current, workInProgress, Component, props, refOrContext, nextRenderExpirationTime) {
15063 renderExpirationTime$1 = nextRenderExpirationTime;
15064 currentlyRenderingFiber$1 = workInProgress;
15065 nextCurrentHook = current !== null ? current.memoizedState : null;
15066
15067 {
15068 hookTypesDev = current !== null ? current._debugHookTypes : null;
15069 hookTypesUpdateIndexDev = -1;
15070 // Used for hot reloading:
15071 ignorePreviousDependencies = current !== null && current.type !== workInProgress.type;
15072 }
15073
15074 // The following should have already been reset
15075 // currentHook = null;
15076 // workInProgressHook = null;
15077
15078 // remainingExpirationTime = NoWork;
15079 // componentUpdateQueue = null;
15080
15081 // didScheduleRenderPhaseUpdate = false;
15082 // renderPhaseUpdates = null;
15083 // numberOfReRenders = 0;
15084 // sideEffectTag = 0;
15085
15086 // TODO Warn if no hooks are used at all during mount, then some are used during update.
15087 // Currently we will identify the update render as a mount because nextCurrentHook === null.
15088 // This is tricky because it's valid for certain types of components (e.g. React.lazy)
15089
15090 // Using nextCurrentHook to differentiate between mount/update only works if at least one stateful hook is used.
15091 // Non-stateful hooks (e.g. context) don't get added to memoizedState,
15092 // so nextCurrentHook would be null during updates and mounts.
15093 {
15094 if (nextCurrentHook !== null) {
15095 ReactCurrentDispatcher$1.current = HooksDispatcherOnUpdateInDEV;
15096 } else if (hookTypesDev !== null) {
15097 // This dispatcher handles an edge case where a component is updating,
15098 // but no stateful hooks have been used.
15099 // We want to match the production code behavior (which will use HooksDispatcherOnMount),
15100 // but with the extra DEV validation to ensure hooks ordering hasn't changed.
15101 // This dispatcher does that.
15102 ReactCurrentDispatcher$1.current = HooksDispatcherOnMountWithHookTypesInDEV;
15103 } else {
15104 ReactCurrentDispatcher$1.current = HooksDispatcherOnMountInDEV;
15105 }
15106 }
15107
15108 var children = Component(props, refOrContext);
15109
15110 if (didScheduleRenderPhaseUpdate) {
15111 do {
15112 didScheduleRenderPhaseUpdate = false;
15113 numberOfReRenders += 1;
15114
15115 // Start over from the beginning of the list
15116 nextCurrentHook = current !== null ? current.memoizedState : null;
15117 nextWorkInProgressHook = firstWorkInProgressHook;
15118
15119 currentHook = null;
15120 workInProgressHook = null;
15121 componentUpdateQueue = null;
15122
15123 {
15124 // Also validate hook order for cascading updates.
15125 hookTypesUpdateIndexDev = -1;
15126 }
15127
15128 ReactCurrentDispatcher$1.current = HooksDispatcherOnUpdateInDEV;
15129
15130 children = Component(props, refOrContext);
15131 } while (didScheduleRenderPhaseUpdate);
15132
15133 renderPhaseUpdates = null;
15134 numberOfReRenders = 0;
15135 }
15136
15137 // We can assume the previous dispatcher is always this one, since we set it
15138 // at the beginning of the render phase and there's no re-entrancy.
15139 ReactCurrentDispatcher$1.current = ContextOnlyDispatcher;
15140
15141 var renderedWork = currentlyRenderingFiber$1;
15142
15143 renderedWork.memoizedState = firstWorkInProgressHook;
15144 renderedWork.expirationTime = remainingExpirationTime;
15145 renderedWork.updateQueue = componentUpdateQueue;
15146 renderedWork.effectTag |= sideEffectTag;
15147
15148 {
15149 renderedWork._debugHookTypes = hookTypesDev;
15150 }
15151
15152 // This check uses currentHook so that it works the same in DEV and prod bundles.
15153 // hookTypesDev could catch more cases (e.g. context) but only in DEV bundles.
15154 var didRenderTooFewHooks = currentHook !== null && currentHook.next !== null;
15155
15156 renderExpirationTime$1 = NoWork;
15157 currentlyRenderingFiber$1 = null;
15158
15159 currentHook = null;
15160 nextCurrentHook = null;
15161 firstWorkInProgressHook = null;
15162 workInProgressHook = null;
15163 nextWorkInProgressHook = null;
15164
15165 {
15166 currentHookNameInDev = null;
15167 hookTypesDev = null;
15168 hookTypesUpdateIndexDev = -1;
15169 }
15170
15171 remainingExpirationTime = NoWork;
15172 componentUpdateQueue = null;
15173 sideEffectTag = 0;
15174
15175 // These were reset above
15176 // didScheduleRenderPhaseUpdate = false;
15177 // renderPhaseUpdates = null;
15178 // numberOfReRenders = 0;
15179
15180 (function () {
15181 if (!!didRenderTooFewHooks) {
15182 {
15183 throw ReactError(Error('Rendered fewer hooks than expected. This may be caused by an accidental early return statement.'));
15184 }
15185 }
15186 })();
15187
15188 return children;
15189}
15190
15191function bailoutHooks(current, workInProgress, expirationTime) {
15192 workInProgress.updateQueue = current.updateQueue;
15193 workInProgress.effectTag &= ~(Passive | Update);
15194 if (current.expirationTime <= expirationTime) {
15195 current.expirationTime = NoWork;
15196 }
15197}
15198
15199function resetHooks() {
15200 // We can assume the previous dispatcher is always this one, since we set it
15201 // at the beginning of the render phase and there's no re-entrancy.
15202 ReactCurrentDispatcher$1.current = ContextOnlyDispatcher;
15203
15204 // This is used to reset the state of this module when a component throws.
15205 // It's also called inside mountIndeterminateComponent if we determine the
15206 // component is a module-style component.
15207 renderExpirationTime$1 = NoWork;
15208 currentlyRenderingFiber$1 = null;
15209
15210 currentHook = null;
15211 nextCurrentHook = null;
15212 firstWorkInProgressHook = null;
15213 workInProgressHook = null;
15214 nextWorkInProgressHook = null;
15215
15216 {
15217 hookTypesDev = null;
15218 hookTypesUpdateIndexDev = -1;
15219
15220 currentHookNameInDev = null;
15221 }
15222
15223 remainingExpirationTime = NoWork;
15224 componentUpdateQueue = null;
15225 sideEffectTag = 0;
15226
15227 didScheduleRenderPhaseUpdate = false;
15228 renderPhaseUpdates = null;
15229 numberOfReRenders = 0;
15230}
15231
15232function mountWorkInProgressHook() {
15233 var hook = {
15234 memoizedState: null,
15235
15236 baseState: null,
15237 queue: null,
15238 baseUpdate: null,
15239
15240 next: null
15241 };
15242
15243 if (workInProgressHook === null) {
15244 // This is the first hook in the list
15245 firstWorkInProgressHook = workInProgressHook = hook;
15246 } else {
15247 // Append to the end of the list
15248 workInProgressHook = workInProgressHook.next = hook;
15249 }
15250 return workInProgressHook;
15251}
15252
15253function updateWorkInProgressHook() {
15254 // This function is used both for updates and for re-renders triggered by a
15255 // render phase update. It assumes there is either a current hook we can
15256 // clone, or a work-in-progress hook from a previous render pass that we can
15257 // use as a base. When we reach the end of the base list, we must switch to
15258 // the dispatcher used for mounts.
15259 if (nextWorkInProgressHook !== null) {
15260 // There's already a work-in-progress. Reuse it.
15261 workInProgressHook = nextWorkInProgressHook;
15262 nextWorkInProgressHook = workInProgressHook.next;
15263
15264 currentHook = nextCurrentHook;
15265 nextCurrentHook = currentHook !== null ? currentHook.next : null;
15266 } else {
15267 // Clone from the current hook.
15268 (function () {
15269 if (!(nextCurrentHook !== null)) {
15270 {
15271 throw ReactError(Error('Rendered more hooks than during the previous render.'));
15272 }
15273 }
15274 })();
15275 currentHook = nextCurrentHook;
15276
15277 var newHook = {
15278 memoizedState: currentHook.memoizedState,
15279
15280 baseState: currentHook.baseState,
15281 queue: currentHook.queue,
15282 baseUpdate: currentHook.baseUpdate,
15283
15284 next: null
15285 };
15286
15287 if (workInProgressHook === null) {
15288 // This is the first hook in the list.
15289 workInProgressHook = firstWorkInProgressHook = newHook;
15290 } else {
15291 // Append to the end of the list.
15292 workInProgressHook = workInProgressHook.next = newHook;
15293 }
15294 nextCurrentHook = currentHook.next;
15295 }
15296 return workInProgressHook;
15297}
15298
15299function createFunctionComponentUpdateQueue() {
15300 return {
15301 lastEffect: null
15302 };
15303}
15304
15305function basicStateReducer(state, action) {
15306 return typeof action === 'function' ? action(state) : action;
15307}
15308
15309function mountReducer(reducer, initialArg, init) {
15310 var hook = mountWorkInProgressHook();
15311 var initialState = void 0;
15312 if (init !== undefined) {
15313 initialState = init(initialArg);
15314 } else {
15315 initialState = initialArg;
15316 }
15317 hook.memoizedState = hook.baseState = initialState;
15318 var queue = hook.queue = {
15319 last: null,
15320 dispatch: null,
15321 lastRenderedReducer: reducer,
15322 lastRenderedState: initialState
15323 };
15324 var dispatch = queue.dispatch = dispatchAction.bind(null,
15325 // Flow doesn't know this is non-null, but we do.
15326 currentlyRenderingFiber$1, queue);
15327 return [hook.memoizedState, dispatch];
15328}
15329
15330function updateReducer(reducer, initialArg, init) {
15331 var hook = updateWorkInProgressHook();
15332 var queue = hook.queue;
15333 (function () {
15334 if (!(queue !== null)) {
15335 {
15336 throw ReactError(Error('Should have a queue. This is likely a bug in React. Please file an issue.'));
15337 }
15338 }
15339 })();
15340
15341 queue.lastRenderedReducer = reducer;
15342
15343 if (numberOfReRenders > 0) {
15344 // This is a re-render. Apply the new render phase updates to the previous
15345 var _dispatch = queue.dispatch;
15346 if (renderPhaseUpdates !== null) {
15347 // Render phase updates are stored in a map of queue -> linked list
15348 var firstRenderPhaseUpdate = renderPhaseUpdates.get(queue);
15349 if (firstRenderPhaseUpdate !== undefined) {
15350 renderPhaseUpdates.delete(queue);
15351 var newState = hook.memoizedState;
15352 var update = firstRenderPhaseUpdate;
15353 do {
15354 // Process this render phase update. We don't have to check the
15355 // priority because it will always be the same as the current
15356 // render's.
15357 var _action = update.action;
15358 newState = reducer(newState, _action);
15359 update = update.next;
15360 } while (update !== null);
15361
15362 // Mark that the fiber performed work, but only if the new state is
15363 // different from the current state.
15364 if (!is(newState, hook.memoizedState)) {
15365 markWorkInProgressReceivedUpdate();
15366 }
15367
15368 hook.memoizedState = newState;
15369 // Don't persist the state accumulated from the render phase updates to
15370 // the base state unless the queue is empty.
15371 // TODO: Not sure if this is the desired semantics, but it's what we
15372 // do for gDSFP. I can't remember why.
15373 if (hook.baseUpdate === queue.last) {
15374 hook.baseState = newState;
15375 }
15376
15377 queue.lastRenderedState = newState;
15378
15379 return [newState, _dispatch];
15380 }
15381 }
15382 return [hook.memoizedState, _dispatch];
15383 }
15384
15385 // The last update in the entire queue
15386 var last = queue.last;
15387 // The last update that is part of the base state.
15388 var baseUpdate = hook.baseUpdate;
15389 var baseState = hook.baseState;
15390
15391 // Find the first unprocessed update.
15392 var first = void 0;
15393 if (baseUpdate !== null) {
15394 if (last !== null) {
15395 // For the first update, the queue is a circular linked list where
15396 // `queue.last.next = queue.first`. Once the first update commits, and
15397 // the `baseUpdate` is no longer empty, we can unravel the list.
15398 last.next = null;
15399 }
15400 first = baseUpdate.next;
15401 } else {
15402 first = last !== null ? last.next : null;
15403 }
15404 if (first !== null) {
15405 var _newState = baseState;
15406 var newBaseState = null;
15407 var newBaseUpdate = null;
15408 var prevUpdate = baseUpdate;
15409 var _update = first;
15410 var didSkip = false;
15411 do {
15412 var updateExpirationTime = _update.expirationTime;
15413 if (updateExpirationTime < renderExpirationTime$1) {
15414 // Priority is insufficient. Skip this update. If this is the first
15415 // skipped update, the previous update/state is the new base
15416 // update/state.
15417 if (!didSkip) {
15418 didSkip = true;
15419 newBaseUpdate = prevUpdate;
15420 newBaseState = _newState;
15421 }
15422 // Update the remaining priority in the queue.
15423 if (updateExpirationTime > remainingExpirationTime) {
15424 remainingExpirationTime = updateExpirationTime;
15425 }
15426 } else {
15427 // This update does have sufficient priority.
15428
15429 // Mark the event time of this update as relevant to this render pass.
15430 // TODO: This should ideally use the true event time of this update rather than
15431 // its priority which is a derived and not reverseable value.
15432 // TODO: We should skip this update if it was already committed but currently
15433 // we have no way of detecting the difference between a committed and suspended
15434 // update here.
15435 markRenderEventTimeAndConfig(updateExpirationTime, _update.suspenseConfig);
15436
15437 // Process this update.
15438 if (_update.eagerReducer === reducer) {
15439 // If this update was processed eagerly, and its reducer matches the
15440 // current reducer, we can use the eagerly computed state.
15441 _newState = _update.eagerState;
15442 } else {
15443 var _action2 = _update.action;
15444 _newState = reducer(_newState, _action2);
15445 }
15446 }
15447 prevUpdate = _update;
15448 _update = _update.next;
15449 } while (_update !== null && _update !== first);
15450
15451 if (!didSkip) {
15452 newBaseUpdate = prevUpdate;
15453 newBaseState = _newState;
15454 }
15455
15456 // Mark that the fiber performed work, but only if the new state is
15457 // different from the current state.
15458 if (!is(_newState, hook.memoizedState)) {
15459 markWorkInProgressReceivedUpdate();
15460 }
15461
15462 hook.memoizedState = _newState;
15463 hook.baseUpdate = newBaseUpdate;
15464 hook.baseState = newBaseState;
15465
15466 queue.lastRenderedState = _newState;
15467 }
15468
15469 var dispatch = queue.dispatch;
15470 return [hook.memoizedState, dispatch];
15471}
15472
15473function mountState(initialState) {
15474 var hook = mountWorkInProgressHook();
15475 if (typeof initialState === 'function') {
15476 initialState = initialState();
15477 }
15478 hook.memoizedState = hook.baseState = initialState;
15479 var queue = hook.queue = {
15480 last: null,
15481 dispatch: null,
15482 lastRenderedReducer: basicStateReducer,
15483 lastRenderedState: initialState
15484 };
15485 var dispatch = queue.dispatch = dispatchAction.bind(null,
15486 // Flow doesn't know this is non-null, but we do.
15487 currentlyRenderingFiber$1, queue);
15488 return [hook.memoizedState, dispatch];
15489}
15490
15491function updateState(initialState) {
15492 return updateReducer(basicStateReducer, initialState);
15493}
15494
15495function pushEffect(tag, create, destroy, deps) {
15496 var effect = {
15497 tag: tag,
15498 create: create,
15499 destroy: destroy,
15500 deps: deps,
15501 // Circular
15502 next: null
15503 };
15504 if (componentUpdateQueue === null) {
15505 componentUpdateQueue = createFunctionComponentUpdateQueue();
15506 componentUpdateQueue.lastEffect = effect.next = effect;
15507 } else {
15508 var _lastEffect = componentUpdateQueue.lastEffect;
15509 if (_lastEffect === null) {
15510 componentUpdateQueue.lastEffect = effect.next = effect;
15511 } else {
15512 var firstEffect = _lastEffect.next;
15513 _lastEffect.next = effect;
15514 effect.next = firstEffect;
15515 componentUpdateQueue.lastEffect = effect;
15516 }
15517 }
15518 return effect;
15519}
15520
15521function mountRef(initialValue) {
15522 var hook = mountWorkInProgressHook();
15523 var ref = { current: initialValue };
15524 {
15525 Object.seal(ref);
15526 }
15527 hook.memoizedState = ref;
15528 return ref;
15529}
15530
15531function updateRef(initialValue) {
15532 var hook = updateWorkInProgressHook();
15533 return hook.memoizedState;
15534}
15535
15536function mountEffectImpl(fiberEffectTag, hookEffectTag, create, deps) {
15537 var hook = mountWorkInProgressHook();
15538 var nextDeps = deps === undefined ? null : deps;
15539 sideEffectTag |= fiberEffectTag;
15540 hook.memoizedState = pushEffect(hookEffectTag, create, undefined, nextDeps);
15541}
15542
15543function updateEffectImpl(fiberEffectTag, hookEffectTag, create, deps) {
15544 var hook = updateWorkInProgressHook();
15545 var nextDeps = deps === undefined ? null : deps;
15546 var destroy = undefined;
15547
15548 if (currentHook !== null) {
15549 var prevEffect = currentHook.memoizedState;
15550 destroy = prevEffect.destroy;
15551 if (nextDeps !== null) {
15552 var prevDeps = prevEffect.deps;
15553 if (areHookInputsEqual(nextDeps, prevDeps)) {
15554 pushEffect(NoEffect$1, create, destroy, nextDeps);
15555 return;
15556 }
15557 }
15558 }
15559
15560 sideEffectTag |= fiberEffectTag;
15561 hook.memoizedState = pushEffect(hookEffectTag, create, destroy, nextDeps);
15562}
15563
15564function mountEffect(create, deps) {
15565 {
15566 // $FlowExpectedError - jest isn't a global, and isn't recognized outside of tests
15567 if ('undefined' !== typeof jest) {
15568 warnIfNotCurrentlyActingEffectsInDEV(currentlyRenderingFiber$1);
15569 }
15570 }
15571 return mountEffectImpl(Update | Passive, UnmountPassive | MountPassive, create, deps);
15572}
15573
15574function updateEffect(create, deps) {
15575 {
15576 // $FlowExpectedError - jest isn't a global, and isn't recognized outside of tests
15577 if ('undefined' !== typeof jest) {
15578 warnIfNotCurrentlyActingEffectsInDEV(currentlyRenderingFiber$1);
15579 }
15580 }
15581 return updateEffectImpl(Update | Passive, UnmountPassive | MountPassive, create, deps);
15582}
15583
15584function mountLayoutEffect(create, deps) {
15585 return mountEffectImpl(Update, UnmountMutation | MountLayout, create, deps);
15586}
15587
15588function updateLayoutEffect(create, deps) {
15589 return updateEffectImpl(Update, UnmountMutation | MountLayout, create, deps);
15590}
15591
15592function imperativeHandleEffect(create, ref) {
15593 if (typeof ref === 'function') {
15594 var refCallback = ref;
15595 var _inst = create();
15596 refCallback(_inst);
15597 return function () {
15598 refCallback(null);
15599 };
15600 } else if (ref !== null && ref !== undefined) {
15601 var refObject = ref;
15602 {
15603 !refObject.hasOwnProperty('current') ? warning$1(false, 'Expected useImperativeHandle() first argument to either be a ' + 'ref callback or React.createRef() object. Instead received: %s.', 'an object with keys {' + Object.keys(refObject).join(', ') + '}') : void 0;
15604 }
15605 var _inst2 = create();
15606 refObject.current = _inst2;
15607 return function () {
15608 refObject.current = null;
15609 };
15610 }
15611}
15612
15613function mountImperativeHandle(ref, create, deps) {
15614 {
15615 !(typeof create === 'function') ? warning$1(false, 'Expected useImperativeHandle() second argument to be a function ' + 'that creates a handle. Instead received: %s.', create !== null ? typeof create : 'null') : void 0;
15616 }
15617
15618 // TODO: If deps are provided, should we skip comparing the ref itself?
15619 var effectDeps = deps !== null && deps !== undefined ? deps.concat([ref]) : null;
15620
15621 return mountEffectImpl(Update, UnmountMutation | MountLayout, imperativeHandleEffect.bind(null, create, ref), effectDeps);
15622}
15623
15624function updateImperativeHandle(ref, create, deps) {
15625 {
15626 !(typeof create === 'function') ? warning$1(false, 'Expected useImperativeHandle() second argument to be a function ' + 'that creates a handle. Instead received: %s.', create !== null ? typeof create : 'null') : void 0;
15627 }
15628
15629 // TODO: If deps are provided, should we skip comparing the ref itself?
15630 var effectDeps = deps !== null && deps !== undefined ? deps.concat([ref]) : null;
15631
15632 return updateEffectImpl(Update, UnmountMutation | MountLayout, imperativeHandleEffect.bind(null, create, ref), effectDeps);
15633}
15634
15635function mountDebugValue(value, formatterFn) {
15636 // This hook is normally a no-op.
15637 // The react-debug-hooks package injects its own implementation
15638 // so that e.g. DevTools can display custom hook values.
15639}
15640
15641var updateDebugValue = mountDebugValue;
15642
15643function mountCallback(callback, deps) {
15644 var hook = mountWorkInProgressHook();
15645 var nextDeps = deps === undefined ? null : deps;
15646 hook.memoizedState = [callback, nextDeps];
15647 return callback;
15648}
15649
15650function updateCallback(callback, deps) {
15651 var hook = updateWorkInProgressHook();
15652 var nextDeps = deps === undefined ? null : deps;
15653 var prevState = hook.memoizedState;
15654 if (prevState !== null) {
15655 if (nextDeps !== null) {
15656 var prevDeps = prevState[1];
15657 if (areHookInputsEqual(nextDeps, prevDeps)) {
15658 return prevState[0];
15659 }
15660 }
15661 }
15662 hook.memoizedState = [callback, nextDeps];
15663 return callback;
15664}
15665
15666function mountMemo(nextCreate, deps) {
15667 var hook = mountWorkInProgressHook();
15668 var nextDeps = deps === undefined ? null : deps;
15669 var nextValue = nextCreate();
15670 hook.memoizedState = [nextValue, nextDeps];
15671 return nextValue;
15672}
15673
15674function updateMemo(nextCreate, deps) {
15675 var hook = updateWorkInProgressHook();
15676 var nextDeps = deps === undefined ? null : deps;
15677 var prevState = hook.memoizedState;
15678 if (prevState !== null) {
15679 // Assume these are defined. If they're not, areHookInputsEqual will warn.
15680 if (nextDeps !== null) {
15681 var prevDeps = prevState[1];
15682 if (areHookInputsEqual(nextDeps, prevDeps)) {
15683 return prevState[0];
15684 }
15685 }
15686 }
15687 var nextValue = nextCreate();
15688 hook.memoizedState = [nextValue, nextDeps];
15689 return nextValue;
15690}
15691
15692function dispatchAction(fiber, queue, action) {
15693 (function () {
15694 if (!(numberOfReRenders < RE_RENDER_LIMIT)) {
15695 {
15696 throw ReactError(Error('Too many re-renders. React limits the number of renders to prevent an infinite loop.'));
15697 }
15698 }
15699 })();
15700
15701 {
15702 !(arguments.length <= 3) ? warning$1(false, "State updates from the useState() and useReducer() Hooks don't support the " + 'second callback argument. To execute a side effect after ' + 'rendering, declare it in the component body with useEffect().') : void 0;
15703 }
15704
15705 var alternate = fiber.alternate;
15706 if (fiber === currentlyRenderingFiber$1 || alternate !== null && alternate === currentlyRenderingFiber$1) {
15707 // This is a render phase update. Stash it in a lazily-created map of
15708 // queue -> linked list of updates. After this render pass, we'll restart
15709 // and apply the stashed updates on top of the work-in-progress hook.
15710 didScheduleRenderPhaseUpdate = true;
15711 var update = {
15712 expirationTime: renderExpirationTime$1,
15713 suspenseConfig: null,
15714 action: action,
15715 eagerReducer: null,
15716 eagerState: null,
15717 next: null
15718 };
15719 {
15720 update.priority = getCurrentPriorityLevel();
15721 }
15722 if (renderPhaseUpdates === null) {
15723 renderPhaseUpdates = new Map();
15724 }
15725 var firstRenderPhaseUpdate = renderPhaseUpdates.get(queue);
15726 if (firstRenderPhaseUpdate === undefined) {
15727 renderPhaseUpdates.set(queue, update);
15728 } else {
15729 // Append the update to the end of the list.
15730 var lastRenderPhaseUpdate = firstRenderPhaseUpdate;
15731 while (lastRenderPhaseUpdate.next !== null) {
15732 lastRenderPhaseUpdate = lastRenderPhaseUpdate.next;
15733 }
15734 lastRenderPhaseUpdate.next = update;
15735 }
15736 } else {
15737 if (revertPassiveEffectsChange) {
15738 flushPassiveEffects();
15739 }
15740
15741 var currentTime = requestCurrentTime();
15742 var _suspenseConfig = requestCurrentSuspenseConfig();
15743 var _expirationTime = computeExpirationForFiber(currentTime, fiber, _suspenseConfig);
15744
15745 var _update2 = {
15746 expirationTime: _expirationTime,
15747 suspenseConfig: _suspenseConfig,
15748 action: action,
15749 eagerReducer: null,
15750 eagerState: null,
15751 next: null
15752 };
15753
15754 {
15755 _update2.priority = getCurrentPriorityLevel();
15756 }
15757
15758 // Append the update to the end of the list.
15759 var _last = queue.last;
15760 if (_last === null) {
15761 // This is the first update. Create a circular list.
15762 _update2.next = _update2;
15763 } else {
15764 var first = _last.next;
15765 if (first !== null) {
15766 // Still circular.
15767 _update2.next = first;
15768 }
15769 _last.next = _update2;
15770 }
15771 queue.last = _update2;
15772
15773 if (fiber.expirationTime === NoWork && (alternate === null || alternate.expirationTime === NoWork)) {
15774 // The queue is currently empty, which means we can eagerly compute the
15775 // next state before entering the render phase. If the new state is the
15776 // same as the current state, we may be able to bail out entirely.
15777 var _lastRenderedReducer = queue.lastRenderedReducer;
15778 if (_lastRenderedReducer !== null) {
15779 var prevDispatcher = void 0;
15780 {
15781 prevDispatcher = ReactCurrentDispatcher$1.current;
15782 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
15783 }
15784 try {
15785 var currentState = queue.lastRenderedState;
15786 var _eagerState = _lastRenderedReducer(currentState, action);
15787 // Stash the eagerly computed state, and the reducer used to compute
15788 // it, on the update object. If the reducer hasn't changed by the
15789 // time we enter the render phase, then the eager state can be used
15790 // without calling the reducer again.
15791 _update2.eagerReducer = _lastRenderedReducer;
15792 _update2.eagerState = _eagerState;
15793 if (is(_eagerState, currentState)) {
15794 // Fast path. We can bail out without scheduling React to re-render.
15795 // It's still possible that we'll need to rebase this update later,
15796 // if the component re-renders for a different reason and by that
15797 // time the reducer has changed.
15798 return;
15799 }
15800 } catch (error) {
15801 // Suppress the error. It will throw again in the render phase.
15802 } finally {
15803 {
15804 ReactCurrentDispatcher$1.current = prevDispatcher;
15805 }
15806 }
15807 }
15808 }
15809 {
15810 // $FlowExpectedError - jest isn't a global, and isn't recognized outside of tests
15811 if ('undefined' !== typeof jest) {
15812 warnIfNotScopedWithMatchingAct(fiber);
15813 warnIfNotCurrentlyActingUpdatesInDev(fiber);
15814 }
15815 }
15816 scheduleWork(fiber, _expirationTime);
15817 }
15818}
15819
15820var ContextOnlyDispatcher = {
15821 readContext: readContext,
15822
15823 useCallback: throwInvalidHookError,
15824 useContext: throwInvalidHookError,
15825 useEffect: throwInvalidHookError,
15826 useImperativeHandle: throwInvalidHookError,
15827 useLayoutEffect: throwInvalidHookError,
15828 useMemo: throwInvalidHookError,
15829 useReducer: throwInvalidHookError,
15830 useRef: throwInvalidHookError,
15831 useState: throwInvalidHookError,
15832 useDebugValue: throwInvalidHookError,
15833 useResponder: throwInvalidHookError
15834};
15835
15836var HooksDispatcherOnMountInDEV = null;
15837var HooksDispatcherOnMountWithHookTypesInDEV = null;
15838var HooksDispatcherOnUpdateInDEV = null;
15839var InvalidNestedHooksDispatcherOnMountInDEV = null;
15840var InvalidNestedHooksDispatcherOnUpdateInDEV = null;
15841
15842{
15843 var warnInvalidContextAccess = function () {
15844 warning$1(false, 'Context can only be read while React is rendering. ' + 'In classes, you can read it in the render method or getDerivedStateFromProps. ' + 'In function components, you can read it directly in the function body, but not ' + 'inside Hooks like useReducer() or useMemo().');
15845 };
15846
15847 var warnInvalidHookAccess = function () {
15848 warning$1(false, 'Do not call Hooks inside useEffect(...), useMemo(...), or other built-in Hooks. ' + 'You can only call Hooks at the top level of your React function. ' + 'For more information, see ' + 'https://fb.me/rules-of-hooks');
15849 };
15850
15851 HooksDispatcherOnMountInDEV = {
15852 readContext: function (context, observedBits) {
15853 return readContext(context, observedBits);
15854 },
15855 useCallback: function (callback, deps) {
15856 currentHookNameInDev = 'useCallback';
15857 mountHookTypesDev();
15858 checkDepsAreArrayDev(deps);
15859 return mountCallback(callback, deps);
15860 },
15861 useContext: function (context, observedBits) {
15862 currentHookNameInDev = 'useContext';
15863 mountHookTypesDev();
15864 return readContext(context, observedBits);
15865 },
15866 useEffect: function (create, deps) {
15867 currentHookNameInDev = 'useEffect';
15868 mountHookTypesDev();
15869 checkDepsAreArrayDev(deps);
15870 return mountEffect(create, deps);
15871 },
15872 useImperativeHandle: function (ref, create, deps) {
15873 currentHookNameInDev = 'useImperativeHandle';
15874 mountHookTypesDev();
15875 checkDepsAreArrayDev(deps);
15876 return mountImperativeHandle(ref, create, deps);
15877 },
15878 useLayoutEffect: function (create, deps) {
15879 currentHookNameInDev = 'useLayoutEffect';
15880 mountHookTypesDev();
15881 checkDepsAreArrayDev(deps);
15882 return mountLayoutEffect(create, deps);
15883 },
15884 useMemo: function (create, deps) {
15885 currentHookNameInDev = 'useMemo';
15886 mountHookTypesDev();
15887 checkDepsAreArrayDev(deps);
15888 var prevDispatcher = ReactCurrentDispatcher$1.current;
15889 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
15890 try {
15891 return mountMemo(create, deps);
15892 } finally {
15893 ReactCurrentDispatcher$1.current = prevDispatcher;
15894 }
15895 },
15896 useReducer: function (reducer, initialArg, init) {
15897 currentHookNameInDev = 'useReducer';
15898 mountHookTypesDev();
15899 var prevDispatcher = ReactCurrentDispatcher$1.current;
15900 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
15901 try {
15902 return mountReducer(reducer, initialArg, init);
15903 } finally {
15904 ReactCurrentDispatcher$1.current = prevDispatcher;
15905 }
15906 },
15907 useRef: function (initialValue) {
15908 currentHookNameInDev = 'useRef';
15909 mountHookTypesDev();
15910 return mountRef(initialValue);
15911 },
15912 useState: function (initialState) {
15913 currentHookNameInDev = 'useState';
15914 mountHookTypesDev();
15915 var prevDispatcher = ReactCurrentDispatcher$1.current;
15916 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
15917 try {
15918 return mountState(initialState);
15919 } finally {
15920 ReactCurrentDispatcher$1.current = prevDispatcher;
15921 }
15922 },
15923 useDebugValue: function (value, formatterFn) {
15924 currentHookNameInDev = 'useDebugValue';
15925 mountHookTypesDev();
15926 return mountDebugValue(value, formatterFn);
15927 },
15928 useResponder: function (responder, props) {
15929 currentHookNameInDev = 'useResponder';
15930 mountHookTypesDev();
15931 return createResponderListener(responder, props);
15932 }
15933 };
15934
15935 HooksDispatcherOnMountWithHookTypesInDEV = {
15936 readContext: function (context, observedBits) {
15937 return readContext(context, observedBits);
15938 },
15939 useCallback: function (callback, deps) {
15940 currentHookNameInDev = 'useCallback';
15941 updateHookTypesDev();
15942 return mountCallback(callback, deps);
15943 },
15944 useContext: function (context, observedBits) {
15945 currentHookNameInDev = 'useContext';
15946 updateHookTypesDev();
15947 return readContext(context, observedBits);
15948 },
15949 useEffect: function (create, deps) {
15950 currentHookNameInDev = 'useEffect';
15951 updateHookTypesDev();
15952 return mountEffect(create, deps);
15953 },
15954 useImperativeHandle: function (ref, create, deps) {
15955 currentHookNameInDev = 'useImperativeHandle';
15956 updateHookTypesDev();
15957 return mountImperativeHandle(ref, create, deps);
15958 },
15959 useLayoutEffect: function (create, deps) {
15960 currentHookNameInDev = 'useLayoutEffect';
15961 updateHookTypesDev();
15962 return mountLayoutEffect(create, deps);
15963 },
15964 useMemo: function (create, deps) {
15965 currentHookNameInDev = 'useMemo';
15966 updateHookTypesDev();
15967 var prevDispatcher = ReactCurrentDispatcher$1.current;
15968 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
15969 try {
15970 return mountMemo(create, deps);
15971 } finally {
15972 ReactCurrentDispatcher$1.current = prevDispatcher;
15973 }
15974 },
15975 useReducer: function (reducer, initialArg, init) {
15976 currentHookNameInDev = 'useReducer';
15977 updateHookTypesDev();
15978 var prevDispatcher = ReactCurrentDispatcher$1.current;
15979 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
15980 try {
15981 return mountReducer(reducer, initialArg, init);
15982 } finally {
15983 ReactCurrentDispatcher$1.current = prevDispatcher;
15984 }
15985 },
15986 useRef: function (initialValue) {
15987 currentHookNameInDev = 'useRef';
15988 updateHookTypesDev();
15989 return mountRef(initialValue);
15990 },
15991 useState: function (initialState) {
15992 currentHookNameInDev = 'useState';
15993 updateHookTypesDev();
15994 var prevDispatcher = ReactCurrentDispatcher$1.current;
15995 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
15996 try {
15997 return mountState(initialState);
15998 } finally {
15999 ReactCurrentDispatcher$1.current = prevDispatcher;
16000 }
16001 },
16002 useDebugValue: function (value, formatterFn) {
16003 currentHookNameInDev = 'useDebugValue';
16004 updateHookTypesDev();
16005 return mountDebugValue(value, formatterFn);
16006 },
16007 useResponder: function (responder, props) {
16008 currentHookNameInDev = 'useResponder';
16009 updateHookTypesDev();
16010 return createResponderListener(responder, props);
16011 }
16012 };
16013
16014 HooksDispatcherOnUpdateInDEV = {
16015 readContext: function (context, observedBits) {
16016 return readContext(context, observedBits);
16017 },
16018 useCallback: function (callback, deps) {
16019 currentHookNameInDev = 'useCallback';
16020 updateHookTypesDev();
16021 return updateCallback(callback, deps);
16022 },
16023 useContext: function (context, observedBits) {
16024 currentHookNameInDev = 'useContext';
16025 updateHookTypesDev();
16026 return readContext(context, observedBits);
16027 },
16028 useEffect: function (create, deps) {
16029 currentHookNameInDev = 'useEffect';
16030 updateHookTypesDev();
16031 return updateEffect(create, deps);
16032 },
16033 useImperativeHandle: function (ref, create, deps) {
16034 currentHookNameInDev = 'useImperativeHandle';
16035 updateHookTypesDev();
16036 return updateImperativeHandle(ref, create, deps);
16037 },
16038 useLayoutEffect: function (create, deps) {
16039 currentHookNameInDev = 'useLayoutEffect';
16040 updateHookTypesDev();
16041 return updateLayoutEffect(create, deps);
16042 },
16043 useMemo: function (create, deps) {
16044 currentHookNameInDev = 'useMemo';
16045 updateHookTypesDev();
16046 var prevDispatcher = ReactCurrentDispatcher$1.current;
16047 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
16048 try {
16049 return updateMemo(create, deps);
16050 } finally {
16051 ReactCurrentDispatcher$1.current = prevDispatcher;
16052 }
16053 },
16054 useReducer: function (reducer, initialArg, init) {
16055 currentHookNameInDev = 'useReducer';
16056 updateHookTypesDev();
16057 var prevDispatcher = ReactCurrentDispatcher$1.current;
16058 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
16059 try {
16060 return updateReducer(reducer, initialArg, init);
16061 } finally {
16062 ReactCurrentDispatcher$1.current = prevDispatcher;
16063 }
16064 },
16065 useRef: function (initialValue) {
16066 currentHookNameInDev = 'useRef';
16067 updateHookTypesDev();
16068 return updateRef(initialValue);
16069 },
16070 useState: function (initialState) {
16071 currentHookNameInDev = 'useState';
16072 updateHookTypesDev();
16073 var prevDispatcher = ReactCurrentDispatcher$1.current;
16074 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
16075 try {
16076 return updateState(initialState);
16077 } finally {
16078 ReactCurrentDispatcher$1.current = prevDispatcher;
16079 }
16080 },
16081 useDebugValue: function (value, formatterFn) {
16082 currentHookNameInDev = 'useDebugValue';
16083 updateHookTypesDev();
16084 return updateDebugValue(value, formatterFn);
16085 },
16086 useResponder: function (responder, props) {
16087 currentHookNameInDev = 'useResponder';
16088 updateHookTypesDev();
16089 return createResponderListener(responder, props);
16090 }
16091 };
16092
16093 InvalidNestedHooksDispatcherOnMountInDEV = {
16094 readContext: function (context, observedBits) {
16095 warnInvalidContextAccess();
16096 return readContext(context, observedBits);
16097 },
16098 useCallback: function (callback, deps) {
16099 currentHookNameInDev = 'useCallback';
16100 warnInvalidHookAccess();
16101 mountHookTypesDev();
16102 return mountCallback(callback, deps);
16103 },
16104 useContext: function (context, observedBits) {
16105 currentHookNameInDev = 'useContext';
16106 warnInvalidHookAccess();
16107 mountHookTypesDev();
16108 return readContext(context, observedBits);
16109 },
16110 useEffect: function (create, deps) {
16111 currentHookNameInDev = 'useEffect';
16112 warnInvalidHookAccess();
16113 mountHookTypesDev();
16114 return mountEffect(create, deps);
16115 },
16116 useImperativeHandle: function (ref, create, deps) {
16117 currentHookNameInDev = 'useImperativeHandle';
16118 warnInvalidHookAccess();
16119 mountHookTypesDev();
16120 return mountImperativeHandle(ref, create, deps);
16121 },
16122 useLayoutEffect: function (create, deps) {
16123 currentHookNameInDev = 'useLayoutEffect';
16124 warnInvalidHookAccess();
16125 mountHookTypesDev();
16126 return mountLayoutEffect(create, deps);
16127 },
16128 useMemo: function (create, deps) {
16129 currentHookNameInDev = 'useMemo';
16130 warnInvalidHookAccess();
16131 mountHookTypesDev();
16132 var prevDispatcher = ReactCurrentDispatcher$1.current;
16133 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
16134 try {
16135 return mountMemo(create, deps);
16136 } finally {
16137 ReactCurrentDispatcher$1.current = prevDispatcher;
16138 }
16139 },
16140 useReducer: function (reducer, initialArg, init) {
16141 currentHookNameInDev = 'useReducer';
16142 warnInvalidHookAccess();
16143 mountHookTypesDev();
16144 var prevDispatcher = ReactCurrentDispatcher$1.current;
16145 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
16146 try {
16147 return mountReducer(reducer, initialArg, init);
16148 } finally {
16149 ReactCurrentDispatcher$1.current = prevDispatcher;
16150 }
16151 },
16152 useRef: function (initialValue) {
16153 currentHookNameInDev = 'useRef';
16154 warnInvalidHookAccess();
16155 mountHookTypesDev();
16156 return mountRef(initialValue);
16157 },
16158 useState: function (initialState) {
16159 currentHookNameInDev = 'useState';
16160 warnInvalidHookAccess();
16161 mountHookTypesDev();
16162 var prevDispatcher = ReactCurrentDispatcher$1.current;
16163 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
16164 try {
16165 return mountState(initialState);
16166 } finally {
16167 ReactCurrentDispatcher$1.current = prevDispatcher;
16168 }
16169 },
16170 useDebugValue: function (value, formatterFn) {
16171 currentHookNameInDev = 'useDebugValue';
16172 warnInvalidHookAccess();
16173 mountHookTypesDev();
16174 return mountDebugValue(value, formatterFn);
16175 },
16176 useResponder: function (responder, props) {
16177 currentHookNameInDev = 'useResponder';
16178 warnInvalidHookAccess();
16179 mountHookTypesDev();
16180 return createResponderListener(responder, props);
16181 }
16182 };
16183
16184 InvalidNestedHooksDispatcherOnUpdateInDEV = {
16185 readContext: function (context, observedBits) {
16186 warnInvalidContextAccess();
16187 return readContext(context, observedBits);
16188 },
16189 useCallback: function (callback, deps) {
16190 currentHookNameInDev = 'useCallback';
16191 warnInvalidHookAccess();
16192 updateHookTypesDev();
16193 return updateCallback(callback, deps);
16194 },
16195 useContext: function (context, observedBits) {
16196 currentHookNameInDev = 'useContext';
16197 warnInvalidHookAccess();
16198 updateHookTypesDev();
16199 return readContext(context, observedBits);
16200 },
16201 useEffect: function (create, deps) {
16202 currentHookNameInDev = 'useEffect';
16203 warnInvalidHookAccess();
16204 updateHookTypesDev();
16205 return updateEffect(create, deps);
16206 },
16207 useImperativeHandle: function (ref, create, deps) {
16208 currentHookNameInDev = 'useImperativeHandle';
16209 warnInvalidHookAccess();
16210 updateHookTypesDev();
16211 return updateImperativeHandle(ref, create, deps);
16212 },
16213 useLayoutEffect: function (create, deps) {
16214 currentHookNameInDev = 'useLayoutEffect';
16215 warnInvalidHookAccess();
16216 updateHookTypesDev();
16217 return updateLayoutEffect(create, deps);
16218 },
16219 useMemo: function (create, deps) {
16220 currentHookNameInDev = 'useMemo';
16221 warnInvalidHookAccess();
16222 updateHookTypesDev();
16223 var prevDispatcher = ReactCurrentDispatcher$1.current;
16224 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
16225 try {
16226 return updateMemo(create, deps);
16227 } finally {
16228 ReactCurrentDispatcher$1.current = prevDispatcher;
16229 }
16230 },
16231 useReducer: function (reducer, initialArg, init) {
16232 currentHookNameInDev = 'useReducer';
16233 warnInvalidHookAccess();
16234 updateHookTypesDev();
16235 var prevDispatcher = ReactCurrentDispatcher$1.current;
16236 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
16237 try {
16238 return updateReducer(reducer, initialArg, init);
16239 } finally {
16240 ReactCurrentDispatcher$1.current = prevDispatcher;
16241 }
16242 },
16243 useRef: function (initialValue) {
16244 currentHookNameInDev = 'useRef';
16245 warnInvalidHookAccess();
16246 updateHookTypesDev();
16247 return updateRef(initialValue);
16248 },
16249 useState: function (initialState) {
16250 currentHookNameInDev = 'useState';
16251 warnInvalidHookAccess();
16252 updateHookTypesDev();
16253 var prevDispatcher = ReactCurrentDispatcher$1.current;
16254 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
16255 try {
16256 return updateState(initialState);
16257 } finally {
16258 ReactCurrentDispatcher$1.current = prevDispatcher;
16259 }
16260 },
16261 useDebugValue: function (value, formatterFn) {
16262 currentHookNameInDev = 'useDebugValue';
16263 warnInvalidHookAccess();
16264 updateHookTypesDev();
16265 return updateDebugValue(value, formatterFn);
16266 },
16267 useResponder: function (responder, props) {
16268 currentHookNameInDev = 'useResponder';
16269 warnInvalidHookAccess();
16270 updateHookTypesDev();
16271 return createResponderListener(responder, props);
16272 }
16273 };
16274}
16275
16276// Intentionally not named imports because Rollup would use dynamic dispatch for
16277// CommonJS interop named imports.
16278var now$1 = Scheduler.unstable_now;
16279
16280
16281var commitTime = 0;
16282var profilerStartTime = -1;
16283
16284function getCommitTime() {
16285 return commitTime;
16286}
16287
16288function recordCommitTime() {
16289 if (!enableProfilerTimer) {
16290 return;
16291 }
16292 commitTime = now$1();
16293}
16294
16295function startProfilerTimer(fiber) {
16296 if (!enableProfilerTimer) {
16297 return;
16298 }
16299
16300 profilerStartTime = now$1();
16301
16302 if (fiber.actualStartTime < 0) {
16303 fiber.actualStartTime = now$1();
16304 }
16305}
16306
16307function stopProfilerTimerIfRunning(fiber) {
16308 if (!enableProfilerTimer) {
16309 return;
16310 }
16311 profilerStartTime = -1;
16312}
16313
16314function stopProfilerTimerIfRunningAndRecordDelta(fiber, overrideBaseTime) {
16315 if (!enableProfilerTimer) {
16316 return;
16317 }
16318
16319 if (profilerStartTime >= 0) {
16320 var elapsedTime = now$1() - profilerStartTime;
16321 fiber.actualDuration += elapsedTime;
16322 if (overrideBaseTime) {
16323 fiber.selfBaseDuration = elapsedTime;
16324 }
16325 profilerStartTime = -1;
16326 }
16327}
16328
16329// The deepest Fiber on the stack involved in a hydration context.
16330// This may have been an insertion or a hydration.
16331var hydrationParentFiber = null;
16332var nextHydratableInstance = null;
16333var isHydrating = false;
16334
16335function enterHydrationState(fiber) {
16336 if (!supportsHydration) {
16337 return false;
16338 }
16339
16340 var parentInstance = fiber.stateNode.containerInfo;
16341 nextHydratableInstance = getFirstHydratableChild(parentInstance);
16342 hydrationParentFiber = fiber;
16343 isHydrating = true;
16344 return true;
16345}
16346
16347function reenterHydrationStateFromDehydratedSuspenseInstance(fiber) {
16348 if (!supportsHydration) {
16349 return false;
16350 }
16351
16352 var suspenseInstance = fiber.stateNode;
16353 nextHydratableInstance = getNextHydratableSibling(suspenseInstance);
16354 popToNextHostParent(fiber);
16355 isHydrating = true;
16356 return true;
16357}
16358
16359function deleteHydratableInstance(returnFiber, instance) {
16360 {
16361 switch (returnFiber.tag) {
16362 case HostRoot:
16363 didNotHydrateContainerInstance(returnFiber.stateNode.containerInfo, instance);
16364 break;
16365 case HostComponent:
16366 didNotHydrateInstance(returnFiber.type, returnFiber.memoizedProps, returnFiber.stateNode, instance);
16367 break;
16368 }
16369 }
16370
16371 var childToDelete = createFiberFromHostInstanceForDeletion();
16372 childToDelete.stateNode = instance;
16373 childToDelete.return = returnFiber;
16374 childToDelete.effectTag = Deletion;
16375
16376 // This might seem like it belongs on progressedFirstDeletion. However,
16377 // these children are not part of the reconciliation list of children.
16378 // Even if we abort and rereconcile the children, that will try to hydrate
16379 // again and the nodes are still in the host tree so these will be
16380 // recreated.
16381 if (returnFiber.lastEffect !== null) {
16382 returnFiber.lastEffect.nextEffect = childToDelete;
16383 returnFiber.lastEffect = childToDelete;
16384 } else {
16385 returnFiber.firstEffect = returnFiber.lastEffect = childToDelete;
16386 }
16387}
16388
16389function insertNonHydratedInstance(returnFiber, fiber) {
16390 fiber.effectTag |= Placement;
16391 {
16392 switch (returnFiber.tag) {
16393 case HostRoot:
16394 {
16395 var parentContainer = returnFiber.stateNode.containerInfo;
16396 switch (fiber.tag) {
16397 case HostComponent:
16398 var type = fiber.type;
16399 var props = fiber.pendingProps;
16400 didNotFindHydratableContainerInstance(parentContainer, type, props);
16401 break;
16402 case HostText:
16403 var text = fiber.pendingProps;
16404 didNotFindHydratableContainerTextInstance(parentContainer, text);
16405 break;
16406 case SuspenseComponent:
16407
16408 break;
16409 }
16410 break;
16411 }
16412 case HostComponent:
16413 {
16414 var parentType = returnFiber.type;
16415 var parentProps = returnFiber.memoizedProps;
16416 var parentInstance = returnFiber.stateNode;
16417 switch (fiber.tag) {
16418 case HostComponent:
16419 var _type = fiber.type;
16420 var _props = fiber.pendingProps;
16421 didNotFindHydratableInstance(parentType, parentProps, parentInstance, _type, _props);
16422 break;
16423 case HostText:
16424 var _text = fiber.pendingProps;
16425 didNotFindHydratableTextInstance(parentType, parentProps, parentInstance, _text);
16426 break;
16427 case SuspenseComponent:
16428 didNotFindHydratableSuspenseInstance(parentType, parentProps, parentInstance);
16429 break;
16430 }
16431 break;
16432 }
16433 default:
16434 return;
16435 }
16436 }
16437}
16438
16439function tryHydrate(fiber, nextInstance) {
16440 switch (fiber.tag) {
16441 case HostComponent:
16442 {
16443 var type = fiber.type;
16444 var props = fiber.pendingProps;
16445 var instance = canHydrateInstance(nextInstance, type, props);
16446 if (instance !== null) {
16447 fiber.stateNode = instance;
16448 return true;
16449 }
16450 return false;
16451 }
16452 case HostText:
16453 {
16454 var text = fiber.pendingProps;
16455 var textInstance = canHydrateTextInstance(nextInstance, text);
16456 if (textInstance !== null) {
16457 fiber.stateNode = textInstance;
16458 return true;
16459 }
16460 return false;
16461 }
16462 case SuspenseComponent:
16463 {
16464 if (enableSuspenseServerRenderer) {
16465 var suspenseInstance = canHydrateSuspenseInstance(nextInstance);
16466 if (suspenseInstance !== null) {
16467 // Downgrade the tag to a dehydrated component until we've hydrated it.
16468 fiber.tag = DehydratedSuspenseComponent;
16469 fiber.stateNode = suspenseInstance;
16470 return true;
16471 }
16472 }
16473 return false;
16474 }
16475 default:
16476 return false;
16477 }
16478}
16479
16480function tryToClaimNextHydratableInstance(fiber) {
16481 if (!isHydrating) {
16482 return;
16483 }
16484 var nextInstance = nextHydratableInstance;
16485 if (!nextInstance) {
16486 // Nothing to hydrate. Make it an insertion.
16487 insertNonHydratedInstance(hydrationParentFiber, fiber);
16488 isHydrating = false;
16489 hydrationParentFiber = fiber;
16490 return;
16491 }
16492 var firstAttemptedInstance = nextInstance;
16493 if (!tryHydrate(fiber, nextInstance)) {
16494 // If we can't hydrate this instance let's try the next one.
16495 // We use this as a heuristic. It's based on intuition and not data so it
16496 // might be flawed or unnecessary.
16497 nextInstance = getNextHydratableSibling(firstAttemptedInstance);
16498 if (!nextInstance || !tryHydrate(fiber, nextInstance)) {
16499 // Nothing to hydrate. Make it an insertion.
16500 insertNonHydratedInstance(hydrationParentFiber, fiber);
16501 isHydrating = false;
16502 hydrationParentFiber = fiber;
16503 return;
16504 }
16505 // We matched the next one, we'll now assume that the first one was
16506 // superfluous and we'll delete it. Since we can't eagerly delete it
16507 // we'll have to schedule a deletion. To do that, this node needs a dummy
16508 // fiber associated with it.
16509 deleteHydratableInstance(hydrationParentFiber, firstAttemptedInstance);
16510 }
16511 hydrationParentFiber = fiber;
16512 nextHydratableInstance = getFirstHydratableChild(nextInstance);
16513}
16514
16515function prepareToHydrateHostInstance(fiber, rootContainerInstance, hostContext) {
16516 if (!supportsHydration) {
16517 (function () {
16518 {
16519 {
16520 throw ReactError(Error('Expected prepareToHydrateHostInstance() to never be called. This error is likely caused by a bug in React. Please file an issue.'));
16521 }
16522 }
16523 })();
16524 }
16525
16526 var instance = fiber.stateNode;
16527 var updatePayload = hydrateInstance(instance, fiber.type, fiber.memoizedProps, rootContainerInstance, hostContext, fiber);
16528 // TODO: Type this specific to this type of component.
16529 fiber.updateQueue = updatePayload;
16530 // If the update payload indicates that there is a change or if there
16531 // is a new ref we mark this as an update.
16532 if (updatePayload !== null) {
16533 return true;
16534 }
16535 return false;
16536}
16537
16538function prepareToHydrateHostTextInstance(fiber) {
16539 if (!supportsHydration) {
16540 (function () {
16541 {
16542 {
16543 throw ReactError(Error('Expected prepareToHydrateHostTextInstance() to never be called. This error is likely caused by a bug in React. Please file an issue.'));
16544 }
16545 }
16546 })();
16547 }
16548
16549 var textInstance = fiber.stateNode;
16550 var textContent = fiber.memoizedProps;
16551 var shouldUpdate = hydrateTextInstance(textInstance, textContent, fiber);
16552 {
16553 if (shouldUpdate) {
16554 // We assume that prepareToHydrateHostTextInstance is called in a context where the
16555 // hydration parent is the parent host component of this host text.
16556 var returnFiber = hydrationParentFiber;
16557 if (returnFiber !== null) {
16558 switch (returnFiber.tag) {
16559 case HostRoot:
16560 {
16561 var parentContainer = returnFiber.stateNode.containerInfo;
16562 didNotMatchHydratedContainerTextInstance(parentContainer, textInstance, textContent);
16563 break;
16564 }
16565 case HostComponent:
16566 {
16567 var parentType = returnFiber.type;
16568 var parentProps = returnFiber.memoizedProps;
16569 var parentInstance = returnFiber.stateNode;
16570 didNotMatchHydratedTextInstance(parentType, parentProps, parentInstance, textInstance, textContent);
16571 break;
16572 }
16573 }
16574 }
16575 }
16576 }
16577 return shouldUpdate;
16578}
16579
16580function skipPastDehydratedSuspenseInstance(fiber) {
16581 if (!supportsHydration) {
16582 (function () {
16583 {
16584 {
16585 throw ReactError(Error('Expected skipPastDehydratedSuspenseInstance() to never be called. This error is likely caused by a bug in React. Please file an issue.'));
16586 }
16587 }
16588 })();
16589 }
16590 var suspenseInstance = fiber.stateNode;
16591 (function () {
16592 if (!suspenseInstance) {
16593 {
16594 throw ReactError(Error('Expected to have a hydrated suspense instance. This error is likely caused by a bug in React. Please file an issue.'));
16595 }
16596 }
16597 })();
16598 nextHydratableInstance = getNextHydratableInstanceAfterSuspenseInstance(suspenseInstance);
16599}
16600
16601function popToNextHostParent(fiber) {
16602 var parent = fiber.return;
16603 while (parent !== null && parent.tag !== HostComponent && parent.tag !== HostRoot && parent.tag !== DehydratedSuspenseComponent) {
16604 parent = parent.return;
16605 }
16606 hydrationParentFiber = parent;
16607}
16608
16609function popHydrationState(fiber) {
16610 if (!supportsHydration) {
16611 return false;
16612 }
16613 if (fiber !== hydrationParentFiber) {
16614 // We're deeper than the current hydration context, inside an inserted
16615 // tree.
16616 return false;
16617 }
16618 if (!isHydrating) {
16619 // If we're not currently hydrating but we're in a hydration context, then
16620 // we were an insertion and now need to pop up reenter hydration of our
16621 // siblings.
16622 popToNextHostParent(fiber);
16623 isHydrating = true;
16624 return false;
16625 }
16626
16627 var type = fiber.type;
16628
16629 // If we have any remaining hydratable nodes, we need to delete them now.
16630 // We only do this deeper than head and body since they tend to have random
16631 // other nodes in them. We also ignore components with pure text content in
16632 // side of them.
16633 // TODO: Better heuristic.
16634 if (fiber.tag !== HostComponent || type !== 'head' && type !== 'body' && !shouldSetTextContent(type, fiber.memoizedProps)) {
16635 var nextInstance = nextHydratableInstance;
16636 while (nextInstance) {
16637 deleteHydratableInstance(fiber, nextInstance);
16638 nextInstance = getNextHydratableSibling(nextInstance);
16639 }
16640 }
16641
16642 popToNextHostParent(fiber);
16643 nextHydratableInstance = hydrationParentFiber ? getNextHydratableSibling(fiber.stateNode) : null;
16644 return true;
16645}
16646
16647function resetHydrationState() {
16648 if (!supportsHydration) {
16649 return;
16650 }
16651
16652 hydrationParentFiber = null;
16653 nextHydratableInstance = null;
16654 isHydrating = false;
16655}
16656
16657var ReactCurrentOwner$3 = ReactSharedInternals.ReactCurrentOwner;
16658
16659var didReceiveUpdate = false;
16660
16661var didWarnAboutBadClass = void 0;
16662var didWarnAboutModulePatternComponent = void 0;
16663var didWarnAboutContextTypeOnFunctionComponent = void 0;
16664var didWarnAboutGetDerivedStateOnFunctionComponent = void 0;
16665var didWarnAboutFunctionRefs = void 0;
16666var didWarnAboutReassigningProps = void 0;
16667var didWarnAboutMaxDuration = void 0;
16668var didWarnAboutRevealOrder = void 0;
16669var didWarnAboutTailOptions = void 0;
16670var didWarnAboutDefaultPropsOnFunctionComponent = void 0;
16671
16672{
16673 didWarnAboutBadClass = {};
16674 didWarnAboutModulePatternComponent = {};
16675 didWarnAboutContextTypeOnFunctionComponent = {};
16676 didWarnAboutGetDerivedStateOnFunctionComponent = {};
16677 didWarnAboutFunctionRefs = {};
16678 didWarnAboutReassigningProps = false;
16679 didWarnAboutMaxDuration = false;
16680 didWarnAboutRevealOrder = {};
16681 didWarnAboutTailOptions = {};
16682 didWarnAboutDefaultPropsOnFunctionComponent = {};
16683}
16684
16685function reconcileChildren(current$$1, workInProgress, nextChildren, renderExpirationTime) {
16686 if (current$$1 === null) {
16687 // If this is a fresh new component that hasn't been rendered yet, we
16688 // won't update its child set by applying minimal side-effects. Instead,
16689 // we will add them all to the child before it gets rendered. That means
16690 // we can optimize this reconciliation pass by not tracking side-effects.
16691 workInProgress.child = mountChildFibers(workInProgress, null, nextChildren, renderExpirationTime);
16692 } else {
16693 // If the current child is the same as the work in progress, it means that
16694 // we haven't yet started any work on these children. Therefore, we use
16695 // the clone algorithm to create a copy of all the current children.
16696
16697 // If we had any progressed work already, that is invalid at this point so
16698 // let's throw it out.
16699 workInProgress.child = reconcileChildFibers(workInProgress, current$$1.child, nextChildren, renderExpirationTime);
16700 }
16701}
16702
16703function forceUnmountCurrentAndReconcile(current$$1, workInProgress, nextChildren, renderExpirationTime) {
16704 // This function is fork of reconcileChildren. It's used in cases where we
16705 // want to reconcile without matching against the existing set. This has the
16706 // effect of all current children being unmounted; even if the type and key
16707 // are the same, the old child is unmounted and a new child is created.
16708 //
16709 // To do this, we're going to go through the reconcile algorithm twice. In
16710 // the first pass, we schedule a deletion for all the current children by
16711 // passing null.
16712 workInProgress.child = reconcileChildFibers(workInProgress, current$$1.child, null, renderExpirationTime);
16713 // In the second pass, we mount the new children. The trick here is that we
16714 // pass null in place of where we usually pass the current child set. This has
16715 // the effect of remounting all children regardless of whether their their
16716 // identity matches.
16717 workInProgress.child = reconcileChildFibers(workInProgress, null, nextChildren, renderExpirationTime);
16718}
16719
16720function updateForwardRef(current$$1, workInProgress, Component, nextProps, renderExpirationTime) {
16721 // TODO: current can be non-null here even if the component
16722 // hasn't yet mounted. This happens after the first render suspends.
16723 // We'll need to figure out if this is fine or can cause issues.
16724
16725 {
16726 if (workInProgress.type !== workInProgress.elementType) {
16727 // Lazy component props can't be validated in createElement
16728 // because they're only guaranteed to be resolved here.
16729 var innerPropTypes = Component.propTypes;
16730 if (innerPropTypes) {
16731 checkPropTypes(innerPropTypes, nextProps, // Resolved props
16732 'prop', getComponentName(Component), getCurrentFiberStackInDev);
16733 }
16734 }
16735 }
16736
16737 var render = Component.render;
16738 var ref = workInProgress.ref;
16739
16740 // The rest is a fork of updateFunctionComponent
16741 var nextChildren = void 0;
16742 prepareToReadContext(workInProgress, renderExpirationTime);
16743 {
16744 ReactCurrentOwner$3.current = workInProgress;
16745 setCurrentPhase('render');
16746 nextChildren = renderWithHooks(current$$1, workInProgress, render, nextProps, ref, renderExpirationTime);
16747 if (debugRenderPhaseSideEffects || debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) {
16748 // Only double-render components with Hooks
16749 if (workInProgress.memoizedState !== null) {
16750 nextChildren = renderWithHooks(current$$1, workInProgress, render, nextProps, ref, renderExpirationTime);
16751 }
16752 }
16753 setCurrentPhase(null);
16754 }
16755
16756 if (current$$1 !== null && !didReceiveUpdate) {
16757 bailoutHooks(current$$1, workInProgress, renderExpirationTime);
16758 return bailoutOnAlreadyFinishedWork(current$$1, workInProgress, renderExpirationTime);
16759 }
16760
16761 // React DevTools reads this flag.
16762 workInProgress.effectTag |= PerformedWork;
16763 reconcileChildren(current$$1, workInProgress, nextChildren, renderExpirationTime);
16764 return workInProgress.child;
16765}
16766
16767function updateMemoComponent(current$$1, workInProgress, Component, nextProps, updateExpirationTime, renderExpirationTime) {
16768 if (current$$1 === null) {
16769 var type = Component.type;
16770 if (isSimpleFunctionComponent(type) && Component.compare === null &&
16771 // SimpleMemoComponent codepath doesn't resolve outer props either.
16772 Component.defaultProps === undefined) {
16773 var resolvedType = type;
16774 {
16775 resolvedType = resolveFunctionForHotReloading(type);
16776 }
16777 // If this is a plain function component without default props,
16778 // and with only the default shallow comparison, we upgrade it
16779 // to a SimpleMemoComponent to allow fast path updates.
16780 workInProgress.tag = SimpleMemoComponent;
16781 workInProgress.type = resolvedType;
16782 {
16783 validateFunctionComponentInDev(workInProgress, type);
16784 }
16785 return updateSimpleMemoComponent(current$$1, workInProgress, resolvedType, nextProps, updateExpirationTime, renderExpirationTime);
16786 }
16787 {
16788 var innerPropTypes = type.propTypes;
16789 if (innerPropTypes) {
16790 // Inner memo component props aren't currently validated in createElement.
16791 // We could move it there, but we'd still need this for lazy code path.
16792 checkPropTypes(innerPropTypes, nextProps, // Resolved props
16793 'prop', getComponentName(type), getCurrentFiberStackInDev);
16794 }
16795 }
16796 var child = createFiberFromTypeAndProps(Component.type, null, nextProps, null, workInProgress.mode, renderExpirationTime);
16797 child.ref = workInProgress.ref;
16798 child.return = workInProgress;
16799 workInProgress.child = child;
16800 return child;
16801 }
16802 {
16803 var _type = Component.type;
16804 var _innerPropTypes = _type.propTypes;
16805 if (_innerPropTypes) {
16806 // Inner memo component props aren't currently validated in createElement.
16807 // We could move it there, but we'd still need this for lazy code path.
16808 checkPropTypes(_innerPropTypes, nextProps, // Resolved props
16809 'prop', getComponentName(_type), getCurrentFiberStackInDev);
16810 }
16811 }
16812 var currentChild = current$$1.child; // This is always exactly one child
16813 if (updateExpirationTime < renderExpirationTime) {
16814 // This will be the props with resolved defaultProps,
16815 // unlike current.memoizedProps which will be the unresolved ones.
16816 var prevProps = currentChild.memoizedProps;
16817 // Default to shallow comparison
16818 var compare = Component.compare;
16819 compare = compare !== null ? compare : shallowEqual;
16820 if (compare(prevProps, nextProps) && current$$1.ref === workInProgress.ref) {
16821 return bailoutOnAlreadyFinishedWork(current$$1, workInProgress, renderExpirationTime);
16822 }
16823 }
16824 // React DevTools reads this flag.
16825 workInProgress.effectTag |= PerformedWork;
16826 var newChild = createWorkInProgress(currentChild, nextProps, renderExpirationTime);
16827 newChild.ref = workInProgress.ref;
16828 newChild.return = workInProgress;
16829 workInProgress.child = newChild;
16830 return newChild;
16831}
16832
16833function updateSimpleMemoComponent(current$$1, workInProgress, Component, nextProps, updateExpirationTime, renderExpirationTime) {
16834 // TODO: current can be non-null here even if the component
16835 // hasn't yet mounted. This happens when the inner render suspends.
16836 // We'll need to figure out if this is fine or can cause issues.
16837
16838 {
16839 if (workInProgress.type !== workInProgress.elementType) {
16840 // Lazy component props can't be validated in createElement
16841 // because they're only guaranteed to be resolved here.
16842 var outerMemoType = workInProgress.elementType;
16843 if (outerMemoType.$$typeof === REACT_LAZY_TYPE) {
16844 // We warn when you define propTypes on lazy()
16845 // so let's just skip over it to find memo() outer wrapper.
16846 // Inner props for memo are validated later.
16847 outerMemoType = refineResolvedLazyComponent(outerMemoType);
16848 }
16849 var outerPropTypes = outerMemoType && outerMemoType.propTypes;
16850 if (outerPropTypes) {
16851 checkPropTypes(outerPropTypes, nextProps, // Resolved (SimpleMemoComponent has no defaultProps)
16852 'prop', getComponentName(outerMemoType), getCurrentFiberStackInDev);
16853 }
16854 // Inner propTypes will be validated in the function component path.
16855 }
16856 }
16857 if (current$$1 !== null) {
16858 var prevProps = current$$1.memoizedProps;
16859 if (shallowEqual(prevProps, nextProps) && current$$1.ref === workInProgress.ref && (
16860 // Prevent bailout if the implementation changed due to hot reload:
16861 workInProgress.type === current$$1.type)) {
16862 didReceiveUpdate = false;
16863 if (updateExpirationTime < renderExpirationTime) {
16864 return bailoutOnAlreadyFinishedWork(current$$1, workInProgress, renderExpirationTime);
16865 }
16866 }
16867 }
16868 return updateFunctionComponent(current$$1, workInProgress, Component, nextProps, renderExpirationTime);
16869}
16870
16871function updateFragment(current$$1, workInProgress, renderExpirationTime) {
16872 var nextChildren = workInProgress.pendingProps;
16873 reconcileChildren(current$$1, workInProgress, nextChildren, renderExpirationTime);
16874 return workInProgress.child;
16875}
16876
16877function updateMode(current$$1, workInProgress, renderExpirationTime) {
16878 var nextChildren = workInProgress.pendingProps.children;
16879 reconcileChildren(current$$1, workInProgress, nextChildren, renderExpirationTime);
16880 return workInProgress.child;
16881}
16882
16883function updateProfiler(current$$1, workInProgress, renderExpirationTime) {
16884 if (enableProfilerTimer) {
16885 workInProgress.effectTag |= Update;
16886 }
16887 var nextProps = workInProgress.pendingProps;
16888 var nextChildren = nextProps.children;
16889 reconcileChildren(current$$1, workInProgress, nextChildren, renderExpirationTime);
16890 return workInProgress.child;
16891}
16892
16893function markRef(current$$1, workInProgress) {
16894 var ref = workInProgress.ref;
16895 if (current$$1 === null && ref !== null || current$$1 !== null && current$$1.ref !== ref) {
16896 // Schedule a Ref effect
16897 workInProgress.effectTag |= Ref;
16898 }
16899}
16900
16901function updateFunctionComponent(current$$1, workInProgress, Component, nextProps, renderExpirationTime) {
16902 {
16903 if (workInProgress.type !== workInProgress.elementType) {
16904 // Lazy component props can't be validated in createElement
16905 // because they're only guaranteed to be resolved here.
16906 var innerPropTypes = Component.propTypes;
16907 if (innerPropTypes) {
16908 checkPropTypes(innerPropTypes, nextProps, // Resolved props
16909 'prop', getComponentName(Component), getCurrentFiberStackInDev);
16910 }
16911 }
16912 }
16913
16914 var context = void 0;
16915 if (!disableLegacyContext) {
16916 var unmaskedContext = getUnmaskedContext(workInProgress, Component, true);
16917 context = getMaskedContext(workInProgress, unmaskedContext);
16918 }
16919
16920 var nextChildren = void 0;
16921 prepareToReadContext(workInProgress, renderExpirationTime);
16922 {
16923 ReactCurrentOwner$3.current = workInProgress;
16924 setCurrentPhase('render');
16925 nextChildren = renderWithHooks(current$$1, workInProgress, Component, nextProps, context, renderExpirationTime);
16926 if (debugRenderPhaseSideEffects || debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) {
16927 // Only double-render components with Hooks
16928 if (workInProgress.memoizedState !== null) {
16929 nextChildren = renderWithHooks(current$$1, workInProgress, Component, nextProps, context, renderExpirationTime);
16930 }
16931 }
16932 setCurrentPhase(null);
16933 }
16934
16935 if (current$$1 !== null && !didReceiveUpdate) {
16936 bailoutHooks(current$$1, workInProgress, renderExpirationTime);
16937 return bailoutOnAlreadyFinishedWork(current$$1, workInProgress, renderExpirationTime);
16938 }
16939
16940 // React DevTools reads this flag.
16941 workInProgress.effectTag |= PerformedWork;
16942 reconcileChildren(current$$1, workInProgress, nextChildren, renderExpirationTime);
16943 return workInProgress.child;
16944}
16945
16946function updateClassComponent(current$$1, workInProgress, Component, nextProps, renderExpirationTime) {
16947 {
16948 if (workInProgress.type !== workInProgress.elementType) {
16949 // Lazy component props can't be validated in createElement
16950 // because they're only guaranteed to be resolved here.
16951 var innerPropTypes = Component.propTypes;
16952 if (innerPropTypes) {
16953 checkPropTypes(innerPropTypes, nextProps, // Resolved props
16954 'prop', getComponentName(Component), getCurrentFiberStackInDev);
16955 }
16956 }
16957 }
16958
16959 // Push context providers early to prevent context stack mismatches.
16960 // During mounting we don't know the child context yet as the instance doesn't exist.
16961 // We will invalidate the child context in finishClassComponent() right after rendering.
16962 var hasContext = void 0;
16963 if (isContextProvider(Component)) {
16964 hasContext = true;
16965 pushContextProvider(workInProgress);
16966 } else {
16967 hasContext = false;
16968 }
16969 prepareToReadContext(workInProgress, renderExpirationTime);
16970
16971 var instance = workInProgress.stateNode;
16972 var shouldUpdate = void 0;
16973 if (instance === null) {
16974 if (current$$1 !== null) {
16975 // An class component without an instance only mounts if it suspended
16976 // inside a non- concurrent tree, in an inconsistent state. We want to
16977 // tree it like a new mount, even though an empty version of it already
16978 // committed. Disconnect the alternate pointers.
16979 current$$1.alternate = null;
16980 workInProgress.alternate = null;
16981 // Since this is conceptually a new fiber, schedule a Placement effect
16982 workInProgress.effectTag |= Placement;
16983 }
16984 // In the initial pass we might need to construct the instance.
16985 constructClassInstance(workInProgress, Component, nextProps, renderExpirationTime);
16986 mountClassInstance(workInProgress, Component, nextProps, renderExpirationTime);
16987 shouldUpdate = true;
16988 } else if (current$$1 === null) {
16989 // In a resume, we'll already have an instance we can reuse.
16990 shouldUpdate = resumeMountClassInstance(workInProgress, Component, nextProps, renderExpirationTime);
16991 } else {
16992 shouldUpdate = updateClassInstance(current$$1, workInProgress, Component, nextProps, renderExpirationTime);
16993 }
16994 var nextUnitOfWork = finishClassComponent(current$$1, workInProgress, Component, shouldUpdate, hasContext, renderExpirationTime);
16995 {
16996 var inst = workInProgress.stateNode;
16997 if (inst.props !== nextProps) {
16998 !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;
16999 didWarnAboutReassigningProps = true;
17000 }
17001 }
17002 return nextUnitOfWork;
17003}
17004
17005function finishClassComponent(current$$1, workInProgress, Component, shouldUpdate, hasContext, renderExpirationTime) {
17006 // Refs should update even if shouldComponentUpdate returns false
17007 markRef(current$$1, workInProgress);
17008
17009 var didCaptureError = (workInProgress.effectTag & DidCapture) !== NoEffect;
17010
17011 if (!shouldUpdate && !didCaptureError) {
17012 // Context providers should defer to sCU for rendering
17013 if (hasContext) {
17014 invalidateContextProvider(workInProgress, Component, false);
17015 }
17016
17017 return bailoutOnAlreadyFinishedWork(current$$1, workInProgress, renderExpirationTime);
17018 }
17019
17020 var instance = workInProgress.stateNode;
17021
17022 // Rerender
17023 ReactCurrentOwner$3.current = workInProgress;
17024 var nextChildren = void 0;
17025 if (didCaptureError && typeof Component.getDerivedStateFromError !== 'function') {
17026 // If we captured an error, but getDerivedStateFrom catch is not defined,
17027 // unmount all the children. componentDidCatch will schedule an update to
17028 // re-render a fallback. This is temporary until we migrate everyone to
17029 // the new API.
17030 // TODO: Warn in a future release.
17031 nextChildren = null;
17032
17033 if (enableProfilerTimer) {
17034 stopProfilerTimerIfRunning(workInProgress);
17035 }
17036 } else {
17037 {
17038 setCurrentPhase('render');
17039 nextChildren = instance.render();
17040 if (debugRenderPhaseSideEffects || debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) {
17041 instance.render();
17042 }
17043 setCurrentPhase(null);
17044 }
17045 }
17046
17047 // React DevTools reads this flag.
17048 workInProgress.effectTag |= PerformedWork;
17049 if (current$$1 !== null && didCaptureError) {
17050 // If we're recovering from an error, reconcile without reusing any of
17051 // the existing children. Conceptually, the normal children and the children
17052 // that are shown on error are two different sets, so we shouldn't reuse
17053 // normal children even if their identities match.
17054 forceUnmountCurrentAndReconcile(current$$1, workInProgress, nextChildren, renderExpirationTime);
17055 } else {
17056 reconcileChildren(current$$1, workInProgress, nextChildren, renderExpirationTime);
17057 }
17058
17059 // Memoize state using the values we just used to render.
17060 // TODO: Restructure so we never read values from the instance.
17061 workInProgress.memoizedState = instance.state;
17062
17063 // The context might have changed so we need to recalculate it.
17064 if (hasContext) {
17065 invalidateContextProvider(workInProgress, Component, true);
17066 }
17067
17068 return workInProgress.child;
17069}
17070
17071function pushHostRootContext(workInProgress) {
17072 var root = workInProgress.stateNode;
17073 if (root.pendingContext) {
17074 pushTopLevelContextObject(workInProgress, root.pendingContext, root.pendingContext !== root.context);
17075 } else if (root.context) {
17076 // Should always be set
17077 pushTopLevelContextObject(workInProgress, root.context, false);
17078 }
17079 pushHostContainer(workInProgress, root.containerInfo);
17080}
17081
17082function updateHostRoot(current$$1, workInProgress, renderExpirationTime) {
17083 pushHostRootContext(workInProgress);
17084 var updateQueue = workInProgress.updateQueue;
17085 (function () {
17086 if (!(updateQueue !== null)) {
17087 {
17088 throw ReactError(Error('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.'));
17089 }
17090 }
17091 })();
17092 var nextProps = workInProgress.pendingProps;
17093 var prevState = workInProgress.memoizedState;
17094 var prevChildren = prevState !== null ? prevState.element : null;
17095 processUpdateQueue(workInProgress, updateQueue, nextProps, null, renderExpirationTime);
17096 var nextState = workInProgress.memoizedState;
17097 // Caution: React DevTools currently depends on this property
17098 // being called "element".
17099 var nextChildren = nextState.element;
17100 if (nextChildren === prevChildren) {
17101 // If the state is the same as before, that's a bailout because we had
17102 // no work that expires at this time.
17103 resetHydrationState();
17104 return bailoutOnAlreadyFinishedWork(current$$1, workInProgress, renderExpirationTime);
17105 }
17106 var root = workInProgress.stateNode;
17107 if ((current$$1 === null || current$$1.child === null) && root.hydrate && enterHydrationState(workInProgress)) {
17108 // If we don't have any current children this might be the first pass.
17109 // We always try to hydrate. If this isn't a hydration pass there won't
17110 // be any children to hydrate which is effectively the same thing as
17111 // not hydrating.
17112
17113 // This is a bit of a hack. We track the host root as a placement to
17114 // know that we're currently in a mounting state. That way isMounted
17115 // works as expected. We must reset this before committing.
17116 // TODO: Delete this when we delete isMounted and findDOMNode.
17117 workInProgress.effectTag |= Placement;
17118
17119 // Ensure that children mount into this root without tracking
17120 // side-effects. This ensures that we don't store Placement effects on
17121 // nodes that will be hydrated.
17122 workInProgress.child = mountChildFibers(workInProgress, null, nextChildren, renderExpirationTime);
17123 } else {
17124 // Otherwise reset hydration state in case we aborted and resumed another
17125 // root.
17126 reconcileChildren(current$$1, workInProgress, nextChildren, renderExpirationTime);
17127 resetHydrationState();
17128 }
17129 return workInProgress.child;
17130}
17131
17132function updateHostComponent(current$$1, workInProgress, renderExpirationTime) {
17133 pushHostContext(workInProgress);
17134
17135 if (current$$1 === null) {
17136 tryToClaimNextHydratableInstance(workInProgress);
17137 }
17138
17139 var type = workInProgress.type;
17140 var nextProps = workInProgress.pendingProps;
17141 var prevProps = current$$1 !== null ? current$$1.memoizedProps : null;
17142
17143 var nextChildren = nextProps.children;
17144 var isDirectTextChild = shouldSetTextContent(type, nextProps);
17145
17146 if (isDirectTextChild) {
17147 // We special case a direct text child of a host node. This is a common
17148 // case. We won't handle it as a reified child. We will instead handle
17149 // this in the host environment that also have access to this prop. That
17150 // avoids allocating another HostText fiber and traversing it.
17151 nextChildren = null;
17152 } else if (prevProps !== null && shouldSetTextContent(type, prevProps)) {
17153 // If we're switching from a direct text child to a normal child, or to
17154 // empty, we need to schedule the text content to be reset.
17155 workInProgress.effectTag |= ContentReset;
17156 }
17157
17158 markRef(current$$1, workInProgress);
17159
17160 // Check the host config to see if the children are offscreen/hidden.
17161 if (workInProgress.mode & ConcurrentMode && renderExpirationTime !== Never && shouldDeprioritizeSubtree(type, nextProps)) {
17162 if (enableSchedulerTracing) {
17163 markSpawnedWork(Never);
17164 }
17165 // Schedule this fiber to re-render at offscreen priority. Then bailout.
17166 workInProgress.expirationTime = workInProgress.childExpirationTime = Never;
17167 return null;
17168 }
17169
17170 reconcileChildren(current$$1, workInProgress, nextChildren, renderExpirationTime);
17171 return workInProgress.child;
17172}
17173
17174function updateHostText(current$$1, workInProgress) {
17175 if (current$$1 === null) {
17176 tryToClaimNextHydratableInstance(workInProgress);
17177 }
17178 // Nothing to do here. This is terminal. We'll do the completion step
17179 // immediately after.
17180 return null;
17181}
17182
17183function mountLazyComponent(_current, workInProgress, elementType, updateExpirationTime, renderExpirationTime) {
17184 if (_current !== null) {
17185 // An lazy component only mounts if it suspended inside a non-
17186 // concurrent tree, in an inconsistent state. We want to treat it like
17187 // a new mount, even though an empty version of it already committed.
17188 // Disconnect the alternate pointers.
17189 _current.alternate = null;
17190 workInProgress.alternate = null;
17191 // Since this is conceptually a new fiber, schedule a Placement effect
17192 workInProgress.effectTag |= Placement;
17193 }
17194
17195 var props = workInProgress.pendingProps;
17196 // We can't start a User Timing measurement with correct label yet.
17197 // Cancel and resume right after we know the tag.
17198 cancelWorkTimer(workInProgress);
17199 var Component = readLazyComponentType(elementType);
17200 // Store the unwrapped component in the type.
17201 workInProgress.type = Component;
17202 var resolvedTag = workInProgress.tag = resolveLazyComponentTag(Component);
17203 startWorkTimer(workInProgress);
17204 var resolvedProps = resolveDefaultProps(Component, props);
17205 var child = void 0;
17206 switch (resolvedTag) {
17207 case FunctionComponent:
17208 {
17209 {
17210 validateFunctionComponentInDev(workInProgress, Component);
17211 workInProgress.type = Component = resolveFunctionForHotReloading(Component);
17212 }
17213 child = updateFunctionComponent(null, workInProgress, Component, resolvedProps, renderExpirationTime);
17214 break;
17215 }
17216 case ClassComponent:
17217 {
17218 {
17219 workInProgress.type = Component = resolveClassForHotReloading(Component);
17220 }
17221 child = updateClassComponent(null, workInProgress, Component, resolvedProps, renderExpirationTime);
17222 break;
17223 }
17224 case ForwardRef:
17225 {
17226 {
17227 workInProgress.type = Component = resolveForwardRefForHotReloading(Component);
17228 }
17229 child = updateForwardRef(null, workInProgress, Component, resolvedProps, renderExpirationTime);
17230 break;
17231 }
17232 case MemoComponent:
17233 {
17234 {
17235 if (workInProgress.type !== workInProgress.elementType) {
17236 var outerPropTypes = Component.propTypes;
17237 if (outerPropTypes) {
17238 checkPropTypes(outerPropTypes, resolvedProps, // Resolved for outer only
17239 'prop', getComponentName(Component), getCurrentFiberStackInDev);
17240 }
17241 }
17242 }
17243 child = updateMemoComponent(null, workInProgress, Component, resolveDefaultProps(Component.type, resolvedProps), // The inner type can have defaults too
17244 updateExpirationTime, renderExpirationTime);
17245 break;
17246 }
17247 default:
17248 {
17249 var hint = '';
17250 {
17251 if (Component !== null && typeof Component === 'object' && Component.$$typeof === REACT_LAZY_TYPE) {
17252 hint = ' Did you wrap a component in React.lazy() more than once?';
17253 }
17254 }
17255 // This message intentionally doesn't mention ForwardRef or MemoComponent
17256 // because the fact that it's a separate type of work is an
17257 // implementation detail.
17258 (function () {
17259 {
17260 {
17261 throw ReactError(Error('Element type is invalid. Received a promise that resolves to: ' + Component + '. Lazy element type must resolve to a class or function.' + hint));
17262 }
17263 }
17264 })();
17265 }
17266 }
17267 return child;
17268}
17269
17270function mountIncompleteClassComponent(_current, workInProgress, Component, nextProps, renderExpirationTime) {
17271 if (_current !== null) {
17272 // An incomplete component only mounts if it suspended inside a non-
17273 // concurrent tree, in an inconsistent state. We want to treat it like
17274 // a new mount, even though an empty version of it already committed.
17275 // Disconnect the alternate pointers.
17276 _current.alternate = null;
17277 workInProgress.alternate = null;
17278 // Since this is conceptually a new fiber, schedule a Placement effect
17279 workInProgress.effectTag |= Placement;
17280 }
17281
17282 // Promote the fiber to a class and try rendering again.
17283 workInProgress.tag = ClassComponent;
17284
17285 // The rest of this function is a fork of `updateClassComponent`
17286
17287 // Push context providers early to prevent context stack mismatches.
17288 // During mounting we don't know the child context yet as the instance doesn't exist.
17289 // We will invalidate the child context in finishClassComponent() right after rendering.
17290 var hasContext = void 0;
17291 if (isContextProvider(Component)) {
17292 hasContext = true;
17293 pushContextProvider(workInProgress);
17294 } else {
17295 hasContext = false;
17296 }
17297 prepareToReadContext(workInProgress, renderExpirationTime);
17298
17299 constructClassInstance(workInProgress, Component, nextProps, renderExpirationTime);
17300 mountClassInstance(workInProgress, Component, nextProps, renderExpirationTime);
17301
17302 return finishClassComponent(null, workInProgress, Component, true, hasContext, renderExpirationTime);
17303}
17304
17305function mountIndeterminateComponent(_current, workInProgress, Component, renderExpirationTime) {
17306 if (_current !== null) {
17307 // An indeterminate component only mounts if it suspended inside a non-
17308 // concurrent tree, in an inconsistent state. We want to treat it like
17309 // a new mount, even though an empty version of it already committed.
17310 // Disconnect the alternate pointers.
17311 _current.alternate = null;
17312 workInProgress.alternate = null;
17313 // Since this is conceptually a new fiber, schedule a Placement effect
17314 workInProgress.effectTag |= Placement;
17315 }
17316
17317 var props = workInProgress.pendingProps;
17318 var context = void 0;
17319 if (!disableLegacyContext) {
17320 var unmaskedContext = getUnmaskedContext(workInProgress, Component, false);
17321 context = getMaskedContext(workInProgress, unmaskedContext);
17322 }
17323
17324 prepareToReadContext(workInProgress, renderExpirationTime);
17325 var value = void 0;
17326
17327 {
17328 if (Component.prototype && typeof Component.prototype.render === 'function') {
17329 var componentName = getComponentName(Component) || 'Unknown';
17330
17331 if (!didWarnAboutBadClass[componentName]) {
17332 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);
17333 didWarnAboutBadClass[componentName] = true;
17334 }
17335 }
17336
17337 if (workInProgress.mode & StrictMode) {
17338 ReactStrictModeWarnings.recordLegacyContextWarning(workInProgress, null);
17339 }
17340
17341 ReactCurrentOwner$3.current = workInProgress;
17342 value = renderWithHooks(null, workInProgress, Component, props, context, renderExpirationTime);
17343 }
17344 // React DevTools reads this flag.
17345 workInProgress.effectTag |= PerformedWork;
17346
17347 if (typeof value === 'object' && value !== null && typeof value.render === 'function' && value.$$typeof === undefined) {
17348 {
17349 var _componentName = getComponentName(Component) || 'Unknown';
17350 if (!didWarnAboutModulePatternComponent[_componentName]) {
17351 warningWithoutStack$1(false, 'The <%s /> component appears to be a function component that returns a class instance. ' + 'Change %s to a class that extends React.Component instead. ' + "If you can't use a class try assigning the prototype on the function as a workaround. " + "`%s.prototype = React.Component.prototype`. Don't use an arrow function since it " + 'cannot be called with `new` by React.', _componentName, _componentName, _componentName);
17352 didWarnAboutModulePatternComponent[_componentName] = true;
17353 }
17354 }
17355
17356 // Proceed under the assumption that this is a class instance
17357 workInProgress.tag = ClassComponent;
17358
17359 // Throw out any hooks that were used.
17360 resetHooks();
17361
17362 // Push context providers early to prevent context stack mismatches.
17363 // During mounting we don't know the child context yet as the instance doesn't exist.
17364 // We will invalidate the child context in finishClassComponent() right after rendering.
17365 var hasContext = false;
17366 if (isContextProvider(Component)) {
17367 hasContext = true;
17368 pushContextProvider(workInProgress);
17369 } else {
17370 hasContext = false;
17371 }
17372
17373 workInProgress.memoizedState = value.state !== null && value.state !== undefined ? value.state : null;
17374
17375 var getDerivedStateFromProps = Component.getDerivedStateFromProps;
17376 if (typeof getDerivedStateFromProps === 'function') {
17377 applyDerivedStateFromProps(workInProgress, Component, getDerivedStateFromProps, props);
17378 }
17379
17380 adoptClassInstance(workInProgress, value);
17381 mountClassInstance(workInProgress, Component, props, renderExpirationTime);
17382 return finishClassComponent(null, workInProgress, Component, true, hasContext, renderExpirationTime);
17383 } else {
17384 // Proceed under the assumption that this is a function component
17385 workInProgress.tag = FunctionComponent;
17386 {
17387 if (disableLegacyContext && Component.contextTypes) {
17388 warningWithoutStack$1(false, '%s uses the legacy contextTypes API which is no longer supported. ' + 'Use React.createContext() with React.useContext() instead.', getComponentName(Component) || 'Unknown');
17389 }
17390
17391 if (debugRenderPhaseSideEffects || debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) {
17392 // Only double-render components with Hooks
17393 if (workInProgress.memoizedState !== null) {
17394 value = renderWithHooks(null, workInProgress, Component, props, context, renderExpirationTime);
17395 }
17396 }
17397 }
17398 reconcileChildren(null, workInProgress, value, renderExpirationTime);
17399 {
17400 validateFunctionComponentInDev(workInProgress, Component);
17401 }
17402 return workInProgress.child;
17403 }
17404}
17405
17406function validateFunctionComponentInDev(workInProgress, Component) {
17407 if (Component) {
17408 !!Component.childContextTypes ? warningWithoutStack$1(false, '%s(...): childContextTypes cannot be defined on a function component.', Component.displayName || Component.name || 'Component') : void 0;
17409 }
17410 if (workInProgress.ref !== null) {
17411 var info = '';
17412 var ownerName = getCurrentFiberOwnerNameInDevOrNull();
17413 if (ownerName) {
17414 info += '\n\nCheck the render method of `' + ownerName + '`.';
17415 }
17416
17417 var warningKey = ownerName || workInProgress._debugID || '';
17418 var debugSource = workInProgress._debugSource;
17419 if (debugSource) {
17420 warningKey = debugSource.fileName + ':' + debugSource.lineNumber;
17421 }
17422 if (!didWarnAboutFunctionRefs[warningKey]) {
17423 didWarnAboutFunctionRefs[warningKey] = true;
17424 warning$1(false, 'Function components cannot be given refs. ' + 'Attempts to access this ref will fail. ' + 'Did you mean to use React.forwardRef()?%s', info);
17425 }
17426 }
17427
17428 if (warnAboutDefaultPropsOnFunctionComponents && Component.defaultProps !== undefined) {
17429 var componentName = getComponentName(Component) || 'Unknown';
17430
17431 if (!didWarnAboutDefaultPropsOnFunctionComponent[componentName]) {
17432 warningWithoutStack$1(false, '%s: Support for defaultProps will be removed from function components ' + 'in a future major release. Use JavaScript default parameters instead.', componentName);
17433 didWarnAboutDefaultPropsOnFunctionComponent[componentName] = true;
17434 }
17435 }
17436
17437 if (typeof Component.getDerivedStateFromProps === 'function') {
17438 var _componentName2 = getComponentName(Component) || 'Unknown';
17439
17440 if (!didWarnAboutGetDerivedStateOnFunctionComponent[_componentName2]) {
17441 warningWithoutStack$1(false, '%s: Function components do not support getDerivedStateFromProps.', _componentName2);
17442 didWarnAboutGetDerivedStateOnFunctionComponent[_componentName2] = true;
17443 }
17444 }
17445
17446 if (typeof Component.contextType === 'object' && Component.contextType !== null) {
17447 var _componentName3 = getComponentName(Component) || 'Unknown';
17448
17449 if (!didWarnAboutContextTypeOnFunctionComponent[_componentName3]) {
17450 warningWithoutStack$1(false, '%s: Function components do not support contextType.', _componentName3);
17451 didWarnAboutContextTypeOnFunctionComponent[_componentName3] = true;
17452 }
17453 }
17454}
17455
17456// TODO: This is now an empty object. Should we just make it a boolean?
17457var SUSPENDED_MARKER = {};
17458
17459function shouldRemainOnFallback(suspenseContext, current$$1, workInProgress) {
17460 // If the context is telling us that we should show a fallback, and we're not
17461 // already showing content, then we should show the fallback instead.
17462 return hasSuspenseContext(suspenseContext, ForceSuspenseFallback) && (current$$1 === null || current$$1.memoizedState !== null);
17463}
17464
17465function updateSuspenseComponent(current$$1, workInProgress, renderExpirationTime) {
17466 var mode = workInProgress.mode;
17467 var nextProps = workInProgress.pendingProps;
17468
17469 // This is used by DevTools to force a boundary to suspend.
17470 {
17471 if (shouldSuspend(workInProgress)) {
17472 workInProgress.effectTag |= DidCapture;
17473 }
17474 }
17475
17476 var suspenseContext = suspenseStackCursor.current;
17477
17478 var nextState = null;
17479 var nextDidTimeout = false;
17480
17481 if ((workInProgress.effectTag & DidCapture) !== NoEffect || shouldRemainOnFallback(suspenseContext, current$$1, workInProgress)) {
17482 // Something in this boundary's subtree already suspended. Switch to
17483 // rendering the fallback children.
17484 nextState = SUSPENDED_MARKER;
17485 nextDidTimeout = true;
17486 workInProgress.effectTag &= ~DidCapture;
17487 } else {
17488 // Attempting the main content
17489 if (current$$1 === null || current$$1.memoizedState !== null) {
17490 // This is a new mount or this boundary is already showing a fallback state.
17491 // Mark this subtree context as having at least one invisible parent that could
17492 // handle the fallback state.
17493 // Boundaries without fallbacks or should be avoided are not considered since
17494 // they cannot handle preferred fallback states.
17495 if (nextProps.fallback !== undefined && nextProps.unstable_avoidThisFallback !== true) {
17496 suspenseContext = addSubtreeSuspenseContext(suspenseContext, InvisibleParentSuspenseContext);
17497 }
17498 }
17499 }
17500
17501 suspenseContext = setDefaultShallowSuspenseContext(suspenseContext);
17502
17503 pushSuspenseContext(workInProgress, suspenseContext);
17504
17505 {
17506 if ('maxDuration' in nextProps) {
17507 if (!didWarnAboutMaxDuration) {
17508 didWarnAboutMaxDuration = true;
17509 warning$1(false, 'maxDuration has been removed from React. ' + 'Remove the maxDuration prop.');
17510 }
17511 }
17512 }
17513
17514 // This next part is a bit confusing. If the children timeout, we switch to
17515 // showing the fallback children in place of the "primary" children.
17516 // However, we don't want to delete the primary children because then their
17517 // state will be lost (both the React state and the host state, e.g.
17518 // uncontrolled form inputs). Instead we keep them mounted and hide them.
17519 // Both the fallback children AND the primary children are rendered at the
17520 // same time. Once the primary children are un-suspended, we can delete
17521 // the fallback children — don't need to preserve their state.
17522 //
17523 // The two sets of children are siblings in the host environment, but
17524 // semantically, for purposes of reconciliation, they are two separate sets.
17525 // So we store them using two fragment fibers.
17526 //
17527 // However, we want to avoid allocating extra fibers for every placeholder.
17528 // They're only necessary when the children time out, because that's the
17529 // only time when both sets are mounted.
17530 //
17531 // So, the extra fragment fibers are only used if the children time out.
17532 // Otherwise, we render the primary children directly. This requires some
17533 // custom reconciliation logic to preserve the state of the primary
17534 // children. It's essentially a very basic form of re-parenting.
17535
17536 // `child` points to the child fiber. In the normal case, this is the first
17537 // fiber of the primary children set. In the timed-out case, it's a
17538 // a fragment fiber containing the primary children.
17539 var child = void 0;
17540 // `next` points to the next fiber React should render. In the normal case,
17541 // it's the same as `child`: the first fiber of the primary children set.
17542 // In the timed-out case, it's a fragment fiber containing the *fallback*
17543 // children -- we skip over the primary children entirely.
17544 var next = void 0;
17545 if (current$$1 === null) {
17546 if (enableSuspenseServerRenderer) {
17547 // If we're currently hydrating, try to hydrate this boundary.
17548 // But only if this has a fallback.
17549 if (nextProps.fallback !== undefined) {
17550 tryToClaimNextHydratableInstance(workInProgress);
17551 // This could've changed the tag if this was a dehydrated suspense component.
17552 if (workInProgress.tag === DehydratedSuspenseComponent) {
17553 popSuspenseContext(workInProgress);
17554 return updateDehydratedSuspenseComponent(null, workInProgress, renderExpirationTime);
17555 }
17556 }
17557 }
17558
17559 // This is the initial mount. This branch is pretty simple because there's
17560 // no previous state that needs to be preserved.
17561 if (nextDidTimeout) {
17562 // Mount separate fragments for primary and fallback children.
17563 var nextFallbackChildren = nextProps.fallback;
17564 var primaryChildFragment = createFiberFromFragment(null, mode, NoWork, null);
17565 primaryChildFragment.return = workInProgress;
17566
17567 if ((workInProgress.mode & BatchedMode) === NoMode) {
17568 // Outside of batched mode, we commit the effects from the
17569 var progressedState = workInProgress.memoizedState;
17570 var progressedPrimaryChild = progressedState !== null ? workInProgress.child.child : workInProgress.child;
17571 primaryChildFragment.child = progressedPrimaryChild;
17572 var progressedChild = progressedPrimaryChild;
17573 while (progressedChild !== null) {
17574 progressedChild.return = primaryChildFragment;
17575 progressedChild = progressedChild.sibling;
17576 }
17577 }
17578
17579 var fallbackChildFragment = createFiberFromFragment(nextFallbackChildren, mode, renderExpirationTime, null);
17580 fallbackChildFragment.return = workInProgress;
17581 primaryChildFragment.sibling = fallbackChildFragment;
17582 child = primaryChildFragment;
17583 // Skip the primary children, and continue working on the
17584 // fallback children.
17585 next = fallbackChildFragment;
17586 } else {
17587 // Mount the primary children without an intermediate fragment fiber.
17588 var nextPrimaryChildren = nextProps.children;
17589 child = next = mountChildFibers(workInProgress, null, nextPrimaryChildren, renderExpirationTime);
17590 }
17591 } else {
17592 // This is an update. This branch is more complicated because we need to
17593 // ensure the state of the primary children is preserved.
17594 var prevState = current$$1.memoizedState;
17595 var prevDidTimeout = prevState !== null;
17596 if (prevDidTimeout) {
17597 // The current tree already timed out. That means each child set is
17598 var currentPrimaryChildFragment = current$$1.child;
17599 var currentFallbackChildFragment = currentPrimaryChildFragment.sibling;
17600 if (nextDidTimeout) {
17601 // Still timed out. Reuse the current primary children by cloning
17602 // its fragment. We're going to skip over these entirely.
17603 var _nextFallbackChildren = nextProps.fallback;
17604 var _primaryChildFragment = createWorkInProgress(currentPrimaryChildFragment, currentPrimaryChildFragment.pendingProps, NoWork);
17605 _primaryChildFragment.return = workInProgress;
17606
17607 if ((workInProgress.mode & BatchedMode) === NoMode) {
17608 // Outside of batched mode, we commit the effects from the
17609 var _progressedState = workInProgress.memoizedState;
17610 var _progressedPrimaryChild = _progressedState !== null ? workInProgress.child.child : workInProgress.child;
17611 if (_progressedPrimaryChild !== currentPrimaryChildFragment.child) {
17612 _primaryChildFragment.child = _progressedPrimaryChild;
17613 var _progressedChild = _progressedPrimaryChild;
17614 while (_progressedChild !== null) {
17615 _progressedChild.return = _primaryChildFragment;
17616 _progressedChild = _progressedChild.sibling;
17617 }
17618 }
17619 }
17620
17621 // Because primaryChildFragment is a new fiber that we're inserting as the
17622 // parent of a new tree, we need to set its treeBaseDuration.
17623 if (enableProfilerTimer && workInProgress.mode & ProfileMode) {
17624 // treeBaseDuration is the sum of all the child tree base durations.
17625 var treeBaseDuration = 0;
17626 var hiddenChild = _primaryChildFragment.child;
17627 while (hiddenChild !== null) {
17628 treeBaseDuration += hiddenChild.treeBaseDuration;
17629 hiddenChild = hiddenChild.sibling;
17630 }
17631 _primaryChildFragment.treeBaseDuration = treeBaseDuration;
17632 }
17633
17634 // Clone the fallback child fragment, too. These we'll continue
17635 // working on.
17636 var _fallbackChildFragment = createWorkInProgress(currentFallbackChildFragment, _nextFallbackChildren, currentFallbackChildFragment.expirationTime);
17637 _fallbackChildFragment.return = workInProgress;
17638 _primaryChildFragment.sibling = _fallbackChildFragment;
17639 child = _primaryChildFragment;
17640 _primaryChildFragment.childExpirationTime = NoWork;
17641 // Skip the primary children, and continue working on the
17642 // fallback children.
17643 next = _fallbackChildFragment;
17644 } else {
17645 // No longer suspended. Switch back to showing the primary children,
17646 // and remove the intermediate fragment fiber.
17647 var _nextPrimaryChildren = nextProps.children;
17648 var currentPrimaryChild = currentPrimaryChildFragment.child;
17649 var primaryChild = reconcileChildFibers(workInProgress, currentPrimaryChild, _nextPrimaryChildren, renderExpirationTime);
17650
17651 // If this render doesn't suspend, we need to delete the fallback
17652 // children. Wait until the complete phase, after we've confirmed the
17653 // fallback is no longer needed.
17654 // TODO: Would it be better to store the fallback fragment on
17655 // the stateNode?
17656
17657 // Continue rendering the children, like we normally do.
17658 child = next = primaryChild;
17659 }
17660 } else {
17661 // The current tree has not already timed out. That means the primary
17662 // children are not wrapped in a fragment fiber.
17663 var _currentPrimaryChild = current$$1.child;
17664 if (nextDidTimeout) {
17665 // Timed out. Wrap the children in a fragment fiber to keep them
17666 // separate from the fallback children.
17667 var _nextFallbackChildren2 = nextProps.fallback;
17668 var _primaryChildFragment2 = createFiberFromFragment(
17669 // It shouldn't matter what the pending props are because we aren't
17670 // going to render this fragment.
17671 null, mode, NoWork, null);
17672 _primaryChildFragment2.return = workInProgress;
17673 _primaryChildFragment2.child = _currentPrimaryChild;
17674 if (_currentPrimaryChild !== null) {
17675 _currentPrimaryChild.return = _primaryChildFragment2;
17676 }
17677
17678 // Even though we're creating a new fiber, there are no new children,
17679 // because we're reusing an already mounted tree. So we don't need to
17680 // schedule a placement.
17681 // primaryChildFragment.effectTag |= Placement;
17682
17683 if ((workInProgress.mode & BatchedMode) === NoMode) {
17684 // Outside of batched mode, we commit the effects from the
17685 var _progressedState2 = workInProgress.memoizedState;
17686 var _progressedPrimaryChild2 = _progressedState2 !== null ? workInProgress.child.child : workInProgress.child;
17687 _primaryChildFragment2.child = _progressedPrimaryChild2;
17688 var _progressedChild2 = _progressedPrimaryChild2;
17689 while (_progressedChild2 !== null) {
17690 _progressedChild2.return = _primaryChildFragment2;
17691 _progressedChild2 = _progressedChild2.sibling;
17692 }
17693 }
17694
17695 // Because primaryChildFragment is a new fiber that we're inserting as the
17696 // parent of a new tree, we need to set its treeBaseDuration.
17697 if (enableProfilerTimer && workInProgress.mode & ProfileMode) {
17698 // treeBaseDuration is the sum of all the child tree base durations.
17699 var _treeBaseDuration = 0;
17700 var _hiddenChild = _primaryChildFragment2.child;
17701 while (_hiddenChild !== null) {
17702 _treeBaseDuration += _hiddenChild.treeBaseDuration;
17703 _hiddenChild = _hiddenChild.sibling;
17704 }
17705 _primaryChildFragment2.treeBaseDuration = _treeBaseDuration;
17706 }
17707
17708 // Create a fragment from the fallback children, too.
17709 var _fallbackChildFragment2 = createFiberFromFragment(_nextFallbackChildren2, mode, renderExpirationTime, null);
17710 _fallbackChildFragment2.return = workInProgress;
17711 _primaryChildFragment2.sibling = _fallbackChildFragment2;
17712 _fallbackChildFragment2.effectTag |= Placement;
17713 child = _primaryChildFragment2;
17714 _primaryChildFragment2.childExpirationTime = NoWork;
17715 // Skip the primary children, and continue working on the
17716 // fallback children.
17717 next = _fallbackChildFragment2;
17718 } else {
17719 // Still haven't timed out. Continue rendering the children, like we
17720 // normally do.
17721 var _nextPrimaryChildren2 = nextProps.children;
17722 next = child = reconcileChildFibers(workInProgress, _currentPrimaryChild, _nextPrimaryChildren2, renderExpirationTime);
17723 }
17724 }
17725 workInProgress.stateNode = current$$1.stateNode;
17726 }
17727
17728 workInProgress.memoizedState = nextState;
17729 workInProgress.child = child;
17730 return next;
17731}
17732
17733function retrySuspenseComponentWithoutHydrating(current$$1, workInProgress, renderExpirationTime) {
17734 // Detach from the current dehydrated boundary.
17735 current$$1.alternate = null;
17736 workInProgress.alternate = null;
17737
17738 // Insert a deletion in the effect list.
17739 var returnFiber = workInProgress.return;
17740 (function () {
17741 if (!(returnFiber !== null)) {
17742 {
17743 throw ReactError(Error('Suspense boundaries are never on the root. This is probably a bug in React.'));
17744 }
17745 }
17746 })();
17747 var last = returnFiber.lastEffect;
17748 if (last !== null) {
17749 last.nextEffect = current$$1;
17750 returnFiber.lastEffect = current$$1;
17751 } else {
17752 returnFiber.firstEffect = returnFiber.lastEffect = current$$1;
17753 }
17754 current$$1.nextEffect = null;
17755 current$$1.effectTag = Deletion;
17756
17757 popSuspenseContext(workInProgress);
17758
17759 // Upgrade this work in progress to a real Suspense component.
17760 workInProgress.tag = SuspenseComponent;
17761 workInProgress.stateNode = null;
17762 workInProgress.memoizedState = null;
17763 // This is now an insertion.
17764 workInProgress.effectTag |= Placement;
17765 // Retry as a real Suspense component.
17766 return updateSuspenseComponent(null, workInProgress, renderExpirationTime);
17767}
17768
17769function updateDehydratedSuspenseComponent(current$$1, workInProgress, renderExpirationTime) {
17770 pushSuspenseContext(workInProgress, setDefaultShallowSuspenseContext(suspenseStackCursor.current));
17771 var suspenseInstance = workInProgress.stateNode;
17772 if (current$$1 === null) {
17773 // During the first pass, we'll bail out and not drill into the children.
17774 // Instead, we'll leave the content in place and try to hydrate it later.
17775 if (isSuspenseInstanceFallback(suspenseInstance)) {
17776 // This is a client-only boundary. Since we won't get any content from the server
17777 // for this, we need to schedule that at a higher priority based on when it would
17778 // have timed out. In theory we could render it in this pass but it would have the
17779 // wrong priority associated with it and will prevent hydration of parent path.
17780 // Instead, we'll leave work left on it to render it in a separate commit.
17781
17782 // TODO This time should be the time at which the server rendered response that is
17783 // a parent to this boundary was displayed. However, since we currently don't have
17784 // a protocol to transfer that time, we'll just estimate it by using the current
17785 // time. This will mean that Suspense timeouts are slightly shifted to later than
17786 // they should be.
17787 var serverDisplayTime = requestCurrentTime();
17788 // Schedule a normal pri update to render this content.
17789 workInProgress.expirationTime = computeAsyncExpiration(serverDisplayTime);
17790 } else {
17791 // We'll continue hydrating the rest at offscreen priority since we'll already
17792 // be showing the right content coming from the server, it is no rush.
17793 workInProgress.expirationTime = Never;
17794 }
17795 return null;
17796 }
17797 if ((workInProgress.effectTag & DidCapture) !== NoEffect) {
17798 // Something suspended. Leave the existing children in place.
17799 // TODO: In non-concurrent mode, should we commit the nodes we have hydrated so far?
17800 workInProgress.child = null;
17801 return null;
17802 }
17803 if (isSuspenseInstanceFallback(suspenseInstance)) {
17804 // This boundary is in a permanent fallback state. In this case, we'll never
17805 // get an update and we'll never be able to hydrate the final content. Let's just try the
17806 // client side render instead.
17807 return retrySuspenseComponentWithoutHydrating(current$$1, workInProgress, renderExpirationTime);
17808 }
17809 // We use childExpirationTime to indicate that a child might depend on context, so if
17810 // any context has changed, we need to treat is as if the input might have changed.
17811 var hasContextChanged$$1 = current$$1.childExpirationTime >= renderExpirationTime;
17812 if (didReceiveUpdate || hasContextChanged$$1) {
17813 // This boundary has changed since the first render. This means that we are now unable to
17814 // hydrate it. We might still be able to hydrate it using an earlier expiration time but
17815 // during this render we can't. Instead, we're going to delete the whole subtree and
17816 // instead inject a new real Suspense boundary to take its place, which may render content
17817 // or fallback. The real Suspense boundary will suspend for a while so we have some time
17818 // to ensure it can produce real content, but all state and pending events will be lost.
17819 return retrySuspenseComponentWithoutHydrating(current$$1, workInProgress, renderExpirationTime);
17820 } else if (isSuspenseInstancePending(suspenseInstance)) {
17821 // This component is still pending more data from the server, so we can't hydrate its
17822 // content. We treat it as if this component suspended itself. It might seem as if
17823 // we could just try to render it client-side instead. However, this will perform a
17824 // lot of unnecessary work and is unlikely to complete since it often will suspend
17825 // on missing data anyway. Additionally, the server might be able to render more
17826 // than we can on the client yet. In that case we'd end up with more fallback states
17827 // on the client than if we just leave it alone. If the server times out or errors
17828 // these should update this boundary to the permanent Fallback state instead.
17829 // Mark it as having captured (i.e. suspended).
17830 workInProgress.effectTag |= DidCapture;
17831 // Leave the children in place. I.e. empty.
17832 workInProgress.child = null;
17833 // Register a callback to retry this boundary once the server has sent the result.
17834 registerSuspenseInstanceRetry(suspenseInstance, retryTimedOutBoundary.bind(null, current$$1));
17835 return null;
17836 } else {
17837 // This is the first attempt.
17838 reenterHydrationStateFromDehydratedSuspenseInstance(workInProgress);
17839 var nextProps = workInProgress.pendingProps;
17840 var nextChildren = nextProps.children;
17841 workInProgress.child = mountChildFibers(workInProgress, null, nextChildren, renderExpirationTime);
17842 return workInProgress.child;
17843 }
17844}
17845
17846function propagateSuspenseContextChange(workInProgress, firstChild, renderExpirationTime) {
17847 // Mark any Suspense boundaries with fallbacks as having work to do.
17848 // If they were previously forced into fallbacks, they may now be able
17849 // to unblock.
17850 var node = firstChild;
17851 while (node !== null) {
17852 if (node.tag === SuspenseComponent) {
17853 var state = node.memoizedState;
17854 if (state !== null) {
17855 if (node.expirationTime < renderExpirationTime) {
17856 node.expirationTime = renderExpirationTime;
17857 }
17858 var alternate = node.alternate;
17859 if (alternate !== null && alternate.expirationTime < renderExpirationTime) {
17860 alternate.expirationTime = renderExpirationTime;
17861 }
17862 scheduleWorkOnParentPath(node.return, renderExpirationTime);
17863 }
17864 } else if (node.child !== null) {
17865 node.child.return = node;
17866 node = node.child;
17867 continue;
17868 }
17869 if (node === workInProgress) {
17870 return;
17871 }
17872 while (node.sibling === null) {
17873 if (node.return === null || node.return === workInProgress) {
17874 return;
17875 }
17876 node = node.return;
17877 }
17878 node.sibling.return = node.return;
17879 node = node.sibling;
17880 }
17881}
17882
17883function findLastContentRow(firstChild) {
17884 // This is going to find the last row among these children that is already
17885 // showing content on the screen, as opposed to being in fallback state or
17886 // new. If a row has multiple Suspense boundaries, any of them being in the
17887 // fallback state, counts as the whole row being in a fallback state.
17888 // Note that the "rows" will be workInProgress, but any nested children
17889 // will still be current since we haven't rendered them yet. The mounted
17890 // order may not be the same as the new order. We use the new order.
17891 var row = firstChild;
17892 var lastContentRow = null;
17893 while (row !== null) {
17894 var currentRow = row.alternate;
17895 // New rows can't be content rows.
17896 if (currentRow !== null && findFirstSuspended(currentRow) === null) {
17897 lastContentRow = row;
17898 }
17899 row = row.sibling;
17900 }
17901 return lastContentRow;
17902}
17903
17904function validateRevealOrder(revealOrder) {
17905 {
17906 if (revealOrder !== undefined && revealOrder !== 'forwards' && revealOrder !== 'backwards' && revealOrder !== 'together' && !didWarnAboutRevealOrder[revealOrder]) {
17907 didWarnAboutRevealOrder[revealOrder] = true;
17908 if (typeof revealOrder === 'string') {
17909 switch (revealOrder.toLowerCase()) {
17910 case 'together':
17911 case 'forwards':
17912 case 'backwards':
17913 {
17914 warning$1(false, '"%s" is not a valid value for revealOrder on <SuspenseList />. ' + 'Use lowercase "%s" instead.', revealOrder, revealOrder.toLowerCase());
17915 break;
17916 }
17917 case 'forward':
17918 case 'backward':
17919 {
17920 warning$1(false, '"%s" is not a valid value for revealOrder on <SuspenseList />. ' + 'React uses the -s suffix in the spelling. Use "%ss" instead.', revealOrder, revealOrder.toLowerCase());
17921 break;
17922 }
17923 default:
17924 warning$1(false, '"%s" is not a supported revealOrder on <SuspenseList />. ' + 'Did you mean "together", "forwards" or "backwards"?', revealOrder);
17925 break;
17926 }
17927 } else {
17928 warning$1(false, '%s is not a supported value for revealOrder on <SuspenseList />. ' + 'Did you mean "together", "forwards" or "backwards"?', revealOrder);
17929 }
17930 }
17931 }
17932}
17933
17934function validateTailOptions(tailMode, revealOrder) {
17935 {
17936 if (tailMode !== undefined && !didWarnAboutTailOptions[tailMode]) {
17937 if (tailMode !== 'collapsed' && tailMode !== 'hidden') {
17938 didWarnAboutTailOptions[tailMode] = true;
17939 warning$1(false, '"%s" is not a supported value for tail on <SuspenseList />. ' + 'Did you mean "collapsed" or "hidden"?', tailMode);
17940 } else if (revealOrder !== 'forwards' && revealOrder !== 'backwards') {
17941 didWarnAboutTailOptions[tailMode] = true;
17942 warning$1(false, '<SuspenseList tail="%s" /> is only valid if revealOrder is ' + '"forwards" or "backwards". ' + 'Did you mean to specify revealOrder="forwards"?', tailMode);
17943 }
17944 }
17945 }
17946}
17947
17948function validateSuspenseListNestedChild(childSlot, index) {
17949 {
17950 var isArray = Array.isArray(childSlot);
17951 var isIterable = !isArray && typeof getIteratorFn(childSlot) === 'function';
17952 if (isArray || isIterable) {
17953 var type = isArray ? 'array' : 'iterable';
17954 warning$1(false, 'A nested %s was passed to row #%s in <SuspenseList />. Wrap it in ' + 'an additional SuspenseList to configure its revealOrder: ' + '<SuspenseList revealOrder=...> ... ' + '<SuspenseList revealOrder=...>{%s}</SuspenseList> ... ' + '</SuspenseList>', type, index, type);
17955 return false;
17956 }
17957 }
17958 return true;
17959}
17960
17961function validateSuspenseListChildren(children, revealOrder) {
17962 {
17963 if ((revealOrder === 'forwards' || revealOrder === 'backwards') && children !== undefined && children !== null && children !== false) {
17964 if (Array.isArray(children)) {
17965 for (var i = 0; i < children.length; i++) {
17966 if (!validateSuspenseListNestedChild(children[i], i)) {
17967 return;
17968 }
17969 }
17970 } else {
17971 var iteratorFn = getIteratorFn(children);
17972 if (typeof iteratorFn === 'function') {
17973 var childrenIterator = iteratorFn.call(children);
17974 if (childrenIterator) {
17975 var step = childrenIterator.next();
17976 var _i = 0;
17977 for (; !step.done; step = childrenIterator.next()) {
17978 if (!validateSuspenseListNestedChild(step.value, _i)) {
17979 return;
17980 }
17981 _i++;
17982 }
17983 }
17984 } else {
17985 warning$1(false, 'A single row was passed to a <SuspenseList revealOrder="%s" />. ' + 'This is not useful since it needs multiple rows. ' + 'Did you mean to pass multiple children or an array?', revealOrder);
17986 }
17987 }
17988 }
17989 }
17990}
17991
17992function initSuspenseListRenderState(workInProgress, isBackwards, tail, lastContentRow, tailMode) {
17993 var renderState = workInProgress.memoizedState;
17994 if (renderState === null) {
17995 workInProgress.memoizedState = {
17996 isBackwards: isBackwards,
17997 rendering: null,
17998 last: lastContentRow,
17999 tail: tail,
18000 tailExpiration: 0,
18001 tailMode: tailMode
18002 };
18003 } else {
18004 // We can reuse the existing object from previous renders.
18005 renderState.isBackwards = isBackwards;
18006 renderState.rendering = null;
18007 renderState.last = lastContentRow;
18008 renderState.tail = tail;
18009 renderState.tailExpiration = 0;
18010 renderState.tailMode = tailMode;
18011 }
18012}
18013
18014// This can end up rendering this component multiple passes.
18015// The first pass splits the children fibers into two sets. A head and tail.
18016// We first render the head. If anything is in fallback state, we do another
18017// pass through beginWork to rerender all children (including the tail) with
18018// the force suspend context. If the first render didn't have anything in
18019// in fallback state. Then we render each row in the tail one-by-one.
18020// That happens in the completeWork phase without going back to beginWork.
18021function updateSuspenseListComponent(current$$1, workInProgress, renderExpirationTime) {
18022 var nextProps = workInProgress.pendingProps;
18023 var revealOrder = nextProps.revealOrder;
18024 var tailMode = nextProps.tail;
18025 var newChildren = nextProps.children;
18026
18027 validateRevealOrder(revealOrder);
18028 validateTailOptions(tailMode, revealOrder);
18029 validateSuspenseListChildren(newChildren, revealOrder);
18030
18031 reconcileChildren(current$$1, workInProgress, newChildren, renderExpirationTime);
18032
18033 var suspenseContext = suspenseStackCursor.current;
18034
18035 var shouldForceFallback = hasSuspenseContext(suspenseContext, ForceSuspenseFallback);
18036 if (shouldForceFallback) {
18037 suspenseContext = setShallowSuspenseContext(suspenseContext, ForceSuspenseFallback);
18038 workInProgress.effectTag |= DidCapture;
18039 } else {
18040 var didSuspendBefore = current$$1 !== null && (current$$1.effectTag & DidCapture) !== NoEffect;
18041 if (didSuspendBefore) {
18042 // If we previously forced a fallback, we need to schedule work
18043 // on any nested boundaries to let them know to try to render
18044 // again. This is the same as context updating.
18045 propagateSuspenseContextChange(workInProgress, workInProgress.child, renderExpirationTime);
18046 }
18047 suspenseContext = setDefaultShallowSuspenseContext(suspenseContext);
18048 }
18049 pushSuspenseContext(workInProgress, suspenseContext);
18050
18051 if ((workInProgress.mode & BatchedMode) === NoMode) {
18052 // Outside of batched mode, SuspenseList doesn't work so we just
18053 // use make it a noop by treating it as the default revealOrder.
18054 workInProgress.memoizedState = null;
18055 } else {
18056 switch (revealOrder) {
18057 case 'forwards':
18058 {
18059 var lastContentRow = findLastContentRow(workInProgress.child);
18060 var tail = void 0;
18061 if (lastContentRow === null) {
18062 // The whole list is part of the tail.
18063 // TODO: We could fast path by just rendering the tail now.
18064 tail = workInProgress.child;
18065 workInProgress.child = null;
18066 } else {
18067 // Disconnect the tail rows after the content row.
18068 // We're going to render them separately later.
18069 tail = lastContentRow.sibling;
18070 lastContentRow.sibling = null;
18071 }
18072 initSuspenseListRenderState(workInProgress, false, // isBackwards
18073 tail, lastContentRow, tailMode);
18074 break;
18075 }
18076 case 'backwards':
18077 {
18078 // We're going to find the first row that has existing content.
18079 // At the same time we're going to reverse the list of everything
18080 // we pass in the meantime. That's going to be our tail in reverse
18081 // order.
18082 var _tail = null;
18083 var row = workInProgress.child;
18084 workInProgress.child = null;
18085 while (row !== null) {
18086 var currentRow = row.alternate;
18087 // New rows can't be content rows.
18088 if (currentRow !== null && findFirstSuspended(currentRow) === null) {
18089 // This is the beginning of the main content.
18090 workInProgress.child = row;
18091 break;
18092 }
18093 var nextRow = row.sibling;
18094 row.sibling = _tail;
18095 _tail = row;
18096 row = nextRow;
18097 }
18098 // TODO: If workInProgress.child is null, we can continue on the tail immediately.
18099 initSuspenseListRenderState(workInProgress, true, // isBackwards
18100 _tail, null, // last
18101 tailMode);
18102 break;
18103 }
18104 case 'together':
18105 {
18106 initSuspenseListRenderState(workInProgress, false, // isBackwards
18107 null, // tail
18108 null, // last
18109 undefined);
18110 break;
18111 }
18112 default:
18113 {
18114 // The default reveal order is the same as not having
18115 // a boundary.
18116 workInProgress.memoizedState = null;
18117 }
18118 }
18119 }
18120 return workInProgress.child;
18121}
18122
18123function updatePortalComponent(current$$1, workInProgress, renderExpirationTime) {
18124 pushHostContainer(workInProgress, workInProgress.stateNode.containerInfo);
18125 var nextChildren = workInProgress.pendingProps;
18126 if (current$$1 === null) {
18127 // Portals are special because we don't append the children during mount
18128 // but at commit. Therefore we need to track insertions which the normal
18129 // flow doesn't do during mount. This doesn't happen at the root because
18130 // the root always starts with a "current" with a null child.
18131 // TODO: Consider unifying this with how the root works.
18132 workInProgress.child = reconcileChildFibers(workInProgress, null, nextChildren, renderExpirationTime);
18133 } else {
18134 reconcileChildren(current$$1, workInProgress, nextChildren, renderExpirationTime);
18135 }
18136 return workInProgress.child;
18137}
18138
18139function updateContextProvider(current$$1, workInProgress, renderExpirationTime) {
18140 var providerType = workInProgress.type;
18141 var context = providerType._context;
18142
18143 var newProps = workInProgress.pendingProps;
18144 var oldProps = workInProgress.memoizedProps;
18145
18146 var newValue = newProps.value;
18147
18148 {
18149 var providerPropTypes = workInProgress.type.propTypes;
18150
18151 if (providerPropTypes) {
18152 checkPropTypes(providerPropTypes, newProps, 'prop', 'Context.Provider', getCurrentFiberStackInDev);
18153 }
18154 }
18155
18156 pushProvider(workInProgress, newValue);
18157
18158 if (oldProps !== null) {
18159 var oldValue = oldProps.value;
18160 var changedBits = calculateChangedBits(context, newValue, oldValue);
18161 if (changedBits === 0) {
18162 // No change. Bailout early if children are the same.
18163 if (oldProps.children === newProps.children && !hasContextChanged()) {
18164 return bailoutOnAlreadyFinishedWork(current$$1, workInProgress, renderExpirationTime);
18165 }
18166 } else {
18167 // The context value changed. Search for matching consumers and schedule
18168 // them to update.
18169 propagateContextChange(workInProgress, context, changedBits, renderExpirationTime);
18170 }
18171 }
18172
18173 var newChildren = newProps.children;
18174 reconcileChildren(current$$1, workInProgress, newChildren, renderExpirationTime);
18175 return workInProgress.child;
18176}
18177
18178var hasWarnedAboutUsingContextAsConsumer = false;
18179
18180function updateContextConsumer(current$$1, workInProgress, renderExpirationTime) {
18181 var context = workInProgress.type;
18182 // The logic below for Context differs depending on PROD or DEV mode. In
18183 // DEV mode, we create a separate object for Context.Consumer that acts
18184 // like a proxy to Context. This proxy object adds unnecessary code in PROD
18185 // so we use the old behaviour (Context.Consumer references Context) to
18186 // reduce size and overhead. The separate object references context via
18187 // a property called "_context", which also gives us the ability to check
18188 // in DEV mode if this property exists or not and warn if it does not.
18189 {
18190 if (context._context === undefined) {
18191 // This may be because it's a Context (rather than a Consumer).
18192 // Or it may be because it's older React where they're the same thing.
18193 // We only want to warn if we're sure it's a new React.
18194 if (context !== context.Consumer) {
18195 if (!hasWarnedAboutUsingContextAsConsumer) {
18196 hasWarnedAboutUsingContextAsConsumer = true;
18197 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?');
18198 }
18199 }
18200 } else {
18201 context = context._context;
18202 }
18203 }
18204 var newProps = workInProgress.pendingProps;
18205 var render = newProps.children;
18206
18207 {
18208 !(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;
18209 }
18210
18211 prepareToReadContext(workInProgress, renderExpirationTime);
18212 var newValue = readContext(context, newProps.unstable_observedBits);
18213 var newChildren = void 0;
18214 {
18215 ReactCurrentOwner$3.current = workInProgress;
18216 setCurrentPhase('render');
18217 newChildren = render(newValue);
18218 setCurrentPhase(null);
18219 }
18220
18221 // React DevTools reads this flag.
18222 workInProgress.effectTag |= PerformedWork;
18223 reconcileChildren(current$$1, workInProgress, newChildren, renderExpirationTime);
18224 return workInProgress.child;
18225}
18226
18227function updateFundamentalComponent$1(current$$1, workInProgress, renderExpirationTime) {
18228 var fundamentalImpl = workInProgress.type.impl;
18229 if (fundamentalImpl.reconcileChildren === false) {
18230 return null;
18231 }
18232 var nextProps = workInProgress.pendingProps;
18233 var nextChildren = nextProps.children;
18234
18235 reconcileChildren(current$$1, workInProgress, nextChildren, renderExpirationTime);
18236 return workInProgress.child;
18237}
18238
18239function markWorkInProgressReceivedUpdate() {
18240 didReceiveUpdate = true;
18241}
18242
18243function bailoutOnAlreadyFinishedWork(current$$1, workInProgress, renderExpirationTime) {
18244 cancelWorkTimer(workInProgress);
18245
18246 if (current$$1 !== null) {
18247 // Reuse previous dependencies
18248 workInProgress.dependencies = current$$1.dependencies;
18249 }
18250
18251 if (enableProfilerTimer) {
18252 // Don't update "base" render times for bailouts.
18253 stopProfilerTimerIfRunning(workInProgress);
18254 }
18255
18256 // Check if the children have any pending work.
18257 var childExpirationTime = workInProgress.childExpirationTime;
18258 if (childExpirationTime < renderExpirationTime) {
18259 // The children don't have any work either. We can skip them.
18260 // TODO: Once we add back resuming, we should check if the children are
18261 // a work-in-progress set. If so, we need to transfer their effects.
18262 return null;
18263 } else {
18264 // This fiber doesn't have work, but its subtree does. Clone the child
18265 // fibers and continue.
18266 cloneChildFibers(current$$1, workInProgress);
18267 return workInProgress.child;
18268 }
18269}
18270
18271function remountFiber(current$$1, oldWorkInProgress, newWorkInProgress) {
18272 {
18273 var returnFiber = oldWorkInProgress.return;
18274 if (returnFiber === null) {
18275 throw new Error('Cannot swap the root fiber.');
18276 }
18277
18278 // Disconnect from the old current.
18279 // It will get deleted.
18280 current$$1.alternate = null;
18281 oldWorkInProgress.alternate = null;
18282
18283 // Connect to the new tree.
18284 newWorkInProgress.index = oldWorkInProgress.index;
18285 newWorkInProgress.sibling = oldWorkInProgress.sibling;
18286 newWorkInProgress.return = oldWorkInProgress.return;
18287 newWorkInProgress.ref = oldWorkInProgress.ref;
18288
18289 // Replace the child/sibling pointers above it.
18290 if (oldWorkInProgress === returnFiber.child) {
18291 returnFiber.child = newWorkInProgress;
18292 } else {
18293 var prevSibling = returnFiber.child;
18294 if (prevSibling === null) {
18295 throw new Error('Expected parent to have a child.');
18296 }
18297 while (prevSibling.sibling !== oldWorkInProgress) {
18298 prevSibling = prevSibling.sibling;
18299 if (prevSibling === null) {
18300 throw new Error('Expected to find the previous sibling.');
18301 }
18302 }
18303 prevSibling.sibling = newWorkInProgress;
18304 }
18305
18306 // Delete the old fiber and place the new one.
18307 // Since the old fiber is disconnected, we have to schedule it manually.
18308 var last = returnFiber.lastEffect;
18309 if (last !== null) {
18310 last.nextEffect = current$$1;
18311 returnFiber.lastEffect = current$$1;
18312 } else {
18313 returnFiber.firstEffect = returnFiber.lastEffect = current$$1;
18314 }
18315 current$$1.nextEffect = null;
18316 current$$1.effectTag = Deletion;
18317
18318 newWorkInProgress.effectTag |= Placement;
18319
18320 // Restart work from the new fiber.
18321 return newWorkInProgress;
18322 }
18323}
18324
18325function beginWork$1(current$$1, workInProgress, renderExpirationTime) {
18326 var updateExpirationTime = workInProgress.expirationTime;
18327
18328 {
18329 if (workInProgress._debugNeedsRemount && current$$1 !== null) {
18330 // This will restart the begin phase with a new fiber.
18331 return remountFiber(current$$1, workInProgress, createFiberFromTypeAndProps(workInProgress.type, workInProgress.key, workInProgress.pendingProps, workInProgress._debugOwner || null, workInProgress.mode, workInProgress.expirationTime));
18332 }
18333 }
18334
18335 if (current$$1 !== null) {
18336 var oldProps = current$$1.memoizedProps;
18337 var newProps = workInProgress.pendingProps;
18338
18339 if (oldProps !== newProps || hasContextChanged() || (
18340 // Force a re-render if the implementation changed due to hot reload:
18341 workInProgress.type !== current$$1.type)) {
18342 // If props or context changed, mark the fiber as having performed work.
18343 // This may be unset if the props are determined to be equal later (memo).
18344 didReceiveUpdate = true;
18345 } else if (updateExpirationTime < renderExpirationTime) {
18346 didReceiveUpdate = false;
18347 // This fiber does not have any pending work. Bailout without entering
18348 // the begin phase. There's still some bookkeeping we that needs to be done
18349 // in this optimized path, mostly pushing stuff onto the stack.
18350 switch (workInProgress.tag) {
18351 case HostRoot:
18352 pushHostRootContext(workInProgress);
18353 resetHydrationState();
18354 break;
18355 case HostComponent:
18356 pushHostContext(workInProgress);
18357 if (workInProgress.mode & ConcurrentMode && renderExpirationTime !== Never && shouldDeprioritizeSubtree(workInProgress.type, newProps)) {
18358 if (enableSchedulerTracing) {
18359 markSpawnedWork(Never);
18360 }
18361 // Schedule this fiber to re-render at offscreen priority. Then bailout.
18362 workInProgress.expirationTime = workInProgress.childExpirationTime = Never;
18363 return null;
18364 }
18365 break;
18366 case ClassComponent:
18367 {
18368 var Component = workInProgress.type;
18369 if (isContextProvider(Component)) {
18370 pushContextProvider(workInProgress);
18371 }
18372 break;
18373 }
18374 case HostPortal:
18375 pushHostContainer(workInProgress, workInProgress.stateNode.containerInfo);
18376 break;
18377 case ContextProvider:
18378 {
18379 var newValue = workInProgress.memoizedProps.value;
18380 pushProvider(workInProgress, newValue);
18381 break;
18382 }
18383 case Profiler:
18384 if (enableProfilerTimer) {
18385 workInProgress.effectTag |= Update;
18386 }
18387 break;
18388 case SuspenseComponent:
18389 {
18390 var state = workInProgress.memoizedState;
18391 var didTimeout = state !== null;
18392 if (didTimeout) {
18393 // If this boundary is currently timed out, we need to decide
18394 // whether to retry the primary children, or to skip over it and
18395 // go straight to the fallback. Check the priority of the primary
18396 var primaryChildFragment = workInProgress.child;
18397 var primaryChildExpirationTime = primaryChildFragment.childExpirationTime;
18398 if (primaryChildExpirationTime !== NoWork && primaryChildExpirationTime >= renderExpirationTime) {
18399 // The primary children have pending work. Use the normal path
18400 // to attempt to render the primary children again.
18401 return updateSuspenseComponent(current$$1, workInProgress, renderExpirationTime);
18402 } else {
18403 pushSuspenseContext(workInProgress, setDefaultShallowSuspenseContext(suspenseStackCursor.current));
18404 // The primary children do not have pending work with sufficient
18405 // priority. Bailout.
18406 var child = bailoutOnAlreadyFinishedWork(current$$1, workInProgress, renderExpirationTime);
18407 if (child !== null) {
18408 // The fallback children have pending work. Skip over the
18409 // primary children and work on the fallback.
18410 return child.sibling;
18411 } else {
18412 return null;
18413 }
18414 }
18415 } else {
18416 pushSuspenseContext(workInProgress, setDefaultShallowSuspenseContext(suspenseStackCursor.current));
18417 }
18418 break;
18419 }
18420 case DehydratedSuspenseComponent:
18421 {
18422 if (enableSuspenseServerRenderer) {
18423 pushSuspenseContext(workInProgress, setDefaultShallowSuspenseContext(suspenseStackCursor.current));
18424 // We know that this component will suspend again because if it has
18425 // been unsuspended it has committed as a regular Suspense component.
18426 // If it needs to be retried, it should have work scheduled on it.
18427 workInProgress.effectTag |= DidCapture;
18428 }
18429 break;
18430 }
18431 case SuspenseListComponent:
18432 {
18433 var didSuspendBefore = (current$$1.effectTag & DidCapture) !== NoEffect;
18434
18435 var hasChildWork = workInProgress.childExpirationTime >= renderExpirationTime;
18436
18437 if (didSuspendBefore) {
18438 if (hasChildWork) {
18439 // If something was in fallback state last time, and we have all the
18440 // same children then we're still in progressive loading state.
18441 // Something might get unblocked by state updates or retries in the
18442 // tree which will affect the tail. So we need to use the normal
18443 // path to compute the correct tail.
18444 return updateSuspenseListComponent(current$$1, workInProgress, renderExpirationTime);
18445 }
18446 // If none of the children had any work, that means that none of
18447 // them got retried so they'll still be blocked in the same way
18448 // as before. We can fast bail out.
18449 workInProgress.effectTag |= DidCapture;
18450 }
18451
18452 // If nothing suspended before and we're rendering the same children,
18453 // then the tail doesn't matter. Anything new that suspends will work
18454 // in the "together" mode, so we can continue from the state we had.
18455 var renderState = workInProgress.memoizedState;
18456 if (renderState !== null) {
18457 // Reset to the "together" mode in case we've started a different
18458 // update in the past but didn't complete it.
18459 renderState.rendering = null;
18460 renderState.tail = null;
18461 }
18462 pushSuspenseContext(workInProgress, suspenseStackCursor.current);
18463
18464 if (hasChildWork) {
18465 break;
18466 } else {
18467 // If none of the children had any work, that means that none of
18468 // them got retried so they'll still be blocked in the same way
18469 // as before. We can fast bail out.
18470 return null;
18471 }
18472 }
18473 }
18474 return bailoutOnAlreadyFinishedWork(current$$1, workInProgress, renderExpirationTime);
18475 }
18476 } else {
18477 didReceiveUpdate = false;
18478 }
18479
18480 // Before entering the begin phase, clear the expiration time.
18481 workInProgress.expirationTime = NoWork;
18482
18483 switch (workInProgress.tag) {
18484 case IndeterminateComponent:
18485 {
18486 return mountIndeterminateComponent(current$$1, workInProgress, workInProgress.type, renderExpirationTime);
18487 }
18488 case LazyComponent:
18489 {
18490 var elementType = workInProgress.elementType;
18491 return mountLazyComponent(current$$1, workInProgress, elementType, updateExpirationTime, renderExpirationTime);
18492 }
18493 case FunctionComponent:
18494 {
18495 var _Component = workInProgress.type;
18496 var unresolvedProps = workInProgress.pendingProps;
18497 var resolvedProps = workInProgress.elementType === _Component ? unresolvedProps : resolveDefaultProps(_Component, unresolvedProps);
18498 return updateFunctionComponent(current$$1, workInProgress, _Component, resolvedProps, renderExpirationTime);
18499 }
18500 case ClassComponent:
18501 {
18502 var _Component2 = workInProgress.type;
18503 var _unresolvedProps = workInProgress.pendingProps;
18504 var _resolvedProps = workInProgress.elementType === _Component2 ? _unresolvedProps : resolveDefaultProps(_Component2, _unresolvedProps);
18505 return updateClassComponent(current$$1, workInProgress, _Component2, _resolvedProps, renderExpirationTime);
18506 }
18507 case HostRoot:
18508 return updateHostRoot(current$$1, workInProgress, renderExpirationTime);
18509 case HostComponent:
18510 return updateHostComponent(current$$1, workInProgress, renderExpirationTime);
18511 case HostText:
18512 return updateHostText(current$$1, workInProgress);
18513 case SuspenseComponent:
18514 return updateSuspenseComponent(current$$1, workInProgress, renderExpirationTime);
18515 case HostPortal:
18516 return updatePortalComponent(current$$1, workInProgress, renderExpirationTime);
18517 case ForwardRef:
18518 {
18519 var type = workInProgress.type;
18520 var _unresolvedProps2 = workInProgress.pendingProps;
18521 var _resolvedProps2 = workInProgress.elementType === type ? _unresolvedProps2 : resolveDefaultProps(type, _unresolvedProps2);
18522 return updateForwardRef(current$$1, workInProgress, type, _resolvedProps2, renderExpirationTime);
18523 }
18524 case Fragment:
18525 return updateFragment(current$$1, workInProgress, renderExpirationTime);
18526 case Mode:
18527 return updateMode(current$$1, workInProgress, renderExpirationTime);
18528 case Profiler:
18529 return updateProfiler(current$$1, workInProgress, renderExpirationTime);
18530 case ContextProvider:
18531 return updateContextProvider(current$$1, workInProgress, renderExpirationTime);
18532 case ContextConsumer:
18533 return updateContextConsumer(current$$1, workInProgress, renderExpirationTime);
18534 case MemoComponent:
18535 {
18536 var _type2 = workInProgress.type;
18537 var _unresolvedProps3 = workInProgress.pendingProps;
18538 // Resolve outer props first, then resolve inner props.
18539 var _resolvedProps3 = resolveDefaultProps(_type2, _unresolvedProps3);
18540 {
18541 if (workInProgress.type !== workInProgress.elementType) {
18542 var outerPropTypes = _type2.propTypes;
18543 if (outerPropTypes) {
18544 checkPropTypes(outerPropTypes, _resolvedProps3, // Resolved for outer only
18545 'prop', getComponentName(_type2), getCurrentFiberStackInDev);
18546 }
18547 }
18548 }
18549 _resolvedProps3 = resolveDefaultProps(_type2.type, _resolvedProps3);
18550 return updateMemoComponent(current$$1, workInProgress, _type2, _resolvedProps3, updateExpirationTime, renderExpirationTime);
18551 }
18552 case SimpleMemoComponent:
18553 {
18554 return updateSimpleMemoComponent(current$$1, workInProgress, workInProgress.type, workInProgress.pendingProps, updateExpirationTime, renderExpirationTime);
18555 }
18556 case IncompleteClassComponent:
18557 {
18558 var _Component3 = workInProgress.type;
18559 var _unresolvedProps4 = workInProgress.pendingProps;
18560 var _resolvedProps4 = workInProgress.elementType === _Component3 ? _unresolvedProps4 : resolveDefaultProps(_Component3, _unresolvedProps4);
18561 return mountIncompleteClassComponent(current$$1, workInProgress, _Component3, _resolvedProps4, renderExpirationTime);
18562 }
18563 case DehydratedSuspenseComponent:
18564 {
18565 if (enableSuspenseServerRenderer) {
18566 return updateDehydratedSuspenseComponent(current$$1, workInProgress, renderExpirationTime);
18567 }
18568 break;
18569 }
18570 case SuspenseListComponent:
18571 {
18572 return updateSuspenseListComponent(current$$1, workInProgress, renderExpirationTime);
18573 }
18574 case FundamentalComponent:
18575 {
18576 if (enableFundamentalAPI) {
18577 return updateFundamentalComponent$1(current$$1, workInProgress, renderExpirationTime);
18578 }
18579 break;
18580 }
18581 }
18582 (function () {
18583 {
18584 {
18585 throw ReactError(Error('Unknown unit of work tag. This error is likely caused by a bug in React. Please file an issue.'));
18586 }
18587 }
18588 })();
18589}
18590
18591function createFundamentalStateInstance(currentFiber, props, impl, state) {
18592 return {
18593 currentFiber: currentFiber,
18594 impl: impl,
18595 instance: null,
18596 prevProps: null,
18597 props: props,
18598 state: state
18599 };
18600}
18601
18602var emptyObject = {};
18603var isArray$2 = Array.isArray;
18604
18605function markUpdate(workInProgress) {
18606 // Tag the fiber with an update effect. This turns a Placement into
18607 // a PlacementAndUpdate.
18608 workInProgress.effectTag |= Update;
18609}
18610
18611function markRef$1(workInProgress) {
18612 workInProgress.effectTag |= Ref;
18613}
18614
18615var appendAllChildren = void 0;
18616var updateHostContainer = void 0;
18617var updateHostComponent$1 = void 0;
18618var updateHostText$1 = void 0;
18619if (supportsMutation) {
18620 // Mutation mode
18621
18622 appendAllChildren = function (parent, workInProgress, needsVisibilityToggle, isHidden) {
18623 // We only have the top Fiber that was created but we need recurse down its
18624 // children to find all the terminal nodes.
18625 var node = workInProgress.child;
18626 while (node !== null) {
18627 if (node.tag === HostComponent || node.tag === HostText) {
18628 appendInitialChild(parent, node.stateNode);
18629 } else if (node.tag === FundamentalComponent) {
18630 appendInitialChild(parent, node.stateNode.instance);
18631 } else if (node.tag === HostPortal) {
18632 // If we have a portal child, then we don't want to traverse
18633 // down its children. Instead, we'll get insertions from each child in
18634 // the portal directly.
18635 } else if (node.child !== null) {
18636 node.child.return = node;
18637 node = node.child;
18638 continue;
18639 }
18640 if (node === workInProgress) {
18641 return;
18642 }
18643 while (node.sibling === null) {
18644 if (node.return === null || node.return === workInProgress) {
18645 return;
18646 }
18647 node = node.return;
18648 }
18649 node.sibling.return = node.return;
18650 node = node.sibling;
18651 }
18652 };
18653
18654 updateHostContainer = function (workInProgress) {
18655 // Noop
18656 };
18657 updateHostComponent$1 = function (current, workInProgress, type, newProps, rootContainerInstance) {
18658 // If we have an alternate, that means this is an update and we need to
18659 // schedule a side-effect to do the updates.
18660 var oldProps = current.memoizedProps;
18661 if (oldProps === newProps) {
18662 // In mutation mode, this is sufficient for a bailout because
18663 // we won't touch this node even if children changed.
18664 return;
18665 }
18666
18667 // If we get updated because one of our children updated, we don't
18668 // have newProps so we'll have to reuse them.
18669 // TODO: Split the update API as separate for the props vs. children.
18670 // Even better would be if children weren't special cased at all tho.
18671 var instance = workInProgress.stateNode;
18672 var currentHostContext = getHostContext();
18673 // TODO: Experiencing an error where oldProps is null. Suggests a host
18674 // component is hitting the resume path. Figure out why. Possibly
18675 // related to `hidden`.
18676 var updatePayload = prepareUpdate(instance, type, oldProps, newProps, rootContainerInstance, currentHostContext);
18677 // TODO: Type this specific to this type of component.
18678 workInProgress.updateQueue = updatePayload;
18679 // If the update payload indicates that there is a change or if there
18680 // is a new ref we mark this as an update. All the work is done in commitWork.
18681 if (updatePayload) {
18682 markUpdate(workInProgress);
18683 }
18684 };
18685 updateHostText$1 = function (current, workInProgress, oldText, newText) {
18686 // If the text differs, mark it as an update. All the work in done in commitWork.
18687 if (oldText !== newText) {
18688 markUpdate(workInProgress);
18689 }
18690 };
18691} else if (supportsPersistence) {
18692 // Persistent host tree mode
18693
18694 appendAllChildren = function (parent, workInProgress, needsVisibilityToggle, isHidden) {
18695 // We only have the top Fiber that was created but we need recurse down its
18696 // children to find all the terminal nodes.
18697 var node = workInProgress.child;
18698 while (node !== null) {
18699 // eslint-disable-next-line no-labels
18700 branches: if (node.tag === HostComponent) {
18701 var instance = node.stateNode;
18702 if (needsVisibilityToggle && isHidden) {
18703 // This child is inside a timed out tree. Hide it.
18704 var props = node.memoizedProps;
18705 var type = node.type;
18706 instance = cloneHiddenInstance(instance, type, props, node);
18707 }
18708 appendInitialChild(parent, instance);
18709 } else if (node.tag === HostText) {
18710 var _instance = node.stateNode;
18711 if (needsVisibilityToggle && isHidden) {
18712 // This child is inside a timed out tree. Hide it.
18713 var text = node.memoizedProps;
18714 _instance = cloneHiddenTextInstance(_instance, text, node);
18715 }
18716 appendInitialChild(parent, _instance);
18717 } else if (enableFundamentalAPI && node.tag === FundamentalComponent) {
18718 var _instance2 = node.stateNode.instance;
18719 if (needsVisibilityToggle && isHidden) {
18720 // This child is inside a timed out tree. Hide it.
18721 var _props = node.memoizedProps;
18722 var _type = node.type;
18723 _instance2 = cloneHiddenInstance(_instance2, _type, _props, node);
18724 }
18725 appendInitialChild(parent, _instance2);
18726 } else if (node.tag === HostPortal) {
18727 // If we have a portal child, then we don't want to traverse
18728 // down its children. Instead, we'll get insertions from each child in
18729 // the portal directly.
18730 } else if (node.tag === SuspenseComponent) {
18731 if ((node.effectTag & Update) !== NoEffect) {
18732 // Need to toggle the visibility of the primary children.
18733 var newIsHidden = node.memoizedState !== null;
18734 if (newIsHidden) {
18735 var primaryChildParent = node.child;
18736 if (primaryChildParent !== null) {
18737 if (primaryChildParent.child !== null) {
18738 primaryChildParent.child.return = primaryChildParent;
18739 appendAllChildren(parent, primaryChildParent, true, newIsHidden);
18740 }
18741 var fallbackChildParent = primaryChildParent.sibling;
18742 if (fallbackChildParent !== null) {
18743 fallbackChildParent.return = node;
18744 node = fallbackChildParent;
18745 continue;
18746 }
18747 }
18748 }
18749 }
18750 if (node.child !== null) {
18751 // Continue traversing like normal
18752 node.child.return = node;
18753 node = node.child;
18754 continue;
18755 }
18756 } else if (node.child !== null) {
18757 node.child.return = node;
18758 node = node.child;
18759 continue;
18760 }
18761 // $FlowFixMe This is correct but Flow is confused by the labeled break.
18762 node = node;
18763 if (node === workInProgress) {
18764 return;
18765 }
18766 while (node.sibling === null) {
18767 if (node.return === null || node.return === workInProgress) {
18768 return;
18769 }
18770 node = node.return;
18771 }
18772 node.sibling.return = node.return;
18773 node = node.sibling;
18774 }
18775 };
18776
18777 // An unfortunate fork of appendAllChildren because we have two different parent types.
18778 var appendAllChildrenToContainer = function (containerChildSet, workInProgress, needsVisibilityToggle, isHidden) {
18779 // We only have the top Fiber that was created but we need recurse down its
18780 // children to find all the terminal nodes.
18781 var node = workInProgress.child;
18782 while (node !== null) {
18783 // eslint-disable-next-line no-labels
18784 branches: if (node.tag === HostComponent) {
18785 var instance = node.stateNode;
18786 if (needsVisibilityToggle && isHidden) {
18787 // This child is inside a timed out tree. Hide it.
18788 var props = node.memoizedProps;
18789 var type = node.type;
18790 instance = cloneHiddenInstance(instance, type, props, node);
18791 }
18792 appendChildToContainerChildSet(containerChildSet, instance);
18793 } else if (node.tag === HostText) {
18794 var _instance3 = node.stateNode;
18795 if (needsVisibilityToggle && isHidden) {
18796 // This child is inside a timed out tree. Hide it.
18797 var text = node.memoizedProps;
18798 _instance3 = cloneHiddenTextInstance(_instance3, text, node);
18799 }
18800 appendChildToContainerChildSet(containerChildSet, _instance3);
18801 } else if (enableFundamentalAPI && node.tag === FundamentalComponent) {
18802 var _instance4 = node.stateNode.instance;
18803 if (needsVisibilityToggle && isHidden) {
18804 // This child is inside a timed out tree. Hide it.
18805 var _props2 = node.memoizedProps;
18806 var _type2 = node.type;
18807 _instance4 = cloneHiddenInstance(_instance4, _type2, _props2, node);
18808 }
18809 appendChildToContainerChildSet(containerChildSet, _instance4);
18810 } else if (node.tag === HostPortal) {
18811 // If we have a portal child, then we don't want to traverse
18812 // down its children. Instead, we'll get insertions from each child in
18813 // the portal directly.
18814 } else if (node.tag === SuspenseComponent) {
18815 if ((node.effectTag & Update) !== NoEffect) {
18816 // Need to toggle the visibility of the primary children.
18817 var newIsHidden = node.memoizedState !== null;
18818 if (newIsHidden) {
18819 var primaryChildParent = node.child;
18820 if (primaryChildParent !== null) {
18821 if (primaryChildParent.child !== null) {
18822 primaryChildParent.child.return = primaryChildParent;
18823 appendAllChildrenToContainer(containerChildSet, primaryChildParent, true, newIsHidden);
18824 }
18825 var fallbackChildParent = primaryChildParent.sibling;
18826 if (fallbackChildParent !== null) {
18827 fallbackChildParent.return = node;
18828 node = fallbackChildParent;
18829 continue;
18830 }
18831 }
18832 }
18833 }
18834 if (node.child !== null) {
18835 // Continue traversing like normal
18836 node.child.return = node;
18837 node = node.child;
18838 continue;
18839 }
18840 } else if (node.child !== null) {
18841 node.child.return = node;
18842 node = node.child;
18843 continue;
18844 }
18845 // $FlowFixMe This is correct but Flow is confused by the labeled break.
18846 node = node;
18847 if (node === workInProgress) {
18848 return;
18849 }
18850 while (node.sibling === null) {
18851 if (node.return === null || node.return === workInProgress) {
18852 return;
18853 }
18854 node = node.return;
18855 }
18856 node.sibling.return = node.return;
18857 node = node.sibling;
18858 }
18859 };
18860 updateHostContainer = function (workInProgress) {
18861 var portalOrRoot = workInProgress.stateNode;
18862 var childrenUnchanged = workInProgress.firstEffect === null;
18863 if (childrenUnchanged) {
18864 // No changes, just reuse the existing instance.
18865 } else {
18866 var container = portalOrRoot.containerInfo;
18867 var newChildSet = createContainerChildSet(container);
18868 // If children might have changed, we have to add them all to the set.
18869 appendAllChildrenToContainer(newChildSet, workInProgress, false, false);
18870 portalOrRoot.pendingChildren = newChildSet;
18871 // Schedule an update on the container to swap out the container.
18872 markUpdate(workInProgress);
18873 finalizeContainerChildren(container, newChildSet);
18874 }
18875 };
18876 updateHostComponent$1 = function (current, workInProgress, type, newProps, rootContainerInstance) {
18877 var currentInstance = current.stateNode;
18878 var oldProps = current.memoizedProps;
18879 // If there are no effects associated with this node, then none of our children had any updates.
18880 // This guarantees that we can reuse all of them.
18881 var childrenUnchanged = workInProgress.firstEffect === null;
18882 if (childrenUnchanged && oldProps === newProps) {
18883 // No changes, just reuse the existing instance.
18884 // Note that this might release a previous clone.
18885 workInProgress.stateNode = currentInstance;
18886 return;
18887 }
18888 var recyclableInstance = workInProgress.stateNode;
18889 var currentHostContext = getHostContext();
18890 var updatePayload = null;
18891 if (oldProps !== newProps) {
18892 updatePayload = prepareUpdate(recyclableInstance, type, oldProps, newProps, rootContainerInstance, currentHostContext);
18893 }
18894 if (childrenUnchanged && updatePayload === null) {
18895 // No changes, just reuse the existing instance.
18896 // Note that this might release a previous clone.
18897 workInProgress.stateNode = currentInstance;
18898 return;
18899 }
18900 var newInstance = cloneInstance(currentInstance, updatePayload, type, oldProps, newProps, workInProgress, childrenUnchanged, recyclableInstance);
18901 if (finalizeInitialChildren(newInstance, type, newProps, rootContainerInstance, currentHostContext)) {
18902 markUpdate(workInProgress);
18903 }
18904 workInProgress.stateNode = newInstance;
18905 if (childrenUnchanged) {
18906 // If there are no other effects in this tree, we need to flag this node as having one.
18907 // Even though we're not going to use it for anything.
18908 // Otherwise parents won't know that there are new children to propagate upwards.
18909 markUpdate(workInProgress);
18910 } else {
18911 // If children might have changed, we have to add them all to the set.
18912 appendAllChildren(newInstance, workInProgress, false, false);
18913 }
18914 };
18915 updateHostText$1 = function (current, workInProgress, oldText, newText) {
18916 if (oldText !== newText) {
18917 // If the text content differs, we'll create a new text instance for it.
18918 var rootContainerInstance = getRootHostContainer();
18919 var currentHostContext = getHostContext();
18920 workInProgress.stateNode = createTextInstance(newText, rootContainerInstance, currentHostContext, workInProgress);
18921 // We'll have to mark it as having an effect, even though we won't use the effect for anything.
18922 // This lets the parents know that at least one of their children has changed.
18923 markUpdate(workInProgress);
18924 }
18925 };
18926} else {
18927 // No host operations
18928 updateHostContainer = function (workInProgress) {
18929 // Noop
18930 };
18931 updateHostComponent$1 = function (current, workInProgress, type, newProps, rootContainerInstance) {
18932 // Noop
18933 };
18934 updateHostText$1 = function (current, workInProgress, oldText, newText) {
18935 // Noop
18936 };
18937}
18938
18939function cutOffTailIfNeeded(renderState, hasRenderedATailFallback) {
18940 switch (renderState.tailMode) {
18941 case 'hidden':
18942 {
18943 // Any insertions at the end of the tail list after this point
18944 // should be invisible. If there are already mounted boundaries
18945 // anything before them are not considered for collapsing.
18946 // Therefore we need to go through the whole tail to find if
18947 // there are any.
18948 var tailNode = renderState.tail;
18949 var lastTailNode = null;
18950 while (tailNode !== null) {
18951 if (tailNode.alternate !== null) {
18952 lastTailNode = tailNode;
18953 }
18954 tailNode = tailNode.sibling;
18955 }
18956 // Next we're simply going to delete all insertions after the
18957 // last rendered item.
18958 if (lastTailNode === null) {
18959 // All remaining items in the tail are insertions.
18960 renderState.tail = null;
18961 } else {
18962 // Detach the insertion after the last node that was already
18963 // inserted.
18964 lastTailNode.sibling = null;
18965 }
18966 break;
18967 }
18968 case 'collapsed':
18969 {
18970 // Any insertions at the end of the tail list after this point
18971 // should be invisible. If there are already mounted boundaries
18972 // anything before them are not considered for collapsing.
18973 // Therefore we need to go through the whole tail to find if
18974 // there are any.
18975 var _tailNode = renderState.tail;
18976 var _lastTailNode = null;
18977 while (_tailNode !== null) {
18978 if (_tailNode.alternate !== null) {
18979 _lastTailNode = _tailNode;
18980 }
18981 _tailNode = _tailNode.sibling;
18982 }
18983 // Next we're simply going to delete all insertions after the
18984 // last rendered item.
18985 if (_lastTailNode === null) {
18986 // All remaining items in the tail are insertions.
18987 if (!hasRenderedATailFallback && renderState.tail !== null) {
18988 // We suspended during the head. We want to show at least one
18989 // row at the tail. So we'll keep on and cut off the rest.
18990 renderState.tail.sibling = null;
18991 } else {
18992 renderState.tail = null;
18993 }
18994 } else {
18995 // Detach the insertion after the last node that was already
18996 // inserted.
18997 _lastTailNode.sibling = null;
18998 }
18999 break;
19000 }
19001 }
19002}
19003
19004function completeWork(current, workInProgress, renderExpirationTime) {
19005 var newProps = workInProgress.pendingProps;
19006
19007 switch (workInProgress.tag) {
19008 case IndeterminateComponent:
19009 break;
19010 case LazyComponent:
19011 break;
19012 case SimpleMemoComponent:
19013 case FunctionComponent:
19014 break;
19015 case ClassComponent:
19016 {
19017 var Component = workInProgress.type;
19018 if (isContextProvider(Component)) {
19019 popContext(workInProgress);
19020 }
19021 break;
19022 }
19023 case HostRoot:
19024 {
19025 popHostContainer(workInProgress);
19026 popTopLevelContextObject(workInProgress);
19027 var fiberRoot = workInProgress.stateNode;
19028 if (fiberRoot.pendingContext) {
19029 fiberRoot.context = fiberRoot.pendingContext;
19030 fiberRoot.pendingContext = null;
19031 }
19032 if (current === null || current.child === null) {
19033 // If we hydrated, pop so that we can delete any remaining children
19034 // that weren't hydrated.
19035 popHydrationState(workInProgress);
19036 // This resets the hacky state to fix isMounted before committing.
19037 // TODO: Delete this when we delete isMounted and findDOMNode.
19038 workInProgress.effectTag &= ~Placement;
19039 }
19040 updateHostContainer(workInProgress);
19041 break;
19042 }
19043 case HostComponent:
19044 {
19045 popHostContext(workInProgress);
19046 var rootContainerInstance = getRootHostContainer();
19047 var type = workInProgress.type;
19048 if (current !== null && workInProgress.stateNode != null) {
19049 updateHostComponent$1(current, workInProgress, type, newProps, rootContainerInstance);
19050
19051 if (enableFlareAPI) {
19052 var prevListeners = current.memoizedProps.listeners;
19053 var nextListeners = newProps.listeners;
19054 var instance = workInProgress.stateNode;
19055 if (prevListeners !== nextListeners) {
19056 updateEventListeners(nextListeners, instance, rootContainerInstance, workInProgress);
19057 }
19058 }
19059
19060 if (current.ref !== workInProgress.ref) {
19061 markRef$1(workInProgress);
19062 }
19063 } else {
19064 if (!newProps) {
19065 (function () {
19066 if (!(workInProgress.stateNode !== null)) {
19067 {
19068 throw ReactError(Error('We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue.'));
19069 }
19070 }
19071 })();
19072 // This can happen when we abort work.
19073 break;
19074 }
19075
19076 var currentHostContext = getHostContext();
19077 // TODO: Move createInstance to beginWork and keep it on a context
19078 // "stack" as the parent. Then append children as we go in beginWork
19079 // or completeWork depending on we want to add then top->down or
19080 // bottom->up. Top->down is faster in IE11.
19081 var wasHydrated = popHydrationState(workInProgress);
19082 if (wasHydrated) {
19083 // TODO: Move this and createInstance step into the beginPhase
19084 // to consolidate.
19085 if (prepareToHydrateHostInstance(workInProgress, rootContainerInstance, currentHostContext)) {
19086 // If changes to the hydrated node needs to be applied at the
19087 // commit-phase we mark this as such.
19088 markUpdate(workInProgress);
19089 }
19090 } else {
19091 var _instance5 = createInstance(type, newProps, rootContainerInstance, currentHostContext, workInProgress);
19092
19093 appendAllChildren(_instance5, workInProgress, false, false);
19094
19095 if (enableFlareAPI) {
19096 var listeners = newProps.listeners;
19097 if (listeners != null) {
19098 updateEventListeners(listeners, _instance5, rootContainerInstance, workInProgress);
19099 }
19100 }
19101
19102 // Certain renderers require commit-time effects for initial mount.
19103 // (eg DOM renderer supports auto-focus for certain elements).
19104 // Make sure such renderers get scheduled for later work.
19105 if (finalizeInitialChildren(_instance5, type, newProps, rootContainerInstance, currentHostContext)) {
19106 markUpdate(workInProgress);
19107 }
19108 workInProgress.stateNode = _instance5;
19109 }
19110
19111 if (workInProgress.ref !== null) {
19112 // If there is a ref on a host node we need to schedule a callback
19113 markRef$1(workInProgress);
19114 }
19115 }
19116 break;
19117 }
19118 case HostText:
19119 {
19120 var newText = newProps;
19121 if (current && workInProgress.stateNode != null) {
19122 var oldText = current.memoizedProps;
19123 // If we have an alternate, that means this is an update and we need
19124 // to schedule a side-effect to do the updates.
19125 updateHostText$1(current, workInProgress, oldText, newText);
19126 } else {
19127 if (typeof newText !== 'string') {
19128 (function () {
19129 if (!(workInProgress.stateNode !== null)) {
19130 {
19131 throw ReactError(Error('We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue.'));
19132 }
19133 }
19134 })();
19135 // This can happen when we abort work.
19136 }
19137 var _rootContainerInstance = getRootHostContainer();
19138 var _currentHostContext = getHostContext();
19139 var _wasHydrated = popHydrationState(workInProgress);
19140 if (_wasHydrated) {
19141 if (prepareToHydrateHostTextInstance(workInProgress)) {
19142 markUpdate(workInProgress);
19143 }
19144 } else {
19145 workInProgress.stateNode = createTextInstance(newText, _rootContainerInstance, _currentHostContext, workInProgress);
19146 }
19147 }
19148 break;
19149 }
19150 case ForwardRef:
19151 break;
19152 case SuspenseComponent:
19153 {
19154 popSuspenseContext(workInProgress);
19155 var nextState = workInProgress.memoizedState;
19156 if ((workInProgress.effectTag & DidCapture) !== NoEffect) {
19157 // Something suspended. Re-render with the fallback children.
19158 workInProgress.expirationTime = renderExpirationTime;
19159 // Do not reset the effect list.
19160 return workInProgress;
19161 }
19162
19163 var nextDidTimeout = nextState !== null;
19164 var prevDidTimeout = false;
19165 if (current === null) {
19166 // In cases where we didn't find a suitable hydration boundary we never
19167 // downgraded this to a DehydratedSuspenseComponent, but we still need to
19168 // pop the hydration state since we might be inside the insertion tree.
19169 popHydrationState(workInProgress);
19170 } else {
19171 var prevState = current.memoizedState;
19172 prevDidTimeout = prevState !== null;
19173 if (!nextDidTimeout && prevState !== null) {
19174 // We just switched from the fallback to the normal children.
19175 // Delete the fallback.
19176 // TODO: Would it be better to store the fallback fragment on
19177 var currentFallbackChild = current.child.sibling;
19178 if (currentFallbackChild !== null) {
19179 // Deletions go at the beginning of the return fiber's effect list
19180 var first = workInProgress.firstEffect;
19181 if (first !== null) {
19182 workInProgress.firstEffect = currentFallbackChild;
19183 currentFallbackChild.nextEffect = first;
19184 } else {
19185 workInProgress.firstEffect = workInProgress.lastEffect = currentFallbackChild;
19186 currentFallbackChild.nextEffect = null;
19187 }
19188 currentFallbackChild.effectTag = Deletion;
19189 }
19190 }
19191 }
19192
19193 if (nextDidTimeout && !prevDidTimeout) {
19194 // If this subtreee is running in batched mode we can suspend,
19195 // otherwise we won't suspend.
19196 // TODO: This will still suspend a synchronous tree if anything
19197 // in the concurrent tree already suspended during this render.
19198 // This is a known bug.
19199 if ((workInProgress.mode & BatchedMode) !== NoMode) {
19200 // TODO: Move this back to throwException because this is too late
19201 // if this is a large tree which is common for initial loads. We
19202 // don't know if we should restart a render or not until we get
19203 // this marker, and this is too late.
19204 // If this render already had a ping or lower pri updates,
19205 // and this is the first time we know we're going to suspend we
19206 // should be able to immediately restart from within throwException.
19207 var hasInvisibleChildContext = current === null && workInProgress.memoizedProps.unstable_avoidThisFallback !== true;
19208 if (hasInvisibleChildContext || hasSuspenseContext(suspenseStackCursor.current, InvisibleParentSuspenseContext)) {
19209 // If this was in an invisible tree or a new render, then showing
19210 // this boundary is ok.
19211 renderDidSuspend();
19212 } else {
19213 // Otherwise, we're going to have to hide content so we should
19214 // suspend for longer if possible.
19215 renderDidSuspendDelayIfPossible();
19216 }
19217 }
19218 }
19219
19220 if (supportsPersistence) {
19221 // TODO: Only schedule updates if not prevDidTimeout.
19222 if (nextDidTimeout) {
19223 // If this boundary just timed out, schedule an effect to attach a
19224 // retry listener to the proimse. This flag is also used to hide the
19225 // primary children.
19226 workInProgress.effectTag |= Update;
19227 }
19228 }
19229 if (supportsMutation) {
19230 // TODO: Only schedule updates if these values are non equal, i.e. it changed.
19231 if (nextDidTimeout || prevDidTimeout) {
19232 // If this boundary just timed out, schedule an effect to attach a
19233 // retry listener to the proimse. This flag is also used to hide the
19234 // primary children. In mutation mode, we also need the flag to
19235 // *unhide* children that were previously hidden, so check if the
19236 // is currently timed out, too.
19237 workInProgress.effectTag |= Update;
19238 }
19239 }
19240 if (enableSuspenseCallback && workInProgress.updateQueue !== null && workInProgress.memoizedProps.suspenseCallback != null) {
19241 // Always notify the callback
19242 workInProgress.effectTag |= Update;
19243 }
19244 break;
19245 }
19246 case Fragment:
19247 break;
19248 case Mode:
19249 break;
19250 case Profiler:
19251 break;
19252 case HostPortal:
19253 popHostContainer(workInProgress);
19254 updateHostContainer(workInProgress);
19255 break;
19256 case ContextProvider:
19257 // Pop provider fiber
19258 popProvider(workInProgress);
19259 break;
19260 case ContextConsumer:
19261 break;
19262 case MemoComponent:
19263 break;
19264 case IncompleteClassComponent:
19265 {
19266 // Same as class component case. I put it down here so that the tags are
19267 // sequential to ensure this switch is compiled to a jump table.
19268 var _Component = workInProgress.type;
19269 if (isContextProvider(_Component)) {
19270 popContext(workInProgress);
19271 }
19272 break;
19273 }
19274 case DehydratedSuspenseComponent:
19275 {
19276 if (enableSuspenseServerRenderer) {
19277 popSuspenseContext(workInProgress);
19278 if (current === null) {
19279 var _wasHydrated2 = popHydrationState(workInProgress);
19280 (function () {
19281 if (!_wasHydrated2) {
19282 {
19283 throw ReactError(Error('A dehydrated suspense component was completed without a hydrated node. This is probably a bug in React.'));
19284 }
19285 }
19286 })();
19287 if (enableSchedulerTracing) {
19288 markSpawnedWork(Never);
19289 }
19290 skipPastDehydratedSuspenseInstance(workInProgress);
19291 } else if ((workInProgress.effectTag & DidCapture) === NoEffect) {
19292 // This boundary did not suspend so it's now hydrated.
19293 // To handle any future suspense cases, we're going to now upgrade it
19294 // to a Suspense component. We detach it from the existing current fiber.
19295 current.alternate = null;
19296 workInProgress.alternate = null;
19297 workInProgress.tag = SuspenseComponent;
19298 workInProgress.memoizedState = null;
19299 workInProgress.stateNode = null;
19300 }
19301 }
19302 break;
19303 }
19304 case SuspenseListComponent:
19305 {
19306 popSuspenseContext(workInProgress);
19307
19308 var renderState = workInProgress.memoizedState;
19309
19310 if (renderState === null) {
19311 // We're running in the default, "independent" mode. We don't do anything
19312 // in this mode.
19313 break;
19314 }
19315
19316 var didSuspendAlready = (workInProgress.effectTag & DidCapture) !== NoEffect;
19317
19318 var renderedTail = renderState.rendering;
19319 if (renderedTail === null) {
19320 // We just rendered the head.
19321 if (!didSuspendAlready) {
19322 // This is the first pass. We need to figure out if anything is still
19323 // suspended in the rendered set.
19324
19325 // If new content unsuspended, but there's still some content that
19326 // didn't. Then we need to do a second pass that forces everything
19327 // to keep showing their fallbacks.
19328
19329 // We might be suspended if something in this render pass suspended, or
19330 // something in the previous committed pass suspended. Otherwise,
19331 // there's no chance so we can skip the expensive call to
19332 // findFirstSuspended.
19333 var cannotBeSuspended = renderHasNotSuspendedYet() && (current === null || (current.effectTag & DidCapture) === NoEffect);
19334 if (!cannotBeSuspended) {
19335 var row = workInProgress.child;
19336 while (row !== null) {
19337 var suspended = findFirstSuspended(row);
19338 if (suspended !== null) {
19339 didSuspendAlready = true;
19340 workInProgress.effectTag |= DidCapture;
19341 cutOffTailIfNeeded(renderState, false);
19342
19343 // If this is a newly suspended tree, it might not get committed as
19344 // part of the second pass. In that case nothing will subscribe to
19345 // its thennables. Instead, we'll transfer its thennables to the
19346 // SuspenseList so that it can retry if they resolve.
19347 // There might be multiple of these in the list but since we're
19348 // going to wait for all of them anyway, it doesn't really matter
19349 // which ones gets to ping. In theory we could get clever and keep
19350 // track of how many dependencies remain but it gets tricky because
19351 // in the meantime, we can add/remove/change items and dependencies.
19352 // We might bail out of the loop before finding any but that
19353 // doesn't matter since that means that the other boundaries that
19354 // we did find already has their listeners attached.
19355 var newThennables = suspended.updateQueue;
19356 if (newThennables !== null) {
19357 workInProgress.updateQueue = newThennables;
19358 workInProgress.effectTag |= Update;
19359 }
19360
19361 // Rerender the whole list, but this time, we'll force fallbacks
19362 // to stay in place.
19363 // Reset the effect list before doing the second pass since that's now invalid.
19364 workInProgress.firstEffect = workInProgress.lastEffect = null;
19365 // Reset the child fibers to their original state.
19366 resetChildFibers(workInProgress, renderExpirationTime);
19367
19368 // Set up the Suspense Context to force suspense and immediately
19369 // rerender the children.
19370 pushSuspenseContext(workInProgress, setShallowSuspenseContext(suspenseStackCursor.current, ForceSuspenseFallback));
19371 return workInProgress.child;
19372 }
19373 row = row.sibling;
19374 }
19375 }
19376 } else {
19377 cutOffTailIfNeeded(renderState, false);
19378 }
19379 // Next we're going to render the tail.
19380 } else {
19381 // Append the rendered row to the child list.
19382 if (!didSuspendAlready) {
19383 var _suspended = findFirstSuspended(renderedTail);
19384 if (_suspended !== null) {
19385 workInProgress.effectTag |= DidCapture;
19386 didSuspendAlready = true;
19387 cutOffTailIfNeeded(renderState, true);
19388 // This might have been modified.
19389 if (renderState.tail === null && renderState.tailMode === 'hidden') {
19390 // We need to delete the row we just rendered.
19391 // Ensure we transfer the update queue to the parent.
19392 var _newThennables = _suspended.updateQueue;
19393 if (_newThennables !== null) {
19394 workInProgress.updateQueue = _newThennables;
19395 workInProgress.effectTag |= Update;
19396 }
19397 // Reset the effect list to what it w as before we rendered this
19398 // child. The nested children have already appended themselves.
19399 var lastEffect = workInProgress.lastEffect = renderState.lastEffect;
19400 // Remove any effects that were appended after this point.
19401 if (lastEffect !== null) {
19402 lastEffect.nextEffect = null;
19403 }
19404 // We're done.
19405 return null;
19406 }
19407 } else if (now() > renderState.tailExpiration && renderExpirationTime > Never) {
19408 // We have now passed our CPU deadline and we'll just give up further
19409 // attempts to render the main content and only render fallbacks.
19410 // The assumption is that this is usually faster.
19411 workInProgress.effectTag |= DidCapture;
19412 didSuspendAlready = true;
19413
19414 cutOffTailIfNeeded(renderState, false);
19415
19416 // Since nothing actually suspended, there will nothing to ping this
19417 // to get it started back up to attempt the next item. If we can show
19418 // them, then they really have the same priority as this render.
19419 // So we'll pick it back up the very next render pass once we've had
19420 // an opportunity to yield for paint.
19421
19422 var nextPriority = renderExpirationTime - 1;
19423 workInProgress.expirationTime = workInProgress.childExpirationTime = nextPriority;
19424 if (enableSchedulerTracing) {
19425 markSpawnedWork(nextPriority);
19426 }
19427 }
19428 }
19429 if (renderState.isBackwards) {
19430 // The effect list of the backwards tail will have been added
19431 // to the end. This breaks the guarantee that life-cycles fire in
19432 // sibling order but that isn't a strong guarantee promised by React.
19433 // Especially since these might also just pop in during future commits.
19434 // Append to the beginning of the list.
19435 renderedTail.sibling = workInProgress.child;
19436 workInProgress.child = renderedTail;
19437 } else {
19438 var previousSibling = renderState.last;
19439 if (previousSibling !== null) {
19440 previousSibling.sibling = renderedTail;
19441 } else {
19442 workInProgress.child = renderedTail;
19443 }
19444 renderState.last = renderedTail;
19445 }
19446 }
19447
19448 if (renderState.tail !== null) {
19449 // We still have tail rows to render.
19450 if (renderState.tailExpiration === 0) {
19451 // Heuristic for how long we're willing to spend rendering rows
19452 // until we just give up and show what we have so far.
19453 var TAIL_EXPIRATION_TIMEOUT_MS = 500;
19454 renderState.tailExpiration = now() + TAIL_EXPIRATION_TIMEOUT_MS;
19455 }
19456 // Pop a row.
19457 var next = renderState.tail;
19458 renderState.rendering = next;
19459 renderState.tail = next.sibling;
19460 renderState.lastEffect = workInProgress.lastEffect;
19461 next.sibling = null;
19462
19463 // Restore the context.
19464 // TODO: We can probably just avoid popping it instead and only
19465 // setting it the first time we go from not suspended to suspended.
19466 var suspenseContext = suspenseStackCursor.current;
19467 if (didSuspendAlready) {
19468 suspenseContext = setShallowSuspenseContext(suspenseContext, ForceSuspenseFallback);
19469 } else {
19470 suspenseContext = setDefaultShallowSuspenseContext(suspenseContext);
19471 }
19472 pushSuspenseContext(workInProgress, suspenseContext);
19473 // Do a pass over the next row.
19474 return next;
19475 }
19476 break;
19477 }
19478 case FundamentalComponent:
19479 {
19480 if (enableFundamentalAPI) {
19481 var fundamentalImpl = workInProgress.type.impl;
19482 var fundamentalInstance = workInProgress.stateNode;
19483
19484 if (fundamentalInstance === null) {
19485 var getInitialState = fundamentalImpl.getInitialState;
19486 var fundamentalState = void 0;
19487 if (getInitialState !== undefined) {
19488 fundamentalState = getInitialState(newProps);
19489 }
19490 fundamentalInstance = workInProgress.stateNode = createFundamentalStateInstance(workInProgress, newProps, fundamentalImpl, fundamentalState || {});
19491 var _instance6 = getFundamentalComponentInstance(fundamentalInstance);
19492 fundamentalInstance.instance = _instance6;
19493 if (fundamentalImpl.reconcileChildren === false) {
19494 return null;
19495 }
19496 appendAllChildren(_instance6, workInProgress, false, false);
19497 mountFundamentalComponent(fundamentalInstance);
19498 } else {
19499 // We fire update in commit phase
19500 var prevProps = fundamentalInstance.props;
19501 fundamentalInstance.prevProps = prevProps;
19502 fundamentalInstance.props = newProps;
19503 fundamentalInstance.currentFiber = workInProgress;
19504 if (supportsPersistence) {
19505 var _instance7 = cloneFundamentalInstance(fundamentalInstance);
19506 fundamentalInstance.instance = _instance7;
19507 appendAllChildren(_instance7, workInProgress, false, false);
19508 }
19509 var shouldUpdate = shouldUpdateFundamentalComponent(fundamentalInstance);
19510 if (shouldUpdate) {
19511 markUpdate(workInProgress);
19512 }
19513 }
19514 }
19515 break;
19516 }
19517 default:
19518 (function () {
19519 {
19520 {
19521 throw ReactError(Error('Unknown unit of work tag. This error is likely caused by a bug in React. Please file an issue.'));
19522 }
19523 }
19524 })();
19525 }
19526
19527 return null;
19528}
19529
19530function mountEventResponder$1(responder, responderProps, instance, rootContainerInstance, fiber, respondersMap) {
19531 var responderState = emptyObject;
19532 var getInitialState = responder.getInitialState;
19533 if (getInitialState !== null) {
19534 responderState = getInitialState(responderProps);
19535 }
19536 var responderInstance = createResponderInstance(responder, responderProps, responderState, instance, fiber);
19537 mountResponderInstance(responder, responderInstance, responderProps, responderState, instance, rootContainerInstance);
19538 respondersMap.set(responder, responderInstance);
19539}
19540
19541function updateEventListener(listener, fiber, visistedResponders, respondersMap, instance, rootContainerInstance) {
19542 var responder = void 0;
19543 var props = void 0;
19544
19545 if (listener) {
19546 responder = listener.responder;
19547 props = listener.props;
19548 }
19549 (function () {
19550 if (!(responder && responder.$$typeof === REACT_RESPONDER_TYPE)) {
19551 {
19552 throw ReactError(Error('An invalid value was used as an event listener. Expect one or many event listeners created via React.unstable_useResponer().'));
19553 }
19554 }
19555 })();
19556 var listenerProps = props;
19557 if (visistedResponders.has(responder)) {
19558 // show warning
19559 {
19560 warning$1(false, 'Duplicate event responder "%s" found in event listeners. ' + 'Event listeners passed to elements cannot use the same event responder more than once.', responder.displayName);
19561 }
19562 return;
19563 }
19564 visistedResponders.add(responder);
19565 var responderInstance = respondersMap.get(responder);
19566
19567 if (responderInstance === undefined) {
19568 // Mount
19569 mountEventResponder$1(responder, listenerProps, instance, rootContainerInstance, fiber, respondersMap);
19570 } else {
19571 // Update
19572 responderInstance.props = listenerProps;
19573 responderInstance.fiber = fiber;
19574 }
19575}
19576
19577function updateEventListeners(listeners, instance, rootContainerInstance, fiber) {
19578 var visistedResponders = new Set();
19579 var dependencies = fiber.dependencies;
19580 if (listeners != null) {
19581 if (dependencies === null) {
19582 dependencies = fiber.dependencies = {
19583 expirationTime: NoWork,
19584 firstContext: null,
19585 responders: new Map()
19586 };
19587 }
19588 var respondersMap = dependencies.responders;
19589 if (respondersMap === null) {
19590 respondersMap = new Map();
19591 }
19592 if (isArray$2(listeners)) {
19593 for (var i = 0, length = listeners.length; i < length; i++) {
19594 var listener = listeners[i];
19595 updateEventListener(listener, fiber, visistedResponders, respondersMap, instance, rootContainerInstance);
19596 }
19597 } else {
19598 updateEventListener(listeners, fiber, visistedResponders, respondersMap, instance, rootContainerInstance);
19599 }
19600 }
19601 if (dependencies !== null) {
19602 var _respondersMap = dependencies.responders;
19603 if (_respondersMap !== null) {
19604 // Unmount
19605 var mountedResponders = Array.from(_respondersMap.keys());
19606 for (var _i = 0, _length = mountedResponders.length; _i < _length; _i++) {
19607 var mountedResponder = mountedResponders[_i];
19608 if (!visistedResponders.has(mountedResponder)) {
19609 var responderInstance = _respondersMap.get(mountedResponder);
19610 unmountResponderInstance(responderInstance);
19611 _respondersMap.delete(mountedResponder);
19612 }
19613 }
19614 }
19615 }
19616}
19617
19618function unwindWork(workInProgress, renderExpirationTime) {
19619 switch (workInProgress.tag) {
19620 case ClassComponent:
19621 {
19622 var Component = workInProgress.type;
19623 if (isContextProvider(Component)) {
19624 popContext(workInProgress);
19625 }
19626 var effectTag = workInProgress.effectTag;
19627 if (effectTag & ShouldCapture) {
19628 workInProgress.effectTag = effectTag & ~ShouldCapture | DidCapture;
19629 return workInProgress;
19630 }
19631 return null;
19632 }
19633 case HostRoot:
19634 {
19635 popHostContainer(workInProgress);
19636 popTopLevelContextObject(workInProgress);
19637 var _effectTag = workInProgress.effectTag;
19638 (function () {
19639 if (!((_effectTag & DidCapture) === NoEffect)) {
19640 {
19641 throw ReactError(Error('The root failed to unmount after an error. This is likely a bug in React. Please file an issue.'));
19642 }
19643 }
19644 })();
19645 workInProgress.effectTag = _effectTag & ~ShouldCapture | DidCapture;
19646 return workInProgress;
19647 }
19648 case HostComponent:
19649 {
19650 // TODO: popHydrationState
19651 popHostContext(workInProgress);
19652 return null;
19653 }
19654 case SuspenseComponent:
19655 {
19656 popSuspenseContext(workInProgress);
19657 var _effectTag2 = workInProgress.effectTag;
19658 if (_effectTag2 & ShouldCapture) {
19659 workInProgress.effectTag = _effectTag2 & ~ShouldCapture | DidCapture;
19660 // Captured a suspense effect. Re-render the boundary.
19661 return workInProgress;
19662 }
19663 return null;
19664 }
19665 case DehydratedSuspenseComponent:
19666 {
19667 if (enableSuspenseServerRenderer) {
19668 // TODO: popHydrationState
19669 popSuspenseContext(workInProgress);
19670 var _effectTag3 = workInProgress.effectTag;
19671 if (_effectTag3 & ShouldCapture) {
19672 workInProgress.effectTag = _effectTag3 & ~ShouldCapture | DidCapture;
19673 // Captured a suspense effect. Re-render the boundary.
19674 return workInProgress;
19675 }
19676 }
19677 return null;
19678 }
19679 case SuspenseListComponent:
19680 {
19681 popSuspenseContext(workInProgress);
19682 // SuspenseList doesn't actually catch anything. It should've been
19683 // caught by a nested boundary. If not, it should bubble through.
19684 return null;
19685 }
19686 case HostPortal:
19687 popHostContainer(workInProgress);
19688 return null;
19689 case ContextProvider:
19690 popProvider(workInProgress);
19691 return null;
19692 default:
19693 return null;
19694 }
19695}
19696
19697function unwindInterruptedWork(interruptedWork) {
19698 switch (interruptedWork.tag) {
19699 case ClassComponent:
19700 {
19701 var childContextTypes = interruptedWork.type.childContextTypes;
19702 if (childContextTypes !== null && childContextTypes !== undefined) {
19703 popContext(interruptedWork);
19704 }
19705 break;
19706 }
19707 case HostRoot:
19708 {
19709 popHostContainer(interruptedWork);
19710 popTopLevelContextObject(interruptedWork);
19711 break;
19712 }
19713 case HostComponent:
19714 {
19715 popHostContext(interruptedWork);
19716 break;
19717 }
19718 case HostPortal:
19719 popHostContainer(interruptedWork);
19720 break;
19721 case SuspenseComponent:
19722 popSuspenseContext(interruptedWork);
19723 break;
19724 case DehydratedSuspenseComponent:
19725 if (enableSuspenseServerRenderer) {
19726 // TODO: popHydrationState
19727 popSuspenseContext(interruptedWork);
19728 }
19729 break;
19730 case SuspenseListComponent:
19731 popSuspenseContext(interruptedWork);
19732 break;
19733 case ContextProvider:
19734 popProvider(interruptedWork);
19735 break;
19736 default:
19737 break;
19738 }
19739}
19740
19741function createCapturedValue(value, source) {
19742 // If the value is an error, call this function immediately after it is thrown
19743 // so the stack is accurate.
19744 return {
19745 value: value,
19746 source: source,
19747 stack: getStackByFiberInDevAndProd(source)
19748 };
19749}
19750
19751// This module is forked in different environments.
19752// By default, return `true` to log errors to the console.
19753// Forks can return `false` if this isn't desirable.
19754function showErrorDialog(capturedError) {
19755 return true;
19756}
19757
19758function logCapturedError(capturedError) {
19759 var logError = showErrorDialog(capturedError);
19760
19761 // Allow injected showErrorDialog() to prevent default console.error logging.
19762 // This enables renderers like ReactNative to better manage redbox behavior.
19763 if (logError === false) {
19764 return;
19765 }
19766
19767 var error = capturedError.error;
19768 {
19769 var componentName = capturedError.componentName,
19770 componentStack = capturedError.componentStack,
19771 errorBoundaryName = capturedError.errorBoundaryName,
19772 errorBoundaryFound = capturedError.errorBoundaryFound,
19773 willRetry = capturedError.willRetry;
19774
19775 // Browsers support silencing uncaught errors by calling
19776 // `preventDefault()` in window `error` handler.
19777 // We record this information as an expando on the error.
19778
19779 if (error != null && error._suppressLogging) {
19780 if (errorBoundaryFound && willRetry) {
19781 // The error is recoverable and was silenced.
19782 // Ignore it and don't print the stack addendum.
19783 // This is handy for testing error boundaries without noise.
19784 return;
19785 }
19786 // The error is fatal. Since the silencing might have
19787 // been accidental, we'll surface it anyway.
19788 // However, the browser would have silenced the original error
19789 // so we'll print it first, and then print the stack addendum.
19790 console.error(error);
19791 // For a more detailed description of this block, see:
19792 // https://github.com/facebook/react/pull/13384
19793 }
19794
19795 var componentNameMessage = componentName ? 'The above error occurred in the <' + componentName + '> component:' : 'The above error occurred in one of your React components:';
19796
19797 var errorBoundaryMessage = void 0;
19798 // errorBoundaryFound check is sufficient; errorBoundaryName check is to satisfy Flow.
19799 if (errorBoundaryFound && errorBoundaryName) {
19800 if (willRetry) {
19801 errorBoundaryMessage = 'React will try to recreate this component tree from scratch ' + ('using the error boundary you provided, ' + errorBoundaryName + '.');
19802 } else {
19803 errorBoundaryMessage = 'This error was initially handled by the error boundary ' + errorBoundaryName + '.\n' + 'Recreating the tree from scratch failed so React will unmount the tree.';
19804 }
19805 } else {
19806 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.';
19807 }
19808 var combinedMessage = '' + componentNameMessage + componentStack + '\n\n' + ('' + errorBoundaryMessage);
19809
19810 // In development, we provide our own message with just the component stack.
19811 // We don't include the original error message and JS stack because the browser
19812 // has already printed it. Even if the application swallows the error, it is still
19813 // displayed by the browser thanks to the DEV-only fake event trick in ReactErrorUtils.
19814 console.error(combinedMessage);
19815 }
19816}
19817
19818var didWarnAboutUndefinedSnapshotBeforeUpdate = null;
19819{
19820 didWarnAboutUndefinedSnapshotBeforeUpdate = new Set();
19821}
19822
19823var PossiblyWeakSet$1 = typeof WeakSet === 'function' ? WeakSet : Set;
19824
19825function logError(boundary, errorInfo) {
19826 var source = errorInfo.source;
19827 var stack = errorInfo.stack;
19828 if (stack === null && source !== null) {
19829 stack = getStackByFiberInDevAndProd(source);
19830 }
19831
19832 var capturedError = {
19833 componentName: source !== null ? getComponentName(source.type) : null,
19834 componentStack: stack !== null ? stack : '',
19835 error: errorInfo.value,
19836 errorBoundary: null,
19837 errorBoundaryName: null,
19838 errorBoundaryFound: false,
19839 willRetry: false
19840 };
19841
19842 if (boundary !== null && boundary.tag === ClassComponent) {
19843 capturedError.errorBoundary = boundary.stateNode;
19844 capturedError.errorBoundaryName = getComponentName(boundary.type);
19845 capturedError.errorBoundaryFound = true;
19846 capturedError.willRetry = true;
19847 }
19848
19849 try {
19850 logCapturedError(capturedError);
19851 } catch (e) {
19852 // This method must not throw, or React internal state will get messed up.
19853 // If console.error is overridden, or logCapturedError() shows a dialog that throws,
19854 // we want to report this error outside of the normal stack as a last resort.
19855 // https://github.com/facebook/react/issues/13188
19856 setTimeout(function () {
19857 throw e;
19858 });
19859 }
19860}
19861
19862var callComponentWillUnmountWithTimer = function (current$$1, instance) {
19863 startPhaseTimer(current$$1, 'componentWillUnmount');
19864 instance.props = current$$1.memoizedProps;
19865 instance.state = current$$1.memoizedState;
19866 instance.componentWillUnmount();
19867 stopPhaseTimer();
19868};
19869
19870// Capture errors so they don't interrupt unmounting.
19871function safelyCallComponentWillUnmount(current$$1, instance) {
19872 {
19873 invokeGuardedCallback(null, callComponentWillUnmountWithTimer, null, current$$1, instance);
19874 if (hasCaughtError()) {
19875 var unmountError = clearCaughtError();
19876 captureCommitPhaseError(current$$1, unmountError);
19877 }
19878 }
19879}
19880
19881function safelyDetachRef(current$$1) {
19882 var ref = current$$1.ref;
19883 if (ref !== null) {
19884 if (typeof ref === 'function') {
19885 {
19886 invokeGuardedCallback(null, ref, null, null);
19887 if (hasCaughtError()) {
19888 var refError = clearCaughtError();
19889 captureCommitPhaseError(current$$1, refError);
19890 }
19891 }
19892 } else {
19893 ref.current = null;
19894 }
19895 }
19896}
19897
19898function safelyCallDestroy(current$$1, destroy) {
19899 {
19900 invokeGuardedCallback(null, destroy, null);
19901 if (hasCaughtError()) {
19902 var error = clearCaughtError();
19903 captureCommitPhaseError(current$$1, error);
19904 }
19905 }
19906}
19907
19908function commitBeforeMutationLifeCycles(current$$1, finishedWork) {
19909 switch (finishedWork.tag) {
19910 case FunctionComponent:
19911 case ForwardRef:
19912 case SimpleMemoComponent:
19913 {
19914 commitHookEffectList(UnmountSnapshot, NoEffect$1, finishedWork);
19915 return;
19916 }
19917 case ClassComponent:
19918 {
19919 if (finishedWork.effectTag & Snapshot) {
19920 if (current$$1 !== null) {
19921 var prevProps = current$$1.memoizedProps;
19922 var prevState = current$$1.memoizedState;
19923 startPhaseTimer(finishedWork, 'getSnapshotBeforeUpdate');
19924 var instance = finishedWork.stateNode;
19925 // We could update instance props and state here,
19926 // but instead we rely on them being set during last render.
19927 // TODO: revisit this when we implement resuming.
19928 {
19929 if (finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps) {
19930 !(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;
19931 !(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;
19932 }
19933 }
19934 var snapshot = instance.getSnapshotBeforeUpdate(finishedWork.elementType === finishedWork.type ? prevProps : resolveDefaultProps(finishedWork.type, prevProps), prevState);
19935 {
19936 var didWarnSet = didWarnAboutUndefinedSnapshotBeforeUpdate;
19937 if (snapshot === undefined && !didWarnSet.has(finishedWork.type)) {
19938 didWarnSet.add(finishedWork.type);
19939 warningWithoutStack$1(false, '%s.getSnapshotBeforeUpdate(): A snapshot value (or null) ' + 'must be returned. You have returned undefined.', getComponentName(finishedWork.type));
19940 }
19941 }
19942 instance.__reactInternalSnapshotBeforeUpdate = snapshot;
19943 stopPhaseTimer();
19944 }
19945 }
19946 return;
19947 }
19948 case HostRoot:
19949 case HostComponent:
19950 case HostText:
19951 case HostPortal:
19952 case IncompleteClassComponent:
19953 // Nothing to do for these component types
19954 return;
19955 default:
19956 {
19957 (function () {
19958 {
19959 {
19960 throw ReactError(Error('This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue.'));
19961 }
19962 }
19963 })();
19964 }
19965 }
19966}
19967
19968function commitHookEffectList(unmountTag, mountTag, finishedWork) {
19969 var updateQueue = finishedWork.updateQueue;
19970 var lastEffect = updateQueue !== null ? updateQueue.lastEffect : null;
19971 if (lastEffect !== null) {
19972 var firstEffect = lastEffect.next;
19973 var effect = firstEffect;
19974 do {
19975 if ((effect.tag & unmountTag) !== NoEffect$1) {
19976 // Unmount
19977 var destroy = effect.destroy;
19978 effect.destroy = undefined;
19979 if (destroy !== undefined) {
19980 destroy();
19981 }
19982 }
19983 if ((effect.tag & mountTag) !== NoEffect$1) {
19984 // Mount
19985 var create = effect.create;
19986 effect.destroy = create();
19987
19988 {
19989 var _destroy = effect.destroy;
19990 if (_destroy !== undefined && typeof _destroy !== 'function') {
19991 var addendum = void 0;
19992 if (_destroy === null) {
19993 addendum = ' You returned null. If your effect does not require clean ' + 'up, return undefined (or nothing).';
19994 } else if (typeof _destroy.then === 'function') {
19995 addendum = '\n\nIt looks like you wrote useEffect(async () => ...) or returned a Promise. ' + 'Instead, write the async function inside your effect ' + 'and call it immediately:\n\n' + 'useEffect(() => {\n' + ' async function fetchData() {\n' + ' // You can await here\n' + ' const response = await MyAPI.getData(someId);\n' + ' // ...\n' + ' }\n' + ' fetchData();\n' + '}, [someId]); // Or [] if effect doesn\'t need props or state\n\n' + 'Learn more about data fetching with Hooks: https://fb.me/react-hooks-data-fetching';
19996 } else {
19997 addendum = ' You returned: ' + _destroy;
19998 }
19999 warningWithoutStack$1(false, 'An effect function must not return anything besides a function, ' + 'which is used for clean-up.%s%s', addendum, getStackByFiberInDevAndProd(finishedWork));
20000 }
20001 }
20002 }
20003 effect = effect.next;
20004 } while (effect !== firstEffect);
20005 }
20006}
20007
20008function commitPassiveHookEffects(finishedWork) {
20009 if ((finishedWork.effectTag & Passive) !== NoEffect) {
20010 switch (finishedWork.tag) {
20011 case FunctionComponent:
20012 case ForwardRef:
20013 case SimpleMemoComponent:
20014 {
20015 commitHookEffectList(UnmountPassive, NoEffect$1, finishedWork);
20016 commitHookEffectList(NoEffect$1, MountPassive, finishedWork);
20017 break;
20018 }
20019 default:
20020 break;
20021 }
20022 }
20023}
20024
20025function commitLifeCycles(finishedRoot, current$$1, finishedWork, committedExpirationTime) {
20026 switch (finishedWork.tag) {
20027 case FunctionComponent:
20028 case ForwardRef:
20029 case SimpleMemoComponent:
20030 {
20031 commitHookEffectList(UnmountLayout, MountLayout, finishedWork);
20032 break;
20033 }
20034 case ClassComponent:
20035 {
20036 var instance = finishedWork.stateNode;
20037 if (finishedWork.effectTag & Update) {
20038 if (current$$1 === null) {
20039 startPhaseTimer(finishedWork, 'componentDidMount');
20040 // We could update instance props and state here,
20041 // but instead we rely on them being set during last render.
20042 // TODO: revisit this when we implement resuming.
20043 {
20044 if (finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps) {
20045 !(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;
20046 !(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;
20047 }
20048 }
20049 instance.componentDidMount();
20050 stopPhaseTimer();
20051 } else {
20052 var prevProps = finishedWork.elementType === finishedWork.type ? current$$1.memoizedProps : resolveDefaultProps(finishedWork.type, current$$1.memoizedProps);
20053 var prevState = current$$1.memoizedState;
20054 startPhaseTimer(finishedWork, 'componentDidUpdate');
20055 // We could update instance props and state here,
20056 // but instead we rely on them being set during last render.
20057 // TODO: revisit this when we implement resuming.
20058 {
20059 if (finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps) {
20060 !(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;
20061 !(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;
20062 }
20063 }
20064 instance.componentDidUpdate(prevProps, prevState, instance.__reactInternalSnapshotBeforeUpdate);
20065 stopPhaseTimer();
20066 }
20067 }
20068 var updateQueue = finishedWork.updateQueue;
20069 if (updateQueue !== null) {
20070 {
20071 if (finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps) {
20072 !(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;
20073 !(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;
20074 }
20075 }
20076 // We could update instance props and state here,
20077 // but instead we rely on them being set during last render.
20078 // TODO: revisit this when we implement resuming.
20079 commitUpdateQueue(finishedWork, updateQueue, instance, committedExpirationTime);
20080 }
20081 return;
20082 }
20083 case HostRoot:
20084 {
20085 var _updateQueue = finishedWork.updateQueue;
20086 if (_updateQueue !== null) {
20087 var _instance = null;
20088 if (finishedWork.child !== null) {
20089 switch (finishedWork.child.tag) {
20090 case HostComponent:
20091 _instance = getPublicInstance(finishedWork.child.stateNode);
20092 break;
20093 case ClassComponent:
20094 _instance = finishedWork.child.stateNode;
20095 break;
20096 }
20097 }
20098 commitUpdateQueue(finishedWork, _updateQueue, _instance, committedExpirationTime);
20099 }
20100 return;
20101 }
20102 case HostComponent:
20103 {
20104 var _instance2 = finishedWork.stateNode;
20105
20106 // Renderers may schedule work to be done after host components are mounted
20107 // (eg DOM renderer may schedule auto-focus for inputs and form controls).
20108 // These effects should only be committed when components are first mounted,
20109 // aka when there is no current/alternate.
20110 if (current$$1 === null && finishedWork.effectTag & Update) {
20111 var type = finishedWork.type;
20112 var props = finishedWork.memoizedProps;
20113 commitMount(_instance2, type, props, finishedWork);
20114 }
20115
20116 return;
20117 }
20118 case HostText:
20119 {
20120 // We have no life-cycles associated with text.
20121 return;
20122 }
20123 case HostPortal:
20124 {
20125 // We have no life-cycles associated with portals.
20126 return;
20127 }
20128 case Profiler:
20129 {
20130 if (enableProfilerTimer) {
20131 var onRender = finishedWork.memoizedProps.onRender;
20132
20133 if (typeof onRender === 'function') {
20134 if (enableSchedulerTracing) {
20135 onRender(finishedWork.memoizedProps.id, current$$1 === null ? 'mount' : 'update', finishedWork.actualDuration, finishedWork.treeBaseDuration, finishedWork.actualStartTime, getCommitTime(), finishedRoot.memoizedInteractions);
20136 } else {
20137 onRender(finishedWork.memoizedProps.id, current$$1 === null ? 'mount' : 'update', finishedWork.actualDuration, finishedWork.treeBaseDuration, finishedWork.actualStartTime, getCommitTime());
20138 }
20139 }
20140 }
20141 return;
20142 }
20143 case SuspenseComponent:
20144 case SuspenseListComponent:
20145 case IncompleteClassComponent:
20146 case FundamentalComponent:
20147 return;
20148 default:
20149 {
20150 (function () {
20151 {
20152 {
20153 throw ReactError(Error('This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue.'));
20154 }
20155 }
20156 })();
20157 }
20158 }
20159}
20160
20161function hideOrUnhideAllChildren(finishedWork, isHidden) {
20162 if (supportsMutation) {
20163 // We only have the top Fiber that was inserted but we need to recurse down its
20164 var node = finishedWork;
20165 while (true) {
20166 if (node.tag === HostComponent) {
20167 var instance = node.stateNode;
20168 if (isHidden) {
20169 hideInstance(instance);
20170 } else {
20171 unhideInstance(node.stateNode, node.memoizedProps);
20172 }
20173 } else if (node.tag === HostText) {
20174 var _instance3 = node.stateNode;
20175 if (isHidden) {
20176 hideTextInstance(_instance3);
20177 } else {
20178 unhideTextInstance(_instance3, node.memoizedProps);
20179 }
20180 } else if (node.tag === SuspenseComponent && node.memoizedState !== null) {
20181 // Found a nested Suspense component that timed out. Skip over the
20182 var fallbackChildFragment = node.child.sibling;
20183 fallbackChildFragment.return = node;
20184 node = fallbackChildFragment;
20185 continue;
20186 } else if (node.child !== null) {
20187 node.child.return = node;
20188 node = node.child;
20189 continue;
20190 }
20191 if (node === finishedWork) {
20192 return;
20193 }
20194 while (node.sibling === null) {
20195 if (node.return === null || node.return === finishedWork) {
20196 return;
20197 }
20198 node = node.return;
20199 }
20200 node.sibling.return = node.return;
20201 node = node.sibling;
20202 }
20203 }
20204}
20205
20206function commitAttachRef(finishedWork) {
20207 var ref = finishedWork.ref;
20208 if (ref !== null) {
20209 var instance = finishedWork.stateNode;
20210 var instanceToUse = void 0;
20211 switch (finishedWork.tag) {
20212 case HostComponent:
20213 instanceToUse = getPublicInstance(instance);
20214 break;
20215 default:
20216 instanceToUse = instance;
20217 }
20218 if (typeof ref === 'function') {
20219 ref(instanceToUse);
20220 } else {
20221 {
20222 if (!ref.hasOwnProperty('current')) {
20223 warningWithoutStack$1(false, 'Unexpected ref object provided for %s. ' + 'Use either a ref-setter function or React.createRef().%s', getComponentName(finishedWork.type), getStackByFiberInDevAndProd(finishedWork));
20224 }
20225 }
20226
20227 ref.current = instanceToUse;
20228 }
20229 }
20230}
20231
20232function commitDetachRef(current$$1) {
20233 var currentRef = current$$1.ref;
20234 if (currentRef !== null) {
20235 if (typeof currentRef === 'function') {
20236 currentRef(null);
20237 } else {
20238 currentRef.current = null;
20239 }
20240 }
20241}
20242
20243// User-originating errors (lifecycles and refs) should not interrupt
20244// deletion, so don't let them throw. Host-originating errors should
20245// interrupt deletion, so it's okay
20246function commitUnmount(current$$1, renderPriorityLevel) {
20247 onCommitUnmount(current$$1);
20248
20249 switch (current$$1.tag) {
20250 case FunctionComponent:
20251 case ForwardRef:
20252 case MemoComponent:
20253 case SimpleMemoComponent:
20254 {
20255 var updateQueue = current$$1.updateQueue;
20256 if (updateQueue !== null) {
20257 var lastEffect = updateQueue.lastEffect;
20258 if (lastEffect !== null) {
20259 var firstEffect = lastEffect.next;
20260
20261 // When the owner fiber is deleted, the destroy function of a passive
20262 // effect hook is called during the synchronous commit phase. This is
20263 // a concession to implementation complexity. Calling it in the
20264 // passive effect phase (like they usually are, when dependencies
20265 // change during an update) would require either traversing the
20266 // children of the deleted fiber again, or including unmount effects
20267 // as part of the fiber effect list.
20268 //
20269 // Because this is during the sync commit phase, we need to change
20270 // the priority.
20271 //
20272 // TODO: Reconsider this implementation trade off.
20273 var priorityLevel = renderPriorityLevel > NormalPriority ? NormalPriority : renderPriorityLevel;
20274 runWithPriority$2(priorityLevel, function () {
20275 var effect = firstEffect;
20276 do {
20277 var destroy = effect.destroy;
20278 if (destroy !== undefined) {
20279 safelyCallDestroy(current$$1, destroy);
20280 }
20281 effect = effect.next;
20282 } while (effect !== firstEffect);
20283 });
20284 }
20285 }
20286 break;
20287 }
20288 case ClassComponent:
20289 {
20290 safelyDetachRef(current$$1);
20291 var instance = current$$1.stateNode;
20292 if (typeof instance.componentWillUnmount === 'function') {
20293 safelyCallComponentWillUnmount(current$$1, instance);
20294 }
20295 return;
20296 }
20297 case HostComponent:
20298 {
20299 if (enableFlareAPI) {
20300 var dependencies = current$$1.dependencies;
20301
20302 if (dependencies !== null) {
20303 var respondersMap = dependencies.responders;
20304 if (respondersMap !== null) {
20305 var responderInstances = Array.from(respondersMap.values());
20306 for (var i = 0, length = responderInstances.length; i < length; i++) {
20307 var responderInstance = responderInstances[i];
20308 unmountResponderInstance(responderInstance);
20309 }
20310 dependencies.responders = null;
20311 }
20312 }
20313 }
20314 safelyDetachRef(current$$1);
20315 return;
20316 }
20317 case HostPortal:
20318 {
20319 // TODO: this is recursive.
20320 // We are also not using this parent because
20321 // the portal will get pushed immediately.
20322 if (supportsMutation) {
20323 unmountHostComponents(current$$1, renderPriorityLevel);
20324 } else if (supportsPersistence) {
20325 emptyPortalContainer(current$$1);
20326 }
20327 return;
20328 }
20329 case FundamentalComponent:
20330 {
20331 if (enableFundamentalAPI) {
20332 var fundamentalInstance = current$$1.stateNode;
20333 if (fundamentalInstance !== null) {
20334 unmountFundamentalComponent(fundamentalInstance);
20335 current$$1.stateNode = null;
20336 }
20337 }
20338 }
20339 }
20340}
20341
20342function commitNestedUnmounts(root, renderPriorityLevel) {
20343 // While we're inside a removed host node we don't want to call
20344 // removeChild on the inner nodes because they're removed by the top
20345 // call anyway. We also want to call componentWillUnmount on all
20346 // composites before this host node is removed from the tree. Therefore
20347 var node = root;
20348 while (true) {
20349 commitUnmount(node, renderPriorityLevel);
20350 // Visit children because they may contain more composite or host nodes.
20351 // Skip portals because commitUnmount() currently visits them recursively.
20352 if (node.child !== null && (
20353 // If we use mutation we drill down into portals using commitUnmount above.
20354 // If we don't use mutation we drill down into portals here instead.
20355 !supportsMutation || node.tag !== HostPortal)) {
20356 node.child.return = node;
20357 node = node.child;
20358 continue;
20359 }
20360 if (node === root) {
20361 return;
20362 }
20363 while (node.sibling === null) {
20364 if (node.return === null || node.return === root) {
20365 return;
20366 }
20367 node = node.return;
20368 }
20369 node.sibling.return = node.return;
20370 node = node.sibling;
20371 }
20372}
20373
20374function detachFiber(current$$1) {
20375 // Cut off the return pointers to disconnect it from the tree. Ideally, we
20376 // should clear the child pointer of the parent alternate to let this
20377 // get GC:ed but we don't know which for sure which parent is the current
20378 // one so we'll settle for GC:ing the subtree of this child. This child
20379 // itself will be GC:ed when the parent updates the next time.
20380 current$$1.return = null;
20381 current$$1.child = null;
20382 current$$1.memoizedState = null;
20383 current$$1.updateQueue = null;
20384 current$$1.dependencies = null;
20385 var alternate = current$$1.alternate;
20386 if (alternate !== null) {
20387 alternate.return = null;
20388 alternate.child = null;
20389 alternate.memoizedState = null;
20390 alternate.updateQueue = null;
20391 alternate.dependencies = null;
20392 }
20393}
20394
20395function emptyPortalContainer(current$$1) {
20396 if (!supportsPersistence) {
20397 return;
20398 }
20399
20400 var portal = current$$1.stateNode;
20401 var containerInfo = portal.containerInfo;
20402
20403 var emptyChildSet = createContainerChildSet(containerInfo);
20404 replaceContainerChildren(containerInfo, emptyChildSet);
20405}
20406
20407function commitContainer(finishedWork) {
20408 if (!supportsPersistence) {
20409 return;
20410 }
20411
20412 switch (finishedWork.tag) {
20413 case ClassComponent:
20414 case HostComponent:
20415 case HostText:
20416 case FundamentalComponent:
20417 {
20418 return;
20419 }
20420 case HostRoot:
20421 case HostPortal:
20422 {
20423 var portalOrRoot = finishedWork.stateNode;
20424 var containerInfo = portalOrRoot.containerInfo,
20425 _pendingChildren = portalOrRoot.pendingChildren;
20426
20427 replaceContainerChildren(containerInfo, _pendingChildren);
20428 return;
20429 }
20430 default:
20431 {
20432 (function () {
20433 {
20434 {
20435 throw ReactError(Error('This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue.'));
20436 }
20437 }
20438 })();
20439 }
20440 }
20441}
20442
20443function getHostParentFiber(fiber) {
20444 var parent = fiber.return;
20445 while (parent !== null) {
20446 if (isHostParent(parent)) {
20447 return parent;
20448 }
20449 parent = parent.return;
20450 }
20451 (function () {
20452 {
20453 {
20454 throw ReactError(Error('Expected to find a host parent. This error is likely caused by a bug in React. Please file an issue.'));
20455 }
20456 }
20457 })();
20458}
20459
20460function isHostParent(fiber) {
20461 return fiber.tag === HostComponent || fiber.tag === HostRoot || fiber.tag === HostPortal;
20462}
20463
20464function getHostSibling(fiber) {
20465 // We're going to search forward into the tree until we find a sibling host
20466 // node. Unfortunately, if multiple insertions are done in a row we have to
20467 // search past them. This leads to exponential search for the next sibling.
20468 var node = fiber;
20469 siblings: while (true) {
20470 // If we didn't find anything, let's try the next sibling.
20471 while (node.sibling === null) {
20472 if (node.return === null || isHostParent(node.return)) {
20473 // If we pop out of the root or hit the parent the fiber we are the
20474 // last sibling.
20475 return null;
20476 }
20477 node = node.return;
20478 }
20479 node.sibling.return = node.return;
20480 node = node.sibling;
20481 while (node.tag !== HostComponent && node.tag !== HostText && node.tag !== DehydratedSuspenseComponent) {
20482 // If it is not host node and, we might have a host node inside it.
20483 // Try to search down until we find one.
20484 if (node.effectTag & Placement) {
20485 // If we don't have a child, try the siblings instead.
20486 continue siblings;
20487 }
20488 // If we don't have a child, try the siblings instead.
20489 // We also skip portals because they are not part of this host tree.
20490 if (node.child === null || node.tag === HostPortal) {
20491 continue siblings;
20492 } else {
20493 node.child.return = node;
20494 node = node.child;
20495 }
20496 }
20497 // Check if this host node is stable or about to be placed.
20498 if (!(node.effectTag & Placement)) {
20499 // Found it!
20500 return node.stateNode;
20501 }
20502 }
20503}
20504
20505function commitPlacement(finishedWork) {
20506 if (!supportsMutation) {
20507 return;
20508 }
20509
20510 // Recursively insert all host nodes into the parent.
20511 var parentFiber = getHostParentFiber(finishedWork);
20512
20513 // Note: these two variables *must* always be updated together.
20514 var parent = void 0;
20515 var isContainer = void 0;
20516 var parentStateNode = parentFiber.stateNode;
20517 switch (parentFiber.tag) {
20518 case HostComponent:
20519 parent = parentStateNode;
20520 isContainer = false;
20521 break;
20522 case HostRoot:
20523 parent = parentStateNode.containerInfo;
20524 isContainer = true;
20525 break;
20526 case HostPortal:
20527 parent = parentStateNode.containerInfo;
20528 isContainer = true;
20529 break;
20530 case FundamentalComponent:
20531 if (enableFundamentalAPI) {
20532 parent = parentStateNode.instance;
20533 isContainer = false;
20534 }
20535 // eslint-disable-next-line-no-fallthrough
20536 default:
20537 (function () {
20538 {
20539 {
20540 throw ReactError(Error('Invalid host parent fiber. This error is likely caused by a bug in React. Please file an issue.'));
20541 }
20542 }
20543 })();
20544 }
20545 if (parentFiber.effectTag & ContentReset) {
20546 // Reset the text content of the parent before doing any insertions
20547 resetTextContent(parent);
20548 // Clear ContentReset from the effect tag
20549 parentFiber.effectTag &= ~ContentReset;
20550 }
20551
20552 var before = getHostSibling(finishedWork);
20553 // We only have the top Fiber that was inserted but we need to recurse down its
20554 // children to find all the terminal nodes.
20555 var node = finishedWork;
20556 while (true) {
20557 var isHost = node.tag === HostComponent || node.tag === HostText;
20558 if (isHost || node.tag === FundamentalComponent) {
20559 var stateNode = isHost ? node.stateNode : node.stateNode.instance;
20560 if (before) {
20561 if (isContainer) {
20562 insertInContainerBefore(parent, stateNode, before);
20563 } else {
20564 insertBefore(parent, stateNode, before);
20565 }
20566 } else {
20567 if (isContainer) {
20568 appendChildToContainer(parent, stateNode);
20569 } else {
20570 appendChild(parent, stateNode);
20571 }
20572 }
20573 } else if (node.tag === HostPortal) {
20574 // If the insertion itself is a portal, then we don't want to traverse
20575 // down its children. Instead, we'll get insertions from each child in
20576 // the portal directly.
20577 } else if (node.child !== null) {
20578 node.child.return = node;
20579 node = node.child;
20580 continue;
20581 }
20582 if (node === finishedWork) {
20583 return;
20584 }
20585 while (node.sibling === null) {
20586 if (node.return === null || node.return === finishedWork) {
20587 return;
20588 }
20589 node = node.return;
20590 }
20591 node.sibling.return = node.return;
20592 node = node.sibling;
20593 }
20594}
20595
20596function unmountHostComponents(current$$1, renderPriorityLevel) {
20597 // We only have the top Fiber that was deleted but we need to recurse down its
20598 var node = current$$1;
20599
20600 // Each iteration, currentParent is populated with node's host parent if not
20601 // currentParentIsValid.
20602 var currentParentIsValid = false;
20603
20604 // Note: these two variables *must* always be updated together.
20605 var currentParent = void 0;
20606 var currentParentIsContainer = void 0;
20607
20608 while (true) {
20609 if (!currentParentIsValid) {
20610 var parent = node.return;
20611 findParent: while (true) {
20612 (function () {
20613 if (!(parent !== null)) {
20614 {
20615 throw ReactError(Error('Expected to find a host parent. This error is likely caused by a bug in React. Please file an issue.'));
20616 }
20617 }
20618 })();
20619 var parentStateNode = parent.stateNode;
20620 switch (parent.tag) {
20621 case HostComponent:
20622 currentParent = parentStateNode;
20623 currentParentIsContainer = false;
20624 break findParent;
20625 case HostRoot:
20626 currentParent = parentStateNode.containerInfo;
20627 currentParentIsContainer = true;
20628 break findParent;
20629 case HostPortal:
20630 currentParent = parentStateNode.containerInfo;
20631 currentParentIsContainer = true;
20632 break findParent;
20633 case FundamentalComponent:
20634 if (enableFundamentalAPI) {
20635 currentParent = parentStateNode.instance;
20636 currentParentIsContainer = false;
20637 }
20638 }
20639 parent = parent.return;
20640 }
20641 currentParentIsValid = true;
20642 }
20643
20644 if (node.tag === HostComponent || node.tag === HostText) {
20645 commitNestedUnmounts(node, renderPriorityLevel);
20646 // After all the children have unmounted, it is now safe to remove the
20647 // node from the tree.
20648 if (currentParentIsContainer) {
20649 removeChildFromContainer(currentParent, node.stateNode);
20650 } else {
20651 removeChild(currentParent, node.stateNode);
20652 }
20653 // Don't visit children because we already visited them.
20654 } else if (node.tag === FundamentalComponent) {
20655 var fundamentalNode = node.stateNode.instance;
20656 commitNestedUnmounts(node, renderPriorityLevel);
20657 // After all the children have unmounted, it is now safe to remove the
20658 // node from the tree.
20659 if (currentParentIsContainer) {
20660 removeChildFromContainer(currentParent, fundamentalNode);
20661 } else {
20662 removeChild(currentParent, fundamentalNode);
20663 }
20664 } else if (enableSuspenseServerRenderer && node.tag === DehydratedSuspenseComponent) {
20665 // Delete the dehydrated suspense boundary and all of its content.
20666 if (currentParentIsContainer) {
20667 clearSuspenseBoundaryFromContainer(currentParent, node.stateNode);
20668 } else {
20669 clearSuspenseBoundary(currentParent, node.stateNode);
20670 }
20671 } else if (node.tag === HostPortal) {
20672 if (node.child !== null) {
20673 // When we go into a portal, it becomes the parent to remove from.
20674 // We will reassign it back when we pop the portal on the way up.
20675 currentParent = node.stateNode.containerInfo;
20676 currentParentIsContainer = true;
20677 // Visit children because portals might contain host components.
20678 node.child.return = node;
20679 node = node.child;
20680 continue;
20681 }
20682 } else {
20683 commitUnmount(node, renderPriorityLevel);
20684 // Visit children because we may find more host components below.
20685 if (node.child !== null) {
20686 node.child.return = node;
20687 node = node.child;
20688 continue;
20689 }
20690 }
20691 if (node === current$$1) {
20692 return;
20693 }
20694 while (node.sibling === null) {
20695 if (node.return === null || node.return === current$$1) {
20696 return;
20697 }
20698 node = node.return;
20699 if (node.tag === HostPortal) {
20700 // When we go out of the portal, we need to restore the parent.
20701 // Since we don't keep a stack of them, we will search for it.
20702 currentParentIsValid = false;
20703 }
20704 }
20705 node.sibling.return = node.return;
20706 node = node.sibling;
20707 }
20708}
20709
20710function commitDeletion(current$$1, renderPriorityLevel) {
20711 if (supportsMutation) {
20712 // Recursively delete all host nodes from the parent.
20713 // Detach refs and call componentWillUnmount() on the whole subtree.
20714 unmountHostComponents(current$$1, renderPriorityLevel);
20715 } else {
20716 // Detach refs and call componentWillUnmount() on the whole subtree.
20717 commitNestedUnmounts(current$$1, renderPriorityLevel);
20718 }
20719 detachFiber(current$$1);
20720}
20721
20722function commitWork(current$$1, finishedWork) {
20723 if (!supportsMutation) {
20724 switch (finishedWork.tag) {
20725 case FunctionComponent:
20726 case ForwardRef:
20727 case MemoComponent:
20728 case SimpleMemoComponent:
20729 {
20730 // Note: We currently never use MountMutation, but useLayout uses
20731 // UnmountMutation.
20732 commitHookEffectList(UnmountMutation, MountMutation, finishedWork);
20733 return;
20734 }
20735 case Profiler:
20736 {
20737 return;
20738 }
20739 case SuspenseComponent:
20740 {
20741 commitSuspenseComponent(finishedWork);
20742 attachSuspenseRetryListeners(finishedWork);
20743 return;
20744 }
20745 case SuspenseListComponent:
20746 {
20747 attachSuspenseRetryListeners(finishedWork);
20748 return;
20749 }
20750 }
20751
20752 commitContainer(finishedWork);
20753 return;
20754 }
20755
20756 switch (finishedWork.tag) {
20757 case FunctionComponent:
20758 case ForwardRef:
20759 case MemoComponent:
20760 case SimpleMemoComponent:
20761 {
20762 // Note: We currently never use MountMutation, but useLayout uses
20763 // UnmountMutation.
20764 commitHookEffectList(UnmountMutation, MountMutation, finishedWork);
20765 return;
20766 }
20767 case ClassComponent:
20768 {
20769 return;
20770 }
20771 case HostComponent:
20772 {
20773 var instance = finishedWork.stateNode;
20774 if (instance != null) {
20775 // Commit the work prepared earlier.
20776 var newProps = finishedWork.memoizedProps;
20777 // For hydration we reuse the update path but we treat the oldProps
20778 // as the newProps. The updatePayload will contain the real change in
20779 // this case.
20780 var oldProps = current$$1 !== null ? current$$1.memoizedProps : newProps;
20781 var type = finishedWork.type;
20782 // TODO: Type the updateQueue to be specific to host components.
20783 var updatePayload = finishedWork.updateQueue;
20784 finishedWork.updateQueue = null;
20785 if (updatePayload !== null) {
20786 commitUpdate(instance, updatePayload, type, oldProps, newProps, finishedWork);
20787 }
20788 }
20789 return;
20790 }
20791 case HostText:
20792 {
20793 (function () {
20794 if (!(finishedWork.stateNode !== null)) {
20795 {
20796 throw ReactError(Error('This should have a text node initialized. This error is likely caused by a bug in React. Please file an issue.'));
20797 }
20798 }
20799 })();
20800 var textInstance = finishedWork.stateNode;
20801 var newText = finishedWork.memoizedProps;
20802 // For hydration we reuse the update path but we treat the oldProps
20803 // as the newProps. The updatePayload will contain the real change in
20804 // this case.
20805 var oldText = current$$1 !== null ? current$$1.memoizedProps : newText;
20806 commitTextUpdate(textInstance, oldText, newText);
20807 return;
20808 }
20809 case HostRoot:
20810 {
20811 return;
20812 }
20813 case Profiler:
20814 {
20815 return;
20816 }
20817 case SuspenseComponent:
20818 {
20819 commitSuspenseComponent(finishedWork);
20820 attachSuspenseRetryListeners(finishedWork);
20821 return;
20822 }
20823 case SuspenseListComponent:
20824 {
20825 attachSuspenseRetryListeners(finishedWork);
20826 return;
20827 }
20828 case IncompleteClassComponent:
20829 {
20830 return;
20831 }
20832 case FundamentalComponent:
20833 {
20834 if (enableFundamentalAPI) {
20835 var fundamentalInstance = finishedWork.stateNode;
20836 updateFundamentalComponent(fundamentalInstance);
20837 }
20838 return;
20839 }
20840 default:
20841 {
20842 (function () {
20843 {
20844 {
20845 throw ReactError(Error('This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue.'));
20846 }
20847 }
20848 })();
20849 }
20850 }
20851}
20852
20853function commitSuspenseComponent(finishedWork) {
20854 var newState = finishedWork.memoizedState;
20855
20856 var newDidTimeout = void 0;
20857 var primaryChildParent = finishedWork;
20858 if (newState === null) {
20859 newDidTimeout = false;
20860 } else {
20861 newDidTimeout = true;
20862 primaryChildParent = finishedWork.child;
20863 markCommitTimeOfFallback();
20864 }
20865
20866 if (supportsMutation && primaryChildParent !== null) {
20867 hideOrUnhideAllChildren(primaryChildParent, newDidTimeout);
20868 }
20869
20870 if (enableSuspenseCallback && newState !== null) {
20871 var suspenseCallback = finishedWork.memoizedProps.suspenseCallback;
20872 if (typeof suspenseCallback === 'function') {
20873 var thenables = finishedWork.updateQueue;
20874 if (thenables !== null) {
20875 suspenseCallback(new Set(thenables));
20876 }
20877 } else {
20878 if (suspenseCallback !== undefined) {
20879 warning$1(false, 'Unexpected type for suspenseCallback.');
20880 }
20881 }
20882 }
20883}
20884
20885function attachSuspenseRetryListeners(finishedWork) {
20886 // If this boundary just timed out, then it will have a set of thenables.
20887 // For each thenable, attach a listener so that when it resolves, React
20888 var thenables = finishedWork.updateQueue;
20889 if (thenables !== null) {
20890 finishedWork.updateQueue = null;
20891 var retryCache = finishedWork.stateNode;
20892 if (retryCache === null) {
20893 retryCache = finishedWork.stateNode = new PossiblyWeakSet$1();
20894 }
20895 thenables.forEach(function (thenable) {
20896 // Memoize using the boundary fiber to prevent redundant listeners.
20897 var retry = resolveRetryThenable.bind(null, finishedWork, thenable);
20898 if (!retryCache.has(thenable)) {
20899 if (enableSchedulerTracing) {
20900 retry = tracing.unstable_wrap(retry);
20901 }
20902 retryCache.add(thenable);
20903 thenable.then(retry, retry);
20904 }
20905 });
20906 }
20907}
20908
20909function commitResetTextContent(current$$1) {
20910 if (!supportsMutation) {
20911 return;
20912 }
20913 resetTextContent(current$$1.stateNode);
20914}
20915
20916var PossiblyWeakSet = typeof WeakSet === 'function' ? WeakSet : Set;
20917var PossiblyWeakMap$1 = typeof WeakMap === 'function' ? WeakMap : Map;
20918
20919function createRootErrorUpdate(fiber, errorInfo, expirationTime) {
20920 var update = createUpdate(expirationTime, null);
20921 // Unmount the root by rendering null.
20922 update.tag = CaptureUpdate;
20923 // Caution: React DevTools currently depends on this property
20924 // being called "element".
20925 update.payload = { element: null };
20926 var error = errorInfo.value;
20927 update.callback = function () {
20928 onUncaughtError(error);
20929 logError(fiber, errorInfo);
20930 };
20931 return update;
20932}
20933
20934function createClassErrorUpdate(fiber, errorInfo, expirationTime) {
20935 var update = createUpdate(expirationTime, null);
20936 update.tag = CaptureUpdate;
20937 var getDerivedStateFromError = fiber.type.getDerivedStateFromError;
20938 if (typeof getDerivedStateFromError === 'function') {
20939 var error = errorInfo.value;
20940 update.payload = function () {
20941 logError(fiber, errorInfo);
20942 return getDerivedStateFromError(error);
20943 };
20944 }
20945
20946 var inst = fiber.stateNode;
20947 if (inst !== null && typeof inst.componentDidCatch === 'function') {
20948 update.callback = function callback() {
20949 {
20950 markFailedErrorBoundaryForHotReloading(fiber);
20951 }
20952 if (typeof getDerivedStateFromError !== 'function') {
20953 // To preserve the preexisting retry behavior of error boundaries,
20954 // we keep track of which ones already failed during this batch.
20955 // This gets reset before we yield back to the browser.
20956 // TODO: Warn in strict mode if getDerivedStateFromError is
20957 // not defined.
20958 markLegacyErrorBoundaryAsFailed(this);
20959
20960 // Only log here if componentDidCatch is the only error boundary method defined
20961 logError(fiber, errorInfo);
20962 }
20963 var error = errorInfo.value;
20964 var stack = errorInfo.stack;
20965 this.componentDidCatch(error, {
20966 componentStack: stack !== null ? stack : ''
20967 });
20968 {
20969 if (typeof getDerivedStateFromError !== 'function') {
20970 // If componentDidCatch is the only error boundary method defined,
20971 // then it needs to call setState to recover from errors.
20972 // If no state update is scheduled then the boundary will swallow the error.
20973 !(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;
20974 }
20975 }
20976 };
20977 } else {
20978 update.callback = function () {
20979 markFailedErrorBoundaryForHotReloading(fiber);
20980 };
20981 }
20982 return update;
20983}
20984
20985function attachPingListener(root, renderExpirationTime, thenable) {
20986 // Attach a listener to the promise to "ping" the root and retry. But
20987 // only if one does not already exist for the current render expiration
20988 // time (which acts like a "thread ID" here).
20989 var pingCache = root.pingCache;
20990 var threadIDs = void 0;
20991 if (pingCache === null) {
20992 pingCache = root.pingCache = new PossiblyWeakMap$1();
20993 threadIDs = new Set();
20994 pingCache.set(thenable, threadIDs);
20995 } else {
20996 threadIDs = pingCache.get(thenable);
20997 if (threadIDs === undefined) {
20998 threadIDs = new Set();
20999 pingCache.set(thenable, threadIDs);
21000 }
21001 }
21002 if (!threadIDs.has(renderExpirationTime)) {
21003 // Memoize using the thread ID to prevent redundant listeners.
21004 threadIDs.add(renderExpirationTime);
21005 var ping = pingSuspendedRoot.bind(null, root, thenable, renderExpirationTime);
21006 if (enableSchedulerTracing) {
21007 ping = tracing.unstable_wrap(ping);
21008 }
21009 thenable.then(ping, ping);
21010 }
21011}
21012
21013function throwException(root, returnFiber, sourceFiber, value, renderExpirationTime) {
21014 // The source fiber did not complete.
21015 sourceFiber.effectTag |= Incomplete;
21016 // Its effect list is no longer valid.
21017 sourceFiber.firstEffect = sourceFiber.lastEffect = null;
21018
21019 if (value !== null && typeof value === 'object' && typeof value.then === 'function') {
21020 // This is a thenable.
21021 var thenable = value;
21022
21023 checkForWrongSuspensePriorityInDEV(sourceFiber);
21024
21025 var hasInvisibleParentBoundary = hasSuspenseContext(suspenseStackCursor.current, InvisibleParentSuspenseContext);
21026
21027 // Schedule the nearest Suspense to re-render the timed out view.
21028 var _workInProgress = returnFiber;
21029 do {
21030 if (_workInProgress.tag === SuspenseComponent && shouldCaptureSuspense(_workInProgress, hasInvisibleParentBoundary)) {
21031 // Found the nearest boundary.
21032
21033 // Stash the promise on the boundary fiber. If the boundary times out, we'll
21034 var thenables = _workInProgress.updateQueue;
21035 if (thenables === null) {
21036 var updateQueue = new Set();
21037 updateQueue.add(thenable);
21038 _workInProgress.updateQueue = updateQueue;
21039 } else {
21040 thenables.add(thenable);
21041 }
21042
21043 // If the boundary is outside of batched mode, we should *not*
21044 // suspend the commit. Pretend as if the suspended component rendered
21045 // null and keep rendering. In the commit phase, we'll schedule a
21046 // subsequent synchronous update to re-render the Suspense.
21047 //
21048 // Note: It doesn't matter whether the component that suspended was
21049 // inside a batched mode tree. If the Suspense is outside of it, we
21050 // should *not* suspend the commit.
21051 if ((_workInProgress.mode & BatchedMode) === NoMode) {
21052 _workInProgress.effectTag |= DidCapture;
21053
21054 // We're going to commit this fiber even though it didn't complete.
21055 // But we shouldn't call any lifecycle methods or callbacks. Remove
21056 // all lifecycle effect tags.
21057 sourceFiber.effectTag &= ~(LifecycleEffectMask | Incomplete);
21058
21059 if (sourceFiber.tag === ClassComponent) {
21060 var currentSourceFiber = sourceFiber.alternate;
21061 if (currentSourceFiber === null) {
21062 // This is a new mount. Change the tag so it's not mistaken for a
21063 // completed class component. For example, we should not call
21064 // componentWillUnmount if it is deleted.
21065 sourceFiber.tag = IncompleteClassComponent;
21066 } else {
21067 // When we try rendering again, we should not reuse the current fiber,
21068 // since it's known to be in an inconsistent state. Use a force update to
21069 // prevent a bail out.
21070 var update = createUpdate(Sync, null);
21071 update.tag = ForceUpdate;
21072 enqueueUpdate(sourceFiber, update);
21073 }
21074 }
21075
21076 // The source fiber did not complete. Mark it with Sync priority to
21077 // indicate that it still has pending work.
21078 sourceFiber.expirationTime = Sync;
21079
21080 // Exit without suspending.
21081 return;
21082 }
21083
21084 // Confirmed that the boundary is in a concurrent mode tree. Continue
21085 // with the normal suspend path.
21086 //
21087 // After this we'll use a set of heuristics to determine whether this
21088 // render pass will run to completion or restart or "suspend" the commit.
21089 // The actual logic for this is spread out in different places.
21090 //
21091 // This first principle is that if we're going to suspend when we complete
21092 // a root, then we should also restart if we get an update or ping that
21093 // might unsuspend it, and vice versa. The only reason to suspend is
21094 // because you think you might want to restart before committing. However,
21095 // it doesn't make sense to restart only while in the period we're suspended.
21096 //
21097 // Restarting too aggressively is also not good because it starves out any
21098 // intermediate loading state. So we use heuristics to determine when.
21099
21100 // Suspense Heuristics
21101 //
21102 // If nothing threw a Promise or all the same fallbacks are already showing,
21103 // then don't suspend/restart.
21104 //
21105 // If this is an initial render of a new tree of Suspense boundaries and
21106 // those trigger a fallback, then don't suspend/restart. We want to ensure
21107 // that we can show the initial loading state as quickly as possible.
21108 //
21109 // If we hit a "Delayed" case, such as when we'd switch from content back into
21110 // a fallback, then we should always suspend/restart. SuspenseConfig applies to
21111 // this case. If none is defined, JND is used instead.
21112 //
21113 // If we're already showing a fallback and it gets "retried", allowing us to show
21114 // another level, but there's still an inner boundary that would show a fallback,
21115 // then we suspend/restart for 500ms since the last time we showed a fallback
21116 // anywhere in the tree. This effectively throttles progressive loading into a
21117 // consistent train of commits. This also gives us an opportunity to restart to
21118 // get to the completed state slightly earlier.
21119 //
21120 // If there's ambiguity due to batching it's resolved in preference of:
21121 // 1) "delayed", 2) "initial render", 3) "retry".
21122 //
21123 // We want to ensure that a "busy" state doesn't get force committed. We want to
21124 // ensure that new initial loading states can commit as soon as possible.
21125
21126 attachPingListener(root, renderExpirationTime, thenable);
21127
21128 _workInProgress.effectTag |= ShouldCapture;
21129 _workInProgress.expirationTime = renderExpirationTime;
21130
21131 return;
21132 } else if (enableSuspenseServerRenderer && _workInProgress.tag === DehydratedSuspenseComponent) {
21133 attachPingListener(root, renderExpirationTime, thenable);
21134
21135 // Since we already have a current fiber, we can eagerly add a retry listener.
21136 var retryCache = _workInProgress.memoizedState;
21137 if (retryCache === null) {
21138 retryCache = _workInProgress.memoizedState = new PossiblyWeakSet();
21139 var current$$1 = _workInProgress.alternate;
21140 (function () {
21141 if (!current$$1) {
21142 {
21143 throw ReactError(Error('A dehydrated suspense boundary must commit before trying to render. This is probably a bug in React.'));
21144 }
21145 }
21146 })();
21147 current$$1.memoizedState = retryCache;
21148 }
21149 // Memoize using the boundary fiber to prevent redundant listeners.
21150 if (!retryCache.has(thenable)) {
21151 retryCache.add(thenable);
21152 var retry = resolveRetryThenable.bind(null, _workInProgress, thenable);
21153 if (enableSchedulerTracing) {
21154 retry = tracing.unstable_wrap(retry);
21155 }
21156 thenable.then(retry, retry);
21157 }
21158 _workInProgress.effectTag |= ShouldCapture;
21159 _workInProgress.expirationTime = renderExpirationTime;
21160 return;
21161 }
21162 // This boundary already captured during this render. Continue to the next
21163 // boundary.
21164 _workInProgress = _workInProgress.return;
21165 } while (_workInProgress !== null);
21166 // No boundary was found. Fallthrough to error mode.
21167 // TODO: Use invariant so the message is stripped in prod?
21168 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));
21169 }
21170
21171 // We didn't find a boundary that could handle this type of exception. Start
21172 // over and traverse parent path again, this time treating the exception
21173 // as an error.
21174 renderDidError();
21175 value = createCapturedValue(value, sourceFiber);
21176 var workInProgress = returnFiber;
21177 do {
21178 switch (workInProgress.tag) {
21179 case HostRoot:
21180 {
21181 var _errorInfo = value;
21182 workInProgress.effectTag |= ShouldCapture;
21183 workInProgress.expirationTime = renderExpirationTime;
21184 var _update = createRootErrorUpdate(workInProgress, _errorInfo, renderExpirationTime);
21185 enqueueCapturedUpdate(workInProgress, _update);
21186 return;
21187 }
21188 case ClassComponent:
21189 // Capture and retry
21190 var errorInfo = value;
21191 var ctor = workInProgress.type;
21192 var instance = workInProgress.stateNode;
21193 if ((workInProgress.effectTag & DidCapture) === NoEffect && (typeof ctor.getDerivedStateFromError === 'function' || instance !== null && typeof instance.componentDidCatch === 'function' && !isAlreadyFailedLegacyErrorBoundary(instance))) {
21194 workInProgress.effectTag |= ShouldCapture;
21195 workInProgress.expirationTime = renderExpirationTime;
21196 // Schedule the error boundary to re-render using updated state
21197 var _update2 = createClassErrorUpdate(workInProgress, errorInfo, renderExpirationTime);
21198 enqueueCapturedUpdate(workInProgress, _update2);
21199 return;
21200 }
21201 break;
21202 default:
21203 break;
21204 }
21205 workInProgress = workInProgress.return;
21206 } while (workInProgress !== null);
21207}
21208
21209// The scheduler is imported here *only* to detect whether it's been mocked
21210// DEV stuff
21211var ceil = Math.ceil;
21212
21213var ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher;
21214var ReactCurrentOwner$2 = ReactSharedInternals.ReactCurrentOwner;
21215var IsSomeRendererActing = ReactSharedInternals.IsSomeRendererActing;
21216
21217
21218var NoContext = /* */0;
21219var BatchedContext = /* */1;
21220var EventContext = /* */2;
21221var DiscreteEventContext = /* */4;
21222var LegacyUnbatchedContext = /* */8;
21223var RenderContext = /* */16;
21224var CommitContext = /* */32;
21225
21226var RootIncomplete = 0;
21227var RootErrored = 1;
21228var RootSuspended = 2;
21229var RootSuspendedWithDelay = 3;
21230var RootCompleted = 4;
21231
21232// Describes where we are in the React execution stack
21233var executionContext = NoContext;
21234// The root we're working on
21235var workInProgressRoot = null;
21236// The fiber we're working on
21237var workInProgress = null;
21238// The expiration time we're rendering
21239var renderExpirationTime = NoWork;
21240// Whether to root completed, errored, suspended, etc.
21241var workInProgressRootExitStatus = RootIncomplete;
21242// Most recent event time among processed updates during this render.
21243// This is conceptually a time stamp but expressed in terms of an ExpirationTime
21244// because we deal mostly with expiration times in the hot path, so this avoids
21245// the conversion happening in the hot path.
21246var workInProgressRootLatestProcessedExpirationTime = Sync;
21247var workInProgressRootLatestSuspenseTimeout = Sync;
21248var workInProgressRootCanSuspendUsingConfig = null;
21249// If we're pinged while rendering we don't always restart immediately.
21250// This flag determines if it might be worthwhile to restart if an opportunity
21251// happens latere.
21252var workInProgressRootHasPendingPing = false;
21253// The most recent time we committed a fallback. This lets us ensure a train
21254// model where we don't commit new loading states in too quick succession.
21255var globalMostRecentFallbackTime = 0;
21256var FALLBACK_THROTTLE_MS = 500;
21257
21258var nextEffect = null;
21259var hasUncaughtError = false;
21260var firstUncaughtError = null;
21261var legacyErrorBoundariesThatAlreadyFailed = null;
21262
21263var rootDoesHavePassiveEffects = false;
21264var rootWithPendingPassiveEffects = null;
21265var pendingPassiveEffectsRenderPriority = NoPriority;
21266var pendingPassiveEffectsExpirationTime = NoWork;
21267
21268var rootsWithPendingDiscreteUpdates = null;
21269
21270// Use these to prevent an infinite loop of nested updates
21271var NESTED_UPDATE_LIMIT = 50;
21272var nestedUpdateCount = 0;
21273var rootWithNestedUpdates = null;
21274
21275var NESTED_PASSIVE_UPDATE_LIMIT = 50;
21276var nestedPassiveUpdateCount = 0;
21277
21278var interruptedBy = null;
21279
21280// Marks the need to reschedule pending interactions at these expiration times
21281// during the commit phase. This enables them to be traced across components
21282// that spawn new work during render. E.g. hidden boundaries, suspended SSR
21283// hydration or SuspenseList.
21284var spawnedWorkDuringRender = null;
21285
21286// Expiration times are computed by adding to the current time (the start
21287// time). However, if two updates are scheduled within the same event, we
21288// should treat their start times as simultaneous, even if the actual clock
21289// time has advanced between the first and second call.
21290
21291// In other words, because expiration times determine how updates are batched,
21292// we want all updates of like priority that occur within the same event to
21293// receive the same expiration time. Otherwise we get tearing.
21294var currentEventTime = NoWork;
21295
21296function requestCurrentTime() {
21297 if ((executionContext & (RenderContext | CommitContext)) !== NoContext) {
21298 // We're inside React, so it's fine to read the actual time.
21299 return msToExpirationTime(now());
21300 }
21301 // We're not inside React, so we may be in the middle of a browser event.
21302 if (currentEventTime !== NoWork) {
21303 // Use the same start time for all updates until we enter React again.
21304 return currentEventTime;
21305 }
21306 // This is the first update since React yielded. Compute a new start time.
21307 currentEventTime = msToExpirationTime(now());
21308 return currentEventTime;
21309}
21310
21311function computeExpirationForFiber(currentTime, fiber, suspenseConfig) {
21312 var mode = fiber.mode;
21313 if ((mode & BatchedMode) === NoMode) {
21314 return Sync;
21315 }
21316
21317 var priorityLevel = getCurrentPriorityLevel();
21318 if ((mode & ConcurrentMode) === NoMode) {
21319 return priorityLevel === ImmediatePriority ? Sync : Batched;
21320 }
21321
21322 if ((executionContext & RenderContext) !== NoContext) {
21323 // Use whatever time we're already rendering
21324 return renderExpirationTime;
21325 }
21326
21327 var expirationTime = void 0;
21328 if (suspenseConfig !== null) {
21329 // Compute an expiration time based on the Suspense timeout.
21330 expirationTime = computeSuspenseExpiration(currentTime, suspenseConfig.timeoutMs | 0 || LOW_PRIORITY_EXPIRATION);
21331 } else {
21332 // Compute an expiration time based on the Scheduler priority.
21333 switch (priorityLevel) {
21334 case ImmediatePriority:
21335 expirationTime = Sync;
21336 break;
21337 case UserBlockingPriority$2:
21338 // TODO: Rename this to computeUserBlockingExpiration
21339 expirationTime = computeInteractiveExpiration(currentTime);
21340 break;
21341 case NormalPriority:
21342 case LowPriority:
21343 // TODO: Handle LowPriority
21344 // TODO: Rename this to... something better.
21345 expirationTime = computeAsyncExpiration(currentTime);
21346 break;
21347 case IdlePriority:
21348 expirationTime = Never;
21349 break;
21350 default:
21351 (function () {
21352 {
21353 {
21354 throw ReactError(Error('Expected a valid priority level'));
21355 }
21356 }
21357 })();
21358 }
21359 }
21360
21361 // If we're in the middle of rendering a tree, do not update at the same
21362 // expiration time that is already rendering.
21363 // TODO: We shouldn't have to do this if the update is on a different root.
21364 // Refactor computeExpirationForFiber + scheduleUpdate so we have access to
21365 // the root when we check for this condition.
21366 if (workInProgressRoot !== null && expirationTime === renderExpirationTime) {
21367 // This is a trick to move this update into a separate batch
21368 expirationTime -= 1;
21369 }
21370
21371 return expirationTime;
21372}
21373
21374var lastUniqueAsyncExpiration = NoWork;
21375function computeUniqueAsyncExpiration() {
21376 var currentTime = requestCurrentTime();
21377 var result = computeAsyncExpiration(currentTime);
21378 if (result <= lastUniqueAsyncExpiration) {
21379 // Since we assume the current time monotonically increases, we only hit
21380 // this branch when computeUniqueAsyncExpiration is fired multiple times
21381 // within a 200ms window (or whatever the async bucket size is).
21382 result -= 1;
21383 }
21384 lastUniqueAsyncExpiration = result;
21385 return result;
21386}
21387
21388function scheduleUpdateOnFiber(fiber, expirationTime) {
21389 checkForNestedUpdates();
21390 warnAboutInvalidUpdatesOnClassComponentsInDEV(fiber);
21391
21392 var root = markUpdateTimeFromFiberToRoot(fiber, expirationTime);
21393 if (root === null) {
21394 warnAboutUpdateOnUnmountedFiberInDEV(fiber);
21395 return;
21396 }
21397
21398 root.pingTime = NoWork;
21399
21400 checkForInterruption(fiber, expirationTime);
21401 recordScheduleUpdate();
21402
21403 // TODO: computeExpirationForFiber also reads the priority. Pass the
21404 // priority as an argument to that function and this one.
21405 var priorityLevel = getCurrentPriorityLevel();
21406
21407 if (expirationTime === Sync) {
21408 if (
21409 // Check if we're inside unbatchedUpdates
21410 (executionContext & LegacyUnbatchedContext) !== NoContext &&
21411 // Check if we're not already rendering
21412 (executionContext & (RenderContext | CommitContext)) === NoContext) {
21413 // Register pending interactions on the root to avoid losing traced interaction data.
21414 schedulePendingInteractions(root, expirationTime);
21415
21416 // This is a legacy edge case. The initial mount of a ReactDOM.render-ed
21417 // root inside of batchedUpdates should be synchronous, but layout updates
21418 // should be deferred until the end of the batch.
21419 var callback = renderRoot(root, Sync, true);
21420 while (callback !== null) {
21421 callback = callback(true);
21422 }
21423 } else {
21424 scheduleCallbackForRoot(root, ImmediatePriority, Sync);
21425 if (executionContext === NoContext) {
21426 // Flush the synchronous work now, wnless we're already working or inside
21427 // a batch. This is intentionally inside scheduleUpdateOnFiber instead of
21428 // scheduleCallbackForFiber to preserve the ability to schedule a callback
21429 // without immediately flushing it. We only do this for user-initiated
21430 // updates, to preserve historical behavior of sync mode.
21431 flushSyncCallbackQueue();
21432 }
21433 }
21434 } else {
21435 scheduleCallbackForRoot(root, priorityLevel, expirationTime);
21436 }
21437
21438 if ((executionContext & DiscreteEventContext) !== NoContext && (
21439 // Only updates at user-blocking priority or greater are considered
21440 // discrete, even inside a discrete event.
21441 priorityLevel === UserBlockingPriority$2 || priorityLevel === ImmediatePriority)) {
21442 // This is the result of a discrete event. Track the lowest priority
21443 // discrete update per root so we can flush them early, if needed.
21444 if (rootsWithPendingDiscreteUpdates === null) {
21445 rootsWithPendingDiscreteUpdates = new Map([[root, expirationTime]]);
21446 } else {
21447 var lastDiscreteTime = rootsWithPendingDiscreteUpdates.get(root);
21448 if (lastDiscreteTime === undefined || lastDiscreteTime > expirationTime) {
21449 rootsWithPendingDiscreteUpdates.set(root, expirationTime);
21450 }
21451 }
21452 }
21453}
21454var scheduleWork = scheduleUpdateOnFiber;
21455
21456// This is split into a separate function so we can mark a fiber with pending
21457// work without treating it as a typical update that originates from an event;
21458// e.g. retrying a Suspense boundary isn't an update, but it does schedule work
21459// on a fiber.
21460function markUpdateTimeFromFiberToRoot(fiber, expirationTime) {
21461 // Update the source fiber's expiration time
21462 if (fiber.expirationTime < expirationTime) {
21463 fiber.expirationTime = expirationTime;
21464 }
21465 var alternate = fiber.alternate;
21466 if (alternate !== null && alternate.expirationTime < expirationTime) {
21467 alternate.expirationTime = expirationTime;
21468 }
21469 // Walk the parent path to the root and update the child expiration time.
21470 var node = fiber.return;
21471 var root = null;
21472 if (node === null && fiber.tag === HostRoot) {
21473 root = fiber.stateNode;
21474 } else {
21475 while (node !== null) {
21476 alternate = node.alternate;
21477 if (node.childExpirationTime < expirationTime) {
21478 node.childExpirationTime = expirationTime;
21479 if (alternate !== null && alternate.childExpirationTime < expirationTime) {
21480 alternate.childExpirationTime = expirationTime;
21481 }
21482 } else if (alternate !== null && alternate.childExpirationTime < expirationTime) {
21483 alternate.childExpirationTime = expirationTime;
21484 }
21485 if (node.return === null && node.tag === HostRoot) {
21486 root = node.stateNode;
21487 break;
21488 }
21489 node = node.return;
21490 }
21491 }
21492
21493 if (root !== null) {
21494 // Update the first and last pending expiration times in this root
21495 var firstPendingTime = root.firstPendingTime;
21496 if (expirationTime > firstPendingTime) {
21497 root.firstPendingTime = expirationTime;
21498 }
21499 var lastPendingTime = root.lastPendingTime;
21500 if (lastPendingTime === NoWork || expirationTime < lastPendingTime) {
21501 root.lastPendingTime = expirationTime;
21502 }
21503 }
21504
21505 return root;
21506}
21507
21508// Use this function, along with runRootCallback, to ensure that only a single
21509// callback per root is scheduled. It's still possible to call renderRoot
21510// directly, but scheduling via this function helps avoid excessive callbacks.
21511// It works by storing the callback node and expiration time on the root. When a
21512// new callback comes in, it compares the expiration time to determine if it
21513// should cancel the previous one. It also relies on commitRoot scheduling a
21514// callback to render the next level, because that means we don't need a
21515// separate callback per expiration time.
21516function scheduleCallbackForRoot(root, priorityLevel, expirationTime) {
21517 var existingCallbackExpirationTime = root.callbackExpirationTime;
21518 if (existingCallbackExpirationTime < expirationTime) {
21519 // New callback has higher priority than the existing one.
21520 var existingCallbackNode = root.callbackNode;
21521 if (existingCallbackNode !== null) {
21522 cancelCallback(existingCallbackNode);
21523 }
21524 root.callbackExpirationTime = expirationTime;
21525
21526 if (expirationTime === Sync) {
21527 // Sync React callbacks are scheduled on a special internal queue
21528 root.callbackNode = scheduleSyncCallback(runRootCallback.bind(null, root, renderRoot.bind(null, root, expirationTime)));
21529 } else {
21530 var options = null;
21531 if (!disableSchedulerTimeoutBasedOnReactExpirationTime && expirationTime !== Never) {
21532 var timeout = expirationTimeToMs(expirationTime) - now();
21533 options = { timeout: timeout };
21534 }
21535
21536 root.callbackNode = scheduleCallback(priorityLevel, runRootCallback.bind(null, root, renderRoot.bind(null, root, expirationTime)), options);
21537 if (enableUserTimingAPI && expirationTime !== Sync && (executionContext & (RenderContext | CommitContext)) === NoContext) {
21538 // Scheduled an async callback, and we're not already working. Add an
21539 // entry to the flamegraph that shows we're waiting for a callback
21540 // to fire.
21541 startRequestCallbackTimer();
21542 }
21543 }
21544 }
21545
21546 // Associate the current interactions with this new root+priority.
21547 schedulePendingInteractions(root, expirationTime);
21548}
21549
21550function runRootCallback(root, callback, isSync) {
21551 var prevCallbackNode = root.callbackNode;
21552 var continuation = null;
21553 try {
21554 continuation = callback(isSync);
21555 if (continuation !== null) {
21556 return runRootCallback.bind(null, root, continuation);
21557 } else {
21558 return null;
21559 }
21560 } finally {
21561 // If the callback exits without returning a continuation, remove the
21562 // corresponding callback node from the root. Unless the callback node
21563 // has changed, which implies that it was already cancelled by a high
21564 // priority update.
21565 if (continuation === null && prevCallbackNode === root.callbackNode) {
21566 root.callbackNode = null;
21567 root.callbackExpirationTime = NoWork;
21568 }
21569 }
21570}
21571
21572function flushRoot(root, expirationTime) {
21573 if ((executionContext & (RenderContext | CommitContext)) !== NoContext) {
21574 (function () {
21575 {
21576 {
21577 throw ReactError(Error('work.commit(): Cannot commit while already rendering. This likely means you attempted to commit from inside a lifecycle method.'));
21578 }
21579 }
21580 })();
21581 }
21582 scheduleSyncCallback(renderRoot.bind(null, root, expirationTime));
21583 flushSyncCallbackQueue();
21584}
21585
21586function flushDiscreteUpdates() {
21587 // TODO: Should be able to flush inside batchedUpdates, but not inside `act`.
21588 // However, `act` uses `batchedUpdates`, so there's no way to distinguish
21589 // those two cases. Need to fix this before exposing flushDiscreteUpdates
21590 // as a public API.
21591 if ((executionContext & (BatchedContext | RenderContext | CommitContext)) !== NoContext) {
21592 if (true && (executionContext & RenderContext) !== NoContext) {
21593 warning$1(false, 'unstable_flushDiscreteUpdates: Cannot flush updates when React is ' + 'already rendering.');
21594 }
21595 // We're already rendering, so we can't synchronously flush pending work.
21596 // This is probably a nested event dispatch triggered by a lifecycle/effect,
21597 // like `el.focus()`. Exit.
21598 return;
21599 }
21600 flushPendingDiscreteUpdates();
21601 if (!revertPassiveEffectsChange) {
21602 // If the discrete updates scheduled passive effects, flush them now so that
21603 // they fire before the next serial event.
21604 flushPassiveEffects();
21605 }
21606}
21607
21608function resolveLocksOnRoot(root, expirationTime) {
21609 var firstBatch = root.firstBatch;
21610 if (firstBatch !== null && firstBatch._defer && firstBatch._expirationTime >= expirationTime) {
21611 scheduleCallback(NormalPriority, function () {
21612 firstBatch._onComplete();
21613 return null;
21614 });
21615 return true;
21616 } else {
21617 return false;
21618 }
21619}
21620
21621
21622
21623
21624
21625function flushPendingDiscreteUpdates() {
21626 if (rootsWithPendingDiscreteUpdates !== null) {
21627 // For each root with pending discrete updates, schedule a callback to
21628 // immediately flush them.
21629 var roots = rootsWithPendingDiscreteUpdates;
21630 rootsWithPendingDiscreteUpdates = null;
21631 roots.forEach(function (expirationTime, root) {
21632 scheduleSyncCallback(renderRoot.bind(null, root, expirationTime));
21633 });
21634 // Now flush the immediate queue.
21635 flushSyncCallbackQueue();
21636 }
21637}
21638
21639function batchedUpdates$1(fn, a) {
21640 var prevExecutionContext = executionContext;
21641 executionContext |= BatchedContext;
21642 try {
21643 return fn(a);
21644 } finally {
21645 executionContext = prevExecutionContext;
21646 if (executionContext === NoContext) {
21647 // Flush the immediate callbacks that were scheduled during this batch
21648 flushSyncCallbackQueue();
21649 }
21650 }
21651}
21652
21653function batchedEventUpdates$1(fn, a) {
21654 var prevExecutionContext = executionContext;
21655 executionContext |= EventContext;
21656 try {
21657 return fn(a);
21658 } finally {
21659 executionContext = prevExecutionContext;
21660 if (executionContext === NoContext) {
21661 // Flush the immediate callbacks that were scheduled during this batch
21662 flushSyncCallbackQueue();
21663 }
21664 }
21665}
21666
21667function discreteUpdates$1(fn, a, b, c) {
21668 var prevExecutionContext = executionContext;
21669 executionContext |= DiscreteEventContext;
21670 try {
21671 // Should this
21672 return runWithPriority$2(UserBlockingPriority$2, fn.bind(null, a, b, c));
21673 } finally {
21674 executionContext = prevExecutionContext;
21675 if (executionContext === NoContext) {
21676 // Flush the immediate callbacks that were scheduled during this batch
21677 flushSyncCallbackQueue();
21678 }
21679 }
21680}
21681
21682function unbatchedUpdates(fn, a) {
21683 var prevExecutionContext = executionContext;
21684 executionContext &= ~BatchedContext;
21685 executionContext |= LegacyUnbatchedContext;
21686 try {
21687 return fn(a);
21688 } finally {
21689 executionContext = prevExecutionContext;
21690 if (executionContext === NoContext) {
21691 // Flush the immediate callbacks that were scheduled during this batch
21692 flushSyncCallbackQueue();
21693 }
21694 }
21695}
21696
21697function flushSync(fn, a) {
21698 if ((executionContext & (RenderContext | CommitContext)) !== NoContext) {
21699 (function () {
21700 {
21701 {
21702 throw ReactError(Error('flushSync was called from inside a lifecycle method. It cannot be called when React is already rendering.'));
21703 }
21704 }
21705 })();
21706 }
21707 var prevExecutionContext = executionContext;
21708 executionContext |= BatchedContext;
21709 try {
21710 return runWithPriority$2(ImmediatePriority, fn.bind(null, a));
21711 } finally {
21712 executionContext = prevExecutionContext;
21713 // Flush the immediate callbacks that were scheduled during this batch.
21714 // Note that this will happen even if batchedUpdates is higher up
21715 // the stack.
21716 flushSyncCallbackQueue();
21717 }
21718}
21719
21720function flushControlled(fn) {
21721 var prevExecutionContext = executionContext;
21722 executionContext |= BatchedContext;
21723 try {
21724 runWithPriority$2(ImmediatePriority, fn);
21725 } finally {
21726 executionContext = prevExecutionContext;
21727 if (executionContext === NoContext) {
21728 // Flush the immediate callbacks that were scheduled during this batch
21729 flushSyncCallbackQueue();
21730 }
21731 }
21732}
21733
21734function prepareFreshStack(root, expirationTime) {
21735 root.finishedWork = null;
21736 root.finishedExpirationTime = NoWork;
21737
21738 var timeoutHandle = root.timeoutHandle;
21739 if (timeoutHandle !== noTimeout) {
21740 // The root previous suspended and scheduled a timeout to commit a fallback
21741 // state. Now that we have additional work, cancel the timeout.
21742 root.timeoutHandle = noTimeout;
21743 // $FlowFixMe Complains noTimeout is not a TimeoutID, despite the check above
21744 cancelTimeout(timeoutHandle);
21745 }
21746
21747 if (workInProgress !== null) {
21748 var interruptedWork = workInProgress.return;
21749 while (interruptedWork !== null) {
21750 unwindInterruptedWork(interruptedWork);
21751 interruptedWork = interruptedWork.return;
21752 }
21753 }
21754 workInProgressRoot = root;
21755 workInProgress = createWorkInProgress(root.current, null, expirationTime);
21756 renderExpirationTime = expirationTime;
21757 workInProgressRootExitStatus = RootIncomplete;
21758 workInProgressRootLatestProcessedExpirationTime = Sync;
21759 workInProgressRootLatestSuspenseTimeout = Sync;
21760 workInProgressRootCanSuspendUsingConfig = null;
21761 workInProgressRootHasPendingPing = false;
21762
21763 if (enableSchedulerTracing) {
21764 spawnedWorkDuringRender = null;
21765 }
21766
21767 {
21768 ReactStrictModeWarnings.discardPendingWarnings();
21769 componentsThatTriggeredHighPriSuspend = null;
21770 }
21771}
21772
21773function renderRoot(root, expirationTime, isSync) {
21774 (function () {
21775 if (!((executionContext & (RenderContext | CommitContext)) === NoContext)) {
21776 {
21777 throw ReactError(Error('Should not already be working.'));
21778 }
21779 }
21780 })();
21781
21782 if (enableUserTimingAPI && expirationTime !== Sync) {
21783 var didExpire = isSync;
21784 stopRequestCallbackTimer(didExpire);
21785 }
21786
21787 if (root.firstPendingTime < expirationTime) {
21788 // If there's no work left at this expiration time, exit immediately. This
21789 // happens when multiple callbacks are scheduled for a single root, but an
21790 // earlier callback flushes the work of a later one.
21791 return null;
21792 }
21793
21794 if (isSync && root.finishedExpirationTime === expirationTime) {
21795 // There's already a pending commit at this expiration time.
21796 // TODO: This is poorly factored. This case only exists for the
21797 // batch.commit() API.
21798 return commitRoot.bind(null, root);
21799 }
21800
21801 flushPassiveEffects();
21802
21803 // If the root or expiration time have changed, throw out the existing stack
21804 // and prepare a fresh one. Otherwise we'll continue where we left off.
21805 if (root !== workInProgressRoot || expirationTime !== renderExpirationTime) {
21806 prepareFreshStack(root, expirationTime);
21807 startWorkOnPendingInteractions(root, expirationTime);
21808 } else if (workInProgressRootExitStatus === RootSuspendedWithDelay) {
21809 // We could've received an update at a lower priority while we yielded.
21810 // We're suspended in a delayed state. Once we complete this render we're
21811 // just going to try to recover at the last pending time anyway so we might
21812 // as well start doing that eagerly.
21813 // Ideally we should be able to do this even for retries but we don't yet
21814 // know if we're going to process an update which wants to commit earlier,
21815 // and this path happens very early so it would happen too often. Instead,
21816 // for that case, we'll wait until we complete.
21817 if (workInProgressRootHasPendingPing) {
21818 // We have a ping at this expiration. Let's restart to see if we get unblocked.
21819 prepareFreshStack(root, expirationTime);
21820 } else {
21821 var lastPendingTime = root.lastPendingTime;
21822 if (lastPendingTime < expirationTime) {
21823 // There's lower priority work. It might be unsuspended. Try rendering
21824 // at that level immediately, while preserving the position in the queue.
21825 return renderRoot.bind(null, root, lastPendingTime);
21826 }
21827 }
21828 }
21829
21830 // If we have a work-in-progress fiber, it means there's still work to do
21831 // in this root.
21832 if (workInProgress !== null) {
21833 var prevExecutionContext = executionContext;
21834 executionContext |= RenderContext;
21835 var prevDispatcher = ReactCurrentDispatcher.current;
21836 if (prevDispatcher === null) {
21837 // The React isomorphic package does not include a default dispatcher.
21838 // Instead the first renderer will lazily attach one, in order to give
21839 // nicer error messages.
21840 prevDispatcher = ContextOnlyDispatcher;
21841 }
21842 ReactCurrentDispatcher.current = ContextOnlyDispatcher;
21843 var prevInteractions = null;
21844 if (enableSchedulerTracing) {
21845 prevInteractions = tracing.__interactionsRef.current;
21846 tracing.__interactionsRef.current = root.memoizedInteractions;
21847 }
21848
21849 startWorkLoopTimer(workInProgress);
21850
21851 // TODO: Fork renderRoot into renderRootSync and renderRootAsync
21852 if (isSync) {
21853 if (expirationTime !== Sync) {
21854 // An async update expired. There may be other expired updates on
21855 // this root. We should render all the expired work in a
21856 // single batch.
21857 var currentTime = requestCurrentTime();
21858 if (currentTime < expirationTime) {
21859 // Restart at the current time.
21860 executionContext = prevExecutionContext;
21861 resetContextDependencies();
21862 ReactCurrentDispatcher.current = prevDispatcher;
21863 if (enableSchedulerTracing) {
21864 tracing.__interactionsRef.current = prevInteractions;
21865 }
21866 return renderRoot.bind(null, root, currentTime);
21867 }
21868 }
21869 } else {
21870 // Since we know we're in a React event, we can clear the current
21871 // event time. The next update will compute a new event time.
21872 currentEventTime = NoWork;
21873 }
21874
21875 do {
21876 try {
21877 if (isSync) {
21878 workLoopSync();
21879 } else {
21880 workLoop();
21881 }
21882 break;
21883 } catch (thrownValue) {
21884 // Reset module-level state that was set during the render phase.
21885 resetContextDependencies();
21886 resetHooks();
21887
21888 var sourceFiber = workInProgress;
21889 if (sourceFiber === null || sourceFiber.return === null) {
21890 // Expected to be working on a non-root fiber. This is a fatal error
21891 // because there's no ancestor that can handle it; the root is
21892 // supposed to capture all errors that weren't caught by an error
21893 // boundary.
21894 prepareFreshStack(root, expirationTime);
21895 executionContext = prevExecutionContext;
21896 throw thrownValue;
21897 }
21898
21899 if (enableProfilerTimer && sourceFiber.mode & ProfileMode) {
21900 // Record the time spent rendering before an error was thrown. This
21901 // avoids inaccurate Profiler durations in the case of a
21902 // suspended render.
21903 stopProfilerTimerIfRunningAndRecordDelta(sourceFiber, true);
21904 }
21905
21906 var returnFiber = sourceFiber.return;
21907 throwException(root, returnFiber, sourceFiber, thrownValue, renderExpirationTime);
21908 workInProgress = completeUnitOfWork(sourceFiber);
21909 }
21910 } while (true);
21911
21912 executionContext = prevExecutionContext;
21913 resetContextDependencies();
21914 ReactCurrentDispatcher.current = prevDispatcher;
21915 if (enableSchedulerTracing) {
21916 tracing.__interactionsRef.current = prevInteractions;
21917 }
21918
21919 if (workInProgress !== null) {
21920 // There's still work left over. Return a continuation.
21921 stopInterruptedWorkLoopTimer();
21922 if (expirationTime !== Sync) {
21923 startRequestCallbackTimer();
21924 }
21925 return renderRoot.bind(null, root, expirationTime);
21926 }
21927 }
21928
21929 // We now have a consistent tree. The next step is either to commit it, or, if
21930 // something suspended, wait to commit it after a timeout.
21931 stopFinishedWorkLoopTimer();
21932
21933 root.finishedWork = root.current.alternate;
21934 root.finishedExpirationTime = expirationTime;
21935
21936 var isLocked = resolveLocksOnRoot(root, expirationTime);
21937 if (isLocked) {
21938 // This root has a lock that prevents it from committing. Exit. If we begin
21939 // work on the root again, without any intervening updates, it will finish
21940 // without doing additional work.
21941 return null;
21942 }
21943
21944 // Set this to null to indicate there's no in-progress render.
21945 workInProgressRoot = null;
21946
21947 switch (workInProgressRootExitStatus) {
21948 case RootIncomplete:
21949 {
21950 (function () {
21951 {
21952 {
21953 throw ReactError(Error('Should have a work-in-progress.'));
21954 }
21955 }
21956 })();
21957 }
21958 // Flow knows about invariant, so it complains if I add a break statement,
21959 // but eslint doesn't know about invariant, so it complains if I do.
21960 // eslint-disable-next-line no-fallthrough
21961 case RootErrored:
21962 {
21963 // An error was thrown. First check if there is lower priority work
21964 // scheduled on this root.
21965 var _lastPendingTime = root.lastPendingTime;
21966 if (_lastPendingTime < expirationTime) {
21967 // There's lower priority work. Before raising the error, try rendering
21968 // at the lower priority to see if it fixes it. Use a continuation to
21969 // maintain the existing priority and position in the queue.
21970 return renderRoot.bind(null, root, _lastPendingTime);
21971 }
21972 if (!isSync) {
21973 // If we're rendering asynchronously, it's possible the error was
21974 // caused by tearing due to a mutation during an event. Try rendering
21975 // one more time without yiedling to events.
21976 prepareFreshStack(root, expirationTime);
21977 scheduleSyncCallback(renderRoot.bind(null, root, expirationTime));
21978 return null;
21979 }
21980 // If we're already rendering synchronously, commit the root in its
21981 // errored state.
21982 return commitRoot.bind(null, root);
21983 }
21984 case RootSuspended:
21985 {
21986 flushSuspensePriorityWarningInDEV();
21987
21988 // We have an acceptable loading state. We need to figure out if we should
21989 // immediately commit it or wait a bit.
21990
21991 // If we have processed new updates during this render, we may now have a
21992 // new loading state ready. We want to ensure that we commit that as soon as
21993 // possible.
21994 var hasNotProcessedNewUpdates = workInProgressRootLatestProcessedExpirationTime === Sync;
21995 if (hasNotProcessedNewUpdates && !isSync &&
21996 // do not delay if we're inside an act() scope
21997 !(true && flushSuspenseFallbacksInTests && IsThisRendererActing.current)) {
21998 // If we have not processed any new updates during this pass, then this is
21999 // either a retry of an existing fallback state or a hidden tree.
22000 // Hidden trees shouldn't be batched with other work and after that's
22001 // fixed it can only be a retry.
22002 // We're going to throttle committing retries so that we don't show too
22003 // many loading states too quickly.
22004 var msUntilTimeout = globalMostRecentFallbackTime + FALLBACK_THROTTLE_MS - now();
22005 // Don't bother with a very short suspense time.
22006 if (msUntilTimeout > 10) {
22007 if (workInProgressRootHasPendingPing) {
22008 // This render was pinged but we didn't get to restart earlier so try
22009 // restarting now instead.
22010 prepareFreshStack(root, expirationTime);
22011 return renderRoot.bind(null, root, expirationTime);
22012 }
22013 var _lastPendingTime2 = root.lastPendingTime;
22014 if (_lastPendingTime2 < expirationTime) {
22015 // There's lower priority work. It might be unsuspended. Try rendering
22016 // at that level.
22017 return renderRoot.bind(null, root, _lastPendingTime2);
22018 }
22019 // The render is suspended, it hasn't timed out, and there's no lower
22020 // priority work to do. Instead of committing the fallback
22021 // immediately, wait for more data to arrive.
22022 root.timeoutHandle = scheduleTimeout(commitRoot.bind(null, root), msUntilTimeout);
22023 return null;
22024 }
22025 }
22026 // The work expired. Commit immediately.
22027 return commitRoot.bind(null, root);
22028 }
22029 case RootSuspendedWithDelay:
22030 {
22031 flushSuspensePriorityWarningInDEV();
22032
22033 if (!isSync &&
22034 // do not delay if we're inside an act() scope
22035 !(true && flushSuspenseFallbacksInTests && IsThisRendererActing.current)) {
22036 // We're suspended in a state that should be avoided. We'll try to avoid committing
22037 // it for as long as the timeouts let us.
22038 if (workInProgressRootHasPendingPing) {
22039 // This render was pinged but we didn't get to restart earlier so try
22040 // restarting now instead.
22041 prepareFreshStack(root, expirationTime);
22042 return renderRoot.bind(null, root, expirationTime);
22043 }
22044 var _lastPendingTime3 = root.lastPendingTime;
22045 if (_lastPendingTime3 < expirationTime) {
22046 // There's lower priority work. It might be unsuspended. Try rendering
22047 // at that level immediately.
22048 return renderRoot.bind(null, root, _lastPendingTime3);
22049 }
22050
22051 var _msUntilTimeout = void 0;
22052 if (workInProgressRootLatestSuspenseTimeout !== Sync) {
22053 // We have processed a suspense config whose expiration time we can use as
22054 // the timeout.
22055 _msUntilTimeout = expirationTimeToMs(workInProgressRootLatestSuspenseTimeout) - now();
22056 } else if (workInProgressRootLatestProcessedExpirationTime === Sync) {
22057 // This should never normally happen because only new updates cause
22058 // delayed states, so we should have processed something. However,
22059 // this could also happen in an offscreen tree.
22060 _msUntilTimeout = 0;
22061 } else {
22062 // If we don't have a suspense config, we're going to use a heuristic to
22063 var eventTimeMs = inferTimeFromExpirationTime(workInProgressRootLatestProcessedExpirationTime);
22064 var currentTimeMs = now();
22065 var timeUntilExpirationMs = expirationTimeToMs(expirationTime) - currentTimeMs;
22066 var timeElapsed = currentTimeMs - eventTimeMs;
22067 if (timeElapsed < 0) {
22068 // We get this wrong some time since we estimate the time.
22069 timeElapsed = 0;
22070 }
22071
22072 _msUntilTimeout = jnd(timeElapsed) - timeElapsed;
22073
22074 // Clamp the timeout to the expiration time.
22075 // TODO: Once the event time is exact instead of inferred from expiration time
22076 // we don't need this.
22077 if (timeUntilExpirationMs < _msUntilTimeout) {
22078 _msUntilTimeout = timeUntilExpirationMs;
22079 }
22080 }
22081
22082 // Don't bother with a very short suspense time.
22083 if (_msUntilTimeout > 10) {
22084 // The render is suspended, it hasn't timed out, and there's no lower
22085 // priority work to do. Instead of committing the fallback
22086 // immediately, wait for more data to arrive.
22087 root.timeoutHandle = scheduleTimeout(commitRoot.bind(null, root), _msUntilTimeout);
22088 return null;
22089 }
22090 }
22091 // The work expired. Commit immediately.
22092 return commitRoot.bind(null, root);
22093 }
22094 case RootCompleted:
22095 {
22096 // The work completed. Ready to commit.
22097 if (!isSync &&
22098 // do not delay if we're inside an act() scope
22099 !(true && flushSuspenseFallbacksInTests && IsThisRendererActing.current) && workInProgressRootLatestProcessedExpirationTime !== Sync && workInProgressRootCanSuspendUsingConfig !== null) {
22100 // If we have exceeded the minimum loading delay, which probably
22101 // means we have shown a spinner already, we might have to suspend
22102 // a bit longer to ensure that the spinner is shown for enough time.
22103 var _msUntilTimeout2 = computeMsUntilSuspenseLoadingDelay(workInProgressRootLatestProcessedExpirationTime, expirationTime, workInProgressRootCanSuspendUsingConfig);
22104 if (_msUntilTimeout2 > 10) {
22105 root.timeoutHandle = scheduleTimeout(commitRoot.bind(null, root), _msUntilTimeout2);
22106 return null;
22107 }
22108 }
22109 return commitRoot.bind(null, root);
22110 }
22111 default:
22112 {
22113 (function () {
22114 {
22115 {
22116 throw ReactError(Error('Unknown root exit status.'));
22117 }
22118 }
22119 })();
22120 }
22121 }
22122}
22123
22124function markCommitTimeOfFallback() {
22125 globalMostRecentFallbackTime = now();
22126}
22127
22128function markRenderEventTimeAndConfig(expirationTime, suspenseConfig) {
22129 if (expirationTime < workInProgressRootLatestProcessedExpirationTime && expirationTime > Never) {
22130 workInProgressRootLatestProcessedExpirationTime = expirationTime;
22131 }
22132 if (suspenseConfig !== null) {
22133 if (expirationTime < workInProgressRootLatestSuspenseTimeout && expirationTime > Never) {
22134 workInProgressRootLatestSuspenseTimeout = expirationTime;
22135 // Most of the time we only have one config and getting wrong is not bad.
22136 workInProgressRootCanSuspendUsingConfig = suspenseConfig;
22137 }
22138 }
22139}
22140
22141function renderDidSuspend() {
22142 if (workInProgressRootExitStatus === RootIncomplete) {
22143 workInProgressRootExitStatus = RootSuspended;
22144 }
22145}
22146
22147function renderDidSuspendDelayIfPossible() {
22148 if (workInProgressRootExitStatus === RootIncomplete || workInProgressRootExitStatus === RootSuspended) {
22149 workInProgressRootExitStatus = RootSuspendedWithDelay;
22150 }
22151}
22152
22153function renderDidError() {
22154 if (workInProgressRootExitStatus !== RootCompleted) {
22155 workInProgressRootExitStatus = RootErrored;
22156 }
22157}
22158
22159// Called during render to determine if anything has suspended.
22160// Returns false if we're not sure.
22161function renderHasNotSuspendedYet() {
22162 // If something errored or completed, we can't really be sure,
22163 // so those are false.
22164 return workInProgressRootExitStatus === RootIncomplete;
22165}
22166
22167function inferTimeFromExpirationTime(expirationTime) {
22168 // We don't know exactly when the update was scheduled, but we can infer an
22169 // approximate start time from the expiration time.
22170 var earliestExpirationTimeMs = expirationTimeToMs(expirationTime);
22171 return earliestExpirationTimeMs - LOW_PRIORITY_EXPIRATION;
22172}
22173
22174function inferTimeFromExpirationTimeWithSuspenseConfig(expirationTime, suspenseConfig) {
22175 // We don't know exactly when the update was scheduled, but we can infer an
22176 // approximate start time from the expiration time by subtracting the timeout
22177 // that was added to the event time.
22178 var earliestExpirationTimeMs = expirationTimeToMs(expirationTime);
22179 return earliestExpirationTimeMs - (suspenseConfig.timeoutMs | 0 || LOW_PRIORITY_EXPIRATION);
22180}
22181
22182function workLoopSync() {
22183 // Already timed out, so perform work without checking if we need to yield.
22184 while (workInProgress !== null) {
22185 workInProgress = performUnitOfWork(workInProgress);
22186 }
22187}
22188
22189function workLoop() {
22190 // Perform work until Scheduler asks us to yield
22191 while (workInProgress !== null && !shouldYield()) {
22192 workInProgress = performUnitOfWork(workInProgress);
22193 }
22194}
22195
22196function performUnitOfWork(unitOfWork) {
22197 // The current, flushed, state of this fiber is the alternate. Ideally
22198 // nothing should rely on this, but relying on it here means that we don't
22199 // need an additional field on the work in progress.
22200 var current$$1 = unitOfWork.alternate;
22201
22202 startWorkTimer(unitOfWork);
22203 setCurrentFiber(unitOfWork);
22204
22205 var next = void 0;
22206 if (enableProfilerTimer && (unitOfWork.mode & ProfileMode) !== NoMode) {
22207 startProfilerTimer(unitOfWork);
22208 next = beginWork$$1(current$$1, unitOfWork, renderExpirationTime);
22209 stopProfilerTimerIfRunningAndRecordDelta(unitOfWork, true);
22210 } else {
22211 next = beginWork$$1(current$$1, unitOfWork, renderExpirationTime);
22212 }
22213
22214 resetCurrentFiber();
22215 unitOfWork.memoizedProps = unitOfWork.pendingProps;
22216 if (next === null) {
22217 // If this doesn't spawn new work, complete the current work.
22218 next = completeUnitOfWork(unitOfWork);
22219 }
22220
22221 ReactCurrentOwner$2.current = null;
22222 return next;
22223}
22224
22225function completeUnitOfWork(unitOfWork) {
22226 // Attempt to complete the current unit of work, then move to the next
22227 // sibling. If there are no more siblings, return to the parent fiber.
22228 workInProgress = unitOfWork;
22229 do {
22230 // The current, flushed, state of this fiber is the alternate. Ideally
22231 // nothing should rely on this, but relying on it here means that we don't
22232 // need an additional field on the work in progress.
22233 var current$$1 = workInProgress.alternate;
22234 var returnFiber = workInProgress.return;
22235
22236 // Check if the work completed or if something threw.
22237 if ((workInProgress.effectTag & Incomplete) === NoEffect) {
22238 setCurrentFiber(workInProgress);
22239 var next = void 0;
22240 if (!enableProfilerTimer || (workInProgress.mode & ProfileMode) === NoMode) {
22241 next = completeWork(current$$1, workInProgress, renderExpirationTime);
22242 } else {
22243 startProfilerTimer(workInProgress);
22244 next = completeWork(current$$1, workInProgress, renderExpirationTime);
22245 // Update render duration assuming we didn't error.
22246 stopProfilerTimerIfRunningAndRecordDelta(workInProgress, false);
22247 }
22248 stopWorkTimer(workInProgress);
22249 resetCurrentFiber();
22250 resetChildExpirationTime(workInProgress);
22251
22252 if (next !== null) {
22253 // Completing this fiber spawned new work. Work on that next.
22254 return next;
22255 }
22256
22257 if (returnFiber !== null &&
22258 // Do not append effects to parents if a sibling failed to complete
22259 (returnFiber.effectTag & Incomplete) === NoEffect) {
22260 // Append all the effects of the subtree and this fiber onto the effect
22261 // list of the parent. The completion order of the children affects the
22262 // side-effect order.
22263 if (returnFiber.firstEffect === null) {
22264 returnFiber.firstEffect = workInProgress.firstEffect;
22265 }
22266 if (workInProgress.lastEffect !== null) {
22267 if (returnFiber.lastEffect !== null) {
22268 returnFiber.lastEffect.nextEffect = workInProgress.firstEffect;
22269 }
22270 returnFiber.lastEffect = workInProgress.lastEffect;
22271 }
22272
22273 // If this fiber had side-effects, we append it AFTER the children's
22274 // side-effects. We can perform certain side-effects earlier if needed,
22275 // by doing multiple passes over the effect list. We don't want to
22276 // schedule our own side-effect on our own list because if end up
22277 // reusing children we'll schedule this effect onto itself since we're
22278 // at the end.
22279 var effectTag = workInProgress.effectTag;
22280
22281 // Skip both NoWork and PerformedWork tags when creating the effect
22282 // list. PerformedWork effect is read by React DevTools but shouldn't be
22283 // committed.
22284 if (effectTag > PerformedWork) {
22285 if (returnFiber.lastEffect !== null) {
22286 returnFiber.lastEffect.nextEffect = workInProgress;
22287 } else {
22288 returnFiber.firstEffect = workInProgress;
22289 }
22290 returnFiber.lastEffect = workInProgress;
22291 }
22292 }
22293 } else {
22294 // This fiber did not complete because something threw. Pop values off
22295 // the stack without entering the complete phase. If this is a boundary,
22296 // capture values if possible.
22297 var _next = unwindWork(workInProgress, renderExpirationTime);
22298
22299 // Because this fiber did not complete, don't reset its expiration time.
22300
22301 if (enableProfilerTimer && (workInProgress.mode & ProfileMode) !== NoMode) {
22302 // Record the render duration for the fiber that errored.
22303 stopProfilerTimerIfRunningAndRecordDelta(workInProgress, false);
22304
22305 // Include the time spent working on failed children before continuing.
22306 var actualDuration = workInProgress.actualDuration;
22307 var child = workInProgress.child;
22308 while (child !== null) {
22309 actualDuration += child.actualDuration;
22310 child = child.sibling;
22311 }
22312 workInProgress.actualDuration = actualDuration;
22313 }
22314
22315 if (_next !== null) {
22316 // If completing this work spawned new work, do that next. We'll come
22317 // back here again.
22318 // Since we're restarting, remove anything that is not a host effect
22319 // from the effect tag.
22320 // TODO: The name stopFailedWorkTimer is misleading because Suspense
22321 // also captures and restarts.
22322 stopFailedWorkTimer(workInProgress);
22323 _next.effectTag &= HostEffectMask;
22324 return _next;
22325 }
22326 stopWorkTimer(workInProgress);
22327
22328 if (returnFiber !== null) {
22329 // Mark the parent fiber as incomplete and clear its effect list.
22330 returnFiber.firstEffect = returnFiber.lastEffect = null;
22331 returnFiber.effectTag |= Incomplete;
22332 }
22333 }
22334
22335 var siblingFiber = workInProgress.sibling;
22336 if (siblingFiber !== null) {
22337 // If there is more work to do in this returnFiber, do that next.
22338 return siblingFiber;
22339 }
22340 // Otherwise, return to the parent
22341 workInProgress = returnFiber;
22342 } while (workInProgress !== null);
22343
22344 // We've reached the root.
22345 if (workInProgressRootExitStatus === RootIncomplete) {
22346 workInProgressRootExitStatus = RootCompleted;
22347 }
22348 return null;
22349}
22350
22351function resetChildExpirationTime(completedWork) {
22352 if (renderExpirationTime !== Never && completedWork.childExpirationTime === Never) {
22353 // The children of this component are hidden. Don't bubble their
22354 // expiration times.
22355 return;
22356 }
22357
22358 var newChildExpirationTime = NoWork;
22359
22360 // Bubble up the earliest expiration time.
22361 if (enableProfilerTimer && (completedWork.mode & ProfileMode) !== NoMode) {
22362 // In profiling mode, resetChildExpirationTime is also used to reset
22363 // profiler durations.
22364 var actualDuration = completedWork.actualDuration;
22365 var treeBaseDuration = completedWork.selfBaseDuration;
22366
22367 // When a fiber is cloned, its actualDuration is reset to 0. This value will
22368 // only be updated if work is done on the fiber (i.e. it doesn't bailout).
22369 // When work is done, it should bubble to the parent's actualDuration. If
22370 // the fiber has not been cloned though, (meaning no work was done), then
22371 // this value will reflect the amount of time spent working on a previous
22372 // render. In that case it should not bubble. We determine whether it was
22373 // cloned by comparing the child pointer.
22374 var shouldBubbleActualDurations = completedWork.alternate === null || completedWork.child !== completedWork.alternate.child;
22375
22376 var child = completedWork.child;
22377 while (child !== null) {
22378 var childUpdateExpirationTime = child.expirationTime;
22379 var childChildExpirationTime = child.childExpirationTime;
22380 if (childUpdateExpirationTime > newChildExpirationTime) {
22381 newChildExpirationTime = childUpdateExpirationTime;
22382 }
22383 if (childChildExpirationTime > newChildExpirationTime) {
22384 newChildExpirationTime = childChildExpirationTime;
22385 }
22386 if (shouldBubbleActualDurations) {
22387 actualDuration += child.actualDuration;
22388 }
22389 treeBaseDuration += child.treeBaseDuration;
22390 child = child.sibling;
22391 }
22392 completedWork.actualDuration = actualDuration;
22393 completedWork.treeBaseDuration = treeBaseDuration;
22394 } else {
22395 var _child = completedWork.child;
22396 while (_child !== null) {
22397 var _childUpdateExpirationTime = _child.expirationTime;
22398 var _childChildExpirationTime = _child.childExpirationTime;
22399 if (_childUpdateExpirationTime > newChildExpirationTime) {
22400 newChildExpirationTime = _childUpdateExpirationTime;
22401 }
22402 if (_childChildExpirationTime > newChildExpirationTime) {
22403 newChildExpirationTime = _childChildExpirationTime;
22404 }
22405 _child = _child.sibling;
22406 }
22407 }
22408
22409 completedWork.childExpirationTime = newChildExpirationTime;
22410}
22411
22412function commitRoot(root) {
22413 var renderPriorityLevel = getCurrentPriorityLevel();
22414 runWithPriority$2(ImmediatePriority, commitRootImpl.bind(null, root, renderPriorityLevel));
22415 // If there are passive effects, schedule a callback to flush them. This goes
22416 // outside commitRootImpl so that it inherits the priority of the render.
22417 if (rootWithPendingPassiveEffects !== null) {
22418 scheduleCallback(NormalPriority, function () {
22419 flushPassiveEffects();
22420 return null;
22421 });
22422 }
22423 return null;
22424}
22425
22426function commitRootImpl(root, renderPriorityLevel) {
22427 flushPassiveEffects();
22428 flushRenderPhaseStrictModeWarningsInDEV();
22429
22430 (function () {
22431 if (!((executionContext & (RenderContext | CommitContext)) === NoContext)) {
22432 {
22433 throw ReactError(Error('Should not already be working.'));
22434 }
22435 }
22436 })();
22437
22438 var finishedWork = root.finishedWork;
22439 var expirationTime = root.finishedExpirationTime;
22440 if (finishedWork === null) {
22441 return null;
22442 }
22443 root.finishedWork = null;
22444 root.finishedExpirationTime = NoWork;
22445
22446 (function () {
22447 if (!(finishedWork !== root.current)) {
22448 {
22449 throw ReactError(Error('Cannot commit the same tree as before. This error is likely caused by a bug in React. Please file an issue.'));
22450 }
22451 }
22452 })();
22453
22454 // commitRoot never returns a continuation; it always finishes synchronously.
22455 // So we can clear these now to allow a new callback to be scheduled.
22456 root.callbackNode = null;
22457 root.callbackExpirationTime = NoWork;
22458
22459 startCommitTimer();
22460
22461 // Update the first and last pending times on this root. The new first
22462 // pending time is whatever is left on the root fiber.
22463 var updateExpirationTimeBeforeCommit = finishedWork.expirationTime;
22464 var childExpirationTimeBeforeCommit = finishedWork.childExpirationTime;
22465 var firstPendingTimeBeforeCommit = childExpirationTimeBeforeCommit > updateExpirationTimeBeforeCommit ? childExpirationTimeBeforeCommit : updateExpirationTimeBeforeCommit;
22466 root.firstPendingTime = firstPendingTimeBeforeCommit;
22467 if (firstPendingTimeBeforeCommit < root.lastPendingTime) {
22468 // This usually means we've finished all the work, but it can also happen
22469 // when something gets downprioritized during render, like a hidden tree.
22470 root.lastPendingTime = firstPendingTimeBeforeCommit;
22471 }
22472
22473 if (root === workInProgressRoot) {
22474 // We can reset these now that they are finished.
22475 workInProgressRoot = null;
22476 workInProgress = null;
22477 renderExpirationTime = NoWork;
22478 } else {}
22479 // This indicates that the last root we worked on is not the same one that
22480 // we're committing now. This most commonly happens when a suspended root
22481 // times out.
22482
22483
22484 // Get the list of effects.
22485 var firstEffect = void 0;
22486 if (finishedWork.effectTag > PerformedWork) {
22487 // A fiber's effect list consists only of its children, not itself. So if
22488 // the root has an effect, we need to add it to the end of the list. The
22489 // resulting list is the set that would belong to the root's parent, if it
22490 // had one; that is, all the effects in the tree including the root.
22491 if (finishedWork.lastEffect !== null) {
22492 finishedWork.lastEffect.nextEffect = finishedWork;
22493 firstEffect = finishedWork.firstEffect;
22494 } else {
22495 firstEffect = finishedWork;
22496 }
22497 } else {
22498 // There is no effect on the root.
22499 firstEffect = finishedWork.firstEffect;
22500 }
22501
22502 if (firstEffect !== null) {
22503 var prevExecutionContext = executionContext;
22504 executionContext |= CommitContext;
22505 var prevInteractions = null;
22506 if (enableSchedulerTracing) {
22507 prevInteractions = tracing.__interactionsRef.current;
22508 tracing.__interactionsRef.current = root.memoizedInteractions;
22509 }
22510
22511 // Reset this to null before calling lifecycles
22512 ReactCurrentOwner$2.current = null;
22513
22514 // The commit phase is broken into several sub-phases. We do a separate pass
22515 // of the effect list for each phase: all mutation effects come before all
22516 // layout effects, and so on.
22517
22518 // The first phase a "before mutation" phase. We use this phase to read the
22519 // state of the host tree right before we mutate it. This is where
22520 // getSnapshotBeforeUpdate is called.
22521 startCommitSnapshotEffectsTimer();
22522 prepareForCommit(root.containerInfo);
22523 nextEffect = firstEffect;
22524 do {
22525 {
22526 invokeGuardedCallback(null, commitBeforeMutationEffects, null);
22527 if (hasCaughtError()) {
22528 (function () {
22529 if (!(nextEffect !== null)) {
22530 {
22531 throw ReactError(Error('Should be working on an effect.'));
22532 }
22533 }
22534 })();
22535 var error = clearCaughtError();
22536 captureCommitPhaseError(nextEffect, error);
22537 nextEffect = nextEffect.nextEffect;
22538 }
22539 }
22540 } while (nextEffect !== null);
22541 stopCommitSnapshotEffectsTimer();
22542
22543 if (enableProfilerTimer) {
22544 // Mark the current commit time to be shared by all Profilers in this
22545 // batch. This enables them to be grouped later.
22546 recordCommitTime();
22547 }
22548
22549 // The next phase is the mutation phase, where we mutate the host tree.
22550 startCommitHostEffectsTimer();
22551 nextEffect = firstEffect;
22552 do {
22553 {
22554 invokeGuardedCallback(null, commitMutationEffects, null, renderPriorityLevel);
22555 if (hasCaughtError()) {
22556 (function () {
22557 if (!(nextEffect !== null)) {
22558 {
22559 throw ReactError(Error('Should be working on an effect.'));
22560 }
22561 }
22562 })();
22563 var _error = clearCaughtError();
22564 captureCommitPhaseError(nextEffect, _error);
22565 nextEffect = nextEffect.nextEffect;
22566 }
22567 }
22568 } while (nextEffect !== null);
22569 stopCommitHostEffectsTimer();
22570 resetAfterCommit(root.containerInfo);
22571
22572 // The work-in-progress tree is now the current tree. This must come after
22573 // the mutation phase, so that the previous tree is still current during
22574 // componentWillUnmount, but before the layout phase, so that the finished
22575 // work is current during componentDidMount/Update.
22576 root.current = finishedWork;
22577
22578 // The next phase is the layout phase, where we call effects that read
22579 // the host tree after it's been mutated. The idiomatic use case for this is
22580 // layout, but class component lifecycles also fire here for legacy reasons.
22581 startCommitLifeCyclesTimer();
22582 nextEffect = firstEffect;
22583 do {
22584 {
22585 invokeGuardedCallback(null, commitLayoutEffects, null, root, expirationTime);
22586 if (hasCaughtError()) {
22587 (function () {
22588 if (!(nextEffect !== null)) {
22589 {
22590 throw ReactError(Error('Should be working on an effect.'));
22591 }
22592 }
22593 })();
22594 var _error2 = clearCaughtError();
22595 captureCommitPhaseError(nextEffect, _error2);
22596 nextEffect = nextEffect.nextEffect;
22597 }
22598 }
22599 } while (nextEffect !== null);
22600 stopCommitLifeCyclesTimer();
22601
22602 nextEffect = null;
22603
22604 // Tell Scheduler to yield at the end of the frame, so the browser has an
22605 // opportunity to paint.
22606 requestPaint();
22607
22608 if (enableSchedulerTracing) {
22609 tracing.__interactionsRef.current = prevInteractions;
22610 }
22611 executionContext = prevExecutionContext;
22612 } else {
22613 // No effects.
22614 root.current = finishedWork;
22615 // Measure these anyway so the flamegraph explicitly shows that there were
22616 // no effects.
22617 // TODO: Maybe there's a better way to report this.
22618 startCommitSnapshotEffectsTimer();
22619 stopCommitSnapshotEffectsTimer();
22620 if (enableProfilerTimer) {
22621 recordCommitTime();
22622 }
22623 startCommitHostEffectsTimer();
22624 stopCommitHostEffectsTimer();
22625 startCommitLifeCyclesTimer();
22626 stopCommitLifeCyclesTimer();
22627 }
22628
22629 stopCommitTimer();
22630
22631 var rootDidHavePassiveEffects = rootDoesHavePassiveEffects;
22632
22633 if (rootDoesHavePassiveEffects) {
22634 // This commit has passive effects. Stash a reference to them. But don't
22635 // schedule a callback until after flushing layout work.
22636 rootDoesHavePassiveEffects = false;
22637 rootWithPendingPassiveEffects = root;
22638 pendingPassiveEffectsExpirationTime = expirationTime;
22639 pendingPassiveEffectsRenderPriority = renderPriorityLevel;
22640 } else {
22641 // We are done with the effect chain at this point so let's clear the
22642 // nextEffect pointers to assist with GC. If we have passive effects, we'll
22643 // clear this in flushPassiveEffects.
22644 nextEffect = firstEffect;
22645 while (nextEffect !== null) {
22646 var nextNextEffect = nextEffect.nextEffect;
22647 nextEffect.nextEffect = null;
22648 nextEffect = nextNextEffect;
22649 }
22650 }
22651
22652 // Check if there's remaining work on this root
22653 var remainingExpirationTime = root.firstPendingTime;
22654 if (remainingExpirationTime !== NoWork) {
22655 var currentTime = requestCurrentTime();
22656 var priorityLevel = inferPriorityFromExpirationTime(currentTime, remainingExpirationTime);
22657
22658 if (enableSchedulerTracing) {
22659 if (spawnedWorkDuringRender !== null) {
22660 var expirationTimes = spawnedWorkDuringRender;
22661 spawnedWorkDuringRender = null;
22662 for (var i = 0; i < expirationTimes.length; i++) {
22663 scheduleInteractions(root, expirationTimes[i], root.memoizedInteractions);
22664 }
22665 }
22666 }
22667
22668 scheduleCallbackForRoot(root, priorityLevel, remainingExpirationTime);
22669 } else {
22670 // If there's no remaining work, we can clear the set of already failed
22671 // error boundaries.
22672 legacyErrorBoundariesThatAlreadyFailed = null;
22673 }
22674
22675 if (enableSchedulerTracing) {
22676 if (!rootDidHavePassiveEffects) {
22677 // If there are no passive effects, then we can complete the pending interactions.
22678 // Otherwise, we'll wait until after the passive effects are flushed.
22679 // Wait to do this until after remaining work has been scheduled,
22680 // so that we don't prematurely signal complete for interactions when there's e.g. hidden work.
22681 finishPendingInteractions(root, expirationTime);
22682 }
22683 }
22684
22685 onCommitRoot(finishedWork.stateNode, expirationTime);
22686
22687 if (remainingExpirationTime === Sync) {
22688 // Count the number of times the root synchronously re-renders without
22689 // finishing. If there are too many, it indicates an infinite update loop.
22690 if (root === rootWithNestedUpdates) {
22691 nestedUpdateCount++;
22692 } else {
22693 nestedUpdateCount = 0;
22694 rootWithNestedUpdates = root;
22695 }
22696 } else {
22697 nestedUpdateCount = 0;
22698 }
22699
22700 if (hasUncaughtError) {
22701 hasUncaughtError = false;
22702 var _error3 = firstUncaughtError;
22703 firstUncaughtError = null;
22704 throw _error3;
22705 }
22706
22707 if ((executionContext & LegacyUnbatchedContext) !== NoContext) {
22708 // This is a legacy edge case. We just committed the initial mount of
22709 // a ReactDOM.render-ed root inside of batchedUpdates. The commit fired
22710 // synchronously, but layout updates should be deferred until the end
22711 // of the batch.
22712 return null;
22713 }
22714
22715 // If layout work was scheduled, flush it now.
22716 flushSyncCallbackQueue();
22717 return null;
22718}
22719
22720function commitBeforeMutationEffects() {
22721 while (nextEffect !== null) {
22722 if ((nextEffect.effectTag & Snapshot) !== NoEffect) {
22723 setCurrentFiber(nextEffect);
22724 recordEffect();
22725
22726 var current$$1 = nextEffect.alternate;
22727 commitBeforeMutationLifeCycles(current$$1, nextEffect);
22728
22729 resetCurrentFiber();
22730 }
22731 nextEffect = nextEffect.nextEffect;
22732 }
22733}
22734
22735function commitMutationEffects(renderPriorityLevel) {
22736 // TODO: Should probably move the bulk of this function to commitWork.
22737 while (nextEffect !== null) {
22738 setCurrentFiber(nextEffect);
22739
22740 var effectTag = nextEffect.effectTag;
22741
22742 if (effectTag & ContentReset) {
22743 commitResetTextContent(nextEffect);
22744 }
22745
22746 if (effectTag & Ref) {
22747 var current$$1 = nextEffect.alternate;
22748 if (current$$1 !== null) {
22749 commitDetachRef(current$$1);
22750 }
22751 }
22752
22753 // The following switch statement is only concerned about placement,
22754 // updates, and deletions. To avoid needing to add a case for every possible
22755 // bitmap value, we remove the secondary effects from the effect tag and
22756 // switch on that value.
22757 var primaryEffectTag = effectTag & (Placement | Update | Deletion);
22758 switch (primaryEffectTag) {
22759 case Placement:
22760 {
22761 commitPlacement(nextEffect);
22762 // Clear the "placement" from effect tag so that we know that this is
22763 // inserted, before any life-cycles like componentDidMount gets called.
22764 // TODO: findDOMNode doesn't rely on this any more but isMounted does
22765 // and isMounted is deprecated anyway so we should be able to kill this.
22766 nextEffect.effectTag &= ~Placement;
22767 break;
22768 }
22769 case PlacementAndUpdate:
22770 {
22771 // Placement
22772 commitPlacement(nextEffect);
22773 // Clear the "placement" from effect tag so that we know that this is
22774 // inserted, before any life-cycles like componentDidMount gets called.
22775 nextEffect.effectTag &= ~Placement;
22776
22777 // Update
22778 var _current = nextEffect.alternate;
22779 commitWork(_current, nextEffect);
22780 break;
22781 }
22782 case Update:
22783 {
22784 var _current2 = nextEffect.alternate;
22785 commitWork(_current2, nextEffect);
22786 break;
22787 }
22788 case Deletion:
22789 {
22790 commitDeletion(nextEffect, renderPriorityLevel);
22791 break;
22792 }
22793 }
22794
22795 // TODO: Only record a mutation effect if primaryEffectTag is non-zero.
22796 recordEffect();
22797
22798 resetCurrentFiber();
22799 nextEffect = nextEffect.nextEffect;
22800 }
22801}
22802
22803function commitLayoutEffects(root, committedExpirationTime) {
22804 // TODO: Should probably move the bulk of this function to commitWork.
22805 while (nextEffect !== null) {
22806 setCurrentFiber(nextEffect);
22807
22808 var effectTag = nextEffect.effectTag;
22809
22810 if (effectTag & (Update | Callback)) {
22811 recordEffect();
22812 var current$$1 = nextEffect.alternate;
22813 commitLifeCycles(root, current$$1, nextEffect, committedExpirationTime);
22814 }
22815
22816 if (effectTag & Ref) {
22817 recordEffect();
22818 commitAttachRef(nextEffect);
22819 }
22820
22821 if (effectTag & Passive) {
22822 rootDoesHavePassiveEffects = true;
22823 }
22824
22825 resetCurrentFiber();
22826 nextEffect = nextEffect.nextEffect;
22827 }
22828}
22829
22830function flushPassiveEffects() {
22831 if (rootWithPendingPassiveEffects === null) {
22832 return false;
22833 }
22834 var root = rootWithPendingPassiveEffects;
22835 var expirationTime = pendingPassiveEffectsExpirationTime;
22836 var renderPriorityLevel = pendingPassiveEffectsRenderPriority;
22837 rootWithPendingPassiveEffects = null;
22838 pendingPassiveEffectsExpirationTime = NoWork;
22839 pendingPassiveEffectsRenderPriority = NoPriority;
22840 var priorityLevel = renderPriorityLevel > NormalPriority ? NormalPriority : renderPriorityLevel;
22841 return runWithPriority$2(priorityLevel, flushPassiveEffectsImpl.bind(null, root, expirationTime));
22842}
22843
22844function flushPassiveEffectsImpl(root, expirationTime) {
22845 var prevInteractions = null;
22846 if (enableSchedulerTracing) {
22847 prevInteractions = tracing.__interactionsRef.current;
22848 tracing.__interactionsRef.current = root.memoizedInteractions;
22849 }
22850
22851 (function () {
22852 if (!((executionContext & (RenderContext | CommitContext)) === NoContext)) {
22853 {
22854 throw ReactError(Error('Cannot flush passive effects while already rendering.'));
22855 }
22856 }
22857 })();
22858 var prevExecutionContext = executionContext;
22859 executionContext |= CommitContext;
22860
22861 // Note: This currently assumes there are no passive effects on the root
22862 // fiber, because the root is not part of its own effect list. This could
22863 // change in the future.
22864 var effect = root.current.firstEffect;
22865 while (effect !== null) {
22866 {
22867 setCurrentFiber(effect);
22868 invokeGuardedCallback(null, commitPassiveHookEffects, null, effect);
22869 if (hasCaughtError()) {
22870 (function () {
22871 if (!(effect !== null)) {
22872 {
22873 throw ReactError(Error('Should be working on an effect.'));
22874 }
22875 }
22876 })();
22877 var error = clearCaughtError();
22878 captureCommitPhaseError(effect, error);
22879 }
22880 resetCurrentFiber();
22881 }
22882 var nextNextEffect = effect.nextEffect;
22883 // Remove nextEffect pointer to assist GC
22884 effect.nextEffect = null;
22885 effect = nextNextEffect;
22886 }
22887
22888 if (enableSchedulerTracing) {
22889 tracing.__interactionsRef.current = prevInteractions;
22890 finishPendingInteractions(root, expirationTime);
22891 }
22892
22893 executionContext = prevExecutionContext;
22894 flushSyncCallbackQueue();
22895
22896 // If additional passive effects were scheduled, increment a counter. If this
22897 // exceeds the limit, we'll fire a warning.
22898 nestedPassiveUpdateCount = rootWithPendingPassiveEffects === null ? 0 : nestedPassiveUpdateCount + 1;
22899
22900 return true;
22901}
22902
22903function isAlreadyFailedLegacyErrorBoundary(instance) {
22904 return legacyErrorBoundariesThatAlreadyFailed !== null && legacyErrorBoundariesThatAlreadyFailed.has(instance);
22905}
22906
22907function markLegacyErrorBoundaryAsFailed(instance) {
22908 if (legacyErrorBoundariesThatAlreadyFailed === null) {
22909 legacyErrorBoundariesThatAlreadyFailed = new Set([instance]);
22910 } else {
22911 legacyErrorBoundariesThatAlreadyFailed.add(instance);
22912 }
22913}
22914
22915function prepareToThrowUncaughtError(error) {
22916 if (!hasUncaughtError) {
22917 hasUncaughtError = true;
22918 firstUncaughtError = error;
22919 }
22920}
22921var onUncaughtError = prepareToThrowUncaughtError;
22922
22923function captureCommitPhaseErrorOnRoot(rootFiber, sourceFiber, error) {
22924 var errorInfo = createCapturedValue(error, sourceFiber);
22925 var update = createRootErrorUpdate(rootFiber, errorInfo, Sync);
22926 enqueueUpdate(rootFiber, update);
22927 var root = markUpdateTimeFromFiberToRoot(rootFiber, Sync);
22928 if (root !== null) {
22929 scheduleCallbackForRoot(root, ImmediatePriority, Sync);
22930 }
22931}
22932
22933function captureCommitPhaseError(sourceFiber, error) {
22934 if (sourceFiber.tag === HostRoot) {
22935 // Error was thrown at the root. There is no parent, so the root
22936 // itself should capture it.
22937 captureCommitPhaseErrorOnRoot(sourceFiber, sourceFiber, error);
22938 return;
22939 }
22940
22941 var fiber = sourceFiber.return;
22942 while (fiber !== null) {
22943 if (fiber.tag === HostRoot) {
22944 captureCommitPhaseErrorOnRoot(fiber, sourceFiber, error);
22945 return;
22946 } else if (fiber.tag === ClassComponent) {
22947 var ctor = fiber.type;
22948 var instance = fiber.stateNode;
22949 if (typeof ctor.getDerivedStateFromError === 'function' || typeof instance.componentDidCatch === 'function' && !isAlreadyFailedLegacyErrorBoundary(instance)) {
22950 var errorInfo = createCapturedValue(error, sourceFiber);
22951 var update = createClassErrorUpdate(fiber, errorInfo,
22952 // TODO: This is always sync
22953 Sync);
22954 enqueueUpdate(fiber, update);
22955 var root = markUpdateTimeFromFiberToRoot(fiber, Sync);
22956 if (root !== null) {
22957 scheduleCallbackForRoot(root, ImmediatePriority, Sync);
22958 }
22959 return;
22960 }
22961 }
22962 fiber = fiber.return;
22963 }
22964}
22965
22966function pingSuspendedRoot(root, thenable, suspendedTime) {
22967 var pingCache = root.pingCache;
22968 if (pingCache !== null) {
22969 // The thenable resolved, so we no longer need to memoize, because it will
22970 // never be thrown again.
22971 pingCache.delete(thenable);
22972 }
22973
22974 if (workInProgressRoot === root && renderExpirationTime === suspendedTime) {
22975 // Received a ping at the same priority level at which we're currently
22976 // rendering. We might want to restart this render. This should mirror
22977 // the logic of whether or not a root suspends once it completes.
22978
22979 // TODO: If we're rendering sync either due to Sync, Batched or expired,
22980 // we should probably never restart.
22981
22982 // If we're suspended with delay, we'll always suspend so we can always
22983 // restart. If we're suspended without any updates, it might be a retry.
22984 // If it's early in the retry we can restart. We can't know for sure
22985 // whether we'll eventually process an update during this render pass,
22986 // but it's somewhat unlikely that we get to a ping before that, since
22987 // getting to the root most update is usually very fast.
22988 if (workInProgressRootExitStatus === RootSuspendedWithDelay || workInProgressRootExitStatus === RootSuspended && workInProgressRootLatestProcessedExpirationTime === Sync && now() - globalMostRecentFallbackTime < FALLBACK_THROTTLE_MS) {
22989 // Restart from the root. Don't need to schedule a ping because
22990 // we're already working on this tree.
22991 prepareFreshStack(root, renderExpirationTime);
22992 } else {
22993 // Even though we can't restart right now, we might get an
22994 // opportunity later. So we mark this render as having a ping.
22995 workInProgressRootHasPendingPing = true;
22996 }
22997 return;
22998 }
22999
23000 var lastPendingTime = root.lastPendingTime;
23001 if (lastPendingTime < suspendedTime) {
23002 // The root is no longer suspended at this time.
23003 return;
23004 }
23005
23006 var pingTime = root.pingTime;
23007 if (pingTime !== NoWork && pingTime < suspendedTime) {
23008 // There's already a lower priority ping scheduled.
23009 return;
23010 }
23011
23012 // Mark the time at which this ping was scheduled.
23013 root.pingTime = suspendedTime;
23014
23015 if (root.finishedExpirationTime === suspendedTime) {
23016 // If there's a pending fallback waiting to commit, throw it away.
23017 root.finishedExpirationTime = NoWork;
23018 root.finishedWork = null;
23019 }
23020
23021 var currentTime = requestCurrentTime();
23022 var priorityLevel = inferPriorityFromExpirationTime(currentTime, suspendedTime);
23023 scheduleCallbackForRoot(root, priorityLevel, suspendedTime);
23024}
23025
23026function retryTimedOutBoundary(boundaryFiber) {
23027 // The boundary fiber (a Suspense component or SuspenseList component)
23028 // previously was rendered in its fallback state. One of the promises that
23029 // suspended it has resolved, which means at least part of the tree was
23030 // likely unblocked. Try rendering again, at a new expiration time.
23031 var currentTime = requestCurrentTime();
23032 var suspenseConfig = null; // Retries don't carry over the already committed update.
23033 var retryTime = computeExpirationForFiber(currentTime, boundaryFiber, suspenseConfig);
23034 // TODO: Special case idle priority?
23035 var priorityLevel = inferPriorityFromExpirationTime(currentTime, retryTime);
23036 var root = markUpdateTimeFromFiberToRoot(boundaryFiber, retryTime);
23037 if (root !== null) {
23038 scheduleCallbackForRoot(root, priorityLevel, retryTime);
23039 }
23040}
23041
23042function resolveRetryThenable(boundaryFiber, thenable) {
23043 var retryCache = void 0;
23044 if (enableSuspenseServerRenderer) {
23045 switch (boundaryFiber.tag) {
23046 case SuspenseComponent:
23047 retryCache = boundaryFiber.stateNode;
23048 break;
23049 case DehydratedSuspenseComponent:
23050 retryCache = boundaryFiber.memoizedState;
23051 break;
23052 default:
23053 (function () {
23054 {
23055 {
23056 throw ReactError(Error('Pinged unknown suspense boundary type. This is probably a bug in React.'));
23057 }
23058 }
23059 })();
23060 }
23061 } else {
23062 retryCache = boundaryFiber.stateNode;
23063 }
23064
23065 if (retryCache !== null) {
23066 // The thenable resolved, so we no longer need to memoize, because it will
23067 // never be thrown again.
23068 retryCache.delete(thenable);
23069 }
23070
23071 retryTimedOutBoundary(boundaryFiber);
23072}
23073
23074// Computes the next Just Noticeable Difference (JND) boundary.
23075// The theory is that a person can't tell the difference between small differences in time.
23076// Therefore, if we wait a bit longer than necessary that won't translate to a noticeable
23077// difference in the experience. However, waiting for longer might mean that we can avoid
23078// showing an intermediate loading state. The longer we have already waited, the harder it
23079// is to tell small differences in time. Therefore, the longer we've already waited,
23080// the longer we can wait additionally. At some point we have to give up though.
23081// We pick a train model where the next boundary commits at a consistent schedule.
23082// These particular numbers are vague estimates. We expect to adjust them based on research.
23083function jnd(timeElapsed) {
23084 return timeElapsed < 120 ? 120 : timeElapsed < 480 ? 480 : timeElapsed < 1080 ? 1080 : timeElapsed < 1920 ? 1920 : timeElapsed < 3000 ? 3000 : timeElapsed < 4320 ? 4320 : ceil(timeElapsed / 1960) * 1960;
23085}
23086
23087function computeMsUntilSuspenseLoadingDelay(mostRecentEventTime, committedExpirationTime, suspenseConfig) {
23088 var busyMinDurationMs = suspenseConfig.busyMinDurationMs | 0;
23089 if (busyMinDurationMs <= 0) {
23090 return 0;
23091 }
23092 var busyDelayMs = suspenseConfig.busyDelayMs | 0;
23093
23094 // Compute the time until this render pass would expire.
23095 var currentTimeMs = now();
23096 var eventTimeMs = inferTimeFromExpirationTimeWithSuspenseConfig(mostRecentEventTime, suspenseConfig);
23097 var timeElapsed = currentTimeMs - eventTimeMs;
23098 if (timeElapsed <= busyDelayMs) {
23099 // If we haven't yet waited longer than the initial delay, we don't
23100 // have to wait any additional time.
23101 return 0;
23102 }
23103 var msUntilTimeout = busyDelayMs + busyMinDurationMs - timeElapsed;
23104 // This is the value that is passed to `setTimeout`.
23105 return msUntilTimeout;
23106}
23107
23108function checkForNestedUpdates() {
23109 if (nestedUpdateCount > NESTED_UPDATE_LIMIT) {
23110 nestedUpdateCount = 0;
23111 rootWithNestedUpdates = null;
23112 (function () {
23113 {
23114 {
23115 throw ReactError(Error('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.'));
23116 }
23117 }
23118 })();
23119 }
23120
23121 {
23122 if (nestedPassiveUpdateCount > NESTED_PASSIVE_UPDATE_LIMIT) {
23123 nestedPassiveUpdateCount = 0;
23124 warning$1(false, 'Maximum update depth exceeded. This can happen when a component ' + "calls setState inside useEffect, but useEffect either doesn't " + 'have a dependency array, or one of the dependencies changes on ' + 'every render.');
23125 }
23126 }
23127}
23128
23129function flushRenderPhaseStrictModeWarningsInDEV() {
23130 {
23131 ReactStrictModeWarnings.flushLegacyContextWarning();
23132
23133 if (warnAboutDeprecatedLifecycles) {
23134 ReactStrictModeWarnings.flushPendingUnsafeLifecycleWarnings();
23135 }
23136 }
23137}
23138
23139function stopFinishedWorkLoopTimer() {
23140 var didCompleteRoot = true;
23141 stopWorkLoopTimer(interruptedBy, didCompleteRoot);
23142 interruptedBy = null;
23143}
23144
23145function stopInterruptedWorkLoopTimer() {
23146 // TODO: Track which fiber caused the interruption.
23147 var didCompleteRoot = false;
23148 stopWorkLoopTimer(interruptedBy, didCompleteRoot);
23149 interruptedBy = null;
23150}
23151
23152function checkForInterruption(fiberThatReceivedUpdate, updateExpirationTime) {
23153 if (enableUserTimingAPI && workInProgressRoot !== null && updateExpirationTime > renderExpirationTime) {
23154 interruptedBy = fiberThatReceivedUpdate;
23155 }
23156}
23157
23158var didWarnStateUpdateForUnmountedComponent = null;
23159function warnAboutUpdateOnUnmountedFiberInDEV(fiber) {
23160 {
23161 var tag = fiber.tag;
23162 if (tag !== HostRoot && tag !== ClassComponent && tag !== FunctionComponent && tag !== ForwardRef && tag !== MemoComponent && tag !== SimpleMemoComponent) {
23163 // Only warn for user-defined components, not internal ones like Suspense.
23164 return;
23165 }
23166 // We show the whole stack but dedupe on the top component's name because
23167 // the problematic code almost always lies inside that component.
23168 var componentName = getComponentName(fiber.type) || 'ReactComponent';
23169 if (didWarnStateUpdateForUnmountedComponent !== null) {
23170 if (didWarnStateUpdateForUnmountedComponent.has(componentName)) {
23171 return;
23172 }
23173 didWarnStateUpdateForUnmountedComponent.add(componentName);
23174 } else {
23175 didWarnStateUpdateForUnmountedComponent = new Set([componentName]);
23176 }
23177 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', tag === ClassComponent ? 'the componentWillUnmount method' : 'a useEffect cleanup function', getStackByFiberInDevAndProd(fiber));
23178 }
23179}
23180
23181var beginWork$$1 = void 0;
23182if (true && replayFailedUnitOfWorkWithInvokeGuardedCallback) {
23183 var dummyFiber = null;
23184 beginWork$$1 = function (current$$1, unitOfWork, expirationTime) {
23185 // If a component throws an error, we replay it again in a synchronously
23186 // dispatched event, so that the debugger will treat it as an uncaught
23187 // error See ReactErrorUtils for more information.
23188
23189 // Before entering the begin phase, copy the work-in-progress onto a dummy
23190 // fiber. If beginWork throws, we'll use this to reset the state.
23191 var originalWorkInProgressCopy = assignFiberPropertiesInDEV(dummyFiber, unitOfWork);
23192 try {
23193 return beginWork$1(current$$1, unitOfWork, expirationTime);
23194 } catch (originalError) {
23195 if (originalError !== null && typeof originalError === 'object' && typeof originalError.then === 'function') {
23196 // Don't replay promises. Treat everything else like an error.
23197 throw originalError;
23198 }
23199
23200 // Keep this code in sync with renderRoot; any changes here must have
23201 // corresponding changes there.
23202 resetContextDependencies();
23203 resetHooks();
23204
23205 // Unwind the failed stack frame
23206 unwindInterruptedWork(unitOfWork);
23207
23208 // Restore the original properties of the fiber.
23209 assignFiberPropertiesInDEV(unitOfWork, originalWorkInProgressCopy);
23210
23211 if (enableProfilerTimer && unitOfWork.mode & ProfileMode) {
23212 // Reset the profiler timer.
23213 startProfilerTimer(unitOfWork);
23214 }
23215
23216 // Run beginWork again.
23217 invokeGuardedCallback(null, beginWork$1, null, current$$1, unitOfWork, expirationTime);
23218
23219 if (hasCaughtError()) {
23220 var replayError = clearCaughtError();
23221 // `invokeGuardedCallback` sometimes sets an expando `_suppressLogging`.
23222 // Rethrow this error instead of the original one.
23223 throw replayError;
23224 } else {
23225 // This branch is reachable if the render phase is impure.
23226 throw originalError;
23227 }
23228 }
23229 };
23230} else {
23231 beginWork$$1 = beginWork$1;
23232}
23233
23234var didWarnAboutUpdateInRender = false;
23235var didWarnAboutUpdateInGetChildContext = false;
23236function warnAboutInvalidUpdatesOnClassComponentsInDEV(fiber) {
23237 {
23238 if (fiber.tag === ClassComponent) {
23239 switch (phase) {
23240 case 'getChildContext':
23241 if (didWarnAboutUpdateInGetChildContext) {
23242 return;
23243 }
23244 warningWithoutStack$1(false, 'setState(...): Cannot call setState() inside getChildContext()');
23245 didWarnAboutUpdateInGetChildContext = true;
23246 break;
23247 case 'render':
23248 if (didWarnAboutUpdateInRender) {
23249 return;
23250 }
23251 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.');
23252 didWarnAboutUpdateInRender = true;
23253 break;
23254 }
23255 }
23256 }
23257}
23258
23259// a 'shared' variable that changes when act() opens/closes in tests.
23260var IsThisRendererActing = { current: false };
23261
23262function warnIfNotScopedWithMatchingAct(fiber) {
23263 {
23264 if (warnsIfNotActing === true && IsSomeRendererActing.current === true && IsThisRendererActing.current !== true) {
23265 warningWithoutStack$1(false, "It looks like you're using the wrong act() around your test interactions.\n" + 'Be sure to use the matching version of act() corresponding to your renderer:\n\n' + '// for react-dom:\n' + "import {act} from 'react-dom/test-utils';\n" + '//...\n' + 'act(() => ...);\n\n' + '// for react-test-renderer:\n' + "import TestRenderer from 'react-test-renderer';\n" + 'const {act} = TestRenderer;\n' + '//...\n' + 'act(() => ...);' + '%s', getStackByFiberInDevAndProd(fiber));
23266 }
23267 }
23268}
23269
23270function warnIfNotCurrentlyActingEffectsInDEV(fiber) {
23271 {
23272 if (warnsIfNotActing === true && (fiber.mode & StrictMode) !== NoMode && IsSomeRendererActing.current === false && IsThisRendererActing.current === false) {
23273 warningWithoutStack$1(false, 'An update to %s ran an effect, but was not wrapped in act(...).\n\n' + 'When testing, code that causes React state updates should be ' + 'wrapped into act(...):\n\n' + 'act(() => {\n' + ' /* fire events that update state */\n' + '});\n' + '/* assert on the output */\n\n' + "This ensures that you're testing the behavior the user would see " + 'in the browser.' + ' Learn more at https://fb.me/react-wrap-tests-with-act' + '%s', getComponentName(fiber.type), getStackByFiberInDevAndProd(fiber));
23274 }
23275 }
23276}
23277
23278function warnIfNotCurrentlyActingUpdatesInDEV(fiber) {
23279 {
23280 if (warnsIfNotActing === true && executionContext === NoContext && IsSomeRendererActing.current === false && IsThisRendererActing.current === false) {
23281 warningWithoutStack$1(false, 'An update to %s inside a test was not wrapped in act(...).\n\n' + 'When testing, code that causes React state updates should be ' + 'wrapped into act(...):\n\n' + 'act(() => {\n' + ' /* fire events that update state */\n' + '});\n' + '/* assert on the output */\n\n' + "This ensures that you're testing the behavior the user would see " + 'in the browser.' + ' Learn more at https://fb.me/react-wrap-tests-with-act' + '%s', getComponentName(fiber.type), getStackByFiberInDevAndProd(fiber));
23282 }
23283 }
23284}
23285
23286var warnIfNotCurrentlyActingUpdatesInDev = warnIfNotCurrentlyActingUpdatesInDEV;
23287
23288// In tests, we want to enforce a mocked scheduler.
23289var didWarnAboutUnmockedScheduler = false;
23290// TODO Before we release concurrent mode, revisit this and decide whether a mocked
23291// scheduler is the actual recommendation. The alternative could be a testing build,
23292// a new lib, or whatever; we dunno just yet. This message is for early adopters
23293// to get their tests right.
23294
23295function warnIfUnmockedScheduler(fiber) {
23296 {
23297 if (didWarnAboutUnmockedScheduler === false && Scheduler.unstable_flushAllWithoutAsserting === undefined) {
23298 if (fiber.mode & BatchedMode || fiber.mode & ConcurrentMode) {
23299 didWarnAboutUnmockedScheduler = true;
23300 warningWithoutStack$1(false, 'In Concurrent or Sync modes, the "scheduler" module needs to be mocked ' + 'to guarantee consistent behaviour across tests and browsers. ' + 'For example, with jest: \n' + "jest.mock('scheduler', () => require('scheduler/unstable_mock'));\n\n" + 'For more info, visit https://fb.me/react-mock-scheduler');
23301 } else if (warnAboutUnmockedScheduler === true) {
23302 didWarnAboutUnmockedScheduler = true;
23303 warningWithoutStack$1(false, 'Starting from React v17, the "scheduler" module will need to be mocked ' + 'to guarantee consistent behaviour across tests and browsers. ' + 'For example, with jest: \n' + "jest.mock('scheduler', () => require('scheduler/unstable_mock'));\n\n" + 'For more info, visit https://fb.me/react-mock-scheduler');
23304 }
23305 }
23306 }
23307}
23308
23309var componentsThatTriggeredHighPriSuspend = null;
23310function checkForWrongSuspensePriorityInDEV(sourceFiber) {
23311 {
23312 var currentPriorityLevel = getCurrentPriorityLevel();
23313 if ((sourceFiber.mode & ConcurrentMode) !== NoEffect && (currentPriorityLevel === UserBlockingPriority$2 || currentPriorityLevel === ImmediatePriority)) {
23314 var workInProgressNode = sourceFiber;
23315 while (workInProgressNode !== null) {
23316 // Add the component that triggered the suspense
23317 var current$$1 = workInProgressNode.alternate;
23318 if (current$$1 !== null) {
23319 // TODO: warn component that triggers the high priority
23320 // suspend is the HostRoot
23321 switch (workInProgressNode.tag) {
23322 case ClassComponent:
23323 // Loop through the component's update queue and see whether the component
23324 // has triggered any high priority updates
23325 var updateQueue = current$$1.updateQueue;
23326 if (updateQueue !== null) {
23327 var update = updateQueue.firstUpdate;
23328 while (update !== null) {
23329 var priorityLevel = update.priority;
23330 if (priorityLevel === UserBlockingPriority$2 || priorityLevel === ImmediatePriority) {
23331 if (componentsThatTriggeredHighPriSuspend === null) {
23332 componentsThatTriggeredHighPriSuspend = new Set([getComponentName(workInProgressNode.type)]);
23333 } else {
23334 componentsThatTriggeredHighPriSuspend.add(getComponentName(workInProgressNode.type));
23335 }
23336 break;
23337 }
23338 update = update.next;
23339 }
23340 }
23341 break;
23342 case FunctionComponent:
23343 case ForwardRef:
23344 case SimpleMemoComponent:
23345 if (workInProgressNode.memoizedState !== null && workInProgressNode.memoizedState.baseUpdate !== null) {
23346 var _update = workInProgressNode.memoizedState.baseUpdate;
23347 // Loop through the functional component's memoized state to see whether
23348 // the component has triggered any high pri updates
23349 while (_update !== null) {
23350 var priority = _update.priority;
23351 if (priority === UserBlockingPriority$2 || priority === ImmediatePriority) {
23352 if (componentsThatTriggeredHighPriSuspend === null) {
23353 componentsThatTriggeredHighPriSuspend = new Set([getComponentName(workInProgressNode.type)]);
23354 } else {
23355 componentsThatTriggeredHighPriSuspend.add(getComponentName(workInProgressNode.type));
23356 }
23357 break;
23358 }
23359 if (_update.next === workInProgressNode.memoizedState.baseUpdate) {
23360 break;
23361 }
23362 _update = _update.next;
23363 }
23364 }
23365 break;
23366 default:
23367 break;
23368 }
23369 }
23370 workInProgressNode = workInProgressNode.return;
23371 }
23372 }
23373 }
23374}
23375
23376function flushSuspensePriorityWarningInDEV() {
23377 {
23378 if (componentsThatTriggeredHighPriSuspend !== null) {
23379 var componentNames = [];
23380 componentsThatTriggeredHighPriSuspend.forEach(function (name) {
23381 return componentNames.push(name);
23382 });
23383 componentsThatTriggeredHighPriSuspend = null;
23384
23385 if (componentNames.length > 0) {
23386 warningWithoutStack$1(false, '%s triggered a user-blocking update that suspended.' + '\n\n' + 'The fix is to split the update into multiple parts: a user-blocking ' + 'update to provide immediate feedback, and another update that ' + 'triggers the bulk of the changes.' + '\n\n' + 'Refer to the documentation for useSuspenseTransition to learn how ' + 'to implement this pattern.',
23387 // TODO: Add link to React docs with more information, once it exists
23388 componentNames.sort().join(', '));
23389 }
23390 }
23391 }
23392}
23393
23394function computeThreadID(root, expirationTime) {
23395 // Interaction threads are unique per root and expiration time.
23396 return expirationTime * 1000 + root.interactionThreadID;
23397}
23398
23399function markSpawnedWork(expirationTime) {
23400 if (!enableSchedulerTracing) {
23401 return;
23402 }
23403 if (spawnedWorkDuringRender === null) {
23404 spawnedWorkDuringRender = [expirationTime];
23405 } else {
23406 spawnedWorkDuringRender.push(expirationTime);
23407 }
23408}
23409
23410function scheduleInteractions(root, expirationTime, interactions) {
23411 if (!enableSchedulerTracing) {
23412 return;
23413 }
23414
23415 if (interactions.size > 0) {
23416 var pendingInteractionMap = root.pendingInteractionMap;
23417 var pendingInteractions = pendingInteractionMap.get(expirationTime);
23418 if (pendingInteractions != null) {
23419 interactions.forEach(function (interaction) {
23420 if (!pendingInteractions.has(interaction)) {
23421 // Update the pending async work count for previously unscheduled interaction.
23422 interaction.__count++;
23423 }
23424
23425 pendingInteractions.add(interaction);
23426 });
23427 } else {
23428 pendingInteractionMap.set(expirationTime, new Set(interactions));
23429
23430 // Update the pending async work count for the current interactions.
23431 interactions.forEach(function (interaction) {
23432 interaction.__count++;
23433 });
23434 }
23435
23436 var subscriber = tracing.__subscriberRef.current;
23437 if (subscriber !== null) {
23438 var threadID = computeThreadID(root, expirationTime);
23439 subscriber.onWorkScheduled(interactions, threadID);
23440 }
23441 }
23442}
23443
23444function schedulePendingInteractions(root, expirationTime) {
23445 // This is called when work is scheduled on a root.
23446 // It associates the current interactions with the newly-scheduled expiration.
23447 // They will be restored when that expiration is later committed.
23448 if (!enableSchedulerTracing) {
23449 return;
23450 }
23451
23452 scheduleInteractions(root, expirationTime, tracing.__interactionsRef.current);
23453}
23454
23455function startWorkOnPendingInteractions(root, expirationTime) {
23456 // This is called when new work is started on a root.
23457 if (!enableSchedulerTracing) {
23458 return;
23459 }
23460
23461 // Determine which interactions this batch of work currently includes, So that
23462 // we can accurately attribute time spent working on it, And so that cascading
23463 // work triggered during the render phase will be associated with it.
23464 var interactions = new Set();
23465 root.pendingInteractionMap.forEach(function (scheduledInteractions, scheduledExpirationTime) {
23466 if (scheduledExpirationTime >= expirationTime) {
23467 scheduledInteractions.forEach(function (interaction) {
23468 return interactions.add(interaction);
23469 });
23470 }
23471 });
23472
23473 // Store the current set of interactions on the FiberRoot for a few reasons:
23474 // We can re-use it in hot functions like renderRoot() without having to
23475 // recalculate it. We will also use it in commitWork() to pass to any Profiler
23476 // onRender() hooks. This also provides DevTools with a way to access it when
23477 // the onCommitRoot() hook is called.
23478 root.memoizedInteractions = interactions;
23479
23480 if (interactions.size > 0) {
23481 var subscriber = tracing.__subscriberRef.current;
23482 if (subscriber !== null) {
23483 var threadID = computeThreadID(root, expirationTime);
23484 try {
23485 subscriber.onWorkStarted(interactions, threadID);
23486 } catch (error) {
23487 // If the subscriber throws, rethrow it in a separate task
23488 scheduleCallback(ImmediatePriority, function () {
23489 throw error;
23490 });
23491 }
23492 }
23493 }
23494}
23495
23496function finishPendingInteractions(root, committedExpirationTime) {
23497 if (!enableSchedulerTracing) {
23498 return;
23499 }
23500
23501 var earliestRemainingTimeAfterCommit = root.firstPendingTime;
23502
23503 var subscriber = void 0;
23504
23505 try {
23506 subscriber = tracing.__subscriberRef.current;
23507 if (subscriber !== null && root.memoizedInteractions.size > 0) {
23508 var threadID = computeThreadID(root, committedExpirationTime);
23509 subscriber.onWorkStopped(root.memoizedInteractions, threadID);
23510 }
23511 } catch (error) {
23512 // If the subscriber throws, rethrow it in a separate task
23513 scheduleCallback(ImmediatePriority, function () {
23514 throw error;
23515 });
23516 } finally {
23517 // Clear completed interactions from the pending Map.
23518 // Unless the render was suspended or cascading work was scheduled,
23519 // In which case– leave pending interactions until the subsequent render.
23520 var pendingInteractionMap = root.pendingInteractionMap;
23521 pendingInteractionMap.forEach(function (scheduledInteractions, scheduledExpirationTime) {
23522 // Only decrement the pending interaction count if we're done.
23523 // If there's still work at the current priority,
23524 // That indicates that we are waiting for suspense data.
23525 if (scheduledExpirationTime > earliestRemainingTimeAfterCommit) {
23526 pendingInteractionMap.delete(scheduledExpirationTime);
23527
23528 scheduledInteractions.forEach(function (interaction) {
23529 interaction.__count--;
23530
23531 if (subscriber !== null && interaction.__count === 0) {
23532 try {
23533 subscriber.onInteractionScheduledWorkCompleted(interaction);
23534 } catch (error) {
23535 // If the subscriber throws, rethrow it in a separate task
23536 scheduleCallback(ImmediatePriority, function () {
23537 throw error;
23538 });
23539 }
23540 }
23541 });
23542 }
23543 });
23544 }
23545}
23546
23547var onCommitFiberRoot = null;
23548var onCommitFiberUnmount = null;
23549var hasLoggedError = false;
23550
23551var isDevToolsPresent = typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ !== 'undefined';
23552
23553function injectInternals(internals) {
23554 if (typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ === 'undefined') {
23555 // No DevTools
23556 return false;
23557 }
23558 var hook = __REACT_DEVTOOLS_GLOBAL_HOOK__;
23559 if (hook.isDisabled) {
23560 // This isn't a real property on the hook, but it can be set to opt out
23561 // of DevTools integration and associated warnings and logs.
23562 // https://github.com/facebook/react/issues/3877
23563 return true;
23564 }
23565 if (!hook.supportsFiber) {
23566 {
23567 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');
23568 }
23569 // DevTools exists, even though it doesn't support Fiber.
23570 return true;
23571 }
23572 try {
23573 var rendererID = hook.inject(internals);
23574 // We have successfully injected, so now it is safe to set up hooks.
23575 onCommitFiberRoot = function (root, expirationTime) {
23576 try {
23577 var didError = (root.current.effectTag & DidCapture) === DidCapture;
23578 if (enableProfilerTimer) {
23579 var currentTime = requestCurrentTime();
23580 var priorityLevel = inferPriorityFromExpirationTime(currentTime, expirationTime);
23581 hook.onCommitFiberRoot(rendererID, root, priorityLevel, didError);
23582 } else {
23583 hook.onCommitFiberRoot(rendererID, root, undefined, didError);
23584 }
23585 } catch (err) {
23586 if (true && !hasLoggedError) {
23587 hasLoggedError = true;
23588 warningWithoutStack$1(false, 'React DevTools encountered an error: %s', err);
23589 }
23590 }
23591 };
23592 onCommitFiberUnmount = function (fiber) {
23593 try {
23594 hook.onCommitFiberUnmount(rendererID, fiber);
23595 } catch (err) {
23596 if (true && !hasLoggedError) {
23597 hasLoggedError = true;
23598 warningWithoutStack$1(false, 'React DevTools encountered an error: %s', err);
23599 }
23600 }
23601 };
23602 } catch (err) {
23603 // Catch all errors because it is unsafe to throw during initialization.
23604 {
23605 warningWithoutStack$1(false, 'React DevTools encountered an error: %s.', err);
23606 }
23607 }
23608 // DevTools exists
23609 return true;
23610}
23611
23612function onCommitRoot(root, expirationTime) {
23613 if (typeof onCommitFiberRoot === 'function') {
23614 onCommitFiberRoot(root, expirationTime);
23615 }
23616}
23617
23618function onCommitUnmount(fiber) {
23619 if (typeof onCommitFiberUnmount === 'function') {
23620 onCommitFiberUnmount(fiber);
23621 }
23622}
23623
23624var hasBadMapPolyfill = void 0;
23625
23626{
23627 hasBadMapPolyfill = false;
23628 try {
23629 var nonExtensibleObject = Object.preventExtensions({});
23630 var testMap = new Map([[nonExtensibleObject, null]]);
23631 var testSet = new Set([nonExtensibleObject]);
23632 // This is necessary for Rollup to not consider these unused.
23633 // https://github.com/rollup/rollup/issues/1771
23634 // TODO: we can remove these if Rollup fixes the bug.
23635 testMap.set(0, 0);
23636 testSet.add(0);
23637 } catch (e) {
23638 // TODO: Consider warning about bad polyfills
23639 hasBadMapPolyfill = true;
23640 }
23641}
23642
23643// A Fiber is work on a Component that needs to be done or was done. There can
23644// be more than one per component.
23645
23646
23647var debugCounter = void 0;
23648
23649{
23650 debugCounter = 1;
23651}
23652
23653function FiberNode(tag, pendingProps, key, mode) {
23654 // Instance
23655 this.tag = tag;
23656 this.key = key;
23657 this.elementType = null;
23658 this.type = null;
23659 this.stateNode = null;
23660
23661 // Fiber
23662 this.return = null;
23663 this.child = null;
23664 this.sibling = null;
23665 this.index = 0;
23666
23667 this.ref = null;
23668
23669 this.pendingProps = pendingProps;
23670 this.memoizedProps = null;
23671 this.updateQueue = null;
23672 this.memoizedState = null;
23673 this.dependencies = null;
23674
23675 this.mode = mode;
23676
23677 // Effects
23678 this.effectTag = NoEffect;
23679 this.nextEffect = null;
23680
23681 this.firstEffect = null;
23682 this.lastEffect = null;
23683
23684 this.expirationTime = NoWork;
23685 this.childExpirationTime = NoWork;
23686
23687 this.alternate = null;
23688
23689 if (enableProfilerTimer) {
23690 // Note: The following is done to avoid a v8 performance cliff.
23691 //
23692 // Initializing the fields below to smis and later updating them with
23693 // double values will cause Fibers to end up having separate shapes.
23694 // This behavior/bug has something to do with Object.preventExtension().
23695 // Fortunately this only impacts DEV builds.
23696 // Unfortunately it makes React unusably slow for some applications.
23697 // To work around this, initialize the fields below with doubles.
23698 //
23699 // Learn more about this here:
23700 // https://github.com/facebook/react/issues/14365
23701 // https://bugs.chromium.org/p/v8/issues/detail?id=8538
23702 this.actualDuration = Number.NaN;
23703 this.actualStartTime = Number.NaN;
23704 this.selfBaseDuration = Number.NaN;
23705 this.treeBaseDuration = Number.NaN;
23706
23707 // It's okay to replace the initial doubles with smis after initialization.
23708 // This won't trigger the performance cliff mentioned above,
23709 // and it simplifies other profiler code (including DevTools).
23710 this.actualDuration = 0;
23711 this.actualStartTime = -1;
23712 this.selfBaseDuration = 0;
23713 this.treeBaseDuration = 0;
23714 }
23715
23716 {
23717 this._debugID = debugCounter++;
23718 this._debugSource = null;
23719 this._debugOwner = null;
23720 this._debugIsCurrentlyTiming = false;
23721 this._debugNeedsRemount = false;
23722 this._debugHookTypes = null;
23723 if (!hasBadMapPolyfill && typeof Object.preventExtensions === 'function') {
23724 Object.preventExtensions(this);
23725 }
23726 }
23727}
23728
23729// This is a constructor function, rather than a POJO constructor, still
23730// please ensure we do the following:
23731// 1) Nobody should add any instance methods on this. Instance methods can be
23732// more difficult to predict when they get optimized and they are almost
23733// never inlined properly in static compilers.
23734// 2) Nobody should rely on `instanceof Fiber` for type testing. We should
23735// always know when it is a fiber.
23736// 3) We might want to experiment with using numeric keys since they are easier
23737// to optimize in a non-JIT environment.
23738// 4) We can easily go from a constructor to a createFiber object literal if that
23739// is faster.
23740// 5) It should be easy to port this to a C struct and keep a C implementation
23741// compatible.
23742var createFiber = function (tag, pendingProps, key, mode) {
23743 // $FlowFixMe: the shapes are exact here but Flow doesn't like constructors
23744 return new FiberNode(tag, pendingProps, key, mode);
23745};
23746
23747function shouldConstruct(Component) {
23748 var prototype = Component.prototype;
23749 return !!(prototype && prototype.isReactComponent);
23750}
23751
23752function isSimpleFunctionComponent(type) {
23753 return typeof type === 'function' && !shouldConstruct(type) && type.defaultProps === undefined;
23754}
23755
23756function resolveLazyComponentTag(Component) {
23757 if (typeof Component === 'function') {
23758 return shouldConstruct(Component) ? ClassComponent : FunctionComponent;
23759 } else if (Component !== undefined && Component !== null) {
23760 var $$typeof = Component.$$typeof;
23761 if ($$typeof === REACT_FORWARD_REF_TYPE) {
23762 return ForwardRef;
23763 }
23764 if ($$typeof === REACT_MEMO_TYPE) {
23765 return MemoComponent;
23766 }
23767 }
23768 return IndeterminateComponent;
23769}
23770
23771// This is used to create an alternate fiber to do work on.
23772function createWorkInProgress(current, pendingProps, expirationTime) {
23773 var workInProgress = current.alternate;
23774 if (workInProgress === null) {
23775 // We use a double buffering pooling technique because we know that we'll
23776 // only ever need at most two versions of a tree. We pool the "other" unused
23777 // node that we're free to reuse. This is lazily created to avoid allocating
23778 // extra objects for things that are never updated. It also allow us to
23779 // reclaim the extra memory if needed.
23780 workInProgress = createFiber(current.tag, pendingProps, current.key, current.mode);
23781 workInProgress.elementType = current.elementType;
23782 workInProgress.type = current.type;
23783 workInProgress.stateNode = current.stateNode;
23784
23785 {
23786 // DEV-only fields
23787 workInProgress._debugID = current._debugID;
23788 workInProgress._debugSource = current._debugSource;
23789 workInProgress._debugOwner = current._debugOwner;
23790 workInProgress._debugHookTypes = current._debugHookTypes;
23791 }
23792
23793 workInProgress.alternate = current;
23794 current.alternate = workInProgress;
23795 } else {
23796 workInProgress.pendingProps = pendingProps;
23797
23798 // We already have an alternate.
23799 // Reset the effect tag.
23800 workInProgress.effectTag = NoEffect;
23801
23802 // The effect list is no longer valid.
23803 workInProgress.nextEffect = null;
23804 workInProgress.firstEffect = null;
23805 workInProgress.lastEffect = null;
23806
23807 if (enableProfilerTimer) {
23808 // We intentionally reset, rather than copy, actualDuration & actualStartTime.
23809 // This prevents time from endlessly accumulating in new commits.
23810 // This has the downside of resetting values for different priority renders,
23811 // But works for yielding (the common case) and should support resuming.
23812 workInProgress.actualDuration = 0;
23813 workInProgress.actualStartTime = -1;
23814 }
23815 }
23816
23817 workInProgress.childExpirationTime = current.childExpirationTime;
23818 workInProgress.expirationTime = current.expirationTime;
23819
23820 workInProgress.child = current.child;
23821 workInProgress.memoizedProps = current.memoizedProps;
23822 workInProgress.memoizedState = current.memoizedState;
23823 workInProgress.updateQueue = current.updateQueue;
23824
23825 // Clone the dependencies object. This is mutated during the render phase, so
23826 // it cannot be shared with the current fiber.
23827 var currentDependencies = current.dependencies;
23828 workInProgress.dependencies = currentDependencies === null ? null : {
23829 expirationTime: currentDependencies.expirationTime,
23830 firstContext: currentDependencies.firstContext,
23831 responders: currentDependencies.responders
23832 };
23833
23834 // These will be overridden during the parent's reconciliation
23835 workInProgress.sibling = current.sibling;
23836 workInProgress.index = current.index;
23837 workInProgress.ref = current.ref;
23838
23839 if (enableProfilerTimer) {
23840 workInProgress.selfBaseDuration = current.selfBaseDuration;
23841 workInProgress.treeBaseDuration = current.treeBaseDuration;
23842 }
23843
23844 {
23845 workInProgress._debugNeedsRemount = current._debugNeedsRemount;
23846 switch (workInProgress.tag) {
23847 case IndeterminateComponent:
23848 case FunctionComponent:
23849 case SimpleMemoComponent:
23850 workInProgress.type = resolveFunctionForHotReloading(current.type);
23851 break;
23852 case ClassComponent:
23853 workInProgress.type = resolveClassForHotReloading(current.type);
23854 break;
23855 case ForwardRef:
23856 workInProgress.type = resolveForwardRefForHotReloading(current.type);
23857 break;
23858 default:
23859 break;
23860 }
23861 }
23862
23863 return workInProgress;
23864}
23865
23866// Used to reuse a Fiber for a second pass.
23867function resetWorkInProgress(workInProgress, renderExpirationTime) {
23868 // This resets the Fiber to what createFiber or createWorkInProgress would
23869 // have set the values to before during the first pass. Ideally this wouldn't
23870 // be necessary but unfortunately many code paths reads from the workInProgress
23871 // when they should be reading from current and writing to workInProgress.
23872
23873 // We assume pendingProps, index, key, ref, return are still untouched to
23874 // avoid doing another reconciliation.
23875
23876 // Reset the effect tag but keep any Placement tags, since that's something
23877 // that child fiber is setting, not the reconciliation.
23878 workInProgress.effectTag &= Placement;
23879
23880 // The effect list is no longer valid.
23881 workInProgress.nextEffect = null;
23882 workInProgress.firstEffect = null;
23883 workInProgress.lastEffect = null;
23884
23885 var current = workInProgress.alternate;
23886 if (current === null) {
23887 // Reset to createFiber's initial values.
23888 workInProgress.childExpirationTime = NoWork;
23889 workInProgress.expirationTime = renderExpirationTime;
23890
23891 workInProgress.child = null;
23892 workInProgress.memoizedProps = null;
23893 workInProgress.memoizedState = null;
23894 workInProgress.updateQueue = null;
23895
23896 workInProgress.dependencies = null;
23897
23898 if (enableProfilerTimer) {
23899 // Note: We don't reset the actualTime counts. It's useful to accumulate
23900 // actual time across multiple render passes.
23901 workInProgress.selfBaseDuration = 0;
23902 workInProgress.treeBaseDuration = 0;
23903 }
23904 } else {
23905 // Reset to the cloned values that createWorkInProgress would've.
23906 workInProgress.childExpirationTime = current.childExpirationTime;
23907 workInProgress.expirationTime = current.expirationTime;
23908
23909 workInProgress.child = current.child;
23910 workInProgress.memoizedProps = current.memoizedProps;
23911 workInProgress.memoizedState = current.memoizedState;
23912 workInProgress.updateQueue = current.updateQueue;
23913
23914 // Clone the dependencies object. This is mutated during the render phase, so
23915 // it cannot be shared with the current fiber.
23916 var currentDependencies = current.dependencies;
23917 workInProgress.dependencies = currentDependencies === null ? null : {
23918 expirationTime: currentDependencies.expirationTime,
23919 firstContext: currentDependencies.firstContext,
23920 responders: currentDependencies.responders
23921 };
23922
23923 if (enableProfilerTimer) {
23924 // Note: We don't reset the actualTime counts. It's useful to accumulate
23925 // actual time across multiple render passes.
23926 workInProgress.selfBaseDuration = current.selfBaseDuration;
23927 workInProgress.treeBaseDuration = current.treeBaseDuration;
23928 }
23929 }
23930
23931 return workInProgress;
23932}
23933
23934function createHostRootFiber(tag) {
23935 var mode = void 0;
23936 if (tag === ConcurrentRoot) {
23937 mode = ConcurrentMode | BatchedMode | StrictMode;
23938 } else if (tag === BatchedRoot) {
23939 mode = BatchedMode | StrictMode;
23940 } else {
23941 mode = NoMode;
23942 }
23943
23944 if (enableProfilerTimer && isDevToolsPresent) {
23945 // Always collect profile timings when DevTools are present.
23946 // This enables DevTools to start capturing timing at any point–
23947 // Without some nodes in the tree having empty base times.
23948 mode |= ProfileMode;
23949 }
23950
23951 return createFiber(HostRoot, null, null, mode);
23952}
23953
23954function createFiberFromTypeAndProps(type, // React$ElementType
23955key, pendingProps, owner, mode, expirationTime) {
23956 var fiber = void 0;
23957
23958 var fiberTag = IndeterminateComponent;
23959 // The resolved type is set if we know what the final type will be. I.e. it's not lazy.
23960 var resolvedType = type;
23961 if (typeof type === 'function') {
23962 if (shouldConstruct(type)) {
23963 fiberTag = ClassComponent;
23964 {
23965 resolvedType = resolveClassForHotReloading(resolvedType);
23966 }
23967 } else {
23968 {
23969 resolvedType = resolveFunctionForHotReloading(resolvedType);
23970 }
23971 }
23972 } else if (typeof type === 'string') {
23973 fiberTag = HostComponent;
23974 } else {
23975 getTag: switch (type) {
23976 case REACT_FRAGMENT_TYPE:
23977 return createFiberFromFragment(pendingProps.children, mode, expirationTime, key);
23978 case REACT_CONCURRENT_MODE_TYPE:
23979 fiberTag = Mode;
23980 mode |= ConcurrentMode | BatchedMode | StrictMode;
23981 break;
23982 case REACT_STRICT_MODE_TYPE:
23983 fiberTag = Mode;
23984 mode |= StrictMode;
23985 break;
23986 case REACT_PROFILER_TYPE:
23987 return createFiberFromProfiler(pendingProps, mode, expirationTime, key);
23988 case REACT_SUSPENSE_TYPE:
23989 return createFiberFromSuspense(pendingProps, mode, expirationTime, key);
23990 case REACT_SUSPENSE_LIST_TYPE:
23991 return createFiberFromSuspenseList(pendingProps, mode, expirationTime, key);
23992 default:
23993 {
23994 if (typeof type === 'object' && type !== null) {
23995 switch (type.$$typeof) {
23996 case REACT_PROVIDER_TYPE:
23997 fiberTag = ContextProvider;
23998 break getTag;
23999 case REACT_CONTEXT_TYPE:
24000 // This is a consumer
24001 fiberTag = ContextConsumer;
24002 break getTag;
24003 case REACT_FORWARD_REF_TYPE:
24004 fiberTag = ForwardRef;
24005 {
24006 resolvedType = resolveForwardRefForHotReloading(resolvedType);
24007 }
24008 break getTag;
24009 case REACT_MEMO_TYPE:
24010 fiberTag = MemoComponent;
24011 break getTag;
24012 case REACT_LAZY_TYPE:
24013 fiberTag = LazyComponent;
24014 resolvedType = null;
24015 break getTag;
24016 case REACT_FUNDAMENTAL_TYPE:
24017 if (enableFundamentalAPI) {
24018 return createFiberFromFundamental(type, pendingProps, mode, expirationTime, key);
24019 }
24020 break;
24021 }
24022 }
24023 var info = '';
24024 {
24025 if (type === undefined || typeof type === 'object' && type !== null && Object.keys(type).length === 0) {
24026 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.';
24027 }
24028 var ownerName = owner ? getComponentName(owner.type) : null;
24029 if (ownerName) {
24030 info += '\n\nCheck the render method of `' + ownerName + '`.';
24031 }
24032 }
24033 (function () {
24034 {
24035 {
24036 throw ReactError(Error('Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: ' + (type == null ? type : typeof type) + '.' + info));
24037 }
24038 }
24039 })();
24040 }
24041 }
24042 }
24043
24044 fiber = createFiber(fiberTag, pendingProps, key, mode);
24045 fiber.elementType = type;
24046 fiber.type = resolvedType;
24047 fiber.expirationTime = expirationTime;
24048
24049 return fiber;
24050}
24051
24052function createFiberFromElement(element, mode, expirationTime) {
24053 var owner = null;
24054 {
24055 owner = element._owner;
24056 }
24057 var type = element.type;
24058 var key = element.key;
24059 var pendingProps = element.props;
24060 var fiber = createFiberFromTypeAndProps(type, key, pendingProps, owner, mode, expirationTime);
24061 {
24062 fiber._debugSource = element._source;
24063 fiber._debugOwner = element._owner;
24064 }
24065 return fiber;
24066}
24067
24068function createFiberFromFragment(elements, mode, expirationTime, key) {
24069 var fiber = createFiber(Fragment, elements, key, mode);
24070 fiber.expirationTime = expirationTime;
24071 return fiber;
24072}
24073
24074function createFiberFromFundamental(fundamentalComponent, pendingProps, mode, expirationTime, key) {
24075 var fiber = createFiber(FundamentalComponent, pendingProps, key, mode);
24076 fiber.elementType = fundamentalComponent;
24077 fiber.type = fundamentalComponent;
24078 fiber.expirationTime = expirationTime;
24079 return fiber;
24080}
24081
24082function createFiberFromProfiler(pendingProps, mode, expirationTime, key) {
24083 {
24084 if (typeof pendingProps.id !== 'string' || typeof pendingProps.onRender !== 'function') {
24085 warningWithoutStack$1(false, 'Profiler must specify an "id" string and "onRender" function as props');
24086 }
24087 }
24088
24089 var fiber = createFiber(Profiler, pendingProps, key, mode | ProfileMode);
24090 // TODO: The Profiler fiber shouldn't have a type. It has a tag.
24091 fiber.elementType = REACT_PROFILER_TYPE;
24092 fiber.type = REACT_PROFILER_TYPE;
24093 fiber.expirationTime = expirationTime;
24094
24095 return fiber;
24096}
24097
24098function createFiberFromSuspense(pendingProps, mode, expirationTime, key) {
24099 var fiber = createFiber(SuspenseComponent, pendingProps, key, mode);
24100
24101 // TODO: The SuspenseComponent fiber shouldn't have a type. It has a tag.
24102 // This needs to be fixed in getComponentName so that it relies on the tag
24103 // instead.
24104 fiber.type = REACT_SUSPENSE_TYPE;
24105 fiber.elementType = REACT_SUSPENSE_TYPE;
24106
24107 fiber.expirationTime = expirationTime;
24108 return fiber;
24109}
24110
24111function createFiberFromSuspenseList(pendingProps, mode, expirationTime, key) {
24112 var fiber = createFiber(SuspenseListComponent, pendingProps, key, mode);
24113 {
24114 // TODO: The SuspenseListComponent fiber shouldn't have a type. It has a tag.
24115 // This needs to be fixed in getComponentName so that it relies on the tag
24116 // instead.
24117 fiber.type = REACT_SUSPENSE_LIST_TYPE;
24118 }
24119 fiber.elementType = REACT_SUSPENSE_LIST_TYPE;
24120 fiber.expirationTime = expirationTime;
24121 return fiber;
24122}
24123
24124function createFiberFromText(content, mode, expirationTime) {
24125 var fiber = createFiber(HostText, content, null, mode);
24126 fiber.expirationTime = expirationTime;
24127 return fiber;
24128}
24129
24130function createFiberFromHostInstanceForDeletion() {
24131 var fiber = createFiber(HostComponent, null, null, NoMode);
24132 // TODO: These should not need a type.
24133 fiber.elementType = 'DELETED';
24134 fiber.type = 'DELETED';
24135 return fiber;
24136}
24137
24138function createFiberFromPortal(portal, mode, expirationTime) {
24139 var pendingProps = portal.children !== null ? portal.children : [];
24140 var fiber = createFiber(HostPortal, pendingProps, portal.key, mode);
24141 fiber.expirationTime = expirationTime;
24142 fiber.stateNode = {
24143 containerInfo: portal.containerInfo,
24144 pendingChildren: null, // Used by persistent updates
24145 implementation: portal.implementation
24146 };
24147 return fiber;
24148}
24149
24150// Used for stashing WIP properties to replay failed work in DEV.
24151function assignFiberPropertiesInDEV(target, source) {
24152 if (target === null) {
24153 // This Fiber's initial properties will always be overwritten.
24154 // We only use a Fiber to ensure the same hidden class so DEV isn't slow.
24155 target = createFiber(IndeterminateComponent, null, null, NoMode);
24156 }
24157
24158 // This is intentionally written as a list of all properties.
24159 // We tried to use Object.assign() instead but this is called in
24160 // the hottest path, and Object.assign() was too slow:
24161 // https://github.com/facebook/react/issues/12502
24162 // This code is DEV-only so size is not a concern.
24163
24164 target.tag = source.tag;
24165 target.key = source.key;
24166 target.elementType = source.elementType;
24167 target.type = source.type;
24168 target.stateNode = source.stateNode;
24169 target.return = source.return;
24170 target.child = source.child;
24171 target.sibling = source.sibling;
24172 target.index = source.index;
24173 target.ref = source.ref;
24174 target.pendingProps = source.pendingProps;
24175 target.memoizedProps = source.memoizedProps;
24176 target.updateQueue = source.updateQueue;
24177 target.memoizedState = source.memoizedState;
24178 target.dependencies = source.dependencies;
24179 target.mode = source.mode;
24180 target.effectTag = source.effectTag;
24181 target.nextEffect = source.nextEffect;
24182 target.firstEffect = source.firstEffect;
24183 target.lastEffect = source.lastEffect;
24184 target.expirationTime = source.expirationTime;
24185 target.childExpirationTime = source.childExpirationTime;
24186 target.alternate = source.alternate;
24187 if (enableProfilerTimer) {
24188 target.actualDuration = source.actualDuration;
24189 target.actualStartTime = source.actualStartTime;
24190 target.selfBaseDuration = source.selfBaseDuration;
24191 target.treeBaseDuration = source.treeBaseDuration;
24192 }
24193 target._debugID = source._debugID;
24194 target._debugSource = source._debugSource;
24195 target._debugOwner = source._debugOwner;
24196 target._debugIsCurrentlyTiming = source._debugIsCurrentlyTiming;
24197 target._debugNeedsRemount = source._debugNeedsRemount;
24198 target._debugHookTypes = source._debugHookTypes;
24199 return target;
24200}
24201
24202// TODO: This should be lifted into the renderer.
24203
24204
24205// The following attributes are only used by interaction tracing builds.
24206// They enable interactions to be associated with their async work,
24207// And expose interaction metadata to the React DevTools Profiler plugin.
24208// Note that these attributes are only defined when the enableSchedulerTracing flag is enabled.
24209
24210
24211// Exported FiberRoot type includes all properties,
24212// To avoid requiring potentially error-prone :any casts throughout the project.
24213// Profiling properties are only safe to access in profiling builds (when enableSchedulerTracing is true).
24214// The types are defined separately within this file to ensure they stay in sync.
24215// (We don't have to use an inline :any cast when enableSchedulerTracing is disabled.)
24216
24217
24218function FiberRootNode(containerInfo, tag, hydrate) {
24219 this.tag = tag;
24220 this.current = null;
24221 this.containerInfo = containerInfo;
24222 this.pendingChildren = null;
24223 this.pingCache = null;
24224 this.finishedExpirationTime = NoWork;
24225 this.finishedWork = null;
24226 this.timeoutHandle = noTimeout;
24227 this.context = null;
24228 this.pendingContext = null;
24229 this.hydrate = hydrate;
24230 this.firstBatch = null;
24231 this.callbackNode = null;
24232 this.callbackExpirationTime = NoWork;
24233 this.firstPendingTime = NoWork;
24234 this.lastPendingTime = NoWork;
24235 this.pingTime = NoWork;
24236
24237 if (enableSchedulerTracing) {
24238 this.interactionThreadID = tracing.unstable_getThreadID();
24239 this.memoizedInteractions = new Set();
24240 this.pendingInteractionMap = new Map();
24241 }
24242}
24243
24244function createFiberRoot(containerInfo, tag, hydrate) {
24245 var root = new FiberRootNode(containerInfo, tag, hydrate);
24246
24247 // Cyclic construction. This cheats the type system right now because
24248 // stateNode is any.
24249 var uninitializedFiber = createHostRootFiber(tag);
24250 root.current = uninitializedFiber;
24251 uninitializedFiber.stateNode = root;
24252
24253 return root;
24254}
24255
24256// This lets us hook into Fiber to debug what it's doing.
24257// See https://github.com/facebook/react/pull/8033.
24258// This is not part of the public API, not even for React DevTools.
24259// You may only inject a debugTool if you work on React Fiber itself.
24260var ReactFiberInstrumentation = {
24261 debugTool: null
24262};
24263
24264var ReactFiberInstrumentation_1 = ReactFiberInstrumentation;
24265
24266// 0 is PROD, 1 is DEV.
24267// Might add PROFILE later.
24268
24269
24270var didWarnAboutNestedUpdates = void 0;
24271var didWarnAboutFindNodeInStrictMode = void 0;
24272
24273{
24274 didWarnAboutNestedUpdates = false;
24275 didWarnAboutFindNodeInStrictMode = {};
24276}
24277
24278function getContextForSubtree(parentComponent) {
24279 if (!parentComponent) {
24280 return emptyContextObject;
24281 }
24282
24283 var fiber = get(parentComponent);
24284 var parentContext = findCurrentUnmaskedContext(fiber);
24285
24286 if (fiber.tag === ClassComponent) {
24287 var Component = fiber.type;
24288 if (isContextProvider(Component)) {
24289 return processChildContext(fiber, Component, parentContext);
24290 }
24291 }
24292
24293 return parentContext;
24294}
24295
24296function scheduleRootUpdate(current$$1, element, expirationTime, suspenseConfig, callback) {
24297 {
24298 if (phase === 'render' && current !== null && !didWarnAboutNestedUpdates) {
24299 didWarnAboutNestedUpdates = true;
24300 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');
24301 }
24302 }
24303
24304 var update = createUpdate(expirationTime, suspenseConfig);
24305 // Caution: React DevTools currently depends on this property
24306 // being called "element".
24307 update.payload = { element: element };
24308
24309 callback = callback === undefined ? null : callback;
24310 if (callback !== null) {
24311 !(typeof callback === 'function') ? warningWithoutStack$1(false, 'render(...): Expected the last optional `callback` argument to be a ' + 'function. Instead received: %s.', callback) : void 0;
24312 update.callback = callback;
24313 }
24314
24315 if (revertPassiveEffectsChange) {
24316 flushPassiveEffects();
24317 }
24318 enqueueUpdate(current$$1, update);
24319 scheduleWork(current$$1, expirationTime);
24320
24321 return expirationTime;
24322}
24323
24324function updateContainerAtExpirationTime(element, container, parentComponent, expirationTime, suspenseConfig, callback) {
24325 // TODO: If this is a nested container, this won't be the root.
24326 var current$$1 = container.current;
24327
24328 {
24329 if (ReactFiberInstrumentation_1.debugTool) {
24330 if (current$$1.alternate === null) {
24331 ReactFiberInstrumentation_1.debugTool.onMountContainer(container);
24332 } else if (element === null) {
24333 ReactFiberInstrumentation_1.debugTool.onUnmountContainer(container);
24334 } else {
24335 ReactFiberInstrumentation_1.debugTool.onUpdateContainer(container);
24336 }
24337 }
24338 }
24339
24340 var context = getContextForSubtree(parentComponent);
24341 if (container.context === null) {
24342 container.context = context;
24343 } else {
24344 container.pendingContext = context;
24345 }
24346
24347 return scheduleRootUpdate(current$$1, element, expirationTime, suspenseConfig, callback);
24348}
24349
24350function findHostInstance(component) {
24351 var fiber = get(component);
24352 if (fiber === undefined) {
24353 if (typeof component.render === 'function') {
24354 (function () {
24355 {
24356 {
24357 throw ReactError(Error('Unable to find node on an unmounted component.'));
24358 }
24359 }
24360 })();
24361 } else {
24362 (function () {
24363 {
24364 {
24365 throw ReactError(Error('Argument appears to not be a ReactComponent. Keys: ' + Object.keys(component)));
24366 }
24367 }
24368 })();
24369 }
24370 }
24371 var hostFiber = findCurrentHostFiber(fiber);
24372 if (hostFiber === null) {
24373 return null;
24374 }
24375 return hostFiber.stateNode;
24376}
24377
24378function findHostInstanceWithWarning(component, methodName) {
24379 {
24380 var fiber = get(component);
24381 if (fiber === undefined) {
24382 if (typeof component.render === 'function') {
24383 (function () {
24384 {
24385 {
24386 throw ReactError(Error('Unable to find node on an unmounted component.'));
24387 }
24388 }
24389 })();
24390 } else {
24391 (function () {
24392 {
24393 {
24394 throw ReactError(Error('Argument appears to not be a ReactComponent. Keys: ' + Object.keys(component)));
24395 }
24396 }
24397 })();
24398 }
24399 }
24400 var hostFiber = findCurrentHostFiber(fiber);
24401 if (hostFiber === null) {
24402 return null;
24403 }
24404 if (hostFiber.mode & StrictMode) {
24405 var componentName = getComponentName(fiber.type) || 'Component';
24406 if (!didWarnAboutFindNodeInStrictMode[componentName]) {
24407 didWarnAboutFindNodeInStrictMode[componentName] = true;
24408 if (fiber.mode & StrictMode) {
24409 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));
24410 } else {
24411 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));
24412 }
24413 }
24414 }
24415 return hostFiber.stateNode;
24416 }
24417 return findHostInstance(component);
24418}
24419
24420function createContainer(containerInfo, tag, hydrate) {
24421 return createFiberRoot(containerInfo, tag, hydrate);
24422}
24423
24424function updateContainer(element, container, parentComponent, callback) {
24425 var current$$1 = container.current;
24426 var currentTime = requestCurrentTime();
24427 {
24428 // $FlowExpectedError - jest isn't a global, and isn't recognized outside of tests
24429 if ('undefined' !== typeof jest) {
24430 warnIfUnmockedScheduler(current$$1);
24431 warnIfNotScopedWithMatchingAct(current$$1);
24432 }
24433 }
24434 var suspenseConfig = requestCurrentSuspenseConfig();
24435 var expirationTime = computeExpirationForFiber(currentTime, current$$1, suspenseConfig);
24436 return updateContainerAtExpirationTime(element, container, parentComponent, expirationTime, suspenseConfig, callback);
24437}
24438
24439function getPublicRootInstance(container) {
24440 var containerFiber = container.current;
24441 if (!containerFiber.child) {
24442 return null;
24443 }
24444 switch (containerFiber.child.tag) {
24445 case HostComponent:
24446 return getPublicInstance(containerFiber.child.stateNode);
24447 default:
24448 return containerFiber.child.stateNode;
24449 }
24450}
24451
24452function findHostInstanceWithNoPortals(fiber) {
24453 var hostFiber = findCurrentHostFiberWithNoPortals(fiber);
24454 if (hostFiber === null) {
24455 return null;
24456 }
24457 if (hostFiber.tag === FundamentalComponent) {
24458 return hostFiber.stateNode.instance;
24459 }
24460 return hostFiber.stateNode;
24461}
24462
24463var shouldSuspendImpl = function (fiber) {
24464 return false;
24465};
24466
24467function shouldSuspend(fiber) {
24468 return shouldSuspendImpl(fiber);
24469}
24470
24471var overrideHookState = null;
24472var overrideProps = null;
24473var scheduleUpdate = null;
24474var setSuspenseHandler = null;
24475
24476{
24477 var copyWithSetImpl = function (obj, path, idx, value) {
24478 if (idx >= path.length) {
24479 return value;
24480 }
24481 var key = path[idx];
24482 var updated = Array.isArray(obj) ? obj.slice() : _assign({}, obj);
24483 // $FlowFixMe number or string is fine here
24484 updated[key] = copyWithSetImpl(obj[key], path, idx + 1, value);
24485 return updated;
24486 };
24487
24488 var copyWithSet = function (obj, path, value) {
24489 return copyWithSetImpl(obj, path, 0, value);
24490 };
24491
24492 // Support DevTools editable values for useState and useReducer.
24493 overrideHookState = function (fiber, id, path, value) {
24494 // For now, the "id" of stateful hooks is just the stateful hook index.
24495 // This may change in the future with e.g. nested hooks.
24496 var currentHook = fiber.memoizedState;
24497 while (currentHook !== null && id > 0) {
24498 currentHook = currentHook.next;
24499 id--;
24500 }
24501 if (currentHook !== null) {
24502 if (revertPassiveEffectsChange) {
24503 flushPassiveEffects();
24504 }
24505
24506 var newState = copyWithSet(currentHook.memoizedState, path, value);
24507 currentHook.memoizedState = newState;
24508 currentHook.baseState = newState;
24509
24510 // We aren't actually adding an update to the queue,
24511 // because there is no update we can add for useReducer hooks that won't trigger an error.
24512 // (There's no appropriate action type for DevTools overrides.)
24513 // As a result though, React will see the scheduled update as a noop and bailout.
24514 // Shallow cloning props works as a workaround for now to bypass the bailout check.
24515 fiber.memoizedProps = _assign({}, fiber.memoizedProps);
24516
24517 scheduleWork(fiber, Sync);
24518 }
24519 };
24520
24521 // Support DevTools props for function components, forwardRef, memo, host components, etc.
24522 overrideProps = function (fiber, path, value) {
24523 if (revertPassiveEffectsChange) {
24524 flushPassiveEffects();
24525 }
24526 fiber.pendingProps = copyWithSet(fiber.memoizedProps, path, value);
24527 if (fiber.alternate) {
24528 fiber.alternate.pendingProps = fiber.pendingProps;
24529 }
24530 scheduleWork(fiber, Sync);
24531 };
24532
24533 scheduleUpdate = function (fiber) {
24534 if (revertPassiveEffectsChange) {
24535 flushPassiveEffects();
24536 }
24537 scheduleWork(fiber, Sync);
24538 };
24539
24540 setSuspenseHandler = function (newShouldSuspendImpl) {
24541 shouldSuspendImpl = newShouldSuspendImpl;
24542 };
24543}
24544
24545function injectIntoDevTools(devToolsConfig) {
24546 var findFiberByHostInstance = devToolsConfig.findFiberByHostInstance;
24547 var ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher;
24548
24549
24550 return injectInternals(_assign({}, devToolsConfig, {
24551 overrideHookState: overrideHookState,
24552 overrideProps: overrideProps,
24553 setSuspenseHandler: setSuspenseHandler,
24554 scheduleUpdate: scheduleUpdate,
24555 currentDispatcherRef: ReactCurrentDispatcher,
24556 findHostInstanceByFiber: function (fiber) {
24557 var hostFiber = findCurrentHostFiber(fiber);
24558 if (hostFiber === null) {
24559 return null;
24560 }
24561 return hostFiber.stateNode;
24562 },
24563 findFiberByHostInstance: function (instance) {
24564 if (!findFiberByHostInstance) {
24565 // Might not be implemented by the renderer.
24566 return null;
24567 }
24568 return findFiberByHostInstance(instance);
24569 },
24570
24571 // React Refresh
24572 findHostInstancesForRefresh: findHostInstancesForRefresh,
24573 scheduleRefresh: scheduleRefresh,
24574 scheduleRoot: scheduleRoot,
24575 setRefreshHandler: setRefreshHandler,
24576 // Enables DevTools to append owner stacks to error messages in DEV mode.
24577 getCurrentFiber: function () {
24578 return current;
24579 }
24580 }));
24581}
24582
24583// This file intentionally does *not* have the Flow annotation.
24584// Don't add it. See `./inline-typed.js` for an explanation.
24585
24586function createPortal$1(children, containerInfo,
24587// TODO: figure out the API for cross-renderer implementation.
24588implementation) {
24589 var key = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null;
24590
24591 return {
24592 // This tag allow us to uniquely identify this as a React Portal
24593 $$typeof: REACT_PORTAL_TYPE,
24594 key: key == null ? null : '' + key,
24595 children: children,
24596 containerInfo: containerInfo,
24597 implementation: implementation
24598 };
24599}
24600
24601// TODO: this is special because it gets imported during build.
24602
24603var ReactVersion = '16.9.0';
24604
24605// TODO: This type is shared between the reconciler and ReactDOM, but will
24606// eventually be lifted out to the renderer.
24607
24608var ReactCurrentOwner = ReactSharedInternals.ReactCurrentOwner;
24609
24610var topLevelUpdateWarnings = void 0;
24611var warnOnInvalidCallback = void 0;
24612var didWarnAboutUnstableCreatePortal = false;
24613
24614{
24615 if (typeof Map !== 'function' ||
24616 // $FlowIssue Flow incorrectly thinks Map has no prototype
24617 Map.prototype == null || typeof Map.prototype.forEach !== 'function' || typeof Set !== 'function' ||
24618 // $FlowIssue Flow incorrectly thinks Set has no prototype
24619 Set.prototype == null || typeof Set.prototype.clear !== 'function' || typeof Set.prototype.forEach !== 'function') {
24620 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');
24621 }
24622
24623 topLevelUpdateWarnings = function (container) {
24624 if (container._reactRootContainer && container.nodeType !== COMMENT_NODE) {
24625 var hostInstance = findHostInstanceWithNoPortals(container._reactRootContainer._internalRoot.current);
24626 if (hostInstance) {
24627 !(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;
24628 }
24629 }
24630
24631 var isRootRenderedBySomeReact = !!container._reactRootContainer;
24632 var rootEl = getReactRootElementInContainer(container);
24633 var hasNonRootReactChild = !!(rootEl && getInstanceFromNode$1(rootEl));
24634
24635 !(!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;
24636
24637 !(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;
24638 };
24639
24640 warnOnInvalidCallback = function (callback, callerName) {
24641 !(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;
24642 };
24643}
24644
24645setRestoreImplementation(restoreControlledState$1);
24646
24647function ReactBatch(root) {
24648 var expirationTime = computeUniqueAsyncExpiration();
24649 this._expirationTime = expirationTime;
24650 this._root = root;
24651 this._next = null;
24652 this._callbacks = null;
24653 this._didComplete = false;
24654 this._hasChildren = false;
24655 this._children = null;
24656 this._defer = true;
24657}
24658ReactBatch.prototype.render = function (children) {
24659 var _this = this;
24660
24661 (function () {
24662 if (!_this._defer) {
24663 {
24664 throw ReactError(Error('batch.render: Cannot render a batch that already committed.'));
24665 }
24666 }
24667 })();
24668 this._hasChildren = true;
24669 this._children = children;
24670 var internalRoot = this._root._internalRoot;
24671 var expirationTime = this._expirationTime;
24672 var work = new ReactWork();
24673 updateContainerAtExpirationTime(children, internalRoot, null, expirationTime, null, work._onCommit);
24674 return work;
24675};
24676ReactBatch.prototype.then = function (onComplete) {
24677 if (this._didComplete) {
24678 onComplete();
24679 return;
24680 }
24681 var callbacks = this._callbacks;
24682 if (callbacks === null) {
24683 callbacks = this._callbacks = [];
24684 }
24685 callbacks.push(onComplete);
24686};
24687ReactBatch.prototype.commit = function () {
24688 var _this2 = this;
24689
24690 var internalRoot = this._root._internalRoot;
24691 var firstBatch = internalRoot.firstBatch;
24692 (function () {
24693 if (!(_this2._defer && firstBatch !== null)) {
24694 {
24695 throw ReactError(Error('batch.commit: Cannot commit a batch multiple times.'));
24696 }
24697 }
24698 })();
24699
24700 if (!this._hasChildren) {
24701 // This batch is empty. Return.
24702 this._next = null;
24703 this._defer = false;
24704 return;
24705 }
24706
24707 var expirationTime = this._expirationTime;
24708
24709 // Ensure this is the first batch in the list.
24710 if (firstBatch !== this) {
24711 // This batch is not the earliest batch. We need to move it to the front.
24712 // Update its expiration time to be the expiration time of the earliest
24713 // batch, so that we can flush it without flushing the other batches.
24714 if (this._hasChildren) {
24715 expirationTime = this._expirationTime = firstBatch._expirationTime;
24716 // Rendering this batch again ensures its children will be the final state
24717 // when we flush (updates are processed in insertion order: last
24718 // update wins).
24719 // TODO: This forces a restart. Should we print a warning?
24720 this.render(this._children);
24721 }
24722
24723 // Remove the batch from the list.
24724 var previous = null;
24725 var batch = firstBatch;
24726 while (batch !== this) {
24727 previous = batch;
24728 batch = batch._next;
24729 }
24730 (function () {
24731 if (!(previous !== null)) {
24732 {
24733 throw ReactError(Error('batch.commit: Cannot commit a batch multiple times.'));
24734 }
24735 }
24736 })();
24737 previous._next = batch._next;
24738
24739 // Add it to the front.
24740 this._next = firstBatch;
24741 firstBatch = internalRoot.firstBatch = this;
24742 }
24743
24744 // Synchronously flush all the work up to this batch's expiration time.
24745 this._defer = false;
24746 flushRoot(internalRoot, expirationTime);
24747
24748 // Pop the batch from the list.
24749 var next = this._next;
24750 this._next = null;
24751 firstBatch = internalRoot.firstBatch = next;
24752
24753 // Append the next earliest batch's children to the update queue.
24754 if (firstBatch !== null && firstBatch._hasChildren) {
24755 firstBatch.render(firstBatch._children);
24756 }
24757};
24758ReactBatch.prototype._onComplete = function () {
24759 if (this._didComplete) {
24760 return;
24761 }
24762 this._didComplete = true;
24763 var callbacks = this._callbacks;
24764 if (callbacks === null) {
24765 return;
24766 }
24767 // TODO: Error handling.
24768 for (var i = 0; i < callbacks.length; i++) {
24769 var _callback = callbacks[i];
24770 _callback();
24771 }
24772};
24773
24774function ReactWork() {
24775 this._callbacks = null;
24776 this._didCommit = false;
24777 // TODO: Avoid need to bind by replacing callbacks in the update queue with
24778 // list of Work objects.
24779 this._onCommit = this._onCommit.bind(this);
24780}
24781ReactWork.prototype.then = function (onCommit) {
24782 if (this._didCommit) {
24783 onCommit();
24784 return;
24785 }
24786 var callbacks = this._callbacks;
24787 if (callbacks === null) {
24788 callbacks = this._callbacks = [];
24789 }
24790 callbacks.push(onCommit);
24791};
24792ReactWork.prototype._onCommit = function () {
24793 if (this._didCommit) {
24794 return;
24795 }
24796 this._didCommit = true;
24797 var callbacks = this._callbacks;
24798 if (callbacks === null) {
24799 return;
24800 }
24801 // TODO: Error handling.
24802 for (var i = 0; i < callbacks.length; i++) {
24803 var _callback2 = callbacks[i];
24804 (function () {
24805 if (!(typeof _callback2 === 'function')) {
24806 {
24807 throw ReactError(Error('Invalid argument passed as callback. Expected a function. Instead received: ' + _callback2));
24808 }
24809 }
24810 })();
24811 _callback2();
24812 }
24813};
24814
24815function ReactSyncRoot(container, tag, hydrate) {
24816 // Tag is either LegacyRoot or Concurrent Root
24817 var root = createContainer(container, tag, hydrate);
24818 this._internalRoot = root;
24819}
24820
24821function ReactRoot(container, hydrate) {
24822 var root = createContainer(container, ConcurrentRoot, hydrate);
24823 this._internalRoot = root;
24824}
24825
24826ReactRoot.prototype.render = ReactSyncRoot.prototype.render = function (children, callback) {
24827 var root = this._internalRoot;
24828 var work = new ReactWork();
24829 callback = callback === undefined ? null : callback;
24830 {
24831 warnOnInvalidCallback(callback, 'render');
24832 }
24833 if (callback !== null) {
24834 work.then(callback);
24835 }
24836 updateContainer(children, root, null, work._onCommit);
24837 return work;
24838};
24839
24840ReactRoot.prototype.unmount = ReactSyncRoot.prototype.unmount = function (callback) {
24841 var root = this._internalRoot;
24842 var work = new ReactWork();
24843 callback = callback === undefined ? null : callback;
24844 {
24845 warnOnInvalidCallback(callback, 'render');
24846 }
24847 if (callback !== null) {
24848 work.then(callback);
24849 }
24850 updateContainer(null, root, null, work._onCommit);
24851 return work;
24852};
24853
24854// Sync roots cannot create batches. Only concurrent ones.
24855ReactRoot.prototype.createBatch = function () {
24856 var batch = new ReactBatch(this);
24857 var expirationTime = batch._expirationTime;
24858
24859 var internalRoot = this._internalRoot;
24860 var firstBatch = internalRoot.firstBatch;
24861 if (firstBatch === null) {
24862 internalRoot.firstBatch = batch;
24863 batch._next = null;
24864 } else {
24865 // Insert sorted by expiration time then insertion order
24866 var insertAfter = null;
24867 var insertBefore = firstBatch;
24868 while (insertBefore !== null && insertBefore._expirationTime >= expirationTime) {
24869 insertAfter = insertBefore;
24870 insertBefore = insertBefore._next;
24871 }
24872 batch._next = insertBefore;
24873 if (insertAfter !== null) {
24874 insertAfter._next = batch;
24875 }
24876 }
24877
24878 return batch;
24879};
24880
24881/**
24882 * True if the supplied DOM node is a valid node element.
24883 *
24884 * @param {?DOMElement} node The candidate DOM node.
24885 * @return {boolean} True if the DOM is a valid DOM node.
24886 * @internal
24887 */
24888function isValidContainer(node) {
24889 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 '));
24890}
24891
24892function getReactRootElementInContainer(container) {
24893 if (!container) {
24894 return null;
24895 }
24896
24897 if (container.nodeType === DOCUMENT_NODE) {
24898 return container.documentElement;
24899 } else {
24900 return container.firstChild;
24901 }
24902}
24903
24904function shouldHydrateDueToLegacyHeuristic(container) {
24905 var rootElement = getReactRootElementInContainer(container);
24906 return !!(rootElement && rootElement.nodeType === ELEMENT_NODE && rootElement.hasAttribute(ROOT_ATTRIBUTE_NAME));
24907}
24908
24909setBatchingImplementation(batchedUpdates$1, discreteUpdates$1, flushDiscreteUpdates, batchedEventUpdates$1);
24910
24911var warnedAboutHydrateAPI = false;
24912
24913function legacyCreateRootFromDOMContainer(container, forceHydrate) {
24914 var shouldHydrate = forceHydrate || shouldHydrateDueToLegacyHeuristic(container);
24915 // First clear any existing content.
24916 if (!shouldHydrate) {
24917 var warned = false;
24918 var rootSibling = void 0;
24919 while (rootSibling = container.lastChild) {
24920 {
24921 if (!warned && rootSibling.nodeType === ELEMENT_NODE && rootSibling.hasAttribute(ROOT_ATTRIBUTE_NAME)) {
24922 warned = true;
24923 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.');
24924 }
24925 }
24926 container.removeChild(rootSibling);
24927 }
24928 }
24929 {
24930 if (shouldHydrate && !forceHydrate && !warnedAboutHydrateAPI) {
24931 warnedAboutHydrateAPI = true;
24932 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.');
24933 }
24934 }
24935
24936 // Legacy roots are not batched.
24937 return new ReactSyncRoot(container, LegacyRoot, shouldHydrate);
24938}
24939
24940function legacyRenderSubtreeIntoContainer(parentComponent, children, container, forceHydrate, callback) {
24941 {
24942 topLevelUpdateWarnings(container);
24943 warnOnInvalidCallback(callback === undefined ? null : callback, 'render');
24944 }
24945
24946 // TODO: Without `any` type, Flow says "Property cannot be accessed on any
24947 // member of intersection type." Whyyyyyy.
24948 var root = container._reactRootContainer;
24949 var fiberRoot = void 0;
24950 if (!root) {
24951 // Initial mount
24952 root = container._reactRootContainer = legacyCreateRootFromDOMContainer(container, forceHydrate);
24953 fiberRoot = root._internalRoot;
24954 if (typeof callback === 'function') {
24955 var originalCallback = callback;
24956 callback = function () {
24957 var instance = getPublicRootInstance(fiberRoot);
24958 originalCallback.call(instance);
24959 };
24960 }
24961 // Initial mount should not be batched.
24962 unbatchedUpdates(function () {
24963 updateContainer(children, fiberRoot, parentComponent, callback);
24964 });
24965 } else {
24966 fiberRoot = root._internalRoot;
24967 if (typeof callback === 'function') {
24968 var _originalCallback = callback;
24969 callback = function () {
24970 var instance = getPublicRootInstance(fiberRoot);
24971 _originalCallback.call(instance);
24972 };
24973 }
24974 // Update
24975 updateContainer(children, fiberRoot, parentComponent, callback);
24976 }
24977 return getPublicRootInstance(fiberRoot);
24978}
24979
24980function createPortal$$1(children, container) {
24981 var key = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
24982
24983 (function () {
24984 if (!isValidContainer(container)) {
24985 {
24986 throw ReactError(Error('Target container is not a DOM element.'));
24987 }
24988 }
24989 })();
24990 // TODO: pass ReactDOM portal implementation as third argument
24991 return createPortal$1(children, container, null, key);
24992}
24993
24994var ReactDOM = {
24995 createPortal: createPortal$$1,
24996
24997 findDOMNode: function (componentOrElement) {
24998 {
24999 var owner = ReactCurrentOwner.current;
25000 if (owner !== null && owner.stateNode !== null) {
25001 var warnedAboutRefsInRender = owner.stateNode._warnedAboutRefsInRender;
25002 !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;
25003 owner.stateNode._warnedAboutRefsInRender = true;
25004 }
25005 }
25006 if (componentOrElement == null) {
25007 return null;
25008 }
25009 if (componentOrElement.nodeType === ELEMENT_NODE) {
25010 return componentOrElement;
25011 }
25012 {
25013 return findHostInstanceWithWarning(componentOrElement, 'findDOMNode');
25014 }
25015 return findHostInstance(componentOrElement);
25016 },
25017 hydrate: function (element, container, callback) {
25018 (function () {
25019 if (!isValidContainer(container)) {
25020 {
25021 throw ReactError(Error('Target container is not a DOM element.'));
25022 }
25023 }
25024 })();
25025 {
25026 !!container._reactHasBeenPassedToCreateRootDEV ? warningWithoutStack$1(false, 'You are calling ReactDOM.hydrate() on a container that was previously ' + 'passed to ReactDOM.%s(). This is not supported. ' + 'Did you mean to call createRoot(container, {hydrate: true}).render(element)?', enableStableConcurrentModeAPIs ? 'createRoot' : 'unstable_createRoot') : void 0;
25027 }
25028 // TODO: throw or warn if we couldn't hydrate?
25029 return legacyRenderSubtreeIntoContainer(null, element, container, true, callback);
25030 },
25031 render: function (element, container, callback) {
25032 (function () {
25033 if (!isValidContainer(container)) {
25034 {
25035 throw ReactError(Error('Target container is not a DOM element.'));
25036 }
25037 }
25038 })();
25039 {
25040 !!container._reactHasBeenPassedToCreateRootDEV ? warningWithoutStack$1(false, 'You are calling ReactDOM.render() on a container that was previously ' + 'passed to ReactDOM.%s(). This is not supported. ' + 'Did you mean to call root.render(element)?', enableStableConcurrentModeAPIs ? 'createRoot' : 'unstable_createRoot') : void 0;
25041 }
25042 return legacyRenderSubtreeIntoContainer(null, element, container, false, callback);
25043 },
25044 unstable_renderSubtreeIntoContainer: function (parentComponent, element, containerNode, callback) {
25045 (function () {
25046 if (!isValidContainer(containerNode)) {
25047 {
25048 throw ReactError(Error('Target container is not a DOM element.'));
25049 }
25050 }
25051 })();
25052 (function () {
25053 if (!(parentComponent != null && has(parentComponent))) {
25054 {
25055 throw ReactError(Error('parentComponent must be a valid React Component'));
25056 }
25057 }
25058 })();
25059 return legacyRenderSubtreeIntoContainer(parentComponent, element, containerNode, false, callback);
25060 },
25061 unmountComponentAtNode: function (container) {
25062 (function () {
25063 if (!isValidContainer(container)) {
25064 {
25065 throw ReactError(Error('unmountComponentAtNode(...): Target container is not a DOM element.'));
25066 }
25067 }
25068 })();
25069
25070 {
25071 !!container._reactHasBeenPassedToCreateRootDEV ? warningWithoutStack$1(false, 'You are calling ReactDOM.unmountComponentAtNode() on a container that was previously ' + 'passed to ReactDOM.%s(). This is not supported. Did you mean to call root.unmount()?', enableStableConcurrentModeAPIs ? 'createRoot' : 'unstable_createRoot') : void 0;
25072 }
25073
25074 if (container._reactRootContainer) {
25075 {
25076 var rootEl = getReactRootElementInContainer(container);
25077 var renderedByDifferentReact = rootEl && !getInstanceFromNode$1(rootEl);
25078 !!renderedByDifferentReact ? warningWithoutStack$1(false, "unmountComponentAtNode(): The node you're attempting to unmount " + 'was rendered by another copy of React.') : void 0;
25079 }
25080
25081 // Unmount should not be batched.
25082 unbatchedUpdates(function () {
25083 legacyRenderSubtreeIntoContainer(null, null, container, false, function () {
25084 container._reactRootContainer = null;
25085 });
25086 });
25087 // If you call unmountComponentAtNode twice in quick succession, you'll
25088 // get `true` twice. That's probably fine?
25089 return true;
25090 } else {
25091 {
25092 var _rootEl = getReactRootElementInContainer(container);
25093 var hasNonRootReactChild = !!(_rootEl && getInstanceFromNode$1(_rootEl));
25094
25095 // Check if the container itself is a React root node.
25096 var isContainerReactRoot = container.nodeType === ELEMENT_NODE && isValidContainer(container.parentNode) && !!container.parentNode._reactRootContainer;
25097
25098 !!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;
25099 }
25100
25101 return false;
25102 }
25103 },
25104
25105
25106 // Temporary alias since we already shipped React 16 RC with it.
25107 // TODO: remove in React 17.
25108 unstable_createPortal: function () {
25109 if (!didWarnAboutUnstableCreatePortal) {
25110 didWarnAboutUnstableCreatePortal = true;
25111 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.');
25112 }
25113 return createPortal$$1.apply(undefined, arguments);
25114 },
25115
25116
25117 unstable_batchedUpdates: batchedUpdates$1,
25118
25119 // TODO remove this legacy method, unstable_discreteUpdates replaces it
25120 unstable_interactiveUpdates: function (fn, a, b, c) {
25121 flushDiscreteUpdates();
25122 return discreteUpdates$1(fn, a, b, c);
25123 },
25124
25125 unstable_discreteUpdates: discreteUpdates$1,
25126 unstable_flushDiscreteUpdates: flushDiscreteUpdates,
25127
25128 flushSync: flushSync,
25129
25130 unstable_createRoot: createRoot,
25131 unstable_createSyncRoot: createSyncRoot,
25132 unstable_flushControlled: flushControlled,
25133
25134 __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED: {
25135 // Keep in sync with ReactDOMUnstableNativeDependencies.js
25136 // ReactTestUtils.js, and ReactTestUtilsAct.js. This is an array for better minification.
25137 Events: [getInstanceFromNode$1, getNodeFromInstance$1, getFiberCurrentPropsFromNode$1, injection.injectEventPluginsByName, eventNameDispatchConfigs, accumulateTwoPhaseDispatches, accumulateDirectDispatches, enqueueStateRestore, restoreStateIfNeeded, dispatchEvent, runEventsInBatch, flushPassiveEffects, IsThisRendererActing]
25138 }
25139};
25140
25141function createRoot(container, options) {
25142 var functionName = enableStableConcurrentModeAPIs ? 'createRoot' : 'unstable_createRoot';
25143 (function () {
25144 if (!isValidContainer(container)) {
25145 {
25146 throw ReactError(Error(functionName + '(...): Target container is not a DOM element.'));
25147 }
25148 }
25149 })();
25150 warnIfReactDOMContainerInDEV(container);
25151 var hydrate = options != null && options.hydrate === true;
25152 return new ReactRoot(container, hydrate);
25153}
25154
25155function createSyncRoot(container, options) {
25156 var functionName = enableStableConcurrentModeAPIs ? 'createRoot' : 'unstable_createRoot';
25157 (function () {
25158 if (!isValidContainer(container)) {
25159 {
25160 throw ReactError(Error(functionName + '(...): Target container is not a DOM element.'));
25161 }
25162 }
25163 })();
25164 warnIfReactDOMContainerInDEV(container);
25165 var hydrate = options != null && options.hydrate === true;
25166 return new ReactSyncRoot(container, BatchedRoot, hydrate);
25167}
25168
25169function warnIfReactDOMContainerInDEV(container) {
25170 {
25171 !!container._reactRootContainer ? warningWithoutStack$1(false, 'You are calling ReactDOM.%s() on a container that was previously ' + 'passed to ReactDOM.render(). This is not supported.', enableStableConcurrentModeAPIs ? 'createRoot' : 'unstable_createRoot') : void 0;
25172 container._reactHasBeenPassedToCreateRootDEV = true;
25173 }
25174}
25175
25176if (enableStableConcurrentModeAPIs) {
25177 ReactDOM.createRoot = createRoot;
25178 ReactDOM.createSyncRoot = createSyncRoot;
25179}
25180
25181var foundDevTools = injectIntoDevTools({
25182 findFiberByHostInstance: getClosestInstanceFromNode,
25183 bundleType: 1,
25184 version: ReactVersion,
25185 rendererPackageName: 'react-dom'
25186});
25187
25188{
25189 if (!foundDevTools && canUseDOM && window.top === window.self) {
25190 // If we're in Chrome or Firefox, provide a download link if not installed.
25191 if (navigator.userAgent.indexOf('Chrome') > -1 && navigator.userAgent.indexOf('Edge') === -1 || navigator.userAgent.indexOf('Firefox') > -1) {
25192 var protocol = window.location.protocol;
25193 // Don't warn in exotic cases like chrome-extension://.
25194 if (/^(https?|file):$/.test(protocol)) {
25195 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');
25196 }
25197 }
25198 }
25199}
25200
25201
25202
25203var ReactDOM$2 = Object.freeze({
25204 default: ReactDOM
25205});
25206
25207var ReactDOM$3 = ( ReactDOM$2 && ReactDOM ) || ReactDOM$2;
25208
25209// TODO: decide on the top-level export form.
25210// This is hacky but makes it work with both Rollup and Jest.
25211var reactDom = ReactDOM$3.default || ReactDOM$3;
25212
25213module.exports = reactDom;
25214 })();
25215}