UNPKG

531 kBJavaScriptView Raw
1/** @license React v16.13.1
2 * react-art.development.js
3 *
4 * Copyright (c) Facebook, Inc. and its affiliates.
5 *
6 * This source code is licensed under the MIT license found in the
7 * LICENSE file in the root directory of this source tree.
8 */
9
10'use strict';
11
12
13
14if (process.env.NODE_ENV !== "production") {
15 (function() {
16'use strict';
17
18var React = require('react');
19var _assign = require('object-assign');
20var Transform = require('art/core/transform');
21var Mode$1 = require('art/modes/current');
22var checkPropTypes = require('prop-types/checkPropTypes');
23var Scheduler = require('scheduler');
24var tracing = require('scheduler/tracing');
25var FastNoSideEffects = require('art/modes/fast-noSideEffects');
26
27function _extends() {
28 _extends = Object.assign || function (target) {
29 for (var i = 1; i < arguments.length; i++) {
30 var source = arguments[i];
31
32 for (var key in source) {
33 if (Object.prototype.hasOwnProperty.call(source, key)) {
34 target[key] = source[key];
35 }
36 }
37 }
38
39 return target;
40 };
41
42 return _extends.apply(this, arguments);
43}
44
45function _inheritsLoose(subClass, superClass) {
46 subClass.prototype = Object.create(superClass.prototype);
47 subClass.prototype.constructor = subClass;
48 subClass.__proto__ = superClass;
49}
50
51function _assertThisInitialized(self) {
52 if (self === void 0) {
53 throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
54 }
55
56 return self;
57}
58
59var ReactVersion = '16.13.1';
60
61var LegacyRoot = 0;
62var BlockingRoot = 1;
63var ConcurrentRoot = 2;
64
65var ReactSharedInternals = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED; // Prevent newer renderers from RTE when used with older react package versions.
66// Current owner and dispatcher used to share the same ref,
67// but PR #14548 split them out to better support the react-debug-tools package.
68
69if (!ReactSharedInternals.hasOwnProperty('ReactCurrentDispatcher')) {
70 ReactSharedInternals.ReactCurrentDispatcher = {
71 current: null
72 };
73}
74
75if (!ReactSharedInternals.hasOwnProperty('ReactCurrentBatchConfig')) {
76 ReactSharedInternals.ReactCurrentBatchConfig = {
77 suspense: null
78 };
79}
80
81// by calls to these methods by a Babel plugin.
82//
83// In PROD (or in packages without access to React internals),
84// they are left as they are instead.
85
86function warn(format) {
87 {
88 for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
89 args[_key - 1] = arguments[_key];
90 }
91
92 printWarning('warn', format, args);
93 }
94}
95function error(format) {
96 {
97 for (var _len2 = arguments.length, args = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {
98 args[_key2 - 1] = arguments[_key2];
99 }
100
101 printWarning('error', format, args);
102 }
103}
104
105function printWarning(level, format, args) {
106 // When changing this logic, you might want to also
107 // update consoleWithStackDev.www.js as well.
108 {
109 var hasExistingStack = args.length > 0 && typeof args[args.length - 1] === 'string' && args[args.length - 1].indexOf('\n in') === 0;
110
111 if (!hasExistingStack) {
112 var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame;
113 var stack = ReactDebugCurrentFrame.getStackAddendum();
114
115 if (stack !== '') {
116 format += '%s';
117 args = args.concat([stack]);
118 }
119 }
120
121 var argsWithFormat = args.map(function (item) {
122 return '' + item;
123 }); // Careful: RN currently depends on this prefix
124
125 argsWithFormat.unshift('Warning: ' + format); // We intentionally don't use spread (or .apply) directly because it
126 // breaks IE9: https://github.com/facebook/react/issues/13610
127 // eslint-disable-next-line react-internal/no-production-logging
128
129 Function.prototype.apply.call(console[level], console, argsWithFormat);
130
131 try {
132 // --- Welcome to debugging React ---
133 // This error was thrown as a convenience so that you can use this stack
134 // to find the callsite that caused this warning to fire.
135 var argIndex = 0;
136 var message = 'Warning: ' + format.replace(/%s/g, function () {
137 return args[argIndex++];
138 });
139 throw new Error(message);
140 } catch (x) {}
141 }
142}
143
144var FunctionComponent = 0;
145var ClassComponent = 1;
146var IndeterminateComponent = 2; // Before we know whether it is function or class
147
148var HostRoot = 3; // Root of a host tree. Could be nested inside another node.
149
150var HostPortal = 4; // A subtree. Could be an entry point to a different renderer.
151
152var HostComponent = 5;
153var HostText = 6;
154var Fragment = 7;
155var Mode = 8;
156var ContextConsumer = 9;
157var ContextProvider = 10;
158var ForwardRef = 11;
159var Profiler = 12;
160var SuspenseComponent = 13;
161var MemoComponent = 14;
162var SimpleMemoComponent = 15;
163var LazyComponent = 16;
164var IncompleteClassComponent = 17;
165var DehydratedFragment = 18;
166var SuspenseListComponent = 19;
167var FundamentalComponent = 20;
168var ScopeComponent = 21;
169var Block = 22;
170
171/**
172 * `ReactInstanceMap` maintains a mapping from a public facing stateful
173 * instance (key) and the internal representation (value). This allows public
174 * methods to accept the user facing instance as an argument and map them back
175 * to internal methods.
176 *
177 * Note that this module is currently shared and assumed to be stateless.
178 * If this becomes an actual Map, that will break.
179 */
180function get(key) {
181 return key._reactInternalFiber;
182}
183function set(key, value) {
184 key._reactInternalFiber = value;
185}
186
187// The Symbol used to tag the ReactElement-like types. If there is no native Symbol
188// nor polyfill, then a plain number is used for performance.
189var hasSymbol = typeof Symbol === 'function' && Symbol.for;
190var REACT_ELEMENT_TYPE = hasSymbol ? Symbol.for('react.element') : 0xeac7;
191var REACT_PORTAL_TYPE = hasSymbol ? Symbol.for('react.portal') : 0xeaca;
192var REACT_FRAGMENT_TYPE = hasSymbol ? Symbol.for('react.fragment') : 0xeacb;
193var REACT_STRICT_MODE_TYPE = hasSymbol ? Symbol.for('react.strict_mode') : 0xeacc;
194var REACT_PROFILER_TYPE = hasSymbol ? Symbol.for('react.profiler') : 0xead2;
195var REACT_PROVIDER_TYPE = hasSymbol ? Symbol.for('react.provider') : 0xeacd;
196var REACT_CONTEXT_TYPE = hasSymbol ? Symbol.for('react.context') : 0xeace; // TODO: We don't use AsyncMode or ConcurrentMode anymore. They were temporary
197var REACT_CONCURRENT_MODE_TYPE = hasSymbol ? Symbol.for('react.concurrent_mode') : 0xeacf;
198var REACT_FORWARD_REF_TYPE = hasSymbol ? Symbol.for('react.forward_ref') : 0xead0;
199var REACT_SUSPENSE_TYPE = hasSymbol ? Symbol.for('react.suspense') : 0xead1;
200var REACT_SUSPENSE_LIST_TYPE = hasSymbol ? Symbol.for('react.suspense_list') : 0xead8;
201var REACT_MEMO_TYPE = hasSymbol ? Symbol.for('react.memo') : 0xead3;
202var REACT_LAZY_TYPE = hasSymbol ? Symbol.for('react.lazy') : 0xead4;
203var REACT_BLOCK_TYPE = hasSymbol ? Symbol.for('react.block') : 0xead9;
204var MAYBE_ITERATOR_SYMBOL = typeof Symbol === 'function' && Symbol.iterator;
205var FAUX_ITERATOR_SYMBOL = '@@iterator';
206function getIteratorFn(maybeIterable) {
207 if (maybeIterable === null || typeof maybeIterable !== 'object') {
208 return null;
209 }
210
211 var maybeIterator = MAYBE_ITERATOR_SYMBOL && maybeIterable[MAYBE_ITERATOR_SYMBOL] || maybeIterable[FAUX_ITERATOR_SYMBOL];
212
213 if (typeof maybeIterator === 'function') {
214 return maybeIterator;
215 }
216
217 return null;
218}
219
220var Uninitialized = -1;
221var Pending = 0;
222var Resolved = 1;
223var Rejected = 2;
224function refineResolvedLazyComponent(lazyComponent) {
225 return lazyComponent._status === Resolved ? lazyComponent._result : null;
226}
227function initializeLazyComponentType(lazyComponent) {
228 if (lazyComponent._status === Uninitialized) {
229 lazyComponent._status = Pending;
230 var ctor = lazyComponent._ctor;
231 var thenable = ctor();
232 lazyComponent._result = thenable;
233 thenable.then(function (moduleObject) {
234 if (lazyComponent._status === Pending) {
235 var defaultExport = moduleObject.default;
236
237 {
238 if (defaultExport === undefined) {
239 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);
240 }
241 }
242
243 lazyComponent._status = Resolved;
244 lazyComponent._result = defaultExport;
245 }
246 }, function (error) {
247 if (lazyComponent._status === Pending) {
248 lazyComponent._status = Rejected;
249 lazyComponent._result = error;
250 }
251 });
252 }
253}
254
255function getWrappedName(outerType, innerType, wrapperName) {
256 var functionName = innerType.displayName || innerType.name || '';
257 return outerType.displayName || (functionName !== '' ? wrapperName + "(" + functionName + ")" : wrapperName);
258}
259
260function getComponentName(type) {
261 if (type == null) {
262 // Host root, text node or just invalid type.
263 return null;
264 }
265
266 {
267 if (typeof type.tag === 'number') {
268 error('Received an unexpected object in getComponentName(). ' + 'This is likely a bug in React. Please file an issue.');
269 }
270 }
271
272 if (typeof type === 'function') {
273 return type.displayName || type.name || null;
274 }
275
276 if (typeof type === 'string') {
277 return type;
278 }
279
280 switch (type) {
281 case REACT_FRAGMENT_TYPE:
282 return 'Fragment';
283
284 case REACT_PORTAL_TYPE:
285 return 'Portal';
286
287 case REACT_PROFILER_TYPE:
288 return "Profiler";
289
290 case REACT_STRICT_MODE_TYPE:
291 return 'StrictMode';
292
293 case REACT_SUSPENSE_TYPE:
294 return 'Suspense';
295
296 case REACT_SUSPENSE_LIST_TYPE:
297 return 'SuspenseList';
298 }
299
300 if (typeof type === 'object') {
301 switch (type.$$typeof) {
302 case REACT_CONTEXT_TYPE:
303 return 'Context.Consumer';
304
305 case REACT_PROVIDER_TYPE:
306 return 'Context.Provider';
307
308 case REACT_FORWARD_REF_TYPE:
309 return getWrappedName(type, type.render, 'ForwardRef');
310
311 case REACT_MEMO_TYPE:
312 return getComponentName(type.type);
313
314 case REACT_BLOCK_TYPE:
315 return getComponentName(type.render);
316
317 case REACT_LAZY_TYPE:
318 {
319 var thenable = type;
320 var resolvedThenable = refineResolvedLazyComponent(thenable);
321
322 if (resolvedThenable) {
323 return getComponentName(resolvedThenable);
324 }
325
326 break;
327 }
328 }
329 }
330
331 return null;
332}
333
334// Don't change these two values. They're used by React Dev Tools.
335var NoEffect =
336/* */
3370;
338var PerformedWork =
339/* */
3401; // You can change the rest (and add more).
341
342var Placement =
343/* */
3442;
345var Update =
346/* */
3474;
348var PlacementAndUpdate =
349/* */
3506;
351var Deletion =
352/* */
3538;
354var ContentReset =
355/* */
35616;
357var Callback =
358/* */
35932;
360var DidCapture =
361/* */
36264;
363var Ref =
364/* */
365128;
366var Snapshot =
367/* */
368256;
369var Passive =
370/* */
371512;
372var Hydrating =
373/* */
3741024;
375var HydratingAndUpdate =
376/* */
3771028; // Passive & Update & Callback & Ref & Snapshot
378
379var LifecycleEffectMask =
380/* */
381932; // Union of all host effects
382
383var HostEffectMask =
384/* */
3852047;
386var Incomplete =
387/* */
3882048;
389var ShouldCapture =
390/* */
3914096;
392
393var enableProfilerTimer = true; // Trace which interactions trigger each commit.
394
395var enableFundamentalAPI = false; // Experimental Scope support.
396var warnAboutStringRefs = false;
397
398var ReactCurrentOwner = ReactSharedInternals.ReactCurrentOwner;
399function getNearestMountedFiber(fiber) {
400 var node = fiber;
401 var nearestMounted = fiber;
402
403 if (!fiber.alternate) {
404 // If there is no alternate, this might be a new tree that isn't inserted
405 // yet. If it is, then it will have a pending insertion effect on it.
406 var nextNode = node;
407
408 do {
409 node = nextNode;
410
411 if ((node.effectTag & (Placement | Hydrating)) !== NoEffect) {
412 // This is an insertion or in-progress hydration. The nearest possible
413 // mounted fiber is the parent but we need to continue to figure out
414 // if that one is still mounted.
415 nearestMounted = node.return;
416 }
417
418 nextNode = node.return;
419 } while (nextNode);
420 } else {
421 while (node.return) {
422 node = node.return;
423 }
424 }
425
426 if (node.tag === HostRoot) {
427 // TODO: Check if this was a nested HostRoot when used with
428 // renderContainerIntoSubtree.
429 return nearestMounted;
430 } // If we didn't hit the root, that means that we're in an disconnected tree
431 // that has been unmounted.
432
433
434 return null;
435}
436function isFiberMounted(fiber) {
437 return getNearestMountedFiber(fiber) === fiber;
438}
439function isMounted(component) {
440 {
441 var owner = ReactCurrentOwner.current;
442
443 if (owner !== null && owner.tag === ClassComponent) {
444 var ownerFiber = owner;
445 var instance = ownerFiber.stateNode;
446
447 if (!instance._warnedAboutRefsInRender) {
448 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');
449 }
450
451 instance._warnedAboutRefsInRender = true;
452 }
453 }
454
455 var fiber = get(component);
456
457 if (!fiber) {
458 return false;
459 }
460
461 return getNearestMountedFiber(fiber) === fiber;
462}
463
464function assertIsMounted(fiber) {
465 if (!(getNearestMountedFiber(fiber) === fiber)) {
466 {
467 throw Error( "Unable to find node on an unmounted component." );
468 }
469 }
470}
471
472function findCurrentFiberUsingSlowPath(fiber) {
473 var alternate = fiber.alternate;
474
475 if (!alternate) {
476 // If there is no alternate, then we only need to check if it is mounted.
477 var nearestMounted = getNearestMountedFiber(fiber);
478
479 if (!(nearestMounted !== null)) {
480 {
481 throw Error( "Unable to find node on an unmounted component." );
482 }
483 }
484
485 if (nearestMounted !== fiber) {
486 return null;
487 }
488
489 return fiber;
490 } // If we have two possible branches, we'll walk backwards up to the root
491 // to see what path the root points to. On the way we may hit one of the
492 // special cases and we'll deal with them.
493
494
495 var a = fiber;
496 var b = alternate;
497
498 while (true) {
499 var parentA = a.return;
500
501 if (parentA === null) {
502 // We're at the root.
503 break;
504 }
505
506 var parentB = parentA.alternate;
507
508 if (parentB === null) {
509 // There is no alternate. This is an unusual case. Currently, it only
510 // happens when a Suspense component is hidden. An extra fragment fiber
511 // is inserted in between the Suspense fiber and its children. Skip
512 // over this extra fragment fiber and proceed to the next parent.
513 var nextParent = parentA.return;
514
515 if (nextParent !== null) {
516 a = b = nextParent;
517 continue;
518 } // If there's no parent, we're at the root.
519
520
521 break;
522 } // If both copies of the parent fiber point to the same child, we can
523 // assume that the child is current. This happens when we bailout on low
524 // priority: the bailed out fiber's child reuses the current child.
525
526
527 if (parentA.child === parentB.child) {
528 var child = parentA.child;
529
530 while (child) {
531 if (child === a) {
532 // We've determined that A is the current branch.
533 assertIsMounted(parentA);
534 return fiber;
535 }
536
537 if (child === b) {
538 // We've determined that B is the current branch.
539 assertIsMounted(parentA);
540 return alternate;
541 }
542
543 child = child.sibling;
544 } // We should never have an alternate for any mounting node. So the only
545 // way this could possibly happen is if this was unmounted, if at all.
546
547
548 {
549 {
550 throw Error( "Unable to find node on an unmounted component." );
551 }
552 }
553 }
554
555 if (a.return !== b.return) {
556 // The return pointer of A and the return pointer of B point to different
557 // fibers. We assume that return pointers never criss-cross, so A must
558 // belong to the child set of A.return, and B must belong to the child
559 // set of B.return.
560 a = parentA;
561 b = parentB;
562 } else {
563 // The return pointers point to the same fiber. We'll have to use the
564 // default, slow path: scan the child sets of each parent alternate to see
565 // which child belongs to which set.
566 //
567 // Search parent A's child set
568 var didFindChild = false;
569 var _child = parentA.child;
570
571 while (_child) {
572 if (_child === a) {
573 didFindChild = true;
574 a = parentA;
575 b = parentB;
576 break;
577 }
578
579 if (_child === b) {
580 didFindChild = true;
581 b = parentA;
582 a = parentB;
583 break;
584 }
585
586 _child = _child.sibling;
587 }
588
589 if (!didFindChild) {
590 // Search parent B's child set
591 _child = parentB.child;
592
593 while (_child) {
594 if (_child === a) {
595 didFindChild = true;
596 a = parentB;
597 b = parentA;
598 break;
599 }
600
601 if (_child === b) {
602 didFindChild = true;
603 b = parentB;
604 a = parentA;
605 break;
606 }
607
608 _child = _child.sibling;
609 }
610
611 if (!didFindChild) {
612 {
613 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." );
614 }
615 }
616 }
617 }
618
619 if (!(a.alternate === b)) {
620 {
621 throw Error( "Return fibers should always be each others' alternates. This error is likely caused by a bug in React. Please file an issue." );
622 }
623 }
624 } // If the root is not a host container, we're in a disconnected tree. I.e.
625 // unmounted.
626
627
628 if (!(a.tag === HostRoot)) {
629 {
630 throw Error( "Unable to find node on an unmounted component." );
631 }
632 }
633
634 if (a.stateNode.current === a) {
635 // We've determined that A is the current branch.
636 return fiber;
637 } // Otherwise B has to be current branch.
638
639
640 return alternate;
641}
642function findCurrentHostFiber(parent) {
643 var currentParent = findCurrentFiberUsingSlowPath(parent);
644
645 if (!currentParent) {
646 return null;
647 } // Next we'll drill down this component to find the first HostComponent/Text.
648
649
650 var node = currentParent;
651
652 while (true) {
653 if (node.tag === HostComponent || node.tag === HostText) {
654 return node;
655 } else if (node.child) {
656 node.child.return = node;
657 node = node.child;
658 continue;
659 }
660
661 if (node === currentParent) {
662 return null;
663 }
664
665 while (!node.sibling) {
666 if (!node.return || node.return === currentParent) {
667 return null;
668 }
669
670 node = node.return;
671 }
672
673 node.sibling.return = node.return;
674 node = node.sibling;
675 } // Flow needs the return null here, but ESLint complains about it.
676 // eslint-disable-next-line no-unreachable
677
678
679 return null;
680}
681
682var TYPES = {
683 CLIPPING_RECTANGLE: 'ClippingRectangle',
684 GROUP: 'Group',
685 SHAPE: 'Shape',
686 TEXT: 'Text'
687};
688var EVENT_TYPES = {
689 onClick: 'click',
690 onMouseMove: 'mousemove',
691 onMouseOver: 'mouseover',
692 onMouseOut: 'mouseout',
693 onMouseUp: 'mouseup',
694 onMouseDown: 'mousedown'
695};
696function childrenAsString(children) {
697 if (!children) {
698 return '';
699 } else if (typeof children === 'string') {
700 return children;
701 } else if (children.length) {
702 return children.join('');
703 } else {
704 return '';
705 }
706}
707
708// can re-export everything from this module.
709
710function shim() {
711 {
712 {
713 throw Error( "The current renderer does not support hydration. This error is likely caused by a bug in React. Please file an issue." );
714 }
715 }
716} // Hydration (when unsupported)
717var isSuspenseInstancePending = shim;
718var isSuspenseInstanceFallback = shim;
719var hydrateTextInstance = shim;
720
721var pooledTransform = new Transform();
722var NO_CONTEXT = {};
723var UPDATE_SIGNAL = {};
724
725{
726 Object.freeze(NO_CONTEXT);
727 Object.freeze(UPDATE_SIGNAL);
728}
729/** Helper Methods */
730
731
732function addEventListeners(instance, type, listener) {
733 // We need to explicitly unregister before unmount.
734 // For this reason we need to track subscriptions.
735 if (!instance._listeners) {
736 instance._listeners = {};
737 instance._subscriptions = {};
738 }
739
740 instance._listeners[type] = listener;
741
742 if (listener) {
743 if (!instance._subscriptions[type]) {
744 instance._subscriptions[type] = instance.subscribe(type, createEventHandler(instance), instance);
745 }
746 } else {
747 if (instance._subscriptions[type]) {
748 instance._subscriptions[type]();
749
750 delete instance._subscriptions[type];
751 }
752 }
753}
754
755function createEventHandler(instance) {
756 return function handleEvent(event) {
757 var listener = instance._listeners[event.type];
758
759 if (!listener) ; else if (typeof listener === 'function') {
760 listener.call(instance, event);
761 } else if (listener.handleEvent) {
762 listener.handleEvent(event);
763 }
764 };
765}
766
767function destroyEventListeners(instance) {
768 if (instance._subscriptions) {
769 for (var type in instance._subscriptions) {
770 instance._subscriptions[type]();
771 }
772 }
773
774 instance._subscriptions = null;
775 instance._listeners = null;
776}
777
778function getScaleX(props) {
779 if (props.scaleX != null) {
780 return props.scaleX;
781 } else if (props.scale != null) {
782 return props.scale;
783 } else {
784 return 1;
785 }
786}
787
788function getScaleY(props) {
789 if (props.scaleY != null) {
790 return props.scaleY;
791 } else if (props.scale != null) {
792 return props.scale;
793 } else {
794 return 1;
795 }
796}
797
798function isSameFont(oldFont, newFont) {
799 if (oldFont === newFont) {
800 return true;
801 } else if (typeof newFont === 'string' || typeof oldFont === 'string') {
802 return false;
803 } else {
804 return newFont.fontSize === oldFont.fontSize && newFont.fontStyle === oldFont.fontStyle && newFont.fontVariant === oldFont.fontVariant && newFont.fontWeight === oldFont.fontWeight && newFont.fontFamily === oldFont.fontFamily;
805 }
806}
807/** Render Methods */
808
809
810function applyClippingRectangleProps(instance, props) {
811 var prevProps = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
812 applyNodeProps(instance, props, prevProps);
813 instance.width = props.width;
814 instance.height = props.height;
815}
816
817function applyGroupProps(instance, props) {
818 var prevProps = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
819 applyNodeProps(instance, props, prevProps);
820 instance.width = props.width;
821 instance.height = props.height;
822}
823
824function applyNodeProps(instance, props) {
825 var prevProps = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
826 var scaleX = getScaleX(props);
827 var scaleY = getScaleY(props);
828 pooledTransform.transformTo(1, 0, 0, 1, 0, 0).move(props.x || 0, props.y || 0).rotate(props.rotation || 0, props.originX, props.originY).scale(scaleX, scaleY, props.originX, props.originY);
829
830 if (props.transform != null) {
831 pooledTransform.transform(props.transform);
832 }
833
834 if (instance.xx !== pooledTransform.xx || instance.yx !== pooledTransform.yx || instance.xy !== pooledTransform.xy || instance.yy !== pooledTransform.yy || instance.x !== pooledTransform.x || instance.y !== pooledTransform.y) {
835 instance.transformTo(pooledTransform);
836 }
837
838 if (props.cursor !== prevProps.cursor || props.title !== prevProps.title) {
839 instance.indicate(props.cursor, props.title);
840 }
841
842 if (instance.blend && props.opacity !== prevProps.opacity) {
843 instance.blend(props.opacity == null ? 1 : props.opacity);
844 }
845
846 if (props.visible !== prevProps.visible) {
847 if (props.visible == null || props.visible) {
848 instance.show();
849 } else {
850 instance.hide();
851 }
852 }
853
854 for (var type in EVENT_TYPES) {
855 addEventListeners(instance, EVENT_TYPES[type], props[type]);
856 }
857}
858
859function applyRenderableNodeProps(instance, props) {
860 var prevProps = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
861 applyNodeProps(instance, props, prevProps);
862
863 if (prevProps.fill !== props.fill) {
864 if (props.fill && props.fill.applyFill) {
865 props.fill.applyFill(instance);
866 } else {
867 instance.fill(props.fill);
868 }
869 }
870
871 if (prevProps.stroke !== props.stroke || prevProps.strokeWidth !== props.strokeWidth || prevProps.strokeCap !== props.strokeCap || prevProps.strokeJoin !== props.strokeJoin || // TODO: Consider deep check of stokeDash; may benefit VML in IE.
872 prevProps.strokeDash !== props.strokeDash) {
873 instance.stroke(props.stroke, props.strokeWidth, props.strokeCap, props.strokeJoin, props.strokeDash);
874 }
875}
876
877function applyShapeProps(instance, props) {
878 var prevProps = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
879 applyRenderableNodeProps(instance, props, prevProps);
880 var path = props.d || childrenAsString(props.children);
881 var prevDelta = instance._prevDelta;
882 var prevPath = instance._prevPath;
883
884 if (path !== prevPath || path.delta !== prevDelta || prevProps.height !== props.height || prevProps.width !== props.width) {
885 instance.draw(path, props.width, props.height);
886 instance._prevDelta = path.delta;
887 instance._prevPath = path;
888 }
889}
890
891function applyTextProps(instance, props) {
892 var prevProps = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
893 applyRenderableNodeProps(instance, props, prevProps);
894 var string = props.children;
895
896 if (instance._currentString !== string || !isSameFont(props.font, prevProps.font) || props.alignment !== prevProps.alignment || props.path !== prevProps.path) {
897 instance.draw(string, props.font, props.alignment, props.path);
898 instance._currentString = string;
899 }
900}
901function appendInitialChild(parentInstance, child) {
902 if (typeof child === 'string') {
903 // Noop for string children of Text (eg <Text>{'foo'}{'bar'}</Text>)
904 {
905 {
906 throw Error( "Text children should already be flattened." );
907 }
908 }
909 }
910
911 child.inject(parentInstance);
912}
913function createInstance(type, props, internalInstanceHandle) {
914 var instance;
915
916 switch (type) {
917 case TYPES.CLIPPING_RECTANGLE:
918 instance = Mode$1.ClippingRectangle();
919 instance._applyProps = applyClippingRectangleProps;
920 break;
921
922 case TYPES.GROUP:
923 instance = Mode$1.Group();
924 instance._applyProps = applyGroupProps;
925 break;
926
927 case TYPES.SHAPE:
928 instance = Mode$1.Shape();
929 instance._applyProps = applyShapeProps;
930 break;
931
932 case TYPES.TEXT:
933 instance = Mode$1.Text(props.children, props.font, props.alignment, props.path);
934 instance._applyProps = applyTextProps;
935 break;
936 }
937
938 if (!instance) {
939 {
940 throw Error( "ReactART does not support the type \"" + type + "\"" );
941 }
942 }
943
944 instance._applyProps(instance, props);
945
946 return instance;
947}
948function createTextInstance(text, rootContainerInstance, internalInstanceHandle) {
949 return text;
950}
951function getPublicInstance(instance) {
952 return instance;
953}
954function prepareForCommit() {// Noop
955}
956function prepareUpdate(domElement, type, oldProps, newProps) {
957 return UPDATE_SIGNAL;
958}
959function resetAfterCommit() {// Noop
960}
961function resetTextContent(domElement) {// Noop
962}
963function shouldDeprioritizeSubtree(type, props) {
964 return false;
965}
966function getRootHostContext() {
967 return NO_CONTEXT;
968}
969function getChildHostContext() {
970 return NO_CONTEXT;
971}
972var scheduleTimeout = setTimeout;
973var cancelTimeout = clearTimeout;
974var noTimeout = -1;
975function shouldSetTextContent(type, props) {
976 return typeof props.children === 'string' || typeof props.children === 'number';
977} // The ART renderer is secondary to the React DOM renderer.
978function appendChild(parentInstance, child) {
979 if (child.parentNode === parentInstance) {
980 child.eject();
981 }
982
983 child.inject(parentInstance);
984}
985function appendChildToContainer(parentInstance, child) {
986 if (child.parentNode === parentInstance) {
987 child.eject();
988 }
989
990 child.inject(parentInstance);
991}
992function insertBefore(parentInstance, child, beforeChild) {
993 if (!(child !== beforeChild)) {
994 {
995 throw Error( "ReactART: Can not insert node before itself" );
996 }
997 }
998
999 child.injectBefore(beforeChild);
1000}
1001function insertInContainerBefore(parentInstance, child, beforeChild) {
1002 if (!(child !== beforeChild)) {
1003 {
1004 throw Error( "ReactART: Can not insert node before itself" );
1005 }
1006 }
1007
1008 child.injectBefore(beforeChild);
1009}
1010function removeChild(parentInstance, child) {
1011 destroyEventListeners(child);
1012 child.eject();
1013}
1014function removeChildFromContainer(parentInstance, child) {
1015 destroyEventListeners(child);
1016 child.eject();
1017}
1018function commitUpdate(instance, updatePayload, type, oldProps, newProps) {
1019 instance._applyProps(instance, newProps, oldProps);
1020}
1021function hideInstance(instance) {
1022 instance.hide();
1023}
1024function unhideInstance(instance, props) {
1025 if (props.visible == null || props.visible) {
1026 instance.show();
1027 }
1028}
1029function unhideTextInstance(textInstance, text) {// Noop
1030}
1031
1032var BEFORE_SLASH_RE = /^(.*)[\\\/]/;
1033function describeComponentFrame (name, source, ownerName) {
1034 var sourceInfo = '';
1035
1036 if (source) {
1037 var path = source.fileName;
1038 var fileName = path.replace(BEFORE_SLASH_RE, '');
1039
1040 {
1041 // In DEV, include code for a common special case:
1042 // prefer "folder/index.js" instead of just "index.js".
1043 if (/^index\./.test(fileName)) {
1044 var match = path.match(BEFORE_SLASH_RE);
1045
1046 if (match) {
1047 var pathBeforeSlash = match[1];
1048
1049 if (pathBeforeSlash) {
1050 var folderName = pathBeforeSlash.replace(BEFORE_SLASH_RE, '');
1051 fileName = folderName + '/' + fileName;
1052 }
1053 }
1054 }
1055 }
1056
1057 sourceInfo = ' (at ' + fileName + ':' + source.lineNumber + ')';
1058 } else if (ownerName) {
1059 sourceInfo = ' (created by ' + ownerName + ')';
1060 }
1061
1062 return '\n in ' + (name || 'Unknown') + sourceInfo;
1063}
1064
1065var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame;
1066
1067function describeFiber(fiber) {
1068 switch (fiber.tag) {
1069 case HostRoot:
1070 case HostPortal:
1071 case HostText:
1072 case Fragment:
1073 case ContextProvider:
1074 case ContextConsumer:
1075 return '';
1076
1077 default:
1078 var owner = fiber._debugOwner;
1079 var source = fiber._debugSource;
1080 var name = getComponentName(fiber.type);
1081 var ownerName = null;
1082
1083 if (owner) {
1084 ownerName = getComponentName(owner.type);
1085 }
1086
1087 return describeComponentFrame(name, source, ownerName);
1088 }
1089}
1090
1091function getStackByFiberInDevAndProd(workInProgress) {
1092 var info = '';
1093 var node = workInProgress;
1094
1095 do {
1096 info += describeFiber(node);
1097 node = node.return;
1098 } while (node);
1099
1100 return info;
1101}
1102var current = null;
1103var isRendering = false;
1104function getCurrentFiberOwnerNameInDevOrNull() {
1105 {
1106 if (current === null) {
1107 return null;
1108 }
1109
1110 var owner = current._debugOwner;
1111
1112 if (owner !== null && typeof owner !== 'undefined') {
1113 return getComponentName(owner.type);
1114 }
1115 }
1116
1117 return null;
1118}
1119function getCurrentFiberStackInDev() {
1120 {
1121 if (current === null) {
1122 return '';
1123 } // Safe because if current fiber exists, we are reconciling,
1124 // and it is guaranteed to be the work-in-progress version.
1125
1126
1127 return getStackByFiberInDevAndProd(current);
1128 }
1129}
1130function resetCurrentFiber() {
1131 {
1132 ReactDebugCurrentFrame.getCurrentStack = null;
1133 current = null;
1134 isRendering = false;
1135 }
1136}
1137function setCurrentFiber(fiber) {
1138 {
1139 ReactDebugCurrentFrame.getCurrentStack = getCurrentFiberStackInDev;
1140 current = fiber;
1141 isRendering = false;
1142 }
1143}
1144function setIsRendering(rendering) {
1145 {
1146 isRendering = rendering;
1147 }
1148}
1149
1150// Prefix measurements so that it's possible to filter them.
1151// Longer prefixes are hard to read in DevTools.
1152var reactEmoji = "\u269B";
1153var warningEmoji = "\u26D4";
1154var 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.
1155// TODO: this looks the same as nextUnitOfWork in scheduler. Can we unify them?
1156
1157var currentFiber = null; // If we're in the middle of user code, which fiber and method is it?
1158// Reusing `currentFiber` would be confusing for this because user code fiber
1159// can change during commit phase too, but we don't need to unwind it (since
1160// lifecycles in the commit phase don't resemble a tree).
1161
1162var currentPhase = null;
1163var currentPhaseFiber = null; // Did lifecycle hook schedule an update? This is often a performance problem,
1164// so we will keep track of it, and include it in the report.
1165// Track commits caused by cascading updates.
1166
1167var isCommitting = false;
1168var hasScheduledUpdateInCurrentCommit = false;
1169var hasScheduledUpdateInCurrentPhase = false;
1170var commitCountInCurrentWorkLoop = 0;
1171var effectCountInCurrentCommit = 0;
1172// to avoid stretch the commit phase with measurement overhead.
1173
1174var labelsInCurrentCommit = new Set();
1175
1176var formatMarkName = function (markName) {
1177 return reactEmoji + " " + markName;
1178};
1179
1180var formatLabel = function (label, warning) {
1181 var prefix = warning ? warningEmoji + " " : reactEmoji + " ";
1182 var suffix = warning ? " Warning: " + warning : '';
1183 return "" + prefix + label + suffix;
1184};
1185
1186var beginMark = function (markName) {
1187 performance.mark(formatMarkName(markName));
1188};
1189
1190var clearMark = function (markName) {
1191 performance.clearMarks(formatMarkName(markName));
1192};
1193
1194var endMark = function (label, markName, warning) {
1195 var formattedMarkName = formatMarkName(markName);
1196 var formattedLabel = formatLabel(label, warning);
1197
1198 try {
1199 performance.measure(formattedLabel, formattedMarkName);
1200 } catch (err) {} // If previous mark was missing for some reason, this will throw.
1201 // This could only happen if React crashed in an unexpected place earlier.
1202 // Don't pile on with more errors.
1203 // Clear marks immediately to avoid growing buffer.
1204
1205
1206 performance.clearMarks(formattedMarkName);
1207 performance.clearMeasures(formattedLabel);
1208};
1209
1210var getFiberMarkName = function (label, debugID) {
1211 return label + " (#" + debugID + ")";
1212};
1213
1214var getFiberLabel = function (componentName, isMounted, phase) {
1215 if (phase === null) {
1216 // These are composite component total time measurements.
1217 return componentName + " [" + (isMounted ? 'update' : 'mount') + "]";
1218 } else {
1219 // Composite component methods.
1220 return componentName + "." + phase;
1221 }
1222};
1223
1224var beginFiberMark = function (fiber, phase) {
1225 var componentName = getComponentName(fiber.type) || 'Unknown';
1226 var debugID = fiber._debugID;
1227 var isMounted = fiber.alternate !== null;
1228 var label = getFiberLabel(componentName, isMounted, phase);
1229
1230 if (isCommitting && labelsInCurrentCommit.has(label)) {
1231 // During the commit phase, we don't show duplicate labels because
1232 // there is a fixed overhead for every measurement, and we don't
1233 // want to stretch the commit phase beyond necessary.
1234 return false;
1235 }
1236
1237 labelsInCurrentCommit.add(label);
1238 var markName = getFiberMarkName(label, debugID);
1239 beginMark(markName);
1240 return true;
1241};
1242
1243var clearFiberMark = function (fiber, phase) {
1244 var componentName = getComponentName(fiber.type) || 'Unknown';
1245 var debugID = fiber._debugID;
1246 var isMounted = fiber.alternate !== null;
1247 var label = getFiberLabel(componentName, isMounted, phase);
1248 var markName = getFiberMarkName(label, debugID);
1249 clearMark(markName);
1250};
1251
1252var endFiberMark = function (fiber, phase, warning) {
1253 var componentName = getComponentName(fiber.type) || 'Unknown';
1254 var debugID = fiber._debugID;
1255 var isMounted = fiber.alternate !== null;
1256 var label = getFiberLabel(componentName, isMounted, phase);
1257 var markName = getFiberMarkName(label, debugID);
1258 endMark(label, markName, warning);
1259};
1260
1261var shouldIgnoreFiber = function (fiber) {
1262 // Host components should be skipped in the timeline.
1263 // We could check typeof fiber.type, but does this work with RN?
1264 switch (fiber.tag) {
1265 case HostRoot:
1266 case HostComponent:
1267 case HostText:
1268 case HostPortal:
1269 case Fragment:
1270 case ContextProvider:
1271 case ContextConsumer:
1272 case Mode:
1273 return true;
1274
1275 default:
1276 return false;
1277 }
1278};
1279
1280var clearPendingPhaseMeasurement = function () {
1281 if (currentPhase !== null && currentPhaseFiber !== null) {
1282 clearFiberMark(currentPhaseFiber, currentPhase);
1283 }
1284
1285 currentPhaseFiber = null;
1286 currentPhase = null;
1287 hasScheduledUpdateInCurrentPhase = false;
1288};
1289
1290var pauseTimers = function () {
1291 // Stops all currently active measurements so that they can be resumed
1292 // if we continue in a later deferred loop from the same unit of work.
1293 var fiber = currentFiber;
1294
1295 while (fiber) {
1296 if (fiber._debugIsCurrentlyTiming) {
1297 endFiberMark(fiber, null, null);
1298 }
1299
1300 fiber = fiber.return;
1301 }
1302};
1303
1304var resumeTimersRecursively = function (fiber) {
1305 if (fiber.return !== null) {
1306 resumeTimersRecursively(fiber.return);
1307 }
1308
1309 if (fiber._debugIsCurrentlyTiming) {
1310 beginFiberMark(fiber, null);
1311 }
1312};
1313
1314var resumeTimers = function () {
1315 // Resumes all measurements that were active during the last deferred loop.
1316 if (currentFiber !== null) {
1317 resumeTimersRecursively(currentFiber);
1318 }
1319};
1320
1321function recordEffect() {
1322 {
1323 effectCountInCurrentCommit++;
1324 }
1325}
1326function recordScheduleUpdate() {
1327 {
1328 if (isCommitting) {
1329 hasScheduledUpdateInCurrentCommit = true;
1330 }
1331
1332 if (currentPhase !== null && currentPhase !== 'componentWillMount' && currentPhase !== 'componentWillReceiveProps') {
1333 hasScheduledUpdateInCurrentPhase = true;
1334 }
1335 }
1336}
1337function startWorkTimer(fiber) {
1338 {
1339 if (!supportsUserTiming || shouldIgnoreFiber(fiber)) {
1340 return;
1341 } // If we pause, this is the fiber to unwind from.
1342
1343
1344 currentFiber = fiber;
1345
1346 if (!beginFiberMark(fiber, null)) {
1347 return;
1348 }
1349
1350 fiber._debugIsCurrentlyTiming = true;
1351 }
1352}
1353function cancelWorkTimer(fiber) {
1354 {
1355 if (!supportsUserTiming || shouldIgnoreFiber(fiber)) {
1356 return;
1357 } // Remember we shouldn't complete measurement for this fiber.
1358 // Otherwise flamechart will be deep even for small updates.
1359
1360
1361 fiber._debugIsCurrentlyTiming = false;
1362 clearFiberMark(fiber, null);
1363 }
1364}
1365function stopWorkTimer(fiber) {
1366 {
1367 if (!supportsUserTiming || shouldIgnoreFiber(fiber)) {
1368 return;
1369 } // If we pause, its parent is the fiber to unwind from.
1370
1371
1372 currentFiber = fiber.return;
1373
1374 if (!fiber._debugIsCurrentlyTiming) {
1375 return;
1376 }
1377
1378 fiber._debugIsCurrentlyTiming = false;
1379 endFiberMark(fiber, null, null);
1380 }
1381}
1382function stopFailedWorkTimer(fiber) {
1383 {
1384 if (!supportsUserTiming || shouldIgnoreFiber(fiber)) {
1385 return;
1386 } // If we pause, its parent is the fiber to unwind from.
1387
1388
1389 currentFiber = fiber.return;
1390
1391 if (!fiber._debugIsCurrentlyTiming) {
1392 return;
1393 }
1394
1395 fiber._debugIsCurrentlyTiming = false;
1396 var warning = fiber.tag === SuspenseComponent ? 'Rendering was suspended' : 'An error was thrown inside this error boundary';
1397 endFiberMark(fiber, null, warning);
1398 }
1399}
1400function startPhaseTimer(fiber, phase) {
1401 {
1402 if (!supportsUserTiming) {
1403 return;
1404 }
1405
1406 clearPendingPhaseMeasurement();
1407
1408 if (!beginFiberMark(fiber, phase)) {
1409 return;
1410 }
1411
1412 currentPhaseFiber = fiber;
1413 currentPhase = phase;
1414 }
1415}
1416function stopPhaseTimer() {
1417 {
1418 if (!supportsUserTiming) {
1419 return;
1420 }
1421
1422 if (currentPhase !== null && currentPhaseFiber !== null) {
1423 var warning = hasScheduledUpdateInCurrentPhase ? 'Scheduled a cascading update' : null;
1424 endFiberMark(currentPhaseFiber, currentPhase, warning);
1425 }
1426
1427 currentPhase = null;
1428 currentPhaseFiber = null;
1429 }
1430}
1431function startWorkLoopTimer(nextUnitOfWork) {
1432 {
1433 currentFiber = nextUnitOfWork;
1434
1435 if (!supportsUserTiming) {
1436 return;
1437 }
1438
1439 commitCountInCurrentWorkLoop = 0; // This is top level call.
1440 // Any other measurements are performed within.
1441
1442 beginMark('(React Tree Reconciliation)'); // Resume any measurements that were in progress during the last loop.
1443
1444 resumeTimers();
1445 }
1446}
1447function stopWorkLoopTimer(interruptedBy, didCompleteRoot) {
1448 {
1449 if (!supportsUserTiming) {
1450 return;
1451 }
1452
1453 var warning = null;
1454
1455 if (interruptedBy !== null) {
1456 if (interruptedBy.tag === HostRoot) {
1457 warning = 'A top-level update interrupted the previous render';
1458 } else {
1459 var componentName = getComponentName(interruptedBy.type) || 'Unknown';
1460 warning = "An update to " + componentName + " interrupted the previous render";
1461 }
1462 } else if (commitCountInCurrentWorkLoop > 1) {
1463 warning = 'There were cascading updates';
1464 }
1465
1466 commitCountInCurrentWorkLoop = 0;
1467 var label = didCompleteRoot ? '(React Tree Reconciliation: Completed Root)' : '(React Tree Reconciliation: Yielded)'; // Pause any measurements until the next loop.
1468
1469 pauseTimers();
1470 endMark(label, '(React Tree Reconciliation)', warning);
1471 }
1472}
1473function startCommitTimer() {
1474 {
1475 if (!supportsUserTiming) {
1476 return;
1477 }
1478
1479 isCommitting = true;
1480 hasScheduledUpdateInCurrentCommit = false;
1481 labelsInCurrentCommit.clear();
1482 beginMark('(Committing Changes)');
1483 }
1484}
1485function stopCommitTimer() {
1486 {
1487 if (!supportsUserTiming) {
1488 return;
1489 }
1490
1491 var warning = null;
1492
1493 if (hasScheduledUpdateInCurrentCommit) {
1494 warning = 'Lifecycle hook scheduled a cascading update';
1495 } else if (commitCountInCurrentWorkLoop > 0) {
1496 warning = 'Caused by a cascading update in earlier commit';
1497 }
1498
1499 hasScheduledUpdateInCurrentCommit = false;
1500 commitCountInCurrentWorkLoop++;
1501 isCommitting = false;
1502 labelsInCurrentCommit.clear();
1503 endMark('(Committing Changes)', '(Committing Changes)', warning);
1504 }
1505}
1506function startCommitSnapshotEffectsTimer() {
1507 {
1508 if (!supportsUserTiming) {
1509 return;
1510 }
1511
1512 effectCountInCurrentCommit = 0;
1513 beginMark('(Committing Snapshot Effects)');
1514 }
1515}
1516function stopCommitSnapshotEffectsTimer() {
1517 {
1518 if (!supportsUserTiming) {
1519 return;
1520 }
1521
1522 var count = effectCountInCurrentCommit;
1523 effectCountInCurrentCommit = 0;
1524 endMark("(Committing Snapshot Effects: " + count + " Total)", '(Committing Snapshot Effects)', null);
1525 }
1526}
1527function startCommitHostEffectsTimer() {
1528 {
1529 if (!supportsUserTiming) {
1530 return;
1531 }
1532
1533 effectCountInCurrentCommit = 0;
1534 beginMark('(Committing Host Effects)');
1535 }
1536}
1537function stopCommitHostEffectsTimer() {
1538 {
1539 if (!supportsUserTiming) {
1540 return;
1541 }
1542
1543 var count = effectCountInCurrentCommit;
1544 effectCountInCurrentCommit = 0;
1545 endMark("(Committing Host Effects: " + count + " Total)", '(Committing Host Effects)', null);
1546 }
1547}
1548function startCommitLifeCyclesTimer() {
1549 {
1550 if (!supportsUserTiming) {
1551 return;
1552 }
1553
1554 effectCountInCurrentCommit = 0;
1555 beginMark('(Calling Lifecycle Methods)');
1556 }
1557}
1558function stopCommitLifeCyclesTimer() {
1559 {
1560 if (!supportsUserTiming) {
1561 return;
1562 }
1563
1564 var count = effectCountInCurrentCommit;
1565 effectCountInCurrentCommit = 0;
1566 endMark("(Calling Lifecycle Methods: " + count + " Total)", '(Calling Lifecycle Methods)', null);
1567 }
1568}
1569
1570var valueStack = [];
1571var fiberStack;
1572
1573{
1574 fiberStack = [];
1575}
1576
1577var index = -1;
1578
1579function createCursor(defaultValue) {
1580 return {
1581 current: defaultValue
1582 };
1583}
1584
1585function pop(cursor, fiber) {
1586 if (index < 0) {
1587 {
1588 error('Unexpected pop.');
1589 }
1590
1591 return;
1592 }
1593
1594 {
1595 if (fiber !== fiberStack[index]) {
1596 error('Unexpected Fiber popped.');
1597 }
1598 }
1599
1600 cursor.current = valueStack[index];
1601 valueStack[index] = null;
1602
1603 {
1604 fiberStack[index] = null;
1605 }
1606
1607 index--;
1608}
1609
1610function push(cursor, value, fiber) {
1611 index++;
1612 valueStack[index] = cursor.current;
1613
1614 {
1615 fiberStack[index] = fiber;
1616 }
1617
1618 cursor.current = value;
1619}
1620
1621var warnedAboutMissingGetChildContext;
1622
1623{
1624 warnedAboutMissingGetChildContext = {};
1625}
1626
1627var emptyContextObject = {};
1628
1629{
1630 Object.freeze(emptyContextObject);
1631} // A cursor to the current merged context object on the stack.
1632
1633
1634var contextStackCursor = createCursor(emptyContextObject); // A cursor to a boolean indicating whether the context has changed.
1635
1636var didPerformWorkStackCursor = createCursor(false); // Keep track of the previous context object that was on the stack.
1637// We use this to get access to the parent context after we have already
1638// pushed the next context provider, and now need to merge their contexts.
1639
1640var previousContext = emptyContextObject;
1641
1642function getUnmaskedContext(workInProgress, Component, didPushOwnContextIfProvider) {
1643 {
1644 if (didPushOwnContextIfProvider && isContextProvider(Component)) {
1645 // If the fiber is a context provider itself, when we read its context
1646 // we may have already pushed its own child context on the stack. A context
1647 // provider should not "see" its own child context. Therefore we read the
1648 // previous (parent) context instead for a context provider.
1649 return previousContext;
1650 }
1651
1652 return contextStackCursor.current;
1653 }
1654}
1655
1656function cacheContext(workInProgress, unmaskedContext, maskedContext) {
1657 {
1658 var instance = workInProgress.stateNode;
1659 instance.__reactInternalMemoizedUnmaskedChildContext = unmaskedContext;
1660 instance.__reactInternalMemoizedMaskedChildContext = maskedContext;
1661 }
1662}
1663
1664function getMaskedContext(workInProgress, unmaskedContext) {
1665 {
1666 var type = workInProgress.type;
1667 var contextTypes = type.contextTypes;
1668
1669 if (!contextTypes) {
1670 return emptyContextObject;
1671 } // Avoid recreating masked context unless unmasked context has changed.
1672 // Failing to do this will result in unnecessary calls to componentWillReceiveProps.
1673 // This may trigger infinite loops if componentWillReceiveProps calls setState.
1674
1675
1676 var instance = workInProgress.stateNode;
1677
1678 if (instance && instance.__reactInternalMemoizedUnmaskedChildContext === unmaskedContext) {
1679 return instance.__reactInternalMemoizedMaskedChildContext;
1680 }
1681
1682 var context = {};
1683
1684 for (var key in contextTypes) {
1685 context[key] = unmaskedContext[key];
1686 }
1687
1688 {
1689 var name = getComponentName(type) || 'Unknown';
1690 checkPropTypes(contextTypes, context, 'context', name, getCurrentFiberStackInDev);
1691 } // Cache unmasked context so we can avoid recreating masked context unless necessary.
1692 // Context is created before the class component is instantiated so check for instance.
1693
1694
1695 if (instance) {
1696 cacheContext(workInProgress, unmaskedContext, context);
1697 }
1698
1699 return context;
1700 }
1701}
1702
1703function hasContextChanged() {
1704 {
1705 return didPerformWorkStackCursor.current;
1706 }
1707}
1708
1709function isContextProvider(type) {
1710 {
1711 var childContextTypes = type.childContextTypes;
1712 return childContextTypes !== null && childContextTypes !== undefined;
1713 }
1714}
1715
1716function popContext(fiber) {
1717 {
1718 pop(didPerformWorkStackCursor, fiber);
1719 pop(contextStackCursor, fiber);
1720 }
1721}
1722
1723function popTopLevelContextObject(fiber) {
1724 {
1725 pop(didPerformWorkStackCursor, fiber);
1726 pop(contextStackCursor, fiber);
1727 }
1728}
1729
1730function pushTopLevelContextObject(fiber, context, didChange) {
1731 {
1732 if (!(contextStackCursor.current === emptyContextObject)) {
1733 {
1734 throw Error( "Unexpected context found on stack. This error is likely caused by a bug in React. Please file an issue." );
1735 }
1736 }
1737
1738 push(contextStackCursor, context, fiber);
1739 push(didPerformWorkStackCursor, didChange, fiber);
1740 }
1741}
1742
1743function processChildContext(fiber, type, parentContext) {
1744 {
1745 var instance = fiber.stateNode;
1746 var childContextTypes = type.childContextTypes; // TODO (bvaughn) Replace this behavior with an invariant() in the future.
1747 // It has only been added in Fiber to match the (unintentional) behavior in Stack.
1748
1749 if (typeof instance.getChildContext !== 'function') {
1750 {
1751 var componentName = getComponentName(type) || 'Unknown';
1752
1753 if (!warnedAboutMissingGetChildContext[componentName]) {
1754 warnedAboutMissingGetChildContext[componentName] = true;
1755
1756 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);
1757 }
1758 }
1759
1760 return parentContext;
1761 }
1762
1763 var childContext;
1764 startPhaseTimer(fiber, 'getChildContext');
1765 childContext = instance.getChildContext();
1766 stopPhaseTimer();
1767
1768 for (var contextKey in childContext) {
1769 if (!(contextKey in childContextTypes)) {
1770 {
1771 throw Error( (getComponentName(type) || 'Unknown') + ".getChildContext(): key \"" + contextKey + "\" is not defined in childContextTypes." );
1772 }
1773 }
1774 }
1775
1776 {
1777 var name = getComponentName(type) || 'Unknown';
1778 checkPropTypes(childContextTypes, childContext, 'child context', name, // In practice, there is one case in which we won't get a stack. It's when
1779 // somebody calls unstable_renderSubtreeIntoContainer() and we process
1780 // context from the parent component instance. The stack will be missing
1781 // because it's outside of the reconciliation, and so the pointer has not
1782 // been set. This is rare and doesn't matter. We'll also remove that API.
1783 getCurrentFiberStackInDev);
1784 }
1785
1786 return _assign({}, parentContext, {}, childContext);
1787 }
1788}
1789
1790function pushContextProvider(workInProgress) {
1791 {
1792 var instance = workInProgress.stateNode; // We push the context as early as possible to ensure stack integrity.
1793 // If the instance does not exist yet, we will push null at first,
1794 // and replace it on the stack later when invalidating the context.
1795
1796 var memoizedMergedChildContext = instance && instance.__reactInternalMemoizedMergedChildContext || emptyContextObject; // Remember the parent context so we can merge with it later.
1797 // Inherit the parent's did-perform-work value to avoid inadvertently blocking updates.
1798
1799 previousContext = contextStackCursor.current;
1800 push(contextStackCursor, memoizedMergedChildContext, workInProgress);
1801 push(didPerformWorkStackCursor, didPerformWorkStackCursor.current, workInProgress);
1802 return true;
1803 }
1804}
1805
1806function invalidateContextProvider(workInProgress, type, didChange) {
1807 {
1808 var instance = workInProgress.stateNode;
1809
1810 if (!instance) {
1811 {
1812 throw Error( "Expected to have an instance by this point. This error is likely caused by a bug in React. Please file an issue." );
1813 }
1814 }
1815
1816 if (didChange) {
1817 // Merge parent and own context.
1818 // Skip this if we're not updating due to sCU.
1819 // This avoids unnecessarily recomputing memoized values.
1820 var mergedContext = processChildContext(workInProgress, type, previousContext);
1821 instance.__reactInternalMemoizedMergedChildContext = mergedContext; // Replace the old (or empty) context with the new one.
1822 // It is important to unwind the context in the reverse order.
1823
1824 pop(didPerformWorkStackCursor, workInProgress);
1825 pop(contextStackCursor, workInProgress); // Now push the new context and mark that it has changed.
1826
1827 push(contextStackCursor, mergedContext, workInProgress);
1828 push(didPerformWorkStackCursor, didChange, workInProgress);
1829 } else {
1830 pop(didPerformWorkStackCursor, workInProgress);
1831 push(didPerformWorkStackCursor, didChange, workInProgress);
1832 }
1833 }
1834}
1835
1836function findCurrentUnmaskedContext(fiber) {
1837 {
1838 // Currently this is only used with renderSubtreeIntoContainer; not sure if it
1839 // makes sense elsewhere
1840 if (!(isFiberMounted(fiber) && fiber.tag === ClassComponent)) {
1841 {
1842 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." );
1843 }
1844 }
1845
1846 var node = fiber;
1847
1848 do {
1849 switch (node.tag) {
1850 case HostRoot:
1851 return node.stateNode.context;
1852
1853 case ClassComponent:
1854 {
1855 var Component = node.type;
1856
1857 if (isContextProvider(Component)) {
1858 return node.stateNode.__reactInternalMemoizedMergedChildContext;
1859 }
1860
1861 break;
1862 }
1863 }
1864
1865 node = node.return;
1866 } while (node !== null);
1867
1868 {
1869 {
1870 throw Error( "Found unexpected detached subtree parent. This error is likely caused by a bug in React. Please file an issue." );
1871 }
1872 }
1873 }
1874}
1875
1876var Scheduler_runWithPriority = Scheduler.unstable_runWithPriority,
1877 Scheduler_scheduleCallback = Scheduler.unstable_scheduleCallback,
1878 Scheduler_cancelCallback = Scheduler.unstable_cancelCallback,
1879 Scheduler_shouldYield = Scheduler.unstable_shouldYield,
1880 Scheduler_requestPaint = Scheduler.unstable_requestPaint,
1881 Scheduler_now = Scheduler.unstable_now,
1882 Scheduler_getCurrentPriorityLevel = Scheduler.unstable_getCurrentPriorityLevel,
1883 Scheduler_ImmediatePriority = Scheduler.unstable_ImmediatePriority,
1884 Scheduler_UserBlockingPriority = Scheduler.unstable_UserBlockingPriority,
1885 Scheduler_NormalPriority = Scheduler.unstable_NormalPriority,
1886 Scheduler_LowPriority = Scheduler.unstable_LowPriority,
1887 Scheduler_IdlePriority = Scheduler.unstable_IdlePriority;
1888
1889{
1890 // Provide explicit error message when production+profiling bundle of e.g.
1891 // react-dom is used with production (non-profiling) bundle of
1892 // scheduler/tracing
1893 if (!(tracing.__interactionsRef != null && tracing.__interactionsRef.current != null)) {
1894 {
1895 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" );
1896 }
1897 }
1898}
1899
1900var fakeCallbackNode = {}; // Except for NoPriority, these correspond to Scheduler priorities. We use
1901// ascending numbers so we can compare them like numbers. They start at 90 to
1902// avoid clashing with Scheduler's priorities.
1903
1904var ImmediatePriority = 99;
1905var UserBlockingPriority = 98;
1906var NormalPriority = 97;
1907var LowPriority = 96;
1908var IdlePriority = 95; // NoPriority is the absence of priority. Also React-only.
1909
1910var NoPriority = 90;
1911var shouldYield = Scheduler_shouldYield;
1912var requestPaint = // Fall back gracefully if we're running an older version of Scheduler.
1913Scheduler_requestPaint !== undefined ? Scheduler_requestPaint : function () {};
1914var syncQueue = null;
1915var immediateQueueCallbackNode = null;
1916var isFlushingSyncQueue = false;
1917var initialTimeMs = Scheduler_now(); // If the initial timestamp is reasonably small, use Scheduler's `now` directly.
1918// This will be the case for modern browsers that support `performance.now`. In
1919// older browsers, Scheduler falls back to `Date.now`, which returns a Unix
1920// timestamp. In that case, subtract the module initialization time to simulate
1921// the behavior of performance.now and keep our times small enough to fit
1922// within 32 bits.
1923// TODO: Consider lifting this into Scheduler.
1924
1925var now = initialTimeMs < 10000 ? Scheduler_now : function () {
1926 return Scheduler_now() - initialTimeMs;
1927};
1928function getCurrentPriorityLevel() {
1929 switch (Scheduler_getCurrentPriorityLevel()) {
1930 case Scheduler_ImmediatePriority:
1931 return ImmediatePriority;
1932
1933 case Scheduler_UserBlockingPriority:
1934 return UserBlockingPriority;
1935
1936 case Scheduler_NormalPriority:
1937 return NormalPriority;
1938
1939 case Scheduler_LowPriority:
1940 return LowPriority;
1941
1942 case Scheduler_IdlePriority:
1943 return IdlePriority;
1944
1945 default:
1946 {
1947 {
1948 throw Error( "Unknown priority level." );
1949 }
1950 }
1951
1952 }
1953}
1954
1955function reactPriorityToSchedulerPriority(reactPriorityLevel) {
1956 switch (reactPriorityLevel) {
1957 case ImmediatePriority:
1958 return Scheduler_ImmediatePriority;
1959
1960 case UserBlockingPriority:
1961 return Scheduler_UserBlockingPriority;
1962
1963 case NormalPriority:
1964 return Scheduler_NormalPriority;
1965
1966 case LowPriority:
1967 return Scheduler_LowPriority;
1968
1969 case IdlePriority:
1970 return Scheduler_IdlePriority;
1971
1972 default:
1973 {
1974 {
1975 throw Error( "Unknown priority level." );
1976 }
1977 }
1978
1979 }
1980}
1981
1982function runWithPriority(reactPriorityLevel, fn) {
1983 var priorityLevel = reactPriorityToSchedulerPriority(reactPriorityLevel);
1984 return Scheduler_runWithPriority(priorityLevel, fn);
1985}
1986function scheduleCallback(reactPriorityLevel, callback, options) {
1987 var priorityLevel = reactPriorityToSchedulerPriority(reactPriorityLevel);
1988 return Scheduler_scheduleCallback(priorityLevel, callback, options);
1989}
1990function scheduleSyncCallback(callback) {
1991 // Push this callback into an internal queue. We'll flush these either in
1992 // the next tick, or earlier if something calls `flushSyncCallbackQueue`.
1993 if (syncQueue === null) {
1994 syncQueue = [callback]; // Flush the queue in the next tick, at the earliest.
1995
1996 immediateQueueCallbackNode = Scheduler_scheduleCallback(Scheduler_ImmediatePriority, flushSyncCallbackQueueImpl);
1997 } else {
1998 // Push onto existing queue. Don't need to schedule a callback because
1999 // we already scheduled one when we created the queue.
2000 syncQueue.push(callback);
2001 }
2002
2003 return fakeCallbackNode;
2004}
2005function cancelCallback(callbackNode) {
2006 if (callbackNode !== fakeCallbackNode) {
2007 Scheduler_cancelCallback(callbackNode);
2008 }
2009}
2010function flushSyncCallbackQueue() {
2011 if (immediateQueueCallbackNode !== null) {
2012 var node = immediateQueueCallbackNode;
2013 immediateQueueCallbackNode = null;
2014 Scheduler_cancelCallback(node);
2015 }
2016
2017 flushSyncCallbackQueueImpl();
2018}
2019
2020function flushSyncCallbackQueueImpl() {
2021 if (!isFlushingSyncQueue && syncQueue !== null) {
2022 // Prevent re-entrancy.
2023 isFlushingSyncQueue = true;
2024 var i = 0;
2025
2026 try {
2027 var _isSync = true;
2028 var queue = syncQueue;
2029 runWithPriority(ImmediatePriority, function () {
2030 for (; i < queue.length; i++) {
2031 var callback = queue[i];
2032
2033 do {
2034 callback = callback(_isSync);
2035 } while (callback !== null);
2036 }
2037 });
2038 syncQueue = null;
2039 } catch (error) {
2040 // If something throws, leave the remaining callbacks on the queue.
2041 if (syncQueue !== null) {
2042 syncQueue = syncQueue.slice(i + 1);
2043 } // Resume flushing in the next tick
2044
2045
2046 Scheduler_scheduleCallback(Scheduler_ImmediatePriority, flushSyncCallbackQueue);
2047 throw error;
2048 } finally {
2049 isFlushingSyncQueue = false;
2050 }
2051 }
2052}
2053
2054var NoMode = 0;
2055var StrictMode = 1; // TODO: Remove BlockingMode and ConcurrentMode by reading from the root
2056// tag instead
2057
2058var BlockingMode = 2;
2059var ConcurrentMode = 4;
2060var ProfileMode = 8;
2061
2062// Max 31 bit integer. The max integer size in V8 for 32-bit systems.
2063// Math.pow(2, 30) - 1
2064// 0b111111111111111111111111111111
2065var MAX_SIGNED_31_BIT_INT = 1073741823;
2066
2067var NoWork = 0; // TODO: Think of a better name for Never. The key difference with Idle is that
2068// Never work can be committed in an inconsistent state without tearing the UI.
2069// The main example is offscreen content, like a hidden subtree. So one possible
2070// name is Offscreen. However, it also includes dehydrated Suspense boundaries,
2071// which are inconsistent in the sense that they haven't finished yet, but
2072// aren't visibly inconsistent because the server rendered HTML matches what the
2073// hydrated tree would look like.
2074
2075var Never = 1; // Idle is slightly higher priority than Never. It must completely finish in
2076// order to be consistent.
2077
2078var Idle = 2; // Continuous Hydration is slightly higher than Idle and is used to increase
2079var Sync = MAX_SIGNED_31_BIT_INT;
2080var Batched = Sync - 1;
2081var UNIT_SIZE = 10;
2082var MAGIC_NUMBER_OFFSET = Batched - 1; // 1 unit of expiration time represents 10ms.
2083
2084function msToExpirationTime(ms) {
2085 // Always subtract from the offset so that we don't clash with the magic number for NoWork.
2086 return MAGIC_NUMBER_OFFSET - (ms / UNIT_SIZE | 0);
2087}
2088function expirationTimeToMs(expirationTime) {
2089 return (MAGIC_NUMBER_OFFSET - expirationTime) * UNIT_SIZE;
2090}
2091
2092function ceiling(num, precision) {
2093 return ((num / precision | 0) + 1) * precision;
2094}
2095
2096function computeExpirationBucket(currentTime, expirationInMs, bucketSizeMs) {
2097 return MAGIC_NUMBER_OFFSET - ceiling(MAGIC_NUMBER_OFFSET - currentTime + expirationInMs / UNIT_SIZE, bucketSizeMs / UNIT_SIZE);
2098} // TODO: This corresponds to Scheduler's NormalPriority, not LowPriority. Update
2099// the names to reflect.
2100
2101
2102var LOW_PRIORITY_EXPIRATION = 5000;
2103var LOW_PRIORITY_BATCH_SIZE = 250;
2104function computeAsyncExpiration(currentTime) {
2105 return computeExpirationBucket(currentTime, LOW_PRIORITY_EXPIRATION, LOW_PRIORITY_BATCH_SIZE);
2106}
2107function computeSuspenseExpiration(currentTime, timeoutMs) {
2108 // TODO: Should we warn if timeoutMs is lower than the normal pri expiration time?
2109 return computeExpirationBucket(currentTime, timeoutMs, LOW_PRIORITY_BATCH_SIZE);
2110} // We intentionally set a higher expiration time for interactive updates in
2111// dev than in production.
2112//
2113// If the main thread is being blocked so long that you hit the expiration,
2114// it's a problem that could be solved with better scheduling.
2115//
2116// People will be more likely to notice this and fix it with the long
2117// expiration time in development.
2118//
2119// In production we opt for better UX at the risk of masking scheduling
2120// problems, by expiring fast.
2121
2122var HIGH_PRIORITY_EXPIRATION = 500 ;
2123var HIGH_PRIORITY_BATCH_SIZE = 100;
2124function computeInteractiveExpiration(currentTime) {
2125 return computeExpirationBucket(currentTime, HIGH_PRIORITY_EXPIRATION, HIGH_PRIORITY_BATCH_SIZE);
2126}
2127function inferPriorityFromExpirationTime(currentTime, expirationTime) {
2128 if (expirationTime === Sync) {
2129 return ImmediatePriority;
2130 }
2131
2132 if (expirationTime === Never || expirationTime === Idle) {
2133 return IdlePriority;
2134 }
2135
2136 var msUntil = expirationTimeToMs(expirationTime) - expirationTimeToMs(currentTime);
2137
2138 if (msUntil <= 0) {
2139 return ImmediatePriority;
2140 }
2141
2142 if (msUntil <= HIGH_PRIORITY_EXPIRATION + HIGH_PRIORITY_BATCH_SIZE) {
2143 return UserBlockingPriority;
2144 }
2145
2146 if (msUntil <= LOW_PRIORITY_EXPIRATION + LOW_PRIORITY_BATCH_SIZE) {
2147 return NormalPriority;
2148 } // TODO: Handle LowPriority
2149 // Assume anything lower has idle priority
2150
2151
2152 return IdlePriority;
2153}
2154
2155/**
2156 * inlined Object.is polyfill to avoid requiring consumers ship their own
2157 * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is
2158 */
2159function is(x, y) {
2160 return x === y && (x !== 0 || 1 / x === 1 / y) || x !== x && y !== y // eslint-disable-line no-self-compare
2161 ;
2162}
2163
2164var objectIs = typeof Object.is === 'function' ? Object.is : is;
2165
2166var hasOwnProperty = Object.prototype.hasOwnProperty;
2167/**
2168 * Performs equality by iterating through keys on an object and returning false
2169 * when any key has values which are not strictly equal between the arguments.
2170 * Returns true when the values of all keys are strictly equal.
2171 */
2172
2173function shallowEqual(objA, objB) {
2174 if (objectIs(objA, objB)) {
2175 return true;
2176 }
2177
2178 if (typeof objA !== 'object' || objA === null || typeof objB !== 'object' || objB === null) {
2179 return false;
2180 }
2181
2182 var keysA = Object.keys(objA);
2183 var keysB = Object.keys(objB);
2184
2185 if (keysA.length !== keysB.length) {
2186 return false;
2187 } // Test for A's keys different from B.
2188
2189
2190 for (var i = 0; i < keysA.length; i++) {
2191 if (!hasOwnProperty.call(objB, keysA[i]) || !objectIs(objA[keysA[i]], objB[keysA[i]])) {
2192 return false;
2193 }
2194 }
2195
2196 return true;
2197}
2198
2199var ReactStrictModeWarnings = {
2200 recordUnsafeLifecycleWarnings: function (fiber, instance) {},
2201 flushPendingUnsafeLifecycleWarnings: function () {},
2202 recordLegacyContextWarning: function (fiber, instance) {},
2203 flushLegacyContextWarning: function () {},
2204 discardPendingWarnings: function () {}
2205};
2206
2207{
2208 var findStrictRoot = function (fiber) {
2209 var maybeStrictRoot = null;
2210 var node = fiber;
2211
2212 while (node !== null) {
2213 if (node.mode & StrictMode) {
2214 maybeStrictRoot = node;
2215 }
2216
2217 node = node.return;
2218 }
2219
2220 return maybeStrictRoot;
2221 };
2222
2223 var setToSortedString = function (set) {
2224 var array = [];
2225 set.forEach(function (value) {
2226 array.push(value);
2227 });
2228 return array.sort().join(', ');
2229 };
2230
2231 var pendingComponentWillMountWarnings = [];
2232 var pendingUNSAFE_ComponentWillMountWarnings = [];
2233 var pendingComponentWillReceivePropsWarnings = [];
2234 var pendingUNSAFE_ComponentWillReceivePropsWarnings = [];
2235 var pendingComponentWillUpdateWarnings = [];
2236 var pendingUNSAFE_ComponentWillUpdateWarnings = []; // Tracks components we have already warned about.
2237
2238 var didWarnAboutUnsafeLifecycles = new Set();
2239
2240 ReactStrictModeWarnings.recordUnsafeLifecycleWarnings = function (fiber, instance) {
2241 // Dedup strategy: Warn once per component.
2242 if (didWarnAboutUnsafeLifecycles.has(fiber.type)) {
2243 return;
2244 }
2245
2246 if (typeof instance.componentWillMount === 'function' && // Don't warn about react-lifecycles-compat polyfilled components.
2247 instance.componentWillMount.__suppressDeprecationWarning !== true) {
2248 pendingComponentWillMountWarnings.push(fiber);
2249 }
2250
2251 if (fiber.mode & StrictMode && typeof instance.UNSAFE_componentWillMount === 'function') {
2252 pendingUNSAFE_ComponentWillMountWarnings.push(fiber);
2253 }
2254
2255 if (typeof instance.componentWillReceiveProps === 'function' && instance.componentWillReceiveProps.__suppressDeprecationWarning !== true) {
2256 pendingComponentWillReceivePropsWarnings.push(fiber);
2257 }
2258
2259 if (fiber.mode & StrictMode && typeof instance.UNSAFE_componentWillReceiveProps === 'function') {
2260 pendingUNSAFE_ComponentWillReceivePropsWarnings.push(fiber);
2261 }
2262
2263 if (typeof instance.componentWillUpdate === 'function' && instance.componentWillUpdate.__suppressDeprecationWarning !== true) {
2264 pendingComponentWillUpdateWarnings.push(fiber);
2265 }
2266
2267 if (fiber.mode & StrictMode && typeof instance.UNSAFE_componentWillUpdate === 'function') {
2268 pendingUNSAFE_ComponentWillUpdateWarnings.push(fiber);
2269 }
2270 };
2271
2272 ReactStrictModeWarnings.flushPendingUnsafeLifecycleWarnings = function () {
2273 // We do an initial pass to gather component names
2274 var componentWillMountUniqueNames = new Set();
2275
2276 if (pendingComponentWillMountWarnings.length > 0) {
2277 pendingComponentWillMountWarnings.forEach(function (fiber) {
2278 componentWillMountUniqueNames.add(getComponentName(fiber.type) || 'Component');
2279 didWarnAboutUnsafeLifecycles.add(fiber.type);
2280 });
2281 pendingComponentWillMountWarnings = [];
2282 }
2283
2284 var UNSAFE_componentWillMountUniqueNames = new Set();
2285
2286 if (pendingUNSAFE_ComponentWillMountWarnings.length > 0) {
2287 pendingUNSAFE_ComponentWillMountWarnings.forEach(function (fiber) {
2288 UNSAFE_componentWillMountUniqueNames.add(getComponentName(fiber.type) || 'Component');
2289 didWarnAboutUnsafeLifecycles.add(fiber.type);
2290 });
2291 pendingUNSAFE_ComponentWillMountWarnings = [];
2292 }
2293
2294 var componentWillReceivePropsUniqueNames = new Set();
2295
2296 if (pendingComponentWillReceivePropsWarnings.length > 0) {
2297 pendingComponentWillReceivePropsWarnings.forEach(function (fiber) {
2298 componentWillReceivePropsUniqueNames.add(getComponentName(fiber.type) || 'Component');
2299 didWarnAboutUnsafeLifecycles.add(fiber.type);
2300 });
2301 pendingComponentWillReceivePropsWarnings = [];
2302 }
2303
2304 var UNSAFE_componentWillReceivePropsUniqueNames = new Set();
2305
2306 if (pendingUNSAFE_ComponentWillReceivePropsWarnings.length > 0) {
2307 pendingUNSAFE_ComponentWillReceivePropsWarnings.forEach(function (fiber) {
2308 UNSAFE_componentWillReceivePropsUniqueNames.add(getComponentName(fiber.type) || 'Component');
2309 didWarnAboutUnsafeLifecycles.add(fiber.type);
2310 });
2311 pendingUNSAFE_ComponentWillReceivePropsWarnings = [];
2312 }
2313
2314 var componentWillUpdateUniqueNames = new Set();
2315
2316 if (pendingComponentWillUpdateWarnings.length > 0) {
2317 pendingComponentWillUpdateWarnings.forEach(function (fiber) {
2318 componentWillUpdateUniqueNames.add(getComponentName(fiber.type) || 'Component');
2319 didWarnAboutUnsafeLifecycles.add(fiber.type);
2320 });
2321 pendingComponentWillUpdateWarnings = [];
2322 }
2323
2324 var UNSAFE_componentWillUpdateUniqueNames = new Set();
2325
2326 if (pendingUNSAFE_ComponentWillUpdateWarnings.length > 0) {
2327 pendingUNSAFE_ComponentWillUpdateWarnings.forEach(function (fiber) {
2328 UNSAFE_componentWillUpdateUniqueNames.add(getComponentName(fiber.type) || 'Component');
2329 didWarnAboutUnsafeLifecycles.add(fiber.type);
2330 });
2331 pendingUNSAFE_ComponentWillUpdateWarnings = [];
2332 } // Finally, we flush all the warnings
2333 // UNSAFE_ ones before the deprecated ones, since they'll be 'louder'
2334
2335
2336 if (UNSAFE_componentWillMountUniqueNames.size > 0) {
2337 var sortedNames = setToSortedString(UNSAFE_componentWillMountUniqueNames);
2338
2339 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);
2340 }
2341
2342 if (UNSAFE_componentWillReceivePropsUniqueNames.size > 0) {
2343 var _sortedNames = setToSortedString(UNSAFE_componentWillReceivePropsUniqueNames);
2344
2345 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);
2346 }
2347
2348 if (UNSAFE_componentWillUpdateUniqueNames.size > 0) {
2349 var _sortedNames2 = setToSortedString(UNSAFE_componentWillUpdateUniqueNames);
2350
2351 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);
2352 }
2353
2354 if (componentWillMountUniqueNames.size > 0) {
2355 var _sortedNames3 = setToSortedString(componentWillMountUniqueNames);
2356
2357 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);
2358 }
2359
2360 if (componentWillReceivePropsUniqueNames.size > 0) {
2361 var _sortedNames4 = setToSortedString(componentWillReceivePropsUniqueNames);
2362
2363 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);
2364 }
2365
2366 if (componentWillUpdateUniqueNames.size > 0) {
2367 var _sortedNames5 = setToSortedString(componentWillUpdateUniqueNames);
2368
2369 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);
2370 }
2371 };
2372
2373 var pendingLegacyContextWarning = new Map(); // Tracks components we have already warned about.
2374
2375 var didWarnAboutLegacyContext = new Set();
2376
2377 ReactStrictModeWarnings.recordLegacyContextWarning = function (fiber, instance) {
2378 var strictRoot = findStrictRoot(fiber);
2379
2380 if (strictRoot === null) {
2381 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.');
2382
2383 return;
2384 } // Dedup strategy: Warn once per component.
2385
2386
2387 if (didWarnAboutLegacyContext.has(fiber.type)) {
2388 return;
2389 }
2390
2391 var warningsForRoot = pendingLegacyContextWarning.get(strictRoot);
2392
2393 if (fiber.type.contextTypes != null || fiber.type.childContextTypes != null || instance !== null && typeof instance.getChildContext === 'function') {
2394 if (warningsForRoot === undefined) {
2395 warningsForRoot = [];
2396 pendingLegacyContextWarning.set(strictRoot, warningsForRoot);
2397 }
2398
2399 warningsForRoot.push(fiber);
2400 }
2401 };
2402
2403 ReactStrictModeWarnings.flushLegacyContextWarning = function () {
2404 pendingLegacyContextWarning.forEach(function (fiberArray, strictRoot) {
2405 if (fiberArray.length === 0) {
2406 return;
2407 }
2408
2409 var firstFiber = fiberArray[0];
2410 var uniqueNames = new Set();
2411 fiberArray.forEach(function (fiber) {
2412 uniqueNames.add(getComponentName(fiber.type) || 'Component');
2413 didWarnAboutLegacyContext.add(fiber.type);
2414 });
2415 var sortedNames = setToSortedString(uniqueNames);
2416 var firstComponentStack = getStackByFiberInDevAndProd(firstFiber);
2417
2418 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);
2419 });
2420 };
2421
2422 ReactStrictModeWarnings.discardPendingWarnings = function () {
2423 pendingComponentWillMountWarnings = [];
2424 pendingUNSAFE_ComponentWillMountWarnings = [];
2425 pendingComponentWillReceivePropsWarnings = [];
2426 pendingUNSAFE_ComponentWillReceivePropsWarnings = [];
2427 pendingComponentWillUpdateWarnings = [];
2428 pendingUNSAFE_ComponentWillUpdateWarnings = [];
2429 pendingLegacyContextWarning = new Map();
2430 };
2431}
2432
2433var resolveFamily = null; // $FlowFixMe Flow gets confused by a WeakSet feature check below.
2434
2435var failedBoundaries = null;
2436var setRefreshHandler = function (handler) {
2437 {
2438 resolveFamily = handler;
2439 }
2440};
2441function resolveFunctionForHotReloading(type) {
2442 {
2443 if (resolveFamily === null) {
2444 // Hot reloading is disabled.
2445 return type;
2446 }
2447
2448 var family = resolveFamily(type);
2449
2450 if (family === undefined) {
2451 return type;
2452 } // Use the latest known implementation.
2453
2454
2455 return family.current;
2456 }
2457}
2458function resolveClassForHotReloading(type) {
2459 // No implementation differences.
2460 return resolveFunctionForHotReloading(type);
2461}
2462function resolveForwardRefForHotReloading(type) {
2463 {
2464 if (resolveFamily === null) {
2465 // Hot reloading is disabled.
2466 return type;
2467 }
2468
2469 var family = resolveFamily(type);
2470
2471 if (family === undefined) {
2472 // Check if we're dealing with a real forwardRef. Don't want to crash early.
2473 if (type !== null && type !== undefined && typeof type.render === 'function') {
2474 // ForwardRef is special because its resolved .type is an object,
2475 // but it's possible that we only have its inner render function in the map.
2476 // If that inner render function is different, we'll build a new forwardRef type.
2477 var currentRender = resolveFunctionForHotReloading(type.render);
2478
2479 if (type.render !== currentRender) {
2480 var syntheticType = {
2481 $$typeof: REACT_FORWARD_REF_TYPE,
2482 render: currentRender
2483 };
2484
2485 if (type.displayName !== undefined) {
2486 syntheticType.displayName = type.displayName;
2487 }
2488
2489 return syntheticType;
2490 }
2491 }
2492
2493 return type;
2494 } // Use the latest known implementation.
2495
2496
2497 return family.current;
2498 }
2499}
2500function isCompatibleFamilyForHotReloading(fiber, element) {
2501 {
2502 if (resolveFamily === null) {
2503 // Hot reloading is disabled.
2504 return false;
2505 }
2506
2507 var prevType = fiber.elementType;
2508 var nextType = element.type; // If we got here, we know types aren't === equal.
2509
2510 var needsCompareFamilies = false;
2511 var $$typeofNextType = typeof nextType === 'object' && nextType !== null ? nextType.$$typeof : null;
2512
2513 switch (fiber.tag) {
2514 case ClassComponent:
2515 {
2516 if (typeof nextType === 'function') {
2517 needsCompareFamilies = true;
2518 }
2519
2520 break;
2521 }
2522
2523 case FunctionComponent:
2524 {
2525 if (typeof nextType === 'function') {
2526 needsCompareFamilies = true;
2527 } else if ($$typeofNextType === REACT_LAZY_TYPE) {
2528 // We don't know the inner type yet.
2529 // We're going to assume that the lazy inner type is stable,
2530 // and so it is sufficient to avoid reconciling it away.
2531 // We're not going to unwrap or actually use the new lazy type.
2532 needsCompareFamilies = true;
2533 }
2534
2535 break;
2536 }
2537
2538 case ForwardRef:
2539 {
2540 if ($$typeofNextType === REACT_FORWARD_REF_TYPE) {
2541 needsCompareFamilies = true;
2542 } else if ($$typeofNextType === REACT_LAZY_TYPE) {
2543 needsCompareFamilies = true;
2544 }
2545
2546 break;
2547 }
2548
2549 case MemoComponent:
2550 case SimpleMemoComponent:
2551 {
2552 if ($$typeofNextType === REACT_MEMO_TYPE) {
2553 // TODO: if it was but can no longer be simple,
2554 // we shouldn't set this.
2555 needsCompareFamilies = true;
2556 } else if ($$typeofNextType === REACT_LAZY_TYPE) {
2557 needsCompareFamilies = true;
2558 }
2559
2560 break;
2561 }
2562
2563 default:
2564 return false;
2565 } // Check if both types have a family and it's the same one.
2566
2567
2568 if (needsCompareFamilies) {
2569 // Note: memo() and forwardRef() we'll compare outer rather than inner type.
2570 // This means both of them need to be registered to preserve state.
2571 // If we unwrapped and compared the inner types for wrappers instead,
2572 // then we would risk falsely saying two separate memo(Foo)
2573 // calls are equivalent because they wrap the same Foo function.
2574 var prevFamily = resolveFamily(prevType);
2575
2576 if (prevFamily !== undefined && prevFamily === resolveFamily(nextType)) {
2577 return true;
2578 }
2579 }
2580
2581 return false;
2582 }
2583}
2584function markFailedErrorBoundaryForHotReloading(fiber) {
2585 {
2586 if (resolveFamily === null) {
2587 // Hot reloading is disabled.
2588 return;
2589 }
2590
2591 if (typeof WeakSet !== 'function') {
2592 return;
2593 }
2594
2595 if (failedBoundaries === null) {
2596 failedBoundaries = new WeakSet();
2597 }
2598
2599 failedBoundaries.add(fiber);
2600 }
2601}
2602var scheduleRefresh = function (root, update) {
2603 {
2604 if (resolveFamily === null) {
2605 // Hot reloading is disabled.
2606 return;
2607 }
2608
2609 var staleFamilies = update.staleFamilies,
2610 updatedFamilies = update.updatedFamilies;
2611 flushPassiveEffects();
2612 flushSync(function () {
2613 scheduleFibersWithFamiliesRecursively(root.current, updatedFamilies, staleFamilies);
2614 });
2615 }
2616};
2617var scheduleRoot = function (root, element) {
2618 {
2619 if (root.context !== emptyContextObject) {
2620 // Super edge case: root has a legacy _renderSubtree context
2621 // but we don't know the parentComponent so we can't pass it.
2622 // Just ignore. We'll delete this with _renderSubtree code path later.
2623 return;
2624 }
2625
2626 flushPassiveEffects();
2627 syncUpdates(function () {
2628 updateContainer(element, root, null, null);
2629 });
2630 }
2631};
2632
2633function scheduleFibersWithFamiliesRecursively(fiber, updatedFamilies, staleFamilies) {
2634 {
2635 var alternate = fiber.alternate,
2636 child = fiber.child,
2637 sibling = fiber.sibling,
2638 tag = fiber.tag,
2639 type = fiber.type;
2640 var candidateType = null;
2641
2642 switch (tag) {
2643 case FunctionComponent:
2644 case SimpleMemoComponent:
2645 case ClassComponent:
2646 candidateType = type;
2647 break;
2648
2649 case ForwardRef:
2650 candidateType = type.render;
2651 break;
2652 }
2653
2654 if (resolveFamily === null) {
2655 throw new Error('Expected resolveFamily to be set during hot reload.');
2656 }
2657
2658 var needsRender = false;
2659 var needsRemount = false;
2660
2661 if (candidateType !== null) {
2662 var family = resolveFamily(candidateType);
2663
2664 if (family !== undefined) {
2665 if (staleFamilies.has(family)) {
2666 needsRemount = true;
2667 } else if (updatedFamilies.has(family)) {
2668 if (tag === ClassComponent) {
2669 needsRemount = true;
2670 } else {
2671 needsRender = true;
2672 }
2673 }
2674 }
2675 }
2676
2677 if (failedBoundaries !== null) {
2678 if (failedBoundaries.has(fiber) || alternate !== null && failedBoundaries.has(alternate)) {
2679 needsRemount = true;
2680 }
2681 }
2682
2683 if (needsRemount) {
2684 fiber._debugNeedsRemount = true;
2685 }
2686
2687 if (needsRemount || needsRender) {
2688 scheduleWork(fiber, Sync);
2689 }
2690
2691 if (child !== null && !needsRemount) {
2692 scheduleFibersWithFamiliesRecursively(child, updatedFamilies, staleFamilies);
2693 }
2694
2695 if (sibling !== null) {
2696 scheduleFibersWithFamiliesRecursively(sibling, updatedFamilies, staleFamilies);
2697 }
2698 }
2699}
2700
2701var findHostInstancesForRefresh = function (root, families) {
2702 {
2703 var hostInstances = new Set();
2704 var types = new Set(families.map(function (family) {
2705 return family.current;
2706 }));
2707 findHostInstancesForMatchingFibersRecursively(root.current, types, hostInstances);
2708 return hostInstances;
2709 }
2710};
2711
2712function findHostInstancesForMatchingFibersRecursively(fiber, types, hostInstances) {
2713 {
2714 var child = fiber.child,
2715 sibling = fiber.sibling,
2716 tag = fiber.tag,
2717 type = fiber.type;
2718 var candidateType = null;
2719
2720 switch (tag) {
2721 case FunctionComponent:
2722 case SimpleMemoComponent:
2723 case ClassComponent:
2724 candidateType = type;
2725 break;
2726
2727 case ForwardRef:
2728 candidateType = type.render;
2729 break;
2730 }
2731
2732 var didMatch = false;
2733
2734 if (candidateType !== null) {
2735 if (types.has(candidateType)) {
2736 didMatch = true;
2737 }
2738 }
2739
2740 if (didMatch) {
2741 // We have a match. This only drills down to the closest host components.
2742 // There's no need to search deeper because for the purpose of giving
2743 // visual feedback, "flashing" outermost parent rectangles is sufficient.
2744 findHostInstancesForFiberShallowly(fiber, hostInstances);
2745 } else {
2746 // If there's no match, maybe there will be one further down in the child tree.
2747 if (child !== null) {
2748 findHostInstancesForMatchingFibersRecursively(child, types, hostInstances);
2749 }
2750 }
2751
2752 if (sibling !== null) {
2753 findHostInstancesForMatchingFibersRecursively(sibling, types, hostInstances);
2754 }
2755 }
2756}
2757
2758function findHostInstancesForFiberShallowly(fiber, hostInstances) {
2759 {
2760 var foundHostInstances = findChildHostInstancesForFiberShallowly(fiber, hostInstances);
2761
2762 if (foundHostInstances) {
2763 return;
2764 } // If we didn't find any host children, fallback to closest host parent.
2765
2766
2767 var node = fiber;
2768
2769 while (true) {
2770 switch (node.tag) {
2771 case HostComponent:
2772 hostInstances.add(node.stateNode);
2773 return;
2774
2775 case HostPortal:
2776 hostInstances.add(node.stateNode.containerInfo);
2777 return;
2778
2779 case HostRoot:
2780 hostInstances.add(node.stateNode.containerInfo);
2781 return;
2782 }
2783
2784 if (node.return === null) {
2785 throw new Error('Expected to reach root first.');
2786 }
2787
2788 node = node.return;
2789 }
2790 }
2791}
2792
2793function findChildHostInstancesForFiberShallowly(fiber, hostInstances) {
2794 {
2795 var node = fiber;
2796 var foundHostInstances = false;
2797
2798 while (true) {
2799 if (node.tag === HostComponent) {
2800 // We got a match.
2801 foundHostInstances = true;
2802 hostInstances.add(node.stateNode); // There may still be more, so keep searching.
2803 } else if (node.child !== null) {
2804 node.child.return = node;
2805 node = node.child;
2806 continue;
2807 }
2808
2809 if (node === fiber) {
2810 return foundHostInstances;
2811 }
2812
2813 while (node.sibling === null) {
2814 if (node.return === null || node.return === fiber) {
2815 return foundHostInstances;
2816 }
2817
2818 node = node.return;
2819 }
2820
2821 node.sibling.return = node.return;
2822 node = node.sibling;
2823 }
2824 }
2825
2826 return false;
2827}
2828
2829function resolveDefaultProps(Component, baseProps) {
2830 if (Component && Component.defaultProps) {
2831 // Resolve default props. Taken from ReactElement
2832 var props = _assign({}, baseProps);
2833
2834 var defaultProps = Component.defaultProps;
2835
2836 for (var propName in defaultProps) {
2837 if (props[propName] === undefined) {
2838 props[propName] = defaultProps[propName];
2839 }
2840 }
2841
2842 return props;
2843 }
2844
2845 return baseProps;
2846}
2847function readLazyComponentType(lazyComponent) {
2848 initializeLazyComponentType(lazyComponent);
2849
2850 if (lazyComponent._status !== Resolved) {
2851 throw lazyComponent._result;
2852 }
2853
2854 return lazyComponent._result;
2855}
2856
2857var valueCursor = createCursor(null);
2858var rendererSigil;
2859
2860{
2861 // Use this to detect multiple renderers using the same context
2862 rendererSigil = {};
2863}
2864
2865var currentlyRenderingFiber = null;
2866var lastContextDependency = null;
2867var lastContextWithAllBitsObserved = null;
2868var isDisallowedContextReadInDEV = false;
2869function resetContextDependencies() {
2870 // This is called right before React yields execution, to ensure `readContext`
2871 // cannot be called outside the render phase.
2872 currentlyRenderingFiber = null;
2873 lastContextDependency = null;
2874 lastContextWithAllBitsObserved = null;
2875
2876 {
2877 isDisallowedContextReadInDEV = false;
2878 }
2879}
2880function enterDisallowedContextReadInDEV() {
2881 {
2882 isDisallowedContextReadInDEV = true;
2883 }
2884}
2885function exitDisallowedContextReadInDEV() {
2886 {
2887 isDisallowedContextReadInDEV = false;
2888 }
2889}
2890function pushProvider(providerFiber, nextValue) {
2891 var context = providerFiber.type._context;
2892
2893 {
2894 push(valueCursor, context._currentValue2, providerFiber);
2895 context._currentValue2 = nextValue;
2896
2897 {
2898 if (context._currentRenderer2 !== undefined && context._currentRenderer2 !== null && context._currentRenderer2 !== rendererSigil) {
2899 error('Detected multiple renderers concurrently rendering the ' + 'same context provider. This is currently unsupported.');
2900 }
2901
2902 context._currentRenderer2 = rendererSigil;
2903 }
2904 }
2905}
2906function popProvider(providerFiber) {
2907 var currentValue = valueCursor.current;
2908 pop(valueCursor, providerFiber);
2909 var context = providerFiber.type._context;
2910
2911 {
2912 context._currentValue2 = currentValue;
2913 }
2914}
2915function calculateChangedBits(context, newValue, oldValue) {
2916 if (objectIs(oldValue, newValue)) {
2917 // No change
2918 return 0;
2919 } else {
2920 var changedBits = typeof context._calculateChangedBits === 'function' ? context._calculateChangedBits(oldValue, newValue) : MAX_SIGNED_31_BIT_INT;
2921
2922 {
2923 if ((changedBits & MAX_SIGNED_31_BIT_INT) !== changedBits) {
2924 error('calculateChangedBits: Expected the return value to be a ' + '31-bit integer. Instead received: %s', changedBits);
2925 }
2926 }
2927
2928 return changedBits | 0;
2929 }
2930}
2931function scheduleWorkOnParentPath(parent, renderExpirationTime) {
2932 // Update the child expiration time of all the ancestors, including
2933 // the alternates.
2934 var node = parent;
2935
2936 while (node !== null) {
2937 var alternate = node.alternate;
2938
2939 if (node.childExpirationTime < renderExpirationTime) {
2940 node.childExpirationTime = renderExpirationTime;
2941
2942 if (alternate !== null && alternate.childExpirationTime < renderExpirationTime) {
2943 alternate.childExpirationTime = renderExpirationTime;
2944 }
2945 } else if (alternate !== null && alternate.childExpirationTime < renderExpirationTime) {
2946 alternate.childExpirationTime = renderExpirationTime;
2947 } else {
2948 // Neither alternate was updated, which means the rest of the
2949 // ancestor path already has sufficient priority.
2950 break;
2951 }
2952
2953 node = node.return;
2954 }
2955}
2956function propagateContextChange(workInProgress, context, changedBits, renderExpirationTime) {
2957 var fiber = workInProgress.child;
2958
2959 if (fiber !== null) {
2960 // Set the return pointer of the child to the work-in-progress fiber.
2961 fiber.return = workInProgress;
2962 }
2963
2964 while (fiber !== null) {
2965 var nextFiber = void 0; // Visit this fiber.
2966
2967 var list = fiber.dependencies;
2968
2969 if (list !== null) {
2970 nextFiber = fiber.child;
2971 var dependency = list.firstContext;
2972
2973 while (dependency !== null) {
2974 // Check if the context matches.
2975 if (dependency.context === context && (dependency.observedBits & changedBits) !== 0) {
2976 // Match! Schedule an update on this fiber.
2977 if (fiber.tag === ClassComponent) {
2978 // Schedule a force update on the work-in-progress.
2979 var update = createUpdate(renderExpirationTime, null);
2980 update.tag = ForceUpdate; // TODO: Because we don't have a work-in-progress, this will add the
2981 // update to the current fiber, too, which means it will persist even if
2982 // this render is thrown away. Since it's a race condition, not sure it's
2983 // worth fixing.
2984
2985 enqueueUpdate(fiber, update);
2986 }
2987
2988 if (fiber.expirationTime < renderExpirationTime) {
2989 fiber.expirationTime = renderExpirationTime;
2990 }
2991
2992 var alternate = fiber.alternate;
2993
2994 if (alternate !== null && alternate.expirationTime < renderExpirationTime) {
2995 alternate.expirationTime = renderExpirationTime;
2996 }
2997
2998 scheduleWorkOnParentPath(fiber.return, renderExpirationTime); // Mark the expiration time on the list, too.
2999
3000 if (list.expirationTime < renderExpirationTime) {
3001 list.expirationTime = renderExpirationTime;
3002 } // Since we already found a match, we can stop traversing the
3003 // dependency list.
3004
3005
3006 break;
3007 }
3008
3009 dependency = dependency.next;
3010 }
3011 } else if (fiber.tag === ContextProvider) {
3012 // Don't scan deeper if this is a matching provider
3013 nextFiber = fiber.type === workInProgress.type ? null : fiber.child;
3014 } else {
3015 // Traverse down.
3016 nextFiber = fiber.child;
3017 }
3018
3019 if (nextFiber !== null) {
3020 // Set the return pointer of the child to the work-in-progress fiber.
3021 nextFiber.return = fiber;
3022 } else {
3023 // No child. Traverse to next sibling.
3024 nextFiber = fiber;
3025
3026 while (nextFiber !== null) {
3027 if (nextFiber === workInProgress) {
3028 // We're back to the root of this subtree. Exit.
3029 nextFiber = null;
3030 break;
3031 }
3032
3033 var sibling = nextFiber.sibling;
3034
3035 if (sibling !== null) {
3036 // Set the return pointer of the sibling to the work-in-progress fiber.
3037 sibling.return = nextFiber.return;
3038 nextFiber = sibling;
3039 break;
3040 } // No more siblings. Traverse up.
3041
3042
3043 nextFiber = nextFiber.return;
3044 }
3045 }
3046
3047 fiber = nextFiber;
3048 }
3049}
3050function prepareToReadContext(workInProgress, renderExpirationTime) {
3051 currentlyRenderingFiber = workInProgress;
3052 lastContextDependency = null;
3053 lastContextWithAllBitsObserved = null;
3054 var dependencies = workInProgress.dependencies;
3055
3056 if (dependencies !== null) {
3057 var firstContext = dependencies.firstContext;
3058
3059 if (firstContext !== null) {
3060 if (dependencies.expirationTime >= renderExpirationTime) {
3061 // Context list has a pending update. Mark that this fiber performed work.
3062 markWorkInProgressReceivedUpdate();
3063 } // Reset the work-in-progress list
3064
3065
3066 dependencies.firstContext = null;
3067 }
3068 }
3069}
3070function readContext(context, observedBits) {
3071 {
3072 // This warning would fire if you read context inside a Hook like useMemo.
3073 // Unlike the class check below, it's not enforced in production for perf.
3074 if (isDisallowedContextReadInDEV) {
3075 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().');
3076 }
3077 }
3078
3079 if (lastContextWithAllBitsObserved === context) ; else if (observedBits === false || observedBits === 0) ; else {
3080 var resolvedObservedBits; // Avoid deopting on observable arguments or heterogeneous types.
3081
3082 if (typeof observedBits !== 'number' || observedBits === MAX_SIGNED_31_BIT_INT) {
3083 // Observe all updates.
3084 lastContextWithAllBitsObserved = context;
3085 resolvedObservedBits = MAX_SIGNED_31_BIT_INT;
3086 } else {
3087 resolvedObservedBits = observedBits;
3088 }
3089
3090 var contextItem = {
3091 context: context,
3092 observedBits: resolvedObservedBits,
3093 next: null
3094 };
3095
3096 if (lastContextDependency === null) {
3097 if (!(currentlyRenderingFiber !== null)) {
3098 {
3099 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()." );
3100 }
3101 } // This is the first dependency for this component. Create a new list.
3102
3103
3104 lastContextDependency = contextItem;
3105 currentlyRenderingFiber.dependencies = {
3106 expirationTime: NoWork,
3107 firstContext: contextItem,
3108 responders: null
3109 };
3110 } else {
3111 // Append a new context item.
3112 lastContextDependency = lastContextDependency.next = contextItem;
3113 }
3114 }
3115
3116 return context._currentValue2;
3117}
3118
3119var UpdateState = 0;
3120var ReplaceState = 1;
3121var ForceUpdate = 2;
3122var CaptureUpdate = 3; // Global state that is reset at the beginning of calling `processUpdateQueue`.
3123// It should only be read right after calling `processUpdateQueue`, via
3124// `checkHasForceUpdateAfterProcessing`.
3125
3126var hasForceUpdate = false;
3127var didWarnUpdateInsideUpdate;
3128var currentlyProcessingQueue;
3129
3130{
3131 didWarnUpdateInsideUpdate = false;
3132 currentlyProcessingQueue = null;
3133}
3134
3135function initializeUpdateQueue(fiber) {
3136 var queue = {
3137 baseState: fiber.memoizedState,
3138 baseQueue: null,
3139 shared: {
3140 pending: null
3141 },
3142 effects: null
3143 };
3144 fiber.updateQueue = queue;
3145}
3146function cloneUpdateQueue(current, workInProgress) {
3147 // Clone the update queue from current. Unless it's already a clone.
3148 var queue = workInProgress.updateQueue;
3149 var currentQueue = current.updateQueue;
3150
3151 if (queue === currentQueue) {
3152 var clone = {
3153 baseState: currentQueue.baseState,
3154 baseQueue: currentQueue.baseQueue,
3155 shared: currentQueue.shared,
3156 effects: currentQueue.effects
3157 };
3158 workInProgress.updateQueue = clone;
3159 }
3160}
3161function createUpdate(expirationTime, suspenseConfig) {
3162 var update = {
3163 expirationTime: expirationTime,
3164 suspenseConfig: suspenseConfig,
3165 tag: UpdateState,
3166 payload: null,
3167 callback: null,
3168 next: null
3169 };
3170 update.next = update;
3171
3172 {
3173 update.priority = getCurrentPriorityLevel();
3174 }
3175
3176 return update;
3177}
3178function enqueueUpdate(fiber, update) {
3179 var updateQueue = fiber.updateQueue;
3180
3181 if (updateQueue === null) {
3182 // Only occurs if the fiber has been unmounted.
3183 return;
3184 }
3185
3186 var sharedQueue = updateQueue.shared;
3187 var pending = sharedQueue.pending;
3188
3189 if (pending === null) {
3190 // This is the first update. Create a circular list.
3191 update.next = update;
3192 } else {
3193 update.next = pending.next;
3194 pending.next = update;
3195 }
3196
3197 sharedQueue.pending = update;
3198
3199 {
3200 if (currentlyProcessingQueue === sharedQueue && !didWarnUpdateInsideUpdate) {
3201 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.');
3202
3203 didWarnUpdateInsideUpdate = true;
3204 }
3205 }
3206}
3207function enqueueCapturedUpdate(workInProgress, update) {
3208 var current = workInProgress.alternate;
3209
3210 if (current !== null) {
3211 // Ensure the work-in-progress queue is a clone
3212 cloneUpdateQueue(current, workInProgress);
3213 } // Captured updates go only on the work-in-progress queue.
3214
3215
3216 var queue = workInProgress.updateQueue; // Append the update to the end of the list.
3217
3218 var last = queue.baseQueue;
3219
3220 if (last === null) {
3221 queue.baseQueue = update.next = update;
3222 update.next = update;
3223 } else {
3224 update.next = last.next;
3225 last.next = update;
3226 }
3227}
3228
3229function getStateFromUpdate(workInProgress, queue, update, prevState, nextProps, instance) {
3230 switch (update.tag) {
3231 case ReplaceState:
3232 {
3233 var payload = update.payload;
3234
3235 if (typeof payload === 'function') {
3236 // Updater function
3237 {
3238 enterDisallowedContextReadInDEV();
3239
3240 if ( workInProgress.mode & StrictMode) {
3241 payload.call(instance, prevState, nextProps);
3242 }
3243 }
3244
3245 var nextState = payload.call(instance, prevState, nextProps);
3246
3247 {
3248 exitDisallowedContextReadInDEV();
3249 }
3250
3251 return nextState;
3252 } // State object
3253
3254
3255 return payload;
3256 }
3257
3258 case CaptureUpdate:
3259 {
3260 workInProgress.effectTag = workInProgress.effectTag & ~ShouldCapture | DidCapture;
3261 }
3262 // Intentional fallthrough
3263
3264 case UpdateState:
3265 {
3266 var _payload = update.payload;
3267 var partialState;
3268
3269 if (typeof _payload === 'function') {
3270 // Updater function
3271 {
3272 enterDisallowedContextReadInDEV();
3273
3274 if ( workInProgress.mode & StrictMode) {
3275 _payload.call(instance, prevState, nextProps);
3276 }
3277 }
3278
3279 partialState = _payload.call(instance, prevState, nextProps);
3280
3281 {
3282 exitDisallowedContextReadInDEV();
3283 }
3284 } else {
3285 // Partial state object
3286 partialState = _payload;
3287 }
3288
3289 if (partialState === null || partialState === undefined) {
3290 // Null and undefined are treated as no-ops.
3291 return prevState;
3292 } // Merge the partial state and the previous state.
3293
3294
3295 return _assign({}, prevState, partialState);
3296 }
3297
3298 case ForceUpdate:
3299 {
3300 hasForceUpdate = true;
3301 return prevState;
3302 }
3303 }
3304
3305 return prevState;
3306}
3307
3308function processUpdateQueue(workInProgress, props, instance, renderExpirationTime) {
3309 // This is always non-null on a ClassComponent or HostRoot
3310 var queue = workInProgress.updateQueue;
3311 hasForceUpdate = false;
3312
3313 {
3314 currentlyProcessingQueue = queue.shared;
3315 } // The last rebase update that is NOT part of the base state.
3316
3317
3318 var baseQueue = queue.baseQueue; // The last pending update that hasn't been processed yet.
3319
3320 var pendingQueue = queue.shared.pending;
3321
3322 if (pendingQueue !== null) {
3323 // We have new updates that haven't been processed yet.
3324 // We'll add them to the base queue.
3325 if (baseQueue !== null) {
3326 // Merge the pending queue and the base queue.
3327 var baseFirst = baseQueue.next;
3328 var pendingFirst = pendingQueue.next;
3329 baseQueue.next = pendingFirst;
3330 pendingQueue.next = baseFirst;
3331 }
3332
3333 baseQueue = pendingQueue;
3334 queue.shared.pending = null; // TODO: Pass `current` as argument
3335
3336 var current = workInProgress.alternate;
3337
3338 if (current !== null) {
3339 var currentQueue = current.updateQueue;
3340
3341 if (currentQueue !== null) {
3342 currentQueue.baseQueue = pendingQueue;
3343 }
3344 }
3345 } // These values may change as we process the queue.
3346
3347
3348 if (baseQueue !== null) {
3349 var first = baseQueue.next; // Iterate through the list of updates to compute the result.
3350
3351 var newState = queue.baseState;
3352 var newExpirationTime = NoWork;
3353 var newBaseState = null;
3354 var newBaseQueueFirst = null;
3355 var newBaseQueueLast = null;
3356
3357 if (first !== null) {
3358 var update = first;
3359
3360 do {
3361 var updateExpirationTime = update.expirationTime;
3362
3363 if (updateExpirationTime < renderExpirationTime) {
3364 // Priority is insufficient. Skip this update. If this is the first
3365 // skipped update, the previous update/state is the new base
3366 // update/state.
3367 var clone = {
3368 expirationTime: update.expirationTime,
3369 suspenseConfig: update.suspenseConfig,
3370 tag: update.tag,
3371 payload: update.payload,
3372 callback: update.callback,
3373 next: null
3374 };
3375
3376 if (newBaseQueueLast === null) {
3377 newBaseQueueFirst = newBaseQueueLast = clone;
3378 newBaseState = newState;
3379 } else {
3380 newBaseQueueLast = newBaseQueueLast.next = clone;
3381 } // Update the remaining priority in the queue.
3382
3383
3384 if (updateExpirationTime > newExpirationTime) {
3385 newExpirationTime = updateExpirationTime;
3386 }
3387 } else {
3388 // This update does have sufficient priority.
3389 if (newBaseQueueLast !== null) {
3390 var _clone = {
3391 expirationTime: Sync,
3392 // This update is going to be committed so we never want uncommit it.
3393 suspenseConfig: update.suspenseConfig,
3394 tag: update.tag,
3395 payload: update.payload,
3396 callback: update.callback,
3397 next: null
3398 };
3399 newBaseQueueLast = newBaseQueueLast.next = _clone;
3400 } // Mark the event time of this update as relevant to this render pass.
3401 // TODO: This should ideally use the true event time of this update rather than
3402 // its priority which is a derived and not reverseable value.
3403 // TODO: We should skip this update if it was already committed but currently
3404 // we have no way of detecting the difference between a committed and suspended
3405 // update here.
3406
3407
3408 markRenderEventTimeAndConfig(updateExpirationTime, update.suspenseConfig); // Process this update.
3409
3410 newState = getStateFromUpdate(workInProgress, queue, update, newState, props, instance);
3411 var callback = update.callback;
3412
3413 if (callback !== null) {
3414 workInProgress.effectTag |= Callback;
3415 var effects = queue.effects;
3416
3417 if (effects === null) {
3418 queue.effects = [update];
3419 } else {
3420 effects.push(update);
3421 }
3422 }
3423 }
3424
3425 update = update.next;
3426
3427 if (update === null || update === first) {
3428 pendingQueue = queue.shared.pending;
3429
3430 if (pendingQueue === null) {
3431 break;
3432 } else {
3433 // An update was scheduled from inside a reducer. Add the new
3434 // pending updates to the end of the list and keep processing.
3435 update = baseQueue.next = pendingQueue.next;
3436 pendingQueue.next = first;
3437 queue.baseQueue = baseQueue = pendingQueue;
3438 queue.shared.pending = null;
3439 }
3440 }
3441 } while (true);
3442 }
3443
3444 if (newBaseQueueLast === null) {
3445 newBaseState = newState;
3446 } else {
3447 newBaseQueueLast.next = newBaseQueueFirst;
3448 }
3449
3450 queue.baseState = newBaseState;
3451 queue.baseQueue = newBaseQueueLast; // Set the remaining expiration time to be whatever is remaining in the queue.
3452 // This should be fine because the only two other things that contribute to
3453 // expiration time are props and context. We're already in the middle of the
3454 // begin phase by the time we start processing the queue, so we've already
3455 // dealt with the props. Context in components that specify
3456 // shouldComponentUpdate is tricky; but we'll have to account for
3457 // that regardless.
3458
3459 markUnprocessedUpdateTime(newExpirationTime);
3460 workInProgress.expirationTime = newExpirationTime;
3461 workInProgress.memoizedState = newState;
3462 }
3463
3464 {
3465 currentlyProcessingQueue = null;
3466 }
3467}
3468
3469function callCallback(callback, context) {
3470 if (!(typeof callback === 'function')) {
3471 {
3472 throw Error( "Invalid argument passed as callback. Expected a function. Instead received: " + callback );
3473 }
3474 }
3475
3476 callback.call(context);
3477}
3478
3479function resetHasForceUpdateBeforeProcessing() {
3480 hasForceUpdate = false;
3481}
3482function checkHasForceUpdateAfterProcessing() {
3483 return hasForceUpdate;
3484}
3485function commitUpdateQueue(finishedWork, finishedQueue, instance) {
3486 // Commit the effects
3487 var effects = finishedQueue.effects;
3488 finishedQueue.effects = null;
3489
3490 if (effects !== null) {
3491 for (var i = 0; i < effects.length; i++) {
3492 var effect = effects[i];
3493 var callback = effect.callback;
3494
3495 if (callback !== null) {
3496 effect.callback = null;
3497 callCallback(callback, instance);
3498 }
3499 }
3500 }
3501}
3502
3503var ReactCurrentBatchConfig = ReactSharedInternals.ReactCurrentBatchConfig;
3504function requestCurrentSuspenseConfig() {
3505 return ReactCurrentBatchConfig.suspense;
3506}
3507
3508var fakeInternalInstance = {};
3509var isArray = Array.isArray; // React.Component uses a shared frozen object by default.
3510// We'll use it to determine whether we need to initialize legacy refs.
3511
3512var emptyRefsObject = new React.Component().refs;
3513var didWarnAboutStateAssignmentForComponent;
3514var didWarnAboutUninitializedState;
3515var didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate;
3516var didWarnAboutLegacyLifecyclesAndDerivedState;
3517var didWarnAboutUndefinedDerivedState;
3518var warnOnUndefinedDerivedState;
3519var warnOnInvalidCallback;
3520var didWarnAboutDirectlyAssigningPropsToState;
3521var didWarnAboutContextTypeAndContextTypes;
3522var didWarnAboutInvalidateContextType;
3523
3524{
3525 didWarnAboutStateAssignmentForComponent = new Set();
3526 didWarnAboutUninitializedState = new Set();
3527 didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate = new Set();
3528 didWarnAboutLegacyLifecyclesAndDerivedState = new Set();
3529 didWarnAboutDirectlyAssigningPropsToState = new Set();
3530 didWarnAboutUndefinedDerivedState = new Set();
3531 didWarnAboutContextTypeAndContextTypes = new Set();
3532 didWarnAboutInvalidateContextType = new Set();
3533 var didWarnOnInvalidCallback = new Set();
3534
3535 warnOnInvalidCallback = function (callback, callerName) {
3536 if (callback === null || typeof callback === 'function') {
3537 return;
3538 }
3539
3540 var key = callerName + "_" + callback;
3541
3542 if (!didWarnOnInvalidCallback.has(key)) {
3543 didWarnOnInvalidCallback.add(key);
3544
3545 error('%s(...): Expected the last optional `callback` argument to be a ' + 'function. Instead received: %s.', callerName, callback);
3546 }
3547 };
3548
3549 warnOnUndefinedDerivedState = function (type, partialState) {
3550 if (partialState === undefined) {
3551 var componentName = getComponentName(type) || 'Component';
3552
3553 if (!didWarnAboutUndefinedDerivedState.has(componentName)) {
3554 didWarnAboutUndefinedDerivedState.add(componentName);
3555
3556 error('%s.getDerivedStateFromProps(): A valid state object (or null) must be returned. ' + 'You have returned undefined.', componentName);
3557 }
3558 }
3559 }; // This is so gross but it's at least non-critical and can be removed if
3560 // it causes problems. This is meant to give a nicer error message for
3561 // ReactDOM15.unstable_renderSubtreeIntoContainer(reactDOM16Component,
3562 // ...)) which otherwise throws a "_processChildContext is not a function"
3563 // exception.
3564
3565
3566 Object.defineProperty(fakeInternalInstance, '_processChildContext', {
3567 enumerable: false,
3568 value: function () {
3569 {
3570 {
3571 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)." );
3572 }
3573 }
3574 }
3575 });
3576 Object.freeze(fakeInternalInstance);
3577}
3578
3579function applyDerivedStateFromProps(workInProgress, ctor, getDerivedStateFromProps, nextProps) {
3580 var prevState = workInProgress.memoizedState;
3581
3582 {
3583 if ( workInProgress.mode & StrictMode) {
3584 // Invoke the function an extra time to help detect side-effects.
3585 getDerivedStateFromProps(nextProps, prevState);
3586 }
3587 }
3588
3589 var partialState = getDerivedStateFromProps(nextProps, prevState);
3590
3591 {
3592 warnOnUndefinedDerivedState(ctor, partialState);
3593 } // Merge the partial state and the previous state.
3594
3595
3596 var memoizedState = partialState === null || partialState === undefined ? prevState : _assign({}, prevState, partialState);
3597 workInProgress.memoizedState = memoizedState; // Once the update queue is empty, persist the derived state onto the
3598 // base state.
3599
3600 if (workInProgress.expirationTime === NoWork) {
3601 // Queue is always non-null for classes
3602 var updateQueue = workInProgress.updateQueue;
3603 updateQueue.baseState = memoizedState;
3604 }
3605}
3606var classComponentUpdater = {
3607 isMounted: isMounted,
3608 enqueueSetState: function (inst, payload, callback) {
3609 var fiber = get(inst);
3610 var currentTime = requestCurrentTimeForUpdate();
3611 var suspenseConfig = requestCurrentSuspenseConfig();
3612 var expirationTime = computeExpirationForFiber(currentTime, fiber, suspenseConfig);
3613 var update = createUpdate(expirationTime, suspenseConfig);
3614 update.payload = payload;
3615
3616 if (callback !== undefined && callback !== null) {
3617 {
3618 warnOnInvalidCallback(callback, 'setState');
3619 }
3620
3621 update.callback = callback;
3622 }
3623
3624 enqueueUpdate(fiber, update);
3625 scheduleWork(fiber, expirationTime);
3626 },
3627 enqueueReplaceState: function (inst, payload, callback) {
3628 var fiber = get(inst);
3629 var currentTime = requestCurrentTimeForUpdate();
3630 var suspenseConfig = requestCurrentSuspenseConfig();
3631 var expirationTime = computeExpirationForFiber(currentTime, fiber, suspenseConfig);
3632 var update = createUpdate(expirationTime, suspenseConfig);
3633 update.tag = ReplaceState;
3634 update.payload = payload;
3635
3636 if (callback !== undefined && callback !== null) {
3637 {
3638 warnOnInvalidCallback(callback, 'replaceState');
3639 }
3640
3641 update.callback = callback;
3642 }
3643
3644 enqueueUpdate(fiber, update);
3645 scheduleWork(fiber, expirationTime);
3646 },
3647 enqueueForceUpdate: function (inst, callback) {
3648 var fiber = get(inst);
3649 var currentTime = requestCurrentTimeForUpdate();
3650 var suspenseConfig = requestCurrentSuspenseConfig();
3651 var expirationTime = computeExpirationForFiber(currentTime, fiber, suspenseConfig);
3652 var update = createUpdate(expirationTime, suspenseConfig);
3653 update.tag = ForceUpdate;
3654
3655 if (callback !== undefined && callback !== null) {
3656 {
3657 warnOnInvalidCallback(callback, 'forceUpdate');
3658 }
3659
3660 update.callback = callback;
3661 }
3662
3663 enqueueUpdate(fiber, update);
3664 scheduleWork(fiber, expirationTime);
3665 }
3666};
3667
3668function checkShouldComponentUpdate(workInProgress, ctor, oldProps, newProps, oldState, newState, nextContext) {
3669 var instance = workInProgress.stateNode;
3670
3671 if (typeof instance.shouldComponentUpdate === 'function') {
3672 {
3673 if ( workInProgress.mode & StrictMode) {
3674 // Invoke the function an extra time to help detect side-effects.
3675 instance.shouldComponentUpdate(newProps, newState, nextContext);
3676 }
3677 }
3678
3679 startPhaseTimer(workInProgress, 'shouldComponentUpdate');
3680 var shouldUpdate = instance.shouldComponentUpdate(newProps, newState, nextContext);
3681 stopPhaseTimer();
3682
3683 {
3684 if (shouldUpdate === undefined) {
3685 error('%s.shouldComponentUpdate(): Returned undefined instead of a ' + 'boolean value. Make sure to return true or false.', getComponentName(ctor) || 'Component');
3686 }
3687 }
3688
3689 return shouldUpdate;
3690 }
3691
3692 if (ctor.prototype && ctor.prototype.isPureReactComponent) {
3693 return !shallowEqual(oldProps, newProps) || !shallowEqual(oldState, newState);
3694 }
3695
3696 return true;
3697}
3698
3699function checkClassInstance(workInProgress, ctor, newProps) {
3700 var instance = workInProgress.stateNode;
3701
3702 {
3703 var name = getComponentName(ctor) || 'Component';
3704 var renderPresent = instance.render;
3705
3706 if (!renderPresent) {
3707 if (ctor.prototype && typeof ctor.prototype.render === 'function') {
3708 error('%s(...): No `render` method found on the returned component ' + 'instance: did you accidentally return an object from the constructor?', name);
3709 } else {
3710 error('%s(...): No `render` method found on the returned component ' + 'instance: you may have forgotten to define `render`.', name);
3711 }
3712 }
3713
3714 if (instance.getInitialState && !instance.getInitialState.isReactClassApproved && !instance.state) {
3715 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);
3716 }
3717
3718 if (instance.getDefaultProps && !instance.getDefaultProps.isReactClassApproved) {
3719 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);
3720 }
3721
3722 if (instance.propTypes) {
3723 error('propTypes was defined as an instance property on %s. Use a static ' + 'property to define propTypes instead.', name);
3724 }
3725
3726 if (instance.contextType) {
3727 error('contextType was defined as an instance property on %s. Use a static ' + 'property to define contextType instead.', name);
3728 }
3729
3730 {
3731 if (instance.contextTypes) {
3732 error('contextTypes was defined as an instance property on %s. Use a static ' + 'property to define contextTypes instead.', name);
3733 }
3734
3735 if (ctor.contextType && ctor.contextTypes && !didWarnAboutContextTypeAndContextTypes.has(ctor)) {
3736 didWarnAboutContextTypeAndContextTypes.add(ctor);
3737
3738 error('%s declares both contextTypes and contextType static properties. ' + 'The legacy contextTypes property will be ignored.', name);
3739 }
3740 }
3741
3742 if (typeof instance.componentShouldUpdate === 'function') {
3743 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);
3744 }
3745
3746 if (ctor.prototype && ctor.prototype.isPureReactComponent && typeof instance.shouldComponentUpdate !== 'undefined') {
3747 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');
3748 }
3749
3750 if (typeof instance.componentDidUnmount === 'function') {
3751 error('%s has a method called ' + 'componentDidUnmount(). But there is no such lifecycle method. ' + 'Did you mean componentWillUnmount()?', name);
3752 }
3753
3754 if (typeof instance.componentDidReceiveProps === 'function') {
3755 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);
3756 }
3757
3758 if (typeof instance.componentWillRecieveProps === 'function') {
3759 error('%s has a method called ' + 'componentWillRecieveProps(). Did you mean componentWillReceiveProps()?', name);
3760 }
3761
3762 if (typeof instance.UNSAFE_componentWillRecieveProps === 'function') {
3763 error('%s has a method called ' + 'UNSAFE_componentWillRecieveProps(). Did you mean UNSAFE_componentWillReceiveProps()?', name);
3764 }
3765
3766 var hasMutatedProps = instance.props !== newProps;
3767
3768 if (instance.props !== undefined && hasMutatedProps) {
3769 error('%s(...): When calling super() in `%s`, make sure to pass ' + "up the same props that your component's constructor was passed.", name, name);
3770 }
3771
3772 if (instance.defaultProps) {
3773 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);
3774 }
3775
3776 if (typeof instance.getSnapshotBeforeUpdate === 'function' && typeof instance.componentDidUpdate !== 'function' && !didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate.has(ctor)) {
3777 didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate.add(ctor);
3778
3779 error('%s: getSnapshotBeforeUpdate() should be used with componentDidUpdate(). ' + 'This component defines getSnapshotBeforeUpdate() only.', getComponentName(ctor));
3780 }
3781
3782 if (typeof instance.getDerivedStateFromProps === 'function') {
3783 error('%s: getDerivedStateFromProps() is defined as an instance method ' + 'and will be ignored. Instead, declare it as a static method.', name);
3784 }
3785
3786 if (typeof instance.getDerivedStateFromError === 'function') {
3787 error('%s: getDerivedStateFromError() is defined as an instance method ' + 'and will be ignored. Instead, declare it as a static method.', name);
3788 }
3789
3790 if (typeof ctor.getSnapshotBeforeUpdate === 'function') {
3791 error('%s: getSnapshotBeforeUpdate() is defined as a static method ' + 'and will be ignored. Instead, declare it as an instance method.', name);
3792 }
3793
3794 var _state = instance.state;
3795
3796 if (_state && (typeof _state !== 'object' || isArray(_state))) {
3797 error('%s.state: must be set to an object or null', name);
3798 }
3799
3800 if (typeof instance.getChildContext === 'function' && typeof ctor.childContextTypes !== 'object') {
3801 error('%s.getChildContext(): childContextTypes must be defined in order to ' + 'use getChildContext().', name);
3802 }
3803 }
3804}
3805
3806function adoptClassInstance(workInProgress, instance) {
3807 instance.updater = classComponentUpdater;
3808 workInProgress.stateNode = instance; // The instance needs access to the fiber so that it can schedule updates
3809
3810 set(instance, workInProgress);
3811
3812 {
3813 instance._reactInternalInstance = fakeInternalInstance;
3814 }
3815}
3816
3817function constructClassInstance(workInProgress, ctor, props) {
3818 var isLegacyContextConsumer = false;
3819 var unmaskedContext = emptyContextObject;
3820 var context = emptyContextObject;
3821 var contextType = ctor.contextType;
3822
3823 {
3824 if ('contextType' in ctor) {
3825 var isValid = // Allow null for conditional declaration
3826 contextType === null || contextType !== undefined && contextType.$$typeof === REACT_CONTEXT_TYPE && contextType._context === undefined; // Not a <Context.Consumer>
3827
3828 if (!isValid && !didWarnAboutInvalidateContextType.has(ctor)) {
3829 didWarnAboutInvalidateContextType.add(ctor);
3830 var addendum = '';
3831
3832 if (contextType === undefined) {
3833 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.';
3834 } else if (typeof contextType !== 'object') {
3835 addendum = ' However, it is set to a ' + typeof contextType + '.';
3836 } else if (contextType.$$typeof === REACT_PROVIDER_TYPE) {
3837 addendum = ' Did you accidentally pass the Context.Provider instead?';
3838 } else if (contextType._context !== undefined) {
3839 // <Context.Consumer>
3840 addendum = ' Did you accidentally pass the Context.Consumer instead?';
3841 } else {
3842 addendum = ' However, it is set to an object with keys {' + Object.keys(contextType).join(', ') + '}.';
3843 }
3844
3845 error('%s defines an invalid contextType. ' + 'contextType should point to the Context object returned by React.createContext().%s', getComponentName(ctor) || 'Component', addendum);
3846 }
3847 }
3848 }
3849
3850 if (typeof contextType === 'object' && contextType !== null) {
3851 context = readContext(contextType);
3852 } else {
3853 unmaskedContext = getUnmaskedContext(workInProgress, ctor, true);
3854 var contextTypes = ctor.contextTypes;
3855 isLegacyContextConsumer = contextTypes !== null && contextTypes !== undefined;
3856 context = isLegacyContextConsumer ? getMaskedContext(workInProgress, unmaskedContext) : emptyContextObject;
3857 } // Instantiate twice to help detect side-effects.
3858
3859
3860 {
3861 if ( workInProgress.mode & StrictMode) {
3862 new ctor(props, context); // eslint-disable-line no-new
3863 }
3864 }
3865
3866 var instance = new ctor(props, context);
3867 var state = workInProgress.memoizedState = instance.state !== null && instance.state !== undefined ? instance.state : null;
3868 adoptClassInstance(workInProgress, instance);
3869
3870 {
3871 if (typeof ctor.getDerivedStateFromProps === 'function' && state === null) {
3872 var componentName = getComponentName(ctor) || 'Component';
3873
3874 if (!didWarnAboutUninitializedState.has(componentName)) {
3875 didWarnAboutUninitializedState.add(componentName);
3876
3877 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);
3878 }
3879 } // If new component APIs are defined, "unsafe" lifecycles won't be called.
3880 // Warn about these lifecycles if they are present.
3881 // Don't warn about react-lifecycles-compat polyfilled methods though.
3882
3883
3884 if (typeof ctor.getDerivedStateFromProps === 'function' || typeof instance.getSnapshotBeforeUpdate === 'function') {
3885 var foundWillMountName = null;
3886 var foundWillReceivePropsName = null;
3887 var foundWillUpdateName = null;
3888
3889 if (typeof instance.componentWillMount === 'function' && instance.componentWillMount.__suppressDeprecationWarning !== true) {
3890 foundWillMountName = 'componentWillMount';
3891 } else if (typeof instance.UNSAFE_componentWillMount === 'function') {
3892 foundWillMountName = 'UNSAFE_componentWillMount';
3893 }
3894
3895 if (typeof instance.componentWillReceiveProps === 'function' && instance.componentWillReceiveProps.__suppressDeprecationWarning !== true) {
3896 foundWillReceivePropsName = 'componentWillReceiveProps';
3897 } else if (typeof instance.UNSAFE_componentWillReceiveProps === 'function') {
3898 foundWillReceivePropsName = 'UNSAFE_componentWillReceiveProps';
3899 }
3900
3901 if (typeof instance.componentWillUpdate === 'function' && instance.componentWillUpdate.__suppressDeprecationWarning !== true) {
3902 foundWillUpdateName = 'componentWillUpdate';
3903 } else if (typeof instance.UNSAFE_componentWillUpdate === 'function') {
3904 foundWillUpdateName = 'UNSAFE_componentWillUpdate';
3905 }
3906
3907 if (foundWillMountName !== null || foundWillReceivePropsName !== null || foundWillUpdateName !== null) {
3908 var _componentName = getComponentName(ctor) || 'Component';
3909
3910 var newApiName = typeof ctor.getDerivedStateFromProps === 'function' ? 'getDerivedStateFromProps()' : 'getSnapshotBeforeUpdate()';
3911
3912 if (!didWarnAboutLegacyLifecyclesAndDerivedState.has(_componentName)) {
3913 didWarnAboutLegacyLifecyclesAndDerivedState.add(_componentName);
3914
3915 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 : '');
3916 }
3917 }
3918 }
3919 } // Cache unmasked context so we can avoid recreating masked context unless necessary.
3920 // ReactFiberContext usually updates this cache but can't for newly-created instances.
3921
3922
3923 if (isLegacyContextConsumer) {
3924 cacheContext(workInProgress, unmaskedContext, context);
3925 }
3926
3927 return instance;
3928}
3929
3930function callComponentWillMount(workInProgress, instance) {
3931 startPhaseTimer(workInProgress, 'componentWillMount');
3932 var oldState = instance.state;
3933
3934 if (typeof instance.componentWillMount === 'function') {
3935 instance.componentWillMount();
3936 }
3937
3938 if (typeof instance.UNSAFE_componentWillMount === 'function') {
3939 instance.UNSAFE_componentWillMount();
3940 }
3941
3942 stopPhaseTimer();
3943
3944 if (oldState !== instance.state) {
3945 {
3946 error('%s.componentWillMount(): Assigning directly to this.state is ' + "deprecated (except inside a component's " + 'constructor). Use setState instead.', getComponentName(workInProgress.type) || 'Component');
3947 }
3948
3949 classComponentUpdater.enqueueReplaceState(instance, instance.state, null);
3950 }
3951}
3952
3953function callComponentWillReceiveProps(workInProgress, instance, newProps, nextContext) {
3954 var oldState = instance.state;
3955 startPhaseTimer(workInProgress, 'componentWillReceiveProps');
3956
3957 if (typeof instance.componentWillReceiveProps === 'function') {
3958 instance.componentWillReceiveProps(newProps, nextContext);
3959 }
3960
3961 if (typeof instance.UNSAFE_componentWillReceiveProps === 'function') {
3962 instance.UNSAFE_componentWillReceiveProps(newProps, nextContext);
3963 }
3964
3965 stopPhaseTimer();
3966
3967 if (instance.state !== oldState) {
3968 {
3969 var componentName = getComponentName(workInProgress.type) || 'Component';
3970
3971 if (!didWarnAboutStateAssignmentForComponent.has(componentName)) {
3972 didWarnAboutStateAssignmentForComponent.add(componentName);
3973
3974 error('%s.componentWillReceiveProps(): Assigning directly to ' + "this.state is deprecated (except inside a component's " + 'constructor). Use setState instead.', componentName);
3975 }
3976 }
3977
3978 classComponentUpdater.enqueueReplaceState(instance, instance.state, null);
3979 }
3980} // Invokes the mount life-cycles on a previously never rendered instance.
3981
3982
3983function mountClassInstance(workInProgress, ctor, newProps, renderExpirationTime) {
3984 {
3985 checkClassInstance(workInProgress, ctor, newProps);
3986 }
3987
3988 var instance = workInProgress.stateNode;
3989 instance.props = newProps;
3990 instance.state = workInProgress.memoizedState;
3991 instance.refs = emptyRefsObject;
3992 initializeUpdateQueue(workInProgress);
3993 var contextType = ctor.contextType;
3994
3995 if (typeof contextType === 'object' && contextType !== null) {
3996 instance.context = readContext(contextType);
3997 } else {
3998 var unmaskedContext = getUnmaskedContext(workInProgress, ctor, true);
3999 instance.context = getMaskedContext(workInProgress, unmaskedContext);
4000 }
4001
4002 {
4003 if (instance.state === newProps) {
4004 var componentName = getComponentName(ctor) || 'Component';
4005
4006 if (!didWarnAboutDirectlyAssigningPropsToState.has(componentName)) {
4007 didWarnAboutDirectlyAssigningPropsToState.add(componentName);
4008
4009 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);
4010 }
4011 }
4012
4013 if (workInProgress.mode & StrictMode) {
4014 ReactStrictModeWarnings.recordLegacyContextWarning(workInProgress, instance);
4015 }
4016
4017 {
4018 ReactStrictModeWarnings.recordUnsafeLifecycleWarnings(workInProgress, instance);
4019 }
4020 }
4021
4022 processUpdateQueue(workInProgress, newProps, instance, renderExpirationTime);
4023 instance.state = workInProgress.memoizedState;
4024 var getDerivedStateFromProps = ctor.getDerivedStateFromProps;
4025
4026 if (typeof getDerivedStateFromProps === 'function') {
4027 applyDerivedStateFromProps(workInProgress, ctor, getDerivedStateFromProps, newProps);
4028 instance.state = workInProgress.memoizedState;
4029 } // In order to support react-lifecycles-compat polyfilled components,
4030 // Unsafe lifecycles should not be invoked for components using the new APIs.
4031
4032
4033 if (typeof ctor.getDerivedStateFromProps !== 'function' && typeof instance.getSnapshotBeforeUpdate !== 'function' && (typeof instance.UNSAFE_componentWillMount === 'function' || typeof instance.componentWillMount === 'function')) {
4034 callComponentWillMount(workInProgress, instance); // If we had additional state updates during this life-cycle, let's
4035 // process them now.
4036
4037 processUpdateQueue(workInProgress, newProps, instance, renderExpirationTime);
4038 instance.state = workInProgress.memoizedState;
4039 }
4040
4041 if (typeof instance.componentDidMount === 'function') {
4042 workInProgress.effectTag |= Update;
4043 }
4044}
4045
4046function resumeMountClassInstance(workInProgress, ctor, newProps, renderExpirationTime) {
4047 var instance = workInProgress.stateNode;
4048 var oldProps = workInProgress.memoizedProps;
4049 instance.props = oldProps;
4050 var oldContext = instance.context;
4051 var contextType = ctor.contextType;
4052 var nextContext = emptyContextObject;
4053
4054 if (typeof contextType === 'object' && contextType !== null) {
4055 nextContext = readContext(contextType);
4056 } else {
4057 var nextLegacyUnmaskedContext = getUnmaskedContext(workInProgress, ctor, true);
4058 nextContext = getMaskedContext(workInProgress, nextLegacyUnmaskedContext);
4059 }
4060
4061 var getDerivedStateFromProps = ctor.getDerivedStateFromProps;
4062 var hasNewLifecycles = typeof getDerivedStateFromProps === 'function' || typeof instance.getSnapshotBeforeUpdate === 'function'; // Note: During these life-cycles, instance.props/instance.state are what
4063 // ever the previously attempted to render - not the "current". However,
4064 // during componentDidUpdate we pass the "current" props.
4065 // In order to support react-lifecycles-compat polyfilled components,
4066 // Unsafe lifecycles should not be invoked for components using the new APIs.
4067
4068 if (!hasNewLifecycles && (typeof instance.UNSAFE_componentWillReceiveProps === 'function' || typeof instance.componentWillReceiveProps === 'function')) {
4069 if (oldProps !== newProps || oldContext !== nextContext) {
4070 callComponentWillReceiveProps(workInProgress, instance, newProps, nextContext);
4071 }
4072 }
4073
4074 resetHasForceUpdateBeforeProcessing();
4075 var oldState = workInProgress.memoizedState;
4076 var newState = instance.state = oldState;
4077 processUpdateQueue(workInProgress, newProps, instance, renderExpirationTime);
4078 newState = workInProgress.memoizedState;
4079
4080 if (oldProps === newProps && oldState === newState && !hasContextChanged() && !checkHasForceUpdateAfterProcessing()) {
4081 // If an update was already in progress, we should schedule an Update
4082 // effect even though we're bailing out, so that cWU/cDU are called.
4083 if (typeof instance.componentDidMount === 'function') {
4084 workInProgress.effectTag |= Update;
4085 }
4086
4087 return false;
4088 }
4089
4090 if (typeof getDerivedStateFromProps === 'function') {
4091 applyDerivedStateFromProps(workInProgress, ctor, getDerivedStateFromProps, newProps);
4092 newState = workInProgress.memoizedState;
4093 }
4094
4095 var shouldUpdate = checkHasForceUpdateAfterProcessing() || checkShouldComponentUpdate(workInProgress, ctor, oldProps, newProps, oldState, newState, nextContext);
4096
4097 if (shouldUpdate) {
4098 // In order to support react-lifecycles-compat polyfilled components,
4099 // Unsafe lifecycles should not be invoked for components using the new APIs.
4100 if (!hasNewLifecycles && (typeof instance.UNSAFE_componentWillMount === 'function' || typeof instance.componentWillMount === 'function')) {
4101 startPhaseTimer(workInProgress, 'componentWillMount');
4102
4103 if (typeof instance.componentWillMount === 'function') {
4104 instance.componentWillMount();
4105 }
4106
4107 if (typeof instance.UNSAFE_componentWillMount === 'function') {
4108 instance.UNSAFE_componentWillMount();
4109 }
4110
4111 stopPhaseTimer();
4112 }
4113
4114 if (typeof instance.componentDidMount === 'function') {
4115 workInProgress.effectTag |= Update;
4116 }
4117 } else {
4118 // If an update was already in progress, we should schedule an Update
4119 // effect even though we're bailing out, so that cWU/cDU are called.
4120 if (typeof instance.componentDidMount === 'function') {
4121 workInProgress.effectTag |= Update;
4122 } // If shouldComponentUpdate returned false, we should still update the
4123 // memoized state to indicate that this work can be reused.
4124
4125
4126 workInProgress.memoizedProps = newProps;
4127 workInProgress.memoizedState = newState;
4128 } // Update the existing instance's state, props, and context pointers even
4129 // if shouldComponentUpdate returns false.
4130
4131
4132 instance.props = newProps;
4133 instance.state = newState;
4134 instance.context = nextContext;
4135 return shouldUpdate;
4136} // Invokes the update life-cycles and returns false if it shouldn't rerender.
4137
4138
4139function updateClassInstance(current, workInProgress, ctor, newProps, renderExpirationTime) {
4140 var instance = workInProgress.stateNode;
4141 cloneUpdateQueue(current, workInProgress);
4142 var oldProps = workInProgress.memoizedProps;
4143 instance.props = workInProgress.type === workInProgress.elementType ? oldProps : resolveDefaultProps(workInProgress.type, oldProps);
4144 var oldContext = instance.context;
4145 var contextType = ctor.contextType;
4146 var nextContext = emptyContextObject;
4147
4148 if (typeof contextType === 'object' && contextType !== null) {
4149 nextContext = readContext(contextType);
4150 } else {
4151 var nextUnmaskedContext = getUnmaskedContext(workInProgress, ctor, true);
4152 nextContext = getMaskedContext(workInProgress, nextUnmaskedContext);
4153 }
4154
4155 var getDerivedStateFromProps = ctor.getDerivedStateFromProps;
4156 var hasNewLifecycles = typeof getDerivedStateFromProps === 'function' || typeof instance.getSnapshotBeforeUpdate === 'function'; // Note: During these life-cycles, instance.props/instance.state are what
4157 // ever the previously attempted to render - not the "current". However,
4158 // during componentDidUpdate we pass the "current" props.
4159 // In order to support react-lifecycles-compat polyfilled components,
4160 // Unsafe lifecycles should not be invoked for components using the new APIs.
4161
4162 if (!hasNewLifecycles && (typeof instance.UNSAFE_componentWillReceiveProps === 'function' || typeof instance.componentWillReceiveProps === 'function')) {
4163 if (oldProps !== newProps || oldContext !== nextContext) {
4164 callComponentWillReceiveProps(workInProgress, instance, newProps, nextContext);
4165 }
4166 }
4167
4168 resetHasForceUpdateBeforeProcessing();
4169 var oldState = workInProgress.memoizedState;
4170 var newState = instance.state = oldState;
4171 processUpdateQueue(workInProgress, newProps, instance, renderExpirationTime);
4172 newState = workInProgress.memoizedState;
4173
4174 if (oldProps === newProps && oldState === newState && !hasContextChanged() && !checkHasForceUpdateAfterProcessing()) {
4175 // If an update was already in progress, we should schedule an Update
4176 // effect even though we're bailing out, so that cWU/cDU are called.
4177 if (typeof instance.componentDidUpdate === 'function') {
4178 if (oldProps !== current.memoizedProps || oldState !== current.memoizedState) {
4179 workInProgress.effectTag |= Update;
4180 }
4181 }
4182
4183 if (typeof instance.getSnapshotBeforeUpdate === 'function') {
4184 if (oldProps !== current.memoizedProps || oldState !== current.memoizedState) {
4185 workInProgress.effectTag |= Snapshot;
4186 }
4187 }
4188
4189 return false;
4190 }
4191
4192 if (typeof getDerivedStateFromProps === 'function') {
4193 applyDerivedStateFromProps(workInProgress, ctor, getDerivedStateFromProps, newProps);
4194 newState = workInProgress.memoizedState;
4195 }
4196
4197 var shouldUpdate = checkHasForceUpdateAfterProcessing() || checkShouldComponentUpdate(workInProgress, ctor, oldProps, newProps, oldState, newState, nextContext);
4198
4199 if (shouldUpdate) {
4200 // In order to support react-lifecycles-compat polyfilled components,
4201 // Unsafe lifecycles should not be invoked for components using the new APIs.
4202 if (!hasNewLifecycles && (typeof instance.UNSAFE_componentWillUpdate === 'function' || typeof instance.componentWillUpdate === 'function')) {
4203 startPhaseTimer(workInProgress, 'componentWillUpdate');
4204
4205 if (typeof instance.componentWillUpdate === 'function') {
4206 instance.componentWillUpdate(newProps, newState, nextContext);
4207 }
4208
4209 if (typeof instance.UNSAFE_componentWillUpdate === 'function') {
4210 instance.UNSAFE_componentWillUpdate(newProps, newState, nextContext);
4211 }
4212
4213 stopPhaseTimer();
4214 }
4215
4216 if (typeof instance.componentDidUpdate === 'function') {
4217 workInProgress.effectTag |= Update;
4218 }
4219
4220 if (typeof instance.getSnapshotBeforeUpdate === 'function') {
4221 workInProgress.effectTag |= Snapshot;
4222 }
4223 } else {
4224 // If an update was already in progress, we should schedule an Update
4225 // effect even though we're bailing out, so that cWU/cDU are called.
4226 if (typeof instance.componentDidUpdate === 'function') {
4227 if (oldProps !== current.memoizedProps || oldState !== current.memoizedState) {
4228 workInProgress.effectTag |= Update;
4229 }
4230 }
4231
4232 if (typeof instance.getSnapshotBeforeUpdate === 'function') {
4233 if (oldProps !== current.memoizedProps || oldState !== current.memoizedState) {
4234 workInProgress.effectTag |= Snapshot;
4235 }
4236 } // If shouldComponentUpdate returned false, we should still update the
4237 // memoized props/state to indicate that this work can be reused.
4238
4239
4240 workInProgress.memoizedProps = newProps;
4241 workInProgress.memoizedState = newState;
4242 } // Update the existing instance's state, props, and context pointers even
4243 // if shouldComponentUpdate returns false.
4244
4245
4246 instance.props = newProps;
4247 instance.state = newState;
4248 instance.context = nextContext;
4249 return shouldUpdate;
4250}
4251
4252var didWarnAboutMaps;
4253var didWarnAboutGenerators;
4254var didWarnAboutStringRefs;
4255var ownerHasKeyUseWarning;
4256var ownerHasFunctionTypeWarning;
4257
4258var warnForMissingKey = function (child) {};
4259
4260{
4261 didWarnAboutMaps = false;
4262 didWarnAboutGenerators = false;
4263 didWarnAboutStringRefs = {};
4264 /**
4265 * Warn if there's no key explicitly set on dynamic arrays of children or
4266 * object keys are not valid. This allows us to keep track of children between
4267 * updates.
4268 */
4269
4270 ownerHasKeyUseWarning = {};
4271 ownerHasFunctionTypeWarning = {};
4272
4273 warnForMissingKey = function (child) {
4274 if (child === null || typeof child !== 'object') {
4275 return;
4276 }
4277
4278 if (!child._store || child._store.validated || child.key != null) {
4279 return;
4280 }
4281
4282 if (!(typeof child._store === 'object')) {
4283 {
4284 throw Error( "React Component in warnForMissingKey should have a _store. This error is likely caused by a bug in React. Please file an issue." );
4285 }
4286 }
4287
4288 child._store.validated = true;
4289 var currentComponentErrorInfo = 'Each child in a list should have a unique ' + '"key" prop. See https://fb.me/react-warning-keys for ' + 'more information.' + getCurrentFiberStackInDev();
4290
4291 if (ownerHasKeyUseWarning[currentComponentErrorInfo]) {
4292 return;
4293 }
4294
4295 ownerHasKeyUseWarning[currentComponentErrorInfo] = true;
4296
4297 error('Each child in a list should have a unique ' + '"key" prop. See https://fb.me/react-warning-keys for ' + 'more information.');
4298 };
4299}
4300
4301var isArray$1 = Array.isArray;
4302
4303function coerceRef(returnFiber, current, element) {
4304 var mixedRef = element.ref;
4305
4306 if (mixedRef !== null && typeof mixedRef !== 'function' && typeof mixedRef !== 'object') {
4307 {
4308 // TODO: Clean this up once we turn on the string ref warning for
4309 // everyone, because the strict mode case will no longer be relevant
4310 if ((returnFiber.mode & StrictMode || warnAboutStringRefs) && // We warn in ReactElement.js if owner and self are equal for string refs
4311 // because these cannot be automatically converted to an arrow function
4312 // using a codemod. Therefore, we don't have to warn about string refs again.
4313 !(element._owner && element._self && element._owner.stateNode !== element._self)) {
4314 var componentName = getComponentName(returnFiber.type) || 'Component';
4315
4316 if (!didWarnAboutStringRefs[componentName]) {
4317 {
4318 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));
4319 }
4320
4321 didWarnAboutStringRefs[componentName] = true;
4322 }
4323 }
4324 }
4325
4326 if (element._owner) {
4327 var owner = element._owner;
4328 var inst;
4329
4330 if (owner) {
4331 var ownerFiber = owner;
4332
4333 if (!(ownerFiber.tag === ClassComponent)) {
4334 {
4335 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" );
4336 }
4337 }
4338
4339 inst = ownerFiber.stateNode;
4340 }
4341
4342 if (!inst) {
4343 {
4344 throw Error( "Missing owner for string ref " + mixedRef + ". This error is likely caused by a bug in React. Please file an issue." );
4345 }
4346 }
4347
4348 var stringRef = '' + mixedRef; // Check if previous string ref matches new string ref
4349
4350 if (current !== null && current.ref !== null && typeof current.ref === 'function' && current.ref._stringRef === stringRef) {
4351 return current.ref;
4352 }
4353
4354 var ref = function (value) {
4355 var refs = inst.refs;
4356
4357 if (refs === emptyRefsObject) {
4358 // This is a lazy pooled frozen object, so we need to initialize.
4359 refs = inst.refs = {};
4360 }
4361
4362 if (value === null) {
4363 delete refs[stringRef];
4364 } else {
4365 refs[stringRef] = value;
4366 }
4367 };
4368
4369 ref._stringRef = stringRef;
4370 return ref;
4371 } else {
4372 if (!(typeof mixedRef === 'string')) {
4373 {
4374 throw Error( "Expected ref to be a function, a string, an object returned by React.createRef(), or null." );
4375 }
4376 }
4377
4378 if (!element._owner) {
4379 {
4380 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." );
4381 }
4382 }
4383 }
4384 }
4385
4386 return mixedRef;
4387}
4388
4389function throwOnInvalidObjectType(returnFiber, newChild) {
4390 if (returnFiber.type !== 'textarea') {
4391 var addendum = '';
4392
4393 {
4394 addendum = ' If you meant to render a collection of children, use an array ' + 'instead.' + getCurrentFiberStackInDev();
4395 }
4396
4397 {
4398 {
4399 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 );
4400 }
4401 }
4402 }
4403}
4404
4405function warnOnFunctionType() {
4406 {
4407 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();
4408
4409 if (ownerHasFunctionTypeWarning[currentComponentErrorInfo]) {
4410 return;
4411 }
4412
4413 ownerHasFunctionTypeWarning[currentComponentErrorInfo] = true;
4414
4415 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.');
4416 }
4417} // This wrapper function exists because I expect to clone the code in each path
4418// to be able to optimize each path individually by branching early. This needs
4419// a compiler or we can do it manually. Helpers that don't need this branching
4420// live outside of this function.
4421
4422
4423function ChildReconciler(shouldTrackSideEffects) {
4424 function deleteChild(returnFiber, childToDelete) {
4425 if (!shouldTrackSideEffects) {
4426 // Noop.
4427 return;
4428 } // Deletions are added in reversed order so we add it to the front.
4429 // At this point, the return fiber's effect list is empty except for
4430 // deletions, so we can just append the deletion to the list. The remaining
4431 // effects aren't added until the complete phase. Once we implement
4432 // resuming, this may not be true.
4433
4434
4435 var last = returnFiber.lastEffect;
4436
4437 if (last !== null) {
4438 last.nextEffect = childToDelete;
4439 returnFiber.lastEffect = childToDelete;
4440 } else {
4441 returnFiber.firstEffect = returnFiber.lastEffect = childToDelete;
4442 }
4443
4444 childToDelete.nextEffect = null;
4445 childToDelete.effectTag = Deletion;
4446 }
4447
4448 function deleteRemainingChildren(returnFiber, currentFirstChild) {
4449 if (!shouldTrackSideEffects) {
4450 // Noop.
4451 return null;
4452 } // TODO: For the shouldClone case, this could be micro-optimized a bit by
4453 // assuming that after the first child we've already added everything.
4454
4455
4456 var childToDelete = currentFirstChild;
4457
4458 while (childToDelete !== null) {
4459 deleteChild(returnFiber, childToDelete);
4460 childToDelete = childToDelete.sibling;
4461 }
4462
4463 return null;
4464 }
4465
4466 function mapRemainingChildren(returnFiber, currentFirstChild) {
4467 // Add the remaining children to a temporary map so that we can find them by
4468 // keys quickly. Implicit (null) keys get added to this set with their index
4469 // instead.
4470 var existingChildren = new Map();
4471 var existingChild = currentFirstChild;
4472
4473 while (existingChild !== null) {
4474 if (existingChild.key !== null) {
4475 existingChildren.set(existingChild.key, existingChild);
4476 } else {
4477 existingChildren.set(existingChild.index, existingChild);
4478 }
4479
4480 existingChild = existingChild.sibling;
4481 }
4482
4483 return existingChildren;
4484 }
4485
4486 function useFiber(fiber, pendingProps) {
4487 // We currently set sibling to null and index to 0 here because it is easy
4488 // to forget to do before returning it. E.g. for the single child case.
4489 var clone = createWorkInProgress(fiber, pendingProps);
4490 clone.index = 0;
4491 clone.sibling = null;
4492 return clone;
4493 }
4494
4495 function placeChild(newFiber, lastPlacedIndex, newIndex) {
4496 newFiber.index = newIndex;
4497
4498 if (!shouldTrackSideEffects) {
4499 // Noop.
4500 return lastPlacedIndex;
4501 }
4502
4503 var current = newFiber.alternate;
4504
4505 if (current !== null) {
4506 var oldIndex = current.index;
4507
4508 if (oldIndex < lastPlacedIndex) {
4509 // This is a move.
4510 newFiber.effectTag = Placement;
4511 return lastPlacedIndex;
4512 } else {
4513 // This item can stay in place.
4514 return oldIndex;
4515 }
4516 } else {
4517 // This is an insertion.
4518 newFiber.effectTag = Placement;
4519 return lastPlacedIndex;
4520 }
4521 }
4522
4523 function placeSingleChild(newFiber) {
4524 // This is simpler for the single child case. We only need to do a
4525 // placement for inserting new children.
4526 if (shouldTrackSideEffects && newFiber.alternate === null) {
4527 newFiber.effectTag = Placement;
4528 }
4529
4530 return newFiber;
4531 }
4532
4533 function updateTextNode(returnFiber, current, textContent, expirationTime) {
4534 if (current === null || current.tag !== HostText) {
4535 // Insert
4536 var created = createFiberFromText(textContent, returnFiber.mode, expirationTime);
4537 created.return = returnFiber;
4538 return created;
4539 } else {
4540 // Update
4541 var existing = useFiber(current, textContent);
4542 existing.return = returnFiber;
4543 return existing;
4544 }
4545 }
4546
4547 function updateElement(returnFiber, current, element, expirationTime) {
4548 if (current !== null) {
4549 if (current.elementType === element.type || ( // Keep this check inline so it only runs on the false path:
4550 isCompatibleFamilyForHotReloading(current, element) )) {
4551 // Move based on index
4552 var existing = useFiber(current, element.props);
4553 existing.ref = coerceRef(returnFiber, current, element);
4554 existing.return = returnFiber;
4555
4556 {
4557 existing._debugSource = element._source;
4558 existing._debugOwner = element._owner;
4559 }
4560
4561 return existing;
4562 }
4563 } // Insert
4564
4565
4566 var created = createFiberFromElement(element, returnFiber.mode, expirationTime);
4567 created.ref = coerceRef(returnFiber, current, element);
4568 created.return = returnFiber;
4569 return created;
4570 }
4571
4572 function updatePortal(returnFiber, current, portal, expirationTime) {
4573 if (current === null || current.tag !== HostPortal || current.stateNode.containerInfo !== portal.containerInfo || current.stateNode.implementation !== portal.implementation) {
4574 // Insert
4575 var created = createFiberFromPortal(portal, returnFiber.mode, expirationTime);
4576 created.return = returnFiber;
4577 return created;
4578 } else {
4579 // Update
4580 var existing = useFiber(current, portal.children || []);
4581 existing.return = returnFiber;
4582 return existing;
4583 }
4584 }
4585
4586 function updateFragment(returnFiber, current, fragment, expirationTime, key) {
4587 if (current === null || current.tag !== Fragment) {
4588 // Insert
4589 var created = createFiberFromFragment(fragment, returnFiber.mode, expirationTime, key);
4590 created.return = returnFiber;
4591 return created;
4592 } else {
4593 // Update
4594 var existing = useFiber(current, fragment);
4595 existing.return = returnFiber;
4596 return existing;
4597 }
4598 }
4599
4600 function createChild(returnFiber, newChild, expirationTime) {
4601 if (typeof newChild === 'string' || typeof newChild === 'number') {
4602 // Text nodes don't have keys. If the previous node is implicitly keyed
4603 // we can continue to replace it without aborting even if it is not a text
4604 // node.
4605 var created = createFiberFromText('' + newChild, returnFiber.mode, expirationTime);
4606 created.return = returnFiber;
4607 return created;
4608 }
4609
4610 if (typeof newChild === 'object' && newChild !== null) {
4611 switch (newChild.$$typeof) {
4612 case REACT_ELEMENT_TYPE:
4613 {
4614 var _created = createFiberFromElement(newChild, returnFiber.mode, expirationTime);
4615
4616 _created.ref = coerceRef(returnFiber, null, newChild);
4617 _created.return = returnFiber;
4618 return _created;
4619 }
4620
4621 case REACT_PORTAL_TYPE:
4622 {
4623 var _created2 = createFiberFromPortal(newChild, returnFiber.mode, expirationTime);
4624
4625 _created2.return = returnFiber;
4626 return _created2;
4627 }
4628 }
4629
4630 if (isArray$1(newChild) || getIteratorFn(newChild)) {
4631 var _created3 = createFiberFromFragment(newChild, returnFiber.mode, expirationTime, null);
4632
4633 _created3.return = returnFiber;
4634 return _created3;
4635 }
4636
4637 throwOnInvalidObjectType(returnFiber, newChild);
4638 }
4639
4640 {
4641 if (typeof newChild === 'function') {
4642 warnOnFunctionType();
4643 }
4644 }
4645
4646 return null;
4647 }
4648
4649 function updateSlot(returnFiber, oldFiber, newChild, expirationTime) {
4650 // Update the fiber if the keys match, otherwise return null.
4651 var key = oldFiber !== null ? oldFiber.key : null;
4652
4653 if (typeof newChild === 'string' || typeof newChild === 'number') {
4654 // Text nodes don't have keys. If the previous node is implicitly keyed
4655 // we can continue to replace it without aborting even if it is not a text
4656 // node.
4657 if (key !== null) {
4658 return null;
4659 }
4660
4661 return updateTextNode(returnFiber, oldFiber, '' + newChild, expirationTime);
4662 }
4663
4664 if (typeof newChild === 'object' && newChild !== null) {
4665 switch (newChild.$$typeof) {
4666 case REACT_ELEMENT_TYPE:
4667 {
4668 if (newChild.key === key) {
4669 if (newChild.type === REACT_FRAGMENT_TYPE) {
4670 return updateFragment(returnFiber, oldFiber, newChild.props.children, expirationTime, key);
4671 }
4672
4673 return updateElement(returnFiber, oldFiber, newChild, expirationTime);
4674 } else {
4675 return null;
4676 }
4677 }
4678
4679 case REACT_PORTAL_TYPE:
4680 {
4681 if (newChild.key === key) {
4682 return updatePortal(returnFiber, oldFiber, newChild, expirationTime);
4683 } else {
4684 return null;
4685 }
4686 }
4687 }
4688
4689 if (isArray$1(newChild) || getIteratorFn(newChild)) {
4690 if (key !== null) {
4691 return null;
4692 }
4693
4694 return updateFragment(returnFiber, oldFiber, newChild, expirationTime, null);
4695 }
4696
4697 throwOnInvalidObjectType(returnFiber, newChild);
4698 }
4699
4700 {
4701 if (typeof newChild === 'function') {
4702 warnOnFunctionType();
4703 }
4704 }
4705
4706 return null;
4707 }
4708
4709 function updateFromMap(existingChildren, returnFiber, newIdx, newChild, expirationTime) {
4710 if (typeof newChild === 'string' || typeof newChild === 'number') {
4711 // Text nodes don't have keys, so we neither have to check the old nor
4712 // new node for the key. If both are text nodes, they match.
4713 var matchedFiber = existingChildren.get(newIdx) || null;
4714 return updateTextNode(returnFiber, matchedFiber, '' + newChild, expirationTime);
4715 }
4716
4717 if (typeof newChild === 'object' && newChild !== null) {
4718 switch (newChild.$$typeof) {
4719 case REACT_ELEMENT_TYPE:
4720 {
4721 var _matchedFiber = existingChildren.get(newChild.key === null ? newIdx : newChild.key) || null;
4722
4723 if (newChild.type === REACT_FRAGMENT_TYPE) {
4724 return updateFragment(returnFiber, _matchedFiber, newChild.props.children, expirationTime, newChild.key);
4725 }
4726
4727 return updateElement(returnFiber, _matchedFiber, newChild, expirationTime);
4728 }
4729
4730 case REACT_PORTAL_TYPE:
4731 {
4732 var _matchedFiber2 = existingChildren.get(newChild.key === null ? newIdx : newChild.key) || null;
4733
4734 return updatePortal(returnFiber, _matchedFiber2, newChild, expirationTime);
4735 }
4736 }
4737
4738 if (isArray$1(newChild) || getIteratorFn(newChild)) {
4739 var _matchedFiber3 = existingChildren.get(newIdx) || null;
4740
4741 return updateFragment(returnFiber, _matchedFiber3, newChild, expirationTime, null);
4742 }
4743
4744 throwOnInvalidObjectType(returnFiber, newChild);
4745 }
4746
4747 {
4748 if (typeof newChild === 'function') {
4749 warnOnFunctionType();
4750 }
4751 }
4752
4753 return null;
4754 }
4755 /**
4756 * Warns if there is a duplicate or missing key
4757 */
4758
4759
4760 function warnOnInvalidKey(child, knownKeys) {
4761 {
4762 if (typeof child !== 'object' || child === null) {
4763 return knownKeys;
4764 }
4765
4766 switch (child.$$typeof) {
4767 case REACT_ELEMENT_TYPE:
4768 case REACT_PORTAL_TYPE:
4769 warnForMissingKey(child);
4770 var key = child.key;
4771
4772 if (typeof key !== 'string') {
4773 break;
4774 }
4775
4776 if (knownKeys === null) {
4777 knownKeys = new Set();
4778 knownKeys.add(key);
4779 break;
4780 }
4781
4782 if (!knownKeys.has(key)) {
4783 knownKeys.add(key);
4784 break;
4785 }
4786
4787 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);
4788
4789 break;
4790 }
4791 }
4792
4793 return knownKeys;
4794 }
4795
4796 function reconcileChildrenArray(returnFiber, currentFirstChild, newChildren, expirationTime) {
4797 // This algorithm can't optimize by searching from both ends since we
4798 // don't have backpointers on fibers. I'm trying to see how far we can get
4799 // with that model. If it ends up not being worth the tradeoffs, we can
4800 // add it later.
4801 // Even with a two ended optimization, we'd want to optimize for the case
4802 // where there are few changes and brute force the comparison instead of
4803 // going for the Map. It'd like to explore hitting that path first in
4804 // forward-only mode and only go for the Map once we notice that we need
4805 // lots of look ahead. This doesn't handle reversal as well as two ended
4806 // search but that's unusual. Besides, for the two ended optimization to
4807 // work on Iterables, we'd need to copy the whole set.
4808 // In this first iteration, we'll just live with hitting the bad case
4809 // (adding everything to a Map) in for every insert/move.
4810 // If you change this code, also update reconcileChildrenIterator() which
4811 // uses the same algorithm.
4812 {
4813 // First, validate keys.
4814 var knownKeys = null;
4815
4816 for (var i = 0; i < newChildren.length; i++) {
4817 var child = newChildren[i];
4818 knownKeys = warnOnInvalidKey(child, knownKeys);
4819 }
4820 }
4821
4822 var resultingFirstChild = null;
4823 var previousNewFiber = null;
4824 var oldFiber = currentFirstChild;
4825 var lastPlacedIndex = 0;
4826 var newIdx = 0;
4827 var nextOldFiber = null;
4828
4829 for (; oldFiber !== null && newIdx < newChildren.length; newIdx++) {
4830 if (oldFiber.index > newIdx) {
4831 nextOldFiber = oldFiber;
4832 oldFiber = null;
4833 } else {
4834 nextOldFiber = oldFiber.sibling;
4835 }
4836
4837 var newFiber = updateSlot(returnFiber, oldFiber, newChildren[newIdx], expirationTime);
4838
4839 if (newFiber === null) {
4840 // TODO: This breaks on empty slots like null children. That's
4841 // unfortunate because it triggers the slow path all the time. We need
4842 // a better way to communicate whether this was a miss or null,
4843 // boolean, undefined, etc.
4844 if (oldFiber === null) {
4845 oldFiber = nextOldFiber;
4846 }
4847
4848 break;
4849 }
4850
4851 if (shouldTrackSideEffects) {
4852 if (oldFiber && newFiber.alternate === null) {
4853 // We matched the slot, but we didn't reuse the existing fiber, so we
4854 // need to delete the existing child.
4855 deleteChild(returnFiber, oldFiber);
4856 }
4857 }
4858
4859 lastPlacedIndex = placeChild(newFiber, lastPlacedIndex, newIdx);
4860
4861 if (previousNewFiber === null) {
4862 // TODO: Move out of the loop. This only happens for the first run.
4863 resultingFirstChild = newFiber;
4864 } else {
4865 // TODO: Defer siblings if we're not at the right index for this slot.
4866 // I.e. if we had null values before, then we want to defer this
4867 // for each null value. However, we also don't want to call updateSlot
4868 // with the previous one.
4869 previousNewFiber.sibling = newFiber;
4870 }
4871
4872 previousNewFiber = newFiber;
4873 oldFiber = nextOldFiber;
4874 }
4875
4876 if (newIdx === newChildren.length) {
4877 // We've reached the end of the new children. We can delete the rest.
4878 deleteRemainingChildren(returnFiber, oldFiber);
4879 return resultingFirstChild;
4880 }
4881
4882 if (oldFiber === null) {
4883 // If we don't have any more existing children we can choose a fast path
4884 // since the rest will all be insertions.
4885 for (; newIdx < newChildren.length; newIdx++) {
4886 var _newFiber = createChild(returnFiber, newChildren[newIdx], expirationTime);
4887
4888 if (_newFiber === null) {
4889 continue;
4890 }
4891
4892 lastPlacedIndex = placeChild(_newFiber, lastPlacedIndex, newIdx);
4893
4894 if (previousNewFiber === null) {
4895 // TODO: Move out of the loop. This only happens for the first run.
4896 resultingFirstChild = _newFiber;
4897 } else {
4898 previousNewFiber.sibling = _newFiber;
4899 }
4900
4901 previousNewFiber = _newFiber;
4902 }
4903
4904 return resultingFirstChild;
4905 } // Add all children to a key map for quick lookups.
4906
4907
4908 var existingChildren = mapRemainingChildren(returnFiber, oldFiber); // Keep scanning and use the map to restore deleted items as moves.
4909
4910 for (; newIdx < newChildren.length; newIdx++) {
4911 var _newFiber2 = updateFromMap(existingChildren, returnFiber, newIdx, newChildren[newIdx], expirationTime);
4912
4913 if (_newFiber2 !== null) {
4914 if (shouldTrackSideEffects) {
4915 if (_newFiber2.alternate !== null) {
4916 // The new fiber is a work in progress, but if there exists a
4917 // current, that means that we reused the fiber. We need to delete
4918 // it from the child list so that we don't add it to the deletion
4919 // list.
4920 existingChildren.delete(_newFiber2.key === null ? newIdx : _newFiber2.key);
4921 }
4922 }
4923
4924 lastPlacedIndex = placeChild(_newFiber2, lastPlacedIndex, newIdx);
4925
4926 if (previousNewFiber === null) {
4927 resultingFirstChild = _newFiber2;
4928 } else {
4929 previousNewFiber.sibling = _newFiber2;
4930 }
4931
4932 previousNewFiber = _newFiber2;
4933 }
4934 }
4935
4936 if (shouldTrackSideEffects) {
4937 // Any existing children that weren't consumed above were deleted. We need
4938 // to add them to the deletion list.
4939 existingChildren.forEach(function (child) {
4940 return deleteChild(returnFiber, child);
4941 });
4942 }
4943
4944 return resultingFirstChild;
4945 }
4946
4947 function reconcileChildrenIterator(returnFiber, currentFirstChild, newChildrenIterable, expirationTime) {
4948 // This is the same implementation as reconcileChildrenArray(),
4949 // but using the iterator instead.
4950 var iteratorFn = getIteratorFn(newChildrenIterable);
4951
4952 if (!(typeof iteratorFn === 'function')) {
4953 {
4954 throw Error( "An object is not an iterable. This error is likely caused by a bug in React. Please file an issue." );
4955 }
4956 }
4957
4958 {
4959 // We don't support rendering Generators because it's a mutation.
4960 // See https://github.com/facebook/react/issues/12995
4961 if (typeof Symbol === 'function' && // $FlowFixMe Flow doesn't know about toStringTag
4962 newChildrenIterable[Symbol.toStringTag] === 'Generator') {
4963 if (!didWarnAboutGenerators) {
4964 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.');
4965 }
4966
4967 didWarnAboutGenerators = true;
4968 } // Warn about using Maps as children
4969
4970
4971 if (newChildrenIterable.entries === iteratorFn) {
4972 if (!didWarnAboutMaps) {
4973 error('Using Maps as children is unsupported and will likely yield ' + 'unexpected results. Convert it to a sequence/iterable of keyed ' + 'ReactElements instead.');
4974 }
4975
4976 didWarnAboutMaps = true;
4977 } // First, validate keys.
4978 // We'll get a different iterator later for the main pass.
4979
4980
4981 var _newChildren = iteratorFn.call(newChildrenIterable);
4982
4983 if (_newChildren) {
4984 var knownKeys = null;
4985
4986 var _step = _newChildren.next();
4987
4988 for (; !_step.done; _step = _newChildren.next()) {
4989 var child = _step.value;
4990 knownKeys = warnOnInvalidKey(child, knownKeys);
4991 }
4992 }
4993 }
4994
4995 var newChildren = iteratorFn.call(newChildrenIterable);
4996
4997 if (!(newChildren != null)) {
4998 {
4999 throw Error( "An iterable object provided no iterator." );
5000 }
5001 }
5002
5003 var resultingFirstChild = null;
5004 var previousNewFiber = null;
5005 var oldFiber = currentFirstChild;
5006 var lastPlacedIndex = 0;
5007 var newIdx = 0;
5008 var nextOldFiber = null;
5009 var step = newChildren.next();
5010
5011 for (; oldFiber !== null && !step.done; newIdx++, step = newChildren.next()) {
5012 if (oldFiber.index > newIdx) {
5013 nextOldFiber = oldFiber;
5014 oldFiber = null;
5015 } else {
5016 nextOldFiber = oldFiber.sibling;
5017 }
5018
5019 var newFiber = updateSlot(returnFiber, oldFiber, step.value, expirationTime);
5020
5021 if (newFiber === null) {
5022 // TODO: This breaks on empty slots like null children. That's
5023 // unfortunate because it triggers the slow path all the time. We need
5024 // a better way to communicate whether this was a miss or null,
5025 // boolean, undefined, etc.
5026 if (oldFiber === null) {
5027 oldFiber = nextOldFiber;
5028 }
5029
5030 break;
5031 }
5032
5033 if (shouldTrackSideEffects) {
5034 if (oldFiber && newFiber.alternate === null) {
5035 // We matched the slot, but we didn't reuse the existing fiber, so we
5036 // need to delete the existing child.
5037 deleteChild(returnFiber, oldFiber);
5038 }
5039 }
5040
5041 lastPlacedIndex = placeChild(newFiber, lastPlacedIndex, newIdx);
5042
5043 if (previousNewFiber === null) {
5044 // TODO: Move out of the loop. This only happens for the first run.
5045 resultingFirstChild = newFiber;
5046 } else {
5047 // TODO: Defer siblings if we're not at the right index for this slot.
5048 // I.e. if we had null values before, then we want to defer this
5049 // for each null value. However, we also don't want to call updateSlot
5050 // with the previous one.
5051 previousNewFiber.sibling = newFiber;
5052 }
5053
5054 previousNewFiber = newFiber;
5055 oldFiber = nextOldFiber;
5056 }
5057
5058 if (step.done) {
5059 // We've reached the end of the new children. We can delete the rest.
5060 deleteRemainingChildren(returnFiber, oldFiber);
5061 return resultingFirstChild;
5062 }
5063
5064 if (oldFiber === null) {
5065 // If we don't have any more existing children we can choose a fast path
5066 // since the rest will all be insertions.
5067 for (; !step.done; newIdx++, step = newChildren.next()) {
5068 var _newFiber3 = createChild(returnFiber, step.value, expirationTime);
5069
5070 if (_newFiber3 === null) {
5071 continue;
5072 }
5073
5074 lastPlacedIndex = placeChild(_newFiber3, lastPlacedIndex, newIdx);
5075
5076 if (previousNewFiber === null) {
5077 // TODO: Move out of the loop. This only happens for the first run.
5078 resultingFirstChild = _newFiber3;
5079 } else {
5080 previousNewFiber.sibling = _newFiber3;
5081 }
5082
5083 previousNewFiber = _newFiber3;
5084 }
5085
5086 return resultingFirstChild;
5087 } // Add all children to a key map for quick lookups.
5088
5089
5090 var existingChildren = mapRemainingChildren(returnFiber, oldFiber); // Keep scanning and use the map to restore deleted items as moves.
5091
5092 for (; !step.done; newIdx++, step = newChildren.next()) {
5093 var _newFiber4 = updateFromMap(existingChildren, returnFiber, newIdx, step.value, expirationTime);
5094
5095 if (_newFiber4 !== null) {
5096 if (shouldTrackSideEffects) {
5097 if (_newFiber4.alternate !== null) {
5098 // The new fiber is a work in progress, but if there exists a
5099 // current, that means that we reused the fiber. We need to delete
5100 // it from the child list so that we don't add it to the deletion
5101 // list.
5102 existingChildren.delete(_newFiber4.key === null ? newIdx : _newFiber4.key);
5103 }
5104 }
5105
5106 lastPlacedIndex = placeChild(_newFiber4, lastPlacedIndex, newIdx);
5107
5108 if (previousNewFiber === null) {
5109 resultingFirstChild = _newFiber4;
5110 } else {
5111 previousNewFiber.sibling = _newFiber4;
5112 }
5113
5114 previousNewFiber = _newFiber4;
5115 }
5116 }
5117
5118 if (shouldTrackSideEffects) {
5119 // Any existing children that weren't consumed above were deleted. We need
5120 // to add them to the deletion list.
5121 existingChildren.forEach(function (child) {
5122 return deleteChild(returnFiber, child);
5123 });
5124 }
5125
5126 return resultingFirstChild;
5127 }
5128
5129 function reconcileSingleTextNode(returnFiber, currentFirstChild, textContent, expirationTime) {
5130 // There's no need to check for keys on text nodes since we don't have a
5131 // way to define them.
5132 if (currentFirstChild !== null && currentFirstChild.tag === HostText) {
5133 // We already have an existing node so let's just update it and delete
5134 // the rest.
5135 deleteRemainingChildren(returnFiber, currentFirstChild.sibling);
5136 var existing = useFiber(currentFirstChild, textContent);
5137 existing.return = returnFiber;
5138 return existing;
5139 } // The existing first child is not a text node so we need to create one
5140 // and delete the existing ones.
5141
5142
5143 deleteRemainingChildren(returnFiber, currentFirstChild);
5144 var created = createFiberFromText(textContent, returnFiber.mode, expirationTime);
5145 created.return = returnFiber;
5146 return created;
5147 }
5148
5149 function reconcileSingleElement(returnFiber, currentFirstChild, element, expirationTime) {
5150 var key = element.key;
5151 var child = currentFirstChild;
5152
5153 while (child !== null) {
5154 // TODO: If key === null and child.key === null, then this only applies to
5155 // the first item in the list.
5156 if (child.key === key) {
5157 switch (child.tag) {
5158 case Fragment:
5159 {
5160 if (element.type === REACT_FRAGMENT_TYPE) {
5161 deleteRemainingChildren(returnFiber, child.sibling);
5162 var existing = useFiber(child, element.props.children);
5163 existing.return = returnFiber;
5164
5165 {
5166 existing._debugSource = element._source;
5167 existing._debugOwner = element._owner;
5168 }
5169
5170 return existing;
5171 }
5172
5173 break;
5174 }
5175
5176 case Block:
5177
5178 // We intentionally fallthrough here if enableBlocksAPI is not on.
5179 // eslint-disable-next-lined no-fallthrough
5180
5181 default:
5182 {
5183 if (child.elementType === element.type || ( // Keep this check inline so it only runs on the false path:
5184 isCompatibleFamilyForHotReloading(child, element) )) {
5185 deleteRemainingChildren(returnFiber, child.sibling);
5186
5187 var _existing3 = useFiber(child, element.props);
5188
5189 _existing3.ref = coerceRef(returnFiber, child, element);
5190 _existing3.return = returnFiber;
5191
5192 {
5193 _existing3._debugSource = element._source;
5194 _existing3._debugOwner = element._owner;
5195 }
5196
5197 return _existing3;
5198 }
5199
5200 break;
5201 }
5202 } // Didn't match.
5203
5204
5205 deleteRemainingChildren(returnFiber, child);
5206 break;
5207 } else {
5208 deleteChild(returnFiber, child);
5209 }
5210
5211 child = child.sibling;
5212 }
5213
5214 if (element.type === REACT_FRAGMENT_TYPE) {
5215 var created = createFiberFromFragment(element.props.children, returnFiber.mode, expirationTime, element.key);
5216 created.return = returnFiber;
5217 return created;
5218 } else {
5219 var _created4 = createFiberFromElement(element, returnFiber.mode, expirationTime);
5220
5221 _created4.ref = coerceRef(returnFiber, currentFirstChild, element);
5222 _created4.return = returnFiber;
5223 return _created4;
5224 }
5225 }
5226
5227 function reconcileSinglePortal(returnFiber, currentFirstChild, portal, expirationTime) {
5228 var key = portal.key;
5229 var child = currentFirstChild;
5230
5231 while (child !== null) {
5232 // TODO: If key === null and child.key === null, then this only applies to
5233 // the first item in the list.
5234 if (child.key === key) {
5235 if (child.tag === HostPortal && child.stateNode.containerInfo === portal.containerInfo && child.stateNode.implementation === portal.implementation) {
5236 deleteRemainingChildren(returnFiber, child.sibling);
5237 var existing = useFiber(child, portal.children || []);
5238 existing.return = returnFiber;
5239 return existing;
5240 } else {
5241 deleteRemainingChildren(returnFiber, child);
5242 break;
5243 }
5244 } else {
5245 deleteChild(returnFiber, child);
5246 }
5247
5248 child = child.sibling;
5249 }
5250
5251 var created = createFiberFromPortal(portal, returnFiber.mode, expirationTime);
5252 created.return = returnFiber;
5253 return created;
5254 } // This API will tag the children with the side-effect of the reconciliation
5255 // itself. They will be added to the side-effect list as we pass through the
5256 // children and the parent.
5257
5258
5259 function reconcileChildFibers(returnFiber, currentFirstChild, newChild, expirationTime) {
5260 // This function is not recursive.
5261 // If the top level item is an array, we treat it as a set of children,
5262 // not as a fragment. Nested arrays on the other hand will be treated as
5263 // fragment nodes. Recursion happens at the normal flow.
5264 // Handle top level unkeyed fragments as if they were arrays.
5265 // This leads to an ambiguity between <>{[...]}</> and <>...</>.
5266 // We treat the ambiguous cases above the same.
5267 var isUnkeyedTopLevelFragment = typeof newChild === 'object' && newChild !== null && newChild.type === REACT_FRAGMENT_TYPE && newChild.key === null;
5268
5269 if (isUnkeyedTopLevelFragment) {
5270 newChild = newChild.props.children;
5271 } // Handle object types
5272
5273
5274 var isObject = typeof newChild === 'object' && newChild !== null;
5275
5276 if (isObject) {
5277 switch (newChild.$$typeof) {
5278 case REACT_ELEMENT_TYPE:
5279 return placeSingleChild(reconcileSingleElement(returnFiber, currentFirstChild, newChild, expirationTime));
5280
5281 case REACT_PORTAL_TYPE:
5282 return placeSingleChild(reconcileSinglePortal(returnFiber, currentFirstChild, newChild, expirationTime));
5283 }
5284 }
5285
5286 if (typeof newChild === 'string' || typeof newChild === 'number') {
5287 return placeSingleChild(reconcileSingleTextNode(returnFiber, currentFirstChild, '' + newChild, expirationTime));
5288 }
5289
5290 if (isArray$1(newChild)) {
5291 return reconcileChildrenArray(returnFiber, currentFirstChild, newChild, expirationTime);
5292 }
5293
5294 if (getIteratorFn(newChild)) {
5295 return reconcileChildrenIterator(returnFiber, currentFirstChild, newChild, expirationTime);
5296 }
5297
5298 if (isObject) {
5299 throwOnInvalidObjectType(returnFiber, newChild);
5300 }
5301
5302 {
5303 if (typeof newChild === 'function') {
5304 warnOnFunctionType();
5305 }
5306 }
5307
5308 if (typeof newChild === 'undefined' && !isUnkeyedTopLevelFragment) {
5309 // If the new child is undefined, and the return fiber is a composite
5310 // component, throw an error. If Fiber return types are disabled,
5311 // we already threw above.
5312 switch (returnFiber.tag) {
5313 case ClassComponent:
5314 {
5315 {
5316 var instance = returnFiber.stateNode;
5317
5318 if (instance.render._isMockFunction) {
5319 // We allow auto-mocks to proceed as if they're returning null.
5320 break;
5321 }
5322 }
5323 }
5324 // Intentionally fall through to the next case, which handles both
5325 // functions and classes
5326 // eslint-disable-next-lined no-fallthrough
5327
5328 case FunctionComponent:
5329 {
5330 var Component = returnFiber.type;
5331
5332 {
5333 {
5334 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." );
5335 }
5336 }
5337 }
5338 }
5339 } // Remaining cases are all treated as empty.
5340
5341
5342 return deleteRemainingChildren(returnFiber, currentFirstChild);
5343 }
5344
5345 return reconcileChildFibers;
5346}
5347
5348var reconcileChildFibers = ChildReconciler(true);
5349var mountChildFibers = ChildReconciler(false);
5350function cloneChildFibers(current, workInProgress) {
5351 if (!(current === null || workInProgress.child === current.child)) {
5352 {
5353 throw Error( "Resuming work not yet implemented." );
5354 }
5355 }
5356
5357 if (workInProgress.child === null) {
5358 return;
5359 }
5360
5361 var currentChild = workInProgress.child;
5362 var newChild = createWorkInProgress(currentChild, currentChild.pendingProps);
5363 workInProgress.child = newChild;
5364 newChild.return = workInProgress;
5365
5366 while (currentChild.sibling !== null) {
5367 currentChild = currentChild.sibling;
5368 newChild = newChild.sibling = createWorkInProgress(currentChild, currentChild.pendingProps);
5369 newChild.return = workInProgress;
5370 }
5371
5372 newChild.sibling = null;
5373} // Reset a workInProgress child set to prepare it for a second pass.
5374
5375function resetChildFibers(workInProgress, renderExpirationTime) {
5376 var child = workInProgress.child;
5377
5378 while (child !== null) {
5379 resetWorkInProgress(child, renderExpirationTime);
5380 child = child.sibling;
5381 }
5382}
5383
5384var NO_CONTEXT$1 = {};
5385var contextStackCursor$1 = createCursor(NO_CONTEXT$1);
5386var contextFiberStackCursor = createCursor(NO_CONTEXT$1);
5387var rootInstanceStackCursor = createCursor(NO_CONTEXT$1);
5388
5389function requiredContext(c) {
5390 if (!(c !== NO_CONTEXT$1)) {
5391 {
5392 throw Error( "Expected host context to exist. This error is likely caused by a bug in React. Please file an issue." );
5393 }
5394 }
5395
5396 return c;
5397}
5398
5399function getRootHostContainer() {
5400 var rootInstance = requiredContext(rootInstanceStackCursor.current);
5401 return rootInstance;
5402}
5403
5404function pushHostContainer(fiber, nextRootInstance) {
5405 // Push current root instance onto the stack;
5406 // This allows us to reset root when portals are popped.
5407 push(rootInstanceStackCursor, nextRootInstance, fiber); // Track the context and the Fiber that provided it.
5408 // This enables us to pop only Fibers that provide unique contexts.
5409
5410 push(contextFiberStackCursor, fiber, fiber); // Finally, we need to push the host context to the stack.
5411 // However, we can't just call getRootHostContext() and push it because
5412 // we'd have a different number of entries on the stack depending on
5413 // whether getRootHostContext() throws somewhere in renderer code or not.
5414 // So we push an empty value first. This lets us safely unwind on errors.
5415
5416 push(contextStackCursor$1, NO_CONTEXT$1, fiber);
5417 var nextRootContext = getRootHostContext(); // Now that we know this function doesn't throw, replace it.
5418
5419 pop(contextStackCursor$1, fiber);
5420 push(contextStackCursor$1, nextRootContext, fiber);
5421}
5422
5423function popHostContainer(fiber) {
5424 pop(contextStackCursor$1, fiber);
5425 pop(contextFiberStackCursor, fiber);
5426 pop(rootInstanceStackCursor, fiber);
5427}
5428
5429function getHostContext() {
5430 var context = requiredContext(contextStackCursor$1.current);
5431 return context;
5432}
5433
5434function pushHostContext(fiber) {
5435 var rootInstance = requiredContext(rootInstanceStackCursor.current);
5436 var context = requiredContext(contextStackCursor$1.current);
5437 var nextContext = getChildHostContext(context, fiber.type); // Don't push this Fiber's context unless it's unique.
5438
5439 if (context === nextContext) {
5440 return;
5441 } // Track the context and the Fiber that provided it.
5442 // This enables us to pop only Fibers that provide unique contexts.
5443
5444
5445 push(contextFiberStackCursor, fiber, fiber);
5446 push(contextStackCursor$1, nextContext, fiber);
5447}
5448
5449function popHostContext(fiber) {
5450 // Do not pop unless this Fiber provided the current context.
5451 // pushHostContext() only pushes Fibers that provide unique contexts.
5452 if (contextFiberStackCursor.current !== fiber) {
5453 return;
5454 }
5455
5456 pop(contextStackCursor$1, fiber);
5457 pop(contextFiberStackCursor, fiber);
5458}
5459
5460var DefaultSuspenseContext = 0; // The Suspense Context is split into two parts. The lower bits is
5461// inherited deeply down the subtree. The upper bits only affect
5462// this immediate suspense boundary and gets reset each new
5463// boundary or suspense list.
5464
5465var SubtreeSuspenseContextMask = 1; // Subtree Flags:
5466// InvisibleParentSuspenseContext indicates that one of our parent Suspense
5467// boundaries is not currently showing visible main content.
5468// Either because it is already showing a fallback or is not mounted at all.
5469// We can use this to determine if it is desirable to trigger a fallback at
5470// the parent. If not, then we might need to trigger undesirable boundaries
5471// and/or suspend the commit to avoid hiding the parent content.
5472
5473var InvisibleParentSuspenseContext = 1; // Shallow Flags:
5474// ForceSuspenseFallback can be used by SuspenseList to force newly added
5475// items into their fallback state during one of the render passes.
5476
5477var ForceSuspenseFallback = 2;
5478var suspenseStackCursor = createCursor(DefaultSuspenseContext);
5479function hasSuspenseContext(parentContext, flag) {
5480 return (parentContext & flag) !== 0;
5481}
5482function setDefaultShallowSuspenseContext(parentContext) {
5483 return parentContext & SubtreeSuspenseContextMask;
5484}
5485function setShallowSuspenseContext(parentContext, shallowContext) {
5486 return parentContext & SubtreeSuspenseContextMask | shallowContext;
5487}
5488function addSubtreeSuspenseContext(parentContext, subtreeContext) {
5489 return parentContext | subtreeContext;
5490}
5491function pushSuspenseContext(fiber, newContext) {
5492 push(suspenseStackCursor, newContext, fiber);
5493}
5494function popSuspenseContext(fiber) {
5495 pop(suspenseStackCursor, fiber);
5496}
5497
5498function shouldCaptureSuspense(workInProgress, hasInvisibleParent) {
5499 // If it was the primary children that just suspended, capture and render the
5500 // fallback. Otherwise, don't capture and bubble to the next boundary.
5501 var nextState = workInProgress.memoizedState;
5502
5503 if (nextState !== null) {
5504 if (nextState.dehydrated !== null) {
5505 // A dehydrated boundary always captures.
5506 return true;
5507 }
5508
5509 return false;
5510 }
5511
5512 var props = workInProgress.memoizedProps; // In order to capture, the Suspense component must have a fallback prop.
5513
5514 if (props.fallback === undefined) {
5515 return false;
5516 } // Regular boundaries always capture.
5517
5518
5519 if (props.unstable_avoidThisFallback !== true) {
5520 return true;
5521 } // If it's a boundary we should avoid, then we prefer to bubble up to the
5522 // parent boundary if it is currently invisible.
5523
5524
5525 if (hasInvisibleParent) {
5526 return false;
5527 } // If the parent is not able to handle it, we must handle it.
5528
5529
5530 return true;
5531}
5532function findFirstSuspended(row) {
5533 var node = row;
5534
5535 while (node !== null) {
5536 if (node.tag === SuspenseComponent) {
5537 var state = node.memoizedState;
5538
5539 if (state !== null) {
5540 var dehydrated = state.dehydrated;
5541
5542 if (dehydrated === null || isSuspenseInstancePending() || isSuspenseInstanceFallback()) {
5543 return node;
5544 }
5545 }
5546 } else if (node.tag === SuspenseListComponent && // revealOrder undefined can't be trusted because it don't
5547 // keep track of whether it suspended or not.
5548 node.memoizedProps.revealOrder !== undefined) {
5549 var didSuspend = (node.effectTag & DidCapture) !== NoEffect;
5550
5551 if (didSuspend) {
5552 return node;
5553 }
5554 } else if (node.child !== null) {
5555 node.child.return = node;
5556 node = node.child;
5557 continue;
5558 }
5559
5560 if (node === row) {
5561 return null;
5562 }
5563
5564 while (node.sibling === null) {
5565 if (node.return === null || node.return === row) {
5566 return null;
5567 }
5568
5569 node = node.return;
5570 }
5571
5572 node.sibling.return = node.return;
5573 node = node.sibling;
5574 }
5575
5576 return null;
5577}
5578
5579function createDeprecatedResponderListener(responder, props) {
5580 var eventResponderListener = {
5581 responder: responder,
5582 props: props
5583 };
5584
5585 {
5586 Object.freeze(eventResponderListener);
5587 }
5588
5589 return eventResponderListener;
5590}
5591
5592var HasEffect =
5593/* */
55941; // Represents the phase in which the effect (not the clean-up) fires.
5595
5596var Layout =
5597/* */
55982;
5599var Passive$1 =
5600/* */
56014;
5602
5603var ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher,
5604 ReactCurrentBatchConfig$1 = ReactSharedInternals.ReactCurrentBatchConfig;
5605var didWarnAboutMismatchedHooksForComponent;
5606
5607{
5608 didWarnAboutMismatchedHooksForComponent = new Set();
5609}
5610
5611// These are set right before calling the component.
5612var renderExpirationTime = NoWork; // The work-in-progress fiber. I've named it differently to distinguish it from
5613// the work-in-progress hook.
5614
5615var currentlyRenderingFiber$1 = null; // Hooks are stored as a linked list on the fiber's memoizedState field. The
5616// current hook list is the list that belongs to the current fiber. The
5617// work-in-progress hook list is a new list that will be added to the
5618// work-in-progress fiber.
5619
5620var currentHook = null;
5621var workInProgressHook = null; // Whether an update was scheduled at any point during the render phase. This
5622// does not get reset if we do another render pass; only when we're completely
5623// finished evaluating this component. This is an optimization so we know
5624// whether we need to clear render phase updates after a throw.
5625
5626var didScheduleRenderPhaseUpdate = false;
5627var RE_RENDER_LIMIT = 25; // In DEV, this is the name of the currently executing primitive hook
5628
5629var currentHookNameInDev = null; // In DEV, this list ensures that hooks are called in the same order between renders.
5630// The list stores the order of hooks used during the initial render (mount).
5631// Subsequent renders (updates) reference this list.
5632
5633var hookTypesDev = null;
5634var hookTypesUpdateIndexDev = -1; // In DEV, this tracks whether currently rendering component needs to ignore
5635// the dependencies for Hooks that need them (e.g. useEffect or useMemo).
5636// When true, such Hooks will always be "remounted". Only used during hot reload.
5637
5638var ignorePreviousDependencies = false;
5639
5640function mountHookTypesDev() {
5641 {
5642 var hookName = currentHookNameInDev;
5643
5644 if (hookTypesDev === null) {
5645 hookTypesDev = [hookName];
5646 } else {
5647 hookTypesDev.push(hookName);
5648 }
5649 }
5650}
5651
5652function updateHookTypesDev() {
5653 {
5654 var hookName = currentHookNameInDev;
5655
5656 if (hookTypesDev !== null) {
5657 hookTypesUpdateIndexDev++;
5658
5659 if (hookTypesDev[hookTypesUpdateIndexDev] !== hookName) {
5660 warnOnHookMismatchInDev(hookName);
5661 }
5662 }
5663 }
5664}
5665
5666function checkDepsAreArrayDev(deps) {
5667 {
5668 if (deps !== undefined && deps !== null && !Array.isArray(deps)) {
5669 // Verify deps, but only on mount to avoid extra checks.
5670 // It's unlikely their type would change as usually you define them inline.
5671 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);
5672 }
5673 }
5674}
5675
5676function warnOnHookMismatchInDev(currentHookName) {
5677 {
5678 var componentName = getComponentName(currentlyRenderingFiber$1.type);
5679
5680 if (!didWarnAboutMismatchedHooksForComponent.has(componentName)) {
5681 didWarnAboutMismatchedHooksForComponent.add(componentName);
5682
5683 if (hookTypesDev !== null) {
5684 var table = '';
5685 var secondColumnStart = 30;
5686
5687 for (var i = 0; i <= hookTypesUpdateIndexDev; i++) {
5688 var oldHookName = hookTypesDev[i];
5689 var newHookName = i === hookTypesUpdateIndexDev ? currentHookName : oldHookName;
5690 var row = i + 1 + ". " + oldHookName; // Extra space so second column lines up
5691 // lol @ IE not supporting String#repeat
5692
5693 while (row.length < secondColumnStart) {
5694 row += ' ';
5695 }
5696
5697 row += newHookName + '\n';
5698 table += row;
5699 }
5700
5701 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);
5702 }
5703 }
5704 }
5705}
5706
5707function throwInvalidHookError() {
5708 {
5709 {
5710 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." );
5711 }
5712 }
5713}
5714
5715function areHookInputsEqual(nextDeps, prevDeps) {
5716 {
5717 if (ignorePreviousDependencies) {
5718 // Only true when this component is being hot reloaded.
5719 return false;
5720 }
5721 }
5722
5723 if (prevDeps === null) {
5724 {
5725 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);
5726 }
5727
5728 return false;
5729 }
5730
5731 {
5732 // Don't bother comparing lengths in prod because these arrays should be
5733 // passed inline.
5734 if (nextDeps.length !== prevDeps.length) {
5735 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(', ') + "]");
5736 }
5737 }
5738
5739 for (var i = 0; i < prevDeps.length && i < nextDeps.length; i++) {
5740 if (objectIs(nextDeps[i], prevDeps[i])) {
5741 continue;
5742 }
5743
5744 return false;
5745 }
5746
5747 return true;
5748}
5749
5750function renderWithHooks(current, workInProgress, Component, props, secondArg, nextRenderExpirationTime) {
5751 renderExpirationTime = nextRenderExpirationTime;
5752 currentlyRenderingFiber$1 = workInProgress;
5753
5754 {
5755 hookTypesDev = current !== null ? current._debugHookTypes : null;
5756 hookTypesUpdateIndexDev = -1; // Used for hot reloading:
5757
5758 ignorePreviousDependencies = current !== null && current.type !== workInProgress.type;
5759 }
5760
5761 workInProgress.memoizedState = null;
5762 workInProgress.updateQueue = null;
5763 workInProgress.expirationTime = NoWork; // The following should have already been reset
5764 // currentHook = null;
5765 // workInProgressHook = null;
5766 // didScheduleRenderPhaseUpdate = false;
5767 // TODO Warn if no hooks are used at all during mount, then some are used during update.
5768 // Currently we will identify the update render as a mount because memoizedState === null.
5769 // This is tricky because it's valid for certain types of components (e.g. React.lazy)
5770 // Using memoizedState to differentiate between mount/update only works if at least one stateful hook is used.
5771 // Non-stateful hooks (e.g. context) don't get added to memoizedState,
5772 // so memoizedState would be null during updates and mounts.
5773
5774 {
5775 if (current !== null && current.memoizedState !== null) {
5776 ReactCurrentDispatcher.current = HooksDispatcherOnUpdateInDEV;
5777 } else if (hookTypesDev !== null) {
5778 // This dispatcher handles an edge case where a component is updating,
5779 // but no stateful hooks have been used.
5780 // We want to match the production code behavior (which will use HooksDispatcherOnMount),
5781 // but with the extra DEV validation to ensure hooks ordering hasn't changed.
5782 // This dispatcher does that.
5783 ReactCurrentDispatcher.current = HooksDispatcherOnMountWithHookTypesInDEV;
5784 } else {
5785 ReactCurrentDispatcher.current = HooksDispatcherOnMountInDEV;
5786 }
5787 }
5788
5789 var children = Component(props, secondArg); // Check if there was a render phase update
5790
5791 if (workInProgress.expirationTime === renderExpirationTime) {
5792 // Keep rendering in a loop for as long as render phase updates continue to
5793 // be scheduled. Use a counter to prevent infinite loops.
5794 var numberOfReRenders = 0;
5795
5796 do {
5797 workInProgress.expirationTime = NoWork;
5798
5799 if (!(numberOfReRenders < RE_RENDER_LIMIT)) {
5800 {
5801 throw Error( "Too many re-renders. React limits the number of renders to prevent an infinite loop." );
5802 }
5803 }
5804
5805 numberOfReRenders += 1;
5806
5807 {
5808 // Even when hot reloading, allow dependencies to stabilize
5809 // after first render to prevent infinite render phase updates.
5810 ignorePreviousDependencies = false;
5811 } // Start over from the beginning of the list
5812
5813
5814 currentHook = null;
5815 workInProgressHook = null;
5816 workInProgress.updateQueue = null;
5817
5818 {
5819 // Also validate hook order for cascading updates.
5820 hookTypesUpdateIndexDev = -1;
5821 }
5822
5823 ReactCurrentDispatcher.current = HooksDispatcherOnRerenderInDEV ;
5824 children = Component(props, secondArg);
5825 } while (workInProgress.expirationTime === renderExpirationTime);
5826 } // We can assume the previous dispatcher is always this one, since we set it
5827 // at the beginning of the render phase and there's no re-entrancy.
5828
5829
5830 ReactCurrentDispatcher.current = ContextOnlyDispatcher;
5831
5832 {
5833 workInProgress._debugHookTypes = hookTypesDev;
5834 } // This check uses currentHook so that it works the same in DEV and prod bundles.
5835 // hookTypesDev could catch more cases (e.g. context) but only in DEV bundles.
5836
5837
5838 var didRenderTooFewHooks = currentHook !== null && currentHook.next !== null;
5839 renderExpirationTime = NoWork;
5840 currentlyRenderingFiber$1 = null;
5841 currentHook = null;
5842 workInProgressHook = null;
5843
5844 {
5845 currentHookNameInDev = null;
5846 hookTypesDev = null;
5847 hookTypesUpdateIndexDev = -1;
5848 }
5849
5850 didScheduleRenderPhaseUpdate = false;
5851
5852 if (!!didRenderTooFewHooks) {
5853 {
5854 throw Error( "Rendered fewer hooks than expected. This may be caused by an accidental early return statement." );
5855 }
5856 }
5857
5858 return children;
5859}
5860function bailoutHooks(current, workInProgress, expirationTime) {
5861 workInProgress.updateQueue = current.updateQueue;
5862 workInProgress.effectTag &= ~(Passive | Update);
5863
5864 if (current.expirationTime <= expirationTime) {
5865 current.expirationTime = NoWork;
5866 }
5867}
5868function resetHooksAfterThrow() {
5869 // We can assume the previous dispatcher is always this one, since we set it
5870 // at the beginning of the render phase and there's no re-entrancy.
5871 ReactCurrentDispatcher.current = ContextOnlyDispatcher;
5872
5873 if (didScheduleRenderPhaseUpdate) {
5874 // There were render phase updates. These are only valid for this render
5875 // phase, which we are now aborting. Remove the updates from the queues so
5876 // they do not persist to the next render. Do not remove updates from hooks
5877 // that weren't processed.
5878 //
5879 // Only reset the updates from the queue if it has a clone. If it does
5880 // not have a clone, that means it wasn't processed, and the updates were
5881 // scheduled before we entered the render phase.
5882 var hook = currentlyRenderingFiber$1.memoizedState;
5883
5884 while (hook !== null) {
5885 var queue = hook.queue;
5886
5887 if (queue !== null) {
5888 queue.pending = null;
5889 }
5890
5891 hook = hook.next;
5892 }
5893 }
5894
5895 renderExpirationTime = NoWork;
5896 currentlyRenderingFiber$1 = null;
5897 currentHook = null;
5898 workInProgressHook = null;
5899
5900 {
5901 hookTypesDev = null;
5902 hookTypesUpdateIndexDev = -1;
5903 currentHookNameInDev = null;
5904 }
5905
5906 didScheduleRenderPhaseUpdate = false;
5907}
5908
5909function mountWorkInProgressHook() {
5910 var hook = {
5911 memoizedState: null,
5912 baseState: null,
5913 baseQueue: null,
5914 queue: null,
5915 next: null
5916 };
5917
5918 if (workInProgressHook === null) {
5919 // This is the first hook in the list
5920 currentlyRenderingFiber$1.memoizedState = workInProgressHook = hook;
5921 } else {
5922 // Append to the end of the list
5923 workInProgressHook = workInProgressHook.next = hook;
5924 }
5925
5926 return workInProgressHook;
5927}
5928
5929function updateWorkInProgressHook() {
5930 // This function is used both for updates and for re-renders triggered by a
5931 // render phase update. It assumes there is either a current hook we can
5932 // clone, or a work-in-progress hook from a previous render pass that we can
5933 // use as a base. When we reach the end of the base list, we must switch to
5934 // the dispatcher used for mounts.
5935 var nextCurrentHook;
5936
5937 if (currentHook === null) {
5938 var current = currentlyRenderingFiber$1.alternate;
5939
5940 if (current !== null) {
5941 nextCurrentHook = current.memoizedState;
5942 } else {
5943 nextCurrentHook = null;
5944 }
5945 } else {
5946 nextCurrentHook = currentHook.next;
5947 }
5948
5949 var nextWorkInProgressHook;
5950
5951 if (workInProgressHook === null) {
5952 nextWorkInProgressHook = currentlyRenderingFiber$1.memoizedState;
5953 } else {
5954 nextWorkInProgressHook = workInProgressHook.next;
5955 }
5956
5957 if (nextWorkInProgressHook !== null) {
5958 // There's already a work-in-progress. Reuse it.
5959 workInProgressHook = nextWorkInProgressHook;
5960 nextWorkInProgressHook = workInProgressHook.next;
5961 currentHook = nextCurrentHook;
5962 } else {
5963 // Clone from the current hook.
5964 if (!(nextCurrentHook !== null)) {
5965 {
5966 throw Error( "Rendered more hooks than during the previous render." );
5967 }
5968 }
5969
5970 currentHook = nextCurrentHook;
5971 var newHook = {
5972 memoizedState: currentHook.memoizedState,
5973 baseState: currentHook.baseState,
5974 baseQueue: currentHook.baseQueue,
5975 queue: currentHook.queue,
5976 next: null
5977 };
5978
5979 if (workInProgressHook === null) {
5980 // This is the first hook in the list.
5981 currentlyRenderingFiber$1.memoizedState = workInProgressHook = newHook;
5982 } else {
5983 // Append to the end of the list.
5984 workInProgressHook = workInProgressHook.next = newHook;
5985 }
5986 }
5987
5988 return workInProgressHook;
5989}
5990
5991function createFunctionComponentUpdateQueue() {
5992 return {
5993 lastEffect: null
5994 };
5995}
5996
5997function basicStateReducer(state, action) {
5998 // $FlowFixMe: Flow doesn't like mixed types
5999 return typeof action === 'function' ? action(state) : action;
6000}
6001
6002function mountReducer(reducer, initialArg, init) {
6003 var hook = mountWorkInProgressHook();
6004 var initialState;
6005
6006 if (init !== undefined) {
6007 initialState = init(initialArg);
6008 } else {
6009 initialState = initialArg;
6010 }
6011
6012 hook.memoizedState = hook.baseState = initialState;
6013 var queue = hook.queue = {
6014 pending: null,
6015 dispatch: null,
6016 lastRenderedReducer: reducer,
6017 lastRenderedState: initialState
6018 };
6019 var dispatch = queue.dispatch = dispatchAction.bind(null, currentlyRenderingFiber$1, queue);
6020 return [hook.memoizedState, dispatch];
6021}
6022
6023function updateReducer(reducer, initialArg, init) {
6024 var hook = updateWorkInProgressHook();
6025 var queue = hook.queue;
6026
6027 if (!(queue !== null)) {
6028 {
6029 throw Error( "Should have a queue. This is likely a bug in React. Please file an issue." );
6030 }
6031 }
6032
6033 queue.lastRenderedReducer = reducer;
6034 var current = currentHook; // The last rebase update that is NOT part of the base state.
6035
6036 var baseQueue = current.baseQueue; // The last pending update that hasn't been processed yet.
6037
6038 var pendingQueue = queue.pending;
6039
6040 if (pendingQueue !== null) {
6041 // We have new updates that haven't been processed yet.
6042 // We'll add them to the base queue.
6043 if (baseQueue !== null) {
6044 // Merge the pending queue and the base queue.
6045 var baseFirst = baseQueue.next;
6046 var pendingFirst = pendingQueue.next;
6047 baseQueue.next = pendingFirst;
6048 pendingQueue.next = baseFirst;
6049 }
6050
6051 current.baseQueue = baseQueue = pendingQueue;
6052 queue.pending = null;
6053 }
6054
6055 if (baseQueue !== null) {
6056 // We have a queue to process.
6057 var first = baseQueue.next;
6058 var newState = current.baseState;
6059 var newBaseState = null;
6060 var newBaseQueueFirst = null;
6061 var newBaseQueueLast = null;
6062 var update = first;
6063
6064 do {
6065 var updateExpirationTime = update.expirationTime;
6066
6067 if (updateExpirationTime < renderExpirationTime) {
6068 // Priority is insufficient. Skip this update. If this is the first
6069 // skipped update, the previous update/state is the new base
6070 // update/state.
6071 var clone = {
6072 expirationTime: update.expirationTime,
6073 suspenseConfig: update.suspenseConfig,
6074 action: update.action,
6075 eagerReducer: update.eagerReducer,
6076 eagerState: update.eagerState,
6077 next: null
6078 };
6079
6080 if (newBaseQueueLast === null) {
6081 newBaseQueueFirst = newBaseQueueLast = clone;
6082 newBaseState = newState;
6083 } else {
6084 newBaseQueueLast = newBaseQueueLast.next = clone;
6085 } // Update the remaining priority in the queue.
6086
6087
6088 if (updateExpirationTime > currentlyRenderingFiber$1.expirationTime) {
6089 currentlyRenderingFiber$1.expirationTime = updateExpirationTime;
6090 markUnprocessedUpdateTime(updateExpirationTime);
6091 }
6092 } else {
6093 // This update does have sufficient priority.
6094 if (newBaseQueueLast !== null) {
6095 var _clone = {
6096 expirationTime: Sync,
6097 // This update is going to be committed so we never want uncommit it.
6098 suspenseConfig: update.suspenseConfig,
6099 action: update.action,
6100 eagerReducer: update.eagerReducer,
6101 eagerState: update.eagerState,
6102 next: null
6103 };
6104 newBaseQueueLast = newBaseQueueLast.next = _clone;
6105 } // Mark the event time of this update as relevant to this render pass.
6106 // TODO: This should ideally use the true event time of this update rather than
6107 // its priority which is a derived and not reverseable value.
6108 // TODO: We should skip this update if it was already committed but currently
6109 // we have no way of detecting the difference between a committed and suspended
6110 // update here.
6111
6112
6113 markRenderEventTimeAndConfig(updateExpirationTime, update.suspenseConfig); // Process this update.
6114
6115 if (update.eagerReducer === reducer) {
6116 // If this update was processed eagerly, and its reducer matches the
6117 // current reducer, we can use the eagerly computed state.
6118 newState = update.eagerState;
6119 } else {
6120 var action = update.action;
6121 newState = reducer(newState, action);
6122 }
6123 }
6124
6125 update = update.next;
6126 } while (update !== null && update !== first);
6127
6128 if (newBaseQueueLast === null) {
6129 newBaseState = newState;
6130 } else {
6131 newBaseQueueLast.next = newBaseQueueFirst;
6132 } // Mark that the fiber performed work, but only if the new state is
6133 // different from the current state.
6134
6135
6136 if (!objectIs(newState, hook.memoizedState)) {
6137 markWorkInProgressReceivedUpdate();
6138 }
6139
6140 hook.memoizedState = newState;
6141 hook.baseState = newBaseState;
6142 hook.baseQueue = newBaseQueueLast;
6143 queue.lastRenderedState = newState;
6144 }
6145
6146 var dispatch = queue.dispatch;
6147 return [hook.memoizedState, dispatch];
6148}
6149
6150function rerenderReducer(reducer, initialArg, init) {
6151 var hook = updateWorkInProgressHook();
6152 var queue = hook.queue;
6153
6154 if (!(queue !== null)) {
6155 {
6156 throw Error( "Should have a queue. This is likely a bug in React. Please file an issue." );
6157 }
6158 }
6159
6160 queue.lastRenderedReducer = reducer; // This is a re-render. Apply the new render phase updates to the previous
6161 // work-in-progress hook.
6162
6163 var dispatch = queue.dispatch;
6164 var lastRenderPhaseUpdate = queue.pending;
6165 var newState = hook.memoizedState;
6166
6167 if (lastRenderPhaseUpdate !== null) {
6168 // The queue doesn't persist past this render pass.
6169 queue.pending = null;
6170 var firstRenderPhaseUpdate = lastRenderPhaseUpdate.next;
6171 var update = firstRenderPhaseUpdate;
6172
6173 do {
6174 // Process this render phase update. We don't have to check the
6175 // priority because it will always be the same as the current
6176 // render's.
6177 var action = update.action;
6178 newState = reducer(newState, action);
6179 update = update.next;
6180 } while (update !== firstRenderPhaseUpdate); // Mark that the fiber performed work, but only if the new state is
6181 // different from the current state.
6182
6183
6184 if (!objectIs(newState, hook.memoizedState)) {
6185 markWorkInProgressReceivedUpdate();
6186 }
6187
6188 hook.memoizedState = newState; // Don't persist the state accumulated from the render phase updates to
6189 // the base state unless the queue is empty.
6190 // TODO: Not sure if this is the desired semantics, but it's what we
6191 // do for gDSFP. I can't remember why.
6192
6193 if (hook.baseQueue === null) {
6194 hook.baseState = newState;
6195 }
6196
6197 queue.lastRenderedState = newState;
6198 }
6199
6200 return [newState, dispatch];
6201}
6202
6203function mountState(initialState) {
6204 var hook = mountWorkInProgressHook();
6205
6206 if (typeof initialState === 'function') {
6207 // $FlowFixMe: Flow doesn't like mixed types
6208 initialState = initialState();
6209 }
6210
6211 hook.memoizedState = hook.baseState = initialState;
6212 var queue = hook.queue = {
6213 pending: null,
6214 dispatch: null,
6215 lastRenderedReducer: basicStateReducer,
6216 lastRenderedState: initialState
6217 };
6218 var dispatch = queue.dispatch = dispatchAction.bind(null, currentlyRenderingFiber$1, queue);
6219 return [hook.memoizedState, dispatch];
6220}
6221
6222function updateState(initialState) {
6223 return updateReducer(basicStateReducer);
6224}
6225
6226function rerenderState(initialState) {
6227 return rerenderReducer(basicStateReducer);
6228}
6229
6230function pushEffect(tag, create, destroy, deps) {
6231 var effect = {
6232 tag: tag,
6233 create: create,
6234 destroy: destroy,
6235 deps: deps,
6236 // Circular
6237 next: null
6238 };
6239 var componentUpdateQueue = currentlyRenderingFiber$1.updateQueue;
6240
6241 if (componentUpdateQueue === null) {
6242 componentUpdateQueue = createFunctionComponentUpdateQueue();
6243 currentlyRenderingFiber$1.updateQueue = componentUpdateQueue;
6244 componentUpdateQueue.lastEffect = effect.next = effect;
6245 } else {
6246 var lastEffect = componentUpdateQueue.lastEffect;
6247
6248 if (lastEffect === null) {
6249 componentUpdateQueue.lastEffect = effect.next = effect;
6250 } else {
6251 var firstEffect = lastEffect.next;
6252 lastEffect.next = effect;
6253 effect.next = firstEffect;
6254 componentUpdateQueue.lastEffect = effect;
6255 }
6256 }
6257
6258 return effect;
6259}
6260
6261function mountRef(initialValue) {
6262 var hook = mountWorkInProgressHook();
6263 var ref = {
6264 current: initialValue
6265 };
6266
6267 {
6268 Object.seal(ref);
6269 }
6270
6271 hook.memoizedState = ref;
6272 return ref;
6273}
6274
6275function updateRef(initialValue) {
6276 var hook = updateWorkInProgressHook();
6277 return hook.memoizedState;
6278}
6279
6280function mountEffectImpl(fiberEffectTag, hookEffectTag, create, deps) {
6281 var hook = mountWorkInProgressHook();
6282 var nextDeps = deps === undefined ? null : deps;
6283 currentlyRenderingFiber$1.effectTag |= fiberEffectTag;
6284 hook.memoizedState = pushEffect(HasEffect | hookEffectTag, create, undefined, nextDeps);
6285}
6286
6287function updateEffectImpl(fiberEffectTag, hookEffectTag, create, deps) {
6288 var hook = updateWorkInProgressHook();
6289 var nextDeps = deps === undefined ? null : deps;
6290 var destroy = undefined;
6291
6292 if (currentHook !== null) {
6293 var prevEffect = currentHook.memoizedState;
6294 destroy = prevEffect.destroy;
6295
6296 if (nextDeps !== null) {
6297 var prevDeps = prevEffect.deps;
6298
6299 if (areHookInputsEqual(nextDeps, prevDeps)) {
6300 pushEffect(hookEffectTag, create, destroy, nextDeps);
6301 return;
6302 }
6303 }
6304 }
6305
6306 currentlyRenderingFiber$1.effectTag |= fiberEffectTag;
6307 hook.memoizedState = pushEffect(HasEffect | hookEffectTag, create, destroy, nextDeps);
6308}
6309
6310function mountEffect(create, deps) {
6311
6312 return mountEffectImpl(Update | Passive, Passive$1, create, deps);
6313}
6314
6315function updateEffect(create, deps) {
6316
6317 return updateEffectImpl(Update | Passive, Passive$1, create, deps);
6318}
6319
6320function mountLayoutEffect(create, deps) {
6321 return mountEffectImpl(Update, Layout, create, deps);
6322}
6323
6324function updateLayoutEffect(create, deps) {
6325 return updateEffectImpl(Update, Layout, create, deps);
6326}
6327
6328function imperativeHandleEffect(create, ref) {
6329 if (typeof ref === 'function') {
6330 var refCallback = ref;
6331
6332 var _inst = create();
6333
6334 refCallback(_inst);
6335 return function () {
6336 refCallback(null);
6337 };
6338 } else if (ref !== null && ref !== undefined) {
6339 var refObject = ref;
6340
6341 {
6342 if (!refObject.hasOwnProperty('current')) {
6343 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(', ') + '}');
6344 }
6345 }
6346
6347 var _inst2 = create();
6348
6349 refObject.current = _inst2;
6350 return function () {
6351 refObject.current = null;
6352 };
6353 }
6354}
6355
6356function mountImperativeHandle(ref, create, deps) {
6357 {
6358 if (typeof create !== 'function') {
6359 error('Expected useImperativeHandle() second argument to be a function ' + 'that creates a handle. Instead received: %s.', create !== null ? typeof create : 'null');
6360 }
6361 } // TODO: If deps are provided, should we skip comparing the ref itself?
6362
6363
6364 var effectDeps = deps !== null && deps !== undefined ? deps.concat([ref]) : null;
6365 return mountEffectImpl(Update, Layout, imperativeHandleEffect.bind(null, create, ref), effectDeps);
6366}
6367
6368function updateImperativeHandle(ref, create, deps) {
6369 {
6370 if (typeof create !== 'function') {
6371 error('Expected useImperativeHandle() second argument to be a function ' + 'that creates a handle. Instead received: %s.', create !== null ? typeof create : 'null');
6372 }
6373 } // TODO: If deps are provided, should we skip comparing the ref itself?
6374
6375
6376 var effectDeps = deps !== null && deps !== undefined ? deps.concat([ref]) : null;
6377 return updateEffectImpl(Update, Layout, imperativeHandleEffect.bind(null, create, ref), effectDeps);
6378}
6379
6380function mountDebugValue(value, formatterFn) {// This hook is normally a no-op.
6381 // The react-debug-hooks package injects its own implementation
6382 // so that e.g. DevTools can display custom hook values.
6383}
6384
6385var updateDebugValue = mountDebugValue;
6386
6387function mountCallback(callback, deps) {
6388 var hook = mountWorkInProgressHook();
6389 var nextDeps = deps === undefined ? null : deps;
6390 hook.memoizedState = [callback, nextDeps];
6391 return callback;
6392}
6393
6394function updateCallback(callback, deps) {
6395 var hook = updateWorkInProgressHook();
6396 var nextDeps = deps === undefined ? null : deps;
6397 var prevState = hook.memoizedState;
6398
6399 if (prevState !== null) {
6400 if (nextDeps !== null) {
6401 var prevDeps = prevState[1];
6402
6403 if (areHookInputsEqual(nextDeps, prevDeps)) {
6404 return prevState[0];
6405 }
6406 }
6407 }
6408
6409 hook.memoizedState = [callback, nextDeps];
6410 return callback;
6411}
6412
6413function mountMemo(nextCreate, deps) {
6414 var hook = mountWorkInProgressHook();
6415 var nextDeps = deps === undefined ? null : deps;
6416 var nextValue = nextCreate();
6417 hook.memoizedState = [nextValue, nextDeps];
6418 return nextValue;
6419}
6420
6421function updateMemo(nextCreate, deps) {
6422 var hook = updateWorkInProgressHook();
6423 var nextDeps = deps === undefined ? null : deps;
6424 var prevState = hook.memoizedState;
6425
6426 if (prevState !== null) {
6427 // Assume these are defined. If they're not, areHookInputsEqual will warn.
6428 if (nextDeps !== null) {
6429 var prevDeps = prevState[1];
6430
6431 if (areHookInputsEqual(nextDeps, prevDeps)) {
6432 return prevState[0];
6433 }
6434 }
6435 }
6436
6437 var nextValue = nextCreate();
6438 hook.memoizedState = [nextValue, nextDeps];
6439 return nextValue;
6440}
6441
6442function mountDeferredValue(value, config) {
6443 var _mountState = mountState(value),
6444 prevValue = _mountState[0],
6445 setValue = _mountState[1];
6446
6447 mountEffect(function () {
6448 var previousConfig = ReactCurrentBatchConfig$1.suspense;
6449 ReactCurrentBatchConfig$1.suspense = config === undefined ? null : config;
6450
6451 try {
6452 setValue(value);
6453 } finally {
6454 ReactCurrentBatchConfig$1.suspense = previousConfig;
6455 }
6456 }, [value, config]);
6457 return prevValue;
6458}
6459
6460function updateDeferredValue(value, config) {
6461 var _updateState = updateState(),
6462 prevValue = _updateState[0],
6463 setValue = _updateState[1];
6464
6465 updateEffect(function () {
6466 var previousConfig = ReactCurrentBatchConfig$1.suspense;
6467 ReactCurrentBatchConfig$1.suspense = config === undefined ? null : config;
6468
6469 try {
6470 setValue(value);
6471 } finally {
6472 ReactCurrentBatchConfig$1.suspense = previousConfig;
6473 }
6474 }, [value, config]);
6475 return prevValue;
6476}
6477
6478function rerenderDeferredValue(value, config) {
6479 var _rerenderState = rerenderState(),
6480 prevValue = _rerenderState[0],
6481 setValue = _rerenderState[1];
6482
6483 updateEffect(function () {
6484 var previousConfig = ReactCurrentBatchConfig$1.suspense;
6485 ReactCurrentBatchConfig$1.suspense = config === undefined ? null : config;
6486
6487 try {
6488 setValue(value);
6489 } finally {
6490 ReactCurrentBatchConfig$1.suspense = previousConfig;
6491 }
6492 }, [value, config]);
6493 return prevValue;
6494}
6495
6496function startTransition(setPending, config, callback) {
6497 var priorityLevel = getCurrentPriorityLevel();
6498 runWithPriority(priorityLevel < UserBlockingPriority ? UserBlockingPriority : priorityLevel, function () {
6499 setPending(true);
6500 });
6501 runWithPriority(priorityLevel > NormalPriority ? NormalPriority : priorityLevel, function () {
6502 var previousConfig = ReactCurrentBatchConfig$1.suspense;
6503 ReactCurrentBatchConfig$1.suspense = config === undefined ? null : config;
6504
6505 try {
6506 setPending(false);
6507 callback();
6508 } finally {
6509 ReactCurrentBatchConfig$1.suspense = previousConfig;
6510 }
6511 });
6512}
6513
6514function mountTransition(config) {
6515 var _mountState2 = mountState(false),
6516 isPending = _mountState2[0],
6517 setPending = _mountState2[1];
6518
6519 var start = mountCallback(startTransition.bind(null, setPending, config), [setPending, config]);
6520 return [start, isPending];
6521}
6522
6523function updateTransition(config) {
6524 var _updateState2 = updateState(),
6525 isPending = _updateState2[0],
6526 setPending = _updateState2[1];
6527
6528 var start = updateCallback(startTransition.bind(null, setPending, config), [setPending, config]);
6529 return [start, isPending];
6530}
6531
6532function rerenderTransition(config) {
6533 var _rerenderState2 = rerenderState(),
6534 isPending = _rerenderState2[0],
6535 setPending = _rerenderState2[1];
6536
6537 var start = updateCallback(startTransition.bind(null, setPending, config), [setPending, config]);
6538 return [start, isPending];
6539}
6540
6541function dispatchAction(fiber, queue, action) {
6542 {
6543 if (typeof arguments[3] === 'function') {
6544 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().');
6545 }
6546 }
6547
6548 var currentTime = requestCurrentTimeForUpdate();
6549 var suspenseConfig = requestCurrentSuspenseConfig();
6550 var expirationTime = computeExpirationForFiber(currentTime, fiber, suspenseConfig);
6551 var update = {
6552 expirationTime: expirationTime,
6553 suspenseConfig: suspenseConfig,
6554 action: action,
6555 eagerReducer: null,
6556 eagerState: null,
6557 next: null
6558 };
6559
6560 {
6561 update.priority = getCurrentPriorityLevel();
6562 } // Append the update to the end of the list.
6563
6564
6565 var pending = queue.pending;
6566
6567 if (pending === null) {
6568 // This is the first update. Create a circular list.
6569 update.next = update;
6570 } else {
6571 update.next = pending.next;
6572 pending.next = update;
6573 }
6574
6575 queue.pending = update;
6576 var alternate = fiber.alternate;
6577
6578 if (fiber === currentlyRenderingFiber$1 || alternate !== null && alternate === currentlyRenderingFiber$1) {
6579 // This is a render phase update. Stash it in a lazily-created map of
6580 // queue -> linked list of updates. After this render pass, we'll restart
6581 // and apply the stashed updates on top of the work-in-progress hook.
6582 didScheduleRenderPhaseUpdate = true;
6583 update.expirationTime = renderExpirationTime;
6584 currentlyRenderingFiber$1.expirationTime = renderExpirationTime;
6585 } else {
6586 if (fiber.expirationTime === NoWork && (alternate === null || alternate.expirationTime === NoWork)) {
6587 // The queue is currently empty, which means we can eagerly compute the
6588 // next state before entering the render phase. If the new state is the
6589 // same as the current state, we may be able to bail out entirely.
6590 var lastRenderedReducer = queue.lastRenderedReducer;
6591
6592 if (lastRenderedReducer !== null) {
6593 var prevDispatcher;
6594
6595 {
6596 prevDispatcher = ReactCurrentDispatcher.current;
6597 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
6598 }
6599
6600 try {
6601 var currentState = queue.lastRenderedState;
6602 var eagerState = lastRenderedReducer(currentState, action); // Stash the eagerly computed state, and the reducer used to compute
6603 // it, on the update object. If the reducer hasn't changed by the
6604 // time we enter the render phase, then the eager state can be used
6605 // without calling the reducer again.
6606
6607 update.eagerReducer = lastRenderedReducer;
6608 update.eagerState = eagerState;
6609
6610 if (objectIs(eagerState, currentState)) {
6611 // Fast path. We can bail out without scheduling React to re-render.
6612 // It's still possible that we'll need to rebase this update later,
6613 // if the component re-renders for a different reason and by that
6614 // time the reducer has changed.
6615 return;
6616 }
6617 } catch (error) {// Suppress the error. It will throw again in the render phase.
6618 } finally {
6619 {
6620 ReactCurrentDispatcher.current = prevDispatcher;
6621 }
6622 }
6623 }
6624 }
6625
6626 scheduleWork(fiber, expirationTime);
6627 }
6628}
6629
6630var ContextOnlyDispatcher = {
6631 readContext: readContext,
6632 useCallback: throwInvalidHookError,
6633 useContext: throwInvalidHookError,
6634 useEffect: throwInvalidHookError,
6635 useImperativeHandle: throwInvalidHookError,
6636 useLayoutEffect: throwInvalidHookError,
6637 useMemo: throwInvalidHookError,
6638 useReducer: throwInvalidHookError,
6639 useRef: throwInvalidHookError,
6640 useState: throwInvalidHookError,
6641 useDebugValue: throwInvalidHookError,
6642 useResponder: throwInvalidHookError,
6643 useDeferredValue: throwInvalidHookError,
6644 useTransition: throwInvalidHookError
6645};
6646var HooksDispatcherOnMountInDEV = null;
6647var HooksDispatcherOnMountWithHookTypesInDEV = null;
6648var HooksDispatcherOnUpdateInDEV = null;
6649var HooksDispatcherOnRerenderInDEV = null;
6650var InvalidNestedHooksDispatcherOnMountInDEV = null;
6651var InvalidNestedHooksDispatcherOnUpdateInDEV = null;
6652var InvalidNestedHooksDispatcherOnRerenderInDEV = null;
6653
6654{
6655 var warnInvalidContextAccess = function () {
6656 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().');
6657 };
6658
6659 var warnInvalidHookAccess = function () {
6660 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');
6661 };
6662
6663 HooksDispatcherOnMountInDEV = {
6664 readContext: function (context, observedBits) {
6665 return readContext(context, observedBits);
6666 },
6667 useCallback: function (callback, deps) {
6668 currentHookNameInDev = 'useCallback';
6669 mountHookTypesDev();
6670 checkDepsAreArrayDev(deps);
6671 return mountCallback(callback, deps);
6672 },
6673 useContext: function (context, observedBits) {
6674 currentHookNameInDev = 'useContext';
6675 mountHookTypesDev();
6676 return readContext(context, observedBits);
6677 },
6678 useEffect: function (create, deps) {
6679 currentHookNameInDev = 'useEffect';
6680 mountHookTypesDev();
6681 checkDepsAreArrayDev(deps);
6682 return mountEffect(create, deps);
6683 },
6684 useImperativeHandle: function (ref, create, deps) {
6685 currentHookNameInDev = 'useImperativeHandle';
6686 mountHookTypesDev();
6687 checkDepsAreArrayDev(deps);
6688 return mountImperativeHandle(ref, create, deps);
6689 },
6690 useLayoutEffect: function (create, deps) {
6691 currentHookNameInDev = 'useLayoutEffect';
6692 mountHookTypesDev();
6693 checkDepsAreArrayDev(deps);
6694 return mountLayoutEffect(create, deps);
6695 },
6696 useMemo: function (create, deps) {
6697 currentHookNameInDev = 'useMemo';
6698 mountHookTypesDev();
6699 checkDepsAreArrayDev(deps);
6700 var prevDispatcher = ReactCurrentDispatcher.current;
6701 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV;
6702
6703 try {
6704 return mountMemo(create, deps);
6705 } finally {
6706 ReactCurrentDispatcher.current = prevDispatcher;
6707 }
6708 },
6709 useReducer: function (reducer, initialArg, init) {
6710 currentHookNameInDev = 'useReducer';
6711 mountHookTypesDev();
6712 var prevDispatcher = ReactCurrentDispatcher.current;
6713 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV;
6714
6715 try {
6716 return mountReducer(reducer, initialArg, init);
6717 } finally {
6718 ReactCurrentDispatcher.current = prevDispatcher;
6719 }
6720 },
6721 useRef: function (initialValue) {
6722 currentHookNameInDev = 'useRef';
6723 mountHookTypesDev();
6724 return mountRef(initialValue);
6725 },
6726 useState: function (initialState) {
6727 currentHookNameInDev = 'useState';
6728 mountHookTypesDev();
6729 var prevDispatcher = ReactCurrentDispatcher.current;
6730 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV;
6731
6732 try {
6733 return mountState(initialState);
6734 } finally {
6735 ReactCurrentDispatcher.current = prevDispatcher;
6736 }
6737 },
6738 useDebugValue: function (value, formatterFn) {
6739 currentHookNameInDev = 'useDebugValue';
6740 mountHookTypesDev();
6741 return mountDebugValue();
6742 },
6743 useResponder: function (responder, props) {
6744 currentHookNameInDev = 'useResponder';
6745 mountHookTypesDev();
6746 return createDeprecatedResponderListener(responder, props);
6747 },
6748 useDeferredValue: function (value, config) {
6749 currentHookNameInDev = 'useDeferredValue';
6750 mountHookTypesDev();
6751 return mountDeferredValue(value, config);
6752 },
6753 useTransition: function (config) {
6754 currentHookNameInDev = 'useTransition';
6755 mountHookTypesDev();
6756 return mountTransition(config);
6757 }
6758 };
6759 HooksDispatcherOnMountWithHookTypesInDEV = {
6760 readContext: function (context, observedBits) {
6761 return readContext(context, observedBits);
6762 },
6763 useCallback: function (callback, deps) {
6764 currentHookNameInDev = 'useCallback';
6765 updateHookTypesDev();
6766 return mountCallback(callback, deps);
6767 },
6768 useContext: function (context, observedBits) {
6769 currentHookNameInDev = 'useContext';
6770 updateHookTypesDev();
6771 return readContext(context, observedBits);
6772 },
6773 useEffect: function (create, deps) {
6774 currentHookNameInDev = 'useEffect';
6775 updateHookTypesDev();
6776 return mountEffect(create, deps);
6777 },
6778 useImperativeHandle: function (ref, create, deps) {
6779 currentHookNameInDev = 'useImperativeHandle';
6780 updateHookTypesDev();
6781 return mountImperativeHandle(ref, create, deps);
6782 },
6783 useLayoutEffect: function (create, deps) {
6784 currentHookNameInDev = 'useLayoutEffect';
6785 updateHookTypesDev();
6786 return mountLayoutEffect(create, deps);
6787 },
6788 useMemo: function (create, deps) {
6789 currentHookNameInDev = 'useMemo';
6790 updateHookTypesDev();
6791 var prevDispatcher = ReactCurrentDispatcher.current;
6792 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV;
6793
6794 try {
6795 return mountMemo(create, deps);
6796 } finally {
6797 ReactCurrentDispatcher.current = prevDispatcher;
6798 }
6799 },
6800 useReducer: function (reducer, initialArg, init) {
6801 currentHookNameInDev = 'useReducer';
6802 updateHookTypesDev();
6803 var prevDispatcher = ReactCurrentDispatcher.current;
6804 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV;
6805
6806 try {
6807 return mountReducer(reducer, initialArg, init);
6808 } finally {
6809 ReactCurrentDispatcher.current = prevDispatcher;
6810 }
6811 },
6812 useRef: function (initialValue) {
6813 currentHookNameInDev = 'useRef';
6814 updateHookTypesDev();
6815 return mountRef(initialValue);
6816 },
6817 useState: function (initialState) {
6818 currentHookNameInDev = 'useState';
6819 updateHookTypesDev();
6820 var prevDispatcher = ReactCurrentDispatcher.current;
6821 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV;
6822
6823 try {
6824 return mountState(initialState);
6825 } finally {
6826 ReactCurrentDispatcher.current = prevDispatcher;
6827 }
6828 },
6829 useDebugValue: function (value, formatterFn) {
6830 currentHookNameInDev = 'useDebugValue';
6831 updateHookTypesDev();
6832 return mountDebugValue();
6833 },
6834 useResponder: function (responder, props) {
6835 currentHookNameInDev = 'useResponder';
6836 updateHookTypesDev();
6837 return createDeprecatedResponderListener(responder, props);
6838 },
6839 useDeferredValue: function (value, config) {
6840 currentHookNameInDev = 'useDeferredValue';
6841 updateHookTypesDev();
6842 return mountDeferredValue(value, config);
6843 },
6844 useTransition: function (config) {
6845 currentHookNameInDev = 'useTransition';
6846 updateHookTypesDev();
6847 return mountTransition(config);
6848 }
6849 };
6850 HooksDispatcherOnUpdateInDEV = {
6851 readContext: function (context, observedBits) {
6852 return readContext(context, observedBits);
6853 },
6854 useCallback: function (callback, deps) {
6855 currentHookNameInDev = 'useCallback';
6856 updateHookTypesDev();
6857 return updateCallback(callback, deps);
6858 },
6859 useContext: function (context, observedBits) {
6860 currentHookNameInDev = 'useContext';
6861 updateHookTypesDev();
6862 return readContext(context, observedBits);
6863 },
6864 useEffect: function (create, deps) {
6865 currentHookNameInDev = 'useEffect';
6866 updateHookTypesDev();
6867 return updateEffect(create, deps);
6868 },
6869 useImperativeHandle: function (ref, create, deps) {
6870 currentHookNameInDev = 'useImperativeHandle';
6871 updateHookTypesDev();
6872 return updateImperativeHandle(ref, create, deps);
6873 },
6874 useLayoutEffect: function (create, deps) {
6875 currentHookNameInDev = 'useLayoutEffect';
6876 updateHookTypesDev();
6877 return updateLayoutEffect(create, deps);
6878 },
6879 useMemo: function (create, deps) {
6880 currentHookNameInDev = 'useMemo';
6881 updateHookTypesDev();
6882 var prevDispatcher = ReactCurrentDispatcher.current;
6883 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
6884
6885 try {
6886 return updateMemo(create, deps);
6887 } finally {
6888 ReactCurrentDispatcher.current = prevDispatcher;
6889 }
6890 },
6891 useReducer: function (reducer, initialArg, init) {
6892 currentHookNameInDev = 'useReducer';
6893 updateHookTypesDev();
6894 var prevDispatcher = ReactCurrentDispatcher.current;
6895 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
6896
6897 try {
6898 return updateReducer(reducer, initialArg, init);
6899 } finally {
6900 ReactCurrentDispatcher.current = prevDispatcher;
6901 }
6902 },
6903 useRef: function (initialValue) {
6904 currentHookNameInDev = 'useRef';
6905 updateHookTypesDev();
6906 return updateRef();
6907 },
6908 useState: function (initialState) {
6909 currentHookNameInDev = 'useState';
6910 updateHookTypesDev();
6911 var prevDispatcher = ReactCurrentDispatcher.current;
6912 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
6913
6914 try {
6915 return updateState(initialState);
6916 } finally {
6917 ReactCurrentDispatcher.current = prevDispatcher;
6918 }
6919 },
6920 useDebugValue: function (value, formatterFn) {
6921 currentHookNameInDev = 'useDebugValue';
6922 updateHookTypesDev();
6923 return updateDebugValue();
6924 },
6925 useResponder: function (responder, props) {
6926 currentHookNameInDev = 'useResponder';
6927 updateHookTypesDev();
6928 return createDeprecatedResponderListener(responder, props);
6929 },
6930 useDeferredValue: function (value, config) {
6931 currentHookNameInDev = 'useDeferredValue';
6932 updateHookTypesDev();
6933 return updateDeferredValue(value, config);
6934 },
6935 useTransition: function (config) {
6936 currentHookNameInDev = 'useTransition';
6937 updateHookTypesDev();
6938 return updateTransition(config);
6939 }
6940 };
6941 HooksDispatcherOnRerenderInDEV = {
6942 readContext: function (context, observedBits) {
6943 return readContext(context, observedBits);
6944 },
6945 useCallback: function (callback, deps) {
6946 currentHookNameInDev = 'useCallback';
6947 updateHookTypesDev();
6948 return updateCallback(callback, deps);
6949 },
6950 useContext: function (context, observedBits) {
6951 currentHookNameInDev = 'useContext';
6952 updateHookTypesDev();
6953 return readContext(context, observedBits);
6954 },
6955 useEffect: function (create, deps) {
6956 currentHookNameInDev = 'useEffect';
6957 updateHookTypesDev();
6958 return updateEffect(create, deps);
6959 },
6960 useImperativeHandle: function (ref, create, deps) {
6961 currentHookNameInDev = 'useImperativeHandle';
6962 updateHookTypesDev();
6963 return updateImperativeHandle(ref, create, deps);
6964 },
6965 useLayoutEffect: function (create, deps) {
6966 currentHookNameInDev = 'useLayoutEffect';
6967 updateHookTypesDev();
6968 return updateLayoutEffect(create, deps);
6969 },
6970 useMemo: function (create, deps) {
6971 currentHookNameInDev = 'useMemo';
6972 updateHookTypesDev();
6973 var prevDispatcher = ReactCurrentDispatcher.current;
6974 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnRerenderInDEV;
6975
6976 try {
6977 return updateMemo(create, deps);
6978 } finally {
6979 ReactCurrentDispatcher.current = prevDispatcher;
6980 }
6981 },
6982 useReducer: function (reducer, initialArg, init) {
6983 currentHookNameInDev = 'useReducer';
6984 updateHookTypesDev();
6985 var prevDispatcher = ReactCurrentDispatcher.current;
6986 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnRerenderInDEV;
6987
6988 try {
6989 return rerenderReducer(reducer, initialArg, init);
6990 } finally {
6991 ReactCurrentDispatcher.current = prevDispatcher;
6992 }
6993 },
6994 useRef: function (initialValue) {
6995 currentHookNameInDev = 'useRef';
6996 updateHookTypesDev();
6997 return updateRef();
6998 },
6999 useState: function (initialState) {
7000 currentHookNameInDev = 'useState';
7001 updateHookTypesDev();
7002 var prevDispatcher = ReactCurrentDispatcher.current;
7003 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnRerenderInDEV;
7004
7005 try {
7006 return rerenderState(initialState);
7007 } finally {
7008 ReactCurrentDispatcher.current = prevDispatcher;
7009 }
7010 },
7011 useDebugValue: function (value, formatterFn) {
7012 currentHookNameInDev = 'useDebugValue';
7013 updateHookTypesDev();
7014 return updateDebugValue();
7015 },
7016 useResponder: function (responder, props) {
7017 currentHookNameInDev = 'useResponder';
7018 updateHookTypesDev();
7019 return createDeprecatedResponderListener(responder, props);
7020 },
7021 useDeferredValue: function (value, config) {
7022 currentHookNameInDev = 'useDeferredValue';
7023 updateHookTypesDev();
7024 return rerenderDeferredValue(value, config);
7025 },
7026 useTransition: function (config) {
7027 currentHookNameInDev = 'useTransition';
7028 updateHookTypesDev();
7029 return rerenderTransition(config);
7030 }
7031 };
7032 InvalidNestedHooksDispatcherOnMountInDEV = {
7033 readContext: function (context, observedBits) {
7034 warnInvalidContextAccess();
7035 return readContext(context, observedBits);
7036 },
7037 useCallback: function (callback, deps) {
7038 currentHookNameInDev = 'useCallback';
7039 warnInvalidHookAccess();
7040 mountHookTypesDev();
7041 return mountCallback(callback, deps);
7042 },
7043 useContext: function (context, observedBits) {
7044 currentHookNameInDev = 'useContext';
7045 warnInvalidHookAccess();
7046 mountHookTypesDev();
7047 return readContext(context, observedBits);
7048 },
7049 useEffect: function (create, deps) {
7050 currentHookNameInDev = 'useEffect';
7051 warnInvalidHookAccess();
7052 mountHookTypesDev();
7053 return mountEffect(create, deps);
7054 },
7055 useImperativeHandle: function (ref, create, deps) {
7056 currentHookNameInDev = 'useImperativeHandle';
7057 warnInvalidHookAccess();
7058 mountHookTypesDev();
7059 return mountImperativeHandle(ref, create, deps);
7060 },
7061 useLayoutEffect: function (create, deps) {
7062 currentHookNameInDev = 'useLayoutEffect';
7063 warnInvalidHookAccess();
7064 mountHookTypesDev();
7065 return mountLayoutEffect(create, deps);
7066 },
7067 useMemo: function (create, deps) {
7068 currentHookNameInDev = 'useMemo';
7069 warnInvalidHookAccess();
7070 mountHookTypesDev();
7071 var prevDispatcher = ReactCurrentDispatcher.current;
7072 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV;
7073
7074 try {
7075 return mountMemo(create, deps);
7076 } finally {
7077 ReactCurrentDispatcher.current = prevDispatcher;
7078 }
7079 },
7080 useReducer: function (reducer, initialArg, init) {
7081 currentHookNameInDev = 'useReducer';
7082 warnInvalidHookAccess();
7083 mountHookTypesDev();
7084 var prevDispatcher = ReactCurrentDispatcher.current;
7085 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV;
7086
7087 try {
7088 return mountReducer(reducer, initialArg, init);
7089 } finally {
7090 ReactCurrentDispatcher.current = prevDispatcher;
7091 }
7092 },
7093 useRef: function (initialValue) {
7094 currentHookNameInDev = 'useRef';
7095 warnInvalidHookAccess();
7096 mountHookTypesDev();
7097 return mountRef(initialValue);
7098 },
7099 useState: function (initialState) {
7100 currentHookNameInDev = 'useState';
7101 warnInvalidHookAccess();
7102 mountHookTypesDev();
7103 var prevDispatcher = ReactCurrentDispatcher.current;
7104 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV;
7105
7106 try {
7107 return mountState(initialState);
7108 } finally {
7109 ReactCurrentDispatcher.current = prevDispatcher;
7110 }
7111 },
7112 useDebugValue: function (value, formatterFn) {
7113 currentHookNameInDev = 'useDebugValue';
7114 warnInvalidHookAccess();
7115 mountHookTypesDev();
7116 return mountDebugValue();
7117 },
7118 useResponder: function (responder, props) {
7119 currentHookNameInDev = 'useResponder';
7120 warnInvalidHookAccess();
7121 mountHookTypesDev();
7122 return createDeprecatedResponderListener(responder, props);
7123 },
7124 useDeferredValue: function (value, config) {
7125 currentHookNameInDev = 'useDeferredValue';
7126 warnInvalidHookAccess();
7127 mountHookTypesDev();
7128 return mountDeferredValue(value, config);
7129 },
7130 useTransition: function (config) {
7131 currentHookNameInDev = 'useTransition';
7132 warnInvalidHookAccess();
7133 mountHookTypesDev();
7134 return mountTransition(config);
7135 }
7136 };
7137 InvalidNestedHooksDispatcherOnUpdateInDEV = {
7138 readContext: function (context, observedBits) {
7139 warnInvalidContextAccess();
7140 return readContext(context, observedBits);
7141 },
7142 useCallback: function (callback, deps) {
7143 currentHookNameInDev = 'useCallback';
7144 warnInvalidHookAccess();
7145 updateHookTypesDev();
7146 return updateCallback(callback, deps);
7147 },
7148 useContext: function (context, observedBits) {
7149 currentHookNameInDev = 'useContext';
7150 warnInvalidHookAccess();
7151 updateHookTypesDev();
7152 return readContext(context, observedBits);
7153 },
7154 useEffect: function (create, deps) {
7155 currentHookNameInDev = 'useEffect';
7156 warnInvalidHookAccess();
7157 updateHookTypesDev();
7158 return updateEffect(create, deps);
7159 },
7160 useImperativeHandle: function (ref, create, deps) {
7161 currentHookNameInDev = 'useImperativeHandle';
7162 warnInvalidHookAccess();
7163 updateHookTypesDev();
7164 return updateImperativeHandle(ref, create, deps);
7165 },
7166 useLayoutEffect: function (create, deps) {
7167 currentHookNameInDev = 'useLayoutEffect';
7168 warnInvalidHookAccess();
7169 updateHookTypesDev();
7170 return updateLayoutEffect(create, deps);
7171 },
7172 useMemo: function (create, deps) {
7173 currentHookNameInDev = 'useMemo';
7174 warnInvalidHookAccess();
7175 updateHookTypesDev();
7176 var prevDispatcher = ReactCurrentDispatcher.current;
7177 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
7178
7179 try {
7180 return updateMemo(create, deps);
7181 } finally {
7182 ReactCurrentDispatcher.current = prevDispatcher;
7183 }
7184 },
7185 useReducer: function (reducer, initialArg, init) {
7186 currentHookNameInDev = 'useReducer';
7187 warnInvalidHookAccess();
7188 updateHookTypesDev();
7189 var prevDispatcher = ReactCurrentDispatcher.current;
7190 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
7191
7192 try {
7193 return updateReducer(reducer, initialArg, init);
7194 } finally {
7195 ReactCurrentDispatcher.current = prevDispatcher;
7196 }
7197 },
7198 useRef: function (initialValue) {
7199 currentHookNameInDev = 'useRef';
7200 warnInvalidHookAccess();
7201 updateHookTypesDev();
7202 return updateRef();
7203 },
7204 useState: function (initialState) {
7205 currentHookNameInDev = 'useState';
7206 warnInvalidHookAccess();
7207 updateHookTypesDev();
7208 var prevDispatcher = ReactCurrentDispatcher.current;
7209 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
7210
7211 try {
7212 return updateState(initialState);
7213 } finally {
7214 ReactCurrentDispatcher.current = prevDispatcher;
7215 }
7216 },
7217 useDebugValue: function (value, formatterFn) {
7218 currentHookNameInDev = 'useDebugValue';
7219 warnInvalidHookAccess();
7220 updateHookTypesDev();
7221 return updateDebugValue();
7222 },
7223 useResponder: function (responder, props) {
7224 currentHookNameInDev = 'useResponder';
7225 warnInvalidHookAccess();
7226 updateHookTypesDev();
7227 return createDeprecatedResponderListener(responder, props);
7228 },
7229 useDeferredValue: function (value, config) {
7230 currentHookNameInDev = 'useDeferredValue';
7231 warnInvalidHookAccess();
7232 updateHookTypesDev();
7233 return updateDeferredValue(value, config);
7234 },
7235 useTransition: function (config) {
7236 currentHookNameInDev = 'useTransition';
7237 warnInvalidHookAccess();
7238 updateHookTypesDev();
7239 return updateTransition(config);
7240 }
7241 };
7242 InvalidNestedHooksDispatcherOnRerenderInDEV = {
7243 readContext: function (context, observedBits) {
7244 warnInvalidContextAccess();
7245 return readContext(context, observedBits);
7246 },
7247 useCallback: function (callback, deps) {
7248 currentHookNameInDev = 'useCallback';
7249 warnInvalidHookAccess();
7250 updateHookTypesDev();
7251 return updateCallback(callback, deps);
7252 },
7253 useContext: function (context, observedBits) {
7254 currentHookNameInDev = 'useContext';
7255 warnInvalidHookAccess();
7256 updateHookTypesDev();
7257 return readContext(context, observedBits);
7258 },
7259 useEffect: function (create, deps) {
7260 currentHookNameInDev = 'useEffect';
7261 warnInvalidHookAccess();
7262 updateHookTypesDev();
7263 return updateEffect(create, deps);
7264 },
7265 useImperativeHandle: function (ref, create, deps) {
7266 currentHookNameInDev = 'useImperativeHandle';
7267 warnInvalidHookAccess();
7268 updateHookTypesDev();
7269 return updateImperativeHandle(ref, create, deps);
7270 },
7271 useLayoutEffect: function (create, deps) {
7272 currentHookNameInDev = 'useLayoutEffect';
7273 warnInvalidHookAccess();
7274 updateHookTypesDev();
7275 return updateLayoutEffect(create, deps);
7276 },
7277 useMemo: function (create, deps) {
7278 currentHookNameInDev = 'useMemo';
7279 warnInvalidHookAccess();
7280 updateHookTypesDev();
7281 var prevDispatcher = ReactCurrentDispatcher.current;
7282 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
7283
7284 try {
7285 return updateMemo(create, deps);
7286 } finally {
7287 ReactCurrentDispatcher.current = prevDispatcher;
7288 }
7289 },
7290 useReducer: function (reducer, initialArg, init) {
7291 currentHookNameInDev = 'useReducer';
7292 warnInvalidHookAccess();
7293 updateHookTypesDev();
7294 var prevDispatcher = ReactCurrentDispatcher.current;
7295 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
7296
7297 try {
7298 return rerenderReducer(reducer, initialArg, init);
7299 } finally {
7300 ReactCurrentDispatcher.current = prevDispatcher;
7301 }
7302 },
7303 useRef: function (initialValue) {
7304 currentHookNameInDev = 'useRef';
7305 warnInvalidHookAccess();
7306 updateHookTypesDev();
7307 return updateRef();
7308 },
7309 useState: function (initialState) {
7310 currentHookNameInDev = 'useState';
7311 warnInvalidHookAccess();
7312 updateHookTypesDev();
7313 var prevDispatcher = ReactCurrentDispatcher.current;
7314 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
7315
7316 try {
7317 return rerenderState(initialState);
7318 } finally {
7319 ReactCurrentDispatcher.current = prevDispatcher;
7320 }
7321 },
7322 useDebugValue: function (value, formatterFn) {
7323 currentHookNameInDev = 'useDebugValue';
7324 warnInvalidHookAccess();
7325 updateHookTypesDev();
7326 return updateDebugValue();
7327 },
7328 useResponder: function (responder, props) {
7329 currentHookNameInDev = 'useResponder';
7330 warnInvalidHookAccess();
7331 updateHookTypesDev();
7332 return createDeprecatedResponderListener(responder, props);
7333 },
7334 useDeferredValue: function (value, config) {
7335 currentHookNameInDev = 'useDeferredValue';
7336 warnInvalidHookAccess();
7337 updateHookTypesDev();
7338 return rerenderDeferredValue(value, config);
7339 },
7340 useTransition: function (config) {
7341 currentHookNameInDev = 'useTransition';
7342 warnInvalidHookAccess();
7343 updateHookTypesDev();
7344 return rerenderTransition(config);
7345 }
7346 };
7347}
7348
7349var now$1 = Scheduler.unstable_now;
7350var commitTime = 0;
7351var profilerStartTime = -1;
7352
7353function getCommitTime() {
7354 return commitTime;
7355}
7356
7357function recordCommitTime() {
7358
7359 commitTime = now$1();
7360}
7361
7362function startProfilerTimer(fiber) {
7363
7364 profilerStartTime = now$1();
7365
7366 if (fiber.actualStartTime < 0) {
7367 fiber.actualStartTime = now$1();
7368 }
7369}
7370
7371function stopProfilerTimerIfRunning(fiber) {
7372
7373 profilerStartTime = -1;
7374}
7375
7376function stopProfilerTimerIfRunningAndRecordDelta(fiber, overrideBaseTime) {
7377
7378 if (profilerStartTime >= 0) {
7379 var elapsedTime = now$1() - profilerStartTime;
7380 fiber.actualDuration += elapsedTime;
7381
7382 if (overrideBaseTime) {
7383 fiber.selfBaseDuration = elapsedTime;
7384 }
7385
7386 profilerStartTime = -1;
7387 }
7388}
7389
7390function enterHydrationState(fiber) {
7391 {
7392 return false;
7393 }
7394}
7395
7396function prepareToHydrateHostInstance(fiber, rootContainerInstance, hostContext) {
7397 {
7398 {
7399 {
7400 throw Error( "Expected prepareToHydrateHostInstance() to never be called. This error is likely caused by a bug in React. Please file an issue." );
7401 }
7402 }
7403 }
7404}
7405
7406function prepareToHydrateHostTextInstance(fiber) {
7407 {
7408 {
7409 {
7410 throw Error( "Expected prepareToHydrateHostTextInstance() to never be called. This error is likely caused by a bug in React. Please file an issue." );
7411 }
7412 }
7413 }
7414 var shouldUpdate = hydrateTextInstance();
7415}
7416
7417function popHydrationState(fiber) {
7418 {
7419 return false;
7420 }
7421}
7422
7423var ReactCurrentOwner$1 = ReactSharedInternals.ReactCurrentOwner;
7424var didReceiveUpdate = false;
7425var didWarnAboutBadClass;
7426var didWarnAboutModulePatternComponent;
7427var didWarnAboutContextTypeOnFunctionComponent;
7428var didWarnAboutGetDerivedStateOnFunctionComponent;
7429var didWarnAboutFunctionRefs;
7430var didWarnAboutReassigningProps;
7431var didWarnAboutRevealOrder;
7432var didWarnAboutTailOptions;
7433
7434{
7435 didWarnAboutBadClass = {};
7436 didWarnAboutModulePatternComponent = {};
7437 didWarnAboutContextTypeOnFunctionComponent = {};
7438 didWarnAboutGetDerivedStateOnFunctionComponent = {};
7439 didWarnAboutFunctionRefs = {};
7440 didWarnAboutReassigningProps = false;
7441 didWarnAboutRevealOrder = {};
7442 didWarnAboutTailOptions = {};
7443}
7444
7445function reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime) {
7446 if (current === null) {
7447 // If this is a fresh new component that hasn't been rendered yet, we
7448 // won't update its child set by applying minimal side-effects. Instead,
7449 // we will add them all to the child before it gets rendered. That means
7450 // we can optimize this reconciliation pass by not tracking side-effects.
7451 workInProgress.child = mountChildFibers(workInProgress, null, nextChildren, renderExpirationTime);
7452 } else {
7453 // If the current child is the same as the work in progress, it means that
7454 // we haven't yet started any work on these children. Therefore, we use
7455 // the clone algorithm to create a copy of all the current children.
7456 // If we had any progressed work already, that is invalid at this point so
7457 // let's throw it out.
7458 workInProgress.child = reconcileChildFibers(workInProgress, current.child, nextChildren, renderExpirationTime);
7459 }
7460}
7461
7462function forceUnmountCurrentAndReconcile(current, workInProgress, nextChildren, renderExpirationTime) {
7463 // This function is fork of reconcileChildren. It's used in cases where we
7464 // want to reconcile without matching against the existing set. This has the
7465 // effect of all current children being unmounted; even if the type and key
7466 // are the same, the old child is unmounted and a new child is created.
7467 //
7468 // To do this, we're going to go through the reconcile algorithm twice. In
7469 // the first pass, we schedule a deletion for all the current children by
7470 // passing null.
7471 workInProgress.child = reconcileChildFibers(workInProgress, current.child, null, renderExpirationTime); // In the second pass, we mount the new children. The trick here is that we
7472 // pass null in place of where we usually pass the current child set. This has
7473 // the effect of remounting all children regardless of whether their
7474 // identities match.
7475
7476 workInProgress.child = reconcileChildFibers(workInProgress, null, nextChildren, renderExpirationTime);
7477}
7478
7479function updateForwardRef(current, workInProgress, Component, nextProps, renderExpirationTime) {
7480 // TODO: current can be non-null here even if the component
7481 // hasn't yet mounted. This happens after the first render suspends.
7482 // We'll need to figure out if this is fine or can cause issues.
7483 {
7484 if (workInProgress.type !== workInProgress.elementType) {
7485 // Lazy component props can't be validated in createElement
7486 // because they're only guaranteed to be resolved here.
7487 var innerPropTypes = Component.propTypes;
7488
7489 if (innerPropTypes) {
7490 checkPropTypes(innerPropTypes, nextProps, // Resolved props
7491 'prop', getComponentName(Component), getCurrentFiberStackInDev);
7492 }
7493 }
7494 }
7495
7496 var render = Component.render;
7497 var ref = workInProgress.ref; // The rest is a fork of updateFunctionComponent
7498
7499 var nextChildren;
7500 prepareToReadContext(workInProgress, renderExpirationTime);
7501
7502 {
7503 ReactCurrentOwner$1.current = workInProgress;
7504 setIsRendering(true);
7505 nextChildren = renderWithHooks(current, workInProgress, render, nextProps, ref, renderExpirationTime);
7506
7507 if ( workInProgress.mode & StrictMode) {
7508 // Only double-render components with Hooks
7509 if (workInProgress.memoizedState !== null) {
7510 nextChildren = renderWithHooks(current, workInProgress, render, nextProps, ref, renderExpirationTime);
7511 }
7512 }
7513
7514 setIsRendering(false);
7515 }
7516
7517 if (current !== null && !didReceiveUpdate) {
7518 bailoutHooks(current, workInProgress, renderExpirationTime);
7519 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderExpirationTime);
7520 } // React DevTools reads this flag.
7521
7522
7523 workInProgress.effectTag |= PerformedWork;
7524 reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime);
7525 return workInProgress.child;
7526}
7527
7528function updateMemoComponent(current, workInProgress, Component, nextProps, updateExpirationTime, renderExpirationTime) {
7529 if (current === null) {
7530 var type = Component.type;
7531
7532 if (isSimpleFunctionComponent(type) && Component.compare === null && // SimpleMemoComponent codepath doesn't resolve outer props either.
7533 Component.defaultProps === undefined) {
7534 var resolvedType = type;
7535
7536 {
7537 resolvedType = resolveFunctionForHotReloading(type);
7538 } // If this is a plain function component without default props,
7539 // and with only the default shallow comparison, we upgrade it
7540 // to a SimpleMemoComponent to allow fast path updates.
7541
7542
7543 workInProgress.tag = SimpleMemoComponent;
7544 workInProgress.type = resolvedType;
7545
7546 {
7547 validateFunctionComponentInDev(workInProgress, type);
7548 }
7549
7550 return updateSimpleMemoComponent(current, workInProgress, resolvedType, nextProps, updateExpirationTime, renderExpirationTime);
7551 }
7552
7553 {
7554 var innerPropTypes = type.propTypes;
7555
7556 if (innerPropTypes) {
7557 // Inner memo component props aren't currently validated in createElement.
7558 // We could move it there, but we'd still need this for lazy code path.
7559 checkPropTypes(innerPropTypes, nextProps, // Resolved props
7560 'prop', getComponentName(type), getCurrentFiberStackInDev);
7561 }
7562 }
7563
7564 var child = createFiberFromTypeAndProps(Component.type, null, nextProps, null, workInProgress.mode, renderExpirationTime);
7565 child.ref = workInProgress.ref;
7566 child.return = workInProgress;
7567 workInProgress.child = child;
7568 return child;
7569 }
7570
7571 {
7572 var _type = Component.type;
7573 var _innerPropTypes = _type.propTypes;
7574
7575 if (_innerPropTypes) {
7576 // Inner memo component props aren't currently validated in createElement.
7577 // We could move it there, but we'd still need this for lazy code path.
7578 checkPropTypes(_innerPropTypes, nextProps, // Resolved props
7579 'prop', getComponentName(_type), getCurrentFiberStackInDev);
7580 }
7581 }
7582
7583 var currentChild = current.child; // This is always exactly one child
7584
7585 if (updateExpirationTime < renderExpirationTime) {
7586 // This will be the props with resolved defaultProps,
7587 // unlike current.memoizedProps which will be the unresolved ones.
7588 var prevProps = currentChild.memoizedProps; // Default to shallow comparison
7589
7590 var compare = Component.compare;
7591 compare = compare !== null ? compare : shallowEqual;
7592
7593 if (compare(prevProps, nextProps) && current.ref === workInProgress.ref) {
7594 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderExpirationTime);
7595 }
7596 } // React DevTools reads this flag.
7597
7598
7599 workInProgress.effectTag |= PerformedWork;
7600 var newChild = createWorkInProgress(currentChild, nextProps);
7601 newChild.ref = workInProgress.ref;
7602 newChild.return = workInProgress;
7603 workInProgress.child = newChild;
7604 return newChild;
7605}
7606
7607function updateSimpleMemoComponent(current, workInProgress, Component, nextProps, updateExpirationTime, renderExpirationTime) {
7608 // TODO: current can be non-null here even if the component
7609 // hasn't yet mounted. This happens when the inner render suspends.
7610 // We'll need to figure out if this is fine or can cause issues.
7611 {
7612 if (workInProgress.type !== workInProgress.elementType) {
7613 // Lazy component props can't be validated in createElement
7614 // because they're only guaranteed to be resolved here.
7615 var outerMemoType = workInProgress.elementType;
7616
7617 if (outerMemoType.$$typeof === REACT_LAZY_TYPE) {
7618 // We warn when you define propTypes on lazy()
7619 // so let's just skip over it to find memo() outer wrapper.
7620 // Inner props for memo are validated later.
7621 outerMemoType = refineResolvedLazyComponent(outerMemoType);
7622 }
7623
7624 var outerPropTypes = outerMemoType && outerMemoType.propTypes;
7625
7626 if (outerPropTypes) {
7627 checkPropTypes(outerPropTypes, nextProps, // Resolved (SimpleMemoComponent has no defaultProps)
7628 'prop', getComponentName(outerMemoType), getCurrentFiberStackInDev);
7629 } // Inner propTypes will be validated in the function component path.
7630
7631 }
7632 }
7633
7634 if (current !== null) {
7635 var prevProps = current.memoizedProps;
7636
7637 if (shallowEqual(prevProps, nextProps) && current.ref === workInProgress.ref && ( // Prevent bailout if the implementation changed due to hot reload.
7638 workInProgress.type === current.type )) {
7639 didReceiveUpdate = false;
7640
7641 if (updateExpirationTime < renderExpirationTime) {
7642 // The pending update priority was cleared at the beginning of
7643 // beginWork. We're about to bail out, but there might be additional
7644 // updates at a lower priority. Usually, the priority level of the
7645 // remaining updates is accumlated during the evaluation of the
7646 // component (i.e. when processing the update queue). But since since
7647 // we're bailing out early *without* evaluating the component, we need
7648 // to account for it here, too. Reset to the value of the current fiber.
7649 // NOTE: This only applies to SimpleMemoComponent, not MemoComponent,
7650 // because a MemoComponent fiber does not have hooks or an update queue;
7651 // rather, it wraps around an inner component, which may or may not
7652 // contains hooks.
7653 // TODO: Move the reset at in beginWork out of the common path so that
7654 // this is no longer necessary.
7655 workInProgress.expirationTime = current.expirationTime;
7656 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderExpirationTime);
7657 }
7658 }
7659 }
7660
7661 return updateFunctionComponent(current, workInProgress, Component, nextProps, renderExpirationTime);
7662}
7663
7664function updateFragment(current, workInProgress, renderExpirationTime) {
7665 var nextChildren = workInProgress.pendingProps;
7666 reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime);
7667 return workInProgress.child;
7668}
7669
7670function updateMode(current, workInProgress, renderExpirationTime) {
7671 var nextChildren = workInProgress.pendingProps.children;
7672 reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime);
7673 return workInProgress.child;
7674}
7675
7676function updateProfiler(current, workInProgress, renderExpirationTime) {
7677 {
7678 workInProgress.effectTag |= Update;
7679 }
7680
7681 var nextProps = workInProgress.pendingProps;
7682 var nextChildren = nextProps.children;
7683 reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime);
7684 return workInProgress.child;
7685}
7686
7687function markRef(current, workInProgress) {
7688 var ref = workInProgress.ref;
7689
7690 if (current === null && ref !== null || current !== null && current.ref !== ref) {
7691 // Schedule a Ref effect
7692 workInProgress.effectTag |= Ref;
7693 }
7694}
7695
7696function updateFunctionComponent(current, workInProgress, Component, nextProps, renderExpirationTime) {
7697 {
7698 if (workInProgress.type !== workInProgress.elementType) {
7699 // Lazy component props can't be validated in createElement
7700 // because they're only guaranteed to be resolved here.
7701 var innerPropTypes = Component.propTypes;
7702
7703 if (innerPropTypes) {
7704 checkPropTypes(innerPropTypes, nextProps, // Resolved props
7705 'prop', getComponentName(Component), getCurrentFiberStackInDev);
7706 }
7707 }
7708 }
7709
7710 var context;
7711
7712 {
7713 var unmaskedContext = getUnmaskedContext(workInProgress, Component, true);
7714 context = getMaskedContext(workInProgress, unmaskedContext);
7715 }
7716
7717 var nextChildren;
7718 prepareToReadContext(workInProgress, renderExpirationTime);
7719
7720 {
7721 ReactCurrentOwner$1.current = workInProgress;
7722 setIsRendering(true);
7723 nextChildren = renderWithHooks(current, workInProgress, Component, nextProps, context, renderExpirationTime);
7724
7725 if ( workInProgress.mode & StrictMode) {
7726 // Only double-render components with Hooks
7727 if (workInProgress.memoizedState !== null) {
7728 nextChildren = renderWithHooks(current, workInProgress, Component, nextProps, context, renderExpirationTime);
7729 }
7730 }
7731
7732 setIsRendering(false);
7733 }
7734
7735 if (current !== null && !didReceiveUpdate) {
7736 bailoutHooks(current, workInProgress, renderExpirationTime);
7737 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderExpirationTime);
7738 } // React DevTools reads this flag.
7739
7740
7741 workInProgress.effectTag |= PerformedWork;
7742 reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime);
7743 return workInProgress.child;
7744}
7745
7746function updateClassComponent(current, workInProgress, Component, nextProps, renderExpirationTime) {
7747 {
7748 if (workInProgress.type !== workInProgress.elementType) {
7749 // Lazy component props can't be validated in createElement
7750 // because they're only guaranteed to be resolved here.
7751 var innerPropTypes = Component.propTypes;
7752
7753 if (innerPropTypes) {
7754 checkPropTypes(innerPropTypes, nextProps, // Resolved props
7755 'prop', getComponentName(Component), getCurrentFiberStackInDev);
7756 }
7757 }
7758 } // Push context providers early to prevent context stack mismatches.
7759 // During mounting we don't know the child context yet as the instance doesn't exist.
7760 // We will invalidate the child context in finishClassComponent() right after rendering.
7761
7762
7763 var hasContext;
7764
7765 if (isContextProvider(Component)) {
7766 hasContext = true;
7767 pushContextProvider(workInProgress);
7768 } else {
7769 hasContext = false;
7770 }
7771
7772 prepareToReadContext(workInProgress, renderExpirationTime);
7773 var instance = workInProgress.stateNode;
7774 var shouldUpdate;
7775
7776 if (instance === null) {
7777 if (current !== null) {
7778 // A class component without an instance only mounts if it suspended
7779 // inside a non-concurrent tree, in an inconsistent state. We want to
7780 // treat it like a new mount, even though an empty version of it already
7781 // committed. Disconnect the alternate pointers.
7782 current.alternate = null;
7783 workInProgress.alternate = null; // Since this is conceptually a new fiber, schedule a Placement effect
7784
7785 workInProgress.effectTag |= Placement;
7786 } // In the initial pass we might need to construct the instance.
7787
7788
7789 constructClassInstance(workInProgress, Component, nextProps);
7790 mountClassInstance(workInProgress, Component, nextProps, renderExpirationTime);
7791 shouldUpdate = true;
7792 } else if (current === null) {
7793 // In a resume, we'll already have an instance we can reuse.
7794 shouldUpdate = resumeMountClassInstance(workInProgress, Component, nextProps, renderExpirationTime);
7795 } else {
7796 shouldUpdate = updateClassInstance(current, workInProgress, Component, nextProps, renderExpirationTime);
7797 }
7798
7799 var nextUnitOfWork = finishClassComponent(current, workInProgress, Component, shouldUpdate, hasContext, renderExpirationTime);
7800
7801 {
7802 var inst = workInProgress.stateNode;
7803
7804 if (inst.props !== nextProps) {
7805 if (!didWarnAboutReassigningProps) {
7806 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');
7807 }
7808
7809 didWarnAboutReassigningProps = true;
7810 }
7811 }
7812
7813 return nextUnitOfWork;
7814}
7815
7816function finishClassComponent(current, workInProgress, Component, shouldUpdate, hasContext, renderExpirationTime) {
7817 // Refs should update even if shouldComponentUpdate returns false
7818 markRef(current, workInProgress);
7819 var didCaptureError = (workInProgress.effectTag & DidCapture) !== NoEffect;
7820
7821 if (!shouldUpdate && !didCaptureError) {
7822 // Context providers should defer to sCU for rendering
7823 if (hasContext) {
7824 invalidateContextProvider(workInProgress, Component, false);
7825 }
7826
7827 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderExpirationTime);
7828 }
7829
7830 var instance = workInProgress.stateNode; // Rerender
7831
7832 ReactCurrentOwner$1.current = workInProgress;
7833 var nextChildren;
7834
7835 if (didCaptureError && typeof Component.getDerivedStateFromError !== 'function') {
7836 // If we captured an error, but getDerivedStateFromError is not defined,
7837 // unmount all the children. componentDidCatch will schedule an update to
7838 // re-render a fallback. This is temporary until we migrate everyone to
7839 // the new API.
7840 // TODO: Warn in a future release.
7841 nextChildren = null;
7842
7843 {
7844 stopProfilerTimerIfRunning();
7845 }
7846 } else {
7847 {
7848 setIsRendering(true);
7849 nextChildren = instance.render();
7850
7851 if ( workInProgress.mode & StrictMode) {
7852 instance.render();
7853 }
7854
7855 setIsRendering(false);
7856 }
7857 } // React DevTools reads this flag.
7858
7859
7860 workInProgress.effectTag |= PerformedWork;
7861
7862 if (current !== null && didCaptureError) {
7863 // If we're recovering from an error, reconcile without reusing any of
7864 // the existing children. Conceptually, the normal children and the children
7865 // that are shown on error are two different sets, so we shouldn't reuse
7866 // normal children even if their identities match.
7867 forceUnmountCurrentAndReconcile(current, workInProgress, nextChildren, renderExpirationTime);
7868 } else {
7869 reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime);
7870 } // Memoize state using the values we just used to render.
7871 // TODO: Restructure so we never read values from the instance.
7872
7873
7874 workInProgress.memoizedState = instance.state; // The context might have changed so we need to recalculate it.
7875
7876 if (hasContext) {
7877 invalidateContextProvider(workInProgress, Component, true);
7878 }
7879
7880 return workInProgress.child;
7881}
7882
7883function pushHostRootContext(workInProgress) {
7884 var root = workInProgress.stateNode;
7885
7886 if (root.pendingContext) {
7887 pushTopLevelContextObject(workInProgress, root.pendingContext, root.pendingContext !== root.context);
7888 } else if (root.context) {
7889 // Should always be set
7890 pushTopLevelContextObject(workInProgress, root.context, false);
7891 }
7892
7893 pushHostContainer(workInProgress, root.containerInfo);
7894}
7895
7896function updateHostRoot(current, workInProgress, renderExpirationTime) {
7897 pushHostRootContext(workInProgress);
7898 var updateQueue = workInProgress.updateQueue;
7899
7900 if (!(current !== null && updateQueue !== null)) {
7901 {
7902 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." );
7903 }
7904 }
7905
7906 var nextProps = workInProgress.pendingProps;
7907 var prevState = workInProgress.memoizedState;
7908 var prevChildren = prevState !== null ? prevState.element : null;
7909 cloneUpdateQueue(current, workInProgress);
7910 processUpdateQueue(workInProgress, nextProps, null, renderExpirationTime);
7911 var nextState = workInProgress.memoizedState; // Caution: React DevTools currently depends on this property
7912 // being called "element".
7913
7914 var nextChildren = nextState.element;
7915
7916 if (nextChildren === prevChildren) {
7917 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderExpirationTime);
7918 }
7919
7920 var root = workInProgress.stateNode;
7921
7922 if (root.hydrate && enterHydrationState()) {
7923 // If we don't have any current children this might be the first pass.
7924 // We always try to hydrate. If this isn't a hydration pass there won't
7925 // be any children to hydrate which is effectively the same thing as
7926 // not hydrating.
7927 var child = mountChildFibers(workInProgress, null, nextChildren, renderExpirationTime);
7928 workInProgress.child = child;
7929 var node = child;
7930
7931 while (node) {
7932 // Mark each child as hydrating. This is a fast path to know whether this
7933 // tree is part of a hydrating tree. This is used to determine if a child
7934 // node has fully mounted yet, and for scheduling event replaying.
7935 // Conceptually this is similar to Placement in that a new subtree is
7936 // inserted into the React tree here. It just happens to not need DOM
7937 // mutations because it already exists.
7938 node.effectTag = node.effectTag & ~Placement | Hydrating;
7939 node = node.sibling;
7940 }
7941 } else {
7942 // Otherwise reset hydration state in case we aborted and resumed another
7943 // root.
7944 reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime);
7945 }
7946
7947 return workInProgress.child;
7948}
7949
7950function updateHostComponent(current, workInProgress, renderExpirationTime) {
7951 pushHostContext(workInProgress);
7952
7953 var type = workInProgress.type;
7954 var nextProps = workInProgress.pendingProps;
7955 var prevProps = current !== null ? current.memoizedProps : null;
7956 var nextChildren = nextProps.children;
7957 var isDirectTextChild = shouldSetTextContent(type, nextProps);
7958
7959 if (isDirectTextChild) {
7960 // We special case a direct text child of a host node. This is a common
7961 // case. We won't handle it as a reified child. We will instead handle
7962 // this in the host environment that also has access to this prop. That
7963 // avoids allocating another HostText fiber and traversing it.
7964 nextChildren = null;
7965 } else if (prevProps !== null && shouldSetTextContent(type, prevProps)) {
7966 // If we're switching from a direct text child to a normal child, or to
7967 // empty, we need to schedule the text content to be reset.
7968 workInProgress.effectTag |= ContentReset;
7969 }
7970
7971 markRef(current, workInProgress); // Check the host config to see if the children are offscreen/hidden.
7972
7973 if (workInProgress.mode & ConcurrentMode && renderExpirationTime !== Never && shouldDeprioritizeSubtree()) {
7974 {
7975 markSpawnedWork(Never);
7976 } // Schedule this fiber to re-render at offscreen priority. Then bailout.
7977
7978
7979 workInProgress.expirationTime = workInProgress.childExpirationTime = Never;
7980 return null;
7981 }
7982
7983 reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime);
7984 return workInProgress.child;
7985}
7986
7987function updateHostText(current, workInProgress) {
7988 // immediately after.
7989
7990
7991 return null;
7992}
7993
7994function mountLazyComponent(_current, workInProgress, elementType, updateExpirationTime, renderExpirationTime) {
7995 if (_current !== null) {
7996 // A lazy component only mounts if it suspended inside a non-
7997 // concurrent tree, in an inconsistent state. We want to treat it like
7998 // a new mount, even though an empty version of it already committed.
7999 // Disconnect the alternate pointers.
8000 _current.alternate = null;
8001 workInProgress.alternate = null; // Since this is conceptually a new fiber, schedule a Placement effect
8002
8003 workInProgress.effectTag |= Placement;
8004 }
8005
8006 var props = workInProgress.pendingProps; // We can't start a User Timing measurement with correct label yet.
8007 // Cancel and resume right after we know the tag.
8008
8009 cancelWorkTimer(workInProgress);
8010 var Component = readLazyComponentType(elementType); // Store the unwrapped component in the type.
8011
8012 workInProgress.type = Component;
8013 var resolvedTag = workInProgress.tag = resolveLazyComponentTag(Component);
8014 startWorkTimer(workInProgress);
8015 var resolvedProps = resolveDefaultProps(Component, props);
8016 var child;
8017
8018 switch (resolvedTag) {
8019 case FunctionComponent:
8020 {
8021 {
8022 validateFunctionComponentInDev(workInProgress, Component);
8023 workInProgress.type = Component = resolveFunctionForHotReloading(Component);
8024 }
8025
8026 child = updateFunctionComponent(null, workInProgress, Component, resolvedProps, renderExpirationTime);
8027 return child;
8028 }
8029
8030 case ClassComponent:
8031 {
8032 {
8033 workInProgress.type = Component = resolveClassForHotReloading(Component);
8034 }
8035
8036 child = updateClassComponent(null, workInProgress, Component, resolvedProps, renderExpirationTime);
8037 return child;
8038 }
8039
8040 case ForwardRef:
8041 {
8042 {
8043 workInProgress.type = Component = resolveForwardRefForHotReloading(Component);
8044 }
8045
8046 child = updateForwardRef(null, workInProgress, Component, resolvedProps, renderExpirationTime);
8047 return child;
8048 }
8049
8050 case MemoComponent:
8051 {
8052 {
8053 if (workInProgress.type !== workInProgress.elementType) {
8054 var outerPropTypes = Component.propTypes;
8055
8056 if (outerPropTypes) {
8057 checkPropTypes(outerPropTypes, resolvedProps, // Resolved for outer only
8058 'prop', getComponentName(Component), getCurrentFiberStackInDev);
8059 }
8060 }
8061 }
8062
8063 child = updateMemoComponent(null, workInProgress, Component, resolveDefaultProps(Component.type, resolvedProps), // The inner type can have defaults too
8064 updateExpirationTime, renderExpirationTime);
8065 return child;
8066 }
8067 }
8068
8069 var hint = '';
8070
8071 {
8072 if (Component !== null && typeof Component === 'object' && Component.$$typeof === REACT_LAZY_TYPE) {
8073 hint = ' Did you wrap a component in React.lazy() more than once?';
8074 }
8075 } // This message intentionally doesn't mention ForwardRef or MemoComponent
8076 // because the fact that it's a separate type of work is an
8077 // implementation detail.
8078
8079
8080 {
8081 {
8082 throw Error( "Element type is invalid. Received a promise that resolves to: " + Component + ". Lazy element type must resolve to a class or function." + hint );
8083 }
8084 }
8085}
8086
8087function mountIncompleteClassComponent(_current, workInProgress, Component, nextProps, renderExpirationTime) {
8088 if (_current !== null) {
8089 // An incomplete component only mounts if it suspended inside a non-
8090 // concurrent tree, in an inconsistent state. We want to treat it like
8091 // a new mount, even though an empty version of it already committed.
8092 // Disconnect the alternate pointers.
8093 _current.alternate = null;
8094 workInProgress.alternate = null; // Since this is conceptually a new fiber, schedule a Placement effect
8095
8096 workInProgress.effectTag |= Placement;
8097 } // Promote the fiber to a class and try rendering again.
8098
8099
8100 workInProgress.tag = ClassComponent; // The rest of this function is a fork of `updateClassComponent`
8101 // Push context providers early to prevent context stack mismatches.
8102 // During mounting we don't know the child context yet as the instance doesn't exist.
8103 // We will invalidate the child context in finishClassComponent() right after rendering.
8104
8105 var hasContext;
8106
8107 if (isContextProvider(Component)) {
8108 hasContext = true;
8109 pushContextProvider(workInProgress);
8110 } else {
8111 hasContext = false;
8112 }
8113
8114 prepareToReadContext(workInProgress, renderExpirationTime);
8115 constructClassInstance(workInProgress, Component, nextProps);
8116 mountClassInstance(workInProgress, Component, nextProps, renderExpirationTime);
8117 return finishClassComponent(null, workInProgress, Component, true, hasContext, renderExpirationTime);
8118}
8119
8120function mountIndeterminateComponent(_current, workInProgress, Component, renderExpirationTime) {
8121 if (_current !== null) {
8122 // An indeterminate component only mounts if it suspended inside a non-
8123 // concurrent tree, in an inconsistent state. We want to treat it like
8124 // a new mount, even though an empty version of it already committed.
8125 // Disconnect the alternate pointers.
8126 _current.alternate = null;
8127 workInProgress.alternate = null; // Since this is conceptually a new fiber, schedule a Placement effect
8128
8129 workInProgress.effectTag |= Placement;
8130 }
8131
8132 var props = workInProgress.pendingProps;
8133 var context;
8134
8135 {
8136 var unmaskedContext = getUnmaskedContext(workInProgress, Component, false);
8137 context = getMaskedContext(workInProgress, unmaskedContext);
8138 }
8139
8140 prepareToReadContext(workInProgress, renderExpirationTime);
8141 var value;
8142
8143 {
8144 if (Component.prototype && typeof Component.prototype.render === 'function') {
8145 var componentName = getComponentName(Component) || 'Unknown';
8146
8147 if (!didWarnAboutBadClass[componentName]) {
8148 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);
8149
8150 didWarnAboutBadClass[componentName] = true;
8151 }
8152 }
8153
8154 if (workInProgress.mode & StrictMode) {
8155 ReactStrictModeWarnings.recordLegacyContextWarning(workInProgress, null);
8156 }
8157
8158 setIsRendering(true);
8159 ReactCurrentOwner$1.current = workInProgress;
8160 value = renderWithHooks(null, workInProgress, Component, props, context, renderExpirationTime);
8161 setIsRendering(false);
8162 } // React DevTools reads this flag.
8163
8164
8165 workInProgress.effectTag |= PerformedWork;
8166
8167 if (typeof value === 'object' && value !== null && typeof value.render === 'function' && value.$$typeof === undefined) {
8168 {
8169 var _componentName = getComponentName(Component) || 'Unknown';
8170
8171 if (!didWarnAboutModulePatternComponent[_componentName]) {
8172 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);
8173
8174 didWarnAboutModulePatternComponent[_componentName] = true;
8175 }
8176 } // Proceed under the assumption that this is a class instance
8177
8178
8179 workInProgress.tag = ClassComponent; // Throw out any hooks that were used.
8180
8181 workInProgress.memoizedState = null;
8182 workInProgress.updateQueue = null; // Push context providers early to prevent context stack mismatches.
8183 // During mounting we don't know the child context yet as the instance doesn't exist.
8184 // We will invalidate the child context in finishClassComponent() right after rendering.
8185
8186 var hasContext = false;
8187
8188 if (isContextProvider(Component)) {
8189 hasContext = true;
8190 pushContextProvider(workInProgress);
8191 } else {
8192 hasContext = false;
8193 }
8194
8195 workInProgress.memoizedState = value.state !== null && value.state !== undefined ? value.state : null;
8196 initializeUpdateQueue(workInProgress);
8197 var getDerivedStateFromProps = Component.getDerivedStateFromProps;
8198
8199 if (typeof getDerivedStateFromProps === 'function') {
8200 applyDerivedStateFromProps(workInProgress, Component, getDerivedStateFromProps, props);
8201 }
8202
8203 adoptClassInstance(workInProgress, value);
8204 mountClassInstance(workInProgress, Component, props, renderExpirationTime);
8205 return finishClassComponent(null, workInProgress, Component, true, hasContext, renderExpirationTime);
8206 } else {
8207 // Proceed under the assumption that this is a function component
8208 workInProgress.tag = FunctionComponent;
8209
8210 {
8211
8212 if ( workInProgress.mode & StrictMode) {
8213 // Only double-render components with Hooks
8214 if (workInProgress.memoizedState !== null) {
8215 value = renderWithHooks(null, workInProgress, Component, props, context, renderExpirationTime);
8216 }
8217 }
8218 }
8219
8220 reconcileChildren(null, workInProgress, value, renderExpirationTime);
8221
8222 {
8223 validateFunctionComponentInDev(workInProgress, Component);
8224 }
8225
8226 return workInProgress.child;
8227 }
8228}
8229
8230function validateFunctionComponentInDev(workInProgress, Component) {
8231 {
8232 if (Component) {
8233 if (Component.childContextTypes) {
8234 error('%s(...): childContextTypes cannot be defined on a function component.', Component.displayName || Component.name || 'Component');
8235 }
8236 }
8237
8238 if (workInProgress.ref !== null) {
8239 var info = '';
8240 var ownerName = getCurrentFiberOwnerNameInDevOrNull();
8241
8242 if (ownerName) {
8243 info += '\n\nCheck the render method of `' + ownerName + '`.';
8244 }
8245
8246 var warningKey = ownerName || workInProgress._debugID || '';
8247 var debugSource = workInProgress._debugSource;
8248
8249 if (debugSource) {
8250 warningKey = debugSource.fileName + ':' + debugSource.lineNumber;
8251 }
8252
8253 if (!didWarnAboutFunctionRefs[warningKey]) {
8254 didWarnAboutFunctionRefs[warningKey] = true;
8255
8256 error('Function components cannot be given refs. ' + 'Attempts to access this ref will fail. ' + 'Did you mean to use React.forwardRef()?%s', info);
8257 }
8258 }
8259
8260 if (typeof Component.getDerivedStateFromProps === 'function') {
8261 var _componentName2 = getComponentName(Component) || 'Unknown';
8262
8263 if (!didWarnAboutGetDerivedStateOnFunctionComponent[_componentName2]) {
8264 error('%s: Function components do not support getDerivedStateFromProps.', _componentName2);
8265
8266 didWarnAboutGetDerivedStateOnFunctionComponent[_componentName2] = true;
8267 }
8268 }
8269
8270 if (typeof Component.contextType === 'object' && Component.contextType !== null) {
8271 var _componentName3 = getComponentName(Component) || 'Unknown';
8272
8273 if (!didWarnAboutContextTypeOnFunctionComponent[_componentName3]) {
8274 error('%s: Function components do not support contextType.', _componentName3);
8275
8276 didWarnAboutContextTypeOnFunctionComponent[_componentName3] = true;
8277 }
8278 }
8279 }
8280}
8281
8282var SUSPENDED_MARKER = {
8283 dehydrated: null,
8284 retryTime: NoWork
8285};
8286
8287function shouldRemainOnFallback(suspenseContext, current, workInProgress) {
8288 // If the context is telling us that we should show a fallback, and we're not
8289 // already showing content, then we should show the fallback instead.
8290 return hasSuspenseContext(suspenseContext, ForceSuspenseFallback) && (current === null || current.memoizedState !== null);
8291}
8292
8293function updateSuspenseComponent(current, workInProgress, renderExpirationTime) {
8294 var mode = workInProgress.mode;
8295 var nextProps = workInProgress.pendingProps; // This is used by DevTools to force a boundary to suspend.
8296
8297 {
8298 if (shouldSuspend(workInProgress)) {
8299 workInProgress.effectTag |= DidCapture;
8300 }
8301 }
8302
8303 var suspenseContext = suspenseStackCursor.current;
8304 var nextDidTimeout = false;
8305 var didSuspend = (workInProgress.effectTag & DidCapture) !== NoEffect;
8306
8307 if (didSuspend || shouldRemainOnFallback(suspenseContext, current)) {
8308 // Something in this boundary's subtree already suspended. Switch to
8309 // rendering the fallback children.
8310 nextDidTimeout = true;
8311 workInProgress.effectTag &= ~DidCapture;
8312 } else {
8313 // Attempting the main content
8314 if (current === null || current.memoizedState !== null) {
8315 // This is a new mount or this boundary is already showing a fallback state.
8316 // Mark this subtree context as having at least one invisible parent that could
8317 // handle the fallback state.
8318 // Boundaries without fallbacks or should be avoided are not considered since
8319 // they cannot handle preferred fallback states.
8320 if (nextProps.fallback !== undefined && nextProps.unstable_avoidThisFallback !== true) {
8321 suspenseContext = addSubtreeSuspenseContext(suspenseContext, InvisibleParentSuspenseContext);
8322 }
8323 }
8324 }
8325
8326 suspenseContext = setDefaultShallowSuspenseContext(suspenseContext);
8327 pushSuspenseContext(workInProgress, suspenseContext); // This next part is a bit confusing. If the children timeout, we switch to
8328 // showing the fallback children in place of the "primary" children.
8329 // However, we don't want to delete the primary children because then their
8330 // state will be lost (both the React state and the host state, e.g.
8331 // uncontrolled form inputs). Instead we keep them mounted and hide them.
8332 // Both the fallback children AND the primary children are rendered at the
8333 // same time. Once the primary children are un-suspended, we can delete
8334 // the fallback children — don't need to preserve their state.
8335 //
8336 // The two sets of children are siblings in the host environment, but
8337 // semantically, for purposes of reconciliation, they are two separate sets.
8338 // So we store them using two fragment fibers.
8339 //
8340 // However, we want to avoid allocating extra fibers for every placeholder.
8341 // They're only necessary when the children time out, because that's the
8342 // only time when both sets are mounted.
8343 //
8344 // So, the extra fragment fibers are only used if the children time out.
8345 // Otherwise, we render the primary children directly. This requires some
8346 // custom reconciliation logic to preserve the state of the primary
8347 // children. It's essentially a very basic form of re-parenting.
8348
8349 if (current === null) {
8350 // If we're currently hydrating, try to hydrate this boundary.
8351 // But only if this has a fallback.
8352 if (nextProps.fallback !== undefined) ; // This is the initial mount. This branch is pretty simple because there's
8353 // no previous state that needs to be preserved.
8354
8355
8356 if (nextDidTimeout) {
8357 // Mount separate fragments for primary and fallback children.
8358 var nextFallbackChildren = nextProps.fallback;
8359 var primaryChildFragment = createFiberFromFragment(null, mode, NoWork, null);
8360 primaryChildFragment.return = workInProgress;
8361
8362 if ((workInProgress.mode & BlockingMode) === NoMode) {
8363 // Outside of blocking mode, we commit the effects from the
8364 // partially completed, timed-out tree, too.
8365 var progressedState = workInProgress.memoizedState;
8366 var progressedPrimaryChild = progressedState !== null ? workInProgress.child.child : workInProgress.child;
8367 primaryChildFragment.child = progressedPrimaryChild;
8368 var progressedChild = progressedPrimaryChild;
8369
8370 while (progressedChild !== null) {
8371 progressedChild.return = primaryChildFragment;
8372 progressedChild = progressedChild.sibling;
8373 }
8374 }
8375
8376 var fallbackChildFragment = createFiberFromFragment(nextFallbackChildren, mode, renderExpirationTime, null);
8377 fallbackChildFragment.return = workInProgress;
8378 primaryChildFragment.sibling = fallbackChildFragment; // Skip the primary children, and continue working on the
8379 // fallback children.
8380
8381 workInProgress.memoizedState = SUSPENDED_MARKER;
8382 workInProgress.child = primaryChildFragment;
8383 return fallbackChildFragment;
8384 } else {
8385 // Mount the primary children without an intermediate fragment fiber.
8386 var nextPrimaryChildren = nextProps.children;
8387 workInProgress.memoizedState = null;
8388 return workInProgress.child = mountChildFibers(workInProgress, null, nextPrimaryChildren, renderExpirationTime);
8389 }
8390 } else {
8391 // This is an update. This branch is more complicated because we need to
8392 // ensure the state of the primary children is preserved.
8393 var prevState = current.memoizedState;
8394
8395 if (prevState !== null) {
8396 // wrapped in a fragment fiber.
8397
8398
8399 var currentPrimaryChildFragment = current.child;
8400 var currentFallbackChildFragment = currentPrimaryChildFragment.sibling;
8401
8402 if (nextDidTimeout) {
8403 // Still timed out. Reuse the current primary children by cloning
8404 // its fragment. We're going to skip over these entirely.
8405 var _nextFallbackChildren2 = nextProps.fallback;
8406
8407 var _primaryChildFragment2 = createWorkInProgress(currentPrimaryChildFragment, currentPrimaryChildFragment.pendingProps);
8408
8409 _primaryChildFragment2.return = workInProgress;
8410
8411 if ((workInProgress.mode & BlockingMode) === NoMode) {
8412 // Outside of blocking mode, we commit the effects from the
8413 // partially completed, timed-out tree, too.
8414 var _progressedState = workInProgress.memoizedState;
8415
8416 var _progressedPrimaryChild = _progressedState !== null ? workInProgress.child.child : workInProgress.child;
8417
8418 if (_progressedPrimaryChild !== currentPrimaryChildFragment.child) {
8419 _primaryChildFragment2.child = _progressedPrimaryChild;
8420 var _progressedChild2 = _progressedPrimaryChild;
8421
8422 while (_progressedChild2 !== null) {
8423 _progressedChild2.return = _primaryChildFragment2;
8424 _progressedChild2 = _progressedChild2.sibling;
8425 }
8426 }
8427 } // Because primaryChildFragment is a new fiber that we're inserting as the
8428 // parent of a new tree, we need to set its treeBaseDuration.
8429
8430
8431 if ( workInProgress.mode & ProfileMode) {
8432 // treeBaseDuration is the sum of all the child tree base durations.
8433 var _treeBaseDuration = 0;
8434 var _hiddenChild = _primaryChildFragment2.child;
8435
8436 while (_hiddenChild !== null) {
8437 _treeBaseDuration += _hiddenChild.treeBaseDuration;
8438 _hiddenChild = _hiddenChild.sibling;
8439 }
8440
8441 _primaryChildFragment2.treeBaseDuration = _treeBaseDuration;
8442 } // Clone the fallback child fragment, too. These we'll continue
8443 // working on.
8444
8445
8446 var _fallbackChildFragment2 = createWorkInProgress(currentFallbackChildFragment, _nextFallbackChildren2);
8447
8448 _fallbackChildFragment2.return = workInProgress;
8449 _primaryChildFragment2.sibling = _fallbackChildFragment2;
8450 _primaryChildFragment2.childExpirationTime = NoWork; // Skip the primary children, and continue working on the
8451 // fallback children.
8452
8453 workInProgress.memoizedState = SUSPENDED_MARKER;
8454 workInProgress.child = _primaryChildFragment2;
8455 return _fallbackChildFragment2;
8456 } else {
8457 // No longer suspended. Switch back to showing the primary children,
8458 // and remove the intermediate fragment fiber.
8459 var _nextPrimaryChildren = nextProps.children;
8460 var currentPrimaryChild = currentPrimaryChildFragment.child;
8461 var primaryChild = reconcileChildFibers(workInProgress, currentPrimaryChild, _nextPrimaryChildren, renderExpirationTime); // If this render doesn't suspend, we need to delete the fallback
8462 // children. Wait until the complete phase, after we've confirmed the
8463 // fallback is no longer needed.
8464 // TODO: Would it be better to store the fallback fragment on
8465 // the stateNode?
8466 // Continue rendering the children, like we normally do.
8467
8468 workInProgress.memoizedState = null;
8469 return workInProgress.child = primaryChild;
8470 }
8471 } else {
8472 // The current tree has not already timed out. That means the primary
8473 // children are not wrapped in a fragment fiber.
8474 var _currentPrimaryChild = current.child;
8475
8476 if (nextDidTimeout) {
8477 // Timed out. Wrap the children in a fragment fiber to keep them
8478 // separate from the fallback children.
8479 var _nextFallbackChildren3 = nextProps.fallback;
8480
8481 var _primaryChildFragment3 = createFiberFromFragment( // It shouldn't matter what the pending props are because we aren't
8482 // going to render this fragment.
8483 null, mode, NoWork, null);
8484
8485 _primaryChildFragment3.return = workInProgress;
8486 _primaryChildFragment3.child = _currentPrimaryChild;
8487
8488 if (_currentPrimaryChild !== null) {
8489 _currentPrimaryChild.return = _primaryChildFragment3;
8490 } // Even though we're creating a new fiber, there are no new children,
8491 // because we're reusing an already mounted tree. So we don't need to
8492 // schedule a placement.
8493 // primaryChildFragment.effectTag |= Placement;
8494
8495
8496 if ((workInProgress.mode & BlockingMode) === NoMode) {
8497 // Outside of blocking mode, we commit the effects from the
8498 // partially completed, timed-out tree, too.
8499 var _progressedState2 = workInProgress.memoizedState;
8500
8501 var _progressedPrimaryChild2 = _progressedState2 !== null ? workInProgress.child.child : workInProgress.child;
8502
8503 _primaryChildFragment3.child = _progressedPrimaryChild2;
8504 var _progressedChild3 = _progressedPrimaryChild2;
8505
8506 while (_progressedChild3 !== null) {
8507 _progressedChild3.return = _primaryChildFragment3;
8508 _progressedChild3 = _progressedChild3.sibling;
8509 }
8510 } // Because primaryChildFragment is a new fiber that we're inserting as the
8511 // parent of a new tree, we need to set its treeBaseDuration.
8512
8513
8514 if ( workInProgress.mode & ProfileMode) {
8515 // treeBaseDuration is the sum of all the child tree base durations.
8516 var _treeBaseDuration2 = 0;
8517 var _hiddenChild2 = _primaryChildFragment3.child;
8518
8519 while (_hiddenChild2 !== null) {
8520 _treeBaseDuration2 += _hiddenChild2.treeBaseDuration;
8521 _hiddenChild2 = _hiddenChild2.sibling;
8522 }
8523
8524 _primaryChildFragment3.treeBaseDuration = _treeBaseDuration2;
8525 } // Create a fragment from the fallback children, too.
8526
8527
8528 var _fallbackChildFragment3 = createFiberFromFragment(_nextFallbackChildren3, mode, renderExpirationTime, null);
8529
8530 _fallbackChildFragment3.return = workInProgress;
8531 _primaryChildFragment3.sibling = _fallbackChildFragment3;
8532 _fallbackChildFragment3.effectTag |= Placement;
8533 _primaryChildFragment3.childExpirationTime = NoWork; // Skip the primary children, and continue working on the
8534 // fallback children.
8535
8536 workInProgress.memoizedState = SUSPENDED_MARKER;
8537 workInProgress.child = _primaryChildFragment3;
8538 return _fallbackChildFragment3;
8539 } else {
8540 // Still haven't timed out. Continue rendering the children, like we
8541 // normally do.
8542 workInProgress.memoizedState = null;
8543 var _nextPrimaryChildren2 = nextProps.children;
8544 return workInProgress.child = reconcileChildFibers(workInProgress, _currentPrimaryChild, _nextPrimaryChildren2, renderExpirationTime);
8545 }
8546 }
8547 }
8548}
8549
8550function scheduleWorkOnFiber(fiber, renderExpirationTime) {
8551 if (fiber.expirationTime < renderExpirationTime) {
8552 fiber.expirationTime = renderExpirationTime;
8553 }
8554
8555 var alternate = fiber.alternate;
8556
8557 if (alternate !== null && alternate.expirationTime < renderExpirationTime) {
8558 alternate.expirationTime = renderExpirationTime;
8559 }
8560
8561 scheduleWorkOnParentPath(fiber.return, renderExpirationTime);
8562}
8563
8564function propagateSuspenseContextChange(workInProgress, firstChild, renderExpirationTime) {
8565 // Mark any Suspense boundaries with fallbacks as having work to do.
8566 // If they were previously forced into fallbacks, they may now be able
8567 // to unblock.
8568 var node = firstChild;
8569
8570 while (node !== null) {
8571 if (node.tag === SuspenseComponent) {
8572 var state = node.memoizedState;
8573
8574 if (state !== null) {
8575 scheduleWorkOnFiber(node, renderExpirationTime);
8576 }
8577 } else if (node.tag === SuspenseListComponent) {
8578 // If the tail is hidden there might not be an Suspense boundaries
8579 // to schedule work on. In this case we have to schedule it on the
8580 // list itself.
8581 // We don't have to traverse to the children of the list since
8582 // the list will propagate the change when it rerenders.
8583 scheduleWorkOnFiber(node, renderExpirationTime);
8584 } else if (node.child !== null) {
8585 node.child.return = node;
8586 node = node.child;
8587 continue;
8588 }
8589
8590 if (node === workInProgress) {
8591 return;
8592 }
8593
8594 while (node.sibling === null) {
8595 if (node.return === null || node.return === workInProgress) {
8596 return;
8597 }
8598
8599 node = node.return;
8600 }
8601
8602 node.sibling.return = node.return;
8603 node = node.sibling;
8604 }
8605}
8606
8607function findLastContentRow(firstChild) {
8608 // This is going to find the last row among these children that is already
8609 // showing content on the screen, as opposed to being in fallback state or
8610 // new. If a row has multiple Suspense boundaries, any of them being in the
8611 // fallback state, counts as the whole row being in a fallback state.
8612 // Note that the "rows" will be workInProgress, but any nested children
8613 // will still be current since we haven't rendered them yet. The mounted
8614 // order may not be the same as the new order. We use the new order.
8615 var row = firstChild;
8616 var lastContentRow = null;
8617
8618 while (row !== null) {
8619 var currentRow = row.alternate; // New rows can't be content rows.
8620
8621 if (currentRow !== null && findFirstSuspended(currentRow) === null) {
8622 lastContentRow = row;
8623 }
8624
8625 row = row.sibling;
8626 }
8627
8628 return lastContentRow;
8629}
8630
8631function validateRevealOrder(revealOrder) {
8632 {
8633 if (revealOrder !== undefined && revealOrder !== 'forwards' && revealOrder !== 'backwards' && revealOrder !== 'together' && !didWarnAboutRevealOrder[revealOrder]) {
8634 didWarnAboutRevealOrder[revealOrder] = true;
8635
8636 if (typeof revealOrder === 'string') {
8637 switch (revealOrder.toLowerCase()) {
8638 case 'together':
8639 case 'forwards':
8640 case 'backwards':
8641 {
8642 error('"%s" is not a valid value for revealOrder on <SuspenseList />. ' + 'Use lowercase "%s" instead.', revealOrder, revealOrder.toLowerCase());
8643
8644 break;
8645 }
8646
8647 case 'forward':
8648 case 'backward':
8649 {
8650 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());
8651
8652 break;
8653 }
8654
8655 default:
8656 error('"%s" is not a supported revealOrder on <SuspenseList />. ' + 'Did you mean "together", "forwards" or "backwards"?', revealOrder);
8657
8658 break;
8659 }
8660 } else {
8661 error('%s is not a supported value for revealOrder on <SuspenseList />. ' + 'Did you mean "together", "forwards" or "backwards"?', revealOrder);
8662 }
8663 }
8664 }
8665}
8666
8667function validateTailOptions(tailMode, revealOrder) {
8668 {
8669 if (tailMode !== undefined && !didWarnAboutTailOptions[tailMode]) {
8670 if (tailMode !== 'collapsed' && tailMode !== 'hidden') {
8671 didWarnAboutTailOptions[tailMode] = true;
8672
8673 error('"%s" is not a supported value for tail on <SuspenseList />. ' + 'Did you mean "collapsed" or "hidden"?', tailMode);
8674 } else if (revealOrder !== 'forwards' && revealOrder !== 'backwards') {
8675 didWarnAboutTailOptions[tailMode] = true;
8676
8677 error('<SuspenseList tail="%s" /> is only valid if revealOrder is ' + '"forwards" or "backwards". ' + 'Did you mean to specify revealOrder="forwards"?', tailMode);
8678 }
8679 }
8680 }
8681}
8682
8683function validateSuspenseListNestedChild(childSlot, index) {
8684 {
8685 var isArray = Array.isArray(childSlot);
8686 var isIterable = !isArray && typeof getIteratorFn(childSlot) === 'function';
8687
8688 if (isArray || isIterable) {
8689 var type = isArray ? 'array' : 'iterable';
8690
8691 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);
8692
8693 return false;
8694 }
8695 }
8696
8697 return true;
8698}
8699
8700function validateSuspenseListChildren(children, revealOrder) {
8701 {
8702 if ((revealOrder === 'forwards' || revealOrder === 'backwards') && children !== undefined && children !== null && children !== false) {
8703 if (Array.isArray(children)) {
8704 for (var i = 0; i < children.length; i++) {
8705 if (!validateSuspenseListNestedChild(children[i], i)) {
8706 return;
8707 }
8708 }
8709 } else {
8710 var iteratorFn = getIteratorFn(children);
8711
8712 if (typeof iteratorFn === 'function') {
8713 var childrenIterator = iteratorFn.call(children);
8714
8715 if (childrenIterator) {
8716 var step = childrenIterator.next();
8717 var _i = 0;
8718
8719 for (; !step.done; step = childrenIterator.next()) {
8720 if (!validateSuspenseListNestedChild(step.value, _i)) {
8721 return;
8722 }
8723
8724 _i++;
8725 }
8726 }
8727 } else {
8728 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);
8729 }
8730 }
8731 }
8732 }
8733}
8734
8735function initSuspenseListRenderState(workInProgress, isBackwards, tail, lastContentRow, tailMode, lastEffectBeforeRendering) {
8736 var renderState = workInProgress.memoizedState;
8737
8738 if (renderState === null) {
8739 workInProgress.memoizedState = {
8740 isBackwards: isBackwards,
8741 rendering: null,
8742 renderingStartTime: 0,
8743 last: lastContentRow,
8744 tail: tail,
8745 tailExpiration: 0,
8746 tailMode: tailMode,
8747 lastEffect: lastEffectBeforeRendering
8748 };
8749 } else {
8750 // We can reuse the existing object from previous renders.
8751 renderState.isBackwards = isBackwards;
8752 renderState.rendering = null;
8753 renderState.renderingStartTime = 0;
8754 renderState.last = lastContentRow;
8755 renderState.tail = tail;
8756 renderState.tailExpiration = 0;
8757 renderState.tailMode = tailMode;
8758 renderState.lastEffect = lastEffectBeforeRendering;
8759 }
8760} // This can end up rendering this component multiple passes.
8761// The first pass splits the children fibers into two sets. A head and tail.
8762// We first render the head. If anything is in fallback state, we do another
8763// pass through beginWork to rerender all children (including the tail) with
8764// the force suspend context. If the first render didn't have anything in
8765// in fallback state. Then we render each row in the tail one-by-one.
8766// That happens in the completeWork phase without going back to beginWork.
8767
8768
8769function updateSuspenseListComponent(current, workInProgress, renderExpirationTime) {
8770 var nextProps = workInProgress.pendingProps;
8771 var revealOrder = nextProps.revealOrder;
8772 var tailMode = nextProps.tail;
8773 var newChildren = nextProps.children;
8774 validateRevealOrder(revealOrder);
8775 validateTailOptions(tailMode, revealOrder);
8776 validateSuspenseListChildren(newChildren, revealOrder);
8777 reconcileChildren(current, workInProgress, newChildren, renderExpirationTime);
8778 var suspenseContext = suspenseStackCursor.current;
8779 var shouldForceFallback = hasSuspenseContext(suspenseContext, ForceSuspenseFallback);
8780
8781 if (shouldForceFallback) {
8782 suspenseContext = setShallowSuspenseContext(suspenseContext, ForceSuspenseFallback);
8783 workInProgress.effectTag |= DidCapture;
8784 } else {
8785 var didSuspendBefore = current !== null && (current.effectTag & DidCapture) !== NoEffect;
8786
8787 if (didSuspendBefore) {
8788 // If we previously forced a fallback, we need to schedule work
8789 // on any nested boundaries to let them know to try to render
8790 // again. This is the same as context updating.
8791 propagateSuspenseContextChange(workInProgress, workInProgress.child, renderExpirationTime);
8792 }
8793
8794 suspenseContext = setDefaultShallowSuspenseContext(suspenseContext);
8795 }
8796
8797 pushSuspenseContext(workInProgress, suspenseContext);
8798
8799 if ((workInProgress.mode & BlockingMode) === NoMode) {
8800 // Outside of blocking mode, SuspenseList doesn't work so we just
8801 // use make it a noop by treating it as the default revealOrder.
8802 workInProgress.memoizedState = null;
8803 } else {
8804 switch (revealOrder) {
8805 case 'forwards':
8806 {
8807 var lastContentRow = findLastContentRow(workInProgress.child);
8808 var tail;
8809
8810 if (lastContentRow === null) {
8811 // The whole list is part of the tail.
8812 // TODO: We could fast path by just rendering the tail now.
8813 tail = workInProgress.child;
8814 workInProgress.child = null;
8815 } else {
8816 // Disconnect the tail rows after the content row.
8817 // We're going to render them separately later.
8818 tail = lastContentRow.sibling;
8819 lastContentRow.sibling = null;
8820 }
8821
8822 initSuspenseListRenderState(workInProgress, false, // isBackwards
8823 tail, lastContentRow, tailMode, workInProgress.lastEffect);
8824 break;
8825 }
8826
8827 case 'backwards':
8828 {
8829 // We're going to find the first row that has existing content.
8830 // At the same time we're going to reverse the list of everything
8831 // we pass in the meantime. That's going to be our tail in reverse
8832 // order.
8833 var _tail = null;
8834 var row = workInProgress.child;
8835 workInProgress.child = null;
8836
8837 while (row !== null) {
8838 var currentRow = row.alternate; // New rows can't be content rows.
8839
8840 if (currentRow !== null && findFirstSuspended(currentRow) === null) {
8841 // This is the beginning of the main content.
8842 workInProgress.child = row;
8843 break;
8844 }
8845
8846 var nextRow = row.sibling;
8847 row.sibling = _tail;
8848 _tail = row;
8849 row = nextRow;
8850 } // TODO: If workInProgress.child is null, we can continue on the tail immediately.
8851
8852
8853 initSuspenseListRenderState(workInProgress, true, // isBackwards
8854 _tail, null, // last
8855 tailMode, workInProgress.lastEffect);
8856 break;
8857 }
8858
8859 case 'together':
8860 {
8861 initSuspenseListRenderState(workInProgress, false, // isBackwards
8862 null, // tail
8863 null, // last
8864 undefined, workInProgress.lastEffect);
8865 break;
8866 }
8867
8868 default:
8869 {
8870 // The default reveal order is the same as not having
8871 // a boundary.
8872 workInProgress.memoizedState = null;
8873 }
8874 }
8875 }
8876
8877 return workInProgress.child;
8878}
8879
8880function updatePortalComponent(current, workInProgress, renderExpirationTime) {
8881 pushHostContainer(workInProgress, workInProgress.stateNode.containerInfo);
8882 var nextChildren = workInProgress.pendingProps;
8883
8884 if (current === null) {
8885 // Portals are special because we don't append the children during mount
8886 // but at commit. Therefore we need to track insertions which the normal
8887 // flow doesn't do during mount. This doesn't happen at the root because
8888 // the root always starts with a "current" with a null child.
8889 // TODO: Consider unifying this with how the root works.
8890 workInProgress.child = reconcileChildFibers(workInProgress, null, nextChildren, renderExpirationTime);
8891 } else {
8892 reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime);
8893 }
8894
8895 return workInProgress.child;
8896}
8897
8898function updateContextProvider(current, workInProgress, renderExpirationTime) {
8899 var providerType = workInProgress.type;
8900 var context = providerType._context;
8901 var newProps = workInProgress.pendingProps;
8902 var oldProps = workInProgress.memoizedProps;
8903 var newValue = newProps.value;
8904
8905 {
8906 var providerPropTypes = workInProgress.type.propTypes;
8907
8908 if (providerPropTypes) {
8909 checkPropTypes(providerPropTypes, newProps, 'prop', 'Context.Provider', getCurrentFiberStackInDev);
8910 }
8911 }
8912
8913 pushProvider(workInProgress, newValue);
8914
8915 if (oldProps !== null) {
8916 var oldValue = oldProps.value;
8917 var changedBits = calculateChangedBits(context, newValue, oldValue);
8918
8919 if (changedBits === 0) {
8920 // No change. Bailout early if children are the same.
8921 if (oldProps.children === newProps.children && !hasContextChanged()) {
8922 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderExpirationTime);
8923 }
8924 } else {
8925 // The context value changed. Search for matching consumers and schedule
8926 // them to update.
8927 propagateContextChange(workInProgress, context, changedBits, renderExpirationTime);
8928 }
8929 }
8930
8931 var newChildren = newProps.children;
8932 reconcileChildren(current, workInProgress, newChildren, renderExpirationTime);
8933 return workInProgress.child;
8934}
8935
8936var hasWarnedAboutUsingContextAsConsumer = false;
8937
8938function updateContextConsumer(current, workInProgress, renderExpirationTime) {
8939 var context = workInProgress.type; // The logic below for Context differs depending on PROD or DEV mode. In
8940 // DEV mode, we create a separate object for Context.Consumer that acts
8941 // like a proxy to Context. This proxy object adds unnecessary code in PROD
8942 // so we use the old behaviour (Context.Consumer references Context) to
8943 // reduce size and overhead. The separate object references context via
8944 // a property called "_context", which also gives us the ability to check
8945 // in DEV mode if this property exists or not and warn if it does not.
8946
8947 {
8948 if (context._context === undefined) {
8949 // This may be because it's a Context (rather than a Consumer).
8950 // Or it may be because it's older React where they're the same thing.
8951 // We only want to warn if we're sure it's a new React.
8952 if (context !== context.Consumer) {
8953 if (!hasWarnedAboutUsingContextAsConsumer) {
8954 hasWarnedAboutUsingContextAsConsumer = true;
8955
8956 error('Rendering <Context> directly is not supported and will be removed in ' + 'a future major release. Did you mean to render <Context.Consumer> instead?');
8957 }
8958 }
8959 } else {
8960 context = context._context;
8961 }
8962 }
8963
8964 var newProps = workInProgress.pendingProps;
8965 var render = newProps.children;
8966
8967 {
8968 if (typeof render !== 'function') {
8969 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.');
8970 }
8971 }
8972
8973 prepareToReadContext(workInProgress, renderExpirationTime);
8974 var newValue = readContext(context, newProps.unstable_observedBits);
8975 var newChildren;
8976
8977 {
8978 ReactCurrentOwner$1.current = workInProgress;
8979 setIsRendering(true);
8980 newChildren = render(newValue);
8981 setIsRendering(false);
8982 } // React DevTools reads this flag.
8983
8984
8985 workInProgress.effectTag |= PerformedWork;
8986 reconcileChildren(current, workInProgress, newChildren, renderExpirationTime);
8987 return workInProgress.child;
8988}
8989
8990function markWorkInProgressReceivedUpdate() {
8991 didReceiveUpdate = true;
8992}
8993
8994function bailoutOnAlreadyFinishedWork(current, workInProgress, renderExpirationTime) {
8995 cancelWorkTimer(workInProgress);
8996
8997 if (current !== null) {
8998 // Reuse previous dependencies
8999 workInProgress.dependencies = current.dependencies;
9000 }
9001
9002 {
9003 // Don't update "base" render times for bailouts.
9004 stopProfilerTimerIfRunning();
9005 }
9006
9007 var updateExpirationTime = workInProgress.expirationTime;
9008
9009 if (updateExpirationTime !== NoWork) {
9010 markUnprocessedUpdateTime(updateExpirationTime);
9011 } // Check if the children have any pending work.
9012
9013
9014 var childExpirationTime = workInProgress.childExpirationTime;
9015
9016 if (childExpirationTime < renderExpirationTime) {
9017 // The children don't have any work either. We can skip them.
9018 // TODO: Once we add back resuming, we should check if the children are
9019 // a work-in-progress set. If so, we need to transfer their effects.
9020 return null;
9021 } else {
9022 // This fiber doesn't have work, but its subtree does. Clone the child
9023 // fibers and continue.
9024 cloneChildFibers(current, workInProgress);
9025 return workInProgress.child;
9026 }
9027}
9028
9029function remountFiber(current, oldWorkInProgress, newWorkInProgress) {
9030 {
9031 var returnFiber = oldWorkInProgress.return;
9032
9033 if (returnFiber === null) {
9034 throw new Error('Cannot swap the root fiber.');
9035 } // Disconnect from the old current.
9036 // It will get deleted.
9037
9038
9039 current.alternate = null;
9040 oldWorkInProgress.alternate = null; // Connect to the new tree.
9041
9042 newWorkInProgress.index = oldWorkInProgress.index;
9043 newWorkInProgress.sibling = oldWorkInProgress.sibling;
9044 newWorkInProgress.return = oldWorkInProgress.return;
9045 newWorkInProgress.ref = oldWorkInProgress.ref; // Replace the child/sibling pointers above it.
9046
9047 if (oldWorkInProgress === returnFiber.child) {
9048 returnFiber.child = newWorkInProgress;
9049 } else {
9050 var prevSibling = returnFiber.child;
9051
9052 if (prevSibling === null) {
9053 throw new Error('Expected parent to have a child.');
9054 }
9055
9056 while (prevSibling.sibling !== oldWorkInProgress) {
9057 prevSibling = prevSibling.sibling;
9058
9059 if (prevSibling === null) {
9060 throw new Error('Expected to find the previous sibling.');
9061 }
9062 }
9063
9064 prevSibling.sibling = newWorkInProgress;
9065 } // Delete the old fiber and place the new one.
9066 // Since the old fiber is disconnected, we have to schedule it manually.
9067
9068
9069 var last = returnFiber.lastEffect;
9070
9071 if (last !== null) {
9072 last.nextEffect = current;
9073 returnFiber.lastEffect = current;
9074 } else {
9075 returnFiber.firstEffect = returnFiber.lastEffect = current;
9076 }
9077
9078 current.nextEffect = null;
9079 current.effectTag = Deletion;
9080 newWorkInProgress.effectTag |= Placement; // Restart work from the new fiber.
9081
9082 return newWorkInProgress;
9083 }
9084}
9085
9086function beginWork(current, workInProgress, renderExpirationTime) {
9087 var updateExpirationTime = workInProgress.expirationTime;
9088
9089 {
9090 if (workInProgress._debugNeedsRemount && current !== null) {
9091 // This will restart the begin phase with a new fiber.
9092 return remountFiber(current, workInProgress, createFiberFromTypeAndProps(workInProgress.type, workInProgress.key, workInProgress.pendingProps, workInProgress._debugOwner || null, workInProgress.mode, workInProgress.expirationTime));
9093 }
9094 }
9095
9096 if (current !== null) {
9097 var oldProps = current.memoizedProps;
9098 var newProps = workInProgress.pendingProps;
9099
9100 if (oldProps !== newProps || hasContextChanged() || ( // Force a re-render if the implementation changed due to hot reload:
9101 workInProgress.type !== current.type )) {
9102 // If props or context changed, mark the fiber as having performed work.
9103 // This may be unset if the props are determined to be equal later (memo).
9104 didReceiveUpdate = true;
9105 } else if (updateExpirationTime < renderExpirationTime) {
9106 didReceiveUpdate = false; // This fiber does not have any pending work. Bailout without entering
9107 // the begin phase. There's still some bookkeeping we that needs to be done
9108 // in this optimized path, mostly pushing stuff onto the stack.
9109
9110 switch (workInProgress.tag) {
9111 case HostRoot:
9112 pushHostRootContext(workInProgress);
9113 break;
9114
9115 case HostComponent:
9116 pushHostContext(workInProgress);
9117
9118 if (workInProgress.mode & ConcurrentMode && renderExpirationTime !== Never && shouldDeprioritizeSubtree(workInProgress.type)) {
9119 {
9120 markSpawnedWork(Never);
9121 } // Schedule this fiber to re-render at offscreen priority. Then bailout.
9122
9123
9124 workInProgress.expirationTime = workInProgress.childExpirationTime = Never;
9125 return null;
9126 }
9127
9128 break;
9129
9130 case ClassComponent:
9131 {
9132 var Component = workInProgress.type;
9133
9134 if (isContextProvider(Component)) {
9135 pushContextProvider(workInProgress);
9136 }
9137
9138 break;
9139 }
9140
9141 case HostPortal:
9142 pushHostContainer(workInProgress, workInProgress.stateNode.containerInfo);
9143 break;
9144
9145 case ContextProvider:
9146 {
9147 var newValue = workInProgress.memoizedProps.value;
9148 pushProvider(workInProgress, newValue);
9149 break;
9150 }
9151
9152 case Profiler:
9153 {
9154 // Profiler should only call onRender when one of its descendants actually rendered.
9155 var hasChildWork = workInProgress.childExpirationTime >= renderExpirationTime;
9156
9157 if (hasChildWork) {
9158 workInProgress.effectTag |= Update;
9159 }
9160 }
9161
9162 break;
9163
9164 case SuspenseComponent:
9165 {
9166 var state = workInProgress.memoizedState;
9167
9168 if (state !== null) {
9169 // whether to retry the primary children, or to skip over it and
9170 // go straight to the fallback. Check the priority of the primary
9171 // child fragment.
9172
9173
9174 var primaryChildFragment = workInProgress.child;
9175 var primaryChildExpirationTime = primaryChildFragment.childExpirationTime;
9176
9177 if (primaryChildExpirationTime !== NoWork && primaryChildExpirationTime >= renderExpirationTime) {
9178 // The primary children have pending work. Use the normal path
9179 // to attempt to render the primary children again.
9180 return updateSuspenseComponent(current, workInProgress, renderExpirationTime);
9181 } else {
9182 pushSuspenseContext(workInProgress, setDefaultShallowSuspenseContext(suspenseStackCursor.current)); // The primary children do not have pending work with sufficient
9183 // priority. Bailout.
9184
9185 var child = bailoutOnAlreadyFinishedWork(current, workInProgress, renderExpirationTime);
9186
9187 if (child !== null) {
9188 // The fallback children have pending work. Skip over the
9189 // primary children and work on the fallback.
9190 return child.sibling;
9191 } else {
9192 return null;
9193 }
9194 }
9195 } else {
9196 pushSuspenseContext(workInProgress, setDefaultShallowSuspenseContext(suspenseStackCursor.current));
9197 }
9198
9199 break;
9200 }
9201
9202 case SuspenseListComponent:
9203 {
9204 var didSuspendBefore = (current.effectTag & DidCapture) !== NoEffect;
9205
9206 var _hasChildWork = workInProgress.childExpirationTime >= renderExpirationTime;
9207
9208 if (didSuspendBefore) {
9209 if (_hasChildWork) {
9210 // If something was in fallback state last time, and we have all the
9211 // same children then we're still in progressive loading state.
9212 // Something might get unblocked by state updates or retries in the
9213 // tree which will affect the tail. So we need to use the normal
9214 // path to compute the correct tail.
9215 return updateSuspenseListComponent(current, workInProgress, renderExpirationTime);
9216 } // If none of the children had any work, that means that none of
9217 // them got retried so they'll still be blocked in the same way
9218 // as before. We can fast bail out.
9219
9220
9221 workInProgress.effectTag |= DidCapture;
9222 } // If nothing suspended before and we're rendering the same children,
9223 // then the tail doesn't matter. Anything new that suspends will work
9224 // in the "together" mode, so we can continue from the state we had.
9225
9226
9227 var renderState = workInProgress.memoizedState;
9228
9229 if (renderState !== null) {
9230 // Reset to the "together" mode in case we've started a different
9231 // update in the past but didn't complete it.
9232 renderState.rendering = null;
9233 renderState.tail = null;
9234 }
9235
9236 pushSuspenseContext(workInProgress, suspenseStackCursor.current);
9237
9238 if (_hasChildWork) {
9239 break;
9240 } else {
9241 // If none of the children had any work, that means that none of
9242 // them got retried so they'll still be blocked in the same way
9243 // as before. We can fast bail out.
9244 return null;
9245 }
9246 }
9247 }
9248
9249 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderExpirationTime);
9250 } else {
9251 // An update was scheduled on this fiber, but there are no new props
9252 // nor legacy context. Set this to false. If an update queue or context
9253 // consumer produces a changed value, it will set this to true. Otherwise,
9254 // the component will assume the children have not changed and bail out.
9255 didReceiveUpdate = false;
9256 }
9257 } else {
9258 didReceiveUpdate = false;
9259 } // Before entering the begin phase, clear pending update priority.
9260 // TODO: This assumes that we're about to evaluate the component and process
9261 // the update queue. However, there's an exception: SimpleMemoComponent
9262 // sometimes bails out later in the begin phase. This indicates that we should
9263 // move this assignment out of the common path and into each branch.
9264
9265
9266 workInProgress.expirationTime = NoWork;
9267
9268 switch (workInProgress.tag) {
9269 case IndeterminateComponent:
9270 {
9271 return mountIndeterminateComponent(current, workInProgress, workInProgress.type, renderExpirationTime);
9272 }
9273
9274 case LazyComponent:
9275 {
9276 var elementType = workInProgress.elementType;
9277 return mountLazyComponent(current, workInProgress, elementType, updateExpirationTime, renderExpirationTime);
9278 }
9279
9280 case FunctionComponent:
9281 {
9282 var _Component = workInProgress.type;
9283 var unresolvedProps = workInProgress.pendingProps;
9284 var resolvedProps = workInProgress.elementType === _Component ? unresolvedProps : resolveDefaultProps(_Component, unresolvedProps);
9285 return updateFunctionComponent(current, workInProgress, _Component, resolvedProps, renderExpirationTime);
9286 }
9287
9288 case ClassComponent:
9289 {
9290 var _Component2 = workInProgress.type;
9291 var _unresolvedProps = workInProgress.pendingProps;
9292
9293 var _resolvedProps = workInProgress.elementType === _Component2 ? _unresolvedProps : resolveDefaultProps(_Component2, _unresolvedProps);
9294
9295 return updateClassComponent(current, workInProgress, _Component2, _resolvedProps, renderExpirationTime);
9296 }
9297
9298 case HostRoot:
9299 return updateHostRoot(current, workInProgress, renderExpirationTime);
9300
9301 case HostComponent:
9302 return updateHostComponent(current, workInProgress, renderExpirationTime);
9303
9304 case HostText:
9305 return updateHostText();
9306
9307 case SuspenseComponent:
9308 return updateSuspenseComponent(current, workInProgress, renderExpirationTime);
9309
9310 case HostPortal:
9311 return updatePortalComponent(current, workInProgress, renderExpirationTime);
9312
9313 case ForwardRef:
9314 {
9315 var type = workInProgress.type;
9316 var _unresolvedProps2 = workInProgress.pendingProps;
9317
9318 var _resolvedProps2 = workInProgress.elementType === type ? _unresolvedProps2 : resolveDefaultProps(type, _unresolvedProps2);
9319
9320 return updateForwardRef(current, workInProgress, type, _resolvedProps2, renderExpirationTime);
9321 }
9322
9323 case Fragment:
9324 return updateFragment(current, workInProgress, renderExpirationTime);
9325
9326 case Mode:
9327 return updateMode(current, workInProgress, renderExpirationTime);
9328
9329 case Profiler:
9330 return updateProfiler(current, workInProgress, renderExpirationTime);
9331
9332 case ContextProvider:
9333 return updateContextProvider(current, workInProgress, renderExpirationTime);
9334
9335 case ContextConsumer:
9336 return updateContextConsumer(current, workInProgress, renderExpirationTime);
9337
9338 case MemoComponent:
9339 {
9340 var _type2 = workInProgress.type;
9341 var _unresolvedProps3 = workInProgress.pendingProps; // Resolve outer props first, then resolve inner props.
9342
9343 var _resolvedProps3 = resolveDefaultProps(_type2, _unresolvedProps3);
9344
9345 {
9346 if (workInProgress.type !== workInProgress.elementType) {
9347 var outerPropTypes = _type2.propTypes;
9348
9349 if (outerPropTypes) {
9350 checkPropTypes(outerPropTypes, _resolvedProps3, // Resolved for outer only
9351 'prop', getComponentName(_type2), getCurrentFiberStackInDev);
9352 }
9353 }
9354 }
9355
9356 _resolvedProps3 = resolveDefaultProps(_type2.type, _resolvedProps3);
9357 return updateMemoComponent(current, workInProgress, _type2, _resolvedProps3, updateExpirationTime, renderExpirationTime);
9358 }
9359
9360 case SimpleMemoComponent:
9361 {
9362 return updateSimpleMemoComponent(current, workInProgress, workInProgress.type, workInProgress.pendingProps, updateExpirationTime, renderExpirationTime);
9363 }
9364
9365 case IncompleteClassComponent:
9366 {
9367 var _Component3 = workInProgress.type;
9368 var _unresolvedProps4 = workInProgress.pendingProps;
9369
9370 var _resolvedProps4 = workInProgress.elementType === _Component3 ? _unresolvedProps4 : resolveDefaultProps(_Component3, _unresolvedProps4);
9371
9372 return mountIncompleteClassComponent(current, workInProgress, _Component3, _resolvedProps4, renderExpirationTime);
9373 }
9374
9375 case SuspenseListComponent:
9376 {
9377 return updateSuspenseListComponent(current, workInProgress, renderExpirationTime);
9378 }
9379 }
9380
9381 {
9382 {
9383 throw Error( "Unknown unit of work tag (" + workInProgress.tag + "). This error is likely caused by a bug in React. Please file an issue." );
9384 }
9385 }
9386}
9387
9388function markUpdate(workInProgress) {
9389 // Tag the fiber with an update effect. This turns a Placement into
9390 // a PlacementAndUpdate.
9391 workInProgress.effectTag |= Update;
9392}
9393
9394function markRef$1(workInProgress) {
9395 workInProgress.effectTag |= Ref;
9396}
9397
9398var appendAllChildren;
9399var updateHostContainer;
9400var updateHostComponent$1;
9401var updateHostText$1;
9402
9403{
9404 // Mutation mode
9405 appendAllChildren = function (parent, workInProgress, needsVisibilityToggle, isHidden) {
9406 // We only have the top Fiber that was created but we need recurse down its
9407 // children to find all the terminal nodes.
9408 var node = workInProgress.child;
9409
9410 while (node !== null) {
9411 if (node.tag === HostComponent || node.tag === HostText) {
9412 appendInitialChild(parent, node.stateNode);
9413 } else if (node.tag === HostPortal) ; else if (node.child !== null) {
9414 node.child.return = node;
9415 node = node.child;
9416 continue;
9417 }
9418
9419 if (node === workInProgress) {
9420 return;
9421 }
9422
9423 while (node.sibling === null) {
9424 if (node.return === null || node.return === workInProgress) {
9425 return;
9426 }
9427
9428 node = node.return;
9429 }
9430
9431 node.sibling.return = node.return;
9432 node = node.sibling;
9433 }
9434 };
9435
9436 updateHostContainer = function (workInProgress) {// Noop
9437 };
9438
9439 updateHostComponent$1 = function (current, workInProgress, type, newProps, rootContainerInstance) {
9440 // If we have an alternate, that means this is an update and we need to
9441 // schedule a side-effect to do the updates.
9442 var oldProps = current.memoizedProps;
9443
9444 if (oldProps === newProps) {
9445 // In mutation mode, this is sufficient for a bailout because
9446 // we won't touch this node even if children changed.
9447 return;
9448 } // If we get updated because one of our children updated, we don't
9449 // have newProps so we'll have to reuse them.
9450 // TODO: Split the update API as separate for the props vs. children.
9451 // Even better would be if children weren't special cased at all tho.
9452
9453
9454 var instance = workInProgress.stateNode;
9455 var currentHostContext = getHostContext(); // TODO: Experiencing an error where oldProps is null. Suggests a host
9456 // component is hitting the resume path. Figure out why. Possibly
9457 // related to `hidden`.
9458
9459 var updatePayload = prepareUpdate(); // TODO: Type this specific to this type of component.
9460
9461 workInProgress.updateQueue = updatePayload; // If the update payload indicates that there is a change or if there
9462 // is a new ref we mark this as an update. All the work is done in commitWork.
9463
9464 if (updatePayload) {
9465 markUpdate(workInProgress);
9466 }
9467 };
9468
9469 updateHostText$1 = function (current, workInProgress, oldText, newText) {
9470 // If the text differs, mark it as an update. All the work in done in commitWork.
9471 if (oldText !== newText) {
9472 markUpdate(workInProgress);
9473 }
9474 };
9475}
9476
9477function cutOffTailIfNeeded(renderState, hasRenderedATailFallback) {
9478 switch (renderState.tailMode) {
9479 case 'hidden':
9480 {
9481 // Any insertions at the end of the tail list after this point
9482 // should be invisible. If there are already mounted boundaries
9483 // anything before them are not considered for collapsing.
9484 // Therefore we need to go through the whole tail to find if
9485 // there are any.
9486 var tailNode = renderState.tail;
9487 var lastTailNode = null;
9488
9489 while (tailNode !== null) {
9490 if (tailNode.alternate !== null) {
9491 lastTailNode = tailNode;
9492 }
9493
9494 tailNode = tailNode.sibling;
9495 } // Next we're simply going to delete all insertions after the
9496 // last rendered item.
9497
9498
9499 if (lastTailNode === null) {
9500 // All remaining items in the tail are insertions.
9501 renderState.tail = null;
9502 } else {
9503 // Detach the insertion after the last node that was already
9504 // inserted.
9505 lastTailNode.sibling = null;
9506 }
9507
9508 break;
9509 }
9510
9511 case 'collapsed':
9512 {
9513 // Any insertions at the end of the tail list after this point
9514 // should be invisible. If there are already mounted boundaries
9515 // anything before them are not considered for collapsing.
9516 // Therefore we need to go through the whole tail to find if
9517 // there are any.
9518 var _tailNode = renderState.tail;
9519 var _lastTailNode = null;
9520
9521 while (_tailNode !== null) {
9522 if (_tailNode.alternate !== null) {
9523 _lastTailNode = _tailNode;
9524 }
9525
9526 _tailNode = _tailNode.sibling;
9527 } // Next we're simply going to delete all insertions after the
9528 // last rendered item.
9529
9530
9531 if (_lastTailNode === null) {
9532 // All remaining items in the tail are insertions.
9533 if (!hasRenderedATailFallback && renderState.tail !== null) {
9534 // We suspended during the head. We want to show at least one
9535 // row at the tail. So we'll keep on and cut off the rest.
9536 renderState.tail.sibling = null;
9537 } else {
9538 renderState.tail = null;
9539 }
9540 } else {
9541 // Detach the insertion after the last node that was already
9542 // inserted.
9543 _lastTailNode.sibling = null;
9544 }
9545
9546 break;
9547 }
9548 }
9549}
9550
9551function completeWork(current, workInProgress, renderExpirationTime) {
9552 var newProps = workInProgress.pendingProps;
9553
9554 switch (workInProgress.tag) {
9555 case IndeterminateComponent:
9556 case LazyComponent:
9557 case SimpleMemoComponent:
9558 case FunctionComponent:
9559 case ForwardRef:
9560 case Fragment:
9561 case Mode:
9562 case Profiler:
9563 case ContextConsumer:
9564 case MemoComponent:
9565 return null;
9566
9567 case ClassComponent:
9568 {
9569 var Component = workInProgress.type;
9570
9571 if (isContextProvider(Component)) {
9572 popContext(workInProgress);
9573 }
9574
9575 return null;
9576 }
9577
9578 case HostRoot:
9579 {
9580 popHostContainer(workInProgress);
9581 popTopLevelContextObject(workInProgress);
9582 var fiberRoot = workInProgress.stateNode;
9583
9584 if (fiberRoot.pendingContext) {
9585 fiberRoot.context = fiberRoot.pendingContext;
9586 fiberRoot.pendingContext = null;
9587 }
9588
9589 if (current === null || current.child === null) {
9590 // If we hydrated, pop so that we can delete any remaining children
9591 // that weren't hydrated.
9592 var wasHydrated = popHydrationState();
9593
9594 if (wasHydrated) {
9595 // If we hydrated, then we'll need to schedule an update for
9596 // the commit side-effects on the root.
9597 markUpdate(workInProgress);
9598 }
9599 }
9600
9601 updateHostContainer(workInProgress);
9602 return null;
9603 }
9604
9605 case HostComponent:
9606 {
9607 popHostContext(workInProgress);
9608 var rootContainerInstance = getRootHostContainer();
9609 var type = workInProgress.type;
9610
9611 if (current !== null && workInProgress.stateNode != null) {
9612 updateHostComponent$1(current, workInProgress, type, newProps, rootContainerInstance);
9613
9614 if (current.ref !== workInProgress.ref) {
9615 markRef$1(workInProgress);
9616 }
9617 } else {
9618 if (!newProps) {
9619 if (!(workInProgress.stateNode !== null)) {
9620 {
9621 throw Error( "We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue." );
9622 }
9623 } // This can happen when we abort work.
9624
9625
9626 return null;
9627 }
9628
9629 var currentHostContext = getHostContext(); // TODO: Move createInstance to beginWork and keep it on a context
9630 // "stack" as the parent. Then append children as we go in beginWork
9631 // or completeWork depending on whether we want to add them top->down or
9632 // bottom->up. Top->down is faster in IE11.
9633
9634 var _wasHydrated = popHydrationState();
9635
9636 if (_wasHydrated) {
9637 // TODO: Move this and createInstance step into the beginPhase
9638 // to consolidate.
9639 if (prepareToHydrateHostInstance()) {
9640 // If changes to the hydrated node need to be applied at the
9641 // commit-phase we mark this as such.
9642 markUpdate(workInProgress);
9643 }
9644 } else {
9645 var instance = createInstance(type, newProps);
9646 appendAllChildren(instance, workInProgress, false, false); // This needs to be set before we mount Flare event listeners
9647
9648 workInProgress.stateNode = instance;
9649 }
9650
9651 if (workInProgress.ref !== null) {
9652 // If there is a ref on a host node we need to schedule a callback
9653 markRef$1(workInProgress);
9654 }
9655 }
9656
9657 return null;
9658 }
9659
9660 case HostText:
9661 {
9662 var newText = newProps;
9663
9664 if (current && workInProgress.stateNode != null) {
9665 var oldText = current.memoizedProps; // If we have an alternate, that means this is an update and we need
9666 // to schedule a side-effect to do the updates.
9667
9668 updateHostText$1(current, workInProgress, oldText, newText);
9669 } else {
9670 if (typeof newText !== 'string') {
9671 if (!(workInProgress.stateNode !== null)) {
9672 {
9673 throw Error( "We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue." );
9674 }
9675 } // This can happen when we abort work.
9676
9677 }
9678
9679 var _rootContainerInstance = getRootHostContainer();
9680
9681 var _currentHostContext = getHostContext();
9682
9683 var _wasHydrated2 = popHydrationState();
9684
9685 if (_wasHydrated2) {
9686 if (prepareToHydrateHostTextInstance()) {
9687 markUpdate(workInProgress);
9688 }
9689 } else {
9690 workInProgress.stateNode = createTextInstance(newText);
9691 }
9692 }
9693
9694 return null;
9695 }
9696
9697 case SuspenseComponent:
9698 {
9699 popSuspenseContext(workInProgress);
9700 var nextState = workInProgress.memoizedState;
9701
9702 if ((workInProgress.effectTag & DidCapture) !== NoEffect) {
9703 // Something suspended. Re-render with the fallback children.
9704 workInProgress.expirationTime = renderExpirationTime; // Do not reset the effect list.
9705
9706 return workInProgress;
9707 }
9708
9709 var nextDidTimeout = nextState !== null;
9710 var prevDidTimeout = false;
9711
9712 if (current === null) {
9713 if (workInProgress.memoizedProps.fallback !== undefined) ;
9714 } else {
9715 var prevState = current.memoizedState;
9716 prevDidTimeout = prevState !== null;
9717
9718 if (!nextDidTimeout && prevState !== null) {
9719 // We just switched from the fallback to the normal children.
9720 // Delete the fallback.
9721 // TODO: Would it be better to store the fallback fragment on
9722 // the stateNode during the begin phase?
9723 var currentFallbackChild = current.child.sibling;
9724
9725 if (currentFallbackChild !== null) {
9726 // Deletions go at the beginning of the return fiber's effect list
9727 var first = workInProgress.firstEffect;
9728
9729 if (first !== null) {
9730 workInProgress.firstEffect = currentFallbackChild;
9731 currentFallbackChild.nextEffect = first;
9732 } else {
9733 workInProgress.firstEffect = workInProgress.lastEffect = currentFallbackChild;
9734 currentFallbackChild.nextEffect = null;
9735 }
9736
9737 currentFallbackChild.effectTag = Deletion;
9738 }
9739 }
9740 }
9741
9742 if (nextDidTimeout && !prevDidTimeout) {
9743 // If this subtreee is running in blocking mode we can suspend,
9744 // otherwise we won't suspend.
9745 // TODO: This will still suspend a synchronous tree if anything
9746 // in the concurrent tree already suspended during this render.
9747 // This is a known bug.
9748 if ((workInProgress.mode & BlockingMode) !== NoMode) {
9749 // TODO: Move this back to throwException because this is too late
9750 // if this is a large tree which is common for initial loads. We
9751 // don't know if we should restart a render or not until we get
9752 // this marker, and this is too late.
9753 // If this render already had a ping or lower pri updates,
9754 // and this is the first time we know we're going to suspend we
9755 // should be able to immediately restart from within throwException.
9756 var hasInvisibleChildContext = current === null && workInProgress.memoizedProps.unstable_avoidThisFallback !== true;
9757
9758 if (hasInvisibleChildContext || hasSuspenseContext(suspenseStackCursor.current, InvisibleParentSuspenseContext)) {
9759 // If this was in an invisible tree or a new render, then showing
9760 // this boundary is ok.
9761 renderDidSuspend();
9762 } else {
9763 // Otherwise, we're going to have to hide content so we should
9764 // suspend for longer if possible.
9765 renderDidSuspendDelayIfPossible();
9766 }
9767 }
9768 }
9769
9770 {
9771 // TODO: Only schedule updates if these values are non equal, i.e. it changed.
9772 if (nextDidTimeout || prevDidTimeout) {
9773 // If this boundary just timed out, schedule an effect to attach a
9774 // retry listener to the promise. This flag is also used to hide the
9775 // primary children. In mutation mode, we also need the flag to
9776 // *unhide* children that were previously hidden, so check if this
9777 // is currently timed out, too.
9778 workInProgress.effectTag |= Update;
9779 }
9780 }
9781
9782 return null;
9783 }
9784
9785 case HostPortal:
9786 popHostContainer(workInProgress);
9787 updateHostContainer(workInProgress);
9788 return null;
9789
9790 case ContextProvider:
9791 // Pop provider fiber
9792 popProvider(workInProgress);
9793 return null;
9794
9795 case IncompleteClassComponent:
9796 {
9797 // Same as class component case. I put it down here so that the tags are
9798 // sequential to ensure this switch is compiled to a jump table.
9799 var _Component = workInProgress.type;
9800
9801 if (isContextProvider(_Component)) {
9802 popContext(workInProgress);
9803 }
9804
9805 return null;
9806 }
9807
9808 case SuspenseListComponent:
9809 {
9810 popSuspenseContext(workInProgress);
9811 var renderState = workInProgress.memoizedState;
9812
9813 if (renderState === null) {
9814 // We're running in the default, "independent" mode.
9815 // We don't do anything in this mode.
9816 return null;
9817 }
9818
9819 var didSuspendAlready = (workInProgress.effectTag & DidCapture) !== NoEffect;
9820 var renderedTail = renderState.rendering;
9821
9822 if (renderedTail === null) {
9823 // We just rendered the head.
9824 if (!didSuspendAlready) {
9825 // This is the first pass. We need to figure out if anything is still
9826 // suspended in the rendered set.
9827 // If new content unsuspended, but there's still some content that
9828 // didn't. Then we need to do a second pass that forces everything
9829 // to keep showing their fallbacks.
9830 // We might be suspended if something in this render pass suspended, or
9831 // something in the previous committed pass suspended. Otherwise,
9832 // there's no chance so we can skip the expensive call to
9833 // findFirstSuspended.
9834 var cannotBeSuspended = renderHasNotSuspendedYet() && (current === null || (current.effectTag & DidCapture) === NoEffect);
9835
9836 if (!cannotBeSuspended) {
9837 var row = workInProgress.child;
9838
9839 while (row !== null) {
9840 var suspended = findFirstSuspended(row);
9841
9842 if (suspended !== null) {
9843 didSuspendAlready = true;
9844 workInProgress.effectTag |= DidCapture;
9845 cutOffTailIfNeeded(renderState, false); // If this is a newly suspended tree, it might not get committed as
9846 // part of the second pass. In that case nothing will subscribe to
9847 // its thennables. Instead, we'll transfer its thennables to the
9848 // SuspenseList so that it can retry if they resolve.
9849 // There might be multiple of these in the list but since we're
9850 // going to wait for all of them anyway, it doesn't really matter
9851 // which ones gets to ping. In theory we could get clever and keep
9852 // track of how many dependencies remain but it gets tricky because
9853 // in the meantime, we can add/remove/change items and dependencies.
9854 // We might bail out of the loop before finding any but that
9855 // doesn't matter since that means that the other boundaries that
9856 // we did find already has their listeners attached.
9857
9858 var newThennables = suspended.updateQueue;
9859
9860 if (newThennables !== null) {
9861 workInProgress.updateQueue = newThennables;
9862 workInProgress.effectTag |= Update;
9863 } // Rerender the whole list, but this time, we'll force fallbacks
9864 // to stay in place.
9865 // Reset the effect list before doing the second pass since that's now invalid.
9866
9867
9868 if (renderState.lastEffect === null) {
9869 workInProgress.firstEffect = null;
9870 }
9871
9872 workInProgress.lastEffect = renderState.lastEffect; // Reset the child fibers to their original state.
9873
9874 resetChildFibers(workInProgress, renderExpirationTime); // Set up the Suspense Context to force suspense and immediately
9875 // rerender the children.
9876
9877 pushSuspenseContext(workInProgress, setShallowSuspenseContext(suspenseStackCursor.current, ForceSuspenseFallback));
9878 return workInProgress.child;
9879 }
9880
9881 row = row.sibling;
9882 }
9883 }
9884 } else {
9885 cutOffTailIfNeeded(renderState, false);
9886 } // Next we're going to render the tail.
9887
9888 } else {
9889 // Append the rendered row to the child list.
9890 if (!didSuspendAlready) {
9891 var _suspended = findFirstSuspended(renderedTail);
9892
9893 if (_suspended !== null) {
9894 workInProgress.effectTag |= DidCapture;
9895 didSuspendAlready = true; // Ensure we transfer the update queue to the parent so that it doesn't
9896 // get lost if this row ends up dropped during a second pass.
9897
9898 var _newThennables = _suspended.updateQueue;
9899
9900 if (_newThennables !== null) {
9901 workInProgress.updateQueue = _newThennables;
9902 workInProgress.effectTag |= Update;
9903 }
9904
9905 cutOffTailIfNeeded(renderState, true); // This might have been modified.
9906
9907 if (renderState.tail === null && renderState.tailMode === 'hidden' && !renderedTail.alternate) {
9908 // We need to delete the row we just rendered.
9909 // Reset the effect list to what it was before we rendered this
9910 // child. The nested children have already appended themselves.
9911 var lastEffect = workInProgress.lastEffect = renderState.lastEffect; // Remove any effects that were appended after this point.
9912
9913 if (lastEffect !== null) {
9914 lastEffect.nextEffect = null;
9915 } // We're done.
9916
9917
9918 return null;
9919 }
9920 } else if ( // The time it took to render last row is greater than time until
9921 // the expiration.
9922 now() * 2 - renderState.renderingStartTime > renderState.tailExpiration && renderExpirationTime > Never) {
9923 // We have now passed our CPU deadline and we'll just give up further
9924 // attempts to render the main content and only render fallbacks.
9925 // The assumption is that this is usually faster.
9926 workInProgress.effectTag |= DidCapture;
9927 didSuspendAlready = true;
9928 cutOffTailIfNeeded(renderState, false); // Since nothing actually suspended, there will nothing to ping this
9929 // to get it started back up to attempt the next item. If we can show
9930 // them, then they really have the same priority as this render.
9931 // So we'll pick it back up the very next render pass once we've had
9932 // an opportunity to yield for paint.
9933
9934 var nextPriority = renderExpirationTime - 1;
9935 workInProgress.expirationTime = workInProgress.childExpirationTime = nextPriority;
9936
9937 {
9938 markSpawnedWork(nextPriority);
9939 }
9940 }
9941 }
9942
9943 if (renderState.isBackwards) {
9944 // The effect list of the backwards tail will have been added
9945 // to the end. This breaks the guarantee that life-cycles fire in
9946 // sibling order but that isn't a strong guarantee promised by React.
9947 // Especially since these might also just pop in during future commits.
9948 // Append to the beginning of the list.
9949 renderedTail.sibling = workInProgress.child;
9950 workInProgress.child = renderedTail;
9951 } else {
9952 var previousSibling = renderState.last;
9953
9954 if (previousSibling !== null) {
9955 previousSibling.sibling = renderedTail;
9956 } else {
9957 workInProgress.child = renderedTail;
9958 }
9959
9960 renderState.last = renderedTail;
9961 }
9962 }
9963
9964 if (renderState.tail !== null) {
9965 // We still have tail rows to render.
9966 if (renderState.tailExpiration === 0) {
9967 // Heuristic for how long we're willing to spend rendering rows
9968 // until we just give up and show what we have so far.
9969 var TAIL_EXPIRATION_TIMEOUT_MS = 500;
9970 renderState.tailExpiration = now() + TAIL_EXPIRATION_TIMEOUT_MS; // TODO: This is meant to mimic the train model or JND but this
9971 // is a per component value. It should really be since the start
9972 // of the total render or last commit. Consider using something like
9973 // globalMostRecentFallbackTime. That doesn't account for being
9974 // suspended for part of the time or when it's a new render.
9975 // It should probably use a global start time value instead.
9976 } // Pop a row.
9977
9978
9979 var next = renderState.tail;
9980 renderState.rendering = next;
9981 renderState.tail = next.sibling;
9982 renderState.lastEffect = workInProgress.lastEffect;
9983 renderState.renderingStartTime = now();
9984 next.sibling = null; // Restore the context.
9985 // TODO: We can probably just avoid popping it instead and only
9986 // setting it the first time we go from not suspended to suspended.
9987
9988 var suspenseContext = suspenseStackCursor.current;
9989
9990 if (didSuspendAlready) {
9991 suspenseContext = setShallowSuspenseContext(suspenseContext, ForceSuspenseFallback);
9992 } else {
9993 suspenseContext = setDefaultShallowSuspenseContext(suspenseContext);
9994 }
9995
9996 pushSuspenseContext(workInProgress, suspenseContext); // Do a pass over the next row.
9997
9998 return next;
9999 }
10000
10001 return null;
10002 }
10003 }
10004
10005 {
10006 {
10007 throw Error( "Unknown unit of work tag (" + workInProgress.tag + "). This error is likely caused by a bug in React. Please file an issue." );
10008 }
10009 }
10010}
10011
10012function unwindWork(workInProgress, renderExpirationTime) {
10013 switch (workInProgress.tag) {
10014 case ClassComponent:
10015 {
10016 var Component = workInProgress.type;
10017
10018 if (isContextProvider(Component)) {
10019 popContext(workInProgress);
10020 }
10021
10022 var effectTag = workInProgress.effectTag;
10023
10024 if (effectTag & ShouldCapture) {
10025 workInProgress.effectTag = effectTag & ~ShouldCapture | DidCapture;
10026 return workInProgress;
10027 }
10028
10029 return null;
10030 }
10031
10032 case HostRoot:
10033 {
10034 popHostContainer(workInProgress);
10035 popTopLevelContextObject(workInProgress);
10036 var _effectTag = workInProgress.effectTag;
10037
10038 if (!((_effectTag & DidCapture) === NoEffect)) {
10039 {
10040 throw Error( "The root failed to unmount after an error. This is likely a bug in React. Please file an issue." );
10041 }
10042 }
10043
10044 workInProgress.effectTag = _effectTag & ~ShouldCapture | DidCapture;
10045 return workInProgress;
10046 }
10047
10048 case HostComponent:
10049 {
10050 // TODO: popHydrationState
10051 popHostContext(workInProgress);
10052 return null;
10053 }
10054
10055 case SuspenseComponent:
10056 {
10057 popSuspenseContext(workInProgress);
10058
10059 var _effectTag2 = workInProgress.effectTag;
10060
10061 if (_effectTag2 & ShouldCapture) {
10062 workInProgress.effectTag = _effectTag2 & ~ShouldCapture | DidCapture; // Captured a suspense effect. Re-render the boundary.
10063
10064 return workInProgress;
10065 }
10066
10067 return null;
10068 }
10069
10070 case SuspenseListComponent:
10071 {
10072 popSuspenseContext(workInProgress); // SuspenseList doesn't actually catch anything. It should've been
10073 // caught by a nested boundary. If not, it should bubble through.
10074
10075 return null;
10076 }
10077
10078 case HostPortal:
10079 popHostContainer(workInProgress);
10080 return null;
10081
10082 case ContextProvider:
10083 popProvider(workInProgress);
10084 return null;
10085
10086 default:
10087 return null;
10088 }
10089}
10090
10091function unwindInterruptedWork(interruptedWork) {
10092 switch (interruptedWork.tag) {
10093 case ClassComponent:
10094 {
10095 var childContextTypes = interruptedWork.type.childContextTypes;
10096
10097 if (childContextTypes !== null && childContextTypes !== undefined) {
10098 popContext(interruptedWork);
10099 }
10100
10101 break;
10102 }
10103
10104 case HostRoot:
10105 {
10106 popHostContainer(interruptedWork);
10107 popTopLevelContextObject(interruptedWork);
10108 break;
10109 }
10110
10111 case HostComponent:
10112 {
10113 popHostContext(interruptedWork);
10114 break;
10115 }
10116
10117 case HostPortal:
10118 popHostContainer(interruptedWork);
10119 break;
10120
10121 case SuspenseComponent:
10122 popSuspenseContext(interruptedWork);
10123 break;
10124
10125 case SuspenseListComponent:
10126 popSuspenseContext(interruptedWork);
10127 break;
10128
10129 case ContextProvider:
10130 popProvider(interruptedWork);
10131 break;
10132 }
10133}
10134
10135function createCapturedValue(value, source) {
10136 // If the value is an error, call this function immediately after it is thrown
10137 // so the stack is accurate.
10138 return {
10139 value: value,
10140 source: source,
10141 stack: getStackByFiberInDevAndProd(source)
10142 };
10143}
10144
10145var invokeGuardedCallbackImpl = function (name, func, context, a, b, c, d, e, f) {
10146 var funcArgs = Array.prototype.slice.call(arguments, 3);
10147
10148 try {
10149 func.apply(context, funcArgs);
10150 } catch (error) {
10151 this.onError(error);
10152 }
10153};
10154
10155{
10156 // In DEV mode, we swap out invokeGuardedCallback for a special version
10157 // that plays more nicely with the browser's DevTools. The idea is to preserve
10158 // "Pause on exceptions" behavior. Because React wraps all user-provided
10159 // functions in invokeGuardedCallback, and the production version of
10160 // invokeGuardedCallback uses a try-catch, all user exceptions are treated
10161 // like caught exceptions, and the DevTools won't pause unless the developer
10162 // takes the extra step of enabling pause on caught exceptions. This is
10163 // unintuitive, though, because even though React has caught the error, from
10164 // the developer's perspective, the error is uncaught.
10165 //
10166 // To preserve the expected "Pause on exceptions" behavior, we don't use a
10167 // try-catch in DEV. Instead, we synchronously dispatch a fake event to a fake
10168 // DOM node, and call the user-provided callback from inside an event handler
10169 // for that fake event. If the callback throws, the error is "captured" using
10170 // a global event handler. But because the error happens in a different
10171 // event loop context, it does not interrupt the normal program flow.
10172 // Effectively, this gives us try-catch behavior without actually using
10173 // try-catch. Neat!
10174 // Check that the browser supports the APIs we need to implement our special
10175 // DEV version of invokeGuardedCallback
10176 if (typeof window !== 'undefined' && typeof window.dispatchEvent === 'function' && typeof document !== 'undefined' && typeof document.createEvent === 'function') {
10177 var fakeNode = document.createElement('react');
10178
10179 var invokeGuardedCallbackDev = function (name, func, context, a, b, c, d, e, f) {
10180 // If document doesn't exist we know for sure we will crash in this method
10181 // when we call document.createEvent(). However this can cause confusing
10182 // errors: https://github.com/facebookincubator/create-react-app/issues/3482
10183 // So we preemptively throw with a better message instead.
10184 if (!(typeof document !== 'undefined')) {
10185 {
10186 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." );
10187 }
10188 }
10189
10190 var evt = document.createEvent('Event'); // Keeps track of whether the user-provided callback threw an error. We
10191 // set this to true at the beginning, then set it to false right after
10192 // calling the function. If the function errors, `didError` will never be
10193 // set to false. This strategy works even if the browser is flaky and
10194 // fails to call our global error handler, because it doesn't rely on
10195 // the error event at all.
10196
10197 var didError = true; // Keeps track of the value of window.event so that we can reset it
10198 // during the callback to let user code access window.event in the
10199 // browsers that support it.
10200
10201 var windowEvent = window.event; // Keeps track of the descriptor of window.event to restore it after event
10202 // dispatching: https://github.com/facebook/react/issues/13688
10203
10204 var windowEventDescriptor = Object.getOwnPropertyDescriptor(window, 'event'); // Create an event handler for our fake event. We will synchronously
10205 // dispatch our fake event using `dispatchEvent`. Inside the handler, we
10206 // call the user-provided callback.
10207
10208 var funcArgs = Array.prototype.slice.call(arguments, 3);
10209
10210 function callCallback() {
10211 // We immediately remove the callback from event listeners so that
10212 // nested `invokeGuardedCallback` calls do not clash. Otherwise, a
10213 // nested call would trigger the fake event handlers of any call higher
10214 // in the stack.
10215 fakeNode.removeEventListener(evtType, callCallback, false); // We check for window.hasOwnProperty('event') to prevent the
10216 // window.event assignment in both IE <= 10 as they throw an error
10217 // "Member not found" in strict mode, and in Firefox which does not
10218 // support window.event.
10219
10220 if (typeof window.event !== 'undefined' && window.hasOwnProperty('event')) {
10221 window.event = windowEvent;
10222 }
10223
10224 func.apply(context, funcArgs);
10225 didError = false;
10226 } // Create a global error event handler. We use this to capture the value
10227 // that was thrown. It's possible that this error handler will fire more
10228 // than once; for example, if non-React code also calls `dispatchEvent`
10229 // and a handler for that event throws. We should be resilient to most of
10230 // those cases. Even if our error event handler fires more than once, the
10231 // last error event is always used. If the callback actually does error,
10232 // we know that the last error event is the correct one, because it's not
10233 // possible for anything else to have happened in between our callback
10234 // erroring and the code that follows the `dispatchEvent` call below. If
10235 // the callback doesn't error, but the error event was fired, we know to
10236 // ignore it because `didError` will be false, as described above.
10237
10238
10239 var error; // Use this to track whether the error event is ever called.
10240
10241 var didSetError = false;
10242 var isCrossOriginError = false;
10243
10244 function handleWindowError(event) {
10245 error = event.error;
10246 didSetError = true;
10247
10248 if (error === null && event.colno === 0 && event.lineno === 0) {
10249 isCrossOriginError = true;
10250 }
10251
10252 if (event.defaultPrevented) {
10253 // Some other error handler has prevented default.
10254 // Browsers silence the error report if this happens.
10255 // We'll remember this to later decide whether to log it or not.
10256 if (error != null && typeof error === 'object') {
10257 try {
10258 error._suppressLogging = true;
10259 } catch (inner) {// Ignore.
10260 }
10261 }
10262 }
10263 } // Create a fake event type.
10264
10265
10266 var evtType = "react-" + (name ? name : 'invokeguardedcallback'); // Attach our event handlers
10267
10268 window.addEventListener('error', handleWindowError);
10269 fakeNode.addEventListener(evtType, callCallback, false); // Synchronously dispatch our fake event. If the user-provided function
10270 // errors, it will trigger our global error handler.
10271
10272 evt.initEvent(evtType, false, false);
10273 fakeNode.dispatchEvent(evt);
10274
10275 if (windowEventDescriptor) {
10276 Object.defineProperty(window, 'event', windowEventDescriptor);
10277 }
10278
10279 if (didError) {
10280 if (!didSetError) {
10281 // The callback errored, but the error event never fired.
10282 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.');
10283 } else if (isCrossOriginError) {
10284 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.');
10285 }
10286
10287 this.onError(error);
10288 } // Remove our event listeners
10289
10290
10291 window.removeEventListener('error', handleWindowError);
10292 };
10293
10294 invokeGuardedCallbackImpl = invokeGuardedCallbackDev;
10295 }
10296}
10297
10298var invokeGuardedCallbackImpl$1 = invokeGuardedCallbackImpl;
10299
10300var hasError = false;
10301var caughtError = null; // Used by event system to capture/rethrow the first error.
10302var reporter = {
10303 onError: function (error) {
10304 hasError = true;
10305 caughtError = error;
10306 }
10307};
10308/**
10309 * Call a function while guarding against errors that happens within it.
10310 * Returns an error if it throws, otherwise null.
10311 *
10312 * In production, this is implemented using a try-catch. The reason we don't
10313 * use a try-catch directly is so that we can swap out a different
10314 * implementation in DEV mode.
10315 *
10316 * @param {String} name of the guard to use for logging or debugging
10317 * @param {Function} func The function to invoke
10318 * @param {*} context The context to use when calling the function
10319 * @param {...*} args Arguments for function
10320 */
10321
10322function invokeGuardedCallback(name, func, context, a, b, c, d, e, f) {
10323 hasError = false;
10324 caughtError = null;
10325 invokeGuardedCallbackImpl$1.apply(reporter, arguments);
10326}
10327function hasCaughtError() {
10328 return hasError;
10329}
10330function clearCaughtError() {
10331 if (hasError) {
10332 var error = caughtError;
10333 hasError = false;
10334 caughtError = null;
10335 return error;
10336 } else {
10337 {
10338 {
10339 throw Error( "clearCaughtError was called but no error was captured. This error is likely caused by a bug in React. Please file an issue." );
10340 }
10341 }
10342 }
10343}
10344
10345function logCapturedError(capturedError) {
10346
10347 var error = capturedError.error;
10348
10349 {
10350 var componentName = capturedError.componentName,
10351 componentStack = capturedError.componentStack,
10352 errorBoundaryName = capturedError.errorBoundaryName,
10353 errorBoundaryFound = capturedError.errorBoundaryFound,
10354 willRetry = capturedError.willRetry; // Browsers support silencing uncaught errors by calling
10355 // `preventDefault()` in window `error` handler.
10356 // We record this information as an expando on the error.
10357
10358 if (error != null && error._suppressLogging) {
10359 if (errorBoundaryFound && willRetry) {
10360 // The error is recoverable and was silenced.
10361 // Ignore it and don't print the stack addendum.
10362 // This is handy for testing error boundaries without noise.
10363 return;
10364 } // The error is fatal. Since the silencing might have
10365 // been accidental, we'll surface it anyway.
10366 // However, the browser would have silenced the original error
10367 // so we'll print it first, and then print the stack addendum.
10368
10369
10370 console['error'](error); // Don't transform to our wrapper
10371 // For a more detailed description of this block, see:
10372 // https://github.com/facebook/react/pull/13384
10373 }
10374
10375 var componentNameMessage = componentName ? "The above error occurred in the <" + componentName + "> component:" : 'The above error occurred in one of your React components:';
10376 var errorBoundaryMessage; // errorBoundaryFound check is sufficient; errorBoundaryName check is to satisfy Flow.
10377
10378 if (errorBoundaryFound && errorBoundaryName) {
10379 if (willRetry) {
10380 errorBoundaryMessage = "React will try to recreate this component tree from scratch " + ("using the error boundary you provided, " + errorBoundaryName + ".");
10381 } else {
10382 errorBoundaryMessage = "This error was initially handled by the error boundary " + errorBoundaryName + ".\n" + "Recreating the tree from scratch failed so React will unmount the tree.";
10383 }
10384 } else {
10385 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.';
10386 }
10387
10388 var combinedMessage = "" + componentNameMessage + componentStack + "\n\n" + ("" + errorBoundaryMessage); // In development, we provide our own message with just the component stack.
10389 // We don't include the original error message and JS stack because the browser
10390 // has already printed it. Even if the application swallows the error, it is still
10391 // displayed by the browser thanks to the DEV-only fake event trick in ReactErrorUtils.
10392
10393 console['error'](combinedMessage); // Don't transform to our wrapper
10394 }
10395}
10396
10397var didWarnAboutUndefinedSnapshotBeforeUpdate = null;
10398
10399{
10400 didWarnAboutUndefinedSnapshotBeforeUpdate = new Set();
10401}
10402
10403var PossiblyWeakSet = typeof WeakSet === 'function' ? WeakSet : Set;
10404function logError(boundary, errorInfo) {
10405 var source = errorInfo.source;
10406 var stack = errorInfo.stack;
10407
10408 if (stack === null && source !== null) {
10409 stack = getStackByFiberInDevAndProd(source);
10410 }
10411
10412 var capturedError = {
10413 componentName: source !== null ? getComponentName(source.type) : null,
10414 componentStack: stack !== null ? stack : '',
10415 error: errorInfo.value,
10416 errorBoundary: null,
10417 errorBoundaryName: null,
10418 errorBoundaryFound: false,
10419 willRetry: false
10420 };
10421
10422 if (boundary !== null && boundary.tag === ClassComponent) {
10423 capturedError.errorBoundary = boundary.stateNode;
10424 capturedError.errorBoundaryName = getComponentName(boundary.type);
10425 capturedError.errorBoundaryFound = true;
10426 capturedError.willRetry = true;
10427 }
10428
10429 try {
10430 logCapturedError(capturedError);
10431 } catch (e) {
10432 // This method must not throw, or React internal state will get messed up.
10433 // If console.error is overridden, or logCapturedError() shows a dialog that throws,
10434 // we want to report this error outside of the normal stack as a last resort.
10435 // https://github.com/facebook/react/issues/13188
10436 setTimeout(function () {
10437 throw e;
10438 });
10439 }
10440}
10441
10442var callComponentWillUnmountWithTimer = function (current, instance) {
10443 startPhaseTimer(current, 'componentWillUnmount');
10444 instance.props = current.memoizedProps;
10445 instance.state = current.memoizedState;
10446 instance.componentWillUnmount();
10447 stopPhaseTimer();
10448}; // Capture errors so they don't interrupt unmounting.
10449
10450
10451function safelyCallComponentWillUnmount(current, instance) {
10452 {
10453 invokeGuardedCallback(null, callComponentWillUnmountWithTimer, null, current, instance);
10454
10455 if (hasCaughtError()) {
10456 var unmountError = clearCaughtError();
10457 captureCommitPhaseError(current, unmountError);
10458 }
10459 }
10460}
10461
10462function safelyDetachRef(current) {
10463 var ref = current.ref;
10464
10465 if (ref !== null) {
10466 if (typeof ref === 'function') {
10467 {
10468 invokeGuardedCallback(null, ref, null, null);
10469
10470 if (hasCaughtError()) {
10471 var refError = clearCaughtError();
10472 captureCommitPhaseError(current, refError);
10473 }
10474 }
10475 } else {
10476 ref.current = null;
10477 }
10478 }
10479}
10480
10481function safelyCallDestroy(current, destroy) {
10482 {
10483 invokeGuardedCallback(null, destroy, null);
10484
10485 if (hasCaughtError()) {
10486 var error = clearCaughtError();
10487 captureCommitPhaseError(current, error);
10488 }
10489 }
10490}
10491
10492function commitBeforeMutationLifeCycles(current, finishedWork) {
10493 switch (finishedWork.tag) {
10494 case FunctionComponent:
10495 case ForwardRef:
10496 case SimpleMemoComponent:
10497 case Block:
10498 {
10499 return;
10500 }
10501
10502 case ClassComponent:
10503 {
10504 if (finishedWork.effectTag & Snapshot) {
10505 if (current !== null) {
10506 var prevProps = current.memoizedProps;
10507 var prevState = current.memoizedState;
10508 startPhaseTimer(finishedWork, 'getSnapshotBeforeUpdate');
10509 var instance = finishedWork.stateNode; // We could update instance props and state here,
10510 // but instead we rely on them being set during last render.
10511 // TODO: revisit this when we implement resuming.
10512
10513 {
10514 if (finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps) {
10515 if (instance.props !== finishedWork.memoizedProps) {
10516 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');
10517 }
10518
10519 if (instance.state !== finishedWork.memoizedState) {
10520 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');
10521 }
10522 }
10523 }
10524
10525 var snapshot = instance.getSnapshotBeforeUpdate(finishedWork.elementType === finishedWork.type ? prevProps : resolveDefaultProps(finishedWork.type, prevProps), prevState);
10526
10527 {
10528 var didWarnSet = didWarnAboutUndefinedSnapshotBeforeUpdate;
10529
10530 if (snapshot === undefined && !didWarnSet.has(finishedWork.type)) {
10531 didWarnSet.add(finishedWork.type);
10532
10533 error('%s.getSnapshotBeforeUpdate(): A snapshot value (or null) ' + 'must be returned. You have returned undefined.', getComponentName(finishedWork.type));
10534 }
10535 }
10536
10537 instance.__reactInternalSnapshotBeforeUpdate = snapshot;
10538 stopPhaseTimer();
10539 }
10540 }
10541
10542 return;
10543 }
10544
10545 case HostRoot:
10546 case HostComponent:
10547 case HostText:
10548 case HostPortal:
10549 case IncompleteClassComponent:
10550 // Nothing to do for these component types
10551 return;
10552 }
10553
10554 {
10555 {
10556 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." );
10557 }
10558 }
10559}
10560
10561function commitHookEffectListUnmount(tag, finishedWork) {
10562 var updateQueue = finishedWork.updateQueue;
10563 var lastEffect = updateQueue !== null ? updateQueue.lastEffect : null;
10564
10565 if (lastEffect !== null) {
10566 var firstEffect = lastEffect.next;
10567 var effect = firstEffect;
10568
10569 do {
10570 if ((effect.tag & tag) === tag) {
10571 // Unmount
10572 var destroy = effect.destroy;
10573 effect.destroy = undefined;
10574
10575 if (destroy !== undefined) {
10576 destroy();
10577 }
10578 }
10579
10580 effect = effect.next;
10581 } while (effect !== firstEffect);
10582 }
10583}
10584
10585function commitHookEffectListMount(tag, finishedWork) {
10586 var updateQueue = finishedWork.updateQueue;
10587 var lastEffect = updateQueue !== null ? updateQueue.lastEffect : null;
10588
10589 if (lastEffect !== null) {
10590 var firstEffect = lastEffect.next;
10591 var effect = firstEffect;
10592
10593 do {
10594 if ((effect.tag & tag) === tag) {
10595 // Mount
10596 var create = effect.create;
10597 effect.destroy = create();
10598
10599 {
10600 var destroy = effect.destroy;
10601
10602 if (destroy !== undefined && typeof destroy !== 'function') {
10603 var addendum = void 0;
10604
10605 if (destroy === null) {
10606 addendum = ' You returned null. If your effect does not require clean ' + 'up, return undefined (or nothing).';
10607 } else if (typeof destroy.then === 'function') {
10608 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';
10609 } else {
10610 addendum = ' You returned: ' + destroy;
10611 }
10612
10613 error('An effect function must not return anything besides a function, ' + 'which is used for clean-up.%s%s', addendum, getStackByFiberInDevAndProd(finishedWork));
10614 }
10615 }
10616 }
10617
10618 effect = effect.next;
10619 } while (effect !== firstEffect);
10620 }
10621}
10622
10623function commitPassiveHookEffects(finishedWork) {
10624 if ((finishedWork.effectTag & Passive) !== NoEffect) {
10625 switch (finishedWork.tag) {
10626 case FunctionComponent:
10627 case ForwardRef:
10628 case SimpleMemoComponent:
10629 case Block:
10630 {
10631 // TODO (#17945) We should call all passive destroy functions (for all fibers)
10632 // before calling any create functions. The current approach only serializes
10633 // these for a single fiber.
10634 commitHookEffectListUnmount(Passive$1 | HasEffect, finishedWork);
10635 commitHookEffectListMount(Passive$1 | HasEffect, finishedWork);
10636 break;
10637 }
10638 }
10639 }
10640}
10641
10642function commitLifeCycles(finishedRoot, current, finishedWork, committedExpirationTime) {
10643 switch (finishedWork.tag) {
10644 case FunctionComponent:
10645 case ForwardRef:
10646 case SimpleMemoComponent:
10647 case Block:
10648 {
10649 // At this point layout effects have already been destroyed (during mutation phase).
10650 // This is done to prevent sibling component effects from interfering with each other,
10651 // e.g. a destroy function in one component should never override a ref set
10652 // by a create function in another component during the same commit.
10653 commitHookEffectListMount(Layout | HasEffect, finishedWork);
10654
10655 return;
10656 }
10657
10658 case ClassComponent:
10659 {
10660 var instance = finishedWork.stateNode;
10661
10662 if (finishedWork.effectTag & Update) {
10663 if (current === null) {
10664 startPhaseTimer(finishedWork, 'componentDidMount'); // We could update instance props and state here,
10665 // but instead we rely on them being set during last render.
10666 // TODO: revisit this when we implement resuming.
10667
10668 {
10669 if (finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps) {
10670 if (instance.props !== finishedWork.memoizedProps) {
10671 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');
10672 }
10673
10674 if (instance.state !== finishedWork.memoizedState) {
10675 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');
10676 }
10677 }
10678 }
10679
10680 instance.componentDidMount();
10681 stopPhaseTimer();
10682 } else {
10683 var prevProps = finishedWork.elementType === finishedWork.type ? current.memoizedProps : resolveDefaultProps(finishedWork.type, current.memoizedProps);
10684 var prevState = current.memoizedState;
10685 startPhaseTimer(finishedWork, 'componentDidUpdate'); // We could update instance props and state here,
10686 // but instead we rely on them being set during last render.
10687 // TODO: revisit this when we implement resuming.
10688
10689 {
10690 if (finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps) {
10691 if (instance.props !== finishedWork.memoizedProps) {
10692 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');
10693 }
10694
10695 if (instance.state !== finishedWork.memoizedState) {
10696 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');
10697 }
10698 }
10699 }
10700
10701 instance.componentDidUpdate(prevProps, prevState, instance.__reactInternalSnapshotBeforeUpdate);
10702 stopPhaseTimer();
10703 }
10704 }
10705
10706 var updateQueue = finishedWork.updateQueue;
10707
10708 if (updateQueue !== null) {
10709 {
10710 if (finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps) {
10711 if (instance.props !== finishedWork.memoizedProps) {
10712 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');
10713 }
10714
10715 if (instance.state !== finishedWork.memoizedState) {
10716 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');
10717 }
10718 }
10719 } // We could update instance props and state here,
10720 // but instead we rely on them being set during last render.
10721 // TODO: revisit this when we implement resuming.
10722
10723
10724 commitUpdateQueue(finishedWork, updateQueue, instance);
10725 }
10726
10727 return;
10728 }
10729
10730 case HostRoot:
10731 {
10732 var _updateQueue = finishedWork.updateQueue;
10733
10734 if (_updateQueue !== null) {
10735 var _instance = null;
10736
10737 if (finishedWork.child !== null) {
10738 switch (finishedWork.child.tag) {
10739 case HostComponent:
10740 _instance = getPublicInstance(finishedWork.child.stateNode);
10741 break;
10742
10743 case ClassComponent:
10744 _instance = finishedWork.child.stateNode;
10745 break;
10746 }
10747 }
10748
10749 commitUpdateQueue(finishedWork, _updateQueue, _instance);
10750 }
10751
10752 return;
10753 }
10754
10755 case HostComponent:
10756 {
10757 var _instance2 = finishedWork.stateNode; // Renderers may schedule work to be done after host components are mounted
10758 // (eg DOM renderer may schedule auto-focus for inputs and form controls).
10759 // These effects should only be committed when components are first mounted,
10760 // aka when there is no current/alternate.
10761
10762 if (current === null && finishedWork.effectTag & Update) {
10763 var type = finishedWork.type;
10764 var props = finishedWork.memoizedProps;
10765 }
10766
10767 return;
10768 }
10769
10770 case HostText:
10771 {
10772 // We have no life-cycles associated with text.
10773 return;
10774 }
10775
10776 case HostPortal:
10777 {
10778 // We have no life-cycles associated with portals.
10779 return;
10780 }
10781
10782 case Profiler:
10783 {
10784 {
10785 var onRender = finishedWork.memoizedProps.onRender;
10786
10787 if (typeof onRender === 'function') {
10788 {
10789 onRender(finishedWork.memoizedProps.id, current === null ? 'mount' : 'update', finishedWork.actualDuration, finishedWork.treeBaseDuration, finishedWork.actualStartTime, getCommitTime(), finishedRoot.memoizedInteractions);
10790 }
10791 }
10792 }
10793
10794 return;
10795 }
10796
10797 case SuspenseComponent:
10798 {
10799 return;
10800 }
10801
10802 case SuspenseListComponent:
10803 case IncompleteClassComponent:
10804 case FundamentalComponent:
10805 case ScopeComponent:
10806 return;
10807 }
10808
10809 {
10810 {
10811 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." );
10812 }
10813 }
10814}
10815
10816function hideOrUnhideAllChildren(finishedWork, isHidden) {
10817 {
10818 // We only have the top Fiber that was inserted but we need to recurse down its
10819 // children to find all the terminal nodes.
10820 var node = finishedWork;
10821
10822 while (true) {
10823 if (node.tag === HostComponent) {
10824 var instance = node.stateNode;
10825
10826 if (isHidden) {
10827 hideInstance(instance);
10828 } else {
10829 unhideInstance(node.stateNode, node.memoizedProps);
10830 }
10831 } else if (node.tag === HostText) {
10832 var _instance3 = node.stateNode;
10833
10834 if (isHidden) ; else {
10835 unhideTextInstance(_instance3, node.memoizedProps);
10836 }
10837 } else if (node.tag === SuspenseComponent && node.memoizedState !== null && node.memoizedState.dehydrated === null) {
10838 // Found a nested Suspense component that timed out. Skip over the
10839 // primary child fragment, which should remain hidden.
10840 var fallbackChildFragment = node.child.sibling;
10841 fallbackChildFragment.return = node;
10842 node = fallbackChildFragment;
10843 continue;
10844 } else if (node.child !== null) {
10845 node.child.return = node;
10846 node = node.child;
10847 continue;
10848 }
10849
10850 if (node === finishedWork) {
10851 return;
10852 }
10853
10854 while (node.sibling === null) {
10855 if (node.return === null || node.return === finishedWork) {
10856 return;
10857 }
10858
10859 node = node.return;
10860 }
10861
10862 node.sibling.return = node.return;
10863 node = node.sibling;
10864 }
10865 }
10866}
10867
10868function commitAttachRef(finishedWork) {
10869 var ref = finishedWork.ref;
10870
10871 if (ref !== null) {
10872 var instance = finishedWork.stateNode;
10873 var instanceToUse;
10874
10875 switch (finishedWork.tag) {
10876 case HostComponent:
10877 instanceToUse = getPublicInstance(instance);
10878 break;
10879
10880 default:
10881 instanceToUse = instance;
10882 } // Moved outside to ensure DCE works with this flag
10883
10884 if (typeof ref === 'function') {
10885 ref(instanceToUse);
10886 } else {
10887 {
10888 if (!ref.hasOwnProperty('current')) {
10889 error('Unexpected ref object provided for %s. ' + 'Use either a ref-setter function or React.createRef().%s', getComponentName(finishedWork.type), getStackByFiberInDevAndProd(finishedWork));
10890 }
10891 }
10892
10893 ref.current = instanceToUse;
10894 }
10895 }
10896}
10897
10898function commitDetachRef(current) {
10899 var currentRef = current.ref;
10900
10901 if (currentRef !== null) {
10902 if (typeof currentRef === 'function') {
10903 currentRef(null);
10904 } else {
10905 currentRef.current = null;
10906 }
10907 }
10908} // User-originating errors (lifecycles and refs) should not interrupt
10909// deletion, so don't let them throw. Host-originating errors should
10910// interrupt deletion, so it's okay
10911
10912
10913function commitUnmount(finishedRoot, current, renderPriorityLevel) {
10914 onCommitUnmount(current);
10915
10916 switch (current.tag) {
10917 case FunctionComponent:
10918 case ForwardRef:
10919 case MemoComponent:
10920 case SimpleMemoComponent:
10921 case Block:
10922 {
10923 var updateQueue = current.updateQueue;
10924
10925 if (updateQueue !== null) {
10926 var lastEffect = updateQueue.lastEffect;
10927
10928 if (lastEffect !== null) {
10929 var firstEffect = lastEffect.next;
10930
10931 {
10932 // When the owner fiber is deleted, the destroy function of a passive
10933 // effect hook is called during the synchronous commit phase. This is
10934 // a concession to implementation complexity. Calling it in the
10935 // passive effect phase (like they usually are, when dependencies
10936 // change during an update) would require either traversing the
10937 // children of the deleted fiber again, or including unmount effects
10938 // as part of the fiber effect list.
10939 //
10940 // Because this is during the sync commit phase, we need to change
10941 // the priority.
10942 //
10943 // TODO: Reconsider this implementation trade off.
10944 var priorityLevel = renderPriorityLevel > NormalPriority ? NormalPriority : renderPriorityLevel;
10945 runWithPriority(priorityLevel, function () {
10946 var effect = firstEffect;
10947
10948 do {
10949 var _destroy = effect.destroy;
10950
10951 if (_destroy !== undefined) {
10952 safelyCallDestroy(current, _destroy);
10953 }
10954
10955 effect = effect.next;
10956 } while (effect !== firstEffect);
10957 });
10958 }
10959 }
10960 }
10961
10962 return;
10963 }
10964
10965 case ClassComponent:
10966 {
10967 safelyDetachRef(current);
10968 var instance = current.stateNode;
10969
10970 if (typeof instance.componentWillUnmount === 'function') {
10971 safelyCallComponentWillUnmount(current, instance);
10972 }
10973
10974 return;
10975 }
10976
10977 case HostComponent:
10978 {
10979
10980 safelyDetachRef(current);
10981 return;
10982 }
10983
10984 case HostPortal:
10985 {
10986 // TODO: this is recursive.
10987 // We are also not using this parent because
10988 // the portal will get pushed immediately.
10989 {
10990 unmountHostComponents(finishedRoot, current, renderPriorityLevel);
10991 }
10992
10993 return;
10994 }
10995
10996 case FundamentalComponent:
10997 {
10998
10999 return;
11000 }
11001
11002 case DehydratedFragment:
11003 {
11004
11005 return;
11006 }
11007
11008 case ScopeComponent:
11009 {
11010
11011 return;
11012 }
11013 }
11014}
11015
11016function commitNestedUnmounts(finishedRoot, root, renderPriorityLevel) {
11017 // While we're inside a removed host node we don't want to call
11018 // removeChild on the inner nodes because they're removed by the top
11019 // call anyway. We also want to call componentWillUnmount on all
11020 // composites before this host node is removed from the tree. Therefore
11021 // we do an inner loop while we're still inside the host node.
11022 var node = root;
11023
11024 while (true) {
11025 commitUnmount(finishedRoot, node, renderPriorityLevel); // Visit children because they may contain more composite or host nodes.
11026 // Skip portals because commitUnmount() currently visits them recursively.
11027
11028 if (node.child !== null && ( // If we use mutation we drill down into portals using commitUnmount above.
11029 // If we don't use mutation we drill down into portals here instead.
11030 node.tag !== HostPortal)) {
11031 node.child.return = node;
11032 node = node.child;
11033 continue;
11034 }
11035
11036 if (node === root) {
11037 return;
11038 }
11039
11040 while (node.sibling === null) {
11041 if (node.return === null || node.return === root) {
11042 return;
11043 }
11044
11045 node = node.return;
11046 }
11047
11048 node.sibling.return = node.return;
11049 node = node.sibling;
11050 }
11051}
11052
11053function detachFiber(current) {
11054 var alternate = current.alternate; // Cut off the return pointers to disconnect it from the tree. Ideally, we
11055 // should clear the child pointer of the parent alternate to let this
11056 // get GC:ed but we don't know which for sure which parent is the current
11057 // one so we'll settle for GC:ing the subtree of this child. This child
11058 // itself will be GC:ed when the parent updates the next time.
11059
11060 current.return = null;
11061 current.child = null;
11062 current.memoizedState = null;
11063 current.updateQueue = null;
11064 current.dependencies = null;
11065 current.alternate = null;
11066 current.firstEffect = null;
11067 current.lastEffect = null;
11068 current.pendingProps = null;
11069 current.memoizedProps = null;
11070 current.stateNode = null;
11071
11072 if (alternate !== null) {
11073 detachFiber(alternate);
11074 }
11075}
11076
11077function getHostParentFiber(fiber) {
11078 var parent = fiber.return;
11079
11080 while (parent !== null) {
11081 if (isHostParent(parent)) {
11082 return parent;
11083 }
11084
11085 parent = parent.return;
11086 }
11087
11088 {
11089 {
11090 throw Error( "Expected to find a host parent. This error is likely caused by a bug in React. Please file an issue." );
11091 }
11092 }
11093}
11094
11095function isHostParent(fiber) {
11096 return fiber.tag === HostComponent || fiber.tag === HostRoot || fiber.tag === HostPortal;
11097}
11098
11099function getHostSibling(fiber) {
11100 // We're going to search forward into the tree until we find a sibling host
11101 // node. Unfortunately, if multiple insertions are done in a row we have to
11102 // search past them. This leads to exponential search for the next sibling.
11103 // TODO: Find a more efficient way to do this.
11104 var node = fiber;
11105
11106 siblings: while (true) {
11107 // If we didn't find anything, let's try the next sibling.
11108 while (node.sibling === null) {
11109 if (node.return === null || isHostParent(node.return)) {
11110 // If we pop out of the root or hit the parent the fiber we are the
11111 // last sibling.
11112 return null;
11113 }
11114
11115 node = node.return;
11116 }
11117
11118 node.sibling.return = node.return;
11119 node = node.sibling;
11120
11121 while (node.tag !== HostComponent && node.tag !== HostText && node.tag !== DehydratedFragment) {
11122 // If it is not host node and, we might have a host node inside it.
11123 // Try to search down until we find one.
11124 if (node.effectTag & Placement) {
11125 // If we don't have a child, try the siblings instead.
11126 continue siblings;
11127 } // If we don't have a child, try the siblings instead.
11128 // We also skip portals because they are not part of this host tree.
11129
11130
11131 if (node.child === null || node.tag === HostPortal) {
11132 continue siblings;
11133 } else {
11134 node.child.return = node;
11135 node = node.child;
11136 }
11137 } // Check if this host node is stable or about to be placed.
11138
11139
11140 if (!(node.effectTag & Placement)) {
11141 // Found it!
11142 return node.stateNode;
11143 }
11144 }
11145}
11146
11147function commitPlacement(finishedWork) {
11148
11149
11150 var parentFiber = getHostParentFiber(finishedWork); // Note: these two variables *must* always be updated together.
11151
11152 var parent;
11153 var isContainer;
11154 var parentStateNode = parentFiber.stateNode;
11155
11156 switch (parentFiber.tag) {
11157 case HostComponent:
11158 parent = parentStateNode;
11159 isContainer = false;
11160 break;
11161
11162 case HostRoot:
11163 parent = parentStateNode.containerInfo;
11164 isContainer = true;
11165 break;
11166
11167 case HostPortal:
11168 parent = parentStateNode.containerInfo;
11169 isContainer = true;
11170 break;
11171
11172 case FundamentalComponent:
11173
11174 // eslint-disable-next-line-no-fallthrough
11175
11176 default:
11177 {
11178 {
11179 throw Error( "Invalid host parent fiber. This error is likely caused by a bug in React. Please file an issue." );
11180 }
11181 }
11182
11183 }
11184
11185 if (parentFiber.effectTag & ContentReset) {
11186
11187 parentFiber.effectTag &= ~ContentReset;
11188 }
11189
11190 var before = getHostSibling(finishedWork); // We only have the top Fiber that was inserted but we need to recurse down its
11191 // children to find all the terminal nodes.
11192
11193 if (isContainer) {
11194 insertOrAppendPlacementNodeIntoContainer(finishedWork, before, parent);
11195 } else {
11196 insertOrAppendPlacementNode(finishedWork, before, parent);
11197 }
11198}
11199
11200function insertOrAppendPlacementNodeIntoContainer(node, before, parent) {
11201 var tag = node.tag;
11202 var isHost = tag === HostComponent || tag === HostText;
11203
11204 if (isHost || enableFundamentalAPI ) {
11205 var stateNode = isHost ? node.stateNode : node.stateNode.instance;
11206
11207 if (before) {
11208 insertInContainerBefore(parent, stateNode, before);
11209 } else {
11210 appendChildToContainer(parent, stateNode);
11211 }
11212 } else if (tag === HostPortal) ; else {
11213 var child = node.child;
11214
11215 if (child !== null) {
11216 insertOrAppendPlacementNodeIntoContainer(child, before, parent);
11217 var sibling = child.sibling;
11218
11219 while (sibling !== null) {
11220 insertOrAppendPlacementNodeIntoContainer(sibling, before, parent);
11221 sibling = sibling.sibling;
11222 }
11223 }
11224 }
11225}
11226
11227function insertOrAppendPlacementNode(node, before, parent) {
11228 var tag = node.tag;
11229 var isHost = tag === HostComponent || tag === HostText;
11230
11231 if (isHost || enableFundamentalAPI ) {
11232 var stateNode = isHost ? node.stateNode : node.stateNode.instance;
11233
11234 if (before) {
11235 insertBefore(parent, stateNode, before);
11236 } else {
11237 appendChild(parent, stateNode);
11238 }
11239 } else if (tag === HostPortal) ; else {
11240 var child = node.child;
11241
11242 if (child !== null) {
11243 insertOrAppendPlacementNode(child, before, parent);
11244 var sibling = child.sibling;
11245
11246 while (sibling !== null) {
11247 insertOrAppendPlacementNode(sibling, before, parent);
11248 sibling = sibling.sibling;
11249 }
11250 }
11251 }
11252}
11253
11254function unmountHostComponents(finishedRoot, current, renderPriorityLevel) {
11255 // We only have the top Fiber that was deleted but we need to recurse down its
11256 // children to find all the terminal nodes.
11257 var node = current; // Each iteration, currentParent is populated with node's host parent if not
11258 // currentParentIsValid.
11259
11260 var currentParentIsValid = false; // Note: these two variables *must* always be updated together.
11261
11262 var currentParent;
11263 var currentParentIsContainer;
11264
11265 while (true) {
11266 if (!currentParentIsValid) {
11267 var parent = node.return;
11268
11269 findParent: while (true) {
11270 if (!(parent !== null)) {
11271 {
11272 throw Error( "Expected to find a host parent. This error is likely caused by a bug in React. Please file an issue." );
11273 }
11274 }
11275
11276 var parentStateNode = parent.stateNode;
11277
11278 switch (parent.tag) {
11279 case HostComponent:
11280 currentParent = parentStateNode;
11281 currentParentIsContainer = false;
11282 break findParent;
11283
11284 case HostRoot:
11285 currentParent = parentStateNode.containerInfo;
11286 currentParentIsContainer = true;
11287 break findParent;
11288
11289 case HostPortal:
11290 currentParent = parentStateNode.containerInfo;
11291 currentParentIsContainer = true;
11292 break findParent;
11293
11294 }
11295
11296 parent = parent.return;
11297 }
11298
11299 currentParentIsValid = true;
11300 }
11301
11302 if (node.tag === HostComponent || node.tag === HostText) {
11303 commitNestedUnmounts(finishedRoot, node, renderPriorityLevel); // After all the children have unmounted, it is now safe to remove the
11304 // node from the tree.
11305
11306 if (currentParentIsContainer) {
11307 removeChildFromContainer(currentParent, node.stateNode);
11308 } else {
11309 removeChild(currentParent, node.stateNode);
11310 } // Don't visit children because we already visited them.
11311
11312 } else if (node.tag === HostPortal) {
11313 if (node.child !== null) {
11314 // When we go into a portal, it becomes the parent to remove from.
11315 // We will reassign it back when we pop the portal on the way up.
11316 currentParent = node.stateNode.containerInfo;
11317 currentParentIsContainer = true; // Visit children because portals might contain host components.
11318
11319 node.child.return = node;
11320 node = node.child;
11321 continue;
11322 }
11323 } else {
11324 commitUnmount(finishedRoot, node, renderPriorityLevel); // Visit children because we may find more host components below.
11325
11326 if (node.child !== null) {
11327 node.child.return = node;
11328 node = node.child;
11329 continue;
11330 }
11331 }
11332
11333 if (node === current) {
11334 return;
11335 }
11336
11337 while (node.sibling === null) {
11338 if (node.return === null || node.return === current) {
11339 return;
11340 }
11341
11342 node = node.return;
11343
11344 if (node.tag === HostPortal) {
11345 // When we go out of the portal, we need to restore the parent.
11346 // Since we don't keep a stack of them, we will search for it.
11347 currentParentIsValid = false;
11348 }
11349 }
11350
11351 node.sibling.return = node.return;
11352 node = node.sibling;
11353 }
11354}
11355
11356function commitDeletion(finishedRoot, current, renderPriorityLevel) {
11357 {
11358 // Recursively delete all host nodes from the parent.
11359 // Detach refs and call componentWillUnmount() on the whole subtree.
11360 unmountHostComponents(finishedRoot, current, renderPriorityLevel);
11361 }
11362
11363 detachFiber(current);
11364}
11365
11366function commitWork(current, finishedWork) {
11367
11368 switch (finishedWork.tag) {
11369 case FunctionComponent:
11370 case ForwardRef:
11371 case MemoComponent:
11372 case SimpleMemoComponent:
11373 case Block:
11374 {
11375 // Layout effects are destroyed during the mutation phase so that all
11376 // destroy functions for all fibers are called before any create functions.
11377 // This prevents sibling component effects from interfering with each other,
11378 // e.g. a destroy function in one component should never override a ref set
11379 // by a create function in another component during the same commit.
11380 commitHookEffectListUnmount(Layout | HasEffect, finishedWork);
11381 return;
11382 }
11383
11384 case ClassComponent:
11385 {
11386 return;
11387 }
11388
11389 case HostComponent:
11390 {
11391 var instance = finishedWork.stateNode;
11392
11393 if (instance != null) {
11394 // Commit the work prepared earlier.
11395 var newProps = finishedWork.memoizedProps; // For hydration we reuse the update path but we treat the oldProps
11396 // as the newProps. The updatePayload will contain the real change in
11397 // this case.
11398
11399 var oldProps = current !== null ? current.memoizedProps : newProps;
11400 var type = finishedWork.type; // TODO: Type the updateQueue to be specific to host components.
11401
11402 var updatePayload = finishedWork.updateQueue;
11403 finishedWork.updateQueue = null;
11404
11405 if (updatePayload !== null) {
11406 commitUpdate(instance, updatePayload, type, oldProps, newProps);
11407 }
11408 }
11409
11410 return;
11411 }
11412
11413 case HostText:
11414 {
11415 if (!(finishedWork.stateNode !== null)) {
11416 {
11417 throw Error( "This should have a text node initialized. This error is likely caused by a bug in React. Please file an issue." );
11418 }
11419 }
11420
11421 var textInstance = finishedWork.stateNode;
11422 var newText = finishedWork.memoizedProps; // For hydration we reuse the update path but we treat the oldProps
11423 // as the newProps. The updatePayload will contain the real change in
11424 // this case.
11425
11426 var oldText = current !== null ? current.memoizedProps : newText;
11427 return;
11428 }
11429
11430 case HostRoot:
11431 {
11432
11433 return;
11434 }
11435
11436 case Profiler:
11437 {
11438 return;
11439 }
11440
11441 case SuspenseComponent:
11442 {
11443 commitSuspenseComponent(finishedWork);
11444 attachSuspenseRetryListeners(finishedWork);
11445 return;
11446 }
11447
11448 case SuspenseListComponent:
11449 {
11450 attachSuspenseRetryListeners(finishedWork);
11451 return;
11452 }
11453
11454 case IncompleteClassComponent:
11455 {
11456 return;
11457 }
11458 }
11459
11460 {
11461 {
11462 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." );
11463 }
11464 }
11465}
11466
11467function commitSuspenseComponent(finishedWork) {
11468 var newState = finishedWork.memoizedState;
11469 var newDidTimeout;
11470 var primaryChildParent = finishedWork;
11471
11472 if (newState === null) {
11473 newDidTimeout = false;
11474 } else {
11475 newDidTimeout = true;
11476 primaryChildParent = finishedWork.child;
11477 markCommitTimeOfFallback();
11478 }
11479
11480 if ( primaryChildParent !== null) {
11481 hideOrUnhideAllChildren(primaryChildParent, newDidTimeout);
11482 }
11483}
11484
11485function attachSuspenseRetryListeners(finishedWork) {
11486 // If this boundary just timed out, then it will have a set of thenables.
11487 // For each thenable, attach a listener so that when it resolves, React
11488 // attempts to re-render the boundary in the primary (pre-timeout) state.
11489 var thenables = finishedWork.updateQueue;
11490
11491 if (thenables !== null) {
11492 finishedWork.updateQueue = null;
11493 var retryCache = finishedWork.stateNode;
11494
11495 if (retryCache === null) {
11496 retryCache = finishedWork.stateNode = new PossiblyWeakSet();
11497 }
11498
11499 thenables.forEach(function (thenable) {
11500 // Memoize using the boundary fiber to prevent redundant listeners.
11501 var retry = resolveRetryThenable.bind(null, finishedWork, thenable);
11502
11503 if (!retryCache.has(thenable)) {
11504 {
11505 if (thenable.__reactDoNotTraceInteractions !== true) {
11506 retry = tracing.unstable_wrap(retry);
11507 }
11508 }
11509
11510 retryCache.add(thenable);
11511 thenable.then(retry, retry);
11512 }
11513 });
11514 }
11515}
11516
11517function commitResetTextContent(current) {
11518
11519 resetTextContent(current.stateNode);
11520}
11521
11522var PossiblyWeakMap = typeof WeakMap === 'function' ? WeakMap : Map;
11523
11524function createRootErrorUpdate(fiber, errorInfo, expirationTime) {
11525 var update = createUpdate(expirationTime, null); // Unmount the root by rendering null.
11526
11527 update.tag = CaptureUpdate; // Caution: React DevTools currently depends on this property
11528 // being called "element".
11529
11530 update.payload = {
11531 element: null
11532 };
11533 var error = errorInfo.value;
11534
11535 update.callback = function () {
11536 onUncaughtError(error);
11537 logError(fiber, errorInfo);
11538 };
11539
11540 return update;
11541}
11542
11543function createClassErrorUpdate(fiber, errorInfo, expirationTime) {
11544 var update = createUpdate(expirationTime, null);
11545 update.tag = CaptureUpdate;
11546 var getDerivedStateFromError = fiber.type.getDerivedStateFromError;
11547
11548 if (typeof getDerivedStateFromError === 'function') {
11549 var error$1 = errorInfo.value;
11550
11551 update.payload = function () {
11552 logError(fiber, errorInfo);
11553 return getDerivedStateFromError(error$1);
11554 };
11555 }
11556
11557 var inst = fiber.stateNode;
11558
11559 if (inst !== null && typeof inst.componentDidCatch === 'function') {
11560 update.callback = function callback() {
11561 {
11562 markFailedErrorBoundaryForHotReloading(fiber);
11563 }
11564
11565 if (typeof getDerivedStateFromError !== 'function') {
11566 // To preserve the preexisting retry behavior of error boundaries,
11567 // we keep track of which ones already failed during this batch.
11568 // This gets reset before we yield back to the browser.
11569 // TODO: Warn in strict mode if getDerivedStateFromError is
11570 // not defined.
11571 markLegacyErrorBoundaryAsFailed(this); // Only log here if componentDidCatch is the only error boundary method defined
11572
11573 logError(fiber, errorInfo);
11574 }
11575
11576 var error$1 = errorInfo.value;
11577 var stack = errorInfo.stack;
11578 this.componentDidCatch(error$1, {
11579 componentStack: stack !== null ? stack : ''
11580 });
11581
11582 {
11583 if (typeof getDerivedStateFromError !== 'function') {
11584 // If componentDidCatch is the only error boundary method defined,
11585 // then it needs to call setState to recover from errors.
11586 // If no state update is scheduled then the boundary will swallow the error.
11587 if (fiber.expirationTime !== Sync) {
11588 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');
11589 }
11590 }
11591 }
11592 };
11593 } else {
11594 update.callback = function () {
11595 markFailedErrorBoundaryForHotReloading(fiber);
11596 };
11597 }
11598
11599 return update;
11600}
11601
11602function attachPingListener(root, renderExpirationTime, thenable) {
11603 // Attach a listener to the promise to "ping" the root and retry. But
11604 // only if one does not already exist for the current render expiration
11605 // time (which acts like a "thread ID" here).
11606 var pingCache = root.pingCache;
11607 var threadIDs;
11608
11609 if (pingCache === null) {
11610 pingCache = root.pingCache = new PossiblyWeakMap();
11611 threadIDs = new Set();
11612 pingCache.set(thenable, threadIDs);
11613 } else {
11614 threadIDs = pingCache.get(thenable);
11615
11616 if (threadIDs === undefined) {
11617 threadIDs = new Set();
11618 pingCache.set(thenable, threadIDs);
11619 }
11620 }
11621
11622 if (!threadIDs.has(renderExpirationTime)) {
11623 // Memoize using the thread ID to prevent redundant listeners.
11624 threadIDs.add(renderExpirationTime);
11625 var ping = pingSuspendedRoot.bind(null, root, thenable, renderExpirationTime);
11626 thenable.then(ping, ping);
11627 }
11628}
11629
11630function throwException(root, returnFiber, sourceFiber, value, renderExpirationTime) {
11631 // The source fiber did not complete.
11632 sourceFiber.effectTag |= Incomplete; // Its effect list is no longer valid.
11633
11634 sourceFiber.firstEffect = sourceFiber.lastEffect = null;
11635
11636 if (value !== null && typeof value === 'object' && typeof value.then === 'function') {
11637 // This is a thenable.
11638 var thenable = value;
11639
11640 if ((sourceFiber.mode & BlockingMode) === NoMode) {
11641 // Reset the memoizedState to what it was before we attempted
11642 // to render it.
11643 var currentSource = sourceFiber.alternate;
11644
11645 if (currentSource) {
11646 sourceFiber.updateQueue = currentSource.updateQueue;
11647 sourceFiber.memoizedState = currentSource.memoizedState;
11648 sourceFiber.expirationTime = currentSource.expirationTime;
11649 } else {
11650 sourceFiber.updateQueue = null;
11651 sourceFiber.memoizedState = null;
11652 }
11653 }
11654
11655 var hasInvisibleParentBoundary = hasSuspenseContext(suspenseStackCursor.current, InvisibleParentSuspenseContext); // Schedule the nearest Suspense to re-render the timed out view.
11656
11657 var _workInProgress = returnFiber;
11658
11659 do {
11660 if (_workInProgress.tag === SuspenseComponent && shouldCaptureSuspense(_workInProgress, hasInvisibleParentBoundary)) {
11661 // Found the nearest boundary.
11662 // Stash the promise on the boundary fiber. If the boundary times out, we'll
11663 // attach another listener to flip the boundary back to its normal state.
11664 var thenables = _workInProgress.updateQueue;
11665
11666 if (thenables === null) {
11667 var updateQueue = new Set();
11668 updateQueue.add(thenable);
11669 _workInProgress.updateQueue = updateQueue;
11670 } else {
11671 thenables.add(thenable);
11672 } // If the boundary is outside of blocking mode, we should *not*
11673 // suspend the commit. Pretend as if the suspended component rendered
11674 // null and keep rendering. In the commit phase, we'll schedule a
11675 // subsequent synchronous update to re-render the Suspense.
11676 //
11677 // Note: It doesn't matter whether the component that suspended was
11678 // inside a blocking mode tree. If the Suspense is outside of it, we
11679 // should *not* suspend the commit.
11680
11681
11682 if ((_workInProgress.mode & BlockingMode) === NoMode) {
11683 _workInProgress.effectTag |= DidCapture; // We're going to commit this fiber even though it didn't complete.
11684 // But we shouldn't call any lifecycle methods or callbacks. Remove
11685 // all lifecycle effect tags.
11686
11687 sourceFiber.effectTag &= ~(LifecycleEffectMask | Incomplete);
11688
11689 if (sourceFiber.tag === ClassComponent) {
11690 var currentSourceFiber = sourceFiber.alternate;
11691
11692 if (currentSourceFiber === null) {
11693 // This is a new mount. Change the tag so it's not mistaken for a
11694 // completed class component. For example, we should not call
11695 // componentWillUnmount if it is deleted.
11696 sourceFiber.tag = IncompleteClassComponent;
11697 } else {
11698 // When we try rendering again, we should not reuse the current fiber,
11699 // since it's known to be in an inconsistent state. Use a force update to
11700 // prevent a bail out.
11701 var update = createUpdate(Sync, null);
11702 update.tag = ForceUpdate;
11703 enqueueUpdate(sourceFiber, update);
11704 }
11705 } // The source fiber did not complete. Mark it with Sync priority to
11706 // indicate that it still has pending work.
11707
11708
11709 sourceFiber.expirationTime = Sync; // Exit without suspending.
11710
11711 return;
11712 } // Confirmed that the boundary is in a concurrent mode tree. Continue
11713 // with the normal suspend path.
11714 //
11715 // After this we'll use a set of heuristics to determine whether this
11716 // render pass will run to completion or restart or "suspend" the commit.
11717 // The actual logic for this is spread out in different places.
11718 //
11719 // This first principle is that if we're going to suspend when we complete
11720 // a root, then we should also restart if we get an update or ping that
11721 // might unsuspend it, and vice versa. The only reason to suspend is
11722 // because you think you might want to restart before committing. However,
11723 // it doesn't make sense to restart only while in the period we're suspended.
11724 //
11725 // Restarting too aggressively is also not good because it starves out any
11726 // intermediate loading state. So we use heuristics to determine when.
11727 // Suspense Heuristics
11728 //
11729 // If nothing threw a Promise or all the same fallbacks are already showing,
11730 // then don't suspend/restart.
11731 //
11732 // If this is an initial render of a new tree of Suspense boundaries and
11733 // those trigger a fallback, then don't suspend/restart. We want to ensure
11734 // that we can show the initial loading state as quickly as possible.
11735 //
11736 // If we hit a "Delayed" case, such as when we'd switch from content back into
11737 // a fallback, then we should always suspend/restart. SuspenseConfig applies to
11738 // this case. If none is defined, JND is used instead.
11739 //
11740 // If we're already showing a fallback and it gets "retried", allowing us to show
11741 // another level, but there's still an inner boundary that would show a fallback,
11742 // then we suspend/restart for 500ms since the last time we showed a fallback
11743 // anywhere in the tree. This effectively throttles progressive loading into a
11744 // consistent train of commits. This also gives us an opportunity to restart to
11745 // get to the completed state slightly earlier.
11746 //
11747 // If there's ambiguity due to batching it's resolved in preference of:
11748 // 1) "delayed", 2) "initial render", 3) "retry".
11749 //
11750 // We want to ensure that a "busy" state doesn't get force committed. We want to
11751 // ensure that new initial loading states can commit as soon as possible.
11752
11753
11754 attachPingListener(root, renderExpirationTime, thenable);
11755 _workInProgress.effectTag |= ShouldCapture;
11756 _workInProgress.expirationTime = renderExpirationTime;
11757 return;
11758 } // This boundary already captured during this render. Continue to the next
11759 // boundary.
11760
11761
11762 _workInProgress = _workInProgress.return;
11763 } while (_workInProgress !== null); // No boundary was found. Fallthrough to error mode.
11764 // TODO: Use invariant so the message is stripped in prod?
11765
11766
11767 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));
11768 } // We didn't find a boundary that could handle this type of exception. Start
11769 // over and traverse parent path again, this time treating the exception
11770 // as an error.
11771
11772
11773 renderDidError();
11774 value = createCapturedValue(value, sourceFiber);
11775 var workInProgress = returnFiber;
11776
11777 do {
11778 switch (workInProgress.tag) {
11779 case HostRoot:
11780 {
11781 var _errorInfo = value;
11782 workInProgress.effectTag |= ShouldCapture;
11783 workInProgress.expirationTime = renderExpirationTime;
11784
11785 var _update = createRootErrorUpdate(workInProgress, _errorInfo, renderExpirationTime);
11786
11787 enqueueCapturedUpdate(workInProgress, _update);
11788 return;
11789 }
11790
11791 case ClassComponent:
11792 // Capture and retry
11793 var errorInfo = value;
11794 var ctor = workInProgress.type;
11795 var instance = workInProgress.stateNode;
11796
11797 if ((workInProgress.effectTag & DidCapture) === NoEffect && (typeof ctor.getDerivedStateFromError === 'function' || instance !== null && typeof instance.componentDidCatch === 'function' && !isAlreadyFailedLegacyErrorBoundary(instance))) {
11798 workInProgress.effectTag |= ShouldCapture;
11799 workInProgress.expirationTime = renderExpirationTime; // Schedule the error boundary to re-render using updated state
11800
11801 var _update2 = createClassErrorUpdate(workInProgress, errorInfo, renderExpirationTime);
11802
11803 enqueueCapturedUpdate(workInProgress, _update2);
11804 return;
11805 }
11806
11807 break;
11808 }
11809
11810 workInProgress = workInProgress.return;
11811 } while (workInProgress !== null);
11812}
11813
11814var ceil = Math.ceil;
11815var ReactCurrentDispatcher$1 = ReactSharedInternals.ReactCurrentDispatcher,
11816 ReactCurrentOwner$2 = ReactSharedInternals.ReactCurrentOwner,
11817 IsSomeRendererActing = ReactSharedInternals.IsSomeRendererActing;
11818var NoContext =
11819/* */
118200;
11821var BatchedContext =
11822/* */
118231;
11824var DiscreteEventContext =
11825/* */
118264;
11827var LegacyUnbatchedContext =
11828/* */
118298;
11830var RenderContext =
11831/* */
1183216;
11833var CommitContext =
11834/* */
1183532;
11836var RootIncomplete = 0;
11837var RootFatalErrored = 1;
11838var RootErrored = 2;
11839var RootSuspended = 3;
11840var RootSuspendedWithDelay = 4;
11841var RootCompleted = 5;
11842// Describes where we are in the React execution stack
11843var executionContext = NoContext; // The root we're working on
11844
11845var workInProgressRoot = null; // The fiber we're working on
11846
11847var workInProgress = null; // The expiration time we're rendering
11848
11849var renderExpirationTime$1 = NoWork; // Whether to root completed, errored, suspended, etc.
11850
11851var workInProgressRootExitStatus = RootIncomplete; // A fatal error, if one is thrown
11852
11853var workInProgressRootFatalError = null; // Most recent event time among processed updates during this render.
11854// This is conceptually a time stamp but expressed in terms of an ExpirationTime
11855// because we deal mostly with expiration times in the hot path, so this avoids
11856// the conversion happening in the hot path.
11857
11858var workInProgressRootLatestProcessedExpirationTime = Sync;
11859var workInProgressRootLatestSuspenseTimeout = Sync;
11860var workInProgressRootCanSuspendUsingConfig = null; // The work left over by components that were visited during this render. Only
11861// includes unprocessed updates, not work in bailed out children.
11862
11863var workInProgressRootNextUnprocessedUpdateTime = NoWork; // If we're pinged while rendering we don't always restart immediately.
11864// This flag determines if it might be worthwhile to restart if an opportunity
11865// happens latere.
11866
11867var workInProgressRootHasPendingPing = false; // The most recent time we committed a fallback. This lets us ensure a train
11868// model where we don't commit new loading states in too quick succession.
11869
11870var globalMostRecentFallbackTime = 0;
11871var FALLBACK_THROTTLE_MS = 500;
11872var nextEffect = null;
11873var hasUncaughtError = false;
11874var firstUncaughtError = null;
11875var legacyErrorBoundariesThatAlreadyFailed = null;
11876var rootDoesHavePassiveEffects = false;
11877var rootWithPendingPassiveEffects = null;
11878var pendingPassiveEffectsRenderPriority = NoPriority;
11879var pendingPassiveEffectsExpirationTime = NoWork;
11880var rootsWithPendingDiscreteUpdates = null; // Use these to prevent an infinite loop of nested updates
11881
11882var NESTED_UPDATE_LIMIT = 50;
11883var nestedUpdateCount = 0;
11884var rootWithNestedUpdates = null;
11885var NESTED_PASSIVE_UPDATE_LIMIT = 50;
11886var nestedPassiveUpdateCount = 0;
11887var interruptedBy = null; // Marks the need to reschedule pending interactions at these expiration times
11888// during the commit phase. This enables them to be traced across components
11889// that spawn new work during render. E.g. hidden boundaries, suspended SSR
11890// hydration or SuspenseList.
11891
11892var spawnedWorkDuringRender = null; // Expiration times are computed by adding to the current time (the start
11893// time). However, if two updates are scheduled within the same event, we
11894// should treat their start times as simultaneous, even if the actual clock
11895// time has advanced between the first and second call.
11896// In other words, because expiration times determine how updates are batched,
11897// we want all updates of like priority that occur within the same event to
11898// receive the same expiration time. Otherwise we get tearing.
11899
11900var currentEventTime = NoWork;
11901function requestCurrentTimeForUpdate() {
11902 if ((executionContext & (RenderContext | CommitContext)) !== NoContext) {
11903 // We're inside React, so it's fine to read the actual time.
11904 return msToExpirationTime(now());
11905 } // We're not inside React, so we may be in the middle of a browser event.
11906
11907
11908 if (currentEventTime !== NoWork) {
11909 // Use the same start time for all updates until we enter React again.
11910 return currentEventTime;
11911 } // This is the first update since React yielded. Compute a new start time.
11912
11913
11914 currentEventTime = msToExpirationTime(now());
11915 return currentEventTime;
11916}
11917function getCurrentTime() {
11918 return msToExpirationTime(now());
11919}
11920function computeExpirationForFiber(currentTime, fiber, suspenseConfig) {
11921 var mode = fiber.mode;
11922
11923 if ((mode & BlockingMode) === NoMode) {
11924 return Sync;
11925 }
11926
11927 var priorityLevel = getCurrentPriorityLevel();
11928
11929 if ((mode & ConcurrentMode) === NoMode) {
11930 return priorityLevel === ImmediatePriority ? Sync : Batched;
11931 }
11932
11933 if ((executionContext & RenderContext) !== NoContext) {
11934 // Use whatever time we're already rendering
11935 // TODO: Should there be a way to opt out, like with `runWithPriority`?
11936 return renderExpirationTime$1;
11937 }
11938
11939 var expirationTime;
11940
11941 if (suspenseConfig !== null) {
11942 // Compute an expiration time based on the Suspense timeout.
11943 expirationTime = computeSuspenseExpiration(currentTime, suspenseConfig.timeoutMs | 0 || LOW_PRIORITY_EXPIRATION);
11944 } else {
11945 // Compute an expiration time based on the Scheduler priority.
11946 switch (priorityLevel) {
11947 case ImmediatePriority:
11948 expirationTime = Sync;
11949 break;
11950
11951 case UserBlockingPriority:
11952 // TODO: Rename this to computeUserBlockingExpiration
11953 expirationTime = computeInteractiveExpiration(currentTime);
11954 break;
11955
11956 case NormalPriority:
11957 case LowPriority:
11958 // TODO: Handle LowPriority
11959 // TODO: Rename this to... something better.
11960 expirationTime = computeAsyncExpiration(currentTime);
11961 break;
11962
11963 case IdlePriority:
11964 expirationTime = Idle;
11965 break;
11966
11967 default:
11968 {
11969 {
11970 throw Error( "Expected a valid priority level" );
11971 }
11972 }
11973
11974 }
11975 } // If we're in the middle of rendering a tree, do not update at the same
11976 // expiration time that is already rendering.
11977 // TODO: We shouldn't have to do this if the update is on a different root.
11978 // Refactor computeExpirationForFiber + scheduleUpdate so we have access to
11979 // the root when we check for this condition.
11980
11981
11982 if (workInProgressRoot !== null && expirationTime === renderExpirationTime$1) {
11983 // This is a trick to move this update into a separate batch
11984 expirationTime -= 1;
11985 }
11986
11987 return expirationTime;
11988}
11989function scheduleUpdateOnFiber(fiber, expirationTime) {
11990 checkForNestedUpdates();
11991 warnAboutRenderPhaseUpdatesInDEV(fiber);
11992 var root = markUpdateTimeFromFiberToRoot(fiber, expirationTime);
11993
11994 if (root === null) {
11995 warnAboutUpdateOnUnmountedFiberInDEV(fiber);
11996 return;
11997 }
11998
11999 checkForInterruption(fiber, expirationTime);
12000 recordScheduleUpdate(); // TODO: computeExpirationForFiber also reads the priority. Pass the
12001 // priority as an argument to that function and this one.
12002
12003 var priorityLevel = getCurrentPriorityLevel();
12004
12005 if (expirationTime === Sync) {
12006 if ( // Check if we're inside unbatchedUpdates
12007 (executionContext & LegacyUnbatchedContext) !== NoContext && // Check if we're not already rendering
12008 (executionContext & (RenderContext | CommitContext)) === NoContext) {
12009 // Register pending interactions on the root to avoid losing traced interaction data.
12010 schedulePendingInteractions(root, expirationTime); // This is a legacy edge case. The initial mount of a ReactDOM.render-ed
12011 // root inside of batchedUpdates should be synchronous, but layout updates
12012 // should be deferred until the end of the batch.
12013
12014 performSyncWorkOnRoot(root);
12015 } else {
12016 ensureRootIsScheduled(root);
12017 schedulePendingInteractions(root, expirationTime);
12018
12019 if (executionContext === NoContext) {
12020 // Flush the synchronous work now, unless we're already working or inside
12021 // a batch. This is intentionally inside scheduleUpdateOnFiber instead of
12022 // scheduleCallbackForFiber to preserve the ability to schedule a callback
12023 // without immediately flushing it. We only do this for user-initiated
12024 // updates, to preserve historical behavior of legacy mode.
12025 flushSyncCallbackQueue();
12026 }
12027 }
12028 } else {
12029 ensureRootIsScheduled(root);
12030 schedulePendingInteractions(root, expirationTime);
12031 }
12032
12033 if ((executionContext & DiscreteEventContext) !== NoContext && ( // Only updates at user-blocking priority or greater are considered
12034 // discrete, even inside a discrete event.
12035 priorityLevel === UserBlockingPriority || priorityLevel === ImmediatePriority)) {
12036 // This is the result of a discrete event. Track the lowest priority
12037 // discrete update per root so we can flush them early, if needed.
12038 if (rootsWithPendingDiscreteUpdates === null) {
12039 rootsWithPendingDiscreteUpdates = new Map([[root, expirationTime]]);
12040 } else {
12041 var lastDiscreteTime = rootsWithPendingDiscreteUpdates.get(root);
12042
12043 if (lastDiscreteTime === undefined || lastDiscreteTime > expirationTime) {
12044 rootsWithPendingDiscreteUpdates.set(root, expirationTime);
12045 }
12046 }
12047 }
12048}
12049var scheduleWork = scheduleUpdateOnFiber; // This is split into a separate function so we can mark a fiber with pending
12050// work without treating it as a typical update that originates from an event;
12051// e.g. retrying a Suspense boundary isn't an update, but it does schedule work
12052// on a fiber.
12053
12054function markUpdateTimeFromFiberToRoot(fiber, expirationTime) {
12055 // Update the source fiber's expiration time
12056 if (fiber.expirationTime < expirationTime) {
12057 fiber.expirationTime = expirationTime;
12058 }
12059
12060 var alternate = fiber.alternate;
12061
12062 if (alternate !== null && alternate.expirationTime < expirationTime) {
12063 alternate.expirationTime = expirationTime;
12064 } // Walk the parent path to the root and update the child expiration time.
12065
12066
12067 var node = fiber.return;
12068 var root = null;
12069
12070 if (node === null && fiber.tag === HostRoot) {
12071 root = fiber.stateNode;
12072 } else {
12073 while (node !== null) {
12074 alternate = node.alternate;
12075
12076 if (node.childExpirationTime < expirationTime) {
12077 node.childExpirationTime = expirationTime;
12078
12079 if (alternate !== null && alternate.childExpirationTime < expirationTime) {
12080 alternate.childExpirationTime = expirationTime;
12081 }
12082 } else if (alternate !== null && alternate.childExpirationTime < expirationTime) {
12083 alternate.childExpirationTime = expirationTime;
12084 }
12085
12086 if (node.return === null && node.tag === HostRoot) {
12087 root = node.stateNode;
12088 break;
12089 }
12090
12091 node = node.return;
12092 }
12093 }
12094
12095 if (root !== null) {
12096 if (workInProgressRoot === root) {
12097 // Received an update to a tree that's in the middle of rendering. Mark
12098 // that's unprocessed work on this root.
12099 markUnprocessedUpdateTime(expirationTime);
12100
12101 if (workInProgressRootExitStatus === RootSuspendedWithDelay) {
12102 // The root already suspended with a delay, which means this render
12103 // definitely won't finish. Since we have a new update, let's mark it as
12104 // suspended now, right before marking the incoming update. This has the
12105 // effect of interrupting the current render and switching to the update.
12106 // TODO: This happens to work when receiving an update during the render
12107 // phase, because of the trick inside computeExpirationForFiber to
12108 // subtract 1 from `renderExpirationTime` to move it into a
12109 // separate bucket. But we should probably model it with an exception,
12110 // using the same mechanism we use to force hydration of a subtree.
12111 // TODO: This does not account for low pri updates that were already
12112 // scheduled before the root started rendering. Need to track the next
12113 // pending expiration time (perhaps by backtracking the return path) and
12114 // then trigger a restart in the `renderDidSuspendDelayIfPossible` path.
12115 markRootSuspendedAtTime(root, renderExpirationTime$1);
12116 }
12117 } // Mark that the root has a pending update.
12118
12119
12120 markRootUpdatedAtTime(root, expirationTime);
12121 }
12122
12123 return root;
12124}
12125
12126function getNextRootExpirationTimeToWorkOn(root) {
12127 // Determines the next expiration time that the root should render, taking
12128 // into account levels that may be suspended, or levels that may have
12129 // received a ping.
12130 var lastExpiredTime = root.lastExpiredTime;
12131
12132 if (lastExpiredTime !== NoWork) {
12133 return lastExpiredTime;
12134 } // "Pending" refers to any update that hasn't committed yet, including if it
12135 // suspended. The "suspended" range is therefore a subset.
12136
12137
12138 var firstPendingTime = root.firstPendingTime;
12139
12140 if (!isRootSuspendedAtTime(root, firstPendingTime)) {
12141 // The highest priority pending time is not suspended. Let's work on that.
12142 return firstPendingTime;
12143 } // If the first pending time is suspended, check if there's a lower priority
12144 // pending level that we know about. Or check if we received a ping. Work
12145 // on whichever is higher priority.
12146
12147
12148 var lastPingedTime = root.lastPingedTime;
12149 var nextKnownPendingLevel = root.nextKnownPendingLevel;
12150 var nextLevel = lastPingedTime > nextKnownPendingLevel ? lastPingedTime : nextKnownPendingLevel;
12151
12152 if ( nextLevel <= Idle && firstPendingTime !== nextLevel) {
12153 // Don't work on Idle/Never priority unless everything else is committed.
12154 return NoWork;
12155 }
12156
12157 return nextLevel;
12158} // Use this function to schedule a task for a root. There's only one task per
12159// root; if a task was already scheduled, we'll check to make sure the
12160// expiration time of the existing task is the same as the expiration time of
12161// the next level that the root has work on. This function is called on every
12162// update, and right before exiting a task.
12163
12164
12165function ensureRootIsScheduled(root) {
12166 var lastExpiredTime = root.lastExpiredTime;
12167
12168 if (lastExpiredTime !== NoWork) {
12169 // Special case: Expired work should flush synchronously.
12170 root.callbackExpirationTime = Sync;
12171 root.callbackPriority = ImmediatePriority;
12172 root.callbackNode = scheduleSyncCallback(performSyncWorkOnRoot.bind(null, root));
12173 return;
12174 }
12175
12176 var expirationTime = getNextRootExpirationTimeToWorkOn(root);
12177 var existingCallbackNode = root.callbackNode;
12178
12179 if (expirationTime === NoWork) {
12180 // There's nothing to work on.
12181 if (existingCallbackNode !== null) {
12182 root.callbackNode = null;
12183 root.callbackExpirationTime = NoWork;
12184 root.callbackPriority = NoPriority;
12185 }
12186
12187 return;
12188 } // TODO: If this is an update, we already read the current time. Pass the
12189 // time as an argument.
12190
12191
12192 var currentTime = requestCurrentTimeForUpdate();
12193 var priorityLevel = inferPriorityFromExpirationTime(currentTime, expirationTime); // If there's an existing render task, confirm it has the correct priority and
12194 // expiration time. Otherwise, we'll cancel it and schedule a new one.
12195
12196 if (existingCallbackNode !== null) {
12197 var existingCallbackPriority = root.callbackPriority;
12198 var existingCallbackExpirationTime = root.callbackExpirationTime;
12199
12200 if ( // Callback must have the exact same expiration time.
12201 existingCallbackExpirationTime === expirationTime && // Callback must have greater or equal priority.
12202 existingCallbackPriority >= priorityLevel) {
12203 // Existing callback is sufficient.
12204 return;
12205 } // Need to schedule a new task.
12206 // TODO: Instead of scheduling a new task, we should be able to change the
12207 // priority of the existing one.
12208
12209
12210 cancelCallback(existingCallbackNode);
12211 }
12212
12213 root.callbackExpirationTime = expirationTime;
12214 root.callbackPriority = priorityLevel;
12215 var callbackNode;
12216
12217 if (expirationTime === Sync) {
12218 // Sync React callbacks are scheduled on a special internal queue
12219 callbackNode = scheduleSyncCallback(performSyncWorkOnRoot.bind(null, root));
12220 } else {
12221 callbackNode = scheduleCallback(priorityLevel, performConcurrentWorkOnRoot.bind(null, root), // Compute a task timeout based on the expiration time. This also affects
12222 // ordering because tasks are processed in timeout order.
12223 {
12224 timeout: expirationTimeToMs(expirationTime) - now()
12225 });
12226 }
12227
12228 root.callbackNode = callbackNode;
12229} // This is the entry point for every concurrent task, i.e. anything that
12230// goes through Scheduler.
12231
12232
12233function performConcurrentWorkOnRoot(root, didTimeout) {
12234 // Since we know we're in a React event, we can clear the current
12235 // event time. The next update will compute a new event time.
12236 currentEventTime = NoWork;
12237
12238 if (didTimeout) {
12239 // The render task took too long to complete. Mark the current time as
12240 // expired to synchronously render all expired work in a single batch.
12241 var currentTime = requestCurrentTimeForUpdate();
12242 markRootExpiredAtTime(root, currentTime); // This will schedule a synchronous callback.
12243
12244 ensureRootIsScheduled(root);
12245 return null;
12246 } // Determine the next expiration time to work on, using the fields stored
12247 // on the root.
12248
12249
12250 var expirationTime = getNextRootExpirationTimeToWorkOn(root);
12251
12252 if (expirationTime !== NoWork) {
12253 var originalCallbackNode = root.callbackNode;
12254
12255 if (!((executionContext & (RenderContext | CommitContext)) === NoContext)) {
12256 {
12257 throw Error( "Should not already be working." );
12258 }
12259 }
12260
12261 flushPassiveEffects(); // If the root or expiration time have changed, throw out the existing stack
12262 // and prepare a fresh one. Otherwise we'll continue where we left off.
12263
12264 if (root !== workInProgressRoot || expirationTime !== renderExpirationTime$1) {
12265 prepareFreshStack(root, expirationTime);
12266 startWorkOnPendingInteractions(root, expirationTime);
12267 } // If we have a work-in-progress fiber, it means there's still work to do
12268 // in this root.
12269
12270
12271 if (workInProgress !== null) {
12272 var prevExecutionContext = executionContext;
12273 executionContext |= RenderContext;
12274 var prevDispatcher = pushDispatcher();
12275 var prevInteractions = pushInteractions(root);
12276 startWorkLoopTimer(workInProgress);
12277
12278 do {
12279 try {
12280 workLoopConcurrent();
12281 break;
12282 } catch (thrownValue) {
12283 handleError(root, thrownValue);
12284 }
12285 } while (true);
12286
12287 resetContextDependencies();
12288 executionContext = prevExecutionContext;
12289 popDispatcher(prevDispatcher);
12290
12291 {
12292 popInteractions(prevInteractions);
12293 }
12294
12295 if (workInProgressRootExitStatus === RootFatalErrored) {
12296 var fatalError = workInProgressRootFatalError;
12297 stopInterruptedWorkLoopTimer();
12298 prepareFreshStack(root, expirationTime);
12299 markRootSuspendedAtTime(root, expirationTime);
12300 ensureRootIsScheduled(root);
12301 throw fatalError;
12302 }
12303
12304 if (workInProgress !== null) {
12305 // There's still work left over. Exit without committing.
12306 stopInterruptedWorkLoopTimer();
12307 } else {
12308 // We now have a consistent tree. The next step is either to commit it,
12309 // or, if something suspended, wait to commit it after a timeout.
12310 stopFinishedWorkLoopTimer();
12311 var finishedWork = root.finishedWork = root.current.alternate;
12312 root.finishedExpirationTime = expirationTime;
12313 finishConcurrentRender(root, finishedWork, workInProgressRootExitStatus, expirationTime);
12314 }
12315
12316 ensureRootIsScheduled(root);
12317
12318 if (root.callbackNode === originalCallbackNode) {
12319 // The task node scheduled for this root is the same one that's
12320 // currently executed. Need to return a continuation.
12321 return performConcurrentWorkOnRoot.bind(null, root);
12322 }
12323 }
12324 }
12325
12326 return null;
12327}
12328
12329function finishConcurrentRender(root, finishedWork, exitStatus, expirationTime) {
12330 // Set this to null to indicate there's no in-progress render.
12331 workInProgressRoot = null;
12332
12333 switch (exitStatus) {
12334 case RootIncomplete:
12335 case RootFatalErrored:
12336 {
12337 {
12338 {
12339 throw Error( "Root did not complete. This is a bug in React." );
12340 }
12341 }
12342 }
12343 // Flow knows about invariant, so it complains if I add a break
12344 // statement, but eslint doesn't know about invariant, so it complains
12345 // if I do. eslint-disable-next-line no-fallthrough
12346
12347 case RootErrored:
12348 {
12349 // If this was an async render, the error may have happened due to
12350 // a mutation in a concurrent event. Try rendering one more time,
12351 // synchronously, to see if the error goes away. If there are
12352 // lower priority updates, let's include those, too, in case they
12353 // fix the inconsistency. Render at Idle to include all updates.
12354 // If it was Idle or Never or some not-yet-invented time, render
12355 // at that time.
12356 markRootExpiredAtTime(root, expirationTime > Idle ? Idle : expirationTime); // We assume that this second render pass will be synchronous
12357 // and therefore not hit this path again.
12358
12359 break;
12360 }
12361
12362 case RootSuspended:
12363 {
12364 markRootSuspendedAtTime(root, expirationTime);
12365 var lastSuspendedTime = root.lastSuspendedTime;
12366
12367 if (expirationTime === lastSuspendedTime) {
12368 root.nextKnownPendingLevel = getRemainingExpirationTime(finishedWork);
12369 } // We have an acceptable loading state. We need to figure out if we
12370 // should immediately commit it or wait a bit.
12371 // If we have processed new updates during this render, we may now
12372 // have a new loading state ready. We want to ensure that we commit
12373 // that as soon as possible.
12374
12375
12376 var hasNotProcessedNewUpdates = workInProgressRootLatestProcessedExpirationTime === Sync;
12377
12378 if (hasNotProcessedNewUpdates && // do not delay if we're inside an act() scope
12379 !( IsThisRendererActing.current)) {
12380 // If we have not processed any new updates during this pass, then
12381 // this is either a retry of an existing fallback state or a
12382 // hidden tree. Hidden trees shouldn't be batched with other work
12383 // and after that's fixed it can only be a retry. We're going to
12384 // throttle committing retries so that we don't show too many
12385 // loading states too quickly.
12386 var msUntilTimeout = globalMostRecentFallbackTime + FALLBACK_THROTTLE_MS - now(); // Don't bother with a very short suspense time.
12387
12388 if (msUntilTimeout > 10) {
12389 if (workInProgressRootHasPendingPing) {
12390 var lastPingedTime = root.lastPingedTime;
12391
12392 if (lastPingedTime === NoWork || lastPingedTime >= expirationTime) {
12393 // This render was pinged but we didn't get to restart
12394 // earlier so try restarting now instead.
12395 root.lastPingedTime = expirationTime;
12396 prepareFreshStack(root, expirationTime);
12397 break;
12398 }
12399 }
12400
12401 var nextTime = getNextRootExpirationTimeToWorkOn(root);
12402
12403 if (nextTime !== NoWork && nextTime !== expirationTime) {
12404 // There's additional work on this root.
12405 break;
12406 }
12407
12408 if (lastSuspendedTime !== NoWork && lastSuspendedTime !== expirationTime) {
12409 // We should prefer to render the fallback of at the last
12410 // suspended level. Ping the last suspended level to try
12411 // rendering it again.
12412 root.lastPingedTime = lastSuspendedTime;
12413 break;
12414 } // The render is suspended, it hasn't timed out, and there's no
12415 // lower priority work to do. Instead of committing the fallback
12416 // immediately, wait for more data to arrive.
12417
12418
12419 root.timeoutHandle = scheduleTimeout(commitRoot.bind(null, root), msUntilTimeout);
12420 break;
12421 }
12422 } // The work expired. Commit immediately.
12423
12424
12425 commitRoot(root);
12426 break;
12427 }
12428
12429 case RootSuspendedWithDelay:
12430 {
12431 markRootSuspendedAtTime(root, expirationTime);
12432 var _lastSuspendedTime = root.lastSuspendedTime;
12433
12434 if (expirationTime === _lastSuspendedTime) {
12435 root.nextKnownPendingLevel = getRemainingExpirationTime(finishedWork);
12436 }
12437
12438 {
12439 // We're suspended in a state that should be avoided. We'll try to
12440 // avoid committing it for as long as the timeouts let us.
12441 if (workInProgressRootHasPendingPing) {
12442 var _lastPingedTime = root.lastPingedTime;
12443
12444 if (_lastPingedTime === NoWork || _lastPingedTime >= expirationTime) {
12445 // This render was pinged but we didn't get to restart earlier
12446 // so try restarting now instead.
12447 root.lastPingedTime = expirationTime;
12448 prepareFreshStack(root, expirationTime);
12449 break;
12450 }
12451 }
12452
12453 var _nextTime = getNextRootExpirationTimeToWorkOn(root);
12454
12455 if (_nextTime !== NoWork && _nextTime !== expirationTime) {
12456 // There's additional work on this root.
12457 break;
12458 }
12459
12460 if (_lastSuspendedTime !== NoWork && _lastSuspendedTime !== expirationTime) {
12461 // We should prefer to render the fallback of at the last
12462 // suspended level. Ping the last suspended level to try
12463 // rendering it again.
12464 root.lastPingedTime = _lastSuspendedTime;
12465 break;
12466 }
12467
12468 var _msUntilTimeout;
12469
12470 if (workInProgressRootLatestSuspenseTimeout !== Sync) {
12471 // We have processed a suspense config whose expiration time we
12472 // can use as the timeout.
12473 _msUntilTimeout = expirationTimeToMs(workInProgressRootLatestSuspenseTimeout) - now();
12474 } else if (workInProgressRootLatestProcessedExpirationTime === Sync) {
12475 // This should never normally happen because only new updates
12476 // cause delayed states, so we should have processed something.
12477 // However, this could also happen in an offscreen tree.
12478 _msUntilTimeout = 0;
12479 } else {
12480 // If we don't have a suspense config, we're going to use a
12481 // heuristic to determine how long we can suspend.
12482 var eventTimeMs = inferTimeFromExpirationTime(workInProgressRootLatestProcessedExpirationTime);
12483 var currentTimeMs = now();
12484 var timeUntilExpirationMs = expirationTimeToMs(expirationTime) - currentTimeMs;
12485 var timeElapsed = currentTimeMs - eventTimeMs;
12486
12487 if (timeElapsed < 0) {
12488 // We get this wrong some time since we estimate the time.
12489 timeElapsed = 0;
12490 }
12491
12492 _msUntilTimeout = jnd(timeElapsed) - timeElapsed; // Clamp the timeout to the expiration time. TODO: Once the
12493 // event time is exact instead of inferred from expiration time
12494 // we don't need this.
12495
12496 if (timeUntilExpirationMs < _msUntilTimeout) {
12497 _msUntilTimeout = timeUntilExpirationMs;
12498 }
12499 } // Don't bother with a very short suspense time.
12500
12501
12502 if (_msUntilTimeout > 10) {
12503 // The render is suspended, it hasn't timed out, and there's no
12504 // lower priority work to do. Instead of committing the fallback
12505 // immediately, wait for more data to arrive.
12506 root.timeoutHandle = scheduleTimeout(commitRoot.bind(null, root), _msUntilTimeout);
12507 break;
12508 }
12509 } // The work expired. Commit immediately.
12510
12511
12512 commitRoot(root);
12513 break;
12514 }
12515
12516 case RootCompleted:
12517 {
12518 // The work completed. Ready to commit.
12519 if ( // do not delay if we're inside an act() scope
12520 workInProgressRootLatestProcessedExpirationTime !== Sync && workInProgressRootCanSuspendUsingConfig !== null) {
12521 // If we have exceeded the minimum loading delay, which probably
12522 // means we have shown a spinner already, we might have to suspend
12523 // a bit longer to ensure that the spinner is shown for
12524 // enough time.
12525 var _msUntilTimeout2 = computeMsUntilSuspenseLoadingDelay(workInProgressRootLatestProcessedExpirationTime, expirationTime, workInProgressRootCanSuspendUsingConfig);
12526
12527 if (_msUntilTimeout2 > 10) {
12528 markRootSuspendedAtTime(root, expirationTime);
12529 root.timeoutHandle = scheduleTimeout(commitRoot.bind(null, root), _msUntilTimeout2);
12530 break;
12531 }
12532 }
12533
12534 commitRoot(root);
12535 break;
12536 }
12537
12538 default:
12539 {
12540 {
12541 {
12542 throw Error( "Unknown root exit status." );
12543 }
12544 }
12545 }
12546 }
12547} // This is the entry point for synchronous tasks that don't go
12548// through Scheduler
12549
12550
12551function performSyncWorkOnRoot(root) {
12552 // Check if there's expired work on this root. Otherwise, render at Sync.
12553 var lastExpiredTime = root.lastExpiredTime;
12554 var expirationTime = lastExpiredTime !== NoWork ? lastExpiredTime : Sync;
12555
12556 if (!((executionContext & (RenderContext | CommitContext)) === NoContext)) {
12557 {
12558 throw Error( "Should not already be working." );
12559 }
12560 }
12561
12562 flushPassiveEffects(); // If the root or expiration time have changed, throw out the existing stack
12563 // and prepare a fresh one. Otherwise we'll continue where we left off.
12564
12565 if (root !== workInProgressRoot || expirationTime !== renderExpirationTime$1) {
12566 prepareFreshStack(root, expirationTime);
12567 startWorkOnPendingInteractions(root, expirationTime);
12568 } // If we have a work-in-progress fiber, it means there's still work to do
12569 // in this root.
12570
12571
12572 if (workInProgress !== null) {
12573 var prevExecutionContext = executionContext;
12574 executionContext |= RenderContext;
12575 var prevDispatcher = pushDispatcher();
12576 var prevInteractions = pushInteractions(root);
12577 startWorkLoopTimer(workInProgress);
12578
12579 do {
12580 try {
12581 workLoopSync();
12582 break;
12583 } catch (thrownValue) {
12584 handleError(root, thrownValue);
12585 }
12586 } while (true);
12587
12588 resetContextDependencies();
12589 executionContext = prevExecutionContext;
12590 popDispatcher(prevDispatcher);
12591
12592 {
12593 popInteractions(prevInteractions);
12594 }
12595
12596 if (workInProgressRootExitStatus === RootFatalErrored) {
12597 var fatalError = workInProgressRootFatalError;
12598 stopInterruptedWorkLoopTimer();
12599 prepareFreshStack(root, expirationTime);
12600 markRootSuspendedAtTime(root, expirationTime);
12601 ensureRootIsScheduled(root);
12602 throw fatalError;
12603 }
12604
12605 if (workInProgress !== null) {
12606 // This is a sync render, so we should have finished the whole tree.
12607 {
12608 {
12609 throw Error( "Cannot commit an incomplete root. This error is likely caused by a bug in React. Please file an issue." );
12610 }
12611 }
12612 } else {
12613 // We now have a consistent tree. Because this is a sync render, we
12614 // will commit it even if something suspended.
12615 stopFinishedWorkLoopTimer();
12616 root.finishedWork = root.current.alternate;
12617 root.finishedExpirationTime = expirationTime;
12618 finishSyncRender(root);
12619 } // Before exiting, make sure there's a callback scheduled for the next
12620 // pending level.
12621
12622
12623 ensureRootIsScheduled(root);
12624 }
12625
12626 return null;
12627}
12628
12629function finishSyncRender(root) {
12630 // Set this to null to indicate there's no in-progress render.
12631 workInProgressRoot = null;
12632 commitRoot(root);
12633}
12634function syncUpdates(fn, a, b, c) {
12635 return runWithPriority(ImmediatePriority, fn.bind(null, a, b, c));
12636}
12637function flushSync(fn, a) {
12638 if ((executionContext & (RenderContext | CommitContext)) !== NoContext) {
12639 {
12640 {
12641 throw Error( "flushSync was called from inside a lifecycle method. It cannot be called when React is already rendering." );
12642 }
12643 }
12644 }
12645
12646 var prevExecutionContext = executionContext;
12647 executionContext |= BatchedContext;
12648
12649 try {
12650 return runWithPriority(ImmediatePriority, fn.bind(null, a));
12651 } finally {
12652 executionContext = prevExecutionContext; // Flush the immediate callbacks that were scheduled during this batch.
12653 // Note that this will happen even if batchedUpdates is higher up
12654 // the stack.
12655
12656 flushSyncCallbackQueue();
12657 }
12658}
12659
12660function prepareFreshStack(root, expirationTime) {
12661 root.finishedWork = null;
12662 root.finishedExpirationTime = NoWork;
12663 var timeoutHandle = root.timeoutHandle;
12664
12665 if (timeoutHandle !== noTimeout) {
12666 // The root previous suspended and scheduled a timeout to commit a fallback
12667 // state. Now that we have additional work, cancel the timeout.
12668 root.timeoutHandle = noTimeout; // $FlowFixMe Complains noTimeout is not a TimeoutID, despite the check above
12669
12670 cancelTimeout(timeoutHandle);
12671 }
12672
12673 if (workInProgress !== null) {
12674 var interruptedWork = workInProgress.return;
12675
12676 while (interruptedWork !== null) {
12677 unwindInterruptedWork(interruptedWork);
12678 interruptedWork = interruptedWork.return;
12679 }
12680 }
12681
12682 workInProgressRoot = root;
12683 workInProgress = createWorkInProgress(root.current, null);
12684 renderExpirationTime$1 = expirationTime;
12685 workInProgressRootExitStatus = RootIncomplete;
12686 workInProgressRootFatalError = null;
12687 workInProgressRootLatestProcessedExpirationTime = Sync;
12688 workInProgressRootLatestSuspenseTimeout = Sync;
12689 workInProgressRootCanSuspendUsingConfig = null;
12690 workInProgressRootNextUnprocessedUpdateTime = NoWork;
12691 workInProgressRootHasPendingPing = false;
12692
12693 {
12694 spawnedWorkDuringRender = null;
12695 }
12696
12697 {
12698 ReactStrictModeWarnings.discardPendingWarnings();
12699 }
12700}
12701
12702function handleError(root, thrownValue) {
12703 do {
12704 try {
12705 // Reset module-level state that was set during the render phase.
12706 resetContextDependencies();
12707 resetHooksAfterThrow();
12708 resetCurrentFiber();
12709
12710 if (workInProgress === null || workInProgress.return === null) {
12711 // Expected to be working on a non-root fiber. This is a fatal error
12712 // because there's no ancestor that can handle it; the root is
12713 // supposed to capture all errors that weren't caught by an error
12714 // boundary.
12715 workInProgressRootExitStatus = RootFatalErrored;
12716 workInProgressRootFatalError = thrownValue; // Set `workInProgress` to null. This represents advancing to the next
12717 // sibling, or the parent if there are no siblings. But since the root
12718 // has no siblings nor a parent, we set it to null. Usually this is
12719 // handled by `completeUnitOfWork` or `unwindWork`, but since we're
12720 // interntionally not calling those, we need set it here.
12721 // TODO: Consider calling `unwindWork` to pop the contexts.
12722
12723 workInProgress = null;
12724 return null;
12725 }
12726
12727 if (enableProfilerTimer && workInProgress.mode & ProfileMode) {
12728 // Record the time spent rendering before an error was thrown. This
12729 // avoids inaccurate Profiler durations in the case of a
12730 // suspended render.
12731 stopProfilerTimerIfRunningAndRecordDelta(workInProgress, true);
12732 }
12733
12734 throwException(root, workInProgress.return, workInProgress, thrownValue, renderExpirationTime$1);
12735 workInProgress = completeUnitOfWork(workInProgress);
12736 } catch (yetAnotherThrownValue) {
12737 // Something in the return path also threw.
12738 thrownValue = yetAnotherThrownValue;
12739 continue;
12740 } // Return to the normal work loop.
12741
12742
12743 return;
12744 } while (true);
12745}
12746
12747function pushDispatcher(root) {
12748 var prevDispatcher = ReactCurrentDispatcher$1.current;
12749 ReactCurrentDispatcher$1.current = ContextOnlyDispatcher;
12750
12751 if (prevDispatcher === null) {
12752 // The React isomorphic package does not include a default dispatcher.
12753 // Instead the first renderer will lazily attach one, in order to give
12754 // nicer error messages.
12755 return ContextOnlyDispatcher;
12756 } else {
12757 return prevDispatcher;
12758 }
12759}
12760
12761function popDispatcher(prevDispatcher) {
12762 ReactCurrentDispatcher$1.current = prevDispatcher;
12763}
12764
12765function pushInteractions(root) {
12766 {
12767 var prevInteractions = tracing.__interactionsRef.current;
12768 tracing.__interactionsRef.current = root.memoizedInteractions;
12769 return prevInteractions;
12770 }
12771}
12772
12773function popInteractions(prevInteractions) {
12774 {
12775 tracing.__interactionsRef.current = prevInteractions;
12776 }
12777}
12778
12779function markCommitTimeOfFallback() {
12780 globalMostRecentFallbackTime = now();
12781}
12782function markRenderEventTimeAndConfig(expirationTime, suspenseConfig) {
12783 if (expirationTime < workInProgressRootLatestProcessedExpirationTime && expirationTime > Idle) {
12784 workInProgressRootLatestProcessedExpirationTime = expirationTime;
12785 }
12786
12787 if (suspenseConfig !== null) {
12788 if (expirationTime < workInProgressRootLatestSuspenseTimeout && expirationTime > Idle) {
12789 workInProgressRootLatestSuspenseTimeout = expirationTime; // Most of the time we only have one config and getting wrong is not bad.
12790
12791 workInProgressRootCanSuspendUsingConfig = suspenseConfig;
12792 }
12793 }
12794}
12795function markUnprocessedUpdateTime(expirationTime) {
12796 if (expirationTime > workInProgressRootNextUnprocessedUpdateTime) {
12797 workInProgressRootNextUnprocessedUpdateTime = expirationTime;
12798 }
12799}
12800function renderDidSuspend() {
12801 if (workInProgressRootExitStatus === RootIncomplete) {
12802 workInProgressRootExitStatus = RootSuspended;
12803 }
12804}
12805function renderDidSuspendDelayIfPossible() {
12806 if (workInProgressRootExitStatus === RootIncomplete || workInProgressRootExitStatus === RootSuspended) {
12807 workInProgressRootExitStatus = RootSuspendedWithDelay;
12808 } // Check if there's a lower priority update somewhere else in the tree.
12809
12810
12811 if (workInProgressRootNextUnprocessedUpdateTime !== NoWork && workInProgressRoot !== null) {
12812 // Mark the current render as suspended, and then mark that there's a
12813 // pending update.
12814 // TODO: This should immediately interrupt the current render, instead
12815 // of waiting until the next time we yield.
12816 markRootSuspendedAtTime(workInProgressRoot, renderExpirationTime$1);
12817 markRootUpdatedAtTime(workInProgressRoot, workInProgressRootNextUnprocessedUpdateTime);
12818 }
12819}
12820function renderDidError() {
12821 if (workInProgressRootExitStatus !== RootCompleted) {
12822 workInProgressRootExitStatus = RootErrored;
12823 }
12824} // Called during render to determine if anything has suspended.
12825// Returns false if we're not sure.
12826
12827function renderHasNotSuspendedYet() {
12828 // If something errored or completed, we can't really be sure,
12829 // so those are false.
12830 return workInProgressRootExitStatus === RootIncomplete;
12831}
12832
12833function inferTimeFromExpirationTime(expirationTime) {
12834 // We don't know exactly when the update was scheduled, but we can infer an
12835 // approximate start time from the expiration time.
12836 var earliestExpirationTimeMs = expirationTimeToMs(expirationTime);
12837 return earliestExpirationTimeMs - LOW_PRIORITY_EXPIRATION;
12838}
12839
12840function inferTimeFromExpirationTimeWithSuspenseConfig(expirationTime, suspenseConfig) {
12841 // We don't know exactly when the update was scheduled, but we can infer an
12842 // approximate start time from the expiration time by subtracting the timeout
12843 // that was added to the event time.
12844 var earliestExpirationTimeMs = expirationTimeToMs(expirationTime);
12845 return earliestExpirationTimeMs - (suspenseConfig.timeoutMs | 0 || LOW_PRIORITY_EXPIRATION);
12846} // The work loop is an extremely hot path. Tell Closure not to inline it.
12847
12848/** @noinline */
12849
12850
12851function workLoopSync() {
12852 // Already timed out, so perform work without checking if we need to yield.
12853 while (workInProgress !== null) {
12854 workInProgress = performUnitOfWork(workInProgress);
12855 }
12856}
12857/** @noinline */
12858
12859
12860function workLoopConcurrent() {
12861 // Perform work until Scheduler asks us to yield
12862 while (workInProgress !== null && !shouldYield()) {
12863 workInProgress = performUnitOfWork(workInProgress);
12864 }
12865}
12866
12867function performUnitOfWork(unitOfWork) {
12868 // The current, flushed, state of this fiber is the alternate. Ideally
12869 // nothing should rely on this, but relying on it here means that we don't
12870 // need an additional field on the work in progress.
12871 var current = unitOfWork.alternate;
12872 startWorkTimer(unitOfWork);
12873 setCurrentFiber(unitOfWork);
12874 var next;
12875
12876 if ( (unitOfWork.mode & ProfileMode) !== NoMode) {
12877 startProfilerTimer(unitOfWork);
12878 next = beginWork$1(current, unitOfWork, renderExpirationTime$1);
12879 stopProfilerTimerIfRunningAndRecordDelta(unitOfWork, true);
12880 } else {
12881 next = beginWork$1(current, unitOfWork, renderExpirationTime$1);
12882 }
12883
12884 resetCurrentFiber();
12885 unitOfWork.memoizedProps = unitOfWork.pendingProps;
12886
12887 if (next === null) {
12888 // If this doesn't spawn new work, complete the current work.
12889 next = completeUnitOfWork(unitOfWork);
12890 }
12891
12892 ReactCurrentOwner$2.current = null;
12893 return next;
12894}
12895
12896function completeUnitOfWork(unitOfWork) {
12897 // Attempt to complete the current unit of work, then move to the next
12898 // sibling. If there are no more siblings, return to the parent fiber.
12899 workInProgress = unitOfWork;
12900
12901 do {
12902 // The current, flushed, state of this fiber is the alternate. Ideally
12903 // nothing should rely on this, but relying on it here means that we don't
12904 // need an additional field on the work in progress.
12905 var current = workInProgress.alternate;
12906 var returnFiber = workInProgress.return; // Check if the work completed or if something threw.
12907
12908 if ((workInProgress.effectTag & Incomplete) === NoEffect) {
12909 setCurrentFiber(workInProgress);
12910 var next = void 0;
12911
12912 if ( (workInProgress.mode & ProfileMode) === NoMode) {
12913 next = completeWork(current, workInProgress, renderExpirationTime$1);
12914 } else {
12915 startProfilerTimer(workInProgress);
12916 next = completeWork(current, workInProgress, renderExpirationTime$1); // Update render duration assuming we didn't error.
12917
12918 stopProfilerTimerIfRunningAndRecordDelta(workInProgress, false);
12919 }
12920
12921 stopWorkTimer(workInProgress);
12922 resetCurrentFiber();
12923 resetChildExpirationTime(workInProgress);
12924
12925 if (next !== null) {
12926 // Completing this fiber spawned new work. Work on that next.
12927 return next;
12928 }
12929
12930 if (returnFiber !== null && // Do not append effects to parents if a sibling failed to complete
12931 (returnFiber.effectTag & Incomplete) === NoEffect) {
12932 // Append all the effects of the subtree and this fiber onto the effect
12933 // list of the parent. The completion order of the children affects the
12934 // side-effect order.
12935 if (returnFiber.firstEffect === null) {
12936 returnFiber.firstEffect = workInProgress.firstEffect;
12937 }
12938
12939 if (workInProgress.lastEffect !== null) {
12940 if (returnFiber.lastEffect !== null) {
12941 returnFiber.lastEffect.nextEffect = workInProgress.firstEffect;
12942 }
12943
12944 returnFiber.lastEffect = workInProgress.lastEffect;
12945 } // If this fiber had side-effects, we append it AFTER the children's
12946 // side-effects. We can perform certain side-effects earlier if needed,
12947 // by doing multiple passes over the effect list. We don't want to
12948 // schedule our own side-effect on our own list because if end up
12949 // reusing children we'll schedule this effect onto itself since we're
12950 // at the end.
12951
12952
12953 var effectTag = workInProgress.effectTag; // Skip both NoWork and PerformedWork tags when creating the effect
12954 // list. PerformedWork effect is read by React DevTools but shouldn't be
12955 // committed.
12956
12957 if (effectTag > PerformedWork) {
12958 if (returnFiber.lastEffect !== null) {
12959 returnFiber.lastEffect.nextEffect = workInProgress;
12960 } else {
12961 returnFiber.firstEffect = workInProgress;
12962 }
12963
12964 returnFiber.lastEffect = workInProgress;
12965 }
12966 }
12967 } else {
12968 // This fiber did not complete because something threw. Pop values off
12969 // the stack without entering the complete phase. If this is a boundary,
12970 // capture values if possible.
12971 var _next = unwindWork(workInProgress); // Because this fiber did not complete, don't reset its expiration time.
12972
12973
12974 if ( (workInProgress.mode & ProfileMode) !== NoMode) {
12975 // Record the render duration for the fiber that errored.
12976 stopProfilerTimerIfRunningAndRecordDelta(workInProgress, false); // Include the time spent working on failed children before continuing.
12977
12978 var actualDuration = workInProgress.actualDuration;
12979 var child = workInProgress.child;
12980
12981 while (child !== null) {
12982 actualDuration += child.actualDuration;
12983 child = child.sibling;
12984 }
12985
12986 workInProgress.actualDuration = actualDuration;
12987 }
12988
12989 if (_next !== null) {
12990 // If completing this work spawned new work, do that next. We'll come
12991 // back here again.
12992 // Since we're restarting, remove anything that is not a host effect
12993 // from the effect tag.
12994 // TODO: The name stopFailedWorkTimer is misleading because Suspense
12995 // also captures and restarts.
12996 stopFailedWorkTimer(workInProgress);
12997 _next.effectTag &= HostEffectMask;
12998 return _next;
12999 }
13000
13001 stopWorkTimer(workInProgress);
13002
13003 if (returnFiber !== null) {
13004 // Mark the parent fiber as incomplete and clear its effect list.
13005 returnFiber.firstEffect = returnFiber.lastEffect = null;
13006 returnFiber.effectTag |= Incomplete;
13007 }
13008 }
13009
13010 var siblingFiber = workInProgress.sibling;
13011
13012 if (siblingFiber !== null) {
13013 // If there is more work to do in this returnFiber, do that next.
13014 return siblingFiber;
13015 } // Otherwise, return to the parent
13016
13017
13018 workInProgress = returnFiber;
13019 } while (workInProgress !== null); // We've reached the root.
13020
13021
13022 if (workInProgressRootExitStatus === RootIncomplete) {
13023 workInProgressRootExitStatus = RootCompleted;
13024 }
13025
13026 return null;
13027}
13028
13029function getRemainingExpirationTime(fiber) {
13030 var updateExpirationTime = fiber.expirationTime;
13031 var childExpirationTime = fiber.childExpirationTime;
13032 return updateExpirationTime > childExpirationTime ? updateExpirationTime : childExpirationTime;
13033}
13034
13035function resetChildExpirationTime(completedWork) {
13036 if (renderExpirationTime$1 !== Never && completedWork.childExpirationTime === Never) {
13037 // The children of this component are hidden. Don't bubble their
13038 // expiration times.
13039 return;
13040 }
13041
13042 var newChildExpirationTime = NoWork; // Bubble up the earliest expiration time.
13043
13044 if ( (completedWork.mode & ProfileMode) !== NoMode) {
13045 // In profiling mode, resetChildExpirationTime is also used to reset
13046 // profiler durations.
13047 var actualDuration = completedWork.actualDuration;
13048 var treeBaseDuration = completedWork.selfBaseDuration; // When a fiber is cloned, its actualDuration is reset to 0. This value will
13049 // only be updated if work is done on the fiber (i.e. it doesn't bailout).
13050 // When work is done, it should bubble to the parent's actualDuration. If
13051 // the fiber has not been cloned though, (meaning no work was done), then
13052 // this value will reflect the amount of time spent working on a previous
13053 // render. In that case it should not bubble. We determine whether it was
13054 // cloned by comparing the child pointer.
13055
13056 var shouldBubbleActualDurations = completedWork.alternate === null || completedWork.child !== completedWork.alternate.child;
13057 var child = completedWork.child;
13058
13059 while (child !== null) {
13060 var childUpdateExpirationTime = child.expirationTime;
13061 var childChildExpirationTime = child.childExpirationTime;
13062
13063 if (childUpdateExpirationTime > newChildExpirationTime) {
13064 newChildExpirationTime = childUpdateExpirationTime;
13065 }
13066
13067 if (childChildExpirationTime > newChildExpirationTime) {
13068 newChildExpirationTime = childChildExpirationTime;
13069 }
13070
13071 if (shouldBubbleActualDurations) {
13072 actualDuration += child.actualDuration;
13073 }
13074
13075 treeBaseDuration += child.treeBaseDuration;
13076 child = child.sibling;
13077 }
13078
13079 completedWork.actualDuration = actualDuration;
13080 completedWork.treeBaseDuration = treeBaseDuration;
13081 } else {
13082 var _child = completedWork.child;
13083
13084 while (_child !== null) {
13085 var _childUpdateExpirationTime = _child.expirationTime;
13086 var _childChildExpirationTime = _child.childExpirationTime;
13087
13088 if (_childUpdateExpirationTime > newChildExpirationTime) {
13089 newChildExpirationTime = _childUpdateExpirationTime;
13090 }
13091
13092 if (_childChildExpirationTime > newChildExpirationTime) {
13093 newChildExpirationTime = _childChildExpirationTime;
13094 }
13095
13096 _child = _child.sibling;
13097 }
13098 }
13099
13100 completedWork.childExpirationTime = newChildExpirationTime;
13101}
13102
13103function commitRoot(root) {
13104 var renderPriorityLevel = getCurrentPriorityLevel();
13105 runWithPriority(ImmediatePriority, commitRootImpl.bind(null, root, renderPriorityLevel));
13106 return null;
13107}
13108
13109function commitRootImpl(root, renderPriorityLevel) {
13110 do {
13111 // `flushPassiveEffects` will call `flushSyncUpdateQueue` at the end, which
13112 // means `flushPassiveEffects` will sometimes result in additional
13113 // passive effects. So we need to keep flushing in a loop until there are
13114 // no more pending effects.
13115 // TODO: Might be better if `flushPassiveEffects` did not automatically
13116 // flush synchronous work at the end, to avoid factoring hazards like this.
13117 flushPassiveEffects();
13118 } while (rootWithPendingPassiveEffects !== null);
13119
13120 flushRenderPhaseStrictModeWarningsInDEV();
13121
13122 if (!((executionContext & (RenderContext | CommitContext)) === NoContext)) {
13123 {
13124 throw Error( "Should not already be working." );
13125 }
13126 }
13127
13128 var finishedWork = root.finishedWork;
13129 var expirationTime = root.finishedExpirationTime;
13130
13131 if (finishedWork === null) {
13132 return null;
13133 }
13134
13135 root.finishedWork = null;
13136 root.finishedExpirationTime = NoWork;
13137
13138 if (!(finishedWork !== root.current)) {
13139 {
13140 throw Error( "Cannot commit the same tree as before. This error is likely caused by a bug in React. Please file an issue." );
13141 }
13142 } // commitRoot never returns a continuation; it always finishes synchronously.
13143 // So we can clear these now to allow a new callback to be scheduled.
13144
13145
13146 root.callbackNode = null;
13147 root.callbackExpirationTime = NoWork;
13148 root.callbackPriority = NoPriority;
13149 root.nextKnownPendingLevel = NoWork;
13150 startCommitTimer(); // Update the first and last pending times on this root. The new first
13151 // pending time is whatever is left on the root fiber.
13152
13153 var remainingExpirationTimeBeforeCommit = getRemainingExpirationTime(finishedWork);
13154 markRootFinishedAtTime(root, expirationTime, remainingExpirationTimeBeforeCommit);
13155
13156 if (root === workInProgressRoot) {
13157 // We can reset these now that they are finished.
13158 workInProgressRoot = null;
13159 workInProgress = null;
13160 renderExpirationTime$1 = NoWork;
13161 } // This indicates that the last root we worked on is not the same one that
13162 // we're committing now. This most commonly happens when a suspended root
13163 // times out.
13164 // Get the list of effects.
13165
13166
13167 var firstEffect;
13168
13169 if (finishedWork.effectTag > PerformedWork) {
13170 // A fiber's effect list consists only of its children, not itself. So if
13171 // the root has an effect, we need to add it to the end of the list. The
13172 // resulting list is the set that would belong to the root's parent, if it
13173 // had one; that is, all the effects in the tree including the root.
13174 if (finishedWork.lastEffect !== null) {
13175 finishedWork.lastEffect.nextEffect = finishedWork;
13176 firstEffect = finishedWork.firstEffect;
13177 } else {
13178 firstEffect = finishedWork;
13179 }
13180 } else {
13181 // There is no effect on the root.
13182 firstEffect = finishedWork.firstEffect;
13183 }
13184
13185 if (firstEffect !== null) {
13186 var prevExecutionContext = executionContext;
13187 executionContext |= CommitContext;
13188 var prevInteractions = pushInteractions(root); // Reset this to null before calling lifecycles
13189
13190 ReactCurrentOwner$2.current = null; // The commit phase is broken into several sub-phases. We do a separate pass
13191 // of the effect list for each phase: all mutation effects come before all
13192 // layout effects, and so on.
13193 // The first phase a "before mutation" phase. We use this phase to read the
13194 // state of the host tree right before we mutate it. This is where
13195 // getSnapshotBeforeUpdate is called.
13196
13197 startCommitSnapshotEffectsTimer();
13198 prepareForCommit(root.containerInfo);
13199 nextEffect = firstEffect;
13200
13201 do {
13202 {
13203 invokeGuardedCallback(null, commitBeforeMutationEffects, null);
13204
13205 if (hasCaughtError()) {
13206 if (!(nextEffect !== null)) {
13207 {
13208 throw Error( "Should be working on an effect." );
13209 }
13210 }
13211
13212 var error = clearCaughtError();
13213 captureCommitPhaseError(nextEffect, error);
13214 nextEffect = nextEffect.nextEffect;
13215 }
13216 }
13217 } while (nextEffect !== null);
13218
13219 stopCommitSnapshotEffectsTimer();
13220
13221 {
13222 // Mark the current commit time to be shared by all Profilers in this
13223 // batch. This enables them to be grouped later.
13224 recordCommitTime();
13225 } // The next phase is the mutation phase, where we mutate the host tree.
13226
13227
13228 startCommitHostEffectsTimer();
13229 nextEffect = firstEffect;
13230
13231 do {
13232 {
13233 invokeGuardedCallback(null, commitMutationEffects, null, root, renderPriorityLevel);
13234
13235 if (hasCaughtError()) {
13236 if (!(nextEffect !== null)) {
13237 {
13238 throw Error( "Should be working on an effect." );
13239 }
13240 }
13241
13242 var _error = clearCaughtError();
13243
13244 captureCommitPhaseError(nextEffect, _error);
13245 nextEffect = nextEffect.nextEffect;
13246 }
13247 }
13248 } while (nextEffect !== null);
13249
13250 stopCommitHostEffectsTimer();
13251 resetAfterCommit(root.containerInfo); // The work-in-progress tree is now the current tree. This must come after
13252 // the mutation phase, so that the previous tree is still current during
13253 // componentWillUnmount, but before the layout phase, so that the finished
13254 // work is current during componentDidMount/Update.
13255
13256 root.current = finishedWork; // The next phase is the layout phase, where we call effects that read
13257 // the host tree after it's been mutated. The idiomatic use case for this is
13258 // layout, but class component lifecycles also fire here for legacy reasons.
13259
13260 startCommitLifeCyclesTimer();
13261 nextEffect = firstEffect;
13262
13263 do {
13264 {
13265 invokeGuardedCallback(null, commitLayoutEffects, null, root, expirationTime);
13266
13267 if (hasCaughtError()) {
13268 if (!(nextEffect !== null)) {
13269 {
13270 throw Error( "Should be working on an effect." );
13271 }
13272 }
13273
13274 var _error2 = clearCaughtError();
13275
13276 captureCommitPhaseError(nextEffect, _error2);
13277 nextEffect = nextEffect.nextEffect;
13278 }
13279 }
13280 } while (nextEffect !== null);
13281
13282 stopCommitLifeCyclesTimer();
13283 nextEffect = null; // Tell Scheduler to yield at the end of the frame, so the browser has an
13284 // opportunity to paint.
13285
13286 requestPaint();
13287
13288 {
13289 popInteractions(prevInteractions);
13290 }
13291
13292 executionContext = prevExecutionContext;
13293 } else {
13294 // No effects.
13295 root.current = finishedWork; // Measure these anyway so the flamegraph explicitly shows that there were
13296 // no effects.
13297 // TODO: Maybe there's a better way to report this.
13298
13299 startCommitSnapshotEffectsTimer();
13300 stopCommitSnapshotEffectsTimer();
13301
13302 {
13303 recordCommitTime();
13304 }
13305
13306 startCommitHostEffectsTimer();
13307 stopCommitHostEffectsTimer();
13308 startCommitLifeCyclesTimer();
13309 stopCommitLifeCyclesTimer();
13310 }
13311
13312 stopCommitTimer();
13313 var rootDidHavePassiveEffects = rootDoesHavePassiveEffects;
13314
13315 if (rootDoesHavePassiveEffects) {
13316 // This commit has passive effects. Stash a reference to them. But don't
13317 // schedule a callback until after flushing layout work.
13318 rootDoesHavePassiveEffects = false;
13319 rootWithPendingPassiveEffects = root;
13320 pendingPassiveEffectsExpirationTime = expirationTime;
13321 pendingPassiveEffectsRenderPriority = renderPriorityLevel;
13322 } else {
13323 // We are done with the effect chain at this point so let's clear the
13324 // nextEffect pointers to assist with GC. If we have passive effects, we'll
13325 // clear this in flushPassiveEffects.
13326 nextEffect = firstEffect;
13327
13328 while (nextEffect !== null) {
13329 var nextNextEffect = nextEffect.nextEffect;
13330 nextEffect.nextEffect = null;
13331 nextEffect = nextNextEffect;
13332 }
13333 } // Check if there's remaining work on this root
13334
13335
13336 var remainingExpirationTime = root.firstPendingTime;
13337
13338 if (remainingExpirationTime !== NoWork) {
13339 {
13340 if (spawnedWorkDuringRender !== null) {
13341 var expirationTimes = spawnedWorkDuringRender;
13342 spawnedWorkDuringRender = null;
13343
13344 for (var i = 0; i < expirationTimes.length; i++) {
13345 scheduleInteractions(root, expirationTimes[i], root.memoizedInteractions);
13346 }
13347 }
13348
13349 schedulePendingInteractions(root, remainingExpirationTime);
13350 }
13351 } else {
13352 // If there's no remaining work, we can clear the set of already failed
13353 // error boundaries.
13354 legacyErrorBoundariesThatAlreadyFailed = null;
13355 }
13356
13357 {
13358 if (!rootDidHavePassiveEffects) {
13359 // If there are no passive effects, then we can complete the pending interactions.
13360 // Otherwise, we'll wait until after the passive effects are flushed.
13361 // Wait to do this until after remaining work has been scheduled,
13362 // so that we don't prematurely signal complete for interactions when there's e.g. hidden work.
13363 finishPendingInteractions(root, expirationTime);
13364 }
13365 }
13366
13367 if (remainingExpirationTime === Sync) {
13368 // Count the number of times the root synchronously re-renders without
13369 // finishing. If there are too many, it indicates an infinite update loop.
13370 if (root === rootWithNestedUpdates) {
13371 nestedUpdateCount++;
13372 } else {
13373 nestedUpdateCount = 0;
13374 rootWithNestedUpdates = root;
13375 }
13376 } else {
13377 nestedUpdateCount = 0;
13378 }
13379
13380 onCommitRoot(finishedWork.stateNode, expirationTime); // Always call this before exiting `commitRoot`, to ensure that any
13381 // additional work on this root is scheduled.
13382
13383 ensureRootIsScheduled(root);
13384
13385 if (hasUncaughtError) {
13386 hasUncaughtError = false;
13387 var _error3 = firstUncaughtError;
13388 firstUncaughtError = null;
13389 throw _error3;
13390 }
13391
13392 if ((executionContext & LegacyUnbatchedContext) !== NoContext) {
13393 // This is a legacy edge case. We just committed the initial mount of
13394 // a ReactDOM.render-ed root inside of batchedUpdates. The commit fired
13395 // synchronously, but layout updates should be deferred until the end
13396 // of the batch.
13397 return null;
13398 } // If layout work was scheduled, flush it now.
13399
13400
13401 flushSyncCallbackQueue();
13402 return null;
13403}
13404
13405function commitBeforeMutationEffects() {
13406 while (nextEffect !== null) {
13407 var effectTag = nextEffect.effectTag;
13408
13409 if ((effectTag & Snapshot) !== NoEffect) {
13410 setCurrentFiber(nextEffect);
13411 recordEffect();
13412 var current = nextEffect.alternate;
13413 commitBeforeMutationLifeCycles(current, nextEffect);
13414 resetCurrentFiber();
13415 }
13416
13417 if ((effectTag & Passive) !== NoEffect) {
13418 // If there are passive effects, schedule a callback to flush at
13419 // the earliest opportunity.
13420 if (!rootDoesHavePassiveEffects) {
13421 rootDoesHavePassiveEffects = true;
13422 scheduleCallback(NormalPriority, function () {
13423 flushPassiveEffects();
13424 return null;
13425 });
13426 }
13427 }
13428
13429 nextEffect = nextEffect.nextEffect;
13430 }
13431}
13432
13433function commitMutationEffects(root, renderPriorityLevel) {
13434 // TODO: Should probably move the bulk of this function to commitWork.
13435 while (nextEffect !== null) {
13436 setCurrentFiber(nextEffect);
13437 var effectTag = nextEffect.effectTag;
13438
13439 if (effectTag & ContentReset) {
13440 commitResetTextContent(nextEffect);
13441 }
13442
13443 if (effectTag & Ref) {
13444 var current = nextEffect.alternate;
13445
13446 if (current !== null) {
13447 commitDetachRef(current);
13448 }
13449 } // The following switch statement is only concerned about placement,
13450 // updates, and deletions. To avoid needing to add a case for every possible
13451 // bitmap value, we remove the secondary effects from the effect tag and
13452 // switch on that value.
13453
13454
13455 var primaryEffectTag = effectTag & (Placement | Update | Deletion | Hydrating);
13456
13457 switch (primaryEffectTag) {
13458 case Placement:
13459 {
13460 commitPlacement(nextEffect); // Clear the "placement" from effect tag so that we know that this is
13461 // inserted, before any life-cycles like componentDidMount gets called.
13462 // TODO: findDOMNode doesn't rely on this any more but isMounted does
13463 // and isMounted is deprecated anyway so we should be able to kill this.
13464
13465 nextEffect.effectTag &= ~Placement;
13466 break;
13467 }
13468
13469 case PlacementAndUpdate:
13470 {
13471 // Placement
13472 commitPlacement(nextEffect); // Clear the "placement" from effect tag so that we know that this is
13473 // inserted, before any life-cycles like componentDidMount gets called.
13474
13475 nextEffect.effectTag &= ~Placement; // Update
13476
13477 var _current = nextEffect.alternate;
13478 commitWork(_current, nextEffect);
13479 break;
13480 }
13481
13482 case Hydrating:
13483 {
13484 nextEffect.effectTag &= ~Hydrating;
13485 break;
13486 }
13487
13488 case HydratingAndUpdate:
13489 {
13490 nextEffect.effectTag &= ~Hydrating; // Update
13491
13492 var _current2 = nextEffect.alternate;
13493 commitWork(_current2, nextEffect);
13494 break;
13495 }
13496
13497 case Update:
13498 {
13499 var _current3 = nextEffect.alternate;
13500 commitWork(_current3, nextEffect);
13501 break;
13502 }
13503
13504 case Deletion:
13505 {
13506 commitDeletion(root, nextEffect, renderPriorityLevel);
13507 break;
13508 }
13509 } // TODO: Only record a mutation effect if primaryEffectTag is non-zero.
13510
13511
13512 recordEffect();
13513 resetCurrentFiber();
13514 nextEffect = nextEffect.nextEffect;
13515 }
13516}
13517
13518function commitLayoutEffects(root, committedExpirationTime) {
13519 // TODO: Should probably move the bulk of this function to commitWork.
13520 while (nextEffect !== null) {
13521 setCurrentFiber(nextEffect);
13522 var effectTag = nextEffect.effectTag;
13523
13524 if (effectTag & (Update | Callback)) {
13525 recordEffect();
13526 var current = nextEffect.alternate;
13527 commitLifeCycles(root, current, nextEffect);
13528 }
13529
13530 if (effectTag & Ref) {
13531 recordEffect();
13532 commitAttachRef(nextEffect);
13533 }
13534
13535 resetCurrentFiber();
13536 nextEffect = nextEffect.nextEffect;
13537 }
13538}
13539
13540function flushPassiveEffects() {
13541 if (pendingPassiveEffectsRenderPriority !== NoPriority) {
13542 var priorityLevel = pendingPassiveEffectsRenderPriority > NormalPriority ? NormalPriority : pendingPassiveEffectsRenderPriority;
13543 pendingPassiveEffectsRenderPriority = NoPriority;
13544 return runWithPriority(priorityLevel, flushPassiveEffectsImpl);
13545 }
13546}
13547
13548function flushPassiveEffectsImpl() {
13549 if (rootWithPendingPassiveEffects === null) {
13550 return false;
13551 }
13552
13553 var root = rootWithPendingPassiveEffects;
13554 var expirationTime = pendingPassiveEffectsExpirationTime;
13555 rootWithPendingPassiveEffects = null;
13556 pendingPassiveEffectsExpirationTime = NoWork;
13557
13558 if (!((executionContext & (RenderContext | CommitContext)) === NoContext)) {
13559 {
13560 throw Error( "Cannot flush passive effects while already rendering." );
13561 }
13562 }
13563
13564 var prevExecutionContext = executionContext;
13565 executionContext |= CommitContext;
13566 var prevInteractions = pushInteractions(root);
13567
13568 {
13569 // Note: This currently assumes there are no passive effects on the root fiber
13570 // because the root is not part of its own effect list.
13571 // This could change in the future.
13572 var _effect2 = root.current.firstEffect;
13573
13574 while (_effect2 !== null) {
13575 {
13576 setCurrentFiber(_effect2);
13577 invokeGuardedCallback(null, commitPassiveHookEffects, null, _effect2);
13578
13579 if (hasCaughtError()) {
13580 if (!(_effect2 !== null)) {
13581 {
13582 throw Error( "Should be working on an effect." );
13583 }
13584 }
13585
13586 var _error5 = clearCaughtError();
13587
13588 captureCommitPhaseError(_effect2, _error5);
13589 }
13590
13591 resetCurrentFiber();
13592 }
13593
13594 var nextNextEffect = _effect2.nextEffect; // Remove nextEffect pointer to assist GC
13595
13596 _effect2.nextEffect = null;
13597 _effect2 = nextNextEffect;
13598 }
13599 }
13600
13601 {
13602 popInteractions(prevInteractions);
13603 finishPendingInteractions(root, expirationTime);
13604 }
13605
13606 executionContext = prevExecutionContext;
13607 flushSyncCallbackQueue(); // If additional passive effects were scheduled, increment a counter. If this
13608 // exceeds the limit, we'll fire a warning.
13609
13610 nestedPassiveUpdateCount = rootWithPendingPassiveEffects === null ? 0 : nestedPassiveUpdateCount + 1;
13611 return true;
13612}
13613
13614function isAlreadyFailedLegacyErrorBoundary(instance) {
13615 return legacyErrorBoundariesThatAlreadyFailed !== null && legacyErrorBoundariesThatAlreadyFailed.has(instance);
13616}
13617function markLegacyErrorBoundaryAsFailed(instance) {
13618 if (legacyErrorBoundariesThatAlreadyFailed === null) {
13619 legacyErrorBoundariesThatAlreadyFailed = new Set([instance]);
13620 } else {
13621 legacyErrorBoundariesThatAlreadyFailed.add(instance);
13622 }
13623}
13624
13625function prepareToThrowUncaughtError(error) {
13626 if (!hasUncaughtError) {
13627 hasUncaughtError = true;
13628 firstUncaughtError = error;
13629 }
13630}
13631
13632var onUncaughtError = prepareToThrowUncaughtError;
13633
13634function captureCommitPhaseErrorOnRoot(rootFiber, sourceFiber, error) {
13635 var errorInfo = createCapturedValue(error, sourceFiber);
13636 var update = createRootErrorUpdate(rootFiber, errorInfo, Sync);
13637 enqueueUpdate(rootFiber, update);
13638 var root = markUpdateTimeFromFiberToRoot(rootFiber, Sync);
13639
13640 if (root !== null) {
13641 ensureRootIsScheduled(root);
13642 schedulePendingInteractions(root, Sync);
13643 }
13644}
13645
13646function captureCommitPhaseError(sourceFiber, error) {
13647 if (sourceFiber.tag === HostRoot) {
13648 // Error was thrown at the root. There is no parent, so the root
13649 // itself should capture it.
13650 captureCommitPhaseErrorOnRoot(sourceFiber, sourceFiber, error);
13651 return;
13652 }
13653
13654 var fiber = sourceFiber.return;
13655
13656 while (fiber !== null) {
13657 if (fiber.tag === HostRoot) {
13658 captureCommitPhaseErrorOnRoot(fiber, sourceFiber, error);
13659 return;
13660 } else if (fiber.tag === ClassComponent) {
13661 var ctor = fiber.type;
13662 var instance = fiber.stateNode;
13663
13664 if (typeof ctor.getDerivedStateFromError === 'function' || typeof instance.componentDidCatch === 'function' && !isAlreadyFailedLegacyErrorBoundary(instance)) {
13665 var errorInfo = createCapturedValue(error, sourceFiber);
13666 var update = createClassErrorUpdate(fiber, errorInfo, // TODO: This is always sync
13667 Sync);
13668 enqueueUpdate(fiber, update);
13669 var root = markUpdateTimeFromFiberToRoot(fiber, Sync);
13670
13671 if (root !== null) {
13672 ensureRootIsScheduled(root);
13673 schedulePendingInteractions(root, Sync);
13674 }
13675
13676 return;
13677 }
13678 }
13679
13680 fiber = fiber.return;
13681 }
13682}
13683function pingSuspendedRoot(root, thenable, suspendedTime) {
13684 var pingCache = root.pingCache;
13685
13686 if (pingCache !== null) {
13687 // The thenable resolved, so we no longer need to memoize, because it will
13688 // never be thrown again.
13689 pingCache.delete(thenable);
13690 }
13691
13692 if (workInProgressRoot === root && renderExpirationTime$1 === suspendedTime) {
13693 // Received a ping at the same priority level at which we're currently
13694 // rendering. We might want to restart this render. This should mirror
13695 // the logic of whether or not a root suspends once it completes.
13696 // TODO: If we're rendering sync either due to Sync, Batched or expired,
13697 // we should probably never restart.
13698 // If we're suspended with delay, we'll always suspend so we can always
13699 // restart. If we're suspended without any updates, it might be a retry.
13700 // If it's early in the retry we can restart. We can't know for sure
13701 // whether we'll eventually process an update during this render pass,
13702 // but it's somewhat unlikely that we get to a ping before that, since
13703 // getting to the root most update is usually very fast.
13704 if (workInProgressRootExitStatus === RootSuspendedWithDelay || workInProgressRootExitStatus === RootSuspended && workInProgressRootLatestProcessedExpirationTime === Sync && now() - globalMostRecentFallbackTime < FALLBACK_THROTTLE_MS) {
13705 // Restart from the root. Don't need to schedule a ping because
13706 // we're already working on this tree.
13707 prepareFreshStack(root, renderExpirationTime$1);
13708 } else {
13709 // Even though we can't restart right now, we might get an
13710 // opportunity later. So we mark this render as having a ping.
13711 workInProgressRootHasPendingPing = true;
13712 }
13713
13714 return;
13715 }
13716
13717 if (!isRootSuspendedAtTime(root, suspendedTime)) {
13718 // The root is no longer suspended at this time.
13719 return;
13720 }
13721
13722 var lastPingedTime = root.lastPingedTime;
13723
13724 if (lastPingedTime !== NoWork && lastPingedTime < suspendedTime) {
13725 // There's already a lower priority ping scheduled.
13726 return;
13727 } // Mark the time at which this ping was scheduled.
13728
13729
13730 root.lastPingedTime = suspendedTime;
13731
13732 ensureRootIsScheduled(root);
13733 schedulePendingInteractions(root, suspendedTime);
13734}
13735
13736function retryTimedOutBoundary(boundaryFiber, retryTime) {
13737 // The boundary fiber (a Suspense component or SuspenseList component)
13738 // previously was rendered in its fallback state. One of the promises that
13739 // suspended it has resolved, which means at least part of the tree was
13740 // likely unblocked. Try rendering again, at a new expiration time.
13741 if (retryTime === NoWork) {
13742 var suspenseConfig = null; // Retries don't carry over the already committed update.
13743
13744 var currentTime = requestCurrentTimeForUpdate();
13745 retryTime = computeExpirationForFiber(currentTime, boundaryFiber, suspenseConfig);
13746 } // TODO: Special case idle priority?
13747
13748
13749 var root = markUpdateTimeFromFiberToRoot(boundaryFiber, retryTime);
13750
13751 if (root !== null) {
13752 ensureRootIsScheduled(root);
13753 schedulePendingInteractions(root, retryTime);
13754 }
13755}
13756function resolveRetryThenable(boundaryFiber, thenable) {
13757 var retryTime = NoWork; // Default
13758
13759 var retryCache;
13760
13761 {
13762 retryCache = boundaryFiber.stateNode;
13763 }
13764
13765 if (retryCache !== null) {
13766 // The thenable resolved, so we no longer need to memoize, because it will
13767 // never be thrown again.
13768 retryCache.delete(thenable);
13769 }
13770
13771 retryTimedOutBoundary(boundaryFiber, retryTime);
13772} // Computes the next Just Noticeable Difference (JND) boundary.
13773// The theory is that a person can't tell the difference between small differences in time.
13774// Therefore, if we wait a bit longer than necessary that won't translate to a noticeable
13775// difference in the experience. However, waiting for longer might mean that we can avoid
13776// showing an intermediate loading state. The longer we have already waited, the harder it
13777// is to tell small differences in time. Therefore, the longer we've already waited,
13778// the longer we can wait additionally. At some point we have to give up though.
13779// We pick a train model where the next boundary commits at a consistent schedule.
13780// These particular numbers are vague estimates. We expect to adjust them based on research.
13781
13782function jnd(timeElapsed) {
13783 return timeElapsed < 120 ? 120 : timeElapsed < 480 ? 480 : timeElapsed < 1080 ? 1080 : timeElapsed < 1920 ? 1920 : timeElapsed < 3000 ? 3000 : timeElapsed < 4320 ? 4320 : ceil(timeElapsed / 1960) * 1960;
13784}
13785
13786function computeMsUntilSuspenseLoadingDelay(mostRecentEventTime, committedExpirationTime, suspenseConfig) {
13787 var busyMinDurationMs = suspenseConfig.busyMinDurationMs | 0;
13788
13789 if (busyMinDurationMs <= 0) {
13790 return 0;
13791 }
13792
13793 var busyDelayMs = suspenseConfig.busyDelayMs | 0; // Compute the time until this render pass would expire.
13794
13795 var currentTimeMs = now();
13796 var eventTimeMs = inferTimeFromExpirationTimeWithSuspenseConfig(mostRecentEventTime, suspenseConfig);
13797 var timeElapsed = currentTimeMs - eventTimeMs;
13798
13799 if (timeElapsed <= busyDelayMs) {
13800 // If we haven't yet waited longer than the initial delay, we don't
13801 // have to wait any additional time.
13802 return 0;
13803 }
13804
13805 var msUntilTimeout = busyDelayMs + busyMinDurationMs - timeElapsed; // This is the value that is passed to `setTimeout`.
13806
13807 return msUntilTimeout;
13808}
13809
13810function checkForNestedUpdates() {
13811 if (nestedUpdateCount > NESTED_UPDATE_LIMIT) {
13812 nestedUpdateCount = 0;
13813 rootWithNestedUpdates = null;
13814
13815 {
13816 {
13817 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." );
13818 }
13819 }
13820 }
13821
13822 {
13823 if (nestedPassiveUpdateCount > NESTED_PASSIVE_UPDATE_LIMIT) {
13824 nestedPassiveUpdateCount = 0;
13825
13826 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.');
13827 }
13828 }
13829}
13830
13831function flushRenderPhaseStrictModeWarningsInDEV() {
13832 {
13833 ReactStrictModeWarnings.flushLegacyContextWarning();
13834
13835 {
13836 ReactStrictModeWarnings.flushPendingUnsafeLifecycleWarnings();
13837 }
13838 }
13839}
13840
13841function stopFinishedWorkLoopTimer() {
13842 var didCompleteRoot = true;
13843 stopWorkLoopTimer(interruptedBy, didCompleteRoot);
13844 interruptedBy = null;
13845}
13846
13847function stopInterruptedWorkLoopTimer() {
13848 // TODO: Track which fiber caused the interruption.
13849 var didCompleteRoot = false;
13850 stopWorkLoopTimer(interruptedBy, didCompleteRoot);
13851 interruptedBy = null;
13852}
13853
13854function checkForInterruption(fiberThatReceivedUpdate, updateExpirationTime) {
13855 if ( workInProgressRoot !== null && updateExpirationTime > renderExpirationTime$1) {
13856 interruptedBy = fiberThatReceivedUpdate;
13857 }
13858}
13859
13860var didWarnStateUpdateForUnmountedComponent = null;
13861
13862function warnAboutUpdateOnUnmountedFiberInDEV(fiber) {
13863 {
13864 var tag = fiber.tag;
13865
13866 if (tag !== HostRoot && tag !== ClassComponent && tag !== FunctionComponent && tag !== ForwardRef && tag !== MemoComponent && tag !== SimpleMemoComponent && tag !== Block) {
13867 // Only warn for user-defined components, not internal ones like Suspense.
13868 return;
13869 }
13870 // the problematic code almost always lies inside that component.
13871
13872
13873 var componentName = getComponentName(fiber.type) || 'ReactComponent';
13874
13875 if (didWarnStateUpdateForUnmountedComponent !== null) {
13876 if (didWarnStateUpdateForUnmountedComponent.has(componentName)) {
13877 return;
13878 }
13879
13880 didWarnStateUpdateForUnmountedComponent.add(componentName);
13881 } else {
13882 didWarnStateUpdateForUnmountedComponent = new Set([componentName]);
13883 }
13884
13885 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));
13886 }
13887}
13888
13889var beginWork$1;
13890
13891{
13892 var dummyFiber = null;
13893
13894 beginWork$1 = function (current, unitOfWork, expirationTime) {
13895 // If a component throws an error, we replay it again in a synchronously
13896 // dispatched event, so that the debugger will treat it as an uncaught
13897 // error See ReactErrorUtils for more information.
13898 // Before entering the begin phase, copy the work-in-progress onto a dummy
13899 // fiber. If beginWork throws, we'll use this to reset the state.
13900 var originalWorkInProgressCopy = assignFiberPropertiesInDEV(dummyFiber, unitOfWork);
13901
13902 try {
13903 return beginWork(current, unitOfWork, expirationTime);
13904 } catch (originalError) {
13905 if (originalError !== null && typeof originalError === 'object' && typeof originalError.then === 'function') {
13906 // Don't replay promises. Treat everything else like an error.
13907 throw originalError;
13908 } // Keep this code in sync with handleError; any changes here must have
13909 // corresponding changes there.
13910
13911
13912 resetContextDependencies();
13913 resetHooksAfterThrow(); // Don't reset current debug fiber, since we're about to work on the
13914 // same fiber again.
13915 // Unwind the failed stack frame
13916
13917 unwindInterruptedWork(unitOfWork); // Restore the original properties of the fiber.
13918
13919 assignFiberPropertiesInDEV(unitOfWork, originalWorkInProgressCopy);
13920
13921 if ( unitOfWork.mode & ProfileMode) {
13922 // Reset the profiler timer.
13923 startProfilerTimer(unitOfWork);
13924 } // Run beginWork again.
13925
13926
13927 invokeGuardedCallback(null, beginWork, null, current, unitOfWork, expirationTime);
13928
13929 if (hasCaughtError()) {
13930 var replayError = clearCaughtError(); // `invokeGuardedCallback` sometimes sets an expando `_suppressLogging`.
13931 // Rethrow this error instead of the original one.
13932
13933 throw replayError;
13934 } else {
13935 // This branch is reachable if the render phase is impure.
13936 throw originalError;
13937 }
13938 }
13939 };
13940}
13941
13942var didWarnAboutUpdateInRender = false;
13943var didWarnAboutUpdateInRenderForAnotherComponent;
13944
13945{
13946 didWarnAboutUpdateInRenderForAnotherComponent = new Set();
13947}
13948
13949function warnAboutRenderPhaseUpdatesInDEV(fiber) {
13950 {
13951 if (isRendering && (executionContext & RenderContext) !== NoContext) {
13952 switch (fiber.tag) {
13953 case FunctionComponent:
13954 case ForwardRef:
13955 case SimpleMemoComponent:
13956 {
13957 var renderingComponentName = workInProgress && getComponentName(workInProgress.type) || 'Unknown'; // Dedupe by the rendering component because it's the one that needs to be fixed.
13958
13959 var dedupeKey = renderingComponentName;
13960
13961 if (!didWarnAboutUpdateInRenderForAnotherComponent.has(dedupeKey)) {
13962 didWarnAboutUpdateInRenderForAnotherComponent.add(dedupeKey);
13963 var setStateComponentName = getComponentName(fiber.type) || 'Unknown';
13964
13965 error('Cannot update a component (`%s`) while rendering a ' + 'different component (`%s`). To locate the bad setState() call inside `%s`, ' + 'follow the stack trace as described in https://fb.me/setstate-in-render', setStateComponentName, renderingComponentName, renderingComponentName);
13966 }
13967
13968 break;
13969 }
13970
13971 case ClassComponent:
13972 {
13973 if (!didWarnAboutUpdateInRender) {
13974 error('Cannot update during an existing state transition (such as ' + 'within `render`). Render methods should be a pure ' + 'function of props and state.');
13975
13976 didWarnAboutUpdateInRender = true;
13977 }
13978
13979 break;
13980 }
13981 }
13982 }
13983 }
13984} // a 'shared' variable that changes when act() opens/closes in tests.
13985
13986
13987var IsThisRendererActing = {
13988 current: false
13989};
13990
13991var didWarnAboutUnmockedScheduler = false; // TODO Before we release concurrent mode, revisit this and decide whether a mocked
13992// scheduler is the actual recommendation. The alternative could be a testing build,
13993// a new lib, or whatever; we dunno just yet. This message is for early adopters
13994// to get their tests right.
13995
13996function warnIfUnmockedScheduler(fiber) {
13997 {
13998 if (didWarnAboutUnmockedScheduler === false && Scheduler.unstable_flushAllWithoutAsserting === undefined) {
13999 if (fiber.mode & BlockingMode || fiber.mode & ConcurrentMode) {
14000 didWarnAboutUnmockedScheduler = true;
14001
14002 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');
14003 }
14004 }
14005 }
14006}
14007
14008function computeThreadID(root, expirationTime) {
14009 // Interaction threads are unique per root and expiration time.
14010 return expirationTime * 1000 + root.interactionThreadID;
14011}
14012
14013function markSpawnedWork(expirationTime) {
14014
14015 if (spawnedWorkDuringRender === null) {
14016 spawnedWorkDuringRender = [expirationTime];
14017 } else {
14018 spawnedWorkDuringRender.push(expirationTime);
14019 }
14020}
14021
14022function scheduleInteractions(root, expirationTime, interactions) {
14023
14024 if (interactions.size > 0) {
14025 var pendingInteractionMap = root.pendingInteractionMap;
14026 var pendingInteractions = pendingInteractionMap.get(expirationTime);
14027
14028 if (pendingInteractions != null) {
14029 interactions.forEach(function (interaction) {
14030 if (!pendingInteractions.has(interaction)) {
14031 // Update the pending async work count for previously unscheduled interaction.
14032 interaction.__count++;
14033 }
14034
14035 pendingInteractions.add(interaction);
14036 });
14037 } else {
14038 pendingInteractionMap.set(expirationTime, new Set(interactions)); // Update the pending async work count for the current interactions.
14039
14040 interactions.forEach(function (interaction) {
14041 interaction.__count++;
14042 });
14043 }
14044
14045 var subscriber = tracing.__subscriberRef.current;
14046
14047 if (subscriber !== null) {
14048 var threadID = computeThreadID(root, expirationTime);
14049 subscriber.onWorkScheduled(interactions, threadID);
14050 }
14051 }
14052}
14053
14054function schedulePendingInteractions(root, expirationTime) {
14055
14056 scheduleInteractions(root, expirationTime, tracing.__interactionsRef.current);
14057}
14058
14059function startWorkOnPendingInteractions(root, expirationTime) {
14060 // we can accurately attribute time spent working on it, And so that cascading
14061 // work triggered during the render phase will be associated with it.
14062
14063
14064 var interactions = new Set();
14065 root.pendingInteractionMap.forEach(function (scheduledInteractions, scheduledExpirationTime) {
14066 if (scheduledExpirationTime >= expirationTime) {
14067 scheduledInteractions.forEach(function (interaction) {
14068 return interactions.add(interaction);
14069 });
14070 }
14071 }); // Store the current set of interactions on the FiberRoot for a few reasons:
14072 // We can re-use it in hot functions like performConcurrentWorkOnRoot()
14073 // without having to recalculate it. We will also use it in commitWork() to
14074 // pass to any Profiler onRender() hooks. This also provides DevTools with a
14075 // way to access it when the onCommitRoot() hook is called.
14076
14077 root.memoizedInteractions = interactions;
14078
14079 if (interactions.size > 0) {
14080 var subscriber = tracing.__subscriberRef.current;
14081
14082 if (subscriber !== null) {
14083 var threadID = computeThreadID(root, expirationTime);
14084
14085 try {
14086 subscriber.onWorkStarted(interactions, threadID);
14087 } catch (error) {
14088 // If the subscriber throws, rethrow it in a separate task
14089 scheduleCallback(ImmediatePriority, function () {
14090 throw error;
14091 });
14092 }
14093 }
14094 }
14095}
14096
14097function finishPendingInteractions(root, committedExpirationTime) {
14098
14099 var earliestRemainingTimeAfterCommit = root.firstPendingTime;
14100 var subscriber;
14101
14102 try {
14103 subscriber = tracing.__subscriberRef.current;
14104
14105 if (subscriber !== null && root.memoizedInteractions.size > 0) {
14106 var threadID = computeThreadID(root, committedExpirationTime);
14107 subscriber.onWorkStopped(root.memoizedInteractions, threadID);
14108 }
14109 } catch (error) {
14110 // If the subscriber throws, rethrow it in a separate task
14111 scheduleCallback(ImmediatePriority, function () {
14112 throw error;
14113 });
14114 } finally {
14115 // Clear completed interactions from the pending Map.
14116 // Unless the render was suspended or cascading work was scheduled,
14117 // In which case– leave pending interactions until the subsequent render.
14118 var pendingInteractionMap = root.pendingInteractionMap;
14119 pendingInteractionMap.forEach(function (scheduledInteractions, scheduledExpirationTime) {
14120 // Only decrement the pending interaction count if we're done.
14121 // If there's still work at the current priority,
14122 // That indicates that we are waiting for suspense data.
14123 if (scheduledExpirationTime > earliestRemainingTimeAfterCommit) {
14124 pendingInteractionMap.delete(scheduledExpirationTime);
14125 scheduledInteractions.forEach(function (interaction) {
14126 interaction.__count--;
14127
14128 if (subscriber !== null && interaction.__count === 0) {
14129 try {
14130 subscriber.onInteractionScheduledWorkCompleted(interaction);
14131 } catch (error) {
14132 // If the subscriber throws, rethrow it in a separate task
14133 scheduleCallback(ImmediatePriority, function () {
14134 throw error;
14135 });
14136 }
14137 }
14138 });
14139 }
14140 });
14141 }
14142}
14143
14144var onScheduleFiberRoot = null;
14145var onCommitFiberRoot = null;
14146var onCommitFiberUnmount = null;
14147var hasLoggedError = false;
14148var isDevToolsPresent = typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ !== 'undefined';
14149function injectInternals(internals) {
14150 if (typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ === 'undefined') {
14151 // No DevTools
14152 return false;
14153 }
14154
14155 var hook = __REACT_DEVTOOLS_GLOBAL_HOOK__;
14156
14157 if (hook.isDisabled) {
14158 // This isn't a real property on the hook, but it can be set to opt out
14159 // of DevTools integration and associated warnings and logs.
14160 // https://github.com/facebook/react/issues/3877
14161 return true;
14162 }
14163
14164 if (!hook.supportsFiber) {
14165 {
14166 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');
14167 } // DevTools exists, even though it doesn't support Fiber.
14168
14169
14170 return true;
14171 }
14172
14173 try {
14174 var rendererID = hook.inject(internals); // We have successfully injected, so now it is safe to set up hooks.
14175
14176 if (true) {
14177 // Only used by Fast Refresh
14178 if (typeof hook.onScheduleFiberRoot === 'function') {
14179 onScheduleFiberRoot = function (root, children) {
14180 try {
14181 hook.onScheduleFiberRoot(rendererID, root, children);
14182 } catch (err) {
14183 if (true && !hasLoggedError) {
14184 hasLoggedError = true;
14185
14186 error('React instrumentation encountered an error: %s', err);
14187 }
14188 }
14189 };
14190 }
14191 }
14192
14193 onCommitFiberRoot = function (root, expirationTime) {
14194 try {
14195 var didError = (root.current.effectTag & DidCapture) === DidCapture;
14196
14197 if (enableProfilerTimer) {
14198 var currentTime = getCurrentTime();
14199 var priorityLevel = inferPriorityFromExpirationTime(currentTime, expirationTime);
14200 hook.onCommitFiberRoot(rendererID, root, priorityLevel, didError);
14201 } else {
14202 hook.onCommitFiberRoot(rendererID, root, undefined, didError);
14203 }
14204 } catch (err) {
14205 if (true) {
14206 if (!hasLoggedError) {
14207 hasLoggedError = true;
14208
14209 error('React instrumentation encountered an error: %s', err);
14210 }
14211 }
14212 }
14213 };
14214
14215 onCommitFiberUnmount = function (fiber) {
14216 try {
14217 hook.onCommitFiberUnmount(rendererID, fiber);
14218 } catch (err) {
14219 if (true) {
14220 if (!hasLoggedError) {
14221 hasLoggedError = true;
14222
14223 error('React instrumentation encountered an error: %s', err);
14224 }
14225 }
14226 }
14227 };
14228 } catch (err) {
14229 // Catch all errors because it is unsafe to throw during initialization.
14230 {
14231 error('React instrumentation encountered an error: %s.', err);
14232 }
14233 } // DevTools exists
14234
14235
14236 return true;
14237}
14238function onScheduleRoot(root, children) {
14239 if (typeof onScheduleFiberRoot === 'function') {
14240 onScheduleFiberRoot(root, children);
14241 }
14242}
14243function onCommitRoot(root, expirationTime) {
14244 if (typeof onCommitFiberRoot === 'function') {
14245 onCommitFiberRoot(root, expirationTime);
14246 }
14247}
14248function onCommitUnmount(fiber) {
14249 if (typeof onCommitFiberUnmount === 'function') {
14250 onCommitFiberUnmount(fiber);
14251 }
14252}
14253
14254var hasBadMapPolyfill;
14255
14256{
14257 hasBadMapPolyfill = false;
14258
14259 try {
14260 var nonExtensibleObject = Object.preventExtensions({});
14261 var testMap = new Map([[nonExtensibleObject, null]]);
14262 var testSet = new Set([nonExtensibleObject]); // This is necessary for Rollup to not consider these unused.
14263 // https://github.com/rollup/rollup/issues/1771
14264 // TODO: we can remove these if Rollup fixes the bug.
14265
14266 testMap.set(0, 0);
14267 testSet.add(0);
14268 } catch (e) {
14269 // TODO: Consider warning about bad polyfills
14270 hasBadMapPolyfill = true;
14271 }
14272}
14273
14274var debugCounter = 1;
14275
14276function FiberNode(tag, pendingProps, key, mode) {
14277 // Instance
14278 this.tag = tag;
14279 this.key = key;
14280 this.elementType = null;
14281 this.type = null;
14282 this.stateNode = null; // Fiber
14283
14284 this.return = null;
14285 this.child = null;
14286 this.sibling = null;
14287 this.index = 0;
14288 this.ref = null;
14289 this.pendingProps = pendingProps;
14290 this.memoizedProps = null;
14291 this.updateQueue = null;
14292 this.memoizedState = null;
14293 this.dependencies = null;
14294 this.mode = mode; // Effects
14295
14296 this.effectTag = NoEffect;
14297 this.nextEffect = null;
14298 this.firstEffect = null;
14299 this.lastEffect = null;
14300 this.expirationTime = NoWork;
14301 this.childExpirationTime = NoWork;
14302 this.alternate = null;
14303
14304 {
14305 // Note: The following is done to avoid a v8 performance cliff.
14306 //
14307 // Initializing the fields below to smis and later updating them with
14308 // double values will cause Fibers to end up having separate shapes.
14309 // This behavior/bug has something to do with Object.preventExtension().
14310 // Fortunately this only impacts DEV builds.
14311 // Unfortunately it makes React unusably slow for some applications.
14312 // To work around this, initialize the fields below with doubles.
14313 //
14314 // Learn more about this here:
14315 // https://github.com/facebook/react/issues/14365
14316 // https://bugs.chromium.org/p/v8/issues/detail?id=8538
14317 this.actualDuration = Number.NaN;
14318 this.actualStartTime = Number.NaN;
14319 this.selfBaseDuration = Number.NaN;
14320 this.treeBaseDuration = Number.NaN; // It's okay to replace the initial doubles with smis after initialization.
14321 // This won't trigger the performance cliff mentioned above,
14322 // and it simplifies other profiler code (including DevTools).
14323
14324 this.actualDuration = 0;
14325 this.actualStartTime = -1;
14326 this.selfBaseDuration = 0;
14327 this.treeBaseDuration = 0;
14328 } // This is normally DEV-only except www when it adds listeners.
14329 // TODO: remove the User Timing integration in favor of Root Events.
14330
14331
14332 {
14333 this._debugID = debugCounter++;
14334 this._debugIsCurrentlyTiming = false;
14335 }
14336
14337 {
14338 this._debugSource = null;
14339 this._debugOwner = null;
14340 this._debugNeedsRemount = false;
14341 this._debugHookTypes = null;
14342
14343 if (!hasBadMapPolyfill && typeof Object.preventExtensions === 'function') {
14344 Object.preventExtensions(this);
14345 }
14346 }
14347} // This is a constructor function, rather than a POJO constructor, still
14348// please ensure we do the following:
14349// 1) Nobody should add any instance methods on this. Instance methods can be
14350// more difficult to predict when they get optimized and they are almost
14351// never inlined properly in static compilers.
14352// 2) Nobody should rely on `instanceof Fiber` for type testing. We should
14353// always know when it is a fiber.
14354// 3) We might want to experiment with using numeric keys since they are easier
14355// to optimize in a non-JIT environment.
14356// 4) We can easily go from a constructor to a createFiber object literal if that
14357// is faster.
14358// 5) It should be easy to port this to a C struct and keep a C implementation
14359// compatible.
14360
14361
14362var createFiber = function (tag, pendingProps, key, mode) {
14363 // $FlowFixMe: the shapes are exact here but Flow doesn't like constructors
14364 return new FiberNode(tag, pendingProps, key, mode);
14365};
14366
14367function shouldConstruct(Component) {
14368 var prototype = Component.prototype;
14369 return !!(prototype && prototype.isReactComponent);
14370}
14371
14372function isSimpleFunctionComponent(type) {
14373 return typeof type === 'function' && !shouldConstruct(type) && type.defaultProps === undefined;
14374}
14375function resolveLazyComponentTag(Component) {
14376 if (typeof Component === 'function') {
14377 return shouldConstruct(Component) ? ClassComponent : FunctionComponent;
14378 } else if (Component !== undefined && Component !== null) {
14379 var $$typeof = Component.$$typeof;
14380
14381 if ($$typeof === REACT_FORWARD_REF_TYPE) {
14382 return ForwardRef;
14383 }
14384
14385 if ($$typeof === REACT_MEMO_TYPE) {
14386 return MemoComponent;
14387 }
14388 }
14389
14390 return IndeterminateComponent;
14391} // This is used to create an alternate fiber to do work on.
14392
14393function createWorkInProgress(current, pendingProps) {
14394 var workInProgress = current.alternate;
14395
14396 if (workInProgress === null) {
14397 // We use a double buffering pooling technique because we know that we'll
14398 // only ever need at most two versions of a tree. We pool the "other" unused
14399 // node that we're free to reuse. This is lazily created to avoid allocating
14400 // extra objects for things that are never updated. It also allow us to
14401 // reclaim the extra memory if needed.
14402 workInProgress = createFiber(current.tag, pendingProps, current.key, current.mode);
14403 workInProgress.elementType = current.elementType;
14404 workInProgress.type = current.type;
14405 workInProgress.stateNode = current.stateNode;
14406
14407 {
14408 // DEV-only fields
14409 {
14410 workInProgress._debugID = current._debugID;
14411 }
14412
14413 workInProgress._debugSource = current._debugSource;
14414 workInProgress._debugOwner = current._debugOwner;
14415 workInProgress._debugHookTypes = current._debugHookTypes;
14416 }
14417
14418 workInProgress.alternate = current;
14419 current.alternate = workInProgress;
14420 } else {
14421 workInProgress.pendingProps = pendingProps; // We already have an alternate.
14422 // Reset the effect tag.
14423
14424 workInProgress.effectTag = NoEffect; // The effect list is no longer valid.
14425
14426 workInProgress.nextEffect = null;
14427 workInProgress.firstEffect = null;
14428 workInProgress.lastEffect = null;
14429
14430 {
14431 // We intentionally reset, rather than copy, actualDuration & actualStartTime.
14432 // This prevents time from endlessly accumulating in new commits.
14433 // This has the downside of resetting values for different priority renders,
14434 // But works for yielding (the common case) and should support resuming.
14435 workInProgress.actualDuration = 0;
14436 workInProgress.actualStartTime = -1;
14437 }
14438 }
14439
14440 workInProgress.childExpirationTime = current.childExpirationTime;
14441 workInProgress.expirationTime = current.expirationTime;
14442 workInProgress.child = current.child;
14443 workInProgress.memoizedProps = current.memoizedProps;
14444 workInProgress.memoizedState = current.memoizedState;
14445 workInProgress.updateQueue = current.updateQueue; // Clone the dependencies object. This is mutated during the render phase, so
14446 // it cannot be shared with the current fiber.
14447
14448 var currentDependencies = current.dependencies;
14449 workInProgress.dependencies = currentDependencies === null ? null : {
14450 expirationTime: currentDependencies.expirationTime,
14451 firstContext: currentDependencies.firstContext,
14452 responders: currentDependencies.responders
14453 }; // These will be overridden during the parent's reconciliation
14454
14455 workInProgress.sibling = current.sibling;
14456 workInProgress.index = current.index;
14457 workInProgress.ref = current.ref;
14458
14459 {
14460 workInProgress.selfBaseDuration = current.selfBaseDuration;
14461 workInProgress.treeBaseDuration = current.treeBaseDuration;
14462 }
14463
14464 {
14465 workInProgress._debugNeedsRemount = current._debugNeedsRemount;
14466
14467 switch (workInProgress.tag) {
14468 case IndeterminateComponent:
14469 case FunctionComponent:
14470 case SimpleMemoComponent:
14471 workInProgress.type = resolveFunctionForHotReloading(current.type);
14472 break;
14473
14474 case ClassComponent:
14475 workInProgress.type = resolveClassForHotReloading(current.type);
14476 break;
14477
14478 case ForwardRef:
14479 workInProgress.type = resolveForwardRefForHotReloading(current.type);
14480 break;
14481 }
14482 }
14483
14484 return workInProgress;
14485} // Used to reuse a Fiber for a second pass.
14486
14487function resetWorkInProgress(workInProgress, renderExpirationTime) {
14488 // This resets the Fiber to what createFiber or createWorkInProgress would
14489 // have set the values to before during the first pass. Ideally this wouldn't
14490 // be necessary but unfortunately many code paths reads from the workInProgress
14491 // when they should be reading from current and writing to workInProgress.
14492 // We assume pendingProps, index, key, ref, return are still untouched to
14493 // avoid doing another reconciliation.
14494 // Reset the effect tag but keep any Placement tags, since that's something
14495 // that child fiber is setting, not the reconciliation.
14496 workInProgress.effectTag &= Placement; // The effect list is no longer valid.
14497
14498 workInProgress.nextEffect = null;
14499 workInProgress.firstEffect = null;
14500 workInProgress.lastEffect = null;
14501 var current = workInProgress.alternate;
14502
14503 if (current === null) {
14504 // Reset to createFiber's initial values.
14505 workInProgress.childExpirationTime = NoWork;
14506 workInProgress.expirationTime = renderExpirationTime;
14507 workInProgress.child = null;
14508 workInProgress.memoizedProps = null;
14509 workInProgress.memoizedState = null;
14510 workInProgress.updateQueue = null;
14511 workInProgress.dependencies = null;
14512
14513 {
14514 // Note: We don't reset the actualTime counts. It's useful to accumulate
14515 // actual time across multiple render passes.
14516 workInProgress.selfBaseDuration = 0;
14517 workInProgress.treeBaseDuration = 0;
14518 }
14519 } else {
14520 // Reset to the cloned values that createWorkInProgress would've.
14521 workInProgress.childExpirationTime = current.childExpirationTime;
14522 workInProgress.expirationTime = current.expirationTime;
14523 workInProgress.child = current.child;
14524 workInProgress.memoizedProps = current.memoizedProps;
14525 workInProgress.memoizedState = current.memoizedState;
14526 workInProgress.updateQueue = current.updateQueue; // Clone the dependencies object. This is mutated during the render phase, so
14527 // it cannot be shared with the current fiber.
14528
14529 var currentDependencies = current.dependencies;
14530 workInProgress.dependencies = currentDependencies === null ? null : {
14531 expirationTime: currentDependencies.expirationTime,
14532 firstContext: currentDependencies.firstContext,
14533 responders: currentDependencies.responders
14534 };
14535
14536 {
14537 // Note: We don't reset the actualTime counts. It's useful to accumulate
14538 // actual time across multiple render passes.
14539 workInProgress.selfBaseDuration = current.selfBaseDuration;
14540 workInProgress.treeBaseDuration = current.treeBaseDuration;
14541 }
14542 }
14543
14544 return workInProgress;
14545}
14546function createHostRootFiber(tag) {
14547 var mode;
14548
14549 if (tag === ConcurrentRoot) {
14550 mode = ConcurrentMode | BlockingMode | StrictMode;
14551 } else if (tag === BlockingRoot) {
14552 mode = BlockingMode | StrictMode;
14553 } else {
14554 mode = NoMode;
14555 }
14556
14557 if ( isDevToolsPresent) {
14558 // Always collect profile timings when DevTools are present.
14559 // This enables DevTools to start capturing timing at any point–
14560 // Without some nodes in the tree having empty base times.
14561 mode |= ProfileMode;
14562 }
14563
14564 return createFiber(HostRoot, null, null, mode);
14565}
14566function createFiberFromTypeAndProps(type, // React$ElementType
14567key, pendingProps, owner, mode, expirationTime) {
14568 var fiber;
14569 var fiberTag = IndeterminateComponent; // The resolved type is set if we know what the final type will be. I.e. it's not lazy.
14570
14571 var resolvedType = type;
14572
14573 if (typeof type === 'function') {
14574 if (shouldConstruct(type)) {
14575 fiberTag = ClassComponent;
14576
14577 {
14578 resolvedType = resolveClassForHotReloading(resolvedType);
14579 }
14580 } else {
14581 {
14582 resolvedType = resolveFunctionForHotReloading(resolvedType);
14583 }
14584 }
14585 } else if (typeof type === 'string') {
14586 fiberTag = HostComponent;
14587 } else {
14588 getTag: switch (type) {
14589 case REACT_FRAGMENT_TYPE:
14590 return createFiberFromFragment(pendingProps.children, mode, expirationTime, key);
14591
14592 case REACT_CONCURRENT_MODE_TYPE:
14593 fiberTag = Mode;
14594 mode |= ConcurrentMode | BlockingMode | StrictMode;
14595 break;
14596
14597 case REACT_STRICT_MODE_TYPE:
14598 fiberTag = Mode;
14599 mode |= StrictMode;
14600 break;
14601
14602 case REACT_PROFILER_TYPE:
14603 return createFiberFromProfiler(pendingProps, mode, expirationTime, key);
14604
14605 case REACT_SUSPENSE_TYPE:
14606 return createFiberFromSuspense(pendingProps, mode, expirationTime, key);
14607
14608 case REACT_SUSPENSE_LIST_TYPE:
14609 return createFiberFromSuspenseList(pendingProps, mode, expirationTime, key);
14610
14611 default:
14612 {
14613 if (typeof type === 'object' && type !== null) {
14614 switch (type.$$typeof) {
14615 case REACT_PROVIDER_TYPE:
14616 fiberTag = ContextProvider;
14617 break getTag;
14618
14619 case REACT_CONTEXT_TYPE:
14620 // This is a consumer
14621 fiberTag = ContextConsumer;
14622 break getTag;
14623
14624 case REACT_FORWARD_REF_TYPE:
14625 fiberTag = ForwardRef;
14626
14627 {
14628 resolvedType = resolveForwardRefForHotReloading(resolvedType);
14629 }
14630
14631 break getTag;
14632
14633 case REACT_MEMO_TYPE:
14634 fiberTag = MemoComponent;
14635 break getTag;
14636
14637 case REACT_LAZY_TYPE:
14638 fiberTag = LazyComponent;
14639 resolvedType = null;
14640 break getTag;
14641
14642 case REACT_BLOCK_TYPE:
14643 fiberTag = Block;
14644 break getTag;
14645
14646 }
14647 }
14648
14649 var info = '';
14650
14651 {
14652 if (type === undefined || typeof type === 'object' && type !== null && Object.keys(type).length === 0) {
14653 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.';
14654 }
14655
14656 var ownerName = owner ? getComponentName(owner.type) : null;
14657
14658 if (ownerName) {
14659 info += '\n\nCheck the render method of `' + ownerName + '`.';
14660 }
14661 }
14662
14663 {
14664 {
14665 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 );
14666 }
14667 }
14668 }
14669 }
14670 }
14671
14672 fiber = createFiber(fiberTag, pendingProps, key, mode);
14673 fiber.elementType = type;
14674 fiber.type = resolvedType;
14675 fiber.expirationTime = expirationTime;
14676 return fiber;
14677}
14678function createFiberFromElement(element, mode, expirationTime) {
14679 var owner = null;
14680
14681 {
14682 owner = element._owner;
14683 }
14684
14685 var type = element.type;
14686 var key = element.key;
14687 var pendingProps = element.props;
14688 var fiber = createFiberFromTypeAndProps(type, key, pendingProps, owner, mode, expirationTime);
14689
14690 {
14691 fiber._debugSource = element._source;
14692 fiber._debugOwner = element._owner;
14693 }
14694
14695 return fiber;
14696}
14697function createFiberFromFragment(elements, mode, expirationTime, key) {
14698 var fiber = createFiber(Fragment, elements, key, mode);
14699 fiber.expirationTime = expirationTime;
14700 return fiber;
14701}
14702
14703function createFiberFromProfiler(pendingProps, mode, expirationTime, key) {
14704 {
14705 if (typeof pendingProps.id !== 'string' || typeof pendingProps.onRender !== 'function') {
14706 error('Profiler must specify an "id" string and "onRender" function as props');
14707 }
14708 }
14709
14710 var fiber = createFiber(Profiler, pendingProps, key, mode | ProfileMode); // TODO: The Profiler fiber shouldn't have a type. It has a tag.
14711
14712 fiber.elementType = REACT_PROFILER_TYPE;
14713 fiber.type = REACT_PROFILER_TYPE;
14714 fiber.expirationTime = expirationTime;
14715 return fiber;
14716}
14717
14718function createFiberFromSuspense(pendingProps, mode, expirationTime, key) {
14719 var fiber = createFiber(SuspenseComponent, pendingProps, key, mode); // TODO: The SuspenseComponent fiber shouldn't have a type. It has a tag.
14720 // This needs to be fixed in getComponentName so that it relies on the tag
14721 // instead.
14722
14723 fiber.type = REACT_SUSPENSE_TYPE;
14724 fiber.elementType = REACT_SUSPENSE_TYPE;
14725 fiber.expirationTime = expirationTime;
14726 return fiber;
14727}
14728function createFiberFromSuspenseList(pendingProps, mode, expirationTime, key) {
14729 var fiber = createFiber(SuspenseListComponent, pendingProps, key, mode);
14730
14731 {
14732 // TODO: The SuspenseListComponent fiber shouldn't have a type. It has a tag.
14733 // This needs to be fixed in getComponentName so that it relies on the tag
14734 // instead.
14735 fiber.type = REACT_SUSPENSE_LIST_TYPE;
14736 }
14737
14738 fiber.elementType = REACT_SUSPENSE_LIST_TYPE;
14739 fiber.expirationTime = expirationTime;
14740 return fiber;
14741}
14742function createFiberFromText(content, mode, expirationTime) {
14743 var fiber = createFiber(HostText, content, null, mode);
14744 fiber.expirationTime = expirationTime;
14745 return fiber;
14746}
14747function createFiberFromPortal(portal, mode, expirationTime) {
14748 var pendingProps = portal.children !== null ? portal.children : [];
14749 var fiber = createFiber(HostPortal, pendingProps, portal.key, mode);
14750 fiber.expirationTime = expirationTime;
14751 fiber.stateNode = {
14752 containerInfo: portal.containerInfo,
14753 pendingChildren: null,
14754 // Used by persistent updates
14755 implementation: portal.implementation
14756 };
14757 return fiber;
14758} // Used for stashing WIP properties to replay failed work in DEV.
14759
14760function assignFiberPropertiesInDEV(target, source) {
14761 if (target === null) {
14762 // This Fiber's initial properties will always be overwritten.
14763 // We only use a Fiber to ensure the same hidden class so DEV isn't slow.
14764 target = createFiber(IndeterminateComponent, null, null, NoMode);
14765 } // This is intentionally written as a list of all properties.
14766 // We tried to use Object.assign() instead but this is called in
14767 // the hottest path, and Object.assign() was too slow:
14768 // https://github.com/facebook/react/issues/12502
14769 // This code is DEV-only so size is not a concern.
14770
14771
14772 target.tag = source.tag;
14773 target.key = source.key;
14774 target.elementType = source.elementType;
14775 target.type = source.type;
14776 target.stateNode = source.stateNode;
14777 target.return = source.return;
14778 target.child = source.child;
14779 target.sibling = source.sibling;
14780 target.index = source.index;
14781 target.ref = source.ref;
14782 target.pendingProps = source.pendingProps;
14783 target.memoizedProps = source.memoizedProps;
14784 target.updateQueue = source.updateQueue;
14785 target.memoizedState = source.memoizedState;
14786 target.dependencies = source.dependencies;
14787 target.mode = source.mode;
14788 target.effectTag = source.effectTag;
14789 target.nextEffect = source.nextEffect;
14790 target.firstEffect = source.firstEffect;
14791 target.lastEffect = source.lastEffect;
14792 target.expirationTime = source.expirationTime;
14793 target.childExpirationTime = source.childExpirationTime;
14794 target.alternate = source.alternate;
14795
14796 {
14797 target.actualDuration = source.actualDuration;
14798 target.actualStartTime = source.actualStartTime;
14799 target.selfBaseDuration = source.selfBaseDuration;
14800 target.treeBaseDuration = source.treeBaseDuration;
14801 }
14802
14803 {
14804 target._debugID = source._debugID;
14805 }
14806
14807 target._debugSource = source._debugSource;
14808 target._debugOwner = source._debugOwner;
14809 target._debugIsCurrentlyTiming = source._debugIsCurrentlyTiming;
14810 target._debugNeedsRemount = source._debugNeedsRemount;
14811 target._debugHookTypes = source._debugHookTypes;
14812 return target;
14813}
14814
14815function FiberRootNode(containerInfo, tag, hydrate) {
14816 this.tag = tag;
14817 this.current = null;
14818 this.containerInfo = containerInfo;
14819 this.pendingChildren = null;
14820 this.pingCache = null;
14821 this.finishedExpirationTime = NoWork;
14822 this.finishedWork = null;
14823 this.timeoutHandle = noTimeout;
14824 this.context = null;
14825 this.pendingContext = null;
14826 this.hydrate = hydrate;
14827 this.callbackNode = null;
14828 this.callbackPriority = NoPriority;
14829 this.firstPendingTime = NoWork;
14830 this.firstSuspendedTime = NoWork;
14831 this.lastSuspendedTime = NoWork;
14832 this.nextKnownPendingLevel = NoWork;
14833 this.lastPingedTime = NoWork;
14834 this.lastExpiredTime = NoWork;
14835
14836 {
14837 this.interactionThreadID = tracing.unstable_getThreadID();
14838 this.memoizedInteractions = new Set();
14839 this.pendingInteractionMap = new Map();
14840 }
14841}
14842
14843function createFiberRoot(containerInfo, tag, hydrate, hydrationCallbacks) {
14844 var root = new FiberRootNode(containerInfo, tag, hydrate);
14845 // stateNode is any.
14846
14847
14848 var uninitializedFiber = createHostRootFiber(tag);
14849 root.current = uninitializedFiber;
14850 uninitializedFiber.stateNode = root;
14851 initializeUpdateQueue(uninitializedFiber);
14852 return root;
14853}
14854function isRootSuspendedAtTime(root, expirationTime) {
14855 var firstSuspendedTime = root.firstSuspendedTime;
14856 var lastSuspendedTime = root.lastSuspendedTime;
14857 return firstSuspendedTime !== NoWork && firstSuspendedTime >= expirationTime && lastSuspendedTime <= expirationTime;
14858}
14859function markRootSuspendedAtTime(root, expirationTime) {
14860 var firstSuspendedTime = root.firstSuspendedTime;
14861 var lastSuspendedTime = root.lastSuspendedTime;
14862
14863 if (firstSuspendedTime < expirationTime) {
14864 root.firstSuspendedTime = expirationTime;
14865 }
14866
14867 if (lastSuspendedTime > expirationTime || firstSuspendedTime === NoWork) {
14868 root.lastSuspendedTime = expirationTime;
14869 }
14870
14871 if (expirationTime <= root.lastPingedTime) {
14872 root.lastPingedTime = NoWork;
14873 }
14874
14875 if (expirationTime <= root.lastExpiredTime) {
14876 root.lastExpiredTime = NoWork;
14877 }
14878}
14879function markRootUpdatedAtTime(root, expirationTime) {
14880 // Update the range of pending times
14881 var firstPendingTime = root.firstPendingTime;
14882
14883 if (expirationTime > firstPendingTime) {
14884 root.firstPendingTime = expirationTime;
14885 } // Update the range of suspended times. Treat everything lower priority or
14886 // equal to this update as unsuspended.
14887
14888
14889 var firstSuspendedTime = root.firstSuspendedTime;
14890
14891 if (firstSuspendedTime !== NoWork) {
14892 if (expirationTime >= firstSuspendedTime) {
14893 // The entire suspended range is now unsuspended.
14894 root.firstSuspendedTime = root.lastSuspendedTime = root.nextKnownPendingLevel = NoWork;
14895 } else if (expirationTime >= root.lastSuspendedTime) {
14896 root.lastSuspendedTime = expirationTime + 1;
14897 } // This is a pending level. Check if it's higher priority than the next
14898 // known pending level.
14899
14900
14901 if (expirationTime > root.nextKnownPendingLevel) {
14902 root.nextKnownPendingLevel = expirationTime;
14903 }
14904 }
14905}
14906function markRootFinishedAtTime(root, finishedExpirationTime, remainingExpirationTime) {
14907 // Update the range of pending times
14908 root.firstPendingTime = remainingExpirationTime; // Update the range of suspended times. Treat everything higher priority or
14909 // equal to this update as unsuspended.
14910
14911 if (finishedExpirationTime <= root.lastSuspendedTime) {
14912 // The entire suspended range is now unsuspended.
14913 root.firstSuspendedTime = root.lastSuspendedTime = root.nextKnownPendingLevel = NoWork;
14914 } else if (finishedExpirationTime <= root.firstSuspendedTime) {
14915 // Part of the suspended range is now unsuspended. Narrow the range to
14916 // include everything between the unsuspended time (non-inclusive) and the
14917 // last suspended time.
14918 root.firstSuspendedTime = finishedExpirationTime - 1;
14919 }
14920
14921 if (finishedExpirationTime <= root.lastPingedTime) {
14922 // Clear the pinged time
14923 root.lastPingedTime = NoWork;
14924 }
14925
14926 if (finishedExpirationTime <= root.lastExpiredTime) {
14927 // Clear the expired time
14928 root.lastExpiredTime = NoWork;
14929 }
14930}
14931function markRootExpiredAtTime(root, expirationTime) {
14932 var lastExpiredTime = root.lastExpiredTime;
14933
14934 if (lastExpiredTime === NoWork || lastExpiredTime > expirationTime) {
14935 root.lastExpiredTime = expirationTime;
14936 }
14937}
14938
14939var didWarnAboutNestedUpdates;
14940
14941{
14942 didWarnAboutNestedUpdates = false;
14943}
14944
14945function getContextForSubtree(parentComponent) {
14946 if (!parentComponent) {
14947 return emptyContextObject;
14948 }
14949
14950 var fiber = get(parentComponent);
14951 var parentContext = findCurrentUnmaskedContext(fiber);
14952
14953 if (fiber.tag === ClassComponent) {
14954 var Component = fiber.type;
14955
14956 if (isContextProvider(Component)) {
14957 return processChildContext(fiber, Component, parentContext);
14958 }
14959 }
14960
14961 return parentContext;
14962}
14963
14964function createContainer(containerInfo, tag, hydrate, hydrationCallbacks) {
14965 return createFiberRoot(containerInfo, tag, hydrate);
14966}
14967function updateContainer(element, container, parentComponent, callback) {
14968 {
14969 onScheduleRoot(container, element);
14970 }
14971
14972 var current$1 = container.current;
14973 var currentTime = requestCurrentTimeForUpdate();
14974
14975 {
14976 // $FlowExpectedError - jest isn't a global, and isn't recognized outside of tests
14977 if ('undefined' !== typeof jest) {
14978 warnIfUnmockedScheduler(current$1);
14979 }
14980 }
14981
14982 var suspenseConfig = requestCurrentSuspenseConfig();
14983 var expirationTime = computeExpirationForFiber(currentTime, current$1, suspenseConfig);
14984 var context = getContextForSubtree(parentComponent);
14985
14986 if (container.context === null) {
14987 container.context = context;
14988 } else {
14989 container.pendingContext = context;
14990 }
14991
14992 {
14993 if (isRendering && current !== null && !didWarnAboutNestedUpdates) {
14994 didWarnAboutNestedUpdates = true;
14995
14996 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');
14997 }
14998 }
14999
15000 var update = createUpdate(expirationTime, suspenseConfig); // Caution: React DevTools currently depends on this property
15001 // being called "element".
15002
15003 update.payload = {
15004 element: element
15005 };
15006 callback = callback === undefined ? null : callback;
15007
15008 if (callback !== null) {
15009 {
15010 if (typeof callback !== 'function') {
15011 error('render(...): Expected the last optional `callback` argument to be a ' + 'function. Instead received: %s.', callback);
15012 }
15013 }
15014
15015 update.callback = callback;
15016 }
15017
15018 enqueueUpdate(current$1, update);
15019 scheduleWork(current$1, expirationTime);
15020 return expirationTime;
15021}
15022
15023var shouldSuspendImpl = function (fiber) {
15024 return false;
15025};
15026
15027function shouldSuspend(fiber) {
15028 return shouldSuspendImpl(fiber);
15029}
15030var overrideHookState = null;
15031var overrideProps = null;
15032var scheduleUpdate = null;
15033var setSuspenseHandler = null;
15034
15035{
15036 var copyWithSetImpl = function (obj, path, idx, value) {
15037 if (idx >= path.length) {
15038 return value;
15039 }
15040
15041 var key = path[idx];
15042 var updated = Array.isArray(obj) ? obj.slice() : _assign({}, obj); // $FlowFixMe number or string is fine here
15043
15044 updated[key] = copyWithSetImpl(obj[key], path, idx + 1, value);
15045 return updated;
15046 };
15047
15048 var copyWithSet = function (obj, path, value) {
15049 return copyWithSetImpl(obj, path, 0, value);
15050 }; // Support DevTools editable values for useState and useReducer.
15051
15052
15053 overrideHookState = function (fiber, id, path, value) {
15054 // For now, the "id" of stateful hooks is just the stateful hook index.
15055 // This may change in the future with e.g. nested hooks.
15056 var currentHook = fiber.memoizedState;
15057
15058 while (currentHook !== null && id > 0) {
15059 currentHook = currentHook.next;
15060 id--;
15061 }
15062
15063 if (currentHook !== null) {
15064 var newState = copyWithSet(currentHook.memoizedState, path, value);
15065 currentHook.memoizedState = newState;
15066 currentHook.baseState = newState; // We aren't actually adding an update to the queue,
15067 // because there is no update we can add for useReducer hooks that won't trigger an error.
15068 // (There's no appropriate action type for DevTools overrides.)
15069 // As a result though, React will see the scheduled update as a noop and bailout.
15070 // Shallow cloning props works as a workaround for now to bypass the bailout check.
15071
15072 fiber.memoizedProps = _assign({}, fiber.memoizedProps);
15073 scheduleWork(fiber, Sync);
15074 }
15075 }; // Support DevTools props for function components, forwardRef, memo, host components, etc.
15076
15077
15078 overrideProps = function (fiber, path, value) {
15079 fiber.pendingProps = copyWithSet(fiber.memoizedProps, path, value);
15080
15081 if (fiber.alternate) {
15082 fiber.alternate.pendingProps = fiber.pendingProps;
15083 }
15084
15085 scheduleWork(fiber, Sync);
15086 };
15087
15088 scheduleUpdate = function (fiber) {
15089 scheduleWork(fiber, Sync);
15090 };
15091
15092 setSuspenseHandler = function (newShouldSuspendImpl) {
15093 shouldSuspendImpl = newShouldSuspendImpl;
15094 };
15095}
15096
15097function injectIntoDevTools(devToolsConfig) {
15098 var findFiberByHostInstance = devToolsConfig.findFiberByHostInstance;
15099 var ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher;
15100 return injectInternals(_assign({}, devToolsConfig, {
15101 overrideHookState: overrideHookState,
15102 overrideProps: overrideProps,
15103 setSuspenseHandler: setSuspenseHandler,
15104 scheduleUpdate: scheduleUpdate,
15105 currentDispatcherRef: ReactCurrentDispatcher,
15106 findHostInstanceByFiber: function (fiber) {
15107 var hostFiber = findCurrentHostFiber(fiber);
15108
15109 if (hostFiber === null) {
15110 return null;
15111 }
15112
15113 return hostFiber.stateNode;
15114 },
15115 findFiberByHostInstance: function (instance) {
15116 if (!findFiberByHostInstance) {
15117 // Might not be implemented by the renderer.
15118 return null;
15119 }
15120
15121 return findFiberByHostInstance(instance);
15122 },
15123 // React Refresh
15124 findHostInstancesForRefresh: findHostInstancesForRefresh ,
15125 scheduleRefresh: scheduleRefresh ,
15126 scheduleRoot: scheduleRoot ,
15127 setRefreshHandler: setRefreshHandler ,
15128 // Enables DevTools to append owner stacks to error messages in DEV mode.
15129 getCurrentFiber: function () {
15130 return current;
15131 }
15132 }));
15133}
15134var IsSomeRendererActing$1 = ReactSharedInternals.IsSomeRendererActing;
15135
15136Mode$1.setCurrent( // Change to 'art/modes/dom' for easier debugging via SVG
15137FastNoSideEffects);
15138/** Declarative fill-type objects; API design not finalized */
15139
15140var slice = Array.prototype.slice;
15141
15142var LinearGradient =
15143/*#__PURE__*/
15144function () {
15145 function LinearGradient(stops, x1, y1, x2, y2) {
15146 this._args = slice.call(arguments);
15147 }
15148
15149 var _proto = LinearGradient.prototype;
15150
15151 _proto.applyFill = function applyFill(node) {
15152 node.fillLinear.apply(node, this._args);
15153 };
15154
15155 return LinearGradient;
15156}();
15157
15158var RadialGradient =
15159/*#__PURE__*/
15160function () {
15161 function RadialGradient(stops, fx, fy, rx, ry, cx, cy) {
15162 this._args = slice.call(arguments);
15163 }
15164
15165 var _proto2 = RadialGradient.prototype;
15166
15167 _proto2.applyFill = function applyFill(node) {
15168 node.fillRadial.apply(node, this._args);
15169 };
15170
15171 return RadialGradient;
15172}();
15173
15174var Pattern =
15175/*#__PURE__*/
15176function () {
15177 function Pattern(url, width, height, left, top) {
15178 this._args = slice.call(arguments);
15179 }
15180
15181 var _proto3 = Pattern.prototype;
15182
15183 _proto3.applyFill = function applyFill(node) {
15184 node.fillImage.apply(node, this._args);
15185 };
15186
15187 return Pattern;
15188}();
15189/** React Components */
15190
15191
15192var Surface =
15193/*#__PURE__*/
15194function (_React$Component) {
15195 _inheritsLoose(Surface, _React$Component);
15196
15197 function Surface() {
15198 return _React$Component.apply(this, arguments) || this;
15199 }
15200
15201 var _proto4 = Surface.prototype;
15202
15203 _proto4.componentDidMount = function componentDidMount() {
15204 var _this$props = this.props,
15205 height = _this$props.height,
15206 width = _this$props.width;
15207 this._surface = Mode$1.Surface(+width, +height, this._tagRef);
15208 this._mountNode = createContainer(this._surface, LegacyRoot, false);
15209 updateContainer(this.props.children, this._mountNode, this);
15210 };
15211
15212 _proto4.componentDidUpdate = function componentDidUpdate(prevProps, prevState) {
15213 var props = this.props;
15214
15215 if (props.height !== prevProps.height || props.width !== prevProps.width) {
15216 this._surface.resize(+props.width, +props.height);
15217 }
15218
15219 updateContainer(this.props.children, this._mountNode, this);
15220
15221 if (this._surface.render) {
15222 this._surface.render();
15223 }
15224 };
15225
15226 _proto4.componentWillUnmount = function componentWillUnmount() {
15227 updateContainer(null, this._mountNode, this);
15228 };
15229
15230 _proto4.render = function render() {
15231 var _this = this;
15232
15233 // This is going to be a placeholder because we don't know what it will
15234 // actually resolve to because ART may render canvas, vml or svg tags here.
15235 // We only allow a subset of properties since others might conflict with
15236 // ART's properties.
15237 var props = this.props; // TODO: ART's Canvas Mode overrides surface title and cursor
15238
15239 var Tag = Mode$1.Surface.tagName;
15240 return React.createElement(Tag, {
15241 ref: function (ref) {
15242 return _this._tagRef = ref;
15243 },
15244 accessKey: props.accessKey,
15245 className: props.className,
15246 draggable: props.draggable,
15247 role: props.role,
15248 style: props.style,
15249 tabIndex: props.tabIndex,
15250 title: props.title
15251 });
15252 };
15253
15254 return Surface;
15255}(React.Component);
15256
15257var Text =
15258/*#__PURE__*/
15259function (_React$Component2) {
15260 _inheritsLoose(Text, _React$Component2);
15261
15262 function Text(props) {
15263 var _this2;
15264
15265 _this2 = _React$Component2.call(this, props) || this; // We allow reading these props. Ideally we could expose the Text node as
15266 // ref directly.
15267
15268 ['height', 'width', 'x', 'y'].forEach(function (key) {
15269 Object.defineProperty(_assertThisInitialized(_this2), key, {
15270 get: function () {
15271 return this._text ? this._text[key] : undefined;
15272 }
15273 });
15274 });
15275 return _this2;
15276 }
15277
15278 var _proto5 = Text.prototype;
15279
15280 _proto5.render = function render() {
15281 var _this3 = this;
15282
15283 // This means you can't have children that render into strings...
15284 var T = TYPES.TEXT;
15285 return React.createElement(T, _extends({}, this.props, {
15286 ref: function (t) {
15287 return _this3._text = t;
15288 }
15289 }), childrenAsString(this.props.children));
15290 };
15291
15292 return Text;
15293}(React.Component);
15294
15295injectIntoDevTools({
15296 findFiberByHostInstance: function () {
15297 return null;
15298 },
15299 bundleType: 1 ,
15300 version: ReactVersion,
15301 rendererPackageName: 'react-art'
15302});
15303/** API */
15304
15305var ClippingRectangle = TYPES.CLIPPING_RECTANGLE;
15306var Group = TYPES.GROUP;
15307var Shape = TYPES.SHAPE;
15308var Path = Mode$1.Path;
15309
15310var ReactART = /*#__PURE__*/Object.freeze({
15311 __proto__: null,
15312 ClippingRectangle: ClippingRectangle,
15313 Group: Group,
15314 Shape: Shape,
15315 Path: Path,
15316 LinearGradient: LinearGradient,
15317 Pattern: Pattern,
15318 RadialGradient: RadialGradient,
15319 Surface: Surface,
15320 Text: Text,
15321 Transform: Transform
15322});
15323
15324var reactArt = ReactART;
15325
15326module.exports = reactArt;
15327 })();
15328}