UNPKG

907 kBJavaScriptView Raw
1/** @license React v16.13.0
2 * react-dom.development.js
3 *
4 * Copyright (c) Facebook, Inc. and its affiliates.
5 *
6 * This source code is licensed under the MIT license found in the
7 * LICENSE file in the root directory of this source tree.
8 */
9
10'use strict';
11
12(function (global, factory) {
13 typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('react')) :
14 typeof define === 'function' && define.amd ? define(['exports', 'react'], factory) :
15 (global = global || self, factory(global.ReactDOM = {}, global.React));
16}(this, (function (exports, React) { 'use strict';
17
18 var ReactSharedInternals = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED; // Prevent newer renderers from RTE when used with older react package versions.
19 // Current owner and dispatcher used to share the same ref,
20 // but PR #14548 split them out to better support the react-debug-tools package.
21
22 if (!ReactSharedInternals.hasOwnProperty('ReactCurrentDispatcher')) {
23 ReactSharedInternals.ReactCurrentDispatcher = {
24 current: null
25 };
26 }
27
28 if (!ReactSharedInternals.hasOwnProperty('ReactCurrentBatchConfig')) {
29 ReactSharedInternals.ReactCurrentBatchConfig = {
30 suspense: null
31 };
32 }
33
34 // by calls to these methods by a Babel plugin.
35 //
36 // In PROD (or in packages without access to React internals),
37 // they are left as they are instead.
38
39 function warn(format) {
40 {
41 for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
42 args[_key - 1] = arguments[_key];
43 }
44
45 printWarning('warn', format, args);
46 }
47 }
48 function error(format) {
49 {
50 for (var _len2 = arguments.length, args = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {
51 args[_key2 - 1] = arguments[_key2];
52 }
53
54 printWarning('error', format, args);
55 }
56 }
57
58 function printWarning(level, format, args) {
59 // When changing this logic, you might want to also
60 // update consoleWithStackDev.www.js as well.
61 {
62 var hasExistingStack = args.length > 0 && typeof args[args.length - 1] === 'string' && args[args.length - 1].indexOf('\n in') === 0;
63
64 if (!hasExistingStack) {
65 var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame;
66 var stack = ReactDebugCurrentFrame.getStackAddendum();
67
68 if (stack !== '') {
69 format += '%s';
70 args = args.concat([stack]);
71 }
72 }
73
74 var argsWithFormat = args.map(function (item) {
75 return '' + item;
76 }); // Careful: RN currently depends on this prefix
77
78 argsWithFormat.unshift('Warning: ' + format); // We intentionally don't use spread (or .apply) directly because it
79 // breaks IE9: https://github.com/facebook/react/issues/13610
80 // eslint-disable-next-line react-internal/no-production-logging
81
82 Function.prototype.apply.call(console[level], console, argsWithFormat);
83
84 try {
85 // --- Welcome to debugging React ---
86 // This error was thrown as a convenience so that you can use this stack
87 // to find the callsite that caused this warning to fire.
88 var argIndex = 0;
89 var message = 'Warning: ' + format.replace(/%s/g, function () {
90 return args[argIndex++];
91 });
92 throw new Error(message);
93 } catch (x) {}
94 }
95 }
96
97 if (!React) {
98 {
99 throw Error( "ReactDOM was loaded before React. Make sure you load the React package before loading ReactDOM." );
100 }
101 }
102
103 var invokeGuardedCallbackImpl = function (name, func, context, a, b, c, d, e, f) {
104 var funcArgs = Array.prototype.slice.call(arguments, 3);
105
106 try {
107 func.apply(context, funcArgs);
108 } catch (error) {
109 this.onError(error);
110 }
111 };
112
113 {
114 // In DEV mode, we swap out invokeGuardedCallback for a special version
115 // that plays more nicely with the browser's DevTools. The idea is to preserve
116 // "Pause on exceptions" behavior. Because React wraps all user-provided
117 // functions in invokeGuardedCallback, and the production version of
118 // invokeGuardedCallback uses a try-catch, all user exceptions are treated
119 // like caught exceptions, and the DevTools won't pause unless the developer
120 // takes the extra step of enabling pause on caught exceptions. This is
121 // unintuitive, though, because even though React has caught the error, from
122 // the developer's perspective, the error is uncaught.
123 //
124 // To preserve the expected "Pause on exceptions" behavior, we don't use a
125 // try-catch in DEV. Instead, we synchronously dispatch a fake event to a fake
126 // DOM node, and call the user-provided callback from inside an event handler
127 // for that fake event. If the callback throws, the error is "captured" using
128 // a global event handler. But because the error happens in a different
129 // event loop context, it does not interrupt the normal program flow.
130 // Effectively, this gives us try-catch behavior without actually using
131 // try-catch. Neat!
132 // Check that the browser supports the APIs we need to implement our special
133 // DEV version of invokeGuardedCallback
134 if (typeof window !== 'undefined' && typeof window.dispatchEvent === 'function' && typeof document !== 'undefined' && typeof document.createEvent === 'function') {
135 var fakeNode = document.createElement('react');
136
137 var invokeGuardedCallbackDev = function (name, func, context, a, b, c, d, e, f) {
138 // If document doesn't exist we know for sure we will crash in this method
139 // when we call document.createEvent(). However this can cause confusing
140 // errors: https://github.com/facebookincubator/create-react-app/issues/3482
141 // So we preemptively throw with a better message instead.
142 if (!(typeof document !== 'undefined')) {
143 {
144 throw 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." );
145 }
146 }
147
148 var evt = document.createEvent('Event'); // Keeps track of whether the user-provided callback threw an error. We
149 // set this to true at the beginning, then set it to false right after
150 // calling the function. If the function errors, `didError` will never be
151 // set to false. This strategy works even if the browser is flaky and
152 // fails to call our global error handler, because it doesn't rely on
153 // the error event at all.
154
155 var didError = true; // Keeps track of the value of window.event so that we can reset it
156 // during the callback to let user code access window.event in the
157 // browsers that support it.
158
159 var windowEvent = window.event; // Keeps track of the descriptor of window.event to restore it after event
160 // dispatching: https://github.com/facebook/react/issues/13688
161
162 var windowEventDescriptor = Object.getOwnPropertyDescriptor(window, 'event'); // Create an event handler for our fake event. We will synchronously
163 // dispatch our fake event using `dispatchEvent`. Inside the handler, we
164 // call the user-provided callback.
165
166 var funcArgs = Array.prototype.slice.call(arguments, 3);
167
168 function callCallback() {
169 // We immediately remove the callback from event listeners so that
170 // nested `invokeGuardedCallback` calls do not clash. Otherwise, a
171 // nested call would trigger the fake event handlers of any call higher
172 // in the stack.
173 fakeNode.removeEventListener(evtType, callCallback, false); // We check for window.hasOwnProperty('event') to prevent the
174 // window.event assignment in both IE <= 10 as they throw an error
175 // "Member not found" in strict mode, and in Firefox which does not
176 // support window.event.
177
178 if (typeof window.event !== 'undefined' && window.hasOwnProperty('event')) {
179 window.event = windowEvent;
180 }
181
182 func.apply(context, funcArgs);
183 didError = false;
184 } // Create a global error event handler. We use this to capture the value
185 // that was thrown. It's possible that this error handler will fire more
186 // than once; for example, if non-React code also calls `dispatchEvent`
187 // and a handler for that event throws. We should be resilient to most of
188 // those cases. Even if our error event handler fires more than once, the
189 // last error event is always used. If the callback actually does error,
190 // we know that the last error event is the correct one, because it's not
191 // possible for anything else to have happened in between our callback
192 // erroring and the code that follows the `dispatchEvent` call below. If
193 // the callback doesn't error, but the error event was fired, we know to
194 // ignore it because `didError` will be false, as described above.
195
196
197 var error; // Use this to track whether the error event is ever called.
198
199 var didSetError = false;
200 var isCrossOriginError = false;
201
202 function handleWindowError(event) {
203 error = event.error;
204 didSetError = true;
205
206 if (error === null && event.colno === 0 && event.lineno === 0) {
207 isCrossOriginError = true;
208 }
209
210 if (event.defaultPrevented) {
211 // Some other error handler has prevented default.
212 // Browsers silence the error report if this happens.
213 // We'll remember this to later decide whether to log it or not.
214 if (error != null && typeof error === 'object') {
215 try {
216 error._suppressLogging = true;
217 } catch (inner) {// Ignore.
218 }
219 }
220 }
221 } // Create a fake event type.
222
223
224 var evtType = "react-" + (name ? name : 'invokeguardedcallback'); // Attach our event handlers
225
226 window.addEventListener('error', handleWindowError);
227 fakeNode.addEventListener(evtType, callCallback, false); // Synchronously dispatch our fake event. If the user-provided function
228 // errors, it will trigger our global error handler.
229
230 evt.initEvent(evtType, false, false);
231 fakeNode.dispatchEvent(evt);
232
233 if (windowEventDescriptor) {
234 Object.defineProperty(window, 'event', windowEventDescriptor);
235 }
236
237 if (didError) {
238 if (!didSetError) {
239 // The callback errored, but the error event never fired.
240 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.');
241 } else if (isCrossOriginError) {
242 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.');
243 }
244
245 this.onError(error);
246 } // Remove our event listeners
247
248
249 window.removeEventListener('error', handleWindowError);
250 };
251
252 invokeGuardedCallbackImpl = invokeGuardedCallbackDev;
253 }
254 }
255
256 var invokeGuardedCallbackImpl$1 = invokeGuardedCallbackImpl;
257
258 var hasError = false;
259 var caughtError = null; // Used by event system to capture/rethrow the first error.
260
261 var hasRethrowError = false;
262 var rethrowError = null;
263 var reporter = {
264 onError: function (error) {
265 hasError = true;
266 caughtError = error;
267 }
268 };
269 /**
270 * Call a function while guarding against errors that happens within it.
271 * Returns an error if it throws, otherwise null.
272 *
273 * In production, this is implemented using a try-catch. The reason we don't
274 * use a try-catch directly is so that we can swap out a different
275 * implementation in DEV mode.
276 *
277 * @param {String} name of the guard to use for logging or debugging
278 * @param {Function} func The function to invoke
279 * @param {*} context The context to use when calling the function
280 * @param {...*} args Arguments for function
281 */
282
283 function invokeGuardedCallback(name, func, context, a, b, c, d, e, f) {
284 hasError = false;
285 caughtError = null;
286 invokeGuardedCallbackImpl$1.apply(reporter, arguments);
287 }
288 /**
289 * Same as invokeGuardedCallback, but instead of returning an error, it stores
290 * it in a global so it can be rethrown by `rethrowCaughtError` later.
291 * TODO: See if caughtError and rethrowError can be unified.
292 *
293 * @param {String} name of the guard to use for logging or debugging
294 * @param {Function} func The function to invoke
295 * @param {*} context The context to use when calling the function
296 * @param {...*} args Arguments for function
297 */
298
299 function invokeGuardedCallbackAndCatchFirstError(name, func, context, a, b, c, d, e, f) {
300 invokeGuardedCallback.apply(this, arguments);
301
302 if (hasError) {
303 var error = clearCaughtError();
304
305 if (!hasRethrowError) {
306 hasRethrowError = true;
307 rethrowError = error;
308 }
309 }
310 }
311 /**
312 * During execution of guarded functions we will capture the first error which
313 * we will rethrow to be handled by the top level error handler.
314 */
315
316 function rethrowCaughtError() {
317 if (hasRethrowError) {
318 var error = rethrowError;
319 hasRethrowError = false;
320 rethrowError = null;
321 throw error;
322 }
323 }
324 function hasCaughtError() {
325 return hasError;
326 }
327 function clearCaughtError() {
328 if (hasError) {
329 var error = caughtError;
330 hasError = false;
331 caughtError = null;
332 return error;
333 } else {
334 {
335 {
336 throw Error( "clearCaughtError was called but no error was captured. This error is likely caused by a bug in React. Please file an issue." );
337 }
338 }
339 }
340 }
341
342 var getFiberCurrentPropsFromNode = null;
343 var getInstanceFromNode = null;
344 var getNodeFromInstance = null;
345 function setComponentTree(getFiberCurrentPropsFromNodeImpl, getInstanceFromNodeImpl, getNodeFromInstanceImpl) {
346 getFiberCurrentPropsFromNode = getFiberCurrentPropsFromNodeImpl;
347 getInstanceFromNode = getInstanceFromNodeImpl;
348 getNodeFromInstance = getNodeFromInstanceImpl;
349
350 {
351 if (!getNodeFromInstance || !getInstanceFromNode) {
352 error('EventPluginUtils.setComponentTree(...): Injected ' + 'module is missing getNodeFromInstance or getInstanceFromNode.');
353 }
354 }
355 }
356 var validateEventDispatches;
357
358 {
359 validateEventDispatches = function (event) {
360 var dispatchListeners = event._dispatchListeners;
361 var dispatchInstances = event._dispatchInstances;
362 var listenersIsArr = Array.isArray(dispatchListeners);
363 var listenersLen = listenersIsArr ? dispatchListeners.length : dispatchListeners ? 1 : 0;
364 var instancesIsArr = Array.isArray(dispatchInstances);
365 var instancesLen = instancesIsArr ? dispatchInstances.length : dispatchInstances ? 1 : 0;
366
367 if (instancesIsArr !== listenersIsArr || instancesLen !== listenersLen) {
368 error('EventPluginUtils: Invalid `event`.');
369 }
370 };
371 }
372 /**
373 * Dispatch the event to the listener.
374 * @param {SyntheticEvent} event SyntheticEvent to handle
375 * @param {function} listener Application-level callback
376 * @param {*} inst Internal component instance
377 */
378
379
380 function executeDispatch(event, listener, inst) {
381 var type = event.type || 'unknown-event';
382 event.currentTarget = getNodeFromInstance(inst);
383 invokeGuardedCallbackAndCatchFirstError(type, listener, undefined, event);
384 event.currentTarget = null;
385 }
386 /**
387 * Standard/simple iteration through an event's collected dispatches.
388 */
389
390 function executeDispatchesInOrder(event) {
391 var dispatchListeners = event._dispatchListeners;
392 var dispatchInstances = event._dispatchInstances;
393
394 {
395 validateEventDispatches(event);
396 }
397
398 if (Array.isArray(dispatchListeners)) {
399 for (var i = 0; i < dispatchListeners.length; i++) {
400 if (event.isPropagationStopped()) {
401 break;
402 } // Listeners and Instances are two parallel arrays that are always in sync.
403
404
405 executeDispatch(event, dispatchListeners[i], dispatchInstances[i]);
406 }
407 } else if (dispatchListeners) {
408 executeDispatch(event, dispatchListeners, dispatchInstances);
409 }
410
411 event._dispatchListeners = null;
412 event._dispatchInstances = null;
413 }
414
415 var FunctionComponent = 0;
416 var ClassComponent = 1;
417 var IndeterminateComponent = 2; // Before we know whether it is function or class
418
419 var HostRoot = 3; // Root of a host tree. Could be nested inside another node.
420
421 var HostPortal = 4; // A subtree. Could be an entry point to a different renderer.
422
423 var HostComponent = 5;
424 var HostText = 6;
425 var Fragment = 7;
426 var Mode = 8;
427 var ContextConsumer = 9;
428 var ContextProvider = 10;
429 var ForwardRef = 11;
430 var Profiler = 12;
431 var SuspenseComponent = 13;
432 var MemoComponent = 14;
433 var SimpleMemoComponent = 15;
434 var LazyComponent = 16;
435 var IncompleteClassComponent = 17;
436 var DehydratedFragment = 18;
437 var SuspenseListComponent = 19;
438 var FundamentalComponent = 20;
439 var ScopeComponent = 21;
440 var Block = 22;
441
442 var BEFORE_SLASH_RE = /^(.*)[\\\/]/;
443 function describeComponentFrame (name, source, ownerName) {
444 var sourceInfo = '';
445
446 if (source) {
447 var path = source.fileName;
448 var fileName = path.replace(BEFORE_SLASH_RE, '');
449
450 {
451 // In DEV, include code for a common special case:
452 // prefer "folder/index.js" instead of just "index.js".
453 if (/^index\./.test(fileName)) {
454 var match = path.match(BEFORE_SLASH_RE);
455
456 if (match) {
457 var pathBeforeSlash = match[1];
458
459 if (pathBeforeSlash) {
460 var folderName = pathBeforeSlash.replace(BEFORE_SLASH_RE, '');
461 fileName = folderName + '/' + fileName;
462 }
463 }
464 }
465 }
466
467 sourceInfo = ' (at ' + fileName + ':' + source.lineNumber + ')';
468 } else if (ownerName) {
469 sourceInfo = ' (created by ' + ownerName + ')';
470 }
471
472 return '\n in ' + (name || 'Unknown') + sourceInfo;
473 }
474
475 // The Symbol used to tag the ReactElement-like types. If there is no native Symbol
476 // nor polyfill, then a plain number is used for performance.
477 var hasSymbol = typeof Symbol === 'function' && Symbol.for;
478 var REACT_ELEMENT_TYPE = hasSymbol ? Symbol.for('react.element') : 0xeac7;
479 var REACT_PORTAL_TYPE = hasSymbol ? Symbol.for('react.portal') : 0xeaca;
480 var REACT_FRAGMENT_TYPE = hasSymbol ? Symbol.for('react.fragment') : 0xeacb;
481 var REACT_STRICT_MODE_TYPE = hasSymbol ? Symbol.for('react.strict_mode') : 0xeacc;
482 var REACT_PROFILER_TYPE = hasSymbol ? Symbol.for('react.profiler') : 0xead2;
483 var REACT_PROVIDER_TYPE = hasSymbol ? Symbol.for('react.provider') : 0xeacd;
484 var REACT_CONTEXT_TYPE = hasSymbol ? Symbol.for('react.context') : 0xeace; // TODO: We don't use AsyncMode or ConcurrentMode anymore. They were temporary
485 var REACT_CONCURRENT_MODE_TYPE = hasSymbol ? Symbol.for('react.concurrent_mode') : 0xeacf;
486 var REACT_FORWARD_REF_TYPE = hasSymbol ? Symbol.for('react.forward_ref') : 0xead0;
487 var REACT_SUSPENSE_TYPE = hasSymbol ? Symbol.for('react.suspense') : 0xead1;
488 var REACT_SUSPENSE_LIST_TYPE = hasSymbol ? Symbol.for('react.suspense_list') : 0xead8;
489 var REACT_MEMO_TYPE = hasSymbol ? Symbol.for('react.memo') : 0xead3;
490 var REACT_LAZY_TYPE = hasSymbol ? Symbol.for('react.lazy') : 0xead4;
491 var REACT_BLOCK_TYPE = hasSymbol ? Symbol.for('react.block') : 0xead9;
492 var MAYBE_ITERATOR_SYMBOL = typeof Symbol === 'function' && Symbol.iterator;
493 var FAUX_ITERATOR_SYMBOL = '@@iterator';
494 function getIteratorFn(maybeIterable) {
495 if (maybeIterable === null || typeof maybeIterable !== 'object') {
496 return null;
497 }
498
499 var maybeIterator = MAYBE_ITERATOR_SYMBOL && maybeIterable[MAYBE_ITERATOR_SYMBOL] || maybeIterable[FAUX_ITERATOR_SYMBOL];
500
501 if (typeof maybeIterator === 'function') {
502 return maybeIterator;
503 }
504
505 return null;
506 }
507
508 var Uninitialized = -1;
509 var Pending = 0;
510 var Resolved = 1;
511 var Rejected = 2;
512 function refineResolvedLazyComponent(lazyComponent) {
513 return lazyComponent._status === Resolved ? lazyComponent._result : null;
514 }
515 function initializeLazyComponentType(lazyComponent) {
516 if (lazyComponent._status === Uninitialized) {
517 lazyComponent._status = Pending;
518 var ctor = lazyComponent._ctor;
519 var thenable = ctor();
520 lazyComponent._result = thenable;
521 thenable.then(function (moduleObject) {
522 if (lazyComponent._status === Pending) {
523 var defaultExport = moduleObject.default;
524
525 {
526 if (defaultExport === undefined) {
527 error('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);
528 }
529 }
530
531 lazyComponent._status = Resolved;
532 lazyComponent._result = defaultExport;
533 }
534 }, function (error) {
535 if (lazyComponent._status === Pending) {
536 lazyComponent._status = Rejected;
537 lazyComponent._result = error;
538 }
539 });
540 }
541 }
542
543 function getWrappedName(outerType, innerType, wrapperName) {
544 var functionName = innerType.displayName || innerType.name || '';
545 return outerType.displayName || (functionName !== '' ? wrapperName + "(" + functionName + ")" : wrapperName);
546 }
547
548 function getComponentName(type) {
549 if (type == null) {
550 // Host root, text node or just invalid type.
551 return null;
552 }
553
554 {
555 if (typeof type.tag === 'number') {
556 error('Received an unexpected object in getComponentName(). ' + 'This is likely a bug in React. Please file an issue.');
557 }
558 }
559
560 if (typeof type === 'function') {
561 return type.displayName || type.name || null;
562 }
563
564 if (typeof type === 'string') {
565 return type;
566 }
567
568 switch (type) {
569 case REACT_FRAGMENT_TYPE:
570 return 'Fragment';
571
572 case REACT_PORTAL_TYPE:
573 return 'Portal';
574
575 case REACT_PROFILER_TYPE:
576 return "Profiler";
577
578 case REACT_STRICT_MODE_TYPE:
579 return 'StrictMode';
580
581 case REACT_SUSPENSE_TYPE:
582 return 'Suspense';
583
584 case REACT_SUSPENSE_LIST_TYPE:
585 return 'SuspenseList';
586 }
587
588 if (typeof type === 'object') {
589 switch (type.$$typeof) {
590 case REACT_CONTEXT_TYPE:
591 return 'Context.Consumer';
592
593 case REACT_PROVIDER_TYPE:
594 return 'Context.Provider';
595
596 case REACT_FORWARD_REF_TYPE:
597 return getWrappedName(type, type.render, 'ForwardRef');
598
599 case REACT_MEMO_TYPE:
600 return getComponentName(type.type);
601
602 case REACT_BLOCK_TYPE:
603 return getComponentName(type.render);
604
605 case REACT_LAZY_TYPE:
606 {
607 var thenable = type;
608 var resolvedThenable = refineResolvedLazyComponent(thenable);
609
610 if (resolvedThenable) {
611 return getComponentName(resolvedThenable);
612 }
613
614 break;
615 }
616 }
617 }
618
619 return null;
620 }
621
622 var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame;
623
624 function describeFiber(fiber) {
625 switch (fiber.tag) {
626 case HostRoot:
627 case HostPortal:
628 case HostText:
629 case Fragment:
630 case ContextProvider:
631 case ContextConsumer:
632 return '';
633
634 default:
635 var owner = fiber._debugOwner;
636 var source = fiber._debugSource;
637 var name = getComponentName(fiber.type);
638 var ownerName = null;
639
640 if (owner) {
641 ownerName = getComponentName(owner.type);
642 }
643
644 return describeComponentFrame(name, source, ownerName);
645 }
646 }
647
648 function getStackByFiberInDevAndProd(workInProgress) {
649 var info = '';
650 var node = workInProgress;
651
652 do {
653 info += describeFiber(node);
654 node = node.return;
655 } while (node);
656
657 return info;
658 }
659 var current = null;
660 var phase = null;
661 function getCurrentFiberOwnerNameInDevOrNull() {
662 {
663 if (current === null) {
664 return null;
665 }
666
667 var owner = current._debugOwner;
668
669 if (owner !== null && typeof owner !== 'undefined') {
670 return getComponentName(owner.type);
671 }
672 }
673
674 return null;
675 }
676 function getCurrentFiberStackInDev() {
677 {
678 if (current === null) {
679 return '';
680 } // Safe because if current fiber exists, we are reconciling,
681 // and it is guaranteed to be the work-in-progress version.
682
683
684 return getStackByFiberInDevAndProd(current);
685 }
686 }
687 function resetCurrentFiber() {
688 {
689 ReactDebugCurrentFrame.getCurrentStack = null;
690 current = null;
691 phase = null;
692 }
693 }
694 function setCurrentFiber(fiber) {
695 {
696 ReactDebugCurrentFrame.getCurrentStack = getCurrentFiberStackInDev;
697 current = fiber;
698 phase = null;
699 }
700 }
701 function setCurrentPhase(lifeCyclePhase) {
702 {
703 phase = lifeCyclePhase;
704 }
705 }
706
707 /**
708 * Injectable ordering of event plugins.
709 */
710 var eventPluginOrder = null;
711 /**
712 * Injectable mapping from names to event plugin modules.
713 */
714
715 var namesToPlugins = {};
716 /**
717 * Recomputes the plugin list using the injected plugins and plugin ordering.
718 *
719 * @private
720 */
721
722 function recomputePluginOrdering() {
723 if (!eventPluginOrder) {
724 // Wait until an `eventPluginOrder` is injected.
725 return;
726 }
727
728 for (var pluginName in namesToPlugins) {
729 var pluginModule = namesToPlugins[pluginName];
730 var pluginIndex = eventPluginOrder.indexOf(pluginName);
731
732 if (!(pluginIndex > -1)) {
733 {
734 throw Error( "EventPluginRegistry: Cannot inject event plugins that do not exist in the plugin ordering, `" + pluginName + "`." );
735 }
736 }
737
738 if (plugins[pluginIndex]) {
739 continue;
740 }
741
742 if (!pluginModule.extractEvents) {
743 {
744 throw Error( "EventPluginRegistry: Event plugins must implement an `extractEvents` method, but `" + pluginName + "` does not." );
745 }
746 }
747
748 plugins[pluginIndex] = pluginModule;
749 var publishedEvents = pluginModule.eventTypes;
750
751 for (var eventName in publishedEvents) {
752 if (!publishEventForPlugin(publishedEvents[eventName], pluginModule, eventName)) {
753 {
754 throw Error( "EventPluginRegistry: Failed to publish event `" + eventName + "` for plugin `" + pluginName + "`." );
755 }
756 }
757 }
758 }
759 }
760 /**
761 * Publishes an event so that it can be dispatched by the supplied plugin.
762 *
763 * @param {object} dispatchConfig Dispatch configuration for the event.
764 * @param {object} PluginModule Plugin publishing the event.
765 * @return {boolean} True if the event was successfully published.
766 * @private
767 */
768
769
770 function publishEventForPlugin(dispatchConfig, pluginModule, eventName) {
771 if (!!eventNameDispatchConfigs.hasOwnProperty(eventName)) {
772 {
773 throw Error( "EventPluginRegistry: More than one plugin attempted to publish the same event name, `" + eventName + "`." );
774 }
775 }
776
777 eventNameDispatchConfigs[eventName] = dispatchConfig;
778 var phasedRegistrationNames = dispatchConfig.phasedRegistrationNames;
779
780 if (phasedRegistrationNames) {
781 for (var phaseName in phasedRegistrationNames) {
782 if (phasedRegistrationNames.hasOwnProperty(phaseName)) {
783 var phasedRegistrationName = phasedRegistrationNames[phaseName];
784 publishRegistrationName(phasedRegistrationName, pluginModule, eventName);
785 }
786 }
787
788 return true;
789 } else if (dispatchConfig.registrationName) {
790 publishRegistrationName(dispatchConfig.registrationName, pluginModule, eventName);
791 return true;
792 }
793
794 return false;
795 }
796 /**
797 * Publishes a registration name that is used to identify dispatched events.
798 *
799 * @param {string} registrationName Registration name to add.
800 * @param {object} PluginModule Plugin publishing the event.
801 * @private
802 */
803
804
805 function publishRegistrationName(registrationName, pluginModule, eventName) {
806 if (!!registrationNameModules[registrationName]) {
807 {
808 throw Error( "EventPluginRegistry: More than one plugin attempted to publish the same registration name, `" + registrationName + "`." );
809 }
810 }
811
812 registrationNameModules[registrationName] = pluginModule;
813 registrationNameDependencies[registrationName] = pluginModule.eventTypes[eventName].dependencies;
814
815 {
816 var lowerCasedName = registrationName.toLowerCase();
817 possibleRegistrationNames[lowerCasedName] = registrationName;
818
819 if (registrationName === 'onDoubleClick') {
820 possibleRegistrationNames.ondblclick = registrationName;
821 }
822 }
823 }
824 /**
825 * Registers plugins so that they can extract and dispatch events.
826 */
827
828 /**
829 * Ordered list of injected plugins.
830 */
831
832
833 var plugins = [];
834 /**
835 * Mapping from event name to dispatch config
836 */
837
838 var eventNameDispatchConfigs = {};
839 /**
840 * Mapping from registration name to plugin module
841 */
842
843 var registrationNameModules = {};
844 /**
845 * Mapping from registration name to event name
846 */
847
848 var registrationNameDependencies = {};
849 /**
850 * Mapping from lowercase registration names to the properly cased version,
851 * used to warn in the case of missing event handlers. Available
852 * only in true.
853 * @type {Object}
854 */
855
856 var possibleRegistrationNames = {} ; // Trust the developer to only use possibleRegistrationNames in true
857
858 /**
859 * Injects an ordering of plugins (by plugin name). This allows the ordering
860 * to be decoupled from injection of the actual plugins so that ordering is
861 * always deterministic regardless of packaging, on-the-fly injection, etc.
862 *
863 * @param {array} InjectedEventPluginOrder
864 * @internal
865 */
866
867 function injectEventPluginOrder(injectedEventPluginOrder) {
868 if (!!eventPluginOrder) {
869 {
870 throw Error( "EventPluginRegistry: Cannot inject event plugin ordering more than once. You are likely trying to load more than one copy of React." );
871 }
872 } // Clone the ordering so it cannot be dynamically mutated.
873
874
875 eventPluginOrder = Array.prototype.slice.call(injectedEventPluginOrder);
876 recomputePluginOrdering();
877 }
878 /**
879 * Injects plugins to be used by plugin event system. The plugin names must be
880 * in the ordering injected by `injectEventPluginOrder`.
881 *
882 * Plugins can be injected as part of page initialization or on-the-fly.
883 *
884 * @param {object} injectedNamesToPlugins Map from names to plugin modules.
885 * @internal
886 */
887
888 function injectEventPluginsByName(injectedNamesToPlugins) {
889 var isOrderingDirty = false;
890
891 for (var pluginName in injectedNamesToPlugins) {
892 if (!injectedNamesToPlugins.hasOwnProperty(pluginName)) {
893 continue;
894 }
895
896 var pluginModule = injectedNamesToPlugins[pluginName];
897
898 if (!namesToPlugins.hasOwnProperty(pluginName) || namesToPlugins[pluginName] !== pluginModule) {
899 if (!!namesToPlugins[pluginName]) {
900 {
901 throw Error( "EventPluginRegistry: Cannot inject two different event plugins using the same name, `" + pluginName + "`." );
902 }
903 }
904
905 namesToPlugins[pluginName] = pluginModule;
906 isOrderingDirty = true;
907 }
908 }
909
910 if (isOrderingDirty) {
911 recomputePluginOrdering();
912 }
913 }
914
915 var canUseDOM = !!(typeof window !== 'undefined' && typeof window.document !== 'undefined' && typeof window.document.createElement !== 'undefined');
916
917 var ReactInternals = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
918 var _assign = ReactInternals.assign;
919
920 var PLUGIN_EVENT_SYSTEM = 1;
921 var IS_REPLAYED = 1 << 5;
922 var IS_FIRST_ANCESTOR = 1 << 6;
923
924 var restoreImpl = null;
925 var restoreTarget = null;
926 var restoreQueue = null;
927
928 function restoreStateOfTarget(target) {
929 // We perform this translation at the end of the event loop so that we
930 // always receive the correct fiber here
931 var internalInstance = getInstanceFromNode(target);
932
933 if (!internalInstance) {
934 // Unmounted
935 return;
936 }
937
938 if (!(typeof restoreImpl === 'function')) {
939 {
940 throw 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." );
941 }
942 }
943
944 var stateNode = internalInstance.stateNode; // Guard against Fiber being unmounted.
945
946 if (stateNode) {
947 var _props = getFiberCurrentPropsFromNode(stateNode);
948
949 restoreImpl(internalInstance.stateNode, internalInstance.type, _props);
950 }
951 }
952
953 function setRestoreImplementation(impl) {
954 restoreImpl = impl;
955 }
956 function enqueueStateRestore(target) {
957 if (restoreTarget) {
958 if (restoreQueue) {
959 restoreQueue.push(target);
960 } else {
961 restoreQueue = [target];
962 }
963 } else {
964 restoreTarget = target;
965 }
966 }
967 function needsStateRestore() {
968 return restoreTarget !== null || restoreQueue !== null;
969 }
970 function restoreStateIfNeeded() {
971 if (!restoreTarget) {
972 return;
973 }
974
975 var target = restoreTarget;
976 var queuedTargets = restoreQueue;
977 restoreTarget = null;
978 restoreQueue = null;
979 restoreStateOfTarget(target);
980
981 if (queuedTargets) {
982 for (var i = 0; i < queuedTargets.length; i++) {
983 restoreStateOfTarget(queuedTargets[i]);
984 }
985 }
986 }
987
988 var enableProfilerTimer = true; // Trace which interactions trigger each commit.
989
990 var enableDeprecatedFlareAPI = false; // Experimental Host Component support.
991
992 var enableFundamentalAPI = false; // Experimental Scope support.
993 var warnAboutStringRefs = false;
994
995 // the renderer. Such as when we're dispatching events or if third party
996 // libraries need to call batchedUpdates. Eventually, this API will go away when
997 // everything is batched by default. We'll then have a similar API to opt-out of
998 // scheduled work and instead do synchronous work.
999 // Defaults
1000
1001 var batchedUpdatesImpl = function (fn, bookkeeping) {
1002 return fn(bookkeeping);
1003 };
1004
1005 var discreteUpdatesImpl = function (fn, a, b, c, d) {
1006 return fn(a, b, c, d);
1007 };
1008
1009 var flushDiscreteUpdatesImpl = function () {};
1010
1011 var batchedEventUpdatesImpl = batchedUpdatesImpl;
1012 var isInsideEventHandler = false;
1013 var isBatchingEventUpdates = false;
1014
1015 function finishEventHandler() {
1016 // Here we wait until all updates have propagated, which is important
1017 // when using controlled components within layers:
1018 // https://github.com/facebook/react/issues/1698
1019 // Then we restore state of any controlled component.
1020 var controlledComponentsHavePendingUpdates = needsStateRestore();
1021
1022 if (controlledComponentsHavePendingUpdates) {
1023 // If a controlled event was fired, we may need to restore the state of
1024 // the DOM node back to the controlled value. This is necessary when React
1025 // bails out of the update without touching the DOM.
1026 flushDiscreteUpdatesImpl();
1027 restoreStateIfNeeded();
1028 }
1029 }
1030
1031 function batchedUpdates(fn, bookkeeping) {
1032 if (isInsideEventHandler) {
1033 // If we are currently inside another batch, we need to wait until it
1034 // fully completes before restoring state.
1035 return fn(bookkeeping);
1036 }
1037
1038 isInsideEventHandler = true;
1039
1040 try {
1041 return batchedUpdatesImpl(fn, bookkeeping);
1042 } finally {
1043 isInsideEventHandler = false;
1044 finishEventHandler();
1045 }
1046 }
1047 function batchedEventUpdates(fn, a, b) {
1048 if (isBatchingEventUpdates) {
1049 // If we are currently inside another batch, we need to wait until it
1050 // fully completes before restoring state.
1051 return fn(a, b);
1052 }
1053
1054 isBatchingEventUpdates = true;
1055
1056 try {
1057 return batchedEventUpdatesImpl(fn, a, b);
1058 } finally {
1059 isBatchingEventUpdates = false;
1060 finishEventHandler();
1061 }
1062 } // This is for the React Flare event system
1063 function discreteUpdates(fn, a, b, c, d) {
1064 var prevIsInsideEventHandler = isInsideEventHandler;
1065 isInsideEventHandler = true;
1066
1067 try {
1068 return discreteUpdatesImpl(fn, a, b, c, d);
1069 } finally {
1070 isInsideEventHandler = prevIsInsideEventHandler;
1071
1072 if (!isInsideEventHandler) {
1073 finishEventHandler();
1074 }
1075 }
1076 }
1077 function flushDiscreteUpdatesIfNeeded(timeStamp) {
1078 // event.timeStamp isn't overly reliable due to inconsistencies in
1079 // how different browsers have historically provided the time stamp.
1080 // Some browsers provide high-resolution time stamps for all events,
1081 // some provide low-resolution time stamps for all events. FF < 52
1082 // even mixes both time stamps together. Some browsers even report
1083 // negative time stamps or time stamps that are 0 (iOS9) in some cases.
1084 // Given we are only comparing two time stamps with equality (!==),
1085 // we are safe from the resolution differences. If the time stamp is 0
1086 // we bail-out of preventing the flush, which can affect semantics,
1087 // such as if an earlier flush removes or adds event listeners that
1088 // are fired in the subsequent flush. However, this is the same
1089 // behaviour as we had before this change, so the risks are low.
1090 if (!isInsideEventHandler && (!enableDeprecatedFlareAPI )) {
1091 flushDiscreteUpdatesImpl();
1092 }
1093 }
1094 function setBatchingImplementation(_batchedUpdatesImpl, _discreteUpdatesImpl, _flushDiscreteUpdatesImpl, _batchedEventUpdatesImpl) {
1095 batchedUpdatesImpl = _batchedUpdatesImpl;
1096 discreteUpdatesImpl = _discreteUpdatesImpl;
1097 flushDiscreteUpdatesImpl = _flushDiscreteUpdatesImpl;
1098 batchedEventUpdatesImpl = _batchedEventUpdatesImpl;
1099 }
1100
1101 var DiscreteEvent = 0;
1102 var UserBlockingEvent = 1;
1103 var ContinuousEvent = 2;
1104
1105 var ReactInternals$1 = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
1106 var _ReactInternals$Sched = ReactInternals$1.Scheduler,
1107 unstable_cancelCallback = _ReactInternals$Sched.unstable_cancelCallback,
1108 unstable_now = _ReactInternals$Sched.unstable_now,
1109 unstable_scheduleCallback = _ReactInternals$Sched.unstable_scheduleCallback,
1110 unstable_shouldYield = _ReactInternals$Sched.unstable_shouldYield,
1111 unstable_requestPaint = _ReactInternals$Sched.unstable_requestPaint,
1112 unstable_getFirstCallbackNode = _ReactInternals$Sched.unstable_getFirstCallbackNode,
1113 unstable_runWithPriority = _ReactInternals$Sched.unstable_runWithPriority,
1114 unstable_next = _ReactInternals$Sched.unstable_next,
1115 unstable_continueExecution = _ReactInternals$Sched.unstable_continueExecution,
1116 unstable_pauseExecution = _ReactInternals$Sched.unstable_pauseExecution,
1117 unstable_getCurrentPriorityLevel = _ReactInternals$Sched.unstable_getCurrentPriorityLevel,
1118 unstable_ImmediatePriority = _ReactInternals$Sched.unstable_ImmediatePriority,
1119 unstable_UserBlockingPriority = _ReactInternals$Sched.unstable_UserBlockingPriority,
1120 unstable_NormalPriority = _ReactInternals$Sched.unstable_NormalPriority,
1121 unstable_LowPriority = _ReactInternals$Sched.unstable_LowPriority,
1122 unstable_IdlePriority = _ReactInternals$Sched.unstable_IdlePriority,
1123 unstable_forceFrameRate = _ReactInternals$Sched.unstable_forceFrameRate,
1124 unstable_flushAllWithoutAsserting = _ReactInternals$Sched.unstable_flushAllWithoutAsserting;
1125
1126 // A reserved attribute.
1127 // It is handled by React separately and shouldn't be written to the DOM.
1128 var RESERVED = 0; // A simple string attribute.
1129 // Attributes that aren't in the whitelist are presumed to have this type.
1130
1131 var STRING = 1; // A string attribute that accepts booleans in React. In HTML, these are called
1132 // "enumerated" attributes with "true" and "false" as possible values.
1133 // When true, it should be set to a "true" string.
1134 // When false, it should be set to a "false" string.
1135
1136 var BOOLEANISH_STRING = 2; // A real boolean attribute.
1137 // When true, it should be present (set either to an empty string or its name).
1138 // When false, it should be omitted.
1139
1140 var BOOLEAN = 3; // An attribute that can be used as a flag as well as with a value.
1141 // When true, it should be present (set either to an empty string or its name).
1142 // When false, it should be omitted.
1143 // For any other value, should be present with that value.
1144
1145 var OVERLOADED_BOOLEAN = 4; // An attribute that must be numeric or parse as a numeric.
1146 // When falsy, it should be removed.
1147
1148 var NUMERIC = 5; // An attribute that must be positive numeric or parse as a positive numeric.
1149 // When falsy, it should be removed.
1150
1151 var POSITIVE_NUMERIC = 6;
1152
1153 /* eslint-disable max-len */
1154 var 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";
1155 /* eslint-enable max-len */
1156
1157 var ATTRIBUTE_NAME_CHAR = ATTRIBUTE_NAME_START_CHAR + "\\-.0-9\\u00B7\\u0300-\\u036F\\u203F-\\u2040";
1158 var ROOT_ATTRIBUTE_NAME = 'data-reactroot';
1159 var VALID_ATTRIBUTE_NAME_REGEX = new RegExp('^[' + ATTRIBUTE_NAME_START_CHAR + '][' + ATTRIBUTE_NAME_CHAR + ']*$');
1160 var hasOwnProperty = Object.prototype.hasOwnProperty;
1161 var illegalAttributeNameCache = {};
1162 var validatedAttributeNameCache = {};
1163 function isAttributeNameSafe(attributeName) {
1164 if (hasOwnProperty.call(validatedAttributeNameCache, attributeName)) {
1165 return true;
1166 }
1167
1168 if (hasOwnProperty.call(illegalAttributeNameCache, attributeName)) {
1169 return false;
1170 }
1171
1172 if (VALID_ATTRIBUTE_NAME_REGEX.test(attributeName)) {
1173 validatedAttributeNameCache[attributeName] = true;
1174 return true;
1175 }
1176
1177 illegalAttributeNameCache[attributeName] = true;
1178
1179 {
1180 error('Invalid attribute name: `%s`', attributeName);
1181 }
1182
1183 return false;
1184 }
1185 function shouldIgnoreAttribute(name, propertyInfo, isCustomComponentTag) {
1186 if (propertyInfo !== null) {
1187 return propertyInfo.type === RESERVED;
1188 }
1189
1190 if (isCustomComponentTag) {
1191 return false;
1192 }
1193
1194 if (name.length > 2 && (name[0] === 'o' || name[0] === 'O') && (name[1] === 'n' || name[1] === 'N')) {
1195 return true;
1196 }
1197
1198 return false;
1199 }
1200 function shouldRemoveAttributeWithWarning(name, value, propertyInfo, isCustomComponentTag) {
1201 if (propertyInfo !== null && propertyInfo.type === RESERVED) {
1202 return false;
1203 }
1204
1205 switch (typeof value) {
1206 case 'function': // $FlowIssue symbol is perfectly valid here
1207
1208 case 'symbol':
1209 // eslint-disable-line
1210 return true;
1211
1212 case 'boolean':
1213 {
1214 if (isCustomComponentTag) {
1215 return false;
1216 }
1217
1218 if (propertyInfo !== null) {
1219 return !propertyInfo.acceptsBooleans;
1220 } else {
1221 var prefix = name.toLowerCase().slice(0, 5);
1222 return prefix !== 'data-' && prefix !== 'aria-';
1223 }
1224 }
1225
1226 default:
1227 return false;
1228 }
1229 }
1230 function shouldRemoveAttribute(name, value, propertyInfo, isCustomComponentTag) {
1231 if (value === null || typeof value === 'undefined') {
1232 return true;
1233 }
1234
1235 if (shouldRemoveAttributeWithWarning(name, value, propertyInfo, isCustomComponentTag)) {
1236 return true;
1237 }
1238
1239 if (isCustomComponentTag) {
1240 return false;
1241 }
1242
1243 if (propertyInfo !== null) {
1244 switch (propertyInfo.type) {
1245 case BOOLEAN:
1246 return !value;
1247
1248 case OVERLOADED_BOOLEAN:
1249 return value === false;
1250
1251 case NUMERIC:
1252 return isNaN(value);
1253
1254 case POSITIVE_NUMERIC:
1255 return isNaN(value) || value < 1;
1256 }
1257 }
1258
1259 return false;
1260 }
1261 function getPropertyInfo(name) {
1262 return properties.hasOwnProperty(name) ? properties[name] : null;
1263 }
1264
1265 function PropertyInfoRecord(name, type, mustUseProperty, attributeName, attributeNamespace, sanitizeURL) {
1266 this.acceptsBooleans = type === BOOLEANISH_STRING || type === BOOLEAN || type === OVERLOADED_BOOLEAN;
1267 this.attributeName = attributeName;
1268 this.attributeNamespace = attributeNamespace;
1269 this.mustUseProperty = mustUseProperty;
1270 this.propertyName = name;
1271 this.type = type;
1272 this.sanitizeURL = sanitizeURL;
1273 } // When adding attributes to this list, be sure to also add them to
1274 // the `possibleStandardNames` module to ensure casing and incorrect
1275 // name warnings.
1276
1277
1278 var properties = {}; // These props are reserved by React. They shouldn't be written to the DOM.
1279
1280 var reservedProps = ['children', 'dangerouslySetInnerHTML', // TODO: This prevents the assignment of defaultValue to regular
1281 // elements (not just inputs). Now that ReactDOMInput assigns to the
1282 // defaultValue property -- do we need this?
1283 'defaultValue', 'defaultChecked', 'innerHTML', 'suppressContentEditableWarning', 'suppressHydrationWarning', 'style'];
1284
1285 reservedProps.forEach(function (name) {
1286 properties[name] = new PropertyInfoRecord(name, RESERVED, false, // mustUseProperty
1287 name, // attributeName
1288 null, // attributeNamespace
1289 false);
1290 }); // A few React string attributes have a different name.
1291 // This is a mapping from React prop names to the attribute names.
1292
1293 [['acceptCharset', 'accept-charset'], ['className', 'class'], ['htmlFor', 'for'], ['httpEquiv', 'http-equiv']].forEach(function (_ref) {
1294 var name = _ref[0],
1295 attributeName = _ref[1];
1296 properties[name] = new PropertyInfoRecord(name, STRING, false, // mustUseProperty
1297 attributeName, // attributeName
1298 null, // attributeNamespace
1299 false);
1300 }); // These are "enumerated" HTML attributes that accept "true" and "false".
1301 // In React, we let users pass `true` and `false` even though technically
1302 // these aren't boolean attributes (they are coerced to strings).
1303
1304 ['contentEditable', 'draggable', 'spellCheck', 'value'].forEach(function (name) {
1305 properties[name] = new PropertyInfoRecord(name, BOOLEANISH_STRING, false, // mustUseProperty
1306 name.toLowerCase(), // attributeName
1307 null, // attributeNamespace
1308 false);
1309 }); // These are "enumerated" SVG attributes that accept "true" and "false".
1310 // In React, we let users pass `true` and `false` even though technically
1311 // these aren't boolean attributes (they are coerced to strings).
1312 // Since these are SVG attributes, their attribute names are case-sensitive.
1313
1314 ['autoReverse', 'externalResourcesRequired', 'focusable', 'preserveAlpha'].forEach(function (name) {
1315 properties[name] = new PropertyInfoRecord(name, BOOLEANISH_STRING, false, // mustUseProperty
1316 name, // attributeName
1317 null, // attributeNamespace
1318 false);
1319 }); // These are HTML boolean attributes.
1320
1321 ['allowFullScreen', 'async', // Note: there is a special case that prevents it from being written to the DOM
1322 // on the client side because the browsers are inconsistent. Instead we call focus().
1323 'autoFocus', 'autoPlay', 'controls', 'default', 'defer', 'disabled', 'disablePictureInPicture', 'formNoValidate', 'hidden', 'loop', 'noModule', 'noValidate', 'open', 'playsInline', 'readOnly', 'required', 'reversed', 'scoped', 'seamless', // Microdata
1324 'itemScope'].forEach(function (name) {
1325 properties[name] = new PropertyInfoRecord(name, BOOLEAN, false, // mustUseProperty
1326 name.toLowerCase(), // attributeName
1327 null, // attributeNamespace
1328 false);
1329 }); // These are the few React props that we set as DOM properties
1330 // rather than attributes. These are all booleans.
1331
1332 ['checked', // Note: `option.selected` is not updated if `select.multiple` is
1333 // disabled with `removeAttribute`. We have special logic for handling this.
1334 'multiple', 'muted', 'selected' // NOTE: if you add a camelCased prop to this list,
1335 // you'll need to set attributeName to name.toLowerCase()
1336 // instead in the assignment below.
1337 ].forEach(function (name) {
1338 properties[name] = new PropertyInfoRecord(name, BOOLEAN, true, // mustUseProperty
1339 name, // attributeName
1340 null, // attributeNamespace
1341 false);
1342 }); // These are HTML attributes that are "overloaded booleans": they behave like
1343 // booleans, but can also accept a string value.
1344
1345 ['capture', 'download' // NOTE: if you add a camelCased prop to this list,
1346 // you'll need to set attributeName to name.toLowerCase()
1347 // instead in the assignment below.
1348 ].forEach(function (name) {
1349 properties[name] = new PropertyInfoRecord(name, OVERLOADED_BOOLEAN, false, // mustUseProperty
1350 name, // attributeName
1351 null, // attributeNamespace
1352 false);
1353 }); // These are HTML attributes that must be positive numbers.
1354
1355 ['cols', 'rows', 'size', 'span' // NOTE: if you add a camelCased prop to this list,
1356 // you'll need to set attributeName to name.toLowerCase()
1357 // instead in the assignment below.
1358 ].forEach(function (name) {
1359 properties[name] = new PropertyInfoRecord(name, POSITIVE_NUMERIC, false, // mustUseProperty
1360 name, // attributeName
1361 null, // attributeNamespace
1362 false);
1363 }); // These are HTML attributes that must be numbers.
1364
1365 ['rowSpan', 'start'].forEach(function (name) {
1366 properties[name] = new PropertyInfoRecord(name, NUMERIC, false, // mustUseProperty
1367 name.toLowerCase(), // attributeName
1368 null, // attributeNamespace
1369 false);
1370 });
1371 var CAMELIZE = /[\-\:]([a-z])/g;
1372
1373 var capitalize = function (token) {
1374 return token[1].toUpperCase();
1375 }; // This is a list of all SVG attributes that need special casing, namespacing,
1376 // or boolean value assignment. Regular attributes that just accept strings
1377 // and have the same names are omitted, just like in the HTML whitelist.
1378 // Some of these attributes can be hard to find. This list was created by
1379 // scraping the MDN documentation.
1380
1381
1382 ['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' // NOTE: if you add a camelCased prop to this list,
1383 // you'll need to set attributeName to name.toLowerCase()
1384 // instead in the assignment below.
1385 ].forEach(function (attributeName) {
1386 var name = attributeName.replace(CAMELIZE, capitalize);
1387 properties[name] = new PropertyInfoRecord(name, STRING, false, // mustUseProperty
1388 attributeName, null, // attributeNamespace
1389 false);
1390 }); // String SVG attributes with the xlink namespace.
1391
1392 ['xlink:actuate', 'xlink:arcrole', 'xlink:role', 'xlink:show', 'xlink:title', 'xlink:type' // NOTE: if you add a camelCased prop to this list,
1393 // you'll need to set attributeName to name.toLowerCase()
1394 // instead in the assignment below.
1395 ].forEach(function (attributeName) {
1396 var name = attributeName.replace(CAMELIZE, capitalize);
1397 properties[name] = new PropertyInfoRecord(name, STRING, false, // mustUseProperty
1398 attributeName, 'http://www.w3.org/1999/xlink', false);
1399 }); // String SVG attributes with the xml namespace.
1400
1401 ['xml:base', 'xml:lang', 'xml:space' // NOTE: if you add a camelCased prop to this list,
1402 // you'll need to set attributeName to name.toLowerCase()
1403 // instead in the assignment below.
1404 ].forEach(function (attributeName) {
1405 var name = attributeName.replace(CAMELIZE, capitalize);
1406 properties[name] = new PropertyInfoRecord(name, STRING, false, // mustUseProperty
1407 attributeName, 'http://www.w3.org/XML/1998/namespace', false);
1408 }); // These attribute exists both in HTML and SVG.
1409 // The attribute name is case-sensitive in SVG so we can't just use
1410 // the React name like we do for attributes that exist only in HTML.
1411
1412 ['tabIndex', 'crossOrigin'].forEach(function (attributeName) {
1413 properties[attributeName] = new PropertyInfoRecord(attributeName, STRING, false, // mustUseProperty
1414 attributeName.toLowerCase(), // attributeName
1415 null, // attributeNamespace
1416 false);
1417 }); // These attributes accept URLs. These must not allow javascript: URLS.
1418 // These will also need to accept Trusted Types object in the future.
1419
1420 var xlinkHref = 'xlinkHref';
1421 properties[xlinkHref] = new PropertyInfoRecord('xlinkHref', STRING, false, // mustUseProperty
1422 'xlink:href', 'http://www.w3.org/1999/xlink', true);
1423 ['src', 'href', 'action', 'formAction'].forEach(function (attributeName) {
1424 properties[attributeName] = new PropertyInfoRecord(attributeName, STRING, false, // mustUseProperty
1425 attributeName.toLowerCase(), // attributeName
1426 null, // attributeNamespace
1427 true);
1428 });
1429
1430 var ReactDebugCurrentFrame$1 = null;
1431
1432 {
1433 ReactDebugCurrentFrame$1 = ReactSharedInternals.ReactDebugCurrentFrame;
1434 } // A javascript: URL can contain leading C0 control or \u0020 SPACE,
1435 // and any newline or tab are filtered out as if they're not part of the URL.
1436 // https://url.spec.whatwg.org/#url-parsing
1437 // Tab or newline are defined as \r\n\t:
1438 // https://infra.spec.whatwg.org/#ascii-tab-or-newline
1439 // A C0 control is a code point in the range \u0000 NULL to \u001F
1440 // INFORMATION SEPARATOR ONE, inclusive:
1441 // https://infra.spec.whatwg.org/#c0-control-or-space
1442
1443 /* eslint-disable max-len */
1444
1445
1446 var 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;
1447 var didWarn = false;
1448
1449 function sanitizeURL(url) {
1450 {
1451 if (!didWarn && isJavaScriptProtocol.test(url)) {
1452 didWarn = true;
1453
1454 error('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));
1455 }
1456 }
1457 }
1458
1459 /**
1460 * Get the value for a property on a node. Only used in DEV for SSR validation.
1461 * The "expected" argument is used as a hint of what the expected value is.
1462 * Some properties have multiple equivalent values.
1463 */
1464 function getValueForProperty(node, name, expected, propertyInfo) {
1465 {
1466 if (propertyInfo.mustUseProperty) {
1467 var propertyName = propertyInfo.propertyName;
1468 return node[propertyName];
1469 } else {
1470 if ( propertyInfo.sanitizeURL) {
1471 // If we haven't fully disabled javascript: URLs, and if
1472 // the hydration is successful of a javascript: URL, we
1473 // still want to warn on the client.
1474 sanitizeURL('' + expected);
1475 }
1476
1477 var attributeName = propertyInfo.attributeName;
1478 var stringValue = null;
1479
1480 if (propertyInfo.type === OVERLOADED_BOOLEAN) {
1481 if (node.hasAttribute(attributeName)) {
1482 var value = node.getAttribute(attributeName);
1483
1484 if (value === '') {
1485 return true;
1486 }
1487
1488 if (shouldRemoveAttribute(name, expected, propertyInfo, false)) {
1489 return value;
1490 }
1491
1492 if (value === '' + expected) {
1493 return expected;
1494 }
1495
1496 return value;
1497 }
1498 } else if (node.hasAttribute(attributeName)) {
1499 if (shouldRemoveAttribute(name, expected, propertyInfo, false)) {
1500 // We had an attribute but shouldn't have had one, so read it
1501 // for the error message.
1502 return node.getAttribute(attributeName);
1503 }
1504
1505 if (propertyInfo.type === BOOLEAN) {
1506 // If this was a boolean, it doesn't matter what the value is
1507 // the fact that we have it is the same as the expected.
1508 return expected;
1509 } // Even if this property uses a namespace we use getAttribute
1510 // because we assume its namespaced name is the same as our config.
1511 // To use getAttributeNS we need the local name which we don't have
1512 // in our config atm.
1513
1514
1515 stringValue = node.getAttribute(attributeName);
1516 }
1517
1518 if (shouldRemoveAttribute(name, expected, propertyInfo, false)) {
1519 return stringValue === null ? expected : stringValue;
1520 } else if (stringValue === '' + expected) {
1521 return expected;
1522 } else {
1523 return stringValue;
1524 }
1525 }
1526 }
1527 }
1528 /**
1529 * Get the value for a attribute on a node. Only used in DEV for SSR validation.
1530 * The third argument is used as a hint of what the expected value is. Some
1531 * attributes have multiple equivalent values.
1532 */
1533
1534 function getValueForAttribute(node, name, expected) {
1535 {
1536 if (!isAttributeNameSafe(name)) {
1537 return;
1538 }
1539
1540 if (!node.hasAttribute(name)) {
1541 return expected === undefined ? undefined : null;
1542 }
1543
1544 var value = node.getAttribute(name);
1545
1546 if (value === '' + expected) {
1547 return expected;
1548 }
1549
1550 return value;
1551 }
1552 }
1553 /**
1554 * Sets the value for a property on a node.
1555 *
1556 * @param {DOMElement} node
1557 * @param {string} name
1558 * @param {*} value
1559 */
1560
1561 function setValueForProperty(node, name, value, isCustomComponentTag) {
1562 var propertyInfo = getPropertyInfo(name);
1563
1564 if (shouldIgnoreAttribute(name, propertyInfo, isCustomComponentTag)) {
1565 return;
1566 }
1567
1568 if (shouldRemoveAttribute(name, value, propertyInfo, isCustomComponentTag)) {
1569 value = null;
1570 } // If the prop isn't in the special list, treat it as a simple attribute.
1571
1572
1573 if (isCustomComponentTag || propertyInfo === null) {
1574 if (isAttributeNameSafe(name)) {
1575 var _attributeName = name;
1576
1577 if (value === null) {
1578 node.removeAttribute(_attributeName);
1579 } else {
1580 node.setAttribute(_attributeName, '' + value);
1581 }
1582 }
1583
1584 return;
1585 }
1586
1587 var mustUseProperty = propertyInfo.mustUseProperty;
1588
1589 if (mustUseProperty) {
1590 var propertyName = propertyInfo.propertyName;
1591
1592 if (value === null) {
1593 var type = propertyInfo.type;
1594 node[propertyName] = type === BOOLEAN ? false : '';
1595 } else {
1596 // Contrary to `setAttribute`, object properties are properly
1597 // `toString`ed by IE8/9.
1598 node[propertyName] = value;
1599 }
1600
1601 return;
1602 } // The rest are treated as attributes with special cases.
1603
1604
1605 var attributeName = propertyInfo.attributeName,
1606 attributeNamespace = propertyInfo.attributeNamespace;
1607
1608 if (value === null) {
1609 node.removeAttribute(attributeName);
1610 } else {
1611 var _type = propertyInfo.type;
1612 var attributeValue;
1613
1614 if (_type === BOOLEAN || _type === OVERLOADED_BOOLEAN && value === true) {
1615 // If attribute type is boolean, we know for sure it won't be an execution sink
1616 // and we won't require Trusted Type here.
1617 attributeValue = '';
1618 } else {
1619 // `setAttribute` with objects becomes only `[object]` in IE8/9,
1620 // ('' + value) makes it output the correct toString()-value.
1621 {
1622 attributeValue = '' + value;
1623 }
1624
1625 if (propertyInfo.sanitizeURL) {
1626 sanitizeURL(attributeValue.toString());
1627 }
1628 }
1629
1630 if (attributeNamespace) {
1631 node.setAttributeNS(attributeNamespace, attributeName, attributeValue);
1632 } else {
1633 node.setAttribute(attributeName, attributeValue);
1634 }
1635 }
1636 }
1637
1638 // Flow does not allow string concatenation of most non-string types. To work
1639 // around this limitation, we use an opaque type that can only be obtained by
1640 // passing the value through getToStringValue first.
1641 function toString(value) {
1642 return '' + value;
1643 }
1644 function getToStringValue(value) {
1645 switch (typeof value) {
1646 case 'boolean':
1647 case 'number':
1648 case 'object':
1649 case 'string':
1650 case 'undefined':
1651 return value;
1652
1653 default:
1654 // function, symbol are assigned as empty strings
1655 return '';
1656 }
1657 }
1658
1659 /**
1660 * Copyright (c) 2013-present, Facebook, Inc.
1661 *
1662 * This source code is licensed under the MIT license found in the
1663 * LICENSE file in the root directory of this source tree.
1664 */
1665
1666 var ReactPropTypesSecret = 'SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED';
1667
1668 var ReactPropTypesSecret_1 = ReactPropTypesSecret;
1669
1670 var printWarning$1 = function() {};
1671
1672 {
1673 var ReactPropTypesSecret$1 = ReactPropTypesSecret_1;
1674 var loggedTypeFailures = {};
1675 var has = Function.call.bind(Object.prototype.hasOwnProperty);
1676
1677 printWarning$1 = function(text) {
1678 var message = 'Warning: ' + text;
1679 if (typeof console !== 'undefined') {
1680 console.error(message);
1681 }
1682 try {
1683 // --- Welcome to debugging React ---
1684 // This error was thrown as a convenience so that you can use this stack
1685 // to find the callsite that caused this warning to fire.
1686 throw new Error(message);
1687 } catch (x) {}
1688 };
1689 }
1690
1691 /**
1692 * Assert that the values match with the type specs.
1693 * Error messages are memorized and will only be shown once.
1694 *
1695 * @param {object} typeSpecs Map of name to a ReactPropType
1696 * @param {object} values Runtime values that need to be type-checked
1697 * @param {string} location e.g. "prop", "context", "child context"
1698 * @param {string} componentName Name of the component for error messages.
1699 * @param {?Function} getStack Returns the component stack.
1700 * @private
1701 */
1702 function checkPropTypes(typeSpecs, values, location, componentName, getStack) {
1703 {
1704 for (var typeSpecName in typeSpecs) {
1705 if (has(typeSpecs, typeSpecName)) {
1706 var error;
1707 // Prop type validation may throw. In case they do, we don't want to
1708 // fail the render phase where it didn't fail before. So we log it.
1709 // After these have been cleaned up, we'll let them throw.
1710 try {
1711 // This is intentionally an invariant that gets caught. It's the same
1712 // behavior as without this statement except with a better message.
1713 if (typeof typeSpecs[typeSpecName] !== 'function') {
1714 var err = Error(
1715 (componentName || 'React class') + ': ' + location + ' type `' + typeSpecName + '` is invalid; ' +
1716 'it must be a function, usually from the `prop-types` package, but received `' + typeof typeSpecs[typeSpecName] + '`.'
1717 );
1718 err.name = 'Invariant Violation';
1719 throw err;
1720 }
1721 error = typeSpecs[typeSpecName](values, typeSpecName, componentName, location, null, ReactPropTypesSecret$1);
1722 } catch (ex) {
1723 error = ex;
1724 }
1725 if (error && !(error instanceof Error)) {
1726 printWarning$1(
1727 (componentName || 'React class') + ': type specification of ' +
1728 location + ' `' + typeSpecName + '` is invalid; the type checker ' +
1729 'function must return `null` or an `Error` but returned a ' + typeof error + '. ' +
1730 'You may have forgotten to pass an argument to the type checker ' +
1731 'creator (arrayOf, instanceOf, objectOf, oneOf, oneOfType, and ' +
1732 'shape all require an argument).'
1733 );
1734 }
1735 if (error instanceof Error && !(error.message in loggedTypeFailures)) {
1736 // Only monitor this failure once because there tends to be a lot of the
1737 // same error.
1738 loggedTypeFailures[error.message] = true;
1739
1740 var stack = getStack ? getStack() : '';
1741
1742 printWarning$1(
1743 'Failed ' + location + ' type: ' + error.message + (stack != null ? stack : '')
1744 );
1745 }
1746 }
1747 }
1748 }
1749 }
1750
1751 /**
1752 * Resets warning cache when testing.
1753 *
1754 * @private
1755 */
1756 checkPropTypes.resetWarningCache = function() {
1757 {
1758 loggedTypeFailures = {};
1759 }
1760 };
1761
1762 var checkPropTypes_1 = checkPropTypes;
1763
1764 var ReactDebugCurrentFrame$2 = null;
1765 var ReactControlledValuePropTypes = {
1766 checkPropTypes: null
1767 };
1768
1769 {
1770 ReactDebugCurrentFrame$2 = ReactSharedInternals.ReactDebugCurrentFrame;
1771 var hasReadOnlyValue = {
1772 button: true,
1773 checkbox: true,
1774 image: true,
1775 hidden: true,
1776 radio: true,
1777 reset: true,
1778 submit: true
1779 };
1780 var propTypes = {
1781 value: function (props, propName, componentName) {
1782 if (hasReadOnlyValue[props.type] || props.onChange || props.readOnly || props.disabled || props[propName] == null || enableDeprecatedFlareAPI ) {
1783 return null;
1784 }
1785
1786 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`.');
1787 },
1788 checked: function (props, propName, componentName) {
1789 if (props.onChange || props.readOnly || props.disabled || props[propName] == null || enableDeprecatedFlareAPI ) {
1790 return null;
1791 }
1792
1793 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`.');
1794 }
1795 };
1796 /**
1797 * Provide a linked `value` attribute for controlled forms. You should not use
1798 * this outside of the ReactDOM controlled form components.
1799 */
1800
1801 ReactControlledValuePropTypes.checkPropTypes = function (tagName, props) {
1802 checkPropTypes_1(propTypes, props, 'prop', tagName, ReactDebugCurrentFrame$2.getStackAddendum);
1803 };
1804 }
1805
1806 function isCheckable(elem) {
1807 var type = elem.type;
1808 var nodeName = elem.nodeName;
1809 return nodeName && nodeName.toLowerCase() === 'input' && (type === 'checkbox' || type === 'radio');
1810 }
1811
1812 function getTracker(node) {
1813 return node._valueTracker;
1814 }
1815
1816 function detachTracker(node) {
1817 node._valueTracker = null;
1818 }
1819
1820 function getValueFromNode(node) {
1821 var value = '';
1822
1823 if (!node) {
1824 return value;
1825 }
1826
1827 if (isCheckable(node)) {
1828 value = node.checked ? 'true' : 'false';
1829 } else {
1830 value = node.value;
1831 }
1832
1833 return value;
1834 }
1835
1836 function trackValueOnNode(node) {
1837 var valueField = isCheckable(node) ? 'checked' : 'value';
1838 var descriptor = Object.getOwnPropertyDescriptor(node.constructor.prototype, valueField);
1839 var currentValue = '' + node[valueField]; // if someone has already defined a value or Safari, then bail
1840 // and don't track value will cause over reporting of changes,
1841 // but it's better then a hard failure
1842 // (needed for certain tests that spyOn input values and Safari)
1843
1844 if (node.hasOwnProperty(valueField) || typeof descriptor === 'undefined' || typeof descriptor.get !== 'function' || typeof descriptor.set !== 'function') {
1845 return;
1846 }
1847
1848 var get = descriptor.get,
1849 set = descriptor.set;
1850 Object.defineProperty(node, valueField, {
1851 configurable: true,
1852 get: function () {
1853 return get.call(this);
1854 },
1855 set: function (value) {
1856 currentValue = '' + value;
1857 set.call(this, value);
1858 }
1859 }); // We could've passed this the first time
1860 // but it triggers a bug in IE11 and Edge 14/15.
1861 // Calling defineProperty() again should be equivalent.
1862 // https://github.com/facebook/react/issues/11768
1863
1864 Object.defineProperty(node, valueField, {
1865 enumerable: descriptor.enumerable
1866 });
1867 var tracker = {
1868 getValue: function () {
1869 return currentValue;
1870 },
1871 setValue: function (value) {
1872 currentValue = '' + value;
1873 },
1874 stopTracking: function () {
1875 detachTracker(node);
1876 delete node[valueField];
1877 }
1878 };
1879 return tracker;
1880 }
1881
1882 function track(node) {
1883 if (getTracker(node)) {
1884 return;
1885 } // TODO: Once it's just Fiber we can move this to node._wrapperState
1886
1887
1888 node._valueTracker = trackValueOnNode(node);
1889 }
1890 function updateValueIfChanged(node) {
1891 if (!node) {
1892 return false;
1893 }
1894
1895 var tracker = getTracker(node); // if there is no tracker at this point it's unlikely
1896 // that trying again will succeed
1897
1898 if (!tracker) {
1899 return true;
1900 }
1901
1902 var lastValue = tracker.getValue();
1903 var nextValue = getValueFromNode(node);
1904
1905 if (nextValue !== lastValue) {
1906 tracker.setValue(nextValue);
1907 return true;
1908 }
1909
1910 return false;
1911 }
1912
1913 var didWarnValueDefaultValue = false;
1914 var didWarnCheckedDefaultChecked = false;
1915 var didWarnControlledToUncontrolled = false;
1916 var didWarnUncontrolledToControlled = false;
1917
1918 function isControlled(props) {
1919 var usesChecked = props.type === 'checkbox' || props.type === 'radio';
1920 return usesChecked ? props.checked != null : props.value != null;
1921 }
1922 /**
1923 * Implements an <input> host component that allows setting these optional
1924 * props: `checked`, `value`, `defaultChecked`, and `defaultValue`.
1925 *
1926 * If `checked` or `value` are not supplied (or null/undefined), user actions
1927 * that affect the checked state or value will trigger updates to the element.
1928 *
1929 * If they are supplied (and not null/undefined), the rendered element will not
1930 * trigger updates to the element. Instead, the props must change in order for
1931 * the rendered element to be updated.
1932 *
1933 * The rendered element will be initialized as unchecked (or `defaultChecked`)
1934 * with an empty value (or `defaultValue`).
1935 *
1936 * See http://www.w3.org/TR/2012/WD-html5-20121025/the-input-element.html
1937 */
1938
1939
1940 function getHostProps(element, props) {
1941 var node = element;
1942 var checked = props.checked;
1943
1944 var hostProps = _assign({}, props, {
1945 defaultChecked: undefined,
1946 defaultValue: undefined,
1947 value: undefined,
1948 checked: checked != null ? checked : node._wrapperState.initialChecked
1949 });
1950
1951 return hostProps;
1952 }
1953 function initWrapperState(element, props) {
1954 {
1955 ReactControlledValuePropTypes.checkPropTypes('input', props);
1956
1957 if (props.checked !== undefined && props.defaultChecked !== undefined && !didWarnCheckedDefaultChecked) {
1958 error('%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);
1959
1960 didWarnCheckedDefaultChecked = true;
1961 }
1962
1963 if (props.value !== undefined && props.defaultValue !== undefined && !didWarnValueDefaultValue) {
1964 error('%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);
1965
1966 didWarnValueDefaultValue = true;
1967 }
1968 }
1969
1970 var node = element;
1971 var defaultValue = props.defaultValue == null ? '' : props.defaultValue;
1972 node._wrapperState = {
1973 initialChecked: props.checked != null ? props.checked : props.defaultChecked,
1974 initialValue: getToStringValue(props.value != null ? props.value : defaultValue),
1975 controlled: isControlled(props)
1976 };
1977 }
1978 function updateChecked(element, props) {
1979 var node = element;
1980 var checked = props.checked;
1981
1982 if (checked != null) {
1983 setValueForProperty(node, 'checked', checked, false);
1984 }
1985 }
1986 function updateWrapper(element, props) {
1987 var node = element;
1988
1989 {
1990 var controlled = isControlled(props);
1991
1992 if (!node._wrapperState.controlled && controlled && !didWarnUncontrolledToControlled) {
1993 error('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);
1994
1995 didWarnUncontrolledToControlled = true;
1996 }
1997
1998 if (node._wrapperState.controlled && !controlled && !didWarnControlledToUncontrolled) {
1999 error('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);
2000
2001 didWarnControlledToUncontrolled = true;
2002 }
2003 }
2004
2005 updateChecked(element, props);
2006 var value = getToStringValue(props.value);
2007 var type = props.type;
2008
2009 if (value != null) {
2010 if (type === 'number') {
2011 if (value === 0 && node.value === '' || // We explicitly want to coerce to number here if possible.
2012 // eslint-disable-next-line
2013 node.value != value) {
2014 node.value = toString(value);
2015 }
2016 } else if (node.value !== toString(value)) {
2017 node.value = toString(value);
2018 }
2019 } else if (type === 'submit' || type === 'reset') {
2020 // Submit/reset inputs need the attribute removed completely to avoid
2021 // blank-text buttons.
2022 node.removeAttribute('value');
2023 return;
2024 }
2025
2026 {
2027 // When syncing the value attribute, the value comes from a cascade of
2028 // properties:
2029 // 1. The value React property
2030 // 2. The defaultValue React property
2031 // 3. Otherwise there should be no change
2032 if (props.hasOwnProperty('value')) {
2033 setDefaultValue(node, props.type, value);
2034 } else if (props.hasOwnProperty('defaultValue')) {
2035 setDefaultValue(node, props.type, getToStringValue(props.defaultValue));
2036 }
2037 }
2038
2039 {
2040 // When syncing the checked attribute, it only changes when it needs
2041 // to be removed, such as transitioning from a checkbox into a text input
2042 if (props.checked == null && props.defaultChecked != null) {
2043 node.defaultChecked = !!props.defaultChecked;
2044 }
2045 }
2046 }
2047 function postMountWrapper(element, props, isHydrating) {
2048 var node = element; // Do not assign value if it is already set. This prevents user text input
2049 // from being lost during SSR hydration.
2050
2051 if (props.hasOwnProperty('value') || props.hasOwnProperty('defaultValue')) {
2052 var type = props.type;
2053 var isButton = type === 'submit' || type === 'reset'; // Avoid setting value attribute on submit/reset inputs as it overrides the
2054 // default value provided by the browser. See: #12872
2055
2056 if (isButton && (props.value === undefined || props.value === null)) {
2057 return;
2058 }
2059
2060 var initialValue = toString(node._wrapperState.initialValue); // Do not assign value if it is already set. This prevents user text input
2061 // from being lost during SSR hydration.
2062
2063 if (!isHydrating) {
2064 {
2065 // When syncing the value attribute, the value property should use
2066 // the wrapperState._initialValue property. This uses:
2067 //
2068 // 1. The value React property when present
2069 // 2. The defaultValue React property when present
2070 // 3. An empty string
2071 if (initialValue !== node.value) {
2072 node.value = initialValue;
2073 }
2074 }
2075 }
2076
2077 {
2078 // Otherwise, the value attribute is synchronized to the property,
2079 // so we assign defaultValue to the same thing as the value property
2080 // assignment step above.
2081 node.defaultValue = initialValue;
2082 }
2083 } // Normally, we'd just do `node.checked = node.checked` upon initial mount, less this bug
2084 // this is needed to work around a chrome bug where setting defaultChecked
2085 // will sometimes influence the value of checked (even after detachment).
2086 // Reference: https://bugs.chromium.org/p/chromium/issues/detail?id=608416
2087 // We need to temporarily unset name to avoid disrupting radio button groups.
2088
2089
2090 var name = node.name;
2091
2092 if (name !== '') {
2093 node.name = '';
2094 }
2095
2096 {
2097 // When syncing the checked attribute, both the checked property and
2098 // attribute are assigned at the same time using defaultChecked. This uses:
2099 //
2100 // 1. The checked React property when present
2101 // 2. The defaultChecked React property when present
2102 // 3. Otherwise, false
2103 node.defaultChecked = !node.defaultChecked;
2104 node.defaultChecked = !!node._wrapperState.initialChecked;
2105 }
2106
2107 if (name !== '') {
2108 node.name = name;
2109 }
2110 }
2111 function restoreControlledState(element, props) {
2112 var node = element;
2113 updateWrapper(node, props);
2114 updateNamedCousins(node, props);
2115 }
2116
2117 function updateNamedCousins(rootNode, props) {
2118 var name = props.name;
2119
2120 if (props.type === 'radio' && name != null) {
2121 var queryRoot = rootNode;
2122
2123 while (queryRoot.parentNode) {
2124 queryRoot = queryRoot.parentNode;
2125 } // If `rootNode.form` was non-null, then we could try `form.elements`,
2126 // but that sometimes behaves strangely in IE8. We could also try using
2127 // `form.getElementsByName`, but that will only return direct children
2128 // and won't include inputs that use the HTML5 `form=` attribute. Since
2129 // the input might not even be in a form. It might not even be in the
2130 // document. Let's just use the local `querySelectorAll` to ensure we don't
2131 // miss anything.
2132
2133
2134 var group = queryRoot.querySelectorAll('input[name=' + JSON.stringify('' + name) + '][type="radio"]');
2135
2136 for (var i = 0; i < group.length; i++) {
2137 var otherNode = group[i];
2138
2139 if (otherNode === rootNode || otherNode.form !== rootNode.form) {
2140 continue;
2141 } // This will throw if radio buttons rendered by different copies of React
2142 // and the same name are rendered into the same form (same as #1939).
2143 // That's probably okay; we don't support it just as we don't support
2144 // mixing React radio buttons with non-React ones.
2145
2146
2147 var otherProps = getFiberCurrentPropsFromNode$1(otherNode);
2148
2149 if (!otherProps) {
2150 {
2151 throw Error( "ReactDOMInput: Mixing React and non-React radio inputs with the same `name` is not supported." );
2152 }
2153 } // We need update the tracked value on the named cousin since the value
2154 // was changed but the input saw no event or value set
2155
2156
2157 updateValueIfChanged(otherNode); // If this is a controlled radio button group, forcing the input that
2158 // was previously checked to update will cause it to be come re-checked
2159 // as appropriate.
2160
2161 updateWrapper(otherNode, otherProps);
2162 }
2163 }
2164 } // In Chrome, assigning defaultValue to certain input types triggers input validation.
2165 // For number inputs, the display value loses trailing decimal points. For email inputs,
2166 // Chrome raises "The specified value <x> is not a valid email address".
2167 //
2168 // Here we check to see if the defaultValue has actually changed, avoiding these problems
2169 // when the user is inputting text
2170 //
2171 // https://github.com/facebook/react/issues/7253
2172
2173
2174 function setDefaultValue(node, type, value) {
2175 if ( // Focused number inputs synchronize on blur. See ChangeEventPlugin.js
2176 type !== 'number' || node.ownerDocument.activeElement !== node) {
2177 if (value == null) {
2178 node.defaultValue = toString(node._wrapperState.initialValue);
2179 } else if (node.defaultValue !== toString(value)) {
2180 node.defaultValue = toString(value);
2181 }
2182 }
2183 }
2184
2185 var didWarnSelectedSetOnOption = false;
2186 var didWarnInvalidChild = false;
2187
2188 function flattenChildren(children) {
2189 var content = ''; // Flatten children. We'll warn if they are invalid
2190 // during validateProps() which runs for hydration too.
2191 // Note that this would throw on non-element objects.
2192 // Elements are stringified (which is normally irrelevant
2193 // but matters for <fbt>).
2194
2195 React.Children.forEach(children, function (child) {
2196 if (child == null) {
2197 return;
2198 }
2199
2200 content += child; // Note: we don't warn about invalid children here.
2201 // Instead, this is done separately below so that
2202 // it happens during the hydration codepath too.
2203 });
2204 return content;
2205 }
2206 /**
2207 * Implements an <option> host component that warns when `selected` is set.
2208 */
2209
2210
2211 function validateProps(element, props) {
2212 {
2213 // This mirrors the codepath above, but runs for hydration too.
2214 // Warn about invalid children here so that client and hydration are consistent.
2215 // TODO: this seems like it could cause a DEV-only throw for hydration
2216 // if children contains a non-element object. We should try to avoid that.
2217 if (typeof props.children === 'object' && props.children !== null) {
2218 React.Children.forEach(props.children, function (child) {
2219 if (child == null) {
2220 return;
2221 }
2222
2223 if (typeof child === 'string' || typeof child === 'number') {
2224 return;
2225 }
2226
2227 if (typeof child.type !== 'string') {
2228 return;
2229 }
2230
2231 if (!didWarnInvalidChild) {
2232 didWarnInvalidChild = true;
2233
2234 error('Only strings and numbers are supported as <option> children.');
2235 }
2236 });
2237 } // TODO: Remove support for `selected` in <option>.
2238
2239
2240 if (props.selected != null && !didWarnSelectedSetOnOption) {
2241 error('Use the `defaultValue` or `value` props on <select> instead of ' + 'setting `selected` on <option>.');
2242
2243 didWarnSelectedSetOnOption = true;
2244 }
2245 }
2246 }
2247 function postMountWrapper$1(element, props) {
2248 // value="" should make a value attribute (#6219)
2249 if (props.value != null) {
2250 element.setAttribute('value', toString(getToStringValue(props.value)));
2251 }
2252 }
2253 function getHostProps$1(element, props) {
2254 var hostProps = _assign({
2255 children: undefined
2256 }, props);
2257
2258 var content = flattenChildren(props.children);
2259
2260 if (content) {
2261 hostProps.children = content;
2262 }
2263
2264 return hostProps;
2265 }
2266
2267 var didWarnValueDefaultValue$1;
2268
2269 {
2270 didWarnValueDefaultValue$1 = false;
2271 }
2272
2273 function getDeclarationErrorAddendum() {
2274 var ownerName = getCurrentFiberOwnerNameInDevOrNull();
2275
2276 if (ownerName) {
2277 return '\n\nCheck the render method of `' + ownerName + '`.';
2278 }
2279
2280 return '';
2281 }
2282
2283 var valuePropNames = ['value', 'defaultValue'];
2284 /**
2285 * Validation function for `value` and `defaultValue`.
2286 */
2287
2288 function checkSelectPropTypes(props) {
2289 {
2290 ReactControlledValuePropTypes.checkPropTypes('select', props);
2291
2292 for (var i = 0; i < valuePropNames.length; i++) {
2293 var propName = valuePropNames[i];
2294
2295 if (props[propName] == null) {
2296 continue;
2297 }
2298
2299 var isArray = Array.isArray(props[propName]);
2300
2301 if (props.multiple && !isArray) {
2302 error('The `%s` prop supplied to <select> must be an array if ' + '`multiple` is true.%s', propName, getDeclarationErrorAddendum());
2303 } else if (!props.multiple && isArray) {
2304 error('The `%s` prop supplied to <select> must be a scalar ' + 'value if `multiple` is false.%s', propName, getDeclarationErrorAddendum());
2305 }
2306 }
2307 }
2308 }
2309
2310 function updateOptions(node, multiple, propValue, setDefaultSelected) {
2311 var options = node.options;
2312
2313 if (multiple) {
2314 var selectedValues = propValue;
2315 var selectedValue = {};
2316
2317 for (var i = 0; i < selectedValues.length; i++) {
2318 // Prefix to avoid chaos with special keys.
2319 selectedValue['$' + selectedValues[i]] = true;
2320 }
2321
2322 for (var _i = 0; _i < options.length; _i++) {
2323 var selected = selectedValue.hasOwnProperty('$' + options[_i].value);
2324
2325 if (options[_i].selected !== selected) {
2326 options[_i].selected = selected;
2327 }
2328
2329 if (selected && setDefaultSelected) {
2330 options[_i].defaultSelected = true;
2331 }
2332 }
2333 } else {
2334 // Do not set `select.value` as exact behavior isn't consistent across all
2335 // browsers for all cases.
2336 var _selectedValue = toString(getToStringValue(propValue));
2337
2338 var defaultSelected = null;
2339
2340 for (var _i2 = 0; _i2 < options.length; _i2++) {
2341 if (options[_i2].value === _selectedValue) {
2342 options[_i2].selected = true;
2343
2344 if (setDefaultSelected) {
2345 options[_i2].defaultSelected = true;
2346 }
2347
2348 return;
2349 }
2350
2351 if (defaultSelected === null && !options[_i2].disabled) {
2352 defaultSelected = options[_i2];
2353 }
2354 }
2355
2356 if (defaultSelected !== null) {
2357 defaultSelected.selected = true;
2358 }
2359 }
2360 }
2361 /**
2362 * Implements a <select> host component that allows optionally setting the
2363 * props `value` and `defaultValue`. If `multiple` is false, the prop must be a
2364 * stringable. If `multiple` is true, the prop must be an array of stringables.
2365 *
2366 * If `value` is not supplied (or null/undefined), user actions that change the
2367 * selected option will trigger updates to the rendered options.
2368 *
2369 * If it is supplied (and not null/undefined), the rendered options will not
2370 * update in response to user actions. Instead, the `value` prop must change in
2371 * order for the rendered options to update.
2372 *
2373 * If `defaultValue` is provided, any options with the supplied values will be
2374 * selected.
2375 */
2376
2377
2378 function getHostProps$2(element, props) {
2379 return _assign({}, props, {
2380 value: undefined
2381 });
2382 }
2383 function initWrapperState$1(element, props) {
2384 var node = element;
2385
2386 {
2387 checkSelectPropTypes(props);
2388 }
2389
2390 node._wrapperState = {
2391 wasMultiple: !!props.multiple
2392 };
2393
2394 {
2395 if (props.value !== undefined && props.defaultValue !== undefined && !didWarnValueDefaultValue$1) {
2396 error('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');
2397
2398 didWarnValueDefaultValue$1 = true;
2399 }
2400 }
2401 }
2402 function postMountWrapper$2(element, props) {
2403 var node = element;
2404 node.multiple = !!props.multiple;
2405 var value = props.value;
2406
2407 if (value != null) {
2408 updateOptions(node, !!props.multiple, value, false);
2409 } else if (props.defaultValue != null) {
2410 updateOptions(node, !!props.multiple, props.defaultValue, true);
2411 }
2412 }
2413 function postUpdateWrapper(element, props) {
2414 var node = element;
2415 var wasMultiple = node._wrapperState.wasMultiple;
2416 node._wrapperState.wasMultiple = !!props.multiple;
2417 var value = props.value;
2418
2419 if (value != null) {
2420 updateOptions(node, !!props.multiple, value, false);
2421 } else if (wasMultiple !== !!props.multiple) {
2422 // For simplicity, reapply `defaultValue` if `multiple` is toggled.
2423 if (props.defaultValue != null) {
2424 updateOptions(node, !!props.multiple, props.defaultValue, true);
2425 } else {
2426 // Revert the select back to its default unselected state.
2427 updateOptions(node, !!props.multiple, props.multiple ? [] : '', false);
2428 }
2429 }
2430 }
2431 function restoreControlledState$1(element, props) {
2432 var node = element;
2433 var value = props.value;
2434
2435 if (value != null) {
2436 updateOptions(node, !!props.multiple, value, false);
2437 }
2438 }
2439
2440 var didWarnValDefaultVal = false;
2441
2442 /**
2443 * Implements a <textarea> host component that allows setting `value`, and
2444 * `defaultValue`. This differs from the traditional DOM API because value is
2445 * usually set as PCDATA children.
2446 *
2447 * If `value` is not supplied (or null/undefined), user actions that affect the
2448 * value will trigger updates to the element.
2449 *
2450 * If `value` is supplied (and not null/undefined), the rendered element will
2451 * not trigger updates to the element. Instead, the `value` prop must change in
2452 * order for the rendered element to be updated.
2453 *
2454 * The rendered element will be initialized with an empty value, the prop
2455 * `defaultValue` if specified, or the children content (deprecated).
2456 */
2457 function getHostProps$3(element, props) {
2458 var node = element;
2459
2460 if (!(props.dangerouslySetInnerHTML == null)) {
2461 {
2462 throw Error( "`dangerouslySetInnerHTML` does not make sense on <textarea>." );
2463 }
2464 } // Always set children to the same thing. In IE9, the selection range will
2465 // get reset if `textContent` is mutated. We could add a check in setTextContent
2466 // to only set the value if/when the value differs from the node value (which would
2467 // completely solve this IE9 bug), but Sebastian+Sophie seemed to like this
2468 // solution. The value can be a boolean or object so that's why it's forced
2469 // to be a string.
2470
2471
2472 var hostProps = _assign({}, props, {
2473 value: undefined,
2474 defaultValue: undefined,
2475 children: toString(node._wrapperState.initialValue)
2476 });
2477
2478 return hostProps;
2479 }
2480 function initWrapperState$2(element, props) {
2481 var node = element;
2482
2483 {
2484 ReactControlledValuePropTypes.checkPropTypes('textarea', props);
2485
2486 if (props.value !== undefined && props.defaultValue !== undefined && !didWarnValDefaultVal) {
2487 error('%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');
2488
2489 didWarnValDefaultVal = true;
2490 }
2491 }
2492
2493 var initialValue = props.value; // Only bother fetching default value if we're going to use it
2494
2495 if (initialValue == null) {
2496 var children = props.children,
2497 defaultValue = props.defaultValue;
2498
2499 if (children != null) {
2500 {
2501 error('Use the `defaultValue` or `value` props instead of setting ' + 'children on <textarea>.');
2502 }
2503
2504 {
2505 if (!(defaultValue == null)) {
2506 {
2507 throw Error( "If you supply `defaultValue` on a <textarea>, do not pass children." );
2508 }
2509 }
2510
2511 if (Array.isArray(children)) {
2512 if (!(children.length <= 1)) {
2513 {
2514 throw Error( "<textarea> can only have at most one child." );
2515 }
2516 }
2517
2518 children = children[0];
2519 }
2520
2521 defaultValue = children;
2522 }
2523 }
2524
2525 if (defaultValue == null) {
2526 defaultValue = '';
2527 }
2528
2529 initialValue = defaultValue;
2530 }
2531
2532 node._wrapperState = {
2533 initialValue: getToStringValue(initialValue)
2534 };
2535 }
2536 function updateWrapper$1(element, props) {
2537 var node = element;
2538 var value = getToStringValue(props.value);
2539 var defaultValue = getToStringValue(props.defaultValue);
2540
2541 if (value != null) {
2542 // Cast `value` to a string to ensure the value is set correctly. While
2543 // browsers typically do this as necessary, jsdom doesn't.
2544 var newValue = toString(value); // To avoid side effects (such as losing text selection), only set value if changed
2545
2546 if (newValue !== node.value) {
2547 node.value = newValue;
2548 }
2549
2550 if (props.defaultValue == null && node.defaultValue !== newValue) {
2551 node.defaultValue = newValue;
2552 }
2553 }
2554
2555 if (defaultValue != null) {
2556 node.defaultValue = toString(defaultValue);
2557 }
2558 }
2559 function postMountWrapper$3(element, props) {
2560 var node = element; // This is in postMount because we need access to the DOM node, which is not
2561 // available until after the component has mounted.
2562
2563 var textContent = node.textContent; // Only set node.value if textContent is equal to the expected
2564 // initial value. In IE10/IE11 there is a bug where the placeholder attribute
2565 // will populate textContent as well.
2566 // https://developer.microsoft.com/microsoft-edge/platform/issues/101525/
2567
2568 if (textContent === node._wrapperState.initialValue) {
2569 if (textContent !== '' && textContent !== null) {
2570 node.value = textContent;
2571 }
2572 }
2573 }
2574 function restoreControlledState$2(element, props) {
2575 // DOM component is still mounted; update
2576 updateWrapper$1(element, props);
2577 }
2578
2579 var HTML_NAMESPACE = 'http://www.w3.org/1999/xhtml';
2580 var MATH_NAMESPACE = 'http://www.w3.org/1998/Math/MathML';
2581 var SVG_NAMESPACE = 'http://www.w3.org/2000/svg';
2582 var Namespaces = {
2583 html: HTML_NAMESPACE,
2584 mathml: MATH_NAMESPACE,
2585 svg: SVG_NAMESPACE
2586 }; // Assumes there is no parent namespace.
2587
2588 function getIntrinsicNamespace(type) {
2589 switch (type) {
2590 case 'svg':
2591 return SVG_NAMESPACE;
2592
2593 case 'math':
2594 return MATH_NAMESPACE;
2595
2596 default:
2597 return HTML_NAMESPACE;
2598 }
2599 }
2600 function getChildNamespace(parentNamespace, type) {
2601 if (parentNamespace == null || parentNamespace === HTML_NAMESPACE) {
2602 // No (or default) parent namespace: potential entry point.
2603 return getIntrinsicNamespace(type);
2604 }
2605
2606 if (parentNamespace === SVG_NAMESPACE && type === 'foreignObject') {
2607 // We're leaving SVG.
2608 return HTML_NAMESPACE;
2609 } // By default, pass namespace below.
2610
2611
2612 return parentNamespace;
2613 }
2614
2615 /* globals MSApp */
2616
2617 /**
2618 * Create a function which has 'unsafe' privileges (required by windows8 apps)
2619 */
2620 var createMicrosoftUnsafeLocalFunction = function (func) {
2621 if (typeof MSApp !== 'undefined' && MSApp.execUnsafeLocalFunction) {
2622 return function (arg0, arg1, arg2, arg3) {
2623 MSApp.execUnsafeLocalFunction(function () {
2624 return func(arg0, arg1, arg2, arg3);
2625 });
2626 };
2627 } else {
2628 return func;
2629 }
2630 };
2631
2632 var reusableSVGContainer;
2633 /**
2634 * Set the innerHTML property of a node
2635 *
2636 * @param {DOMElement} node
2637 * @param {string} html
2638 * @internal
2639 */
2640
2641 var setInnerHTML = createMicrosoftUnsafeLocalFunction(function (node, html) {
2642 if (node.namespaceURI === Namespaces.svg) {
2643
2644 if (!('innerHTML' in node)) {
2645 // IE does not have innerHTML for SVG nodes, so instead we inject the
2646 // new markup in a temp node and then move the child nodes across into
2647 // the target node
2648 reusableSVGContainer = reusableSVGContainer || document.createElement('div');
2649 reusableSVGContainer.innerHTML = '<svg>' + html.valueOf().toString() + '</svg>';
2650 var svgNode = reusableSVGContainer.firstChild;
2651
2652 while (node.firstChild) {
2653 node.removeChild(node.firstChild);
2654 }
2655
2656 while (svgNode.firstChild) {
2657 node.appendChild(svgNode.firstChild);
2658 }
2659
2660 return;
2661 }
2662 }
2663
2664 node.innerHTML = html;
2665 });
2666
2667 /**
2668 * HTML nodeType values that represent the type of the node
2669 */
2670 var ELEMENT_NODE = 1;
2671 var TEXT_NODE = 3;
2672 var COMMENT_NODE = 8;
2673 var DOCUMENT_NODE = 9;
2674 var DOCUMENT_FRAGMENT_NODE = 11;
2675
2676 /**
2677 * Set the textContent property of a node. For text updates, it's faster
2678 * to set the `nodeValue` of the Text node directly instead of using
2679 * `.textContent` which will remove the existing node and create a new one.
2680 *
2681 * @param {DOMElement} node
2682 * @param {string} text
2683 * @internal
2684 */
2685
2686 var setTextContent = function (node, text) {
2687 if (text) {
2688 var firstChild = node.firstChild;
2689
2690 if (firstChild && firstChild === node.lastChild && firstChild.nodeType === TEXT_NODE) {
2691 firstChild.nodeValue = text;
2692 return;
2693 }
2694 }
2695
2696 node.textContent = text;
2697 };
2698
2699 // Do not use the below two methods directly!
2700 // Instead use constants exported from DOMTopLevelEventTypes in ReactDOM.
2701 // (It is the only module that is allowed to access these methods.)
2702 function unsafeCastStringToDOMTopLevelType(topLevelType) {
2703 return topLevelType;
2704 }
2705 function unsafeCastDOMTopLevelTypeToString(topLevelType) {
2706 return topLevelType;
2707 }
2708
2709 /**
2710 * Generate a mapping of standard vendor prefixes using the defined style property and event name.
2711 *
2712 * @param {string} styleProp
2713 * @param {string} eventName
2714 * @returns {object}
2715 */
2716
2717 function makePrefixMap(styleProp, eventName) {
2718 var prefixes = {};
2719 prefixes[styleProp.toLowerCase()] = eventName.toLowerCase();
2720 prefixes['Webkit' + styleProp] = 'webkit' + eventName;
2721 prefixes['Moz' + styleProp] = 'moz' + eventName;
2722 return prefixes;
2723 }
2724 /**
2725 * A list of event names to a configurable list of vendor prefixes.
2726 */
2727
2728
2729 var vendorPrefixes = {
2730 animationend: makePrefixMap('Animation', 'AnimationEnd'),
2731 animationiteration: makePrefixMap('Animation', 'AnimationIteration'),
2732 animationstart: makePrefixMap('Animation', 'AnimationStart'),
2733 transitionend: makePrefixMap('Transition', 'TransitionEnd')
2734 };
2735 /**
2736 * Event names that have already been detected and prefixed (if applicable).
2737 */
2738
2739 var prefixedEventNames = {};
2740 /**
2741 * Element to check for prefixes on.
2742 */
2743
2744 var style = {};
2745 /**
2746 * Bootstrap if a DOM exists.
2747 */
2748
2749 if (canUseDOM) {
2750 style = document.createElement('div').style; // On some platforms, in particular some releases of Android 4.x,
2751 // the un-prefixed "animation" and "transition" properties are defined on the
2752 // style object but the events that fire will still be prefixed, so we need
2753 // to check if the un-prefixed events are usable, and if not remove them from the map.
2754
2755 if (!('AnimationEvent' in window)) {
2756 delete vendorPrefixes.animationend.animation;
2757 delete vendorPrefixes.animationiteration.animation;
2758 delete vendorPrefixes.animationstart.animation;
2759 } // Same as above
2760
2761
2762 if (!('TransitionEvent' in window)) {
2763 delete vendorPrefixes.transitionend.transition;
2764 }
2765 }
2766 /**
2767 * Attempts to determine the correct vendor prefixed event name.
2768 *
2769 * @param {string} eventName
2770 * @returns {string}
2771 */
2772
2773
2774 function getVendorPrefixedEventName(eventName) {
2775 if (prefixedEventNames[eventName]) {
2776 return prefixedEventNames[eventName];
2777 } else if (!vendorPrefixes[eventName]) {
2778 return eventName;
2779 }
2780
2781 var prefixMap = vendorPrefixes[eventName];
2782
2783 for (var styleProp in prefixMap) {
2784 if (prefixMap.hasOwnProperty(styleProp) && styleProp in style) {
2785 return prefixedEventNames[eventName] = prefixMap[styleProp];
2786 }
2787 }
2788
2789 return eventName;
2790 }
2791
2792 /**
2793 * To identify top level events in ReactDOM, we use constants defined by this
2794 * module. This is the only module that uses the unsafe* methods to express
2795 * that the constants actually correspond to the browser event names. This lets
2796 * us save some bundle size by avoiding a top level type -> event name map.
2797 * The rest of ReactDOM code should import top level types from this file.
2798 */
2799
2800 var TOP_ABORT = unsafeCastStringToDOMTopLevelType('abort');
2801 var TOP_ANIMATION_END = unsafeCastStringToDOMTopLevelType(getVendorPrefixedEventName('animationend'));
2802 var TOP_ANIMATION_ITERATION = unsafeCastStringToDOMTopLevelType(getVendorPrefixedEventName('animationiteration'));
2803 var TOP_ANIMATION_START = unsafeCastStringToDOMTopLevelType(getVendorPrefixedEventName('animationstart'));
2804 var TOP_BLUR = unsafeCastStringToDOMTopLevelType('blur');
2805 var TOP_CAN_PLAY = unsafeCastStringToDOMTopLevelType('canplay');
2806 var TOP_CAN_PLAY_THROUGH = unsafeCastStringToDOMTopLevelType('canplaythrough');
2807 var TOP_CANCEL = unsafeCastStringToDOMTopLevelType('cancel');
2808 var TOP_CHANGE = unsafeCastStringToDOMTopLevelType('change');
2809 var TOP_CLICK = unsafeCastStringToDOMTopLevelType('click');
2810 var TOP_CLOSE = unsafeCastStringToDOMTopLevelType('close');
2811 var TOP_COMPOSITION_END = unsafeCastStringToDOMTopLevelType('compositionend');
2812 var TOP_COMPOSITION_START = unsafeCastStringToDOMTopLevelType('compositionstart');
2813 var TOP_COMPOSITION_UPDATE = unsafeCastStringToDOMTopLevelType('compositionupdate');
2814 var TOP_CONTEXT_MENU = unsafeCastStringToDOMTopLevelType('contextmenu');
2815 var TOP_COPY = unsafeCastStringToDOMTopLevelType('copy');
2816 var TOP_CUT = unsafeCastStringToDOMTopLevelType('cut');
2817 var TOP_DOUBLE_CLICK = unsafeCastStringToDOMTopLevelType('dblclick');
2818 var TOP_AUX_CLICK = unsafeCastStringToDOMTopLevelType('auxclick');
2819 var TOP_DRAG = unsafeCastStringToDOMTopLevelType('drag');
2820 var TOP_DRAG_END = unsafeCastStringToDOMTopLevelType('dragend');
2821 var TOP_DRAG_ENTER = unsafeCastStringToDOMTopLevelType('dragenter');
2822 var TOP_DRAG_EXIT = unsafeCastStringToDOMTopLevelType('dragexit');
2823 var TOP_DRAG_LEAVE = unsafeCastStringToDOMTopLevelType('dragleave');
2824 var TOP_DRAG_OVER = unsafeCastStringToDOMTopLevelType('dragover');
2825 var TOP_DRAG_START = unsafeCastStringToDOMTopLevelType('dragstart');
2826 var TOP_DROP = unsafeCastStringToDOMTopLevelType('drop');
2827 var TOP_DURATION_CHANGE = unsafeCastStringToDOMTopLevelType('durationchange');
2828 var TOP_EMPTIED = unsafeCastStringToDOMTopLevelType('emptied');
2829 var TOP_ENCRYPTED = unsafeCastStringToDOMTopLevelType('encrypted');
2830 var TOP_ENDED = unsafeCastStringToDOMTopLevelType('ended');
2831 var TOP_ERROR = unsafeCastStringToDOMTopLevelType('error');
2832 var TOP_FOCUS = unsafeCastStringToDOMTopLevelType('focus');
2833 var TOP_GOT_POINTER_CAPTURE = unsafeCastStringToDOMTopLevelType('gotpointercapture');
2834 var TOP_INPUT = unsafeCastStringToDOMTopLevelType('input');
2835 var TOP_INVALID = unsafeCastStringToDOMTopLevelType('invalid');
2836 var TOP_KEY_DOWN = unsafeCastStringToDOMTopLevelType('keydown');
2837 var TOP_KEY_PRESS = unsafeCastStringToDOMTopLevelType('keypress');
2838 var TOP_KEY_UP = unsafeCastStringToDOMTopLevelType('keyup');
2839 var TOP_LOAD = unsafeCastStringToDOMTopLevelType('load');
2840 var TOP_LOAD_START = unsafeCastStringToDOMTopLevelType('loadstart');
2841 var TOP_LOADED_DATA = unsafeCastStringToDOMTopLevelType('loadeddata');
2842 var TOP_LOADED_METADATA = unsafeCastStringToDOMTopLevelType('loadedmetadata');
2843 var TOP_LOST_POINTER_CAPTURE = unsafeCastStringToDOMTopLevelType('lostpointercapture');
2844 var TOP_MOUSE_DOWN = unsafeCastStringToDOMTopLevelType('mousedown');
2845 var TOP_MOUSE_MOVE = unsafeCastStringToDOMTopLevelType('mousemove');
2846 var TOP_MOUSE_OUT = unsafeCastStringToDOMTopLevelType('mouseout');
2847 var TOP_MOUSE_OVER = unsafeCastStringToDOMTopLevelType('mouseover');
2848 var TOP_MOUSE_UP = unsafeCastStringToDOMTopLevelType('mouseup');
2849 var TOP_PASTE = unsafeCastStringToDOMTopLevelType('paste');
2850 var TOP_PAUSE = unsafeCastStringToDOMTopLevelType('pause');
2851 var TOP_PLAY = unsafeCastStringToDOMTopLevelType('play');
2852 var TOP_PLAYING = unsafeCastStringToDOMTopLevelType('playing');
2853 var TOP_POINTER_CANCEL = unsafeCastStringToDOMTopLevelType('pointercancel');
2854 var TOP_POINTER_DOWN = unsafeCastStringToDOMTopLevelType('pointerdown');
2855 var TOP_POINTER_MOVE = unsafeCastStringToDOMTopLevelType('pointermove');
2856 var TOP_POINTER_OUT = unsafeCastStringToDOMTopLevelType('pointerout');
2857 var TOP_POINTER_OVER = unsafeCastStringToDOMTopLevelType('pointerover');
2858 var TOP_POINTER_UP = unsafeCastStringToDOMTopLevelType('pointerup');
2859 var TOP_PROGRESS = unsafeCastStringToDOMTopLevelType('progress');
2860 var TOP_RATE_CHANGE = unsafeCastStringToDOMTopLevelType('ratechange');
2861 var TOP_RESET = unsafeCastStringToDOMTopLevelType('reset');
2862 var TOP_SCROLL = unsafeCastStringToDOMTopLevelType('scroll');
2863 var TOP_SEEKED = unsafeCastStringToDOMTopLevelType('seeked');
2864 var TOP_SEEKING = unsafeCastStringToDOMTopLevelType('seeking');
2865 var TOP_SELECTION_CHANGE = unsafeCastStringToDOMTopLevelType('selectionchange');
2866 var TOP_STALLED = unsafeCastStringToDOMTopLevelType('stalled');
2867 var TOP_SUBMIT = unsafeCastStringToDOMTopLevelType('submit');
2868 var TOP_SUSPEND = unsafeCastStringToDOMTopLevelType('suspend');
2869 var TOP_TEXT_INPUT = unsafeCastStringToDOMTopLevelType('textInput');
2870 var TOP_TIME_UPDATE = unsafeCastStringToDOMTopLevelType('timeupdate');
2871 var TOP_TOGGLE = unsafeCastStringToDOMTopLevelType('toggle');
2872 var TOP_TOUCH_CANCEL = unsafeCastStringToDOMTopLevelType('touchcancel');
2873 var TOP_TOUCH_END = unsafeCastStringToDOMTopLevelType('touchend');
2874 var TOP_TOUCH_MOVE = unsafeCastStringToDOMTopLevelType('touchmove');
2875 var TOP_TOUCH_START = unsafeCastStringToDOMTopLevelType('touchstart');
2876 var TOP_TRANSITION_END = unsafeCastStringToDOMTopLevelType(getVendorPrefixedEventName('transitionend'));
2877 var TOP_VOLUME_CHANGE = unsafeCastStringToDOMTopLevelType('volumechange');
2878 var TOP_WAITING = unsafeCastStringToDOMTopLevelType('waiting');
2879 var TOP_WHEEL = unsafeCastStringToDOMTopLevelType('wheel'); // List of events that need to be individually attached to media elements.
2880 // Note that events in this list will *not* be listened to at the top level
2881 // unless they're explicitly whitelisted in `ReactBrowserEventEmitter.listenTo`.
2882
2883 var 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];
2884 function getRawEventName(topLevelType) {
2885 return unsafeCastDOMTopLevelTypeToString(topLevelType);
2886 }
2887
2888 var PossiblyWeakMap = typeof WeakMap === 'function' ? WeakMap : Map; // prettier-ignore
2889
2890 var elementListenerMap = new PossiblyWeakMap();
2891 function getListenerMapForElement(element) {
2892 var listenerMap = elementListenerMap.get(element);
2893
2894 if (listenerMap === undefined) {
2895 listenerMap = new Map();
2896 elementListenerMap.set(element, listenerMap);
2897 }
2898
2899 return listenerMap;
2900 }
2901
2902 /**
2903 * `ReactInstanceMap` maintains a mapping from a public facing stateful
2904 * instance (key) and the internal representation (value). This allows public
2905 * methods to accept the user facing instance as an argument and map them back
2906 * to internal methods.
2907 *
2908 * Note that this module is currently shared and assumed to be stateless.
2909 * If this becomes an actual Map, that will break.
2910 */
2911 function get(key) {
2912 return key._reactInternalFiber;
2913 }
2914 function has$1(key) {
2915 return key._reactInternalFiber !== undefined;
2916 }
2917 function set(key, value) {
2918 key._reactInternalFiber = value;
2919 }
2920
2921 // Don't change these two values. They're used by React Dev Tools.
2922 var NoEffect =
2923 /* */
2924 0;
2925 var PerformedWork =
2926 /* */
2927 1; // You can change the rest (and add more).
2928
2929 var Placement =
2930 /* */
2931 2;
2932 var Update =
2933 /* */
2934 4;
2935 var PlacementAndUpdate =
2936 /* */
2937 6;
2938 var Deletion =
2939 /* */
2940 8;
2941 var ContentReset =
2942 /* */
2943 16;
2944 var Callback =
2945 /* */
2946 32;
2947 var DidCapture =
2948 /* */
2949 64;
2950 var Ref =
2951 /* */
2952 128;
2953 var Snapshot =
2954 /* */
2955 256;
2956 var Passive =
2957 /* */
2958 512;
2959 var Hydrating =
2960 /* */
2961 1024;
2962 var HydratingAndUpdate =
2963 /* */
2964 1028; // Passive & Update & Callback & Ref & Snapshot
2965
2966 var LifecycleEffectMask =
2967 /* */
2968 932; // Union of all host effects
2969
2970 var HostEffectMask =
2971 /* */
2972 2047;
2973 var Incomplete =
2974 /* */
2975 2048;
2976 var ShouldCapture =
2977 /* */
2978 4096;
2979
2980 var ReactCurrentOwner = ReactSharedInternals.ReactCurrentOwner;
2981 function getNearestMountedFiber(fiber) {
2982 var node = fiber;
2983 var nearestMounted = fiber;
2984
2985 if (!fiber.alternate) {
2986 // If there is no alternate, this might be a new tree that isn't inserted
2987 // yet. If it is, then it will have a pending insertion effect on it.
2988 var nextNode = node;
2989
2990 do {
2991 node = nextNode;
2992
2993 if ((node.effectTag & (Placement | Hydrating)) !== NoEffect) {
2994 // This is an insertion or in-progress hydration. The nearest possible
2995 // mounted fiber is the parent but we need to continue to figure out
2996 // if that one is still mounted.
2997 nearestMounted = node.return;
2998 }
2999
3000 nextNode = node.return;
3001 } while (nextNode);
3002 } else {
3003 while (node.return) {
3004 node = node.return;
3005 }
3006 }
3007
3008 if (node.tag === HostRoot) {
3009 // TODO: Check if this was a nested HostRoot when used with
3010 // renderContainerIntoSubtree.
3011 return nearestMounted;
3012 } // If we didn't hit the root, that means that we're in an disconnected tree
3013 // that has been unmounted.
3014
3015
3016 return null;
3017 }
3018 function getSuspenseInstanceFromFiber(fiber) {
3019 if (fiber.tag === SuspenseComponent) {
3020 var suspenseState = fiber.memoizedState;
3021
3022 if (suspenseState === null) {
3023 var current = fiber.alternate;
3024
3025 if (current !== null) {
3026 suspenseState = current.memoizedState;
3027 }
3028 }
3029
3030 if (suspenseState !== null) {
3031 return suspenseState.dehydrated;
3032 }
3033 }
3034
3035 return null;
3036 }
3037 function getContainerFromFiber(fiber) {
3038 return fiber.tag === HostRoot ? fiber.stateNode.containerInfo : null;
3039 }
3040 function isFiberMounted(fiber) {
3041 return getNearestMountedFiber(fiber) === fiber;
3042 }
3043 function isMounted(component) {
3044 {
3045 var owner = ReactCurrentOwner.current;
3046
3047 if (owner !== null && owner.tag === ClassComponent) {
3048 var ownerFiber = owner;
3049 var instance = ownerFiber.stateNode;
3050
3051 if (!instance._warnedAboutRefsInRender) {
3052 error('%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');
3053 }
3054
3055 instance._warnedAboutRefsInRender = true;
3056 }
3057 }
3058
3059 var fiber = get(component);
3060
3061 if (!fiber) {
3062 return false;
3063 }
3064
3065 return getNearestMountedFiber(fiber) === fiber;
3066 }
3067
3068 function assertIsMounted(fiber) {
3069 if (!(getNearestMountedFiber(fiber) === fiber)) {
3070 {
3071 throw Error( "Unable to find node on an unmounted component." );
3072 }
3073 }
3074 }
3075
3076 function findCurrentFiberUsingSlowPath(fiber) {
3077 var alternate = fiber.alternate;
3078
3079 if (!alternate) {
3080 // If there is no alternate, then we only need to check if it is mounted.
3081 var nearestMounted = getNearestMountedFiber(fiber);
3082
3083 if (!(nearestMounted !== null)) {
3084 {
3085 throw Error( "Unable to find node on an unmounted component." );
3086 }
3087 }
3088
3089 if (nearestMounted !== fiber) {
3090 return null;
3091 }
3092
3093 return fiber;
3094 } // If we have two possible branches, we'll walk backwards up to the root
3095 // to see what path the root points to. On the way we may hit one of the
3096 // special cases and we'll deal with them.
3097
3098
3099 var a = fiber;
3100 var b = alternate;
3101
3102 while (true) {
3103 var parentA = a.return;
3104
3105 if (parentA === null) {
3106 // We're at the root.
3107 break;
3108 }
3109
3110 var parentB = parentA.alternate;
3111
3112 if (parentB === null) {
3113 // There is no alternate. This is an unusual case. Currently, it only
3114 // happens when a Suspense component is hidden. An extra fragment fiber
3115 // is inserted in between the Suspense fiber and its children. Skip
3116 // over this extra fragment fiber and proceed to the next parent.
3117 var nextParent = parentA.return;
3118
3119 if (nextParent !== null) {
3120 a = b = nextParent;
3121 continue;
3122 } // If there's no parent, we're at the root.
3123
3124
3125 break;
3126 } // If both copies of the parent fiber point to the same child, we can
3127 // assume that the child is current. This happens when we bailout on low
3128 // priority: the bailed out fiber's child reuses the current child.
3129
3130
3131 if (parentA.child === parentB.child) {
3132 var child = parentA.child;
3133
3134 while (child) {
3135 if (child === a) {
3136 // We've determined that A is the current branch.
3137 assertIsMounted(parentA);
3138 return fiber;
3139 }
3140
3141 if (child === b) {
3142 // We've determined that B is the current branch.
3143 assertIsMounted(parentA);
3144 return alternate;
3145 }
3146
3147 child = child.sibling;
3148 } // We should never have an alternate for any mounting node. So the only
3149 // way this could possibly happen is if this was unmounted, if at all.
3150
3151
3152 {
3153 {
3154 throw Error( "Unable to find node on an unmounted component." );
3155 }
3156 }
3157 }
3158
3159 if (a.return !== b.return) {
3160 // The return pointer of A and the return pointer of B point to different
3161 // fibers. We assume that return pointers never criss-cross, so A must
3162 // belong to the child set of A.return, and B must belong to the child
3163 // set of B.return.
3164 a = parentA;
3165 b = parentB;
3166 } else {
3167 // The return pointers point to the same fiber. We'll have to use the
3168 // default, slow path: scan the child sets of each parent alternate to see
3169 // which child belongs to which set.
3170 //
3171 // Search parent A's child set
3172 var didFindChild = false;
3173 var _child = parentA.child;
3174
3175 while (_child) {
3176 if (_child === a) {
3177 didFindChild = true;
3178 a = parentA;
3179 b = parentB;
3180 break;
3181 }
3182
3183 if (_child === b) {
3184 didFindChild = true;
3185 b = parentA;
3186 a = parentB;
3187 break;
3188 }
3189
3190 _child = _child.sibling;
3191 }
3192
3193 if (!didFindChild) {
3194 // Search parent B's child set
3195 _child = parentB.child;
3196
3197 while (_child) {
3198 if (_child === a) {
3199 didFindChild = true;
3200 a = parentB;
3201 b = parentA;
3202 break;
3203 }
3204
3205 if (_child === b) {
3206 didFindChild = true;
3207 b = parentB;
3208 a = parentA;
3209 break;
3210 }
3211
3212 _child = _child.sibling;
3213 }
3214
3215 if (!didFindChild) {
3216 {
3217 throw Error( "Child was not found in either parent set. This indicates a bug in React related to the return pointer. Please file an issue." );
3218 }
3219 }
3220 }
3221 }
3222
3223 if (!(a.alternate === b)) {
3224 {
3225 throw Error( "Return fibers should always be each others' alternates. This error is likely caused by a bug in React. Please file an issue." );
3226 }
3227 }
3228 } // If the root is not a host container, we're in a disconnected tree. I.e.
3229 // unmounted.
3230
3231
3232 if (!(a.tag === HostRoot)) {
3233 {
3234 throw Error( "Unable to find node on an unmounted component." );
3235 }
3236 }
3237
3238 if (a.stateNode.current === a) {
3239 // We've determined that A is the current branch.
3240 return fiber;
3241 } // Otherwise B has to be current branch.
3242
3243
3244 return alternate;
3245 }
3246 function findCurrentHostFiber(parent) {
3247 var currentParent = findCurrentFiberUsingSlowPath(parent);
3248
3249 if (!currentParent) {
3250 return null;
3251 } // Next we'll drill down this component to find the first HostComponent/Text.
3252
3253
3254 var node = currentParent;
3255
3256 while (true) {
3257 if (node.tag === HostComponent || node.tag === HostText) {
3258 return node;
3259 } else if (node.child) {
3260 node.child.return = node;
3261 node = node.child;
3262 continue;
3263 }
3264
3265 if (node === currentParent) {
3266 return null;
3267 }
3268
3269 while (!node.sibling) {
3270 if (!node.return || node.return === currentParent) {
3271 return null;
3272 }
3273
3274 node = node.return;
3275 }
3276
3277 node.sibling.return = node.return;
3278 node = node.sibling;
3279 } // Flow needs the return null here, but ESLint complains about it.
3280 // eslint-disable-next-line no-unreachable
3281
3282
3283 return null;
3284 }
3285 function findCurrentHostFiberWithNoPortals(parent) {
3286 var currentParent = findCurrentFiberUsingSlowPath(parent);
3287
3288 if (!currentParent) {
3289 return null;
3290 } // Next we'll drill down this component to find the first HostComponent/Text.
3291
3292
3293 var node = currentParent;
3294
3295 while (true) {
3296 if (node.tag === HostComponent || node.tag === HostText || enableFundamentalAPI ) {
3297 return node;
3298 } else if (node.child && node.tag !== HostPortal) {
3299 node.child.return = node;
3300 node = node.child;
3301 continue;
3302 }
3303
3304 if (node === currentParent) {
3305 return null;
3306 }
3307
3308 while (!node.sibling) {
3309 if (!node.return || node.return === currentParent) {
3310 return null;
3311 }
3312
3313 node = node.return;
3314 }
3315
3316 node.sibling.return = node.return;
3317 node = node.sibling;
3318 } // Flow needs the return null here, but ESLint complains about it.
3319 // eslint-disable-next-line no-unreachable
3320
3321
3322 return null;
3323 }
3324
3325 /**
3326 * Accumulates items that must not be null or undefined into the first one. This
3327 * is used to conserve memory by avoiding array allocations, and thus sacrifices
3328 * API cleanness. Since `current` can be null before being passed in and not
3329 * null after this function, make sure to assign it back to `current`:
3330 *
3331 * `a = accumulateInto(a, b);`
3332 *
3333 * This API should be sparingly used. Try `accumulate` for something cleaner.
3334 *
3335 * @return {*|array<*>} An accumulation of items.
3336 */
3337
3338 function accumulateInto(current, next) {
3339 if (!(next != null)) {
3340 {
3341 throw Error( "accumulateInto(...): Accumulated items must not be null or undefined." );
3342 }
3343 }
3344
3345 if (current == null) {
3346 return next;
3347 } // Both are not empty. Warning: Never call x.concat(y) when you are not
3348 // certain that x is an Array (x could be a string with concat method).
3349
3350
3351 if (Array.isArray(current)) {
3352 if (Array.isArray(next)) {
3353 current.push.apply(current, next);
3354 return current;
3355 }
3356
3357 current.push(next);
3358 return current;
3359 }
3360
3361 if (Array.isArray(next)) {
3362 // A bit too dangerous to mutate `next`.
3363 return [current].concat(next);
3364 }
3365
3366 return [current, next];
3367 }
3368
3369 /**
3370 * @param {array} arr an "accumulation" of items which is either an Array or
3371 * a single item. Useful when paired with the `accumulate` module. This is a
3372 * simple utility that allows us to reason about a collection of items, but
3373 * handling the case when there is exactly one item (and we do not need to
3374 * allocate an array).
3375 * @param {function} cb Callback invoked with each element or a collection.
3376 * @param {?} [scope] Scope used as `this` in a callback.
3377 */
3378 function forEachAccumulated(arr, cb, scope) {
3379 if (Array.isArray(arr)) {
3380 arr.forEach(cb, scope);
3381 } else if (arr) {
3382 cb.call(scope, arr);
3383 }
3384 }
3385
3386 /**
3387 * Internal queue of events that have accumulated their dispatches and are
3388 * waiting to have their dispatches executed.
3389 */
3390
3391 var eventQueue = null;
3392 /**
3393 * Dispatches an event and releases it back into the pool, unless persistent.
3394 *
3395 * @param {?object} event Synthetic event to be dispatched.
3396 * @private
3397 */
3398
3399 var executeDispatchesAndRelease = function (event) {
3400 if (event) {
3401 executeDispatchesInOrder(event);
3402
3403 if (!event.isPersistent()) {
3404 event.constructor.release(event);
3405 }
3406 }
3407 };
3408
3409 var executeDispatchesAndReleaseTopLevel = function (e) {
3410 return executeDispatchesAndRelease(e);
3411 };
3412
3413 function runEventsInBatch(events) {
3414 if (events !== null) {
3415 eventQueue = accumulateInto(eventQueue, events);
3416 } // Set `eventQueue` to null before processing it so that we can tell if more
3417 // events get enqueued while processing.
3418
3419
3420 var processingEventQueue = eventQueue;
3421 eventQueue = null;
3422
3423 if (!processingEventQueue) {
3424 return;
3425 }
3426
3427 forEachAccumulated(processingEventQueue, executeDispatchesAndReleaseTopLevel);
3428
3429 if (!!eventQueue) {
3430 {
3431 throw Error( "processEventQueue(): Additional events were enqueued while processing an event queue. Support for this has not yet been implemented." );
3432 }
3433 } // This would be a good time to rethrow if any of the event handlers threw.
3434
3435
3436 rethrowCaughtError();
3437 }
3438
3439 /**
3440 * Gets the target node from a native browser event by accounting for
3441 * inconsistencies in browser DOM APIs.
3442 *
3443 * @param {object} nativeEvent Native browser event.
3444 * @return {DOMEventTarget} Target node.
3445 */
3446
3447 function getEventTarget(nativeEvent) {
3448 // Fallback to nativeEvent.srcElement for IE9
3449 // https://github.com/facebook/react/issues/12506
3450 var target = nativeEvent.target || nativeEvent.srcElement || window; // Normalize SVG <use> element events #4963
3451
3452 if (target.correspondingUseElement) {
3453 target = target.correspondingUseElement;
3454 } // Safari may fire events on text nodes (Node.TEXT_NODE is 3).
3455 // @see http://www.quirksmode.org/js/events_properties.html
3456
3457
3458 return target.nodeType === TEXT_NODE ? target.parentNode : target;
3459 }
3460
3461 /**
3462 * Checks if an event is supported in the current execution environment.
3463 *
3464 * NOTE: This will not work correctly for non-generic events such as `change`,
3465 * `reset`, `load`, `error`, and `select`.
3466 *
3467 * Borrows from Modernizr.
3468 *
3469 * @param {string} eventNameSuffix Event name, e.g. "click".
3470 * @return {boolean} True if the event is supported.
3471 * @internal
3472 * @license Modernizr 3.0.0pre (Custom Build) | MIT
3473 */
3474
3475 function isEventSupported(eventNameSuffix) {
3476 if (!canUseDOM) {
3477 return false;
3478 }
3479
3480 var eventName = 'on' + eventNameSuffix;
3481 var isSupported = eventName in document;
3482
3483 if (!isSupported) {
3484 var element = document.createElement('div');
3485 element.setAttribute(eventName, 'return;');
3486 isSupported = typeof element[eventName] === 'function';
3487 }
3488
3489 return isSupported;
3490 }
3491
3492 /**
3493 * Summary of `DOMEventPluginSystem` event handling:
3494 *
3495 * - Top-level delegation is used to trap most native browser events. This
3496 * may only occur in the main thread and is the responsibility of
3497 * ReactDOMEventListener, which is injected and can therefore support
3498 * pluggable event sources. This is the only work that occurs in the main
3499 * thread.
3500 *
3501 * - We normalize and de-duplicate events to account for browser quirks. This
3502 * may be done in the worker thread.
3503 *
3504 * - Forward these native events (with the associated top-level type used to
3505 * trap it) to `EventPluginRegistry`, which in turn will ask plugins if they want
3506 * to extract any synthetic events.
3507 *
3508 * - The `EventPluginRegistry` will then process each event by annotating them with
3509 * "dispatches", a sequence of listeners and IDs that care about that event.
3510 *
3511 * - The `EventPluginRegistry` then dispatches the events.
3512 *
3513 * Overview of React and the event system:
3514 *
3515 * +------------+ .
3516 * | DOM | .
3517 * +------------+ .
3518 * | .
3519 * v .
3520 * +------------+ .
3521 * | ReactEvent | .
3522 * | Listener | .
3523 * +------------+ . +-----------+
3524 * | . +--------+|SimpleEvent|
3525 * | . | |Plugin |
3526 * +-----|------+ . v +-----------+
3527 * | | | . +--------------+ +------------+
3528 * | +-----------.--->|PluginRegistry| | Event |
3529 * | | . | | +-----------+ | Propagators|
3530 * | ReactEvent | . | | |TapEvent | |------------|
3531 * | Emitter | . | |<---+|Plugin | |other plugin|
3532 * | | . | | +-----------+ | utilities |
3533 * | +-----------.--->| | +------------+
3534 * | | | . +--------------+
3535 * +-----|------+ . ^ +-----------+
3536 * | . | |Enter/Leave|
3537 * + . +-------+|Plugin |
3538 * +-------------+ . +-----------+
3539 * | application | .
3540 * |-------------| .
3541 * | | .
3542 * | | .
3543 * +-------------+ .
3544 * .
3545 * React Core . General Purpose Event Plugin System
3546 */
3547
3548 var CALLBACK_BOOKKEEPING_POOL_SIZE = 10;
3549 var callbackBookkeepingPool = [];
3550
3551 function releaseTopLevelCallbackBookKeeping(instance) {
3552 instance.topLevelType = null;
3553 instance.nativeEvent = null;
3554 instance.targetInst = null;
3555 instance.ancestors.length = 0;
3556
3557 if (callbackBookkeepingPool.length < CALLBACK_BOOKKEEPING_POOL_SIZE) {
3558 callbackBookkeepingPool.push(instance);
3559 }
3560 } // Used to store ancestor hierarchy in top level callback
3561
3562
3563 function getTopLevelCallbackBookKeeping(topLevelType, nativeEvent, targetInst, eventSystemFlags) {
3564 if (callbackBookkeepingPool.length) {
3565 var instance = callbackBookkeepingPool.pop();
3566 instance.topLevelType = topLevelType;
3567 instance.eventSystemFlags = eventSystemFlags;
3568 instance.nativeEvent = nativeEvent;
3569 instance.targetInst = targetInst;
3570 return instance;
3571 }
3572
3573 return {
3574 topLevelType: topLevelType,
3575 eventSystemFlags: eventSystemFlags,
3576 nativeEvent: nativeEvent,
3577 targetInst: targetInst,
3578 ancestors: []
3579 };
3580 }
3581 /**
3582 * Find the deepest React component completely containing the root of the
3583 * passed-in instance (for use when entire React trees are nested within each
3584 * other). If React trees are not nested, returns null.
3585 */
3586
3587
3588 function findRootContainerNode(inst) {
3589 if (inst.tag === HostRoot) {
3590 return inst.stateNode.containerInfo;
3591 } // TODO: It may be a good idea to cache this to prevent unnecessary DOM
3592 // traversal, but caching is difficult to do correctly without using a
3593 // mutation observer to listen for all DOM changes.
3594
3595
3596 while (inst.return) {
3597 inst = inst.return;
3598 }
3599
3600 if (inst.tag !== HostRoot) {
3601 // This can happen if we're in a detached tree.
3602 return null;
3603 }
3604
3605 return inst.stateNode.containerInfo;
3606 }
3607 /**
3608 * Allows registered plugins an opportunity to extract events from top-level
3609 * native browser events.
3610 *
3611 * @return {*} An accumulation of synthetic events.
3612 * @internal
3613 */
3614
3615
3616 function extractPluginEvents(topLevelType, targetInst, nativeEvent, nativeEventTarget, eventSystemFlags) {
3617 var events = null;
3618
3619 for (var i = 0; i < plugins.length; i++) {
3620 // Not every plugin in the ordering may be loaded at runtime.
3621 var possiblePlugin = plugins[i];
3622
3623 if (possiblePlugin) {
3624 var extractedEvents = possiblePlugin.extractEvents(topLevelType, targetInst, nativeEvent, nativeEventTarget, eventSystemFlags);
3625
3626 if (extractedEvents) {
3627 events = accumulateInto(events, extractedEvents);
3628 }
3629 }
3630 }
3631
3632 return events;
3633 }
3634
3635 function runExtractedPluginEventsInBatch(topLevelType, targetInst, nativeEvent, nativeEventTarget, eventSystemFlags) {
3636 var events = extractPluginEvents(topLevelType, targetInst, nativeEvent, nativeEventTarget, eventSystemFlags);
3637 runEventsInBatch(events);
3638 }
3639
3640 function handleTopLevel(bookKeeping) {
3641 var targetInst = bookKeeping.targetInst; // Loop through the hierarchy, in case there's any nested components.
3642 // It's important that we build the array of ancestors before calling any
3643 // event handlers, because event handlers can modify the DOM, leading to
3644 // inconsistencies with ReactMount's node cache. See #1105.
3645
3646 var ancestor = targetInst;
3647
3648 do {
3649 if (!ancestor) {
3650 var ancestors = bookKeeping.ancestors;
3651 ancestors.push(ancestor);
3652 break;
3653 }
3654
3655 var root = findRootContainerNode(ancestor);
3656
3657 if (!root) {
3658 break;
3659 }
3660
3661 var tag = ancestor.tag;
3662
3663 if (tag === HostComponent || tag === HostText) {
3664 bookKeeping.ancestors.push(ancestor);
3665 }
3666
3667 ancestor = getClosestInstanceFromNode(root);
3668 } while (ancestor);
3669
3670 for (var i = 0; i < bookKeeping.ancestors.length; i++) {
3671 targetInst = bookKeeping.ancestors[i];
3672 var eventTarget = getEventTarget(bookKeeping.nativeEvent);
3673 var topLevelType = bookKeeping.topLevelType;
3674 var nativeEvent = bookKeeping.nativeEvent;
3675 var eventSystemFlags = bookKeeping.eventSystemFlags; // If this is the first ancestor, we mark it on the system flags
3676
3677 if (i === 0) {
3678 eventSystemFlags |= IS_FIRST_ANCESTOR;
3679 }
3680
3681 runExtractedPluginEventsInBatch(topLevelType, targetInst, nativeEvent, eventTarget, eventSystemFlags);
3682 }
3683 }
3684
3685 function dispatchEventForLegacyPluginEventSystem(topLevelType, eventSystemFlags, nativeEvent, targetInst) {
3686 var bookKeeping = getTopLevelCallbackBookKeeping(topLevelType, nativeEvent, targetInst, eventSystemFlags);
3687
3688 try {
3689 // Event queue being processed in the same cycle allows
3690 // `preventDefault`.
3691 batchedEventUpdates(handleTopLevel, bookKeeping);
3692 } finally {
3693 releaseTopLevelCallbackBookKeeping(bookKeeping);
3694 }
3695 }
3696 /**
3697 * We listen for bubbled touch events on the document object.
3698 *
3699 * Firefox v8.01 (and possibly others) exhibited strange behavior when
3700 * mounting `onmousemove` events at some node that was not the document
3701 * element. The symptoms were that if your mouse is not moving over something
3702 * contained within that mount point (for example on the background) the
3703 * top-level listeners for `onmousemove` won't be called. However, if you
3704 * register the `mousemove` on the document object, then it will of course
3705 * catch all `mousemove`s. This along with iOS quirks, justifies restricting
3706 * top-level listeners to the document object only, at least for these
3707 * movement types of events and possibly all events.
3708 *
3709 * @see http://www.quirksmode.org/blog/archives/2010/09/click_event_del.html
3710 *
3711 * Also, `keyup`/`keypress`/`keydown` do not bubble to the window on IE, but
3712 * they bubble to document.
3713 *
3714 * @param {string} registrationName Name of listener (e.g. `onClick`).
3715 * @param {object} mountAt Container where to mount the listener
3716 */
3717
3718 function legacyListenToEvent(registrationName, mountAt) {
3719 var listenerMap = getListenerMapForElement(mountAt);
3720 var dependencies = registrationNameDependencies[registrationName];
3721
3722 for (var i = 0; i < dependencies.length; i++) {
3723 var dependency = dependencies[i];
3724 legacyListenToTopLevelEvent(dependency, mountAt, listenerMap);
3725 }
3726 }
3727 function legacyListenToTopLevelEvent(topLevelType, mountAt, listenerMap) {
3728 if (!listenerMap.has(topLevelType)) {
3729 switch (topLevelType) {
3730 case TOP_SCROLL:
3731 trapCapturedEvent(TOP_SCROLL, mountAt);
3732 break;
3733
3734 case TOP_FOCUS:
3735 case TOP_BLUR:
3736 trapCapturedEvent(TOP_FOCUS, mountAt);
3737 trapCapturedEvent(TOP_BLUR, mountAt); // We set the flag for a single dependency later in this function,
3738 // but this ensures we mark both as attached rather than just one.
3739
3740 listenerMap.set(TOP_BLUR, null);
3741 listenerMap.set(TOP_FOCUS, null);
3742 break;
3743
3744 case TOP_CANCEL:
3745 case TOP_CLOSE:
3746 if (isEventSupported(getRawEventName(topLevelType))) {
3747 trapCapturedEvent(topLevelType, mountAt);
3748 }
3749
3750 break;
3751
3752 case TOP_INVALID:
3753 case TOP_SUBMIT:
3754 case TOP_RESET:
3755 // We listen to them on the target DOM elements.
3756 // Some of them bubble so we don't want them to fire twice.
3757 break;
3758
3759 default:
3760 // By default, listen on the top level to all non-media events.
3761 // Media events don't bubble so adding the listener wouldn't do anything.
3762 var isMediaEvent = mediaEventTypes.indexOf(topLevelType) !== -1;
3763
3764 if (!isMediaEvent) {
3765 trapBubbledEvent(topLevelType, mountAt);
3766 }
3767
3768 break;
3769 }
3770
3771 listenerMap.set(topLevelType, null);
3772 }
3773 }
3774 function isListeningToAllDependencies(registrationName, mountAt) {
3775 var listenerMap = getListenerMapForElement(mountAt);
3776 var dependencies = registrationNameDependencies[registrationName];
3777
3778 for (var i = 0; i < dependencies.length; i++) {
3779 var dependency = dependencies[i];
3780
3781 if (!listenerMap.has(dependency)) {
3782 return false;
3783 }
3784 }
3785
3786 return true;
3787 }
3788
3789 var attemptUserBlockingHydration;
3790 function setAttemptUserBlockingHydration(fn) {
3791 attemptUserBlockingHydration = fn;
3792 }
3793 var attemptContinuousHydration;
3794 function setAttemptContinuousHydration(fn) {
3795 attemptContinuousHydration = fn;
3796 }
3797 var attemptHydrationAtCurrentPriority;
3798 function setAttemptHydrationAtCurrentPriority(fn) {
3799 attemptHydrationAtCurrentPriority = fn;
3800 } // TODO: Upgrade this definition once we're on a newer version of Flow that
3801 var hasScheduledReplayAttempt = false; // The queue of discrete events to be replayed.
3802
3803 var queuedDiscreteEvents = []; // Indicates if any continuous event targets are non-null for early bailout.
3804 // if the last target was dehydrated.
3805
3806 var queuedFocus = null;
3807 var queuedDrag = null;
3808 var queuedMouse = null; // For pointer events there can be one latest event per pointerId.
3809
3810 var queuedPointers = new Map();
3811 var queuedPointerCaptures = new Map(); // We could consider replaying selectionchange and touchmoves too.
3812
3813 var queuedExplicitHydrationTargets = [];
3814 function hasQueuedDiscreteEvents() {
3815 return queuedDiscreteEvents.length > 0;
3816 }
3817 var discreteReplayableEvents = [TOP_MOUSE_DOWN, TOP_MOUSE_UP, TOP_TOUCH_CANCEL, TOP_TOUCH_END, TOP_TOUCH_START, TOP_AUX_CLICK, TOP_DOUBLE_CLICK, TOP_POINTER_CANCEL, TOP_POINTER_DOWN, TOP_POINTER_UP, TOP_DRAG_END, TOP_DRAG_START, TOP_DROP, TOP_COMPOSITION_END, TOP_COMPOSITION_START, TOP_KEY_DOWN, TOP_KEY_PRESS, TOP_KEY_UP, TOP_INPUT, TOP_TEXT_INPUT, TOP_CLOSE, TOP_CANCEL, TOP_COPY, TOP_CUT, TOP_PASTE, TOP_CLICK, TOP_CHANGE, TOP_CONTEXT_MENU, TOP_RESET, TOP_SUBMIT];
3818 var continuousReplayableEvents = [TOP_FOCUS, TOP_BLUR, TOP_DRAG_ENTER, TOP_DRAG_LEAVE, TOP_MOUSE_OVER, TOP_MOUSE_OUT, TOP_POINTER_OVER, TOP_POINTER_OUT, TOP_GOT_POINTER_CAPTURE, TOP_LOST_POINTER_CAPTURE];
3819 function isReplayableDiscreteEvent(eventType) {
3820 return discreteReplayableEvents.indexOf(eventType) > -1;
3821 }
3822
3823 function trapReplayableEventForDocument(topLevelType, document, listenerMap) {
3824 legacyListenToTopLevelEvent(topLevelType, document, listenerMap);
3825 }
3826
3827 function eagerlyTrapReplayableEvents(container, document) {
3828 var listenerMapForDoc = getListenerMapForElement(document); // Discrete
3829
3830 discreteReplayableEvents.forEach(function (topLevelType) {
3831 trapReplayableEventForDocument(topLevelType, document, listenerMapForDoc);
3832 }); // Continuous
3833
3834 continuousReplayableEvents.forEach(function (topLevelType) {
3835 trapReplayableEventForDocument(topLevelType, document, listenerMapForDoc);
3836 });
3837 }
3838
3839 function createQueuedReplayableEvent(blockedOn, topLevelType, eventSystemFlags, container, nativeEvent) {
3840 return {
3841 blockedOn: blockedOn,
3842 topLevelType: topLevelType,
3843 eventSystemFlags: eventSystemFlags | IS_REPLAYED,
3844 nativeEvent: nativeEvent,
3845 container: container
3846 };
3847 }
3848
3849 function queueDiscreteEvent(blockedOn, topLevelType, eventSystemFlags, container, nativeEvent) {
3850 var queuedEvent = createQueuedReplayableEvent(blockedOn, topLevelType, eventSystemFlags, container, nativeEvent);
3851 queuedDiscreteEvents.push(queuedEvent);
3852 } // Resets the replaying for this type of continuous event to no event.
3853
3854 function clearIfContinuousEvent(topLevelType, nativeEvent) {
3855 switch (topLevelType) {
3856 case TOP_FOCUS:
3857 case TOP_BLUR:
3858 queuedFocus = null;
3859 break;
3860
3861 case TOP_DRAG_ENTER:
3862 case TOP_DRAG_LEAVE:
3863 queuedDrag = null;
3864 break;
3865
3866 case TOP_MOUSE_OVER:
3867 case TOP_MOUSE_OUT:
3868 queuedMouse = null;
3869 break;
3870
3871 case TOP_POINTER_OVER:
3872 case TOP_POINTER_OUT:
3873 {
3874 var pointerId = nativeEvent.pointerId;
3875 queuedPointers.delete(pointerId);
3876 break;
3877 }
3878
3879 case TOP_GOT_POINTER_CAPTURE:
3880 case TOP_LOST_POINTER_CAPTURE:
3881 {
3882 var _pointerId = nativeEvent.pointerId;
3883 queuedPointerCaptures.delete(_pointerId);
3884 break;
3885 }
3886 }
3887 }
3888
3889 function accumulateOrCreateContinuousQueuedReplayableEvent(existingQueuedEvent, blockedOn, topLevelType, eventSystemFlags, container, nativeEvent) {
3890 if (existingQueuedEvent === null || existingQueuedEvent.nativeEvent !== nativeEvent) {
3891 var queuedEvent = createQueuedReplayableEvent(blockedOn, topLevelType, eventSystemFlags, container, nativeEvent);
3892
3893 if (blockedOn !== null) {
3894 var _fiber2 = getInstanceFromNode$1(blockedOn);
3895
3896 if (_fiber2 !== null) {
3897 // Attempt to increase the priority of this target.
3898 attemptContinuousHydration(_fiber2);
3899 }
3900 }
3901
3902 return queuedEvent;
3903 } // If we have already queued this exact event, then it's because
3904 // the different event systems have different DOM event listeners.
3905 // We can accumulate the flags and store a single event to be
3906 // replayed.
3907
3908
3909 existingQueuedEvent.eventSystemFlags |= eventSystemFlags;
3910 return existingQueuedEvent;
3911 }
3912
3913 function queueIfContinuousEvent(blockedOn, topLevelType, eventSystemFlags, container, nativeEvent) {
3914 // These set relatedTarget to null because the replayed event will be treated as if we
3915 // moved from outside the window (no target) onto the target once it hydrates.
3916 // Instead of mutating we could clone the event.
3917 switch (topLevelType) {
3918 case TOP_FOCUS:
3919 {
3920 var focusEvent = nativeEvent;
3921 queuedFocus = accumulateOrCreateContinuousQueuedReplayableEvent(queuedFocus, blockedOn, topLevelType, eventSystemFlags, container, focusEvent);
3922 return true;
3923 }
3924
3925 case TOP_DRAG_ENTER:
3926 {
3927 var dragEvent = nativeEvent;
3928 queuedDrag = accumulateOrCreateContinuousQueuedReplayableEvent(queuedDrag, blockedOn, topLevelType, eventSystemFlags, container, dragEvent);
3929 return true;
3930 }
3931
3932 case TOP_MOUSE_OVER:
3933 {
3934 var mouseEvent = nativeEvent;
3935 queuedMouse = accumulateOrCreateContinuousQueuedReplayableEvent(queuedMouse, blockedOn, topLevelType, eventSystemFlags, container, mouseEvent);
3936 return true;
3937 }
3938
3939 case TOP_POINTER_OVER:
3940 {
3941 var pointerEvent = nativeEvent;
3942 var pointerId = pointerEvent.pointerId;
3943 queuedPointers.set(pointerId, accumulateOrCreateContinuousQueuedReplayableEvent(queuedPointers.get(pointerId) || null, blockedOn, topLevelType, eventSystemFlags, container, pointerEvent));
3944 return true;
3945 }
3946
3947 case TOP_GOT_POINTER_CAPTURE:
3948 {
3949 var _pointerEvent = nativeEvent;
3950 var _pointerId2 = _pointerEvent.pointerId;
3951 queuedPointerCaptures.set(_pointerId2, accumulateOrCreateContinuousQueuedReplayableEvent(queuedPointerCaptures.get(_pointerId2) || null, blockedOn, topLevelType, eventSystemFlags, container, _pointerEvent));
3952 return true;
3953 }
3954 }
3955
3956 return false;
3957 } // Check if this target is unblocked. Returns true if it's unblocked.
3958
3959 function attemptExplicitHydrationTarget(queuedTarget) {
3960 // TODO: This function shares a lot of logic with attemptToDispatchEvent.
3961 // Try to unify them. It's a bit tricky since it would require two return
3962 // values.
3963 var targetInst = getClosestInstanceFromNode(queuedTarget.target);
3964
3965 if (targetInst !== null) {
3966 var nearestMounted = getNearestMountedFiber(targetInst);
3967
3968 if (nearestMounted !== null) {
3969 var tag = nearestMounted.tag;
3970
3971 if (tag === SuspenseComponent) {
3972 var instance = getSuspenseInstanceFromFiber(nearestMounted);
3973
3974 if (instance !== null) {
3975 // We're blocked on hydrating this boundary.
3976 // Increase its priority.
3977 queuedTarget.blockedOn = instance;
3978 unstable_runWithPriority(queuedTarget.priority, function () {
3979 attemptHydrationAtCurrentPriority(nearestMounted);
3980 });
3981 return;
3982 }
3983 } else if (tag === HostRoot) {
3984 var root = nearestMounted.stateNode;
3985
3986 if (root.hydrate) {
3987 queuedTarget.blockedOn = getContainerFromFiber(nearestMounted); // We don't currently have a way to increase the priority of
3988 // a root other than sync.
3989
3990 return;
3991 }
3992 }
3993 }
3994 }
3995
3996 queuedTarget.blockedOn = null;
3997 }
3998
3999 function attemptReplayContinuousQueuedEvent(queuedEvent) {
4000 if (queuedEvent.blockedOn !== null) {
4001 return false;
4002 }
4003
4004 var nextBlockedOn = attemptToDispatchEvent(queuedEvent.topLevelType, queuedEvent.eventSystemFlags, queuedEvent.container, queuedEvent.nativeEvent);
4005
4006 if (nextBlockedOn !== null) {
4007 // We're still blocked. Try again later.
4008 var _fiber3 = getInstanceFromNode$1(nextBlockedOn);
4009
4010 if (_fiber3 !== null) {
4011 attemptContinuousHydration(_fiber3);
4012 }
4013
4014 queuedEvent.blockedOn = nextBlockedOn;
4015 return false;
4016 }
4017
4018 return true;
4019 }
4020
4021 function attemptReplayContinuousQueuedEventInMap(queuedEvent, key, map) {
4022 if (attemptReplayContinuousQueuedEvent(queuedEvent)) {
4023 map.delete(key);
4024 }
4025 }
4026
4027 function replayUnblockedEvents() {
4028 hasScheduledReplayAttempt = false; // First replay discrete events.
4029
4030 while (queuedDiscreteEvents.length > 0) {
4031 var nextDiscreteEvent = queuedDiscreteEvents[0];
4032
4033 if (nextDiscreteEvent.blockedOn !== null) {
4034 // We're still blocked.
4035 // Increase the priority of this boundary to unblock
4036 // the next discrete event.
4037 var _fiber4 = getInstanceFromNode$1(nextDiscreteEvent.blockedOn);
4038
4039 if (_fiber4 !== null) {
4040 attemptUserBlockingHydration(_fiber4);
4041 }
4042
4043 break;
4044 }
4045
4046 var nextBlockedOn = attemptToDispatchEvent(nextDiscreteEvent.topLevelType, nextDiscreteEvent.eventSystemFlags, nextDiscreteEvent.container, nextDiscreteEvent.nativeEvent);
4047
4048 if (nextBlockedOn !== null) {
4049 // We're still blocked. Try again later.
4050 nextDiscreteEvent.blockedOn = nextBlockedOn;
4051 } else {
4052 // We've successfully replayed the first event. Let's try the next one.
4053 queuedDiscreteEvents.shift();
4054 }
4055 } // Next replay any continuous events.
4056
4057
4058 if (queuedFocus !== null && attemptReplayContinuousQueuedEvent(queuedFocus)) {
4059 queuedFocus = null;
4060 }
4061
4062 if (queuedDrag !== null && attemptReplayContinuousQueuedEvent(queuedDrag)) {
4063 queuedDrag = null;
4064 }
4065
4066 if (queuedMouse !== null && attemptReplayContinuousQueuedEvent(queuedMouse)) {
4067 queuedMouse = null;
4068 }
4069
4070 queuedPointers.forEach(attemptReplayContinuousQueuedEventInMap);
4071 queuedPointerCaptures.forEach(attemptReplayContinuousQueuedEventInMap);
4072 }
4073
4074 function scheduleCallbackIfUnblocked(queuedEvent, unblocked) {
4075 if (queuedEvent.blockedOn === unblocked) {
4076 queuedEvent.blockedOn = null;
4077
4078 if (!hasScheduledReplayAttempt) {
4079 hasScheduledReplayAttempt = true; // Schedule a callback to attempt replaying as many events as are
4080 // now unblocked. This first might not actually be unblocked yet.
4081 // We could check it early to avoid scheduling an unnecessary callback.
4082
4083 unstable_scheduleCallback(unstable_NormalPriority, replayUnblockedEvents);
4084 }
4085 }
4086 }
4087
4088 function retryIfBlockedOn(unblocked) {
4089 // Mark anything that was blocked on this as no longer blocked
4090 // and eligible for a replay.
4091 if (queuedDiscreteEvents.length > 0) {
4092 scheduleCallbackIfUnblocked(queuedDiscreteEvents[0], unblocked); // This is a exponential search for each boundary that commits. I think it's
4093 // worth it because we expect very few discrete events to queue up and once
4094 // we are actually fully unblocked it will be fast to replay them.
4095
4096 for (var i = 1; i < queuedDiscreteEvents.length; i++) {
4097 var queuedEvent = queuedDiscreteEvents[i];
4098
4099 if (queuedEvent.blockedOn === unblocked) {
4100 queuedEvent.blockedOn = null;
4101 }
4102 }
4103 }
4104
4105 if (queuedFocus !== null) {
4106 scheduleCallbackIfUnblocked(queuedFocus, unblocked);
4107 }
4108
4109 if (queuedDrag !== null) {
4110 scheduleCallbackIfUnblocked(queuedDrag, unblocked);
4111 }
4112
4113 if (queuedMouse !== null) {
4114 scheduleCallbackIfUnblocked(queuedMouse, unblocked);
4115 }
4116
4117 var unblock = function (queuedEvent) {
4118 return scheduleCallbackIfUnblocked(queuedEvent, unblocked);
4119 };
4120
4121 queuedPointers.forEach(unblock);
4122 queuedPointerCaptures.forEach(unblock);
4123
4124 for (var _i = 0; _i < queuedExplicitHydrationTargets.length; _i++) {
4125 var queuedTarget = queuedExplicitHydrationTargets[_i];
4126
4127 if (queuedTarget.blockedOn === unblocked) {
4128 queuedTarget.blockedOn = null;
4129 }
4130 }
4131
4132 while (queuedExplicitHydrationTargets.length > 0) {
4133 var nextExplicitTarget = queuedExplicitHydrationTargets[0];
4134
4135 if (nextExplicitTarget.blockedOn !== null) {
4136 // We're still blocked.
4137 break;
4138 } else {
4139 attemptExplicitHydrationTarget(nextExplicitTarget);
4140
4141 if (nextExplicitTarget.blockedOn === null) {
4142 // We're unblocked.
4143 queuedExplicitHydrationTargets.shift();
4144 }
4145 }
4146 }
4147 }
4148
4149 function addEventBubbleListener(element, eventType, listener) {
4150 element.addEventListener(eventType, listener, false);
4151 }
4152 function addEventCaptureListener(element, eventType, listener) {
4153 element.addEventListener(eventType, listener, true);
4154 }
4155
4156 // do it in two places, which duplicates logic
4157 // and increases the bundle size, we do it all
4158 // here once. If we remove or refactor the
4159 // SimpleEventPlugin, we should also remove or
4160 // update the below line.
4161
4162 var simpleEventPluginEventTypes = {};
4163 var topLevelEventsToDispatchConfig = new Map();
4164 var eventPriorities = new Map(); // We store most of the events in this module in pairs of two strings so we can re-use
4165 // the code required to apply the same logic for event prioritization and that of the
4166 // SimpleEventPlugin. This complicates things slightly, but the aim is to reduce code
4167 // duplication (for which there would be quite a bit). For the events that are not needed
4168 // for the SimpleEventPlugin (otherDiscreteEvents) we process them separately as an
4169 // array of top level events.
4170 // Lastly, we ignore prettier so we can keep the formatting sane.
4171 // prettier-ignore
4172
4173 var discreteEventPairsForSimpleEventPlugin = [TOP_BLUR, 'blur', TOP_CANCEL, 'cancel', TOP_CLICK, 'click', TOP_CLOSE, 'close', TOP_CONTEXT_MENU, 'contextMenu', TOP_COPY, 'copy', TOP_CUT, 'cut', TOP_AUX_CLICK, 'auxClick', TOP_DOUBLE_CLICK, 'doubleClick', TOP_DRAG_END, 'dragEnd', TOP_DRAG_START, 'dragStart', TOP_DROP, 'drop', TOP_FOCUS, 'focus', TOP_INPUT, 'input', TOP_INVALID, 'invalid', TOP_KEY_DOWN, 'keyDown', TOP_KEY_PRESS, 'keyPress', TOP_KEY_UP, 'keyUp', TOP_MOUSE_DOWN, 'mouseDown', TOP_MOUSE_UP, 'mouseUp', TOP_PASTE, 'paste', TOP_PAUSE, 'pause', TOP_PLAY, 'play', TOP_POINTER_CANCEL, 'pointerCancel', TOP_POINTER_DOWN, 'pointerDown', TOP_POINTER_UP, 'pointerUp', TOP_RATE_CHANGE, 'rateChange', TOP_RESET, 'reset', TOP_SEEKED, 'seeked', TOP_SUBMIT, 'submit', TOP_TOUCH_CANCEL, 'touchCancel', TOP_TOUCH_END, 'touchEnd', TOP_TOUCH_START, 'touchStart', TOP_VOLUME_CHANGE, 'volumeChange'];
4174 var otherDiscreteEvents = [TOP_CHANGE, TOP_SELECTION_CHANGE, TOP_TEXT_INPUT, TOP_COMPOSITION_START, TOP_COMPOSITION_END, TOP_COMPOSITION_UPDATE]; // prettier-ignore
4175
4176 var userBlockingPairsForSimpleEventPlugin = [TOP_DRAG, 'drag', TOP_DRAG_ENTER, 'dragEnter', TOP_DRAG_EXIT, 'dragExit', TOP_DRAG_LEAVE, 'dragLeave', TOP_DRAG_OVER, 'dragOver', TOP_MOUSE_MOVE, 'mouseMove', TOP_MOUSE_OUT, 'mouseOut', TOP_MOUSE_OVER, 'mouseOver', TOP_POINTER_MOVE, 'pointerMove', TOP_POINTER_OUT, 'pointerOut', TOP_POINTER_OVER, 'pointerOver', TOP_SCROLL, 'scroll', TOP_TOGGLE, 'toggle', TOP_TOUCH_MOVE, 'touchMove', TOP_WHEEL, 'wheel']; // prettier-ignore
4177
4178 var continuousPairsForSimpleEventPlugin = [TOP_ABORT, 'abort', TOP_ANIMATION_END, 'animationEnd', TOP_ANIMATION_ITERATION, 'animationIteration', TOP_ANIMATION_START, 'animationStart', TOP_CAN_PLAY, 'canPlay', TOP_CAN_PLAY_THROUGH, 'canPlayThrough', TOP_DURATION_CHANGE, 'durationChange', TOP_EMPTIED, 'emptied', TOP_ENCRYPTED, 'encrypted', TOP_ENDED, 'ended', TOP_ERROR, 'error', TOP_GOT_POINTER_CAPTURE, 'gotPointerCapture', TOP_LOAD, 'load', TOP_LOADED_DATA, 'loadedData', TOP_LOADED_METADATA, 'loadedMetadata', TOP_LOAD_START, 'loadStart', TOP_LOST_POINTER_CAPTURE, 'lostPointerCapture', TOP_PLAYING, 'playing', TOP_PROGRESS, 'progress', TOP_SEEKING, 'seeking', TOP_STALLED, 'stalled', TOP_SUSPEND, 'suspend', TOP_TIME_UPDATE, 'timeUpdate', TOP_TRANSITION_END, 'transitionEnd', TOP_WAITING, 'waiting'];
4179 /**
4180 * Turns
4181 * ['abort', ...]
4182 * into
4183 * eventTypes = {
4184 * 'abort': {
4185 * phasedRegistrationNames: {
4186 * bubbled: 'onAbort',
4187 * captured: 'onAbortCapture',
4188 * },
4189 * dependencies: [TOP_ABORT],
4190 * },
4191 * ...
4192 * };
4193 * topLevelEventsToDispatchConfig = new Map([
4194 * [TOP_ABORT, { sameConfig }],
4195 * ]);
4196 */
4197
4198 function processSimpleEventPluginPairsByPriority(eventTypes, priority) {
4199 // As the event types are in pairs of two, we need to iterate
4200 // through in twos. The events are in pairs of two to save code
4201 // and improve init perf of processing this array, as it will
4202 // result in far fewer object allocations and property accesses
4203 // if we only use three arrays to process all the categories of
4204 // instead of tuples.
4205 for (var i = 0; i < eventTypes.length; i += 2) {
4206 var topEvent = eventTypes[i];
4207 var event = eventTypes[i + 1];
4208 var capitalizedEvent = event[0].toUpperCase() + event.slice(1);
4209 var onEvent = 'on' + capitalizedEvent;
4210 var config = {
4211 phasedRegistrationNames: {
4212 bubbled: onEvent,
4213 captured: onEvent + 'Capture'
4214 },
4215 dependencies: [topEvent],
4216 eventPriority: priority
4217 };
4218 eventPriorities.set(topEvent, priority);
4219 topLevelEventsToDispatchConfig.set(topEvent, config);
4220 simpleEventPluginEventTypes[event] = config;
4221 }
4222 }
4223
4224 function processTopEventPairsByPriority(eventTypes, priority) {
4225 for (var i = 0; i < eventTypes.length; i++) {
4226 eventPriorities.set(eventTypes[i], priority);
4227 }
4228 } // SimpleEventPlugin
4229
4230
4231 processSimpleEventPluginPairsByPriority(discreteEventPairsForSimpleEventPlugin, DiscreteEvent);
4232 processSimpleEventPluginPairsByPriority(userBlockingPairsForSimpleEventPlugin, UserBlockingEvent);
4233 processSimpleEventPluginPairsByPriority(continuousPairsForSimpleEventPlugin, ContinuousEvent); // Not used by SimpleEventPlugin
4234
4235 processTopEventPairsByPriority(otherDiscreteEvents, DiscreteEvent);
4236 function getEventPriorityForPluginSystem(topLevelType) {
4237 var priority = eventPriorities.get(topLevelType); // Default to a ContinuousEvent. Note: we might
4238 // want to warn if we can't detect the priority
4239 // for the event.
4240
4241 return priority === undefined ? ContinuousEvent : priority;
4242 }
4243
4244 // Intentionally not named imports because Rollup would use dynamic dispatch for
4245 var UserBlockingPriority = unstable_UserBlockingPriority,
4246 runWithPriority = unstable_runWithPriority; // TODO: can we stop exporting these?
4247
4248 var _enabled = true;
4249 function setEnabled(enabled) {
4250 _enabled = !!enabled;
4251 }
4252 function isEnabled() {
4253 return _enabled;
4254 }
4255 function trapBubbledEvent(topLevelType, element) {
4256 trapEventForPluginEventSystem(element, topLevelType, false);
4257 }
4258 function trapCapturedEvent(topLevelType, element) {
4259 trapEventForPluginEventSystem(element, topLevelType, true);
4260 }
4261
4262 function trapEventForPluginEventSystem(container, topLevelType, capture) {
4263 var listener;
4264
4265 switch (getEventPriorityForPluginSystem(topLevelType)) {
4266 case DiscreteEvent:
4267 listener = dispatchDiscreteEvent.bind(null, topLevelType, PLUGIN_EVENT_SYSTEM, container);
4268 break;
4269
4270 case UserBlockingEvent:
4271 listener = dispatchUserBlockingUpdate.bind(null, topLevelType, PLUGIN_EVENT_SYSTEM, container);
4272 break;
4273
4274 case ContinuousEvent:
4275 default:
4276 listener = dispatchEvent.bind(null, topLevelType, PLUGIN_EVENT_SYSTEM, container);
4277 break;
4278 }
4279
4280 var rawEventName = getRawEventName(topLevelType);
4281
4282 if (capture) {
4283 addEventCaptureListener(container, rawEventName, listener);
4284 } else {
4285 addEventBubbleListener(container, rawEventName, listener);
4286 }
4287 }
4288
4289 function dispatchDiscreteEvent(topLevelType, eventSystemFlags, container, nativeEvent) {
4290 flushDiscreteUpdatesIfNeeded(nativeEvent.timeStamp);
4291 discreteUpdates(dispatchEvent, topLevelType, eventSystemFlags, container, nativeEvent);
4292 }
4293
4294 function dispatchUserBlockingUpdate(topLevelType, eventSystemFlags, container, nativeEvent) {
4295 runWithPriority(UserBlockingPriority, dispatchEvent.bind(null, topLevelType, eventSystemFlags, container, nativeEvent));
4296 }
4297
4298 function dispatchEvent(topLevelType, eventSystemFlags, container, nativeEvent) {
4299 if (!_enabled) {
4300 return;
4301 }
4302
4303 if (hasQueuedDiscreteEvents() && isReplayableDiscreteEvent(topLevelType)) {
4304 // If we already have a queue of discrete events, and this is another discrete
4305 // event, then we can't dispatch it regardless of its target, since they
4306 // need to dispatch in order.
4307 queueDiscreteEvent(null, // Flags that we're not actually blocked on anything as far as we know.
4308 topLevelType, eventSystemFlags, container, nativeEvent);
4309 return;
4310 }
4311
4312 var blockedOn = attemptToDispatchEvent(topLevelType, eventSystemFlags, container, nativeEvent);
4313
4314 if (blockedOn === null) {
4315 // We successfully dispatched this event.
4316 clearIfContinuousEvent(topLevelType, nativeEvent);
4317 return;
4318 }
4319
4320 if (isReplayableDiscreteEvent(topLevelType)) {
4321 // This this to be replayed later once the target is available.
4322 queueDiscreteEvent(blockedOn, topLevelType, eventSystemFlags, container, nativeEvent);
4323 return;
4324 }
4325
4326 if (queueIfContinuousEvent(blockedOn, topLevelType, eventSystemFlags, container, nativeEvent)) {
4327 return;
4328 } // We need to clear only if we didn't queue because
4329 // queueing is accummulative.
4330
4331
4332 clearIfContinuousEvent(topLevelType, nativeEvent); // This is not replayable so we'll invoke it but without a target,
4333 // in case the event system needs to trace it.
4334
4335 {
4336 dispatchEventForLegacyPluginEventSystem(topLevelType, eventSystemFlags, nativeEvent, null);
4337 }
4338 } // Attempt dispatching an event. Returns a SuspenseInstance or Container if it's blocked.
4339
4340 function attemptToDispatchEvent(topLevelType, eventSystemFlags, container, nativeEvent) {
4341 // TODO: Warn if _enabled is false.
4342 var nativeEventTarget = getEventTarget(nativeEvent);
4343 var targetInst = getClosestInstanceFromNode(nativeEventTarget);
4344
4345 if (targetInst !== null) {
4346 var nearestMounted = getNearestMountedFiber(targetInst);
4347
4348 if (nearestMounted === null) {
4349 // This tree has been unmounted already. Dispatch without a target.
4350 targetInst = null;
4351 } else {
4352 var tag = nearestMounted.tag;
4353
4354 if (tag === SuspenseComponent) {
4355 var instance = getSuspenseInstanceFromFiber(nearestMounted);
4356
4357 if (instance !== null) {
4358 // Queue the event to be replayed later. Abort dispatching since we
4359 // don't want this event dispatched twice through the event system.
4360 // TODO: If this is the first discrete event in the queue. Schedule an increased
4361 // priority for this boundary.
4362 return instance;
4363 } // This shouldn't happen, something went wrong but to avoid blocking
4364 // the whole system, dispatch the event without a target.
4365 // TODO: Warn.
4366
4367
4368 targetInst = null;
4369 } else if (tag === HostRoot) {
4370 var root = nearestMounted.stateNode;
4371
4372 if (root.hydrate) {
4373 // If this happens during a replay something went wrong and it might block
4374 // the whole system.
4375 return getContainerFromFiber(nearestMounted);
4376 }
4377
4378 targetInst = null;
4379 } else if (nearestMounted !== targetInst) {
4380 // If we get an event (ex: img onload) before committing that
4381 // component's mount, ignore it for now (that is, treat it as if it was an
4382 // event on a non-React tree). We might also consider queueing events and
4383 // dispatching them after the mount.
4384 targetInst = null;
4385 }
4386 }
4387 }
4388
4389 {
4390 dispatchEventForLegacyPluginEventSystem(topLevelType, eventSystemFlags, nativeEvent, targetInst);
4391 } // We're not blocked on anything.
4392
4393
4394 return null;
4395 }
4396
4397 // List derived from Gecko source code:
4398 // https://github.com/mozilla/gecko-dev/blob/4e638efc71/layout/style/test/property_database.js
4399 var shorthandToLonghand = {
4400 animation: ['animationDelay', 'animationDirection', 'animationDuration', 'animationFillMode', 'animationIterationCount', 'animationName', 'animationPlayState', 'animationTimingFunction'],
4401 background: ['backgroundAttachment', 'backgroundClip', 'backgroundColor', 'backgroundImage', 'backgroundOrigin', 'backgroundPositionX', 'backgroundPositionY', 'backgroundRepeat', 'backgroundSize'],
4402 backgroundPosition: ['backgroundPositionX', 'backgroundPositionY'],
4403 border: ['borderBottomColor', 'borderBottomStyle', 'borderBottomWidth', 'borderImageOutset', 'borderImageRepeat', 'borderImageSlice', 'borderImageSource', 'borderImageWidth', 'borderLeftColor', 'borderLeftStyle', 'borderLeftWidth', 'borderRightColor', 'borderRightStyle', 'borderRightWidth', 'borderTopColor', 'borderTopStyle', 'borderTopWidth'],
4404 borderBlockEnd: ['borderBlockEndColor', 'borderBlockEndStyle', 'borderBlockEndWidth'],
4405 borderBlockStart: ['borderBlockStartColor', 'borderBlockStartStyle', 'borderBlockStartWidth'],
4406 borderBottom: ['borderBottomColor', 'borderBottomStyle', 'borderBottomWidth'],
4407 borderColor: ['borderBottomColor', 'borderLeftColor', 'borderRightColor', 'borderTopColor'],
4408 borderImage: ['borderImageOutset', 'borderImageRepeat', 'borderImageSlice', 'borderImageSource', 'borderImageWidth'],
4409 borderInlineEnd: ['borderInlineEndColor', 'borderInlineEndStyle', 'borderInlineEndWidth'],
4410 borderInlineStart: ['borderInlineStartColor', 'borderInlineStartStyle', 'borderInlineStartWidth'],
4411 borderLeft: ['borderLeftColor', 'borderLeftStyle', 'borderLeftWidth'],
4412 borderRadius: ['borderBottomLeftRadius', 'borderBottomRightRadius', 'borderTopLeftRadius', 'borderTopRightRadius'],
4413 borderRight: ['borderRightColor', 'borderRightStyle', 'borderRightWidth'],
4414 borderStyle: ['borderBottomStyle', 'borderLeftStyle', 'borderRightStyle', 'borderTopStyle'],
4415 borderTop: ['borderTopColor', 'borderTopStyle', 'borderTopWidth'],
4416 borderWidth: ['borderBottomWidth', 'borderLeftWidth', 'borderRightWidth', 'borderTopWidth'],
4417 columnRule: ['columnRuleColor', 'columnRuleStyle', 'columnRuleWidth'],
4418 columns: ['columnCount', 'columnWidth'],
4419 flex: ['flexBasis', 'flexGrow', 'flexShrink'],
4420 flexFlow: ['flexDirection', 'flexWrap'],
4421 font: ['fontFamily', 'fontFeatureSettings', 'fontKerning', 'fontLanguageOverride', 'fontSize', 'fontSizeAdjust', 'fontStretch', 'fontStyle', 'fontVariant', 'fontVariantAlternates', 'fontVariantCaps', 'fontVariantEastAsian', 'fontVariantLigatures', 'fontVariantNumeric', 'fontVariantPosition', 'fontWeight', 'lineHeight'],
4422 fontVariant: ['fontVariantAlternates', 'fontVariantCaps', 'fontVariantEastAsian', 'fontVariantLigatures', 'fontVariantNumeric', 'fontVariantPosition'],
4423 gap: ['columnGap', 'rowGap'],
4424 grid: ['gridAutoColumns', 'gridAutoFlow', 'gridAutoRows', 'gridTemplateAreas', 'gridTemplateColumns', 'gridTemplateRows'],
4425 gridArea: ['gridColumnEnd', 'gridColumnStart', 'gridRowEnd', 'gridRowStart'],
4426 gridColumn: ['gridColumnEnd', 'gridColumnStart'],
4427 gridColumnGap: ['columnGap'],
4428 gridGap: ['columnGap', 'rowGap'],
4429 gridRow: ['gridRowEnd', 'gridRowStart'],
4430 gridRowGap: ['rowGap'],
4431 gridTemplate: ['gridTemplateAreas', 'gridTemplateColumns', 'gridTemplateRows'],
4432 listStyle: ['listStyleImage', 'listStylePosition', 'listStyleType'],
4433 margin: ['marginBottom', 'marginLeft', 'marginRight', 'marginTop'],
4434 marker: ['markerEnd', 'markerMid', 'markerStart'],
4435 mask: ['maskClip', 'maskComposite', 'maskImage', 'maskMode', 'maskOrigin', 'maskPositionX', 'maskPositionY', 'maskRepeat', 'maskSize'],
4436 maskPosition: ['maskPositionX', 'maskPositionY'],
4437 outline: ['outlineColor', 'outlineStyle', 'outlineWidth'],
4438 overflow: ['overflowX', 'overflowY'],
4439 padding: ['paddingBottom', 'paddingLeft', 'paddingRight', 'paddingTop'],
4440 placeContent: ['alignContent', 'justifyContent'],
4441 placeItems: ['alignItems', 'justifyItems'],
4442 placeSelf: ['alignSelf', 'justifySelf'],
4443 textDecoration: ['textDecorationColor', 'textDecorationLine', 'textDecorationStyle'],
4444 textEmphasis: ['textEmphasisColor', 'textEmphasisStyle'],
4445 transition: ['transitionDelay', 'transitionDuration', 'transitionProperty', 'transitionTimingFunction'],
4446 wordWrap: ['overflowWrap']
4447 };
4448
4449 /**
4450 * CSS properties which accept numbers but are not in units of "px".
4451 */
4452 var isUnitlessNumber = {
4453 animationIterationCount: true,
4454 borderImageOutset: true,
4455 borderImageSlice: true,
4456 borderImageWidth: true,
4457 boxFlex: true,
4458 boxFlexGroup: true,
4459 boxOrdinalGroup: true,
4460 columnCount: true,
4461 columns: true,
4462 flex: true,
4463 flexGrow: true,
4464 flexPositive: true,
4465 flexShrink: true,
4466 flexNegative: true,
4467 flexOrder: true,
4468 gridArea: true,
4469 gridRow: true,
4470 gridRowEnd: true,
4471 gridRowSpan: true,
4472 gridRowStart: true,
4473 gridColumn: true,
4474 gridColumnEnd: true,
4475 gridColumnSpan: true,
4476 gridColumnStart: true,
4477 fontWeight: true,
4478 lineClamp: true,
4479 lineHeight: true,
4480 opacity: true,
4481 order: true,
4482 orphans: true,
4483 tabSize: true,
4484 widows: true,
4485 zIndex: true,
4486 zoom: true,
4487 // SVG-related properties
4488 fillOpacity: true,
4489 floodOpacity: true,
4490 stopOpacity: true,
4491 strokeDasharray: true,
4492 strokeDashoffset: true,
4493 strokeMiterlimit: true,
4494 strokeOpacity: true,
4495 strokeWidth: true
4496 };
4497 /**
4498 * @param {string} prefix vendor-specific prefix, eg: Webkit
4499 * @param {string} key style name, eg: transitionDuration
4500 * @return {string} style name prefixed with `prefix`, properly camelCased, eg:
4501 * WebkitTransitionDuration
4502 */
4503
4504 function prefixKey(prefix, key) {
4505 return prefix + key.charAt(0).toUpperCase() + key.substring(1);
4506 }
4507 /**
4508 * Support style names that may come passed in prefixed by adding permutations
4509 * of vendor prefixes.
4510 */
4511
4512
4513 var prefixes = ['Webkit', 'ms', 'Moz', 'O']; // Using Object.keys here, or else the vanilla for-in loop makes IE8 go into an
4514 // infinite loop, because it iterates over the newly added props too.
4515
4516 Object.keys(isUnitlessNumber).forEach(function (prop) {
4517 prefixes.forEach(function (prefix) {
4518 isUnitlessNumber[prefixKey(prefix, prop)] = isUnitlessNumber[prop];
4519 });
4520 });
4521
4522 /**
4523 * Convert a value into the proper css writable value. The style name `name`
4524 * should be logical (no hyphens), as specified
4525 * in `CSSProperty.isUnitlessNumber`.
4526 *
4527 * @param {string} name CSS property name such as `topMargin`.
4528 * @param {*} value CSS property value such as `10px`.
4529 * @return {string} Normalized style value with dimensions applied.
4530 */
4531
4532 function dangerousStyleValue(name, value, isCustomProperty) {
4533 // Note that we've removed escapeTextForBrowser() calls here since the
4534 // whole string will be escaped when the attribute is injected into
4535 // the markup. If you provide unsafe user data here they can inject
4536 // arbitrary CSS which may be problematic (I couldn't repro this):
4537 // https://www.owasp.org/index.php/XSS_Filter_Evasion_Cheat_Sheet
4538 // http://www.thespanner.co.uk/2007/11/26/ultimate-xss-css-injection/
4539 // This is not an XSS hole but instead a potential CSS injection issue
4540 // which has lead to a greater discussion about how we're going to
4541 // trust URLs moving forward. See #2115901
4542 var isEmpty = value == null || typeof value === 'boolean' || value === '';
4543
4544 if (isEmpty) {
4545 return '';
4546 }
4547
4548 if (!isCustomProperty && typeof value === 'number' && value !== 0 && !(isUnitlessNumber.hasOwnProperty(name) && isUnitlessNumber[name])) {
4549 return value + 'px'; // Presumes implicit 'px' suffix for unitless numbers
4550 }
4551
4552 return ('' + value).trim();
4553 }
4554
4555 var uppercasePattern = /([A-Z])/g;
4556 var msPattern = /^ms-/;
4557 /**
4558 * Hyphenates a camelcased CSS property name, for example:
4559 *
4560 * > hyphenateStyleName('backgroundColor')
4561 * < "background-color"
4562 * > hyphenateStyleName('MozTransition')
4563 * < "-moz-transition"
4564 * > hyphenateStyleName('msTransition')
4565 * < "-ms-transition"
4566 *
4567 * As Modernizr suggests (http://modernizr.com/docs/#prefixed), an `ms` prefix
4568 * is converted to `-ms-`.
4569 */
4570
4571 function hyphenateStyleName(name) {
4572 return name.replace(uppercasePattern, '-$1').toLowerCase().replace(msPattern, '-ms-');
4573 }
4574
4575 var warnValidStyle = function () {};
4576
4577 {
4578 // 'msTransform' is correct, but the other prefixes should be capitalized
4579 var badVendoredStyleNamePattern = /^(?:webkit|moz|o)[A-Z]/;
4580 var msPattern$1 = /^-ms-/;
4581 var hyphenPattern = /-(.)/g; // style values shouldn't contain a semicolon
4582
4583 var badStyleValueWithSemicolonPattern = /;\s*$/;
4584 var warnedStyleNames = {};
4585 var warnedStyleValues = {};
4586 var warnedForNaNValue = false;
4587 var warnedForInfinityValue = false;
4588
4589 var camelize = function (string) {
4590 return string.replace(hyphenPattern, function (_, character) {
4591 return character.toUpperCase();
4592 });
4593 };
4594
4595 var warnHyphenatedStyleName = function (name) {
4596 if (warnedStyleNames.hasOwnProperty(name) && warnedStyleNames[name]) {
4597 return;
4598 }
4599
4600 warnedStyleNames[name] = true;
4601
4602 error('Unsupported style property %s. Did you mean %s?', name, // As Andi Smith suggests
4603 // (http://www.andismith.com/blog/2012/02/modernizr-prefixed/), an `-ms` prefix
4604 // is converted to lowercase `ms`.
4605 camelize(name.replace(msPattern$1, 'ms-')));
4606 };
4607
4608 var warnBadVendoredStyleName = function (name) {
4609 if (warnedStyleNames.hasOwnProperty(name) && warnedStyleNames[name]) {
4610 return;
4611 }
4612
4613 warnedStyleNames[name] = true;
4614
4615 error('Unsupported vendor-prefixed style property %s. Did you mean %s?', name, name.charAt(0).toUpperCase() + name.slice(1));
4616 };
4617
4618 var warnStyleValueWithSemicolon = function (name, value) {
4619 if (warnedStyleValues.hasOwnProperty(value) && warnedStyleValues[value]) {
4620 return;
4621 }
4622
4623 warnedStyleValues[value] = true;
4624
4625 error("Style property values shouldn't contain a semicolon. " + 'Try "%s: %s" instead.', name, value.replace(badStyleValueWithSemicolonPattern, ''));
4626 };
4627
4628 var warnStyleValueIsNaN = function (name, value) {
4629 if (warnedForNaNValue) {
4630 return;
4631 }
4632
4633 warnedForNaNValue = true;
4634
4635 error('`NaN` is an invalid value for the `%s` css style property.', name);
4636 };
4637
4638 var warnStyleValueIsInfinity = function (name, value) {
4639 if (warnedForInfinityValue) {
4640 return;
4641 }
4642
4643 warnedForInfinityValue = true;
4644
4645 error('`Infinity` is an invalid value for the `%s` css style property.', name);
4646 };
4647
4648 warnValidStyle = function (name, value) {
4649 if (name.indexOf('-') > -1) {
4650 warnHyphenatedStyleName(name);
4651 } else if (badVendoredStyleNamePattern.test(name)) {
4652 warnBadVendoredStyleName(name);
4653 } else if (badStyleValueWithSemicolonPattern.test(value)) {
4654 warnStyleValueWithSemicolon(name, value);
4655 }
4656
4657 if (typeof value === 'number') {
4658 if (isNaN(value)) {
4659 warnStyleValueIsNaN(name, value);
4660 } else if (!isFinite(value)) {
4661 warnStyleValueIsInfinity(name, value);
4662 }
4663 }
4664 };
4665 }
4666
4667 var warnValidStyle$1 = warnValidStyle;
4668
4669 /**
4670 * Operations for dealing with CSS properties.
4671 */
4672
4673 /**
4674 * This creates a string that is expected to be equivalent to the style
4675 * attribute generated by server-side rendering. It by-passes warnings and
4676 * security checks so it's not safe to use this value for anything other than
4677 * comparison. It is only used in DEV for SSR validation.
4678 */
4679
4680 function createDangerousStringForStyles(styles) {
4681 {
4682 var serialized = '';
4683 var delimiter = '';
4684
4685 for (var styleName in styles) {
4686 if (!styles.hasOwnProperty(styleName)) {
4687 continue;
4688 }
4689
4690 var styleValue = styles[styleName];
4691
4692 if (styleValue != null) {
4693 var isCustomProperty = styleName.indexOf('--') === 0;
4694 serialized += delimiter + (isCustomProperty ? styleName : hyphenateStyleName(styleName)) + ':';
4695 serialized += dangerousStyleValue(styleName, styleValue, isCustomProperty);
4696 delimiter = ';';
4697 }
4698 }
4699
4700 return serialized || null;
4701 }
4702 }
4703 /**
4704 * Sets the value for multiple styles on a node. If a value is specified as
4705 * '' (empty string), the corresponding style property will be unset.
4706 *
4707 * @param {DOMElement} node
4708 * @param {object} styles
4709 */
4710
4711 function setValueForStyles(node, styles) {
4712 var style = node.style;
4713
4714 for (var styleName in styles) {
4715 if (!styles.hasOwnProperty(styleName)) {
4716 continue;
4717 }
4718
4719 var isCustomProperty = styleName.indexOf('--') === 0;
4720
4721 {
4722 if (!isCustomProperty) {
4723 warnValidStyle$1(styleName, styles[styleName]);
4724 }
4725 }
4726
4727 var styleValue = dangerousStyleValue(styleName, styles[styleName], isCustomProperty);
4728
4729 if (styleName === 'float') {
4730 styleName = 'cssFloat';
4731 }
4732
4733 if (isCustomProperty) {
4734 style.setProperty(styleName, styleValue);
4735 } else {
4736 style[styleName] = styleValue;
4737 }
4738 }
4739 }
4740
4741 function isValueEmpty(value) {
4742 return value == null || typeof value === 'boolean' || value === '';
4743 }
4744 /**
4745 * Given {color: 'red', overflow: 'hidden'} returns {
4746 * color: 'color',
4747 * overflowX: 'overflow',
4748 * overflowY: 'overflow',
4749 * }. This can be read as "the overflowY property was set by the overflow
4750 * shorthand". That is, the values are the property that each was derived from.
4751 */
4752
4753
4754 function expandShorthandMap(styles) {
4755 var expanded = {};
4756
4757 for (var key in styles) {
4758 var longhands = shorthandToLonghand[key] || [key];
4759
4760 for (var i = 0; i < longhands.length; i++) {
4761 expanded[longhands[i]] = key;
4762 }
4763 }
4764
4765 return expanded;
4766 }
4767 /**
4768 * When mixing shorthand and longhand property names, we warn during updates if
4769 * we expect an incorrect result to occur. In particular, we warn for:
4770 *
4771 * Updating a shorthand property (longhand gets overwritten):
4772 * {font: 'foo', fontVariant: 'bar'} -> {font: 'baz', fontVariant: 'bar'}
4773 * becomes .style.font = 'baz'
4774 * Removing a shorthand property (longhand gets lost too):
4775 * {font: 'foo', fontVariant: 'bar'} -> {fontVariant: 'bar'}
4776 * becomes .style.font = ''
4777 * Removing a longhand property (should revert to shorthand; doesn't):
4778 * {font: 'foo', fontVariant: 'bar'} -> {font: 'foo'}
4779 * becomes .style.fontVariant = ''
4780 */
4781
4782
4783 function validateShorthandPropertyCollisionInDev(styleUpdates, nextStyles) {
4784 {
4785
4786 if (!nextStyles) {
4787 return;
4788 }
4789
4790 var expandedUpdates = expandShorthandMap(styleUpdates);
4791 var expandedStyles = expandShorthandMap(nextStyles);
4792 var warnedAbout = {};
4793
4794 for (var key in expandedUpdates) {
4795 var originalKey = expandedUpdates[key];
4796 var correctOriginalKey = expandedStyles[key];
4797
4798 if (correctOriginalKey && originalKey !== correctOriginalKey) {
4799 var warningKey = originalKey + ',' + correctOriginalKey;
4800
4801 if (warnedAbout[warningKey]) {
4802 continue;
4803 }
4804
4805 warnedAbout[warningKey] = true;
4806
4807 error('%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);
4808 }
4809 }
4810 }
4811 }
4812
4813 // For HTML, certain tags should omit their close tag. We keep a whitelist for
4814 // those special-case tags.
4815 var omittedCloseTags = {
4816 area: true,
4817 base: true,
4818 br: true,
4819 col: true,
4820 embed: true,
4821 hr: true,
4822 img: true,
4823 input: true,
4824 keygen: true,
4825 link: true,
4826 meta: true,
4827 param: true,
4828 source: true,
4829 track: true,
4830 wbr: true // NOTE: menuitem's close tag should be omitted, but that causes problems.
4831
4832 };
4833
4834 // `omittedCloseTags` except that `menuitem` should still have its closing tag.
4835
4836 var voidElementTags = _assign({
4837 menuitem: true
4838 }, omittedCloseTags);
4839
4840 var HTML = '__html';
4841 var ReactDebugCurrentFrame$3 = null;
4842
4843 {
4844 ReactDebugCurrentFrame$3 = ReactSharedInternals.ReactDebugCurrentFrame;
4845 }
4846
4847 function assertValidProps(tag, props) {
4848 if (!props) {
4849 return;
4850 } // Note the use of `==` which checks for null or undefined.
4851
4852
4853 if (voidElementTags[tag]) {
4854 if (!(props.children == null && props.dangerouslySetInnerHTML == null)) {
4855 {
4856 throw Error( tag + " is a void element tag and must neither have `children` nor use `dangerouslySetInnerHTML`." + ( ReactDebugCurrentFrame$3.getStackAddendum() ) );
4857 }
4858 }
4859 }
4860
4861 if (props.dangerouslySetInnerHTML != null) {
4862 if (!(props.children == null)) {
4863 {
4864 throw Error( "Can only set one of `children` or `props.dangerouslySetInnerHTML`." );
4865 }
4866 }
4867
4868 if (!(typeof props.dangerouslySetInnerHTML === 'object' && HTML in props.dangerouslySetInnerHTML)) {
4869 {
4870 throw Error( "`props.dangerouslySetInnerHTML` must be in the form `{__html: ...}`. Please visit https://fb.me/react-invariant-dangerously-set-inner-html for more information." );
4871 }
4872 }
4873 }
4874
4875 {
4876 if (!props.suppressContentEditableWarning && props.contentEditable && props.children != null) {
4877 error('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.');
4878 }
4879 }
4880
4881 if (!(props.style == null || typeof props.style === 'object')) {
4882 {
4883 throw 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() ) );
4884 }
4885 }
4886 }
4887
4888 function isCustomComponent(tagName, props) {
4889 if (tagName.indexOf('-') === -1) {
4890 return typeof props.is === 'string';
4891 }
4892
4893 switch (tagName) {
4894 // These are reserved SVG and MathML elements.
4895 // We don't mind this whitelist too much because we expect it to never grow.
4896 // The alternative is to track the namespace in a few places which is convoluted.
4897 // https://w3c.github.io/webcomponents/spec/custom/#custom-elements-core-concepts
4898 case 'annotation-xml':
4899 case 'color-profile':
4900 case 'font-face':
4901 case 'font-face-src':
4902 case 'font-face-uri':
4903 case 'font-face-format':
4904 case 'font-face-name':
4905 case 'missing-glyph':
4906 return false;
4907
4908 default:
4909 return true;
4910 }
4911 }
4912
4913 // When adding attributes to the HTML or SVG whitelist, be sure to
4914 // also add them to this module to ensure casing and incorrect name
4915 // warnings.
4916 var possibleStandardNames = {
4917 // HTML
4918 accept: 'accept',
4919 acceptcharset: 'acceptCharset',
4920 'accept-charset': 'acceptCharset',
4921 accesskey: 'accessKey',
4922 action: 'action',
4923 allowfullscreen: 'allowFullScreen',
4924 alt: 'alt',
4925 as: 'as',
4926 async: 'async',
4927 autocapitalize: 'autoCapitalize',
4928 autocomplete: 'autoComplete',
4929 autocorrect: 'autoCorrect',
4930 autofocus: 'autoFocus',
4931 autoplay: 'autoPlay',
4932 autosave: 'autoSave',
4933 capture: 'capture',
4934 cellpadding: 'cellPadding',
4935 cellspacing: 'cellSpacing',
4936 challenge: 'challenge',
4937 charset: 'charSet',
4938 checked: 'checked',
4939 children: 'children',
4940 cite: 'cite',
4941 class: 'className',
4942 classid: 'classID',
4943 classname: 'className',
4944 cols: 'cols',
4945 colspan: 'colSpan',
4946 content: 'content',
4947 contenteditable: 'contentEditable',
4948 contextmenu: 'contextMenu',
4949 controls: 'controls',
4950 controlslist: 'controlsList',
4951 coords: 'coords',
4952 crossorigin: 'crossOrigin',
4953 dangerouslysetinnerhtml: 'dangerouslySetInnerHTML',
4954 data: 'data',
4955 datetime: 'dateTime',
4956 default: 'default',
4957 defaultchecked: 'defaultChecked',
4958 defaultvalue: 'defaultValue',
4959 defer: 'defer',
4960 dir: 'dir',
4961 disabled: 'disabled',
4962 disablepictureinpicture: 'disablePictureInPicture',
4963 download: 'download',
4964 draggable: 'draggable',
4965 enctype: 'encType',
4966 for: 'htmlFor',
4967 form: 'form',
4968 formmethod: 'formMethod',
4969 formaction: 'formAction',
4970 formenctype: 'formEncType',
4971 formnovalidate: 'formNoValidate',
4972 formtarget: 'formTarget',
4973 frameborder: 'frameBorder',
4974 headers: 'headers',
4975 height: 'height',
4976 hidden: 'hidden',
4977 high: 'high',
4978 href: 'href',
4979 hreflang: 'hrefLang',
4980 htmlfor: 'htmlFor',
4981 httpequiv: 'httpEquiv',
4982 'http-equiv': 'httpEquiv',
4983 icon: 'icon',
4984 id: 'id',
4985 innerhtml: 'innerHTML',
4986 inputmode: 'inputMode',
4987 integrity: 'integrity',
4988 is: 'is',
4989 itemid: 'itemID',
4990 itemprop: 'itemProp',
4991 itemref: 'itemRef',
4992 itemscope: 'itemScope',
4993 itemtype: 'itemType',
4994 keyparams: 'keyParams',
4995 keytype: 'keyType',
4996 kind: 'kind',
4997 label: 'label',
4998 lang: 'lang',
4999 list: 'list',
5000 loop: 'loop',
5001 low: 'low',
5002 manifest: 'manifest',
5003 marginwidth: 'marginWidth',
5004 marginheight: 'marginHeight',
5005 max: 'max',
5006 maxlength: 'maxLength',
5007 media: 'media',
5008 mediagroup: 'mediaGroup',
5009 method: 'method',
5010 min: 'min',
5011 minlength: 'minLength',
5012 multiple: 'multiple',
5013 muted: 'muted',
5014 name: 'name',
5015 nomodule: 'noModule',
5016 nonce: 'nonce',
5017 novalidate: 'noValidate',
5018 open: 'open',
5019 optimum: 'optimum',
5020 pattern: 'pattern',
5021 placeholder: 'placeholder',
5022 playsinline: 'playsInline',
5023 poster: 'poster',
5024 preload: 'preload',
5025 profile: 'profile',
5026 radiogroup: 'radioGroup',
5027 readonly: 'readOnly',
5028 referrerpolicy: 'referrerPolicy',
5029 rel: 'rel',
5030 required: 'required',
5031 reversed: 'reversed',
5032 role: 'role',
5033 rows: 'rows',
5034 rowspan: 'rowSpan',
5035 sandbox: 'sandbox',
5036 scope: 'scope',
5037 scoped: 'scoped',
5038 scrolling: 'scrolling',
5039 seamless: 'seamless',
5040 selected: 'selected',
5041 shape: 'shape',
5042 size: 'size',
5043 sizes: 'sizes',
5044 span: 'span',
5045 spellcheck: 'spellCheck',
5046 src: 'src',
5047 srcdoc: 'srcDoc',
5048 srclang: 'srcLang',
5049 srcset: 'srcSet',
5050 start: 'start',
5051 step: 'step',
5052 style: 'style',
5053 summary: 'summary',
5054 tabindex: 'tabIndex',
5055 target: 'target',
5056 title: 'title',
5057 type: 'type',
5058 usemap: 'useMap',
5059 value: 'value',
5060 width: 'width',
5061 wmode: 'wmode',
5062 wrap: 'wrap',
5063 // SVG
5064 about: 'about',
5065 accentheight: 'accentHeight',
5066 'accent-height': 'accentHeight',
5067 accumulate: 'accumulate',
5068 additive: 'additive',
5069 alignmentbaseline: 'alignmentBaseline',
5070 'alignment-baseline': 'alignmentBaseline',
5071 allowreorder: 'allowReorder',
5072 alphabetic: 'alphabetic',
5073 amplitude: 'amplitude',
5074 arabicform: 'arabicForm',
5075 'arabic-form': 'arabicForm',
5076 ascent: 'ascent',
5077 attributename: 'attributeName',
5078 attributetype: 'attributeType',
5079 autoreverse: 'autoReverse',
5080 azimuth: 'azimuth',
5081 basefrequency: 'baseFrequency',
5082 baselineshift: 'baselineShift',
5083 'baseline-shift': 'baselineShift',
5084 baseprofile: 'baseProfile',
5085 bbox: 'bbox',
5086 begin: 'begin',
5087 bias: 'bias',
5088 by: 'by',
5089 calcmode: 'calcMode',
5090 capheight: 'capHeight',
5091 'cap-height': 'capHeight',
5092 clip: 'clip',
5093 clippath: 'clipPath',
5094 'clip-path': 'clipPath',
5095 clippathunits: 'clipPathUnits',
5096 cliprule: 'clipRule',
5097 'clip-rule': 'clipRule',
5098 color: 'color',
5099 colorinterpolation: 'colorInterpolation',
5100 'color-interpolation': 'colorInterpolation',
5101 colorinterpolationfilters: 'colorInterpolationFilters',
5102 'color-interpolation-filters': 'colorInterpolationFilters',
5103 colorprofile: 'colorProfile',
5104 'color-profile': 'colorProfile',
5105 colorrendering: 'colorRendering',
5106 'color-rendering': 'colorRendering',
5107 contentscripttype: 'contentScriptType',
5108 contentstyletype: 'contentStyleType',
5109 cursor: 'cursor',
5110 cx: 'cx',
5111 cy: 'cy',
5112 d: 'd',
5113 datatype: 'datatype',
5114 decelerate: 'decelerate',
5115 descent: 'descent',
5116 diffuseconstant: 'diffuseConstant',
5117 direction: 'direction',
5118 display: 'display',
5119 divisor: 'divisor',
5120 dominantbaseline: 'dominantBaseline',
5121 'dominant-baseline': 'dominantBaseline',
5122 dur: 'dur',
5123 dx: 'dx',
5124 dy: 'dy',
5125 edgemode: 'edgeMode',
5126 elevation: 'elevation',
5127 enablebackground: 'enableBackground',
5128 'enable-background': 'enableBackground',
5129 end: 'end',
5130 exponent: 'exponent',
5131 externalresourcesrequired: 'externalResourcesRequired',
5132 fill: 'fill',
5133 fillopacity: 'fillOpacity',
5134 'fill-opacity': 'fillOpacity',
5135 fillrule: 'fillRule',
5136 'fill-rule': 'fillRule',
5137 filter: 'filter',
5138 filterres: 'filterRes',
5139 filterunits: 'filterUnits',
5140 floodopacity: 'floodOpacity',
5141 'flood-opacity': 'floodOpacity',
5142 floodcolor: 'floodColor',
5143 'flood-color': 'floodColor',
5144 focusable: 'focusable',
5145 fontfamily: 'fontFamily',
5146 'font-family': 'fontFamily',
5147 fontsize: 'fontSize',
5148 'font-size': 'fontSize',
5149 fontsizeadjust: 'fontSizeAdjust',
5150 'font-size-adjust': 'fontSizeAdjust',
5151 fontstretch: 'fontStretch',
5152 'font-stretch': 'fontStretch',
5153 fontstyle: 'fontStyle',
5154 'font-style': 'fontStyle',
5155 fontvariant: 'fontVariant',
5156 'font-variant': 'fontVariant',
5157 fontweight: 'fontWeight',
5158 'font-weight': 'fontWeight',
5159 format: 'format',
5160 from: 'from',
5161 fx: 'fx',
5162 fy: 'fy',
5163 g1: 'g1',
5164 g2: 'g2',
5165 glyphname: 'glyphName',
5166 'glyph-name': 'glyphName',
5167 glyphorientationhorizontal: 'glyphOrientationHorizontal',
5168 'glyph-orientation-horizontal': 'glyphOrientationHorizontal',
5169 glyphorientationvertical: 'glyphOrientationVertical',
5170 'glyph-orientation-vertical': 'glyphOrientationVertical',
5171 glyphref: 'glyphRef',
5172 gradienttransform: 'gradientTransform',
5173 gradientunits: 'gradientUnits',
5174 hanging: 'hanging',
5175 horizadvx: 'horizAdvX',
5176 'horiz-adv-x': 'horizAdvX',
5177 horizoriginx: 'horizOriginX',
5178 'horiz-origin-x': 'horizOriginX',
5179 ideographic: 'ideographic',
5180 imagerendering: 'imageRendering',
5181 'image-rendering': 'imageRendering',
5182 in2: 'in2',
5183 in: 'in',
5184 inlist: 'inlist',
5185 intercept: 'intercept',
5186 k1: 'k1',
5187 k2: 'k2',
5188 k3: 'k3',
5189 k4: 'k4',
5190 k: 'k',
5191 kernelmatrix: 'kernelMatrix',
5192 kernelunitlength: 'kernelUnitLength',
5193 kerning: 'kerning',
5194 keypoints: 'keyPoints',
5195 keysplines: 'keySplines',
5196 keytimes: 'keyTimes',
5197 lengthadjust: 'lengthAdjust',
5198 letterspacing: 'letterSpacing',
5199 'letter-spacing': 'letterSpacing',
5200 lightingcolor: 'lightingColor',
5201 'lighting-color': 'lightingColor',
5202 limitingconeangle: 'limitingConeAngle',
5203 local: 'local',
5204 markerend: 'markerEnd',
5205 'marker-end': 'markerEnd',
5206 markerheight: 'markerHeight',
5207 markermid: 'markerMid',
5208 'marker-mid': 'markerMid',
5209 markerstart: 'markerStart',
5210 'marker-start': 'markerStart',
5211 markerunits: 'markerUnits',
5212 markerwidth: 'markerWidth',
5213 mask: 'mask',
5214 maskcontentunits: 'maskContentUnits',
5215 maskunits: 'maskUnits',
5216 mathematical: 'mathematical',
5217 mode: 'mode',
5218 numoctaves: 'numOctaves',
5219 offset: 'offset',
5220 opacity: 'opacity',
5221 operator: 'operator',
5222 order: 'order',
5223 orient: 'orient',
5224 orientation: 'orientation',
5225 origin: 'origin',
5226 overflow: 'overflow',
5227 overlineposition: 'overlinePosition',
5228 'overline-position': 'overlinePosition',
5229 overlinethickness: 'overlineThickness',
5230 'overline-thickness': 'overlineThickness',
5231 paintorder: 'paintOrder',
5232 'paint-order': 'paintOrder',
5233 panose1: 'panose1',
5234 'panose-1': 'panose1',
5235 pathlength: 'pathLength',
5236 patterncontentunits: 'patternContentUnits',
5237 patterntransform: 'patternTransform',
5238 patternunits: 'patternUnits',
5239 pointerevents: 'pointerEvents',
5240 'pointer-events': 'pointerEvents',
5241 points: 'points',
5242 pointsatx: 'pointsAtX',
5243 pointsaty: 'pointsAtY',
5244 pointsatz: 'pointsAtZ',
5245 prefix: 'prefix',
5246 preservealpha: 'preserveAlpha',
5247 preserveaspectratio: 'preserveAspectRatio',
5248 primitiveunits: 'primitiveUnits',
5249 property: 'property',
5250 r: 'r',
5251 radius: 'radius',
5252 refx: 'refX',
5253 refy: 'refY',
5254 renderingintent: 'renderingIntent',
5255 'rendering-intent': 'renderingIntent',
5256 repeatcount: 'repeatCount',
5257 repeatdur: 'repeatDur',
5258 requiredextensions: 'requiredExtensions',
5259 requiredfeatures: 'requiredFeatures',
5260 resource: 'resource',
5261 restart: 'restart',
5262 result: 'result',
5263 results: 'results',
5264 rotate: 'rotate',
5265 rx: 'rx',
5266 ry: 'ry',
5267 scale: 'scale',
5268 security: 'security',
5269 seed: 'seed',
5270 shaperendering: 'shapeRendering',
5271 'shape-rendering': 'shapeRendering',
5272 slope: 'slope',
5273 spacing: 'spacing',
5274 specularconstant: 'specularConstant',
5275 specularexponent: 'specularExponent',
5276 speed: 'speed',
5277 spreadmethod: 'spreadMethod',
5278 startoffset: 'startOffset',
5279 stddeviation: 'stdDeviation',
5280 stemh: 'stemh',
5281 stemv: 'stemv',
5282 stitchtiles: 'stitchTiles',
5283 stopcolor: 'stopColor',
5284 'stop-color': 'stopColor',
5285 stopopacity: 'stopOpacity',
5286 'stop-opacity': 'stopOpacity',
5287 strikethroughposition: 'strikethroughPosition',
5288 'strikethrough-position': 'strikethroughPosition',
5289 strikethroughthickness: 'strikethroughThickness',
5290 'strikethrough-thickness': 'strikethroughThickness',
5291 string: 'string',
5292 stroke: 'stroke',
5293 strokedasharray: 'strokeDasharray',
5294 'stroke-dasharray': 'strokeDasharray',
5295 strokedashoffset: 'strokeDashoffset',
5296 'stroke-dashoffset': 'strokeDashoffset',
5297 strokelinecap: 'strokeLinecap',
5298 'stroke-linecap': 'strokeLinecap',
5299 strokelinejoin: 'strokeLinejoin',
5300 'stroke-linejoin': 'strokeLinejoin',
5301 strokemiterlimit: 'strokeMiterlimit',
5302 'stroke-miterlimit': 'strokeMiterlimit',
5303 strokewidth: 'strokeWidth',
5304 'stroke-width': 'strokeWidth',
5305 strokeopacity: 'strokeOpacity',
5306 'stroke-opacity': 'strokeOpacity',
5307 suppresscontenteditablewarning: 'suppressContentEditableWarning',
5308 suppresshydrationwarning: 'suppressHydrationWarning',
5309 surfacescale: 'surfaceScale',
5310 systemlanguage: 'systemLanguage',
5311 tablevalues: 'tableValues',
5312 targetx: 'targetX',
5313 targety: 'targetY',
5314 textanchor: 'textAnchor',
5315 'text-anchor': 'textAnchor',
5316 textdecoration: 'textDecoration',
5317 'text-decoration': 'textDecoration',
5318 textlength: 'textLength',
5319 textrendering: 'textRendering',
5320 'text-rendering': 'textRendering',
5321 to: 'to',
5322 transform: 'transform',
5323 typeof: 'typeof',
5324 u1: 'u1',
5325 u2: 'u2',
5326 underlineposition: 'underlinePosition',
5327 'underline-position': 'underlinePosition',
5328 underlinethickness: 'underlineThickness',
5329 'underline-thickness': 'underlineThickness',
5330 unicode: 'unicode',
5331 unicodebidi: 'unicodeBidi',
5332 'unicode-bidi': 'unicodeBidi',
5333 unicoderange: 'unicodeRange',
5334 'unicode-range': 'unicodeRange',
5335 unitsperem: 'unitsPerEm',
5336 'units-per-em': 'unitsPerEm',
5337 unselectable: 'unselectable',
5338 valphabetic: 'vAlphabetic',
5339 'v-alphabetic': 'vAlphabetic',
5340 values: 'values',
5341 vectoreffect: 'vectorEffect',
5342 'vector-effect': 'vectorEffect',
5343 version: 'version',
5344 vertadvy: 'vertAdvY',
5345 'vert-adv-y': 'vertAdvY',
5346 vertoriginx: 'vertOriginX',
5347 'vert-origin-x': 'vertOriginX',
5348 vertoriginy: 'vertOriginY',
5349 'vert-origin-y': 'vertOriginY',
5350 vhanging: 'vHanging',
5351 'v-hanging': 'vHanging',
5352 videographic: 'vIdeographic',
5353 'v-ideographic': 'vIdeographic',
5354 viewbox: 'viewBox',
5355 viewtarget: 'viewTarget',
5356 visibility: 'visibility',
5357 vmathematical: 'vMathematical',
5358 'v-mathematical': 'vMathematical',
5359 vocab: 'vocab',
5360 widths: 'widths',
5361 wordspacing: 'wordSpacing',
5362 'word-spacing': 'wordSpacing',
5363 writingmode: 'writingMode',
5364 'writing-mode': 'writingMode',
5365 x1: 'x1',
5366 x2: 'x2',
5367 x: 'x',
5368 xchannelselector: 'xChannelSelector',
5369 xheight: 'xHeight',
5370 'x-height': 'xHeight',
5371 xlinkactuate: 'xlinkActuate',
5372 'xlink:actuate': 'xlinkActuate',
5373 xlinkarcrole: 'xlinkArcrole',
5374 'xlink:arcrole': 'xlinkArcrole',
5375 xlinkhref: 'xlinkHref',
5376 'xlink:href': 'xlinkHref',
5377 xlinkrole: 'xlinkRole',
5378 'xlink:role': 'xlinkRole',
5379 xlinkshow: 'xlinkShow',
5380 'xlink:show': 'xlinkShow',
5381 xlinktitle: 'xlinkTitle',
5382 'xlink:title': 'xlinkTitle',
5383 xlinktype: 'xlinkType',
5384 'xlink:type': 'xlinkType',
5385 xmlbase: 'xmlBase',
5386 'xml:base': 'xmlBase',
5387 xmllang: 'xmlLang',
5388 'xml:lang': 'xmlLang',
5389 xmlns: 'xmlns',
5390 'xml:space': 'xmlSpace',
5391 xmlnsxlink: 'xmlnsXlink',
5392 'xmlns:xlink': 'xmlnsXlink',
5393 xmlspace: 'xmlSpace',
5394 y1: 'y1',
5395 y2: 'y2',
5396 y: 'y',
5397 ychannelselector: 'yChannelSelector',
5398 z: 'z',
5399 zoomandpan: 'zoomAndPan'
5400 };
5401
5402 var ariaProperties = {
5403 'aria-current': 0,
5404 // state
5405 'aria-details': 0,
5406 'aria-disabled': 0,
5407 // state
5408 'aria-hidden': 0,
5409 // state
5410 'aria-invalid': 0,
5411 // state
5412 'aria-keyshortcuts': 0,
5413 'aria-label': 0,
5414 'aria-roledescription': 0,
5415 // Widget Attributes
5416 'aria-autocomplete': 0,
5417 'aria-checked': 0,
5418 'aria-expanded': 0,
5419 'aria-haspopup': 0,
5420 'aria-level': 0,
5421 'aria-modal': 0,
5422 'aria-multiline': 0,
5423 'aria-multiselectable': 0,
5424 'aria-orientation': 0,
5425 'aria-placeholder': 0,
5426 'aria-pressed': 0,
5427 'aria-readonly': 0,
5428 'aria-required': 0,
5429 'aria-selected': 0,
5430 'aria-sort': 0,
5431 'aria-valuemax': 0,
5432 'aria-valuemin': 0,
5433 'aria-valuenow': 0,
5434 'aria-valuetext': 0,
5435 // Live Region Attributes
5436 'aria-atomic': 0,
5437 'aria-busy': 0,
5438 'aria-live': 0,
5439 'aria-relevant': 0,
5440 // Drag-and-Drop Attributes
5441 'aria-dropeffect': 0,
5442 'aria-grabbed': 0,
5443 // Relationship Attributes
5444 'aria-activedescendant': 0,
5445 'aria-colcount': 0,
5446 'aria-colindex': 0,
5447 'aria-colspan': 0,
5448 'aria-controls': 0,
5449 'aria-describedby': 0,
5450 'aria-errormessage': 0,
5451 'aria-flowto': 0,
5452 'aria-labelledby': 0,
5453 'aria-owns': 0,
5454 'aria-posinset': 0,
5455 'aria-rowcount': 0,
5456 'aria-rowindex': 0,
5457 'aria-rowspan': 0,
5458 'aria-setsize': 0
5459 };
5460
5461 var warnedProperties = {};
5462 var rARIA = new RegExp('^(aria)-[' + ATTRIBUTE_NAME_CHAR + ']*$');
5463 var rARIACamel = new RegExp('^(aria)[A-Z][' + ATTRIBUTE_NAME_CHAR + ']*$');
5464 var hasOwnProperty$1 = Object.prototype.hasOwnProperty;
5465
5466 function validateProperty(tagName, name) {
5467 {
5468 if (hasOwnProperty$1.call(warnedProperties, name) && warnedProperties[name]) {
5469 return true;
5470 }
5471
5472 if (rARIACamel.test(name)) {
5473 var ariaName = 'aria-' + name.slice(4).toLowerCase();
5474 var correctName = ariaProperties.hasOwnProperty(ariaName) ? ariaName : null; // If this is an aria-* attribute, but is not listed in the known DOM
5475 // DOM properties, then it is an invalid aria-* attribute.
5476
5477 if (correctName == null) {
5478 error('Invalid ARIA attribute `%s`. ARIA attributes follow the pattern aria-* and must be lowercase.', name);
5479
5480 warnedProperties[name] = true;
5481 return true;
5482 } // aria-* attributes should be lowercase; suggest the lowercase version.
5483
5484
5485 if (name !== correctName) {
5486 error('Invalid ARIA attribute `%s`. Did you mean `%s`?', name, correctName);
5487
5488 warnedProperties[name] = true;
5489 return true;
5490 }
5491 }
5492
5493 if (rARIA.test(name)) {
5494 var lowerCasedName = name.toLowerCase();
5495 var standardName = ariaProperties.hasOwnProperty(lowerCasedName) ? lowerCasedName : null; // If this is an aria-* attribute, but is not listed in the known DOM
5496 // DOM properties, then it is an invalid aria-* attribute.
5497
5498 if (standardName == null) {
5499 warnedProperties[name] = true;
5500 return false;
5501 } // aria-* attributes should be lowercase; suggest the lowercase version.
5502
5503
5504 if (name !== standardName) {
5505 error('Unknown ARIA attribute `%s`. Did you mean `%s`?', name, standardName);
5506
5507 warnedProperties[name] = true;
5508 return true;
5509 }
5510 }
5511 }
5512
5513 return true;
5514 }
5515
5516 function warnInvalidARIAProps(type, props) {
5517 {
5518 var invalidProps = [];
5519
5520 for (var key in props) {
5521 var isValid = validateProperty(type, key);
5522
5523 if (!isValid) {
5524 invalidProps.push(key);
5525 }
5526 }
5527
5528 var unknownPropString = invalidProps.map(function (prop) {
5529 return '`' + prop + '`';
5530 }).join(', ');
5531
5532 if (invalidProps.length === 1) {
5533 error('Invalid aria prop %s on <%s> tag. ' + 'For details, see https://fb.me/invalid-aria-prop', unknownPropString, type);
5534 } else if (invalidProps.length > 1) {
5535 error('Invalid aria props %s on <%s> tag. ' + 'For details, see https://fb.me/invalid-aria-prop', unknownPropString, type);
5536 }
5537 }
5538 }
5539
5540 function validateProperties(type, props) {
5541 if (isCustomComponent(type, props)) {
5542 return;
5543 }
5544
5545 warnInvalidARIAProps(type, props);
5546 }
5547
5548 var didWarnValueNull = false;
5549 function validateProperties$1(type, props) {
5550 {
5551 if (type !== 'input' && type !== 'textarea' && type !== 'select') {
5552 return;
5553 }
5554
5555 if (props != null && props.value === null && !didWarnValueNull) {
5556 didWarnValueNull = true;
5557
5558 if (type === 'select' && props.multiple) {
5559 error('`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);
5560 } else {
5561 error('`value` prop on `%s` should not be null. ' + 'Consider using an empty string to clear the component or `undefined` ' + 'for uncontrolled components.', type);
5562 }
5563 }
5564 }
5565 }
5566
5567 var validateProperty$1 = function () {};
5568
5569 {
5570 var warnedProperties$1 = {};
5571 var _hasOwnProperty = Object.prototype.hasOwnProperty;
5572 var EVENT_NAME_REGEX = /^on./;
5573 var INVALID_EVENT_NAME_REGEX = /^on[^A-Z]/;
5574 var rARIA$1 = new RegExp('^(aria)-[' + ATTRIBUTE_NAME_CHAR + ']*$');
5575 var rARIACamel$1 = new RegExp('^(aria)[A-Z][' + ATTRIBUTE_NAME_CHAR + ']*$');
5576
5577 validateProperty$1 = function (tagName, name, value, canUseEventSystem) {
5578 if (_hasOwnProperty.call(warnedProperties$1, name) && warnedProperties$1[name]) {
5579 return true;
5580 }
5581
5582 var lowerCasedName = name.toLowerCase();
5583
5584 if (lowerCasedName === 'onfocusin' || lowerCasedName === 'onfocusout') {
5585 error('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.');
5586
5587 warnedProperties$1[name] = true;
5588 return true;
5589 } // We can't rely on the event system being injected on the server.
5590
5591
5592 if (canUseEventSystem) {
5593 if (registrationNameModules.hasOwnProperty(name)) {
5594 return true;
5595 }
5596
5597 var registrationName = possibleRegistrationNames.hasOwnProperty(lowerCasedName) ? possibleRegistrationNames[lowerCasedName] : null;
5598
5599 if (registrationName != null) {
5600 error('Invalid event handler property `%s`. Did you mean `%s`?', name, registrationName);
5601
5602 warnedProperties$1[name] = true;
5603 return true;
5604 }
5605
5606 if (EVENT_NAME_REGEX.test(name)) {
5607 error('Unknown event handler property `%s`. It will be ignored.', name);
5608
5609 warnedProperties$1[name] = true;
5610 return true;
5611 }
5612 } else if (EVENT_NAME_REGEX.test(name)) {
5613 // If no event plugins have been injected, we are in a server environment.
5614 // So we can't tell if the event name is correct for sure, but we can filter
5615 // out known bad ones like `onclick`. We can't suggest a specific replacement though.
5616 if (INVALID_EVENT_NAME_REGEX.test(name)) {
5617 error('Invalid event handler property `%s`. ' + 'React events use the camelCase naming convention, for example `onClick`.', name);
5618 }
5619
5620 warnedProperties$1[name] = true;
5621 return true;
5622 } // Let the ARIA attribute hook validate ARIA attributes
5623
5624
5625 if (rARIA$1.test(name) || rARIACamel$1.test(name)) {
5626 return true;
5627 }
5628
5629 if (lowerCasedName === 'innerhtml') {
5630 error('Directly setting property `innerHTML` is not permitted. ' + 'For more information, lookup documentation on `dangerouslySetInnerHTML`.');
5631
5632 warnedProperties$1[name] = true;
5633 return true;
5634 }
5635
5636 if (lowerCasedName === 'aria') {
5637 error('The `aria` attribute is reserved for future use in React. ' + 'Pass individual `aria-` attributes instead.');
5638
5639 warnedProperties$1[name] = true;
5640 return true;
5641 }
5642
5643 if (lowerCasedName === 'is' && value !== null && value !== undefined && typeof value !== 'string') {
5644 error('Received a `%s` for a string attribute `is`. If this is expected, cast ' + 'the value to a string.', typeof value);
5645
5646 warnedProperties$1[name] = true;
5647 return true;
5648 }
5649
5650 if (typeof value === 'number' && isNaN(value)) {
5651 error('Received NaN for the `%s` attribute. If this is expected, cast ' + 'the value to a string.', name);
5652
5653 warnedProperties$1[name] = true;
5654 return true;
5655 }
5656
5657 var propertyInfo = getPropertyInfo(name);
5658 var isReserved = propertyInfo !== null && propertyInfo.type === RESERVED; // Known attributes should match the casing specified in the property config.
5659
5660 if (possibleStandardNames.hasOwnProperty(lowerCasedName)) {
5661 var standardName = possibleStandardNames[lowerCasedName];
5662
5663 if (standardName !== name) {
5664 error('Invalid DOM property `%s`. Did you mean `%s`?', name, standardName);
5665
5666 warnedProperties$1[name] = true;
5667 return true;
5668 }
5669 } else if (!isReserved && name !== lowerCasedName) {
5670 // Unknown attributes should have lowercase casing since that's how they
5671 // will be cased anyway with server rendering.
5672 error('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);
5673
5674 warnedProperties$1[name] = true;
5675 return true;
5676 }
5677
5678 if (typeof value === 'boolean' && shouldRemoveAttributeWithWarning(name, value, propertyInfo, false)) {
5679 if (value) {
5680 error('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);
5681 } else {
5682 error('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);
5683 }
5684
5685 warnedProperties$1[name] = true;
5686 return true;
5687 } // Now that we've validated casing, do not validate
5688 // data types for reserved props
5689
5690
5691 if (isReserved) {
5692 return true;
5693 } // Warn when a known attribute is a bad type
5694
5695
5696 if (shouldRemoveAttributeWithWarning(name, value, propertyInfo, false)) {
5697 warnedProperties$1[name] = true;
5698 return false;
5699 } // Warn when passing the strings 'false' or 'true' into a boolean prop
5700
5701
5702 if ((value === 'false' || value === 'true') && propertyInfo !== null && propertyInfo.type === BOOLEAN) {
5703 error('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);
5704
5705 warnedProperties$1[name] = true;
5706 return true;
5707 }
5708
5709 return true;
5710 };
5711 }
5712
5713 var warnUnknownProperties = function (type, props, canUseEventSystem) {
5714 {
5715 var unknownProps = [];
5716
5717 for (var key in props) {
5718 var isValid = validateProperty$1(type, key, props[key], canUseEventSystem);
5719
5720 if (!isValid) {
5721 unknownProps.push(key);
5722 }
5723 }
5724
5725 var unknownPropString = unknownProps.map(function (prop) {
5726 return '`' + prop + '`';
5727 }).join(', ');
5728
5729 if (unknownProps.length === 1) {
5730 error('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);
5731 } else if (unknownProps.length > 1) {
5732 error('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);
5733 }
5734 }
5735 };
5736
5737 function validateProperties$2(type, props, canUseEventSystem) {
5738 if (isCustomComponent(type, props)) {
5739 return;
5740 }
5741
5742 warnUnknownProperties(type, props, canUseEventSystem);
5743 }
5744
5745 var didWarnInvalidHydration = false;
5746 var didWarnShadyDOM = false;
5747 var DANGEROUSLY_SET_INNER_HTML = 'dangerouslySetInnerHTML';
5748 var SUPPRESS_CONTENT_EDITABLE_WARNING = 'suppressContentEditableWarning';
5749 var SUPPRESS_HYDRATION_WARNING = 'suppressHydrationWarning';
5750 var AUTOFOCUS = 'autoFocus';
5751 var CHILDREN = 'children';
5752 var STYLE = 'style';
5753 var HTML$1 = '__html';
5754 var HTML_NAMESPACE$1 = Namespaces.html;
5755 var warnedUnknownTags;
5756 var suppressHydrationWarning;
5757 var validatePropertiesInDevelopment;
5758 var warnForTextDifference;
5759 var warnForPropDifference;
5760 var warnForExtraAttributes;
5761 var warnForInvalidEventListener;
5762 var canDiffStyleForHydrationWarning;
5763 var normalizeMarkupForTextOrAttribute;
5764 var normalizeHTML;
5765
5766 {
5767 warnedUnknownTags = {
5768 // Chrome is the only major browser not shipping <time>. But as of July
5769 // 2017 it intends to ship it due to widespread usage. We intentionally
5770 // *don't* warn for <time> even if it's unrecognized by Chrome because
5771 // it soon will be, and many apps have been using it anyway.
5772 time: true,
5773 // There are working polyfills for <dialog>. Let people use it.
5774 dialog: true,
5775 // Electron ships a custom <webview> tag to display external web content in
5776 // an isolated frame and process.
5777 // This tag is not present in non Electron environments such as JSDom which
5778 // is often used for testing purposes.
5779 // @see https://electronjs.org/docs/api/webview-tag
5780 webview: true
5781 };
5782
5783 validatePropertiesInDevelopment = function (type, props) {
5784 validateProperties(type, props);
5785 validateProperties$1(type, props);
5786 validateProperties$2(type, props,
5787 /* canUseEventSystem */
5788 true);
5789 }; // IE 11 parses & normalizes the style attribute as opposed to other
5790 // browsers. It adds spaces and sorts the properties in some
5791 // non-alphabetical order. Handling that would require sorting CSS
5792 // properties in the client & server versions or applying
5793 // `expectedStyle` to a temporary DOM node to read its `style` attribute
5794 // normalized. Since it only affects IE, we're skipping style warnings
5795 // in that browser completely in favor of doing all that work.
5796 // See https://github.com/facebook/react/issues/11807
5797
5798
5799 canDiffStyleForHydrationWarning = canUseDOM && !document.documentMode; // HTML parsing normalizes CR and CRLF to LF.
5800 // It also can turn \u0000 into \uFFFD inside attributes.
5801 // https://www.w3.org/TR/html5/single-page.html#preprocessing-the-input-stream
5802 // If we have a mismatch, it might be caused by that.
5803 // We will still patch up in this case but not fire the warning.
5804
5805 var NORMALIZE_NEWLINES_REGEX = /\r\n?/g;
5806 var NORMALIZE_NULL_AND_REPLACEMENT_REGEX = /\u0000|\uFFFD/g;
5807
5808 normalizeMarkupForTextOrAttribute = function (markup) {
5809 var markupString = typeof markup === 'string' ? markup : '' + markup;
5810 return markupString.replace(NORMALIZE_NEWLINES_REGEX, '\n').replace(NORMALIZE_NULL_AND_REPLACEMENT_REGEX, '');
5811 };
5812
5813 warnForTextDifference = function (serverText, clientText) {
5814 if (didWarnInvalidHydration) {
5815 return;
5816 }
5817
5818 var normalizedClientText = normalizeMarkupForTextOrAttribute(clientText);
5819 var normalizedServerText = normalizeMarkupForTextOrAttribute(serverText);
5820
5821 if (normalizedServerText === normalizedClientText) {
5822 return;
5823 }
5824
5825 didWarnInvalidHydration = true;
5826
5827 error('Text content did not match. Server: "%s" Client: "%s"', normalizedServerText, normalizedClientText);
5828 };
5829
5830 warnForPropDifference = function (propName, serverValue, clientValue) {
5831 if (didWarnInvalidHydration) {
5832 return;
5833 }
5834
5835 var normalizedClientValue = normalizeMarkupForTextOrAttribute(clientValue);
5836 var normalizedServerValue = normalizeMarkupForTextOrAttribute(serverValue);
5837
5838 if (normalizedServerValue === normalizedClientValue) {
5839 return;
5840 }
5841
5842 didWarnInvalidHydration = true;
5843
5844 error('Prop `%s` did not match. Server: %s Client: %s', propName, JSON.stringify(normalizedServerValue), JSON.stringify(normalizedClientValue));
5845 };
5846
5847 warnForExtraAttributes = function (attributeNames) {
5848 if (didWarnInvalidHydration) {
5849 return;
5850 }
5851
5852 didWarnInvalidHydration = true;
5853 var names = [];
5854 attributeNames.forEach(function (name) {
5855 names.push(name);
5856 });
5857
5858 error('Extra attributes from the server: %s', names);
5859 };
5860
5861 warnForInvalidEventListener = function (registrationName, listener) {
5862 if (listener === false) {
5863 error('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);
5864 } else {
5865 error('Expected `%s` listener to be a function, instead got a value of `%s` type.', registrationName, typeof listener);
5866 }
5867 }; // Parse the HTML and read it back to normalize the HTML string so that it
5868 // can be used for comparison.
5869
5870
5871 normalizeHTML = function (parent, html) {
5872 // We could have created a separate document here to avoid
5873 // re-initializing custom elements if they exist. But this breaks
5874 // how <noscript> is being handled. So we use the same document.
5875 // See the discussion in https://github.com/facebook/react/pull/11157.
5876 var testElement = parent.namespaceURI === HTML_NAMESPACE$1 ? parent.ownerDocument.createElement(parent.tagName) : parent.ownerDocument.createElementNS(parent.namespaceURI, parent.tagName);
5877 testElement.innerHTML = html;
5878 return testElement.innerHTML;
5879 };
5880 }
5881
5882 function ensureListeningTo(rootContainerElement, registrationName) {
5883 var isDocumentOrFragment = rootContainerElement.nodeType === DOCUMENT_NODE || rootContainerElement.nodeType === DOCUMENT_FRAGMENT_NODE;
5884 var doc = isDocumentOrFragment ? rootContainerElement : rootContainerElement.ownerDocument;
5885 legacyListenToEvent(registrationName, doc);
5886 }
5887
5888 function getOwnerDocumentFromRootContainer(rootContainerElement) {
5889 return rootContainerElement.nodeType === DOCUMENT_NODE ? rootContainerElement : rootContainerElement.ownerDocument;
5890 }
5891
5892 function noop() {}
5893
5894 function trapClickOnNonInteractiveElement(node) {
5895 // Mobile Safari does not fire properly bubble click events on
5896 // non-interactive elements, which means delegated click listeners do not
5897 // fire. The workaround for this bug involves attaching an empty click
5898 // listener on the target node.
5899 // http://www.quirksmode.org/blog/archives/2010/09/click_event_del.html
5900 // Just set it using the onclick property so that we don't have to manage any
5901 // bookkeeping for it. Not sure if we need to clear it when the listener is
5902 // removed.
5903 // TODO: Only do this for the relevant Safaris maybe?
5904 node.onclick = noop;
5905 }
5906
5907 function setInitialDOMProperties(tag, domElement, rootContainerElement, nextProps, isCustomComponentTag) {
5908 for (var propKey in nextProps) {
5909 if (!nextProps.hasOwnProperty(propKey)) {
5910 continue;
5911 }
5912
5913 var nextProp = nextProps[propKey];
5914
5915 if (propKey === STYLE) {
5916 {
5917 if (nextProp) {
5918 // Freeze the next style object so that we can assume it won't be
5919 // mutated. We have already warned for this in the past.
5920 Object.freeze(nextProp);
5921 }
5922 } // Relies on `updateStylesByID` not mutating `styleUpdates`.
5923
5924
5925 setValueForStyles(domElement, nextProp);
5926 } else if (propKey === DANGEROUSLY_SET_INNER_HTML) {
5927 var nextHtml = nextProp ? nextProp[HTML$1] : undefined;
5928
5929 if (nextHtml != null) {
5930 setInnerHTML(domElement, nextHtml);
5931 }
5932 } else if (propKey === CHILDREN) {
5933 if (typeof nextProp === 'string') {
5934 // Avoid setting initial textContent when the text is empty. In IE11 setting
5935 // textContent on a <textarea> will cause the placeholder to not
5936 // show within the <textarea> until it has been focused and blurred again.
5937 // https://github.com/facebook/react/issues/6731#issuecomment-254874553
5938 var canSetTextContent = tag !== 'textarea' || nextProp !== '';
5939
5940 if (canSetTextContent) {
5941 setTextContent(domElement, nextProp);
5942 }
5943 } else if (typeof nextProp === 'number') {
5944 setTextContent(domElement, '' + nextProp);
5945 }
5946 } else if ( propKey === SUPPRESS_CONTENT_EDITABLE_WARNING || propKey === SUPPRESS_HYDRATION_WARNING) ; else if (propKey === AUTOFOCUS) ; else if (registrationNameModules.hasOwnProperty(propKey)) {
5947 if (nextProp != null) {
5948 if ( typeof nextProp !== 'function') {
5949 warnForInvalidEventListener(propKey, nextProp);
5950 }
5951
5952 ensureListeningTo(rootContainerElement, propKey);
5953 }
5954 } else if (nextProp != null) {
5955 setValueForProperty(domElement, propKey, nextProp, isCustomComponentTag);
5956 }
5957 }
5958 }
5959
5960 function updateDOMProperties(domElement, updatePayload, wasCustomComponentTag, isCustomComponentTag) {
5961 // TODO: Handle wasCustomComponentTag
5962 for (var i = 0; i < updatePayload.length; i += 2) {
5963 var propKey = updatePayload[i];
5964 var propValue = updatePayload[i + 1];
5965
5966 if (propKey === STYLE) {
5967 setValueForStyles(domElement, propValue);
5968 } else if (propKey === DANGEROUSLY_SET_INNER_HTML) {
5969 setInnerHTML(domElement, propValue);
5970 } else if (propKey === CHILDREN) {
5971 setTextContent(domElement, propValue);
5972 } else {
5973 setValueForProperty(domElement, propKey, propValue, isCustomComponentTag);
5974 }
5975 }
5976 }
5977
5978 function createElement(type, props, rootContainerElement, parentNamespace) {
5979 var isCustomComponentTag; // We create tags in the namespace of their parent container, except HTML
5980 // tags get no namespace.
5981
5982 var ownerDocument = getOwnerDocumentFromRootContainer(rootContainerElement);
5983 var domElement;
5984 var namespaceURI = parentNamespace;
5985
5986 if (namespaceURI === HTML_NAMESPACE$1) {
5987 namespaceURI = getIntrinsicNamespace(type);
5988 }
5989
5990 if (namespaceURI === HTML_NAMESPACE$1) {
5991 {
5992 isCustomComponentTag = isCustomComponent(type, props); // Should this check be gated by parent namespace? Not sure we want to
5993 // allow <SVG> or <mATH>.
5994
5995 if (!isCustomComponentTag && type !== type.toLowerCase()) {
5996 error('<%s /> is using incorrect casing. ' + 'Use PascalCase for React components, ' + 'or lowercase for HTML elements.', type);
5997 }
5998 }
5999
6000 if (type === 'script') {
6001 // Create the script via .innerHTML so its "parser-inserted" flag is
6002 // set to true and it does not execute
6003 var div = ownerDocument.createElement('div');
6004
6005 div.innerHTML = '<script><' + '/script>'; // eslint-disable-line
6006 // This is guaranteed to yield a script element.
6007
6008 var firstChild = div.firstChild;
6009 domElement = div.removeChild(firstChild);
6010 } else if (typeof props.is === 'string') {
6011 // $FlowIssue `createElement` should be updated for Web Components
6012 domElement = ownerDocument.createElement(type, {
6013 is: props.is
6014 });
6015 } else {
6016 // Separate else branch instead of using `props.is || undefined` above because of a Firefox bug.
6017 // See discussion in https://github.com/facebook/react/pull/6896
6018 // and discussion in https://bugzilla.mozilla.org/show_bug.cgi?id=1276240
6019 domElement = ownerDocument.createElement(type); // Normally attributes are assigned in `setInitialDOMProperties`, however the `multiple` and `size`
6020 // attributes on `select`s needs to be added before `option`s are inserted.
6021 // This prevents:
6022 // - a bug where the `select` does not scroll to the correct option because singular
6023 // `select` elements automatically pick the first item #13222
6024 // - a bug where the `select` set the first item as selected despite the `size` attribute #14239
6025 // See https://github.com/facebook/react/issues/13222
6026 // and https://github.com/facebook/react/issues/14239
6027
6028 if (type === 'select') {
6029 var node = domElement;
6030
6031 if (props.multiple) {
6032 node.multiple = true;
6033 } else if (props.size) {
6034 // Setting a size greater than 1 causes a select to behave like `multiple=true`, where
6035 // it is possible that no option is selected.
6036 //
6037 // This is only necessary when a select in "single selection mode".
6038 node.size = props.size;
6039 }
6040 }
6041 }
6042 } else {
6043 domElement = ownerDocument.createElementNS(namespaceURI, type);
6044 }
6045
6046 {
6047 if (namespaceURI === HTML_NAMESPACE$1) {
6048 if (!isCustomComponentTag && Object.prototype.toString.call(domElement) === '[object HTMLUnknownElement]' && !Object.prototype.hasOwnProperty.call(warnedUnknownTags, type)) {
6049 warnedUnknownTags[type] = true;
6050
6051 error('The tag <%s> is unrecognized in this browser. ' + 'If you meant to render a React component, start its name with ' + 'an uppercase letter.', type);
6052 }
6053 }
6054 }
6055
6056 return domElement;
6057 }
6058 function createTextNode(text, rootContainerElement) {
6059 return getOwnerDocumentFromRootContainer(rootContainerElement).createTextNode(text);
6060 }
6061 function setInitialProperties(domElement, tag, rawProps, rootContainerElement) {
6062 var isCustomComponentTag = isCustomComponent(tag, rawProps);
6063
6064 {
6065 validatePropertiesInDevelopment(tag, rawProps);
6066
6067 if (isCustomComponentTag && !didWarnShadyDOM && domElement.shadyRoot) {
6068 error('%s is using shady DOM. Using shady DOM with React can ' + 'cause things to break subtly.', getCurrentFiberOwnerNameInDevOrNull() || 'A component');
6069
6070 didWarnShadyDOM = true;
6071 }
6072 } // TODO: Make sure that we check isMounted before firing any of these events.
6073
6074
6075 var props;
6076
6077 switch (tag) {
6078 case 'iframe':
6079 case 'object':
6080 case 'embed':
6081 trapBubbledEvent(TOP_LOAD, domElement);
6082 props = rawProps;
6083 break;
6084
6085 case 'video':
6086 case 'audio':
6087 // Create listener for each media event
6088 for (var i = 0; i < mediaEventTypes.length; i++) {
6089 trapBubbledEvent(mediaEventTypes[i], domElement);
6090 }
6091
6092 props = rawProps;
6093 break;
6094
6095 case 'source':
6096 trapBubbledEvent(TOP_ERROR, domElement);
6097 props = rawProps;
6098 break;
6099
6100 case 'img':
6101 case 'image':
6102 case 'link':
6103 trapBubbledEvent(TOP_ERROR, domElement);
6104 trapBubbledEvent(TOP_LOAD, domElement);
6105 props = rawProps;
6106 break;
6107
6108 case 'form':
6109 trapBubbledEvent(TOP_RESET, domElement);
6110 trapBubbledEvent(TOP_SUBMIT, domElement);
6111 props = rawProps;
6112 break;
6113
6114 case 'details':
6115 trapBubbledEvent(TOP_TOGGLE, domElement);
6116 props = rawProps;
6117 break;
6118
6119 case 'input':
6120 initWrapperState(domElement, rawProps);
6121 props = getHostProps(domElement, rawProps);
6122 trapBubbledEvent(TOP_INVALID, domElement); // For controlled components we always need to ensure we're listening
6123 // to onChange. Even if there is no listener.
6124
6125 ensureListeningTo(rootContainerElement, 'onChange');
6126 break;
6127
6128 case 'option':
6129 validateProps(domElement, rawProps);
6130 props = getHostProps$1(domElement, rawProps);
6131 break;
6132
6133 case 'select':
6134 initWrapperState$1(domElement, rawProps);
6135 props = getHostProps$2(domElement, rawProps);
6136 trapBubbledEvent(TOP_INVALID, domElement); // For controlled components we always need to ensure we're listening
6137 // to onChange. Even if there is no listener.
6138
6139 ensureListeningTo(rootContainerElement, 'onChange');
6140 break;
6141
6142 case 'textarea':
6143 initWrapperState$2(domElement, rawProps);
6144 props = getHostProps$3(domElement, rawProps);
6145 trapBubbledEvent(TOP_INVALID, domElement); // For controlled components we always need to ensure we're listening
6146 // to onChange. Even if there is no listener.
6147
6148 ensureListeningTo(rootContainerElement, 'onChange');
6149 break;
6150
6151 default:
6152 props = rawProps;
6153 }
6154
6155 assertValidProps(tag, props);
6156 setInitialDOMProperties(tag, domElement, rootContainerElement, props, isCustomComponentTag);
6157
6158 switch (tag) {
6159 case 'input':
6160 // TODO: Make sure we check if this is still unmounted or do any clean
6161 // up necessary since we never stop tracking anymore.
6162 track(domElement);
6163 postMountWrapper(domElement, rawProps, false);
6164 break;
6165
6166 case 'textarea':
6167 // TODO: Make sure we check if this is still unmounted or do any clean
6168 // up necessary since we never stop tracking anymore.
6169 track(domElement);
6170 postMountWrapper$3(domElement);
6171 break;
6172
6173 case 'option':
6174 postMountWrapper$1(domElement, rawProps);
6175 break;
6176
6177 case 'select':
6178 postMountWrapper$2(domElement, rawProps);
6179 break;
6180
6181 default:
6182 if (typeof props.onClick === 'function') {
6183 // TODO: This cast may not be sound for SVG, MathML or custom elements.
6184 trapClickOnNonInteractiveElement(domElement);
6185 }
6186
6187 break;
6188 }
6189 } // Calculate the diff between the two objects.
6190
6191 function diffProperties(domElement, tag, lastRawProps, nextRawProps, rootContainerElement) {
6192 {
6193 validatePropertiesInDevelopment(tag, nextRawProps);
6194 }
6195
6196 var updatePayload = null;
6197 var lastProps;
6198 var nextProps;
6199
6200 switch (tag) {
6201 case 'input':
6202 lastProps = getHostProps(domElement, lastRawProps);
6203 nextProps = getHostProps(domElement, nextRawProps);
6204 updatePayload = [];
6205 break;
6206
6207 case 'option':
6208 lastProps = getHostProps$1(domElement, lastRawProps);
6209 nextProps = getHostProps$1(domElement, nextRawProps);
6210 updatePayload = [];
6211 break;
6212
6213 case 'select':
6214 lastProps = getHostProps$2(domElement, lastRawProps);
6215 nextProps = getHostProps$2(domElement, nextRawProps);
6216 updatePayload = [];
6217 break;
6218
6219 case 'textarea':
6220 lastProps = getHostProps$3(domElement, lastRawProps);
6221 nextProps = getHostProps$3(domElement, nextRawProps);
6222 updatePayload = [];
6223 break;
6224
6225 default:
6226 lastProps = lastRawProps;
6227 nextProps = nextRawProps;
6228
6229 if (typeof lastProps.onClick !== 'function' && typeof nextProps.onClick === 'function') {
6230 // TODO: This cast may not be sound for SVG, MathML or custom elements.
6231 trapClickOnNonInteractiveElement(domElement);
6232 }
6233
6234 break;
6235 }
6236
6237 assertValidProps(tag, nextProps);
6238 var propKey;
6239 var styleName;
6240 var styleUpdates = null;
6241
6242 for (propKey in lastProps) {
6243 if (nextProps.hasOwnProperty(propKey) || !lastProps.hasOwnProperty(propKey) || lastProps[propKey] == null) {
6244 continue;
6245 }
6246
6247 if (propKey === STYLE) {
6248 var lastStyle = lastProps[propKey];
6249
6250 for (styleName in lastStyle) {
6251 if (lastStyle.hasOwnProperty(styleName)) {
6252 if (!styleUpdates) {
6253 styleUpdates = {};
6254 }
6255
6256 styleUpdates[styleName] = '';
6257 }
6258 }
6259 } else if (propKey === DANGEROUSLY_SET_INNER_HTML || propKey === CHILDREN) ; else if ( propKey === SUPPRESS_CONTENT_EDITABLE_WARNING || propKey === SUPPRESS_HYDRATION_WARNING) ; else if (propKey === AUTOFOCUS) ; else if (registrationNameModules.hasOwnProperty(propKey)) {
6260 // This is a special case. If any listener updates we need to ensure
6261 // that the "current" fiber pointer gets updated so we need a commit
6262 // to update this element.
6263 if (!updatePayload) {
6264 updatePayload = [];
6265 }
6266 } else {
6267 // For all other deleted properties we add it to the queue. We use
6268 // the whitelist in the commit phase instead.
6269 (updatePayload = updatePayload || []).push(propKey, null);
6270 }
6271 }
6272
6273 for (propKey in nextProps) {
6274 var nextProp = nextProps[propKey];
6275 var lastProp = lastProps != null ? lastProps[propKey] : undefined;
6276
6277 if (!nextProps.hasOwnProperty(propKey) || nextProp === lastProp || nextProp == null && lastProp == null) {
6278 continue;
6279 }
6280
6281 if (propKey === STYLE) {
6282 {
6283 if (nextProp) {
6284 // Freeze the next style object so that we can assume it won't be
6285 // mutated. We have already warned for this in the past.
6286 Object.freeze(nextProp);
6287 }
6288 }
6289
6290 if (lastProp) {
6291 // Unset styles on `lastProp` but not on `nextProp`.
6292 for (styleName in lastProp) {
6293 if (lastProp.hasOwnProperty(styleName) && (!nextProp || !nextProp.hasOwnProperty(styleName))) {
6294 if (!styleUpdates) {
6295 styleUpdates = {};
6296 }
6297
6298 styleUpdates[styleName] = '';
6299 }
6300 } // Update styles that changed since `lastProp`.
6301
6302
6303 for (styleName in nextProp) {
6304 if (nextProp.hasOwnProperty(styleName) && lastProp[styleName] !== nextProp[styleName]) {
6305 if (!styleUpdates) {
6306 styleUpdates = {};
6307 }
6308
6309 styleUpdates[styleName] = nextProp[styleName];
6310 }
6311 }
6312 } else {
6313 // Relies on `updateStylesByID` not mutating `styleUpdates`.
6314 if (!styleUpdates) {
6315 if (!updatePayload) {
6316 updatePayload = [];
6317 }
6318
6319 updatePayload.push(propKey, styleUpdates);
6320 }
6321
6322 styleUpdates = nextProp;
6323 }
6324 } else if (propKey === DANGEROUSLY_SET_INNER_HTML) {
6325 var nextHtml = nextProp ? nextProp[HTML$1] : undefined;
6326 var lastHtml = lastProp ? lastProp[HTML$1] : undefined;
6327
6328 if (nextHtml != null) {
6329 if (lastHtml !== nextHtml) {
6330 (updatePayload = updatePayload || []).push(propKey, nextHtml);
6331 }
6332 }
6333 } else if (propKey === CHILDREN) {
6334 if (lastProp !== nextProp && (typeof nextProp === 'string' || typeof nextProp === 'number')) {
6335 (updatePayload = updatePayload || []).push(propKey, '' + nextProp);
6336 }
6337 } else if ( propKey === SUPPRESS_CONTENT_EDITABLE_WARNING || propKey === SUPPRESS_HYDRATION_WARNING) ; else if (registrationNameModules.hasOwnProperty(propKey)) {
6338 if (nextProp != null) {
6339 // We eagerly listen to this even though we haven't committed yet.
6340 if ( typeof nextProp !== 'function') {
6341 warnForInvalidEventListener(propKey, nextProp);
6342 }
6343
6344 ensureListeningTo(rootContainerElement, propKey);
6345 }
6346
6347 if (!updatePayload && lastProp !== nextProp) {
6348 // This is a special case. If any listener updates we need to ensure
6349 // that the "current" props pointer gets updated so we need a commit
6350 // to update this element.
6351 updatePayload = [];
6352 }
6353 } else {
6354 // For any other property we always add it to the queue and then we
6355 // filter it out using the whitelist during the commit.
6356 (updatePayload = updatePayload || []).push(propKey, nextProp);
6357 }
6358 }
6359
6360 if (styleUpdates) {
6361 {
6362 validateShorthandPropertyCollisionInDev(styleUpdates, nextProps[STYLE]);
6363 }
6364
6365 (updatePayload = updatePayload || []).push(STYLE, styleUpdates);
6366 }
6367
6368 return updatePayload;
6369 } // Apply the diff.
6370
6371 function updateProperties(domElement, updatePayload, tag, lastRawProps, nextRawProps) {
6372 // Update checked *before* name.
6373 // In the middle of an update, it is possible to have multiple checked.
6374 // When a checked radio tries to change name, browser makes another radio's checked false.
6375 if (tag === 'input' && nextRawProps.type === 'radio' && nextRawProps.name != null) {
6376 updateChecked(domElement, nextRawProps);
6377 }
6378
6379 var wasCustomComponentTag = isCustomComponent(tag, lastRawProps);
6380 var isCustomComponentTag = isCustomComponent(tag, nextRawProps); // Apply the diff.
6381
6382 updateDOMProperties(domElement, updatePayload, wasCustomComponentTag, isCustomComponentTag); // TODO: Ensure that an update gets scheduled if any of the special props
6383 // changed.
6384
6385 switch (tag) {
6386 case 'input':
6387 // Update the wrapper around inputs *after* updating props. This has to
6388 // happen after `updateDOMProperties`. Otherwise HTML5 input validations
6389 // raise warnings and prevent the new value from being assigned.
6390 updateWrapper(domElement, nextRawProps);
6391 break;
6392
6393 case 'textarea':
6394 updateWrapper$1(domElement, nextRawProps);
6395 break;
6396
6397 case 'select':
6398 // <select> value update needs to occur after <option> children
6399 // reconciliation
6400 postUpdateWrapper(domElement, nextRawProps);
6401 break;
6402 }
6403 }
6404
6405 function getPossibleStandardName(propName) {
6406 {
6407 var lowerCasedName = propName.toLowerCase();
6408
6409 if (!possibleStandardNames.hasOwnProperty(lowerCasedName)) {
6410 return null;
6411 }
6412
6413 return possibleStandardNames[lowerCasedName] || null;
6414 }
6415 }
6416
6417 function diffHydratedProperties(domElement, tag, rawProps, parentNamespace, rootContainerElement) {
6418 var isCustomComponentTag;
6419 var extraAttributeNames;
6420
6421 {
6422 suppressHydrationWarning = rawProps[SUPPRESS_HYDRATION_WARNING] === true;
6423 isCustomComponentTag = isCustomComponent(tag, rawProps);
6424 validatePropertiesInDevelopment(tag, rawProps);
6425
6426 if (isCustomComponentTag && !didWarnShadyDOM && domElement.shadyRoot) {
6427 error('%s is using shady DOM. Using shady DOM with React can ' + 'cause things to break subtly.', getCurrentFiberOwnerNameInDevOrNull() || 'A component');
6428
6429 didWarnShadyDOM = true;
6430 }
6431 } // TODO: Make sure that we check isMounted before firing any of these events.
6432
6433
6434 switch (tag) {
6435 case 'iframe':
6436 case 'object':
6437 case 'embed':
6438 trapBubbledEvent(TOP_LOAD, domElement);
6439 break;
6440
6441 case 'video':
6442 case 'audio':
6443 // Create listener for each media event
6444 for (var i = 0; i < mediaEventTypes.length; i++) {
6445 trapBubbledEvent(mediaEventTypes[i], domElement);
6446 }
6447
6448 break;
6449
6450 case 'source':
6451 trapBubbledEvent(TOP_ERROR, domElement);
6452 break;
6453
6454 case 'img':
6455 case 'image':
6456 case 'link':
6457 trapBubbledEvent(TOP_ERROR, domElement);
6458 trapBubbledEvent(TOP_LOAD, domElement);
6459 break;
6460
6461 case 'form':
6462 trapBubbledEvent(TOP_RESET, domElement);
6463 trapBubbledEvent(TOP_SUBMIT, domElement);
6464 break;
6465
6466 case 'details':
6467 trapBubbledEvent(TOP_TOGGLE, domElement);
6468 break;
6469
6470 case 'input':
6471 initWrapperState(domElement, rawProps);
6472 trapBubbledEvent(TOP_INVALID, domElement); // For controlled components we always need to ensure we're listening
6473 // to onChange. Even if there is no listener.
6474
6475 ensureListeningTo(rootContainerElement, 'onChange');
6476 break;
6477
6478 case 'option':
6479 validateProps(domElement, rawProps);
6480 break;
6481
6482 case 'select':
6483 initWrapperState$1(domElement, rawProps);
6484 trapBubbledEvent(TOP_INVALID, domElement); // For controlled components we always need to ensure we're listening
6485 // to onChange. Even if there is no listener.
6486
6487 ensureListeningTo(rootContainerElement, 'onChange');
6488 break;
6489
6490 case 'textarea':
6491 initWrapperState$2(domElement, rawProps);
6492 trapBubbledEvent(TOP_INVALID, domElement); // For controlled components we always need to ensure we're listening
6493 // to onChange. Even if there is no listener.
6494
6495 ensureListeningTo(rootContainerElement, 'onChange');
6496 break;
6497 }
6498
6499 assertValidProps(tag, rawProps);
6500
6501 {
6502 extraAttributeNames = new Set();
6503 var attributes = domElement.attributes;
6504
6505 for (var _i = 0; _i < attributes.length; _i++) {
6506 var name = attributes[_i].name.toLowerCase();
6507
6508 switch (name) {
6509 // Built-in SSR attribute is whitelisted
6510 case 'data-reactroot':
6511 break;
6512 // Controlled attributes are not validated
6513 // TODO: Only ignore them on controlled tags.
6514
6515 case 'value':
6516 break;
6517
6518 case 'checked':
6519 break;
6520
6521 case 'selected':
6522 break;
6523
6524 default:
6525 // Intentionally use the original name.
6526 // See discussion in https://github.com/facebook/react/pull/10676.
6527 extraAttributeNames.add(attributes[_i].name);
6528 }
6529 }
6530 }
6531
6532 var updatePayload = null;
6533
6534 for (var propKey in rawProps) {
6535 if (!rawProps.hasOwnProperty(propKey)) {
6536 continue;
6537 }
6538
6539 var nextProp = rawProps[propKey];
6540
6541 if (propKey === CHILDREN) {
6542 // For text content children we compare against textContent. This
6543 // might match additional HTML that is hidden when we read it using
6544 // textContent. E.g. "foo" will match "f<span>oo</span>" but that still
6545 // satisfies our requirement. Our requirement is not to produce perfect
6546 // HTML and attributes. Ideally we should preserve structure but it's
6547 // ok not to if the visible content is still enough to indicate what
6548 // even listeners these nodes might be wired up to.
6549 // TODO: Warn if there is more than a single textNode as a child.
6550 // TODO: Should we use domElement.firstChild.nodeValue to compare?
6551 if (typeof nextProp === 'string') {
6552 if (domElement.textContent !== nextProp) {
6553 if ( !suppressHydrationWarning) {
6554 warnForTextDifference(domElement.textContent, nextProp);
6555 }
6556
6557 updatePayload = [CHILDREN, nextProp];
6558 }
6559 } else if (typeof nextProp === 'number') {
6560 if (domElement.textContent !== '' + nextProp) {
6561 if ( !suppressHydrationWarning) {
6562 warnForTextDifference(domElement.textContent, nextProp);
6563 }
6564
6565 updatePayload = [CHILDREN, '' + nextProp];
6566 }
6567 }
6568 } else if (registrationNameModules.hasOwnProperty(propKey)) {
6569 if (nextProp != null) {
6570 if ( typeof nextProp !== 'function') {
6571 warnForInvalidEventListener(propKey, nextProp);
6572 }
6573
6574 ensureListeningTo(rootContainerElement, propKey);
6575 }
6576 } else if ( // Convince Flow we've calculated it (it's DEV-only in this method.)
6577 typeof isCustomComponentTag === 'boolean') {
6578 // Validate that the properties correspond to their expected values.
6579 var serverValue = void 0;
6580 var propertyInfo = getPropertyInfo(propKey);
6581
6582 if (suppressHydrationWarning) ; else if ( propKey === SUPPRESS_CONTENT_EDITABLE_WARNING || propKey === SUPPRESS_HYDRATION_WARNING || // Controlled attributes are not validated
6583 // TODO: Only ignore them on controlled tags.
6584 propKey === 'value' || propKey === 'checked' || propKey === 'selected') ; else if (propKey === DANGEROUSLY_SET_INNER_HTML) {
6585 var serverHTML = domElement.innerHTML;
6586 var nextHtml = nextProp ? nextProp[HTML$1] : undefined;
6587 var expectedHTML = normalizeHTML(domElement, nextHtml != null ? nextHtml : '');
6588
6589 if (expectedHTML !== serverHTML) {
6590 warnForPropDifference(propKey, serverHTML, expectedHTML);
6591 }
6592 } else if (propKey === STYLE) {
6593 // $FlowFixMe - Should be inferred as not undefined.
6594 extraAttributeNames.delete(propKey);
6595
6596 if (canDiffStyleForHydrationWarning) {
6597 var expectedStyle = createDangerousStringForStyles(nextProp);
6598 serverValue = domElement.getAttribute('style');
6599
6600 if (expectedStyle !== serverValue) {
6601 warnForPropDifference(propKey, serverValue, expectedStyle);
6602 }
6603 }
6604 } else if (isCustomComponentTag) {
6605 // $FlowFixMe - Should be inferred as not undefined.
6606 extraAttributeNames.delete(propKey.toLowerCase());
6607 serverValue = getValueForAttribute(domElement, propKey, nextProp);
6608
6609 if (nextProp !== serverValue) {
6610 warnForPropDifference(propKey, serverValue, nextProp);
6611 }
6612 } else if (!shouldIgnoreAttribute(propKey, propertyInfo, isCustomComponentTag) && !shouldRemoveAttribute(propKey, nextProp, propertyInfo, isCustomComponentTag)) {
6613 var isMismatchDueToBadCasing = false;
6614
6615 if (propertyInfo !== null) {
6616 // $FlowFixMe - Should be inferred as not undefined.
6617 extraAttributeNames.delete(propertyInfo.attributeName);
6618 serverValue = getValueForProperty(domElement, propKey, nextProp, propertyInfo);
6619 } else {
6620 var ownNamespace = parentNamespace;
6621
6622 if (ownNamespace === HTML_NAMESPACE$1) {
6623 ownNamespace = getIntrinsicNamespace(tag);
6624 }
6625
6626 if (ownNamespace === HTML_NAMESPACE$1) {
6627 // $FlowFixMe - Should be inferred as not undefined.
6628 extraAttributeNames.delete(propKey.toLowerCase());
6629 } else {
6630 var standardName = getPossibleStandardName(propKey);
6631
6632 if (standardName !== null && standardName !== propKey) {
6633 // If an SVG prop is supplied with bad casing, it will
6634 // be successfully parsed from HTML, but will produce a mismatch
6635 // (and would be incorrectly rendered on the client).
6636 // However, we already warn about bad casing elsewhere.
6637 // So we'll skip the misleading extra mismatch warning in this case.
6638 isMismatchDueToBadCasing = true; // $FlowFixMe - Should be inferred as not undefined.
6639
6640 extraAttributeNames.delete(standardName);
6641 } // $FlowFixMe - Should be inferred as not undefined.
6642
6643
6644 extraAttributeNames.delete(propKey);
6645 }
6646
6647 serverValue = getValueForAttribute(domElement, propKey, nextProp);
6648 }
6649
6650 if (nextProp !== serverValue && !isMismatchDueToBadCasing) {
6651 warnForPropDifference(propKey, serverValue, nextProp);
6652 }
6653 }
6654 }
6655 }
6656
6657 {
6658 // $FlowFixMe - Should be inferred as not undefined.
6659 if (extraAttributeNames.size > 0 && !suppressHydrationWarning) {
6660 // $FlowFixMe - Should be inferred as not undefined.
6661 warnForExtraAttributes(extraAttributeNames);
6662 }
6663 }
6664
6665 switch (tag) {
6666 case 'input':
6667 // TODO: Make sure we check if this is still unmounted or do any clean
6668 // up necessary since we never stop tracking anymore.
6669 track(domElement);
6670 postMountWrapper(domElement, rawProps, true);
6671 break;
6672
6673 case 'textarea':
6674 // TODO: Make sure we check if this is still unmounted or do any clean
6675 // up necessary since we never stop tracking anymore.
6676 track(domElement);
6677 postMountWrapper$3(domElement);
6678 break;
6679
6680 case 'select':
6681 case 'option':
6682 // For input and textarea we current always set the value property at
6683 // post mount to force it to diverge from attributes. However, for
6684 // option and select we don't quite do the same thing and select
6685 // is not resilient to the DOM state changing so we don't do that here.
6686 // TODO: Consider not doing this for input and textarea.
6687 break;
6688
6689 default:
6690 if (typeof rawProps.onClick === 'function') {
6691 // TODO: This cast may not be sound for SVG, MathML or custom elements.
6692 trapClickOnNonInteractiveElement(domElement);
6693 }
6694
6695 break;
6696 }
6697
6698 return updatePayload;
6699 }
6700 function diffHydratedText(textNode, text) {
6701 var isDifferent = textNode.nodeValue !== text;
6702 return isDifferent;
6703 }
6704 function warnForUnmatchedText(textNode, text) {
6705 {
6706 warnForTextDifference(textNode.nodeValue, text);
6707 }
6708 }
6709 function warnForDeletedHydratableElement(parentNode, child) {
6710 {
6711 if (didWarnInvalidHydration) {
6712 return;
6713 }
6714
6715 didWarnInvalidHydration = true;
6716
6717 error('Did not expect server HTML to contain a <%s> in <%s>.', child.nodeName.toLowerCase(), parentNode.nodeName.toLowerCase());
6718 }
6719 }
6720 function warnForDeletedHydratableText(parentNode, child) {
6721 {
6722 if (didWarnInvalidHydration) {
6723 return;
6724 }
6725
6726 didWarnInvalidHydration = true;
6727
6728 error('Did not expect server HTML to contain the text node "%s" in <%s>.', child.nodeValue, parentNode.nodeName.toLowerCase());
6729 }
6730 }
6731 function warnForInsertedHydratedElement(parentNode, tag, props) {
6732 {
6733 if (didWarnInvalidHydration) {
6734 return;
6735 }
6736
6737 didWarnInvalidHydration = true;
6738
6739 error('Expected server HTML to contain a matching <%s> in <%s>.', tag, parentNode.nodeName.toLowerCase());
6740 }
6741 }
6742 function warnForInsertedHydratedText(parentNode, text) {
6743 {
6744 if (text === '') {
6745 // We expect to insert empty text nodes since they're not represented in
6746 // the HTML.
6747 // TODO: Remove this special case if we can just avoid inserting empty
6748 // text nodes.
6749 return;
6750 }
6751
6752 if (didWarnInvalidHydration) {
6753 return;
6754 }
6755
6756 didWarnInvalidHydration = true;
6757
6758 error('Expected server HTML to contain a matching text node for "%s" in <%s>.', text, parentNode.nodeName.toLowerCase());
6759 }
6760 }
6761 function restoreControlledState$3(domElement, tag, props) {
6762 switch (tag) {
6763 case 'input':
6764 restoreControlledState(domElement, props);
6765 return;
6766
6767 case 'textarea':
6768 restoreControlledState$2(domElement, props);
6769 return;
6770
6771 case 'select':
6772 restoreControlledState$1(domElement, props);
6773 return;
6774 }
6775 }
6776
6777 function getActiveElement(doc) {
6778 doc = doc || (typeof document !== 'undefined' ? document : undefined);
6779
6780 if (typeof doc === 'undefined') {
6781 return null;
6782 }
6783
6784 try {
6785 return doc.activeElement || doc.body;
6786 } catch (e) {
6787 return doc.body;
6788 }
6789 }
6790
6791 /**
6792 * Given any node return the first leaf node without children.
6793 *
6794 * @param {DOMElement|DOMTextNode} node
6795 * @return {DOMElement|DOMTextNode}
6796 */
6797
6798 function getLeafNode(node) {
6799 while (node && node.firstChild) {
6800 node = node.firstChild;
6801 }
6802
6803 return node;
6804 }
6805 /**
6806 * Get the next sibling within a container. This will walk up the
6807 * DOM if a node's siblings have been exhausted.
6808 *
6809 * @param {DOMElement|DOMTextNode} node
6810 * @return {?DOMElement|DOMTextNode}
6811 */
6812
6813
6814 function getSiblingNode(node) {
6815 while (node) {
6816 if (node.nextSibling) {
6817 return node.nextSibling;
6818 }
6819
6820 node = node.parentNode;
6821 }
6822 }
6823 /**
6824 * Get object describing the nodes which contain characters at offset.
6825 *
6826 * @param {DOMElement|DOMTextNode} root
6827 * @param {number} offset
6828 * @return {?object}
6829 */
6830
6831
6832 function getNodeForCharacterOffset(root, offset) {
6833 var node = getLeafNode(root);
6834 var nodeStart = 0;
6835 var nodeEnd = 0;
6836
6837 while (node) {
6838 if (node.nodeType === TEXT_NODE) {
6839 nodeEnd = nodeStart + node.textContent.length;
6840
6841 if (nodeStart <= offset && nodeEnd >= offset) {
6842 return {
6843 node: node,
6844 offset: offset - nodeStart
6845 };
6846 }
6847
6848 nodeStart = nodeEnd;
6849 }
6850
6851 node = getLeafNode(getSiblingNode(node));
6852 }
6853 }
6854
6855 /**
6856 * @param {DOMElement} outerNode
6857 * @return {?object}
6858 */
6859
6860 function getOffsets(outerNode) {
6861 var ownerDocument = outerNode.ownerDocument;
6862 var win = ownerDocument && ownerDocument.defaultView || window;
6863 var selection = win.getSelection && win.getSelection();
6864
6865 if (!selection || selection.rangeCount === 0) {
6866 return null;
6867 }
6868
6869 var anchorNode = selection.anchorNode,
6870 anchorOffset = selection.anchorOffset,
6871 focusNode = selection.focusNode,
6872 focusOffset = selection.focusOffset; // In Firefox, anchorNode and focusNode can be "anonymous divs", e.g. the
6873 // up/down buttons on an <input type="number">. Anonymous divs do not seem to
6874 // expose properties, triggering a "Permission denied error" if any of its
6875 // properties are accessed. The only seemingly possible way to avoid erroring
6876 // is to access a property that typically works for non-anonymous divs and
6877 // catch any error that may otherwise arise. See
6878 // https://bugzilla.mozilla.org/show_bug.cgi?id=208427
6879
6880 try {
6881 /* eslint-disable no-unused-expressions */
6882 anchorNode.nodeType;
6883 focusNode.nodeType;
6884 /* eslint-enable no-unused-expressions */
6885 } catch (e) {
6886 return null;
6887 }
6888
6889 return getModernOffsetsFromPoints(outerNode, anchorNode, anchorOffset, focusNode, focusOffset);
6890 }
6891 /**
6892 * Returns {start, end} where `start` is the character/codepoint index of
6893 * (anchorNode, anchorOffset) within the textContent of `outerNode`, and
6894 * `end` is the index of (focusNode, focusOffset).
6895 *
6896 * Returns null if you pass in garbage input but we should probably just crash.
6897 *
6898 * Exported only for testing.
6899 */
6900
6901 function getModernOffsetsFromPoints(outerNode, anchorNode, anchorOffset, focusNode, focusOffset) {
6902 var length = 0;
6903 var start = -1;
6904 var end = -1;
6905 var indexWithinAnchor = 0;
6906 var indexWithinFocus = 0;
6907 var node = outerNode;
6908 var parentNode = null;
6909
6910 outer: while (true) {
6911 var next = null;
6912
6913 while (true) {
6914 if (node === anchorNode && (anchorOffset === 0 || node.nodeType === TEXT_NODE)) {
6915 start = length + anchorOffset;
6916 }
6917
6918 if (node === focusNode && (focusOffset === 0 || node.nodeType === TEXT_NODE)) {
6919 end = length + focusOffset;
6920 }
6921
6922 if (node.nodeType === TEXT_NODE) {
6923 length += node.nodeValue.length;
6924 }
6925
6926 if ((next = node.firstChild) === null) {
6927 break;
6928 } // Moving from `node` to its first child `next`.
6929
6930
6931 parentNode = node;
6932 node = next;
6933 }
6934
6935 while (true) {
6936 if (node === outerNode) {
6937 // If `outerNode` has children, this is always the second time visiting
6938 // it. If it has no children, this is still the first loop, and the only
6939 // valid selection is anchorNode and focusNode both equal to this node
6940 // and both offsets 0, in which case we will have handled above.
6941 break outer;
6942 }
6943
6944 if (parentNode === anchorNode && ++indexWithinAnchor === anchorOffset) {
6945 start = length;
6946 }
6947
6948 if (parentNode === focusNode && ++indexWithinFocus === focusOffset) {
6949 end = length;
6950 }
6951
6952 if ((next = node.nextSibling) !== null) {
6953 break;
6954 }
6955
6956 node = parentNode;
6957 parentNode = node.parentNode;
6958 } // Moving from `node` to its next sibling `next`.
6959
6960
6961 node = next;
6962 }
6963
6964 if (start === -1 || end === -1) {
6965 // This should never happen. (Would happen if the anchor/focus nodes aren't
6966 // actually inside the passed-in node.)
6967 return null;
6968 }
6969
6970 return {
6971 start: start,
6972 end: end
6973 };
6974 }
6975 /**
6976 * In modern non-IE browsers, we can support both forward and backward
6977 * selections.
6978 *
6979 * Note: IE10+ supports the Selection object, but it does not support
6980 * the `extend` method, which means that even in modern IE, it's not possible
6981 * to programmatically create a backward selection. Thus, for all IE
6982 * versions, we use the old IE API to create our selections.
6983 *
6984 * @param {DOMElement|DOMTextNode} node
6985 * @param {object} offsets
6986 */
6987
6988 function setOffsets(node, offsets) {
6989 var doc = node.ownerDocument || document;
6990 var win = doc && doc.defaultView || window; // Edge fails with "Object expected" in some scenarios.
6991 // (For instance: TinyMCE editor used in a list component that supports pasting to add more,
6992 // fails when pasting 100+ items)
6993
6994 if (!win.getSelection) {
6995 return;
6996 }
6997
6998 var selection = win.getSelection();
6999 var length = node.textContent.length;
7000 var start = Math.min(offsets.start, length);
7001 var end = offsets.end === undefined ? start : Math.min(offsets.end, length); // IE 11 uses modern selection, but doesn't support the extend method.
7002 // Flip backward selections, so we can set with a single range.
7003
7004 if (!selection.extend && start > end) {
7005 var temp = end;
7006 end = start;
7007 start = temp;
7008 }
7009
7010 var startMarker = getNodeForCharacterOffset(node, start);
7011 var endMarker = getNodeForCharacterOffset(node, end);
7012
7013 if (startMarker && endMarker) {
7014 if (selection.rangeCount === 1 && selection.anchorNode === startMarker.node && selection.anchorOffset === startMarker.offset && selection.focusNode === endMarker.node && selection.focusOffset === endMarker.offset) {
7015 return;
7016 }
7017
7018 var range = doc.createRange();
7019 range.setStart(startMarker.node, startMarker.offset);
7020 selection.removeAllRanges();
7021
7022 if (start > end) {
7023 selection.addRange(range);
7024 selection.extend(endMarker.node, endMarker.offset);
7025 } else {
7026 range.setEnd(endMarker.node, endMarker.offset);
7027 selection.addRange(range);
7028 }
7029 }
7030 }
7031
7032 function isTextNode(node) {
7033 return node && node.nodeType === TEXT_NODE;
7034 }
7035
7036 function containsNode(outerNode, innerNode) {
7037 if (!outerNode || !innerNode) {
7038 return false;
7039 } else if (outerNode === innerNode) {
7040 return true;
7041 } else if (isTextNode(outerNode)) {
7042 return false;
7043 } else if (isTextNode(innerNode)) {
7044 return containsNode(outerNode, innerNode.parentNode);
7045 } else if ('contains' in outerNode) {
7046 return outerNode.contains(innerNode);
7047 } else if (outerNode.compareDocumentPosition) {
7048 return !!(outerNode.compareDocumentPosition(innerNode) & 16);
7049 } else {
7050 return false;
7051 }
7052 }
7053
7054 function isInDocument(node) {
7055 return node && node.ownerDocument && containsNode(node.ownerDocument.documentElement, node);
7056 }
7057
7058 function isSameOriginFrame(iframe) {
7059 try {
7060 // Accessing the contentDocument of a HTMLIframeElement can cause the browser
7061 // to throw, e.g. if it has a cross-origin src attribute.
7062 // Safari will show an error in the console when the access results in "Blocked a frame with origin". e.g:
7063 // iframe.contentDocument.defaultView;
7064 // A safety way is to access one of the cross origin properties: Window or Location
7065 // Which might result in "SecurityError" DOM Exception and it is compatible to Safari.
7066 // https://html.spec.whatwg.org/multipage/browsers.html#integration-with-idl
7067 return typeof iframe.contentWindow.location.href === 'string';
7068 } catch (err) {
7069 return false;
7070 }
7071 }
7072
7073 function getActiveElementDeep() {
7074 var win = window;
7075 var element = getActiveElement();
7076
7077 while (element instanceof win.HTMLIFrameElement) {
7078 if (isSameOriginFrame(element)) {
7079 win = element.contentWindow;
7080 } else {
7081 return element;
7082 }
7083
7084 element = getActiveElement(win.document);
7085 }
7086
7087 return element;
7088 }
7089 /**
7090 * @ReactInputSelection: React input selection module. Based on Selection.js,
7091 * but modified to be suitable for react and has a couple of bug fixes (doesn't
7092 * assume buttons have range selections allowed).
7093 * Input selection module for React.
7094 */
7095
7096 /**
7097 * @hasSelectionCapabilities: we get the element types that support selection
7098 * from https://html.spec.whatwg.org/#do-not-apply, looking at `selectionStart`
7099 * and `selectionEnd` rows.
7100 */
7101
7102
7103 function hasSelectionCapabilities(elem) {
7104 var nodeName = elem && elem.nodeName && elem.nodeName.toLowerCase();
7105 return nodeName && (nodeName === 'input' && (elem.type === 'text' || elem.type === 'search' || elem.type === 'tel' || elem.type === 'url' || elem.type === 'password') || nodeName === 'textarea' || elem.contentEditable === 'true');
7106 }
7107 function getSelectionInformation() {
7108 var focusedElem = getActiveElementDeep();
7109 return {
7110 // Used by Flare
7111 activeElementDetached: null,
7112 focusedElem: focusedElem,
7113 selectionRange: hasSelectionCapabilities(focusedElem) ? getSelection(focusedElem) : null
7114 };
7115 }
7116 /**
7117 * @restoreSelection: If any selection information was potentially lost,
7118 * restore it. This is useful when performing operations that could remove dom
7119 * nodes and place them back in, resulting in focus being lost.
7120 */
7121
7122 function restoreSelection(priorSelectionInformation) {
7123 var curFocusedElem = getActiveElementDeep();
7124 var priorFocusedElem = priorSelectionInformation.focusedElem;
7125 var priorSelectionRange = priorSelectionInformation.selectionRange;
7126
7127 if (curFocusedElem !== priorFocusedElem && isInDocument(priorFocusedElem)) {
7128 if (priorSelectionRange !== null && hasSelectionCapabilities(priorFocusedElem)) {
7129 setSelection(priorFocusedElem, priorSelectionRange);
7130 } // Focusing a node can change the scroll position, which is undesirable
7131
7132
7133 var ancestors = [];
7134 var ancestor = priorFocusedElem;
7135
7136 while (ancestor = ancestor.parentNode) {
7137 if (ancestor.nodeType === ELEMENT_NODE) {
7138 ancestors.push({
7139 element: ancestor,
7140 left: ancestor.scrollLeft,
7141 top: ancestor.scrollTop
7142 });
7143 }
7144 }
7145
7146 if (typeof priorFocusedElem.focus === 'function') {
7147 priorFocusedElem.focus();
7148 }
7149
7150 for (var i = 0; i < ancestors.length; i++) {
7151 var info = ancestors[i];
7152 info.element.scrollLeft = info.left;
7153 info.element.scrollTop = info.top;
7154 }
7155 }
7156 }
7157 /**
7158 * @getSelection: Gets the selection bounds of a focused textarea, input or
7159 * contentEditable node.
7160 * -@input: Look up selection bounds of this input
7161 * -@return {start: selectionStart, end: selectionEnd}
7162 */
7163
7164 function getSelection(input) {
7165 var selection;
7166
7167 if ('selectionStart' in input) {
7168 // Modern browser with input or textarea.
7169 selection = {
7170 start: input.selectionStart,
7171 end: input.selectionEnd
7172 };
7173 } else {
7174 // Content editable or old IE textarea.
7175 selection = getOffsets(input);
7176 }
7177
7178 return selection || {
7179 start: 0,
7180 end: 0
7181 };
7182 }
7183 /**
7184 * @setSelection: Sets the selection bounds of a textarea or input and focuses
7185 * the input.
7186 * -@input Set selection bounds of this input or textarea
7187 * -@offsets Object of same form that is returned from get*
7188 */
7189
7190 function setSelection(input, offsets) {
7191 var start = offsets.start,
7192 end = offsets.end;
7193
7194 if (end === undefined) {
7195 end = start;
7196 }
7197
7198 if ('selectionStart' in input) {
7199 input.selectionStart = start;
7200 input.selectionEnd = Math.min(end, input.value.length);
7201 } else {
7202 setOffsets(input, offsets);
7203 }
7204 }
7205
7206 var validateDOMNesting = function () {};
7207
7208 var updatedAncestorInfo = function () {};
7209
7210 {
7211 // This validation code was written based on the HTML5 parsing spec:
7212 // https://html.spec.whatwg.org/multipage/syntax.html#has-an-element-in-scope
7213 //
7214 // Note: this does not catch all invalid nesting, nor does it try to (as it's
7215 // not clear what practical benefit doing so provides); instead, we warn only
7216 // for cases where the parser will give a parse tree differing from what React
7217 // intended. For example, <b><div></div></b> is invalid but we don't warn
7218 // because it still parses correctly; we do warn for other cases like nested
7219 // <p> tags where the beginning of the second element implicitly closes the
7220 // first, causing a confusing mess.
7221 // https://html.spec.whatwg.org/multipage/syntax.html#special
7222 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']; // https://html.spec.whatwg.org/multipage/syntax.html#has-an-element-in-scope
7223
7224 var inScopeTags = ['applet', 'caption', 'html', 'table', 'td', 'th', 'marquee', 'object', 'template', // https://html.spec.whatwg.org/multipage/syntax.html#html-integration-point
7225 // TODO: Distinguish by namespace here -- for <title>, including it here
7226 // errs on the side of fewer warnings
7227 'foreignObject', 'desc', 'title']; // https://html.spec.whatwg.org/multipage/syntax.html#has-an-element-in-button-scope
7228
7229 var buttonScopeTags = inScopeTags.concat(['button']); // https://html.spec.whatwg.org/multipage/syntax.html#generate-implied-end-tags
7230
7231 var impliedEndTags = ['dd', 'dt', 'li', 'option', 'optgroup', 'p', 'rp', 'rt'];
7232 var emptyAncestorInfo = {
7233 current: null,
7234 formTag: null,
7235 aTagInScope: null,
7236 buttonTagInScope: null,
7237 nobrTagInScope: null,
7238 pTagInButtonScope: null,
7239 listItemTagAutoclosing: null,
7240 dlItemTagAutoclosing: null
7241 };
7242
7243 updatedAncestorInfo = function (oldInfo, tag) {
7244 var ancestorInfo = _assign({}, oldInfo || emptyAncestorInfo);
7245
7246 var info = {
7247 tag: tag
7248 };
7249
7250 if (inScopeTags.indexOf(tag) !== -1) {
7251 ancestorInfo.aTagInScope = null;
7252 ancestorInfo.buttonTagInScope = null;
7253 ancestorInfo.nobrTagInScope = null;
7254 }
7255
7256 if (buttonScopeTags.indexOf(tag) !== -1) {
7257 ancestorInfo.pTagInButtonScope = null;
7258 } // See rules for 'li', 'dd', 'dt' start tags in
7259 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inbody
7260
7261
7262 if (specialTags.indexOf(tag) !== -1 && tag !== 'address' && tag !== 'div' && tag !== 'p') {
7263 ancestorInfo.listItemTagAutoclosing = null;
7264 ancestorInfo.dlItemTagAutoclosing = null;
7265 }
7266
7267 ancestorInfo.current = info;
7268
7269 if (tag === 'form') {
7270 ancestorInfo.formTag = info;
7271 }
7272
7273 if (tag === 'a') {
7274 ancestorInfo.aTagInScope = info;
7275 }
7276
7277 if (tag === 'button') {
7278 ancestorInfo.buttonTagInScope = info;
7279 }
7280
7281 if (tag === 'nobr') {
7282 ancestorInfo.nobrTagInScope = info;
7283 }
7284
7285 if (tag === 'p') {
7286 ancestorInfo.pTagInButtonScope = info;
7287 }
7288
7289 if (tag === 'li') {
7290 ancestorInfo.listItemTagAutoclosing = info;
7291 }
7292
7293 if (tag === 'dd' || tag === 'dt') {
7294 ancestorInfo.dlItemTagAutoclosing = info;
7295 }
7296
7297 return ancestorInfo;
7298 };
7299 /**
7300 * Returns whether
7301 */
7302
7303
7304 var isTagValidWithParent = function (tag, parentTag) {
7305 // First, let's check if we're in an unusual parsing mode...
7306 switch (parentTag) {
7307 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inselect
7308 case 'select':
7309 return tag === 'option' || tag === 'optgroup' || tag === '#text';
7310
7311 case 'optgroup':
7312 return tag === 'option' || tag === '#text';
7313 // Strictly speaking, seeing an <option> doesn't mean we're in a <select>
7314 // but
7315
7316 case 'option':
7317 return tag === '#text';
7318 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intd
7319 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-incaption
7320 // No special behavior since these rules fall back to "in body" mode for
7321 // all except special table nodes which cause bad parsing behavior anyway.
7322 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intr
7323
7324 case 'tr':
7325 return tag === 'th' || tag === 'td' || tag === 'style' || tag === 'script' || tag === 'template';
7326 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intbody
7327
7328 case 'tbody':
7329 case 'thead':
7330 case 'tfoot':
7331 return tag === 'tr' || tag === 'style' || tag === 'script' || tag === 'template';
7332 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-incolgroup
7333
7334 case 'colgroup':
7335 return tag === 'col' || tag === 'template';
7336 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intable
7337
7338 case 'table':
7339 return tag === 'caption' || tag === 'colgroup' || tag === 'tbody' || tag === 'tfoot' || tag === 'thead' || tag === 'style' || tag === 'script' || tag === 'template';
7340 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inhead
7341
7342 case 'head':
7343 return tag === 'base' || tag === 'basefont' || tag === 'bgsound' || tag === 'link' || tag === 'meta' || tag === 'title' || tag === 'noscript' || tag === 'noframes' || tag === 'style' || tag === 'script' || tag === 'template';
7344 // https://html.spec.whatwg.org/multipage/semantics.html#the-html-element
7345
7346 case 'html':
7347 return tag === 'head' || tag === 'body' || tag === 'frameset';
7348
7349 case 'frameset':
7350 return tag === 'frame';
7351
7352 case '#document':
7353 return tag === 'html';
7354 } // Probably in the "in body" parsing mode, so we outlaw only tag combos
7355 // where the parsing rules cause implicit opens or closes to be added.
7356 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inbody
7357
7358
7359 switch (tag) {
7360 case 'h1':
7361 case 'h2':
7362 case 'h3':
7363 case 'h4':
7364 case 'h5':
7365 case 'h6':
7366 return parentTag !== 'h1' && parentTag !== 'h2' && parentTag !== 'h3' && parentTag !== 'h4' && parentTag !== 'h5' && parentTag !== 'h6';
7367
7368 case 'rp':
7369 case 'rt':
7370 return impliedEndTags.indexOf(parentTag) === -1;
7371
7372 case 'body':
7373 case 'caption':
7374 case 'col':
7375 case 'colgroup':
7376 case 'frameset':
7377 case 'frame':
7378 case 'head':
7379 case 'html':
7380 case 'tbody':
7381 case 'td':
7382 case 'tfoot':
7383 case 'th':
7384 case 'thead':
7385 case 'tr':
7386 // These tags are only valid with a few parents that have special child
7387 // parsing rules -- if we're down here, then none of those matched and
7388 // so we allow it only if we don't know what the parent is, as all other
7389 // cases are invalid.
7390 return parentTag == null;
7391 }
7392
7393 return true;
7394 };
7395 /**
7396 * Returns whether
7397 */
7398
7399
7400 var findInvalidAncestorForTag = function (tag, ancestorInfo) {
7401 switch (tag) {
7402 case 'address':
7403 case 'article':
7404 case 'aside':
7405 case 'blockquote':
7406 case 'center':
7407 case 'details':
7408 case 'dialog':
7409 case 'dir':
7410 case 'div':
7411 case 'dl':
7412 case 'fieldset':
7413 case 'figcaption':
7414 case 'figure':
7415 case 'footer':
7416 case 'header':
7417 case 'hgroup':
7418 case 'main':
7419 case 'menu':
7420 case 'nav':
7421 case 'ol':
7422 case 'p':
7423 case 'section':
7424 case 'summary':
7425 case 'ul':
7426 case 'pre':
7427 case 'listing':
7428 case 'table':
7429 case 'hr':
7430 case 'xmp':
7431 case 'h1':
7432 case 'h2':
7433 case 'h3':
7434 case 'h4':
7435 case 'h5':
7436 case 'h6':
7437 return ancestorInfo.pTagInButtonScope;
7438
7439 case 'form':
7440 return ancestorInfo.formTag || ancestorInfo.pTagInButtonScope;
7441
7442 case 'li':
7443 return ancestorInfo.listItemTagAutoclosing;
7444
7445 case 'dd':
7446 case 'dt':
7447 return ancestorInfo.dlItemTagAutoclosing;
7448
7449 case 'button':
7450 return ancestorInfo.buttonTagInScope;
7451
7452 case 'a':
7453 // Spec says something about storing a list of markers, but it sounds
7454 // equivalent to this check.
7455 return ancestorInfo.aTagInScope;
7456
7457 case 'nobr':
7458 return ancestorInfo.nobrTagInScope;
7459 }
7460
7461 return null;
7462 };
7463
7464 var didWarn$1 = {};
7465
7466 validateDOMNesting = function (childTag, childText, ancestorInfo) {
7467 ancestorInfo = ancestorInfo || emptyAncestorInfo;
7468 var parentInfo = ancestorInfo.current;
7469 var parentTag = parentInfo && parentInfo.tag;
7470
7471 if (childText != null) {
7472 if (childTag != null) {
7473 error('validateDOMNesting: when childText is passed, childTag should be null');
7474 }
7475
7476 childTag = '#text';
7477 }
7478
7479 var invalidParent = isTagValidWithParent(childTag, parentTag) ? null : parentInfo;
7480 var invalidAncestor = invalidParent ? null : findInvalidAncestorForTag(childTag, ancestorInfo);
7481 var invalidParentOrAncestor = invalidParent || invalidAncestor;
7482
7483 if (!invalidParentOrAncestor) {
7484 return;
7485 }
7486
7487 var ancestorTag = invalidParentOrAncestor.tag;
7488 var addendum = getCurrentFiberStackInDev();
7489 var warnKey = !!invalidParent + '|' + childTag + '|' + ancestorTag + '|' + addendum;
7490
7491 if (didWarn$1[warnKey]) {
7492 return;
7493 }
7494
7495 didWarn$1[warnKey] = true;
7496 var tagDisplayName = childTag;
7497 var whitespaceInfo = '';
7498
7499 if (childTag === '#text') {
7500 if (/\S/.test(childText)) {
7501 tagDisplayName = 'Text nodes';
7502 } else {
7503 tagDisplayName = 'Whitespace text nodes';
7504 whitespaceInfo = " Make sure you don't have any extra whitespace between tags on " + 'each line of your source code.';
7505 }
7506 } else {
7507 tagDisplayName = '<' + childTag + '>';
7508 }
7509
7510 if (invalidParent) {
7511 var info = '';
7512
7513 if (ancestorTag === 'table' && childTag === 'tr') {
7514 info += ' Add a <tbody>, <thead> or <tfoot> to your code to match the DOM tree generated by ' + 'the browser.';
7515 }
7516
7517 error('validateDOMNesting(...): %s cannot appear as a child of <%s>.%s%s', tagDisplayName, ancestorTag, whitespaceInfo, info);
7518 } else {
7519 error('validateDOMNesting(...): %s cannot appear as a descendant of ' + '<%s>.', tagDisplayName, ancestorTag);
7520 }
7521 };
7522 }
7523
7524 var SUPPRESS_HYDRATION_WARNING$1;
7525
7526 {
7527 SUPPRESS_HYDRATION_WARNING$1 = 'suppressHydrationWarning';
7528 }
7529
7530 var SUSPENSE_START_DATA = '$';
7531 var SUSPENSE_END_DATA = '/$';
7532 var SUSPENSE_PENDING_START_DATA = '$?';
7533 var SUSPENSE_FALLBACK_START_DATA = '$!';
7534 var STYLE$1 = 'style';
7535 var eventsEnabled = null;
7536 var selectionInformation = null;
7537
7538 function shouldAutoFocusHostComponent(type, props) {
7539 switch (type) {
7540 case 'button':
7541 case 'input':
7542 case 'select':
7543 case 'textarea':
7544 return !!props.autoFocus;
7545 }
7546
7547 return false;
7548 }
7549 function getRootHostContext(rootContainerInstance) {
7550 var type;
7551 var namespace;
7552 var nodeType = rootContainerInstance.nodeType;
7553
7554 switch (nodeType) {
7555 case DOCUMENT_NODE:
7556 case DOCUMENT_FRAGMENT_NODE:
7557 {
7558 type = nodeType === DOCUMENT_NODE ? '#document' : '#fragment';
7559 var root = rootContainerInstance.documentElement;
7560 namespace = root ? root.namespaceURI : getChildNamespace(null, '');
7561 break;
7562 }
7563
7564 default:
7565 {
7566 var container = nodeType === COMMENT_NODE ? rootContainerInstance.parentNode : rootContainerInstance;
7567 var ownNamespace = container.namespaceURI || null;
7568 type = container.tagName;
7569 namespace = getChildNamespace(ownNamespace, type);
7570 break;
7571 }
7572 }
7573
7574 {
7575 var validatedTag = type.toLowerCase();
7576 var ancestorInfo = updatedAncestorInfo(null, validatedTag);
7577 return {
7578 namespace: namespace,
7579 ancestorInfo: ancestorInfo
7580 };
7581 }
7582 }
7583 function getChildHostContext(parentHostContext, type, rootContainerInstance) {
7584 {
7585 var parentHostContextDev = parentHostContext;
7586 var namespace = getChildNamespace(parentHostContextDev.namespace, type);
7587 var ancestorInfo = updatedAncestorInfo(parentHostContextDev.ancestorInfo, type);
7588 return {
7589 namespace: namespace,
7590 ancestorInfo: ancestorInfo
7591 };
7592 }
7593 }
7594 function getPublicInstance(instance) {
7595 return instance;
7596 }
7597 function prepareForCommit(containerInfo) {
7598 eventsEnabled = isEnabled();
7599 selectionInformation = getSelectionInformation();
7600 setEnabled(false);
7601 }
7602 function resetAfterCommit(containerInfo) {
7603 restoreSelection(selectionInformation);
7604 setEnabled(eventsEnabled);
7605 eventsEnabled = null;
7606
7607 selectionInformation = null;
7608 }
7609 function createInstance(type, props, rootContainerInstance, hostContext, internalInstanceHandle) {
7610 var parentNamespace;
7611
7612 {
7613 // TODO: take namespace into account when validating.
7614 var hostContextDev = hostContext;
7615 validateDOMNesting(type, null, hostContextDev.ancestorInfo);
7616
7617 if (typeof props.children === 'string' || typeof props.children === 'number') {
7618 var string = '' + props.children;
7619 var ownAncestorInfo = updatedAncestorInfo(hostContextDev.ancestorInfo, type);
7620 validateDOMNesting(null, string, ownAncestorInfo);
7621 }
7622
7623 parentNamespace = hostContextDev.namespace;
7624 }
7625
7626 var domElement = createElement(type, props, rootContainerInstance, parentNamespace);
7627 precacheFiberNode(internalInstanceHandle, domElement);
7628 updateFiberProps(domElement, props);
7629 return domElement;
7630 }
7631 function appendInitialChild(parentInstance, child) {
7632 parentInstance.appendChild(child);
7633 }
7634 function finalizeInitialChildren(domElement, type, props, rootContainerInstance, hostContext) {
7635 setInitialProperties(domElement, type, props, rootContainerInstance);
7636 return shouldAutoFocusHostComponent(type, props);
7637 }
7638 function prepareUpdate(domElement, type, oldProps, newProps, rootContainerInstance, hostContext) {
7639 {
7640 var hostContextDev = hostContext;
7641
7642 if (typeof newProps.children !== typeof oldProps.children && (typeof newProps.children === 'string' || typeof newProps.children === 'number')) {
7643 var string = '' + newProps.children;
7644 var ownAncestorInfo = updatedAncestorInfo(hostContextDev.ancestorInfo, type);
7645 validateDOMNesting(null, string, ownAncestorInfo);
7646 }
7647 }
7648
7649 return diffProperties(domElement, type, oldProps, newProps, rootContainerInstance);
7650 }
7651 function shouldSetTextContent(type, props) {
7652 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;
7653 }
7654 function shouldDeprioritizeSubtree(type, props) {
7655 return !!props.hidden;
7656 }
7657 function createTextInstance(text, rootContainerInstance, hostContext, internalInstanceHandle) {
7658 {
7659 var hostContextDev = hostContext;
7660 validateDOMNesting(null, text, hostContextDev.ancestorInfo);
7661 }
7662
7663 var textNode = createTextNode(text, rootContainerInstance);
7664 precacheFiberNode(internalInstanceHandle, textNode);
7665 return textNode;
7666 }
7667 // if a component just imports ReactDOM (e.g. for findDOMNode).
7668 // Some environments might not have setTimeout or clearTimeout.
7669
7670 var scheduleTimeout = typeof setTimeout === 'function' ? setTimeout : undefined;
7671 var cancelTimeout = typeof clearTimeout === 'function' ? clearTimeout : undefined;
7672 var noTimeout = -1; // -------------------
7673 function commitMount(domElement, type, newProps, internalInstanceHandle) {
7674 // Despite the naming that might imply otherwise, this method only
7675 // fires if there is an `Update` effect scheduled during mounting.
7676 // This happens if `finalizeInitialChildren` returns `true` (which it
7677 // does to implement the `autoFocus` attribute on the client). But
7678 // there are also other cases when this might happen (such as patching
7679 // up text content during hydration mismatch). So we'll check this again.
7680 if (shouldAutoFocusHostComponent(type, newProps)) {
7681 domElement.focus();
7682 }
7683 }
7684 function commitUpdate(domElement, updatePayload, type, oldProps, newProps, internalInstanceHandle) {
7685 // Update the props handle so that we know which props are the ones with
7686 // with current event handlers.
7687 updateFiberProps(domElement, newProps); // Apply the diff to the DOM node.
7688
7689 updateProperties(domElement, updatePayload, type, oldProps, newProps);
7690 }
7691 function resetTextContent(domElement) {
7692 setTextContent(domElement, '');
7693 }
7694 function commitTextUpdate(textInstance, oldText, newText) {
7695 textInstance.nodeValue = newText;
7696 }
7697 function appendChild(parentInstance, child) {
7698 parentInstance.appendChild(child);
7699 }
7700 function appendChildToContainer(container, child) {
7701 var parentNode;
7702
7703 if (container.nodeType === COMMENT_NODE) {
7704 parentNode = container.parentNode;
7705 parentNode.insertBefore(child, container);
7706 } else {
7707 parentNode = container;
7708 parentNode.appendChild(child);
7709 } // This container might be used for a portal.
7710 // If something inside a portal is clicked, that click should bubble
7711 // through the React tree. However, on Mobile Safari the click would
7712 // never bubble through the *DOM* tree unless an ancestor with onclick
7713 // event exists. So we wouldn't see it and dispatch it.
7714 // This is why we ensure that non React root containers have inline onclick
7715 // defined.
7716 // https://github.com/facebook/react/issues/11918
7717
7718
7719 var reactRootContainer = container._reactRootContainer;
7720
7721 if ((reactRootContainer === null || reactRootContainer === undefined) && parentNode.onclick === null) {
7722 // TODO: This cast may not be sound for SVG, MathML or custom elements.
7723 trapClickOnNonInteractiveElement(parentNode);
7724 }
7725 }
7726 function insertBefore(parentInstance, child, beforeChild) {
7727 parentInstance.insertBefore(child, beforeChild);
7728 }
7729 function insertInContainerBefore(container, child, beforeChild) {
7730 if (container.nodeType === COMMENT_NODE) {
7731 container.parentNode.insertBefore(child, beforeChild);
7732 } else {
7733 container.insertBefore(child, beforeChild);
7734 }
7735 }
7736 function removeChild(parentInstance, child) {
7737 parentInstance.removeChild(child);
7738 }
7739 function removeChildFromContainer(container, child) {
7740 if (container.nodeType === COMMENT_NODE) {
7741 container.parentNode.removeChild(child);
7742 } else {
7743 container.removeChild(child);
7744 }
7745 }
7746
7747 function hideInstance(instance) {
7748 // pass host context to this method?
7749
7750
7751 instance = instance;
7752 var style = instance.style;
7753
7754 if (typeof style.setProperty === 'function') {
7755 style.setProperty('display', 'none', 'important');
7756 } else {
7757 style.display = 'none';
7758 }
7759 }
7760 function hideTextInstance(textInstance) {
7761 textInstance.nodeValue = '';
7762 }
7763 function unhideInstance(instance, props) {
7764 instance = instance;
7765 var styleProp = props[STYLE$1];
7766 var display = styleProp !== undefined && styleProp !== null && styleProp.hasOwnProperty('display') ? styleProp.display : null;
7767 instance.style.display = dangerousStyleValue('display', display);
7768 }
7769 function unhideTextInstance(textInstance, text) {
7770 textInstance.nodeValue = text;
7771 } // -------------------
7772 function canHydrateInstance(instance, type, props) {
7773 if (instance.nodeType !== ELEMENT_NODE || type.toLowerCase() !== instance.nodeName.toLowerCase()) {
7774 return null;
7775 } // This has now been refined to an element node.
7776
7777
7778 return instance;
7779 }
7780 function canHydrateTextInstance(instance, text) {
7781 if (text === '' || instance.nodeType !== TEXT_NODE) {
7782 // Empty strings are not parsed by HTML so there won't be a correct match here.
7783 return null;
7784 } // This has now been refined to a text node.
7785
7786
7787 return instance;
7788 }
7789 function isSuspenseInstancePending(instance) {
7790 return instance.data === SUSPENSE_PENDING_START_DATA;
7791 }
7792 function isSuspenseInstanceFallback(instance) {
7793 return instance.data === SUSPENSE_FALLBACK_START_DATA;
7794 }
7795
7796 function getNextHydratable(node) {
7797 // Skip non-hydratable nodes.
7798 for (; node != null; node = node.nextSibling) {
7799 var nodeType = node.nodeType;
7800
7801 if (nodeType === ELEMENT_NODE || nodeType === TEXT_NODE) {
7802 break;
7803 }
7804 }
7805
7806 return node;
7807 }
7808
7809 function getNextHydratableSibling(instance) {
7810 return getNextHydratable(instance.nextSibling);
7811 }
7812 function getFirstHydratableChild(parentInstance) {
7813 return getNextHydratable(parentInstance.firstChild);
7814 }
7815 function hydrateInstance(instance, type, props, rootContainerInstance, hostContext, internalInstanceHandle) {
7816 precacheFiberNode(internalInstanceHandle, instance); // TODO: Possibly defer this until the commit phase where all the events
7817 // get attached.
7818
7819 updateFiberProps(instance, props);
7820 var parentNamespace;
7821
7822 {
7823 var hostContextDev = hostContext;
7824 parentNamespace = hostContextDev.namespace;
7825 }
7826
7827 return diffHydratedProperties(instance, type, props, parentNamespace, rootContainerInstance);
7828 }
7829 function hydrateTextInstance(textInstance, text, internalInstanceHandle) {
7830 precacheFiberNode(internalInstanceHandle, textInstance);
7831 return diffHydratedText(textInstance, text);
7832 }
7833 function getNextHydratableInstanceAfterSuspenseInstance(suspenseInstance) {
7834 var node = suspenseInstance.nextSibling; // Skip past all nodes within this suspense boundary.
7835 // There might be nested nodes so we need to keep track of how
7836 // deep we are and only break out when we're back on top.
7837
7838 var depth = 0;
7839
7840 while (node) {
7841 if (node.nodeType === COMMENT_NODE) {
7842 var data = node.data;
7843
7844 if (data === SUSPENSE_END_DATA) {
7845 if (depth === 0) {
7846 return getNextHydratableSibling(node);
7847 } else {
7848 depth--;
7849 }
7850 } else if (data === SUSPENSE_START_DATA || data === SUSPENSE_FALLBACK_START_DATA || data === SUSPENSE_PENDING_START_DATA) {
7851 depth++;
7852 }
7853 }
7854
7855 node = node.nextSibling;
7856 } // TODO: Warn, we didn't find the end comment boundary.
7857
7858
7859 return null;
7860 } // Returns the SuspenseInstance if this node is a direct child of a
7861 // SuspenseInstance. I.e. if its previous sibling is a Comment with
7862 // SUSPENSE_x_START_DATA. Otherwise, null.
7863
7864 function getParentSuspenseInstance(targetInstance) {
7865 var node = targetInstance.previousSibling; // Skip past all nodes within this suspense boundary.
7866 // There might be nested nodes so we need to keep track of how
7867 // deep we are and only break out when we're back on top.
7868
7869 var depth = 0;
7870
7871 while (node) {
7872 if (node.nodeType === COMMENT_NODE) {
7873 var data = node.data;
7874
7875 if (data === SUSPENSE_START_DATA || data === SUSPENSE_FALLBACK_START_DATA || data === SUSPENSE_PENDING_START_DATA) {
7876 if (depth === 0) {
7877 return node;
7878 } else {
7879 depth--;
7880 }
7881 } else if (data === SUSPENSE_END_DATA) {
7882 depth++;
7883 }
7884 }
7885
7886 node = node.previousSibling;
7887 }
7888
7889 return null;
7890 }
7891 function commitHydratedContainer(container) {
7892 // Retry if any event replaying was blocked on this.
7893 retryIfBlockedOn(container);
7894 }
7895 function commitHydratedSuspenseInstance(suspenseInstance) {
7896 // Retry if any event replaying was blocked on this.
7897 retryIfBlockedOn(suspenseInstance);
7898 }
7899 function didNotMatchHydratedContainerTextInstance(parentContainer, textInstance, text) {
7900 {
7901 warnForUnmatchedText(textInstance, text);
7902 }
7903 }
7904 function didNotMatchHydratedTextInstance(parentType, parentProps, parentInstance, textInstance, text) {
7905 if ( parentProps[SUPPRESS_HYDRATION_WARNING$1] !== true) {
7906 warnForUnmatchedText(textInstance, text);
7907 }
7908 }
7909 function didNotHydrateContainerInstance(parentContainer, instance) {
7910 {
7911 if (instance.nodeType === ELEMENT_NODE) {
7912 warnForDeletedHydratableElement(parentContainer, instance);
7913 } else if (instance.nodeType === COMMENT_NODE) ; else {
7914 warnForDeletedHydratableText(parentContainer, instance);
7915 }
7916 }
7917 }
7918 function didNotHydrateInstance(parentType, parentProps, parentInstance, instance) {
7919 if ( parentProps[SUPPRESS_HYDRATION_WARNING$1] !== true) {
7920 if (instance.nodeType === ELEMENT_NODE) {
7921 warnForDeletedHydratableElement(parentInstance, instance);
7922 } else if (instance.nodeType === COMMENT_NODE) ; else {
7923 warnForDeletedHydratableText(parentInstance, instance);
7924 }
7925 }
7926 }
7927 function didNotFindHydratableContainerInstance(parentContainer, type, props) {
7928 {
7929 warnForInsertedHydratedElement(parentContainer, type);
7930 }
7931 }
7932 function didNotFindHydratableContainerTextInstance(parentContainer, text) {
7933 {
7934 warnForInsertedHydratedText(parentContainer, text);
7935 }
7936 }
7937 function didNotFindHydratableInstance(parentType, parentProps, parentInstance, type, props) {
7938 if ( parentProps[SUPPRESS_HYDRATION_WARNING$1] !== true) {
7939 warnForInsertedHydratedElement(parentInstance, type);
7940 }
7941 }
7942 function didNotFindHydratableTextInstance(parentType, parentProps, parentInstance, text) {
7943 if ( parentProps[SUPPRESS_HYDRATION_WARNING$1] !== true) {
7944 warnForInsertedHydratedText(parentInstance, text);
7945 }
7946 }
7947 function didNotFindHydratableSuspenseInstance(parentType, parentProps, parentInstance) {
7948 if ( parentProps[SUPPRESS_HYDRATION_WARNING$1] !== true) ;
7949 }
7950
7951 var randomKey = Math.random().toString(36).slice(2);
7952 var internalInstanceKey = '__reactInternalInstance$' + randomKey;
7953 var internalEventHandlersKey = '__reactEventHandlers$' + randomKey;
7954 var internalContainerInstanceKey = '__reactContainere$' + randomKey;
7955 function precacheFiberNode(hostInst, node) {
7956 node[internalInstanceKey] = hostInst;
7957 }
7958 function markContainerAsRoot(hostRoot, node) {
7959 node[internalContainerInstanceKey] = hostRoot;
7960 }
7961 function unmarkContainerAsRoot(node) {
7962 node[internalContainerInstanceKey] = null;
7963 }
7964 function isContainerMarkedAsRoot(node) {
7965 return !!node[internalContainerInstanceKey];
7966 } // Given a DOM node, return the closest HostComponent or HostText fiber ancestor.
7967 // If the target node is part of a hydrated or not yet rendered subtree, then
7968 // this may also return a SuspenseComponent or HostRoot to indicate that.
7969 // Conceptually the HostRoot fiber is a child of the Container node. So if you
7970 // pass the Container node as the targetNode, you will not actually get the
7971 // HostRoot back. To get to the HostRoot, you need to pass a child of it.
7972 // The same thing applies to Suspense boundaries.
7973
7974 function getClosestInstanceFromNode(targetNode) {
7975 var targetInst = targetNode[internalInstanceKey];
7976
7977 if (targetInst) {
7978 // Don't return HostRoot or SuspenseComponent here.
7979 return targetInst;
7980 } // If the direct event target isn't a React owned DOM node, we need to look
7981 // to see if one of its parents is a React owned DOM node.
7982
7983
7984 var parentNode = targetNode.parentNode;
7985
7986 while (parentNode) {
7987 // We'll check if this is a container root that could include
7988 // React nodes in the future. We need to check this first because
7989 // if we're a child of a dehydrated container, we need to first
7990 // find that inner container before moving on to finding the parent
7991 // instance. Note that we don't check this field on the targetNode
7992 // itself because the fibers are conceptually between the container
7993 // node and the first child. It isn't surrounding the container node.
7994 // If it's not a container, we check if it's an instance.
7995 targetInst = parentNode[internalContainerInstanceKey] || parentNode[internalInstanceKey];
7996
7997 if (targetInst) {
7998 // Since this wasn't the direct target of the event, we might have
7999 // stepped past dehydrated DOM nodes to get here. However they could
8000 // also have been non-React nodes. We need to answer which one.
8001 // If we the instance doesn't have any children, then there can't be
8002 // a nested suspense boundary within it. So we can use this as a fast
8003 // bailout. Most of the time, when people add non-React children to
8004 // the tree, it is using a ref to a child-less DOM node.
8005 // Normally we'd only need to check one of the fibers because if it
8006 // has ever gone from having children to deleting them or vice versa
8007 // it would have deleted the dehydrated boundary nested inside already.
8008 // However, since the HostRoot starts out with an alternate it might
8009 // have one on the alternate so we need to check in case this was a
8010 // root.
8011 var alternate = targetInst.alternate;
8012
8013 if (targetInst.child !== null || alternate !== null && alternate.child !== null) {
8014 // Next we need to figure out if the node that skipped past is
8015 // nested within a dehydrated boundary and if so, which one.
8016 var suspenseInstance = getParentSuspenseInstance(targetNode);
8017
8018 while (suspenseInstance !== null) {
8019 // We found a suspense instance. That means that we haven't
8020 // hydrated it yet. Even though we leave the comments in the
8021 // DOM after hydrating, and there are boundaries in the DOM
8022 // that could already be hydrated, we wouldn't have found them
8023 // through this pass since if the target is hydrated it would
8024 // have had an internalInstanceKey on it.
8025 // Let's get the fiber associated with the SuspenseComponent
8026 // as the deepest instance.
8027 var targetSuspenseInst = suspenseInstance[internalInstanceKey];
8028
8029 if (targetSuspenseInst) {
8030 return targetSuspenseInst;
8031 } // If we don't find a Fiber on the comment, it might be because
8032 // we haven't gotten to hydrate it yet. There might still be a
8033 // parent boundary that hasn't above this one so we need to find
8034 // the outer most that is known.
8035
8036
8037 suspenseInstance = getParentSuspenseInstance(suspenseInstance); // If we don't find one, then that should mean that the parent
8038 // host component also hasn't hydrated yet. We can return it
8039 // below since it will bail out on the isMounted check later.
8040 }
8041 }
8042
8043 return targetInst;
8044 }
8045
8046 targetNode = parentNode;
8047 parentNode = targetNode.parentNode;
8048 }
8049
8050 return null;
8051 }
8052 /**
8053 * Given a DOM node, return the ReactDOMComponent or ReactDOMTextComponent
8054 * instance, or null if the node was not rendered by this React.
8055 */
8056
8057 function getInstanceFromNode$1(node) {
8058 var inst = node[internalInstanceKey] || node[internalContainerInstanceKey];
8059
8060 if (inst) {
8061 if (inst.tag === HostComponent || inst.tag === HostText || inst.tag === SuspenseComponent || inst.tag === HostRoot) {
8062 return inst;
8063 } else {
8064 return null;
8065 }
8066 }
8067
8068 return null;
8069 }
8070 /**
8071 * Given a ReactDOMComponent or ReactDOMTextComponent, return the corresponding
8072 * DOM node.
8073 */
8074
8075 function getNodeFromInstance$1(inst) {
8076 if (inst.tag === HostComponent || inst.tag === HostText) {
8077 // In Fiber this, is just the state node right now. We assume it will be
8078 // a host component or host text.
8079 return inst.stateNode;
8080 } // Without this first invariant, passing a non-DOM-component triggers the next
8081 // invariant for a missing parent, which is super confusing.
8082
8083
8084 {
8085 {
8086 throw Error( "getNodeFromInstance: Invalid argument." );
8087 }
8088 }
8089 }
8090 function getFiberCurrentPropsFromNode$1(node) {
8091 return node[internalEventHandlersKey] || null;
8092 }
8093 function updateFiberProps(node, props) {
8094 node[internalEventHandlersKey] = props;
8095 }
8096
8097 function getParent(inst) {
8098 do {
8099 inst = inst.return; // TODO: If this is a HostRoot we might want to bail out.
8100 // That is depending on if we want nested subtrees (layers) to bubble
8101 // events to their parent. We could also go through parentNode on the
8102 // host node but that wouldn't work for React Native and doesn't let us
8103 // do the portal feature.
8104 } while (inst && inst.tag !== HostComponent);
8105
8106 if (inst) {
8107 return inst;
8108 }
8109
8110 return null;
8111 }
8112 /**
8113 * Return the lowest common ancestor of A and B, or null if they are in
8114 * different trees.
8115 */
8116
8117
8118 function getLowestCommonAncestor(instA, instB) {
8119 var depthA = 0;
8120
8121 for (var tempA = instA; tempA; tempA = getParent(tempA)) {
8122 depthA++;
8123 }
8124
8125 var depthB = 0;
8126
8127 for (var tempB = instB; tempB; tempB = getParent(tempB)) {
8128 depthB++;
8129 } // If A is deeper, crawl up.
8130
8131
8132 while (depthA - depthB > 0) {
8133 instA = getParent(instA);
8134 depthA--;
8135 } // If B is deeper, crawl up.
8136
8137
8138 while (depthB - depthA > 0) {
8139 instB = getParent(instB);
8140 depthB--;
8141 } // Walk in lockstep until we find a match.
8142
8143
8144 var depth = depthA;
8145
8146 while (depth--) {
8147 if (instA === instB || instA === instB.alternate) {
8148 return instA;
8149 }
8150
8151 instA = getParent(instA);
8152 instB = getParent(instB);
8153 }
8154
8155 return null;
8156 }
8157 /**
8158 * Simulates the traversal of a two-phase, capture/bubble event dispatch.
8159 */
8160
8161 function traverseTwoPhase(inst, fn, arg) {
8162 var path = [];
8163
8164 while (inst) {
8165 path.push(inst);
8166 inst = getParent(inst);
8167 }
8168
8169 var i;
8170
8171 for (i = path.length; i-- > 0;) {
8172 fn(path[i], 'captured', arg);
8173 }
8174
8175 for (i = 0; i < path.length; i++) {
8176 fn(path[i], 'bubbled', arg);
8177 }
8178 }
8179 /**
8180 * Traverses the ID hierarchy and invokes the supplied `cb` on any IDs that
8181 * should would receive a `mouseEnter` or `mouseLeave` event.
8182 *
8183 * Does not invoke the callback on the nearest common ancestor because nothing
8184 * "entered" or "left" that element.
8185 */
8186
8187 function traverseEnterLeave(from, to, fn, argFrom, argTo) {
8188 var common = from && to ? getLowestCommonAncestor(from, to) : null;
8189 var pathFrom = [];
8190
8191 while (true) {
8192 if (!from) {
8193 break;
8194 }
8195
8196 if (from === common) {
8197 break;
8198 }
8199
8200 var alternate = from.alternate;
8201
8202 if (alternate !== null && alternate === common) {
8203 break;
8204 }
8205
8206 pathFrom.push(from);
8207 from = getParent(from);
8208 }
8209
8210 var pathTo = [];
8211
8212 while (true) {
8213 if (!to) {
8214 break;
8215 }
8216
8217 if (to === common) {
8218 break;
8219 }
8220
8221 var _alternate = to.alternate;
8222
8223 if (_alternate !== null && _alternate === common) {
8224 break;
8225 }
8226
8227 pathTo.push(to);
8228 to = getParent(to);
8229 }
8230
8231 for (var i = 0; i < pathFrom.length; i++) {
8232 fn(pathFrom[i], 'bubbled', argFrom);
8233 }
8234
8235 for (var _i = pathTo.length; _i-- > 0;) {
8236 fn(pathTo[_i], 'captured', argTo);
8237 }
8238 }
8239
8240 function isInteractive(tag) {
8241 return tag === 'button' || tag === 'input' || tag === 'select' || tag === 'textarea';
8242 }
8243
8244 function shouldPreventMouseEvent(name, type, props) {
8245 switch (name) {
8246 case 'onClick':
8247 case 'onClickCapture':
8248 case 'onDoubleClick':
8249 case 'onDoubleClickCapture':
8250 case 'onMouseDown':
8251 case 'onMouseDownCapture':
8252 case 'onMouseMove':
8253 case 'onMouseMoveCapture':
8254 case 'onMouseUp':
8255 case 'onMouseUpCapture':
8256 case 'onMouseEnter':
8257 return !!(props.disabled && isInteractive(type));
8258
8259 default:
8260 return false;
8261 }
8262 }
8263 /**
8264 * @param {object} inst The instance, which is the source of events.
8265 * @param {string} registrationName Name of listener (e.g. `onClick`).
8266 * @return {?function} The stored callback.
8267 */
8268
8269
8270 function getListener(inst, registrationName) {
8271 var listener; // TODO: shouldPreventMouseEvent is DOM-specific and definitely should not
8272 // live here; needs to be moved to a better place soon
8273
8274 var stateNode = inst.stateNode;
8275
8276 if (!stateNode) {
8277 // Work in progress (ex: onload events in incremental mode).
8278 return null;
8279 }
8280
8281 var props = getFiberCurrentPropsFromNode(stateNode);
8282
8283 if (!props) {
8284 // Work in progress.
8285 return null;
8286 }
8287
8288 listener = props[registrationName];
8289
8290 if (shouldPreventMouseEvent(registrationName, inst.type, props)) {
8291 return null;
8292 }
8293
8294 if (!(!listener || typeof listener === 'function')) {
8295 {
8296 throw Error( "Expected `" + registrationName + "` listener to be a function, instead got a value of `" + typeof listener + "` type." );
8297 }
8298 }
8299
8300 return listener;
8301 }
8302
8303 /**
8304 * Some event types have a notion of different registration names for different
8305 * "phases" of propagation. This finds listeners by a given phase.
8306 */
8307 function listenerAtPhase(inst, event, propagationPhase) {
8308 var registrationName = event.dispatchConfig.phasedRegistrationNames[propagationPhase];
8309 return getListener(inst, registrationName);
8310 }
8311 /**
8312 * A small set of propagation patterns, each of which will accept a small amount
8313 * of information, and generate a set of "dispatch ready event objects" - which
8314 * are sets of events that have already been annotated with a set of dispatched
8315 * listener functions/ids. The API is designed this way to discourage these
8316 * propagation strategies from actually executing the dispatches, since we
8317 * always want to collect the entire set of dispatches before executing even a
8318 * single one.
8319 */
8320
8321 /**
8322 * Tags a `SyntheticEvent` with dispatched listeners. Creating this function
8323 * here, allows us to not have to bind or create functions for each event.
8324 * Mutating the event's members allows us to not have to create a wrapping
8325 * "dispatch" object that pairs the event with the listener.
8326 */
8327
8328
8329 function accumulateDirectionalDispatches(inst, phase, event) {
8330 {
8331 if (!inst) {
8332 error('Dispatching inst must not be null');
8333 }
8334 }
8335
8336 var listener = listenerAtPhase(inst, event, phase);
8337
8338 if (listener) {
8339 event._dispatchListeners = accumulateInto(event._dispatchListeners, listener);
8340 event._dispatchInstances = accumulateInto(event._dispatchInstances, inst);
8341 }
8342 }
8343 /**
8344 * Collect dispatches (must be entirely collected before dispatching - see unit
8345 * tests). Lazily allocate the array to conserve memory. We must loop through
8346 * each event and perform the traversal for each one. We cannot perform a
8347 * single traversal for the entire collection of events because each event may
8348 * have a different target.
8349 */
8350
8351
8352 function accumulateTwoPhaseDispatchesSingle(event) {
8353 if (event && event.dispatchConfig.phasedRegistrationNames) {
8354 traverseTwoPhase(event._targetInst, accumulateDirectionalDispatches, event);
8355 }
8356 }
8357 /**
8358 * Accumulates without regard to direction, does not look for phased
8359 * registration names. Same as `accumulateDirectDispatchesSingle` but without
8360 * requiring that the `dispatchMarker` be the same as the dispatched ID.
8361 */
8362
8363
8364 function accumulateDispatches(inst, ignoredDirection, event) {
8365 if (inst && event && event.dispatchConfig.registrationName) {
8366 var registrationName = event.dispatchConfig.registrationName;
8367 var listener = getListener(inst, registrationName);
8368
8369 if (listener) {
8370 event._dispatchListeners = accumulateInto(event._dispatchListeners, listener);
8371 event._dispatchInstances = accumulateInto(event._dispatchInstances, inst);
8372 }
8373 }
8374 }
8375 /**
8376 * Accumulates dispatches on an `SyntheticEvent`, but only for the
8377 * `dispatchMarker`.
8378 * @param {SyntheticEvent} event
8379 */
8380
8381
8382 function accumulateDirectDispatchesSingle(event) {
8383 if (event && event.dispatchConfig.registrationName) {
8384 accumulateDispatches(event._targetInst, null, event);
8385 }
8386 }
8387
8388 function accumulateTwoPhaseDispatches(events) {
8389 forEachAccumulated(events, accumulateTwoPhaseDispatchesSingle);
8390 }
8391 function accumulateEnterLeaveDispatches(leave, enter, from, to) {
8392 traverseEnterLeave(from, to, accumulateDispatches, leave, enter);
8393 }
8394 function accumulateDirectDispatches(events) {
8395 forEachAccumulated(events, accumulateDirectDispatchesSingle);
8396 }
8397
8398 /**
8399 * These variables store information about text content of a target node,
8400 * allowing comparison of content before and after a given event.
8401 *
8402 * Identify the node where selection currently begins, then observe
8403 * both its text content and its current position in the DOM. Since the
8404 * browser may natively replace the target node during composition, we can
8405 * use its position to find its replacement.
8406 *
8407 *
8408 */
8409 var root = null;
8410 var startText = null;
8411 var fallbackText = null;
8412 function initialize(nativeEventTarget) {
8413 root = nativeEventTarget;
8414 startText = getText();
8415 return true;
8416 }
8417 function reset() {
8418 root = null;
8419 startText = null;
8420 fallbackText = null;
8421 }
8422 function getData() {
8423 if (fallbackText) {
8424 return fallbackText;
8425 }
8426
8427 var start;
8428 var startValue = startText;
8429 var startLength = startValue.length;
8430 var end;
8431 var endValue = getText();
8432 var endLength = endValue.length;
8433
8434 for (start = 0; start < startLength; start++) {
8435 if (startValue[start] !== endValue[start]) {
8436 break;
8437 }
8438 }
8439
8440 var minEnd = startLength - start;
8441
8442 for (end = 1; end <= minEnd; end++) {
8443 if (startValue[startLength - end] !== endValue[endLength - end]) {
8444 break;
8445 }
8446 }
8447
8448 var sliceTail = end > 1 ? 1 - end : undefined;
8449 fallbackText = endValue.slice(start, sliceTail);
8450 return fallbackText;
8451 }
8452 function getText() {
8453 if ('value' in root) {
8454 return root.value;
8455 }
8456
8457 return root.textContent;
8458 }
8459
8460 var EVENT_POOL_SIZE = 10;
8461 /**
8462 * @interface Event
8463 * @see http://www.w3.org/TR/DOM-Level-3-Events/
8464 */
8465
8466 var EventInterface = {
8467 type: null,
8468 target: null,
8469 // currentTarget is set when dispatching; no use in copying it here
8470 currentTarget: function () {
8471 return null;
8472 },
8473 eventPhase: null,
8474 bubbles: null,
8475 cancelable: null,
8476 timeStamp: function (event) {
8477 return event.timeStamp || Date.now();
8478 },
8479 defaultPrevented: null,
8480 isTrusted: null
8481 };
8482
8483 function functionThatReturnsTrue() {
8484 return true;
8485 }
8486
8487 function functionThatReturnsFalse() {
8488 return false;
8489 }
8490 /**
8491 * Synthetic events are dispatched by event plugins, typically in response to a
8492 * top-level event delegation handler.
8493 *
8494 * These systems should generally use pooling to reduce the frequency of garbage
8495 * collection. The system should check `isPersistent` to determine whether the
8496 * event should be released into the pool after being dispatched. Users that
8497 * need a persisted event should invoke `persist`.
8498 *
8499 * Synthetic events (and subclasses) implement the DOM Level 3 Events API by
8500 * normalizing browser quirks. Subclasses do not necessarily have to implement a
8501 * DOM interface; custom application-specific events can also subclass this.
8502 *
8503 * @param {object} dispatchConfig Configuration used to dispatch this event.
8504 * @param {*} targetInst Marker identifying the event target.
8505 * @param {object} nativeEvent Native browser event.
8506 * @param {DOMEventTarget} nativeEventTarget Target node.
8507 */
8508
8509
8510 function SyntheticEvent(dispatchConfig, targetInst, nativeEvent, nativeEventTarget) {
8511 {
8512 // these have a getter/setter for warnings
8513 delete this.nativeEvent;
8514 delete this.preventDefault;
8515 delete this.stopPropagation;
8516 delete this.isDefaultPrevented;
8517 delete this.isPropagationStopped;
8518 }
8519
8520 this.dispatchConfig = dispatchConfig;
8521 this._targetInst = targetInst;
8522 this.nativeEvent = nativeEvent;
8523 var Interface = this.constructor.Interface;
8524
8525 for (var propName in Interface) {
8526 if (!Interface.hasOwnProperty(propName)) {
8527 continue;
8528 }
8529
8530 {
8531 delete this[propName]; // this has a getter/setter for warnings
8532 }
8533
8534 var normalize = Interface[propName];
8535
8536 if (normalize) {
8537 this[propName] = normalize(nativeEvent);
8538 } else {
8539 if (propName === 'target') {
8540 this.target = nativeEventTarget;
8541 } else {
8542 this[propName] = nativeEvent[propName];
8543 }
8544 }
8545 }
8546
8547 var defaultPrevented = nativeEvent.defaultPrevented != null ? nativeEvent.defaultPrevented : nativeEvent.returnValue === false;
8548
8549 if (defaultPrevented) {
8550 this.isDefaultPrevented = functionThatReturnsTrue;
8551 } else {
8552 this.isDefaultPrevented = functionThatReturnsFalse;
8553 }
8554
8555 this.isPropagationStopped = functionThatReturnsFalse;
8556 return this;
8557 }
8558
8559 _assign(SyntheticEvent.prototype, {
8560 preventDefault: function () {
8561 this.defaultPrevented = true;
8562 var event = this.nativeEvent;
8563
8564 if (!event) {
8565 return;
8566 }
8567
8568 if (event.preventDefault) {
8569 event.preventDefault();
8570 } else if (typeof event.returnValue !== 'unknown') {
8571 event.returnValue = false;
8572 }
8573
8574 this.isDefaultPrevented = functionThatReturnsTrue;
8575 },
8576 stopPropagation: function () {
8577 var event = this.nativeEvent;
8578
8579 if (!event) {
8580 return;
8581 }
8582
8583 if (event.stopPropagation) {
8584 event.stopPropagation();
8585 } else if (typeof event.cancelBubble !== 'unknown') {
8586 // The ChangeEventPlugin registers a "propertychange" event for
8587 // IE. This event does not support bubbling or cancelling, and
8588 // any references to cancelBubble throw "Member not found". A
8589 // typeof check of "unknown" circumvents this issue (and is also
8590 // IE specific).
8591 event.cancelBubble = true;
8592 }
8593
8594 this.isPropagationStopped = functionThatReturnsTrue;
8595 },
8596
8597 /**
8598 * We release all dispatched `SyntheticEvent`s after each event loop, adding
8599 * them back into the pool. This allows a way to hold onto a reference that
8600 * won't be added back into the pool.
8601 */
8602 persist: function () {
8603 this.isPersistent = functionThatReturnsTrue;
8604 },
8605
8606 /**
8607 * Checks if this event should be released back into the pool.
8608 *
8609 * @return {boolean} True if this should not be released, false otherwise.
8610 */
8611 isPersistent: functionThatReturnsFalse,
8612
8613 /**
8614 * `PooledClass` looks for `destructor` on each instance it releases.
8615 */
8616 destructor: function () {
8617 var Interface = this.constructor.Interface;
8618
8619 for (var propName in Interface) {
8620 {
8621 Object.defineProperty(this, propName, getPooledWarningPropertyDefinition(propName, Interface[propName]));
8622 }
8623 }
8624
8625 this.dispatchConfig = null;
8626 this._targetInst = null;
8627 this.nativeEvent = null;
8628 this.isDefaultPrevented = functionThatReturnsFalse;
8629 this.isPropagationStopped = functionThatReturnsFalse;
8630 this._dispatchListeners = null;
8631 this._dispatchInstances = null;
8632
8633 {
8634 Object.defineProperty(this, 'nativeEvent', getPooledWarningPropertyDefinition('nativeEvent', null));
8635 Object.defineProperty(this, 'isDefaultPrevented', getPooledWarningPropertyDefinition('isDefaultPrevented', functionThatReturnsFalse));
8636 Object.defineProperty(this, 'isPropagationStopped', getPooledWarningPropertyDefinition('isPropagationStopped', functionThatReturnsFalse));
8637 Object.defineProperty(this, 'preventDefault', getPooledWarningPropertyDefinition('preventDefault', function () {}));
8638 Object.defineProperty(this, 'stopPropagation', getPooledWarningPropertyDefinition('stopPropagation', function () {}));
8639 }
8640 }
8641 });
8642
8643 SyntheticEvent.Interface = EventInterface;
8644 /**
8645 * Helper to reduce boilerplate when creating subclasses.
8646 */
8647
8648 SyntheticEvent.extend = function (Interface) {
8649 var Super = this;
8650
8651 var E = function () {};
8652
8653 E.prototype = Super.prototype;
8654 var prototype = new E();
8655
8656 function Class() {
8657 return Super.apply(this, arguments);
8658 }
8659
8660 _assign(prototype, Class.prototype);
8661
8662 Class.prototype = prototype;
8663 Class.prototype.constructor = Class;
8664 Class.Interface = _assign({}, Super.Interface, Interface);
8665 Class.extend = Super.extend;
8666 addEventPoolingTo(Class);
8667 return Class;
8668 };
8669
8670 addEventPoolingTo(SyntheticEvent);
8671 /**
8672 * Helper to nullify syntheticEvent instance properties when destructing
8673 *
8674 * @param {String} propName
8675 * @param {?object} getVal
8676 * @return {object} defineProperty object
8677 */
8678
8679 function getPooledWarningPropertyDefinition(propName, getVal) {
8680 var isFunction = typeof getVal === 'function';
8681 return {
8682 configurable: true,
8683 set: set,
8684 get: get
8685 };
8686
8687 function set(val) {
8688 var action = isFunction ? 'setting the method' : 'setting the property';
8689 warn(action, 'This is effectively a no-op');
8690 return val;
8691 }
8692
8693 function get() {
8694 var action = isFunction ? 'accessing the method' : 'accessing the property';
8695 var result = isFunction ? 'This is a no-op function' : 'This is set to null';
8696 warn(action, result);
8697 return getVal;
8698 }
8699
8700 function warn(action, result) {
8701 {
8702 error("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);
8703 }
8704 }
8705 }
8706
8707 function getPooledEvent(dispatchConfig, targetInst, nativeEvent, nativeInst) {
8708 var EventConstructor = this;
8709
8710 if (EventConstructor.eventPool.length) {
8711 var instance = EventConstructor.eventPool.pop();
8712 EventConstructor.call(instance, dispatchConfig, targetInst, nativeEvent, nativeInst);
8713 return instance;
8714 }
8715
8716 return new EventConstructor(dispatchConfig, targetInst, nativeEvent, nativeInst);
8717 }
8718
8719 function releasePooledEvent(event) {
8720 var EventConstructor = this;
8721
8722 if (!(event instanceof EventConstructor)) {
8723 {
8724 throw Error( "Trying to release an event instance into a pool of a different type." );
8725 }
8726 }
8727
8728 event.destructor();
8729
8730 if (EventConstructor.eventPool.length < EVENT_POOL_SIZE) {
8731 EventConstructor.eventPool.push(event);
8732 }
8733 }
8734
8735 function addEventPoolingTo(EventConstructor) {
8736 EventConstructor.eventPool = [];
8737 EventConstructor.getPooled = getPooledEvent;
8738 EventConstructor.release = releasePooledEvent;
8739 }
8740
8741 /**
8742 * @interface Event
8743 * @see http://www.w3.org/TR/DOM-Level-3-Events/#events-compositionevents
8744 */
8745
8746 var SyntheticCompositionEvent = SyntheticEvent.extend({
8747 data: null
8748 });
8749
8750 /**
8751 * @interface Event
8752 * @see http://www.w3.org/TR/2013/WD-DOM-Level-3-Events-20131105
8753 * /#events-inputevents
8754 */
8755
8756 var SyntheticInputEvent = SyntheticEvent.extend({
8757 data: null
8758 });
8759
8760 var END_KEYCODES = [9, 13, 27, 32]; // Tab, Return, Esc, Space
8761
8762 var START_KEYCODE = 229;
8763 var canUseCompositionEvent = canUseDOM && 'CompositionEvent' in window;
8764 var documentMode = null;
8765
8766 if (canUseDOM && 'documentMode' in document) {
8767 documentMode = document.documentMode;
8768 } // Webkit offers a very useful `textInput` event that can be used to
8769 // directly represent `beforeInput`. The IE `textinput` event is not as
8770 // useful, so we don't use it.
8771
8772
8773 var canUseTextInputEvent = canUseDOM && 'TextEvent' in window && !documentMode; // In IE9+, we have access to composition events, but the data supplied
8774 // by the native compositionend event may be incorrect. Japanese ideographic
8775 // spaces, for instance (\u3000) are not recorded correctly.
8776
8777 var useFallbackCompositionData = canUseDOM && (!canUseCompositionEvent || documentMode && documentMode > 8 && documentMode <= 11);
8778 var SPACEBAR_CODE = 32;
8779 var SPACEBAR_CHAR = String.fromCharCode(SPACEBAR_CODE); // Events and their corresponding property names.
8780
8781 var eventTypes = {
8782 beforeInput: {
8783 phasedRegistrationNames: {
8784 bubbled: 'onBeforeInput',
8785 captured: 'onBeforeInputCapture'
8786 },
8787 dependencies: [TOP_COMPOSITION_END, TOP_KEY_PRESS, TOP_TEXT_INPUT, TOP_PASTE]
8788 },
8789 compositionEnd: {
8790 phasedRegistrationNames: {
8791 bubbled: 'onCompositionEnd',
8792 captured: 'onCompositionEndCapture'
8793 },
8794 dependencies: [TOP_BLUR, TOP_COMPOSITION_END, TOP_KEY_DOWN, TOP_KEY_PRESS, TOP_KEY_UP, TOP_MOUSE_DOWN]
8795 },
8796 compositionStart: {
8797 phasedRegistrationNames: {
8798 bubbled: 'onCompositionStart',
8799 captured: 'onCompositionStartCapture'
8800 },
8801 dependencies: [TOP_BLUR, TOP_COMPOSITION_START, TOP_KEY_DOWN, TOP_KEY_PRESS, TOP_KEY_UP, TOP_MOUSE_DOWN]
8802 },
8803 compositionUpdate: {
8804 phasedRegistrationNames: {
8805 bubbled: 'onCompositionUpdate',
8806 captured: 'onCompositionUpdateCapture'
8807 },
8808 dependencies: [TOP_BLUR, TOP_COMPOSITION_UPDATE, TOP_KEY_DOWN, TOP_KEY_PRESS, TOP_KEY_UP, TOP_MOUSE_DOWN]
8809 }
8810 }; // Track whether we've ever handled a keypress on the space key.
8811
8812 var hasSpaceKeypress = false;
8813 /**
8814 * Return whether a native keypress event is assumed to be a command.
8815 * This is required because Firefox fires `keypress` events for key commands
8816 * (cut, copy, select-all, etc.) even though no character is inserted.
8817 */
8818
8819 function isKeypressCommand(nativeEvent) {
8820 return (nativeEvent.ctrlKey || nativeEvent.altKey || nativeEvent.metaKey) && // ctrlKey && altKey is equivalent to AltGr, and is not a command.
8821 !(nativeEvent.ctrlKey && nativeEvent.altKey);
8822 }
8823 /**
8824 * Translate native top level events into event types.
8825 *
8826 * @param {string} topLevelType
8827 * @return {object}
8828 */
8829
8830
8831 function getCompositionEventType(topLevelType) {
8832 switch (topLevelType) {
8833 case TOP_COMPOSITION_START:
8834 return eventTypes.compositionStart;
8835
8836 case TOP_COMPOSITION_END:
8837 return eventTypes.compositionEnd;
8838
8839 case TOP_COMPOSITION_UPDATE:
8840 return eventTypes.compositionUpdate;
8841 }
8842 }
8843 /**
8844 * Does our fallback best-guess model think this event signifies that
8845 * composition has begun?
8846 *
8847 * @param {string} topLevelType
8848 * @param {object} nativeEvent
8849 * @return {boolean}
8850 */
8851
8852
8853 function isFallbackCompositionStart(topLevelType, nativeEvent) {
8854 return topLevelType === TOP_KEY_DOWN && nativeEvent.keyCode === START_KEYCODE;
8855 }
8856 /**
8857 * Does our fallback mode think that this event is the end of composition?
8858 *
8859 * @param {string} topLevelType
8860 * @param {object} nativeEvent
8861 * @return {boolean}
8862 */
8863
8864
8865 function isFallbackCompositionEnd(topLevelType, nativeEvent) {
8866 switch (topLevelType) {
8867 case TOP_KEY_UP:
8868 // Command keys insert or clear IME input.
8869 return END_KEYCODES.indexOf(nativeEvent.keyCode) !== -1;
8870
8871 case TOP_KEY_DOWN:
8872 // Expect IME keyCode on each keydown. If we get any other
8873 // code we must have exited earlier.
8874 return nativeEvent.keyCode !== START_KEYCODE;
8875
8876 case TOP_KEY_PRESS:
8877 case TOP_MOUSE_DOWN:
8878 case TOP_BLUR:
8879 // Events are not possible without cancelling IME.
8880 return true;
8881
8882 default:
8883 return false;
8884 }
8885 }
8886 /**
8887 * Google Input Tools provides composition data via a CustomEvent,
8888 * with the `data` property populated in the `detail` object. If this
8889 * is available on the event object, use it. If not, this is a plain
8890 * composition event and we have nothing special to extract.
8891 *
8892 * @param {object} nativeEvent
8893 * @return {?string}
8894 */
8895
8896
8897 function getDataFromCustomEvent(nativeEvent) {
8898 var detail = nativeEvent.detail;
8899
8900 if (typeof detail === 'object' && 'data' in detail) {
8901 return detail.data;
8902 }
8903
8904 return null;
8905 }
8906 /**
8907 * Check if a composition event was triggered by Korean IME.
8908 * Our fallback mode does not work well with IE's Korean IME,
8909 * so just use native composition events when Korean IME is used.
8910 * Although CompositionEvent.locale property is deprecated,
8911 * it is available in IE, where our fallback mode is enabled.
8912 *
8913 * @param {object} nativeEvent
8914 * @return {boolean}
8915 */
8916
8917
8918 function isUsingKoreanIME(nativeEvent) {
8919 return nativeEvent.locale === 'ko';
8920 } // Track the current IME composition status, if any.
8921
8922
8923 var isComposing = false;
8924 /**
8925 * @return {?object} A SyntheticCompositionEvent.
8926 */
8927
8928 function extractCompositionEvent(topLevelType, targetInst, nativeEvent, nativeEventTarget) {
8929 var eventType;
8930 var fallbackData;
8931
8932 if (canUseCompositionEvent) {
8933 eventType = getCompositionEventType(topLevelType);
8934 } else if (!isComposing) {
8935 if (isFallbackCompositionStart(topLevelType, nativeEvent)) {
8936 eventType = eventTypes.compositionStart;
8937 }
8938 } else if (isFallbackCompositionEnd(topLevelType, nativeEvent)) {
8939 eventType = eventTypes.compositionEnd;
8940 }
8941
8942 if (!eventType) {
8943 return null;
8944 }
8945
8946 if (useFallbackCompositionData && !isUsingKoreanIME(nativeEvent)) {
8947 // The current composition is stored statically and must not be
8948 // overwritten while composition continues.
8949 if (!isComposing && eventType === eventTypes.compositionStart) {
8950 isComposing = initialize(nativeEventTarget);
8951 } else if (eventType === eventTypes.compositionEnd) {
8952 if (isComposing) {
8953 fallbackData = getData();
8954 }
8955 }
8956 }
8957
8958 var event = SyntheticCompositionEvent.getPooled(eventType, targetInst, nativeEvent, nativeEventTarget);
8959
8960 if (fallbackData) {
8961 // Inject data generated from fallback path into the synthetic event.
8962 // This matches the property of native CompositionEventInterface.
8963 event.data = fallbackData;
8964 } else {
8965 var customData = getDataFromCustomEvent(nativeEvent);
8966
8967 if (customData !== null) {
8968 event.data = customData;
8969 }
8970 }
8971
8972 accumulateTwoPhaseDispatches(event);
8973 return event;
8974 }
8975 /**
8976 * @param {TopLevelType} topLevelType Number from `TopLevelType`.
8977 * @param {object} nativeEvent Native browser event.
8978 * @return {?string} The string corresponding to this `beforeInput` event.
8979 */
8980
8981
8982 function getNativeBeforeInputChars(topLevelType, nativeEvent) {
8983 switch (topLevelType) {
8984 case TOP_COMPOSITION_END:
8985 return getDataFromCustomEvent(nativeEvent);
8986
8987 case TOP_KEY_PRESS:
8988 /**
8989 * If native `textInput` events are available, our goal is to make
8990 * use of them. However, there is a special case: the spacebar key.
8991 * In Webkit, preventing default on a spacebar `textInput` event
8992 * cancels character insertion, but it *also* causes the browser
8993 * to fall back to its default spacebar behavior of scrolling the
8994 * page.
8995 *
8996 * Tracking at:
8997 * https://code.google.com/p/chromium/issues/detail?id=355103
8998 *
8999 * To avoid this issue, use the keypress event as if no `textInput`
9000 * event is available.
9001 */
9002 var which = nativeEvent.which;
9003
9004 if (which !== SPACEBAR_CODE) {
9005 return null;
9006 }
9007
9008 hasSpaceKeypress = true;
9009 return SPACEBAR_CHAR;
9010
9011 case TOP_TEXT_INPUT:
9012 // Record the characters to be added to the DOM.
9013 var chars = nativeEvent.data; // If it's a spacebar character, assume that we have already handled
9014 // it at the keypress level and bail immediately. Android Chrome
9015 // doesn't give us keycodes, so we need to ignore it.
9016
9017 if (chars === SPACEBAR_CHAR && hasSpaceKeypress) {
9018 return null;
9019 }
9020
9021 return chars;
9022
9023 default:
9024 // For other native event types, do nothing.
9025 return null;
9026 }
9027 }
9028 /**
9029 * For browsers that do not provide the `textInput` event, extract the
9030 * appropriate string to use for SyntheticInputEvent.
9031 *
9032 * @param {number} topLevelType Number from `TopLevelEventTypes`.
9033 * @param {object} nativeEvent Native browser event.
9034 * @return {?string} The fallback string for this `beforeInput` event.
9035 */
9036
9037
9038 function getFallbackBeforeInputChars(topLevelType, nativeEvent) {
9039 // If we are currently composing (IME) and using a fallback to do so,
9040 // try to extract the composed characters from the fallback object.
9041 // If composition event is available, we extract a string only at
9042 // compositionevent, otherwise extract it at fallback events.
9043 if (isComposing) {
9044 if (topLevelType === TOP_COMPOSITION_END || !canUseCompositionEvent && isFallbackCompositionEnd(topLevelType, nativeEvent)) {
9045 var chars = getData();
9046 reset();
9047 isComposing = false;
9048 return chars;
9049 }
9050
9051 return null;
9052 }
9053
9054 switch (topLevelType) {
9055 case TOP_PASTE:
9056 // If a paste event occurs after a keypress, throw out the input
9057 // chars. Paste events should not lead to BeforeInput events.
9058 return null;
9059
9060 case TOP_KEY_PRESS:
9061 /**
9062 * As of v27, Firefox may fire keypress events even when no character
9063 * will be inserted. A few possibilities:
9064 *
9065 * - `which` is `0`. Arrow keys, Esc key, etc.
9066 *
9067 * - `which` is the pressed key code, but no char is available.
9068 * Ex: 'AltGr + d` in Polish. There is no modified character for
9069 * this key combination and no character is inserted into the
9070 * document, but FF fires the keypress for char code `100` anyway.
9071 * No `input` event will occur.
9072 *
9073 * - `which` is the pressed key code, but a command combination is
9074 * being used. Ex: `Cmd+C`. No character is inserted, and no
9075 * `input` event will occur.
9076 */
9077 if (!isKeypressCommand(nativeEvent)) {
9078 // IE fires the `keypress` event when a user types an emoji via
9079 // Touch keyboard of Windows. In such a case, the `char` property
9080 // holds an emoji character like `\uD83D\uDE0A`. Because its length
9081 // is 2, the property `which` does not represent an emoji correctly.
9082 // In such a case, we directly return the `char` property instead of
9083 // using `which`.
9084 if (nativeEvent.char && nativeEvent.char.length > 1) {
9085 return nativeEvent.char;
9086 } else if (nativeEvent.which) {
9087 return String.fromCharCode(nativeEvent.which);
9088 }
9089 }
9090
9091 return null;
9092
9093 case TOP_COMPOSITION_END:
9094 return useFallbackCompositionData && !isUsingKoreanIME(nativeEvent) ? null : nativeEvent.data;
9095
9096 default:
9097 return null;
9098 }
9099 }
9100 /**
9101 * Extract a SyntheticInputEvent for `beforeInput`, based on either native
9102 * `textInput` or fallback behavior.
9103 *
9104 * @return {?object} A SyntheticInputEvent.
9105 */
9106
9107
9108 function extractBeforeInputEvent(topLevelType, targetInst, nativeEvent, nativeEventTarget) {
9109 var chars;
9110
9111 if (canUseTextInputEvent) {
9112 chars = getNativeBeforeInputChars(topLevelType, nativeEvent);
9113 } else {
9114 chars = getFallbackBeforeInputChars(topLevelType, nativeEvent);
9115 } // If no characters are being inserted, no BeforeInput event should
9116 // be fired.
9117
9118
9119 if (!chars) {
9120 return null;
9121 }
9122
9123 var event = SyntheticInputEvent.getPooled(eventTypes.beforeInput, targetInst, nativeEvent, nativeEventTarget);
9124 event.data = chars;
9125 accumulateTwoPhaseDispatches(event);
9126 return event;
9127 }
9128 /**
9129 * Create an `onBeforeInput` event to match
9130 * http://www.w3.org/TR/2013/WD-DOM-Level-3-Events-20131105/#events-inputevents.
9131 *
9132 * This event plugin is based on the native `textInput` event
9133 * available in Chrome, Safari, Opera, and IE. This event fires after
9134 * `onKeyPress` and `onCompositionEnd`, but before `onInput`.
9135 *
9136 * `beforeInput` is spec'd but not implemented in any browsers, and
9137 * the `input` event does not provide any useful information about what has
9138 * actually been added, contrary to the spec. Thus, `textInput` is the best
9139 * available event to identify the characters that have actually been inserted
9140 * into the target node.
9141 *
9142 * This plugin is also responsible for emitting `composition` events, thus
9143 * allowing us to share composition fallback code for both `beforeInput` and
9144 * `composition` event types.
9145 */
9146
9147
9148 var BeforeInputEventPlugin = {
9149 eventTypes: eventTypes,
9150 extractEvents: function (topLevelType, targetInst, nativeEvent, nativeEventTarget, eventSystemFlags) {
9151 var composition = extractCompositionEvent(topLevelType, targetInst, nativeEvent, nativeEventTarget);
9152 var beforeInput = extractBeforeInputEvent(topLevelType, targetInst, nativeEvent, nativeEventTarget);
9153
9154 if (composition === null) {
9155 return beforeInput;
9156 }
9157
9158 if (beforeInput === null) {
9159 return composition;
9160 }
9161
9162 return [composition, beforeInput];
9163 }
9164 };
9165
9166 /**
9167 * @see http://www.whatwg.org/specs/web-apps/current-work/multipage/the-input-element.html#input-type-attr-summary
9168 */
9169 var supportedInputTypes = {
9170 color: true,
9171 date: true,
9172 datetime: true,
9173 'datetime-local': true,
9174 email: true,
9175 month: true,
9176 number: true,
9177 password: true,
9178 range: true,
9179 search: true,
9180 tel: true,
9181 text: true,
9182 time: true,
9183 url: true,
9184 week: true
9185 };
9186
9187 function isTextInputElement(elem) {
9188 var nodeName = elem && elem.nodeName && elem.nodeName.toLowerCase();
9189
9190 if (nodeName === 'input') {
9191 return !!supportedInputTypes[elem.type];
9192 }
9193
9194 if (nodeName === 'textarea') {
9195 return true;
9196 }
9197
9198 return false;
9199 }
9200
9201 var eventTypes$1 = {
9202 change: {
9203 phasedRegistrationNames: {
9204 bubbled: 'onChange',
9205 captured: 'onChangeCapture'
9206 },
9207 dependencies: [TOP_BLUR, TOP_CHANGE, TOP_CLICK, TOP_FOCUS, TOP_INPUT, TOP_KEY_DOWN, TOP_KEY_UP, TOP_SELECTION_CHANGE]
9208 }
9209 };
9210
9211 function createAndAccumulateChangeEvent(inst, nativeEvent, target) {
9212 var event = SyntheticEvent.getPooled(eventTypes$1.change, inst, nativeEvent, target);
9213 event.type = 'change'; // Flag this event loop as needing state restore.
9214
9215 enqueueStateRestore(target);
9216 accumulateTwoPhaseDispatches(event);
9217 return event;
9218 }
9219 /**
9220 * For IE shims
9221 */
9222
9223
9224 var activeElement = null;
9225 var activeElementInst = null;
9226 /**
9227 * SECTION: handle `change` event
9228 */
9229
9230 function shouldUseChangeEvent(elem) {
9231 var nodeName = elem.nodeName && elem.nodeName.toLowerCase();
9232 return nodeName === 'select' || nodeName === 'input' && elem.type === 'file';
9233 }
9234
9235 function manualDispatchChangeEvent(nativeEvent) {
9236 var event = createAndAccumulateChangeEvent(activeElementInst, nativeEvent, getEventTarget(nativeEvent)); // If change and propertychange bubbled, we'd just bind to it like all the
9237 // other events and have it go through ReactBrowserEventEmitter. Since it
9238 // doesn't, we manually listen for the events and so we have to enqueue and
9239 // process the abstract event manually.
9240 //
9241 // Batching is necessary here in order to ensure that all event handlers run
9242 // before the next rerender (including event handlers attached to ancestor
9243 // elements instead of directly on the input). Without this, controlled
9244 // components don't work properly in conjunction with event bubbling because
9245 // the component is rerendered and the value reverted before all the event
9246 // handlers can run. See https://github.com/facebook/react/issues/708.
9247
9248 batchedUpdates(runEventInBatch, event);
9249 }
9250
9251 function runEventInBatch(event) {
9252 runEventsInBatch(event);
9253 }
9254
9255 function getInstIfValueChanged(targetInst) {
9256 var targetNode = getNodeFromInstance$1(targetInst);
9257
9258 if (updateValueIfChanged(targetNode)) {
9259 return targetInst;
9260 }
9261 }
9262
9263 function getTargetInstForChangeEvent(topLevelType, targetInst) {
9264 if (topLevelType === TOP_CHANGE) {
9265 return targetInst;
9266 }
9267 }
9268 /**
9269 * SECTION: handle `input` event
9270 */
9271
9272
9273 var isInputEventSupported = false;
9274
9275 if (canUseDOM) {
9276 // IE9 claims to support the input event but fails to trigger it when
9277 // deleting text, so we ignore its input events.
9278 isInputEventSupported = isEventSupported('input') && (!document.documentMode || document.documentMode > 9);
9279 }
9280 /**
9281 * (For IE <=9) Starts tracking propertychange events on the passed-in element
9282 * and override the value property so that we can distinguish user events from
9283 * value changes in JS.
9284 */
9285
9286
9287 function startWatchingForValueChange(target, targetInst) {
9288 activeElement = target;
9289 activeElementInst = targetInst;
9290 activeElement.attachEvent('onpropertychange', handlePropertyChange);
9291 }
9292 /**
9293 * (For IE <=9) Removes the event listeners from the currently-tracked element,
9294 * if any exists.
9295 */
9296
9297
9298 function stopWatchingForValueChange() {
9299 if (!activeElement) {
9300 return;
9301 }
9302
9303 activeElement.detachEvent('onpropertychange', handlePropertyChange);
9304 activeElement = null;
9305 activeElementInst = null;
9306 }
9307 /**
9308 * (For IE <=9) Handles a propertychange event, sending a `change` event if
9309 * the value of the active element has changed.
9310 */
9311
9312
9313 function handlePropertyChange(nativeEvent) {
9314 if (nativeEvent.propertyName !== 'value') {
9315 return;
9316 }
9317
9318 if (getInstIfValueChanged(activeElementInst)) {
9319 manualDispatchChangeEvent(nativeEvent);
9320 }
9321 }
9322
9323 function handleEventsForInputEventPolyfill(topLevelType, target, targetInst) {
9324 if (topLevelType === TOP_FOCUS) {
9325 // In IE9, propertychange fires for most input events but is buggy and
9326 // doesn't fire when text is deleted, but conveniently, selectionchange
9327 // appears to fire in all of the remaining cases so we catch those and
9328 // forward the event if the value has changed
9329 // In either case, we don't want to call the event handler if the value
9330 // is changed from JS so we redefine a setter for `.value` that updates
9331 // our activeElementValue variable, allowing us to ignore those changes
9332 //
9333 // stopWatching() should be a noop here but we call it just in case we
9334 // missed a blur event somehow.
9335 stopWatchingForValueChange();
9336 startWatchingForValueChange(target, targetInst);
9337 } else if (topLevelType === TOP_BLUR) {
9338 stopWatchingForValueChange();
9339 }
9340 } // For IE8 and IE9.
9341
9342
9343 function getTargetInstForInputEventPolyfill(topLevelType, targetInst) {
9344 if (topLevelType === TOP_SELECTION_CHANGE || topLevelType === TOP_KEY_UP || topLevelType === TOP_KEY_DOWN) {
9345 // On the selectionchange event, the target is just document which isn't
9346 // helpful for us so just check activeElement instead.
9347 //
9348 // 99% of the time, keydown and keyup aren't necessary. IE8 fails to fire
9349 // propertychange on the first input event after setting `value` from a
9350 // script and fires only keydown, keypress, keyup. Catching keyup usually
9351 // gets it and catching keydown lets us fire an event for the first
9352 // keystroke if user does a key repeat (it'll be a little delayed: right
9353 // before the second keystroke). Other input methods (e.g., paste) seem to
9354 // fire selectionchange normally.
9355 return getInstIfValueChanged(activeElementInst);
9356 }
9357 }
9358 /**
9359 * SECTION: handle `click` event
9360 */
9361
9362
9363 function shouldUseClickEvent(elem) {
9364 // Use the `click` event to detect changes to checkbox and radio inputs.
9365 // This approach works across all browsers, whereas `change` does not fire
9366 // until `blur` in IE8.
9367 var nodeName = elem.nodeName;
9368 return nodeName && nodeName.toLowerCase() === 'input' && (elem.type === 'checkbox' || elem.type === 'radio');
9369 }
9370
9371 function getTargetInstForClickEvent(topLevelType, targetInst) {
9372 if (topLevelType === TOP_CLICK) {
9373 return getInstIfValueChanged(targetInst);
9374 }
9375 }
9376
9377 function getTargetInstForInputOrChangeEvent(topLevelType, targetInst) {
9378 if (topLevelType === TOP_INPUT || topLevelType === TOP_CHANGE) {
9379 return getInstIfValueChanged(targetInst);
9380 }
9381 }
9382
9383 function handleControlledInputBlur(node) {
9384 var state = node._wrapperState;
9385
9386 if (!state || !state.controlled || node.type !== 'number') {
9387 return;
9388 }
9389
9390 {
9391 // If controlled, assign the value attribute to the current value on blur
9392 setDefaultValue(node, 'number', node.value);
9393 }
9394 }
9395 /**
9396 * This plugin creates an `onChange` event that normalizes change events
9397 * across form elements. This event fires at a time when it's possible to
9398 * change the element's value without seeing a flicker.
9399 *
9400 * Supported elements are:
9401 * - input (see `isTextInputElement`)
9402 * - textarea
9403 * - select
9404 */
9405
9406
9407 var ChangeEventPlugin = {
9408 eventTypes: eventTypes$1,
9409 _isInputEventSupported: isInputEventSupported,
9410 extractEvents: function (topLevelType, targetInst, nativeEvent, nativeEventTarget, eventSystemFlags) {
9411 var targetNode = targetInst ? getNodeFromInstance$1(targetInst) : window;
9412 var getTargetInstFunc, handleEventFunc;
9413
9414 if (shouldUseChangeEvent(targetNode)) {
9415 getTargetInstFunc = getTargetInstForChangeEvent;
9416 } else if (isTextInputElement(targetNode)) {
9417 if (isInputEventSupported) {
9418 getTargetInstFunc = getTargetInstForInputOrChangeEvent;
9419 } else {
9420 getTargetInstFunc = getTargetInstForInputEventPolyfill;
9421 handleEventFunc = handleEventsForInputEventPolyfill;
9422 }
9423 } else if (shouldUseClickEvent(targetNode)) {
9424 getTargetInstFunc = getTargetInstForClickEvent;
9425 }
9426
9427 if (getTargetInstFunc) {
9428 var inst = getTargetInstFunc(topLevelType, targetInst);
9429
9430 if (inst) {
9431 var event = createAndAccumulateChangeEvent(inst, nativeEvent, nativeEventTarget);
9432 return event;
9433 }
9434 }
9435
9436 if (handleEventFunc) {
9437 handleEventFunc(topLevelType, targetNode, targetInst);
9438 } // When blurring, set the value attribute for number inputs
9439
9440
9441 if (topLevelType === TOP_BLUR) {
9442 handleControlledInputBlur(targetNode);
9443 }
9444 }
9445 };
9446
9447 var SyntheticUIEvent = SyntheticEvent.extend({
9448 view: null,
9449 detail: null
9450 });
9451
9452 /**
9453 * Translation from modifier key to the associated property in the event.
9454 * @see http://www.w3.org/TR/DOM-Level-3-Events/#keys-Modifiers
9455 */
9456 var modifierKeyToProp = {
9457 Alt: 'altKey',
9458 Control: 'ctrlKey',
9459 Meta: 'metaKey',
9460 Shift: 'shiftKey'
9461 }; // Older browsers (Safari <= 10, iOS Safari <= 10.2) do not support
9462 // getModifierState. If getModifierState is not supported, we map it to a set of
9463 // modifier keys exposed by the event. In this case, Lock-keys are not supported.
9464
9465 function modifierStateGetter(keyArg) {
9466 var syntheticEvent = this;
9467 var nativeEvent = syntheticEvent.nativeEvent;
9468
9469 if (nativeEvent.getModifierState) {
9470 return nativeEvent.getModifierState(keyArg);
9471 }
9472
9473 var keyProp = modifierKeyToProp[keyArg];
9474 return keyProp ? !!nativeEvent[keyProp] : false;
9475 }
9476
9477 function getEventModifierState(nativeEvent) {
9478 return modifierStateGetter;
9479 }
9480
9481 var previousScreenX = 0;
9482 var previousScreenY = 0; // Use flags to signal movementX/Y has already been set
9483
9484 var isMovementXSet = false;
9485 var isMovementYSet = false;
9486 /**
9487 * @interface MouseEvent
9488 * @see http://www.w3.org/TR/DOM-Level-3-Events/
9489 */
9490
9491 var SyntheticMouseEvent = SyntheticUIEvent.extend({
9492 screenX: null,
9493 screenY: null,
9494 clientX: null,
9495 clientY: null,
9496 pageX: null,
9497 pageY: null,
9498 ctrlKey: null,
9499 shiftKey: null,
9500 altKey: null,
9501 metaKey: null,
9502 getModifierState: getEventModifierState,
9503 button: null,
9504 buttons: null,
9505 relatedTarget: function (event) {
9506 return event.relatedTarget || (event.fromElement === event.srcElement ? event.toElement : event.fromElement);
9507 },
9508 movementX: function (event) {
9509 if ('movementX' in event) {
9510 return event.movementX;
9511 }
9512
9513 var screenX = previousScreenX;
9514 previousScreenX = event.screenX;
9515
9516 if (!isMovementXSet) {
9517 isMovementXSet = true;
9518 return 0;
9519 }
9520
9521 return event.type === 'mousemove' ? event.screenX - screenX : 0;
9522 },
9523 movementY: function (event) {
9524 if ('movementY' in event) {
9525 return event.movementY;
9526 }
9527
9528 var screenY = previousScreenY;
9529 previousScreenY = event.screenY;
9530
9531 if (!isMovementYSet) {
9532 isMovementYSet = true;
9533 return 0;
9534 }
9535
9536 return event.type === 'mousemove' ? event.screenY - screenY : 0;
9537 }
9538 });
9539
9540 /**
9541 * @interface PointerEvent
9542 * @see http://www.w3.org/TR/pointerevents/
9543 */
9544
9545 var SyntheticPointerEvent = SyntheticMouseEvent.extend({
9546 pointerId: null,
9547 width: null,
9548 height: null,
9549 pressure: null,
9550 tangentialPressure: null,
9551 tiltX: null,
9552 tiltY: null,
9553 twist: null,
9554 pointerType: null,
9555 isPrimary: null
9556 });
9557
9558 var eventTypes$2 = {
9559 mouseEnter: {
9560 registrationName: 'onMouseEnter',
9561 dependencies: [TOP_MOUSE_OUT, TOP_MOUSE_OVER]
9562 },
9563 mouseLeave: {
9564 registrationName: 'onMouseLeave',
9565 dependencies: [TOP_MOUSE_OUT, TOP_MOUSE_OVER]
9566 },
9567 pointerEnter: {
9568 registrationName: 'onPointerEnter',
9569 dependencies: [TOP_POINTER_OUT, TOP_POINTER_OVER]
9570 },
9571 pointerLeave: {
9572 registrationName: 'onPointerLeave',
9573 dependencies: [TOP_POINTER_OUT, TOP_POINTER_OVER]
9574 }
9575 };
9576 var EnterLeaveEventPlugin = {
9577 eventTypes: eventTypes$2,
9578
9579 /**
9580 * For almost every interaction we care about, there will be both a top-level
9581 * `mouseover` and `mouseout` event that occurs. Only use `mouseout` so that
9582 * we do not extract duplicate events. However, moving the mouse into the
9583 * browser from outside will not fire a `mouseout` event. In this case, we use
9584 * the `mouseover` top-level event.
9585 */
9586 extractEvents: function (topLevelType, targetInst, nativeEvent, nativeEventTarget, eventSystemFlags) {
9587 var isOverEvent = topLevelType === TOP_MOUSE_OVER || topLevelType === TOP_POINTER_OVER;
9588 var isOutEvent = topLevelType === TOP_MOUSE_OUT || topLevelType === TOP_POINTER_OUT;
9589
9590 if (isOverEvent && (eventSystemFlags & IS_REPLAYED) === 0 && (nativeEvent.relatedTarget || nativeEvent.fromElement)) {
9591 // If this is an over event with a target, then we've already dispatched
9592 // the event in the out event of the other target. If this is replayed,
9593 // then it's because we couldn't dispatch against this target previously
9594 // so we have to do it now instead.
9595 return null;
9596 }
9597
9598 if (!isOutEvent && !isOverEvent) {
9599 // Must not be a mouse or pointer in or out - ignoring.
9600 return null;
9601 }
9602
9603 var win;
9604
9605 if (nativeEventTarget.window === nativeEventTarget) {
9606 // `nativeEventTarget` is probably a window object.
9607 win = nativeEventTarget;
9608 } else {
9609 // TODO: Figure out why `ownerDocument` is sometimes undefined in IE8.
9610 var doc = nativeEventTarget.ownerDocument;
9611
9612 if (doc) {
9613 win = doc.defaultView || doc.parentWindow;
9614 } else {
9615 win = window;
9616 }
9617 }
9618
9619 var from;
9620 var to;
9621
9622 if (isOutEvent) {
9623 from = targetInst;
9624 var related = nativeEvent.relatedTarget || nativeEvent.toElement;
9625 to = related ? getClosestInstanceFromNode(related) : null;
9626
9627 if (to !== null) {
9628 var nearestMounted = getNearestMountedFiber(to);
9629
9630 if (to !== nearestMounted || to.tag !== HostComponent && to.tag !== HostText) {
9631 to = null;
9632 }
9633 }
9634 } else {
9635 // Moving to a node from outside the window.
9636 from = null;
9637 to = targetInst;
9638 }
9639
9640 if (from === to) {
9641 // Nothing pertains to our managed components.
9642 return null;
9643 }
9644
9645 var eventInterface, leaveEventType, enterEventType, eventTypePrefix;
9646
9647 if (topLevelType === TOP_MOUSE_OUT || topLevelType === TOP_MOUSE_OVER) {
9648 eventInterface = SyntheticMouseEvent;
9649 leaveEventType = eventTypes$2.mouseLeave;
9650 enterEventType = eventTypes$2.mouseEnter;
9651 eventTypePrefix = 'mouse';
9652 } else if (topLevelType === TOP_POINTER_OUT || topLevelType === TOP_POINTER_OVER) {
9653 eventInterface = SyntheticPointerEvent;
9654 leaveEventType = eventTypes$2.pointerLeave;
9655 enterEventType = eventTypes$2.pointerEnter;
9656 eventTypePrefix = 'pointer';
9657 }
9658
9659 var fromNode = from == null ? win : getNodeFromInstance$1(from);
9660 var toNode = to == null ? win : getNodeFromInstance$1(to);
9661 var leave = eventInterface.getPooled(leaveEventType, from, nativeEvent, nativeEventTarget);
9662 leave.type = eventTypePrefix + 'leave';
9663 leave.target = fromNode;
9664 leave.relatedTarget = toNode;
9665 var enter = eventInterface.getPooled(enterEventType, to, nativeEvent, nativeEventTarget);
9666 enter.type = eventTypePrefix + 'enter';
9667 enter.target = toNode;
9668 enter.relatedTarget = fromNode;
9669 accumulateEnterLeaveDispatches(leave, enter, from, to); // If we are not processing the first ancestor, then we
9670 // should not process the same nativeEvent again, as we
9671 // will have already processed it in the first ancestor.
9672
9673 if ((eventSystemFlags & IS_FIRST_ANCESTOR) === 0) {
9674 return [leave];
9675 }
9676
9677 return [leave, enter];
9678 }
9679 };
9680
9681 /**
9682 * inlined Object.is polyfill to avoid requiring consumers ship their own
9683 * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is
9684 */
9685 function is(x, y) {
9686 return x === y && (x !== 0 || 1 / x === 1 / y) || x !== x && y !== y // eslint-disable-line no-self-compare
9687 ;
9688 }
9689
9690 var objectIs = typeof Object.is === 'function' ? Object.is : is;
9691
9692 var hasOwnProperty$2 = Object.prototype.hasOwnProperty;
9693 /**
9694 * Performs equality by iterating through keys on an object and returning false
9695 * when any key has values which are not strictly equal between the arguments.
9696 * Returns true when the values of all keys are strictly equal.
9697 */
9698
9699 function shallowEqual(objA, objB) {
9700 if (objectIs(objA, objB)) {
9701 return true;
9702 }
9703
9704 if (typeof objA !== 'object' || objA === null || typeof objB !== 'object' || objB === null) {
9705 return false;
9706 }
9707
9708 var keysA = Object.keys(objA);
9709 var keysB = Object.keys(objB);
9710
9711 if (keysA.length !== keysB.length) {
9712 return false;
9713 } // Test for A's keys different from B.
9714
9715
9716 for (var i = 0; i < keysA.length; i++) {
9717 if (!hasOwnProperty$2.call(objB, keysA[i]) || !objectIs(objA[keysA[i]], objB[keysA[i]])) {
9718 return false;
9719 }
9720 }
9721
9722 return true;
9723 }
9724
9725 var skipSelectionChangeEvent = canUseDOM && 'documentMode' in document && document.documentMode <= 11;
9726 var eventTypes$3 = {
9727 select: {
9728 phasedRegistrationNames: {
9729 bubbled: 'onSelect',
9730 captured: 'onSelectCapture'
9731 },
9732 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]
9733 }
9734 };
9735 var activeElement$1 = null;
9736 var activeElementInst$1 = null;
9737 var lastSelection = null;
9738 var mouseDown = false;
9739 /**
9740 * Get an object which is a unique representation of the current selection.
9741 *
9742 * The return value will not be consistent across nodes or browsers, but
9743 * two identical selections on the same node will return identical objects.
9744 *
9745 * @param {DOMElement} node
9746 * @return {object}
9747 */
9748
9749 function getSelection$1(node) {
9750 if ('selectionStart' in node && hasSelectionCapabilities(node)) {
9751 return {
9752 start: node.selectionStart,
9753 end: node.selectionEnd
9754 };
9755 } else {
9756 var win = node.ownerDocument && node.ownerDocument.defaultView || window;
9757 var selection = win.getSelection();
9758 return {
9759 anchorNode: selection.anchorNode,
9760 anchorOffset: selection.anchorOffset,
9761 focusNode: selection.focusNode,
9762 focusOffset: selection.focusOffset
9763 };
9764 }
9765 }
9766 /**
9767 * Get document associated with the event target.
9768 *
9769 * @param {object} nativeEventTarget
9770 * @return {Document}
9771 */
9772
9773
9774 function getEventTargetDocument(eventTarget) {
9775 return eventTarget.window === eventTarget ? eventTarget.document : eventTarget.nodeType === DOCUMENT_NODE ? eventTarget : eventTarget.ownerDocument;
9776 }
9777 /**
9778 * Poll selection to see whether it's changed.
9779 *
9780 * @param {object} nativeEvent
9781 * @param {object} nativeEventTarget
9782 * @return {?SyntheticEvent}
9783 */
9784
9785
9786 function constructSelectEvent(nativeEvent, nativeEventTarget) {
9787 // Ensure we have the right element, and that the user is not dragging a
9788 // selection (this matches native `select` event behavior). In HTML5, select
9789 // fires only on input and textarea thus if there's no focused element we
9790 // won't dispatch.
9791 var doc = getEventTargetDocument(nativeEventTarget);
9792
9793 if (mouseDown || activeElement$1 == null || activeElement$1 !== getActiveElement(doc)) {
9794 return null;
9795 } // Only fire when selection has actually changed.
9796
9797
9798 var currentSelection = getSelection$1(activeElement$1);
9799
9800 if (!lastSelection || !shallowEqual(lastSelection, currentSelection)) {
9801 lastSelection = currentSelection;
9802 var syntheticEvent = SyntheticEvent.getPooled(eventTypes$3.select, activeElementInst$1, nativeEvent, nativeEventTarget);
9803 syntheticEvent.type = 'select';
9804 syntheticEvent.target = activeElement$1;
9805 accumulateTwoPhaseDispatches(syntheticEvent);
9806 return syntheticEvent;
9807 }
9808
9809 return null;
9810 }
9811 /**
9812 * This plugin creates an `onSelect` event that normalizes select events
9813 * across form elements.
9814 *
9815 * Supported elements are:
9816 * - input (see `isTextInputElement`)
9817 * - textarea
9818 * - contentEditable
9819 *
9820 * This differs from native browser implementations in the following ways:
9821 * - Fires on contentEditable fields as well as inputs.
9822 * - Fires for collapsed selection.
9823 * - Fires after user input.
9824 */
9825
9826
9827 var SelectEventPlugin = {
9828 eventTypes: eventTypes$3,
9829 extractEvents: function (topLevelType, targetInst, nativeEvent, nativeEventTarget, eventSystemFlags, container) {
9830 var containerOrDoc = container || getEventTargetDocument(nativeEventTarget); // Track whether all listeners exists for this plugin. If none exist, we do
9831 // not extract events. See #3639.
9832
9833 if (!containerOrDoc || !isListeningToAllDependencies('onSelect', containerOrDoc)) {
9834 return null;
9835 }
9836
9837 var targetNode = targetInst ? getNodeFromInstance$1(targetInst) : window;
9838
9839 switch (topLevelType) {
9840 // Track the input node that has focus.
9841 case TOP_FOCUS:
9842 if (isTextInputElement(targetNode) || targetNode.contentEditable === 'true') {
9843 activeElement$1 = targetNode;
9844 activeElementInst$1 = targetInst;
9845 lastSelection = null;
9846 }
9847
9848 break;
9849
9850 case TOP_BLUR:
9851 activeElement$1 = null;
9852 activeElementInst$1 = null;
9853 lastSelection = null;
9854 break;
9855 // Don't fire the event while the user is dragging. This matches the
9856 // semantics of the native select event.
9857
9858 case TOP_MOUSE_DOWN:
9859 mouseDown = true;
9860 break;
9861
9862 case TOP_CONTEXT_MENU:
9863 case TOP_MOUSE_UP:
9864 case TOP_DRAG_END:
9865 mouseDown = false;
9866 return constructSelectEvent(nativeEvent, nativeEventTarget);
9867 // Chrome and IE fire non-standard event when selection is changed (and
9868 // sometimes when it hasn't). IE's event fires out of order with respect
9869 // to key and input events on deletion, so we discard it.
9870 //
9871 // Firefox doesn't support selectionchange, so check selection status
9872 // after each key entry. The selection changes after keydown and before
9873 // keyup, but we check on keydown as well in the case of holding down a
9874 // key, when multiple keydown events are fired but only one keyup is.
9875 // This is also our approach for IE handling, for the reason above.
9876
9877 case TOP_SELECTION_CHANGE:
9878 if (skipSelectionChangeEvent) {
9879 break;
9880 }
9881
9882 // falls through
9883
9884 case TOP_KEY_DOWN:
9885 case TOP_KEY_UP:
9886 return constructSelectEvent(nativeEvent, nativeEventTarget);
9887 }
9888
9889 return null;
9890 }
9891 };
9892
9893 /**
9894 * @interface Event
9895 * @see http://www.w3.org/TR/css3-animations/#AnimationEvent-interface
9896 * @see https://developer.mozilla.org/en-US/docs/Web/API/AnimationEvent
9897 */
9898
9899 var SyntheticAnimationEvent = SyntheticEvent.extend({
9900 animationName: null,
9901 elapsedTime: null,
9902 pseudoElement: null
9903 });
9904
9905 /**
9906 * @interface Event
9907 * @see http://www.w3.org/TR/clipboard-apis/
9908 */
9909
9910 var SyntheticClipboardEvent = SyntheticEvent.extend({
9911 clipboardData: function (event) {
9912 return 'clipboardData' in event ? event.clipboardData : window.clipboardData;
9913 }
9914 });
9915
9916 /**
9917 * @interface FocusEvent
9918 * @see http://www.w3.org/TR/DOM-Level-3-Events/
9919 */
9920
9921 var SyntheticFocusEvent = SyntheticUIEvent.extend({
9922 relatedTarget: null
9923 });
9924
9925 /**
9926 * `charCode` represents the actual "character code" and is safe to use with
9927 * `String.fromCharCode`. As such, only keys that correspond to printable
9928 * characters produce a valid `charCode`, the only exception to this is Enter.
9929 * The Tab-key is considered non-printable and does not have a `charCode`,
9930 * presumably because it does not produce a tab-character in browsers.
9931 *
9932 * @param {object} nativeEvent Native browser event.
9933 * @return {number} Normalized `charCode` property.
9934 */
9935 function getEventCharCode(nativeEvent) {
9936 var charCode;
9937 var keyCode = nativeEvent.keyCode;
9938
9939 if ('charCode' in nativeEvent) {
9940 charCode = nativeEvent.charCode; // FF does not set `charCode` for the Enter-key, check against `keyCode`.
9941
9942 if (charCode === 0 && keyCode === 13) {
9943 charCode = 13;
9944 }
9945 } else {
9946 // IE8 does not implement `charCode`, but `keyCode` has the correct value.
9947 charCode = keyCode;
9948 } // IE and Edge (on Windows) and Chrome / Safari (on Windows and Linux)
9949 // report Enter as charCode 10 when ctrl is pressed.
9950
9951
9952 if (charCode === 10) {
9953 charCode = 13;
9954 } // Some non-printable keys are reported in `charCode`/`keyCode`, discard them.
9955 // Must not discard the (non-)printable Enter-key.
9956
9957
9958 if (charCode >= 32 || charCode === 13) {
9959 return charCode;
9960 }
9961
9962 return 0;
9963 }
9964
9965 /**
9966 * Normalization of deprecated HTML5 `key` values
9967 * @see https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent#Key_names
9968 */
9969
9970 var normalizeKey = {
9971 Esc: 'Escape',
9972 Spacebar: ' ',
9973 Left: 'ArrowLeft',
9974 Up: 'ArrowUp',
9975 Right: 'ArrowRight',
9976 Down: 'ArrowDown',
9977 Del: 'Delete',
9978 Win: 'OS',
9979 Menu: 'ContextMenu',
9980 Apps: 'ContextMenu',
9981 Scroll: 'ScrollLock',
9982 MozPrintableKey: 'Unidentified'
9983 };
9984 /**
9985 * Translation from legacy `keyCode` to HTML5 `key`
9986 * Only special keys supported, all others depend on keyboard layout or browser
9987 * @see https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent#Key_names
9988 */
9989
9990 var translateToKey = {
9991 '8': 'Backspace',
9992 '9': 'Tab',
9993 '12': 'Clear',
9994 '13': 'Enter',
9995 '16': 'Shift',
9996 '17': 'Control',
9997 '18': 'Alt',
9998 '19': 'Pause',
9999 '20': 'CapsLock',
10000 '27': 'Escape',
10001 '32': ' ',
10002 '33': 'PageUp',
10003 '34': 'PageDown',
10004 '35': 'End',
10005 '36': 'Home',
10006 '37': 'ArrowLeft',
10007 '38': 'ArrowUp',
10008 '39': 'ArrowRight',
10009 '40': 'ArrowDown',
10010 '45': 'Insert',
10011 '46': 'Delete',
10012 '112': 'F1',
10013 '113': 'F2',
10014 '114': 'F3',
10015 '115': 'F4',
10016 '116': 'F5',
10017 '117': 'F6',
10018 '118': 'F7',
10019 '119': 'F8',
10020 '120': 'F9',
10021 '121': 'F10',
10022 '122': 'F11',
10023 '123': 'F12',
10024 '144': 'NumLock',
10025 '145': 'ScrollLock',
10026 '224': 'Meta'
10027 };
10028 /**
10029 * @param {object} nativeEvent Native browser event.
10030 * @return {string} Normalized `key` property.
10031 */
10032
10033 function getEventKey(nativeEvent) {
10034 if (nativeEvent.key) {
10035 // Normalize inconsistent values reported by browsers due to
10036 // implementations of a working draft specification.
10037 // FireFox implements `key` but returns `MozPrintableKey` for all
10038 // printable characters (normalized to `Unidentified`), ignore it.
10039 var key = normalizeKey[nativeEvent.key] || nativeEvent.key;
10040
10041 if (key !== 'Unidentified') {
10042 return key;
10043 }
10044 } // Browser does not implement `key`, polyfill as much of it as we can.
10045
10046
10047 if (nativeEvent.type === 'keypress') {
10048 var charCode = getEventCharCode(nativeEvent); // The enter-key is technically both printable and non-printable and can
10049 // thus be captured by `keypress`, no other non-printable key should.
10050
10051 return charCode === 13 ? 'Enter' : String.fromCharCode(charCode);
10052 }
10053
10054 if (nativeEvent.type === 'keydown' || nativeEvent.type === 'keyup') {
10055 // While user keyboard layout determines the actual meaning of each
10056 // `keyCode` value, almost all function keys have a universal value.
10057 return translateToKey[nativeEvent.keyCode] || 'Unidentified';
10058 }
10059
10060 return '';
10061 }
10062
10063 /**
10064 * @interface KeyboardEvent
10065 * @see http://www.w3.org/TR/DOM-Level-3-Events/
10066 */
10067
10068 var SyntheticKeyboardEvent = SyntheticUIEvent.extend({
10069 key: getEventKey,
10070 location: null,
10071 ctrlKey: null,
10072 shiftKey: null,
10073 altKey: null,
10074 metaKey: null,
10075 repeat: null,
10076 locale: null,
10077 getModifierState: getEventModifierState,
10078 // Legacy Interface
10079 charCode: function (event) {
10080 // `charCode` is the result of a KeyPress event and represents the value of
10081 // the actual printable character.
10082 // KeyPress is deprecated, but its replacement is not yet final and not
10083 // implemented in any major browser. Only KeyPress has charCode.
10084 if (event.type === 'keypress') {
10085 return getEventCharCode(event);
10086 }
10087
10088 return 0;
10089 },
10090 keyCode: function (event) {
10091 // `keyCode` is the result of a KeyDown/Up event and represents the value of
10092 // physical keyboard key.
10093 // The actual meaning of the value depends on the users' keyboard layout
10094 // which cannot be detected. Assuming that it is a US keyboard layout
10095 // provides a surprisingly accurate mapping for US and European users.
10096 // Due to this, it is left to the user to implement at this time.
10097 if (event.type === 'keydown' || event.type === 'keyup') {
10098 return event.keyCode;
10099 }
10100
10101 return 0;
10102 },
10103 which: function (event) {
10104 // `which` is an alias for either `keyCode` or `charCode` depending on the
10105 // type of the event.
10106 if (event.type === 'keypress') {
10107 return getEventCharCode(event);
10108 }
10109
10110 if (event.type === 'keydown' || event.type === 'keyup') {
10111 return event.keyCode;
10112 }
10113
10114 return 0;
10115 }
10116 });
10117
10118 /**
10119 * @interface DragEvent
10120 * @see http://www.w3.org/TR/DOM-Level-3-Events/
10121 */
10122
10123 var SyntheticDragEvent = SyntheticMouseEvent.extend({
10124 dataTransfer: null
10125 });
10126
10127 /**
10128 * @interface TouchEvent
10129 * @see http://www.w3.org/TR/touch-events/
10130 */
10131
10132 var SyntheticTouchEvent = SyntheticUIEvent.extend({
10133 touches: null,
10134 targetTouches: null,
10135 changedTouches: null,
10136 altKey: null,
10137 metaKey: null,
10138 ctrlKey: null,
10139 shiftKey: null,
10140 getModifierState: getEventModifierState
10141 });
10142
10143 /**
10144 * @interface Event
10145 * @see http://www.w3.org/TR/2009/WD-css3-transitions-20090320/#transition-events-
10146 * @see https://developer.mozilla.org/en-US/docs/Web/API/TransitionEvent
10147 */
10148
10149 var SyntheticTransitionEvent = SyntheticEvent.extend({
10150 propertyName: null,
10151 elapsedTime: null,
10152 pseudoElement: null
10153 });
10154
10155 /**
10156 * @interface WheelEvent
10157 * @see http://www.w3.org/TR/DOM-Level-3-Events/
10158 */
10159
10160 var SyntheticWheelEvent = SyntheticMouseEvent.extend({
10161 deltaX: function (event) {
10162 return 'deltaX' in event ? event.deltaX : // Fallback to `wheelDeltaX` for Webkit and normalize (right is positive).
10163 'wheelDeltaX' in event ? -event.wheelDeltaX : 0;
10164 },
10165 deltaY: function (event) {
10166 return 'deltaY' in event ? event.deltaY : // Fallback to `wheelDeltaY` for Webkit and normalize (down is positive).
10167 'wheelDeltaY' in event ? -event.wheelDeltaY : // Fallback to `wheelDelta` for IE<9 and normalize (down is positive).
10168 'wheelDelta' in event ? -event.wheelDelta : 0;
10169 },
10170 deltaZ: null,
10171 // Browsers without "deltaMode" is reporting in raw wheel delta where one
10172 // notch on the scroll is always +/- 120, roughly equivalent to pixels.
10173 // A good approximation of DOM_DELTA_LINE (1) is 5% of viewport size or
10174 // ~40 pixels, for DOM_DELTA_SCREEN (2) it is 87.5% of viewport size.
10175 deltaMode: null
10176 });
10177
10178 var 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];
10179 var SimpleEventPlugin = {
10180 // simpleEventPluginEventTypes gets populated from
10181 // the DOMEventProperties module.
10182 eventTypes: simpleEventPluginEventTypes,
10183 extractEvents: function (topLevelType, targetInst, nativeEvent, nativeEventTarget, eventSystemFlags) {
10184 var dispatchConfig = topLevelEventsToDispatchConfig.get(topLevelType);
10185
10186 if (!dispatchConfig) {
10187 return null;
10188 }
10189
10190 var EventConstructor;
10191
10192 switch (topLevelType) {
10193 case TOP_KEY_PRESS:
10194 // Firefox creates a keypress event for function keys too. This removes
10195 // the unwanted keypress events. Enter is however both printable and
10196 // non-printable. One would expect Tab to be as well (but it isn't).
10197 if (getEventCharCode(nativeEvent) === 0) {
10198 return null;
10199 }
10200
10201 /* falls through */
10202
10203 case TOP_KEY_DOWN:
10204 case TOP_KEY_UP:
10205 EventConstructor = SyntheticKeyboardEvent;
10206 break;
10207
10208 case TOP_BLUR:
10209 case TOP_FOCUS:
10210 EventConstructor = SyntheticFocusEvent;
10211 break;
10212
10213 case TOP_CLICK:
10214 // Firefox creates a click event on right mouse clicks. This removes the
10215 // unwanted click events.
10216 if (nativeEvent.button === 2) {
10217 return null;
10218 }
10219
10220 /* falls through */
10221
10222 case TOP_AUX_CLICK:
10223 case TOP_DOUBLE_CLICK:
10224 case TOP_MOUSE_DOWN:
10225 case TOP_MOUSE_MOVE:
10226 case TOP_MOUSE_UP: // TODO: Disabled elements should not respond to mouse events
10227
10228 /* falls through */
10229
10230 case TOP_MOUSE_OUT:
10231 case TOP_MOUSE_OVER:
10232 case TOP_CONTEXT_MENU:
10233 EventConstructor = SyntheticMouseEvent;
10234 break;
10235
10236 case TOP_DRAG:
10237 case TOP_DRAG_END:
10238 case TOP_DRAG_ENTER:
10239 case TOP_DRAG_EXIT:
10240 case TOP_DRAG_LEAVE:
10241 case TOP_DRAG_OVER:
10242 case TOP_DRAG_START:
10243 case TOP_DROP:
10244 EventConstructor = SyntheticDragEvent;
10245 break;
10246
10247 case TOP_TOUCH_CANCEL:
10248 case TOP_TOUCH_END:
10249 case TOP_TOUCH_MOVE:
10250 case TOP_TOUCH_START:
10251 EventConstructor = SyntheticTouchEvent;
10252 break;
10253
10254 case TOP_ANIMATION_END:
10255 case TOP_ANIMATION_ITERATION:
10256 case TOP_ANIMATION_START:
10257 EventConstructor = SyntheticAnimationEvent;
10258 break;
10259
10260 case TOP_TRANSITION_END:
10261 EventConstructor = SyntheticTransitionEvent;
10262 break;
10263
10264 case TOP_SCROLL:
10265 EventConstructor = SyntheticUIEvent;
10266 break;
10267
10268 case TOP_WHEEL:
10269 EventConstructor = SyntheticWheelEvent;
10270 break;
10271
10272 case TOP_COPY:
10273 case TOP_CUT:
10274 case TOP_PASTE:
10275 EventConstructor = SyntheticClipboardEvent;
10276 break;
10277
10278 case TOP_GOT_POINTER_CAPTURE:
10279 case TOP_LOST_POINTER_CAPTURE:
10280 case TOP_POINTER_CANCEL:
10281 case TOP_POINTER_DOWN:
10282 case TOP_POINTER_MOVE:
10283 case TOP_POINTER_OUT:
10284 case TOP_POINTER_OVER:
10285 case TOP_POINTER_UP:
10286 EventConstructor = SyntheticPointerEvent;
10287 break;
10288
10289 default:
10290 {
10291 if (knownHTMLTopLevelTypes.indexOf(topLevelType) === -1) {
10292 error('SimpleEventPlugin: Unhandled event type, `%s`. This warning ' + 'is likely caused by a bug in React. Please file an issue.', topLevelType);
10293 }
10294 } // HTML Events
10295 // @see http://www.w3.org/TR/html5/index.html#events-0
10296
10297
10298 EventConstructor = SyntheticEvent;
10299 break;
10300 }
10301
10302 var event = EventConstructor.getPooled(dispatchConfig, targetInst, nativeEvent, nativeEventTarget);
10303 accumulateTwoPhaseDispatches(event);
10304 return event;
10305 }
10306 };
10307
10308 /**
10309 * Specifies a deterministic ordering of `EventPlugin`s. A convenient way to
10310 * reason about plugins, without having to package every one of them. This
10311 * is better than having plugins be ordered in the same order that they
10312 * are injected because that ordering would be influenced by the packaging order.
10313 * `ResponderEventPlugin` must occur before `SimpleEventPlugin` so that
10314 * preventing default on events is convenient in `SimpleEventPlugin` handlers.
10315 */
10316
10317 var DOMEventPluginOrder = ['ResponderEventPlugin', 'SimpleEventPlugin', 'EnterLeaveEventPlugin', 'ChangeEventPlugin', 'SelectEventPlugin', 'BeforeInputEventPlugin'];
10318 /**
10319 * Inject modules for resolving DOM hierarchy and plugin ordering.
10320 */
10321
10322 injectEventPluginOrder(DOMEventPluginOrder);
10323 setComponentTree(getFiberCurrentPropsFromNode$1, getInstanceFromNode$1, getNodeFromInstance$1);
10324 /**
10325 * Some important event plugins included by default (without having to require
10326 * them).
10327 */
10328
10329 injectEventPluginsByName({
10330 SimpleEventPlugin: SimpleEventPlugin,
10331 EnterLeaveEventPlugin: EnterLeaveEventPlugin,
10332 ChangeEventPlugin: ChangeEventPlugin,
10333 SelectEventPlugin: SelectEventPlugin,
10334 BeforeInputEventPlugin: BeforeInputEventPlugin
10335 });
10336
10337 // Prefix measurements so that it's possible to filter them.
10338 // Longer prefixes are hard to read in DevTools.
10339 var reactEmoji = "\u269B";
10340 var warningEmoji = "\u26D4";
10341 var supportsUserTiming = typeof performance !== 'undefined' && typeof performance.mark === 'function' && typeof performance.clearMarks === 'function' && typeof performance.measure === 'function' && typeof performance.clearMeasures === 'function'; // Keep track of current fiber so that we know the path to unwind on pause.
10342 // TODO: this looks the same as nextUnitOfWork in scheduler. Can we unify them?
10343
10344 var currentFiber = null; // If we're in the middle of user code, which fiber and method is it?
10345 // Reusing `currentFiber` would be confusing for this because user code fiber
10346 // can change during commit phase too, but we don't need to unwind it (since
10347 // lifecycles in the commit phase don't resemble a tree).
10348
10349 var currentPhase = null;
10350 var currentPhaseFiber = null; // Did lifecycle hook schedule an update? This is often a performance problem,
10351 // so we will keep track of it, and include it in the report.
10352 // Track commits caused by cascading updates.
10353
10354 var isCommitting = false;
10355 var hasScheduledUpdateInCurrentCommit = false;
10356 var hasScheduledUpdateInCurrentPhase = false;
10357 var commitCountInCurrentWorkLoop = 0;
10358 var effectCountInCurrentCommit = 0;
10359 // to avoid stretch the commit phase with measurement overhead.
10360
10361 var labelsInCurrentCommit = new Set();
10362
10363 var formatMarkName = function (markName) {
10364 return reactEmoji + " " + markName;
10365 };
10366
10367 var formatLabel = function (label, warning) {
10368 var prefix = warning ? warningEmoji + " " : reactEmoji + " ";
10369 var suffix = warning ? " Warning: " + warning : '';
10370 return "" + prefix + label + suffix;
10371 };
10372
10373 var beginMark = function (markName) {
10374 performance.mark(formatMarkName(markName));
10375 };
10376
10377 var clearMark = function (markName) {
10378 performance.clearMarks(formatMarkName(markName));
10379 };
10380
10381 var endMark = function (label, markName, warning) {
10382 var formattedMarkName = formatMarkName(markName);
10383 var formattedLabel = formatLabel(label, warning);
10384
10385 try {
10386 performance.measure(formattedLabel, formattedMarkName);
10387 } catch (err) {} // If previous mark was missing for some reason, this will throw.
10388 // This could only happen if React crashed in an unexpected place earlier.
10389 // Don't pile on with more errors.
10390 // Clear marks immediately to avoid growing buffer.
10391
10392
10393 performance.clearMarks(formattedMarkName);
10394 performance.clearMeasures(formattedLabel);
10395 };
10396
10397 var getFiberMarkName = function (label, debugID) {
10398 return label + " (#" + debugID + ")";
10399 };
10400
10401 var getFiberLabel = function (componentName, isMounted, phase) {
10402 if (phase === null) {
10403 // These are composite component total time measurements.
10404 return componentName + " [" + (isMounted ? 'update' : 'mount') + "]";
10405 } else {
10406 // Composite component methods.
10407 return componentName + "." + phase;
10408 }
10409 };
10410
10411 var beginFiberMark = function (fiber, phase) {
10412 var componentName = getComponentName(fiber.type) || 'Unknown';
10413 var debugID = fiber._debugID;
10414 var isMounted = fiber.alternate !== null;
10415 var label = getFiberLabel(componentName, isMounted, phase);
10416
10417 if (isCommitting && labelsInCurrentCommit.has(label)) {
10418 // During the commit phase, we don't show duplicate labels because
10419 // there is a fixed overhead for every measurement, and we don't
10420 // want to stretch the commit phase beyond necessary.
10421 return false;
10422 }
10423
10424 labelsInCurrentCommit.add(label);
10425 var markName = getFiberMarkName(label, debugID);
10426 beginMark(markName);
10427 return true;
10428 };
10429
10430 var clearFiberMark = function (fiber, phase) {
10431 var componentName = getComponentName(fiber.type) || 'Unknown';
10432 var debugID = fiber._debugID;
10433 var isMounted = fiber.alternate !== null;
10434 var label = getFiberLabel(componentName, isMounted, phase);
10435 var markName = getFiberMarkName(label, debugID);
10436 clearMark(markName);
10437 };
10438
10439 var endFiberMark = function (fiber, phase, warning) {
10440 var componentName = getComponentName(fiber.type) || 'Unknown';
10441 var debugID = fiber._debugID;
10442 var isMounted = fiber.alternate !== null;
10443 var label = getFiberLabel(componentName, isMounted, phase);
10444 var markName = getFiberMarkName(label, debugID);
10445 endMark(label, markName, warning);
10446 };
10447
10448 var shouldIgnoreFiber = function (fiber) {
10449 // Host components should be skipped in the timeline.
10450 // We could check typeof fiber.type, but does this work with RN?
10451 switch (fiber.tag) {
10452 case HostRoot:
10453 case HostComponent:
10454 case HostText:
10455 case HostPortal:
10456 case Fragment:
10457 case ContextProvider:
10458 case ContextConsumer:
10459 case Mode:
10460 return true;
10461
10462 default:
10463 return false;
10464 }
10465 };
10466
10467 var clearPendingPhaseMeasurement = function () {
10468 if (currentPhase !== null && currentPhaseFiber !== null) {
10469 clearFiberMark(currentPhaseFiber, currentPhase);
10470 }
10471
10472 currentPhaseFiber = null;
10473 currentPhase = null;
10474 hasScheduledUpdateInCurrentPhase = false;
10475 };
10476
10477 var pauseTimers = function () {
10478 // Stops all currently active measurements so that they can be resumed
10479 // if we continue in a later deferred loop from the same unit of work.
10480 var fiber = currentFiber;
10481
10482 while (fiber) {
10483 if (fiber._debugIsCurrentlyTiming) {
10484 endFiberMark(fiber, null, null);
10485 }
10486
10487 fiber = fiber.return;
10488 }
10489 };
10490
10491 var resumeTimersRecursively = function (fiber) {
10492 if (fiber.return !== null) {
10493 resumeTimersRecursively(fiber.return);
10494 }
10495
10496 if (fiber._debugIsCurrentlyTiming) {
10497 beginFiberMark(fiber, null);
10498 }
10499 };
10500
10501 var resumeTimers = function () {
10502 // Resumes all measurements that were active during the last deferred loop.
10503 if (currentFiber !== null) {
10504 resumeTimersRecursively(currentFiber);
10505 }
10506 };
10507
10508 function recordEffect() {
10509 {
10510 effectCountInCurrentCommit++;
10511 }
10512 }
10513 function recordScheduleUpdate() {
10514 {
10515 if (isCommitting) {
10516 hasScheduledUpdateInCurrentCommit = true;
10517 }
10518
10519 if (currentPhase !== null && currentPhase !== 'componentWillMount' && currentPhase !== 'componentWillReceiveProps') {
10520 hasScheduledUpdateInCurrentPhase = true;
10521 }
10522 }
10523 }
10524 function startWorkTimer(fiber) {
10525 {
10526 if (!supportsUserTiming || shouldIgnoreFiber(fiber)) {
10527 return;
10528 } // If we pause, this is the fiber to unwind from.
10529
10530
10531 currentFiber = fiber;
10532
10533 if (!beginFiberMark(fiber, null)) {
10534 return;
10535 }
10536
10537 fiber._debugIsCurrentlyTiming = true;
10538 }
10539 }
10540 function cancelWorkTimer(fiber) {
10541 {
10542 if (!supportsUserTiming || shouldIgnoreFiber(fiber)) {
10543 return;
10544 } // Remember we shouldn't complete measurement for this fiber.
10545 // Otherwise flamechart will be deep even for small updates.
10546
10547
10548 fiber._debugIsCurrentlyTiming = false;
10549 clearFiberMark(fiber, null);
10550 }
10551 }
10552 function stopWorkTimer(fiber) {
10553 {
10554 if (!supportsUserTiming || shouldIgnoreFiber(fiber)) {
10555 return;
10556 } // If we pause, its parent is the fiber to unwind from.
10557
10558
10559 currentFiber = fiber.return;
10560
10561 if (!fiber._debugIsCurrentlyTiming) {
10562 return;
10563 }
10564
10565 fiber._debugIsCurrentlyTiming = false;
10566 endFiberMark(fiber, null, null);
10567 }
10568 }
10569 function stopFailedWorkTimer(fiber) {
10570 {
10571 if (!supportsUserTiming || shouldIgnoreFiber(fiber)) {
10572 return;
10573 } // If we pause, its parent is the fiber to unwind from.
10574
10575
10576 currentFiber = fiber.return;
10577
10578 if (!fiber._debugIsCurrentlyTiming) {
10579 return;
10580 }
10581
10582 fiber._debugIsCurrentlyTiming = false;
10583 var warning = fiber.tag === SuspenseComponent ? 'Rendering was suspended' : 'An error was thrown inside this error boundary';
10584 endFiberMark(fiber, null, warning);
10585 }
10586 }
10587 function startPhaseTimer(fiber, phase) {
10588 {
10589 if (!supportsUserTiming) {
10590 return;
10591 }
10592
10593 clearPendingPhaseMeasurement();
10594
10595 if (!beginFiberMark(fiber, phase)) {
10596 return;
10597 }
10598
10599 currentPhaseFiber = fiber;
10600 currentPhase = phase;
10601 }
10602 }
10603 function stopPhaseTimer() {
10604 {
10605 if (!supportsUserTiming) {
10606 return;
10607 }
10608
10609 if (currentPhase !== null && currentPhaseFiber !== null) {
10610 var warning = hasScheduledUpdateInCurrentPhase ? 'Scheduled a cascading update' : null;
10611 endFiberMark(currentPhaseFiber, currentPhase, warning);
10612 }
10613
10614 currentPhase = null;
10615 currentPhaseFiber = null;
10616 }
10617 }
10618 function startWorkLoopTimer(nextUnitOfWork) {
10619 {
10620 currentFiber = nextUnitOfWork;
10621
10622 if (!supportsUserTiming) {
10623 return;
10624 }
10625
10626 commitCountInCurrentWorkLoop = 0; // This is top level call.
10627 // Any other measurements are performed within.
10628
10629 beginMark('(React Tree Reconciliation)'); // Resume any measurements that were in progress during the last loop.
10630
10631 resumeTimers();
10632 }
10633 }
10634 function stopWorkLoopTimer(interruptedBy, didCompleteRoot) {
10635 {
10636 if (!supportsUserTiming) {
10637 return;
10638 }
10639
10640 var warning = null;
10641
10642 if (interruptedBy !== null) {
10643 if (interruptedBy.tag === HostRoot) {
10644 warning = 'A top-level update interrupted the previous render';
10645 } else {
10646 var componentName = getComponentName(interruptedBy.type) || 'Unknown';
10647 warning = "An update to " + componentName + " interrupted the previous render";
10648 }
10649 } else if (commitCountInCurrentWorkLoop > 1) {
10650 warning = 'There were cascading updates';
10651 }
10652
10653 commitCountInCurrentWorkLoop = 0;
10654 var label = didCompleteRoot ? '(React Tree Reconciliation: Completed Root)' : '(React Tree Reconciliation: Yielded)'; // Pause any measurements until the next loop.
10655
10656 pauseTimers();
10657 endMark(label, '(React Tree Reconciliation)', warning);
10658 }
10659 }
10660 function startCommitTimer() {
10661 {
10662 if (!supportsUserTiming) {
10663 return;
10664 }
10665
10666 isCommitting = true;
10667 hasScheduledUpdateInCurrentCommit = false;
10668 labelsInCurrentCommit.clear();
10669 beginMark('(Committing Changes)');
10670 }
10671 }
10672 function stopCommitTimer() {
10673 {
10674 if (!supportsUserTiming) {
10675 return;
10676 }
10677
10678 var warning = null;
10679
10680 if (hasScheduledUpdateInCurrentCommit) {
10681 warning = 'Lifecycle hook scheduled a cascading update';
10682 } else if (commitCountInCurrentWorkLoop > 0) {
10683 warning = 'Caused by a cascading update in earlier commit';
10684 }
10685
10686 hasScheduledUpdateInCurrentCommit = false;
10687 commitCountInCurrentWorkLoop++;
10688 isCommitting = false;
10689 labelsInCurrentCommit.clear();
10690 endMark('(Committing Changes)', '(Committing Changes)', warning);
10691 }
10692 }
10693 function startCommitSnapshotEffectsTimer() {
10694 {
10695 if (!supportsUserTiming) {
10696 return;
10697 }
10698
10699 effectCountInCurrentCommit = 0;
10700 beginMark('(Committing Snapshot Effects)');
10701 }
10702 }
10703 function stopCommitSnapshotEffectsTimer() {
10704 {
10705 if (!supportsUserTiming) {
10706 return;
10707 }
10708
10709 var count = effectCountInCurrentCommit;
10710 effectCountInCurrentCommit = 0;
10711 endMark("(Committing Snapshot Effects: " + count + " Total)", '(Committing Snapshot Effects)', null);
10712 }
10713 }
10714 function startCommitHostEffectsTimer() {
10715 {
10716 if (!supportsUserTiming) {
10717 return;
10718 }
10719
10720 effectCountInCurrentCommit = 0;
10721 beginMark('(Committing Host Effects)');
10722 }
10723 }
10724 function stopCommitHostEffectsTimer() {
10725 {
10726 if (!supportsUserTiming) {
10727 return;
10728 }
10729
10730 var count = effectCountInCurrentCommit;
10731 effectCountInCurrentCommit = 0;
10732 endMark("(Committing Host Effects: " + count + " Total)", '(Committing Host Effects)', null);
10733 }
10734 }
10735 function startCommitLifeCyclesTimer() {
10736 {
10737 if (!supportsUserTiming) {
10738 return;
10739 }
10740
10741 effectCountInCurrentCommit = 0;
10742 beginMark('(Calling Lifecycle Methods)');
10743 }
10744 }
10745 function stopCommitLifeCyclesTimer() {
10746 {
10747 if (!supportsUserTiming) {
10748 return;
10749 }
10750
10751 var count = effectCountInCurrentCommit;
10752 effectCountInCurrentCommit = 0;
10753 endMark("(Calling Lifecycle Methods: " + count + " Total)", '(Calling Lifecycle Methods)', null);
10754 }
10755 }
10756
10757 var valueStack = [];
10758 var fiberStack;
10759
10760 {
10761 fiberStack = [];
10762 }
10763
10764 var index = -1;
10765
10766 function createCursor(defaultValue) {
10767 return {
10768 current: defaultValue
10769 };
10770 }
10771
10772 function pop(cursor, fiber) {
10773 if (index < 0) {
10774 {
10775 error('Unexpected pop.');
10776 }
10777
10778 return;
10779 }
10780
10781 {
10782 if (fiber !== fiberStack[index]) {
10783 error('Unexpected Fiber popped.');
10784 }
10785 }
10786
10787 cursor.current = valueStack[index];
10788 valueStack[index] = null;
10789
10790 {
10791 fiberStack[index] = null;
10792 }
10793
10794 index--;
10795 }
10796
10797 function push(cursor, value, fiber) {
10798 index++;
10799 valueStack[index] = cursor.current;
10800
10801 {
10802 fiberStack[index] = fiber;
10803 }
10804
10805 cursor.current = value;
10806 }
10807
10808 var warnedAboutMissingGetChildContext;
10809
10810 {
10811 warnedAboutMissingGetChildContext = {};
10812 }
10813
10814 var emptyContextObject = {};
10815
10816 {
10817 Object.freeze(emptyContextObject);
10818 } // A cursor to the current merged context object on the stack.
10819
10820
10821 var contextStackCursor = createCursor(emptyContextObject); // A cursor to a boolean indicating whether the context has changed.
10822
10823 var didPerformWorkStackCursor = createCursor(false); // Keep track of the previous context object that was on the stack.
10824 // We use this to get access to the parent context after we have already
10825 // pushed the next context provider, and now need to merge their contexts.
10826
10827 var previousContext = emptyContextObject;
10828
10829 function getUnmaskedContext(workInProgress, Component, didPushOwnContextIfProvider) {
10830 {
10831 if (didPushOwnContextIfProvider && isContextProvider(Component)) {
10832 // If the fiber is a context provider itself, when we read its context
10833 // we may have already pushed its own child context on the stack. A context
10834 // provider should not "see" its own child context. Therefore we read the
10835 // previous (parent) context instead for a context provider.
10836 return previousContext;
10837 }
10838
10839 return contextStackCursor.current;
10840 }
10841 }
10842
10843 function cacheContext(workInProgress, unmaskedContext, maskedContext) {
10844 {
10845 var instance = workInProgress.stateNode;
10846 instance.__reactInternalMemoizedUnmaskedChildContext = unmaskedContext;
10847 instance.__reactInternalMemoizedMaskedChildContext = maskedContext;
10848 }
10849 }
10850
10851 function getMaskedContext(workInProgress, unmaskedContext) {
10852 {
10853 var type = workInProgress.type;
10854 var contextTypes = type.contextTypes;
10855
10856 if (!contextTypes) {
10857 return emptyContextObject;
10858 } // Avoid recreating masked context unless unmasked context has changed.
10859 // Failing to do this will result in unnecessary calls to componentWillReceiveProps.
10860 // This may trigger infinite loops if componentWillReceiveProps calls setState.
10861
10862
10863 var instance = workInProgress.stateNode;
10864
10865 if (instance && instance.__reactInternalMemoizedUnmaskedChildContext === unmaskedContext) {
10866 return instance.__reactInternalMemoizedMaskedChildContext;
10867 }
10868
10869 var context = {};
10870
10871 for (var key in contextTypes) {
10872 context[key] = unmaskedContext[key];
10873 }
10874
10875 {
10876 var name = getComponentName(type) || 'Unknown';
10877 checkPropTypes_1(contextTypes, context, 'context', name, getCurrentFiberStackInDev);
10878 } // Cache unmasked context so we can avoid recreating masked context unless necessary.
10879 // Context is created before the class component is instantiated so check for instance.
10880
10881
10882 if (instance) {
10883 cacheContext(workInProgress, unmaskedContext, context);
10884 }
10885
10886 return context;
10887 }
10888 }
10889
10890 function hasContextChanged() {
10891 {
10892 return didPerformWorkStackCursor.current;
10893 }
10894 }
10895
10896 function isContextProvider(type) {
10897 {
10898 var childContextTypes = type.childContextTypes;
10899 return childContextTypes !== null && childContextTypes !== undefined;
10900 }
10901 }
10902
10903 function popContext(fiber) {
10904 {
10905 pop(didPerformWorkStackCursor, fiber);
10906 pop(contextStackCursor, fiber);
10907 }
10908 }
10909
10910 function popTopLevelContextObject(fiber) {
10911 {
10912 pop(didPerformWorkStackCursor, fiber);
10913 pop(contextStackCursor, fiber);
10914 }
10915 }
10916
10917 function pushTopLevelContextObject(fiber, context, didChange) {
10918 {
10919 if (!(contextStackCursor.current === emptyContextObject)) {
10920 {
10921 throw Error( "Unexpected context found on stack. This error is likely caused by a bug in React. Please file an issue." );
10922 }
10923 }
10924
10925 push(contextStackCursor, context, fiber);
10926 push(didPerformWorkStackCursor, didChange, fiber);
10927 }
10928 }
10929
10930 function processChildContext(fiber, type, parentContext) {
10931 {
10932 var instance = fiber.stateNode;
10933 var childContextTypes = type.childContextTypes; // TODO (bvaughn) Replace this behavior with an invariant() in the future.
10934 // It has only been added in Fiber to match the (unintentional) behavior in Stack.
10935
10936 if (typeof instance.getChildContext !== 'function') {
10937 {
10938 var componentName = getComponentName(type) || 'Unknown';
10939
10940 if (!warnedAboutMissingGetChildContext[componentName]) {
10941 warnedAboutMissingGetChildContext[componentName] = true;
10942
10943 error('%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);
10944 }
10945 }
10946
10947 return parentContext;
10948 }
10949
10950 var childContext;
10951
10952 {
10953 setCurrentPhase('getChildContext');
10954 }
10955
10956 startPhaseTimer(fiber, 'getChildContext');
10957 childContext = instance.getChildContext();
10958 stopPhaseTimer();
10959
10960 {
10961 setCurrentPhase(null);
10962 }
10963
10964 for (var contextKey in childContext) {
10965 if (!(contextKey in childContextTypes)) {
10966 {
10967 throw Error( (getComponentName(type) || 'Unknown') + ".getChildContext(): key \"" + contextKey + "\" is not defined in childContextTypes." );
10968 }
10969 }
10970 }
10971
10972 {
10973 var name = getComponentName(type) || 'Unknown';
10974 checkPropTypes_1(childContextTypes, childContext, 'child context', name, // In practice, there is one case in which we won't get a stack. It's when
10975 // somebody calls unstable_renderSubtreeIntoContainer() and we process
10976 // context from the parent component instance. The stack will be missing
10977 // because it's outside of the reconciliation, and so the pointer has not
10978 // been set. This is rare and doesn't matter. We'll also remove that API.
10979 getCurrentFiberStackInDev);
10980 }
10981
10982 return _assign({}, parentContext, {}, childContext);
10983 }
10984 }
10985
10986 function pushContextProvider(workInProgress) {
10987 {
10988 var instance = workInProgress.stateNode; // We push the context as early as possible to ensure stack integrity.
10989 // If the instance does not exist yet, we will push null at first,
10990 // and replace it on the stack later when invalidating the context.
10991
10992 var memoizedMergedChildContext = instance && instance.__reactInternalMemoizedMergedChildContext || emptyContextObject; // Remember the parent context so we can merge with it later.
10993 // Inherit the parent's did-perform-work value to avoid inadvertently blocking updates.
10994
10995 previousContext = contextStackCursor.current;
10996 push(contextStackCursor, memoizedMergedChildContext, workInProgress);
10997 push(didPerformWorkStackCursor, didPerformWorkStackCursor.current, workInProgress);
10998 return true;
10999 }
11000 }
11001
11002 function invalidateContextProvider(workInProgress, type, didChange) {
11003 {
11004 var instance = workInProgress.stateNode;
11005
11006 if (!instance) {
11007 {
11008 throw Error( "Expected to have an instance by this point. This error is likely caused by a bug in React. Please file an issue." );
11009 }
11010 }
11011
11012 if (didChange) {
11013 // Merge parent and own context.
11014 // Skip this if we're not updating due to sCU.
11015 // This avoids unnecessarily recomputing memoized values.
11016 var mergedContext = processChildContext(workInProgress, type, previousContext);
11017 instance.__reactInternalMemoizedMergedChildContext = mergedContext; // Replace the old (or empty) context with the new one.
11018 // It is important to unwind the context in the reverse order.
11019
11020 pop(didPerformWorkStackCursor, workInProgress);
11021 pop(contextStackCursor, workInProgress); // Now push the new context and mark that it has changed.
11022
11023 push(contextStackCursor, mergedContext, workInProgress);
11024 push(didPerformWorkStackCursor, didChange, workInProgress);
11025 } else {
11026 pop(didPerformWorkStackCursor, workInProgress);
11027 push(didPerformWorkStackCursor, didChange, workInProgress);
11028 }
11029 }
11030 }
11031
11032 function findCurrentUnmaskedContext(fiber) {
11033 {
11034 // Currently this is only used with renderSubtreeIntoContainer; not sure if it
11035 // makes sense elsewhere
11036 if (!(isFiberMounted(fiber) && fiber.tag === ClassComponent)) {
11037 {
11038 throw Error( "Expected subtree parent to be a mounted class component. This error is likely caused by a bug in React. Please file an issue." );
11039 }
11040 }
11041
11042 var node = fiber;
11043
11044 do {
11045 switch (node.tag) {
11046 case HostRoot:
11047 return node.stateNode.context;
11048
11049 case ClassComponent:
11050 {
11051 var Component = node.type;
11052
11053 if (isContextProvider(Component)) {
11054 return node.stateNode.__reactInternalMemoizedMergedChildContext;
11055 }
11056
11057 break;
11058 }
11059 }
11060
11061 node = node.return;
11062 } while (node !== null);
11063
11064 {
11065 {
11066 throw Error( "Found unexpected detached subtree parent. This error is likely caused by a bug in React. Please file an issue." );
11067 }
11068 }
11069 }
11070 }
11071
11072 var LegacyRoot = 0;
11073 var BlockingRoot = 1;
11074 var ConcurrentRoot = 2;
11075
11076 var ReactInternals$2 = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
11077 var _ReactInternals$Sched$1 = ReactInternals$2.SchedulerTracing,
11078 __interactionsRef = _ReactInternals$Sched$1.__interactionsRef,
11079 __subscriberRef = _ReactInternals$Sched$1.__subscriberRef,
11080 unstable_clear = _ReactInternals$Sched$1.unstable_clear,
11081 unstable_getCurrent = _ReactInternals$Sched$1.unstable_getCurrent,
11082 unstable_getThreadID = _ReactInternals$Sched$1.unstable_getThreadID,
11083 unstable_subscribe = _ReactInternals$Sched$1.unstable_subscribe,
11084 unstable_trace = _ReactInternals$Sched$1.unstable_trace,
11085 unstable_unsubscribe = _ReactInternals$Sched$1.unstable_unsubscribe,
11086 unstable_wrap = _ReactInternals$Sched$1.unstable_wrap;
11087
11088 var Scheduler_runWithPriority = unstable_runWithPriority,
11089 Scheduler_scheduleCallback = unstable_scheduleCallback,
11090 Scheduler_cancelCallback = unstable_cancelCallback,
11091 Scheduler_shouldYield = unstable_shouldYield,
11092 Scheduler_requestPaint = unstable_requestPaint,
11093 Scheduler_now = unstable_now,
11094 Scheduler_getCurrentPriorityLevel = unstable_getCurrentPriorityLevel,
11095 Scheduler_ImmediatePriority = unstable_ImmediatePriority,
11096 Scheduler_UserBlockingPriority = unstable_UserBlockingPriority,
11097 Scheduler_NormalPriority = unstable_NormalPriority,
11098 Scheduler_LowPriority = unstable_LowPriority,
11099 Scheduler_IdlePriority = unstable_IdlePriority;
11100
11101 {
11102 // Provide explicit error message when production+profiling bundle of e.g.
11103 // react-dom is used with production (non-profiling) bundle of
11104 // scheduler/tracing
11105 if (!(__interactionsRef != null && __interactionsRef.current != null)) {
11106 {
11107 throw 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" );
11108 }
11109 }
11110 }
11111
11112 var fakeCallbackNode = {}; // Except for NoPriority, these correspond to Scheduler priorities. We use
11113 // ascending numbers so we can compare them like numbers. They start at 90 to
11114 // avoid clashing with Scheduler's priorities.
11115
11116 var ImmediatePriority = 99;
11117 var UserBlockingPriority$1 = 98;
11118 var NormalPriority = 97;
11119 var LowPriority = 96;
11120 var IdlePriority = 95; // NoPriority is the absence of priority. Also React-only.
11121
11122 var NoPriority = 90;
11123 var shouldYield = Scheduler_shouldYield;
11124 var requestPaint = // Fall back gracefully if we're running an older version of Scheduler.
11125 Scheduler_requestPaint !== undefined ? Scheduler_requestPaint : function () {};
11126 var syncQueue = null;
11127 var immediateQueueCallbackNode = null;
11128 var isFlushingSyncQueue = false;
11129 var initialTimeMs = Scheduler_now(); // If the initial timestamp is reasonably small, use Scheduler's `now` directly.
11130 // This will be the case for modern browsers that support `performance.now`. In
11131 // older browsers, Scheduler falls back to `Date.now`, which returns a Unix
11132 // timestamp. In that case, subtract the module initialization time to simulate
11133 // the behavior of performance.now and keep our times small enough to fit
11134 // within 32 bits.
11135 // TODO: Consider lifting this into Scheduler.
11136
11137 var now = initialTimeMs < 10000 ? Scheduler_now : function () {
11138 return Scheduler_now() - initialTimeMs;
11139 };
11140 function getCurrentPriorityLevel() {
11141 switch (Scheduler_getCurrentPriorityLevel()) {
11142 case Scheduler_ImmediatePriority:
11143 return ImmediatePriority;
11144
11145 case Scheduler_UserBlockingPriority:
11146 return UserBlockingPriority$1;
11147
11148 case Scheduler_NormalPriority:
11149 return NormalPriority;
11150
11151 case Scheduler_LowPriority:
11152 return LowPriority;
11153
11154 case Scheduler_IdlePriority:
11155 return IdlePriority;
11156
11157 default:
11158 {
11159 {
11160 throw Error( "Unknown priority level." );
11161 }
11162 }
11163
11164 }
11165 }
11166
11167 function reactPriorityToSchedulerPriority(reactPriorityLevel) {
11168 switch (reactPriorityLevel) {
11169 case ImmediatePriority:
11170 return Scheduler_ImmediatePriority;
11171
11172 case UserBlockingPriority$1:
11173 return Scheduler_UserBlockingPriority;
11174
11175 case NormalPriority:
11176 return Scheduler_NormalPriority;
11177
11178 case LowPriority:
11179 return Scheduler_LowPriority;
11180
11181 case IdlePriority:
11182 return Scheduler_IdlePriority;
11183
11184 default:
11185 {
11186 {
11187 throw Error( "Unknown priority level." );
11188 }
11189 }
11190
11191 }
11192 }
11193
11194 function runWithPriority$1(reactPriorityLevel, fn) {
11195 var priorityLevel = reactPriorityToSchedulerPriority(reactPriorityLevel);
11196 return Scheduler_runWithPriority(priorityLevel, fn);
11197 }
11198 function scheduleCallback(reactPriorityLevel, callback, options) {
11199 var priorityLevel = reactPriorityToSchedulerPriority(reactPriorityLevel);
11200 return Scheduler_scheduleCallback(priorityLevel, callback, options);
11201 }
11202 function scheduleSyncCallback(callback) {
11203 // Push this callback into an internal queue. We'll flush these either in
11204 // the next tick, or earlier if something calls `flushSyncCallbackQueue`.
11205 if (syncQueue === null) {
11206 syncQueue = [callback]; // Flush the queue in the next tick, at the earliest.
11207
11208 immediateQueueCallbackNode = Scheduler_scheduleCallback(Scheduler_ImmediatePriority, flushSyncCallbackQueueImpl);
11209 } else {
11210 // Push onto existing queue. Don't need to schedule a callback because
11211 // we already scheduled one when we created the queue.
11212 syncQueue.push(callback);
11213 }
11214
11215 return fakeCallbackNode;
11216 }
11217 function cancelCallback(callbackNode) {
11218 if (callbackNode !== fakeCallbackNode) {
11219 Scheduler_cancelCallback(callbackNode);
11220 }
11221 }
11222 function flushSyncCallbackQueue() {
11223 if (immediateQueueCallbackNode !== null) {
11224 var node = immediateQueueCallbackNode;
11225 immediateQueueCallbackNode = null;
11226 Scheduler_cancelCallback(node);
11227 }
11228
11229 flushSyncCallbackQueueImpl();
11230 }
11231
11232 function flushSyncCallbackQueueImpl() {
11233 if (!isFlushingSyncQueue && syncQueue !== null) {
11234 // Prevent re-entrancy.
11235 isFlushingSyncQueue = true;
11236 var i = 0;
11237
11238 try {
11239 var _isSync = true;
11240 var queue = syncQueue;
11241 runWithPriority$1(ImmediatePriority, function () {
11242 for (; i < queue.length; i++) {
11243 var callback = queue[i];
11244
11245 do {
11246 callback = callback(_isSync);
11247 } while (callback !== null);
11248 }
11249 });
11250 syncQueue = null;
11251 } catch (error) {
11252 // If something throws, leave the remaining callbacks on the queue.
11253 if (syncQueue !== null) {
11254 syncQueue = syncQueue.slice(i + 1);
11255 } // Resume flushing in the next tick
11256
11257
11258 Scheduler_scheduleCallback(Scheduler_ImmediatePriority, flushSyncCallbackQueue);
11259 throw error;
11260 } finally {
11261 isFlushingSyncQueue = false;
11262 }
11263 }
11264 }
11265
11266 var NoMode = 0;
11267 var StrictMode = 1; // TODO: Remove BlockingMode and ConcurrentMode by reading from the root
11268 // tag instead
11269
11270 var BlockingMode = 2;
11271 var ConcurrentMode = 4;
11272 var ProfileMode = 8;
11273
11274 // Max 31 bit integer. The max integer size in V8 for 32-bit systems.
11275 // Math.pow(2, 30) - 1
11276 // 0b111111111111111111111111111111
11277 var MAX_SIGNED_31_BIT_INT = 1073741823;
11278
11279 var NoWork = 0; // TODO: Think of a better name for Never. The key difference with Idle is that
11280 // Never work can be committed in an inconsistent state without tearing the UI.
11281 // The main example is offscreen content, like a hidden subtree. So one possible
11282 // name is Offscreen. However, it also includes dehydrated Suspense boundaries,
11283 // which are inconsistent in the sense that they haven't finished yet, but
11284 // aren't visibly inconsistent because the server rendered HTML matches what the
11285 // hydrated tree would look like.
11286
11287 var Never = 1; // Idle is slightly higher priority than Never. It must completely finish in
11288 // order to be consistent.
11289
11290 var Idle = 2; // Continuous Hydration is slightly higher than Idle and is used to increase
11291 // priority of hover targets.
11292
11293 var ContinuousHydration = 3;
11294 var Sync = MAX_SIGNED_31_BIT_INT;
11295 var Batched = Sync - 1;
11296 var UNIT_SIZE = 10;
11297 var MAGIC_NUMBER_OFFSET = Batched - 1; // 1 unit of expiration time represents 10ms.
11298
11299 function msToExpirationTime(ms) {
11300 // Always subtract from the offset so that we don't clash with the magic number for NoWork.
11301 return MAGIC_NUMBER_OFFSET - (ms / UNIT_SIZE | 0);
11302 }
11303 function expirationTimeToMs(expirationTime) {
11304 return (MAGIC_NUMBER_OFFSET - expirationTime) * UNIT_SIZE;
11305 }
11306
11307 function ceiling(num, precision) {
11308 return ((num / precision | 0) + 1) * precision;
11309 }
11310
11311 function computeExpirationBucket(currentTime, expirationInMs, bucketSizeMs) {
11312 return MAGIC_NUMBER_OFFSET - ceiling(MAGIC_NUMBER_OFFSET - currentTime + expirationInMs / UNIT_SIZE, bucketSizeMs / UNIT_SIZE);
11313 } // TODO: This corresponds to Scheduler's NormalPriority, not LowPriority. Update
11314 // the names to reflect.
11315
11316
11317 var LOW_PRIORITY_EXPIRATION = 5000;
11318 var LOW_PRIORITY_BATCH_SIZE = 250;
11319 function computeAsyncExpiration(currentTime) {
11320 return computeExpirationBucket(currentTime, LOW_PRIORITY_EXPIRATION, LOW_PRIORITY_BATCH_SIZE);
11321 }
11322 function computeSuspenseExpiration(currentTime, timeoutMs) {
11323 // TODO: Should we warn if timeoutMs is lower than the normal pri expiration time?
11324 return computeExpirationBucket(currentTime, timeoutMs, LOW_PRIORITY_BATCH_SIZE);
11325 } // We intentionally set a higher expiration time for interactive updates in
11326 // dev than in production.
11327 //
11328 // If the main thread is being blocked so long that you hit the expiration,
11329 // it's a problem that could be solved with better scheduling.
11330 //
11331 // People will be more likely to notice this and fix it with the long
11332 // expiration time in development.
11333 //
11334 // In production we opt for better UX at the risk of masking scheduling
11335 // problems, by expiring fast.
11336
11337 var HIGH_PRIORITY_EXPIRATION = 500 ;
11338 var HIGH_PRIORITY_BATCH_SIZE = 100;
11339 function computeInteractiveExpiration(currentTime) {
11340 return computeExpirationBucket(currentTime, HIGH_PRIORITY_EXPIRATION, HIGH_PRIORITY_BATCH_SIZE);
11341 }
11342 function inferPriorityFromExpirationTime(currentTime, expirationTime) {
11343 if (expirationTime === Sync) {
11344 return ImmediatePriority;
11345 }
11346
11347 if (expirationTime === Never || expirationTime === Idle) {
11348 return IdlePriority;
11349 }
11350
11351 var msUntil = expirationTimeToMs(expirationTime) - expirationTimeToMs(currentTime);
11352
11353 if (msUntil <= 0) {
11354 return ImmediatePriority;
11355 }
11356
11357 if (msUntil <= HIGH_PRIORITY_EXPIRATION + HIGH_PRIORITY_BATCH_SIZE) {
11358 return UserBlockingPriority$1;
11359 }
11360
11361 if (msUntil <= LOW_PRIORITY_EXPIRATION + LOW_PRIORITY_BATCH_SIZE) {
11362 return NormalPriority;
11363 } // TODO: Handle LowPriority
11364 // Assume anything lower has idle priority
11365
11366
11367 return IdlePriority;
11368 }
11369
11370 var ReactStrictModeWarnings = {
11371 recordUnsafeLifecycleWarnings: function (fiber, instance) {},
11372 flushPendingUnsafeLifecycleWarnings: function () {},
11373 recordLegacyContextWarning: function (fiber, instance) {},
11374 flushLegacyContextWarning: function () {},
11375 discardPendingWarnings: function () {}
11376 };
11377
11378 {
11379 var findStrictRoot = function (fiber) {
11380 var maybeStrictRoot = null;
11381 var node = fiber;
11382
11383 while (node !== null) {
11384 if (node.mode & StrictMode) {
11385 maybeStrictRoot = node;
11386 }
11387
11388 node = node.return;
11389 }
11390
11391 return maybeStrictRoot;
11392 };
11393
11394 var setToSortedString = function (set) {
11395 var array = [];
11396 set.forEach(function (value) {
11397 array.push(value);
11398 });
11399 return array.sort().join(', ');
11400 };
11401
11402 var pendingComponentWillMountWarnings = [];
11403 var pendingUNSAFE_ComponentWillMountWarnings = [];
11404 var pendingComponentWillReceivePropsWarnings = [];
11405 var pendingUNSAFE_ComponentWillReceivePropsWarnings = [];
11406 var pendingComponentWillUpdateWarnings = [];
11407 var pendingUNSAFE_ComponentWillUpdateWarnings = []; // Tracks components we have already warned about.
11408
11409 var didWarnAboutUnsafeLifecycles = new Set();
11410
11411 ReactStrictModeWarnings.recordUnsafeLifecycleWarnings = function (fiber, instance) {
11412 // Dedup strategy: Warn once per component.
11413 if (didWarnAboutUnsafeLifecycles.has(fiber.type)) {
11414 return;
11415 }
11416
11417 if (typeof instance.componentWillMount === 'function' && // Don't warn about react-lifecycles-compat polyfilled components.
11418 instance.componentWillMount.__suppressDeprecationWarning !== true) {
11419 pendingComponentWillMountWarnings.push(fiber);
11420 }
11421
11422 if (fiber.mode & StrictMode && typeof instance.UNSAFE_componentWillMount === 'function') {
11423 pendingUNSAFE_ComponentWillMountWarnings.push(fiber);
11424 }
11425
11426 if (typeof instance.componentWillReceiveProps === 'function' && instance.componentWillReceiveProps.__suppressDeprecationWarning !== true) {
11427 pendingComponentWillReceivePropsWarnings.push(fiber);
11428 }
11429
11430 if (fiber.mode & StrictMode && typeof instance.UNSAFE_componentWillReceiveProps === 'function') {
11431 pendingUNSAFE_ComponentWillReceivePropsWarnings.push(fiber);
11432 }
11433
11434 if (typeof instance.componentWillUpdate === 'function' && instance.componentWillUpdate.__suppressDeprecationWarning !== true) {
11435 pendingComponentWillUpdateWarnings.push(fiber);
11436 }
11437
11438 if (fiber.mode & StrictMode && typeof instance.UNSAFE_componentWillUpdate === 'function') {
11439 pendingUNSAFE_ComponentWillUpdateWarnings.push(fiber);
11440 }
11441 };
11442
11443 ReactStrictModeWarnings.flushPendingUnsafeLifecycleWarnings = function () {
11444 // We do an initial pass to gather component names
11445 var componentWillMountUniqueNames = new Set();
11446
11447 if (pendingComponentWillMountWarnings.length > 0) {
11448 pendingComponentWillMountWarnings.forEach(function (fiber) {
11449 componentWillMountUniqueNames.add(getComponentName(fiber.type) || 'Component');
11450 didWarnAboutUnsafeLifecycles.add(fiber.type);
11451 });
11452 pendingComponentWillMountWarnings = [];
11453 }
11454
11455 var UNSAFE_componentWillMountUniqueNames = new Set();
11456
11457 if (pendingUNSAFE_ComponentWillMountWarnings.length > 0) {
11458 pendingUNSAFE_ComponentWillMountWarnings.forEach(function (fiber) {
11459 UNSAFE_componentWillMountUniqueNames.add(getComponentName(fiber.type) || 'Component');
11460 didWarnAboutUnsafeLifecycles.add(fiber.type);
11461 });
11462 pendingUNSAFE_ComponentWillMountWarnings = [];
11463 }
11464
11465 var componentWillReceivePropsUniqueNames = new Set();
11466
11467 if (pendingComponentWillReceivePropsWarnings.length > 0) {
11468 pendingComponentWillReceivePropsWarnings.forEach(function (fiber) {
11469 componentWillReceivePropsUniqueNames.add(getComponentName(fiber.type) || 'Component');
11470 didWarnAboutUnsafeLifecycles.add(fiber.type);
11471 });
11472 pendingComponentWillReceivePropsWarnings = [];
11473 }
11474
11475 var UNSAFE_componentWillReceivePropsUniqueNames = new Set();
11476
11477 if (pendingUNSAFE_ComponentWillReceivePropsWarnings.length > 0) {
11478 pendingUNSAFE_ComponentWillReceivePropsWarnings.forEach(function (fiber) {
11479 UNSAFE_componentWillReceivePropsUniqueNames.add(getComponentName(fiber.type) || 'Component');
11480 didWarnAboutUnsafeLifecycles.add(fiber.type);
11481 });
11482 pendingUNSAFE_ComponentWillReceivePropsWarnings = [];
11483 }
11484
11485 var componentWillUpdateUniqueNames = new Set();
11486
11487 if (pendingComponentWillUpdateWarnings.length > 0) {
11488 pendingComponentWillUpdateWarnings.forEach(function (fiber) {
11489 componentWillUpdateUniqueNames.add(getComponentName(fiber.type) || 'Component');
11490 didWarnAboutUnsafeLifecycles.add(fiber.type);
11491 });
11492 pendingComponentWillUpdateWarnings = [];
11493 }
11494
11495 var UNSAFE_componentWillUpdateUniqueNames = new Set();
11496
11497 if (pendingUNSAFE_ComponentWillUpdateWarnings.length > 0) {
11498 pendingUNSAFE_ComponentWillUpdateWarnings.forEach(function (fiber) {
11499 UNSAFE_componentWillUpdateUniqueNames.add(getComponentName(fiber.type) || 'Component');
11500 didWarnAboutUnsafeLifecycles.add(fiber.type);
11501 });
11502 pendingUNSAFE_ComponentWillUpdateWarnings = [];
11503 } // Finally, we flush all the warnings
11504 // UNSAFE_ ones before the deprecated ones, since they'll be 'louder'
11505
11506
11507 if (UNSAFE_componentWillMountUniqueNames.size > 0) {
11508 var sortedNames = setToSortedString(UNSAFE_componentWillMountUniqueNames);
11509
11510 error('Using UNSAFE_componentWillMount in strict mode is not recommended and may indicate bugs in your code. ' + 'See https://fb.me/react-unsafe-component-lifecycles 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);
11511 }
11512
11513 if (UNSAFE_componentWillReceivePropsUniqueNames.size > 0) {
11514 var _sortedNames = setToSortedString(UNSAFE_componentWillReceivePropsUniqueNames);
11515
11516 error('Using UNSAFE_componentWillReceiveProps in strict mode is not recommended ' + 'and may indicate bugs in your code. ' + 'See https://fb.me/react-unsafe-component-lifecycles 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);
11517 }
11518
11519 if (UNSAFE_componentWillUpdateUniqueNames.size > 0) {
11520 var _sortedNames2 = setToSortedString(UNSAFE_componentWillUpdateUniqueNames);
11521
11522 error('Using UNSAFE_componentWillUpdate in strict mode is not recommended ' + 'and may indicate bugs in your code. ' + 'See https://fb.me/react-unsafe-component-lifecycles for details.\n\n' + '* Move data fetching code or side effects to componentDidUpdate.\n' + '\nPlease update the following components: %s', _sortedNames2);
11523 }
11524
11525 if (componentWillMountUniqueNames.size > 0) {
11526 var _sortedNames3 = setToSortedString(componentWillMountUniqueNames);
11527
11528 warn('componentWillMount has been renamed, and is not recommended for use. ' + 'See https://fb.me/react-unsafe-component-lifecycles 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);
11529 }
11530
11531 if (componentWillReceivePropsUniqueNames.size > 0) {
11532 var _sortedNames4 = setToSortedString(componentWillReceivePropsUniqueNames);
11533
11534 warn('componentWillReceiveProps has been renamed, and is not recommended for use. ' + 'See https://fb.me/react-unsafe-component-lifecycles 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);
11535 }
11536
11537 if (componentWillUpdateUniqueNames.size > 0) {
11538 var _sortedNames5 = setToSortedString(componentWillUpdateUniqueNames);
11539
11540 warn('componentWillUpdate has been renamed, and is not recommended for use. ' + 'See https://fb.me/react-unsafe-component-lifecycles 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);
11541 }
11542 };
11543
11544 var pendingLegacyContextWarning = new Map(); // Tracks components we have already warned about.
11545
11546 var didWarnAboutLegacyContext = new Set();
11547
11548 ReactStrictModeWarnings.recordLegacyContextWarning = function (fiber, instance) {
11549 var strictRoot = findStrictRoot(fiber);
11550
11551 if (strictRoot === null) {
11552 error('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.');
11553
11554 return;
11555 } // Dedup strategy: Warn once per component.
11556
11557
11558 if (didWarnAboutLegacyContext.has(fiber.type)) {
11559 return;
11560 }
11561
11562 var warningsForRoot = pendingLegacyContextWarning.get(strictRoot);
11563
11564 if (fiber.type.contextTypes != null || fiber.type.childContextTypes != null || instance !== null && typeof instance.getChildContext === 'function') {
11565 if (warningsForRoot === undefined) {
11566 warningsForRoot = [];
11567 pendingLegacyContextWarning.set(strictRoot, warningsForRoot);
11568 }
11569
11570 warningsForRoot.push(fiber);
11571 }
11572 };
11573
11574 ReactStrictModeWarnings.flushLegacyContextWarning = function () {
11575 pendingLegacyContextWarning.forEach(function (fiberArray, strictRoot) {
11576 if (fiberArray.length === 0) {
11577 return;
11578 }
11579
11580 var firstFiber = fiberArray[0];
11581 var uniqueNames = new Set();
11582 fiberArray.forEach(function (fiber) {
11583 uniqueNames.add(getComponentName(fiber.type) || 'Component');
11584 didWarnAboutLegacyContext.add(fiber.type);
11585 });
11586 var sortedNames = setToSortedString(uniqueNames);
11587 var firstComponentStack = getStackByFiberInDevAndProd(firstFiber);
11588
11589 error('Legacy context API has been detected within a strict-mode tree.' + '\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: https://fb.me/react-legacy-context' + '%s', sortedNames, firstComponentStack);
11590 });
11591 };
11592
11593 ReactStrictModeWarnings.discardPendingWarnings = function () {
11594 pendingComponentWillMountWarnings = [];
11595 pendingUNSAFE_ComponentWillMountWarnings = [];
11596 pendingComponentWillReceivePropsWarnings = [];
11597 pendingUNSAFE_ComponentWillReceivePropsWarnings = [];
11598 pendingComponentWillUpdateWarnings = [];
11599 pendingUNSAFE_ComponentWillUpdateWarnings = [];
11600 pendingLegacyContextWarning = new Map();
11601 };
11602 }
11603
11604 var resolveFamily = null; // $FlowFixMe Flow gets confused by a WeakSet feature check below.
11605
11606 var failedBoundaries = null;
11607 var setRefreshHandler = function (handler) {
11608 {
11609 resolveFamily = handler;
11610 }
11611 };
11612 function resolveFunctionForHotReloading(type) {
11613 {
11614 if (resolveFamily === null) {
11615 // Hot reloading is disabled.
11616 return type;
11617 }
11618
11619 var family = resolveFamily(type);
11620
11621 if (family === undefined) {
11622 return type;
11623 } // Use the latest known implementation.
11624
11625
11626 return family.current;
11627 }
11628 }
11629 function resolveClassForHotReloading(type) {
11630 // No implementation differences.
11631 return resolveFunctionForHotReloading(type);
11632 }
11633 function resolveForwardRefForHotReloading(type) {
11634 {
11635 if (resolveFamily === null) {
11636 // Hot reloading is disabled.
11637 return type;
11638 }
11639
11640 var family = resolveFamily(type);
11641
11642 if (family === undefined) {
11643 // Check if we're dealing with a real forwardRef. Don't want to crash early.
11644 if (type !== null && type !== undefined && typeof type.render === 'function') {
11645 // ForwardRef is special because its resolved .type is an object,
11646 // but it's possible that we only have its inner render function in the map.
11647 // If that inner render function is different, we'll build a new forwardRef type.
11648 var currentRender = resolveFunctionForHotReloading(type.render);
11649
11650 if (type.render !== currentRender) {
11651 var syntheticType = {
11652 $$typeof: REACT_FORWARD_REF_TYPE,
11653 render: currentRender
11654 };
11655
11656 if (type.displayName !== undefined) {
11657 syntheticType.displayName = type.displayName;
11658 }
11659
11660 return syntheticType;
11661 }
11662 }
11663
11664 return type;
11665 } // Use the latest known implementation.
11666
11667
11668 return family.current;
11669 }
11670 }
11671 function isCompatibleFamilyForHotReloading(fiber, element) {
11672 {
11673 if (resolveFamily === null) {
11674 // Hot reloading is disabled.
11675 return false;
11676 }
11677
11678 var prevType = fiber.elementType;
11679 var nextType = element.type; // If we got here, we know types aren't === equal.
11680
11681 var needsCompareFamilies = false;
11682 var $$typeofNextType = typeof nextType === 'object' && nextType !== null ? nextType.$$typeof : null;
11683
11684 switch (fiber.tag) {
11685 case ClassComponent:
11686 {
11687 if (typeof nextType === 'function') {
11688 needsCompareFamilies = true;
11689 }
11690
11691 break;
11692 }
11693
11694 case FunctionComponent:
11695 {
11696 if (typeof nextType === 'function') {
11697 needsCompareFamilies = true;
11698 } else if ($$typeofNextType === REACT_LAZY_TYPE) {
11699 // We don't know the inner type yet.
11700 // We're going to assume that the lazy inner type is stable,
11701 // and so it is sufficient to avoid reconciling it away.
11702 // We're not going to unwrap or actually use the new lazy type.
11703 needsCompareFamilies = true;
11704 }
11705
11706 break;
11707 }
11708
11709 case ForwardRef:
11710 {
11711 if ($$typeofNextType === REACT_FORWARD_REF_TYPE) {
11712 needsCompareFamilies = true;
11713 } else if ($$typeofNextType === REACT_LAZY_TYPE) {
11714 needsCompareFamilies = true;
11715 }
11716
11717 break;
11718 }
11719
11720 case MemoComponent:
11721 case SimpleMemoComponent:
11722 {
11723 if ($$typeofNextType === REACT_MEMO_TYPE) {
11724 // TODO: if it was but can no longer be simple,
11725 // we shouldn't set this.
11726 needsCompareFamilies = true;
11727 } else if ($$typeofNextType === REACT_LAZY_TYPE) {
11728 needsCompareFamilies = true;
11729 }
11730
11731 break;
11732 }
11733
11734 default:
11735 return false;
11736 } // Check if both types have a family and it's the same one.
11737
11738
11739 if (needsCompareFamilies) {
11740 // Note: memo() and forwardRef() we'll compare outer rather than inner type.
11741 // This means both of them need to be registered to preserve state.
11742 // If we unwrapped and compared the inner types for wrappers instead,
11743 // then we would risk falsely saying two separate memo(Foo)
11744 // calls are equivalent because they wrap the same Foo function.
11745 var prevFamily = resolveFamily(prevType);
11746
11747 if (prevFamily !== undefined && prevFamily === resolveFamily(nextType)) {
11748 return true;
11749 }
11750 }
11751
11752 return false;
11753 }
11754 }
11755 function markFailedErrorBoundaryForHotReloading(fiber) {
11756 {
11757 if (resolveFamily === null) {
11758 // Hot reloading is disabled.
11759 return;
11760 }
11761
11762 if (typeof WeakSet !== 'function') {
11763 return;
11764 }
11765
11766 if (failedBoundaries === null) {
11767 failedBoundaries = new WeakSet();
11768 }
11769
11770 failedBoundaries.add(fiber);
11771 }
11772 }
11773 var scheduleRefresh = function (root, update) {
11774 {
11775 if (resolveFamily === null) {
11776 // Hot reloading is disabled.
11777 return;
11778 }
11779
11780 var staleFamilies = update.staleFamilies,
11781 updatedFamilies = update.updatedFamilies;
11782 flushPassiveEffects();
11783 flushSync(function () {
11784 scheduleFibersWithFamiliesRecursively(root.current, updatedFamilies, staleFamilies);
11785 });
11786 }
11787 };
11788 var scheduleRoot = function (root, element) {
11789 {
11790 if (root.context !== emptyContextObject) {
11791 // Super edge case: root has a legacy _renderSubtree context
11792 // but we don't know the parentComponent so we can't pass it.
11793 // Just ignore. We'll delete this with _renderSubtree code path later.
11794 return;
11795 }
11796
11797 flushPassiveEffects();
11798 syncUpdates(function () {
11799 updateContainer(element, root, null, null);
11800 });
11801 }
11802 };
11803
11804 function scheduleFibersWithFamiliesRecursively(fiber, updatedFamilies, staleFamilies) {
11805 {
11806 var alternate = fiber.alternate,
11807 child = fiber.child,
11808 sibling = fiber.sibling,
11809 tag = fiber.tag,
11810 type = fiber.type;
11811 var candidateType = null;
11812
11813 switch (tag) {
11814 case FunctionComponent:
11815 case SimpleMemoComponent:
11816 case ClassComponent:
11817 candidateType = type;
11818 break;
11819
11820 case ForwardRef:
11821 candidateType = type.render;
11822 break;
11823 }
11824
11825 if (resolveFamily === null) {
11826 throw new Error('Expected resolveFamily to be set during hot reload.');
11827 }
11828
11829 var needsRender = false;
11830 var needsRemount = false;
11831
11832 if (candidateType !== null) {
11833 var family = resolveFamily(candidateType);
11834
11835 if (family !== undefined) {
11836 if (staleFamilies.has(family)) {
11837 needsRemount = true;
11838 } else if (updatedFamilies.has(family)) {
11839 if (tag === ClassComponent) {
11840 needsRemount = true;
11841 } else {
11842 needsRender = true;
11843 }
11844 }
11845 }
11846 }
11847
11848 if (failedBoundaries !== null) {
11849 if (failedBoundaries.has(fiber) || alternate !== null && failedBoundaries.has(alternate)) {
11850 needsRemount = true;
11851 }
11852 }
11853
11854 if (needsRemount) {
11855 fiber._debugNeedsRemount = true;
11856 }
11857
11858 if (needsRemount || needsRender) {
11859 scheduleWork(fiber, Sync);
11860 }
11861
11862 if (child !== null && !needsRemount) {
11863 scheduleFibersWithFamiliesRecursively(child, updatedFamilies, staleFamilies);
11864 }
11865
11866 if (sibling !== null) {
11867 scheduleFibersWithFamiliesRecursively(sibling, updatedFamilies, staleFamilies);
11868 }
11869 }
11870 }
11871
11872 var findHostInstancesForRefresh = function (root, families) {
11873 {
11874 var hostInstances = new Set();
11875 var types = new Set(families.map(function (family) {
11876 return family.current;
11877 }));
11878 findHostInstancesForMatchingFibersRecursively(root.current, types, hostInstances);
11879 return hostInstances;
11880 }
11881 };
11882
11883 function findHostInstancesForMatchingFibersRecursively(fiber, types, hostInstances) {
11884 {
11885 var child = fiber.child,
11886 sibling = fiber.sibling,
11887 tag = fiber.tag,
11888 type = fiber.type;
11889 var candidateType = null;
11890
11891 switch (tag) {
11892 case FunctionComponent:
11893 case SimpleMemoComponent:
11894 case ClassComponent:
11895 candidateType = type;
11896 break;
11897
11898 case ForwardRef:
11899 candidateType = type.render;
11900 break;
11901 }
11902
11903 var didMatch = false;
11904
11905 if (candidateType !== null) {
11906 if (types.has(candidateType)) {
11907 didMatch = true;
11908 }
11909 }
11910
11911 if (didMatch) {
11912 // We have a match. This only drills down to the closest host components.
11913 // There's no need to search deeper because for the purpose of giving
11914 // visual feedback, "flashing" outermost parent rectangles is sufficient.
11915 findHostInstancesForFiberShallowly(fiber, hostInstances);
11916 } else {
11917 // If there's no match, maybe there will be one further down in the child tree.
11918 if (child !== null) {
11919 findHostInstancesForMatchingFibersRecursively(child, types, hostInstances);
11920 }
11921 }
11922
11923 if (sibling !== null) {
11924 findHostInstancesForMatchingFibersRecursively(sibling, types, hostInstances);
11925 }
11926 }
11927 }
11928
11929 function findHostInstancesForFiberShallowly(fiber, hostInstances) {
11930 {
11931 var foundHostInstances = findChildHostInstancesForFiberShallowly(fiber, hostInstances);
11932
11933 if (foundHostInstances) {
11934 return;
11935 } // If we didn't find any host children, fallback to closest host parent.
11936
11937
11938 var node = fiber;
11939
11940 while (true) {
11941 switch (node.tag) {
11942 case HostComponent:
11943 hostInstances.add(node.stateNode);
11944 return;
11945
11946 case HostPortal:
11947 hostInstances.add(node.stateNode.containerInfo);
11948 return;
11949
11950 case HostRoot:
11951 hostInstances.add(node.stateNode.containerInfo);
11952 return;
11953 }
11954
11955 if (node.return === null) {
11956 throw new Error('Expected to reach root first.');
11957 }
11958
11959 node = node.return;
11960 }
11961 }
11962 }
11963
11964 function findChildHostInstancesForFiberShallowly(fiber, hostInstances) {
11965 {
11966 var node = fiber;
11967 var foundHostInstances = false;
11968
11969 while (true) {
11970 if (node.tag === HostComponent) {
11971 // We got a match.
11972 foundHostInstances = true;
11973 hostInstances.add(node.stateNode); // There may still be more, so keep searching.
11974 } else if (node.child !== null) {
11975 node.child.return = node;
11976 node = node.child;
11977 continue;
11978 }
11979
11980 if (node === fiber) {
11981 return foundHostInstances;
11982 }
11983
11984 while (node.sibling === null) {
11985 if (node.return === null || node.return === fiber) {
11986 return foundHostInstances;
11987 }
11988
11989 node = node.return;
11990 }
11991
11992 node.sibling.return = node.return;
11993 node = node.sibling;
11994 }
11995 }
11996
11997 return false;
11998 }
11999
12000 function resolveDefaultProps(Component, baseProps) {
12001 if (Component && Component.defaultProps) {
12002 // Resolve default props. Taken from ReactElement
12003 var props = _assign({}, baseProps);
12004
12005 var defaultProps = Component.defaultProps;
12006
12007 for (var propName in defaultProps) {
12008 if (props[propName] === undefined) {
12009 props[propName] = defaultProps[propName];
12010 }
12011 }
12012
12013 return props;
12014 }
12015
12016 return baseProps;
12017 }
12018 function readLazyComponentType(lazyComponent) {
12019 initializeLazyComponentType(lazyComponent);
12020
12021 if (lazyComponent._status !== Resolved) {
12022 throw lazyComponent._result;
12023 }
12024
12025 return lazyComponent._result;
12026 }
12027
12028 var valueCursor = createCursor(null);
12029 var rendererSigil;
12030
12031 {
12032 // Use this to detect multiple renderers using the same context
12033 rendererSigil = {};
12034 }
12035
12036 var currentlyRenderingFiber = null;
12037 var lastContextDependency = null;
12038 var lastContextWithAllBitsObserved = null;
12039 var isDisallowedContextReadInDEV = false;
12040 function resetContextDependencies() {
12041 // This is called right before React yields execution, to ensure `readContext`
12042 // cannot be called outside the render phase.
12043 currentlyRenderingFiber = null;
12044 lastContextDependency = null;
12045 lastContextWithAllBitsObserved = null;
12046
12047 {
12048 isDisallowedContextReadInDEV = false;
12049 }
12050 }
12051 function enterDisallowedContextReadInDEV() {
12052 {
12053 isDisallowedContextReadInDEV = true;
12054 }
12055 }
12056 function exitDisallowedContextReadInDEV() {
12057 {
12058 isDisallowedContextReadInDEV = false;
12059 }
12060 }
12061 function pushProvider(providerFiber, nextValue) {
12062 var context = providerFiber.type._context;
12063
12064 {
12065 push(valueCursor, context._currentValue, providerFiber);
12066 context._currentValue = nextValue;
12067
12068 {
12069 if (context._currentRenderer !== undefined && context._currentRenderer !== null && context._currentRenderer !== rendererSigil) {
12070 error('Detected multiple renderers concurrently rendering the ' + 'same context provider. This is currently unsupported.');
12071 }
12072
12073 context._currentRenderer = rendererSigil;
12074 }
12075 }
12076 }
12077 function popProvider(providerFiber) {
12078 var currentValue = valueCursor.current;
12079 pop(valueCursor, providerFiber);
12080 var context = providerFiber.type._context;
12081
12082 {
12083 context._currentValue = currentValue;
12084 }
12085 }
12086 function calculateChangedBits(context, newValue, oldValue) {
12087 if (objectIs(oldValue, newValue)) {
12088 // No change
12089 return 0;
12090 } else {
12091 var changedBits = typeof context._calculateChangedBits === 'function' ? context._calculateChangedBits(oldValue, newValue) : MAX_SIGNED_31_BIT_INT;
12092
12093 {
12094 if ((changedBits & MAX_SIGNED_31_BIT_INT) !== changedBits) {
12095 error('calculateChangedBits: Expected the return value to be a ' + '31-bit integer. Instead received: %s', changedBits);
12096 }
12097 }
12098
12099 return changedBits | 0;
12100 }
12101 }
12102 function scheduleWorkOnParentPath(parent, renderExpirationTime) {
12103 // Update the child expiration time of all the ancestors, including
12104 // the alternates.
12105 var node = parent;
12106
12107 while (node !== null) {
12108 var alternate = node.alternate;
12109
12110 if (node.childExpirationTime < renderExpirationTime) {
12111 node.childExpirationTime = renderExpirationTime;
12112
12113 if (alternate !== null && alternate.childExpirationTime < renderExpirationTime) {
12114 alternate.childExpirationTime = renderExpirationTime;
12115 }
12116 } else if (alternate !== null && alternate.childExpirationTime < renderExpirationTime) {
12117 alternate.childExpirationTime = renderExpirationTime;
12118 } else {
12119 // Neither alternate was updated, which means the rest of the
12120 // ancestor path already has sufficient priority.
12121 break;
12122 }
12123
12124 node = node.return;
12125 }
12126 }
12127 function propagateContextChange(workInProgress, context, changedBits, renderExpirationTime) {
12128 var fiber = workInProgress.child;
12129
12130 if (fiber !== null) {
12131 // Set the return pointer of the child to the work-in-progress fiber.
12132 fiber.return = workInProgress;
12133 }
12134
12135 while (fiber !== null) {
12136 var nextFiber = void 0; // Visit this fiber.
12137
12138 var list = fiber.dependencies;
12139
12140 if (list !== null) {
12141 nextFiber = fiber.child;
12142 var dependency = list.firstContext;
12143
12144 while (dependency !== null) {
12145 // Check if the context matches.
12146 if (dependency.context === context && (dependency.observedBits & changedBits) !== 0) {
12147 // Match! Schedule an update on this fiber.
12148 if (fiber.tag === ClassComponent) {
12149 // Schedule a force update on the work-in-progress.
12150 var update = createUpdate(renderExpirationTime, null);
12151 update.tag = ForceUpdate; // TODO: Because we don't have a work-in-progress, this will add the
12152 // update to the current fiber, too, which means it will persist even if
12153 // this render is thrown away. Since it's a race condition, not sure it's
12154 // worth fixing.
12155
12156 enqueueUpdate(fiber, update);
12157 }
12158
12159 if (fiber.expirationTime < renderExpirationTime) {
12160 fiber.expirationTime = renderExpirationTime;
12161 }
12162
12163 var alternate = fiber.alternate;
12164
12165 if (alternate !== null && alternate.expirationTime < renderExpirationTime) {
12166 alternate.expirationTime = renderExpirationTime;
12167 }
12168
12169 scheduleWorkOnParentPath(fiber.return, renderExpirationTime); // Mark the expiration time on the list, too.
12170
12171 if (list.expirationTime < renderExpirationTime) {
12172 list.expirationTime = renderExpirationTime;
12173 } // Since we already found a match, we can stop traversing the
12174 // dependency list.
12175
12176
12177 break;
12178 }
12179
12180 dependency = dependency.next;
12181 }
12182 } else if (fiber.tag === ContextProvider) {
12183 // Don't scan deeper if this is a matching provider
12184 nextFiber = fiber.type === workInProgress.type ? null : fiber.child;
12185 } else {
12186 // Traverse down.
12187 nextFiber = fiber.child;
12188 }
12189
12190 if (nextFiber !== null) {
12191 // Set the return pointer of the child to the work-in-progress fiber.
12192 nextFiber.return = fiber;
12193 } else {
12194 // No child. Traverse to next sibling.
12195 nextFiber = fiber;
12196
12197 while (nextFiber !== null) {
12198 if (nextFiber === workInProgress) {
12199 // We're back to the root of this subtree. Exit.
12200 nextFiber = null;
12201 break;
12202 }
12203
12204 var sibling = nextFiber.sibling;
12205
12206 if (sibling !== null) {
12207 // Set the return pointer of the sibling to the work-in-progress fiber.
12208 sibling.return = nextFiber.return;
12209 nextFiber = sibling;
12210 break;
12211 } // No more siblings. Traverse up.
12212
12213
12214 nextFiber = nextFiber.return;
12215 }
12216 }
12217
12218 fiber = nextFiber;
12219 }
12220 }
12221 function prepareToReadContext(workInProgress, renderExpirationTime) {
12222 currentlyRenderingFiber = workInProgress;
12223 lastContextDependency = null;
12224 lastContextWithAllBitsObserved = null;
12225 var dependencies = workInProgress.dependencies;
12226
12227 if (dependencies !== null) {
12228 var firstContext = dependencies.firstContext;
12229
12230 if (firstContext !== null) {
12231 if (dependencies.expirationTime >= renderExpirationTime) {
12232 // Context list has a pending update. Mark that this fiber performed work.
12233 markWorkInProgressReceivedUpdate();
12234 } // Reset the work-in-progress list
12235
12236
12237 dependencies.firstContext = null;
12238 }
12239 }
12240 }
12241 function readContext(context, observedBits) {
12242 {
12243 // This warning would fire if you read context inside a Hook like useMemo.
12244 // Unlike the class check below, it's not enforced in production for perf.
12245 if (isDisallowedContextReadInDEV) {
12246 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().');
12247 }
12248 }
12249
12250 if (lastContextWithAllBitsObserved === context) ; else if (observedBits === false || observedBits === 0) ; else {
12251 var resolvedObservedBits; // Avoid deopting on observable arguments or heterogeneous types.
12252
12253 if (typeof observedBits !== 'number' || observedBits === MAX_SIGNED_31_BIT_INT) {
12254 // Observe all updates.
12255 lastContextWithAllBitsObserved = context;
12256 resolvedObservedBits = MAX_SIGNED_31_BIT_INT;
12257 } else {
12258 resolvedObservedBits = observedBits;
12259 }
12260
12261 var contextItem = {
12262 context: context,
12263 observedBits: resolvedObservedBits,
12264 next: null
12265 };
12266
12267 if (lastContextDependency === null) {
12268 if (!(currentlyRenderingFiber !== null)) {
12269 {
12270 throw 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()." );
12271 }
12272 } // This is the first dependency for this component. Create a new list.
12273
12274
12275 lastContextDependency = contextItem;
12276 currentlyRenderingFiber.dependencies = {
12277 expirationTime: NoWork,
12278 firstContext: contextItem,
12279 responders: null
12280 };
12281 } else {
12282 // Append a new context item.
12283 lastContextDependency = lastContextDependency.next = contextItem;
12284 }
12285 }
12286
12287 return context._currentValue ;
12288 }
12289
12290 var UpdateState = 0;
12291 var ReplaceState = 1;
12292 var ForceUpdate = 2;
12293 var CaptureUpdate = 3; // Global state that is reset at the beginning of calling `processUpdateQueue`.
12294 // It should only be read right after calling `processUpdateQueue`, via
12295 // `checkHasForceUpdateAfterProcessing`.
12296
12297 var hasForceUpdate = false;
12298 var didWarnUpdateInsideUpdate;
12299 var currentlyProcessingQueue;
12300
12301 {
12302 didWarnUpdateInsideUpdate = false;
12303 currentlyProcessingQueue = null;
12304 }
12305
12306 function initializeUpdateQueue(fiber) {
12307 var queue = {
12308 baseState: fiber.memoizedState,
12309 baseQueue: null,
12310 shared: {
12311 pending: null
12312 },
12313 effects: null
12314 };
12315 fiber.updateQueue = queue;
12316 }
12317 function cloneUpdateQueue(current, workInProgress) {
12318 // Clone the update queue from current. Unless it's already a clone.
12319 var queue = workInProgress.updateQueue;
12320 var currentQueue = current.updateQueue;
12321
12322 if (queue === currentQueue) {
12323 var clone = {
12324 baseState: currentQueue.baseState,
12325 baseQueue: currentQueue.baseQueue,
12326 shared: currentQueue.shared,
12327 effects: currentQueue.effects
12328 };
12329 workInProgress.updateQueue = clone;
12330 }
12331 }
12332 function createUpdate(expirationTime, suspenseConfig) {
12333 var update = {
12334 expirationTime: expirationTime,
12335 suspenseConfig: suspenseConfig,
12336 tag: UpdateState,
12337 payload: null,
12338 callback: null,
12339 next: null
12340 };
12341 update.next = update;
12342
12343 {
12344 update.priority = getCurrentPriorityLevel();
12345 }
12346
12347 return update;
12348 }
12349 function enqueueUpdate(fiber, update) {
12350 var updateQueue = fiber.updateQueue;
12351
12352 if (updateQueue === null) {
12353 // Only occurs if the fiber has been unmounted.
12354 return;
12355 }
12356
12357 var sharedQueue = updateQueue.shared;
12358 var pending = sharedQueue.pending;
12359
12360 if (pending === null) {
12361 // This is the first update. Create a circular list.
12362 update.next = update;
12363 } else {
12364 update.next = pending.next;
12365 pending.next = update;
12366 }
12367
12368 sharedQueue.pending = update;
12369
12370 {
12371 if (currentlyProcessingQueue === sharedQueue && !didWarnUpdateInsideUpdate) {
12372 error('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.');
12373
12374 didWarnUpdateInsideUpdate = true;
12375 }
12376 }
12377 }
12378 function enqueueCapturedUpdate(workInProgress, update) {
12379 var current = workInProgress.alternate;
12380
12381 if (current !== null) {
12382 // Ensure the work-in-progress queue is a clone
12383 cloneUpdateQueue(current, workInProgress);
12384 } // Captured updates go only on the work-in-progress queue.
12385
12386
12387 var queue = workInProgress.updateQueue; // Append the update to the end of the list.
12388
12389 var last = queue.baseQueue;
12390
12391 if (last === null) {
12392 queue.baseQueue = update.next = update;
12393 update.next = update;
12394 } else {
12395 update.next = last.next;
12396 last.next = update;
12397 }
12398 }
12399
12400 function getStateFromUpdate(workInProgress, queue, update, prevState, nextProps, instance) {
12401 switch (update.tag) {
12402 case ReplaceState:
12403 {
12404 var payload = update.payload;
12405
12406 if (typeof payload === 'function') {
12407 // Updater function
12408 {
12409 enterDisallowedContextReadInDEV();
12410
12411 if ( workInProgress.mode & StrictMode) {
12412 payload.call(instance, prevState, nextProps);
12413 }
12414 }
12415
12416 var nextState = payload.call(instance, prevState, nextProps);
12417
12418 {
12419 exitDisallowedContextReadInDEV();
12420 }
12421
12422 return nextState;
12423 } // State object
12424
12425
12426 return payload;
12427 }
12428
12429 case CaptureUpdate:
12430 {
12431 workInProgress.effectTag = workInProgress.effectTag & ~ShouldCapture | DidCapture;
12432 }
12433 // Intentional fallthrough
12434
12435 case UpdateState:
12436 {
12437 var _payload = update.payload;
12438 var partialState;
12439
12440 if (typeof _payload === 'function') {
12441 // Updater function
12442 {
12443 enterDisallowedContextReadInDEV();
12444
12445 if ( workInProgress.mode & StrictMode) {
12446 _payload.call(instance, prevState, nextProps);
12447 }
12448 }
12449
12450 partialState = _payload.call(instance, prevState, nextProps);
12451
12452 {
12453 exitDisallowedContextReadInDEV();
12454 }
12455 } else {
12456 // Partial state object
12457 partialState = _payload;
12458 }
12459
12460 if (partialState === null || partialState === undefined) {
12461 // Null and undefined are treated as no-ops.
12462 return prevState;
12463 } // Merge the partial state and the previous state.
12464
12465
12466 return _assign({}, prevState, partialState);
12467 }
12468
12469 case ForceUpdate:
12470 {
12471 hasForceUpdate = true;
12472 return prevState;
12473 }
12474 }
12475
12476 return prevState;
12477 }
12478
12479 function processUpdateQueue(workInProgress, props, instance, renderExpirationTime) {
12480 // This is always non-null on a ClassComponent or HostRoot
12481 var queue = workInProgress.updateQueue;
12482 hasForceUpdate = false;
12483
12484 {
12485 currentlyProcessingQueue = queue.shared;
12486 } // The last rebase update that is NOT part of the base state.
12487
12488
12489 var baseQueue = queue.baseQueue; // The last pending update that hasn't been processed yet.
12490
12491 var pendingQueue = queue.shared.pending;
12492
12493 if (pendingQueue !== null) {
12494 // We have new updates that haven't been processed yet.
12495 // We'll add them to the base queue.
12496 if (baseQueue !== null) {
12497 // Merge the pending queue and the base queue.
12498 var baseFirst = baseQueue.next;
12499 var pendingFirst = pendingQueue.next;
12500 baseQueue.next = pendingFirst;
12501 pendingQueue.next = baseFirst;
12502 }
12503
12504 baseQueue = pendingQueue;
12505 queue.shared.pending = null; // TODO: Pass `current` as argument
12506
12507 var current = workInProgress.alternate;
12508
12509 if (current !== null) {
12510 var currentQueue = current.updateQueue;
12511
12512 if (currentQueue !== null) {
12513 currentQueue.baseQueue = pendingQueue;
12514 }
12515 }
12516 } // These values may change as we process the queue.
12517
12518
12519 if (baseQueue !== null) {
12520 var first = baseQueue.next; // Iterate through the list of updates to compute the result.
12521
12522 var newState = queue.baseState;
12523 var newExpirationTime = NoWork;
12524 var newBaseState = null;
12525 var newBaseQueueFirst = null;
12526 var newBaseQueueLast = null;
12527
12528 if (first !== null) {
12529 var update = first;
12530
12531 do {
12532 var updateExpirationTime = update.expirationTime;
12533
12534 if (updateExpirationTime < renderExpirationTime) {
12535 // Priority is insufficient. Skip this update. If this is the first
12536 // skipped update, the previous update/state is the new base
12537 // update/state.
12538 var clone = {
12539 expirationTime: update.expirationTime,
12540 suspenseConfig: update.suspenseConfig,
12541 tag: update.tag,
12542 payload: update.payload,
12543 callback: update.callback,
12544 next: null
12545 };
12546
12547 if (newBaseQueueLast === null) {
12548 newBaseQueueFirst = newBaseQueueLast = clone;
12549 newBaseState = newState;
12550 } else {
12551 newBaseQueueLast = newBaseQueueLast.next = clone;
12552 } // Update the remaining priority in the queue.
12553
12554
12555 if (updateExpirationTime > newExpirationTime) {
12556 newExpirationTime = updateExpirationTime;
12557 }
12558 } else {
12559 // This update does have sufficient priority.
12560 if (newBaseQueueLast !== null) {
12561 var _clone = {
12562 expirationTime: Sync,
12563 // This update is going to be committed so we never want uncommit it.
12564 suspenseConfig: update.suspenseConfig,
12565 tag: update.tag,
12566 payload: update.payload,
12567 callback: update.callback,
12568 next: null
12569 };
12570 newBaseQueueLast = newBaseQueueLast.next = _clone;
12571 } // Mark the event time of this update as relevant to this render pass.
12572 // TODO: This should ideally use the true event time of this update rather than
12573 // its priority which is a derived and not reverseable value.
12574 // TODO: We should skip this update if it was already committed but currently
12575 // we have no way of detecting the difference between a committed and suspended
12576 // update here.
12577
12578
12579 markRenderEventTimeAndConfig(updateExpirationTime, update.suspenseConfig); // Process this update.
12580
12581 newState = getStateFromUpdate(workInProgress, queue, update, newState, props, instance);
12582 var callback = update.callback;
12583
12584 if (callback !== null) {
12585 workInProgress.effectTag |= Callback;
12586 var effects = queue.effects;
12587
12588 if (effects === null) {
12589 queue.effects = [update];
12590 } else {
12591 effects.push(update);
12592 }
12593 }
12594 }
12595
12596 update = update.next;
12597
12598 if (update === null || update === first) {
12599 pendingQueue = queue.shared.pending;
12600
12601 if (pendingQueue === null) {
12602 break;
12603 } else {
12604 // An update was scheduled from inside a reducer. Add the new
12605 // pending updates to the end of the list and keep processing.
12606 update = baseQueue.next = pendingQueue.next;
12607 pendingQueue.next = first;
12608 queue.baseQueue = baseQueue = pendingQueue;
12609 queue.shared.pending = null;
12610 }
12611 }
12612 } while (true);
12613 }
12614
12615 if (newBaseQueueLast === null) {
12616 newBaseState = newState;
12617 } else {
12618 newBaseQueueLast.next = newBaseQueueFirst;
12619 }
12620
12621 queue.baseState = newBaseState;
12622 queue.baseQueue = newBaseQueueLast; // Set the remaining expiration time to be whatever is remaining in the queue.
12623 // This should be fine because the only two other things that contribute to
12624 // expiration time are props and context. We're already in the middle of the
12625 // begin phase by the time we start processing the queue, so we've already
12626 // dealt with the props. Context in components that specify
12627 // shouldComponentUpdate is tricky; but we'll have to account for
12628 // that regardless.
12629
12630 markUnprocessedUpdateTime(newExpirationTime);
12631 workInProgress.expirationTime = newExpirationTime;
12632 workInProgress.memoizedState = newState;
12633 }
12634
12635 {
12636 currentlyProcessingQueue = null;
12637 }
12638 }
12639
12640 function callCallback(callback, context) {
12641 if (!(typeof callback === 'function')) {
12642 {
12643 throw Error( "Invalid argument passed as callback. Expected a function. Instead received: " + callback );
12644 }
12645 }
12646
12647 callback.call(context);
12648 }
12649
12650 function resetHasForceUpdateBeforeProcessing() {
12651 hasForceUpdate = false;
12652 }
12653 function checkHasForceUpdateAfterProcessing() {
12654 return hasForceUpdate;
12655 }
12656 function commitUpdateQueue(finishedWork, finishedQueue, instance) {
12657 // Commit the effects
12658 var effects = finishedQueue.effects;
12659 finishedQueue.effects = null;
12660
12661 if (effects !== null) {
12662 for (var i = 0; i < effects.length; i++) {
12663 var effect = effects[i];
12664 var callback = effect.callback;
12665
12666 if (callback !== null) {
12667 effect.callback = null;
12668 callCallback(callback, instance);
12669 }
12670 }
12671 }
12672 }
12673
12674 var ReactCurrentBatchConfig = ReactSharedInternals.ReactCurrentBatchConfig;
12675 function requestCurrentSuspenseConfig() {
12676 return ReactCurrentBatchConfig.suspense;
12677 }
12678
12679 var fakeInternalInstance = {};
12680 var isArray = Array.isArray; // React.Component uses a shared frozen object by default.
12681 // We'll use it to determine whether we need to initialize legacy refs.
12682
12683 var emptyRefsObject = new React.Component().refs;
12684 var didWarnAboutStateAssignmentForComponent;
12685 var didWarnAboutUninitializedState;
12686 var didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate;
12687 var didWarnAboutLegacyLifecyclesAndDerivedState;
12688 var didWarnAboutUndefinedDerivedState;
12689 var warnOnUndefinedDerivedState;
12690 var warnOnInvalidCallback;
12691 var didWarnAboutDirectlyAssigningPropsToState;
12692 var didWarnAboutContextTypeAndContextTypes;
12693 var didWarnAboutInvalidateContextType;
12694
12695 {
12696 didWarnAboutStateAssignmentForComponent = new Set();
12697 didWarnAboutUninitializedState = new Set();
12698 didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate = new Set();
12699 didWarnAboutLegacyLifecyclesAndDerivedState = new Set();
12700 didWarnAboutDirectlyAssigningPropsToState = new Set();
12701 didWarnAboutUndefinedDerivedState = new Set();
12702 didWarnAboutContextTypeAndContextTypes = new Set();
12703 didWarnAboutInvalidateContextType = new Set();
12704 var didWarnOnInvalidCallback = new Set();
12705
12706 warnOnInvalidCallback = function (callback, callerName) {
12707 if (callback === null || typeof callback === 'function') {
12708 return;
12709 }
12710
12711 var key = callerName + "_" + callback;
12712
12713 if (!didWarnOnInvalidCallback.has(key)) {
12714 didWarnOnInvalidCallback.add(key);
12715
12716 error('%s(...): Expected the last optional `callback` argument to be a ' + 'function. Instead received: %s.', callerName, callback);
12717 }
12718 };
12719
12720 warnOnUndefinedDerivedState = function (type, partialState) {
12721 if (partialState === undefined) {
12722 var componentName = getComponentName(type) || 'Component';
12723
12724 if (!didWarnAboutUndefinedDerivedState.has(componentName)) {
12725 didWarnAboutUndefinedDerivedState.add(componentName);
12726
12727 error('%s.getDerivedStateFromProps(): A valid state object (or null) must be returned. ' + 'You have returned undefined.', componentName);
12728 }
12729 }
12730 }; // This is so gross but it's at least non-critical and can be removed if
12731 // it causes problems. This is meant to give a nicer error message for
12732 // ReactDOM15.unstable_renderSubtreeIntoContainer(reactDOM16Component,
12733 // ...)) which otherwise throws a "_processChildContext is not a function"
12734 // exception.
12735
12736
12737 Object.defineProperty(fakeInternalInstance, '_processChildContext', {
12738 enumerable: false,
12739 value: function () {
12740 {
12741 {
12742 throw 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)." );
12743 }
12744 }
12745 }
12746 });
12747 Object.freeze(fakeInternalInstance);
12748 }
12749
12750 function applyDerivedStateFromProps(workInProgress, ctor, getDerivedStateFromProps, nextProps) {
12751 var prevState = workInProgress.memoizedState;
12752
12753 {
12754 if ( workInProgress.mode & StrictMode) {
12755 // Invoke the function an extra time to help detect side-effects.
12756 getDerivedStateFromProps(nextProps, prevState);
12757 }
12758 }
12759
12760 var partialState = getDerivedStateFromProps(nextProps, prevState);
12761
12762 {
12763 warnOnUndefinedDerivedState(ctor, partialState);
12764 } // Merge the partial state and the previous state.
12765
12766
12767 var memoizedState = partialState === null || partialState === undefined ? prevState : _assign({}, prevState, partialState);
12768 workInProgress.memoizedState = memoizedState; // Once the update queue is empty, persist the derived state onto the
12769 // base state.
12770
12771 if (workInProgress.expirationTime === NoWork) {
12772 // Queue is always non-null for classes
12773 var updateQueue = workInProgress.updateQueue;
12774 updateQueue.baseState = memoizedState;
12775 }
12776 }
12777 var classComponentUpdater = {
12778 isMounted: isMounted,
12779 enqueueSetState: function (inst, payload, callback) {
12780 var fiber = get(inst);
12781 var currentTime = requestCurrentTimeForUpdate();
12782 var suspenseConfig = requestCurrentSuspenseConfig();
12783 var expirationTime = computeExpirationForFiber(currentTime, fiber, suspenseConfig);
12784 var update = createUpdate(expirationTime, suspenseConfig);
12785 update.payload = payload;
12786
12787 if (callback !== undefined && callback !== null) {
12788 {
12789 warnOnInvalidCallback(callback, 'setState');
12790 }
12791
12792 update.callback = callback;
12793 }
12794
12795 enqueueUpdate(fiber, update);
12796 scheduleWork(fiber, expirationTime);
12797 },
12798 enqueueReplaceState: function (inst, payload, callback) {
12799 var fiber = get(inst);
12800 var currentTime = requestCurrentTimeForUpdate();
12801 var suspenseConfig = requestCurrentSuspenseConfig();
12802 var expirationTime = computeExpirationForFiber(currentTime, fiber, suspenseConfig);
12803 var update = createUpdate(expirationTime, suspenseConfig);
12804 update.tag = ReplaceState;
12805 update.payload = payload;
12806
12807 if (callback !== undefined && callback !== null) {
12808 {
12809 warnOnInvalidCallback(callback, 'replaceState');
12810 }
12811
12812 update.callback = callback;
12813 }
12814
12815 enqueueUpdate(fiber, update);
12816 scheduleWork(fiber, expirationTime);
12817 },
12818 enqueueForceUpdate: function (inst, callback) {
12819 var fiber = get(inst);
12820 var currentTime = requestCurrentTimeForUpdate();
12821 var suspenseConfig = requestCurrentSuspenseConfig();
12822 var expirationTime = computeExpirationForFiber(currentTime, fiber, suspenseConfig);
12823 var update = createUpdate(expirationTime, suspenseConfig);
12824 update.tag = ForceUpdate;
12825
12826 if (callback !== undefined && callback !== null) {
12827 {
12828 warnOnInvalidCallback(callback, 'forceUpdate');
12829 }
12830
12831 update.callback = callback;
12832 }
12833
12834 enqueueUpdate(fiber, update);
12835 scheduleWork(fiber, expirationTime);
12836 }
12837 };
12838
12839 function checkShouldComponentUpdate(workInProgress, ctor, oldProps, newProps, oldState, newState, nextContext) {
12840 var instance = workInProgress.stateNode;
12841
12842 if (typeof instance.shouldComponentUpdate === 'function') {
12843 {
12844 if ( workInProgress.mode & StrictMode) {
12845 // Invoke the function an extra time to help detect side-effects.
12846 instance.shouldComponentUpdate(newProps, newState, nextContext);
12847 }
12848 }
12849
12850 startPhaseTimer(workInProgress, 'shouldComponentUpdate');
12851 var shouldUpdate = instance.shouldComponentUpdate(newProps, newState, nextContext);
12852 stopPhaseTimer();
12853
12854 {
12855 if (shouldUpdate === undefined) {
12856 error('%s.shouldComponentUpdate(): Returned undefined instead of a ' + 'boolean value. Make sure to return true or false.', getComponentName(ctor) || 'Component');
12857 }
12858 }
12859
12860 return shouldUpdate;
12861 }
12862
12863 if (ctor.prototype && ctor.prototype.isPureReactComponent) {
12864 return !shallowEqual(oldProps, newProps) || !shallowEqual(oldState, newState);
12865 }
12866
12867 return true;
12868 }
12869
12870 function checkClassInstance(workInProgress, ctor, newProps) {
12871 var instance = workInProgress.stateNode;
12872
12873 {
12874 var name = getComponentName(ctor) || 'Component';
12875 var renderPresent = instance.render;
12876
12877 if (!renderPresent) {
12878 if (ctor.prototype && typeof ctor.prototype.render === 'function') {
12879 error('%s(...): No `render` method found on the returned component ' + 'instance: did you accidentally return an object from the constructor?', name);
12880 } else {
12881 error('%s(...): No `render` method found on the returned component ' + 'instance: you may have forgotten to define `render`.', name);
12882 }
12883 }
12884
12885 if (instance.getInitialState && !instance.getInitialState.isReactClassApproved && !instance.state) {
12886 error('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);
12887 }
12888
12889 if (instance.getDefaultProps && !instance.getDefaultProps.isReactClassApproved) {
12890 error('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);
12891 }
12892
12893 if (instance.propTypes) {
12894 error('propTypes was defined as an instance property on %s. Use a static ' + 'property to define propTypes instead.', name);
12895 }
12896
12897 if (instance.contextType) {
12898 error('contextType was defined as an instance property on %s. Use a static ' + 'property to define contextType instead.', name);
12899 }
12900
12901 {
12902 if (instance.contextTypes) {
12903 error('contextTypes was defined as an instance property on %s. Use a static ' + 'property to define contextTypes instead.', name);
12904 }
12905
12906 if (ctor.contextType && ctor.contextTypes && !didWarnAboutContextTypeAndContextTypes.has(ctor)) {
12907 didWarnAboutContextTypeAndContextTypes.add(ctor);
12908
12909 error('%s declares both contextTypes and contextType static properties. ' + 'The legacy contextTypes property will be ignored.', name);
12910 }
12911 }
12912
12913 if (typeof instance.componentShouldUpdate === 'function') {
12914 error('%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);
12915 }
12916
12917 if (ctor.prototype && ctor.prototype.isPureReactComponent && typeof instance.shouldComponentUpdate !== 'undefined') {
12918 error('%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');
12919 }
12920
12921 if (typeof instance.componentDidUnmount === 'function') {
12922 error('%s has a method called ' + 'componentDidUnmount(). But there is no such lifecycle method. ' + 'Did you mean componentWillUnmount()?', name);
12923 }
12924
12925 if (typeof instance.componentDidReceiveProps === 'function') {
12926 error('%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);
12927 }
12928
12929 if (typeof instance.componentWillRecieveProps === 'function') {
12930 error('%s has a method called ' + 'componentWillRecieveProps(). Did you mean componentWillReceiveProps()?', name);
12931 }
12932
12933 if (typeof instance.UNSAFE_componentWillRecieveProps === 'function') {
12934 error('%s has a method called ' + 'UNSAFE_componentWillRecieveProps(). Did you mean UNSAFE_componentWillReceiveProps()?', name);
12935 }
12936
12937 var hasMutatedProps = instance.props !== newProps;
12938
12939 if (instance.props !== undefined && hasMutatedProps) {
12940 error('%s(...): When calling super() in `%s`, make sure to pass ' + "up the same props that your component's constructor was passed.", name, name);
12941 }
12942
12943 if (instance.defaultProps) {
12944 error('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);
12945 }
12946
12947 if (typeof instance.getSnapshotBeforeUpdate === 'function' && typeof instance.componentDidUpdate !== 'function' && !didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate.has(ctor)) {
12948 didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate.add(ctor);
12949
12950 error('%s: getSnapshotBeforeUpdate() should be used with componentDidUpdate(). ' + 'This component defines getSnapshotBeforeUpdate() only.', getComponentName(ctor));
12951 }
12952
12953 if (typeof instance.getDerivedStateFromProps === 'function') {
12954 error('%s: getDerivedStateFromProps() is defined as an instance method ' + 'and will be ignored. Instead, declare it as a static method.', name);
12955 }
12956
12957 if (typeof instance.getDerivedStateFromError === 'function') {
12958 error('%s: getDerivedStateFromError() is defined as an instance method ' + 'and will be ignored. Instead, declare it as a static method.', name);
12959 }
12960
12961 if (typeof ctor.getSnapshotBeforeUpdate === 'function') {
12962 error('%s: getSnapshotBeforeUpdate() is defined as a static method ' + 'and will be ignored. Instead, declare it as an instance method.', name);
12963 }
12964
12965 var _state = instance.state;
12966
12967 if (_state && (typeof _state !== 'object' || isArray(_state))) {
12968 error('%s.state: must be set to an object or null', name);
12969 }
12970
12971 if (typeof instance.getChildContext === 'function' && typeof ctor.childContextTypes !== 'object') {
12972 error('%s.getChildContext(): childContextTypes must be defined in order to ' + 'use getChildContext().', name);
12973 }
12974 }
12975 }
12976
12977 function adoptClassInstance(workInProgress, instance) {
12978 instance.updater = classComponentUpdater;
12979 workInProgress.stateNode = instance; // The instance needs access to the fiber so that it can schedule updates
12980
12981 set(instance, workInProgress);
12982
12983 {
12984 instance._reactInternalInstance = fakeInternalInstance;
12985 }
12986 }
12987
12988 function constructClassInstance(workInProgress, ctor, props) {
12989 var isLegacyContextConsumer = false;
12990 var unmaskedContext = emptyContextObject;
12991 var context = emptyContextObject;
12992 var contextType = ctor.contextType;
12993
12994 {
12995 if ('contextType' in ctor) {
12996 var isValid = // Allow null for conditional declaration
12997 contextType === null || contextType !== undefined && contextType.$$typeof === REACT_CONTEXT_TYPE && contextType._context === undefined; // Not a <Context.Consumer>
12998
12999 if (!isValid && !didWarnAboutInvalidateContextType.has(ctor)) {
13000 didWarnAboutInvalidateContextType.add(ctor);
13001 var addendum = '';
13002
13003 if (contextType === undefined) {
13004 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.';
13005 } else if (typeof contextType !== 'object') {
13006 addendum = ' However, it is set to a ' + typeof contextType + '.';
13007 } else if (contextType.$$typeof === REACT_PROVIDER_TYPE) {
13008 addendum = ' Did you accidentally pass the Context.Provider instead?';
13009 } else if (contextType._context !== undefined) {
13010 // <Context.Consumer>
13011 addendum = ' Did you accidentally pass the Context.Consumer instead?';
13012 } else {
13013 addendum = ' However, it is set to an object with keys {' + Object.keys(contextType).join(', ') + '}.';
13014 }
13015
13016 error('%s defines an invalid contextType. ' + 'contextType should point to the Context object returned by React.createContext().%s', getComponentName(ctor) || 'Component', addendum);
13017 }
13018 }
13019 }
13020
13021 if (typeof contextType === 'object' && contextType !== null) {
13022 context = readContext(contextType);
13023 } else {
13024 unmaskedContext = getUnmaskedContext(workInProgress, ctor, true);
13025 var contextTypes = ctor.contextTypes;
13026 isLegacyContextConsumer = contextTypes !== null && contextTypes !== undefined;
13027 context = isLegacyContextConsumer ? getMaskedContext(workInProgress, unmaskedContext) : emptyContextObject;
13028 } // Instantiate twice to help detect side-effects.
13029
13030
13031 {
13032 if ( workInProgress.mode & StrictMode) {
13033 new ctor(props, context); // eslint-disable-line no-new
13034 }
13035 }
13036
13037 var instance = new ctor(props, context);
13038 var state = workInProgress.memoizedState = instance.state !== null && instance.state !== undefined ? instance.state : null;
13039 adoptClassInstance(workInProgress, instance);
13040
13041 {
13042 if (typeof ctor.getDerivedStateFromProps === 'function' && state === null) {
13043 var componentName = getComponentName(ctor) || 'Component';
13044
13045 if (!didWarnAboutUninitializedState.has(componentName)) {
13046 didWarnAboutUninitializedState.add(componentName);
13047
13048 error('`%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);
13049 }
13050 } // If new component APIs are defined, "unsafe" lifecycles won't be called.
13051 // Warn about these lifecycles if they are present.
13052 // Don't warn about react-lifecycles-compat polyfilled methods though.
13053
13054
13055 if (typeof ctor.getDerivedStateFromProps === 'function' || typeof instance.getSnapshotBeforeUpdate === 'function') {
13056 var foundWillMountName = null;
13057 var foundWillReceivePropsName = null;
13058 var foundWillUpdateName = null;
13059
13060 if (typeof instance.componentWillMount === 'function' && instance.componentWillMount.__suppressDeprecationWarning !== true) {
13061 foundWillMountName = 'componentWillMount';
13062 } else if (typeof instance.UNSAFE_componentWillMount === 'function') {
13063 foundWillMountName = 'UNSAFE_componentWillMount';
13064 }
13065
13066 if (typeof instance.componentWillReceiveProps === 'function' && instance.componentWillReceiveProps.__suppressDeprecationWarning !== true) {
13067 foundWillReceivePropsName = 'componentWillReceiveProps';
13068 } else if (typeof instance.UNSAFE_componentWillReceiveProps === 'function') {
13069 foundWillReceivePropsName = 'UNSAFE_componentWillReceiveProps';
13070 }
13071
13072 if (typeof instance.componentWillUpdate === 'function' && instance.componentWillUpdate.__suppressDeprecationWarning !== true) {
13073 foundWillUpdateName = 'componentWillUpdate';
13074 } else if (typeof instance.UNSAFE_componentWillUpdate === 'function') {
13075 foundWillUpdateName = 'UNSAFE_componentWillUpdate';
13076 }
13077
13078 if (foundWillMountName !== null || foundWillReceivePropsName !== null || foundWillUpdateName !== null) {
13079 var _componentName = getComponentName(ctor) || 'Component';
13080
13081 var newApiName = typeof ctor.getDerivedStateFromProps === 'function' ? 'getDerivedStateFromProps()' : 'getSnapshotBeforeUpdate()';
13082
13083 if (!didWarnAboutLegacyLifecyclesAndDerivedState.has(_componentName)) {
13084 didWarnAboutLegacyLifecyclesAndDerivedState.add(_componentName);
13085
13086 error('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-unsafe-component-lifecycles', _componentName, newApiName, foundWillMountName !== null ? "\n " + foundWillMountName : '', foundWillReceivePropsName !== null ? "\n " + foundWillReceivePropsName : '', foundWillUpdateName !== null ? "\n " + foundWillUpdateName : '');
13087 }
13088 }
13089 }
13090 } // Cache unmasked context so we can avoid recreating masked context unless necessary.
13091 // ReactFiberContext usually updates this cache but can't for newly-created instances.
13092
13093
13094 if (isLegacyContextConsumer) {
13095 cacheContext(workInProgress, unmaskedContext, context);
13096 }
13097
13098 return instance;
13099 }
13100
13101 function callComponentWillMount(workInProgress, instance) {
13102 startPhaseTimer(workInProgress, 'componentWillMount');
13103 var oldState = instance.state;
13104
13105 if (typeof instance.componentWillMount === 'function') {
13106 instance.componentWillMount();
13107 }
13108
13109 if (typeof instance.UNSAFE_componentWillMount === 'function') {
13110 instance.UNSAFE_componentWillMount();
13111 }
13112
13113 stopPhaseTimer();
13114
13115 if (oldState !== instance.state) {
13116 {
13117 error('%s.componentWillMount(): Assigning directly to this.state is ' + "deprecated (except inside a component's " + 'constructor). Use setState instead.', getComponentName(workInProgress.type) || 'Component');
13118 }
13119
13120 classComponentUpdater.enqueueReplaceState(instance, instance.state, null);
13121 }
13122 }
13123
13124 function callComponentWillReceiveProps(workInProgress, instance, newProps, nextContext) {
13125 var oldState = instance.state;
13126 startPhaseTimer(workInProgress, 'componentWillReceiveProps');
13127
13128 if (typeof instance.componentWillReceiveProps === 'function') {
13129 instance.componentWillReceiveProps(newProps, nextContext);
13130 }
13131
13132 if (typeof instance.UNSAFE_componentWillReceiveProps === 'function') {
13133 instance.UNSAFE_componentWillReceiveProps(newProps, nextContext);
13134 }
13135
13136 stopPhaseTimer();
13137
13138 if (instance.state !== oldState) {
13139 {
13140 var componentName = getComponentName(workInProgress.type) || 'Component';
13141
13142 if (!didWarnAboutStateAssignmentForComponent.has(componentName)) {
13143 didWarnAboutStateAssignmentForComponent.add(componentName);
13144
13145 error('%s.componentWillReceiveProps(): Assigning directly to ' + "this.state is deprecated (except inside a component's " + 'constructor). Use setState instead.', componentName);
13146 }
13147 }
13148
13149 classComponentUpdater.enqueueReplaceState(instance, instance.state, null);
13150 }
13151 } // Invokes the mount life-cycles on a previously never rendered instance.
13152
13153
13154 function mountClassInstance(workInProgress, ctor, newProps, renderExpirationTime) {
13155 {
13156 checkClassInstance(workInProgress, ctor, newProps);
13157 }
13158
13159 var instance = workInProgress.stateNode;
13160 instance.props = newProps;
13161 instance.state = workInProgress.memoizedState;
13162 instance.refs = emptyRefsObject;
13163 initializeUpdateQueue(workInProgress);
13164 var contextType = ctor.contextType;
13165
13166 if (typeof contextType === 'object' && contextType !== null) {
13167 instance.context = readContext(contextType);
13168 } else {
13169 var unmaskedContext = getUnmaskedContext(workInProgress, ctor, true);
13170 instance.context = getMaskedContext(workInProgress, unmaskedContext);
13171 }
13172
13173 {
13174 if (instance.state === newProps) {
13175 var componentName = getComponentName(ctor) || 'Component';
13176
13177 if (!didWarnAboutDirectlyAssigningPropsToState.has(componentName)) {
13178 didWarnAboutDirectlyAssigningPropsToState.add(componentName);
13179
13180 error('%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);
13181 }
13182 }
13183
13184 if (workInProgress.mode & StrictMode) {
13185 ReactStrictModeWarnings.recordLegacyContextWarning(workInProgress, instance);
13186 }
13187
13188 {
13189 ReactStrictModeWarnings.recordUnsafeLifecycleWarnings(workInProgress, instance);
13190 }
13191 }
13192
13193 processUpdateQueue(workInProgress, newProps, instance, renderExpirationTime);
13194 instance.state = workInProgress.memoizedState;
13195 var getDerivedStateFromProps = ctor.getDerivedStateFromProps;
13196
13197 if (typeof getDerivedStateFromProps === 'function') {
13198 applyDerivedStateFromProps(workInProgress, ctor, getDerivedStateFromProps, newProps);
13199 instance.state = workInProgress.memoizedState;
13200 } // In order to support react-lifecycles-compat polyfilled components,
13201 // Unsafe lifecycles should not be invoked for components using the new APIs.
13202
13203
13204 if (typeof ctor.getDerivedStateFromProps !== 'function' && typeof instance.getSnapshotBeforeUpdate !== 'function' && (typeof instance.UNSAFE_componentWillMount === 'function' || typeof instance.componentWillMount === 'function')) {
13205 callComponentWillMount(workInProgress, instance); // If we had additional state updates during this life-cycle, let's
13206 // process them now.
13207
13208 processUpdateQueue(workInProgress, newProps, instance, renderExpirationTime);
13209 instance.state = workInProgress.memoizedState;
13210 }
13211
13212 if (typeof instance.componentDidMount === 'function') {
13213 workInProgress.effectTag |= Update;
13214 }
13215 }
13216
13217 function resumeMountClassInstance(workInProgress, ctor, newProps, renderExpirationTime) {
13218 var instance = workInProgress.stateNode;
13219 var oldProps = workInProgress.memoizedProps;
13220 instance.props = oldProps;
13221 var oldContext = instance.context;
13222 var contextType = ctor.contextType;
13223 var nextContext = emptyContextObject;
13224
13225 if (typeof contextType === 'object' && contextType !== null) {
13226 nextContext = readContext(contextType);
13227 } else {
13228 var nextLegacyUnmaskedContext = getUnmaskedContext(workInProgress, ctor, true);
13229 nextContext = getMaskedContext(workInProgress, nextLegacyUnmaskedContext);
13230 }
13231
13232 var getDerivedStateFromProps = ctor.getDerivedStateFromProps;
13233 var hasNewLifecycles = typeof getDerivedStateFromProps === 'function' || typeof instance.getSnapshotBeforeUpdate === 'function'; // Note: During these life-cycles, instance.props/instance.state are what
13234 // ever the previously attempted to render - not the "current". However,
13235 // during componentDidUpdate we pass the "current" props.
13236 // In order to support react-lifecycles-compat polyfilled components,
13237 // Unsafe lifecycles should not be invoked for components using the new APIs.
13238
13239 if (!hasNewLifecycles && (typeof instance.UNSAFE_componentWillReceiveProps === 'function' || typeof instance.componentWillReceiveProps === 'function')) {
13240 if (oldProps !== newProps || oldContext !== nextContext) {
13241 callComponentWillReceiveProps(workInProgress, instance, newProps, nextContext);
13242 }
13243 }
13244
13245 resetHasForceUpdateBeforeProcessing();
13246 var oldState = workInProgress.memoizedState;
13247 var newState = instance.state = oldState;
13248 processUpdateQueue(workInProgress, newProps, instance, renderExpirationTime);
13249 newState = workInProgress.memoizedState;
13250
13251 if (oldProps === newProps && oldState === newState && !hasContextChanged() && !checkHasForceUpdateAfterProcessing()) {
13252 // If an update was already in progress, we should schedule an Update
13253 // effect even though we're bailing out, so that cWU/cDU are called.
13254 if (typeof instance.componentDidMount === 'function') {
13255 workInProgress.effectTag |= Update;
13256 }
13257
13258 return false;
13259 }
13260
13261 if (typeof getDerivedStateFromProps === 'function') {
13262 applyDerivedStateFromProps(workInProgress, ctor, getDerivedStateFromProps, newProps);
13263 newState = workInProgress.memoizedState;
13264 }
13265
13266 var shouldUpdate = checkHasForceUpdateAfterProcessing() || checkShouldComponentUpdate(workInProgress, ctor, oldProps, newProps, oldState, newState, nextContext);
13267
13268 if (shouldUpdate) {
13269 // In order to support react-lifecycles-compat polyfilled components,
13270 // Unsafe lifecycles should not be invoked for components using the new APIs.
13271 if (!hasNewLifecycles && (typeof instance.UNSAFE_componentWillMount === 'function' || typeof instance.componentWillMount === 'function')) {
13272 startPhaseTimer(workInProgress, 'componentWillMount');
13273
13274 if (typeof instance.componentWillMount === 'function') {
13275 instance.componentWillMount();
13276 }
13277
13278 if (typeof instance.UNSAFE_componentWillMount === 'function') {
13279 instance.UNSAFE_componentWillMount();
13280 }
13281
13282 stopPhaseTimer();
13283 }
13284
13285 if (typeof instance.componentDidMount === 'function') {
13286 workInProgress.effectTag |= Update;
13287 }
13288 } else {
13289 // If an update was already in progress, we should schedule an Update
13290 // effect even though we're bailing out, so that cWU/cDU are called.
13291 if (typeof instance.componentDidMount === 'function') {
13292 workInProgress.effectTag |= Update;
13293 } // If shouldComponentUpdate returned false, we should still update the
13294 // memoized state to indicate that this work can be reused.
13295
13296
13297 workInProgress.memoizedProps = newProps;
13298 workInProgress.memoizedState = newState;
13299 } // Update the existing instance's state, props, and context pointers even
13300 // if shouldComponentUpdate returns false.
13301
13302
13303 instance.props = newProps;
13304 instance.state = newState;
13305 instance.context = nextContext;
13306 return shouldUpdate;
13307 } // Invokes the update life-cycles and returns false if it shouldn't rerender.
13308
13309
13310 function updateClassInstance(current, workInProgress, ctor, newProps, renderExpirationTime) {
13311 var instance = workInProgress.stateNode;
13312 cloneUpdateQueue(current, workInProgress);
13313 var oldProps = workInProgress.memoizedProps;
13314 instance.props = workInProgress.type === workInProgress.elementType ? oldProps : resolveDefaultProps(workInProgress.type, oldProps);
13315 var oldContext = instance.context;
13316 var contextType = ctor.contextType;
13317 var nextContext = emptyContextObject;
13318
13319 if (typeof contextType === 'object' && contextType !== null) {
13320 nextContext = readContext(contextType);
13321 } else {
13322 var nextUnmaskedContext = getUnmaskedContext(workInProgress, ctor, true);
13323 nextContext = getMaskedContext(workInProgress, nextUnmaskedContext);
13324 }
13325
13326 var getDerivedStateFromProps = ctor.getDerivedStateFromProps;
13327 var hasNewLifecycles = typeof getDerivedStateFromProps === 'function' || typeof instance.getSnapshotBeforeUpdate === 'function'; // Note: During these life-cycles, instance.props/instance.state are what
13328 // ever the previously attempted to render - not the "current". However,
13329 // during componentDidUpdate we pass the "current" props.
13330 // In order to support react-lifecycles-compat polyfilled components,
13331 // Unsafe lifecycles should not be invoked for components using the new APIs.
13332
13333 if (!hasNewLifecycles && (typeof instance.UNSAFE_componentWillReceiveProps === 'function' || typeof instance.componentWillReceiveProps === 'function')) {
13334 if (oldProps !== newProps || oldContext !== nextContext) {
13335 callComponentWillReceiveProps(workInProgress, instance, newProps, nextContext);
13336 }
13337 }
13338
13339 resetHasForceUpdateBeforeProcessing();
13340 var oldState = workInProgress.memoizedState;
13341 var newState = instance.state = oldState;
13342 processUpdateQueue(workInProgress, newProps, instance, renderExpirationTime);
13343 newState = workInProgress.memoizedState;
13344
13345 if (oldProps === newProps && oldState === newState && !hasContextChanged() && !checkHasForceUpdateAfterProcessing()) {
13346 // If an update was already in progress, we should schedule an Update
13347 // effect even though we're bailing out, so that cWU/cDU are called.
13348 if (typeof instance.componentDidUpdate === 'function') {
13349 if (oldProps !== current.memoizedProps || oldState !== current.memoizedState) {
13350 workInProgress.effectTag |= Update;
13351 }
13352 }
13353
13354 if (typeof instance.getSnapshotBeforeUpdate === 'function') {
13355 if (oldProps !== current.memoizedProps || oldState !== current.memoizedState) {
13356 workInProgress.effectTag |= Snapshot;
13357 }
13358 }
13359
13360 return false;
13361 }
13362
13363 if (typeof getDerivedStateFromProps === 'function') {
13364 applyDerivedStateFromProps(workInProgress, ctor, getDerivedStateFromProps, newProps);
13365 newState = workInProgress.memoizedState;
13366 }
13367
13368 var shouldUpdate = checkHasForceUpdateAfterProcessing() || checkShouldComponentUpdate(workInProgress, ctor, oldProps, newProps, oldState, newState, nextContext);
13369
13370 if (shouldUpdate) {
13371 // In order to support react-lifecycles-compat polyfilled components,
13372 // Unsafe lifecycles should not be invoked for components using the new APIs.
13373 if (!hasNewLifecycles && (typeof instance.UNSAFE_componentWillUpdate === 'function' || typeof instance.componentWillUpdate === 'function')) {
13374 startPhaseTimer(workInProgress, 'componentWillUpdate');
13375
13376 if (typeof instance.componentWillUpdate === 'function') {
13377 instance.componentWillUpdate(newProps, newState, nextContext);
13378 }
13379
13380 if (typeof instance.UNSAFE_componentWillUpdate === 'function') {
13381 instance.UNSAFE_componentWillUpdate(newProps, newState, nextContext);
13382 }
13383
13384 stopPhaseTimer();
13385 }
13386
13387 if (typeof instance.componentDidUpdate === 'function') {
13388 workInProgress.effectTag |= Update;
13389 }
13390
13391 if (typeof instance.getSnapshotBeforeUpdate === 'function') {
13392 workInProgress.effectTag |= Snapshot;
13393 }
13394 } else {
13395 // If an update was already in progress, we should schedule an Update
13396 // effect even though we're bailing out, so that cWU/cDU are called.
13397 if (typeof instance.componentDidUpdate === 'function') {
13398 if (oldProps !== current.memoizedProps || oldState !== current.memoizedState) {
13399 workInProgress.effectTag |= Update;
13400 }
13401 }
13402
13403 if (typeof instance.getSnapshotBeforeUpdate === 'function') {
13404 if (oldProps !== current.memoizedProps || oldState !== current.memoizedState) {
13405 workInProgress.effectTag |= Snapshot;
13406 }
13407 } // If shouldComponentUpdate returned false, we should still update the
13408 // memoized props/state to indicate that this work can be reused.
13409
13410
13411 workInProgress.memoizedProps = newProps;
13412 workInProgress.memoizedState = newState;
13413 } // Update the existing instance's state, props, and context pointers even
13414 // if shouldComponentUpdate returns false.
13415
13416
13417 instance.props = newProps;
13418 instance.state = newState;
13419 instance.context = nextContext;
13420 return shouldUpdate;
13421 }
13422
13423 var didWarnAboutMaps;
13424 var didWarnAboutGenerators;
13425 var didWarnAboutStringRefs;
13426 var ownerHasKeyUseWarning;
13427 var ownerHasFunctionTypeWarning;
13428
13429 var warnForMissingKey = function (child) {};
13430
13431 {
13432 didWarnAboutMaps = false;
13433 didWarnAboutGenerators = false;
13434 didWarnAboutStringRefs = {};
13435 /**
13436 * Warn if there's no key explicitly set on dynamic arrays of children or
13437 * object keys are not valid. This allows us to keep track of children between
13438 * updates.
13439 */
13440
13441 ownerHasKeyUseWarning = {};
13442 ownerHasFunctionTypeWarning = {};
13443
13444 warnForMissingKey = function (child) {
13445 if (child === null || typeof child !== 'object') {
13446 return;
13447 }
13448
13449 if (!child._store || child._store.validated || child.key != null) {
13450 return;
13451 }
13452
13453 if (!(typeof child._store === 'object')) {
13454 {
13455 throw Error( "React Component in warnForMissingKey should have a _store. This error is likely caused by a bug in React. Please file an issue." );
13456 }
13457 }
13458
13459 child._store.validated = true;
13460 var currentComponentErrorInfo = 'Each child in a list should have a unique ' + '"key" prop. See https://fb.me/react-warning-keys for ' + 'more information.' + getCurrentFiberStackInDev();
13461
13462 if (ownerHasKeyUseWarning[currentComponentErrorInfo]) {
13463 return;
13464 }
13465
13466 ownerHasKeyUseWarning[currentComponentErrorInfo] = true;
13467
13468 error('Each child in a list should have a unique ' + '"key" prop. See https://fb.me/react-warning-keys for ' + 'more information.');
13469 };
13470 }
13471
13472 var isArray$1 = Array.isArray;
13473
13474 function coerceRef(returnFiber, current, element) {
13475 var mixedRef = element.ref;
13476
13477 if (mixedRef !== null && typeof mixedRef !== 'function' && typeof mixedRef !== 'object') {
13478 {
13479 // TODO: Clean this up once we turn on the string ref warning for
13480 // everyone, because the strict mode case will no longer be relevant
13481 if ((returnFiber.mode & StrictMode || warnAboutStringRefs) && // We warn in ReactElement.js if owner and self are equal for string refs
13482 // because these cannot be automatically converted to an arrow function
13483 // using a codemod. Therefore, we don't have to warn about string refs again.
13484 !(element._owner && element._self && element._owner.stateNode !== element._self)) {
13485 var componentName = getComponentName(returnFiber.type) || 'Component';
13486
13487 if (!didWarnAboutStringRefs[componentName]) {
13488 {
13489 error('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 useRef() or createRef() instead. ' + 'Learn more about using refs safely here: ' + 'https://fb.me/react-strict-mode-string-ref%s', mixedRef, getStackByFiberInDevAndProd(returnFiber));
13490 }
13491
13492 didWarnAboutStringRefs[componentName] = true;
13493 }
13494 }
13495 }
13496
13497 if (element._owner) {
13498 var owner = element._owner;
13499 var inst;
13500
13501 if (owner) {
13502 var ownerFiber = owner;
13503
13504 if (!(ownerFiber.tag === ClassComponent)) {
13505 {
13506 throw Error( "Function components cannot have string refs. We recommend using useRef() instead. Learn more about using refs safely here: https://fb.me/react-strict-mode-string-ref" );
13507 }
13508 }
13509
13510 inst = ownerFiber.stateNode;
13511 }
13512
13513 if (!inst) {
13514 {
13515 throw Error( "Missing owner for string ref " + mixedRef + ". This error is likely caused by a bug in React. Please file an issue." );
13516 }
13517 }
13518
13519 var stringRef = '' + mixedRef; // Check if previous string ref matches new string ref
13520
13521 if (current !== null && current.ref !== null && typeof current.ref === 'function' && current.ref._stringRef === stringRef) {
13522 return current.ref;
13523 }
13524
13525 var ref = function (value) {
13526 var refs = inst.refs;
13527
13528 if (refs === emptyRefsObject) {
13529 // This is a lazy pooled frozen object, so we need to initialize.
13530 refs = inst.refs = {};
13531 }
13532
13533 if (value === null) {
13534 delete refs[stringRef];
13535 } else {
13536 refs[stringRef] = value;
13537 }
13538 };
13539
13540 ref._stringRef = stringRef;
13541 return ref;
13542 } else {
13543 if (!(typeof mixedRef === 'string')) {
13544 {
13545 throw Error( "Expected ref to be a function, a string, an object returned by React.createRef(), or null." );
13546 }
13547 }
13548
13549 if (!element._owner) {
13550 {
13551 throw 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." );
13552 }
13553 }
13554 }
13555 }
13556
13557 return mixedRef;
13558 }
13559
13560 function throwOnInvalidObjectType(returnFiber, newChild) {
13561 if (returnFiber.type !== 'textarea') {
13562 var addendum = '';
13563
13564 {
13565 addendum = ' If you meant to render a collection of children, use an array ' + 'instead.' + getCurrentFiberStackInDev();
13566 }
13567
13568 {
13569 {
13570 throw 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 );
13571 }
13572 }
13573 }
13574 }
13575
13576 function warnOnFunctionType() {
13577 {
13578 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();
13579
13580 if (ownerHasFunctionTypeWarning[currentComponentErrorInfo]) {
13581 return;
13582 }
13583
13584 ownerHasFunctionTypeWarning[currentComponentErrorInfo] = true;
13585
13586 error('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.');
13587 }
13588 } // This wrapper function exists because I expect to clone the code in each path
13589 // to be able to optimize each path individually by branching early. This needs
13590 // a compiler or we can do it manually. Helpers that don't need this branching
13591 // live outside of this function.
13592
13593
13594 function ChildReconciler(shouldTrackSideEffects) {
13595 function deleteChild(returnFiber, childToDelete) {
13596 if (!shouldTrackSideEffects) {
13597 // Noop.
13598 return;
13599 } // Deletions are added in reversed order so we add it to the front.
13600 // At this point, the return fiber's effect list is empty except for
13601 // deletions, so we can just append the deletion to the list. The remaining
13602 // effects aren't added until the complete phase. Once we implement
13603 // resuming, this may not be true.
13604
13605
13606 var last = returnFiber.lastEffect;
13607
13608 if (last !== null) {
13609 last.nextEffect = childToDelete;
13610 returnFiber.lastEffect = childToDelete;
13611 } else {
13612 returnFiber.firstEffect = returnFiber.lastEffect = childToDelete;
13613 }
13614
13615 childToDelete.nextEffect = null;
13616 childToDelete.effectTag = Deletion;
13617 }
13618
13619 function deleteRemainingChildren(returnFiber, currentFirstChild) {
13620 if (!shouldTrackSideEffects) {
13621 // Noop.
13622 return null;
13623 } // TODO: For the shouldClone case, this could be micro-optimized a bit by
13624 // assuming that after the first child we've already added everything.
13625
13626
13627 var childToDelete = currentFirstChild;
13628
13629 while (childToDelete !== null) {
13630 deleteChild(returnFiber, childToDelete);
13631 childToDelete = childToDelete.sibling;
13632 }
13633
13634 return null;
13635 }
13636
13637 function mapRemainingChildren(returnFiber, currentFirstChild) {
13638 // Add the remaining children to a temporary map so that we can find them by
13639 // keys quickly. Implicit (null) keys get added to this set with their index
13640 // instead.
13641 var existingChildren = new Map();
13642 var existingChild = currentFirstChild;
13643
13644 while (existingChild !== null) {
13645 if (existingChild.key !== null) {
13646 existingChildren.set(existingChild.key, existingChild);
13647 } else {
13648 existingChildren.set(existingChild.index, existingChild);
13649 }
13650
13651 existingChild = existingChild.sibling;
13652 }
13653
13654 return existingChildren;
13655 }
13656
13657 function useFiber(fiber, pendingProps) {
13658 // We currently set sibling to null and index to 0 here because it is easy
13659 // to forget to do before returning it. E.g. for the single child case.
13660 var clone = createWorkInProgress(fiber, pendingProps);
13661 clone.index = 0;
13662 clone.sibling = null;
13663 return clone;
13664 }
13665
13666 function placeChild(newFiber, lastPlacedIndex, newIndex) {
13667 newFiber.index = newIndex;
13668
13669 if (!shouldTrackSideEffects) {
13670 // Noop.
13671 return lastPlacedIndex;
13672 }
13673
13674 var current = newFiber.alternate;
13675
13676 if (current !== null) {
13677 var oldIndex = current.index;
13678
13679 if (oldIndex < lastPlacedIndex) {
13680 // This is a move.
13681 newFiber.effectTag = Placement;
13682 return lastPlacedIndex;
13683 } else {
13684 // This item can stay in place.
13685 return oldIndex;
13686 }
13687 } else {
13688 // This is an insertion.
13689 newFiber.effectTag = Placement;
13690 return lastPlacedIndex;
13691 }
13692 }
13693
13694 function placeSingleChild(newFiber) {
13695 // This is simpler for the single child case. We only need to do a
13696 // placement for inserting new children.
13697 if (shouldTrackSideEffects && newFiber.alternate === null) {
13698 newFiber.effectTag = Placement;
13699 }
13700
13701 return newFiber;
13702 }
13703
13704 function updateTextNode(returnFiber, current, textContent, expirationTime) {
13705 if (current === null || current.tag !== HostText) {
13706 // Insert
13707 var created = createFiberFromText(textContent, returnFiber.mode, expirationTime);
13708 created.return = returnFiber;
13709 return created;
13710 } else {
13711 // Update
13712 var existing = useFiber(current, textContent);
13713 existing.return = returnFiber;
13714 return existing;
13715 }
13716 }
13717
13718 function updateElement(returnFiber, current, element, expirationTime) {
13719 if (current !== null) {
13720 if (current.elementType === element.type || ( // Keep this check inline so it only runs on the false path:
13721 isCompatibleFamilyForHotReloading(current, element) )) {
13722 // Move based on index
13723 var existing = useFiber(current, element.props);
13724 existing.ref = coerceRef(returnFiber, current, element);
13725 existing.return = returnFiber;
13726
13727 {
13728 existing._debugSource = element._source;
13729 existing._debugOwner = element._owner;
13730 }
13731
13732 return existing;
13733 }
13734 } // Insert
13735
13736
13737 var created = createFiberFromElement(element, returnFiber.mode, expirationTime);
13738 created.ref = coerceRef(returnFiber, current, element);
13739 created.return = returnFiber;
13740 return created;
13741 }
13742
13743 function updatePortal(returnFiber, current, portal, expirationTime) {
13744 if (current === null || current.tag !== HostPortal || current.stateNode.containerInfo !== portal.containerInfo || current.stateNode.implementation !== portal.implementation) {
13745 // Insert
13746 var created = createFiberFromPortal(portal, returnFiber.mode, expirationTime);
13747 created.return = returnFiber;
13748 return created;
13749 } else {
13750 // Update
13751 var existing = useFiber(current, portal.children || []);
13752 existing.return = returnFiber;
13753 return existing;
13754 }
13755 }
13756
13757 function updateFragment(returnFiber, current, fragment, expirationTime, key) {
13758 if (current === null || current.tag !== Fragment) {
13759 // Insert
13760 var created = createFiberFromFragment(fragment, returnFiber.mode, expirationTime, key);
13761 created.return = returnFiber;
13762 return created;
13763 } else {
13764 // Update
13765 var existing = useFiber(current, fragment);
13766 existing.return = returnFiber;
13767 return existing;
13768 }
13769 }
13770
13771 function createChild(returnFiber, newChild, expirationTime) {
13772 if (typeof newChild === 'string' || typeof newChild === 'number') {
13773 // Text nodes don't have keys. If the previous node is implicitly keyed
13774 // we can continue to replace it without aborting even if it is not a text
13775 // node.
13776 var created = createFiberFromText('' + newChild, returnFiber.mode, expirationTime);
13777 created.return = returnFiber;
13778 return created;
13779 }
13780
13781 if (typeof newChild === 'object' && newChild !== null) {
13782 switch (newChild.$$typeof) {
13783 case REACT_ELEMENT_TYPE:
13784 {
13785 var _created = createFiberFromElement(newChild, returnFiber.mode, expirationTime);
13786
13787 _created.ref = coerceRef(returnFiber, null, newChild);
13788 _created.return = returnFiber;
13789 return _created;
13790 }
13791
13792 case REACT_PORTAL_TYPE:
13793 {
13794 var _created2 = createFiberFromPortal(newChild, returnFiber.mode, expirationTime);
13795
13796 _created2.return = returnFiber;
13797 return _created2;
13798 }
13799 }
13800
13801 if (isArray$1(newChild) || getIteratorFn(newChild)) {
13802 var _created3 = createFiberFromFragment(newChild, returnFiber.mode, expirationTime, null);
13803
13804 _created3.return = returnFiber;
13805 return _created3;
13806 }
13807
13808 throwOnInvalidObjectType(returnFiber, newChild);
13809 }
13810
13811 {
13812 if (typeof newChild === 'function') {
13813 warnOnFunctionType();
13814 }
13815 }
13816
13817 return null;
13818 }
13819
13820 function updateSlot(returnFiber, oldFiber, newChild, expirationTime) {
13821 // Update the fiber if the keys match, otherwise return null.
13822 var key = oldFiber !== null ? oldFiber.key : null;
13823
13824 if (typeof newChild === 'string' || typeof newChild === 'number') {
13825 // Text nodes don't have keys. If the previous node is implicitly keyed
13826 // we can continue to replace it without aborting even if it is not a text
13827 // node.
13828 if (key !== null) {
13829 return null;
13830 }
13831
13832 return updateTextNode(returnFiber, oldFiber, '' + newChild, expirationTime);
13833 }
13834
13835 if (typeof newChild === 'object' && newChild !== null) {
13836 switch (newChild.$$typeof) {
13837 case REACT_ELEMENT_TYPE:
13838 {
13839 if (newChild.key === key) {
13840 if (newChild.type === REACT_FRAGMENT_TYPE) {
13841 return updateFragment(returnFiber, oldFiber, newChild.props.children, expirationTime, key);
13842 }
13843
13844 return updateElement(returnFiber, oldFiber, newChild, expirationTime);
13845 } else {
13846 return null;
13847 }
13848 }
13849
13850 case REACT_PORTAL_TYPE:
13851 {
13852 if (newChild.key === key) {
13853 return updatePortal(returnFiber, oldFiber, newChild, expirationTime);
13854 } else {
13855 return null;
13856 }
13857 }
13858 }
13859
13860 if (isArray$1(newChild) || getIteratorFn(newChild)) {
13861 if (key !== null) {
13862 return null;
13863 }
13864
13865 return updateFragment(returnFiber, oldFiber, newChild, expirationTime, null);
13866 }
13867
13868 throwOnInvalidObjectType(returnFiber, newChild);
13869 }
13870
13871 {
13872 if (typeof newChild === 'function') {
13873 warnOnFunctionType();
13874 }
13875 }
13876
13877 return null;
13878 }
13879
13880 function updateFromMap(existingChildren, returnFiber, newIdx, newChild, expirationTime) {
13881 if (typeof newChild === 'string' || typeof newChild === 'number') {
13882 // Text nodes don't have keys, so we neither have to check the old nor
13883 // new node for the key. If both are text nodes, they match.
13884 var matchedFiber = existingChildren.get(newIdx) || null;
13885 return updateTextNode(returnFiber, matchedFiber, '' + newChild, expirationTime);
13886 }
13887
13888 if (typeof newChild === 'object' && newChild !== null) {
13889 switch (newChild.$$typeof) {
13890 case REACT_ELEMENT_TYPE:
13891 {
13892 var _matchedFiber = existingChildren.get(newChild.key === null ? newIdx : newChild.key) || null;
13893
13894 if (newChild.type === REACT_FRAGMENT_TYPE) {
13895 return updateFragment(returnFiber, _matchedFiber, newChild.props.children, expirationTime, newChild.key);
13896 }
13897
13898 return updateElement(returnFiber, _matchedFiber, newChild, expirationTime);
13899 }
13900
13901 case REACT_PORTAL_TYPE:
13902 {
13903 var _matchedFiber2 = existingChildren.get(newChild.key === null ? newIdx : newChild.key) || null;
13904
13905 return updatePortal(returnFiber, _matchedFiber2, newChild, expirationTime);
13906 }
13907 }
13908
13909 if (isArray$1(newChild) || getIteratorFn(newChild)) {
13910 var _matchedFiber3 = existingChildren.get(newIdx) || null;
13911
13912 return updateFragment(returnFiber, _matchedFiber3, newChild, expirationTime, null);
13913 }
13914
13915 throwOnInvalidObjectType(returnFiber, newChild);
13916 }
13917
13918 {
13919 if (typeof newChild === 'function') {
13920 warnOnFunctionType();
13921 }
13922 }
13923
13924 return null;
13925 }
13926 /**
13927 * Warns if there is a duplicate or missing key
13928 */
13929
13930
13931 function warnOnInvalidKey(child, knownKeys) {
13932 {
13933 if (typeof child !== 'object' || child === null) {
13934 return knownKeys;
13935 }
13936
13937 switch (child.$$typeof) {
13938 case REACT_ELEMENT_TYPE:
13939 case REACT_PORTAL_TYPE:
13940 warnForMissingKey(child);
13941 var key = child.key;
13942
13943 if (typeof key !== 'string') {
13944 break;
13945 }
13946
13947 if (knownKeys === null) {
13948 knownKeys = new Set();
13949 knownKeys.add(key);
13950 break;
13951 }
13952
13953 if (!knownKeys.has(key)) {
13954 knownKeys.add(key);
13955 break;
13956 }
13957
13958 error('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);
13959
13960 break;
13961 }
13962 }
13963
13964 return knownKeys;
13965 }
13966
13967 function reconcileChildrenArray(returnFiber, currentFirstChild, newChildren, expirationTime) {
13968 // This algorithm can't optimize by searching from both ends since we
13969 // don't have backpointers on fibers. I'm trying to see how far we can get
13970 // with that model. If it ends up not being worth the tradeoffs, we can
13971 // add it later.
13972 // Even with a two ended optimization, we'd want to optimize for the case
13973 // where there are few changes and brute force the comparison instead of
13974 // going for the Map. It'd like to explore hitting that path first in
13975 // forward-only mode and only go for the Map once we notice that we need
13976 // lots of look ahead. This doesn't handle reversal as well as two ended
13977 // search but that's unusual. Besides, for the two ended optimization to
13978 // work on Iterables, we'd need to copy the whole set.
13979 // In this first iteration, we'll just live with hitting the bad case
13980 // (adding everything to a Map) in for every insert/move.
13981 // If you change this code, also update reconcileChildrenIterator() which
13982 // uses the same algorithm.
13983 {
13984 // First, validate keys.
13985 var knownKeys = null;
13986
13987 for (var i = 0; i < newChildren.length; i++) {
13988 var child = newChildren[i];
13989 knownKeys = warnOnInvalidKey(child, knownKeys);
13990 }
13991 }
13992
13993 var resultingFirstChild = null;
13994 var previousNewFiber = null;
13995 var oldFiber = currentFirstChild;
13996 var lastPlacedIndex = 0;
13997 var newIdx = 0;
13998 var nextOldFiber = null;
13999
14000 for (; oldFiber !== null && newIdx < newChildren.length; newIdx++) {
14001 if (oldFiber.index > newIdx) {
14002 nextOldFiber = oldFiber;
14003 oldFiber = null;
14004 } else {
14005 nextOldFiber = oldFiber.sibling;
14006 }
14007
14008 var newFiber = updateSlot(returnFiber, oldFiber, newChildren[newIdx], expirationTime);
14009
14010 if (newFiber === null) {
14011 // TODO: This breaks on empty slots like null children. That's
14012 // unfortunate because it triggers the slow path all the time. We need
14013 // a better way to communicate whether this was a miss or null,
14014 // boolean, undefined, etc.
14015 if (oldFiber === null) {
14016 oldFiber = nextOldFiber;
14017 }
14018
14019 break;
14020 }
14021
14022 if (shouldTrackSideEffects) {
14023 if (oldFiber && newFiber.alternate === null) {
14024 // We matched the slot, but we didn't reuse the existing fiber, so we
14025 // need to delete the existing child.
14026 deleteChild(returnFiber, oldFiber);
14027 }
14028 }
14029
14030 lastPlacedIndex = placeChild(newFiber, lastPlacedIndex, newIdx);
14031
14032 if (previousNewFiber === null) {
14033 // TODO: Move out of the loop. This only happens for the first run.
14034 resultingFirstChild = newFiber;
14035 } else {
14036 // TODO: Defer siblings if we're not at the right index for this slot.
14037 // I.e. if we had null values before, then we want to defer this
14038 // for each null value. However, we also don't want to call updateSlot
14039 // with the previous one.
14040 previousNewFiber.sibling = newFiber;
14041 }
14042
14043 previousNewFiber = newFiber;
14044 oldFiber = nextOldFiber;
14045 }
14046
14047 if (newIdx === newChildren.length) {
14048 // We've reached the end of the new children. We can delete the rest.
14049 deleteRemainingChildren(returnFiber, oldFiber);
14050 return resultingFirstChild;
14051 }
14052
14053 if (oldFiber === null) {
14054 // If we don't have any more existing children we can choose a fast path
14055 // since the rest will all be insertions.
14056 for (; newIdx < newChildren.length; newIdx++) {
14057 var _newFiber = createChild(returnFiber, newChildren[newIdx], expirationTime);
14058
14059 if (_newFiber === null) {
14060 continue;
14061 }
14062
14063 lastPlacedIndex = placeChild(_newFiber, lastPlacedIndex, newIdx);
14064
14065 if (previousNewFiber === null) {
14066 // TODO: Move out of the loop. This only happens for the first run.
14067 resultingFirstChild = _newFiber;
14068 } else {
14069 previousNewFiber.sibling = _newFiber;
14070 }
14071
14072 previousNewFiber = _newFiber;
14073 }
14074
14075 return resultingFirstChild;
14076 } // Add all children to a key map for quick lookups.
14077
14078
14079 var existingChildren = mapRemainingChildren(returnFiber, oldFiber); // Keep scanning and use the map to restore deleted items as moves.
14080
14081 for (; newIdx < newChildren.length; newIdx++) {
14082 var _newFiber2 = updateFromMap(existingChildren, returnFiber, newIdx, newChildren[newIdx], expirationTime);
14083
14084 if (_newFiber2 !== null) {
14085 if (shouldTrackSideEffects) {
14086 if (_newFiber2.alternate !== null) {
14087 // The new fiber is a work in progress, but if there exists a
14088 // current, that means that we reused the fiber. We need to delete
14089 // it from the child list so that we don't add it to the deletion
14090 // list.
14091 existingChildren.delete(_newFiber2.key === null ? newIdx : _newFiber2.key);
14092 }
14093 }
14094
14095 lastPlacedIndex = placeChild(_newFiber2, lastPlacedIndex, newIdx);
14096
14097 if (previousNewFiber === null) {
14098 resultingFirstChild = _newFiber2;
14099 } else {
14100 previousNewFiber.sibling = _newFiber2;
14101 }
14102
14103 previousNewFiber = _newFiber2;
14104 }
14105 }
14106
14107 if (shouldTrackSideEffects) {
14108 // Any existing children that weren't consumed above were deleted. We need
14109 // to add them to the deletion list.
14110 existingChildren.forEach(function (child) {
14111 return deleteChild(returnFiber, child);
14112 });
14113 }
14114
14115 return resultingFirstChild;
14116 }
14117
14118 function reconcileChildrenIterator(returnFiber, currentFirstChild, newChildrenIterable, expirationTime) {
14119 // This is the same implementation as reconcileChildrenArray(),
14120 // but using the iterator instead.
14121 var iteratorFn = getIteratorFn(newChildrenIterable);
14122
14123 if (!(typeof iteratorFn === 'function')) {
14124 {
14125 throw Error( "An object is not an iterable. This error is likely caused by a bug in React. Please file an issue." );
14126 }
14127 }
14128
14129 {
14130 // We don't support rendering Generators because it's a mutation.
14131 // See https://github.com/facebook/react/issues/12995
14132 if (typeof Symbol === 'function' && // $FlowFixMe Flow doesn't know about toStringTag
14133 newChildrenIterable[Symbol.toStringTag] === 'Generator') {
14134 if (!didWarnAboutGenerators) {
14135 error('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.');
14136 }
14137
14138 didWarnAboutGenerators = true;
14139 } // Warn about using Maps as children
14140
14141
14142 if (newChildrenIterable.entries === iteratorFn) {
14143 if (!didWarnAboutMaps) {
14144 error('Using Maps as children is unsupported and will likely yield ' + 'unexpected results. Convert it to a sequence/iterable of keyed ' + 'ReactElements instead.');
14145 }
14146
14147 didWarnAboutMaps = true;
14148 } // First, validate keys.
14149 // We'll get a different iterator later for the main pass.
14150
14151
14152 var _newChildren = iteratorFn.call(newChildrenIterable);
14153
14154 if (_newChildren) {
14155 var knownKeys = null;
14156
14157 var _step = _newChildren.next();
14158
14159 for (; !_step.done; _step = _newChildren.next()) {
14160 var child = _step.value;
14161 knownKeys = warnOnInvalidKey(child, knownKeys);
14162 }
14163 }
14164 }
14165
14166 var newChildren = iteratorFn.call(newChildrenIterable);
14167
14168 if (!(newChildren != null)) {
14169 {
14170 throw Error( "An iterable object provided no iterator." );
14171 }
14172 }
14173
14174 var resultingFirstChild = null;
14175 var previousNewFiber = null;
14176 var oldFiber = currentFirstChild;
14177 var lastPlacedIndex = 0;
14178 var newIdx = 0;
14179 var nextOldFiber = null;
14180 var step = newChildren.next();
14181
14182 for (; oldFiber !== null && !step.done; newIdx++, step = newChildren.next()) {
14183 if (oldFiber.index > newIdx) {
14184 nextOldFiber = oldFiber;
14185 oldFiber = null;
14186 } else {
14187 nextOldFiber = oldFiber.sibling;
14188 }
14189
14190 var newFiber = updateSlot(returnFiber, oldFiber, step.value, expirationTime);
14191
14192 if (newFiber === null) {
14193 // TODO: This breaks on empty slots like null children. That's
14194 // unfortunate because it triggers the slow path all the time. We need
14195 // a better way to communicate whether this was a miss or null,
14196 // boolean, undefined, etc.
14197 if (oldFiber === null) {
14198 oldFiber = nextOldFiber;
14199 }
14200
14201 break;
14202 }
14203
14204 if (shouldTrackSideEffects) {
14205 if (oldFiber && newFiber.alternate === null) {
14206 // We matched the slot, but we didn't reuse the existing fiber, so we
14207 // need to delete the existing child.
14208 deleteChild(returnFiber, oldFiber);
14209 }
14210 }
14211
14212 lastPlacedIndex = placeChild(newFiber, lastPlacedIndex, newIdx);
14213
14214 if (previousNewFiber === null) {
14215 // TODO: Move out of the loop. This only happens for the first run.
14216 resultingFirstChild = newFiber;
14217 } else {
14218 // TODO: Defer siblings if we're not at the right index for this slot.
14219 // I.e. if we had null values before, then we want to defer this
14220 // for each null value. However, we also don't want to call updateSlot
14221 // with the previous one.
14222 previousNewFiber.sibling = newFiber;
14223 }
14224
14225 previousNewFiber = newFiber;
14226 oldFiber = nextOldFiber;
14227 }
14228
14229 if (step.done) {
14230 // We've reached the end of the new children. We can delete the rest.
14231 deleteRemainingChildren(returnFiber, oldFiber);
14232 return resultingFirstChild;
14233 }
14234
14235 if (oldFiber === null) {
14236 // If we don't have any more existing children we can choose a fast path
14237 // since the rest will all be insertions.
14238 for (; !step.done; newIdx++, step = newChildren.next()) {
14239 var _newFiber3 = createChild(returnFiber, step.value, expirationTime);
14240
14241 if (_newFiber3 === null) {
14242 continue;
14243 }
14244
14245 lastPlacedIndex = placeChild(_newFiber3, lastPlacedIndex, newIdx);
14246
14247 if (previousNewFiber === null) {
14248 // TODO: Move out of the loop. This only happens for the first run.
14249 resultingFirstChild = _newFiber3;
14250 } else {
14251 previousNewFiber.sibling = _newFiber3;
14252 }
14253
14254 previousNewFiber = _newFiber3;
14255 }
14256
14257 return resultingFirstChild;
14258 } // Add all children to a key map for quick lookups.
14259
14260
14261 var existingChildren = mapRemainingChildren(returnFiber, oldFiber); // Keep scanning and use the map to restore deleted items as moves.
14262
14263 for (; !step.done; newIdx++, step = newChildren.next()) {
14264 var _newFiber4 = updateFromMap(existingChildren, returnFiber, newIdx, step.value, expirationTime);
14265
14266 if (_newFiber4 !== null) {
14267 if (shouldTrackSideEffects) {
14268 if (_newFiber4.alternate !== null) {
14269 // The new fiber is a work in progress, but if there exists a
14270 // current, that means that we reused the fiber. We need to delete
14271 // it from the child list so that we don't add it to the deletion
14272 // list.
14273 existingChildren.delete(_newFiber4.key === null ? newIdx : _newFiber4.key);
14274 }
14275 }
14276
14277 lastPlacedIndex = placeChild(_newFiber4, lastPlacedIndex, newIdx);
14278
14279 if (previousNewFiber === null) {
14280 resultingFirstChild = _newFiber4;
14281 } else {
14282 previousNewFiber.sibling = _newFiber4;
14283 }
14284
14285 previousNewFiber = _newFiber4;
14286 }
14287 }
14288
14289 if (shouldTrackSideEffects) {
14290 // Any existing children that weren't consumed above were deleted. We need
14291 // to add them to the deletion list.
14292 existingChildren.forEach(function (child) {
14293 return deleteChild(returnFiber, child);
14294 });
14295 }
14296
14297 return resultingFirstChild;
14298 }
14299
14300 function reconcileSingleTextNode(returnFiber, currentFirstChild, textContent, expirationTime) {
14301 // There's no need to check for keys on text nodes since we don't have a
14302 // way to define them.
14303 if (currentFirstChild !== null && currentFirstChild.tag === HostText) {
14304 // We already have an existing node so let's just update it and delete
14305 // the rest.
14306 deleteRemainingChildren(returnFiber, currentFirstChild.sibling);
14307 var existing = useFiber(currentFirstChild, textContent);
14308 existing.return = returnFiber;
14309 return existing;
14310 } // The existing first child is not a text node so we need to create one
14311 // and delete the existing ones.
14312
14313
14314 deleteRemainingChildren(returnFiber, currentFirstChild);
14315 var created = createFiberFromText(textContent, returnFiber.mode, expirationTime);
14316 created.return = returnFiber;
14317 return created;
14318 }
14319
14320 function reconcileSingleElement(returnFiber, currentFirstChild, element, expirationTime) {
14321 var key = element.key;
14322 var child = currentFirstChild;
14323
14324 while (child !== null) {
14325 // TODO: If key === null and child.key === null, then this only applies to
14326 // the first item in the list.
14327 if (child.key === key) {
14328 switch (child.tag) {
14329 case Fragment:
14330 {
14331 if (element.type === REACT_FRAGMENT_TYPE) {
14332 deleteRemainingChildren(returnFiber, child.sibling);
14333 var existing = useFiber(child, element.props.children);
14334 existing.return = returnFiber;
14335
14336 {
14337 existing._debugSource = element._source;
14338 existing._debugOwner = element._owner;
14339 }
14340
14341 return existing;
14342 }
14343
14344 break;
14345 }
14346
14347 case Block:
14348
14349 // We intentionally fallthrough here if enableBlocksAPI is not on.
14350 // eslint-disable-next-lined no-fallthrough
14351
14352 default:
14353 {
14354 if (child.elementType === element.type || ( // Keep this check inline so it only runs on the false path:
14355 isCompatibleFamilyForHotReloading(child, element) )) {
14356 deleteRemainingChildren(returnFiber, child.sibling);
14357
14358 var _existing3 = useFiber(child, element.props);
14359
14360 _existing3.ref = coerceRef(returnFiber, child, element);
14361 _existing3.return = returnFiber;
14362
14363 {
14364 _existing3._debugSource = element._source;
14365 _existing3._debugOwner = element._owner;
14366 }
14367
14368 return _existing3;
14369 }
14370
14371 break;
14372 }
14373 } // Didn't match.
14374
14375
14376 deleteRemainingChildren(returnFiber, child);
14377 break;
14378 } else {
14379 deleteChild(returnFiber, child);
14380 }
14381
14382 child = child.sibling;
14383 }
14384
14385 if (element.type === REACT_FRAGMENT_TYPE) {
14386 var created = createFiberFromFragment(element.props.children, returnFiber.mode, expirationTime, element.key);
14387 created.return = returnFiber;
14388 return created;
14389 } else {
14390 var _created4 = createFiberFromElement(element, returnFiber.mode, expirationTime);
14391
14392 _created4.ref = coerceRef(returnFiber, currentFirstChild, element);
14393 _created4.return = returnFiber;
14394 return _created4;
14395 }
14396 }
14397
14398 function reconcileSinglePortal(returnFiber, currentFirstChild, portal, expirationTime) {
14399 var key = portal.key;
14400 var child = currentFirstChild;
14401
14402 while (child !== null) {
14403 // TODO: If key === null and child.key === null, then this only applies to
14404 // the first item in the list.
14405 if (child.key === key) {
14406 if (child.tag === HostPortal && child.stateNode.containerInfo === portal.containerInfo && child.stateNode.implementation === portal.implementation) {
14407 deleteRemainingChildren(returnFiber, child.sibling);
14408 var existing = useFiber(child, portal.children || []);
14409 existing.return = returnFiber;
14410 return existing;
14411 } else {
14412 deleteRemainingChildren(returnFiber, child);
14413 break;
14414 }
14415 } else {
14416 deleteChild(returnFiber, child);
14417 }
14418
14419 child = child.sibling;
14420 }
14421
14422 var created = createFiberFromPortal(portal, returnFiber.mode, expirationTime);
14423 created.return = returnFiber;
14424 return created;
14425 } // This API will tag the children with the side-effect of the reconciliation
14426 // itself. They will be added to the side-effect list as we pass through the
14427 // children and the parent.
14428
14429
14430 function reconcileChildFibers(returnFiber, currentFirstChild, newChild, expirationTime) {
14431 // This function is not recursive.
14432 // If the top level item is an array, we treat it as a set of children,
14433 // not as a fragment. Nested arrays on the other hand will be treated as
14434 // fragment nodes. Recursion happens at the normal flow.
14435 // Handle top level unkeyed fragments as if they were arrays.
14436 // This leads to an ambiguity between <>{[...]}</> and <>...</>.
14437 // We treat the ambiguous cases above the same.
14438 var isUnkeyedTopLevelFragment = typeof newChild === 'object' && newChild !== null && newChild.type === REACT_FRAGMENT_TYPE && newChild.key === null;
14439
14440 if (isUnkeyedTopLevelFragment) {
14441 newChild = newChild.props.children;
14442 } // Handle object types
14443
14444
14445 var isObject = typeof newChild === 'object' && newChild !== null;
14446
14447 if (isObject) {
14448 switch (newChild.$$typeof) {
14449 case REACT_ELEMENT_TYPE:
14450 return placeSingleChild(reconcileSingleElement(returnFiber, currentFirstChild, newChild, expirationTime));
14451
14452 case REACT_PORTAL_TYPE:
14453 return placeSingleChild(reconcileSinglePortal(returnFiber, currentFirstChild, newChild, expirationTime));
14454 }
14455 }
14456
14457 if (typeof newChild === 'string' || typeof newChild === 'number') {
14458 return placeSingleChild(reconcileSingleTextNode(returnFiber, currentFirstChild, '' + newChild, expirationTime));
14459 }
14460
14461 if (isArray$1(newChild)) {
14462 return reconcileChildrenArray(returnFiber, currentFirstChild, newChild, expirationTime);
14463 }
14464
14465 if (getIteratorFn(newChild)) {
14466 return reconcileChildrenIterator(returnFiber, currentFirstChild, newChild, expirationTime);
14467 }
14468
14469 if (isObject) {
14470 throwOnInvalidObjectType(returnFiber, newChild);
14471 }
14472
14473 {
14474 if (typeof newChild === 'function') {
14475 warnOnFunctionType();
14476 }
14477 }
14478
14479 if (typeof newChild === 'undefined' && !isUnkeyedTopLevelFragment) {
14480 // If the new child is undefined, and the return fiber is a composite
14481 // component, throw an error. If Fiber return types are disabled,
14482 // we already threw above.
14483 switch (returnFiber.tag) {
14484 case ClassComponent:
14485 {
14486 {
14487 var instance = returnFiber.stateNode;
14488
14489 if (instance.render._isMockFunction) {
14490 // We allow auto-mocks to proceed as if they're returning null.
14491 break;
14492 }
14493 }
14494 }
14495 // Intentionally fall through to the next case, which handles both
14496 // functions and classes
14497 // eslint-disable-next-lined no-fallthrough
14498
14499 case FunctionComponent:
14500 {
14501 var Component = returnFiber.type;
14502
14503 {
14504 {
14505 throw 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." );
14506 }
14507 }
14508 }
14509 }
14510 } // Remaining cases are all treated as empty.
14511
14512
14513 return deleteRemainingChildren(returnFiber, currentFirstChild);
14514 }
14515
14516 return reconcileChildFibers;
14517 }
14518
14519 var reconcileChildFibers = ChildReconciler(true);
14520 var mountChildFibers = ChildReconciler(false);
14521 function cloneChildFibers(current, workInProgress) {
14522 if (!(current === null || workInProgress.child === current.child)) {
14523 {
14524 throw Error( "Resuming work not yet implemented." );
14525 }
14526 }
14527
14528 if (workInProgress.child === null) {
14529 return;
14530 }
14531
14532 var currentChild = workInProgress.child;
14533 var newChild = createWorkInProgress(currentChild, currentChild.pendingProps);
14534 workInProgress.child = newChild;
14535 newChild.return = workInProgress;
14536
14537 while (currentChild.sibling !== null) {
14538 currentChild = currentChild.sibling;
14539 newChild = newChild.sibling = createWorkInProgress(currentChild, currentChild.pendingProps);
14540 newChild.return = workInProgress;
14541 }
14542
14543 newChild.sibling = null;
14544 } // Reset a workInProgress child set to prepare it for a second pass.
14545
14546 function resetChildFibers(workInProgress, renderExpirationTime) {
14547 var child = workInProgress.child;
14548
14549 while (child !== null) {
14550 resetWorkInProgress(child, renderExpirationTime);
14551 child = child.sibling;
14552 }
14553 }
14554
14555 var NO_CONTEXT = {};
14556 var contextStackCursor$1 = createCursor(NO_CONTEXT);
14557 var contextFiberStackCursor = createCursor(NO_CONTEXT);
14558 var rootInstanceStackCursor = createCursor(NO_CONTEXT);
14559
14560 function requiredContext(c) {
14561 if (!(c !== NO_CONTEXT)) {
14562 {
14563 throw Error( "Expected host context to exist. This error is likely caused by a bug in React. Please file an issue." );
14564 }
14565 }
14566
14567 return c;
14568 }
14569
14570 function getRootHostContainer() {
14571 var rootInstance = requiredContext(rootInstanceStackCursor.current);
14572 return rootInstance;
14573 }
14574
14575 function pushHostContainer(fiber, nextRootInstance) {
14576 // Push current root instance onto the stack;
14577 // This allows us to reset root when portals are popped.
14578 push(rootInstanceStackCursor, nextRootInstance, fiber); // Track the context and the Fiber that provided it.
14579 // This enables us to pop only Fibers that provide unique contexts.
14580
14581 push(contextFiberStackCursor, fiber, fiber); // Finally, we need to push the host context to the stack.
14582 // However, we can't just call getRootHostContext() and push it because
14583 // we'd have a different number of entries on the stack depending on
14584 // whether getRootHostContext() throws somewhere in renderer code or not.
14585 // So we push an empty value first. This lets us safely unwind on errors.
14586
14587 push(contextStackCursor$1, NO_CONTEXT, fiber);
14588 var nextRootContext = getRootHostContext(nextRootInstance); // Now that we know this function doesn't throw, replace it.
14589
14590 pop(contextStackCursor$1, fiber);
14591 push(contextStackCursor$1, nextRootContext, fiber);
14592 }
14593
14594 function popHostContainer(fiber) {
14595 pop(contextStackCursor$1, fiber);
14596 pop(contextFiberStackCursor, fiber);
14597 pop(rootInstanceStackCursor, fiber);
14598 }
14599
14600 function getHostContext() {
14601 var context = requiredContext(contextStackCursor$1.current);
14602 return context;
14603 }
14604
14605 function pushHostContext(fiber) {
14606 var rootInstance = requiredContext(rootInstanceStackCursor.current);
14607 var context = requiredContext(contextStackCursor$1.current);
14608 var nextContext = getChildHostContext(context, fiber.type); // Don't push this Fiber's context unless it's unique.
14609
14610 if (context === nextContext) {
14611 return;
14612 } // Track the context and the Fiber that provided it.
14613 // This enables us to pop only Fibers that provide unique contexts.
14614
14615
14616 push(contextFiberStackCursor, fiber, fiber);
14617 push(contextStackCursor$1, nextContext, fiber);
14618 }
14619
14620 function popHostContext(fiber) {
14621 // Do not pop unless this Fiber provided the current context.
14622 // pushHostContext() only pushes Fibers that provide unique contexts.
14623 if (contextFiberStackCursor.current !== fiber) {
14624 return;
14625 }
14626
14627 pop(contextStackCursor$1, fiber);
14628 pop(contextFiberStackCursor, fiber);
14629 }
14630
14631 var DefaultSuspenseContext = 0; // The Suspense Context is split into two parts. The lower bits is
14632 // inherited deeply down the subtree. The upper bits only affect
14633 // this immediate suspense boundary and gets reset each new
14634 // boundary or suspense list.
14635
14636 var SubtreeSuspenseContextMask = 1; // Subtree Flags:
14637 // InvisibleParentSuspenseContext indicates that one of our parent Suspense
14638 // boundaries is not currently showing visible main content.
14639 // Either because it is already showing a fallback or is not mounted at all.
14640 // We can use this to determine if it is desirable to trigger a fallback at
14641 // the parent. If not, then we might need to trigger undesirable boundaries
14642 // and/or suspend the commit to avoid hiding the parent content.
14643
14644 var InvisibleParentSuspenseContext = 1; // Shallow Flags:
14645 // ForceSuspenseFallback can be used by SuspenseList to force newly added
14646 // items into their fallback state during one of the render passes.
14647
14648 var ForceSuspenseFallback = 2;
14649 var suspenseStackCursor = createCursor(DefaultSuspenseContext);
14650 function hasSuspenseContext(parentContext, flag) {
14651 return (parentContext & flag) !== 0;
14652 }
14653 function setDefaultShallowSuspenseContext(parentContext) {
14654 return parentContext & SubtreeSuspenseContextMask;
14655 }
14656 function setShallowSuspenseContext(parentContext, shallowContext) {
14657 return parentContext & SubtreeSuspenseContextMask | shallowContext;
14658 }
14659 function addSubtreeSuspenseContext(parentContext, subtreeContext) {
14660 return parentContext | subtreeContext;
14661 }
14662 function pushSuspenseContext(fiber, newContext) {
14663 push(suspenseStackCursor, newContext, fiber);
14664 }
14665 function popSuspenseContext(fiber) {
14666 pop(suspenseStackCursor, fiber);
14667 }
14668
14669 function shouldCaptureSuspense(workInProgress, hasInvisibleParent) {
14670 // If it was the primary children that just suspended, capture and render the
14671 // fallback. Otherwise, don't capture and bubble to the next boundary.
14672 var nextState = workInProgress.memoizedState;
14673
14674 if (nextState !== null) {
14675 if (nextState.dehydrated !== null) {
14676 // A dehydrated boundary always captures.
14677 return true;
14678 }
14679
14680 return false;
14681 }
14682
14683 var props = workInProgress.memoizedProps; // In order to capture, the Suspense component must have a fallback prop.
14684
14685 if (props.fallback === undefined) {
14686 return false;
14687 } // Regular boundaries always capture.
14688
14689
14690 if (props.unstable_avoidThisFallback !== true) {
14691 return true;
14692 } // If it's a boundary we should avoid, then we prefer to bubble up to the
14693 // parent boundary if it is currently invisible.
14694
14695
14696 if (hasInvisibleParent) {
14697 return false;
14698 } // If the parent is not able to handle it, we must handle it.
14699
14700
14701 return true;
14702 }
14703 function findFirstSuspended(row) {
14704 var node = row;
14705
14706 while (node !== null) {
14707 if (node.tag === SuspenseComponent) {
14708 var state = node.memoizedState;
14709
14710 if (state !== null) {
14711 var dehydrated = state.dehydrated;
14712
14713 if (dehydrated === null || isSuspenseInstancePending(dehydrated) || isSuspenseInstanceFallback(dehydrated)) {
14714 return node;
14715 }
14716 }
14717 } else if (node.tag === SuspenseListComponent && // revealOrder undefined can't be trusted because it don't
14718 // keep track of whether it suspended or not.
14719 node.memoizedProps.revealOrder !== undefined) {
14720 var didSuspend = (node.effectTag & DidCapture) !== NoEffect;
14721
14722 if (didSuspend) {
14723 return node;
14724 }
14725 } else if (node.child !== null) {
14726 node.child.return = node;
14727 node = node.child;
14728 continue;
14729 }
14730
14731 if (node === row) {
14732 return null;
14733 }
14734
14735 while (node.sibling === null) {
14736 if (node.return === null || node.return === row) {
14737 return null;
14738 }
14739
14740 node = node.return;
14741 }
14742
14743 node.sibling.return = node.return;
14744 node = node.sibling;
14745 }
14746
14747 return null;
14748 }
14749
14750 function createDeprecatedResponderListener(responder, props) {
14751 var eventResponderListener = {
14752 responder: responder,
14753 props: props
14754 };
14755
14756 {
14757 Object.freeze(eventResponderListener);
14758 }
14759
14760 return eventResponderListener;
14761 }
14762
14763 var HasEffect =
14764 /* */
14765 1; // Represents the phase in which the effect (not the clean-up) fires.
14766
14767 var Layout =
14768 /* */
14769 2;
14770 var Passive$1 =
14771 /* */
14772 4;
14773
14774 var ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher,
14775 ReactCurrentBatchConfig$1 = ReactSharedInternals.ReactCurrentBatchConfig;
14776 var didWarnAboutMismatchedHooksForComponent;
14777
14778 {
14779 didWarnAboutMismatchedHooksForComponent = new Set();
14780 }
14781
14782 // These are set right before calling the component.
14783 var renderExpirationTime = NoWork; // The work-in-progress fiber. I've named it differently to distinguish it from
14784 // the work-in-progress hook.
14785
14786 var currentlyRenderingFiber$1 = null; // Hooks are stored as a linked list on the fiber's memoizedState field. The
14787 // current hook list is the list that belongs to the current fiber. The
14788 // work-in-progress hook list is a new list that will be added to the
14789 // work-in-progress fiber.
14790
14791 var currentHook = null;
14792 var workInProgressHook = null; // Whether an update was scheduled at any point during the render phase. This
14793 // does not get reset if we do another render pass; only when we're completely
14794 // finished evaluating this component. This is an optimization so we know
14795 // whether we need to clear render phase updates after a throw.
14796
14797 var didScheduleRenderPhaseUpdate = false;
14798 var RE_RENDER_LIMIT = 25; // In DEV, this is the name of the currently executing primitive hook
14799
14800 var currentHookNameInDev = null; // In DEV, this list ensures that hooks are called in the same order between renders.
14801 // The list stores the order of hooks used during the initial render (mount).
14802 // Subsequent renders (updates) reference this list.
14803
14804 var hookTypesDev = null;
14805 var hookTypesUpdateIndexDev = -1; // In DEV, this tracks whether currently rendering component needs to ignore
14806 // the dependencies for Hooks that need them (e.g. useEffect or useMemo).
14807 // When true, such Hooks will always be "remounted". Only used during hot reload.
14808
14809 var ignorePreviousDependencies = false;
14810
14811 function mountHookTypesDev() {
14812 {
14813 var hookName = currentHookNameInDev;
14814
14815 if (hookTypesDev === null) {
14816 hookTypesDev = [hookName];
14817 } else {
14818 hookTypesDev.push(hookName);
14819 }
14820 }
14821 }
14822
14823 function updateHookTypesDev() {
14824 {
14825 var hookName = currentHookNameInDev;
14826
14827 if (hookTypesDev !== null) {
14828 hookTypesUpdateIndexDev++;
14829
14830 if (hookTypesDev[hookTypesUpdateIndexDev] !== hookName) {
14831 warnOnHookMismatchInDev(hookName);
14832 }
14833 }
14834 }
14835 }
14836
14837 function checkDepsAreArrayDev(deps) {
14838 {
14839 if (deps !== undefined && deps !== null && !Array.isArray(deps)) {
14840 // Verify deps, but only on mount to avoid extra checks.
14841 // It's unlikely their type would change as usually you define them inline.
14842 error('%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);
14843 }
14844 }
14845 }
14846
14847 function warnOnHookMismatchInDev(currentHookName) {
14848 {
14849 var componentName = getComponentName(currentlyRenderingFiber$1.type);
14850
14851 if (!didWarnAboutMismatchedHooksForComponent.has(componentName)) {
14852 didWarnAboutMismatchedHooksForComponent.add(componentName);
14853
14854 if (hookTypesDev !== null) {
14855 var table = '';
14856 var secondColumnStart = 30;
14857
14858 for (var i = 0; i <= hookTypesUpdateIndexDev; i++) {
14859 var oldHookName = hookTypesDev[i];
14860 var newHookName = i === hookTypesUpdateIndexDev ? currentHookName : oldHookName;
14861 var row = i + 1 + ". " + oldHookName; // Extra space so second column lines up
14862 // lol @ IE not supporting String#repeat
14863
14864 while (row.length < secondColumnStart) {
14865 row += ' ';
14866 }
14867
14868 row += newHookName + '\n';
14869 table += row;
14870 }
14871
14872 error('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);
14873 }
14874 }
14875 }
14876 }
14877
14878 function throwInvalidHookError() {
14879 {
14880 {
14881 throw 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." );
14882 }
14883 }
14884 }
14885
14886 function areHookInputsEqual(nextDeps, prevDeps) {
14887 {
14888 if (ignorePreviousDependencies) {
14889 // Only true when this component is being hot reloaded.
14890 return false;
14891 }
14892 }
14893
14894 if (prevDeps === null) {
14895 {
14896 error('%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);
14897 }
14898
14899 return false;
14900 }
14901
14902 {
14903 // Don't bother comparing lengths in prod because these arrays should be
14904 // passed inline.
14905 if (nextDeps.length !== prevDeps.length) {
14906 error('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(', ') + "]");
14907 }
14908 }
14909
14910 for (var i = 0; i < prevDeps.length && i < nextDeps.length; i++) {
14911 if (objectIs(nextDeps[i], prevDeps[i])) {
14912 continue;
14913 }
14914
14915 return false;
14916 }
14917
14918 return true;
14919 }
14920
14921 function renderWithHooks(current, workInProgress, Component, props, secondArg, nextRenderExpirationTime) {
14922 renderExpirationTime = nextRenderExpirationTime;
14923 currentlyRenderingFiber$1 = workInProgress;
14924
14925 {
14926 hookTypesDev = current !== null ? current._debugHookTypes : null;
14927 hookTypesUpdateIndexDev = -1; // Used for hot reloading:
14928
14929 ignorePreviousDependencies = current !== null && current.type !== workInProgress.type;
14930 }
14931
14932 workInProgress.memoizedState = null;
14933 workInProgress.updateQueue = null;
14934 workInProgress.expirationTime = NoWork; // The following should have already been reset
14935 // currentHook = null;
14936 // workInProgressHook = null;
14937 // didScheduleRenderPhaseUpdate = false;
14938 // TODO Warn if no hooks are used at all during mount, then some are used during update.
14939 // Currently we will identify the update render as a mount because memoizedState === null.
14940 // This is tricky because it's valid for certain types of components (e.g. React.lazy)
14941 // Using memoizedState to differentiate between mount/update only works if at least one stateful hook is used.
14942 // Non-stateful hooks (e.g. context) don't get added to memoizedState,
14943 // so memoizedState would be null during updates and mounts.
14944
14945 {
14946 if (current !== null && current.memoizedState !== null) {
14947 ReactCurrentDispatcher.current = HooksDispatcherOnUpdateInDEV;
14948 } else if (hookTypesDev !== null) {
14949 // This dispatcher handles an edge case where a component is updating,
14950 // but no stateful hooks have been used.
14951 // We want to match the production code behavior (which will use HooksDispatcherOnMount),
14952 // but with the extra DEV validation to ensure hooks ordering hasn't changed.
14953 // This dispatcher does that.
14954 ReactCurrentDispatcher.current = HooksDispatcherOnMountWithHookTypesInDEV;
14955 } else {
14956 ReactCurrentDispatcher.current = HooksDispatcherOnMountInDEV;
14957 }
14958 }
14959
14960 var children = Component(props, secondArg); // Check if there was a render phase update
14961
14962 if (workInProgress.expirationTime === renderExpirationTime) {
14963 // Keep rendering in a loop for as long as render phase updates continue to
14964 // be scheduled. Use a counter to prevent infinite loops.
14965 var numberOfReRenders = 0;
14966
14967 do {
14968 workInProgress.expirationTime = NoWork;
14969
14970 if (!(numberOfReRenders < RE_RENDER_LIMIT)) {
14971 {
14972 throw Error( "Too many re-renders. React limits the number of renders to prevent an infinite loop." );
14973 }
14974 }
14975
14976 numberOfReRenders += 1;
14977
14978 {
14979 // Even when hot reloading, allow dependencies to stabilize
14980 // after first render to prevent infinite render phase updates.
14981 ignorePreviousDependencies = false;
14982 } // Start over from the beginning of the list
14983
14984
14985 currentHook = null;
14986 workInProgressHook = null;
14987 workInProgress.updateQueue = null;
14988
14989 {
14990 // Also validate hook order for cascading updates.
14991 hookTypesUpdateIndexDev = -1;
14992 }
14993
14994 ReactCurrentDispatcher.current = HooksDispatcherOnRerenderInDEV ;
14995 children = Component(props, secondArg);
14996 } while (workInProgress.expirationTime === renderExpirationTime);
14997 } // We can assume the previous dispatcher is always this one, since we set it
14998 // at the beginning of the render phase and there's no re-entrancy.
14999
15000
15001 ReactCurrentDispatcher.current = ContextOnlyDispatcher;
15002
15003 {
15004 workInProgress._debugHookTypes = hookTypesDev;
15005 } // This check uses currentHook so that it works the same in DEV and prod bundles.
15006 // hookTypesDev could catch more cases (e.g. context) but only in DEV bundles.
15007
15008
15009 var didRenderTooFewHooks = currentHook !== null && currentHook.next !== null;
15010 renderExpirationTime = NoWork;
15011 currentlyRenderingFiber$1 = null;
15012 currentHook = null;
15013 workInProgressHook = null;
15014
15015 {
15016 currentHookNameInDev = null;
15017 hookTypesDev = null;
15018 hookTypesUpdateIndexDev = -1;
15019 }
15020
15021 didScheduleRenderPhaseUpdate = false;
15022
15023 if (!!didRenderTooFewHooks) {
15024 {
15025 throw Error( "Rendered fewer hooks than expected. This may be caused by an accidental early return statement." );
15026 }
15027 }
15028
15029 return children;
15030 }
15031 function bailoutHooks(current, workInProgress, expirationTime) {
15032 workInProgress.updateQueue = current.updateQueue;
15033 workInProgress.effectTag &= ~(Passive | Update);
15034
15035 if (current.expirationTime <= expirationTime) {
15036 current.expirationTime = NoWork;
15037 }
15038 }
15039 function resetHooksAfterThrow() {
15040 // We can assume the previous dispatcher is always this one, since we set it
15041 // at the beginning of the render phase and there's no re-entrancy.
15042 ReactCurrentDispatcher.current = ContextOnlyDispatcher;
15043
15044 if (didScheduleRenderPhaseUpdate) {
15045 // There were render phase updates. These are only valid for this render
15046 // phase, which we are now aborting. Remove the updates from the queues so
15047 // they do not persist to the next render. Do not remove updates from hooks
15048 // that weren't processed.
15049 //
15050 // Only reset the updates from the queue if it has a clone. If it does
15051 // not have a clone, that means it wasn't processed, and the updates were
15052 // scheduled before we entered the render phase.
15053 var hook = currentlyRenderingFiber$1.memoizedState;
15054
15055 while (hook !== null) {
15056 var queue = hook.queue;
15057
15058 if (queue !== null) {
15059 queue.pending = null;
15060 }
15061
15062 hook = hook.next;
15063 }
15064 }
15065
15066 renderExpirationTime = NoWork;
15067 currentlyRenderingFiber$1 = null;
15068 currentHook = null;
15069 workInProgressHook = null;
15070
15071 {
15072 hookTypesDev = null;
15073 hookTypesUpdateIndexDev = -1;
15074 currentHookNameInDev = null;
15075 }
15076
15077 didScheduleRenderPhaseUpdate = false;
15078 }
15079
15080 function mountWorkInProgressHook() {
15081 var hook = {
15082 memoizedState: null,
15083 baseState: null,
15084 baseQueue: null,
15085 queue: null,
15086 next: null
15087 };
15088
15089 if (workInProgressHook === null) {
15090 // This is the first hook in the list
15091 currentlyRenderingFiber$1.memoizedState = workInProgressHook = hook;
15092 } else {
15093 // Append to the end of the list
15094 workInProgressHook = workInProgressHook.next = hook;
15095 }
15096
15097 return workInProgressHook;
15098 }
15099
15100 function updateWorkInProgressHook() {
15101 // This function is used both for updates and for re-renders triggered by a
15102 // render phase update. It assumes there is either a current hook we can
15103 // clone, or a work-in-progress hook from a previous render pass that we can
15104 // use as a base. When we reach the end of the base list, we must switch to
15105 // the dispatcher used for mounts.
15106 var nextCurrentHook;
15107
15108 if (currentHook === null) {
15109 var current = currentlyRenderingFiber$1.alternate;
15110
15111 if (current !== null) {
15112 nextCurrentHook = current.memoizedState;
15113 } else {
15114 nextCurrentHook = null;
15115 }
15116 } else {
15117 nextCurrentHook = currentHook.next;
15118 }
15119
15120 var nextWorkInProgressHook;
15121
15122 if (workInProgressHook === null) {
15123 nextWorkInProgressHook = currentlyRenderingFiber$1.memoizedState;
15124 } else {
15125 nextWorkInProgressHook = workInProgressHook.next;
15126 }
15127
15128 if (nextWorkInProgressHook !== null) {
15129 // There's already a work-in-progress. Reuse it.
15130 workInProgressHook = nextWorkInProgressHook;
15131 nextWorkInProgressHook = workInProgressHook.next;
15132 currentHook = nextCurrentHook;
15133 } else {
15134 // Clone from the current hook.
15135 if (!(nextCurrentHook !== null)) {
15136 {
15137 throw Error( "Rendered more hooks than during the previous render." );
15138 }
15139 }
15140
15141 currentHook = nextCurrentHook;
15142 var newHook = {
15143 memoizedState: currentHook.memoizedState,
15144 baseState: currentHook.baseState,
15145 baseQueue: currentHook.baseQueue,
15146 queue: currentHook.queue,
15147 next: null
15148 };
15149
15150 if (workInProgressHook === null) {
15151 // This is the first hook in the list.
15152 currentlyRenderingFiber$1.memoizedState = workInProgressHook = newHook;
15153 } else {
15154 // Append to the end of the list.
15155 workInProgressHook = workInProgressHook.next = newHook;
15156 }
15157 }
15158
15159 return workInProgressHook;
15160 }
15161
15162 function createFunctionComponentUpdateQueue() {
15163 return {
15164 lastEffect: null
15165 };
15166 }
15167
15168 function basicStateReducer(state, action) {
15169 // $FlowFixMe: Flow doesn't like mixed types
15170 return typeof action === 'function' ? action(state) : action;
15171 }
15172
15173 function mountReducer(reducer, initialArg, init) {
15174 var hook = mountWorkInProgressHook();
15175 var initialState;
15176
15177 if (init !== undefined) {
15178 initialState = init(initialArg);
15179 } else {
15180 initialState = initialArg;
15181 }
15182
15183 hook.memoizedState = hook.baseState = initialState;
15184 var queue = hook.queue = {
15185 pending: null,
15186 dispatch: null,
15187 lastRenderedReducer: reducer,
15188 lastRenderedState: initialState
15189 };
15190 var dispatch = queue.dispatch = dispatchAction.bind(null, currentlyRenderingFiber$1, queue);
15191 return [hook.memoizedState, dispatch];
15192 }
15193
15194 function updateReducer(reducer, initialArg, init) {
15195 var hook = updateWorkInProgressHook();
15196 var queue = hook.queue;
15197
15198 if (!(queue !== null)) {
15199 {
15200 throw Error( "Should have a queue. This is likely a bug in React. Please file an issue." );
15201 }
15202 }
15203
15204 queue.lastRenderedReducer = reducer;
15205 var current = currentHook; // The last rebase update that is NOT part of the base state.
15206
15207 var baseQueue = current.baseQueue; // The last pending update that hasn't been processed yet.
15208
15209 var pendingQueue = queue.pending;
15210
15211 if (pendingQueue !== null) {
15212 // We have new updates that haven't been processed yet.
15213 // We'll add them to the base queue.
15214 if (baseQueue !== null) {
15215 // Merge the pending queue and the base queue.
15216 var baseFirst = baseQueue.next;
15217 var pendingFirst = pendingQueue.next;
15218 baseQueue.next = pendingFirst;
15219 pendingQueue.next = baseFirst;
15220 }
15221
15222 current.baseQueue = baseQueue = pendingQueue;
15223 queue.pending = null;
15224 }
15225
15226 if (baseQueue !== null) {
15227 // We have a queue to process.
15228 var first = baseQueue.next;
15229 var newState = current.baseState;
15230 var newBaseState = null;
15231 var newBaseQueueFirst = null;
15232 var newBaseQueueLast = null;
15233 var update = first;
15234
15235 do {
15236 var updateExpirationTime = update.expirationTime;
15237
15238 if (updateExpirationTime < renderExpirationTime) {
15239 // Priority is insufficient. Skip this update. If this is the first
15240 // skipped update, the previous update/state is the new base
15241 // update/state.
15242 var clone = {
15243 expirationTime: update.expirationTime,
15244 suspenseConfig: update.suspenseConfig,
15245 action: update.action,
15246 eagerReducer: update.eagerReducer,
15247 eagerState: update.eagerState,
15248 next: null
15249 };
15250
15251 if (newBaseQueueLast === null) {
15252 newBaseQueueFirst = newBaseQueueLast = clone;
15253 newBaseState = newState;
15254 } else {
15255 newBaseQueueLast = newBaseQueueLast.next = clone;
15256 } // Update the remaining priority in the queue.
15257
15258
15259 if (updateExpirationTime > currentlyRenderingFiber$1.expirationTime) {
15260 currentlyRenderingFiber$1.expirationTime = updateExpirationTime;
15261 markUnprocessedUpdateTime(updateExpirationTime);
15262 }
15263 } else {
15264 // This update does have sufficient priority.
15265 if (newBaseQueueLast !== null) {
15266 var _clone = {
15267 expirationTime: Sync,
15268 // This update is going to be committed so we never want uncommit it.
15269 suspenseConfig: update.suspenseConfig,
15270 action: update.action,
15271 eagerReducer: update.eagerReducer,
15272 eagerState: update.eagerState,
15273 next: null
15274 };
15275 newBaseQueueLast = newBaseQueueLast.next = _clone;
15276 } // Mark the event time of this update as relevant to this render pass.
15277 // TODO: This should ideally use the true event time of this update rather than
15278 // its priority which is a derived and not reverseable value.
15279 // TODO: We should skip this update if it was already committed but currently
15280 // we have no way of detecting the difference between a committed and suspended
15281 // update here.
15282
15283
15284 markRenderEventTimeAndConfig(updateExpirationTime, update.suspenseConfig); // Process this update.
15285
15286 if (update.eagerReducer === reducer) {
15287 // If this update was processed eagerly, and its reducer matches the
15288 // current reducer, we can use the eagerly computed state.
15289 newState = update.eagerState;
15290 } else {
15291 var action = update.action;
15292 newState = reducer(newState, action);
15293 }
15294 }
15295
15296 update = update.next;
15297 } while (update !== null && update !== first);
15298
15299 if (newBaseQueueLast === null) {
15300 newBaseState = newState;
15301 } else {
15302 newBaseQueueLast.next = newBaseQueueFirst;
15303 } // Mark that the fiber performed work, but only if the new state is
15304 // different from the current state.
15305
15306
15307 if (!objectIs(newState, hook.memoizedState)) {
15308 markWorkInProgressReceivedUpdate();
15309 }
15310
15311 hook.memoizedState = newState;
15312 hook.baseState = newBaseState;
15313 hook.baseQueue = newBaseQueueLast;
15314 queue.lastRenderedState = newState;
15315 }
15316
15317 var dispatch = queue.dispatch;
15318 return [hook.memoizedState, dispatch];
15319 }
15320
15321 function rerenderReducer(reducer, initialArg, init) {
15322 var hook = updateWorkInProgressHook();
15323 var queue = hook.queue;
15324
15325 if (!(queue !== null)) {
15326 {
15327 throw Error( "Should have a queue. This is likely a bug in React. Please file an issue." );
15328 }
15329 }
15330
15331 queue.lastRenderedReducer = reducer; // This is a re-render. Apply the new render phase updates to the previous
15332 // work-in-progress hook.
15333
15334 var dispatch = queue.dispatch;
15335 var lastRenderPhaseUpdate = queue.pending;
15336 var newState = hook.memoizedState;
15337
15338 if (lastRenderPhaseUpdate !== null) {
15339 // The queue doesn't persist past this render pass.
15340 queue.pending = null;
15341 var firstRenderPhaseUpdate = lastRenderPhaseUpdate.next;
15342 var update = firstRenderPhaseUpdate;
15343
15344 do {
15345 // Process this render phase update. We don't have to check the
15346 // priority because it will always be the same as the current
15347 // render's.
15348 var action = update.action;
15349 newState = reducer(newState, action);
15350 update = update.next;
15351 } while (update !== firstRenderPhaseUpdate); // Mark that the fiber performed work, but only if the new state is
15352 // different from the current state.
15353
15354
15355 if (!objectIs(newState, hook.memoizedState)) {
15356 markWorkInProgressReceivedUpdate();
15357 }
15358
15359 hook.memoizedState = newState; // Don't persist the state accumulated from the render phase updates to
15360 // the base state unless the queue is empty.
15361 // TODO: Not sure if this is the desired semantics, but it's what we
15362 // do for gDSFP. I can't remember why.
15363
15364 if (hook.baseQueue === null) {
15365 hook.baseState = newState;
15366 }
15367
15368 queue.lastRenderedState = newState;
15369 }
15370
15371 return [newState, dispatch];
15372 }
15373
15374 function mountState(initialState) {
15375 var hook = mountWorkInProgressHook();
15376
15377 if (typeof initialState === 'function') {
15378 // $FlowFixMe: Flow doesn't like mixed types
15379 initialState = initialState();
15380 }
15381
15382 hook.memoizedState = hook.baseState = initialState;
15383 var queue = hook.queue = {
15384 pending: null,
15385 dispatch: null,
15386 lastRenderedReducer: basicStateReducer,
15387 lastRenderedState: initialState
15388 };
15389 var dispatch = queue.dispatch = dispatchAction.bind(null, currentlyRenderingFiber$1, queue);
15390 return [hook.memoizedState, dispatch];
15391 }
15392
15393 function updateState(initialState) {
15394 return updateReducer(basicStateReducer);
15395 }
15396
15397 function rerenderState(initialState) {
15398 return rerenderReducer(basicStateReducer);
15399 }
15400
15401 function pushEffect(tag, create, destroy, deps) {
15402 var effect = {
15403 tag: tag,
15404 create: create,
15405 destroy: destroy,
15406 deps: deps,
15407 // Circular
15408 next: null
15409 };
15410 var componentUpdateQueue = currentlyRenderingFiber$1.updateQueue;
15411
15412 if (componentUpdateQueue === null) {
15413 componentUpdateQueue = createFunctionComponentUpdateQueue();
15414 currentlyRenderingFiber$1.updateQueue = componentUpdateQueue;
15415 componentUpdateQueue.lastEffect = effect.next = effect;
15416 } else {
15417 var lastEffect = componentUpdateQueue.lastEffect;
15418
15419 if (lastEffect === null) {
15420 componentUpdateQueue.lastEffect = effect.next = effect;
15421 } else {
15422 var firstEffect = lastEffect.next;
15423 lastEffect.next = effect;
15424 effect.next = firstEffect;
15425 componentUpdateQueue.lastEffect = effect;
15426 }
15427 }
15428
15429 return effect;
15430 }
15431
15432 function mountRef(initialValue) {
15433 var hook = mountWorkInProgressHook();
15434 var ref = {
15435 current: initialValue
15436 };
15437
15438 {
15439 Object.seal(ref);
15440 }
15441
15442 hook.memoizedState = ref;
15443 return ref;
15444 }
15445
15446 function updateRef(initialValue) {
15447 var hook = updateWorkInProgressHook();
15448 return hook.memoizedState;
15449 }
15450
15451 function mountEffectImpl(fiberEffectTag, hookEffectTag, create, deps) {
15452 var hook = mountWorkInProgressHook();
15453 var nextDeps = deps === undefined ? null : deps;
15454 currentlyRenderingFiber$1.effectTag |= fiberEffectTag;
15455 hook.memoizedState = pushEffect(HasEffect | hookEffectTag, create, undefined, nextDeps);
15456 }
15457
15458 function updateEffectImpl(fiberEffectTag, hookEffectTag, create, deps) {
15459 var hook = updateWorkInProgressHook();
15460 var nextDeps = deps === undefined ? null : deps;
15461 var destroy = undefined;
15462
15463 if (currentHook !== null) {
15464 var prevEffect = currentHook.memoizedState;
15465 destroy = prevEffect.destroy;
15466
15467 if (nextDeps !== null) {
15468 var prevDeps = prevEffect.deps;
15469
15470 if (areHookInputsEqual(nextDeps, prevDeps)) {
15471 pushEffect(hookEffectTag, create, destroy, nextDeps);
15472 return;
15473 }
15474 }
15475 }
15476
15477 currentlyRenderingFiber$1.effectTag |= fiberEffectTag;
15478 hook.memoizedState = pushEffect(HasEffect | hookEffectTag, create, destroy, nextDeps);
15479 }
15480
15481 function mountEffect(create, deps) {
15482 {
15483 // $FlowExpectedError - jest isn't a global, and isn't recognized outside of tests
15484 if ('undefined' !== typeof jest) {
15485 warnIfNotCurrentlyActingEffectsInDEV(currentlyRenderingFiber$1);
15486 }
15487 }
15488
15489 return mountEffectImpl(Update | Passive, Passive$1, create, deps);
15490 }
15491
15492 function updateEffect(create, deps) {
15493 {
15494 // $FlowExpectedError - jest isn't a global, and isn't recognized outside of tests
15495 if ('undefined' !== typeof jest) {
15496 warnIfNotCurrentlyActingEffectsInDEV(currentlyRenderingFiber$1);
15497 }
15498 }
15499
15500 return updateEffectImpl(Update | Passive, Passive$1, create, deps);
15501 }
15502
15503 function mountLayoutEffect(create, deps) {
15504 return mountEffectImpl(Update, Layout, create, deps);
15505 }
15506
15507 function updateLayoutEffect(create, deps) {
15508 return updateEffectImpl(Update, Layout, create, deps);
15509 }
15510
15511 function imperativeHandleEffect(create, ref) {
15512 if (typeof ref === 'function') {
15513 var refCallback = ref;
15514
15515 var _inst = create();
15516
15517 refCallback(_inst);
15518 return function () {
15519 refCallback(null);
15520 };
15521 } else if (ref !== null && ref !== undefined) {
15522 var refObject = ref;
15523
15524 {
15525 if (!refObject.hasOwnProperty('current')) {
15526 error('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(', ') + '}');
15527 }
15528 }
15529
15530 var _inst2 = create();
15531
15532 refObject.current = _inst2;
15533 return function () {
15534 refObject.current = null;
15535 };
15536 }
15537 }
15538
15539 function mountImperativeHandle(ref, create, deps) {
15540 {
15541 if (typeof create !== 'function') {
15542 error('Expected useImperativeHandle() second argument to be a function ' + 'that creates a handle. Instead received: %s.', create !== null ? typeof create : 'null');
15543 }
15544 } // TODO: If deps are provided, should we skip comparing the ref itself?
15545
15546
15547 var effectDeps = deps !== null && deps !== undefined ? deps.concat([ref]) : null;
15548 return mountEffectImpl(Update, Layout, imperativeHandleEffect.bind(null, create, ref), effectDeps);
15549 }
15550
15551 function updateImperativeHandle(ref, create, deps) {
15552 {
15553 if (typeof create !== 'function') {
15554 error('Expected useImperativeHandle() second argument to be a function ' + 'that creates a handle. Instead received: %s.', create !== null ? typeof create : 'null');
15555 }
15556 } // TODO: If deps are provided, should we skip comparing the ref itself?
15557
15558
15559 var effectDeps = deps !== null && deps !== undefined ? deps.concat([ref]) : null;
15560 return updateEffectImpl(Update, Layout, imperativeHandleEffect.bind(null, create, ref), effectDeps);
15561 }
15562
15563 function mountDebugValue(value, formatterFn) {// This hook is normally a no-op.
15564 // The react-debug-hooks package injects its own implementation
15565 // so that e.g. DevTools can display custom hook values.
15566 }
15567
15568 var updateDebugValue = mountDebugValue;
15569
15570 function mountCallback(callback, deps) {
15571 var hook = mountWorkInProgressHook();
15572 var nextDeps = deps === undefined ? null : deps;
15573 hook.memoizedState = [callback, nextDeps];
15574 return callback;
15575 }
15576
15577 function updateCallback(callback, deps) {
15578 var hook = updateWorkInProgressHook();
15579 var nextDeps = deps === undefined ? null : deps;
15580 var prevState = hook.memoizedState;
15581
15582 if (prevState !== null) {
15583 if (nextDeps !== null) {
15584 var prevDeps = prevState[1];
15585
15586 if (areHookInputsEqual(nextDeps, prevDeps)) {
15587 return prevState[0];
15588 }
15589 }
15590 }
15591
15592 hook.memoizedState = [callback, nextDeps];
15593 return callback;
15594 }
15595
15596 function mountMemo(nextCreate, deps) {
15597 var hook = mountWorkInProgressHook();
15598 var nextDeps = deps === undefined ? null : deps;
15599 var nextValue = nextCreate();
15600 hook.memoizedState = [nextValue, nextDeps];
15601 return nextValue;
15602 }
15603
15604 function updateMemo(nextCreate, deps) {
15605 var hook = updateWorkInProgressHook();
15606 var nextDeps = deps === undefined ? null : deps;
15607 var prevState = hook.memoizedState;
15608
15609 if (prevState !== null) {
15610 // Assume these are defined. If they're not, areHookInputsEqual will warn.
15611 if (nextDeps !== null) {
15612 var prevDeps = prevState[1];
15613
15614 if (areHookInputsEqual(nextDeps, prevDeps)) {
15615 return prevState[0];
15616 }
15617 }
15618 }
15619
15620 var nextValue = nextCreate();
15621 hook.memoizedState = [nextValue, nextDeps];
15622 return nextValue;
15623 }
15624
15625 function mountDeferredValue(value, config) {
15626 var _mountState = mountState(value),
15627 prevValue = _mountState[0],
15628 setValue = _mountState[1];
15629
15630 mountEffect(function () {
15631 var previousConfig = ReactCurrentBatchConfig$1.suspense;
15632 ReactCurrentBatchConfig$1.suspense = config === undefined ? null : config;
15633
15634 try {
15635 setValue(value);
15636 } finally {
15637 ReactCurrentBatchConfig$1.suspense = previousConfig;
15638 }
15639 }, [value, config]);
15640 return prevValue;
15641 }
15642
15643 function updateDeferredValue(value, config) {
15644 var _updateState = updateState(),
15645 prevValue = _updateState[0],
15646 setValue = _updateState[1];
15647
15648 updateEffect(function () {
15649 var previousConfig = ReactCurrentBatchConfig$1.suspense;
15650 ReactCurrentBatchConfig$1.suspense = config === undefined ? null : config;
15651
15652 try {
15653 setValue(value);
15654 } finally {
15655 ReactCurrentBatchConfig$1.suspense = previousConfig;
15656 }
15657 }, [value, config]);
15658 return prevValue;
15659 }
15660
15661 function rerenderDeferredValue(value, config) {
15662 var _rerenderState = rerenderState(),
15663 prevValue = _rerenderState[0],
15664 setValue = _rerenderState[1];
15665
15666 updateEffect(function () {
15667 var previousConfig = ReactCurrentBatchConfig$1.suspense;
15668 ReactCurrentBatchConfig$1.suspense = config === undefined ? null : config;
15669
15670 try {
15671 setValue(value);
15672 } finally {
15673 ReactCurrentBatchConfig$1.suspense = previousConfig;
15674 }
15675 }, [value, config]);
15676 return prevValue;
15677 }
15678
15679 function startTransition(setPending, config, callback) {
15680 var priorityLevel = getCurrentPriorityLevel();
15681 runWithPriority$1(priorityLevel < UserBlockingPriority$1 ? UserBlockingPriority$1 : priorityLevel, function () {
15682 setPending(true);
15683 });
15684 runWithPriority$1(priorityLevel > NormalPriority ? NormalPriority : priorityLevel, function () {
15685 var previousConfig = ReactCurrentBatchConfig$1.suspense;
15686 ReactCurrentBatchConfig$1.suspense = config === undefined ? null : config;
15687
15688 try {
15689 setPending(false);
15690 callback();
15691 } finally {
15692 ReactCurrentBatchConfig$1.suspense = previousConfig;
15693 }
15694 });
15695 }
15696
15697 function mountTransition(config) {
15698 var _mountState2 = mountState(false),
15699 isPending = _mountState2[0],
15700 setPending = _mountState2[1];
15701
15702 var start = mountCallback(startTransition.bind(null, setPending, config), [setPending, config]);
15703 return [start, isPending];
15704 }
15705
15706 function updateTransition(config) {
15707 var _updateState2 = updateState(),
15708 isPending = _updateState2[0],
15709 setPending = _updateState2[1];
15710
15711 var start = updateCallback(startTransition.bind(null, setPending, config), [setPending, config]);
15712 return [start, isPending];
15713 }
15714
15715 function rerenderTransition(config) {
15716 var _rerenderState2 = rerenderState(),
15717 isPending = _rerenderState2[0],
15718 setPending = _rerenderState2[1];
15719
15720 var start = updateCallback(startTransition.bind(null, setPending, config), [setPending, config]);
15721 return [start, isPending];
15722 }
15723
15724 function dispatchAction(fiber, queue, action) {
15725 {
15726 if (typeof arguments[3] === 'function') {
15727 error("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().');
15728 }
15729 }
15730
15731 var currentTime = requestCurrentTimeForUpdate();
15732 var suspenseConfig = requestCurrentSuspenseConfig();
15733 var expirationTime = computeExpirationForFiber(currentTime, fiber, suspenseConfig);
15734 var update = {
15735 expirationTime: expirationTime,
15736 suspenseConfig: suspenseConfig,
15737 action: action,
15738 eagerReducer: null,
15739 eagerState: null,
15740 next: null
15741 };
15742
15743 {
15744 update.priority = getCurrentPriorityLevel();
15745 } // Append the update to the end of the list.
15746
15747
15748 var pending = queue.pending;
15749
15750 if (pending === null) {
15751 // This is the first update. Create a circular list.
15752 update.next = update;
15753 } else {
15754 update.next = pending.next;
15755 pending.next = update;
15756 }
15757
15758 queue.pending = update;
15759 var alternate = fiber.alternate;
15760
15761 if (fiber === currentlyRenderingFiber$1 || alternate !== null && alternate === currentlyRenderingFiber$1) {
15762 // This is a render phase update. Stash it in a lazily-created map of
15763 // queue -> linked list of updates. After this render pass, we'll restart
15764 // and apply the stashed updates on top of the work-in-progress hook.
15765 didScheduleRenderPhaseUpdate = true;
15766 update.expirationTime = renderExpirationTime;
15767 currentlyRenderingFiber$1.expirationTime = renderExpirationTime;
15768 } else {
15769 if (fiber.expirationTime === NoWork && (alternate === null || alternate.expirationTime === NoWork)) {
15770 // The queue is currently empty, which means we can eagerly compute the
15771 // next state before entering the render phase. If the new state is the
15772 // same as the current state, we may be able to bail out entirely.
15773 var lastRenderedReducer = queue.lastRenderedReducer;
15774
15775 if (lastRenderedReducer !== null) {
15776 var prevDispatcher;
15777
15778 {
15779 prevDispatcher = ReactCurrentDispatcher.current;
15780 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
15781 }
15782
15783 try {
15784 var currentState = queue.lastRenderedState;
15785 var eagerState = lastRenderedReducer(currentState, action); // Stash the eagerly computed state, and the reducer used to compute
15786 // it, on the update object. If the reducer hasn't changed by the
15787 // time we enter the render phase, then the eager state can be used
15788 // without calling the reducer again.
15789
15790 update.eagerReducer = lastRenderedReducer;
15791 update.eagerState = eagerState;
15792
15793 if (objectIs(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) {// Suppress the error. It will throw again in the render phase.
15801 } finally {
15802 {
15803 ReactCurrentDispatcher.current = prevDispatcher;
15804 }
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
15817 scheduleWork(fiber, expirationTime);
15818 }
15819 }
15820
15821 var ContextOnlyDispatcher = {
15822 readContext: readContext,
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 useDeferredValue: throwInvalidHookError,
15835 useTransition: throwInvalidHookError
15836 };
15837 var HooksDispatcherOnMountInDEV = null;
15838 var HooksDispatcherOnMountWithHookTypesInDEV = null;
15839 var HooksDispatcherOnUpdateInDEV = null;
15840 var HooksDispatcherOnRerenderInDEV = null;
15841 var InvalidNestedHooksDispatcherOnMountInDEV = null;
15842 var InvalidNestedHooksDispatcherOnUpdateInDEV = null;
15843 var InvalidNestedHooksDispatcherOnRerenderInDEV = null;
15844
15845 {
15846 var warnInvalidContextAccess = function () {
15847 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().');
15848 };
15849
15850 var warnInvalidHookAccess = function () {
15851 error('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');
15852 };
15853
15854 HooksDispatcherOnMountInDEV = {
15855 readContext: function (context, observedBits) {
15856 return readContext(context, observedBits);
15857 },
15858 useCallback: function (callback, deps) {
15859 currentHookNameInDev = 'useCallback';
15860 mountHookTypesDev();
15861 checkDepsAreArrayDev(deps);
15862 return mountCallback(callback, deps);
15863 },
15864 useContext: function (context, observedBits) {
15865 currentHookNameInDev = 'useContext';
15866 mountHookTypesDev();
15867 return readContext(context, observedBits);
15868 },
15869 useEffect: function (create, deps) {
15870 currentHookNameInDev = 'useEffect';
15871 mountHookTypesDev();
15872 checkDepsAreArrayDev(deps);
15873 return mountEffect(create, deps);
15874 },
15875 useImperativeHandle: function (ref, create, deps) {
15876 currentHookNameInDev = 'useImperativeHandle';
15877 mountHookTypesDev();
15878 checkDepsAreArrayDev(deps);
15879 return mountImperativeHandle(ref, create, deps);
15880 },
15881 useLayoutEffect: function (create, deps) {
15882 currentHookNameInDev = 'useLayoutEffect';
15883 mountHookTypesDev();
15884 checkDepsAreArrayDev(deps);
15885 return mountLayoutEffect(create, deps);
15886 },
15887 useMemo: function (create, deps) {
15888 currentHookNameInDev = 'useMemo';
15889 mountHookTypesDev();
15890 checkDepsAreArrayDev(deps);
15891 var prevDispatcher = ReactCurrentDispatcher.current;
15892 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV;
15893
15894 try {
15895 return mountMemo(create, deps);
15896 } finally {
15897 ReactCurrentDispatcher.current = prevDispatcher;
15898 }
15899 },
15900 useReducer: function (reducer, initialArg, init) {
15901 currentHookNameInDev = 'useReducer';
15902 mountHookTypesDev();
15903 var prevDispatcher = ReactCurrentDispatcher.current;
15904 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV;
15905
15906 try {
15907 return mountReducer(reducer, initialArg, init);
15908 } finally {
15909 ReactCurrentDispatcher.current = prevDispatcher;
15910 }
15911 },
15912 useRef: function (initialValue) {
15913 currentHookNameInDev = 'useRef';
15914 mountHookTypesDev();
15915 return mountRef(initialValue);
15916 },
15917 useState: function (initialState) {
15918 currentHookNameInDev = 'useState';
15919 mountHookTypesDev();
15920 var prevDispatcher = ReactCurrentDispatcher.current;
15921 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV;
15922
15923 try {
15924 return mountState(initialState);
15925 } finally {
15926 ReactCurrentDispatcher.current = prevDispatcher;
15927 }
15928 },
15929 useDebugValue: function (value, formatterFn) {
15930 currentHookNameInDev = 'useDebugValue';
15931 mountHookTypesDev();
15932 return mountDebugValue();
15933 },
15934 useResponder: function (responder, props) {
15935 currentHookNameInDev = 'useResponder';
15936 mountHookTypesDev();
15937 return createDeprecatedResponderListener(responder, props);
15938 },
15939 useDeferredValue: function (value, config) {
15940 currentHookNameInDev = 'useDeferredValue';
15941 mountHookTypesDev();
15942 return mountDeferredValue(value, config);
15943 },
15944 useTransition: function (config) {
15945 currentHookNameInDev = 'useTransition';
15946 mountHookTypesDev();
15947 return mountTransition(config);
15948 }
15949 };
15950 HooksDispatcherOnMountWithHookTypesInDEV = {
15951 readContext: function (context, observedBits) {
15952 return readContext(context, observedBits);
15953 },
15954 useCallback: function (callback, deps) {
15955 currentHookNameInDev = 'useCallback';
15956 updateHookTypesDev();
15957 return mountCallback(callback, deps);
15958 },
15959 useContext: function (context, observedBits) {
15960 currentHookNameInDev = 'useContext';
15961 updateHookTypesDev();
15962 return readContext(context, observedBits);
15963 },
15964 useEffect: function (create, deps) {
15965 currentHookNameInDev = 'useEffect';
15966 updateHookTypesDev();
15967 return mountEffect(create, deps);
15968 },
15969 useImperativeHandle: function (ref, create, deps) {
15970 currentHookNameInDev = 'useImperativeHandle';
15971 updateHookTypesDev();
15972 return mountImperativeHandle(ref, create, deps);
15973 },
15974 useLayoutEffect: function (create, deps) {
15975 currentHookNameInDev = 'useLayoutEffect';
15976 updateHookTypesDev();
15977 return mountLayoutEffect(create, deps);
15978 },
15979 useMemo: function (create, deps) {
15980 currentHookNameInDev = 'useMemo';
15981 updateHookTypesDev();
15982 var prevDispatcher = ReactCurrentDispatcher.current;
15983 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV;
15984
15985 try {
15986 return mountMemo(create, deps);
15987 } finally {
15988 ReactCurrentDispatcher.current = prevDispatcher;
15989 }
15990 },
15991 useReducer: function (reducer, initialArg, init) {
15992 currentHookNameInDev = 'useReducer';
15993 updateHookTypesDev();
15994 var prevDispatcher = ReactCurrentDispatcher.current;
15995 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV;
15996
15997 try {
15998 return mountReducer(reducer, initialArg, init);
15999 } finally {
16000 ReactCurrentDispatcher.current = prevDispatcher;
16001 }
16002 },
16003 useRef: function (initialValue) {
16004 currentHookNameInDev = 'useRef';
16005 updateHookTypesDev();
16006 return mountRef(initialValue);
16007 },
16008 useState: function (initialState) {
16009 currentHookNameInDev = 'useState';
16010 updateHookTypesDev();
16011 var prevDispatcher = ReactCurrentDispatcher.current;
16012 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV;
16013
16014 try {
16015 return mountState(initialState);
16016 } finally {
16017 ReactCurrentDispatcher.current = prevDispatcher;
16018 }
16019 },
16020 useDebugValue: function (value, formatterFn) {
16021 currentHookNameInDev = 'useDebugValue';
16022 updateHookTypesDev();
16023 return mountDebugValue();
16024 },
16025 useResponder: function (responder, props) {
16026 currentHookNameInDev = 'useResponder';
16027 updateHookTypesDev();
16028 return createDeprecatedResponderListener(responder, props);
16029 },
16030 useDeferredValue: function (value, config) {
16031 currentHookNameInDev = 'useDeferredValue';
16032 updateHookTypesDev();
16033 return mountDeferredValue(value, config);
16034 },
16035 useTransition: function (config) {
16036 currentHookNameInDev = 'useTransition';
16037 updateHookTypesDev();
16038 return mountTransition(config);
16039 }
16040 };
16041 HooksDispatcherOnUpdateInDEV = {
16042 readContext: function (context, observedBits) {
16043 return readContext(context, observedBits);
16044 },
16045 useCallback: function (callback, deps) {
16046 currentHookNameInDev = 'useCallback';
16047 updateHookTypesDev();
16048 return updateCallback(callback, deps);
16049 },
16050 useContext: function (context, observedBits) {
16051 currentHookNameInDev = 'useContext';
16052 updateHookTypesDev();
16053 return readContext(context, observedBits);
16054 },
16055 useEffect: function (create, deps) {
16056 currentHookNameInDev = 'useEffect';
16057 updateHookTypesDev();
16058 return updateEffect(create, deps);
16059 },
16060 useImperativeHandle: function (ref, create, deps) {
16061 currentHookNameInDev = 'useImperativeHandle';
16062 updateHookTypesDev();
16063 return updateImperativeHandle(ref, create, deps);
16064 },
16065 useLayoutEffect: function (create, deps) {
16066 currentHookNameInDev = 'useLayoutEffect';
16067 updateHookTypesDev();
16068 return updateLayoutEffect(create, deps);
16069 },
16070 useMemo: function (create, deps) {
16071 currentHookNameInDev = 'useMemo';
16072 updateHookTypesDev();
16073 var prevDispatcher = ReactCurrentDispatcher.current;
16074 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
16075
16076 try {
16077 return updateMemo(create, deps);
16078 } finally {
16079 ReactCurrentDispatcher.current = prevDispatcher;
16080 }
16081 },
16082 useReducer: function (reducer, initialArg, init) {
16083 currentHookNameInDev = 'useReducer';
16084 updateHookTypesDev();
16085 var prevDispatcher = ReactCurrentDispatcher.current;
16086 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
16087
16088 try {
16089 return updateReducer(reducer, initialArg, init);
16090 } finally {
16091 ReactCurrentDispatcher.current = prevDispatcher;
16092 }
16093 },
16094 useRef: function (initialValue) {
16095 currentHookNameInDev = 'useRef';
16096 updateHookTypesDev();
16097 return updateRef();
16098 },
16099 useState: function (initialState) {
16100 currentHookNameInDev = 'useState';
16101 updateHookTypesDev();
16102 var prevDispatcher = ReactCurrentDispatcher.current;
16103 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
16104
16105 try {
16106 return updateState(initialState);
16107 } finally {
16108 ReactCurrentDispatcher.current = prevDispatcher;
16109 }
16110 },
16111 useDebugValue: function (value, formatterFn) {
16112 currentHookNameInDev = 'useDebugValue';
16113 updateHookTypesDev();
16114 return updateDebugValue();
16115 },
16116 useResponder: function (responder, props) {
16117 currentHookNameInDev = 'useResponder';
16118 updateHookTypesDev();
16119 return createDeprecatedResponderListener(responder, props);
16120 },
16121 useDeferredValue: function (value, config) {
16122 currentHookNameInDev = 'useDeferredValue';
16123 updateHookTypesDev();
16124 return updateDeferredValue(value, config);
16125 },
16126 useTransition: function (config) {
16127 currentHookNameInDev = 'useTransition';
16128 updateHookTypesDev();
16129 return updateTransition(config);
16130 }
16131 };
16132 HooksDispatcherOnRerenderInDEV = {
16133 readContext: function (context, observedBits) {
16134 return readContext(context, observedBits);
16135 },
16136 useCallback: function (callback, deps) {
16137 currentHookNameInDev = 'useCallback';
16138 updateHookTypesDev();
16139 return updateCallback(callback, deps);
16140 },
16141 useContext: function (context, observedBits) {
16142 currentHookNameInDev = 'useContext';
16143 updateHookTypesDev();
16144 return readContext(context, observedBits);
16145 },
16146 useEffect: function (create, deps) {
16147 currentHookNameInDev = 'useEffect';
16148 updateHookTypesDev();
16149 return updateEffect(create, deps);
16150 },
16151 useImperativeHandle: function (ref, create, deps) {
16152 currentHookNameInDev = 'useImperativeHandle';
16153 updateHookTypesDev();
16154 return updateImperativeHandle(ref, create, deps);
16155 },
16156 useLayoutEffect: function (create, deps) {
16157 currentHookNameInDev = 'useLayoutEffect';
16158 updateHookTypesDev();
16159 return updateLayoutEffect(create, deps);
16160 },
16161 useMemo: function (create, deps) {
16162 currentHookNameInDev = 'useMemo';
16163 updateHookTypesDev();
16164 var prevDispatcher = ReactCurrentDispatcher.current;
16165 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnRerenderInDEV;
16166
16167 try {
16168 return updateMemo(create, deps);
16169 } finally {
16170 ReactCurrentDispatcher.current = prevDispatcher;
16171 }
16172 },
16173 useReducer: function (reducer, initialArg, init) {
16174 currentHookNameInDev = 'useReducer';
16175 updateHookTypesDev();
16176 var prevDispatcher = ReactCurrentDispatcher.current;
16177 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnRerenderInDEV;
16178
16179 try {
16180 return rerenderReducer(reducer, initialArg, init);
16181 } finally {
16182 ReactCurrentDispatcher.current = prevDispatcher;
16183 }
16184 },
16185 useRef: function (initialValue) {
16186 currentHookNameInDev = 'useRef';
16187 updateHookTypesDev();
16188 return updateRef();
16189 },
16190 useState: function (initialState) {
16191 currentHookNameInDev = 'useState';
16192 updateHookTypesDev();
16193 var prevDispatcher = ReactCurrentDispatcher.current;
16194 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnRerenderInDEV;
16195
16196 try {
16197 return rerenderState(initialState);
16198 } finally {
16199 ReactCurrentDispatcher.current = prevDispatcher;
16200 }
16201 },
16202 useDebugValue: function (value, formatterFn) {
16203 currentHookNameInDev = 'useDebugValue';
16204 updateHookTypesDev();
16205 return updateDebugValue();
16206 },
16207 useResponder: function (responder, props) {
16208 currentHookNameInDev = 'useResponder';
16209 updateHookTypesDev();
16210 return createDeprecatedResponderListener(responder, props);
16211 },
16212 useDeferredValue: function (value, config) {
16213 currentHookNameInDev = 'useDeferredValue';
16214 updateHookTypesDev();
16215 return rerenderDeferredValue(value, config);
16216 },
16217 useTransition: function (config) {
16218 currentHookNameInDev = 'useTransition';
16219 updateHookTypesDev();
16220 return rerenderTransition(config);
16221 }
16222 };
16223 InvalidNestedHooksDispatcherOnMountInDEV = {
16224 readContext: function (context, observedBits) {
16225 warnInvalidContextAccess();
16226 return readContext(context, observedBits);
16227 },
16228 useCallback: function (callback, deps) {
16229 currentHookNameInDev = 'useCallback';
16230 warnInvalidHookAccess();
16231 mountHookTypesDev();
16232 return mountCallback(callback, deps);
16233 },
16234 useContext: function (context, observedBits) {
16235 currentHookNameInDev = 'useContext';
16236 warnInvalidHookAccess();
16237 mountHookTypesDev();
16238 return readContext(context, observedBits);
16239 },
16240 useEffect: function (create, deps) {
16241 currentHookNameInDev = 'useEffect';
16242 warnInvalidHookAccess();
16243 mountHookTypesDev();
16244 return mountEffect(create, deps);
16245 },
16246 useImperativeHandle: function (ref, create, deps) {
16247 currentHookNameInDev = 'useImperativeHandle';
16248 warnInvalidHookAccess();
16249 mountHookTypesDev();
16250 return mountImperativeHandle(ref, create, deps);
16251 },
16252 useLayoutEffect: function (create, deps) {
16253 currentHookNameInDev = 'useLayoutEffect';
16254 warnInvalidHookAccess();
16255 mountHookTypesDev();
16256 return mountLayoutEffect(create, deps);
16257 },
16258 useMemo: function (create, deps) {
16259 currentHookNameInDev = 'useMemo';
16260 warnInvalidHookAccess();
16261 mountHookTypesDev();
16262 var prevDispatcher = ReactCurrentDispatcher.current;
16263 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV;
16264
16265 try {
16266 return mountMemo(create, deps);
16267 } finally {
16268 ReactCurrentDispatcher.current = prevDispatcher;
16269 }
16270 },
16271 useReducer: function (reducer, initialArg, init) {
16272 currentHookNameInDev = 'useReducer';
16273 warnInvalidHookAccess();
16274 mountHookTypesDev();
16275 var prevDispatcher = ReactCurrentDispatcher.current;
16276 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV;
16277
16278 try {
16279 return mountReducer(reducer, initialArg, init);
16280 } finally {
16281 ReactCurrentDispatcher.current = prevDispatcher;
16282 }
16283 },
16284 useRef: function (initialValue) {
16285 currentHookNameInDev = 'useRef';
16286 warnInvalidHookAccess();
16287 mountHookTypesDev();
16288 return mountRef(initialValue);
16289 },
16290 useState: function (initialState) {
16291 currentHookNameInDev = 'useState';
16292 warnInvalidHookAccess();
16293 mountHookTypesDev();
16294 var prevDispatcher = ReactCurrentDispatcher.current;
16295 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV;
16296
16297 try {
16298 return mountState(initialState);
16299 } finally {
16300 ReactCurrentDispatcher.current = prevDispatcher;
16301 }
16302 },
16303 useDebugValue: function (value, formatterFn) {
16304 currentHookNameInDev = 'useDebugValue';
16305 warnInvalidHookAccess();
16306 mountHookTypesDev();
16307 return mountDebugValue();
16308 },
16309 useResponder: function (responder, props) {
16310 currentHookNameInDev = 'useResponder';
16311 warnInvalidHookAccess();
16312 mountHookTypesDev();
16313 return createDeprecatedResponderListener(responder, props);
16314 },
16315 useDeferredValue: function (value, config) {
16316 currentHookNameInDev = 'useDeferredValue';
16317 warnInvalidHookAccess();
16318 mountHookTypesDev();
16319 return mountDeferredValue(value, config);
16320 },
16321 useTransition: function (config) {
16322 currentHookNameInDev = 'useTransition';
16323 warnInvalidHookAccess();
16324 mountHookTypesDev();
16325 return mountTransition(config);
16326 }
16327 };
16328 InvalidNestedHooksDispatcherOnUpdateInDEV = {
16329 readContext: function (context, observedBits) {
16330 warnInvalidContextAccess();
16331 return readContext(context, observedBits);
16332 },
16333 useCallback: function (callback, deps) {
16334 currentHookNameInDev = 'useCallback';
16335 warnInvalidHookAccess();
16336 updateHookTypesDev();
16337 return updateCallback(callback, deps);
16338 },
16339 useContext: function (context, observedBits) {
16340 currentHookNameInDev = 'useContext';
16341 warnInvalidHookAccess();
16342 updateHookTypesDev();
16343 return readContext(context, observedBits);
16344 },
16345 useEffect: function (create, deps) {
16346 currentHookNameInDev = 'useEffect';
16347 warnInvalidHookAccess();
16348 updateHookTypesDev();
16349 return updateEffect(create, deps);
16350 },
16351 useImperativeHandle: function (ref, create, deps) {
16352 currentHookNameInDev = 'useImperativeHandle';
16353 warnInvalidHookAccess();
16354 updateHookTypesDev();
16355 return updateImperativeHandle(ref, create, deps);
16356 },
16357 useLayoutEffect: function (create, deps) {
16358 currentHookNameInDev = 'useLayoutEffect';
16359 warnInvalidHookAccess();
16360 updateHookTypesDev();
16361 return updateLayoutEffect(create, deps);
16362 },
16363 useMemo: function (create, deps) {
16364 currentHookNameInDev = 'useMemo';
16365 warnInvalidHookAccess();
16366 updateHookTypesDev();
16367 var prevDispatcher = ReactCurrentDispatcher.current;
16368 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
16369
16370 try {
16371 return updateMemo(create, deps);
16372 } finally {
16373 ReactCurrentDispatcher.current = prevDispatcher;
16374 }
16375 },
16376 useReducer: function (reducer, initialArg, init) {
16377 currentHookNameInDev = 'useReducer';
16378 warnInvalidHookAccess();
16379 updateHookTypesDev();
16380 var prevDispatcher = ReactCurrentDispatcher.current;
16381 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
16382
16383 try {
16384 return updateReducer(reducer, initialArg, init);
16385 } finally {
16386 ReactCurrentDispatcher.current = prevDispatcher;
16387 }
16388 },
16389 useRef: function (initialValue) {
16390 currentHookNameInDev = 'useRef';
16391 warnInvalidHookAccess();
16392 updateHookTypesDev();
16393 return updateRef();
16394 },
16395 useState: function (initialState) {
16396 currentHookNameInDev = 'useState';
16397 warnInvalidHookAccess();
16398 updateHookTypesDev();
16399 var prevDispatcher = ReactCurrentDispatcher.current;
16400 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
16401
16402 try {
16403 return updateState(initialState);
16404 } finally {
16405 ReactCurrentDispatcher.current = prevDispatcher;
16406 }
16407 },
16408 useDebugValue: function (value, formatterFn) {
16409 currentHookNameInDev = 'useDebugValue';
16410 warnInvalidHookAccess();
16411 updateHookTypesDev();
16412 return updateDebugValue();
16413 },
16414 useResponder: function (responder, props) {
16415 currentHookNameInDev = 'useResponder';
16416 warnInvalidHookAccess();
16417 updateHookTypesDev();
16418 return createDeprecatedResponderListener(responder, props);
16419 },
16420 useDeferredValue: function (value, config) {
16421 currentHookNameInDev = 'useDeferredValue';
16422 warnInvalidHookAccess();
16423 updateHookTypesDev();
16424 return updateDeferredValue(value, config);
16425 },
16426 useTransition: function (config) {
16427 currentHookNameInDev = 'useTransition';
16428 warnInvalidHookAccess();
16429 updateHookTypesDev();
16430 return updateTransition(config);
16431 }
16432 };
16433 InvalidNestedHooksDispatcherOnRerenderInDEV = {
16434 readContext: function (context, observedBits) {
16435 warnInvalidContextAccess();
16436 return readContext(context, observedBits);
16437 },
16438 useCallback: function (callback, deps) {
16439 currentHookNameInDev = 'useCallback';
16440 warnInvalidHookAccess();
16441 updateHookTypesDev();
16442 return updateCallback(callback, deps);
16443 },
16444 useContext: function (context, observedBits) {
16445 currentHookNameInDev = 'useContext';
16446 warnInvalidHookAccess();
16447 updateHookTypesDev();
16448 return readContext(context, observedBits);
16449 },
16450 useEffect: function (create, deps) {
16451 currentHookNameInDev = 'useEffect';
16452 warnInvalidHookAccess();
16453 updateHookTypesDev();
16454 return updateEffect(create, deps);
16455 },
16456 useImperativeHandle: function (ref, create, deps) {
16457 currentHookNameInDev = 'useImperativeHandle';
16458 warnInvalidHookAccess();
16459 updateHookTypesDev();
16460 return updateImperativeHandle(ref, create, deps);
16461 },
16462 useLayoutEffect: function (create, deps) {
16463 currentHookNameInDev = 'useLayoutEffect';
16464 warnInvalidHookAccess();
16465 updateHookTypesDev();
16466 return updateLayoutEffect(create, deps);
16467 },
16468 useMemo: function (create, deps) {
16469 currentHookNameInDev = 'useMemo';
16470 warnInvalidHookAccess();
16471 updateHookTypesDev();
16472 var prevDispatcher = ReactCurrentDispatcher.current;
16473 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
16474
16475 try {
16476 return updateMemo(create, deps);
16477 } finally {
16478 ReactCurrentDispatcher.current = prevDispatcher;
16479 }
16480 },
16481 useReducer: function (reducer, initialArg, init) {
16482 currentHookNameInDev = 'useReducer';
16483 warnInvalidHookAccess();
16484 updateHookTypesDev();
16485 var prevDispatcher = ReactCurrentDispatcher.current;
16486 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
16487
16488 try {
16489 return rerenderReducer(reducer, initialArg, init);
16490 } finally {
16491 ReactCurrentDispatcher.current = prevDispatcher;
16492 }
16493 },
16494 useRef: function (initialValue) {
16495 currentHookNameInDev = 'useRef';
16496 warnInvalidHookAccess();
16497 updateHookTypesDev();
16498 return updateRef();
16499 },
16500 useState: function (initialState) {
16501 currentHookNameInDev = 'useState';
16502 warnInvalidHookAccess();
16503 updateHookTypesDev();
16504 var prevDispatcher = ReactCurrentDispatcher.current;
16505 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
16506
16507 try {
16508 return rerenderState(initialState);
16509 } finally {
16510 ReactCurrentDispatcher.current = prevDispatcher;
16511 }
16512 },
16513 useDebugValue: function (value, formatterFn) {
16514 currentHookNameInDev = 'useDebugValue';
16515 warnInvalidHookAccess();
16516 updateHookTypesDev();
16517 return updateDebugValue();
16518 },
16519 useResponder: function (responder, props) {
16520 currentHookNameInDev = 'useResponder';
16521 warnInvalidHookAccess();
16522 updateHookTypesDev();
16523 return createDeprecatedResponderListener(responder, props);
16524 },
16525 useDeferredValue: function (value, config) {
16526 currentHookNameInDev = 'useDeferredValue';
16527 warnInvalidHookAccess();
16528 updateHookTypesDev();
16529 return rerenderDeferredValue(value, config);
16530 },
16531 useTransition: function (config) {
16532 currentHookNameInDev = 'useTransition';
16533 warnInvalidHookAccess();
16534 updateHookTypesDev();
16535 return rerenderTransition(config);
16536 }
16537 };
16538 }
16539
16540 var now$1 = unstable_now;
16541 var commitTime = 0;
16542 var profilerStartTime = -1;
16543
16544 function getCommitTime() {
16545 return commitTime;
16546 }
16547
16548 function recordCommitTime() {
16549
16550 commitTime = now$1();
16551 }
16552
16553 function startProfilerTimer(fiber) {
16554
16555 profilerStartTime = now$1();
16556
16557 if (fiber.actualStartTime < 0) {
16558 fiber.actualStartTime = now$1();
16559 }
16560 }
16561
16562 function stopProfilerTimerIfRunning(fiber) {
16563
16564 profilerStartTime = -1;
16565 }
16566
16567 function stopProfilerTimerIfRunningAndRecordDelta(fiber, overrideBaseTime) {
16568
16569 if (profilerStartTime >= 0) {
16570 var elapsedTime = now$1() - profilerStartTime;
16571 fiber.actualDuration += elapsedTime;
16572
16573 if (overrideBaseTime) {
16574 fiber.selfBaseDuration = elapsedTime;
16575 }
16576
16577 profilerStartTime = -1;
16578 }
16579 }
16580
16581 // This may have been an insertion or a hydration.
16582
16583 var hydrationParentFiber = null;
16584 var nextHydratableInstance = null;
16585 var isHydrating = false;
16586
16587 function enterHydrationState(fiber) {
16588
16589 var parentInstance = fiber.stateNode.containerInfo;
16590 nextHydratableInstance = getFirstHydratableChild(parentInstance);
16591 hydrationParentFiber = fiber;
16592 isHydrating = true;
16593 return true;
16594 }
16595
16596 function deleteHydratableInstance(returnFiber, instance) {
16597 {
16598 switch (returnFiber.tag) {
16599 case HostRoot:
16600 didNotHydrateContainerInstance(returnFiber.stateNode.containerInfo, instance);
16601 break;
16602
16603 case HostComponent:
16604 didNotHydrateInstance(returnFiber.type, returnFiber.memoizedProps, returnFiber.stateNode, instance);
16605 break;
16606 }
16607 }
16608
16609 var childToDelete = createFiberFromHostInstanceForDeletion();
16610 childToDelete.stateNode = instance;
16611 childToDelete.return = returnFiber;
16612 childToDelete.effectTag = Deletion; // This might seem like it belongs on progressedFirstDeletion. However,
16613 // these children are not part of the reconciliation list of children.
16614 // Even if we abort and rereconcile the children, that will try to hydrate
16615 // again and the nodes are still in the host tree so these will be
16616 // recreated.
16617
16618 if (returnFiber.lastEffect !== null) {
16619 returnFiber.lastEffect.nextEffect = childToDelete;
16620 returnFiber.lastEffect = childToDelete;
16621 } else {
16622 returnFiber.firstEffect = returnFiber.lastEffect = childToDelete;
16623 }
16624 }
16625
16626 function insertNonHydratedInstance(returnFiber, fiber) {
16627 fiber.effectTag = fiber.effectTag & ~Hydrating | Placement;
16628
16629 {
16630 switch (returnFiber.tag) {
16631 case HostRoot:
16632 {
16633 var parentContainer = returnFiber.stateNode.containerInfo;
16634
16635 switch (fiber.tag) {
16636 case HostComponent:
16637 var type = fiber.type;
16638 var props = fiber.pendingProps;
16639 didNotFindHydratableContainerInstance(parentContainer, type);
16640 break;
16641
16642 case HostText:
16643 var text = fiber.pendingProps;
16644 didNotFindHydratableContainerTextInstance(parentContainer, text);
16645 break;
16646 }
16647
16648 break;
16649 }
16650
16651 case HostComponent:
16652 {
16653 var parentType = returnFiber.type;
16654 var parentProps = returnFiber.memoizedProps;
16655 var parentInstance = returnFiber.stateNode;
16656
16657 switch (fiber.tag) {
16658 case HostComponent:
16659 var _type = fiber.type;
16660 var _props = fiber.pendingProps;
16661 didNotFindHydratableInstance(parentType, parentProps, parentInstance, _type);
16662 break;
16663
16664 case HostText:
16665 var _text = fiber.pendingProps;
16666 didNotFindHydratableTextInstance(parentType, parentProps, parentInstance, _text);
16667 break;
16668
16669 case SuspenseComponent:
16670 didNotFindHydratableSuspenseInstance(parentType, parentProps);
16671 break;
16672 }
16673
16674 break;
16675 }
16676
16677 default:
16678 return;
16679 }
16680 }
16681 }
16682
16683 function tryHydrate(fiber, nextInstance) {
16684 switch (fiber.tag) {
16685 case HostComponent:
16686 {
16687 var type = fiber.type;
16688 var props = fiber.pendingProps;
16689 var instance = canHydrateInstance(nextInstance, type);
16690
16691 if (instance !== null) {
16692 fiber.stateNode = instance;
16693 return true;
16694 }
16695
16696 return false;
16697 }
16698
16699 case HostText:
16700 {
16701 var text = fiber.pendingProps;
16702 var textInstance = canHydrateTextInstance(nextInstance, text);
16703
16704 if (textInstance !== null) {
16705 fiber.stateNode = textInstance;
16706 return true;
16707 }
16708
16709 return false;
16710 }
16711
16712 case SuspenseComponent:
16713 {
16714
16715 return false;
16716 }
16717
16718 default:
16719 return false;
16720 }
16721 }
16722
16723 function tryToClaimNextHydratableInstance(fiber) {
16724 if (!isHydrating) {
16725 return;
16726 }
16727
16728 var nextInstance = nextHydratableInstance;
16729
16730 if (!nextInstance) {
16731 // Nothing to hydrate. Make it an insertion.
16732 insertNonHydratedInstance(hydrationParentFiber, fiber);
16733 isHydrating = false;
16734 hydrationParentFiber = fiber;
16735 return;
16736 }
16737
16738 var firstAttemptedInstance = nextInstance;
16739
16740 if (!tryHydrate(fiber, nextInstance)) {
16741 // If we can't hydrate this instance let's try the next one.
16742 // We use this as a heuristic. It's based on intuition and not data so it
16743 // might be flawed or unnecessary.
16744 nextInstance = getNextHydratableSibling(firstAttemptedInstance);
16745
16746 if (!nextInstance || !tryHydrate(fiber, nextInstance)) {
16747 // Nothing to hydrate. Make it an insertion.
16748 insertNonHydratedInstance(hydrationParentFiber, fiber);
16749 isHydrating = false;
16750 hydrationParentFiber = fiber;
16751 return;
16752 } // We matched the next one, we'll now assume that the first one was
16753 // superfluous and we'll delete it. Since we can't eagerly delete it
16754 // we'll have to schedule a deletion. To do that, this node needs a dummy
16755 // fiber associated with it.
16756
16757
16758 deleteHydratableInstance(hydrationParentFiber, firstAttemptedInstance);
16759 }
16760
16761 hydrationParentFiber = fiber;
16762 nextHydratableInstance = getFirstHydratableChild(nextInstance);
16763 }
16764
16765 function prepareToHydrateHostInstance(fiber, rootContainerInstance, hostContext) {
16766
16767 var instance = fiber.stateNode;
16768 var updatePayload = hydrateInstance(instance, fiber.type, fiber.memoizedProps, rootContainerInstance, hostContext, fiber); // TODO: Type this specific to this type of component.
16769
16770 fiber.updateQueue = updatePayload; // If the update payload indicates that there is a change or if there
16771 // is a new ref we mark this as an update.
16772
16773 if (updatePayload !== null) {
16774 return true;
16775 }
16776
16777 return false;
16778 }
16779
16780 function prepareToHydrateHostTextInstance(fiber) {
16781
16782 var textInstance = fiber.stateNode;
16783 var textContent = fiber.memoizedProps;
16784 var shouldUpdate = hydrateTextInstance(textInstance, textContent, fiber);
16785
16786 {
16787 if (shouldUpdate) {
16788 // We assume that prepareToHydrateHostTextInstance is called in a context where the
16789 // hydration parent is the parent host component of this host text.
16790 var returnFiber = hydrationParentFiber;
16791
16792 if (returnFiber !== null) {
16793 switch (returnFiber.tag) {
16794 case HostRoot:
16795 {
16796 var parentContainer = returnFiber.stateNode.containerInfo;
16797 didNotMatchHydratedContainerTextInstance(parentContainer, textInstance, textContent);
16798 break;
16799 }
16800
16801 case HostComponent:
16802 {
16803 var parentType = returnFiber.type;
16804 var parentProps = returnFiber.memoizedProps;
16805 var parentInstance = returnFiber.stateNode;
16806 didNotMatchHydratedTextInstance(parentType, parentProps, parentInstance, textInstance, textContent);
16807 break;
16808 }
16809 }
16810 }
16811 }
16812 }
16813
16814 return shouldUpdate;
16815 }
16816
16817 function skipPastDehydratedSuspenseInstance(fiber) {
16818
16819 var suspenseState = fiber.memoizedState;
16820 var suspenseInstance = suspenseState !== null ? suspenseState.dehydrated : null;
16821
16822 if (!suspenseInstance) {
16823 {
16824 throw Error( "Expected to have a hydrated suspense instance. This error is likely caused by a bug in React. Please file an issue." );
16825 }
16826 }
16827
16828 return getNextHydratableInstanceAfterSuspenseInstance(suspenseInstance);
16829 }
16830
16831 function popToNextHostParent(fiber) {
16832 var parent = fiber.return;
16833
16834 while (parent !== null && parent.tag !== HostComponent && parent.tag !== HostRoot && parent.tag !== SuspenseComponent) {
16835 parent = parent.return;
16836 }
16837
16838 hydrationParentFiber = parent;
16839 }
16840
16841 function popHydrationState(fiber) {
16842
16843 if (fiber !== hydrationParentFiber) {
16844 // We're deeper than the current hydration context, inside an inserted
16845 // tree.
16846 return false;
16847 }
16848
16849 if (!isHydrating) {
16850 // If we're not currently hydrating but we're in a hydration context, then
16851 // we were an insertion and now need to pop up reenter hydration of our
16852 // siblings.
16853 popToNextHostParent(fiber);
16854 isHydrating = true;
16855 return false;
16856 }
16857
16858 var type = fiber.type; // If we have any remaining hydratable nodes, we need to delete them now.
16859 // We only do this deeper than head and body since they tend to have random
16860 // other nodes in them. We also ignore components with pure text content in
16861 // side of them.
16862 // TODO: Better heuristic.
16863
16864 if (fiber.tag !== HostComponent || type !== 'head' && type !== 'body' && !shouldSetTextContent(type, fiber.memoizedProps)) {
16865 var nextInstance = nextHydratableInstance;
16866
16867 while (nextInstance) {
16868 deleteHydratableInstance(fiber, nextInstance);
16869 nextInstance = getNextHydratableSibling(nextInstance);
16870 }
16871 }
16872
16873 popToNextHostParent(fiber);
16874
16875 if (fiber.tag === SuspenseComponent) {
16876 nextHydratableInstance = skipPastDehydratedSuspenseInstance(fiber);
16877 } else {
16878 nextHydratableInstance = hydrationParentFiber ? getNextHydratableSibling(fiber.stateNode) : null;
16879 }
16880
16881 return true;
16882 }
16883
16884 function resetHydrationState() {
16885
16886 hydrationParentFiber = null;
16887 nextHydratableInstance = null;
16888 isHydrating = false;
16889 }
16890
16891 var ReactCurrentOwner$1 = ReactSharedInternals.ReactCurrentOwner;
16892 var didReceiveUpdate = false;
16893 var didWarnAboutBadClass;
16894 var didWarnAboutModulePatternComponent;
16895 var didWarnAboutContextTypeOnFunctionComponent;
16896 var didWarnAboutGetDerivedStateOnFunctionComponent;
16897 var didWarnAboutFunctionRefs;
16898 var didWarnAboutReassigningProps;
16899 var didWarnAboutMaxDuration;
16900 var didWarnAboutRevealOrder;
16901 var didWarnAboutTailOptions;
16902
16903 {
16904 didWarnAboutBadClass = {};
16905 didWarnAboutModulePatternComponent = {};
16906 didWarnAboutContextTypeOnFunctionComponent = {};
16907 didWarnAboutGetDerivedStateOnFunctionComponent = {};
16908 didWarnAboutFunctionRefs = {};
16909 didWarnAboutReassigningProps = false;
16910 didWarnAboutMaxDuration = false;
16911 didWarnAboutRevealOrder = {};
16912 didWarnAboutTailOptions = {};
16913 }
16914
16915 function reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime) {
16916 if (current === null) {
16917 // If this is a fresh new component that hasn't been rendered yet, we
16918 // won't update its child set by applying minimal side-effects. Instead,
16919 // we will add them all to the child before it gets rendered. That means
16920 // we can optimize this reconciliation pass by not tracking side-effects.
16921 workInProgress.child = mountChildFibers(workInProgress, null, nextChildren, renderExpirationTime);
16922 } else {
16923 // If the current child is the same as the work in progress, it means that
16924 // we haven't yet started any work on these children. Therefore, we use
16925 // the clone algorithm to create a copy of all the current children.
16926 // If we had any progressed work already, that is invalid at this point so
16927 // let's throw it out.
16928 workInProgress.child = reconcileChildFibers(workInProgress, current.child, nextChildren, renderExpirationTime);
16929 }
16930 }
16931
16932 function forceUnmountCurrentAndReconcile(current, workInProgress, nextChildren, renderExpirationTime) {
16933 // This function is fork of reconcileChildren. It's used in cases where we
16934 // want to reconcile without matching against the existing set. This has the
16935 // effect of all current children being unmounted; even if the type and key
16936 // are the same, the old child is unmounted and a new child is created.
16937 //
16938 // To do this, we're going to go through the reconcile algorithm twice. In
16939 // the first pass, we schedule a deletion for all the current children by
16940 // passing null.
16941 workInProgress.child = reconcileChildFibers(workInProgress, current.child, null, renderExpirationTime); // In the second pass, we mount the new children. The trick here is that we
16942 // pass null in place of where we usually pass the current child set. This has
16943 // the effect of remounting all children regardless of whether their
16944 // identities match.
16945
16946 workInProgress.child = reconcileChildFibers(workInProgress, null, nextChildren, renderExpirationTime);
16947 }
16948
16949 function updateForwardRef(current, workInProgress, Component, nextProps, renderExpirationTime) {
16950 // TODO: current can be non-null here even if the component
16951 // hasn't yet mounted. This happens after the first render suspends.
16952 // We'll need to figure out if this is fine or can cause issues.
16953 {
16954 if (workInProgress.type !== workInProgress.elementType) {
16955 // Lazy component props can't be validated in createElement
16956 // because they're only guaranteed to be resolved here.
16957 var innerPropTypes = Component.propTypes;
16958
16959 if (innerPropTypes) {
16960 checkPropTypes_1(innerPropTypes, nextProps, // Resolved props
16961 'prop', getComponentName(Component), getCurrentFiberStackInDev);
16962 }
16963 }
16964 }
16965
16966 var render = Component.render;
16967 var ref = workInProgress.ref; // The rest is a fork of updateFunctionComponent
16968
16969 var nextChildren;
16970 prepareToReadContext(workInProgress, renderExpirationTime);
16971
16972 {
16973 ReactCurrentOwner$1.current = workInProgress;
16974 setCurrentPhase('render');
16975 nextChildren = renderWithHooks(current, workInProgress, render, nextProps, ref, renderExpirationTime);
16976
16977 if ( workInProgress.mode & StrictMode) {
16978 // Only double-render components with Hooks
16979 if (workInProgress.memoizedState !== null) {
16980 nextChildren = renderWithHooks(current, workInProgress, render, nextProps, ref, renderExpirationTime);
16981 }
16982 }
16983
16984 setCurrentPhase(null);
16985 }
16986
16987 if (current !== null && !didReceiveUpdate) {
16988 bailoutHooks(current, workInProgress, renderExpirationTime);
16989 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderExpirationTime);
16990 } // React DevTools reads this flag.
16991
16992
16993 workInProgress.effectTag |= PerformedWork;
16994 reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime);
16995 return workInProgress.child;
16996 }
16997
16998 function updateMemoComponent(current, workInProgress, Component, nextProps, updateExpirationTime, renderExpirationTime) {
16999 if (current === null) {
17000 var type = Component.type;
17001
17002 if (isSimpleFunctionComponent(type) && Component.compare === null && // SimpleMemoComponent codepath doesn't resolve outer props either.
17003 Component.defaultProps === undefined) {
17004 var resolvedType = type;
17005
17006 {
17007 resolvedType = resolveFunctionForHotReloading(type);
17008 } // If this is a plain function component without default props,
17009 // and with only the default shallow comparison, we upgrade it
17010 // to a SimpleMemoComponent to allow fast path updates.
17011
17012
17013 workInProgress.tag = SimpleMemoComponent;
17014 workInProgress.type = resolvedType;
17015
17016 {
17017 validateFunctionComponentInDev(workInProgress, type);
17018 }
17019
17020 return updateSimpleMemoComponent(current, workInProgress, resolvedType, nextProps, updateExpirationTime, renderExpirationTime);
17021 }
17022
17023 {
17024 var innerPropTypes = type.propTypes;
17025
17026 if (innerPropTypes) {
17027 // Inner memo component props aren't currently validated in createElement.
17028 // We could move it there, but we'd still need this for lazy code path.
17029 checkPropTypes_1(innerPropTypes, nextProps, // Resolved props
17030 'prop', getComponentName(type), getCurrentFiberStackInDev);
17031 }
17032 }
17033
17034 var child = createFiberFromTypeAndProps(Component.type, null, nextProps, null, workInProgress.mode, renderExpirationTime);
17035 child.ref = workInProgress.ref;
17036 child.return = workInProgress;
17037 workInProgress.child = child;
17038 return child;
17039 }
17040
17041 {
17042 var _type = Component.type;
17043 var _innerPropTypes = _type.propTypes;
17044
17045 if (_innerPropTypes) {
17046 // Inner memo component props aren't currently validated in createElement.
17047 // We could move it there, but we'd still need this for lazy code path.
17048 checkPropTypes_1(_innerPropTypes, nextProps, // Resolved props
17049 'prop', getComponentName(_type), getCurrentFiberStackInDev);
17050 }
17051 }
17052
17053 var currentChild = current.child; // This is always exactly one child
17054
17055 if (updateExpirationTime < renderExpirationTime) {
17056 // This will be the props with resolved defaultProps,
17057 // unlike current.memoizedProps which will be the unresolved ones.
17058 var prevProps = currentChild.memoizedProps; // Default to shallow comparison
17059
17060 var compare = Component.compare;
17061 compare = compare !== null ? compare : shallowEqual;
17062
17063 if (compare(prevProps, nextProps) && current.ref === workInProgress.ref) {
17064 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderExpirationTime);
17065 }
17066 } // React DevTools reads this flag.
17067
17068
17069 workInProgress.effectTag |= PerformedWork;
17070 var newChild = createWorkInProgress(currentChild, nextProps);
17071 newChild.ref = workInProgress.ref;
17072 newChild.return = workInProgress;
17073 workInProgress.child = newChild;
17074 return newChild;
17075 }
17076
17077 function updateSimpleMemoComponent(current, workInProgress, Component, nextProps, updateExpirationTime, renderExpirationTime) {
17078 // TODO: current can be non-null here even if the component
17079 // hasn't yet mounted. This happens when the inner render suspends.
17080 // We'll need to figure out if this is fine or can cause issues.
17081 {
17082 if (workInProgress.type !== workInProgress.elementType) {
17083 // Lazy component props can't be validated in createElement
17084 // because they're only guaranteed to be resolved here.
17085 var outerMemoType = workInProgress.elementType;
17086
17087 if (outerMemoType.$$typeof === REACT_LAZY_TYPE) {
17088 // We warn when you define propTypes on lazy()
17089 // so let's just skip over it to find memo() outer wrapper.
17090 // Inner props for memo are validated later.
17091 outerMemoType = refineResolvedLazyComponent(outerMemoType);
17092 }
17093
17094 var outerPropTypes = outerMemoType && outerMemoType.propTypes;
17095
17096 if (outerPropTypes) {
17097 checkPropTypes_1(outerPropTypes, nextProps, // Resolved (SimpleMemoComponent has no defaultProps)
17098 'prop', getComponentName(outerMemoType), getCurrentFiberStackInDev);
17099 } // Inner propTypes will be validated in the function component path.
17100
17101 }
17102 }
17103
17104 if (current !== null) {
17105 var prevProps = current.memoizedProps;
17106
17107 if (shallowEqual(prevProps, nextProps) && current.ref === workInProgress.ref && ( // Prevent bailout if the implementation changed due to hot reload.
17108 workInProgress.type === current.type )) {
17109 didReceiveUpdate = false;
17110
17111 if (updateExpirationTime < renderExpirationTime) {
17112 // The pending update priority was cleared at the beginning of
17113 // beginWork. We're about to bail out, but there might be additional
17114 // updates at a lower priority. Usually, the priority level of the
17115 // remaining updates is accumlated during the evaluation of the
17116 // component (i.e. when processing the update queue). But since since
17117 // we're bailing out early *without* evaluating the component, we need
17118 // to account for it here, too. Reset to the value of the current fiber.
17119 // NOTE: This only applies to SimpleMemoComponent, not MemoComponent,
17120 // because a MemoComponent fiber does not have hooks or an update queue;
17121 // rather, it wraps around an inner component, which may or may not
17122 // contains hooks.
17123 // TODO: Move the reset at in beginWork out of the common path so that
17124 // this is no longer necessary.
17125 workInProgress.expirationTime = current.expirationTime;
17126 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderExpirationTime);
17127 }
17128 }
17129 }
17130
17131 return updateFunctionComponent(current, workInProgress, Component, nextProps, renderExpirationTime);
17132 }
17133
17134 function updateFragment(current, workInProgress, renderExpirationTime) {
17135 var nextChildren = workInProgress.pendingProps;
17136 reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime);
17137 return workInProgress.child;
17138 }
17139
17140 function updateMode(current, workInProgress, renderExpirationTime) {
17141 var nextChildren = workInProgress.pendingProps.children;
17142 reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime);
17143 return workInProgress.child;
17144 }
17145
17146 function updateProfiler(current, workInProgress, renderExpirationTime) {
17147 {
17148 workInProgress.effectTag |= Update;
17149 }
17150
17151 var nextProps = workInProgress.pendingProps;
17152 var nextChildren = nextProps.children;
17153 reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime);
17154 return workInProgress.child;
17155 }
17156
17157 function markRef(current, workInProgress) {
17158 var ref = workInProgress.ref;
17159
17160 if (current === null && ref !== null || current !== null && current.ref !== ref) {
17161 // Schedule a Ref effect
17162 workInProgress.effectTag |= Ref;
17163 }
17164 }
17165
17166 function updateFunctionComponent(current, workInProgress, Component, nextProps, renderExpirationTime) {
17167 {
17168 if (workInProgress.type !== workInProgress.elementType) {
17169 // Lazy component props can't be validated in createElement
17170 // because they're only guaranteed to be resolved here.
17171 var innerPropTypes = Component.propTypes;
17172
17173 if (innerPropTypes) {
17174 checkPropTypes_1(innerPropTypes, nextProps, // Resolved props
17175 'prop', getComponentName(Component), getCurrentFiberStackInDev);
17176 }
17177 }
17178 }
17179
17180 var context;
17181
17182 {
17183 var unmaskedContext = getUnmaskedContext(workInProgress, Component, true);
17184 context = getMaskedContext(workInProgress, unmaskedContext);
17185 }
17186
17187 var nextChildren;
17188 prepareToReadContext(workInProgress, renderExpirationTime);
17189
17190 {
17191 ReactCurrentOwner$1.current = workInProgress;
17192 setCurrentPhase('render');
17193 nextChildren = renderWithHooks(current, workInProgress, Component, nextProps, context, renderExpirationTime);
17194
17195 if ( workInProgress.mode & StrictMode) {
17196 // Only double-render components with Hooks
17197 if (workInProgress.memoizedState !== null) {
17198 nextChildren = renderWithHooks(current, workInProgress, Component, nextProps, context, renderExpirationTime);
17199 }
17200 }
17201
17202 setCurrentPhase(null);
17203 }
17204
17205 if (current !== null && !didReceiveUpdate) {
17206 bailoutHooks(current, workInProgress, renderExpirationTime);
17207 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderExpirationTime);
17208 } // React DevTools reads this flag.
17209
17210
17211 workInProgress.effectTag |= PerformedWork;
17212 reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime);
17213 return workInProgress.child;
17214 }
17215
17216 function updateClassComponent(current, workInProgress, Component, nextProps, renderExpirationTime) {
17217 {
17218 if (workInProgress.type !== workInProgress.elementType) {
17219 // Lazy component props can't be validated in createElement
17220 // because they're only guaranteed to be resolved here.
17221 var innerPropTypes = Component.propTypes;
17222
17223 if (innerPropTypes) {
17224 checkPropTypes_1(innerPropTypes, nextProps, // Resolved props
17225 'prop', getComponentName(Component), getCurrentFiberStackInDev);
17226 }
17227 }
17228 } // Push context providers early to prevent context stack mismatches.
17229 // During mounting we don't know the child context yet as the instance doesn't exist.
17230 // We will invalidate the child context in finishClassComponent() right after rendering.
17231
17232
17233 var hasContext;
17234
17235 if (isContextProvider(Component)) {
17236 hasContext = true;
17237 pushContextProvider(workInProgress);
17238 } else {
17239 hasContext = false;
17240 }
17241
17242 prepareToReadContext(workInProgress, renderExpirationTime);
17243 var instance = workInProgress.stateNode;
17244 var shouldUpdate;
17245
17246 if (instance === null) {
17247 if (current !== null) {
17248 // A class component without an instance only mounts if it suspended
17249 // inside a non-concurrent tree, in an inconsistent state. We want to
17250 // treat it like a new mount, even though an empty version of it already
17251 // committed. Disconnect the alternate pointers.
17252 current.alternate = null;
17253 workInProgress.alternate = null; // Since this is conceptually a new fiber, schedule a Placement effect
17254
17255 workInProgress.effectTag |= Placement;
17256 } // In the initial pass we might need to construct the instance.
17257
17258
17259 constructClassInstance(workInProgress, Component, nextProps);
17260 mountClassInstance(workInProgress, Component, nextProps, renderExpirationTime);
17261 shouldUpdate = true;
17262 } else if (current === null) {
17263 // In a resume, we'll already have an instance we can reuse.
17264 shouldUpdate = resumeMountClassInstance(workInProgress, Component, nextProps, renderExpirationTime);
17265 } else {
17266 shouldUpdate = updateClassInstance(current, workInProgress, Component, nextProps, renderExpirationTime);
17267 }
17268
17269 var nextUnitOfWork = finishClassComponent(current, workInProgress, Component, shouldUpdate, hasContext, renderExpirationTime);
17270
17271 {
17272 var inst = workInProgress.stateNode;
17273
17274 if (inst.props !== nextProps) {
17275 if (!didWarnAboutReassigningProps) {
17276 error('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');
17277 }
17278
17279 didWarnAboutReassigningProps = true;
17280 }
17281 }
17282
17283 return nextUnitOfWork;
17284 }
17285
17286 function finishClassComponent(current, workInProgress, Component, shouldUpdate, hasContext, renderExpirationTime) {
17287 // Refs should update even if shouldComponentUpdate returns false
17288 markRef(current, workInProgress);
17289 var didCaptureError = (workInProgress.effectTag & DidCapture) !== NoEffect;
17290
17291 if (!shouldUpdate && !didCaptureError) {
17292 // Context providers should defer to sCU for rendering
17293 if (hasContext) {
17294 invalidateContextProvider(workInProgress, Component, false);
17295 }
17296
17297 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderExpirationTime);
17298 }
17299
17300 var instance = workInProgress.stateNode; // Rerender
17301
17302 ReactCurrentOwner$1.current = workInProgress;
17303 var nextChildren;
17304
17305 if (didCaptureError && typeof Component.getDerivedStateFromError !== 'function') {
17306 // If we captured an error, but getDerivedStateFromError is not defined,
17307 // unmount all the children. componentDidCatch will schedule an update to
17308 // re-render a fallback. This is temporary until we migrate everyone to
17309 // the new API.
17310 // TODO: Warn in a future release.
17311 nextChildren = null;
17312
17313 {
17314 stopProfilerTimerIfRunning();
17315 }
17316 } else {
17317 {
17318 setCurrentPhase('render');
17319 nextChildren = instance.render();
17320
17321 if ( workInProgress.mode & StrictMode) {
17322 instance.render();
17323 }
17324
17325 setCurrentPhase(null);
17326 }
17327 } // React DevTools reads this flag.
17328
17329
17330 workInProgress.effectTag |= PerformedWork;
17331
17332 if (current !== null && didCaptureError) {
17333 // If we're recovering from an error, reconcile without reusing any of
17334 // the existing children. Conceptually, the normal children and the children
17335 // that are shown on error are two different sets, so we shouldn't reuse
17336 // normal children even if their identities match.
17337 forceUnmountCurrentAndReconcile(current, workInProgress, nextChildren, renderExpirationTime);
17338 } else {
17339 reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime);
17340 } // Memoize state using the values we just used to render.
17341 // TODO: Restructure so we never read values from the instance.
17342
17343
17344 workInProgress.memoizedState = instance.state; // The context might have changed so we need to recalculate it.
17345
17346 if (hasContext) {
17347 invalidateContextProvider(workInProgress, Component, true);
17348 }
17349
17350 return workInProgress.child;
17351 }
17352
17353 function pushHostRootContext(workInProgress) {
17354 var root = workInProgress.stateNode;
17355
17356 if (root.pendingContext) {
17357 pushTopLevelContextObject(workInProgress, root.pendingContext, root.pendingContext !== root.context);
17358 } else if (root.context) {
17359 // Should always be set
17360 pushTopLevelContextObject(workInProgress, root.context, false);
17361 }
17362
17363 pushHostContainer(workInProgress, root.containerInfo);
17364 }
17365
17366 function updateHostRoot(current, workInProgress, renderExpirationTime) {
17367 pushHostRootContext(workInProgress);
17368 var updateQueue = workInProgress.updateQueue;
17369
17370 if (!(current !== null && updateQueue !== null)) {
17371 {
17372 throw 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." );
17373 }
17374 }
17375
17376 var nextProps = workInProgress.pendingProps;
17377 var prevState = workInProgress.memoizedState;
17378 var prevChildren = prevState !== null ? prevState.element : null;
17379 cloneUpdateQueue(current, workInProgress);
17380 processUpdateQueue(workInProgress, nextProps, null, renderExpirationTime);
17381 var nextState = workInProgress.memoizedState; // Caution: React DevTools currently depends on this property
17382 // being called "element".
17383
17384 var nextChildren = nextState.element;
17385
17386 if (nextChildren === prevChildren) {
17387 // If the state is the same as before, that's a bailout because we had
17388 // no work that expires at this time.
17389 resetHydrationState();
17390 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderExpirationTime);
17391 }
17392
17393 var root = workInProgress.stateNode;
17394
17395 if (root.hydrate && enterHydrationState(workInProgress)) {
17396 // If we don't have any current children this might be the first pass.
17397 // We always try to hydrate. If this isn't a hydration pass there won't
17398 // be any children to hydrate which is effectively the same thing as
17399 // not hydrating.
17400 var child = mountChildFibers(workInProgress, null, nextChildren, renderExpirationTime);
17401 workInProgress.child = child;
17402 var node = child;
17403
17404 while (node) {
17405 // Mark each child as hydrating. This is a fast path to know whether this
17406 // tree is part of a hydrating tree. This is used to determine if a child
17407 // node has fully mounted yet, and for scheduling event replaying.
17408 // Conceptually this is similar to Placement in that a new subtree is
17409 // inserted into the React tree here. It just happens to not need DOM
17410 // mutations because it already exists.
17411 node.effectTag = node.effectTag & ~Placement | Hydrating;
17412 node = node.sibling;
17413 }
17414 } else {
17415 // Otherwise reset hydration state in case we aborted and resumed another
17416 // root.
17417 reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime);
17418 resetHydrationState();
17419 }
17420
17421 return workInProgress.child;
17422 }
17423
17424 function updateHostComponent(current, workInProgress, renderExpirationTime) {
17425 pushHostContext(workInProgress);
17426
17427 if (current === null) {
17428 tryToClaimNextHydratableInstance(workInProgress);
17429 }
17430
17431 var type = workInProgress.type;
17432 var nextProps = workInProgress.pendingProps;
17433 var prevProps = current !== null ? current.memoizedProps : null;
17434 var nextChildren = nextProps.children;
17435 var isDirectTextChild = shouldSetTextContent(type, nextProps);
17436
17437 if (isDirectTextChild) {
17438 // We special case a direct text child of a host node. This is a common
17439 // case. We won't handle it as a reified child. We will instead handle
17440 // this in the host environment that also has access to this prop. That
17441 // avoids allocating another HostText fiber and traversing it.
17442 nextChildren = null;
17443 } else if (prevProps !== null && shouldSetTextContent(type, prevProps)) {
17444 // If we're switching from a direct text child to a normal child, or to
17445 // empty, we need to schedule the text content to be reset.
17446 workInProgress.effectTag |= ContentReset;
17447 }
17448
17449 markRef(current, workInProgress); // Check the host config to see if the children are offscreen/hidden.
17450
17451 if (workInProgress.mode & ConcurrentMode && renderExpirationTime !== Never && shouldDeprioritizeSubtree(type, nextProps)) {
17452 {
17453 markSpawnedWork(Never);
17454 } // Schedule this fiber to re-render at offscreen priority. Then bailout.
17455
17456
17457 workInProgress.expirationTime = workInProgress.childExpirationTime = Never;
17458 return null;
17459 }
17460
17461 reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime);
17462 return workInProgress.child;
17463 }
17464
17465 function updateHostText(current, workInProgress) {
17466 if (current === null) {
17467 tryToClaimNextHydratableInstance(workInProgress);
17468 } // Nothing to do here. This is terminal. We'll do the completion step
17469 // immediately after.
17470
17471
17472 return null;
17473 }
17474
17475 function mountLazyComponent(_current, workInProgress, elementType, updateExpirationTime, renderExpirationTime) {
17476 if (_current !== null) {
17477 // A lazy component only mounts if it suspended inside a non-
17478 // concurrent tree, in an inconsistent state. We want to treat it like
17479 // a new mount, even though an empty version of it already committed.
17480 // Disconnect the alternate pointers.
17481 _current.alternate = null;
17482 workInProgress.alternate = null; // Since this is conceptually a new fiber, schedule a Placement effect
17483
17484 workInProgress.effectTag |= Placement;
17485 }
17486
17487 var props = workInProgress.pendingProps; // We can't start a User Timing measurement with correct label yet.
17488 // Cancel and resume right after we know the tag.
17489
17490 cancelWorkTimer(workInProgress);
17491 var Component = readLazyComponentType(elementType); // Store the unwrapped component in the type.
17492
17493 workInProgress.type = Component;
17494 var resolvedTag = workInProgress.tag = resolveLazyComponentTag(Component);
17495 startWorkTimer(workInProgress);
17496 var resolvedProps = resolveDefaultProps(Component, props);
17497 var child;
17498
17499 switch (resolvedTag) {
17500 case FunctionComponent:
17501 {
17502 {
17503 validateFunctionComponentInDev(workInProgress, Component);
17504 workInProgress.type = Component = resolveFunctionForHotReloading(Component);
17505 }
17506
17507 child = updateFunctionComponent(null, workInProgress, Component, resolvedProps, renderExpirationTime);
17508 return child;
17509 }
17510
17511 case ClassComponent:
17512 {
17513 {
17514 workInProgress.type = Component = resolveClassForHotReloading(Component);
17515 }
17516
17517 child = updateClassComponent(null, workInProgress, Component, resolvedProps, renderExpirationTime);
17518 return child;
17519 }
17520
17521 case ForwardRef:
17522 {
17523 {
17524 workInProgress.type = Component = resolveForwardRefForHotReloading(Component);
17525 }
17526
17527 child = updateForwardRef(null, workInProgress, Component, resolvedProps, renderExpirationTime);
17528 return child;
17529 }
17530
17531 case MemoComponent:
17532 {
17533 {
17534 if (workInProgress.type !== workInProgress.elementType) {
17535 var outerPropTypes = Component.propTypes;
17536
17537 if (outerPropTypes) {
17538 checkPropTypes_1(outerPropTypes, resolvedProps, // Resolved for outer only
17539 'prop', getComponentName(Component), getCurrentFiberStackInDev);
17540 }
17541 }
17542 }
17543
17544 child = updateMemoComponent(null, workInProgress, Component, resolveDefaultProps(Component.type, resolvedProps), // The inner type can have defaults too
17545 updateExpirationTime, renderExpirationTime);
17546 return child;
17547 }
17548 }
17549
17550 var hint = '';
17551
17552 {
17553 if (Component !== null && typeof Component === 'object' && Component.$$typeof === REACT_LAZY_TYPE) {
17554 hint = ' Did you wrap a component in React.lazy() more than once?';
17555 }
17556 } // This message intentionally doesn't mention ForwardRef or MemoComponent
17557 // because the fact that it's a separate type of work is an
17558 // implementation detail.
17559
17560
17561 {
17562 {
17563 throw Error( "Element type is invalid. Received a promise that resolves to: " + Component + ". Lazy element type must resolve to a class or function." + hint );
17564 }
17565 }
17566 }
17567
17568 function mountIncompleteClassComponent(_current, workInProgress, Component, nextProps, renderExpirationTime) {
17569 if (_current !== null) {
17570 // An incomplete component only mounts if it suspended inside a non-
17571 // concurrent tree, in an inconsistent state. We want to treat it like
17572 // a new mount, even though an empty version of it already committed.
17573 // Disconnect the alternate pointers.
17574 _current.alternate = null;
17575 workInProgress.alternate = null; // Since this is conceptually a new fiber, schedule a Placement effect
17576
17577 workInProgress.effectTag |= Placement;
17578 } // Promote the fiber to a class and try rendering again.
17579
17580
17581 workInProgress.tag = ClassComponent; // The rest of this function is a fork of `updateClassComponent`
17582 // Push context providers early to prevent context stack mismatches.
17583 // During mounting we don't know the child context yet as the instance doesn't exist.
17584 // We will invalidate the child context in finishClassComponent() right after rendering.
17585
17586 var hasContext;
17587
17588 if (isContextProvider(Component)) {
17589 hasContext = true;
17590 pushContextProvider(workInProgress);
17591 } else {
17592 hasContext = false;
17593 }
17594
17595 prepareToReadContext(workInProgress, renderExpirationTime);
17596 constructClassInstance(workInProgress, Component, nextProps);
17597 mountClassInstance(workInProgress, Component, nextProps, renderExpirationTime);
17598 return finishClassComponent(null, workInProgress, Component, true, hasContext, renderExpirationTime);
17599 }
17600
17601 function mountIndeterminateComponent(_current, workInProgress, Component, renderExpirationTime) {
17602 if (_current !== null) {
17603 // An indeterminate component only mounts if it suspended inside a non-
17604 // concurrent tree, in an inconsistent state. We want to treat it like
17605 // a new mount, even though an empty version of it already committed.
17606 // Disconnect the alternate pointers.
17607 _current.alternate = null;
17608 workInProgress.alternate = null; // Since this is conceptually a new fiber, schedule a Placement effect
17609
17610 workInProgress.effectTag |= Placement;
17611 }
17612
17613 var props = workInProgress.pendingProps;
17614 var context;
17615
17616 {
17617 var unmaskedContext = getUnmaskedContext(workInProgress, Component, false);
17618 context = getMaskedContext(workInProgress, unmaskedContext);
17619 }
17620
17621 prepareToReadContext(workInProgress, renderExpirationTime);
17622 var value;
17623
17624 {
17625 if (Component.prototype && typeof Component.prototype.render === 'function') {
17626 var componentName = getComponentName(Component) || 'Unknown';
17627
17628 if (!didWarnAboutBadClass[componentName]) {
17629 error("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);
17630
17631 didWarnAboutBadClass[componentName] = true;
17632 }
17633 }
17634
17635 if (workInProgress.mode & StrictMode) {
17636 ReactStrictModeWarnings.recordLegacyContextWarning(workInProgress, null);
17637 }
17638
17639 ReactCurrentOwner$1.current = workInProgress;
17640 value = renderWithHooks(null, workInProgress, Component, props, context, renderExpirationTime);
17641 } // React DevTools reads this flag.
17642
17643
17644 workInProgress.effectTag |= PerformedWork;
17645
17646 if (typeof value === 'object' && value !== null && typeof value.render === 'function' && value.$$typeof === undefined) {
17647 {
17648 var _componentName = getComponentName(Component) || 'Unknown';
17649
17650 if (!didWarnAboutModulePatternComponent[_componentName]) {
17651 error('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);
17652
17653 didWarnAboutModulePatternComponent[_componentName] = true;
17654 }
17655 } // Proceed under the assumption that this is a class instance
17656
17657
17658 workInProgress.tag = ClassComponent; // Throw out any hooks that were used.
17659
17660 workInProgress.memoizedState = null;
17661 workInProgress.updateQueue = null; // Push context providers early to prevent context stack mismatches.
17662 // During mounting we don't know the child context yet as the instance doesn't exist.
17663 // We will invalidate the child context in finishClassComponent() right after rendering.
17664
17665 var hasContext = false;
17666
17667 if (isContextProvider(Component)) {
17668 hasContext = true;
17669 pushContextProvider(workInProgress);
17670 } else {
17671 hasContext = false;
17672 }
17673
17674 workInProgress.memoizedState = value.state !== null && value.state !== undefined ? value.state : null;
17675 initializeUpdateQueue(workInProgress);
17676 var getDerivedStateFromProps = Component.getDerivedStateFromProps;
17677
17678 if (typeof getDerivedStateFromProps === 'function') {
17679 applyDerivedStateFromProps(workInProgress, Component, getDerivedStateFromProps, props);
17680 }
17681
17682 adoptClassInstance(workInProgress, value);
17683 mountClassInstance(workInProgress, Component, props, renderExpirationTime);
17684 return finishClassComponent(null, workInProgress, Component, true, hasContext, renderExpirationTime);
17685 } else {
17686 // Proceed under the assumption that this is a function component
17687 workInProgress.tag = FunctionComponent;
17688
17689 {
17690
17691 if ( workInProgress.mode & StrictMode) {
17692 // Only double-render components with Hooks
17693 if (workInProgress.memoizedState !== null) {
17694 value = renderWithHooks(null, workInProgress, Component, props, context, renderExpirationTime);
17695 }
17696 }
17697 }
17698
17699 reconcileChildren(null, workInProgress, value, renderExpirationTime);
17700
17701 {
17702 validateFunctionComponentInDev(workInProgress, Component);
17703 }
17704
17705 return workInProgress.child;
17706 }
17707 }
17708
17709 function validateFunctionComponentInDev(workInProgress, Component) {
17710 {
17711 if (Component) {
17712 if (Component.childContextTypes) {
17713 error('%s(...): childContextTypes cannot be defined on a function component.', Component.displayName || Component.name || 'Component');
17714 }
17715 }
17716
17717 if (workInProgress.ref !== null) {
17718 var info = '';
17719 var ownerName = getCurrentFiberOwnerNameInDevOrNull();
17720
17721 if (ownerName) {
17722 info += '\n\nCheck the render method of `' + ownerName + '`.';
17723 }
17724
17725 var warningKey = ownerName || workInProgress._debugID || '';
17726 var debugSource = workInProgress._debugSource;
17727
17728 if (debugSource) {
17729 warningKey = debugSource.fileName + ':' + debugSource.lineNumber;
17730 }
17731
17732 if (!didWarnAboutFunctionRefs[warningKey]) {
17733 didWarnAboutFunctionRefs[warningKey] = true;
17734
17735 error('Function components cannot be given refs. ' + 'Attempts to access this ref will fail. ' + 'Did you mean to use React.forwardRef()?%s', info);
17736 }
17737 }
17738
17739 if (typeof Component.getDerivedStateFromProps === 'function') {
17740 var _componentName2 = getComponentName(Component) || 'Unknown';
17741
17742 if (!didWarnAboutGetDerivedStateOnFunctionComponent[_componentName2]) {
17743 error('%s: Function components do not support getDerivedStateFromProps.', _componentName2);
17744
17745 didWarnAboutGetDerivedStateOnFunctionComponent[_componentName2] = true;
17746 }
17747 }
17748
17749 if (typeof Component.contextType === 'object' && Component.contextType !== null) {
17750 var _componentName3 = getComponentName(Component) || 'Unknown';
17751
17752 if (!didWarnAboutContextTypeOnFunctionComponent[_componentName3]) {
17753 error('%s: Function components do not support contextType.', _componentName3);
17754
17755 didWarnAboutContextTypeOnFunctionComponent[_componentName3] = true;
17756 }
17757 }
17758 }
17759 }
17760
17761 var SUSPENDED_MARKER = {
17762 dehydrated: null,
17763 retryTime: NoWork
17764 };
17765
17766 function shouldRemainOnFallback(suspenseContext, current, workInProgress) {
17767 // If the context is telling us that we should show a fallback, and we're not
17768 // already showing content, then we should show the fallback instead.
17769 return hasSuspenseContext(suspenseContext, ForceSuspenseFallback) && (current === null || current.memoizedState !== null);
17770 }
17771
17772 function updateSuspenseComponent(current, workInProgress, renderExpirationTime) {
17773 var mode = workInProgress.mode;
17774 var nextProps = workInProgress.pendingProps; // This is used by DevTools to force a boundary to suspend.
17775
17776 {
17777 if (shouldSuspend(workInProgress)) {
17778 workInProgress.effectTag |= DidCapture;
17779 }
17780 }
17781
17782 var suspenseContext = suspenseStackCursor.current;
17783 var nextDidTimeout = false;
17784 var didSuspend = (workInProgress.effectTag & DidCapture) !== NoEffect;
17785
17786 if (didSuspend || shouldRemainOnFallback(suspenseContext, current)) {
17787 // Something in this boundary's subtree already suspended. Switch to
17788 // rendering the fallback children.
17789 nextDidTimeout = true;
17790 workInProgress.effectTag &= ~DidCapture;
17791 } else {
17792 // Attempting the main content
17793 if (current === null || current.memoizedState !== null) {
17794 // This is a new mount or this boundary is already showing a fallback state.
17795 // Mark this subtree context as having at least one invisible parent that could
17796 // handle the fallback state.
17797 // Boundaries without fallbacks or should be avoided are not considered since
17798 // they cannot handle preferred fallback states.
17799 if (nextProps.fallback !== undefined && nextProps.unstable_avoidThisFallback !== true) {
17800 suspenseContext = addSubtreeSuspenseContext(suspenseContext, InvisibleParentSuspenseContext);
17801 }
17802 }
17803 }
17804
17805 suspenseContext = setDefaultShallowSuspenseContext(suspenseContext);
17806 pushSuspenseContext(workInProgress, suspenseContext);
17807
17808 {
17809 if ('maxDuration' in nextProps) {
17810 if (!didWarnAboutMaxDuration) {
17811 didWarnAboutMaxDuration = true;
17812
17813 error('maxDuration has been removed from React. ' + 'Remove the maxDuration prop.');
17814 }
17815 }
17816 } // This next part is a bit confusing. If the children timeout, we switch to
17817 // showing the fallback children in place of the "primary" children.
17818 // However, we don't want to delete the primary children because then their
17819 // state will be lost (both the React state and the host state, e.g.
17820 // uncontrolled form inputs). Instead we keep them mounted and hide them.
17821 // Both the fallback children AND the primary children are rendered at the
17822 // same time. Once the primary children are un-suspended, we can delete
17823 // the fallback children — don't need to preserve their state.
17824 //
17825 // The two sets of children are siblings in the host environment, but
17826 // semantically, for purposes of reconciliation, they are two separate sets.
17827 // So we store them using two fragment fibers.
17828 //
17829 // However, we want to avoid allocating extra fibers for every placeholder.
17830 // They're only necessary when the children time out, because that's the
17831 // only time when both sets are mounted.
17832 //
17833 // So, the extra fragment fibers are only used if the children time out.
17834 // Otherwise, we render the primary children directly. This requires some
17835 // custom reconciliation logic to preserve the state of the primary
17836 // children. It's essentially a very basic form of re-parenting.
17837
17838
17839 if (current === null) {
17840 // If we're currently hydrating, try to hydrate this boundary.
17841 // But only if this has a fallback.
17842 if (nextProps.fallback !== undefined) {
17843 tryToClaimNextHydratableInstance(workInProgress); // This could've been a dehydrated suspense component.
17844 } // This is the initial mount. This branch is pretty simple because there's
17845 // no previous state that needs to be preserved.
17846
17847
17848 if (nextDidTimeout) {
17849 // Mount separate fragments for primary and fallback children.
17850 var nextFallbackChildren = nextProps.fallback;
17851 var primaryChildFragment = createFiberFromFragment(null, mode, NoWork, null);
17852 primaryChildFragment.return = workInProgress;
17853
17854 if ((workInProgress.mode & BlockingMode) === NoMode) {
17855 // Outside of blocking mode, we commit the effects from the
17856 // partially completed, timed-out tree, too.
17857 var progressedState = workInProgress.memoizedState;
17858 var progressedPrimaryChild = progressedState !== null ? workInProgress.child.child : workInProgress.child;
17859 primaryChildFragment.child = progressedPrimaryChild;
17860 var progressedChild = progressedPrimaryChild;
17861
17862 while (progressedChild !== null) {
17863 progressedChild.return = primaryChildFragment;
17864 progressedChild = progressedChild.sibling;
17865 }
17866 }
17867
17868 var fallbackChildFragment = createFiberFromFragment(nextFallbackChildren, mode, renderExpirationTime, null);
17869 fallbackChildFragment.return = workInProgress;
17870 primaryChildFragment.sibling = fallbackChildFragment; // Skip the primary children, and continue working on the
17871 // fallback children.
17872
17873 workInProgress.memoizedState = SUSPENDED_MARKER;
17874 workInProgress.child = primaryChildFragment;
17875 return fallbackChildFragment;
17876 } else {
17877 // Mount the primary children without an intermediate fragment fiber.
17878 var nextPrimaryChildren = nextProps.children;
17879 workInProgress.memoizedState = null;
17880 return workInProgress.child = mountChildFibers(workInProgress, null, nextPrimaryChildren, renderExpirationTime);
17881 }
17882 } else {
17883 // This is an update. This branch is more complicated because we need to
17884 // ensure the state of the primary children is preserved.
17885 var prevState = current.memoizedState;
17886
17887 if (prevState !== null) {
17888 // wrapped in a fragment fiber.
17889
17890
17891 var currentPrimaryChildFragment = current.child;
17892 var currentFallbackChildFragment = currentPrimaryChildFragment.sibling;
17893
17894 if (nextDidTimeout) {
17895 // Still timed out. Reuse the current primary children by cloning
17896 // its fragment. We're going to skip over these entirely.
17897 var _nextFallbackChildren2 = nextProps.fallback;
17898
17899 var _primaryChildFragment2 = createWorkInProgress(currentPrimaryChildFragment, currentPrimaryChildFragment.pendingProps);
17900
17901 _primaryChildFragment2.return = workInProgress;
17902
17903 if ((workInProgress.mode & BlockingMode) === NoMode) {
17904 // Outside of blocking mode, we commit the effects from the
17905 // partially completed, timed-out tree, too.
17906 var _progressedState = workInProgress.memoizedState;
17907
17908 var _progressedPrimaryChild = _progressedState !== null ? workInProgress.child.child : workInProgress.child;
17909
17910 if (_progressedPrimaryChild !== currentPrimaryChildFragment.child) {
17911 _primaryChildFragment2.child = _progressedPrimaryChild;
17912 var _progressedChild2 = _progressedPrimaryChild;
17913
17914 while (_progressedChild2 !== null) {
17915 _progressedChild2.return = _primaryChildFragment2;
17916 _progressedChild2 = _progressedChild2.sibling;
17917 }
17918 }
17919 } // Because primaryChildFragment is a new fiber that we're inserting as the
17920 // parent of a new tree, we need to set its treeBaseDuration.
17921
17922
17923 if ( workInProgress.mode & ProfileMode) {
17924 // treeBaseDuration is the sum of all the child tree base durations.
17925 var _treeBaseDuration = 0;
17926 var _hiddenChild = _primaryChildFragment2.child;
17927
17928 while (_hiddenChild !== null) {
17929 _treeBaseDuration += _hiddenChild.treeBaseDuration;
17930 _hiddenChild = _hiddenChild.sibling;
17931 }
17932
17933 _primaryChildFragment2.treeBaseDuration = _treeBaseDuration;
17934 } // Clone the fallback child fragment, too. These we'll continue
17935 // working on.
17936
17937
17938 var _fallbackChildFragment2 = createWorkInProgress(currentFallbackChildFragment, _nextFallbackChildren2);
17939
17940 _fallbackChildFragment2.return = workInProgress;
17941 _primaryChildFragment2.sibling = _fallbackChildFragment2;
17942 _primaryChildFragment2.childExpirationTime = NoWork; // Skip the primary children, and continue working on the
17943 // fallback children.
17944
17945 workInProgress.memoizedState = SUSPENDED_MARKER;
17946 workInProgress.child = _primaryChildFragment2;
17947 return _fallbackChildFragment2;
17948 } else {
17949 // No longer suspended. Switch back to showing the primary children,
17950 // and remove the intermediate fragment fiber.
17951 var _nextPrimaryChildren = nextProps.children;
17952 var currentPrimaryChild = currentPrimaryChildFragment.child;
17953 var primaryChild = reconcileChildFibers(workInProgress, currentPrimaryChild, _nextPrimaryChildren, renderExpirationTime); // If this render doesn't suspend, we need to delete the fallback
17954 // children. Wait until the complete phase, after we've confirmed the
17955 // fallback is no longer needed.
17956 // TODO: Would it be better to store the fallback fragment on
17957 // the stateNode?
17958 // Continue rendering the children, like we normally do.
17959
17960 workInProgress.memoizedState = null;
17961 return workInProgress.child = primaryChild;
17962 }
17963 } else {
17964 // The current tree has not already timed out. That means the primary
17965 // children are not wrapped in a fragment fiber.
17966 var _currentPrimaryChild = current.child;
17967
17968 if (nextDidTimeout) {
17969 // Timed out. Wrap the children in a fragment fiber to keep them
17970 // separate from the fallback children.
17971 var _nextFallbackChildren3 = nextProps.fallback;
17972
17973 var _primaryChildFragment3 = createFiberFromFragment( // It shouldn't matter what the pending props are because we aren't
17974 // going to render this fragment.
17975 null, mode, NoWork, null);
17976
17977 _primaryChildFragment3.return = workInProgress;
17978 _primaryChildFragment3.child = _currentPrimaryChild;
17979
17980 if (_currentPrimaryChild !== null) {
17981 _currentPrimaryChild.return = _primaryChildFragment3;
17982 } // Even though we're creating a new fiber, there are no new children,
17983 // because we're reusing an already mounted tree. So we don't need to
17984 // schedule a placement.
17985 // primaryChildFragment.effectTag |= Placement;
17986
17987
17988 if ((workInProgress.mode & BlockingMode) === NoMode) {
17989 // Outside of blocking mode, we commit the effects from the
17990 // partially completed, timed-out tree, too.
17991 var _progressedState2 = workInProgress.memoizedState;
17992
17993 var _progressedPrimaryChild2 = _progressedState2 !== null ? workInProgress.child.child : workInProgress.child;
17994
17995 _primaryChildFragment3.child = _progressedPrimaryChild2;
17996 var _progressedChild3 = _progressedPrimaryChild2;
17997
17998 while (_progressedChild3 !== null) {
17999 _progressedChild3.return = _primaryChildFragment3;
18000 _progressedChild3 = _progressedChild3.sibling;
18001 }
18002 } // Because primaryChildFragment is a new fiber that we're inserting as the
18003 // parent of a new tree, we need to set its treeBaseDuration.
18004
18005
18006 if ( workInProgress.mode & ProfileMode) {
18007 // treeBaseDuration is the sum of all the child tree base durations.
18008 var _treeBaseDuration2 = 0;
18009 var _hiddenChild2 = _primaryChildFragment3.child;
18010
18011 while (_hiddenChild2 !== null) {
18012 _treeBaseDuration2 += _hiddenChild2.treeBaseDuration;
18013 _hiddenChild2 = _hiddenChild2.sibling;
18014 }
18015
18016 _primaryChildFragment3.treeBaseDuration = _treeBaseDuration2;
18017 } // Create a fragment from the fallback children, too.
18018
18019
18020 var _fallbackChildFragment3 = createFiberFromFragment(_nextFallbackChildren3, mode, renderExpirationTime, null);
18021
18022 _fallbackChildFragment3.return = workInProgress;
18023 _primaryChildFragment3.sibling = _fallbackChildFragment3;
18024 _fallbackChildFragment3.effectTag |= Placement;
18025 _primaryChildFragment3.childExpirationTime = NoWork; // Skip the primary children, and continue working on the
18026 // fallback children.
18027
18028 workInProgress.memoizedState = SUSPENDED_MARKER;
18029 workInProgress.child = _primaryChildFragment3;
18030 return _fallbackChildFragment3;
18031 } else {
18032 // Still haven't timed out. Continue rendering the children, like we
18033 // normally do.
18034 workInProgress.memoizedState = null;
18035 var _nextPrimaryChildren2 = nextProps.children;
18036 return workInProgress.child = reconcileChildFibers(workInProgress, _currentPrimaryChild, _nextPrimaryChildren2, renderExpirationTime);
18037 }
18038 }
18039 }
18040 }
18041
18042 function scheduleWorkOnFiber(fiber, renderExpirationTime) {
18043 if (fiber.expirationTime < renderExpirationTime) {
18044 fiber.expirationTime = renderExpirationTime;
18045 }
18046
18047 var alternate = fiber.alternate;
18048
18049 if (alternate !== null && alternate.expirationTime < renderExpirationTime) {
18050 alternate.expirationTime = renderExpirationTime;
18051 }
18052
18053 scheduleWorkOnParentPath(fiber.return, renderExpirationTime);
18054 }
18055
18056 function propagateSuspenseContextChange(workInProgress, firstChild, renderExpirationTime) {
18057 // Mark any Suspense boundaries with fallbacks as having work to do.
18058 // If they were previously forced into fallbacks, they may now be able
18059 // to unblock.
18060 var node = firstChild;
18061
18062 while (node !== null) {
18063 if (node.tag === SuspenseComponent) {
18064 var state = node.memoizedState;
18065
18066 if (state !== null) {
18067 scheduleWorkOnFiber(node, renderExpirationTime);
18068 }
18069 } else if (node.tag === SuspenseListComponent) {
18070 // If the tail is hidden there might not be an Suspense boundaries
18071 // to schedule work on. In this case we have to schedule it on the
18072 // list itself.
18073 // We don't have to traverse to the children of the list since
18074 // the list will propagate the change when it rerenders.
18075 scheduleWorkOnFiber(node, renderExpirationTime);
18076 } else if (node.child !== null) {
18077 node.child.return = node;
18078 node = node.child;
18079 continue;
18080 }
18081
18082 if (node === workInProgress) {
18083 return;
18084 }
18085
18086 while (node.sibling === null) {
18087 if (node.return === null || node.return === workInProgress) {
18088 return;
18089 }
18090
18091 node = node.return;
18092 }
18093
18094 node.sibling.return = node.return;
18095 node = node.sibling;
18096 }
18097 }
18098
18099 function findLastContentRow(firstChild) {
18100 // This is going to find the last row among these children that is already
18101 // showing content on the screen, as opposed to being in fallback state or
18102 // new. If a row has multiple Suspense boundaries, any of them being in the
18103 // fallback state, counts as the whole row being in a fallback state.
18104 // Note that the "rows" will be workInProgress, but any nested children
18105 // will still be current since we haven't rendered them yet. The mounted
18106 // order may not be the same as the new order. We use the new order.
18107 var row = firstChild;
18108 var lastContentRow = null;
18109
18110 while (row !== null) {
18111 var currentRow = row.alternate; // New rows can't be content rows.
18112
18113 if (currentRow !== null && findFirstSuspended(currentRow) === null) {
18114 lastContentRow = row;
18115 }
18116
18117 row = row.sibling;
18118 }
18119
18120 return lastContentRow;
18121 }
18122
18123 function validateRevealOrder(revealOrder) {
18124 {
18125 if (revealOrder !== undefined && revealOrder !== 'forwards' && revealOrder !== 'backwards' && revealOrder !== 'together' && !didWarnAboutRevealOrder[revealOrder]) {
18126 didWarnAboutRevealOrder[revealOrder] = true;
18127
18128 if (typeof revealOrder === 'string') {
18129 switch (revealOrder.toLowerCase()) {
18130 case 'together':
18131 case 'forwards':
18132 case 'backwards':
18133 {
18134 error('"%s" is not a valid value for revealOrder on <SuspenseList />. ' + 'Use lowercase "%s" instead.', revealOrder, revealOrder.toLowerCase());
18135
18136 break;
18137 }
18138
18139 case 'forward':
18140 case 'backward':
18141 {
18142 error('"%s" is not a valid value for revealOrder on <SuspenseList />. ' + 'React uses the -s suffix in the spelling. Use "%ss" instead.', revealOrder, revealOrder.toLowerCase());
18143
18144 break;
18145 }
18146
18147 default:
18148 error('"%s" is not a supported revealOrder on <SuspenseList />. ' + 'Did you mean "together", "forwards" or "backwards"?', revealOrder);
18149
18150 break;
18151 }
18152 } else {
18153 error('%s is not a supported value for revealOrder on <SuspenseList />. ' + 'Did you mean "together", "forwards" or "backwards"?', revealOrder);
18154 }
18155 }
18156 }
18157 }
18158
18159 function validateTailOptions(tailMode, revealOrder) {
18160 {
18161 if (tailMode !== undefined && !didWarnAboutTailOptions[tailMode]) {
18162 if (tailMode !== 'collapsed' && tailMode !== 'hidden') {
18163 didWarnAboutTailOptions[tailMode] = true;
18164
18165 error('"%s" is not a supported value for tail on <SuspenseList />. ' + 'Did you mean "collapsed" or "hidden"?', tailMode);
18166 } else if (revealOrder !== 'forwards' && revealOrder !== 'backwards') {
18167 didWarnAboutTailOptions[tailMode] = true;
18168
18169 error('<SuspenseList tail="%s" /> is only valid if revealOrder is ' + '"forwards" or "backwards". ' + 'Did you mean to specify revealOrder="forwards"?', tailMode);
18170 }
18171 }
18172 }
18173 }
18174
18175 function validateSuspenseListNestedChild(childSlot, index) {
18176 {
18177 var isArray = Array.isArray(childSlot);
18178 var isIterable = !isArray && typeof getIteratorFn(childSlot) === 'function';
18179
18180 if (isArray || isIterable) {
18181 var type = isArray ? 'array' : 'iterable';
18182
18183 error('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);
18184
18185 return false;
18186 }
18187 }
18188
18189 return true;
18190 }
18191
18192 function validateSuspenseListChildren(children, revealOrder) {
18193 {
18194 if ((revealOrder === 'forwards' || revealOrder === 'backwards') && children !== undefined && children !== null && children !== false) {
18195 if (Array.isArray(children)) {
18196 for (var i = 0; i < children.length; i++) {
18197 if (!validateSuspenseListNestedChild(children[i], i)) {
18198 return;
18199 }
18200 }
18201 } else {
18202 var iteratorFn = getIteratorFn(children);
18203
18204 if (typeof iteratorFn === 'function') {
18205 var childrenIterator = iteratorFn.call(children);
18206
18207 if (childrenIterator) {
18208 var step = childrenIterator.next();
18209 var _i = 0;
18210
18211 for (; !step.done; step = childrenIterator.next()) {
18212 if (!validateSuspenseListNestedChild(step.value, _i)) {
18213 return;
18214 }
18215
18216 _i++;
18217 }
18218 }
18219 } else {
18220 error('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);
18221 }
18222 }
18223 }
18224 }
18225 }
18226
18227 function initSuspenseListRenderState(workInProgress, isBackwards, tail, lastContentRow, tailMode, lastEffectBeforeRendering) {
18228 var renderState = workInProgress.memoizedState;
18229
18230 if (renderState === null) {
18231 workInProgress.memoizedState = {
18232 isBackwards: isBackwards,
18233 rendering: null,
18234 renderingStartTime: 0,
18235 last: lastContentRow,
18236 tail: tail,
18237 tailExpiration: 0,
18238 tailMode: tailMode,
18239 lastEffect: lastEffectBeforeRendering
18240 };
18241 } else {
18242 // We can reuse the existing object from previous renders.
18243 renderState.isBackwards = isBackwards;
18244 renderState.rendering = null;
18245 renderState.renderingStartTime = 0;
18246 renderState.last = lastContentRow;
18247 renderState.tail = tail;
18248 renderState.tailExpiration = 0;
18249 renderState.tailMode = tailMode;
18250 renderState.lastEffect = lastEffectBeforeRendering;
18251 }
18252 } // This can end up rendering this component multiple passes.
18253 // The first pass splits the children fibers into two sets. A head and tail.
18254 // We first render the head. If anything is in fallback state, we do another
18255 // pass through beginWork to rerender all children (including the tail) with
18256 // the force suspend context. If the first render didn't have anything in
18257 // in fallback state. Then we render each row in the tail one-by-one.
18258 // That happens in the completeWork phase without going back to beginWork.
18259
18260
18261 function updateSuspenseListComponent(current, workInProgress, renderExpirationTime) {
18262 var nextProps = workInProgress.pendingProps;
18263 var revealOrder = nextProps.revealOrder;
18264 var tailMode = nextProps.tail;
18265 var newChildren = nextProps.children;
18266 validateRevealOrder(revealOrder);
18267 validateTailOptions(tailMode, revealOrder);
18268 validateSuspenseListChildren(newChildren, revealOrder);
18269 reconcileChildren(current, workInProgress, newChildren, renderExpirationTime);
18270 var suspenseContext = suspenseStackCursor.current;
18271 var shouldForceFallback = hasSuspenseContext(suspenseContext, ForceSuspenseFallback);
18272
18273 if (shouldForceFallback) {
18274 suspenseContext = setShallowSuspenseContext(suspenseContext, ForceSuspenseFallback);
18275 workInProgress.effectTag |= DidCapture;
18276 } else {
18277 var didSuspendBefore = current !== null && (current.effectTag & DidCapture) !== NoEffect;
18278
18279 if (didSuspendBefore) {
18280 // If we previously forced a fallback, we need to schedule work
18281 // on any nested boundaries to let them know to try to render
18282 // again. This is the same as context updating.
18283 propagateSuspenseContextChange(workInProgress, workInProgress.child, renderExpirationTime);
18284 }
18285
18286 suspenseContext = setDefaultShallowSuspenseContext(suspenseContext);
18287 }
18288
18289 pushSuspenseContext(workInProgress, suspenseContext);
18290
18291 if ((workInProgress.mode & BlockingMode) === NoMode) {
18292 // Outside of blocking mode, SuspenseList doesn't work so we just
18293 // use make it a noop by treating it as the default revealOrder.
18294 workInProgress.memoizedState = null;
18295 } else {
18296 switch (revealOrder) {
18297 case 'forwards':
18298 {
18299 var lastContentRow = findLastContentRow(workInProgress.child);
18300 var tail;
18301
18302 if (lastContentRow === null) {
18303 // The whole list is part of the tail.
18304 // TODO: We could fast path by just rendering the tail now.
18305 tail = workInProgress.child;
18306 workInProgress.child = null;
18307 } else {
18308 // Disconnect the tail rows after the content row.
18309 // We're going to render them separately later.
18310 tail = lastContentRow.sibling;
18311 lastContentRow.sibling = null;
18312 }
18313
18314 initSuspenseListRenderState(workInProgress, false, // isBackwards
18315 tail, lastContentRow, tailMode, workInProgress.lastEffect);
18316 break;
18317 }
18318
18319 case 'backwards':
18320 {
18321 // We're going to find the first row that has existing content.
18322 // At the same time we're going to reverse the list of everything
18323 // we pass in the meantime. That's going to be our tail in reverse
18324 // order.
18325 var _tail = null;
18326 var row = workInProgress.child;
18327 workInProgress.child = null;
18328
18329 while (row !== null) {
18330 var currentRow = row.alternate; // New rows can't be content rows.
18331
18332 if (currentRow !== null && findFirstSuspended(currentRow) === null) {
18333 // This is the beginning of the main content.
18334 workInProgress.child = row;
18335 break;
18336 }
18337
18338 var nextRow = row.sibling;
18339 row.sibling = _tail;
18340 _tail = row;
18341 row = nextRow;
18342 } // TODO: If workInProgress.child is null, we can continue on the tail immediately.
18343
18344
18345 initSuspenseListRenderState(workInProgress, true, // isBackwards
18346 _tail, null, // last
18347 tailMode, workInProgress.lastEffect);
18348 break;
18349 }
18350
18351 case 'together':
18352 {
18353 initSuspenseListRenderState(workInProgress, false, // isBackwards
18354 null, // tail
18355 null, // last
18356 undefined, workInProgress.lastEffect);
18357 break;
18358 }
18359
18360 default:
18361 {
18362 // The default reveal order is the same as not having
18363 // a boundary.
18364 workInProgress.memoizedState = null;
18365 }
18366 }
18367 }
18368
18369 return workInProgress.child;
18370 }
18371
18372 function updatePortalComponent(current, workInProgress, renderExpirationTime) {
18373 pushHostContainer(workInProgress, workInProgress.stateNode.containerInfo);
18374 var nextChildren = workInProgress.pendingProps;
18375
18376 if (current === null) {
18377 // Portals are special because we don't append the children during mount
18378 // but at commit. Therefore we need to track insertions which the normal
18379 // flow doesn't do during mount. This doesn't happen at the root because
18380 // the root always starts with a "current" with a null child.
18381 // TODO: Consider unifying this with how the root works.
18382 workInProgress.child = reconcileChildFibers(workInProgress, null, nextChildren, renderExpirationTime);
18383 } else {
18384 reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime);
18385 }
18386
18387 return workInProgress.child;
18388 }
18389
18390 function updateContextProvider(current, workInProgress, renderExpirationTime) {
18391 var providerType = workInProgress.type;
18392 var context = providerType._context;
18393 var newProps = workInProgress.pendingProps;
18394 var oldProps = workInProgress.memoizedProps;
18395 var newValue = newProps.value;
18396
18397 {
18398 var providerPropTypes = workInProgress.type.propTypes;
18399
18400 if (providerPropTypes) {
18401 checkPropTypes_1(providerPropTypes, newProps, 'prop', 'Context.Provider', getCurrentFiberStackInDev);
18402 }
18403 }
18404
18405 pushProvider(workInProgress, newValue);
18406
18407 if (oldProps !== null) {
18408 var oldValue = oldProps.value;
18409 var changedBits = calculateChangedBits(context, newValue, oldValue);
18410
18411 if (changedBits === 0) {
18412 // No change. Bailout early if children are the same.
18413 if (oldProps.children === newProps.children && !hasContextChanged()) {
18414 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderExpirationTime);
18415 }
18416 } else {
18417 // The context value changed. Search for matching consumers and schedule
18418 // them to update.
18419 propagateContextChange(workInProgress, context, changedBits, renderExpirationTime);
18420 }
18421 }
18422
18423 var newChildren = newProps.children;
18424 reconcileChildren(current, workInProgress, newChildren, renderExpirationTime);
18425 return workInProgress.child;
18426 }
18427
18428 var hasWarnedAboutUsingContextAsConsumer = false;
18429
18430 function updateContextConsumer(current, workInProgress, renderExpirationTime) {
18431 var context = workInProgress.type; // The logic below for Context differs depending on PROD or DEV mode. In
18432 // DEV mode, we create a separate object for Context.Consumer that acts
18433 // like a proxy to Context. This proxy object adds unnecessary code in PROD
18434 // so we use the old behaviour (Context.Consumer references Context) to
18435 // reduce size and overhead. The separate object references context via
18436 // a property called "_context", which also gives us the ability to check
18437 // in DEV mode if this property exists or not and warn if it does not.
18438
18439 {
18440 if (context._context === undefined) {
18441 // This may be because it's a Context (rather than a Consumer).
18442 // Or it may be because it's older React where they're the same thing.
18443 // We only want to warn if we're sure it's a new React.
18444 if (context !== context.Consumer) {
18445 if (!hasWarnedAboutUsingContextAsConsumer) {
18446 hasWarnedAboutUsingContextAsConsumer = true;
18447
18448 error('Rendering <Context> directly is not supported and will be removed in ' + 'a future major release. Did you mean to render <Context.Consumer> instead?');
18449 }
18450 }
18451 } else {
18452 context = context._context;
18453 }
18454 }
18455
18456 var newProps = workInProgress.pendingProps;
18457 var render = newProps.children;
18458
18459 {
18460 if (typeof render !== 'function') {
18461 error('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.');
18462 }
18463 }
18464
18465 prepareToReadContext(workInProgress, renderExpirationTime);
18466 var newValue = readContext(context, newProps.unstable_observedBits);
18467 var newChildren;
18468
18469 {
18470 ReactCurrentOwner$1.current = workInProgress;
18471 setCurrentPhase('render');
18472 newChildren = render(newValue);
18473 setCurrentPhase(null);
18474 } // React DevTools reads this flag.
18475
18476
18477 workInProgress.effectTag |= PerformedWork;
18478 reconcileChildren(current, workInProgress, newChildren, renderExpirationTime);
18479 return workInProgress.child;
18480 }
18481
18482 function markWorkInProgressReceivedUpdate() {
18483 didReceiveUpdate = true;
18484 }
18485
18486 function bailoutOnAlreadyFinishedWork(current, workInProgress, renderExpirationTime) {
18487 cancelWorkTimer(workInProgress);
18488
18489 if (current !== null) {
18490 // Reuse previous dependencies
18491 workInProgress.dependencies = current.dependencies;
18492 }
18493
18494 {
18495 // Don't update "base" render times for bailouts.
18496 stopProfilerTimerIfRunning();
18497 }
18498
18499 var updateExpirationTime = workInProgress.expirationTime;
18500
18501 if (updateExpirationTime !== NoWork) {
18502 markUnprocessedUpdateTime(updateExpirationTime);
18503 } // Check if the children have any pending work.
18504
18505
18506 var childExpirationTime = workInProgress.childExpirationTime;
18507
18508 if (childExpirationTime < renderExpirationTime) {
18509 // The children don't have any work either. We can skip them.
18510 // TODO: Once we add back resuming, we should check if the children are
18511 // a work-in-progress set. If so, we need to transfer their effects.
18512 return null;
18513 } else {
18514 // This fiber doesn't have work, but its subtree does. Clone the child
18515 // fibers and continue.
18516 cloneChildFibers(current, workInProgress);
18517 return workInProgress.child;
18518 }
18519 }
18520
18521 function remountFiber(current, oldWorkInProgress, newWorkInProgress) {
18522 {
18523 var returnFiber = oldWorkInProgress.return;
18524
18525 if (returnFiber === null) {
18526 throw new Error('Cannot swap the root fiber.');
18527 } // Disconnect from the old current.
18528 // It will get deleted.
18529
18530
18531 current.alternate = null;
18532 oldWorkInProgress.alternate = null; // Connect to the new tree.
18533
18534 newWorkInProgress.index = oldWorkInProgress.index;
18535 newWorkInProgress.sibling = oldWorkInProgress.sibling;
18536 newWorkInProgress.return = oldWorkInProgress.return;
18537 newWorkInProgress.ref = oldWorkInProgress.ref; // Replace the child/sibling pointers above it.
18538
18539 if (oldWorkInProgress === returnFiber.child) {
18540 returnFiber.child = newWorkInProgress;
18541 } else {
18542 var prevSibling = returnFiber.child;
18543
18544 if (prevSibling === null) {
18545 throw new Error('Expected parent to have a child.');
18546 }
18547
18548 while (prevSibling.sibling !== oldWorkInProgress) {
18549 prevSibling = prevSibling.sibling;
18550
18551 if (prevSibling === null) {
18552 throw new Error('Expected to find the previous sibling.');
18553 }
18554 }
18555
18556 prevSibling.sibling = newWorkInProgress;
18557 } // Delete the old fiber and place the new one.
18558 // Since the old fiber is disconnected, we have to schedule it manually.
18559
18560
18561 var last = returnFiber.lastEffect;
18562
18563 if (last !== null) {
18564 last.nextEffect = current;
18565 returnFiber.lastEffect = current;
18566 } else {
18567 returnFiber.firstEffect = returnFiber.lastEffect = current;
18568 }
18569
18570 current.nextEffect = null;
18571 current.effectTag = Deletion;
18572 newWorkInProgress.effectTag |= Placement; // Restart work from the new fiber.
18573
18574 return newWorkInProgress;
18575 }
18576 }
18577
18578 function beginWork(current, workInProgress, renderExpirationTime) {
18579 var updateExpirationTime = workInProgress.expirationTime;
18580
18581 {
18582 if (workInProgress._debugNeedsRemount && current !== null) {
18583 // This will restart the begin phase with a new fiber.
18584 return remountFiber(current, workInProgress, createFiberFromTypeAndProps(workInProgress.type, workInProgress.key, workInProgress.pendingProps, workInProgress._debugOwner || null, workInProgress.mode, workInProgress.expirationTime));
18585 }
18586 }
18587
18588 if (current !== null) {
18589 var oldProps = current.memoizedProps;
18590 var newProps = workInProgress.pendingProps;
18591
18592 if (oldProps !== newProps || hasContextChanged() || ( // Force a re-render if the implementation changed due to hot reload:
18593 workInProgress.type !== current.type )) {
18594 // If props or context changed, mark the fiber as having performed work.
18595 // This may be unset if the props are determined to be equal later (memo).
18596 didReceiveUpdate = true;
18597 } else if (updateExpirationTime < renderExpirationTime) {
18598 didReceiveUpdate = false; // This fiber does not have any pending work. Bailout without entering
18599 // the begin phase. There's still some bookkeeping we that needs to be done
18600 // in this optimized path, mostly pushing stuff onto the stack.
18601
18602 switch (workInProgress.tag) {
18603 case HostRoot:
18604 pushHostRootContext(workInProgress);
18605 resetHydrationState();
18606 break;
18607
18608 case HostComponent:
18609 pushHostContext(workInProgress);
18610
18611 if (workInProgress.mode & ConcurrentMode && renderExpirationTime !== Never && shouldDeprioritizeSubtree(workInProgress.type, newProps)) {
18612 {
18613 markSpawnedWork(Never);
18614 } // Schedule this fiber to re-render at offscreen priority. Then bailout.
18615
18616
18617 workInProgress.expirationTime = workInProgress.childExpirationTime = Never;
18618 return null;
18619 }
18620
18621 break;
18622
18623 case ClassComponent:
18624 {
18625 var Component = workInProgress.type;
18626
18627 if (isContextProvider(Component)) {
18628 pushContextProvider(workInProgress);
18629 }
18630
18631 break;
18632 }
18633
18634 case HostPortal:
18635 pushHostContainer(workInProgress, workInProgress.stateNode.containerInfo);
18636 break;
18637
18638 case ContextProvider:
18639 {
18640 var newValue = workInProgress.memoizedProps.value;
18641 pushProvider(workInProgress, newValue);
18642 break;
18643 }
18644
18645 case Profiler:
18646 {
18647 // Profiler should only call onRender when one of its descendants actually rendered.
18648 var hasChildWork = workInProgress.childExpirationTime >= renderExpirationTime;
18649
18650 if (hasChildWork) {
18651 workInProgress.effectTag |= Update;
18652 }
18653 }
18654
18655 break;
18656
18657 case SuspenseComponent:
18658 {
18659 var state = workInProgress.memoizedState;
18660
18661 if (state !== null) {
18662 // whether to retry the primary children, or to skip over it and
18663 // go straight to the fallback. Check the priority of the primary
18664 // child fragment.
18665
18666
18667 var primaryChildFragment = workInProgress.child;
18668 var primaryChildExpirationTime = primaryChildFragment.childExpirationTime;
18669
18670 if (primaryChildExpirationTime !== NoWork && primaryChildExpirationTime >= renderExpirationTime) {
18671 // The primary children have pending work. Use the normal path
18672 // to attempt to render the primary children again.
18673 return updateSuspenseComponent(current, workInProgress, renderExpirationTime);
18674 } else {
18675 pushSuspenseContext(workInProgress, setDefaultShallowSuspenseContext(suspenseStackCursor.current)); // The primary children do not have pending work with sufficient
18676 // priority. Bailout.
18677
18678 var child = bailoutOnAlreadyFinishedWork(current, workInProgress, renderExpirationTime);
18679
18680 if (child !== null) {
18681 // The fallback children have pending work. Skip over the
18682 // primary children and work on the fallback.
18683 return child.sibling;
18684 } else {
18685 return null;
18686 }
18687 }
18688 } else {
18689 pushSuspenseContext(workInProgress, setDefaultShallowSuspenseContext(suspenseStackCursor.current));
18690 }
18691
18692 break;
18693 }
18694
18695 case SuspenseListComponent:
18696 {
18697 var didSuspendBefore = (current.effectTag & DidCapture) !== NoEffect;
18698
18699 var _hasChildWork = workInProgress.childExpirationTime >= renderExpirationTime;
18700
18701 if (didSuspendBefore) {
18702 if (_hasChildWork) {
18703 // If something was in fallback state last time, and we have all the
18704 // same children then we're still in progressive loading state.
18705 // Something might get unblocked by state updates or retries in the
18706 // tree which will affect the tail. So we need to use the normal
18707 // path to compute the correct tail.
18708 return updateSuspenseListComponent(current, workInProgress, renderExpirationTime);
18709 } // If none of the children had any work, that means that none of
18710 // them got retried so they'll still be blocked in the same way
18711 // as before. We can fast bail out.
18712
18713
18714 workInProgress.effectTag |= DidCapture;
18715 } // If nothing suspended before and we're rendering the same children,
18716 // then the tail doesn't matter. Anything new that suspends will work
18717 // in the "together" mode, so we can continue from the state we had.
18718
18719
18720 var renderState = workInProgress.memoizedState;
18721
18722 if (renderState !== null) {
18723 // Reset to the "together" mode in case we've started a different
18724 // update in the past but didn't complete it.
18725 renderState.rendering = null;
18726 renderState.tail = null;
18727 }
18728
18729 pushSuspenseContext(workInProgress, suspenseStackCursor.current);
18730
18731 if (_hasChildWork) {
18732 break;
18733 } else {
18734 // If none of the children had any work, that means that none of
18735 // them got retried so they'll still be blocked in the same way
18736 // as before. We can fast bail out.
18737 return null;
18738 }
18739 }
18740 }
18741
18742 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderExpirationTime);
18743 } else {
18744 // An update was scheduled on this fiber, but there are no new props
18745 // nor legacy context. Set this to false. If an update queue or context
18746 // consumer produces a changed value, it will set this to true. Otherwise,
18747 // the component will assume the children have not changed and bail out.
18748 didReceiveUpdate = false;
18749 }
18750 } else {
18751 didReceiveUpdate = false;
18752 } // Before entering the begin phase, clear pending update priority.
18753 // TODO: This assumes that we're about to evaluate the component and process
18754 // the update queue. However, there's an exception: SimpleMemoComponent
18755 // sometimes bails out later in the begin phase. This indicates that we should
18756 // move this assignment out of the common path and into each branch.
18757
18758
18759 workInProgress.expirationTime = NoWork;
18760
18761 switch (workInProgress.tag) {
18762 case IndeterminateComponent:
18763 {
18764 return mountIndeterminateComponent(current, workInProgress, workInProgress.type, renderExpirationTime);
18765 }
18766
18767 case LazyComponent:
18768 {
18769 var elementType = workInProgress.elementType;
18770 return mountLazyComponent(current, workInProgress, elementType, updateExpirationTime, renderExpirationTime);
18771 }
18772
18773 case FunctionComponent:
18774 {
18775 var _Component = workInProgress.type;
18776 var unresolvedProps = workInProgress.pendingProps;
18777 var resolvedProps = workInProgress.elementType === _Component ? unresolvedProps : resolveDefaultProps(_Component, unresolvedProps);
18778 return updateFunctionComponent(current, workInProgress, _Component, resolvedProps, renderExpirationTime);
18779 }
18780
18781 case ClassComponent:
18782 {
18783 var _Component2 = workInProgress.type;
18784 var _unresolvedProps = workInProgress.pendingProps;
18785
18786 var _resolvedProps = workInProgress.elementType === _Component2 ? _unresolvedProps : resolveDefaultProps(_Component2, _unresolvedProps);
18787
18788 return updateClassComponent(current, workInProgress, _Component2, _resolvedProps, renderExpirationTime);
18789 }
18790
18791 case HostRoot:
18792 return updateHostRoot(current, workInProgress, renderExpirationTime);
18793
18794 case HostComponent:
18795 return updateHostComponent(current, workInProgress, renderExpirationTime);
18796
18797 case HostText:
18798 return updateHostText(current, workInProgress);
18799
18800 case SuspenseComponent:
18801 return updateSuspenseComponent(current, workInProgress, renderExpirationTime);
18802
18803 case HostPortal:
18804 return updatePortalComponent(current, workInProgress, renderExpirationTime);
18805
18806 case ForwardRef:
18807 {
18808 var type = workInProgress.type;
18809 var _unresolvedProps2 = workInProgress.pendingProps;
18810
18811 var _resolvedProps2 = workInProgress.elementType === type ? _unresolvedProps2 : resolveDefaultProps(type, _unresolvedProps2);
18812
18813 return updateForwardRef(current, workInProgress, type, _resolvedProps2, renderExpirationTime);
18814 }
18815
18816 case Fragment:
18817 return updateFragment(current, workInProgress, renderExpirationTime);
18818
18819 case Mode:
18820 return updateMode(current, workInProgress, renderExpirationTime);
18821
18822 case Profiler:
18823 return updateProfiler(current, workInProgress, renderExpirationTime);
18824
18825 case ContextProvider:
18826 return updateContextProvider(current, workInProgress, renderExpirationTime);
18827
18828 case ContextConsumer:
18829 return updateContextConsumer(current, workInProgress, renderExpirationTime);
18830
18831 case MemoComponent:
18832 {
18833 var _type2 = workInProgress.type;
18834 var _unresolvedProps3 = workInProgress.pendingProps; // Resolve outer props first, then resolve inner props.
18835
18836 var _resolvedProps3 = resolveDefaultProps(_type2, _unresolvedProps3);
18837
18838 {
18839 if (workInProgress.type !== workInProgress.elementType) {
18840 var outerPropTypes = _type2.propTypes;
18841
18842 if (outerPropTypes) {
18843 checkPropTypes_1(outerPropTypes, _resolvedProps3, // Resolved for outer only
18844 'prop', getComponentName(_type2), getCurrentFiberStackInDev);
18845 }
18846 }
18847 }
18848
18849 _resolvedProps3 = resolveDefaultProps(_type2.type, _resolvedProps3);
18850 return updateMemoComponent(current, workInProgress, _type2, _resolvedProps3, updateExpirationTime, renderExpirationTime);
18851 }
18852
18853 case SimpleMemoComponent:
18854 {
18855 return updateSimpleMemoComponent(current, workInProgress, workInProgress.type, workInProgress.pendingProps, updateExpirationTime, renderExpirationTime);
18856 }
18857
18858 case IncompleteClassComponent:
18859 {
18860 var _Component3 = workInProgress.type;
18861 var _unresolvedProps4 = workInProgress.pendingProps;
18862
18863 var _resolvedProps4 = workInProgress.elementType === _Component3 ? _unresolvedProps4 : resolveDefaultProps(_Component3, _unresolvedProps4);
18864
18865 return mountIncompleteClassComponent(current, workInProgress, _Component3, _resolvedProps4, renderExpirationTime);
18866 }
18867
18868 case SuspenseListComponent:
18869 {
18870 return updateSuspenseListComponent(current, workInProgress, renderExpirationTime);
18871 }
18872 }
18873
18874 {
18875 {
18876 throw Error( "Unknown unit of work tag (" + workInProgress.tag + "). This error is likely caused by a bug in React. Please file an issue." );
18877 }
18878 }
18879 }
18880
18881 function markUpdate(workInProgress) {
18882 // Tag the fiber with an update effect. This turns a Placement into
18883 // a PlacementAndUpdate.
18884 workInProgress.effectTag |= Update;
18885 }
18886
18887 function markRef$1(workInProgress) {
18888 workInProgress.effectTag |= Ref;
18889 }
18890
18891 var appendAllChildren;
18892 var updateHostContainer;
18893 var updateHostComponent$1;
18894 var updateHostText$1;
18895
18896 {
18897 // Mutation mode
18898 appendAllChildren = function (parent, workInProgress, needsVisibilityToggle, isHidden) {
18899 // We only have the top Fiber that was created but we need recurse down its
18900 // children to find all the terminal nodes.
18901 var node = workInProgress.child;
18902
18903 while (node !== null) {
18904 if (node.tag === HostComponent || node.tag === HostText) {
18905 appendInitialChild(parent, node.stateNode);
18906 } else if (node.tag === HostPortal) ; else if (node.child !== null) {
18907 node.child.return = node;
18908 node = node.child;
18909 continue;
18910 }
18911
18912 if (node === workInProgress) {
18913 return;
18914 }
18915
18916 while (node.sibling === null) {
18917 if (node.return === null || node.return === workInProgress) {
18918 return;
18919 }
18920
18921 node = node.return;
18922 }
18923
18924 node.sibling.return = node.return;
18925 node = node.sibling;
18926 }
18927 };
18928
18929 updateHostContainer = function (workInProgress) {// Noop
18930 };
18931
18932 updateHostComponent$1 = function (current, workInProgress, type, newProps, rootContainerInstance) {
18933 // If we have an alternate, that means this is an update and we need to
18934 // schedule a side-effect to do the updates.
18935 var oldProps = current.memoizedProps;
18936
18937 if (oldProps === newProps) {
18938 // In mutation mode, this is sufficient for a bailout because
18939 // we won't touch this node even if children changed.
18940 return;
18941 } // If we get updated because one of our children updated, we don't
18942 // have newProps so we'll have to reuse them.
18943 // TODO: Split the update API as separate for the props vs. children.
18944 // Even better would be if children weren't special cased at all tho.
18945
18946
18947 var instance = workInProgress.stateNode;
18948 var currentHostContext = getHostContext(); // TODO: Experiencing an error where oldProps is null. Suggests a host
18949 // component is hitting the resume path. Figure out why. Possibly
18950 // related to `hidden`.
18951
18952 var updatePayload = prepareUpdate(instance, type, oldProps, newProps, rootContainerInstance, currentHostContext); // TODO: Type this specific to this type of component.
18953
18954 workInProgress.updateQueue = updatePayload; // If the update payload indicates that there is a change or if there
18955 // is a new ref we mark this as an update. All the work is done in commitWork.
18956
18957 if (updatePayload) {
18958 markUpdate(workInProgress);
18959 }
18960 };
18961
18962 updateHostText$1 = function (current, workInProgress, oldText, newText) {
18963 // If the text differs, mark it as an update. All the work in done in commitWork.
18964 if (oldText !== newText) {
18965 markUpdate(workInProgress);
18966 }
18967 };
18968 }
18969
18970 function cutOffTailIfNeeded(renderState, hasRenderedATailFallback) {
18971 switch (renderState.tailMode) {
18972 case 'hidden':
18973 {
18974 // Any insertions at the end of the tail list after this point
18975 // should be invisible. If there are already mounted boundaries
18976 // anything before them are not considered for collapsing.
18977 // Therefore we need to go through the whole tail to find if
18978 // there are any.
18979 var tailNode = renderState.tail;
18980 var lastTailNode = null;
18981
18982 while (tailNode !== null) {
18983 if (tailNode.alternate !== null) {
18984 lastTailNode = tailNode;
18985 }
18986
18987 tailNode = tailNode.sibling;
18988 } // Next we're simply going to delete all insertions after the
18989 // last rendered item.
18990
18991
18992 if (lastTailNode === null) {
18993 // All remaining items in the tail are insertions.
18994 renderState.tail = null;
18995 } else {
18996 // Detach the insertion after the last node that was already
18997 // inserted.
18998 lastTailNode.sibling = null;
18999 }
19000
19001 break;
19002 }
19003
19004 case 'collapsed':
19005 {
19006 // Any insertions at the end of the tail list after this point
19007 // should be invisible. If there are already mounted boundaries
19008 // anything before them are not considered for collapsing.
19009 // Therefore we need to go through the whole tail to find if
19010 // there are any.
19011 var _tailNode = renderState.tail;
19012 var _lastTailNode = null;
19013
19014 while (_tailNode !== null) {
19015 if (_tailNode.alternate !== null) {
19016 _lastTailNode = _tailNode;
19017 }
19018
19019 _tailNode = _tailNode.sibling;
19020 } // Next we're simply going to delete all insertions after the
19021 // last rendered item.
19022
19023
19024 if (_lastTailNode === null) {
19025 // All remaining items in the tail are insertions.
19026 if (!hasRenderedATailFallback && renderState.tail !== null) {
19027 // We suspended during the head. We want to show at least one
19028 // row at the tail. So we'll keep on and cut off the rest.
19029 renderState.tail.sibling = null;
19030 } else {
19031 renderState.tail = null;
19032 }
19033 } else {
19034 // Detach the insertion after the last node that was already
19035 // inserted.
19036 _lastTailNode.sibling = null;
19037 }
19038
19039 break;
19040 }
19041 }
19042 }
19043
19044 function completeWork(current, workInProgress, renderExpirationTime) {
19045 var newProps = workInProgress.pendingProps;
19046
19047 switch (workInProgress.tag) {
19048 case IndeterminateComponent:
19049 case LazyComponent:
19050 case SimpleMemoComponent:
19051 case FunctionComponent:
19052 case ForwardRef:
19053 case Fragment:
19054 case Mode:
19055 case Profiler:
19056 case ContextConsumer:
19057 case MemoComponent:
19058 return null;
19059
19060 case ClassComponent:
19061 {
19062 var Component = workInProgress.type;
19063
19064 if (isContextProvider(Component)) {
19065 popContext(workInProgress);
19066 }
19067
19068 return null;
19069 }
19070
19071 case HostRoot:
19072 {
19073 popHostContainer(workInProgress);
19074 popTopLevelContextObject(workInProgress);
19075 var fiberRoot = workInProgress.stateNode;
19076
19077 if (fiberRoot.pendingContext) {
19078 fiberRoot.context = fiberRoot.pendingContext;
19079 fiberRoot.pendingContext = null;
19080 }
19081
19082 if (current === null || current.child === null) {
19083 // If we hydrated, pop so that we can delete any remaining children
19084 // that weren't hydrated.
19085 var wasHydrated = popHydrationState(workInProgress);
19086
19087 if (wasHydrated) {
19088 // If we hydrated, then we'll need to schedule an update for
19089 // the commit side-effects on the root.
19090 markUpdate(workInProgress);
19091 }
19092 }
19093
19094 updateHostContainer(workInProgress);
19095 return null;
19096 }
19097
19098 case HostComponent:
19099 {
19100 popHostContext(workInProgress);
19101 var rootContainerInstance = getRootHostContainer();
19102 var type = workInProgress.type;
19103
19104 if (current !== null && workInProgress.stateNode != null) {
19105 updateHostComponent$1(current, workInProgress, type, newProps, rootContainerInstance);
19106
19107 if (current.ref !== workInProgress.ref) {
19108 markRef$1(workInProgress);
19109 }
19110 } else {
19111 if (!newProps) {
19112 if (!(workInProgress.stateNode !== null)) {
19113 {
19114 throw Error( "We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue." );
19115 }
19116 } // This can happen when we abort work.
19117
19118
19119 return null;
19120 }
19121
19122 var currentHostContext = getHostContext(); // TODO: Move createInstance to beginWork and keep it on a context
19123 // "stack" as the parent. Then append children as we go in beginWork
19124 // or completeWork depending on whether we want to add them top->down or
19125 // bottom->up. Top->down is faster in IE11.
19126
19127 var _wasHydrated = popHydrationState(workInProgress);
19128
19129 if (_wasHydrated) {
19130 // TODO: Move this and createInstance step into the beginPhase
19131 // to consolidate.
19132 if (prepareToHydrateHostInstance(workInProgress, rootContainerInstance, currentHostContext)) {
19133 // If changes to the hydrated node need to be applied at the
19134 // commit-phase we mark this as such.
19135 markUpdate(workInProgress);
19136 }
19137 } else {
19138 var instance = createInstance(type, newProps, rootContainerInstance, currentHostContext, workInProgress);
19139 appendAllChildren(instance, workInProgress, false, false); // This needs to be set before we mount Flare event listeners
19140
19141 workInProgress.stateNode = instance;
19142 // (eg DOM renderer supports auto-focus for certain elements).
19143 // Make sure such renderers get scheduled for later work.
19144
19145
19146 if (finalizeInitialChildren(instance, type, newProps, rootContainerInstance)) {
19147 markUpdate(workInProgress);
19148 }
19149 }
19150
19151 if (workInProgress.ref !== null) {
19152 // If there is a ref on a host node we need to schedule a callback
19153 markRef$1(workInProgress);
19154 }
19155 }
19156
19157 return null;
19158 }
19159
19160 case HostText:
19161 {
19162 var newText = newProps;
19163
19164 if (current && workInProgress.stateNode != null) {
19165 var oldText = current.memoizedProps; // If we have an alternate, that means this is an update and we need
19166 // to schedule a side-effect to do the updates.
19167
19168 updateHostText$1(current, workInProgress, oldText, newText);
19169 } else {
19170 if (typeof newText !== 'string') {
19171 if (!(workInProgress.stateNode !== null)) {
19172 {
19173 throw Error( "We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue." );
19174 }
19175 } // This can happen when we abort work.
19176
19177 }
19178
19179 var _rootContainerInstance = getRootHostContainer();
19180
19181 var _currentHostContext = getHostContext();
19182
19183 var _wasHydrated2 = popHydrationState(workInProgress);
19184
19185 if (_wasHydrated2) {
19186 if (prepareToHydrateHostTextInstance(workInProgress)) {
19187 markUpdate(workInProgress);
19188 }
19189 } else {
19190 workInProgress.stateNode = createTextInstance(newText, _rootContainerInstance, _currentHostContext, workInProgress);
19191 }
19192 }
19193
19194 return null;
19195 }
19196
19197 case SuspenseComponent:
19198 {
19199 popSuspenseContext(workInProgress);
19200 var nextState = workInProgress.memoizedState;
19201
19202 if ((workInProgress.effectTag & DidCapture) !== NoEffect) {
19203 // Something suspended. Re-render with the fallback children.
19204 workInProgress.expirationTime = renderExpirationTime; // Do not reset the effect list.
19205
19206 return workInProgress;
19207 }
19208
19209 var nextDidTimeout = nextState !== null;
19210 var prevDidTimeout = false;
19211
19212 if (current === null) {
19213 if (workInProgress.memoizedProps.fallback !== undefined) {
19214 popHydrationState(workInProgress);
19215 }
19216 } else {
19217 var prevState = current.memoizedState;
19218 prevDidTimeout = prevState !== null;
19219
19220 if (!nextDidTimeout && prevState !== null) {
19221 // We just switched from the fallback to the normal children.
19222 // Delete the fallback.
19223 // TODO: Would it be better to store the fallback fragment on
19224 // the stateNode during the begin phase?
19225 var currentFallbackChild = current.child.sibling;
19226
19227 if (currentFallbackChild !== null) {
19228 // Deletions go at the beginning of the return fiber's effect list
19229 var first = workInProgress.firstEffect;
19230
19231 if (first !== null) {
19232 workInProgress.firstEffect = currentFallbackChild;
19233 currentFallbackChild.nextEffect = first;
19234 } else {
19235 workInProgress.firstEffect = workInProgress.lastEffect = currentFallbackChild;
19236 currentFallbackChild.nextEffect = null;
19237 }
19238
19239 currentFallbackChild.effectTag = Deletion;
19240 }
19241 }
19242 }
19243
19244 if (nextDidTimeout && !prevDidTimeout) {
19245 // If this subtreee is running in blocking mode we can suspend,
19246 // otherwise we won't suspend.
19247 // TODO: This will still suspend a synchronous tree if anything
19248 // in the concurrent tree already suspended during this render.
19249 // This is a known bug.
19250 if ((workInProgress.mode & BlockingMode) !== NoMode) {
19251 // TODO: Move this back to throwException because this is too late
19252 // if this is a large tree which is common for initial loads. We
19253 // don't know if we should restart a render or not until we get
19254 // this marker, and this is too late.
19255 // If this render already had a ping or lower pri updates,
19256 // and this is the first time we know we're going to suspend we
19257 // should be able to immediately restart from within throwException.
19258 var hasInvisibleChildContext = current === null && workInProgress.memoizedProps.unstable_avoidThisFallback !== true;
19259
19260 if (hasInvisibleChildContext || hasSuspenseContext(suspenseStackCursor.current, InvisibleParentSuspenseContext)) {
19261 // If this was in an invisible tree or a new render, then showing
19262 // this boundary is ok.
19263 renderDidSuspend();
19264 } else {
19265 // Otherwise, we're going to have to hide content so we should
19266 // suspend for longer if possible.
19267 renderDidSuspendDelayIfPossible();
19268 }
19269 }
19270 }
19271
19272 {
19273 // TODO: Only schedule updates if these values are non equal, i.e. it changed.
19274 if (nextDidTimeout || prevDidTimeout) {
19275 // If this boundary just timed out, schedule an effect to attach a
19276 // retry listener to the promise. This flag is also used to hide the
19277 // primary children. In mutation mode, we also need the flag to
19278 // *unhide* children that were previously hidden, so check if this
19279 // is currently timed out, too.
19280 workInProgress.effectTag |= Update;
19281 }
19282 }
19283
19284 return null;
19285 }
19286
19287 case HostPortal:
19288 popHostContainer(workInProgress);
19289 updateHostContainer(workInProgress);
19290 return null;
19291
19292 case ContextProvider:
19293 // Pop provider fiber
19294 popProvider(workInProgress);
19295 return null;
19296
19297 case IncompleteClassComponent:
19298 {
19299 // Same as class component case. I put it down here so that the tags are
19300 // sequential to ensure this switch is compiled to a jump table.
19301 var _Component = workInProgress.type;
19302
19303 if (isContextProvider(_Component)) {
19304 popContext(workInProgress);
19305 }
19306
19307 return null;
19308 }
19309
19310 case SuspenseListComponent:
19311 {
19312 popSuspenseContext(workInProgress);
19313 var renderState = workInProgress.memoizedState;
19314
19315 if (renderState === null) {
19316 // We're running in the default, "independent" mode.
19317 // We don't do anything in this mode.
19318 return null;
19319 }
19320
19321 var didSuspendAlready = (workInProgress.effectTag & DidCapture) !== NoEffect;
19322 var renderedTail = renderState.rendering;
19323
19324 if (renderedTail === null) {
19325 // We just rendered the head.
19326 if (!didSuspendAlready) {
19327 // This is the first pass. We need to figure out if anything is still
19328 // suspended in the rendered set.
19329 // If new content unsuspended, but there's still some content that
19330 // didn't. Then we need to do a second pass that forces everything
19331 // to keep showing their fallbacks.
19332 // We might be suspended if something in this render pass suspended, or
19333 // something in the previous committed pass suspended. Otherwise,
19334 // there's no chance so we can skip the expensive call to
19335 // findFirstSuspended.
19336 var cannotBeSuspended = renderHasNotSuspendedYet() && (current === null || (current.effectTag & DidCapture) === NoEffect);
19337
19338 if (!cannotBeSuspended) {
19339 var row = workInProgress.child;
19340
19341 while (row !== null) {
19342 var suspended = findFirstSuspended(row);
19343
19344 if (suspended !== null) {
19345 didSuspendAlready = true;
19346 workInProgress.effectTag |= DidCapture;
19347 cutOffTailIfNeeded(renderState, false); // If this is a newly suspended tree, it might not get committed as
19348 // part of the second pass. In that case nothing will subscribe to
19349 // its thennables. Instead, we'll transfer its thennables to the
19350 // SuspenseList so that it can retry if they resolve.
19351 // There might be multiple of these in the list but since we're
19352 // going to wait for all of them anyway, it doesn't really matter
19353 // which ones gets to ping. In theory we could get clever and keep
19354 // track of how many dependencies remain but it gets tricky because
19355 // in the meantime, we can add/remove/change items and dependencies.
19356 // We might bail out of the loop before finding any but that
19357 // doesn't matter since that means that the other boundaries that
19358 // we did find already has their listeners attached.
19359
19360 var newThennables = suspended.updateQueue;
19361
19362 if (newThennables !== null) {
19363 workInProgress.updateQueue = newThennables;
19364 workInProgress.effectTag |= Update;
19365 } // Rerender the whole list, but this time, we'll force fallbacks
19366 // to stay in place.
19367 // Reset the effect list before doing the second pass since that's now invalid.
19368
19369
19370 if (renderState.lastEffect === null) {
19371 workInProgress.firstEffect = null;
19372 }
19373
19374 workInProgress.lastEffect = renderState.lastEffect; // Reset the child fibers to their original state.
19375
19376 resetChildFibers(workInProgress, renderExpirationTime); // Set up the Suspense Context to force suspense and immediately
19377 // rerender the children.
19378
19379 pushSuspenseContext(workInProgress, setShallowSuspenseContext(suspenseStackCursor.current, ForceSuspenseFallback));
19380 return workInProgress.child;
19381 }
19382
19383 row = row.sibling;
19384 }
19385 }
19386 } else {
19387 cutOffTailIfNeeded(renderState, false);
19388 } // Next we're going to render the tail.
19389
19390 } else {
19391 // Append the rendered row to the child list.
19392 if (!didSuspendAlready) {
19393 var _suspended = findFirstSuspended(renderedTail);
19394
19395 if (_suspended !== null) {
19396 workInProgress.effectTag |= DidCapture;
19397 didSuspendAlready = true; // Ensure we transfer the update queue to the parent so that it doesn't
19398 // get lost if this row ends up dropped during a second pass.
19399
19400 var _newThennables = _suspended.updateQueue;
19401
19402 if (_newThennables !== null) {
19403 workInProgress.updateQueue = _newThennables;
19404 workInProgress.effectTag |= Update;
19405 }
19406
19407 cutOffTailIfNeeded(renderState, true); // This might have been modified.
19408
19409 if (renderState.tail === null && renderState.tailMode === 'hidden' && !renderedTail.alternate) {
19410 // We need to delete the row we just rendered.
19411 // Reset the effect list to what it was before we rendered this
19412 // child. The nested children have already appended themselves.
19413 var lastEffect = workInProgress.lastEffect = renderState.lastEffect; // Remove any effects that were appended after this point.
19414
19415 if (lastEffect !== null) {
19416 lastEffect.nextEffect = null;
19417 } // We're done.
19418
19419
19420 return null;
19421 }
19422 } else if ( // The time it took to render last row is greater than time until
19423 // the expiration.
19424 now() * 2 - renderState.renderingStartTime > renderState.tailExpiration && renderExpirationTime > Never) {
19425 // We have now passed our CPU deadline and we'll just give up further
19426 // attempts to render the main content and only render fallbacks.
19427 // The assumption is that this is usually faster.
19428 workInProgress.effectTag |= DidCapture;
19429 didSuspendAlready = true;
19430 cutOffTailIfNeeded(renderState, false); // Since nothing actually suspended, there will nothing to ping this
19431 // to get it started back up to attempt the next item. If we can show
19432 // them, then they really have the same priority as this render.
19433 // So we'll pick it back up the very next render pass once we've had
19434 // an opportunity to yield for paint.
19435
19436 var nextPriority = renderExpirationTime - 1;
19437 workInProgress.expirationTime = workInProgress.childExpirationTime = nextPriority;
19438
19439 {
19440 markSpawnedWork(nextPriority);
19441 }
19442 }
19443 }
19444
19445 if (renderState.isBackwards) {
19446 // The effect list of the backwards tail will have been added
19447 // to the end. This breaks the guarantee that life-cycles fire in
19448 // sibling order but that isn't a strong guarantee promised by React.
19449 // Especially since these might also just pop in during future commits.
19450 // Append to the beginning of the list.
19451 renderedTail.sibling = workInProgress.child;
19452 workInProgress.child = renderedTail;
19453 } else {
19454 var previousSibling = renderState.last;
19455
19456 if (previousSibling !== null) {
19457 previousSibling.sibling = renderedTail;
19458 } else {
19459 workInProgress.child = renderedTail;
19460 }
19461
19462 renderState.last = renderedTail;
19463 }
19464 }
19465
19466 if (renderState.tail !== null) {
19467 // We still have tail rows to render.
19468 if (renderState.tailExpiration === 0) {
19469 // Heuristic for how long we're willing to spend rendering rows
19470 // until we just give up and show what we have so far.
19471 var TAIL_EXPIRATION_TIMEOUT_MS = 500;
19472 renderState.tailExpiration = now() + TAIL_EXPIRATION_TIMEOUT_MS; // TODO: This is meant to mimic the train model or JND but this
19473 // is a per component value. It should really be since the start
19474 // of the total render or last commit. Consider using something like
19475 // globalMostRecentFallbackTime. That doesn't account for being
19476 // suspended for part of the time or when it's a new render.
19477 // It should probably use a global start time value instead.
19478 } // Pop a row.
19479
19480
19481 var next = renderState.tail;
19482 renderState.rendering = next;
19483 renderState.tail = next.sibling;
19484 renderState.lastEffect = workInProgress.lastEffect;
19485 renderState.renderingStartTime = now();
19486 next.sibling = null; // Restore the context.
19487 // TODO: We can probably just avoid popping it instead and only
19488 // setting it the first time we go from not suspended to suspended.
19489
19490 var suspenseContext = suspenseStackCursor.current;
19491
19492 if (didSuspendAlready) {
19493 suspenseContext = setShallowSuspenseContext(suspenseContext, ForceSuspenseFallback);
19494 } else {
19495 suspenseContext = setDefaultShallowSuspenseContext(suspenseContext);
19496 }
19497
19498 pushSuspenseContext(workInProgress, suspenseContext); // Do a pass over the next row.
19499
19500 return next;
19501 }
19502
19503 return null;
19504 }
19505 }
19506
19507 {
19508 {
19509 throw Error( "Unknown unit of work tag (" + workInProgress.tag + "). This error is likely caused by a bug in React. Please file an issue." );
19510 }
19511 }
19512 }
19513
19514 function unwindWork(workInProgress, renderExpirationTime) {
19515 switch (workInProgress.tag) {
19516 case ClassComponent:
19517 {
19518 var Component = workInProgress.type;
19519
19520 if (isContextProvider(Component)) {
19521 popContext(workInProgress);
19522 }
19523
19524 var effectTag = workInProgress.effectTag;
19525
19526 if (effectTag & ShouldCapture) {
19527 workInProgress.effectTag = effectTag & ~ShouldCapture | DidCapture;
19528 return workInProgress;
19529 }
19530
19531 return null;
19532 }
19533
19534 case HostRoot:
19535 {
19536 popHostContainer(workInProgress);
19537 popTopLevelContextObject(workInProgress);
19538 var _effectTag = workInProgress.effectTag;
19539
19540 if (!((_effectTag & DidCapture) === NoEffect)) {
19541 {
19542 throw Error( "The root failed to unmount after an error. This is likely a bug in React. Please file an issue." );
19543 }
19544 }
19545
19546 workInProgress.effectTag = _effectTag & ~ShouldCapture | DidCapture;
19547 return workInProgress;
19548 }
19549
19550 case HostComponent:
19551 {
19552 // TODO: popHydrationState
19553 popHostContext(workInProgress);
19554 return null;
19555 }
19556
19557 case SuspenseComponent:
19558 {
19559 popSuspenseContext(workInProgress);
19560
19561 var _effectTag2 = workInProgress.effectTag;
19562
19563 if (_effectTag2 & ShouldCapture) {
19564 workInProgress.effectTag = _effectTag2 & ~ShouldCapture | DidCapture; // Captured a suspense effect. Re-render the boundary.
19565
19566 return workInProgress;
19567 }
19568
19569 return null;
19570 }
19571
19572 case SuspenseListComponent:
19573 {
19574 popSuspenseContext(workInProgress); // SuspenseList doesn't actually catch anything. It should've been
19575 // caught by a nested boundary. If not, it should bubble through.
19576
19577 return null;
19578 }
19579
19580 case HostPortal:
19581 popHostContainer(workInProgress);
19582 return null;
19583
19584 case ContextProvider:
19585 popProvider(workInProgress);
19586 return null;
19587
19588 default:
19589 return null;
19590 }
19591 }
19592
19593 function unwindInterruptedWork(interruptedWork) {
19594 switch (interruptedWork.tag) {
19595 case ClassComponent:
19596 {
19597 var childContextTypes = interruptedWork.type.childContextTypes;
19598
19599 if (childContextTypes !== null && childContextTypes !== undefined) {
19600 popContext(interruptedWork);
19601 }
19602
19603 break;
19604 }
19605
19606 case HostRoot:
19607 {
19608 popHostContainer(interruptedWork);
19609 popTopLevelContextObject(interruptedWork);
19610 break;
19611 }
19612
19613 case HostComponent:
19614 {
19615 popHostContext(interruptedWork);
19616 break;
19617 }
19618
19619 case HostPortal:
19620 popHostContainer(interruptedWork);
19621 break;
19622
19623 case SuspenseComponent:
19624 popSuspenseContext(interruptedWork);
19625 break;
19626
19627 case SuspenseListComponent:
19628 popSuspenseContext(interruptedWork);
19629 break;
19630
19631 case ContextProvider:
19632 popProvider(interruptedWork);
19633 break;
19634 }
19635 }
19636
19637 function createCapturedValue(value, source) {
19638 // If the value is an error, call this function immediately after it is thrown
19639 // so the stack is accurate.
19640 return {
19641 value: value,
19642 source: source,
19643 stack: getStackByFiberInDevAndProd(source)
19644 };
19645 }
19646
19647 function logCapturedError(capturedError) {
19648
19649 var error = capturedError.error;
19650
19651 {
19652 var componentName = capturedError.componentName,
19653 componentStack = capturedError.componentStack,
19654 errorBoundaryName = capturedError.errorBoundaryName,
19655 errorBoundaryFound = capturedError.errorBoundaryFound,
19656 willRetry = capturedError.willRetry; // Browsers support silencing uncaught errors by calling
19657 // `preventDefault()` in window `error` handler.
19658 // We record this information as an expando on the error.
19659
19660 if (error != null && error._suppressLogging) {
19661 if (errorBoundaryFound && willRetry) {
19662 // The error is recoverable and was silenced.
19663 // Ignore it and don't print the stack addendum.
19664 // This is handy for testing error boundaries without noise.
19665 return;
19666 } // The error is fatal. Since the silencing might have
19667 // been accidental, we'll surface it anyway.
19668 // However, the browser would have silenced the original error
19669 // so we'll print it first, and then print the stack addendum.
19670
19671
19672 console['error'](error); // Don't transform to our wrapper
19673 // For a more detailed description of this block, see:
19674 // https://github.com/facebook/react/pull/13384
19675 }
19676
19677 var componentNameMessage = componentName ? "The above error occurred in the <" + componentName + "> component:" : 'The above error occurred in one of your React components:';
19678 var errorBoundaryMessage; // errorBoundaryFound check is sufficient; errorBoundaryName check is to satisfy Flow.
19679
19680 if (errorBoundaryFound && errorBoundaryName) {
19681 if (willRetry) {
19682 errorBoundaryMessage = "React will try to recreate this component tree from scratch " + ("using the error boundary you provided, " + errorBoundaryName + ".");
19683 } else {
19684 errorBoundaryMessage = "This error was initially handled by the error boundary " + errorBoundaryName + ".\n" + "Recreating the tree from scratch failed so React will unmount the tree.";
19685 }
19686 } else {
19687 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.';
19688 }
19689
19690 var combinedMessage = "" + componentNameMessage + componentStack + "\n\n" + ("" + errorBoundaryMessage); // In development, we provide our own message with just the component stack.
19691 // We don't include the original error message and JS stack because the browser
19692 // has already printed it. Even if the application swallows the error, it is still
19693 // displayed by the browser thanks to the DEV-only fake event trick in ReactErrorUtils.
19694
19695 console['error'](combinedMessage); // Don't transform to our wrapper
19696 }
19697 }
19698
19699 var didWarnAboutUndefinedSnapshotBeforeUpdate = null;
19700
19701 {
19702 didWarnAboutUndefinedSnapshotBeforeUpdate = new Set();
19703 }
19704
19705 var PossiblyWeakSet = typeof WeakSet === 'function' ? WeakSet : Set;
19706 function logError(boundary, errorInfo) {
19707 var source = errorInfo.source;
19708 var stack = errorInfo.stack;
19709
19710 if (stack === null && source !== null) {
19711 stack = getStackByFiberInDevAndProd(source);
19712 }
19713
19714 var capturedError = {
19715 componentName: source !== null ? getComponentName(source.type) : null,
19716 componentStack: stack !== null ? stack : '',
19717 error: errorInfo.value,
19718 errorBoundary: null,
19719 errorBoundaryName: null,
19720 errorBoundaryFound: false,
19721 willRetry: false
19722 };
19723
19724 if (boundary !== null && boundary.tag === ClassComponent) {
19725 capturedError.errorBoundary = boundary.stateNode;
19726 capturedError.errorBoundaryName = getComponentName(boundary.type);
19727 capturedError.errorBoundaryFound = true;
19728 capturedError.willRetry = true;
19729 }
19730
19731 try {
19732 logCapturedError(capturedError);
19733 } catch (e) {
19734 // This method must not throw, or React internal state will get messed up.
19735 // If console.error is overridden, or logCapturedError() shows a dialog that throws,
19736 // we want to report this error outside of the normal stack as a last resort.
19737 // https://github.com/facebook/react/issues/13188
19738 setTimeout(function () {
19739 throw e;
19740 });
19741 }
19742 }
19743
19744 var callComponentWillUnmountWithTimer = function (current, instance) {
19745 startPhaseTimer(current, 'componentWillUnmount');
19746 instance.props = current.memoizedProps;
19747 instance.state = current.memoizedState;
19748 instance.componentWillUnmount();
19749 stopPhaseTimer();
19750 }; // Capture errors so they don't interrupt unmounting.
19751
19752
19753 function safelyCallComponentWillUnmount(current, instance) {
19754 {
19755 invokeGuardedCallback(null, callComponentWillUnmountWithTimer, null, current, instance);
19756
19757 if (hasCaughtError()) {
19758 var unmountError = clearCaughtError();
19759 captureCommitPhaseError(current, unmountError);
19760 }
19761 }
19762 }
19763
19764 function safelyDetachRef(current) {
19765 var ref = current.ref;
19766
19767 if (ref !== null) {
19768 if (typeof ref === 'function') {
19769 {
19770 invokeGuardedCallback(null, ref, null, null);
19771
19772 if (hasCaughtError()) {
19773 var refError = clearCaughtError();
19774 captureCommitPhaseError(current, refError);
19775 }
19776 }
19777 } else {
19778 ref.current = null;
19779 }
19780 }
19781 }
19782
19783 function safelyCallDestroy(current, destroy) {
19784 {
19785 invokeGuardedCallback(null, destroy, null);
19786
19787 if (hasCaughtError()) {
19788 var error = clearCaughtError();
19789 captureCommitPhaseError(current, error);
19790 }
19791 }
19792 }
19793
19794 function commitBeforeMutationLifeCycles(current, finishedWork) {
19795 switch (finishedWork.tag) {
19796 case FunctionComponent:
19797 case ForwardRef:
19798 case SimpleMemoComponent:
19799 case Block:
19800 {
19801 return;
19802 }
19803
19804 case ClassComponent:
19805 {
19806 if (finishedWork.effectTag & Snapshot) {
19807 if (current !== null) {
19808 var prevProps = current.memoizedProps;
19809 var prevState = current.memoizedState;
19810 startPhaseTimer(finishedWork, 'getSnapshotBeforeUpdate');
19811 var instance = finishedWork.stateNode; // We could update instance props and state here,
19812 // but instead we rely on them being set during last render.
19813 // TODO: revisit this when we implement resuming.
19814
19815 {
19816 if (finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps) {
19817 if (instance.props !== finishedWork.memoizedProps) {
19818 error('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');
19819 }
19820
19821 if (instance.state !== finishedWork.memoizedState) {
19822 error('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');
19823 }
19824 }
19825 }
19826
19827 var snapshot = instance.getSnapshotBeforeUpdate(finishedWork.elementType === finishedWork.type ? prevProps : resolveDefaultProps(finishedWork.type, prevProps), prevState);
19828
19829 {
19830 var didWarnSet = didWarnAboutUndefinedSnapshotBeforeUpdate;
19831
19832 if (snapshot === undefined && !didWarnSet.has(finishedWork.type)) {
19833 didWarnSet.add(finishedWork.type);
19834
19835 error('%s.getSnapshotBeforeUpdate(): A snapshot value (or null) ' + 'must be returned. You have returned undefined.', getComponentName(finishedWork.type));
19836 }
19837 }
19838
19839 instance.__reactInternalSnapshotBeforeUpdate = snapshot;
19840 stopPhaseTimer();
19841 }
19842 }
19843
19844 return;
19845 }
19846
19847 case HostRoot:
19848 case HostComponent:
19849 case HostText:
19850 case HostPortal:
19851 case IncompleteClassComponent:
19852 // Nothing to do for these component types
19853 return;
19854 }
19855
19856 {
19857 {
19858 throw 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." );
19859 }
19860 }
19861 }
19862
19863 function commitHookEffectListUnmount(tag, finishedWork) {
19864 var updateQueue = finishedWork.updateQueue;
19865 var lastEffect = updateQueue !== null ? updateQueue.lastEffect : null;
19866
19867 if (lastEffect !== null) {
19868 var firstEffect = lastEffect.next;
19869 var effect = firstEffect;
19870
19871 do {
19872 if ((effect.tag & tag) === tag) {
19873 // Unmount
19874 var destroy = effect.destroy;
19875 effect.destroy = undefined;
19876
19877 if (destroy !== undefined) {
19878 destroy();
19879 }
19880 }
19881
19882 effect = effect.next;
19883 } while (effect !== firstEffect);
19884 }
19885 }
19886
19887 function commitHookEffectListMount(tag, finishedWork) {
19888 var updateQueue = finishedWork.updateQueue;
19889 var lastEffect = updateQueue !== null ? updateQueue.lastEffect : null;
19890
19891 if (lastEffect !== null) {
19892 var firstEffect = lastEffect.next;
19893 var effect = firstEffect;
19894
19895 do {
19896 if ((effect.tag & tag) === tag) {
19897 // Mount
19898 var create = effect.create;
19899 effect.destroy = create();
19900
19901 {
19902 var destroy = effect.destroy;
19903
19904 if (destroy !== undefined && typeof destroy !== 'function') {
19905 var addendum = void 0;
19906
19907 if (destroy === null) {
19908 addendum = ' You returned null. If your effect does not require clean ' + 'up, return undefined (or nothing).';
19909 } else if (typeof destroy.then === 'function') {
19910 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';
19911 } else {
19912 addendum = ' You returned: ' + destroy;
19913 }
19914
19915 error('An effect function must not return anything besides a function, ' + 'which is used for clean-up.%s%s', addendum, getStackByFiberInDevAndProd(finishedWork));
19916 }
19917 }
19918 }
19919
19920 effect = effect.next;
19921 } while (effect !== firstEffect);
19922 }
19923 }
19924
19925 function commitPassiveHookEffects(finishedWork) {
19926 if ((finishedWork.effectTag & Passive) !== NoEffect) {
19927 switch (finishedWork.tag) {
19928 case FunctionComponent:
19929 case ForwardRef:
19930 case SimpleMemoComponent:
19931 case Block:
19932 {
19933 // TODO (#17945) We should call all passive destroy functions (for all fibers)
19934 // before calling any create functions. The current approach only serializes
19935 // these for a single fiber.
19936 commitHookEffectListUnmount(Passive$1 | HasEffect, finishedWork);
19937 commitHookEffectListMount(Passive$1 | HasEffect, finishedWork);
19938 break;
19939 }
19940 }
19941 }
19942 }
19943
19944 function commitLifeCycles(finishedRoot, current, finishedWork, committedExpirationTime) {
19945 switch (finishedWork.tag) {
19946 case FunctionComponent:
19947 case ForwardRef:
19948 case SimpleMemoComponent:
19949 case Block:
19950 {
19951 // At this point layout effects have already been destroyed (during mutation phase).
19952 // This is done to prevent sibling component effects from interfering with each other,
19953 // e.g. a destroy function in one component should never override a ref set
19954 // by a create function in another component during the same commit.
19955 commitHookEffectListMount(Layout | HasEffect, finishedWork);
19956
19957 return;
19958 }
19959
19960 case ClassComponent:
19961 {
19962 var instance = finishedWork.stateNode;
19963
19964 if (finishedWork.effectTag & Update) {
19965 if (current === null) {
19966 startPhaseTimer(finishedWork, 'componentDidMount'); // We could update instance props and state here,
19967 // but instead we rely on them being set during last render.
19968 // TODO: revisit this when we implement resuming.
19969
19970 {
19971 if (finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps) {
19972 if (instance.props !== finishedWork.memoizedProps) {
19973 error('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');
19974 }
19975
19976 if (instance.state !== finishedWork.memoizedState) {
19977 error('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');
19978 }
19979 }
19980 }
19981
19982 instance.componentDidMount();
19983 stopPhaseTimer();
19984 } else {
19985 var prevProps = finishedWork.elementType === finishedWork.type ? current.memoizedProps : resolveDefaultProps(finishedWork.type, current.memoizedProps);
19986 var prevState = current.memoizedState;
19987 startPhaseTimer(finishedWork, 'componentDidUpdate'); // We could update instance props and state here,
19988 // but instead we rely on them being set during last render.
19989 // TODO: revisit this when we implement resuming.
19990
19991 {
19992 if (finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps) {
19993 if (instance.props !== finishedWork.memoizedProps) {
19994 error('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');
19995 }
19996
19997 if (instance.state !== finishedWork.memoizedState) {
19998 error('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');
19999 }
20000 }
20001 }
20002
20003 instance.componentDidUpdate(prevProps, prevState, instance.__reactInternalSnapshotBeforeUpdate);
20004 stopPhaseTimer();
20005 }
20006 }
20007
20008 var updateQueue = finishedWork.updateQueue;
20009
20010 if (updateQueue !== null) {
20011 {
20012 if (finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps) {
20013 if (instance.props !== finishedWork.memoizedProps) {
20014 error('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');
20015 }
20016
20017 if (instance.state !== finishedWork.memoizedState) {
20018 error('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');
20019 }
20020 }
20021 } // We could update instance props and state here,
20022 // but instead we rely on them being set during last render.
20023 // TODO: revisit this when we implement resuming.
20024
20025
20026 commitUpdateQueue(finishedWork, updateQueue, instance);
20027 }
20028
20029 return;
20030 }
20031
20032 case HostRoot:
20033 {
20034 var _updateQueue = finishedWork.updateQueue;
20035
20036 if (_updateQueue !== null) {
20037 var _instance = null;
20038
20039 if (finishedWork.child !== null) {
20040 switch (finishedWork.child.tag) {
20041 case HostComponent:
20042 _instance = getPublicInstance(finishedWork.child.stateNode);
20043 break;
20044
20045 case ClassComponent:
20046 _instance = finishedWork.child.stateNode;
20047 break;
20048 }
20049 }
20050
20051 commitUpdateQueue(finishedWork, _updateQueue, _instance);
20052 }
20053
20054 return;
20055 }
20056
20057 case HostComponent:
20058 {
20059 var _instance2 = finishedWork.stateNode; // Renderers may schedule work to be done after host components are mounted
20060 // (eg DOM renderer may schedule auto-focus for inputs and form controls).
20061 // These effects should only be committed when components are first mounted,
20062 // aka when there is no current/alternate.
20063
20064 if (current === null && finishedWork.effectTag & Update) {
20065 var type = finishedWork.type;
20066 var props = finishedWork.memoizedProps;
20067 commitMount(_instance2, type, props);
20068 }
20069
20070 return;
20071 }
20072
20073 case HostText:
20074 {
20075 // We have no life-cycles associated with text.
20076 return;
20077 }
20078
20079 case HostPortal:
20080 {
20081 // We have no life-cycles associated with portals.
20082 return;
20083 }
20084
20085 case Profiler:
20086 {
20087 {
20088 var onRender = finishedWork.memoizedProps.onRender;
20089
20090 if (typeof onRender === 'function') {
20091 {
20092 onRender(finishedWork.memoizedProps.id, current === null ? 'mount' : 'update', finishedWork.actualDuration, finishedWork.treeBaseDuration, finishedWork.actualStartTime, getCommitTime(), finishedRoot.memoizedInteractions);
20093 }
20094 }
20095 }
20096
20097 return;
20098 }
20099
20100 case SuspenseComponent:
20101 {
20102 commitSuspenseHydrationCallbacks(finishedRoot, finishedWork);
20103 return;
20104 }
20105
20106 case SuspenseListComponent:
20107 case IncompleteClassComponent:
20108 case FundamentalComponent:
20109 case ScopeComponent:
20110 return;
20111 }
20112
20113 {
20114 {
20115 throw 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." );
20116 }
20117 }
20118 }
20119
20120 function hideOrUnhideAllChildren(finishedWork, isHidden) {
20121 {
20122 // We only have the top Fiber that was inserted but we need to recurse down its
20123 // children to find all the terminal nodes.
20124 var node = finishedWork;
20125
20126 while (true) {
20127 if (node.tag === HostComponent) {
20128 var instance = node.stateNode;
20129
20130 if (isHidden) {
20131 hideInstance(instance);
20132 } else {
20133 unhideInstance(node.stateNode, node.memoizedProps);
20134 }
20135 } else if (node.tag === HostText) {
20136 var _instance3 = node.stateNode;
20137
20138 if (isHidden) {
20139 hideTextInstance(_instance3);
20140 } else {
20141 unhideTextInstance(_instance3, node.memoizedProps);
20142 }
20143 } else if (node.tag === SuspenseComponent && node.memoizedState !== null && node.memoizedState.dehydrated === null) {
20144 // Found a nested Suspense component that timed out. Skip over the
20145 // primary child fragment, which should remain hidden.
20146 var fallbackChildFragment = node.child.sibling;
20147 fallbackChildFragment.return = node;
20148 node = fallbackChildFragment;
20149 continue;
20150 } else if (node.child !== null) {
20151 node.child.return = node;
20152 node = node.child;
20153 continue;
20154 }
20155
20156 if (node === finishedWork) {
20157 return;
20158 }
20159
20160 while (node.sibling === null) {
20161 if (node.return === null || node.return === finishedWork) {
20162 return;
20163 }
20164
20165 node = node.return;
20166 }
20167
20168 node.sibling.return = node.return;
20169 node = node.sibling;
20170 }
20171 }
20172 }
20173
20174 function commitAttachRef(finishedWork) {
20175 var ref = finishedWork.ref;
20176
20177 if (ref !== null) {
20178 var instance = finishedWork.stateNode;
20179 var instanceToUse;
20180
20181 switch (finishedWork.tag) {
20182 case HostComponent:
20183 instanceToUse = getPublicInstance(instance);
20184 break;
20185
20186 default:
20187 instanceToUse = instance;
20188 } // Moved outside to ensure DCE works with this flag
20189
20190 if (typeof ref === 'function') {
20191 ref(instanceToUse);
20192 } else {
20193 {
20194 if (!ref.hasOwnProperty('current')) {
20195 error('Unexpected ref object provided for %s. ' + 'Use either a ref-setter function or React.createRef().%s', getComponentName(finishedWork.type), getStackByFiberInDevAndProd(finishedWork));
20196 }
20197 }
20198
20199 ref.current = instanceToUse;
20200 }
20201 }
20202 }
20203
20204 function commitDetachRef(current) {
20205 var currentRef = current.ref;
20206
20207 if (currentRef !== null) {
20208 if (typeof currentRef === 'function') {
20209 currentRef(null);
20210 } else {
20211 currentRef.current = null;
20212 }
20213 }
20214 } // User-originating errors (lifecycles and refs) should not interrupt
20215 // deletion, so don't let them throw. Host-originating errors should
20216 // interrupt deletion, so it's okay
20217
20218
20219 function commitUnmount(finishedRoot, current, renderPriorityLevel) {
20220 onCommitUnmount(current);
20221
20222 switch (current.tag) {
20223 case FunctionComponent:
20224 case ForwardRef:
20225 case MemoComponent:
20226 case SimpleMemoComponent:
20227 case Block:
20228 {
20229 var updateQueue = current.updateQueue;
20230
20231 if (updateQueue !== null) {
20232 var lastEffect = updateQueue.lastEffect;
20233
20234 if (lastEffect !== null) {
20235 var firstEffect = lastEffect.next;
20236
20237 {
20238 // When the owner fiber is deleted, the destroy function of a passive
20239 // effect hook is called during the synchronous commit phase. This is
20240 // a concession to implementation complexity. Calling it in the
20241 // passive effect phase (like they usually are, when dependencies
20242 // change during an update) would require either traversing the
20243 // children of the deleted fiber again, or including unmount effects
20244 // as part of the fiber effect list.
20245 //
20246 // Because this is during the sync commit phase, we need to change
20247 // the priority.
20248 //
20249 // TODO: Reconsider this implementation trade off.
20250 var priorityLevel = renderPriorityLevel > NormalPriority ? NormalPriority : renderPriorityLevel;
20251 runWithPriority$1(priorityLevel, function () {
20252 var effect = firstEffect;
20253
20254 do {
20255 var _destroy = effect.destroy;
20256
20257 if (_destroy !== undefined) {
20258 safelyCallDestroy(current, _destroy);
20259 }
20260
20261 effect = effect.next;
20262 } while (effect !== firstEffect);
20263 });
20264 }
20265 }
20266 }
20267
20268 return;
20269 }
20270
20271 case ClassComponent:
20272 {
20273 safelyDetachRef(current);
20274 var instance = current.stateNode;
20275
20276 if (typeof instance.componentWillUnmount === 'function') {
20277 safelyCallComponentWillUnmount(current, instance);
20278 }
20279
20280 return;
20281 }
20282
20283 case HostComponent:
20284 {
20285
20286 safelyDetachRef(current);
20287 return;
20288 }
20289
20290 case HostPortal:
20291 {
20292 // TODO: this is recursive.
20293 // We are also not using this parent because
20294 // the portal will get pushed immediately.
20295 {
20296 unmountHostComponents(finishedRoot, current, renderPriorityLevel);
20297 }
20298
20299 return;
20300 }
20301
20302 case FundamentalComponent:
20303 {
20304
20305 return;
20306 }
20307
20308 case DehydratedFragment:
20309 {
20310
20311 return;
20312 }
20313
20314 case ScopeComponent:
20315 {
20316
20317 return;
20318 }
20319 }
20320 }
20321
20322 function commitNestedUnmounts(finishedRoot, root, renderPriorityLevel) {
20323 // While we're inside a removed host node we don't want to call
20324 // removeChild on the inner nodes because they're removed by the top
20325 // call anyway. We also want to call componentWillUnmount on all
20326 // composites before this host node is removed from the tree. Therefore
20327 // we do an inner loop while we're still inside the host node.
20328 var node = root;
20329
20330 while (true) {
20331 commitUnmount(finishedRoot, node, renderPriorityLevel); // Visit children because they may contain more composite or host nodes.
20332 // Skip portals because commitUnmount() currently visits them recursively.
20333
20334 if (node.child !== null && ( // If we use mutation we drill down into portals using commitUnmount above.
20335 // If we don't use mutation we drill down into portals here instead.
20336 node.tag !== HostPortal)) {
20337 node.child.return = node;
20338 node = node.child;
20339 continue;
20340 }
20341
20342 if (node === root) {
20343 return;
20344 }
20345
20346 while (node.sibling === null) {
20347 if (node.return === null || node.return === root) {
20348 return;
20349 }
20350
20351 node = node.return;
20352 }
20353
20354 node.sibling.return = node.return;
20355 node = node.sibling;
20356 }
20357 }
20358
20359 function detachFiber(current) {
20360 var alternate = current.alternate; // Cut off the return pointers to disconnect it from the tree. Ideally, we
20361 // should clear the child pointer of the parent alternate to let this
20362 // get GC:ed but we don't know which for sure which parent is the current
20363 // one so we'll settle for GC:ing the subtree of this child. This child
20364 // itself will be GC:ed when the parent updates the next time.
20365
20366 current.return = null;
20367 current.child = null;
20368 current.memoizedState = null;
20369 current.updateQueue = null;
20370 current.dependencies = null;
20371 current.alternate = null;
20372 current.firstEffect = null;
20373 current.lastEffect = null;
20374 current.pendingProps = null;
20375 current.memoizedProps = null;
20376 current.stateNode = null;
20377
20378 if (alternate !== null) {
20379 detachFiber(alternate);
20380 }
20381 }
20382
20383 function getHostParentFiber(fiber) {
20384 var parent = fiber.return;
20385
20386 while (parent !== null) {
20387 if (isHostParent(parent)) {
20388 return parent;
20389 }
20390
20391 parent = parent.return;
20392 }
20393
20394 {
20395 {
20396 throw Error( "Expected to find a host parent. This error is likely caused by a bug in React. Please file an issue." );
20397 }
20398 }
20399 }
20400
20401 function isHostParent(fiber) {
20402 return fiber.tag === HostComponent || fiber.tag === HostRoot || fiber.tag === HostPortal;
20403 }
20404
20405 function getHostSibling(fiber) {
20406 // We're going to search forward into the tree until we find a sibling host
20407 // node. Unfortunately, if multiple insertions are done in a row we have to
20408 // search past them. This leads to exponential search for the next sibling.
20409 // TODO: Find a more efficient way to do this.
20410 var node = fiber;
20411
20412 siblings: while (true) {
20413 // If we didn't find anything, let's try the next sibling.
20414 while (node.sibling === null) {
20415 if (node.return === null || isHostParent(node.return)) {
20416 // If we pop out of the root or hit the parent the fiber we are the
20417 // last sibling.
20418 return null;
20419 }
20420
20421 node = node.return;
20422 }
20423
20424 node.sibling.return = node.return;
20425 node = node.sibling;
20426
20427 while (node.tag !== HostComponent && node.tag !== HostText && node.tag !== DehydratedFragment) {
20428 // If it is not host node and, we might have a host node inside it.
20429 // Try to search down until we find one.
20430 if (node.effectTag & Placement) {
20431 // If we don't have a child, try the siblings instead.
20432 continue siblings;
20433 } // If we don't have a child, try the siblings instead.
20434 // We also skip portals because they are not part of this host tree.
20435
20436
20437 if (node.child === null || node.tag === HostPortal) {
20438 continue siblings;
20439 } else {
20440 node.child.return = node;
20441 node = node.child;
20442 }
20443 } // Check if this host node is stable or about to be placed.
20444
20445
20446 if (!(node.effectTag & Placement)) {
20447 // Found it!
20448 return node.stateNode;
20449 }
20450 }
20451 }
20452
20453 function commitPlacement(finishedWork) {
20454
20455
20456 var parentFiber = getHostParentFiber(finishedWork); // Note: these two variables *must* always be updated together.
20457
20458 var parent;
20459 var isContainer;
20460 var parentStateNode = parentFiber.stateNode;
20461
20462 switch (parentFiber.tag) {
20463 case HostComponent:
20464 parent = parentStateNode;
20465 isContainer = false;
20466 break;
20467
20468 case HostRoot:
20469 parent = parentStateNode.containerInfo;
20470 isContainer = true;
20471 break;
20472
20473 case HostPortal:
20474 parent = parentStateNode.containerInfo;
20475 isContainer = true;
20476 break;
20477
20478 case FundamentalComponent:
20479
20480 // eslint-disable-next-line-no-fallthrough
20481
20482 default:
20483 {
20484 {
20485 throw Error( "Invalid host parent fiber. This error is likely caused by a bug in React. Please file an issue." );
20486 }
20487 }
20488
20489 }
20490
20491 if (parentFiber.effectTag & ContentReset) {
20492 // Reset the text content of the parent before doing any insertions
20493 resetTextContent(parent); // Clear ContentReset from the effect tag
20494
20495 parentFiber.effectTag &= ~ContentReset;
20496 }
20497
20498 var before = getHostSibling(finishedWork); // We only have the top Fiber that was inserted but we need to recurse down its
20499 // children to find all the terminal nodes.
20500
20501 if (isContainer) {
20502 insertOrAppendPlacementNodeIntoContainer(finishedWork, before, parent);
20503 } else {
20504 insertOrAppendPlacementNode(finishedWork, before, parent);
20505 }
20506 }
20507
20508 function insertOrAppendPlacementNodeIntoContainer(node, before, parent) {
20509 var tag = node.tag;
20510 var isHost = tag === HostComponent || tag === HostText;
20511
20512 if (isHost || enableFundamentalAPI ) {
20513 var stateNode = isHost ? node.stateNode : node.stateNode.instance;
20514
20515 if (before) {
20516 insertInContainerBefore(parent, stateNode, before);
20517 } else {
20518 appendChildToContainer(parent, stateNode);
20519 }
20520 } else if (tag === HostPortal) ; else {
20521 var child = node.child;
20522
20523 if (child !== null) {
20524 insertOrAppendPlacementNodeIntoContainer(child, before, parent);
20525 var sibling = child.sibling;
20526
20527 while (sibling !== null) {
20528 insertOrAppendPlacementNodeIntoContainer(sibling, before, parent);
20529 sibling = sibling.sibling;
20530 }
20531 }
20532 }
20533 }
20534
20535 function insertOrAppendPlacementNode(node, before, parent) {
20536 var tag = node.tag;
20537 var isHost = tag === HostComponent || tag === HostText;
20538
20539 if (isHost || enableFundamentalAPI ) {
20540 var stateNode = isHost ? node.stateNode : node.stateNode.instance;
20541
20542 if (before) {
20543 insertBefore(parent, stateNode, before);
20544 } else {
20545 appendChild(parent, stateNode);
20546 }
20547 } else if (tag === HostPortal) ; else {
20548 var child = node.child;
20549
20550 if (child !== null) {
20551 insertOrAppendPlacementNode(child, before, parent);
20552 var sibling = child.sibling;
20553
20554 while (sibling !== null) {
20555 insertOrAppendPlacementNode(sibling, before, parent);
20556 sibling = sibling.sibling;
20557 }
20558 }
20559 }
20560 }
20561
20562 function unmountHostComponents(finishedRoot, current, renderPriorityLevel) {
20563 // We only have the top Fiber that was deleted but we need to recurse down its
20564 // children to find all the terminal nodes.
20565 var node = current; // Each iteration, currentParent is populated with node's host parent if not
20566 // currentParentIsValid.
20567
20568 var currentParentIsValid = false; // Note: these two variables *must* always be updated together.
20569
20570 var currentParent;
20571 var currentParentIsContainer;
20572
20573 while (true) {
20574 if (!currentParentIsValid) {
20575 var parent = node.return;
20576
20577 findParent: while (true) {
20578 if (!(parent !== null)) {
20579 {
20580 throw Error( "Expected to find a host parent. This error is likely caused by a bug in React. Please file an issue." );
20581 }
20582 }
20583
20584 var parentStateNode = parent.stateNode;
20585
20586 switch (parent.tag) {
20587 case HostComponent:
20588 currentParent = parentStateNode;
20589 currentParentIsContainer = false;
20590 break findParent;
20591
20592 case HostRoot:
20593 currentParent = parentStateNode.containerInfo;
20594 currentParentIsContainer = true;
20595 break findParent;
20596
20597 case HostPortal:
20598 currentParent = parentStateNode.containerInfo;
20599 currentParentIsContainer = true;
20600 break findParent;
20601
20602 }
20603
20604 parent = parent.return;
20605 }
20606
20607 currentParentIsValid = true;
20608 }
20609
20610 if (node.tag === HostComponent || node.tag === HostText) {
20611 commitNestedUnmounts(finishedRoot, node, renderPriorityLevel); // After all the children have unmounted, it is now safe to remove the
20612 // node from the tree.
20613
20614 if (currentParentIsContainer) {
20615 removeChildFromContainer(currentParent, node.stateNode);
20616 } else {
20617 removeChild(currentParent, node.stateNode);
20618 } // Don't visit children because we already visited them.
20619
20620 } else if (node.tag === HostPortal) {
20621 if (node.child !== null) {
20622 // When we go into a portal, it becomes the parent to remove from.
20623 // We will reassign it back when we pop the portal on the way up.
20624 currentParent = node.stateNode.containerInfo;
20625 currentParentIsContainer = true; // Visit children because portals might contain host components.
20626
20627 node.child.return = node;
20628 node = node.child;
20629 continue;
20630 }
20631 } else {
20632 commitUnmount(finishedRoot, node, renderPriorityLevel); // Visit children because we may find more host components below.
20633
20634 if (node.child !== null) {
20635 node.child.return = node;
20636 node = node.child;
20637 continue;
20638 }
20639 }
20640
20641 if (node === current) {
20642 return;
20643 }
20644
20645 while (node.sibling === null) {
20646 if (node.return === null || node.return === current) {
20647 return;
20648 }
20649
20650 node = node.return;
20651
20652 if (node.tag === HostPortal) {
20653 // When we go out of the portal, we need to restore the parent.
20654 // Since we don't keep a stack of them, we will search for it.
20655 currentParentIsValid = false;
20656 }
20657 }
20658
20659 node.sibling.return = node.return;
20660 node = node.sibling;
20661 }
20662 }
20663
20664 function commitDeletion(finishedRoot, current, renderPriorityLevel) {
20665 {
20666 // Recursively delete all host nodes from the parent.
20667 // Detach refs and call componentWillUnmount() on the whole subtree.
20668 unmountHostComponents(finishedRoot, current, renderPriorityLevel);
20669 }
20670
20671 detachFiber(current);
20672 }
20673
20674 function commitWork(current, finishedWork) {
20675
20676 switch (finishedWork.tag) {
20677 case FunctionComponent:
20678 case ForwardRef:
20679 case MemoComponent:
20680 case SimpleMemoComponent:
20681 case Block:
20682 {
20683 // Layout effects are destroyed during the mutation phase so that all
20684 // destroy functions for all fibers are called before any create functions.
20685 // This prevents sibling component effects from interfering with each other,
20686 // e.g. a destroy function in one component should never override a ref set
20687 // by a create function in another component during the same commit.
20688 commitHookEffectListUnmount(Layout | HasEffect, finishedWork);
20689 return;
20690 }
20691
20692 case ClassComponent:
20693 {
20694 return;
20695 }
20696
20697 case HostComponent:
20698 {
20699 var instance = finishedWork.stateNode;
20700
20701 if (instance != null) {
20702 // Commit the work prepared earlier.
20703 var newProps = finishedWork.memoizedProps; // For hydration we reuse the update path but we treat the oldProps
20704 // as the newProps. The updatePayload will contain the real change in
20705 // this case.
20706
20707 var oldProps = current !== null ? current.memoizedProps : newProps;
20708 var type = finishedWork.type; // TODO: Type the updateQueue to be specific to host components.
20709
20710 var updatePayload = finishedWork.updateQueue;
20711 finishedWork.updateQueue = null;
20712
20713 if (updatePayload !== null) {
20714 commitUpdate(instance, updatePayload, type, oldProps, newProps);
20715 }
20716 }
20717
20718 return;
20719 }
20720
20721 case HostText:
20722 {
20723 if (!(finishedWork.stateNode !== null)) {
20724 {
20725 throw Error( "This should have a text node initialized. This error is likely caused by a bug in React. Please file an issue." );
20726 }
20727 }
20728
20729 var textInstance = finishedWork.stateNode;
20730 var newText = finishedWork.memoizedProps; // For hydration we reuse the update path but we treat the oldProps
20731 // as the newProps. The updatePayload will contain the real change in
20732 // this case.
20733
20734 var oldText = current !== null ? current.memoizedProps : newText;
20735 commitTextUpdate(textInstance, oldText, newText);
20736 return;
20737 }
20738
20739 case HostRoot:
20740 {
20741 {
20742 var _root = finishedWork.stateNode;
20743
20744 if (_root.hydrate) {
20745 // We've just hydrated. No need to hydrate again.
20746 _root.hydrate = false;
20747 commitHydratedContainer(_root.containerInfo);
20748 }
20749 }
20750
20751 return;
20752 }
20753
20754 case Profiler:
20755 {
20756 return;
20757 }
20758
20759 case SuspenseComponent:
20760 {
20761 commitSuspenseComponent(finishedWork);
20762 attachSuspenseRetryListeners(finishedWork);
20763 return;
20764 }
20765
20766 case SuspenseListComponent:
20767 {
20768 attachSuspenseRetryListeners(finishedWork);
20769 return;
20770 }
20771
20772 case IncompleteClassComponent:
20773 {
20774 return;
20775 }
20776 }
20777
20778 {
20779 {
20780 throw 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." );
20781 }
20782 }
20783 }
20784
20785 function commitSuspenseComponent(finishedWork) {
20786 var newState = finishedWork.memoizedState;
20787 var newDidTimeout;
20788 var primaryChildParent = finishedWork;
20789
20790 if (newState === null) {
20791 newDidTimeout = false;
20792 } else {
20793 newDidTimeout = true;
20794 primaryChildParent = finishedWork.child;
20795 markCommitTimeOfFallback();
20796 }
20797
20798 if ( primaryChildParent !== null) {
20799 hideOrUnhideAllChildren(primaryChildParent, newDidTimeout);
20800 }
20801 }
20802
20803 function commitSuspenseHydrationCallbacks(finishedRoot, finishedWork) {
20804
20805 var newState = finishedWork.memoizedState;
20806
20807 if (newState === null) {
20808 var current = finishedWork.alternate;
20809
20810 if (current !== null) {
20811 var prevState = current.memoizedState;
20812
20813 if (prevState !== null) {
20814 var suspenseInstance = prevState.dehydrated;
20815
20816 if (suspenseInstance !== null) {
20817 commitHydratedSuspenseInstance(suspenseInstance);
20818 }
20819 }
20820 }
20821 }
20822 }
20823
20824 function attachSuspenseRetryListeners(finishedWork) {
20825 // If this boundary just timed out, then it will have a set of thenables.
20826 // For each thenable, attach a listener so that when it resolves, React
20827 // attempts to re-render the boundary in the primary (pre-timeout) state.
20828 var thenables = finishedWork.updateQueue;
20829
20830 if (thenables !== null) {
20831 finishedWork.updateQueue = null;
20832 var retryCache = finishedWork.stateNode;
20833
20834 if (retryCache === null) {
20835 retryCache = finishedWork.stateNode = new PossiblyWeakSet();
20836 }
20837
20838 thenables.forEach(function (thenable) {
20839 // Memoize using the boundary fiber to prevent redundant listeners.
20840 var retry = resolveRetryThenable.bind(null, finishedWork, thenable);
20841
20842 if (!retryCache.has(thenable)) {
20843 {
20844 if (thenable.__reactDoNotTraceInteractions !== true) {
20845 retry = unstable_wrap(retry);
20846 }
20847 }
20848
20849 retryCache.add(thenable);
20850 thenable.then(retry, retry);
20851 }
20852 });
20853 }
20854 }
20855
20856 function commitResetTextContent(current) {
20857
20858 resetTextContent(current.stateNode);
20859 }
20860
20861 var PossiblyWeakMap$1 = typeof WeakMap === 'function' ? WeakMap : Map;
20862
20863 function createRootErrorUpdate(fiber, errorInfo, expirationTime) {
20864 var update = createUpdate(expirationTime, null); // Unmount the root by rendering null.
20865
20866 update.tag = CaptureUpdate; // Caution: React DevTools currently depends on this property
20867 // being called "element".
20868
20869 update.payload = {
20870 element: null
20871 };
20872 var error = errorInfo.value;
20873
20874 update.callback = function () {
20875 onUncaughtError(error);
20876 logError(fiber, errorInfo);
20877 };
20878
20879 return update;
20880 }
20881
20882 function createClassErrorUpdate(fiber, errorInfo, expirationTime) {
20883 var update = createUpdate(expirationTime, null);
20884 update.tag = CaptureUpdate;
20885 var getDerivedStateFromError = fiber.type.getDerivedStateFromError;
20886
20887 if (typeof getDerivedStateFromError === 'function') {
20888 var error$1 = errorInfo.value;
20889
20890 update.payload = function () {
20891 logError(fiber, errorInfo);
20892 return getDerivedStateFromError(error$1);
20893 };
20894 }
20895
20896 var inst = fiber.stateNode;
20897
20898 if (inst !== null && typeof inst.componentDidCatch === 'function') {
20899 update.callback = function callback() {
20900 {
20901 markFailedErrorBoundaryForHotReloading(fiber);
20902 }
20903
20904 if (typeof getDerivedStateFromError !== 'function') {
20905 // To preserve the preexisting retry behavior of error boundaries,
20906 // we keep track of which ones already failed during this batch.
20907 // This gets reset before we yield back to the browser.
20908 // TODO: Warn in strict mode if getDerivedStateFromError is
20909 // not defined.
20910 markLegacyErrorBoundaryAsFailed(this); // Only log here if componentDidCatch is the only error boundary method defined
20911
20912 logError(fiber, errorInfo);
20913 }
20914
20915 var error$1 = errorInfo.value;
20916 var stack = errorInfo.stack;
20917 this.componentDidCatch(error$1, {
20918 componentStack: stack !== null ? stack : ''
20919 });
20920
20921 {
20922 if (typeof getDerivedStateFromError !== 'function') {
20923 // If componentDidCatch is the only error boundary method defined,
20924 // then it needs to call setState to recover from errors.
20925 // If no state update is scheduled then the boundary will swallow the error.
20926 if (fiber.expirationTime !== Sync) {
20927 error('%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');
20928 }
20929 }
20930 }
20931 };
20932 } else {
20933 update.callback = function () {
20934 markFailedErrorBoundaryForHotReloading(fiber);
20935 };
20936 }
20937
20938 return update;
20939 }
20940
20941 function attachPingListener(root, renderExpirationTime, thenable) {
20942 // Attach a listener to the promise to "ping" the root and retry. But
20943 // only if one does not already exist for the current render expiration
20944 // time (which acts like a "thread ID" here).
20945 var pingCache = root.pingCache;
20946 var threadIDs;
20947
20948 if (pingCache === null) {
20949 pingCache = root.pingCache = new PossiblyWeakMap$1();
20950 threadIDs = new Set();
20951 pingCache.set(thenable, threadIDs);
20952 } else {
20953 threadIDs = pingCache.get(thenable);
20954
20955 if (threadIDs === undefined) {
20956 threadIDs = new Set();
20957 pingCache.set(thenable, threadIDs);
20958 }
20959 }
20960
20961 if (!threadIDs.has(renderExpirationTime)) {
20962 // Memoize using the thread ID to prevent redundant listeners.
20963 threadIDs.add(renderExpirationTime);
20964 var ping = pingSuspendedRoot.bind(null, root, thenable, renderExpirationTime);
20965 thenable.then(ping, ping);
20966 }
20967 }
20968
20969 function throwException(root, returnFiber, sourceFiber, value, renderExpirationTime) {
20970 // The source fiber did not complete.
20971 sourceFiber.effectTag |= Incomplete; // Its effect list is no longer valid.
20972
20973 sourceFiber.firstEffect = sourceFiber.lastEffect = null;
20974
20975 if (value !== null && typeof value === 'object' && typeof value.then === 'function') {
20976 // This is a thenable.
20977 var thenable = value;
20978
20979 if ((sourceFiber.mode & BlockingMode) === NoMode) {
20980 // Reset the memoizedState to what it was before we attempted
20981 // to render it.
20982 var currentSource = sourceFiber.alternate;
20983
20984 if (currentSource) {
20985 sourceFiber.memoizedState = currentSource.memoizedState;
20986 sourceFiber.expirationTime = currentSource.expirationTime;
20987 } else {
20988 sourceFiber.memoizedState = null;
20989 }
20990 }
20991
20992 var hasInvisibleParentBoundary = hasSuspenseContext(suspenseStackCursor.current, InvisibleParentSuspenseContext); // Schedule the nearest Suspense to re-render the timed out view.
20993
20994 var _workInProgress = returnFiber;
20995
20996 do {
20997 if (_workInProgress.tag === SuspenseComponent && shouldCaptureSuspense(_workInProgress, hasInvisibleParentBoundary)) {
20998 // Found the nearest boundary.
20999 // Stash the promise on the boundary fiber. If the boundary times out, we'll
21000 // attach another listener to flip the boundary back to its normal state.
21001 var thenables = _workInProgress.updateQueue;
21002
21003 if (thenables === null) {
21004 var updateQueue = new Set();
21005 updateQueue.add(thenable);
21006 _workInProgress.updateQueue = updateQueue;
21007 } else {
21008 thenables.add(thenable);
21009 } // If the boundary is outside of blocking mode, we should *not*
21010 // suspend the commit. Pretend as if the suspended component rendered
21011 // null and keep rendering. In the commit phase, we'll schedule a
21012 // subsequent synchronous update to re-render the Suspense.
21013 //
21014 // Note: It doesn't matter whether the component that suspended was
21015 // inside a blocking mode tree. If the Suspense is outside of it, we
21016 // should *not* suspend the commit.
21017
21018
21019 if ((_workInProgress.mode & BlockingMode) === NoMode) {
21020 _workInProgress.effectTag |= DidCapture; // We're going to commit this fiber even though it didn't complete.
21021 // But we shouldn't call any lifecycle methods or callbacks. Remove
21022 // all lifecycle effect tags.
21023
21024 sourceFiber.effectTag &= ~(LifecycleEffectMask | Incomplete);
21025
21026 if (sourceFiber.tag === ClassComponent) {
21027 var currentSourceFiber = sourceFiber.alternate;
21028
21029 if (currentSourceFiber === null) {
21030 // This is a new mount. Change the tag so it's not mistaken for a
21031 // completed class component. For example, we should not call
21032 // componentWillUnmount if it is deleted.
21033 sourceFiber.tag = IncompleteClassComponent;
21034 } else {
21035 // When we try rendering again, we should not reuse the current fiber,
21036 // since it's known to be in an inconsistent state. Use a force update to
21037 // prevent a bail out.
21038 var update = createUpdate(Sync, null);
21039 update.tag = ForceUpdate;
21040 enqueueUpdate(sourceFiber, update);
21041 }
21042 } // The source fiber did not complete. Mark it with Sync priority to
21043 // indicate that it still has pending work.
21044
21045
21046 sourceFiber.expirationTime = Sync; // Exit without suspending.
21047
21048 return;
21049 } // Confirmed that the boundary is in a concurrent mode tree. Continue
21050 // with the normal suspend path.
21051 //
21052 // After this we'll use a set of heuristics to determine whether this
21053 // render pass will run to completion or restart or "suspend" the commit.
21054 // The actual logic for this is spread out in different places.
21055 //
21056 // This first principle is that if we're going to suspend when we complete
21057 // a root, then we should also restart if we get an update or ping that
21058 // might unsuspend it, and vice versa. The only reason to suspend is
21059 // because you think you might want to restart before committing. However,
21060 // it doesn't make sense to restart only while in the period we're suspended.
21061 //
21062 // Restarting too aggressively is also not good because it starves out any
21063 // intermediate loading state. So we use heuristics to determine when.
21064 // Suspense Heuristics
21065 //
21066 // If nothing threw a Promise or all the same fallbacks are already showing,
21067 // then don't suspend/restart.
21068 //
21069 // If this is an initial render of a new tree of Suspense boundaries and
21070 // those trigger a fallback, then don't suspend/restart. We want to ensure
21071 // that we can show the initial loading state as quickly as possible.
21072 //
21073 // If we hit a "Delayed" case, such as when we'd switch from content back into
21074 // a fallback, then we should always suspend/restart. SuspenseConfig applies to
21075 // this case. If none is defined, JND is used instead.
21076 //
21077 // If we're already showing a fallback and it gets "retried", allowing us to show
21078 // another level, but there's still an inner boundary that would show a fallback,
21079 // then we suspend/restart for 500ms since the last time we showed a fallback
21080 // anywhere in the tree. This effectively throttles progressive loading into a
21081 // consistent train of commits. This also gives us an opportunity to restart to
21082 // get to the completed state slightly earlier.
21083 //
21084 // If there's ambiguity due to batching it's resolved in preference of:
21085 // 1) "delayed", 2) "initial render", 3) "retry".
21086 //
21087 // We want to ensure that a "busy" state doesn't get force committed. We want to
21088 // ensure that new initial loading states can commit as soon as possible.
21089
21090
21091 attachPingListener(root, renderExpirationTime, thenable);
21092 _workInProgress.effectTag |= ShouldCapture;
21093 _workInProgress.expirationTime = renderExpirationTime;
21094 return;
21095 } // This boundary already captured during this render. Continue to the next
21096 // boundary.
21097
21098
21099 _workInProgress = _workInProgress.return;
21100 } while (_workInProgress !== null); // No boundary was found. Fallthrough to error mode.
21101 // TODO: Use invariant so the message is stripped in prod?
21102
21103
21104 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));
21105 } // We didn't find a boundary that could handle this type of exception. Start
21106 // over and traverse parent path again, this time treating the exception
21107 // as an error.
21108
21109
21110 renderDidError();
21111 value = createCapturedValue(value, sourceFiber);
21112 var workInProgress = returnFiber;
21113
21114 do {
21115 switch (workInProgress.tag) {
21116 case HostRoot:
21117 {
21118 var _errorInfo = value;
21119 workInProgress.effectTag |= ShouldCapture;
21120 workInProgress.expirationTime = renderExpirationTime;
21121
21122 var _update = createRootErrorUpdate(workInProgress, _errorInfo, renderExpirationTime);
21123
21124 enqueueCapturedUpdate(workInProgress, _update);
21125 return;
21126 }
21127
21128 case ClassComponent:
21129 // Capture and retry
21130 var errorInfo = value;
21131 var ctor = workInProgress.type;
21132 var instance = workInProgress.stateNode;
21133
21134 if ((workInProgress.effectTag & DidCapture) === NoEffect && (typeof ctor.getDerivedStateFromError === 'function' || instance !== null && typeof instance.componentDidCatch === 'function' && !isAlreadyFailedLegacyErrorBoundary(instance))) {
21135 workInProgress.effectTag |= ShouldCapture;
21136 workInProgress.expirationTime = renderExpirationTime; // Schedule the error boundary to re-render using updated state
21137
21138 var _update2 = createClassErrorUpdate(workInProgress, errorInfo, renderExpirationTime);
21139
21140 enqueueCapturedUpdate(workInProgress, _update2);
21141 return;
21142 }
21143
21144 break;
21145 }
21146
21147 workInProgress = workInProgress.return;
21148 } while (workInProgress !== null);
21149 }
21150
21151 var ceil = Math.ceil;
21152 var ReactCurrentDispatcher$1 = ReactSharedInternals.ReactCurrentDispatcher,
21153 ReactCurrentOwner$2 = ReactSharedInternals.ReactCurrentOwner,
21154 IsSomeRendererActing = ReactSharedInternals.IsSomeRendererActing;
21155 var NoContext =
21156 /* */
21157 0;
21158 var BatchedContext =
21159 /* */
21160 1;
21161 var EventContext =
21162 /* */
21163 2;
21164 var DiscreteEventContext =
21165 /* */
21166 4;
21167 var LegacyUnbatchedContext =
21168 /* */
21169 8;
21170 var RenderContext =
21171 /* */
21172 16;
21173 var CommitContext =
21174 /* */
21175 32;
21176 var RootIncomplete = 0;
21177 var RootFatalErrored = 1;
21178 var RootErrored = 2;
21179 var RootSuspended = 3;
21180 var RootSuspendedWithDelay = 4;
21181 var RootCompleted = 5;
21182 // Describes where we are in the React execution stack
21183 var executionContext = NoContext; // The root we're working on
21184
21185 var workInProgressRoot = null; // The fiber we're working on
21186
21187 var workInProgress = null; // The expiration time we're rendering
21188
21189 var renderExpirationTime$1 = NoWork; // Whether to root completed, errored, suspended, etc.
21190
21191 var workInProgressRootExitStatus = RootIncomplete; // A fatal error, if one is thrown
21192
21193 var workInProgressRootFatalError = null; // Most recent event time among processed updates during this render.
21194 // This is conceptually a time stamp but expressed in terms of an ExpirationTime
21195 // because we deal mostly with expiration times in the hot path, so this avoids
21196 // the conversion happening in the hot path.
21197
21198 var workInProgressRootLatestProcessedExpirationTime = Sync;
21199 var workInProgressRootLatestSuspenseTimeout = Sync;
21200 var workInProgressRootCanSuspendUsingConfig = null; // The work left over by components that were visited during this render. Only
21201 // includes unprocessed updates, not work in bailed out children.
21202
21203 var workInProgressRootNextUnprocessedUpdateTime = NoWork; // If we're pinged while rendering we don't always restart immediately.
21204 // This flag determines if it might be worthwhile to restart if an opportunity
21205 // happens latere.
21206
21207 var workInProgressRootHasPendingPing = false; // The most recent time we committed a fallback. This lets us ensure a train
21208 // model where we don't commit new loading states in too quick succession.
21209
21210 var globalMostRecentFallbackTime = 0;
21211 var FALLBACK_THROTTLE_MS = 500;
21212 var nextEffect = null;
21213 var hasUncaughtError = false;
21214 var firstUncaughtError = null;
21215 var legacyErrorBoundariesThatAlreadyFailed = null;
21216 var rootDoesHavePassiveEffects = false;
21217 var rootWithPendingPassiveEffects = null;
21218 var pendingPassiveEffectsRenderPriority = NoPriority;
21219 var pendingPassiveEffectsExpirationTime = NoWork;
21220 var rootsWithPendingDiscreteUpdates = null; // Use these to prevent an infinite loop of nested updates
21221
21222 var NESTED_UPDATE_LIMIT = 50;
21223 var nestedUpdateCount = 0;
21224 var rootWithNestedUpdates = null;
21225 var NESTED_PASSIVE_UPDATE_LIMIT = 50;
21226 var nestedPassiveUpdateCount = 0;
21227 var interruptedBy = null; // Marks the need to reschedule pending interactions at these expiration times
21228 // during the commit phase. This enables them to be traced across components
21229 // that spawn new work during render. E.g. hidden boundaries, suspended SSR
21230 // hydration or SuspenseList.
21231
21232 var spawnedWorkDuringRender = null; // Expiration times are computed by adding to the current time (the start
21233 // time). However, if two updates are scheduled within the same event, we
21234 // should treat their start times as simultaneous, even if the actual clock
21235 // time has advanced between the first and second call.
21236 // In other words, because expiration times determine how updates are batched,
21237 // we want all updates of like priority that occur within the same event to
21238 // receive the same expiration time. Otherwise we get tearing.
21239
21240 var currentEventTime = NoWork;
21241 function requestCurrentTimeForUpdate() {
21242 if ((executionContext & (RenderContext | CommitContext)) !== NoContext) {
21243 // We're inside React, so it's fine to read the actual time.
21244 return msToExpirationTime(now());
21245 } // We're not inside React, so we may be in the middle of a browser event.
21246
21247
21248 if (currentEventTime !== NoWork) {
21249 // Use the same start time for all updates until we enter React again.
21250 return currentEventTime;
21251 } // This is the first update since React yielded. Compute a new start time.
21252
21253
21254 currentEventTime = msToExpirationTime(now());
21255 return currentEventTime;
21256 }
21257 function getCurrentTime() {
21258 return msToExpirationTime(now());
21259 }
21260 function computeExpirationForFiber(currentTime, fiber, suspenseConfig) {
21261 var mode = fiber.mode;
21262
21263 if ((mode & BlockingMode) === NoMode) {
21264 return Sync;
21265 }
21266
21267 var priorityLevel = getCurrentPriorityLevel();
21268
21269 if ((mode & ConcurrentMode) === NoMode) {
21270 return priorityLevel === ImmediatePriority ? Sync : Batched;
21271 }
21272
21273 if ((executionContext & RenderContext) !== NoContext) {
21274 // Use whatever time we're already rendering
21275 // TODO: Should there be a way to opt out, like with `runWithPriority`?
21276 return renderExpirationTime$1;
21277 }
21278
21279 var expirationTime;
21280
21281 if (suspenseConfig !== null) {
21282 // Compute an expiration time based on the Suspense timeout.
21283 expirationTime = computeSuspenseExpiration(currentTime, suspenseConfig.timeoutMs | 0 || LOW_PRIORITY_EXPIRATION);
21284 } else {
21285 // Compute an expiration time based on the Scheduler priority.
21286 switch (priorityLevel) {
21287 case ImmediatePriority:
21288 expirationTime = Sync;
21289 break;
21290
21291 case UserBlockingPriority$1:
21292 // TODO: Rename this to computeUserBlockingExpiration
21293 expirationTime = computeInteractiveExpiration(currentTime);
21294 break;
21295
21296 case NormalPriority:
21297 case LowPriority:
21298 // TODO: Handle LowPriority
21299 // TODO: Rename this to... something better.
21300 expirationTime = computeAsyncExpiration(currentTime);
21301 break;
21302
21303 case IdlePriority:
21304 expirationTime = Idle;
21305 break;
21306
21307 default:
21308 {
21309 {
21310 throw Error( "Expected a valid priority level" );
21311 }
21312 }
21313
21314 }
21315 } // If we're in the middle of rendering a tree, do not update at the same
21316 // expiration time that is already rendering.
21317 // TODO: We shouldn't have to do this if the update is on a different root.
21318 // Refactor computeExpirationForFiber + scheduleUpdate so we have access to
21319 // the root when we check for this condition.
21320
21321
21322 if (workInProgressRoot !== null && expirationTime === renderExpirationTime$1) {
21323 // This is a trick to move this update into a separate batch
21324 expirationTime -= 1;
21325 }
21326
21327 return expirationTime;
21328 }
21329 function scheduleUpdateOnFiber(fiber, expirationTime) {
21330 checkForNestedUpdates();
21331 warnAboutRenderPhaseUpdatesInDEV(fiber);
21332 var root = markUpdateTimeFromFiberToRoot(fiber, expirationTime);
21333
21334 if (root === null) {
21335 warnAboutUpdateOnUnmountedFiberInDEV(fiber);
21336 return;
21337 }
21338
21339 checkForInterruption(fiber, expirationTime);
21340 recordScheduleUpdate(); // TODO: computeExpirationForFiber also reads the priority. Pass the
21341 // priority as an argument to that function and this one.
21342
21343 var priorityLevel = getCurrentPriorityLevel();
21344
21345 if (expirationTime === Sync) {
21346 if ( // Check if we're inside unbatchedUpdates
21347 (executionContext & LegacyUnbatchedContext) !== NoContext && // Check if we're not already rendering
21348 (executionContext & (RenderContext | CommitContext)) === NoContext) {
21349 // Register pending interactions on the root to avoid losing traced interaction data.
21350 schedulePendingInteractions(root, expirationTime); // This is a legacy edge case. The initial mount of a ReactDOM.render-ed
21351 // root inside of batchedUpdates should be synchronous, but layout updates
21352 // should be deferred until the end of the batch.
21353
21354 performSyncWorkOnRoot(root);
21355 } else {
21356 ensureRootIsScheduled(root);
21357 schedulePendingInteractions(root, expirationTime);
21358
21359 if (executionContext === NoContext) {
21360 // Flush the synchronous work now, unless we're already working or inside
21361 // a batch. This is intentionally inside scheduleUpdateOnFiber instead of
21362 // scheduleCallbackForFiber to preserve the ability to schedule a callback
21363 // without immediately flushing it. We only do this for user-initiated
21364 // updates, to preserve historical behavior of legacy mode.
21365 flushSyncCallbackQueue();
21366 }
21367 }
21368 } else {
21369 ensureRootIsScheduled(root);
21370 schedulePendingInteractions(root, expirationTime);
21371 }
21372
21373 if ((executionContext & DiscreteEventContext) !== NoContext && ( // Only updates at user-blocking priority or greater are considered
21374 // discrete, even inside a discrete event.
21375 priorityLevel === UserBlockingPriority$1 || priorityLevel === ImmediatePriority)) {
21376 // This is the result of a discrete event. Track the lowest priority
21377 // discrete update per root so we can flush them early, if needed.
21378 if (rootsWithPendingDiscreteUpdates === null) {
21379 rootsWithPendingDiscreteUpdates = new Map([[root, expirationTime]]);
21380 } else {
21381 var lastDiscreteTime = rootsWithPendingDiscreteUpdates.get(root);
21382
21383 if (lastDiscreteTime === undefined || lastDiscreteTime > expirationTime) {
21384 rootsWithPendingDiscreteUpdates.set(root, expirationTime);
21385 }
21386 }
21387 }
21388 }
21389 var scheduleWork = scheduleUpdateOnFiber; // This is split into a separate function so we can mark a fiber with pending
21390 // work without treating it as a typical update that originates from an event;
21391 // e.g. retrying a Suspense boundary isn't an update, but it does schedule work
21392 // on a fiber.
21393
21394 function markUpdateTimeFromFiberToRoot(fiber, expirationTime) {
21395 // Update the source fiber's expiration time
21396 if (fiber.expirationTime < expirationTime) {
21397 fiber.expirationTime = expirationTime;
21398 }
21399
21400 var alternate = fiber.alternate;
21401
21402 if (alternate !== null && alternate.expirationTime < expirationTime) {
21403 alternate.expirationTime = expirationTime;
21404 } // Walk the parent path to the root and update the child expiration time.
21405
21406
21407 var node = fiber.return;
21408 var root = null;
21409
21410 if (node === null && fiber.tag === HostRoot) {
21411 root = fiber.stateNode;
21412 } else {
21413 while (node !== null) {
21414 alternate = node.alternate;
21415
21416 if (node.childExpirationTime < expirationTime) {
21417 node.childExpirationTime = expirationTime;
21418
21419 if (alternate !== null && alternate.childExpirationTime < expirationTime) {
21420 alternate.childExpirationTime = expirationTime;
21421 }
21422 } else if (alternate !== null && alternate.childExpirationTime < expirationTime) {
21423 alternate.childExpirationTime = expirationTime;
21424 }
21425
21426 if (node.return === null && node.tag === HostRoot) {
21427 root = node.stateNode;
21428 break;
21429 }
21430
21431 node = node.return;
21432 }
21433 }
21434
21435 if (root !== null) {
21436 if (workInProgressRoot === root) {
21437 // Received an update to a tree that's in the middle of rendering. Mark
21438 // that's unprocessed work on this root.
21439 markUnprocessedUpdateTime(expirationTime);
21440
21441 if (workInProgressRootExitStatus === RootSuspendedWithDelay) {
21442 // The root already suspended with a delay, which means this render
21443 // definitely won't finish. Since we have a new update, let's mark it as
21444 // suspended now, right before marking the incoming update. This has the
21445 // effect of interrupting the current render and switching to the update.
21446 // TODO: This happens to work when receiving an update during the render
21447 // phase, because of the trick inside computeExpirationForFiber to
21448 // subtract 1 from `renderExpirationTime` to move it into a
21449 // separate bucket. But we should probably model it with an exception,
21450 // using the same mechanism we use to force hydration of a subtree.
21451 // TODO: This does not account for low pri updates that were already
21452 // scheduled before the root started rendering. Need to track the next
21453 // pending expiration time (perhaps by backtracking the return path) and
21454 // then trigger a restart in the `renderDidSuspendDelayIfPossible` path.
21455 markRootSuspendedAtTime(root, renderExpirationTime$1);
21456 }
21457 } // Mark that the root has a pending update.
21458
21459
21460 markRootUpdatedAtTime(root, expirationTime);
21461 }
21462
21463 return root;
21464 }
21465
21466 function getNextRootExpirationTimeToWorkOn(root) {
21467 // Determines the next expiration time that the root should render, taking
21468 // into account levels that may be suspended, or levels that may have
21469 // received a ping.
21470 var lastExpiredTime = root.lastExpiredTime;
21471
21472 if (lastExpiredTime !== NoWork) {
21473 return lastExpiredTime;
21474 } // "Pending" refers to any update that hasn't committed yet, including if it
21475 // suspended. The "suspended" range is therefore a subset.
21476
21477
21478 var firstPendingTime = root.firstPendingTime;
21479
21480 if (!isRootSuspendedAtTime(root, firstPendingTime)) {
21481 // The highest priority pending time is not suspended. Let's work on that.
21482 return firstPendingTime;
21483 } // If the first pending time is suspended, check if there's a lower priority
21484 // pending level that we know about. Or check if we received a ping. Work
21485 // on whichever is higher priority.
21486
21487
21488 var lastPingedTime = root.lastPingedTime;
21489 var nextKnownPendingLevel = root.nextKnownPendingLevel;
21490 var nextLevel = lastPingedTime > nextKnownPendingLevel ? lastPingedTime : nextKnownPendingLevel;
21491
21492 if ( nextLevel <= Idle && firstPendingTime !== nextLevel) {
21493 // Don't work on Idle/Never priority unless everything else is committed.
21494 return NoWork;
21495 }
21496
21497 return nextLevel;
21498 } // Use this function to schedule a task for a root. There's only one task per
21499 // root; if a task was already scheduled, we'll check to make sure the
21500 // expiration time of the existing task is the same as the expiration time of
21501 // the next level that the root has work on. This function is called on every
21502 // update, and right before exiting a task.
21503
21504
21505 function ensureRootIsScheduled(root) {
21506 var lastExpiredTime = root.lastExpiredTime;
21507
21508 if (lastExpiredTime !== NoWork) {
21509 // Special case: Expired work should flush synchronously.
21510 root.callbackExpirationTime = Sync;
21511 root.callbackPriority = ImmediatePriority;
21512 root.callbackNode = scheduleSyncCallback(performSyncWorkOnRoot.bind(null, root));
21513 return;
21514 }
21515
21516 var expirationTime = getNextRootExpirationTimeToWorkOn(root);
21517 var existingCallbackNode = root.callbackNode;
21518
21519 if (expirationTime === NoWork) {
21520 // There's nothing to work on.
21521 if (existingCallbackNode !== null) {
21522 root.callbackNode = null;
21523 root.callbackExpirationTime = NoWork;
21524 root.callbackPriority = NoPriority;
21525 }
21526
21527 return;
21528 } // TODO: If this is an update, we already read the current time. Pass the
21529 // time as an argument.
21530
21531
21532 var currentTime = requestCurrentTimeForUpdate();
21533 var priorityLevel = inferPriorityFromExpirationTime(currentTime, expirationTime); // If there's an existing render task, confirm it has the correct priority and
21534 // expiration time. Otherwise, we'll cancel it and schedule a new one.
21535
21536 if (existingCallbackNode !== null) {
21537 var existingCallbackPriority = root.callbackPriority;
21538 var existingCallbackExpirationTime = root.callbackExpirationTime;
21539
21540 if ( // Callback must have the exact same expiration time.
21541 existingCallbackExpirationTime === expirationTime && // Callback must have greater or equal priority.
21542 existingCallbackPriority >= priorityLevel) {
21543 // Existing callback is sufficient.
21544 return;
21545 } // Need to schedule a new task.
21546 // TODO: Instead of scheduling a new task, we should be able to change the
21547 // priority of the existing one.
21548
21549
21550 cancelCallback(existingCallbackNode);
21551 }
21552
21553 root.callbackExpirationTime = expirationTime;
21554 root.callbackPriority = priorityLevel;
21555 var callbackNode;
21556
21557 if (expirationTime === Sync) {
21558 // Sync React callbacks are scheduled on a special internal queue
21559 callbackNode = scheduleSyncCallback(performSyncWorkOnRoot.bind(null, root));
21560 } else {
21561 callbackNode = scheduleCallback(priorityLevel, performConcurrentWorkOnRoot.bind(null, root), // Compute a task timeout based on the expiration time. This also affects
21562 // ordering because tasks are processed in timeout order.
21563 {
21564 timeout: expirationTimeToMs(expirationTime) - now()
21565 });
21566 }
21567
21568 root.callbackNode = callbackNode;
21569 } // This is the entry point for every concurrent task, i.e. anything that
21570 // goes through Scheduler.
21571
21572
21573 function performConcurrentWorkOnRoot(root, didTimeout) {
21574 // Since we know we're in a React event, we can clear the current
21575 // event time. The next update will compute a new event time.
21576 currentEventTime = NoWork;
21577
21578 if (didTimeout) {
21579 // The render task took too long to complete. Mark the current time as
21580 // expired to synchronously render all expired work in a single batch.
21581 var currentTime = requestCurrentTimeForUpdate();
21582 markRootExpiredAtTime(root, currentTime); // This will schedule a synchronous callback.
21583
21584 ensureRootIsScheduled(root);
21585 return null;
21586 } // Determine the next expiration time to work on, using the fields stored
21587 // on the root.
21588
21589
21590 var expirationTime = getNextRootExpirationTimeToWorkOn(root);
21591
21592 if (expirationTime !== NoWork) {
21593 var originalCallbackNode = root.callbackNode;
21594
21595 if (!((executionContext & (RenderContext | CommitContext)) === NoContext)) {
21596 {
21597 throw Error( "Should not already be working." );
21598 }
21599 }
21600
21601 flushPassiveEffects(); // If the root or expiration time have changed, throw out the existing stack
21602 // and prepare a fresh one. Otherwise we'll continue where we left off.
21603
21604 if (root !== workInProgressRoot || expirationTime !== renderExpirationTime$1) {
21605 prepareFreshStack(root, expirationTime);
21606 startWorkOnPendingInteractions(root, expirationTime);
21607 } // If we have a work-in-progress fiber, it means there's still work to do
21608 // in this root.
21609
21610
21611 if (workInProgress !== null) {
21612 var prevExecutionContext = executionContext;
21613 executionContext |= RenderContext;
21614 var prevDispatcher = pushDispatcher();
21615 var prevInteractions = pushInteractions(root);
21616 startWorkLoopTimer(workInProgress);
21617
21618 do {
21619 try {
21620 workLoopConcurrent();
21621 break;
21622 } catch (thrownValue) {
21623 handleError(root, thrownValue);
21624 }
21625 } while (true);
21626
21627 resetContextDependencies();
21628 executionContext = prevExecutionContext;
21629 popDispatcher(prevDispatcher);
21630
21631 {
21632 popInteractions(prevInteractions);
21633 }
21634
21635 if (workInProgressRootExitStatus === RootFatalErrored) {
21636 var fatalError = workInProgressRootFatalError;
21637 stopInterruptedWorkLoopTimer();
21638 prepareFreshStack(root, expirationTime);
21639 markRootSuspendedAtTime(root, expirationTime);
21640 ensureRootIsScheduled(root);
21641 throw fatalError;
21642 }
21643
21644 if (workInProgress !== null) {
21645 // There's still work left over. Exit without committing.
21646 stopInterruptedWorkLoopTimer();
21647 } else {
21648 // We now have a consistent tree. The next step is either to commit it,
21649 // or, if something suspended, wait to commit it after a timeout.
21650 stopFinishedWorkLoopTimer();
21651 var finishedWork = root.finishedWork = root.current.alternate;
21652 root.finishedExpirationTime = expirationTime;
21653 finishConcurrentRender(root, finishedWork, workInProgressRootExitStatus, expirationTime);
21654 }
21655
21656 ensureRootIsScheduled(root);
21657
21658 if (root.callbackNode === originalCallbackNode) {
21659 // The task node scheduled for this root is the same one that's
21660 // currently executed. Need to return a continuation.
21661 return performConcurrentWorkOnRoot.bind(null, root);
21662 }
21663 }
21664 }
21665
21666 return null;
21667 }
21668
21669 function finishConcurrentRender(root, finishedWork, exitStatus, expirationTime) {
21670 // Set this to null to indicate there's no in-progress render.
21671 workInProgressRoot = null;
21672
21673 switch (exitStatus) {
21674 case RootIncomplete:
21675 case RootFatalErrored:
21676 {
21677 {
21678 {
21679 throw Error( "Root did not complete. This is a bug in React." );
21680 }
21681 }
21682 }
21683 // Flow knows about invariant, so it complains if I add a break
21684 // statement, but eslint doesn't know about invariant, so it complains
21685 // if I do. eslint-disable-next-line no-fallthrough
21686
21687 case RootErrored:
21688 {
21689 // If this was an async render, the error may have happened due to
21690 // a mutation in a concurrent event. Try rendering one more time,
21691 // synchronously, to see if the error goes away. If there are
21692 // lower priority updates, let's include those, too, in case they
21693 // fix the inconsistency. Render at Idle to include all updates.
21694 // If it was Idle or Never or some not-yet-invented time, render
21695 // at that time.
21696 markRootExpiredAtTime(root, expirationTime > Idle ? Idle : expirationTime); // We assume that this second render pass will be synchronous
21697 // and therefore not hit this path again.
21698
21699 break;
21700 }
21701
21702 case RootSuspended:
21703 {
21704 markRootSuspendedAtTime(root, expirationTime);
21705 var lastSuspendedTime = root.lastSuspendedTime;
21706
21707 if (expirationTime === lastSuspendedTime) {
21708 root.nextKnownPendingLevel = getRemainingExpirationTime(finishedWork);
21709 } // We have an acceptable loading state. We need to figure out if we
21710 // should immediately commit it or wait a bit.
21711 // If we have processed new updates during this render, we may now
21712 // have a new loading state ready. We want to ensure that we commit
21713 // that as soon as possible.
21714
21715
21716 var hasNotProcessedNewUpdates = workInProgressRootLatestProcessedExpirationTime === Sync;
21717
21718 if (hasNotProcessedNewUpdates && // do not delay if we're inside an act() scope
21719 !( IsThisRendererActing.current)) {
21720 // If we have not processed any new updates during this pass, then
21721 // this is either a retry of an existing fallback state or a
21722 // hidden tree. Hidden trees shouldn't be batched with other work
21723 // and after that's fixed it can only be a retry. We're going to
21724 // throttle committing retries so that we don't show too many
21725 // loading states too quickly.
21726 var msUntilTimeout = globalMostRecentFallbackTime + FALLBACK_THROTTLE_MS - now(); // Don't bother with a very short suspense time.
21727
21728 if (msUntilTimeout > 10) {
21729 if (workInProgressRootHasPendingPing) {
21730 var lastPingedTime = root.lastPingedTime;
21731
21732 if (lastPingedTime === NoWork || lastPingedTime >= expirationTime) {
21733 // This render was pinged but we didn't get to restart
21734 // earlier so try restarting now instead.
21735 root.lastPingedTime = expirationTime;
21736 prepareFreshStack(root, expirationTime);
21737 break;
21738 }
21739 }
21740
21741 var nextTime = getNextRootExpirationTimeToWorkOn(root);
21742
21743 if (nextTime !== NoWork && nextTime !== expirationTime) {
21744 // There's additional work on this root.
21745 break;
21746 }
21747
21748 if (lastSuspendedTime !== NoWork && lastSuspendedTime !== expirationTime) {
21749 // We should prefer to render the fallback of at the last
21750 // suspended level. Ping the last suspended level to try
21751 // rendering it again.
21752 root.lastPingedTime = lastSuspendedTime;
21753 break;
21754 } // The render is suspended, it hasn't timed out, and there's no
21755 // lower priority work to do. Instead of committing the fallback
21756 // immediately, wait for more data to arrive.
21757
21758
21759 root.timeoutHandle = scheduleTimeout(commitRoot.bind(null, root), msUntilTimeout);
21760 break;
21761 }
21762 } // The work expired. Commit immediately.
21763
21764
21765 commitRoot(root);
21766 break;
21767 }
21768
21769 case RootSuspendedWithDelay:
21770 {
21771 markRootSuspendedAtTime(root, expirationTime);
21772 var _lastSuspendedTime = root.lastSuspendedTime;
21773
21774 if (expirationTime === _lastSuspendedTime) {
21775 root.nextKnownPendingLevel = getRemainingExpirationTime(finishedWork);
21776 }
21777
21778 if ( // do not delay if we're inside an act() scope
21779 !( IsThisRendererActing.current)) {
21780 // We're suspended in a state that should be avoided. We'll try to
21781 // avoid committing it for as long as the timeouts let us.
21782 if (workInProgressRootHasPendingPing) {
21783 var _lastPingedTime = root.lastPingedTime;
21784
21785 if (_lastPingedTime === NoWork || _lastPingedTime >= expirationTime) {
21786 // This render was pinged but we didn't get to restart earlier
21787 // so try restarting now instead.
21788 root.lastPingedTime = expirationTime;
21789 prepareFreshStack(root, expirationTime);
21790 break;
21791 }
21792 }
21793
21794 var _nextTime = getNextRootExpirationTimeToWorkOn(root);
21795
21796 if (_nextTime !== NoWork && _nextTime !== expirationTime) {
21797 // There's additional work on this root.
21798 break;
21799 }
21800
21801 if (_lastSuspendedTime !== NoWork && _lastSuspendedTime !== expirationTime) {
21802 // We should prefer to render the fallback of at the last
21803 // suspended level. Ping the last suspended level to try
21804 // rendering it again.
21805 root.lastPingedTime = _lastSuspendedTime;
21806 break;
21807 }
21808
21809 var _msUntilTimeout;
21810
21811 if (workInProgressRootLatestSuspenseTimeout !== Sync) {
21812 // We have processed a suspense config whose expiration time we
21813 // can use as the timeout.
21814 _msUntilTimeout = expirationTimeToMs(workInProgressRootLatestSuspenseTimeout) - now();
21815 } else if (workInProgressRootLatestProcessedExpirationTime === Sync) {
21816 // This should never normally happen because only new updates
21817 // cause delayed states, so we should have processed something.
21818 // However, this could also happen in an offscreen tree.
21819 _msUntilTimeout = 0;
21820 } else {
21821 // If we don't have a suspense config, we're going to use a
21822 // heuristic to determine how long we can suspend.
21823 var eventTimeMs = inferTimeFromExpirationTime(workInProgressRootLatestProcessedExpirationTime);
21824 var currentTimeMs = now();
21825 var timeUntilExpirationMs = expirationTimeToMs(expirationTime) - currentTimeMs;
21826 var timeElapsed = currentTimeMs - eventTimeMs;
21827
21828 if (timeElapsed < 0) {
21829 // We get this wrong some time since we estimate the time.
21830 timeElapsed = 0;
21831 }
21832
21833 _msUntilTimeout = jnd(timeElapsed) - timeElapsed; // Clamp the timeout to the expiration time. TODO: Once the
21834 // event time is exact instead of inferred from expiration time
21835 // we don't need this.
21836
21837 if (timeUntilExpirationMs < _msUntilTimeout) {
21838 _msUntilTimeout = timeUntilExpirationMs;
21839 }
21840 } // Don't bother with a very short suspense time.
21841
21842
21843 if (_msUntilTimeout > 10) {
21844 // The render is suspended, it hasn't timed out, and there's no
21845 // lower priority work to do. Instead of committing the fallback
21846 // immediately, wait for more data to arrive.
21847 root.timeoutHandle = scheduleTimeout(commitRoot.bind(null, root), _msUntilTimeout);
21848 break;
21849 }
21850 } // The work expired. Commit immediately.
21851
21852
21853 commitRoot(root);
21854 break;
21855 }
21856
21857 case RootCompleted:
21858 {
21859 // The work completed. Ready to commit.
21860 if ( // do not delay if we're inside an act() scope
21861 !( IsThisRendererActing.current) && workInProgressRootLatestProcessedExpirationTime !== Sync && workInProgressRootCanSuspendUsingConfig !== null) {
21862 // If we have exceeded the minimum loading delay, which probably
21863 // means we have shown a spinner already, we might have to suspend
21864 // a bit longer to ensure that the spinner is shown for
21865 // enough time.
21866 var _msUntilTimeout2 = computeMsUntilSuspenseLoadingDelay(workInProgressRootLatestProcessedExpirationTime, expirationTime, workInProgressRootCanSuspendUsingConfig);
21867
21868 if (_msUntilTimeout2 > 10) {
21869 markRootSuspendedAtTime(root, expirationTime);
21870 root.timeoutHandle = scheduleTimeout(commitRoot.bind(null, root), _msUntilTimeout2);
21871 break;
21872 }
21873 }
21874
21875 commitRoot(root);
21876 break;
21877 }
21878
21879 default:
21880 {
21881 {
21882 {
21883 throw Error( "Unknown root exit status." );
21884 }
21885 }
21886 }
21887 }
21888 } // This is the entry point for synchronous tasks that don't go
21889 // through Scheduler
21890
21891
21892 function performSyncWorkOnRoot(root) {
21893 // Check if there's expired work on this root. Otherwise, render at Sync.
21894 var lastExpiredTime = root.lastExpiredTime;
21895 var expirationTime = lastExpiredTime !== NoWork ? lastExpiredTime : Sync;
21896
21897 if (!((executionContext & (RenderContext | CommitContext)) === NoContext)) {
21898 {
21899 throw Error( "Should not already be working." );
21900 }
21901 }
21902
21903 flushPassiveEffects(); // If the root or expiration time have changed, throw out the existing stack
21904 // and prepare a fresh one. Otherwise we'll continue where we left off.
21905
21906 if (root !== workInProgressRoot || expirationTime !== renderExpirationTime$1) {
21907 prepareFreshStack(root, expirationTime);
21908 startWorkOnPendingInteractions(root, expirationTime);
21909 } // If we have a work-in-progress fiber, it means there's still work to do
21910 // in this root.
21911
21912
21913 if (workInProgress !== null) {
21914 var prevExecutionContext = executionContext;
21915 executionContext |= RenderContext;
21916 var prevDispatcher = pushDispatcher();
21917 var prevInteractions = pushInteractions(root);
21918 startWorkLoopTimer(workInProgress);
21919
21920 do {
21921 try {
21922 workLoopSync();
21923 break;
21924 } catch (thrownValue) {
21925 handleError(root, thrownValue);
21926 }
21927 } while (true);
21928
21929 resetContextDependencies();
21930 executionContext = prevExecutionContext;
21931 popDispatcher(prevDispatcher);
21932
21933 {
21934 popInteractions(prevInteractions);
21935 }
21936
21937 if (workInProgressRootExitStatus === RootFatalErrored) {
21938 var fatalError = workInProgressRootFatalError;
21939 stopInterruptedWorkLoopTimer();
21940 prepareFreshStack(root, expirationTime);
21941 markRootSuspendedAtTime(root, expirationTime);
21942 ensureRootIsScheduled(root);
21943 throw fatalError;
21944 }
21945
21946 if (workInProgress !== null) {
21947 // This is a sync render, so we should have finished the whole tree.
21948 {
21949 {
21950 throw Error( "Cannot commit an incomplete root. This error is likely caused by a bug in React. Please file an issue." );
21951 }
21952 }
21953 } else {
21954 // We now have a consistent tree. Because this is a sync render, we
21955 // will commit it even if something suspended.
21956 stopFinishedWorkLoopTimer();
21957 root.finishedWork = root.current.alternate;
21958 root.finishedExpirationTime = expirationTime;
21959 finishSyncRender(root);
21960 } // Before exiting, make sure there's a callback scheduled for the next
21961 // pending level.
21962
21963
21964 ensureRootIsScheduled(root);
21965 }
21966
21967 return null;
21968 }
21969
21970 function finishSyncRender(root) {
21971 // Set this to null to indicate there's no in-progress render.
21972 workInProgressRoot = null;
21973 commitRoot(root);
21974 }
21975 function flushDiscreteUpdates() {
21976 // TODO: Should be able to flush inside batchedUpdates, but not inside `act`.
21977 // However, `act` uses `batchedUpdates`, so there's no way to distinguish
21978 // those two cases. Need to fix this before exposing flushDiscreteUpdates
21979 // as a public API.
21980 if ((executionContext & (BatchedContext | RenderContext | CommitContext)) !== NoContext) {
21981 {
21982 if ((executionContext & RenderContext) !== NoContext) {
21983 error('unstable_flushDiscreteUpdates: Cannot flush updates when React is ' + 'already rendering.');
21984 }
21985 } // We're already rendering, so we can't synchronously flush pending work.
21986 // This is probably a nested event dispatch triggered by a lifecycle/effect,
21987 // like `el.focus()`. Exit.
21988
21989
21990 return;
21991 }
21992
21993 flushPendingDiscreteUpdates(); // If the discrete updates scheduled passive effects, flush them now so that
21994 // they fire before the next serial event.
21995
21996 flushPassiveEffects();
21997 }
21998 function syncUpdates(fn, a, b, c) {
21999 return runWithPriority$1(ImmediatePriority, fn.bind(null, a, b, c));
22000 }
22001
22002 function flushPendingDiscreteUpdates() {
22003 if (rootsWithPendingDiscreteUpdates !== null) {
22004 // For each root with pending discrete updates, schedule a callback to
22005 // immediately flush them.
22006 var roots = rootsWithPendingDiscreteUpdates;
22007 rootsWithPendingDiscreteUpdates = null;
22008 roots.forEach(function (expirationTime, root) {
22009 markRootExpiredAtTime(root, expirationTime);
22010 ensureRootIsScheduled(root);
22011 }); // Now flush the immediate queue.
22012
22013 flushSyncCallbackQueue();
22014 }
22015 }
22016
22017 function batchedUpdates$1(fn, a) {
22018 var prevExecutionContext = executionContext;
22019 executionContext |= BatchedContext;
22020
22021 try {
22022 return fn(a);
22023 } finally {
22024 executionContext = prevExecutionContext;
22025
22026 if (executionContext === NoContext) {
22027 // Flush the immediate callbacks that were scheduled during this batch
22028 flushSyncCallbackQueue();
22029 }
22030 }
22031 }
22032 function batchedEventUpdates$1(fn, a) {
22033 var prevExecutionContext = executionContext;
22034 executionContext |= EventContext;
22035
22036 try {
22037 return fn(a);
22038 } finally {
22039 executionContext = prevExecutionContext;
22040
22041 if (executionContext === NoContext) {
22042 // Flush the immediate callbacks that were scheduled during this batch
22043 flushSyncCallbackQueue();
22044 }
22045 }
22046 }
22047 function discreteUpdates$1(fn, a, b, c, d) {
22048 var prevExecutionContext = executionContext;
22049 executionContext |= DiscreteEventContext;
22050
22051 try {
22052 // Should this
22053 return runWithPriority$1(UserBlockingPriority$1, fn.bind(null, a, b, c, d));
22054 } finally {
22055 executionContext = prevExecutionContext;
22056
22057 if (executionContext === NoContext) {
22058 // Flush the immediate callbacks that were scheduled during this batch
22059 flushSyncCallbackQueue();
22060 }
22061 }
22062 }
22063 function unbatchedUpdates(fn, a) {
22064 var prevExecutionContext = executionContext;
22065 executionContext &= ~BatchedContext;
22066 executionContext |= LegacyUnbatchedContext;
22067
22068 try {
22069 return fn(a);
22070 } finally {
22071 executionContext = prevExecutionContext;
22072
22073 if (executionContext === NoContext) {
22074 // Flush the immediate callbacks that were scheduled during this batch
22075 flushSyncCallbackQueue();
22076 }
22077 }
22078 }
22079 function flushSync(fn, a) {
22080 if ((executionContext & (RenderContext | CommitContext)) !== NoContext) {
22081 {
22082 {
22083 throw Error( "flushSync was called from inside a lifecycle method. It cannot be called when React is already rendering." );
22084 }
22085 }
22086 }
22087
22088 var prevExecutionContext = executionContext;
22089 executionContext |= BatchedContext;
22090
22091 try {
22092 return runWithPriority$1(ImmediatePriority, fn.bind(null, a));
22093 } finally {
22094 executionContext = prevExecutionContext; // Flush the immediate callbacks that were scheduled during this batch.
22095 // Note that this will happen even if batchedUpdates is higher up
22096 // the stack.
22097
22098 flushSyncCallbackQueue();
22099 }
22100 }
22101
22102 function prepareFreshStack(root, expirationTime) {
22103 root.finishedWork = null;
22104 root.finishedExpirationTime = NoWork;
22105 var timeoutHandle = root.timeoutHandle;
22106
22107 if (timeoutHandle !== noTimeout) {
22108 // The root previous suspended and scheduled a timeout to commit a fallback
22109 // state. Now that we have additional work, cancel the timeout.
22110 root.timeoutHandle = noTimeout; // $FlowFixMe Complains noTimeout is not a TimeoutID, despite the check above
22111
22112 cancelTimeout(timeoutHandle);
22113 }
22114
22115 if (workInProgress !== null) {
22116 var interruptedWork = workInProgress.return;
22117
22118 while (interruptedWork !== null) {
22119 unwindInterruptedWork(interruptedWork);
22120 interruptedWork = interruptedWork.return;
22121 }
22122 }
22123
22124 workInProgressRoot = root;
22125 workInProgress = createWorkInProgress(root.current, null);
22126 renderExpirationTime$1 = expirationTime;
22127 workInProgressRootExitStatus = RootIncomplete;
22128 workInProgressRootFatalError = null;
22129 workInProgressRootLatestProcessedExpirationTime = Sync;
22130 workInProgressRootLatestSuspenseTimeout = Sync;
22131 workInProgressRootCanSuspendUsingConfig = null;
22132 workInProgressRootNextUnprocessedUpdateTime = NoWork;
22133 workInProgressRootHasPendingPing = false;
22134
22135 {
22136 spawnedWorkDuringRender = null;
22137 }
22138
22139 {
22140 ReactStrictModeWarnings.discardPendingWarnings();
22141 }
22142 }
22143
22144 function handleError(root, thrownValue) {
22145 do {
22146 try {
22147 // Reset module-level state that was set during the render phase.
22148 resetContextDependencies();
22149 resetHooksAfterThrow();
22150 resetCurrentFiber();
22151
22152 if (workInProgress === null || workInProgress.return === null) {
22153 // Expected to be working on a non-root fiber. This is a fatal error
22154 // because there's no ancestor that can handle it; the root is
22155 // supposed to capture all errors that weren't caught by an error
22156 // boundary.
22157 workInProgressRootExitStatus = RootFatalErrored;
22158 workInProgressRootFatalError = thrownValue; // Set `workInProgress` to null. This represents advancing to the next
22159 // sibling, or the parent if there are no siblings. But since the root
22160 // has no siblings nor a parent, we set it to null. Usually this is
22161 // handled by `completeUnitOfWork` or `unwindWork`, but since we're
22162 // interntionally not calling those, we need set it here.
22163 // TODO: Consider calling `unwindWork` to pop the contexts.
22164
22165 workInProgress = null;
22166 return null;
22167 }
22168
22169 if (enableProfilerTimer && workInProgress.mode & ProfileMode) {
22170 // Record the time spent rendering before an error was thrown. This
22171 // avoids inaccurate Profiler durations in the case of a
22172 // suspended render.
22173 stopProfilerTimerIfRunningAndRecordDelta(workInProgress, true);
22174 }
22175
22176 throwException(root, workInProgress.return, workInProgress, thrownValue, renderExpirationTime$1);
22177 workInProgress = completeUnitOfWork(workInProgress);
22178 } catch (yetAnotherThrownValue) {
22179 // Something in the return path also threw.
22180 thrownValue = yetAnotherThrownValue;
22181 continue;
22182 } // Return to the normal work loop.
22183
22184
22185 return;
22186 } while (true);
22187 }
22188
22189 function pushDispatcher(root) {
22190 var prevDispatcher = ReactCurrentDispatcher$1.current;
22191 ReactCurrentDispatcher$1.current = ContextOnlyDispatcher;
22192
22193 if (prevDispatcher === null) {
22194 // The React isomorphic package does not include a default dispatcher.
22195 // Instead the first renderer will lazily attach one, in order to give
22196 // nicer error messages.
22197 return ContextOnlyDispatcher;
22198 } else {
22199 return prevDispatcher;
22200 }
22201 }
22202
22203 function popDispatcher(prevDispatcher) {
22204 ReactCurrentDispatcher$1.current = prevDispatcher;
22205 }
22206
22207 function pushInteractions(root) {
22208 {
22209 var prevInteractions = __interactionsRef.current;
22210 __interactionsRef.current = root.memoizedInteractions;
22211 return prevInteractions;
22212 }
22213 }
22214
22215 function popInteractions(prevInteractions) {
22216 {
22217 __interactionsRef.current = prevInteractions;
22218 }
22219 }
22220
22221 function markCommitTimeOfFallback() {
22222 globalMostRecentFallbackTime = now();
22223 }
22224 function markRenderEventTimeAndConfig(expirationTime, suspenseConfig) {
22225 if (expirationTime < workInProgressRootLatestProcessedExpirationTime && expirationTime > Idle) {
22226 workInProgressRootLatestProcessedExpirationTime = expirationTime;
22227 }
22228
22229 if (suspenseConfig !== null) {
22230 if (expirationTime < workInProgressRootLatestSuspenseTimeout && expirationTime > Idle) {
22231 workInProgressRootLatestSuspenseTimeout = expirationTime; // Most of the time we only have one config and getting wrong is not bad.
22232
22233 workInProgressRootCanSuspendUsingConfig = suspenseConfig;
22234 }
22235 }
22236 }
22237 function markUnprocessedUpdateTime(expirationTime) {
22238 if (expirationTime > workInProgressRootNextUnprocessedUpdateTime) {
22239 workInProgressRootNextUnprocessedUpdateTime = expirationTime;
22240 }
22241 }
22242 function renderDidSuspend() {
22243 if (workInProgressRootExitStatus === RootIncomplete) {
22244 workInProgressRootExitStatus = RootSuspended;
22245 }
22246 }
22247 function renderDidSuspendDelayIfPossible() {
22248 if (workInProgressRootExitStatus === RootIncomplete || workInProgressRootExitStatus === RootSuspended) {
22249 workInProgressRootExitStatus = RootSuspendedWithDelay;
22250 } // Check if there's a lower priority update somewhere else in the tree.
22251
22252
22253 if (workInProgressRootNextUnprocessedUpdateTime !== NoWork && workInProgressRoot !== null) {
22254 // Mark the current render as suspended, and then mark that there's a
22255 // pending update.
22256 // TODO: This should immediately interrupt the current render, instead
22257 // of waiting until the next time we yield.
22258 markRootSuspendedAtTime(workInProgressRoot, renderExpirationTime$1);
22259 markRootUpdatedAtTime(workInProgressRoot, workInProgressRootNextUnprocessedUpdateTime);
22260 }
22261 }
22262 function renderDidError() {
22263 if (workInProgressRootExitStatus !== RootCompleted) {
22264 workInProgressRootExitStatus = RootErrored;
22265 }
22266 } // Called during render to determine if anything has suspended.
22267 // Returns false if we're not sure.
22268
22269 function renderHasNotSuspendedYet() {
22270 // If something errored or completed, we can't really be sure,
22271 // so those are false.
22272 return workInProgressRootExitStatus === RootIncomplete;
22273 }
22274
22275 function inferTimeFromExpirationTime(expirationTime) {
22276 // We don't know exactly when the update was scheduled, but we can infer an
22277 // approximate start time from the expiration time.
22278 var earliestExpirationTimeMs = expirationTimeToMs(expirationTime);
22279 return earliestExpirationTimeMs - LOW_PRIORITY_EXPIRATION;
22280 }
22281
22282 function inferTimeFromExpirationTimeWithSuspenseConfig(expirationTime, suspenseConfig) {
22283 // We don't know exactly when the update was scheduled, but we can infer an
22284 // approximate start time from the expiration time by subtracting the timeout
22285 // that was added to the event time.
22286 var earliestExpirationTimeMs = expirationTimeToMs(expirationTime);
22287 return earliestExpirationTimeMs - (suspenseConfig.timeoutMs | 0 || LOW_PRIORITY_EXPIRATION);
22288 } // The work loop is an extremely hot path. Tell Closure not to inline it.
22289
22290 /** @noinline */
22291
22292
22293 function workLoopSync() {
22294 // Already timed out, so perform work without checking if we need to yield.
22295 while (workInProgress !== null) {
22296 workInProgress = performUnitOfWork(workInProgress);
22297 }
22298 }
22299 /** @noinline */
22300
22301
22302 function workLoopConcurrent() {
22303 // Perform work until Scheduler asks us to yield
22304 while (workInProgress !== null && !shouldYield()) {
22305 workInProgress = performUnitOfWork(workInProgress);
22306 }
22307 }
22308
22309 function performUnitOfWork(unitOfWork) {
22310 // The current, flushed, state of this fiber is the alternate. Ideally
22311 // nothing should rely on this, but relying on it here means that we don't
22312 // need an additional field on the work in progress.
22313 var current = unitOfWork.alternate;
22314 startWorkTimer(unitOfWork);
22315 setCurrentFiber(unitOfWork);
22316 var next;
22317
22318 if ( (unitOfWork.mode & ProfileMode) !== NoMode) {
22319 startProfilerTimer(unitOfWork);
22320 next = beginWork$1(current, unitOfWork, renderExpirationTime$1);
22321 stopProfilerTimerIfRunningAndRecordDelta(unitOfWork, true);
22322 } else {
22323 next = beginWork$1(current, unitOfWork, renderExpirationTime$1);
22324 }
22325
22326 resetCurrentFiber();
22327 unitOfWork.memoizedProps = unitOfWork.pendingProps;
22328
22329 if (next === null) {
22330 // If this doesn't spawn new work, complete the current work.
22331 next = completeUnitOfWork(unitOfWork);
22332 }
22333
22334 ReactCurrentOwner$2.current = null;
22335 return next;
22336 }
22337
22338 function completeUnitOfWork(unitOfWork) {
22339 // Attempt to complete the current unit of work, then move to the next
22340 // sibling. If there are no more siblings, return to the parent fiber.
22341 workInProgress = unitOfWork;
22342
22343 do {
22344 // The current, flushed, state of this fiber is the alternate. Ideally
22345 // nothing should rely on this, but relying on it here means that we don't
22346 // need an additional field on the work in progress.
22347 var current = workInProgress.alternate;
22348 var returnFiber = workInProgress.return; // Check if the work completed or if something threw.
22349
22350 if ((workInProgress.effectTag & Incomplete) === NoEffect) {
22351 setCurrentFiber(workInProgress);
22352 var next = void 0;
22353
22354 if ( (workInProgress.mode & ProfileMode) === NoMode) {
22355 next = completeWork(current, workInProgress, renderExpirationTime$1);
22356 } else {
22357 startProfilerTimer(workInProgress);
22358 next = completeWork(current, workInProgress, renderExpirationTime$1); // Update render duration assuming we didn't error.
22359
22360 stopProfilerTimerIfRunningAndRecordDelta(workInProgress, false);
22361 }
22362
22363 stopWorkTimer(workInProgress);
22364 resetCurrentFiber();
22365 resetChildExpirationTime(workInProgress);
22366
22367 if (next !== null) {
22368 // Completing this fiber spawned new work. Work on that next.
22369 return next;
22370 }
22371
22372 if (returnFiber !== null && // Do not append effects to parents if a sibling failed to complete
22373 (returnFiber.effectTag & Incomplete) === NoEffect) {
22374 // Append all the effects of the subtree and this fiber onto the effect
22375 // list of the parent. The completion order of the children affects the
22376 // side-effect order.
22377 if (returnFiber.firstEffect === null) {
22378 returnFiber.firstEffect = workInProgress.firstEffect;
22379 }
22380
22381 if (workInProgress.lastEffect !== null) {
22382 if (returnFiber.lastEffect !== null) {
22383 returnFiber.lastEffect.nextEffect = workInProgress.firstEffect;
22384 }
22385
22386 returnFiber.lastEffect = workInProgress.lastEffect;
22387 } // If this fiber had side-effects, we append it AFTER the children's
22388 // side-effects. We can perform certain side-effects earlier if needed,
22389 // by doing multiple passes over the effect list. We don't want to
22390 // schedule our own side-effect on our own list because if end up
22391 // reusing children we'll schedule this effect onto itself since we're
22392 // at the end.
22393
22394
22395 var effectTag = workInProgress.effectTag; // Skip both NoWork and PerformedWork tags when creating the effect
22396 // list. PerformedWork effect is read by React DevTools but shouldn't be
22397 // committed.
22398
22399 if (effectTag > PerformedWork) {
22400 if (returnFiber.lastEffect !== null) {
22401 returnFiber.lastEffect.nextEffect = workInProgress;
22402 } else {
22403 returnFiber.firstEffect = workInProgress;
22404 }
22405
22406 returnFiber.lastEffect = workInProgress;
22407 }
22408 }
22409 } else {
22410 // This fiber did not complete because something threw. Pop values off
22411 // the stack without entering the complete phase. If this is a boundary,
22412 // capture values if possible.
22413 var _next = unwindWork(workInProgress); // Because this fiber did not complete, don't reset its expiration time.
22414
22415
22416 if ( (workInProgress.mode & ProfileMode) !== NoMode) {
22417 // Record the render duration for the fiber that errored.
22418 stopProfilerTimerIfRunningAndRecordDelta(workInProgress, false); // Include the time spent working on failed children before continuing.
22419
22420 var actualDuration = workInProgress.actualDuration;
22421 var child = workInProgress.child;
22422
22423 while (child !== null) {
22424 actualDuration += child.actualDuration;
22425 child = child.sibling;
22426 }
22427
22428 workInProgress.actualDuration = actualDuration;
22429 }
22430
22431 if (_next !== null) {
22432 // If completing this work spawned new work, do that next. We'll come
22433 // back here again.
22434 // Since we're restarting, remove anything that is not a host effect
22435 // from the effect tag.
22436 // TODO: The name stopFailedWorkTimer is misleading because Suspense
22437 // also captures and restarts.
22438 stopFailedWorkTimer(workInProgress);
22439 _next.effectTag &= HostEffectMask;
22440 return _next;
22441 }
22442
22443 stopWorkTimer(workInProgress);
22444
22445 if (returnFiber !== null) {
22446 // Mark the parent fiber as incomplete and clear its effect list.
22447 returnFiber.firstEffect = returnFiber.lastEffect = null;
22448 returnFiber.effectTag |= Incomplete;
22449 }
22450 }
22451
22452 var siblingFiber = workInProgress.sibling;
22453
22454 if (siblingFiber !== null) {
22455 // If there is more work to do in this returnFiber, do that next.
22456 return siblingFiber;
22457 } // Otherwise, return to the parent
22458
22459
22460 workInProgress = returnFiber;
22461 } while (workInProgress !== null); // We've reached the root.
22462
22463
22464 if (workInProgressRootExitStatus === RootIncomplete) {
22465 workInProgressRootExitStatus = RootCompleted;
22466 }
22467
22468 return null;
22469 }
22470
22471 function getRemainingExpirationTime(fiber) {
22472 var updateExpirationTime = fiber.expirationTime;
22473 var childExpirationTime = fiber.childExpirationTime;
22474 return updateExpirationTime > childExpirationTime ? updateExpirationTime : childExpirationTime;
22475 }
22476
22477 function resetChildExpirationTime(completedWork) {
22478 if (renderExpirationTime$1 !== Never && completedWork.childExpirationTime === Never) {
22479 // The children of this component are hidden. Don't bubble their
22480 // expiration times.
22481 return;
22482 }
22483
22484 var newChildExpirationTime = NoWork; // Bubble up the earliest expiration time.
22485
22486 if ( (completedWork.mode & ProfileMode) !== NoMode) {
22487 // In profiling mode, resetChildExpirationTime is also used to reset
22488 // profiler durations.
22489 var actualDuration = completedWork.actualDuration;
22490 var treeBaseDuration = completedWork.selfBaseDuration; // When a fiber is cloned, its actualDuration is reset to 0. This value will
22491 // only be updated if work is done on the fiber (i.e. it doesn't bailout).
22492 // When work is done, it should bubble to the parent's actualDuration. If
22493 // the fiber has not been cloned though, (meaning no work was done), then
22494 // this value will reflect the amount of time spent working on a previous
22495 // render. In that case it should not bubble. We determine whether it was
22496 // cloned by comparing the child pointer.
22497
22498 var shouldBubbleActualDurations = completedWork.alternate === null || completedWork.child !== completedWork.alternate.child;
22499 var child = completedWork.child;
22500
22501 while (child !== null) {
22502 var childUpdateExpirationTime = child.expirationTime;
22503 var childChildExpirationTime = child.childExpirationTime;
22504
22505 if (childUpdateExpirationTime > newChildExpirationTime) {
22506 newChildExpirationTime = childUpdateExpirationTime;
22507 }
22508
22509 if (childChildExpirationTime > newChildExpirationTime) {
22510 newChildExpirationTime = childChildExpirationTime;
22511 }
22512
22513 if (shouldBubbleActualDurations) {
22514 actualDuration += child.actualDuration;
22515 }
22516
22517 treeBaseDuration += child.treeBaseDuration;
22518 child = child.sibling;
22519 }
22520
22521 completedWork.actualDuration = actualDuration;
22522 completedWork.treeBaseDuration = treeBaseDuration;
22523 } else {
22524 var _child = completedWork.child;
22525
22526 while (_child !== null) {
22527 var _childUpdateExpirationTime = _child.expirationTime;
22528 var _childChildExpirationTime = _child.childExpirationTime;
22529
22530 if (_childUpdateExpirationTime > newChildExpirationTime) {
22531 newChildExpirationTime = _childUpdateExpirationTime;
22532 }
22533
22534 if (_childChildExpirationTime > newChildExpirationTime) {
22535 newChildExpirationTime = _childChildExpirationTime;
22536 }
22537
22538 _child = _child.sibling;
22539 }
22540 }
22541
22542 completedWork.childExpirationTime = newChildExpirationTime;
22543 }
22544
22545 function commitRoot(root) {
22546 var renderPriorityLevel = getCurrentPriorityLevel();
22547 runWithPriority$1(ImmediatePriority, commitRootImpl.bind(null, root, renderPriorityLevel));
22548 return null;
22549 }
22550
22551 function commitRootImpl(root, renderPriorityLevel) {
22552 do {
22553 // `flushPassiveEffects` will call `flushSyncUpdateQueue` at the end, which
22554 // means `flushPassiveEffects` will sometimes result in additional
22555 // passive effects. So we need to keep flushing in a loop until there are
22556 // no more pending effects.
22557 // TODO: Might be better if `flushPassiveEffects` did not automatically
22558 // flush synchronous work at the end, to avoid factoring hazards like this.
22559 flushPassiveEffects();
22560 } while (rootWithPendingPassiveEffects !== null);
22561
22562 flushRenderPhaseStrictModeWarningsInDEV();
22563
22564 if (!((executionContext & (RenderContext | CommitContext)) === NoContext)) {
22565 {
22566 throw Error( "Should not already be working." );
22567 }
22568 }
22569
22570 var finishedWork = root.finishedWork;
22571 var expirationTime = root.finishedExpirationTime;
22572
22573 if (finishedWork === null) {
22574 return null;
22575 }
22576
22577 root.finishedWork = null;
22578 root.finishedExpirationTime = NoWork;
22579
22580 if (!(finishedWork !== root.current)) {
22581 {
22582 throw Error( "Cannot commit the same tree as before. This error is likely caused by a bug in React. Please file an issue." );
22583 }
22584 } // commitRoot never returns a continuation; it always finishes synchronously.
22585 // So we can clear these now to allow a new callback to be scheduled.
22586
22587
22588 root.callbackNode = null;
22589 root.callbackExpirationTime = NoWork;
22590 root.callbackPriority = NoPriority;
22591 root.nextKnownPendingLevel = NoWork;
22592 startCommitTimer(); // Update the first and last pending times on this root. The new first
22593 // pending time is whatever is left on the root fiber.
22594
22595 var remainingExpirationTimeBeforeCommit = getRemainingExpirationTime(finishedWork);
22596 markRootFinishedAtTime(root, expirationTime, remainingExpirationTimeBeforeCommit);
22597
22598 if (root === workInProgressRoot) {
22599 // We can reset these now that they are finished.
22600 workInProgressRoot = null;
22601 workInProgress = null;
22602 renderExpirationTime$1 = NoWork;
22603 } // This indicates that the last root we worked on is not the same one that
22604 // we're committing now. This most commonly happens when a suspended root
22605 // times out.
22606 // Get the list of effects.
22607
22608
22609 var firstEffect;
22610
22611 if (finishedWork.effectTag > PerformedWork) {
22612 // A fiber's effect list consists only of its children, not itself. So if
22613 // the root has an effect, we need to add it to the end of the list. The
22614 // resulting list is the set that would belong to the root's parent, if it
22615 // had one; that is, all the effects in the tree including the root.
22616 if (finishedWork.lastEffect !== null) {
22617 finishedWork.lastEffect.nextEffect = finishedWork;
22618 firstEffect = finishedWork.firstEffect;
22619 } else {
22620 firstEffect = finishedWork;
22621 }
22622 } else {
22623 // There is no effect on the root.
22624 firstEffect = finishedWork.firstEffect;
22625 }
22626
22627 if (firstEffect !== null) {
22628 var prevExecutionContext = executionContext;
22629 executionContext |= CommitContext;
22630 var prevInteractions = pushInteractions(root); // Reset this to null before calling lifecycles
22631
22632 ReactCurrentOwner$2.current = null; // The commit phase is broken into several sub-phases. We do a separate pass
22633 // of the effect list for each phase: all mutation effects come before all
22634 // layout effects, and so on.
22635 // The first phase a "before mutation" phase. We use this phase to read the
22636 // state of the host tree right before we mutate it. This is where
22637 // getSnapshotBeforeUpdate is called.
22638
22639 startCommitSnapshotEffectsTimer();
22640 prepareForCommit(root.containerInfo);
22641 nextEffect = firstEffect;
22642
22643 do {
22644 {
22645 invokeGuardedCallback(null, commitBeforeMutationEffects, null);
22646
22647 if (hasCaughtError()) {
22648 if (!(nextEffect !== null)) {
22649 {
22650 throw Error( "Should be working on an effect." );
22651 }
22652 }
22653
22654 var error = clearCaughtError();
22655 captureCommitPhaseError(nextEffect, error);
22656 nextEffect = nextEffect.nextEffect;
22657 }
22658 }
22659 } while (nextEffect !== null);
22660
22661 stopCommitSnapshotEffectsTimer();
22662
22663 {
22664 // Mark the current commit time to be shared by all Profilers in this
22665 // batch. This enables them to be grouped later.
22666 recordCommitTime();
22667 } // The next phase is the mutation phase, where we mutate the host tree.
22668
22669
22670 startCommitHostEffectsTimer();
22671 nextEffect = firstEffect;
22672
22673 do {
22674 {
22675 invokeGuardedCallback(null, commitMutationEffects, null, root, renderPriorityLevel);
22676
22677 if (hasCaughtError()) {
22678 if (!(nextEffect !== null)) {
22679 {
22680 throw Error( "Should be working on an effect." );
22681 }
22682 }
22683
22684 var _error = clearCaughtError();
22685
22686 captureCommitPhaseError(nextEffect, _error);
22687 nextEffect = nextEffect.nextEffect;
22688 }
22689 }
22690 } while (nextEffect !== null);
22691
22692 stopCommitHostEffectsTimer();
22693 resetAfterCommit(root.containerInfo); // The work-in-progress tree is now the current tree. This must come after
22694 // the mutation phase, so that the previous tree is still current during
22695 // componentWillUnmount, but before the layout phase, so that the finished
22696 // work is current during componentDidMount/Update.
22697
22698 root.current = finishedWork; // The next phase is the layout phase, where we call effects that read
22699 // the host tree after it's been mutated. The idiomatic use case for this is
22700 // layout, but class component lifecycles also fire here for legacy reasons.
22701
22702 startCommitLifeCyclesTimer();
22703 nextEffect = firstEffect;
22704
22705 do {
22706 {
22707 invokeGuardedCallback(null, commitLayoutEffects, null, root, expirationTime);
22708
22709 if (hasCaughtError()) {
22710 if (!(nextEffect !== null)) {
22711 {
22712 throw Error( "Should be working on an effect." );
22713 }
22714 }
22715
22716 var _error2 = clearCaughtError();
22717
22718 captureCommitPhaseError(nextEffect, _error2);
22719 nextEffect = nextEffect.nextEffect;
22720 }
22721 }
22722 } while (nextEffect !== null);
22723
22724 stopCommitLifeCyclesTimer();
22725 nextEffect = null; // Tell Scheduler to yield at the end of the frame, so the browser has an
22726 // opportunity to paint.
22727
22728 requestPaint();
22729
22730 {
22731 popInteractions(prevInteractions);
22732 }
22733
22734 executionContext = prevExecutionContext;
22735 } else {
22736 // No effects.
22737 root.current = finishedWork; // Measure these anyway so the flamegraph explicitly shows that there were
22738 // no effects.
22739 // TODO: Maybe there's a better way to report this.
22740
22741 startCommitSnapshotEffectsTimer();
22742 stopCommitSnapshotEffectsTimer();
22743
22744 {
22745 recordCommitTime();
22746 }
22747
22748 startCommitHostEffectsTimer();
22749 stopCommitHostEffectsTimer();
22750 startCommitLifeCyclesTimer();
22751 stopCommitLifeCyclesTimer();
22752 }
22753
22754 stopCommitTimer();
22755 var rootDidHavePassiveEffects = rootDoesHavePassiveEffects;
22756
22757 if (rootDoesHavePassiveEffects) {
22758 // This commit has passive effects. Stash a reference to them. But don't
22759 // schedule a callback until after flushing layout work.
22760 rootDoesHavePassiveEffects = false;
22761 rootWithPendingPassiveEffects = root;
22762 pendingPassiveEffectsExpirationTime = expirationTime;
22763 pendingPassiveEffectsRenderPriority = renderPriorityLevel;
22764 } else {
22765 // We are done with the effect chain at this point so let's clear the
22766 // nextEffect pointers to assist with GC. If we have passive effects, we'll
22767 // clear this in flushPassiveEffects.
22768 nextEffect = firstEffect;
22769
22770 while (nextEffect !== null) {
22771 var nextNextEffect = nextEffect.nextEffect;
22772 nextEffect.nextEffect = null;
22773 nextEffect = nextNextEffect;
22774 }
22775 } // Check if there's remaining work on this root
22776
22777
22778 var remainingExpirationTime = root.firstPendingTime;
22779
22780 if (remainingExpirationTime !== NoWork) {
22781 {
22782 if (spawnedWorkDuringRender !== null) {
22783 var expirationTimes = spawnedWorkDuringRender;
22784 spawnedWorkDuringRender = null;
22785
22786 for (var i = 0; i < expirationTimes.length; i++) {
22787 scheduleInteractions(root, expirationTimes[i], root.memoizedInteractions);
22788 }
22789 }
22790
22791 schedulePendingInteractions(root, remainingExpirationTime);
22792 }
22793 } else {
22794 // If there's no remaining work, we can clear the set of already failed
22795 // error boundaries.
22796 legacyErrorBoundariesThatAlreadyFailed = null;
22797 }
22798
22799 {
22800 if (!rootDidHavePassiveEffects) {
22801 // If there are no passive effects, then we can complete the pending interactions.
22802 // Otherwise, we'll wait until after the passive effects are flushed.
22803 // Wait to do this until after remaining work has been scheduled,
22804 // so that we don't prematurely signal complete for interactions when there's e.g. hidden work.
22805 finishPendingInteractions(root, expirationTime);
22806 }
22807 }
22808
22809 if (remainingExpirationTime === Sync) {
22810 // Count the number of times the root synchronously re-renders without
22811 // finishing. If there are too many, it indicates an infinite update loop.
22812 if (root === rootWithNestedUpdates) {
22813 nestedUpdateCount++;
22814 } else {
22815 nestedUpdateCount = 0;
22816 rootWithNestedUpdates = root;
22817 }
22818 } else {
22819 nestedUpdateCount = 0;
22820 }
22821
22822 onCommitRoot(finishedWork.stateNode, expirationTime); // Always call this before exiting `commitRoot`, to ensure that any
22823 // additional work on this root is scheduled.
22824
22825 ensureRootIsScheduled(root);
22826
22827 if (hasUncaughtError) {
22828 hasUncaughtError = false;
22829 var _error3 = firstUncaughtError;
22830 firstUncaughtError = null;
22831 throw _error3;
22832 }
22833
22834 if ((executionContext & LegacyUnbatchedContext) !== NoContext) {
22835 // This is a legacy edge case. We just committed the initial mount of
22836 // a ReactDOM.render-ed root inside of batchedUpdates. The commit fired
22837 // synchronously, but layout updates should be deferred until the end
22838 // of the batch.
22839 return null;
22840 } // If layout work was scheduled, flush it now.
22841
22842
22843 flushSyncCallbackQueue();
22844 return null;
22845 }
22846
22847 function commitBeforeMutationEffects() {
22848 while (nextEffect !== null) {
22849 var effectTag = nextEffect.effectTag;
22850
22851 if ((effectTag & Snapshot) !== NoEffect) {
22852 setCurrentFiber(nextEffect);
22853 recordEffect();
22854 var current = nextEffect.alternate;
22855 commitBeforeMutationLifeCycles(current, nextEffect);
22856 resetCurrentFiber();
22857 }
22858
22859 if ((effectTag & Passive) !== NoEffect) {
22860 // If there are passive effects, schedule a callback to flush at
22861 // the earliest opportunity.
22862 if (!rootDoesHavePassiveEffects) {
22863 rootDoesHavePassiveEffects = true;
22864 scheduleCallback(NormalPriority, function () {
22865 flushPassiveEffects();
22866 return null;
22867 });
22868 }
22869 }
22870
22871 nextEffect = nextEffect.nextEffect;
22872 }
22873 }
22874
22875 function commitMutationEffects(root, renderPriorityLevel) {
22876 // TODO: Should probably move the bulk of this function to commitWork.
22877 while (nextEffect !== null) {
22878 setCurrentFiber(nextEffect);
22879 var effectTag = nextEffect.effectTag;
22880
22881 if (effectTag & ContentReset) {
22882 commitResetTextContent(nextEffect);
22883 }
22884
22885 if (effectTag & Ref) {
22886 var current = nextEffect.alternate;
22887
22888 if (current !== null) {
22889 commitDetachRef(current);
22890 }
22891 } // The following switch statement is only concerned about placement,
22892 // updates, and deletions. To avoid needing to add a case for every possible
22893 // bitmap value, we remove the secondary effects from the effect tag and
22894 // switch on that value.
22895
22896
22897 var primaryEffectTag = effectTag & (Placement | Update | Deletion | Hydrating);
22898
22899 switch (primaryEffectTag) {
22900 case Placement:
22901 {
22902 commitPlacement(nextEffect); // Clear the "placement" from effect tag so that we know that this is
22903 // inserted, before any life-cycles like componentDidMount gets called.
22904 // TODO: findDOMNode doesn't rely on this any more but isMounted does
22905 // and isMounted is deprecated anyway so we should be able to kill this.
22906
22907 nextEffect.effectTag &= ~Placement;
22908 break;
22909 }
22910
22911 case PlacementAndUpdate:
22912 {
22913 // Placement
22914 commitPlacement(nextEffect); // Clear the "placement" from effect tag so that we know that this is
22915 // inserted, before any life-cycles like componentDidMount gets called.
22916
22917 nextEffect.effectTag &= ~Placement; // Update
22918
22919 var _current = nextEffect.alternate;
22920 commitWork(_current, nextEffect);
22921 break;
22922 }
22923
22924 case Hydrating:
22925 {
22926 nextEffect.effectTag &= ~Hydrating;
22927 break;
22928 }
22929
22930 case HydratingAndUpdate:
22931 {
22932 nextEffect.effectTag &= ~Hydrating; // Update
22933
22934 var _current2 = nextEffect.alternate;
22935 commitWork(_current2, nextEffect);
22936 break;
22937 }
22938
22939 case Update:
22940 {
22941 var _current3 = nextEffect.alternate;
22942 commitWork(_current3, nextEffect);
22943 break;
22944 }
22945
22946 case Deletion:
22947 {
22948 commitDeletion(root, nextEffect, renderPriorityLevel);
22949 break;
22950 }
22951 } // TODO: Only record a mutation effect if primaryEffectTag is non-zero.
22952
22953
22954 recordEffect();
22955 resetCurrentFiber();
22956 nextEffect = nextEffect.nextEffect;
22957 }
22958 }
22959
22960 function commitLayoutEffects(root, committedExpirationTime) {
22961 // TODO: Should probably move the bulk of this function to commitWork.
22962 while (nextEffect !== null) {
22963 setCurrentFiber(nextEffect);
22964 var effectTag = nextEffect.effectTag;
22965
22966 if (effectTag & (Update | Callback)) {
22967 recordEffect();
22968 var current = nextEffect.alternate;
22969 commitLifeCycles(root, current, nextEffect);
22970 }
22971
22972 if (effectTag & Ref) {
22973 recordEffect();
22974 commitAttachRef(nextEffect);
22975 }
22976
22977 resetCurrentFiber();
22978 nextEffect = nextEffect.nextEffect;
22979 }
22980 }
22981
22982 function flushPassiveEffects() {
22983 if (pendingPassiveEffectsRenderPriority !== NoPriority) {
22984 var priorityLevel = pendingPassiveEffectsRenderPriority > NormalPriority ? NormalPriority : pendingPassiveEffectsRenderPriority;
22985 pendingPassiveEffectsRenderPriority = NoPriority;
22986 return runWithPriority$1(priorityLevel, flushPassiveEffectsImpl);
22987 }
22988 }
22989
22990 function flushPassiveEffectsImpl() {
22991 if (rootWithPendingPassiveEffects === null) {
22992 return false;
22993 }
22994
22995 var root = rootWithPendingPassiveEffects;
22996 var expirationTime = pendingPassiveEffectsExpirationTime;
22997 rootWithPendingPassiveEffects = null;
22998 pendingPassiveEffectsExpirationTime = NoWork;
22999
23000 if (!((executionContext & (RenderContext | CommitContext)) === NoContext)) {
23001 {
23002 throw Error( "Cannot flush passive effects while already rendering." );
23003 }
23004 }
23005
23006 var prevExecutionContext = executionContext;
23007 executionContext |= CommitContext;
23008 var prevInteractions = pushInteractions(root);
23009
23010 {
23011 // Note: This currently assumes there are no passive effects on the root fiber
23012 // because the root is not part of its own effect list.
23013 // This could change in the future.
23014 var _effect2 = root.current.firstEffect;
23015
23016 while (_effect2 !== null) {
23017 {
23018 setCurrentFiber(_effect2);
23019 invokeGuardedCallback(null, commitPassiveHookEffects, null, _effect2);
23020
23021 if (hasCaughtError()) {
23022 if (!(_effect2 !== null)) {
23023 {
23024 throw Error( "Should be working on an effect." );
23025 }
23026 }
23027
23028 var _error5 = clearCaughtError();
23029
23030 captureCommitPhaseError(_effect2, _error5);
23031 }
23032
23033 resetCurrentFiber();
23034 }
23035
23036 var nextNextEffect = _effect2.nextEffect; // Remove nextEffect pointer to assist GC
23037
23038 _effect2.nextEffect = null;
23039 _effect2 = nextNextEffect;
23040 }
23041 }
23042
23043 {
23044 popInteractions(prevInteractions);
23045 finishPendingInteractions(root, expirationTime);
23046 }
23047
23048 executionContext = prevExecutionContext;
23049 flushSyncCallbackQueue(); // If additional passive effects were scheduled, increment a counter. If this
23050 // exceeds the limit, we'll fire a warning.
23051
23052 nestedPassiveUpdateCount = rootWithPendingPassiveEffects === null ? 0 : nestedPassiveUpdateCount + 1;
23053 return true;
23054 }
23055
23056 function isAlreadyFailedLegacyErrorBoundary(instance) {
23057 return legacyErrorBoundariesThatAlreadyFailed !== null && legacyErrorBoundariesThatAlreadyFailed.has(instance);
23058 }
23059 function markLegacyErrorBoundaryAsFailed(instance) {
23060 if (legacyErrorBoundariesThatAlreadyFailed === null) {
23061 legacyErrorBoundariesThatAlreadyFailed = new Set([instance]);
23062 } else {
23063 legacyErrorBoundariesThatAlreadyFailed.add(instance);
23064 }
23065 }
23066
23067 function prepareToThrowUncaughtError(error) {
23068 if (!hasUncaughtError) {
23069 hasUncaughtError = true;
23070 firstUncaughtError = error;
23071 }
23072 }
23073
23074 var onUncaughtError = prepareToThrowUncaughtError;
23075
23076 function captureCommitPhaseErrorOnRoot(rootFiber, sourceFiber, error) {
23077 var errorInfo = createCapturedValue(error, sourceFiber);
23078 var update = createRootErrorUpdate(rootFiber, errorInfo, Sync);
23079 enqueueUpdate(rootFiber, update);
23080 var root = markUpdateTimeFromFiberToRoot(rootFiber, Sync);
23081
23082 if (root !== null) {
23083 ensureRootIsScheduled(root);
23084 schedulePendingInteractions(root, Sync);
23085 }
23086 }
23087
23088 function captureCommitPhaseError(sourceFiber, error) {
23089 if (sourceFiber.tag === HostRoot) {
23090 // Error was thrown at the root. There is no parent, so the root
23091 // itself should capture it.
23092 captureCommitPhaseErrorOnRoot(sourceFiber, sourceFiber, error);
23093 return;
23094 }
23095
23096 var fiber = sourceFiber.return;
23097
23098 while (fiber !== null) {
23099 if (fiber.tag === HostRoot) {
23100 captureCommitPhaseErrorOnRoot(fiber, sourceFiber, error);
23101 return;
23102 } else if (fiber.tag === ClassComponent) {
23103 var ctor = fiber.type;
23104 var instance = fiber.stateNode;
23105
23106 if (typeof ctor.getDerivedStateFromError === 'function' || typeof instance.componentDidCatch === 'function' && !isAlreadyFailedLegacyErrorBoundary(instance)) {
23107 var errorInfo = createCapturedValue(error, sourceFiber);
23108 var update = createClassErrorUpdate(fiber, errorInfo, // TODO: This is always sync
23109 Sync);
23110 enqueueUpdate(fiber, update);
23111 var root = markUpdateTimeFromFiberToRoot(fiber, Sync);
23112
23113 if (root !== null) {
23114 ensureRootIsScheduled(root);
23115 schedulePendingInteractions(root, Sync);
23116 }
23117
23118 return;
23119 }
23120 }
23121
23122 fiber = fiber.return;
23123 }
23124 }
23125 function pingSuspendedRoot(root, thenable, suspendedTime) {
23126 var pingCache = root.pingCache;
23127
23128 if (pingCache !== null) {
23129 // The thenable resolved, so we no longer need to memoize, because it will
23130 // never be thrown again.
23131 pingCache.delete(thenable);
23132 }
23133
23134 if (workInProgressRoot === root && renderExpirationTime$1 === suspendedTime) {
23135 // Received a ping at the same priority level at which we're currently
23136 // rendering. We might want to restart this render. This should mirror
23137 // the logic of whether or not a root suspends once it completes.
23138 // TODO: If we're rendering sync either due to Sync, Batched or expired,
23139 // we should probably never restart.
23140 // If we're suspended with delay, we'll always suspend so we can always
23141 // restart. If we're suspended without any updates, it might be a retry.
23142 // If it's early in the retry we can restart. We can't know for sure
23143 // whether we'll eventually process an update during this render pass,
23144 // but it's somewhat unlikely that we get to a ping before that, since
23145 // getting to the root most update is usually very fast.
23146 if (workInProgressRootExitStatus === RootSuspendedWithDelay || workInProgressRootExitStatus === RootSuspended && workInProgressRootLatestProcessedExpirationTime === Sync && now() - globalMostRecentFallbackTime < FALLBACK_THROTTLE_MS) {
23147 // Restart from the root. Don't need to schedule a ping because
23148 // we're already working on this tree.
23149 prepareFreshStack(root, renderExpirationTime$1);
23150 } else {
23151 // Even though we can't restart right now, we might get an
23152 // opportunity later. So we mark this render as having a ping.
23153 workInProgressRootHasPendingPing = true;
23154 }
23155
23156 return;
23157 }
23158
23159 if (!isRootSuspendedAtTime(root, suspendedTime)) {
23160 // The root is no longer suspended at this time.
23161 return;
23162 }
23163
23164 var lastPingedTime = root.lastPingedTime;
23165
23166 if (lastPingedTime !== NoWork && lastPingedTime < suspendedTime) {
23167 // There's already a lower priority ping scheduled.
23168 return;
23169 } // Mark the time at which this ping was scheduled.
23170
23171
23172 root.lastPingedTime = suspendedTime;
23173
23174 ensureRootIsScheduled(root);
23175 schedulePendingInteractions(root, suspendedTime);
23176 }
23177
23178 function retryTimedOutBoundary(boundaryFiber, retryTime) {
23179 // The boundary fiber (a Suspense component or SuspenseList component)
23180 // previously was rendered in its fallback state. One of the promises that
23181 // suspended it has resolved, which means at least part of the tree was
23182 // likely unblocked. Try rendering again, at a new expiration time.
23183 if (retryTime === NoWork) {
23184 var suspenseConfig = null; // Retries don't carry over the already committed update.
23185
23186 var currentTime = requestCurrentTimeForUpdate();
23187 retryTime = computeExpirationForFiber(currentTime, boundaryFiber, suspenseConfig);
23188 } // TODO: Special case idle priority?
23189
23190
23191 var root = markUpdateTimeFromFiberToRoot(boundaryFiber, retryTime);
23192
23193 if (root !== null) {
23194 ensureRootIsScheduled(root);
23195 schedulePendingInteractions(root, retryTime);
23196 }
23197 }
23198 function resolveRetryThenable(boundaryFiber, thenable) {
23199 var retryTime = NoWork; // Default
23200
23201 var retryCache;
23202
23203 {
23204 retryCache = boundaryFiber.stateNode;
23205 }
23206
23207 if (retryCache !== null) {
23208 // The thenable resolved, so we no longer need to memoize, because it will
23209 // never be thrown again.
23210 retryCache.delete(thenable);
23211 }
23212
23213 retryTimedOutBoundary(boundaryFiber, retryTime);
23214 } // Computes the next Just Noticeable Difference (JND) boundary.
23215 // The theory is that a person can't tell the difference between small differences in time.
23216 // Therefore, if we wait a bit longer than necessary that won't translate to a noticeable
23217 // difference in the experience. However, waiting for longer might mean that we can avoid
23218 // showing an intermediate loading state. The longer we have already waited, the harder it
23219 // is to tell small differences in time. Therefore, the longer we've already waited,
23220 // the longer we can wait additionally. At some point we have to give up though.
23221 // We pick a train model where the next boundary commits at a consistent schedule.
23222 // These particular numbers are vague estimates. We expect to adjust them based on research.
23223
23224 function jnd(timeElapsed) {
23225 return timeElapsed < 120 ? 120 : timeElapsed < 480 ? 480 : timeElapsed < 1080 ? 1080 : timeElapsed < 1920 ? 1920 : timeElapsed < 3000 ? 3000 : timeElapsed < 4320 ? 4320 : ceil(timeElapsed / 1960) * 1960;
23226 }
23227
23228 function computeMsUntilSuspenseLoadingDelay(mostRecentEventTime, committedExpirationTime, suspenseConfig) {
23229 var busyMinDurationMs = suspenseConfig.busyMinDurationMs | 0;
23230
23231 if (busyMinDurationMs <= 0) {
23232 return 0;
23233 }
23234
23235 var busyDelayMs = suspenseConfig.busyDelayMs | 0; // Compute the time until this render pass would expire.
23236
23237 var currentTimeMs = now();
23238 var eventTimeMs = inferTimeFromExpirationTimeWithSuspenseConfig(mostRecentEventTime, suspenseConfig);
23239 var timeElapsed = currentTimeMs - eventTimeMs;
23240
23241 if (timeElapsed <= busyDelayMs) {
23242 // If we haven't yet waited longer than the initial delay, we don't
23243 // have to wait any additional time.
23244 return 0;
23245 }
23246
23247 var msUntilTimeout = busyDelayMs + busyMinDurationMs - timeElapsed; // This is the value that is passed to `setTimeout`.
23248
23249 return msUntilTimeout;
23250 }
23251
23252 function checkForNestedUpdates() {
23253 if (nestedUpdateCount > NESTED_UPDATE_LIMIT) {
23254 nestedUpdateCount = 0;
23255 rootWithNestedUpdates = null;
23256
23257 {
23258 {
23259 throw 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." );
23260 }
23261 }
23262 }
23263
23264 {
23265 if (nestedPassiveUpdateCount > NESTED_PASSIVE_UPDATE_LIMIT) {
23266 nestedPassiveUpdateCount = 0;
23267
23268 error('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.');
23269 }
23270 }
23271 }
23272
23273 function flushRenderPhaseStrictModeWarningsInDEV() {
23274 {
23275 ReactStrictModeWarnings.flushLegacyContextWarning();
23276
23277 {
23278 ReactStrictModeWarnings.flushPendingUnsafeLifecycleWarnings();
23279 }
23280 }
23281 }
23282
23283 function stopFinishedWorkLoopTimer() {
23284 var didCompleteRoot = true;
23285 stopWorkLoopTimer(interruptedBy, didCompleteRoot);
23286 interruptedBy = null;
23287 }
23288
23289 function stopInterruptedWorkLoopTimer() {
23290 // TODO: Track which fiber caused the interruption.
23291 var didCompleteRoot = false;
23292 stopWorkLoopTimer(interruptedBy, didCompleteRoot);
23293 interruptedBy = null;
23294 }
23295
23296 function checkForInterruption(fiberThatReceivedUpdate, updateExpirationTime) {
23297 if ( workInProgressRoot !== null && updateExpirationTime > renderExpirationTime$1) {
23298 interruptedBy = fiberThatReceivedUpdate;
23299 }
23300 }
23301
23302 var didWarnStateUpdateForUnmountedComponent = null;
23303
23304 function warnAboutUpdateOnUnmountedFiberInDEV(fiber) {
23305 {
23306 var tag = fiber.tag;
23307
23308 if (tag !== HostRoot && tag !== ClassComponent && tag !== FunctionComponent && tag !== ForwardRef && tag !== MemoComponent && tag !== SimpleMemoComponent && tag !== Block) {
23309 // Only warn for user-defined components, not internal ones like Suspense.
23310 return;
23311 }
23312 // the problematic code almost always lies inside that component.
23313
23314
23315 var componentName = getComponentName(fiber.type) || 'ReactComponent';
23316
23317 if (didWarnStateUpdateForUnmountedComponent !== null) {
23318 if (didWarnStateUpdateForUnmountedComponent.has(componentName)) {
23319 return;
23320 }
23321
23322 didWarnStateUpdateForUnmountedComponent.add(componentName);
23323 } else {
23324 didWarnStateUpdateForUnmountedComponent = new Set([componentName]);
23325 }
23326
23327 error("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));
23328 }
23329 }
23330
23331 var beginWork$1;
23332
23333 {
23334 var dummyFiber = null;
23335
23336 beginWork$1 = function (current, unitOfWork, expirationTime) {
23337 // If a component throws an error, we replay it again in a synchronously
23338 // dispatched event, so that the debugger will treat it as an uncaught
23339 // error See ReactErrorUtils for more information.
23340 // Before entering the begin phase, copy the work-in-progress onto a dummy
23341 // fiber. If beginWork throws, we'll use this to reset the state.
23342 var originalWorkInProgressCopy = assignFiberPropertiesInDEV(dummyFiber, unitOfWork);
23343
23344 try {
23345 return beginWork(current, unitOfWork, expirationTime);
23346 } catch (originalError) {
23347 if (originalError !== null && typeof originalError === 'object' && typeof originalError.then === 'function') {
23348 // Don't replay promises. Treat everything else like an error.
23349 throw originalError;
23350 } // Keep this code in sync with handleError; any changes here must have
23351 // corresponding changes there.
23352
23353
23354 resetContextDependencies();
23355 resetHooksAfterThrow(); // Don't reset current debug fiber, since we're about to work on the
23356 // same fiber again.
23357 // Unwind the failed stack frame
23358
23359 unwindInterruptedWork(unitOfWork); // Restore the original properties of the fiber.
23360
23361 assignFiberPropertiesInDEV(unitOfWork, originalWorkInProgressCopy);
23362
23363 if ( unitOfWork.mode & ProfileMode) {
23364 // Reset the profiler timer.
23365 startProfilerTimer(unitOfWork);
23366 } // Run beginWork again.
23367
23368
23369 invokeGuardedCallback(null, beginWork, null, current, unitOfWork, expirationTime);
23370
23371 if (hasCaughtError()) {
23372 var replayError = clearCaughtError(); // `invokeGuardedCallback` sometimes sets an expando `_suppressLogging`.
23373 // Rethrow this error instead of the original one.
23374
23375 throw replayError;
23376 } else {
23377 // This branch is reachable if the render phase is impure.
23378 throw originalError;
23379 }
23380 }
23381 };
23382 }
23383
23384 var didWarnAboutUpdateInRender = false;
23385 var didWarnAboutUpdateInGetChildContext = false;
23386
23387 function warnAboutRenderPhaseUpdatesInDEV(fiber) {
23388 {
23389 if ((executionContext & RenderContext) !== NoContext) {
23390 switch (fiber.tag) {
23391 case FunctionComponent:
23392 case ForwardRef:
23393 case SimpleMemoComponent:
23394 {
23395 error('Cannot update a component from inside the function body of a ' + 'different component.');
23396
23397 break;
23398 }
23399
23400 case ClassComponent:
23401 {
23402 switch (phase) {
23403 case 'getChildContext':
23404 if (didWarnAboutUpdateInGetChildContext) {
23405 return;
23406 }
23407
23408 error('setState(...): Cannot call setState() inside getChildContext()');
23409
23410 didWarnAboutUpdateInGetChildContext = true;
23411 break;
23412
23413 case 'render':
23414 if (didWarnAboutUpdateInRender) {
23415 return;
23416 }
23417
23418 error('Cannot update during an existing state transition (such as ' + 'within `render`). Render methods should be a pure ' + 'function of props and state.');
23419
23420 didWarnAboutUpdateInRender = true;
23421 break;
23422 }
23423
23424 break;
23425 }
23426 }
23427 }
23428 }
23429 } // a 'shared' variable that changes when act() opens/closes in tests.
23430
23431
23432 var IsThisRendererActing = {
23433 current: false
23434 };
23435 function warnIfNotScopedWithMatchingAct(fiber) {
23436 {
23437 if ( IsSomeRendererActing.current === true && IsThisRendererActing.current !== true) {
23438 error("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));
23439 }
23440 }
23441 }
23442 function warnIfNotCurrentlyActingEffectsInDEV(fiber) {
23443 {
23444 if ( (fiber.mode & StrictMode) !== NoMode && IsSomeRendererActing.current === false && IsThisRendererActing.current === false) {
23445 error('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));
23446 }
23447 }
23448 }
23449
23450 function warnIfNotCurrentlyActingUpdatesInDEV(fiber) {
23451 {
23452 if ( executionContext === NoContext && IsSomeRendererActing.current === false && IsThisRendererActing.current === false) {
23453 error('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));
23454 }
23455 }
23456 }
23457
23458 var warnIfNotCurrentlyActingUpdatesInDev = warnIfNotCurrentlyActingUpdatesInDEV; // In tests, we want to enforce a mocked scheduler.
23459
23460 var didWarnAboutUnmockedScheduler = false; // TODO Before we release concurrent mode, revisit this and decide whether a mocked
23461 // scheduler is the actual recommendation. The alternative could be a testing build,
23462 // a new lib, or whatever; we dunno just yet. This message is for early adopters
23463 // to get their tests right.
23464
23465 function warnIfUnmockedScheduler(fiber) {
23466 {
23467 if (didWarnAboutUnmockedScheduler === false && unstable_flushAllWithoutAsserting === undefined) {
23468 if (fiber.mode & BlockingMode || fiber.mode & ConcurrentMode) {
23469 didWarnAboutUnmockedScheduler = true;
23470
23471 error('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');
23472 }
23473 }
23474 }
23475 }
23476
23477 function computeThreadID(root, expirationTime) {
23478 // Interaction threads are unique per root and expiration time.
23479 return expirationTime * 1000 + root.interactionThreadID;
23480 }
23481
23482 function markSpawnedWork(expirationTime) {
23483
23484 if (spawnedWorkDuringRender === null) {
23485 spawnedWorkDuringRender = [expirationTime];
23486 } else {
23487 spawnedWorkDuringRender.push(expirationTime);
23488 }
23489 }
23490
23491 function scheduleInteractions(root, expirationTime, interactions) {
23492
23493 if (interactions.size > 0) {
23494 var pendingInteractionMap = root.pendingInteractionMap;
23495 var pendingInteractions = pendingInteractionMap.get(expirationTime);
23496
23497 if (pendingInteractions != null) {
23498 interactions.forEach(function (interaction) {
23499 if (!pendingInteractions.has(interaction)) {
23500 // Update the pending async work count for previously unscheduled interaction.
23501 interaction.__count++;
23502 }
23503
23504 pendingInteractions.add(interaction);
23505 });
23506 } else {
23507 pendingInteractionMap.set(expirationTime, new Set(interactions)); // Update the pending async work count for the current interactions.
23508
23509 interactions.forEach(function (interaction) {
23510 interaction.__count++;
23511 });
23512 }
23513
23514 var subscriber = __subscriberRef.current;
23515
23516 if (subscriber !== null) {
23517 var threadID = computeThreadID(root, expirationTime);
23518 subscriber.onWorkScheduled(interactions, threadID);
23519 }
23520 }
23521 }
23522
23523 function schedulePendingInteractions(root, expirationTime) {
23524
23525 scheduleInteractions(root, expirationTime, __interactionsRef.current);
23526 }
23527
23528 function startWorkOnPendingInteractions(root, expirationTime) {
23529 // we can accurately attribute time spent working on it, And so that cascading
23530 // work triggered during the render phase will be associated with it.
23531
23532
23533 var interactions = new Set();
23534 root.pendingInteractionMap.forEach(function (scheduledInteractions, scheduledExpirationTime) {
23535 if (scheduledExpirationTime >= expirationTime) {
23536 scheduledInteractions.forEach(function (interaction) {
23537 return interactions.add(interaction);
23538 });
23539 }
23540 }); // Store the current set of interactions on the FiberRoot for a few reasons:
23541 // We can re-use it in hot functions like performConcurrentWorkOnRoot()
23542 // without having to recalculate it. We will also use it in commitWork() to
23543 // pass to any Profiler onRender() hooks. This also provides DevTools with a
23544 // way to access it when the onCommitRoot() hook is called.
23545
23546 root.memoizedInteractions = interactions;
23547
23548 if (interactions.size > 0) {
23549 var subscriber = __subscriberRef.current;
23550
23551 if (subscriber !== null) {
23552 var threadID = computeThreadID(root, expirationTime);
23553
23554 try {
23555 subscriber.onWorkStarted(interactions, threadID);
23556 } catch (error) {
23557 // If the subscriber throws, rethrow it in a separate task
23558 scheduleCallback(ImmediatePriority, function () {
23559 throw error;
23560 });
23561 }
23562 }
23563 }
23564 }
23565
23566 function finishPendingInteractions(root, committedExpirationTime) {
23567
23568 var earliestRemainingTimeAfterCommit = root.firstPendingTime;
23569 var subscriber;
23570
23571 try {
23572 subscriber = __subscriberRef.current;
23573
23574 if (subscriber !== null && root.memoizedInteractions.size > 0) {
23575 var threadID = computeThreadID(root, committedExpirationTime);
23576 subscriber.onWorkStopped(root.memoizedInteractions, threadID);
23577 }
23578 } catch (error) {
23579 // If the subscriber throws, rethrow it in a separate task
23580 scheduleCallback(ImmediatePriority, function () {
23581 throw error;
23582 });
23583 } finally {
23584 // Clear completed interactions from the pending Map.
23585 // Unless the render was suspended or cascading work was scheduled,
23586 // In which case– leave pending interactions until the subsequent render.
23587 var pendingInteractionMap = root.pendingInteractionMap;
23588 pendingInteractionMap.forEach(function (scheduledInteractions, scheduledExpirationTime) {
23589 // Only decrement the pending interaction count if we're done.
23590 // If there's still work at the current priority,
23591 // That indicates that we are waiting for suspense data.
23592 if (scheduledExpirationTime > earliestRemainingTimeAfterCommit) {
23593 pendingInteractionMap.delete(scheduledExpirationTime);
23594 scheduledInteractions.forEach(function (interaction) {
23595 interaction.__count--;
23596
23597 if (subscriber !== null && interaction.__count === 0) {
23598 try {
23599 subscriber.onInteractionScheduledWorkCompleted(interaction);
23600 } catch (error) {
23601 // If the subscriber throws, rethrow it in a separate task
23602 scheduleCallback(ImmediatePriority, function () {
23603 throw error;
23604 });
23605 }
23606 }
23607 });
23608 }
23609 });
23610 }
23611 }
23612
23613 var onScheduleFiberRoot = null;
23614 var onCommitFiberRoot = null;
23615 var onCommitFiberUnmount = null;
23616 var hasLoggedError = false;
23617 var isDevToolsPresent = typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ !== 'undefined';
23618 function injectInternals(internals) {
23619 if (typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ === 'undefined') {
23620 // No DevTools
23621 return false;
23622 }
23623
23624 var hook = __REACT_DEVTOOLS_GLOBAL_HOOK__;
23625
23626 if (hook.isDisabled) {
23627 // This isn't a real property on the hook, but it can be set to opt out
23628 // of DevTools integration and associated warnings and logs.
23629 // https://github.com/facebook/react/issues/3877
23630 return true;
23631 }
23632
23633 if (!hook.supportsFiber) {
23634 {
23635 error('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');
23636 } // DevTools exists, even though it doesn't support Fiber.
23637
23638
23639 return true;
23640 }
23641
23642 try {
23643 var rendererID = hook.inject(internals); // We have successfully injected, so now it is safe to set up hooks.
23644
23645 if (true) {
23646 // Only used by Fast Refresh
23647 if (typeof hook.onScheduleFiberRoot === 'function') {
23648 onScheduleFiberRoot = function (root, children) {
23649 try {
23650 hook.onScheduleFiberRoot(rendererID, root, children);
23651 } catch (err) {
23652 if (true && !hasLoggedError) {
23653 hasLoggedError = true;
23654
23655 error('React instrumentation encountered an error: %s', err);
23656 }
23657 }
23658 };
23659 }
23660 }
23661
23662 onCommitFiberRoot = function (root, expirationTime) {
23663 try {
23664 var didError = (root.current.effectTag & DidCapture) === DidCapture;
23665
23666 if (enableProfilerTimer) {
23667 var currentTime = getCurrentTime();
23668 var priorityLevel = inferPriorityFromExpirationTime(currentTime, expirationTime);
23669 hook.onCommitFiberRoot(rendererID, root, priorityLevel, didError);
23670 } else {
23671 hook.onCommitFiberRoot(rendererID, root, undefined, didError);
23672 }
23673 } catch (err) {
23674 if (true) {
23675 if (!hasLoggedError) {
23676 hasLoggedError = true;
23677
23678 error('React instrumentation encountered an error: %s', err);
23679 }
23680 }
23681 }
23682 };
23683
23684 onCommitFiberUnmount = function (fiber) {
23685 try {
23686 hook.onCommitFiberUnmount(rendererID, fiber);
23687 } catch (err) {
23688 if (true) {
23689 if (!hasLoggedError) {
23690 hasLoggedError = true;
23691
23692 error('React instrumentation encountered an error: %s', err);
23693 }
23694 }
23695 }
23696 };
23697 } catch (err) {
23698 // Catch all errors because it is unsafe to throw during initialization.
23699 {
23700 error('React instrumentation encountered an error: %s.', err);
23701 }
23702 } // DevTools exists
23703
23704
23705 return true;
23706 }
23707 function onScheduleRoot(root, children) {
23708 if (typeof onScheduleFiberRoot === 'function') {
23709 onScheduleFiberRoot(root, children);
23710 }
23711 }
23712 function onCommitRoot(root, expirationTime) {
23713 if (typeof onCommitFiberRoot === 'function') {
23714 onCommitFiberRoot(root, expirationTime);
23715 }
23716 }
23717 function onCommitUnmount(fiber) {
23718 if (typeof onCommitFiberUnmount === 'function') {
23719 onCommitFiberUnmount(fiber);
23720 }
23721 }
23722
23723 var hasBadMapPolyfill;
23724
23725 {
23726 hasBadMapPolyfill = false;
23727
23728 try {
23729 var nonExtensibleObject = Object.preventExtensions({});
23730 var testMap = new Map([[nonExtensibleObject, null]]);
23731 var testSet = new Set([nonExtensibleObject]); // This is necessary for Rollup to not consider these unused.
23732 // https://github.com/rollup/rollup/issues/1771
23733 // TODO: we can remove these if Rollup fixes the bug.
23734
23735 testMap.set(0, 0);
23736 testSet.add(0);
23737 } catch (e) {
23738 // TODO: Consider warning about bad polyfills
23739 hasBadMapPolyfill = true;
23740 }
23741 }
23742
23743 var debugCounter = 1;
23744
23745 function FiberNode(tag, pendingProps, key, mode) {
23746 // Instance
23747 this.tag = tag;
23748 this.key = key;
23749 this.elementType = null;
23750 this.type = null;
23751 this.stateNode = null; // Fiber
23752
23753 this.return = null;
23754 this.child = null;
23755 this.sibling = null;
23756 this.index = 0;
23757 this.ref = null;
23758 this.pendingProps = pendingProps;
23759 this.memoizedProps = null;
23760 this.updateQueue = null;
23761 this.memoizedState = null;
23762 this.dependencies = null;
23763 this.mode = mode; // Effects
23764
23765 this.effectTag = NoEffect;
23766 this.nextEffect = null;
23767 this.firstEffect = null;
23768 this.lastEffect = null;
23769 this.expirationTime = NoWork;
23770 this.childExpirationTime = NoWork;
23771 this.alternate = null;
23772
23773 {
23774 // Note: The following is done to avoid a v8 performance cliff.
23775 //
23776 // Initializing the fields below to smis and later updating them with
23777 // double values will cause Fibers to end up having separate shapes.
23778 // This behavior/bug has something to do with Object.preventExtension().
23779 // Fortunately this only impacts DEV builds.
23780 // Unfortunately it makes React unusably slow for some applications.
23781 // To work around this, initialize the fields below with doubles.
23782 //
23783 // Learn more about this here:
23784 // https://github.com/facebook/react/issues/14365
23785 // https://bugs.chromium.org/p/v8/issues/detail?id=8538
23786 this.actualDuration = Number.NaN;
23787 this.actualStartTime = Number.NaN;
23788 this.selfBaseDuration = Number.NaN;
23789 this.treeBaseDuration = Number.NaN; // It's okay to replace the initial doubles with smis after initialization.
23790 // This won't trigger the performance cliff mentioned above,
23791 // and it simplifies other profiler code (including DevTools).
23792
23793 this.actualDuration = 0;
23794 this.actualStartTime = -1;
23795 this.selfBaseDuration = 0;
23796 this.treeBaseDuration = 0;
23797 } // This is normally DEV-only except www when it adds listeners.
23798 // TODO: remove the User Timing integration in favor of Root Events.
23799
23800
23801 {
23802 this._debugID = debugCounter++;
23803 this._debugIsCurrentlyTiming = false;
23804 }
23805
23806 {
23807 this._debugSource = null;
23808 this._debugOwner = null;
23809 this._debugNeedsRemount = false;
23810 this._debugHookTypes = null;
23811
23812 if (!hasBadMapPolyfill && typeof Object.preventExtensions === 'function') {
23813 Object.preventExtensions(this);
23814 }
23815 }
23816 } // This is a constructor function, rather than a POJO constructor, still
23817 // please ensure we do the following:
23818 // 1) Nobody should add any instance methods on this. Instance methods can be
23819 // more difficult to predict when they get optimized and they are almost
23820 // never inlined properly in static compilers.
23821 // 2) Nobody should rely on `instanceof Fiber` for type testing. We should
23822 // always know when it is a fiber.
23823 // 3) We might want to experiment with using numeric keys since they are easier
23824 // to optimize in a non-JIT environment.
23825 // 4) We can easily go from a constructor to a createFiber object literal if that
23826 // is faster.
23827 // 5) It should be easy to port this to a C struct and keep a C implementation
23828 // compatible.
23829
23830
23831 var createFiber = function (tag, pendingProps, key, mode) {
23832 // $FlowFixMe: the shapes are exact here but Flow doesn't like constructors
23833 return new FiberNode(tag, pendingProps, key, mode);
23834 };
23835
23836 function shouldConstruct(Component) {
23837 var prototype = Component.prototype;
23838 return !!(prototype && prototype.isReactComponent);
23839 }
23840
23841 function isSimpleFunctionComponent(type) {
23842 return typeof type === 'function' && !shouldConstruct(type) && type.defaultProps === undefined;
23843 }
23844 function resolveLazyComponentTag(Component) {
23845 if (typeof Component === 'function') {
23846 return shouldConstruct(Component) ? ClassComponent : FunctionComponent;
23847 } else if (Component !== undefined && Component !== null) {
23848 var $$typeof = Component.$$typeof;
23849
23850 if ($$typeof === REACT_FORWARD_REF_TYPE) {
23851 return ForwardRef;
23852 }
23853
23854 if ($$typeof === REACT_MEMO_TYPE) {
23855 return MemoComponent;
23856 }
23857 }
23858
23859 return IndeterminateComponent;
23860 } // This is used to create an alternate fiber to do work on.
23861
23862 function createWorkInProgress(current, pendingProps) {
23863 var workInProgress = current.alternate;
23864
23865 if (workInProgress === null) {
23866 // We use a double buffering pooling technique because we know that we'll
23867 // only ever need at most two versions of a tree. We pool the "other" unused
23868 // node that we're free to reuse. This is lazily created to avoid allocating
23869 // extra objects for things that are never updated. It also allow us to
23870 // reclaim the extra memory if needed.
23871 workInProgress = createFiber(current.tag, pendingProps, current.key, current.mode);
23872 workInProgress.elementType = current.elementType;
23873 workInProgress.type = current.type;
23874 workInProgress.stateNode = current.stateNode;
23875
23876 {
23877 // DEV-only fields
23878 {
23879 workInProgress._debugID = current._debugID;
23880 }
23881
23882 workInProgress._debugSource = current._debugSource;
23883 workInProgress._debugOwner = current._debugOwner;
23884 workInProgress._debugHookTypes = current._debugHookTypes;
23885 }
23886
23887 workInProgress.alternate = current;
23888 current.alternate = workInProgress;
23889 } else {
23890 workInProgress.pendingProps = pendingProps; // We already have an alternate.
23891 // Reset the effect tag.
23892
23893 workInProgress.effectTag = NoEffect; // The effect list is no longer valid.
23894
23895 workInProgress.nextEffect = null;
23896 workInProgress.firstEffect = null;
23897 workInProgress.lastEffect = null;
23898
23899 {
23900 // We intentionally reset, rather than copy, actualDuration & actualStartTime.
23901 // This prevents time from endlessly accumulating in new commits.
23902 // This has the downside of resetting values for different priority renders,
23903 // But works for yielding (the common case) and should support resuming.
23904 workInProgress.actualDuration = 0;
23905 workInProgress.actualStartTime = -1;
23906 }
23907 }
23908
23909 workInProgress.childExpirationTime = current.childExpirationTime;
23910 workInProgress.expirationTime = current.expirationTime;
23911 workInProgress.child = current.child;
23912 workInProgress.memoizedProps = current.memoizedProps;
23913 workInProgress.memoizedState = current.memoizedState;
23914 workInProgress.updateQueue = current.updateQueue; // Clone the dependencies object. This is mutated during the render phase, so
23915 // it cannot be shared with the current fiber.
23916
23917 var currentDependencies = current.dependencies;
23918 workInProgress.dependencies = currentDependencies === null ? null : {
23919 expirationTime: currentDependencies.expirationTime,
23920 firstContext: currentDependencies.firstContext,
23921 responders: currentDependencies.responders
23922 }; // These will be overridden during the parent's reconciliation
23923
23924 workInProgress.sibling = current.sibling;
23925 workInProgress.index = current.index;
23926 workInProgress.ref = current.ref;
23927
23928 {
23929 workInProgress.selfBaseDuration = current.selfBaseDuration;
23930 workInProgress.treeBaseDuration = current.treeBaseDuration;
23931 }
23932
23933 {
23934 workInProgress._debugNeedsRemount = current._debugNeedsRemount;
23935
23936 switch (workInProgress.tag) {
23937 case IndeterminateComponent:
23938 case FunctionComponent:
23939 case SimpleMemoComponent:
23940 workInProgress.type = resolveFunctionForHotReloading(current.type);
23941 break;
23942
23943 case ClassComponent:
23944 workInProgress.type = resolveClassForHotReloading(current.type);
23945 break;
23946
23947 case ForwardRef:
23948 workInProgress.type = resolveForwardRefForHotReloading(current.type);
23949 break;
23950 }
23951 }
23952
23953 return workInProgress;
23954 } // Used to reuse a Fiber for a second pass.
23955
23956 function resetWorkInProgress(workInProgress, renderExpirationTime) {
23957 // This resets the Fiber to what createFiber or createWorkInProgress would
23958 // have set the values to before during the first pass. Ideally this wouldn't
23959 // be necessary but unfortunately many code paths reads from the workInProgress
23960 // when they should be reading from current and writing to workInProgress.
23961 // We assume pendingProps, index, key, ref, return are still untouched to
23962 // avoid doing another reconciliation.
23963 // Reset the effect tag but keep any Placement tags, since that's something
23964 // that child fiber is setting, not the reconciliation.
23965 workInProgress.effectTag &= Placement; // The effect list is no longer valid.
23966
23967 workInProgress.nextEffect = null;
23968 workInProgress.firstEffect = null;
23969 workInProgress.lastEffect = null;
23970 var current = workInProgress.alternate;
23971
23972 if (current === null) {
23973 // Reset to createFiber's initial values.
23974 workInProgress.childExpirationTime = NoWork;
23975 workInProgress.expirationTime = renderExpirationTime;
23976 workInProgress.child = null;
23977 workInProgress.memoizedProps = null;
23978 workInProgress.memoizedState = null;
23979 workInProgress.updateQueue = null;
23980 workInProgress.dependencies = null;
23981
23982 {
23983 // Note: We don't reset the actualTime counts. It's useful to accumulate
23984 // actual time across multiple render passes.
23985 workInProgress.selfBaseDuration = 0;
23986 workInProgress.treeBaseDuration = 0;
23987 }
23988 } else {
23989 // Reset to the cloned values that createWorkInProgress would've.
23990 workInProgress.childExpirationTime = current.childExpirationTime;
23991 workInProgress.expirationTime = current.expirationTime;
23992 workInProgress.child = current.child;
23993 workInProgress.memoizedProps = current.memoizedProps;
23994 workInProgress.memoizedState = current.memoizedState;
23995 workInProgress.updateQueue = current.updateQueue; // Clone the dependencies object. This is mutated during the render phase, so
23996 // it cannot be shared with the current fiber.
23997
23998 var currentDependencies = current.dependencies;
23999 workInProgress.dependencies = currentDependencies === null ? null : {
24000 expirationTime: currentDependencies.expirationTime,
24001 firstContext: currentDependencies.firstContext,
24002 responders: currentDependencies.responders
24003 };
24004
24005 {
24006 // Note: We don't reset the actualTime counts. It's useful to accumulate
24007 // actual time across multiple render passes.
24008 workInProgress.selfBaseDuration = current.selfBaseDuration;
24009 workInProgress.treeBaseDuration = current.treeBaseDuration;
24010 }
24011 }
24012
24013 return workInProgress;
24014 }
24015 function createHostRootFiber(tag) {
24016 var mode;
24017
24018 if (tag === ConcurrentRoot) {
24019 mode = ConcurrentMode | BlockingMode | StrictMode;
24020 } else if (tag === BlockingRoot) {
24021 mode = BlockingMode | StrictMode;
24022 } else {
24023 mode = NoMode;
24024 }
24025
24026 if ( isDevToolsPresent) {
24027 // Always collect profile timings when DevTools are present.
24028 // This enables DevTools to start capturing timing at any point–
24029 // Without some nodes in the tree having empty base times.
24030 mode |= ProfileMode;
24031 }
24032
24033 return createFiber(HostRoot, null, null, mode);
24034 }
24035 function createFiberFromTypeAndProps(type, // React$ElementType
24036 key, pendingProps, owner, mode, expirationTime) {
24037 var fiber;
24038 var fiberTag = IndeterminateComponent; // The resolved type is set if we know what the final type will be. I.e. it's not lazy.
24039
24040 var resolvedType = type;
24041
24042 if (typeof type === 'function') {
24043 if (shouldConstruct(type)) {
24044 fiberTag = ClassComponent;
24045
24046 {
24047 resolvedType = resolveClassForHotReloading(resolvedType);
24048 }
24049 } else {
24050 {
24051 resolvedType = resolveFunctionForHotReloading(resolvedType);
24052 }
24053 }
24054 } else if (typeof type === 'string') {
24055 fiberTag = HostComponent;
24056 } else {
24057 getTag: switch (type) {
24058 case REACT_FRAGMENT_TYPE:
24059 return createFiberFromFragment(pendingProps.children, mode, expirationTime, key);
24060
24061 case REACT_CONCURRENT_MODE_TYPE:
24062 fiberTag = Mode;
24063 mode |= ConcurrentMode | BlockingMode | StrictMode;
24064 break;
24065
24066 case REACT_STRICT_MODE_TYPE:
24067 fiberTag = Mode;
24068 mode |= StrictMode;
24069 break;
24070
24071 case REACT_PROFILER_TYPE:
24072 return createFiberFromProfiler(pendingProps, mode, expirationTime, key);
24073
24074 case REACT_SUSPENSE_TYPE:
24075 return createFiberFromSuspense(pendingProps, mode, expirationTime, key);
24076
24077 case REACT_SUSPENSE_LIST_TYPE:
24078 return createFiberFromSuspenseList(pendingProps, mode, expirationTime, key);
24079
24080 default:
24081 {
24082 if (typeof type === 'object' && type !== null) {
24083 switch (type.$$typeof) {
24084 case REACT_PROVIDER_TYPE:
24085 fiberTag = ContextProvider;
24086 break getTag;
24087
24088 case REACT_CONTEXT_TYPE:
24089 // This is a consumer
24090 fiberTag = ContextConsumer;
24091 break getTag;
24092
24093 case REACT_FORWARD_REF_TYPE:
24094 fiberTag = ForwardRef;
24095
24096 {
24097 resolvedType = resolveForwardRefForHotReloading(resolvedType);
24098 }
24099
24100 break getTag;
24101
24102 case REACT_MEMO_TYPE:
24103 fiberTag = MemoComponent;
24104 break getTag;
24105
24106 case REACT_LAZY_TYPE:
24107 fiberTag = LazyComponent;
24108 resolvedType = null;
24109 break getTag;
24110
24111 case REACT_BLOCK_TYPE:
24112 fiberTag = Block;
24113 break getTag;
24114
24115 }
24116 }
24117
24118 var info = '';
24119
24120 {
24121 if (type === undefined || typeof type === 'object' && type !== null && Object.keys(type).length === 0) {
24122 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.';
24123 }
24124
24125 var ownerName = owner ? getComponentName(owner.type) : null;
24126
24127 if (ownerName) {
24128 info += '\n\nCheck the render method of `' + ownerName + '`.';
24129 }
24130 }
24131
24132 {
24133 {
24134 throw 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 );
24135 }
24136 }
24137 }
24138 }
24139 }
24140
24141 fiber = createFiber(fiberTag, pendingProps, key, mode);
24142 fiber.elementType = type;
24143 fiber.type = resolvedType;
24144 fiber.expirationTime = expirationTime;
24145 return fiber;
24146 }
24147 function createFiberFromElement(element, mode, expirationTime) {
24148 var owner = null;
24149
24150 {
24151 owner = element._owner;
24152 }
24153
24154 var type = element.type;
24155 var key = element.key;
24156 var pendingProps = element.props;
24157 var fiber = createFiberFromTypeAndProps(type, key, pendingProps, owner, mode, expirationTime);
24158
24159 {
24160 fiber._debugSource = element._source;
24161 fiber._debugOwner = element._owner;
24162 }
24163
24164 return fiber;
24165 }
24166 function createFiberFromFragment(elements, mode, expirationTime, key) {
24167 var fiber = createFiber(Fragment, elements, key, mode);
24168 fiber.expirationTime = expirationTime;
24169 return fiber;
24170 }
24171
24172 function createFiberFromProfiler(pendingProps, mode, expirationTime, key) {
24173 {
24174 if (typeof pendingProps.id !== 'string' || typeof pendingProps.onRender !== 'function') {
24175 error('Profiler must specify an "id" string and "onRender" function as props');
24176 }
24177 }
24178
24179 var fiber = createFiber(Profiler, pendingProps, key, mode | ProfileMode); // TODO: The Profiler fiber shouldn't have a type. It has a tag.
24180
24181 fiber.elementType = REACT_PROFILER_TYPE;
24182 fiber.type = REACT_PROFILER_TYPE;
24183 fiber.expirationTime = expirationTime;
24184 return fiber;
24185 }
24186
24187 function createFiberFromSuspense(pendingProps, mode, expirationTime, key) {
24188 var fiber = createFiber(SuspenseComponent, pendingProps, key, mode); // TODO: The SuspenseComponent fiber shouldn't have a type. It has a tag.
24189 // This needs to be fixed in getComponentName so that it relies on the tag
24190 // instead.
24191
24192 fiber.type = REACT_SUSPENSE_TYPE;
24193 fiber.elementType = REACT_SUSPENSE_TYPE;
24194 fiber.expirationTime = expirationTime;
24195 return fiber;
24196 }
24197 function createFiberFromSuspenseList(pendingProps, mode, expirationTime, key) {
24198 var fiber = createFiber(SuspenseListComponent, pendingProps, key, mode);
24199
24200 {
24201 // TODO: The SuspenseListComponent fiber shouldn't have a type. It has a tag.
24202 // This needs to be fixed in getComponentName so that it relies on the tag
24203 // instead.
24204 fiber.type = REACT_SUSPENSE_LIST_TYPE;
24205 }
24206
24207 fiber.elementType = REACT_SUSPENSE_LIST_TYPE;
24208 fiber.expirationTime = expirationTime;
24209 return fiber;
24210 }
24211 function createFiberFromText(content, mode, expirationTime) {
24212 var fiber = createFiber(HostText, content, null, mode);
24213 fiber.expirationTime = expirationTime;
24214 return fiber;
24215 }
24216 function createFiberFromHostInstanceForDeletion() {
24217 var fiber = createFiber(HostComponent, null, null, NoMode); // TODO: These should not need a type.
24218
24219 fiber.elementType = 'DELETED';
24220 fiber.type = 'DELETED';
24221 return fiber;
24222 }
24223 function createFiberFromPortal(portal, mode, expirationTime) {
24224 var pendingProps = portal.children !== null ? portal.children : [];
24225 var fiber = createFiber(HostPortal, pendingProps, portal.key, mode);
24226 fiber.expirationTime = expirationTime;
24227 fiber.stateNode = {
24228 containerInfo: portal.containerInfo,
24229 pendingChildren: null,
24230 // Used by persistent updates
24231 implementation: portal.implementation
24232 };
24233 return fiber;
24234 } // Used for stashing WIP properties to replay failed work in DEV.
24235
24236 function assignFiberPropertiesInDEV(target, source) {
24237 if (target === null) {
24238 // This Fiber's initial properties will always be overwritten.
24239 // We only use a Fiber to ensure the same hidden class so DEV isn't slow.
24240 target = createFiber(IndeterminateComponent, null, null, NoMode);
24241 } // This is intentionally written as a list of all properties.
24242 // We tried to use Object.assign() instead but this is called in
24243 // the hottest path, and Object.assign() was too slow:
24244 // https://github.com/facebook/react/issues/12502
24245 // This code is DEV-only so size is not a concern.
24246
24247
24248 target.tag = source.tag;
24249 target.key = source.key;
24250 target.elementType = source.elementType;
24251 target.type = source.type;
24252 target.stateNode = source.stateNode;
24253 target.return = source.return;
24254 target.child = source.child;
24255 target.sibling = source.sibling;
24256 target.index = source.index;
24257 target.ref = source.ref;
24258 target.pendingProps = source.pendingProps;
24259 target.memoizedProps = source.memoizedProps;
24260 target.updateQueue = source.updateQueue;
24261 target.memoizedState = source.memoizedState;
24262 target.dependencies = source.dependencies;
24263 target.mode = source.mode;
24264 target.effectTag = source.effectTag;
24265 target.nextEffect = source.nextEffect;
24266 target.firstEffect = source.firstEffect;
24267 target.lastEffect = source.lastEffect;
24268 target.expirationTime = source.expirationTime;
24269 target.childExpirationTime = source.childExpirationTime;
24270 target.alternate = source.alternate;
24271
24272 {
24273 target.actualDuration = source.actualDuration;
24274 target.actualStartTime = source.actualStartTime;
24275 target.selfBaseDuration = source.selfBaseDuration;
24276 target.treeBaseDuration = source.treeBaseDuration;
24277 }
24278
24279 {
24280 target._debugID = source._debugID;
24281 }
24282
24283 target._debugSource = source._debugSource;
24284 target._debugOwner = source._debugOwner;
24285 target._debugIsCurrentlyTiming = source._debugIsCurrentlyTiming;
24286 target._debugNeedsRemount = source._debugNeedsRemount;
24287 target._debugHookTypes = source._debugHookTypes;
24288 return target;
24289 }
24290
24291 function FiberRootNode(containerInfo, tag, hydrate) {
24292 this.tag = tag;
24293 this.current = null;
24294 this.containerInfo = containerInfo;
24295 this.pendingChildren = null;
24296 this.pingCache = null;
24297 this.finishedExpirationTime = NoWork;
24298 this.finishedWork = null;
24299 this.timeoutHandle = noTimeout;
24300 this.context = null;
24301 this.pendingContext = null;
24302 this.hydrate = hydrate;
24303 this.callbackNode = null;
24304 this.callbackPriority = NoPriority;
24305 this.firstPendingTime = NoWork;
24306 this.firstSuspendedTime = NoWork;
24307 this.lastSuspendedTime = NoWork;
24308 this.nextKnownPendingLevel = NoWork;
24309 this.lastPingedTime = NoWork;
24310 this.lastExpiredTime = NoWork;
24311
24312 {
24313 this.interactionThreadID = unstable_getThreadID();
24314 this.memoizedInteractions = new Set();
24315 this.pendingInteractionMap = new Map();
24316 }
24317 }
24318
24319 function createFiberRoot(containerInfo, tag, hydrate, hydrationCallbacks) {
24320 var root = new FiberRootNode(containerInfo, tag, hydrate);
24321 // stateNode is any.
24322
24323
24324 var uninitializedFiber = createHostRootFiber(tag);
24325 root.current = uninitializedFiber;
24326 uninitializedFiber.stateNode = root;
24327 initializeUpdateQueue(uninitializedFiber);
24328 return root;
24329 }
24330 function isRootSuspendedAtTime(root, expirationTime) {
24331 var firstSuspendedTime = root.firstSuspendedTime;
24332 var lastSuspendedTime = root.lastSuspendedTime;
24333 return firstSuspendedTime !== NoWork && firstSuspendedTime >= expirationTime && lastSuspendedTime <= expirationTime;
24334 }
24335 function markRootSuspendedAtTime(root, expirationTime) {
24336 var firstSuspendedTime = root.firstSuspendedTime;
24337 var lastSuspendedTime = root.lastSuspendedTime;
24338
24339 if (firstSuspendedTime < expirationTime) {
24340 root.firstSuspendedTime = expirationTime;
24341 }
24342
24343 if (lastSuspendedTime > expirationTime || firstSuspendedTime === NoWork) {
24344 root.lastSuspendedTime = expirationTime;
24345 }
24346
24347 if (expirationTime <= root.lastPingedTime) {
24348 root.lastPingedTime = NoWork;
24349 }
24350
24351 if (expirationTime <= root.lastExpiredTime) {
24352 root.lastExpiredTime = NoWork;
24353 }
24354 }
24355 function markRootUpdatedAtTime(root, expirationTime) {
24356 // Update the range of pending times
24357 var firstPendingTime = root.firstPendingTime;
24358
24359 if (expirationTime > firstPendingTime) {
24360 root.firstPendingTime = expirationTime;
24361 } // Update the range of suspended times. Treat everything lower priority or
24362 // equal to this update as unsuspended.
24363
24364
24365 var firstSuspendedTime = root.firstSuspendedTime;
24366
24367 if (firstSuspendedTime !== NoWork) {
24368 if (expirationTime >= firstSuspendedTime) {
24369 // The entire suspended range is now unsuspended.
24370 root.firstSuspendedTime = root.lastSuspendedTime = root.nextKnownPendingLevel = NoWork;
24371 } else if (expirationTime >= root.lastSuspendedTime) {
24372 root.lastSuspendedTime = expirationTime + 1;
24373 } // This is a pending level. Check if it's higher priority than the next
24374 // known pending level.
24375
24376
24377 if (expirationTime > root.nextKnownPendingLevel) {
24378 root.nextKnownPendingLevel = expirationTime;
24379 }
24380 }
24381 }
24382 function markRootFinishedAtTime(root, finishedExpirationTime, remainingExpirationTime) {
24383 // Update the range of pending times
24384 root.firstPendingTime = remainingExpirationTime; // Update the range of suspended times. Treat everything higher priority or
24385 // equal to this update as unsuspended.
24386
24387 if (finishedExpirationTime <= root.lastSuspendedTime) {
24388 // The entire suspended range is now unsuspended.
24389 root.firstSuspendedTime = root.lastSuspendedTime = root.nextKnownPendingLevel = NoWork;
24390 } else if (finishedExpirationTime <= root.firstSuspendedTime) {
24391 // Part of the suspended range is now unsuspended. Narrow the range to
24392 // include everything between the unsuspended time (non-inclusive) and the
24393 // last suspended time.
24394 root.firstSuspendedTime = finishedExpirationTime - 1;
24395 }
24396
24397 if (finishedExpirationTime <= root.lastPingedTime) {
24398 // Clear the pinged time
24399 root.lastPingedTime = NoWork;
24400 }
24401
24402 if (finishedExpirationTime <= root.lastExpiredTime) {
24403 // Clear the expired time
24404 root.lastExpiredTime = NoWork;
24405 }
24406 }
24407 function markRootExpiredAtTime(root, expirationTime) {
24408 var lastExpiredTime = root.lastExpiredTime;
24409
24410 if (lastExpiredTime === NoWork || lastExpiredTime > expirationTime) {
24411 root.lastExpiredTime = expirationTime;
24412 }
24413 }
24414
24415 var didWarnAboutNestedUpdates;
24416 var didWarnAboutFindNodeInStrictMode;
24417
24418 {
24419 didWarnAboutNestedUpdates = false;
24420 didWarnAboutFindNodeInStrictMode = {};
24421 }
24422
24423 function getContextForSubtree(parentComponent) {
24424 if (!parentComponent) {
24425 return emptyContextObject;
24426 }
24427
24428 var fiber = get(parentComponent);
24429 var parentContext = findCurrentUnmaskedContext(fiber);
24430
24431 if (fiber.tag === ClassComponent) {
24432 var Component = fiber.type;
24433
24434 if (isContextProvider(Component)) {
24435 return processChildContext(fiber, Component, parentContext);
24436 }
24437 }
24438
24439 return parentContext;
24440 }
24441
24442 function findHostInstanceWithWarning(component, methodName) {
24443 {
24444 var fiber = get(component);
24445
24446 if (fiber === undefined) {
24447 if (typeof component.render === 'function') {
24448 {
24449 {
24450 throw Error( "Unable to find node on an unmounted component." );
24451 }
24452 }
24453 } else {
24454 {
24455 {
24456 throw Error( "Argument appears to not be a ReactComponent. Keys: " + Object.keys(component) );
24457 }
24458 }
24459 }
24460 }
24461
24462 var hostFiber = findCurrentHostFiber(fiber);
24463
24464 if (hostFiber === null) {
24465 return null;
24466 }
24467
24468 if (hostFiber.mode & StrictMode) {
24469 var componentName = getComponentName(fiber.type) || 'Component';
24470
24471 if (!didWarnAboutFindNodeInStrictMode[componentName]) {
24472 didWarnAboutFindNodeInStrictMode[componentName] = true;
24473
24474 if (fiber.mode & StrictMode) {
24475 error('%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. ' + 'Learn more about using refs safely here: ' + 'https://fb.me/react-strict-mode-find-node%s', methodName, methodName, componentName, getStackByFiberInDevAndProd(hostFiber));
24476 } else {
24477 error('%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. ' + 'Learn more about using refs safely here: ' + 'https://fb.me/react-strict-mode-find-node%s', methodName, methodName, componentName, getStackByFiberInDevAndProd(hostFiber));
24478 }
24479 }
24480 }
24481
24482 return hostFiber.stateNode;
24483 }
24484 }
24485
24486 function createContainer(containerInfo, tag, hydrate, hydrationCallbacks) {
24487 return createFiberRoot(containerInfo, tag, hydrate);
24488 }
24489 function updateContainer(element, container, parentComponent, callback) {
24490 {
24491 onScheduleRoot(container, element);
24492 }
24493
24494 var current$1 = container.current;
24495 var currentTime = requestCurrentTimeForUpdate();
24496
24497 {
24498 // $FlowExpectedError - jest isn't a global, and isn't recognized outside of tests
24499 if ('undefined' !== typeof jest) {
24500 warnIfUnmockedScheduler(current$1);
24501 warnIfNotScopedWithMatchingAct(current$1);
24502 }
24503 }
24504
24505 var suspenseConfig = requestCurrentSuspenseConfig();
24506 var expirationTime = computeExpirationForFiber(currentTime, current$1, suspenseConfig);
24507 var context = getContextForSubtree(parentComponent);
24508
24509 if (container.context === null) {
24510 container.context = context;
24511 } else {
24512 container.pendingContext = context;
24513 }
24514
24515 {
24516 if (phase === 'render' && current !== null && !didWarnAboutNestedUpdates) {
24517 didWarnAboutNestedUpdates = true;
24518
24519 error('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');
24520 }
24521 }
24522
24523 var update = createUpdate(expirationTime, suspenseConfig); // Caution: React DevTools currently depends on this property
24524 // being called "element".
24525
24526 update.payload = {
24527 element: element
24528 };
24529 callback = callback === undefined ? null : callback;
24530
24531 if (callback !== null) {
24532 {
24533 if (typeof callback !== 'function') {
24534 error('render(...): Expected the last optional `callback` argument to be a ' + 'function. Instead received: %s.', callback);
24535 }
24536 }
24537
24538 update.callback = callback;
24539 }
24540
24541 enqueueUpdate(current$1, update);
24542 scheduleWork(current$1, expirationTime);
24543 return expirationTime;
24544 }
24545 function getPublicRootInstance(container) {
24546 var containerFiber = container.current;
24547
24548 if (!containerFiber.child) {
24549 return null;
24550 }
24551
24552 switch (containerFiber.child.tag) {
24553 case HostComponent:
24554 return getPublicInstance(containerFiber.child.stateNode);
24555
24556 default:
24557 return containerFiber.child.stateNode;
24558 }
24559 }
24560
24561 function markRetryTimeImpl(fiber, retryTime) {
24562 var suspenseState = fiber.memoizedState;
24563
24564 if (suspenseState !== null && suspenseState.dehydrated !== null) {
24565 if (suspenseState.retryTime < retryTime) {
24566 suspenseState.retryTime = retryTime;
24567 }
24568 }
24569 } // Increases the priority of thennables when they resolve within this boundary.
24570
24571
24572 function markRetryTimeIfNotHydrated(fiber, retryTime) {
24573 markRetryTimeImpl(fiber, retryTime);
24574 var alternate = fiber.alternate;
24575
24576 if (alternate) {
24577 markRetryTimeImpl(alternate, retryTime);
24578 }
24579 }
24580
24581 function attemptUserBlockingHydration$1(fiber) {
24582 if (fiber.tag !== SuspenseComponent) {
24583 // We ignore HostRoots here because we can't increase
24584 // their priority and they should not suspend on I/O,
24585 // since you have to wrap anything that might suspend in
24586 // Suspense.
24587 return;
24588 }
24589
24590 var expTime = computeInteractiveExpiration(requestCurrentTimeForUpdate());
24591 scheduleWork(fiber, expTime);
24592 markRetryTimeIfNotHydrated(fiber, expTime);
24593 }
24594 function attemptContinuousHydration$1(fiber) {
24595 if (fiber.tag !== SuspenseComponent) {
24596 // We ignore HostRoots here because we can't increase
24597 // their priority and they should not suspend on I/O,
24598 // since you have to wrap anything that might suspend in
24599 // Suspense.
24600 return;
24601 }
24602
24603 scheduleWork(fiber, ContinuousHydration);
24604 markRetryTimeIfNotHydrated(fiber, ContinuousHydration);
24605 }
24606 function attemptHydrationAtCurrentPriority$1(fiber) {
24607 if (fiber.tag !== SuspenseComponent) {
24608 // We ignore HostRoots here because we can't increase
24609 // their priority other than synchronously flush it.
24610 return;
24611 }
24612
24613 var currentTime = requestCurrentTimeForUpdate();
24614 var expTime = computeExpirationForFiber(currentTime, fiber, null);
24615 scheduleWork(fiber, expTime);
24616 markRetryTimeIfNotHydrated(fiber, expTime);
24617 }
24618 function findHostInstanceWithNoPortals(fiber) {
24619 var hostFiber = findCurrentHostFiberWithNoPortals(fiber);
24620
24621 if (hostFiber === null) {
24622 return null;
24623 }
24624
24625 if (hostFiber.tag === FundamentalComponent) {
24626 return hostFiber.stateNode.instance;
24627 }
24628
24629 return hostFiber.stateNode;
24630 }
24631
24632 var shouldSuspendImpl = function (fiber) {
24633 return false;
24634 };
24635
24636 function shouldSuspend(fiber) {
24637 return shouldSuspendImpl(fiber);
24638 }
24639 var overrideHookState = null;
24640 var overrideProps = null;
24641 var scheduleUpdate = null;
24642 var setSuspenseHandler = null;
24643
24644 {
24645 var copyWithSetImpl = function (obj, path, idx, value) {
24646 if (idx >= path.length) {
24647 return value;
24648 }
24649
24650 var key = path[idx];
24651 var updated = Array.isArray(obj) ? obj.slice() : _assign({}, obj); // $FlowFixMe number or string is fine here
24652
24653 updated[key] = copyWithSetImpl(obj[key], path, idx + 1, value);
24654 return updated;
24655 };
24656
24657 var copyWithSet = function (obj, path, value) {
24658 return copyWithSetImpl(obj, path, 0, value);
24659 }; // Support DevTools editable values for useState and useReducer.
24660
24661
24662 overrideHookState = function (fiber, id, path, value) {
24663 // For now, the "id" of stateful hooks is just the stateful hook index.
24664 // This may change in the future with e.g. nested hooks.
24665 var currentHook = fiber.memoizedState;
24666
24667 while (currentHook !== null && id > 0) {
24668 currentHook = currentHook.next;
24669 id--;
24670 }
24671
24672 if (currentHook !== null) {
24673 var newState = copyWithSet(currentHook.memoizedState, path, value);
24674 currentHook.memoizedState = newState;
24675 currentHook.baseState = newState; // We aren't actually adding an update to the queue,
24676 // because there is no update we can add for useReducer hooks that won't trigger an error.
24677 // (There's no appropriate action type for DevTools overrides.)
24678 // As a result though, React will see the scheduled update as a noop and bailout.
24679 // Shallow cloning props works as a workaround for now to bypass the bailout check.
24680
24681 fiber.memoizedProps = _assign({}, fiber.memoizedProps);
24682 scheduleWork(fiber, Sync);
24683 }
24684 }; // Support DevTools props for function components, forwardRef, memo, host components, etc.
24685
24686
24687 overrideProps = function (fiber, path, value) {
24688 fiber.pendingProps = copyWithSet(fiber.memoizedProps, path, value);
24689
24690 if (fiber.alternate) {
24691 fiber.alternate.pendingProps = fiber.pendingProps;
24692 }
24693
24694 scheduleWork(fiber, Sync);
24695 };
24696
24697 scheduleUpdate = function (fiber) {
24698 scheduleWork(fiber, Sync);
24699 };
24700
24701 setSuspenseHandler = function (newShouldSuspendImpl) {
24702 shouldSuspendImpl = newShouldSuspendImpl;
24703 };
24704 }
24705
24706 function injectIntoDevTools(devToolsConfig) {
24707 var findFiberByHostInstance = devToolsConfig.findFiberByHostInstance;
24708 var ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher;
24709 return injectInternals(_assign({}, devToolsConfig, {
24710 overrideHookState: overrideHookState,
24711 overrideProps: overrideProps,
24712 setSuspenseHandler: setSuspenseHandler,
24713 scheduleUpdate: scheduleUpdate,
24714 currentDispatcherRef: ReactCurrentDispatcher,
24715 findHostInstanceByFiber: function (fiber) {
24716 var hostFiber = findCurrentHostFiber(fiber);
24717
24718 if (hostFiber === null) {
24719 return null;
24720 }
24721
24722 return hostFiber.stateNode;
24723 },
24724 findFiberByHostInstance: function (instance) {
24725 if (!findFiberByHostInstance) {
24726 // Might not be implemented by the renderer.
24727 return null;
24728 }
24729
24730 return findFiberByHostInstance(instance);
24731 },
24732 // React Refresh
24733 findHostInstancesForRefresh: findHostInstancesForRefresh ,
24734 scheduleRefresh: scheduleRefresh ,
24735 scheduleRoot: scheduleRoot ,
24736 setRefreshHandler: setRefreshHandler ,
24737 // Enables DevTools to append owner stacks to error messages in DEV mode.
24738 getCurrentFiber: function () {
24739 return current;
24740 }
24741 }));
24742 }
24743 var IsSomeRendererActing$1 = ReactSharedInternals.IsSomeRendererActing;
24744
24745 function ReactDOMRoot(container, options) {
24746 this._internalRoot = createRootImpl(container, ConcurrentRoot, options);
24747 }
24748
24749 function ReactDOMBlockingRoot(container, tag, options) {
24750 this._internalRoot = createRootImpl(container, tag, options);
24751 }
24752
24753 ReactDOMRoot.prototype.render = ReactDOMBlockingRoot.prototype.render = function (children) {
24754 var root = this._internalRoot;
24755
24756 {
24757 if (typeof arguments[1] === 'function') {
24758 error('render(...): does not support the second callback argument. ' + 'To execute a side effect after rendering, declare it in a component body with useEffect().');
24759 }
24760
24761 var container = root.containerInfo;
24762
24763 if (container.nodeType !== COMMENT_NODE) {
24764 var hostInstance = findHostInstanceWithNoPortals(root.current);
24765
24766 if (hostInstance) {
24767 if (hostInstance.parentNode !== container) {
24768 error('render(...): It looks like the React-rendered content of the ' + 'root container was removed without using React. This is not ' + 'supported and will cause errors. Instead, call ' + "root.unmount() to empty a root's container.");
24769 }
24770 }
24771 }
24772 }
24773
24774 updateContainer(children, root, null, null);
24775 };
24776
24777 ReactDOMRoot.prototype.unmount = ReactDOMBlockingRoot.prototype.unmount = function () {
24778 {
24779 if (typeof arguments[0] === 'function') {
24780 error('unmount(...): does not support a callback argument. ' + 'To execute a side effect after rendering, declare it in a component body with useEffect().');
24781 }
24782 }
24783
24784 var root = this._internalRoot;
24785 var container = root.containerInfo;
24786 updateContainer(null, root, null, function () {
24787 unmarkContainerAsRoot(container);
24788 });
24789 };
24790
24791 function createRootImpl(container, tag, options) {
24792 // Tag is either LegacyRoot or Concurrent Root
24793 var hydrate = options != null && options.hydrate === true;
24794 var hydrationCallbacks = options != null && options.hydrationOptions || null;
24795 var root = createContainer(container, tag, hydrate);
24796 markContainerAsRoot(root.current, container);
24797
24798 if (hydrate && tag !== LegacyRoot) {
24799 var doc = container.nodeType === DOCUMENT_NODE ? container : container.ownerDocument;
24800 eagerlyTrapReplayableEvents(container, doc);
24801 }
24802
24803 return root;
24804 }
24805 function createLegacyRoot(container, options) {
24806 return new ReactDOMBlockingRoot(container, LegacyRoot, options);
24807 }
24808 function isValidContainer(node) {
24809 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 '));
24810 }
24811
24812 var ReactCurrentOwner$3 = ReactSharedInternals.ReactCurrentOwner;
24813 var topLevelUpdateWarnings;
24814 var warnedAboutHydrateAPI = false;
24815
24816 {
24817 topLevelUpdateWarnings = function (container) {
24818 if (container._reactRootContainer && container.nodeType !== COMMENT_NODE) {
24819 var hostInstance = findHostInstanceWithNoPortals(container._reactRootContainer._internalRoot.current);
24820
24821 if (hostInstance) {
24822 if (hostInstance.parentNode !== container) {
24823 error('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.');
24824 }
24825 }
24826 }
24827
24828 var isRootRenderedBySomeReact = !!container._reactRootContainer;
24829 var rootEl = getReactRootElementInContainer(container);
24830 var hasNonRootReactChild = !!(rootEl && getInstanceFromNode$1(rootEl));
24831
24832 if (hasNonRootReactChild && !isRootRenderedBySomeReact) {
24833 error('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.');
24834 }
24835
24836 if (container.nodeType === ELEMENT_NODE && container.tagName && container.tagName.toUpperCase() === 'BODY') {
24837 error('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.');
24838 }
24839 };
24840 }
24841
24842 function getReactRootElementInContainer(container) {
24843 if (!container) {
24844 return null;
24845 }
24846
24847 if (container.nodeType === DOCUMENT_NODE) {
24848 return container.documentElement;
24849 } else {
24850 return container.firstChild;
24851 }
24852 }
24853
24854 function shouldHydrateDueToLegacyHeuristic(container) {
24855 var rootElement = getReactRootElementInContainer(container);
24856 return !!(rootElement && rootElement.nodeType === ELEMENT_NODE && rootElement.hasAttribute(ROOT_ATTRIBUTE_NAME));
24857 }
24858
24859 function legacyCreateRootFromDOMContainer(container, forceHydrate) {
24860 var shouldHydrate = forceHydrate || shouldHydrateDueToLegacyHeuristic(container); // First clear any existing content.
24861
24862 if (!shouldHydrate) {
24863 var warned = false;
24864 var rootSibling;
24865
24866 while (rootSibling = container.lastChild) {
24867 {
24868 if (!warned && rootSibling.nodeType === ELEMENT_NODE && rootSibling.hasAttribute(ROOT_ATTRIBUTE_NAME)) {
24869 warned = true;
24870
24871 error('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.');
24872 }
24873 }
24874
24875 container.removeChild(rootSibling);
24876 }
24877 }
24878
24879 {
24880 if (shouldHydrate && !forceHydrate && !warnedAboutHydrateAPI) {
24881 warnedAboutHydrateAPI = true;
24882
24883 warn('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.');
24884 }
24885 }
24886
24887 return createLegacyRoot(container, shouldHydrate ? {
24888 hydrate: true
24889 } : undefined);
24890 }
24891
24892 function warnOnInvalidCallback$1(callback, callerName) {
24893 {
24894 if (callback !== null && typeof callback !== 'function') {
24895 error('%s(...): Expected the last optional `callback` argument to be a ' + 'function. Instead received: %s.', callerName, callback);
24896 }
24897 }
24898 }
24899
24900 function legacyRenderSubtreeIntoContainer(parentComponent, children, container, forceHydrate, callback) {
24901 {
24902 topLevelUpdateWarnings(container);
24903 warnOnInvalidCallback$1(callback === undefined ? null : callback, 'render');
24904 } // TODO: Without `any` type, Flow says "Property cannot be accessed on any
24905 // member of intersection type." Whyyyyyy.
24906
24907
24908 var root = container._reactRootContainer;
24909 var fiberRoot;
24910
24911 if (!root) {
24912 // Initial mount
24913 root = container._reactRootContainer = legacyCreateRootFromDOMContainer(container, forceHydrate);
24914 fiberRoot = root._internalRoot;
24915
24916 if (typeof callback === 'function') {
24917 var originalCallback = callback;
24918
24919 callback = function () {
24920 var instance = getPublicRootInstance(fiberRoot);
24921 originalCallback.call(instance);
24922 };
24923 } // Initial mount should not be batched.
24924
24925
24926 unbatchedUpdates(function () {
24927 updateContainer(children, fiberRoot, parentComponent, callback);
24928 });
24929 } else {
24930 fiberRoot = root._internalRoot;
24931
24932 if (typeof callback === 'function') {
24933 var _originalCallback = callback;
24934
24935 callback = function () {
24936 var instance = getPublicRootInstance(fiberRoot);
24937
24938 _originalCallback.call(instance);
24939 };
24940 } // Update
24941
24942
24943 updateContainer(children, fiberRoot, parentComponent, callback);
24944 }
24945
24946 return getPublicRootInstance(fiberRoot);
24947 }
24948
24949 function findDOMNode(componentOrElement) {
24950 {
24951 var owner = ReactCurrentOwner$3.current;
24952
24953 if (owner !== null && owner.stateNode !== null) {
24954 var warnedAboutRefsInRender = owner.stateNode._warnedAboutRefsInRender;
24955
24956 if (!warnedAboutRefsInRender) {
24957 error('%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');
24958 }
24959
24960 owner.stateNode._warnedAboutRefsInRender = true;
24961 }
24962 }
24963
24964 if (componentOrElement == null) {
24965 return null;
24966 }
24967
24968 if (componentOrElement.nodeType === ELEMENT_NODE) {
24969 return componentOrElement;
24970 }
24971
24972 {
24973 return findHostInstanceWithWarning(componentOrElement, 'findDOMNode');
24974 }
24975 }
24976 function hydrate(element, container, callback) {
24977 if (!isValidContainer(container)) {
24978 {
24979 throw Error( "Target container is not a DOM element." );
24980 }
24981 }
24982
24983 {
24984 var isModernRoot = isContainerMarkedAsRoot(container) && container._reactRootContainer === undefined;
24985
24986 if (isModernRoot) {
24987 error('You are calling ReactDOM.hydrate() on a container that was previously ' + 'passed to ReactDOM.createRoot(). This is not supported. ' + 'Did you mean to call createRoot(container, {hydrate: true}).render(element)?');
24988 }
24989 } // TODO: throw or warn if we couldn't hydrate?
24990
24991
24992 return legacyRenderSubtreeIntoContainer(null, element, container, true, callback);
24993 }
24994 function render(element, container, callback) {
24995 if (!isValidContainer(container)) {
24996 {
24997 throw Error( "Target container is not a DOM element." );
24998 }
24999 }
25000
25001 {
25002 var isModernRoot = isContainerMarkedAsRoot(container) && container._reactRootContainer === undefined;
25003
25004 if (isModernRoot) {
25005 error('You are calling ReactDOM.render() on a container that was previously ' + 'passed to ReactDOM.createRoot(). This is not supported. ' + 'Did you mean to call root.render(element)?');
25006 }
25007 }
25008
25009 return legacyRenderSubtreeIntoContainer(null, element, container, false, callback);
25010 }
25011 function unstable_renderSubtreeIntoContainer(parentComponent, element, containerNode, callback) {
25012 if (!isValidContainer(containerNode)) {
25013 {
25014 throw Error( "Target container is not a DOM element." );
25015 }
25016 }
25017
25018 if (!(parentComponent != null && has$1(parentComponent))) {
25019 {
25020 throw Error( "parentComponent must be a valid React Component" );
25021 }
25022 }
25023
25024 return legacyRenderSubtreeIntoContainer(parentComponent, element, containerNode, false, callback);
25025 }
25026 function unmountComponentAtNode(container) {
25027 if (!isValidContainer(container)) {
25028 {
25029 throw Error( "unmountComponentAtNode(...): Target container is not a DOM element." );
25030 }
25031 }
25032
25033 {
25034 var isModernRoot = isContainerMarkedAsRoot(container) && container._reactRootContainer === undefined;
25035
25036 if (isModernRoot) {
25037 error('You are calling ReactDOM.unmountComponentAtNode() on a container that was previously ' + 'passed to ReactDOM.createRoot(). This is not supported. Did you mean to call root.unmount()?');
25038 }
25039 }
25040
25041 if (container._reactRootContainer) {
25042 {
25043 var rootEl = getReactRootElementInContainer(container);
25044 var renderedByDifferentReact = rootEl && !getInstanceFromNode$1(rootEl);
25045
25046 if (renderedByDifferentReact) {
25047 error("unmountComponentAtNode(): The node you're attempting to unmount " + 'was rendered by another copy of React.');
25048 }
25049 } // Unmount should not be batched.
25050
25051
25052 unbatchedUpdates(function () {
25053 legacyRenderSubtreeIntoContainer(null, null, container, false, function () {
25054 // $FlowFixMe This should probably use `delete container._reactRootContainer`
25055 container._reactRootContainer = null;
25056 unmarkContainerAsRoot(container);
25057 });
25058 }); // If you call unmountComponentAtNode twice in quick succession, you'll
25059 // get `true` twice. That's probably fine?
25060
25061 return true;
25062 } else {
25063 {
25064 var _rootEl = getReactRootElementInContainer(container);
25065
25066 var hasNonRootReactChild = !!(_rootEl && getInstanceFromNode$1(_rootEl)); // Check if the container itself is a React root node.
25067
25068 var isContainerReactRoot = container.nodeType === ELEMENT_NODE && isValidContainer(container.parentNode) && !!container.parentNode._reactRootContainer;
25069
25070 if (hasNonRootReactChild) {
25071 error("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.');
25072 }
25073 }
25074
25075 return false;
25076 }
25077 }
25078
25079 function createPortal(children, containerInfo, // TODO: figure out the API for cross-renderer implementation.
25080 implementation) {
25081 var key = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null;
25082 return {
25083 // This tag allow us to uniquely identify this as a React Portal
25084 $$typeof: REACT_PORTAL_TYPE,
25085 key: key == null ? null : '' + key,
25086 children: children,
25087 containerInfo: containerInfo,
25088 implementation: implementation
25089 };
25090 }
25091
25092 var ReactVersion = '16.13.0';
25093
25094 setAttemptUserBlockingHydration(attemptUserBlockingHydration$1);
25095 setAttemptContinuousHydration(attemptContinuousHydration$1);
25096 setAttemptHydrationAtCurrentPriority(attemptHydrationAtCurrentPriority$1);
25097 var didWarnAboutUnstableCreatePortal = false;
25098
25099 {
25100 if (typeof Map !== 'function' || // $FlowIssue Flow incorrectly thinks Map has no prototype
25101 Map.prototype == null || typeof Map.prototype.forEach !== 'function' || typeof Set !== 'function' || // $FlowIssue Flow incorrectly thinks Set has no prototype
25102 Set.prototype == null || typeof Set.prototype.clear !== 'function' || typeof Set.prototype.forEach !== 'function') {
25103 error('React depends on Map and Set built-in types. Make sure that you load a ' + 'polyfill in older browsers. https://fb.me/react-polyfills');
25104 }
25105 }
25106
25107 setRestoreImplementation(restoreControlledState$3);
25108 setBatchingImplementation(batchedUpdates$1, discreteUpdates$1, flushDiscreteUpdates, batchedEventUpdates$1);
25109
25110 function createPortal$1(children, container) {
25111 var key = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
25112
25113 if (!isValidContainer(container)) {
25114 {
25115 throw Error( "Target container is not a DOM element." );
25116 }
25117 } // TODO: pass ReactDOM portal implementation as third argument
25118 // $FlowFixMe The Flow type is opaque but there's no way to actually create it.
25119
25120
25121 return createPortal(children, container, null, key);
25122 }
25123
25124 function renderSubtreeIntoContainer(parentComponent, element, containerNode, callback) {
25125
25126 return unstable_renderSubtreeIntoContainer(parentComponent, element, containerNode, callback);
25127 }
25128
25129 function unstable_createPortal(children, container) {
25130 var key = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
25131
25132 {
25133 if (!didWarnAboutUnstableCreatePortal) {
25134 didWarnAboutUnstableCreatePortal = true;
25135
25136 warn('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.');
25137 }
25138 }
25139
25140 return createPortal$1(children, container, key);
25141 }
25142
25143 var Internals = {
25144 // Keep in sync with ReactDOMUnstableNativeDependencies.js
25145 // ReactTestUtils.js, and ReactTestUtilsAct.js. This is an array for better minification.
25146 Events: [getInstanceFromNode$1, getNodeFromInstance$1, getFiberCurrentPropsFromNode$1, injectEventPluginsByName, eventNameDispatchConfigs, accumulateTwoPhaseDispatches, accumulateDirectDispatches, enqueueStateRestore, restoreStateIfNeeded, dispatchEvent, runEventsInBatch, flushPassiveEffects, IsThisRendererActing]
25147 };
25148 var foundDevTools = injectIntoDevTools({
25149 findFiberByHostInstance: getClosestInstanceFromNode,
25150 bundleType: 1 ,
25151 version: ReactVersion,
25152 rendererPackageName: 'react-dom'
25153 });
25154
25155 {
25156 if (!foundDevTools && canUseDOM && window.top === window.self) {
25157 // If we're in Chrome or Firefox, provide a download link if not installed.
25158 if (navigator.userAgent.indexOf('Chrome') > -1 && navigator.userAgent.indexOf('Edge') === -1 || navigator.userAgent.indexOf('Firefox') > -1) {
25159 var protocol = window.location.protocol; // Don't warn in exotic cases like chrome-extension://.
25160
25161 if (/^(https?|file):$/.test(protocol)) {
25162 // eslint-disable-next-line react-internal/no-production-logging
25163 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');
25164 }
25165 }
25166 }
25167 }
25168
25169 exports.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED = Internals;
25170 exports.createPortal = createPortal$1;
25171 exports.findDOMNode = findDOMNode;
25172 exports.flushSync = flushSync;
25173 exports.hydrate = hydrate;
25174 exports.render = render;
25175 exports.unmountComponentAtNode = unmountComponentAtNode;
25176 exports.unstable_batchedUpdates = batchedUpdates$1;
25177 exports.unstable_createPortal = unstable_createPortal;
25178 exports.unstable_renderSubtreeIntoContainer = renderSubtreeIntoContainer;
25179 exports.version = ReactVersion;
25180
25181})));