UNPKG

1.28 MBJavaScriptView Raw
1/**
2 * @license React
3 * react-dom-client.development.js
4 *
5 * Copyright (c) Meta Platforms, Inc. and affiliates.
6 *
7 * This source code is licensed under the MIT license found in the
8 * LICENSE file in the root directory of this source tree.
9 */
10
11'use strict';
12
13if (process.env.NODE_ENV !== "production") {
14 (function() {
15
16 'use strict';
17
18/* global __REACT_DEVTOOLS_GLOBAL_HOOK__ */
19if (
20 typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ !== 'undefined' &&
21 typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart ===
22 'function'
23) {
24 __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart(new Error());
25}
26 var React = require('react');
27var Scheduler = require('scheduler');
28var ReactDOM = require('react-dom');
29
30var ReactSharedInternals = React.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE;
31
32var suppressWarning = false;
33function setSuppressWarning(newSuppressWarning) {
34 {
35 suppressWarning = newSuppressWarning;
36 }
37} // In DEV, calls to console.warn and console.error get replaced
38// by calls to these methods by a Babel plugin.
39//
40// In PROD (or in packages without access to React internals),
41// they are left as they are instead.
42
43function warn(format) {
44 {
45 if (!suppressWarning) {
46 for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
47 args[_key - 1] = arguments[_key];
48 }
49
50 printWarning('warn', format, args);
51 }
52 }
53}
54function error(format) {
55 {
56 if (!suppressWarning) {
57 for (var _len2 = arguments.length, args = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {
58 args[_key2 - 1] = arguments[_key2];
59 }
60
61 printWarning('error', format, args);
62 }
63 }
64}
65
66function printWarning(level, format, args) {
67 // When changing this logic, you might want to also
68 // update consoleWithStackDev.www.js as well.
69 {
70 var stack = ReactSharedInternals.getStackAddendum();
71
72 if (stack !== '') {
73 format += '%s';
74 args = args.concat([stack]);
75 } // eslint-disable-next-line react-internal/safe-string-coercion
76
77
78 var argsWithFormat = args.map(function (item) {
79 return String(item);
80 }); // Careful: RN currently depends on this prefix
81
82 argsWithFormat.unshift('Warning: ' + format); // We intentionally don't use spread (or .apply) directly because it
83 // breaks IE9: https://github.com/facebook/react/issues/13610
84 // eslint-disable-next-line react-internal/no-production-logging
85
86 Function.prototype.apply.call(console[level], console, argsWithFormat);
87 }
88}
89
90// -----------------------------------------------------------------------------
91// Killswitch
92//
93// Flags that exist solely to turn off a change in case it causes a regression
94// when it rolls out to prod. We should remove these as soon as possible.
95// -----------------------------------------------------------------------------
96// -----------------------------------------------------------------------------
97// Land or remove (moderate effort)
98//
99// Flags that can be probably deleted or landed, but might require extra effort
100// like migrating internal callers or performance testing.
101// -----------------------------------------------------------------------------
102// TODO: Finish rolling out in www
103
104var favorSafetyOverHydrationPerf = true;
105var enableAsyncActions = true; // Need to remove didTimeout argument from Scheduler before landing
106
107var disableDefaultPropsExceptForClasses = true; // -----------------------------------------------------------------------------
108// Slated for removal in the future (significant effort)
109//
110// These are experiments that didn't work out, and never shipped, but we can't
111// delete from the codebase until we migrate internal callers.
112// -----------------------------------------------------------------------------
113// Add a callback property to suspense to notify which promises are currently
114// in the update queue. This allows reporting and tracing of what is causing
115// the user to see a loading state.
116//
117// Also allows hydration callbacks to fire when a dehydrated boundary gets
118// hydrated or deleted.
119//
120// This will eventually be replaced by the Transition Tracing proposal.
121
122var enableSuspenseCallback = false; // Experimental Scope support.
123var enableAsyncIterableChildren = false;
124
125var enableLazyContextPropagation = false; // FB-only usage. The new API has different semantics.
126
127var enableLegacyHidden = false; // Enables unstable_avoidThisFallback feature in Fiber
128var alwaysThrottleRetries = true;
129var syncLaneExpirationMs = 250;
130var transitionLaneExpirationMs = 5000; // -----------------------------------------------------------------------------
131// Remove IE and MsApp specific workarounds for innerHTML
132
133var disableIEWorkarounds = true; // Filter certain DOM attributes (e.g. src, href) if their values are empty
134// This allows us to land breaking changes to remove legacy mode APIs in experimental builds
135// before removing them in stable in the next Major
136
137var disableLegacyMode = true;
138// React DOM Chopping Block
139//
140// Similar to main Chopping Block but only flags related to React DOM. These are
141// grouped because we will likely batch all of them into a single major release.
142// -----------------------------------------------------------------------------
143// Disable support for comment nodes as React DOM containers. Already disabled
144// in open source, but www codebase still relies on it. Need to remove.
145
146var disableCommentsAsDOMContainers = true;
147// Debugging and DevTools
148// -----------------------------------------------------------------------------
149// Adds user timing marks for e.g. state updates, suspense, and work loop stuff,
150// for an experimental timeline tool.
151
152var enableSchedulingProfiler = true; // Helps identify side effects in render-phase lifecycle hooks and setState
153
154var enableProfilerTimer = true; // Record durations for commit and passive effects phases.
155
156var enableProfilerCommitHooks = true; // Phase param passed to onRender callback differentiates between an "update" and a "cascading-update".
157
158var enableProfilerNestedUpdatePhase = true; // Adds verbose console logging for e.g. state updates, suspense, and work loop
159
160/**
161 * HTML nodeType values that represent the type of the node
162 */
163var ELEMENT_NODE = 1;
164var TEXT_NODE = 3;
165var COMMENT_NODE = 8;
166var DOCUMENT_NODE = 9;
167var DOCUMENT_TYPE_NODE = 10;
168var DOCUMENT_FRAGMENT_NODE = 11;
169
170function isValidContainer(node) {
171 return !!(node && (node.nodeType === ELEMENT_NODE || node.nodeType === DOCUMENT_NODE || node.nodeType === DOCUMENT_FRAGMENT_NODE || !disableCommentsAsDOMContainers ));
172} // TODO: Remove this function which also includes comment nodes.
173
174/**
175 * `ReactInstanceMap` maintains a mapping from a public facing stateful
176 * instance (key) and the internal representation (value). This allows public
177 * methods to accept the user facing instance as an argument and map them back
178 * to internal methods.
179 *
180 * Note that this module is currently shared and assumed to be stateless.
181 * If this becomes an actual Map, that will break.
182 */
183function get(key) {
184 return key._reactInternals;
185}
186function set(key, value) {
187 key._reactInternals = value;
188}
189
190var FunctionComponent = 0;
191var ClassComponent = 1;
192var HostRoot = 3; // Root of a host tree. Could be nested inside another node.
193
194var HostPortal = 4; // A subtree. Could be an entry point to a different renderer.
195
196var HostComponent = 5;
197var HostText = 6;
198var Fragment = 7;
199var Mode = 8;
200var ContextConsumer = 9;
201var ContextProvider = 10;
202var ForwardRef = 11;
203var Profiler = 12;
204var SuspenseComponent = 13;
205var MemoComponent = 14;
206var SimpleMemoComponent = 15;
207var LazyComponent = 16;
208var IncompleteClassComponent = 17;
209var DehydratedFragment = 18;
210var SuspenseListComponent = 19;
211var ScopeComponent = 21;
212var OffscreenComponent = 22;
213var LegacyHiddenComponent = 23;
214var CacheComponent = 24;
215var TracingMarkerComponent = 25;
216var HostHoistable = 26;
217var HostSingleton = 27;
218var IncompleteFunctionComponent = 28;
219
220// When adding new symbols to this file,
221// Please consider also adding to 'react-devtools-shared/src/backend/ReactSymbols'
222// The Symbol used to tag the ReactElement-like types.
223
224var REACT_LEGACY_ELEMENT_TYPE = Symbol.for('react.element');
225var REACT_ELEMENT_TYPE = Symbol.for('react.transitional.element') ;
226var REACT_PORTAL_TYPE = Symbol.for('react.portal');
227var REACT_FRAGMENT_TYPE = Symbol.for('react.fragment');
228var REACT_STRICT_MODE_TYPE = Symbol.for('react.strict_mode');
229var REACT_PROFILER_TYPE = Symbol.for('react.profiler');
230var REACT_PROVIDER_TYPE = Symbol.for('react.provider'); // TODO: Delete with enableRenderableContext
231
232var REACT_CONSUMER_TYPE = Symbol.for('react.consumer');
233var REACT_CONTEXT_TYPE = Symbol.for('react.context');
234var REACT_FORWARD_REF_TYPE = Symbol.for('react.forward_ref');
235var REACT_SUSPENSE_TYPE = Symbol.for('react.suspense');
236var REACT_SUSPENSE_LIST_TYPE = Symbol.for('react.suspense_list');
237var REACT_MEMO_TYPE = Symbol.for('react.memo');
238var REACT_LAZY_TYPE = Symbol.for('react.lazy');
239var REACT_SCOPE_TYPE = Symbol.for('react.scope');
240var REACT_DEBUG_TRACING_MODE_TYPE = Symbol.for('react.debug_trace_mode');
241var REACT_OFFSCREEN_TYPE = Symbol.for('react.offscreen');
242var REACT_LEGACY_HIDDEN_TYPE = Symbol.for('react.legacy_hidden');
243var REACT_TRACING_MARKER_TYPE = Symbol.for('react.tracing_marker');
244var MAYBE_ITERATOR_SYMBOL = Symbol.iterator;
245var FAUX_ITERATOR_SYMBOL = '@@iterator';
246function getIteratorFn(maybeIterable) {
247 if (maybeIterable === null || typeof maybeIterable !== 'object') {
248 return null;
249 }
250
251 var maybeIterator = MAYBE_ITERATOR_SYMBOL && maybeIterable[MAYBE_ITERATOR_SYMBOL] || maybeIterable[FAUX_ITERATOR_SYMBOL];
252
253 if (typeof maybeIterator === 'function') {
254 return maybeIterator;
255 }
256
257 return null;
258}
259
260function getWrappedName$1(outerType, innerType, wrapperName) {
261 var displayName = outerType.displayName;
262
263 if (displayName) {
264 return displayName;
265 }
266
267 var functionName = innerType.displayName || innerType.name || '';
268 return functionName !== '' ? wrapperName + "(" + functionName + ")" : wrapperName;
269} // Keep in sync with react-reconciler/getComponentNameFromFiber
270
271
272function getContextName$1(type) {
273 return type.displayName || 'Context';
274}
275
276var REACT_CLIENT_REFERENCE = Symbol.for('react.client.reference'); // Note that the reconciler package should generally prefer to use getComponentNameFromFiber() instead.
277
278function getComponentNameFromType(type) {
279 if (type == null) {
280 // Host root, text node or just invalid type.
281 return null;
282 }
283
284 if (typeof type === 'function') {
285 if (type.$$typeof === REACT_CLIENT_REFERENCE) {
286 // TODO: Create a convention for naming client references with debug info.
287 return null;
288 }
289
290 return type.displayName || type.name || null;
291 }
292
293 if (typeof type === 'string') {
294 return type;
295 }
296
297 switch (type) {
298 case REACT_FRAGMENT_TYPE:
299 return 'Fragment';
300
301 case REACT_PORTAL_TYPE:
302 return 'Portal';
303
304 case REACT_PROFILER_TYPE:
305 return 'Profiler';
306
307 case REACT_STRICT_MODE_TYPE:
308 return 'StrictMode';
309
310 case REACT_SUSPENSE_TYPE:
311 return 'Suspense';
312
313 case REACT_SUSPENSE_LIST_TYPE:
314 return 'SuspenseList';
315
316 }
317
318 if (typeof type === 'object') {
319 {
320 if (typeof type.tag === 'number') {
321 error('Received an unexpected object in getComponentNameFromType(). ' + 'This is likely a bug in React. Please file an issue.');
322 }
323 }
324
325 switch (type.$$typeof) {
326 case REACT_PROVIDER_TYPE:
327 {
328 return null;
329 }
330
331 case REACT_CONTEXT_TYPE:
332 var context = type;
333
334 {
335 return getContextName$1(context) + '.Provider';
336 }
337
338 case REACT_CONSUMER_TYPE:
339 {
340 var consumer = type;
341 return getContextName$1(consumer._context) + '.Consumer';
342 }
343
344 case REACT_FORWARD_REF_TYPE:
345 return getWrappedName$1(type, type.render, 'ForwardRef');
346
347 case REACT_MEMO_TYPE:
348 var outerName = type.displayName || null;
349
350 if (outerName !== null) {
351 return outerName;
352 }
353
354 return getComponentNameFromType(type.type) || 'Memo';
355
356 case REACT_LAZY_TYPE:
357 {
358 var lazyComponent = type;
359 var payload = lazyComponent._payload;
360 var init = lazyComponent._init;
361
362 try {
363 return getComponentNameFromType(init(payload));
364 } catch (x) {
365 return null;
366 }
367 }
368 }
369 }
370
371 return null;
372}
373
374function getWrappedName(outerType, innerType, wrapperName) {
375 var functionName = innerType.displayName || innerType.name || '';
376 return outerType.displayName || (functionName !== '' ? wrapperName + "(" + functionName + ")" : wrapperName);
377} // Keep in sync with shared/getComponentNameFromType
378
379
380function getContextName(type) {
381 return type.displayName || 'Context';
382}
383
384function getComponentNameFromOwner(owner) {
385 if (typeof owner.tag === 'number') {
386 return getComponentNameFromFiber(owner);
387 }
388
389 if (typeof owner.name === 'string') {
390 return owner.name;
391 }
392
393 return null;
394}
395function getComponentNameFromFiber(fiber) {
396 var tag = fiber.tag,
397 type = fiber.type;
398
399 switch (tag) {
400 case CacheComponent:
401 return 'Cache';
402
403 case ContextConsumer:
404 {
405 var consumer = type;
406 return getContextName(consumer._context) + '.Consumer';
407 }
408
409 case ContextProvider:
410 {
411 var _context = type;
412 return getContextName(_context) + '.Provider';
413 }
414
415 case DehydratedFragment:
416 return 'DehydratedFragment';
417
418 case ForwardRef:
419 return getWrappedName(type, type.render, 'ForwardRef');
420
421 case Fragment:
422 return 'Fragment';
423
424 case HostHoistable:
425 case HostSingleton:
426 case HostComponent:
427 // Host component type is the display name (e.g. "div", "View")
428 return type;
429
430 case HostPortal:
431 return 'Portal';
432
433 case HostRoot:
434 return 'Root';
435
436 case HostText:
437 return 'Text';
438
439 case LazyComponent:
440 // Name comes from the type in this case; we don't have a tag.
441 return getComponentNameFromType(type);
442
443 case Mode:
444 if (type === REACT_STRICT_MODE_TYPE) {
445 // Don't be less specific than shared/getComponentNameFromType
446 return 'StrictMode';
447 }
448
449 return 'Mode';
450
451 case OffscreenComponent:
452 return 'Offscreen';
453
454 case Profiler:
455 return 'Profiler';
456
457 case ScopeComponent:
458 return 'Scope';
459
460 case SuspenseComponent:
461 return 'Suspense';
462
463 case SuspenseListComponent:
464 return 'SuspenseList';
465
466 case TracingMarkerComponent:
467 return 'TracingMarker';
468 // The display name for these tags come from the user-provided type:
469
470 case IncompleteClassComponent:
471 case IncompleteFunctionComponent:
472 {
473 break;
474 }
475
476 // Fallthrough
477
478 case ClassComponent:
479 case FunctionComponent:
480 case MemoComponent:
481 case SimpleMemoComponent:
482 if (typeof type === 'function') {
483 return type.displayName || type.name || null;
484 }
485
486 if (typeof type === 'string') {
487 return type;
488 }
489
490 break;
491
492 }
493
494 return null;
495}
496
497var NoFlags$1 =
498/* */
4990;
500var PerformedWork =
501/* */
5021;
503var Placement =
504/* */
5052;
506var DidCapture =
507/* */
508128;
509var Hydrating =
510/* */
5114096; // You can change the rest (and add more).
512
513var Update =
514/* */
5154;
516/* Skipped value: 0b0000000000000000000000001000; */
517
518var ChildDeletion =
519/* */
52016;
521var ContentReset =
522/* */
52332;
524var Callback =
525/* */
52664;
527/* Used by DidCapture: 0b0000000000000000000010000000; */
528
529var ForceClientRender =
530/* */
531256;
532var Ref =
533/* */
534512;
535var Snapshot =
536/* */
5371024;
538var Passive$1 =
539/* */
5402048;
541/* Used by Hydrating: 0b0000000000000001000000000000; */
542
543var Visibility =
544/* */
5458192;
546var StoreConsistency =
547/* */
54816384; // It's OK to reuse these bits because these flags are mutually exclusive for
549// different fiber types. We should really be doing this for as many flags as
550// possible, because we're about to run out of bits.
551
552var ScheduleRetry = StoreConsistency;
553var ShouldSuspendCommit = Visibility;
554var DidDefer = ContentReset;
555var FormReset = Snapshot;
556
557var HostEffectMask =
558/* */
55932767; // These are not really side effects, but we still reuse this field.
560
561var Incomplete =
562/* */
56332768;
564var ShouldCapture =
565/* */
56665536;
567var ForceUpdateForLegacySuspense =
568/* */
569131072;
570var Forked =
571/* */
5721048576; // Static tags describe aspects of a fiber that are not specific to a render,
573// e.g. a fiber uses a passive effect (even if there are no updates on this particular render).
574// This enables us to defer more work in the unmount case,
575// since we can defer traversing the tree during layout to look for Passive effects,
576// and instead rely on the static flag as a signal that there may be cleanup work.
577
578var RefStatic =
579/* */
5802097152;
581var LayoutStatic =
582/* */
5834194304;
584var PassiveStatic =
585/* */
5868388608;
587var MaySuspendCommit =
588/* */
58916777216; // Flag used to identify newly inserted fibers. It isn't reset after commit unlike `Placement`.
590
591var PlacementDEV =
592/* */
59333554432;
594var MountLayoutDev =
595/* */
59667108864;
597var MountPassiveDev =
598/* */
599134217728; // Groups of flags that are used in the commit phase to skip over trees that
600// don't contain effects, by checking subtreeFlags.
601
602var BeforeMutationMask = // TODO: Remove Update flag from before mutation phase by re-landing Visibility
603// flag logic (see #20043)
604Update | Snapshot | (0);
605var MutationMask = Placement | Update | ChildDeletion | ContentReset | Ref | Hydrating | Visibility | FormReset;
606var LayoutMask = Update | Callback | Ref | Visibility; // TODO: Split into PassiveMountMask and PassiveUnmountMask
607
608var PassiveMask = Passive$1 | Visibility | ChildDeletion; // Union of tags that don't get reset on clones.
609// This allows certain concepts to persist without recalculating them,
610// e.g. whether a subtree contains passive effects or portals.
611
612var StaticMask = LayoutStatic | PassiveStatic | RefStatic | MaySuspendCommit;
613
614var currentOwner = null;
615function setCurrentOwner(fiber) {
616 currentOwner = fiber;
617}
618
619function getNearestMountedFiber(fiber) {
620 var node = fiber;
621 var nearestMounted = fiber;
622
623 if (!fiber.alternate) {
624 // If there is no alternate, this might be a new tree that isn't inserted
625 // yet. If it is, then it will have a pending insertion effect on it.
626 var nextNode = node;
627
628 do {
629 node = nextNode;
630
631 if ((node.flags & (Placement | Hydrating)) !== NoFlags$1) {
632 // This is an insertion or in-progress hydration. The nearest possible
633 // mounted fiber is the parent but we need to continue to figure out
634 // if that one is still mounted.
635 nearestMounted = node.return;
636 } // $FlowFixMe[incompatible-type] we bail out when we get a null
637
638
639 nextNode = node.return;
640 } while (nextNode);
641 } else {
642 while (node.return) {
643 node = node.return;
644 }
645 }
646
647 if (node.tag === HostRoot) {
648 // TODO: Check if this was a nested HostRoot when used with
649 // renderContainerIntoSubtree.
650 return nearestMounted;
651 } // If we didn't hit the root, that means that we're in an disconnected tree
652 // that has been unmounted.
653
654
655 return null;
656}
657function getSuspenseInstanceFromFiber(fiber) {
658 if (fiber.tag === SuspenseComponent) {
659 var suspenseState = fiber.memoizedState;
660
661 if (suspenseState === null) {
662 var current = fiber.alternate;
663
664 if (current !== null) {
665 suspenseState = current.memoizedState;
666 }
667 }
668
669 if (suspenseState !== null) {
670 return suspenseState.dehydrated;
671 }
672 }
673
674 return null;
675}
676function getContainerFromFiber(fiber) {
677 return fiber.tag === HostRoot ? fiber.stateNode.containerInfo : null;
678}
679function isMounted(component) {
680 {
681 var owner = currentOwner;
682
683 if (owner !== null && owner.tag === ClassComponent) {
684 var ownerFiber = owner;
685 var instance = ownerFiber.stateNode;
686
687 if (!instance._warnedAboutRefsInRender) {
688 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.', getComponentNameFromFiber(ownerFiber) || 'A component');
689 }
690
691 instance._warnedAboutRefsInRender = true;
692 }
693 }
694
695 var fiber = get(component);
696
697 if (!fiber) {
698 return false;
699 }
700
701 return getNearestMountedFiber(fiber) === fiber;
702}
703
704function assertIsMounted(fiber) {
705 if (getNearestMountedFiber(fiber) !== fiber) {
706 throw new Error('Unable to find node on an unmounted component.');
707 }
708}
709
710function findCurrentFiberUsingSlowPath(fiber) {
711 var alternate = fiber.alternate;
712
713 if (!alternate) {
714 // If there is no alternate, then we only need to check if it is mounted.
715 var nearestMounted = getNearestMountedFiber(fiber);
716
717 if (nearestMounted === null) {
718 throw new Error('Unable to find node on an unmounted component.');
719 }
720
721 if (nearestMounted !== fiber) {
722 return null;
723 }
724
725 return fiber;
726 } // If we have two possible branches, we'll walk backwards up to the root
727 // to see what path the root points to. On the way we may hit one of the
728 // special cases and we'll deal with them.
729
730
731 var a = fiber;
732 var b = alternate;
733
734 while (true) {
735 var parentA = a.return;
736
737 if (parentA === null) {
738 // We're at the root.
739 break;
740 }
741
742 var parentB = parentA.alternate;
743
744 if (parentB === null) {
745 // There is no alternate. This is an unusual case. Currently, it only
746 // happens when a Suspense component is hidden. An extra fragment fiber
747 // is inserted in between the Suspense fiber and its children. Skip
748 // over this extra fragment fiber and proceed to the next parent.
749 var nextParent = parentA.return;
750
751 if (nextParent !== null) {
752 a = b = nextParent;
753 continue;
754 } // If there's no parent, we're at the root.
755
756
757 break;
758 } // If both copies of the parent fiber point to the same child, we can
759 // assume that the child is current. This happens when we bailout on low
760 // priority: the bailed out fiber's child reuses the current child.
761
762
763 if (parentA.child === parentB.child) {
764 var child = parentA.child;
765
766 while (child) {
767 if (child === a) {
768 // We've determined that A is the current branch.
769 assertIsMounted(parentA);
770 return fiber;
771 }
772
773 if (child === b) {
774 // We've determined that B is the current branch.
775 assertIsMounted(parentA);
776 return alternate;
777 }
778
779 child = child.sibling;
780 } // We should never have an alternate for any mounting node. So the only
781 // way this could possibly happen is if this was unmounted, if at all.
782
783
784 throw new Error('Unable to find node on an unmounted component.');
785 }
786
787 if (a.return !== b.return) {
788 // The return pointer of A and the return pointer of B point to different
789 // fibers. We assume that return pointers never criss-cross, so A must
790 // belong to the child set of A.return, and B must belong to the child
791 // set of B.return.
792 a = parentA;
793 b = parentB;
794 } else {
795 // The return pointers point to the same fiber. We'll have to use the
796 // default, slow path: scan the child sets of each parent alternate to see
797 // which child belongs to which set.
798 //
799 // Search parent A's child set
800 var didFindChild = false;
801 var _child = parentA.child;
802
803 while (_child) {
804 if (_child === a) {
805 didFindChild = true;
806 a = parentA;
807 b = parentB;
808 break;
809 }
810
811 if (_child === b) {
812 didFindChild = true;
813 b = parentA;
814 a = parentB;
815 break;
816 }
817
818 _child = _child.sibling;
819 }
820
821 if (!didFindChild) {
822 // Search parent B's child set
823 _child = parentB.child;
824
825 while (_child) {
826 if (_child === a) {
827 didFindChild = true;
828 a = parentB;
829 b = parentA;
830 break;
831 }
832
833 if (_child === b) {
834 didFindChild = true;
835 b = parentB;
836 a = parentA;
837 break;
838 }
839
840 _child = _child.sibling;
841 }
842
843 if (!didFindChild) {
844 throw new Error('Child was not found in either parent set. This indicates a bug ' + 'in React related to the return pointer. Please file an issue.');
845 }
846 }
847 }
848
849 if (a.alternate !== b) {
850 throw new Error("Return fibers should always be each others' alternates. " + 'This error is likely caused by a bug in React. Please file an issue.');
851 }
852 } // If the root is not a host container, we're in a disconnected tree. I.e.
853 // unmounted.
854
855
856 if (a.tag !== HostRoot) {
857 throw new Error('Unable to find node on an unmounted component.');
858 }
859
860 if (a.stateNode.current === a) {
861 // We've determined that A is the current branch.
862 return fiber;
863 } // Otherwise B has to be current branch.
864
865
866 return alternate;
867}
868function findCurrentHostFiber(parent) {
869 var currentParent = findCurrentFiberUsingSlowPath(parent);
870 return currentParent !== null ? findCurrentHostFiberImpl(currentParent) : null;
871}
872
873function findCurrentHostFiberImpl(node) {
874 // Next we'll drill down this component to find the first HostComponent/Text.
875 var tag = node.tag;
876
877 if (tag === HostComponent || tag === HostHoistable || tag === HostSingleton || tag === HostText) {
878 return node;
879 }
880
881 var child = node.child;
882
883 while (child !== null) {
884 var match = findCurrentHostFiberImpl(child);
885
886 if (match !== null) {
887 return match;
888 }
889
890 child = child.sibling;
891 }
892
893 return null;
894}
895
896var assign = Object.assign;
897
898var LegacyRoot = 0;
899var ConcurrentRoot = 1;
900
901var isArrayImpl = Array.isArray; // eslint-disable-next-line no-redeclare
902
903function isArray(a) {
904 return isArrayImpl(a);
905}
906
907var ReactDOMSharedInternals = ReactDOM.__DOM_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE;
908
909// same object across all transitions.
910
911var sharedNotPendingObject = {
912 pending: false,
913 data: null,
914 method: null,
915 action: null
916};
917var NotPending = Object.freeze(sharedNotPendingObject) ;
918
919var valueStack = [];
920var fiberStack;
921
922{
923 fiberStack = [];
924}
925
926var index = -1;
927
928function createCursor(defaultValue) {
929 return {
930 current: defaultValue
931 };
932}
933
934function pop(cursor, fiber) {
935 if (index < 0) {
936 {
937 error('Unexpected pop.');
938 }
939
940 return;
941 }
942
943 {
944 if (fiber !== fiberStack[index]) {
945 error('Unexpected Fiber popped.');
946 }
947 }
948
949 cursor.current = valueStack[index];
950 valueStack[index] = null;
951
952 {
953 fiberStack[index] = null;
954 }
955
956 index--;
957}
958
959function push(cursor, value, fiber) {
960 index++;
961 valueStack[index] = cursor.current;
962
963 {
964 fiberStack[index] = fiber;
965 }
966
967 cursor.current = value;
968}
969
970var contextStackCursor = createCursor(null);
971var contextFiberStackCursor = createCursor(null);
972var rootInstanceStackCursor = createCursor(null); // Represents the nearest host transition provider (in React DOM, a <form />)
973// NOTE: Since forms cannot be nested, and this feature is only implemented by
974// React DOM, we don't technically need this to be a stack. It could be a single
975// module variable instead.
976
977var hostTransitionProviderCursor = createCursor(null); // TODO: This should initialize to NotPendingTransition, a constant
978// imported from the fiber config. However, because of a cycle in the module
979// graph, that value isn't defined during this module's initialization. I can't
980// think of a way to work around this without moving that value out of the
981// fiber config. For now, the "no provider" case is handled when reading,
982// inside useHostTransitionStatus.
983
984var HostTransitionContext = {
985 $$typeof: REACT_CONTEXT_TYPE,
986 Provider: null,
987 Consumer: null,
988 _currentValue: null,
989 _currentValue2: null,
990 _threadCount: 0
991};
992
993function requiredContext(c) {
994 {
995 if (c === null) {
996 error('Expected host context to exist. This error is likely caused by a bug ' + 'in React. Please file an issue.');
997 }
998 }
999
1000 return c;
1001}
1002
1003function getCurrentRootHostContainer() {
1004 return rootInstanceStackCursor.current;
1005}
1006
1007function getRootHostContainer() {
1008 var rootInstance = requiredContext(rootInstanceStackCursor.current);
1009 return rootInstance;
1010}
1011
1012function pushHostContainer(fiber, nextRootInstance) {
1013 // Push current root instance onto the stack;
1014 // This allows us to reset root when portals are popped.
1015 push(rootInstanceStackCursor, nextRootInstance, fiber); // Track the context and the Fiber that provided it.
1016 // This enables us to pop only Fibers that provide unique contexts.
1017
1018 push(contextFiberStackCursor, fiber, fiber); // Finally, we need to push the host context to the stack.
1019 // However, we can't just call getRootHostContext() and push it because
1020 // we'd have a different number of entries on the stack depending on
1021 // whether getRootHostContext() throws somewhere in renderer code or not.
1022 // So we push an empty value first. This lets us safely unwind on errors.
1023
1024 push(contextStackCursor, null, fiber);
1025 var nextRootContext = getRootHostContext(nextRootInstance); // Now that we know this function doesn't throw, replace it.
1026
1027 pop(contextStackCursor, fiber);
1028 push(contextStackCursor, nextRootContext, fiber);
1029}
1030
1031function popHostContainer(fiber) {
1032 pop(contextStackCursor, fiber);
1033 pop(contextFiberStackCursor, fiber);
1034 pop(rootInstanceStackCursor, fiber);
1035}
1036
1037function getHostContext() {
1038 var context = requiredContext(contextStackCursor.current);
1039 return context;
1040}
1041
1042function pushHostContext(fiber) {
1043 {
1044 var stateHook = fiber.memoizedState;
1045
1046 if (stateHook !== null) {
1047 // Only provide context if this fiber has been upgraded by a host
1048 // transition. We use the same optimization for regular host context below.
1049 push(hostTransitionProviderCursor, fiber, fiber);
1050 }
1051 }
1052
1053 var context = requiredContext(contextStackCursor.current);
1054 var nextContext = getChildHostContext(context, fiber.type); // Don't push this Fiber's context unless it's unique.
1055
1056 if (context !== nextContext) {
1057 // Track the context and the Fiber that provided it.
1058 // This enables us to pop only Fibers that provide unique contexts.
1059 push(contextFiberStackCursor, fiber, fiber);
1060 push(contextStackCursor, nextContext, fiber);
1061 }
1062}
1063
1064function popHostContext(fiber) {
1065 if (contextFiberStackCursor.current === fiber) {
1066 // Do not pop unless this Fiber provided the current context.
1067 // pushHostContext() only pushes Fibers that provide unique contexts.
1068 pop(contextStackCursor, fiber);
1069 pop(contextFiberStackCursor, fiber);
1070 }
1071
1072 {
1073 if (hostTransitionProviderCursor.current === fiber) {
1074 // Do not pop unless this Fiber provided the current context. This is mostly
1075 // a performance optimization, but conveniently it also prevents a potential
1076 // data race where a host provider is upgraded (i.e. memoizedState becomes
1077 // non-null) during a concurrent event. This is a bit of a flaw in the way
1078 // we upgrade host components, but because we're accounting for it here, it
1079 // should be fine.
1080 pop(hostTransitionProviderCursor, fiber); // When popping the transition provider, we reset the context value back
1081 // to `null`. We can do this because you're not allowd to nest forms. If
1082 // we allowed for multiple nested host transition providers, then we'd
1083 // need to reset this to the parent provider's status.
1084
1085 {
1086 HostTransitionContext._currentValue = null;
1087 }
1088 }
1089 }
1090}
1091
1092// $FlowFixMe[method-unbinding]
1093var hasOwnProperty = Object.prototype.hasOwnProperty;
1094
1095/*
1096 * The `'' + value` pattern (used in perf-sensitive code) throws for Symbol
1097 * and Temporal.* types. See https://github.com/facebook/react/pull/22064.
1098 *
1099 * The functions in this module will throw an easier-to-understand,
1100 * easier-to-debug exception with a clear errors message message explaining the
1101 * problem. (Instead of a confusing exception thrown inside the implementation
1102 * of the `value` object).
1103 */
1104// $FlowFixMe[incompatible-return] only called in DEV, so void return is not possible.
1105function typeName(value) {
1106 {
1107 // toStringTag is needed for namespaced types like Temporal.Instant
1108 var hasToStringTag = typeof Symbol === 'function' && Symbol.toStringTag;
1109 var type = hasToStringTag && value[Symbol.toStringTag] || value.constructor.name || 'Object'; // $FlowFixMe[incompatible-return]
1110
1111 return type;
1112 }
1113} // $FlowFixMe[incompatible-return] only called in DEV, so void return is not possible.
1114
1115
1116function willCoercionThrow(value) {
1117 {
1118 try {
1119 testStringCoercion(value);
1120 return false;
1121 } catch (e) {
1122 return true;
1123 }
1124 }
1125}
1126
1127function testStringCoercion(value) {
1128 // If you ended up here by following an exception call stack, here's what's
1129 // happened: you supplied an object or symbol value to React (as a prop, key,
1130 // DOM attribute, CSS property, string ref, etc.) and when React tried to
1131 // coerce it to a string using `'' + value`, an exception was thrown.
1132 //
1133 // The most common types that will cause this exception are `Symbol` instances
1134 // and Temporal objects like `Temporal.Instant`. But any object that has a
1135 // `valueOf` or `[Symbol.toPrimitive]` method that throws will also cause this
1136 // exception. (Library authors do this to prevent users from using built-in
1137 // numeric operators like `+` or comparison operators like `>=` because custom
1138 // methods are needed to perform accurate arithmetic or comparison.)
1139 //
1140 // To fix the problem, coerce this object or symbol value to a string before
1141 // passing it to React. The most reliable way is usually `String(value)`.
1142 //
1143 // To find which value is throwing, check the browser or debugger console.
1144 // Before this exception was thrown, there should be `console.error` output
1145 // that shows the type (Symbol, Temporal.PlainDate, etc.) that caused the
1146 // problem and how that type was used: key, atrribute, input value prop, etc.
1147 // In most cases, this console output also shows the component and its
1148 // ancestor components where the exception happened.
1149 //
1150 // eslint-disable-next-line react-internal/safe-string-coercion
1151 return '' + value;
1152}
1153
1154function checkAttributeStringCoercion(value, attributeName) {
1155 {
1156 if (willCoercionThrow(value)) {
1157 error('The provided `%s` attribute is an unsupported type %s.' + ' This value must be coerced to a string before using it here.', attributeName, typeName(value));
1158
1159 return testStringCoercion(value); // throw (to help callers find troubleshooting comments)
1160 }
1161 }
1162}
1163function checkCSSPropertyStringCoercion(value, propName) {
1164 {
1165 if (willCoercionThrow(value)) {
1166 error('The provided `%s` CSS property is an unsupported type %s.' + ' This value must be coerced to a string before using it here.', propName, typeName(value));
1167
1168 return testStringCoercion(value); // throw (to help callers find troubleshooting comments)
1169 }
1170 }
1171}
1172function checkHtmlStringCoercion(value) {
1173 {
1174 if (willCoercionThrow(value)) {
1175 error('The provided HTML markup uses a value of unsupported type %s.' + ' This value must be coerced to a string before using it here.', typeName(value));
1176
1177 return testStringCoercion(value); // throw (to help callers find troubleshooting comments)
1178 }
1179 }
1180}
1181function checkFormFieldValueStringCoercion(value) {
1182 {
1183 if (willCoercionThrow(value)) {
1184 error('Form field values (value, checked, defaultValue, or defaultChecked props)' + ' must be strings, not %s.' + ' This value must be coerced to a string before using it here.', typeName(value));
1185
1186 return testStringCoercion(value); // throw (to help callers find troubleshooting comments)
1187 }
1188 }
1189}
1190
1191// This module only exists as an ESM wrapper around the external CommonJS
1192var scheduleCallback$3 = Scheduler.unstable_scheduleCallback;
1193var cancelCallback$1 = Scheduler.unstable_cancelCallback;
1194var shouldYield = Scheduler.unstable_shouldYield;
1195var requestPaint = Scheduler.unstable_requestPaint;
1196var now$1 = Scheduler.unstable_now;
1197var getCurrentPriorityLevel = Scheduler.unstable_getCurrentPriorityLevel;
1198var ImmediatePriority = Scheduler.unstable_ImmediatePriority;
1199var UserBlockingPriority = Scheduler.unstable_UserBlockingPriority;
1200var NormalPriority$1 = Scheduler.unstable_NormalPriority;
1201var LowPriority = Scheduler.unstable_LowPriority;
1202var IdlePriority = Scheduler.unstable_IdlePriority; // this doesn't actually exist on the scheduler, but it *does*
1203// on scheduler/unstable_mock, which we'll need for internal testing
1204
1205var log$1 = Scheduler.log;
1206var unstable_setDisableYieldValue = Scheduler.unstable_setDisableYieldValue;
1207
1208// Helpers to patch console.logs to avoid logging during side-effect free
1209// replaying on render function. This currently only patches the object
1210// lazily which won't cover if the log function was extracted eagerly.
1211// We could also eagerly patch the method.
1212var disabledDepth = 0;
1213var prevLog;
1214var prevInfo;
1215var prevWarn;
1216var prevError;
1217var prevGroup;
1218var prevGroupCollapsed;
1219var prevGroupEnd;
1220
1221function disabledLog() {}
1222
1223disabledLog.__reactDisabledLog = true;
1224function disableLogs() {
1225 {
1226 if (disabledDepth === 0) {
1227 /* eslint-disable react-internal/no-production-logging */
1228 prevLog = console.log;
1229 prevInfo = console.info;
1230 prevWarn = console.warn;
1231 prevError = console.error;
1232 prevGroup = console.group;
1233 prevGroupCollapsed = console.groupCollapsed;
1234 prevGroupEnd = console.groupEnd; // https://github.com/facebook/react/issues/19099
1235
1236 var props = {
1237 configurable: true,
1238 enumerable: true,
1239 value: disabledLog,
1240 writable: true
1241 }; // $FlowFixMe[cannot-write] Flow thinks console is immutable.
1242
1243 Object.defineProperties(console, {
1244 info: props,
1245 log: props,
1246 warn: props,
1247 error: props,
1248 group: props,
1249 groupCollapsed: props,
1250 groupEnd: props
1251 });
1252 /* eslint-enable react-internal/no-production-logging */
1253 }
1254
1255 disabledDepth++;
1256 }
1257}
1258function reenableLogs() {
1259 {
1260 disabledDepth--;
1261
1262 if (disabledDepth === 0) {
1263 /* eslint-disable react-internal/no-production-logging */
1264 var props = {
1265 configurable: true,
1266 enumerable: true,
1267 writable: true
1268 }; // $FlowFixMe[cannot-write] Flow thinks console is immutable.
1269
1270 Object.defineProperties(console, {
1271 log: assign({}, props, {
1272 value: prevLog
1273 }),
1274 info: assign({}, props, {
1275 value: prevInfo
1276 }),
1277 warn: assign({}, props, {
1278 value: prevWarn
1279 }),
1280 error: assign({}, props, {
1281 value: prevError
1282 }),
1283 group: assign({}, props, {
1284 value: prevGroup
1285 }),
1286 groupCollapsed: assign({}, props, {
1287 value: prevGroupCollapsed
1288 }),
1289 groupEnd: assign({}, props, {
1290 value: prevGroupEnd
1291 })
1292 });
1293 /* eslint-enable react-internal/no-production-logging */
1294 }
1295
1296 if (disabledDepth < 0) {
1297 error('disabledDepth fell below zero. ' + 'This is a bug in React. Please file an issue.');
1298 }
1299 }
1300}
1301
1302var rendererID = null;
1303var injectedHook = null;
1304var injectedProfilingHooks = null;
1305var hasLoggedError = false;
1306var isDevToolsPresent = typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ !== 'undefined';
1307function injectInternals(internals) {
1308 if (typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ === 'undefined') {
1309 // No DevTools
1310 return false;
1311 }
1312
1313 var hook = __REACT_DEVTOOLS_GLOBAL_HOOK__;
1314
1315 if (hook.isDisabled) {
1316 // This isn't a real property on the hook, but it can be set to opt out
1317 // of DevTools integration and associated warnings and logs.
1318 // https://github.com/facebook/react/issues/3877
1319 return true;
1320 }
1321
1322 if (!hook.supportsFiber) {
1323 {
1324 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://react.dev/link/react-devtools');
1325 } // DevTools exists, even though it doesn't support Fiber.
1326
1327
1328 return true;
1329 }
1330
1331 try {
1332 if (enableSchedulingProfiler) {
1333 // Conditionally inject these hooks only if Timeline profiler is supported by this build.
1334 // This gives DevTools a way to feature detect that isn't tied to version number
1335 // (since profiling and timeline are controlled by different feature flags).
1336 internals = assign({}, internals, {
1337 getLaneLabelMap: getLaneLabelMap,
1338 injectProfilingHooks: injectProfilingHooks
1339 });
1340 }
1341
1342 rendererID = hook.inject(internals); // We have successfully injected, so now it is safe to set up hooks.
1343
1344 injectedHook = hook;
1345 } catch (err) {
1346 // Catch all errors because it is unsafe to throw during initialization.
1347 {
1348 error('React instrumentation encountered an error: %s.', err);
1349 }
1350 }
1351
1352 if (hook.checkDCE) {
1353 // This is the real DevTools.
1354 return true;
1355 } else {
1356 // This is likely a hook installed by Fast Refresh runtime.
1357 return false;
1358 }
1359}
1360function onScheduleRoot(root, children) {
1361 {
1362 if (injectedHook && typeof injectedHook.onScheduleFiberRoot === 'function') {
1363 try {
1364 injectedHook.onScheduleFiberRoot(rendererID, root, children);
1365 } catch (err) {
1366 if (!hasLoggedError) {
1367 hasLoggedError = true;
1368
1369 error('React instrumentation encountered an error: %s', err);
1370 }
1371 }
1372 }
1373 }
1374}
1375function onCommitRoot$1(root, eventPriority) {
1376 if (injectedHook && typeof injectedHook.onCommitFiberRoot === 'function') {
1377 try {
1378 var didError = (root.current.flags & DidCapture) === DidCapture;
1379
1380 if (enableProfilerTimer) {
1381 var schedulerPriority;
1382
1383 switch (eventPriority) {
1384 case DiscreteEventPriority:
1385 schedulerPriority = ImmediatePriority;
1386 break;
1387
1388 case ContinuousEventPriority:
1389 schedulerPriority = UserBlockingPriority;
1390 break;
1391
1392 case DefaultEventPriority:
1393 schedulerPriority = NormalPriority$1;
1394 break;
1395
1396 case IdleEventPriority:
1397 schedulerPriority = IdlePriority;
1398 break;
1399
1400 default:
1401 schedulerPriority = NormalPriority$1;
1402 break;
1403 }
1404
1405 injectedHook.onCommitFiberRoot(rendererID, root, schedulerPriority, didError);
1406 }
1407 } catch (err) {
1408 {
1409 if (!hasLoggedError) {
1410 hasLoggedError = true;
1411
1412 error('React instrumentation encountered an error: %s', err);
1413 }
1414 }
1415 }
1416 }
1417}
1418function onPostCommitRoot(root) {
1419 if (injectedHook && typeof injectedHook.onPostCommitFiberRoot === 'function') {
1420 try {
1421 injectedHook.onPostCommitFiberRoot(rendererID, root);
1422 } catch (err) {
1423 {
1424 if (!hasLoggedError) {
1425 hasLoggedError = true;
1426
1427 error('React instrumentation encountered an error: %s', err);
1428 }
1429 }
1430 }
1431 }
1432}
1433function onCommitUnmount(fiber) {
1434 if (injectedHook && typeof injectedHook.onCommitFiberUnmount === 'function') {
1435 try {
1436 injectedHook.onCommitFiberUnmount(rendererID, fiber);
1437 } catch (err) {
1438 {
1439 if (!hasLoggedError) {
1440 hasLoggedError = true;
1441
1442 error('React instrumentation encountered an error: %s', err);
1443 }
1444 }
1445 }
1446 }
1447}
1448function setIsStrictModeForDevtools(newIsStrictMode) {
1449 {
1450 if (typeof log$1 === 'function') {
1451 // We're in a test because Scheduler.log only exists
1452 // in SchedulerMock. To reduce the noise in strict mode tests,
1453 // suppress warnings and disable scheduler yielding during the double render
1454 unstable_setDisableYieldValue(newIsStrictMode);
1455 setSuppressWarning(newIsStrictMode);
1456 }
1457
1458 if (injectedHook && typeof injectedHook.setStrictMode === 'function') {
1459 try {
1460 injectedHook.setStrictMode(rendererID, newIsStrictMode);
1461 } catch (err) {
1462 {
1463 if (!hasLoggedError) {
1464 hasLoggedError = true;
1465
1466 error('React instrumentation encountered an error: %s', err);
1467 }
1468 }
1469 }
1470 }
1471 }
1472} // Profiler API hooks
1473
1474function injectProfilingHooks(profilingHooks) {
1475 injectedProfilingHooks = profilingHooks;
1476}
1477
1478function getLaneLabelMap() {
1479 {
1480 var map = new Map();
1481 var lane = 1;
1482
1483 for (var index = 0; index < TotalLanes; index++) {
1484 var label = getLabelForLane(lane);
1485 map.set(lane, label);
1486 lane *= 2;
1487 }
1488
1489 return map;
1490 }
1491}
1492
1493function markCommitStarted(lanes) {
1494 {
1495 if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markCommitStarted === 'function') {
1496 injectedProfilingHooks.markCommitStarted(lanes);
1497 }
1498 }
1499}
1500function markCommitStopped() {
1501 {
1502 if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markCommitStopped === 'function') {
1503 injectedProfilingHooks.markCommitStopped();
1504 }
1505 }
1506}
1507function markComponentRenderStarted(fiber) {
1508 {
1509 if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markComponentRenderStarted === 'function') {
1510 injectedProfilingHooks.markComponentRenderStarted(fiber);
1511 }
1512 }
1513}
1514function markComponentRenderStopped() {
1515 {
1516 if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markComponentRenderStopped === 'function') {
1517 injectedProfilingHooks.markComponentRenderStopped();
1518 }
1519 }
1520}
1521function markComponentPassiveEffectMountStarted(fiber) {
1522 {
1523 if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markComponentPassiveEffectMountStarted === 'function') {
1524 injectedProfilingHooks.markComponentPassiveEffectMountStarted(fiber);
1525 }
1526 }
1527}
1528function markComponentPassiveEffectMountStopped() {
1529 {
1530 if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markComponentPassiveEffectMountStopped === 'function') {
1531 injectedProfilingHooks.markComponentPassiveEffectMountStopped();
1532 }
1533 }
1534}
1535function markComponentPassiveEffectUnmountStarted(fiber) {
1536 {
1537 if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markComponentPassiveEffectUnmountStarted === 'function') {
1538 injectedProfilingHooks.markComponentPassiveEffectUnmountStarted(fiber);
1539 }
1540 }
1541}
1542function markComponentPassiveEffectUnmountStopped() {
1543 {
1544 if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markComponentPassiveEffectUnmountStopped === 'function') {
1545 injectedProfilingHooks.markComponentPassiveEffectUnmountStopped();
1546 }
1547 }
1548}
1549function markComponentLayoutEffectMountStarted(fiber) {
1550 {
1551 if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markComponentLayoutEffectMountStarted === 'function') {
1552 injectedProfilingHooks.markComponentLayoutEffectMountStarted(fiber);
1553 }
1554 }
1555}
1556function markComponentLayoutEffectMountStopped() {
1557 {
1558 if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markComponentLayoutEffectMountStopped === 'function') {
1559 injectedProfilingHooks.markComponentLayoutEffectMountStopped();
1560 }
1561 }
1562}
1563function markComponentLayoutEffectUnmountStarted(fiber) {
1564 {
1565 if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markComponentLayoutEffectUnmountStarted === 'function') {
1566 injectedProfilingHooks.markComponentLayoutEffectUnmountStarted(fiber);
1567 }
1568 }
1569}
1570function markComponentLayoutEffectUnmountStopped() {
1571 {
1572 if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markComponentLayoutEffectUnmountStopped === 'function') {
1573 injectedProfilingHooks.markComponentLayoutEffectUnmountStopped();
1574 }
1575 }
1576}
1577function markComponentErrored(fiber, thrownValue, lanes) {
1578 {
1579 if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markComponentErrored === 'function') {
1580 injectedProfilingHooks.markComponentErrored(fiber, thrownValue, lanes);
1581 }
1582 }
1583}
1584function markComponentSuspended(fiber, wakeable, lanes) {
1585 {
1586 if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markComponentSuspended === 'function') {
1587 injectedProfilingHooks.markComponentSuspended(fiber, wakeable, lanes);
1588 }
1589 }
1590}
1591function markLayoutEffectsStarted(lanes) {
1592 {
1593 if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markLayoutEffectsStarted === 'function') {
1594 injectedProfilingHooks.markLayoutEffectsStarted(lanes);
1595 }
1596 }
1597}
1598function markLayoutEffectsStopped() {
1599 {
1600 if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markLayoutEffectsStopped === 'function') {
1601 injectedProfilingHooks.markLayoutEffectsStopped();
1602 }
1603 }
1604}
1605function markPassiveEffectsStarted(lanes) {
1606 {
1607 if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markPassiveEffectsStarted === 'function') {
1608 injectedProfilingHooks.markPassiveEffectsStarted(lanes);
1609 }
1610 }
1611}
1612function markPassiveEffectsStopped() {
1613 {
1614 if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markPassiveEffectsStopped === 'function') {
1615 injectedProfilingHooks.markPassiveEffectsStopped();
1616 }
1617 }
1618}
1619function markRenderStarted(lanes) {
1620 {
1621 if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markRenderStarted === 'function') {
1622 injectedProfilingHooks.markRenderStarted(lanes);
1623 }
1624 }
1625}
1626function markRenderYielded() {
1627 {
1628 if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markRenderYielded === 'function') {
1629 injectedProfilingHooks.markRenderYielded();
1630 }
1631 }
1632}
1633function markRenderStopped() {
1634 {
1635 if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markRenderStopped === 'function') {
1636 injectedProfilingHooks.markRenderStopped();
1637 }
1638 }
1639}
1640function markRenderScheduled(lane) {
1641 {
1642 if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markRenderScheduled === 'function') {
1643 injectedProfilingHooks.markRenderScheduled(lane);
1644 }
1645 }
1646}
1647function markForceUpdateScheduled(fiber, lane) {
1648 {
1649 if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markForceUpdateScheduled === 'function') {
1650 injectedProfilingHooks.markForceUpdateScheduled(fiber, lane);
1651 }
1652 }
1653}
1654function markStateUpdateScheduled(fiber, lane) {
1655 {
1656 if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markStateUpdateScheduled === 'function') {
1657 injectedProfilingHooks.markStateUpdateScheduled(fiber, lane);
1658 }
1659 }
1660}
1661
1662var NoMode =
1663/* */
16640; // TODO: Remove ConcurrentMode by reading from the root tag instead
1665
1666var ConcurrentMode =
1667/* */
16681;
1669var ProfileMode =
1670/* */
16712;
1672var StrictLegacyMode =
1673/* */
16748;
1675var StrictEffectsMode =
1676/* */
167716;
1678var NoStrictPassiveEffectsMode =
1679/* */
168064;
1681
1682// TODO: This is pretty well supported by browsers. Maybe we can drop it.
1683var clz32 = Math.clz32 ? Math.clz32 : clz32Fallback; // Count leading zeros.
1684// Based on:
1685// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/clz32
1686
1687var log = Math.log;
1688var LN2 = Math.LN2;
1689
1690function clz32Fallback(x) {
1691 var asUint = x >>> 0;
1692
1693 if (asUint === 0) {
1694 return 32;
1695 }
1696
1697 return 31 - (log(asUint) / LN2 | 0) | 0;
1698}
1699
1700// If those values are changed that package should be rebuilt and redeployed.
1701
1702var TotalLanes = 31;
1703var NoLanes =
1704/* */
17050;
1706var NoLane =
1707/* */
17080;
1709var SyncHydrationLane =
1710/* */
17111;
1712var SyncLane =
1713/* */
17142;
1715var SyncLaneIndex = 1;
1716var InputContinuousHydrationLane =
1717/* */
17184;
1719var InputContinuousLane =
1720/* */
17218;
1722var DefaultHydrationLane =
1723/* */
172416;
1725var DefaultLane =
1726/* */
172732;
1728var SyncUpdateLanes = SyncLane | InputContinuousLane | DefaultLane ;
1729var TransitionHydrationLane =
1730/* */
173164;
1732var TransitionLanes =
1733/* */
17344194176;
1735var TransitionLane1 =
1736/* */
1737128;
1738var TransitionLane2 =
1739/* */
1740256;
1741var TransitionLane3 =
1742/* */
1743512;
1744var TransitionLane4 =
1745/* */
17461024;
1747var TransitionLane5 =
1748/* */
17492048;
1750var TransitionLane6 =
1751/* */
17524096;
1753var TransitionLane7 =
1754/* */
17558192;
1756var TransitionLane8 =
1757/* */
175816384;
1759var TransitionLane9 =
1760/* */
176132768;
1762var TransitionLane10 =
1763/* */
176465536;
1765var TransitionLane11 =
1766/* */
1767131072;
1768var TransitionLane12 =
1769/* */
1770262144;
1771var TransitionLane13 =
1772/* */
1773524288;
1774var TransitionLane14 =
1775/* */
17761048576;
1777var TransitionLane15 =
1778/* */
17792097152;
1780var RetryLanes =
1781/* */
178262914560;
1783var RetryLane1 =
1784/* */
17854194304;
1786var RetryLane2 =
1787/* */
17888388608;
1789var RetryLane3 =
1790/* */
179116777216;
1792var RetryLane4 =
1793/* */
179433554432;
1795var SomeRetryLane = RetryLane1;
1796var SelectiveHydrationLane =
1797/* */
179867108864;
1799var NonIdleLanes =
1800/* */
1801134217727;
1802var IdleHydrationLane =
1803/* */
1804134217728;
1805var IdleLane =
1806/* */
1807268435456;
1808var OffscreenLane =
1809/* */
1810536870912;
1811var DeferredLane =
1812/* */
18131073741824; // Any lane that might schedule an update. This is used to detect infinite
1814// update loops, so it doesn't include hydration lanes or retries.
1815
1816var UpdateLanes = SyncLane | InputContinuousLane | DefaultLane | TransitionLanes; // This function is used for the experimental timeline (react-devtools-timeline)
1817// It should be kept in sync with the Lanes values above.
1818
1819function getLabelForLane(lane) {
1820 {
1821 if (lane & SyncHydrationLane) {
1822 return 'SyncHydrationLane';
1823 }
1824
1825 if (lane & SyncLane) {
1826 return 'Sync';
1827 }
1828
1829 if (lane & InputContinuousHydrationLane) {
1830 return 'InputContinuousHydration';
1831 }
1832
1833 if (lane & InputContinuousLane) {
1834 return 'InputContinuous';
1835 }
1836
1837 if (lane & DefaultHydrationLane) {
1838 return 'DefaultHydration';
1839 }
1840
1841 if (lane & DefaultLane) {
1842 return 'Default';
1843 }
1844
1845 if (lane & TransitionHydrationLane) {
1846 return 'TransitionHydration';
1847 }
1848
1849 if (lane & TransitionLanes) {
1850 return 'Transition';
1851 }
1852
1853 if (lane & RetryLanes) {
1854 return 'Retry';
1855 }
1856
1857 if (lane & SelectiveHydrationLane) {
1858 return 'SelectiveHydration';
1859 }
1860
1861 if (lane & IdleHydrationLane) {
1862 return 'IdleHydration';
1863 }
1864
1865 if (lane & IdleLane) {
1866 return 'Idle';
1867 }
1868
1869 if (lane & OffscreenLane) {
1870 return 'Offscreen';
1871 }
1872
1873 if (lane & DeferredLane) {
1874 return 'Deferred';
1875 }
1876 }
1877}
1878var NoTimestamp = -1;
1879var nextTransitionLane = TransitionLane1;
1880var nextRetryLane = RetryLane1;
1881
1882function getHighestPriorityLanes(lanes) {
1883 {
1884 var pendingSyncLanes = lanes & SyncUpdateLanes;
1885
1886 if (pendingSyncLanes !== 0) {
1887 return pendingSyncLanes;
1888 }
1889 }
1890
1891 switch (getHighestPriorityLane(lanes)) {
1892 case SyncHydrationLane:
1893 return SyncHydrationLane;
1894
1895 case SyncLane:
1896 return SyncLane;
1897
1898 case InputContinuousHydrationLane:
1899 return InputContinuousHydrationLane;
1900
1901 case InputContinuousLane:
1902 return InputContinuousLane;
1903
1904 case DefaultHydrationLane:
1905 return DefaultHydrationLane;
1906
1907 case DefaultLane:
1908 return DefaultLane;
1909
1910 case TransitionHydrationLane:
1911 return TransitionHydrationLane;
1912
1913 case TransitionLane1:
1914 case TransitionLane2:
1915 case TransitionLane3:
1916 case TransitionLane4:
1917 case TransitionLane5:
1918 case TransitionLane6:
1919 case TransitionLane7:
1920 case TransitionLane8:
1921 case TransitionLane9:
1922 case TransitionLane10:
1923 case TransitionLane11:
1924 case TransitionLane12:
1925 case TransitionLane13:
1926 case TransitionLane14:
1927 case TransitionLane15:
1928 return lanes & TransitionLanes;
1929
1930 case RetryLane1:
1931 case RetryLane2:
1932 case RetryLane3:
1933 case RetryLane4:
1934 return lanes & RetryLanes;
1935
1936 case SelectiveHydrationLane:
1937 return SelectiveHydrationLane;
1938
1939 case IdleHydrationLane:
1940 return IdleHydrationLane;
1941
1942 case IdleLane:
1943 return IdleLane;
1944
1945 case OffscreenLane:
1946 return OffscreenLane;
1947
1948 case DeferredLane:
1949 // This shouldn't be reachable because deferred work is always entangled
1950 // with something else.
1951 return NoLanes;
1952
1953 default:
1954 {
1955 error('Should have found matching lanes. This is a bug in React.');
1956 } // This shouldn't be reachable, but as a fallback, return the entire bitmask.
1957
1958
1959 return lanes;
1960 }
1961}
1962
1963function getNextLanes(root, wipLanes) {
1964 // Early bailout if there's no pending work left.
1965 var pendingLanes = root.pendingLanes;
1966
1967 if (pendingLanes === NoLanes) {
1968 return NoLanes;
1969 }
1970
1971 var nextLanes = NoLanes;
1972 var suspendedLanes = root.suspendedLanes;
1973 var pingedLanes = root.pingedLanes; // Do not work on any idle work until all the non-idle work has finished,
1974 // even if the work is suspended.
1975
1976 var nonIdlePendingLanes = pendingLanes & NonIdleLanes;
1977
1978 if (nonIdlePendingLanes !== NoLanes) {
1979 var nonIdleUnblockedLanes = nonIdlePendingLanes & ~suspendedLanes;
1980
1981 if (nonIdleUnblockedLanes !== NoLanes) {
1982 nextLanes = getHighestPriorityLanes(nonIdleUnblockedLanes);
1983 } else {
1984 var nonIdlePingedLanes = nonIdlePendingLanes & pingedLanes;
1985
1986 if (nonIdlePingedLanes !== NoLanes) {
1987 nextLanes = getHighestPriorityLanes(nonIdlePingedLanes);
1988 }
1989 }
1990 } else {
1991 // The only remaining work is Idle.
1992 var unblockedLanes = pendingLanes & ~suspendedLanes;
1993
1994 if (unblockedLanes !== NoLanes) {
1995 nextLanes = getHighestPriorityLanes(unblockedLanes);
1996 } else {
1997 if (pingedLanes !== NoLanes) {
1998 nextLanes = getHighestPriorityLanes(pingedLanes);
1999 }
2000 }
2001 }
2002
2003 if (nextLanes === NoLanes) {
2004 // This should only be reachable if we're suspended
2005 // TODO: Consider warning in this path if a fallback timer is not scheduled.
2006 return NoLanes;
2007 } // If we're already in the middle of a render, switching lanes will interrupt
2008 // it and we'll lose our progress. We should only do this if the new lanes are
2009 // higher priority.
2010
2011
2012 if (wipLanes !== NoLanes && wipLanes !== nextLanes && // If we already suspended with a delay, then interrupting is fine. Don't
2013 // bother waiting until the root is complete.
2014 (wipLanes & suspendedLanes) === NoLanes) {
2015 var nextLane = getHighestPriorityLane(nextLanes);
2016 var wipLane = getHighestPriorityLane(wipLanes);
2017
2018 if ( // Tests whether the next lane is equal or lower priority than the wip
2019 // one. This works because the bits decrease in priority as you go left.
2020 nextLane >= wipLane || // Default priority updates should not interrupt transition updates. The
2021 // only difference between default updates and transition updates is that
2022 // default updates do not support refresh transitions.
2023 nextLane === DefaultLane && (wipLane & TransitionLanes) !== NoLanes) {
2024 // Keep working on the existing in-progress tree. Do not interrupt.
2025 return wipLanes;
2026 }
2027 }
2028
2029 return nextLanes;
2030}
2031function getEntangledLanes(root, renderLanes) {
2032 var entangledLanes = renderLanes;
2033
2034 if ((entangledLanes & InputContinuousLane) !== NoLanes) {
2035 // When updates are sync by default, we entangle continuous priority updates
2036 // and default updates, so they render in the same batch. The only reason
2037 // they use separate lanes is because continuous updates should interrupt
2038 // transitions, but default updates should not.
2039 entangledLanes |= entangledLanes & DefaultLane;
2040 } // Check for entangled lanes and add them to the batch.
2041 //
2042 // A lane is said to be entangled with another when it's not allowed to render
2043 // in a batch that does not also include the other lane. Typically we do this
2044 // when multiple updates have the same source, and we only want to respond to
2045 // the most recent event from that source.
2046 //
2047 // Note that we apply entanglements *after* checking for partial work above.
2048 // This means that if a lane is entangled during an interleaved event while
2049 // it's already rendering, we won't interrupt it. This is intentional, since
2050 // entanglement is usually "best effort": we'll try our best to render the
2051 // lanes in the same batch, but it's not worth throwing out partially
2052 // completed work in order to do it.
2053 // TODO: Reconsider this. The counter-argument is that the partial work
2054 // represents an intermediate state, which we don't want to show to the user.
2055 // And by spending extra time finishing it, we're increasing the amount of
2056 // time it takes to show the final state, which is what they are actually
2057 // waiting for.
2058 //
2059 // For those exceptions where entanglement is semantically important,
2060 // we should ensure that there is no partial work at the
2061 // time we apply the entanglement.
2062
2063
2064 var allEntangledLanes = root.entangledLanes;
2065
2066 if (allEntangledLanes !== NoLanes) {
2067 var entanglements = root.entanglements;
2068 var lanes = entangledLanes & allEntangledLanes;
2069
2070 while (lanes > 0) {
2071 var index = pickArbitraryLaneIndex(lanes);
2072 var lane = 1 << index;
2073 entangledLanes |= entanglements[index];
2074 lanes &= ~lane;
2075 }
2076 }
2077
2078 return entangledLanes;
2079}
2080
2081function computeExpirationTime(lane, currentTime) {
2082 switch (lane) {
2083 case SyncHydrationLane:
2084 case SyncLane:
2085 case InputContinuousHydrationLane:
2086 case InputContinuousLane:
2087 // User interactions should expire slightly more quickly.
2088 //
2089 // NOTE: This is set to the corresponding constant as in Scheduler.js.
2090 // When we made it larger, a product metric in www regressed, suggesting
2091 // there's a user interaction that's being starved by a series of
2092 // synchronous updates. If that theory is correct, the proper solution is
2093 // to fix the starvation. However, this scenario supports the idea that
2094 // expiration times are an important safeguard when starvation
2095 // does happen.
2096 return currentTime + syncLaneExpirationMs;
2097
2098 case DefaultHydrationLane:
2099 case DefaultLane:
2100 case TransitionHydrationLane:
2101 case TransitionLane1:
2102 case TransitionLane2:
2103 case TransitionLane3:
2104 case TransitionLane4:
2105 case TransitionLane5:
2106 case TransitionLane6:
2107 case TransitionLane7:
2108 case TransitionLane8:
2109 case TransitionLane9:
2110 case TransitionLane10:
2111 case TransitionLane11:
2112 case TransitionLane12:
2113 case TransitionLane13:
2114 case TransitionLane14:
2115 case TransitionLane15:
2116 return currentTime + transitionLaneExpirationMs;
2117
2118 case RetryLane1:
2119 case RetryLane2:
2120 case RetryLane3:
2121 case RetryLane4:
2122 // TODO: Retries should be allowed to expire if they are CPU bound for
2123 // too long, but when I made this change it caused a spike in browser
2124 // crashes. There must be some other underlying bug; not super urgent but
2125 // ideally should figure out why and fix it. Unfortunately we don't have
2126 // a repro for the crashes, only detected via production metrics.
2127 return NoTimestamp;
2128
2129 case SelectiveHydrationLane:
2130 case IdleHydrationLane:
2131 case IdleLane:
2132 case OffscreenLane:
2133 case DeferredLane:
2134 // Anything idle priority or lower should never expire.
2135 return NoTimestamp;
2136
2137 default:
2138 {
2139 error('Should have found matching lanes. This is a bug in React.');
2140 }
2141
2142 return NoTimestamp;
2143 }
2144}
2145
2146function markStarvedLanesAsExpired(root, currentTime) {
2147 // TODO: This gets called every time we yield. We can optimize by storing
2148 // the earliest expiration time on the root. Then use that to quickly bail out
2149 // of this function.
2150 var pendingLanes = root.pendingLanes;
2151 var suspendedLanes = root.suspendedLanes;
2152 var pingedLanes = root.pingedLanes;
2153 var expirationTimes = root.expirationTimes; // Iterate through the pending lanes and check if we've reached their
2154 // expiration time. If so, we'll assume the update is being starved and mark
2155 // it as expired to force it to finish.
2156 // TODO: We should be able to replace this with upgradePendingLanesToSync
2157 //
2158 // We exclude retry lanes because those must always be time sliced, in order
2159 // to unwrap uncached promises.
2160 // TODO: Write a test for this
2161
2162 var lanes = pendingLanes & ~RetryLanes;
2163
2164 while (lanes > 0) {
2165 var index = pickArbitraryLaneIndex(lanes);
2166 var lane = 1 << index;
2167 var expirationTime = expirationTimes[index];
2168
2169 if (expirationTime === NoTimestamp) {
2170 // Found a pending lane with no expiration time. If it's not suspended, or
2171 // if it's pinged, assume it's CPU-bound. Compute a new expiration time
2172 // using the current time.
2173 if ((lane & suspendedLanes) === NoLanes || (lane & pingedLanes) !== NoLanes) {
2174 // Assumes timestamps are monotonically increasing.
2175 expirationTimes[index] = computeExpirationTime(lane, currentTime);
2176 }
2177 } else if (expirationTime <= currentTime) {
2178 // This lane expired
2179 root.expiredLanes |= lane;
2180 }
2181
2182 lanes &= ~lane;
2183 }
2184} // This returns the highest priority pending lanes regardless of whether they
2185// are suspended.
2186
2187function getHighestPriorityPendingLanes(root) {
2188 return getHighestPriorityLanes(root.pendingLanes);
2189}
2190function getLanesToRetrySynchronouslyOnError(root, originallyAttemptedLanes) {
2191 if (root.errorRecoveryDisabledLanes & originallyAttemptedLanes) {
2192 // The error recovery mechanism is disabled until these lanes are cleared.
2193 return NoLanes;
2194 }
2195
2196 var everythingButOffscreen = root.pendingLanes & ~OffscreenLane;
2197
2198 if (everythingButOffscreen !== NoLanes) {
2199 return everythingButOffscreen;
2200 }
2201
2202 if (everythingButOffscreen & OffscreenLane) {
2203 return OffscreenLane;
2204 }
2205
2206 return NoLanes;
2207}
2208function includesSyncLane(lanes) {
2209 return (lanes & (SyncLane | SyncHydrationLane)) !== NoLanes;
2210}
2211function includesNonIdleWork(lanes) {
2212 return (lanes & NonIdleLanes) !== NoLanes;
2213}
2214function includesOnlyRetries(lanes) {
2215 return (lanes & RetryLanes) === lanes;
2216}
2217function includesOnlyNonUrgentLanes(lanes) {
2218 // TODO: Should hydration lanes be included here? This function is only
2219 // used in `updateDeferredValueImpl`.
2220 var UrgentLanes = SyncLane | InputContinuousLane | DefaultLane;
2221 return (lanes & UrgentLanes) === NoLanes;
2222}
2223function includesOnlyTransitions(lanes) {
2224 return (lanes & TransitionLanes) === lanes;
2225}
2226function includesBlockingLane(root, lanes) {
2227
2228 var SyncDefaultLanes = InputContinuousHydrationLane | InputContinuousLane | DefaultHydrationLane | DefaultLane;
2229 return (lanes & SyncDefaultLanes) !== NoLanes;
2230}
2231function includesExpiredLane(root, lanes) {
2232 // This is a separate check from includesBlockingLane because a lane can
2233 // expire after a render has already started.
2234 return (lanes & root.expiredLanes) !== NoLanes;
2235}
2236function isTransitionLane(lane) {
2237 return (lane & TransitionLanes) !== NoLanes;
2238}
2239function claimNextTransitionLane() {
2240 // Cycle through the lanes, assigning each new transition to the next lane.
2241 // In most cases, this means every transition gets its own lane, until we
2242 // run out of lanes and cycle back to the beginning.
2243 var lane = nextTransitionLane;
2244 nextTransitionLane <<= 1;
2245
2246 if ((nextTransitionLane & TransitionLanes) === NoLanes) {
2247 nextTransitionLane = TransitionLane1;
2248 }
2249
2250 return lane;
2251}
2252function claimNextRetryLane() {
2253 var lane = nextRetryLane;
2254 nextRetryLane <<= 1;
2255
2256 if ((nextRetryLane & RetryLanes) === NoLanes) {
2257 nextRetryLane = RetryLane1;
2258 }
2259
2260 return lane;
2261}
2262function getHighestPriorityLane(lanes) {
2263 return lanes & -lanes;
2264}
2265function pickArbitraryLane(lanes) {
2266 // This wrapper function gets inlined. Only exists so to communicate that it
2267 // doesn't matter which bit is selected; you can pick any bit without
2268 // affecting the algorithms where its used. Here I'm using
2269 // getHighestPriorityLane because it requires the fewest operations.
2270 return getHighestPriorityLane(lanes);
2271}
2272
2273function pickArbitraryLaneIndex(lanes) {
2274 return 31 - clz32(lanes);
2275}
2276
2277function laneToIndex(lane) {
2278 return pickArbitraryLaneIndex(lane);
2279}
2280
2281function includesSomeLane(a, b) {
2282 return (a & b) !== NoLanes;
2283}
2284function isSubsetOfLanes(set, subset) {
2285 return (set & subset) === subset;
2286}
2287function mergeLanes(a, b) {
2288 return a | b;
2289}
2290function removeLanes(set, subset) {
2291 return set & ~subset;
2292}
2293function intersectLanes(a, b) {
2294 return a & b;
2295} // Seems redundant, but it changes the type from a single lane (used for
2296// updates) to a group of lanes (used for flushing work).
2297
2298function laneToLanes(lane) {
2299 return lane;
2300}
2301function higherPriorityLane(a, b) {
2302 // This works because the bit ranges decrease in priority as you go left.
2303 return a !== NoLane && a < b ? a : b;
2304}
2305function createLaneMap(initial) {
2306 // Intentionally pushing one by one.
2307 // https://v8.dev/blog/elements-kinds#avoid-creating-holes
2308 var laneMap = [];
2309
2310 for (var i = 0; i < TotalLanes; i++) {
2311 laneMap.push(initial);
2312 }
2313
2314 return laneMap;
2315}
2316function markRootUpdated$1(root, updateLane) {
2317 root.pendingLanes |= updateLane; // If there are any suspended transitions, it's possible this new update
2318 // could unblock them. Clear the suspended lanes so that we can try rendering
2319 // them again.
2320 //
2321 // TODO: We really only need to unsuspend only lanes that are in the
2322 // `subtreeLanes` of the updated fiber, or the update lanes of the return
2323 // path. This would exclude suspended updates in an unrelated sibling tree,
2324 // since there's no way for this update to unblock it.
2325 //
2326 // We don't do this if the incoming update is idle, because we never process
2327 // idle updates until after all the regular updates have finished; there's no
2328 // way it could unblock a transition.
2329
2330 if (updateLane !== IdleLane) {
2331 root.suspendedLanes = NoLanes;
2332 root.pingedLanes = NoLanes;
2333 }
2334}
2335function markRootSuspended$1(root, suspendedLanes, spawnedLane) {
2336 root.suspendedLanes |= suspendedLanes;
2337 root.pingedLanes &= ~suspendedLanes; // The suspended lanes are no longer CPU-bound. Clear their expiration times.
2338
2339 var expirationTimes = root.expirationTimes;
2340 var lanes = suspendedLanes;
2341
2342 while (lanes > 0) {
2343 var index = pickArbitraryLaneIndex(lanes);
2344 var lane = 1 << index;
2345 expirationTimes[index] = NoTimestamp;
2346 lanes &= ~lane;
2347 }
2348
2349 if (spawnedLane !== NoLane) {
2350 markSpawnedDeferredLane(root, spawnedLane, suspendedLanes);
2351 }
2352}
2353function markRootPinged$1(root, pingedLanes) {
2354 root.pingedLanes |= root.suspendedLanes & pingedLanes;
2355}
2356function markRootFinished(root, remainingLanes, spawnedLane) {
2357 var noLongerPendingLanes = root.pendingLanes & ~remainingLanes;
2358 root.pendingLanes = remainingLanes; // Let's try everything again
2359
2360 root.suspendedLanes = NoLanes;
2361 root.pingedLanes = NoLanes;
2362 root.expiredLanes &= remainingLanes;
2363 root.entangledLanes &= remainingLanes;
2364 root.errorRecoveryDisabledLanes &= remainingLanes;
2365 root.shellSuspendCounter = 0;
2366 var entanglements = root.entanglements;
2367 var expirationTimes = root.expirationTimes;
2368 var hiddenUpdates = root.hiddenUpdates; // Clear the lanes that no longer have pending work
2369
2370 var lanes = noLongerPendingLanes;
2371
2372 while (lanes > 0) {
2373 var index = pickArbitraryLaneIndex(lanes);
2374 var lane = 1 << index;
2375 entanglements[index] = NoLanes;
2376 expirationTimes[index] = NoTimestamp;
2377 var hiddenUpdatesForLane = hiddenUpdates[index];
2378
2379 if (hiddenUpdatesForLane !== null) {
2380 hiddenUpdates[index] = null; // "Hidden" updates are updates that were made to a hidden component. They
2381 // have special logic associated with them because they may be entangled
2382 // with updates that occur outside that tree. But once the outer tree
2383 // commits, they behave like regular updates.
2384
2385 for (var i = 0; i < hiddenUpdatesForLane.length; i++) {
2386 var update = hiddenUpdatesForLane[i];
2387
2388 if (update !== null) {
2389 update.lane &= ~OffscreenLane;
2390 }
2391 }
2392 }
2393
2394 lanes &= ~lane;
2395 }
2396
2397 if (spawnedLane !== NoLane) {
2398 markSpawnedDeferredLane(root, spawnedLane, // This render finished successfully without suspending, so we don't need
2399 // to entangle the spawned task with the parent task.
2400 NoLanes);
2401 }
2402}
2403
2404function markSpawnedDeferredLane(root, spawnedLane, entangledLanes) {
2405 // This render spawned a deferred task. Mark it as pending.
2406 root.pendingLanes |= spawnedLane;
2407 root.suspendedLanes &= ~spawnedLane; // Entangle the spawned lane with the DeferredLane bit so that we know it
2408 // was the result of another render. This lets us avoid a useDeferredValue
2409 // waterfall — only the first level will defer.
2410
2411 var spawnedLaneIndex = laneToIndex(spawnedLane);
2412 root.entangledLanes |= spawnedLane;
2413 root.entanglements[spawnedLaneIndex] |= DeferredLane | // If the parent render task suspended, we must also entangle those lanes
2414 // with the spawned task, so that the deferred task includes all the same
2415 // updates that the parent task did. We can exclude any lane that is not
2416 // used for updates (e.g. Offscreen).
2417 entangledLanes & UpdateLanes;
2418}
2419
2420function markRootEntangled(root, entangledLanes) {
2421 // In addition to entangling each of the given lanes with each other, we also
2422 // have to consider _transitive_ entanglements. For each lane that is already
2423 // entangled with *any* of the given lanes, that lane is now transitively
2424 // entangled with *all* the given lanes.
2425 //
2426 // Translated: If C is entangled with A, then entangling A with B also
2427 // entangles C with B.
2428 //
2429 // If this is hard to grasp, it might help to intentionally break this
2430 // function and look at the tests that fail in ReactTransition-test.js. Try
2431 // commenting out one of the conditions below.
2432 var rootEntangledLanes = root.entangledLanes |= entangledLanes;
2433 var entanglements = root.entanglements;
2434 var lanes = rootEntangledLanes;
2435
2436 while (lanes) {
2437 var index = pickArbitraryLaneIndex(lanes);
2438 var lane = 1 << index;
2439
2440 if ( // Is this one of the newly entangled lanes?
2441 lane & entangledLanes | // Is this lane transitively entangled with the newly entangled lanes?
2442 entanglements[index] & entangledLanes) {
2443 entanglements[index] |= entangledLanes;
2444 }
2445
2446 lanes &= ~lane;
2447 }
2448}
2449function upgradePendingLaneToSync(root, lane) {
2450 // Since we're upgrading the priority of the given lane, there is now pending
2451 // sync work.
2452 root.pendingLanes |= SyncLane; // Entangle the sync lane with the lane we're upgrading. This means SyncLane
2453 // will not be allowed to finish without also finishing the given lane.
2454
2455 root.entangledLanes |= SyncLane;
2456 root.entanglements[SyncLaneIndex] |= lane;
2457}
2458function upgradePendingLanesToSync(root, lanesToUpgrade) {
2459 // Same as upgradePendingLaneToSync but accepts multiple lanes, so it's a
2460 // bit slower.
2461 root.pendingLanes |= SyncLane;
2462 root.entangledLanes |= SyncLane;
2463 var lanes = lanesToUpgrade;
2464
2465 while (lanes) {
2466 var index = pickArbitraryLaneIndex(lanes);
2467 var lane = 1 << index;
2468 root.entanglements[SyncLaneIndex] |= lane;
2469 lanes &= ~lane;
2470 }
2471}
2472function markHiddenUpdate(root, update, lane) {
2473 var index = laneToIndex(lane);
2474 var hiddenUpdates = root.hiddenUpdates;
2475 var hiddenUpdatesForLane = hiddenUpdates[index];
2476
2477 if (hiddenUpdatesForLane === null) {
2478 hiddenUpdates[index] = [update];
2479 } else {
2480 hiddenUpdatesForLane.push(update);
2481 }
2482
2483 update.lane = lane | OffscreenLane;
2484}
2485function getBumpedLaneForHydration(root, renderLanes) {
2486 var renderLane = getHighestPriorityLane(renderLanes);
2487 var lane;
2488
2489 if ((renderLane & SyncUpdateLanes) !== NoLane) {
2490 lane = SyncHydrationLane;
2491 } else {
2492 switch (renderLane) {
2493 case SyncLane:
2494 lane = SyncHydrationLane;
2495 break;
2496
2497 case InputContinuousLane:
2498 lane = InputContinuousHydrationLane;
2499 break;
2500
2501 case DefaultLane:
2502 lane = DefaultHydrationLane;
2503 break;
2504
2505 case TransitionLane1:
2506 case TransitionLane2:
2507 case TransitionLane3:
2508 case TransitionLane4:
2509 case TransitionLane5:
2510 case TransitionLane6:
2511 case TransitionLane7:
2512 case TransitionLane8:
2513 case TransitionLane9:
2514 case TransitionLane10:
2515 case TransitionLane11:
2516 case TransitionLane12:
2517 case TransitionLane13:
2518 case TransitionLane14:
2519 case TransitionLane15:
2520 case RetryLane1:
2521 case RetryLane2:
2522 case RetryLane3:
2523 case RetryLane4:
2524 lane = TransitionHydrationLane;
2525 break;
2526
2527 case IdleLane:
2528 lane = IdleHydrationLane;
2529 break;
2530
2531 default:
2532 // Everything else is already either a hydration lane, or shouldn't
2533 // be retried at a hydration lane.
2534 lane = NoLane;
2535 break;
2536 }
2537 } // Check if the lane we chose is suspended. If so, that indicates that we
2538 // already attempted and failed to hydrate at that level. Also check if we're
2539 // already rendering that lane, which is rare but could happen.
2540
2541
2542 if ((lane & (root.suspendedLanes | renderLanes)) !== NoLane) {
2543 // Give up trying to hydrate and fall back to client render.
2544 return NoLane;
2545 }
2546
2547 return lane;
2548}
2549function addFiberToLanesMap(root, fiber, lanes) {
2550
2551 if (!isDevToolsPresent) {
2552 return;
2553 }
2554
2555 var pendingUpdatersLaneMap = root.pendingUpdatersLaneMap;
2556
2557 while (lanes > 0) {
2558 var index = laneToIndex(lanes);
2559 var lane = 1 << index;
2560 var updaters = pendingUpdatersLaneMap[index];
2561 updaters.add(fiber);
2562 lanes &= ~lane;
2563 }
2564}
2565function movePendingFibersToMemoized(root, lanes) {
2566
2567 if (!isDevToolsPresent) {
2568 return;
2569 }
2570
2571 var pendingUpdatersLaneMap = root.pendingUpdatersLaneMap;
2572 var memoizedUpdaters = root.memoizedUpdaters;
2573
2574 while (lanes > 0) {
2575 var index = laneToIndex(lanes);
2576 var lane = 1 << index;
2577 var updaters = pendingUpdatersLaneMap[index];
2578
2579 if (updaters.size > 0) {
2580 updaters.forEach(function (fiber) {
2581 var alternate = fiber.alternate;
2582
2583 if (alternate === null || !memoizedUpdaters.has(alternate)) {
2584 memoizedUpdaters.add(fiber);
2585 }
2586 });
2587 updaters.clear();
2588 }
2589
2590 lanes &= ~lane;
2591 }
2592}
2593function getTransitionsForLanes(root, lanes) {
2594 {
2595 return null;
2596 }
2597}
2598
2599var NoEventPriority = NoLane;
2600var DiscreteEventPriority = SyncLane;
2601var ContinuousEventPriority = InputContinuousLane;
2602var DefaultEventPriority = DefaultLane;
2603var IdleEventPriority = IdleLane;
2604function higherEventPriority(a, b) {
2605 return a !== 0 && a < b ? a : b;
2606}
2607function lowerEventPriority(a, b) {
2608 return a === 0 || a > b ? a : b;
2609}
2610function isHigherEventPriority(a, b) {
2611 return a !== 0 && a < b;
2612}
2613function eventPriorityToLane(updatePriority) {
2614 return updatePriority;
2615}
2616function lanesToEventPriority(lanes) {
2617 var lane = getHighestPriorityLane(lanes);
2618
2619 if (!isHigherEventPriority(DiscreteEventPriority, lane)) {
2620 return DiscreteEventPriority;
2621 }
2622
2623 if (!isHigherEventPriority(ContinuousEventPriority, lane)) {
2624 return ContinuousEventPriority;
2625 }
2626
2627 if (includesNonIdleWork(lane)) {
2628 return DefaultEventPriority;
2629 }
2630
2631 return IdleEventPriority;
2632}
2633
2634function setCurrentUpdatePriority(newPriority, // Closure will consistently not inline this function when it has arity 1
2635// however when it has arity 2 even if the second arg is omitted at every
2636// callsite it seems to inline it even when the internal length of the function
2637// is much longer. I hope this is consistent enough to rely on across builds
2638IntentionallyUnusedArgument) {
2639 ReactDOMSharedInternals.p
2640 /* currentUpdatePriority */
2641 = newPriority;
2642}
2643function getCurrentUpdatePriority() {
2644 return ReactDOMSharedInternals.p;
2645 /* currentUpdatePriority */
2646}
2647function resolveUpdatePriority() {
2648 var updatePriority = ReactDOMSharedInternals.p;
2649 /* currentUpdatePriority */
2650
2651 if (updatePriority !== NoEventPriority) {
2652 return updatePriority;
2653 }
2654
2655 var currentEvent = window.event;
2656
2657 if (currentEvent === undefined) {
2658 return DefaultEventPriority;
2659 }
2660
2661 return getEventPriority(currentEvent.type);
2662}
2663function runWithPriority(priority, fn) {
2664 var previousPriority = getCurrentUpdatePriority();
2665
2666 try {
2667 setCurrentUpdatePriority(priority);
2668 return fn();
2669 } finally {
2670 setCurrentUpdatePriority(previousPriority);
2671 }
2672}
2673
2674var randomKey = Math.random().toString(36).slice(2);
2675var internalInstanceKey = '__reactFiber$' + randomKey;
2676var internalPropsKey = '__reactProps$' + randomKey;
2677var internalContainerInstanceKey = '__reactContainer$' + randomKey;
2678var internalEventHandlersKey = '__reactEvents$' + randomKey;
2679var internalEventHandlerListenersKey = '__reactListeners$' + randomKey;
2680var internalEventHandlesSetKey = '__reactHandles$' + randomKey;
2681var internalRootNodeResourcesKey = '__reactResources$' + randomKey;
2682var internalHoistableMarker = '__reactMarker$' + randomKey;
2683function detachDeletedInstance(node) {
2684 // TODO: This function is only called on host components. I don't think all of
2685 // these fields are relevant.
2686 delete node[internalInstanceKey];
2687 delete node[internalPropsKey];
2688 delete node[internalEventHandlersKey];
2689 delete node[internalEventHandlerListenersKey];
2690 delete node[internalEventHandlesSetKey];
2691}
2692function precacheFiberNode(hostInst, node) {
2693 node[internalInstanceKey] = hostInst;
2694}
2695function markContainerAsRoot(hostRoot, node) {
2696 // $FlowFixMe[prop-missing]
2697 node[internalContainerInstanceKey] = hostRoot;
2698}
2699function unmarkContainerAsRoot(node) {
2700 // $FlowFixMe[prop-missing]
2701 node[internalContainerInstanceKey] = null;
2702}
2703function isContainerMarkedAsRoot(node) {
2704 // $FlowFixMe[prop-missing]
2705 return !!node[internalContainerInstanceKey];
2706} // Given a DOM node, return the closest HostComponent or HostText fiber ancestor.
2707// If the target node is part of a hydrated or not yet rendered subtree, then
2708// this may also return a SuspenseComponent or HostRoot to indicate that.
2709// Conceptually the HostRoot fiber is a child of the Container node. So if you
2710// pass the Container node as the targetNode, you will not actually get the
2711// HostRoot back. To get to the HostRoot, you need to pass a child of it.
2712// The same thing applies to Suspense boundaries.
2713
2714function getClosestInstanceFromNode(targetNode) {
2715 var targetInst = targetNode[internalInstanceKey];
2716
2717 if (targetInst) {
2718 // Don't return HostRoot or SuspenseComponent here.
2719 return targetInst;
2720 } // If the direct event target isn't a React owned DOM node, we need to look
2721 // to see if one of its parents is a React owned DOM node.
2722
2723
2724 var parentNode = targetNode.parentNode;
2725
2726 while (parentNode) {
2727 // We'll check if this is a container root that could include
2728 // React nodes in the future. We need to check this first because
2729 // if we're a child of a dehydrated container, we need to first
2730 // find that inner container before moving on to finding the parent
2731 // instance. Note that we don't check this field on the targetNode
2732 // itself because the fibers are conceptually between the container
2733 // node and the first child. It isn't surrounding the container node.
2734 // If it's not a container, we check if it's an instance.
2735 targetInst = parentNode[internalContainerInstanceKey] || parentNode[internalInstanceKey];
2736
2737 if (targetInst) {
2738 // Since this wasn't the direct target of the event, we might have
2739 // stepped past dehydrated DOM nodes to get here. However they could
2740 // also have been non-React nodes. We need to answer which one.
2741 // If we the instance doesn't have any children, then there can't be
2742 // a nested suspense boundary within it. So we can use this as a fast
2743 // bailout. Most of the time, when people add non-React children to
2744 // the tree, it is using a ref to a child-less DOM node.
2745 // Normally we'd only need to check one of the fibers because if it
2746 // has ever gone from having children to deleting them or vice versa
2747 // it would have deleted the dehydrated boundary nested inside already.
2748 // However, since the HostRoot starts out with an alternate it might
2749 // have one on the alternate so we need to check in case this was a
2750 // root.
2751 var alternate = targetInst.alternate;
2752
2753 if (targetInst.child !== null || alternate !== null && alternate.child !== null) {
2754 // Next we need to figure out if the node that skipped past is
2755 // nested within a dehydrated boundary and if so, which one.
2756 var suspenseInstance = getParentSuspenseInstance(targetNode);
2757
2758 while (suspenseInstance !== null) {
2759 // We found a suspense instance. That means that we haven't
2760 // hydrated it yet. Even though we leave the comments in the
2761 // DOM after hydrating, and there are boundaries in the DOM
2762 // that could already be hydrated, we wouldn't have found them
2763 // through this pass since if the target is hydrated it would
2764 // have had an internalInstanceKey on it.
2765 // Let's get the fiber associated with the SuspenseComponent
2766 // as the deepest instance.
2767 // $FlowFixMe[prop-missing]
2768 var targetSuspenseInst = suspenseInstance[internalInstanceKey];
2769
2770 if (targetSuspenseInst) {
2771 return targetSuspenseInst;
2772 } // If we don't find a Fiber on the comment, it might be because
2773 // we haven't gotten to hydrate it yet. There might still be a
2774 // parent boundary that hasn't above this one so we need to find
2775 // the outer most that is known.
2776
2777
2778 suspenseInstance = getParentSuspenseInstance(suspenseInstance); // If we don't find one, then that should mean that the parent
2779 // host component also hasn't hydrated yet. We can return it
2780 // below since it will bail out on the isMounted check later.
2781 }
2782 }
2783
2784 return targetInst;
2785 }
2786
2787 targetNode = parentNode;
2788 parentNode = targetNode.parentNode;
2789 }
2790
2791 return null;
2792}
2793/**
2794 * Given a DOM node, return the ReactDOMComponent or ReactDOMTextComponent
2795 * instance, or null if the node was not rendered by this React.
2796 */
2797
2798function getInstanceFromNode(node) {
2799 var inst = node[internalInstanceKey] || node[internalContainerInstanceKey];
2800
2801 if (inst) {
2802 var tag = inst.tag;
2803
2804 if (tag === HostComponent || tag === HostText || tag === SuspenseComponent || tag === HostHoistable || tag === HostSingleton || tag === HostRoot) {
2805 return inst;
2806 } else {
2807 return null;
2808 }
2809 }
2810
2811 return null;
2812}
2813/**
2814 * Given a ReactDOMComponent or ReactDOMTextComponent, return the corresponding
2815 * DOM node.
2816 */
2817
2818function getNodeFromInstance(inst) {
2819 var tag = inst.tag;
2820
2821 if (tag === HostComponent || tag === HostHoistable || tag === HostSingleton || tag === HostText) {
2822 // In Fiber this, is just the state node right now. We assume it will be
2823 // a host component or host text.
2824 return inst.stateNode;
2825 } // Without this first invariant, passing a non-DOM-component triggers the next
2826 // invariant for a missing parent, which is super confusing.
2827
2828
2829 throw new Error('getNodeFromInstance: Invalid argument.');
2830}
2831function getFiberCurrentPropsFromNode(node) {
2832 return node[internalPropsKey] || null;
2833}
2834function updateFiberProps(node, props) {
2835 node[internalPropsKey] = props;
2836}
2837function getEventListenerSet(node) {
2838 var elementListenerSet = node[internalEventHandlersKey];
2839
2840 if (elementListenerSet === undefined) {
2841 elementListenerSet = node[internalEventHandlersKey] = new Set();
2842 }
2843
2844 return elementListenerSet;
2845}
2846function getResourcesFromRoot(root) {
2847 var resources = root[internalRootNodeResourcesKey];
2848
2849 if (!resources) {
2850 resources = root[internalRootNodeResourcesKey] = {
2851 hoistableStyles: new Map(),
2852 hoistableScripts: new Map()
2853 };
2854 }
2855
2856 return resources;
2857}
2858function isMarkedHoistable(node) {
2859 return !!node[internalHoistableMarker];
2860}
2861function markNodeAsHoistable(node) {
2862 node[internalHoistableMarker] = true;
2863}
2864function isOwnedInstance(node) {
2865 return !!(node[internalHoistableMarker] || node[internalInstanceKey]);
2866}
2867
2868var allNativeEvents = new Set();
2869/**
2870 * Mapping from registration name to event name
2871 */
2872
2873
2874var registrationNameDependencies = {};
2875/**
2876 * Mapping from lowercase registration names to the properly cased version,
2877 * used to warn in the case of missing event handlers. Available
2878 * only in __DEV__.
2879 * @type {Object}
2880 */
2881
2882var possibleRegistrationNames = {} ; // Trust the developer to only use possibleRegistrationNames in true
2883
2884function registerTwoPhaseEvent(registrationName, dependencies) {
2885 registerDirectEvent(registrationName, dependencies);
2886 registerDirectEvent(registrationName + 'Capture', dependencies);
2887}
2888function registerDirectEvent(registrationName, dependencies) {
2889 {
2890 if (registrationNameDependencies[registrationName]) {
2891 error('EventRegistry: More than one plugin attempted to publish the same ' + 'registration name, `%s`.', registrationName);
2892 }
2893 }
2894
2895 registrationNameDependencies[registrationName] = dependencies;
2896
2897 {
2898 var lowerCasedName = registrationName.toLowerCase();
2899 possibleRegistrationNames[lowerCasedName] = registrationName;
2900
2901 if (registrationName === 'onDoubleClick') {
2902 possibleRegistrationNames.ondblclick = registrationName;
2903 }
2904 }
2905
2906 for (var i = 0; i < dependencies.length; i++) {
2907 allNativeEvents.add(dependencies[i]);
2908 }
2909}
2910
2911var canUseDOM = !!(typeof window !== 'undefined' && typeof window.document !== 'undefined' && typeof window.document.createElement !== 'undefined');
2912
2913var hasReadOnlyValue = {
2914 button: true,
2915 checkbox: true,
2916 image: true,
2917 hidden: true,
2918 radio: true,
2919 reset: true,
2920 submit: true
2921};
2922function checkControlledValueProps(tagName, props) {
2923 {
2924 if (!(hasReadOnlyValue[props.type] || props.onChange || props.onInput || props.readOnly || props.disabled || props.value == null)) {
2925 if (tagName === 'select') {
2926 error('You provided a `value` prop to a form field without an ' + '`onChange` handler. This will render a read-only field. If ' + 'the field should be mutable use `defaultValue`. Otherwise, set `onChange`.');
2927 } else {
2928 error('You provided a `value` prop to a form field without an ' + '`onChange` handler. This will render a read-only field. If ' + 'the field should be mutable use `defaultValue`. Otherwise, set either `onChange` or `readOnly`.');
2929 }
2930 }
2931
2932 if (!(props.onChange || props.readOnly || props.disabled || props.checked == null)) {
2933 error('You provided a `checked` prop to a form field without an ' + '`onChange` handler. This will render a read-only field. If ' + 'the field should be mutable use `defaultChecked`. Otherwise, ' + 'set either `onChange` or `readOnly`.');
2934 }
2935 }
2936}
2937
2938/* eslint-disable max-len */
2939
2940var ATTRIBUTE_NAME_START_CHAR = ":A-Z_a-z\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02FF\\u0370-\\u037D\\u037F-\\u1FFF\\u200C-\\u200D\\u2070-\\u218F\\u2C00-\\u2FEF\\u3001-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFFD";
2941/* eslint-enable max-len */
2942
2943var ATTRIBUTE_NAME_CHAR = ATTRIBUTE_NAME_START_CHAR + "\\-.0-9\\u00B7\\u0300-\\u036F\\u203F-\\u2040";
2944var VALID_ATTRIBUTE_NAME_REGEX = new RegExp('^[' + ATTRIBUTE_NAME_START_CHAR + '][' + ATTRIBUTE_NAME_CHAR + ']*$');
2945var illegalAttributeNameCache = {};
2946var validatedAttributeNameCache = {};
2947function isAttributeNameSafe(attributeName) {
2948 if (hasOwnProperty.call(validatedAttributeNameCache, attributeName)) {
2949 return true;
2950 }
2951
2952 if (hasOwnProperty.call(illegalAttributeNameCache, attributeName)) {
2953 return false;
2954 }
2955
2956 if (VALID_ATTRIBUTE_NAME_REGEX.test(attributeName)) {
2957 validatedAttributeNameCache[attributeName] = true;
2958 return true;
2959 }
2960
2961 illegalAttributeNameCache[attributeName] = true;
2962
2963 {
2964 error('Invalid attribute name: `%s`', attributeName);
2965 }
2966
2967 return false;
2968}
2969
2970/**
2971 * Get the value for a attribute on a node. Only used in DEV for SSR validation.
2972 * The third argument is used as a hint of what the expected value is. Some
2973 * attributes have multiple equivalent values.
2974 */
2975
2976function getValueForAttribute(node, name, expected) {
2977 {
2978 if (!isAttributeNameSafe(name)) {
2979 return;
2980 }
2981
2982 if (!node.hasAttribute(name)) {
2983 // shouldRemoveAttribute
2984 switch (typeof expected) {
2985 case 'function':
2986 case 'symbol':
2987 // eslint-disable-line
2988 return expected;
2989
2990 case 'boolean':
2991 {
2992 var prefix = name.toLowerCase().slice(0, 5);
2993
2994 if (prefix !== 'data-' && prefix !== 'aria-') {
2995 return expected;
2996 }
2997 }
2998 }
2999
3000 return expected === undefined ? undefined : null;
3001 }
3002
3003 var value = node.getAttribute(name);
3004
3005 {
3006 checkAttributeStringCoercion(expected, name);
3007 }
3008
3009 if (value === '' + expected) {
3010 return expected;
3011 }
3012
3013 return value;
3014 }
3015}
3016function getValueForAttributeOnCustomComponent(node, name, expected) {
3017 {
3018 if (!isAttributeNameSafe(name)) {
3019 return;
3020 }
3021
3022 if (!node.hasAttribute(name)) {
3023 // shouldRemoveAttribute
3024 switch (typeof expected) {
3025 case 'symbol':
3026 case 'object':
3027 // Symbols and objects are ignored when they're emitted so
3028 // it would be expected that they end up not having an attribute.
3029 return expected;
3030
3031 case 'function':
3032 return expected;
3033
3034 case 'boolean':
3035 if (expected === false) {
3036 return expected;
3037 }
3038
3039 }
3040
3041 return expected === undefined ? undefined : null;
3042 }
3043
3044 var value = node.getAttribute(name);
3045
3046 if (value === '' && expected === true) {
3047 return true;
3048 }
3049
3050 {
3051 checkAttributeStringCoercion(expected, name);
3052 }
3053
3054 if (value === '' + expected) {
3055 return expected;
3056 }
3057
3058 return value;
3059 }
3060}
3061function setValueForAttribute(node, name, value) {
3062 if (isAttributeNameSafe(name)) {
3063 // If the prop isn't in the special list, treat it as a simple attribute.
3064 // shouldRemoveAttribute
3065 if (value === null) {
3066 node.removeAttribute(name);
3067 return;
3068 }
3069
3070 switch (typeof value) {
3071 case 'undefined':
3072 case 'function':
3073 case 'symbol':
3074 // eslint-disable-line
3075 node.removeAttribute(name);
3076 return;
3077
3078 case 'boolean':
3079 {
3080 var prefix = name.toLowerCase().slice(0, 5);
3081
3082 if (prefix !== 'data-' && prefix !== 'aria-') {
3083 node.removeAttribute(name);
3084 return;
3085 }
3086 }
3087 }
3088
3089 {
3090 checkAttributeStringCoercion(value, name);
3091 }
3092
3093 node.setAttribute(name, '' + value);
3094 }
3095}
3096function setValueForKnownAttribute(node, name, value) {
3097 if (value === null) {
3098 node.removeAttribute(name);
3099 return;
3100 }
3101
3102 switch (typeof value) {
3103 case 'undefined':
3104 case 'function':
3105 case 'symbol':
3106 case 'boolean':
3107 {
3108 node.removeAttribute(name);
3109 return;
3110 }
3111 }
3112
3113 {
3114 checkAttributeStringCoercion(value, name);
3115 }
3116
3117 node.setAttribute(name, '' + value);
3118}
3119function setValueForNamespacedAttribute(node, namespace, name, value) {
3120 if (value === null) {
3121 node.removeAttribute(name);
3122 return;
3123 }
3124
3125 switch (typeof value) {
3126 case 'undefined':
3127 case 'function':
3128 case 'symbol':
3129 case 'boolean':
3130 {
3131 node.removeAttribute(name);
3132 return;
3133 }
3134 }
3135
3136 {
3137 checkAttributeStringCoercion(value, name);
3138 }
3139
3140 node.setAttributeNS(namespace, name, '' + value);
3141}
3142function setValueForPropertyOnCustomComponent(node, name, value) {
3143 if (name[0] === 'o' && name[1] === 'n') {
3144 var useCapture = name.endsWith('Capture');
3145 var eventName = name.slice(2, useCapture ? name.length - 7 : undefined);
3146 var prevProps = getFiberCurrentPropsFromNode(node);
3147 var prevValue = prevProps != null ? prevProps[name] : null;
3148
3149 if (typeof prevValue === 'function') {
3150 node.removeEventListener(eventName, prevValue, useCapture);
3151 }
3152
3153 if (typeof value === 'function') {
3154 if (typeof prevValue !== 'function' && prevValue !== null) {
3155 // If we previously assigned a non-function type into this node, then
3156 // remove it when switching to event listener mode.
3157 if (name in node) {
3158 node[name] = null;
3159 } else if (node.hasAttribute(name)) {
3160 node.removeAttribute(name);
3161 }
3162 } // $FlowFixMe[incompatible-cast] value can't be casted to EventListener.
3163
3164
3165 node.addEventListener(eventName, value, useCapture);
3166 return;
3167 }
3168 }
3169
3170 if (name in node) {
3171 node[name] = value;
3172 return;
3173 }
3174
3175 if (value === true) {
3176 node.setAttribute(name, '');
3177 return;
3178 } // From here, it's the same as any attribute
3179
3180
3181 setValueForAttribute(node, name, value);
3182}
3183
3184var prefix;
3185function describeBuiltInComponentFrame(name) {
3186 {
3187 if (prefix === undefined) {
3188 // Extract the VM specific prefix used by each line.
3189 try {
3190 throw Error();
3191 } catch (x) {
3192 var match = x.stack.trim().match(/\n( *(at )?)/);
3193 prefix = match && match[1] || '';
3194 }
3195 } // We use the prefix to ensure our stacks line up with native stack frames.
3196
3197
3198 return '\n' + prefix + name;
3199 }
3200}
3201function describeDebugInfoFrame(name, env) {
3202 return describeBuiltInComponentFrame(name + (env ? ' (' + env + ')' : ''));
3203}
3204var reentry = false;
3205var componentFrameCache;
3206
3207{
3208 var PossiblyWeakMap$1 = typeof WeakMap === 'function' ? WeakMap : Map;
3209 componentFrameCache = new PossiblyWeakMap$1();
3210}
3211/**
3212 * Leverages native browser/VM stack frames to get proper details (e.g.
3213 * filename, line + col number) for a single component in a component stack. We
3214 * do this by:
3215 * (1) throwing and catching an error in the function - this will be our
3216 * control error.
3217 * (2) calling the component which will eventually throw an error that we'll
3218 * catch - this will be our sample error.
3219 * (3) diffing the control and sample error stacks to find the stack frame
3220 * which represents our component.
3221 */
3222
3223
3224function describeNativeComponentFrame(fn, construct) {
3225 // If something asked for a stack inside a fake render, it should get ignored.
3226 if (!fn || reentry) {
3227 return '';
3228 }
3229
3230 {
3231 var frame = componentFrameCache.get(fn);
3232
3233 if (frame !== undefined) {
3234 return frame;
3235 }
3236 }
3237
3238 reentry = true;
3239 var previousPrepareStackTrace = Error.prepareStackTrace; // $FlowFixMe[incompatible-type] It does accept undefined.
3240
3241 Error.prepareStackTrace = undefined;
3242 var previousDispatcher = null;
3243
3244 {
3245 previousDispatcher = ReactSharedInternals.H; // Set the dispatcher in DEV because this might be call in the render function
3246 // for warnings.
3247
3248 ReactSharedInternals.H = null;
3249 disableLogs();
3250 }
3251 /**
3252 * Finding a common stack frame between sample and control errors can be
3253 * tricky given the different types and levels of stack trace truncation from
3254 * different JS VMs. So instead we'll attempt to control what that common
3255 * frame should be through this object method:
3256 * Having both the sample and control errors be in the function under the
3257 * `DescribeNativeComponentFrameRoot` property, + setting the `name` and
3258 * `displayName` properties of the function ensures that a stack
3259 * frame exists that has the method name `DescribeNativeComponentFrameRoot` in
3260 * it for both control and sample stacks.
3261 */
3262
3263
3264 var RunInRootFrame = {
3265 DetermineComponentFrameRoot: function () {
3266 var control;
3267
3268 try {
3269 // This should throw.
3270 if (construct) {
3271 // Something should be setting the props in the constructor.
3272 var Fake = function () {
3273 throw Error();
3274 }; // $FlowFixMe[prop-missing]
3275
3276
3277 Object.defineProperty(Fake.prototype, 'props', {
3278 set: function () {
3279 // We use a throwing setter instead of frozen or non-writable props
3280 // because that won't throw in a non-strict mode function.
3281 throw Error();
3282 }
3283 });
3284
3285 if (typeof Reflect === 'object' && Reflect.construct) {
3286 // We construct a different control for this case to include any extra
3287 // frames added by the construct call.
3288 try {
3289 Reflect.construct(Fake, []);
3290 } catch (x) {
3291 control = x;
3292 }
3293
3294 Reflect.construct(fn, [], Fake);
3295 } else {
3296 try {
3297 Fake.call();
3298 } catch (x) {
3299 control = x;
3300 } // $FlowFixMe[prop-missing] found when upgrading Flow
3301
3302
3303 fn.call(Fake.prototype);
3304 }
3305 } else {
3306 try {
3307 throw Error();
3308 } catch (x) {
3309 control = x;
3310 } // TODO(luna): This will currently only throw if the function component
3311 // tries to access React/ReactDOM/props. We should probably make this throw
3312 // in simple components too
3313
3314
3315 var maybePromise = fn(); // If the function component returns a promise, it's likely an async
3316 // component, which we don't yet support. Attach a noop catch handler to
3317 // silence the error.
3318 // TODO: Implement component stacks for async client components?
3319
3320 if (maybePromise && typeof maybePromise.catch === 'function') {
3321 maybePromise.catch(function () {});
3322 }
3323 }
3324 } catch (sample) {
3325 // This is inlined manually because closure doesn't do it for us.
3326 if (sample && control && typeof sample.stack === 'string') {
3327 return [sample.stack, control.stack];
3328 }
3329 }
3330
3331 return [null, null];
3332 }
3333 }; // $FlowFixMe[prop-missing]
3334
3335 RunInRootFrame.DetermineComponentFrameRoot.displayName = 'DetermineComponentFrameRoot';
3336 var namePropDescriptor = Object.getOwnPropertyDescriptor(RunInRootFrame.DetermineComponentFrameRoot, 'name'); // Before ES6, the `name` property was not configurable.
3337
3338 if (namePropDescriptor && namePropDescriptor.configurable) {
3339 // V8 utilizes a function's `name` property when generating a stack trace.
3340 Object.defineProperty(RunInRootFrame.DetermineComponentFrameRoot, // Configurable properties can be updated even if its writable descriptor
3341 // is set to `false`.
3342 // $FlowFixMe[cannot-write]
3343 'name', {
3344 value: 'DetermineComponentFrameRoot'
3345 });
3346 }
3347
3348 try {
3349 var _RunInRootFrame$Deter = RunInRootFrame.DetermineComponentFrameRoot(),
3350 sampleStack = _RunInRootFrame$Deter[0],
3351 controlStack = _RunInRootFrame$Deter[1];
3352
3353 if (sampleStack && controlStack) {
3354 // This extracts the first frame from the sample that isn't also in the control.
3355 // Skipping one frame that we assume is the frame that calls the two.
3356 var sampleLines = sampleStack.split('\n');
3357 var controlLines = controlStack.split('\n');
3358 var s = 0;
3359 var c = 0;
3360
3361 while (s < sampleLines.length && !sampleLines[s].includes('DetermineComponentFrameRoot')) {
3362 s++;
3363 }
3364
3365 while (c < controlLines.length && !controlLines[c].includes('DetermineComponentFrameRoot')) {
3366 c++;
3367 } // We couldn't find our intentionally injected common root frame, attempt
3368 // to find another common root frame by search from the bottom of the
3369 // control stack...
3370
3371
3372 if (s === sampleLines.length || c === controlLines.length) {
3373 s = sampleLines.length - 1;
3374 c = controlLines.length - 1;
3375
3376 while (s >= 1 && c >= 0 && sampleLines[s] !== controlLines[c]) {
3377 // We expect at least one stack frame to be shared.
3378 // Typically this will be the root most one. However, stack frames may be
3379 // cut off due to maximum stack limits. In this case, one maybe cut off
3380 // earlier than the other. We assume that the sample is longer or the same
3381 // and there for cut off earlier. So we should find the root most frame in
3382 // the sample somewhere in the control.
3383 c--;
3384 }
3385 }
3386
3387 for (; s >= 1 && c >= 0; s--, c--) {
3388 // Next we find the first one that isn't the same which should be the
3389 // frame that called our sample function and the control.
3390 if (sampleLines[s] !== controlLines[c]) {
3391 // In V8, the first line is describing the message but other VMs don't.
3392 // If we're about to return the first line, and the control is also on the same
3393 // line, that's a pretty good indicator that our sample threw at same line as
3394 // the control. I.e. before we entered the sample frame. So we ignore this result.
3395 // This can happen if you passed a class to function component, or non-function.
3396 if (s !== 1 || c !== 1) {
3397 do {
3398 s--;
3399 c--; // We may still have similar intermediate frames from the construct call.
3400 // The next one that isn't the same should be our match though.
3401
3402 if (c < 0 || sampleLines[s] !== controlLines[c]) {
3403 // V8 adds a "new" prefix for native classes. Let's remove it to make it prettier.
3404 var _frame = '\n' + sampleLines[s].replace(' at new ', ' at '); // If our component frame is labeled "<anonymous>"
3405 // but we have a user-provided "displayName"
3406 // splice it in to make the stack more readable.
3407
3408
3409 if (fn.displayName && _frame.includes('<anonymous>')) {
3410 _frame = _frame.replace('<anonymous>', fn.displayName);
3411 }
3412
3413 if (true) {
3414 if (typeof fn === 'function') {
3415 componentFrameCache.set(fn, _frame);
3416 }
3417 } // Return the line we found.
3418
3419
3420 return _frame;
3421 }
3422 } while (s >= 1 && c >= 0);
3423 }
3424
3425 break;
3426 }
3427 }
3428 }
3429 } finally {
3430 reentry = false;
3431
3432 {
3433 ReactSharedInternals.H = previousDispatcher;
3434 reenableLogs();
3435 }
3436
3437 Error.prepareStackTrace = previousPrepareStackTrace;
3438 } // Fallback to just using the name if we couldn't make it throw.
3439
3440
3441 var name = fn ? fn.displayName || fn.name : '';
3442 var syntheticFrame = name ? describeBuiltInComponentFrame(name) : '';
3443
3444 {
3445 if (typeof fn === 'function') {
3446 componentFrameCache.set(fn, syntheticFrame);
3447 }
3448 }
3449
3450 return syntheticFrame;
3451}
3452
3453function describeClassComponentFrame(ctor) {
3454 {
3455 return describeNativeComponentFrame(ctor, true);
3456 }
3457}
3458function describeFunctionComponentFrame(fn) {
3459 {
3460 return describeNativeComponentFrame(fn, false);
3461 }
3462}
3463
3464function describeFiber(fiber) {
3465 switch (fiber.tag) {
3466 case HostHoistable:
3467 case HostSingleton:
3468 case HostComponent:
3469 return describeBuiltInComponentFrame(fiber.type);
3470
3471 case LazyComponent:
3472 return describeBuiltInComponentFrame('Lazy');
3473
3474 case SuspenseComponent:
3475 return describeBuiltInComponentFrame('Suspense');
3476
3477 case SuspenseListComponent:
3478 return describeBuiltInComponentFrame('SuspenseList');
3479
3480 case FunctionComponent:
3481 case SimpleMemoComponent:
3482 return describeFunctionComponentFrame(fiber.type);
3483
3484 case ForwardRef:
3485 return describeFunctionComponentFrame(fiber.type.render);
3486
3487 case ClassComponent:
3488 return describeClassComponentFrame(fiber.type);
3489
3490 default:
3491 return '';
3492 }
3493}
3494
3495function getStackByFiberInDevAndProd(workInProgress) {
3496 try {
3497 var info = '';
3498 var node = workInProgress;
3499
3500 do {
3501 info += describeFiber(node);
3502
3503 if (true) {
3504 // Add any Server Component stack frames in reverse order.
3505 var debugInfo = node._debugInfo;
3506
3507 if (debugInfo) {
3508 for (var i = debugInfo.length - 1; i >= 0; i--) {
3509 var entry = debugInfo[i];
3510
3511 if (typeof entry.name === 'string') {
3512 info += describeDebugInfoFrame(entry.name, entry.env);
3513 }
3514 }
3515 }
3516 } // $FlowFixMe[incompatible-type] we bail out when we get a null
3517
3518
3519 node = node.return;
3520 } while (node);
3521
3522 return info;
3523 } catch (x) {
3524 return '\nError generating stack: ' + x.message + '\n' + x.stack;
3525 }
3526}
3527
3528var current = null;
3529var isRendering = false;
3530function getCurrentFiberOwnerNameInDevOrNull() {
3531 {
3532 if (current === null) {
3533 return null;
3534 }
3535
3536 var owner = current._debugOwner;
3537
3538 if (owner != null) {
3539 return getComponentNameFromOwner(owner);
3540 }
3541 }
3542
3543 return null;
3544}
3545
3546function getCurrentFiberStackInDev() {
3547 {
3548 if (current === null) {
3549 return '';
3550 } // Safe because if current fiber exists, we are reconciling,
3551 // and it is guaranteed to be the work-in-progress version.
3552
3553
3554 return getStackByFiberInDevAndProd(current);
3555 }
3556}
3557
3558function resetCurrentFiber() {
3559 {
3560 ReactSharedInternals.getCurrentStack = null;
3561 current = null;
3562 isRendering = false;
3563 }
3564}
3565function setCurrentFiber(fiber) {
3566 {
3567 ReactSharedInternals.getCurrentStack = fiber === null ? null : getCurrentFiberStackInDev;
3568 current = fiber;
3569 isRendering = false;
3570 }
3571}
3572function getCurrentFiber() {
3573 {
3574 return current;
3575 }
3576}
3577function setIsRendering(rendering) {
3578 {
3579 isRendering = rendering;
3580 }
3581}
3582
3583// around this limitation, we use an opaque type that can only be obtained by
3584// passing the value through getToStringValue first.
3585
3586function toString(value) {
3587 // The coercion safety check is performed in getToStringValue().
3588 // eslint-disable-next-line react-internal/safe-string-coercion
3589 return '' + value;
3590}
3591function getToStringValue(value) {
3592 switch (typeof value) {
3593 case 'bigint':
3594 case 'boolean':
3595 case 'number':
3596 case 'string':
3597 case 'undefined':
3598 return value;
3599
3600 case 'object':
3601 {
3602 checkFormFieldValueStringCoercion(value);
3603 }
3604
3605 return value;
3606
3607 default:
3608 // function, symbol are assigned as empty strings
3609 return '';
3610 }
3611}
3612
3613function isCheckable(elem) {
3614 var type = elem.type;
3615 var nodeName = elem.nodeName;
3616 return nodeName && nodeName.toLowerCase() === 'input' && (type === 'checkbox' || type === 'radio');
3617}
3618
3619function getTracker(node) {
3620 return node._valueTracker;
3621}
3622
3623function detachTracker(node) {
3624 node._valueTracker = null;
3625}
3626
3627function getValueFromNode(node) {
3628 var value = '';
3629
3630 if (!node) {
3631 return value;
3632 }
3633
3634 if (isCheckable(node)) {
3635 value = node.checked ? 'true' : 'false';
3636 } else {
3637 value = node.value;
3638 }
3639
3640 return value;
3641}
3642
3643function trackValueOnNode(node) {
3644 var valueField = isCheckable(node) ? 'checked' : 'value';
3645 var descriptor = Object.getOwnPropertyDescriptor(node.constructor.prototype, valueField);
3646
3647 {
3648 checkFormFieldValueStringCoercion(node[valueField]);
3649 }
3650
3651 var currentValue = '' + node[valueField]; // if someone has already defined a value or Safari, then bail
3652 // and don't track value will cause over reporting of changes,
3653 // but it's better then a hard failure
3654 // (needed for certain tests that spyOn input values and Safari)
3655
3656 if (node.hasOwnProperty(valueField) || typeof descriptor === 'undefined' || typeof descriptor.get !== 'function' || typeof descriptor.set !== 'function') {
3657 return;
3658 }
3659
3660 var get = descriptor.get,
3661 set = descriptor.set;
3662 Object.defineProperty(node, valueField, {
3663 configurable: true,
3664 // $FlowFixMe[missing-this-annot]
3665 get: function () {
3666 return get.call(this);
3667 },
3668 // $FlowFixMe[missing-local-annot]
3669 // $FlowFixMe[missing-this-annot]
3670 set: function (value) {
3671 {
3672 checkFormFieldValueStringCoercion(value);
3673 }
3674
3675 currentValue = '' + value;
3676 set.call(this, value);
3677 }
3678 }); // We could've passed this the first time
3679 // but it triggers a bug in IE11 and Edge 14/15.
3680 // Calling defineProperty() again should be equivalent.
3681 // https://github.com/facebook/react/issues/11768
3682
3683 Object.defineProperty(node, valueField, {
3684 enumerable: descriptor.enumerable
3685 });
3686 var tracker = {
3687 getValue: function () {
3688 return currentValue;
3689 },
3690 setValue: function (value) {
3691 {
3692 checkFormFieldValueStringCoercion(value);
3693 }
3694
3695 currentValue = '' + value;
3696 },
3697 stopTracking: function () {
3698 detachTracker(node);
3699 delete node[valueField];
3700 }
3701 };
3702 return tracker;
3703}
3704
3705function track(node) {
3706 if (getTracker(node)) {
3707 return;
3708 }
3709
3710 node._valueTracker = trackValueOnNode(node);
3711}
3712function updateValueIfChanged(node) {
3713 if (!node) {
3714 return false;
3715 }
3716
3717 var tracker = getTracker(node); // if there is no tracker at this point it's unlikely
3718 // that trying again will succeed
3719
3720 if (!tracker) {
3721 return true;
3722 }
3723
3724 var lastValue = tracker.getValue();
3725 var nextValue = getValueFromNode(node);
3726
3727 if (nextValue !== lastValue) {
3728 tracker.setValue(nextValue);
3729 return true;
3730 }
3731
3732 return false;
3733}
3734
3735function getActiveElement(doc) {
3736 doc = doc || (typeof document !== 'undefined' ? document : undefined);
3737
3738 if (typeof doc === 'undefined') {
3739 return null;
3740 }
3741
3742 try {
3743 return doc.activeElement || doc.body;
3744 } catch (e) {
3745 return doc.body;
3746 }
3747}
3748
3749// When passing user input into querySelector(All) the embedded string must not alter
3750// the semantics of the query. This escape function is safe to use when we know the
3751// provided value is going to be wrapped in double quotes as part of an attribute selector
3752// Do not use it anywhere else
3753// we escape double quotes and backslashes
3754var escapeSelectorAttributeValueInsideDoubleQuotesRegex = /[\n\"\\]/g;
3755function escapeSelectorAttributeValueInsideDoubleQuotes(value) {
3756 return value.replace(escapeSelectorAttributeValueInsideDoubleQuotesRegex, function (ch) {
3757 return '\\' + ch.charCodeAt(0).toString(16) + ' ';
3758 });
3759}
3760
3761var didWarnValueDefaultValue$1 = false;
3762var didWarnCheckedDefaultChecked = false;
3763/**
3764 * Implements an <input> host component that allows setting these optional
3765 * props: `checked`, `value`, `defaultChecked`, and `defaultValue`.
3766 *
3767 * If `checked` or `value` are not supplied (or null/undefined), user actions
3768 * that affect the checked state or value will trigger updates to the element.
3769 *
3770 * If they are supplied (and not null/undefined), the rendered element will not
3771 * trigger updates to the element. Instead, the props must change in order for
3772 * the rendered element to be updated.
3773 *
3774 * The rendered element will be initialized as unchecked (or `defaultChecked`)
3775 * with an empty value (or `defaultValue`).
3776 *
3777 * See http://www.w3.org/TR/2012/WD-html5-20121025/the-input-element.html
3778 */
3779
3780function validateInputProps(element, props) {
3781 {
3782 // Normally we check for undefined and null the same, but explicitly specifying both
3783 // properties, at all is probably worth warning for. We could move this either direction
3784 // and just make it ok to pass null or just check hasOwnProperty.
3785 if (props.checked !== undefined && props.defaultChecked !== undefined && !didWarnCheckedDefaultChecked) {
3786 error('%s contains an input of type %s with both checked and defaultChecked props. ' + 'Input elements must be either controlled or uncontrolled ' + '(specify either the checked prop, or the defaultChecked prop, but not ' + 'both). Decide between using a controlled or uncontrolled input ' + 'element and remove one of these props. More info: ' + 'https://react.dev/link/controlled-components', getCurrentFiberOwnerNameInDevOrNull() || 'A component', props.type);
3787
3788 didWarnCheckedDefaultChecked = true;
3789 }
3790
3791 if (props.value !== undefined && props.defaultValue !== undefined && !didWarnValueDefaultValue$1) {
3792 error('%s contains an input of type %s with both value and defaultValue props. ' + 'Input elements must be either controlled or uncontrolled ' + '(specify either the value prop, or the defaultValue prop, but not ' + 'both). Decide between using a controlled or uncontrolled input ' + 'element and remove one of these props. More info: ' + 'https://react.dev/link/controlled-components', getCurrentFiberOwnerNameInDevOrNull() || 'A component', props.type);
3793
3794 didWarnValueDefaultValue$1 = true;
3795 }
3796 }
3797}
3798function updateInput(element, value, defaultValue, lastDefaultValue, checked, defaultChecked, type, name) {
3799 var node = element; // Temporarily disconnect the input from any radio buttons.
3800 // Changing the type or name as the same time as changing the checked value
3801 // needs to be atomically applied. We can only ensure that by disconnecting
3802 // the name while do the mutations and then reapply the name after that's done.
3803
3804 node.name = '';
3805
3806 if (type != null && typeof type !== 'function' && typeof type !== 'symbol' && typeof type !== 'boolean') {
3807 {
3808 checkAttributeStringCoercion(type, 'type');
3809 }
3810
3811 node.type = type;
3812 } else {
3813 node.removeAttribute('type');
3814 }
3815
3816 if (value != null) {
3817 if (type === 'number') {
3818 if ( // $FlowFixMe[incompatible-type]
3819 value === 0 && node.value === '' || // We explicitly want to coerce to number here if possible.
3820 // eslint-disable-next-line
3821 node.value != value) {
3822 node.value = toString(getToStringValue(value));
3823 }
3824 } else if (node.value !== toString(getToStringValue(value))) {
3825 node.value = toString(getToStringValue(value));
3826 }
3827 } else if (type === 'submit' || type === 'reset') {
3828 // Submit/reset inputs need the attribute removed completely to avoid
3829 // blank-text buttons.
3830 node.removeAttribute('value');
3831 }
3832
3833 {
3834 // When syncing the value attribute, the value comes from a cascade of
3835 // properties:
3836 // 1. The value React property
3837 // 2. The defaultValue React property
3838 // 3. Otherwise there should be no change
3839 if (value != null) {
3840 setDefaultValue(node, type, getToStringValue(value));
3841 } else if (defaultValue != null) {
3842 setDefaultValue(node, type, getToStringValue(defaultValue));
3843 } else if (lastDefaultValue != null) {
3844 node.removeAttribute('value');
3845 }
3846 }
3847
3848 {
3849 // When syncing the checked attribute, it only changes when it needs
3850 // to be removed, such as transitioning from a checkbox into a text input
3851 if (checked == null && defaultChecked != null) {
3852 node.defaultChecked = !!defaultChecked;
3853 }
3854 }
3855
3856 if (checked != null) {
3857 // Important to set this even if it's not a change in order to update input
3858 // value tracking with radio buttons
3859 // TODO: Should really update input value tracking for the whole radio
3860 // button group in an effect or something (similar to #27024)
3861 node.checked = checked && typeof checked !== 'function' && typeof checked !== 'symbol';
3862 }
3863
3864 if (name != null && typeof name !== 'function' && typeof name !== 'symbol' && typeof name !== 'boolean') {
3865 {
3866 checkAttributeStringCoercion(name, 'name');
3867 }
3868
3869 node.name = toString(getToStringValue(name));
3870 } else {
3871 node.removeAttribute('name');
3872 }
3873}
3874function initInput(element, value, defaultValue, checked, defaultChecked, type, name, isHydrating) {
3875 var node = element;
3876
3877 if (type != null && typeof type !== 'function' && typeof type !== 'symbol' && typeof type !== 'boolean') {
3878 {
3879 checkAttributeStringCoercion(type, 'type');
3880 }
3881
3882 node.type = type;
3883 }
3884
3885 if (value != null || defaultValue != null) {
3886 var isButton = type === 'submit' || type === 'reset'; // Avoid setting value attribute on submit/reset inputs as it overrides the
3887 // default value provided by the browser. See: #12872
3888
3889 if (isButton && (value === undefined || value === null)) {
3890 return;
3891 }
3892
3893 var defaultValueStr = defaultValue != null ? toString(getToStringValue(defaultValue)) : '';
3894 var initialValue = value != null ? toString(getToStringValue(value)) : defaultValueStr; // Do not assign value if it is already set. This prevents user text input
3895 // from being lost during SSR hydration.
3896
3897 if (!isHydrating) {
3898 {
3899 // When syncing the value attribute, the value property should use
3900 // the wrapperState._initialValue property. This uses:
3901 //
3902 // 1. The value React property when present
3903 // 2. The defaultValue React property when present
3904 // 3. An empty string
3905 if (initialValue !== node.value) {
3906 node.value = initialValue;
3907 }
3908 }
3909 }
3910
3911 {
3912 // Otherwise, the value attribute is synchronized to the property,
3913 // so we assign defaultValue to the same thing as the value property
3914 // assignment step above.
3915 node.defaultValue = initialValue;
3916 }
3917 } // Normally, we'd just do `node.checked = node.checked` upon initial mount, less this bug
3918 // this is needed to work around a chrome bug where setting defaultChecked
3919 // will sometimes influence the value of checked (even after detachment).
3920 // Reference: https://bugs.chromium.org/p/chromium/issues/detail?id=608416
3921 // We need to temporarily unset name to avoid disrupting radio button groups.
3922
3923
3924 var checkedOrDefault = checked != null ? checked : defaultChecked; // TODO: This 'function' or 'symbol' check isn't replicated in other places
3925 // so this semantic is inconsistent.
3926
3927 var initialChecked = typeof checkedOrDefault !== 'function' && typeof checkedOrDefault !== 'symbol' && !!checkedOrDefault;
3928
3929 if (isHydrating) {
3930 // Detach .checked from .defaultChecked but leave user input alone
3931 node.checked = node.checked;
3932 } else {
3933 node.checked = !!initialChecked;
3934 }
3935
3936 {
3937 // When syncing the checked attribute, both the checked property and
3938 // attribute are assigned at the same time using defaultChecked. This uses:
3939 //
3940 // 1. The checked React property when present
3941 // 2. The defaultChecked React property when present
3942 // 3. Otherwise, false
3943 node.defaultChecked = !node.defaultChecked;
3944 node.defaultChecked = !!initialChecked;
3945 } // Name needs to be set at the end so that it applies atomically to connected radio buttons.
3946
3947
3948 if (name != null && typeof name !== 'function' && typeof name !== 'symbol' && typeof name !== 'boolean') {
3949 {
3950 checkAttributeStringCoercion(name, 'name');
3951 }
3952
3953 node.name = name;
3954 }
3955}
3956function restoreControlledInputState(element, props) {
3957 var rootNode = element;
3958 updateInput(rootNode, props.value, props.defaultValue, props.defaultValue, props.checked, props.defaultChecked, props.type, props.name);
3959 var name = props.name;
3960
3961 if (props.type === 'radio' && name != null) {
3962 var queryRoot = rootNode;
3963
3964 while (queryRoot.parentNode) {
3965 queryRoot = queryRoot.parentNode;
3966 } // If `rootNode.form` was non-null, then we could try `form.elements`,
3967 // but that sometimes behaves strangely in IE8. We could also try using
3968 // `form.getElementsByName`, but that will only return direct children
3969 // and won't include inputs that use the HTML5 `form=` attribute. Since
3970 // the input might not even be in a form. It might not even be in the
3971 // document. Let's just use the local `querySelectorAll` to ensure we don't
3972 // miss anything.
3973
3974
3975 {
3976 checkAttributeStringCoercion(name, 'name');
3977 }
3978
3979 var group = queryRoot.querySelectorAll('input[name="' + escapeSelectorAttributeValueInsideDoubleQuotes('' + name) + '"][type="radio"]');
3980
3981 for (var i = 0; i < group.length; i++) {
3982 var otherNode = group[i];
3983
3984 if (otherNode === rootNode || otherNode.form !== rootNode.form) {
3985 continue;
3986 } // This will throw if radio buttons rendered by different copies of React
3987 // and the same name are rendered into the same form (same as #1939).
3988 // That's probably okay; we don't support it just as we don't support
3989 // mixing React radio buttons with non-React ones.
3990
3991
3992 var otherProps = getFiberCurrentPropsFromNode(otherNode);
3993
3994 if (!otherProps) {
3995 throw new Error('ReactDOMInput: Mixing React and non-React radio inputs with the ' + 'same `name` is not supported.');
3996 } // If this is a controlled radio button group, forcing the input that
3997 // was previously checked to update will cause it to be come re-checked
3998 // as appropriate.
3999
4000
4001 updateInput(otherNode, otherProps.value, otherProps.defaultValue, otherProps.defaultValue, otherProps.checked, otherProps.defaultChecked, otherProps.type, otherProps.name);
4002 } // If any updateInput() call set .checked to true, an input in this group
4003 // (often, `rootNode` itself) may have become unchecked
4004
4005
4006 for (var _i = 0; _i < group.length; _i++) {
4007 var _otherNode = group[_i];
4008
4009 if (_otherNode.form !== rootNode.form) {
4010 continue;
4011 }
4012
4013 updateValueIfChanged(_otherNode);
4014 }
4015 }
4016} // In Chrome, assigning defaultValue to certain input types triggers input validation.
4017// For number inputs, the display value loses trailing decimal points. For email inputs,
4018// Chrome raises "The specified value <x> is not a valid email address".
4019//
4020// Here we check to see if the defaultValue has actually changed, avoiding these problems
4021// when the user is inputting text
4022//
4023// https://github.com/facebook/react/issues/7253
4024
4025function setDefaultValue(node, type, value) {
4026 if ( // Focused number inputs synchronize on blur. See ChangeEventPlugin.js
4027 type !== 'number' || getActiveElement(node.ownerDocument) !== node) {
4028 if (node.defaultValue !== toString(value)) {
4029 node.defaultValue = toString(value);
4030 }
4031 }
4032}
4033
4034var didWarnSelectedSetOnOption = false;
4035var didWarnInvalidChild = false;
4036var didWarnInvalidInnerHTML = false;
4037/**
4038 * Implements an <option> host component that warns when `selected` is set.
4039 */
4040
4041function validateOptionProps(element, props) {
4042 {
4043 // If a value is not provided, then the children must be simple.
4044 if (props.value == null) {
4045 if (typeof props.children === 'object' && props.children !== null) {
4046 React.Children.forEach(props.children, function (child) {
4047 if (child == null) {
4048 return;
4049 }
4050
4051 if (typeof child === 'string' || typeof child === 'number' || typeof child === 'bigint') {
4052 return;
4053 }
4054
4055 if (!didWarnInvalidChild) {
4056 didWarnInvalidChild = true;
4057
4058 error('Cannot infer the option value of complex children. ' + 'Pass a `value` prop or use a plain string as children to <option>.');
4059 }
4060 });
4061 } else if (props.dangerouslySetInnerHTML != null) {
4062 if (!didWarnInvalidInnerHTML) {
4063 didWarnInvalidInnerHTML = true;
4064
4065 error('Pass a `value` prop if you set dangerouslyInnerHTML so React knows ' + 'which value should be selected.');
4066 }
4067 }
4068 } // TODO: Remove support for `selected` in <option>.
4069
4070
4071 if (props.selected != null && !didWarnSelectedSetOnOption) {
4072 error('Use the `defaultValue` or `value` props on <select> instead of ' + 'setting `selected` on <option>.');
4073
4074 didWarnSelectedSetOnOption = true;
4075 }
4076 }
4077}
4078
4079var didWarnValueDefaultValue;
4080
4081{
4082 didWarnValueDefaultValue = false;
4083}
4084
4085function getDeclarationErrorAddendum() {
4086 var ownerName = getCurrentFiberOwnerNameInDevOrNull();
4087
4088 if (ownerName) {
4089 return '\n\nCheck the render method of `' + ownerName + '`.';
4090 }
4091
4092 return '';
4093}
4094
4095var valuePropNames = ['value', 'defaultValue'];
4096/**
4097 * Validation function for `value` and `defaultValue`.
4098 */
4099
4100function checkSelectPropTypes(props) {
4101 {
4102 for (var i = 0; i < valuePropNames.length; i++) {
4103 var propName = valuePropNames[i];
4104
4105 if (props[propName] == null) {
4106 continue;
4107 }
4108
4109 var propNameIsArray = isArray(props[propName]);
4110
4111 if (props.multiple && !propNameIsArray) {
4112 error('The `%s` prop supplied to <select> must be an array if ' + '`multiple` is true.%s', propName, getDeclarationErrorAddendum());
4113 } else if (!props.multiple && propNameIsArray) {
4114 error('The `%s` prop supplied to <select> must be a scalar ' + 'value if `multiple` is false.%s', propName, getDeclarationErrorAddendum());
4115 }
4116 }
4117 }
4118}
4119
4120function updateOptions(node, multiple, propValue, setDefaultSelected) {
4121 var options = node.options;
4122
4123 if (multiple) {
4124 var selectedValues = propValue;
4125 var selectedValue = {};
4126
4127 for (var i = 0; i < selectedValues.length; i++) {
4128 // Prefix to avoid chaos with special keys.
4129 selectedValue['$' + selectedValues[i]] = true;
4130 }
4131
4132 for (var _i = 0; _i < options.length; _i++) {
4133 var selected = selectedValue.hasOwnProperty('$' + options[_i].value);
4134
4135 if (options[_i].selected !== selected) {
4136 options[_i].selected = selected;
4137 }
4138
4139 if (selected && setDefaultSelected) {
4140 options[_i].defaultSelected = true;
4141 }
4142 }
4143 } else {
4144 // Do not set `select.value` as exact behavior isn't consistent across all
4145 // browsers for all cases.
4146 var _selectedValue = toString(getToStringValue(propValue));
4147
4148 var defaultSelected = null;
4149
4150 for (var _i2 = 0; _i2 < options.length; _i2++) {
4151 if (options[_i2].value === _selectedValue) {
4152 options[_i2].selected = true;
4153
4154 if (setDefaultSelected) {
4155 options[_i2].defaultSelected = true;
4156 }
4157
4158 return;
4159 }
4160
4161 if (defaultSelected === null && !options[_i2].disabled) {
4162 defaultSelected = options[_i2];
4163 }
4164 }
4165
4166 if (defaultSelected !== null) {
4167 defaultSelected.selected = true;
4168 }
4169 }
4170}
4171/**
4172 * Implements a <select> host component that allows optionally setting the
4173 * props `value` and `defaultValue`. If `multiple` is false, the prop must be a
4174 * stringable. If `multiple` is true, the prop must be an array of stringables.
4175 *
4176 * If `value` is not supplied (or null/undefined), user actions that change the
4177 * selected option will trigger updates to the rendered options.
4178 *
4179 * If it is supplied (and not null/undefined), the rendered options will not
4180 * update in response to user actions. Instead, the `value` prop must change in
4181 * order for the rendered options to update.
4182 *
4183 * If `defaultValue` is provided, any options with the supplied values will be
4184 * selected.
4185 */
4186
4187
4188function validateSelectProps(element, props) {
4189 {
4190 checkSelectPropTypes(props);
4191
4192 if (props.value !== undefined && props.defaultValue !== undefined && !didWarnValueDefaultValue) {
4193 error('Select elements must be either controlled or uncontrolled ' + '(specify either the value prop, or the defaultValue prop, but not ' + 'both). Decide between using a controlled or uncontrolled select ' + 'element and remove one of these props. More info: ' + 'https://react.dev/link/controlled-components');
4194
4195 didWarnValueDefaultValue = true;
4196 }
4197 }
4198}
4199function initSelect(element, value, defaultValue, multiple) {
4200 var node = element;
4201 node.multiple = !!multiple;
4202
4203 if (value != null) {
4204 updateOptions(node, !!multiple, value, false);
4205 } else if (defaultValue != null) {
4206 updateOptions(node, !!multiple, defaultValue, true);
4207 }
4208}
4209function updateSelect(element, value, defaultValue, multiple, wasMultiple) {
4210 var node = element;
4211
4212 if (value != null) {
4213 updateOptions(node, !!multiple, value, false);
4214 } else if (!!wasMultiple !== !!multiple) {
4215 // For simplicity, reapply `defaultValue` if `multiple` is toggled.
4216 if (defaultValue != null) {
4217 updateOptions(node, !!multiple, defaultValue, true);
4218 } else {
4219 // Revert the select back to its default unselected state.
4220 updateOptions(node, !!multiple, multiple ? [] : '', false);
4221 }
4222 }
4223}
4224function restoreControlledSelectState(element, props) {
4225 var node = element;
4226 var value = props.value;
4227
4228 if (value != null) {
4229 updateOptions(node, !!props.multiple, value, false);
4230 }
4231}
4232
4233var didWarnValDefaultVal = false;
4234/**
4235 * Implements a <textarea> host component that allows setting `value`, and
4236 * `defaultValue`. This differs from the traditional DOM API because value is
4237 * usually set as PCDATA children.
4238 *
4239 * If `value` is not supplied (or null/undefined), user actions that affect the
4240 * value will trigger updates to the element.
4241 *
4242 * If `value` is supplied (and not null/undefined), the rendered element will
4243 * not trigger updates to the element. Instead, the `value` prop must change in
4244 * order for the rendered element to be updated.
4245 *
4246 * The rendered element will be initialized with an empty value, the prop
4247 * `defaultValue` if specified, or the children content (deprecated).
4248 */
4249
4250function validateTextareaProps(element, props) {
4251 {
4252 if (props.value !== undefined && props.defaultValue !== undefined && !didWarnValDefaultVal) {
4253 error('%s contains a textarea with both value and defaultValue props. ' + 'Textarea elements must be either controlled or uncontrolled ' + '(specify either the value prop, or the defaultValue prop, but not ' + 'both). Decide between using a controlled or uncontrolled textarea ' + 'and remove one of these props. More info: ' + 'https://react.dev/link/controlled-components', getCurrentFiberOwnerNameInDevOrNull() || 'A component');
4254
4255 didWarnValDefaultVal = true;
4256 }
4257
4258 if (props.children != null && props.value == null) {
4259 error('Use the `defaultValue` or `value` props instead of setting ' + 'children on <textarea>.');
4260 }
4261 }
4262}
4263function updateTextarea(element, value, defaultValue) {
4264 var node = element;
4265
4266 if (value != null) {
4267 // Cast `value` to a string to ensure the value is set correctly. While
4268 // browsers typically do this as necessary, jsdom doesn't.
4269 var newValue = toString(getToStringValue(value)); // To avoid side effects (such as losing text selection), only set value if changed
4270
4271 if (newValue !== node.value) {
4272 node.value = newValue;
4273 } // TOOO: This should respect disableInputAttributeSyncing flag.
4274
4275
4276 if (defaultValue == null) {
4277 if (node.defaultValue !== newValue) {
4278 node.defaultValue = newValue;
4279 }
4280
4281 return;
4282 }
4283 }
4284
4285 if (defaultValue != null) {
4286 node.defaultValue = toString(getToStringValue(defaultValue));
4287 } else {
4288 node.defaultValue = '';
4289 }
4290}
4291function initTextarea(element, value, defaultValue, children) {
4292 var node = element;
4293 var initialValue = value; // Only bother fetching default value if we're going to use it
4294
4295 if (initialValue == null) {
4296 if (children != null) {
4297 {
4298 if (defaultValue != null) {
4299 throw new Error('If you supply `defaultValue` on a <textarea>, do not pass children.');
4300 }
4301
4302 if (isArray(children)) {
4303 if (children.length > 1) {
4304 throw new Error('<textarea> can only have at most one child.');
4305 }
4306
4307 children = children[0];
4308 }
4309
4310 defaultValue = children;
4311 }
4312 }
4313
4314 if (defaultValue == null) {
4315 defaultValue = '';
4316 }
4317
4318 initialValue = defaultValue;
4319 }
4320
4321 var stringValue = getToStringValue(initialValue);
4322 node.defaultValue = stringValue; // This will be toString:ed.
4323 // This is in postMount because we need access to the DOM node, which is not
4324 // available until after the component has mounted.
4325
4326 var textContent = node.textContent; // Only set node.value if textContent is equal to the expected
4327 // initial value. In IE10/IE11 there is a bug where the placeholder attribute
4328 // will populate textContent as well.
4329 // https://developer.microsoft.com/microsoft-edge/platform/issues/101525/
4330
4331 if (textContent === stringValue) {
4332 if (textContent !== '' && textContent !== null) {
4333 node.value = textContent;
4334 }
4335 }
4336}
4337function restoreControlledTextareaState(element, props) {
4338 // DOM component is still mounted; update
4339 updateTextarea(element, props.value, props.defaultValue);
4340}
4341
4342// This validation code was written based on the HTML5 parsing spec:
4343// https://html.spec.whatwg.org/multipage/syntax.html#has-an-element-in-scope
4344//
4345// Note: this does not catch all invalid nesting, nor does it try to (as it's
4346// not clear what practical benefit doing so provides); instead, we warn only
4347// for cases where the parser will give a parse tree differing from what React
4348// intended. For example, <b><div></div></b> is invalid but we don't warn
4349// because it still parses correctly; we do warn for other cases like nested
4350// <p> tags where the beginning of the second element implicitly closes the
4351// first, causing a confusing mess.
4352// https://html.spec.whatwg.org/multipage/syntax.html#special
4353var specialTags = ['address', 'applet', 'area', 'article', 'aside', 'base', 'basefont', 'bgsound', 'blockquote', 'body', 'br', 'button', 'caption', 'center', 'col', 'colgroup', 'dd', 'details', 'dir', 'div', 'dl', 'dt', 'embed', 'fieldset', 'figcaption', 'figure', 'footer', 'form', 'frame', 'frameset', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'head', 'header', 'hgroup', 'hr', 'html', 'iframe', 'img', 'input', 'isindex', 'li', 'link', 'listing', 'main', 'marquee', 'menu', 'menuitem', 'meta', 'nav', 'noembed', 'noframes', 'noscript', 'object', 'ol', 'p', 'param', 'plaintext', 'pre', 'script', 'section', 'select', 'source', 'style', 'summary', 'table', 'tbody', 'td', 'template', 'textarea', 'tfoot', 'th', 'thead', 'title', 'tr', 'track', 'ul', 'wbr', 'xmp']; // https://html.spec.whatwg.org/multipage/syntax.html#has-an-element-in-scope
4354
4355var inScopeTags = ['applet', 'caption', 'html', 'table', 'td', 'th', 'marquee', 'object', 'template', // https://html.spec.whatwg.org/multipage/syntax.html#html-integration-point
4356// TODO: Distinguish by namespace here -- for <title>, including it here
4357// errs on the side of fewer warnings
4358'foreignObject', 'desc', 'title']; // https://html.spec.whatwg.org/multipage/syntax.html#has-an-element-in-button-scope
4359
4360var buttonScopeTags = inScopeTags.concat(['button']) ; // https://html.spec.whatwg.org/multipage/syntax.html#generate-implied-end-tags
4361
4362var impliedEndTags = ['dd', 'dt', 'li', 'option', 'optgroup', 'p', 'rp', 'rt'];
4363var emptyAncestorInfoDev = {
4364 current: null,
4365 formTag: null,
4366 aTagInScope: null,
4367 buttonTagInScope: null,
4368 nobrTagInScope: null,
4369 pTagInButtonScope: null,
4370 listItemTagAutoclosing: null,
4371 dlItemTagAutoclosing: null,
4372 containerTagInScope: null
4373};
4374
4375function updatedAncestorInfoDev(oldInfo, tag) {
4376 {
4377 var ancestorInfo = assign({}, oldInfo || emptyAncestorInfoDev);
4378
4379 var info = {
4380 tag: tag
4381 };
4382
4383 if (inScopeTags.indexOf(tag) !== -1) {
4384 ancestorInfo.aTagInScope = null;
4385 ancestorInfo.buttonTagInScope = null;
4386 ancestorInfo.nobrTagInScope = null;
4387 }
4388
4389 if (buttonScopeTags.indexOf(tag) !== -1) {
4390 ancestorInfo.pTagInButtonScope = null;
4391 } // See rules for 'li', 'dd', 'dt' start tags in
4392 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inbody
4393
4394
4395 if (specialTags.indexOf(tag) !== -1 && tag !== 'address' && tag !== 'div' && tag !== 'p') {
4396 ancestorInfo.listItemTagAutoclosing = null;
4397 ancestorInfo.dlItemTagAutoclosing = null;
4398 }
4399
4400 ancestorInfo.current = info;
4401
4402 if (tag === 'form') {
4403 ancestorInfo.formTag = info;
4404 }
4405
4406 if (tag === 'a') {
4407 ancestorInfo.aTagInScope = info;
4408 }
4409
4410 if (tag === 'button') {
4411 ancestorInfo.buttonTagInScope = info;
4412 }
4413
4414 if (tag === 'nobr') {
4415 ancestorInfo.nobrTagInScope = info;
4416 }
4417
4418 if (tag === 'p') {
4419 ancestorInfo.pTagInButtonScope = info;
4420 }
4421
4422 if (tag === 'li') {
4423 ancestorInfo.listItemTagAutoclosing = info;
4424 }
4425
4426 if (tag === 'dd' || tag === 'dt') {
4427 ancestorInfo.dlItemTagAutoclosing = info;
4428 }
4429
4430 if (tag === '#document' || tag === 'html') {
4431 ancestorInfo.containerTagInScope = null;
4432 } else if (!ancestorInfo.containerTagInScope) {
4433 ancestorInfo.containerTagInScope = info;
4434 }
4435
4436 return ancestorInfo;
4437 }
4438}
4439/**
4440 * Returns whether
4441 */
4442
4443
4444function isTagValidWithParent(tag, parentTag) {
4445 // First, let's check if we're in an unusual parsing mode...
4446 switch (parentTag) {
4447 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inselect
4448 case 'select':
4449 return tag === 'hr' || tag === 'option' || tag === 'optgroup' || tag === '#text';
4450
4451 case 'optgroup':
4452 return tag === 'option' || tag === '#text';
4453 // Strictly speaking, seeing an <option> doesn't mean we're in a <select>
4454 // but
4455
4456 case 'option':
4457 return tag === '#text';
4458 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intd
4459 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-incaption
4460 // No special behavior since these rules fall back to "in body" mode for
4461 // all except special table nodes which cause bad parsing behavior anyway.
4462 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intr
4463
4464 case 'tr':
4465 return tag === 'th' || tag === 'td' || tag === 'style' || tag === 'script' || tag === 'template';
4466 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intbody
4467
4468 case 'tbody':
4469 case 'thead':
4470 case 'tfoot':
4471 return tag === 'tr' || tag === 'style' || tag === 'script' || tag === 'template';
4472 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-incolgroup
4473
4474 case 'colgroup':
4475 return tag === 'col' || tag === 'template';
4476 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intable
4477
4478 case 'table':
4479 return tag === 'caption' || tag === 'colgroup' || tag === 'tbody' || tag === 'tfoot' || tag === 'thead' || tag === 'style' || tag === 'script' || tag === 'template';
4480 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inhead
4481
4482 case 'head':
4483 return tag === 'base' || tag === 'basefont' || tag === 'bgsound' || tag === 'link' || tag === 'meta' || tag === 'title' || tag === 'noscript' || tag === 'noframes' || tag === 'style' || tag === 'script' || tag === 'template';
4484 // https://html.spec.whatwg.org/multipage/semantics.html#the-html-element
4485
4486 case 'html':
4487 return tag === 'head' || tag === 'body' || tag === 'frameset';
4488
4489 case 'frameset':
4490 return tag === 'frame';
4491
4492 case '#document':
4493 return tag === 'html';
4494 } // Probably in the "in body" parsing mode, so we outlaw only tag combos
4495 // where the parsing rules cause implicit opens or closes to be added.
4496 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inbody
4497
4498
4499 switch (tag) {
4500 case 'h1':
4501 case 'h2':
4502 case 'h3':
4503 case 'h4':
4504 case 'h5':
4505 case 'h6':
4506 return parentTag !== 'h1' && parentTag !== 'h2' && parentTag !== 'h3' && parentTag !== 'h4' && parentTag !== 'h5' && parentTag !== 'h6';
4507
4508 case 'rp':
4509 case 'rt':
4510 return impliedEndTags.indexOf(parentTag) === -1;
4511
4512 case 'body':
4513 case 'caption':
4514 case 'col':
4515 case 'colgroup':
4516 case 'frameset':
4517 case 'frame':
4518 case 'head':
4519 case 'html':
4520 case 'tbody':
4521 case 'td':
4522 case 'tfoot':
4523 case 'th':
4524 case 'thead':
4525 case 'tr':
4526 // These tags are only valid with a few parents that have special child
4527 // parsing rules -- if we're down here, then none of those matched and
4528 // so we allow it only if we don't know what the parent is, as all other
4529 // cases are invalid.
4530 return parentTag == null;
4531 }
4532
4533 return true;
4534}
4535/**
4536 * Returns whether
4537 */
4538
4539
4540function findInvalidAncestorForTag(tag, ancestorInfo) {
4541 switch (tag) {
4542 case 'address':
4543 case 'article':
4544 case 'aside':
4545 case 'blockquote':
4546 case 'center':
4547 case 'details':
4548 case 'dialog':
4549 case 'dir':
4550 case 'div':
4551 case 'dl':
4552 case 'fieldset':
4553 case 'figcaption':
4554 case 'figure':
4555 case 'footer':
4556 case 'header':
4557 case 'hgroup':
4558 case 'main':
4559 case 'menu':
4560 case 'nav':
4561 case 'ol':
4562 case 'p':
4563 case 'section':
4564 case 'summary':
4565 case 'ul':
4566 case 'pre':
4567 case 'listing':
4568 case 'table':
4569 case 'hr':
4570 case 'xmp':
4571 case 'h1':
4572 case 'h2':
4573 case 'h3':
4574 case 'h4':
4575 case 'h5':
4576 case 'h6':
4577 return ancestorInfo.pTagInButtonScope;
4578
4579 case 'form':
4580 return ancestorInfo.formTag || ancestorInfo.pTagInButtonScope;
4581
4582 case 'li':
4583 return ancestorInfo.listItemTagAutoclosing;
4584
4585 case 'dd':
4586 case 'dt':
4587 return ancestorInfo.dlItemTagAutoclosing;
4588
4589 case 'button':
4590 return ancestorInfo.buttonTagInScope;
4591
4592 case 'a':
4593 // Spec says something about storing a list of markers, but it sounds
4594 // equivalent to this check.
4595 return ancestorInfo.aTagInScope;
4596
4597 case 'nobr':
4598 return ancestorInfo.nobrTagInScope;
4599 }
4600
4601 return null;
4602}
4603
4604var didWarn = {};
4605
4606function validateDOMNesting(childTag, ancestorInfo) {
4607 {
4608 ancestorInfo = ancestorInfo || emptyAncestorInfoDev;
4609 var parentInfo = ancestorInfo.current;
4610 var parentTag = parentInfo && parentInfo.tag;
4611 var invalidParent = isTagValidWithParent(childTag, parentTag) ? null : parentInfo;
4612 var invalidAncestor = invalidParent ? null : findInvalidAncestorForTag(childTag, ancestorInfo);
4613 var invalidParentOrAncestor = invalidParent || invalidAncestor;
4614
4615 if (!invalidParentOrAncestor) {
4616 return true;
4617 }
4618
4619 var ancestorTag = invalidParentOrAncestor.tag;
4620 var warnKey = // eslint-disable-next-line react-internal/safe-string-coercion
4621 String(!!invalidParent) + '|' + childTag + '|' + ancestorTag;
4622
4623 if (didWarn[warnKey]) {
4624 return false;
4625 }
4626
4627 didWarn[warnKey] = true;
4628 var tagDisplayName = '<' + childTag + '>';
4629
4630 if (invalidParent) {
4631 var info = '';
4632
4633 if (ancestorTag === 'table' && childTag === 'tr') {
4634 info += ' Add a <tbody>, <thead> or <tfoot> to your code to match the DOM tree generated by ' + 'the browser.';
4635 }
4636
4637 error('In HTML, %s cannot be a child of <%s>.%s\n' + 'This will cause a hydration error.', tagDisplayName, ancestorTag, info);
4638 } else {
4639 error('In HTML, %s cannot be a descendant of <%s>.\n' + 'This will cause a hydration error.', tagDisplayName, ancestorTag);
4640 }
4641
4642 return false;
4643 }
4644}
4645
4646function validateTextNesting(childText, parentTag) {
4647 {
4648 if (isTagValidWithParent('#text', parentTag)) {
4649 return true;
4650 } // eslint-disable-next-line react-internal/safe-string-coercion
4651
4652
4653 var warnKey = '#text|' + parentTag;
4654
4655 if (didWarn[warnKey]) {
4656 return false;
4657 }
4658
4659 didWarn[warnKey] = true;
4660
4661 if (/\S/.test(childText)) {
4662 error('In HTML, text nodes cannot be a child of <%s>.\n' + 'This will cause a hydration error.', parentTag);
4663 } else {
4664 error('In HTML, whitespace text nodes cannot be a child of <%s>. ' + "Make sure you don't have any extra whitespace between tags on " + 'each line of your source code.\n' + 'This will cause a hydration error.', parentTag);
4665 }
4666
4667 return false;
4668 }
4669}
4670
4671var MATH_NAMESPACE = 'http://www.w3.org/1998/Math/MathML';
4672var SVG_NAMESPACE = 'http://www.w3.org/2000/svg';
4673
4674if (typeof MSApp !== 'undefined' && MSApp.execUnsafeLocalFunction) ;
4675
4676/**
4677 * Set the textContent property of a node. For text updates, it's faster
4678 * to set the `nodeValue` of the Text node directly instead of using
4679 * `.textContent` which will remove the existing node and create a new one.
4680 *
4681 * @param {DOMElement} node
4682 * @param {string} text
4683 * @internal
4684 */
4685
4686function setTextContent(node, text) {
4687 if (text) {
4688 var firstChild = node.firstChild;
4689
4690 if (firstChild && firstChild === node.lastChild && firstChild.nodeType === TEXT_NODE) {
4691 firstChild.nodeValue = text;
4692 return;
4693 }
4694 }
4695
4696 node.textContent = text;
4697}
4698
4699// List derived from Gecko source code:
4700// https://github.com/mozilla/gecko-dev/blob/4e638efc71/layout/style/test/property_database.js
4701var shorthandToLonghand = {
4702 animation: ['animationDelay', 'animationDirection', 'animationDuration', 'animationFillMode', 'animationIterationCount', 'animationName', 'animationPlayState', 'animationTimingFunction'],
4703 background: ['backgroundAttachment', 'backgroundClip', 'backgroundColor', 'backgroundImage', 'backgroundOrigin', 'backgroundPositionX', 'backgroundPositionY', 'backgroundRepeat', 'backgroundSize'],
4704 backgroundPosition: ['backgroundPositionX', 'backgroundPositionY'],
4705 border: ['borderBottomColor', 'borderBottomStyle', 'borderBottomWidth', 'borderImageOutset', 'borderImageRepeat', 'borderImageSlice', 'borderImageSource', 'borderImageWidth', 'borderLeftColor', 'borderLeftStyle', 'borderLeftWidth', 'borderRightColor', 'borderRightStyle', 'borderRightWidth', 'borderTopColor', 'borderTopStyle', 'borderTopWidth'],
4706 borderBlockEnd: ['borderBlockEndColor', 'borderBlockEndStyle', 'borderBlockEndWidth'],
4707 borderBlockStart: ['borderBlockStartColor', 'borderBlockStartStyle', 'borderBlockStartWidth'],
4708 borderBottom: ['borderBottomColor', 'borderBottomStyle', 'borderBottomWidth'],
4709 borderColor: ['borderBottomColor', 'borderLeftColor', 'borderRightColor', 'borderTopColor'],
4710 borderImage: ['borderImageOutset', 'borderImageRepeat', 'borderImageSlice', 'borderImageSource', 'borderImageWidth'],
4711 borderInlineEnd: ['borderInlineEndColor', 'borderInlineEndStyle', 'borderInlineEndWidth'],
4712 borderInlineStart: ['borderInlineStartColor', 'borderInlineStartStyle', 'borderInlineStartWidth'],
4713 borderLeft: ['borderLeftColor', 'borderLeftStyle', 'borderLeftWidth'],
4714 borderRadius: ['borderBottomLeftRadius', 'borderBottomRightRadius', 'borderTopLeftRadius', 'borderTopRightRadius'],
4715 borderRight: ['borderRightColor', 'borderRightStyle', 'borderRightWidth'],
4716 borderStyle: ['borderBottomStyle', 'borderLeftStyle', 'borderRightStyle', 'borderTopStyle'],
4717 borderTop: ['borderTopColor', 'borderTopStyle', 'borderTopWidth'],
4718 borderWidth: ['borderBottomWidth', 'borderLeftWidth', 'borderRightWidth', 'borderTopWidth'],
4719 columnRule: ['columnRuleColor', 'columnRuleStyle', 'columnRuleWidth'],
4720 columns: ['columnCount', 'columnWidth'],
4721 flex: ['flexBasis', 'flexGrow', 'flexShrink'],
4722 flexFlow: ['flexDirection', 'flexWrap'],
4723 font: ['fontFamily', 'fontFeatureSettings', 'fontKerning', 'fontLanguageOverride', 'fontSize', 'fontSizeAdjust', 'fontStretch', 'fontStyle', 'fontVariant', 'fontVariantAlternates', 'fontVariantCaps', 'fontVariantEastAsian', 'fontVariantLigatures', 'fontVariantNumeric', 'fontVariantPosition', 'fontWeight', 'lineHeight'],
4724 fontVariant: ['fontVariantAlternates', 'fontVariantCaps', 'fontVariantEastAsian', 'fontVariantLigatures', 'fontVariantNumeric', 'fontVariantPosition'],
4725 gap: ['columnGap', 'rowGap'],
4726 grid: ['gridAutoColumns', 'gridAutoFlow', 'gridAutoRows', 'gridTemplateAreas', 'gridTemplateColumns', 'gridTemplateRows'],
4727 gridArea: ['gridColumnEnd', 'gridColumnStart', 'gridRowEnd', 'gridRowStart'],
4728 gridColumn: ['gridColumnEnd', 'gridColumnStart'],
4729 gridColumnGap: ['columnGap'],
4730 gridGap: ['columnGap', 'rowGap'],
4731 gridRow: ['gridRowEnd', 'gridRowStart'],
4732 gridRowGap: ['rowGap'],
4733 gridTemplate: ['gridTemplateAreas', 'gridTemplateColumns', 'gridTemplateRows'],
4734 listStyle: ['listStyleImage', 'listStylePosition', 'listStyleType'],
4735 margin: ['marginBottom', 'marginLeft', 'marginRight', 'marginTop'],
4736 marker: ['markerEnd', 'markerMid', 'markerStart'],
4737 mask: ['maskClip', 'maskComposite', 'maskImage', 'maskMode', 'maskOrigin', 'maskPositionX', 'maskPositionY', 'maskRepeat', 'maskSize'],
4738 maskPosition: ['maskPositionX', 'maskPositionY'],
4739 outline: ['outlineColor', 'outlineStyle', 'outlineWidth'],
4740 overflow: ['overflowX', 'overflowY'],
4741 padding: ['paddingBottom', 'paddingLeft', 'paddingRight', 'paddingTop'],
4742 placeContent: ['alignContent', 'justifyContent'],
4743 placeItems: ['alignItems', 'justifyItems'],
4744 placeSelf: ['alignSelf', 'justifySelf'],
4745 textDecoration: ['textDecorationColor', 'textDecorationLine', 'textDecorationStyle'],
4746 textEmphasis: ['textEmphasisColor', 'textEmphasisStyle'],
4747 transition: ['transitionDelay', 'transitionDuration', 'transitionProperty', 'transitionTimingFunction'],
4748 wordWrap: ['overflowWrap']
4749};
4750
4751var uppercasePattern = /([A-Z])/g;
4752var msPattern$1 = /^ms-/;
4753/**
4754 * Hyphenates a camelcased CSS property name, for example:
4755 *
4756 * > hyphenateStyleName('backgroundColor')
4757 * < "background-color"
4758 * > hyphenateStyleName('MozTransition')
4759 * < "-moz-transition"
4760 * > hyphenateStyleName('msTransition')
4761 * < "-ms-transition"
4762 *
4763 * As Modernizr suggests (http://modernizr.com/docs/#prefixed), an `ms` prefix
4764 * is converted to `-ms-`.
4765 */
4766
4767function hyphenateStyleName(name) {
4768 return name.replace(uppercasePattern, '-$1').toLowerCase().replace(msPattern$1, '-ms-');
4769}
4770
4771// 'msTransform' is correct, but the other prefixes should be capitalized
4772var badVendoredStyleNamePattern = /^(?:webkit|moz|o)[A-Z]/;
4773var msPattern = /^-ms-/;
4774var hyphenPattern = /-(.)/g; // style values shouldn't contain a semicolon
4775
4776var badStyleValueWithSemicolonPattern = /;\s*$/;
4777var warnedStyleNames = {};
4778var warnedStyleValues = {};
4779var warnedForNaNValue = false;
4780var warnedForInfinityValue = false;
4781
4782function camelize(string) {
4783 return string.replace(hyphenPattern, function (_, character) {
4784 return character.toUpperCase();
4785 });
4786}
4787
4788function warnHyphenatedStyleName(name) {
4789 {
4790 if (warnedStyleNames.hasOwnProperty(name) && warnedStyleNames[name]) {
4791 return;
4792 }
4793
4794 warnedStyleNames[name] = true;
4795
4796 error('Unsupported style property %s. Did you mean %s?', name, // As Andi Smith suggests
4797 // (http://www.andismith.com/blog/2012/02/modernizr-prefixed/), an `-ms` prefix
4798 // is converted to lowercase `ms`.
4799 camelize(name.replace(msPattern, 'ms-')));
4800 }
4801}
4802
4803function warnBadVendoredStyleName(name) {
4804 {
4805 if (warnedStyleNames.hasOwnProperty(name) && warnedStyleNames[name]) {
4806 return;
4807 }
4808
4809 warnedStyleNames[name] = true;
4810
4811 error('Unsupported vendor-prefixed style property %s. Did you mean %s?', name, name.charAt(0).toUpperCase() + name.slice(1));
4812 }
4813}
4814
4815function warnStyleValueWithSemicolon(name, value) {
4816 {
4817 if (warnedStyleValues.hasOwnProperty(value) && warnedStyleValues[value]) {
4818 return;
4819 }
4820
4821 warnedStyleValues[value] = true;
4822
4823 error("Style property values shouldn't contain a semicolon. " + 'Try "%s: %s" instead.', name, value.replace(badStyleValueWithSemicolonPattern, ''));
4824 }
4825}
4826
4827function warnStyleValueIsNaN(name, value) {
4828 {
4829 if (warnedForNaNValue) {
4830 return;
4831 }
4832
4833 warnedForNaNValue = true;
4834
4835 error('`NaN` is an invalid value for the `%s` css style property.', name);
4836 }
4837}
4838
4839function warnStyleValueIsInfinity(name, value) {
4840 {
4841 if (warnedForInfinityValue) {
4842 return;
4843 }
4844
4845 warnedForInfinityValue = true;
4846
4847 error('`Infinity` is an invalid value for the `%s` css style property.', name);
4848 }
4849}
4850
4851function warnValidStyle(name, value) {
4852 {
4853 if (name.indexOf('-') > -1) {
4854 warnHyphenatedStyleName(name);
4855 } else if (badVendoredStyleNamePattern.test(name)) {
4856 warnBadVendoredStyleName(name);
4857 } else if (badStyleValueWithSemicolonPattern.test(value)) {
4858 warnStyleValueWithSemicolon(name, value);
4859 }
4860
4861 if (typeof value === 'number') {
4862 if (isNaN(value)) {
4863 warnStyleValueIsNaN(name);
4864 } else if (!isFinite(value)) {
4865 warnStyleValueIsInfinity(name);
4866 }
4867 }
4868 }
4869}
4870
4871/**
4872 * CSS properties which accept numbers but are not in units of "px".
4873 */
4874var unitlessNumbers = new Set(['animationIterationCount', 'aspectRatio', 'borderImageOutset', 'borderImageSlice', 'borderImageWidth', 'boxFlex', 'boxFlexGroup', 'boxOrdinalGroup', 'columnCount', 'columns', 'flex', 'flexGrow', 'flexPositive', 'flexShrink', 'flexNegative', 'flexOrder', 'gridArea', 'gridRow', 'gridRowEnd', 'gridRowSpan', 'gridRowStart', 'gridColumn', 'gridColumnEnd', 'gridColumnSpan', 'gridColumnStart', 'fontWeight', 'lineClamp', 'lineHeight', 'opacity', 'order', 'orphans', 'scale', 'tabSize', 'widows', 'zIndex', 'zoom', 'fillOpacity', // SVG-related properties
4875'floodOpacity', 'stopOpacity', 'strokeDasharray', 'strokeDashoffset', 'strokeMiterlimit', 'strokeOpacity', 'strokeWidth', 'MozAnimationIterationCount', // Known Prefixed Properties
4876'MozBoxFlex', // TODO: Remove these since they shouldn't be used in modern code
4877'MozBoxFlexGroup', 'MozLineClamp', 'msAnimationIterationCount', 'msFlex', 'msZoom', 'msFlexGrow', 'msFlexNegative', 'msFlexOrder', 'msFlexPositive', 'msFlexShrink', 'msGridColumn', 'msGridColumnSpan', 'msGridRow', 'msGridRowSpan', 'WebkitAnimationIterationCount', 'WebkitBoxFlex', 'WebKitBoxFlexGroup', 'WebkitBoxOrdinalGroup', 'WebkitColumnCount', 'WebkitColumns', 'WebkitFlex', 'WebkitFlexGrow', 'WebkitFlexPositive', 'WebkitFlexShrink', 'WebkitLineClamp']);
4878function isUnitlessNumber (name) {
4879 return unitlessNumbers.has(name);
4880}
4881
4882/**
4883 * Operations for dealing with CSS properties.
4884 */
4885
4886/**
4887 * This creates a string that is expected to be equivalent to the style
4888 * attribute generated by server-side rendering. It by-passes warnings and
4889 * security checks so it's not safe to use this value for anything other than
4890 * comparison. It is only used in DEV for SSR validation.
4891 */
4892
4893function createDangerousStringForStyles(styles) {
4894 {
4895 var serialized = '';
4896 var delimiter = '';
4897
4898 for (var styleName in styles) {
4899 if (!styles.hasOwnProperty(styleName)) {
4900 continue;
4901 }
4902
4903 var value = styles[styleName];
4904
4905 if (value != null && typeof value !== 'boolean' && value !== '') {
4906 var isCustomProperty = styleName.indexOf('--') === 0;
4907
4908 if (isCustomProperty) {
4909 {
4910 checkCSSPropertyStringCoercion(value, styleName);
4911 }
4912
4913 serialized += delimiter + styleName + ':' + ('' + value).trim();
4914 } else {
4915 if (typeof value === 'number' && value !== 0 && !isUnitlessNumber(styleName)) {
4916 serialized += delimiter + hyphenateStyleName(styleName) + ':' + value + 'px';
4917 } else {
4918 {
4919 checkCSSPropertyStringCoercion(value, styleName);
4920 }
4921
4922 serialized += delimiter + hyphenateStyleName(styleName) + ':' + ('' + value).trim();
4923 }
4924 }
4925
4926 delimiter = ';';
4927 }
4928 }
4929
4930 return serialized || null;
4931 }
4932}
4933
4934function setValueForStyle(style, styleName, value) {
4935 var isCustomProperty = styleName.indexOf('--') === 0;
4936
4937 {
4938 if (!isCustomProperty) {
4939 warnValidStyle(styleName, value);
4940 }
4941 }
4942
4943 if (value == null || typeof value === 'boolean' || value === '') {
4944 if (isCustomProperty) {
4945 style.setProperty(styleName, '');
4946 } else if (styleName === 'float') {
4947 style.cssFloat = '';
4948 } else {
4949 style[styleName] = '';
4950 }
4951 } else if (isCustomProperty) {
4952 style.setProperty(styleName, value);
4953 } else if (typeof value === 'number' && value !== 0 && !isUnitlessNumber(styleName)) {
4954 style[styleName] = value + 'px'; // Presumes implicit 'px' suffix for unitless numbers
4955 } else {
4956 if (styleName === 'float') {
4957 style.cssFloat = value;
4958 } else {
4959 {
4960 checkCSSPropertyStringCoercion(value, styleName);
4961 }
4962
4963 style[styleName] = ('' + value).trim();
4964 }
4965 }
4966}
4967/**
4968 * Sets the value for multiple styles on a node. If a value is specified as
4969 * '' (empty string), the corresponding style property will be unset.
4970 *
4971 * @param {DOMElement} node
4972 * @param {object} styles
4973 */
4974
4975
4976function setValueForStyles(node, styles, prevStyles) {
4977 if (styles != null && typeof styles !== 'object') {
4978 throw new Error('The `style` prop expects a mapping from style properties to values, ' + "not a string. For example, style={{marginRight: spacing + 'em'}} when " + 'using JSX.');
4979 }
4980
4981 {
4982 if (styles) {
4983 // Freeze the next style object so that we can assume it won't be
4984 // mutated. We have already warned for this in the past.
4985 Object.freeze(styles);
4986 }
4987 }
4988
4989 var style = node.style;
4990
4991 if (prevStyles != null) {
4992 {
4993 validateShorthandPropertyCollisionInDev(prevStyles, styles);
4994 }
4995
4996 for (var styleName in prevStyles) {
4997 if (prevStyles.hasOwnProperty(styleName) && (styles == null || !styles.hasOwnProperty(styleName))) {
4998 // Clear style
4999 var isCustomProperty = styleName.indexOf('--') === 0;
5000
5001 if (isCustomProperty) {
5002 style.setProperty(styleName, '');
5003 } else if (styleName === 'float') {
5004 style.cssFloat = '';
5005 } else {
5006 style[styleName] = '';
5007 }
5008 }
5009 }
5010
5011 for (var _styleName in styles) {
5012 var value = styles[_styleName];
5013
5014 if (styles.hasOwnProperty(_styleName) && prevStyles[_styleName] !== value) {
5015 setValueForStyle(style, _styleName, value);
5016 }
5017 }
5018 } else {
5019 for (var _styleName2 in styles) {
5020 if (styles.hasOwnProperty(_styleName2)) {
5021 var _value = styles[_styleName2];
5022 setValueForStyle(style, _styleName2, _value);
5023 }
5024 }
5025 }
5026}
5027
5028function isValueEmpty(value) {
5029 return value == null || typeof value === 'boolean' || value === '';
5030}
5031/**
5032 * Given {color: 'red', overflow: 'hidden'} returns {
5033 * color: 'color',
5034 * overflowX: 'overflow',
5035 * overflowY: 'overflow',
5036 * }. This can be read as "the overflowY property was set by the overflow
5037 * shorthand". That is, the values are the property that each was derived from.
5038 */
5039
5040
5041function expandShorthandMap(styles) {
5042 var expanded = {};
5043
5044 for (var key in styles) {
5045 var longhands = shorthandToLonghand[key] || [key];
5046
5047 for (var i = 0; i < longhands.length; i++) {
5048 expanded[longhands[i]] = key;
5049 }
5050 }
5051
5052 return expanded;
5053}
5054/**
5055 * When mixing shorthand and longhand property names, we warn during updates if
5056 * we expect an incorrect result to occur. In particular, we warn for:
5057 *
5058 * Updating a shorthand property (longhand gets overwritten):
5059 * {font: 'foo', fontVariant: 'bar'} -> {font: 'baz', fontVariant: 'bar'}
5060 * becomes .style.font = 'baz'
5061 * Removing a shorthand property (longhand gets lost too):
5062 * {font: 'foo', fontVariant: 'bar'} -> {fontVariant: 'bar'}
5063 * becomes .style.font = ''
5064 * Removing a longhand property (should revert to shorthand; doesn't):
5065 * {font: 'foo', fontVariant: 'bar'} -> {font: 'foo'}
5066 * becomes .style.fontVariant = ''
5067 */
5068
5069
5070function validateShorthandPropertyCollisionInDev(prevStyles, nextStyles) {
5071 {
5072 if (!nextStyles) {
5073 return;
5074 } // Compute the diff as it would happen elsewhere.
5075
5076
5077 var expandedUpdates = {};
5078
5079 if (prevStyles) {
5080 for (var key in prevStyles) {
5081 if (prevStyles.hasOwnProperty(key) && !nextStyles.hasOwnProperty(key)) {
5082 var longhands = shorthandToLonghand[key] || [key];
5083
5084 for (var i = 0; i < longhands.length; i++) {
5085 expandedUpdates[longhands[i]] = key;
5086 }
5087 }
5088 }
5089 }
5090
5091 for (var _key in nextStyles) {
5092 if (nextStyles.hasOwnProperty(_key) && (!prevStyles || prevStyles[_key] !== nextStyles[_key])) {
5093 var _longhands = shorthandToLonghand[_key] || [_key];
5094
5095 for (var _i = 0; _i < _longhands.length; _i++) {
5096 expandedUpdates[_longhands[_i]] = _key;
5097 }
5098 }
5099 }
5100
5101 var expandedStyles = expandShorthandMap(nextStyles);
5102 var warnedAbout = {};
5103
5104 for (var _key2 in expandedUpdates) {
5105 var originalKey = expandedUpdates[_key2];
5106 var correctOriginalKey = expandedStyles[_key2];
5107
5108 if (correctOriginalKey && originalKey !== correctOriginalKey) {
5109 var warningKey = originalKey + ',' + correctOriginalKey;
5110
5111 if (warnedAbout[warningKey]) {
5112 continue;
5113 }
5114
5115 warnedAbout[warningKey] = true;
5116
5117 error('%s a style property during rerender (%s) when a ' + 'conflicting property is set (%s) can lead to styling bugs. To ' + "avoid this, don't mix shorthand and non-shorthand properties " + 'for the same value; instead, replace the shorthand with ' + 'separate values.', isValueEmpty(nextStyles[originalKey]) ? 'Removing' : 'Updating', originalKey, correctOriginalKey);
5118 }
5119 }
5120 }
5121}
5122
5123function isCustomElement(tagName, props) {
5124 if (tagName.indexOf('-') === -1) {
5125 return false;
5126 }
5127
5128 switch (tagName) {
5129 // These are reserved SVG and MathML elements.
5130 // We don't mind this list too much because we expect it to never grow.
5131 // The alternative is to track the namespace in a few places which is convoluted.
5132 // https://html.spec.whatwg.org/multipage/custom-elements.html#custom-elements-core-concepts
5133 case 'annotation-xml':
5134 case 'color-profile':
5135 case 'font-face':
5136 case 'font-face-src':
5137 case 'font-face-uri':
5138 case 'font-face-format':
5139 case 'font-face-name':
5140 case 'missing-glyph':
5141 return false;
5142
5143 default:
5144 return true;
5145 }
5146}
5147
5148var aliases = new Map([['acceptCharset', 'accept-charset'], ['htmlFor', 'for'], ['httpEquiv', 'http-equiv'], // HTML and SVG attributes, but the SVG attribute is case sensitive.],
5149['crossOrigin', 'crossorigin'], // This is a list of all SVG attributes that need special casing.
5150// Regular attributes that just accept strings.],
5151['accentHeight', 'accent-height'], ['alignmentBaseline', 'alignment-baseline'], ['arabicForm', 'arabic-form'], ['baselineShift', 'baseline-shift'], ['capHeight', 'cap-height'], ['clipPath', 'clip-path'], ['clipRule', 'clip-rule'], ['colorInterpolation', 'color-interpolation'], ['colorInterpolationFilters', 'color-interpolation-filters'], ['colorProfile', 'color-profile'], ['colorRendering', 'color-rendering'], ['dominantBaseline', 'dominant-baseline'], ['enableBackground', 'enable-background'], ['fillOpacity', 'fill-opacity'], ['fillRule', 'fill-rule'], ['floodColor', 'flood-color'], ['floodOpacity', 'flood-opacity'], ['fontFamily', 'font-family'], ['fontSize', 'font-size'], ['fontSizeAdjust', 'font-size-adjust'], ['fontStretch', 'font-stretch'], ['fontStyle', 'font-style'], ['fontVariant', 'font-variant'], ['fontWeight', 'font-weight'], ['glyphName', 'glyph-name'], ['glyphOrientationHorizontal', 'glyph-orientation-horizontal'], ['glyphOrientationVertical', 'glyph-orientation-vertical'], ['horizAdvX', 'horiz-adv-x'], ['horizOriginX', 'horiz-origin-x'], ['imageRendering', 'image-rendering'], ['letterSpacing', 'letter-spacing'], ['lightingColor', 'lighting-color'], ['markerEnd', 'marker-end'], ['markerMid', 'marker-mid'], ['markerStart', 'marker-start'], ['overlinePosition', 'overline-position'], ['overlineThickness', 'overline-thickness'], ['paintOrder', 'paint-order'], ['panose-1', 'panose-1'], ['pointerEvents', 'pointer-events'], ['renderingIntent', 'rendering-intent'], ['shapeRendering', 'shape-rendering'], ['stopColor', 'stop-color'], ['stopOpacity', 'stop-opacity'], ['strikethroughPosition', 'strikethrough-position'], ['strikethroughThickness', 'strikethrough-thickness'], ['strokeDasharray', 'stroke-dasharray'], ['strokeDashoffset', 'stroke-dashoffset'], ['strokeLinecap', 'stroke-linecap'], ['strokeLinejoin', 'stroke-linejoin'], ['strokeMiterlimit', 'stroke-miterlimit'], ['strokeOpacity', 'stroke-opacity'], ['strokeWidth', 'stroke-width'], ['textAnchor', 'text-anchor'], ['textDecoration', 'text-decoration'], ['textRendering', 'text-rendering'], ['transformOrigin', 'transform-origin'], ['underlinePosition', 'underline-position'], ['underlineThickness', 'underline-thickness'], ['unicodeBidi', 'unicode-bidi'], ['unicodeRange', 'unicode-range'], ['unitsPerEm', 'units-per-em'], ['vAlphabetic', 'v-alphabetic'], ['vHanging', 'v-hanging'], ['vIdeographic', 'v-ideographic'], ['vMathematical', 'v-mathematical'], ['vectorEffect', 'vector-effect'], ['vertAdvY', 'vert-adv-y'], ['vertOriginX', 'vert-origin-x'], ['vertOriginY', 'vert-origin-y'], ['wordSpacing', 'word-spacing'], ['writingMode', 'writing-mode'], ['xmlnsXlink', 'xmlns:xlink'], ['xHeight', 'x-height']]);
5152function getAttributeAlias (name) {
5153 return aliases.get(name) || name;
5154}
5155
5156// When adding attributes to the HTML or SVG allowed attribute list, be sure to
5157// also add them to this module to ensure casing and incorrect name
5158// warnings.
5159var possibleStandardNames = {
5160 // HTML
5161 accept: 'accept',
5162 acceptcharset: 'acceptCharset',
5163 'accept-charset': 'acceptCharset',
5164 accesskey: 'accessKey',
5165 action: 'action',
5166 allowfullscreen: 'allowFullScreen',
5167 alt: 'alt',
5168 as: 'as',
5169 async: 'async',
5170 autocapitalize: 'autoCapitalize',
5171 autocomplete: 'autoComplete',
5172 autocorrect: 'autoCorrect',
5173 autofocus: 'autoFocus',
5174 autoplay: 'autoPlay',
5175 autosave: 'autoSave',
5176 capture: 'capture',
5177 cellpadding: 'cellPadding',
5178 cellspacing: 'cellSpacing',
5179 challenge: 'challenge',
5180 charset: 'charSet',
5181 checked: 'checked',
5182 children: 'children',
5183 cite: 'cite',
5184 class: 'className',
5185 classid: 'classID',
5186 classname: 'className',
5187 cols: 'cols',
5188 colspan: 'colSpan',
5189 content: 'content',
5190 contenteditable: 'contentEditable',
5191 contextmenu: 'contextMenu',
5192 controls: 'controls',
5193 controlslist: 'controlsList',
5194 coords: 'coords',
5195 crossorigin: 'crossOrigin',
5196 dangerouslysetinnerhtml: 'dangerouslySetInnerHTML',
5197 data: 'data',
5198 datetime: 'dateTime',
5199 default: 'default',
5200 defaultchecked: 'defaultChecked',
5201 defaultvalue: 'defaultValue',
5202 defer: 'defer',
5203 dir: 'dir',
5204 disabled: 'disabled',
5205 disablepictureinpicture: 'disablePictureInPicture',
5206 disableremoteplayback: 'disableRemotePlayback',
5207 download: 'download',
5208 draggable: 'draggable',
5209 enctype: 'encType',
5210 enterkeyhint: 'enterKeyHint',
5211 fetchpriority: 'fetchPriority',
5212 for: 'htmlFor',
5213 form: 'form',
5214 formmethod: 'formMethod',
5215 formaction: 'formAction',
5216 formenctype: 'formEncType',
5217 formnovalidate: 'formNoValidate',
5218 formtarget: 'formTarget',
5219 frameborder: 'frameBorder',
5220 headers: 'headers',
5221 height: 'height',
5222 hidden: 'hidden',
5223 high: 'high',
5224 href: 'href',
5225 hreflang: 'hrefLang',
5226 htmlfor: 'htmlFor',
5227 httpequiv: 'httpEquiv',
5228 'http-equiv': 'httpEquiv',
5229 icon: 'icon',
5230 id: 'id',
5231 imagesizes: 'imageSizes',
5232 imagesrcset: 'imageSrcSet',
5233 inert: 'inert',
5234 innerhtml: 'innerHTML',
5235 inputmode: 'inputMode',
5236 integrity: 'integrity',
5237 is: 'is',
5238 itemid: 'itemID',
5239 itemprop: 'itemProp',
5240 itemref: 'itemRef',
5241 itemscope: 'itemScope',
5242 itemtype: 'itemType',
5243 keyparams: 'keyParams',
5244 keytype: 'keyType',
5245 kind: 'kind',
5246 label: 'label',
5247 lang: 'lang',
5248 list: 'list',
5249 loop: 'loop',
5250 low: 'low',
5251 manifest: 'manifest',
5252 marginwidth: 'marginWidth',
5253 marginheight: 'marginHeight',
5254 max: 'max',
5255 maxlength: 'maxLength',
5256 media: 'media',
5257 mediagroup: 'mediaGroup',
5258 method: 'method',
5259 min: 'min',
5260 minlength: 'minLength',
5261 multiple: 'multiple',
5262 muted: 'muted',
5263 name: 'name',
5264 nomodule: 'noModule',
5265 nonce: 'nonce',
5266 novalidate: 'noValidate',
5267 open: 'open',
5268 optimum: 'optimum',
5269 pattern: 'pattern',
5270 placeholder: 'placeholder',
5271 playsinline: 'playsInline',
5272 poster: 'poster',
5273 preload: 'preload',
5274 profile: 'profile',
5275 radiogroup: 'radioGroup',
5276 readonly: 'readOnly',
5277 referrerpolicy: 'referrerPolicy',
5278 rel: 'rel',
5279 required: 'required',
5280 reversed: 'reversed',
5281 role: 'role',
5282 rows: 'rows',
5283 rowspan: 'rowSpan',
5284 sandbox: 'sandbox',
5285 scope: 'scope',
5286 scoped: 'scoped',
5287 scrolling: 'scrolling',
5288 seamless: 'seamless',
5289 selected: 'selected',
5290 shape: 'shape',
5291 size: 'size',
5292 sizes: 'sizes',
5293 span: 'span',
5294 spellcheck: 'spellCheck',
5295 src: 'src',
5296 srcdoc: 'srcDoc',
5297 srclang: 'srcLang',
5298 srcset: 'srcSet',
5299 start: 'start',
5300 step: 'step',
5301 style: 'style',
5302 summary: 'summary',
5303 tabindex: 'tabIndex',
5304 target: 'target',
5305 title: 'title',
5306 type: 'type',
5307 usemap: 'useMap',
5308 value: 'value',
5309 width: 'width',
5310 wmode: 'wmode',
5311 wrap: 'wrap',
5312 // SVG
5313 about: 'about',
5314 accentheight: 'accentHeight',
5315 'accent-height': 'accentHeight',
5316 accumulate: 'accumulate',
5317 additive: 'additive',
5318 alignmentbaseline: 'alignmentBaseline',
5319 'alignment-baseline': 'alignmentBaseline',
5320 allowreorder: 'allowReorder',
5321 alphabetic: 'alphabetic',
5322 amplitude: 'amplitude',
5323 arabicform: 'arabicForm',
5324 'arabic-form': 'arabicForm',
5325 ascent: 'ascent',
5326 attributename: 'attributeName',
5327 attributetype: 'attributeType',
5328 autoreverse: 'autoReverse',
5329 azimuth: 'azimuth',
5330 basefrequency: 'baseFrequency',
5331 baselineshift: 'baselineShift',
5332 'baseline-shift': 'baselineShift',
5333 baseprofile: 'baseProfile',
5334 bbox: 'bbox',
5335 begin: 'begin',
5336 bias: 'bias',
5337 by: 'by',
5338 calcmode: 'calcMode',
5339 capheight: 'capHeight',
5340 'cap-height': 'capHeight',
5341 clip: 'clip',
5342 clippath: 'clipPath',
5343 'clip-path': 'clipPath',
5344 clippathunits: 'clipPathUnits',
5345 cliprule: 'clipRule',
5346 'clip-rule': 'clipRule',
5347 color: 'color',
5348 colorinterpolation: 'colorInterpolation',
5349 'color-interpolation': 'colorInterpolation',
5350 colorinterpolationfilters: 'colorInterpolationFilters',
5351 'color-interpolation-filters': 'colorInterpolationFilters',
5352 colorprofile: 'colorProfile',
5353 'color-profile': 'colorProfile',
5354 colorrendering: 'colorRendering',
5355 'color-rendering': 'colorRendering',
5356 contentscripttype: 'contentScriptType',
5357 contentstyletype: 'contentStyleType',
5358 cursor: 'cursor',
5359 cx: 'cx',
5360 cy: 'cy',
5361 d: 'd',
5362 datatype: 'datatype',
5363 decelerate: 'decelerate',
5364 descent: 'descent',
5365 diffuseconstant: 'diffuseConstant',
5366 direction: 'direction',
5367 display: 'display',
5368 divisor: 'divisor',
5369 dominantbaseline: 'dominantBaseline',
5370 'dominant-baseline': 'dominantBaseline',
5371 dur: 'dur',
5372 dx: 'dx',
5373 dy: 'dy',
5374 edgemode: 'edgeMode',
5375 elevation: 'elevation',
5376 enablebackground: 'enableBackground',
5377 'enable-background': 'enableBackground',
5378 end: 'end',
5379 exponent: 'exponent',
5380 externalresourcesrequired: 'externalResourcesRequired',
5381 fill: 'fill',
5382 fillopacity: 'fillOpacity',
5383 'fill-opacity': 'fillOpacity',
5384 fillrule: 'fillRule',
5385 'fill-rule': 'fillRule',
5386 filter: 'filter',
5387 filterres: 'filterRes',
5388 filterunits: 'filterUnits',
5389 floodopacity: 'floodOpacity',
5390 'flood-opacity': 'floodOpacity',
5391 floodcolor: 'floodColor',
5392 'flood-color': 'floodColor',
5393 focusable: 'focusable',
5394 fontfamily: 'fontFamily',
5395 'font-family': 'fontFamily',
5396 fontsize: 'fontSize',
5397 'font-size': 'fontSize',
5398 fontsizeadjust: 'fontSizeAdjust',
5399 'font-size-adjust': 'fontSizeAdjust',
5400 fontstretch: 'fontStretch',
5401 'font-stretch': 'fontStretch',
5402 fontstyle: 'fontStyle',
5403 'font-style': 'fontStyle',
5404 fontvariant: 'fontVariant',
5405 'font-variant': 'fontVariant',
5406 fontweight: 'fontWeight',
5407 'font-weight': 'fontWeight',
5408 format: 'format',
5409 from: 'from',
5410 fx: 'fx',
5411 fy: 'fy',
5412 g1: 'g1',
5413 g2: 'g2',
5414 glyphname: 'glyphName',
5415 'glyph-name': 'glyphName',
5416 glyphorientationhorizontal: 'glyphOrientationHorizontal',
5417 'glyph-orientation-horizontal': 'glyphOrientationHorizontal',
5418 glyphorientationvertical: 'glyphOrientationVertical',
5419 'glyph-orientation-vertical': 'glyphOrientationVertical',
5420 glyphref: 'glyphRef',
5421 gradienttransform: 'gradientTransform',
5422 gradientunits: 'gradientUnits',
5423 hanging: 'hanging',
5424 horizadvx: 'horizAdvX',
5425 'horiz-adv-x': 'horizAdvX',
5426 horizoriginx: 'horizOriginX',
5427 'horiz-origin-x': 'horizOriginX',
5428 ideographic: 'ideographic',
5429 imagerendering: 'imageRendering',
5430 'image-rendering': 'imageRendering',
5431 in2: 'in2',
5432 in: 'in',
5433 inlist: 'inlist',
5434 intercept: 'intercept',
5435 k1: 'k1',
5436 k2: 'k2',
5437 k3: 'k3',
5438 k4: 'k4',
5439 k: 'k',
5440 kernelmatrix: 'kernelMatrix',
5441 kernelunitlength: 'kernelUnitLength',
5442 kerning: 'kerning',
5443 keypoints: 'keyPoints',
5444 keysplines: 'keySplines',
5445 keytimes: 'keyTimes',
5446 lengthadjust: 'lengthAdjust',
5447 letterspacing: 'letterSpacing',
5448 'letter-spacing': 'letterSpacing',
5449 lightingcolor: 'lightingColor',
5450 'lighting-color': 'lightingColor',
5451 limitingconeangle: 'limitingConeAngle',
5452 local: 'local',
5453 markerend: 'markerEnd',
5454 'marker-end': 'markerEnd',
5455 markerheight: 'markerHeight',
5456 markermid: 'markerMid',
5457 'marker-mid': 'markerMid',
5458 markerstart: 'markerStart',
5459 'marker-start': 'markerStart',
5460 markerunits: 'markerUnits',
5461 markerwidth: 'markerWidth',
5462 mask: 'mask',
5463 maskcontentunits: 'maskContentUnits',
5464 maskunits: 'maskUnits',
5465 mathematical: 'mathematical',
5466 mode: 'mode',
5467 numoctaves: 'numOctaves',
5468 offset: 'offset',
5469 opacity: 'opacity',
5470 operator: 'operator',
5471 order: 'order',
5472 orient: 'orient',
5473 orientation: 'orientation',
5474 origin: 'origin',
5475 overflow: 'overflow',
5476 overlineposition: 'overlinePosition',
5477 'overline-position': 'overlinePosition',
5478 overlinethickness: 'overlineThickness',
5479 'overline-thickness': 'overlineThickness',
5480 paintorder: 'paintOrder',
5481 'paint-order': 'paintOrder',
5482 panose1: 'panose1',
5483 'panose-1': 'panose1',
5484 pathlength: 'pathLength',
5485 patterncontentunits: 'patternContentUnits',
5486 patterntransform: 'patternTransform',
5487 patternunits: 'patternUnits',
5488 pointerevents: 'pointerEvents',
5489 'pointer-events': 'pointerEvents',
5490 points: 'points',
5491 pointsatx: 'pointsAtX',
5492 pointsaty: 'pointsAtY',
5493 pointsatz: 'pointsAtZ',
5494 prefix: 'prefix',
5495 preservealpha: 'preserveAlpha',
5496 preserveaspectratio: 'preserveAspectRatio',
5497 primitiveunits: 'primitiveUnits',
5498 property: 'property',
5499 r: 'r',
5500 radius: 'radius',
5501 refx: 'refX',
5502 refy: 'refY',
5503 renderingintent: 'renderingIntent',
5504 'rendering-intent': 'renderingIntent',
5505 repeatcount: 'repeatCount',
5506 repeatdur: 'repeatDur',
5507 requiredextensions: 'requiredExtensions',
5508 requiredfeatures: 'requiredFeatures',
5509 resource: 'resource',
5510 restart: 'restart',
5511 result: 'result',
5512 results: 'results',
5513 rotate: 'rotate',
5514 rx: 'rx',
5515 ry: 'ry',
5516 scale: 'scale',
5517 security: 'security',
5518 seed: 'seed',
5519 shaperendering: 'shapeRendering',
5520 'shape-rendering': 'shapeRendering',
5521 slope: 'slope',
5522 spacing: 'spacing',
5523 specularconstant: 'specularConstant',
5524 specularexponent: 'specularExponent',
5525 speed: 'speed',
5526 spreadmethod: 'spreadMethod',
5527 startoffset: 'startOffset',
5528 stddeviation: 'stdDeviation',
5529 stemh: 'stemh',
5530 stemv: 'stemv',
5531 stitchtiles: 'stitchTiles',
5532 stopcolor: 'stopColor',
5533 'stop-color': 'stopColor',
5534 stopopacity: 'stopOpacity',
5535 'stop-opacity': 'stopOpacity',
5536 strikethroughposition: 'strikethroughPosition',
5537 'strikethrough-position': 'strikethroughPosition',
5538 strikethroughthickness: 'strikethroughThickness',
5539 'strikethrough-thickness': 'strikethroughThickness',
5540 string: 'string',
5541 stroke: 'stroke',
5542 strokedasharray: 'strokeDasharray',
5543 'stroke-dasharray': 'strokeDasharray',
5544 strokedashoffset: 'strokeDashoffset',
5545 'stroke-dashoffset': 'strokeDashoffset',
5546 strokelinecap: 'strokeLinecap',
5547 'stroke-linecap': 'strokeLinecap',
5548 strokelinejoin: 'strokeLinejoin',
5549 'stroke-linejoin': 'strokeLinejoin',
5550 strokemiterlimit: 'strokeMiterlimit',
5551 'stroke-miterlimit': 'strokeMiterlimit',
5552 strokewidth: 'strokeWidth',
5553 'stroke-width': 'strokeWidth',
5554 strokeopacity: 'strokeOpacity',
5555 'stroke-opacity': 'strokeOpacity',
5556 suppresscontenteditablewarning: 'suppressContentEditableWarning',
5557 suppresshydrationwarning: 'suppressHydrationWarning',
5558 surfacescale: 'surfaceScale',
5559 systemlanguage: 'systemLanguage',
5560 tablevalues: 'tableValues',
5561 targetx: 'targetX',
5562 targety: 'targetY',
5563 textanchor: 'textAnchor',
5564 'text-anchor': 'textAnchor',
5565 textdecoration: 'textDecoration',
5566 'text-decoration': 'textDecoration',
5567 textlength: 'textLength',
5568 textrendering: 'textRendering',
5569 'text-rendering': 'textRendering',
5570 to: 'to',
5571 transform: 'transform',
5572 transformorigin: 'transformOrigin',
5573 'transform-origin': 'transformOrigin',
5574 typeof: 'typeof',
5575 u1: 'u1',
5576 u2: 'u2',
5577 underlineposition: 'underlinePosition',
5578 'underline-position': 'underlinePosition',
5579 underlinethickness: 'underlineThickness',
5580 'underline-thickness': 'underlineThickness',
5581 unicode: 'unicode',
5582 unicodebidi: 'unicodeBidi',
5583 'unicode-bidi': 'unicodeBidi',
5584 unicoderange: 'unicodeRange',
5585 'unicode-range': 'unicodeRange',
5586 unitsperem: 'unitsPerEm',
5587 'units-per-em': 'unitsPerEm',
5588 unselectable: 'unselectable',
5589 valphabetic: 'vAlphabetic',
5590 'v-alphabetic': 'vAlphabetic',
5591 values: 'values',
5592 vectoreffect: 'vectorEffect',
5593 'vector-effect': 'vectorEffect',
5594 version: 'version',
5595 vertadvy: 'vertAdvY',
5596 'vert-adv-y': 'vertAdvY',
5597 vertoriginx: 'vertOriginX',
5598 'vert-origin-x': 'vertOriginX',
5599 vertoriginy: 'vertOriginY',
5600 'vert-origin-y': 'vertOriginY',
5601 vhanging: 'vHanging',
5602 'v-hanging': 'vHanging',
5603 videographic: 'vIdeographic',
5604 'v-ideographic': 'vIdeographic',
5605 viewbox: 'viewBox',
5606 viewtarget: 'viewTarget',
5607 visibility: 'visibility',
5608 vmathematical: 'vMathematical',
5609 'v-mathematical': 'vMathematical',
5610 vocab: 'vocab',
5611 widths: 'widths',
5612 wordspacing: 'wordSpacing',
5613 'word-spacing': 'wordSpacing',
5614 writingmode: 'writingMode',
5615 'writing-mode': 'writingMode',
5616 x1: 'x1',
5617 x2: 'x2',
5618 x: 'x',
5619 xchannelselector: 'xChannelSelector',
5620 xheight: 'xHeight',
5621 'x-height': 'xHeight',
5622 xlinkactuate: 'xlinkActuate',
5623 'xlink:actuate': 'xlinkActuate',
5624 xlinkarcrole: 'xlinkArcrole',
5625 'xlink:arcrole': 'xlinkArcrole',
5626 xlinkhref: 'xlinkHref',
5627 'xlink:href': 'xlinkHref',
5628 xlinkrole: 'xlinkRole',
5629 'xlink:role': 'xlinkRole',
5630 xlinkshow: 'xlinkShow',
5631 'xlink:show': 'xlinkShow',
5632 xlinktitle: 'xlinkTitle',
5633 'xlink:title': 'xlinkTitle',
5634 xlinktype: 'xlinkType',
5635 'xlink:type': 'xlinkType',
5636 xmlbase: 'xmlBase',
5637 'xml:base': 'xmlBase',
5638 xmllang: 'xmlLang',
5639 'xml:lang': 'xmlLang',
5640 xmlns: 'xmlns',
5641 'xml:space': 'xmlSpace',
5642 xmlnsxlink: 'xmlnsXlink',
5643 'xmlns:xlink': 'xmlnsXlink',
5644 xmlspace: 'xmlSpace',
5645 y1: 'y1',
5646 y2: 'y2',
5647 y: 'y',
5648 ychannelselector: 'yChannelSelector',
5649 z: 'z',
5650 zoomandpan: 'zoomAndPan'
5651};
5652
5653var ariaProperties = {
5654 'aria-current': 0,
5655 // state
5656 'aria-description': 0,
5657 'aria-details': 0,
5658 'aria-disabled': 0,
5659 // state
5660 'aria-hidden': 0,
5661 // state
5662 'aria-invalid': 0,
5663 // state
5664 'aria-keyshortcuts': 0,
5665 'aria-label': 0,
5666 'aria-roledescription': 0,
5667 // Widget Attributes
5668 'aria-autocomplete': 0,
5669 'aria-checked': 0,
5670 'aria-expanded': 0,
5671 'aria-haspopup': 0,
5672 'aria-level': 0,
5673 'aria-modal': 0,
5674 'aria-multiline': 0,
5675 'aria-multiselectable': 0,
5676 'aria-orientation': 0,
5677 'aria-placeholder': 0,
5678 'aria-pressed': 0,
5679 'aria-readonly': 0,
5680 'aria-required': 0,
5681 'aria-selected': 0,
5682 'aria-sort': 0,
5683 'aria-valuemax': 0,
5684 'aria-valuemin': 0,
5685 'aria-valuenow': 0,
5686 'aria-valuetext': 0,
5687 // Live Region Attributes
5688 'aria-atomic': 0,
5689 'aria-busy': 0,
5690 'aria-live': 0,
5691 'aria-relevant': 0,
5692 // Drag-and-Drop Attributes
5693 'aria-dropeffect': 0,
5694 'aria-grabbed': 0,
5695 // Relationship Attributes
5696 'aria-activedescendant': 0,
5697 'aria-colcount': 0,
5698 'aria-colindex': 0,
5699 'aria-colspan': 0,
5700 'aria-controls': 0,
5701 'aria-describedby': 0,
5702 'aria-errormessage': 0,
5703 'aria-flowto': 0,
5704 'aria-labelledby': 0,
5705 'aria-owns': 0,
5706 'aria-posinset': 0,
5707 'aria-rowcount': 0,
5708 'aria-rowindex': 0,
5709 'aria-rowspan': 0,
5710 'aria-setsize': 0
5711};
5712
5713var warnedProperties$1 = {};
5714var rARIA$1 = new RegExp('^(aria)-[' + ATTRIBUTE_NAME_CHAR + ']*$');
5715var rARIACamel$1 = new RegExp('^(aria)[A-Z][' + ATTRIBUTE_NAME_CHAR + ']*$');
5716
5717function validateProperty$1(tagName, name) {
5718 {
5719 if (hasOwnProperty.call(warnedProperties$1, name) && warnedProperties$1[name]) {
5720 return true;
5721 }
5722
5723 if (rARIACamel$1.test(name)) {
5724 var ariaName = 'aria-' + name.slice(4).toLowerCase();
5725 var correctName = ariaProperties.hasOwnProperty(ariaName) ? ariaName : null; // If this is an aria-* attribute, but is not listed in the known DOM
5726 // DOM properties, then it is an invalid aria-* attribute.
5727
5728 if (correctName == null) {
5729 error('Invalid ARIA attribute `%s`. ARIA attributes follow the pattern aria-* and must be lowercase.', name);
5730
5731 warnedProperties$1[name] = true;
5732 return true;
5733 } // aria-* attributes should be lowercase; suggest the lowercase version.
5734
5735
5736 if (name !== correctName) {
5737 error('Invalid ARIA attribute `%s`. Did you mean `%s`?', name, correctName);
5738
5739 warnedProperties$1[name] = true;
5740 return true;
5741 }
5742 }
5743
5744 if (rARIA$1.test(name)) {
5745 var lowerCasedName = name.toLowerCase();
5746 var standardName = ariaProperties.hasOwnProperty(lowerCasedName) ? lowerCasedName : null; // If this is an aria-* attribute, but is not listed in the known DOM
5747 // DOM properties, then it is an invalid aria-* attribute.
5748
5749 if (standardName == null) {
5750 warnedProperties$1[name] = true;
5751 return false;
5752 } // aria-* attributes should be lowercase; suggest the lowercase version.
5753
5754
5755 if (name !== standardName) {
5756 error('Unknown ARIA attribute `%s`. Did you mean `%s`?', name, standardName);
5757
5758 warnedProperties$1[name] = true;
5759 return true;
5760 }
5761 }
5762 }
5763
5764 return true;
5765}
5766
5767function validateProperties$2(type, props) {
5768 {
5769 var invalidProps = [];
5770
5771 for (var key in props) {
5772 var isValid = validateProperty$1(type, key);
5773
5774 if (!isValid) {
5775 invalidProps.push(key);
5776 }
5777 }
5778
5779 var unknownPropString = invalidProps.map(function (prop) {
5780 return '`' + prop + '`';
5781 }).join(', ');
5782
5783 if (invalidProps.length === 1) {
5784 error('Invalid aria prop %s on <%s> tag. ' + 'For details, see https://react.dev/link/invalid-aria-props', unknownPropString, type);
5785 } else if (invalidProps.length > 1) {
5786 error('Invalid aria props %s on <%s> tag. ' + 'For details, see https://react.dev/link/invalid-aria-props', unknownPropString, type);
5787 }
5788 }
5789}
5790
5791var didWarnValueNull = false;
5792function validateProperties$1(type, props) {
5793 {
5794 if (type !== 'input' && type !== 'textarea' && type !== 'select') {
5795 return;
5796 }
5797
5798 if (props != null && props.value === null && !didWarnValueNull) {
5799 didWarnValueNull = true;
5800
5801 if (type === 'select' && props.multiple) {
5802 error('`value` prop on `%s` should not be null. ' + 'Consider using an empty array when `multiple` is set to `true` ' + 'to clear the component or `undefined` for uncontrolled components.', type);
5803 } else {
5804 error('`value` prop on `%s` should not be null. ' + 'Consider using an empty string to clear the component or `undefined` ' + 'for uncontrolled components.', type);
5805 }
5806 }
5807 }
5808}
5809
5810var warnedProperties = {};
5811var EVENT_NAME_REGEX = /^on./;
5812var INVALID_EVENT_NAME_REGEX = /^on[^A-Z]/;
5813var rARIA = new RegExp('^(aria)-[' + ATTRIBUTE_NAME_CHAR + ']*$') ;
5814var rARIACamel = new RegExp('^(aria)[A-Z][' + ATTRIBUTE_NAME_CHAR + ']*$') ;
5815
5816function validateProperty(tagName, name, value, eventRegistry) {
5817 {
5818 if (hasOwnProperty.call(warnedProperties, name) && warnedProperties[name]) {
5819 return true;
5820 }
5821
5822 var lowerCasedName = name.toLowerCase();
5823
5824 if (lowerCasedName === 'onfocusin' || lowerCasedName === 'onfocusout') {
5825 error('React uses onFocus and onBlur instead of onFocusIn and onFocusOut. ' + 'All React events are normalized to bubble, so onFocusIn and onFocusOut ' + 'are not needed/supported by React.');
5826
5827 warnedProperties[name] = true;
5828 return true;
5829 } // Actions are special because unlike events they can have other value types.
5830
5831
5832 if (typeof value === 'function') {
5833 if (tagName === 'form' && name === 'action') {
5834 return true;
5835 }
5836
5837 if (tagName === 'input' && name === 'formAction') {
5838 return true;
5839 }
5840
5841 if (tagName === 'button' && name === 'formAction') {
5842 return true;
5843 }
5844 } // We can't rely on the event system being injected on the server.
5845
5846
5847 if (eventRegistry != null) {
5848 var registrationNameDependencies = eventRegistry.registrationNameDependencies,
5849 possibleRegistrationNames = eventRegistry.possibleRegistrationNames;
5850
5851 if (registrationNameDependencies.hasOwnProperty(name)) {
5852 return true;
5853 }
5854
5855 var registrationName = possibleRegistrationNames.hasOwnProperty(lowerCasedName) ? possibleRegistrationNames[lowerCasedName] : null;
5856
5857 if (registrationName != null) {
5858 error('Invalid event handler property `%s`. Did you mean `%s`?', name, registrationName);
5859
5860 warnedProperties[name] = true;
5861 return true;
5862 }
5863
5864 if (EVENT_NAME_REGEX.test(name)) {
5865 error('Unknown event handler property `%s`. It will be ignored.', name);
5866
5867 warnedProperties[name] = true;
5868 return true;
5869 }
5870 } else if (EVENT_NAME_REGEX.test(name)) {
5871 // If no event plugins have been injected, we are in a server environment.
5872 // So we can't tell if the event name is correct for sure, but we can filter
5873 // out known bad ones like `onclick`. We can't suggest a specific replacement though.
5874 if (INVALID_EVENT_NAME_REGEX.test(name)) {
5875 error('Invalid event handler property `%s`. ' + 'React events use the camelCase naming convention, for example `onClick`.', name);
5876 }
5877
5878 warnedProperties[name] = true;
5879 return true;
5880 } // Let the ARIA attribute hook validate ARIA attributes
5881
5882
5883 if (rARIA.test(name) || rARIACamel.test(name)) {
5884 return true;
5885 }
5886
5887 if (lowerCasedName === 'innerhtml') {
5888 error('Directly setting property `innerHTML` is not permitted. ' + 'For more information, lookup documentation on `dangerouslySetInnerHTML`.');
5889
5890 warnedProperties[name] = true;
5891 return true;
5892 }
5893
5894 if (lowerCasedName === 'aria') {
5895 error('The `aria` attribute is reserved for future use in React. ' + 'Pass individual `aria-` attributes instead.');
5896
5897 warnedProperties[name] = true;
5898 return true;
5899 }
5900
5901 if (lowerCasedName === 'is' && value !== null && value !== undefined && typeof value !== 'string') {
5902 error('Received a `%s` for a string attribute `is`. If this is expected, cast ' + 'the value to a string.', typeof value);
5903
5904 warnedProperties[name] = true;
5905 return true;
5906 }
5907
5908 if (typeof value === 'number' && isNaN(value)) {
5909 error('Received NaN for the `%s` attribute. If this is expected, cast ' + 'the value to a string.', name);
5910
5911 warnedProperties[name] = true;
5912 return true;
5913 } // Known attributes should match the casing specified in the property config.
5914
5915
5916 if (possibleStandardNames.hasOwnProperty(lowerCasedName)) {
5917 var standardName = possibleStandardNames[lowerCasedName];
5918
5919 if (standardName !== name) {
5920 error('Invalid DOM property `%s`. Did you mean `%s`?', name, standardName);
5921
5922 warnedProperties[name] = true;
5923 return true;
5924 }
5925 } else if (name !== lowerCasedName) {
5926 // Unknown attributes should have lowercase casing since that's how they
5927 // will be cased anyway with server rendering.
5928 error('React does not recognize the `%s` prop on a DOM element. If you ' + 'intentionally want it to appear in the DOM as a custom ' + 'attribute, spell it as lowercase `%s` instead. ' + 'If you accidentally passed it from a parent component, remove ' + 'it from the DOM element.', name, lowerCasedName);
5929
5930 warnedProperties[name] = true;
5931 return true;
5932 } // Now that we've validated casing, do not validate
5933 // data types for reserved props
5934
5935
5936 switch (name) {
5937 case 'dangerouslySetInnerHTML':
5938 case 'children':
5939 case 'style':
5940 case 'suppressContentEditableWarning':
5941 case 'suppressHydrationWarning':
5942 case 'defaultValue': // Reserved
5943
5944 case 'defaultChecked':
5945 case 'innerHTML':
5946 case 'ref':
5947 {
5948 return true;
5949 }
5950
5951 case 'innerText': // Properties
5952
5953 case 'textContent':
5954 return true;
5955 }
5956
5957 switch (typeof value) {
5958 case 'boolean':
5959 {
5960 switch (name) {
5961 case 'autoFocus':
5962 case 'checked':
5963 case 'multiple':
5964 case 'muted':
5965 case 'selected':
5966 case 'contentEditable':
5967 case 'spellCheck':
5968 case 'draggable':
5969 case 'value':
5970 case 'autoReverse':
5971 case 'externalResourcesRequired':
5972 case 'focusable':
5973 case 'preserveAlpha':
5974 case 'allowFullScreen':
5975 case 'async':
5976 case 'autoPlay':
5977 case 'controls':
5978 case 'default':
5979 case 'defer':
5980 case 'disabled':
5981 case 'disablePictureInPicture':
5982 case 'disableRemotePlayback':
5983 case 'formNoValidate':
5984 case 'hidden':
5985 case 'loop':
5986 case 'noModule':
5987 case 'noValidate':
5988 case 'open':
5989 case 'playsInline':
5990 case 'readOnly':
5991 case 'required':
5992 case 'reversed':
5993 case 'scoped':
5994 case 'seamless':
5995 case 'itemScope':
5996 case 'capture':
5997 case 'download':
5998 case 'inert':
5999 {
6000 // Boolean properties can accept boolean values
6001 return true;
6002 }
6003 // fallthrough
6004
6005 default:
6006 {
6007 var prefix = name.toLowerCase().slice(0, 5);
6008
6009 if (prefix === 'data-' || prefix === 'aria-') {
6010 return true;
6011 }
6012
6013 if (value) {
6014 error('Received `%s` for a non-boolean attribute `%s`.\n\n' + 'If you want to write it to the DOM, pass a string instead: ' + '%s="%s" or %s={value.toString()}.', value, name, name, value, name);
6015 } else {
6016 error('Received `%s` for a non-boolean attribute `%s`.\n\n' + 'If you want to write it to the DOM, pass a string instead: ' + '%s="%s" or %s={value.toString()}.\n\n' + 'If you used to conditionally omit it with %s={condition && value}, ' + 'pass %s={condition ? value : undefined} instead.', value, name, name, value, name, name, name);
6017 }
6018
6019 warnedProperties[name] = true;
6020 return true;
6021 }
6022 }
6023 }
6024
6025 case 'function':
6026 case 'symbol':
6027 // eslint-disable-line
6028 // Warn when a known attribute is a bad type
6029 warnedProperties[name] = true;
6030 return false;
6031
6032 case 'string':
6033 {
6034 // Warn when passing the strings 'false' or 'true' into a boolean prop
6035 if (value === 'false' || value === 'true') {
6036 switch (name) {
6037 case 'checked':
6038 case 'selected':
6039 case 'multiple':
6040 case 'muted':
6041 case 'allowFullScreen':
6042 case 'async':
6043 case 'autoPlay':
6044 case 'controls':
6045 case 'default':
6046 case 'defer':
6047 case 'disabled':
6048 case 'disablePictureInPicture':
6049 case 'disableRemotePlayback':
6050 case 'formNoValidate':
6051 case 'hidden':
6052 case 'loop':
6053 case 'noModule':
6054 case 'noValidate':
6055 case 'open':
6056 case 'playsInline':
6057 case 'readOnly':
6058 case 'required':
6059 case 'reversed':
6060 case 'scoped':
6061 case 'seamless':
6062 case 'itemScope':
6063 case 'inert':
6064 {
6065 break;
6066 }
6067
6068 default:
6069 {
6070 return true;
6071 }
6072 }
6073
6074 error('Received the string `%s` for the boolean attribute `%s`. ' + '%s ' + 'Did you mean %s={%s}?', value, name, value === 'false' ? 'The browser will interpret it as a truthy value.' : 'Although this works, it will not work as expected if you pass the string "false".', name, value);
6075
6076 warnedProperties[name] = true;
6077 return true;
6078 }
6079 }
6080 }
6081
6082 return true;
6083 }
6084}
6085
6086function warnUnknownProperties(type, props, eventRegistry) {
6087 {
6088 var unknownProps = [];
6089
6090 for (var key in props) {
6091 var isValid = validateProperty(type, key, props[key], eventRegistry);
6092
6093 if (!isValid) {
6094 unknownProps.push(key);
6095 }
6096 }
6097
6098 var unknownPropString = unknownProps.map(function (prop) {
6099 return '`' + prop + '`';
6100 }).join(', ');
6101
6102 if (unknownProps.length === 1) {
6103 error('Invalid value for prop %s on <%s> tag. Either remove it from the element, ' + 'or pass a string or number value to keep it in the DOM. ' + 'For details, see https://react.dev/link/attribute-behavior ', unknownPropString, type);
6104 } else if (unknownProps.length > 1) {
6105 error('Invalid values for props %s on <%s> tag. Either remove them from the element, ' + 'or pass a string or number value to keep them in the DOM. ' + 'For details, see https://react.dev/link/attribute-behavior ', unknownPropString, type);
6106 }
6107 }
6108}
6109
6110function validateProperties(type, props, eventRegistry) {
6111 if (isCustomElement(type) || typeof props.is === 'string') {
6112 return;
6113 }
6114
6115 warnUnknownProperties(type, props, eventRegistry);
6116}
6117
6118// A javascript: URL can contain leading C0 control or \u0020 SPACE,
6119// and any newline or tab are filtered out as if they're not part of the URL.
6120// https://url.spec.whatwg.org/#url-parsing
6121// Tab or newline are defined as \r\n\t:
6122// https://infra.spec.whatwg.org/#ascii-tab-or-newline
6123// A C0 control is a code point in the range \u0000 NULL to \u001F
6124// INFORMATION SEPARATOR ONE, inclusive:
6125// https://infra.spec.whatwg.org/#c0-control-or-space
6126
6127/* eslint-disable max-len */
6128var isJavaScriptProtocol = /^[\u0000-\u001F ]*j[\r\n\t]*a[\r\n\t]*v[\r\n\t]*a[\r\n\t]*s[\r\n\t]*c[\r\n\t]*r[\r\n\t]*i[\r\n\t]*p[\r\n\t]*t[\r\n\t]*\:/i;
6129
6130function sanitizeURL(url) {
6131 // We should never have symbols here because they get filtered out elsewhere.
6132 // eslint-disable-next-line react-internal/safe-string-coercion
6133 if (isJavaScriptProtocol.test('' + url)) {
6134 // Return a different javascript: url that doesn't cause any side-effects and just
6135 // throws if ever visited.
6136 // eslint-disable-next-line no-script-url
6137 return "javascript:throw new Error('React has blocked a javascript: URL as a security precaution.')";
6138 }
6139
6140 return url;
6141}
6142
6143var IS_EVENT_HANDLE_NON_MANAGED_NODE = 1;
6144var IS_NON_DELEGATED = 1 << 1;
6145var IS_CAPTURE_PHASE = 1 << 2;
6146// set to LEGACY_FB_SUPPORT. LEGACY_FB_SUPPORT only gets set when
6147// we call willDeferLaterForLegacyFBSupport, thus not bailing out
6148// will result in endless cycles like an infinite loop.
6149// We also don't want to defer during event replaying.
6150
6151var SHOULD_NOT_PROCESS_POLYFILL_EVENT_PLUGINS = IS_EVENT_HANDLE_NON_MANAGED_NODE | IS_NON_DELEGATED | IS_CAPTURE_PHASE;
6152
6153// This exists to avoid circular dependency between ReactDOMEventReplaying
6154// and DOMPluginEventSystem.
6155var currentReplayingEvent = null;
6156function setReplayingEvent(event) {
6157 {
6158 if (currentReplayingEvent !== null) {
6159 error('Expected currently replaying event to be null. This error ' + 'is likely caused by a bug in React. Please file an issue.');
6160 }
6161 }
6162
6163 currentReplayingEvent = event;
6164}
6165function resetReplayingEvent() {
6166 {
6167 if (currentReplayingEvent === null) {
6168 error('Expected currently replaying event to not be null. This error ' + 'is likely caused by a bug in React. Please file an issue.');
6169 }
6170 }
6171
6172 currentReplayingEvent = null;
6173}
6174function isReplayingEvent(event) {
6175 return event === currentReplayingEvent;
6176}
6177
6178/**
6179 * Gets the target node from a native browser event by accounting for
6180 * inconsistencies in browser DOM APIs.
6181 *
6182 * @param {object} nativeEvent Native browser event.
6183 * @return {DOMEventTarget} Target node.
6184 */
6185
6186function getEventTarget(nativeEvent) {
6187 // Fallback to nativeEvent.srcElement for IE9
6188 // https://github.com/facebook/react/issues/12506
6189 var target = nativeEvent.target || nativeEvent.srcElement || window; // Normalize SVG <use> element events #4963
6190
6191 if (target.correspondingUseElement) {
6192 target = target.correspondingUseElement;
6193 } // Safari may fire events on text nodes (Node.TEXT_NODE is 3).
6194 // @see http://www.quirksmode.org/js/events_properties.html
6195
6196
6197 return target.nodeType === TEXT_NODE ? target.parentNode : target;
6198}
6199
6200var restoreTarget = null;
6201var restoreQueue = null;
6202
6203function restoreStateOfTarget(target) {
6204 // We perform this translation at the end of the event loop so that we
6205 // always receive the correct fiber here
6206 var internalInstance = getInstanceFromNode(target);
6207
6208 if (!internalInstance) {
6209 // Unmounted
6210 return;
6211 }
6212
6213 var stateNode = internalInstance.stateNode; // Guard against Fiber being unmounted.
6214
6215 if (stateNode) {
6216 var props = getFiberCurrentPropsFromNode(stateNode);
6217 restoreControlledState(internalInstance.stateNode, internalInstance.type, props);
6218 }
6219}
6220
6221function enqueueStateRestore(target) {
6222 if (restoreTarget) {
6223 if (restoreQueue) {
6224 restoreQueue.push(target);
6225 } else {
6226 restoreQueue = [target];
6227 }
6228 } else {
6229 restoreTarget = target;
6230 }
6231}
6232function needsStateRestore() {
6233 return restoreTarget !== null || restoreQueue !== null;
6234}
6235function restoreStateIfNeeded() {
6236 if (!restoreTarget) {
6237 return;
6238 }
6239
6240 var target = restoreTarget;
6241 var queuedTargets = restoreQueue;
6242 restoreTarget = null;
6243 restoreQueue = null;
6244 restoreStateOfTarget(target);
6245
6246 if (queuedTargets) {
6247 for (var i = 0; i < queuedTargets.length; i++) {
6248 restoreStateOfTarget(queuedTargets[i]);
6249 }
6250 }
6251}
6252
6253// the renderer. Such as when we're dispatching events or if third party
6254// libraries need to call batchedUpdates. Eventually, this API will go away when
6255// everything is batched by default. We'll then have a similar API to opt-out of
6256// scheduled work and instead do synchronous work.
6257
6258var isInsideEventHandler = false;
6259
6260function finishEventHandler() {
6261 // Here we wait until all updates have propagated, which is important
6262 // when using controlled components within layers:
6263 // https://github.com/facebook/react/issues/1698
6264 // Then we restore state of any controlled component.
6265 var controlledComponentsHavePendingUpdates = needsStateRestore();
6266
6267 if (controlledComponentsHavePendingUpdates) {
6268 // If a controlled event was fired, we may need to restore the state of
6269 // the DOM node back to the controlled value. This is necessary when React
6270 // bails out of the update without touching the DOM.
6271 // TODO: Restore state in the microtask, after the discrete updates flush,
6272 // instead of early flushing them here.
6273 // @TODO Should move to flushSyncWork once legacy mode is removed but since this flushSync
6274 // flushes passive effects we can't do this yet.
6275 flushSyncWork$1();
6276 restoreStateIfNeeded();
6277 }
6278}
6279
6280function batchedUpdates$1(fn, a, b) {
6281 if (isInsideEventHandler) {
6282 // If we are currently inside another batch, we need to wait until it
6283 // fully completes before restoring state.
6284 return fn(a, b);
6285 }
6286
6287 isInsideEventHandler = true;
6288
6289 try {
6290 return batchedUpdates(fn, a, b);
6291 } finally {
6292 isInsideEventHandler = false;
6293 finishEventHandler();
6294 }
6295} // TODO: Replace with flushSync
6296
6297function isInteractive(tag) {
6298 return tag === 'button' || tag === 'input' || tag === 'select' || tag === 'textarea';
6299}
6300
6301function shouldPreventMouseEvent(name, type, props) {
6302 switch (name) {
6303 case 'onClick':
6304 case 'onClickCapture':
6305 case 'onDoubleClick':
6306 case 'onDoubleClickCapture':
6307 case 'onMouseDown':
6308 case 'onMouseDownCapture':
6309 case 'onMouseMove':
6310 case 'onMouseMoveCapture':
6311 case 'onMouseUp':
6312 case 'onMouseUpCapture':
6313 case 'onMouseEnter':
6314 return !!(props.disabled && isInteractive(type));
6315
6316 default:
6317 return false;
6318 }
6319}
6320/**
6321 * @param {object} inst The instance, which is the source of events.
6322 * @param {string} registrationName Name of listener (e.g. `onClick`).
6323 * @return {?function} The stored callback.
6324 */
6325
6326
6327function getListener(inst, registrationName) {
6328 var stateNode = inst.stateNode;
6329
6330 if (stateNode === null) {
6331 // Work in progress (ex: onload events in incremental mode).
6332 return null;
6333 }
6334
6335 var props = getFiberCurrentPropsFromNode(stateNode);
6336
6337 if (props === null) {
6338 // Work in progress.
6339 return null;
6340 }
6341
6342 var listener = props[registrationName];
6343
6344 if (shouldPreventMouseEvent(registrationName, inst.type, props)) {
6345 return null;
6346 }
6347
6348 if (listener && typeof listener !== 'function') {
6349 throw new Error("Expected `" + registrationName + "` listener to be a function, instead got a value of `" + typeof listener + "` type.");
6350 }
6351
6352 return listener;
6353}
6354
6355var passiveBrowserEventsSupported = false; // Check if browser support events with passive listeners
6356// https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener#Safely_detecting_option_support
6357
6358if (canUseDOM) {
6359 try {
6360 var options = {};
6361 Object.defineProperty(options, 'passive', {
6362 get: function () {
6363 passiveBrowserEventsSupported = true;
6364 }
6365 });
6366 window.addEventListener('test', options, options);
6367 window.removeEventListener('test', options, options);
6368 } catch (e) {
6369 passiveBrowserEventsSupported = false;
6370 }
6371}
6372
6373function addEventBubbleListener(target, eventType, listener) {
6374 target.addEventListener(eventType, listener, false);
6375 return listener;
6376}
6377function addEventCaptureListener(target, eventType, listener) {
6378 target.addEventListener(eventType, listener, true);
6379 return listener;
6380}
6381function addEventCaptureListenerWithPassiveFlag(target, eventType, listener, passive) {
6382 target.addEventListener(eventType, listener, {
6383 capture: true,
6384 passive: passive
6385 });
6386 return listener;
6387}
6388function addEventBubbleListenerWithPassiveFlag(target, eventType, listener, passive) {
6389 target.addEventListener(eventType, listener, {
6390 passive: passive
6391 });
6392 return listener;
6393}
6394
6395/**
6396 * These variables store information about text content of a target node,
6397 * allowing comparison of content before and after a given event.
6398 *
6399 * Identify the node where selection currently begins, then observe
6400 * both its text content and its current position in the DOM. Since the
6401 * browser may natively replace the target node during composition, we can
6402 * use its position to find its replacement.
6403 *
6404 *
6405 */
6406var root = null;
6407var startText = null;
6408var fallbackText = null;
6409function initialize(nativeEventTarget) {
6410 root = nativeEventTarget;
6411 startText = getText();
6412 return true;
6413}
6414function reset() {
6415 root = null;
6416 startText = null;
6417 fallbackText = null;
6418}
6419function getData() {
6420 if (fallbackText) {
6421 return fallbackText;
6422 }
6423
6424 var start;
6425 var startValue = startText;
6426 var startLength = startValue.length;
6427 var end;
6428 var endValue = getText();
6429 var endLength = endValue.length;
6430
6431 for (start = 0; start < startLength; start++) {
6432 if (startValue[start] !== endValue[start]) {
6433 break;
6434 }
6435 }
6436
6437 var minEnd = startLength - start;
6438
6439 for (end = 1; end <= minEnd; end++) {
6440 if (startValue[startLength - end] !== endValue[endLength - end]) {
6441 break;
6442 }
6443 }
6444
6445 var sliceTail = end > 1 ? 1 - end : undefined;
6446 fallbackText = endValue.slice(start, sliceTail);
6447 return fallbackText;
6448}
6449function getText() {
6450 if ('value' in root) {
6451 return root.value;
6452 }
6453
6454 return root.textContent;
6455}
6456
6457/**
6458 * `charCode` represents the actual "character code" and is safe to use with
6459 * `String.fromCharCode`. As such, only keys that correspond to printable
6460 * characters produce a valid `charCode`, the only exception to this is Enter.
6461 * The Tab-key is considered non-printable and does not have a `charCode`,
6462 * presumably because it does not produce a tab-character in browsers.
6463 *
6464 * @param {object} nativeEvent Native browser event.
6465 * @return {number} Normalized `charCode` property.
6466 */
6467function getEventCharCode(nativeEvent) {
6468 var charCode;
6469 var keyCode = nativeEvent.keyCode;
6470
6471 if ('charCode' in nativeEvent) {
6472 charCode = nativeEvent.charCode; // FF does not set `charCode` for the Enter-key, check against `keyCode`.
6473
6474 if (charCode === 0 && keyCode === 13) {
6475 charCode = 13;
6476 }
6477 } else {
6478 // IE8 does not implement `charCode`, but `keyCode` has the correct value.
6479 charCode = keyCode;
6480 } // IE and Edge (on Windows) and Chrome / Safari (on Windows and Linux)
6481 // report Enter as charCode 10 when ctrl is pressed.
6482
6483
6484 if (charCode === 10) {
6485 charCode = 13;
6486 } // Some non-printable keys are reported in `charCode`/`keyCode`, discard them.
6487 // Must not discard the (non-)printable Enter-key.
6488
6489
6490 if (charCode >= 32 || charCode === 13) {
6491 return charCode;
6492 }
6493
6494 return 0;
6495}
6496
6497function functionThatReturnsTrue() {
6498 return true;
6499}
6500
6501function functionThatReturnsFalse() {
6502 return false;
6503} // This is intentionally a factory so that we have different returned constructors.
6504// If we had a single constructor, it would be megamorphic and engines would deopt.
6505
6506
6507function createSyntheticEvent(Interface) {
6508 /**
6509 * Synthetic events are dispatched by event plugins, typically in response to a
6510 * top-level event delegation handler.
6511 *
6512 * These systems should generally use pooling to reduce the frequency of garbage
6513 * collection. The system should check `isPersistent` to determine whether the
6514 * event should be released into the pool after being dispatched. Users that
6515 * need a persisted event should invoke `persist`.
6516 *
6517 * Synthetic events (and subclasses) implement the DOM Level 3 Events API by
6518 * normalizing browser quirks. Subclasses do not necessarily have to implement a
6519 * DOM interface; custom application-specific events can also subclass this.
6520 */
6521 // $FlowFixMe[missing-this-annot]
6522 function SyntheticBaseEvent(reactName, reactEventType, targetInst, nativeEvent, nativeEventTarget) {
6523 this._reactName = reactName;
6524 this._targetInst = targetInst;
6525 this.type = reactEventType;
6526 this.nativeEvent = nativeEvent;
6527 this.target = nativeEventTarget;
6528 this.currentTarget = null;
6529
6530 for (var propName in Interface) {
6531 if (!Interface.hasOwnProperty(propName)) {
6532 continue;
6533 }
6534
6535 var normalize = Interface[propName];
6536
6537 if (normalize) {
6538 this[propName] = normalize(nativeEvent);
6539 } else {
6540 this[propName] = nativeEvent[propName];
6541 }
6542 }
6543
6544 var defaultPrevented = nativeEvent.defaultPrevented != null ? nativeEvent.defaultPrevented : nativeEvent.returnValue === false;
6545
6546 if (defaultPrevented) {
6547 this.isDefaultPrevented = functionThatReturnsTrue;
6548 } else {
6549 this.isDefaultPrevented = functionThatReturnsFalse;
6550 }
6551
6552 this.isPropagationStopped = functionThatReturnsFalse;
6553 return this;
6554 } // $FlowFixMe[prop-missing] found when upgrading Flow
6555
6556
6557 assign(SyntheticBaseEvent.prototype, {
6558 // $FlowFixMe[missing-this-annot]
6559 preventDefault: function () {
6560 this.defaultPrevented = true;
6561 var event = this.nativeEvent;
6562
6563 if (!event) {
6564 return;
6565 }
6566
6567 if (event.preventDefault) {
6568 event.preventDefault(); // $FlowFixMe[illegal-typeof] - flow is not aware of `unknown` in IE
6569 } else if (typeof event.returnValue !== 'unknown') {
6570 event.returnValue = false;
6571 }
6572
6573 this.isDefaultPrevented = functionThatReturnsTrue;
6574 },
6575 // $FlowFixMe[missing-this-annot]
6576 stopPropagation: function () {
6577 var event = this.nativeEvent;
6578
6579 if (!event) {
6580 return;
6581 }
6582
6583 if (event.stopPropagation) {
6584 event.stopPropagation(); // $FlowFixMe[illegal-typeof] - flow is not aware of `unknown` in IE
6585 } else if (typeof event.cancelBubble !== 'unknown') {
6586 // The ChangeEventPlugin registers a "propertychange" event for
6587 // IE. This event does not support bubbling or cancelling, and
6588 // any references to cancelBubble throw "Member not found". A
6589 // typeof check of "unknown" circumvents this issue (and is also
6590 // IE specific).
6591 event.cancelBubble = true;
6592 }
6593
6594 this.isPropagationStopped = functionThatReturnsTrue;
6595 },
6596
6597 /**
6598 * We release all dispatched `SyntheticEvent`s after each event loop, adding
6599 * them back into the pool. This allows a way to hold onto a reference that
6600 * won't be added back into the pool.
6601 */
6602 persist: function () {// Modern event system doesn't use pooling.
6603 },
6604
6605 /**
6606 * Checks if this event should be released back into the pool.
6607 *
6608 * @return {boolean} True if this should not be released, false otherwise.
6609 */
6610 isPersistent: functionThatReturnsTrue
6611 });
6612 return SyntheticBaseEvent;
6613}
6614/**
6615 * @interface Event
6616 * @see http://www.w3.org/TR/DOM-Level-3-Events/
6617 */
6618
6619
6620var EventInterface = {
6621 eventPhase: 0,
6622 bubbles: 0,
6623 cancelable: 0,
6624 timeStamp: function (event) {
6625 return event.timeStamp || Date.now();
6626 },
6627 defaultPrevented: 0,
6628 isTrusted: 0
6629};
6630var SyntheticEvent = createSyntheticEvent(EventInterface);
6631
6632var UIEventInterface = assign({}, EventInterface, {
6633 view: 0,
6634 detail: 0
6635});
6636
6637var SyntheticUIEvent = createSyntheticEvent(UIEventInterface);
6638var lastMovementX;
6639var lastMovementY;
6640var lastMouseEvent;
6641
6642function updateMouseMovementPolyfillState(event) {
6643 if (event !== lastMouseEvent) {
6644 if (lastMouseEvent && event.type === 'mousemove') {
6645 // $FlowFixMe[unsafe-arithmetic] assuming this is a number
6646 lastMovementX = event.screenX - lastMouseEvent.screenX; // $FlowFixMe[unsafe-arithmetic] assuming this is a number
6647
6648 lastMovementY = event.screenY - lastMouseEvent.screenY;
6649 } else {
6650 lastMovementX = 0;
6651 lastMovementY = 0;
6652 }
6653
6654 lastMouseEvent = event;
6655 }
6656}
6657/**
6658 * @interface MouseEvent
6659 * @see http://www.w3.org/TR/DOM-Level-3-Events/
6660 */
6661
6662
6663var MouseEventInterface = assign({}, UIEventInterface, {
6664 screenX: 0,
6665 screenY: 0,
6666 clientX: 0,
6667 clientY: 0,
6668 pageX: 0,
6669 pageY: 0,
6670 ctrlKey: 0,
6671 shiftKey: 0,
6672 altKey: 0,
6673 metaKey: 0,
6674 getModifierState: getEventModifierState,
6675 button: 0,
6676 buttons: 0,
6677 relatedTarget: function (event) {
6678 if (event.relatedTarget === undefined) return event.fromElement === event.srcElement ? event.toElement : event.fromElement;
6679 return event.relatedTarget;
6680 },
6681 movementX: function (event) {
6682 if ('movementX' in event) {
6683 return event.movementX;
6684 }
6685
6686 updateMouseMovementPolyfillState(event);
6687 return lastMovementX;
6688 },
6689 movementY: function (event) {
6690 if ('movementY' in event) {
6691 return event.movementY;
6692 } // Don't need to call updateMouseMovementPolyfillState() here
6693 // because it's guaranteed to have already run when movementX
6694 // was copied.
6695
6696
6697 return lastMovementY;
6698 }
6699});
6700
6701var SyntheticMouseEvent = createSyntheticEvent(MouseEventInterface);
6702/**
6703 * @interface DragEvent
6704 * @see http://www.w3.org/TR/DOM-Level-3-Events/
6705 */
6706
6707var DragEventInterface = assign({}, MouseEventInterface, {
6708 dataTransfer: 0
6709});
6710
6711var SyntheticDragEvent = createSyntheticEvent(DragEventInterface);
6712/**
6713 * @interface FocusEvent
6714 * @see http://www.w3.org/TR/DOM-Level-3-Events/
6715 */
6716
6717var FocusEventInterface = assign({}, UIEventInterface, {
6718 relatedTarget: 0
6719});
6720
6721var SyntheticFocusEvent = createSyntheticEvent(FocusEventInterface);
6722/**
6723 * @interface Event
6724 * @see http://www.w3.org/TR/css3-animations/#AnimationEvent-interface
6725 * @see https://developer.mozilla.org/en-US/docs/Web/API/AnimationEvent
6726 */
6727
6728var AnimationEventInterface = assign({}, EventInterface, {
6729 animationName: 0,
6730 elapsedTime: 0,
6731 pseudoElement: 0
6732});
6733
6734var SyntheticAnimationEvent = createSyntheticEvent(AnimationEventInterface);
6735/**
6736 * @interface Event
6737 * @see http://www.w3.org/TR/clipboard-apis/
6738 */
6739
6740var ClipboardEventInterface = assign({}, EventInterface, {
6741 clipboardData: function (event) {
6742 return 'clipboardData' in event ? event.clipboardData : window.clipboardData;
6743 }
6744});
6745
6746var SyntheticClipboardEvent = createSyntheticEvent(ClipboardEventInterface);
6747/**
6748 * @interface Event
6749 * @see http://www.w3.org/TR/DOM-Level-3-Events/#events-compositionevents
6750 */
6751
6752var CompositionEventInterface = assign({}, EventInterface, {
6753 data: 0
6754});
6755
6756var SyntheticCompositionEvent = createSyntheticEvent(CompositionEventInterface);
6757/**
6758 * @interface Event
6759 * @see http://www.w3.org/TR/2013/WD-DOM-Level-3-Events-20131105
6760 * /#events-inputevents
6761 */
6762// Happens to share the same list for now.
6763
6764var SyntheticInputEvent = SyntheticCompositionEvent;
6765/**
6766 * Normalization of deprecated HTML5 `key` values
6767 * @see https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent#Key_names
6768 */
6769
6770var normalizeKey = {
6771 Esc: 'Escape',
6772 Spacebar: ' ',
6773 Left: 'ArrowLeft',
6774 Up: 'ArrowUp',
6775 Right: 'ArrowRight',
6776 Down: 'ArrowDown',
6777 Del: 'Delete',
6778 Win: 'OS',
6779 Menu: 'ContextMenu',
6780 Apps: 'ContextMenu',
6781 Scroll: 'ScrollLock',
6782 MozPrintableKey: 'Unidentified'
6783};
6784/**
6785 * Translation from legacy `keyCode` to HTML5 `key`
6786 * Only special keys supported, all others depend on keyboard layout or browser
6787 * @see https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent#Key_names
6788 */
6789
6790var translateToKey = {
6791 '8': 'Backspace',
6792 '9': 'Tab',
6793 '12': 'Clear',
6794 '13': 'Enter',
6795 '16': 'Shift',
6796 '17': 'Control',
6797 '18': 'Alt',
6798 '19': 'Pause',
6799 '20': 'CapsLock',
6800 '27': 'Escape',
6801 '32': ' ',
6802 '33': 'PageUp',
6803 '34': 'PageDown',
6804 '35': 'End',
6805 '36': 'Home',
6806 '37': 'ArrowLeft',
6807 '38': 'ArrowUp',
6808 '39': 'ArrowRight',
6809 '40': 'ArrowDown',
6810 '45': 'Insert',
6811 '46': 'Delete',
6812 '112': 'F1',
6813 '113': 'F2',
6814 '114': 'F3',
6815 '115': 'F4',
6816 '116': 'F5',
6817 '117': 'F6',
6818 '118': 'F7',
6819 '119': 'F8',
6820 '120': 'F9',
6821 '121': 'F10',
6822 '122': 'F11',
6823 '123': 'F12',
6824 '144': 'NumLock',
6825 '145': 'ScrollLock',
6826 '224': 'Meta'
6827};
6828/**
6829 * @param {object} nativeEvent Native browser event.
6830 * @return {string} Normalized `key` property.
6831 */
6832
6833function getEventKey(nativeEvent) {
6834 if (nativeEvent.key) {
6835 // Normalize inconsistent values reported by browsers due to
6836 // implementations of a working draft specification.
6837 // FireFox implements `key` but returns `MozPrintableKey` for all
6838 // printable characters (normalized to `Unidentified`), ignore it.
6839 var key = // $FlowFixMe[invalid-computed-prop] unable to index with a `mixed` value
6840 normalizeKey[nativeEvent.key] || nativeEvent.key;
6841
6842 if (key !== 'Unidentified') {
6843 return key;
6844 }
6845 } // Browser does not implement `key`, polyfill as much of it as we can.
6846
6847
6848 if (nativeEvent.type === 'keypress') {
6849 var charCode = getEventCharCode( // $FlowFixMe[incompatible-call] unable to narrow to `KeyboardEvent`
6850 nativeEvent); // The enter-key is technically both printable and non-printable and can
6851 // thus be captured by `keypress`, no other non-printable key should.
6852
6853 return charCode === 13 ? 'Enter' : String.fromCharCode(charCode);
6854 }
6855
6856 if (nativeEvent.type === 'keydown' || nativeEvent.type === 'keyup') {
6857 // While user keyboard layout determines the actual meaning of each
6858 // `keyCode` value, almost all function keys have a universal value.
6859 // $FlowFixMe[invalid-computed-prop] unable to index with a `mixed` value
6860 return translateToKey[nativeEvent.keyCode] || 'Unidentified';
6861 }
6862
6863 return '';
6864}
6865/**
6866 * Translation from modifier key to the associated property in the event.
6867 * @see http://www.w3.org/TR/DOM-Level-3-Events/#keys-Modifiers
6868 */
6869
6870
6871var modifierKeyToProp = {
6872 Alt: 'altKey',
6873 Control: 'ctrlKey',
6874 Meta: 'metaKey',
6875 Shift: 'shiftKey'
6876}; // Older browsers (Safari <= 10, iOS Safari <= 10.2) do not support
6877// getModifierState. If getModifierState is not supported, we map it to a set of
6878// modifier keys exposed by the event. In this case, Lock-keys are not supported.
6879// $FlowFixMe[missing-local-annot]
6880// $FlowFixMe[missing-this-annot]
6881
6882function modifierStateGetter(keyArg) {
6883 var syntheticEvent = this;
6884 var nativeEvent = syntheticEvent.nativeEvent;
6885
6886 if (nativeEvent.getModifierState) {
6887 return nativeEvent.getModifierState(keyArg);
6888 }
6889
6890 var keyProp = modifierKeyToProp[keyArg];
6891 return keyProp ? !!nativeEvent[keyProp] : false;
6892}
6893
6894function getEventModifierState(nativeEvent) {
6895 return modifierStateGetter;
6896}
6897/**
6898 * @interface KeyboardEvent
6899 * @see http://www.w3.org/TR/DOM-Level-3-Events/
6900 */
6901
6902
6903var KeyboardEventInterface = assign({}, UIEventInterface, {
6904 key: getEventKey,
6905 code: 0,
6906 location: 0,
6907 ctrlKey: 0,
6908 shiftKey: 0,
6909 altKey: 0,
6910 metaKey: 0,
6911 repeat: 0,
6912 locale: 0,
6913 getModifierState: getEventModifierState,
6914 // Legacy Interface
6915 charCode: function (event) {
6916 // `charCode` is the result of a KeyPress event and represents the value of
6917 // the actual printable character.
6918 // KeyPress is deprecated, but its replacement is not yet final and not
6919 // implemented in any major browser. Only KeyPress has charCode.
6920 if (event.type === 'keypress') {
6921 return getEventCharCode( // $FlowFixMe[incompatible-call] unable to narrow to `KeyboardEvent`
6922 event);
6923 }
6924
6925 return 0;
6926 },
6927 keyCode: function (event) {
6928 // `keyCode` is the result of a KeyDown/Up event and represents the value of
6929 // physical keyboard key.
6930 // The actual meaning of the value depends on the users' keyboard layout
6931 // which cannot be detected. Assuming that it is a US keyboard layout
6932 // provides a surprisingly accurate mapping for US and European users.
6933 // Due to this, it is left to the user to implement at this time.
6934 if (event.type === 'keydown' || event.type === 'keyup') {
6935 return event.keyCode;
6936 }
6937
6938 return 0;
6939 },
6940 which: function (event) {
6941 // `which` is an alias for either `keyCode` or `charCode` depending on the
6942 // type of the event.
6943 if (event.type === 'keypress') {
6944 return getEventCharCode( // $FlowFixMe[incompatible-call] unable to narrow to `KeyboardEvent`
6945 event);
6946 }
6947
6948 if (event.type === 'keydown' || event.type === 'keyup') {
6949 return event.keyCode;
6950 }
6951
6952 return 0;
6953 }
6954});
6955
6956var SyntheticKeyboardEvent = createSyntheticEvent(KeyboardEventInterface);
6957/**
6958 * @interface PointerEvent
6959 * @see http://www.w3.org/TR/pointerevents/
6960 */
6961
6962var PointerEventInterface = assign({}, MouseEventInterface, {
6963 pointerId: 0,
6964 width: 0,
6965 height: 0,
6966 pressure: 0,
6967 tangentialPressure: 0,
6968 tiltX: 0,
6969 tiltY: 0,
6970 twist: 0,
6971 pointerType: 0,
6972 isPrimary: 0
6973});
6974
6975var SyntheticPointerEvent = createSyntheticEvent(PointerEventInterface);
6976/**
6977 * @interface TouchEvent
6978 * @see http://www.w3.org/TR/touch-events/
6979 */
6980
6981var TouchEventInterface = assign({}, UIEventInterface, {
6982 touches: 0,
6983 targetTouches: 0,
6984 changedTouches: 0,
6985 altKey: 0,
6986 metaKey: 0,
6987 ctrlKey: 0,
6988 shiftKey: 0,
6989 getModifierState: getEventModifierState
6990});
6991
6992var SyntheticTouchEvent = createSyntheticEvent(TouchEventInterface);
6993/**
6994 * @interface Event
6995 * @see http://www.w3.org/TR/2009/WD-css3-transitions-20090320/#transition-events-
6996 * @see https://developer.mozilla.org/en-US/docs/Web/API/TransitionEvent
6997 */
6998
6999var TransitionEventInterface = assign({}, EventInterface, {
7000 propertyName: 0,
7001 elapsedTime: 0,
7002 pseudoElement: 0
7003});
7004
7005var SyntheticTransitionEvent = createSyntheticEvent(TransitionEventInterface);
7006/**
7007 * @interface WheelEvent
7008 * @see http://www.w3.org/TR/DOM-Level-3-Events/
7009 */
7010
7011var WheelEventInterface = assign({}, MouseEventInterface, {
7012 deltaX: function (event) {
7013 return 'deltaX' in event ? event.deltaX : // Fallback to `wheelDeltaX` for Webkit and normalize (right is positive).
7014 'wheelDeltaX' in event ? // $FlowFixMe[unsafe-arithmetic] assuming this is a number
7015 -event.wheelDeltaX : 0;
7016 },
7017 deltaY: function (event) {
7018 return 'deltaY' in event ? event.deltaY : // Fallback to `wheelDeltaY` for Webkit and normalize (down is positive).
7019 'wheelDeltaY' in event ? // $FlowFixMe[unsafe-arithmetic] assuming this is a number
7020 -event.wheelDeltaY : // Fallback to `wheelDelta` for IE<9 and normalize (down is positive).
7021 'wheelDelta' in event ? // $FlowFixMe[unsafe-arithmetic] assuming this is a number
7022 -event.wheelDelta : 0;
7023 },
7024 deltaZ: 0,
7025 // Browsers without "deltaMode" is reporting in raw wheel delta where one
7026 // notch on the scroll is always +/- 120, roughly equivalent to pixels.
7027 // A good approximation of DOM_DELTA_LINE (1) is 5% of viewport size or
7028 // ~40 pixels, for DOM_DELTA_SCREEN (2) it is 87.5% of viewport size.
7029 deltaMode: 0
7030});
7031
7032var SyntheticWheelEvent = createSyntheticEvent(WheelEventInterface);
7033
7034var END_KEYCODES = [9, 13, 27, 32]; // Tab, Return, Esc, Space
7035
7036var START_KEYCODE = 229;
7037var canUseCompositionEvent = canUseDOM && 'CompositionEvent' in window;
7038var documentMode = null;
7039
7040if (canUseDOM && 'documentMode' in document) {
7041 documentMode = document.documentMode;
7042} // Webkit offers a very useful `textInput` event that can be used to
7043// directly represent `beforeInput`. The IE `textinput` event is not as
7044// useful, so we don't use it.
7045
7046
7047var canUseTextInputEvent = canUseDOM && 'TextEvent' in window && !documentMode; // In IE9+, we have access to composition events, but the data supplied
7048// by the native compositionend event may be incorrect. Japanese ideographic
7049// spaces, for instance (\u3000) are not recorded correctly.
7050
7051var useFallbackCompositionData = canUseDOM && (!canUseCompositionEvent || documentMode && documentMode > 8 && documentMode <= 11);
7052var SPACEBAR_CODE = 32;
7053var SPACEBAR_CHAR = String.fromCharCode(SPACEBAR_CODE);
7054
7055function registerEvents$3() {
7056 registerTwoPhaseEvent('onBeforeInput', ['compositionend', 'keypress', 'textInput', 'paste']);
7057 registerTwoPhaseEvent('onCompositionEnd', ['compositionend', 'focusout', 'keydown', 'keypress', 'keyup', 'mousedown']);
7058 registerTwoPhaseEvent('onCompositionStart', ['compositionstart', 'focusout', 'keydown', 'keypress', 'keyup', 'mousedown']);
7059 registerTwoPhaseEvent('onCompositionUpdate', ['compositionupdate', 'focusout', 'keydown', 'keypress', 'keyup', 'mousedown']);
7060} // Track whether we've ever handled a keypress on the space key.
7061
7062
7063var hasSpaceKeypress = false;
7064/**
7065 * Return whether a native keypress event is assumed to be a command.
7066 * This is required because Firefox fires `keypress` events for key commands
7067 * (cut, copy, select-all, etc.) even though no character is inserted.
7068 */
7069
7070function isKeypressCommand(nativeEvent) {
7071 return (nativeEvent.ctrlKey || nativeEvent.altKey || nativeEvent.metaKey) && // ctrlKey && altKey is equivalent to AltGr, and is not a command.
7072 !(nativeEvent.ctrlKey && nativeEvent.altKey);
7073}
7074/**
7075 * Translate native top level events into event types.
7076 */
7077
7078
7079function getCompositionEventType(domEventName) {
7080 switch (domEventName) {
7081 case 'compositionstart':
7082 return 'onCompositionStart';
7083
7084 case 'compositionend':
7085 return 'onCompositionEnd';
7086
7087 case 'compositionupdate':
7088 return 'onCompositionUpdate';
7089 }
7090}
7091/**
7092 * Does our fallback best-guess model think this event signifies that
7093 * composition has begun?
7094 */
7095
7096
7097function isFallbackCompositionStart(domEventName, nativeEvent) {
7098 return domEventName === 'keydown' && nativeEvent.keyCode === START_KEYCODE;
7099}
7100/**
7101 * Does our fallback mode think that this event is the end of composition?
7102 */
7103
7104
7105function isFallbackCompositionEnd(domEventName, nativeEvent) {
7106 switch (domEventName) {
7107 case 'keyup':
7108 // Command keys insert or clear IME input.
7109 return END_KEYCODES.indexOf(nativeEvent.keyCode) !== -1;
7110
7111 case 'keydown':
7112 // Expect IME keyCode on each keydown. If we get any other
7113 // code we must have exited earlier.
7114 return nativeEvent.keyCode !== START_KEYCODE;
7115
7116 case 'keypress':
7117 case 'mousedown':
7118 case 'focusout':
7119 // Events are not possible without cancelling IME.
7120 return true;
7121
7122 default:
7123 return false;
7124 }
7125}
7126/**
7127 * Google Input Tools provides composition data via a CustomEvent,
7128 * with the `data` property populated in the `detail` object. If this
7129 * is available on the event object, use it. If not, this is a plain
7130 * composition event and we have nothing special to extract.
7131 *
7132 * @param {object} nativeEvent
7133 * @return {?string}
7134 */
7135
7136
7137function getDataFromCustomEvent(nativeEvent) {
7138 var detail = nativeEvent.detail;
7139
7140 if (typeof detail === 'object' && 'data' in detail) {
7141 return detail.data;
7142 }
7143
7144 return null;
7145}
7146/**
7147 * Check if a composition event was triggered by Korean IME.
7148 * Our fallback mode does not work well with IE's Korean IME,
7149 * so just use native composition events when Korean IME is used.
7150 * Although CompositionEvent.locale property is deprecated,
7151 * it is available in IE, where our fallback mode is enabled.
7152 *
7153 * @param {object} nativeEvent
7154 * @return {boolean}
7155 */
7156
7157
7158function isUsingKoreanIME(nativeEvent) {
7159 return nativeEvent.locale === 'ko';
7160} // Track the current IME composition status, if any.
7161
7162
7163var isComposing = false;
7164/**
7165 * @return {?object} A SyntheticCompositionEvent.
7166 */
7167
7168function extractCompositionEvent(dispatchQueue, domEventName, targetInst, nativeEvent, nativeEventTarget) {
7169 var eventType;
7170 var fallbackData;
7171
7172 if (canUseCompositionEvent) {
7173 eventType = getCompositionEventType(domEventName);
7174 } else if (!isComposing) {
7175 if (isFallbackCompositionStart(domEventName, nativeEvent)) {
7176 eventType = 'onCompositionStart';
7177 }
7178 } else if (isFallbackCompositionEnd(domEventName, nativeEvent)) {
7179 eventType = 'onCompositionEnd';
7180 }
7181
7182 if (!eventType) {
7183 return null;
7184 }
7185
7186 if (useFallbackCompositionData && !isUsingKoreanIME(nativeEvent)) {
7187 // The current composition is stored statically and must not be
7188 // overwritten while composition continues.
7189 if (!isComposing && eventType === 'onCompositionStart') {
7190 isComposing = initialize(nativeEventTarget);
7191 } else if (eventType === 'onCompositionEnd') {
7192 if (isComposing) {
7193 fallbackData = getData();
7194 }
7195 }
7196 }
7197
7198 var listeners = accumulateTwoPhaseListeners(targetInst, eventType);
7199
7200 if (listeners.length > 0) {
7201 var event = new SyntheticCompositionEvent(eventType, domEventName, null, nativeEvent, nativeEventTarget);
7202 dispatchQueue.push({
7203 event: event,
7204 listeners: listeners
7205 });
7206
7207 if (fallbackData) {
7208 // Inject data generated from fallback path into the synthetic event.
7209 // This matches the property of native CompositionEventInterface.
7210 // $FlowFixMe[incompatible-use]
7211 event.data = fallbackData;
7212 } else {
7213 var customData = getDataFromCustomEvent(nativeEvent);
7214
7215 if (customData !== null) {
7216 // $FlowFixMe[incompatible-use]
7217 event.data = customData;
7218 }
7219 }
7220 }
7221}
7222
7223function getNativeBeforeInputChars(domEventName, nativeEvent) {
7224 switch (domEventName) {
7225 case 'compositionend':
7226 return getDataFromCustomEvent(nativeEvent);
7227
7228 case 'keypress':
7229 /**
7230 * If native `textInput` events are available, our goal is to make
7231 * use of them. However, there is a special case: the spacebar key.
7232 * In Webkit, preventing default on a spacebar `textInput` event
7233 * cancels character insertion, but it *also* causes the browser
7234 * to fall back to its default spacebar behavior of scrolling the
7235 * page.
7236 *
7237 * Tracking at:
7238 * https://code.google.com/p/chromium/issues/detail?id=355103
7239 *
7240 * To avoid this issue, use the keypress event as if no `textInput`
7241 * event is available.
7242 */
7243 var which = nativeEvent.which;
7244
7245 if (which !== SPACEBAR_CODE) {
7246 return null;
7247 }
7248
7249 hasSpaceKeypress = true;
7250 return SPACEBAR_CHAR;
7251
7252 case 'textInput':
7253 // Record the characters to be added to the DOM.
7254 var chars = nativeEvent.data; // If it's a spacebar character, assume that we have already handled
7255 // it at the keypress level and bail immediately. Android Chrome
7256 // doesn't give us keycodes, so we need to ignore it.
7257
7258 if (chars === SPACEBAR_CHAR && hasSpaceKeypress) {
7259 return null;
7260 }
7261
7262 return chars;
7263
7264 default:
7265 // For other native event types, do nothing.
7266 return null;
7267 }
7268}
7269/**
7270 * For browsers that do not provide the `textInput` event, extract the
7271 * appropriate string to use for SyntheticInputEvent.
7272 */
7273
7274
7275function getFallbackBeforeInputChars(domEventName, nativeEvent) {
7276 // If we are currently composing (IME) and using a fallback to do so,
7277 // try to extract the composed characters from the fallback object.
7278 // If composition event is available, we extract a string only at
7279 // compositionevent, otherwise extract it at fallback events.
7280 if (isComposing) {
7281 if (domEventName === 'compositionend' || !canUseCompositionEvent && isFallbackCompositionEnd(domEventName, nativeEvent)) {
7282 var chars = getData();
7283 reset();
7284 isComposing = false;
7285 return chars;
7286 }
7287
7288 return null;
7289 }
7290
7291 switch (domEventName) {
7292 case 'paste':
7293 // If a paste event occurs after a keypress, throw out the input
7294 // chars. Paste events should not lead to BeforeInput events.
7295 return null;
7296
7297 case 'keypress':
7298 /**
7299 * As of v27, Firefox may fire keypress events even when no character
7300 * will be inserted. A few possibilities:
7301 *
7302 * - `which` is `0`. Arrow keys, Esc key, etc.
7303 *
7304 * - `which` is the pressed key code, but no char is available.
7305 * Ex: 'AltGr + d` in Polish. There is no modified character for
7306 * this key combination and no character is inserted into the
7307 * document, but FF fires the keypress for char code `100` anyway.
7308 * No `input` event will occur.
7309 *
7310 * - `which` is the pressed key code, but a command combination is
7311 * being used. Ex: `Cmd+C`. No character is inserted, and no
7312 * `input` event will occur.
7313 */
7314 if (!isKeypressCommand(nativeEvent)) {
7315 // IE fires the `keypress` event when a user types an emoji via
7316 // Touch keyboard of Windows. In such a case, the `char` property
7317 // holds an emoji character like `\uD83D\uDE0A`. Because its length
7318 // is 2, the property `which` does not represent an emoji correctly.
7319 // In such a case, we directly return the `char` property instead of
7320 // using `which`.
7321 if (nativeEvent.char && nativeEvent.char.length > 1) {
7322 return nativeEvent.char;
7323 } else if (nativeEvent.which) {
7324 return String.fromCharCode(nativeEvent.which);
7325 }
7326 }
7327
7328 return null;
7329
7330 case 'compositionend':
7331 return useFallbackCompositionData && !isUsingKoreanIME(nativeEvent) ? null : nativeEvent.data;
7332
7333 default:
7334 return null;
7335 }
7336}
7337/**
7338 * Extract a SyntheticInputEvent for `beforeInput`, based on either native
7339 * `textInput` or fallback behavior.
7340 *
7341 * @return {?object} A SyntheticInputEvent.
7342 */
7343
7344
7345function extractBeforeInputEvent(dispatchQueue, domEventName, targetInst, nativeEvent, nativeEventTarget) {
7346 var chars;
7347
7348 if (canUseTextInputEvent) {
7349 chars = getNativeBeforeInputChars(domEventName, nativeEvent);
7350 } else {
7351 chars = getFallbackBeforeInputChars(domEventName, nativeEvent);
7352 } // If no characters are being inserted, no BeforeInput event should
7353 // be fired.
7354
7355
7356 if (!chars) {
7357 return null;
7358 }
7359
7360 var listeners = accumulateTwoPhaseListeners(targetInst, 'onBeforeInput');
7361
7362 if (listeners.length > 0) {
7363 var event = new SyntheticInputEvent('onBeforeInput', 'beforeinput', null, nativeEvent, nativeEventTarget);
7364 dispatchQueue.push({
7365 event: event,
7366 listeners: listeners
7367 }); // $FlowFixMe[incompatible-use]
7368
7369 event.data = chars;
7370 }
7371}
7372/**
7373 * Create an `onBeforeInput` event to match
7374 * http://www.w3.org/TR/2013/WD-DOM-Level-3-Events-20131105/#events-inputevents.
7375 *
7376 * This event plugin is based on the native `textInput` event
7377 * available in Chrome, Safari, Opera, and IE. This event fires after
7378 * `onKeyPress` and `onCompositionEnd`, but before `onInput`.
7379 *
7380 * `beforeInput` is spec'd but not implemented in any browsers, and
7381 * the `input` event does not provide any useful information about what has
7382 * actually been added, contrary to the spec. Thus, `textInput` is the best
7383 * available event to identify the characters that have actually been inserted
7384 * into the target node.
7385 *
7386 * This plugin is also responsible for emitting `composition` events, thus
7387 * allowing us to share composition fallback code for both `beforeInput` and
7388 * `composition` event types.
7389 */
7390
7391
7392function extractEvents$6(dispatchQueue, domEventName, targetInst, nativeEvent, nativeEventTarget, eventSystemFlags, targetContainer) {
7393 extractCompositionEvent(dispatchQueue, domEventName, targetInst, nativeEvent, nativeEventTarget);
7394 extractBeforeInputEvent(dispatchQueue, domEventName, targetInst, nativeEvent, nativeEventTarget);
7395}
7396
7397/**
7398 * @see http://www.whatwg.org/specs/web-apps/current-work/multipage/the-input-element.html#input-type-attr-summary
7399 */
7400var supportedInputTypes = {
7401 color: true,
7402 date: true,
7403 datetime: true,
7404 'datetime-local': true,
7405 email: true,
7406 month: true,
7407 number: true,
7408 password: true,
7409 range: true,
7410 search: true,
7411 tel: true,
7412 text: true,
7413 time: true,
7414 url: true,
7415 week: true
7416};
7417
7418function isTextInputElement(elem) {
7419 var nodeName = elem && elem.nodeName && elem.nodeName.toLowerCase();
7420
7421 if (nodeName === 'input') {
7422 return !!supportedInputTypes[elem.type];
7423 }
7424
7425 if (nodeName === 'textarea') {
7426 return true;
7427 }
7428
7429 return false;
7430}
7431
7432/**
7433 * Checks if an event is supported in the current execution environment.
7434 *
7435 * NOTE: This will not work correctly for non-generic events such as `change`,
7436 * `reset`, `load`, `error`, and `select`.
7437 *
7438 * Borrows from Modernizr.
7439 *
7440 * @param {string} eventNameSuffix Event name, e.g. "click".
7441 * @return {boolean} True if the event is supported.
7442 * @internal
7443 * @license Modernizr 3.0.0pre (Custom Build) | MIT
7444 */
7445
7446function isEventSupported(eventNameSuffix) {
7447 if (!canUseDOM) {
7448 return false;
7449 }
7450
7451 var eventName = 'on' + eventNameSuffix;
7452 var isSupported = (eventName in document);
7453
7454 if (!isSupported) {
7455 var element = document.createElement('div');
7456 element.setAttribute(eventName, 'return;');
7457 isSupported = typeof element[eventName] === 'function';
7458 }
7459
7460 return isSupported;
7461}
7462
7463function registerEvents$2() {
7464 registerTwoPhaseEvent('onChange', ['change', 'click', 'focusin', 'focusout', 'input', 'keydown', 'keyup', 'selectionchange']);
7465}
7466
7467function createAndAccumulateChangeEvent(dispatchQueue, inst, nativeEvent, target) {
7468 // Flag this event loop as needing state restore.
7469 enqueueStateRestore(target);
7470 var listeners = accumulateTwoPhaseListeners(inst, 'onChange');
7471
7472 if (listeners.length > 0) {
7473 var event = new SyntheticEvent('onChange', 'change', null, nativeEvent, target);
7474 dispatchQueue.push({
7475 event: event,
7476 listeners: listeners
7477 });
7478 }
7479}
7480/**
7481 * For IE shims
7482 */
7483
7484
7485var activeElement$1 = null;
7486var activeElementInst$1 = null;
7487/**
7488 * SECTION: handle `change` event
7489 */
7490
7491function shouldUseChangeEvent(elem) {
7492 var nodeName = elem.nodeName && elem.nodeName.toLowerCase();
7493 return nodeName === 'select' || nodeName === 'input' && elem.type === 'file';
7494}
7495
7496function manualDispatchChangeEvent(nativeEvent) {
7497 var dispatchQueue = [];
7498 createAndAccumulateChangeEvent(dispatchQueue, activeElementInst$1, nativeEvent, getEventTarget(nativeEvent)); // If change and propertychange bubbled, we'd just bind to it like all the
7499 // other events and have it go through ReactBrowserEventEmitter. Since it
7500 // doesn't, we manually listen for the events and so we have to enqueue and
7501 // process the abstract event manually.
7502 //
7503 // Batching is necessary here in order to ensure that all event handlers run
7504 // before the next rerender (including event handlers attached to ancestor
7505 // elements instead of directly on the input). Without this, controlled
7506 // components don't work properly in conjunction with event bubbling because
7507 // the component is rerendered and the value reverted before all the event
7508 // handlers can run. See https://github.com/facebook/react/issues/708.
7509
7510 batchedUpdates$1(runEventInBatch, dispatchQueue);
7511}
7512
7513function runEventInBatch(dispatchQueue) {
7514 processDispatchQueue(dispatchQueue, 0);
7515}
7516
7517function getInstIfValueChanged(targetInst) {
7518 var targetNode = getNodeFromInstance(targetInst);
7519
7520 if (updateValueIfChanged(targetNode)) {
7521 return targetInst;
7522 }
7523}
7524
7525function getTargetInstForChangeEvent(domEventName, targetInst) {
7526 if (domEventName === 'change') {
7527 return targetInst;
7528 }
7529}
7530/**
7531 * SECTION: handle `input` event
7532 */
7533
7534
7535var isInputEventSupported = false;
7536
7537if (canUseDOM) {
7538 // IE9 claims to support the input event but fails to trigger it when
7539 // deleting text, so we ignore its input events.
7540 isInputEventSupported = isEventSupported('input') && (!document.documentMode || document.documentMode > 9);
7541}
7542/**
7543 * (For IE <=9) Starts tracking propertychange events on the passed-in element
7544 * and override the value property so that we can distinguish user events from
7545 * value changes in JS.
7546 */
7547
7548
7549function startWatchingForValueChange(target, targetInst) {
7550 activeElement$1 = target;
7551 activeElementInst$1 = targetInst;
7552 activeElement$1.attachEvent('onpropertychange', handlePropertyChange);
7553}
7554/**
7555 * (For IE <=9) Removes the event listeners from the currently-tracked element,
7556 * if any exists.
7557 */
7558
7559
7560function stopWatchingForValueChange() {
7561 if (!activeElement$1) {
7562 return;
7563 }
7564
7565 activeElement$1.detachEvent('onpropertychange', handlePropertyChange);
7566 activeElement$1 = null;
7567 activeElementInst$1 = null;
7568}
7569/**
7570 * (For IE <=9) Handles a propertychange event, sending a `change` event if
7571 * the value of the active element has changed.
7572 */
7573// $FlowFixMe[missing-local-annot]
7574
7575
7576function handlePropertyChange(nativeEvent) {
7577 if (nativeEvent.propertyName !== 'value') {
7578 return;
7579 }
7580
7581 if (getInstIfValueChanged(activeElementInst$1)) {
7582 manualDispatchChangeEvent(nativeEvent);
7583 }
7584}
7585
7586function handleEventsForInputEventPolyfill(domEventName, target, targetInst) {
7587 if (domEventName === 'focusin') {
7588 // In IE9, propertychange fires for most input events but is buggy and
7589 // doesn't fire when text is deleted, but conveniently, selectionchange
7590 // appears to fire in all of the remaining cases so we catch those and
7591 // forward the event if the value has changed
7592 // In either case, we don't want to call the event handler if the value
7593 // is changed from JS so we redefine a setter for `.value` that updates
7594 // our activeElementValue variable, allowing us to ignore those changes
7595 //
7596 // stopWatching() should be a noop here but we call it just in case we
7597 // missed a blur event somehow.
7598 stopWatchingForValueChange();
7599 startWatchingForValueChange(target, targetInst);
7600 } else if (domEventName === 'focusout') {
7601 stopWatchingForValueChange();
7602 }
7603} // For IE8 and IE9.
7604
7605
7606function getTargetInstForInputEventPolyfill(domEventName, targetInst) {
7607 if (domEventName === 'selectionchange' || domEventName === 'keyup' || domEventName === 'keydown') {
7608 // On the selectionchange event, the target is just document which isn't
7609 // helpful for us so just check activeElement instead.
7610 //
7611 // 99% of the time, keydown and keyup aren't necessary. IE8 fails to fire
7612 // propertychange on the first input event after setting `value` from a
7613 // script and fires only keydown, keypress, keyup. Catching keyup usually
7614 // gets it and catching keydown lets us fire an event for the first
7615 // keystroke if user does a key repeat (it'll be a little delayed: right
7616 // before the second keystroke). Other input methods (e.g., paste) seem to
7617 // fire selectionchange normally.
7618 return getInstIfValueChanged(activeElementInst$1);
7619 }
7620}
7621/**
7622 * SECTION: handle `click` event
7623 */
7624
7625
7626function shouldUseClickEvent(elem) {
7627 // Use the `click` event to detect changes to checkbox and radio inputs.
7628 // This approach works across all browsers, whereas `change` does not fire
7629 // until `blur` in IE8.
7630 var nodeName = elem.nodeName;
7631 return nodeName && nodeName.toLowerCase() === 'input' && (elem.type === 'checkbox' || elem.type === 'radio');
7632}
7633
7634function getTargetInstForClickEvent(domEventName, targetInst) {
7635 if (domEventName === 'click') {
7636 return getInstIfValueChanged(targetInst);
7637 }
7638}
7639
7640function getTargetInstForInputOrChangeEvent(domEventName, targetInst) {
7641 if (domEventName === 'input' || domEventName === 'change') {
7642 return getInstIfValueChanged(targetInst);
7643 }
7644}
7645
7646function handleControlledInputBlur(node, props) {
7647 if (node.type !== 'number') {
7648 return;
7649 }
7650
7651 {
7652 var isControlled = props.value != null;
7653
7654 if (isControlled) {
7655 // If controlled, assign the value attribute to the current value on blur
7656 setDefaultValue(node, 'number', node.value);
7657 }
7658 }
7659}
7660/**
7661 * This plugin creates an `onChange` event that normalizes change events
7662 * across form elements. This event fires at a time when it's possible to
7663 * change the element's value without seeing a flicker.
7664 *
7665 * Supported elements are:
7666 * - input (see `isTextInputElement`)
7667 * - textarea
7668 * - select
7669 */
7670
7671
7672function extractEvents$5(dispatchQueue, domEventName, targetInst, nativeEvent, nativeEventTarget, eventSystemFlags, targetContainer) {
7673 var targetNode = targetInst ? getNodeFromInstance(targetInst) : window;
7674 var getTargetInstFunc, handleEventFunc;
7675
7676 if (shouldUseChangeEvent(targetNode)) {
7677 getTargetInstFunc = getTargetInstForChangeEvent;
7678 } else if (isTextInputElement(targetNode)) {
7679 if (isInputEventSupported) {
7680 getTargetInstFunc = getTargetInstForInputOrChangeEvent;
7681 } else {
7682 getTargetInstFunc = getTargetInstForInputEventPolyfill;
7683 handleEventFunc = handleEventsForInputEventPolyfill;
7684 }
7685 } else if (shouldUseClickEvent(targetNode)) {
7686 getTargetInstFunc = getTargetInstForClickEvent;
7687 } else if (targetInst && isCustomElement(targetInst.elementType)) {
7688 getTargetInstFunc = getTargetInstForChangeEvent;
7689 }
7690
7691 if (getTargetInstFunc) {
7692 var inst = getTargetInstFunc(domEventName, targetInst);
7693
7694 if (inst) {
7695 createAndAccumulateChangeEvent(dispatchQueue, inst, nativeEvent, nativeEventTarget);
7696 return;
7697 }
7698 }
7699
7700 if (handleEventFunc) {
7701 handleEventFunc(domEventName, targetNode, targetInst);
7702 } // When blurring, set the value attribute for number inputs
7703
7704
7705 if (domEventName === 'focusout' && targetInst) {
7706 // These props aren't necessarily the most current but we warn for changing
7707 // between controlled and uncontrolled, so it doesn't matter and the previous
7708 // code was also broken for changes.
7709 var props = targetInst.memoizedProps;
7710 handleControlledInputBlur(targetNode, props);
7711 }
7712}
7713
7714function registerEvents$1() {
7715 registerDirectEvent('onMouseEnter', ['mouseout', 'mouseover']);
7716 registerDirectEvent('onMouseLeave', ['mouseout', 'mouseover']);
7717 registerDirectEvent('onPointerEnter', ['pointerout', 'pointerover']);
7718 registerDirectEvent('onPointerLeave', ['pointerout', 'pointerover']);
7719}
7720/**
7721 * For almost every interaction we care about, there will be both a top-level
7722 * `mouseover` and `mouseout` event that occurs. Only use `mouseout` so that
7723 * we do not extract duplicate events. However, moving the mouse into the
7724 * browser from outside will not fire a `mouseout` event. In this case, we use
7725 * the `mouseover` top-level event.
7726 */
7727
7728
7729function extractEvents$4(dispatchQueue, domEventName, targetInst, nativeEvent, nativeEventTarget, eventSystemFlags, targetContainer) {
7730 var isOverEvent = domEventName === 'mouseover' || domEventName === 'pointerover';
7731 var isOutEvent = domEventName === 'mouseout' || domEventName === 'pointerout';
7732
7733 if (isOverEvent && !isReplayingEvent(nativeEvent)) {
7734 // If this is an over event with a target, we might have already dispatched
7735 // the event in the out event of the other target. If this is replayed,
7736 // then it's because we couldn't dispatch against this target previously
7737 // so we have to do it now instead.
7738 var related = nativeEvent.relatedTarget || nativeEvent.fromElement;
7739
7740 if (related) {
7741 // If the related node is managed by React, we can assume that we have
7742 // already dispatched the corresponding events during its mouseout.
7743 if (getClosestInstanceFromNode(related) || isContainerMarkedAsRoot(related)) {
7744 return;
7745 }
7746 }
7747 }
7748
7749 if (!isOutEvent && !isOverEvent) {
7750 // Must not be a mouse or pointer in or out - ignoring.
7751 return;
7752 }
7753
7754 var win; // TODO: why is this nullable in the types but we read from it?
7755
7756 if (nativeEventTarget.window === nativeEventTarget) {
7757 // `nativeEventTarget` is probably a window object.
7758 win = nativeEventTarget;
7759 } else {
7760 // TODO: Figure out why `ownerDocument` is sometimes undefined in IE8.
7761 var doc = nativeEventTarget.ownerDocument;
7762
7763 if (doc) {
7764 win = doc.defaultView || doc.parentWindow;
7765 } else {
7766 win = window;
7767 }
7768 }
7769
7770 var from;
7771 var to;
7772
7773 if (isOutEvent) {
7774 var _related = nativeEvent.relatedTarget || nativeEvent.toElement;
7775
7776 from = targetInst;
7777 to = _related ? getClosestInstanceFromNode(_related) : null;
7778
7779 if (to !== null) {
7780 var nearestMounted = getNearestMountedFiber(to);
7781 var tag = to.tag;
7782
7783 if (to !== nearestMounted || tag !== HostComponent && tag !== HostSingleton && tag !== HostText) {
7784 to = null;
7785 }
7786 }
7787 } else {
7788 // Moving to a node from outside the window.
7789 from = null;
7790 to = targetInst;
7791 }
7792
7793 if (from === to) {
7794 // Nothing pertains to our managed components.
7795 return;
7796 }
7797
7798 var SyntheticEventCtor = SyntheticMouseEvent;
7799 var leaveEventType = 'onMouseLeave';
7800 var enterEventType = 'onMouseEnter';
7801 var eventTypePrefix = 'mouse';
7802
7803 if (domEventName === 'pointerout' || domEventName === 'pointerover') {
7804 SyntheticEventCtor = SyntheticPointerEvent;
7805 leaveEventType = 'onPointerLeave';
7806 enterEventType = 'onPointerEnter';
7807 eventTypePrefix = 'pointer';
7808 }
7809
7810 var fromNode = from == null ? win : getNodeFromInstance(from);
7811 var toNode = to == null ? win : getNodeFromInstance(to);
7812 var leave = new SyntheticEventCtor(leaveEventType, eventTypePrefix + 'leave', from, nativeEvent, nativeEventTarget);
7813 leave.target = fromNode;
7814 leave.relatedTarget = toNode;
7815 var enter = null; // We should only process this nativeEvent if we are processing
7816 // the first ancestor. Next time, we will ignore the event.
7817
7818 var nativeTargetInst = getClosestInstanceFromNode(nativeEventTarget);
7819
7820 if (nativeTargetInst === targetInst) {
7821 var enterEvent = new SyntheticEventCtor(enterEventType, eventTypePrefix + 'enter', to, nativeEvent, nativeEventTarget);
7822 enterEvent.target = toNode;
7823 enterEvent.relatedTarget = fromNode;
7824 enter = enterEvent;
7825 }
7826
7827 accumulateEnterLeaveTwoPhaseListeners(dispatchQueue, leave, enter, from, to);
7828}
7829
7830/**
7831 * inlined Object.is polyfill to avoid requiring consumers ship their own
7832 * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is
7833 */
7834function is(x, y) {
7835 return x === y && (x !== 0 || 1 / x === 1 / y) || x !== x && y !== y // eslint-disable-line no-self-compare
7836 ;
7837}
7838
7839var objectIs = // $FlowFixMe[method-unbinding]
7840typeof Object.is === 'function' ? Object.is : is;
7841
7842/**
7843 * Performs equality by iterating through keys on an object and returning false
7844 * when any key has values which are not strictly equal between the arguments.
7845 * Returns true when the values of all keys are strictly equal.
7846 */
7847
7848function shallowEqual(objA, objB) {
7849 if (objectIs(objA, objB)) {
7850 return true;
7851 }
7852
7853 if (typeof objA !== 'object' || objA === null || typeof objB !== 'object' || objB === null) {
7854 return false;
7855 }
7856
7857 var keysA = Object.keys(objA);
7858 var keysB = Object.keys(objB);
7859
7860 if (keysA.length !== keysB.length) {
7861 return false;
7862 } // Test for A's keys different from B.
7863
7864
7865 for (var i = 0; i < keysA.length; i++) {
7866 var currentKey = keysA[i];
7867
7868 if (!hasOwnProperty.call(objB, currentKey) || // $FlowFixMe[incompatible-use] lost refinement of `objB`
7869 !objectIs(objA[currentKey], objB[currentKey])) {
7870 return false;
7871 }
7872 }
7873
7874 return true;
7875}
7876
7877/**
7878 * Given any node return the first leaf node without children.
7879 *
7880 * @param {DOMElement|DOMTextNode} node
7881 * @return {DOMElement|DOMTextNode}
7882 */
7883
7884function getLeafNode(node) {
7885 while (node && node.firstChild) {
7886 node = node.firstChild;
7887 }
7888
7889 return node;
7890}
7891/**
7892 * Get the next sibling within a container. This will walk up the
7893 * DOM if a node's siblings have been exhausted.
7894 *
7895 * @param {DOMElement|DOMTextNode} node
7896 * @return {?DOMElement|DOMTextNode}
7897 */
7898
7899
7900function getSiblingNode(node) {
7901 while (node) {
7902 if (node.nextSibling) {
7903 return node.nextSibling;
7904 }
7905
7906 node = node.parentNode;
7907 }
7908}
7909/**
7910 * Get object describing the nodes which contain characters at offset.
7911 *
7912 * @param {DOMElement|DOMTextNode} root
7913 * @param {number} offset
7914 * @return {?object}
7915 */
7916
7917
7918function getNodeForCharacterOffset(root, offset) {
7919 var node = getLeafNode(root);
7920 var nodeStart = 0;
7921 var nodeEnd = 0;
7922
7923 while (node) {
7924 if (node.nodeType === TEXT_NODE) {
7925 nodeEnd = nodeStart + node.textContent.length;
7926
7927 if (nodeStart <= offset && nodeEnd >= offset) {
7928 return {
7929 node: node,
7930 offset: offset - nodeStart
7931 };
7932 }
7933
7934 nodeStart = nodeEnd;
7935 }
7936
7937 node = getLeafNode(getSiblingNode(node));
7938 }
7939}
7940
7941/**
7942 * @param {DOMElement} outerNode
7943 * @return {?object}
7944 */
7945
7946function getOffsets(outerNode) {
7947 var ownerDocument = outerNode.ownerDocument;
7948 var win = ownerDocument && ownerDocument.defaultView || window;
7949 var selection = win.getSelection && win.getSelection();
7950
7951 if (!selection || selection.rangeCount === 0) {
7952 return null;
7953 }
7954
7955 var anchorNode = selection.anchorNode,
7956 anchorOffset = selection.anchorOffset,
7957 focusNode = selection.focusNode,
7958 focusOffset = selection.focusOffset; // In Firefox, anchorNode and focusNode can be "anonymous divs", e.g. the
7959 // up/down buttons on an <input type="number">. Anonymous divs do not seem to
7960 // expose properties, triggering a "Permission denied error" if any of its
7961 // properties are accessed. The only seemingly possible way to avoid erroring
7962 // is to access a property that typically works for non-anonymous divs and
7963 // catch any error that may otherwise arise. See
7964 // https://bugzilla.mozilla.org/show_bug.cgi?id=208427
7965
7966 try {
7967 /* eslint-disable ft-flow/no-unused-expressions */
7968 anchorNode.nodeType;
7969 focusNode.nodeType;
7970 /* eslint-enable ft-flow/no-unused-expressions */
7971 } catch (e) {
7972 return null;
7973 }
7974
7975 return getModernOffsetsFromPoints(outerNode, anchorNode, anchorOffset, focusNode, focusOffset);
7976}
7977/**
7978 * Returns {start, end} where `start` is the character/codepoint index of
7979 * (anchorNode, anchorOffset) within the textContent of `outerNode`, and
7980 * `end` is the index of (focusNode, focusOffset).
7981 *
7982 * Returns null if you pass in garbage input but we should probably just crash.
7983 *
7984 * Exported only for testing.
7985 */
7986
7987function getModernOffsetsFromPoints(outerNode, anchorNode, anchorOffset, focusNode, focusOffset) {
7988 var length = 0;
7989 var start = -1;
7990 var end = -1;
7991 var indexWithinAnchor = 0;
7992 var indexWithinFocus = 0;
7993 var node = outerNode;
7994 var parentNode = null;
7995
7996 outer: while (true) {
7997 var next = null;
7998
7999 while (true) {
8000 if (node === anchorNode && (anchorOffset === 0 || node.nodeType === TEXT_NODE)) {
8001 start = length + anchorOffset;
8002 }
8003
8004 if (node === focusNode && (focusOffset === 0 || node.nodeType === TEXT_NODE)) {
8005 end = length + focusOffset;
8006 }
8007
8008 if (node.nodeType === TEXT_NODE) {
8009 length += node.nodeValue.length;
8010 }
8011
8012 if ((next = node.firstChild) === null) {
8013 break;
8014 } // Moving from `node` to its first child `next`.
8015
8016
8017 parentNode = node;
8018 node = next;
8019 }
8020
8021 while (true) {
8022 if (node === outerNode) {
8023 // If `outerNode` has children, this is always the second time visiting
8024 // it. If it has no children, this is still the first loop, and the only
8025 // valid selection is anchorNode and focusNode both equal to this node
8026 // and both offsets 0, in which case we will have handled above.
8027 break outer;
8028 }
8029
8030 if (parentNode === anchorNode && ++indexWithinAnchor === anchorOffset) {
8031 start = length;
8032 }
8033
8034 if (parentNode === focusNode && ++indexWithinFocus === focusOffset) {
8035 end = length;
8036 }
8037
8038 if ((next = node.nextSibling) !== null) {
8039 break;
8040 }
8041
8042 node = parentNode;
8043 parentNode = node.parentNode;
8044 } // Moving from `node` to its next sibling `next`.
8045
8046
8047 node = next;
8048 }
8049
8050 if (start === -1 || end === -1) {
8051 // This should never happen. (Would happen if the anchor/focus nodes aren't
8052 // actually inside the passed-in node.)
8053 return null;
8054 }
8055
8056 return {
8057 start: start,
8058 end: end
8059 };
8060}
8061/**
8062 * In modern non-IE browsers, we can support both forward and backward
8063 * selections.
8064 *
8065 * Note: IE10+ supports the Selection object, but it does not support
8066 * the `extend` method, which means that even in modern IE, it's not possible
8067 * to programmatically create a backward selection. Thus, for all IE
8068 * versions, we use the old IE API to create our selections.
8069 *
8070 * @param {DOMElement|DOMTextNode} node
8071 * @param {object} offsets
8072 */
8073
8074function setOffsets(node, offsets) {
8075 var doc = node.ownerDocument || document;
8076 var win = doc && doc.defaultView || window; // Edge fails with "Object expected" in some scenarios.
8077 // (For instance: TinyMCE editor used in a list component that supports pasting to add more,
8078 // fails when pasting 100+ items)
8079
8080 if (!win.getSelection) {
8081 return;
8082 }
8083
8084 var selection = win.getSelection();
8085 var length = node.textContent.length;
8086 var start = Math.min(offsets.start, length);
8087 var end = offsets.end === undefined ? start : Math.min(offsets.end, length); // IE 11 uses modern selection, but doesn't support the extend method.
8088 // Flip backward selections, so we can set with a single range.
8089
8090 if (!selection.extend && start > end) {
8091 var temp = end;
8092 end = start;
8093 start = temp;
8094 }
8095
8096 var startMarker = getNodeForCharacterOffset(node, start);
8097 var endMarker = getNodeForCharacterOffset(node, end);
8098
8099 if (startMarker && endMarker) {
8100 if (selection.rangeCount === 1 && selection.anchorNode === startMarker.node && selection.anchorOffset === startMarker.offset && selection.focusNode === endMarker.node && selection.focusOffset === endMarker.offset) {
8101 return;
8102 }
8103
8104 var range = doc.createRange();
8105 range.setStart(startMarker.node, startMarker.offset);
8106 selection.removeAllRanges();
8107
8108 if (start > end) {
8109 selection.addRange(range);
8110 selection.extend(endMarker.node, endMarker.offset);
8111 } else {
8112 range.setEnd(endMarker.node, endMarker.offset);
8113 selection.addRange(range);
8114 }
8115 }
8116}
8117
8118function isTextNode(node) {
8119 return node && node.nodeType === TEXT_NODE;
8120}
8121
8122function containsNode(outerNode, innerNode) {
8123 if (!outerNode || !innerNode) {
8124 return false;
8125 } else if (outerNode === innerNode) {
8126 return true;
8127 } else if (isTextNode(outerNode)) {
8128 return false;
8129 } else if (isTextNode(innerNode)) {
8130 return containsNode(outerNode, innerNode.parentNode);
8131 } else if ('contains' in outerNode) {
8132 return outerNode.contains(innerNode);
8133 } else if (outerNode.compareDocumentPosition) {
8134 return !!(outerNode.compareDocumentPosition(innerNode) & 16);
8135 } else {
8136 return false;
8137 }
8138}
8139
8140function isInDocument(node) {
8141 return node && node.ownerDocument && containsNode(node.ownerDocument.documentElement, node);
8142}
8143
8144function isSameOriginFrame(iframe) {
8145 try {
8146 // Accessing the contentDocument of a HTMLIframeElement can cause the browser
8147 // to throw, e.g. if it has a cross-origin src attribute.
8148 // Safari will show an error in the console when the access results in "Blocked a frame with origin". e.g:
8149 // iframe.contentDocument.defaultView;
8150 // A safety way is to access one of the cross origin properties: Window or Location
8151 // Which might result in "SecurityError" DOM Exception and it is compatible to Safari.
8152 // https://html.spec.whatwg.org/multipage/browsers.html#integration-with-idl
8153 return typeof iframe.contentWindow.location.href === 'string';
8154 } catch (err) {
8155 return false;
8156 }
8157}
8158
8159function getActiveElementDeep() {
8160 var win = window;
8161 var element = getActiveElement();
8162
8163 while (element instanceof win.HTMLIFrameElement) {
8164 if (isSameOriginFrame(element)) {
8165 win = element.contentWindow;
8166 } else {
8167 return element;
8168 }
8169
8170 element = getActiveElement(win.document);
8171 }
8172
8173 return element;
8174}
8175/**
8176 * @ReactInputSelection: React input selection module. Based on Selection.js,
8177 * but modified to be suitable for react and has a couple of bug fixes (doesn't
8178 * assume buttons have range selections allowed).
8179 * Input selection module for React.
8180 */
8181
8182/**
8183 * @hasSelectionCapabilities: we get the element types that support selection
8184 * from https://html.spec.whatwg.org/#do-not-apply, looking at `selectionStart`
8185 * and `selectionEnd` rows.
8186 */
8187
8188
8189function hasSelectionCapabilities(elem) {
8190 var nodeName = elem && elem.nodeName && elem.nodeName.toLowerCase();
8191 return nodeName && (nodeName === 'input' && (elem.type === 'text' || elem.type === 'search' || elem.type === 'tel' || elem.type === 'url' || elem.type === 'password') || nodeName === 'textarea' || elem.contentEditable === 'true');
8192}
8193function getSelectionInformation() {
8194 var focusedElem = getActiveElementDeep();
8195 return {
8196 focusedElem: focusedElem,
8197 selectionRange: hasSelectionCapabilities(focusedElem) ? getSelection$1(focusedElem) : null
8198 };
8199}
8200/**
8201 * @restoreSelection: If any selection information was potentially lost,
8202 * restore it. This is useful when performing operations that could remove dom
8203 * nodes and place them back in, resulting in focus being lost.
8204 */
8205
8206function restoreSelection(priorSelectionInformation) {
8207 var curFocusedElem = getActiveElementDeep();
8208 var priorFocusedElem = priorSelectionInformation.focusedElem;
8209 var priorSelectionRange = priorSelectionInformation.selectionRange;
8210
8211 if (curFocusedElem !== priorFocusedElem && isInDocument(priorFocusedElem)) {
8212 if (priorSelectionRange !== null && hasSelectionCapabilities(priorFocusedElem)) {
8213 setSelection(priorFocusedElem, priorSelectionRange);
8214 } // Focusing a node can change the scroll position, which is undesirable
8215
8216
8217 var ancestors = [];
8218 var ancestor = priorFocusedElem;
8219
8220 while (ancestor = ancestor.parentNode) {
8221 if (ancestor.nodeType === ELEMENT_NODE) {
8222 ancestors.push({
8223 element: ancestor,
8224 left: ancestor.scrollLeft,
8225 top: ancestor.scrollTop
8226 });
8227 }
8228 }
8229
8230 if (typeof priorFocusedElem.focus === 'function') {
8231 priorFocusedElem.focus();
8232 }
8233
8234 for (var i = 0; i < ancestors.length; i++) {
8235 var info = ancestors[i];
8236 info.element.scrollLeft = info.left;
8237 info.element.scrollTop = info.top;
8238 }
8239 }
8240}
8241/**
8242 * @getSelection: Gets the selection bounds of a focused textarea, input or
8243 * contentEditable node.
8244 * -@input: Look up selection bounds of this input
8245 * -@return {start: selectionStart, end: selectionEnd}
8246 */
8247
8248function getSelection$1(input) {
8249 var selection;
8250
8251 if ('selectionStart' in input) {
8252 // Modern browser with input or textarea.
8253 selection = {
8254 start: input.selectionStart,
8255 end: input.selectionEnd
8256 };
8257 } else {
8258 // Content editable or old IE textarea.
8259 selection = getOffsets(input);
8260 }
8261
8262 return selection || {
8263 start: 0,
8264 end: 0
8265 };
8266}
8267/**
8268 * @setSelection: Sets the selection bounds of a textarea or input and focuses
8269 * the input.
8270 * -@input Set selection bounds of this input or textarea
8271 * -@offsets Object of same form that is returned from get*
8272 */
8273
8274function setSelection(input, offsets) {
8275 var start = offsets.start;
8276 var end = offsets.end;
8277
8278 if (end === undefined) {
8279 end = start;
8280 }
8281
8282 if ('selectionStart' in input) {
8283 input.selectionStart = start;
8284 input.selectionEnd = Math.min(end, input.value.length);
8285 } else {
8286 setOffsets(input, offsets);
8287 }
8288}
8289
8290var skipSelectionChangeEvent = canUseDOM && 'documentMode' in document && document.documentMode <= 11;
8291
8292function registerEvents() {
8293 registerTwoPhaseEvent('onSelect', ['focusout', 'contextmenu', 'dragend', 'focusin', 'keydown', 'keyup', 'mousedown', 'mouseup', 'selectionchange']);
8294}
8295
8296var activeElement = null;
8297var activeElementInst = null;
8298var lastSelection = null;
8299var mouseDown = false;
8300/**
8301 * Get an object which is a unique representation of the current selection.
8302 *
8303 * The return value will not be consistent across nodes or browsers, but
8304 * two identical selections on the same node will return identical objects.
8305 */
8306
8307function getSelection(node) {
8308 if ('selectionStart' in node && hasSelectionCapabilities(node)) {
8309 return {
8310 start: node.selectionStart,
8311 end: node.selectionEnd
8312 };
8313 } else {
8314 var win = node.ownerDocument && node.ownerDocument.defaultView || window;
8315 var selection = win.getSelection();
8316 return {
8317 anchorNode: selection.anchorNode,
8318 anchorOffset: selection.anchorOffset,
8319 focusNode: selection.focusNode,
8320 focusOffset: selection.focusOffset
8321 };
8322 }
8323}
8324/**
8325 * Get document associated with the event target.
8326 */
8327
8328
8329function getEventTargetDocument(eventTarget) {
8330 return eventTarget.window === eventTarget ? eventTarget.document : eventTarget.nodeType === DOCUMENT_NODE ? eventTarget : eventTarget.ownerDocument;
8331}
8332/**
8333 * Poll selection to see whether it's changed.
8334 *
8335 * @param {object} nativeEvent
8336 * @param {object} nativeEventTarget
8337 * @return {?SyntheticEvent}
8338 */
8339
8340
8341function constructSelectEvent(dispatchQueue, nativeEvent, nativeEventTarget) {
8342 // Ensure we have the right element, and that the user is not dragging a
8343 // selection (this matches native `select` event behavior). In HTML5, select
8344 // fires only on input and textarea thus if there's no focused element we
8345 // won't dispatch.
8346 var doc = getEventTargetDocument(nativeEventTarget);
8347
8348 if (mouseDown || activeElement == null || activeElement !== getActiveElement(doc)) {
8349 return;
8350 } // Only fire when selection has actually changed.
8351
8352
8353 var currentSelection = getSelection(activeElement);
8354
8355 if (!lastSelection || !shallowEqual(lastSelection, currentSelection)) {
8356 lastSelection = currentSelection;
8357 var listeners = accumulateTwoPhaseListeners(activeElementInst, 'onSelect');
8358
8359 if (listeners.length > 0) {
8360 var event = new SyntheticEvent('onSelect', 'select', null, nativeEvent, nativeEventTarget);
8361 dispatchQueue.push({
8362 event: event,
8363 listeners: listeners
8364 });
8365 event.target = activeElement;
8366 }
8367 }
8368}
8369/**
8370 * This plugin creates an `onSelect` event that normalizes select events
8371 * across form elements.
8372 *
8373 * Supported elements are:
8374 * - input (see `isTextInputElement`)
8375 * - textarea
8376 * - contentEditable
8377 *
8378 * This differs from native browser implementations in the following ways:
8379 * - Fires on contentEditable fields as well as inputs.
8380 * - Fires for collapsed selection.
8381 * - Fires after user input.
8382 */
8383
8384
8385function extractEvents$3(dispatchQueue, domEventName, targetInst, nativeEvent, nativeEventTarget, eventSystemFlags, targetContainer) {
8386 var targetNode = targetInst ? getNodeFromInstance(targetInst) : window;
8387
8388 switch (domEventName) {
8389 // Track the input node that has focus.
8390 case 'focusin':
8391 if (isTextInputElement(targetNode) || targetNode.contentEditable === 'true') {
8392 activeElement = targetNode;
8393 activeElementInst = targetInst;
8394 lastSelection = null;
8395 }
8396
8397 break;
8398
8399 case 'focusout':
8400 activeElement = null;
8401 activeElementInst = null;
8402 lastSelection = null;
8403 break;
8404 // Don't fire the event while the user is dragging. This matches the
8405 // semantics of the native select event.
8406
8407 case 'mousedown':
8408 mouseDown = true;
8409 break;
8410
8411 case 'contextmenu':
8412 case 'mouseup':
8413 case 'dragend':
8414 mouseDown = false;
8415 constructSelectEvent(dispatchQueue, nativeEvent, nativeEventTarget);
8416 break;
8417 // Chrome and IE fire non-standard event when selection is changed (and
8418 // sometimes when it hasn't). IE's event fires out of order with respect
8419 // to key and input events on deletion, so we discard it.
8420 //
8421 // Firefox doesn't support selectionchange, so check selection status
8422 // after each key entry. The selection changes after keydown and before
8423 // keyup, but we check on keydown as well in the case of holding down a
8424 // key, when multiple keydown events are fired but only one keyup is.
8425 // This is also our approach for IE handling, for the reason above.
8426
8427 case 'selectionchange':
8428 if (skipSelectionChangeEvent) {
8429 break;
8430 }
8431
8432 // falls through
8433
8434 case 'keydown':
8435 case 'keyup':
8436 constructSelectEvent(dispatchQueue, nativeEvent, nativeEventTarget);
8437 }
8438}
8439
8440/**
8441 * Generate a mapping of standard vendor prefixes using the defined style property and event name.
8442 *
8443 * @param {string} styleProp
8444 * @param {string} eventName
8445 * @returns {object}
8446 */
8447
8448function makePrefixMap(styleProp, eventName) {
8449 var prefixes = {};
8450 prefixes[styleProp.toLowerCase()] = eventName.toLowerCase();
8451 prefixes['Webkit' + styleProp] = 'webkit' + eventName;
8452 prefixes['Moz' + styleProp] = 'moz' + eventName;
8453 return prefixes;
8454}
8455/**
8456 * A list of event names to a configurable list of vendor prefixes.
8457 */
8458
8459
8460var vendorPrefixes = {
8461 animationend: makePrefixMap('Animation', 'AnimationEnd'),
8462 animationiteration: makePrefixMap('Animation', 'AnimationIteration'),
8463 animationstart: makePrefixMap('Animation', 'AnimationStart'),
8464 transitionrun: makePrefixMap('Transition', 'TransitionRun'),
8465 transitionstart: makePrefixMap('Transition', 'TransitionStart'),
8466 transitioncancel: makePrefixMap('Transition', 'TransitionCancel'),
8467 transitionend: makePrefixMap('Transition', 'TransitionEnd')
8468};
8469/**
8470 * Event names that have already been detected and prefixed (if applicable).
8471 */
8472
8473var prefixedEventNames = {};
8474/**
8475 * Element to check for prefixes on.
8476 */
8477
8478var style = {};
8479/**
8480 * Bootstrap if a DOM exists.
8481 */
8482
8483if (canUseDOM) {
8484 style = document.createElement('div').style; // On some platforms, in particular some releases of Android 4.x,
8485 // the un-prefixed "animation" and "transition" properties are defined on the
8486 // style object but the events that fire will still be prefixed, so we need
8487 // to check if the un-prefixed events are usable, and if not remove them from the map.
8488
8489 if (!('AnimationEvent' in window)) {
8490 delete vendorPrefixes.animationend.animation;
8491 delete vendorPrefixes.animationiteration.animation;
8492 delete vendorPrefixes.animationstart.animation;
8493 } // Same as above
8494
8495
8496 if (!('TransitionEvent' in window)) {
8497 delete vendorPrefixes.transitionend.transition;
8498 }
8499}
8500/**
8501 * Attempts to determine the correct vendor prefixed event name.
8502 *
8503 * @param {string} eventName
8504 * @returns {string}
8505 */
8506
8507
8508function getVendorPrefixedEventName(eventName) {
8509 if (prefixedEventNames[eventName]) {
8510 return prefixedEventNames[eventName];
8511 } else if (!vendorPrefixes[eventName]) {
8512 return eventName;
8513 }
8514
8515 var prefixMap = vendorPrefixes[eventName];
8516
8517 for (var styleProp in prefixMap) {
8518 if (prefixMap.hasOwnProperty(styleProp) && styleProp in style) {
8519 return prefixedEventNames[eventName] = prefixMap[styleProp];
8520 }
8521 }
8522
8523 return eventName;
8524}
8525
8526var ANIMATION_END = getVendorPrefixedEventName('animationend');
8527var ANIMATION_ITERATION = getVendorPrefixedEventName('animationiteration');
8528var ANIMATION_START = getVendorPrefixedEventName('animationstart');
8529var TRANSITION_RUN = getVendorPrefixedEventName('transitionrun');
8530var TRANSITION_START = getVendorPrefixedEventName('transitionstart');
8531var TRANSITION_CANCEL = getVendorPrefixedEventName('transitioncancel');
8532var TRANSITION_END = getVendorPrefixedEventName('transitionend');
8533
8534var topLevelEventsToReactNames = new Map(); // NOTE: Capitalization is important in this list!
8535//
8536// E.g. it needs "pointerDown", not "pointerdown".
8537// This is because we derive both React name ("onPointerDown")
8538// and DOM name ("pointerdown") from the same list.
8539//
8540// Exceptions that don't match this convention are listed separately.
8541//
8542// prettier-ignore
8543
8544var simpleEventPluginEvents = ['abort', 'auxClick', 'cancel', 'canPlay', 'canPlayThrough', 'click', 'close', 'contextMenu', 'copy', 'cut', 'drag', 'dragEnd', 'dragEnter', 'dragExit', 'dragLeave', 'dragOver', 'dragStart', 'drop', 'durationChange', 'emptied', 'encrypted', 'ended', 'error', 'gotPointerCapture', 'input', 'invalid', 'keyDown', 'keyPress', 'keyUp', 'load', 'loadedData', 'loadedMetadata', 'loadStart', 'lostPointerCapture', 'mouseDown', 'mouseMove', 'mouseOut', 'mouseOver', 'mouseUp', 'paste', 'pause', 'play', 'playing', 'pointerCancel', 'pointerDown', 'pointerMove', 'pointerOut', 'pointerOver', 'pointerUp', 'progress', 'rateChange', 'reset', 'resize', 'seeked', 'seeking', 'stalled', 'submit', 'suspend', 'timeUpdate', 'touchCancel', 'touchEnd', 'touchStart', 'volumeChange', 'scroll', 'scrollEnd', 'toggle', 'touchMove', 'waiting', 'wheel'];
8545
8546function registerSimpleEvent(domEventName, reactName) {
8547 topLevelEventsToReactNames.set(domEventName, reactName);
8548 registerTwoPhaseEvent(reactName, [domEventName]);
8549}
8550
8551function registerSimpleEvents() {
8552 for (var i = 0; i < simpleEventPluginEvents.length; i++) {
8553 var eventName = simpleEventPluginEvents[i];
8554 var domEventName = eventName.toLowerCase();
8555 var capitalizedEvent = eventName[0].toUpperCase() + eventName.slice(1);
8556 registerSimpleEvent(domEventName, 'on' + capitalizedEvent);
8557 } // Special cases where event names don't match.
8558
8559
8560 registerSimpleEvent(ANIMATION_END, 'onAnimationEnd');
8561 registerSimpleEvent(ANIMATION_ITERATION, 'onAnimationIteration');
8562 registerSimpleEvent(ANIMATION_START, 'onAnimationStart');
8563 registerSimpleEvent('dblclick', 'onDoubleClick');
8564 registerSimpleEvent('focusin', 'onFocus');
8565 registerSimpleEvent('focusout', 'onBlur');
8566 registerSimpleEvent(TRANSITION_RUN, 'onTransitionRun');
8567 registerSimpleEvent(TRANSITION_START, 'onTransitionStart');
8568 registerSimpleEvent(TRANSITION_CANCEL, 'onTransitionCancel');
8569 registerSimpleEvent(TRANSITION_END, 'onTransitionEnd');
8570}
8571
8572function extractEvents$2(dispatchQueue, domEventName, targetInst, nativeEvent, nativeEventTarget, eventSystemFlags, targetContainer) {
8573 var reactName = topLevelEventsToReactNames.get(domEventName);
8574
8575 if (reactName === undefined) {
8576 return;
8577 }
8578
8579 var SyntheticEventCtor = SyntheticEvent;
8580 var reactEventType = domEventName;
8581
8582 switch (domEventName) {
8583 case 'keypress':
8584 // Firefox creates a keypress event for function keys too. This removes
8585 // the unwanted keypress events. Enter is however both printable and
8586 // non-printable. One would expect Tab to be as well (but it isn't).
8587 // TODO: Fixed in https://bugzilla.mozilla.org/show_bug.cgi?id=968056. Can
8588 // probably remove.
8589 if (getEventCharCode(nativeEvent) === 0) {
8590 return;
8591 }
8592
8593 /* falls through */
8594
8595 case 'keydown':
8596 case 'keyup':
8597 SyntheticEventCtor = SyntheticKeyboardEvent;
8598 break;
8599
8600 case 'focusin':
8601 reactEventType = 'focus';
8602 SyntheticEventCtor = SyntheticFocusEvent;
8603 break;
8604
8605 case 'focusout':
8606 reactEventType = 'blur';
8607 SyntheticEventCtor = SyntheticFocusEvent;
8608 break;
8609
8610 case 'beforeblur':
8611 case 'afterblur':
8612 SyntheticEventCtor = SyntheticFocusEvent;
8613 break;
8614
8615 case 'click':
8616 // Firefox creates a click event on right mouse clicks. This removes the
8617 // unwanted click events.
8618 // TODO: Fixed in https://phabricator.services.mozilla.com/D26793. Can
8619 // probably remove.
8620 if (nativeEvent.button === 2) {
8621 return;
8622 }
8623
8624 /* falls through */
8625
8626 case 'auxclick':
8627 case 'dblclick':
8628 case 'mousedown':
8629 case 'mousemove':
8630 case 'mouseup': // TODO: Disabled elements should not respond to mouse events
8631
8632 /* falls through */
8633
8634 case 'mouseout':
8635 case 'mouseover':
8636 case 'contextmenu':
8637 SyntheticEventCtor = SyntheticMouseEvent;
8638 break;
8639
8640 case 'drag':
8641 case 'dragend':
8642 case 'dragenter':
8643 case 'dragexit':
8644 case 'dragleave':
8645 case 'dragover':
8646 case 'dragstart':
8647 case 'drop':
8648 SyntheticEventCtor = SyntheticDragEvent;
8649 break;
8650
8651 case 'touchcancel':
8652 case 'touchend':
8653 case 'touchmove':
8654 case 'touchstart':
8655 SyntheticEventCtor = SyntheticTouchEvent;
8656 break;
8657
8658 case ANIMATION_END:
8659 case ANIMATION_ITERATION:
8660 case ANIMATION_START:
8661 SyntheticEventCtor = SyntheticAnimationEvent;
8662 break;
8663
8664 case TRANSITION_END:
8665 SyntheticEventCtor = SyntheticTransitionEvent;
8666 break;
8667
8668 case 'scroll':
8669 case 'scrollend':
8670 SyntheticEventCtor = SyntheticUIEvent;
8671 break;
8672
8673 case 'wheel':
8674 SyntheticEventCtor = SyntheticWheelEvent;
8675 break;
8676
8677 case 'copy':
8678 case 'cut':
8679 case 'paste':
8680 SyntheticEventCtor = SyntheticClipboardEvent;
8681 break;
8682
8683 case 'gotpointercapture':
8684 case 'lostpointercapture':
8685 case 'pointercancel':
8686 case 'pointerdown':
8687 case 'pointermove':
8688 case 'pointerout':
8689 case 'pointerover':
8690 case 'pointerup':
8691 SyntheticEventCtor = SyntheticPointerEvent;
8692 break;
8693 }
8694
8695 var inCapturePhase = (eventSystemFlags & IS_CAPTURE_PHASE) !== 0;
8696
8697 {
8698 // Some events don't bubble in the browser.
8699 // In the past, React has always bubbled them, but this can be surprising.
8700 // We're going to try aligning closer to the browser behavior by not bubbling
8701 // them in React either. We'll start by not bubbling onScroll, and then expand.
8702 var accumulateTargetOnly = !inCapturePhase && ( // TODO: ideally, we'd eventually add all events from
8703 // nonDelegatedEvents list in DOMPluginEventSystem.
8704 // Then we can remove this special list.
8705 // This is a breaking change that can wait until React 18.
8706 domEventName === 'scroll' || domEventName === 'scrollend');
8707
8708 var _listeners = accumulateSinglePhaseListeners(targetInst, reactName, nativeEvent.type, inCapturePhase, accumulateTargetOnly);
8709
8710 if (_listeners.length > 0) {
8711 // Intentionally create event lazily.
8712 var _event = new SyntheticEventCtor(reactName, reactEventType, null, nativeEvent, nativeEventTarget);
8713
8714 dispatchQueue.push({
8715 event: _event,
8716 listeners: _listeners
8717 });
8718 }
8719 }
8720}
8721
8722/**
8723 * This plugin invokes action functions on forms, inputs and buttons if
8724 * the form doesn't prevent default.
8725 */
8726
8727function extractEvents$1(dispatchQueue, domEventName, maybeTargetInst, nativeEvent, nativeEventTarget, eventSystemFlags, targetContainer) {
8728 if (domEventName !== 'submit') {
8729 return;
8730 }
8731
8732 if (!maybeTargetInst || maybeTargetInst.stateNode !== nativeEventTarget) {
8733 // If we're inside a parent root that itself is a parent of this root, then
8734 // its deepest target won't be the actual form that's being submitted.
8735 return;
8736 }
8737
8738 var formInst = maybeTargetInst;
8739 var form = nativeEventTarget;
8740 var action = getFiberCurrentPropsFromNode(form).action;
8741 var submitter = nativeEvent.submitter;
8742 var submitterAction;
8743
8744 if (submitter) {
8745 var submitterProps = getFiberCurrentPropsFromNode(submitter);
8746 submitterAction = submitterProps ? submitterProps.formAction : submitter.getAttribute('formAction');
8747
8748 if (submitterAction != null) {
8749 // The submitter overrides the form action.
8750 action = submitterAction; // If the action is a function, we don't want to pass its name
8751 // value to the FormData since it's controlled by the server.
8752
8753 submitter = null;
8754 }
8755 }
8756
8757 if (typeof action !== 'function') {
8758 return;
8759 }
8760
8761 var event = new SyntheticEvent('action', 'action', null, nativeEvent, nativeEventTarget);
8762
8763 function submitForm() {
8764 if (nativeEvent.defaultPrevented) {
8765 // We let earlier events to prevent the action from submitting.
8766 return;
8767 } // Prevent native navigation.
8768
8769
8770 event.preventDefault();
8771 var formData;
8772
8773 if (submitter) {
8774 // The submitter's value should be included in the FormData.
8775 // It should be in the document order in the form.
8776 // Since the FormData constructor invokes the formdata event it also
8777 // needs to be available before that happens so after construction it's too
8778 // late. We use a temporary fake node for the duration of this event.
8779 // TODO: FormData takes a second argument that it's the submitter but this
8780 // is fairly new so not all browsers support it yet. Switch to that technique
8781 // when available.
8782 var temp = submitter.ownerDocument.createElement('input');
8783 temp.name = submitter.name;
8784 temp.value = submitter.value;
8785 submitter.parentNode.insertBefore(temp, submitter);
8786 formData = new FormData(form);
8787 temp.parentNode.removeChild(temp);
8788 } else {
8789 formData = new FormData(form);
8790 }
8791
8792 var pendingState = {
8793 pending: true,
8794 data: formData,
8795 method: form.method,
8796 action: action
8797 };
8798
8799 {
8800 Object.freeze(pendingState);
8801 }
8802
8803 startHostTransition(formInst, pendingState, action, formData);
8804 }
8805
8806 dispatchQueue.push({
8807 event: event,
8808 listeners: [{
8809 instance: null,
8810 listener: submitForm,
8811 currentTarget: form
8812 }]
8813 });
8814}
8815function dispatchReplayedFormAction(formInst, form, action, formData) {
8816 var pendingState = {
8817 pending: true,
8818 data: formData,
8819 method: form.method,
8820 action: action
8821 };
8822
8823 {
8824 Object.freeze(pendingState);
8825 }
8826
8827 startHostTransition(formInst, pendingState, action, formData);
8828}
8829
8830var reportGlobalError = typeof reportError === 'function' ? // In modern browsers, reportError will dispatch an error event,
8831// emulating an uncaught JavaScript error.
8832reportError : function (error) {
8833 if (typeof window === 'object' && typeof window.ErrorEvent === 'function') {
8834 // Browser Polyfill
8835 var message = typeof error === 'object' && error !== null && typeof error.message === 'string' ? // eslint-disable-next-line react-internal/safe-string-coercion
8836 String(error.message) : // eslint-disable-next-line react-internal/safe-string-coercion
8837 String(error);
8838 var event = new window.ErrorEvent('error', {
8839 bubbles: true,
8840 cancelable: true,
8841 message: message,
8842 error: error
8843 });
8844 var shouldLog = window.dispatchEvent(event);
8845
8846 if (!shouldLog) {
8847 return;
8848 }
8849 } else if (typeof process === 'object' && // $FlowFixMe[method-unbinding]
8850 typeof process.emit === 'function') {
8851 // Node Polyfill
8852 process.emit('uncaughtException', error);
8853 return;
8854 } // eslint-disable-next-line react-internal/no-production-logging
8855
8856
8857 console['error'](error);
8858};
8859
8860registerSimpleEvents();
8861registerEvents$1();
8862registerEvents$2();
8863registerEvents();
8864registerEvents$3();
8865
8866function extractEvents(dispatchQueue, domEventName, targetInst, nativeEvent, nativeEventTarget, eventSystemFlags, targetContainer) {
8867 // TODO: we should remove the concept of a "SimpleEventPlugin".
8868 // This is the basic functionality of the event system. All
8869 // the other plugins are essentially polyfills. So the plugin
8870 // should probably be inlined somewhere and have its logic
8871 // be core the to event system. This would potentially allow
8872 // us to ship builds of React without the polyfilled plugins below.
8873 extractEvents$2(dispatchQueue, domEventName, targetInst, nativeEvent, nativeEventTarget, eventSystemFlags);
8874 var shouldProcessPolyfillPlugins = (eventSystemFlags & SHOULD_NOT_PROCESS_POLYFILL_EVENT_PLUGINS) === 0; // We don't process these events unless we are in the
8875 // event's native "bubble" phase, which means that we're
8876 // not in the capture phase. That's because we emulate
8877 // the capture phase here still. This is a trade-off,
8878 // because in an ideal world we would not emulate and use
8879 // the phases properly, like we do with the SimpleEvent
8880 // plugin. However, the plugins below either expect
8881 // emulation (EnterLeave) or use state localized to that
8882 // plugin (BeforeInput, Change, Select). The state in
8883 // these modules complicates things, as you'll essentially
8884 // get the case where the capture phase event might change
8885 // state, only for the following bubble event to come in
8886 // later and not trigger anything as the state now
8887 // invalidates the heuristics of the event plugin. We
8888 // could alter all these plugins to work in such ways, but
8889 // that might cause other unknown side-effects that we
8890 // can't foresee right now.
8891
8892 if (shouldProcessPolyfillPlugins) {
8893 extractEvents$4(dispatchQueue, domEventName, targetInst, nativeEvent, nativeEventTarget);
8894 extractEvents$5(dispatchQueue, domEventName, targetInst, nativeEvent, nativeEventTarget);
8895 extractEvents$3(dispatchQueue, domEventName, targetInst, nativeEvent, nativeEventTarget);
8896 extractEvents$6(dispatchQueue, domEventName, targetInst, nativeEvent, nativeEventTarget);
8897 extractEvents$1(dispatchQueue, domEventName, targetInst, nativeEvent, nativeEventTarget);
8898 }
8899} // List of events that need to be individually attached to media elements.
8900
8901
8902var mediaEventTypes = ['abort', 'canplay', 'canplaythrough', 'durationchange', 'emptied', 'encrypted', 'ended', 'error', 'loadeddata', 'loadedmetadata', 'loadstart', 'pause', 'play', 'playing', 'progress', 'ratechange', 'resize', 'seeked', 'seeking', 'stalled', 'suspend', 'timeupdate', 'volumechange', 'waiting']; // We should not delegate these events to the container, but rather
8903// set them on the actual target element itself. This is primarily
8904// because these events do not consistently bubble in the DOM.
8905
8906var nonDelegatedEvents = new Set(['cancel', 'close', 'invalid', 'load', 'scroll', 'scrollend', 'toggle'].concat(mediaEventTypes));
8907
8908function executeDispatch(event, listener, currentTarget) {
8909 event.currentTarget = currentTarget;
8910
8911 try {
8912 listener(event);
8913 } catch (error) {
8914 reportGlobalError(error);
8915 }
8916
8917 event.currentTarget = null;
8918}
8919
8920function processDispatchQueueItemsInOrder(event, dispatchListeners, inCapturePhase) {
8921 var previousInstance;
8922
8923 if (inCapturePhase) {
8924 for (var i = dispatchListeners.length - 1; i >= 0; i--) {
8925 var _dispatchListeners$i = dispatchListeners[i],
8926 instance = _dispatchListeners$i.instance,
8927 currentTarget = _dispatchListeners$i.currentTarget,
8928 listener = _dispatchListeners$i.listener;
8929
8930 if (instance !== previousInstance && event.isPropagationStopped()) {
8931 return;
8932 }
8933
8934 executeDispatch(event, listener, currentTarget);
8935 previousInstance = instance;
8936 }
8937 } else {
8938 for (var _i = 0; _i < dispatchListeners.length; _i++) {
8939 var _dispatchListeners$_i = dispatchListeners[_i],
8940 _instance = _dispatchListeners$_i.instance,
8941 _currentTarget = _dispatchListeners$_i.currentTarget,
8942 _listener = _dispatchListeners$_i.listener;
8943
8944 if (_instance !== previousInstance && event.isPropagationStopped()) {
8945 return;
8946 }
8947
8948 executeDispatch(event, _listener, _currentTarget);
8949 previousInstance = _instance;
8950 }
8951 }
8952}
8953
8954function processDispatchQueue(dispatchQueue, eventSystemFlags) {
8955 var inCapturePhase = (eventSystemFlags & IS_CAPTURE_PHASE) !== 0;
8956
8957 for (var i = 0; i < dispatchQueue.length; i++) {
8958 var _dispatchQueue$i = dispatchQueue[i],
8959 event = _dispatchQueue$i.event,
8960 listeners = _dispatchQueue$i.listeners;
8961 processDispatchQueueItemsInOrder(event, listeners, inCapturePhase); // event system doesn't use pooling.
8962 }
8963}
8964
8965function dispatchEventsForPlugins(domEventName, eventSystemFlags, nativeEvent, targetInst, targetContainer) {
8966 var nativeEventTarget = getEventTarget(nativeEvent);
8967 var dispatchQueue = [];
8968 extractEvents(dispatchQueue, domEventName, targetInst, nativeEvent, nativeEventTarget, eventSystemFlags);
8969 processDispatchQueue(dispatchQueue, eventSystemFlags);
8970}
8971
8972function listenToNonDelegatedEvent(domEventName, targetElement) {
8973 {
8974 if (!nonDelegatedEvents.has(domEventName)) {
8975 error('Did not expect a listenToNonDelegatedEvent() call for "%s". ' + 'This is a bug in React. Please file an issue.', domEventName);
8976 }
8977 }
8978
8979 var isCapturePhaseListener = false;
8980 var listenerSet = getEventListenerSet(targetElement);
8981 var listenerSetKey = getListenerSetKey(domEventName, isCapturePhaseListener);
8982
8983 if (!listenerSet.has(listenerSetKey)) {
8984 addTrappedEventListener(targetElement, domEventName, IS_NON_DELEGATED, isCapturePhaseListener);
8985 listenerSet.add(listenerSetKey);
8986 }
8987}
8988function listenToNativeEvent(domEventName, isCapturePhaseListener, target) {
8989 {
8990 if (nonDelegatedEvents.has(domEventName) && !isCapturePhaseListener) {
8991 error('Did not expect a listenToNativeEvent() call for "%s" in the bubble phase. ' + 'This is a bug in React. Please file an issue.', domEventName);
8992 }
8993 }
8994
8995 var eventSystemFlags = 0;
8996
8997 if (isCapturePhaseListener) {
8998 eventSystemFlags |= IS_CAPTURE_PHASE;
8999 }
9000
9001 addTrappedEventListener(target, domEventName, eventSystemFlags, isCapturePhaseListener);
9002} // This is only used by createEventHandle when the
9003var listeningMarker = '_reactListening' + Math.random().toString(36).slice(2);
9004function listenToAllSupportedEvents(rootContainerElement) {
9005 if (!rootContainerElement[listeningMarker]) {
9006 rootContainerElement[listeningMarker] = true;
9007 allNativeEvents.forEach(function (domEventName) {
9008 // We handle selectionchange separately because it
9009 // doesn't bubble and needs to be on the document.
9010 if (domEventName !== 'selectionchange') {
9011 if (!nonDelegatedEvents.has(domEventName)) {
9012 listenToNativeEvent(domEventName, false, rootContainerElement);
9013 }
9014
9015 listenToNativeEvent(domEventName, true, rootContainerElement);
9016 }
9017 });
9018 var ownerDocument = rootContainerElement.nodeType === DOCUMENT_NODE ? rootContainerElement : rootContainerElement.ownerDocument;
9019
9020 if (ownerDocument !== null) {
9021 // The selectionchange event also needs deduplication
9022 // but it is attached to the document.
9023 if (!ownerDocument[listeningMarker]) {
9024 ownerDocument[listeningMarker] = true;
9025 listenToNativeEvent('selectionchange', false, ownerDocument);
9026 }
9027 }
9028 }
9029}
9030
9031function addTrappedEventListener(targetContainer, domEventName, eventSystemFlags, isCapturePhaseListener, isDeferredListenerForLegacyFBSupport) {
9032 var listener = createEventListenerWrapperWithPriority(targetContainer, domEventName, eventSystemFlags); // If passive option is not supported, then the event will be
9033 // active and not passive.
9034
9035 var isPassiveListener = undefined;
9036
9037 if (passiveBrowserEventsSupported) {
9038 // Browsers introduced an intervention, making these events
9039 // passive by default on document. React doesn't bind them
9040 // to document anymore, but changing this now would undo
9041 // the performance wins from the change. So we emulate
9042 // the existing behavior manually on the roots now.
9043 // https://github.com/facebook/react/issues/19651
9044 if (domEventName === 'touchstart' || domEventName === 'touchmove' || domEventName === 'wheel') {
9045 isPassiveListener = true;
9046 }
9047 }
9048
9049 targetContainer = targetContainer;
9050
9051
9052 if (isCapturePhaseListener) {
9053 if (isPassiveListener !== undefined) {
9054 addEventCaptureListenerWithPassiveFlag(targetContainer, domEventName, listener, isPassiveListener);
9055 } else {
9056 addEventCaptureListener(targetContainer, domEventName, listener);
9057 }
9058 } else {
9059 if (isPassiveListener !== undefined) {
9060 addEventBubbleListenerWithPassiveFlag(targetContainer, domEventName, listener, isPassiveListener);
9061 } else {
9062 addEventBubbleListener(targetContainer, domEventName, listener);
9063 }
9064 }
9065}
9066
9067function isMatchingRootContainer(grandContainer, targetContainer) {
9068 return grandContainer === targetContainer || grandContainer.nodeType === COMMENT_NODE && grandContainer.parentNode === targetContainer;
9069}
9070
9071function dispatchEventForPluginEventSystem(domEventName, eventSystemFlags, nativeEvent, targetInst, targetContainer) {
9072 var ancestorInst = targetInst;
9073
9074 if ((eventSystemFlags & IS_EVENT_HANDLE_NON_MANAGED_NODE) === 0 && (eventSystemFlags & IS_NON_DELEGATED) === 0) {
9075 var targetContainerNode = targetContainer; // If we are using the legacy FB support flag, we
9076
9077 if (targetInst !== null) {
9078 // The below logic attempts to work out if we need to change
9079 // the target fiber to a different ancestor. We had similar logic
9080 // in the legacy event system, except the big difference between
9081 // systems is that the modern event system now has an event listener
9082 // attached to each React Root and React Portal Root. Together,
9083 // the DOM nodes representing these roots are the "rootContainer".
9084 // To figure out which ancestor instance we should use, we traverse
9085 // up the fiber tree from the target instance and attempt to find
9086 // root boundaries that match that of our current "rootContainer".
9087 // If we find that "rootContainer", we find the parent fiber
9088 // sub-tree for that root and make that our ancestor instance.
9089 var node = targetInst;
9090
9091 mainLoop: while (true) {
9092 if (node === null) {
9093 return;
9094 }
9095
9096 var nodeTag = node.tag;
9097
9098 if (nodeTag === HostRoot || nodeTag === HostPortal) {
9099 var container = node.stateNode.containerInfo;
9100
9101 if (isMatchingRootContainer(container, targetContainerNode)) {
9102 break;
9103 }
9104
9105 if (nodeTag === HostPortal) {
9106 // The target is a portal, but it's not the rootContainer we're looking for.
9107 // Normally portals handle their own events all the way down to the root.
9108 // So we should be able to stop now. However, we don't know if this portal
9109 // was part of *our* root.
9110 var grandNode = node.return;
9111
9112 while (grandNode !== null) {
9113 var grandTag = grandNode.tag;
9114
9115 if (grandTag === HostRoot || grandTag === HostPortal) {
9116 var grandContainer = grandNode.stateNode.containerInfo;
9117
9118 if (isMatchingRootContainer(grandContainer, targetContainerNode)) {
9119 // This is the rootContainer we're looking for and we found it as
9120 // a parent of the Portal. That means we can ignore it because the
9121 // Portal will bubble through to us.
9122 return;
9123 }
9124 }
9125
9126 grandNode = grandNode.return;
9127 }
9128 } // Now we need to find it's corresponding host fiber in the other
9129 // tree. To do this we can use getClosestInstanceFromNode, but we
9130 // need to validate that the fiber is a host instance, otherwise
9131 // we need to traverse up through the DOM till we find the correct
9132 // node that is from the other tree.
9133
9134
9135 while (container !== null) {
9136 var parentNode = getClosestInstanceFromNode(container);
9137
9138 if (parentNode === null) {
9139 return;
9140 }
9141
9142 var parentTag = parentNode.tag;
9143
9144 if (parentTag === HostComponent || parentTag === HostText || parentTag === HostHoistable || parentTag === HostSingleton) {
9145 node = ancestorInst = parentNode;
9146 continue mainLoop;
9147 }
9148
9149 container = container.parentNode;
9150 }
9151 }
9152
9153 node = node.return;
9154 }
9155 }
9156 }
9157
9158 batchedUpdates$1(function () {
9159 return dispatchEventsForPlugins(domEventName, eventSystemFlags, nativeEvent, ancestorInst);
9160 });
9161}
9162
9163function createDispatchListener(instance, listener, currentTarget) {
9164 return {
9165 instance: instance,
9166 listener: listener,
9167 currentTarget: currentTarget
9168 };
9169}
9170
9171function accumulateSinglePhaseListeners(targetFiber, reactName, nativeEventType, inCapturePhase, accumulateTargetOnly, nativeEvent) {
9172 var captureName = reactName !== null ? reactName + 'Capture' : null;
9173 var reactEventName = inCapturePhase ? captureName : reactName;
9174 var listeners = [];
9175 var instance = targetFiber;
9176 var lastHostComponent = null; // Accumulate all instances and listeners via the target -> root path.
9177
9178 while (instance !== null) {
9179 var _instance2 = instance,
9180 stateNode = _instance2.stateNode,
9181 tag = _instance2.tag; // Handle listeners that are on HostComponents (i.e. <div>)
9182
9183 if ((tag === HostComponent || tag === HostHoistable || tag === HostSingleton) && stateNode !== null) {
9184 lastHostComponent = stateNode; // createEventHandle listeners
9185
9186
9187 if (reactEventName !== null) {
9188 var listener = getListener(instance, reactEventName);
9189
9190 if (listener != null) {
9191 listeners.push(createDispatchListener(instance, listener, lastHostComponent));
9192 }
9193 }
9194 } // If we are only accumulating events for the target, then we don't
9195 // continue to propagate through the React fiber tree to find other
9196 // listeners.
9197
9198
9199 if (accumulateTargetOnly) {
9200 break;
9201 } // If we are processing the onBeforeBlur event, then we need to take
9202
9203 instance = instance.return;
9204 }
9205
9206 return listeners;
9207} // We should only use this function for:
9208// - BeforeInputEventPlugin
9209// - ChangeEventPlugin
9210// - SelectEventPlugin
9211// This is because we only process these plugins
9212// in the bubble phase, so we need to accumulate two
9213// phase event listeners (via emulation).
9214
9215function accumulateTwoPhaseListeners(targetFiber, reactName) {
9216 var captureName = reactName + 'Capture';
9217 var listeners = [];
9218 var instance = targetFiber; // Accumulate all instances and listeners via the target -> root path.
9219
9220 while (instance !== null) {
9221 var _instance3 = instance,
9222 stateNode = _instance3.stateNode,
9223 tag = _instance3.tag; // Handle listeners that are on HostComponents (i.e. <div>)
9224
9225 if ((tag === HostComponent || tag === HostHoistable || tag === HostSingleton) && stateNode !== null) {
9226 var currentTarget = stateNode;
9227 var captureListener = getListener(instance, captureName);
9228
9229 if (captureListener != null) {
9230 listeners.unshift(createDispatchListener(instance, captureListener, currentTarget));
9231 }
9232
9233 var bubbleListener = getListener(instance, reactName);
9234
9235 if (bubbleListener != null) {
9236 listeners.push(createDispatchListener(instance, bubbleListener, currentTarget));
9237 }
9238 }
9239
9240 instance = instance.return;
9241 }
9242
9243 return listeners;
9244}
9245
9246function getParent(inst) {
9247 if (inst === null) {
9248 return null;
9249 }
9250
9251 do {
9252 // $FlowFixMe[incompatible-use] found when upgrading Flow
9253 inst = inst.return; // TODO: If this is a HostRoot we might want to bail out.
9254 // That is depending on if we want nested subtrees (layers) to bubble
9255 // events to their parent. We could also go through parentNode on the
9256 // host node but that wouldn't work for React Native and doesn't let us
9257 // do the portal feature.
9258 } while (inst && inst.tag !== HostComponent && inst.tag !== HostSingleton);
9259
9260 if (inst) {
9261 return inst;
9262 }
9263
9264 return null;
9265}
9266/**
9267 * Return the lowest common ancestor of A and B, or null if they are in
9268 * different trees.
9269 */
9270
9271
9272function getLowestCommonAncestor(instA, instB) {
9273 var nodeA = instA;
9274 var nodeB = instB;
9275 var depthA = 0;
9276
9277 for (var tempA = nodeA; tempA; tempA = getParent(tempA)) {
9278 depthA++;
9279 }
9280
9281 var depthB = 0;
9282
9283 for (var tempB = nodeB; tempB; tempB = getParent(tempB)) {
9284 depthB++;
9285 } // If A is deeper, crawl up.
9286
9287
9288 while (depthA - depthB > 0) {
9289 nodeA = getParent(nodeA);
9290 depthA--;
9291 } // If B is deeper, crawl up.
9292
9293
9294 while (depthB - depthA > 0) {
9295 nodeB = getParent(nodeB);
9296 depthB--;
9297 } // Walk in lockstep until we find a match.
9298
9299
9300 var depth = depthA;
9301
9302 while (depth--) {
9303 if (nodeA === nodeB || nodeB !== null && nodeA === nodeB.alternate) {
9304 return nodeA;
9305 }
9306
9307 nodeA = getParent(nodeA);
9308 nodeB = getParent(nodeB);
9309 }
9310
9311 return null;
9312}
9313
9314function accumulateEnterLeaveListenersForEvent(dispatchQueue, event, target, common, inCapturePhase) {
9315 var registrationName = event._reactName;
9316 var listeners = [];
9317 var instance = target;
9318
9319 while (instance !== null) {
9320 if (instance === common) {
9321 break;
9322 }
9323
9324 var _instance4 = instance,
9325 alternate = _instance4.alternate,
9326 stateNode = _instance4.stateNode,
9327 tag = _instance4.tag;
9328
9329 if (alternate !== null && alternate === common) {
9330 break;
9331 }
9332
9333 if ((tag === HostComponent || tag === HostHoistable || tag === HostSingleton) && stateNode !== null) {
9334 var currentTarget = stateNode;
9335
9336 if (inCapturePhase) {
9337 var captureListener = getListener(instance, registrationName);
9338
9339 if (captureListener != null) {
9340 listeners.unshift(createDispatchListener(instance, captureListener, currentTarget));
9341 }
9342 } else if (!inCapturePhase) {
9343 var bubbleListener = getListener(instance, registrationName);
9344
9345 if (bubbleListener != null) {
9346 listeners.push(createDispatchListener(instance, bubbleListener, currentTarget));
9347 }
9348 }
9349 }
9350
9351 instance = instance.return;
9352 }
9353
9354 if (listeners.length !== 0) {
9355 dispatchQueue.push({
9356 event: event,
9357 listeners: listeners
9358 });
9359 }
9360} // We should only use this function for:
9361// - EnterLeaveEventPlugin
9362// This is because we only process this plugin
9363// in the bubble phase, so we need to accumulate two
9364// phase event listeners.
9365
9366
9367function accumulateEnterLeaveTwoPhaseListeners(dispatchQueue, leaveEvent, enterEvent, from, to) {
9368 var common = from && to ? getLowestCommonAncestor(from, to) : null;
9369
9370 if (from !== null) {
9371 accumulateEnterLeaveListenersForEvent(dispatchQueue, leaveEvent, from, common, false);
9372 }
9373
9374 if (to !== null && enterEvent !== null) {
9375 accumulateEnterLeaveListenersForEvent(dispatchQueue, enterEvent, to, common, true);
9376 }
9377}
9378function getListenerSetKey(domEventName, capture) {
9379 return domEventName + "__" + (capture ? 'capture' : 'bubble');
9380}
9381
9382var didWarnControlledToUncontrolled = false;
9383var didWarnUncontrolledToControlled = false;
9384var didWarnFormActionType = false;
9385var didWarnFormActionName = false;
9386var didWarnFormActionTarget = false;
9387var didWarnFormActionMethod = false;
9388var didWarnForNewBooleanPropsWithEmptyValue;
9389var canDiffStyleForHydrationWarning;
9390
9391{
9392 didWarnForNewBooleanPropsWithEmptyValue = {}; // IE 11 parses & normalizes the style attribute as opposed to other
9393 // browsers. It adds spaces and sorts the properties in some
9394 // non-alphabetical order. Handling that would require sorting CSS
9395 // properties in the client & server versions or applying
9396 // `expectedStyle` to a temporary DOM node to read its `style` attribute
9397 // normalized. Since it only affects IE, we're skipping style warnings
9398 // in that browser completely in favor of doing all that work.
9399 // See https://github.com/facebook/react/issues/11807
9400
9401 canDiffStyleForHydrationWarning = disableIEWorkarounds ;
9402}
9403
9404function validatePropertiesInDevelopment(type, props) {
9405 {
9406 validateProperties$2(type, props);
9407 validateProperties$1(type, props);
9408 validateProperties(type, props, {
9409 registrationNameDependencies: registrationNameDependencies,
9410 possibleRegistrationNames: possibleRegistrationNames
9411 });
9412
9413 if (props.contentEditable && !props.suppressContentEditableWarning && props.children != null) {
9414 error('A component is `contentEditable` and contains `children` managed by ' + 'React. It is now your responsibility to guarantee that none of ' + 'those nodes are unexpectedly modified or duplicated. This is ' + 'probably not intentional.');
9415 }
9416 }
9417}
9418
9419function validateFormActionInDevelopment(tag, key, value, props) {
9420 {
9421 if (value == null) {
9422 return;
9423 }
9424
9425 if (tag === 'form') {
9426 if (key === 'formAction') {
9427 error('You can only pass the formAction prop to <input> or <button>. Use the action prop on <form>.');
9428 } else if (typeof value === 'function') {
9429 if ((props.encType != null || props.method != null) && !didWarnFormActionMethod) {
9430 didWarnFormActionMethod = true;
9431
9432 error('Cannot specify a encType or method for a form that specifies a ' + 'function as the action. React provides those automatically. ' + 'They will get overridden.');
9433 }
9434
9435 if (props.target != null && !didWarnFormActionTarget) {
9436 didWarnFormActionTarget = true;
9437
9438 error('Cannot specify a target for a form that specifies a function as the action. ' + 'The function will always be executed in the same window.');
9439 }
9440 }
9441 } else if (tag === 'input' || tag === 'button') {
9442 if (key === 'action') {
9443 error('You can only pass the action prop to <form>. Use the formAction prop on <input> or <button>.');
9444 } else if (tag === 'input' && props.type !== 'submit' && props.type !== 'image' && !didWarnFormActionType) {
9445 didWarnFormActionType = true;
9446
9447 error('An input can only specify a formAction along with type="submit" or type="image".');
9448 } else if (tag === 'button' && props.type != null && props.type !== 'submit' && !didWarnFormActionType) {
9449 didWarnFormActionType = true;
9450
9451 error('A button can only specify a formAction along with type="submit" or no type.');
9452 } else if (typeof value === 'function') {
9453 // Function form actions cannot control the form properties
9454 if (props.name != null && !didWarnFormActionName) {
9455 didWarnFormActionName = true;
9456
9457 error('Cannot specify a "name" prop for a button that specifies a function as a formAction. ' + 'React needs it to encode which action should be invoked. It will get overridden.');
9458 }
9459
9460 if ((props.formEncType != null || props.formMethod != null) && !didWarnFormActionMethod) {
9461 didWarnFormActionMethod = true;
9462
9463 error('Cannot specify a formEncType or formMethod for a button that specifies a ' + 'function as a formAction. React provides those automatically. They will get overridden.');
9464 }
9465
9466 if (props.formTarget != null && !didWarnFormActionTarget) {
9467 didWarnFormActionTarget = true;
9468
9469 error('Cannot specify a formTarget for a button that specifies a function as a formAction. ' + 'The function will always be executed in the same window.');
9470 }
9471 }
9472 } else {
9473 if (key === 'action') {
9474 error('You can only pass the action prop to <form>.');
9475 } else {
9476 error('You can only pass the formAction prop to <input> or <button>.');
9477 }
9478 }
9479 }
9480}
9481
9482function warnForPropDifference(propName, serverValue, clientValue, serverDifferences) {
9483 {
9484 if (serverValue === clientValue) {
9485 return;
9486 }
9487
9488 var normalizedClientValue = normalizeMarkupForTextOrAttribute(clientValue);
9489 var normalizedServerValue = normalizeMarkupForTextOrAttribute(serverValue);
9490
9491 if (normalizedServerValue === normalizedClientValue) {
9492 return;
9493 }
9494
9495 serverDifferences[propName] = serverValue;
9496 }
9497}
9498
9499function warnForExtraAttributes(domElement, attributeNames, serverDifferences) {
9500 {
9501 attributeNames.forEach(function (attributeName) {
9502 serverDifferences[getPropNameFromAttributeName(attributeName)] = attributeName === 'style' ? getStylesObjectFromElement(domElement) : domElement.getAttribute(attributeName);
9503 });
9504 }
9505}
9506
9507function warnForInvalidEventListener(registrationName, listener) {
9508 {
9509 if (listener === false) {
9510 error('Expected `%s` listener to be a function, instead got `false`.\n\n' + 'If you used to conditionally omit it with %s={condition && value}, ' + 'pass %s={condition ? value : undefined} instead.', registrationName, registrationName, registrationName);
9511 } else {
9512 error('Expected `%s` listener to be a function, instead got a value of `%s` type.', registrationName, typeof listener);
9513 }
9514 }
9515} // Parse the HTML and read it back to normalize the HTML string so that it
9516// can be used for comparison.
9517
9518
9519function normalizeHTML(parent, html) {
9520 {
9521 // We could have created a separate document here to avoid
9522 // re-initializing custom elements if they exist. But this breaks
9523 // how <noscript> is being handled. So we use the same document.
9524 // See the discussion in https://github.com/facebook/react/pull/11157.
9525 var testElement = parent.namespaceURI === MATH_NAMESPACE || parent.namespaceURI === SVG_NAMESPACE ? parent.ownerDocument.createElementNS(parent.namespaceURI, parent.tagName) : parent.ownerDocument.createElement(parent.tagName);
9526 testElement.innerHTML = html;
9527 return testElement.innerHTML;
9528 }
9529} // HTML parsing normalizes CR and CRLF to LF.
9530// It also can turn \u0000 into \uFFFD inside attributes.
9531// https://www.w3.org/TR/html5/single-page.html#preprocessing-the-input-stream
9532// If we have a mismatch, it might be caused by that.
9533// We will still patch up in this case but not fire the warning.
9534
9535
9536var NORMALIZE_NEWLINES_REGEX = /\r\n?/g;
9537var NORMALIZE_NULL_AND_REPLACEMENT_REGEX = /\u0000|\uFFFD/g;
9538
9539function normalizeMarkupForTextOrAttribute(markup) {
9540 {
9541 checkHtmlStringCoercion(markup);
9542 }
9543
9544 var markupString = typeof markup === 'string' ? markup : '' + markup;
9545 return markupString.replace(NORMALIZE_NEWLINES_REGEX, '\n').replace(NORMALIZE_NULL_AND_REPLACEMENT_REGEX, '');
9546}
9547
9548function checkForUnmatchedText(serverText, clientText) {
9549 var normalizedClientText = normalizeMarkupForTextOrAttribute(clientText);
9550 var normalizedServerText = normalizeMarkupForTextOrAttribute(serverText);
9551
9552 if (normalizedServerText === normalizedClientText) {
9553 return true;
9554 }
9555
9556 return false;
9557}
9558
9559function noop$2() {}
9560
9561function trapClickOnNonInteractiveElement(node) {
9562 // Mobile Safari does not fire properly bubble click events on
9563 // non-interactive elements, which means delegated click listeners do not
9564 // fire. The workaround for this bug involves attaching an empty click
9565 // listener on the target node.
9566 // https://www.quirksmode.org/blog/archives/2010/09/click_event_del.html
9567 // Just set it using the onclick property so that we don't have to manage any
9568 // bookkeeping for it. Not sure if we need to clear it when the listener is
9569 // removed.
9570 // TODO: Only do this for the relevant Safaris maybe?
9571 node.onclick = noop$2;
9572}
9573var xlinkNamespace = 'http://www.w3.org/1999/xlink';
9574var xmlNamespace = 'http://www.w3.org/XML/1998/namespace';
9575
9576function setProp(domElement, tag, key, value, props, prevValue) {
9577 switch (key) {
9578 case 'children':
9579 {
9580 if (typeof value === 'string') {
9581 {
9582 validateTextNesting(value, tag);
9583 } // Avoid setting initial textContent when the text is empty. In IE11 setting
9584 // textContent on a <textarea> will cause the placeholder to not
9585 // show within the <textarea> until it has been focused and blurred again.
9586 // https://github.com/facebook/react/issues/6731#issuecomment-254874553
9587
9588
9589 var canSetTextContent = tag !== 'body' && (tag !== 'textarea' || value !== '');
9590
9591 if (canSetTextContent) {
9592 setTextContent(domElement, value);
9593 }
9594 } else if (typeof value === 'number' || typeof value === 'bigint') {
9595 {
9596 // $FlowFixMe[unsafe-addition] Flow doesn't want us to use `+` operator with string and bigint
9597 validateTextNesting('' + value, tag);
9598 }
9599
9600 var _canSetTextContent = tag !== 'body';
9601
9602 if (_canSetTextContent) {
9603 // $FlowFixMe[unsafe-addition] Flow doesn't want us to use `+` operator with string and bigint
9604 setTextContent(domElement, '' + value);
9605 }
9606 }
9607
9608 break;
9609 }
9610 // These are very common props and therefore are in the beginning of the switch.
9611 // TODO: aria-label is a very common prop but allows booleans so is not like the others
9612 // but should ideally go in this list too.
9613
9614 case 'className':
9615 setValueForKnownAttribute(domElement, 'class', value);
9616 break;
9617
9618 case 'tabIndex':
9619 // This has to be case sensitive in SVG.
9620 setValueForKnownAttribute(domElement, 'tabindex', value);
9621 break;
9622
9623 case 'dir':
9624 case 'role':
9625 case 'viewBox':
9626 case 'width':
9627 case 'height':
9628 {
9629 setValueForKnownAttribute(domElement, key, value);
9630 break;
9631 }
9632
9633 case 'style':
9634 {
9635 setValueForStyles(domElement, value, prevValue);
9636 break;
9637 }
9638 // These attributes accept URLs. These must not allow javascript: URLS.
9639
9640 case 'src':
9641 case 'href':
9642 {
9643 {
9644 if (value === '' && // <a href=""> is fine for "reload" links.
9645 !(tag === 'a' && key === 'href')) {
9646 {
9647 if (key === 'src') {
9648 error('An empty string ("") was passed to the %s attribute. ' + 'This may cause the browser to download the whole page again over the network. ' + 'To fix this, either do not render the element at all ' + 'or pass null to %s instead of an empty string.', key, key);
9649 } else {
9650 error('An empty string ("") was passed to the %s attribute. ' + 'To fix this, either do not render the element at all ' + 'or pass null to %s instead of an empty string.', key, key);
9651 }
9652 }
9653
9654 domElement.removeAttribute(key);
9655 break;
9656 }
9657 }
9658
9659 if (value == null || typeof value === 'function' || typeof value === 'symbol' || typeof value === 'boolean') {
9660 domElement.removeAttribute(key);
9661 break;
9662 } // `setAttribute` with objects becomes only `[object]` in IE8/9,
9663 // ('' + value) makes it output the correct toString()-value.
9664
9665
9666 {
9667 checkAttributeStringCoercion(value, key);
9668 }
9669
9670 var sanitizedValue = sanitizeURL('' + value);
9671 domElement.setAttribute(key, sanitizedValue);
9672 break;
9673 }
9674
9675 case 'action':
9676 case 'formAction':
9677 {
9678 // TODO: Consider moving these special cases to the form, input and button tags.
9679 {
9680 validateFormActionInDevelopment(tag, key, value, props);
9681 }
9682
9683 if (typeof value === 'function') {
9684 // Set a javascript URL that doesn't do anything. We don't expect this to be invoked
9685 // because we'll preventDefault, but it can happen if a form is manually submitted or
9686 // if someone calls stopPropagation before React gets the event.
9687 // If CSP is used to block javascript: URLs that's fine too. It just won't show this
9688 // error message but the URL will be logged.
9689 domElement.setAttribute(key, // eslint-disable-next-line no-script-url
9690 "javascript:throw new Error('" + 'A React form was unexpectedly submitted. If you called form.submit() manually, ' + "consider using form.requestSubmit() instead. If you\\'re trying to use " + 'event.stopPropagation() in a submit event handler, consider also calling ' + 'event.preventDefault().' + "')");
9691 break;
9692 } else if (typeof prevValue === 'function') {
9693 // When we're switching off a Server Action that was originally hydrated.
9694 // The server control these fields during SSR that are now trailing.
9695 // The regular diffing doesn't apply since we compare against the previous props.
9696 // Instead, we need to force them to be set to whatever they should be now.
9697 // This would be a lot cleaner if we did this whole fork in the per-tag approach.
9698 if (key === 'formAction') {
9699 if (tag !== 'input') {
9700 // Setting the name here isn't completely safe for inputs if this is switching
9701 // to become a radio button. In that case we let the tag based override take
9702 // control.
9703 setProp(domElement, tag, 'name', props.name, props, null);
9704 }
9705
9706 setProp(domElement, tag, 'formEncType', props.formEncType, props, null);
9707 setProp(domElement, tag, 'formMethod', props.formMethod, props, null);
9708 setProp(domElement, tag, 'formTarget', props.formTarget, props, null);
9709 } else {
9710 setProp(domElement, tag, 'encType', props.encType, props, null);
9711 setProp(domElement, tag, 'method', props.method, props, null);
9712 setProp(domElement, tag, 'target', props.target, props, null);
9713 }
9714 }
9715
9716 if (value == null || typeof value === 'symbol' || typeof value === 'boolean') {
9717 domElement.removeAttribute(key);
9718 break;
9719 } // `setAttribute` with objects becomes only `[object]` in IE8/9,
9720 // ('' + value) makes it output the correct toString()-value.
9721
9722
9723 {
9724 checkAttributeStringCoercion(value, key);
9725 }
9726
9727 var _sanitizedValue = sanitizeURL('' + value);
9728
9729 domElement.setAttribute(key, _sanitizedValue);
9730 break;
9731 }
9732
9733 case 'onClick':
9734 {
9735 // TODO: This cast may not be sound for SVG, MathML or custom elements.
9736 if (value != null) {
9737 if (typeof value !== 'function') {
9738 warnForInvalidEventListener(key, value);
9739 }
9740
9741 trapClickOnNonInteractiveElement(domElement);
9742 }
9743
9744 break;
9745 }
9746
9747 case 'onScroll':
9748 {
9749 if (value != null) {
9750 if (typeof value !== 'function') {
9751 warnForInvalidEventListener(key, value);
9752 }
9753
9754 listenToNonDelegatedEvent('scroll', domElement);
9755 }
9756
9757 break;
9758 }
9759
9760 case 'onScrollEnd':
9761 {
9762 if (value != null) {
9763 if (typeof value !== 'function') {
9764 warnForInvalidEventListener(key, value);
9765 }
9766
9767 listenToNonDelegatedEvent('scrollend', domElement);
9768 }
9769
9770 break;
9771 }
9772
9773 case 'dangerouslySetInnerHTML':
9774 {
9775 if (value != null) {
9776 if (typeof value !== 'object' || !('__html' in value)) {
9777 throw new Error('`props.dangerouslySetInnerHTML` must be in the form `{__html: ...}`. ' + 'Please visit https://react.dev/link/dangerously-set-inner-html ' + 'for more information.');
9778 }
9779
9780 var nextHtml = value.__html;
9781
9782 if (nextHtml != null) {
9783 if (props.children != null) {
9784 throw new Error('Can only set one of `children` or `props.dangerouslySetInnerHTML`.');
9785 }
9786
9787 {
9788 domElement.innerHTML = nextHtml;
9789 }
9790 }
9791 }
9792
9793 break;
9794 }
9795 // Note: `option.selected` is not updated if `select.multiple` is
9796 // disabled with `removeAttribute`. We have special logic for handling this.
9797
9798 case 'multiple':
9799 {
9800 domElement.multiple = value && typeof value !== 'function' && typeof value !== 'symbol';
9801 break;
9802 }
9803
9804 case 'muted':
9805 {
9806 domElement.muted = value && typeof value !== 'function' && typeof value !== 'symbol';
9807 break;
9808 }
9809
9810 case 'suppressContentEditableWarning':
9811 case 'suppressHydrationWarning':
9812 case 'defaultValue': // Reserved
9813
9814 case 'defaultChecked':
9815 case 'innerHTML':
9816 case 'ref':
9817 {
9818 // TODO: `ref` is pretty common, should we move it up?
9819 // Noop
9820 break;
9821 }
9822
9823 case 'autoFocus':
9824 {
9825 // We polyfill it separately on the client during commit.
9826 // We could have excluded it in the property list instead of
9827 // adding a special case here, but then it wouldn't be emitted
9828 // on server rendering (but we *do* want to emit it in SSR).
9829 break;
9830 }
9831
9832 case 'xlinkHref':
9833 {
9834 if (value == null || typeof value === 'function' || typeof value === 'boolean' || typeof value === 'symbol') {
9835 domElement.removeAttribute('xlink:href');
9836 break;
9837 } // `setAttribute` with objects becomes only `[object]` in IE8/9,
9838 // ('' + value) makes it output the correct toString()-value.
9839
9840
9841 {
9842 checkAttributeStringCoercion(value, key);
9843 }
9844
9845 var _sanitizedValue2 = sanitizeURL('' + value);
9846
9847 domElement.setAttributeNS(xlinkNamespace, 'xlink:href', _sanitizedValue2);
9848 break;
9849 }
9850
9851 case 'contentEditable':
9852 case 'spellCheck':
9853 case 'draggable':
9854 case 'value':
9855 case 'autoReverse':
9856 case 'externalResourcesRequired':
9857 case 'focusable':
9858 case 'preserveAlpha':
9859 {
9860 // Booleanish String
9861 // These are "enumerated" attributes that accept "true" and "false".
9862 // In React, we let users pass `true` and `false` even though technically
9863 // these aren't boolean attributes (they are coerced to strings).
9864 // The SVG attributes are case-sensitive. Since the HTML attributes are
9865 // insensitive they also work even though we canonically use lower case.
9866 if (value != null && typeof value !== 'function' && typeof value !== 'symbol') {
9867 {
9868 checkAttributeStringCoercion(value, key);
9869 }
9870
9871 domElement.setAttribute(key, '' + value);
9872 } else {
9873 domElement.removeAttribute(key);
9874 }
9875
9876 break;
9877 }
9878 // Boolean
9879
9880 case 'inert':
9881 {
9882 {
9883 if (value === '' && !didWarnForNewBooleanPropsWithEmptyValue[key]) {
9884 didWarnForNewBooleanPropsWithEmptyValue[key] = true;
9885
9886 error('Received an empty string for a boolean attribute `%s`. ' + 'This will treat the attribute as if it were false. ' + 'Either pass `false` to silence this warning, or ' + 'pass `true` if you used an empty string in earlier versions of React to indicate this attribute is true.', key);
9887 }
9888 }
9889 }
9890 // Fallthrough for boolean props that don't have a warning for empty strings.
9891
9892 case 'allowFullScreen':
9893 case 'async':
9894 case 'autoPlay':
9895 case 'controls':
9896 case 'default':
9897 case 'defer':
9898 case 'disabled':
9899 case 'disablePictureInPicture':
9900 case 'disableRemotePlayback':
9901 case 'formNoValidate':
9902 case 'hidden':
9903 case 'loop':
9904 case 'noModule':
9905 case 'noValidate':
9906 case 'open':
9907 case 'playsInline':
9908 case 'readOnly':
9909 case 'required':
9910 case 'reversed':
9911 case 'scoped':
9912 case 'seamless':
9913 case 'itemScope':
9914 {
9915 if (value && typeof value !== 'function' && typeof value !== 'symbol') {
9916 domElement.setAttribute(key, '');
9917 } else {
9918 domElement.removeAttribute(key);
9919 }
9920
9921 break;
9922 }
9923 // Overloaded Boolean
9924
9925 case 'capture':
9926 case 'download':
9927 {
9928 // An attribute that can be used as a flag as well as with a value.
9929 // When true, it should be present (set either to an empty string or its name).
9930 // When false, it should be omitted.
9931 // For any other value, should be present with that value.
9932 if (value === true) {
9933 domElement.setAttribute(key, '');
9934 } else if (value !== false && value != null && typeof value !== 'function' && typeof value !== 'symbol') {
9935 {
9936 checkAttributeStringCoercion(value, key);
9937 }
9938
9939 domElement.setAttribute(key, value);
9940 } else {
9941 domElement.removeAttribute(key);
9942 }
9943
9944 break;
9945 }
9946
9947 case 'cols':
9948 case 'rows':
9949 case 'size':
9950 case 'span':
9951 {
9952 // These are HTML attributes that must be positive numbers.
9953 if (value != null && typeof value !== 'function' && typeof value !== 'symbol' && !isNaN(value) && value >= 1) {
9954 {
9955 checkAttributeStringCoercion(value, key);
9956 }
9957
9958 domElement.setAttribute(key, value);
9959 } else {
9960 domElement.removeAttribute(key);
9961 }
9962
9963 break;
9964 }
9965
9966 case 'rowSpan':
9967 case 'start':
9968 {
9969 // These are HTML attributes that must be numbers.
9970 if (value != null && typeof value !== 'function' && typeof value !== 'symbol' && !isNaN(value)) {
9971 {
9972 checkAttributeStringCoercion(value, key);
9973 }
9974
9975 domElement.setAttribute(key, value);
9976 } else {
9977 domElement.removeAttribute(key);
9978 }
9979
9980 break;
9981 }
9982
9983 case 'xlinkActuate':
9984 setValueForNamespacedAttribute(domElement, xlinkNamespace, 'xlink:actuate', value);
9985 break;
9986
9987 case 'xlinkArcrole':
9988 setValueForNamespacedAttribute(domElement, xlinkNamespace, 'xlink:arcrole', value);
9989 break;
9990
9991 case 'xlinkRole':
9992 setValueForNamespacedAttribute(domElement, xlinkNamespace, 'xlink:role', value);
9993 break;
9994
9995 case 'xlinkShow':
9996 setValueForNamespacedAttribute(domElement, xlinkNamespace, 'xlink:show', value);
9997 break;
9998
9999 case 'xlinkTitle':
10000 setValueForNamespacedAttribute(domElement, xlinkNamespace, 'xlink:title', value);
10001 break;
10002
10003 case 'xlinkType':
10004 setValueForNamespacedAttribute(domElement, xlinkNamespace, 'xlink:type', value);
10005 break;
10006
10007 case 'xmlBase':
10008 setValueForNamespacedAttribute(domElement, xmlNamespace, 'xml:base', value);
10009 break;
10010
10011 case 'xmlLang':
10012 setValueForNamespacedAttribute(domElement, xmlNamespace, 'xml:lang', value);
10013 break;
10014
10015 case 'xmlSpace':
10016 setValueForNamespacedAttribute(domElement, xmlNamespace, 'xml:space', value);
10017 break;
10018 // Properties that should not be allowed on custom elements.
10019
10020 case 'is':
10021 {
10022 {
10023 if (prevValue != null) {
10024 error('Cannot update the "is" prop after it has been initialized.');
10025 }
10026 } // TODO: We shouldn't actually set this attribute, because we've already
10027 // passed it to createElement. We don't also need the attribute.
10028 // However, our tests currently query for it so it's plausible someone
10029 // else does too so it's break.
10030
10031
10032 setValueForAttribute(domElement, 'is', value);
10033 break;
10034 }
10035
10036 case 'innerText':
10037 case 'textContent':
10038 break;
10039 // Fall through
10040
10041 default:
10042 {
10043 if (key.length > 2 && (key[0] === 'o' || key[0] === 'O') && (key[1] === 'n' || key[1] === 'N')) {
10044 if (registrationNameDependencies.hasOwnProperty(key) && value != null && typeof value !== 'function') {
10045 warnForInvalidEventListener(key, value);
10046 }
10047 } else {
10048 var attributeName = getAttributeAlias(key);
10049 setValueForAttribute(domElement, attributeName, value);
10050 }
10051 }
10052 }
10053}
10054
10055function setPropOnCustomElement(domElement, tag, key, value, props, prevValue) {
10056 switch (key) {
10057 case 'style':
10058 {
10059 setValueForStyles(domElement, value, prevValue);
10060 break;
10061 }
10062
10063 case 'dangerouslySetInnerHTML':
10064 {
10065 if (value != null) {
10066 if (typeof value !== 'object' || !('__html' in value)) {
10067 throw new Error('`props.dangerouslySetInnerHTML` must be in the form `{__html: ...}`. ' + 'Please visit https://react.dev/link/dangerously-set-inner-html ' + 'for more information.');
10068 }
10069
10070 var nextHtml = value.__html;
10071
10072 if (nextHtml != null) {
10073 if (props.children != null) {
10074 throw new Error('Can only set one of `children` or `props.dangerouslySetInnerHTML`.');
10075 }
10076
10077 {
10078 domElement.innerHTML = nextHtml;
10079 }
10080 }
10081 }
10082
10083 break;
10084 }
10085
10086 case 'children':
10087 {
10088 if (typeof value === 'string') {
10089 setTextContent(domElement, value);
10090 } else if (typeof value === 'number' || typeof value === 'bigint') {
10091 // $FlowFixMe[unsafe-addition] Flow doesn't want us to use `+` operator with string and bigint
10092 setTextContent(domElement, '' + value);
10093 }
10094
10095 break;
10096 }
10097
10098 case 'onScroll':
10099 {
10100 if (value != null) {
10101 if (typeof value !== 'function') {
10102 warnForInvalidEventListener(key, value);
10103 }
10104
10105 listenToNonDelegatedEvent('scroll', domElement);
10106 }
10107
10108 break;
10109 }
10110
10111 case 'onScrollEnd':
10112 {
10113 if (value != null) {
10114 if (typeof value !== 'function') {
10115 warnForInvalidEventListener(key, value);
10116 }
10117
10118 listenToNonDelegatedEvent('scrollend', domElement);
10119 }
10120
10121 break;
10122 }
10123
10124 case 'onClick':
10125 {
10126 // TODO: This cast may not be sound for SVG, MathML or custom elements.
10127 if (value != null) {
10128 if (typeof value !== 'function') {
10129 warnForInvalidEventListener(key, value);
10130 }
10131
10132 trapClickOnNonInteractiveElement(domElement);
10133 }
10134
10135 break;
10136 }
10137
10138 case 'suppressContentEditableWarning':
10139 case 'suppressHydrationWarning':
10140 case 'innerHTML':
10141 case 'ref':
10142 {
10143 // Noop
10144 break;
10145 }
10146
10147 case 'innerText': // Properties
10148
10149 case 'textContent':
10150 break;
10151 // Fall through
10152
10153 default:
10154 {
10155 if (registrationNameDependencies.hasOwnProperty(key)) {
10156 if (value != null && typeof value !== 'function') {
10157 warnForInvalidEventListener(key, value);
10158 }
10159 } else {
10160 setValueForPropertyOnCustomComponent(domElement, key, value);
10161 }
10162 }
10163 }
10164}
10165
10166function setInitialProperties(domElement, tag, props) {
10167 {
10168 validatePropertiesInDevelopment(tag, props);
10169 } // TODO: Make sure that we check isMounted before firing any of these events.
10170
10171
10172 switch (tag) {
10173 case 'div':
10174 case 'span':
10175 case 'svg':
10176 case 'path':
10177 case 'a':
10178 case 'g':
10179 case 'p':
10180 case 'li':
10181 {
10182 // Fast track the most common tag types
10183 break;
10184 }
10185
10186 case 'input':
10187 {
10188 {
10189 checkControlledValueProps('input', props);
10190 } // We listen to this event in case to ensure emulated bubble
10191 // listeners still fire for the invalid event.
10192
10193
10194 listenToNonDelegatedEvent('invalid', domElement);
10195 var name = null;
10196 var type = null;
10197 var value = null;
10198 var defaultValue = null;
10199 var checked = null;
10200 var defaultChecked = null;
10201
10202 for (var propKey in props) {
10203 if (!props.hasOwnProperty(propKey)) {
10204 continue;
10205 }
10206
10207 var propValue = props[propKey];
10208
10209 if (propValue == null) {
10210 continue;
10211 }
10212
10213 switch (propKey) {
10214 case 'name':
10215 {
10216 name = propValue;
10217 break;
10218 }
10219
10220 case 'type':
10221 {
10222 type = propValue;
10223 break;
10224 }
10225
10226 case 'checked':
10227 {
10228 checked = propValue;
10229 break;
10230 }
10231
10232 case 'defaultChecked':
10233 {
10234 defaultChecked = propValue;
10235 break;
10236 }
10237
10238 case 'value':
10239 {
10240 value = propValue;
10241 break;
10242 }
10243
10244 case 'defaultValue':
10245 {
10246 defaultValue = propValue;
10247 break;
10248 }
10249
10250 case 'children':
10251 case 'dangerouslySetInnerHTML':
10252 {
10253 if (propValue != null) {
10254 throw new Error(tag + " is a void element tag and must neither have `children` nor " + 'use `dangerouslySetInnerHTML`.');
10255 }
10256
10257 break;
10258 }
10259
10260 default:
10261 {
10262 setProp(domElement, tag, propKey, propValue, props, null);
10263 }
10264 }
10265 } // TODO: Make sure we check if this is still unmounted or do any clean
10266 // up necessary since we never stop tracking anymore.
10267
10268
10269 validateInputProps(domElement, props);
10270 initInput(domElement, value, defaultValue, checked, defaultChecked, type, name, false);
10271 track(domElement);
10272 return;
10273 }
10274
10275 case 'select':
10276 {
10277 {
10278 checkControlledValueProps('select', props);
10279 } // We listen to this event in case to ensure emulated bubble
10280 // listeners still fire for the invalid event.
10281
10282
10283 listenToNonDelegatedEvent('invalid', domElement);
10284 var _value = null;
10285 var _defaultValue = null;
10286 var multiple = null;
10287
10288 for (var _propKey in props) {
10289 if (!props.hasOwnProperty(_propKey)) {
10290 continue;
10291 }
10292
10293 var _propValue = props[_propKey];
10294
10295 if (_propValue == null) {
10296 continue;
10297 }
10298
10299 switch (_propKey) {
10300 case 'value':
10301 {
10302 _value = _propValue; // This is handled by initSelect below.
10303
10304 break;
10305 }
10306
10307 case 'defaultValue':
10308 {
10309 _defaultValue = _propValue; // This is handled by initSelect below.
10310
10311 break;
10312 }
10313
10314 case 'multiple':
10315 {
10316 multiple = _propValue; // TODO: We don't actually have to fall through here because we set it
10317 // in initSelect anyway. We can remove the special case in setProp.
10318 }
10319 // Fallthrough
10320
10321 default:
10322 {
10323 setProp(domElement, tag, _propKey, _propValue, props, null);
10324 }
10325 }
10326 }
10327
10328 validateSelectProps(domElement, props);
10329 initSelect(domElement, _value, _defaultValue, multiple);
10330 return;
10331 }
10332
10333 case 'textarea':
10334 {
10335 {
10336 checkControlledValueProps('textarea', props);
10337 } // We listen to this event in case to ensure emulated bubble
10338 // listeners still fire for the invalid event.
10339
10340
10341 listenToNonDelegatedEvent('invalid', domElement);
10342 var _value2 = null;
10343 var _defaultValue2 = null;
10344 var children = null;
10345
10346 for (var _propKey2 in props) {
10347 if (!props.hasOwnProperty(_propKey2)) {
10348 continue;
10349 }
10350
10351 var _propValue2 = props[_propKey2];
10352
10353 if (_propValue2 == null) {
10354 continue;
10355 }
10356
10357 switch (_propKey2) {
10358 case 'value':
10359 {
10360 _value2 = _propValue2; // This is handled by initTextarea below.
10361
10362 break;
10363 }
10364
10365 case 'defaultValue':
10366 {
10367 _defaultValue2 = _propValue2;
10368 break;
10369 }
10370
10371 case 'children':
10372 {
10373 children = _propValue2; // Handled by initTextarea above.
10374
10375 break;
10376 }
10377
10378 case 'dangerouslySetInnerHTML':
10379 {
10380 if (_propValue2 != null) {
10381 // TODO: Do we really need a special error message for this. It's also pretty blunt.
10382 throw new Error('`dangerouslySetInnerHTML` does not make sense on <textarea>.');
10383 }
10384
10385 break;
10386 }
10387
10388 default:
10389 {
10390 setProp(domElement, tag, _propKey2, _propValue2, props, null);
10391 }
10392 }
10393 } // TODO: Make sure we check if this is still unmounted or do any clean
10394 // up necessary since we never stop tracking anymore.
10395
10396
10397 validateTextareaProps(domElement, props);
10398 initTextarea(domElement, _value2, _defaultValue2, children);
10399 track(domElement);
10400 return;
10401 }
10402
10403 case 'option':
10404 {
10405 validateOptionProps(domElement, props);
10406
10407 for (var _propKey3 in props) {
10408 if (!props.hasOwnProperty(_propKey3)) {
10409 continue;
10410 }
10411
10412 var _propValue3 = props[_propKey3];
10413
10414 if (_propValue3 == null) {
10415 continue;
10416 }
10417
10418 switch (_propKey3) {
10419 case 'selected':
10420 {
10421 // TODO: Remove support for selected on option.
10422 domElement.selected = _propValue3 && typeof _propValue3 !== 'function' && typeof _propValue3 !== 'symbol';
10423 break;
10424 }
10425
10426 default:
10427 {
10428 setProp(domElement, tag, _propKey3, _propValue3, props, null);
10429 }
10430 }
10431 }
10432
10433 return;
10434 }
10435
10436 case 'dialog':
10437 {
10438 listenToNonDelegatedEvent('cancel', domElement);
10439 listenToNonDelegatedEvent('close', domElement);
10440 break;
10441 }
10442
10443 case 'iframe':
10444 case 'object':
10445 {
10446 // We listen to this event in case to ensure emulated bubble
10447 // listeners still fire for the load event.
10448 listenToNonDelegatedEvent('load', domElement);
10449 break;
10450 }
10451
10452 case 'video':
10453 case 'audio':
10454 {
10455 // We listen to these events in case to ensure emulated bubble
10456 // listeners still fire for all the media events.
10457 for (var i = 0; i < mediaEventTypes.length; i++) {
10458 listenToNonDelegatedEvent(mediaEventTypes[i], domElement);
10459 }
10460
10461 break;
10462 }
10463
10464 case 'image':
10465 {
10466 // We listen to these events in case to ensure emulated bubble
10467 // listeners still fire for error and load events.
10468 listenToNonDelegatedEvent('error', domElement);
10469 listenToNonDelegatedEvent('load', domElement);
10470 break;
10471 }
10472
10473 case 'details':
10474 {
10475 // We listen to this event in case to ensure emulated bubble
10476 // listeners still fire for the toggle event.
10477 listenToNonDelegatedEvent('toggle', domElement);
10478 break;
10479 }
10480
10481 case 'embed':
10482 case 'source':
10483 case 'img':
10484 case 'link':
10485 {
10486 // These are void elements that also need delegated events.
10487 listenToNonDelegatedEvent('error', domElement);
10488 listenToNonDelegatedEvent('load', domElement); // We fallthrough to the return of the void elements
10489 }
10490
10491 case 'area':
10492 case 'base':
10493 case 'br':
10494 case 'col':
10495 case 'hr':
10496 case 'keygen':
10497 case 'meta':
10498 case 'param':
10499 case 'track':
10500 case 'wbr':
10501 case 'menuitem':
10502 {
10503 // Void elements
10504 for (var _propKey4 in props) {
10505 if (!props.hasOwnProperty(_propKey4)) {
10506 continue;
10507 }
10508
10509 var _propValue4 = props[_propKey4];
10510
10511 if (_propValue4 == null) {
10512 continue;
10513 }
10514
10515 switch (_propKey4) {
10516 case 'children':
10517 case 'dangerouslySetInnerHTML':
10518 {
10519 // TODO: Can we make this a DEV warning to avoid this deny list?
10520 throw new Error(tag + " is a void element tag and must neither have `children` nor " + 'use `dangerouslySetInnerHTML`.');
10521 }
10522 // defaultChecked and defaultValue are ignored by setProp
10523
10524 default:
10525 {
10526 setProp(domElement, tag, _propKey4, _propValue4, props, null);
10527 }
10528 }
10529 }
10530
10531 return;
10532 }
10533
10534 default:
10535 {
10536 if (isCustomElement(tag)) {
10537 for (var _propKey5 in props) {
10538 if (!props.hasOwnProperty(_propKey5)) {
10539 continue;
10540 }
10541
10542 var _propValue5 = props[_propKey5];
10543
10544 if (_propValue5 === undefined) {
10545 continue;
10546 }
10547
10548 setPropOnCustomElement(domElement, tag, _propKey5, _propValue5, props, undefined);
10549 }
10550
10551 return;
10552 }
10553 }
10554 }
10555
10556 for (var _propKey6 in props) {
10557 if (!props.hasOwnProperty(_propKey6)) {
10558 continue;
10559 }
10560
10561 var _propValue6 = props[_propKey6];
10562
10563 if (_propValue6 == null) {
10564 continue;
10565 }
10566
10567 setProp(domElement, tag, _propKey6, _propValue6, props, null);
10568 }
10569}
10570function updateProperties(domElement, tag, lastProps, nextProps) {
10571 {
10572 validatePropertiesInDevelopment(tag, nextProps);
10573 }
10574
10575 switch (tag) {
10576 case 'div':
10577 case 'span':
10578 case 'svg':
10579 case 'path':
10580 case 'a':
10581 case 'g':
10582 case 'p':
10583 case 'li':
10584 {
10585 // Fast track the most common tag types
10586 break;
10587 }
10588
10589 case 'input':
10590 {
10591 var name = null;
10592 var type = null;
10593 var value = null;
10594 var defaultValue = null;
10595 var lastDefaultValue = null;
10596 var checked = null;
10597 var defaultChecked = null;
10598
10599 for (var propKey in lastProps) {
10600 var lastProp = lastProps[propKey];
10601
10602 if (lastProps.hasOwnProperty(propKey) && lastProp != null) {
10603 switch (propKey) {
10604 case 'checked':
10605 {
10606 break;
10607 }
10608
10609 case 'value':
10610 {
10611 // This is handled by updateWrapper below.
10612 break;
10613 }
10614
10615 case 'defaultValue':
10616 {
10617 lastDefaultValue = lastProp;
10618 }
10619 // defaultChecked and defaultValue are ignored by setProp
10620 // Fallthrough
10621
10622 default:
10623 {
10624 if (!nextProps.hasOwnProperty(propKey)) setProp(domElement, tag, propKey, null, nextProps, lastProp);
10625 }
10626 }
10627 }
10628 }
10629
10630 for (var _propKey7 in nextProps) {
10631 var nextProp = nextProps[_propKey7];
10632 var _lastProp = lastProps[_propKey7];
10633
10634 if (nextProps.hasOwnProperty(_propKey7) && (nextProp != null || _lastProp != null)) {
10635 switch (_propKey7) {
10636 case 'type':
10637 {
10638 type = nextProp;
10639 break;
10640 }
10641
10642 case 'name':
10643 {
10644 name = nextProp;
10645 break;
10646 }
10647
10648 case 'checked':
10649 {
10650 checked = nextProp;
10651 break;
10652 }
10653
10654 case 'defaultChecked':
10655 {
10656 defaultChecked = nextProp;
10657 break;
10658 }
10659
10660 case 'value':
10661 {
10662 value = nextProp;
10663 break;
10664 }
10665
10666 case 'defaultValue':
10667 {
10668 defaultValue = nextProp;
10669 break;
10670 }
10671
10672 case 'children':
10673 case 'dangerouslySetInnerHTML':
10674 {
10675 if (nextProp != null) {
10676 throw new Error(tag + " is a void element tag and must neither have `children` nor " + 'use `dangerouslySetInnerHTML`.');
10677 }
10678
10679 break;
10680 }
10681
10682 default:
10683 {
10684 if (nextProp !== _lastProp) setProp(domElement, tag, _propKey7, nextProp, nextProps, _lastProp);
10685 }
10686 }
10687 }
10688 }
10689
10690 {
10691 var wasControlled = lastProps.type === 'checkbox' || lastProps.type === 'radio' ? lastProps.checked != null : lastProps.value != null;
10692 var isControlled = nextProps.type === 'checkbox' || nextProps.type === 'radio' ? nextProps.checked != null : nextProps.value != null;
10693
10694 if (!wasControlled && isControlled && !didWarnUncontrolledToControlled) {
10695 error('A component is changing an uncontrolled input to be controlled. ' + 'This is likely caused by the value changing from undefined to ' + 'a defined value, which should not happen. ' + 'Decide between using a controlled or uncontrolled input ' + 'element for the lifetime of the component. More info: https://react.dev/link/controlled-components');
10696
10697 didWarnUncontrolledToControlled = true;
10698 }
10699
10700 if (wasControlled && !isControlled && !didWarnControlledToUncontrolled) {
10701 error('A component is changing a controlled input to be uncontrolled. ' + 'This is likely caused by the value changing from a defined to ' + 'undefined, which should not happen. ' + 'Decide between using a controlled or uncontrolled input ' + 'element for the lifetime of the component. More info: https://react.dev/link/controlled-components');
10702
10703 didWarnControlledToUncontrolled = true;
10704 }
10705 } // Update the wrapper around inputs *after* updating props. This has to
10706 // happen after updating the rest of props. Otherwise HTML5 input validations
10707 // raise warnings and prevent the new value from being assigned.
10708
10709
10710 updateInput(domElement, value, defaultValue, lastDefaultValue, checked, defaultChecked, type, name);
10711 return;
10712 }
10713
10714 case 'select':
10715 {
10716 var _value3 = null;
10717 var _defaultValue3 = null;
10718 var multiple = null;
10719 var wasMultiple = null;
10720
10721 for (var _propKey8 in lastProps) {
10722 var _lastProp2 = lastProps[_propKey8];
10723
10724 if (lastProps.hasOwnProperty(_propKey8) && _lastProp2 != null) {
10725 switch (_propKey8) {
10726 case 'value':
10727 {
10728 // This is handled by updateWrapper below.
10729 break;
10730 }
10731 // defaultValue are ignored by setProp
10732
10733 case 'multiple':
10734 {
10735 wasMultiple = _lastProp2; // TODO: Move special case in here from setProp.
10736 }
10737 // Fallthrough
10738
10739 default:
10740 {
10741 if (!nextProps.hasOwnProperty(_propKey8)) setProp(domElement, tag, _propKey8, null, nextProps, _lastProp2);
10742 }
10743 }
10744 }
10745 }
10746
10747 for (var _propKey9 in nextProps) {
10748 var _nextProp = nextProps[_propKey9];
10749 var _lastProp3 = lastProps[_propKey9];
10750
10751 if (nextProps.hasOwnProperty(_propKey9) && (_nextProp != null || _lastProp3 != null)) {
10752 switch (_propKey9) {
10753 case 'value':
10754 {
10755 _value3 = _nextProp; // This is handled by updateSelect below.
10756
10757 break;
10758 }
10759
10760 case 'defaultValue':
10761 {
10762 _defaultValue3 = _nextProp;
10763 break;
10764 }
10765
10766 case 'multiple':
10767 {
10768 multiple = _nextProp; // TODO: Just move the special case in here from setProp.
10769 }
10770 // Fallthrough
10771
10772 default:
10773 {
10774 if (_nextProp !== _lastProp3) setProp(domElement, tag, _propKey9, _nextProp, nextProps, _lastProp3);
10775 }
10776 }
10777 }
10778 } // <select> value update needs to occur after <option> children
10779 // reconciliation
10780
10781
10782 updateSelect(domElement, _value3, _defaultValue3, multiple, wasMultiple);
10783 return;
10784 }
10785
10786 case 'textarea':
10787 {
10788 var _value4 = null;
10789 var _defaultValue4 = null;
10790
10791 for (var _propKey10 in lastProps) {
10792 var _lastProp4 = lastProps[_propKey10];
10793
10794 if (lastProps.hasOwnProperty(_propKey10) && _lastProp4 != null && !nextProps.hasOwnProperty(_propKey10)) {
10795 switch (_propKey10) {
10796 case 'value':
10797 {
10798 // This is handled by updateTextarea below.
10799 break;
10800 }
10801
10802 case 'children':
10803 {
10804 // TODO: This doesn't actually do anything if it updates.
10805 break;
10806 }
10807 // defaultValue is ignored by setProp
10808
10809 default:
10810 {
10811 setProp(domElement, tag, _propKey10, null, nextProps, _lastProp4);
10812 }
10813 }
10814 }
10815 }
10816
10817 for (var _propKey11 in nextProps) {
10818 var _nextProp2 = nextProps[_propKey11];
10819 var _lastProp5 = lastProps[_propKey11];
10820
10821 if (nextProps.hasOwnProperty(_propKey11) && (_nextProp2 != null || _lastProp5 != null)) {
10822 switch (_propKey11) {
10823 case 'value':
10824 {
10825 _value4 = _nextProp2; // This is handled by updateTextarea below.
10826
10827 break;
10828 }
10829
10830 case 'defaultValue':
10831 {
10832 _defaultValue4 = _nextProp2;
10833 break;
10834 }
10835
10836 case 'children':
10837 {
10838 // TODO: This doesn't actually do anything if it updates.
10839 break;
10840 }
10841
10842 case 'dangerouslySetInnerHTML':
10843 {
10844 if (_nextProp2 != null) {
10845 // TODO: Do we really need a special error message for this. It's also pretty blunt.
10846 throw new Error('`dangerouslySetInnerHTML` does not make sense on <textarea>.');
10847 }
10848
10849 break;
10850 }
10851
10852 default:
10853 {
10854 if (_nextProp2 !== _lastProp5) setProp(domElement, tag, _propKey11, _nextProp2, nextProps, _lastProp5);
10855 }
10856 }
10857 }
10858 }
10859
10860 updateTextarea(domElement, _value4, _defaultValue4);
10861 return;
10862 }
10863
10864 case 'option':
10865 {
10866 for (var _propKey12 in lastProps) {
10867 var _lastProp6 = lastProps[_propKey12];
10868
10869 if (lastProps.hasOwnProperty(_propKey12) && _lastProp6 != null && !nextProps.hasOwnProperty(_propKey12)) {
10870 switch (_propKey12) {
10871 case 'selected':
10872 {
10873 // TODO: Remove support for selected on option.
10874 domElement.selected = false;
10875 break;
10876 }
10877
10878 default:
10879 {
10880 setProp(domElement, tag, _propKey12, null, nextProps, _lastProp6);
10881 }
10882 }
10883 }
10884 }
10885
10886 for (var _propKey13 in nextProps) {
10887 var _nextProp3 = nextProps[_propKey13];
10888 var _lastProp7 = lastProps[_propKey13];
10889
10890 if (nextProps.hasOwnProperty(_propKey13) && _nextProp3 !== _lastProp7 && (_nextProp3 != null || _lastProp7 != null)) {
10891 switch (_propKey13) {
10892 case 'selected':
10893 {
10894 // TODO: Remove support for selected on option.
10895 domElement.selected = _nextProp3 && typeof _nextProp3 !== 'function' && typeof _nextProp3 !== 'symbol';
10896 break;
10897 }
10898
10899 default:
10900 {
10901 setProp(domElement, tag, _propKey13, _nextProp3, nextProps, _lastProp7);
10902 }
10903 }
10904 }
10905 }
10906
10907 return;
10908 }
10909
10910 case 'img':
10911 case 'link':
10912 case 'area':
10913 case 'base':
10914 case 'br':
10915 case 'col':
10916 case 'embed':
10917 case 'hr':
10918 case 'keygen':
10919 case 'meta':
10920 case 'param':
10921 case 'source':
10922 case 'track':
10923 case 'wbr':
10924 case 'menuitem':
10925 {
10926 // Void elements
10927 for (var _propKey14 in lastProps) {
10928 var _lastProp8 = lastProps[_propKey14];
10929
10930 if (lastProps.hasOwnProperty(_propKey14) && _lastProp8 != null && !nextProps.hasOwnProperty(_propKey14)) {
10931 setProp(domElement, tag, _propKey14, null, nextProps, _lastProp8);
10932 }
10933 }
10934
10935 for (var _propKey15 in nextProps) {
10936 var _nextProp4 = nextProps[_propKey15];
10937 var _lastProp9 = lastProps[_propKey15];
10938
10939 if (nextProps.hasOwnProperty(_propKey15) && _nextProp4 !== _lastProp9 && (_nextProp4 != null || _lastProp9 != null)) {
10940 switch (_propKey15) {
10941 case 'children':
10942 case 'dangerouslySetInnerHTML':
10943 {
10944 if (_nextProp4 != null) {
10945 // TODO: Can we make this a DEV warning to avoid this deny list?
10946 throw new Error(tag + " is a void element tag and must neither have `children` nor " + 'use `dangerouslySetInnerHTML`.');
10947 }
10948
10949 break;
10950 }
10951 // defaultChecked and defaultValue are ignored by setProp
10952
10953 default:
10954 {
10955 setProp(domElement, tag, _propKey15, _nextProp4, nextProps, _lastProp9);
10956 }
10957 }
10958 }
10959 }
10960
10961 return;
10962 }
10963
10964 default:
10965 {
10966 if (isCustomElement(tag)) {
10967 for (var _propKey16 in lastProps) {
10968 var _lastProp10 = lastProps[_propKey16];
10969
10970 if (lastProps.hasOwnProperty(_propKey16) && _lastProp10 !== undefined && !nextProps.hasOwnProperty(_propKey16)) {
10971 setPropOnCustomElement(domElement, tag, _propKey16, undefined, nextProps, _lastProp10);
10972 }
10973 }
10974
10975 for (var _propKey17 in nextProps) {
10976 var _nextProp5 = nextProps[_propKey17];
10977 var _lastProp11 = lastProps[_propKey17];
10978
10979 if (nextProps.hasOwnProperty(_propKey17) && _nextProp5 !== _lastProp11 && (_nextProp5 !== undefined || _lastProp11 !== undefined)) {
10980 setPropOnCustomElement(domElement, tag, _propKey17, _nextProp5, nextProps, _lastProp11);
10981 }
10982 }
10983
10984 return;
10985 }
10986 }
10987 }
10988
10989 for (var _propKey18 in lastProps) {
10990 var _lastProp12 = lastProps[_propKey18];
10991
10992 if (lastProps.hasOwnProperty(_propKey18) && _lastProp12 != null && !nextProps.hasOwnProperty(_propKey18)) {
10993 setProp(domElement, tag, _propKey18, null, nextProps, _lastProp12);
10994 }
10995 }
10996
10997 for (var _propKey19 in nextProps) {
10998 var _nextProp6 = nextProps[_propKey19];
10999 var _lastProp13 = lastProps[_propKey19];
11000
11001 if (nextProps.hasOwnProperty(_propKey19) && _nextProp6 !== _lastProp13 && (_nextProp6 != null || _lastProp13 != null)) {
11002 setProp(domElement, tag, _propKey19, _nextProp6, nextProps, _lastProp13);
11003 }
11004 }
11005}
11006
11007function getPossibleStandardName(propName) {
11008 {
11009 var lowerCasedName = propName.toLowerCase();
11010
11011 if (!possibleStandardNames.hasOwnProperty(lowerCasedName)) {
11012 return null;
11013 }
11014
11015 return possibleStandardNames[lowerCasedName] || null;
11016 }
11017}
11018
11019function getPropNameFromAttributeName(attrName) {
11020 switch (attrName) {
11021 case 'class':
11022 return 'className';
11023
11024 case 'for':
11025 return 'htmlFor';
11026 // TODO: The rest of the aliases.
11027
11028 default:
11029 return attrName;
11030 }
11031}
11032
11033function getPropsFromElement(domElement) {
11034 var serverDifferences = {};
11035 var attributes = domElement.attributes;
11036
11037 for (var i = 0; i < attributes.length; i++) {
11038 var attr = attributes[i];
11039 serverDifferences[getPropNameFromAttributeName(attr.name)] = attr.name.toLowerCase() === 'style' ? getStylesObjectFromElement(domElement) : attr.value;
11040 }
11041
11042 return serverDifferences;
11043}
11044
11045function getStylesObjectFromElement(domElement) {
11046 var serverValueInObjectForm = {};
11047 var style = domElement.style;
11048
11049 for (var i = 0; i < style.length; i++) {
11050 var styleName = style[i]; // TODO: We should use the original prop value here if it is equivalent.
11051 // TODO: We could use the original client capitalization if the equivalent
11052 // other capitalization exists in the DOM.
11053
11054 serverValueInObjectForm[styleName] = style.getPropertyValue(styleName);
11055 }
11056
11057 return serverValueInObjectForm;
11058}
11059
11060function diffHydratedStyles(domElement, value, serverDifferences) {
11061 if (value != null && typeof value !== 'object') {
11062 {
11063 error('The `style` prop expects a mapping from style properties to values, ' + "not a string. For example, style={{marginRight: spacing + 'em'}} when " + 'using JSX.');
11064 }
11065
11066 return;
11067 }
11068
11069 if (canDiffStyleForHydrationWarning) {
11070 // First we compare the string form and see if it's equivalent.
11071 // This lets us bail out on anything that used to pass in this form.
11072 // It also lets us compare anything that's not parsed by this browser.
11073 var clientValue = createDangerousStringForStyles(value);
11074 var serverValue = domElement.getAttribute('style');
11075
11076 if (serverValue === clientValue) {
11077 return;
11078 }
11079
11080 var normalizedClientValue = normalizeMarkupForTextOrAttribute(clientValue);
11081 var normalizedServerValue = normalizeMarkupForTextOrAttribute(serverValue);
11082
11083 if (normalizedServerValue === normalizedClientValue) {
11084 return;
11085 } // Otherwise, we create the object from the DOM for the diff view.
11086
11087
11088 serverDifferences.style = getStylesObjectFromElement(domElement);
11089 }
11090}
11091
11092function hydrateAttribute(domElement, propKey, attributeName, value, extraAttributes, serverDifferences) {
11093 extraAttributes.delete(attributeName);
11094 var serverValue = domElement.getAttribute(attributeName);
11095
11096 if (serverValue === null) {
11097 switch (typeof value) {
11098 case 'undefined':
11099 case 'function':
11100 case 'symbol':
11101 case 'boolean':
11102 return;
11103 }
11104 } else {
11105 if (value == null) ; else {
11106 switch (typeof value) {
11107 case 'function':
11108 case 'symbol':
11109 case 'boolean':
11110 break;
11111
11112 default:
11113 {
11114 {
11115 checkAttributeStringCoercion(value, propKey);
11116 }
11117
11118 if (serverValue === '' + value) {
11119 return;
11120 }
11121 }
11122 }
11123 }
11124 }
11125
11126 warnForPropDifference(propKey, serverValue, value, serverDifferences);
11127}
11128
11129function hydrateBooleanAttribute(domElement, propKey, attributeName, value, extraAttributes, serverDifferences) {
11130 extraAttributes.delete(attributeName);
11131 var serverValue = domElement.getAttribute(attributeName);
11132
11133 if (serverValue === null) {
11134 switch (typeof value) {
11135 case 'function':
11136 case 'symbol':
11137 return;
11138 }
11139
11140 if (!value) {
11141 return;
11142 }
11143 } else {
11144 switch (typeof value) {
11145 case 'function':
11146 case 'symbol':
11147 break;
11148
11149 default:
11150 {
11151 if (value) {
11152 // If this was a boolean, it doesn't matter what the value is
11153 // the fact that we have it is the same as the expected.
11154 // As long as it's positive.
11155 return;
11156 }
11157 }
11158 }
11159 }
11160
11161 warnForPropDifference(propKey, serverValue, value, serverDifferences);
11162}
11163
11164function hydrateOverloadedBooleanAttribute(domElement, propKey, attributeName, value, extraAttributes, serverDifferences) {
11165 extraAttributes.delete(attributeName);
11166 var serverValue = domElement.getAttribute(attributeName);
11167
11168 if (serverValue === null) {
11169 switch (typeof value) {
11170 case 'undefined':
11171 case 'function':
11172 case 'symbol':
11173 return;
11174
11175 default:
11176 if (value === false) {
11177 return;
11178 }
11179
11180 }
11181 } else {
11182 if (value == null) ; else {
11183 switch (typeof value) {
11184 case 'function':
11185 case 'symbol':
11186 break;
11187
11188 case 'boolean':
11189 if (value === true && serverValue === '') {
11190 return;
11191 }
11192
11193 break;
11194
11195 default:
11196 {
11197 {
11198 checkAttributeStringCoercion(value, propKey);
11199 }
11200
11201 if (serverValue === '' + value) {
11202 return;
11203 }
11204 }
11205 }
11206 }
11207 }
11208
11209 warnForPropDifference(propKey, serverValue, value, serverDifferences);
11210}
11211
11212function hydrateBooleanishAttribute(domElement, propKey, attributeName, value, extraAttributes, serverDifferences) {
11213 extraAttributes.delete(attributeName);
11214 var serverValue = domElement.getAttribute(attributeName);
11215
11216 if (serverValue === null) {
11217 switch (typeof value) {
11218 case 'undefined':
11219 case 'function':
11220 case 'symbol':
11221 return;
11222 }
11223 } else {
11224 if (value == null) ; else {
11225 switch (typeof value) {
11226 case 'function':
11227 case 'symbol':
11228 break;
11229
11230 default:
11231 {
11232 {
11233 checkAttributeStringCoercion(value, attributeName);
11234 }
11235
11236 if (serverValue === '' + value) {
11237 return;
11238 }
11239 }
11240 }
11241 }
11242 }
11243
11244 warnForPropDifference(propKey, serverValue, value, serverDifferences);
11245}
11246
11247function hydrateNumericAttribute(domElement, propKey, attributeName, value, extraAttributes, serverDifferences) {
11248 extraAttributes.delete(attributeName);
11249 var serverValue = domElement.getAttribute(attributeName);
11250
11251 if (serverValue === null) {
11252 switch (typeof value) {
11253 case 'undefined':
11254 case 'function':
11255 case 'symbol':
11256 case 'boolean':
11257 return;
11258
11259 default:
11260 if (isNaN(value)) {
11261 return;
11262 }
11263
11264 }
11265 } else {
11266 if (value == null) ; else {
11267 switch (typeof value) {
11268 case 'function':
11269 case 'symbol':
11270 case 'boolean':
11271 break;
11272
11273 default:
11274 {
11275 if (isNaN(value)) {
11276 // We had an attribute but shouldn't have had one, so read it
11277 // for the error message.
11278 break;
11279 }
11280
11281 {
11282 checkAttributeStringCoercion(value, propKey);
11283 }
11284
11285 if (serverValue === '' + value) {
11286 return;
11287 }
11288 }
11289 }
11290 }
11291 }
11292
11293 warnForPropDifference(propKey, serverValue, value, serverDifferences);
11294}
11295
11296function hydratePositiveNumericAttribute(domElement, propKey, attributeName, value, extraAttributes, serverDifferences) {
11297 extraAttributes.delete(attributeName);
11298 var serverValue = domElement.getAttribute(attributeName);
11299
11300 if (serverValue === null) {
11301 switch (typeof value) {
11302 case 'undefined':
11303 case 'function':
11304 case 'symbol':
11305 case 'boolean':
11306 return;
11307
11308 default:
11309 if (isNaN(value) || value < 1) {
11310 return;
11311 }
11312
11313 }
11314 } else {
11315 if (value == null) ; else {
11316 switch (typeof value) {
11317 case 'function':
11318 case 'symbol':
11319 case 'boolean':
11320 break;
11321
11322 default:
11323 {
11324 if (isNaN(value) || value < 1) {
11325 // We had an attribute but shouldn't have had one, so read it
11326 // for the error message.
11327 break;
11328 }
11329
11330 {
11331 checkAttributeStringCoercion(value, propKey);
11332 }
11333
11334 if (serverValue === '' + value) {
11335 return;
11336 }
11337 }
11338 }
11339 }
11340 }
11341
11342 warnForPropDifference(propKey, serverValue, value, serverDifferences);
11343}
11344
11345function hydrateSanitizedAttribute(domElement, propKey, attributeName, value, extraAttributes, serverDifferences) {
11346 extraAttributes.delete(attributeName);
11347 var serverValue = domElement.getAttribute(attributeName);
11348
11349 if (serverValue === null) {
11350 switch (typeof value) {
11351 case 'undefined':
11352 case 'function':
11353 case 'symbol':
11354 case 'boolean':
11355 return;
11356 }
11357 } else {
11358 if (value == null) ; else {
11359 switch (typeof value) {
11360 case 'function':
11361 case 'symbol':
11362 case 'boolean':
11363 break;
11364
11365 default:
11366 {
11367 {
11368 checkAttributeStringCoercion(value, propKey);
11369 }
11370
11371 var sanitizedValue = sanitizeURL('' + value);
11372
11373 if (serverValue === sanitizedValue) {
11374 return;
11375 }
11376 }
11377 }
11378 }
11379 }
11380
11381 warnForPropDifference(propKey, serverValue, value, serverDifferences);
11382}
11383
11384function diffHydratedCustomComponent(domElement, tag, props, hostContext, extraAttributes, serverDifferences) {
11385 for (var propKey in props) {
11386 if (!props.hasOwnProperty(propKey)) {
11387 continue;
11388 }
11389
11390 var value = props[propKey];
11391
11392 if (value == null) {
11393 continue;
11394 }
11395
11396 if (registrationNameDependencies.hasOwnProperty(propKey)) {
11397 if (typeof value !== 'function') {
11398 warnForInvalidEventListener(propKey, value);
11399 }
11400
11401 continue;
11402 }
11403
11404 if (props.suppressHydrationWarning === true) {
11405 // Don't bother comparing. We're ignoring all these warnings.
11406 continue;
11407 } // Validate that the properties correspond to their expected values.
11408
11409
11410 switch (propKey) {
11411 case 'children':
11412 {
11413 if (typeof value === 'string' || typeof value === 'number') {
11414 warnForPropDifference('children', domElement.textContent, value, serverDifferences);
11415 }
11416
11417 continue;
11418 }
11419 // Checked above already
11420
11421 case 'suppressContentEditableWarning':
11422 case 'suppressHydrationWarning':
11423 case 'defaultValue':
11424 case 'defaultChecked':
11425 case 'innerHTML':
11426 case 'ref':
11427 // Noop
11428 continue;
11429
11430 case 'dangerouslySetInnerHTML':
11431 var serverHTML = domElement.innerHTML;
11432 var nextHtml = value ? value.__html : undefined;
11433
11434 if (nextHtml != null) {
11435 var expectedHTML = normalizeHTML(domElement, nextHtml);
11436 warnForPropDifference(propKey, serverHTML, expectedHTML, serverDifferences);
11437 }
11438
11439 continue;
11440
11441 case 'style':
11442 extraAttributes.delete(propKey);
11443 diffHydratedStyles(domElement, value, serverDifferences);
11444 continue;
11445
11446 case 'offsetParent':
11447 case 'offsetTop':
11448 case 'offsetLeft':
11449 case 'offsetWidth':
11450 case 'offsetHeight':
11451 case 'isContentEditable':
11452 case 'outerText':
11453 case 'outerHTML':
11454 extraAttributes.delete(propKey.toLowerCase());
11455
11456 {
11457 error('Assignment to read-only property will result in a no-op: `%s`', propKey);
11458 }
11459
11460 continue;
11461 // Fall through
11462
11463 case 'className':
11464 // className is a special cased property on the server to render as an attribute.
11465 extraAttributes.delete('class');
11466 var serverValue = getValueForAttributeOnCustomComponent(domElement, 'class', value);
11467 warnForPropDifference('className', serverValue, value, serverDifferences);
11468 continue;
11469
11470 default:
11471 {
11472 // This is a DEV-only path
11473 var hostContextDev = hostContext;
11474 var hostContextProd = hostContextDev.context;
11475
11476 if (hostContextProd === HostContextNamespaceNone && tag !== 'svg' && tag !== 'math') {
11477 extraAttributes.delete(propKey.toLowerCase());
11478 } else {
11479 extraAttributes.delete(propKey);
11480 }
11481
11482 var valueOnCustomComponent = getValueForAttributeOnCustomComponent(domElement, propKey, value);
11483 warnForPropDifference(propKey, valueOnCustomComponent, value, serverDifferences);
11484 }
11485 }
11486 }
11487} // This is the exact URL string we expect that Fizz renders if we provide a function action.
11488// We use this for hydration warnings. It needs to be in sync with Fizz. Maybe makes sense
11489// as a shared module for that reason.
11490
11491
11492var EXPECTED_FORM_ACTION_URL = // eslint-disable-next-line no-script-url
11493"javascript:throw new Error('React form unexpectedly submitted.')";
11494
11495function diffHydratedGenericElement(domElement, tag, props, hostContext, extraAttributes, serverDifferences) {
11496 for (var propKey in props) {
11497 if (!props.hasOwnProperty(propKey)) {
11498 continue;
11499 }
11500
11501 var value = props[propKey];
11502
11503 if (value == null) {
11504 continue;
11505 }
11506
11507 if (registrationNameDependencies.hasOwnProperty(propKey)) {
11508 if (typeof value !== 'function') {
11509 warnForInvalidEventListener(propKey, value);
11510 }
11511
11512 continue;
11513 }
11514
11515 if (props.suppressHydrationWarning === true) {
11516 // Don't bother comparing. We're ignoring all these warnings.
11517 continue;
11518 } // Validate that the properties correspond to their expected values.
11519
11520
11521 switch (propKey) {
11522 case 'children':
11523 {
11524 if (typeof value === 'string' || typeof value === 'number') {
11525 warnForPropDifference('children', domElement.textContent, value, serverDifferences);
11526 }
11527
11528 continue;
11529 }
11530 // Checked above already
11531
11532 case 'suppressContentEditableWarning':
11533 case 'suppressHydrationWarning':
11534 case 'value': // Controlled attributes are not validated
11535
11536 case 'checked': // TODO: Only ignore them on controlled tags.
11537
11538 case 'selected':
11539 case 'defaultValue':
11540 case 'defaultChecked':
11541 case 'innerHTML':
11542 case 'ref':
11543 // Noop
11544 continue;
11545
11546 case 'dangerouslySetInnerHTML':
11547 var serverHTML = domElement.innerHTML;
11548 var nextHtml = value ? value.__html : undefined;
11549
11550 if (nextHtml != null) {
11551 var expectedHTML = normalizeHTML(domElement, nextHtml);
11552
11553 if (serverHTML !== expectedHTML) {
11554 serverDifferences[propKey] = {
11555 __html: serverHTML
11556 };
11557 }
11558 }
11559
11560 continue;
11561
11562 case 'className':
11563 hydrateAttribute(domElement, propKey, 'class', value, extraAttributes, serverDifferences);
11564 continue;
11565
11566 case 'tabIndex':
11567 hydrateAttribute(domElement, propKey, 'tabindex', value, extraAttributes, serverDifferences);
11568 continue;
11569
11570 case 'style':
11571 extraAttributes.delete(propKey);
11572 diffHydratedStyles(domElement, value, serverDifferences);
11573 continue;
11574
11575 case 'multiple':
11576 {
11577 extraAttributes.delete(propKey);
11578 var serverValue = domElement.multiple;
11579 warnForPropDifference(propKey, serverValue, value, serverDifferences);
11580 continue;
11581 }
11582
11583 case 'muted':
11584 {
11585 extraAttributes.delete(propKey);
11586 var _serverValue = domElement.muted;
11587 warnForPropDifference(propKey, _serverValue, value, serverDifferences);
11588 continue;
11589 }
11590
11591 case 'autoFocus':
11592 {
11593 extraAttributes.delete('autofocus');
11594 var _serverValue2 = domElement.autofocus;
11595 warnForPropDifference(propKey, _serverValue2, value, serverDifferences);
11596 continue;
11597 }
11598
11599 case 'src':
11600 case 'href':
11601 {
11602 if (value === '' && // <a href=""> is fine for "reload" links.
11603 !(tag === 'a' && propKey === 'href')) {
11604 {
11605 if (propKey === 'src') {
11606 error('An empty string ("") was passed to the %s attribute. ' + 'This may cause the browser to download the whole page again over the network. ' + 'To fix this, either do not render the element at all ' + 'or pass null to %s instead of an empty string.', propKey, propKey);
11607 } else {
11608 error('An empty string ("") was passed to the %s attribute. ' + 'To fix this, either do not render the element at all ' + 'or pass null to %s instead of an empty string.', propKey, propKey);
11609 }
11610 }
11611
11612 hydrateSanitizedAttribute(domElement, propKey, propKey, null, extraAttributes, serverDifferences);
11613 continue;
11614 }
11615 }
11616
11617 hydrateSanitizedAttribute(domElement, propKey, propKey, value, extraAttributes, serverDifferences);
11618 continue;
11619
11620 case 'action':
11621 case 'formAction':
11622 {
11623 var _serverValue3 = domElement.getAttribute(propKey);
11624
11625 if (typeof value === 'function') {
11626 extraAttributes.delete(propKey.toLowerCase()); // The server can set these extra properties to implement actions.
11627 // So we remove them from the extra attributes warnings.
11628
11629 if (propKey === 'formAction') {
11630 extraAttributes.delete('name');
11631 extraAttributes.delete('formenctype');
11632 extraAttributes.delete('formmethod');
11633 extraAttributes.delete('formtarget');
11634 } else {
11635 extraAttributes.delete('enctype');
11636 extraAttributes.delete('method');
11637 extraAttributes.delete('target');
11638 } // Ideally we should be able to warn if the server value was not a function
11639 // however since the function can return any of these attributes any way it
11640 // wants as a custom progressive enhancement, there's nothing to compare to.
11641 // We can check if the function has the $FORM_ACTION property on the client
11642 // and if it's not, warn, but that's an unnecessary constraint that they
11643 // have to have the extra extension that doesn't do anything on the client.
11644
11645
11646 continue;
11647 } else if (_serverValue3 === EXPECTED_FORM_ACTION_URL) {
11648 extraAttributes.delete(propKey.toLowerCase());
11649 warnForPropDifference(propKey, 'function', value, serverDifferences);
11650 continue;
11651 }
11652
11653 hydrateSanitizedAttribute(domElement, propKey, propKey.toLowerCase(), value, extraAttributes, serverDifferences);
11654 continue;
11655 }
11656
11657 case 'xlinkHref':
11658 hydrateSanitizedAttribute(domElement, propKey, 'xlink:href', value, extraAttributes, serverDifferences);
11659 continue;
11660
11661 case 'contentEditable':
11662 {
11663 // Lower-case Booleanish String
11664 hydrateBooleanishAttribute(domElement, propKey, 'contenteditable', value, extraAttributes, serverDifferences);
11665 continue;
11666 }
11667
11668 case 'spellCheck':
11669 {
11670 // Lower-case Booleanish String
11671 hydrateBooleanishAttribute(domElement, propKey, 'spellcheck', value, extraAttributes, serverDifferences);
11672 continue;
11673 }
11674
11675 case 'draggable':
11676 case 'autoReverse':
11677 case 'externalResourcesRequired':
11678 case 'focusable':
11679 case 'preserveAlpha':
11680 {
11681 // Case-sensitive Booleanish String
11682 hydrateBooleanishAttribute(domElement, propKey, propKey, value, extraAttributes, serverDifferences);
11683 continue;
11684 }
11685
11686 case 'allowFullScreen':
11687 case 'async':
11688 case 'autoPlay':
11689 case 'controls':
11690 case 'default':
11691 case 'defer':
11692 case 'disabled':
11693 case 'disablePictureInPicture':
11694 case 'disableRemotePlayback':
11695 case 'formNoValidate':
11696 case 'hidden':
11697 case 'loop':
11698 case 'noModule':
11699 case 'noValidate':
11700 case 'open':
11701 case 'playsInline':
11702 case 'readOnly':
11703 case 'required':
11704 case 'reversed':
11705 case 'scoped':
11706 case 'seamless':
11707 case 'itemScope':
11708 {
11709 // Some of these need to be lower case to remove them from the extraAttributes list.
11710 hydrateBooleanAttribute(domElement, propKey, propKey.toLowerCase(), value, extraAttributes, serverDifferences);
11711 continue;
11712 }
11713
11714 case 'capture':
11715 case 'download':
11716 {
11717 hydrateOverloadedBooleanAttribute(domElement, propKey, propKey, value, extraAttributes, serverDifferences);
11718 continue;
11719 }
11720
11721 case 'cols':
11722 case 'rows':
11723 case 'size':
11724 case 'span':
11725 {
11726 hydratePositiveNumericAttribute(domElement, propKey, propKey, value, extraAttributes, serverDifferences);
11727 continue;
11728 }
11729
11730 case 'rowSpan':
11731 {
11732 hydrateNumericAttribute(domElement, propKey, 'rowspan', value, extraAttributes, serverDifferences);
11733 continue;
11734 }
11735
11736 case 'start':
11737 {
11738 hydrateNumericAttribute(domElement, propKey, propKey, value, extraAttributes, serverDifferences);
11739 continue;
11740 }
11741
11742 case 'xHeight':
11743 hydrateAttribute(domElement, propKey, 'x-height', value, extraAttributes, serverDifferences);
11744 continue;
11745
11746 case 'xlinkActuate':
11747 hydrateAttribute(domElement, propKey, 'xlink:actuate', value, extraAttributes, serverDifferences);
11748 continue;
11749
11750 case 'xlinkArcrole':
11751 hydrateAttribute(domElement, propKey, 'xlink:arcrole', value, extraAttributes, serverDifferences);
11752 continue;
11753
11754 case 'xlinkRole':
11755 hydrateAttribute(domElement, propKey, 'xlink:role', value, extraAttributes, serverDifferences);
11756 continue;
11757
11758 case 'xlinkShow':
11759 hydrateAttribute(domElement, propKey, 'xlink:show', value, extraAttributes, serverDifferences);
11760 continue;
11761
11762 case 'xlinkTitle':
11763 hydrateAttribute(domElement, propKey, 'xlink:title', value, extraAttributes, serverDifferences);
11764 continue;
11765
11766 case 'xlinkType':
11767 hydrateAttribute(domElement, propKey, 'xlink:type', value, extraAttributes, serverDifferences);
11768 continue;
11769
11770 case 'xmlBase':
11771 hydrateAttribute(domElement, propKey, 'xml:base', value, extraAttributes, serverDifferences);
11772 continue;
11773
11774 case 'xmlLang':
11775 hydrateAttribute(domElement, propKey, 'xml:lang', value, extraAttributes, serverDifferences);
11776 continue;
11777
11778 case 'xmlSpace':
11779 hydrateAttribute(domElement, propKey, 'xml:space', value, extraAttributes, serverDifferences);
11780 continue;
11781
11782 case 'inert':
11783 {
11784 if (value === '' && !didWarnForNewBooleanPropsWithEmptyValue[propKey]) {
11785 didWarnForNewBooleanPropsWithEmptyValue[propKey] = true;
11786
11787 error('Received an empty string for a boolean attribute `%s`. ' + 'This will treat the attribute as if it were false. ' + 'Either pass `false` to silence this warning, or ' + 'pass `true` if you used an empty string in earlier versions of React to indicate this attribute is true.', propKey);
11788 }
11789 }
11790
11791 hydrateBooleanAttribute(domElement, propKey, propKey, value, extraAttributes, serverDifferences);
11792 continue;
11793
11794 default:
11795 {
11796 if ( // shouldIgnoreAttribute
11797 // We have already filtered out null/undefined and reserved words.
11798 propKey.length > 2 && (propKey[0] === 'o' || propKey[0] === 'O') && (propKey[1] === 'n' || propKey[1] === 'N')) {
11799 continue;
11800 }
11801
11802 var attributeName = getAttributeAlias(propKey);
11803 var isMismatchDueToBadCasing = false; // This is a DEV-only path
11804
11805 var hostContextDev = hostContext;
11806 var hostContextProd = hostContextDev.context;
11807
11808 if (hostContextProd === HostContextNamespaceNone && tag !== 'svg' && tag !== 'math') {
11809 extraAttributes.delete(attributeName.toLowerCase());
11810 } else {
11811 var standardName = getPossibleStandardName(propKey);
11812
11813 if (standardName !== null && standardName !== propKey) {
11814 // If an SVG prop is supplied with bad casing, it will
11815 // be successfully parsed from HTML, but will produce a mismatch
11816 // (and would be incorrectly rendered on the client).
11817 // However, we already warn about bad casing elsewhere.
11818 // So we'll skip the misleading extra mismatch warning in this case.
11819 isMismatchDueToBadCasing = true;
11820 extraAttributes.delete(standardName);
11821 }
11822
11823 extraAttributes.delete(attributeName);
11824 }
11825
11826 var _serverValue4 = getValueForAttribute(domElement, attributeName, value);
11827
11828 if (!isMismatchDueToBadCasing) {
11829 warnForPropDifference(propKey, _serverValue4, value, serverDifferences);
11830 }
11831 }
11832 }
11833 }
11834}
11835
11836function hydrateProperties(domElement, tag, props, hostContext) {
11837 {
11838 validatePropertiesInDevelopment(tag, props);
11839 } // TODO: Make sure that we check isMounted before firing any of these events.
11840
11841
11842 switch (tag) {
11843 case 'dialog':
11844 listenToNonDelegatedEvent('cancel', domElement);
11845 listenToNonDelegatedEvent('close', domElement);
11846 break;
11847
11848 case 'iframe':
11849 case 'object':
11850 case 'embed':
11851 // We listen to this event in case to ensure emulated bubble
11852 // listeners still fire for the load event.
11853 listenToNonDelegatedEvent('load', domElement);
11854 break;
11855
11856 case 'video':
11857 case 'audio':
11858 // We listen to these events in case to ensure emulated bubble
11859 // listeners still fire for all the media events.
11860 for (var i = 0; i < mediaEventTypes.length; i++) {
11861 listenToNonDelegatedEvent(mediaEventTypes[i], domElement);
11862 }
11863
11864 break;
11865
11866 case 'source':
11867 // We listen to this event in case to ensure emulated bubble
11868 // listeners still fire for the error event.
11869 listenToNonDelegatedEvent('error', domElement);
11870 break;
11871
11872 case 'img':
11873 case 'image':
11874 case 'link':
11875 // We listen to these events in case to ensure emulated bubble
11876 // listeners still fire for error and load events.
11877 listenToNonDelegatedEvent('error', domElement);
11878 listenToNonDelegatedEvent('load', domElement);
11879 break;
11880
11881 case 'details':
11882 // We listen to this event in case to ensure emulated bubble
11883 // listeners still fire for the toggle event.
11884 listenToNonDelegatedEvent('toggle', domElement);
11885 break;
11886
11887 case 'input':
11888 {
11889 checkControlledValueProps('input', props);
11890 } // We listen to this event in case to ensure emulated bubble
11891 // listeners still fire for the invalid event.
11892
11893
11894 listenToNonDelegatedEvent('invalid', domElement); // TODO: Make sure we check if this is still unmounted or do any clean
11895 // up necessary since we never stop tracking anymore.
11896
11897 validateInputProps(domElement, props); // For input and textarea we current always set the value property at
11898 // post mount to force it to diverge from attributes. However, for
11899 // option and select we don't quite do the same thing and select
11900 // is not resilient to the DOM state changing so we don't do that here.
11901 // TODO: Consider not doing this for input and textarea.
11902
11903 initInput(domElement, props.value, props.defaultValue, props.checked, props.defaultChecked, props.type, props.name, true);
11904 track(domElement);
11905 break;
11906
11907 case 'option':
11908 validateOptionProps(domElement, props);
11909 break;
11910
11911 case 'select':
11912 {
11913 checkControlledValueProps('select', props);
11914 } // We listen to this event in case to ensure emulated bubble
11915 // listeners still fire for the invalid event.
11916
11917
11918 listenToNonDelegatedEvent('invalid', domElement);
11919 validateSelectProps(domElement, props);
11920 break;
11921
11922 case 'textarea':
11923 {
11924 checkControlledValueProps('textarea', props);
11925 } // We listen to this event in case to ensure emulated bubble
11926 // listeners still fire for the invalid event.
11927
11928
11929 listenToNonDelegatedEvent('invalid', domElement); // TODO: Make sure we check if this is still unmounted or do any clean
11930 // up necessary since we never stop tracking anymore.
11931
11932 validateTextareaProps(domElement, props);
11933 initTextarea(domElement, props.value, props.defaultValue, props.children);
11934 track(domElement);
11935 break;
11936 }
11937
11938 var children = props.children; // For text content children we compare against textContent. This
11939 // might match additional HTML that is hidden when we read it using
11940 // textContent. E.g. "foo" will match "f<span>oo</span>" but that still
11941 // satisfies our requirement. Our requirement is not to produce perfect
11942 // HTML and attributes. Ideally we should preserve structure but it's
11943 // ok not to if the visible content is still enough to indicate what
11944 // even listeners these nodes might be wired up to.
11945 // TODO: Warn if there is more than a single textNode as a child.
11946 // TODO: Should we use domElement.firstChild.nodeValue to compare?
11947
11948 if (typeof children === 'string' || typeof children === 'number' || typeof children === 'bigint') {
11949 if ( // $FlowFixMe[unsafe-addition] Flow doesn't want us to use `+` operator with string and bigint
11950 domElement.textContent !== '' + children && props.suppressHydrationWarning !== true && !checkForUnmatchedText(domElement.textContent, children)) {
11951 return false;
11952 }
11953 }
11954
11955 if (props.onScroll != null) {
11956 listenToNonDelegatedEvent('scroll', domElement);
11957 }
11958
11959 if (props.onScrollEnd != null) {
11960 listenToNonDelegatedEvent('scrollend', domElement);
11961 }
11962
11963 if (props.onClick != null) {
11964 // TODO: This cast may not be sound for SVG, MathML or custom elements.
11965 trapClickOnNonInteractiveElement(domElement);
11966 }
11967
11968 return true;
11969}
11970function diffHydratedProperties(domElement, tag, props, hostContext) {
11971 var serverDifferences = {};
11972
11973 {
11974 var extraAttributes = new Set();
11975 var attributes = domElement.attributes;
11976
11977 for (var i = 0; i < attributes.length; i++) {
11978 var name = attributes[i].name.toLowerCase();
11979
11980 switch (name) {
11981 // Controlled attributes are not validated
11982 // TODO: Only ignore them on controlled tags.
11983 case 'value':
11984 break;
11985
11986 case 'checked':
11987 break;
11988
11989 case 'selected':
11990 break;
11991
11992 default:
11993 // Intentionally use the original name.
11994 // See discussion in https://github.com/facebook/react/pull/10676.
11995 extraAttributes.add(attributes[i].name);
11996 }
11997 }
11998
11999 if (isCustomElement(tag)) {
12000 diffHydratedCustomComponent(domElement, tag, props, hostContext, extraAttributes, serverDifferences);
12001 } else {
12002 diffHydratedGenericElement(domElement, tag, props, hostContext, extraAttributes, serverDifferences);
12003 }
12004
12005 if (extraAttributes.size > 0 && props.suppressHydrationWarning !== true) {
12006 warnForExtraAttributes(domElement, extraAttributes, serverDifferences);
12007 }
12008 }
12009
12010 if (Object.keys(serverDifferences).length === 0) {
12011 return null;
12012 }
12013
12014 return serverDifferences;
12015}
12016function hydrateText(textNode, text, parentProps) {
12017 var isDifferent = textNode.nodeValue !== text;
12018
12019 if (isDifferent && (parentProps === null || parentProps.suppressHydrationWarning !== true) && !checkForUnmatchedText(textNode.nodeValue, text)) {
12020 return false;
12021 }
12022
12023 return true;
12024}
12025function diffHydratedText(textNode, text) {
12026 if (textNode.nodeValue === text) {
12027 return null;
12028 }
12029
12030 var normalizedClientText = normalizeMarkupForTextOrAttribute(text);
12031 var normalizedServerText = normalizeMarkupForTextOrAttribute(textNode.nodeValue);
12032
12033 if (normalizedServerText === normalizedClientText) {
12034 return null;
12035 }
12036
12037 return textNode.nodeValue;
12038}
12039function restoreControlledState(domElement, tag, props) {
12040 switch (tag) {
12041 case 'input':
12042 restoreControlledInputState(domElement, props);
12043 return;
12044
12045 case 'textarea':
12046 restoreControlledTextareaState(domElement, props);
12047 return;
12048
12049 case 'select':
12050 restoreControlledSelectState(domElement, props);
12051 return;
12052 }
12053}
12054
12055function validateLinkPropsForStyleResource(props) {
12056 {
12057 // This should only be called when we know we are opting into Resource semantics (i.e. precedence is not null)
12058 var href = props.href,
12059 onLoad = props.onLoad,
12060 onError = props.onError,
12061 disabled = props.disabled;
12062 var includedProps = [];
12063 if (onLoad) includedProps.push('`onLoad`');
12064 if (onError) includedProps.push('`onError`');
12065 if (disabled != null) includedProps.push('`disabled`');
12066 var includedPropsPhrase = propNamesListJoin(includedProps, 'and');
12067 includedPropsPhrase += includedProps.length === 1 ? ' prop' : ' props';
12068 var withArticlePhrase = includedProps.length === 1 ? 'an ' + includedPropsPhrase : 'the ' + includedPropsPhrase;
12069
12070 if (includedProps.length) {
12071 error('React encountered a <link rel="stylesheet" href="%s" ... /> with a `precedence` prop that' + ' also included %s. The presence of loading and error handlers indicates an intent to manage' + ' the stylesheet loading state from your from your Component code and React will not hoist or' + ' deduplicate this stylesheet. If your intent was to have React hoist and deduplciate this stylesheet' + ' using the `precedence` prop remove the %s, otherwise remove the `precedence` prop.', href, withArticlePhrase, includedPropsPhrase);
12072
12073 return true;
12074 }
12075 }
12076
12077 return false;
12078}
12079
12080function propNamesListJoin(list, combinator) {
12081 switch (list.length) {
12082 case 0:
12083 return '';
12084
12085 case 1:
12086 return list[0];
12087
12088 case 2:
12089 return list[0] + ' ' + combinator + ' ' + list[1];
12090
12091 default:
12092 return list.slice(0, -1).join(', ') + ', ' + combinator + ' ' + list[list.length - 1];
12093 }
12094}
12095
12096// We use the existence of the state object as an indicator that the component
12097// is hidden.
12098var OffscreenVisible =
12099/* */
121001;
12101var OffscreenDetached =
12102/* */
121032;
12104var OffscreenPassiveEffectsConnected =
12105/* */
121064;
12107function isOffscreenManual(offscreenFiber) {
12108 return offscreenFiber.memoizedProps !== null && offscreenFiber.memoizedProps.mode === 'manual';
12109}
12110
12111// we wait until the current render is over (either finished or interrupted)
12112// before adding it to the fiber/hook queue. Push to this array so we can
12113// access the queue, fiber, update, et al later.
12114
12115var concurrentQueues = [];
12116var concurrentQueuesIndex = 0;
12117var concurrentlyUpdatedLanes = NoLanes;
12118function finishQueueingConcurrentUpdates() {
12119 var endIndex = concurrentQueuesIndex;
12120 concurrentQueuesIndex = 0;
12121 concurrentlyUpdatedLanes = NoLanes;
12122 var i = 0;
12123
12124 while (i < endIndex) {
12125 var fiber = concurrentQueues[i];
12126 concurrentQueues[i++] = null;
12127 var queue = concurrentQueues[i];
12128 concurrentQueues[i++] = null;
12129 var update = concurrentQueues[i];
12130 concurrentQueues[i++] = null;
12131 var lane = concurrentQueues[i];
12132 concurrentQueues[i++] = null;
12133
12134 if (queue !== null && update !== null) {
12135 var pending = queue.pending;
12136
12137 if (pending === null) {
12138 // This is the first update. Create a circular list.
12139 update.next = update;
12140 } else {
12141 update.next = pending.next;
12142 pending.next = update;
12143 }
12144
12145 queue.pending = update;
12146 }
12147
12148 if (lane !== NoLane) {
12149 markUpdateLaneFromFiberToRoot(fiber, update, lane);
12150 }
12151 }
12152}
12153function getConcurrentlyUpdatedLanes() {
12154 return concurrentlyUpdatedLanes;
12155}
12156
12157function enqueueUpdate$1(fiber, queue, update, lane) {
12158 // Don't update the `childLanes` on the return path yet. If we already in
12159 // the middle of rendering, wait until after it has completed.
12160 concurrentQueues[concurrentQueuesIndex++] = fiber;
12161 concurrentQueues[concurrentQueuesIndex++] = queue;
12162 concurrentQueues[concurrentQueuesIndex++] = update;
12163 concurrentQueues[concurrentQueuesIndex++] = lane;
12164 concurrentlyUpdatedLanes = mergeLanes(concurrentlyUpdatedLanes, lane); // The fiber's `lane` field is used in some places to check if any work is
12165 // scheduled, to perform an eager bailout, so we need to update it immediately.
12166 // TODO: We should probably move this to the "shared" queue instead.
12167
12168 fiber.lanes = mergeLanes(fiber.lanes, lane);
12169 var alternate = fiber.alternate;
12170
12171 if (alternate !== null) {
12172 alternate.lanes = mergeLanes(alternate.lanes, lane);
12173 }
12174}
12175
12176function enqueueConcurrentHookUpdate(fiber, queue, update, lane) {
12177 var concurrentQueue = queue;
12178 var concurrentUpdate = update;
12179 enqueueUpdate$1(fiber, concurrentQueue, concurrentUpdate, lane);
12180 return getRootForUpdatedFiber(fiber);
12181}
12182function enqueueConcurrentHookUpdateAndEagerlyBailout(fiber, queue, update) {
12183 // This function is used to queue an update that doesn't need a rerender. The
12184 // only reason we queue it is in case there's a subsequent higher priority
12185 // update that causes it to be rebased.
12186 var lane = NoLane;
12187 var concurrentQueue = queue;
12188 var concurrentUpdate = update;
12189 enqueueUpdate$1(fiber, concurrentQueue, concurrentUpdate, lane); // Usually we can rely on the upcoming render phase to process the concurrent
12190 // queue. However, since this is a bail out, we're not scheduling any work
12191 // here. So the update we just queued will leak until something else happens
12192 // to schedule work (if ever).
12193 //
12194 // Check if we're currently in the middle of rendering a tree, and if not,
12195 // process the queue immediately to prevent a leak.
12196
12197 var isConcurrentlyRendering = getWorkInProgressRoot() !== null;
12198
12199 if (!isConcurrentlyRendering) {
12200 finishQueueingConcurrentUpdates();
12201 }
12202}
12203function enqueueConcurrentClassUpdate(fiber, queue, update, lane) {
12204 var concurrentQueue = queue;
12205 var concurrentUpdate = update;
12206 enqueueUpdate$1(fiber, concurrentQueue, concurrentUpdate, lane);
12207 return getRootForUpdatedFiber(fiber);
12208}
12209function enqueueConcurrentRenderForLane(fiber, lane) {
12210 enqueueUpdate$1(fiber, null, null, lane);
12211 return getRootForUpdatedFiber(fiber);
12212} // Calling this function outside this module should only be done for backwards
12213// compatibility and should always be accompanied by a warning.
12214
12215function unsafe_markUpdateLaneFromFiberToRoot(sourceFiber, lane) {
12216 // NOTE: For Hyrum's Law reasons, if an infinite update loop is detected, it
12217 // should throw before `markUpdateLaneFromFiberToRoot` is called. But this is
12218 // undefined behavior and we can change it if we need to; it just so happens
12219 // that, at the time of this writing, there's an internal product test that
12220 // happens to rely on this.
12221 var root = getRootForUpdatedFiber(sourceFiber);
12222 markUpdateLaneFromFiberToRoot(sourceFiber, null, lane);
12223 return root;
12224}
12225
12226function markUpdateLaneFromFiberToRoot(sourceFiber, update, lane) {
12227 // Update the source fiber's lanes
12228 sourceFiber.lanes = mergeLanes(sourceFiber.lanes, lane);
12229 var alternate = sourceFiber.alternate;
12230
12231 if (alternate !== null) {
12232 alternate.lanes = mergeLanes(alternate.lanes, lane);
12233 } // Walk the parent path to the root and update the child lanes.
12234
12235
12236 var isHidden = false;
12237 var parent = sourceFiber.return;
12238 var node = sourceFiber;
12239
12240 while (parent !== null) {
12241 parent.childLanes = mergeLanes(parent.childLanes, lane);
12242 alternate = parent.alternate;
12243
12244 if (alternate !== null) {
12245 alternate.childLanes = mergeLanes(alternate.childLanes, lane);
12246 }
12247
12248 if (parent.tag === OffscreenComponent) {
12249 // Check if this offscreen boundary is currently hidden.
12250 //
12251 // The instance may be null if the Offscreen parent was unmounted. Usually
12252 // the parent wouldn't be reachable in that case because we disconnect
12253 // fibers from the tree when they are deleted. However, there's a weird
12254 // edge case where setState is called on a fiber that was interrupted
12255 // before it ever mounted. Because it never mounts, it also never gets
12256 // deleted. Because it never gets deleted, its return pointer never gets
12257 // disconnected. Which means it may be attached to a deleted Offscreen
12258 // parent node. (This discovery suggests it may be better for memory usage
12259 // if we don't attach the `return` pointer until the commit phase, though
12260 // in order to do that we'd need some other way to track the return
12261 // pointer during the initial render, like on the stack.)
12262 //
12263 // This case is always accompanied by a warning, but we still need to
12264 // account for it. (There may be other cases that we haven't discovered,
12265 // too.)
12266 var offscreenInstance = parent.stateNode;
12267
12268 if (offscreenInstance !== null && !(offscreenInstance._visibility & OffscreenVisible)) {
12269 isHidden = true;
12270 }
12271 }
12272
12273 node = parent;
12274 parent = parent.return;
12275 }
12276
12277 if (isHidden && update !== null && node.tag === HostRoot) {
12278 var root = node.stateNode;
12279 markHiddenUpdate(root, update, lane);
12280 }
12281}
12282
12283function getRootForUpdatedFiber(sourceFiber) {
12284 // TODO: We will detect and infinite update loop and throw even if this fiber
12285 // has already unmounted. This isn't really necessary but it happens to be the
12286 // current behavior we've used for several release cycles. Consider not
12287 // performing this check if the updated fiber already unmounted, since it's
12288 // not possible for that to cause an infinite update loop.
12289 throwIfInfiniteUpdateLoopDetected(); // When a setState happens, we must ensure the root is scheduled. Because
12290 // update queues do not have a backpointer to the root, the only way to do
12291 // this currently is to walk up the return path. This used to not be a big
12292 // deal because we would have to walk up the return path to set
12293 // the `childLanes`, anyway, but now those two traversals happen at
12294 // different times.
12295 // TODO: Consider adding a `root` backpointer on the update queue.
12296
12297 detectUpdateOnUnmountedFiber(sourceFiber, sourceFiber);
12298 var node = sourceFiber;
12299 var parent = node.return;
12300
12301 while (parent !== null) {
12302 detectUpdateOnUnmountedFiber(sourceFiber, node);
12303 node = parent;
12304 parent = node.return;
12305 }
12306
12307 return node.tag === HostRoot ? node.stateNode : null;
12308}
12309
12310function detectUpdateOnUnmountedFiber(sourceFiber, parent) {
12311 {
12312 var alternate = parent.alternate;
12313
12314 if (alternate === null && (parent.flags & (Placement | Hydrating)) !== NoFlags$1) {
12315 warnAboutUpdateOnNotYetMountedFiberInDEV(sourceFiber);
12316 }
12317 }
12318}
12319
12320var emptyContextObject = {};
12321
12322{
12323 Object.freeze(emptyContextObject);
12324} // A cursor to the current merged context object on the stack.
12325
12326function hasContextChanged() {
12327 {
12328 return false;
12329 }
12330}
12331
12332function isContextProvider(type) {
12333 {
12334 return false;
12335 }
12336}
12337
12338function processChildContext(fiber, type, parentContext) {
12339 {
12340 return parentContext;
12341 }
12342}
12343
12344function findCurrentUnmaskedContext(fiber) {
12345 {
12346 return emptyContextObject;
12347 }
12348}
12349
12350/* eslint-disable react-internal/prod-error-codes */
12351// Used by React Refresh runtime through DevTools Global Hook.
12352
12353var resolveFamily = null;
12354var failedBoundaries = null;
12355var setRefreshHandler = function (handler) {
12356 {
12357 resolveFamily = handler;
12358 }
12359};
12360function resolveFunctionForHotReloading(type) {
12361 {
12362 if (resolveFamily === null) {
12363 // Hot reloading is disabled.
12364 return type;
12365 }
12366
12367 var family = resolveFamily(type);
12368
12369 if (family === undefined) {
12370 return type;
12371 } // Use the latest known implementation.
12372
12373
12374 return family.current;
12375 }
12376}
12377function resolveClassForHotReloading(type) {
12378 // No implementation differences.
12379 return resolveFunctionForHotReloading(type);
12380}
12381function resolveForwardRefForHotReloading(type) {
12382 {
12383 if (resolveFamily === null) {
12384 // Hot reloading is disabled.
12385 return type;
12386 }
12387
12388 var family = resolveFamily(type);
12389
12390 if (family === undefined) {
12391 // Check if we're dealing with a real forwardRef. Don't want to crash early.
12392 if (type !== null && type !== undefined && typeof type.render === 'function') {
12393 // ForwardRef is special because its resolved .type is an object,
12394 // but it's possible that we only have its inner render function in the map.
12395 // If that inner render function is different, we'll build a new forwardRef type.
12396 var currentRender = resolveFunctionForHotReloading(type.render);
12397
12398 if (type.render !== currentRender) {
12399 var syntheticType = {
12400 $$typeof: REACT_FORWARD_REF_TYPE,
12401 render: currentRender
12402 };
12403
12404 if (type.displayName !== undefined) {
12405 syntheticType.displayName = type.displayName;
12406 }
12407
12408 return syntheticType;
12409 }
12410 }
12411
12412 return type;
12413 } // Use the latest known implementation.
12414
12415
12416 return family.current;
12417 }
12418}
12419function isCompatibleFamilyForHotReloading(fiber, element) {
12420 {
12421 if (resolveFamily === null) {
12422 // Hot reloading is disabled.
12423 return false;
12424 }
12425
12426 var prevType = fiber.elementType;
12427 var nextType = element.type; // If we got here, we know types aren't === equal.
12428
12429 var needsCompareFamilies = false;
12430 var $$typeofNextType = typeof nextType === 'object' && nextType !== null ? nextType.$$typeof : null;
12431
12432 switch (fiber.tag) {
12433 case ClassComponent:
12434 {
12435 if (typeof nextType === 'function') {
12436 needsCompareFamilies = true;
12437 }
12438
12439 break;
12440 }
12441
12442 case FunctionComponent:
12443 {
12444 if (typeof nextType === 'function') {
12445 needsCompareFamilies = true;
12446 } else if ($$typeofNextType === REACT_LAZY_TYPE) {
12447 // We don't know the inner type yet.
12448 // We're going to assume that the lazy inner type is stable,
12449 // and so it is sufficient to avoid reconciling it away.
12450 // We're not going to unwrap or actually use the new lazy type.
12451 needsCompareFamilies = true;
12452 }
12453
12454 break;
12455 }
12456
12457 case ForwardRef:
12458 {
12459 if ($$typeofNextType === REACT_FORWARD_REF_TYPE) {
12460 needsCompareFamilies = true;
12461 } else if ($$typeofNextType === REACT_LAZY_TYPE) {
12462 needsCompareFamilies = true;
12463 }
12464
12465 break;
12466 }
12467
12468 case MemoComponent:
12469 case SimpleMemoComponent:
12470 {
12471 if ($$typeofNextType === REACT_MEMO_TYPE) {
12472 // TODO: if it was but can no longer be simple,
12473 // we shouldn't set this.
12474 needsCompareFamilies = true;
12475 } else if ($$typeofNextType === REACT_LAZY_TYPE) {
12476 needsCompareFamilies = true;
12477 }
12478
12479 break;
12480 }
12481
12482 default:
12483 return false;
12484 } // Check if both types have a family and it's the same one.
12485
12486
12487 if (needsCompareFamilies) {
12488 // Note: memo() and forwardRef() we'll compare outer rather than inner type.
12489 // This means both of them need to be registered to preserve state.
12490 // If we unwrapped and compared the inner types for wrappers instead,
12491 // then we would risk falsely saying two separate memo(Foo)
12492 // calls are equivalent because they wrap the same Foo function.
12493 var prevFamily = resolveFamily(prevType); // $FlowFixMe[not-a-function] found when upgrading Flow
12494
12495 if (prevFamily !== undefined && prevFamily === resolveFamily(nextType)) {
12496 return true;
12497 }
12498 }
12499
12500 return false;
12501 }
12502}
12503function markFailedErrorBoundaryForHotReloading(fiber) {
12504 {
12505 if (resolveFamily === null) {
12506 // Hot reloading is disabled.
12507 return;
12508 }
12509
12510 if (typeof WeakSet !== 'function') {
12511 return;
12512 }
12513
12514 if (failedBoundaries === null) {
12515 failedBoundaries = new WeakSet();
12516 }
12517
12518 failedBoundaries.add(fiber);
12519 }
12520}
12521var scheduleRefresh = function (root, update) {
12522 {
12523 if (resolveFamily === null) {
12524 // Hot reloading is disabled.
12525 return;
12526 }
12527
12528 var staleFamilies = update.staleFamilies,
12529 updatedFamilies = update.updatedFamilies;
12530 flushPassiveEffects();
12531 scheduleFibersWithFamiliesRecursively(root.current, updatedFamilies, staleFamilies);
12532 flushSyncWork$1();
12533 }
12534};
12535var scheduleRoot = function (root, element) {
12536 {
12537 if (root.context !== emptyContextObject) {
12538 // Super edge case: root has a legacy _renderSubtree context
12539 // but we don't know the parentComponent so we can't pass it.
12540 // Just ignore. We'll delete this with _renderSubtree code path later.
12541 return;
12542 }
12543
12544 updateContainerSync(element, root, null, null);
12545 flushSyncWork$1();
12546 }
12547};
12548
12549function scheduleFibersWithFamiliesRecursively(fiber, updatedFamilies, staleFamilies) {
12550 {
12551 var alternate = fiber.alternate,
12552 child = fiber.child,
12553 sibling = fiber.sibling,
12554 tag = fiber.tag,
12555 type = fiber.type;
12556 var candidateType = null;
12557
12558 switch (tag) {
12559 case FunctionComponent:
12560 case SimpleMemoComponent:
12561 case ClassComponent:
12562 candidateType = type;
12563 break;
12564
12565 case ForwardRef:
12566 candidateType = type.render;
12567 break;
12568 }
12569
12570 if (resolveFamily === null) {
12571 throw new Error('Expected resolveFamily to be set during hot reload.');
12572 }
12573
12574 var needsRender = false;
12575 var needsRemount = false;
12576
12577 if (candidateType !== null) {
12578 var family = resolveFamily(candidateType);
12579
12580 if (family !== undefined) {
12581 if (staleFamilies.has(family)) {
12582 needsRemount = true;
12583 } else if (updatedFamilies.has(family)) {
12584 if (tag === ClassComponent) {
12585 needsRemount = true;
12586 } else {
12587 needsRender = true;
12588 }
12589 }
12590 }
12591 }
12592
12593 if (failedBoundaries !== null) {
12594 if (failedBoundaries.has(fiber) || // $FlowFixMe[incompatible-use] found when upgrading Flow
12595 alternate !== null && failedBoundaries.has(alternate)) {
12596 needsRemount = true;
12597 }
12598 }
12599
12600 if (needsRemount) {
12601 fiber._debugNeedsRemount = true;
12602 }
12603
12604 if (needsRemount || needsRender) {
12605 var root = enqueueConcurrentRenderForLane(fiber, SyncLane);
12606
12607 if (root !== null) {
12608 scheduleUpdateOnFiber(root, fiber, SyncLane);
12609 }
12610 }
12611
12612 if (child !== null && !needsRemount) {
12613 scheduleFibersWithFamiliesRecursively(child, updatedFamilies, staleFamilies);
12614 }
12615
12616 if (sibling !== null) {
12617 scheduleFibersWithFamiliesRecursively(sibling, updatedFamilies, staleFamilies);
12618 }
12619 }
12620}
12621
12622var findHostInstancesForRefresh = function (root, families) {
12623 {
12624 var hostInstances = new Set();
12625 var types = new Set(families.map(function (family) {
12626 return family.current;
12627 }));
12628 findHostInstancesForMatchingFibersRecursively(root.current, types, hostInstances);
12629 return hostInstances;
12630 }
12631};
12632
12633function findHostInstancesForMatchingFibersRecursively(fiber, types, hostInstances) {
12634 {
12635 var child = fiber.child,
12636 sibling = fiber.sibling,
12637 tag = fiber.tag,
12638 type = fiber.type;
12639 var candidateType = null;
12640
12641 switch (tag) {
12642 case FunctionComponent:
12643 case SimpleMemoComponent:
12644 case ClassComponent:
12645 candidateType = type;
12646 break;
12647
12648 case ForwardRef:
12649 candidateType = type.render;
12650 break;
12651 }
12652
12653 var didMatch = false;
12654
12655 if (candidateType !== null) {
12656 if (types.has(candidateType)) {
12657 didMatch = true;
12658 }
12659 }
12660
12661 if (didMatch) {
12662 // We have a match. This only drills down to the closest host components.
12663 // There's no need to search deeper because for the purpose of giving
12664 // visual feedback, "flashing" outermost parent rectangles is sufficient.
12665 findHostInstancesForFiberShallowly(fiber, hostInstances);
12666 } else {
12667 // If there's no match, maybe there will be one further down in the child tree.
12668 if (child !== null) {
12669 findHostInstancesForMatchingFibersRecursively(child, types, hostInstances);
12670 }
12671 }
12672
12673 if (sibling !== null) {
12674 findHostInstancesForMatchingFibersRecursively(sibling, types, hostInstances);
12675 }
12676 }
12677}
12678
12679function findHostInstancesForFiberShallowly(fiber, hostInstances) {
12680 {
12681 var foundHostInstances = findChildHostInstancesForFiberShallowly(fiber, hostInstances);
12682
12683 if (foundHostInstances) {
12684 return;
12685 } // If we didn't find any host children, fallback to closest host parent.
12686
12687
12688 var node = fiber;
12689
12690 while (true) {
12691 switch (node.tag) {
12692 case HostSingleton:
12693 case HostComponent:
12694 hostInstances.add(node.stateNode);
12695 return;
12696
12697 case HostPortal:
12698 hostInstances.add(node.stateNode.containerInfo);
12699 return;
12700
12701 case HostRoot:
12702 hostInstances.add(node.stateNode.containerInfo);
12703 return;
12704 }
12705
12706 if (node.return === null) {
12707 throw new Error('Expected to reach root first.');
12708 }
12709
12710 node = node.return;
12711 }
12712 }
12713}
12714
12715function findChildHostInstancesForFiberShallowly(fiber, hostInstances) {
12716 {
12717 var node = fiber;
12718 var foundHostInstances = false;
12719
12720 while (true) {
12721 if (node.tag === HostComponent || node.tag === HostHoistable || (node.tag === HostSingleton )) {
12722 // We got a match.
12723 foundHostInstances = true;
12724 hostInstances.add(node.stateNode); // There may still be more, so keep searching.
12725 } else if (node.child !== null) {
12726 node.child.return = node;
12727 node = node.child;
12728 continue;
12729 }
12730
12731 if (node === fiber) {
12732 return foundHostInstances;
12733 }
12734
12735 while (node.sibling === null) {
12736 if (node.return === null || node.return === fiber) {
12737 return foundHostInstances;
12738 }
12739
12740 node = node.return;
12741 }
12742
12743 node.sibling.return = node.return;
12744 node = node.sibling;
12745 }
12746 }
12747
12748 return false;
12749}
12750
12751var ReactStrictModeWarnings = {
12752 recordUnsafeLifecycleWarnings: function (fiber, instance) {},
12753 flushPendingUnsafeLifecycleWarnings: function () {},
12754 recordLegacyContextWarning: function (fiber, instance) {},
12755 flushLegacyContextWarning: function () {},
12756 discardPendingWarnings: function () {}
12757};
12758
12759{
12760 var findStrictRoot = function (fiber) {
12761 var maybeStrictRoot = null;
12762 var node = fiber;
12763
12764 while (node !== null) {
12765 if (node.mode & StrictLegacyMode) {
12766 maybeStrictRoot = node;
12767 }
12768
12769 node = node.return;
12770 }
12771
12772 return maybeStrictRoot;
12773 };
12774
12775 var setToSortedString = function (set) {
12776 var array = [];
12777 set.forEach(function (value) {
12778 array.push(value);
12779 });
12780 return array.sort().join(', ');
12781 };
12782
12783 var pendingComponentWillMountWarnings = [];
12784 var pendingUNSAFE_ComponentWillMountWarnings = [];
12785 var pendingComponentWillReceivePropsWarnings = [];
12786 var pendingUNSAFE_ComponentWillReceivePropsWarnings = [];
12787 var pendingComponentWillUpdateWarnings = [];
12788 var pendingUNSAFE_ComponentWillUpdateWarnings = []; // Tracks components we have already warned about.
12789
12790 var didWarnAboutUnsafeLifecycles = new Set();
12791
12792 ReactStrictModeWarnings.recordUnsafeLifecycleWarnings = function (fiber, instance) {
12793 // Dedupe strategy: Warn once per component.
12794 if (didWarnAboutUnsafeLifecycles.has(fiber.type)) {
12795 return;
12796 }
12797
12798 if (typeof instance.componentWillMount === 'function' && // Don't warn about react-lifecycles-compat polyfilled components.
12799 instance.componentWillMount.__suppressDeprecationWarning !== true) {
12800 pendingComponentWillMountWarnings.push(fiber);
12801 }
12802
12803 if (fiber.mode & StrictLegacyMode && typeof instance.UNSAFE_componentWillMount === 'function') {
12804 pendingUNSAFE_ComponentWillMountWarnings.push(fiber);
12805 }
12806
12807 if (typeof instance.componentWillReceiveProps === 'function' && instance.componentWillReceiveProps.__suppressDeprecationWarning !== true) {
12808 pendingComponentWillReceivePropsWarnings.push(fiber);
12809 }
12810
12811 if (fiber.mode & StrictLegacyMode && typeof instance.UNSAFE_componentWillReceiveProps === 'function') {
12812 pendingUNSAFE_ComponentWillReceivePropsWarnings.push(fiber);
12813 }
12814
12815 if (typeof instance.componentWillUpdate === 'function' && instance.componentWillUpdate.__suppressDeprecationWarning !== true) {
12816 pendingComponentWillUpdateWarnings.push(fiber);
12817 }
12818
12819 if (fiber.mode & StrictLegacyMode && typeof instance.UNSAFE_componentWillUpdate === 'function') {
12820 pendingUNSAFE_ComponentWillUpdateWarnings.push(fiber);
12821 }
12822 };
12823
12824 ReactStrictModeWarnings.flushPendingUnsafeLifecycleWarnings = function () {
12825 // We do an initial pass to gather component names
12826 var componentWillMountUniqueNames = new Set();
12827
12828 if (pendingComponentWillMountWarnings.length > 0) {
12829 pendingComponentWillMountWarnings.forEach(function (fiber) {
12830 componentWillMountUniqueNames.add(getComponentNameFromFiber(fiber) || 'Component');
12831 didWarnAboutUnsafeLifecycles.add(fiber.type);
12832 });
12833 pendingComponentWillMountWarnings = [];
12834 }
12835
12836 var UNSAFE_componentWillMountUniqueNames = new Set();
12837
12838 if (pendingUNSAFE_ComponentWillMountWarnings.length > 0) {
12839 pendingUNSAFE_ComponentWillMountWarnings.forEach(function (fiber) {
12840 UNSAFE_componentWillMountUniqueNames.add(getComponentNameFromFiber(fiber) || 'Component');
12841 didWarnAboutUnsafeLifecycles.add(fiber.type);
12842 });
12843 pendingUNSAFE_ComponentWillMountWarnings = [];
12844 }
12845
12846 var componentWillReceivePropsUniqueNames = new Set();
12847
12848 if (pendingComponentWillReceivePropsWarnings.length > 0) {
12849 pendingComponentWillReceivePropsWarnings.forEach(function (fiber) {
12850 componentWillReceivePropsUniqueNames.add(getComponentNameFromFiber(fiber) || 'Component');
12851 didWarnAboutUnsafeLifecycles.add(fiber.type);
12852 });
12853 pendingComponentWillReceivePropsWarnings = [];
12854 }
12855
12856 var UNSAFE_componentWillReceivePropsUniqueNames = new Set();
12857
12858 if (pendingUNSAFE_ComponentWillReceivePropsWarnings.length > 0) {
12859 pendingUNSAFE_ComponentWillReceivePropsWarnings.forEach(function (fiber) {
12860 UNSAFE_componentWillReceivePropsUniqueNames.add(getComponentNameFromFiber(fiber) || 'Component');
12861 didWarnAboutUnsafeLifecycles.add(fiber.type);
12862 });
12863 pendingUNSAFE_ComponentWillReceivePropsWarnings = [];
12864 }
12865
12866 var componentWillUpdateUniqueNames = new Set();
12867
12868 if (pendingComponentWillUpdateWarnings.length > 0) {
12869 pendingComponentWillUpdateWarnings.forEach(function (fiber) {
12870 componentWillUpdateUniqueNames.add(getComponentNameFromFiber(fiber) || 'Component');
12871 didWarnAboutUnsafeLifecycles.add(fiber.type);
12872 });
12873 pendingComponentWillUpdateWarnings = [];
12874 }
12875
12876 var UNSAFE_componentWillUpdateUniqueNames = new Set();
12877
12878 if (pendingUNSAFE_ComponentWillUpdateWarnings.length > 0) {
12879 pendingUNSAFE_ComponentWillUpdateWarnings.forEach(function (fiber) {
12880 UNSAFE_componentWillUpdateUniqueNames.add(getComponentNameFromFiber(fiber) || 'Component');
12881 didWarnAboutUnsafeLifecycles.add(fiber.type);
12882 });
12883 pendingUNSAFE_ComponentWillUpdateWarnings = [];
12884 } // Finally, we flush all the warnings
12885 // UNSAFE_ ones before the deprecated ones, since they'll be 'louder'
12886
12887
12888 if (UNSAFE_componentWillMountUniqueNames.size > 0) {
12889 var sortedNames = setToSortedString(UNSAFE_componentWillMountUniqueNames);
12890
12891 error('Using UNSAFE_componentWillMount in strict mode is not recommended and may indicate bugs in your code. ' + 'See https://react.dev/link/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);
12892 }
12893
12894 if (UNSAFE_componentWillReceivePropsUniqueNames.size > 0) {
12895 var _sortedNames = setToSortedString(UNSAFE_componentWillReceivePropsUniqueNames);
12896
12897 error('Using UNSAFE_componentWillReceiveProps in strict mode is not recommended ' + 'and may indicate bugs in your code. ' + 'See https://react.dev/link/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://react.dev/link/derived-state\n' + '\nPlease update the following components: %s', _sortedNames);
12898 }
12899
12900 if (UNSAFE_componentWillUpdateUniqueNames.size > 0) {
12901 var _sortedNames2 = setToSortedString(UNSAFE_componentWillUpdateUniqueNames);
12902
12903 error('Using UNSAFE_componentWillUpdate in strict mode is not recommended ' + 'and may indicate bugs in your code. ' + 'See https://react.dev/link/unsafe-component-lifecycles for details.\n\n' + '* Move data fetching code or side effects to componentDidUpdate.\n' + '\nPlease update the following components: %s', _sortedNames2);
12904 }
12905
12906 if (componentWillMountUniqueNames.size > 0) {
12907 var _sortedNames3 = setToSortedString(componentWillMountUniqueNames);
12908
12909 warn('componentWillMount has been renamed, and is not recommended for use. ' + 'See https://react.dev/link/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 18.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);
12910 }
12911
12912 if (componentWillReceivePropsUniqueNames.size > 0) {
12913 var _sortedNames4 = setToSortedString(componentWillReceivePropsUniqueNames);
12914
12915 warn('componentWillReceiveProps has been renamed, and is not recommended for use. ' + 'See https://react.dev/link/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://react.dev/link/derived-state\n' + '* Rename componentWillReceiveProps to UNSAFE_componentWillReceiveProps to suppress ' + 'this warning in non-strict mode. In React 18.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);
12916 }
12917
12918 if (componentWillUpdateUniqueNames.size > 0) {
12919 var _sortedNames5 = setToSortedString(componentWillUpdateUniqueNames);
12920
12921 warn('componentWillUpdate has been renamed, and is not recommended for use. ' + 'See https://react.dev/link/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 18.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);
12922 }
12923 };
12924
12925 var pendingLegacyContextWarning = new Map(); // Tracks components we have already warned about.
12926
12927 var didWarnAboutLegacyContext = new Set();
12928
12929 ReactStrictModeWarnings.recordLegacyContextWarning = function (fiber, instance) {
12930 var strictRoot = findStrictRoot(fiber);
12931
12932 if (strictRoot === null) {
12933 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.');
12934
12935 return;
12936 } // Dedup strategy: Warn once per component.
12937
12938
12939 if (didWarnAboutLegacyContext.has(fiber.type)) {
12940 return;
12941 }
12942
12943 var warningsForRoot = pendingLegacyContextWarning.get(strictRoot);
12944
12945 if (fiber.type.contextTypes != null || fiber.type.childContextTypes != null || instance !== null && typeof instance.getChildContext === 'function') {
12946 if (warningsForRoot === undefined) {
12947 warningsForRoot = [];
12948 pendingLegacyContextWarning.set(strictRoot, warningsForRoot);
12949 }
12950
12951 warningsForRoot.push(fiber);
12952 }
12953 };
12954
12955 ReactStrictModeWarnings.flushLegacyContextWarning = function () {
12956 pendingLegacyContextWarning.forEach(function (fiberArray, strictRoot) {
12957 if (fiberArray.length === 0) {
12958 return;
12959 }
12960
12961 var firstFiber = fiberArray[0];
12962 var uniqueNames = new Set();
12963 fiberArray.forEach(function (fiber) {
12964 uniqueNames.add(getComponentNameFromFiber(fiber) || 'Component');
12965 didWarnAboutLegacyContext.add(fiber.type);
12966 });
12967 var sortedNames = setToSortedString(uniqueNames);
12968
12969 try {
12970 setCurrentFiber(firstFiber);
12971
12972 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://react.dev/link/legacy-context', sortedNames);
12973 } finally {
12974 resetCurrentFiber();
12975 }
12976 });
12977 };
12978
12979 ReactStrictModeWarnings.discardPendingWarnings = function () {
12980 pendingComponentWillMountWarnings = [];
12981 pendingUNSAFE_ComponentWillMountWarnings = [];
12982 pendingComponentWillReceivePropsWarnings = [];
12983 pendingUNSAFE_ComponentWillReceivePropsWarnings = [];
12984 pendingComponentWillUpdateWarnings = [];
12985 pendingUNSAFE_ComponentWillUpdateWarnings = [];
12986 pendingLegacyContextWarning = new Map();
12987 };
12988}
12989
12990var CapturedStacks = new WeakMap();
12991function createCapturedValueAtFiber(value, source) {
12992 // If the value is an error, call this function immediately after it is thrown
12993 // so the stack is accurate.
12994 var stack;
12995
12996 if (typeof value === 'object' && value !== null) {
12997 var capturedStack = CapturedStacks.get(value);
12998
12999 if (typeof capturedStack === 'string') {
13000 stack = capturedStack;
13001 } else {
13002 stack = getStackByFiberInDevAndProd(source);
13003 CapturedStacks.set(value, stack);
13004 }
13005 } else {
13006 stack = getStackByFiberInDevAndProd(source);
13007 }
13008
13009 return {
13010 value: value,
13011 source: source,
13012 stack: stack
13013 };
13014}
13015function createCapturedValueFromError(value, stack) {
13016 if (typeof stack === 'string') {
13017 CapturedStacks.set(value, stack);
13018 }
13019
13020 return {
13021 value: value,
13022 source: null,
13023 stack: stack
13024 };
13025}
13026
13027// Intentionally not using it yet to derisk the initial implementation, because
13028// the way we push/pop these values is a bit unusual. If there's a mistake, I'd
13029// rather the ids be wrong than crash the whole reconciler.
13030
13031var forkStack = [];
13032var forkStackIndex = 0;
13033var treeForkProvider = null;
13034var treeForkCount = 0;
13035var idStack = [];
13036var idStackIndex = 0;
13037var treeContextProvider = null;
13038var treeContextId = 1;
13039var treeContextOverflow = '';
13040function isForkedChild(workInProgress) {
13041 warnIfNotHydrating();
13042 return (workInProgress.flags & Forked) !== NoFlags$1;
13043}
13044function getForksAtLevel(workInProgress) {
13045 warnIfNotHydrating();
13046 return treeForkCount;
13047}
13048function getTreeId() {
13049 var overflow = treeContextOverflow;
13050 var idWithLeadingBit = treeContextId;
13051 var id = idWithLeadingBit & ~getLeadingBit(idWithLeadingBit);
13052 return id.toString(32) + overflow;
13053}
13054function pushTreeFork(workInProgress, totalChildren) {
13055 // This is called right after we reconcile an array (or iterator) of child
13056 // fibers, because that's the only place where we know how many children in
13057 // the whole set without doing extra work later, or storing addtional
13058 // information on the fiber.
13059 //
13060 // That's why this function is separate from pushTreeId — it's called during
13061 // the render phase of the fork parent, not the child, which is where we push
13062 // the other context values.
13063 //
13064 // In the Fizz implementation this is much simpler because the child is
13065 // rendered in the same callstack as the parent.
13066 //
13067 // It might be better to just add a `forks` field to the Fiber type. It would
13068 // make this module simpler.
13069 warnIfNotHydrating();
13070 forkStack[forkStackIndex++] = treeForkCount;
13071 forkStack[forkStackIndex++] = treeForkProvider;
13072 treeForkProvider = workInProgress;
13073 treeForkCount = totalChildren;
13074}
13075function pushTreeId(workInProgress, totalChildren, index) {
13076 warnIfNotHydrating();
13077 idStack[idStackIndex++] = treeContextId;
13078 idStack[idStackIndex++] = treeContextOverflow;
13079 idStack[idStackIndex++] = treeContextProvider;
13080 treeContextProvider = workInProgress;
13081 var baseIdWithLeadingBit = treeContextId;
13082 var baseOverflow = treeContextOverflow; // The leftmost 1 marks the end of the sequence, non-inclusive. It's not part
13083 // of the id; we use it to account for leading 0s.
13084
13085 var baseLength = getBitLength(baseIdWithLeadingBit) - 1;
13086 var baseId = baseIdWithLeadingBit & ~(1 << baseLength);
13087 var slot = index + 1;
13088 var length = getBitLength(totalChildren) + baseLength; // 30 is the max length we can store without overflowing, taking into
13089 // consideration the leading 1 we use to mark the end of the sequence.
13090
13091 if (length > 30) {
13092 // We overflowed the bitwise-safe range. Fall back to slower algorithm.
13093 // This branch assumes the length of the base id is greater than 5; it won't
13094 // work for smaller ids, because you need 5 bits per character.
13095 //
13096 // We encode the id in multiple steps: first the base id, then the
13097 // remaining digits.
13098 //
13099 // Each 5 bit sequence corresponds to a single base 32 character. So for
13100 // example, if the current id is 23 bits long, we can convert 20 of those
13101 // bits into a string of 4 characters, with 3 bits left over.
13102 //
13103 // First calculate how many bits in the base id represent a complete
13104 // sequence of characters.
13105 var numberOfOverflowBits = baseLength - baseLength % 5; // Then create a bitmask that selects only those bits.
13106
13107 var newOverflowBits = (1 << numberOfOverflowBits) - 1; // Select the bits, and convert them to a base 32 string.
13108
13109 var newOverflow = (baseId & newOverflowBits).toString(32); // Now we can remove those bits from the base id.
13110
13111 var restOfBaseId = baseId >> numberOfOverflowBits;
13112 var restOfBaseLength = baseLength - numberOfOverflowBits; // Finally, encode the rest of the bits using the normal algorithm. Because
13113 // we made more room, this time it won't overflow.
13114
13115 var restOfLength = getBitLength(totalChildren) + restOfBaseLength;
13116 var restOfNewBits = slot << restOfBaseLength;
13117 var id = restOfNewBits | restOfBaseId;
13118 var overflow = newOverflow + baseOverflow;
13119 treeContextId = 1 << restOfLength | id;
13120 treeContextOverflow = overflow;
13121 } else {
13122 // Normal path
13123 var newBits = slot << baseLength;
13124
13125 var _id = newBits | baseId;
13126
13127 var _overflow = baseOverflow;
13128 treeContextId = 1 << length | _id;
13129 treeContextOverflow = _overflow;
13130 }
13131}
13132function pushMaterializedTreeId(workInProgress) {
13133 warnIfNotHydrating(); // This component materialized an id. This will affect any ids that appear
13134 // in its children.
13135
13136 var returnFiber = workInProgress.return;
13137
13138 if (returnFiber !== null) {
13139 var numberOfForks = 1;
13140 var slotIndex = 0;
13141 pushTreeFork(workInProgress, numberOfForks);
13142 pushTreeId(workInProgress, numberOfForks, slotIndex);
13143 }
13144}
13145
13146function getBitLength(number) {
13147 return 32 - clz32(number);
13148}
13149
13150function getLeadingBit(id) {
13151 return 1 << getBitLength(id) - 1;
13152}
13153
13154function popTreeContext(workInProgress) {
13155 // Restore the previous values.
13156 // This is a bit more complicated than other context-like modules in Fiber
13157 // because the same Fiber may appear on the stack multiple times and for
13158 // different reasons. We have to keep popping until the work-in-progress is
13159 // no longer at the top of the stack.
13160 while (workInProgress === treeForkProvider) {
13161 treeForkProvider = forkStack[--forkStackIndex];
13162 forkStack[forkStackIndex] = null;
13163 treeForkCount = forkStack[--forkStackIndex];
13164 forkStack[forkStackIndex] = null;
13165 }
13166
13167 while (workInProgress === treeContextProvider) {
13168 treeContextProvider = idStack[--idStackIndex];
13169 idStack[idStackIndex] = null;
13170 treeContextOverflow = idStack[--idStackIndex];
13171 idStack[idStackIndex] = null;
13172 treeContextId = idStack[--idStackIndex];
13173 idStack[idStackIndex] = null;
13174 }
13175}
13176function getSuspendedTreeContext() {
13177 warnIfNotHydrating();
13178
13179 if (treeContextProvider !== null) {
13180 return {
13181 id: treeContextId,
13182 overflow: treeContextOverflow
13183 };
13184 } else {
13185 return null;
13186 }
13187}
13188function restoreSuspendedTreeContext(workInProgress, suspendedContext) {
13189 warnIfNotHydrating();
13190 idStack[idStackIndex++] = treeContextId;
13191 idStack[idStackIndex++] = treeContextOverflow;
13192 idStack[idStackIndex++] = treeContextProvider;
13193 treeContextId = suspendedContext.id;
13194 treeContextOverflow = suspendedContext.overflow;
13195 treeContextProvider = workInProgress;
13196}
13197
13198function warnIfNotHydrating() {
13199 {
13200 if (!getIsHydrating()) {
13201 error('Expected to be hydrating. This is a bug in React. Please file ' + 'an issue.');
13202 }
13203 }
13204}
13205
13206var maxRowLength = 120;
13207var idealDepth = 15;
13208
13209function findNotableNode(node, indent) {
13210 if (node.serverProps === undefined && node.serverTail.length === 0 && node.children.length === 1 && node.distanceFromLeaf > 3 && node.distanceFromLeaf > idealDepth - indent) {
13211 // This is not an interesting node for contextual purposes so we can skip it.
13212 var child = node.children[0];
13213 return findNotableNode(child, indent);
13214 }
13215
13216 return node;
13217}
13218
13219function indentation(indent) {
13220 return ' ' + ' '.repeat(indent);
13221}
13222
13223function added(indent) {
13224 return '+ ' + ' '.repeat(indent);
13225}
13226
13227function removed(indent) {
13228 return '- ' + ' '.repeat(indent);
13229}
13230
13231function describeFiberType(fiber) {
13232 switch (fiber.tag) {
13233 case HostHoistable:
13234 case HostSingleton:
13235 case HostComponent:
13236 return fiber.type;
13237
13238 case LazyComponent:
13239 return 'Lazy';
13240
13241 case SuspenseComponent:
13242 return 'Suspense';
13243
13244 case SuspenseListComponent:
13245 return 'SuspenseList';
13246
13247 case FunctionComponent:
13248 case SimpleMemoComponent:
13249 var fn = fiber.type;
13250 return fn.displayName || fn.name || null;
13251
13252 case ForwardRef:
13253 var render = fiber.type.render;
13254 return render.displayName || render.name || null;
13255
13256 case ClassComponent:
13257 var ctr = fiber.type;
13258 return ctr.displayName || ctr.name || null;
13259
13260 default:
13261 // Skip
13262 return null;
13263 }
13264}
13265
13266var needsEscaping = /["'&<>\n\t]/;
13267
13268function describeTextNode(content, maxLength) {
13269 if (needsEscaping.test(content)) {
13270 var encoded = JSON.stringify(content);
13271
13272 if (encoded.length > maxLength - 2) {
13273 if (maxLength < 8) {
13274 return '{"..."}';
13275 }
13276
13277 return '{' + encoded.slice(0, maxLength - 7) + '..."}';
13278 }
13279
13280 return '{' + encoded + '}';
13281 } else {
13282 if (content.length > maxLength) {
13283 if (maxLength < 5) {
13284 return '{"..."}';
13285 }
13286
13287 return content.slice(0, maxLength - 3) + '...';
13288 }
13289
13290 return content;
13291 }
13292}
13293
13294function describeTextDiff(clientText, serverProps, indent) {
13295 var maxLength = maxRowLength - indent * 2;
13296
13297 if (serverProps === null) {
13298 return added(indent) + describeTextNode(clientText, maxLength) + '\n';
13299 } else if (typeof serverProps === 'string') {
13300 var serverText = serverProps;
13301 var firstDiff = 0;
13302
13303 for (; firstDiff < serverText.length && firstDiff < clientText.length; firstDiff++) {
13304 if (serverText.charCodeAt(firstDiff) !== clientText.charCodeAt(firstDiff)) {
13305 break;
13306 }
13307 }
13308
13309 if (firstDiff > maxLength - 8 && firstDiff > 10) {
13310 // The first difference between the two strings would be cut off, so cut off in
13311 // the beginning instead.
13312 clientText = '...' + clientText.slice(firstDiff - 8);
13313 serverText = '...' + serverText.slice(firstDiff - 8);
13314 }
13315
13316 return added(indent) + describeTextNode(clientText, maxLength) + '\n' + removed(indent) + describeTextNode(serverText, maxLength) + '\n';
13317 } else {
13318 return indentation(indent) + describeTextNode(clientText, maxLength) + '\n';
13319 }
13320}
13321
13322function objectName(object) {
13323 // $FlowFixMe[method-unbinding]
13324 var name = Object.prototype.toString.call(object);
13325 return name.replace(/^\[object (.*)\]$/, function (m, p0) {
13326 return p0;
13327 });
13328}
13329
13330function describeValue(value, maxLength) {
13331 switch (typeof value) {
13332 case 'string':
13333 {
13334 var encoded = JSON.stringify(value);
13335
13336 if (encoded.length > maxLength) {
13337 if (maxLength < 5) {
13338 return '"..."';
13339 }
13340
13341 return encoded.slice(0, maxLength - 4) + '..."';
13342 }
13343
13344 return encoded;
13345 }
13346
13347 case 'object':
13348 {
13349 if (value === null) {
13350 return 'null';
13351 }
13352
13353 if (isArray(value)) {
13354 return '[...]';
13355 }
13356
13357 if (value.$$typeof === REACT_ELEMENT_TYPE) {
13358 var type = getComponentNameFromType(value.type);
13359 return type ? '<' + type + '>' : '<...>';
13360 }
13361
13362 var name = objectName(value);
13363
13364 if (name === 'Object') {
13365 var properties = '';
13366 maxLength -= 2;
13367
13368 for (var propName in value) {
13369 if (!value.hasOwnProperty(propName)) {
13370 continue;
13371 }
13372
13373 var jsonPropName = JSON.stringify(propName);
13374
13375 if (jsonPropName !== '"' + propName + '"') {
13376 propName = jsonPropName;
13377 }
13378
13379 maxLength -= propName.length - 2;
13380 var propValue = describeValue(value[propName], maxLength < 15 ? maxLength : 15);
13381 maxLength -= propValue.length;
13382
13383 if (maxLength < 0) {
13384 properties += properties === '' ? '...' : ', ...';
13385 break;
13386 }
13387
13388 properties += (properties === '' ? '' : ',') + propName + ':' + propValue;
13389 }
13390
13391 return '{' + properties + '}';
13392 }
13393
13394 return name;
13395 }
13396
13397 case 'function':
13398 {
13399 var _name = value.displayName || value.name;
13400
13401 return _name ? 'function ' + _name : 'function';
13402 }
13403
13404 default:
13405 // eslint-disable-next-line react-internal/safe-string-coercion
13406 return String(value);
13407 }
13408}
13409
13410function describePropValue(value, maxLength) {
13411 if (typeof value === 'string' && !needsEscaping.test(value)) {
13412 if (value.length > maxLength - 2) {
13413 if (maxLength < 5) {
13414 return '"..."';
13415 }
13416
13417 return '"' + value.slice(0, maxLength - 5) + '..."';
13418 }
13419
13420 return '"' + value + '"';
13421 }
13422
13423 return '{' + describeValue(value, maxLength - 2) + '}';
13424}
13425
13426function describeCollapsedElement(type, props, indent) {
13427 // This function tries to fit the props into a single line for non-essential elements.
13428 // We also ignore children because we're not going deeper.
13429 var maxLength = maxRowLength - indent * 2 - type.length - 2;
13430 var content = '';
13431
13432 for (var propName in props) {
13433 if (!props.hasOwnProperty(propName)) {
13434 continue;
13435 }
13436
13437 if (propName === 'children') {
13438 // Ignored.
13439 continue;
13440 }
13441
13442 var propValue = describePropValue(props[propName], 15);
13443 maxLength -= propName.length + propValue.length + 2;
13444
13445 if (maxLength < 0) {
13446 content += ' ...';
13447 break;
13448 }
13449
13450 content += ' ' + propName + '=' + propValue;
13451 }
13452
13453 return indentation(indent) + '<' + type + content + '>\n';
13454}
13455
13456function describeExpandedElement(type, props, rowPrefix) {
13457 // This function tries to fit the props into a single line for non-essential elements.
13458 // We also ignore children because we're not going deeper.
13459 var remainingRowLength = maxRowLength - rowPrefix.length - type.length; // We add the properties to a set so we can choose later whether we'll put it on one
13460 // line or multiple lines.
13461
13462 var properties = [];
13463
13464 for (var propName in props) {
13465 if (!props.hasOwnProperty(propName)) {
13466 continue;
13467 }
13468
13469 if (propName === 'children') {
13470 // Ignored.
13471 continue;
13472 }
13473
13474 var maxLength = maxRowLength - rowPrefix.length - propName.length - 1;
13475 var propValue = describePropValue(props[propName], maxLength);
13476 remainingRowLength -= propName.length + propValue.length + 2;
13477 properties.push(propName + '=' + propValue);
13478 }
13479
13480 if (properties.length === 0) {
13481 return rowPrefix + '<' + type + '>\n';
13482 } else if (remainingRowLength > 0) {
13483 // We can fit all on one row.
13484 return rowPrefix + '<' + type + ' ' + properties.join(' ') + '>\n';
13485 } else {
13486 // Split into one row per property:
13487 return rowPrefix + '<' + type + '\n' + rowPrefix + ' ' + properties.join('\n' + rowPrefix + ' ') + '\n' + rowPrefix + '>\n';
13488 }
13489}
13490
13491function describePropertiesDiff(clientObject, serverObject, indent) {
13492 var properties = '';
13493 var remainingServerProperties = assign({}, serverObject);
13494
13495 for (var propName in clientObject) {
13496 if (!clientObject.hasOwnProperty(propName)) {
13497 continue;
13498 }
13499
13500 delete remainingServerProperties[propName];
13501 var maxLength = maxRowLength - indent * 2 - propName.length - 2;
13502 var clientValue = clientObject[propName];
13503 var clientPropValue = describeValue(clientValue, maxLength);
13504
13505 if (serverObject.hasOwnProperty(propName)) {
13506 var serverValue = serverObject[propName];
13507 var serverPropValue = describeValue(serverValue, maxLength);
13508 properties += added(indent) + propName + ': ' + clientPropValue + '\n';
13509 properties += removed(indent) + propName + ': ' + serverPropValue + '\n';
13510 } else {
13511 properties += added(indent) + propName + ': ' + clientPropValue + '\n';
13512 }
13513 }
13514
13515 for (var _propName in remainingServerProperties) {
13516 if (!remainingServerProperties.hasOwnProperty(_propName)) {
13517 continue;
13518 }
13519
13520 var _maxLength = maxRowLength - indent * 2 - _propName.length - 2;
13521
13522 var _serverValue = remainingServerProperties[_propName];
13523
13524 var _serverPropValue = describeValue(_serverValue, _maxLength);
13525
13526 properties += removed(indent) + _propName + ': ' + _serverPropValue + '\n';
13527 }
13528
13529 return properties;
13530}
13531
13532function describeElementDiff(type, clientProps, serverProps, indent) {
13533 var content = ''; // Maps any previously unmatched lower case server prop name to its full prop name
13534
13535 var serverPropNames = new Map();
13536
13537 for (var propName in serverProps) {
13538 if (!serverProps.hasOwnProperty(propName)) {
13539 continue;
13540 }
13541
13542 serverPropNames.set(propName.toLowerCase(), propName);
13543 }
13544
13545 if (serverPropNames.size === 1 && serverPropNames.has('children')) {
13546 content += describeExpandedElement(type, clientProps, indentation(indent));
13547 } else {
13548 for (var _propName2 in clientProps) {
13549 if (!clientProps.hasOwnProperty(_propName2)) {
13550 continue;
13551 }
13552
13553 if (_propName2 === 'children') {
13554 // Handled below.
13555 continue;
13556 }
13557
13558 var maxLength = maxRowLength - (indent + 1) * 2 - _propName2.length - 1;
13559 var serverPropName = serverPropNames.get(_propName2.toLowerCase());
13560
13561 if (serverPropName !== undefined) {
13562 serverPropNames.delete(_propName2.toLowerCase()); // There's a diff here.
13563
13564 var clientValue = clientProps[_propName2];
13565 var serverValue = serverProps[serverPropName];
13566 var clientPropValue = describePropValue(clientValue, maxLength);
13567 var serverPropValue = describePropValue(serverValue, maxLength);
13568
13569 if (typeof clientValue === 'object' && clientValue !== null && typeof serverValue === 'object' && serverValue !== null && objectName(clientValue) === 'Object' && objectName(serverValue) === 'Object' && ( // Only do the diff if the object has a lot of keys or was shortened.
13570 Object.keys(clientValue).length > 2 || Object.keys(serverValue).length > 2 || clientPropValue.indexOf('...') > -1 || serverPropValue.indexOf('...') > -1)) {
13571 // We're comparing two plain objects. We can diff the nested objects instead.
13572 content += indentation(indent + 1) + _propName2 + '={{\n' + describePropertiesDiff(clientValue, serverValue, indent + 2) + indentation(indent + 1) + '}}\n';
13573 } else {
13574 content += added(indent + 1) + _propName2 + '=' + clientPropValue + '\n';
13575 content += removed(indent + 1) + _propName2 + '=' + serverPropValue + '\n';
13576 }
13577 } else {
13578 // Considered equal.
13579 content += indentation(indent + 1) + _propName2 + '=' + describePropValue(clientProps[_propName2], maxLength) + '\n';
13580 }
13581 }
13582
13583 serverPropNames.forEach(function (propName) {
13584 if (propName === 'children') {
13585 // Handled below.
13586 return;
13587 }
13588
13589 var maxLength = maxRowLength - (indent + 1) * 2 - propName.length - 1;
13590 content += removed(indent + 1) + propName + '=' + describePropValue(serverProps[propName], maxLength) + '\n';
13591 });
13592
13593 if (content === '') {
13594 // No properties
13595 content = indentation(indent) + '<' + type + '>\n';
13596 } else {
13597 // Had properties
13598 content = indentation(indent) + '<' + type + '\n' + content + indentation(indent) + '>\n';
13599 }
13600 }
13601
13602 var serverChildren = serverProps.children;
13603 var clientChildren = clientProps.children;
13604
13605 if (typeof serverChildren === 'string' || typeof serverChildren === 'number' || typeof serverChildren === 'bigint') {
13606 // There's a diff of the children.
13607 // $FlowFixMe[unsafe-addition]
13608 var serverText = '' + serverChildren;
13609 var clientText = '';
13610
13611 if (typeof clientChildren === 'string' || typeof clientChildren === 'number' || typeof clientChildren === 'bigint') {
13612 // $FlowFixMe[unsafe-addition]
13613 clientText = '' + clientChildren;
13614 }
13615
13616 content += describeTextDiff(clientText, serverText, indent + 1);
13617 } else if (typeof clientChildren === 'string' || typeof clientChildren === 'number' || typeof clientChildren === 'bigint') {
13618 // The client has children but it's not considered a difference from the server.
13619 // $FlowFixMe[unsafe-addition]
13620 content += describeTextDiff('' + clientChildren, undefined, indent + 1);
13621 }
13622
13623 return content;
13624}
13625
13626function describeSiblingFiber(fiber, indent) {
13627 var type = describeFiberType(fiber);
13628
13629 if (type === null) {
13630 // Skip this type of fiber. We currently treat this as a fragment
13631 // so it's just part of the parent's children.
13632 var flatContent = '';
13633 var childFiber = fiber.child;
13634
13635 while (childFiber) {
13636 flatContent += describeSiblingFiber(childFiber, indent);
13637 childFiber = childFiber.sibling;
13638 }
13639
13640 return flatContent;
13641 }
13642
13643 return indentation(indent) + '<' + type + '>' + '\n';
13644}
13645
13646function describeNode(node, indent) {
13647 var skipToNode = findNotableNode(node, indent);
13648
13649 if (skipToNode !== node && (node.children.length !== 1 || node.children[0] !== skipToNode)) {
13650 return indentation(indent) + '...\n' + describeNode(skipToNode, indent + 1);
13651 } // Prefix with any server components for context
13652
13653
13654 var parentContent = '';
13655 var debugInfo = node.fiber._debugInfo;
13656
13657 if (debugInfo) {
13658 for (var i = 0; i < debugInfo.length; i++) {
13659 var serverComponentName = debugInfo[i].name;
13660
13661 if (typeof serverComponentName === 'string') {
13662 parentContent += indentation(indent) + '<' + serverComponentName + '>' + '\n';
13663 indent++;
13664 }
13665 }
13666 } // Self
13667
13668
13669 var selfContent = ''; // We use the pending props since we might be generating a diff before the complete phase
13670 // when something throws.
13671
13672 var clientProps = node.fiber.pendingProps;
13673
13674 if (node.fiber.tag === HostText) {
13675 // Text Node
13676 selfContent = describeTextDiff(clientProps, node.serverProps, indent);
13677 } else {
13678 var type = describeFiberType(node.fiber);
13679
13680 if (type !== null) {
13681 // Element Node
13682 if (node.serverProps === undefined) {
13683 // Just a reference node for context.
13684 selfContent = describeCollapsedElement(type, clientProps, indent);
13685 indent++;
13686 } else if (node.serverProps === null) {
13687 selfContent = describeExpandedElement(type, clientProps, added(indent)); // If this was an insertion we won't step down further. Any tail
13688 // are considered siblings so we don't indent.
13689 // TODO: Model this a little better.
13690 } else if (typeof node.serverProps === 'string') {
13691 {
13692 error('Should not have matched a non HostText fiber to a Text node. This is a bug in React.');
13693 }
13694 } else {
13695 selfContent = describeElementDiff(type, clientProps, node.serverProps, indent);
13696 indent++;
13697 }
13698 }
13699 } // Compute children
13700
13701
13702 var childContent = '';
13703 var childFiber = node.fiber.child;
13704 var diffIdx = 0;
13705
13706 while (childFiber && diffIdx < node.children.length) {
13707 var childNode = node.children[diffIdx];
13708
13709 if (childNode.fiber === childFiber) {
13710 // This was a match in the diff.
13711 childContent += describeNode(childNode, indent);
13712 diffIdx++;
13713 } else {
13714 // This is an unrelated previous sibling.
13715 childContent += describeSiblingFiber(childFiber, indent);
13716 }
13717
13718 childFiber = childFiber.sibling;
13719 }
13720
13721 if (childFiber && node.children.length > 0) {
13722 // If we had any further siblings after the last mismatch, we can't be sure if it's
13723 // actually a valid match since it might not have found a match. So we exclude next
13724 // siblings to avoid confusion.
13725 childContent += indentation(indent) + '...' + '\n';
13726 } // Deleted tail nodes
13727
13728
13729 var serverTail = node.serverTail;
13730
13731 for (var _i = 0; _i < serverTail.length; _i++) {
13732 var tailNode = serverTail[_i];
13733
13734 if (typeof tailNode === 'string') {
13735 // Removed text node
13736 childContent += removed(indent) + describeTextNode(tailNode, maxRowLength - indent * 2) + '\n';
13737 } else {
13738 // Removed element
13739 childContent += describeExpandedElement(tailNode.type, tailNode.props, removed(indent));
13740 }
13741 }
13742
13743 return parentContent + selfContent + childContent;
13744}
13745
13746function describeDiff(rootNode) {
13747 try {
13748 return '\n\n' + describeNode(rootNode, 0);
13749 } catch (x) {
13750 return '';
13751 }
13752}
13753
13754// This may have been an insertion or a hydration.
13755
13756var hydrationParentFiber = null;
13757var nextHydratableInstance = null;
13758var isHydrating = false; // This flag allows for warning supression when we expect there to be mismatches
13759// due to earlier mismatches or a suspended fiber.
13760
13761var didSuspendOrErrorDEV = false; // Hydration differences found that haven't yet been logged.
13762
13763var hydrationDiffRootDEV = null; // Hydration errors that were thrown inside this boundary
13764
13765var hydrationErrors = null;
13766var rootOrSingletonContext = false; // Builds a common ancestor tree from the root down for collecting diffs.
13767
13768function buildHydrationDiffNode(fiber, distanceFromLeaf) {
13769 if (fiber.return === null) {
13770 // We're at the root.
13771 if (hydrationDiffRootDEV === null) {
13772 hydrationDiffRootDEV = {
13773 fiber: fiber,
13774 children: [],
13775 serverProps: undefined,
13776 serverTail: [],
13777 distanceFromLeaf: distanceFromLeaf
13778 };
13779 } else if (hydrationDiffRootDEV.fiber !== fiber) {
13780 throw new Error('Saw multiple hydration diff roots in a pass. This is a bug in React.');
13781 } else if (hydrationDiffRootDEV.distanceFromLeaf > distanceFromLeaf) {
13782 hydrationDiffRootDEV.distanceFromLeaf = distanceFromLeaf;
13783 }
13784
13785 return hydrationDiffRootDEV;
13786 }
13787
13788 var siblings = buildHydrationDiffNode(fiber.return, distanceFromLeaf + 1).children; // The same node may already exist in the parent. Since we currently always render depth first
13789 // and rerender if we suspend or terminate early, if a shared ancestor was added we should still
13790 // be inside of that shared ancestor which means it was the last one to be added. If this changes
13791 // we may have to scan the whole set.
13792
13793 if (siblings.length > 0 && siblings[siblings.length - 1].fiber === fiber) {
13794 var existing = siblings[siblings.length - 1];
13795
13796 if (existing.distanceFromLeaf > distanceFromLeaf) {
13797 existing.distanceFromLeaf = distanceFromLeaf;
13798 }
13799
13800 return existing;
13801 }
13802
13803 var newNode = {
13804 fiber: fiber,
13805 children: [],
13806 serverProps: undefined,
13807 serverTail: [],
13808 distanceFromLeaf: distanceFromLeaf
13809 };
13810 siblings.push(newNode);
13811 return newNode;
13812}
13813
13814function warnIfHydrating() {
13815 {
13816 if (isHydrating) {
13817 error('We should not be hydrating here. This is a bug in React. Please file a bug.');
13818 }
13819 }
13820}
13821
13822function markDidThrowWhileHydratingDEV() {
13823 {
13824 didSuspendOrErrorDEV = true;
13825 }
13826}
13827
13828function enterHydrationState(fiber) {
13829
13830 var parentInstance = fiber.stateNode.containerInfo;
13831 nextHydratableInstance = getFirstHydratableChildWithinContainer(parentInstance);
13832 hydrationParentFiber = fiber;
13833 isHydrating = true;
13834 hydrationErrors = null;
13835 didSuspendOrErrorDEV = false;
13836 hydrationDiffRootDEV = null;
13837 rootOrSingletonContext = true;
13838 return true;
13839}
13840
13841function reenterHydrationStateFromDehydratedSuspenseInstance(fiber, suspenseInstance, treeContext) {
13842
13843 nextHydratableInstance = getFirstHydratableChildWithinSuspenseInstance(suspenseInstance);
13844 hydrationParentFiber = fiber;
13845 isHydrating = true;
13846 hydrationErrors = null;
13847 didSuspendOrErrorDEV = false;
13848 hydrationDiffRootDEV = null;
13849 rootOrSingletonContext = false;
13850
13851 if (treeContext !== null) {
13852 restoreSuspendedTreeContext(fiber, treeContext);
13853 }
13854
13855 return true;
13856}
13857
13858function warnNonHydratedInstance(fiber, rejectedCandidate) {
13859 {
13860 if (didSuspendOrErrorDEV) {
13861 // Inside a boundary that already suspended. We're currently rendering the
13862 // siblings of a suspended node. The mismatch may be due to the missing
13863 // data, so it's probably a false positive.
13864 return;
13865 } // Add this fiber to the diff tree.
13866
13867
13868 var diffNode = buildHydrationDiffNode(fiber, 0); // We use null as a signal that there was no node to match.
13869
13870 diffNode.serverProps = null;
13871
13872 if (rejectedCandidate !== null) {
13873 var description = describeHydratableInstanceForDevWarnings(rejectedCandidate);
13874 diffNode.serverTail.push(description);
13875 }
13876 }
13877}
13878
13879function tryHydrateInstance(fiber, nextInstance, hostContext) {
13880 // fiber is a HostComponent Fiber
13881 var instance = canHydrateInstance(nextInstance, fiber.type, fiber.pendingProps, rootOrSingletonContext);
13882
13883 if (instance !== null) {
13884 fiber.stateNode = instance;
13885
13886 {
13887 if (!didSuspendOrErrorDEV) {
13888 var differences = diffHydratedPropsForDevWarnings(instance, fiber.type, fiber.pendingProps, hostContext);
13889
13890 if (differences !== null) {
13891 var diffNode = buildHydrationDiffNode(fiber, 0);
13892 diffNode.serverProps = differences;
13893 }
13894 }
13895 }
13896
13897 hydrationParentFiber = fiber;
13898 nextHydratableInstance = getFirstHydratableChild(instance);
13899 rootOrSingletonContext = false;
13900 return true;
13901 }
13902
13903 return false;
13904}
13905
13906function tryHydrateText(fiber, nextInstance) {
13907 // fiber is a HostText Fiber
13908 var text = fiber.pendingProps;
13909 var textInstance = canHydrateTextInstance(nextInstance, text, rootOrSingletonContext);
13910
13911 if (textInstance !== null) {
13912 fiber.stateNode = textInstance;
13913 hydrationParentFiber = fiber; // Text Instances don't have children so there's nothing to hydrate.
13914
13915 nextHydratableInstance = null;
13916 return true;
13917 }
13918
13919 return false;
13920}
13921
13922function tryHydrateSuspense(fiber, nextInstance) {
13923 // fiber is a SuspenseComponent Fiber
13924 var suspenseInstance = canHydrateSuspenseInstance(nextInstance, rootOrSingletonContext);
13925
13926 if (suspenseInstance !== null) {
13927 var suspenseState = {
13928 dehydrated: suspenseInstance,
13929 treeContext: getSuspendedTreeContext(),
13930 retryLane: OffscreenLane
13931 };
13932 fiber.memoizedState = suspenseState; // Store the dehydrated fragment as a child fiber.
13933 // This simplifies the code for getHostSibling and deleting nodes,
13934 // since it doesn't have to consider all Suspense boundaries and
13935 // check if they're dehydrated ones or not.
13936
13937 var dehydratedFragment = createFiberFromDehydratedFragment(suspenseInstance);
13938 dehydratedFragment.return = fiber;
13939 fiber.child = dehydratedFragment;
13940 hydrationParentFiber = fiber; // While a Suspense Instance does have children, we won't step into
13941 // it during the first pass. Instead, we'll reenter it later.
13942
13943 nextHydratableInstance = null;
13944 return true;
13945 }
13946
13947 return false;
13948}
13949
13950var HydrationMismatchException = new Error('Hydration Mismatch Exception: This is not a real error, and should not leak into ' + "userspace. If you're seeing this, it's likely a bug in React.");
13951
13952function throwOnHydrationMismatch(fiber) {
13953 var diff = '';
13954
13955 {
13956 // Consume the diff root for this mismatch.
13957 // Any other errors will get their own diffs.
13958 var diffRoot = hydrationDiffRootDEV;
13959
13960 if (diffRoot !== null) {
13961 hydrationDiffRootDEV = null;
13962 diff = describeDiff(diffRoot);
13963 }
13964 }
13965
13966 var error = new Error("Hydration failed because the server rendered HTML didn't match the client. As a result this tree will be regenerated on the client. This can happen if a SSR-ed Client Component used:\n" + '\n' + "- A server/client branch `if (typeof window !== 'undefined')`.\n" + "- Variable input such as `Date.now()` or `Math.random()` which changes each time it's called.\n" + "- Date formatting in a user's locale which doesn't match the server.\n" + '- External changing data without sending a snapshot of it along with the HTML.\n' + '- Invalid HTML tag nesting.\n' + '\n' + 'It can also happen if the client has a browser extension installed which messes with the HTML before React loaded.\n' + '\n' + 'https://react.dev/link/hydration-mismatch' + diff);
13967 queueHydrationError(createCapturedValueAtFiber(error, fiber));
13968 throw HydrationMismatchException;
13969}
13970
13971function claimHydratableSingleton(fiber) {
13972 {
13973 if (!isHydrating) {
13974 return;
13975 }
13976
13977 var currentRootContainer = getRootHostContainer();
13978 var currentHostContext = getHostContext();
13979 var instance = fiber.stateNode = resolveSingletonInstance(fiber.type, fiber.pendingProps, currentRootContainer, currentHostContext, false);
13980
13981 {
13982 if (!didSuspendOrErrorDEV) {
13983 var differences = diffHydratedPropsForDevWarnings(instance, fiber.type, fiber.pendingProps, currentHostContext);
13984
13985 if (differences !== null) {
13986 var diffNode = buildHydrationDiffNode(fiber, 0);
13987 diffNode.serverProps = differences;
13988 }
13989 }
13990 }
13991
13992 hydrationParentFiber = fiber;
13993 rootOrSingletonContext = true;
13994 nextHydratableInstance = getFirstHydratableChild(instance);
13995 }
13996}
13997
13998function tryToClaimNextHydratableInstance(fiber) {
13999 if (!isHydrating) {
14000 return;
14001 } // Validate that this is ok to render here before any mismatches.
14002
14003
14004 var currentHostContext = getHostContext();
14005 var shouldKeepWarning = validateHydratableInstance(fiber.type, fiber.pendingProps, currentHostContext);
14006 var nextInstance = nextHydratableInstance;
14007
14008 if (!nextInstance || !tryHydrateInstance(fiber, nextInstance, currentHostContext)) {
14009 if (shouldKeepWarning) {
14010 warnNonHydratedInstance(fiber, nextInstance);
14011 }
14012
14013 throwOnHydrationMismatch(fiber);
14014 }
14015}
14016
14017function tryToClaimNextHydratableTextInstance(fiber) {
14018 if (!isHydrating) {
14019 return;
14020 }
14021
14022 var text = fiber.pendingProps;
14023 var shouldKeepWarning = true; // Validate that this is ok to render here before any mismatches.
14024
14025 var currentHostContext = getHostContext();
14026 shouldKeepWarning = validateHydratableTextInstance(text, currentHostContext);
14027 var nextInstance = nextHydratableInstance;
14028
14029 if (!nextInstance || !tryHydrateText(fiber, nextInstance)) {
14030 if (shouldKeepWarning) {
14031 warnNonHydratedInstance(fiber, nextInstance);
14032 }
14033
14034 throwOnHydrationMismatch(fiber);
14035 }
14036}
14037
14038function tryToClaimNextHydratableSuspenseInstance(fiber) {
14039 if (!isHydrating) {
14040 return;
14041 }
14042
14043 var nextInstance = nextHydratableInstance;
14044
14045 if (!nextInstance || !tryHydrateSuspense(fiber, nextInstance)) {
14046 warnNonHydratedInstance(fiber, nextInstance);
14047 throwOnHydrationMismatch(fiber);
14048 }
14049}
14050
14051function tryToClaimNextHydratableFormMarkerInstance(fiber) {
14052 if (!isHydrating) {
14053 return false;
14054 }
14055
14056 if (nextHydratableInstance) {
14057 var markerInstance = canHydrateFormStateMarker(nextHydratableInstance, rootOrSingletonContext);
14058
14059 if (markerInstance) {
14060 // Found the marker instance.
14061 nextHydratableInstance = getNextHydratableSibling(markerInstance); // Return true if this marker instance should use the state passed
14062 // to hydrateRoot.
14063 // TODO: As an optimization, Fizz should only emit these markers if form
14064 // state is passed at the root.
14065
14066 return isFormStateMarkerMatching(markerInstance);
14067 }
14068 } // Should have found a marker instance. Throw an error to trigger client
14069 // rendering. We don't bother to check if we're in a concurrent root because
14070 // useActionState is a new API, so backwards compat is not an issue.
14071
14072
14073 throwOnHydrationMismatch(fiber);
14074 return false;
14075}
14076
14077function prepareToHydrateHostInstance(fiber, hostContext) {
14078
14079 var instance = fiber.stateNode;
14080 var didHydrate = hydrateInstance(instance, fiber.type, fiber.memoizedProps, hostContext, fiber);
14081
14082 if (!didHydrate && favorSafetyOverHydrationPerf) {
14083 throwOnHydrationMismatch(fiber);
14084 }
14085}
14086
14087function prepareToHydrateHostTextInstance(fiber) {
14088
14089 var textInstance = fiber.stateNode;
14090 var textContent = fiber.memoizedProps;
14091 var shouldWarnIfMismatchDev = !didSuspendOrErrorDEV;
14092 var parentProps = null; // We assume that prepareToHydrateHostTextInstance is called in a context where the
14093 // hydration parent is the parent host component of this host text.
14094
14095 var returnFiber = hydrationParentFiber;
14096
14097 if (returnFiber !== null) {
14098 switch (returnFiber.tag) {
14099 case HostRoot:
14100 {
14101 {
14102 if (shouldWarnIfMismatchDev) {
14103 var difference = diffHydratedTextForDevWarnings(textInstance, textContent, parentProps);
14104
14105 if (difference !== null) {
14106 var diffNode = buildHydrationDiffNode(fiber, 0);
14107 diffNode.serverProps = difference;
14108 }
14109 }
14110 }
14111
14112 break;
14113 }
14114
14115 case HostSingleton:
14116 case HostComponent:
14117 {
14118 parentProps = returnFiber.memoizedProps;
14119
14120 {
14121 if (shouldWarnIfMismatchDev) {
14122 var _difference = diffHydratedTextForDevWarnings(textInstance, textContent, parentProps);
14123
14124 if (_difference !== null) {
14125 var _diffNode = buildHydrationDiffNode(fiber, 0);
14126
14127 _diffNode.serverProps = _difference;
14128 }
14129 }
14130 }
14131
14132 break;
14133 }
14134 } // TODO: What if it's a SuspenseInstance?
14135
14136 }
14137
14138 var didHydrate = hydrateTextInstance(textInstance, textContent, fiber, parentProps);
14139
14140 if (!didHydrate && favorSafetyOverHydrationPerf) {
14141 throwOnHydrationMismatch(fiber);
14142 }
14143}
14144
14145function prepareToHydrateHostSuspenseInstance(fiber) {
14146
14147 var suspenseState = fiber.memoizedState;
14148 var suspenseInstance = suspenseState !== null ? suspenseState.dehydrated : null;
14149
14150 if (!suspenseInstance) {
14151 throw new Error('Expected to have a hydrated suspense instance. ' + 'This error is likely caused by a bug in React. Please file an issue.');
14152 }
14153
14154 hydrateSuspenseInstance(suspenseInstance, fiber);
14155}
14156
14157function skipPastDehydratedSuspenseInstance(fiber) {
14158
14159 var suspenseState = fiber.memoizedState;
14160 var suspenseInstance = suspenseState !== null ? suspenseState.dehydrated : null;
14161
14162 if (!suspenseInstance) {
14163 throw new Error('Expected to have a hydrated suspense instance. ' + 'This error is likely caused by a bug in React. Please file an issue.');
14164 }
14165
14166 return getNextHydratableInstanceAfterSuspenseInstance(suspenseInstance);
14167}
14168
14169function popToNextHostParent(fiber) {
14170 hydrationParentFiber = fiber.return;
14171
14172 while (hydrationParentFiber) {
14173 switch (hydrationParentFiber.tag) {
14174 case HostRoot:
14175 case HostSingleton:
14176 rootOrSingletonContext = true;
14177 return;
14178
14179 case HostComponent:
14180 case SuspenseComponent:
14181 rootOrSingletonContext = false;
14182 return;
14183
14184 default:
14185 hydrationParentFiber = hydrationParentFiber.return;
14186 }
14187 }
14188}
14189
14190function popHydrationState(fiber) {
14191
14192 if (fiber !== hydrationParentFiber) {
14193 // We're deeper than the current hydration context, inside an inserted
14194 // tree.
14195 return false;
14196 }
14197
14198 if (!isHydrating) {
14199 // If we're not currently hydrating but we're in a hydration context, then
14200 // we were an insertion and now need to pop up reenter hydration of our
14201 // siblings.
14202 popToNextHostParent(fiber);
14203 isHydrating = true;
14204 return false;
14205 }
14206
14207 var shouldClear = false;
14208
14209 {
14210 // With float we never clear the Root, or Singleton instances. We also do not clear Instances
14211 // that have singleton text content
14212 if (fiber.tag !== HostRoot && fiber.tag !== HostSingleton && !(fiber.tag === HostComponent && (!shouldDeleteUnhydratedTailInstances(fiber.type) || shouldSetTextContent(fiber.type, fiber.memoizedProps)))) {
14213 shouldClear = true;
14214 }
14215 }
14216
14217 if (shouldClear) {
14218 var nextInstance = nextHydratableInstance;
14219
14220 if (nextInstance) {
14221 warnIfUnhydratedTailNodes(fiber);
14222 throwOnHydrationMismatch(fiber);
14223 }
14224 }
14225
14226 popToNextHostParent(fiber);
14227
14228 if (fiber.tag === SuspenseComponent) {
14229 nextHydratableInstance = skipPastDehydratedSuspenseInstance(fiber);
14230 } else {
14231 nextHydratableInstance = hydrationParentFiber ? getNextHydratableSibling(fiber.stateNode) : null;
14232 }
14233
14234 return true;
14235}
14236
14237function warnIfUnhydratedTailNodes(fiber) {
14238 {
14239 var nextInstance = nextHydratableInstance;
14240
14241 while (nextInstance) {
14242 var diffNode = buildHydrationDiffNode(fiber, 0);
14243 var description = describeHydratableInstanceForDevWarnings(nextInstance);
14244 diffNode.serverTail.push(description);
14245
14246 if (description.type === 'Suspense') {
14247 var suspenseInstance = nextInstance;
14248 nextInstance = getNextHydratableInstanceAfterSuspenseInstance(suspenseInstance);
14249 } else {
14250 nextInstance = getNextHydratableSibling(nextInstance);
14251 }
14252 }
14253 }
14254}
14255
14256function resetHydrationState() {
14257
14258 hydrationParentFiber = null;
14259 nextHydratableInstance = null;
14260 isHydrating = false;
14261 didSuspendOrErrorDEV = false;
14262}
14263
14264function upgradeHydrationErrorsToRecoverable() {
14265 if (hydrationErrors !== null) {
14266 // Successfully completed a forced client render. The errors that occurred
14267 // during the hydration attempt are now recovered. We will log them in
14268 // commit phase, once the entire tree has finished.
14269 queueRecoverableErrors(hydrationErrors);
14270 hydrationErrors = null;
14271 }
14272}
14273
14274function getIsHydrating() {
14275 return isHydrating;
14276}
14277
14278function queueHydrationError(error) {
14279 if (hydrationErrors === null) {
14280 hydrationErrors = [error];
14281 } else {
14282 hydrationErrors.push(error);
14283 }
14284}
14285function emitPendingHydrationWarnings() {
14286 {
14287 // If we haven't yet thrown any hydration errors by the time we reach the end we've successfully
14288 // hydrated, however, we might still have DEV-only mismatches that we log now.
14289 var diffRoot = hydrationDiffRootDEV;
14290
14291 if (diffRoot !== null) {
14292 hydrationDiffRootDEV = null;
14293 var diff = describeDiff(diffRoot);
14294
14295 error("A tree hydrated but some attributes of the server rendered HTML didn't match the client properties. This won't be patched up. " + 'This can happen if a SSR-ed Client Component used:\n' + '\n' + "- A server/client branch `if (typeof window !== 'undefined')`.\n" + "- Variable input such as `Date.now()` or `Math.random()` which changes each time it's called.\n" + "- Date formatting in a user's locale which doesn't match the server.\n" + '- External changing data without sending a snapshot of it along with the HTML.\n' + '- Invalid HTML tag nesting.\n' + '\n' + 'It can also happen if the client has a browser extension installed which messes with the HTML before React loaded.\n' + '\n' + '%s%s', 'https://react.dev/link/hydration-mismatch', diff);
14296 }
14297 }
14298}
14299
14300function getThenablesFromState(state) {
14301 {
14302 var devState = state;
14303 return devState.thenables;
14304 }
14305} // An error that is thrown (e.g. by `use`) to trigger Suspense. If we
14306// detect this is caught by userspace, we'll log a warning in development.
14307
14308
14309var SuspenseException = new Error("Suspense Exception: This is not a real error! It's an implementation " + 'detail of `use` to interrupt the current render. You must either ' + 'rethrow it immediately, or move the `use` call outside of the ' + '`try/catch` block. Capturing without rethrowing will lead to ' + 'unexpected behavior.\n\n' + 'To handle async errors, wrap your component in an error boundary, or ' + "call the promise's `.catch` method and pass the result to `use`");
14310var SuspenseyCommitException = new Error('Suspense Exception: This is not a real error, and should not leak into ' + "userspace. If you're seeing this, it's likely a bug in React."); // This is a noop thenable that we use to trigger a fallback in throwException.
14311// TODO: It would be better to refactor throwException into multiple functions
14312// so we can trigger a fallback directly without having to check the type. But
14313// for now this will do.
14314
14315var noopSuspenseyCommitThenable = {
14316 then: function () {
14317 {
14318 error('Internal React error: A listener was unexpectedly attached to a ' + '"noop" thenable. This is a bug in React. Please file an issue.');
14319 }
14320 }
14321};
14322function createThenableState() {
14323 // The ThenableState is created the first time a component suspends. If it
14324 // suspends again, we'll reuse the same state.
14325 {
14326 return {
14327 didWarnAboutUncachedPromise: false,
14328 thenables: []
14329 };
14330 }
14331}
14332function isThenableResolved(thenable) {
14333 var status = thenable.status;
14334 return status === 'fulfilled' || status === 'rejected';
14335}
14336
14337function noop$1() {}
14338
14339function trackUsedThenable(thenableState, thenable, index) {
14340 if (ReactSharedInternals.actQueue !== null) {
14341 ReactSharedInternals.didUsePromise = true;
14342 }
14343
14344 var trackedThenables = getThenablesFromState(thenableState);
14345 var previous = trackedThenables[index];
14346
14347 if (previous === undefined) {
14348 trackedThenables.push(thenable);
14349 } else {
14350 if (previous !== thenable) {
14351 // Reuse the previous thenable, and drop the new one. We can assume
14352 // they represent the same value, because components are idempotent.
14353 {
14354 var thenableStateDev = thenableState;
14355
14356 if (!thenableStateDev.didWarnAboutUncachedPromise) {
14357 // We should only warn the first time an uncached thenable is
14358 // discovered per component, because if there are multiple, the
14359 // subsequent ones are likely derived from the first.
14360 //
14361 // We track this on the thenableState instead of deduping using the
14362 // component name like we usually do, because in the case of a
14363 // promise-as-React-node, the owner component is likely different from
14364 // the parent that's currently being reconciled. We'd have to track
14365 // the owner using state, which we're trying to move away from. Though
14366 // since this is dev-only, maybe that'd be OK.
14367 //
14368 // However, another benefit of doing it this way is we might
14369 // eventually have a thenableState per memo/Forget boundary instead
14370 // of per component, so this would allow us to have more
14371 // granular warnings.
14372 thenableStateDev.didWarnAboutUncachedPromise = true; // TODO: This warning should link to a corresponding docs page.
14373
14374 error('A component was suspended by an uncached promise. Creating ' + 'promises inside a Client Component or hook is not yet ' + 'supported, except via a Suspense-compatible library or framework.');
14375 }
14376 } // Avoid an unhandled rejection errors for the Promises that we'll
14377 // intentionally ignore.
14378
14379
14380 thenable.then(noop$1, noop$1);
14381 thenable = previous;
14382 }
14383 } // We use an expando to track the status and result of a thenable so that we
14384 // can synchronously unwrap the value. Think of this as an extension of the
14385 // Promise API, or a custom interface that is a superset of Thenable.
14386 //
14387 // If the thenable doesn't have a status, set it to "pending" and attach
14388 // a listener that will update its status and result when it resolves.
14389
14390
14391 switch (thenable.status) {
14392 case 'fulfilled':
14393 {
14394 var fulfilledValue = thenable.value;
14395 return fulfilledValue;
14396 }
14397
14398 case 'rejected':
14399 {
14400 var rejectedError = thenable.reason;
14401 checkIfUseWrappedInAsyncCatch(rejectedError);
14402 throw rejectedError;
14403 }
14404
14405 default:
14406 {
14407 if (typeof thenable.status === 'string') {
14408 // Only instrument the thenable if the status if not defined. If
14409 // it's defined, but an unknown value, assume it's been instrumented by
14410 // some custom userspace implementation. We treat it as "pending".
14411 // Attach a dummy listener, to ensure that any lazy initialization can
14412 // happen. Flight lazily parses JSON when the value is actually awaited.
14413 thenable.then(noop$1, noop$1);
14414 } else {
14415 // This is an uncached thenable that we haven't seen before.
14416 // Detect infinite ping loops caused by uncached promises.
14417 var root = getWorkInProgressRoot();
14418
14419 if (root !== null && root.shellSuspendCounter > 100) {
14420 // This root has suspended repeatedly in the shell without making any
14421 // progress (i.e. committing something). This is highly suggestive of
14422 // an infinite ping loop, often caused by an accidental Async Client
14423 // Component.
14424 //
14425 // During a transition, we can suspend the work loop until the promise
14426 // to resolve, but this is a sync render, so that's not an option. We
14427 // also can't show a fallback, because none was provided. So our last
14428 // resort is to throw an error.
14429 //
14430 // TODO: Remove this error in a future release. Other ways of handling
14431 // this case include forcing a concurrent render, or putting the whole
14432 // root into offscreen mode.
14433 throw new Error('async/await is not yet supported in Client Components, only ' + 'Server Components. This error is often caused by accidentally ' + "adding `'use client'` to a module that was originally written " + 'for the server.');
14434 }
14435
14436 var pendingThenable = thenable;
14437 pendingThenable.status = 'pending';
14438 pendingThenable.then(function (fulfilledValue) {
14439 if (thenable.status === 'pending') {
14440 var fulfilledThenable = thenable;
14441 fulfilledThenable.status = 'fulfilled';
14442 fulfilledThenable.value = fulfilledValue;
14443 }
14444 }, function (error) {
14445 if (thenable.status === 'pending') {
14446 var rejectedThenable = thenable;
14447 rejectedThenable.status = 'rejected';
14448 rejectedThenable.reason = error;
14449 }
14450 });
14451 } // Check one more time in case the thenable resolved synchronously.
14452
14453
14454 switch (thenable.status) {
14455 case 'fulfilled':
14456 {
14457 var fulfilledThenable = thenable;
14458 return fulfilledThenable.value;
14459 }
14460
14461 case 'rejected':
14462 {
14463 var rejectedThenable = thenable;
14464 var _rejectedError = rejectedThenable.reason;
14465 checkIfUseWrappedInAsyncCatch(_rejectedError);
14466 throw _rejectedError;
14467 }
14468 } // Suspend.
14469 //
14470 // Throwing here is an implementation detail that allows us to unwind the
14471 // call stack. But we shouldn't allow it to leak into userspace. Throw an
14472 // opaque placeholder value instead of the actual thenable. If it doesn't
14473 // get captured by the work loop, log a warning, because that means
14474 // something in userspace must have caught it.
14475
14476
14477 suspendedThenable = thenable;
14478
14479 {
14480 needsToResetSuspendedThenableDEV = true;
14481 }
14482
14483 throw SuspenseException;
14484 }
14485 }
14486}
14487function suspendCommit() {
14488 // This extra indirection only exists so it can handle passing
14489 // noopSuspenseyCommitThenable through to throwException.
14490 // TODO: Factor the thenable check out of throwException
14491 suspendedThenable = noopSuspenseyCommitThenable;
14492 throw SuspenseyCommitException;
14493} // This is used to track the actual thenable that suspended so it can be
14494// passed to the rest of the Suspense implementation — which, for historical
14495// reasons, expects to receive a thenable.
14496
14497var suspendedThenable = null;
14498var needsToResetSuspendedThenableDEV = false;
14499function getSuspendedThenable() {
14500 // This is called right after `use` suspends by throwing an exception. `use`
14501 // throws an opaque value instead of the thenable itself so that it can't be
14502 // caught in userspace. Then the work loop accesses the actual thenable using
14503 // this function.
14504 if (suspendedThenable === null) {
14505 throw new Error('Expected a suspended thenable. This is a bug in React. Please file ' + 'an issue.');
14506 }
14507
14508 var thenable = suspendedThenable;
14509 suspendedThenable = null;
14510
14511 {
14512 needsToResetSuspendedThenableDEV = false;
14513 }
14514
14515 return thenable;
14516}
14517function checkIfUseWrappedInTryCatch() {
14518 {
14519 // This was set right before SuspenseException was thrown, and it should
14520 // have been cleared when the exception was handled. If it wasn't,
14521 // it must have been caught by userspace.
14522 if (needsToResetSuspendedThenableDEV) {
14523 needsToResetSuspendedThenableDEV = false;
14524 return true;
14525 }
14526 }
14527
14528 return false;
14529}
14530function checkIfUseWrappedInAsyncCatch(rejectedReason) {
14531 // This check runs in prod, too, because it prevents a more confusing
14532 // downstream error, where SuspenseException is caught by a promise and
14533 // thrown asynchronously.
14534 // TODO: Another way to prevent SuspenseException from leaking into an async
14535 // execution context is to check the dispatcher every time `use` is called,
14536 // or some equivalent. That might be preferable for other reasons, too, since
14537 // it matches how we prevent similar mistakes for other hooks.
14538 if (rejectedReason === SuspenseException) {
14539 throw new Error('Hooks are not supported inside an async component. This ' + "error is often caused by accidentally adding `'use client'` " + 'to a module that was originally written for the server.');
14540 }
14541}
14542
14543var thenableState$1 = null;
14544var thenableIndexCounter$1 = 0;
14545
14546function mergeDebugInfo(outer, inner) {
14547
14548 if (inner == null) {
14549 return outer;
14550 } else if (outer === null) {
14551 return inner;
14552 } else {
14553 // If we have two debugInfo, we need to create a new one. This makes the array no longer
14554 // live so we'll miss any future updates if we received more so ideally we should always
14555 // do this after both have fully resolved/unsuspended.
14556 return outer.concat(inner);
14557 }
14558}
14559
14560var didWarnAboutMaps;
14561var didWarnAboutGenerators;
14562var ownerHasKeyUseWarning;
14563var ownerHasFunctionTypeWarning;
14564var ownerHasSymbolTypeWarning;
14565
14566var warnForMissingKey = function (child, returnFiber) {};
14567
14568{
14569 didWarnAboutMaps = false;
14570 didWarnAboutGenerators = false;
14571 /**
14572 * Warn if there's no key explicitly set on dynamic arrays of children or
14573 * object keys are not valid. This allows us to keep track of children between
14574 * updates.
14575 */
14576
14577 ownerHasKeyUseWarning = {};
14578 ownerHasFunctionTypeWarning = {};
14579 ownerHasSymbolTypeWarning = {};
14580
14581 warnForMissingKey = function (child, returnFiber) {
14582 if (child === null || typeof child !== 'object') {
14583 return;
14584 }
14585
14586 if (!child._store || child._store.validated || child.key != null) {
14587 return;
14588 }
14589
14590 if (typeof child._store !== 'object') {
14591 throw new Error('React Component in warnForMissingKey should have a _store. ' + 'This error is likely caused by a bug in React. Please file an issue.');
14592 } // $FlowFixMe[cannot-write] unable to narrow type from mixed to writable object
14593
14594
14595 child._store.validated = true;
14596 var componentName = getComponentNameFromFiber(returnFiber) || 'Component';
14597
14598 if (ownerHasKeyUseWarning[componentName]) {
14599 return;
14600 }
14601
14602 ownerHasKeyUseWarning[componentName] = true;
14603
14604 error('Each child in a list should have a unique ' + '"key" prop. See https://react.dev/link/warning-keys for ' + 'more information.');
14605 };
14606}
14607
14608function unwrapThenable(thenable) {
14609 var index = thenableIndexCounter$1;
14610 thenableIndexCounter$1 += 1;
14611
14612 if (thenableState$1 === null) {
14613 thenableState$1 = createThenableState();
14614 }
14615
14616 return trackUsedThenable(thenableState$1, thenable, index);
14617}
14618
14619function coerceRef(returnFiber, current, workInProgress, element) {
14620 var ref;
14621
14622 {
14623 // TODO: This is a temporary, intermediate step. When enableRefAsProp is on,
14624 // we should resolve the `ref` prop during the begin phase of the component
14625 // it's attached to (HostComponent, ClassComponent, etc).
14626 var refProp = element.props.ref;
14627 ref = refProp !== undefined ? refProp : null;
14628 } // TODO: If enableRefAsProp is on, we shouldn't use the `ref` field. We
14629 // should always read the ref from the prop.
14630
14631
14632 workInProgress.ref = ref;
14633}
14634
14635function throwOnInvalidObjectType(returnFiber, newChild) {
14636 if (newChild.$$typeof === REACT_LEGACY_ELEMENT_TYPE) {
14637 throw new Error('A React Element from an older version of React was rendered. ' + 'This is not supported. It can happen if:\n' + '- Multiple copies of the "react" package is used.\n' + '- A library pre-bundled an old copy of "react" or "react/jsx-runtime".\n' + '- A compiler tries to "inline" JSX instead of using the runtime.');
14638 } // $FlowFixMe[method-unbinding]
14639
14640
14641 var childString = Object.prototype.toString.call(newChild);
14642 throw new Error("Objects are not valid as a React child (found: " + (childString === '[object Object]' ? 'object with keys {' + Object.keys(newChild).join(', ') + '}' : childString) + "). " + 'If you meant to render a collection of children, use an array ' + 'instead.');
14643}
14644
14645function warnOnFunctionType(returnFiber, invalidChild) {
14646 {
14647 var parentName = getComponentNameFromFiber(returnFiber) || 'Component';
14648
14649 if (ownerHasFunctionTypeWarning[parentName]) {
14650 return;
14651 }
14652
14653 ownerHasFunctionTypeWarning[parentName] = true;
14654 var name = invalidChild.displayName || invalidChild.name || 'Component';
14655
14656 if (returnFiber.tag === HostRoot) {
14657 error('Functions are not valid as a React child. This may happen if ' + 'you return %s instead of <%s /> from render. ' + 'Or maybe you meant to call this function rather than return it.\n' + ' root.render(%s)', name, name, name);
14658 } else {
14659 error('Functions are not valid as a React child. This may happen if ' + 'you return %s instead of <%s /> from render. ' + 'Or maybe you meant to call this function rather than return it.\n' + ' <%s>{%s}</%s>', name, name, parentName, name, parentName);
14660 }
14661 }
14662}
14663
14664function warnOnSymbolType(returnFiber, invalidChild) {
14665 {
14666 var parentName = getComponentNameFromFiber(returnFiber) || 'Component';
14667
14668 if (ownerHasSymbolTypeWarning[parentName]) {
14669 return;
14670 }
14671
14672 ownerHasSymbolTypeWarning[parentName] = true; // eslint-disable-next-line react-internal/safe-string-coercion
14673
14674 var name = String(invalidChild);
14675
14676 if (returnFiber.tag === HostRoot) {
14677 error('Symbols are not valid as a React child.\n' + ' root.render(%s)', name);
14678 } else {
14679 error('Symbols are not valid as a React child.\n' + ' <%s>%s</%s>', parentName, name, parentName);
14680 }
14681 }
14682}
14683
14684function resolveLazy(lazyType) {
14685 var payload = lazyType._payload;
14686 var init = lazyType._init;
14687 return init(payload);
14688} // This wrapper function exists because I expect to clone the code in each path
14689// to be able to optimize each path individually by branching early. This needs
14690// a compiler or we can do it manually. Helpers that don't need this branching
14691// live outside of this function.
14692
14693
14694function createChildReconciler(shouldTrackSideEffects) {
14695 function deleteChild(returnFiber, childToDelete) {
14696 if (!shouldTrackSideEffects) {
14697 // Noop.
14698 return;
14699 }
14700
14701 var deletions = returnFiber.deletions;
14702
14703 if (deletions === null) {
14704 returnFiber.deletions = [childToDelete];
14705 returnFiber.flags |= ChildDeletion;
14706 } else {
14707 deletions.push(childToDelete);
14708 }
14709 }
14710
14711 function deleteRemainingChildren(returnFiber, currentFirstChild) {
14712 if (!shouldTrackSideEffects) {
14713 // Noop.
14714 return null;
14715 } // TODO: For the shouldClone case, this could be micro-optimized a bit by
14716 // assuming that after the first child we've already added everything.
14717
14718
14719 var childToDelete = currentFirstChild;
14720
14721 while (childToDelete !== null) {
14722 deleteChild(returnFiber, childToDelete);
14723 childToDelete = childToDelete.sibling;
14724 }
14725
14726 return null;
14727 }
14728
14729 function mapRemainingChildren(currentFirstChild) {
14730 // Add the remaining children to a temporary map so that we can find them by
14731 // keys quickly. Implicit (null) keys get added to this set with their index
14732 // instead.
14733 var existingChildren = new Map();
14734 var existingChild = currentFirstChild;
14735
14736 while (existingChild !== null) {
14737 if (existingChild.key !== null) {
14738 existingChildren.set(existingChild.key, existingChild);
14739 } else {
14740 existingChildren.set(existingChild.index, existingChild);
14741 }
14742
14743 existingChild = existingChild.sibling;
14744 }
14745
14746 return existingChildren;
14747 }
14748
14749 function useFiber(fiber, pendingProps) {
14750 // We currently set sibling to null and index to 0 here because it is easy
14751 // to forget to do before returning it. E.g. for the single child case.
14752 var clone = createWorkInProgress(fiber, pendingProps);
14753 clone.index = 0;
14754 clone.sibling = null;
14755 return clone;
14756 }
14757
14758 function placeChild(newFiber, lastPlacedIndex, newIndex) {
14759 newFiber.index = newIndex;
14760
14761 if (!shouldTrackSideEffects) {
14762 // During hydration, the useId algorithm needs to know which fibers are
14763 // part of a list of children (arrays, iterators).
14764 newFiber.flags |= Forked;
14765 return lastPlacedIndex;
14766 }
14767
14768 var current = newFiber.alternate;
14769
14770 if (current !== null) {
14771 var oldIndex = current.index;
14772
14773 if (oldIndex < lastPlacedIndex) {
14774 // This is a move.
14775 newFiber.flags |= Placement | PlacementDEV;
14776 return lastPlacedIndex;
14777 } else {
14778 // This item can stay in place.
14779 return oldIndex;
14780 }
14781 } else {
14782 // This is an insertion.
14783 newFiber.flags |= Placement | PlacementDEV;
14784 return lastPlacedIndex;
14785 }
14786 }
14787
14788 function placeSingleChild(newFiber) {
14789 // This is simpler for the single child case. We only need to do a
14790 // placement for inserting new children.
14791 if (shouldTrackSideEffects && newFiber.alternate === null) {
14792 newFiber.flags |= Placement | PlacementDEV;
14793 }
14794
14795 return newFiber;
14796 }
14797
14798 function updateTextNode(returnFiber, current, textContent, lanes, debugInfo) {
14799 if (current === null || current.tag !== HostText) {
14800 // Insert
14801 var created = createFiberFromText(textContent, returnFiber.mode, lanes);
14802 created.return = returnFiber;
14803
14804 {
14805 created._debugInfo = debugInfo;
14806 }
14807
14808 return created;
14809 } else {
14810 // Update
14811 var existing = useFiber(current, textContent);
14812 existing.return = returnFiber;
14813
14814 {
14815 existing._debugInfo = debugInfo;
14816 }
14817
14818 return existing;
14819 }
14820 }
14821
14822 function updateElement(returnFiber, current, element, lanes, debugInfo) {
14823 var elementType = element.type;
14824
14825 if (elementType === REACT_FRAGMENT_TYPE) {
14826 return updateFragment(returnFiber, current, element.props.children, lanes, element.key, debugInfo);
14827 }
14828
14829 if (current !== null) {
14830 if (current.elementType === elementType || ( // Keep this check inline so it only runs on the false path:
14831 isCompatibleFamilyForHotReloading(current, element) ) || // Lazy types should reconcile their resolved type.
14832 // We need to do this after the Hot Reloading check above,
14833 // because hot reloading has different semantics than prod because
14834 // it doesn't resuspend. So we can't let the call below suspend.
14835 typeof elementType === 'object' && elementType !== null && elementType.$$typeof === REACT_LAZY_TYPE && resolveLazy(elementType) === current.type) {
14836 // Move based on index
14837 var existing = useFiber(current, element.props);
14838 coerceRef(returnFiber, current, existing, element);
14839 existing.return = returnFiber;
14840
14841 {
14842 existing._debugOwner = element._owner;
14843 existing._debugInfo = debugInfo;
14844 }
14845
14846 return existing;
14847 }
14848 } // Insert
14849
14850
14851 var created = createFiberFromElement(element, returnFiber.mode, lanes);
14852 coerceRef(returnFiber, current, created, element);
14853 created.return = returnFiber;
14854
14855 {
14856 created._debugInfo = debugInfo;
14857 }
14858
14859 return created;
14860 }
14861
14862 function updatePortal(returnFiber, current, portal, lanes, debugInfo) {
14863 if (current === null || current.tag !== HostPortal || current.stateNode.containerInfo !== portal.containerInfo || current.stateNode.implementation !== portal.implementation) {
14864 // Insert
14865 var created = createFiberFromPortal(portal, returnFiber.mode, lanes);
14866 created.return = returnFiber;
14867
14868 {
14869 created._debugInfo = debugInfo;
14870 }
14871
14872 return created;
14873 } else {
14874 // Update
14875 var existing = useFiber(current, portal.children || []);
14876 existing.return = returnFiber;
14877
14878 {
14879 existing._debugInfo = debugInfo;
14880 }
14881
14882 return existing;
14883 }
14884 }
14885
14886 function updateFragment(returnFiber, current, fragment, lanes, key, debugInfo) {
14887 if (current === null || current.tag !== Fragment) {
14888 // Insert
14889 var created = createFiberFromFragment(fragment, returnFiber.mode, lanes, key);
14890 created.return = returnFiber;
14891
14892 {
14893 created._debugInfo = debugInfo;
14894 }
14895
14896 return created;
14897 } else {
14898 // Update
14899 var existing = useFiber(current, fragment);
14900 existing.return = returnFiber;
14901
14902 {
14903 existing._debugInfo = debugInfo;
14904 }
14905
14906 return existing;
14907 }
14908 }
14909
14910 function createChild(returnFiber, newChild, lanes, debugInfo) {
14911 if (typeof newChild === 'string' && newChild !== '' || typeof newChild === 'number' || typeof newChild === 'bigint') {
14912 // Text nodes don't have keys. If the previous node is implicitly keyed
14913 // we can continue to replace it without aborting even if it is not a text
14914 // node.
14915 var created = createFiberFromText( // $FlowFixMe[unsafe-addition] Flow doesn't want us to use `+` operator with string and bigint
14916 '' + newChild, returnFiber.mode, lanes);
14917 created.return = returnFiber;
14918
14919 {
14920 created._debugInfo = debugInfo;
14921 }
14922
14923 return created;
14924 }
14925
14926 if (typeof newChild === 'object' && newChild !== null) {
14927 switch (newChild.$$typeof) {
14928 case REACT_ELEMENT_TYPE:
14929 {
14930 var _created = createFiberFromElement(newChild, returnFiber.mode, lanes);
14931
14932 coerceRef(returnFiber, null, _created, newChild);
14933 _created.return = returnFiber;
14934
14935 {
14936 _created._debugInfo = mergeDebugInfo(debugInfo, newChild._debugInfo);
14937 }
14938
14939 return _created;
14940 }
14941
14942 case REACT_PORTAL_TYPE:
14943 {
14944 var _created2 = createFiberFromPortal(newChild, returnFiber.mode, lanes);
14945
14946 _created2.return = returnFiber;
14947
14948 {
14949 _created2._debugInfo = debugInfo;
14950 }
14951
14952 return _created2;
14953 }
14954
14955 case REACT_LAZY_TYPE:
14956 {
14957 var payload = newChild._payload;
14958 var init = newChild._init;
14959 return createChild(returnFiber, init(payload), lanes, mergeDebugInfo(debugInfo, newChild._debugInfo) // call merge after init
14960 );
14961 }
14962 }
14963
14964 if (isArray(newChild) || getIteratorFn(newChild) || enableAsyncIterableChildren ) {
14965 var _created3 = createFiberFromFragment(newChild, returnFiber.mode, lanes, null);
14966
14967 _created3.return = returnFiber;
14968
14969 {
14970 _created3._debugInfo = mergeDebugInfo(debugInfo, newChild._debugInfo);
14971 }
14972
14973 return _created3;
14974 } // Usable node types
14975 //
14976 // Unwrap the inner value and recursively call this function again.
14977
14978
14979 if (typeof newChild.then === 'function') {
14980 var thenable = newChild;
14981 return createChild(returnFiber, unwrapThenable(thenable), lanes, mergeDebugInfo(debugInfo, newChild._debugInfo));
14982 }
14983
14984 if (newChild.$$typeof === REACT_CONTEXT_TYPE) {
14985 var context = newChild;
14986 return createChild(returnFiber, readContextDuringReconciliation(returnFiber, context, lanes), lanes, debugInfo);
14987 }
14988
14989 throwOnInvalidObjectType(returnFiber, newChild);
14990 }
14991
14992 {
14993 if (typeof newChild === 'function') {
14994 warnOnFunctionType(returnFiber, newChild);
14995 }
14996
14997 if (typeof newChild === 'symbol') {
14998 warnOnSymbolType(returnFiber, newChild);
14999 }
15000 }
15001
15002 return null;
15003 }
15004
15005 function updateSlot(returnFiber, oldFiber, newChild, lanes, debugInfo) {
15006 // Update the fiber if the keys match, otherwise return null.
15007 var key = oldFiber !== null ? oldFiber.key : null;
15008
15009 if (typeof newChild === 'string' && newChild !== '' || typeof newChild === 'number' || typeof newChild === 'bigint') {
15010 // Text nodes don't have keys. If the previous node is implicitly keyed
15011 // we can continue to replace it without aborting even if it is not a text
15012 // node.
15013 if (key !== null) {
15014 return null;
15015 }
15016
15017 return updateTextNode(returnFiber, oldFiber, // $FlowFixMe[unsafe-addition] Flow doesn't want us to use `+` operator with string and bigint
15018 '' + newChild, lanes, debugInfo);
15019 }
15020
15021 if (typeof newChild === 'object' && newChild !== null) {
15022 switch (newChild.$$typeof) {
15023 case REACT_ELEMENT_TYPE:
15024 {
15025 if (newChild.key === key) {
15026 return updateElement(returnFiber, oldFiber, newChild, lanes, mergeDebugInfo(debugInfo, newChild._debugInfo));
15027 } else {
15028 return null;
15029 }
15030 }
15031
15032 case REACT_PORTAL_TYPE:
15033 {
15034 if (newChild.key === key) {
15035 return updatePortal(returnFiber, oldFiber, newChild, lanes, debugInfo);
15036 } else {
15037 return null;
15038 }
15039 }
15040
15041 case REACT_LAZY_TYPE:
15042 {
15043 var payload = newChild._payload;
15044 var init = newChild._init;
15045 return updateSlot(returnFiber, oldFiber, init(payload), lanes, mergeDebugInfo(debugInfo, newChild._debugInfo));
15046 }
15047 }
15048
15049 if (isArray(newChild) || getIteratorFn(newChild) || enableAsyncIterableChildren ) {
15050 if (key !== null) {
15051 return null;
15052 }
15053
15054 return updateFragment(returnFiber, oldFiber, newChild, lanes, null, mergeDebugInfo(debugInfo, newChild._debugInfo));
15055 } // Usable node types
15056 //
15057 // Unwrap the inner value and recursively call this function again.
15058
15059
15060 if (typeof newChild.then === 'function') {
15061 var thenable = newChild;
15062 return updateSlot(returnFiber, oldFiber, unwrapThenable(thenable), lanes, debugInfo);
15063 }
15064
15065 if (newChild.$$typeof === REACT_CONTEXT_TYPE) {
15066 var context = newChild;
15067 return updateSlot(returnFiber, oldFiber, readContextDuringReconciliation(returnFiber, context, lanes), lanes, debugInfo);
15068 }
15069
15070 throwOnInvalidObjectType(returnFiber, newChild);
15071 }
15072
15073 {
15074 if (typeof newChild === 'function') {
15075 warnOnFunctionType(returnFiber, newChild);
15076 }
15077
15078 if (typeof newChild === 'symbol') {
15079 warnOnSymbolType(returnFiber, newChild);
15080 }
15081 }
15082
15083 return null;
15084 }
15085
15086 function updateFromMap(existingChildren, returnFiber, newIdx, newChild, lanes, debugInfo) {
15087 if (typeof newChild === 'string' && newChild !== '' || typeof newChild === 'number' || typeof newChild === 'bigint') {
15088 // Text nodes don't have keys, so we neither have to check the old nor
15089 // new node for the key. If both are text nodes, they match.
15090 var matchedFiber = existingChildren.get(newIdx) || null;
15091 return updateTextNode(returnFiber, matchedFiber, // $FlowFixMe[unsafe-addition] Flow doesn't want us to use `+` operator with string and bigint
15092 '' + newChild, lanes, debugInfo);
15093 }
15094
15095 if (typeof newChild === 'object' && newChild !== null) {
15096 switch (newChild.$$typeof) {
15097 case REACT_ELEMENT_TYPE:
15098 {
15099 var _matchedFiber = existingChildren.get(newChild.key === null ? newIdx : newChild.key) || null;
15100
15101 return updateElement(returnFiber, _matchedFiber, newChild, lanes, mergeDebugInfo(debugInfo, newChild._debugInfo));
15102 }
15103
15104 case REACT_PORTAL_TYPE:
15105 {
15106 var _matchedFiber2 = existingChildren.get(newChild.key === null ? newIdx : newChild.key) || null;
15107
15108 return updatePortal(returnFiber, _matchedFiber2, newChild, lanes, debugInfo);
15109 }
15110
15111 case REACT_LAZY_TYPE:
15112 var payload = newChild._payload;
15113 var init = newChild._init;
15114 return updateFromMap(existingChildren, returnFiber, newIdx, init(payload), lanes, mergeDebugInfo(debugInfo, newChild._debugInfo));
15115 }
15116
15117 if (isArray(newChild) || getIteratorFn(newChild) || enableAsyncIterableChildren ) {
15118 var _matchedFiber3 = existingChildren.get(newIdx) || null;
15119
15120 return updateFragment(returnFiber, _matchedFiber3, newChild, lanes, null, mergeDebugInfo(debugInfo, newChild._debugInfo));
15121 } // Usable node types
15122 //
15123 // Unwrap the inner value and recursively call this function again.
15124
15125
15126 if (typeof newChild.then === 'function') {
15127 var thenable = newChild;
15128 return updateFromMap(existingChildren, returnFiber, newIdx, unwrapThenable(thenable), lanes, debugInfo);
15129 }
15130
15131 if (newChild.$$typeof === REACT_CONTEXT_TYPE) {
15132 var context = newChild;
15133 return updateFromMap(existingChildren, returnFiber, newIdx, readContextDuringReconciliation(returnFiber, context, lanes), lanes, debugInfo);
15134 }
15135
15136 throwOnInvalidObjectType(returnFiber, newChild);
15137 }
15138
15139 {
15140 if (typeof newChild === 'function') {
15141 warnOnFunctionType(returnFiber, newChild);
15142 }
15143
15144 if (typeof newChild === 'symbol') {
15145 warnOnSymbolType(returnFiber, newChild);
15146 }
15147 }
15148
15149 return null;
15150 }
15151 /**
15152 * Warns if there is a duplicate or missing key
15153 */
15154
15155
15156 function warnOnInvalidKey(child, knownKeys, returnFiber) {
15157 {
15158 if (typeof child !== 'object' || child === null) {
15159 return knownKeys;
15160 }
15161
15162 switch (child.$$typeof) {
15163 case REACT_ELEMENT_TYPE:
15164 case REACT_PORTAL_TYPE:
15165 warnForMissingKey(child, returnFiber);
15166 var key = child.key;
15167
15168 if (typeof key !== 'string') {
15169 break;
15170 }
15171
15172 if (knownKeys === null) {
15173 knownKeys = new Set();
15174 knownKeys.add(key);
15175 break;
15176 }
15177
15178 if (!knownKeys.has(key)) {
15179 knownKeys.add(key);
15180 break;
15181 }
15182
15183 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);
15184
15185 break;
15186
15187 case REACT_LAZY_TYPE:
15188 var payload = child._payload;
15189 var init = child._init;
15190 warnOnInvalidKey(init(payload), knownKeys, returnFiber);
15191 break;
15192 }
15193 }
15194
15195 return knownKeys;
15196 }
15197
15198 function reconcileChildrenArray(returnFiber, currentFirstChild, newChildren, lanes, debugInfo) {
15199 // This algorithm can't optimize by searching from both ends since we
15200 // don't have backpointers on fibers. I'm trying to see how far we can get
15201 // with that model. If it ends up not being worth the tradeoffs, we can
15202 // add it later.
15203 // Even with a two ended optimization, we'd want to optimize for the case
15204 // where there are few changes and brute force the comparison instead of
15205 // going for the Map. It'd like to explore hitting that path first in
15206 // forward-only mode and only go for the Map once we notice that we need
15207 // lots of look ahead. This doesn't handle reversal as well as two ended
15208 // search but that's unusual. Besides, for the two ended optimization to
15209 // work on Iterables, we'd need to copy the whole set.
15210 // In this first iteration, we'll just live with hitting the bad case
15211 // (adding everything to a Map) in for every insert/move.
15212 // If you change this code, also update reconcileChildrenIterator() which
15213 // uses the same algorithm.
15214 {
15215 // First, validate keys.
15216 var knownKeys = null;
15217
15218 for (var i = 0; i < newChildren.length; i++) {
15219 var child = newChildren[i];
15220 knownKeys = warnOnInvalidKey(child, knownKeys, returnFiber);
15221 }
15222 }
15223
15224 var resultingFirstChild = null;
15225 var previousNewFiber = null;
15226 var oldFiber = currentFirstChild;
15227 var lastPlacedIndex = 0;
15228 var newIdx = 0;
15229 var nextOldFiber = null;
15230
15231 for (; oldFiber !== null && newIdx < newChildren.length; newIdx++) {
15232 if (oldFiber.index > newIdx) {
15233 nextOldFiber = oldFiber;
15234 oldFiber = null;
15235 } else {
15236 nextOldFiber = oldFiber.sibling;
15237 }
15238
15239 var newFiber = updateSlot(returnFiber, oldFiber, newChildren[newIdx], lanes, debugInfo);
15240
15241 if (newFiber === null) {
15242 // TODO: This breaks on empty slots like null children. That's
15243 // unfortunate because it triggers the slow path all the time. We need
15244 // a better way to communicate whether this was a miss or null,
15245 // boolean, undefined, etc.
15246 if (oldFiber === null) {
15247 oldFiber = nextOldFiber;
15248 }
15249
15250 break;
15251 }
15252
15253 if (shouldTrackSideEffects) {
15254 if (oldFiber && newFiber.alternate === null) {
15255 // We matched the slot, but we didn't reuse the existing fiber, so we
15256 // need to delete the existing child.
15257 deleteChild(returnFiber, oldFiber);
15258 }
15259 }
15260
15261 lastPlacedIndex = placeChild(newFiber, lastPlacedIndex, newIdx);
15262
15263 if (previousNewFiber === null) {
15264 // TODO: Move out of the loop. This only happens for the first run.
15265 resultingFirstChild = newFiber;
15266 } else {
15267 // TODO: Defer siblings if we're not at the right index for this slot.
15268 // I.e. if we had null values before, then we want to defer this
15269 // for each null value. However, we also don't want to call updateSlot
15270 // with the previous one.
15271 previousNewFiber.sibling = newFiber;
15272 }
15273
15274 previousNewFiber = newFiber;
15275 oldFiber = nextOldFiber;
15276 }
15277
15278 if (newIdx === newChildren.length) {
15279 // We've reached the end of the new children. We can delete the rest.
15280 deleteRemainingChildren(returnFiber, oldFiber);
15281
15282 if (getIsHydrating()) {
15283 var numberOfForks = newIdx;
15284 pushTreeFork(returnFiber, numberOfForks);
15285 }
15286
15287 return resultingFirstChild;
15288 }
15289
15290 if (oldFiber === null) {
15291 // If we don't have any more existing children we can choose a fast path
15292 // since the rest will all be insertions.
15293 for (; newIdx < newChildren.length; newIdx++) {
15294 var _newFiber = createChild(returnFiber, newChildren[newIdx], lanes, debugInfo);
15295
15296 if (_newFiber === null) {
15297 continue;
15298 }
15299
15300 lastPlacedIndex = placeChild(_newFiber, lastPlacedIndex, newIdx);
15301
15302 if (previousNewFiber === null) {
15303 // TODO: Move out of the loop. This only happens for the first run.
15304 resultingFirstChild = _newFiber;
15305 } else {
15306 previousNewFiber.sibling = _newFiber;
15307 }
15308
15309 previousNewFiber = _newFiber;
15310 }
15311
15312 if (getIsHydrating()) {
15313 var _numberOfForks = newIdx;
15314 pushTreeFork(returnFiber, _numberOfForks);
15315 }
15316
15317 return resultingFirstChild;
15318 } // Add all children to a key map for quick lookups.
15319
15320
15321 var existingChildren = mapRemainingChildren(oldFiber); // Keep scanning and use the map to restore deleted items as moves.
15322
15323 for (; newIdx < newChildren.length; newIdx++) {
15324 var _newFiber2 = updateFromMap(existingChildren, returnFiber, newIdx, newChildren[newIdx], lanes, debugInfo);
15325
15326 if (_newFiber2 !== null) {
15327 if (shouldTrackSideEffects) {
15328 if (_newFiber2.alternate !== null) {
15329 // The new fiber is a work in progress, but if there exists a
15330 // current, that means that we reused the fiber. We need to delete
15331 // it from the child list so that we don't add it to the deletion
15332 // list.
15333 existingChildren.delete(_newFiber2.key === null ? newIdx : _newFiber2.key);
15334 }
15335 }
15336
15337 lastPlacedIndex = placeChild(_newFiber2, lastPlacedIndex, newIdx);
15338
15339 if (previousNewFiber === null) {
15340 resultingFirstChild = _newFiber2;
15341 } else {
15342 previousNewFiber.sibling = _newFiber2;
15343 }
15344
15345 previousNewFiber = _newFiber2;
15346 }
15347 }
15348
15349 if (shouldTrackSideEffects) {
15350 // Any existing children that weren't consumed above were deleted. We need
15351 // to add them to the deletion list.
15352 existingChildren.forEach(function (child) {
15353 return deleteChild(returnFiber, child);
15354 });
15355 }
15356
15357 if (getIsHydrating()) {
15358 var _numberOfForks2 = newIdx;
15359 pushTreeFork(returnFiber, _numberOfForks2);
15360 }
15361
15362 return resultingFirstChild;
15363 }
15364
15365 function reconcileChildrenIteratable(returnFiber, currentFirstChild, newChildrenIterable, lanes, debugInfo) {
15366 // This is the same implementation as reconcileChildrenArray(),
15367 // but using the iterator instead.
15368 var iteratorFn = getIteratorFn(newChildrenIterable);
15369
15370 if (typeof iteratorFn !== 'function') {
15371 throw new Error('An object is not an iterable. This error is likely caused by a bug in ' + 'React. Please file an issue.');
15372 }
15373
15374 var newChildren = iteratorFn.call(newChildrenIterable);
15375
15376 {
15377 if (newChildren === newChildrenIterable) {
15378 // We don't support rendering Generators as props because it's a mutation.
15379 // See https://github.com/facebook/react/issues/12995
15380 // We do support generators if they were created by a GeneratorFunction component
15381 // as its direct child since we can recreate those by rerendering the component
15382 // as needed.
15383 var isGeneratorComponent = returnFiber.tag === FunctionComponent && // $FlowFixMe[method-unbinding]
15384 Object.prototype.toString.call(returnFiber.type) === '[object GeneratorFunction]' && // $FlowFixMe[method-unbinding]
15385 Object.prototype.toString.call(newChildren) === '[object Generator]';
15386
15387 if (!isGeneratorComponent) {
15388 if (!didWarnAboutGenerators) {
15389 error('Using Iterators 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. You can also use an ' + 'Iterable that can iterate multiple times over the same items.');
15390 }
15391
15392 didWarnAboutGenerators = true;
15393 }
15394 } else if (newChildrenIterable.entries === iteratorFn) {
15395 // Warn about using Maps as children
15396 if (!didWarnAboutMaps) {
15397 error('Using Maps as children is not supported. ' + 'Use an array of keyed ReactElements instead.');
15398
15399 didWarnAboutMaps = true;
15400 }
15401 }
15402 }
15403
15404 return reconcileChildrenIterator(returnFiber, currentFirstChild, newChildren, lanes, debugInfo);
15405 }
15406
15407 function reconcileChildrenIterator(returnFiber, currentFirstChild, newChildren, lanes, debugInfo) {
15408 if (newChildren == null) {
15409 throw new Error('An iterable object provided no iterator.');
15410 }
15411
15412 var resultingFirstChild = null;
15413 var previousNewFiber = null;
15414 var oldFiber = currentFirstChild;
15415 var lastPlacedIndex = 0;
15416 var newIdx = 0;
15417 var nextOldFiber = null;
15418 var knownKeys = null;
15419 var step = newChildren.next();
15420
15421 {
15422 knownKeys = warnOnInvalidKey(step.value, knownKeys, returnFiber);
15423 }
15424
15425 for (; oldFiber !== null && !step.done; newIdx++, step = newChildren.next(), knownKeys = warnOnInvalidKey(step.value, knownKeys, returnFiber) ) {
15426 if (oldFiber.index > newIdx) {
15427 nextOldFiber = oldFiber;
15428 oldFiber = null;
15429 } else {
15430 nextOldFiber = oldFiber.sibling;
15431 }
15432
15433 var newFiber = updateSlot(returnFiber, oldFiber, step.value, lanes, debugInfo);
15434
15435 if (newFiber === null) {
15436 // TODO: This breaks on empty slots like null children. That's
15437 // unfortunate because it triggers the slow path all the time. We need
15438 // a better way to communicate whether this was a miss or null,
15439 // boolean, undefined, etc.
15440 if (oldFiber === null) {
15441 oldFiber = nextOldFiber;
15442 }
15443
15444 break;
15445 }
15446
15447 if (shouldTrackSideEffects) {
15448 if (oldFiber && newFiber.alternate === null) {
15449 // We matched the slot, but we didn't reuse the existing fiber, so we
15450 // need to delete the existing child.
15451 deleteChild(returnFiber, oldFiber);
15452 }
15453 }
15454
15455 lastPlacedIndex = placeChild(newFiber, lastPlacedIndex, newIdx);
15456
15457 if (previousNewFiber === null) {
15458 // TODO: Move out of the loop. This only happens for the first run.
15459 resultingFirstChild = newFiber;
15460 } else {
15461 // TODO: Defer siblings if we're not at the right index for this slot.
15462 // I.e. if we had null values before, then we want to defer this
15463 // for each null value. However, we also don't want to call updateSlot
15464 // with the previous one.
15465 previousNewFiber.sibling = newFiber;
15466 }
15467
15468 previousNewFiber = newFiber;
15469 oldFiber = nextOldFiber;
15470 }
15471
15472 if (step.done) {
15473 // We've reached the end of the new children. We can delete the rest.
15474 deleteRemainingChildren(returnFiber, oldFiber);
15475
15476 if (getIsHydrating()) {
15477 var numberOfForks = newIdx;
15478 pushTreeFork(returnFiber, numberOfForks);
15479 }
15480
15481 return resultingFirstChild;
15482 }
15483
15484 if (oldFiber === null) {
15485 // If we don't have any more existing children we can choose a fast path
15486 // since the rest will all be insertions.
15487 for (; !step.done; newIdx++, step = newChildren.next(), knownKeys = warnOnInvalidKey(step.value, knownKeys, returnFiber) ) {
15488 var _newFiber3 = createChild(returnFiber, step.value, lanes, debugInfo);
15489
15490 if (_newFiber3 === null) {
15491 continue;
15492 }
15493
15494 lastPlacedIndex = placeChild(_newFiber3, lastPlacedIndex, newIdx);
15495
15496 if (previousNewFiber === null) {
15497 // TODO: Move out of the loop. This only happens for the first run.
15498 resultingFirstChild = _newFiber3;
15499 } else {
15500 previousNewFiber.sibling = _newFiber3;
15501 }
15502
15503 previousNewFiber = _newFiber3;
15504 }
15505
15506 if (getIsHydrating()) {
15507 var _numberOfForks3 = newIdx;
15508 pushTreeFork(returnFiber, _numberOfForks3);
15509 }
15510
15511 return resultingFirstChild;
15512 } // Add all children to a key map for quick lookups.
15513
15514
15515 var existingChildren = mapRemainingChildren(oldFiber); // Keep scanning and use the map to restore deleted items as moves.
15516
15517 for (; !step.done; newIdx++, step = newChildren.next(), knownKeys = warnOnInvalidKey(step.value, knownKeys, returnFiber) ) {
15518 var _newFiber4 = updateFromMap(existingChildren, returnFiber, newIdx, step.value, lanes, debugInfo);
15519
15520 if (_newFiber4 !== null) {
15521 if (shouldTrackSideEffects) {
15522 if (_newFiber4.alternate !== null) {
15523 // The new fiber is a work in progress, but if there exists a
15524 // current, that means that we reused the fiber. We need to delete
15525 // it from the child list so that we don't add it to the deletion
15526 // list.
15527 existingChildren.delete(_newFiber4.key === null ? newIdx : _newFiber4.key);
15528 }
15529 }
15530
15531 lastPlacedIndex = placeChild(_newFiber4, lastPlacedIndex, newIdx);
15532
15533 if (previousNewFiber === null) {
15534 resultingFirstChild = _newFiber4;
15535 } else {
15536 previousNewFiber.sibling = _newFiber4;
15537 }
15538
15539 previousNewFiber = _newFiber4;
15540 }
15541 }
15542
15543 if (shouldTrackSideEffects) {
15544 // Any existing children that weren't consumed above were deleted. We need
15545 // to add them to the deletion list.
15546 existingChildren.forEach(function (child) {
15547 return deleteChild(returnFiber, child);
15548 });
15549 }
15550
15551 if (getIsHydrating()) {
15552 var _numberOfForks4 = newIdx;
15553 pushTreeFork(returnFiber, _numberOfForks4);
15554 }
15555
15556 return resultingFirstChild;
15557 }
15558
15559 function reconcileSingleTextNode(returnFiber, currentFirstChild, textContent, lanes) {
15560 // There's no need to check for keys on text nodes since we don't have a
15561 // way to define them.
15562 if (currentFirstChild !== null && currentFirstChild.tag === HostText) {
15563 // We already have an existing node so let's just update it and delete
15564 // the rest.
15565 deleteRemainingChildren(returnFiber, currentFirstChild.sibling);
15566 var existing = useFiber(currentFirstChild, textContent);
15567 existing.return = returnFiber;
15568 return existing;
15569 } // The existing first child is not a text node so we need to create one
15570 // and delete the existing ones.
15571
15572
15573 deleteRemainingChildren(returnFiber, currentFirstChild);
15574 var created = createFiberFromText(textContent, returnFiber.mode, lanes);
15575 created.return = returnFiber;
15576 return created;
15577 }
15578
15579 function reconcileSingleElement(returnFiber, currentFirstChild, element, lanes, debugInfo) {
15580 var key = element.key;
15581 var child = currentFirstChild;
15582
15583 while (child !== null) {
15584 // TODO: If key === null and child.key === null, then this only applies to
15585 // the first item in the list.
15586 if (child.key === key) {
15587 var elementType = element.type;
15588
15589 if (elementType === REACT_FRAGMENT_TYPE) {
15590 if (child.tag === Fragment) {
15591 deleteRemainingChildren(returnFiber, child.sibling);
15592 var existing = useFiber(child, element.props.children);
15593 existing.return = returnFiber;
15594
15595 {
15596 existing._debugOwner = element._owner;
15597 existing._debugInfo = debugInfo;
15598 }
15599
15600 return existing;
15601 }
15602 } else {
15603 if (child.elementType === elementType || ( // Keep this check inline so it only runs on the false path:
15604 isCompatibleFamilyForHotReloading(child, element) ) || // Lazy types should reconcile their resolved type.
15605 // We need to do this after the Hot Reloading check above,
15606 // because hot reloading has different semantics than prod because
15607 // it doesn't resuspend. So we can't let the call below suspend.
15608 typeof elementType === 'object' && elementType !== null && elementType.$$typeof === REACT_LAZY_TYPE && resolveLazy(elementType) === child.type) {
15609 deleteRemainingChildren(returnFiber, child.sibling);
15610
15611 var _existing = useFiber(child, element.props);
15612
15613 coerceRef(returnFiber, child, _existing, element);
15614 _existing.return = returnFiber;
15615
15616 {
15617 _existing._debugOwner = element._owner;
15618 _existing._debugInfo = debugInfo;
15619 }
15620
15621 return _existing;
15622 }
15623 } // Didn't match.
15624
15625
15626 deleteRemainingChildren(returnFiber, child);
15627 break;
15628 } else {
15629 deleteChild(returnFiber, child);
15630 }
15631
15632 child = child.sibling;
15633 }
15634
15635 if (element.type === REACT_FRAGMENT_TYPE) {
15636 var created = createFiberFromFragment(element.props.children, returnFiber.mode, lanes, element.key);
15637 created.return = returnFiber;
15638
15639 {
15640 created._debugInfo = debugInfo;
15641 }
15642
15643 return created;
15644 } else {
15645 var _created4 = createFiberFromElement(element, returnFiber.mode, lanes);
15646
15647 coerceRef(returnFiber, currentFirstChild, _created4, element);
15648 _created4.return = returnFiber;
15649
15650 {
15651 _created4._debugInfo = debugInfo;
15652 }
15653
15654 return _created4;
15655 }
15656 }
15657
15658 function reconcileSinglePortal(returnFiber, currentFirstChild, portal, lanes, debugInfo) {
15659 var key = portal.key;
15660 var child = currentFirstChild;
15661
15662 while (child !== null) {
15663 // TODO: If key === null and child.key === null, then this only applies to
15664 // the first item in the list.
15665 if (child.key === key) {
15666 if (child.tag === HostPortal && child.stateNode.containerInfo === portal.containerInfo && child.stateNode.implementation === portal.implementation) {
15667 deleteRemainingChildren(returnFiber, child.sibling);
15668 var existing = useFiber(child, portal.children || []);
15669 existing.return = returnFiber;
15670 return existing;
15671 } else {
15672 deleteRemainingChildren(returnFiber, child);
15673 break;
15674 }
15675 } else {
15676 deleteChild(returnFiber, child);
15677 }
15678
15679 child = child.sibling;
15680 }
15681
15682 var created = createFiberFromPortal(portal, returnFiber.mode, lanes);
15683 created.return = returnFiber;
15684 return created;
15685 } // This API will tag the children with the side-effect of the reconciliation
15686 // itself. They will be added to the side-effect list as we pass through the
15687 // children and the parent.
15688
15689
15690 function reconcileChildFibersImpl(returnFiber, currentFirstChild, newChild, lanes, debugInfo) {
15691 // This function is only recursive for Usables/Lazy and not nested arrays.
15692 // That's so that using a Lazy wrapper is unobservable to the Fragment
15693 // convention.
15694 // If the top level item is an array, we treat it as a set of children,
15695 // not as a fragment. Nested arrays on the other hand will be treated as
15696 // fragment nodes. Recursion happens at the normal flow.
15697 // Handle top level unkeyed fragments as if they were arrays.
15698 // This leads to an ambiguity between <>{[...]}</> and <>...</>.
15699 // We treat the ambiguous cases above the same.
15700 // We don't use recursion here because a fragment inside a fragment
15701 // is no longer considered "top level" for these purposes.
15702 var isUnkeyedTopLevelFragment = typeof newChild === 'object' && newChild !== null && newChild.type === REACT_FRAGMENT_TYPE && newChild.key === null;
15703
15704 if (isUnkeyedTopLevelFragment) {
15705 newChild = newChild.props.children;
15706 } // Handle object types
15707
15708
15709 if (typeof newChild === 'object' && newChild !== null) {
15710 switch (newChild.$$typeof) {
15711 case REACT_ELEMENT_TYPE:
15712 return placeSingleChild(reconcileSingleElement(returnFiber, currentFirstChild, newChild, lanes, mergeDebugInfo(debugInfo, newChild._debugInfo)));
15713
15714 case REACT_PORTAL_TYPE:
15715 return placeSingleChild(reconcileSinglePortal(returnFiber, currentFirstChild, newChild, lanes));
15716
15717 case REACT_LAZY_TYPE:
15718 var payload = newChild._payload;
15719 var init = newChild._init;
15720 return reconcileChildFibersImpl(returnFiber, currentFirstChild, init(payload), lanes, mergeDebugInfo(debugInfo, newChild._debugInfo));
15721 }
15722
15723 if (isArray(newChild)) {
15724 return reconcileChildrenArray(returnFiber, currentFirstChild, newChild, lanes, mergeDebugInfo(debugInfo, newChild._debugInfo));
15725 }
15726
15727 if (getIteratorFn(newChild)) {
15728 return reconcileChildrenIteratable(returnFiber, currentFirstChild, newChild, lanes, mergeDebugInfo(debugInfo, newChild._debugInfo));
15729 }
15730 // a child position, it unwraps it using the same algorithm as `use`. For
15731 // example, for promises, React will throw an exception to unwind the
15732 // stack, then replay the component once the promise resolves.
15733 //
15734 // A difference from `use` is that React will keep unwrapping the value
15735 // until it reaches a non-Usable type.
15736 //
15737 // e.g. Usable<Usable<Usable<T>>> should resolve to T
15738 //
15739 // The structure is a bit unfortunate. Ideally, we shouldn't need to
15740 // replay the entire begin phase of the parent fiber in order to reconcile
15741 // the children again. This would require a somewhat significant refactor,
15742 // because reconcilation happens deep within the begin phase, and
15743 // depending on the type of work, not always at the end. We should
15744 // consider as an future improvement.
15745
15746
15747 if (typeof newChild.then === 'function') {
15748 var thenable = newChild;
15749 return reconcileChildFibersImpl(returnFiber, currentFirstChild, unwrapThenable(thenable), lanes, mergeDebugInfo(debugInfo, thenable._debugInfo));
15750 }
15751
15752 if (newChild.$$typeof === REACT_CONTEXT_TYPE) {
15753 var context = newChild;
15754 return reconcileChildFibersImpl(returnFiber, currentFirstChild, readContextDuringReconciliation(returnFiber, context, lanes), lanes, debugInfo);
15755 }
15756
15757 throwOnInvalidObjectType(returnFiber, newChild);
15758 }
15759
15760 if (typeof newChild === 'string' && newChild !== '' || typeof newChild === 'number' || typeof newChild === 'bigint') {
15761 return placeSingleChild(reconcileSingleTextNode(returnFiber, currentFirstChild, // $FlowFixMe[unsafe-addition] Flow doesn't want us to use `+` operator with string and bigint
15762 '' + newChild, lanes));
15763 }
15764
15765 {
15766 if (typeof newChild === 'function') {
15767 warnOnFunctionType(returnFiber, newChild);
15768 }
15769
15770 if (typeof newChild === 'symbol') {
15771 warnOnSymbolType(returnFiber, newChild);
15772 }
15773 } // Remaining cases are all treated as empty.
15774
15775
15776 return deleteRemainingChildren(returnFiber, currentFirstChild);
15777 }
15778
15779 function reconcileChildFibers(returnFiber, currentFirstChild, newChild, lanes) {
15780 // This indirection only exists so we can reset `thenableState` at the end.
15781 // It should get inlined by Closure.
15782 thenableIndexCounter$1 = 0;
15783 var firstChildFiber = reconcileChildFibersImpl(returnFiber, currentFirstChild, newChild, lanes, null // debugInfo
15784 );
15785 thenableState$1 = null; // Don't bother to reset `thenableIndexCounter` to 0 because it always gets
15786 // set at the beginning.
15787
15788 return firstChildFiber;
15789 }
15790
15791 return reconcileChildFibers;
15792}
15793
15794var reconcileChildFibers = createChildReconciler(true);
15795var mountChildFibers = createChildReconciler(false);
15796function resetChildReconcilerOnUnwind() {
15797 // On unwind, clear any pending thenables that were used.
15798 thenableState$1 = null;
15799 thenableIndexCounter$1 = 0;
15800}
15801function cloneChildFibers(current, workInProgress) {
15802 if (current !== null && workInProgress.child !== current.child) {
15803 throw new Error('Resuming work not yet implemented.');
15804 }
15805
15806 if (workInProgress.child === null) {
15807 return;
15808 }
15809
15810 var currentChild = workInProgress.child;
15811 var newChild = createWorkInProgress(currentChild, currentChild.pendingProps);
15812 workInProgress.child = newChild;
15813 newChild.return = workInProgress;
15814
15815 while (currentChild.sibling !== null) {
15816 currentChild = currentChild.sibling;
15817 newChild = newChild.sibling = createWorkInProgress(currentChild, currentChild.pendingProps);
15818 newChild.return = workInProgress;
15819 }
15820
15821 newChild.sibling = null;
15822} // Reset a workInProgress child set to prepare it for a second pass.
15823
15824function resetChildFibers(workInProgress, lanes) {
15825 var child = workInProgress.child;
15826
15827 while (child !== null) {
15828 resetWorkInProgress(child, lanes);
15829 child = child.sibling;
15830 }
15831}
15832
15833// TODO: This isn't being used yet, but it's intended to replace the
15834// InvisibleParentContext that is currently managed by SuspenseContext.
15835
15836var currentTreeHiddenStackCursor = createCursor(null);
15837var prevEntangledRenderLanesCursor = createCursor(NoLanes);
15838function pushHiddenContext(fiber, context) {
15839 var prevEntangledRenderLanes = getEntangledRenderLanes();
15840 push(prevEntangledRenderLanesCursor, prevEntangledRenderLanes, fiber);
15841 push(currentTreeHiddenStackCursor, context, fiber); // When rendering a subtree that's currently hidden, we must include all
15842 // lanes that would have rendered if the hidden subtree hadn't been deferred.
15843 // That is, in order to reveal content from hidden -> visible, we must commit
15844 // all the updates that we skipped when we originally hid the tree.
15845
15846 setEntangledRenderLanes(mergeLanes(prevEntangledRenderLanes, context.baseLanes));
15847}
15848function reuseHiddenContextOnStack(fiber) {
15849 // This subtree is not currently hidden, so we don't need to add any lanes
15850 // to the render lanes. But we still need to push something to avoid a
15851 // context mismatch. Reuse the existing context on the stack.
15852 push(prevEntangledRenderLanesCursor, getEntangledRenderLanes(), fiber);
15853 push(currentTreeHiddenStackCursor, currentTreeHiddenStackCursor.current, fiber);
15854}
15855function popHiddenContext(fiber) {
15856 // Restore the previous render lanes from the stack
15857 setEntangledRenderLanes(prevEntangledRenderLanesCursor.current);
15858 pop(currentTreeHiddenStackCursor, fiber);
15859 pop(prevEntangledRenderLanesCursor, fiber);
15860}
15861function isCurrentTreeHidden() {
15862 return currentTreeHiddenStackCursor.current !== null;
15863}
15864
15865// suspends, i.e. it's the nearest `catch` block on the stack.
15866
15867var suspenseHandlerStackCursor = createCursor(null); // Represents the outermost boundary that is not visible in the current tree.
15868// Everything above this is the "shell". When this is null, it means we're
15869// rendering in the shell of the app. If it's non-null, it means we're rendering
15870// deeper than the shell, inside a new tree that wasn't already visible.
15871//
15872// The main way we use this concept is to determine whether showing a fallback
15873// would result in a desirable or undesirable loading state. Activing a fallback
15874// in the shell is considered an undersirable loading state, because it would
15875// mean hiding visible (albeit stale) content in the current tree — we prefer to
15876// show the stale content, rather than switch to a fallback. But showing a
15877// fallback in a new tree is fine, because there's no stale content to
15878// prefer instead.
15879
15880var shellBoundary = null;
15881function getShellBoundary() {
15882 return shellBoundary;
15883}
15884function pushPrimaryTreeSuspenseHandler(handler) {
15885 // TODO: Pass as argument
15886 var current = handler.alternate;
15887 // propagated a single level. For example, when ForceSuspenseFallback is set,
15888 // it should only force the nearest Suspense boundary into fallback mode.
15889
15890 pushSuspenseListContext(handler, setDefaultShallowSuspenseListContext(suspenseStackCursor.current)); // Experimental feature: Some Suspense boundaries are marked as having an
15891 // to push a nested Suspense handler, because it will get replaced by the
15892 // outer fallback, anyway. Consider this as a future optimization.
15893
15894
15895 push(suspenseHandlerStackCursor, handler, handler);
15896
15897 if (shellBoundary === null) {
15898 if (current === null || isCurrentTreeHidden()) {
15899 // This boundary is not visible in the current UI.
15900 shellBoundary = handler;
15901 } else {
15902 var prevState = current.memoizedState;
15903
15904 if (prevState !== null) {
15905 // This boundary is showing a fallback in the current UI.
15906 shellBoundary = handler;
15907 }
15908 }
15909 }
15910}
15911function pushFallbackTreeSuspenseHandler(fiber) {
15912 // We're about to render the fallback. If something in the fallback suspends,
15913 // it's akin to throwing inside of a `catch` block. This boundary should not
15914 // capture. Reuse the existing handler on the stack.
15915 reuseSuspenseHandlerOnStack(fiber);
15916}
15917function pushOffscreenSuspenseHandler(fiber) {
15918 if (fiber.tag === OffscreenComponent) {
15919 // A SuspenseList context is only pushed here to avoid a push/pop mismatch.
15920 // Reuse the current value on the stack.
15921 // TODO: We can avoid needing to push here by by forking popSuspenseHandler
15922 // into separate functions for Suspense and Offscreen.
15923 pushSuspenseListContext(fiber, suspenseStackCursor.current);
15924 push(suspenseHandlerStackCursor, fiber, fiber);
15925
15926 if (shellBoundary !== null) ; else {
15927 var current = fiber.alternate;
15928
15929 if (current !== null) {
15930 var prevState = current.memoizedState;
15931
15932 if (prevState !== null) {
15933 // This is the first boundary in the stack that's already showing
15934 // a fallback. So everything outside is considered the shell.
15935 shellBoundary = fiber;
15936 }
15937 }
15938 }
15939 } else {
15940 // This is a LegacyHidden component.
15941 reuseSuspenseHandlerOnStack(fiber);
15942 }
15943}
15944function reuseSuspenseHandlerOnStack(fiber) {
15945 pushSuspenseListContext(fiber, suspenseStackCursor.current);
15946 push(suspenseHandlerStackCursor, getSuspenseHandler(), fiber);
15947}
15948function getSuspenseHandler() {
15949 return suspenseHandlerStackCursor.current;
15950}
15951function popSuspenseHandler(fiber) {
15952 pop(suspenseHandlerStackCursor, fiber);
15953
15954 if (shellBoundary === fiber) {
15955 // Popping back into the shell.
15956 shellBoundary = null;
15957 }
15958
15959 popSuspenseListContext(fiber);
15960} // SuspenseList context
15961// TODO: Move to a separate module? We may change the SuspenseList
15962// implementation to hide/show in the commit phase, anyway.
15963
15964var DefaultSuspenseContext = 0;
15965var SubtreeSuspenseContextMask = 1; // ForceSuspenseFallback can be used by SuspenseList to force newly added
15966// items into their fallback state during one of the render passes.
15967
15968var ForceSuspenseFallback = 2;
15969var suspenseStackCursor = createCursor(DefaultSuspenseContext);
15970function hasSuspenseListContext(parentContext, flag) {
15971 return (parentContext & flag) !== 0;
15972}
15973function setDefaultShallowSuspenseListContext(parentContext) {
15974 return parentContext & SubtreeSuspenseContextMask;
15975}
15976function setShallowSuspenseListContext(parentContext, shallowContext) {
15977 return parentContext & SubtreeSuspenseContextMask | shallowContext;
15978}
15979function pushSuspenseListContext(fiber, newContext) {
15980 push(suspenseStackCursor, newContext, fiber);
15981}
15982function popSuspenseListContext(fiber) {
15983 pop(suspenseStackCursor, fiber);
15984}
15985
15986// A non-null SuspenseState means that it is blocked for one reason or another.
15987// - A non-null dehydrated field means it's blocked pending hydration.
15988// - A non-null dehydrated field can use isSuspenseInstancePending or
15989// isSuspenseInstanceFallback to query the reason for being dehydrated.
15990// - A null dehydrated field means it's blocked by something suspending and
15991// we're currently showing a fallback instead.
15992
15993function findFirstSuspended(row) {
15994 var node = row;
15995
15996 while (node !== null) {
15997 if (node.tag === SuspenseComponent) {
15998 var state = node.memoizedState;
15999
16000 if (state !== null) {
16001 var dehydrated = state.dehydrated;
16002
16003 if (dehydrated === null || isSuspenseInstancePending(dehydrated) || isSuspenseInstanceFallback(dehydrated)) {
16004 return node;
16005 }
16006 }
16007 } else if (node.tag === SuspenseListComponent && // revealOrder undefined can't be trusted because it don't
16008 // keep track of whether it suspended or not.
16009 node.memoizedProps.revealOrder !== undefined) {
16010 var didSuspend = (node.flags & DidCapture) !== NoFlags$1;
16011
16012 if (didSuspend) {
16013 return node;
16014 }
16015 } else if (node.child !== null) {
16016 node.child.return = node;
16017 node = node.child;
16018 continue;
16019 }
16020
16021 if (node === row) {
16022 return null;
16023 }
16024
16025 while (node.sibling === null) {
16026 if (node.return === null || node.return === row) {
16027 return null;
16028 }
16029
16030 node = node.return;
16031 }
16032
16033 node.sibling.return = node.return;
16034 node = node.sibling;
16035 }
16036
16037 return null;
16038}
16039
16040var NoFlags =
16041/* */
160420; // Represents whether effect should fire.
16043
16044var HasEffect =
16045/* */
160461; // Represents the phase in which the effect (not the clean-up) fires.
16047
16048var Insertion =
16049/* */
160502;
16051var Layout =
16052/* */
160534;
16054var Passive =
16055/* */
160568;
16057
16058// replace it with a lightweight shim that only has the features we use.
16059
16060var AbortControllerLocal = typeof AbortController !== 'undefined' ? AbortController : // $FlowFixMe[missing-this-annot]
16061// $FlowFixMe[prop-missing]
16062function AbortControllerShim() {
16063 var listeners = [];
16064 var signal = this.signal = {
16065 aborted: false,
16066 addEventListener: function (type, listener) {
16067 listeners.push(listener);
16068 }
16069 };
16070
16071 this.abort = function () {
16072 signal.aborted = true;
16073 listeners.forEach(function (listener) {
16074 return listener();
16075 });
16076 };
16077} ; // Intentionally not named imports because Rollup would
16078// use dynamic dispatch for CommonJS interop named imports.
16079
16080var scheduleCallback$2 = Scheduler.unstable_scheduleCallback,
16081 NormalPriority = Scheduler.unstable_NormalPriority;
16082var CacheContext = {
16083 $$typeof: REACT_CONTEXT_TYPE,
16084 // We don't use Consumer/Provider for Cache components. So we'll cheat.
16085 Consumer: null,
16086 Provider: null,
16087 // We'll initialize these at the root.
16088 _currentValue: null,
16089 _currentValue2: null,
16090 _threadCount: 0
16091} ;
16092
16093{
16094 CacheContext._currentRenderer = null;
16095 CacheContext._currentRenderer2 = null;
16096} // Creates a new empty Cache instance with a ref-count of 0. The caller is responsible
16097// for retaining the cache once it is in use (retainCache), and releasing the cache
16098// once it is no longer needed (releaseCache).
16099
16100
16101function createCache() {
16102
16103 var cache = {
16104 controller: new AbortControllerLocal(),
16105 data: new Map(),
16106 refCount: 0
16107 };
16108 return cache;
16109}
16110function retainCache(cache) {
16111
16112 {
16113 if (cache.controller.signal.aborted) {
16114 warn('A cache instance was retained after it was already freed. ' + 'This likely indicates a bug in React.');
16115 }
16116 }
16117
16118 cache.refCount++;
16119} // Cleanup a cache instance, potentially freeing it if there are no more references
16120
16121function releaseCache(cache) {
16122
16123 cache.refCount--;
16124
16125 {
16126 if (cache.refCount < 0) {
16127 warn('A cache instance was released after it was already freed. ' + 'This likely indicates a bug in React.');
16128 }
16129 }
16130
16131 if (cache.refCount === 0) {
16132 scheduleCallback$2(NormalPriority, function () {
16133 cache.controller.abort();
16134 });
16135 }
16136}
16137function pushCacheProvider(workInProgress, cache) {
16138
16139 pushProvider(workInProgress, CacheContext, cache);
16140}
16141function popCacheProvider(workInProgress, cache) {
16142
16143 popProvider(CacheContext, workInProgress);
16144}
16145
16146// there's only a single root, but we do support multi root apps, hence this
16147// extra complexity. But this module is optimized for the single root case.
16148
16149var firstScheduledRoot = null;
16150var lastScheduledRoot = null; // Used to prevent redundant mircotasks from being scheduled.
16151
16152var didScheduleMicrotask = false; // `act` "microtasks" are scheduled on the `act` queue instead of an actual
16153// microtask, so we have to dedupe those separately. This wouldn't be an issue
16154// if we required all `act` calls to be awaited, which we might in the future.
16155
16156var didScheduleMicrotask_act = false; // Used to quickly bail out of flushSync if there's no sync work to do.
16157
16158var mightHavePendingSyncWork = false;
16159var isFlushingWork = false;
16160var currentEventTransitionLane = NoLane;
16161function ensureRootIsScheduled(root) {
16162 // This function is called whenever a root receives an update. It does two
16163 // things 1) it ensures the root is in the root schedule, and 2) it ensures
16164 // there's a pending microtask to process the root schedule.
16165 //
16166 // Most of the actual scheduling logic does not happen until
16167 // `scheduleTaskForRootDuringMicrotask` runs.
16168 // Add the root to the schedule
16169 if (root === lastScheduledRoot || root.next !== null) ; else {
16170 if (lastScheduledRoot === null) {
16171 firstScheduledRoot = lastScheduledRoot = root;
16172 } else {
16173 lastScheduledRoot.next = root;
16174 lastScheduledRoot = root;
16175 }
16176 } // Any time a root received an update, we set this to true until the next time
16177 // we process the schedule. If it's false, then we can quickly exit flushSync
16178 // without consulting the schedule.
16179
16180
16181 mightHavePendingSyncWork = true; // At the end of the current event, go through each of the roots and ensure
16182 // there's a task scheduled for each one at the correct priority.
16183
16184 if (ReactSharedInternals.actQueue !== null) {
16185 // We're inside an `act` scope.
16186 if (!didScheduleMicrotask_act) {
16187 didScheduleMicrotask_act = true;
16188 scheduleImmediateTask(processRootScheduleInMicrotask);
16189 }
16190 } else {
16191 if (!didScheduleMicrotask) {
16192 didScheduleMicrotask = true;
16193 scheduleImmediateTask(processRootScheduleInMicrotask);
16194 }
16195 }
16196}
16197function flushSyncWorkOnAllRoots() {
16198 // This is allowed to be called synchronously, but the caller should check
16199 // the execution context first.
16200 flushSyncWorkAcrossRoots_impl(false);
16201}
16202
16203function flushSyncWorkAcrossRoots_impl(onlyLegacy) {
16204 if (isFlushingWork) {
16205 // Prevent reentrancy.
16206 // TODO: Is this overly defensive? The callers must check the execution
16207 // context first regardless.
16208 return;
16209 }
16210
16211 if (!mightHavePendingSyncWork) {
16212 // Fast path. There's no sync work to do.
16213 return;
16214 } // There may or may not be synchronous work scheduled. Let's check.
16215
16216
16217 var didPerformSomeWork;
16218 isFlushingWork = true;
16219
16220 do {
16221 didPerformSomeWork = false;
16222 var root = firstScheduledRoot;
16223
16224 while (root !== null) {
16225 if (onlyLegacy && (disableLegacyMode )) ; else {
16226 var workInProgressRoot = getWorkInProgressRoot();
16227 var workInProgressRootRenderLanes = getWorkInProgressRootRenderLanes();
16228 var nextLanes = getNextLanes(root, root === workInProgressRoot ? workInProgressRootRenderLanes : NoLanes);
16229
16230 if (includesSyncLane(nextLanes)) {
16231 // This root has pending sync work. Flush it now.
16232 didPerformSomeWork = true;
16233 performSyncWorkOnRoot(root, nextLanes);
16234 }
16235 }
16236
16237 root = root.next;
16238 }
16239 } while (didPerformSomeWork);
16240
16241 isFlushingWork = false;
16242}
16243
16244function processRootScheduleInMicrotask() {
16245 // This function is always called inside a microtask. It should never be
16246 // called synchronously.
16247 didScheduleMicrotask = false;
16248
16249 {
16250 didScheduleMicrotask_act = false;
16251 } // We'll recompute this as we iterate through all the roots and schedule them.
16252
16253
16254 mightHavePendingSyncWork = false;
16255 var currentTime = now$1();
16256 var prev = null;
16257 var root = firstScheduledRoot;
16258
16259 while (root !== null) {
16260 var next = root.next;
16261
16262 if (currentEventTransitionLane !== NoLane && shouldAttemptEagerTransition()) {
16263 // A transition was scheduled during an event, but we're going to try to
16264 // render it synchronously anyway. We do this during a popstate event to
16265 // preserve the scroll position of the previous page.
16266 upgradePendingLaneToSync(root, currentEventTransitionLane);
16267 }
16268
16269 var nextLanes = scheduleTaskForRootDuringMicrotask(root, currentTime);
16270
16271 if (nextLanes === NoLane) {
16272 // This root has no more pending work. Remove it from the schedule. To
16273 // guard against subtle reentrancy bugs, this microtask is the only place
16274 // we do this — you can add roots to the schedule whenever, but you can
16275 // only remove them here.
16276 // Null this out so we know it's been removed from the schedule.
16277 root.next = null;
16278
16279 if (prev === null) {
16280 // This is the new head of the list
16281 firstScheduledRoot = next;
16282 } else {
16283 prev.next = next;
16284 }
16285
16286 if (next === null) {
16287 // This is the new tail of the list
16288 lastScheduledRoot = prev;
16289 }
16290 } else {
16291 // This root still has work. Keep it in the list.
16292 prev = root;
16293
16294 if (includesSyncLane(nextLanes)) {
16295 mightHavePendingSyncWork = true;
16296 }
16297 }
16298
16299 root = next;
16300 }
16301
16302 currentEventTransitionLane = NoLane; // At the end of the microtask, flush any pending synchronous work. This has
16303 // to come at the end, because it does actual rendering work that might throw.
16304
16305 flushSyncWorkOnAllRoots();
16306}
16307
16308function scheduleTaskForRootDuringMicrotask(root, currentTime) {
16309 // This function is always called inside a microtask, or at the very end of a
16310 // rendering task right before we yield to the main thread. It should never be
16311 // called synchronously.
16312 //
16313 // TODO: Unless enableDeferRootSchedulingToMicrotask is off. We need to land
16314 // that ASAP to unblock additional features we have planned.
16315 //
16316 // This function also never performs React work synchronously; it should
16317 // only schedule work to be performed later, in a separate task or microtask.
16318 // Check if any lanes are being starved by other work. If so, mark them as
16319 // expired so we know to work on those next.
16320 markStarvedLanesAsExpired(root, currentTime); // Determine the next lanes to work on, and their priority.
16321
16322 var workInProgressRoot = getWorkInProgressRoot();
16323 var workInProgressRootRenderLanes = getWorkInProgressRootRenderLanes();
16324 var nextLanes = getNextLanes(root, root === workInProgressRoot ? workInProgressRootRenderLanes : NoLanes);
16325 var existingCallbackNode = root.callbackNode;
16326
16327 if ( // Check if there's nothing to work on
16328 nextLanes === NoLanes || // If this root is currently suspended and waiting for data to resolve, don't
16329 // schedule a task to render it. We'll either wait for a ping, or wait to
16330 // receive an update.
16331 //
16332 // Suspended render phase
16333 root === workInProgressRoot && isWorkLoopSuspendedOnData() || // Suspended commit phase
16334 root.cancelPendingCommit !== null) {
16335 // Fast path: There's nothing to work on.
16336 if (existingCallbackNode !== null) {
16337 cancelCallback(existingCallbackNode);
16338 }
16339
16340 root.callbackNode = null;
16341 root.callbackPriority = NoLane;
16342 return NoLane;
16343 } // Schedule a new callback in the host environment.
16344
16345
16346 if (includesSyncLane(nextLanes)) {
16347 // Synchronous work is always flushed at the end of the microtask, so we
16348 // don't need to schedule an additional task.
16349 if (existingCallbackNode !== null) {
16350 cancelCallback(existingCallbackNode);
16351 }
16352
16353 root.callbackPriority = SyncLane;
16354 root.callbackNode = null;
16355 return SyncLane;
16356 } else {
16357 // We use the highest priority lane to represent the priority of the callback.
16358 var existingCallbackPriority = root.callbackPriority;
16359 var newCallbackPriority = getHighestPriorityLane(nextLanes);
16360
16361 if (newCallbackPriority === existingCallbackPriority && // Special case related to `act`. If the currently scheduled task is a
16362 // Scheduler task, rather than an `act` task, cancel it and re-schedule
16363 // on the `act` queue.
16364 !(ReactSharedInternals.actQueue !== null && existingCallbackNode !== fakeActCallbackNode$1)) {
16365 // The priority hasn't changed. We can reuse the existing task.
16366 return newCallbackPriority;
16367 } else {
16368 // Cancel the existing callback. We'll schedule a new one below.
16369 cancelCallback(existingCallbackNode);
16370 }
16371
16372 var schedulerPriorityLevel;
16373
16374 switch (lanesToEventPriority(nextLanes)) {
16375 case DiscreteEventPriority:
16376 schedulerPriorityLevel = ImmediatePriority;
16377 break;
16378
16379 case ContinuousEventPriority:
16380 schedulerPriorityLevel = UserBlockingPriority;
16381 break;
16382
16383 case DefaultEventPriority:
16384 schedulerPriorityLevel = NormalPriority$1;
16385 break;
16386
16387 case IdleEventPriority:
16388 schedulerPriorityLevel = IdlePriority;
16389 break;
16390
16391 default:
16392 schedulerPriorityLevel = NormalPriority$1;
16393 break;
16394 }
16395
16396 var newCallbackNode = scheduleCallback$1(schedulerPriorityLevel, performConcurrentWorkOnRoot.bind(null, root));
16397 root.callbackPriority = newCallbackPriority;
16398 root.callbackNode = newCallbackNode;
16399 return newCallbackPriority;
16400 }
16401}
16402
16403function getContinuationForRoot(root, originalCallbackNode) {
16404 // This is called at the end of `performConcurrentWorkOnRoot` to determine
16405 // if we need to schedule a continuation task.
16406 //
16407 // Usually `scheduleTaskForRootDuringMicrotask` only runs inside a microtask;
16408 // however, since most of the logic for determining if we need a continuation
16409 // versus a new task is the same, we cheat a bit and call it here. This is
16410 // only safe to do because we know we're at the end of the browser task.
16411 // So although it's not an actual microtask, it might as well be.
16412 scheduleTaskForRootDuringMicrotask(root, now$1());
16413
16414 if (root.callbackNode === originalCallbackNode) {
16415 // The task node scheduled for this root is the same one that's
16416 // currently executed. Need to return a continuation.
16417 return performConcurrentWorkOnRoot.bind(null, root);
16418 }
16419
16420 return null;
16421}
16422var fakeActCallbackNode$1 = {};
16423
16424function scheduleCallback$1(priorityLevel, callback) {
16425 if (ReactSharedInternals.actQueue !== null) {
16426 // Special case: We're inside an `act` scope (a testing utility).
16427 // Instead of scheduling work in the host environment, add it to a
16428 // fake internal queue that's managed by the `act` implementation.
16429 ReactSharedInternals.actQueue.push(callback);
16430 return fakeActCallbackNode$1;
16431 } else {
16432 return scheduleCallback$3(priorityLevel, callback);
16433 }
16434}
16435
16436function cancelCallback(callbackNode) {
16437 if (callbackNode === fakeActCallbackNode$1) ; else if (callbackNode !== null) {
16438 cancelCallback$1(callbackNode);
16439 }
16440}
16441
16442function scheduleImmediateTask(cb) {
16443 if (ReactSharedInternals.actQueue !== null) {
16444 // Special case: Inside an `act` scope, we push microtasks to the fake `act`
16445 // callback queue. This is because we currently support calling `act`
16446 // without awaiting the result. The plan is to deprecate that, and require
16447 // that you always await the result so that the microtasks have a chance to
16448 // run. But it hasn't happened yet.
16449 ReactSharedInternals.actQueue.push(function () {
16450 cb();
16451 return null;
16452 });
16453 } // TODO: Can we land supportsMicrotasks? Which environments don't support it?
16454 // Alternatively, can we move this check to the host config?
16455
16456
16457 {
16458 scheduleMicrotask(function () {
16459 // In Safari, appending an iframe forces microtasks to run.
16460 // https://github.com/facebook/react/issues/22459
16461 // We don't support running callbacks in the middle of render
16462 // or commit so we need to check against that.
16463 var executionContext = getExecutionContext();
16464
16465 if ((executionContext & (RenderContext | CommitContext)) !== NoContext) {
16466 // Note that this would still prematurely flush the callbacks
16467 // if this happens outside render or commit phase (e.g. in an event).
16468 // Intentionally using a macrotask instead of a microtask here. This is
16469 // wrong semantically but it prevents an infinite loop. The bug is
16470 // Safari's, not ours, so we just do our best to not crash even though
16471 // the behavior isn't completely correct.
16472 scheduleCallback$3(ImmediatePriority, cb);
16473 return;
16474 }
16475
16476 cb();
16477 });
16478 }
16479}
16480
16481function requestTransitionLane( // This argument isn't used, it's only here to encourage the caller to
16482// check that it's inside a transition before calling this function.
16483// TODO: Make this non-nullable. Requires a tweak to useOptimistic.
16484transition) {
16485 // The algorithm for assigning an update to a lane should be stable for all
16486 // updates at the same priority within the same event. To do this, the
16487 // inputs to the algorithm must be the same.
16488 //
16489 // The trick we use is to cache the first of each of these inputs within an
16490 // event. Then reset the cached values once we can be sure the event is
16491 // over. Our heuristic for that is whenever we enter a concurrent work loop.
16492 if (currentEventTransitionLane === NoLane) {
16493 // All transitions within the same event are assigned the same lane.
16494 currentEventTransitionLane = claimNextTransitionLane();
16495 }
16496
16497 return currentEventTransitionLane;
16498}
16499
16500// transition updates that occur while the async action is still in progress
16501// are treated as part of the action.
16502//
16503// The ideal behavior would be to treat each async function as an independent
16504// action. However, without a mechanism like AsyncContext, we can't tell which
16505// action an update corresponds to. So instead, we entangle them all into one.
16506// The listeners to notify once the entangled scope completes.
16507
16508var currentEntangledListeners = null; // The number of pending async actions in the entangled scope.
16509
16510var currentEntangledPendingCount = 0; // The transition lane shared by all updates in the entangled scope.
16511
16512var currentEntangledLane = NoLane; // A thenable that resolves when the entangled scope completes. It does not
16513// resolve to a particular value because it's only used for suspending the UI
16514// until the async action scope has completed.
16515
16516var currentEntangledActionThenable = null;
16517function entangleAsyncAction(transition, thenable) {
16518 // `thenable` is the return value of the async action scope function. Create
16519 // a combined thenable that resolves once every entangled scope function
16520 // has finished.
16521 if (currentEntangledListeners === null) {
16522 // There's no outer async action scope. Create a new one.
16523 var entangledListeners = currentEntangledListeners = [];
16524 currentEntangledPendingCount = 0;
16525 currentEntangledLane = requestTransitionLane();
16526 var entangledThenable = {
16527 status: 'pending',
16528 value: undefined,
16529 then: function (resolve) {
16530 entangledListeners.push(resolve);
16531 }
16532 };
16533 currentEntangledActionThenable = entangledThenable;
16534 }
16535
16536 currentEntangledPendingCount++;
16537 thenable.then(pingEngtangledActionScope, pingEngtangledActionScope);
16538 return thenable;
16539}
16540
16541function pingEngtangledActionScope() {
16542 if (currentEntangledListeners !== null && --currentEntangledPendingCount === 0) {
16543 // All the actions have finished. Close the entangled async action scope
16544 // and notify all the listeners.
16545 if (currentEntangledActionThenable !== null) {
16546 var fulfilledThenable = currentEntangledActionThenable;
16547 fulfilledThenable.status = 'fulfilled';
16548 }
16549
16550 var listeners = currentEntangledListeners;
16551 currentEntangledListeners = null;
16552 currentEntangledLane = NoLane;
16553 currentEntangledActionThenable = null;
16554
16555 for (var i = 0; i < listeners.length; i++) {
16556 var listener = listeners[i];
16557 listener();
16558 }
16559 }
16560}
16561
16562function chainThenableValue(thenable, result) {
16563 // Equivalent to: Promise.resolve(thenable).then(() => result), except we can
16564 // cheat a bit since we know that that this thenable is only ever consumed
16565 // by React.
16566 //
16567 // We don't technically require promise support on the client yet, hence this
16568 // extra code.
16569 var listeners = [];
16570 var thenableWithOverride = {
16571 status: 'pending',
16572 value: null,
16573 reason: null,
16574 then: function (resolve) {
16575 listeners.push(resolve);
16576 }
16577 };
16578 thenable.then(function (value) {
16579 var fulfilledThenable = thenableWithOverride;
16580 fulfilledThenable.status = 'fulfilled';
16581 fulfilledThenable.value = result;
16582
16583 for (var i = 0; i < listeners.length; i++) {
16584 var listener = listeners[i];
16585 listener(result);
16586 }
16587 }, function (error) {
16588 var rejectedThenable = thenableWithOverride;
16589 rejectedThenable.status = 'rejected';
16590 rejectedThenable.reason = error;
16591
16592 for (var i = 0; i < listeners.length; i++) {
16593 var listener = listeners[i]; // This is a perf hack where we call the `onFulfill` ping function
16594 // instead of `onReject`, because we know that React is the only
16595 // consumer of these promises, and it passes the same listener to both.
16596 // We also know that it will read the error directly off the
16597 // `.reason` field.
16598
16599 listener(undefined);
16600 }
16601 });
16602 return thenableWithOverride;
16603}
16604function peekEntangledActionLane() {
16605 return currentEntangledLane;
16606}
16607function peekEntangledActionThenable() {
16608 return currentEntangledActionThenable;
16609}
16610
16611function requestCurrentTransition() {
16612 var transition = ReactSharedInternals.T;
16613
16614 if (transition !== null) {
16615 // Whenever a transition update is scheduled, register a callback on the
16616 // transition object so we can get the return value of the scope function.
16617 transition._callbacks.add(handleAsyncAction);
16618 }
16619
16620 return transition;
16621}
16622
16623function handleAsyncAction(transition, thenable) {
16624 {
16625 // This is an async action.
16626 entangleAsyncAction(transition, thenable);
16627 }
16628}
16629
16630function notifyTransitionCallbacks(transition, returnValue) {
16631 var callbacks = transition._callbacks;
16632 callbacks.forEach(function (callback) {
16633 return callback(transition, returnValue);
16634 });
16635} // When retrying a Suspense/Offscreen boundary, we restore the cache that was
16636// used during the previous render by placing it here, on the stack.
16637
16638var resumedCache = createCursor(null); // During the render/synchronous commit phase, we don't actually process the
16639
16640function peekCacheFromPool() {
16641 // If we're rendering inside a Suspense boundary that is currently hidden,
16642 // we should use the same cache that we used during the previous render, if
16643 // one exists.
16644
16645
16646 var cacheResumedFromPreviousRender = resumedCache.current;
16647
16648 if (cacheResumedFromPreviousRender !== null) {
16649 return cacheResumedFromPreviousRender;
16650 } // Otherwise, check the root's cache pool.
16651
16652
16653 var root = getWorkInProgressRoot();
16654 var cacheFromRootCachePool = root.pooledCache;
16655 return cacheFromRootCachePool;
16656}
16657
16658function requestCacheFromPool(renderLanes) {
16659 // Similar to previous function, except if there's not already a cache in the
16660 // pool, we allocate a new one.
16661 var cacheFromPool = peekCacheFromPool();
16662
16663 if (cacheFromPool !== null) {
16664 return cacheFromPool;
16665 } // Create a fresh cache and add it to the root cache pool. A cache can have
16666 // multiple owners:
16667 // - A cache pool that lives on the FiberRoot. This is where all fresh caches
16668 // are originally created (TODO: except during refreshes, until we implement
16669 // this correctly). The root takes ownership immediately when the cache is
16670 // created. Conceptually, root.pooledCache is an Option<Arc<Cache>> (owned),
16671 // and the return value of this function is a &Arc<Cache> (borrowed).
16672 // - One of several fiber types: host root, cache boundary, suspense
16673 // component. These retain and release in the commit phase.
16674
16675
16676 var root = getWorkInProgressRoot();
16677 var freshCache = createCache();
16678 root.pooledCache = freshCache;
16679 retainCache(freshCache);
16680
16681 if (freshCache !== null) {
16682 root.pooledCacheLanes |= renderLanes;
16683 }
16684
16685 return freshCache;
16686}
16687function pushTransition(offscreenWorkInProgress, prevCachePool, newTransitions) {
16688 {
16689 if (prevCachePool === null) {
16690 push(resumedCache, resumedCache.current, offscreenWorkInProgress);
16691 } else {
16692 push(resumedCache, prevCachePool.pool, offscreenWorkInProgress);
16693 }
16694 }
16695}
16696function popTransition(workInProgress, current) {
16697 if (current !== null) {
16698
16699 {
16700 pop(resumedCache, workInProgress);
16701 }
16702 }
16703}
16704function getSuspendedCache() {
16705 // cache that would have been used to render fresh data during this render,
16706 // if there was any, so that we can resume rendering with the same cache when
16707 // we receive more data.
16708
16709
16710 var cacheFromPool = peekCacheFromPool();
16711
16712 if (cacheFromPool === null) {
16713 return null;
16714 }
16715
16716 return {
16717 // We must also save the parent, so that when we resume we can detect
16718 // a refresh.
16719 parent: CacheContext._currentValue ,
16720 pool: cacheFromPool
16721 };
16722}
16723function getOffscreenDeferredCache() {
16724
16725 var cacheFromPool = peekCacheFromPool();
16726
16727 if (cacheFromPool === null) {
16728 return null;
16729 }
16730
16731 return {
16732 // We must also store the parent, so that when we resume we can detect
16733 // a refresh.
16734 parent: CacheContext._currentValue ,
16735 pool: cacheFromPool
16736 };
16737}
16738
16739var didWarnAboutMismatchedHooksForComponent;
16740var didWarnUncachedGetSnapshot;
16741var didWarnAboutUseWrappedInTryCatch;
16742var didWarnAboutAsyncClientComponent;
16743var didWarnAboutUseFormState;
16744
16745{
16746 didWarnAboutMismatchedHooksForComponent = new Set();
16747 didWarnAboutUseWrappedInTryCatch = new Set();
16748 didWarnAboutAsyncClientComponent = new Set();
16749 didWarnAboutUseFormState = new Set();
16750} // The effect "instance" is a shared object that remains the same for the entire
16751// lifetime of an effect. In Rust terms, a RefCell. We use it to store the
16752// "destroy" function that is returned from an effect, because that is stateful.
16753// The field is `undefined` if the effect is unmounted, or if the effect ran
16754// but is not stateful. We don't explicitly track whether the effect is mounted
16755// or unmounted because that can be inferred by the hiddenness of the fiber in
16756// the tree, i.e. whether there is a hidden Offscreen fiber above it.
16757//
16758// It's unfortunate that this is stored on a separate object, because it adds
16759// more memory per effect instance, but it's conceptually sound. I think there's
16760// likely a better data structure we could use for effects; perhaps just one
16761// array of effect instances per fiber. But I think this is OK for now despite
16762// the additional memory and we can follow up with performance
16763// optimizations later.
16764// These are set right before calling the component.
16765
16766
16767var renderLanes = NoLanes; // The work-in-progress fiber. I've named it differently to distinguish it from
16768// the work-in-progress hook.
16769
16770var currentlyRenderingFiber$1 = null; // Hooks are stored as a linked list on the fiber's memoizedState field. The
16771// current hook list is the list that belongs to the current fiber. The
16772// work-in-progress hook list is a new list that will be added to the
16773// work-in-progress fiber.
16774
16775var currentHook = null;
16776var workInProgressHook = null; // Whether an update was scheduled at any point during the render phase. This
16777// does not get reset if we do another render pass; only when we're completely
16778// finished evaluating this component. This is an optimization so we know
16779// whether we need to clear render phase updates after a throw.
16780
16781var didScheduleRenderPhaseUpdate = false; // Where an update was scheduled only during the current render pass. This
16782// gets reset after each attempt.
16783// TODO: Maybe there's some way to consolidate this with
16784// `didScheduleRenderPhaseUpdate`. Or with `numberOfReRenders`.
16785
16786var didScheduleRenderPhaseUpdateDuringThisPass = false;
16787var shouldDoubleInvokeUserFnsInHooksDEV = false; // Counts the number of useId hooks in this component.
16788
16789var localIdCounter = 0; // Counts number of `use`-d thenables
16790
16791var thenableIndexCounter = 0;
16792var thenableState = null; // Used for ids that are generated completely client-side (i.e. not during
16793// hydration). This counter is global, so client ids are not stable across
16794// render attempts.
16795
16796var globalClientIdCounter = 0;
16797var RE_RENDER_LIMIT = 25; // In DEV, this is the name of the currently executing primitive hook
16798
16799var currentHookNameInDev = null; // In DEV, this list ensures that hooks are called in the same order between renders.
16800// The list stores the order of hooks used during the initial render (mount).
16801// Subsequent renders (updates) reference this list.
16802
16803var hookTypesDev = null;
16804var hookTypesUpdateIndexDev = -1; // In DEV, this tracks whether currently rendering component needs to ignore
16805// the dependencies for Hooks that need them (e.g. useEffect or useMemo).
16806// When true, such Hooks will always be "remounted". Only used during hot reload.
16807
16808var ignorePreviousDependencies = false;
16809
16810function mountHookTypesDev() {
16811 {
16812 var hookName = currentHookNameInDev;
16813
16814 if (hookTypesDev === null) {
16815 hookTypesDev = [hookName];
16816 } else {
16817 hookTypesDev.push(hookName);
16818 }
16819 }
16820}
16821
16822function updateHookTypesDev() {
16823 {
16824 var hookName = currentHookNameInDev;
16825
16826 if (hookTypesDev !== null) {
16827 hookTypesUpdateIndexDev++;
16828
16829 if (hookTypesDev[hookTypesUpdateIndexDev] !== hookName) {
16830 warnOnHookMismatchInDev(hookName);
16831 }
16832 }
16833 }
16834}
16835
16836function checkDepsAreArrayDev(deps) {
16837 {
16838 if (deps !== undefined && deps !== null && !isArray(deps)) {
16839 // Verify deps, but only on mount to avoid extra checks.
16840 // It's unlikely their type would change as usually you define them inline.
16841 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);
16842 }
16843 }
16844}
16845
16846function warnOnHookMismatchInDev(currentHookName) {
16847 {
16848 var componentName = getComponentNameFromFiber(currentlyRenderingFiber$1);
16849
16850 if (!didWarnAboutMismatchedHooksForComponent.has(componentName)) {
16851 didWarnAboutMismatchedHooksForComponent.add(componentName);
16852
16853 if (hookTypesDev !== null) {
16854 var table = '';
16855 var secondColumnStart = 30;
16856
16857 for (var i = 0; i <= hookTypesUpdateIndexDev; i++) {
16858 var oldHookName = hookTypesDev[i];
16859 var newHookName = i === hookTypesUpdateIndexDev ? currentHookName : oldHookName;
16860 var row = i + 1 + ". " + oldHookName; // Extra space so second column lines up
16861 // lol @ IE not supporting String#repeat
16862
16863 while (row.length < secondColumnStart) {
16864 row += ' ';
16865 }
16866
16867 row += newHookName + '\n';
16868 table += row;
16869 }
16870
16871 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://react.dev/link/rules-of-hooks\n\n' + ' Previous render Next render\n' + ' ------------------------------------------------------\n' + '%s' + ' ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n', componentName, table);
16872 }
16873 }
16874 }
16875}
16876
16877function warnOnUseFormStateInDev() {
16878 {
16879 var componentName = getComponentNameFromFiber(currentlyRenderingFiber$1);
16880
16881 if (!didWarnAboutUseFormState.has(componentName)) {
16882 didWarnAboutUseFormState.add(componentName);
16883
16884 error('ReactDOM.useFormState has been renamed to React.useActionState. ' + 'Please update %s to use React.useActionState.', componentName);
16885 }
16886 }
16887}
16888
16889function warnIfAsyncClientComponent(Component) {
16890 {
16891 // This dev-only check only works for detecting native async functions,
16892 // not transpiled ones. There's also a prod check that we use to prevent
16893 // async client components from crashing the app; the prod one works even
16894 // for transpiled async functions. Neither mechanism is completely
16895 // bulletproof but together they cover the most common cases.
16896 var isAsyncFunction = // $FlowIgnore[method-unbinding]
16897 Object.prototype.toString.call(Component) === '[object AsyncFunction]' || // $FlowIgnore[method-unbinding]
16898 Object.prototype.toString.call(Component) === '[object AsyncGeneratorFunction]';
16899
16900 if (isAsyncFunction) {
16901 // Encountered an async Client Component. This is not yet supported.
16902 var componentName = getComponentNameFromFiber(currentlyRenderingFiber$1);
16903
16904 if (!didWarnAboutAsyncClientComponent.has(componentName)) {
16905 didWarnAboutAsyncClientComponent.add(componentName);
16906
16907 error('async/await is not yet supported in Client Components, only ' + 'Server Components. This error is often caused by accidentally ' + "adding `'use client'` to a module that was originally written " + 'for the server.');
16908 }
16909 }
16910 }
16911}
16912
16913function throwInvalidHookError() {
16914 throw new 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:\n' + '1. You might have mismatching versions of React and the renderer (such as React DOM)\n' + '2. You might be breaking the Rules of Hooks\n' + '3. You might have more than one copy of React in the same app\n' + 'See https://react.dev/link/invalid-hook-call for tips about how to debug and fix this problem.');
16915}
16916
16917function areHookInputsEqual(nextDeps, prevDeps) {
16918 {
16919 if (ignorePreviousDependencies) {
16920 // Only true when this component is being hot reloaded.
16921 return false;
16922 }
16923 }
16924
16925 if (prevDeps === null) {
16926 {
16927 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);
16928 }
16929
16930 return false;
16931 }
16932
16933 {
16934 // Don't bother comparing lengths in prod because these arrays should be
16935 // passed inline.
16936 if (nextDeps.length !== prevDeps.length) {
16937 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(', ') + "]");
16938 }
16939 } // $FlowFixMe[incompatible-use] found when upgrading Flow
16940
16941
16942 for (var i = 0; i < prevDeps.length && i < nextDeps.length; i++) {
16943 // $FlowFixMe[incompatible-use] found when upgrading Flow
16944 if (objectIs(nextDeps[i], prevDeps[i])) {
16945 continue;
16946 }
16947
16948 return false;
16949 }
16950
16951 return true;
16952}
16953
16954function renderWithHooks(current, workInProgress, Component, props, secondArg, nextRenderLanes) {
16955 renderLanes = nextRenderLanes;
16956 currentlyRenderingFiber$1 = workInProgress;
16957
16958 {
16959 hookTypesDev = current !== null ? current._debugHookTypes : null;
16960 hookTypesUpdateIndexDev = -1; // Used for hot reloading:
16961
16962 ignorePreviousDependencies = current !== null && current.type !== workInProgress.type;
16963 warnIfAsyncClientComponent(Component);
16964 }
16965
16966 workInProgress.memoizedState = null;
16967 workInProgress.updateQueue = null;
16968 workInProgress.lanes = NoLanes; // The following should have already been reset
16969 // currentHook = null;
16970 // workInProgressHook = null;
16971 // didScheduleRenderPhaseUpdate = false;
16972 // localIdCounter = 0;
16973 // thenableIndexCounter = 0;
16974 // thenableState = null;
16975 // TODO Warn if no hooks are used at all during mount, then some are used during update.
16976 // Currently we will identify the update render as a mount because memoizedState === null.
16977 // This is tricky because it's valid for certain types of components (e.g. React.lazy)
16978 // Using memoizedState to differentiate between mount/update only works if at least one stateful hook is used.
16979 // Non-stateful hooks (e.g. context) don't get added to memoizedState,
16980 // so memoizedState would be null during updates and mounts.
16981
16982 {
16983 if (current !== null && current.memoizedState !== null) {
16984 ReactSharedInternals.H = HooksDispatcherOnUpdateInDEV;
16985 } else if (hookTypesDev !== null) {
16986 // This dispatcher handles an edge case where a component is updating,
16987 // but no stateful hooks have been used.
16988 // We want to match the production code behavior (which will use HooksDispatcherOnMount),
16989 // but with the extra DEV validation to ensure hooks ordering hasn't changed.
16990 // This dispatcher does that.
16991 ReactSharedInternals.H = HooksDispatcherOnMountWithHookTypesInDEV;
16992 } else {
16993 ReactSharedInternals.H = HooksDispatcherOnMountInDEV;
16994 }
16995 } // In Strict Mode, during development, user functions are double invoked to
16996 // help detect side effects. The logic for how this is implemented for in
16997 // hook components is a bit complex so let's break it down.
16998 //
16999 // We will invoke the entire component function twice. However, during the
17000 // second invocation of the component, the hook state from the first
17001 // invocation will be reused. That means things like `useMemo` functions won't
17002 // run again, because the deps will match and the memoized result will
17003 // be reused.
17004 //
17005 // We want memoized functions to run twice, too, so account for this, user
17006 // functions are double invoked during the *first* invocation of the component
17007 // function, and are *not* double invoked during the second incovation:
17008 //
17009 // - First execution of component function: user functions are double invoked
17010 // - Second execution of component function (in Strict Mode, during
17011 // development): user functions are not double invoked.
17012 //
17013 // This is intentional for a few reasons; most importantly, it's because of
17014 // how `use` works when something suspends: it reuses the promise that was
17015 // passed during the first attempt. This is itself a form of memoization.
17016 // We need to be able to memoize the reactive inputs to the `use` call using
17017 // a hook (i.e. `useMemo`), which means, the reactive inputs to `use` must
17018 // come from the same component invocation as the output.
17019 //
17020 // There are plenty of tests to ensure this behavior is correct.
17021
17022
17023 var shouldDoubleRenderDEV = (workInProgress.mode & StrictLegacyMode) !== NoMode;
17024 shouldDoubleInvokeUserFnsInHooksDEV = shouldDoubleRenderDEV;
17025 var children = Component(props, secondArg);
17026 shouldDoubleInvokeUserFnsInHooksDEV = false; // Check if there was a render phase update
17027
17028 if (didScheduleRenderPhaseUpdateDuringThisPass) {
17029 // Keep rendering until the component stabilizes (there are no more render
17030 // phase updates).
17031 children = renderWithHooksAgain(workInProgress, Component, props, secondArg);
17032 }
17033
17034 if (shouldDoubleRenderDEV) {
17035 // In development, components are invoked twice to help detect side effects.
17036 setIsStrictModeForDevtools(true);
17037
17038 try {
17039 children = renderWithHooksAgain(workInProgress, Component, props, secondArg);
17040 } finally {
17041 setIsStrictModeForDevtools(false);
17042 }
17043 }
17044
17045 finishRenderingHooks(current, workInProgress);
17046 return children;
17047}
17048
17049function finishRenderingHooks(current, workInProgress, Component) {
17050 {
17051 workInProgress._debugHookTypes = hookTypesDev;
17052 } // We can assume the previous dispatcher is always this one, since we set it
17053 // at the beginning of the render phase and there's no re-entrance.
17054
17055
17056 ReactSharedInternals.H = ContextOnlyDispatcher; // This check uses currentHook so that it works the same in DEV and prod bundles.
17057 // hookTypesDev could catch more cases (e.g. context) but only in DEV bundles.
17058
17059 var didRenderTooFewHooks = currentHook !== null && currentHook.next !== null;
17060 renderLanes = NoLanes;
17061 currentlyRenderingFiber$1 = null;
17062 currentHook = null;
17063 workInProgressHook = null;
17064
17065 {
17066 currentHookNameInDev = null;
17067 hookTypesDev = null;
17068 hookTypesUpdateIndexDev = -1; // Confirm that a static flag was not added or removed since the last
17069 // render. If this fires, it suggests that we incorrectly reset the static
17070 // flags in some other part of the codebase. This has happened before, for
17071 // example, in the SuspenseList implementation.
17072
17073 if (current !== null && (current.flags & StaticMask) !== (workInProgress.flags & StaticMask) && ( // Disable this warning in legacy mode, because legacy Suspense is weird
17074 // and creates false positives. To make this work in legacy mode, we'd
17075 // need to mark fibers that commit in an incomplete state, somehow. For
17076 // now I'll disable the warning that most of the bugs that would trigger
17077 // it are either exclusive to concurrent mode or exist in both.
17078 disableLegacyMode )) {
17079 error('Internal React error: Expected static flag was missing. Please ' + 'notify the React team.');
17080 }
17081 }
17082
17083 didScheduleRenderPhaseUpdate = false; // This is reset by checkDidRenderIdHook
17084 // localIdCounter = 0;
17085
17086 thenableIndexCounter = 0;
17087 thenableState = null;
17088
17089 if (didRenderTooFewHooks) {
17090 throw new Error('Rendered fewer hooks than expected. This may be caused by an accidental ' + 'early return statement.');
17091 }
17092
17093 {
17094 if (checkIfUseWrappedInTryCatch()) {
17095 var componentName = getComponentNameFromFiber(workInProgress) || 'Unknown';
17096
17097 if (!didWarnAboutUseWrappedInTryCatch.has(componentName) && // This warning also fires if you suspend with `use` inside an
17098 // async component. Since we warn for that above, we'll silence this
17099 // second warning by checking here.
17100 !didWarnAboutAsyncClientComponent.has(componentName)) {
17101 didWarnAboutUseWrappedInTryCatch.add(componentName);
17102
17103 error('`use` was called from inside a try/catch block. This is not allowed ' + 'and can lead to unexpected behavior. To handle errors triggered ' + 'by `use`, wrap your component in a error boundary.');
17104 }
17105 }
17106 }
17107}
17108
17109function replaySuspendedComponentWithHooks(current, workInProgress, Component, props, secondArg) {
17110 // This function is used to replay a component that previously suspended,
17111 // after its data resolves.
17112 //
17113 // It's a simplified version of renderWithHooks, but it doesn't need to do
17114 // most of the set up work because they weren't reset when we suspended; they
17115 // only get reset when the component either completes (finishRenderingHooks)
17116 // or unwinds (resetHooksOnUnwind).
17117 {
17118 hookTypesUpdateIndexDev = -1; // Used for hot reloading:
17119
17120 ignorePreviousDependencies = current !== null && current.type !== workInProgress.type;
17121 }
17122
17123 var children = renderWithHooksAgain(workInProgress, Component, props, secondArg);
17124 finishRenderingHooks(current, workInProgress);
17125 return children;
17126}
17127
17128function renderWithHooksAgain(workInProgress, Component, props, secondArg) {
17129 // This is used to perform another render pass. It's used when setState is
17130 // called during render, and for double invoking components in Strict Mode
17131 // during development.
17132 //
17133 // The state from the previous pass is reused whenever possible. So, state
17134 // updates that were already processed are not processed again, and memoized
17135 // functions (`useMemo`) are not invoked again.
17136 //
17137 // Keep rendering in a loop for as long as render phase updates continue to
17138 // be scheduled. Use a counter to prevent infinite loops.
17139 currentlyRenderingFiber$1 = workInProgress;
17140 var numberOfReRenders = 0;
17141 var children;
17142
17143 do {
17144 if (didScheduleRenderPhaseUpdateDuringThisPass) {
17145 // It's possible that a use() value depended on a state that was updated in
17146 // this rerender, so we need to watch for different thenables this time.
17147 thenableState = null;
17148 }
17149
17150 thenableIndexCounter = 0;
17151 didScheduleRenderPhaseUpdateDuringThisPass = false;
17152
17153 if (numberOfReRenders >= RE_RENDER_LIMIT) {
17154 throw new Error('Too many re-renders. React limits the number of renders to prevent ' + 'an infinite loop.');
17155 }
17156
17157 numberOfReRenders += 1;
17158
17159 {
17160 // Even when hot reloading, allow dependencies to stabilize
17161 // after first render to prevent infinite render phase updates.
17162 ignorePreviousDependencies = false;
17163 } // Start over from the beginning of the list
17164
17165
17166 currentHook = null;
17167 workInProgressHook = null;
17168 workInProgress.updateQueue = null;
17169
17170 {
17171 // Also validate hook order for cascading updates.
17172 hookTypesUpdateIndexDev = -1;
17173 }
17174
17175 ReactSharedInternals.H = HooksDispatcherOnRerenderInDEV ;
17176 children = Component(props, secondArg);
17177 } while (didScheduleRenderPhaseUpdateDuringThisPass);
17178
17179 return children;
17180}
17181
17182function renderTransitionAwareHostComponentWithHooks(current, workInProgress, lanes) {
17183
17184 return renderWithHooks(current, workInProgress, TransitionAwareHostComponent, null, null, lanes);
17185}
17186function TransitionAwareHostComponent() {
17187
17188 var dispatcher = ReactSharedInternals.H;
17189
17190 var _dispatcher$useState = dispatcher.useState(),
17191 maybeThenable = _dispatcher$useState[0];
17192
17193 var nextState;
17194
17195 if (typeof maybeThenable.then === 'function') {
17196 var thenable = maybeThenable;
17197 nextState = useThenable(thenable);
17198 } else {
17199 var status = maybeThenable;
17200 nextState = status;
17201 } // The "reset state" is an object. If it changes, that means something
17202 // requested that we reset the form.
17203
17204
17205 var _dispatcher$useState2 = dispatcher.useState(),
17206 nextResetState = _dispatcher$useState2[0];
17207
17208 var prevResetState = currentHook !== null ? currentHook.memoizedState : null;
17209
17210 if (prevResetState !== nextResetState) {
17211 // Schedule a form reset
17212 currentlyRenderingFiber$1.flags |= FormReset;
17213 }
17214
17215 return nextState;
17216}
17217function checkDidRenderIdHook() {
17218 // This should be called immediately after every renderWithHooks call.
17219 // Conceptually, it's part of the return value of renderWithHooks; it's only a
17220 // separate function to avoid using an array tuple.
17221 var didRenderIdHook = localIdCounter !== 0;
17222 localIdCounter = 0;
17223 return didRenderIdHook;
17224}
17225function bailoutHooks(current, workInProgress, lanes) {
17226 workInProgress.updateQueue = current.updateQueue; // TODO: Don't need to reset the flags here, because they're reset in the
17227 // complete phase (bubbleProperties).
17228
17229 if ((workInProgress.mode & StrictEffectsMode) !== NoMode) {
17230 workInProgress.flags &= ~(MountPassiveDev | MountLayoutDev | Passive$1 | Update);
17231 } else {
17232 workInProgress.flags &= ~(Passive$1 | Update);
17233 }
17234
17235 current.lanes = removeLanes(current.lanes, lanes);
17236}
17237function resetHooksAfterThrow() {
17238 // This is called immediaetly after a throw. It shouldn't reset the entire
17239 // module state, because the work loop might decide to replay the component
17240 // again without rewinding.
17241 //
17242 // It should only reset things like the current dispatcher, to prevent hooks
17243 // from being called outside of a component.
17244 currentlyRenderingFiber$1 = null; // We can assume the previous dispatcher is always this one, since we set it
17245 // at the beginning of the render phase and there's no re-entrance.
17246
17247 ReactSharedInternals.H = ContextOnlyDispatcher;
17248}
17249function resetHooksOnUnwind(workInProgress) {
17250 if (didScheduleRenderPhaseUpdate) {
17251 // There were render phase updates. These are only valid for this render
17252 // phase, which we are now aborting. Remove the updates from the queues so
17253 // they do not persist to the next render. Do not remove updates from hooks
17254 // that weren't processed.
17255 //
17256 // Only reset the updates from the queue if it has a clone. If it does
17257 // not have a clone, that means it wasn't processed, and the updates were
17258 // scheduled before we entered the render phase.
17259 var hook = workInProgress.memoizedState;
17260
17261 while (hook !== null) {
17262 var queue = hook.queue;
17263
17264 if (queue !== null) {
17265 queue.pending = null;
17266 }
17267
17268 hook = hook.next;
17269 }
17270
17271 didScheduleRenderPhaseUpdate = false;
17272 }
17273
17274 renderLanes = NoLanes;
17275 currentlyRenderingFiber$1 = null;
17276 currentHook = null;
17277 workInProgressHook = null;
17278
17279 {
17280 hookTypesDev = null;
17281 hookTypesUpdateIndexDev = -1;
17282 currentHookNameInDev = null;
17283 }
17284
17285 didScheduleRenderPhaseUpdateDuringThisPass = false;
17286 localIdCounter = 0;
17287 thenableIndexCounter = 0;
17288 thenableState = null;
17289}
17290
17291function mountWorkInProgressHook() {
17292 var hook = {
17293 memoizedState: null,
17294 baseState: null,
17295 baseQueue: null,
17296 queue: null,
17297 next: null
17298 };
17299
17300 if (workInProgressHook === null) {
17301 // This is the first hook in the list
17302 currentlyRenderingFiber$1.memoizedState = workInProgressHook = hook;
17303 } else {
17304 // Append to the end of the list
17305 workInProgressHook = workInProgressHook.next = hook;
17306 }
17307
17308 return workInProgressHook;
17309}
17310
17311function updateWorkInProgressHook() {
17312 // This function is used both for updates and for re-renders triggered by a
17313 // render phase update. It assumes there is either a current hook we can
17314 // clone, or a work-in-progress hook from a previous render pass that we can
17315 // use as a base.
17316 var nextCurrentHook;
17317
17318 if (currentHook === null) {
17319 var current = currentlyRenderingFiber$1.alternate;
17320
17321 if (current !== null) {
17322 nextCurrentHook = current.memoizedState;
17323 } else {
17324 nextCurrentHook = null;
17325 }
17326 } else {
17327 nextCurrentHook = currentHook.next;
17328 }
17329
17330 var nextWorkInProgressHook;
17331
17332 if (workInProgressHook === null) {
17333 nextWorkInProgressHook = currentlyRenderingFiber$1.memoizedState;
17334 } else {
17335 nextWorkInProgressHook = workInProgressHook.next;
17336 }
17337
17338 if (nextWorkInProgressHook !== null) {
17339 // There's already a work-in-progress. Reuse it.
17340 workInProgressHook = nextWorkInProgressHook;
17341 nextWorkInProgressHook = workInProgressHook.next;
17342 currentHook = nextCurrentHook;
17343 } else {
17344 // Clone from the current hook.
17345 if (nextCurrentHook === null) {
17346 var currentFiber = currentlyRenderingFiber$1.alternate;
17347
17348 if (currentFiber === null) {
17349 // This is the initial render. This branch is reached when the component
17350 // suspends, resumes, then renders an additional hook.
17351 // Should never be reached because we should switch to the mount dispatcher first.
17352 throw new Error('Update hook called on initial render. This is likely a bug in React. Please file an issue.');
17353 } else {
17354 // This is an update. We should always have a current hook.
17355 throw new Error('Rendered more hooks than during the previous render.');
17356 }
17357 }
17358
17359 currentHook = nextCurrentHook;
17360 var newHook = {
17361 memoizedState: currentHook.memoizedState,
17362 baseState: currentHook.baseState,
17363 baseQueue: currentHook.baseQueue,
17364 queue: currentHook.queue,
17365 next: null
17366 };
17367
17368 if (workInProgressHook === null) {
17369 // This is the first hook in the list.
17370 currentlyRenderingFiber$1.memoizedState = workInProgressHook = newHook;
17371 } else {
17372 // Append to the end of the list.
17373 workInProgressHook = workInProgressHook.next = newHook;
17374 }
17375 }
17376
17377 return workInProgressHook;
17378} // NOTE: defining two versions of this function to avoid size impact when this feature is disabled.
17379// Previously this function was inlined, the additional `memoCache` property makes it not inlined.
17380
17381
17382var createFunctionComponentUpdateQueue;
17383
17384{
17385 createFunctionComponentUpdateQueue = function () {
17386 return {
17387 lastEffect: null,
17388 events: null,
17389 stores: null
17390 };
17391 };
17392}
17393
17394function useThenable(thenable) {
17395 // Track the position of the thenable within this fiber.
17396 var index = thenableIndexCounter;
17397 thenableIndexCounter += 1;
17398
17399 if (thenableState === null) {
17400 thenableState = createThenableState();
17401 }
17402
17403 var result = trackUsedThenable(thenableState, thenable, index);
17404
17405 if (currentlyRenderingFiber$1.alternate === null && (workInProgressHook === null ? currentlyRenderingFiber$1.memoizedState === null : workInProgressHook.next === null)) {
17406 // Initial render, and either this is the first time the component is
17407 // called, or there were no Hooks called after this use() the previous
17408 // time (perhaps because it threw). Subsequent Hook calls should use the
17409 // mount dispatcher.
17410 {
17411 ReactSharedInternals.H = HooksDispatcherOnMountInDEV;
17412 }
17413 }
17414
17415 return result;
17416}
17417
17418function use(usable) {
17419 if (usable !== null && typeof usable === 'object') {
17420 // $FlowFixMe[method-unbinding]
17421 if (typeof usable.then === 'function') {
17422 // This is a thenable.
17423 var thenable = usable;
17424 return useThenable(thenable);
17425 } else if (usable.$$typeof === REACT_CONTEXT_TYPE) {
17426 var context = usable;
17427 return readContext(context);
17428 }
17429 } // eslint-disable-next-line react-internal/safe-string-coercion
17430
17431
17432 throw new Error('An unsupported type was passed to use(): ' + String(usable));
17433}
17434
17435function basicStateReducer(state, action) {
17436 // $FlowFixMe[incompatible-use]: Flow doesn't like mixed types
17437 return typeof action === 'function' ? action(state) : action;
17438}
17439
17440function mountReducer(reducer, initialArg, init) {
17441 var hook = mountWorkInProgressHook();
17442 var initialState;
17443
17444 if (init !== undefined) {
17445 initialState = init(initialArg);
17446
17447 if (shouldDoubleInvokeUserFnsInHooksDEV) {
17448 setIsStrictModeForDevtools(true);
17449 init(initialArg);
17450 setIsStrictModeForDevtools(false);
17451 }
17452 } else {
17453 initialState = initialArg;
17454 }
17455
17456 hook.memoizedState = hook.baseState = initialState;
17457 var queue = {
17458 pending: null,
17459 lanes: NoLanes,
17460 dispatch: null,
17461 lastRenderedReducer: reducer,
17462 lastRenderedState: initialState
17463 };
17464 hook.queue = queue;
17465 var dispatch = queue.dispatch = dispatchReducerAction.bind(null, currentlyRenderingFiber$1, queue);
17466 return [hook.memoizedState, dispatch];
17467}
17468
17469function updateReducer(reducer, initialArg, init) {
17470 var hook = updateWorkInProgressHook();
17471 return updateReducerImpl(hook, currentHook, reducer);
17472}
17473
17474function updateReducerImpl(hook, current, reducer) {
17475 var queue = hook.queue;
17476
17477 if (queue === null) {
17478 throw new Error('Should have a queue. This is likely a bug in React. Please file an issue.');
17479 }
17480
17481 queue.lastRenderedReducer = reducer; // The last rebase update that is NOT part of the base state.
17482
17483 var baseQueue = hook.baseQueue; // The last pending update that hasn't been processed yet.
17484
17485 var pendingQueue = queue.pending;
17486
17487 if (pendingQueue !== null) {
17488 // We have new updates that haven't been processed yet.
17489 // We'll add them to the base queue.
17490 if (baseQueue !== null) {
17491 // Merge the pending queue and the base queue.
17492 var baseFirst = baseQueue.next;
17493 var pendingFirst = pendingQueue.next;
17494 baseQueue.next = pendingFirst;
17495 pendingQueue.next = baseFirst;
17496 }
17497
17498 {
17499 if (current.baseQueue !== baseQueue) {
17500 // Internal invariant that should never happen, but feasibly could in
17501 // the future if we implement resuming, or some form of that.
17502 error('Internal error: Expected work-in-progress queue to be a clone. ' + 'This is a bug in React.');
17503 }
17504 }
17505
17506 current.baseQueue = baseQueue = pendingQueue;
17507 queue.pending = null;
17508 }
17509
17510 var baseState = hook.baseState;
17511
17512 if (baseQueue === null) {
17513 // If there are no pending updates, then the memoized state should be the
17514 // same as the base state. Currently these only diverge in the case of
17515 // useOptimistic, because useOptimistic accepts a new baseState on
17516 // every render.
17517 hook.memoizedState = baseState; // We don't need to call markWorkInProgressReceivedUpdate because
17518 // baseState is derived from other reactive values.
17519 } else {
17520 // We have a queue to process.
17521 var first = baseQueue.next;
17522 var newState = baseState;
17523 var newBaseState = null;
17524 var newBaseQueueFirst = null;
17525 var newBaseQueueLast = null;
17526 var update = first;
17527 var didReadFromEntangledAsyncAction = false;
17528
17529 do {
17530 // An extra OffscreenLane bit is added to updates that were made to
17531 // a hidden tree, so that we can distinguish them from updates that were
17532 // already there when the tree was hidden.
17533 var updateLane = removeLanes(update.lane, OffscreenLane);
17534 var isHiddenUpdate = updateLane !== update.lane; // Check if this update was made while the tree was hidden. If so, then
17535 // it's not a "base" update and we should disregard the extra base lanes
17536 // that were added to renderLanes when we entered the Offscreen tree.
17537
17538 var shouldSkipUpdate = isHiddenUpdate ? !isSubsetOfLanes(getWorkInProgressRootRenderLanes(), updateLane) : !isSubsetOfLanes(renderLanes, updateLane);
17539
17540 if (shouldSkipUpdate) {
17541 // Priority is insufficient. Skip this update. If this is the first
17542 // skipped update, the previous update/state is the new base
17543 // update/state.
17544 var clone = {
17545 lane: updateLane,
17546 revertLane: update.revertLane,
17547 action: update.action,
17548 hasEagerState: update.hasEagerState,
17549 eagerState: update.eagerState,
17550 next: null
17551 };
17552
17553 if (newBaseQueueLast === null) {
17554 newBaseQueueFirst = newBaseQueueLast = clone;
17555 newBaseState = newState;
17556 } else {
17557 newBaseQueueLast = newBaseQueueLast.next = clone;
17558 } // Update the remaining priority in the queue.
17559 // TODO: Don't need to accumulate this. Instead, we can remove
17560 // renderLanes from the original lanes.
17561
17562
17563 currentlyRenderingFiber$1.lanes = mergeLanes(currentlyRenderingFiber$1.lanes, updateLane);
17564 markSkippedUpdateLanes(updateLane);
17565 } else {
17566 // This update does have sufficient priority.
17567 // Check if this is an optimistic update.
17568 var revertLane = update.revertLane;
17569
17570 if (revertLane === NoLane) {
17571 // This is not an optimistic update, and we're going to apply it now.
17572 // But, if there were earlier updates that were skipped, we need to
17573 // leave this update in the queue so it can be rebased later.
17574 if (newBaseQueueLast !== null) {
17575 var _clone = {
17576 // This update is going to be committed so we never want uncommit
17577 // it. Using NoLane works because 0 is a subset of all bitmasks, so
17578 // this will never be skipped by the check above.
17579 lane: NoLane,
17580 revertLane: NoLane,
17581 action: update.action,
17582 hasEagerState: update.hasEagerState,
17583 eagerState: update.eagerState,
17584 next: null
17585 };
17586 newBaseQueueLast = newBaseQueueLast.next = _clone;
17587 } // Check if this update is part of a pending async action. If so,
17588 // we'll need to suspend until the action has finished, so that it's
17589 // batched together with future updates in the same action.
17590
17591
17592 if (updateLane === peekEntangledActionLane()) {
17593 didReadFromEntangledAsyncAction = true;
17594 }
17595 } else {
17596 // This is an optimistic update. If the "revert" priority is
17597 // sufficient, don't apply the update. Otherwise, apply the update,
17598 // but leave it in the queue so it can be either reverted or
17599 // rebased in a subsequent render.
17600 if (isSubsetOfLanes(renderLanes, revertLane)) {
17601 // The transition that this optimistic update is associated with
17602 // has finished. Pretend the update doesn't exist by skipping
17603 // over it.
17604 update = update.next; // Check if this update is part of a pending async action. If so,
17605 // we'll need to suspend until the action has finished, so that it's
17606 // batched together with future updates in the same action.
17607
17608 if (revertLane === peekEntangledActionLane()) {
17609 didReadFromEntangledAsyncAction = true;
17610 }
17611
17612 continue;
17613 } else {
17614 var _clone2 = {
17615 // Once we commit an optimistic update, we shouldn't uncommit it
17616 // until the transition it is associated with has finished
17617 // (represented by revertLane). Using NoLane here works because 0
17618 // is a subset of all bitmasks, so this will never be skipped by
17619 // the check above.
17620 lane: NoLane,
17621 // Reuse the same revertLane so we know when the transition
17622 // has finished.
17623 revertLane: update.revertLane,
17624 action: update.action,
17625 hasEagerState: update.hasEagerState,
17626 eagerState: update.eagerState,
17627 next: null
17628 };
17629
17630 if (newBaseQueueLast === null) {
17631 newBaseQueueFirst = newBaseQueueLast = _clone2;
17632 newBaseState = newState;
17633 } else {
17634 newBaseQueueLast = newBaseQueueLast.next = _clone2;
17635 } // Update the remaining priority in the queue.
17636 // TODO: Don't need to accumulate this. Instead, we can remove
17637 // renderLanes from the original lanes.
17638
17639
17640 currentlyRenderingFiber$1.lanes = mergeLanes(currentlyRenderingFiber$1.lanes, revertLane);
17641 markSkippedUpdateLanes(revertLane);
17642 }
17643 } // Process this update.
17644
17645
17646 var action = update.action;
17647
17648 if (shouldDoubleInvokeUserFnsInHooksDEV) {
17649 reducer(newState, action);
17650 }
17651
17652 if (update.hasEagerState) {
17653 // If this update is a state update (not a reducer) and was processed eagerly,
17654 // we can use the eagerly computed state
17655 newState = update.eagerState;
17656 } else {
17657 newState = reducer(newState, action);
17658 }
17659 }
17660
17661 update = update.next;
17662 } while (update !== null && update !== first);
17663
17664 if (newBaseQueueLast === null) {
17665 newBaseState = newState;
17666 } else {
17667 newBaseQueueLast.next = newBaseQueueFirst;
17668 } // Mark that the fiber performed work, but only if the new state is
17669 // different from the current state.
17670
17671
17672 if (!objectIs(newState, hook.memoizedState)) {
17673 markWorkInProgressReceivedUpdate(); // Check if this update is part of a pending async action. If so, we'll
17674 // need to suspend until the action has finished, so that it's batched
17675 // together with future updates in the same action.
17676 // TODO: Once we support hooks inside useMemo (or an equivalent
17677 // memoization boundary like Forget), hoist this logic so that it only
17678 // suspends if the memo boundary produces a new value.
17679
17680 if (didReadFromEntangledAsyncAction) {
17681 var entangledActionThenable = peekEntangledActionThenable();
17682
17683 if (entangledActionThenable !== null) {
17684 // TODO: Instead of the throwing the thenable directly, throw a
17685 // special object like `use` does so we can detect if it's captured
17686 // by userspace.
17687 throw entangledActionThenable;
17688 }
17689 }
17690 }
17691
17692 hook.memoizedState = newState;
17693 hook.baseState = newBaseState;
17694 hook.baseQueue = newBaseQueueLast;
17695 queue.lastRenderedState = newState;
17696 }
17697
17698 if (baseQueue === null) {
17699 // `queue.lanes` is used for entangling transitions. We can set it back to
17700 // zero once the queue is empty.
17701 queue.lanes = NoLanes;
17702 }
17703
17704 var dispatch = queue.dispatch;
17705 return [hook.memoizedState, dispatch];
17706}
17707
17708function rerenderReducer(reducer, initialArg, init) {
17709 var hook = updateWorkInProgressHook();
17710 var queue = hook.queue;
17711
17712 if (queue === null) {
17713 throw new Error('Should have a queue. This is likely a bug in React. Please file an issue.');
17714 }
17715
17716 queue.lastRenderedReducer = reducer; // This is a re-render. Apply the new render phase updates to the previous
17717 // work-in-progress hook.
17718
17719 var dispatch = queue.dispatch;
17720 var lastRenderPhaseUpdate = queue.pending;
17721 var newState = hook.memoizedState;
17722
17723 if (lastRenderPhaseUpdate !== null) {
17724 // The queue doesn't persist past this render pass.
17725 queue.pending = null;
17726 var firstRenderPhaseUpdate = lastRenderPhaseUpdate.next;
17727 var update = firstRenderPhaseUpdate;
17728
17729 do {
17730 // Process this render phase update. We don't have to check the
17731 // priority because it will always be the same as the current
17732 // render's.
17733 var action = update.action;
17734 newState = reducer(newState, action);
17735 update = update.next;
17736 } while (update !== firstRenderPhaseUpdate); // Mark that the fiber performed work, but only if the new state is
17737 // different from the current state.
17738
17739
17740 if (!objectIs(newState, hook.memoizedState)) {
17741 markWorkInProgressReceivedUpdate();
17742 }
17743
17744 hook.memoizedState = newState; // Don't persist the state accumulated from the render phase updates to
17745 // the base state unless the queue is empty.
17746 // TODO: Not sure if this is the desired semantics, but it's what we
17747 // do for gDSFP. I can't remember why.
17748
17749 if (hook.baseQueue === null) {
17750 hook.baseState = newState;
17751 }
17752
17753 queue.lastRenderedState = newState;
17754 }
17755
17756 return [newState, dispatch];
17757}
17758
17759function mountSyncExternalStore(subscribe, getSnapshot, getServerSnapshot) {
17760 var fiber = currentlyRenderingFiber$1;
17761 var hook = mountWorkInProgressHook();
17762 var nextSnapshot;
17763 var isHydrating = getIsHydrating();
17764
17765 if (isHydrating) {
17766 if (getServerSnapshot === undefined) {
17767 throw new Error('Missing getServerSnapshot, which is required for ' + 'server-rendered content. Will revert to client rendering.');
17768 }
17769
17770 nextSnapshot = getServerSnapshot();
17771
17772 {
17773 if (!didWarnUncachedGetSnapshot) {
17774 if (nextSnapshot !== getServerSnapshot()) {
17775 error('The result of getServerSnapshot should be cached to avoid an infinite loop');
17776
17777 didWarnUncachedGetSnapshot = true;
17778 }
17779 }
17780 }
17781 } else {
17782 nextSnapshot = getSnapshot();
17783
17784 {
17785 if (!didWarnUncachedGetSnapshot) {
17786 var cachedSnapshot = getSnapshot();
17787
17788 if (!objectIs(nextSnapshot, cachedSnapshot)) {
17789 error('The result of getSnapshot should be cached to avoid an infinite loop');
17790
17791 didWarnUncachedGetSnapshot = true;
17792 }
17793 }
17794 } // Unless we're rendering a blocking lane, schedule a consistency check.
17795 // Right before committing, we will walk the tree and check if any of the
17796 // stores were mutated.
17797 //
17798 // We won't do this if we're hydrating server-rendered content, because if
17799 // the content is stale, it's already visible anyway. Instead we'll patch
17800 // it up in a passive effect.
17801
17802
17803 var root = getWorkInProgressRoot();
17804
17805 if (root === null) {
17806 throw new Error('Expected a work-in-progress root. This is a bug in React. Please file an issue.');
17807 }
17808
17809 var rootRenderLanes = getWorkInProgressRootRenderLanes();
17810
17811 if (!includesBlockingLane(root, rootRenderLanes)) {
17812 pushStoreConsistencyCheck(fiber, getSnapshot, nextSnapshot);
17813 }
17814 } // Read the current snapshot from the store on every render. This breaks the
17815 // normal rules of React, and only works because store updates are
17816 // always synchronous.
17817
17818
17819 hook.memoizedState = nextSnapshot;
17820 var inst = {
17821 value: nextSnapshot,
17822 getSnapshot: getSnapshot
17823 };
17824 hook.queue = inst; // Schedule an effect to subscribe to the store.
17825
17826 mountEffect(subscribeToStore.bind(null, fiber, inst, subscribe), [subscribe]); // Schedule an effect to update the mutable instance fields. We will update
17827 // this whenever subscribe, getSnapshot, or value changes. Because there's no
17828 // clean-up function, and we track the deps correctly, we can call pushEffect
17829 // directly, without storing any additional state. For the same reason, we
17830 // don't need to set a static flag, either.
17831
17832 fiber.flags |= Passive$1;
17833 pushEffect(HasEffect | Passive, updateStoreInstance.bind(null, fiber, inst, nextSnapshot, getSnapshot), createEffectInstance(), null);
17834 return nextSnapshot;
17835}
17836
17837function updateSyncExternalStore(subscribe, getSnapshot, getServerSnapshot) {
17838 var fiber = currentlyRenderingFiber$1;
17839 var hook = updateWorkInProgressHook(); // Read the current snapshot from the store on every render. This breaks the
17840 // normal rules of React, and only works because store updates are
17841 // always synchronous.
17842
17843 var nextSnapshot;
17844 var isHydrating = getIsHydrating();
17845
17846 if (isHydrating) {
17847 // Needed for strict mode double render
17848 if (getServerSnapshot === undefined) {
17849 throw new Error('Missing getServerSnapshot, which is required for ' + 'server-rendered content. Will revert to client rendering.');
17850 }
17851
17852 nextSnapshot = getServerSnapshot();
17853 } else {
17854 nextSnapshot = getSnapshot();
17855
17856 {
17857 if (!didWarnUncachedGetSnapshot) {
17858 var cachedSnapshot = getSnapshot();
17859
17860 if (!objectIs(nextSnapshot, cachedSnapshot)) {
17861 error('The result of getSnapshot should be cached to avoid an infinite loop');
17862
17863 didWarnUncachedGetSnapshot = true;
17864 }
17865 }
17866 }
17867 }
17868
17869 var prevSnapshot = (currentHook || hook).memoizedState;
17870 var snapshotChanged = !objectIs(prevSnapshot, nextSnapshot);
17871
17872 if (snapshotChanged) {
17873 hook.memoizedState = nextSnapshot;
17874 markWorkInProgressReceivedUpdate();
17875 }
17876
17877 var inst = hook.queue;
17878 updateEffect(subscribeToStore.bind(null, fiber, inst, subscribe), [subscribe]); // Whenever getSnapshot or subscribe changes, we need to check in the
17879 // commit phase if there was an interleaved mutation. In concurrent mode
17880 // this can happen all the time, but even in synchronous mode, an earlier
17881 // effect may have mutated the store.
17882
17883 if (inst.getSnapshot !== getSnapshot || snapshotChanged || // Check if the subscribe function changed. We can save some memory by
17884 // checking whether we scheduled a subscription effect above.
17885 workInProgressHook !== null && workInProgressHook.memoizedState.tag & HasEffect) {
17886 fiber.flags |= Passive$1;
17887 pushEffect(HasEffect | Passive, updateStoreInstance.bind(null, fiber, inst, nextSnapshot, getSnapshot), createEffectInstance(), null); // Unless we're rendering a blocking lane, schedule a consistency check.
17888 // Right before committing, we will walk the tree and check if any of the
17889 // stores were mutated.
17890
17891 var root = getWorkInProgressRoot();
17892
17893 if (root === null) {
17894 throw new Error('Expected a work-in-progress root. This is a bug in React. Please file an issue.');
17895 }
17896
17897 if (!isHydrating && !includesBlockingLane(root, renderLanes)) {
17898 pushStoreConsistencyCheck(fiber, getSnapshot, nextSnapshot);
17899 }
17900 }
17901
17902 return nextSnapshot;
17903}
17904
17905function pushStoreConsistencyCheck(fiber, getSnapshot, renderedSnapshot) {
17906 fiber.flags |= StoreConsistency;
17907 var check = {
17908 getSnapshot: getSnapshot,
17909 value: renderedSnapshot
17910 };
17911 var componentUpdateQueue = currentlyRenderingFiber$1.updateQueue;
17912
17913 if (componentUpdateQueue === null) {
17914 componentUpdateQueue = createFunctionComponentUpdateQueue();
17915 currentlyRenderingFiber$1.updateQueue = componentUpdateQueue;
17916 componentUpdateQueue.stores = [check];
17917 } else {
17918 var stores = componentUpdateQueue.stores;
17919
17920 if (stores === null) {
17921 componentUpdateQueue.stores = [check];
17922 } else {
17923 stores.push(check);
17924 }
17925 }
17926}
17927
17928function updateStoreInstance(fiber, inst, nextSnapshot, getSnapshot) {
17929 // These are updated in the passive phase
17930 inst.value = nextSnapshot;
17931 inst.getSnapshot = getSnapshot; // Something may have been mutated in between render and commit. This could
17932 // have been in an event that fired before the passive effects, or it could
17933 // have been in a layout effect. In that case, we would have used the old
17934 // snapsho and getSnapshot values to bail out. We need to check one more time.
17935
17936 if (checkIfSnapshotChanged(inst)) {
17937 // Force a re-render.
17938 forceStoreRerender(fiber);
17939 }
17940}
17941
17942function subscribeToStore(fiber, inst, subscribe) {
17943 var handleStoreChange = function () {
17944 // The store changed. Check if the snapshot changed since the last time we
17945 // read from the store.
17946 if (checkIfSnapshotChanged(inst)) {
17947 // Force a re-render.
17948 forceStoreRerender(fiber);
17949 }
17950 }; // Subscribe to the store and return a clean-up function.
17951
17952
17953 return subscribe(handleStoreChange);
17954}
17955
17956function checkIfSnapshotChanged(inst) {
17957 var latestGetSnapshot = inst.getSnapshot;
17958 var prevValue = inst.value;
17959
17960 try {
17961 var nextValue = latestGetSnapshot();
17962 return !objectIs(prevValue, nextValue);
17963 } catch (error) {
17964 return true;
17965 }
17966}
17967
17968function forceStoreRerender(fiber) {
17969 var root = enqueueConcurrentRenderForLane(fiber, SyncLane);
17970
17971 if (root !== null) {
17972 scheduleUpdateOnFiber(root, fiber, SyncLane);
17973 }
17974}
17975
17976function mountStateImpl(initialState) {
17977 var hook = mountWorkInProgressHook();
17978
17979 if (typeof initialState === 'function') {
17980 var initialStateInitializer = initialState; // $FlowFixMe[incompatible-use]: Flow doesn't like mixed types
17981
17982 initialState = initialStateInitializer();
17983
17984 if (shouldDoubleInvokeUserFnsInHooksDEV) {
17985 setIsStrictModeForDevtools(true); // $FlowFixMe[incompatible-use]: Flow doesn't like mixed types
17986
17987 initialStateInitializer();
17988 setIsStrictModeForDevtools(false);
17989 }
17990 }
17991
17992 hook.memoizedState = hook.baseState = initialState;
17993 var queue = {
17994 pending: null,
17995 lanes: NoLanes,
17996 dispatch: null,
17997 lastRenderedReducer: basicStateReducer,
17998 lastRenderedState: initialState
17999 };
18000 hook.queue = queue;
18001 return hook;
18002}
18003
18004function mountState(initialState) {
18005 var hook = mountStateImpl(initialState);
18006 var queue = hook.queue;
18007 var dispatch = dispatchSetState.bind(null, currentlyRenderingFiber$1, queue);
18008 queue.dispatch = dispatch;
18009 return [hook.memoizedState, dispatch];
18010}
18011
18012function updateState(initialState) {
18013 return updateReducer(basicStateReducer);
18014}
18015
18016function rerenderState(initialState) {
18017 return rerenderReducer(basicStateReducer);
18018}
18019
18020function mountOptimistic(passthrough, reducer) {
18021 var hook = mountWorkInProgressHook();
18022 hook.memoizedState = hook.baseState = passthrough;
18023 var queue = {
18024 pending: null,
18025 lanes: NoLanes,
18026 dispatch: null,
18027 // Optimistic state does not use the eager update optimization.
18028 lastRenderedReducer: null,
18029 lastRenderedState: null
18030 };
18031 hook.queue = queue; // This is different than the normal setState function.
18032
18033 var dispatch = dispatchOptimisticSetState.bind(null, currentlyRenderingFiber$1, true, queue);
18034 queue.dispatch = dispatch;
18035 return [passthrough, dispatch];
18036}
18037
18038function updateOptimistic(passthrough, reducer) {
18039 var hook = updateWorkInProgressHook();
18040 return updateOptimisticImpl(hook, currentHook, passthrough, reducer);
18041}
18042
18043function updateOptimisticImpl(hook, current, passthrough, reducer) {
18044 // Optimistic updates are always rebased on top of the latest value passed in
18045 // as an argument. It's called a passthrough because if there are no pending
18046 // updates, it will be returned as-is.
18047 //
18048 // Reset the base state to the passthrough. Future updates will be applied
18049 // on top of this.
18050 hook.baseState = passthrough; // If a reducer is not provided, default to the same one used by useState.
18051
18052 var resolvedReducer = typeof reducer === 'function' ? reducer : basicStateReducer;
18053 return updateReducerImpl(hook, currentHook, resolvedReducer);
18054}
18055
18056function rerenderOptimistic(passthrough, reducer) {
18057 // Unlike useState, useOptimistic doesn't support render phase updates.
18058 // Also unlike useState, we need to replay all pending updates again in case
18059 // the passthrough value changed.
18060 //
18061 // So instead of a forked re-render implementation that knows how to handle
18062 // render phase udpates, we can use the same implementation as during a
18063 // regular mount or update.
18064 var hook = updateWorkInProgressHook();
18065
18066 if (currentHook !== null) {
18067 // This is an update. Process the update queue.
18068 return updateOptimisticImpl(hook, currentHook, passthrough, reducer);
18069 } // This is a mount. No updates to process.
18070 // Reset the base state to the passthrough. Future updates will be applied
18071 // on top of this.
18072
18073
18074 hook.baseState = passthrough;
18075 var dispatch = hook.queue.dispatch;
18076 return [passthrough, dispatch];
18077} // useActionState actions run sequentially, because each action receives the
18078// previous state as an argument. We store pending actions on a queue.
18079
18080
18081function dispatchActionState(fiber, actionQueue, setPendingState, setState, payload) {
18082 if (isRenderPhaseUpdate(fiber)) {
18083 throw new Error('Cannot update form state while rendering.');
18084 }
18085
18086 var last = actionQueue.pending;
18087
18088 if (last === null) {
18089 // There are no pending actions; this is the first one. We can run
18090 // it immediately.
18091 var newLast = {
18092 payload: payload,
18093 next: null // circular
18094
18095 };
18096 newLast.next = actionQueue.pending = newLast;
18097 runActionStateAction(actionQueue, setPendingState, setState, payload);
18098 } else {
18099 // There's already an action running. Add to the queue.
18100 var first = last.next;
18101 var _newLast = {
18102 payload: payload,
18103 next: first
18104 };
18105 actionQueue.pending = last.next = _newLast;
18106 }
18107}
18108
18109function runActionStateAction(actionQueue, setPendingState, setState, payload) {
18110 var action = actionQueue.action;
18111 var prevState = actionQueue.state; // This is a fork of startTransition
18112
18113 var prevTransition = ReactSharedInternals.T;
18114 var currentTransition = {
18115 _callbacks: new Set()
18116 };
18117 ReactSharedInternals.T = currentTransition;
18118
18119 {
18120 ReactSharedInternals.T._updatedFibers = new Set();
18121 } // Optimistically update the pending state, similar to useTransition.
18122 // This will be reverted automatically when all actions are finished.
18123
18124
18125 setPendingState(true);
18126
18127 try {
18128 var returnValue = action(prevState, payload);
18129
18130 if (returnValue !== null && typeof returnValue === 'object' && // $FlowFixMe[method-unbinding]
18131 typeof returnValue.then === 'function') {
18132 var thenable = returnValue;
18133 notifyTransitionCallbacks(currentTransition, thenable); // Attach a listener to read the return state of the action. As soon as
18134 // this resolves, we can run the next action in the sequence.
18135
18136 thenable.then(function (nextState) {
18137 actionQueue.state = nextState;
18138 finishRunningActionStateAction(actionQueue, setPendingState, setState);
18139 }, function () {
18140 return finishRunningActionStateAction(actionQueue, setPendingState, setState);
18141 });
18142 setState(thenable);
18143 } else {
18144 setState(returnValue);
18145 var nextState = returnValue;
18146 actionQueue.state = nextState;
18147 finishRunningActionStateAction(actionQueue, setPendingState, setState);
18148 }
18149 } catch (error) {
18150 // This is a trick to get the `useActionState` hook to rethrow the error.
18151 // When it unwraps the thenable with the `use` algorithm, the error
18152 // will be thrown.
18153 var rejectedThenable = {
18154 then: function () {},
18155 status: 'rejected',
18156 reason: error // $FlowFixMe: Not sure why this doesn't work
18157
18158 };
18159 setState(rejectedThenable);
18160 finishRunningActionStateAction(actionQueue, setPendingState, setState);
18161 } finally {
18162 ReactSharedInternals.T = prevTransition;
18163
18164 {
18165 if (prevTransition === null && currentTransition._updatedFibers) {
18166 var updatedFibersCount = currentTransition._updatedFibers.size;
18167
18168 currentTransition._updatedFibers.clear();
18169
18170 if (updatedFibersCount > 10) {
18171 warn('Detected a large number of updates inside startTransition. ' + 'If this is due to a subscription please re-write it to use React provided hooks. ' + 'Otherwise concurrent mode guarantees are off the table.');
18172 }
18173 }
18174 }
18175 }
18176}
18177
18178function finishRunningActionStateAction(actionQueue, setPendingState, setState) {
18179 // The action finished running. Pop it from the queue and run the next pending
18180 // action, if there are any.
18181 var last = actionQueue.pending;
18182
18183 if (last !== null) {
18184 var first = last.next;
18185
18186 if (first === last) {
18187 // This was the last action in the queue.
18188 actionQueue.pending = null;
18189 } else {
18190 // Remove the first node from the circular queue.
18191 var next = first.next;
18192 last.next = next; // Run the next action.
18193
18194 runActionStateAction(actionQueue, setPendingState, setState, next.payload);
18195 }
18196 }
18197}
18198
18199function actionStateReducer(oldState, newState) {
18200 return newState;
18201}
18202
18203function mountActionState(action, initialStateProp, permalink) {
18204 var initialState = initialStateProp;
18205
18206 if (getIsHydrating()) {
18207 var root = getWorkInProgressRoot();
18208 var ssrFormState = root.formState; // If a formState option was passed to the root, there are form state
18209 // markers that we need to hydrate. These indicate whether the form state
18210 // matches this hook instance.
18211
18212 if (ssrFormState !== null) {
18213 var isMatching = tryToClaimNextHydratableFormMarkerInstance(currentlyRenderingFiber$1);
18214
18215 if (isMatching) {
18216 initialState = ssrFormState[0];
18217 }
18218 }
18219 } // State hook. The state is stored in a thenable which is then unwrapped by
18220 // the `use` algorithm during render.
18221
18222
18223 var stateHook = mountWorkInProgressHook();
18224 stateHook.memoizedState = stateHook.baseState = initialState; // TODO: Typing this "correctly" results in recursion limit errors
18225 // const stateQueue: UpdateQueue<S | Awaited<S>, S | Awaited<S>> = {
18226
18227 var stateQueue = {
18228 pending: null,
18229 lanes: NoLanes,
18230 dispatch: null,
18231 lastRenderedReducer: actionStateReducer,
18232 lastRenderedState: initialState
18233 };
18234 stateHook.queue = stateQueue;
18235 var setState = dispatchSetState.bind(null, currentlyRenderingFiber$1, stateQueue);
18236 stateQueue.dispatch = setState; // Pending state. This is used to store the pending state of the action.
18237 // Tracked optimistically, like a transition pending state.
18238
18239 var pendingStateHook = mountStateImpl(false);
18240 var setPendingState = dispatchOptimisticSetState.bind(null, currentlyRenderingFiber$1, false, pendingStateHook.queue); // Action queue hook. This is used to queue pending actions. The queue is
18241 // shared between all instances of the hook. Similar to a regular state queue,
18242 // but different because the actions are run sequentially, and they run in
18243 // an event instead of during render.
18244
18245 var actionQueueHook = mountWorkInProgressHook();
18246 var actionQueue = {
18247 state: initialState,
18248 dispatch: null,
18249 // circular
18250 action: action,
18251 pending: null
18252 };
18253 actionQueueHook.queue = actionQueue;
18254 var dispatch = dispatchActionState.bind(null, currentlyRenderingFiber$1, actionQueue, setPendingState, setState);
18255 actionQueue.dispatch = dispatch; // Stash the action function on the memoized state of the hook. We'll use this
18256 // to detect when the action function changes so we can update it in
18257 // an effect.
18258
18259 actionQueueHook.memoizedState = action;
18260 return [initialState, dispatch, false];
18261}
18262
18263function updateActionState(action, initialState, permalink) {
18264 var stateHook = updateWorkInProgressHook();
18265 var currentStateHook = currentHook;
18266 return updateActionStateImpl(stateHook, currentStateHook, action);
18267}
18268
18269function updateActionStateImpl(stateHook, currentStateHook, action, initialState, permalink) {
18270 var _updateReducerImpl = updateReducerImpl(stateHook, currentStateHook, actionStateReducer),
18271 actionResult = _updateReducerImpl[0];
18272
18273 var _updateState = updateState(),
18274 isPending = _updateState[0]; // This will suspend until the action finishes.
18275
18276
18277 var state = typeof actionResult === 'object' && actionResult !== null && // $FlowFixMe[method-unbinding]
18278 typeof actionResult.then === 'function' ? useThenable(actionResult) : actionResult;
18279 var actionQueueHook = updateWorkInProgressHook();
18280 var actionQueue = actionQueueHook.queue;
18281 var dispatch = actionQueue.dispatch; // Check if a new action was passed. If so, update it in an effect.
18282
18283 var prevAction = actionQueueHook.memoizedState;
18284
18285 if (action !== prevAction) {
18286 currentlyRenderingFiber$1.flags |= Passive$1;
18287 pushEffect(HasEffect | Passive, actionStateActionEffect.bind(null, actionQueue, action), createEffectInstance(), null);
18288 }
18289
18290 return [state, dispatch, isPending];
18291}
18292
18293function actionStateActionEffect(actionQueue, action) {
18294 actionQueue.action = action;
18295}
18296
18297function rerenderActionState(action, initialState, permalink) {
18298 // Unlike useState, useActionState doesn't support render phase updates.
18299 // Also unlike useState, we need to replay all pending updates again in case
18300 // the passthrough value changed.
18301 //
18302 // So instead of a forked re-render implementation that knows how to handle
18303 // render phase udpates, we can use the same implementation as during a
18304 // regular mount or update.
18305 var stateHook = updateWorkInProgressHook();
18306 var currentStateHook = currentHook;
18307
18308 if (currentStateHook !== null) {
18309 // This is an update. Process the update queue.
18310 return updateActionStateImpl(stateHook, currentStateHook, action);
18311 }
18312
18313 updateWorkInProgressHook(); // State
18314 // This is a mount. No updates to process.
18315
18316 var state = stateHook.memoizedState;
18317 var actionQueueHook = updateWorkInProgressHook();
18318 var actionQueue = actionQueueHook.queue;
18319 var dispatch = actionQueue.dispatch; // This may have changed during the rerender.
18320
18321 actionQueueHook.memoizedState = action; // For mount, pending is always false.
18322
18323 return [state, dispatch, false];
18324}
18325
18326function pushEffect(tag, create, inst, deps) {
18327 var effect = {
18328 tag: tag,
18329 create: create,
18330 inst: inst,
18331 deps: deps,
18332 // Circular
18333 next: null
18334 };
18335 var componentUpdateQueue = currentlyRenderingFiber$1.updateQueue;
18336
18337 if (componentUpdateQueue === null) {
18338 componentUpdateQueue = createFunctionComponentUpdateQueue();
18339 currentlyRenderingFiber$1.updateQueue = componentUpdateQueue;
18340 componentUpdateQueue.lastEffect = effect.next = effect;
18341 } else {
18342 var lastEffect = componentUpdateQueue.lastEffect;
18343
18344 if (lastEffect === null) {
18345 componentUpdateQueue.lastEffect = effect.next = effect;
18346 } else {
18347 var firstEffect = lastEffect.next;
18348 lastEffect.next = effect;
18349 effect.next = firstEffect;
18350 componentUpdateQueue.lastEffect = effect;
18351 }
18352 }
18353
18354 return effect;
18355}
18356
18357function createEffectInstance() {
18358 return {
18359 destroy: undefined
18360 };
18361}
18362
18363function mountRef(initialValue) {
18364 var hook = mountWorkInProgressHook();
18365 var ref = {
18366 current: initialValue
18367 };
18368 hook.memoizedState = ref;
18369 return ref;
18370}
18371
18372function updateRef(initialValue) {
18373 var hook = updateWorkInProgressHook();
18374 return hook.memoizedState;
18375}
18376
18377function mountEffectImpl(fiberFlags, hookFlags, create, deps) {
18378 var hook = mountWorkInProgressHook();
18379 var nextDeps = deps === undefined ? null : deps;
18380 currentlyRenderingFiber$1.flags |= fiberFlags;
18381 hook.memoizedState = pushEffect(HasEffect | hookFlags, create, createEffectInstance(), nextDeps);
18382}
18383
18384function updateEffectImpl(fiberFlags, hookFlags, create, deps) {
18385 var hook = updateWorkInProgressHook();
18386 var nextDeps = deps === undefined ? null : deps;
18387 var effect = hook.memoizedState;
18388 var inst = effect.inst; // currentHook is null on initial mount when rerendering after a render phase
18389 // state update or for strict mode.
18390
18391 if (currentHook !== null) {
18392 if (nextDeps !== null) {
18393 var prevEffect = currentHook.memoizedState;
18394 var prevDeps = prevEffect.deps;
18395
18396 if (areHookInputsEqual(nextDeps, prevDeps)) {
18397 hook.memoizedState = pushEffect(hookFlags, create, inst, nextDeps);
18398 return;
18399 }
18400 }
18401 }
18402
18403 currentlyRenderingFiber$1.flags |= fiberFlags;
18404 hook.memoizedState = pushEffect(HasEffect | hookFlags, create, inst, nextDeps);
18405}
18406
18407function mountEffect(create, deps) {
18408 if ((currentlyRenderingFiber$1.mode & StrictEffectsMode) !== NoMode && (currentlyRenderingFiber$1.mode & NoStrictPassiveEffectsMode) === NoMode) {
18409 mountEffectImpl(MountPassiveDev | Passive$1 | PassiveStatic, Passive, create, deps);
18410 } else {
18411 mountEffectImpl(Passive$1 | PassiveStatic, Passive, create, deps);
18412 }
18413}
18414
18415function updateEffect(create, deps) {
18416 updateEffectImpl(Passive$1, Passive, create, deps);
18417}
18418
18419function mountInsertionEffect(create, deps) {
18420 mountEffectImpl(Update, Insertion, create, deps);
18421}
18422
18423function updateInsertionEffect(create, deps) {
18424 return updateEffectImpl(Update, Insertion, create, deps);
18425}
18426
18427function mountLayoutEffect(create, deps) {
18428 var fiberFlags = Update | LayoutStatic;
18429
18430 if ((currentlyRenderingFiber$1.mode & StrictEffectsMode) !== NoMode) {
18431 fiberFlags |= MountLayoutDev;
18432 }
18433
18434 return mountEffectImpl(fiberFlags, Layout, create, deps);
18435}
18436
18437function updateLayoutEffect(create, deps) {
18438 return updateEffectImpl(Update, Layout, create, deps);
18439}
18440
18441function imperativeHandleEffect(create, ref) {
18442 if (typeof ref === 'function') {
18443 var refCallback = ref;
18444 var inst = create();
18445 var refCleanup = refCallback(inst);
18446 return function () {
18447 if (typeof refCleanup === 'function') {
18448 // $FlowFixMe[incompatible-use] we need to assume no parameters
18449 refCleanup();
18450 } else {
18451 refCallback(null);
18452 }
18453 };
18454 } else if (ref !== null && ref !== undefined) {
18455 var refObject = ref;
18456
18457 {
18458 if (!refObject.hasOwnProperty('current')) {
18459 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(', ') + '}');
18460 }
18461 }
18462
18463 var _inst = create();
18464
18465 refObject.current = _inst;
18466 return function () {
18467 refObject.current = null;
18468 };
18469 }
18470}
18471
18472function mountImperativeHandle(ref, create, deps) {
18473 {
18474 if (typeof create !== 'function') {
18475 error('Expected useImperativeHandle() second argument to be a function ' + 'that creates a handle. Instead received: %s.', create !== null ? typeof create : 'null');
18476 }
18477 } // TODO: If deps are provided, should we skip comparing the ref itself?
18478
18479
18480 var effectDeps = deps !== null && deps !== undefined ? deps.concat([ref]) : null;
18481 var fiberFlags = Update | LayoutStatic;
18482
18483 if ((currentlyRenderingFiber$1.mode & StrictEffectsMode) !== NoMode) {
18484 fiberFlags |= MountLayoutDev;
18485 }
18486
18487 mountEffectImpl(fiberFlags, Layout, imperativeHandleEffect.bind(null, create, ref), effectDeps);
18488}
18489
18490function updateImperativeHandle(ref, create, deps) {
18491 {
18492 if (typeof create !== 'function') {
18493 error('Expected useImperativeHandle() second argument to be a function ' + 'that creates a handle. Instead received: %s.', create !== null ? typeof create : 'null');
18494 }
18495 } // TODO: If deps are provided, should we skip comparing the ref itself?
18496
18497
18498 var effectDeps = deps !== null && deps !== undefined ? deps.concat([ref]) : null;
18499 updateEffectImpl(Update, Layout, imperativeHandleEffect.bind(null, create, ref), effectDeps);
18500}
18501
18502function mountDebugValue(value, formatterFn) {// This hook is normally a no-op.
18503 // The react-debug-hooks package injects its own implementation
18504 // so that e.g. DevTools can display custom hook values.
18505}
18506
18507var updateDebugValue = mountDebugValue;
18508
18509function mountCallback(callback, deps) {
18510 var hook = mountWorkInProgressHook();
18511 var nextDeps = deps === undefined ? null : deps;
18512 hook.memoizedState = [callback, nextDeps];
18513 return callback;
18514}
18515
18516function updateCallback(callback, deps) {
18517 var hook = updateWorkInProgressHook();
18518 var nextDeps = deps === undefined ? null : deps;
18519 var prevState = hook.memoizedState;
18520
18521 if (nextDeps !== null) {
18522 var prevDeps = prevState[1];
18523
18524 if (areHookInputsEqual(nextDeps, prevDeps)) {
18525 return prevState[0];
18526 }
18527 }
18528
18529 hook.memoizedState = [callback, nextDeps];
18530 return callback;
18531}
18532
18533function mountMemo(nextCreate, deps) {
18534 var hook = mountWorkInProgressHook();
18535 var nextDeps = deps === undefined ? null : deps;
18536 var nextValue = nextCreate();
18537
18538 if (shouldDoubleInvokeUserFnsInHooksDEV) {
18539 setIsStrictModeForDevtools(true);
18540 nextCreate();
18541 setIsStrictModeForDevtools(false);
18542 }
18543
18544 hook.memoizedState = [nextValue, nextDeps];
18545 return nextValue;
18546}
18547
18548function updateMemo(nextCreate, deps) {
18549 var hook = updateWorkInProgressHook();
18550 var nextDeps = deps === undefined ? null : deps;
18551 var prevState = hook.memoizedState; // Assume these are defined. If they're not, areHookInputsEqual will warn.
18552
18553 if (nextDeps !== null) {
18554 var prevDeps = prevState[1];
18555
18556 if (areHookInputsEqual(nextDeps, prevDeps)) {
18557 return prevState[0];
18558 }
18559 }
18560
18561 var nextValue = nextCreate();
18562
18563 if (shouldDoubleInvokeUserFnsInHooksDEV) {
18564 setIsStrictModeForDevtools(true);
18565 nextCreate();
18566 setIsStrictModeForDevtools(false);
18567 }
18568
18569 hook.memoizedState = [nextValue, nextDeps];
18570 return nextValue;
18571}
18572
18573function mountDeferredValue(value, initialValue) {
18574 var hook = mountWorkInProgressHook();
18575 return mountDeferredValueImpl(hook, value, initialValue);
18576}
18577
18578function updateDeferredValue(value, initialValue) {
18579 var hook = updateWorkInProgressHook();
18580 var resolvedCurrentHook = currentHook;
18581 var prevValue = resolvedCurrentHook.memoizedState;
18582 return updateDeferredValueImpl(hook, prevValue, value, initialValue);
18583}
18584
18585function rerenderDeferredValue(value, initialValue) {
18586 var hook = updateWorkInProgressHook();
18587
18588 if (currentHook === null) {
18589 // This is a rerender during a mount.
18590 return mountDeferredValueImpl(hook, value, initialValue);
18591 } else {
18592 // This is a rerender during an update.
18593 var prevValue = currentHook.memoizedState;
18594 return updateDeferredValueImpl(hook, prevValue, value, initialValue);
18595 }
18596}
18597
18598function mountDeferredValueImpl(hook, value, initialValue) {
18599 if (// When `initialValue` is provided, we defer the initial render even if the
18600 // current render is not synchronous.
18601 initialValue !== undefined && // However, to avoid waterfalls, we do not defer if this render
18602 // was itself spawned by an earlier useDeferredValue. Check if DeferredLane
18603 // is part of the render lanes.
18604 !includesSomeLane(renderLanes, DeferredLane)) {
18605 // Render with the initial value
18606 hook.memoizedState = initialValue; // Schedule a deferred render to switch to the final value.
18607
18608 var deferredLane = requestDeferredLane();
18609 currentlyRenderingFiber$1.lanes = mergeLanes(currentlyRenderingFiber$1.lanes, deferredLane);
18610 markSkippedUpdateLanes(deferredLane);
18611 return initialValue;
18612 } else {
18613 hook.memoizedState = value;
18614 return value;
18615 }
18616}
18617
18618function updateDeferredValueImpl(hook, prevValue, value, initialValue) {
18619 if (objectIs(value, prevValue)) {
18620 // The incoming value is referentially identical to the currently rendered
18621 // value, so we can bail out quickly.
18622 return value;
18623 } else {
18624 // Received a new value that's different from the current value.
18625 // Check if we're inside a hidden tree
18626 if (isCurrentTreeHidden()) {
18627 // Revealing a prerendered tree is considered the same as mounting new
18628 // one, so we reuse the "mount" path in this case.
18629 var resultValue = mountDeferredValueImpl(hook, value, initialValue); // Unlike during an actual mount, we need to mark this as an update if
18630 // the value changed.
18631
18632 if (!objectIs(resultValue, prevValue)) {
18633 markWorkInProgressReceivedUpdate();
18634 }
18635
18636 return resultValue;
18637 }
18638
18639 var shouldDeferValue = !includesOnlyNonUrgentLanes(renderLanes);
18640
18641 if (shouldDeferValue) {
18642 // This is an urgent update. Since the value has changed, keep using the
18643 // previous value and spawn a deferred render to update it later.
18644 // Schedule a deferred render
18645 var deferredLane = requestDeferredLane();
18646 currentlyRenderingFiber$1.lanes = mergeLanes(currentlyRenderingFiber$1.lanes, deferredLane);
18647 markSkippedUpdateLanes(deferredLane); // Reuse the previous value. We do not need to mark this as an update,
18648 // because we did not render a new value.
18649
18650 return prevValue;
18651 } else {
18652 // This is not an urgent update, so we can use the latest value regardless
18653 // of what it is. No need to defer it.
18654 // Mark this as an update to prevent the fiber from bailing out.
18655 markWorkInProgressReceivedUpdate();
18656 hook.memoizedState = value;
18657 return value;
18658 }
18659 }
18660}
18661
18662function startTransition(fiber, queue, pendingState, finishedState, callback, options) {
18663 var previousPriority = getCurrentUpdatePriority();
18664 setCurrentUpdatePriority(higherEventPriority(previousPriority, ContinuousEventPriority));
18665 var prevTransition = ReactSharedInternals.T;
18666 var currentTransition = {
18667 _callbacks: new Set()
18668 };
18669
18670 {
18671 // We don't really need to use an optimistic update here, because we
18672 // schedule a second "revert" update below (which we use to suspend the
18673 // transition until the async action scope has finished). But we'll use an
18674 // optimistic update anyway to make it less likely the behavior accidentally
18675 // diverges; for example, both an optimistic update and this one should
18676 // share the same lane.
18677 ReactSharedInternals.T = currentTransition;
18678 dispatchOptimisticSetState(fiber, false, queue, pendingState);
18679 }
18680
18681 {
18682 currentTransition._updatedFibers = new Set();
18683 }
18684
18685 try {
18686 if (enableAsyncActions) {
18687 var returnValue = callback(); // Check if we're inside an async action scope. If so, we'll entangle
18688 // this new action with the existing scope.
18689 //
18690 // If we're not already inside an async action scope, and this action is
18691 // async, then we'll create a new async scope.
18692 //
18693 // In the async case, the resulting render will suspend until the async
18694 // action scope has finished.
18695
18696 if (returnValue !== null && typeof returnValue === 'object' && typeof returnValue.then === 'function') {
18697 var thenable = returnValue;
18698 notifyTransitionCallbacks(currentTransition, thenable); // Create a thenable that resolves to `finishedState` once the async
18699 // action has completed.
18700
18701 var thenableForFinishedState = chainThenableValue(thenable, finishedState);
18702 dispatchSetState(fiber, queue, thenableForFinishedState);
18703 } else {
18704 dispatchSetState(fiber, queue, finishedState);
18705 }
18706 }
18707 } catch (error) {
18708 {
18709 // This is a trick to get the `useTransition` hook to rethrow the error.
18710 // When it unwraps the thenable with the `use` algorithm, the error
18711 // will be thrown.
18712 var rejectedThenable = {
18713 then: function () {},
18714 status: 'rejected',
18715 reason: error
18716 };
18717 dispatchSetState(fiber, queue, rejectedThenable);
18718 }
18719 } finally {
18720 setCurrentUpdatePriority(previousPriority);
18721 ReactSharedInternals.T = prevTransition;
18722
18723 {
18724 if (prevTransition === null && currentTransition._updatedFibers) {
18725 var updatedFibersCount = currentTransition._updatedFibers.size;
18726
18727 currentTransition._updatedFibers.clear();
18728
18729 if (updatedFibersCount > 10) {
18730 warn('Detected a large number of updates inside startTransition. ' + 'If this is due to a subscription please re-write it to use React provided hooks. ' + 'Otherwise concurrent mode guarantees are off the table.');
18731 }
18732 }
18733 }
18734 }
18735}
18736
18737function startHostTransition(formFiber, pendingState, callback, formData) {
18738
18739 if (formFiber.tag !== HostComponent) {
18740 throw new Error('Expected the form instance to be a HostComponent. This ' + 'is a bug in React.');
18741 }
18742
18743 var stateHook = ensureFormComponentIsStateful(formFiber);
18744 var queue = stateHook.queue;
18745 startTransition(formFiber, queue, pendingState, NotPendingTransition, // TODO: We can avoid this extra wrapper, somehow. Figure out layering
18746 // once more of this function is implemented.
18747 function () {
18748 // Automatically reset the form when the action completes.
18749 requestFormReset$1(formFiber);
18750 return callback(formData);
18751 });
18752}
18753
18754function ensureFormComponentIsStateful(formFiber) {
18755 var existingStateHook = formFiber.memoizedState;
18756
18757 if (existingStateHook !== null) {
18758 // This fiber was already upgraded to be stateful.
18759 return existingStateHook;
18760 } // Upgrade this host component fiber to be stateful. We're going to pretend
18761 // it was stateful all along so we can reuse most of the implementation
18762 // for function components and useTransition.
18763 //
18764 // Create the state hook used by TransitionAwareHostComponent. This is
18765 // essentially an inlined version of mountState.
18766
18767
18768 var newQueue = {
18769 pending: null,
18770 lanes: NoLanes,
18771 // We're going to cheat and intentionally not create a bound dispatch
18772 // method, because we can call it directly in startTransition.
18773 dispatch: null,
18774 lastRenderedReducer: basicStateReducer,
18775 lastRenderedState: NotPendingTransition
18776 };
18777 var stateHook = {
18778 memoizedState: NotPendingTransition,
18779 baseState: NotPendingTransition,
18780 baseQueue: null,
18781 queue: newQueue,
18782 next: null
18783 }; // We use another state hook to track whether the form needs to be reset.
18784 // The state is an empty object. To trigger a reset, we update the state
18785 // to a new object. Then during rendering, we detect that the state has
18786 // changed and schedule a commit effect.
18787
18788 var initialResetState = {};
18789 var newResetStateQueue = {
18790 pending: null,
18791 lanes: NoLanes,
18792 // We're going to cheat and intentionally not create a bound dispatch
18793 // method, because we can call it directly in startTransition.
18794 dispatch: null,
18795 lastRenderedReducer: basicStateReducer,
18796 lastRenderedState: initialResetState
18797 };
18798 var resetStateHook = {
18799 memoizedState: initialResetState,
18800 baseState: initialResetState,
18801 baseQueue: null,
18802 queue: newResetStateQueue,
18803 next: null
18804 };
18805 stateHook.next = resetStateHook; // Add the hook list to both fiber alternates. The idea is that the fiber
18806 // had this hook all along.
18807
18808 formFiber.memoizedState = stateHook;
18809 var alternate = formFiber.alternate;
18810
18811 if (alternate !== null) {
18812 alternate.memoizedState = stateHook;
18813 }
18814
18815 return stateHook;
18816}
18817
18818function requestFormReset$1(formFiber) {
18819 var transition = requestCurrentTransition();
18820
18821 {
18822 if (transition === null) {
18823 // An optimistic update occurred, but startTransition is not on the stack.
18824 // The form reset will be scheduled at default (sync) priority, which
18825 // is probably not what the user intended. Most likely because the
18826 // requestFormReset call happened after an `await`.
18827 // TODO: Theoretically, requestFormReset is still useful even for
18828 // non-transition updates because it allows you to update defaultValue
18829 // synchronously and then wait to reset until after the update commits.
18830 // I've chosen to warn anyway because it's more likely the `await` mistake
18831 // described above. But arguably we shouldn't.
18832 error('requestFormReset was called outside a transition or action. To ' + 'fix, move to an action, or wrap with startTransition.');
18833 }
18834 }
18835
18836 var stateHook = ensureFormComponentIsStateful(formFiber);
18837 var newResetState = {};
18838 var resetStateHook = stateHook.next;
18839 var resetStateQueue = resetStateHook.queue;
18840 dispatchSetState(formFiber, resetStateQueue, newResetState);
18841}
18842
18843function mountTransition() {
18844 var stateHook = mountStateImpl(false); // The `start` method never changes.
18845
18846 var start = startTransition.bind(null, currentlyRenderingFiber$1, stateHook.queue, true, false);
18847 var hook = mountWorkInProgressHook();
18848 hook.memoizedState = start;
18849 return [false, start];
18850}
18851
18852function updateTransition() {
18853 var _updateState2 = updateState(),
18854 booleanOrThenable = _updateState2[0];
18855
18856 var hook = updateWorkInProgressHook();
18857 var start = hook.memoizedState;
18858 var isPending = typeof booleanOrThenable === 'boolean' ? booleanOrThenable : // This will suspend until the async action scope has finished.
18859 useThenable(booleanOrThenable);
18860 return [isPending, start];
18861}
18862
18863function rerenderTransition() {
18864 var _rerenderState = rerenderState(),
18865 booleanOrThenable = _rerenderState[0];
18866
18867 var hook = updateWorkInProgressHook();
18868 var start = hook.memoizedState;
18869 var isPending = typeof booleanOrThenable === 'boolean' ? booleanOrThenable : // This will suspend until the async action scope has finished.
18870 useThenable(booleanOrThenable);
18871 return [isPending, start];
18872}
18873
18874function useHostTransitionStatus() {
18875
18876 var status = readContext(HostTransitionContext);
18877 return status !== null ? status : NotPendingTransition;
18878}
18879
18880function mountId() {
18881 var hook = mountWorkInProgressHook();
18882 var root = getWorkInProgressRoot(); // TODO: In Fizz, id generation is specific to each server config. Maybe we
18883 // should do this in Fiber, too? Deferring this decision for now because
18884 // there's no other place to store the prefix except for an internal field on
18885 // the public createRoot object, which the fiber tree does not currently have
18886 // a reference to.
18887
18888 var identifierPrefix = root.identifierPrefix;
18889 var id;
18890
18891 if (getIsHydrating()) {
18892 var treeId = getTreeId(); // Use a captial R prefix for server-generated ids.
18893
18894 id = ':' + identifierPrefix + 'R' + treeId; // Unless this is the first id at this level, append a number at the end
18895 // that represents the position of this useId hook among all the useId
18896 // hooks for this fiber.
18897
18898 var localId = localIdCounter++;
18899
18900 if (localId > 0) {
18901 id += 'H' + localId.toString(32);
18902 }
18903
18904 id += ':';
18905 } else {
18906 // Use a lowercase r prefix for client-generated ids.
18907 var globalClientId = globalClientIdCounter++;
18908 id = ':' + identifierPrefix + 'r' + globalClientId.toString(32) + ':';
18909 }
18910
18911 hook.memoizedState = id;
18912 return id;
18913}
18914
18915function updateId() {
18916 var hook = updateWorkInProgressHook();
18917 var id = hook.memoizedState;
18918 return id;
18919}
18920
18921function mountRefresh() {
18922 var hook = mountWorkInProgressHook();
18923 var refresh = hook.memoizedState = refreshCache.bind(null, currentlyRenderingFiber$1);
18924 return refresh;
18925}
18926
18927function updateRefresh() {
18928 var hook = updateWorkInProgressHook();
18929 return hook.memoizedState;
18930}
18931
18932function refreshCache(fiber, seedKey, seedValue) {
18933 // TODO: Consider warning if the refresh is at discrete priority, or if we
18934 // otherwise suspect that it wasn't batched properly.
18935
18936
18937 var provider = fiber.return;
18938
18939 while (provider !== null) {
18940 switch (provider.tag) {
18941 case CacheComponent:
18942 case HostRoot:
18943 {
18944 // Schedule an update on the cache boundary to trigger a refresh.
18945 var lane = requestUpdateLane(provider);
18946 var refreshUpdate = createUpdate(lane);
18947 var root = enqueueUpdate(provider, refreshUpdate, lane);
18948
18949 if (root !== null) {
18950 scheduleUpdateOnFiber(root, provider, lane);
18951 entangleTransitions(root, provider, lane);
18952 } // TODO: If a refresh never commits, the new cache created here must be
18953 // released. A simple case is start refreshing a cache boundary, but then
18954 // unmount that boundary before the refresh completes.
18955
18956
18957 var seededCache = createCache();
18958
18959 if (seedKey !== null && seedKey !== undefined && root !== null) {
18960 {
18961 {
18962 error('The seed argument is not enabled outside experimental channels.');
18963 }
18964 }
18965 }
18966
18967 var payload = {
18968 cache: seededCache
18969 };
18970 refreshUpdate.payload = payload;
18971 return;
18972 }
18973 }
18974
18975 provider = provider.return;
18976 } // TODO: Warn if unmounted?
18977
18978}
18979
18980function dispatchReducerAction(fiber, queue, action) {
18981 {
18982 if (typeof arguments[3] === 'function') {
18983 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().');
18984 }
18985 }
18986
18987 var lane = requestUpdateLane(fiber);
18988 var update = {
18989 lane: lane,
18990 revertLane: NoLane,
18991 action: action,
18992 hasEagerState: false,
18993 eagerState: null,
18994 next: null
18995 };
18996
18997 if (isRenderPhaseUpdate(fiber)) {
18998 enqueueRenderPhaseUpdate(queue, update);
18999 } else {
19000 var root = enqueueConcurrentHookUpdate(fiber, queue, update, lane);
19001
19002 if (root !== null) {
19003 scheduleUpdateOnFiber(root, fiber, lane);
19004 entangleTransitionUpdate(root, queue, lane);
19005 }
19006 }
19007
19008 markUpdateInDevTools(fiber, lane);
19009}
19010
19011function dispatchSetState(fiber, queue, action) {
19012 {
19013 if (typeof arguments[3] === 'function') {
19014 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().');
19015 }
19016 }
19017
19018 var lane = requestUpdateLane(fiber);
19019 var update = {
19020 lane: lane,
19021 revertLane: NoLane,
19022 action: action,
19023 hasEagerState: false,
19024 eagerState: null,
19025 next: null
19026 };
19027
19028 if (isRenderPhaseUpdate(fiber)) {
19029 enqueueRenderPhaseUpdate(queue, update);
19030 } else {
19031 var alternate = fiber.alternate;
19032
19033 if (fiber.lanes === NoLanes && (alternate === null || alternate.lanes === NoLanes)) {
19034 // The queue is currently empty, which means we can eagerly compute the
19035 // next state before entering the render phase. If the new state is the
19036 // same as the current state, we may be able to bail out entirely.
19037 var lastRenderedReducer = queue.lastRenderedReducer;
19038
19039 if (lastRenderedReducer !== null) {
19040 var prevDispatcher = null;
19041
19042 {
19043 prevDispatcher = ReactSharedInternals.H;
19044 ReactSharedInternals.H = InvalidNestedHooksDispatcherOnUpdateInDEV;
19045 }
19046
19047 try {
19048 var currentState = queue.lastRenderedState;
19049 var eagerState = lastRenderedReducer(currentState, action); // Stash the eagerly computed state, and the reducer used to compute
19050 // it, on the update object. If the reducer hasn't changed by the
19051 // time we enter the render phase, then the eager state can be used
19052 // without calling the reducer again.
19053
19054 update.hasEagerState = true;
19055 update.eagerState = eagerState;
19056
19057 if (objectIs(eagerState, currentState)) {
19058 // Fast path. We can bail out without scheduling React to re-render.
19059 // It's still possible that we'll need to rebase this update later,
19060 // if the component re-renders for a different reason and by that
19061 // time the reducer has changed.
19062 // TODO: Do we still need to entangle transitions in this case?
19063 enqueueConcurrentHookUpdateAndEagerlyBailout(fiber, queue, update);
19064 return;
19065 }
19066 } catch (error) {// Suppress the error. It will throw again in the render phase.
19067 } finally {
19068 {
19069 ReactSharedInternals.H = prevDispatcher;
19070 }
19071 }
19072 }
19073 }
19074
19075 var root = enqueueConcurrentHookUpdate(fiber, queue, update, lane);
19076
19077 if (root !== null) {
19078 scheduleUpdateOnFiber(root, fiber, lane);
19079 entangleTransitionUpdate(root, queue, lane);
19080 }
19081 }
19082
19083 markUpdateInDevTools(fiber, lane);
19084}
19085
19086function dispatchOptimisticSetState(fiber, throwIfDuringRender, queue, action) {
19087 var transition = requestCurrentTransition();
19088
19089 {
19090 if (transition === null) {
19091 // An optimistic update occurred, but startTransition is not on the stack.
19092 // There are two likely scenarios.
19093 // One possibility is that the optimistic update is triggered by a regular
19094 // event handler (e.g. `onSubmit`) instead of an action. This is a mistake
19095 // and we will warn.
19096 // The other possibility is the optimistic update is inside an async
19097 // action, but after an `await`. In this case, we can make it "just work"
19098 // by associating the optimistic update with the pending async action.
19099 // Technically it's possible that the optimistic update is unrelated to
19100 // the pending action, but we don't have a way of knowing this for sure
19101 // because browsers currently do not provide a way to track async scope.
19102 // (The AsyncContext proposal, if it lands, will solve this in the
19103 // future.) However, this is no different than the problem of unrelated
19104 // transitions being grouped together — it's not wrong per se, but it's
19105 // not ideal.
19106 // Once AsyncContext starts landing in browsers, we will provide better
19107 // warnings in development for these cases.
19108 if (peekEntangledActionLane() !== NoLane) ; else {
19109 // There's no pending async action. The most likely cause is that we're
19110 // inside a regular event handler (e.g. onSubmit) instead of an action.
19111 error('An optimistic state update occurred outside a transition or ' + 'action. To fix, move the update to an action, or wrap ' + 'with startTransition.');
19112 }
19113 }
19114 }
19115
19116 var update = {
19117 // An optimistic update commits synchronously.
19118 lane: SyncLane,
19119 // After committing, the optimistic update is "reverted" using the same
19120 // lane as the transition it's associated with.
19121 revertLane: requestTransitionLane(),
19122 action: action,
19123 hasEagerState: false,
19124 eagerState: null,
19125 next: null
19126 };
19127
19128 if (isRenderPhaseUpdate(fiber)) {
19129 // When calling startTransition during render, this warns instead of
19130 // throwing because throwing would be a breaking change. setOptimisticState
19131 // is a new API so it's OK to throw.
19132 if (throwIfDuringRender) {
19133 throw new Error('Cannot update optimistic state while rendering.');
19134 } else {
19135 // startTransition was called during render. We don't need to do anything
19136 // besides warn here because the render phase update would be overidden by
19137 // the second update, anyway. We can remove this branch and make it throw
19138 // in a future release.
19139 {
19140 error('Cannot call startTransition while rendering.');
19141 }
19142 }
19143 } else {
19144 var root = enqueueConcurrentHookUpdate(fiber, queue, update, SyncLane);
19145
19146 if (root !== null) {
19147 // NOTE: The optimistic update implementation assumes that the transition
19148 // will never be attempted before the optimistic update. This currently
19149 // holds because the optimistic update is always synchronous. If we ever
19150 // change that, we'll need to account for this.
19151 scheduleUpdateOnFiber(root, fiber, SyncLane); // Optimistic updates are always synchronous, so we don't need to call
19152 // entangleTransitionUpdate here.
19153 }
19154 }
19155
19156 markUpdateInDevTools(fiber, SyncLane);
19157}
19158
19159function isRenderPhaseUpdate(fiber) {
19160 var alternate = fiber.alternate;
19161 return fiber === currentlyRenderingFiber$1 || alternate !== null && alternate === currentlyRenderingFiber$1;
19162}
19163
19164function enqueueRenderPhaseUpdate(queue, update) {
19165 // This is a render phase update. Stash it in a lazily-created map of
19166 // queue -> linked list of updates. After this render pass, we'll restart
19167 // and apply the stashed updates on top of the work-in-progress hook.
19168 didScheduleRenderPhaseUpdateDuringThisPass = didScheduleRenderPhaseUpdate = true;
19169 var pending = queue.pending;
19170
19171 if (pending === null) {
19172 // This is the first update. Create a circular list.
19173 update.next = update;
19174 } else {
19175 update.next = pending.next;
19176 pending.next = update;
19177 }
19178
19179 queue.pending = update;
19180} // TODO: Move to ReactFiberConcurrentUpdates?
19181
19182
19183function entangleTransitionUpdate(root, queue, lane) {
19184 if (isTransitionLane(lane)) {
19185 var queueLanes = queue.lanes; // If any entangled lanes are no longer pending on the root, then they
19186 // must have finished. We can remove them from the shared queue, which
19187 // represents a superset of the actually pending lanes. In some cases we
19188 // may entangle more than we need to, but that's OK. In fact it's worse if
19189 // we *don't* entangle when we should.
19190
19191 queueLanes = intersectLanes(queueLanes, root.pendingLanes); // Entangle the new transition lane with the other transition lanes.
19192
19193 var newQueueLanes = mergeLanes(queueLanes, lane);
19194 queue.lanes = newQueueLanes; // Even if queue.lanes already include lane, we don't know for certain if
19195 // the lane finished since the last time we entangled it. So we need to
19196 // entangle it again, just to be sure.
19197
19198 markRootEntangled(root, newQueueLanes);
19199 }
19200}
19201
19202function markUpdateInDevTools(fiber, lane, action) {
19203
19204 {
19205 markStateUpdateScheduled(fiber, lane);
19206 }
19207}
19208
19209var ContextOnlyDispatcher = {
19210 readContext: readContext,
19211 use: use,
19212 useCallback: throwInvalidHookError,
19213 useContext: throwInvalidHookError,
19214 useEffect: throwInvalidHookError,
19215 useImperativeHandle: throwInvalidHookError,
19216 useLayoutEffect: throwInvalidHookError,
19217 useInsertionEffect: throwInvalidHookError,
19218 useMemo: throwInvalidHookError,
19219 useReducer: throwInvalidHookError,
19220 useRef: throwInvalidHookError,
19221 useState: throwInvalidHookError,
19222 useDebugValue: throwInvalidHookError,
19223 useDeferredValue: throwInvalidHookError,
19224 useTransition: throwInvalidHookError,
19225 useSyncExternalStore: throwInvalidHookError,
19226 useId: throwInvalidHookError
19227};
19228
19229{
19230 ContextOnlyDispatcher.useCacheRefresh = throwInvalidHookError;
19231}
19232
19233{
19234 ContextOnlyDispatcher.useHostTransitionStatus = throwInvalidHookError;
19235 ContextOnlyDispatcher.useFormState = throwInvalidHookError;
19236 ContextOnlyDispatcher.useActionState = throwInvalidHookError;
19237}
19238
19239{
19240 ContextOnlyDispatcher.useOptimistic = throwInvalidHookError;
19241}
19242
19243var HooksDispatcherOnMountInDEV = null;
19244var HooksDispatcherOnMountWithHookTypesInDEV = null;
19245var HooksDispatcherOnUpdateInDEV = null;
19246var HooksDispatcherOnRerenderInDEV = null;
19247var InvalidNestedHooksDispatcherOnMountInDEV = null;
19248var InvalidNestedHooksDispatcherOnUpdateInDEV = null;
19249var InvalidNestedHooksDispatcherOnRerenderInDEV = null;
19250
19251{
19252 var warnInvalidContextAccess = function () {
19253 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().');
19254 };
19255
19256 var warnInvalidHookAccess = function () {
19257 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://react.dev/link/rules-of-hooks');
19258 };
19259
19260 HooksDispatcherOnMountInDEV = {
19261 readContext: function (context) {
19262 return readContext(context);
19263 },
19264 use: use,
19265 useCallback: function (callback, deps) {
19266 currentHookNameInDev = 'useCallback';
19267 mountHookTypesDev();
19268 checkDepsAreArrayDev(deps);
19269 return mountCallback(callback, deps);
19270 },
19271 useContext: function (context) {
19272 currentHookNameInDev = 'useContext';
19273 mountHookTypesDev();
19274 return readContext(context);
19275 },
19276 useEffect: function (create, deps) {
19277 currentHookNameInDev = 'useEffect';
19278 mountHookTypesDev();
19279 checkDepsAreArrayDev(deps);
19280 return mountEffect(create, deps);
19281 },
19282 useImperativeHandle: function (ref, create, deps) {
19283 currentHookNameInDev = 'useImperativeHandle';
19284 mountHookTypesDev();
19285 checkDepsAreArrayDev(deps);
19286 return mountImperativeHandle(ref, create, deps);
19287 },
19288 useInsertionEffect: function (create, deps) {
19289 currentHookNameInDev = 'useInsertionEffect';
19290 mountHookTypesDev();
19291 checkDepsAreArrayDev(deps);
19292 return mountInsertionEffect(create, deps);
19293 },
19294 useLayoutEffect: function (create, deps) {
19295 currentHookNameInDev = 'useLayoutEffect';
19296 mountHookTypesDev();
19297 checkDepsAreArrayDev(deps);
19298 return mountLayoutEffect(create, deps);
19299 },
19300 useMemo: function (create, deps) {
19301 currentHookNameInDev = 'useMemo';
19302 mountHookTypesDev();
19303 checkDepsAreArrayDev(deps);
19304 var prevDispatcher = ReactSharedInternals.H;
19305 ReactSharedInternals.H = InvalidNestedHooksDispatcherOnMountInDEV;
19306
19307 try {
19308 return mountMemo(create, deps);
19309 } finally {
19310 ReactSharedInternals.H = prevDispatcher;
19311 }
19312 },
19313 useReducer: function (reducer, initialArg, init) {
19314 currentHookNameInDev = 'useReducer';
19315 mountHookTypesDev();
19316 var prevDispatcher = ReactSharedInternals.H;
19317 ReactSharedInternals.H = InvalidNestedHooksDispatcherOnMountInDEV;
19318
19319 try {
19320 return mountReducer(reducer, initialArg, init);
19321 } finally {
19322 ReactSharedInternals.H = prevDispatcher;
19323 }
19324 },
19325 useRef: function (initialValue) {
19326 currentHookNameInDev = 'useRef';
19327 mountHookTypesDev();
19328 return mountRef(initialValue);
19329 },
19330 useState: function (initialState) {
19331 currentHookNameInDev = 'useState';
19332 mountHookTypesDev();
19333 var prevDispatcher = ReactSharedInternals.H;
19334 ReactSharedInternals.H = InvalidNestedHooksDispatcherOnMountInDEV;
19335
19336 try {
19337 return mountState(initialState);
19338 } finally {
19339 ReactSharedInternals.H = prevDispatcher;
19340 }
19341 },
19342 useDebugValue: function (value, formatterFn) {
19343 currentHookNameInDev = 'useDebugValue';
19344 mountHookTypesDev();
19345 return mountDebugValue();
19346 },
19347 useDeferredValue: function (value, initialValue) {
19348 currentHookNameInDev = 'useDeferredValue';
19349 mountHookTypesDev();
19350 return mountDeferredValue(value, initialValue);
19351 },
19352 useTransition: function () {
19353 currentHookNameInDev = 'useTransition';
19354 mountHookTypesDev();
19355 return mountTransition();
19356 },
19357 useSyncExternalStore: function (subscribe, getSnapshot, getServerSnapshot) {
19358 currentHookNameInDev = 'useSyncExternalStore';
19359 mountHookTypesDev();
19360 return mountSyncExternalStore(subscribe, getSnapshot, getServerSnapshot);
19361 },
19362 useId: function () {
19363 currentHookNameInDev = 'useId';
19364 mountHookTypesDev();
19365 return mountId();
19366 }
19367 };
19368
19369 {
19370 HooksDispatcherOnMountInDEV.useCacheRefresh = function useCacheRefresh() {
19371 currentHookNameInDev = 'useCacheRefresh';
19372 mountHookTypesDev();
19373 return mountRefresh();
19374 };
19375 }
19376
19377 {
19378 HooksDispatcherOnMountInDEV.useHostTransitionStatus = useHostTransitionStatus;
19379
19380 HooksDispatcherOnMountInDEV.useFormState = function useFormState(action, initialState, permalink) {
19381 currentHookNameInDev = 'useFormState';
19382 mountHookTypesDev();
19383 return mountActionState(action, initialState);
19384 };
19385
19386 HooksDispatcherOnMountInDEV.useActionState = function useActionState(action, initialState, permalink) {
19387 currentHookNameInDev = 'useActionState';
19388 mountHookTypesDev();
19389 return mountActionState(action, initialState);
19390 };
19391 }
19392
19393 {
19394 HooksDispatcherOnMountInDEV.useOptimistic = function useOptimistic(passthrough, reducer) {
19395 currentHookNameInDev = 'useOptimistic';
19396 mountHookTypesDev();
19397 return mountOptimistic(passthrough);
19398 };
19399 }
19400
19401 HooksDispatcherOnMountWithHookTypesInDEV = {
19402 readContext: function (context) {
19403 return readContext(context);
19404 },
19405 use: use,
19406 useCallback: function (callback, deps) {
19407 currentHookNameInDev = 'useCallback';
19408 updateHookTypesDev();
19409 return mountCallback(callback, deps);
19410 },
19411 useContext: function (context) {
19412 currentHookNameInDev = 'useContext';
19413 updateHookTypesDev();
19414 return readContext(context);
19415 },
19416 useEffect: function (create, deps) {
19417 currentHookNameInDev = 'useEffect';
19418 updateHookTypesDev();
19419 return mountEffect(create, deps);
19420 },
19421 useImperativeHandle: function (ref, create, deps) {
19422 currentHookNameInDev = 'useImperativeHandle';
19423 updateHookTypesDev();
19424 return mountImperativeHandle(ref, create, deps);
19425 },
19426 useInsertionEffect: function (create, deps) {
19427 currentHookNameInDev = 'useInsertionEffect';
19428 updateHookTypesDev();
19429 return mountInsertionEffect(create, deps);
19430 },
19431 useLayoutEffect: function (create, deps) {
19432 currentHookNameInDev = 'useLayoutEffect';
19433 updateHookTypesDev();
19434 return mountLayoutEffect(create, deps);
19435 },
19436 useMemo: function (create, deps) {
19437 currentHookNameInDev = 'useMemo';
19438 updateHookTypesDev();
19439 var prevDispatcher = ReactSharedInternals.H;
19440 ReactSharedInternals.H = InvalidNestedHooksDispatcherOnMountInDEV;
19441
19442 try {
19443 return mountMemo(create, deps);
19444 } finally {
19445 ReactSharedInternals.H = prevDispatcher;
19446 }
19447 },
19448 useReducer: function (reducer, initialArg, init) {
19449 currentHookNameInDev = 'useReducer';
19450 updateHookTypesDev();
19451 var prevDispatcher = ReactSharedInternals.H;
19452 ReactSharedInternals.H = InvalidNestedHooksDispatcherOnMountInDEV;
19453
19454 try {
19455 return mountReducer(reducer, initialArg, init);
19456 } finally {
19457 ReactSharedInternals.H = prevDispatcher;
19458 }
19459 },
19460 useRef: function (initialValue) {
19461 currentHookNameInDev = 'useRef';
19462 updateHookTypesDev();
19463 return mountRef(initialValue);
19464 },
19465 useState: function (initialState) {
19466 currentHookNameInDev = 'useState';
19467 updateHookTypesDev();
19468 var prevDispatcher = ReactSharedInternals.H;
19469 ReactSharedInternals.H = InvalidNestedHooksDispatcherOnMountInDEV;
19470
19471 try {
19472 return mountState(initialState);
19473 } finally {
19474 ReactSharedInternals.H = prevDispatcher;
19475 }
19476 },
19477 useDebugValue: function (value, formatterFn) {
19478 currentHookNameInDev = 'useDebugValue';
19479 updateHookTypesDev();
19480 return mountDebugValue();
19481 },
19482 useDeferredValue: function (value, initialValue) {
19483 currentHookNameInDev = 'useDeferredValue';
19484 updateHookTypesDev();
19485 return mountDeferredValue(value, initialValue);
19486 },
19487 useTransition: function () {
19488 currentHookNameInDev = 'useTransition';
19489 updateHookTypesDev();
19490 return mountTransition();
19491 },
19492 useSyncExternalStore: function (subscribe, getSnapshot, getServerSnapshot) {
19493 currentHookNameInDev = 'useSyncExternalStore';
19494 updateHookTypesDev();
19495 return mountSyncExternalStore(subscribe, getSnapshot, getServerSnapshot);
19496 },
19497 useId: function () {
19498 currentHookNameInDev = 'useId';
19499 updateHookTypesDev();
19500 return mountId();
19501 }
19502 };
19503
19504 {
19505 HooksDispatcherOnMountWithHookTypesInDEV.useCacheRefresh = function useCacheRefresh() {
19506 currentHookNameInDev = 'useCacheRefresh';
19507 updateHookTypesDev();
19508 return mountRefresh();
19509 };
19510 }
19511
19512 {
19513 HooksDispatcherOnMountWithHookTypesInDEV.useHostTransitionStatus = useHostTransitionStatus;
19514
19515 HooksDispatcherOnMountWithHookTypesInDEV.useFormState = function useFormState(action, initialState, permalink) {
19516 currentHookNameInDev = 'useFormState';
19517 updateHookTypesDev();
19518 warnOnUseFormStateInDev();
19519 return mountActionState(action, initialState);
19520 };
19521
19522 HooksDispatcherOnMountWithHookTypesInDEV.useActionState = function useActionState(action, initialState, permalink) {
19523 currentHookNameInDev = 'useActionState';
19524 updateHookTypesDev();
19525 return mountActionState(action, initialState);
19526 };
19527 }
19528
19529 {
19530 HooksDispatcherOnMountWithHookTypesInDEV.useOptimistic = function useOptimistic(passthrough, reducer) {
19531 currentHookNameInDev = 'useOptimistic';
19532 updateHookTypesDev();
19533 return mountOptimistic(passthrough);
19534 };
19535 }
19536
19537 HooksDispatcherOnUpdateInDEV = {
19538 readContext: function (context) {
19539 return readContext(context);
19540 },
19541 use: use,
19542 useCallback: function (callback, deps) {
19543 currentHookNameInDev = 'useCallback';
19544 updateHookTypesDev();
19545 return updateCallback(callback, deps);
19546 },
19547 useContext: function (context) {
19548 currentHookNameInDev = 'useContext';
19549 updateHookTypesDev();
19550 return readContext(context);
19551 },
19552 useEffect: function (create, deps) {
19553 currentHookNameInDev = 'useEffect';
19554 updateHookTypesDev();
19555 return updateEffect(create, deps);
19556 },
19557 useImperativeHandle: function (ref, create, deps) {
19558 currentHookNameInDev = 'useImperativeHandle';
19559 updateHookTypesDev();
19560 return updateImperativeHandle(ref, create, deps);
19561 },
19562 useInsertionEffect: function (create, deps) {
19563 currentHookNameInDev = 'useInsertionEffect';
19564 updateHookTypesDev();
19565 return updateInsertionEffect(create, deps);
19566 },
19567 useLayoutEffect: function (create, deps) {
19568 currentHookNameInDev = 'useLayoutEffect';
19569 updateHookTypesDev();
19570 return updateLayoutEffect(create, deps);
19571 },
19572 useMemo: function (create, deps) {
19573 currentHookNameInDev = 'useMemo';
19574 updateHookTypesDev();
19575 var prevDispatcher = ReactSharedInternals.H;
19576 ReactSharedInternals.H = InvalidNestedHooksDispatcherOnUpdateInDEV;
19577
19578 try {
19579 return updateMemo(create, deps);
19580 } finally {
19581 ReactSharedInternals.H = prevDispatcher;
19582 }
19583 },
19584 useReducer: function (reducer, initialArg, init) {
19585 currentHookNameInDev = 'useReducer';
19586 updateHookTypesDev();
19587 var prevDispatcher = ReactSharedInternals.H;
19588 ReactSharedInternals.H = InvalidNestedHooksDispatcherOnUpdateInDEV;
19589
19590 try {
19591 return updateReducer(reducer, initialArg, init);
19592 } finally {
19593 ReactSharedInternals.H = prevDispatcher;
19594 }
19595 },
19596 useRef: function (initialValue) {
19597 currentHookNameInDev = 'useRef';
19598 updateHookTypesDev();
19599 return updateRef();
19600 },
19601 useState: function (initialState) {
19602 currentHookNameInDev = 'useState';
19603 updateHookTypesDev();
19604 var prevDispatcher = ReactSharedInternals.H;
19605 ReactSharedInternals.H = InvalidNestedHooksDispatcherOnUpdateInDEV;
19606
19607 try {
19608 return updateState(initialState);
19609 } finally {
19610 ReactSharedInternals.H = prevDispatcher;
19611 }
19612 },
19613 useDebugValue: function (value, formatterFn) {
19614 currentHookNameInDev = 'useDebugValue';
19615 updateHookTypesDev();
19616 return updateDebugValue();
19617 },
19618 useDeferredValue: function (value, initialValue) {
19619 currentHookNameInDev = 'useDeferredValue';
19620 updateHookTypesDev();
19621 return updateDeferredValue(value, initialValue);
19622 },
19623 useTransition: function () {
19624 currentHookNameInDev = 'useTransition';
19625 updateHookTypesDev();
19626 return updateTransition();
19627 },
19628 useSyncExternalStore: function (subscribe, getSnapshot, getServerSnapshot) {
19629 currentHookNameInDev = 'useSyncExternalStore';
19630 updateHookTypesDev();
19631 return updateSyncExternalStore(subscribe, getSnapshot, getServerSnapshot);
19632 },
19633 useId: function () {
19634 currentHookNameInDev = 'useId';
19635 updateHookTypesDev();
19636 return updateId();
19637 }
19638 };
19639
19640 {
19641 HooksDispatcherOnUpdateInDEV.useCacheRefresh = function useCacheRefresh() {
19642 currentHookNameInDev = 'useCacheRefresh';
19643 updateHookTypesDev();
19644 return updateRefresh();
19645 };
19646 }
19647
19648 {
19649 HooksDispatcherOnUpdateInDEV.useHostTransitionStatus = useHostTransitionStatus;
19650
19651 HooksDispatcherOnUpdateInDEV.useFormState = function useFormState(action, initialState, permalink) {
19652 currentHookNameInDev = 'useFormState';
19653 updateHookTypesDev();
19654 warnOnUseFormStateInDev();
19655 return updateActionState(action);
19656 };
19657
19658 HooksDispatcherOnUpdateInDEV.useActionState = function useActionState(action, initialState, permalink) {
19659 currentHookNameInDev = 'useActionState';
19660 updateHookTypesDev();
19661 return updateActionState(action);
19662 };
19663 }
19664
19665 {
19666 HooksDispatcherOnUpdateInDEV.useOptimistic = function useOptimistic(passthrough, reducer) {
19667 currentHookNameInDev = 'useOptimistic';
19668 updateHookTypesDev();
19669 return updateOptimistic(passthrough, reducer);
19670 };
19671 }
19672
19673 HooksDispatcherOnRerenderInDEV = {
19674 readContext: function (context) {
19675 return readContext(context);
19676 },
19677 use: use,
19678 useCallback: function (callback, deps) {
19679 currentHookNameInDev = 'useCallback';
19680 updateHookTypesDev();
19681 return updateCallback(callback, deps);
19682 },
19683 useContext: function (context) {
19684 currentHookNameInDev = 'useContext';
19685 updateHookTypesDev();
19686 return readContext(context);
19687 },
19688 useEffect: function (create, deps) {
19689 currentHookNameInDev = 'useEffect';
19690 updateHookTypesDev();
19691 return updateEffect(create, deps);
19692 },
19693 useImperativeHandle: function (ref, create, deps) {
19694 currentHookNameInDev = 'useImperativeHandle';
19695 updateHookTypesDev();
19696 return updateImperativeHandle(ref, create, deps);
19697 },
19698 useInsertionEffect: function (create, deps) {
19699 currentHookNameInDev = 'useInsertionEffect';
19700 updateHookTypesDev();
19701 return updateInsertionEffect(create, deps);
19702 },
19703 useLayoutEffect: function (create, deps) {
19704 currentHookNameInDev = 'useLayoutEffect';
19705 updateHookTypesDev();
19706 return updateLayoutEffect(create, deps);
19707 },
19708 useMemo: function (create, deps) {
19709 currentHookNameInDev = 'useMemo';
19710 updateHookTypesDev();
19711 var prevDispatcher = ReactSharedInternals.H;
19712 ReactSharedInternals.H = InvalidNestedHooksDispatcherOnRerenderInDEV;
19713
19714 try {
19715 return updateMemo(create, deps);
19716 } finally {
19717 ReactSharedInternals.H = prevDispatcher;
19718 }
19719 },
19720 useReducer: function (reducer, initialArg, init) {
19721 currentHookNameInDev = 'useReducer';
19722 updateHookTypesDev();
19723 var prevDispatcher = ReactSharedInternals.H;
19724 ReactSharedInternals.H = InvalidNestedHooksDispatcherOnRerenderInDEV;
19725
19726 try {
19727 return rerenderReducer(reducer, initialArg, init);
19728 } finally {
19729 ReactSharedInternals.H = prevDispatcher;
19730 }
19731 },
19732 useRef: function (initialValue) {
19733 currentHookNameInDev = 'useRef';
19734 updateHookTypesDev();
19735 return updateRef();
19736 },
19737 useState: function (initialState) {
19738 currentHookNameInDev = 'useState';
19739 updateHookTypesDev();
19740 var prevDispatcher = ReactSharedInternals.H;
19741 ReactSharedInternals.H = InvalidNestedHooksDispatcherOnRerenderInDEV;
19742
19743 try {
19744 return rerenderState(initialState);
19745 } finally {
19746 ReactSharedInternals.H = prevDispatcher;
19747 }
19748 },
19749 useDebugValue: function (value, formatterFn) {
19750 currentHookNameInDev = 'useDebugValue';
19751 updateHookTypesDev();
19752 return updateDebugValue();
19753 },
19754 useDeferredValue: function (value, initialValue) {
19755 currentHookNameInDev = 'useDeferredValue';
19756 updateHookTypesDev();
19757 return rerenderDeferredValue(value, initialValue);
19758 },
19759 useTransition: function () {
19760 currentHookNameInDev = 'useTransition';
19761 updateHookTypesDev();
19762 return rerenderTransition();
19763 },
19764 useSyncExternalStore: function (subscribe, getSnapshot, getServerSnapshot) {
19765 currentHookNameInDev = 'useSyncExternalStore';
19766 updateHookTypesDev();
19767 return updateSyncExternalStore(subscribe, getSnapshot, getServerSnapshot);
19768 },
19769 useId: function () {
19770 currentHookNameInDev = 'useId';
19771 updateHookTypesDev();
19772 return updateId();
19773 }
19774 };
19775
19776 {
19777 HooksDispatcherOnRerenderInDEV.useCacheRefresh = function useCacheRefresh() {
19778 currentHookNameInDev = 'useCacheRefresh';
19779 updateHookTypesDev();
19780 return updateRefresh();
19781 };
19782 }
19783
19784 {
19785 HooksDispatcherOnRerenderInDEV.useHostTransitionStatus = useHostTransitionStatus;
19786
19787 HooksDispatcherOnRerenderInDEV.useFormState = function useFormState(action, initialState, permalink) {
19788 currentHookNameInDev = 'useFormState';
19789 updateHookTypesDev();
19790 warnOnUseFormStateInDev();
19791 return rerenderActionState(action);
19792 };
19793
19794 HooksDispatcherOnRerenderInDEV.useActionState = function useActionState(action, initialState, permalink) {
19795 currentHookNameInDev = 'useActionState';
19796 updateHookTypesDev();
19797 return rerenderActionState(action);
19798 };
19799 }
19800
19801 {
19802 HooksDispatcherOnRerenderInDEV.useOptimistic = function useOptimistic(passthrough, reducer) {
19803 currentHookNameInDev = 'useOptimistic';
19804 updateHookTypesDev();
19805 return rerenderOptimistic(passthrough, reducer);
19806 };
19807 }
19808
19809 InvalidNestedHooksDispatcherOnMountInDEV = {
19810 readContext: function (context) {
19811 warnInvalidContextAccess();
19812 return readContext(context);
19813 },
19814 use: function (usable) {
19815 warnInvalidHookAccess();
19816 return use(usable);
19817 },
19818 useCallback: function (callback, deps) {
19819 currentHookNameInDev = 'useCallback';
19820 warnInvalidHookAccess();
19821 mountHookTypesDev();
19822 return mountCallback(callback, deps);
19823 },
19824 useContext: function (context) {
19825 currentHookNameInDev = 'useContext';
19826 warnInvalidHookAccess();
19827 mountHookTypesDev();
19828 return readContext(context);
19829 },
19830 useEffect: function (create, deps) {
19831 currentHookNameInDev = 'useEffect';
19832 warnInvalidHookAccess();
19833 mountHookTypesDev();
19834 return mountEffect(create, deps);
19835 },
19836 useImperativeHandle: function (ref, create, deps) {
19837 currentHookNameInDev = 'useImperativeHandle';
19838 warnInvalidHookAccess();
19839 mountHookTypesDev();
19840 return mountImperativeHandle(ref, create, deps);
19841 },
19842 useInsertionEffect: function (create, deps) {
19843 currentHookNameInDev = 'useInsertionEffect';
19844 warnInvalidHookAccess();
19845 mountHookTypesDev();
19846 return mountInsertionEffect(create, deps);
19847 },
19848 useLayoutEffect: function (create, deps) {
19849 currentHookNameInDev = 'useLayoutEffect';
19850 warnInvalidHookAccess();
19851 mountHookTypesDev();
19852 return mountLayoutEffect(create, deps);
19853 },
19854 useMemo: function (create, deps) {
19855 currentHookNameInDev = 'useMemo';
19856 warnInvalidHookAccess();
19857 mountHookTypesDev();
19858 var prevDispatcher = ReactSharedInternals.H;
19859 ReactSharedInternals.H = InvalidNestedHooksDispatcherOnMountInDEV;
19860
19861 try {
19862 return mountMemo(create, deps);
19863 } finally {
19864 ReactSharedInternals.H = prevDispatcher;
19865 }
19866 },
19867 useReducer: function (reducer, initialArg, init) {
19868 currentHookNameInDev = 'useReducer';
19869 warnInvalidHookAccess();
19870 mountHookTypesDev();
19871 var prevDispatcher = ReactSharedInternals.H;
19872 ReactSharedInternals.H = InvalidNestedHooksDispatcherOnMountInDEV;
19873
19874 try {
19875 return mountReducer(reducer, initialArg, init);
19876 } finally {
19877 ReactSharedInternals.H = prevDispatcher;
19878 }
19879 },
19880 useRef: function (initialValue) {
19881 currentHookNameInDev = 'useRef';
19882 warnInvalidHookAccess();
19883 mountHookTypesDev();
19884 return mountRef(initialValue);
19885 },
19886 useState: function (initialState) {
19887 currentHookNameInDev = 'useState';
19888 warnInvalidHookAccess();
19889 mountHookTypesDev();
19890 var prevDispatcher = ReactSharedInternals.H;
19891 ReactSharedInternals.H = InvalidNestedHooksDispatcherOnMountInDEV;
19892
19893 try {
19894 return mountState(initialState);
19895 } finally {
19896 ReactSharedInternals.H = prevDispatcher;
19897 }
19898 },
19899 useDebugValue: function (value, formatterFn) {
19900 currentHookNameInDev = 'useDebugValue';
19901 warnInvalidHookAccess();
19902 mountHookTypesDev();
19903 return mountDebugValue();
19904 },
19905 useDeferredValue: function (value, initialValue) {
19906 currentHookNameInDev = 'useDeferredValue';
19907 warnInvalidHookAccess();
19908 mountHookTypesDev();
19909 return mountDeferredValue(value, initialValue);
19910 },
19911 useTransition: function () {
19912 currentHookNameInDev = 'useTransition';
19913 warnInvalidHookAccess();
19914 mountHookTypesDev();
19915 return mountTransition();
19916 },
19917 useSyncExternalStore: function (subscribe, getSnapshot, getServerSnapshot) {
19918 currentHookNameInDev = 'useSyncExternalStore';
19919 warnInvalidHookAccess();
19920 mountHookTypesDev();
19921 return mountSyncExternalStore(subscribe, getSnapshot, getServerSnapshot);
19922 },
19923 useId: function () {
19924 currentHookNameInDev = 'useId';
19925 warnInvalidHookAccess();
19926 mountHookTypesDev();
19927 return mountId();
19928 }
19929 };
19930
19931 {
19932 InvalidNestedHooksDispatcherOnMountInDEV.useCacheRefresh = function useCacheRefresh() {
19933 currentHookNameInDev = 'useCacheRefresh';
19934 mountHookTypesDev();
19935 return mountRefresh();
19936 };
19937 }
19938
19939 {
19940 InvalidNestedHooksDispatcherOnMountInDEV.useHostTransitionStatus = useHostTransitionStatus;
19941
19942 InvalidNestedHooksDispatcherOnMountInDEV.useFormState = function useFormState(action, initialState, permalink) {
19943 currentHookNameInDev = 'useFormState';
19944 warnInvalidHookAccess();
19945 mountHookTypesDev();
19946 return mountActionState(action, initialState);
19947 };
19948
19949 InvalidNestedHooksDispatcherOnMountInDEV.useActionState = function useActionState(action, initialState, permalink) {
19950 currentHookNameInDev = 'useActionState';
19951 warnInvalidHookAccess();
19952 mountHookTypesDev();
19953 return mountActionState(action, initialState);
19954 };
19955 }
19956
19957 {
19958 InvalidNestedHooksDispatcherOnMountInDEV.useOptimistic = function useOptimistic(passthrough, reducer) {
19959 currentHookNameInDev = 'useOptimistic';
19960 warnInvalidHookAccess();
19961 mountHookTypesDev();
19962 return mountOptimistic(passthrough);
19963 };
19964 }
19965
19966 InvalidNestedHooksDispatcherOnUpdateInDEV = {
19967 readContext: function (context) {
19968 warnInvalidContextAccess();
19969 return readContext(context);
19970 },
19971 use: function (usable) {
19972 warnInvalidHookAccess();
19973 return use(usable);
19974 },
19975 useCallback: function (callback, deps) {
19976 currentHookNameInDev = 'useCallback';
19977 warnInvalidHookAccess();
19978 updateHookTypesDev();
19979 return updateCallback(callback, deps);
19980 },
19981 useContext: function (context) {
19982 currentHookNameInDev = 'useContext';
19983 warnInvalidHookAccess();
19984 updateHookTypesDev();
19985 return readContext(context);
19986 },
19987 useEffect: function (create, deps) {
19988 currentHookNameInDev = 'useEffect';
19989 warnInvalidHookAccess();
19990 updateHookTypesDev();
19991 return updateEffect(create, deps);
19992 },
19993 useImperativeHandle: function (ref, create, deps) {
19994 currentHookNameInDev = 'useImperativeHandle';
19995 warnInvalidHookAccess();
19996 updateHookTypesDev();
19997 return updateImperativeHandle(ref, create, deps);
19998 },
19999 useInsertionEffect: function (create, deps) {
20000 currentHookNameInDev = 'useInsertionEffect';
20001 warnInvalidHookAccess();
20002 updateHookTypesDev();
20003 return updateInsertionEffect(create, deps);
20004 },
20005 useLayoutEffect: function (create, deps) {
20006 currentHookNameInDev = 'useLayoutEffect';
20007 warnInvalidHookAccess();
20008 updateHookTypesDev();
20009 return updateLayoutEffect(create, deps);
20010 },
20011 useMemo: function (create, deps) {
20012 currentHookNameInDev = 'useMemo';
20013 warnInvalidHookAccess();
20014 updateHookTypesDev();
20015 var prevDispatcher = ReactSharedInternals.H;
20016 ReactSharedInternals.H = InvalidNestedHooksDispatcherOnUpdateInDEV;
20017
20018 try {
20019 return updateMemo(create, deps);
20020 } finally {
20021 ReactSharedInternals.H = prevDispatcher;
20022 }
20023 },
20024 useReducer: function (reducer, initialArg, init) {
20025 currentHookNameInDev = 'useReducer';
20026 warnInvalidHookAccess();
20027 updateHookTypesDev();
20028 var prevDispatcher = ReactSharedInternals.H;
20029 ReactSharedInternals.H = InvalidNestedHooksDispatcherOnUpdateInDEV;
20030
20031 try {
20032 return updateReducer(reducer, initialArg, init);
20033 } finally {
20034 ReactSharedInternals.H = prevDispatcher;
20035 }
20036 },
20037 useRef: function (initialValue) {
20038 currentHookNameInDev = 'useRef';
20039 warnInvalidHookAccess();
20040 updateHookTypesDev();
20041 return updateRef();
20042 },
20043 useState: function (initialState) {
20044 currentHookNameInDev = 'useState';
20045 warnInvalidHookAccess();
20046 updateHookTypesDev();
20047 var prevDispatcher = ReactSharedInternals.H;
20048 ReactSharedInternals.H = InvalidNestedHooksDispatcherOnUpdateInDEV;
20049
20050 try {
20051 return updateState(initialState);
20052 } finally {
20053 ReactSharedInternals.H = prevDispatcher;
20054 }
20055 },
20056 useDebugValue: function (value, formatterFn) {
20057 currentHookNameInDev = 'useDebugValue';
20058 warnInvalidHookAccess();
20059 updateHookTypesDev();
20060 return updateDebugValue();
20061 },
20062 useDeferredValue: function (value, initialValue) {
20063 currentHookNameInDev = 'useDeferredValue';
20064 warnInvalidHookAccess();
20065 updateHookTypesDev();
20066 return updateDeferredValue(value, initialValue);
20067 },
20068 useTransition: function () {
20069 currentHookNameInDev = 'useTransition';
20070 warnInvalidHookAccess();
20071 updateHookTypesDev();
20072 return updateTransition();
20073 },
20074 useSyncExternalStore: function (subscribe, getSnapshot, getServerSnapshot) {
20075 currentHookNameInDev = 'useSyncExternalStore';
20076 warnInvalidHookAccess();
20077 updateHookTypesDev();
20078 return updateSyncExternalStore(subscribe, getSnapshot, getServerSnapshot);
20079 },
20080 useId: function () {
20081 currentHookNameInDev = 'useId';
20082 warnInvalidHookAccess();
20083 updateHookTypesDev();
20084 return updateId();
20085 }
20086 };
20087
20088 {
20089 InvalidNestedHooksDispatcherOnUpdateInDEV.useCacheRefresh = function useCacheRefresh() {
20090 currentHookNameInDev = 'useCacheRefresh';
20091 updateHookTypesDev();
20092 return updateRefresh();
20093 };
20094 }
20095
20096 {
20097 InvalidNestedHooksDispatcherOnUpdateInDEV.useHostTransitionStatus = useHostTransitionStatus;
20098
20099 InvalidNestedHooksDispatcherOnUpdateInDEV.useFormState = function useFormState(action, initialState, permalink) {
20100 currentHookNameInDev = 'useFormState';
20101 warnInvalidHookAccess();
20102 updateHookTypesDev();
20103 return updateActionState(action);
20104 };
20105
20106 InvalidNestedHooksDispatcherOnUpdateInDEV.useActionState = function useActionState(action, initialState, permalink) {
20107 currentHookNameInDev = 'useActionState';
20108 warnInvalidHookAccess();
20109 updateHookTypesDev();
20110 return updateActionState(action);
20111 };
20112 }
20113
20114 {
20115 InvalidNestedHooksDispatcherOnUpdateInDEV.useOptimistic = function useOptimistic(passthrough, reducer) {
20116 currentHookNameInDev = 'useOptimistic';
20117 warnInvalidHookAccess();
20118 updateHookTypesDev();
20119 return updateOptimistic(passthrough, reducer);
20120 };
20121 }
20122
20123 InvalidNestedHooksDispatcherOnRerenderInDEV = {
20124 readContext: function (context) {
20125 warnInvalidContextAccess();
20126 return readContext(context);
20127 },
20128 use: function (usable) {
20129 warnInvalidHookAccess();
20130 return use(usable);
20131 },
20132 useCallback: function (callback, deps) {
20133 currentHookNameInDev = 'useCallback';
20134 warnInvalidHookAccess();
20135 updateHookTypesDev();
20136 return updateCallback(callback, deps);
20137 },
20138 useContext: function (context) {
20139 currentHookNameInDev = 'useContext';
20140 warnInvalidHookAccess();
20141 updateHookTypesDev();
20142 return readContext(context);
20143 },
20144 useEffect: function (create, deps) {
20145 currentHookNameInDev = 'useEffect';
20146 warnInvalidHookAccess();
20147 updateHookTypesDev();
20148 return updateEffect(create, deps);
20149 },
20150 useImperativeHandle: function (ref, create, deps) {
20151 currentHookNameInDev = 'useImperativeHandle';
20152 warnInvalidHookAccess();
20153 updateHookTypesDev();
20154 return updateImperativeHandle(ref, create, deps);
20155 },
20156 useInsertionEffect: function (create, deps) {
20157 currentHookNameInDev = 'useInsertionEffect';
20158 warnInvalidHookAccess();
20159 updateHookTypesDev();
20160 return updateInsertionEffect(create, deps);
20161 },
20162 useLayoutEffect: function (create, deps) {
20163 currentHookNameInDev = 'useLayoutEffect';
20164 warnInvalidHookAccess();
20165 updateHookTypesDev();
20166 return updateLayoutEffect(create, deps);
20167 },
20168 useMemo: function (create, deps) {
20169 currentHookNameInDev = 'useMemo';
20170 warnInvalidHookAccess();
20171 updateHookTypesDev();
20172 var prevDispatcher = ReactSharedInternals.H;
20173 ReactSharedInternals.H = InvalidNestedHooksDispatcherOnUpdateInDEV;
20174
20175 try {
20176 return updateMemo(create, deps);
20177 } finally {
20178 ReactSharedInternals.H = prevDispatcher;
20179 }
20180 },
20181 useReducer: function (reducer, initialArg, init) {
20182 currentHookNameInDev = 'useReducer';
20183 warnInvalidHookAccess();
20184 updateHookTypesDev();
20185 var prevDispatcher = ReactSharedInternals.H;
20186 ReactSharedInternals.H = InvalidNestedHooksDispatcherOnUpdateInDEV;
20187
20188 try {
20189 return rerenderReducer(reducer, initialArg, init);
20190 } finally {
20191 ReactSharedInternals.H = prevDispatcher;
20192 }
20193 },
20194 useRef: function (initialValue) {
20195 currentHookNameInDev = 'useRef';
20196 warnInvalidHookAccess();
20197 updateHookTypesDev();
20198 return updateRef();
20199 },
20200 useState: function (initialState) {
20201 currentHookNameInDev = 'useState';
20202 warnInvalidHookAccess();
20203 updateHookTypesDev();
20204 var prevDispatcher = ReactSharedInternals.H;
20205 ReactSharedInternals.H = InvalidNestedHooksDispatcherOnUpdateInDEV;
20206
20207 try {
20208 return rerenderState(initialState);
20209 } finally {
20210 ReactSharedInternals.H = prevDispatcher;
20211 }
20212 },
20213 useDebugValue: function (value, formatterFn) {
20214 currentHookNameInDev = 'useDebugValue';
20215 warnInvalidHookAccess();
20216 updateHookTypesDev();
20217 return updateDebugValue();
20218 },
20219 useDeferredValue: function (value, initialValue) {
20220 currentHookNameInDev = 'useDeferredValue';
20221 warnInvalidHookAccess();
20222 updateHookTypesDev();
20223 return rerenderDeferredValue(value, initialValue);
20224 },
20225 useTransition: function () {
20226 currentHookNameInDev = 'useTransition';
20227 warnInvalidHookAccess();
20228 updateHookTypesDev();
20229 return rerenderTransition();
20230 },
20231 useSyncExternalStore: function (subscribe, getSnapshot, getServerSnapshot) {
20232 currentHookNameInDev = 'useSyncExternalStore';
20233 warnInvalidHookAccess();
20234 updateHookTypesDev();
20235 return updateSyncExternalStore(subscribe, getSnapshot, getServerSnapshot);
20236 },
20237 useId: function () {
20238 currentHookNameInDev = 'useId';
20239 warnInvalidHookAccess();
20240 updateHookTypesDev();
20241 return updateId();
20242 }
20243 };
20244
20245 {
20246 InvalidNestedHooksDispatcherOnRerenderInDEV.useCacheRefresh = function useCacheRefresh() {
20247 currentHookNameInDev = 'useCacheRefresh';
20248 updateHookTypesDev();
20249 return updateRefresh();
20250 };
20251 }
20252
20253 {
20254 InvalidNestedHooksDispatcherOnRerenderInDEV.useHostTransitionStatus = useHostTransitionStatus;
20255
20256 InvalidNestedHooksDispatcherOnRerenderInDEV.useFormState = function useFormState(action, initialState, permalink) {
20257 currentHookNameInDev = 'useFormState';
20258 warnInvalidHookAccess();
20259 updateHookTypesDev();
20260 return rerenderActionState(action);
20261 };
20262
20263 InvalidNestedHooksDispatcherOnRerenderInDEV.useActionState = function useActionState(action, initialState, permalink) {
20264 currentHookNameInDev = 'useActionState';
20265 warnInvalidHookAccess();
20266 updateHookTypesDev();
20267 return rerenderActionState(action);
20268 };
20269 }
20270
20271 {
20272 InvalidNestedHooksDispatcherOnRerenderInDEV.useOptimistic = function useOptimistic(passthrough, reducer) {
20273 currentHookNameInDev = 'useOptimistic';
20274 warnInvalidHookAccess();
20275 updateHookTypesDev();
20276 return rerenderOptimistic(passthrough, reducer);
20277 };
20278 }
20279}
20280
20281var now = Scheduler.unstable_now;
20282var commitTime = 0;
20283var layoutEffectStartTime = -1;
20284var profilerStartTime = -1;
20285var passiveEffectStartTime = -1;
20286/**
20287 * Tracks whether the current update was a nested/cascading update (scheduled from a layout effect).
20288 *
20289 * The overall sequence is:
20290 * 1. render
20291 * 2. commit (and call `onRender`, `onCommit`)
20292 * 3. check for nested updates
20293 * 4. flush passive effects (and call `onPostCommit`)
20294 *
20295 * Nested updates are identified in step 3 above,
20296 * but step 4 still applies to the work that was just committed.
20297 * We use two flags to track nested updates then:
20298 * one tracks whether the upcoming update is a nested update,
20299 * and the other tracks whether the current update was a nested update.
20300 * The first value gets synced to the second at the start of the render phase.
20301 */
20302
20303var currentUpdateIsNested = false;
20304var nestedUpdateScheduled = false;
20305
20306function isCurrentUpdateNested() {
20307 return currentUpdateIsNested;
20308}
20309
20310function markNestedUpdateScheduled() {
20311 {
20312 nestedUpdateScheduled = true;
20313 }
20314}
20315
20316function resetNestedUpdateFlag() {
20317 {
20318 currentUpdateIsNested = false;
20319 nestedUpdateScheduled = false;
20320 }
20321}
20322
20323function syncNestedUpdateFlag() {
20324 {
20325 currentUpdateIsNested = nestedUpdateScheduled;
20326 nestedUpdateScheduled = false;
20327 }
20328}
20329
20330function getCommitTime() {
20331 return commitTime;
20332}
20333
20334function recordCommitTime() {
20335
20336 commitTime = now();
20337}
20338
20339function startProfilerTimer(fiber) {
20340
20341 profilerStartTime = now();
20342
20343 if (fiber.actualStartTime < 0) {
20344 fiber.actualStartTime = now();
20345 }
20346}
20347
20348function stopProfilerTimerIfRunning(fiber) {
20349
20350 profilerStartTime = -1;
20351}
20352
20353function stopProfilerTimerIfRunningAndRecordDelta(fiber, overrideBaseTime) {
20354
20355 if (profilerStartTime >= 0) {
20356 var elapsedTime = now() - profilerStartTime;
20357 fiber.actualDuration += elapsedTime;
20358
20359 if (overrideBaseTime) {
20360 fiber.selfBaseDuration = elapsedTime;
20361 }
20362
20363 profilerStartTime = -1;
20364 }
20365}
20366
20367function recordLayoutEffectDuration(fiber) {
20368
20369 if (layoutEffectStartTime >= 0) {
20370 var elapsedTime = now() - layoutEffectStartTime;
20371 layoutEffectStartTime = -1; // Store duration on the next nearest Profiler ancestor
20372 // Or the root (for the DevTools Profiler to read)
20373
20374 var parentFiber = fiber.return;
20375
20376 while (parentFiber !== null) {
20377 switch (parentFiber.tag) {
20378 case HostRoot:
20379 var root = parentFiber.stateNode;
20380 root.effectDuration += elapsedTime;
20381 return;
20382
20383 case Profiler:
20384 var parentStateNode = parentFiber.stateNode;
20385 parentStateNode.effectDuration += elapsedTime;
20386 return;
20387 }
20388
20389 parentFiber = parentFiber.return;
20390 }
20391 }
20392}
20393
20394function recordPassiveEffectDuration(fiber) {
20395
20396 if (passiveEffectStartTime >= 0) {
20397 var elapsedTime = now() - passiveEffectStartTime;
20398 passiveEffectStartTime = -1; // Store duration on the next nearest Profiler ancestor
20399 // Or the root (for the DevTools Profiler to read)
20400
20401 var parentFiber = fiber.return;
20402
20403 while (parentFiber !== null) {
20404 switch (parentFiber.tag) {
20405 case HostRoot:
20406 var root = parentFiber.stateNode;
20407
20408 if (root !== null) {
20409 root.passiveEffectDuration += elapsedTime;
20410 }
20411
20412 return;
20413
20414 case Profiler:
20415 var parentStateNode = parentFiber.stateNode;
20416
20417 if (parentStateNode !== null) {
20418 // Detached fibers have their state node cleared out.
20419 // In this case, the return pointer is also cleared out,
20420 // so we won't be able to report the time spent in this Profiler's subtree.
20421 parentStateNode.passiveEffectDuration += elapsedTime;
20422 }
20423
20424 return;
20425 }
20426
20427 parentFiber = parentFiber.return;
20428 }
20429 }
20430}
20431
20432function startLayoutEffectTimer() {
20433
20434 layoutEffectStartTime = now();
20435}
20436
20437function startPassiveEffectTimer() {
20438
20439 passiveEffectStartTime = now();
20440}
20441
20442function transferActualDuration(fiber) {
20443 // Transfer time spent rendering these children so we don't lose it
20444 // after we rerender. This is used as a helper in special cases
20445 // where we should count the work of multiple passes.
20446 var child = fiber.child;
20447
20448 while (child) {
20449 // $FlowFixMe[unsafe-addition] addition with possible null/undefined value
20450 fiber.actualDuration += child.actualDuration;
20451 child = child.sibling;
20452 }
20453}
20454
20455var componentName = null;
20456var errorBoundaryName = null;
20457function defaultOnUncaughtError(error, errorInfo) {
20458 // Overriding this can silence these warnings e.g. for tests.
20459 // See https://github.com/facebook/react/pull/13384
20460 // For uncaught root errors we report them as uncaught to the browser's
20461 // onerror callback. This won't have component stacks and the error addendum.
20462 // So we add those into a separate console.warn.
20463 reportGlobalError(error);
20464
20465 {
20466 var componentStack = errorInfo.componentStack != null ? errorInfo.componentStack : '';
20467 var componentNameMessage = componentName ? "An error occurred in the <" + componentName + "> component:" : 'An error occurred in one of your React components:';
20468 console['warn']('%s\n%s\n\n%s', componentNameMessage, componentStack || '', 'Consider adding an error boundary to your tree to customize error handling behavior.\n' + 'Visit https://react.dev/link/error-boundaries to learn more about error boundaries.');
20469 }
20470}
20471function defaultOnCaughtError(error, errorInfo) {
20472 // Overriding this can silence these warnings e.g. for tests.
20473 // See https://github.com/facebook/react/pull/13384
20474 // Caught by error boundary
20475 {
20476 var componentStack = errorInfo.componentStack != null ? errorInfo.componentStack : '';
20477 var componentNameMessage = componentName ? "The above error occurred in the <" + componentName + "> component:" : 'The above error occurred in one of your React components:'; // In development, we provide our own message which includes the component stack
20478 // in addition to the error.
20479 // Don't transform to our wrapper
20480
20481 console['error']('%o\n\n%s\n%s\n\n%s', error, componentNameMessage, componentStack, "React will try to recreate this component tree from scratch " + ("using the error boundary you provided, " + (errorBoundaryName || 'Anonymous') + "."));
20482 }
20483}
20484function defaultOnRecoverableError(error, errorInfo) {
20485 reportGlobalError(error);
20486}
20487function logUncaughtError(root, errorInfo) {
20488 try {
20489 if (true) {
20490 componentName = errorInfo.source ? getComponentNameFromFiber(errorInfo.source) : null;
20491 errorBoundaryName = null;
20492 }
20493
20494 var error = errorInfo.value;
20495
20496 if (true && ReactSharedInternals.actQueue !== null) {
20497 // For uncaught errors inside act, we track them on the act and then
20498 // rethrow them into the test.
20499 ReactSharedInternals.thrownErrors.push(error);
20500 return;
20501 }
20502
20503 var onUncaughtError = root.onUncaughtError;
20504 onUncaughtError(error, {
20505 componentStack: errorInfo.stack
20506 });
20507 } catch (e) {
20508 // This method must not throw, or React internal state will get messed up.
20509 // If console.error is overridden, or logCapturedError() shows a dialog that throws,
20510 // we want to report this error outside of the normal stack as a last resort.
20511 // https://github.com/facebook/react/issues/13188
20512 setTimeout(function () {
20513 throw e;
20514 });
20515 }
20516}
20517function logCaughtError(root, boundary, errorInfo) {
20518 try {
20519 if (true) {
20520 componentName = errorInfo.source ? getComponentNameFromFiber(errorInfo.source) : null;
20521 errorBoundaryName = getComponentNameFromFiber(boundary);
20522 }
20523
20524 var error = errorInfo.value;
20525 var onCaughtError = root.onCaughtError;
20526 onCaughtError(error, {
20527 componentStack: errorInfo.stack,
20528 errorBoundary: boundary.tag === ClassComponent ? boundary.stateNode // This should always be the case as long as we only have class boundaries
20529 : null
20530 });
20531 } catch (e) {
20532 // This method must not throw, or React internal state will get messed up.
20533 // If console.error is overridden, or logCapturedError() shows a dialog that throws,
20534 // we want to report this error outside of the normal stack as a last resort.
20535 // https://github.com/facebook/react/issues/13188
20536 setTimeout(function () {
20537 throw e;
20538 });
20539 }
20540}
20541
20542function createRootErrorUpdate(root, errorInfo, lane) {
20543 var update = createUpdate(lane); // Unmount the root by rendering null.
20544
20545 update.tag = CaptureUpdate; // Caution: React DevTools currently depends on this property
20546 // being called "element".
20547
20548 update.payload = {
20549 element: null
20550 };
20551
20552 update.callback = function () {
20553 logUncaughtError(root, errorInfo);
20554 };
20555
20556 return update;
20557}
20558
20559function createClassErrorUpdate(lane) {
20560 var update = createUpdate(lane);
20561 update.tag = CaptureUpdate;
20562 return update;
20563}
20564
20565function initializeClassErrorUpdate(update, root, fiber, errorInfo) {
20566 var getDerivedStateFromError = fiber.type.getDerivedStateFromError;
20567
20568 if (typeof getDerivedStateFromError === 'function') {
20569 var error$1 = errorInfo.value;
20570
20571 update.payload = function () {
20572 return getDerivedStateFromError(error$1);
20573 };
20574
20575 update.callback = function () {
20576 {
20577 markFailedErrorBoundaryForHotReloading(fiber);
20578 }
20579
20580 logCaughtError(root, fiber, errorInfo);
20581 };
20582 }
20583
20584 var inst = fiber.stateNode;
20585
20586 if (inst !== null && typeof inst.componentDidCatch === 'function') {
20587 // $FlowFixMe[missing-this-annot]
20588 update.callback = function callback() {
20589 {
20590 markFailedErrorBoundaryForHotReloading(fiber);
20591 }
20592
20593 logCaughtError(root, fiber, errorInfo);
20594
20595 if (typeof getDerivedStateFromError !== 'function') {
20596 // To preserve the preexisting retry behavior of error boundaries,
20597 // we keep track of which ones already failed during this batch.
20598 // This gets reset before we yield back to the browser.
20599 // TODO: Warn in strict mode if getDerivedStateFromError is
20600 // not defined.
20601 markLegacyErrorBoundaryAsFailed(this);
20602 }
20603
20604 var error$1 = errorInfo.value;
20605 var stack = errorInfo.stack;
20606 this.componentDidCatch(error$1, {
20607 componentStack: stack !== null ? stack : ''
20608 });
20609
20610 {
20611 if (typeof getDerivedStateFromError !== 'function') {
20612 // If componentDidCatch is the only error boundary method defined,
20613 // then it needs to call setState to recover from errors.
20614 // If no state update is scheduled then the boundary will swallow the error.
20615 if (!includesSomeLane(fiber.lanes, SyncLane)) {
20616 error('%s: Error boundaries should implement getDerivedStateFromError(). ' + 'In that method, return a state update to display an error message or fallback UI.', getComponentNameFromFiber(fiber) || 'Unknown');
20617 }
20618 }
20619 }
20620 };
20621 }
20622}
20623
20624function markSuspenseBoundaryShouldCapture(suspenseBoundary, returnFiber, sourceFiber, root, rootRenderLanes) {
20625 // with the normal suspend path.
20626 //
20627 // After this we'll use a set of heuristics to determine whether this
20628 // render pass will run to completion or restart or "suspend" the commit.
20629 // The actual logic for this is spread out in different places.
20630 //
20631 // This first principle is that if we're going to suspend when we complete
20632 // a root, then we should also restart if we get an update or ping that
20633 // might unsuspend it, and vice versa. The only reason to suspend is
20634 // because you think you might want to restart before committing. However,
20635 // it doesn't make sense to restart only while in the period we're suspended.
20636 //
20637 // Restarting too aggressively is also not good because it starves out any
20638 // intermediate loading state. So we use heuristics to determine when.
20639 // Suspense Heuristics
20640 //
20641 // If nothing threw a Promise or all the same fallbacks are already showing,
20642 // then don't suspend/restart.
20643 //
20644 // If this is an initial render of a new tree of Suspense boundaries and
20645 // those trigger a fallback, then don't suspend/restart. We want to ensure
20646 // that we can show the initial loading state as quickly as possible.
20647 //
20648 // If we hit a "Delayed" case, such as when we'd switch from content back into
20649 // a fallback, then we should always suspend/restart. Transitions apply
20650 // to this case. If none is defined, JND is used instead.
20651 //
20652 // If we're already showing a fallback and it gets "retried", allowing us to show
20653 // another level, but there's still an inner boundary that would show a fallback,
20654 // then we suspend/restart for 500ms since the last time we showed a fallback
20655 // anywhere in the tree. This effectively throttles progressive loading into a
20656 // consistent train of commits. This also gives us an opportunity to restart to
20657 // get to the completed state slightly earlier.
20658 //
20659 // If there's ambiguity due to batching it's resolved in preference of:
20660 // 1) "delayed", 2) "initial render", 3) "retry".
20661 //
20662 // We want to ensure that a "busy" state doesn't get force committed. We want to
20663 // ensure that new initial loading states can commit as soon as possible.
20664
20665
20666 suspenseBoundary.flags |= ShouldCapture; // TODO: I think we can remove this, since we now use `DidCapture` in
20667 // the begin phase to prevent an early bailout.
20668
20669 suspenseBoundary.lanes = rootRenderLanes;
20670 return suspenseBoundary;
20671}
20672
20673function throwException(root, returnFiber, sourceFiber, value, rootRenderLanes) {
20674 // The source fiber did not complete.
20675 sourceFiber.flags |= Incomplete;
20676
20677 {
20678 if (isDevToolsPresent) {
20679 // If we have pending work still, restore the original updaters
20680 restorePendingUpdaters(root, rootRenderLanes);
20681 }
20682 }
20683
20684 if (value !== null && typeof value === 'object') {
20685
20686 if (typeof value.then === 'function') {
20687 // This is a wakeable. The component suspended.
20688 var wakeable = value;
20689
20690 {
20691 if (getIsHydrating() && (disableLegacyMode )) {
20692 markDidThrowWhileHydratingDEV();
20693 }
20694 }
20695
20696
20697 var suspenseBoundary = getSuspenseHandler();
20698
20699 if (suspenseBoundary !== null) {
20700 switch (suspenseBoundary.tag) {
20701 case SuspenseComponent:
20702 {
20703 // If this suspense boundary is not already showing a fallback, mark
20704 // the in-progress render as suspended. We try to perform this logic
20705 // as soon as soon as possible during the render phase, so the work
20706 // loop can know things like whether it's OK to switch to other tasks,
20707 // or whether it can wait for data to resolve before continuing.
20708 // TODO: Most of these checks are already performed when entering a
20709 // Suspense boundary. We should track the information on the stack so
20710 // we don't have to recompute it on demand. This would also allow us
20711 // to unify with `use` which needs to perform this logic even sooner,
20712 // before `throwException` is called.
20713 {
20714 if (getShellBoundary() === null) {
20715 // Suspended in the "shell" of the app. This is an undesirable
20716 // loading state. We should avoid committing this tree.
20717 renderDidSuspendDelayIfPossible();
20718 } else {
20719 // If we suspended deeper than the shell, we don't need to delay
20720 // the commmit. However, we still call renderDidSuspend if this is
20721 // a new boundary, to tell the work loop that a new fallback has
20722 // appeared during this render.
20723 // TODO: Theoretically we should be able to delete this branch.
20724 // It's currently used for two things: 1) to throttle the
20725 // appearance of successive loading states, and 2) in
20726 // SuspenseList, to determine whether the children include any
20727 // pending fallbacks. For 1, we should apply throttling to all
20728 // retries, not just ones that render an additional fallback. For
20729 // 2, we should check subtreeFlags instead. Then we can delete
20730 // this branch.
20731 var current = suspenseBoundary.alternate;
20732
20733 if (current === null) {
20734 renderDidSuspend();
20735 }
20736 }
20737 }
20738
20739 suspenseBoundary.flags &= ~ForceClientRender;
20740 markSuspenseBoundaryShouldCapture(suspenseBoundary, returnFiber, sourceFiber, root, rootRenderLanes); // Retry listener
20741 //
20742 // If the fallback does commit, we need to attach a different type of
20743 // listener. This one schedules an update on the Suspense boundary to
20744 // turn the fallback state off.
20745 //
20746 // Stash the wakeable on the boundary fiber so we can access it in the
20747 // commit phase.
20748 //
20749 // When the wakeable resolves, we'll attempt to render the boundary
20750 // again ("retry").
20751 // Check if this is a Suspensey resource. We do not attach retry
20752 // listeners to these, because we don't actually need them for
20753 // rendering. Only for committing. Instead, if a fallback commits
20754 // and the only thing that suspended was a Suspensey resource, we
20755 // retry immediately.
20756 // TODO: Refactor throwException so that we don't have to do this type
20757 // check. The caller already knows what the cause was.
20758
20759 var isSuspenseyResource = wakeable === noopSuspenseyCommitThenable;
20760
20761 if (isSuspenseyResource) {
20762 suspenseBoundary.flags |= ScheduleRetry;
20763 } else {
20764 var retryQueue = suspenseBoundary.updateQueue;
20765
20766 if (retryQueue === null) {
20767 suspenseBoundary.updateQueue = new Set([wakeable]);
20768 } else {
20769 retryQueue.add(wakeable);
20770 } // We only attach ping listeners in concurrent mode. Legacy
20771 // Suspense always commits fallbacks synchronously, so there are
20772 // no pings.
20773
20774
20775 {
20776 attachPingListener(root, wakeable, rootRenderLanes);
20777 }
20778 }
20779
20780 return false;
20781 }
20782
20783 case OffscreenComponent:
20784 {
20785 {
20786 suspenseBoundary.flags |= ShouldCapture;
20787
20788 var _isSuspenseyResource = wakeable === noopSuspenseyCommitThenable;
20789
20790 if (_isSuspenseyResource) {
20791 suspenseBoundary.flags |= ScheduleRetry;
20792 } else {
20793 var offscreenQueue = suspenseBoundary.updateQueue;
20794
20795 if (offscreenQueue === null) {
20796 var newOffscreenQueue = {
20797 transitions: null,
20798 markerInstances: null,
20799 retryQueue: new Set([wakeable])
20800 };
20801 suspenseBoundary.updateQueue = newOffscreenQueue;
20802 } else {
20803 var _retryQueue = offscreenQueue.retryQueue;
20804
20805 if (_retryQueue === null) {
20806 offscreenQueue.retryQueue = new Set([wakeable]);
20807 } else {
20808 _retryQueue.add(wakeable);
20809 }
20810 }
20811
20812 attachPingListener(root, wakeable, rootRenderLanes);
20813 }
20814
20815 return false;
20816 }
20817 }
20818 }
20819
20820 throw new Error("Unexpected Suspense handler tag (" + suspenseBoundary.tag + "). This " + 'is a bug in React.');
20821 } else {
20822 // No boundary was found. Unless this is a sync update, this is OK.
20823 // We can suspend and wait for more data to arrive.
20824 {
20825 // In a concurrent root, suspending without a Suspense boundary is
20826 // allowed. It will suspend indefinitely without committing.
20827 //
20828 // TODO: Should we have different behavior for discrete updates? What
20829 // about flushSync? Maybe it should put the tree into an inert state,
20830 // and potentially log a warning. Revisit this for a future release.
20831 attachPingListener(root, wakeable, rootRenderLanes);
20832 renderDidSuspendDelayIfPossible();
20833 return false;
20834 }
20835 }
20836 }
20837 } // This is a regular error, not a Suspense wakeable.
20838
20839
20840 if (getIsHydrating() && (disableLegacyMode )) {
20841 markDidThrowWhileHydratingDEV();
20842
20843 var _suspenseBoundary = getSuspenseHandler(); // If the error was thrown during hydration, we may be able to recover by
20844 // discarding the dehydrated content and switching to a client render.
20845 // Instead of surfacing the error, find the nearest Suspense boundary
20846 // and render it again without hydration.
20847
20848
20849 if (_suspenseBoundary !== null) {
20850 if ((_suspenseBoundary.flags & ShouldCapture) === NoFlags$1) {
20851 // Set a flag to indicate that we should try rendering the normal
20852 // children again, not the fallback.
20853 _suspenseBoundary.flags |= ForceClientRender;
20854 }
20855
20856 markSuspenseBoundaryShouldCapture(_suspenseBoundary, returnFiber, sourceFiber, root, rootRenderLanes); // Even though the user may not be affected by this error, we should
20857 // still log it so it can be fixed.
20858
20859 if (value !== HydrationMismatchException) {
20860 var _wrapperError = new Error('There was an error while hydrating but React was able to recover by ' + 'instead client rendering from the nearest Suspense boundary.', {
20861 cause: value
20862 });
20863
20864 queueHydrationError(createCapturedValueAtFiber(_wrapperError, sourceFiber));
20865 }
20866
20867 return false;
20868 } else {
20869 if (value !== HydrationMismatchException) {
20870 var _wrapperError2 = new Error('There was an error while hydrating but React was able to recover by ' + 'instead client rendering the entire root.', {
20871 cause: value
20872 });
20873
20874 queueHydrationError(createCapturedValueAtFiber(_wrapperError2, sourceFiber));
20875 }
20876
20877 var _workInProgress = root.current.alternate; // Schedule an update at the root to log the error but this shouldn't
20878 // actually happen because we should recover.
20879
20880 _workInProgress.flags |= ShouldCapture;
20881 var lane = pickArbitraryLane(rootRenderLanes);
20882 _workInProgress.lanes = mergeLanes(_workInProgress.lanes, lane);
20883 var rootErrorInfo = createCapturedValueAtFiber(value, sourceFiber);
20884 var update = createRootErrorUpdate(_workInProgress.stateNode, rootErrorInfo, // This should never actually get logged due to the recovery.
20885 lane);
20886 enqueueCapturedUpdate(_workInProgress, update);
20887 renderDidError();
20888 return false;
20889 }
20890 }
20891
20892 var wrapperError = new Error('There was an error during concurrent rendering but React was able to recover by ' + 'instead synchronously rendering the entire root.', {
20893 cause: value
20894 });
20895 queueConcurrentError(createCapturedValueAtFiber(wrapperError, sourceFiber));
20896 renderDidError(); // We didn't find a boundary that could handle this type of exception. Start
20897 // over and traverse parent path again, this time treating the exception
20898 // as an error.
20899
20900 if (returnFiber === null) {
20901 // There's no return fiber, which means the root errored. This should never
20902 // happen. Return `true` to trigger a fatal error (panic).
20903 return true;
20904 }
20905
20906 var errorInfo = createCapturedValueAtFiber(value, sourceFiber);
20907 var workInProgress = returnFiber;
20908
20909 do {
20910 switch (workInProgress.tag) {
20911 case HostRoot:
20912 {
20913 workInProgress.flags |= ShouldCapture;
20914
20915 var _lane = pickArbitraryLane(rootRenderLanes);
20916
20917 workInProgress.lanes = mergeLanes(workInProgress.lanes, _lane);
20918
20919 var _update = createRootErrorUpdate(workInProgress.stateNode, errorInfo, _lane);
20920
20921 enqueueCapturedUpdate(workInProgress, _update);
20922 return false;
20923 }
20924
20925 case ClassComponent:
20926 // Capture and retry
20927 var ctor = workInProgress.type;
20928 var instance = workInProgress.stateNode;
20929
20930 if ((workInProgress.flags & DidCapture) === NoFlags$1 && (typeof ctor.getDerivedStateFromError === 'function' || instance !== null && typeof instance.componentDidCatch === 'function' && !isAlreadyFailedLegacyErrorBoundary(instance))) {
20931 workInProgress.flags |= ShouldCapture;
20932
20933 var _lane2 = pickArbitraryLane(rootRenderLanes);
20934
20935 workInProgress.lanes = mergeLanes(workInProgress.lanes, _lane2); // Schedule the error boundary to re-render using updated state
20936
20937 var _update2 = createClassErrorUpdate(_lane2);
20938
20939 initializeClassErrorUpdate(_update2, root, workInProgress, errorInfo);
20940 enqueueCapturedUpdate(workInProgress, _update2);
20941 return false;
20942 }
20943
20944 break;
20945 } // $FlowFixMe[incompatible-type] we bail out when we get a null
20946
20947
20948 workInProgress = workInProgress.return;
20949 } while (workInProgress !== null);
20950
20951 return false;
20952}
20953
20954// into a dehydrated boundary.
20955
20956var SelectiveHydrationException = new Error("This is not a real error. It's an implementation detail of React's " + "selective hydration feature. If this leaks into userspace, it's a bug in " + 'React. Please file an issue.');
20957var didReceiveUpdate = false;
20958var didWarnAboutBadClass;
20959var didWarnAboutContextTypeOnFunctionComponent;
20960var didWarnAboutGetDerivedStateOnFunctionComponent;
20961var didWarnAboutReassigningProps;
20962var didWarnAboutRevealOrder;
20963var didWarnAboutTailOptions;
20964
20965{
20966 didWarnAboutBadClass = {};
20967 didWarnAboutContextTypeOnFunctionComponent = {};
20968 didWarnAboutGetDerivedStateOnFunctionComponent = {};
20969 didWarnAboutReassigningProps = false;
20970 didWarnAboutRevealOrder = {};
20971 didWarnAboutTailOptions = {};
20972}
20973
20974function reconcileChildren(current, workInProgress, nextChildren, renderLanes) {
20975 if (current === null) {
20976 // If this is a fresh new component that hasn't been rendered yet, we
20977 // won't update its child set by applying minimal side-effects. Instead,
20978 // we will add them all to the child before it gets rendered. That means
20979 // we can optimize this reconciliation pass by not tracking side-effects.
20980 workInProgress.child = mountChildFibers(workInProgress, null, nextChildren, renderLanes);
20981 } else {
20982 // If the current child is the same as the work in progress, it means that
20983 // we haven't yet started any work on these children. Therefore, we use
20984 // the clone algorithm to create a copy of all the current children.
20985 // If we had any progressed work already, that is invalid at this point so
20986 // let's throw it out.
20987 workInProgress.child = reconcileChildFibers(workInProgress, current.child, nextChildren, renderLanes);
20988 }
20989}
20990
20991function forceUnmountCurrentAndReconcile(current, workInProgress, nextChildren, renderLanes) {
20992 // This function is fork of reconcileChildren. It's used in cases where we
20993 // want to reconcile without matching against the existing set. This has the
20994 // effect of all current children being unmounted; even if the type and key
20995 // are the same, the old child is unmounted and a new child is created.
20996 //
20997 // To do this, we're going to go through the reconcile algorithm twice. In
20998 // the first pass, we schedule a deletion for all the current children by
20999 // passing null.
21000 workInProgress.child = reconcileChildFibers(workInProgress, current.child, null, renderLanes); // In the second pass, we mount the new children. The trick here is that we
21001 // pass null in place of where we usually pass the current child set. This has
21002 // the effect of remounting all children regardless of whether their
21003 // identities match.
21004
21005 workInProgress.child = reconcileChildFibers(workInProgress, null, nextChildren, renderLanes);
21006}
21007
21008function updateForwardRef(current, workInProgress, Component, nextProps, renderLanes) {
21009 // TODO: current can be non-null here even if the component
21010 // hasn't yet mounted. This happens after the first render suspends.
21011 // We'll need to figure out if this is fine or can cause issues.
21012 var render = Component.render;
21013 var ref = workInProgress.ref;
21014 var propsWithoutRef;
21015
21016 if ('ref' in nextProps) {
21017 // `ref` is just a prop now, but `forwardRef` expects it to not appear in
21018 // the props object. This used to happen in the JSX runtime, but now we do
21019 // it here.
21020 propsWithoutRef = {};
21021
21022 for (var key in nextProps) {
21023 // Since `ref` should only appear in props via the JSX transform, we can
21024 // assume that this is a plain object. So we don't need a
21025 // hasOwnProperty check.
21026 if (key !== 'ref') {
21027 propsWithoutRef[key] = nextProps[key];
21028 }
21029 }
21030 } else {
21031 propsWithoutRef = nextProps;
21032 } // The rest is a fork of updateFunctionComponent
21033
21034
21035 var nextChildren;
21036 var hasId;
21037 prepareToReadContext(workInProgress, renderLanes);
21038
21039 {
21040 markComponentRenderStarted(workInProgress);
21041 }
21042
21043 {
21044 setCurrentOwner(workInProgress);
21045 setIsRendering(true);
21046 nextChildren = renderWithHooks(current, workInProgress, render, propsWithoutRef, ref, renderLanes);
21047 hasId = checkDidRenderIdHook();
21048 setIsRendering(false);
21049 }
21050
21051 {
21052 markComponentRenderStopped();
21053 }
21054
21055 if (current !== null && !didReceiveUpdate) {
21056 bailoutHooks(current, workInProgress, renderLanes);
21057 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes);
21058 }
21059
21060 if (getIsHydrating() && hasId) {
21061 pushMaterializedTreeId(workInProgress);
21062 } // React DevTools reads this flag.
21063
21064
21065 workInProgress.flags |= PerformedWork;
21066 reconcileChildren(current, workInProgress, nextChildren, renderLanes);
21067 return workInProgress.child;
21068}
21069
21070function updateMemoComponent(current, workInProgress, Component, nextProps, renderLanes) {
21071 if (current === null) {
21072 var type = Component.type;
21073
21074 if (isSimpleFunctionComponent(type) && Component.compare === null && ( // SimpleMemoComponent codepath doesn't resolve outer props either.
21075 disableDefaultPropsExceptForClasses )) {
21076 var resolvedType = type;
21077
21078 {
21079 resolvedType = resolveFunctionForHotReloading(type);
21080 } // If this is a plain function component without default props,
21081 // and with only the default shallow comparison, we upgrade it
21082 // to a SimpleMemoComponent to allow fast path updates.
21083
21084
21085 workInProgress.tag = SimpleMemoComponent;
21086 workInProgress.type = resolvedType;
21087
21088 {
21089 validateFunctionComponentInDev(workInProgress, type);
21090 }
21091
21092 return updateSimpleMemoComponent(current, workInProgress, resolvedType, nextProps, renderLanes);
21093 }
21094
21095 var child = createFiberFromTypeAndProps(Component.type, null, nextProps, workInProgress, workInProgress.mode, renderLanes);
21096 child.ref = workInProgress.ref;
21097 child.return = workInProgress;
21098 workInProgress.child = child;
21099 return child;
21100 }
21101
21102 var currentChild = current.child; // This is always exactly one child
21103
21104 var hasScheduledUpdateOrContext = checkScheduledUpdateOrContext(current, renderLanes);
21105
21106 if (!hasScheduledUpdateOrContext) {
21107 // This will be the props with resolved defaultProps,
21108 // unlike current.memoizedProps which will be the unresolved ones.
21109 var prevProps = currentChild.memoizedProps; // Default to shallow comparison
21110
21111 var compare = Component.compare;
21112 compare = compare !== null ? compare : shallowEqual;
21113
21114 if (compare(prevProps, nextProps) && current.ref === workInProgress.ref) {
21115 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes);
21116 }
21117 } // React DevTools reads this flag.
21118
21119
21120 workInProgress.flags |= PerformedWork;
21121 var newChild = createWorkInProgress(currentChild, nextProps);
21122 newChild.ref = workInProgress.ref;
21123 newChild.return = workInProgress;
21124 workInProgress.child = newChild;
21125 return newChild;
21126}
21127
21128function updateSimpleMemoComponent(current, workInProgress, Component, nextProps, renderLanes) {
21129 // TODO: current can be non-null here even if the component
21130 // hasn't yet mounted. This happens when the inner render suspends.
21131 // We'll need to figure out if this is fine or can cause issues.
21132 if (current !== null) {
21133 var prevProps = current.memoizedProps;
21134
21135 if (shallowEqual(prevProps, nextProps) && current.ref === workInProgress.ref && ( // Prevent bailout if the implementation changed due to hot reload.
21136 workInProgress.type === current.type )) {
21137 didReceiveUpdate = false; // The props are shallowly equal. Reuse the previous props object, like we
21138 // would during a normal fiber bailout.
21139 //
21140 // We don't have strong guarantees that the props object is referentially
21141 // equal during updates where we can't bail out anyway — like if the props
21142 // are shallowly equal, but there's a local state or context update in the
21143 // same batch.
21144 //
21145 // However, as a principle, we should aim to make the behavior consistent
21146 // across different ways of memoizing a component. For example, React.memo
21147 // has a different internal Fiber layout if you pass a normal function
21148 // component (SimpleMemoComponent) versus if you pass a different type
21149 // like forwardRef (MemoComponent). But this is an implementation detail.
21150 // Wrapping a component in forwardRef (or React.lazy, etc) shouldn't
21151 // affect whether the props object is reused during a bailout.
21152
21153 workInProgress.pendingProps = nextProps = prevProps;
21154
21155 if (!checkScheduledUpdateOrContext(current, renderLanes)) {
21156 // The pending lanes were cleared at the beginning of beginWork. We're
21157 // about to bail out, but there might be other lanes that weren't
21158 // included in the current render. Usually, the priority level of the
21159 // remaining updates is accumulated during the evaluation of the
21160 // component (i.e. when processing the update queue). But since since
21161 // we're bailing out early *without* evaluating the component, we need
21162 // to account for it here, too. Reset to the value of the current fiber.
21163 // NOTE: This only applies to SimpleMemoComponent, not MemoComponent,
21164 // because a MemoComponent fiber does not have hooks or an update queue;
21165 // rather, it wraps around an inner component, which may or may not
21166 // contains hooks.
21167 // TODO: Move the reset at in beginWork out of the common path so that
21168 // this is no longer necessary.
21169 workInProgress.lanes = current.lanes;
21170 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes);
21171 } else if ((current.flags & ForceUpdateForLegacySuspense) !== NoFlags$1) {
21172 // This is a special case that only exists for legacy mode.
21173 // See https://github.com/facebook/react/pull/19216.
21174 didReceiveUpdate = true;
21175 }
21176 }
21177 }
21178
21179 return updateFunctionComponent(current, workInProgress, Component, nextProps, renderLanes);
21180}
21181
21182function updateOffscreenComponent(current, workInProgress, renderLanes) {
21183 var nextProps = workInProgress.pendingProps;
21184 var nextChildren = nextProps.children;
21185 var nextIsDetached = (workInProgress.stateNode._pendingVisibility & OffscreenDetached) !== 0;
21186 var prevState = current !== null ? current.memoizedState : null;
21187 markRef(current, workInProgress);
21188
21189 if (nextProps.mode === 'hidden' || enableLegacyHidden || nextIsDetached) {
21190 // Rendering a hidden tree.
21191 var didSuspend = (workInProgress.flags & DidCapture) !== NoFlags$1;
21192
21193 if (didSuspend) {
21194 // Something suspended inside a hidden tree
21195 // Include the base lanes from the last render
21196 var nextBaseLanes = prevState !== null ? mergeLanes(prevState.baseLanes, renderLanes) : renderLanes;
21197
21198 if (current !== null) {
21199 // Reset to the current children
21200 var currentChild = workInProgress.child = current.child; // The current render suspended, but there may be other lanes with
21201 // pending work. We can't read `childLanes` from the current Offscreen
21202 // fiber because we reset it when it was deferred; however, we can read
21203 // the pending lanes from the child fibers.
21204
21205 var currentChildLanes = NoLanes;
21206
21207 while (currentChild !== null) {
21208 currentChildLanes = mergeLanes(mergeLanes(currentChildLanes, currentChild.lanes), currentChild.childLanes);
21209 currentChild = currentChild.sibling;
21210 }
21211
21212 var lanesWeJustAttempted = nextBaseLanes;
21213 var remainingChildLanes = removeLanes(currentChildLanes, lanesWeJustAttempted);
21214 workInProgress.childLanes = remainingChildLanes;
21215 } else {
21216 workInProgress.childLanes = NoLanes;
21217 workInProgress.child = null;
21218 }
21219
21220 return deferHiddenOffscreenComponent(current, workInProgress, nextBaseLanes);
21221 }
21222
21223 if (!includesSomeLane(renderLanes, OffscreenLane)) {
21224 // We're hidden, and we're not rendering at Offscreen. We will bail out
21225 // and resume this tree later.
21226 // Schedule this fiber to re-render at Offscreen priority
21227 workInProgress.lanes = workInProgress.childLanes = laneToLanes(OffscreenLane); // Include the base lanes from the last render
21228
21229 var _nextBaseLanes = prevState !== null ? mergeLanes(prevState.baseLanes, renderLanes) : renderLanes;
21230
21231 return deferHiddenOffscreenComponent(current, workInProgress, _nextBaseLanes);
21232 } else {
21233 // This is the second render. The surrounding visible content has already
21234 // committed. Now we resume rendering the hidden tree.
21235 // Rendering at offscreen, so we can clear the base lanes.
21236 var _nextState = {
21237 baseLanes: NoLanes,
21238 cachePool: null
21239 };
21240 workInProgress.memoizedState = _nextState;
21241
21242 if (current !== null) {
21243 // If the render that spawned this one accessed the cache pool, resume
21244 // using the same cache. Unless the parent changed, since that means
21245 // there was a refresh.
21246 var prevCachePool = prevState !== null ? prevState.cachePool : null; // TODO: Consider if and how Offscreen pre-rendering should
21247 // be attributed to the transition that spawned it
21248
21249 pushTransition(workInProgress, prevCachePool);
21250 } // Push the lanes that were skipped when we bailed out.
21251
21252
21253 if (prevState !== null) {
21254 pushHiddenContext(workInProgress, prevState);
21255 } else {
21256 reuseHiddenContextOnStack(workInProgress);
21257 }
21258
21259 pushOffscreenSuspenseHandler(workInProgress);
21260 }
21261 } else {
21262 // Rendering a visible tree.
21263 if (prevState !== null) {
21264 // We're going from hidden -> visible.
21265 var _prevCachePool = null;
21266
21267 {
21268 // If the render that spawned this one accessed the cache pool, resume
21269 // using the same cache. Unless the parent changed, since that means
21270 // there was a refresh.
21271 _prevCachePool = prevState.cachePool;
21272 }
21273
21274 pushTransition(workInProgress, _prevCachePool); // Push the lanes that were skipped when we bailed out.
21275
21276 pushHiddenContext(workInProgress, prevState);
21277 reuseSuspenseHandlerOnStack(workInProgress); // Since we're not hidden anymore, reset the state
21278
21279 workInProgress.memoizedState = null;
21280 } else {
21281 // We weren't previously hidden, and we still aren't, so there's nothing
21282 // special to do. Need to push to the stack regardless, though, to avoid
21283 // a push/pop misalignment.
21284 {
21285 // If the render that spawned this one accessed the cache pool, resume
21286 // using the same cache. Unless the parent changed, since that means
21287 // there was a refresh.
21288 if (current !== null) {
21289 pushTransition(workInProgress, null);
21290 }
21291 } // We're about to bail out, but we need to push this to the stack anyway
21292 // to avoid a push/pop misalignment.
21293
21294
21295 reuseHiddenContextOnStack(workInProgress);
21296 reuseSuspenseHandlerOnStack(workInProgress);
21297 }
21298 }
21299
21300 reconcileChildren(current, workInProgress, nextChildren, renderLanes);
21301 return workInProgress.child;
21302}
21303
21304function deferHiddenOffscreenComponent(current, workInProgress, nextBaseLanes, renderLanes) {
21305 var nextState = {
21306 baseLanes: nextBaseLanes,
21307 // Save the cache pool so we can resume later.
21308 cachePool: getOffscreenDeferredCache()
21309 };
21310 workInProgress.memoizedState = nextState;
21311
21312 {
21313 // push the cache pool even though we're going to bail out
21314 // because otherwise there'd be a context mismatch
21315 if (current !== null) {
21316 pushTransition(workInProgress, null);
21317 }
21318 } // We're about to bail out, but we need to push this to the stack anyway
21319 // to avoid a push/pop misalignment.
21320
21321
21322 reuseHiddenContextOnStack(workInProgress);
21323 pushOffscreenSuspenseHandler(workInProgress);
21324
21325 return null;
21326} // Note: These happen to have identical begin phases, for now. We shouldn't hold
21327
21328function updateCacheComponent(current, workInProgress, renderLanes) {
21329
21330 prepareToReadContext(workInProgress, renderLanes);
21331 var parentCache = readContext(CacheContext);
21332
21333 if (current === null) {
21334 // Initial mount. Request a fresh cache from the pool.
21335 var freshCache = requestCacheFromPool(renderLanes);
21336 var initialState = {
21337 parent: parentCache,
21338 cache: freshCache
21339 };
21340 workInProgress.memoizedState = initialState;
21341 initializeUpdateQueue(workInProgress);
21342 pushCacheProvider(workInProgress, freshCache);
21343 } else {
21344 // Check for updates
21345 if (includesSomeLane(current.lanes, renderLanes)) {
21346 cloneUpdateQueue(current, workInProgress);
21347 processUpdateQueue(workInProgress, null, null, renderLanes);
21348 suspendIfUpdateReadFromEntangledAsyncAction();
21349 }
21350
21351 var prevState = current.memoizedState;
21352 var nextState = workInProgress.memoizedState; // Compare the new parent cache to the previous to see detect there was
21353 // a refresh.
21354
21355 if (prevState.parent !== parentCache) {
21356 // Refresh in parent. Update the parent.
21357 var derivedState = {
21358 parent: parentCache,
21359 cache: parentCache
21360 }; // Copied from getDerivedStateFromProps implementation. Once the update
21361 // queue is empty, persist the derived state onto the base state.
21362
21363 workInProgress.memoizedState = derivedState;
21364
21365 if (workInProgress.lanes === NoLanes) {
21366 var updateQueue = workInProgress.updateQueue;
21367 workInProgress.memoizedState = updateQueue.baseState = derivedState;
21368 }
21369
21370 pushCacheProvider(workInProgress, parentCache); // No need to propagate a context change because the refreshed parent
21371 // already did.
21372 } else {
21373 // The parent didn't refresh. Now check if this cache did.
21374 var nextCache = nextState.cache;
21375 pushCacheProvider(workInProgress, nextCache);
21376
21377 if (nextCache !== prevState.cache) {
21378 // This cache refreshed. Propagate a context change.
21379 propagateContextChange(workInProgress, CacheContext, renderLanes);
21380 }
21381 }
21382 }
21383
21384 var nextChildren = workInProgress.pendingProps.children;
21385 reconcileChildren(current, workInProgress, nextChildren, renderLanes);
21386 return workInProgress.child;
21387} // This should only be called if the name changes
21388
21389function updateFragment(current, workInProgress, renderLanes) {
21390 var nextChildren = workInProgress.pendingProps;
21391 reconcileChildren(current, workInProgress, nextChildren, renderLanes);
21392 return workInProgress.child;
21393}
21394
21395function updateMode(current, workInProgress, renderLanes) {
21396 var nextChildren = workInProgress.pendingProps.children;
21397 reconcileChildren(current, workInProgress, nextChildren, renderLanes);
21398 return workInProgress.child;
21399}
21400
21401function updateProfiler(current, workInProgress, renderLanes) {
21402 {
21403 workInProgress.flags |= Update;
21404
21405 {
21406 // Reset effect durations for the next eventual effect phase.
21407 // These are reset during render to allow the DevTools commit hook a chance to read them,
21408 var stateNode = workInProgress.stateNode;
21409 stateNode.effectDuration = 0;
21410 stateNode.passiveEffectDuration = 0;
21411 }
21412 }
21413
21414 var nextProps = workInProgress.pendingProps;
21415 var nextChildren = nextProps.children;
21416 reconcileChildren(current, workInProgress, nextChildren, renderLanes);
21417 return workInProgress.child;
21418}
21419
21420function markRef(current, workInProgress) {
21421 // TODO: Check props.ref instead of fiber.ref when enableRefAsProp is on.
21422 var ref = workInProgress.ref;
21423
21424 if (ref === null) {
21425 if (current !== null && current.ref !== null) {
21426 // Schedule a Ref effect
21427 workInProgress.flags |= Ref | RefStatic;
21428 }
21429 } else {
21430 if (typeof ref !== 'function' && typeof ref !== 'object') {
21431 throw new Error('Expected ref to be a function, an object returned by React.createRef(), or undefined/null.');
21432 }
21433
21434 if (current === null || current.ref !== ref) {
21435
21436
21437 workInProgress.flags |= Ref | RefStatic;
21438 }
21439 }
21440}
21441
21442function updateFunctionComponent(current, workInProgress, Component, nextProps, renderLanes) {
21443 {
21444 if (Component.prototype && typeof Component.prototype.render === 'function') {
21445 var componentName = getComponentNameFromType(Component) || 'Unknown';
21446
21447 if (!didWarnAboutBadClass[componentName]) {
21448 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);
21449
21450 didWarnAboutBadClass[componentName] = true;
21451 }
21452 }
21453
21454 if (workInProgress.mode & StrictLegacyMode) {
21455 ReactStrictModeWarnings.recordLegacyContextWarning(workInProgress, null);
21456 }
21457
21458 if (current === null) {
21459 // Some validations were previously done in mountIndeterminateComponent however and are now run
21460 // in updateFuntionComponent but only on mount
21461 validateFunctionComponentInDev(workInProgress, workInProgress.type);
21462
21463 if (Component.contextTypes) {
21464 error('%s uses the legacy contextTypes API which was removed in React 19. ' + 'Use React.createContext() with React.useContext() instead.', getComponentNameFromType(Component) || 'Unknown');
21465 }
21466 }
21467 }
21468
21469 var context;
21470
21471 var nextChildren;
21472 var hasId;
21473 prepareToReadContext(workInProgress, renderLanes);
21474
21475 {
21476 markComponentRenderStarted(workInProgress);
21477 }
21478
21479 {
21480 setCurrentOwner(workInProgress);
21481 setIsRendering(true);
21482 nextChildren = renderWithHooks(current, workInProgress, Component, nextProps, context, renderLanes);
21483 hasId = checkDidRenderIdHook();
21484 setIsRendering(false);
21485 }
21486
21487 {
21488 markComponentRenderStopped();
21489 }
21490
21491 if (current !== null && !didReceiveUpdate) {
21492 bailoutHooks(current, workInProgress, renderLanes);
21493 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes);
21494 }
21495
21496 if (getIsHydrating() && hasId) {
21497 pushMaterializedTreeId(workInProgress);
21498 } // React DevTools reads this flag.
21499
21500
21501 workInProgress.flags |= PerformedWork;
21502 reconcileChildren(current, workInProgress, nextChildren, renderLanes);
21503 return workInProgress.child;
21504}
21505
21506function replayFunctionComponent(current, workInProgress, nextProps, Component, secondArg, renderLanes) {
21507 // This function is used to replay a component that previously suspended,
21508 // after its data resolves. It's a simplified version of
21509 // updateFunctionComponent that reuses the hooks from the previous attempt.
21510 prepareToReadContext(workInProgress, renderLanes);
21511
21512 {
21513 markComponentRenderStarted(workInProgress);
21514 }
21515
21516 var nextChildren = replaySuspendedComponentWithHooks(current, workInProgress, Component, nextProps, secondArg);
21517 var hasId = checkDidRenderIdHook();
21518
21519 {
21520 markComponentRenderStopped();
21521 }
21522
21523 if (current !== null && !didReceiveUpdate) {
21524 bailoutHooks(current, workInProgress, renderLanes);
21525 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes);
21526 }
21527
21528 if (getIsHydrating() && hasId) {
21529 pushMaterializedTreeId(workInProgress);
21530 } // React DevTools reads this flag.
21531
21532
21533 workInProgress.flags |= PerformedWork;
21534 reconcileChildren(current, workInProgress, nextChildren, renderLanes);
21535 return workInProgress.child;
21536}
21537
21538function updateClassComponent(current, workInProgress, Component, nextProps, renderLanes) {
21539 {
21540 // This is used by DevTools to force a boundary to error.
21541 switch (shouldError(workInProgress)) {
21542 case false:
21543 {
21544 var _instance = workInProgress.stateNode;
21545 var ctor = workInProgress.type; // TODO This way of resetting the error boundary state is a hack.
21546 // Is there a better way to do this?
21547
21548 var tempInstance = new ctor(workInProgress.memoizedProps, _instance.context);
21549 var state = tempInstance.state;
21550
21551 _instance.updater.enqueueSetState(_instance, state, null);
21552
21553 break;
21554 }
21555
21556 case true:
21557 {
21558 workInProgress.flags |= DidCapture;
21559 workInProgress.flags |= ShouldCapture; // eslint-disable-next-line react-internal/prod-error-codes
21560
21561 var error$1 = new Error('Simulated error coming from DevTools');
21562 var lane = pickArbitraryLane(renderLanes);
21563 workInProgress.lanes = mergeLanes(workInProgress.lanes, lane); // Schedule the error boundary to re-render using updated state
21564
21565 var root = getWorkInProgressRoot();
21566
21567 if (root === null) {
21568 throw new Error('Expected a work-in-progress root. This is a bug in React. Please file an issue.');
21569 }
21570
21571 var update = createClassErrorUpdate(lane);
21572 initializeClassErrorUpdate(update, root, workInProgress, createCapturedValueAtFiber(error$1, workInProgress));
21573 enqueueCapturedUpdate(workInProgress, update);
21574 break;
21575 }
21576 }
21577 } // Push context providers early to prevent context stack mismatches.
21578 // During mounting we don't know the child context yet as the instance doesn't exist.
21579 // We will invalidate the child context in finishClassComponent() right after rendering.
21580
21581
21582 var hasContext;
21583
21584 if (isContextProvider()) {
21585 hasContext = true;
21586 } else {
21587 hasContext = false;
21588 }
21589
21590 prepareToReadContext(workInProgress, renderLanes);
21591 var instance = workInProgress.stateNode;
21592 var shouldUpdate;
21593
21594 if (instance === null) {
21595
21596 constructClassInstance(workInProgress, Component, nextProps);
21597 mountClassInstance(workInProgress, Component, nextProps, renderLanes);
21598 shouldUpdate = true;
21599 } else if (current === null) {
21600 // In a resume, we'll already have an instance we can reuse.
21601 shouldUpdate = resumeMountClassInstance(workInProgress, Component, nextProps, renderLanes);
21602 } else {
21603 shouldUpdate = updateClassInstance(current, workInProgress, Component, nextProps, renderLanes);
21604 }
21605
21606 var nextUnitOfWork = finishClassComponent(current, workInProgress, Component, shouldUpdate, hasContext, renderLanes);
21607
21608 {
21609 var inst = workInProgress.stateNode;
21610
21611 if (shouldUpdate && inst.props !== nextProps) {
21612 if (!didWarnAboutReassigningProps) {
21613 error('It looks like %s is reassigning its own `this.props` while rendering. ' + 'This is not supported and can lead to confusing bugs.', getComponentNameFromFiber(workInProgress) || 'a component');
21614 }
21615
21616 didWarnAboutReassigningProps = true;
21617 }
21618 }
21619
21620 return nextUnitOfWork;
21621}
21622
21623function finishClassComponent(current, workInProgress, Component, shouldUpdate, hasContext, renderLanes) {
21624 // Refs should update even if shouldComponentUpdate returns false
21625 markRef(current, workInProgress);
21626 var didCaptureError = (workInProgress.flags & DidCapture) !== NoFlags$1;
21627
21628 if (!shouldUpdate && !didCaptureError) {
21629
21630 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes);
21631 }
21632
21633 var instance = workInProgress.stateNode; // Rerender
21634
21635 {
21636 setCurrentOwner(workInProgress);
21637 }
21638
21639 var nextChildren;
21640
21641 if (didCaptureError && typeof Component.getDerivedStateFromError !== 'function') {
21642 // If we captured an error, but getDerivedStateFromError is not defined,
21643 // unmount all the children. componentDidCatch will schedule an update to
21644 // re-render a fallback. This is temporary until we migrate everyone to
21645 // the new API.
21646 // TODO: Warn in a future release.
21647 nextChildren = null;
21648
21649 {
21650 stopProfilerTimerIfRunning();
21651 }
21652 } else {
21653 {
21654 markComponentRenderStarted(workInProgress);
21655 }
21656
21657 {
21658 setIsRendering(true);
21659 nextChildren = instance.render();
21660
21661 if (workInProgress.mode & StrictLegacyMode) {
21662 setIsStrictModeForDevtools(true);
21663
21664 try {
21665 instance.render();
21666 } finally {
21667 setIsStrictModeForDevtools(false);
21668 }
21669 }
21670
21671 setIsRendering(false);
21672 }
21673
21674 {
21675 markComponentRenderStopped();
21676 }
21677 } // React DevTools reads this flag.
21678
21679
21680 workInProgress.flags |= PerformedWork;
21681
21682 if (current !== null && didCaptureError) {
21683 // If we're recovering from an error, reconcile without reusing any of
21684 // the existing children. Conceptually, the normal children and the children
21685 // that are shown on error are two different sets, so we shouldn't reuse
21686 // normal children even if their identities match.
21687 forceUnmountCurrentAndReconcile(current, workInProgress, nextChildren, renderLanes);
21688 } else {
21689 reconcileChildren(current, workInProgress, nextChildren, renderLanes);
21690 } // Memoize state using the values we just used to render.
21691 // TODO: Restructure so we never read values from the instance.
21692
21693
21694 workInProgress.memoizedState = instance.state; // The context might have changed so we need to recalculate it.
21695
21696 return workInProgress.child;
21697}
21698
21699function pushHostRootContext(workInProgress) {
21700 var root = workInProgress.stateNode;
21701
21702 pushHostContainer(workInProgress, root.containerInfo);
21703}
21704
21705function updateHostRoot(current, workInProgress, renderLanes) {
21706 pushHostRootContext(workInProgress);
21707
21708 if (current === null) {
21709 throw new Error('Should have a current fiber. This is a bug in React.');
21710 }
21711
21712 var nextProps = workInProgress.pendingProps;
21713 var prevState = workInProgress.memoizedState;
21714 var prevChildren = prevState.element;
21715 cloneUpdateQueue(current, workInProgress);
21716 processUpdateQueue(workInProgress, nextProps, null, renderLanes);
21717 var nextState = workInProgress.memoizedState;
21718
21719 {
21720 var nextCache = nextState.cache;
21721 pushCacheProvider(workInProgress, nextCache);
21722
21723 if (nextCache !== prevState.cache) {
21724 // The root cache refreshed.
21725 propagateContextChange(workInProgress, CacheContext, renderLanes);
21726 }
21727 } // This would ideally go inside processUpdateQueue, but because it suspends,
21728 // it needs to happen after the `pushCacheProvider` call above to avoid a
21729 // context stack mismatch. A bit unfortunate.
21730
21731
21732 suspendIfUpdateReadFromEntangledAsyncAction(); // Caution: React DevTools currently depends on this property
21733 // being called "element".
21734
21735 var nextChildren = nextState.element;
21736
21737 if (prevState.isDehydrated) {
21738 // This is a hydration root whose shell has not yet hydrated. We should
21739 // attempt to hydrate.
21740 // Flip isDehydrated to false to indicate that when this render
21741 // finishes, the root will no longer be dehydrated.
21742 var overrideState = {
21743 element: nextChildren,
21744 isDehydrated: false,
21745 cache: nextState.cache
21746 };
21747 var updateQueue = workInProgress.updateQueue; // `baseState` can always be the last state because the root doesn't
21748 // have reducer functions so it doesn't need rebasing.
21749
21750 updateQueue.baseState = overrideState;
21751 workInProgress.memoizedState = overrideState;
21752
21753 if (workInProgress.flags & ForceClientRender) {
21754 // Something errored during a previous attempt to hydrate the shell, so we
21755 // forced a client render. We should have a recoverable error already scheduled.
21756 return mountHostRootWithoutHydrating(current, workInProgress, nextChildren, renderLanes);
21757 } else if (nextChildren !== prevChildren) {
21758 var recoverableError = createCapturedValueAtFiber(new Error('This root received an early update, before anything was able ' + 'hydrate. Switched the entire root to client rendering.'), workInProgress);
21759 queueHydrationError(recoverableError);
21760 return mountHostRootWithoutHydrating(current, workInProgress, nextChildren, renderLanes);
21761 } else {
21762 // The outermost shell has not hydrated yet. Start hydrating.
21763 enterHydrationState(workInProgress);
21764 var child = mountChildFibers(workInProgress, null, nextChildren, renderLanes);
21765 workInProgress.child = child;
21766 var node = child;
21767
21768 while (node) {
21769 // Mark each child as hydrating. This is a fast path to know whether this
21770 // tree is part of a hydrating tree. This is used to determine if a child
21771 // node has fully mounted yet, and for scheduling event replaying.
21772 // Conceptually this is similar to Placement in that a new subtree is
21773 // inserted into the React tree here. It just happens to not need DOM
21774 // mutations because it already exists.
21775 node.flags = node.flags & ~Placement | Hydrating;
21776 node = node.sibling;
21777 }
21778 }
21779 } else {
21780 // Root is not dehydrated. Either this is a client-only root, or it
21781 // already hydrated.
21782 resetHydrationState();
21783
21784 if (nextChildren === prevChildren) {
21785 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes);
21786 }
21787
21788 reconcileChildren(current, workInProgress, nextChildren, renderLanes);
21789 }
21790
21791 return workInProgress.child;
21792}
21793
21794function mountHostRootWithoutHydrating(current, workInProgress, nextChildren, renderLanes) {
21795 // Revert to client rendering.
21796 resetHydrationState();
21797 workInProgress.flags |= ForceClientRender;
21798 reconcileChildren(current, workInProgress, nextChildren, renderLanes);
21799 return workInProgress.child;
21800}
21801
21802function updateHostComponent$1(current, workInProgress, renderLanes) {
21803 if (current === null) {
21804 tryToClaimNextHydratableInstance(workInProgress);
21805 }
21806
21807 pushHostContext(workInProgress);
21808 var type = workInProgress.type;
21809 var nextProps = workInProgress.pendingProps;
21810 var prevProps = current !== null ? current.memoizedProps : null;
21811 var nextChildren = nextProps.children;
21812 var isDirectTextChild = shouldSetTextContent(type, nextProps);
21813
21814 if (isDirectTextChild) {
21815 // We special case a direct text child of a host node. This is a common
21816 // case. We won't handle it as a reified child. We will instead handle
21817 // this in the host environment that also has access to this prop. That
21818 // avoids allocating another HostText fiber and traversing it.
21819 nextChildren = null;
21820 } else if (prevProps !== null && shouldSetTextContent(type, prevProps)) {
21821 // If we're switching from a direct text child to a normal child, or to
21822 // empty, we need to schedule the text content to be reset.
21823 workInProgress.flags |= ContentReset;
21824 }
21825
21826 {
21827 var memoizedState = workInProgress.memoizedState;
21828
21829 if (memoizedState !== null) {
21830 // This fiber has been upgraded to a stateful component. The only way
21831 // happens currently is for form actions. We use hooks to track the
21832 // pending and error state of the form.
21833 //
21834 // Once a fiber is upgraded to be stateful, it remains stateful for the
21835 // rest of its lifetime.
21836 var newState = renderTransitionAwareHostComponentWithHooks(current, workInProgress, renderLanes); // If the transition state changed, propagate the change to all the
21837 // descendents. We use Context as an implementation detail for this.
21838 //
21839 // This is intentionally set here instead of pushHostContext because
21840 // pushHostContext gets called before we process the state hook, to avoid
21841 // a state mismatch in the event that something suspends.
21842 //
21843 // NOTE: This assumes that there cannot be nested transition providers,
21844 // because the only renderer that implements this feature is React DOM,
21845 // and forms cannot be nested. If we did support nested providers, then
21846 // we would need to push a context value even for host fibers that
21847 // haven't been upgraded yet.
21848
21849 {
21850 HostTransitionContext._currentValue = newState;
21851 }
21852
21853 {
21854 if (didReceiveUpdate) {
21855 if (current !== null) {
21856 var oldStateHook = current.memoizedState;
21857 var oldState = oldStateHook.memoizedState; // This uses regular equality instead of Object.is because we assume
21858 // that host transition state doesn't include NaN as a valid type.
21859
21860 if (oldState !== newState) {
21861 propagateContextChange(workInProgress, HostTransitionContext, renderLanes);
21862 }
21863 }
21864 }
21865 }
21866 }
21867 }
21868
21869 markRef(current, workInProgress);
21870 reconcileChildren(current, workInProgress, nextChildren, renderLanes);
21871 return workInProgress.child;
21872}
21873
21874function updateHostHoistable(current, workInProgress, renderLanes) {
21875 markRef(current, workInProgress);
21876 var currentProps = current === null ? null : current.memoizedProps;
21877 var resource = workInProgress.memoizedState = getResource(workInProgress.type, currentProps, workInProgress.pendingProps);
21878
21879 if (current === null) {
21880 if (!getIsHydrating() && resource === null) {
21881 // This is not a Resource Hoistable and we aren't hydrating so we construct the instance.
21882 workInProgress.stateNode = createHoistableInstance(workInProgress.type, workInProgress.pendingProps, getRootHostContainer(), workInProgress);
21883 }
21884 } // Resources never have reconciler managed children. It is possible for
21885 // the host implementation of getResource to consider children in the
21886 // resource construction but they will otherwise be discarded. In practice
21887 // this precludes all but the simplest children and Host specific warnings
21888 // should be implemented to warn when children are passsed when otherwise not
21889 // expected
21890
21891
21892 return null;
21893}
21894
21895function updateHostSingleton(current, workInProgress, renderLanes) {
21896 pushHostContext(workInProgress);
21897
21898 if (current === null) {
21899 claimHydratableSingleton(workInProgress);
21900 }
21901
21902 var nextChildren = workInProgress.pendingProps.children;
21903
21904 if (current === null && !getIsHydrating()) {
21905 // Similar to Portals we append Singleton children in the commit phase. So we
21906 // Track insertions even on mount.
21907 // TODO: Consider unifying this with how the root works.
21908 workInProgress.child = reconcileChildFibers(workInProgress, null, nextChildren, renderLanes);
21909 } else {
21910 reconcileChildren(current, workInProgress, nextChildren, renderLanes);
21911 }
21912
21913 markRef(current, workInProgress);
21914 return workInProgress.child;
21915}
21916
21917function updateHostText$1(current, workInProgress) {
21918 if (current === null) {
21919 tryToClaimNextHydratableTextInstance(workInProgress);
21920 } // Nothing to do here. This is terminal. We'll do the completion step
21921 // immediately after.
21922
21923
21924 return null;
21925}
21926
21927function mountLazyComponent(_current, workInProgress, elementType, renderLanes) {
21928 var props = workInProgress.pendingProps;
21929 var lazyComponent = elementType;
21930 var payload = lazyComponent._payload;
21931 var init = lazyComponent._init;
21932 var Component = init(payload); // Store the unwrapped component in the type.
21933
21934 workInProgress.type = Component;
21935
21936 if (typeof Component === 'function') {
21937 if (isFunctionClassComponent(Component)) {
21938 var resolvedProps = resolveClassComponentProps(Component, props);
21939 workInProgress.tag = ClassComponent;
21940
21941 {
21942 workInProgress.type = Component = resolveClassForHotReloading(Component);
21943 }
21944
21945 return updateClassComponent(null, workInProgress, Component, resolvedProps, renderLanes);
21946 } else {
21947 var _resolvedProps = props ;
21948
21949 workInProgress.tag = FunctionComponent;
21950
21951 {
21952 validateFunctionComponentInDev(workInProgress, Component);
21953 workInProgress.type = Component = resolveFunctionForHotReloading(Component);
21954 }
21955
21956 return updateFunctionComponent(null, workInProgress, Component, _resolvedProps, renderLanes);
21957 }
21958 } else if (Component !== undefined && Component !== null) {
21959 var $$typeof = Component.$$typeof;
21960
21961 if ($$typeof === REACT_FORWARD_REF_TYPE) {
21962 var _resolvedProps2 = props ;
21963
21964 workInProgress.tag = ForwardRef;
21965
21966 {
21967 workInProgress.type = Component = resolveForwardRefForHotReloading(Component);
21968 }
21969
21970 return updateForwardRef(null, workInProgress, Component, _resolvedProps2, renderLanes);
21971 } else if ($$typeof === REACT_MEMO_TYPE) {
21972 var _resolvedProps3 = props ;
21973
21974 workInProgress.tag = MemoComponent;
21975 return updateMemoComponent(null, workInProgress, Component, _resolvedProps3 , // The inner type can have defaults too
21976 renderLanes);
21977 }
21978 }
21979
21980 var hint = '';
21981
21982 {
21983 if (Component !== null && typeof Component === 'object' && Component.$$typeof === REACT_LAZY_TYPE) {
21984 hint = ' Did you wrap a component in React.lazy() more than once?';
21985 }
21986 } // This message intentionally doesn't mention ForwardRef or MemoComponent
21987 // because the fact that it's a separate type of work is an
21988 // implementation detail.
21989
21990
21991 throw new Error("Element type is invalid. Received a promise that resolves to: " + Component + ". " + ("Lazy element type must resolve to a class or function." + hint));
21992}
21993
21994function validateFunctionComponentInDev(workInProgress, Component) {
21995 {
21996 if (Component) {
21997 if (Component.childContextTypes) {
21998 error('childContextTypes cannot be defined on a function component.\n' + ' %s.childContextTypes = ...', Component.displayName || Component.name || 'Component');
21999 }
22000 }
22001
22002 if (typeof Component.getDerivedStateFromProps === 'function') {
22003 var _componentName2 = getComponentNameFromType(Component) || 'Unknown';
22004
22005 if (!didWarnAboutGetDerivedStateOnFunctionComponent[_componentName2]) {
22006 error('%s: Function components do not support getDerivedStateFromProps.', _componentName2);
22007
22008 didWarnAboutGetDerivedStateOnFunctionComponent[_componentName2] = true;
22009 }
22010 }
22011
22012 if (typeof Component.contextType === 'object' && Component.contextType !== null) {
22013 var _componentName3 = getComponentNameFromType(Component) || 'Unknown';
22014
22015 if (!didWarnAboutContextTypeOnFunctionComponent[_componentName3]) {
22016 error('%s: Function components do not support contextType.', _componentName3);
22017
22018 didWarnAboutContextTypeOnFunctionComponent[_componentName3] = true;
22019 }
22020 }
22021 }
22022}
22023
22024var SUSPENDED_MARKER = {
22025 dehydrated: null,
22026 treeContext: null,
22027 retryLane: NoLane
22028};
22029
22030function mountSuspenseOffscreenState(renderLanes) {
22031 return {
22032 baseLanes: renderLanes,
22033 cachePool: getSuspendedCache()
22034 };
22035}
22036
22037function updateSuspenseOffscreenState(prevOffscreenState, renderLanes) {
22038 var cachePool = null;
22039
22040 {
22041 var prevCachePool = prevOffscreenState.cachePool;
22042
22043 if (prevCachePool !== null) {
22044 var parentCache = CacheContext._currentValue ;
22045
22046 if (prevCachePool.parent !== parentCache) {
22047 // Detected a refresh in the parent. This overrides any previously
22048 // suspended cache.
22049 cachePool = {
22050 parent: parentCache,
22051 pool: parentCache
22052 };
22053 } else {
22054 // We can reuse the cache from last time. The only thing that would have
22055 // overridden it is a parent refresh, which we checked for above.
22056 cachePool = prevCachePool;
22057 }
22058 } else {
22059 // If there's no previous cache pool, grab the current one.
22060 cachePool = getSuspendedCache();
22061 }
22062 }
22063
22064 return {
22065 baseLanes: mergeLanes(prevOffscreenState.baseLanes, renderLanes),
22066 cachePool: cachePool
22067 };
22068} // TODO: Probably should inline this back
22069
22070
22071function shouldRemainOnFallback(current, workInProgress, renderLanes) {
22072 // If we're already showing a fallback, there are cases where we need to
22073 // remain on that fallback regardless of whether the content has resolved.
22074 // For example, SuspenseList coordinates when nested content appears.
22075 // TODO: For compatibility with offscreen prerendering, this should also check
22076 // whether the current fiber (if it exists) was visible in the previous tree.
22077 if (current !== null) {
22078 var suspenseState = current.memoizedState;
22079
22080 if (suspenseState === null) {
22081 // Currently showing content. Don't hide it, even if ForceSuspenseFallback
22082 // is true. More precise name might be "ForceRemainSuspenseFallback".
22083 // Note: This is a factoring smell. Can't remain on a fallback if there's
22084 // no fallback to remain on.
22085 return false;
22086 }
22087 } // Not currently showing content. Consult the Suspense context.
22088
22089
22090 var suspenseContext = suspenseStackCursor.current;
22091 return hasSuspenseListContext(suspenseContext, ForceSuspenseFallback);
22092}
22093
22094function getRemainingWorkInPrimaryTree(current, primaryTreeDidDefer, renderLanes) {
22095 var remainingLanes = current !== null ? removeLanes(current.childLanes, renderLanes) : NoLanes;
22096
22097 if (primaryTreeDidDefer) {
22098 // A useDeferredValue hook spawned a deferred task inside the primary tree.
22099 // Ensure that we retry this component at the deferred priority.
22100 // TODO: We could make this a per-subtree value instead of a global one.
22101 // Would need to track it on the context stack somehow, similar to what
22102 // we'd have to do for resumable contexts.
22103 remainingLanes = mergeLanes(remainingLanes, peekDeferredLane());
22104 }
22105
22106 return remainingLanes;
22107}
22108
22109function updateSuspenseComponent(current, workInProgress, renderLanes) {
22110 var nextProps = workInProgress.pendingProps; // This is used by DevTools to force a boundary to suspend.
22111
22112 {
22113 if (shouldSuspend(workInProgress)) {
22114 workInProgress.flags |= DidCapture;
22115 }
22116 }
22117
22118 var showFallback = false;
22119 var didSuspend = (workInProgress.flags & DidCapture) !== NoFlags$1;
22120
22121 if (didSuspend || shouldRemainOnFallback(current)) {
22122 // Something in this boundary's subtree already suspended. Switch to
22123 // rendering the fallback children.
22124 showFallback = true;
22125 workInProgress.flags &= ~DidCapture;
22126 } // Check if the primary children spawned a deferred task (useDeferredValue)
22127 // during the first pass.
22128
22129
22130 var didPrimaryChildrenDefer = (workInProgress.flags & DidDefer) !== NoFlags$1;
22131 workInProgress.flags &= ~DidDefer; // OK, the next part is confusing. We're about to reconcile the Suspense
22132 // boundary's children. This involves some custom reconciliation logic. Two
22133 // main reasons this is so complicated.
22134 //
22135 // First, Legacy Mode has different semantics for backwards compatibility. The
22136 // primary tree will commit in an inconsistent state, so when we do the
22137 // second pass to render the fallback, we do some exceedingly, uh, clever
22138 // hacks to make that not totally break. Like transferring effects and
22139 // deletions from hidden tree. In Concurrent Mode, it's much simpler,
22140 // because we bailout on the primary tree completely and leave it in its old
22141 // state, no effects. Same as what we do for Offscreen (except that
22142 // Offscreen doesn't have the first render pass).
22143 //
22144 // Second is hydration. During hydration, the Suspense fiber has a slightly
22145 // different layout, where the child points to a dehydrated fragment, which
22146 // contains the DOM rendered by the server.
22147 //
22148 // Third, even if you set all that aside, Suspense is like error boundaries in
22149 // that we first we try to render one tree, and if that fails, we render again
22150 // and switch to a different tree. Like a try/catch block. So we have to track
22151 // which branch we're currently rendering. Ideally we would model this using
22152 // a stack.
22153
22154 if (current === null) {
22155 // Initial mount
22156 // Special path for hydration
22157 // If we're currently hydrating, try to hydrate this boundary.
22158 if (getIsHydrating()) {
22159 // We must push the suspense handler context *before* attempting to
22160 // hydrate, to avoid a mismatch in case it errors.
22161 if (showFallback) {
22162 pushPrimaryTreeSuspenseHandler(workInProgress);
22163 } else {
22164 pushFallbackTreeSuspenseHandler(workInProgress);
22165 }
22166
22167 tryToClaimNextHydratableSuspenseInstance(workInProgress); // This could've been a dehydrated suspense component.
22168
22169 var suspenseState = workInProgress.memoizedState;
22170
22171 if (suspenseState !== null) {
22172 var dehydrated = suspenseState.dehydrated;
22173
22174 if (dehydrated !== null) {
22175 return mountDehydratedSuspenseComponent(workInProgress, dehydrated);
22176 }
22177 } // If hydration didn't succeed, fall through to the normal Suspense path.
22178 // To avoid a stack mismatch we need to pop the Suspense handler that we
22179 // pushed above. This will become less awkward when move the hydration
22180 // logic to its own fiber.
22181
22182
22183 popSuspenseHandler(workInProgress);
22184 }
22185
22186 var nextPrimaryChildren = nextProps.children;
22187 var nextFallbackChildren = nextProps.fallback;
22188
22189 if (showFallback) {
22190 pushFallbackTreeSuspenseHandler(workInProgress);
22191 var fallbackFragment = mountSuspenseFallbackChildren(workInProgress, nextPrimaryChildren, nextFallbackChildren, renderLanes);
22192 var primaryChildFragment = workInProgress.child;
22193 primaryChildFragment.memoizedState = mountSuspenseOffscreenState(renderLanes);
22194 primaryChildFragment.childLanes = getRemainingWorkInPrimaryTree(current, didPrimaryChildrenDefer, renderLanes);
22195 workInProgress.memoizedState = SUSPENDED_MARKER;
22196
22197 return fallbackFragment;
22198 } else {
22199 pushPrimaryTreeSuspenseHandler(workInProgress);
22200 return mountSuspensePrimaryChildren(workInProgress, nextPrimaryChildren);
22201 }
22202 } else {
22203 // This is an update.
22204 // Special path for hydration
22205 var prevState = current.memoizedState;
22206
22207 if (prevState !== null) {
22208 var _dehydrated = prevState.dehydrated;
22209
22210 if (_dehydrated !== null) {
22211 return updateDehydratedSuspenseComponent(current, workInProgress, didSuspend, didPrimaryChildrenDefer, nextProps, _dehydrated, prevState, renderLanes);
22212 }
22213 }
22214
22215 if (showFallback) {
22216 pushFallbackTreeSuspenseHandler(workInProgress);
22217 var _nextFallbackChildren = nextProps.fallback;
22218 var _nextPrimaryChildren = nextProps.children;
22219 var fallbackChildFragment = updateSuspenseFallbackChildren(current, workInProgress, _nextPrimaryChildren, _nextFallbackChildren, renderLanes);
22220 var _primaryChildFragment2 = workInProgress.child;
22221 var prevOffscreenState = current.child.memoizedState;
22222 _primaryChildFragment2.memoizedState = prevOffscreenState === null ? mountSuspenseOffscreenState(renderLanes) : updateSuspenseOffscreenState(prevOffscreenState, renderLanes);
22223
22224 _primaryChildFragment2.childLanes = getRemainingWorkInPrimaryTree(current, didPrimaryChildrenDefer, renderLanes);
22225 workInProgress.memoizedState = SUSPENDED_MARKER;
22226 return fallbackChildFragment;
22227 } else {
22228 pushPrimaryTreeSuspenseHandler(workInProgress);
22229 var _nextPrimaryChildren2 = nextProps.children;
22230
22231 var _primaryChildFragment3 = updateSuspensePrimaryChildren(current, workInProgress, _nextPrimaryChildren2);
22232
22233 workInProgress.memoizedState = null;
22234 return _primaryChildFragment3;
22235 }
22236 }
22237}
22238
22239function mountSuspensePrimaryChildren(workInProgress, primaryChildren, renderLanes) {
22240 var mode = workInProgress.mode;
22241 var primaryChildProps = {
22242 mode: 'visible',
22243 children: primaryChildren
22244 };
22245 var primaryChildFragment = mountWorkInProgressOffscreenFiber(primaryChildProps, mode);
22246 primaryChildFragment.return = workInProgress;
22247 workInProgress.child = primaryChildFragment;
22248 return primaryChildFragment;
22249}
22250
22251function mountSuspenseFallbackChildren(workInProgress, primaryChildren, fallbackChildren, renderLanes) {
22252 var mode = workInProgress.mode;
22253 var primaryChildProps = {
22254 mode: 'hidden',
22255 children: primaryChildren
22256 };
22257 var primaryChildFragment;
22258 var fallbackChildFragment;
22259
22260 {
22261 primaryChildFragment = mountWorkInProgressOffscreenFiber(primaryChildProps, mode);
22262 fallbackChildFragment = createFiberFromFragment(fallbackChildren, mode, renderLanes, null);
22263 }
22264
22265 primaryChildFragment.return = workInProgress;
22266 fallbackChildFragment.return = workInProgress;
22267 primaryChildFragment.sibling = fallbackChildFragment;
22268 workInProgress.child = primaryChildFragment;
22269 return fallbackChildFragment;
22270}
22271
22272function mountWorkInProgressOffscreenFiber(offscreenProps, mode, renderLanes) {
22273 // The props argument to `createFiberFromOffscreen` is `any` typed, so we use
22274 // this wrapper function to constrain it.
22275 return createFiberFromOffscreen(offscreenProps, mode, NoLanes, null);
22276}
22277
22278function updateWorkInProgressOffscreenFiber(current, offscreenProps) {
22279 // The props argument to `createWorkInProgress` is `any` typed, so we use this
22280 // wrapper function to constrain it.
22281 return createWorkInProgress(current, offscreenProps);
22282}
22283
22284function updateSuspensePrimaryChildren(current, workInProgress, primaryChildren, renderLanes) {
22285 var currentPrimaryChildFragment = current.child;
22286 var currentFallbackChildFragment = currentPrimaryChildFragment.sibling;
22287 var primaryChildFragment = updateWorkInProgressOffscreenFiber(currentPrimaryChildFragment, {
22288 mode: 'visible',
22289 children: primaryChildren
22290 });
22291
22292 primaryChildFragment.return = workInProgress;
22293 primaryChildFragment.sibling = null;
22294
22295 if (currentFallbackChildFragment !== null) {
22296 // Delete the fallback child fragment
22297 var deletions = workInProgress.deletions;
22298
22299 if (deletions === null) {
22300 workInProgress.deletions = [currentFallbackChildFragment];
22301 workInProgress.flags |= ChildDeletion;
22302 } else {
22303 deletions.push(currentFallbackChildFragment);
22304 }
22305 }
22306
22307 workInProgress.child = primaryChildFragment;
22308 return primaryChildFragment;
22309}
22310
22311function updateSuspenseFallbackChildren(current, workInProgress, primaryChildren, fallbackChildren, renderLanes) {
22312 var mode = workInProgress.mode;
22313 var currentPrimaryChildFragment = current.child;
22314 var currentFallbackChildFragment = currentPrimaryChildFragment.sibling;
22315 var primaryChildProps = {
22316 mode: 'hidden',
22317 children: primaryChildren
22318 };
22319 var primaryChildFragment;
22320
22321 {
22322 primaryChildFragment = updateWorkInProgressOffscreenFiber(currentPrimaryChildFragment, primaryChildProps); // Since we're reusing a current tree, we need to reuse the flags, too.
22323 // (We don't do this in legacy mode, because in legacy mode we don't re-use
22324 // the current tree; see previous branch.)
22325
22326 primaryChildFragment.subtreeFlags = currentPrimaryChildFragment.subtreeFlags & StaticMask;
22327 }
22328
22329 var fallbackChildFragment;
22330
22331 if (currentFallbackChildFragment !== null) {
22332 fallbackChildFragment = createWorkInProgress(currentFallbackChildFragment, fallbackChildren);
22333 } else {
22334 fallbackChildFragment = createFiberFromFragment(fallbackChildren, mode, renderLanes, null); // Needs a placement effect because the parent (the Suspense boundary) already
22335 // mounted but this is a new fiber.
22336
22337 fallbackChildFragment.flags |= Placement;
22338 }
22339
22340 fallbackChildFragment.return = workInProgress;
22341 primaryChildFragment.return = workInProgress;
22342 primaryChildFragment.sibling = fallbackChildFragment;
22343 workInProgress.child = primaryChildFragment;
22344 return fallbackChildFragment;
22345}
22346
22347function retrySuspenseComponentWithoutHydrating(current, workInProgress, renderLanes) {
22348 // Falling back to client rendering. Because this has performance
22349 // implications, it's considered a recoverable error, even though the user
22350 // likely won't observe anything wrong with the UI.
22351 // This will add the old fiber to the deletion list
22352 reconcileChildFibers(workInProgress, current.child, null, renderLanes); // We're now not suspended nor dehydrated.
22353
22354 var nextProps = workInProgress.pendingProps;
22355 var primaryChildren = nextProps.children;
22356 var primaryChildFragment = mountSuspensePrimaryChildren(workInProgress, primaryChildren); // Needs a placement effect because the parent (the Suspense boundary) already
22357 // mounted but this is a new fiber.
22358
22359 primaryChildFragment.flags |= Placement;
22360 workInProgress.memoizedState = null;
22361 return primaryChildFragment;
22362}
22363
22364function mountSuspenseFallbackAfterRetryWithoutHydrating(current, workInProgress, primaryChildren, fallbackChildren, renderLanes) {
22365 var fiberMode = workInProgress.mode;
22366 var primaryChildProps = {
22367 mode: 'visible',
22368 children: primaryChildren
22369 };
22370 var primaryChildFragment = mountWorkInProgressOffscreenFiber(primaryChildProps, fiberMode);
22371 var fallbackChildFragment = createFiberFromFragment(fallbackChildren, fiberMode, renderLanes, null); // Needs a placement effect because the parent (the Suspense
22372 // boundary) already mounted but this is a new fiber.
22373
22374 fallbackChildFragment.flags |= Placement;
22375 primaryChildFragment.return = workInProgress;
22376 fallbackChildFragment.return = workInProgress;
22377 primaryChildFragment.sibling = fallbackChildFragment;
22378 workInProgress.child = primaryChildFragment;
22379
22380 {
22381 // We will have dropped the effect list which contains the
22382 // deletion. We need to reconcile to delete the current child.
22383 reconcileChildFibers(workInProgress, current.child, null, renderLanes);
22384 }
22385
22386 return fallbackChildFragment;
22387}
22388
22389function mountDehydratedSuspenseComponent(workInProgress, suspenseInstance, renderLanes) {
22390 // During the first pass, we'll bail out and not drill into the children.
22391 // Instead, we'll leave the content in place and try to hydrate it later.
22392 if (isSuspenseInstanceFallback(suspenseInstance)) {
22393 // This is a client-only boundary. Since we won't get any content from the server
22394 // for this, we need to schedule that at a higher priority based on when it would
22395 // have timed out. In theory we could render it in this pass but it would have the
22396 // wrong priority associated with it and will prevent hydration of parent path.
22397 // Instead, we'll leave work left on it to render it in a separate commit.
22398 // TODO This time should be the time at which the server rendered response that is
22399 // a parent to this boundary was displayed. However, since we currently don't have
22400 // a protocol to transfer that time, we'll just estimate it by using the current
22401 // time. This will mean that Suspense timeouts are slightly shifted to later than
22402 // they should be.
22403 // Schedule a normal pri update to render this content.
22404 workInProgress.lanes = laneToLanes(DefaultHydrationLane);
22405 } else {
22406 // We'll continue hydrating the rest at offscreen priority since we'll already
22407 // be showing the right content coming from the server, it is no rush.
22408 workInProgress.lanes = laneToLanes(OffscreenLane);
22409 }
22410
22411 return null;
22412}
22413
22414function updateDehydratedSuspenseComponent(current, workInProgress, didSuspend, didPrimaryChildrenDefer, nextProps, suspenseInstance, suspenseState, renderLanes) {
22415 if (!didSuspend) {
22416 // This is the first render pass. Attempt to hydrate.
22417 pushPrimaryTreeSuspenseHandler(workInProgress); // We should never be hydrating at this point because it is the first pass,
22418 // but after we've already committed once.
22419
22420 warnIfHydrating();
22421
22422 if (isSuspenseInstanceFallback(suspenseInstance)) {
22423 // This boundary is in a permanent fallback state. In this case, we'll never
22424 // get an update and we'll never be able to hydrate the final content. Let's just try the
22425 // client side render instead.
22426 var digest;
22427 var message;
22428 var stack = null;
22429 var componentStack = null;
22430
22431 {
22432 var _getSuspenseInstanceF = getSuspenseInstanceFallbackErrorDetails(suspenseInstance);
22433
22434 digest = _getSuspenseInstanceF.digest;
22435 message = _getSuspenseInstanceF.message;
22436 stack = _getSuspenseInstanceF.stack;
22437 componentStack = _getSuspenseInstanceF.componentStack;
22438 } // TODO: Figure out a better signal than encoding a magic digest value.
22439
22440
22441 {
22442 var error;
22443
22444 if (message) {
22445 // eslint-disable-next-line react-internal/prod-error-codes
22446 error = new Error(message);
22447 } else {
22448 error = new Error('The server could not finish this Suspense boundary, likely ' + 'due to an error during server rendering. ' + 'Switched to client rendering.');
22449 } // Replace the stack with the server stack
22450
22451
22452 error.stack = stack || '';
22453 error.digest = digest;
22454 var capturedValue = createCapturedValueFromError(error, componentStack === undefined ? null : componentStack);
22455 queueHydrationError(capturedValue);
22456 }
22457
22458 return retrySuspenseComponentWithoutHydrating(current, workInProgress, renderLanes);
22459 }
22460 // any context has changed, we need to treat is as if the input might have changed.
22461
22462
22463 var hasContextChanged = includesSomeLane(renderLanes, current.childLanes);
22464
22465 if (didReceiveUpdate || hasContextChanged) {
22466 // This boundary has changed since the first render. This means that we are now unable to
22467 // hydrate it. We might still be able to hydrate it using a higher priority lane.
22468 var root = getWorkInProgressRoot();
22469
22470 if (root !== null) {
22471 var attemptHydrationAtLane = getBumpedLaneForHydration(root, renderLanes);
22472
22473 if (attemptHydrationAtLane !== NoLane && attemptHydrationAtLane !== suspenseState.retryLane) {
22474 // Intentionally mutating since this render will get interrupted. This
22475 // is one of the very rare times where we mutate the current tree
22476 // during the render phase.
22477 suspenseState.retryLane = attemptHydrationAtLane;
22478 enqueueConcurrentRenderForLane(current, attemptHydrationAtLane);
22479 scheduleUpdateOnFiber(root, current, attemptHydrationAtLane); // Throw a special object that signals to the work loop that it should
22480 // interrupt the current render.
22481 //
22482 // Because we're inside a React-only execution stack, we don't
22483 // strictly need to throw here — we could instead modify some internal
22484 // work loop state. But using an exception means we don't need to
22485 // check for this case on every iteration of the work loop. So doing
22486 // it this way moves the check out of the fast path.
22487
22488 throw SelectiveHydrationException;
22489 }
22490 } // If we did not selectively hydrate, we'll continue rendering without
22491 // hydrating. Mark this tree as suspended to prevent it from committing
22492 // outside a transition.
22493 //
22494 // This path should only happen if the hydration lane already suspended.
22495 // Currently, it also happens during sync updates because there is no
22496 // hydration lane for sync updates.
22497 // TODO: We should ideally have a sync hydration lane that we can apply to do
22498 // a pass where we hydrate this subtree in place using the previous Context and then
22499 // reapply the update afterwards.
22500
22501
22502 if (isSuspenseInstancePending(suspenseInstance)) ; else {
22503 renderDidSuspendDelayIfPossible();
22504 }
22505
22506 return retrySuspenseComponentWithoutHydrating(current, workInProgress, renderLanes);
22507 } else if (isSuspenseInstancePending(suspenseInstance)) {
22508 // This component is still pending more data from the server, so we can't hydrate its
22509 // content. We treat it as if this component suspended itself. It might seem as if
22510 // we could just try to render it client-side instead. However, this will perform a
22511 // lot of unnecessary work and is unlikely to complete since it often will suspend
22512 // on missing data anyway. Additionally, the server might be able to render more
22513 // than we can on the client yet. In that case we'd end up with more fallback states
22514 // on the client than if we just leave it alone. If the server times out or errors
22515 // these should update this boundary to the permanent Fallback state instead.
22516 // Mark it as having captured (i.e. suspended).
22517 workInProgress.flags |= DidCapture; // Leave the child in place. I.e. the dehydrated fragment.
22518
22519 workInProgress.child = current.child; // Register a callback to retry this boundary once the server has sent the result.
22520
22521 var retry = retryDehydratedSuspenseBoundary.bind(null, current);
22522 registerSuspenseInstanceRetry(suspenseInstance, retry);
22523 return null;
22524 } else {
22525 // This is the first attempt.
22526 reenterHydrationStateFromDehydratedSuspenseInstance(workInProgress, suspenseInstance, suspenseState.treeContext);
22527 var primaryChildren = nextProps.children;
22528 var primaryChildFragment = mountSuspensePrimaryChildren(workInProgress, primaryChildren); // Mark the children as hydrating. This is a fast path to know whether this
22529 // tree is part of a hydrating tree. This is used to determine if a child
22530 // node has fully mounted yet, and for scheduling event replaying.
22531 // Conceptually this is similar to Placement in that a new subtree is
22532 // inserted into the React tree here. It just happens to not need DOM
22533 // mutations because it already exists.
22534
22535 primaryChildFragment.flags |= Hydrating;
22536 return primaryChildFragment;
22537 }
22538 } else {
22539 // This is the second render pass. We already attempted to hydrated, but
22540 // something either suspended or errored.
22541 if (workInProgress.flags & ForceClientRender) {
22542 // Something errored during hydration. Try again without hydrating.
22543 // The error should've already been logged in throwException.
22544 pushPrimaryTreeSuspenseHandler(workInProgress);
22545 workInProgress.flags &= ~ForceClientRender;
22546 return retrySuspenseComponentWithoutHydrating(current, workInProgress, renderLanes);
22547 } else if (workInProgress.memoizedState !== null) {
22548 // Something suspended and we should still be in dehydrated mode.
22549 // Leave the existing child in place.
22550 // Push to avoid a mismatch
22551 pushFallbackTreeSuspenseHandler(workInProgress);
22552 workInProgress.child = current.child; // The dehydrated completion pass expects this flag to be there
22553 // but the normal suspense pass doesn't.
22554
22555 workInProgress.flags |= DidCapture;
22556 return null;
22557 } else {
22558 // Suspended but we should no longer be in dehydrated mode.
22559 // Therefore we now have to render the fallback.
22560 pushFallbackTreeSuspenseHandler(workInProgress);
22561 var nextPrimaryChildren = nextProps.children;
22562 var nextFallbackChildren = nextProps.fallback;
22563 var fallbackChildFragment = mountSuspenseFallbackAfterRetryWithoutHydrating(current, workInProgress, nextPrimaryChildren, nextFallbackChildren, renderLanes);
22564 var _primaryChildFragment4 = workInProgress.child;
22565 _primaryChildFragment4.memoizedState = mountSuspenseOffscreenState(renderLanes);
22566 _primaryChildFragment4.childLanes = getRemainingWorkInPrimaryTree(current, didPrimaryChildrenDefer, renderLanes);
22567 workInProgress.memoizedState = SUSPENDED_MARKER;
22568 return fallbackChildFragment;
22569 }
22570 }
22571}
22572
22573function scheduleSuspenseWorkOnFiber(fiber, renderLanes, propagationRoot) {
22574 fiber.lanes = mergeLanes(fiber.lanes, renderLanes);
22575 var alternate = fiber.alternate;
22576
22577 if (alternate !== null) {
22578 alternate.lanes = mergeLanes(alternate.lanes, renderLanes);
22579 }
22580
22581 scheduleContextWorkOnParentPath(fiber.return, renderLanes, propagationRoot);
22582}
22583
22584function propagateSuspenseContextChange(workInProgress, firstChild, renderLanes) {
22585 // Mark any Suspense boundaries with fallbacks as having work to do.
22586 // If they were previously forced into fallbacks, they may now be able
22587 // to unblock.
22588 var node = firstChild;
22589
22590 while (node !== null) {
22591 if (node.tag === SuspenseComponent) {
22592 var state = node.memoizedState;
22593
22594 if (state !== null) {
22595 scheduleSuspenseWorkOnFiber(node, renderLanes, workInProgress);
22596 }
22597 } else if (node.tag === SuspenseListComponent) {
22598 // If the tail is hidden there might not be an Suspense boundaries
22599 // to schedule work on. In this case we have to schedule it on the
22600 // list itself.
22601 // We don't have to traverse to the children of the list since
22602 // the list will propagate the change when it rerenders.
22603 scheduleSuspenseWorkOnFiber(node, renderLanes, workInProgress);
22604 } else if (node.child !== null) {
22605 node.child.return = node;
22606 node = node.child;
22607 continue;
22608 }
22609
22610 if (node === workInProgress) {
22611 return;
22612 } // $FlowFixMe[incompatible-use] found when upgrading Flow
22613
22614
22615 while (node.sibling === null) {
22616 // $FlowFixMe[incompatible-use] found when upgrading Flow
22617 if (node.return === null || node.return === workInProgress) {
22618 return;
22619 }
22620
22621 node = node.return;
22622 } // $FlowFixMe[incompatible-use] found when upgrading Flow
22623
22624
22625 node.sibling.return = node.return;
22626 node = node.sibling;
22627 }
22628}
22629
22630function findLastContentRow(firstChild) {
22631 // This is going to find the last row among these children that is already
22632 // showing content on the screen, as opposed to being in fallback state or
22633 // new. If a row has multiple Suspense boundaries, any of them being in the
22634 // fallback state, counts as the whole row being in a fallback state.
22635 // Note that the "rows" will be workInProgress, but any nested children
22636 // will still be current since we haven't rendered them yet. The mounted
22637 // order may not be the same as the new order. We use the new order.
22638 var row = firstChild;
22639 var lastContentRow = null;
22640
22641 while (row !== null) {
22642 var currentRow = row.alternate; // New rows can't be content rows.
22643
22644 if (currentRow !== null && findFirstSuspended(currentRow) === null) {
22645 lastContentRow = row;
22646 }
22647
22648 row = row.sibling;
22649 }
22650
22651 return lastContentRow;
22652}
22653
22654function validateRevealOrder(revealOrder) {
22655 {
22656 if (revealOrder !== undefined && revealOrder !== 'forwards' && revealOrder !== 'backwards' && revealOrder !== 'together' && !didWarnAboutRevealOrder[revealOrder]) {
22657 didWarnAboutRevealOrder[revealOrder] = true;
22658
22659 if (typeof revealOrder === 'string') {
22660 switch (revealOrder.toLowerCase()) {
22661 case 'together':
22662 case 'forwards':
22663 case 'backwards':
22664 {
22665 error('"%s" is not a valid value for revealOrder on <SuspenseList />. ' + 'Use lowercase "%s" instead.', revealOrder, revealOrder.toLowerCase());
22666
22667 break;
22668 }
22669
22670 case 'forward':
22671 case 'backward':
22672 {
22673 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());
22674
22675 break;
22676 }
22677
22678 default:
22679 error('"%s" is not a supported revealOrder on <SuspenseList />. ' + 'Did you mean "together", "forwards" or "backwards"?', revealOrder);
22680
22681 break;
22682 }
22683 } else {
22684 error('%s is not a supported value for revealOrder on <SuspenseList />. ' + 'Did you mean "together", "forwards" or "backwards"?', revealOrder);
22685 }
22686 }
22687 }
22688}
22689
22690function validateTailOptions(tailMode, revealOrder) {
22691 {
22692 if (tailMode !== undefined && !didWarnAboutTailOptions[tailMode]) {
22693 if (tailMode !== 'collapsed' && tailMode !== 'hidden') {
22694 didWarnAboutTailOptions[tailMode] = true;
22695
22696 error('"%s" is not a supported value for tail on <SuspenseList />. ' + 'Did you mean "collapsed" or "hidden"?', tailMode);
22697 } else if (revealOrder !== 'forwards' && revealOrder !== 'backwards') {
22698 didWarnAboutTailOptions[tailMode] = true;
22699
22700 error('<SuspenseList tail="%s" /> is only valid if revealOrder is ' + '"forwards" or "backwards". ' + 'Did you mean to specify revealOrder="forwards"?', tailMode);
22701 }
22702 }
22703 }
22704}
22705
22706function validateSuspenseListNestedChild(childSlot, index) {
22707 {
22708 var isAnArray = isArray(childSlot);
22709 var isIterable = !isAnArray && typeof getIteratorFn(childSlot) === 'function';
22710
22711 if (isAnArray || isIterable) {
22712 var type = isAnArray ? 'array' : 'iterable';
22713
22714 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);
22715
22716 return false;
22717 }
22718 }
22719
22720 return true;
22721}
22722
22723function validateSuspenseListChildren(children, revealOrder) {
22724 {
22725 if ((revealOrder === 'forwards' || revealOrder === 'backwards') && children !== undefined && children !== null && children !== false) {
22726 if (isArray(children)) {
22727 for (var i = 0; i < children.length; i++) {
22728 if (!validateSuspenseListNestedChild(children[i], i)) {
22729 return;
22730 }
22731 }
22732 } else {
22733 var iteratorFn = getIteratorFn(children);
22734
22735 if (typeof iteratorFn === 'function') {
22736 var childrenIterator = iteratorFn.call(children);
22737
22738 if (childrenIterator) {
22739 var step = childrenIterator.next();
22740 var _i = 0;
22741
22742 for (; !step.done; step = childrenIterator.next()) {
22743 if (!validateSuspenseListNestedChild(step.value, _i)) {
22744 return;
22745 }
22746
22747 _i++;
22748 }
22749 }
22750 } else {
22751 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);
22752 }
22753 }
22754 }
22755 }
22756}
22757
22758function initSuspenseListRenderState(workInProgress, isBackwards, tail, lastContentRow, tailMode) {
22759 var renderState = workInProgress.memoizedState;
22760
22761 if (renderState === null) {
22762 workInProgress.memoizedState = {
22763 isBackwards: isBackwards,
22764 rendering: null,
22765 renderingStartTime: 0,
22766 last: lastContentRow,
22767 tail: tail,
22768 tailMode: tailMode
22769 };
22770 } else {
22771 // We can reuse the existing object from previous renders.
22772 renderState.isBackwards = isBackwards;
22773 renderState.rendering = null;
22774 renderState.renderingStartTime = 0;
22775 renderState.last = lastContentRow;
22776 renderState.tail = tail;
22777 renderState.tailMode = tailMode;
22778 }
22779} // This can end up rendering this component multiple passes.
22780// The first pass splits the children fibers into two sets. A head and tail.
22781// We first render the head. If anything is in fallback state, we do another
22782// pass through beginWork to rerender all children (including the tail) with
22783// the force suspend context. If the first render didn't have anything in
22784// in fallback state. Then we render each row in the tail one-by-one.
22785// That happens in the completeWork phase without going back to beginWork.
22786
22787
22788function updateSuspenseListComponent(current, workInProgress, renderLanes) {
22789 var nextProps = workInProgress.pendingProps;
22790 var revealOrder = nextProps.revealOrder;
22791 var tailMode = nextProps.tail;
22792 var newChildren = nextProps.children;
22793 validateRevealOrder(revealOrder);
22794 validateTailOptions(tailMode, revealOrder);
22795 validateSuspenseListChildren(newChildren, revealOrder);
22796 reconcileChildren(current, workInProgress, newChildren, renderLanes);
22797 var suspenseContext = suspenseStackCursor.current;
22798 var shouldForceFallback = hasSuspenseListContext(suspenseContext, ForceSuspenseFallback);
22799
22800 if (shouldForceFallback) {
22801 suspenseContext = setShallowSuspenseListContext(suspenseContext, ForceSuspenseFallback);
22802 workInProgress.flags |= DidCapture;
22803 } else {
22804 var didSuspendBefore = current !== null && (current.flags & DidCapture) !== NoFlags$1;
22805
22806 if (didSuspendBefore) {
22807 // If we previously forced a fallback, we need to schedule work
22808 // on any nested boundaries to let them know to try to render
22809 // again. This is the same as context updating.
22810 propagateSuspenseContextChange(workInProgress, workInProgress.child, renderLanes);
22811 }
22812
22813 suspenseContext = setDefaultShallowSuspenseListContext(suspenseContext);
22814 }
22815
22816 pushSuspenseListContext(workInProgress, suspenseContext);
22817
22818 {
22819 switch (revealOrder) {
22820 case 'forwards':
22821 {
22822 var lastContentRow = findLastContentRow(workInProgress.child);
22823 var tail;
22824
22825 if (lastContentRow === null) {
22826 // The whole list is part of the tail.
22827 // TODO: We could fast path by just rendering the tail now.
22828 tail = workInProgress.child;
22829 workInProgress.child = null;
22830 } else {
22831 // Disconnect the tail rows after the content row.
22832 // We're going to render them separately later.
22833 tail = lastContentRow.sibling;
22834 lastContentRow.sibling = null;
22835 }
22836
22837 initSuspenseListRenderState(workInProgress, false, // isBackwards
22838 tail, lastContentRow, tailMode);
22839 break;
22840 }
22841
22842 case 'backwards':
22843 {
22844 // We're going to find the first row that has existing content.
22845 // At the same time we're going to reverse the list of everything
22846 // we pass in the meantime. That's going to be our tail in reverse
22847 // order.
22848 var _tail = null;
22849 var row = workInProgress.child;
22850 workInProgress.child = null;
22851
22852 while (row !== null) {
22853 var currentRow = row.alternate; // New rows can't be content rows.
22854
22855 if (currentRow !== null && findFirstSuspended(currentRow) === null) {
22856 // This is the beginning of the main content.
22857 workInProgress.child = row;
22858 break;
22859 }
22860
22861 var nextRow = row.sibling;
22862 row.sibling = _tail;
22863 _tail = row;
22864 row = nextRow;
22865 } // TODO: If workInProgress.child is null, we can continue on the tail immediately.
22866
22867
22868 initSuspenseListRenderState(workInProgress, true, // isBackwards
22869 _tail, null, // last
22870 tailMode);
22871 break;
22872 }
22873
22874 case 'together':
22875 {
22876 initSuspenseListRenderState(workInProgress, false, // isBackwards
22877 null, // tail
22878 null, // last
22879 undefined);
22880 break;
22881 }
22882
22883 default:
22884 {
22885 // The default reveal order is the same as not having
22886 // a boundary.
22887 workInProgress.memoizedState = null;
22888 }
22889 }
22890 }
22891
22892 return workInProgress.child;
22893}
22894
22895function updatePortalComponent(current, workInProgress, renderLanes) {
22896 pushHostContainer(workInProgress, workInProgress.stateNode.containerInfo);
22897 var nextChildren = workInProgress.pendingProps;
22898
22899 if (current === null) {
22900 // Portals are special because we don't append the children during mount
22901 // but at commit. Therefore we need to track insertions which the normal
22902 // flow doesn't do during mount. This doesn't happen at the root because
22903 // the root always starts with a "current" with a null child.
22904 // TODO: Consider unifying this with how the root works.
22905 workInProgress.child = reconcileChildFibers(workInProgress, null, nextChildren, renderLanes);
22906 } else {
22907 reconcileChildren(current, workInProgress, nextChildren, renderLanes);
22908 }
22909
22910 return workInProgress.child;
22911}
22912
22913var hasWarnedAboutUsingNoValuePropOnContextProvider = false;
22914
22915function updateContextProvider(current, workInProgress, renderLanes) {
22916 var context;
22917
22918 {
22919 context = workInProgress.type;
22920 }
22921
22922 var newProps = workInProgress.pendingProps;
22923 var oldProps = workInProgress.memoizedProps;
22924 var newValue = newProps.value;
22925
22926 {
22927 if (!('value' in newProps)) {
22928 if (!hasWarnedAboutUsingNoValuePropOnContextProvider) {
22929 hasWarnedAboutUsingNoValuePropOnContextProvider = true;
22930
22931 error('The `value` prop is required for the `<Context.Provider>`. Did you misspell it or forget to pass it?');
22932 }
22933 }
22934 }
22935
22936 pushProvider(workInProgress, context, newValue);
22937
22938 {
22939 if (oldProps !== null) {
22940 var oldValue = oldProps.value;
22941
22942 if (objectIs(oldValue, newValue)) {
22943 // No change. Bailout early if children are the same.
22944 if (oldProps.children === newProps.children && !hasContextChanged()) {
22945 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes);
22946 }
22947 } else {
22948 // The context value changed. Search for matching consumers and schedule
22949 // them to update.
22950 propagateContextChange(workInProgress, context, renderLanes);
22951 }
22952 }
22953 }
22954
22955 var newChildren = newProps.children;
22956 reconcileChildren(current, workInProgress, newChildren, renderLanes);
22957 return workInProgress.child;
22958}
22959
22960function updateContextConsumer(current, workInProgress, renderLanes) {
22961 var context;
22962
22963 {
22964 var consumerType = workInProgress.type;
22965 context = consumerType._context;
22966 }
22967
22968 var newProps = workInProgress.pendingProps;
22969 var render = newProps.children;
22970
22971 {
22972 if (typeof render !== 'function') {
22973 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.');
22974 }
22975 }
22976
22977 prepareToReadContext(workInProgress, renderLanes);
22978 var newValue = readContext(context);
22979
22980 {
22981 markComponentRenderStarted(workInProgress);
22982 }
22983
22984 var newChildren;
22985
22986 {
22987 setCurrentOwner(workInProgress);
22988 setIsRendering(true);
22989 newChildren = render(newValue);
22990 setIsRendering(false);
22991 }
22992
22993 {
22994 markComponentRenderStopped();
22995 } // React DevTools reads this flag.
22996
22997
22998 workInProgress.flags |= PerformedWork;
22999 reconcileChildren(current, workInProgress, newChildren, renderLanes);
23000 return workInProgress.child;
23001}
23002
23003function markWorkInProgressReceivedUpdate() {
23004 didReceiveUpdate = true;
23005}
23006
23007function bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes) {
23008 if (current !== null) {
23009 // Reuse previous dependencies
23010 workInProgress.dependencies = current.dependencies;
23011 }
23012
23013 {
23014 // Don't update "base" render times for bailouts.
23015 stopProfilerTimerIfRunning();
23016 }
23017
23018 markSkippedUpdateLanes(workInProgress.lanes); // Check if the children have any pending work.
23019
23020 if (!includesSomeLane(renderLanes, workInProgress.childLanes)) {
23021 // The children don't have any work either. We can skip them.
23022 // TODO: Once we add back resuming, we should check if the children are
23023 // a work-in-progress set. If so, we need to transfer their effects.
23024 {
23025 return null;
23026 }
23027 } // This fiber doesn't have work, but its subtree does. Clone the child
23028 // fibers and continue.
23029
23030
23031 cloneChildFibers(current, workInProgress);
23032 return workInProgress.child;
23033}
23034
23035function remountFiber(current, oldWorkInProgress, newWorkInProgress) {
23036 {
23037 var returnFiber = oldWorkInProgress.return;
23038
23039 if (returnFiber === null) {
23040 // eslint-disable-next-line react-internal/prod-error-codes
23041 throw new Error('Cannot swap the root fiber.');
23042 } // Disconnect from the old current.
23043 // It will get deleted.
23044
23045
23046 current.alternate = null;
23047 oldWorkInProgress.alternate = null; // Connect to the new tree.
23048
23049 newWorkInProgress.index = oldWorkInProgress.index;
23050 newWorkInProgress.sibling = oldWorkInProgress.sibling;
23051 newWorkInProgress.return = oldWorkInProgress.return;
23052 newWorkInProgress.ref = oldWorkInProgress.ref;
23053
23054 {
23055 newWorkInProgress._debugInfo = oldWorkInProgress._debugInfo;
23056 } // Replace the child/sibling pointers above it.
23057
23058
23059 if (oldWorkInProgress === returnFiber.child) {
23060 returnFiber.child = newWorkInProgress;
23061 } else {
23062 var prevSibling = returnFiber.child;
23063
23064 if (prevSibling === null) {
23065 // eslint-disable-next-line react-internal/prod-error-codes
23066 throw new Error('Expected parent to have a child.');
23067 } // $FlowFixMe[incompatible-use] found when upgrading Flow
23068
23069
23070 while (prevSibling.sibling !== oldWorkInProgress) {
23071 // $FlowFixMe[incompatible-use] found when upgrading Flow
23072 prevSibling = prevSibling.sibling;
23073
23074 if (prevSibling === null) {
23075 // eslint-disable-next-line react-internal/prod-error-codes
23076 throw new Error('Expected to find the previous sibling.');
23077 }
23078 } // $FlowFixMe[incompatible-use] found when upgrading Flow
23079
23080
23081 prevSibling.sibling = newWorkInProgress;
23082 } // Delete the old fiber and place the new one.
23083 // Since the old fiber is disconnected, we have to schedule it manually.
23084
23085
23086 var deletions = returnFiber.deletions;
23087
23088 if (deletions === null) {
23089 returnFiber.deletions = [current];
23090 returnFiber.flags |= ChildDeletion;
23091 } else {
23092 deletions.push(current);
23093 }
23094
23095 newWorkInProgress.flags |= Placement; // Restart work from the new fiber.
23096
23097 return newWorkInProgress;
23098 }
23099}
23100
23101function checkScheduledUpdateOrContext(current, renderLanes) {
23102 // Before performing an early bailout, we must check if there are pending
23103 // updates or context.
23104 var updateLanes = current.lanes;
23105
23106 if (includesSomeLane(updateLanes, renderLanes)) {
23107 return true;
23108 } // No pending update, but because context is propagated lazily, we need
23109
23110 return false;
23111}
23112
23113function attemptEarlyBailoutIfNoScheduledUpdate(current, workInProgress, renderLanes) {
23114 // This fiber does not have any pending work. Bailout without entering
23115 // the begin phase. There's still some bookkeeping we that needs to be done
23116 // in this optimized path, mostly pushing stuff onto the stack.
23117 switch (workInProgress.tag) {
23118 case HostRoot:
23119 pushHostRootContext(workInProgress);
23120
23121 {
23122 var cache = current.memoizedState.cache;
23123 pushCacheProvider(workInProgress, cache);
23124 }
23125
23126 resetHydrationState();
23127 break;
23128
23129 case HostSingleton:
23130 case HostComponent:
23131 pushHostContext(workInProgress);
23132 break;
23133
23134 case ClassComponent:
23135 {
23136
23137 break;
23138 }
23139
23140 case HostPortal:
23141 pushHostContainer(workInProgress, workInProgress.stateNode.containerInfo);
23142 break;
23143
23144 case ContextProvider:
23145 {
23146 var newValue = workInProgress.memoizedProps.value;
23147 var context;
23148
23149 {
23150 context = workInProgress.type;
23151 }
23152
23153 pushProvider(workInProgress, context, newValue);
23154 break;
23155 }
23156
23157 case Profiler:
23158 {
23159 // Profiler should only call onRender when one of its descendants actually rendered.
23160 var hasChildWork = includesSomeLane(renderLanes, workInProgress.childLanes);
23161
23162 if (hasChildWork) {
23163 workInProgress.flags |= Update;
23164 }
23165
23166 {
23167 // Reset effect durations for the next eventual effect phase.
23168 // These are reset during render to allow the DevTools commit hook a chance to read them,
23169 var stateNode = workInProgress.stateNode;
23170 stateNode.effectDuration = 0;
23171 stateNode.passiveEffectDuration = 0;
23172 }
23173 }
23174
23175 break;
23176
23177 case SuspenseComponent:
23178 {
23179 var state = workInProgress.memoizedState;
23180
23181 if (state !== null) {
23182 if (state.dehydrated !== null) {
23183 // We're not going to render the children, so this is just to maintain
23184 // push/pop symmetry
23185 pushPrimaryTreeSuspenseHandler(workInProgress); // We know that this component will suspend again because if it has
23186 // been unsuspended it has committed as a resolved Suspense component.
23187 // If it needs to be retried, it should have work scheduled on it.
23188
23189 workInProgress.flags |= DidCapture; // We should never render the children of a dehydrated boundary until we
23190 // upgrade it. We return null instead of bailoutOnAlreadyFinishedWork.
23191
23192 return null;
23193 } // If this boundary is currently timed out, we need to decide
23194 // whether to retry the primary children, or to skip over it and
23195 // go straight to the fallback. Check the priority of the primary
23196 // child fragment.
23197
23198
23199 var primaryChildFragment = workInProgress.child;
23200 var primaryChildLanes = primaryChildFragment.childLanes;
23201
23202 if (includesSomeLane(renderLanes, primaryChildLanes)) {
23203 // The primary children have pending work. Use the normal path
23204 // to attempt to render the primary children again.
23205 return updateSuspenseComponent(current, workInProgress, renderLanes);
23206 } else {
23207 // The primary child fragment does not have pending work marked
23208 // on it
23209 pushPrimaryTreeSuspenseHandler(workInProgress); // The primary children do not have pending work with sufficient
23210 // priority. Bailout.
23211
23212 var child = bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes);
23213
23214 if (child !== null) {
23215 // The fallback children have pending work. Skip over the
23216 // primary children and work on the fallback.
23217 return child.sibling;
23218 } else {
23219 // Note: We can return `null` here because we already checked
23220 // whether there were nested context consumers, via the call to
23221 // `bailoutOnAlreadyFinishedWork` above.
23222 return null;
23223 }
23224 }
23225 } else {
23226 pushPrimaryTreeSuspenseHandler(workInProgress);
23227 }
23228
23229 break;
23230 }
23231
23232 case SuspenseListComponent:
23233 {
23234 var didSuspendBefore = (current.flags & DidCapture) !== NoFlags$1;
23235
23236 var _hasChildWork = includesSomeLane(renderLanes, workInProgress.childLanes);
23237
23238 if (didSuspendBefore) {
23239 if (_hasChildWork) {
23240 // If something was in fallback state last time, and we have all the
23241 // same children then we're still in progressive loading state.
23242 // Something might get unblocked by state updates or retries in the
23243 // tree which will affect the tail. So we need to use the normal
23244 // path to compute the correct tail.
23245 return updateSuspenseListComponent(current, workInProgress, renderLanes);
23246 } // If none of the children had any work, that means that none of
23247 // them got retried so they'll still be blocked in the same way
23248 // as before. We can fast bail out.
23249
23250
23251 workInProgress.flags |= DidCapture;
23252 } // If nothing suspended before and we're rendering the same children,
23253 // then the tail doesn't matter. Anything new that suspends will work
23254 // in the "together" mode, so we can continue from the state we had.
23255
23256
23257 var renderState = workInProgress.memoizedState;
23258
23259 if (renderState !== null) {
23260 // Reset to the "together" mode in case we've started a different
23261 // update in the past but didn't complete it.
23262 renderState.rendering = null;
23263 renderState.tail = null;
23264 renderState.lastEffect = null;
23265 }
23266
23267 pushSuspenseListContext(workInProgress, suspenseStackCursor.current);
23268
23269 if (_hasChildWork) {
23270 break;
23271 } else {
23272 // If none of the children had any work, that means that none of
23273 // them got retried so they'll still be blocked in the same way
23274 // as before. We can fast bail out.
23275 return null;
23276 }
23277 }
23278
23279 case OffscreenComponent:
23280 case LegacyHiddenComponent:
23281 {
23282 // Need to check if the tree still needs to be deferred. This is
23283 // almost identical to the logic used in the normal update path,
23284 // so we'll just enter that. The only difference is we'll bail out
23285 // at the next level instead of this one, because the child props
23286 // have not changed. Which is fine.
23287 // TODO: Probably should refactor `beginWork` to split the bailout
23288 // path from the normal path. I'm tempted to do a labeled break here
23289 // but I won't :)
23290 workInProgress.lanes = NoLanes;
23291 return updateOffscreenComponent(current, workInProgress, renderLanes);
23292 }
23293
23294 case CacheComponent:
23295 {
23296 {
23297 var _cache = current.memoizedState.cache;
23298 pushCacheProvider(workInProgress, _cache);
23299 }
23300
23301 break;
23302 }
23303 }
23304
23305 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes);
23306}
23307
23308function beginWork(current, workInProgress, renderLanes) {
23309 {
23310 if (workInProgress._debugNeedsRemount && current !== null) {
23311 // This will restart the begin phase with a new fiber.
23312 return remountFiber(current, workInProgress, createFiberFromTypeAndProps(workInProgress.type, workInProgress.key, workInProgress.pendingProps, workInProgress._debugOwner || null, workInProgress.mode, workInProgress.lanes));
23313 }
23314 }
23315
23316 if (current !== null) {
23317 var oldProps = current.memoizedProps;
23318 var newProps = workInProgress.pendingProps;
23319
23320 if (oldProps !== newProps || hasContextChanged() || ( // Force a re-render if the implementation changed due to hot reload:
23321 workInProgress.type !== current.type )) {
23322 // If props or context changed, mark the fiber as having performed work.
23323 // This may be unset if the props are determined to be equal later (memo).
23324 didReceiveUpdate = true;
23325 } else {
23326 // Neither props nor legacy context changes. Check if there's a pending
23327 // update or context change.
23328 var hasScheduledUpdateOrContext = checkScheduledUpdateOrContext(current, renderLanes);
23329
23330 if (!hasScheduledUpdateOrContext && // If this is the second pass of an error or suspense boundary, there
23331 // may not be work scheduled on `current`, so we check for this flag.
23332 (workInProgress.flags & DidCapture) === NoFlags$1) {
23333 // No pending updates or context. Bail out now.
23334 didReceiveUpdate = false;
23335 return attemptEarlyBailoutIfNoScheduledUpdate(current, workInProgress, renderLanes);
23336 }
23337
23338 if ((current.flags & ForceUpdateForLegacySuspense) !== NoFlags$1) {
23339 // This is a special case that only exists for legacy mode.
23340 // See https://github.com/facebook/react/pull/19216.
23341 didReceiveUpdate = true;
23342 } else {
23343 // An update was scheduled on this fiber, but there are no new props
23344 // nor legacy context. Set this to false. If an update queue or context
23345 // consumer produces a changed value, it will set this to true. Otherwise,
23346 // the component will assume the children have not changed and bail out.
23347 didReceiveUpdate = false;
23348 }
23349 }
23350 } else {
23351 didReceiveUpdate = false;
23352
23353 if (getIsHydrating() && isForkedChild(workInProgress)) {
23354 // Check if this child belongs to a list of muliple children in
23355 // its parent.
23356 //
23357 // In a true multi-threaded implementation, we would render children on
23358 // parallel threads. This would represent the beginning of a new render
23359 // thread for this subtree.
23360 //
23361 // We only use this for id generation during hydration, which is why the
23362 // logic is located in this special branch.
23363 var slotIndex = workInProgress.index;
23364 var numberOfForks = getForksAtLevel();
23365 pushTreeId(workInProgress, numberOfForks, slotIndex);
23366 }
23367 } // Before entering the begin phase, clear pending update priority.
23368 // TODO: This assumes that we're about to evaluate the component and process
23369 // the update queue. However, there's an exception: SimpleMemoComponent
23370 // sometimes bails out later in the begin phase. This indicates that we should
23371 // move this assignment out of the common path and into each branch.
23372
23373
23374 workInProgress.lanes = NoLanes;
23375
23376 switch (workInProgress.tag) {
23377 case LazyComponent:
23378 {
23379 var elementType = workInProgress.elementType;
23380 return mountLazyComponent(current, workInProgress, elementType, renderLanes);
23381 }
23382
23383 case FunctionComponent:
23384 {
23385 var Component = workInProgress.type;
23386 var unresolvedProps = workInProgress.pendingProps;
23387 var resolvedProps = unresolvedProps ;
23388 return updateFunctionComponent(current, workInProgress, Component, resolvedProps, renderLanes);
23389 }
23390
23391 case ClassComponent:
23392 {
23393 var _Component = workInProgress.type;
23394 var _unresolvedProps = workInProgress.pendingProps;
23395
23396 var _resolvedProps4 = resolveClassComponentProps(_Component, _unresolvedProps);
23397
23398 return updateClassComponent(current, workInProgress, _Component, _resolvedProps4, renderLanes);
23399 }
23400
23401 case HostRoot:
23402 return updateHostRoot(current, workInProgress, renderLanes);
23403
23404 case HostHoistable:
23405 {
23406 return updateHostHoistable(current, workInProgress);
23407 }
23408
23409 // Fall through
23410
23411 case HostSingleton:
23412 {
23413 return updateHostSingleton(current, workInProgress, renderLanes);
23414 }
23415
23416 // Fall through
23417
23418 case HostComponent:
23419 return updateHostComponent$1(current, workInProgress, renderLanes);
23420
23421 case HostText:
23422 return updateHostText$1(current, workInProgress);
23423
23424 case SuspenseComponent:
23425 return updateSuspenseComponent(current, workInProgress, renderLanes);
23426
23427 case HostPortal:
23428 return updatePortalComponent(current, workInProgress, renderLanes);
23429
23430 case ForwardRef:
23431 {
23432 var type = workInProgress.type;
23433 var _unresolvedProps2 = workInProgress.pendingProps;
23434
23435 var _resolvedProps5 = _unresolvedProps2 ;
23436
23437 return updateForwardRef(current, workInProgress, type, _resolvedProps5, renderLanes);
23438 }
23439
23440 case Fragment:
23441 return updateFragment(current, workInProgress, renderLanes);
23442
23443 case Mode:
23444 return updateMode(current, workInProgress, renderLanes);
23445
23446 case Profiler:
23447 return updateProfiler(current, workInProgress, renderLanes);
23448
23449 case ContextProvider:
23450 return updateContextProvider(current, workInProgress, renderLanes);
23451
23452 case ContextConsumer:
23453 return updateContextConsumer(current, workInProgress, renderLanes);
23454
23455 case MemoComponent:
23456 {
23457 var _type = workInProgress.type;
23458 var _unresolvedProps3 = workInProgress.pendingProps; // Resolve outer props first, then resolve inner props.
23459
23460 var _resolvedProps6 = _unresolvedProps3 ;
23461
23462 _resolvedProps6 = _resolvedProps6 ;
23463 return updateMemoComponent(current, workInProgress, _type, _resolvedProps6, renderLanes);
23464 }
23465
23466 case SimpleMemoComponent:
23467 {
23468 return updateSimpleMemoComponent(current, workInProgress, workInProgress.type, workInProgress.pendingProps, renderLanes);
23469 }
23470
23471 case IncompleteClassComponent:
23472 {
23473 {
23474 break;
23475 }
23476 }
23477
23478 case IncompleteFunctionComponent:
23479 {
23480 {
23481 break;
23482 }
23483 }
23484
23485 case SuspenseListComponent:
23486 {
23487 return updateSuspenseListComponent(current, workInProgress, renderLanes);
23488 }
23489
23490 case ScopeComponent:
23491 {
23492
23493 break;
23494 }
23495
23496 case OffscreenComponent:
23497 {
23498 return updateOffscreenComponent(current, workInProgress, renderLanes);
23499 }
23500
23501 case LegacyHiddenComponent:
23502 {
23503
23504 break;
23505 }
23506
23507 case CacheComponent:
23508 {
23509 {
23510 return updateCacheComponent(current, workInProgress, renderLanes);
23511 }
23512 }
23513 }
23514
23515 throw new Error("Unknown unit of work tag (" + workInProgress.tag + "). This error is likely caused by a bug in " + 'React. Please file an issue.');
23516}
23517
23518var valueCursor = createCursor(null);
23519var rendererCursorDEV;
23520
23521{
23522 rendererCursorDEV = createCursor(null);
23523}
23524
23525var rendererSigil;
23526
23527{
23528 // Use this to detect multiple renderers using the same context
23529 rendererSigil = {};
23530}
23531
23532var currentlyRenderingFiber = null;
23533var lastContextDependency = null;
23534var lastFullyObservedContext = null;
23535var isDisallowedContextReadInDEV = false;
23536function resetContextDependencies() {
23537 // This is called right before React yields execution, to ensure `readContext`
23538 // cannot be called outside the render phase.
23539 currentlyRenderingFiber = null;
23540 lastContextDependency = null;
23541 lastFullyObservedContext = null;
23542
23543 {
23544 isDisallowedContextReadInDEV = false;
23545 }
23546}
23547function enterDisallowedContextReadInDEV() {
23548 {
23549 isDisallowedContextReadInDEV = true;
23550 }
23551}
23552function exitDisallowedContextReadInDEV() {
23553 {
23554 isDisallowedContextReadInDEV = false;
23555 }
23556}
23557function pushProvider(providerFiber, context, nextValue) {
23558 {
23559 push(valueCursor, context._currentValue, providerFiber);
23560 context._currentValue = nextValue;
23561
23562 {
23563 push(rendererCursorDEV, context._currentRenderer, providerFiber);
23564
23565 if (context._currentRenderer !== undefined && context._currentRenderer !== null && context._currentRenderer !== rendererSigil) {
23566 error('Detected multiple renderers concurrently rendering the ' + 'same context provider. This is currently unsupported.');
23567 }
23568
23569 context._currentRenderer = rendererSigil;
23570 }
23571 }
23572}
23573function popProvider(context, providerFiber) {
23574 var currentValue = valueCursor.current;
23575
23576 {
23577 context._currentValue = currentValue;
23578
23579 {
23580 var currentRenderer = rendererCursorDEV.current;
23581 pop(rendererCursorDEV, providerFiber);
23582 context._currentRenderer = currentRenderer;
23583 }
23584 }
23585
23586 pop(valueCursor, providerFiber);
23587}
23588function scheduleContextWorkOnParentPath(parent, renderLanes, propagationRoot) {
23589 // Update the child lanes of all the ancestors, including the alternates.
23590 var node = parent;
23591
23592 while (node !== null) {
23593 var alternate = node.alternate;
23594
23595 if (!isSubsetOfLanes(node.childLanes, renderLanes)) {
23596 node.childLanes = mergeLanes(node.childLanes, renderLanes);
23597
23598 if (alternate !== null) {
23599 alternate.childLanes = mergeLanes(alternate.childLanes, renderLanes);
23600 }
23601 } else if (alternate !== null && !isSubsetOfLanes(alternate.childLanes, renderLanes)) {
23602 alternate.childLanes = mergeLanes(alternate.childLanes, renderLanes);
23603 } else ;
23604
23605 if (node === propagationRoot) {
23606 break;
23607 }
23608
23609 node = node.return;
23610 }
23611
23612 {
23613 if (node !== propagationRoot) {
23614 error('Expected to find the propagation root when scheduling context work. ' + 'This error is likely caused by a bug in React. Please file an issue.');
23615 }
23616 }
23617}
23618function propagateContextChange(workInProgress, context, renderLanes) {
23619 {
23620 propagateContextChange_eager(workInProgress, context, renderLanes);
23621 }
23622}
23623
23624function propagateContextChange_eager(workInProgress, context, renderLanes) {
23625
23626 var fiber = workInProgress.child;
23627
23628 if (fiber !== null) {
23629 // Set the return pointer of the child to the work-in-progress fiber.
23630 fiber.return = workInProgress;
23631 }
23632
23633 while (fiber !== null) {
23634 var nextFiber = void 0; // Visit this fiber.
23635
23636 var list = fiber.dependencies;
23637
23638 if (list !== null) {
23639 nextFiber = fiber.child;
23640 var dependency = list.firstContext;
23641
23642 while (dependency !== null) {
23643 // Check if the context matches.
23644 if (dependency.context === context) {
23645 // Match! Schedule an update on this fiber.
23646 if (fiber.tag === ClassComponent) {
23647 // Schedule a force update on the work-in-progress.
23648 var lane = pickArbitraryLane(renderLanes);
23649 var update = createUpdate(lane);
23650 update.tag = ForceUpdate; // TODO: Because we don't have a work-in-progress, this will add the
23651 // update to the current fiber, too, which means it will persist even if
23652 // this render is thrown away. Since it's a race condition, not sure it's
23653 // worth fixing.
23654 // Inlined `enqueueUpdate` to remove interleaved update check
23655
23656 var updateQueue = fiber.updateQueue;
23657
23658 if (updateQueue === null) ; else {
23659 var sharedQueue = updateQueue.shared;
23660 var pending = sharedQueue.pending;
23661
23662 if (pending === null) {
23663 // This is the first update. Create a circular list.
23664 update.next = update;
23665 } else {
23666 update.next = pending.next;
23667 pending.next = update;
23668 }
23669
23670 sharedQueue.pending = update;
23671 }
23672 }
23673
23674 fiber.lanes = mergeLanes(fiber.lanes, renderLanes);
23675 var alternate = fiber.alternate;
23676
23677 if (alternate !== null) {
23678 alternate.lanes = mergeLanes(alternate.lanes, renderLanes);
23679 }
23680
23681 scheduleContextWorkOnParentPath(fiber.return, renderLanes, workInProgress); // Mark the updated lanes on the list, too.
23682
23683 list.lanes = mergeLanes(list.lanes, renderLanes); // Since we already found a match, we can stop traversing the
23684 // dependency list.
23685
23686 break;
23687 }
23688
23689 dependency = dependency.next;
23690 }
23691 } else if (fiber.tag === ContextProvider) {
23692 // Don't scan deeper if this is a matching provider
23693 nextFiber = fiber.type === workInProgress.type ? null : fiber.child;
23694 } else if (fiber.tag === DehydratedFragment) {
23695 // If a dehydrated suspense boundary is in this subtree, we don't know
23696 // if it will have any context consumers in it. The best we can do is
23697 // mark it as having updates.
23698 var parentSuspense = fiber.return;
23699
23700 if (parentSuspense === null) {
23701 throw new Error('We just came from a parent so we must have had a parent. This is a bug in React.');
23702 }
23703
23704 parentSuspense.lanes = mergeLanes(parentSuspense.lanes, renderLanes);
23705 var _alternate = parentSuspense.alternate;
23706
23707 if (_alternate !== null) {
23708 _alternate.lanes = mergeLanes(_alternate.lanes, renderLanes);
23709 } // This is intentionally passing this fiber as the parent
23710 // because we want to schedule this fiber as having work
23711 // on its children. We'll use the childLanes on
23712 // this fiber to indicate that a context has changed.
23713
23714
23715 scheduleContextWorkOnParentPath(parentSuspense, renderLanes, workInProgress);
23716 nextFiber = fiber.sibling;
23717 } else {
23718 // Traverse down.
23719 nextFiber = fiber.child;
23720 }
23721
23722 if (nextFiber !== null) {
23723 // Set the return pointer of the child to the work-in-progress fiber.
23724 nextFiber.return = fiber;
23725 } else {
23726 // No child. Traverse to next sibling.
23727 nextFiber = fiber;
23728
23729 while (nextFiber !== null) {
23730 if (nextFiber === workInProgress) {
23731 // We're back to the root of this subtree. Exit.
23732 nextFiber = null;
23733 break;
23734 }
23735
23736 var sibling = nextFiber.sibling;
23737
23738 if (sibling !== null) {
23739 // Set the return pointer of the sibling to the work-in-progress fiber.
23740 sibling.return = nextFiber.return;
23741 nextFiber = sibling;
23742 break;
23743 } // No more siblings. Traverse up.
23744
23745
23746 nextFiber = nextFiber.return;
23747 }
23748 }
23749
23750 fiber = nextFiber;
23751 }
23752}
23753function prepareToReadContext(workInProgress, renderLanes) {
23754 currentlyRenderingFiber = workInProgress;
23755 lastContextDependency = null;
23756 lastFullyObservedContext = null;
23757 var dependencies = workInProgress.dependencies;
23758
23759 if (dependencies !== null) {
23760 {
23761 var firstContext = dependencies.firstContext;
23762
23763 if (firstContext !== null) {
23764 if (includesSomeLane(dependencies.lanes, renderLanes)) {
23765 // Context list has a pending update. Mark that this fiber performed work.
23766 markWorkInProgressReceivedUpdate();
23767 } // Reset the work-in-progress list
23768
23769
23770 dependencies.firstContext = null;
23771 }
23772 }
23773 }
23774}
23775function readContext(context) {
23776 {
23777 // This warning would fire if you read context inside a Hook like useMemo.
23778 // Unlike the class check below, it's not enforced in production for perf.
23779 if (isDisallowedContextReadInDEV) {
23780 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().');
23781 }
23782 }
23783
23784 return readContextForConsumer(currentlyRenderingFiber, context);
23785}
23786function readContextDuringReconciliation(consumer, context, renderLanes) {
23787 if (currentlyRenderingFiber === null) {
23788 prepareToReadContext(consumer, renderLanes);
23789 }
23790
23791 return readContextForConsumer(consumer, context);
23792}
23793
23794function readContextForConsumer(consumer, context) {
23795 var value = context._currentValue ;
23796
23797 if (lastFullyObservedContext === context) ; else {
23798 var contextItem = {
23799 context: context,
23800 memoizedValue: value,
23801 next: null
23802 };
23803
23804 if (lastContextDependency === null) {
23805 if (consumer === null) {
23806 throw new 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().');
23807 } // This is the first dependency for this component. Create a new list.
23808
23809
23810 lastContextDependency = contextItem;
23811 consumer.dependencies = {
23812 lanes: NoLanes,
23813 firstContext: contextItem
23814 };
23815 } else {
23816 // Append a new context item.
23817 lastContextDependency = lastContextDependency.next = contextItem;
23818 }
23819 }
23820
23821 return value;
23822}
23823
23824var UpdateState = 0;
23825var ReplaceState = 1;
23826var ForceUpdate = 2;
23827var CaptureUpdate = 3; // Global state that is reset at the beginning of calling `processUpdateQueue`.
23828// It should only be read right after calling `processUpdateQueue`, via
23829// `checkHasForceUpdateAfterProcessing`.
23830
23831var hasForceUpdate = false;
23832var didWarnUpdateInsideUpdate;
23833var currentlyProcessingQueue;
23834
23835{
23836 didWarnUpdateInsideUpdate = false;
23837 currentlyProcessingQueue = null;
23838}
23839
23840function initializeUpdateQueue(fiber) {
23841 var queue = {
23842 baseState: fiber.memoizedState,
23843 firstBaseUpdate: null,
23844 lastBaseUpdate: null,
23845 shared: {
23846 pending: null,
23847 lanes: NoLanes,
23848 hiddenCallbacks: null
23849 },
23850 callbacks: null
23851 };
23852 fiber.updateQueue = queue;
23853}
23854function cloneUpdateQueue(current, workInProgress) {
23855 // Clone the update queue from current. Unless it's already a clone.
23856 var queue = workInProgress.updateQueue;
23857 var currentQueue = current.updateQueue;
23858
23859 if (queue === currentQueue) {
23860 var clone = {
23861 baseState: currentQueue.baseState,
23862 firstBaseUpdate: currentQueue.firstBaseUpdate,
23863 lastBaseUpdate: currentQueue.lastBaseUpdate,
23864 shared: currentQueue.shared,
23865 callbacks: null
23866 };
23867 workInProgress.updateQueue = clone;
23868 }
23869}
23870function createUpdate(lane) {
23871 var update = {
23872 lane: lane,
23873 tag: UpdateState,
23874 payload: null,
23875 callback: null,
23876 next: null
23877 };
23878 return update;
23879}
23880function enqueueUpdate(fiber, update, lane) {
23881 var updateQueue = fiber.updateQueue;
23882
23883 if (updateQueue === null) {
23884 // Only occurs if the fiber has been unmounted.
23885 return null;
23886 }
23887
23888 var sharedQueue = updateQueue.shared;
23889
23890 {
23891 if (currentlyProcessingQueue === sharedQueue && !didWarnUpdateInsideUpdate) {
23892 var componentName = getComponentNameFromFiber(fiber);
23893
23894 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.\n\nPlease update the following component: %s', componentName);
23895
23896 didWarnUpdateInsideUpdate = true;
23897 }
23898 }
23899
23900 if (isUnsafeClassRenderPhaseUpdate()) {
23901 // This is an unsafe render phase update. Add directly to the update
23902 // queue so we can process it immediately during the current render.
23903 var pending = sharedQueue.pending;
23904
23905 if (pending === null) {
23906 // This is the first update. Create a circular list.
23907 update.next = update;
23908 } else {
23909 update.next = pending.next;
23910 pending.next = update;
23911 }
23912
23913 sharedQueue.pending = update; // Update the childLanes even though we're most likely already rendering
23914 // this fiber. This is for backwards compatibility in the case where you
23915 // update a different component during render phase than the one that is
23916 // currently renderings (a pattern that is accompanied by a warning).
23917
23918 return unsafe_markUpdateLaneFromFiberToRoot(fiber, lane);
23919 } else {
23920 return enqueueConcurrentClassUpdate(fiber, sharedQueue, update, lane);
23921 }
23922}
23923function entangleTransitions(root, fiber, lane) {
23924 var updateQueue = fiber.updateQueue;
23925
23926 if (updateQueue === null) {
23927 // Only occurs if the fiber has been unmounted.
23928 return;
23929 }
23930
23931 var sharedQueue = updateQueue.shared;
23932
23933 if (isTransitionLane(lane)) {
23934 var queueLanes = sharedQueue.lanes; // If any entangled lanes are no longer pending on the root, then they must
23935 // have finished. We can remove them from the shared queue, which represents
23936 // a superset of the actually pending lanes. In some cases we may entangle
23937 // more than we need to, but that's OK. In fact it's worse if we *don't*
23938 // entangle when we should.
23939
23940 queueLanes = intersectLanes(queueLanes, root.pendingLanes); // Entangle the new transition lane with the other transition lanes.
23941
23942 var newQueueLanes = mergeLanes(queueLanes, lane);
23943 sharedQueue.lanes = newQueueLanes; // Even if queue.lanes already include lane, we don't know for certain if
23944 // the lane finished since the last time we entangled it. So we need to
23945 // entangle it again, just to be sure.
23946
23947 markRootEntangled(root, newQueueLanes);
23948 }
23949}
23950function enqueueCapturedUpdate(workInProgress, capturedUpdate) {
23951 // Captured updates are updates that are thrown by a child during the render
23952 // phase. They should be discarded if the render is aborted. Therefore,
23953 // we should only put them on the work-in-progress queue, not the current one.
23954 var queue = workInProgress.updateQueue; // Check if the work-in-progress queue is a clone.
23955
23956 var current = workInProgress.alternate;
23957
23958 if (current !== null) {
23959 var currentQueue = current.updateQueue;
23960
23961 if (queue === currentQueue) {
23962 // The work-in-progress queue is the same as current. This happens when
23963 // we bail out on a parent fiber that then captures an error thrown by
23964 // a child. Since we want to append the update only to the work-in
23965 // -progress queue, we need to clone the updates. We usually clone during
23966 // processUpdateQueue, but that didn't happen in this case because we
23967 // skipped over the parent when we bailed out.
23968 var newFirst = null;
23969 var newLast = null;
23970 var firstBaseUpdate = queue.firstBaseUpdate;
23971
23972 if (firstBaseUpdate !== null) {
23973 // Loop through the updates and clone them.
23974 var update = firstBaseUpdate;
23975
23976 do {
23977 var clone = {
23978 lane: update.lane,
23979 tag: update.tag,
23980 payload: update.payload,
23981 // When this update is rebased, we should not fire its
23982 // callback again.
23983 callback: null,
23984 next: null
23985 };
23986
23987 if (newLast === null) {
23988 newFirst = newLast = clone;
23989 } else {
23990 newLast.next = clone;
23991 newLast = clone;
23992 } // $FlowFixMe[incompatible-type] we bail out when we get a null
23993
23994
23995 update = update.next;
23996 } while (update !== null); // Append the captured update the end of the cloned list.
23997
23998
23999 if (newLast === null) {
24000 newFirst = newLast = capturedUpdate;
24001 } else {
24002 newLast.next = capturedUpdate;
24003 newLast = capturedUpdate;
24004 }
24005 } else {
24006 // There are no base updates.
24007 newFirst = newLast = capturedUpdate;
24008 }
24009
24010 queue = {
24011 baseState: currentQueue.baseState,
24012 firstBaseUpdate: newFirst,
24013 lastBaseUpdate: newLast,
24014 shared: currentQueue.shared,
24015 callbacks: currentQueue.callbacks
24016 };
24017 workInProgress.updateQueue = queue;
24018 return;
24019 }
24020 } // Append the update to the end of the list.
24021
24022
24023 var lastBaseUpdate = queue.lastBaseUpdate;
24024
24025 if (lastBaseUpdate === null) {
24026 queue.firstBaseUpdate = capturedUpdate;
24027 } else {
24028 lastBaseUpdate.next = capturedUpdate;
24029 }
24030
24031 queue.lastBaseUpdate = capturedUpdate;
24032}
24033
24034function getStateFromUpdate(workInProgress, queue, update, prevState, nextProps, instance) {
24035 switch (update.tag) {
24036 case ReplaceState:
24037 {
24038 var payload = update.payload;
24039
24040 if (typeof payload === 'function') {
24041 // Updater function
24042 {
24043 enterDisallowedContextReadInDEV();
24044 }
24045
24046 var nextState = payload.call(instance, prevState, nextProps);
24047
24048 {
24049 if (workInProgress.mode & StrictLegacyMode) {
24050 setIsStrictModeForDevtools(true);
24051
24052 try {
24053 payload.call(instance, prevState, nextProps);
24054 } finally {
24055 setIsStrictModeForDevtools(false);
24056 }
24057 }
24058
24059 exitDisallowedContextReadInDEV();
24060 }
24061
24062 return nextState;
24063 } // State object
24064
24065
24066 return payload;
24067 }
24068
24069 case CaptureUpdate:
24070 {
24071 workInProgress.flags = workInProgress.flags & ~ShouldCapture | DidCapture;
24072 }
24073 // Intentional fallthrough
24074
24075 case UpdateState:
24076 {
24077 var _payload = update.payload;
24078 var partialState;
24079
24080 if (typeof _payload === 'function') {
24081 // Updater function
24082 {
24083 enterDisallowedContextReadInDEV();
24084 }
24085
24086 partialState = _payload.call(instance, prevState, nextProps);
24087
24088 {
24089 if (workInProgress.mode & StrictLegacyMode) {
24090 setIsStrictModeForDevtools(true);
24091
24092 try {
24093 _payload.call(instance, prevState, nextProps);
24094 } finally {
24095 setIsStrictModeForDevtools(false);
24096 }
24097 }
24098
24099 exitDisallowedContextReadInDEV();
24100 }
24101 } else {
24102 // Partial state object
24103 partialState = _payload;
24104 }
24105
24106 if (partialState === null || partialState === undefined) {
24107 // Null and undefined are treated as no-ops.
24108 return prevState;
24109 } // Merge the partial state and the previous state.
24110
24111
24112 return assign({}, prevState, partialState);
24113 }
24114
24115 case ForceUpdate:
24116 {
24117 hasForceUpdate = true;
24118 return prevState;
24119 }
24120 }
24121
24122 return prevState;
24123}
24124
24125var didReadFromEntangledAsyncAction = false; // Each call to processUpdateQueue should be accompanied by a call to this. It's
24126// only in a separate function because in updateHostRoot, it must happen after
24127// all the context stacks have been pushed to, to prevent a stack mismatch. A
24128// bit unfortunate.
24129
24130function suspendIfUpdateReadFromEntangledAsyncAction() {
24131 // Check if this update is part of a pending async action. If so, we'll
24132 // need to suspend until the action has finished, so that it's batched
24133 // together with future updates in the same action.
24134 // TODO: Once we support hooks inside useMemo (or an equivalent
24135 // memoization boundary like Forget), hoist this logic so that it only
24136 // suspends if the memo boundary produces a new value.
24137 if (didReadFromEntangledAsyncAction) {
24138 var entangledActionThenable = peekEntangledActionThenable();
24139
24140 if (entangledActionThenable !== null) {
24141 // TODO: Instead of the throwing the thenable directly, throw a
24142 // special object like `use` does so we can detect if it's captured
24143 // by userspace.
24144 throw entangledActionThenable;
24145 }
24146 }
24147}
24148function processUpdateQueue(workInProgress, props, instance, renderLanes) {
24149 didReadFromEntangledAsyncAction = false; // This is always non-null on a ClassComponent or HostRoot
24150
24151 var queue = workInProgress.updateQueue;
24152 hasForceUpdate = false;
24153
24154 {
24155 currentlyProcessingQueue = queue.shared;
24156 }
24157
24158 var firstBaseUpdate = queue.firstBaseUpdate;
24159 var lastBaseUpdate = queue.lastBaseUpdate; // Check if there are pending updates. If so, transfer them to the base queue.
24160
24161 var pendingQueue = queue.shared.pending;
24162
24163 if (pendingQueue !== null) {
24164 queue.shared.pending = null; // The pending queue is circular. Disconnect the pointer between first
24165 // and last so that it's non-circular.
24166
24167 var lastPendingUpdate = pendingQueue;
24168 var firstPendingUpdate = lastPendingUpdate.next;
24169 lastPendingUpdate.next = null; // Append pending updates to base queue
24170
24171 if (lastBaseUpdate === null) {
24172 firstBaseUpdate = firstPendingUpdate;
24173 } else {
24174 lastBaseUpdate.next = firstPendingUpdate;
24175 }
24176
24177 lastBaseUpdate = lastPendingUpdate; // If there's a current queue, and it's different from the base queue, then
24178 // we need to transfer the updates to that queue, too. Because the base
24179 // queue is a singly-linked list with no cycles, we can append to both
24180 // lists and take advantage of structural sharing.
24181 // TODO: Pass `current` as argument
24182
24183 var current = workInProgress.alternate;
24184
24185 if (current !== null) {
24186 // This is always non-null on a ClassComponent or HostRoot
24187 var currentQueue = current.updateQueue;
24188 var currentLastBaseUpdate = currentQueue.lastBaseUpdate;
24189
24190 if (currentLastBaseUpdate !== lastBaseUpdate) {
24191 if (currentLastBaseUpdate === null) {
24192 currentQueue.firstBaseUpdate = firstPendingUpdate;
24193 } else {
24194 currentLastBaseUpdate.next = firstPendingUpdate;
24195 }
24196
24197 currentQueue.lastBaseUpdate = lastPendingUpdate;
24198 }
24199 }
24200 } // These values may change as we process the queue.
24201
24202
24203 if (firstBaseUpdate !== null) {
24204 // Iterate through the list of updates to compute the result.
24205 var newState = queue.baseState; // TODO: Don't need to accumulate this. Instead, we can remove renderLanes
24206 // from the original lanes.
24207
24208 var newLanes = NoLanes;
24209 var newBaseState = null;
24210 var newFirstBaseUpdate = null;
24211 var newLastBaseUpdate = null;
24212 var update = firstBaseUpdate;
24213
24214 do {
24215 // An extra OffscreenLane bit is added to updates that were made to
24216 // a hidden tree, so that we can distinguish them from updates that were
24217 // already there when the tree was hidden.
24218 var updateLane = removeLanes(update.lane, OffscreenLane);
24219 var isHiddenUpdate = updateLane !== update.lane; // Check if this update was made while the tree was hidden. If so, then
24220 // it's not a "base" update and we should disregard the extra base lanes
24221 // that were added to renderLanes when we entered the Offscreen tree.
24222
24223 var shouldSkipUpdate = isHiddenUpdate ? !isSubsetOfLanes(getWorkInProgressRootRenderLanes(), updateLane) : !isSubsetOfLanes(renderLanes, updateLane);
24224
24225 if (shouldSkipUpdate) {
24226 // Priority is insufficient. Skip this update. If this is the first
24227 // skipped update, the previous update/state is the new base
24228 // update/state.
24229 var clone = {
24230 lane: updateLane,
24231 tag: update.tag,
24232 payload: update.payload,
24233 callback: update.callback,
24234 next: null
24235 };
24236
24237 if (newLastBaseUpdate === null) {
24238 newFirstBaseUpdate = newLastBaseUpdate = clone;
24239 newBaseState = newState;
24240 } else {
24241 newLastBaseUpdate = newLastBaseUpdate.next = clone;
24242 } // Update the remaining priority in the queue.
24243
24244
24245 newLanes = mergeLanes(newLanes, updateLane);
24246 } else {
24247 // This update does have sufficient priority.
24248 // Check if this update is part of a pending async action. If so,
24249 // we'll need to suspend until the action has finished, so that it's
24250 // batched together with future updates in the same action.
24251 if (updateLane !== NoLane && updateLane === peekEntangledActionLane()) {
24252 didReadFromEntangledAsyncAction = true;
24253 }
24254
24255 if (newLastBaseUpdate !== null) {
24256 var _clone = {
24257 // This update is going to be committed so we never want uncommit
24258 // it. Using NoLane works because 0 is a subset of all bitmasks, so
24259 // this will never be skipped by the check above.
24260 lane: NoLane,
24261 tag: update.tag,
24262 payload: update.payload,
24263 // When this update is rebased, we should not fire its
24264 // callback again.
24265 callback: null,
24266 next: null
24267 };
24268 newLastBaseUpdate = newLastBaseUpdate.next = _clone;
24269 } // Process this update.
24270
24271
24272 newState = getStateFromUpdate(workInProgress, queue, update, newState, props, instance);
24273 var callback = update.callback;
24274
24275 if (callback !== null) {
24276 workInProgress.flags |= Callback;
24277
24278 if (isHiddenUpdate) {
24279 workInProgress.flags |= Visibility;
24280 }
24281
24282 var callbacks = queue.callbacks;
24283
24284 if (callbacks === null) {
24285 queue.callbacks = [callback];
24286 } else {
24287 callbacks.push(callback);
24288 }
24289 }
24290 } // $FlowFixMe[incompatible-type] we bail out when we get a null
24291
24292
24293 update = update.next;
24294
24295 if (update === null) {
24296 pendingQueue = queue.shared.pending;
24297
24298 if (pendingQueue === null) {
24299 break;
24300 } else {
24301 // An update was scheduled from inside a reducer. Add the new
24302 // pending updates to the end of the list and keep processing.
24303 var _lastPendingUpdate = pendingQueue; // Intentionally unsound. Pending updates form a circular list, but we
24304 // unravel them when transferring them to the base queue.
24305
24306 var _firstPendingUpdate = _lastPendingUpdate.next;
24307 _lastPendingUpdate.next = null;
24308 update = _firstPendingUpdate;
24309 queue.lastBaseUpdate = _lastPendingUpdate;
24310 queue.shared.pending = null;
24311 }
24312 }
24313 } while (true);
24314
24315 if (newLastBaseUpdate === null) {
24316 newBaseState = newState;
24317 }
24318
24319 queue.baseState = newBaseState;
24320 queue.firstBaseUpdate = newFirstBaseUpdate;
24321 queue.lastBaseUpdate = newLastBaseUpdate;
24322
24323 if (firstBaseUpdate === null) {
24324 // `queue.lanes` is used for entangling transitions. We can set it back to
24325 // zero once the queue is empty.
24326 queue.shared.lanes = NoLanes;
24327 } // Set the remaining expiration time to be whatever is remaining in the queue.
24328 // This should be fine because the only two other things that contribute to
24329 // expiration time are props and context. We're already in the middle of the
24330 // begin phase by the time we start processing the queue, so we've already
24331 // dealt with the props. Context in components that specify
24332 // shouldComponentUpdate is tricky; but we'll have to account for
24333 // that regardless.
24334
24335
24336 markSkippedUpdateLanes(newLanes);
24337 workInProgress.lanes = newLanes;
24338 workInProgress.memoizedState = newState;
24339 }
24340
24341 {
24342 currentlyProcessingQueue = null;
24343 }
24344}
24345
24346function callCallback(callback, context) {
24347 if (typeof callback !== 'function') {
24348 throw new Error('Invalid argument passed as callback. Expected a function. Instead ' + ("received: " + callback));
24349 }
24350
24351 callback.call(context);
24352}
24353
24354function resetHasForceUpdateBeforeProcessing() {
24355 hasForceUpdate = false;
24356}
24357function checkHasForceUpdateAfterProcessing() {
24358 return hasForceUpdate;
24359}
24360function deferHiddenCallbacks(updateQueue) {
24361 // When an update finishes on a hidden component, its callback should not
24362 // be fired until/unless the component is made visible again. Stash the
24363 // callback on the shared queue object so it can be fired later.
24364 var newHiddenCallbacks = updateQueue.callbacks;
24365
24366 if (newHiddenCallbacks !== null) {
24367 var existingHiddenCallbacks = updateQueue.shared.hiddenCallbacks;
24368
24369 if (existingHiddenCallbacks === null) {
24370 updateQueue.shared.hiddenCallbacks = newHiddenCallbacks;
24371 } else {
24372 updateQueue.shared.hiddenCallbacks = existingHiddenCallbacks.concat(newHiddenCallbacks);
24373 }
24374 }
24375}
24376function commitHiddenCallbacks(updateQueue, context) {
24377 // This component is switching from hidden -> visible. Commit any callbacks
24378 // that were previously deferred.
24379 var hiddenCallbacks = updateQueue.shared.hiddenCallbacks;
24380
24381 if (hiddenCallbacks !== null) {
24382 updateQueue.shared.hiddenCallbacks = null;
24383
24384 for (var i = 0; i < hiddenCallbacks.length; i++) {
24385 var callback = hiddenCallbacks[i];
24386 callCallback(callback, context);
24387 }
24388 }
24389}
24390function commitCallbacks(updateQueue, context) {
24391 var callbacks = updateQueue.callbacks;
24392
24393 if (callbacks !== null) {
24394 updateQueue.callbacks = null;
24395
24396 for (var i = 0; i < callbacks.length; i++) {
24397 var callback = callbacks[i];
24398 callCallback(callback, context);
24399 }
24400 }
24401}
24402
24403var fakeInternalInstance = {};
24404var didWarnAboutStateAssignmentForComponent;
24405var didWarnAboutUninitializedState;
24406var didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate;
24407var didWarnAboutLegacyLifecyclesAndDerivedState;
24408var didWarnAboutUndefinedDerivedState;
24409var didWarnAboutDirectlyAssigningPropsToState;
24410var didWarnAboutInvalidateContextType;
24411var didWarnOnInvalidCallback;
24412
24413{
24414 didWarnAboutStateAssignmentForComponent = new Set();
24415 didWarnAboutUninitializedState = new Set();
24416 didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate = new Set();
24417 didWarnAboutLegacyLifecyclesAndDerivedState = new Set();
24418 didWarnAboutDirectlyAssigningPropsToState = new Set();
24419 didWarnAboutUndefinedDerivedState = new Set();
24420 didWarnAboutInvalidateContextType = new Set();
24421 didWarnOnInvalidCallback = new Set(); // This is so gross but it's at least non-critical and can be removed if
24422 // it causes problems. This is meant to give a nicer error message for
24423 // ReactDOM15.unstable_renderSubtreeIntoContainer(reactDOM16Component,
24424 // ...)) which otherwise throws a "_processChildContext is not a function"
24425 // exception.
24426
24427 Object.defineProperty(fakeInternalInstance, '_processChildContext', {
24428 enumerable: false,
24429 value: function () {
24430 throw new 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).');
24431 }
24432 });
24433 Object.freeze(fakeInternalInstance);
24434}
24435
24436function warnOnInvalidCallback(callback) {
24437 {
24438 if (callback === null || typeof callback === 'function') {
24439 return;
24440 } // eslint-disable-next-line react-internal/safe-string-coercion
24441
24442
24443 var key = String(callback);
24444
24445 if (!didWarnOnInvalidCallback.has(key)) {
24446 didWarnOnInvalidCallback.add(key);
24447
24448 error('Expected the last optional `callback` argument to be a ' + 'function. Instead received: %s.', callback);
24449 }
24450 }
24451}
24452
24453function warnOnUndefinedDerivedState(type, partialState) {
24454 {
24455 if (partialState === undefined) {
24456 var componentName = getComponentNameFromType(type) || 'Component';
24457
24458 if (!didWarnAboutUndefinedDerivedState.has(componentName)) {
24459 didWarnAboutUndefinedDerivedState.add(componentName);
24460
24461 error('%s.getDerivedStateFromProps(): A valid state object (or null) must be returned. ' + 'You have returned undefined.', componentName);
24462 }
24463 }
24464 }
24465}
24466
24467function applyDerivedStateFromProps(workInProgress, ctor, getDerivedStateFromProps, nextProps) {
24468 var prevState = workInProgress.memoizedState;
24469 var partialState = getDerivedStateFromProps(nextProps, prevState);
24470
24471 {
24472 if (workInProgress.mode & StrictLegacyMode) {
24473 setIsStrictModeForDevtools(true);
24474
24475 try {
24476 // Invoke the function an extra time to help detect side-effects.
24477 partialState = getDerivedStateFromProps(nextProps, prevState);
24478 } finally {
24479 setIsStrictModeForDevtools(false);
24480 }
24481 }
24482
24483 warnOnUndefinedDerivedState(ctor, partialState);
24484 } // Merge the partial state and the previous state.
24485
24486
24487 var memoizedState = partialState === null || partialState === undefined ? prevState : assign({}, prevState, partialState);
24488 workInProgress.memoizedState = memoizedState; // Once the update queue is empty, persist the derived state onto the
24489 // base state.
24490
24491 if (workInProgress.lanes === NoLanes) {
24492 // Queue is always non-null for classes
24493 var updateQueue = workInProgress.updateQueue;
24494 updateQueue.baseState = memoizedState;
24495 }
24496}
24497
24498var classComponentUpdater = {
24499 isMounted: isMounted,
24500 // $FlowFixMe[missing-local-annot]
24501 enqueueSetState: function (inst, payload, callback) {
24502 var fiber = get(inst);
24503 var lane = requestUpdateLane(fiber);
24504 var update = createUpdate(lane);
24505 update.payload = payload;
24506
24507 if (callback !== undefined && callback !== null) {
24508 {
24509 warnOnInvalidCallback(callback);
24510 }
24511
24512 update.callback = callback;
24513 }
24514
24515 var root = enqueueUpdate(fiber, update, lane);
24516
24517 if (root !== null) {
24518 scheduleUpdateOnFiber(root, fiber, lane);
24519 entangleTransitions(root, fiber, lane);
24520 }
24521
24522 {
24523 markStateUpdateScheduled(fiber, lane);
24524 }
24525 },
24526 enqueueReplaceState: function (inst, payload, callback) {
24527 var fiber = get(inst);
24528 var lane = requestUpdateLane(fiber);
24529 var update = createUpdate(lane);
24530 update.tag = ReplaceState;
24531 update.payload = payload;
24532
24533 if (callback !== undefined && callback !== null) {
24534 {
24535 warnOnInvalidCallback(callback);
24536 }
24537
24538 update.callback = callback;
24539 }
24540
24541 var root = enqueueUpdate(fiber, update, lane);
24542
24543 if (root !== null) {
24544 scheduleUpdateOnFiber(root, fiber, lane);
24545 entangleTransitions(root, fiber, lane);
24546 }
24547
24548 {
24549 markStateUpdateScheduled(fiber, lane);
24550 }
24551 },
24552 // $FlowFixMe[missing-local-annot]
24553 enqueueForceUpdate: function (inst, callback) {
24554 var fiber = get(inst);
24555 var lane = requestUpdateLane(fiber);
24556 var update = createUpdate(lane);
24557 update.tag = ForceUpdate;
24558
24559 if (callback !== undefined && callback !== null) {
24560 {
24561 warnOnInvalidCallback(callback);
24562 }
24563
24564 update.callback = callback;
24565 }
24566
24567 var root = enqueueUpdate(fiber, update, lane);
24568
24569 if (root !== null) {
24570 scheduleUpdateOnFiber(root, fiber, lane);
24571 entangleTransitions(root, fiber, lane);
24572 }
24573
24574 {
24575 markForceUpdateScheduled(fiber, lane);
24576 }
24577 }
24578};
24579
24580function checkShouldComponentUpdate(workInProgress, ctor, oldProps, newProps, oldState, newState, nextContext) {
24581 var instance = workInProgress.stateNode;
24582
24583 if (typeof instance.shouldComponentUpdate === 'function') {
24584 var shouldUpdate = instance.shouldComponentUpdate(newProps, newState, nextContext);
24585
24586 {
24587 if (workInProgress.mode & StrictLegacyMode) {
24588 setIsStrictModeForDevtools(true);
24589
24590 try {
24591 // Invoke the function an extra time to help detect side-effects.
24592 shouldUpdate = instance.shouldComponentUpdate(newProps, newState, nextContext);
24593 } finally {
24594 setIsStrictModeForDevtools(false);
24595 }
24596 }
24597
24598 if (shouldUpdate === undefined) {
24599 error('%s.shouldComponentUpdate(): Returned undefined instead of a ' + 'boolean value. Make sure to return true or false.', getComponentNameFromType(ctor) || 'Component');
24600 }
24601 }
24602
24603 return shouldUpdate;
24604 }
24605
24606 if (ctor.prototype && ctor.prototype.isPureReactComponent) {
24607 return !shallowEqual(oldProps, newProps) || !shallowEqual(oldState, newState);
24608 }
24609
24610 return true;
24611}
24612
24613function checkClassInstance(workInProgress, ctor, newProps) {
24614 var instance = workInProgress.stateNode;
24615
24616 {
24617 var name = getComponentNameFromType(ctor) || 'Component';
24618 var renderPresent = instance.render;
24619
24620 if (!renderPresent) {
24621 if (ctor.prototype && typeof ctor.prototype.render === 'function') {
24622 error('No `render` method found on the %s ' + 'instance: did you accidentally return an object from the constructor?', name);
24623 } else {
24624 error('No `render` method found on the %s ' + 'instance: you may have forgotten to define `render`.', name);
24625 }
24626 }
24627
24628 if (instance.getInitialState && !instance.getInitialState.isReactClassApproved && !instance.state) {
24629 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);
24630 }
24631
24632 if (instance.getDefaultProps && !instance.getDefaultProps.isReactClassApproved) {
24633 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);
24634 }
24635
24636 if (instance.propTypes) {
24637 error('propTypes was defined as an instance property on %s. Use a static ' + 'property to define propTypes instead.', name);
24638 }
24639
24640 if (instance.contextType) {
24641 error('contextType was defined as an instance property on %s. Use a static ' + 'property to define contextType instead.', name);
24642 }
24643
24644 {
24645 if (ctor.childContextTypes) {
24646 error('%s uses the legacy childContextTypes API which was removed in React 19. ' + 'Use React.createContext() instead.', name);
24647 }
24648
24649 if (ctor.contextTypes) {
24650 error('%s uses the legacy contextTypes API which was removed in React 19. ' + 'Use React.createContext() with static contextType instead.', name);
24651 }
24652 }
24653
24654 if (typeof instance.componentShouldUpdate === 'function') {
24655 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);
24656 }
24657
24658 if (ctor.prototype && ctor.prototype.isPureReactComponent && typeof instance.shouldComponentUpdate !== 'undefined') {
24659 error('%s has a method called shouldComponentUpdate(). ' + 'shouldComponentUpdate should not be used when extending React.PureComponent. ' + 'Please extend React.Component if shouldComponentUpdate is used.', getComponentNameFromType(ctor) || 'A pure component');
24660 }
24661
24662 if (typeof instance.componentDidUnmount === 'function') {
24663 error('%s has a method called ' + 'componentDidUnmount(). But there is no such lifecycle method. ' + 'Did you mean componentWillUnmount()?', name);
24664 }
24665
24666 if (typeof instance.componentDidReceiveProps === 'function') {
24667 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);
24668 }
24669
24670 if (typeof instance.componentWillRecieveProps === 'function') {
24671 error('%s has a method called ' + 'componentWillRecieveProps(). Did you mean componentWillReceiveProps()?', name);
24672 }
24673
24674 if (typeof instance.UNSAFE_componentWillRecieveProps === 'function') {
24675 error('%s has a method called ' + 'UNSAFE_componentWillRecieveProps(). Did you mean UNSAFE_componentWillReceiveProps()?', name);
24676 }
24677
24678 var hasMutatedProps = instance.props !== newProps;
24679
24680 if (instance.props !== undefined && hasMutatedProps) {
24681 error('When calling super() in `%s`, make sure to pass ' + "up the same props that your component's constructor was passed.", name);
24682 }
24683
24684 if (instance.defaultProps) {
24685 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);
24686 }
24687
24688 if (typeof instance.getSnapshotBeforeUpdate === 'function' && typeof instance.componentDidUpdate !== 'function' && !didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate.has(ctor)) {
24689 didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate.add(ctor);
24690
24691 error('%s: getSnapshotBeforeUpdate() should be used with componentDidUpdate(). ' + 'This component defines getSnapshotBeforeUpdate() only.', getComponentNameFromType(ctor));
24692 }
24693
24694 if (typeof instance.getDerivedStateFromProps === 'function') {
24695 error('%s: getDerivedStateFromProps() is defined as an instance method ' + 'and will be ignored. Instead, declare it as a static method.', name);
24696 }
24697
24698 if (typeof instance.getDerivedStateFromError === 'function') {
24699 error('%s: getDerivedStateFromError() is defined as an instance method ' + 'and will be ignored. Instead, declare it as a static method.', name);
24700 }
24701
24702 if (typeof ctor.getSnapshotBeforeUpdate === 'function') {
24703 error('%s: getSnapshotBeforeUpdate() is defined as a static method ' + 'and will be ignored. Instead, declare it as an instance method.', name);
24704 }
24705
24706 var state = instance.state;
24707
24708 if (state && (typeof state !== 'object' || isArray(state))) {
24709 error('%s.state: must be set to an object or null', name);
24710 }
24711
24712 if (typeof instance.getChildContext === 'function' && typeof ctor.childContextTypes !== 'object') {
24713 error('%s.getChildContext(): childContextTypes must be defined in order to ' + 'use getChildContext().', name);
24714 }
24715 }
24716}
24717
24718function constructClassInstance(workInProgress, ctor, props) {
24719 var context = emptyContextObject;
24720 var contextType = ctor.contextType;
24721
24722 {
24723 if ('contextType' in ctor) {
24724 var isValid = // Allow null for conditional declaration
24725 contextType === null || contextType !== undefined && contextType.$$typeof === REACT_CONTEXT_TYPE;
24726
24727 if (!isValid && !didWarnAboutInvalidateContextType.has(ctor)) {
24728 didWarnAboutInvalidateContextType.add(ctor);
24729 var addendum = '';
24730
24731 if (contextType === undefined) {
24732 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.';
24733 } else if (typeof contextType !== 'object') {
24734 addendum = ' However, it is set to a ' + typeof contextType + '.';
24735 } else if (contextType.$$typeof === REACT_CONSUMER_TYPE) {
24736 addendum = ' Did you accidentally pass the Context.Consumer instead?';
24737 } else {
24738 addendum = ' However, it is set to an object with keys {' + Object.keys(contextType).join(', ') + '}.';
24739 }
24740
24741 error('%s defines an invalid contextType. ' + 'contextType should point to the Context object returned by React.createContext().%s', getComponentNameFromType(ctor) || 'Component', addendum);
24742 }
24743 }
24744 }
24745
24746 if (typeof contextType === 'object' && contextType !== null) {
24747 context = readContext(contextType);
24748 }
24749
24750 var instance = new ctor(props, context); // Instantiate twice to help detect side-effects.
24751
24752 {
24753 if (workInProgress.mode & StrictLegacyMode) {
24754 setIsStrictModeForDevtools(true);
24755
24756 try {
24757 instance = new ctor(props, context); // eslint-disable-line no-new
24758 } finally {
24759 setIsStrictModeForDevtools(false);
24760 }
24761 }
24762 }
24763
24764 var state = workInProgress.memoizedState = instance.state !== null && instance.state !== undefined ? instance.state : null;
24765 instance.updater = classComponentUpdater;
24766 workInProgress.stateNode = instance; // The instance needs access to the fiber so that it can schedule updates
24767
24768 set(instance, workInProgress);
24769
24770 {
24771 instance._reactInternalInstance = fakeInternalInstance;
24772 }
24773
24774 {
24775 if (typeof ctor.getDerivedStateFromProps === 'function' && state === null) {
24776 var componentName = getComponentNameFromType(ctor) || 'Component';
24777
24778 if (!didWarnAboutUninitializedState.has(componentName)) {
24779 didWarnAboutUninitializedState.add(componentName);
24780
24781 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);
24782 }
24783 } // If new component APIs are defined, "unsafe" lifecycles won't be called.
24784 // Warn about these lifecycles if they are present.
24785 // Don't warn about react-lifecycles-compat polyfilled methods though.
24786
24787
24788 if (typeof ctor.getDerivedStateFromProps === 'function' || typeof instance.getSnapshotBeforeUpdate === 'function') {
24789 var foundWillMountName = null;
24790 var foundWillReceivePropsName = null;
24791 var foundWillUpdateName = null;
24792
24793 if (typeof instance.componentWillMount === 'function' && instance.componentWillMount.__suppressDeprecationWarning !== true) {
24794 foundWillMountName = 'componentWillMount';
24795 } else if (typeof instance.UNSAFE_componentWillMount === 'function') {
24796 foundWillMountName = 'UNSAFE_componentWillMount';
24797 }
24798
24799 if (typeof instance.componentWillReceiveProps === 'function' && instance.componentWillReceiveProps.__suppressDeprecationWarning !== true) {
24800 foundWillReceivePropsName = 'componentWillReceiveProps';
24801 } else if (typeof instance.UNSAFE_componentWillReceiveProps === 'function') {
24802 foundWillReceivePropsName = 'UNSAFE_componentWillReceiveProps';
24803 }
24804
24805 if (typeof instance.componentWillUpdate === 'function' && instance.componentWillUpdate.__suppressDeprecationWarning !== true) {
24806 foundWillUpdateName = 'componentWillUpdate';
24807 } else if (typeof instance.UNSAFE_componentWillUpdate === 'function') {
24808 foundWillUpdateName = 'UNSAFE_componentWillUpdate';
24809 }
24810
24811 if (foundWillMountName !== null || foundWillReceivePropsName !== null || foundWillUpdateName !== null) {
24812 var _componentName = getComponentNameFromType(ctor) || 'Component';
24813
24814 var newApiName = typeof ctor.getDerivedStateFromProps === 'function' ? 'getDerivedStateFromProps()' : 'getSnapshotBeforeUpdate()';
24815
24816 if (!didWarnAboutLegacyLifecyclesAndDerivedState.has(_componentName)) {
24817 didWarnAboutLegacyLifecyclesAndDerivedState.add(_componentName);
24818
24819 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://react.dev/link/unsafe-component-lifecycles', _componentName, newApiName, foundWillMountName !== null ? "\n " + foundWillMountName : '', foundWillReceivePropsName !== null ? "\n " + foundWillReceivePropsName : '', foundWillUpdateName !== null ? "\n " + foundWillUpdateName : '');
24820 }
24821 }
24822 }
24823 } // Cache unmasked context so we can avoid recreating masked context unless necessary.
24824
24825 return instance;
24826}
24827
24828function callComponentWillMount(workInProgress, instance) {
24829 var oldState = instance.state;
24830
24831 if (typeof instance.componentWillMount === 'function') {
24832 instance.componentWillMount();
24833 }
24834
24835 if (typeof instance.UNSAFE_componentWillMount === 'function') {
24836 instance.UNSAFE_componentWillMount();
24837 }
24838
24839 if (oldState !== instance.state) {
24840 {
24841 error('%s.componentWillMount(): Assigning directly to this.state is ' + "deprecated (except inside a component's " + 'constructor). Use setState instead.', getComponentNameFromFiber(workInProgress) || 'Component');
24842 }
24843
24844 classComponentUpdater.enqueueReplaceState(instance, instance.state, null);
24845 }
24846}
24847
24848function callComponentWillReceiveProps(workInProgress, instance, newProps, nextContext) {
24849 var oldState = instance.state;
24850
24851 if (typeof instance.componentWillReceiveProps === 'function') {
24852 instance.componentWillReceiveProps(newProps, nextContext);
24853 }
24854
24855 if (typeof instance.UNSAFE_componentWillReceiveProps === 'function') {
24856 instance.UNSAFE_componentWillReceiveProps(newProps, nextContext);
24857 }
24858
24859 if (instance.state !== oldState) {
24860 {
24861 var componentName = getComponentNameFromFiber(workInProgress) || 'Component';
24862
24863 if (!didWarnAboutStateAssignmentForComponent.has(componentName)) {
24864 didWarnAboutStateAssignmentForComponent.add(componentName);
24865
24866 error('%s.componentWillReceiveProps(): Assigning directly to ' + "this.state is deprecated (except inside a component's " + 'constructor). Use setState instead.', componentName);
24867 }
24868 }
24869
24870 classComponentUpdater.enqueueReplaceState(instance, instance.state, null);
24871 }
24872} // Invokes the mount life-cycles on a previously never rendered instance.
24873
24874
24875function mountClassInstance(workInProgress, ctor, newProps, renderLanes) {
24876 {
24877 checkClassInstance(workInProgress, ctor, newProps);
24878 }
24879
24880 var instance = workInProgress.stateNode;
24881 instance.props = newProps;
24882 instance.state = workInProgress.memoizedState;
24883 instance.refs = {};
24884 initializeUpdateQueue(workInProgress);
24885 var contextType = ctor.contextType;
24886
24887 if (typeof contextType === 'object' && contextType !== null) {
24888 instance.context = readContext(contextType);
24889 } else {
24890 instance.context = emptyContextObject;
24891 }
24892
24893 {
24894 if (instance.state === newProps) {
24895 var componentName = getComponentNameFromType(ctor) || 'Component';
24896
24897 if (!didWarnAboutDirectlyAssigningPropsToState.has(componentName)) {
24898 didWarnAboutDirectlyAssigningPropsToState.add(componentName);
24899
24900 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);
24901 }
24902 }
24903
24904 if (workInProgress.mode & StrictLegacyMode) {
24905 ReactStrictModeWarnings.recordLegacyContextWarning(workInProgress, instance);
24906 }
24907
24908 ReactStrictModeWarnings.recordUnsafeLifecycleWarnings(workInProgress, instance);
24909 }
24910
24911 instance.state = workInProgress.memoizedState;
24912 var getDerivedStateFromProps = ctor.getDerivedStateFromProps;
24913
24914 if (typeof getDerivedStateFromProps === 'function') {
24915 applyDerivedStateFromProps(workInProgress, ctor, getDerivedStateFromProps, newProps);
24916 instance.state = workInProgress.memoizedState;
24917 } // In order to support react-lifecycles-compat polyfilled components,
24918 // Unsafe lifecycles should not be invoked for components using the new APIs.
24919
24920
24921 if (typeof ctor.getDerivedStateFromProps !== 'function' && typeof instance.getSnapshotBeforeUpdate !== 'function' && (typeof instance.UNSAFE_componentWillMount === 'function' || typeof instance.componentWillMount === 'function')) {
24922 callComponentWillMount(workInProgress, instance); // If we had additional state updates during this life-cycle, let's
24923 // process them now.
24924
24925 processUpdateQueue(workInProgress, newProps, instance, renderLanes);
24926 suspendIfUpdateReadFromEntangledAsyncAction();
24927 instance.state = workInProgress.memoizedState;
24928 }
24929
24930 if (typeof instance.componentDidMount === 'function') {
24931 workInProgress.flags |= Update | LayoutStatic;
24932 }
24933
24934 if ((workInProgress.mode & StrictEffectsMode) !== NoMode) {
24935 workInProgress.flags |= MountLayoutDev;
24936 }
24937}
24938
24939function resumeMountClassInstance(workInProgress, ctor, newProps, renderLanes) {
24940 var instance = workInProgress.stateNode;
24941 var unresolvedOldProps = workInProgress.memoizedProps;
24942 var oldProps = resolveClassComponentProps(ctor, unresolvedOldProps);
24943 instance.props = oldProps;
24944 var oldContext = instance.context;
24945 var contextType = ctor.contextType;
24946 var nextContext = emptyContextObject;
24947
24948 if (typeof contextType === 'object' && contextType !== null) {
24949 nextContext = readContext(contextType);
24950 }
24951
24952 var getDerivedStateFromProps = ctor.getDerivedStateFromProps;
24953 var hasNewLifecycles = typeof getDerivedStateFromProps === 'function' || typeof instance.getSnapshotBeforeUpdate === 'function'; // When comparing whether props changed, we should compare using the
24954 // unresolved props object that is stored on the fiber, rather than the
24955 // one that gets assigned to the instance, because that object may have been
24956 // cloned to resolve default props and/or remove `ref`.
24957
24958 var unresolvedNewProps = workInProgress.pendingProps;
24959 var didReceiveNewProps = unresolvedNewProps !== unresolvedOldProps; // Note: During these life-cycles, instance.props/instance.state are what
24960 // ever the previously attempted to render - not the "current". However,
24961 // during componentDidUpdate we pass the "current" props.
24962 // In order to support react-lifecycles-compat polyfilled components,
24963 // Unsafe lifecycles should not be invoked for components using the new APIs.
24964
24965 if (!hasNewLifecycles && (typeof instance.UNSAFE_componentWillReceiveProps === 'function' || typeof instance.componentWillReceiveProps === 'function')) {
24966 if (didReceiveNewProps || oldContext !== nextContext) {
24967 callComponentWillReceiveProps(workInProgress, instance, newProps, nextContext);
24968 }
24969 }
24970
24971 resetHasForceUpdateBeforeProcessing();
24972 var oldState = workInProgress.memoizedState;
24973 var newState = instance.state = oldState;
24974 processUpdateQueue(workInProgress, newProps, instance, renderLanes);
24975 suspendIfUpdateReadFromEntangledAsyncAction();
24976 newState = workInProgress.memoizedState;
24977
24978 if (!didReceiveNewProps && oldState === newState && !hasContextChanged() && !checkHasForceUpdateAfterProcessing()) {
24979 // If an update was already in progress, we should schedule an Update
24980 // effect even though we're bailing out, so that cWU/cDU are called.
24981 if (typeof instance.componentDidMount === 'function') {
24982 workInProgress.flags |= Update | LayoutStatic;
24983 }
24984
24985 if ((workInProgress.mode & StrictEffectsMode) !== NoMode) {
24986 workInProgress.flags |= MountLayoutDev;
24987 }
24988
24989 return false;
24990 }
24991
24992 if (typeof getDerivedStateFromProps === 'function') {
24993 applyDerivedStateFromProps(workInProgress, ctor, getDerivedStateFromProps, newProps);
24994 newState = workInProgress.memoizedState;
24995 }
24996
24997 var shouldUpdate = checkHasForceUpdateAfterProcessing() || checkShouldComponentUpdate(workInProgress, ctor, oldProps, newProps, oldState, newState, nextContext);
24998
24999 if (shouldUpdate) {
25000 // In order to support react-lifecycles-compat polyfilled components,
25001 // Unsafe lifecycles should not be invoked for components using the new APIs.
25002 if (!hasNewLifecycles && (typeof instance.UNSAFE_componentWillMount === 'function' || typeof instance.componentWillMount === 'function')) {
25003 if (typeof instance.componentWillMount === 'function') {
25004 instance.componentWillMount();
25005 }
25006
25007 if (typeof instance.UNSAFE_componentWillMount === 'function') {
25008 instance.UNSAFE_componentWillMount();
25009 }
25010 }
25011
25012 if (typeof instance.componentDidMount === 'function') {
25013 workInProgress.flags |= Update | LayoutStatic;
25014 }
25015
25016 if ((workInProgress.mode & StrictEffectsMode) !== NoMode) {
25017 workInProgress.flags |= MountLayoutDev;
25018 }
25019 } else {
25020 // If an update was already in progress, we should schedule an Update
25021 // effect even though we're bailing out, so that cWU/cDU are called.
25022 if (typeof instance.componentDidMount === 'function') {
25023 workInProgress.flags |= Update | LayoutStatic;
25024 }
25025
25026 if ((workInProgress.mode & StrictEffectsMode) !== NoMode) {
25027 workInProgress.flags |= MountLayoutDev;
25028 } // If shouldComponentUpdate returned false, we should still update the
25029 // memoized state to indicate that this work can be reused.
25030
25031
25032 workInProgress.memoizedProps = newProps;
25033 workInProgress.memoizedState = newState;
25034 } // Update the existing instance's state, props, and context pointers even
25035 // if shouldComponentUpdate returns false.
25036
25037
25038 instance.props = newProps;
25039 instance.state = newState;
25040 instance.context = nextContext;
25041 return shouldUpdate;
25042} // Invokes the update life-cycles and returns false if it shouldn't rerender.
25043
25044
25045function updateClassInstance(current, workInProgress, ctor, newProps, renderLanes) {
25046 var instance = workInProgress.stateNode;
25047 cloneUpdateQueue(current, workInProgress);
25048 var unresolvedOldProps = workInProgress.memoizedProps;
25049 var oldProps = resolveClassComponentProps(ctor, unresolvedOldProps);
25050 instance.props = oldProps;
25051 var unresolvedNewProps = workInProgress.pendingProps;
25052 var oldContext = instance.context;
25053 var contextType = ctor.contextType;
25054 var nextContext = emptyContextObject;
25055
25056 if (typeof contextType === 'object' && contextType !== null) {
25057 nextContext = readContext(contextType);
25058 }
25059
25060 var getDerivedStateFromProps = ctor.getDerivedStateFromProps;
25061 var hasNewLifecycles = typeof getDerivedStateFromProps === 'function' || typeof instance.getSnapshotBeforeUpdate === 'function'; // Note: During these life-cycles, instance.props/instance.state are what
25062 // ever the previously attempted to render - not the "current". However,
25063 // during componentDidUpdate we pass the "current" props.
25064 // In order to support react-lifecycles-compat polyfilled components,
25065 // Unsafe lifecycles should not be invoked for components using the new APIs.
25066
25067 if (!hasNewLifecycles && (typeof instance.UNSAFE_componentWillReceiveProps === 'function' || typeof instance.componentWillReceiveProps === 'function')) {
25068 if (unresolvedOldProps !== unresolvedNewProps || oldContext !== nextContext) {
25069 callComponentWillReceiveProps(workInProgress, instance, newProps, nextContext);
25070 }
25071 }
25072
25073 resetHasForceUpdateBeforeProcessing();
25074 var oldState = workInProgress.memoizedState;
25075 var newState = instance.state = oldState;
25076 processUpdateQueue(workInProgress, newProps, instance, renderLanes);
25077 suspendIfUpdateReadFromEntangledAsyncAction();
25078 newState = workInProgress.memoizedState;
25079
25080 if (unresolvedOldProps === unresolvedNewProps && oldState === newState && !hasContextChanged() && !checkHasForceUpdateAfterProcessing() && !(enableLazyContextPropagation )) {
25081 // If an update was already in progress, we should schedule an Update
25082 // effect even though we're bailing out, so that cWU/cDU are called.
25083 if (typeof instance.componentDidUpdate === 'function') {
25084 if (unresolvedOldProps !== current.memoizedProps || oldState !== current.memoizedState) {
25085 workInProgress.flags |= Update;
25086 }
25087 }
25088
25089 if (typeof instance.getSnapshotBeforeUpdate === 'function') {
25090 if (unresolvedOldProps !== current.memoizedProps || oldState !== current.memoizedState) {
25091 workInProgress.flags |= Snapshot;
25092 }
25093 }
25094
25095 return false;
25096 }
25097
25098 if (typeof getDerivedStateFromProps === 'function') {
25099 applyDerivedStateFromProps(workInProgress, ctor, getDerivedStateFromProps, newProps);
25100 newState = workInProgress.memoizedState;
25101 }
25102
25103 var shouldUpdate = checkHasForceUpdateAfterProcessing() || checkShouldComponentUpdate(workInProgress, ctor, oldProps, newProps, oldState, newState, nextContext) || // TODO: In some cases, we'll end up checking if context has changed twice,
25104 // both before and after `shouldComponentUpdate` has been called. Not ideal,
25105 // but I'm loath to refactor this function. This only happens for memoized
25106 // components so it's not that common.
25107 enableLazyContextPropagation ;
25108
25109 if (shouldUpdate) {
25110 // In order to support react-lifecycles-compat polyfilled components,
25111 // Unsafe lifecycles should not be invoked for components using the new APIs.
25112 if (!hasNewLifecycles && (typeof instance.UNSAFE_componentWillUpdate === 'function' || typeof instance.componentWillUpdate === 'function')) {
25113 if (typeof instance.componentWillUpdate === 'function') {
25114 instance.componentWillUpdate(newProps, newState, nextContext);
25115 }
25116
25117 if (typeof instance.UNSAFE_componentWillUpdate === 'function') {
25118 instance.UNSAFE_componentWillUpdate(newProps, newState, nextContext);
25119 }
25120 }
25121
25122 if (typeof instance.componentDidUpdate === 'function') {
25123 workInProgress.flags |= Update;
25124 }
25125
25126 if (typeof instance.getSnapshotBeforeUpdate === 'function') {
25127 workInProgress.flags |= Snapshot;
25128 }
25129 } else {
25130 // If an update was already in progress, we should schedule an Update
25131 // effect even though we're bailing out, so that cWU/cDU are called.
25132 if (typeof instance.componentDidUpdate === 'function') {
25133 if (unresolvedOldProps !== current.memoizedProps || oldState !== current.memoizedState) {
25134 workInProgress.flags |= Update;
25135 }
25136 }
25137
25138 if (typeof instance.getSnapshotBeforeUpdate === 'function') {
25139 if (unresolvedOldProps !== current.memoizedProps || oldState !== current.memoizedState) {
25140 workInProgress.flags |= Snapshot;
25141 }
25142 } // If shouldComponentUpdate returned false, we should still update the
25143 // memoized props/state to indicate that this work can be reused.
25144
25145
25146 workInProgress.memoizedProps = newProps;
25147 workInProgress.memoizedState = newState;
25148 } // Update the existing instance's state, props, and context pointers even
25149 // if shouldComponentUpdate returns false.
25150
25151
25152 instance.props = newProps;
25153 instance.state = newState;
25154 instance.context = nextContext;
25155 return shouldUpdate;
25156}
25157
25158function resolveClassComponentProps(Component, baseProps, // Only resolve default props if this is a lazy component. Otherwise, they
25159// would have already been resolved by the JSX runtime.
25160// TODO: We're going to remove default prop resolution from the JSX runtime
25161// and keep it only for class components. As part of that change, we should
25162// remove this extra check.
25163alreadyResolvedDefaultProps) {
25164 var newProps = baseProps;
25165
25166 {
25167 // Remove ref from the props object, if it exists.
25168 if ('ref' in baseProps) {
25169 newProps = {};
25170
25171 for (var propName in baseProps) {
25172 if (propName !== 'ref') {
25173 newProps[propName] = baseProps[propName];
25174 }
25175 }
25176 }
25177 } // Resolve default props.
25178
25179
25180 var defaultProps = Component.defaultProps;
25181
25182 if (defaultProps && ( // If disableDefaultPropsExceptForClasses is true, we always resolve
25183 // default props here in the reconciler, rather than in the JSX runtime.
25184 disableDefaultPropsExceptForClasses )) {
25185 // We may have already copied the props object above to remove ref. If so,
25186 // we can modify that. Otherwise, copy the props object with Object.assign.
25187 if (newProps === baseProps) {
25188 newProps = assign({}, newProps);
25189 } // Taken from old JSX runtime, where this used to live.
25190
25191
25192 for (var _propName in defaultProps) {
25193 if (newProps[_propName] === undefined) {
25194 newProps[_propName] = defaultProps[_propName];
25195 }
25196 }
25197 }
25198
25199 return newProps;
25200}
25201
25202var didWarnAboutUndefinedSnapshotBeforeUpdate = null;
25203
25204{
25205 didWarnAboutUndefinedSnapshotBeforeUpdate = new Set();
25206} // Used during the commit phase to track the state of the Offscreen component stack.
25207// Allows us to avoid traversing the return path to find the nearest Offscreen ancestor.
25208
25209
25210var offscreenSubtreeIsHidden = false;
25211var offscreenSubtreeWasHidden = false; // Used to track if a form needs to be reset at the end of the mutation phase.
25212
25213var needsFormReset = false;
25214var PossiblyWeakSet = typeof WeakSet === 'function' ? WeakSet : Set;
25215var nextEffect = null; // Used for Profiling builds to track updaters.
25216
25217var inProgressLanes = null;
25218var inProgressRoot = null;
25219
25220function shouldProfile(current) {
25221 return (current.mode & ProfileMode) !== NoMode && (getExecutionContext() & CommitContext) !== NoContext;
25222}
25223
25224function callComponentWillUnmountWithTimer(current, instance) {
25225 instance.props = resolveClassComponentProps(current.type, current.memoizedProps);
25226 instance.state = current.memoizedState;
25227
25228 if (shouldProfile(current)) {
25229 try {
25230 startLayoutEffectTimer();
25231 instance.componentWillUnmount();
25232 } finally {
25233 recordLayoutEffectDuration(current);
25234 }
25235 } else {
25236 instance.componentWillUnmount();
25237 }
25238} // Capture errors so they don't interrupt unmounting.
25239
25240
25241function safelyCallComponentWillUnmount(current, nearestMountedAncestor, instance) {
25242 try {
25243 callComponentWillUnmountWithTimer(current, instance);
25244 } catch (error) {
25245 captureCommitPhaseError(current, nearestMountedAncestor, error);
25246 }
25247} // Capture errors so they don't interrupt mounting.
25248
25249
25250function safelyAttachRef(current, nearestMountedAncestor) {
25251 try {
25252 commitAttachRef(current);
25253 } catch (error) {
25254 captureCommitPhaseError(current, nearestMountedAncestor, error);
25255 }
25256}
25257
25258function safelyDetachRef(current, nearestMountedAncestor) {
25259 var ref = current.ref;
25260 var refCleanup = current.refCleanup;
25261
25262 if (ref !== null) {
25263 if (typeof refCleanup === 'function') {
25264 try {
25265 if (shouldProfile(current)) {
25266 try {
25267 startLayoutEffectTimer();
25268 refCleanup();
25269 } finally {
25270 recordLayoutEffectDuration(current);
25271 }
25272 } else {
25273 refCleanup();
25274 }
25275 } catch (error) {
25276 captureCommitPhaseError(current, nearestMountedAncestor, error);
25277 } finally {
25278 // `refCleanup` has been called. Nullify all references to it to prevent double invocation.
25279 current.refCleanup = null;
25280 var finishedWork = current.alternate;
25281
25282 if (finishedWork != null) {
25283 finishedWork.refCleanup = null;
25284 }
25285 }
25286 } else if (typeof ref === 'function') {
25287 try {
25288 if (shouldProfile(current)) {
25289 try {
25290 startLayoutEffectTimer();
25291 ref(null);
25292 } finally {
25293 recordLayoutEffectDuration(current);
25294 }
25295 } else {
25296 ref(null);
25297 }
25298 } catch (error) {
25299 captureCommitPhaseError(current, nearestMountedAncestor, error);
25300 }
25301 } else {
25302 // $FlowFixMe[incompatible-use] unable to narrow type to RefObject
25303 ref.current = null;
25304 }
25305 }
25306}
25307
25308function safelyCallDestroy(current, nearestMountedAncestor, destroy) {
25309 try {
25310 destroy();
25311 } catch (error) {
25312 captureCommitPhaseError(current, nearestMountedAncestor, error);
25313 }
25314}
25315var shouldFireAfterActiveInstanceBlur = false;
25316function commitBeforeMutationEffects(root, firstChild) {
25317 prepareForCommit();
25318 nextEffect = firstChild;
25319 commitBeforeMutationEffects_begin(); // We no longer need to track the active instance fiber
25320
25321 var shouldFire = shouldFireAfterActiveInstanceBlur;
25322 shouldFireAfterActiveInstanceBlur = false;
25323 return shouldFire;
25324}
25325
25326function commitBeforeMutationEffects_begin() {
25327 while (nextEffect !== null) {
25328 var fiber = nextEffect; // This phase is only used for beforeActiveInstanceBlur.
25329
25330 var child = fiber.child;
25331
25332 if ((fiber.subtreeFlags & BeforeMutationMask) !== NoFlags$1 && child !== null) {
25333 child.return = fiber;
25334 nextEffect = child;
25335 } else {
25336 commitBeforeMutationEffects_complete();
25337 }
25338 }
25339}
25340
25341function commitBeforeMutationEffects_complete() {
25342 while (nextEffect !== null) {
25343 var fiber = nextEffect;
25344 setCurrentFiber(fiber);
25345
25346 try {
25347 commitBeforeMutationEffectsOnFiber(fiber);
25348 } catch (error) {
25349 captureCommitPhaseError(fiber, fiber.return, error);
25350 }
25351
25352 resetCurrentFiber();
25353 var sibling = fiber.sibling;
25354
25355 if (sibling !== null) {
25356 sibling.return = fiber.return;
25357 nextEffect = sibling;
25358 return;
25359 }
25360
25361 nextEffect = fiber.return;
25362 }
25363}
25364
25365function commitBeforeMutationEffectsOnFiber(finishedWork) {
25366 var current = finishedWork.alternate;
25367 var flags = finishedWork.flags;
25368
25369 if ((flags & Snapshot) !== NoFlags$1) {
25370 setCurrentFiber(finishedWork);
25371 }
25372
25373 switch (finishedWork.tag) {
25374 case FunctionComponent:
25375 {
25376
25377 break;
25378 }
25379
25380 case ForwardRef:
25381 case SimpleMemoComponent:
25382 {
25383 break;
25384 }
25385
25386 case ClassComponent:
25387 {
25388 if ((flags & Snapshot) !== NoFlags$1) {
25389 if (current !== null) {
25390 var prevProps = current.memoizedProps;
25391 var prevState = current.memoizedState;
25392 var instance = finishedWork.stateNode; // We could update instance props and state here,
25393 // but instead we rely on them being set during last render.
25394 // TODO: revisit this when we implement resuming.
25395
25396 {
25397 if (!finishedWork.type.defaultProps && !('ref' in finishedWork.memoizedProps) && !didWarnAboutReassigningProps) {
25398 if (instance.props !== finishedWork.memoizedProps) {
25399 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.', getComponentNameFromFiber(finishedWork) || 'instance');
25400 }
25401
25402 if (instance.state !== finishedWork.memoizedState) {
25403 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.state`. ' + 'Please file an issue.', getComponentNameFromFiber(finishedWork) || 'instance');
25404 }
25405 }
25406 }
25407
25408 var snapshot = instance.getSnapshotBeforeUpdate(resolveClassComponentProps(finishedWork.type, prevProps), prevState);
25409
25410 {
25411 var didWarnSet = didWarnAboutUndefinedSnapshotBeforeUpdate;
25412
25413 if (snapshot === undefined && !didWarnSet.has(finishedWork.type)) {
25414 didWarnSet.add(finishedWork.type);
25415
25416 error('%s.getSnapshotBeforeUpdate(): A snapshot value (or null) ' + 'must be returned. You have returned undefined.', getComponentNameFromFiber(finishedWork));
25417 }
25418 }
25419
25420 instance.__reactInternalSnapshotBeforeUpdate = snapshot;
25421 }
25422 }
25423
25424 break;
25425 }
25426
25427 case HostRoot:
25428 {
25429 if ((flags & Snapshot) !== NoFlags$1) {
25430 {
25431 var root = finishedWork.stateNode;
25432 clearContainer(root.containerInfo);
25433 }
25434 }
25435
25436 break;
25437 }
25438
25439 case HostComponent:
25440 case HostHoistable:
25441 case HostSingleton:
25442 case HostText:
25443 case HostPortal:
25444 case IncompleteClassComponent:
25445 // Nothing to do for these component types
25446 break;
25447
25448 default:
25449 {
25450 if ((flags & Snapshot) !== NoFlags$1) {
25451 throw new 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.');
25452 }
25453 }
25454 }
25455
25456 if ((flags & Snapshot) !== NoFlags$1) {
25457 resetCurrentFiber();
25458 }
25459}
25460
25461function commitHookEffectListUnmount(flags, finishedWork, nearestMountedAncestor) {
25462 var updateQueue = finishedWork.updateQueue;
25463 var lastEffect = updateQueue !== null ? updateQueue.lastEffect : null;
25464
25465 if (lastEffect !== null) {
25466 var firstEffect = lastEffect.next;
25467 var effect = firstEffect;
25468
25469 do {
25470 if ((effect.tag & flags) === flags) {
25471 // Unmount
25472 var inst = effect.inst;
25473 var destroy = inst.destroy;
25474
25475 if (destroy !== undefined) {
25476 inst.destroy = undefined;
25477
25478 {
25479 if ((flags & Passive) !== NoFlags) {
25480 markComponentPassiveEffectUnmountStarted(finishedWork);
25481 } else if ((flags & Layout) !== NoFlags) {
25482 markComponentLayoutEffectUnmountStarted(finishedWork);
25483 }
25484 }
25485
25486 {
25487 if ((flags & Insertion) !== NoFlags) {
25488 setIsRunningInsertionEffect(true);
25489 }
25490 }
25491
25492 safelyCallDestroy(finishedWork, nearestMountedAncestor, destroy);
25493
25494 {
25495 if ((flags & Insertion) !== NoFlags) {
25496 setIsRunningInsertionEffect(false);
25497 }
25498 }
25499
25500 {
25501 if ((flags & Passive) !== NoFlags) {
25502 markComponentPassiveEffectUnmountStopped();
25503 } else if ((flags & Layout) !== NoFlags) {
25504 markComponentLayoutEffectUnmountStopped();
25505 }
25506 }
25507 }
25508 }
25509
25510 effect = effect.next;
25511 } while (effect !== firstEffect);
25512 }
25513}
25514
25515function commitHookEffectListMount(flags, finishedWork) {
25516 var updateQueue = finishedWork.updateQueue;
25517 var lastEffect = updateQueue !== null ? updateQueue.lastEffect : null;
25518
25519 if (lastEffect !== null) {
25520 var firstEffect = lastEffect.next;
25521 var effect = firstEffect;
25522
25523 do {
25524 if ((effect.tag & flags) === flags) {
25525 {
25526 if ((flags & Passive) !== NoFlags) {
25527 markComponentPassiveEffectMountStarted(finishedWork);
25528 } else if ((flags & Layout) !== NoFlags) {
25529 markComponentLayoutEffectMountStarted(finishedWork);
25530 }
25531 } // Mount
25532
25533
25534 var create = effect.create;
25535
25536 {
25537 if ((flags & Insertion) !== NoFlags) {
25538 setIsRunningInsertionEffect(true);
25539 }
25540 }
25541
25542 var inst = effect.inst;
25543 var destroy = create();
25544 inst.destroy = destroy;
25545
25546 {
25547 if ((flags & Insertion) !== NoFlags) {
25548 setIsRunningInsertionEffect(false);
25549 }
25550 }
25551
25552 {
25553 if ((flags & Passive) !== NoFlags) {
25554 markComponentPassiveEffectMountStopped();
25555 } else if ((flags & Layout) !== NoFlags) {
25556 markComponentLayoutEffectMountStopped();
25557 }
25558 }
25559
25560 {
25561 if (destroy !== undefined && typeof destroy !== 'function') {
25562 var hookName = void 0;
25563
25564 if ((effect.tag & Layout) !== NoFlags$1) {
25565 hookName = 'useLayoutEffect';
25566 } else if ((effect.tag & Insertion) !== NoFlags$1) {
25567 hookName = 'useInsertionEffect';
25568 } else {
25569 hookName = 'useEffect';
25570 }
25571
25572 var addendum = void 0;
25573
25574 if (destroy === null) {
25575 addendum = ' You returned null. If your effect does not require clean ' + 'up, return undefined (or nothing).';
25576 } else if (typeof destroy.then === 'function') {
25577 addendum = '\n\nIt looks like you wrote ' + hookName + '(async () => ...) or returned a Promise. ' + 'Instead, write the async function inside your effect ' + 'and call it immediately:\n\n' + hookName + '(() => {\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://react.dev/link/hooks-data-fetching';
25578 } else {
25579 addendum = ' You returned: ' + destroy;
25580 }
25581
25582 error('%s must not return anything besides a function, ' + 'which is used for clean-up.%s', hookName, addendum);
25583 }
25584 }
25585 }
25586
25587 effect = effect.next;
25588 } while (effect !== firstEffect);
25589 }
25590}
25591
25592function commitPassiveEffectDurations(finishedRoot, finishedWork) {
25593 if (getExecutionContext() & CommitContext) {
25594 // Only Profilers with work in their subtree will have an Update effect scheduled.
25595 if ((finishedWork.flags & Update) !== NoFlags$1) {
25596 switch (finishedWork.tag) {
25597 case Profiler:
25598 {
25599 var passiveEffectDuration = finishedWork.stateNode.passiveEffectDuration;
25600 var _finishedWork$memoize = finishedWork.memoizedProps,
25601 id = _finishedWork$memoize.id,
25602 onPostCommit = _finishedWork$memoize.onPostCommit; // This value will still reflect the previous commit phase.
25603 // It does not get reset until the start of the next commit phase.
25604
25605 var commitTime = getCommitTime();
25606 var phase = finishedWork.alternate === null ? 'mount' : 'update';
25607
25608 {
25609 if (isCurrentUpdateNested()) {
25610 phase = 'nested-update';
25611 }
25612 }
25613
25614 if (typeof onPostCommit === 'function') {
25615 onPostCommit(id, phase, passiveEffectDuration, commitTime);
25616 } // Bubble times to the next nearest ancestor Profiler.
25617 // After we process that Profiler, we'll bubble further up.
25618
25619
25620 var parentFiber = finishedWork.return;
25621
25622 outer: while (parentFiber !== null) {
25623 switch (parentFiber.tag) {
25624 case HostRoot:
25625 var root = parentFiber.stateNode;
25626 root.passiveEffectDuration += passiveEffectDuration;
25627 break outer;
25628
25629 case Profiler:
25630 var parentStateNode = parentFiber.stateNode;
25631 parentStateNode.passiveEffectDuration += passiveEffectDuration;
25632 break outer;
25633 }
25634
25635 parentFiber = parentFiber.return;
25636 }
25637
25638 break;
25639 }
25640 }
25641 }
25642 }
25643}
25644
25645function commitHookLayoutEffects(finishedWork, hookFlags) {
25646 // At this point layout effects have already been destroyed (during mutation phase).
25647 // This is done to prevent sibling component effects from interfering with each other,
25648 // e.g. a destroy function in one component should never override a ref set
25649 // by a create function in another component during the same commit.
25650 if (shouldProfile(finishedWork)) {
25651 try {
25652 startLayoutEffectTimer();
25653 commitHookEffectListMount(hookFlags, finishedWork);
25654 } catch (error) {
25655 captureCommitPhaseError(finishedWork, finishedWork.return, error);
25656 }
25657
25658 recordLayoutEffectDuration(finishedWork);
25659 } else {
25660 try {
25661 commitHookEffectListMount(hookFlags, finishedWork);
25662 } catch (error) {
25663 captureCommitPhaseError(finishedWork, finishedWork.return, error);
25664 }
25665 }
25666}
25667
25668function commitClassLayoutLifecycles(finishedWork, current) {
25669 var instance = finishedWork.stateNode;
25670
25671 if (current === null) {
25672 // We could update instance props and state here,
25673 // but instead we rely on them being set during last render.
25674 // TODO: revisit this when we implement resuming.
25675 {
25676 if (!finishedWork.type.defaultProps && !('ref' in finishedWork.memoizedProps) && !didWarnAboutReassigningProps) {
25677 if (instance.props !== finishedWork.memoizedProps) {
25678 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.', getComponentNameFromFiber(finishedWork) || 'instance');
25679 }
25680
25681 if (instance.state !== finishedWork.memoizedState) {
25682 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.state`. ' + 'Please file an issue.', getComponentNameFromFiber(finishedWork) || 'instance');
25683 }
25684 }
25685 }
25686
25687 if (shouldProfile(finishedWork)) {
25688 try {
25689 startLayoutEffectTimer();
25690 instance.componentDidMount();
25691 } catch (error) {
25692 captureCommitPhaseError(finishedWork, finishedWork.return, error);
25693 }
25694
25695 recordLayoutEffectDuration(finishedWork);
25696 } else {
25697 try {
25698 instance.componentDidMount();
25699 } catch (error) {
25700 captureCommitPhaseError(finishedWork, finishedWork.return, error);
25701 }
25702 }
25703 } else {
25704 var prevProps = resolveClassComponentProps(finishedWork.type, current.memoizedProps);
25705 var prevState = current.memoizedState; // We could update instance props and state here,
25706 // but instead we rely on them being set during last render.
25707 // TODO: revisit this when we implement resuming.
25708
25709 {
25710 if (!finishedWork.type.defaultProps && !('ref' in finishedWork.memoizedProps) && !didWarnAboutReassigningProps) {
25711 if (instance.props !== finishedWork.memoizedProps) {
25712 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.', getComponentNameFromFiber(finishedWork) || 'instance');
25713 }
25714
25715 if (instance.state !== finishedWork.memoizedState) {
25716 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.state`. ' + 'Please file an issue.', getComponentNameFromFiber(finishedWork) || 'instance');
25717 }
25718 }
25719 }
25720
25721 if (shouldProfile(finishedWork)) {
25722 try {
25723 startLayoutEffectTimer();
25724 instance.componentDidUpdate(prevProps, prevState, instance.__reactInternalSnapshotBeforeUpdate);
25725 } catch (error) {
25726 captureCommitPhaseError(finishedWork, finishedWork.return, error);
25727 }
25728
25729 recordLayoutEffectDuration(finishedWork);
25730 } else {
25731 try {
25732 instance.componentDidUpdate(prevProps, prevState, instance.__reactInternalSnapshotBeforeUpdate);
25733 } catch (error) {
25734 captureCommitPhaseError(finishedWork, finishedWork.return, error);
25735 }
25736 }
25737 }
25738}
25739
25740function commitClassCallbacks(finishedWork) {
25741 // TODO: I think this is now always non-null by the time it reaches the
25742 // commit phase. Consider removing the type check.
25743 var updateQueue = finishedWork.updateQueue;
25744
25745 if (updateQueue !== null) {
25746 var instance = finishedWork.stateNode;
25747
25748 {
25749 if (!finishedWork.type.defaultProps && !('ref' in finishedWork.memoizedProps) && !didWarnAboutReassigningProps) {
25750 if (instance.props !== finishedWork.memoizedProps) {
25751 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.', getComponentNameFromFiber(finishedWork) || 'instance');
25752 }
25753
25754 if (instance.state !== finishedWork.memoizedState) {
25755 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.state`. ' + 'Please file an issue.', getComponentNameFromFiber(finishedWork) || 'instance');
25756 }
25757 }
25758 } // We could update instance props and state here,
25759 // but instead we rely on them being set during last render.
25760 // TODO: revisit this when we implement resuming.
25761
25762
25763 try {
25764 commitCallbacks(updateQueue, instance);
25765 } catch (error) {
25766 captureCommitPhaseError(finishedWork, finishedWork.return, error);
25767 }
25768 }
25769}
25770
25771function commitHostComponentMount(finishedWork) {
25772 var type = finishedWork.type;
25773 var props = finishedWork.memoizedProps;
25774 var instance = finishedWork.stateNode;
25775
25776 try {
25777 commitMount(instance, type, props, finishedWork);
25778 } catch (error) {
25779 captureCommitPhaseError(finishedWork, finishedWork.return, error);
25780 }
25781}
25782
25783function commitProfilerUpdate(finishedWork, current) {
25784 if (getExecutionContext() & CommitContext) {
25785 try {
25786 var _finishedWork$memoize2 = finishedWork.memoizedProps,
25787 onCommit = _finishedWork$memoize2.onCommit,
25788 onRender = _finishedWork$memoize2.onRender;
25789 var effectDuration = finishedWork.stateNode.effectDuration;
25790 var commitTime = getCommitTime();
25791 var phase = current === null ? 'mount' : 'update';
25792
25793 if (enableProfilerNestedUpdatePhase) {
25794 if (isCurrentUpdateNested()) {
25795 phase = 'nested-update';
25796 }
25797 }
25798
25799 if (typeof onRender === 'function') {
25800 onRender(finishedWork.memoizedProps.id, phase, finishedWork.actualDuration, finishedWork.treeBaseDuration, finishedWork.actualStartTime, commitTime);
25801 }
25802
25803 if (enableProfilerCommitHooks) {
25804 if (typeof onCommit === 'function') {
25805 onCommit(finishedWork.memoizedProps.id, phase, effectDuration, commitTime);
25806 } // Schedule a passive effect for this Profiler to call onPostCommit hooks.
25807 // This effect should be scheduled even if there is no onPostCommit callback for this Profiler,
25808 // because the effect is also where times bubble to parent Profilers.
25809
25810
25811 enqueuePendingPassiveProfilerEffect(finishedWork); // Propagate layout effect durations to the next nearest Profiler ancestor.
25812 // Do not reset these values until the next render so DevTools has a chance to read them first.
25813
25814 var parentFiber = finishedWork.return;
25815
25816 outer: while (parentFiber !== null) {
25817 switch (parentFiber.tag) {
25818 case HostRoot:
25819 var root = parentFiber.stateNode;
25820 root.effectDuration += effectDuration;
25821 break outer;
25822
25823 case Profiler:
25824 var parentStateNode = parentFiber.stateNode;
25825 parentStateNode.effectDuration += effectDuration;
25826 break outer;
25827 }
25828
25829 parentFiber = parentFiber.return;
25830 }
25831 }
25832 } catch (error) {
25833 captureCommitPhaseError(finishedWork, finishedWork.return, error);
25834 }
25835 }
25836}
25837
25838function commitLayoutEffectOnFiber(finishedRoot, current, finishedWork, committedLanes) {
25839 // When updating this function, also update reappearLayoutEffects, which does
25840 // most of the same things when an offscreen tree goes from hidden -> visible.
25841 var flags = finishedWork.flags;
25842
25843 switch (finishedWork.tag) {
25844 case FunctionComponent:
25845 case ForwardRef:
25846 case SimpleMemoComponent:
25847 {
25848 recursivelyTraverseLayoutEffects(finishedRoot, finishedWork);
25849
25850 if (flags & Update) {
25851 commitHookLayoutEffects(finishedWork, Layout | HasEffect);
25852 }
25853
25854 break;
25855 }
25856
25857 case ClassComponent:
25858 {
25859 recursivelyTraverseLayoutEffects(finishedRoot, finishedWork);
25860
25861 if (flags & Update) {
25862 commitClassLayoutLifecycles(finishedWork, current);
25863 }
25864
25865 if (flags & Callback) {
25866 commitClassCallbacks(finishedWork);
25867 }
25868
25869 if (flags & Ref) {
25870 safelyAttachRef(finishedWork, finishedWork.return);
25871 }
25872
25873 break;
25874 }
25875
25876 case HostRoot:
25877 {
25878 recursivelyTraverseLayoutEffects(finishedRoot, finishedWork);
25879
25880 if (flags & Callback) {
25881 // TODO: I think this is now always non-null by the time it reaches the
25882 // commit phase. Consider removing the type check.
25883 var updateQueue = finishedWork.updateQueue;
25884
25885 if (updateQueue !== null) {
25886 var instance = null;
25887
25888 if (finishedWork.child !== null) {
25889 switch (finishedWork.child.tag) {
25890 case HostSingleton:
25891 case HostComponent:
25892 instance = getPublicInstance(finishedWork.child.stateNode);
25893 break;
25894
25895 case ClassComponent:
25896 instance = finishedWork.child.stateNode;
25897 break;
25898 }
25899 }
25900
25901 try {
25902 commitCallbacks(updateQueue, instance);
25903 } catch (error) {
25904 captureCommitPhaseError(finishedWork, finishedWork.return, error);
25905 }
25906 }
25907 }
25908
25909 break;
25910 }
25911
25912 case HostHoistable:
25913 {
25914 {
25915 recursivelyTraverseLayoutEffects(finishedRoot, finishedWork);
25916
25917 if (flags & Ref) {
25918 safelyAttachRef(finishedWork, finishedWork.return);
25919 }
25920
25921 break;
25922 } // Fall through
25923
25924 }
25925
25926 case HostSingleton:
25927 case HostComponent:
25928 {
25929 recursivelyTraverseLayoutEffects(finishedRoot, finishedWork); // Renderers may schedule work to be done after host components are mounted
25930 // (eg DOM renderer may schedule auto-focus for inputs and form controls).
25931 // These effects should only be committed when components are first mounted,
25932 // aka when there is no current/alternate.
25933
25934 if (current === null && flags & Update) {
25935 commitHostComponentMount(finishedWork);
25936 }
25937
25938 if (flags & Ref) {
25939 safelyAttachRef(finishedWork, finishedWork.return);
25940 }
25941
25942 break;
25943 }
25944
25945 case Profiler:
25946 {
25947 recursivelyTraverseLayoutEffects(finishedRoot, finishedWork); // TODO: Should this fire inside an offscreen tree? Or should it wait to
25948 // fire when the tree becomes visible again.
25949
25950 if (flags & Update) {
25951 commitProfilerUpdate(finishedWork, current);
25952 }
25953
25954 break;
25955 }
25956
25957 case SuspenseComponent:
25958 {
25959 recursivelyTraverseLayoutEffects(finishedRoot, finishedWork);
25960
25961 if (flags & Update) {
25962 commitSuspenseHydrationCallbacks(finishedRoot, finishedWork);
25963 }
25964
25965 break;
25966 }
25967
25968 case OffscreenComponent:
25969 {
25970 var isModernRoot = disableLegacyMode ;
25971
25972 if (isModernRoot) {
25973 var isHidden = finishedWork.memoizedState !== null;
25974 var newOffscreenSubtreeIsHidden = isHidden || offscreenSubtreeIsHidden;
25975
25976 if (newOffscreenSubtreeIsHidden) ; else {
25977 // The Offscreen tree is visible.
25978 var wasHidden = current !== null && current.memoizedState !== null;
25979 var newOffscreenSubtreeWasHidden = wasHidden || offscreenSubtreeWasHidden;
25980 var prevOffscreenSubtreeIsHidden = offscreenSubtreeIsHidden;
25981 var prevOffscreenSubtreeWasHidden = offscreenSubtreeWasHidden;
25982 offscreenSubtreeIsHidden = newOffscreenSubtreeIsHidden;
25983 offscreenSubtreeWasHidden = newOffscreenSubtreeWasHidden;
25984
25985 if (offscreenSubtreeWasHidden && !prevOffscreenSubtreeWasHidden) {
25986 // This is the root of a reappearing boundary. As we continue
25987 // traversing the layout effects, we must also re-mount layout
25988 // effects that were unmounted when the Offscreen subtree was
25989 // hidden. So this is a superset of the normal commitLayoutEffects.
25990 var includeWorkInProgressEffects = (finishedWork.subtreeFlags & LayoutMask) !== NoFlags$1;
25991 recursivelyTraverseReappearLayoutEffects(finishedRoot, finishedWork, includeWorkInProgressEffects);
25992 } else {
25993 recursivelyTraverseLayoutEffects(finishedRoot, finishedWork);
25994 }
25995
25996 offscreenSubtreeIsHidden = prevOffscreenSubtreeIsHidden;
25997 offscreenSubtreeWasHidden = prevOffscreenSubtreeWasHidden;
25998 }
25999 } else {
26000 recursivelyTraverseLayoutEffects(finishedRoot, finishedWork);
26001 }
26002
26003 if (flags & Ref) {
26004 var props = finishedWork.memoizedProps;
26005
26006 if (props.mode === 'manual') {
26007 safelyAttachRef(finishedWork, finishedWork.return);
26008 } else {
26009 safelyDetachRef(finishedWork, finishedWork.return);
26010 }
26011 }
26012
26013 break;
26014 }
26015
26016 default:
26017 {
26018 recursivelyTraverseLayoutEffects(finishedRoot, finishedWork);
26019 break;
26020 }
26021 }
26022}
26023
26024function hideOrUnhideAllChildren(finishedWork, isHidden) {
26025 // Only hide or unhide the top-most host nodes.
26026 var hostSubtreeRoot = null;
26027
26028 {
26029 // We only have the top Fiber that was inserted but we need to recurse down its
26030 // children to find all the terminal nodes.
26031 var node = finishedWork;
26032
26033 while (true) {
26034 if (node.tag === HostComponent || (node.tag === HostHoistable ) || (node.tag === HostSingleton )) {
26035 if (hostSubtreeRoot === null) {
26036 hostSubtreeRoot = node;
26037
26038 try {
26039 var instance = node.stateNode;
26040
26041 if (isHidden) {
26042 hideInstance(instance);
26043 } else {
26044 unhideInstance(node.stateNode, node.memoizedProps);
26045 }
26046 } catch (error) {
26047 captureCommitPhaseError(finishedWork, finishedWork.return, error);
26048 }
26049 }
26050 } else if (node.tag === HostText) {
26051 if (hostSubtreeRoot === null) {
26052 try {
26053 var _instance = node.stateNode;
26054
26055 if (isHidden) {
26056 hideTextInstance(_instance);
26057 } else {
26058 unhideTextInstance(_instance, node.memoizedProps);
26059 }
26060 } catch (error) {
26061 captureCommitPhaseError(finishedWork, finishedWork.return, error);
26062 }
26063 }
26064 } else if ((node.tag === OffscreenComponent || node.tag === LegacyHiddenComponent) && node.memoizedState !== null && node !== finishedWork) ; else if (node.child !== null) {
26065 node.child.return = node;
26066 node = node.child;
26067 continue;
26068 }
26069
26070 if (node === finishedWork) {
26071 return;
26072 }
26073
26074 while (node.sibling === null) {
26075 if (node.return === null || node.return === finishedWork) {
26076 return;
26077 }
26078
26079 if (hostSubtreeRoot === node) {
26080 hostSubtreeRoot = null;
26081 }
26082
26083 node = node.return;
26084 }
26085
26086 if (hostSubtreeRoot === node) {
26087 hostSubtreeRoot = null;
26088 }
26089
26090 node.sibling.return = node.return;
26091 node = node.sibling;
26092 }
26093 }
26094}
26095
26096function commitAttachRef(finishedWork) {
26097 var ref = finishedWork.ref;
26098
26099 if (ref !== null) {
26100 var instance = finishedWork.stateNode;
26101 var instanceToUse;
26102
26103 switch (finishedWork.tag) {
26104 case HostHoistable:
26105 case HostSingleton:
26106 case HostComponent:
26107 instanceToUse = getPublicInstance(instance);
26108 break;
26109
26110 default:
26111 instanceToUse = instance;
26112 } // Moved outside to ensure DCE works with this flag
26113
26114 if (typeof ref === 'function') {
26115 if (shouldProfile(finishedWork)) {
26116 try {
26117 startLayoutEffectTimer();
26118 finishedWork.refCleanup = ref(instanceToUse);
26119 } finally {
26120 recordLayoutEffectDuration(finishedWork);
26121 }
26122 } else {
26123 finishedWork.refCleanup = ref(instanceToUse);
26124 }
26125 } else {
26126 {
26127 // TODO: We should move these warnings to happen during the render
26128 // phase (markRef).
26129 if (typeof ref === 'string') {
26130 error('String refs are no longer supported.');
26131 } else if (!ref.hasOwnProperty('current')) {
26132 error('Unexpected ref object provided for %s. ' + 'Use either a ref-setter function or React.createRef().', getComponentNameFromFiber(finishedWork));
26133 }
26134 } // $FlowFixMe[incompatible-use] unable to narrow type to the non-function case
26135
26136
26137 ref.current = instanceToUse;
26138 }
26139 }
26140}
26141
26142function detachFiberMutation(fiber) {
26143 // Cut off the return pointer to disconnect it from the tree.
26144 // This enables us to detect and warn against state updates on an unmounted component.
26145 // It also prevents events from bubbling from within disconnected components.
26146 //
26147 // Ideally, we should also clear the child pointer of the parent alternate to let this
26148 // get GC:ed but we don't know which for sure which parent is the current
26149 // one so we'll settle for GC:ing the subtree of this child.
26150 // This child itself will be GC:ed when the parent updates the next time.
26151 //
26152 // Note that we can't clear child or sibling pointers yet.
26153 // They're needed for passive effects and for findDOMNode.
26154 // We defer those fields, and all other cleanup, to the passive phase (see detachFiberAfterEffects).
26155 //
26156 // Don't reset the alternate yet, either. We need that so we can detach the
26157 // alternate's fields in the passive phase. Clearing the return pointer is
26158 // sufficient for findDOMNode semantics.
26159 var alternate = fiber.alternate;
26160
26161 if (alternate !== null) {
26162 alternate.return = null;
26163 }
26164
26165 fiber.return = null;
26166}
26167
26168function detachFiberAfterEffects(fiber) {
26169 var alternate = fiber.alternate;
26170
26171 if (alternate !== null) {
26172 fiber.alternate = null;
26173 detachFiberAfterEffects(alternate);
26174 } // Clear cyclical Fiber fields. This level alone is designed to roughly
26175 // approximate the planned Fiber refactor. In that world, `setState` will be
26176 // bound to a special "instance" object instead of a Fiber. The Instance
26177 // object will not have any of these fields. It will only be connected to
26178 // the fiber tree via a single link at the root. So if this level alone is
26179 // sufficient to fix memory issues, that bodes well for our plans.
26180
26181
26182 fiber.child = null;
26183 fiber.deletions = null;
26184 fiber.sibling = null; // The `stateNode` is cyclical because on host nodes it points to the host
26185 // tree, which has its own pointers to children, parents, and siblings.
26186 // The other host nodes also point back to fibers, so we should detach that
26187 // one, too.
26188
26189 if (fiber.tag === HostComponent) {
26190 var hostInstance = fiber.stateNode;
26191
26192 if (hostInstance !== null) {
26193 detachDeletedInstance(hostInstance);
26194 }
26195 }
26196
26197 fiber.stateNode = null;
26198
26199 {
26200 fiber._debugOwner = null;
26201 } // Theoretically, nothing in here should be necessary, because we already
26202 // disconnected the fiber from the tree. So even if something leaks this
26203 // particular fiber, it won't leak anything else.
26204
26205
26206 fiber.return = null;
26207 fiber.dependencies = null;
26208 fiber.memoizedProps = null;
26209 fiber.memoizedState = null;
26210 fiber.pendingProps = null;
26211 fiber.stateNode = null; // TODO: Move to `commitPassiveUnmountInsideDeletedTreeOnFiber` instead.
26212
26213 fiber.updateQueue = null;
26214}
26215
26216function getHostParentFiber(fiber) {
26217 var parent = fiber.return;
26218
26219 while (parent !== null) {
26220 if (isHostParent(parent)) {
26221 return parent;
26222 }
26223
26224 parent = parent.return;
26225 }
26226
26227 throw new Error('Expected to find a host parent. This error is likely caused by a bug ' + 'in React. Please file an issue.');
26228}
26229
26230function isHostParent(fiber) {
26231 return fiber.tag === HostComponent || fiber.tag === HostRoot || (fiber.tag === HostHoistable ) || (fiber.tag === HostSingleton ) || fiber.tag === HostPortal;
26232}
26233
26234function getHostSibling(fiber) {
26235 // We're going to search forward into the tree until we find a sibling host
26236 // node. Unfortunately, if multiple insertions are done in a row we have to
26237 // search past them. This leads to exponential search for the next sibling.
26238 // TODO: Find a more efficient way to do this.
26239 var node = fiber;
26240
26241 siblings: while (true) {
26242 // If we didn't find anything, let's try the next sibling.
26243 while (node.sibling === null) {
26244 if (node.return === null || isHostParent(node.return)) {
26245 // If we pop out of the root or hit the parent the fiber we are the
26246 // last sibling.
26247 return null;
26248 } // $FlowFixMe[incompatible-type] found when upgrading Flow
26249
26250
26251 node = node.return;
26252 }
26253
26254 node.sibling.return = node.return;
26255 node = node.sibling;
26256
26257 while (node.tag !== HostComponent && node.tag !== HostText && (node.tag !== HostSingleton) && node.tag !== DehydratedFragment) {
26258 // If it is not host node and, we might have a host node inside it.
26259 // Try to search down until we find one.
26260 if (node.flags & Placement) {
26261 // If we don't have a child, try the siblings instead.
26262 continue siblings;
26263 } // If we don't have a child, try the siblings instead.
26264 // We also skip portals because they are not part of this host tree.
26265
26266
26267 if (node.child === null || node.tag === HostPortal) {
26268 continue siblings;
26269 } else {
26270 node.child.return = node;
26271 node = node.child;
26272 }
26273 } // Check if this host node is stable or about to be placed.
26274
26275
26276 if (!(node.flags & Placement)) {
26277 // Found it!
26278 return node.stateNode;
26279 }
26280 }
26281}
26282
26283function commitPlacement(finishedWork) {
26284
26285 {
26286 if (finishedWork.tag === HostSingleton) {
26287 // Singletons are already in the Host and don't need to be placed
26288 // Since they operate somewhat like Portals though their children will
26289 // have Placement and will get placed inside them
26290 return;
26291 }
26292 } // Recursively insert all host nodes into the parent.
26293
26294
26295 var parentFiber = getHostParentFiber(finishedWork);
26296
26297 switch (parentFiber.tag) {
26298 case HostSingleton:
26299 {
26300 {
26301 var parent = parentFiber.stateNode;
26302 var before = getHostSibling(finishedWork); // We only have the top Fiber that was inserted but we need to recurse down its
26303 // children to find all the terminal nodes.
26304
26305 insertOrAppendPlacementNode(finishedWork, before, parent);
26306 break;
26307 } // Fall through
26308
26309 }
26310
26311 case HostComponent:
26312 {
26313 var _parent = parentFiber.stateNode;
26314
26315 if (parentFiber.flags & ContentReset) {
26316 // Reset the text content of the parent before doing any insertions
26317 resetTextContent(_parent); // Clear ContentReset from the effect tag
26318
26319 parentFiber.flags &= ~ContentReset;
26320 }
26321
26322 var _before = getHostSibling(finishedWork); // We only have the top Fiber that was inserted but we need to recurse down its
26323 // children to find all the terminal nodes.
26324
26325
26326 insertOrAppendPlacementNode(finishedWork, _before, _parent);
26327 break;
26328 }
26329
26330 case HostRoot:
26331 case HostPortal:
26332 {
26333 var _parent2 = parentFiber.stateNode.containerInfo;
26334
26335 var _before2 = getHostSibling(finishedWork);
26336
26337 insertOrAppendPlacementNodeIntoContainer(finishedWork, _before2, _parent2);
26338 break;
26339 }
26340
26341 default:
26342 throw new Error('Invalid host parent fiber. This error is likely caused by a bug ' + 'in React. Please file an issue.');
26343 }
26344}
26345
26346function insertOrAppendPlacementNodeIntoContainer(node, before, parent) {
26347 var tag = node.tag;
26348 var isHost = tag === HostComponent || tag === HostText;
26349
26350 if (isHost) {
26351 var stateNode = node.stateNode;
26352
26353 if (before) {
26354 insertInContainerBefore(parent, stateNode, before);
26355 } else {
26356 appendChildToContainer(parent, stateNode);
26357 }
26358 } else if (tag === HostPortal || (tag === HostSingleton )) ; else {
26359 var child = node.child;
26360
26361 if (child !== null) {
26362 insertOrAppendPlacementNodeIntoContainer(child, before, parent);
26363 var sibling = child.sibling;
26364
26365 while (sibling !== null) {
26366 insertOrAppendPlacementNodeIntoContainer(sibling, before, parent);
26367 sibling = sibling.sibling;
26368 }
26369 }
26370 }
26371}
26372
26373function insertOrAppendPlacementNode(node, before, parent) {
26374 var tag = node.tag;
26375 var isHost = tag === HostComponent || tag === HostText;
26376
26377 if (isHost) {
26378 var stateNode = node.stateNode;
26379
26380 if (before) {
26381 insertBefore(parent, stateNode, before);
26382 } else {
26383 appendChild(parent, stateNode);
26384 }
26385 } else if (tag === HostPortal || (tag === HostSingleton )) ; else {
26386 var child = node.child;
26387
26388 if (child !== null) {
26389 insertOrAppendPlacementNode(child, before, parent);
26390 var sibling = child.sibling;
26391
26392 while (sibling !== null) {
26393 insertOrAppendPlacementNode(sibling, before, parent);
26394 sibling = sibling.sibling;
26395 }
26396 }
26397 }
26398} // These are tracked on the stack as we recursively traverse a
26399// deleted subtree.
26400// TODO: Update these during the whole mutation phase, not just during
26401// a deletion.
26402
26403
26404var hostParent = null;
26405var hostParentIsContainer = false;
26406
26407function commitDeletionEffects(root, returnFiber, deletedFiber) {
26408 {
26409 // We only have the top Fiber that was deleted but we need to recurse down its
26410 // children to find all the terminal nodes.
26411 // Recursively delete all host nodes from the parent, detach refs, clean
26412 // up mounted layout effects, and call componentWillUnmount.
26413 // We only need to remove the topmost host child in each branch. But then we
26414 // still need to keep traversing to unmount effects, refs, and cWU. TODO: We
26415 // could split this into two separate traversals functions, where the second
26416 // one doesn't include any removeChild logic. This is maybe the same
26417 // function as "disappearLayoutEffects" (or whatever that turns into after
26418 // the layout phase is refactored to use recursion).
26419 // Before starting, find the nearest host parent on the stack so we know
26420 // which instance/container to remove the children from.
26421 // TODO: Instead of searching up the fiber return path on every deletion, we
26422 // can track the nearest host component on the JS stack as we traverse the
26423 // tree during the commit phase. This would make insertions faster, too.
26424 var parent = returnFiber;
26425
26426 findParent: while (parent !== null) {
26427 switch (parent.tag) {
26428 case HostSingleton:
26429 case HostComponent:
26430 {
26431 hostParent = parent.stateNode;
26432 hostParentIsContainer = false;
26433 break findParent;
26434 }
26435
26436 case HostRoot:
26437 {
26438 hostParent = parent.stateNode.containerInfo;
26439 hostParentIsContainer = true;
26440 break findParent;
26441 }
26442
26443 case HostPortal:
26444 {
26445 hostParent = parent.stateNode.containerInfo;
26446 hostParentIsContainer = true;
26447 break findParent;
26448 }
26449 }
26450
26451 parent = parent.return;
26452 }
26453
26454 if (hostParent === null) {
26455 throw new Error('Expected to find a host parent. This error is likely caused by ' + 'a bug in React. Please file an issue.');
26456 }
26457
26458 commitDeletionEffectsOnFiber(root, returnFiber, deletedFiber);
26459 hostParent = null;
26460 hostParentIsContainer = false;
26461 }
26462
26463 detachFiberMutation(deletedFiber);
26464}
26465
26466function recursivelyTraverseDeletionEffects(finishedRoot, nearestMountedAncestor, parent) {
26467 // TODO: Use a static flag to skip trees that don't have unmount effects
26468 var child = parent.child;
26469
26470 while (child !== null) {
26471 commitDeletionEffectsOnFiber(finishedRoot, nearestMountedAncestor, child);
26472 child = child.sibling;
26473 }
26474}
26475
26476function commitDeletionEffectsOnFiber(finishedRoot, nearestMountedAncestor, deletedFiber) {
26477 onCommitUnmount(deletedFiber); // The cases in this outer switch modify the stack before they traverse
26478 // into their subtree. There are simpler cases in the inner switch
26479 // that don't modify the stack.
26480
26481 switch (deletedFiber.tag) {
26482 case HostHoistable:
26483 {
26484 {
26485 if (!offscreenSubtreeWasHidden) {
26486 safelyDetachRef(deletedFiber, nearestMountedAncestor);
26487 }
26488
26489 recursivelyTraverseDeletionEffects(finishedRoot, nearestMountedAncestor, deletedFiber);
26490
26491 if (deletedFiber.memoizedState) {
26492 releaseResource(deletedFiber.memoizedState);
26493 } else if (deletedFiber.stateNode) {
26494 unmountHoistable(deletedFiber.stateNode);
26495 }
26496
26497 return;
26498 } // Fall through
26499
26500 }
26501
26502 case HostSingleton:
26503 {
26504 {
26505 if (!offscreenSubtreeWasHidden) {
26506 safelyDetachRef(deletedFiber, nearestMountedAncestor);
26507 }
26508
26509 var prevHostParent = hostParent;
26510 var prevHostParentIsContainer = hostParentIsContainer;
26511 hostParent = deletedFiber.stateNode;
26512 recursivelyTraverseDeletionEffects(finishedRoot, nearestMountedAncestor, deletedFiber); // Normally this is called in passive unmount effect phase however with
26513 // HostSingleton we warn if you acquire one that is already associated to
26514 // a different fiber. To increase our chances of avoiding this, specifically
26515 // if you keyed a HostSingleton so there will be a delete followed by a Placement
26516 // we treat detach eagerly here
26517
26518 releaseSingletonInstance(deletedFiber.stateNode);
26519 hostParent = prevHostParent;
26520 hostParentIsContainer = prevHostParentIsContainer;
26521 return;
26522 } // Fall through
26523
26524 }
26525
26526 case HostComponent:
26527 {
26528 if (!offscreenSubtreeWasHidden) {
26529 safelyDetachRef(deletedFiber, nearestMountedAncestor);
26530 } // Intentional fallthrough to next branch
26531
26532 }
26533
26534 case HostText:
26535 {
26536 // We only need to remove the nearest host child. Set the host parent
26537 // to `null` on the stack to indicate that nested children don't
26538 // need to be removed.
26539 {
26540 var _prevHostParent = hostParent;
26541 var _prevHostParentIsContainer = hostParentIsContainer;
26542 hostParent = null;
26543 recursivelyTraverseDeletionEffects(finishedRoot, nearestMountedAncestor, deletedFiber);
26544 hostParent = _prevHostParent;
26545 hostParentIsContainer = _prevHostParentIsContainer;
26546
26547 if (hostParent !== null) {
26548 // Now that all the child effects have unmounted, we can remove the
26549 // node from the tree.
26550 if (hostParentIsContainer) {
26551 removeChildFromContainer(hostParent, deletedFiber.stateNode);
26552 } else {
26553 removeChild(hostParent, deletedFiber.stateNode);
26554 }
26555 }
26556 }
26557
26558 return;
26559 }
26560
26561 case DehydratedFragment:
26562 {
26563 // Delete the dehydrated suspense boundary and all of its content.
26564
26565
26566 {
26567 if (hostParent !== null) {
26568 if (hostParentIsContainer) {
26569 clearSuspenseBoundaryFromContainer(hostParent, deletedFiber.stateNode);
26570 } else {
26571 clearSuspenseBoundary(hostParent, deletedFiber.stateNode);
26572 }
26573 }
26574 }
26575
26576 return;
26577 }
26578
26579 case HostPortal:
26580 {
26581 {
26582 // When we go into a portal, it becomes the parent to remove from.
26583 var _prevHostParent2 = hostParent;
26584 var _prevHostParentIsContainer2 = hostParentIsContainer;
26585 hostParent = deletedFiber.stateNode.containerInfo;
26586 hostParentIsContainer = true;
26587 recursivelyTraverseDeletionEffects(finishedRoot, nearestMountedAncestor, deletedFiber);
26588 hostParent = _prevHostParent2;
26589 hostParentIsContainer = _prevHostParentIsContainer2;
26590 }
26591
26592 return;
26593 }
26594
26595 case FunctionComponent:
26596 case ForwardRef:
26597 case MemoComponent:
26598 case SimpleMemoComponent:
26599 {
26600 if (!offscreenSubtreeWasHidden) {
26601 var updateQueue = deletedFiber.updateQueue;
26602
26603 if (updateQueue !== null) {
26604 var lastEffect = updateQueue.lastEffect;
26605
26606 if (lastEffect !== null) {
26607 var firstEffect = lastEffect.next;
26608 var effect = firstEffect;
26609
26610 do {
26611 var tag = effect.tag;
26612 var inst = effect.inst;
26613 var destroy = inst.destroy;
26614
26615 if (destroy !== undefined) {
26616 if ((tag & Insertion) !== NoFlags) {
26617 inst.destroy = undefined;
26618 safelyCallDestroy(deletedFiber, nearestMountedAncestor, destroy);
26619 } else if ((tag & Layout) !== NoFlags) {
26620 {
26621 markComponentLayoutEffectUnmountStarted(deletedFiber);
26622 }
26623
26624 if (shouldProfile(deletedFiber)) {
26625 startLayoutEffectTimer();
26626 inst.destroy = undefined;
26627 safelyCallDestroy(deletedFiber, nearestMountedAncestor, destroy);
26628 recordLayoutEffectDuration(deletedFiber);
26629 } else {
26630 inst.destroy = undefined;
26631 safelyCallDestroy(deletedFiber, nearestMountedAncestor, destroy);
26632 }
26633
26634 {
26635 markComponentLayoutEffectUnmountStopped();
26636 }
26637 }
26638 }
26639
26640 effect = effect.next;
26641 } while (effect !== firstEffect);
26642 }
26643 }
26644 }
26645
26646 recursivelyTraverseDeletionEffects(finishedRoot, nearestMountedAncestor, deletedFiber);
26647 return;
26648 }
26649
26650 case ClassComponent:
26651 {
26652 if (!offscreenSubtreeWasHidden) {
26653 safelyDetachRef(deletedFiber, nearestMountedAncestor);
26654 var instance = deletedFiber.stateNode;
26655
26656 if (typeof instance.componentWillUnmount === 'function') {
26657 safelyCallComponentWillUnmount(deletedFiber, nearestMountedAncestor, instance);
26658 }
26659 }
26660
26661 recursivelyTraverseDeletionEffects(finishedRoot, nearestMountedAncestor, deletedFiber);
26662 return;
26663 }
26664
26665 case ScopeComponent:
26666 {
26667
26668 recursivelyTraverseDeletionEffects(finishedRoot, nearestMountedAncestor, deletedFiber);
26669 return;
26670 }
26671
26672 case OffscreenComponent:
26673 {
26674 safelyDetachRef(deletedFiber, nearestMountedAncestor);
26675
26676 {
26677 // If this offscreen component is hidden, we already unmounted it. Before
26678 // deleting the children, track that it's already unmounted so that we
26679 // don't attempt to unmount the effects again.
26680 // TODO: If the tree is hidden, in most cases we should be able to skip
26681 // over the nested children entirely. An exception is we haven't yet found
26682 // the topmost host node to delete, which we already track on the stack.
26683 // But the other case is portals, which need to be detached no matter how
26684 // deeply they are nested. We should use a subtree flag to track whether a
26685 // subtree includes a nested portal.
26686 var prevOffscreenSubtreeWasHidden = offscreenSubtreeWasHidden;
26687 offscreenSubtreeWasHidden = prevOffscreenSubtreeWasHidden || deletedFiber.memoizedState !== null;
26688 recursivelyTraverseDeletionEffects(finishedRoot, nearestMountedAncestor, deletedFiber);
26689 offscreenSubtreeWasHidden = prevOffscreenSubtreeWasHidden;
26690 }
26691
26692 break;
26693 }
26694
26695 default:
26696 {
26697 recursivelyTraverseDeletionEffects(finishedRoot, nearestMountedAncestor, deletedFiber);
26698 return;
26699 }
26700 }
26701}
26702
26703function commitSuspenseCallback(finishedWork) {
26704}
26705
26706function commitSuspenseHydrationCallbacks(finishedRoot, finishedWork) {
26707
26708 var newState = finishedWork.memoizedState;
26709
26710 if (newState === null) {
26711 var current = finishedWork.alternate;
26712
26713 if (current !== null) {
26714 var prevState = current.memoizedState;
26715
26716 if (prevState !== null) {
26717 var suspenseInstance = prevState.dehydrated;
26718
26719 if (suspenseInstance !== null) {
26720 try {
26721 commitHydratedSuspenseInstance(suspenseInstance);
26722
26723 var hydrationCallbacks, onHydrated; if (enableSuspenseCallback) ;
26724 } catch (error) {
26725 captureCommitPhaseError(finishedWork, finishedWork.return, error);
26726 }
26727 }
26728 }
26729 }
26730 }
26731}
26732
26733function getRetryCache(finishedWork) {
26734 // TODO: Unify the interface for the retry cache so we don't have to switch
26735 // on the tag like this.
26736 switch (finishedWork.tag) {
26737 case SuspenseComponent:
26738 case SuspenseListComponent:
26739 {
26740 var retryCache = finishedWork.stateNode;
26741
26742 if (retryCache === null) {
26743 retryCache = finishedWork.stateNode = new PossiblyWeakSet();
26744 }
26745
26746 return retryCache;
26747 }
26748
26749 case OffscreenComponent:
26750 {
26751 var instance = finishedWork.stateNode;
26752 var _retryCache = instance._retryCache;
26753
26754 if (_retryCache === null) {
26755 _retryCache = instance._retryCache = new PossiblyWeakSet();
26756 }
26757
26758 return _retryCache;
26759 }
26760
26761 default:
26762 {
26763 throw new Error("Unexpected Suspense handler tag (" + finishedWork.tag + "). This is a " + 'bug in React.');
26764 }
26765 }
26766}
26767
26768function detachOffscreenInstance(instance) {
26769 var fiber = instance._current;
26770
26771 if (fiber === null) {
26772 throw new Error('Calling Offscreen.detach before instance handle has been set.');
26773 }
26774
26775 if ((instance._pendingVisibility & OffscreenDetached) !== NoFlags$1) {
26776 // The instance is already detached, this is a noop.
26777 return;
26778 } // TODO: There is an opportunity to optimise this by not entering commit phase
26779 // and unmounting effects directly.
26780
26781
26782 var root = enqueueConcurrentRenderForLane(fiber, SyncLane);
26783
26784 if (root !== null) {
26785 instance._pendingVisibility |= OffscreenDetached;
26786 scheduleUpdateOnFiber(root, fiber, SyncLane);
26787 }
26788}
26789function attachOffscreenInstance(instance) {
26790 var fiber = instance._current;
26791
26792 if (fiber === null) {
26793 throw new Error('Calling Offscreen.detach before instance handle has been set.');
26794 }
26795
26796 if ((instance._pendingVisibility & OffscreenDetached) === NoFlags$1) {
26797 // The instance is already attached, this is a noop.
26798 return;
26799 }
26800
26801 var root = enqueueConcurrentRenderForLane(fiber, SyncLane);
26802
26803 if (root !== null) {
26804 instance._pendingVisibility &= ~OffscreenDetached;
26805 scheduleUpdateOnFiber(root, fiber, SyncLane);
26806 }
26807}
26808
26809function attachSuspenseRetryListeners(finishedWork, wakeables) {
26810 // If this boundary just timed out, then it will have a set of wakeables.
26811 // For each wakeable, attach a listener so that when it resolves, React
26812 // attempts to re-render the boundary in the primary (pre-timeout) state.
26813 var retryCache = getRetryCache(finishedWork);
26814 wakeables.forEach(function (wakeable) {
26815 // Memoize using the boundary fiber to prevent redundant listeners.
26816 var retry = resolveRetryWakeable.bind(null, finishedWork, wakeable);
26817
26818 if (!retryCache.has(wakeable)) {
26819 retryCache.add(wakeable);
26820
26821 {
26822 if (isDevToolsPresent) {
26823 if (inProgressLanes !== null && inProgressRoot !== null) {
26824 // If we have pending work still, associate the original updaters with it.
26825 restorePendingUpdaters(inProgressRoot, inProgressLanes);
26826 } else {
26827 throw Error('Expected finished root and lanes to be set. This is a bug in React.');
26828 }
26829 }
26830 }
26831
26832 wakeable.then(retry, retry);
26833 }
26834 });
26835} // This function detects when a Suspense boundary goes from visible to hidden.
26836function commitMutationEffects(root, finishedWork, committedLanes) {
26837 inProgressLanes = committedLanes;
26838 inProgressRoot = root;
26839 setCurrentFiber(finishedWork);
26840 commitMutationEffectsOnFiber(finishedWork, root);
26841 setCurrentFiber(finishedWork);
26842 inProgressLanes = null;
26843 inProgressRoot = null;
26844}
26845
26846function recursivelyTraverseMutationEffects(root, parentFiber, lanes) {
26847 // Deletions effects can be scheduled on any fiber type. They need to happen
26848 // before the children effects hae fired.
26849 var deletions = parentFiber.deletions;
26850
26851 if (deletions !== null) {
26852 for (var i = 0; i < deletions.length; i++) {
26853 var childToDelete = deletions[i];
26854
26855 try {
26856 commitDeletionEffects(root, parentFiber, childToDelete);
26857 } catch (error) {
26858 captureCommitPhaseError(childToDelete, parentFiber, error);
26859 }
26860 }
26861 }
26862
26863 var prevDebugFiber = getCurrentFiber();
26864
26865 if (parentFiber.subtreeFlags & MutationMask) {
26866 var child = parentFiber.child;
26867
26868 while (child !== null) {
26869 setCurrentFiber(child);
26870 commitMutationEffectsOnFiber(child, root);
26871 child = child.sibling;
26872 }
26873 }
26874
26875 setCurrentFiber(prevDebugFiber);
26876}
26877
26878var currentHoistableRoot = null;
26879
26880function commitMutationEffectsOnFiber(finishedWork, root, lanes) {
26881 var current = finishedWork.alternate;
26882 var flags = finishedWork.flags; // The effect flag should be checked *after* we refine the type of fiber,
26883 // because the fiber tag is more specific. An exception is any flag related
26884 // to reconciliation, because those can be set on all fiber types.
26885
26886 switch (finishedWork.tag) {
26887 case FunctionComponent:
26888 case ForwardRef:
26889 case MemoComponent:
26890 case SimpleMemoComponent:
26891 {
26892 recursivelyTraverseMutationEffects(root, finishedWork);
26893 commitReconciliationEffects(finishedWork);
26894
26895 if (flags & Update) {
26896 try {
26897 commitHookEffectListUnmount(Insertion | HasEffect, finishedWork, finishedWork.return);
26898 commitHookEffectListMount(Insertion | HasEffect, finishedWork);
26899 } catch (error) {
26900 captureCommitPhaseError(finishedWork, finishedWork.return, error);
26901 } // Layout effects are destroyed during the mutation phase so that all
26902 // destroy functions for all fibers are called before any create functions.
26903 // This prevents sibling component effects from interfering with each other,
26904 // e.g. a destroy function in one component should never override a ref set
26905 // by a create function in another component during the same commit.
26906
26907
26908 if (shouldProfile(finishedWork)) {
26909 try {
26910 startLayoutEffectTimer();
26911 commitHookEffectListUnmount(Layout | HasEffect, finishedWork, finishedWork.return);
26912 } catch (error) {
26913 captureCommitPhaseError(finishedWork, finishedWork.return, error);
26914 }
26915
26916 recordLayoutEffectDuration(finishedWork);
26917 } else {
26918 try {
26919 commitHookEffectListUnmount(Layout | HasEffect, finishedWork, finishedWork.return);
26920 } catch (error) {
26921 captureCommitPhaseError(finishedWork, finishedWork.return, error);
26922 }
26923 }
26924 }
26925
26926 return;
26927 }
26928
26929 case ClassComponent:
26930 {
26931 recursivelyTraverseMutationEffects(root, finishedWork);
26932 commitReconciliationEffects(finishedWork);
26933
26934 if (flags & Ref) {
26935 if (current !== null) {
26936 safelyDetachRef(current, current.return);
26937 }
26938 }
26939
26940 if (flags & Callback && offscreenSubtreeIsHidden) {
26941 var updateQueue = finishedWork.updateQueue;
26942
26943 if (updateQueue !== null) {
26944 deferHiddenCallbacks(updateQueue);
26945 }
26946 }
26947
26948 return;
26949 }
26950
26951 case HostHoistable:
26952 {
26953 {
26954 // We cast because we always set the root at the React root and so it cannot be
26955 // null while we are processing mutation effects
26956 var hoistableRoot = currentHoistableRoot;
26957 recursivelyTraverseMutationEffects(root, finishedWork);
26958 commitReconciliationEffects(finishedWork);
26959
26960 if (flags & Ref) {
26961 if (current !== null) {
26962 safelyDetachRef(current, current.return);
26963 }
26964 }
26965
26966 if (flags & Update) {
26967 var currentResource = current !== null ? current.memoizedState : null;
26968 var newResource = finishedWork.memoizedState;
26969
26970 if (current === null) {
26971 // We are mounting a new HostHoistable Fiber. We fork the mount
26972 // behavior based on whether this instance is a Hoistable Instance
26973 // or a Hoistable Resource
26974 if (newResource === null) {
26975 if (finishedWork.stateNode === null) {
26976 finishedWork.stateNode = hydrateHoistable(hoistableRoot, finishedWork.type, finishedWork.memoizedProps, finishedWork);
26977 } else {
26978 mountHoistable(hoistableRoot, finishedWork.type, finishedWork.stateNode);
26979 }
26980 } else {
26981 finishedWork.stateNode = acquireResource(hoistableRoot, newResource, finishedWork.memoizedProps);
26982 }
26983 } else if (currentResource !== newResource) {
26984 // We are moving to or from Hoistable Resource, or between different Hoistable Resources
26985 if (currentResource === null) {
26986 if (current.stateNode !== null) {
26987 unmountHoistable(current.stateNode);
26988 }
26989 } else {
26990 releaseResource(currentResource);
26991 }
26992
26993 if (newResource === null) {
26994 mountHoistable(hoistableRoot, finishedWork.type, finishedWork.stateNode);
26995 } else {
26996 acquireResource(hoistableRoot, newResource, finishedWork.memoizedProps);
26997 }
26998 } else if (newResource === null && finishedWork.stateNode !== null) {
26999 try {
27000 commitUpdate(finishedWork.stateNode, finishedWork.type, current.memoizedProps, finishedWork.memoizedProps, finishedWork);
27001 } catch (error) {
27002 captureCommitPhaseError(finishedWork, finishedWork.return, error);
27003 }
27004 }
27005 }
27006
27007 return;
27008 } // Fall through
27009
27010 }
27011
27012 case HostSingleton:
27013 {
27014 {
27015 if (flags & Update) {
27016 var previousWork = finishedWork.alternate;
27017
27018 if (previousWork === null) {
27019 var singleton = finishedWork.stateNode;
27020 var props = finishedWork.memoizedProps; // This was a new mount, we need to clear and set initial properties
27021
27022 clearSingleton(singleton);
27023 acquireSingletonInstance(finishedWork.type, props, singleton, finishedWork);
27024 }
27025 }
27026 } // Fall through
27027
27028 }
27029
27030 case HostComponent:
27031 {
27032 recursivelyTraverseMutationEffects(root, finishedWork);
27033 commitReconciliationEffects(finishedWork);
27034
27035 if (flags & Ref) {
27036 if (current !== null) {
27037 safelyDetachRef(current, current.return);
27038 }
27039 }
27040
27041 {
27042 // TODO: ContentReset gets cleared by the children during the commit
27043 // phase. This is a refactor hazard because it means we must read
27044 // flags the flags after `commitReconciliationEffects` has already run;
27045 // the order matters. We should refactor so that ContentReset does not
27046 // rely on mutating the flag during commit. Like by setting a flag
27047 // during the render phase instead.
27048 if (finishedWork.flags & ContentReset) {
27049 var instance = finishedWork.stateNode;
27050
27051 try {
27052 resetTextContent(instance);
27053 } catch (error) {
27054 captureCommitPhaseError(finishedWork, finishedWork.return, error);
27055 }
27056 }
27057
27058 if (flags & Update) {
27059 var _instance2 = finishedWork.stateNode;
27060
27061 if (_instance2 != null) {
27062 // Commit the work prepared earlier.
27063 var newProps = finishedWork.memoizedProps; // For hydration we reuse the update path but we treat the oldProps
27064 // as the newProps. The updatePayload will contain the real change in
27065 // this case.
27066
27067 var oldProps = current !== null ? current.memoizedProps : newProps;
27068 var type = finishedWork.type;
27069
27070 try {
27071 commitUpdate(_instance2, type, oldProps, newProps, finishedWork);
27072 } catch (error) {
27073 captureCommitPhaseError(finishedWork, finishedWork.return, error);
27074 }
27075 }
27076 }
27077
27078 if (flags & FormReset) {
27079 needsFormReset = true;
27080
27081 {
27082 if (finishedWork.type !== 'form') {
27083 // Paranoid coding. In case we accidentally start using the
27084 // FormReset bit for something else.
27085 error('Unexpected host component type. Expected a form. This is a ' + 'bug in React.');
27086 }
27087 }
27088 }
27089 }
27090
27091 return;
27092 }
27093
27094 case HostText:
27095 {
27096 recursivelyTraverseMutationEffects(root, finishedWork);
27097 commitReconciliationEffects(finishedWork);
27098
27099 if (flags & Update) {
27100 {
27101 if (finishedWork.stateNode === null) {
27102 throw new Error('This should have a text node initialized. This error is likely ' + 'caused by a bug in React. Please file an issue.');
27103 }
27104
27105 var textInstance = finishedWork.stateNode;
27106 var newText = finishedWork.memoizedProps; // For hydration we reuse the update path but we treat the oldProps
27107 // as the newProps. The updatePayload will contain the real change in
27108 // this case.
27109
27110 var oldText = current !== null ? current.memoizedProps : newText;
27111
27112 try {
27113 commitTextUpdate(textInstance, oldText, newText);
27114 } catch (error) {
27115 captureCommitPhaseError(finishedWork, finishedWork.return, error);
27116 }
27117 }
27118 }
27119
27120 return;
27121 }
27122
27123 case HostRoot:
27124 {
27125 {
27126 prepareToCommitHoistables();
27127 var previousHoistableRoot = currentHoistableRoot;
27128 currentHoistableRoot = getHoistableRoot(root.containerInfo);
27129 recursivelyTraverseMutationEffects(root, finishedWork);
27130 currentHoistableRoot = previousHoistableRoot;
27131 commitReconciliationEffects(finishedWork);
27132 }
27133
27134 if (flags & Update) {
27135 {
27136 if (current !== null) {
27137 var prevRootState = current.memoizedState;
27138
27139 if (prevRootState.isDehydrated) {
27140 try {
27141 commitHydratedContainer(root.containerInfo);
27142 } catch (error) {
27143 captureCommitPhaseError(finishedWork, finishedWork.return, error);
27144 }
27145 }
27146 }
27147 }
27148 }
27149
27150 if (needsFormReset) {
27151 // A form component requested to be reset during this commit. We do this
27152 // after all mutations in the rest of the tree so that `defaultValue`
27153 // will already be updated. This way you can update `defaultValue` using
27154 // data sent by the server as a result of the form submission.
27155 //
27156 // Theoretically we could check finishedWork.subtreeFlags & FormReset,
27157 // but the FormReset bit is overloaded with other flags used by other
27158 // fiber types. So this extra variable lets us skip traversing the tree
27159 // except when a form was actually submitted.
27160 needsFormReset = false;
27161 recursivelyResetForms(finishedWork);
27162 }
27163
27164 return;
27165 }
27166
27167 case HostPortal:
27168 {
27169 {
27170 var _previousHoistableRoot = currentHoistableRoot;
27171 currentHoistableRoot = getHoistableRoot(finishedWork.stateNode.containerInfo);
27172 recursivelyTraverseMutationEffects(root, finishedWork);
27173 commitReconciliationEffects(finishedWork);
27174 currentHoistableRoot = _previousHoistableRoot;
27175 }
27176
27177 return;
27178 }
27179
27180 case SuspenseComponent:
27181 {
27182 recursivelyTraverseMutationEffects(root, finishedWork);
27183 commitReconciliationEffects(finishedWork); // TODO: We should mark a flag on the Suspense fiber itself, rather than
27184 // relying on the Offscreen fiber having a flag also being marked. The
27185 // reason is that this offscreen fiber might not be part of the work-in-
27186 // progress tree! It could have been reused from a previous render. This
27187 // doesn't lead to incorrect behavior because we don't rely on the flag
27188 // check alone; we also compare the states explicitly below. But for
27189 // modeling purposes, we _should_ be able to rely on the flag check alone.
27190 // So this is a bit fragile.
27191 //
27192 // Also, all this logic could/should move to the passive phase so it
27193 // doesn't block paint.
27194
27195 var offscreenFiber = finishedWork.child;
27196
27197 if (offscreenFiber.flags & Visibility) {
27198 // Throttle the appearance and disappearance of Suspense fallbacks.
27199 var isShowingFallback = finishedWork.memoizedState !== null;
27200 var wasShowingFallback = current !== null && current.memoizedState !== null;
27201
27202 {
27203 if (isShowingFallback !== wasShowingFallback) {
27204 // A fallback is either appearing or disappearing.
27205 markCommitTimeOfFallback();
27206 }
27207 }
27208 }
27209
27210 if (flags & Update) {
27211 try {
27212 commitSuspenseCallback(finishedWork);
27213 } catch (error) {
27214 captureCommitPhaseError(finishedWork, finishedWork.return, error);
27215 }
27216
27217 var retryQueue = finishedWork.updateQueue;
27218
27219 if (retryQueue !== null) {
27220 finishedWork.updateQueue = null;
27221 attachSuspenseRetryListeners(finishedWork, retryQueue);
27222 }
27223 }
27224
27225 return;
27226 }
27227
27228 case OffscreenComponent:
27229 {
27230 if (flags & Ref) {
27231 if (current !== null) {
27232 safelyDetachRef(current, current.return);
27233 }
27234 }
27235
27236 var newState = finishedWork.memoizedState;
27237 var isHidden = newState !== null;
27238 var wasHidden = current !== null && current.memoizedState !== null;
27239
27240 {
27241 // Before committing the children, track on the stack whether this
27242 // offscreen subtree was already hidden, so that we don't unmount the
27243 // effects again.
27244 var prevOffscreenSubtreeIsHidden = offscreenSubtreeIsHidden;
27245 var prevOffscreenSubtreeWasHidden = offscreenSubtreeWasHidden;
27246 offscreenSubtreeIsHidden = prevOffscreenSubtreeIsHidden || isHidden;
27247 offscreenSubtreeWasHidden = prevOffscreenSubtreeWasHidden || wasHidden;
27248 recursivelyTraverseMutationEffects(root, finishedWork);
27249 offscreenSubtreeWasHidden = prevOffscreenSubtreeWasHidden;
27250 offscreenSubtreeIsHidden = prevOffscreenSubtreeIsHidden;
27251 }
27252
27253 commitReconciliationEffects(finishedWork);
27254 var offscreenInstance = finishedWork.stateNode; // TODO: Add explicit effect flag to set _current.
27255
27256 offscreenInstance._current = finishedWork; // Offscreen stores pending changes to visibility in `_pendingVisibility`. This is
27257 // to support batching of `attach` and `detach` calls.
27258
27259 offscreenInstance._visibility &= ~OffscreenDetached;
27260 offscreenInstance._visibility |= offscreenInstance._pendingVisibility & OffscreenDetached;
27261
27262 if (flags & Visibility) {
27263 // Track the current state on the Offscreen instance so we can
27264 // read it during an event
27265 if (isHidden) {
27266 offscreenInstance._visibility &= ~OffscreenVisible;
27267 } else {
27268 offscreenInstance._visibility |= OffscreenVisible;
27269 }
27270
27271 if (isHidden) {
27272 var isUpdate = current !== null;
27273 var wasHiddenByAncestorOffscreen = offscreenSubtreeIsHidden || offscreenSubtreeWasHidden; // Only trigger disapper layout effects if:
27274 // - This is an update, not first mount.
27275 // - This Offscreen was not hidden before.
27276 // - Ancestor Offscreen was not hidden in previous commit.
27277
27278 if (isUpdate && !wasHidden && !wasHiddenByAncestorOffscreen) {
27279 {
27280 // Disappear the layout effects of all the children
27281 recursivelyTraverseDisappearLayoutEffects(finishedWork);
27282 }
27283 }
27284 } // Offscreen with manual mode manages visibility manually.
27285
27286
27287 if (!isOffscreenManual(finishedWork)) {
27288 // TODO: This needs to run whenever there's an insertion or update
27289 // inside a hidden Offscreen tree.
27290 hideOrUnhideAllChildren(finishedWork, isHidden);
27291 }
27292 } // TODO: Move to passive phase
27293
27294
27295 if (flags & Update) {
27296 var offscreenQueue = finishedWork.updateQueue;
27297
27298 if (offscreenQueue !== null) {
27299 var _retryQueue = offscreenQueue.retryQueue;
27300
27301 if (_retryQueue !== null) {
27302 offscreenQueue.retryQueue = null;
27303 attachSuspenseRetryListeners(finishedWork, _retryQueue);
27304 }
27305 }
27306 }
27307
27308 return;
27309 }
27310
27311 case SuspenseListComponent:
27312 {
27313 recursivelyTraverseMutationEffects(root, finishedWork);
27314 commitReconciliationEffects(finishedWork);
27315
27316 if (flags & Update) {
27317 var _retryQueue2 = finishedWork.updateQueue;
27318
27319 if (_retryQueue2 !== null) {
27320 finishedWork.updateQueue = null;
27321 attachSuspenseRetryListeners(finishedWork, _retryQueue2);
27322 }
27323 }
27324
27325 return;
27326 }
27327
27328 case ScopeComponent:
27329 {
27330
27331 return;
27332 }
27333
27334 default:
27335 {
27336 recursivelyTraverseMutationEffects(root, finishedWork);
27337 commitReconciliationEffects(finishedWork);
27338 return;
27339 }
27340 }
27341}
27342
27343function commitReconciliationEffects(finishedWork) {
27344 // Placement effects (insertions, reorders) can be scheduled on any fiber
27345 // type. They needs to happen after the children effects have fired, but
27346 // before the effects on this fiber have fired.
27347 var flags = finishedWork.flags;
27348
27349 if (flags & Placement) {
27350 try {
27351 commitPlacement(finishedWork);
27352 } catch (error) {
27353 captureCommitPhaseError(finishedWork, finishedWork.return, error);
27354 } // Clear the "placement" from effect tag so that we know that this is
27355 // inserted, before any life-cycles like componentDidMount gets called.
27356 // TODO: findDOMNode doesn't rely on this any more but isMounted does
27357 // and isMounted is deprecated anyway so we should be able to kill this.
27358
27359
27360 finishedWork.flags &= ~Placement;
27361 }
27362
27363 if (flags & Hydrating) {
27364 finishedWork.flags &= ~Hydrating;
27365 }
27366}
27367
27368function recursivelyResetForms(parentFiber) {
27369 if (parentFiber.subtreeFlags & FormReset) {
27370 var child = parentFiber.child;
27371
27372 while (child !== null) {
27373 resetFormOnFiber(child);
27374 child = child.sibling;
27375 }
27376 }
27377}
27378
27379function resetFormOnFiber(fiber) {
27380 recursivelyResetForms(fiber);
27381
27382 if (fiber.tag === HostComponent && fiber.flags & FormReset) {
27383 var formInstance = fiber.stateNode;
27384 resetFormInstance(formInstance);
27385 }
27386}
27387
27388function commitLayoutEffects(finishedWork, root, committedLanes) {
27389 inProgressLanes = committedLanes;
27390 inProgressRoot = root;
27391 var current = finishedWork.alternate;
27392 commitLayoutEffectOnFiber(root, current, finishedWork);
27393 inProgressLanes = null;
27394 inProgressRoot = null;
27395}
27396
27397function recursivelyTraverseLayoutEffects(root, parentFiber, lanes) {
27398 var prevDebugFiber = getCurrentFiber();
27399
27400 if (parentFiber.subtreeFlags & LayoutMask) {
27401 var child = parentFiber.child;
27402
27403 while (child !== null) {
27404 setCurrentFiber(child);
27405 var current = child.alternate;
27406 commitLayoutEffectOnFiber(root, current, child);
27407 child = child.sibling;
27408 }
27409 }
27410
27411 setCurrentFiber(prevDebugFiber);
27412}
27413
27414function disappearLayoutEffects(finishedWork) {
27415 switch (finishedWork.tag) {
27416 case FunctionComponent:
27417 case ForwardRef:
27418 case MemoComponent:
27419 case SimpleMemoComponent:
27420 {
27421 // TODO (Offscreen) Check: flags & LayoutStatic
27422 if (shouldProfile(finishedWork)) {
27423 try {
27424 startLayoutEffectTimer();
27425 commitHookEffectListUnmount(Layout, finishedWork, finishedWork.return);
27426 } finally {
27427 recordLayoutEffectDuration(finishedWork);
27428 }
27429 } else {
27430 commitHookEffectListUnmount(Layout, finishedWork, finishedWork.return);
27431 }
27432
27433 recursivelyTraverseDisappearLayoutEffects(finishedWork);
27434 break;
27435 }
27436
27437 case ClassComponent:
27438 {
27439 // TODO (Offscreen) Check: flags & RefStatic
27440 safelyDetachRef(finishedWork, finishedWork.return);
27441 var instance = finishedWork.stateNode;
27442
27443 if (typeof instance.componentWillUnmount === 'function') {
27444 safelyCallComponentWillUnmount(finishedWork, finishedWork.return, instance);
27445 }
27446
27447 recursivelyTraverseDisappearLayoutEffects(finishedWork);
27448 break;
27449 }
27450
27451 case HostHoistable:
27452 case HostSingleton:
27453 case HostComponent:
27454 {
27455 // TODO (Offscreen) Check: flags & RefStatic
27456 safelyDetachRef(finishedWork, finishedWork.return);
27457 recursivelyTraverseDisappearLayoutEffects(finishedWork);
27458 break;
27459 }
27460
27461 case OffscreenComponent:
27462 {
27463 // TODO (Offscreen) Check: flags & RefStatic
27464 safelyDetachRef(finishedWork, finishedWork.return);
27465 var isHidden = finishedWork.memoizedState !== null;
27466
27467 if (isHidden) ; else {
27468 recursivelyTraverseDisappearLayoutEffects(finishedWork);
27469 }
27470
27471 break;
27472 }
27473
27474 default:
27475 {
27476 recursivelyTraverseDisappearLayoutEffects(finishedWork);
27477 break;
27478 }
27479 }
27480}
27481
27482function recursivelyTraverseDisappearLayoutEffects(parentFiber) {
27483 // TODO (Offscreen) Check: flags & (RefStatic | LayoutStatic)
27484 var child = parentFiber.child;
27485
27486 while (child !== null) {
27487 disappearLayoutEffects(child);
27488 child = child.sibling;
27489 }
27490}
27491
27492function reappearLayoutEffects(finishedRoot, current, finishedWork, // This function visits both newly finished work and nodes that were re-used
27493// from a previously committed tree. We cannot check non-static flags if the
27494// node was reused.
27495includeWorkInProgressEffects) {
27496 // Turn on layout effects in a tree that previously disappeared.
27497 var flags = finishedWork.flags;
27498
27499 switch (finishedWork.tag) {
27500 case FunctionComponent:
27501 case ForwardRef:
27502 case SimpleMemoComponent:
27503 {
27504 recursivelyTraverseReappearLayoutEffects(finishedRoot, finishedWork, includeWorkInProgressEffects); // TODO: Check flags & LayoutStatic
27505
27506 commitHookLayoutEffects(finishedWork, Layout);
27507 break;
27508 }
27509
27510 case ClassComponent:
27511 {
27512 recursivelyTraverseReappearLayoutEffects(finishedRoot, finishedWork, includeWorkInProgressEffects); // TODO: Check for LayoutStatic flag
27513
27514 var instance = finishedWork.stateNode;
27515
27516 if (typeof instance.componentDidMount === 'function') {
27517 try {
27518 instance.componentDidMount();
27519 } catch (error) {
27520 captureCommitPhaseError(finishedWork, finishedWork.return, error);
27521 }
27522 } // Commit any callbacks that would have fired while the component
27523 // was hidden.
27524
27525
27526 var updateQueue = finishedWork.updateQueue;
27527
27528 if (updateQueue !== null) {
27529 commitHiddenCallbacks(updateQueue, instance);
27530 } // If this is newly finished work, check for setState callbacks
27531
27532
27533 if (includeWorkInProgressEffects && flags & Callback) {
27534 commitClassCallbacks(finishedWork);
27535 } // TODO: Check flags & RefStatic
27536
27537
27538 safelyAttachRef(finishedWork, finishedWork.return);
27539 break;
27540 }
27541 // Unlike commitLayoutEffectsOnFiber, we don't need to handle HostRoot
27542 // because this function only visits nodes that are inside an
27543 // Offscreen fiber.
27544 // case HostRoot: {
27545 // ...
27546 // }
27547
27548 case HostHoistable:
27549 case HostSingleton:
27550 case HostComponent:
27551 {
27552 recursivelyTraverseReappearLayoutEffects(finishedRoot, finishedWork, includeWorkInProgressEffects); // Renderers may schedule work to be done after host components are mounted
27553 // (eg DOM renderer may schedule auto-focus for inputs and form controls).
27554 // These effects should only be committed when components are first mounted,
27555 // aka when there is no current/alternate.
27556
27557 if (includeWorkInProgressEffects && current === null && flags & Update) {
27558 commitHostComponentMount(finishedWork);
27559 } // TODO: Check flags & Ref
27560
27561
27562 safelyAttachRef(finishedWork, finishedWork.return);
27563 break;
27564 }
27565
27566 case Profiler:
27567 {
27568 recursivelyTraverseReappearLayoutEffects(finishedRoot, finishedWork, includeWorkInProgressEffects); // TODO: Figure out how Profiler updates should work with Offscreen
27569
27570 if (includeWorkInProgressEffects && flags & Update) {
27571 commitProfilerUpdate(finishedWork, current);
27572 }
27573
27574 break;
27575 }
27576
27577 case SuspenseComponent:
27578 {
27579 recursivelyTraverseReappearLayoutEffects(finishedRoot, finishedWork, includeWorkInProgressEffects); // TODO: Figure out how Suspense hydration callbacks should work
27580 // with Offscreen.
27581
27582 if (includeWorkInProgressEffects && flags & Update) {
27583 commitSuspenseHydrationCallbacks(finishedRoot, finishedWork);
27584 }
27585
27586 break;
27587 }
27588
27589 case OffscreenComponent:
27590 {
27591 var offscreenState = finishedWork.memoizedState;
27592 var isHidden = offscreenState !== null;
27593
27594 if (isHidden) ; else {
27595 recursivelyTraverseReappearLayoutEffects(finishedRoot, finishedWork, includeWorkInProgressEffects);
27596 } // TODO: Check flags & Ref
27597
27598
27599 safelyAttachRef(finishedWork, finishedWork.return);
27600 break;
27601 }
27602
27603 default:
27604 {
27605 recursivelyTraverseReappearLayoutEffects(finishedRoot, finishedWork, includeWorkInProgressEffects);
27606 break;
27607 }
27608 }
27609}
27610
27611function recursivelyTraverseReappearLayoutEffects(finishedRoot, parentFiber, includeWorkInProgressEffects) {
27612 // This function visits both newly finished work and nodes that were re-used
27613 // from a previously committed tree. We cannot check non-static flags if the
27614 // node was reused.
27615 var childShouldIncludeWorkInProgressEffects = includeWorkInProgressEffects && (parentFiber.subtreeFlags & LayoutMask) !== NoFlags$1; // TODO (Offscreen) Check: flags & (RefStatic | LayoutStatic)
27616
27617 var prevDebugFiber = getCurrentFiber();
27618 var child = parentFiber.child;
27619
27620 while (child !== null) {
27621 var current = child.alternate;
27622 reappearLayoutEffects(finishedRoot, current, child, childShouldIncludeWorkInProgressEffects);
27623 child = child.sibling;
27624 }
27625
27626 setCurrentFiber(prevDebugFiber);
27627}
27628
27629function commitHookPassiveMountEffects(finishedWork, hookFlags) {
27630 if (shouldProfile(finishedWork)) {
27631 startPassiveEffectTimer();
27632
27633 try {
27634 commitHookEffectListMount(hookFlags, finishedWork);
27635 } catch (error) {
27636 captureCommitPhaseError(finishedWork, finishedWork.return, error);
27637 }
27638
27639 recordPassiveEffectDuration(finishedWork);
27640 } else {
27641 try {
27642 commitHookEffectListMount(hookFlags, finishedWork);
27643 } catch (error) {
27644 captureCommitPhaseError(finishedWork, finishedWork.return, error);
27645 }
27646 }
27647}
27648
27649function commitOffscreenPassiveMountEffects(current, finishedWork, instance) {
27650 {
27651 var previousCache = null;
27652
27653 if (current !== null && current.memoizedState !== null && current.memoizedState.cachePool !== null) {
27654 previousCache = current.memoizedState.cachePool.pool;
27655 }
27656
27657 var nextCache = null;
27658
27659 if (finishedWork.memoizedState !== null && finishedWork.memoizedState.cachePool !== null) {
27660 nextCache = finishedWork.memoizedState.cachePool.pool;
27661 } // Retain/release the cache used for pending (suspended) nodes.
27662 // Note that this is only reached in the non-suspended/visible case:
27663 // when the content is suspended/hidden, the retain/release occurs
27664 // via the parent Suspense component (see case above).
27665
27666
27667 if (nextCache !== previousCache) {
27668 if (nextCache != null) {
27669 retainCache(nextCache);
27670 }
27671
27672 if (previousCache != null) {
27673 releaseCache(previousCache);
27674 }
27675 }
27676 }
27677}
27678
27679function commitCachePassiveMountEffect(current, finishedWork) {
27680 {
27681 var previousCache = null;
27682
27683 if (finishedWork.alternate !== null) {
27684 previousCache = finishedWork.alternate.memoizedState.cache;
27685 }
27686
27687 var nextCache = finishedWork.memoizedState.cache; // Retain/release the cache. In theory the cache component
27688 // could be "borrowing" a cache instance owned by some parent,
27689 // in which case we could avoid retaining/releasing. But it
27690 // is non-trivial to determine when that is the case, so we
27691 // always retain/release.
27692
27693 if (nextCache !== previousCache) {
27694 retainCache(nextCache);
27695
27696 if (previousCache != null) {
27697 releaseCache(previousCache);
27698 }
27699 }
27700 }
27701}
27702
27703function commitPassiveMountEffects(root, finishedWork, committedLanes, committedTransitions) {
27704 setCurrentFiber(finishedWork);
27705 commitPassiveMountOnFiber(root, finishedWork, committedLanes, committedTransitions);
27706 resetCurrentFiber();
27707}
27708
27709function recursivelyTraversePassiveMountEffects(root, parentFiber, committedLanes, committedTransitions) {
27710 var prevDebugFiber = getCurrentFiber();
27711
27712 if (parentFiber.subtreeFlags & PassiveMask) {
27713 var child = parentFiber.child;
27714
27715 while (child !== null) {
27716 setCurrentFiber(child);
27717 commitPassiveMountOnFiber(root, child, committedLanes, committedTransitions);
27718 child = child.sibling;
27719 }
27720 }
27721
27722 setCurrentFiber(prevDebugFiber);
27723}
27724
27725function commitPassiveMountOnFiber(finishedRoot, finishedWork, committedLanes, committedTransitions) {
27726 // When updating this function, also update reconnectPassiveEffects, which does
27727 // most of the same things when an offscreen tree goes from hidden -> visible,
27728 // or when toggling effects inside a hidden tree.
27729 var flags = finishedWork.flags;
27730
27731 switch (finishedWork.tag) {
27732 case FunctionComponent:
27733 case ForwardRef:
27734 case SimpleMemoComponent:
27735 {
27736 recursivelyTraversePassiveMountEffects(finishedRoot, finishedWork, committedLanes, committedTransitions);
27737
27738 if (flags & Passive$1) {
27739 commitHookPassiveMountEffects(finishedWork, Passive | HasEffect);
27740 }
27741
27742 break;
27743 }
27744
27745 case HostRoot:
27746 {
27747 recursivelyTraversePassiveMountEffects(finishedRoot, finishedWork, committedLanes, committedTransitions);
27748
27749 if (flags & Passive$1) {
27750 {
27751 var previousCache = null;
27752
27753 if (finishedWork.alternate !== null) {
27754 previousCache = finishedWork.alternate.memoizedState.cache;
27755 }
27756
27757 var nextCache = finishedWork.memoizedState.cache; // Retain/release the root cache.
27758 // Note that on initial mount, previousCache and nextCache will be the same
27759 // and this retain won't occur. To counter this, we instead retain the HostRoot's
27760 // initial cache when creating the root itself (see createFiberRoot() in
27761 // ReactFiberRoot.js). Subsequent updates that change the cache are reflected
27762 // here, such that previous/next caches are retained correctly.
27763
27764 if (nextCache !== previousCache) {
27765 retainCache(nextCache);
27766
27767 if (previousCache != null) {
27768 releaseCache(previousCache);
27769 }
27770 }
27771 }
27772 }
27773
27774 break;
27775 }
27776
27777 case LegacyHiddenComponent:
27778 {
27779
27780 break;
27781 }
27782
27783 case OffscreenComponent:
27784 {
27785 // TODO: Pass `current` as argument to this function
27786 var _instance3 = finishedWork.stateNode;
27787 var nextState = finishedWork.memoizedState;
27788 var isHidden = nextState !== null;
27789
27790 if (isHidden) {
27791 if (_instance3._visibility & OffscreenPassiveEffectsConnected) {
27792 // The effects are currently connected. Update them.
27793 recursivelyTraversePassiveMountEffects(finishedRoot, finishedWork, committedLanes, committedTransitions);
27794 } else {
27795 {
27796 // The effects are currently disconnected. Since the tree is hidden,
27797 // don't connect them. This also applies to the initial render.
27798 {
27799 // "Atomic" effects are ones that need to fire on every commit,
27800 // even during pre-rendering. An example is updating the reference
27801 // count on cache instances.
27802 recursivelyTraverseAtomicPassiveEffects(finishedRoot, finishedWork);
27803 }
27804 }
27805 }
27806 } else {
27807 // Tree is visible
27808 if (_instance3._visibility & OffscreenPassiveEffectsConnected) {
27809 // The effects are currently connected. Update them.
27810 recursivelyTraversePassiveMountEffects(finishedRoot, finishedWork, committedLanes, committedTransitions);
27811 } else {
27812 // The effects are currently disconnected. Reconnect them, while also
27813 // firing effects inside newly mounted trees. This also applies to
27814 // the initial render.
27815 _instance3._visibility |= OffscreenPassiveEffectsConnected;
27816 var includeWorkInProgressEffects = (finishedWork.subtreeFlags & PassiveMask) !== NoFlags$1;
27817 recursivelyTraverseReconnectPassiveEffects(finishedRoot, finishedWork, committedLanes, committedTransitions, includeWorkInProgressEffects);
27818 }
27819 }
27820
27821 if (flags & Passive$1) {
27822 var _current = finishedWork.alternate;
27823 commitOffscreenPassiveMountEffects(_current, finishedWork);
27824 }
27825
27826 break;
27827 }
27828
27829 case CacheComponent:
27830 {
27831 recursivelyTraversePassiveMountEffects(finishedRoot, finishedWork, committedLanes, committedTransitions);
27832
27833 if (flags & Passive$1) {
27834 // TODO: Pass `current` as argument to this function
27835 var _current2 = finishedWork.alternate;
27836 commitCachePassiveMountEffect(_current2, finishedWork);
27837 }
27838
27839 break;
27840 }
27841
27842 case TracingMarkerComponent:
27843
27844 default:
27845 {
27846 recursivelyTraversePassiveMountEffects(finishedRoot, finishedWork, committedLanes, committedTransitions);
27847 break;
27848 }
27849 }
27850}
27851
27852function recursivelyTraverseReconnectPassiveEffects(finishedRoot, parentFiber, committedLanes, committedTransitions, includeWorkInProgressEffects) {
27853 // This function visits both newly finished work and nodes that were re-used
27854 // from a previously committed tree. We cannot check non-static flags if the
27855 // node was reused.
27856 var childShouldIncludeWorkInProgressEffects = includeWorkInProgressEffects && (parentFiber.subtreeFlags & PassiveMask) !== NoFlags$1; // TODO (Offscreen) Check: flags & (RefStatic | LayoutStatic)
27857
27858 var prevDebugFiber = getCurrentFiber();
27859 var child = parentFiber.child;
27860
27861 while (child !== null) {
27862 reconnectPassiveEffects(finishedRoot, child, committedLanes, committedTransitions, childShouldIncludeWorkInProgressEffects);
27863 child = child.sibling;
27864 }
27865
27866 setCurrentFiber(prevDebugFiber);
27867}
27868
27869function reconnectPassiveEffects(finishedRoot, finishedWork, committedLanes, committedTransitions, // This function visits both newly finished work and nodes that were re-used
27870// from a previously committed tree. We cannot check non-static flags if the
27871// node was reused.
27872includeWorkInProgressEffects) {
27873 var flags = finishedWork.flags;
27874
27875 switch (finishedWork.tag) {
27876 case FunctionComponent:
27877 case ForwardRef:
27878 case SimpleMemoComponent:
27879 {
27880 recursivelyTraverseReconnectPassiveEffects(finishedRoot, finishedWork, committedLanes, committedTransitions, includeWorkInProgressEffects); // TODO: Check for PassiveStatic flag
27881
27882 commitHookPassiveMountEffects(finishedWork, Passive);
27883 break;
27884 }
27885 // Unlike commitPassiveMountOnFiber, we don't need to handle HostRoot
27886 // because this function only visits nodes that are inside an
27887 // Offscreen fiber.
27888 // case HostRoot: {
27889 // ...
27890 // }
27891
27892 case LegacyHiddenComponent:
27893 {
27894
27895 break;
27896 }
27897
27898 case OffscreenComponent:
27899 {
27900 var _instance4 = finishedWork.stateNode;
27901 var nextState = finishedWork.memoizedState;
27902 var isHidden = nextState !== null;
27903
27904 if (isHidden) {
27905 if (_instance4._visibility & OffscreenPassiveEffectsConnected) {
27906 // The effects are currently connected. Update them.
27907 recursivelyTraverseReconnectPassiveEffects(finishedRoot, finishedWork, committedLanes, committedTransitions, includeWorkInProgressEffects);
27908 } else {
27909 {
27910 // The effects are currently disconnected. Since the tree is hidden,
27911 // don't connect them. This also applies to the initial render.
27912 {
27913 // "Atomic" effects are ones that need to fire on every commit,
27914 // even during pre-rendering. An example is updating the reference
27915 // count on cache instances.
27916 recursivelyTraverseAtomicPassiveEffects(finishedRoot, finishedWork);
27917 }
27918 }
27919 }
27920 } else {
27921 // Tree is visible
27922 // Since we're already inside a reconnecting tree, it doesn't matter
27923 // whether the effects are currently connected. In either case, we'll
27924 // continue traversing the tree and firing all the effects.
27925 //
27926 // We do need to set the "connected" flag on the instance, though.
27927 _instance4._visibility |= OffscreenPassiveEffectsConnected;
27928 recursivelyTraverseReconnectPassiveEffects(finishedRoot, finishedWork, committedLanes, committedTransitions, includeWorkInProgressEffects);
27929 }
27930
27931 if (includeWorkInProgressEffects && flags & Passive$1) {
27932 // TODO: Pass `current` as argument to this function
27933 var _current3 = finishedWork.alternate;
27934 commitOffscreenPassiveMountEffects(_current3, finishedWork);
27935 }
27936
27937 break;
27938 }
27939
27940 case CacheComponent:
27941 {
27942 recursivelyTraverseReconnectPassiveEffects(finishedRoot, finishedWork, committedLanes, committedTransitions, includeWorkInProgressEffects);
27943
27944 if (includeWorkInProgressEffects && flags & Passive$1) {
27945 // TODO: Pass `current` as argument to this function
27946 var _current4 = finishedWork.alternate;
27947 commitCachePassiveMountEffect(_current4, finishedWork);
27948 }
27949
27950 break;
27951 }
27952
27953 case TracingMarkerComponent:
27954
27955 default:
27956 {
27957 recursivelyTraverseReconnectPassiveEffects(finishedRoot, finishedWork, committedLanes, committedTransitions, includeWorkInProgressEffects);
27958 break;
27959 }
27960 }
27961}
27962
27963function recursivelyTraverseAtomicPassiveEffects(finishedRoot, parentFiber, committedLanes, committedTransitions) {
27964 // "Atomic" effects are ones that need to fire on every commit, even during
27965 // pre-rendering. We call this function when traversing a hidden tree whose
27966 // regular effects are currently disconnected.
27967 var prevDebugFiber = getCurrentFiber(); // TODO: Add special flag for atomic effects
27968
27969 if (parentFiber.subtreeFlags & PassiveMask) {
27970 var child = parentFiber.child;
27971
27972 while (child !== null) {
27973 setCurrentFiber(child);
27974 commitAtomicPassiveEffects(finishedRoot, child);
27975 child = child.sibling;
27976 }
27977 }
27978
27979 setCurrentFiber(prevDebugFiber);
27980}
27981
27982function commitAtomicPassiveEffects(finishedRoot, finishedWork, committedLanes, committedTransitions) {
27983 // "Atomic" effects are ones that need to fire on every commit, even during
27984 // pre-rendering. We call this function when traversing a hidden tree whose
27985 // regular effects are currently disconnected.
27986 var flags = finishedWork.flags;
27987
27988 switch (finishedWork.tag) {
27989 case OffscreenComponent:
27990 {
27991 recursivelyTraverseAtomicPassiveEffects(finishedRoot, finishedWork);
27992
27993 if (flags & Passive$1) {
27994 // TODO: Pass `current` as argument to this function
27995 var current = finishedWork.alternate;
27996 commitOffscreenPassiveMountEffects(current, finishedWork);
27997 }
27998
27999 break;
28000 }
28001
28002 case CacheComponent:
28003 {
28004 recursivelyTraverseAtomicPassiveEffects(finishedRoot, finishedWork);
28005
28006 if (flags & Passive$1) {
28007 // TODO: Pass `current` as argument to this function
28008 var _current5 = finishedWork.alternate;
28009 commitCachePassiveMountEffect(_current5, finishedWork);
28010 }
28011
28012 break;
28013 }
28014
28015 default:
28016 {
28017 recursivelyTraverseAtomicPassiveEffects(finishedRoot, finishedWork);
28018 break;
28019 }
28020 }
28021}
28022
28023function commitPassiveUnmountEffects(finishedWork) {
28024 setCurrentFiber(finishedWork);
28025 commitPassiveUnmountOnFiber(finishedWork);
28026 resetCurrentFiber();
28027} // If we're inside a brand new tree, or a tree that was already visible, then we
28028// should only suspend host components that have a ShouldSuspendCommit flag.
28029// Components without it haven't changed since the last commit, so we can skip
28030// over those.
28031//
28032// When we enter a tree that is being revealed (going from hidden -> visible),
28033// we need to suspend _any_ component that _may_ suspend. Even if they're
28034// already in the "current" tree. Because their visibility has changed, the
28035// browser may not have prerendered them yet. So we check the MaySuspendCommit
28036// flag instead.
28037
28038var suspenseyCommitFlag = ShouldSuspendCommit;
28039function accumulateSuspenseyCommit(finishedWork) {
28040 accumulateSuspenseyCommitOnFiber(finishedWork);
28041}
28042
28043function recursivelyAccumulateSuspenseyCommit(parentFiber) {
28044 if (parentFiber.subtreeFlags & suspenseyCommitFlag) {
28045 var child = parentFiber.child;
28046
28047 while (child !== null) {
28048 accumulateSuspenseyCommitOnFiber(child);
28049 child = child.sibling;
28050 }
28051 }
28052}
28053
28054function accumulateSuspenseyCommitOnFiber(fiber) {
28055 switch (fiber.tag) {
28056 case HostHoistable:
28057 {
28058 recursivelyAccumulateSuspenseyCommit(fiber);
28059
28060 if (fiber.flags & suspenseyCommitFlag) {
28061 if (fiber.memoizedState !== null) {
28062 suspendResource( // This should always be set by visiting HostRoot first
28063 currentHoistableRoot, fiber.memoizedState, fiber.memoizedProps);
28064 }
28065 }
28066
28067 break;
28068 }
28069
28070 case HostComponent:
28071 {
28072 recursivelyAccumulateSuspenseyCommit(fiber);
28073
28074 break;
28075 }
28076
28077 case HostRoot:
28078 case HostPortal:
28079 {
28080 {
28081 var previousHoistableRoot = currentHoistableRoot;
28082 var container = fiber.stateNode.containerInfo;
28083 currentHoistableRoot = getHoistableRoot(container);
28084 recursivelyAccumulateSuspenseyCommit(fiber);
28085 currentHoistableRoot = previousHoistableRoot;
28086 }
28087
28088 break;
28089 }
28090
28091 case OffscreenComponent:
28092 {
28093 var isHidden = fiber.memoizedState !== null;
28094
28095 if (isHidden) ; else {
28096 var current = fiber.alternate;
28097 var wasHidden = current !== null && current.memoizedState !== null;
28098
28099 if (wasHidden) {
28100 // This tree is being revealed. Visit all newly visible suspensey
28101 // instances, even if they're in the current tree.
28102 var prevFlags = suspenseyCommitFlag;
28103 suspenseyCommitFlag = MaySuspendCommit;
28104 recursivelyAccumulateSuspenseyCommit(fiber);
28105 suspenseyCommitFlag = prevFlags;
28106 } else {
28107 recursivelyAccumulateSuspenseyCommit(fiber);
28108 }
28109 }
28110
28111 break;
28112 }
28113
28114 default:
28115 {
28116 recursivelyAccumulateSuspenseyCommit(fiber);
28117 }
28118 }
28119}
28120
28121function detachAlternateSiblings(parentFiber) {
28122 // A fiber was deleted from this parent fiber, but it's still part of the
28123 // previous (alternate) parent fiber's list of children. Because children
28124 // are a linked list, an earlier sibling that's still alive will be
28125 // connected to the deleted fiber via its `alternate`:
28126 //
28127 // live fiber --alternate--> previous live fiber --sibling--> deleted
28128 // fiber
28129 //
28130 // We can't disconnect `alternate` on nodes that haven't been deleted yet,
28131 // but we can disconnect the `sibling` and `child` pointers.
28132 var previousFiber = parentFiber.alternate;
28133
28134 if (previousFiber !== null) {
28135 var detachedChild = previousFiber.child;
28136
28137 if (detachedChild !== null) {
28138 previousFiber.child = null;
28139
28140 do {
28141 // $FlowFixMe[incompatible-use] found when upgrading Flow
28142 var detachedSibling = detachedChild.sibling; // $FlowFixMe[incompatible-use] found when upgrading Flow
28143
28144 detachedChild.sibling = null;
28145 detachedChild = detachedSibling;
28146 } while (detachedChild !== null);
28147 }
28148 }
28149}
28150
28151function commitHookPassiveUnmountEffects(finishedWork, nearestMountedAncestor, hookFlags) {
28152 if (shouldProfile(finishedWork)) {
28153 startPassiveEffectTimer();
28154 commitHookEffectListUnmount(hookFlags, finishedWork, nearestMountedAncestor);
28155 recordPassiveEffectDuration(finishedWork);
28156 } else {
28157 commitHookEffectListUnmount(hookFlags, finishedWork, nearestMountedAncestor);
28158 }
28159}
28160
28161function recursivelyTraversePassiveUnmountEffects(parentFiber) {
28162 // Deletions effects can be scheduled on any fiber type. They need to happen
28163 // before the children effects have fired.
28164 var deletions = parentFiber.deletions;
28165
28166 if ((parentFiber.flags & ChildDeletion) !== NoFlags$1) {
28167 if (deletions !== null) {
28168 for (var i = 0; i < deletions.length; i++) {
28169 var childToDelete = deletions[i]; // TODO: Convert this to use recursion
28170
28171 nextEffect = childToDelete;
28172 commitPassiveUnmountEffectsInsideOfDeletedTree_begin(childToDelete, parentFiber);
28173 }
28174 }
28175
28176 detachAlternateSiblings(parentFiber);
28177 }
28178
28179 var prevDebugFiber = getCurrentFiber(); // TODO: Split PassiveMask into separate masks for mount and unmount?
28180
28181 if (parentFiber.subtreeFlags & PassiveMask) {
28182 var child = parentFiber.child;
28183
28184 while (child !== null) {
28185 setCurrentFiber(child);
28186 commitPassiveUnmountOnFiber(child);
28187 child = child.sibling;
28188 }
28189 }
28190
28191 setCurrentFiber(prevDebugFiber);
28192}
28193
28194function commitPassiveUnmountOnFiber(finishedWork) {
28195 switch (finishedWork.tag) {
28196 case FunctionComponent:
28197 case ForwardRef:
28198 case SimpleMemoComponent:
28199 {
28200 recursivelyTraversePassiveUnmountEffects(finishedWork);
28201
28202 if (finishedWork.flags & Passive$1) {
28203 commitHookPassiveUnmountEffects(finishedWork, finishedWork.return, Passive | HasEffect);
28204 }
28205
28206 break;
28207 }
28208
28209 case OffscreenComponent:
28210 {
28211 var instance = finishedWork.stateNode;
28212 var nextState = finishedWork.memoizedState;
28213 var isHidden = nextState !== null;
28214
28215 if (isHidden && instance._visibility & OffscreenPassiveEffectsConnected && ( // For backwards compatibility, don't unmount when a tree suspends. In
28216 // the future we may change this to unmount after a delay.
28217 finishedWork.return === null || finishedWork.return.tag !== SuspenseComponent)) {
28218 // The effects are currently connected. Disconnect them.
28219 // TODO: Add option or heuristic to delay before disconnecting the
28220 // effects. Then if the tree reappears before the delay has elapsed, we
28221 // can skip toggling the effects entirely.
28222 instance._visibility &= ~OffscreenPassiveEffectsConnected;
28223 recursivelyTraverseDisconnectPassiveEffects(finishedWork);
28224 } else {
28225 recursivelyTraversePassiveUnmountEffects(finishedWork);
28226 }
28227
28228 break;
28229 }
28230
28231 default:
28232 {
28233 recursivelyTraversePassiveUnmountEffects(finishedWork);
28234 break;
28235 }
28236 }
28237}
28238
28239function recursivelyTraverseDisconnectPassiveEffects(parentFiber) {
28240 // Deletions effects can be scheduled on any fiber type. They need to happen
28241 // before the children effects have fired.
28242 var deletions = parentFiber.deletions;
28243
28244 if ((parentFiber.flags & ChildDeletion) !== NoFlags$1) {
28245 if (deletions !== null) {
28246 for (var i = 0; i < deletions.length; i++) {
28247 var childToDelete = deletions[i]; // TODO: Convert this to use recursion
28248
28249 nextEffect = childToDelete;
28250 commitPassiveUnmountEffectsInsideOfDeletedTree_begin(childToDelete, parentFiber);
28251 }
28252 }
28253
28254 detachAlternateSiblings(parentFiber);
28255 }
28256
28257 var prevDebugFiber = getCurrentFiber(); // TODO: Check PassiveStatic flag
28258
28259 var child = parentFiber.child;
28260
28261 while (child !== null) {
28262 setCurrentFiber(child);
28263 disconnectPassiveEffect(child);
28264 child = child.sibling;
28265 }
28266
28267 setCurrentFiber(prevDebugFiber);
28268}
28269
28270function disconnectPassiveEffect(finishedWork) {
28271 switch (finishedWork.tag) {
28272 case FunctionComponent:
28273 case ForwardRef:
28274 case SimpleMemoComponent:
28275 {
28276 // TODO: Check PassiveStatic flag
28277 commitHookPassiveUnmountEffects(finishedWork, finishedWork.return, Passive); // When disconnecting passive effects, we fire the effects in the same
28278 // order as during a deletiong: parent before child
28279
28280 recursivelyTraverseDisconnectPassiveEffects(finishedWork);
28281 break;
28282 }
28283
28284 case OffscreenComponent:
28285 {
28286 var instance = finishedWork.stateNode;
28287
28288 if (instance._visibility & OffscreenPassiveEffectsConnected) {
28289 instance._visibility &= ~OffscreenPassiveEffectsConnected;
28290 recursivelyTraverseDisconnectPassiveEffects(finishedWork);
28291 }
28292
28293 break;
28294 }
28295
28296 default:
28297 {
28298 recursivelyTraverseDisconnectPassiveEffects(finishedWork);
28299 break;
28300 }
28301 }
28302}
28303
28304function commitPassiveUnmountEffectsInsideOfDeletedTree_begin(deletedSubtreeRoot, nearestMountedAncestor) {
28305 while (nextEffect !== null) {
28306 var fiber = nextEffect; // Deletion effects fire in parent -> child order
28307 // TODO: Check if fiber has a PassiveStatic flag
28308
28309 setCurrentFiber(fiber);
28310 commitPassiveUnmountInsideDeletedTreeOnFiber(fiber, nearestMountedAncestor);
28311 resetCurrentFiber();
28312 var child = fiber.child; // TODO: Only traverse subtree if it has a PassiveStatic flag.
28313
28314 if (child !== null) {
28315 child.return = fiber;
28316 nextEffect = child;
28317 } else {
28318 commitPassiveUnmountEffectsInsideOfDeletedTree_complete(deletedSubtreeRoot);
28319 }
28320 }
28321}
28322
28323function commitPassiveUnmountEffectsInsideOfDeletedTree_complete(deletedSubtreeRoot) {
28324 while (nextEffect !== null) {
28325 var fiber = nextEffect;
28326 var sibling = fiber.sibling;
28327 var returnFiber = fiber.return; // Recursively traverse the entire deleted tree and clean up fiber fields.
28328 // This is more aggressive than ideal, and the long term goal is to only
28329 // have to detach the deleted tree at the root.
28330
28331 detachFiberAfterEffects(fiber);
28332
28333 if (fiber === deletedSubtreeRoot) {
28334 nextEffect = null;
28335 return;
28336 }
28337
28338 if (sibling !== null) {
28339 sibling.return = returnFiber;
28340 nextEffect = sibling;
28341 return;
28342 }
28343
28344 nextEffect = returnFiber;
28345 }
28346}
28347
28348function commitPassiveUnmountInsideDeletedTreeOnFiber(current, nearestMountedAncestor) {
28349 switch (current.tag) {
28350 case FunctionComponent:
28351 case ForwardRef:
28352 case SimpleMemoComponent:
28353 {
28354 commitHookPassiveUnmountEffects(current, nearestMountedAncestor, Passive);
28355 break;
28356 }
28357 // TODO: run passive unmount effects when unmounting a root.
28358 // Because passive unmount effects are not currently run,
28359 // the cache instance owned by the root will never be freed.
28360 // When effects are run, the cache should be freed here:
28361 // case HostRoot: {
28362 // if (enableCache) {
28363 // const cache = current.memoizedState.cache;
28364 // releaseCache(cache);
28365 // }
28366 // break;
28367 // }
28368
28369 case LegacyHiddenComponent:
28370 case OffscreenComponent:
28371 {
28372 {
28373 if (current.memoizedState !== null && current.memoizedState.cachePool !== null) {
28374 var cache = current.memoizedState.cachePool.pool; // Retain/release the cache used for pending (suspended) nodes.
28375 // Note that this is only reached in the non-suspended/visible case:
28376 // when the content is suspended/hidden, the retain/release occurs
28377 // via the parent Suspense component (see case above).
28378
28379 if (cache != null) {
28380 retainCache(cache);
28381 }
28382 }
28383 }
28384
28385 break;
28386 }
28387
28388 case SuspenseComponent:
28389 {
28390
28391 break;
28392 }
28393
28394 case CacheComponent:
28395 {
28396 {
28397 var _cache = current.memoizedState.cache;
28398 releaseCache(_cache);
28399 }
28400
28401 break;
28402 }
28403 }
28404}
28405
28406var hasBadMapPolyfill;
28407
28408{
28409 hasBadMapPolyfill = false;
28410
28411 try {
28412 var nonExtensibleObject = Object.preventExtensions({});
28413 /* eslint-disable no-new */
28414
28415 new Map([[nonExtensibleObject, null]]);
28416 new Set([nonExtensibleObject]);
28417 /* eslint-enable no-new */
28418 } catch (e) {
28419 // TODO: Consider warning about bad polyfills
28420 hasBadMapPolyfill = true;
28421 }
28422}
28423
28424function FiberNode(tag, pendingProps, key, mode) {
28425 // Instance
28426 this.tag = tag;
28427 this.key = key;
28428 this.elementType = null;
28429 this.type = null;
28430 this.stateNode = null; // Fiber
28431
28432 this.return = null;
28433 this.child = null;
28434 this.sibling = null;
28435 this.index = 0;
28436 this.ref = null;
28437 this.refCleanup = null;
28438 this.pendingProps = pendingProps;
28439 this.memoizedProps = null;
28440 this.updateQueue = null;
28441 this.memoizedState = null;
28442 this.dependencies = null;
28443 this.mode = mode; // Effects
28444
28445 this.flags = NoFlags$1;
28446 this.subtreeFlags = NoFlags$1;
28447 this.deletions = null;
28448 this.lanes = NoLanes;
28449 this.childLanes = NoLanes;
28450 this.alternate = null;
28451
28452 {
28453 // Note: The following is done to avoid a v8 performance cliff.
28454 //
28455 // Initializing the fields below to smis and later updating them with
28456 // double values will cause Fibers to end up having separate shapes.
28457 // This behavior/bug has something to do with Object.preventExtension().
28458 // Fortunately this only impacts DEV builds.
28459 // Unfortunately it makes React unusably slow for some applications.
28460 // To work around this, initialize the fields below with doubles.
28461 //
28462 // Learn more about this here:
28463 // https://github.com/facebook/react/issues/14365
28464 // https://bugs.chromium.org/p/v8/issues/detail?id=8538
28465 this.actualDuration = Number.NaN;
28466 this.actualStartTime = Number.NaN;
28467 this.selfBaseDuration = Number.NaN;
28468 this.treeBaseDuration = Number.NaN; // It's okay to replace the initial doubles with smis after initialization.
28469 // This won't trigger the performance cliff mentioned above,
28470 // and it simplifies other profiler code (including DevTools).
28471
28472 this.actualDuration = 0;
28473 this.actualStartTime = -1;
28474 this.selfBaseDuration = 0;
28475 this.treeBaseDuration = 0;
28476 }
28477
28478 {
28479 // This isn't directly used but is handy for debugging internals:
28480 this._debugInfo = null;
28481 this._debugOwner = null;
28482 this._debugNeedsRemount = false;
28483 this._debugHookTypes = null;
28484
28485 if (!hasBadMapPolyfill && typeof Object.preventExtensions === 'function') {
28486 Object.preventExtensions(this);
28487 }
28488 }
28489} // This is a constructor function, rather than a POJO constructor, still
28490// please ensure we do the following:
28491// 1) Nobody should add any instance methods on this. Instance methods can be
28492// more difficult to predict when they get optimized and they are almost
28493// never inlined properly in static compilers.
28494// 2) Nobody should rely on `instanceof Fiber` for type testing. We should
28495// always know when it is a fiber.
28496// 3) We might want to experiment with using numeric keys since they are easier
28497// to optimize in a non-JIT environment.
28498// 4) We can easily go from a constructor to a createFiber object literal if that
28499// is faster.
28500// 5) It should be easy to port this to a C struct and keep a C implementation
28501// compatible.
28502
28503
28504function createFiber(tag, pendingProps, key, mode) {
28505 // $FlowFixMe[invalid-constructor]: the shapes are exact here but Flow doesn't like constructors
28506 return new FiberNode(tag, pendingProps, key, mode);
28507}
28508
28509function shouldConstruct(Component) {
28510 var prototype = Component.prototype;
28511 return !!(prototype && prototype.isReactComponent);
28512}
28513
28514function isSimpleFunctionComponent(type) {
28515 return typeof type === 'function' && !shouldConstruct(type) && type.defaultProps === undefined;
28516}
28517function isFunctionClassComponent(type) {
28518 return shouldConstruct(type);
28519} // This is used to create an alternate fiber to do work on.
28520
28521function createWorkInProgress(current, pendingProps) {
28522 var workInProgress = current.alternate;
28523
28524 if (workInProgress === null) {
28525 // We use a double buffering pooling technique because we know that we'll
28526 // only ever need at most two versions of a tree. We pool the "other" unused
28527 // node that we're free to reuse. This is lazily created to avoid allocating
28528 // extra objects for things that are never updated. It also allow us to
28529 // reclaim the extra memory if needed.
28530 workInProgress = createFiber(current.tag, pendingProps, current.key, current.mode);
28531 workInProgress.elementType = current.elementType;
28532 workInProgress.type = current.type;
28533 workInProgress.stateNode = current.stateNode;
28534
28535 {
28536 // DEV-only fields
28537 workInProgress._debugOwner = current._debugOwner;
28538 workInProgress._debugHookTypes = current._debugHookTypes;
28539 }
28540
28541 workInProgress.alternate = current;
28542 current.alternate = workInProgress;
28543 } else {
28544 workInProgress.pendingProps = pendingProps; // Needed because Blocks store data on type.
28545
28546 workInProgress.type = current.type; // We already have an alternate.
28547 // Reset the effect tag.
28548
28549 workInProgress.flags = NoFlags$1; // The effects are no longer valid.
28550
28551 workInProgress.subtreeFlags = NoFlags$1;
28552 workInProgress.deletions = null;
28553
28554 {
28555 // We intentionally reset, rather than copy, actualDuration & actualStartTime.
28556 // This prevents time from endlessly accumulating in new commits.
28557 // This has the downside of resetting values for different priority renders,
28558 // But works for yielding (the common case) and should support resuming.
28559 workInProgress.actualDuration = 0;
28560 workInProgress.actualStartTime = -1;
28561 }
28562 } // Reset all effects except static ones.
28563 // Static effects are not specific to a render.
28564
28565
28566 workInProgress.flags = current.flags & StaticMask;
28567 workInProgress.childLanes = current.childLanes;
28568 workInProgress.lanes = current.lanes;
28569 workInProgress.child = current.child;
28570 workInProgress.memoizedProps = current.memoizedProps;
28571 workInProgress.memoizedState = current.memoizedState;
28572 workInProgress.updateQueue = current.updateQueue; // Clone the dependencies object. This is mutated during the render phase, so
28573 // it cannot be shared with the current fiber.
28574
28575 var currentDependencies = current.dependencies;
28576 workInProgress.dependencies = currentDependencies === null ? null : {
28577 lanes: currentDependencies.lanes,
28578 firstContext: currentDependencies.firstContext
28579 }; // These will be overridden during the parent's reconciliation
28580
28581 workInProgress.sibling = current.sibling;
28582 workInProgress.index = current.index;
28583 workInProgress.ref = current.ref;
28584 workInProgress.refCleanup = current.refCleanup;
28585
28586 {
28587 workInProgress.selfBaseDuration = current.selfBaseDuration;
28588 workInProgress.treeBaseDuration = current.treeBaseDuration;
28589 }
28590
28591 {
28592 workInProgress._debugInfo = current._debugInfo;
28593 workInProgress._debugNeedsRemount = current._debugNeedsRemount;
28594
28595 switch (workInProgress.tag) {
28596 case FunctionComponent:
28597 case SimpleMemoComponent:
28598 workInProgress.type = resolveFunctionForHotReloading(current.type);
28599 break;
28600
28601 case ClassComponent:
28602 workInProgress.type = resolveClassForHotReloading(current.type);
28603 break;
28604
28605 case ForwardRef:
28606 workInProgress.type = resolveForwardRefForHotReloading(current.type);
28607 break;
28608 }
28609 }
28610
28611 return workInProgress;
28612} // Used to reuse a Fiber for a second pass.
28613
28614function resetWorkInProgress(workInProgress, renderLanes) {
28615 // This resets the Fiber to what createFiber or createWorkInProgress would
28616 // have set the values to before during the first pass. Ideally this wouldn't
28617 // be necessary but unfortunately many code paths reads from the workInProgress
28618 // when they should be reading from current and writing to workInProgress.
28619 // We assume pendingProps, index, key, ref, return are still untouched to
28620 // avoid doing another reconciliation.
28621 // Reset the effect flags but keep any Placement tags, since that's something
28622 // that child fiber is setting, not the reconciliation.
28623 workInProgress.flags &= StaticMask | Placement; // The effects are no longer valid.
28624
28625 var current = workInProgress.alternate;
28626
28627 if (current === null) {
28628 // Reset to createFiber's initial values.
28629 workInProgress.childLanes = NoLanes;
28630 workInProgress.lanes = renderLanes;
28631 workInProgress.child = null;
28632 workInProgress.subtreeFlags = NoFlags$1;
28633 workInProgress.memoizedProps = null;
28634 workInProgress.memoizedState = null;
28635 workInProgress.updateQueue = null;
28636 workInProgress.dependencies = null;
28637 workInProgress.stateNode = null;
28638
28639 {
28640 // Note: We don't reset the actualTime counts. It's useful to accumulate
28641 // actual time across multiple render passes.
28642 workInProgress.selfBaseDuration = 0;
28643 workInProgress.treeBaseDuration = 0;
28644 }
28645 } else {
28646 // Reset to the cloned values that createWorkInProgress would've.
28647 workInProgress.childLanes = current.childLanes;
28648 workInProgress.lanes = current.lanes;
28649 workInProgress.child = current.child;
28650 workInProgress.subtreeFlags = NoFlags$1;
28651 workInProgress.deletions = null;
28652 workInProgress.memoizedProps = current.memoizedProps;
28653 workInProgress.memoizedState = current.memoizedState;
28654 workInProgress.updateQueue = current.updateQueue; // Needed because Blocks store data on type.
28655
28656 workInProgress.type = current.type; // Clone the dependencies object. This is mutated during the render phase, so
28657 // it cannot be shared with the current fiber.
28658
28659 var currentDependencies = current.dependencies;
28660 workInProgress.dependencies = currentDependencies === null ? null : {
28661 lanes: currentDependencies.lanes,
28662 firstContext: currentDependencies.firstContext
28663 };
28664
28665 {
28666 // Note: We don't reset the actualTime counts. It's useful to accumulate
28667 // actual time across multiple render passes.
28668 workInProgress.selfBaseDuration = current.selfBaseDuration;
28669 workInProgress.treeBaseDuration = current.treeBaseDuration;
28670 }
28671 }
28672
28673 return workInProgress;
28674}
28675function createHostRootFiber(tag, isStrictMode, concurrentUpdatesByDefaultOverride) {
28676 var mode;
28677
28678 {
28679 mode = ConcurrentMode;
28680
28681 if (isStrictMode === true) {
28682 mode |= StrictLegacyMode | StrictEffectsMode;
28683 }
28684 }
28685
28686 if (isDevToolsPresent) {
28687 // Always collect profile timings when DevTools are present.
28688 // This enables DevTools to start capturing timing at any point–
28689 // Without some nodes in the tree having empty base times.
28690 mode |= ProfileMode;
28691 }
28692
28693 return createFiber(HostRoot, null, null, mode);
28694}
28695function createFiberFromTypeAndProps(type, // React$ElementType
28696key, pendingProps, owner, mode, lanes) {
28697 var fiberTag = FunctionComponent; // The resolved type is set if we know what the final type will be. I.e. it's not lazy.
28698
28699 var resolvedType = type;
28700
28701 if (typeof type === 'function') {
28702 if (shouldConstruct(type)) {
28703 fiberTag = ClassComponent;
28704
28705 {
28706 resolvedType = resolveClassForHotReloading(resolvedType);
28707 }
28708 } else {
28709 {
28710 resolvedType = resolveFunctionForHotReloading(resolvedType);
28711 }
28712 }
28713 } else if (typeof type === 'string') {
28714 {
28715 var hostContext = getHostContext();
28716 fiberTag = isHostHoistableType(type, pendingProps, hostContext) ? HostHoistable : isHostSingletonType(type) ? HostSingleton : HostComponent;
28717 }
28718 } else {
28719 getTag: switch (type) {
28720 case REACT_FRAGMENT_TYPE:
28721 return createFiberFromFragment(pendingProps.children, mode, lanes, key);
28722
28723 case REACT_STRICT_MODE_TYPE:
28724 fiberTag = Mode;
28725 mode |= StrictLegacyMode;
28726
28727 {
28728 // Strict effects should never run on legacy roots
28729 mode |= StrictEffectsMode;
28730 }
28731
28732 break;
28733
28734 case REACT_PROFILER_TYPE:
28735 return createFiberFromProfiler(pendingProps, mode, lanes, key);
28736
28737 case REACT_SUSPENSE_TYPE:
28738 return createFiberFromSuspense(pendingProps, mode, lanes, key);
28739
28740 case REACT_SUSPENSE_LIST_TYPE:
28741 return createFiberFromSuspenseList(pendingProps, mode, lanes, key);
28742
28743 case REACT_OFFSCREEN_TYPE:
28744 return createFiberFromOffscreen(pendingProps, mode, lanes, key);
28745
28746 case REACT_LEGACY_HIDDEN_TYPE:
28747
28748 // Fall through
28749
28750 case REACT_SCOPE_TYPE:
28751
28752 // Fall through
28753
28754 case REACT_TRACING_MARKER_TYPE:
28755
28756 // Fall through
28757
28758 case REACT_DEBUG_TRACING_MODE_TYPE:
28759
28760 // Fall through
28761
28762 default:
28763 {
28764 if (typeof type === 'object' && type !== null) {
28765 switch (type.$$typeof) {
28766 case REACT_PROVIDER_TYPE:
28767
28768 // Fall through
28769
28770 case REACT_CONTEXT_TYPE:
28771 {
28772 fiberTag = ContextProvider;
28773 break getTag;
28774 }
28775
28776 case REACT_CONSUMER_TYPE:
28777 {
28778 fiberTag = ContextConsumer;
28779 break getTag;
28780 }
28781
28782 // Fall through
28783
28784 case REACT_FORWARD_REF_TYPE:
28785 fiberTag = ForwardRef;
28786
28787 {
28788 resolvedType = resolveForwardRefForHotReloading(resolvedType);
28789 }
28790
28791 break getTag;
28792
28793 case REACT_MEMO_TYPE:
28794 fiberTag = MemoComponent;
28795 break getTag;
28796
28797 case REACT_LAZY_TYPE:
28798 fiberTag = LazyComponent;
28799 resolvedType = null;
28800 break getTag;
28801 }
28802 }
28803
28804 var info = '';
28805
28806 {
28807 if (type === undefined || typeof type === 'object' && type !== null && Object.keys(type).length === 0) {
28808 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.';
28809 }
28810
28811 var ownerName = owner ? getComponentNameFromOwner(owner) : null;
28812
28813 if (ownerName) {
28814 info += '\n\nCheck the render method of `' + ownerName + '`.';
28815 }
28816 }
28817
28818 throw new 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));
28819 }
28820 }
28821 }
28822
28823 var fiber = createFiber(fiberTag, pendingProps, key, mode);
28824 fiber.elementType = type;
28825 fiber.type = resolvedType;
28826 fiber.lanes = lanes;
28827
28828 {
28829 fiber._debugOwner = owner;
28830 }
28831
28832 return fiber;
28833}
28834function createFiberFromElement(element, mode, lanes) {
28835 var owner = null;
28836
28837 {
28838 owner = element._owner;
28839 }
28840
28841 var type = element.type;
28842 var key = element.key;
28843 var pendingProps = element.props;
28844 var fiber = createFiberFromTypeAndProps(type, key, pendingProps, owner, mode, lanes);
28845
28846 {
28847 fiber._debugOwner = element._owner;
28848 }
28849
28850 return fiber;
28851}
28852function createFiberFromFragment(elements, mode, lanes, key) {
28853 var fiber = createFiber(Fragment, elements, key, mode);
28854 fiber.lanes = lanes;
28855 return fiber;
28856}
28857
28858function createFiberFromProfiler(pendingProps, mode, lanes, key) {
28859 {
28860 if (typeof pendingProps.id !== 'string') {
28861 error('Profiler must specify an "id" of type `string` as a prop. Received the type `%s` instead.', typeof pendingProps.id);
28862 }
28863 }
28864
28865 var fiber = createFiber(Profiler, pendingProps, key, mode | ProfileMode);
28866 fiber.elementType = REACT_PROFILER_TYPE;
28867 fiber.lanes = lanes;
28868
28869 {
28870 fiber.stateNode = {
28871 effectDuration: 0,
28872 passiveEffectDuration: 0
28873 };
28874 }
28875
28876 return fiber;
28877}
28878
28879function createFiberFromSuspense(pendingProps, mode, lanes, key) {
28880 var fiber = createFiber(SuspenseComponent, pendingProps, key, mode);
28881 fiber.elementType = REACT_SUSPENSE_TYPE;
28882 fiber.lanes = lanes;
28883 return fiber;
28884}
28885function createFiberFromSuspenseList(pendingProps, mode, lanes, key) {
28886 var fiber = createFiber(SuspenseListComponent, pendingProps, key, mode);
28887 fiber.elementType = REACT_SUSPENSE_LIST_TYPE;
28888 fiber.lanes = lanes;
28889 return fiber;
28890}
28891function createFiberFromOffscreen(pendingProps, mode, lanes, key) {
28892 var fiber = createFiber(OffscreenComponent, pendingProps, key, mode);
28893 fiber.elementType = REACT_OFFSCREEN_TYPE;
28894 fiber.lanes = lanes;
28895 var primaryChildInstance = {
28896 _visibility: OffscreenVisible,
28897 _pendingVisibility: OffscreenVisible,
28898 _pendingMarkers: null,
28899 _retryCache: null,
28900 _transitions: null,
28901 _current: null,
28902 detach: function () {
28903 return detachOffscreenInstance(primaryChildInstance);
28904 },
28905 attach: function () {
28906 return attachOffscreenInstance(primaryChildInstance);
28907 }
28908 };
28909 fiber.stateNode = primaryChildInstance;
28910 return fiber;
28911}
28912function createFiberFromText(content, mode, lanes) {
28913 var fiber = createFiber(HostText, content, null, mode);
28914 fiber.lanes = lanes;
28915 return fiber;
28916}
28917function createFiberFromDehydratedFragment(dehydratedNode) {
28918 var fiber = createFiber(DehydratedFragment, null, null, NoMode);
28919 fiber.stateNode = dehydratedNode;
28920 return fiber;
28921}
28922function createFiberFromPortal(portal, mode, lanes) {
28923 var pendingProps = portal.children !== null ? portal.children : [];
28924 var fiber = createFiber(HostPortal, pendingProps, portal.key, mode);
28925 fiber.lanes = lanes;
28926 fiber.stateNode = {
28927 containerInfo: portal.containerInfo,
28928 pendingChildren: null,
28929 // Used by persistent updates
28930 implementation: portal.implementation
28931 };
28932 return fiber;
28933}
28934
28935// This is imported by the event replaying implementation in React DOM. It's
28936// in a separate file to break a circular dependency between the renderer and
28937// the reconciler.
28938function isRootDehydrated(root) {
28939 var currentState = root.current.memoizedState;
28940 return currentState.isDehydrated;
28941}
28942
28943/**
28944 * Tag the fiber with an update effect. This turns a Placement into
28945 * a PlacementAndUpdate.
28946 */
28947
28948function markUpdate(workInProgress) {
28949 workInProgress.flags |= Update;
28950}
28951
28952function appendAllChildren(parent, workInProgress, needsVisibilityToggle, isHidden) {
28953 {
28954 // We only have the top Fiber that was created but we need recurse down its
28955 // children to find all the terminal nodes.
28956 var node = workInProgress.child;
28957
28958 while (node !== null) {
28959 if (node.tag === HostComponent || node.tag === HostText) {
28960 appendInitialChild(parent, node.stateNode);
28961 } else if (node.tag === HostPortal || (node.tag === HostSingleton )) ; else if (node.child !== null) {
28962 node.child.return = node;
28963 node = node.child;
28964 continue;
28965 }
28966
28967 if (node === workInProgress) {
28968 return;
28969 } // $FlowFixMe[incompatible-use] found when upgrading Flow
28970
28971
28972 while (node.sibling === null) {
28973 // $FlowFixMe[incompatible-use] found when upgrading Flow
28974 if (node.return === null || node.return === workInProgress) {
28975 return;
28976 }
28977
28978 node = node.return;
28979 } // $FlowFixMe[incompatible-use] found when upgrading Flow
28980
28981
28982 node.sibling.return = node.return;
28983 node = node.sibling;
28984 }
28985 }
28986} // An unfortunate fork of appendAllChildren because we have two different parent types.
28987
28988function updateHostComponent(current, workInProgress, type, newProps, renderLanes) {
28989 {
28990 // If we have an alternate, that means this is an update and we need to
28991 // schedule a side-effect to do the updates.
28992 var oldProps = current.memoizedProps;
28993
28994 if (oldProps === newProps) {
28995 // In mutation mode, this is sufficient for a bailout because
28996 // we won't touch this node even if children changed.
28997 return;
28998 }
28999
29000 markUpdate(workInProgress);
29001 }
29002} // This function must be called at the very end of the complete phase, because
29003// it might throw to suspend, and if the resource immediately loads, the work
29004// loop will resume rendering as if the work-in-progress completed. So it must
29005// fully complete.
29006// TODO: This should ideally move to begin phase, but currently the instance is
29007// not created until the complete phase. For our existing use cases, host nodes
29008// that suspend don't have children, so it doesn't matter. But that might not
29009// always be true in the future.
29010
29011
29012function preloadInstanceAndSuspendIfNeeded(workInProgress, type, props, renderLanes) {
29013 {
29014 // If this flag was set previously, we can remove it. The flag
29015 // represents whether this particular set of props might ever need to
29016 // suspend. The safest thing to do is for maySuspendCommit to always
29017 // return true, but if the renderer is reasonably confident that the
29018 // underlying resource won't be evicted, it can return false as a
29019 // performance optimization.
29020 workInProgress.flags &= ~MaySuspendCommit;
29021 return;
29022 } // Mark this fiber with a flag. This gets set on all host instances
29023}
29024
29025function preloadResourceAndSuspendIfNeeded(workInProgress, resource, type, props, renderLanes) {
29026 // This is a fork of preloadInstanceAndSuspendIfNeeded, but for resources.
29027 if (!mayResourceSuspendCommit(resource)) {
29028 workInProgress.flags &= ~MaySuspendCommit;
29029 return;
29030 }
29031
29032 workInProgress.flags |= MaySuspendCommit;
29033 var rootRenderLanes = getWorkInProgressRootRenderLanes();
29034
29035 if (!includesOnlyNonUrgentLanes(rootRenderLanes)) ; else {
29036 var isReady = preloadResource(resource);
29037
29038 if (!isReady) {
29039 if (shouldRemainOnPreviousScreen()) {
29040 workInProgress.flags |= ShouldSuspendCommit;
29041 } else {
29042 suspendCommit();
29043 }
29044 }
29045 }
29046}
29047
29048function scheduleRetryEffect(workInProgress, retryQueue) {
29049 var wakeables = retryQueue;
29050
29051 if (wakeables !== null) {
29052 // Schedule an effect to attach a retry listener to the promise.
29053 // TODO: Move to passive phase
29054 workInProgress.flags |= Update;
29055 } else {
29056 // This boundary suspended, but no wakeables were added to the retry
29057 // queue. Check if the renderer suspended commit. If so, this means
29058 // that once the fallback is committed, we can immediately retry
29059 // rendering again, because rendering wasn't actually blocked. Only
29060 // the commit phase.
29061 // TODO: Consider a model where we always schedule an immediate retry, even
29062 // for normal Suspense. That way the retry can partially render up to the
29063 // first thing that suspends.
29064 if (workInProgress.flags & ScheduleRetry) {
29065 var retryLane = // TODO: This check should probably be moved into claimNextRetryLane
29066 // I also suspect that we need some further consolidation of offscreen
29067 // and retry lanes.
29068 workInProgress.tag !== OffscreenComponent ? claimNextRetryLane() : OffscreenLane;
29069 workInProgress.lanes = mergeLanes(workInProgress.lanes, retryLane);
29070 }
29071 }
29072}
29073
29074function updateHostText(current, workInProgress, oldText, newText) {
29075 {
29076 // If the text differs, mark it as an update. All the work in done in commitWork.
29077 if (oldText !== newText) {
29078 markUpdate(workInProgress);
29079 }
29080 }
29081}
29082
29083function cutOffTailIfNeeded(renderState, hasRenderedATailFallback) {
29084 if (getIsHydrating()) {
29085 // If we're hydrating, we should consume as many items as we can
29086 // so we don't leave any behind.
29087 return;
29088 }
29089
29090 switch (renderState.tailMode) {
29091 case 'hidden':
29092 {
29093 // Any insertions at the end of the tail list after this point
29094 // should be invisible. If there are already mounted boundaries
29095 // anything before them are not considered for collapsing.
29096 // Therefore we need to go through the whole tail to find if
29097 // there are any.
29098 var tailNode = renderState.tail;
29099 var lastTailNode = null;
29100
29101 while (tailNode !== null) {
29102 if (tailNode.alternate !== null) {
29103 lastTailNode = tailNode;
29104 }
29105
29106 tailNode = tailNode.sibling;
29107 } // Next we're simply going to delete all insertions after the
29108 // last rendered item.
29109
29110
29111 if (lastTailNode === null) {
29112 // All remaining items in the tail are insertions.
29113 renderState.tail = null;
29114 } else {
29115 // Detach the insertion after the last node that was already
29116 // inserted.
29117 lastTailNode.sibling = null;
29118 }
29119
29120 break;
29121 }
29122
29123 case 'collapsed':
29124 {
29125 // Any insertions at the end of the tail list after this point
29126 // should be invisible. If there are already mounted boundaries
29127 // anything before them are not considered for collapsing.
29128 // Therefore we need to go through the whole tail to find if
29129 // there are any.
29130 var _tailNode = renderState.tail;
29131 var _lastTailNode = null;
29132
29133 while (_tailNode !== null) {
29134 if (_tailNode.alternate !== null) {
29135 _lastTailNode = _tailNode;
29136 }
29137
29138 _tailNode = _tailNode.sibling;
29139 } // Next we're simply going to delete all insertions after the
29140 // last rendered item.
29141
29142
29143 if (_lastTailNode === null) {
29144 // All remaining items in the tail are insertions.
29145 if (!hasRenderedATailFallback && renderState.tail !== null) {
29146 // We suspended during the head. We want to show at least one
29147 // row at the tail. So we'll keep on and cut off the rest.
29148 renderState.tail.sibling = null;
29149 } else {
29150 renderState.tail = null;
29151 }
29152 } else {
29153 // Detach the insertion after the last node that was already
29154 // inserted.
29155 _lastTailNode.sibling = null;
29156 }
29157
29158 break;
29159 }
29160 }
29161}
29162
29163function bubbleProperties(completedWork) {
29164 var didBailout = completedWork.alternate !== null && completedWork.alternate.child === completedWork.child;
29165 var newChildLanes = NoLanes;
29166 var subtreeFlags = NoFlags$1;
29167
29168 if (!didBailout) {
29169 // Bubble up the earliest expiration time.
29170 if ((completedWork.mode & ProfileMode) !== NoMode) {
29171 // In profiling mode, resetChildExpirationTime is also used to reset
29172 // profiler durations.
29173 var actualDuration = completedWork.actualDuration;
29174 var treeBaseDuration = completedWork.selfBaseDuration;
29175 var child = completedWork.child;
29176
29177 while (child !== null) {
29178 newChildLanes = mergeLanes(newChildLanes, mergeLanes(child.lanes, child.childLanes));
29179 subtreeFlags |= child.subtreeFlags;
29180 subtreeFlags |= child.flags; // When a fiber is cloned, its actualDuration is reset to 0. This value will
29181 // only be updated if work is done on the fiber (i.e. it doesn't bailout).
29182 // When work is done, it should bubble to the parent's actualDuration. If
29183 // the fiber has not been cloned though, (meaning no work was done), then
29184 // this value will reflect the amount of time spent working on a previous
29185 // render. In that case it should not bubble. We determine whether it was
29186 // cloned by comparing the child pointer.
29187 // $FlowFixMe[unsafe-addition] addition with possible null/undefined value
29188
29189 actualDuration += child.actualDuration; // $FlowFixMe[unsafe-addition] addition with possible null/undefined value
29190
29191 treeBaseDuration += child.treeBaseDuration;
29192 child = child.sibling;
29193 }
29194
29195 completedWork.actualDuration = actualDuration;
29196 completedWork.treeBaseDuration = treeBaseDuration;
29197 } else {
29198 var _child = completedWork.child;
29199
29200 while (_child !== null) {
29201 newChildLanes = mergeLanes(newChildLanes, mergeLanes(_child.lanes, _child.childLanes));
29202 subtreeFlags |= _child.subtreeFlags;
29203 subtreeFlags |= _child.flags; // Update the return pointer so the tree is consistent. This is a code
29204 // smell because it assumes the commit phase is never concurrent with
29205 // the render phase. Will address during refactor to alternate model.
29206
29207 _child.return = completedWork;
29208 _child = _child.sibling;
29209 }
29210 }
29211
29212 completedWork.subtreeFlags |= subtreeFlags;
29213 } else {
29214 // Bubble up the earliest expiration time.
29215 if ((completedWork.mode & ProfileMode) !== NoMode) {
29216 // In profiling mode, resetChildExpirationTime is also used to reset
29217 // profiler durations.
29218 var _treeBaseDuration = completedWork.selfBaseDuration;
29219 var _child2 = completedWork.child;
29220
29221 while (_child2 !== null) {
29222 newChildLanes = mergeLanes(newChildLanes, mergeLanes(_child2.lanes, _child2.childLanes)); // "Static" flags share the lifetime of the fiber/hook they belong to,
29223 // so we should bubble those up even during a bailout. All the other
29224 // flags have a lifetime only of a single render + commit, so we should
29225 // ignore them.
29226
29227 subtreeFlags |= _child2.subtreeFlags & StaticMask;
29228 subtreeFlags |= _child2.flags & StaticMask; // $FlowFixMe[unsafe-addition] addition with possible null/undefined value
29229
29230 _treeBaseDuration += _child2.treeBaseDuration;
29231 _child2 = _child2.sibling;
29232 }
29233
29234 completedWork.treeBaseDuration = _treeBaseDuration;
29235 } else {
29236 var _child3 = completedWork.child;
29237
29238 while (_child3 !== null) {
29239 newChildLanes = mergeLanes(newChildLanes, mergeLanes(_child3.lanes, _child3.childLanes)); // "Static" flags share the lifetime of the fiber/hook they belong to,
29240 // so we should bubble those up even during a bailout. All the other
29241 // flags have a lifetime only of a single render + commit, so we should
29242 // ignore them.
29243
29244 subtreeFlags |= _child3.subtreeFlags & StaticMask;
29245 subtreeFlags |= _child3.flags & StaticMask; // Update the return pointer so the tree is consistent. This is a code
29246 // smell because it assumes the commit phase is never concurrent with
29247 // the render phase. Will address during refactor to alternate model.
29248
29249 _child3.return = completedWork;
29250 _child3 = _child3.sibling;
29251 }
29252 }
29253
29254 completedWork.subtreeFlags |= subtreeFlags;
29255 }
29256
29257 completedWork.childLanes = newChildLanes;
29258 return didBailout;
29259}
29260
29261function completeDehydratedSuspenseBoundary(current, workInProgress, nextState) {
29262 var wasHydrated = popHydrationState(workInProgress);
29263
29264 if (nextState !== null && nextState.dehydrated !== null) {
29265 // We might be inside a hydration state the first time we're picking up this
29266 // Suspense boundary, and also after we've reentered it for further hydration.
29267 if (current === null) {
29268 if (!wasHydrated) {
29269 throw new Error('A dehydrated suspense component was completed without a hydrated node. ' + 'This is probably a bug in React.');
29270 }
29271
29272 prepareToHydrateHostSuspenseInstance(workInProgress);
29273 bubbleProperties(workInProgress);
29274
29275 {
29276 if ((workInProgress.mode & ProfileMode) !== NoMode) {
29277 var isTimedOutSuspense = nextState !== null;
29278
29279 if (isTimedOutSuspense) {
29280 // Don't count time spent in a timed out Suspense subtree as part of the base duration.
29281 var primaryChildFragment = workInProgress.child;
29282
29283 if (primaryChildFragment !== null) {
29284 // $FlowFixMe[unsafe-arithmetic] Flow doesn't support type casting in combination with the -= operator
29285 workInProgress.treeBaseDuration -= primaryChildFragment.treeBaseDuration;
29286 }
29287 }
29288 }
29289 }
29290
29291 return false;
29292 } else {
29293 emitPendingHydrationWarnings(); // We might have reentered this boundary to hydrate it. If so, we need to reset the hydration
29294 // state since we're now exiting out of it. popHydrationState doesn't do that for us.
29295
29296 resetHydrationState();
29297
29298 if ((workInProgress.flags & DidCapture) === NoFlags$1) {
29299 // This boundary did not suspend so it's now hydrated and unsuspended.
29300 workInProgress.memoizedState = null;
29301 } // If nothing suspended, we need to schedule an effect to mark this boundary
29302 // as having hydrated so events know that they're free to be invoked.
29303 // It's also a signal to replay events and the suspense callback.
29304 // If something suspended, schedule an effect to attach retry listeners.
29305 // So we might as well always mark this.
29306
29307
29308 workInProgress.flags |= Update;
29309 bubbleProperties(workInProgress);
29310
29311 {
29312 if ((workInProgress.mode & ProfileMode) !== NoMode) {
29313 var _isTimedOutSuspense = nextState !== null;
29314
29315 if (_isTimedOutSuspense) {
29316 // Don't count time spent in a timed out Suspense subtree as part of the base duration.
29317 var _primaryChildFragment = workInProgress.child;
29318
29319 if (_primaryChildFragment !== null) {
29320 // $FlowFixMe[unsafe-arithmetic] Flow doesn't support type casting in combination with the -= operator
29321 workInProgress.treeBaseDuration -= _primaryChildFragment.treeBaseDuration;
29322 }
29323 }
29324 }
29325 }
29326
29327 return false;
29328 }
29329 } else {
29330 // Successfully completed this tree. If this was a forced client render,
29331 // there may have been recoverable errors during first hydration
29332 // attempt. If so, add them to a queue so we can log them in the
29333 // commit phase.
29334 upgradeHydrationErrorsToRecoverable(); // Fall through to normal Suspense path
29335
29336 return true;
29337 }
29338}
29339
29340function completeWork(current, workInProgress, renderLanes) {
29341 var newProps = workInProgress.pendingProps; // Note: This intentionally doesn't check if we're hydrating because comparing
29342 // to the current tree provider fiber is just as fast and less error-prone.
29343 // Ideally we would have a special version of the work loop only
29344 // for hydration.
29345
29346 popTreeContext(workInProgress);
29347
29348 switch (workInProgress.tag) {
29349 case IncompleteFunctionComponent:
29350 {
29351 {
29352 break;
29353 } // Fallthrough
29354
29355 }
29356
29357 case LazyComponent:
29358 case SimpleMemoComponent:
29359 case FunctionComponent:
29360 case ForwardRef:
29361 case Fragment:
29362 case Mode:
29363 case Profiler:
29364 case ContextConsumer:
29365 case MemoComponent:
29366 bubbleProperties(workInProgress);
29367 return null;
29368
29369 case ClassComponent:
29370 {
29371
29372 bubbleProperties(workInProgress);
29373 return null;
29374 }
29375
29376 case HostRoot:
29377 {
29378 var fiberRoot = workInProgress.stateNode;
29379
29380 {
29381 var previousCache = null;
29382
29383 if (current !== null) {
29384 previousCache = current.memoizedState.cache;
29385 }
29386
29387 var cache = workInProgress.memoizedState.cache;
29388
29389 if (cache !== previousCache) {
29390 // Run passive effects to retain/release the cache.
29391 workInProgress.flags |= Passive$1;
29392 }
29393
29394 popCacheProvider(workInProgress);
29395 }
29396 popHostContainer(workInProgress);
29397
29398 if (fiberRoot.pendingContext) {
29399 fiberRoot.context = fiberRoot.pendingContext;
29400 fiberRoot.pendingContext = null;
29401 }
29402
29403 if (current === null || current.child === null) {
29404 // If we hydrated, pop so that we can delete any remaining children
29405 // that weren't hydrated.
29406 var wasHydrated = popHydrationState(workInProgress);
29407
29408 if (wasHydrated) {
29409 emitPendingHydrationWarnings(); // If we hydrated, then we'll need to schedule an update for
29410 // the commit side-effects on the root.
29411
29412 markUpdate(workInProgress);
29413 } else {
29414 if (current !== null) {
29415 var prevState = current.memoizedState;
29416
29417 if ( // Check if this is a client root
29418 !prevState.isDehydrated || // Check if we reverted to client rendering (e.g. due to an error)
29419 (workInProgress.flags & ForceClientRender) !== NoFlags$1) {
29420 // Schedule an effect to clear this container at the start of the
29421 // next commit. This handles the case of React rendering into a
29422 // container with previous children. It's also safe to do for
29423 // updates too, because current.child would only be null if the
29424 // previous render was null (so the container would already
29425 // be empty).
29426 workInProgress.flags |= Snapshot; // If this was a forced client render, there may have been
29427 // recoverable errors during first hydration attempt. If so, add
29428 // them to a queue so we can log them in the commit phase.
29429
29430 upgradeHydrationErrorsToRecoverable();
29431 }
29432 }
29433 }
29434 }
29435 bubbleProperties(workInProgress);
29436
29437 return null;
29438 }
29439
29440 case HostHoistable:
29441 {
29442 {
29443 var nextResource = workInProgress.memoizedState;
29444
29445 if (current === null) {
29446 // We are mounting and must Update this Hoistable in this commit
29447 // @TODO refactor this block to create the instance here in complete
29448 // phase if we are not hydrating.
29449 markUpdate(workInProgress);
29450
29451 if (nextResource !== null) {
29452 // This is a Hoistable Resource
29453 // This must come at the very end of the complete phase.
29454 bubbleProperties(workInProgress);
29455 preloadResourceAndSuspendIfNeeded(workInProgress, nextResource);
29456 return null;
29457 } else {
29458 // This is a Hoistable Instance
29459 // This must come at the very end of the complete phase.
29460 bubbleProperties(workInProgress);
29461 preloadInstanceAndSuspendIfNeeded(workInProgress);
29462 return null;
29463 }
29464 } else {
29465 // We are updating.
29466 var currentResource = current.memoizedState;
29467
29468 if (nextResource !== currentResource) {
29469 // We are transitioning to, from, or between Hoistable Resources
29470 // and require an update
29471 markUpdate(workInProgress);
29472 }
29473
29474 if (nextResource !== null) {
29475 // This is a Hoistable Resource
29476 // This must come at the very end of the complete phase.
29477 bubbleProperties(workInProgress);
29478
29479 if (nextResource === currentResource) {
29480 workInProgress.flags &= ~MaySuspendCommit;
29481 } else {
29482 preloadResourceAndSuspendIfNeeded(workInProgress, nextResource);
29483 }
29484
29485 return null;
29486 } else {
29487 // This is a Hoistable Instance
29488 // We may have props to update on the Hoistable instance.
29489 {
29490 var oldProps = current.memoizedProps;
29491
29492 if (oldProps !== newProps) {
29493 markUpdate(workInProgress);
29494 }
29495 } // This must come at the very end of the complete phase.
29496
29497
29498 bubbleProperties(workInProgress);
29499 preloadInstanceAndSuspendIfNeeded(workInProgress);
29500 return null;
29501 }
29502 }
29503 } // Fall through
29504
29505 }
29506
29507 case HostSingleton:
29508 {
29509 {
29510 popHostContext(workInProgress);
29511 var rootContainerInstance = getRootHostContainer();
29512 var _type = workInProgress.type;
29513
29514 if (current !== null && workInProgress.stateNode != null) {
29515 {
29516 var _oldProps2 = current.memoizedProps;
29517
29518 if (_oldProps2 !== newProps) {
29519 markUpdate(workInProgress);
29520 }
29521 }
29522 } else {
29523 if (!newProps) {
29524 if (workInProgress.stateNode === null) {
29525 throw new Error('We must have new props for new mounts. This error is likely ' + 'caused by a bug in React. Please file an issue.');
29526 } // This can happen when we abort work.
29527
29528
29529 bubbleProperties(workInProgress);
29530 return null;
29531 }
29532
29533 var currentHostContext = getHostContext();
29534
29535 var _wasHydrated = popHydrationState(workInProgress);
29536
29537 var instance;
29538
29539 if (_wasHydrated) {
29540 // We ignore the boolean indicating there is an updateQueue because
29541 // it is used only to set text children and HostSingletons do not
29542 // use them.
29543 prepareToHydrateHostInstance(workInProgress, currentHostContext);
29544 instance = workInProgress.stateNode;
29545 } else {
29546 instance = resolveSingletonInstance(_type, newProps, rootContainerInstance, currentHostContext, true);
29547 workInProgress.stateNode = instance;
29548 markUpdate(workInProgress);
29549 }
29550 }
29551
29552 bubbleProperties(workInProgress);
29553 return null;
29554 } // Fall through
29555
29556 }
29557
29558 case HostComponent:
29559 {
29560 popHostContext(workInProgress);
29561 var _type2 = workInProgress.type;
29562
29563 if (current !== null && workInProgress.stateNode != null) {
29564 updateHostComponent(current, workInProgress, _type2, newProps);
29565 } else {
29566 if (!newProps) {
29567 if (workInProgress.stateNode === null) {
29568 throw new Error('We must have new props for new mounts. This error is likely ' + 'caused by a bug in React. Please file an issue.');
29569 } // This can happen when we abort work.
29570
29571
29572 bubbleProperties(workInProgress);
29573 return null;
29574 }
29575
29576 var _currentHostContext = getHostContext(); // TODO: Move createInstance to beginWork and keep it on a context
29577 // "stack" as the parent. Then append children as we go in beginWork
29578 // or completeWork depending on whether we want to add them top->down or
29579 // bottom->up. Top->down is faster in IE11.
29580
29581
29582 var _wasHydrated2 = popHydrationState(workInProgress);
29583
29584 if (_wasHydrated2) {
29585 // TODO: Move this and createInstance step into the beginPhase
29586 // to consolidate.
29587 prepareToHydrateHostInstance(workInProgress, _currentHostContext);
29588 } else {
29589 var _rootContainerInstance = getRootHostContainer();
29590
29591 var _instance3 = createInstance(_type2, newProps, _rootContainerInstance, _currentHostContext, workInProgress); // TODO: For persistent renderers, we should pass children as part
29592 // of the initial instance creation
29593
29594
29595 appendAllChildren(_instance3, workInProgress);
29596 workInProgress.stateNode = _instance3; // Certain renderers require commit-time effects for initial mount.
29597 // (eg DOM renderer supports auto-focus for certain elements).
29598 // Make sure such renderers get scheduled for later work.
29599
29600 if (finalizeInitialChildren(_instance3, _type2, newProps)) {
29601 markUpdate(workInProgress);
29602 }
29603 }
29604 }
29605
29606 bubbleProperties(workInProgress); // This must come at the very end of the complete phase, because it might
29607 // throw to suspend, and if the resource immediately loads, the work loop
29608 // will resume rendering as if the work-in-progress completed. So it must
29609 // fully complete.
29610
29611 preloadInstanceAndSuspendIfNeeded(workInProgress);
29612 return null;
29613 }
29614
29615 case HostText:
29616 {
29617 var newText = newProps;
29618
29619 if (current && workInProgress.stateNode != null) {
29620 var oldText = current.memoizedProps; // If we have an alternate, that means this is an update and we need
29621 // to schedule a side-effect to do the updates.
29622
29623 updateHostText(current, workInProgress, oldText, newText);
29624 } else {
29625 if (typeof newText !== 'string') {
29626 if (workInProgress.stateNode === null) {
29627 throw new Error('We must have new props for new mounts. This error is likely ' + 'caused by a bug in React. Please file an issue.');
29628 } // This can happen when we abort work.
29629
29630 }
29631
29632 var _rootContainerInstance2 = getRootHostContainer();
29633
29634 var _currentHostContext2 = getHostContext();
29635
29636 var _wasHydrated3 = popHydrationState(workInProgress);
29637
29638 if (_wasHydrated3) {
29639 prepareToHydrateHostTextInstance(workInProgress);
29640 } else {
29641 workInProgress.stateNode = createTextInstance(newText, _rootContainerInstance2, _currentHostContext2, workInProgress);
29642 }
29643 }
29644
29645 bubbleProperties(workInProgress);
29646 return null;
29647 }
29648
29649 case SuspenseComponent:
29650 {
29651 var nextState = workInProgress.memoizedState; // Special path for dehydrated boundaries. We may eventually move this
29652 // to its own fiber type so that we can add other kinds of hydration
29653 // boundaries that aren't associated with a Suspense tree. In anticipation
29654 // of such a refactor, all the hydration logic is contained in
29655 // this branch.
29656
29657 if (current === null || current.memoizedState !== null && current.memoizedState.dehydrated !== null) {
29658 var fallthroughToNormalSuspensePath = completeDehydratedSuspenseBoundary(current, workInProgress, nextState);
29659
29660 if (!fallthroughToNormalSuspensePath) {
29661 if (workInProgress.flags & ForceClientRender) {
29662 popSuspenseHandler(workInProgress); // Special case. There were remaining unhydrated nodes. We treat
29663 // this as a mismatch. Revert to client rendering.
29664
29665 return workInProgress;
29666 } else {
29667 popSuspenseHandler(workInProgress); // Did not finish hydrating, either because this is the initial
29668 // render or because something suspended.
29669
29670 return null;
29671 }
29672 } // Continue with the normal Suspense path.
29673
29674 }
29675
29676 popSuspenseHandler(workInProgress);
29677
29678 if ((workInProgress.flags & DidCapture) !== NoFlags$1) {
29679 // Something suspended. Re-render with the fallback children.
29680 workInProgress.lanes = renderLanes; // Do not reset the effect list.
29681
29682 if ((workInProgress.mode & ProfileMode) !== NoMode) {
29683 transferActualDuration(workInProgress);
29684 } // Don't bubble properties in this case.
29685
29686
29687 return workInProgress;
29688 }
29689
29690 var nextDidTimeout = nextState !== null;
29691 var prevDidTimeout = current !== null && current.memoizedState !== null;
29692
29693 if (nextDidTimeout) {
29694 var offscreenFiber = workInProgress.child;
29695 var _previousCache = null;
29696
29697 if (offscreenFiber.alternate !== null && offscreenFiber.alternate.memoizedState !== null && offscreenFiber.alternate.memoizedState.cachePool !== null) {
29698 _previousCache = offscreenFiber.alternate.memoizedState.cachePool.pool;
29699 }
29700
29701 var _cache = null;
29702
29703 if (offscreenFiber.memoizedState !== null && offscreenFiber.memoizedState.cachePool !== null) {
29704 _cache = offscreenFiber.memoizedState.cachePool.pool;
29705 }
29706
29707 if (_cache !== _previousCache) {
29708 // Run passive effects to retain/release the cache.
29709 offscreenFiber.flags |= Passive$1;
29710 }
29711 } // If the suspended state of the boundary changes, we need to schedule
29712 // a passive effect, which is when we process the transitions
29713
29714
29715 if (nextDidTimeout !== prevDidTimeout) {
29716 // an effect to toggle the subtree's visibility. When we switch from
29717 // fallback -> primary, the inner Offscreen fiber schedules this effect
29718 // as part of its normal complete phase. But when we switch from
29719 // primary -> fallback, the inner Offscreen fiber does not have a complete
29720 // phase. So we need to schedule its effect here.
29721 //
29722 // We also use this flag to connect/disconnect the effects, but the same
29723 // logic applies: when re-connecting, the Offscreen fiber's complete
29724 // phase will handle scheduling the effect. It's only when the fallback
29725 // is active that we have to do anything special.
29726
29727
29728 if (nextDidTimeout) {
29729 var _offscreenFiber2 = workInProgress.child;
29730 _offscreenFiber2.flags |= Visibility;
29731 }
29732 }
29733
29734 var retryQueue = workInProgress.updateQueue;
29735 scheduleRetryEffect(workInProgress, retryQueue);
29736
29737 bubbleProperties(workInProgress);
29738
29739 {
29740 if ((workInProgress.mode & ProfileMode) !== NoMode) {
29741 if (nextDidTimeout) {
29742 // Don't count time spent in a timed out Suspense subtree as part of the base duration.
29743 var primaryChildFragment = workInProgress.child;
29744
29745 if (primaryChildFragment !== null) {
29746 // $FlowFixMe[unsafe-arithmetic] Flow doesn't support type casting in combination with the -= operator
29747 workInProgress.treeBaseDuration -= primaryChildFragment.treeBaseDuration;
29748 }
29749 }
29750 }
29751 }
29752
29753 return null;
29754 }
29755
29756 case HostPortal:
29757 popHostContainer(workInProgress);
29758
29759 if (current === null) {
29760 preparePortalMount(workInProgress.stateNode.containerInfo);
29761 }
29762
29763 bubbleProperties(workInProgress);
29764 return null;
29765
29766 case ContextProvider:
29767 // Pop provider fiber
29768 var context;
29769
29770 {
29771 context = workInProgress.type;
29772 }
29773
29774 popProvider(context, workInProgress);
29775 bubbleProperties(workInProgress);
29776 return null;
29777
29778 case IncompleteClassComponent:
29779 {
29780 {
29781 break;
29782 } // Same as class component case. I put it down here so that the tags are
29783 }
29784
29785 case SuspenseListComponent:
29786 {
29787 popSuspenseListContext(workInProgress);
29788 var renderState = workInProgress.memoizedState;
29789
29790 if (renderState === null) {
29791 // We're running in the default, "independent" mode.
29792 // We don't do anything in this mode.
29793 bubbleProperties(workInProgress);
29794 return null;
29795 }
29796
29797 var didSuspendAlready = (workInProgress.flags & DidCapture) !== NoFlags$1;
29798 var renderedTail = renderState.rendering;
29799
29800 if (renderedTail === null) {
29801 // We just rendered the head.
29802 if (!didSuspendAlready) {
29803 // This is the first pass. We need to figure out if anything is still
29804 // suspended in the rendered set.
29805 // If new content unsuspended, but there's still some content that
29806 // didn't. Then we need to do a second pass that forces everything
29807 // to keep showing their fallbacks.
29808 // We might be suspended if something in this render pass suspended, or
29809 // something in the previous committed pass suspended. Otherwise,
29810 // there's no chance so we can skip the expensive call to
29811 // findFirstSuspended.
29812 var cannotBeSuspended = renderHasNotSuspendedYet() && (current === null || (current.flags & DidCapture) === NoFlags$1);
29813
29814 if (!cannotBeSuspended) {
29815 var row = workInProgress.child;
29816
29817 while (row !== null) {
29818 var suspended = findFirstSuspended(row);
29819
29820 if (suspended !== null) {
29821 didSuspendAlready = true;
29822 workInProgress.flags |= DidCapture;
29823 cutOffTailIfNeeded(renderState, false); // If this is a newly suspended tree, it might not get committed as
29824 // part of the second pass. In that case nothing will subscribe to
29825 // its thenables. Instead, we'll transfer its thenables to the
29826 // SuspenseList so that it can retry if they resolve.
29827 // There might be multiple of these in the list but since we're
29828 // going to wait for all of them anyway, it doesn't really matter
29829 // which ones gets to ping. In theory we could get clever and keep
29830 // track of how many dependencies remain but it gets tricky because
29831 // in the meantime, we can add/remove/change items and dependencies.
29832 // We might bail out of the loop before finding any but that
29833 // doesn't matter since that means that the other boundaries that
29834 // we did find already has their listeners attached.
29835
29836 var _retryQueue = suspended.updateQueue;
29837 workInProgress.updateQueue = _retryQueue;
29838 scheduleRetryEffect(workInProgress, _retryQueue); // Rerender the whole list, but this time, we'll force fallbacks
29839 // to stay in place.
29840 // Reset the effect flags before doing the second pass since that's now invalid.
29841 // Reset the child fibers to their original state.
29842
29843 workInProgress.subtreeFlags = NoFlags$1;
29844 resetChildFibers(workInProgress, renderLanes); // Set up the Suspense List Context to force suspense and
29845 // immediately rerender the children.
29846
29847 pushSuspenseListContext(workInProgress, setShallowSuspenseListContext(suspenseStackCursor.current, ForceSuspenseFallback)); // Don't bubble properties in this case.
29848
29849 return workInProgress.child;
29850 }
29851
29852 row = row.sibling;
29853 }
29854 }
29855
29856 if (renderState.tail !== null && now$1() > getRenderTargetTime()) {
29857 // We have already passed our CPU deadline but we still have rows
29858 // left in the tail. We'll just give up further attempts to render
29859 // the main content and only render fallbacks.
29860 workInProgress.flags |= DidCapture;
29861 didSuspendAlready = true;
29862 cutOffTailIfNeeded(renderState, false); // Since nothing actually suspended, there will nothing to ping this
29863 // to get it started back up to attempt the next item. While in terms
29864 // of priority this work has the same priority as this current render,
29865 // it's not part of the same transition once the transition has
29866 // committed. If it's sync, we still want to yield so that it can be
29867 // painted. Conceptually, this is really the same as pinging.
29868 // We can use any RetryLane even if it's the one currently rendering
29869 // since we're leaving it behind on this node.
29870
29871 workInProgress.lanes = SomeRetryLane;
29872 }
29873 } else {
29874 cutOffTailIfNeeded(renderState, false);
29875 } // Next we're going to render the tail.
29876
29877 } else {
29878 // Append the rendered row to the child list.
29879 if (!didSuspendAlready) {
29880 var _suspended = findFirstSuspended(renderedTail);
29881
29882 if (_suspended !== null) {
29883 workInProgress.flags |= DidCapture;
29884 didSuspendAlready = true; // Ensure we transfer the update queue to the parent so that it doesn't
29885 // get lost if this row ends up dropped during a second pass.
29886
29887 var _retryQueue2 = _suspended.updateQueue;
29888 workInProgress.updateQueue = _retryQueue2;
29889 scheduleRetryEffect(workInProgress, _retryQueue2);
29890 cutOffTailIfNeeded(renderState, true); // This might have been modified.
29891
29892 if (renderState.tail === null && renderState.tailMode === 'hidden' && !renderedTail.alternate && !getIsHydrating() // We don't cut it if we're hydrating.
29893 ) {
29894 // We're done.
29895 bubbleProperties(workInProgress);
29896 return null;
29897 }
29898 } else if ( // The time it took to render last row is greater than the remaining
29899 // time we have to render. So rendering one more row would likely
29900 // exceed it.
29901 now$1() * 2 - renderState.renderingStartTime > getRenderTargetTime() && renderLanes !== OffscreenLane) {
29902 // We have now passed our CPU deadline and we'll just give up further
29903 // attempts to render the main content and only render fallbacks.
29904 // The assumption is that this is usually faster.
29905 workInProgress.flags |= DidCapture;
29906 didSuspendAlready = true;
29907 cutOffTailIfNeeded(renderState, false); // Since nothing actually suspended, there will nothing to ping this
29908 // to get it started back up to attempt the next item. While in terms
29909 // of priority this work has the same priority as this current render,
29910 // it's not part of the same transition once the transition has
29911 // committed. If it's sync, we still want to yield so that it can be
29912 // painted. Conceptually, this is really the same as pinging.
29913 // We can use any RetryLane even if it's the one currently rendering
29914 // since we're leaving it behind on this node.
29915
29916 workInProgress.lanes = SomeRetryLane;
29917 }
29918 }
29919
29920 if (renderState.isBackwards) {
29921 // The effect list of the backwards tail will have been added
29922 // to the end. This breaks the guarantee that life-cycles fire in
29923 // sibling order but that isn't a strong guarantee promised by React.
29924 // Especially since these might also just pop in during future commits.
29925 // Append to the beginning of the list.
29926 renderedTail.sibling = workInProgress.child;
29927 workInProgress.child = renderedTail;
29928 } else {
29929 var previousSibling = renderState.last;
29930
29931 if (previousSibling !== null) {
29932 previousSibling.sibling = renderedTail;
29933 } else {
29934 workInProgress.child = renderedTail;
29935 }
29936
29937 renderState.last = renderedTail;
29938 }
29939 }
29940
29941 if (renderState.tail !== null) {
29942 // We still have tail rows to render.
29943 // Pop a row.
29944 var next = renderState.tail;
29945 renderState.rendering = next;
29946 renderState.tail = next.sibling;
29947 renderState.renderingStartTime = now$1();
29948 next.sibling = null; // Restore the context.
29949 // TODO: We can probably just avoid popping it instead and only
29950 // setting it the first time we go from not suspended to suspended.
29951
29952 var suspenseContext = suspenseStackCursor.current;
29953
29954 if (didSuspendAlready) {
29955 suspenseContext = setShallowSuspenseListContext(suspenseContext, ForceSuspenseFallback);
29956 } else {
29957 suspenseContext = setDefaultShallowSuspenseListContext(suspenseContext);
29958 }
29959
29960 pushSuspenseListContext(workInProgress, suspenseContext); // Do a pass over the next row.
29961 // Don't bubble properties in this case.
29962
29963 return next;
29964 }
29965
29966 bubbleProperties(workInProgress);
29967 return null;
29968 }
29969
29970 case ScopeComponent:
29971 {
29972
29973 break;
29974 }
29975
29976 case OffscreenComponent:
29977 case LegacyHiddenComponent:
29978 {
29979 popSuspenseHandler(workInProgress);
29980 popHiddenContext(workInProgress);
29981 var _nextState = workInProgress.memoizedState;
29982 var nextIsHidden = _nextState !== null; // Schedule a Visibility effect if the visibility has changed
29983
29984 {
29985 if (current !== null) {
29986 var _prevState = current.memoizedState;
29987 var prevIsHidden = _prevState !== null;
29988
29989 if (prevIsHidden !== nextIsHidden) {
29990 workInProgress.flags |= Visibility;
29991 }
29992 } else {
29993 // On initial mount, we only need a Visibility effect if the tree
29994 // is hidden.
29995 if (nextIsHidden) {
29996 workInProgress.flags |= Visibility;
29997 }
29998 }
29999 }
30000
30001 if (!nextIsHidden || !disableLegacyMode ) {
30002 bubbleProperties(workInProgress);
30003 } else {
30004 // Don't bubble properties for hidden children unless we're rendering
30005 // at offscreen priority.
30006 if (includesSomeLane(renderLanes, OffscreenLane) && // Also don't bubble if the tree suspended
30007 (workInProgress.flags & DidCapture) === NoLanes) {
30008 bubbleProperties(workInProgress); // Check if there was an insertion or update in the hidden subtree.
30009 // If so, we need to hide those nodes in the commit phase, so
30010 // schedule a visibility effect.
30011
30012 if (workInProgress.subtreeFlags & (Placement | Update)) {
30013 workInProgress.flags |= Visibility;
30014 }
30015 }
30016 }
30017
30018 var offscreenQueue = workInProgress.updateQueue;
30019
30020 if (offscreenQueue !== null) {
30021 var _retryQueue3 = offscreenQueue.retryQueue;
30022 scheduleRetryEffect(workInProgress, _retryQueue3);
30023 }
30024
30025 {
30026 var _previousCache2 = null;
30027
30028 if (current !== null && current.memoizedState !== null && current.memoizedState.cachePool !== null) {
30029 _previousCache2 = current.memoizedState.cachePool.pool;
30030 }
30031
30032 var _cache2 = null;
30033
30034 if (workInProgress.memoizedState !== null && workInProgress.memoizedState.cachePool !== null) {
30035 _cache2 = workInProgress.memoizedState.cachePool.pool;
30036 }
30037
30038 if (_cache2 !== _previousCache2) {
30039 // Run passive effects to retain/release the cache.
30040 workInProgress.flags |= Passive$1;
30041 }
30042 }
30043
30044 popTransition(workInProgress, current);
30045 return null;
30046 }
30047
30048 case CacheComponent:
30049 {
30050 {
30051 var _previousCache3 = null;
30052
30053 if (current !== null) {
30054 _previousCache3 = current.memoizedState.cache;
30055 }
30056
30057 var _cache3 = workInProgress.memoizedState.cache;
30058
30059 if (_cache3 !== _previousCache3) {
30060 // Run passive effects to retain/release the cache.
30061 workInProgress.flags |= Passive$1;
30062 }
30063
30064 popCacheProvider(workInProgress);
30065 bubbleProperties(workInProgress);
30066 }
30067
30068 return null;
30069 }
30070
30071 case TracingMarkerComponent:
30072 {
30073
30074 return null;
30075 }
30076 }
30077
30078 throw new Error("Unknown unit of work tag (" + workInProgress.tag + "). This error is likely caused by a bug in " + 'React. Please file an issue.');
30079}
30080
30081function unwindWork(current, workInProgress, renderLanes) {
30082 // Note: This intentionally doesn't check if we're hydrating because comparing
30083 // to the current tree provider fiber is just as fast and less error-prone.
30084 // Ideally we would have a special version of the work loop only
30085 // for hydration.
30086 popTreeContext(workInProgress);
30087
30088 switch (workInProgress.tag) {
30089 case ClassComponent:
30090 {
30091
30092 var flags = workInProgress.flags;
30093
30094 if (flags & ShouldCapture) {
30095 workInProgress.flags = flags & ~ShouldCapture | DidCapture;
30096
30097 if ((workInProgress.mode & ProfileMode) !== NoMode) {
30098 transferActualDuration(workInProgress);
30099 }
30100
30101 return workInProgress;
30102 }
30103
30104 return null;
30105 }
30106
30107 case HostRoot:
30108 {
30109
30110 {
30111 popCacheProvider(workInProgress);
30112 }
30113 popHostContainer(workInProgress);
30114 var _flags = workInProgress.flags;
30115
30116 if ((_flags & ShouldCapture) !== NoFlags$1 && (_flags & DidCapture) === NoFlags$1) {
30117 // There was an error during render that wasn't captured by a suspense
30118 // boundary. Do a second pass on the root to unmount the children.
30119 workInProgress.flags = _flags & ~ShouldCapture | DidCapture;
30120 return workInProgress;
30121 } // We unwound to the root without completing it. Exit.
30122
30123
30124 return null;
30125 }
30126
30127 case HostHoistable:
30128 case HostSingleton:
30129 case HostComponent:
30130 {
30131 // TODO: popHydrationState
30132 popHostContext(workInProgress);
30133 return null;
30134 }
30135
30136 case SuspenseComponent:
30137 {
30138 popSuspenseHandler(workInProgress);
30139 var suspenseState = workInProgress.memoizedState;
30140
30141 if (suspenseState !== null && suspenseState.dehydrated !== null) {
30142 if (workInProgress.alternate === null) {
30143 throw new Error('Threw in newly mounted dehydrated component. This is likely a bug in ' + 'React. Please file an issue.');
30144 }
30145
30146 resetHydrationState();
30147 }
30148
30149 var _flags2 = workInProgress.flags;
30150
30151 if (_flags2 & ShouldCapture) {
30152 workInProgress.flags = _flags2 & ~ShouldCapture | DidCapture; // Captured a suspense effect. Re-render the boundary.
30153
30154 if ((workInProgress.mode & ProfileMode) !== NoMode) {
30155 transferActualDuration(workInProgress);
30156 }
30157
30158 return workInProgress;
30159 }
30160
30161 return null;
30162 }
30163
30164 case SuspenseListComponent:
30165 {
30166 popSuspenseListContext(workInProgress); // SuspenseList doesn't actually catch anything. It should've been
30167 // caught by a nested boundary. If not, it should bubble through.
30168
30169 return null;
30170 }
30171
30172 case HostPortal:
30173 popHostContainer(workInProgress);
30174 return null;
30175
30176 case ContextProvider:
30177 var context;
30178
30179 {
30180 context = workInProgress.type;
30181 }
30182
30183 popProvider(context, workInProgress);
30184 return null;
30185
30186 case OffscreenComponent:
30187 case LegacyHiddenComponent:
30188 {
30189 popSuspenseHandler(workInProgress);
30190 popHiddenContext(workInProgress);
30191 popTransition(workInProgress, current);
30192 var _flags3 = workInProgress.flags;
30193
30194 if (_flags3 & ShouldCapture) {
30195 workInProgress.flags = _flags3 & ~ShouldCapture | DidCapture; // Captured a suspense effect. Re-render the boundary.
30196
30197 if ((workInProgress.mode & ProfileMode) !== NoMode) {
30198 transferActualDuration(workInProgress);
30199 }
30200
30201 return workInProgress;
30202 }
30203
30204 return null;
30205 }
30206
30207 case CacheComponent:
30208 {
30209 popCacheProvider(workInProgress);
30210 }
30211
30212 return null;
30213
30214 case TracingMarkerComponent:
30215
30216 return null;
30217
30218 default:
30219 return null;
30220 }
30221}
30222
30223function unwindInterruptedWork(current, interruptedWork, renderLanes) {
30224 // Note: This intentionally doesn't check if we're hydrating because comparing
30225 // to the current tree provider fiber is just as fast and less error-prone.
30226 // Ideally we would have a special version of the work loop only
30227 // for hydration.
30228 popTreeContext(interruptedWork);
30229
30230 switch (interruptedWork.tag) {
30231 case ClassComponent:
30232 {
30233
30234 break;
30235 }
30236
30237 case HostRoot:
30238 {
30239
30240 {
30241 popCacheProvider(interruptedWork);
30242 }
30243 popHostContainer(interruptedWork);
30244 break;
30245 }
30246
30247 case HostHoistable:
30248 case HostSingleton:
30249 case HostComponent:
30250 {
30251 popHostContext(interruptedWork);
30252 break;
30253 }
30254
30255 case HostPortal:
30256 popHostContainer(interruptedWork);
30257 break;
30258
30259 case SuspenseComponent:
30260 popSuspenseHandler(interruptedWork);
30261 break;
30262
30263 case SuspenseListComponent:
30264 popSuspenseListContext(interruptedWork);
30265 break;
30266
30267 case ContextProvider:
30268 var context;
30269
30270 {
30271 context = interruptedWork.type;
30272 }
30273
30274 popProvider(context, interruptedWork);
30275 break;
30276
30277 case OffscreenComponent:
30278 case LegacyHiddenComponent:
30279 popSuspenseHandler(interruptedWork);
30280 popHiddenContext(interruptedWork);
30281 popTransition(interruptedWork, current);
30282 break;
30283
30284 case CacheComponent:
30285 {
30286 popCacheProvider(interruptedWork);
30287 }
30288
30289 break;
30290 }
30291}
30292
30293function getCacheForType(resourceType) {
30294
30295 var cache = readContext(CacheContext);
30296 var cacheForType = cache.data.get(resourceType);
30297
30298 if (cacheForType === undefined) {
30299 cacheForType = resourceType();
30300 cache.data.set(resourceType, cacheForType);
30301 }
30302
30303 return cacheForType;
30304}
30305
30306var DefaultAsyncDispatcher = {
30307 getCacheForType: getCacheForType
30308};
30309
30310{
30311 DefaultAsyncDispatcher.getOwner = function () {
30312 return currentOwner;
30313 };
30314}
30315
30316if (typeof Symbol === 'function' && Symbol.for) {
30317 var symbolFor = Symbol.for;
30318 symbolFor('selector.component');
30319 symbolFor('selector.has_pseudo_class');
30320 symbolFor('selector.role');
30321 symbolFor('selector.test_id');
30322 symbolFor('selector.text');
30323}
30324var commitHooks = [];
30325function onCommitRoot() {
30326 {
30327 commitHooks.forEach(function (commitHook) {
30328 return commitHook();
30329 });
30330 }
30331}
30332
30333function isConcurrentActEnvironment() {
30334 {
30335 var isReactActEnvironmentGlobal = // $FlowFixMe[cannot-resolve-name] Flow doesn't know about IS_REACT_ACT_ENVIRONMENT global
30336 typeof IS_REACT_ACT_ENVIRONMENT !== 'undefined' ? // $FlowFixMe[cannot-resolve-name]
30337 IS_REACT_ACT_ENVIRONMENT : undefined;
30338
30339 if (!isReactActEnvironmentGlobal && ReactSharedInternals.actQueue !== null) {
30340 // TODO: Include link to relevant documentation page.
30341 error('The current testing environment is not configured to support ' + 'act(...)');
30342 }
30343
30344 return isReactActEnvironmentGlobal;
30345 }
30346}
30347
30348var PossiblyWeakMap = typeof WeakMap === 'function' ? WeakMap : Map;
30349var NoContext =
30350/* */
303510;
30352var RenderContext =
30353/* */
303542;
30355var CommitContext =
30356/* */
303574;
30358var RootInProgress = 0;
30359var RootFatalErrored = 1;
30360var RootErrored = 2;
30361var RootSuspended = 3;
30362var RootSuspendedWithDelay = 4;
30363var RootCompleted = 5;
30364var RootDidNotComplete = 6; // Describes where we are in the React execution stack
30365
30366var executionContext = NoContext; // The root we're working on
30367
30368var workInProgressRoot = null; // The fiber we're working on
30369
30370var workInProgress = null; // The lanes we're rendering
30371
30372var workInProgressRootRenderLanes = NoLanes;
30373var NotSuspended = 0;
30374var SuspendedOnError = 1;
30375var SuspendedOnData = 2;
30376var SuspendedOnImmediate = 3;
30377var SuspendedOnInstance = 4;
30378var SuspendedOnInstanceAndReadyToContinue = 5;
30379var SuspendedOnDeprecatedThrowPromise = 6;
30380var SuspendedAndReadyToContinue = 7;
30381var SuspendedOnHydration = 8; // When this is true, the work-in-progress fiber just suspended (or errored) and
30382// we've yet to unwind the stack. In some cases, we may yield to the main thread
30383// after this happens. If the fiber is pinged before we resume, we can retry
30384// immediately instead of unwinding the stack.
30385
30386var workInProgressSuspendedReason = NotSuspended;
30387var workInProgressThrownValue = null; // Whether a ping listener was attached during this render. This is slightly
30388// different that whether something suspended, because we don't add multiple
30389// listeners to a promise we've already seen (per root and lane).
30390
30391var workInProgressRootDidAttachPingListener = false; // A contextual version of workInProgressRootRenderLanes. It is a superset of
30392// the lanes that we started working on at the root. When we enter a subtree
30393// that is currently hidden, we add the lanes that would have committed if
30394// the hidden tree hadn't been deferred. This is modified by the
30395// HiddenContext module.
30396//
30397// Most things in the work loop should deal with workInProgressRootRenderLanes.
30398// Most things in begin/complete phases should deal with entangledRenderLanes.
30399
30400var entangledRenderLanes = NoLanes; // Whether to root completed, errored, suspended, etc.
30401
30402var workInProgressRootExitStatus = RootInProgress; // The work left over by components that were visited during this render. Only
30403// includes unprocessed updates, not work in bailed out children.
30404
30405var workInProgressRootSkippedLanes = NoLanes; // Lanes that were updated (in an interleaved event) during this render.
30406
30407var workInProgressRootInterleavedUpdatedLanes = NoLanes; // Lanes that were updated during the render phase (*not* an interleaved event).
30408
30409var workInProgressRootPingedLanes = NoLanes; // If this lane scheduled deferred work, this is the lane of the deferred task.
30410
30411var workInProgressDeferredLane = NoLane; // Errors that are thrown during the render phase.
30412
30413var workInProgressRootConcurrentErrors = null; // These are errors that we recovered from without surfacing them to the UI.
30414// We will log them once the tree commits.
30415
30416var workInProgressRootRecoverableErrors = null; // Tracks when an update occurs during the render phase.
30417
30418var workInProgressRootDidIncludeRecursiveRenderUpdate = false; // Thacks when an update occurs during the commit phase. It's a separate
30419// variable from the one for renders because the commit phase may run
30420// concurrently to a render phase.
30421
30422var didIncludeCommitPhaseUpdate = false; // The most recent time we either committed a fallback, or when a fallback was
30423// filled in with the resolved UI. This lets us throttle the appearance of new
30424// content as it streams in, to minimize jank.
30425// TODO: Think of a better name for this variable?
30426
30427var globalMostRecentFallbackTime = 0;
30428var FALLBACK_THROTTLE_MS = 300; // The absolute time for when we should start giving up on rendering
30429// more and prefer CPU suspense heuristics instead.
30430
30431var workInProgressRootRenderTargetTime = Infinity; // How long a render is supposed to take before we start following CPU
30432// suspense heuristics and opt out of rendering more content.
30433
30434var RENDER_TIMEOUT_MS = 500;
30435var workInProgressTransitions = null;
30436
30437function resetRenderTimer() {
30438 workInProgressRootRenderTargetTime = now$1() + RENDER_TIMEOUT_MS;
30439}
30440
30441function getRenderTargetTime() {
30442 return workInProgressRootRenderTargetTime;
30443}
30444var legacyErrorBoundariesThatAlreadyFailed = null;
30445var rootDoesHavePassiveEffects = false;
30446var rootWithPendingPassiveEffects = null;
30447var pendingPassiveEffectsLanes = NoLanes;
30448var pendingPassiveProfilerEffects = [];
30449var pendingPassiveEffectsRemainingLanes = NoLanes;
30450var pendingPassiveTransitions = null; // Use these to prevent an infinite loop of nested updates
30451
30452var NESTED_UPDATE_LIMIT = 50;
30453var nestedUpdateCount = 0;
30454var rootWithNestedUpdates = null;
30455var isFlushingPassiveEffects = false;
30456var didScheduleUpdateDuringPassiveEffects = false;
30457var NESTED_PASSIVE_UPDATE_LIMIT = 50;
30458var nestedPassiveUpdateCount = 0;
30459var rootWithPassiveNestedUpdates = null;
30460var isRunningInsertionEffect = false;
30461function getWorkInProgressRoot() {
30462 return workInProgressRoot;
30463}
30464function getWorkInProgressRootRenderLanes() {
30465 return workInProgressRootRenderLanes;
30466}
30467function isWorkLoopSuspendedOnData() {
30468 return workInProgressSuspendedReason === SuspendedOnData;
30469}
30470function requestUpdateLane(fiber) {
30471
30472 if ((executionContext & RenderContext) !== NoContext && workInProgressRootRenderLanes !== NoLanes) {
30473 // This is a render phase update. These are not officially supported. The
30474 // old behavior is to give this the same "thread" (lanes) as
30475 // whatever is currently rendering. So if you call `setState` on a component
30476 // that happens later in the same render, it will flush. Ideally, we want to
30477 // remove the special case and treat them as if they came from an
30478 // interleaved event. Regardless, this pattern is not officially supported.
30479 // This behavior is only a fallback. The flag only exists until we can roll
30480 // out the setState warning, since existing code might accidentally rely on
30481 // the current behavior.
30482 return pickArbitraryLane(workInProgressRootRenderLanes);
30483 }
30484
30485 var transition = requestCurrentTransition();
30486
30487 if (transition !== null) {
30488 {
30489 if (!transition._updatedFibers) {
30490 transition._updatedFibers = new Set();
30491 }
30492
30493 transition._updatedFibers.add(fiber);
30494 }
30495
30496 var actionScopeLane = peekEntangledActionLane();
30497 return actionScopeLane !== NoLane ? // We're inside an async action scope. Reuse the same lane.
30498 actionScopeLane : // We may or may not be inside an async action scope. If we are, this
30499 // is the first update in that scope. Either way, we need to get a
30500 // fresh transition lane.
30501 requestTransitionLane();
30502 }
30503
30504 return eventPriorityToLane(resolveUpdatePriority());
30505}
30506
30507function requestRetryLane(fiber) {
30508
30509 return claimNextRetryLane();
30510}
30511
30512function requestDeferredLane() {
30513 if (workInProgressDeferredLane === NoLane) {
30514 // If there are multiple useDeferredValue hooks in the same render, the
30515 // tasks that they spawn should all be batched together, so they should all
30516 // receive the same lane.
30517 // Check the priority of the current render to decide the priority of the
30518 // deferred task.
30519 // OffscreenLane is used for prerendering, but we also use OffscreenLane
30520 // for incremental hydration. It's given the lowest priority because the
30521 // initial HTML is the same as the final UI. But useDeferredValue during
30522 // hydration is an exception — we need to upgrade the UI to the final
30523 // value. So if we're currently hydrating, we treat it like a transition.
30524 var isPrerendering = includesSomeLane(workInProgressRootRenderLanes, OffscreenLane) && !getIsHydrating();
30525
30526 if (isPrerendering) {
30527 // There's only one OffscreenLane, so if it contains deferred work, we
30528 // should just reschedule using the same lane.
30529 workInProgressDeferredLane = OffscreenLane;
30530 } else {
30531 // Everything else is spawned as a transition.
30532 workInProgressDeferredLane = claimNextTransitionLane();
30533 }
30534 } // Mark the parent Suspense boundary so it knows to spawn the deferred lane.
30535
30536
30537 var suspenseHandler = getSuspenseHandler();
30538
30539 if (suspenseHandler !== null) {
30540 // TODO: As an optimization, we shouldn't entangle the lanes at the root; we
30541 // can entangle them using the baseLanes of the Suspense boundary instead.
30542 // We only need to do something special if there's no Suspense boundary.
30543 suspenseHandler.flags |= DidDefer;
30544 }
30545
30546 return workInProgressDeferredLane;
30547}
30548function peekDeferredLane() {
30549 return workInProgressDeferredLane;
30550}
30551function scheduleUpdateOnFiber(root, fiber, lane) {
30552 {
30553 if (isRunningInsertionEffect) {
30554 error('useInsertionEffect must not schedule updates.');
30555 }
30556 }
30557
30558 {
30559 if (isFlushingPassiveEffects) {
30560 didScheduleUpdateDuringPassiveEffects = true;
30561 }
30562 } // Check if the work loop is currently suspended and waiting for data to
30563 // finish loading.
30564
30565
30566 if ( // Suspended render phase
30567 root === workInProgressRoot && workInProgressSuspendedReason === SuspendedOnData || // Suspended commit phase
30568 root.cancelPendingCommit !== null) {
30569 // The incoming update might unblock the current render. Interrupt the
30570 // current attempt and restart from the top.
30571 prepareFreshStack(root, NoLanes);
30572 markRootSuspended(root, workInProgressRootRenderLanes, workInProgressDeferredLane);
30573 } // Mark that the root has a pending update.
30574
30575
30576 markRootUpdated(root, lane);
30577
30578 if ((executionContext & RenderContext) !== NoLanes && root === workInProgressRoot) {
30579 // This update was dispatched during the render phase. This is a mistake
30580 // if the update originates from user space (with the exception of local
30581 // hook updates, which are handled differently and don't reach this
30582 // function), but there are some internal React features that use this as
30583 // an implementation detail, like selective hydration.
30584 warnAboutRenderPhaseUpdatesInDEV(fiber); // Track lanes that were updated during the render phase
30585 } else {
30586 // This is a normal update, scheduled from outside the render phase. For
30587 // example, during an input event.
30588 {
30589 if (isDevToolsPresent) {
30590 addFiberToLanesMap(root, fiber, lane);
30591 }
30592 }
30593
30594 warnIfUpdatesNotWrappedWithActDEV(fiber);
30595
30596 if (root === workInProgressRoot) {
30597 // Received an update to a tree that's in the middle of rendering. Mark
30598 // that there was an interleaved update work on this root.
30599 if ((executionContext & RenderContext) === NoContext) {
30600 workInProgressRootInterleavedUpdatedLanes = mergeLanes(workInProgressRootInterleavedUpdatedLanes, lane);
30601 }
30602
30603 if (workInProgressRootExitStatus === RootSuspendedWithDelay) {
30604 // The root already suspended with a delay, which means this render
30605 // definitely won't finish. Since we have a new update, let's mark it as
30606 // suspended now, right before marking the incoming update. This has the
30607 // effect of interrupting the current render and switching to the update.
30608 // TODO: Make sure this doesn't override pings that happen while we've
30609 // already started rendering.
30610 markRootSuspended(root, workInProgressRootRenderLanes, workInProgressDeferredLane);
30611 }
30612 }
30613
30614 ensureRootIsScheduled(root);
30615
30616 if (lane === SyncLane && executionContext === NoContext && !disableLegacyMode && (fiber.mode & ConcurrentMode) === NoMode) {
30617 if (ReactSharedInternals.isBatchingLegacy) ; else {
30618 // Flush the synchronous work now, unless we're already working or inside
30619 // a batch. This is intentionally inside scheduleUpdateOnFiber instead of
30620 // scheduleCallbackForFiber to preserve the ability to schedule a callback
30621 // without immediately flushing it. We only do this for user-initiated
30622 // updates, to preserve historical behavior of legacy mode.
30623 resetRenderTimer();
30624 }
30625 }
30626 }
30627}
30628function scheduleInitialHydrationOnRoot(root, lane) {
30629 // This is a special fork of scheduleUpdateOnFiber that is only used to
30630 // schedule the initial hydration of a root that has just been created. Most
30631 // of the stuff in scheduleUpdateOnFiber can be skipped.
30632 //
30633 // The main reason for this separate path, though, is to distinguish the
30634 // initial children from subsequent updates. In fully client-rendered roots
30635 // (createRoot instead of hydrateRoot), all top-level renders are modeled as
30636 // updates, but hydration roots are special because the initial render must
30637 // match what was rendered on the server.
30638 var current = root.current;
30639 current.lanes = lane;
30640 markRootUpdated(root, lane);
30641 ensureRootIsScheduled(root);
30642}
30643function isUnsafeClassRenderPhaseUpdate(fiber) {
30644 // Check if this is a render phase update. Only called by class components,
30645 // which special (deprecated) behavior for UNSAFE_componentWillReceive props.
30646 return (executionContext & RenderContext) !== NoContext;
30647} // This is the entry point for every concurrent task, i.e. anything that
30648// goes through Scheduler.
30649
30650function performConcurrentWorkOnRoot(root, didTimeout) {
30651 {
30652 resetNestedUpdateFlag();
30653 }
30654
30655 if ((executionContext & (RenderContext | CommitContext)) !== NoContext) {
30656 throw new Error('Should not already be working.');
30657 } // Flush any pending passive effects before deciding which lanes to work on,
30658 // in case they schedule additional work.
30659
30660
30661 var originalCallbackNode = root.callbackNode;
30662 var didFlushPassiveEffects = flushPassiveEffects();
30663
30664 if (didFlushPassiveEffects) {
30665 // Something in the passive effect phase may have canceled the current task.
30666 // Check if the task node for this root was changed.
30667 if (root.callbackNode !== originalCallbackNode) {
30668 // The current task was canceled. Exit. We don't need to call
30669 // `ensureRootIsScheduled` because the check above implies either that
30670 // there's a new task, or that there's no remaining work on this root.
30671 return null;
30672 }
30673 } // Determine the next lanes to work on, using the fields stored
30674 // on the root.
30675 // TODO: This was already computed in the caller. Pass it as an argument.
30676
30677
30678 var lanes = getNextLanes(root, root === workInProgressRoot ? workInProgressRootRenderLanes : NoLanes);
30679
30680 if (lanes === NoLanes) {
30681 // Defensive coding. This is never expected to happen.
30682 return null;
30683 } // We disable time-slicing in some cases: if the work has been CPU-bound
30684 // for too long ("expired" work, to prevent starvation), or we're in
30685 // sync-updates-by-default mode.
30686 // TODO: We only check `didTimeout` defensively, to account for a Scheduler
30687 // bug we're still investigating. Once the bug in Scheduler is fixed,
30688 // we can remove this, since we track expiration ourselves.
30689
30690
30691 var shouldTimeSlice = !includesBlockingLane(root, lanes) && !includesExpiredLane(root, lanes) && (!didTimeout);
30692 var exitStatus = shouldTimeSlice ? renderRootConcurrent(root, lanes) : renderRootSync(root, lanes);
30693
30694 if (exitStatus !== RootInProgress) {
30695 var renderWasConcurrent = shouldTimeSlice;
30696
30697 do {
30698 if (exitStatus === RootDidNotComplete) {
30699 // The render unwound without completing the tree. This happens in special
30700 // cases where need to exit the current render without producing a
30701 // consistent tree or committing.
30702 markRootSuspended(root, lanes, NoLane);
30703 } else {
30704 // The render completed.
30705 // Check if this render may have yielded to a concurrent event, and if so,
30706 // confirm that any newly rendered stores are consistent.
30707 // TODO: It's possible that even a concurrent render may never have yielded
30708 // to the main thread, if it was fast enough, or if it expired. We could
30709 // skip the consistency check in that case, too.
30710 var finishedWork = root.current.alternate;
30711
30712 if (renderWasConcurrent && !isRenderConsistentWithExternalStores(finishedWork)) {
30713 // A store was mutated in an interleaved event. Render again,
30714 // synchronously, to block further mutations.
30715 exitStatus = renderRootSync(root, lanes); // We assume the tree is now consistent because we didn't yield to any
30716 // concurrent events.
30717
30718 renderWasConcurrent = false; // Need to check the exit status again.
30719
30720 continue;
30721 } // Check if something threw
30722
30723
30724 if (exitStatus === RootErrored) {
30725 var lanesThatJustErrored = lanes;
30726 var errorRetryLanes = getLanesToRetrySynchronouslyOnError(root, lanesThatJustErrored);
30727
30728 if (errorRetryLanes !== NoLanes) {
30729 lanes = errorRetryLanes;
30730 exitStatus = recoverFromConcurrentError(root, lanesThatJustErrored, errorRetryLanes);
30731 renderWasConcurrent = false; // Need to check the exit status again.
30732
30733 if (exitStatus !== RootErrored) {
30734 // The root did not error this time. Restart the exit algorithm
30735 // from the beginning.
30736 // TODO: Refactor the exit algorithm to be less confusing. Maybe
30737 // more branches + recursion instead of a loop. I think the only
30738 // thing that causes it to be a loop is the RootDidNotComplete
30739 // check. If that's true, then we don't need a loop/recursion
30740 // at all.
30741 continue;
30742 }
30743 }
30744 }
30745
30746 if (exitStatus === RootFatalErrored) {
30747 prepareFreshStack(root, NoLanes);
30748 markRootSuspended(root, lanes, NoLane);
30749 break;
30750 } // We now have a consistent tree. The next step is either to commit it,
30751 // or, if something suspended, wait to commit it after a timeout.
30752
30753
30754 root.finishedWork = finishedWork;
30755 root.finishedLanes = lanes;
30756 finishConcurrentRender(root, exitStatus, finishedWork, lanes);
30757 }
30758
30759 break;
30760 } while (true);
30761 }
30762
30763 ensureRootIsScheduled(root);
30764 return getContinuationForRoot(root, originalCallbackNode);
30765}
30766
30767function recoverFromConcurrentError(root, originallyAttemptedLanes, errorRetryLanes) {
30768 // If an error occurred during hydration, discard server response and fall
30769 // back to client side render.
30770 // Before rendering again, save the errors from the previous attempt.
30771 var errorsFromFirstAttempt = workInProgressRootConcurrentErrors;
30772 var wasRootDehydrated = isRootDehydrated(root);
30773
30774 if (wasRootDehydrated) {
30775 // The shell failed to hydrate. Set a flag to force a client rendering
30776 // during the next attempt. To do this, we call prepareFreshStack now
30777 // to create the root work-in-progress fiber. This is a bit weird in terms
30778 // of factoring, because it relies on renderRootSync not calling
30779 // prepareFreshStack again in the call below, which happens because the
30780 // root and lanes haven't changed.
30781 //
30782 // TODO: I think what we should do is set ForceClientRender inside
30783 // throwException, like we do for nested Suspense boundaries. The reason
30784 // it's here instead is so we can switch to the synchronous work loop, too.
30785 // Something to consider for a future refactor.
30786 var rootWorkInProgress = prepareFreshStack(root, errorRetryLanes);
30787 rootWorkInProgress.flags |= ForceClientRender;
30788 }
30789
30790 var exitStatus = renderRootSync(root, errorRetryLanes);
30791
30792 if (exitStatus !== RootErrored) {
30793 // Successfully finished rendering on retry
30794 if (workInProgressRootDidAttachPingListener && !wasRootDehydrated) {
30795 // During the synchronous render, we attached additional ping listeners.
30796 // This is highly suggestive of an uncached promise (though it's not the
30797 // only reason this would happen). If it was an uncached promise, then
30798 // it may have masked a downstream error from ocurring without actually
30799 // fixing it. Example:
30800 //
30801 // use(Promise.resolve('uncached'))
30802 // throw new Error('Oops!')
30803 //
30804 // When this happens, there's a conflict between blocking potential
30805 // concurrent data races and unwrapping uncached promise values. We
30806 // have to choose one or the other. Because the data race recovery is
30807 // a last ditch effort, we'll disable it.
30808 root.errorRecoveryDisabledLanes = mergeLanes(root.errorRecoveryDisabledLanes, originallyAttemptedLanes); // Mark the current render as suspended and force it to restart. Once
30809 // these lanes finish successfully, we'll re-enable the error recovery
30810 // mechanism for subsequent updates.
30811
30812 workInProgressRootInterleavedUpdatedLanes |= originallyAttemptedLanes;
30813 return RootSuspendedWithDelay;
30814 } // The errors from the failed first attempt have been recovered. Add
30815 // them to the collection of recoverable errors. We'll log them in the
30816 // commit phase.
30817
30818
30819 var errorsFromSecondAttempt = workInProgressRootRecoverableErrors;
30820 workInProgressRootRecoverableErrors = errorsFromFirstAttempt; // The errors from the second attempt should be queued after the errors
30821 // from the first attempt, to preserve the causal sequence.
30822
30823 if (errorsFromSecondAttempt !== null) {
30824 queueRecoverableErrors(errorsFromSecondAttempt);
30825 }
30826 }
30827
30828 return exitStatus;
30829}
30830
30831function queueRecoverableErrors(errors) {
30832 if (workInProgressRootRecoverableErrors === null) {
30833 workInProgressRootRecoverableErrors = errors;
30834 } else {
30835 // $FlowFixMe[method-unbinding]
30836 workInProgressRootRecoverableErrors.push.apply(workInProgressRootRecoverableErrors, errors);
30837 }
30838}
30839
30840function finishConcurrentRender(root, exitStatus, finishedWork, lanes) {
30841 // TODO: The fact that most of these branches are identical suggests that some
30842 // of the exit statuses are not best modeled as exit statuses and should be
30843 // tracked orthogonally.
30844 switch (exitStatus) {
30845 case RootInProgress:
30846 case RootFatalErrored:
30847 {
30848 throw new Error('Root did not complete. This is a bug in React.');
30849 }
30850
30851 case RootSuspendedWithDelay:
30852 {
30853 if (includesOnlyTransitions(lanes)) {
30854 // This is a transition, so we should exit without committing a
30855 // placeholder and without scheduling a timeout. Delay indefinitely
30856 // until we receive more data.
30857 markRootSuspended(root, lanes, workInProgressDeferredLane);
30858 return;
30859 } // Commit the placeholder.
30860
30861
30862 break;
30863 }
30864
30865 case RootErrored:
30866 {
30867 // This render errored. Ignore any recoverable errors because we weren't actually
30868 // able to recover. Instead, whatever the final errors were is the ones we log.
30869 // This ensures that we only log the actual client side error if it's just a plain
30870 // error thrown from a component on the server and the client.
30871 workInProgressRootRecoverableErrors = null;
30872 break;
30873 }
30874
30875 case RootSuspended:
30876 case RootCompleted:
30877 {
30878 break;
30879 }
30880
30881 default:
30882 {
30883 throw new Error('Unknown root exit status.');
30884 }
30885 }
30886
30887 if (shouldForceFlushFallbacksInDEV()) {
30888 // We're inside an `act` scope. Commit immediately.
30889 commitRoot(root, workInProgressRootRecoverableErrors, workInProgressTransitions, workInProgressRootDidIncludeRecursiveRenderUpdate, workInProgressDeferredLane);
30890 } else {
30891 if (includesOnlyRetries(lanes) && (alwaysThrottleRetries )) {
30892 // This render only included retries, no updates. Throttle committing
30893 // retries so that we don't show too many loading states too quickly.
30894 var msUntilTimeout = globalMostRecentFallbackTime + FALLBACK_THROTTLE_MS - now$1(); // Don't bother with a very short suspense time.
30895
30896 if (msUntilTimeout > 10) {
30897 markRootSuspended(root, lanes, workInProgressDeferredLane);
30898 var nextLanes = getNextLanes(root, NoLanes);
30899
30900 if (nextLanes !== NoLanes) {
30901 // There's additional work we can do on this root. We might as well
30902 // attempt to work on that while we're suspended.
30903 return;
30904 } // The render is suspended, it hasn't timed out, and there's no
30905 // lower priority work to do. Instead of committing the fallback
30906 // immediately, wait for more data to arrive.
30907 // TODO: Combine retry throttling with Suspensey commits. Right now they
30908 // run one after the other.
30909
30910
30911 root.timeoutHandle = scheduleTimeout(commitRootWhenReady.bind(null, root, finishedWork, workInProgressRootRecoverableErrors, workInProgressTransitions, workInProgressRootDidIncludeRecursiveRenderUpdate, lanes, workInProgressDeferredLane), msUntilTimeout);
30912 return;
30913 }
30914 }
30915
30916 commitRootWhenReady(root, finishedWork, workInProgressRootRecoverableErrors, workInProgressTransitions, workInProgressRootDidIncludeRecursiveRenderUpdate, lanes, workInProgressDeferredLane);
30917 }
30918}
30919
30920function commitRootWhenReady(root, finishedWork, recoverableErrors, transitions, didIncludeRenderPhaseUpdate, lanes, spawnedLane) {
30921 // TODO: Combine retry throttling with Suspensey commits. Right now they run
30922 // one after the other.
30923 if (includesOnlyNonUrgentLanes(lanes)) {
30924 // Before committing, ask the renderer whether the host tree is ready.
30925 // If it's not, we'll wait until it notifies us.
30926 startSuspendingCommit(); // This will walk the completed fiber tree and attach listeners to all
30927 // the suspensey resources. The renderer is responsible for accumulating
30928 // all the load events. This all happens in a single synchronous
30929 // transaction, so it track state in its own module scope.
30930
30931 accumulateSuspenseyCommit(finishedWork); // At the end, ask the renderer if it's ready to commit, or if we should
30932 // suspend. If it's not ready, it will return a callback to subscribe to
30933 // a ready event.
30934
30935 var schedulePendingCommit = waitForCommitToBeReady();
30936
30937 if (schedulePendingCommit !== null) {
30938 // NOTE: waitForCommitToBeReady returns a subscribe function so that we
30939 // only allocate a function if the commit isn't ready yet. The other
30940 // pattern would be to always pass a callback to waitForCommitToBeReady.
30941 // Not yet ready to commit. Delay the commit until the renderer notifies
30942 // us that it's ready. This will be canceled if we start work on the
30943 // root again.
30944 root.cancelPendingCommit = schedulePendingCommit(commitRoot.bind(null, root, recoverableErrors, transitions, didIncludeRenderPhaseUpdate));
30945 markRootSuspended(root, lanes, spawnedLane);
30946 return;
30947 }
30948 } // Otherwise, commit immediately.
30949
30950
30951 commitRoot(root, recoverableErrors, transitions, didIncludeRenderPhaseUpdate, spawnedLane);
30952}
30953
30954function isRenderConsistentWithExternalStores(finishedWork) {
30955 // Search the rendered tree for external store reads, and check whether the
30956 // stores were mutated in a concurrent event. Intentionally using an iterative
30957 // loop instead of recursion so we can exit early.
30958 var node = finishedWork;
30959
30960 while (true) {
30961 if (node.flags & StoreConsistency) {
30962 var updateQueue = node.updateQueue;
30963
30964 if (updateQueue !== null) {
30965 var checks = updateQueue.stores;
30966
30967 if (checks !== null) {
30968 for (var i = 0; i < checks.length; i++) {
30969 var check = checks[i];
30970 var getSnapshot = check.getSnapshot;
30971 var renderedValue = check.value;
30972
30973 try {
30974 if (!objectIs(getSnapshot(), renderedValue)) {
30975 // Found an inconsistent store.
30976 return false;
30977 }
30978 } catch (error) {
30979 // If `getSnapshot` throws, return `false`. This will schedule
30980 // a re-render, and the error will be rethrown during render.
30981 return false;
30982 }
30983 }
30984 }
30985 }
30986 }
30987
30988 var child = node.child;
30989
30990 if (node.subtreeFlags & StoreConsistency && child !== null) {
30991 child.return = node;
30992 node = child;
30993 continue;
30994 }
30995
30996 if (node === finishedWork) {
30997 return true;
30998 }
30999
31000 while (node.sibling === null) {
31001 if (node.return === null || node.return === finishedWork) {
31002 return true;
31003 }
31004
31005 node = node.return;
31006 }
31007
31008 node.sibling.return = node.return;
31009 node = node.sibling;
31010 } // Flow doesn't know this is unreachable, but eslint does
31011 // eslint-disable-next-line no-unreachable
31012
31013
31014 return true;
31015} // The extra indirections around markRootUpdated and markRootSuspended is
31016// needed to avoid a circular dependency between this module and
31017// ReactFiberLane. There's probably a better way to split up these modules and
31018// avoid this problem. Perhaps all the root-marking functions should move into
31019// the work loop.
31020
31021
31022function markRootUpdated(root, updatedLanes) {
31023 markRootUpdated$1(root, updatedLanes);
31024
31025 {
31026 // Check for recursive updates
31027 if (executionContext & RenderContext) {
31028 workInProgressRootDidIncludeRecursiveRenderUpdate = true;
31029 } else if (executionContext & CommitContext) {
31030 didIncludeCommitPhaseUpdate = true;
31031 }
31032
31033 throwIfInfiniteUpdateLoopDetected();
31034 }
31035}
31036
31037function markRootPinged(root, pingedLanes) {
31038 markRootPinged$1(root, pingedLanes);
31039
31040 {
31041 // Check for recursive pings. Pings are conceptually different from updates in
31042 // other contexts but we call it an "update" in this context because
31043 // repeatedly pinging a suspended render can cause a recursive render loop.
31044 // The relevant property is that it can result in a new render attempt
31045 // being scheduled.
31046 if (executionContext & RenderContext) {
31047 workInProgressRootDidIncludeRecursiveRenderUpdate = true;
31048 } else if (executionContext & CommitContext) {
31049 didIncludeCommitPhaseUpdate = true;
31050 }
31051
31052 throwIfInfiniteUpdateLoopDetected();
31053 }
31054}
31055
31056function markRootSuspended(root, suspendedLanes, spawnedLane) {
31057 // When suspending, we should always exclude lanes that were pinged or (more
31058 // rarely, since we try to avoid it) updated during the render phase.
31059 suspendedLanes = removeLanes(suspendedLanes, workInProgressRootPingedLanes);
31060 suspendedLanes = removeLanes(suspendedLanes, workInProgressRootInterleavedUpdatedLanes);
31061
31062 markRootSuspended$1(root, suspendedLanes, spawnedLane);
31063} // This is the entry point for synchronous tasks that don't go
31064// through Scheduler
31065
31066
31067function performSyncWorkOnRoot(root, lanes) {
31068 if ((executionContext & (RenderContext | CommitContext)) !== NoContext) {
31069 throw new Error('Should not already be working.');
31070 }
31071
31072 var didFlushPassiveEffects = flushPassiveEffects();
31073
31074 if (didFlushPassiveEffects) {
31075 // If passive effects were flushed, exit to the outer work loop in the root
31076 // scheduler, so we can recompute the priority.
31077 // TODO: We don't actually need this `ensureRootIsScheduled` call because
31078 // this path is only reachable if the root is already part of the schedule.
31079 // I'm including it only for consistency with the other exit points from
31080 // this function. Can address in a subsequent refactor.
31081 ensureRootIsScheduled(root);
31082 return null;
31083 }
31084
31085 {
31086 syncNestedUpdateFlag();
31087 }
31088
31089 var exitStatus = renderRootSync(root, lanes);
31090
31091 if (exitStatus === RootErrored) {
31092 // If something threw an error, try rendering one more time. We'll render
31093 // synchronously to block concurrent data mutations, and we'll includes
31094 // all pending updates are included. If it still fails after the second
31095 // attempt, we'll give up and commit the resulting tree.
31096 var originallyAttemptedLanes = lanes;
31097 var errorRetryLanes = getLanesToRetrySynchronouslyOnError(root, originallyAttemptedLanes);
31098
31099 if (errorRetryLanes !== NoLanes) {
31100 lanes = errorRetryLanes;
31101 exitStatus = recoverFromConcurrentError(root, originallyAttemptedLanes, errorRetryLanes);
31102 }
31103 }
31104
31105 if (exitStatus === RootFatalErrored) {
31106 prepareFreshStack(root, NoLanes);
31107 markRootSuspended(root, lanes, NoLane);
31108 ensureRootIsScheduled(root);
31109 return null;
31110 }
31111
31112 if (exitStatus === RootDidNotComplete) {
31113 // The render unwound without completing the tree. This happens in special
31114 // cases where need to exit the current render without producing a
31115 // consistent tree or committing.
31116 markRootSuspended(root, lanes, workInProgressDeferredLane);
31117 ensureRootIsScheduled(root);
31118 return null;
31119 } // We now have a consistent tree. Because this is a sync render, we
31120 // will commit it even if something suspended.
31121
31122
31123 var finishedWork = root.current.alternate;
31124 root.finishedWork = finishedWork;
31125 root.finishedLanes = lanes;
31126 commitRoot(root, workInProgressRootRecoverableErrors, workInProgressTransitions, workInProgressRootDidIncludeRecursiveRenderUpdate, workInProgressDeferredLane); // Before exiting, make sure there's a callback scheduled for the next
31127 // pending level.
31128
31129 ensureRootIsScheduled(root);
31130 return null;
31131}
31132function flushRoot(root, lanes) {
31133 if (lanes !== NoLanes) {
31134 upgradePendingLanesToSync(root, lanes);
31135 ensureRootIsScheduled(root);
31136
31137 if ((executionContext & (RenderContext | CommitContext)) === NoContext) {
31138 resetRenderTimer(); // TODO: For historical reasons this flushes all sync work across all
31139 // roots. It shouldn't really matter either way, but we could change this
31140 // to only flush the given root.
31141
31142 flushSyncWorkOnAllRoots();
31143 }
31144 }
31145}
31146function getExecutionContext() {
31147 return executionContext;
31148}
31149function batchedUpdates(fn, a) {
31150 {
31151 // batchedUpdates is a no-op now, but there's still some internal react-dom
31152 // code calling it, that we can't remove until we remove legacy mode.
31153 return fn(a);
31154 }
31155}
31156// Returns whether the the call was during a render or not
31157
31158function flushSyncWork$1() {
31159 if ((executionContext & (RenderContext | CommitContext)) === NoContext) {
31160 flushSyncWorkOnAllRoots();
31161 return false;
31162 }
31163
31164 return true;
31165}
31166function isAlreadyRendering() {
31167 // Used by the renderer to print a warning if certain APIs are called from
31168 // the wrong context.
31169 return (executionContext & (RenderContext | CommitContext)) !== NoContext;
31170}
31171// hidden subtree. The stack logic is managed there because that's the only
31172// place that ever modifies it. Which module it lives in doesn't matter for
31173// performance because this function will get inlined regardless
31174
31175function setEntangledRenderLanes(newEntangledRenderLanes) {
31176 entangledRenderLanes = newEntangledRenderLanes;
31177}
31178function getEntangledRenderLanes() {
31179 return entangledRenderLanes;
31180}
31181
31182function resetWorkInProgressStack() {
31183 if (workInProgress === null) return;
31184 var interruptedWork;
31185
31186 if (workInProgressSuspendedReason === NotSuspended) {
31187 // Normal case. Work-in-progress hasn't started yet. Unwind all
31188 // its parents.
31189 interruptedWork = workInProgress.return;
31190 } else {
31191 // Work-in-progress is in suspended state. Reset the work loop and unwind
31192 // both the suspended fiber and all its parents.
31193 resetSuspendedWorkLoopOnUnwind(workInProgress);
31194 interruptedWork = workInProgress;
31195 }
31196
31197 while (interruptedWork !== null) {
31198 var current = interruptedWork.alternate;
31199 unwindInterruptedWork(current, interruptedWork);
31200 interruptedWork = interruptedWork.return;
31201 }
31202
31203 workInProgress = null;
31204}
31205
31206function prepareFreshStack(root, lanes) {
31207 root.finishedWork = null;
31208 root.finishedLanes = NoLanes;
31209 var timeoutHandle = root.timeoutHandle;
31210
31211 if (timeoutHandle !== noTimeout) {
31212 // The root previous suspended and scheduled a timeout to commit a fallback
31213 // state. Now that we have additional work, cancel the timeout.
31214 root.timeoutHandle = noTimeout; // $FlowFixMe[incompatible-call] Complains noTimeout is not a TimeoutID, despite the check above
31215
31216 cancelTimeout(timeoutHandle);
31217 }
31218
31219 var cancelPendingCommit = root.cancelPendingCommit;
31220
31221 if (cancelPendingCommit !== null) {
31222 root.cancelPendingCommit = null;
31223 cancelPendingCommit();
31224 }
31225
31226 resetWorkInProgressStack();
31227 workInProgressRoot = root;
31228 var rootWorkInProgress = createWorkInProgress(root.current, null);
31229 workInProgress = rootWorkInProgress;
31230 workInProgressRootRenderLanes = lanes;
31231 workInProgressSuspendedReason = NotSuspended;
31232 workInProgressThrownValue = null;
31233 workInProgressRootDidAttachPingListener = false;
31234 workInProgressRootExitStatus = RootInProgress;
31235 workInProgressRootSkippedLanes = NoLanes;
31236 workInProgressRootInterleavedUpdatedLanes = NoLanes;
31237 workInProgressRootPingedLanes = NoLanes;
31238 workInProgressDeferredLane = NoLane;
31239 workInProgressRootConcurrentErrors = null;
31240 workInProgressRootRecoverableErrors = null;
31241 workInProgressRootDidIncludeRecursiveRenderUpdate = false; // Get the lanes that are entangled with whatever we're about to render. We
31242 // track these separately so we can distinguish the priority of the render
31243 // task from the priority of the lanes it is entangled with. For example, a
31244 // transition may not be allowed to finish unless it includes the Sync lane,
31245 // which is currently suspended. We should be able to render the Transition
31246 // and Sync lane in the same batch, but at Transition priority, because the
31247 // Sync lane already suspended.
31248
31249 entangledRenderLanes = getEntangledLanes(root, lanes);
31250 finishQueueingConcurrentUpdates();
31251
31252 {
31253 ReactStrictModeWarnings.discardPendingWarnings();
31254 }
31255
31256 return rootWorkInProgress;
31257}
31258
31259function resetSuspendedWorkLoopOnUnwind(fiber) {
31260 // Reset module-level state that was set during the render phase.
31261 resetContextDependencies();
31262 resetHooksOnUnwind(fiber);
31263 resetChildReconcilerOnUnwind();
31264}
31265
31266function handleThrow(root, thrownValue) {
31267 // A component threw an exception. Usually this is because it suspended, but
31268 // it also includes regular program errors.
31269 //
31270 // We're either going to unwind the stack to show a Suspense or error
31271 // boundary, or we're going to replay the component again. Like after a
31272 // promise resolves.
31273 //
31274 // Until we decide whether we're going to unwind or replay, we should preserve
31275 // the current state of the work loop without resetting anything.
31276 //
31277 // If we do decide to unwind the stack, module-level variables will be reset
31278 // in resetSuspendedWorkLoopOnUnwind.
31279 // These should be reset immediately because they're only supposed to be set
31280 // when React is executing user code.
31281 resetHooksAfterThrow();
31282 resetCurrentFiber();
31283
31284 {
31285 setCurrentOwner(null);
31286 }
31287
31288 if (thrownValue === SuspenseException) {
31289 // This is a special type of exception used for Suspense. For historical
31290 // reasons, the rest of the Suspense implementation expects the thrown value
31291 // to be a thenable, because before `use` existed that was the (unstable)
31292 // API for suspending. This implementation detail can change later, once we
31293 // deprecate the old API in favor of `use`.
31294 thrownValue = getSuspendedThenable();
31295 workInProgressSuspendedReason = shouldRemainOnPreviousScreen() && // Check if there are other pending updates that might possibly unblock this
31296 // component from suspending. This mirrors the check in
31297 // renderDidSuspendDelayIfPossible. We should attempt to unify them somehow.
31298 // TODO: Consider unwinding immediately, using the
31299 // SuspendedOnHydration mechanism.
31300 !includesNonIdleWork(workInProgressRootSkippedLanes) && !includesNonIdleWork(workInProgressRootInterleavedUpdatedLanes) ? // Suspend work loop until data resolves
31301 SuspendedOnData : // Don't suspend work loop, except to check if the data has
31302 // immediately resolved (i.e. in a microtask). Otherwise, trigger the
31303 // nearest Suspense fallback.
31304 SuspendedOnImmediate;
31305 } else if (thrownValue === SuspenseyCommitException) {
31306 thrownValue = getSuspendedThenable();
31307 workInProgressSuspendedReason = SuspendedOnInstance;
31308 } else if (thrownValue === SelectiveHydrationException) {
31309 // An update flowed into a dehydrated boundary. Before we can apply the
31310 // update, we need to finish hydrating. Interrupt the work-in-progress
31311 // render so we can restart at the hydration lane.
31312 //
31313 // The ideal implementation would be able to switch contexts without
31314 // unwinding the current stack.
31315 //
31316 // We could name this something more general but as of now it's the only
31317 // case where we think this should happen.
31318 workInProgressSuspendedReason = SuspendedOnHydration;
31319 } else {
31320 // This is a regular error.
31321 var isWakeable = thrownValue !== null && typeof thrownValue === 'object' && typeof thrownValue.then === 'function';
31322 workInProgressSuspendedReason = isWakeable ? // A wakeable object was thrown by a legacy Suspense implementation.
31323 // This has slightly different behavior than suspending with `use`.
31324 SuspendedOnDeprecatedThrowPromise : // This is a regular error. If something earlier in the component already
31325 // suspended, we must clear the thenable state to unblock the work loop.
31326 SuspendedOnError;
31327 }
31328
31329 workInProgressThrownValue = thrownValue;
31330 var erroredWork = workInProgress;
31331
31332 if (erroredWork === null) {
31333 // This is a fatal error
31334 workInProgressRootExitStatus = RootFatalErrored;
31335 logUncaughtError(root, createCapturedValueAtFiber(thrownValue, root.current));
31336 return;
31337 }
31338
31339 if (erroredWork.mode & ProfileMode) {
31340 // Record the time spent rendering before an error was thrown. This
31341 // avoids inaccurate Profiler durations in the case of a
31342 // suspended render.
31343 stopProfilerTimerIfRunningAndRecordDelta(erroredWork, true);
31344 }
31345
31346 {
31347 markComponentRenderStopped();
31348
31349 switch (workInProgressSuspendedReason) {
31350 case SuspendedOnError:
31351 {
31352 markComponentErrored(erroredWork, thrownValue, workInProgressRootRenderLanes);
31353 break;
31354 }
31355
31356 case SuspendedOnData:
31357 case SuspendedOnImmediate:
31358 case SuspendedOnDeprecatedThrowPromise:
31359 case SuspendedAndReadyToContinue:
31360 {
31361 var wakeable = thrownValue;
31362 markComponentSuspended(erroredWork, wakeable, workInProgressRootRenderLanes);
31363 break;
31364 }
31365 }
31366 }
31367}
31368
31369function shouldRemainOnPreviousScreen() {
31370 // This is asking whether it's better to suspend the transition and remain
31371 // on the previous screen, versus showing a fallback as soon as possible. It
31372 // takes into account both the priority of render and also whether showing a
31373 // fallback would produce a desirable user experience.
31374 var handler = getSuspenseHandler();
31375
31376 if (handler === null) {
31377 // There's no Suspense boundary that can provide a fallback. We have no
31378 // choice but to remain on the previous screen.
31379 // NOTE: We do this even for sync updates, for lack of any better option. In
31380 // the future, we may change how we handle this, like by putting the whole
31381 // root into a "detached" mode.
31382 return true;
31383 } // TODO: Once `use` has fully replaced the `throw promise` pattern, we should
31384 // be able to remove the equivalent check in finishConcurrentRender, and rely
31385 // just on this one.
31386
31387
31388 if (includesOnlyTransitions(workInProgressRootRenderLanes)) {
31389 if (getShellBoundary() === null) {
31390 // We're rendering inside the "shell" of the app. Activating the nearest
31391 // fallback would cause visible content to disappear. It's better to
31392 // suspend the transition and remain on the previous screen.
31393 return true;
31394 } else {
31395 // We're rendering content that wasn't part of the previous screen.
31396 // Rather than block the transition, it's better to show a fallback as
31397 // soon as possible. The appearance of any nested fallbacks will be
31398 // throttled to avoid jank.
31399 return false;
31400 }
31401 }
31402
31403 if (includesOnlyRetries(workInProgressRootRenderLanes) || // In this context, an OffscreenLane counts as a Retry
31404 // TODO: It's become increasingly clear that Retries and Offscreen are
31405 // deeply connected. They probably can be unified further.
31406 includesSomeLane(workInProgressRootRenderLanes, OffscreenLane)) {
31407 // During a retry, we can suspend rendering if the nearest Suspense boundary
31408 // is the boundary of the "shell", because we're guaranteed not to block
31409 // any new content from appearing.
31410 //
31411 // The reason we must check if this is a retry is because it guarantees
31412 // that suspending the work loop won't block an actual update, because
31413 // retries don't "update" anything; they fill in fallbacks that were left
31414 // behind by a previous transition.
31415 return handler === getShellBoundary();
31416 } // For all other Lanes besides Transitions and Retries, we should not wait
31417 // for the data to load.
31418
31419
31420 return false;
31421}
31422
31423function pushDispatcher(container) {
31424 var prevDispatcher = ReactSharedInternals.H;
31425 ReactSharedInternals.H = ContextOnlyDispatcher;
31426
31427 if (prevDispatcher === null) {
31428 // The React isomorphic package does not include a default dispatcher.
31429 // Instead the first renderer will lazily attach one, in order to give
31430 // nicer error messages.
31431 return ContextOnlyDispatcher;
31432 } else {
31433 return prevDispatcher;
31434 }
31435}
31436
31437function popDispatcher(prevDispatcher) {
31438 ReactSharedInternals.H = prevDispatcher;
31439}
31440
31441function pushAsyncDispatcher() {
31442 {
31443 var prevAsyncDispatcher = ReactSharedInternals.A;
31444 ReactSharedInternals.A = DefaultAsyncDispatcher;
31445 return prevAsyncDispatcher;
31446 }
31447}
31448
31449function popAsyncDispatcher(prevAsyncDispatcher) {
31450 {
31451 ReactSharedInternals.A = prevAsyncDispatcher;
31452 }
31453}
31454
31455function markCommitTimeOfFallback() {
31456 globalMostRecentFallbackTime = now$1();
31457}
31458function markSkippedUpdateLanes(lane) {
31459 workInProgressRootSkippedLanes = mergeLanes(lane, workInProgressRootSkippedLanes);
31460}
31461function renderDidSuspend() {
31462 if (workInProgressRootExitStatus === RootInProgress) {
31463 workInProgressRootExitStatus = RootSuspended;
31464 }
31465}
31466function renderDidSuspendDelayIfPossible() {
31467 workInProgressRootExitStatus = RootSuspendedWithDelay; // Check if there are updates that we skipped tree that might have unblocked
31468 // this render.
31469
31470 if ((includesNonIdleWork(workInProgressRootSkippedLanes) || includesNonIdleWork(workInProgressRootInterleavedUpdatedLanes)) && workInProgressRoot !== null) {
31471 // Mark the current render as suspended so that we switch to working on
31472 // the updates that were skipped. Usually we only suspend at the end of
31473 // the render phase.
31474 // TODO: We should probably always mark the root as suspended immediately
31475 // (inside this function), since by suspending at the end of the render
31476 // phase introduces a potential mistake where we suspend lanes that were
31477 // pinged or updated while we were rendering.
31478 // TODO: Consider unwinding immediately, using the
31479 // SuspendedOnHydration mechanism.
31480 markRootSuspended(workInProgressRoot, workInProgressRootRenderLanes, workInProgressDeferredLane);
31481 }
31482}
31483function renderDidError() {
31484 if (workInProgressRootExitStatus !== RootSuspendedWithDelay) {
31485 workInProgressRootExitStatus = RootErrored;
31486 }
31487}
31488function queueConcurrentError(error) {
31489 if (workInProgressRootConcurrentErrors === null) {
31490 workInProgressRootConcurrentErrors = [error];
31491 } else {
31492 workInProgressRootConcurrentErrors.push(error);
31493 }
31494} // Called during render to determine if anything has suspended.
31495// Returns false if we're not sure.
31496
31497function renderHasNotSuspendedYet() {
31498 // If something errored or completed, we can't really be sure,
31499 // so those are false.
31500 return workInProgressRootExitStatus === RootInProgress;
31501} // TODO: Over time, this function and renderRootConcurrent have become more
31502// and more similar. Not sure it makes sense to maintain forked paths. Consider
31503// unifying them again.
31504
31505function renderRootSync(root, lanes) {
31506 var prevExecutionContext = executionContext;
31507 executionContext |= RenderContext;
31508 var prevDispatcher = pushDispatcher();
31509 var prevAsyncDispatcher = pushAsyncDispatcher(); // If the root or lanes have changed, throw out the existing stack
31510 // and prepare a fresh one. Otherwise we'll continue where we left off.
31511
31512 if (workInProgressRoot !== root || workInProgressRootRenderLanes !== lanes) {
31513 {
31514 if (isDevToolsPresent) {
31515 var memoizedUpdaters = root.memoizedUpdaters;
31516
31517 if (memoizedUpdaters.size > 0) {
31518 restorePendingUpdaters(root, workInProgressRootRenderLanes);
31519 memoizedUpdaters.clear();
31520 } // At this point, move Fibers that scheduled the upcoming work from the Map to the Set.
31521 // If we bailout on this work, we'll move them back (like above).
31522 // It's important to move them now in case the work spawns more work at the same priority with different updaters.
31523 // That way we can keep the current update and future updates separate.
31524
31525
31526 movePendingFibersToMemoized(root, lanes);
31527 }
31528 }
31529
31530 workInProgressTransitions = getTransitionsForLanes();
31531 prepareFreshStack(root, lanes);
31532 }
31533
31534 {
31535 markRenderStarted(lanes);
31536 }
31537
31538 var didSuspendInShell = false;
31539
31540 outer: do {
31541 try {
31542 if (workInProgressSuspendedReason !== NotSuspended && workInProgress !== null) {
31543 // The work loop is suspended. During a synchronous render, we don't
31544 // yield to the main thread. Immediately unwind the stack. This will
31545 // trigger either a fallback or an error boundary.
31546 // TODO: For discrete and "default" updates (anything that's not
31547 // flushSync), we want to wait for the microtasks the flush before
31548 // unwinding. Will probably implement this using renderRootConcurrent,
31549 // or merge renderRootSync and renderRootConcurrent into the same
31550 // function and fork the behavior some other way.
31551 var unitOfWork = workInProgress;
31552 var thrownValue = workInProgressThrownValue;
31553
31554 switch (workInProgressSuspendedReason) {
31555 case SuspendedOnHydration:
31556 {
31557 // Selective hydration. An update flowed into a dehydrated tree.
31558 // Interrupt the current render so the work loop can switch to the
31559 // hydration lane.
31560 resetWorkInProgressStack();
31561 workInProgressRootExitStatus = RootDidNotComplete;
31562 break outer;
31563 }
31564
31565 case SuspendedOnImmediate:
31566 case SuspendedOnData:
31567 {
31568 if (!didSuspendInShell && getSuspenseHandler() === null) {
31569 didSuspendInShell = true;
31570 } // Intentional fallthrough
31571
31572 }
31573
31574 default:
31575 {
31576 // Unwind then continue with the normal work loop.
31577 workInProgressSuspendedReason = NotSuspended;
31578 workInProgressThrownValue = null;
31579 throwAndUnwindWorkLoop(root, unitOfWork, thrownValue);
31580 break;
31581 }
31582 }
31583 }
31584
31585 workLoopSync();
31586 break;
31587 } catch (thrownValue) {
31588 handleThrow(root, thrownValue);
31589 }
31590 } while (true); // Check if something suspended in the shell. We use this to detect an
31591 // infinite ping loop caused by an uncached promise.
31592 //
31593 // Only increment this counter once per synchronous render attempt across the
31594 // whole tree. Even if there are many sibling components that suspend, this
31595 // counter only gets incremented once.
31596
31597
31598 if (didSuspendInShell) {
31599 root.shellSuspendCounter++;
31600 }
31601
31602 resetContextDependencies();
31603 executionContext = prevExecutionContext;
31604 popDispatcher(prevDispatcher);
31605 popAsyncDispatcher(prevAsyncDispatcher);
31606
31607 if (workInProgress !== null) {
31608 // This is a sync render, so we should have finished the whole tree.
31609 throw new Error('Cannot commit an incomplete root. This error is likely caused by a ' + 'bug in React. Please file an issue.');
31610 }
31611
31612 {
31613 markRenderStopped();
31614 } // Set this to null to indicate there's no in-progress render.
31615
31616
31617 workInProgressRoot = null;
31618 workInProgressRootRenderLanes = NoLanes; // It's safe to process the queue now that the render phase is complete.
31619
31620 finishQueueingConcurrentUpdates();
31621 return workInProgressRootExitStatus;
31622} // The work loop is an extremely hot path. Tell Closure not to inline it.
31623
31624/** @noinline */
31625
31626
31627function workLoopSync() {
31628 // Perform work without checking if we need to yield between fiber.
31629 while (workInProgress !== null) {
31630 performUnitOfWork(workInProgress);
31631 }
31632}
31633
31634function renderRootConcurrent(root, lanes) {
31635 var prevExecutionContext = executionContext;
31636 executionContext |= RenderContext;
31637 var prevDispatcher = pushDispatcher();
31638 var prevAsyncDispatcher = pushAsyncDispatcher(); // If the root or lanes have changed, throw out the existing stack
31639 // and prepare a fresh one. Otherwise we'll continue where we left off.
31640
31641 if (workInProgressRoot !== root || workInProgressRootRenderLanes !== lanes) {
31642 {
31643 if (isDevToolsPresent) {
31644 var memoizedUpdaters = root.memoizedUpdaters;
31645
31646 if (memoizedUpdaters.size > 0) {
31647 restorePendingUpdaters(root, workInProgressRootRenderLanes);
31648 memoizedUpdaters.clear();
31649 } // At this point, move Fibers that scheduled the upcoming work from the Map to the Set.
31650 // If we bailout on this work, we'll move them back (like above).
31651 // It's important to move them now in case the work spawns more work at the same priority with different updaters.
31652 // That way we can keep the current update and future updates separate.
31653
31654
31655 movePendingFibersToMemoized(root, lanes);
31656 }
31657 }
31658
31659 workInProgressTransitions = getTransitionsForLanes();
31660 resetRenderTimer();
31661 prepareFreshStack(root, lanes);
31662 }
31663
31664 {
31665 markRenderStarted(lanes);
31666 }
31667
31668 outer: do {
31669 try {
31670 if (workInProgressSuspendedReason !== NotSuspended && workInProgress !== null) {
31671 // The work loop is suspended. We need to either unwind the stack or
31672 // replay the suspended component.
31673 var unitOfWork = workInProgress;
31674 var thrownValue = workInProgressThrownValue;
31675
31676 resumeOrUnwind: switch (workInProgressSuspendedReason) {
31677 case SuspendedOnError:
31678 {
31679 // Unwind then continue with the normal work loop.
31680 workInProgressSuspendedReason = NotSuspended;
31681 workInProgressThrownValue = null;
31682 throwAndUnwindWorkLoop(root, unitOfWork, thrownValue);
31683 break;
31684 }
31685
31686 case SuspendedOnData:
31687 {
31688 var thenable = thrownValue;
31689
31690 if (isThenableResolved(thenable)) {
31691 // The data resolved. Try rendering the component again.
31692 workInProgressSuspendedReason = NotSuspended;
31693 workInProgressThrownValue = null;
31694 replaySuspendedUnitOfWork(unitOfWork);
31695 break;
31696 } // The work loop is suspended on data. We should wait for it to
31697 // resolve before continuing to render.
31698 // TODO: Handle the case where the promise resolves synchronously.
31699 // Usually this is handled when we instrument the promise to add a
31700 // `status` field, but if the promise already has a status, we won't
31701 // have added a listener until right here.
31702
31703
31704 var onResolution = function () {
31705 // Check if the root is still suspended on this promise.
31706 if (workInProgressSuspendedReason === SuspendedOnData && workInProgressRoot === root) {
31707 // Mark the root as ready to continue rendering.
31708 workInProgressSuspendedReason = SuspendedAndReadyToContinue;
31709 } // Ensure the root is scheduled. We should do this even if we're
31710 // currently working on a different root, so that we resume
31711 // rendering later.
31712
31713
31714 ensureRootIsScheduled(root);
31715 };
31716
31717 thenable.then(onResolution, onResolution);
31718 break outer;
31719 }
31720
31721 case SuspendedOnImmediate:
31722 {
31723 // If this fiber just suspended, it's possible the data is already
31724 // cached. Yield to the main thread to give it a chance to ping. If
31725 // it does, we can retry immediately without unwinding the stack.
31726 workInProgressSuspendedReason = SuspendedAndReadyToContinue;
31727 break outer;
31728 }
31729
31730 case SuspendedOnInstance:
31731 {
31732 workInProgressSuspendedReason = SuspendedOnInstanceAndReadyToContinue;
31733 break outer;
31734 }
31735
31736 case SuspendedAndReadyToContinue:
31737 {
31738 var _thenable = thrownValue;
31739
31740 if (isThenableResolved(_thenable)) {
31741 // The data resolved. Try rendering the component again.
31742 workInProgressSuspendedReason = NotSuspended;
31743 workInProgressThrownValue = null;
31744 replaySuspendedUnitOfWork(unitOfWork);
31745 } else {
31746 // Otherwise, unwind then continue with the normal work loop.
31747 workInProgressSuspendedReason = NotSuspended;
31748 workInProgressThrownValue = null;
31749 throwAndUnwindWorkLoop(root, unitOfWork, thrownValue);
31750 }
31751
31752 break;
31753 }
31754
31755 case SuspendedOnInstanceAndReadyToContinue:
31756 {
31757 switch (workInProgress.tag) {
31758 case HostComponent:
31759 case HostHoistable:
31760 case HostSingleton:
31761 {
31762 // Before unwinding the stack, check one more time if the
31763 // instance is ready. It may have loaded when React yielded to
31764 // the main thread.
31765 // Assigning this to a constant so Flow knows the binding won't
31766 // be mutated by `preloadInstance`.
31767 var hostFiber = workInProgress;
31768 var type = hostFiber.type;
31769 var props = hostFiber.pendingProps;
31770 var isReady = preloadInstance(type, props);
31771
31772 if (isReady) {
31773 // The data resolved. Resume the work loop as if nothing
31774 // suspended. Unlike when a user component suspends, we don't
31775 // have to replay anything because the host fiber
31776 // already completed.
31777 workInProgressSuspendedReason = NotSuspended;
31778 workInProgressThrownValue = null;
31779 var sibling = hostFiber.sibling;
31780
31781 if (sibling !== null) {
31782 workInProgress = sibling;
31783 } else {
31784 var returnFiber = hostFiber.return;
31785
31786 if (returnFiber !== null) {
31787 workInProgress = returnFiber;
31788 completeUnitOfWork(returnFiber);
31789 } else {
31790 workInProgress = null;
31791 }
31792 }
31793
31794 break resumeOrUnwind;
31795 }
31796
31797 break;
31798 }
31799
31800 default:
31801 {
31802 // This will fail gracefully but it's not correct, so log a
31803 // warning in dev.
31804 if (true) {
31805 error('Unexpected type of fiber triggered a suspensey commit. ' + 'This is a bug in React.');
31806 }
31807
31808 break;
31809 }
31810 } // Otherwise, unwind then continue with the normal work loop.
31811
31812
31813 workInProgressSuspendedReason = NotSuspended;
31814 workInProgressThrownValue = null;
31815 throwAndUnwindWorkLoop(root, unitOfWork, thrownValue);
31816 break;
31817 }
31818
31819 case SuspendedOnDeprecatedThrowPromise:
31820 {
31821 // Suspended by an old implementation that uses the `throw promise`
31822 // pattern. The newer replaying behavior can cause subtle issues
31823 // like infinite ping loops. So we maintain the old behavior and
31824 // always unwind.
31825 workInProgressSuspendedReason = NotSuspended;
31826 workInProgressThrownValue = null;
31827 throwAndUnwindWorkLoop(root, unitOfWork, thrownValue);
31828 break;
31829 }
31830
31831 case SuspendedOnHydration:
31832 {
31833 // Selective hydration. An update flowed into a dehydrated tree.
31834 // Interrupt the current render so the work loop can switch to the
31835 // hydration lane.
31836 resetWorkInProgressStack();
31837 workInProgressRootExitStatus = RootDidNotComplete;
31838 break outer;
31839 }
31840
31841 default:
31842 {
31843 throw new Error('Unexpected SuspendedReason. This is a bug in React.');
31844 }
31845 }
31846 }
31847
31848 if (true && ReactSharedInternals.actQueue !== null) {
31849 // `act` special case: If we're inside an `act` scope, don't consult
31850 // `shouldYield`. Always keep working until the render is complete.
31851 // This is not just an optimization: in a unit test environment, we
31852 // can't trust the result of `shouldYield`, because the host I/O is
31853 // likely mocked.
31854 workLoopSync();
31855 } else {
31856 workLoopConcurrent();
31857 }
31858
31859 break;
31860 } catch (thrownValue) {
31861 handleThrow(root, thrownValue);
31862 }
31863 } while (true);
31864
31865 resetContextDependencies();
31866 popDispatcher(prevDispatcher);
31867 popAsyncDispatcher(prevAsyncDispatcher);
31868 executionContext = prevExecutionContext;
31869
31870
31871 if (workInProgress !== null) {
31872 // Still work remaining.
31873 {
31874 markRenderYielded();
31875 }
31876
31877 return RootInProgress;
31878 } else {
31879 // Completed the tree.
31880 {
31881 markRenderStopped();
31882 } // Set this to null to indicate there's no in-progress render.
31883
31884
31885 workInProgressRoot = null;
31886 workInProgressRootRenderLanes = NoLanes; // It's safe to process the queue now that the render phase is complete.
31887
31888 finishQueueingConcurrentUpdates(); // Return the final exit status.
31889
31890 return workInProgressRootExitStatus;
31891 }
31892}
31893/** @noinline */
31894
31895
31896function workLoopConcurrent() {
31897 // Perform work until Scheduler asks us to yield
31898 while (workInProgress !== null && !shouldYield()) {
31899 // $FlowFixMe[incompatible-call] found when upgrading Flow
31900 performUnitOfWork(workInProgress);
31901 }
31902}
31903
31904function performUnitOfWork(unitOfWork) {
31905 // The current, flushed, state of this fiber is the alternate. Ideally
31906 // nothing should rely on this, but relying on it here means that we don't
31907 // need an additional field on the work in progress.
31908 var current = unitOfWork.alternate;
31909 setCurrentFiber(unitOfWork);
31910 var next;
31911
31912 if ((unitOfWork.mode & ProfileMode) !== NoMode) {
31913 startProfilerTimer(unitOfWork);
31914 next = beginWork(current, unitOfWork, entangledRenderLanes);
31915 stopProfilerTimerIfRunningAndRecordDelta(unitOfWork, true);
31916 } else {
31917 next = beginWork(current, unitOfWork, entangledRenderLanes);
31918 }
31919
31920 resetCurrentFiber();
31921 unitOfWork.memoizedProps = unitOfWork.pendingProps;
31922
31923 if (next === null) {
31924 // If this doesn't spawn new work, complete the current work.
31925 completeUnitOfWork(unitOfWork);
31926 } else {
31927 workInProgress = next;
31928 }
31929
31930 {
31931 setCurrentOwner(null);
31932 }
31933}
31934
31935function replaySuspendedUnitOfWork(unitOfWork) {
31936 // This is a fork of performUnitOfWork specifcally for replaying a fiber that
31937 // just suspended.
31938 //
31939 var current = unitOfWork.alternate;
31940 setCurrentFiber(unitOfWork);
31941 var next;
31942 setCurrentFiber(unitOfWork);
31943 var isProfilingMode = (unitOfWork.mode & ProfileMode) !== NoMode;
31944
31945 if (isProfilingMode) {
31946 startProfilerTimer(unitOfWork);
31947 }
31948
31949 switch (unitOfWork.tag) {
31950 case SimpleMemoComponent:
31951 case FunctionComponent:
31952 {
31953 // Resolve `defaultProps`. This logic is copied from `beginWork`.
31954 // TODO: Consider moving this switch statement into that module. Also,
31955 // could maybe use this as an opportunity to say `use` doesn't work with
31956 // `defaultProps` :)
31957 var Component = unitOfWork.type;
31958 var unresolvedProps = unitOfWork.pendingProps;
31959 var resolvedProps = unresolvedProps ;
31960 var context;
31961
31962 next = replayFunctionComponent(current, unitOfWork, resolvedProps, Component, context, workInProgressRootRenderLanes);
31963 break;
31964 }
31965
31966 case ForwardRef:
31967 {
31968 // Resolve `defaultProps`. This logic is copied from `beginWork`.
31969 // TODO: Consider moving this switch statement into that module. Also,
31970 // could maybe use this as an opportunity to say `use` doesn't work with
31971 // `defaultProps` :)
31972 var _Component = unitOfWork.type.render;
31973 var _unresolvedProps = unitOfWork.pendingProps;
31974
31975 var _resolvedProps = _unresolvedProps ;
31976
31977 next = replayFunctionComponent(current, unitOfWork, _resolvedProps, _Component, unitOfWork.ref, workInProgressRootRenderLanes);
31978 break;
31979 }
31980
31981 case HostComponent:
31982 {
31983 // Some host components are stateful (that's how we implement form
31984 // actions) but we don't bother to reuse the memoized state because it's
31985 // not worth the extra code. The main reason to reuse the previous hooks
31986 // is to reuse uncached promises, but we happen to know that the only
31987 // promises that a host component might suspend on are definitely cached
31988 // because they are controlled by us. So don't bother.
31989 resetHooksOnUnwind(unitOfWork); // Fallthrough to the next branch.
31990 }
31991
31992 default:
31993 {
31994 // Other types besides function components are reset completely before
31995 // being replayed. Currently this only happens when a Usable type is
31996 // reconciled — the reconciler will suspend.
31997 //
31998 // We reset the fiber back to its original state; however, this isn't
31999 // a full "unwind" because we're going to reuse the promises that were
32000 // reconciled previously. So it's intentional that we don't call
32001 // resetSuspendedWorkLoopOnUnwind here.
32002 unwindInterruptedWork(current, unitOfWork);
32003 unitOfWork = workInProgress = resetWorkInProgress(unitOfWork, entangledRenderLanes);
32004 next = beginWork(current, unitOfWork, entangledRenderLanes);
32005 break;
32006 }
32007 }
32008
32009 if (isProfilingMode) {
32010 stopProfilerTimerIfRunningAndRecordDelta(unitOfWork, true);
32011 } // The begin phase finished successfully without suspending. Return to the
32012 // normal work loop.
32013
32014
32015 resetCurrentFiber();
32016 unitOfWork.memoizedProps = unitOfWork.pendingProps;
32017
32018 if (next === null) {
32019 // If this doesn't spawn new work, complete the current work.
32020 completeUnitOfWork(unitOfWork);
32021 } else {
32022 workInProgress = next;
32023 }
32024
32025 {
32026 setCurrentOwner(null);
32027 }
32028}
32029
32030function throwAndUnwindWorkLoop(root, unitOfWork, thrownValue) {
32031 // This is a fork of performUnitOfWork specifcally for unwinding a fiber
32032 // that threw an exception.
32033 //
32034 // Return to the normal work loop. This will unwind the stack, and potentially
32035 // result in showing a fallback.
32036 resetSuspendedWorkLoopOnUnwind(unitOfWork);
32037 var returnFiber = unitOfWork.return;
32038
32039 try {
32040 // Find and mark the nearest Suspense or error boundary that can handle
32041 // this "exception".
32042 var didFatal = throwException(root, returnFiber, unitOfWork, thrownValue, workInProgressRootRenderLanes);
32043
32044 if (didFatal) {
32045 panicOnRootError(root, thrownValue);
32046 return;
32047 }
32048 } catch (error) {
32049 // We had trouble processing the error. An example of this happening is
32050 // when accessing the `componentDidCatch` property of an error boundary
32051 // throws an error. A weird edge case. There's a regression test for this.
32052 // To prevent an infinite loop, bubble the error up to the next parent.
32053 if (returnFiber !== null) {
32054 workInProgress = returnFiber;
32055 throw error;
32056 } else {
32057 panicOnRootError(root, thrownValue);
32058 return;
32059 }
32060 }
32061
32062 if (unitOfWork.flags & Incomplete) {
32063 // Unwind the stack until we reach the nearest boundary.
32064 unwindUnitOfWork(unitOfWork);
32065 } else {
32066 // Although the fiber suspended, we're intentionally going to commit it in
32067 // an inconsistent state. We can do this safely in cases where we know the
32068 // inconsistent tree will be hidden.
32069 //
32070 // This currently only applies to Legacy Suspense implementation, but we may
32071 // port a version of this to concurrent roots, too, when performing a
32072 // synchronous render. Because that will allow us to mutate the tree as we
32073 // go instead of buffering mutations until the end. Though it's unclear if
32074 // this particular path is how that would be implemented.
32075 completeUnitOfWork(unitOfWork);
32076 }
32077}
32078
32079function panicOnRootError(root, error) {
32080 // There's no ancestor that can handle this exception. This should never
32081 // happen because the root is supposed to capture all errors that weren't
32082 // caught by an error boundary. This is a fatal error, or panic condition,
32083 // because we've run out of ways to recover.
32084 workInProgressRootExitStatus = RootFatalErrored;
32085 logUncaughtError(root, createCapturedValueAtFiber(error, root.current)); // Set `workInProgress` to null. This represents advancing to the next
32086 // sibling, or the parent if there are no siblings. But since the root
32087 // has no siblings nor a parent, we set it to null. Usually this is
32088 // handled by `completeUnitOfWork` or `unwindWork`, but since we're
32089 // intentionally not calling those, we need set it here.
32090 // TODO: Consider calling `unwindWork` to pop the contexts.
32091
32092 workInProgress = null;
32093}
32094
32095function completeUnitOfWork(unitOfWork) {
32096 // Attempt to complete the current unit of work, then move to the next
32097 // sibling. If there are no more siblings, return to the parent fiber.
32098 var completedWork = unitOfWork;
32099
32100 do {
32101 {
32102 if ((completedWork.flags & Incomplete) !== NoFlags$1) {
32103 // NOTE: If we re-enable sibling prerendering in some cases, this branch
32104 // is where we would switch to the unwinding path.
32105 error('Internal React error: Expected this fiber to be complete, but ' + "it isn't. It should have been unwound. This is a bug in React.");
32106 }
32107 } // The current, flushed, state of this fiber is the alternate. Ideally
32108 // nothing should rely on this, but relying on it here means that we don't
32109 // need an additional field on the work in progress.
32110
32111
32112 var current = completedWork.alternate;
32113 var returnFiber = completedWork.return;
32114 setCurrentFiber(completedWork);
32115 var next = void 0;
32116
32117 if ((completedWork.mode & ProfileMode) === NoMode) {
32118 next = completeWork(current, completedWork, entangledRenderLanes);
32119 } else {
32120 startProfilerTimer(completedWork);
32121 next = completeWork(current, completedWork, entangledRenderLanes); // Update render duration assuming we didn't error.
32122
32123 stopProfilerTimerIfRunningAndRecordDelta(completedWork, false);
32124 }
32125
32126 resetCurrentFiber();
32127
32128 if (next !== null) {
32129 // Completing this fiber spawned new work. Work on that next.
32130 workInProgress = next;
32131 return;
32132 }
32133
32134 var siblingFiber = completedWork.sibling;
32135
32136 if (siblingFiber !== null) {
32137 // If there is more work to do in this returnFiber, do that next.
32138 workInProgress = siblingFiber;
32139 return;
32140 } // Otherwise, return to the parent
32141 // $FlowFixMe[incompatible-type] we bail out when we get a null
32142
32143
32144 completedWork = returnFiber; // Update the next thing we're working on in case something throws.
32145
32146 workInProgress = completedWork;
32147 } while (completedWork !== null); // We've reached the root.
32148
32149
32150 if (workInProgressRootExitStatus === RootInProgress) {
32151 workInProgressRootExitStatus = RootCompleted;
32152 }
32153}
32154
32155function unwindUnitOfWork(unitOfWork) {
32156 var incompleteWork = unitOfWork;
32157
32158 do {
32159 // The current, flushed, state of this fiber is the alternate. Ideally
32160 // nothing should rely on this, but relying on it here means that we don't
32161 // need an additional field on the work in progress.
32162 var current = incompleteWork.alternate; // This fiber did not complete because something threw. Pop values off
32163 // the stack without entering the complete phase. If this is a boundary,
32164 // capture values if possible.
32165
32166 var next = unwindWork(current, incompleteWork); // Because this fiber did not complete, don't reset its lanes.
32167
32168 if (next !== null) {
32169 // Found a boundary that can handle this exception. Re-renter the
32170 // begin phase. This branch will return us to the normal work loop.
32171 //
32172 // Since we're restarting, remove anything that is not a host effect
32173 // from the effect tag.
32174 next.flags &= HostEffectMask;
32175 workInProgress = next;
32176 return;
32177 } // Keep unwinding until we reach either a boundary or the root.
32178
32179
32180 if ((incompleteWork.mode & ProfileMode) !== NoMode) {
32181 // Record the render duration for the fiber that errored.
32182 stopProfilerTimerIfRunningAndRecordDelta(incompleteWork, false); // Include the time spent working on failed children before continuing.
32183
32184 var actualDuration = incompleteWork.actualDuration;
32185 var child = incompleteWork.child;
32186
32187 while (child !== null) {
32188 // $FlowFixMe[unsafe-addition] addition with possible null/undefined value
32189 actualDuration += child.actualDuration;
32190 child = child.sibling;
32191 }
32192
32193 incompleteWork.actualDuration = actualDuration;
32194 } // TODO: Once we stop prerendering siblings, instead of resetting the parent
32195 // of the node being unwound, we should be able to reset node itself as we
32196 // unwind the stack. Saves an additional null check.
32197
32198
32199 var returnFiber = incompleteWork.return;
32200
32201 if (returnFiber !== null) {
32202 // Mark the parent fiber as incomplete and clear its subtree flags.
32203 // TODO: Once we stop prerendering siblings, we may be able to get rid of
32204 // the Incomplete flag because unwinding to the nearest boundary will
32205 // happen synchronously.
32206 returnFiber.flags |= Incomplete;
32207 returnFiber.subtreeFlags = NoFlags$1;
32208 returnFiber.deletions = null;
32209 } // NOTE: If we re-enable sibling prerendering in some cases, here we
32210 // would switch to the normal completion path: check if a sibling
32211 // exists, and if so, begin work on it.
32212 // Otherwise, return to the parent
32213 // $FlowFixMe[incompatible-type] we bail out when we get a null
32214
32215
32216 incompleteWork = returnFiber; // Update the next thing we're working on in case something throws.
32217
32218 workInProgress = incompleteWork;
32219 } while (incompleteWork !== null); // We've unwound all the way to the root.
32220
32221
32222 workInProgressRootExitStatus = RootDidNotComplete;
32223 workInProgress = null;
32224}
32225
32226function commitRoot(root, recoverableErrors, transitions, didIncludeRenderPhaseUpdate, spawnedLane) {
32227 // TODO: This no longer makes any sense. We already wrap the mutation and
32228 // layout phases. Should be able to remove.
32229 var prevTransition = ReactSharedInternals.T;
32230 var previousUpdateLanePriority = getCurrentUpdatePriority();
32231
32232 try {
32233 setCurrentUpdatePriority(DiscreteEventPriority);
32234 ReactSharedInternals.T = null;
32235 commitRootImpl(root, recoverableErrors, transitions, didIncludeRenderPhaseUpdate, previousUpdateLanePriority, spawnedLane);
32236 } finally {
32237 ReactSharedInternals.T = prevTransition;
32238 setCurrentUpdatePriority(previousUpdateLanePriority);
32239 }
32240
32241 return null;
32242}
32243
32244function commitRootImpl(root, recoverableErrors, transitions, didIncludeRenderPhaseUpdate, renderPriorityLevel, spawnedLane) {
32245 do {
32246 // `flushPassiveEffects` will call `flushSyncUpdateQueue` at the end, which
32247 // means `flushPassiveEffects` will sometimes result in additional
32248 // passive effects. So we need to keep flushing in a loop until there are
32249 // no more pending effects.
32250 // TODO: Might be better if `flushPassiveEffects` did not automatically
32251 // flush synchronous work at the end, to avoid factoring hazards like this.
32252 flushPassiveEffects();
32253 } while (rootWithPendingPassiveEffects !== null);
32254
32255 flushRenderPhaseStrictModeWarningsInDEV();
32256
32257 if ((executionContext & (RenderContext | CommitContext)) !== NoContext) {
32258 throw new Error('Should not already be working.');
32259 }
32260
32261 var finishedWork = root.finishedWork;
32262 var lanes = root.finishedLanes;
32263
32264 {
32265 markCommitStarted(lanes);
32266 }
32267
32268 if (finishedWork === null) {
32269
32270 {
32271 markCommitStopped();
32272 }
32273
32274 return null;
32275 } else {
32276 {
32277 if (lanes === NoLanes) {
32278 error('root.finishedLanes should not be empty during a commit. This is a ' + 'bug in React.');
32279 }
32280 }
32281 }
32282
32283 root.finishedWork = null;
32284 root.finishedLanes = NoLanes;
32285
32286 if (finishedWork === root.current) {
32287 throw new Error('Cannot commit the same tree as before. This error is likely caused by ' + 'a bug in React. Please file an issue.');
32288 } // commitRoot never returns a continuation; it always finishes synchronously.
32289 // So we can clear these now to allow a new callback to be scheduled.
32290
32291
32292 root.callbackNode = null;
32293 root.callbackPriority = NoLane;
32294 root.cancelPendingCommit = null; // Check which lanes no longer have any work scheduled on them, and mark
32295 // those as finished.
32296
32297 var remainingLanes = mergeLanes(finishedWork.lanes, finishedWork.childLanes); // Make sure to account for lanes that were updated by a concurrent event
32298 // during the render phase; don't mark them as finished.
32299
32300 var concurrentlyUpdatedLanes = getConcurrentlyUpdatedLanes();
32301 remainingLanes = mergeLanes(remainingLanes, concurrentlyUpdatedLanes);
32302 markRootFinished(root, remainingLanes, spawnedLane); // Reset this before firing side effects so we can detect recursive updates.
32303
32304 didIncludeCommitPhaseUpdate = false;
32305
32306 if (root === workInProgressRoot) {
32307 // We can reset these now that they are finished.
32308 workInProgressRoot = null;
32309 workInProgress = null;
32310 workInProgressRootRenderLanes = NoLanes;
32311 } // If there are pending passive effects, schedule a callback to process them.
32312 // Do this as early as possible, so it is queued before anything else that
32313 // might get scheduled in the commit phase. (See #16714.)
32314 // TODO: Delete all other places that schedule the passive effect callback
32315 // They're redundant.
32316
32317
32318 if ((finishedWork.subtreeFlags & PassiveMask) !== NoFlags$1 || (finishedWork.flags & PassiveMask) !== NoFlags$1) {
32319 if (!rootDoesHavePassiveEffects) {
32320 rootDoesHavePassiveEffects = true;
32321 pendingPassiveEffectsRemainingLanes = remainingLanes; // workInProgressTransitions might be overwritten, so we want
32322 // to store it in pendingPassiveTransitions until they get processed
32323 // We need to pass this through as an argument to commitRoot
32324 // because workInProgressTransitions might have changed between
32325 // the previous render and commit if we throttle the commit
32326 // with setTimeout
32327
32328 pendingPassiveTransitions = transitions;
32329 scheduleCallback(NormalPriority$1, function () {
32330 flushPassiveEffects(); // This render triggered passive effects: release the root cache pool
32331 // *after* passive effects fire to avoid freeing a cache pool that may
32332 // be referenced by a node in the tree (HostRoot, Cache boundary etc)
32333
32334 return null;
32335 });
32336 }
32337 } // Check if there are any effects in the whole tree.
32338 // TODO: This is left over from the effect list implementation, where we had
32339 // to check for the existence of `firstEffect` to satisfy Flow. I think the
32340 // only other reason this optimization exists is because it affects profiling.
32341 // Reconsider whether this is necessary.
32342
32343
32344 var subtreeHasEffects = (finishedWork.subtreeFlags & (BeforeMutationMask | MutationMask | LayoutMask | PassiveMask)) !== NoFlags$1;
32345 var rootHasEffect = (finishedWork.flags & (BeforeMutationMask | MutationMask | LayoutMask | PassiveMask)) !== NoFlags$1;
32346
32347 if (subtreeHasEffects || rootHasEffect) {
32348 var prevTransition = ReactSharedInternals.T;
32349 ReactSharedInternals.T = null;
32350 var previousPriority = getCurrentUpdatePriority();
32351 setCurrentUpdatePriority(DiscreteEventPriority);
32352 var prevExecutionContext = executionContext;
32353 executionContext |= CommitContext; // Reset this to null before calling lifecycles
32354
32355 {
32356 setCurrentOwner(null);
32357 } // The commit phase is broken into several sub-phases. We do a separate pass
32358 // of the effect list for each phase: all mutation effects come before all
32359 // layout effects, and so on.
32360 // The first phase a "before mutation" phase. We use this phase to read the
32361 // state of the host tree right before we mutate it. This is where
32362 // getSnapshotBeforeUpdate is called.
32363
32364
32365 commitBeforeMutationEffects(root, finishedWork);
32366
32367 {
32368 // Mark the current commit time to be shared by all Profilers in this
32369 // batch. This enables them to be grouped later.
32370 recordCommitTime();
32371 } // The next phase is the mutation phase, where we mutate the host tree.
32372
32373
32374 commitMutationEffects(root, finishedWork, lanes);
32375
32376 resetAfterCommit(); // The work-in-progress tree is now the current tree. This must come after
32377 // the mutation phase, so that the previous tree is still current during
32378 // componentWillUnmount, but before the layout phase, so that the finished
32379 // work is current during componentDidMount/Update.
32380
32381 root.current = finishedWork; // The next phase is the layout phase, where we call effects that read
32382
32383 {
32384 markLayoutEffectsStarted(lanes);
32385 }
32386
32387 commitLayoutEffects(finishedWork, root, lanes);
32388
32389 {
32390 markLayoutEffectsStopped();
32391 } // Tell Scheduler to yield at the end of the frame, so the browser has an
32392 // opportunity to paint.
32393
32394
32395 requestPaint();
32396 executionContext = prevExecutionContext; // Reset the priority to the previous non-sync value.
32397
32398 setCurrentUpdatePriority(previousPriority);
32399 ReactSharedInternals.T = prevTransition;
32400 } else {
32401 // No effects.
32402 root.current = finishedWork; // Measure these anyway so the flamegraph explicitly shows that there were
32403 // no effects.
32404 // TODO: Maybe there's a better way to report this.
32405
32406 {
32407 recordCommitTime();
32408 }
32409 }
32410
32411 var rootDidHavePassiveEffects = rootDoesHavePassiveEffects;
32412
32413 if (rootDoesHavePassiveEffects) {
32414 // This commit has passive effects. Stash a reference to them. But don't
32415 // schedule a callback until after flushing layout work.
32416 rootDoesHavePassiveEffects = false;
32417 rootWithPendingPassiveEffects = root;
32418 pendingPassiveEffectsLanes = lanes;
32419 } else {
32420 // There were no passive effects, so we can immediately release the cache
32421 // pool for this render.
32422 releaseRootPooledCache(root, remainingLanes);
32423
32424 {
32425 nestedPassiveUpdateCount = 0;
32426 rootWithPassiveNestedUpdates = null;
32427 }
32428 } // Read this again, since an effect might have updated it
32429
32430
32431 remainingLanes = root.pendingLanes; // Check if there's remaining work on this root
32432 // TODO: This is part of the `componentDidCatch` implementation. Its purpose
32433 // is to detect whether something might have called setState inside
32434 // `componentDidCatch`. The mechanism is known to be flawed because `setState`
32435 // inside `componentDidCatch` is itself flawed — that's why we recommend
32436 // `getDerivedStateFromError` instead. However, it could be improved by
32437 // checking if remainingLanes includes Sync work, instead of whether there's
32438 // any work remaining at all (which would also include stuff like Suspense
32439 // retries or transitions). It's been like this for a while, though, so fixing
32440 // it probably isn't that urgent.
32441
32442 if (remainingLanes === NoLanes) {
32443 // If there's no remaining work, we can clear the set of already failed
32444 // error boundaries.
32445 legacyErrorBoundariesThatAlreadyFailed = null;
32446 }
32447
32448 {
32449 if (!rootDidHavePassiveEffects) {
32450 commitDoubleInvokeEffectsInDEV(root);
32451 }
32452 }
32453
32454 onCommitRoot$1(finishedWork.stateNode, renderPriorityLevel);
32455
32456 {
32457 if (isDevToolsPresent) {
32458 root.memoizedUpdaters.clear();
32459 }
32460 }
32461
32462 {
32463 onCommitRoot();
32464 } // Always call this before exiting `commitRoot`, to ensure that any
32465 // additional work on this root is scheduled.
32466
32467
32468 ensureRootIsScheduled(root);
32469
32470 if (recoverableErrors !== null) {
32471 // There were errors during this render, but recovered from them without
32472 // needing to surface it to the UI. We log them here.
32473 var onRecoverableError = root.onRecoverableError;
32474
32475 for (var i = 0; i < recoverableErrors.length; i++) {
32476 var recoverableError = recoverableErrors[i];
32477 var errorInfo = makeErrorInfo(recoverableError.stack);
32478 onRecoverableError(recoverableError.value, errorInfo);
32479 }
32480 } // If the passive effects are the result of a discrete render, flush them
32481 // synchronously at the end of the current task so that the result is
32482 // immediately observable. Otherwise, we assume that they are not
32483 // order-dependent and do not need to be observed by external systems, so we
32484 // can wait until after paint.
32485 // TODO: We can optimize this by not scheduling the callback earlier. Since we
32486 // currently schedule the callback in multiple places, will wait until those
32487 // are consolidated.
32488
32489
32490 if (includesSyncLane(pendingPassiveEffectsLanes) && (disableLegacyMode )) {
32491 flushPassiveEffects();
32492 } // Read this again, since a passive effect might have updated it
32493
32494
32495 remainingLanes = root.pendingLanes; // Check if this render scheduled a cascading synchronous update. This is a
32496 // heurstic to detect infinite update loops. We are intentionally excluding
32497 // hydration lanes in this check, because render triggered by selective
32498 // hydration is conceptually not an update.
32499
32500 if ( // Check if there was a recursive update spawned by this render, in either
32501 // the render phase or the commit phase. We track these explicitly because
32502 // we can't infer from the remaining lanes alone.
32503 (didIncludeRenderPhaseUpdate || didIncludeCommitPhaseUpdate) || // Was the finished render the result of an update (not hydration)?
32504 includesSomeLane(lanes, UpdateLanes) && // Did it schedule a sync update?
32505 includesSomeLane(remainingLanes, SyncUpdateLanes)) {
32506 {
32507 markNestedUpdateScheduled();
32508 } // Count the number of times the root synchronously re-renders without
32509 // finishing. If there are too many, it indicates an infinite update loop.
32510
32511
32512 if (root === rootWithNestedUpdates) {
32513 nestedUpdateCount++;
32514 } else {
32515 nestedUpdateCount = 0;
32516 rootWithNestedUpdates = root;
32517 }
32518 } else {
32519 nestedUpdateCount = 0;
32520 } // If layout work was scheduled, flush it now.
32521
32522
32523 flushSyncWorkOnAllRoots();
32524
32525 {
32526 markCommitStopped();
32527 }
32528
32529 return null;
32530}
32531
32532function makeErrorInfo(componentStack) {
32533 var errorInfo = {
32534 componentStack: componentStack
32535 };
32536
32537 {
32538 Object.defineProperty(errorInfo, 'digest', {
32539 get: function () {
32540 error('You are accessing "digest" from the errorInfo object passed to onRecoverableError.' + ' This property is no longer provided as part of errorInfo but can be accessed as a property' + ' of the Error instance itself.');
32541 }
32542 });
32543 }
32544
32545 return errorInfo;
32546}
32547
32548function releaseRootPooledCache(root, remainingLanes) {
32549 {
32550 var pooledCacheLanes = root.pooledCacheLanes &= remainingLanes;
32551
32552 if (pooledCacheLanes === NoLanes) {
32553 // None of the remaining work relies on the cache pool. Clear it so
32554 // subsequent requests get a new cache
32555 var pooledCache = root.pooledCache;
32556
32557 if (pooledCache != null) {
32558 root.pooledCache = null;
32559 releaseCache(pooledCache);
32560 }
32561 }
32562 }
32563}
32564
32565function flushPassiveEffects() {
32566 // Returns whether passive effects were flushed.
32567 // TODO: Combine this check with the one in flushPassiveEFfectsImpl. We should
32568 // probably just combine the two functions. I believe they were only separate
32569 // in the first place because we used to wrap it with
32570 // `Scheduler.runWithPriority`, which accepts a function. But now we track the
32571 // priority within React itself, so we can mutate the variable directly.
32572 if (rootWithPendingPassiveEffects !== null) {
32573 // Cache the root since rootWithPendingPassiveEffects is cleared in
32574 // flushPassiveEffectsImpl
32575 var root = rootWithPendingPassiveEffects; // Cache and clear the remaining lanes flag; it must be reset since this
32576 // method can be called from various places, not always from commitRoot
32577 // where the remaining lanes are known
32578
32579 var remainingLanes = pendingPassiveEffectsRemainingLanes;
32580 pendingPassiveEffectsRemainingLanes = NoLanes;
32581 var renderPriority = lanesToEventPriority(pendingPassiveEffectsLanes);
32582 var priority = lowerEventPriority(DefaultEventPriority, renderPriority);
32583 var prevTransition = ReactSharedInternals.T;
32584 var previousPriority = getCurrentUpdatePriority();
32585
32586 try {
32587 setCurrentUpdatePriority(priority);
32588 ReactSharedInternals.T = null;
32589 return flushPassiveEffectsImpl();
32590 } finally {
32591 setCurrentUpdatePriority(previousPriority);
32592 ReactSharedInternals.T = prevTransition; // Once passive effects have run for the tree - giving components a
32593 // chance to retain cache instances they use - release the pooled
32594 // cache at the root (if there is one)
32595
32596 releaseRootPooledCache(root, remainingLanes);
32597 }
32598 }
32599
32600 return false;
32601}
32602function enqueuePendingPassiveProfilerEffect(fiber) {
32603 {
32604 pendingPassiveProfilerEffects.push(fiber);
32605
32606 if (!rootDoesHavePassiveEffects) {
32607 rootDoesHavePassiveEffects = true;
32608 scheduleCallback(NormalPriority$1, function () {
32609 flushPassiveEffects();
32610 return null;
32611 });
32612 }
32613 }
32614}
32615
32616function flushPassiveEffectsImpl() {
32617 if (rootWithPendingPassiveEffects === null) {
32618 return false;
32619 } // Cache and clear the transitions flag
32620
32621
32622 var transitions = pendingPassiveTransitions;
32623 pendingPassiveTransitions = null;
32624 var root = rootWithPendingPassiveEffects;
32625 var lanes = pendingPassiveEffectsLanes;
32626 rootWithPendingPassiveEffects = null; // TODO: This is sometimes out of sync with rootWithPendingPassiveEffects.
32627 // Figure out why and fix it. It's not causing any known issues (probably
32628 // because it's only used for profiling), but it's a refactor hazard.
32629
32630 pendingPassiveEffectsLanes = NoLanes;
32631
32632 if ((executionContext & (RenderContext | CommitContext)) !== NoContext) {
32633 throw new Error('Cannot flush passive effects while already rendering.');
32634 }
32635
32636 {
32637 isFlushingPassiveEffects = true;
32638 didScheduleUpdateDuringPassiveEffects = false;
32639 }
32640
32641 {
32642 markPassiveEffectsStarted(lanes);
32643 }
32644
32645 var prevExecutionContext = executionContext;
32646 executionContext |= CommitContext;
32647 commitPassiveUnmountEffects(root.current);
32648 commitPassiveMountEffects(root, root.current, lanes, transitions); // TODO: Move to commitPassiveMountEffects
32649
32650 {
32651 var profilerEffects = pendingPassiveProfilerEffects;
32652 pendingPassiveProfilerEffects = [];
32653
32654 for (var i = 0; i < profilerEffects.length; i++) {
32655 var fiber = profilerEffects[i];
32656 commitPassiveEffectDurations(root, fiber);
32657 }
32658 }
32659
32660 {
32661 markPassiveEffectsStopped();
32662 }
32663
32664 {
32665 commitDoubleInvokeEffectsInDEV(root);
32666 }
32667
32668 executionContext = prevExecutionContext;
32669 flushSyncWorkOnAllRoots();
32670
32671 {
32672 // If additional passive effects were scheduled, increment a counter. If this
32673 // exceeds the limit, we'll fire a warning.
32674 if (didScheduleUpdateDuringPassiveEffects) {
32675 if (root === rootWithPassiveNestedUpdates) {
32676 nestedPassiveUpdateCount++;
32677 } else {
32678 nestedPassiveUpdateCount = 0;
32679 rootWithPassiveNestedUpdates = root;
32680 }
32681 } else {
32682 nestedPassiveUpdateCount = 0;
32683 }
32684
32685 isFlushingPassiveEffects = false;
32686 didScheduleUpdateDuringPassiveEffects = false;
32687 } // TODO: Move to commitPassiveMountEffects
32688
32689
32690 onPostCommitRoot(root);
32691
32692 {
32693 var stateNode = root.current.stateNode;
32694 stateNode.effectDuration = 0;
32695 stateNode.passiveEffectDuration = 0;
32696 }
32697
32698 return true;
32699}
32700
32701function isAlreadyFailedLegacyErrorBoundary(instance) {
32702 return legacyErrorBoundariesThatAlreadyFailed !== null && legacyErrorBoundariesThatAlreadyFailed.has(instance);
32703}
32704function markLegacyErrorBoundaryAsFailed(instance) {
32705 if (legacyErrorBoundariesThatAlreadyFailed === null) {
32706 legacyErrorBoundariesThatAlreadyFailed = new Set([instance]);
32707 } else {
32708 legacyErrorBoundariesThatAlreadyFailed.add(instance);
32709 }
32710}
32711
32712function captureCommitPhaseErrorOnRoot(rootFiber, sourceFiber, error) {
32713 var errorInfo = createCapturedValueAtFiber(error, sourceFiber);
32714 var update = createRootErrorUpdate(rootFiber.stateNode, errorInfo, SyncLane);
32715 var root = enqueueUpdate(rootFiber, update, SyncLane);
32716
32717 if (root !== null) {
32718 markRootUpdated(root, SyncLane);
32719 ensureRootIsScheduled(root);
32720 }
32721}
32722
32723function captureCommitPhaseError(sourceFiber, nearestMountedAncestor, error$1) {
32724 {
32725 setIsRunningInsertionEffect(false);
32726 }
32727
32728 if (sourceFiber.tag === HostRoot) {
32729 // Error was thrown at the root. There is no parent, so the root
32730 // itself should capture it.
32731 captureCommitPhaseErrorOnRoot(sourceFiber, sourceFiber, error$1);
32732 return;
32733 }
32734
32735 var fiber = nearestMountedAncestor;
32736
32737 while (fiber !== null) {
32738 if (fiber.tag === HostRoot) {
32739 captureCommitPhaseErrorOnRoot(fiber, sourceFiber, error$1);
32740 return;
32741 } else if (fiber.tag === ClassComponent) {
32742 var ctor = fiber.type;
32743 var instance = fiber.stateNode;
32744
32745 if (typeof ctor.getDerivedStateFromError === 'function' || typeof instance.componentDidCatch === 'function' && !isAlreadyFailedLegacyErrorBoundary(instance)) {
32746 var errorInfo = createCapturedValueAtFiber(error$1, sourceFiber);
32747 var update = createClassErrorUpdate(SyncLane);
32748 var root = enqueueUpdate(fiber, update, SyncLane);
32749
32750 if (root !== null) {
32751 initializeClassErrorUpdate(update, root, fiber, errorInfo);
32752 markRootUpdated(root, SyncLane);
32753 ensureRootIsScheduled(root);
32754 }
32755
32756 return;
32757 }
32758 }
32759
32760 fiber = fiber.return;
32761 }
32762
32763 {
32764 error('Internal React error: Attempted to capture a commit phase error ' + 'inside a detached tree. This indicates a bug in React. Potential ' + 'causes include deleting the same fiber more than once, committing an ' + 'already-finished tree, or an inconsistent return pointer.\n\n' + 'Error message:\n\n%s', error$1);
32765 }
32766}
32767function attachPingListener(root, wakeable, lanes) {
32768 // Attach a ping listener
32769 //
32770 // The data might resolve before we have a chance to commit the fallback. Or,
32771 // in the case of a refresh, we'll never commit a fallback. So we need to
32772 // attach a listener now. When it resolves ("pings"), we can decide whether to
32773 // try rendering the tree again.
32774 //
32775 // Only attach a listener if one does not already exist for the lanes
32776 // we're currently rendering (which acts like a "thread ID" here).
32777 //
32778 // We only need to do this in concurrent mode. Legacy Suspense always
32779 // commits fallbacks synchronously, so there are no pings.
32780 var pingCache = root.pingCache;
32781 var threadIDs;
32782
32783 if (pingCache === null) {
32784 pingCache = root.pingCache = new PossiblyWeakMap();
32785 threadIDs = new Set();
32786 pingCache.set(wakeable, threadIDs);
32787 } else {
32788 threadIDs = pingCache.get(wakeable);
32789
32790 if (threadIDs === undefined) {
32791 threadIDs = new Set();
32792 pingCache.set(wakeable, threadIDs);
32793 }
32794 }
32795
32796 if (!threadIDs.has(lanes)) {
32797 workInProgressRootDidAttachPingListener = true; // Memoize using the thread ID to prevent redundant listeners.
32798
32799 threadIDs.add(lanes);
32800 var ping = pingSuspendedRoot.bind(null, root, wakeable, lanes);
32801
32802 {
32803 if (isDevToolsPresent) {
32804 // If we have pending work still, restore the original updaters
32805 restorePendingUpdaters(root, lanes);
32806 }
32807 }
32808
32809 wakeable.then(ping, ping);
32810 }
32811}
32812
32813function pingSuspendedRoot(root, wakeable, pingedLanes) {
32814 var pingCache = root.pingCache;
32815
32816 if (pingCache !== null) {
32817 // The wakeable resolved, so we no longer need to memoize, because it will
32818 // never be thrown again.
32819 pingCache.delete(wakeable);
32820 }
32821
32822 markRootPinged(root, pingedLanes);
32823 warnIfSuspenseResolutionNotWrappedWithActDEV();
32824
32825 if (workInProgressRoot === root && isSubsetOfLanes(workInProgressRootRenderLanes, pingedLanes)) {
32826 // Received a ping at the same priority level at which we're currently
32827 // rendering. We might want to restart this render. This should mirror
32828 // the logic of whether or not a root suspends once it completes.
32829 // TODO: If we're rendering sync either due to Sync, Batched or expired,
32830 // we should probably never restart.
32831 // If we're suspended with delay, or if it's a retry, we'll always suspend
32832 // so we can always restart.
32833 if (workInProgressRootExitStatus === RootSuspendedWithDelay || workInProgressRootExitStatus === RootSuspended && includesOnlyRetries(workInProgressRootRenderLanes) && now$1() - globalMostRecentFallbackTime < FALLBACK_THROTTLE_MS) {
32834 // Force a restart from the root by unwinding the stack. Unless this is
32835 // being called from the render phase, because that would cause a crash.
32836 if ((executionContext & RenderContext) === NoContext) {
32837 prepareFreshStack(root, NoLanes);
32838 }
32839 } else {
32840 // Even though we can't restart right now, we might get an
32841 // opportunity later. So we mark this render as having a ping.
32842 workInProgressRootPingedLanes = mergeLanes(workInProgressRootPingedLanes, pingedLanes);
32843 }
32844 }
32845
32846 ensureRootIsScheduled(root);
32847}
32848
32849function retryTimedOutBoundary(boundaryFiber, retryLane) {
32850 // The boundary fiber (a Suspense component or SuspenseList component)
32851 // previously was rendered in its fallback state. One of the promises that
32852 // suspended it has resolved, which means at least part of the tree was
32853 // likely unblocked. Try rendering again, at a new lanes.
32854 if (retryLane === NoLane) {
32855 // TODO: Assign this to `suspenseState.retryLane`? to avoid
32856 // unnecessary entanglement?
32857 retryLane = requestRetryLane();
32858 } // TODO: Special case idle priority?
32859
32860
32861 var root = enqueueConcurrentRenderForLane(boundaryFiber, retryLane);
32862
32863 if (root !== null) {
32864 markRootUpdated(root, retryLane);
32865 ensureRootIsScheduled(root);
32866 }
32867}
32868
32869function retryDehydratedSuspenseBoundary(boundaryFiber) {
32870 var suspenseState = boundaryFiber.memoizedState;
32871 var retryLane = NoLane;
32872
32873 if (suspenseState !== null) {
32874 retryLane = suspenseState.retryLane;
32875 }
32876
32877 retryTimedOutBoundary(boundaryFiber, retryLane);
32878}
32879function resolveRetryWakeable(boundaryFiber, wakeable) {
32880 var retryLane = NoLane; // Default
32881
32882 var retryCache;
32883
32884 switch (boundaryFiber.tag) {
32885 case SuspenseComponent:
32886 retryCache = boundaryFiber.stateNode;
32887 var suspenseState = boundaryFiber.memoizedState;
32888
32889 if (suspenseState !== null) {
32890 retryLane = suspenseState.retryLane;
32891 }
32892
32893 break;
32894
32895 case SuspenseListComponent:
32896 retryCache = boundaryFiber.stateNode;
32897 break;
32898
32899 case OffscreenComponent:
32900 {
32901 var instance = boundaryFiber.stateNode;
32902 retryCache = instance._retryCache;
32903 break;
32904 }
32905
32906 default:
32907 throw new Error('Pinged unknown suspense boundary type. ' + 'This is probably a bug in React.');
32908 }
32909
32910 if (retryCache !== null) {
32911 // The wakeable resolved, so we no longer need to memoize, because it will
32912 // never be thrown again.
32913 retryCache.delete(wakeable);
32914 }
32915
32916 retryTimedOutBoundary(boundaryFiber, retryLane);
32917}
32918function throwIfInfiniteUpdateLoopDetected() {
32919 if (nestedUpdateCount > NESTED_UPDATE_LIMIT) {
32920 nestedUpdateCount = 0;
32921 nestedPassiveUpdateCount = 0;
32922 rootWithNestedUpdates = null;
32923 rootWithPassiveNestedUpdates = null;
32924
32925 {
32926 if (executionContext & RenderContext && workInProgressRoot !== null) {
32927 // We're in the render phase. Disable the concurrent error recovery
32928 // mechanism to ensure that the error we're about to throw gets handled.
32929 // We need it to trigger the nearest error boundary so that the infinite
32930 // update loop is broken.
32931 workInProgressRoot.errorRecoveryDisabledLanes = mergeLanes(workInProgressRoot.errorRecoveryDisabledLanes, workInProgressRootRenderLanes);
32932 }
32933 }
32934
32935 throw new 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.');
32936 }
32937
32938 {
32939 if (nestedPassiveUpdateCount > NESTED_PASSIVE_UPDATE_LIMIT) {
32940 nestedPassiveUpdateCount = 0;
32941 rootWithPassiveNestedUpdates = null;
32942
32943 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.');
32944 }
32945 }
32946}
32947
32948function flushRenderPhaseStrictModeWarningsInDEV() {
32949 {
32950 ReactStrictModeWarnings.flushLegacyContextWarning();
32951 ReactStrictModeWarnings.flushPendingUnsafeLifecycleWarnings();
32952 }
32953}
32954
32955function recursivelyTraverseAndDoubleInvokeEffectsInDEV(root, parentFiber, isInStrictMode) {
32956 if ((parentFiber.subtreeFlags & (PlacementDEV | Visibility)) === NoFlags$1) {
32957 // Parent's descendants have already had effects double invoked.
32958 // Early exit to avoid unnecessary tree traversal.
32959 return;
32960 }
32961
32962 var child = parentFiber.child;
32963
32964 while (child !== null) {
32965 doubleInvokeEffectsInDEVIfNecessary(root, child, isInStrictMode);
32966 child = child.sibling;
32967 }
32968} // Unconditionally disconnects and connects passive and layout effects.
32969
32970
32971function doubleInvokeEffectsOnFiber(root, fiber) {
32972 var shouldDoubleInvokePassiveEffects = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true;
32973 disappearLayoutEffects(fiber);
32974
32975 if (shouldDoubleInvokePassiveEffects) {
32976 disconnectPassiveEffect(fiber);
32977 }
32978
32979 reappearLayoutEffects(root, fiber.alternate, fiber, false);
32980
32981 if (shouldDoubleInvokePassiveEffects) {
32982 reconnectPassiveEffects(root, fiber, NoLanes, null, false);
32983 }
32984}
32985
32986function doubleInvokeEffectsInDEVIfNecessary(root, fiber, parentIsInStrictMode) {
32987 var isStrictModeFiber = fiber.type === REACT_STRICT_MODE_TYPE;
32988 var isInStrictMode = parentIsInStrictMode || isStrictModeFiber; // First case: the fiber **is not** of type OffscreenComponent. No
32989 // special rules apply to double invoking effects.
32990
32991 if (fiber.tag !== OffscreenComponent) {
32992 if (fiber.flags & PlacementDEV) {
32993 setCurrentFiber(fiber);
32994
32995 if (isInStrictMode) {
32996 doubleInvokeEffectsOnFiber(root, fiber, (fiber.mode & NoStrictPassiveEffectsMode) === NoMode);
32997 }
32998
32999 resetCurrentFiber();
33000 } else {
33001 recursivelyTraverseAndDoubleInvokeEffectsInDEV(root, fiber, isInStrictMode);
33002 }
33003
33004 return;
33005 } // Second case: the fiber **is** of type OffscreenComponent.
33006 // This branch contains cases specific to Offscreen.
33007
33008
33009 if (fiber.memoizedState === null) {
33010 // Only consider Offscreen that is visible.
33011 // TODO (Offscreen) Handle manual mode.
33012 setCurrentFiber(fiber);
33013
33014 if (isInStrictMode && fiber.flags & Visibility) {
33015 // Double invoke effects on Offscreen's subtree only
33016 // if it is visible and its visibility has changed.
33017 doubleInvokeEffectsOnFiber(root, fiber);
33018 } else if (fiber.subtreeFlags & PlacementDEV) {
33019 // Something in the subtree could have been suspended.
33020 // We need to continue traversal and find newly inserted fibers.
33021 recursivelyTraverseAndDoubleInvokeEffectsInDEV(root, fiber, isInStrictMode);
33022 }
33023
33024 resetCurrentFiber();
33025 }
33026}
33027
33028function commitDoubleInvokeEffectsInDEV(root, hasPassiveEffects) {
33029 {
33030 {
33031 var doubleInvokeEffects = true;
33032
33033 if (!(root.current.mode & (StrictLegacyMode | StrictEffectsMode))) {
33034 doubleInvokeEffects = false;
33035 }
33036
33037 recursivelyTraverseAndDoubleInvokeEffectsInDEV(root, root.current, doubleInvokeEffects);
33038 }
33039 }
33040}
33041
33042var didWarnStateUpdateForNotYetMountedComponent = null;
33043function warnAboutUpdateOnNotYetMountedFiberInDEV(fiber) {
33044 {
33045 if ((executionContext & RenderContext) !== NoContext) {
33046 // We let the other warning about render phase updates deal with this one.
33047 return;
33048 }
33049
33050 var tag = fiber.tag;
33051
33052 if (tag !== HostRoot && tag !== ClassComponent && tag !== FunctionComponent && tag !== ForwardRef && tag !== MemoComponent && tag !== SimpleMemoComponent) {
33053 // Only warn for user-defined components, not internal ones like Suspense.
33054 return;
33055 } // We show the whole stack but dedupe on the top component's name because
33056 // the problematic code almost always lies inside that component.
33057
33058
33059 var componentName = getComponentNameFromFiber(fiber) || 'ReactComponent';
33060
33061 if (didWarnStateUpdateForNotYetMountedComponent !== null) {
33062 if (didWarnStateUpdateForNotYetMountedComponent.has(componentName)) {
33063 return;
33064 } // $FlowFixMe[incompatible-use] found when upgrading Flow
33065
33066
33067 didWarnStateUpdateForNotYetMountedComponent.add(componentName);
33068 } else {
33069 didWarnStateUpdateForNotYetMountedComponent = new Set([componentName]);
33070 }
33071
33072 var previousFiber = current;
33073
33074 try {
33075 setCurrentFiber(fiber);
33076
33077 error("Can't perform a React state update on a component that hasn't mounted yet. " + 'This indicates that you have a side-effect in your render function that ' + 'asynchronously later calls tries to update the component. Move this work to ' + 'useEffect instead.');
33078 } finally {
33079 if (previousFiber) {
33080 setCurrentFiber(fiber);
33081 } else {
33082 resetCurrentFiber();
33083 }
33084 }
33085 }
33086}
33087var didWarnAboutUpdateInRender = false;
33088var didWarnAboutUpdateInRenderForAnotherComponent;
33089
33090{
33091 didWarnAboutUpdateInRenderForAnotherComponent = new Set();
33092}
33093
33094function warnAboutRenderPhaseUpdatesInDEV(fiber) {
33095 {
33096 if (isRendering) {
33097 switch (fiber.tag) {
33098 case FunctionComponent:
33099 case ForwardRef:
33100 case SimpleMemoComponent:
33101 {
33102 var renderingComponentName = workInProgress && getComponentNameFromFiber(workInProgress) || 'Unknown'; // Dedupe by the rendering component because it's the one that needs to be fixed.
33103
33104 var dedupeKey = renderingComponentName;
33105
33106 if (!didWarnAboutUpdateInRenderForAnotherComponent.has(dedupeKey)) {
33107 didWarnAboutUpdateInRenderForAnotherComponent.add(dedupeKey);
33108 var setStateComponentName = getComponentNameFromFiber(fiber) || 'Unknown';
33109
33110 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://react.dev/link/setstate-in-render', setStateComponentName, renderingComponentName, renderingComponentName);
33111 }
33112
33113 break;
33114 }
33115
33116 case ClassComponent:
33117 {
33118 if (!didWarnAboutUpdateInRender) {
33119 error('Cannot update during an existing state transition (such as ' + 'within `render`). Render methods should be a pure ' + 'function of props and state.');
33120
33121 didWarnAboutUpdateInRender = true;
33122 }
33123
33124 break;
33125 }
33126 }
33127 }
33128 }
33129}
33130
33131function restorePendingUpdaters(root, lanes) {
33132 {
33133 if (isDevToolsPresent) {
33134 var memoizedUpdaters = root.memoizedUpdaters;
33135 memoizedUpdaters.forEach(function (schedulingFiber) {
33136 addFiberToLanesMap(root, schedulingFiber, lanes);
33137 }); // This function intentionally does not clear memoized updaters.
33138 // Those may still be relevant to the current commit
33139 // and a future one (e.g. Suspense).
33140 }
33141 }
33142}
33143var fakeActCallbackNode = {}; // $FlowFixMe[missing-local-annot]
33144
33145function scheduleCallback(priorityLevel, callback) {
33146 {
33147 // If we're currently inside an `act` scope, bypass Scheduler and push to
33148 // the `act` queue instead.
33149 var actQueue = ReactSharedInternals.actQueue;
33150
33151 if (actQueue !== null) {
33152 actQueue.push(callback);
33153 return fakeActCallbackNode;
33154 } else {
33155 return scheduleCallback$3(priorityLevel, callback);
33156 }
33157 }
33158}
33159
33160function shouldForceFlushFallbacksInDEV() {
33161 // Never force flush in production. This function should get stripped out.
33162 return ReactSharedInternals.actQueue !== null;
33163}
33164
33165function warnIfUpdatesNotWrappedWithActDEV(fiber) {
33166 {
33167 {
33168 if (!isConcurrentActEnvironment()) {
33169 // Not in an act environment. No need to warn.
33170 return;
33171 }
33172 }
33173
33174 if (ReactSharedInternals.actQueue === null) {
33175 var previousFiber = current;
33176
33177 try {
33178 setCurrentFiber(fiber);
33179
33180 error('An update to %s inside a test was not wrapped in act(...).\n\n' + 'When testing, code that causes React state updates should be ' + 'wrapped into act(...):\n\n' + 'act(() => {\n' + ' /* fire events that update state */\n' + '});\n' + '/* assert on the output */\n\n' + "This ensures that you're testing the behavior the user would see " + 'in the browser.' + ' Learn more at https://react.dev/link/wrap-tests-with-act', getComponentNameFromFiber(fiber));
33181 } finally {
33182 if (previousFiber) {
33183 setCurrentFiber(fiber);
33184 } else {
33185 resetCurrentFiber();
33186 }
33187 }
33188 }
33189 }
33190}
33191
33192function warnIfSuspenseResolutionNotWrappedWithActDEV(root) {
33193 {
33194 if (isConcurrentActEnvironment() && ReactSharedInternals.actQueue === null) {
33195 error('A suspended resource finished loading inside a test, but the event ' + 'was not wrapped in act(...).\n\n' + 'When testing, code that resolves suspended data should be wrapped ' + 'into act(...):\n\n' + 'act(() => {\n' + ' /* finish loading suspended data */\n' + '});\n' + '/* assert on the output */\n\n' + "This ensures that you're testing the behavior the user would see " + 'in the browser.' + ' Learn more at https://react.dev/link/wrap-tests-with-act');
33196 }
33197 }
33198}
33199
33200function setIsRunningInsertionEffect(isRunning) {
33201 {
33202 isRunningInsertionEffect = isRunning;
33203 }
33204}
33205
33206var SUPPRESS_HYDRATION_WARNING = 'suppressHydrationWarning';
33207var SUSPENSE_START_DATA = '$';
33208var SUSPENSE_END_DATA = '/$';
33209var SUSPENSE_PENDING_START_DATA = '$?';
33210var SUSPENSE_FALLBACK_START_DATA = '$!';
33211var FORM_STATE_IS_MATCHING = 'F!';
33212var FORM_STATE_IS_NOT_MATCHING = 'F';
33213var STYLE = 'style';
33214var HostContextNamespaceNone = 0;
33215var HostContextNamespaceSvg = 1;
33216var HostContextNamespaceMath = 2;
33217var eventsEnabled = null;
33218var selectionInformation = null;
33219
33220function getOwnerDocumentFromRootContainer(rootContainerElement) {
33221 return rootContainerElement.nodeType === DOCUMENT_NODE ? rootContainerElement : rootContainerElement.ownerDocument;
33222}
33223
33224function getRootHostContext(rootContainerInstance) {
33225 var type;
33226 var context;
33227 var nodeType = rootContainerInstance.nodeType;
33228
33229 switch (nodeType) {
33230 case DOCUMENT_NODE:
33231 case DOCUMENT_FRAGMENT_NODE:
33232 {
33233 type = nodeType === DOCUMENT_NODE ? '#document' : '#fragment';
33234 var root = rootContainerInstance.documentElement;
33235
33236 if (root) {
33237 var namespaceURI = root.namespaceURI;
33238 context = namespaceURI ? getOwnHostContext(namespaceURI) : HostContextNamespaceNone;
33239 } else {
33240 context = HostContextNamespaceNone;
33241 }
33242
33243 break;
33244 }
33245
33246 default:
33247 {
33248 var container = nodeType === COMMENT_NODE ? rootContainerInstance.parentNode : rootContainerInstance;
33249 type = container.tagName;
33250 var _namespaceURI = container.namespaceURI;
33251
33252 if (!_namespaceURI) {
33253 switch (type) {
33254 case 'svg':
33255 context = HostContextNamespaceSvg;
33256 break;
33257
33258 case 'math':
33259 context = HostContextNamespaceMath;
33260 break;
33261
33262 default:
33263 context = HostContextNamespaceNone;
33264 break;
33265 }
33266 } else {
33267 var ownContext = getOwnHostContext(_namespaceURI);
33268 context = getChildHostContextProd(ownContext, type);
33269 }
33270
33271 break;
33272 }
33273 }
33274
33275 {
33276 var validatedTag = type.toLowerCase();
33277 var ancestorInfo = updatedAncestorInfoDev(null, validatedTag);
33278 return {
33279 context: context,
33280 ancestorInfo: ancestorInfo
33281 };
33282 }
33283}
33284
33285function getOwnHostContext(namespaceURI) {
33286 switch (namespaceURI) {
33287 case SVG_NAMESPACE:
33288 return HostContextNamespaceSvg;
33289
33290 case MATH_NAMESPACE:
33291 return HostContextNamespaceMath;
33292
33293 default:
33294 return HostContextNamespaceNone;
33295 }
33296}
33297
33298function getChildHostContextProd(parentNamespace, type) {
33299 if (parentNamespace === HostContextNamespaceNone) {
33300 // No (or default) parent namespace: potential entry point.
33301 switch (type) {
33302 case 'svg':
33303 return HostContextNamespaceSvg;
33304
33305 case 'math':
33306 return HostContextNamespaceMath;
33307
33308 default:
33309 return HostContextNamespaceNone;
33310 }
33311 }
33312
33313 if (parentNamespace === HostContextNamespaceSvg && type === 'foreignObject') {
33314 // We're leaving SVG.
33315 return HostContextNamespaceNone;
33316 } // By default, pass namespace below.
33317
33318
33319 return parentNamespace;
33320}
33321
33322function getChildHostContext(parentHostContext, type) {
33323 {
33324 var parentHostContextDev = parentHostContext;
33325 var context = getChildHostContextProd(parentHostContextDev.context, type);
33326 var ancestorInfo = updatedAncestorInfoDev(parentHostContextDev.ancestorInfo, type);
33327 return {
33328 context: context,
33329 ancestorInfo: ancestorInfo
33330 };
33331 }
33332}
33333function getPublicInstance(instance) {
33334 return instance;
33335}
33336function prepareForCommit(containerInfo) {
33337 eventsEnabled = isEnabled();
33338 selectionInformation = getSelectionInformation();
33339 var activeInstance = null;
33340
33341 setEnabled(false);
33342 return activeInstance;
33343}
33344function resetAfterCommit(containerInfo) {
33345 restoreSelection(selectionInformation);
33346 setEnabled(eventsEnabled);
33347 eventsEnabled = null;
33348 selectionInformation = null;
33349}
33350function createHoistableInstance(type, props, rootContainerInstance, internalInstanceHandle) {
33351 var ownerDocument = getOwnerDocumentFromRootContainer(rootContainerInstance);
33352 var domElement = ownerDocument.createElement(type);
33353 precacheFiberNode(internalInstanceHandle, domElement);
33354 updateFiberProps(domElement, props);
33355 setInitialProperties(domElement, type, props);
33356 markNodeAsHoistable(domElement);
33357 return domElement;
33358}
33359var warnedUnknownTags = {
33360 // There are working polyfills for <dialog>. Let people use it.
33361 dialog: true,
33362 // Electron ships a custom <webview> tag to display external web content in
33363 // an isolated frame and process.
33364 // This tag is not present in non Electron environments such as JSDom which
33365 // is often used for testing purposes.
33366 // @see https://electronjs.org/docs/api/webview-tag
33367 webview: true
33368};
33369function createInstance(type, props, rootContainerInstance, hostContext, internalInstanceHandle) {
33370 var hostContextProd;
33371
33372 {
33373 // TODO: take namespace into account when validating.
33374 var hostContextDev = hostContext;
33375 validateDOMNesting(type, hostContextDev.ancestorInfo);
33376 hostContextProd = hostContextDev.context;
33377 }
33378
33379 var ownerDocument = getOwnerDocumentFromRootContainer(rootContainerInstance);
33380 var domElement;
33381
33382 switch (hostContextProd) {
33383 case HostContextNamespaceSvg:
33384 domElement = ownerDocument.createElementNS(SVG_NAMESPACE, type);
33385 break;
33386
33387 case HostContextNamespaceMath:
33388 domElement = ownerDocument.createElementNS(MATH_NAMESPACE, type);
33389 break;
33390
33391 default:
33392 switch (type) {
33393 case 'svg':
33394 {
33395 domElement = ownerDocument.createElementNS(SVG_NAMESPACE, type);
33396 break;
33397 }
33398
33399 case 'math':
33400 {
33401 domElement = ownerDocument.createElementNS(MATH_NAMESPACE, type);
33402 break;
33403 }
33404
33405 case 'script':
33406 {
33407 // Create the script via .innerHTML so its "parser-inserted" flag is
33408 // set to true and it does not execute
33409 var div = ownerDocument.createElement('div');
33410
33411 div.innerHTML = '<script><' + '/script>'; // eslint-disable-line
33412 // This is guaranteed to yield a script element.
33413
33414 var firstChild = div.firstChild;
33415 domElement = div.removeChild(firstChild);
33416 break;
33417 }
33418
33419 case 'select':
33420 {
33421 if (typeof props.is === 'string') {
33422 domElement = ownerDocument.createElement('select', {
33423 is: props.is
33424 });
33425 } else {
33426 // Separate else branch instead of using `props.is || undefined` above because of a Firefox bug.
33427 // See discussion in https://github.com/facebook/react/pull/6896
33428 // and discussion in https://bugzilla.mozilla.org/show_bug.cgi?id=1276240
33429 domElement = ownerDocument.createElement('select');
33430 }
33431
33432 if (props.multiple) {
33433 domElement.multiple = true;
33434 } else if (props.size) {
33435 // Setting a size greater than 1 causes a select to behave like `multiple=true`, where
33436 // it is possible that no option is selected.
33437 //
33438 // This is only necessary when a select in "single selection mode".
33439 domElement.size = props.size;
33440 }
33441
33442 break;
33443 }
33444
33445 default:
33446 {
33447 if (typeof props.is === 'string') {
33448 domElement = ownerDocument.createElement(type, {
33449 is: props.is
33450 });
33451 } else {
33452 // Separate else branch instead of using `props.is || undefined` above because of a Firefox bug.
33453 // See discussion in https://github.com/facebook/react/pull/6896
33454 // and discussion in https://bugzilla.mozilla.org/show_bug.cgi?id=1276240
33455 domElement = ownerDocument.createElement(type);
33456 }
33457
33458 {
33459 if (type.indexOf('-') === -1) {
33460 // We're not SVG/MathML and we don't have a dash, so we're not a custom element
33461 // Even if you use `is`, these should be of known type and lower case.
33462 if (type !== type.toLowerCase()) {
33463 error('<%s /> is using incorrect casing. ' + 'Use PascalCase for React components, ' + 'or lowercase for HTML elements.', type);
33464 }
33465
33466 if ( // $FlowFixMe[method-unbinding]
33467 Object.prototype.toString.call(domElement) === '[object HTMLUnknownElement]' && !hasOwnProperty.call(warnedUnknownTags, type)) {
33468 warnedUnknownTags[type] = true;
33469
33470 error('The tag <%s> is unrecognized in this browser. ' + 'If you meant to render a React component, start its name with ' + 'an uppercase letter.', type);
33471 }
33472 }
33473 }
33474 }
33475 }
33476
33477 }
33478
33479 precacheFiberNode(internalInstanceHandle, domElement);
33480 updateFiberProps(domElement, props);
33481 return domElement;
33482}
33483function appendInitialChild(parentInstance, child) {
33484 parentInstance.appendChild(child);
33485}
33486function finalizeInitialChildren(domElement, type, props, hostContext) {
33487 setInitialProperties(domElement, type, props);
33488
33489 switch (type) {
33490 case 'button':
33491 case 'input':
33492 case 'select':
33493 case 'textarea':
33494 return !!props.autoFocus;
33495
33496 case 'img':
33497 return true;
33498
33499 default:
33500 return false;
33501 }
33502}
33503function shouldSetTextContent(type, props) {
33504 return type === 'textarea' || type === 'noscript' || typeof props.children === 'string' || typeof props.children === 'number' || typeof props.children === 'bigint' || typeof props.dangerouslySetInnerHTML === 'object' && props.dangerouslySetInnerHTML !== null && props.dangerouslySetInnerHTML.__html != null;
33505}
33506function createTextInstance(text, rootContainerInstance, hostContext, internalInstanceHandle) {
33507 {
33508 var hostContextDev = hostContext;
33509 var ancestor = hostContextDev.ancestorInfo.current;
33510
33511 if (ancestor != null) {
33512 validateTextNesting(text, ancestor.tag);
33513 }
33514 }
33515
33516 var textNode = getOwnerDocumentFromRootContainer(rootContainerInstance).createTextNode(text);
33517 precacheFiberNode(internalInstanceHandle, textNode);
33518 return textNode;
33519}
33520var currentPopstateTransitionEvent = null;
33521function shouldAttemptEagerTransition() {
33522 var event = window.event;
33523
33524 if (event && event.type === 'popstate') {
33525 // This is a popstate event. Attempt to render any transition during this
33526 // event synchronously. Unless we already attempted during this event.
33527 if (event === currentPopstateTransitionEvent) {
33528 // We already attempted to render this popstate transition synchronously.
33529 // Any subsequent attempts must have happened as the result of a derived
33530 // update, like startTransition inside useEffect, or useDV. Switch back to
33531 // the default behavior for all remaining transitions during the current
33532 // popstate event.
33533 return false;
33534 } else {
33535 // Cache the current event in case a derived transition is scheduled.
33536 // (Refer to previous branch.)
33537 currentPopstateTransitionEvent = event;
33538 return true;
33539 }
33540 } // We're not inside a popstate event.
33541
33542
33543 currentPopstateTransitionEvent = null;
33544 return false;
33545}
33546// if a component just imports ReactDOM (e.g. for findDOMNode).
33547// Some environments might not have setTimeout or clearTimeout.
33548
33549var scheduleTimeout = typeof setTimeout === 'function' ? setTimeout : undefined;
33550var cancelTimeout = typeof clearTimeout === 'function' ? clearTimeout : undefined;
33551var noTimeout = -1;
33552var localPromise = typeof Promise === 'function' ? Promise : undefined;
33553function preparePortalMount(portalInstance) {
33554 listenToAllSupportedEvents(portalInstance);
33555}
33556var scheduleMicrotask = typeof queueMicrotask === 'function' ? queueMicrotask : typeof localPromise !== 'undefined' ? function (callback) {
33557 return localPromise.resolve(null).then(callback).catch(handleErrorInNextTick);
33558} : scheduleTimeout; // TODO: Determine the best fallback here.
33559
33560function handleErrorInNextTick(error) {
33561 setTimeout(function () {
33562 throw error;
33563 });
33564} // -------------------
33565function commitMount(domElement, type, newProps, internalInstanceHandle) {
33566 // Despite the naming that might imply otherwise, this method only
33567 // fires if there is an `Update` effect scheduled during mounting.
33568 // This happens if `finalizeInitialChildren` returns `true` (which it
33569 // does to implement the `autoFocus` attribute on the client). But
33570 // there are also other cases when this might happen (such as patching
33571 // up text content during hydration mismatch). So we'll check this again.
33572 switch (type) {
33573 case 'button':
33574 case 'input':
33575 case 'select':
33576 case 'textarea':
33577 if (newProps.autoFocus) {
33578 domElement.focus();
33579 }
33580
33581 return;
33582
33583 case 'img':
33584 {
33585 if (newProps.src) {
33586 domElement.src = newProps.src;
33587 }
33588
33589 return;
33590 }
33591 }
33592}
33593function commitUpdate(domElement, type, oldProps, newProps, internalInstanceHandle) {
33594 // Diff and update the properties.
33595 updateProperties(domElement, type, oldProps, newProps); // Update the props handle so that we know which props are the ones with
33596 // with current event handlers.
33597
33598 updateFiberProps(domElement, newProps);
33599}
33600function resetTextContent(domElement) {
33601 setTextContent(domElement, '');
33602}
33603function commitTextUpdate(textInstance, oldText, newText) {
33604 textInstance.nodeValue = newText;
33605}
33606function appendChild(parentInstance, child) {
33607 parentInstance.appendChild(child);
33608}
33609function appendChildToContainer(container, child) {
33610 var parentNode;
33611
33612 if (container.nodeType === COMMENT_NODE) {
33613 parentNode = container.parentNode;
33614 parentNode.insertBefore(child, container);
33615 } else {
33616 parentNode = container;
33617 parentNode.appendChild(child);
33618 } // This container might be used for a portal.
33619 // If something inside a portal is clicked, that click should bubble
33620 // through the React tree. However, on Mobile Safari the click would
33621 // never bubble through the *DOM* tree unless an ancestor with onclick
33622 // event exists. So we wouldn't see it and dispatch it.
33623 // This is why we ensure that non React root containers have inline onclick
33624 // defined.
33625 // https://github.com/facebook/react/issues/11918
33626
33627
33628 var reactRootContainer = container._reactRootContainer;
33629
33630 if ((reactRootContainer === null || reactRootContainer === undefined) && parentNode.onclick === null) {
33631 // TODO: This cast may not be sound for SVG, MathML or custom elements.
33632 trapClickOnNonInteractiveElement(parentNode);
33633 }
33634}
33635function insertBefore(parentInstance, child, beforeChild) {
33636 parentInstance.insertBefore(child, beforeChild);
33637}
33638function insertInContainerBefore(container, child, beforeChild) {
33639 if (container.nodeType === COMMENT_NODE) {
33640 container.parentNode.insertBefore(child, beforeChild);
33641 } else {
33642 container.insertBefore(child, beforeChild);
33643 }
33644}
33645
33646function removeChild(parentInstance, child) {
33647 parentInstance.removeChild(child);
33648}
33649function removeChildFromContainer(container, child) {
33650 if (container.nodeType === COMMENT_NODE) {
33651 container.parentNode.removeChild(child);
33652 } else {
33653 container.removeChild(child);
33654 }
33655}
33656function clearSuspenseBoundary(parentInstance, suspenseInstance) {
33657 var node = suspenseInstance; // Delete all nodes within this suspense boundary.
33658 // There might be nested nodes so we need to keep track of how
33659 // deep we are and only break out when we're back on top.
33660
33661 var depth = 0;
33662
33663 do {
33664 var nextNode = node.nextSibling;
33665 parentInstance.removeChild(node);
33666
33667 if (nextNode && nextNode.nodeType === COMMENT_NODE) {
33668 var data = nextNode.data;
33669
33670 if (data === SUSPENSE_END_DATA) {
33671 if (depth === 0) {
33672 parentInstance.removeChild(nextNode); // Retry if any event replaying was blocked on this.
33673
33674 retryIfBlockedOn(suspenseInstance);
33675 return;
33676 } else {
33677 depth--;
33678 }
33679 } else if (data === SUSPENSE_START_DATA || data === SUSPENSE_PENDING_START_DATA || data === SUSPENSE_FALLBACK_START_DATA) {
33680 depth++;
33681 }
33682 } // $FlowFixMe[incompatible-type] we bail out when we get a null
33683
33684
33685 node = nextNode;
33686 } while (node); // TODO: Warn, we didn't find the end comment boundary.
33687 // Retry if any event replaying was blocked on this.
33688
33689
33690 retryIfBlockedOn(suspenseInstance);
33691}
33692function clearSuspenseBoundaryFromContainer(container, suspenseInstance) {
33693 if (container.nodeType === COMMENT_NODE) {
33694 clearSuspenseBoundary(container.parentNode, suspenseInstance);
33695 } else if (container.nodeType === ELEMENT_NODE) {
33696 clearSuspenseBoundary(container, suspenseInstance);
33697 } else ; // Retry if any event replaying was blocked on this.
33698
33699
33700 retryIfBlockedOn(container);
33701}
33702function hideInstance(instance) {
33703 // TODO: Does this work for all element types? What about MathML? Should we
33704 // pass host context to this method?
33705 instance = instance;
33706 var style = instance.style; // $FlowFixMe[method-unbinding]
33707
33708 if (typeof style.setProperty === 'function') {
33709 style.setProperty('display', 'none', 'important');
33710 } else {
33711 style.display = 'none';
33712 }
33713}
33714function hideTextInstance(textInstance) {
33715 textInstance.nodeValue = '';
33716}
33717function unhideInstance(instance, props) {
33718 instance = instance;
33719 var styleProp = props[STYLE];
33720 var display = styleProp !== undefined && styleProp !== null && styleProp.hasOwnProperty('display') ? styleProp.display : null;
33721 instance.style.display = display == null || typeof display === 'boolean' ? '' : // The value would've errored already if it wasn't safe.
33722 // eslint-disable-next-line react-internal/safe-string-coercion
33723 ('' + display).trim();
33724}
33725function unhideTextInstance(textInstance, text) {
33726 textInstance.nodeValue = text;
33727}
33728function clearContainer(container) {
33729 var nodeType = container.nodeType;
33730
33731 if (nodeType === DOCUMENT_NODE) {
33732 clearContainerSparingly(container);
33733 } else if (nodeType === ELEMENT_NODE) {
33734 switch (container.nodeName) {
33735 case 'HEAD':
33736 case 'HTML':
33737 case 'BODY':
33738 clearContainerSparingly(container);
33739 return;
33740
33741 default:
33742 {
33743 container.textContent = '';
33744 }
33745 }
33746 }
33747}
33748
33749function clearContainerSparingly(container) {
33750 var node;
33751 var nextNode = container.firstChild;
33752
33753 if (nextNode && nextNode.nodeType === DOCUMENT_TYPE_NODE) {
33754 nextNode = nextNode.nextSibling;
33755 }
33756
33757 while (nextNode) {
33758 node = nextNode;
33759 nextNode = nextNode.nextSibling;
33760
33761 switch (node.nodeName) {
33762 case 'HTML':
33763 case 'HEAD':
33764 case 'BODY':
33765 {
33766 var element = node;
33767 clearContainerSparingly(element); // If these singleton instances had previously been rendered with React they
33768 // may still hold on to references to the previous fiber tree. We detatch them
33769 // prospectively to reset them to a baseline starting state since we cannot create
33770 // new instances.
33771
33772 detachDeletedInstance(element);
33773 continue;
33774 }
33775 // Script tags are retained to avoid an edge case bug. Normally scripts will execute if they
33776 // are ever inserted into the DOM. However when streaming if a script tag is opened but not
33777 // yet closed some browsers create and insert the script DOM Node but the script cannot execute
33778 // yet until the closing tag is parsed. If something causes React to call clearContainer while
33779 // this DOM node is in the document but not yet executable the DOM node will be removed from the
33780 // document and when the script closing tag comes in the script will not end up running. This seems
33781 // to happen in Chrome/Firefox but not Safari at the moment though this is not necessarily specified
33782 // behavior so it could change in future versions of browsers. While leaving all scripts is broader
33783 // than strictly necessary this is the least amount of additional code to avoid this breaking
33784 // edge case.
33785 //
33786 // Style tags are retained because they may likely come from 3rd party scripts and extensions
33787
33788 case 'SCRIPT':
33789 case 'STYLE':
33790 {
33791 continue;
33792 }
33793 // Stylesheet tags are retained because tehy may likely come from 3rd party scripts and extensions
33794
33795 case 'LINK':
33796 {
33797 if (node.rel.toLowerCase() === 'stylesheet') {
33798 continue;
33799 }
33800 }
33801 }
33802
33803 container.removeChild(node);
33804 }
33805
33806 return;
33807} // Making this so we can eventually move all of the instance caching to the commit phase.
33808function canHydrateInstance(instance, type, props, inRootOrSingleton) {
33809 while (instance.nodeType === ELEMENT_NODE) {
33810 var element = instance;
33811 var anyProps = props;
33812
33813 if (element.nodeName.toLowerCase() !== type.toLowerCase()) {
33814 if (!inRootOrSingleton) {
33815 // Usually we error for mismatched tags.
33816 if (element.nodeName === 'INPUT' && element.type === 'hidden') ; else {
33817 return null;
33818 }
33819 } // In root or singleton parents we skip past mismatched instances.
33820
33821 } else if (!inRootOrSingleton) {
33822 // Match
33823 if (type === 'input' && element.type === 'hidden') {
33824 {
33825 checkAttributeStringCoercion(anyProps.name, 'name');
33826 }
33827
33828 var name = anyProps.name == null ? null : '' + anyProps.name;
33829
33830 if (anyProps.type !== 'hidden' || element.getAttribute('name') !== name) ; else {
33831 return element;
33832 }
33833 } else {
33834 return element;
33835 }
33836 } else if (isMarkedHoistable(element)) ; else {
33837 // We have an Element with the right type.
33838 // We are going to try to exclude it if we can definitely identify it as a hoisted Node or if
33839 // we can guess that the node is likely hoisted or was inserted by a 3rd party script or browser extension
33840 // using high entropy attributes for certain types. This technique will fail for strange insertions like
33841 // extension prepending <div> in the <body> but that already breaks before and that is an edge case.
33842 switch (type) {
33843 // case 'title':
33844 //We assume all titles are matchable. You should only have one in the Document, at least in a hoistable scope
33845 // and if you are a HostComponent with type title we must either be in an <svg> context or this title must have an `itemProp` prop.
33846 case 'meta':
33847 {
33848 // The only way to opt out of hoisting meta tags is to give it an itemprop attribute. We assume there will be
33849 // not 3rd party meta tags that are prepended, accepting the cases where this isn't true because meta tags
33850 // are usually only functional for SSR so even in a rare case where we did bind to an injected tag the runtime
33851 // implications are minimal
33852 if (!element.hasAttribute('itemprop')) {
33853 // This is a Hoistable
33854 break;
33855 }
33856
33857 return element;
33858 }
33859
33860 case 'link':
33861 {
33862 // Links come in many forms and we do expect 3rd parties to inject them into <head> / <body>. We exclude known resources
33863 // and then use high-entroy attributes like href which are almost always used and almost always unique to filter out unlikely
33864 // matches.
33865 var rel = element.getAttribute('rel');
33866
33867 if (rel === 'stylesheet' && element.hasAttribute('data-precedence')) {
33868 // This is a stylesheet resource
33869 break;
33870 } else if (rel !== anyProps.rel || element.getAttribute('href') !== (anyProps.href == null ? null : anyProps.href) || element.getAttribute('crossorigin') !== (anyProps.crossOrigin == null ? null : anyProps.crossOrigin) || element.getAttribute('title') !== (anyProps.title == null ? null : anyProps.title)) {
33871 // rel + href should usually be enough to uniquely identify a link however crossOrigin can vary for rel preconnect
33872 // and title could vary for rel alternate
33873 break;
33874 }
33875
33876 return element;
33877 }
33878
33879 case 'style':
33880 {
33881 // Styles are hard to match correctly. We can exclude known resources but otherwise we accept the fact that a non-hoisted style tags
33882 // in <head> or <body> are likely never going to be unmounted given their position in the document and the fact they likely hold global styles
33883 if (element.hasAttribute('data-precedence')) {
33884 // This is a style resource
33885 break;
33886 }
33887
33888 return element;
33889 }
33890
33891 case 'script':
33892 {
33893 // Scripts are a little tricky, we exclude known resources and then similar to links try to use high-entropy attributes
33894 // to reject poor matches. One challenge with scripts are inline scripts. We don't attempt to check text content which could
33895 // in theory lead to a hydration error later if a 3rd party injected an inline script before the React rendered nodes.
33896 // Falling back to client rendering if this happens should be seemless though so we will try this hueristic and revisit later
33897 // if we learn it is problematic
33898 var srcAttr = element.getAttribute('src');
33899
33900 if (srcAttr !== (anyProps.src == null ? null : anyProps.src) || element.getAttribute('type') !== (anyProps.type == null ? null : anyProps.type) || element.getAttribute('crossorigin') !== (anyProps.crossOrigin == null ? null : anyProps.crossOrigin)) {
33901 // This script is for a different src/type/crossOrigin. It may be a script resource
33902 // or it may just be a mistmatch
33903 if (srcAttr && element.hasAttribute('async') && !element.hasAttribute('itemprop')) {
33904 // This is an async script resource
33905 break;
33906 }
33907 }
33908
33909 return element;
33910 }
33911
33912 default:
33913 {
33914 // We have excluded the most likely cases of mismatch between hoistable tags, 3rd party script inserted tags,
33915 // and browser extension inserted tags. While it is possible this is not the right match it is a decent hueristic
33916 // that should work in the vast majority of cases.
33917 return element;
33918 }
33919 }
33920 }
33921
33922 var nextInstance = getNextHydratableSibling(element);
33923
33924 if (nextInstance === null) {
33925 break;
33926 }
33927
33928 instance = nextInstance;
33929 } // This is a suspense boundary or Text node or we got the end.
33930 // Suspense Boundaries are never expected to be injected by 3rd parties. If we see one it should be matched
33931 // and this is a hydration error.
33932 // Text Nodes are also not expected to be injected by 3rd parties. This is less of a guarantee for <body>
33933 // but it seems reasonable and conservative to reject this as a hydration error as well
33934
33935
33936 return null;
33937}
33938function canHydrateTextInstance(instance, text, inRootOrSingleton) {
33939 // Empty strings are not parsed by HTML so there won't be a correct match here.
33940 if (text === '') return null;
33941
33942 while (instance.nodeType !== TEXT_NODE) {
33943 if (instance.nodeType === ELEMENT_NODE && instance.nodeName === 'INPUT' && instance.type === 'hidden') ; else if (!inRootOrSingleton) {
33944 return null;
33945 }
33946
33947 var nextInstance = getNextHydratableSibling(instance);
33948
33949 if (nextInstance === null) {
33950 return null;
33951 }
33952
33953 instance = nextInstance;
33954 } // This has now been refined to a text node.
33955
33956
33957 return instance;
33958}
33959function canHydrateSuspenseInstance(instance, inRootOrSingleton) {
33960 while (instance.nodeType !== COMMENT_NODE) {
33961 if (!inRootOrSingleton) {
33962 return null;
33963 }
33964
33965 var nextInstance = getNextHydratableSibling(instance);
33966
33967 if (nextInstance === null) {
33968 return null;
33969 }
33970
33971 instance = nextInstance;
33972 } // This has now been refined to a suspense node.
33973
33974
33975 return instance;
33976}
33977function isSuspenseInstancePending(instance) {
33978 return instance.data === SUSPENSE_PENDING_START_DATA;
33979}
33980function isSuspenseInstanceFallback(instance) {
33981 return instance.data === SUSPENSE_FALLBACK_START_DATA;
33982}
33983function getSuspenseInstanceFallbackErrorDetails(instance) {
33984 var dataset = instance.nextSibling && instance.nextSibling.dataset;
33985 var digest, message, stack, componentStack;
33986
33987 if (dataset) {
33988 digest = dataset.dgst;
33989
33990 {
33991 message = dataset.msg;
33992 stack = dataset.stck;
33993 componentStack = dataset.cstck;
33994 }
33995 }
33996
33997 {
33998 return {
33999 message: message,
34000 digest: digest,
34001 stack: stack,
34002 componentStack: componentStack
34003 };
34004 }
34005}
34006function registerSuspenseInstanceRetry(instance, callback) {
34007 instance._reactRetry = callback;
34008}
34009function canHydrateFormStateMarker(instance, inRootOrSingleton) {
34010 while (instance.nodeType !== COMMENT_NODE) {
34011 if (!inRootOrSingleton) {
34012 return null;
34013 }
34014
34015 var nextInstance = getNextHydratableSibling(instance);
34016
34017 if (nextInstance === null) {
34018 return null;
34019 }
34020
34021 instance = nextInstance;
34022 }
34023
34024 var nodeData = instance.data;
34025
34026 if (nodeData === FORM_STATE_IS_MATCHING || nodeData === FORM_STATE_IS_NOT_MATCHING) {
34027 var markerInstance = instance;
34028 return markerInstance;
34029 }
34030
34031 return null;
34032}
34033function isFormStateMarkerMatching(markerInstance) {
34034 return markerInstance.data === FORM_STATE_IS_MATCHING;
34035}
34036
34037function getNextHydratable(node) {
34038 // Skip non-hydratable nodes.
34039 for (; node != null; node = node.nextSibling) {
34040 var nodeType = node.nodeType;
34041
34042 if (nodeType === ELEMENT_NODE || nodeType === TEXT_NODE) {
34043 break;
34044 }
34045
34046 if (nodeType === COMMENT_NODE) {
34047 var nodeData = node.data;
34048
34049 if (nodeData === SUSPENSE_START_DATA || nodeData === SUSPENSE_FALLBACK_START_DATA || nodeData === SUSPENSE_PENDING_START_DATA || (nodeData === FORM_STATE_IS_MATCHING || nodeData === FORM_STATE_IS_NOT_MATCHING)) {
34050 break;
34051 }
34052
34053 if (nodeData === SUSPENSE_END_DATA) {
34054 return null;
34055 }
34056 }
34057 }
34058
34059 return node;
34060}
34061
34062function getNextHydratableSibling(instance) {
34063 return getNextHydratable(instance.nextSibling);
34064}
34065function getFirstHydratableChild(parentInstance) {
34066 return getNextHydratable(parentInstance.firstChild);
34067}
34068function getFirstHydratableChildWithinContainer(parentContainer) {
34069 return getNextHydratable(parentContainer.firstChild);
34070}
34071function getFirstHydratableChildWithinSuspenseInstance(parentInstance) {
34072 return getNextHydratable(parentInstance.nextSibling);
34073}
34074function describeHydratableInstanceForDevWarnings(instance) {
34075 // Reverse engineer a pseudo react-element from hydratable instnace
34076 if (instance.nodeType === ELEMENT_NODE) {
34077 // Reverse engineer a set of props that can print for dev warnings
34078 return {
34079 type: instance.nodeName.toLowerCase(),
34080 props: getPropsFromElement(instance)
34081 };
34082 } else if (instance.nodeType === COMMENT_NODE) {
34083 return {
34084 type: 'Suspense',
34085 props: {}
34086 };
34087 } else {
34088 return instance.nodeValue;
34089 }
34090}
34091function validateHydratableInstance(type, props, hostContext) {
34092 {
34093 // TODO: take namespace into account when validating.
34094 var hostContextDev = hostContext;
34095 return validateDOMNesting(type, hostContextDev.ancestorInfo);
34096 }
34097}
34098function hydrateInstance(instance, type, props, hostContext, internalInstanceHandle) {
34099 precacheFiberNode(internalInstanceHandle, instance); // TODO: Possibly defer this until the commit phase where all the events
34100 // get attached.
34101
34102 updateFiberProps(instance, props);
34103 return hydrateProperties(instance, type, props);
34104} // Returns a Map of properties that were different on the server.
34105
34106function diffHydratedPropsForDevWarnings(instance, type, props, hostContext) {
34107 return diffHydratedProperties(instance, type, props, hostContext);
34108}
34109function validateHydratableTextInstance(text, hostContext) {
34110 {
34111 var hostContextDev = hostContext;
34112 var ancestor = hostContextDev.ancestorInfo.current;
34113
34114 if (ancestor != null) {
34115 return validateTextNesting(text, ancestor.tag);
34116 }
34117 }
34118
34119 return true;
34120}
34121function hydrateTextInstance(textInstance, text, internalInstanceHandle, parentInstanceProps) {
34122 precacheFiberNode(internalInstanceHandle, textInstance);
34123 return hydrateText(textInstance, text, parentInstanceProps);
34124} // Returns the server text if it differs from the client.
34125
34126function diffHydratedTextForDevWarnings(textInstance, text, parentProps) {
34127 if (parentProps === null || parentProps[SUPPRESS_HYDRATION_WARNING] !== true) {
34128 return diffHydratedText(textInstance, text);
34129 }
34130
34131 return null;
34132}
34133function hydrateSuspenseInstance(suspenseInstance, internalInstanceHandle) {
34134 precacheFiberNode(internalInstanceHandle, suspenseInstance);
34135}
34136function getNextHydratableInstanceAfterSuspenseInstance(suspenseInstance) {
34137 var node = suspenseInstance.nextSibling; // Skip past all nodes within this suspense boundary.
34138 // There might be nested nodes so we need to keep track of how
34139 // deep we are and only break out when we're back on top.
34140
34141 var depth = 0;
34142
34143 while (node) {
34144 if (node.nodeType === COMMENT_NODE) {
34145 var data = node.data;
34146
34147 if (data === SUSPENSE_END_DATA) {
34148 if (depth === 0) {
34149 return getNextHydratableSibling(node);
34150 } else {
34151 depth--;
34152 }
34153 } else if (data === SUSPENSE_START_DATA || data === SUSPENSE_FALLBACK_START_DATA || data === SUSPENSE_PENDING_START_DATA) {
34154 depth++;
34155 }
34156 }
34157
34158 node = node.nextSibling;
34159 } // TODO: Warn, we didn't find the end comment boundary.
34160
34161
34162 return null;
34163} // Returns the SuspenseInstance if this node is a direct child of a
34164// SuspenseInstance. I.e. if its previous sibling is a Comment with
34165// SUSPENSE_x_START_DATA. Otherwise, null.
34166
34167function getParentSuspenseInstance(targetInstance) {
34168 var node = targetInstance.previousSibling; // Skip past all nodes within this suspense boundary.
34169 // There might be nested nodes so we need to keep track of how
34170 // deep we are and only break out when we're back on top.
34171
34172 var depth = 0;
34173
34174 while (node) {
34175 if (node.nodeType === COMMENT_NODE) {
34176 var data = node.data;
34177
34178 if (data === SUSPENSE_START_DATA || data === SUSPENSE_FALLBACK_START_DATA || data === SUSPENSE_PENDING_START_DATA) {
34179 if (depth === 0) {
34180 return node;
34181 } else {
34182 depth--;
34183 }
34184 } else if (data === SUSPENSE_END_DATA) {
34185 depth++;
34186 }
34187 }
34188
34189 node = node.previousSibling;
34190 }
34191
34192 return null;
34193}
34194function commitHydratedContainer(container) {
34195 // Retry if any event replaying was blocked on this.
34196 retryIfBlockedOn(container);
34197}
34198function commitHydratedSuspenseInstance(suspenseInstance) {
34199 // Retry if any event replaying was blocked on this.
34200 retryIfBlockedOn(suspenseInstance);
34201}
34202function shouldDeleteUnhydratedTailInstances(parentType) {
34203 return parentType !== 'form' && parentType !== 'button';
34204} // -------------------
34205function isHostSingletonType(type) {
34206 return type === 'html' || type === 'head' || type === 'body';
34207}
34208function resolveSingletonInstance(type, props, rootContainerInstance, hostContext, validateDOMNestingDev) {
34209 {
34210 var hostContextDev = hostContext;
34211
34212 if (validateDOMNestingDev) {
34213 validateDOMNesting(type, hostContextDev.ancestorInfo);
34214 }
34215 }
34216
34217 var ownerDocument = getOwnerDocumentFromRootContainer(rootContainerInstance);
34218
34219 switch (type) {
34220 case 'html':
34221 {
34222 var documentElement = ownerDocument.documentElement;
34223
34224 if (!documentElement) {
34225 throw new Error('React expected an <html> element (document.documentElement) to exist in the Document but one was' + ' not found. React never removes the documentElement for any Document it renders into so' + ' the cause is likely in some other script running on this page.');
34226 }
34227
34228 return documentElement;
34229 }
34230
34231 case 'head':
34232 {
34233 var head = ownerDocument.head;
34234
34235 if (!head) {
34236 throw new Error('React expected a <head> element (document.head) to exist in the Document but one was' + ' not found. React never removes the head for any Document it renders into so' + ' the cause is likely in some other script running on this page.');
34237 }
34238
34239 return head;
34240 }
34241
34242 case 'body':
34243 {
34244 var body = ownerDocument.body;
34245
34246 if (!body) {
34247 throw new Error('React expected a <body> element (document.body) to exist in the Document but one was' + ' not found. React never removes the body for any Document it renders into so' + ' the cause is likely in some other script running on this page.');
34248 }
34249
34250 return body;
34251 }
34252
34253 default:
34254 {
34255 throw new Error('resolveSingletonInstance was called with an element type that is not supported. This is a bug in React.');
34256 }
34257 }
34258}
34259function acquireSingletonInstance(type, props, instance, internalInstanceHandle) {
34260 {
34261 var currentInstanceHandle = getInstanceFromNode(instance);
34262
34263 if (currentInstanceHandle) {
34264 var tagName = instance.tagName.toLowerCase();
34265
34266 error('You are mounting a new %s component when a previous one has not first unmounted. It is an' + ' error to render more than one %s component at a time and attributes and children of these' + ' components will likely fail in unpredictable ways. Please only render a single instance of' + ' <%s> and if you need to mount a new one, ensure any previous ones have unmounted first.', tagName, tagName, tagName);
34267 }
34268
34269 switch (type) {
34270 case 'html':
34271 case 'head':
34272 case 'body':
34273 {
34274 break;
34275 }
34276
34277 default:
34278 {
34279 error('acquireSingletonInstance was called with an element type that is not supported. This is a bug in React.');
34280 }
34281 }
34282 }
34283
34284 var attributes = instance.attributes;
34285
34286 while (attributes.length) {
34287 instance.removeAttributeNode(attributes[0]);
34288 }
34289
34290 setInitialProperties(instance, type, props);
34291 precacheFiberNode(internalInstanceHandle, instance);
34292 updateFiberProps(instance, props);
34293}
34294function releaseSingletonInstance(instance) {
34295 var attributes = instance.attributes;
34296
34297 while (attributes.length) {
34298 instance.removeAttributeNode(attributes[0]);
34299 }
34300
34301 detachDeletedInstance(instance);
34302}
34303function clearSingleton(instance) {
34304 var element = instance;
34305 var node = element.firstChild;
34306
34307 while (node) {
34308 var nextNode = node.nextSibling;
34309 var nodeName = node.nodeName;
34310
34311 if (isMarkedHoistable(node) || nodeName === 'HEAD' || nodeName === 'BODY' || nodeName === 'SCRIPT' || nodeName === 'STYLE' || nodeName === 'LINK' && node.rel.toLowerCase() === 'stylesheet') ; else {
34312 element.removeChild(node);
34313 }
34314
34315 node = nextNode;
34316 }
34317
34318 return;
34319} // -------------------
34320var NotLoaded =
34321/* */
343220;
34323var Loaded =
34324/* */
343251;
34326var Errored =
34327/* */
343282;
34329var Settled =
34330/* */
343313;
34332var Inserted =
34333/* */
343344;
34335function prepareToCommitHoistables() {
34336 tagCaches = null;
34337} // global collections of Resources
34338
34339var preloadPropsMap = new Map();
34340var preconnectsSet = new Set(); // getRootNode is missing from IE and old jsdom versions
34341
34342function getHoistableRoot(container) {
34343 // $FlowFixMe[method-unbinding]
34344 return typeof container.getRootNode === 'function' ?
34345 /* $FlowFixMe[incompatible-return] Flow types this as returning a `Node`,
34346 * but it's either a `Document` or `ShadowRoot`. */
34347 container.getRootNode() : container.ownerDocument;
34348}
34349
34350function getCurrentResourceRoot() {
34351 var currentContainer = getCurrentRootHostContainer();
34352 return currentContainer ? getHoistableRoot(currentContainer) : null;
34353}
34354
34355function getDocumentFromRoot(root) {
34356 return root.ownerDocument || root;
34357}
34358
34359var previousDispatcher = ReactDOMSharedInternals.d;
34360/* ReactDOMCurrentDispatcher */
34361
34362ReactDOMSharedInternals.d
34363/* ReactDOMCurrentDispatcher */
34364= {
34365 f
34366 /* flushSyncWork */
34367 : flushSyncWork
34368 /* flushSyncWork */
34369 ,
34370 r: requestFormReset,
34371 D
34372 /* prefetchDNS */
34373 : prefetchDNS,
34374 C
34375 /* preconnect */
34376 : preconnect,
34377 L
34378 /* preload */
34379 : preload,
34380 m
34381 /* preloadModule */
34382 : preloadModule,
34383 X
34384 /* preinitScript */
34385 : preinitScript,
34386 S
34387 /* preinitStyle */
34388 : preinitStyle,
34389 M
34390 /* preinitModuleScript */
34391 : preinitModuleScript
34392};
34393
34394function flushSyncWork() {
34395 {
34396 var previousWasRendering = previousDispatcher.f();
34397 /* flushSyncWork */
34398
34399 var wasRendering = flushSyncWork$1(); // Since multiple dispatchers can flush sync work during a single flushSync call
34400 // we need to return true if any of them were rendering.
34401
34402 return previousWasRendering || wasRendering;
34403 }
34404}
34405
34406function requestFormReset(form) {
34407 var formInst = getInstanceFromNode(form);
34408
34409 if (formInst !== null && formInst.tag === HostComponent && formInst.type === 'form') {
34410 requestFormReset$1(formInst);
34411 } else {
34412 // This form was either not rendered by this React renderer (or it's an
34413 // invalid type). Try the next one.
34414 //
34415 // The last implementation in the sequence will throw an error.
34416 previousDispatcher.r(
34417 /* requestFormReset */
34418 form);
34419 }
34420} // We expect this to get inlined. It is a function mostly to communicate the special nature of
34421// how we resolve the HoistableRoot for ReactDOM.pre*() methods. Because we support calling
34422// these methods outside of render there is no way to know which Document or ShadowRoot is 'scoped'
34423// and so we have to fall back to something universal. Currently we just refer to the global document.
34424// This is notable because nowhere else in ReactDOM do we actually reference the global document or window
34425// because we may be rendering inside an iframe.
34426
34427
34428var globalDocument = typeof document === 'undefined' ? null : document;
34429
34430function getGlobalDocument() {
34431 return globalDocument;
34432}
34433
34434function preconnectAs(rel, href, crossOrigin) {
34435 var ownerDocument = getGlobalDocument();
34436
34437 if (ownerDocument && typeof href === 'string' && href) {
34438 var limitedEscapedHref = escapeSelectorAttributeValueInsideDoubleQuotes(href);
34439 var key = "link[rel=\"" + rel + "\"][href=\"" + limitedEscapedHref + "\"]";
34440
34441 if (typeof crossOrigin === 'string') {
34442 key += "[crossorigin=\"" + crossOrigin + "\"]";
34443 }
34444
34445 if (!preconnectsSet.has(key)) {
34446 preconnectsSet.add(key);
34447 var preconnectProps = {
34448 rel: rel,
34449 crossOrigin: crossOrigin,
34450 href: href
34451 };
34452
34453 if (null === ownerDocument.querySelector(key)) {
34454 var instance = ownerDocument.createElement('link');
34455 setInitialProperties(instance, 'link', preconnectProps);
34456 markNodeAsHoistable(instance);
34457 ownerDocument.head.appendChild(instance);
34458 }
34459 }
34460 }
34461}
34462
34463function prefetchDNS(href) {
34464 previousDispatcher.D(
34465 /* prefetchDNS */
34466 href);
34467 preconnectAs('dns-prefetch', href, null);
34468}
34469
34470function preconnect(href, crossOrigin) {
34471 previousDispatcher.C(
34472 /* preconnect */
34473 href, crossOrigin);
34474 preconnectAs('preconnect', href, crossOrigin);
34475}
34476
34477function preload(href, as, options) {
34478 previousDispatcher.L(
34479 /* preload */
34480 href, as, options);
34481 var ownerDocument = getGlobalDocument();
34482
34483 if (ownerDocument && href && as) {
34484 var preloadSelector = "link[rel=\"preload\"][as=\"" + escapeSelectorAttributeValueInsideDoubleQuotes(as) + "\"]";
34485
34486 if (as === 'image') {
34487 if (options && options.imageSrcSet) {
34488 preloadSelector += "[imagesrcset=\"" + escapeSelectorAttributeValueInsideDoubleQuotes(options.imageSrcSet) + "\"]";
34489
34490 if (typeof options.imageSizes === 'string') {
34491 preloadSelector += "[imagesizes=\"" + escapeSelectorAttributeValueInsideDoubleQuotes(options.imageSizes) + "\"]";
34492 }
34493 } else {
34494 preloadSelector += "[href=\"" + escapeSelectorAttributeValueInsideDoubleQuotes(href) + "\"]";
34495 }
34496 } else {
34497 preloadSelector += "[href=\"" + escapeSelectorAttributeValueInsideDoubleQuotes(href) + "\"]";
34498 } // Some preloads are keyed under their selector. This happens when the preload is for
34499 // an arbitrary type. Other preloads are keyed under the resource key they represent a preload for.
34500 // Here we figure out which key to use to determine if we have a preload already.
34501
34502
34503 var key = preloadSelector;
34504
34505 switch (as) {
34506 case 'style':
34507 key = getStyleKey(href);
34508 break;
34509
34510 case 'script':
34511 key = getScriptKey(href);
34512 break;
34513 }
34514
34515 if (!preloadPropsMap.has(key)) {
34516 var preloadProps = assign({
34517 rel: 'preload',
34518 // There is a bug in Safari where imageSrcSet is not respected on preload links
34519 // so we omit the href here if we have imageSrcSet b/c safari will load the wrong image.
34520 // This harms older browers that do not support imageSrcSet by making their preloads not work
34521 // but this population is shrinking fast and is already small so we accept this tradeoff.
34522 href: as === 'image' && options && options.imageSrcSet ? undefined : href,
34523 as: as
34524 }, options);
34525
34526 preloadPropsMap.set(key, preloadProps);
34527
34528 if (null === ownerDocument.querySelector(preloadSelector)) {
34529 if (as === 'style' && ownerDocument.querySelector(getStylesheetSelectorFromKey(key))) {
34530 // We already have a stylesheet for this key. We don't need to preload it.
34531 return;
34532 } else if (as === 'script' && ownerDocument.querySelector(getScriptSelectorFromKey(key))) {
34533 // We already have a stylesheet for this key. We don't need to preload it.
34534 return;
34535 }
34536
34537 var instance = ownerDocument.createElement('link');
34538 setInitialProperties(instance, 'link', preloadProps);
34539 markNodeAsHoistable(instance);
34540 ownerDocument.head.appendChild(instance);
34541 }
34542 }
34543 }
34544}
34545
34546function preloadModule(href, options) {
34547 previousDispatcher.m(
34548 /* preloadModule */
34549 href, options);
34550 var ownerDocument = getGlobalDocument();
34551
34552 if (ownerDocument && href) {
34553 var as = options && typeof options.as === 'string' ? options.as : 'script';
34554 var preloadSelector = "link[rel=\"modulepreload\"][as=\"" + escapeSelectorAttributeValueInsideDoubleQuotes(as) + "\"][href=\"" + escapeSelectorAttributeValueInsideDoubleQuotes(href) + "\"]"; // Some preloads are keyed under their selector. This happens when the preload is for
34555 // an arbitrary type. Other preloads are keyed under the resource key they represent a preload for.
34556 // Here we figure out which key to use to determine if we have a preload already.
34557
34558 var key = preloadSelector;
34559
34560 switch (as) {
34561 case 'audioworklet':
34562 case 'paintworklet':
34563 case 'serviceworker':
34564 case 'sharedworker':
34565 case 'worker':
34566 case 'script':
34567 {
34568 key = getScriptKey(href);
34569 break;
34570 }
34571 }
34572
34573 if (!preloadPropsMap.has(key)) {
34574 var props = assign({
34575 rel: 'modulepreload',
34576 href: href
34577 }, options);
34578
34579 preloadPropsMap.set(key, props);
34580
34581 if (null === ownerDocument.querySelector(preloadSelector)) {
34582 switch (as) {
34583 case 'audioworklet':
34584 case 'paintworklet':
34585 case 'serviceworker':
34586 case 'sharedworker':
34587 case 'worker':
34588 case 'script':
34589 {
34590 if (ownerDocument.querySelector(getScriptSelectorFromKey(key))) {
34591 return;
34592 }
34593 }
34594 }
34595
34596 var instance = ownerDocument.createElement('link');
34597 setInitialProperties(instance, 'link', props);
34598 markNodeAsHoistable(instance);
34599 ownerDocument.head.appendChild(instance);
34600 }
34601 }
34602 }
34603}
34604
34605function preinitStyle(href, precedence, options) {
34606 previousDispatcher.S(
34607 /* preinitStyle */
34608 href, precedence, options);
34609 var ownerDocument = getGlobalDocument();
34610
34611 if (ownerDocument && href) {
34612 var styles = getResourcesFromRoot(ownerDocument).hoistableStyles;
34613 var key = getStyleKey(href);
34614 precedence = precedence || 'default'; // Check if this resource already exists
34615
34616 var resource = styles.get(key);
34617
34618 if (resource) {
34619 // We can early return. The resource exists and there is nothing
34620 // more to do
34621 return;
34622 }
34623
34624 var state = {
34625 loading: NotLoaded,
34626 preload: null
34627 }; // Attempt to hydrate instance from DOM
34628
34629 var instance = ownerDocument.querySelector(getStylesheetSelectorFromKey(key));
34630
34631 if (instance) {
34632 state.loading = Loaded | Inserted;
34633 } else {
34634 // Construct a new instance and insert it
34635 var stylesheetProps = assign({
34636 rel: 'stylesheet',
34637 href: href,
34638 'data-precedence': precedence
34639 }, options);
34640
34641 var preloadProps = preloadPropsMap.get(key);
34642
34643 if (preloadProps) {
34644 adoptPreloadPropsForStylesheet(stylesheetProps, preloadProps);
34645 }
34646
34647 var link = instance = ownerDocument.createElement('link');
34648 markNodeAsHoistable(link);
34649 setInitialProperties(link, 'link', stylesheetProps);
34650 link._p = new Promise(function (resolve, reject) {
34651 link.onload = resolve;
34652 link.onerror = reject;
34653 });
34654 link.addEventListener('load', function () {
34655 state.loading |= Loaded;
34656 });
34657 link.addEventListener('error', function () {
34658 state.loading |= Errored;
34659 });
34660 state.loading |= Inserted;
34661 insertStylesheet(instance, precedence, ownerDocument);
34662 } // Construct a Resource and cache it
34663
34664
34665 resource = {
34666 type: 'stylesheet',
34667 instance: instance,
34668 count: 1,
34669 state: state
34670 };
34671 styles.set(key, resource);
34672 return;
34673 }
34674}
34675
34676function preinitScript(src, options) {
34677 previousDispatcher.X(
34678 /* preinitScript */
34679 src, options);
34680 var ownerDocument = getGlobalDocument();
34681
34682 if (ownerDocument && src) {
34683 var scripts = getResourcesFromRoot(ownerDocument).hoistableScripts;
34684 var key = getScriptKey(src); // Check if this resource already exists
34685
34686 var resource = scripts.get(key);
34687
34688 if (resource) {
34689 // We can early return. The resource exists and there is nothing
34690 // more to do
34691 return;
34692 } // Attempt to hydrate instance from DOM
34693
34694
34695 var instance = ownerDocument.querySelector(getScriptSelectorFromKey(key));
34696
34697 if (!instance) {
34698 // Construct a new instance and insert it
34699 var scriptProps = assign({
34700 src: src,
34701 async: true
34702 }, options); // Adopt certain preload props
34703
34704
34705 var preloadProps = preloadPropsMap.get(key);
34706
34707 if (preloadProps) {
34708 adoptPreloadPropsForScript(scriptProps, preloadProps);
34709 }
34710
34711 instance = ownerDocument.createElement('script');
34712 markNodeAsHoistable(instance);
34713 setInitialProperties(instance, 'link', scriptProps);
34714 ownerDocument.head.appendChild(instance);
34715 } // Construct a Resource and cache it
34716
34717
34718 resource = {
34719 type: 'script',
34720 instance: instance,
34721 count: 1,
34722 state: null
34723 };
34724 scripts.set(key, resource);
34725 return;
34726 }
34727}
34728
34729function preinitModuleScript(src, options) {
34730 previousDispatcher.M(
34731 /* preinitModuleScript */
34732 src, options);
34733 var ownerDocument = getGlobalDocument();
34734
34735 if (ownerDocument && src) {
34736 var scripts = getResourcesFromRoot(ownerDocument).hoistableScripts;
34737 var key = getScriptKey(src); // Check if this resource already exists
34738
34739 var resource = scripts.get(key);
34740
34741 if (resource) {
34742 // We can early return. The resource exists and there is nothing
34743 // more to do
34744 return;
34745 } // Attempt to hydrate instance from DOM
34746
34747
34748 var instance = ownerDocument.querySelector(getScriptSelectorFromKey(key));
34749
34750 if (!instance) {
34751 // Construct a new instance and insert it
34752 var scriptProps = assign({
34753 src: src,
34754 async: true,
34755 type: 'module'
34756 }, options); // Adopt certain preload props
34757
34758
34759 var preloadProps = preloadPropsMap.get(key);
34760
34761 if (preloadProps) {
34762 adoptPreloadPropsForScript(scriptProps, preloadProps);
34763 }
34764
34765 instance = ownerDocument.createElement('script');
34766 markNodeAsHoistable(instance);
34767 setInitialProperties(instance, 'link', scriptProps);
34768 ownerDocument.head.appendChild(instance);
34769 } // Construct a Resource and cache it
34770
34771
34772 resource = {
34773 type: 'script',
34774 instance: instance,
34775 count: 1,
34776 state: null
34777 };
34778 scripts.set(key, resource);
34779 return;
34780 }
34781} // This function is called in begin work and we should always have a currentDocument set
34782
34783
34784function getResource(type, currentProps, pendingProps) {
34785 var resourceRoot = getCurrentResourceRoot();
34786
34787 if (!resourceRoot) {
34788 throw new Error('"resourceRoot" was expected to exist. This is a bug in React.');
34789 }
34790
34791 switch (type) {
34792 case 'meta':
34793 case 'title':
34794 {
34795 return null;
34796 }
34797
34798 case 'style':
34799 {
34800 if (typeof pendingProps.precedence === 'string' && typeof pendingProps.href === 'string') {
34801 var key = getStyleKey(pendingProps.href);
34802 var styles = getResourcesFromRoot(resourceRoot).hoistableStyles;
34803 var resource = styles.get(key);
34804
34805 if (!resource) {
34806 resource = {
34807 type: 'style',
34808 instance: null,
34809 count: 0,
34810 state: null
34811 };
34812 styles.set(key, resource);
34813 }
34814
34815 return resource;
34816 }
34817
34818 return {
34819 type: 'void',
34820 instance: null,
34821 count: 0,
34822 state: null
34823 };
34824 }
34825
34826 case 'link':
34827 {
34828 if (pendingProps.rel === 'stylesheet' && typeof pendingProps.href === 'string' && typeof pendingProps.precedence === 'string') {
34829 var qualifiedProps = pendingProps;
34830
34831 var _key = getStyleKey(qualifiedProps.href);
34832
34833 var _styles = getResourcesFromRoot(resourceRoot).hoistableStyles;
34834
34835 var _resource = _styles.get(_key);
34836
34837 if (!_resource) {
34838 // We asserted this above but Flow can't figure out that the type satisfies
34839 var ownerDocument = getDocumentFromRoot(resourceRoot);
34840 _resource = {
34841 type: 'stylesheet',
34842 instance: null,
34843 count: 0,
34844 state: {
34845 loading: NotLoaded,
34846 preload: null
34847 }
34848 };
34849
34850 _styles.set(_key, _resource);
34851
34852 if (!preloadPropsMap.has(_key)) {
34853 preloadStylesheet(ownerDocument, _key, preloadPropsFromStylesheet(qualifiedProps), _resource.state);
34854 }
34855 }
34856
34857 return _resource;
34858 }
34859
34860 return null;
34861 }
34862
34863 case 'script':
34864 {
34865 var async = pendingProps.async;
34866 var src = pendingProps.src;
34867
34868 if (typeof src === 'string' && async && typeof async !== 'function' && typeof async !== 'symbol') {
34869 var _key2 = getScriptKey(src);
34870
34871 var scripts = getResourcesFromRoot(resourceRoot).hoistableScripts;
34872
34873 var _resource2 = scripts.get(_key2);
34874
34875 if (!_resource2) {
34876 _resource2 = {
34877 type: 'script',
34878 instance: null,
34879 count: 0,
34880 state: null
34881 };
34882 scripts.set(_key2, _resource2);
34883 }
34884
34885 return _resource2;
34886 }
34887
34888 return {
34889 type: 'void',
34890 instance: null,
34891 count: 0,
34892 state: null
34893 };
34894 }
34895
34896 default:
34897 {
34898 throw new Error("getResource encountered a type it did not expect: \"" + type + "\". this is a bug in React.");
34899 }
34900 }
34901}
34902
34903function styleTagPropsFromRawProps(rawProps) {
34904 return assign({}, rawProps, {
34905 'data-href': rawProps.href,
34906 'data-precedence': rawProps.precedence,
34907 href: null,
34908 precedence: null
34909 });
34910}
34911
34912function getStyleKey(href) {
34913 var limitedEscapedHref = escapeSelectorAttributeValueInsideDoubleQuotes(href);
34914 return "href=\"" + limitedEscapedHref + "\"";
34915}
34916
34917function getStyleTagSelector(href) {
34918 var limitedEscapedHref = escapeSelectorAttributeValueInsideDoubleQuotes(href);
34919 return "style[data-href~=\"" + limitedEscapedHref + "\"]";
34920}
34921
34922function getStylesheetSelectorFromKey(key) {
34923 return "link[rel=\"stylesheet\"][" + key + "]";
34924}
34925
34926function getPreloadStylesheetSelectorFromKey(key) {
34927 return "link[rel=\"preload\"][as=\"style\"][" + key + "]";
34928}
34929
34930function stylesheetPropsFromRawProps(rawProps) {
34931 return assign({}, rawProps, {
34932 'data-precedence': rawProps.precedence,
34933 precedence: null
34934 });
34935}
34936
34937function preloadStylesheet(ownerDocument, key, preloadProps, state) {
34938 preloadPropsMap.set(key, preloadProps);
34939
34940 if (!ownerDocument.querySelector(getStylesheetSelectorFromKey(key))) {
34941 // There is no matching stylesheet instance in the Document.
34942 // We will insert a preload now to kick off loading because
34943 // we expect this stylesheet to commit
34944 var preloadEl = ownerDocument.querySelector(getPreloadStylesheetSelectorFromKey(key));
34945
34946 if (preloadEl) {
34947 // If we find a preload already it was SSR'd and we won't have an actual
34948 // loading state to track. For now we will just assume it is loaded
34949 state.loading = Loaded;
34950 } else {
34951 var instance = ownerDocument.createElement('link');
34952 state.preload = instance;
34953 instance.addEventListener('load', function () {
34954 return state.loading |= Loaded;
34955 });
34956 instance.addEventListener('error', function () {
34957 return state.loading |= Errored;
34958 });
34959 setInitialProperties(instance, 'link', preloadProps);
34960 markNodeAsHoistable(instance);
34961 ownerDocument.head.appendChild(instance);
34962 }
34963 }
34964}
34965
34966function preloadPropsFromStylesheet(props) {
34967 return {
34968 rel: 'preload',
34969 as: 'style',
34970 href: props.href,
34971 crossOrigin: props.crossOrigin,
34972 integrity: props.integrity,
34973 media: props.media,
34974 hrefLang: props.hrefLang,
34975 referrerPolicy: props.referrerPolicy
34976 };
34977}
34978
34979function getScriptKey(src) {
34980 var limitedEscapedSrc = escapeSelectorAttributeValueInsideDoubleQuotes(src);
34981 return "[src=\"" + limitedEscapedSrc + "\"]";
34982}
34983
34984function getScriptSelectorFromKey(key) {
34985 return 'script[async]' + key;
34986}
34987
34988function acquireResource(hoistableRoot, resource, props) {
34989 resource.count++;
34990
34991 if (resource.instance === null) {
34992 switch (resource.type) {
34993 case 'style':
34994 {
34995 var qualifiedProps = props; // Attempt to hydrate instance from DOM
34996
34997 var instance = hoistableRoot.querySelector(getStyleTagSelector(qualifiedProps.href));
34998
34999 if (instance) {
35000 resource.instance = instance;
35001 markNodeAsHoistable(instance);
35002 return instance;
35003 }
35004
35005 var styleProps = styleTagPropsFromRawProps(props);
35006 var ownerDocument = getDocumentFromRoot(hoistableRoot);
35007 instance = ownerDocument.createElement('style');
35008 markNodeAsHoistable(instance);
35009 setInitialProperties(instance, 'style', styleProps); // TODO: `style` does not have loading state for tracking insertions. I
35010 // guess because these aren't suspensey? Not sure whether this is a
35011 // factoring smell.
35012 // resource.state.loading |= Inserted;
35013
35014 insertStylesheet(instance, qualifiedProps.precedence, hoistableRoot);
35015 resource.instance = instance;
35016 return instance;
35017 }
35018
35019 case 'stylesheet':
35020 {
35021 // This typing is enforce by `getResource`. If we change the logic
35022 // there for what qualifies as a stylesheet resource we need to ensure
35023 // this cast still makes sense;
35024 var _qualifiedProps = props;
35025 var key = getStyleKey(_qualifiedProps.href); // Attempt to hydrate instance from DOM
35026
35027 var _instance = hoistableRoot.querySelector(getStylesheetSelectorFromKey(key));
35028
35029 if (_instance) {
35030 resource.state.loading |= Inserted;
35031 resource.instance = _instance;
35032 markNodeAsHoistable(_instance);
35033 return _instance;
35034 }
35035
35036 var stylesheetProps = stylesheetPropsFromRawProps(props);
35037 var preloadProps = preloadPropsMap.get(key);
35038
35039 if (preloadProps) {
35040 adoptPreloadPropsForStylesheet(stylesheetProps, preloadProps);
35041 } // Construct and insert a new instance
35042
35043
35044 var _ownerDocument = getDocumentFromRoot(hoistableRoot);
35045
35046 _instance = _ownerDocument.createElement('link');
35047 markNodeAsHoistable(_instance);
35048 var linkInstance = _instance;
35049 linkInstance._p = new Promise(function (resolve, reject) {
35050 linkInstance.onload = resolve;
35051 linkInstance.onerror = reject;
35052 });
35053 setInitialProperties(_instance, 'link', stylesheetProps);
35054 resource.state.loading |= Inserted;
35055 insertStylesheet(_instance, _qualifiedProps.precedence, hoistableRoot);
35056 resource.instance = _instance;
35057 return _instance;
35058 }
35059
35060 case 'script':
35061 {
35062 // This typing is enforce by `getResource`. If we change the logic
35063 // there for what qualifies as a stylesheet resource we need to ensure
35064 // this cast still makes sense;
35065 var borrowedScriptProps = props;
35066
35067 var _key3 = getScriptKey(borrowedScriptProps.src); // Attempt to hydrate instance from DOM
35068
35069
35070 var _instance2 = hoistableRoot.querySelector(getScriptSelectorFromKey(_key3));
35071
35072 if (_instance2) {
35073 resource.instance = _instance2;
35074 markNodeAsHoistable(_instance2);
35075 return _instance2;
35076 }
35077
35078 var scriptProps = borrowedScriptProps;
35079
35080 var _preloadProps = preloadPropsMap.get(_key3);
35081
35082 if (_preloadProps) {
35083 scriptProps = assign({}, borrowedScriptProps);
35084 adoptPreloadPropsForScript(scriptProps, _preloadProps);
35085 } // Construct and insert a new instance
35086
35087
35088 var _ownerDocument2 = getDocumentFromRoot(hoistableRoot);
35089
35090 _instance2 = _ownerDocument2.createElement('script');
35091 markNodeAsHoistable(_instance2);
35092 setInitialProperties(_instance2, 'link', scriptProps);
35093
35094 _ownerDocument2.head.appendChild(_instance2);
35095
35096 resource.instance = _instance2;
35097 return _instance2;
35098 }
35099
35100 case 'void':
35101 {
35102 return null;
35103 }
35104
35105 default:
35106 {
35107 throw new Error("acquireResource encountered a resource type it did not expect: \"" + resource.type + "\". this is a bug in React.");
35108 }
35109 }
35110 } else {
35111 // In the case of stylesheets, they might have already been assigned an
35112 // instance during `suspendResource`. But that doesn't mean they were
35113 // inserted, because the commit might have been interrupted. So we need to
35114 // check now.
35115 //
35116 // The other resource types are unaffected because they are not
35117 // yet suspensey.
35118 //
35119 // TODO: This is a bit of a code smell. Consider refactoring how
35120 // `suspendResource` and `acquireResource` work together. The idea is that
35121 // `suspendResource` does all the same stuff as `acquireResource` except
35122 // for the insertion.
35123 if (resource.type === 'stylesheet' && (resource.state.loading & Inserted) === NotLoaded) {
35124 var _qualifiedProps2 = props;
35125 var _instance3 = resource.instance;
35126 resource.state.loading |= Inserted;
35127 insertStylesheet(_instance3, _qualifiedProps2.precedence, hoistableRoot);
35128 }
35129 }
35130
35131 return resource.instance;
35132}
35133function releaseResource(resource) {
35134 resource.count--;
35135}
35136
35137function insertStylesheet(instance, precedence, root) {
35138 var nodes = root.querySelectorAll('link[rel="stylesheet"][data-precedence],style[data-precedence]');
35139 var last = nodes.length ? nodes[nodes.length - 1] : null;
35140 var prior = last;
35141
35142 for (var i = 0; i < nodes.length; i++) {
35143 var node = nodes[i];
35144 var nodePrecedence = node.dataset.precedence;
35145
35146 if (nodePrecedence === precedence) {
35147 prior = node;
35148 } else if (prior !== last) {
35149 break;
35150 }
35151 }
35152
35153 if (prior) {
35154 // We get the prior from the document so we know it is in the tree.
35155 // We also know that links can't be the topmost Node so the parentNode
35156 // must exist.
35157 prior.parentNode.insertBefore(instance, prior.nextSibling);
35158 } else {
35159 var parent = root.nodeType === DOCUMENT_NODE ? root.head : root;
35160 parent.insertBefore(instance, parent.firstChild);
35161 }
35162}
35163
35164function adoptPreloadPropsForStylesheet(stylesheetProps, preloadProps) {
35165 if (stylesheetProps.crossOrigin == null) stylesheetProps.crossOrigin = preloadProps.crossOrigin;
35166 if (stylesheetProps.referrerPolicy == null) stylesheetProps.referrerPolicy = preloadProps.referrerPolicy;
35167 if (stylesheetProps.title == null) stylesheetProps.title = preloadProps.title;
35168}
35169
35170function adoptPreloadPropsForScript(scriptProps, preloadProps) {
35171 if (scriptProps.crossOrigin == null) scriptProps.crossOrigin = preloadProps.crossOrigin;
35172 if (scriptProps.referrerPolicy == null) scriptProps.referrerPolicy = preloadProps.referrerPolicy;
35173 if (scriptProps.integrity == null) scriptProps.integrity = preloadProps.integrity;
35174}
35175
35176var tagCaches = null;
35177function hydrateHoistable(hoistableRoot, type, props, internalInstanceHandle) {
35178 var ownerDocument = getDocumentFromRoot(hoistableRoot);
35179 var instance = null;
35180
35181 getInstance: switch (type) {
35182 case 'title':
35183 {
35184 instance = ownerDocument.getElementsByTagName('title')[0];
35185
35186 if (!instance || isOwnedInstance(instance) || instance.namespaceURI === SVG_NAMESPACE || instance.hasAttribute('itemprop')) {
35187 instance = ownerDocument.createElement(type);
35188 ownerDocument.head.insertBefore(instance, ownerDocument.querySelector('head > title'));
35189 }
35190
35191 setInitialProperties(instance, type, props);
35192 precacheFiberNode(internalInstanceHandle, instance);
35193 markNodeAsHoistable(instance);
35194 return instance;
35195 }
35196
35197 case 'link':
35198 {
35199 var cache = getHydratableHoistableCache('link', 'href', ownerDocument);
35200 var key = type + (props.href || '');
35201 var maybeNodes = cache.get(key);
35202
35203 if (maybeNodes) {
35204 var nodes = maybeNodes;
35205
35206 for (var i = 0; i < nodes.length; i++) {
35207 var node = nodes[i];
35208
35209 if (node.getAttribute('href') !== (props.href == null ? null : props.href) || node.getAttribute('rel') !== (props.rel == null ? null : props.rel) || node.getAttribute('title') !== (props.title == null ? null : props.title) || node.getAttribute('crossorigin') !== (props.crossOrigin == null ? null : props.crossOrigin)) {
35210 // mismatch, try the next node;
35211 continue;
35212 }
35213
35214 instance = node;
35215 nodes.splice(i, 1);
35216 break getInstance;
35217 }
35218 }
35219
35220 instance = ownerDocument.createElement(type);
35221 setInitialProperties(instance, type, props);
35222 ownerDocument.head.appendChild(instance);
35223 break;
35224 }
35225
35226 case 'meta':
35227 {
35228 var _cache = getHydratableHoistableCache('meta', 'content', ownerDocument);
35229
35230 var _key4 = type + (props.content || '');
35231
35232 var _maybeNodes = _cache.get(_key4);
35233
35234 if (_maybeNodes) {
35235 var _nodes = _maybeNodes;
35236
35237 for (var _i = 0; _i < _nodes.length; _i++) {
35238 var _node = _nodes[_i]; // We coerce content to string because it is the most likely one to
35239 // use a `toString` capable value. For the rest we just do identity match
35240 // passing non-strings here is not really valid anyway.
35241
35242 {
35243 checkAttributeStringCoercion(props.content, 'content');
35244 }
35245
35246 if (_node.getAttribute('content') !== (props.content == null ? null : '' + props.content) || _node.getAttribute('name') !== (props.name == null ? null : props.name) || _node.getAttribute('property') !== (props.property == null ? null : props.property) || _node.getAttribute('http-equiv') !== (props.httpEquiv == null ? null : props.httpEquiv) || _node.getAttribute('charset') !== (props.charSet == null ? null : props.charSet)) {
35247 // mismatch, try the next node;
35248 continue;
35249 }
35250
35251 instance = _node;
35252
35253 _nodes.splice(_i, 1);
35254
35255 break getInstance;
35256 }
35257 }
35258
35259 instance = ownerDocument.createElement(type);
35260 setInitialProperties(instance, type, props);
35261 ownerDocument.head.appendChild(instance);
35262 break;
35263 }
35264
35265 default:
35266 throw new Error("getNodesForType encountered a type it did not expect: \"" + type + "\". This is a bug in React.");
35267 } // This node is a match
35268
35269
35270 precacheFiberNode(internalInstanceHandle, instance);
35271 markNodeAsHoistable(instance);
35272 return instance;
35273}
35274
35275function getHydratableHoistableCache(type, keyAttribute, ownerDocument) {
35276 var cache;
35277 var caches;
35278
35279 if (tagCaches === null) {
35280 cache = new Map();
35281 caches = tagCaches = new Map();
35282 caches.set(ownerDocument, cache);
35283 } else {
35284 caches = tagCaches;
35285 var maybeCache = caches.get(ownerDocument);
35286
35287 if (!maybeCache) {
35288 cache = new Map();
35289 caches.set(ownerDocument, cache);
35290 } else {
35291 cache = maybeCache;
35292 }
35293 }
35294
35295 if (cache.has(type)) {
35296 // We use type as a special key that signals that this cache has been seeded for this type
35297 return cache;
35298 } // Mark this cache as seeded for this type
35299
35300
35301 cache.set(type, null);
35302 var nodes = ownerDocument.getElementsByTagName(type);
35303
35304 for (var i = 0; i < nodes.length; i++) {
35305 var node = nodes[i];
35306
35307 if (!isOwnedInstance(node) && (type !== 'link' || node.getAttribute('rel') !== 'stylesheet') && node.namespaceURI !== SVG_NAMESPACE) {
35308 var nodeKey = node.getAttribute(keyAttribute) || '';
35309 var key = type + nodeKey;
35310 var existing = cache.get(key);
35311
35312 if (existing) {
35313 existing.push(node);
35314 } else {
35315 cache.set(key, [node]);
35316 }
35317 }
35318 }
35319
35320 return cache;
35321}
35322
35323function mountHoistable(hoistableRoot, type, instance) {
35324 var ownerDocument = getDocumentFromRoot(hoistableRoot);
35325 ownerDocument.head.insertBefore(instance, type === 'title' ? ownerDocument.querySelector('head > title') : null);
35326}
35327function unmountHoistable(instance) {
35328 instance.parentNode.removeChild(instance);
35329}
35330function isHostHoistableType(type, props, hostContext) {
35331 var outsideHostContainerContext;
35332 var hostContextProd;
35333
35334 {
35335 var hostContextDev = hostContext; // We can only render resources when we are not within the host container context
35336
35337 outsideHostContainerContext = !hostContextDev.ancestorInfo.containerTagInScope;
35338 hostContextProd = hostContextDev.context;
35339 } // Global opt out of hoisting for anything in SVG Namespace or anything with an itemProp inside an itemScope
35340
35341
35342 if (hostContextProd === HostContextNamespaceSvg || props.itemProp != null) {
35343 {
35344 if (outsideHostContainerContext && props.itemProp != null && (type === 'meta' || type === 'title' || type === 'style' || type === 'link' || type === 'script')) {
35345 error('Cannot render a <%s> outside the main document if it has an `itemProp` prop. `itemProp` suggests the tag belongs to an' + ' `itemScope` which can appear anywhere in the DOM. If you were intending for React to hoist this <%s> remove the `itemProp` prop.' + ' Otherwise, try moving this tag into the <head> or <body> of the Document.', type, type);
35346 }
35347 }
35348
35349 return false;
35350 }
35351
35352 switch (type) {
35353 case 'meta':
35354 case 'title':
35355 {
35356 return true;
35357 }
35358
35359 case 'style':
35360 {
35361 if (typeof props.precedence !== 'string' || typeof props.href !== 'string' || props.href === '') {
35362 {
35363 if (outsideHostContainerContext) {
35364 error('Cannot render a <style> outside the main document without knowing its precedence and a unique href key.' + ' React can hoist and deduplicate <style> tags if you provide a `precedence` prop along with an `href` prop that' + ' does not conflic with the `href` values used in any other hoisted <style> or <link rel="stylesheet" ...> tags. ' + ' Note that hoisting <style> tags is considered an advanced feature that most will not use directly.' + ' Consider moving the <style> tag to the <head> or consider adding a `precedence="default"` and `href="some unique resource identifier"`, or move the <style>' + ' to the <style> tag.');
35365 }
35366 }
35367
35368 return false;
35369 }
35370
35371 return true;
35372 }
35373
35374 case 'link':
35375 {
35376 if (typeof props.rel !== 'string' || typeof props.href !== 'string' || props.href === '' || props.onLoad || props.onError) {
35377 {
35378 if (props.rel === 'stylesheet' && typeof props.precedence === 'string') {
35379 validateLinkPropsForStyleResource(props);
35380 }
35381
35382 if (outsideHostContainerContext) {
35383 if (typeof props.rel !== 'string' || typeof props.href !== 'string' || props.href === '') {
35384 error('Cannot render a <link> outside the main document without a `rel` and `href` prop.' + ' Try adding a `rel` and/or `href` prop to this <link> or moving the link into the <head> tag');
35385 } else if (props.onError || props.onLoad) {
35386 error('Cannot render a <link> with onLoad or onError listeners outside the main document.' + ' Try removing onLoad={...} and onError={...} or moving it into the root <head> tag or' + ' somewhere in the <body>.');
35387 }
35388 }
35389 }
35390
35391 return false;
35392 }
35393
35394 switch (props.rel) {
35395 case 'stylesheet':
35396 {
35397 var precedence = props.precedence,
35398 disabled = props.disabled;
35399
35400 {
35401 if (typeof precedence !== 'string') {
35402 if (outsideHostContainerContext) {
35403 error('Cannot render a <link rel="stylesheet" /> outside the main document without knowing its precedence.' + ' Consider adding precedence="default" or moving it into the root <head> tag.');
35404 }
35405 }
35406 }
35407
35408 return typeof precedence === 'string' && disabled == null;
35409 }
35410
35411 default:
35412 {
35413 return true;
35414 }
35415 }
35416 }
35417
35418 case 'script':
35419 {
35420 var isAsync = props.async && typeof props.async !== 'function' && typeof props.async !== 'symbol';
35421
35422 if (!isAsync || props.onLoad || props.onError || !props.src || typeof props.src !== 'string') {
35423 {
35424 if (outsideHostContainerContext) {
35425 if (!isAsync) {
35426 error('Cannot render a sync or defer <script> outside the main document without knowing its order.' + ' Try adding async="" or moving it into the root <head> tag.');
35427 } else if (props.onLoad || props.onError) {
35428 error('Cannot render a <script> with onLoad or onError listeners outside the main document.' + ' Try removing onLoad={...} and onError={...} or moving it into the root <head> tag or' + ' somewhere in the <body>.');
35429 } else {
35430 error('Cannot render a <script> outside the main document without `async={true}` and a non-empty `src` prop.' + ' Ensure there is a valid `src` and either make the script async or move it into the root <head> tag or' + ' somewhere in the <body>.');
35431 }
35432 }
35433 }
35434
35435 return false;
35436 }
35437
35438 return true;
35439 }
35440
35441 case 'noscript':
35442 case 'template':
35443 {
35444 {
35445 if (outsideHostContainerContext) {
35446 error('Cannot render <%s> outside the main document. Try moving it into the root <head> tag.', type);
35447 }
35448 }
35449
35450 return false;
35451 }
35452 }
35453
35454 return false;
35455}
35456function mayResourceSuspendCommit(resource) {
35457 return resource.type === 'stylesheet' && (resource.state.loading & Inserted) === NotLoaded;
35458}
35459function preloadInstance(type, props) {
35460 // Return true to indicate it's already loaded
35461 return true;
35462}
35463function preloadResource(resource) {
35464 if (resource.type === 'stylesheet' && (resource.state.loading & Settled) === NotLoaded) {
35465 // we have not finished loading the underlying stylesheet yet.
35466 return false;
35467 } // Return true to indicate it's already loaded
35468
35469
35470 return true;
35471}
35472var suspendedState = null; // We use a noop function when we begin suspending because if possible we want the
35473// waitfor step to finish synchronously. If it doesn't we'll return a function to
35474// provide the actual unsuspend function and that will get completed when the count
35475// hits zero or it will get cancelled if the root starts new work.
35476
35477function noop() {}
35478
35479function startSuspendingCommit() {
35480 suspendedState = {
35481 stylesheets: null,
35482 count: 0,
35483 unsuspend: noop
35484 };
35485}
35486function suspendResource(hoistableRoot, resource, props) {
35487 if (suspendedState === null) {
35488 throw new Error('Internal React Error: suspendedState null when it was expected to exists. Please report this as a React bug.');
35489 }
35490
35491 var state = suspendedState;
35492
35493 if (resource.type === 'stylesheet') {
35494 if (typeof props.media === 'string') {
35495 // If we don't currently match media we avoid suspending on this resource
35496 // and let it insert on the mutation path
35497 if (matchMedia(props.media).matches === false) {
35498 return;
35499 }
35500 }
35501
35502 if ((resource.state.loading & Inserted) === NotLoaded) {
35503 if (resource.instance === null) {
35504 var qualifiedProps = props;
35505 var key = getStyleKey(qualifiedProps.href); // Attempt to hydrate instance from DOM
35506
35507 var instance = hoistableRoot.querySelector(getStylesheetSelectorFromKey(key));
35508
35509 if (instance) {
35510 // If this instance has a loading state it came from the Fizz runtime.
35511 // If there is not loading state it is assumed to have been server rendered
35512 // as part of the preamble and therefore synchronously loaded. It could have
35513 // errored however which we still do not yet have a means to detect. For now
35514 // we assume it is loaded.
35515 var maybeLoadingState = instance._p;
35516
35517 if (maybeLoadingState !== null && typeof maybeLoadingState === 'object' && // $FlowFixMe[method-unbinding]
35518 typeof maybeLoadingState.then === 'function') {
35519 var loadingState = maybeLoadingState;
35520 state.count++;
35521 var ping = onUnsuspend.bind(state);
35522 loadingState.then(ping, ping);
35523 }
35524
35525 resource.state.loading |= Inserted;
35526 resource.instance = instance;
35527 markNodeAsHoistable(instance);
35528 return;
35529 }
35530
35531 var ownerDocument = getDocumentFromRoot(hoistableRoot);
35532 var stylesheetProps = stylesheetPropsFromRawProps(props);
35533 var preloadProps = preloadPropsMap.get(key);
35534
35535 if (preloadProps) {
35536 adoptPreloadPropsForStylesheet(stylesheetProps, preloadProps);
35537 } // Construct and insert a new instance
35538
35539
35540 instance = ownerDocument.createElement('link');
35541 markNodeAsHoistable(instance);
35542 var linkInstance = instance; // This Promise is a loading state used by the Fizz runtime. We need this incase there is a race
35543 // between this resource being rendered on the client and being rendered with a late completed boundary.
35544
35545 linkInstance._p = new Promise(function (resolve, reject) {
35546 linkInstance.onload = resolve;
35547 linkInstance.onerror = reject;
35548 });
35549 setInitialProperties(instance, 'link', stylesheetProps);
35550 resource.instance = instance;
35551 }
35552
35553 if (state.stylesheets === null) {
35554 state.stylesheets = new Map();
35555 }
35556
35557 state.stylesheets.set(resource, hoistableRoot);
35558 var preloadEl = resource.state.preload;
35559
35560 if (preloadEl && (resource.state.loading & Settled) === NotLoaded) {
35561 state.count++;
35562
35563 var _ping = onUnsuspend.bind(state);
35564
35565 preloadEl.addEventListener('load', _ping);
35566 preloadEl.addEventListener('error', _ping);
35567 }
35568 }
35569 }
35570}
35571function waitForCommitToBeReady() {
35572 if (suspendedState === null) {
35573 throw new Error('Internal React Error: suspendedState null when it was expected to exists. Please report this as a React bug.');
35574 }
35575
35576 var state = suspendedState;
35577
35578 if (state.stylesheets && state.count === 0) {
35579 // We are not currently blocked but we have not inserted all stylesheets.
35580 // If this insertion happens and loads or errors synchronously then we can
35581 // avoid suspending the commit. To do this we check the count again immediately after
35582 insertSuspendedStylesheets(state, state.stylesheets);
35583 } // We need to check the count again because the inserted stylesheets may have led to new
35584 // tasks to wait on.
35585
35586
35587 if (state.count > 0) {
35588 return function (commit) {
35589 // We almost never want to show content before its styles have loaded. But
35590 // eventually we will give up and allow unstyled content. So this number is
35591 // somewhat arbitrary — big enough that you'd only reach it under
35592 // extreme circumstances.
35593 // TODO: Figure out what the browser engines do during initial page load and
35594 // consider aligning our behavior with that.
35595 var stylesheetTimer = setTimeout(function () {
35596 if (state.stylesheets) {
35597 insertSuspendedStylesheets(state, state.stylesheets);
35598 }
35599
35600 if (state.unsuspend) {
35601 var unsuspend = state.unsuspend;
35602 state.unsuspend = null;
35603 unsuspend();
35604 }
35605 }, 60000); // one minute
35606
35607 state.unsuspend = commit;
35608 return function () {
35609 state.unsuspend = null;
35610 clearTimeout(stylesheetTimer);
35611 };
35612 };
35613 }
35614
35615 return null;
35616}
35617
35618function onUnsuspend() {
35619 this.count--;
35620
35621 if (this.count === 0) {
35622 if (this.stylesheets) {
35623 // If we haven't actually inserted the stylesheets yet we need to do so now before starting the commit.
35624 // The reason we do this after everything else has finished is because we want to have all the stylesheets
35625 // load synchronously right before mutating. Ideally the new styles will cause a single recalc only on the
35626 // new tree. When we filled up stylesheets we only inlcuded stylesheets with matching media attributes so we
35627 // wait for them to load before actually continuing. We expect this to increase the count above zero
35628 insertSuspendedStylesheets(this, this.stylesheets);
35629 } else if (this.unsuspend) {
35630 var unsuspend = this.unsuspend;
35631 this.unsuspend = null;
35632 unsuspend();
35633 }
35634 }
35635} // We use a value that is type distinct from precedence to track which one is last.
35636// This ensures there is no collision with user defined precedences. Normally we would
35637// just track this in module scope but since the precedences are tracked per HoistableRoot
35638// we need to associate it to something other than a global scope hence why we try to
35639// colocate it with the map of precedences in the first place
35640
35641
35642var LAST_PRECEDENCE = null; // This is typecast to non-null because it will always be set before read.
35643// it is important that this not be used except when the stack guarantees it exists.
35644// Currentlyt his is only during insertSuspendedStylesheet.
35645
35646var precedencesByRoot = null;
35647
35648function insertSuspendedStylesheets(state, resources) {
35649 // We need to clear this out so we don't try to reinsert after the stylesheets have loaded
35650 state.stylesheets = null;
35651
35652 if (state.unsuspend === null) {
35653 // The suspended commit was cancelled. We don't need to insert any stylesheets.
35654 return;
35655 } // Temporarily increment count. we don't want any synchronously loaded stylesheets to try to unsuspend
35656 // before we finish inserting all stylesheets.
35657
35658
35659 state.count++;
35660 precedencesByRoot = new Map();
35661 resources.forEach(insertStylesheetIntoRoot, state);
35662 precedencesByRoot = null; // We can remove our temporary count and if we're still at zero we can unsuspend.
35663 // If we are in the synchronous phase before deciding if the commit should suspend and this
35664 // ends up hitting the unsuspend path it will just invoke the noop unsuspend.
35665
35666 onUnsuspend.call(state);
35667}
35668
35669function insertStylesheetIntoRoot(root, resource, map) {
35670 if (resource.state.loading & Inserted) {
35671 // This resource was inserted by another root committing. we don't need to insert it again
35672 return;
35673 }
35674
35675 var last;
35676 var precedences = precedencesByRoot.get(root);
35677
35678 if (!precedences) {
35679 precedences = new Map();
35680 precedencesByRoot.set(root, precedences);
35681 var nodes = root.querySelectorAll('link[data-precedence],style[data-precedence]');
35682
35683 for (var i = 0; i < nodes.length; i++) {
35684 var node = nodes[i];
35685
35686 if (node.nodeName === 'link' || // We omit style tags with media="not all" because they are not in the right position
35687 // and will be hoisted by the Fizz runtime imminently.
35688 node.getAttribute('media') !== 'not all') {
35689 precedences.set(node.dataset.precedence, node);
35690 last = node;
35691 }
35692 }
35693
35694 if (last) {
35695 precedences.set(LAST_PRECEDENCE, last);
35696 }
35697 } else {
35698 last = precedences.get(LAST_PRECEDENCE);
35699 } // We only call this after we have constructed an instance so we assume it here
35700
35701
35702 var instance = resource.instance; // We will always have a precedence for stylesheet instances
35703
35704 var precedence = instance.getAttribute('data-precedence');
35705 var prior = precedences.get(precedence) || last;
35706
35707 if (prior === last) {
35708 precedences.set(LAST_PRECEDENCE, instance);
35709 }
35710
35711 precedences.set(precedence, instance);
35712 this.count++;
35713 var onComplete = onUnsuspend.bind(this);
35714 instance.addEventListener('load', onComplete);
35715 instance.addEventListener('error', onComplete);
35716
35717 if (prior) {
35718 prior.parentNode.insertBefore(instance, prior.nextSibling);
35719 } else {
35720 var parent = root.nodeType === DOCUMENT_NODE ? root.head : root;
35721 parent.insertBefore(instance, parent.firstChild);
35722 }
35723
35724 resource.state.loading |= Inserted;
35725}
35726
35727var NotPendingTransition = NotPending;
35728function resetFormInstance(form) {
35729 form.reset();
35730}
35731
35732function FiberRootNode(containerInfo, // $FlowFixMe[missing-local-annot]
35733tag, hydrate, identifierPrefix, onUncaughtError, onCaughtError, onRecoverableError, formState) {
35734 this.tag = ConcurrentRoot ;
35735 this.containerInfo = containerInfo;
35736 this.pendingChildren = null;
35737 this.current = null;
35738 this.pingCache = null;
35739 this.finishedWork = null;
35740 this.timeoutHandle = noTimeout;
35741 this.cancelPendingCommit = null;
35742 this.context = null;
35743 this.pendingContext = null;
35744 this.next = null;
35745 this.callbackNode = null;
35746 this.callbackPriority = NoLane;
35747 this.expirationTimes = createLaneMap(NoTimestamp);
35748 this.pendingLanes = NoLanes;
35749 this.suspendedLanes = NoLanes;
35750 this.pingedLanes = NoLanes;
35751 this.expiredLanes = NoLanes;
35752 this.finishedLanes = NoLanes;
35753 this.errorRecoveryDisabledLanes = NoLanes;
35754 this.shellSuspendCounter = 0;
35755 this.entangledLanes = NoLanes;
35756 this.entanglements = createLaneMap(NoLanes);
35757 this.hiddenUpdates = createLaneMap(null);
35758 this.identifierPrefix = identifierPrefix;
35759 this.onUncaughtError = onUncaughtError;
35760 this.onCaughtError = onCaughtError;
35761 this.onRecoverableError = onRecoverableError;
35762
35763 {
35764 this.pooledCache = null;
35765 this.pooledCacheLanes = NoLanes;
35766 }
35767
35768 this.formState = formState;
35769 this.incompleteTransitions = new Map();
35770
35771 {
35772 this.effectDuration = 0;
35773 this.passiveEffectDuration = 0;
35774 }
35775
35776 {
35777 this.memoizedUpdaters = new Set();
35778 var pendingUpdatersLaneMap = this.pendingUpdatersLaneMap = [];
35779
35780 for (var _i = 0; _i < TotalLanes; _i++) {
35781 pendingUpdatersLaneMap.push(new Set());
35782 }
35783 }
35784
35785 {
35786 {
35787 // TODO: This varies by each renderer.
35788 this._debugRootType = hydrate ? 'hydrateRoot()' : 'createRoot()';
35789 }
35790 }
35791}
35792
35793function createFiberRoot(containerInfo, tag, hydrate, initialChildren, hydrationCallbacks, isStrictMode, concurrentUpdatesByDefaultOverride, // TODO: We have several of these arguments that are conceptually part of the
35794// host config, but because they are passed in at runtime, we have to thread
35795// them through the root constructor. Perhaps we should put them all into a
35796// single type, like a DynamicHostConfig that is defined by the renderer.
35797identifierPrefix, onUncaughtError, onCaughtError, onRecoverableError, transitionCallbacks, formState) {
35798 // $FlowFixMe[invalid-constructor] Flow no longer supports calling new on functions
35799 var root = new FiberRootNode(containerInfo, tag, hydrate, identifierPrefix, onUncaughtError, onCaughtError, onRecoverableError, formState);
35800 // stateNode is any.
35801
35802
35803 var uninitializedFiber = createHostRootFiber(tag, isStrictMode);
35804 root.current = uninitializedFiber;
35805 uninitializedFiber.stateNode = root;
35806
35807 {
35808 var initialCache = createCache();
35809 retainCache(initialCache); // The pooledCache is a fresh cache instance that is used temporarily
35810 // for newly mounted boundaries during a render. In general, the
35811 // pooledCache is always cleared from the root at the end of a render:
35812 // it is either released when render commits, or moved to an Offscreen
35813 // component if rendering suspends. Because the lifetime of the pooled
35814 // cache is distinct from the main memoizedState.cache, it must be
35815 // retained separately.
35816
35817 root.pooledCache = initialCache;
35818 retainCache(initialCache);
35819 var initialState = {
35820 element: initialChildren,
35821 isDehydrated: hydrate,
35822 cache: initialCache
35823 };
35824 uninitializedFiber.memoizedState = initialState;
35825 }
35826
35827 initializeUpdateQueue(uninitializedFiber);
35828 return root;
35829}
35830
35831var ReactVersion = '19.0.0-beta-4508873393-20240430';
35832
35833// Might add PROFILE later.
35834
35835var didWarnAboutNestedUpdates;
35836
35837{
35838 didWarnAboutNestedUpdates = false;
35839}
35840
35841function getContextForSubtree(parentComponent) {
35842 if (!parentComponent) {
35843 return emptyContextObject;
35844 }
35845
35846 var fiber = get(parentComponent);
35847 var parentContext = findCurrentUnmaskedContext();
35848
35849 if (fiber.tag === ClassComponent) {
35850 var Component = fiber.type;
35851
35852 if (isContextProvider()) {
35853 return processChildContext(fiber, Component, parentContext);
35854 }
35855 }
35856
35857 return parentContext;
35858}
35859
35860function findHostInstance(component) {
35861 var fiber = get(component);
35862
35863 if (fiber === undefined) {
35864 if (typeof component.render === 'function') {
35865 throw new Error('Unable to find node on an unmounted component.');
35866 } else {
35867 var keys = Object.keys(component).join(',');
35868 throw new Error("Argument appears to not be a ReactComponent. Keys: " + keys);
35869 }
35870 }
35871
35872 var hostFiber = findCurrentHostFiber(fiber);
35873
35874 if (hostFiber === null) {
35875 return null;
35876 }
35877
35878 return getPublicInstance(hostFiber.stateNode);
35879}
35880
35881function createContainer(containerInfo, tag, hydrationCallbacks, isStrictMode, concurrentUpdatesByDefaultOverride, identifierPrefix, onUncaughtError, onCaughtError, onRecoverableError, transitionCallbacks) {
35882 var hydrate = false;
35883 var initialChildren = null;
35884 return createFiberRoot(containerInfo, tag, hydrate, initialChildren, hydrationCallbacks, isStrictMode, concurrentUpdatesByDefaultOverride, identifierPrefix, onUncaughtError, onCaughtError, onRecoverableError, transitionCallbacks, null);
35885}
35886function createHydrationContainer(initialChildren, // TODO: Remove `callback` when we delete legacy mode.
35887callback, containerInfo, tag, hydrationCallbacks, isStrictMode, concurrentUpdatesByDefaultOverride, identifierPrefix, onUncaughtError, onCaughtError, onRecoverableError, transitionCallbacks, formState) {
35888 var hydrate = true;
35889 var root = createFiberRoot(containerInfo, tag, hydrate, initialChildren, hydrationCallbacks, isStrictMode, concurrentUpdatesByDefaultOverride, identifierPrefix, onUncaughtError, onCaughtError, onRecoverableError, transitionCallbacks, formState); // TODO: Move this to FiberRoot constructor
35890
35891 root.context = getContextForSubtree(null); // Schedule the initial render. In a hydration root, this is different from
35892 // a regular update because the initial render must match was was rendered
35893 // on the server.
35894 // NOTE: This update intentionally doesn't have a payload. We're only using
35895 // the update to schedule work on the root fiber (and, for legacy roots, to
35896 // enqueue the callback if one is provided).
35897
35898 var current = root.current;
35899 var lane = requestUpdateLane(current);
35900 var update = createUpdate(lane);
35901 update.callback = callback !== undefined && callback !== null ? callback : null;
35902 enqueueUpdate(current, update, lane);
35903 scheduleInitialHydrationOnRoot(root, lane);
35904 return root;
35905}
35906function updateContainer(element, container, parentComponent, callback) {
35907 var current = container.current;
35908 var lane = requestUpdateLane(current);
35909 updateContainerImpl(current, lane, element, container, parentComponent, callback);
35910 return lane;
35911}
35912function updateContainerSync(element, container, parentComponent, callback) {
35913 if (container.tag === LegacyRoot) {
35914 flushPassiveEffects();
35915 }
35916
35917 var current = container.current;
35918 updateContainerImpl(current, SyncLane, element, container, parentComponent, callback);
35919 return SyncLane;
35920}
35921
35922function updateContainerImpl(rootFiber, lane, element, container, parentComponent, callback) {
35923 {
35924 onScheduleRoot(container, element);
35925 }
35926
35927 {
35928 markRenderScheduled(lane);
35929 }
35930
35931 var context = getContextForSubtree(parentComponent);
35932
35933 if (container.context === null) {
35934 container.context = context;
35935 } else {
35936 container.pendingContext = context;
35937 }
35938
35939 {
35940 if (isRendering && current !== null && !didWarnAboutNestedUpdates) {
35941 didWarnAboutNestedUpdates = true;
35942
35943 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.', getComponentNameFromFiber(current) || 'Unknown');
35944 }
35945 }
35946
35947 var update = createUpdate(lane); // Caution: React DevTools currently depends on this property
35948 // being called "element".
35949
35950 update.payload = {
35951 element: element
35952 };
35953 callback = callback === undefined ? null : callback;
35954
35955 if (callback !== null) {
35956 {
35957 if (typeof callback !== 'function') {
35958 error('Expected the last optional `callback` argument to be a ' + 'function. Instead received: %s.', callback);
35959 }
35960 }
35961
35962 update.callback = callback;
35963 }
35964
35965 var root = enqueueUpdate(rootFiber, update, lane);
35966
35967 if (root !== null) {
35968 scheduleUpdateOnFiber(root, rootFiber, lane);
35969 entangleTransitions(root, rootFiber, lane);
35970 }
35971}
35972function attemptSynchronousHydration(fiber) {
35973 switch (fiber.tag) {
35974 case HostRoot:
35975 {
35976 var root = fiber.stateNode;
35977
35978 if (isRootDehydrated(root)) {
35979 // Flush the first scheduled "update".
35980 var lanes = getHighestPriorityPendingLanes(root);
35981 flushRoot(root, lanes);
35982 }
35983
35984 break;
35985 }
35986
35987 case SuspenseComponent:
35988 {
35989 var _root = enqueueConcurrentRenderForLane(fiber, SyncLane);
35990
35991 if (_root !== null) {
35992 scheduleUpdateOnFiber(_root, fiber, SyncLane);
35993 }
35994
35995 flushSyncWork$1(); // If we're still blocked after this, we need to increase
35996 // the priority of any promises resolving within this
35997 // boundary so that they next attempt also has higher pri.
35998
35999 var retryLane = SyncLane;
36000 markRetryLaneIfNotHydrated(fiber, retryLane);
36001 break;
36002 }
36003 }
36004}
36005
36006function markRetryLaneImpl(fiber, retryLane) {
36007 var suspenseState = fiber.memoizedState;
36008
36009 if (suspenseState !== null && suspenseState.dehydrated !== null) {
36010 suspenseState.retryLane = higherPriorityLane(suspenseState.retryLane, retryLane);
36011 }
36012} // Increases the priority of thenables when they resolve within this boundary.
36013
36014
36015function markRetryLaneIfNotHydrated(fiber, retryLane) {
36016 markRetryLaneImpl(fiber, retryLane);
36017 var alternate = fiber.alternate;
36018
36019 if (alternate) {
36020 markRetryLaneImpl(alternate, retryLane);
36021 }
36022}
36023
36024function attemptContinuousHydration(fiber) {
36025 if (fiber.tag !== SuspenseComponent) {
36026 // We ignore HostRoots here because we can't increase
36027 // their priority and they should not suspend on I/O,
36028 // since you have to wrap anything that might suspend in
36029 // Suspense.
36030 return;
36031 }
36032
36033 var lane = SelectiveHydrationLane;
36034 var root = enqueueConcurrentRenderForLane(fiber, lane);
36035
36036 if (root !== null) {
36037 scheduleUpdateOnFiber(root, fiber, lane);
36038 }
36039
36040 markRetryLaneIfNotHydrated(fiber, lane);
36041}
36042function attemptHydrationAtCurrentPriority(fiber) {
36043 if (fiber.tag !== SuspenseComponent) {
36044 // We ignore HostRoots here because we can't increase
36045 // their priority other than synchronously flush it.
36046 return;
36047 }
36048
36049 var lane = requestUpdateLane(fiber);
36050 var root = enqueueConcurrentRenderForLane(fiber, lane);
36051
36052 if (root !== null) {
36053 scheduleUpdateOnFiber(root, fiber, lane);
36054 }
36055
36056 markRetryLaneIfNotHydrated(fiber, lane);
36057}
36058
36059var shouldErrorImpl = function (fiber) {
36060 return null;
36061};
36062
36063function shouldError(fiber) {
36064 return shouldErrorImpl(fiber);
36065}
36066
36067var shouldSuspendImpl = function (fiber) {
36068 return false;
36069};
36070
36071function shouldSuspend(fiber) {
36072 return shouldSuspendImpl(fiber);
36073}
36074var overrideHookState = null;
36075var overrideHookStateDeletePath = null;
36076var overrideHookStateRenamePath = null;
36077var overrideProps = null;
36078var overridePropsDeletePath = null;
36079var overridePropsRenamePath = null;
36080var scheduleUpdate = null;
36081var setErrorHandler = null;
36082var setSuspenseHandler = null;
36083
36084{
36085 var copyWithDeleteImpl = function (obj, path, index) {
36086 var key = path[index];
36087 var updated = isArray(obj) ? obj.slice() : assign({}, obj);
36088
36089 if (index + 1 === path.length) {
36090 if (isArray(updated)) {
36091 updated.splice(key, 1);
36092 } else {
36093 delete updated[key];
36094 }
36095
36096 return updated;
36097 } // $FlowFixMe[incompatible-use] number or string is fine here
36098
36099
36100 updated[key] = copyWithDeleteImpl(obj[key], path, index + 1);
36101 return updated;
36102 };
36103
36104 var copyWithDelete = function (obj, path) {
36105 return copyWithDeleteImpl(obj, path, 0);
36106 };
36107
36108 var copyWithRenameImpl = function (obj, oldPath, newPath, index) {
36109 var oldKey = oldPath[index];
36110 var updated = isArray(obj) ? obj.slice() : assign({}, obj);
36111
36112 if (index + 1 === oldPath.length) {
36113 var newKey = newPath[index]; // $FlowFixMe[incompatible-use] number or string is fine here
36114
36115 updated[newKey] = updated[oldKey];
36116
36117 if (isArray(updated)) {
36118 updated.splice(oldKey, 1);
36119 } else {
36120 delete updated[oldKey];
36121 }
36122 } else {
36123 // $FlowFixMe[incompatible-use] number or string is fine here
36124 updated[oldKey] = copyWithRenameImpl( // $FlowFixMe[incompatible-use] number or string is fine here
36125 obj[oldKey], oldPath, newPath, index + 1);
36126 }
36127
36128 return updated;
36129 };
36130
36131 var copyWithRename = function (obj, oldPath, newPath) {
36132 if (oldPath.length !== newPath.length) {
36133 warn('copyWithRename() expects paths of the same length');
36134
36135 return;
36136 } else {
36137 for (var i = 0; i < newPath.length - 1; i++) {
36138 if (oldPath[i] !== newPath[i]) {
36139 warn('copyWithRename() expects paths to be the same except for the deepest key');
36140
36141 return;
36142 }
36143 }
36144 }
36145
36146 return copyWithRenameImpl(obj, oldPath, newPath, 0);
36147 };
36148
36149 var copyWithSetImpl = function (obj, path, index, value) {
36150 if (index >= path.length) {
36151 return value;
36152 }
36153
36154 var key = path[index];
36155 var updated = isArray(obj) ? obj.slice() : assign({}, obj); // $FlowFixMe[incompatible-use] number or string is fine here
36156
36157 updated[key] = copyWithSetImpl(obj[key], path, index + 1, value);
36158 return updated;
36159 };
36160
36161 var copyWithSet = function (obj, path, value) {
36162 return copyWithSetImpl(obj, path, 0, value);
36163 };
36164
36165 var findHook = function (fiber, id) {
36166 // For now, the "id" of stateful hooks is just the stateful hook index.
36167 // This may change in the future with e.g. nested hooks.
36168 var currentHook = fiber.memoizedState;
36169
36170 while (currentHook !== null && id > 0) {
36171 currentHook = currentHook.next;
36172 id--;
36173 }
36174
36175 return currentHook;
36176 }; // Support DevTools editable values for useState and useReducer.
36177
36178
36179 overrideHookState = function (fiber, id, path, value) {
36180 var hook = findHook(fiber, id);
36181
36182 if (hook !== null) {
36183 var newState = copyWithSet(hook.memoizedState, path, value);
36184 hook.memoizedState = newState;
36185 hook.baseState = newState; // We aren't actually adding an update to the queue,
36186 // because there is no update we can add for useReducer hooks that won't trigger an error.
36187 // (There's no appropriate action type for DevTools overrides.)
36188 // As a result though, React will see the scheduled update as a noop and bailout.
36189 // Shallow cloning props works as a workaround for now to bypass the bailout check.
36190
36191 fiber.memoizedProps = assign({}, fiber.memoizedProps);
36192 var root = enqueueConcurrentRenderForLane(fiber, SyncLane);
36193
36194 if (root !== null) {
36195 scheduleUpdateOnFiber(root, fiber, SyncLane);
36196 }
36197 }
36198 };
36199
36200 overrideHookStateDeletePath = function (fiber, id, path) {
36201 var hook = findHook(fiber, id);
36202
36203 if (hook !== null) {
36204 var newState = copyWithDelete(hook.memoizedState, path);
36205 hook.memoizedState = newState;
36206 hook.baseState = newState; // We aren't actually adding an update to the queue,
36207 // because there is no update we can add for useReducer hooks that won't trigger an error.
36208 // (There's no appropriate action type for DevTools overrides.)
36209 // As a result though, React will see the scheduled update as a noop and bailout.
36210 // Shallow cloning props works as a workaround for now to bypass the bailout check.
36211
36212 fiber.memoizedProps = assign({}, fiber.memoizedProps);
36213 var root = enqueueConcurrentRenderForLane(fiber, SyncLane);
36214
36215 if (root !== null) {
36216 scheduleUpdateOnFiber(root, fiber, SyncLane);
36217 }
36218 }
36219 };
36220
36221 overrideHookStateRenamePath = function (fiber, id, oldPath, newPath) {
36222 var hook = findHook(fiber, id);
36223
36224 if (hook !== null) {
36225 var newState = copyWithRename(hook.memoizedState, oldPath, newPath);
36226 hook.memoizedState = newState;
36227 hook.baseState = newState; // We aren't actually adding an update to the queue,
36228 // because there is no update we can add for useReducer hooks that won't trigger an error.
36229 // (There's no appropriate action type for DevTools overrides.)
36230 // As a result though, React will see the scheduled update as a noop and bailout.
36231 // Shallow cloning props works as a workaround for now to bypass the bailout check.
36232
36233 fiber.memoizedProps = assign({}, fiber.memoizedProps);
36234 var root = enqueueConcurrentRenderForLane(fiber, SyncLane);
36235
36236 if (root !== null) {
36237 scheduleUpdateOnFiber(root, fiber, SyncLane);
36238 }
36239 }
36240 }; // Support DevTools props for function components, forwardRef, memo, host components, etc.
36241
36242
36243 overrideProps = function (fiber, path, value) {
36244 fiber.pendingProps = copyWithSet(fiber.memoizedProps, path, value);
36245
36246 if (fiber.alternate) {
36247 fiber.alternate.pendingProps = fiber.pendingProps;
36248 }
36249
36250 var root = enqueueConcurrentRenderForLane(fiber, SyncLane);
36251
36252 if (root !== null) {
36253 scheduleUpdateOnFiber(root, fiber, SyncLane);
36254 }
36255 };
36256
36257 overridePropsDeletePath = function (fiber, path) {
36258 fiber.pendingProps = copyWithDelete(fiber.memoizedProps, path);
36259
36260 if (fiber.alternate) {
36261 fiber.alternate.pendingProps = fiber.pendingProps;
36262 }
36263
36264 var root = enqueueConcurrentRenderForLane(fiber, SyncLane);
36265
36266 if (root !== null) {
36267 scheduleUpdateOnFiber(root, fiber, SyncLane);
36268 }
36269 };
36270
36271 overridePropsRenamePath = function (fiber, oldPath, newPath) {
36272 fiber.pendingProps = copyWithRename(fiber.memoizedProps, oldPath, newPath);
36273
36274 if (fiber.alternate) {
36275 fiber.alternate.pendingProps = fiber.pendingProps;
36276 }
36277
36278 var root = enqueueConcurrentRenderForLane(fiber, SyncLane);
36279
36280 if (root !== null) {
36281 scheduleUpdateOnFiber(root, fiber, SyncLane);
36282 }
36283 };
36284
36285 scheduleUpdate = function (fiber) {
36286 var root = enqueueConcurrentRenderForLane(fiber, SyncLane);
36287
36288 if (root !== null) {
36289 scheduleUpdateOnFiber(root, fiber, SyncLane);
36290 }
36291 };
36292
36293 setErrorHandler = function (newShouldErrorImpl) {
36294 shouldErrorImpl = newShouldErrorImpl;
36295 };
36296
36297 setSuspenseHandler = function (newShouldSuspendImpl) {
36298 shouldSuspendImpl = newShouldSuspendImpl;
36299 };
36300}
36301
36302function findHostInstanceByFiber(fiber) {
36303 var hostFiber = findCurrentHostFiber(fiber);
36304
36305 if (hostFiber === null) {
36306 return null;
36307 }
36308
36309 return hostFiber.stateNode;
36310}
36311
36312function emptyFindFiberByHostInstance(instance) {
36313 return null;
36314}
36315
36316function getCurrentFiberForDevTools() {
36317 return current;
36318}
36319
36320function injectIntoDevTools(devToolsConfig) {
36321 var findFiberByHostInstance = devToolsConfig.findFiberByHostInstance;
36322 return injectInternals({
36323 bundleType: devToolsConfig.bundleType,
36324 version: devToolsConfig.version,
36325 rendererPackageName: devToolsConfig.rendererPackageName,
36326 rendererConfig: devToolsConfig.rendererConfig,
36327 overrideHookState: overrideHookState,
36328 overrideHookStateDeletePath: overrideHookStateDeletePath,
36329 overrideHookStateRenamePath: overrideHookStateRenamePath,
36330 overrideProps: overrideProps,
36331 overridePropsDeletePath: overridePropsDeletePath,
36332 overridePropsRenamePath: overridePropsRenamePath,
36333 setErrorHandler: setErrorHandler,
36334 setSuspenseHandler: setSuspenseHandler,
36335 scheduleUpdate: scheduleUpdate,
36336 currentDispatcherRef: ReactSharedInternals,
36337 findHostInstanceByFiber: findHostInstanceByFiber,
36338 findFiberByHostInstance: findFiberByHostInstance || emptyFindFiberByHostInstance,
36339 // React Refresh
36340 findHostInstancesForRefresh: findHostInstancesForRefresh ,
36341 scheduleRefresh: scheduleRefresh ,
36342 scheduleRoot: scheduleRoot ,
36343 setRefreshHandler: setRefreshHandler ,
36344 // Enables DevTools to append owner stacks to error messages in DEV mode.
36345 getCurrentFiber: getCurrentFiberForDevTools ,
36346 // Enables DevTools to detect reconciler version rather than renderer version
36347 // which may not match for third party renderers.
36348 reconcilerVersion: ReactVersion
36349 });
36350}
36351
36352var _enabled = true; // This is exported in FB builds for use by legacy FB layer infra.
36353// We'd like to remove this but it's not clear if this is safe.
36354
36355function setEnabled(enabled) {
36356 _enabled = !!enabled;
36357}
36358function isEnabled() {
36359 return _enabled;
36360}
36361function createEventListenerWrapperWithPriority(targetContainer, domEventName, eventSystemFlags) {
36362 var eventPriority = getEventPriority(domEventName);
36363 var listenerWrapper;
36364
36365 switch (eventPriority) {
36366 case DiscreteEventPriority:
36367 listenerWrapper = dispatchDiscreteEvent;
36368 break;
36369
36370 case ContinuousEventPriority:
36371 listenerWrapper = dispatchContinuousEvent;
36372 break;
36373
36374 case DefaultEventPriority:
36375 default:
36376 listenerWrapper = dispatchEvent;
36377 break;
36378 }
36379
36380 return listenerWrapper.bind(null, domEventName, eventSystemFlags, targetContainer);
36381}
36382
36383function dispatchDiscreteEvent(domEventName, eventSystemFlags, container, nativeEvent) {
36384 var prevTransition = ReactSharedInternals.T;
36385 ReactSharedInternals.T = null;
36386 var previousPriority = getCurrentUpdatePriority();
36387
36388 try {
36389 setCurrentUpdatePriority(DiscreteEventPriority);
36390 dispatchEvent(domEventName, eventSystemFlags, container, nativeEvent);
36391 } finally {
36392 setCurrentUpdatePriority(previousPriority);
36393 ReactSharedInternals.T = prevTransition;
36394 }
36395}
36396
36397function dispatchContinuousEvent(domEventName, eventSystemFlags, container, nativeEvent) {
36398 var prevTransition = ReactSharedInternals.T;
36399 ReactSharedInternals.T = null;
36400 var previousPriority = getCurrentUpdatePriority();
36401
36402 try {
36403 setCurrentUpdatePriority(ContinuousEventPriority);
36404 dispatchEvent(domEventName, eventSystemFlags, container, nativeEvent);
36405 } finally {
36406 setCurrentUpdatePriority(previousPriority);
36407 ReactSharedInternals.T = prevTransition;
36408 }
36409}
36410
36411function dispatchEvent(domEventName, eventSystemFlags, targetContainer, nativeEvent) {
36412 if (!_enabled) {
36413 return;
36414 }
36415
36416 var blockedOn = findInstanceBlockingEvent(nativeEvent);
36417
36418 if (blockedOn === null) {
36419 dispatchEventForPluginEventSystem(domEventName, eventSystemFlags, nativeEvent, return_targetInst, targetContainer);
36420 clearIfContinuousEvent(domEventName, nativeEvent);
36421 return;
36422 }
36423
36424 if (queueIfContinuousEvent(blockedOn, domEventName, eventSystemFlags, targetContainer, nativeEvent)) {
36425 nativeEvent.stopPropagation();
36426 return;
36427 } // We need to clear only if we didn't queue because
36428 // queueing is accumulative.
36429
36430
36431 clearIfContinuousEvent(domEventName, nativeEvent);
36432
36433 if (eventSystemFlags & IS_CAPTURE_PHASE && isDiscreteEventThatRequiresHydration(domEventName)) {
36434 while (blockedOn !== null) {
36435 var fiber = getInstanceFromNode(blockedOn);
36436
36437 if (fiber !== null) {
36438 attemptSynchronousHydration(fiber);
36439 }
36440
36441 var nextBlockedOn = findInstanceBlockingEvent(nativeEvent);
36442
36443 if (nextBlockedOn === null) {
36444 dispatchEventForPluginEventSystem(domEventName, eventSystemFlags, nativeEvent, return_targetInst, targetContainer);
36445 }
36446
36447 if (nextBlockedOn === blockedOn) {
36448 break;
36449 }
36450
36451 blockedOn = nextBlockedOn;
36452 }
36453
36454 if (blockedOn !== null) {
36455 nativeEvent.stopPropagation();
36456 }
36457
36458 return;
36459 } // This is not replayable so we'll invoke it but without a target,
36460 // in case the event system needs to trace it.
36461
36462
36463 dispatchEventForPluginEventSystem(domEventName, eventSystemFlags, nativeEvent, null, targetContainer);
36464}
36465function findInstanceBlockingEvent(nativeEvent) {
36466 var nativeEventTarget = getEventTarget(nativeEvent);
36467 return findInstanceBlockingTarget(nativeEventTarget);
36468}
36469var return_targetInst = null; // Returns a SuspenseInstance or Container if it's blocked.
36470// The return_targetInst field above is conceptually part of the return value.
36471
36472function findInstanceBlockingTarget(targetNode) {
36473 // TODO: Warn if _enabled is false.
36474 return_targetInst = null;
36475 var targetInst = getClosestInstanceFromNode(targetNode);
36476
36477 if (targetInst !== null) {
36478 var nearestMounted = getNearestMountedFiber(targetInst);
36479
36480 if (nearestMounted === null) {
36481 // This tree has been unmounted already. Dispatch without a target.
36482 targetInst = null;
36483 } else {
36484 var tag = nearestMounted.tag;
36485
36486 if (tag === SuspenseComponent) {
36487 var instance = getSuspenseInstanceFromFiber(nearestMounted);
36488
36489 if (instance !== null) {
36490 // Queue the event to be replayed later. Abort dispatching since we
36491 // don't want this event dispatched twice through the event system.
36492 // TODO: If this is the first discrete event in the queue. Schedule an increased
36493 // priority for this boundary.
36494 return instance;
36495 } // This shouldn't happen, something went wrong but to avoid blocking
36496 // the whole system, dispatch the event without a target.
36497 // TODO: Warn.
36498
36499
36500 targetInst = null;
36501 } else if (tag === HostRoot) {
36502 var root = nearestMounted.stateNode;
36503
36504 if (isRootDehydrated(root)) {
36505 // If this happens during a replay something went wrong and it might block
36506 // the whole system.
36507 return getContainerFromFiber(nearestMounted);
36508 }
36509
36510 targetInst = null;
36511 } else if (nearestMounted !== targetInst) {
36512 // If we get an event (ex: img onload) before committing that
36513 // component's mount, ignore it for now (that is, treat it as if it was an
36514 // event on a non-React tree). We might also consider queueing events and
36515 // dispatching them after the mount.
36516 targetInst = null;
36517 }
36518 }
36519 }
36520
36521 return_targetInst = targetInst; // We're not blocked on anything.
36522
36523 return null;
36524}
36525function getEventPriority(domEventName) {
36526 switch (domEventName) {
36527 // Used by SimpleEventPlugin:
36528 case 'cancel':
36529 case 'click':
36530 case 'close':
36531 case 'contextmenu':
36532 case 'copy':
36533 case 'cut':
36534 case 'auxclick':
36535 case 'dblclick':
36536 case 'dragend':
36537 case 'dragstart':
36538 case 'drop':
36539 case 'focusin':
36540 case 'focusout':
36541 case 'input':
36542 case 'invalid':
36543 case 'keydown':
36544 case 'keypress':
36545 case 'keyup':
36546 case 'mousedown':
36547 case 'mouseup':
36548 case 'paste':
36549 case 'pause':
36550 case 'play':
36551 case 'pointercancel':
36552 case 'pointerdown':
36553 case 'pointerup':
36554 case 'ratechange':
36555 case 'reset':
36556 case 'resize':
36557 case 'seeked':
36558 case 'submit':
36559 case 'touchcancel':
36560 case 'touchend':
36561 case 'touchstart':
36562 case 'volumechange': // Used by polyfills: (fall through)
36563
36564 case 'change':
36565 case 'selectionchange':
36566 case 'textInput':
36567 case 'compositionstart':
36568 case 'compositionend':
36569 case 'compositionupdate': // Only enableCreateEventHandleAPI: (fall through)
36570
36571 case 'beforeblur':
36572 case 'afterblur': // Not used by React but could be by user code: (fall through)
36573
36574 case 'beforeinput':
36575 case 'blur':
36576 case 'fullscreenchange':
36577 case 'focus':
36578 case 'hashchange':
36579 case 'popstate':
36580 case 'select':
36581 case 'selectstart':
36582 return DiscreteEventPriority;
36583
36584 case 'drag':
36585 case 'dragenter':
36586 case 'dragexit':
36587 case 'dragleave':
36588 case 'dragover':
36589 case 'mousemove':
36590 case 'mouseout':
36591 case 'mouseover':
36592 case 'pointermove':
36593 case 'pointerout':
36594 case 'pointerover':
36595 case 'scroll':
36596 case 'toggle':
36597 case 'touchmove':
36598 case 'wheel': // Not used by React but could be by user code: (fall through)
36599
36600 case 'mouseenter':
36601 case 'mouseleave':
36602 case 'pointerenter':
36603 case 'pointerleave':
36604 return ContinuousEventPriority;
36605
36606 case 'message':
36607 {
36608 // We might be in the Scheduler callback.
36609 // Eventually this mechanism will be replaced by a check
36610 // of the current priority on the native scheduler.
36611 var schedulerPriority = getCurrentPriorityLevel();
36612
36613 switch (schedulerPriority) {
36614 case ImmediatePriority:
36615 return DiscreteEventPriority;
36616
36617 case UserBlockingPriority:
36618 return ContinuousEventPriority;
36619
36620 case NormalPriority$1:
36621 case LowPriority:
36622 // TODO: Handle LowSchedulerPriority, somehow. Maybe the same lane as hydration.
36623 return DefaultEventPriority;
36624
36625 case IdlePriority:
36626 return IdleEventPriority;
36627
36628 default:
36629 return DefaultEventPriority;
36630 }
36631 }
36632
36633 default:
36634 return DefaultEventPriority;
36635 }
36636}
36637
36638// has this definition built-in.
36639
36640var hasScheduledReplayAttempt = false; // The last of each continuous event type. We only need to replay the last one
36641// if the last target was dehydrated.
36642
36643var queuedFocus = null;
36644var queuedDrag = null;
36645var queuedMouse = null; // For pointer events there can be one latest event per pointerId.
36646
36647var queuedPointers = new Map();
36648var queuedPointerCaptures = new Map(); // We could consider replaying selectionchange and touchmoves too.
36649
36650var queuedExplicitHydrationTargets = [];
36651var discreteReplayableEvents = ['mousedown', 'mouseup', 'touchcancel', 'touchend', 'touchstart', 'auxclick', 'dblclick', 'pointercancel', 'pointerdown', 'pointerup', 'dragend', 'dragstart', 'drop', 'compositionend', 'compositionstart', 'keydown', 'keypress', 'keyup', 'input', 'textInput', // Intentionally camelCase
36652'copy', 'cut', 'paste', 'click', 'change', 'contextmenu', 'reset' // 'submit', // stopPropagation blocks the replay mechanism
36653];
36654function isDiscreteEventThatRequiresHydration(eventType) {
36655 return discreteReplayableEvents.indexOf(eventType) > -1;
36656}
36657
36658function createQueuedReplayableEvent(blockedOn, domEventName, eventSystemFlags, targetContainer, nativeEvent) {
36659 return {
36660 blockedOn: blockedOn,
36661 domEventName: domEventName,
36662 eventSystemFlags: eventSystemFlags,
36663 nativeEvent: nativeEvent,
36664 targetContainers: [targetContainer]
36665 };
36666} // Resets the replaying for this type of continuous event to no event.
36667
36668
36669function clearIfContinuousEvent(domEventName, nativeEvent) {
36670 switch (domEventName) {
36671 case 'focusin':
36672 case 'focusout':
36673 queuedFocus = null;
36674 break;
36675
36676 case 'dragenter':
36677 case 'dragleave':
36678 queuedDrag = null;
36679 break;
36680
36681 case 'mouseover':
36682 case 'mouseout':
36683 queuedMouse = null;
36684 break;
36685
36686 case 'pointerover':
36687 case 'pointerout':
36688 {
36689 var pointerId = nativeEvent.pointerId;
36690 queuedPointers.delete(pointerId);
36691 break;
36692 }
36693
36694 case 'gotpointercapture':
36695 case 'lostpointercapture':
36696 {
36697 var _pointerId = nativeEvent.pointerId;
36698 queuedPointerCaptures.delete(_pointerId);
36699 break;
36700 }
36701 }
36702}
36703
36704function accumulateOrCreateContinuousQueuedReplayableEvent(existingQueuedEvent, blockedOn, domEventName, eventSystemFlags, targetContainer, nativeEvent) {
36705 if (existingQueuedEvent === null || existingQueuedEvent.nativeEvent !== nativeEvent) {
36706 var queuedEvent = createQueuedReplayableEvent(blockedOn, domEventName, eventSystemFlags, targetContainer, nativeEvent);
36707
36708 if (blockedOn !== null) {
36709 var fiber = getInstanceFromNode(blockedOn);
36710
36711 if (fiber !== null) {
36712 // Attempt to increase the priority of this target.
36713 attemptContinuousHydration(fiber);
36714 }
36715 }
36716
36717 return queuedEvent;
36718 } // If we have already queued this exact event, then it's because
36719 // the different event systems have different DOM event listeners.
36720 // We can accumulate the flags, and the targetContainers, and
36721 // store a single event to be replayed.
36722
36723
36724 existingQueuedEvent.eventSystemFlags |= eventSystemFlags;
36725 var targetContainers = existingQueuedEvent.targetContainers;
36726
36727 if (targetContainer !== null && targetContainers.indexOf(targetContainer) === -1) {
36728 targetContainers.push(targetContainer);
36729 }
36730
36731 return existingQueuedEvent;
36732}
36733
36734function queueIfContinuousEvent(blockedOn, domEventName, eventSystemFlags, targetContainer, nativeEvent) {
36735 // These set relatedTarget to null because the replayed event will be treated as if we
36736 // moved from outside the window (no target) onto the target once it hydrates.
36737 // Instead of mutating we could clone the event.
36738 switch (domEventName) {
36739 case 'focusin':
36740 {
36741 var focusEvent = nativeEvent;
36742 queuedFocus = accumulateOrCreateContinuousQueuedReplayableEvent(queuedFocus, blockedOn, domEventName, eventSystemFlags, targetContainer, focusEvent);
36743 return true;
36744 }
36745
36746 case 'dragenter':
36747 {
36748 var dragEvent = nativeEvent;
36749 queuedDrag = accumulateOrCreateContinuousQueuedReplayableEvent(queuedDrag, blockedOn, domEventName, eventSystemFlags, targetContainer, dragEvent);
36750 return true;
36751 }
36752
36753 case 'mouseover':
36754 {
36755 var mouseEvent = nativeEvent;
36756 queuedMouse = accumulateOrCreateContinuousQueuedReplayableEvent(queuedMouse, blockedOn, domEventName, eventSystemFlags, targetContainer, mouseEvent);
36757 return true;
36758 }
36759
36760 case 'pointerover':
36761 {
36762 var pointerEvent = nativeEvent;
36763 var pointerId = pointerEvent.pointerId;
36764 queuedPointers.set(pointerId, accumulateOrCreateContinuousQueuedReplayableEvent(queuedPointers.get(pointerId) || null, blockedOn, domEventName, eventSystemFlags, targetContainer, pointerEvent));
36765 return true;
36766 }
36767
36768 case 'gotpointercapture':
36769 {
36770 var _pointerEvent = nativeEvent;
36771 var _pointerId2 = _pointerEvent.pointerId;
36772 queuedPointerCaptures.set(_pointerId2, accumulateOrCreateContinuousQueuedReplayableEvent(queuedPointerCaptures.get(_pointerId2) || null, blockedOn, domEventName, eventSystemFlags, targetContainer, _pointerEvent));
36773 return true;
36774 }
36775 }
36776
36777 return false;
36778} // Check if this target is unblocked. Returns true if it's unblocked.
36779
36780function attemptExplicitHydrationTarget(queuedTarget) {
36781 // TODO: This function shares a lot of logic with findInstanceBlockingEvent.
36782 // Try to unify them. It's a bit tricky since it would require two return
36783 // values.
36784 var targetInst = getClosestInstanceFromNode(queuedTarget.target);
36785
36786 if (targetInst !== null) {
36787 var nearestMounted = getNearestMountedFiber(targetInst);
36788
36789 if (nearestMounted !== null) {
36790 var tag = nearestMounted.tag;
36791
36792 if (tag === SuspenseComponent) {
36793 var instance = getSuspenseInstanceFromFiber(nearestMounted);
36794
36795 if (instance !== null) {
36796 // We're blocked on hydrating this boundary.
36797 // Increase its priority.
36798 queuedTarget.blockedOn = instance;
36799 runWithPriority(queuedTarget.priority, function () {
36800 attemptHydrationAtCurrentPriority(nearestMounted);
36801 });
36802 return;
36803 }
36804 } else if (tag === HostRoot) {
36805 var root = nearestMounted.stateNode;
36806
36807 if (isRootDehydrated(root)) {
36808 queuedTarget.blockedOn = getContainerFromFiber(nearestMounted); // We don't currently have a way to increase the priority of
36809 // a root other than sync.
36810
36811 return;
36812 }
36813 }
36814 }
36815 }
36816
36817 queuedTarget.blockedOn = null;
36818}
36819
36820function queueExplicitHydrationTarget(target) {
36821 var updatePriority = resolveUpdatePriority();
36822 var queuedTarget = {
36823 blockedOn: null,
36824 target: target,
36825 priority: updatePriority
36826 };
36827 var i = 0;
36828
36829 for (; i < queuedExplicitHydrationTargets.length; i++) {
36830 // Stop once we hit the first target with lower priority than
36831 if (!isHigherEventPriority(updatePriority, queuedExplicitHydrationTargets[i].priority)) {
36832 break;
36833 }
36834 }
36835
36836 queuedExplicitHydrationTargets.splice(i, 0, queuedTarget);
36837
36838 if (i === 0) {
36839 attemptExplicitHydrationTarget(queuedTarget);
36840 }
36841}
36842
36843function attemptReplayContinuousQueuedEvent(queuedEvent) {
36844 if (queuedEvent.blockedOn !== null) {
36845 return false;
36846 }
36847
36848 var targetContainers = queuedEvent.targetContainers;
36849
36850 while (targetContainers.length > 0) {
36851 var nextBlockedOn = findInstanceBlockingEvent(queuedEvent.nativeEvent);
36852
36853 if (nextBlockedOn === null) {
36854 var nativeEvent = queuedEvent.nativeEvent;
36855 var nativeEventClone = new nativeEvent.constructor(nativeEvent.type, nativeEvent);
36856 setReplayingEvent(nativeEventClone);
36857 nativeEvent.target.dispatchEvent(nativeEventClone);
36858 resetReplayingEvent();
36859 } else {
36860 // We're still blocked. Try again later.
36861 var fiber = getInstanceFromNode(nextBlockedOn);
36862
36863 if (fiber !== null) {
36864 attemptContinuousHydration(fiber);
36865 }
36866
36867 queuedEvent.blockedOn = nextBlockedOn;
36868 return false;
36869 } // This target container was successfully dispatched. Try the next.
36870
36871
36872 targetContainers.shift();
36873 }
36874
36875 return true;
36876}
36877
36878function attemptReplayContinuousQueuedEventInMap(queuedEvent, key, map) {
36879 if (attemptReplayContinuousQueuedEvent(queuedEvent)) {
36880 map.delete(key);
36881 }
36882}
36883
36884function replayUnblockedEvents() {
36885 hasScheduledReplayAttempt = false; // Replay any continuous events.
36886
36887 if (queuedFocus !== null && attemptReplayContinuousQueuedEvent(queuedFocus)) {
36888 queuedFocus = null;
36889 }
36890
36891 if (queuedDrag !== null && attemptReplayContinuousQueuedEvent(queuedDrag)) {
36892 queuedDrag = null;
36893 }
36894
36895 if (queuedMouse !== null && attemptReplayContinuousQueuedEvent(queuedMouse)) {
36896 queuedMouse = null;
36897 }
36898
36899 queuedPointers.forEach(attemptReplayContinuousQueuedEventInMap);
36900 queuedPointerCaptures.forEach(attemptReplayContinuousQueuedEventInMap);
36901}
36902
36903function scheduleCallbackIfUnblocked(queuedEvent, unblocked) {
36904 if (queuedEvent.blockedOn === unblocked) {
36905 queuedEvent.blockedOn = null;
36906
36907 if (!hasScheduledReplayAttempt) {
36908 hasScheduledReplayAttempt = true; // Schedule a callback to attempt replaying as many events as are
36909 // now unblocked. This first might not actually be unblocked yet.
36910 // We could check it early to avoid scheduling an unnecessary callback.
36911
36912 Scheduler.unstable_scheduleCallback(Scheduler.unstable_NormalPriority, replayUnblockedEvents);
36913 }
36914 }
36915} // [form, submitter or action, formData...]
36916
36917
36918var lastScheduledReplayQueue = null;
36919
36920function replayUnblockedFormActions(formReplayingQueue) {
36921 if (lastScheduledReplayQueue === formReplayingQueue) {
36922 lastScheduledReplayQueue = null;
36923 }
36924
36925 for (var i = 0; i < formReplayingQueue.length; i += 3) {
36926 var form = formReplayingQueue[i];
36927 var submitterOrAction = formReplayingQueue[i + 1];
36928 var formData = formReplayingQueue[i + 2];
36929
36930 if (typeof submitterOrAction !== 'function') {
36931 // This action is not hydrated yet. This might be because it's blocked on
36932 // a different React instance or higher up our tree.
36933 var blockedOn = findInstanceBlockingTarget(submitterOrAction || form);
36934
36935 if (blockedOn === null) {
36936 // We're not blocked but we don't have an action. This must mean that
36937 // this is in another React instance. We'll just skip past it.
36938 continue;
36939 } else {
36940 // We're blocked on something in this React instance. We'll retry later.
36941 break;
36942 }
36943 }
36944
36945 var formInst = getInstanceFromNode(form);
36946
36947 if (formInst !== null) {
36948 // This is part of our instance.
36949 // We're ready to replay this. Let's delete it from the queue.
36950 formReplayingQueue.splice(i, 3);
36951 i -= 3;
36952 dispatchReplayedFormAction(formInst, form, submitterOrAction, formData); // Continue without incrementing the index.
36953
36954 continue;
36955 } // This form must've been part of a different React instance.
36956 // If we want to preserve ordering between React instances on the same root
36957 // we'd need some way for the other instance to ping us when it's done.
36958 // We'll just skip this and let the other instance execute it.
36959
36960 }
36961}
36962
36963function scheduleReplayQueueIfNeeded(formReplayingQueue) {
36964 // Schedule a callback to execute any unblocked form actions in.
36965 // We only keep track of the last queue which means that if multiple React oscillate
36966 // commits, we could schedule more callbacks than necessary but it's not a big deal
36967 // and we only really except one instance.
36968 if (lastScheduledReplayQueue !== formReplayingQueue) {
36969 lastScheduledReplayQueue = formReplayingQueue;
36970 Scheduler.unstable_scheduleCallback(Scheduler.unstable_NormalPriority, function () {
36971 return replayUnblockedFormActions(formReplayingQueue);
36972 });
36973 }
36974}
36975
36976function retryIfBlockedOn(unblocked) {
36977 if (queuedFocus !== null) {
36978 scheduleCallbackIfUnblocked(queuedFocus, unblocked);
36979 }
36980
36981 if (queuedDrag !== null) {
36982 scheduleCallbackIfUnblocked(queuedDrag, unblocked);
36983 }
36984
36985 if (queuedMouse !== null) {
36986 scheduleCallbackIfUnblocked(queuedMouse, unblocked);
36987 }
36988
36989 var unblock = function (queuedEvent) {
36990 return scheduleCallbackIfUnblocked(queuedEvent, unblocked);
36991 };
36992
36993 queuedPointers.forEach(unblock);
36994 queuedPointerCaptures.forEach(unblock);
36995
36996 for (var i = 0; i < queuedExplicitHydrationTargets.length; i++) {
36997 var queuedTarget = queuedExplicitHydrationTargets[i];
36998
36999 if (queuedTarget.blockedOn === unblocked) {
37000 queuedTarget.blockedOn = null;
37001 }
37002 }
37003
37004 while (queuedExplicitHydrationTargets.length > 0) {
37005 var nextExplicitTarget = queuedExplicitHydrationTargets[0];
37006
37007 if (nextExplicitTarget.blockedOn !== null) {
37008 // We're still blocked.
37009 break;
37010 } else {
37011 attemptExplicitHydrationTarget(nextExplicitTarget);
37012
37013 if (nextExplicitTarget.blockedOn === null) {
37014 // We're unblocked.
37015 queuedExplicitHydrationTargets.shift();
37016 }
37017 }
37018 } // Check the document if there are any queued form actions.
37019 // If there's no ownerDocument, then this is the document.
37020
37021
37022 var root = unblocked.ownerDocument || unblocked;
37023 var formReplayingQueue = root.$$reactFormReplay;
37024
37025 if (formReplayingQueue != null) {
37026 for (var _i = 0; _i < formReplayingQueue.length; _i += 3) {
37027 var form = formReplayingQueue[_i];
37028 var submitterOrAction = formReplayingQueue[_i + 1];
37029 var formProps = getFiberCurrentPropsFromNode(form);
37030
37031 if (typeof submitterOrAction === 'function') {
37032 // This action has already resolved. We're just waiting to dispatch it.
37033 if (!formProps) {
37034 // This was not part of this React instance. It might have been recently
37035 // unblocking us from dispatching our events. So let's make sure we schedule
37036 // a retry.
37037 scheduleReplayQueueIfNeeded(formReplayingQueue);
37038 }
37039
37040 continue;
37041 }
37042
37043 var target = form;
37044
37045 if (formProps) {
37046 // This form belongs to this React instance but the submitter might
37047 // not be done yet.
37048 var action = null;
37049 var submitter = submitterOrAction;
37050
37051 if (submitter && submitter.hasAttribute('formAction')) {
37052 // The submitter is the one that is responsible for the action.
37053 target = submitter;
37054 var submitterProps = getFiberCurrentPropsFromNode(submitter);
37055
37056 if (submitterProps) {
37057 // The submitter is part of this instance.
37058 action = submitterProps.formAction;
37059 } else {
37060 var blockedOn = findInstanceBlockingTarget(target);
37061
37062 if (blockedOn !== null) {
37063 // The submitter is not hydrated yet. We'll wait for it.
37064 continue;
37065 } // The submitter must have been a part of a different React instance.
37066 // Except the form isn't. We don't dispatch actions in this scenario.
37067
37068 }
37069 } else {
37070 action = formProps.action;
37071 }
37072
37073 if (typeof action === 'function') {
37074 formReplayingQueue[_i + 1] = action;
37075 } else {
37076 // Something went wrong so let's just delete this action.
37077 formReplayingQueue.splice(_i, 3);
37078 _i -= 3;
37079 } // Schedule a replay in case this unblocked something.
37080
37081
37082 scheduleReplayQueueIfNeeded(formReplayingQueue);
37083 continue;
37084 } // Something above this target is still blocked so we can't continue yet.
37085 // We're not sure if this target is actually part of this React instance
37086 // yet. It could be a different React as a child but at least some parent is.
37087 // We must continue for any further queued actions.
37088
37089 }
37090 }
37091}
37092
37093function ReactDOMRoot(internalRoot) {
37094 this._internalRoot = internalRoot;
37095} // $FlowFixMe[prop-missing] found when upgrading Flow
37096
37097
37098ReactDOMHydrationRoot.prototype.render = ReactDOMRoot.prototype.render = // $FlowFixMe[missing-this-annot]
37099function (children) {
37100 var root = this._internalRoot;
37101
37102 if (root === null) {
37103 throw new Error('Cannot update an unmounted root.');
37104 }
37105
37106 {
37107 if (typeof arguments[1] === 'function') {
37108 error('does not support the second callback argument. ' + 'To execute a side effect after rendering, declare it in a component body with useEffect().');
37109 } else if (isValidContainer(arguments[1])) {
37110 error('You passed a container to the second argument of root.render(...). ' + "You don't need to pass it again since you already passed it to create the root.");
37111 } else if (typeof arguments[1] !== 'undefined') {
37112 error('You passed a second argument to root.render(...) but it only accepts ' + 'one argument.');
37113 }
37114 }
37115
37116 updateContainer(children, root, null, null);
37117}; // $FlowFixMe[prop-missing] found when upgrading Flow
37118
37119
37120ReactDOMHydrationRoot.prototype.unmount = ReactDOMRoot.prototype.unmount = // $FlowFixMe[missing-this-annot]
37121function () {
37122 {
37123 if (typeof arguments[0] === 'function') {
37124 error('does not support a callback argument. ' + 'To execute a side effect after rendering, declare it in a component body with useEffect().');
37125 }
37126 }
37127
37128 var root = this._internalRoot;
37129
37130 if (root !== null) {
37131 this._internalRoot = null;
37132 var container = root.containerInfo;
37133
37134 {
37135 if (isAlreadyRendering()) {
37136 error('Attempted to synchronously unmount a root while React was already ' + 'rendering. React cannot finish unmounting the root until the ' + 'current render has completed, which may lead to a race condition.');
37137 }
37138 }
37139
37140 updateContainerSync(null, root, null, null);
37141 flushSyncWork$1();
37142 unmarkContainerAsRoot(container);
37143 }
37144};
37145
37146function createRoot(container, options) {
37147 if (!isValidContainer(container)) {
37148 throw new Error('Target container is not a DOM element.');
37149 }
37150
37151 warnIfReactDOMContainerInDEV(container);
37152 var isStrictMode = false;
37153 var concurrentUpdatesByDefaultOverride = false;
37154 var identifierPrefix = '';
37155 var onUncaughtError = defaultOnUncaughtError;
37156 var onCaughtError = defaultOnCaughtError;
37157 var onRecoverableError = defaultOnRecoverableError;
37158 var transitionCallbacks = null;
37159
37160 if (options !== null && options !== undefined) {
37161 {
37162 if (options.hydrate) {
37163 warn('hydrate through createRoot is deprecated. Use ReactDOMClient.hydrateRoot(container, <App />) instead.');
37164 } else {
37165 if (typeof options === 'object' && options !== null && options.$$typeof === REACT_ELEMENT_TYPE) {
37166 error('You passed a JSX element to createRoot. You probably meant to ' + 'call root.render instead. ' + 'Example usage:\n\n' + ' let root = createRoot(domContainer);\n' + ' root.render(<App />);');
37167 }
37168 }
37169 }
37170
37171 if (options.unstable_strictMode === true) {
37172 isStrictMode = true;
37173 }
37174
37175 if (options.identifierPrefix !== undefined) {
37176 identifierPrefix = options.identifierPrefix;
37177 }
37178
37179 if (options.onUncaughtError !== undefined) {
37180 onUncaughtError = options.onUncaughtError;
37181 }
37182
37183 if (options.onCaughtError !== undefined) {
37184 onCaughtError = options.onCaughtError;
37185 }
37186
37187 if (options.onRecoverableError !== undefined) {
37188 onRecoverableError = options.onRecoverableError;
37189 }
37190
37191 if (options.unstable_transitionCallbacks !== undefined) {
37192 transitionCallbacks = options.unstable_transitionCallbacks;
37193 }
37194 }
37195
37196 var root = createContainer(container, ConcurrentRoot, null, isStrictMode, concurrentUpdatesByDefaultOverride, identifierPrefix, onUncaughtError, onCaughtError, onRecoverableError, transitionCallbacks);
37197 markContainerAsRoot(root.current, container);
37198 var rootContainerElement = container.nodeType === COMMENT_NODE ? container.parentNode : container;
37199 listenToAllSupportedEvents(rootContainerElement); // $FlowFixMe[invalid-constructor] Flow no longer supports calling new on functions
37200
37201 return new ReactDOMRoot(root);
37202} // $FlowFixMe[missing-this-annot]
37203
37204function ReactDOMHydrationRoot(internalRoot) {
37205 this._internalRoot = internalRoot;
37206}
37207
37208function scheduleHydration(target) {
37209 if (target) {
37210 queueExplicitHydrationTarget(target);
37211 }
37212} // $FlowFixMe[prop-missing] found when upgrading Flow
37213
37214
37215ReactDOMHydrationRoot.prototype.unstable_scheduleHydration = scheduleHydration;
37216function hydrateRoot(container, initialChildren, options) {
37217 if (!isValidContainer(container)) {
37218 throw new Error('Target container is not a DOM element.');
37219 }
37220
37221 warnIfReactDOMContainerInDEV(container);
37222
37223 {
37224 if (initialChildren === undefined) {
37225 error('Must provide initial children as second argument to hydrateRoot. ' + 'Example usage: hydrateRoot(domContainer, <App />)');
37226 }
37227 } // For now we reuse the whole bag of options since they contain
37228 // the hydration callbacks.
37229
37230
37231 var hydrationCallbacks = options != null ? options : null;
37232 var isStrictMode = false;
37233 var concurrentUpdatesByDefaultOverride = false;
37234 var identifierPrefix = '';
37235 var onUncaughtError = defaultOnUncaughtError;
37236 var onCaughtError = defaultOnCaughtError;
37237 var onRecoverableError = defaultOnRecoverableError;
37238 var transitionCallbacks = null;
37239 var formState = null;
37240
37241 if (options !== null && options !== undefined) {
37242 if (options.unstable_strictMode === true) {
37243 isStrictMode = true;
37244 }
37245
37246 if (options.identifierPrefix !== undefined) {
37247 identifierPrefix = options.identifierPrefix;
37248 }
37249
37250 if (options.onUncaughtError !== undefined) {
37251 onUncaughtError = options.onUncaughtError;
37252 }
37253
37254 if (options.onCaughtError !== undefined) {
37255 onCaughtError = options.onCaughtError;
37256 }
37257
37258 if (options.onRecoverableError !== undefined) {
37259 onRecoverableError = options.onRecoverableError;
37260 }
37261
37262 if (options.unstable_transitionCallbacks !== undefined) {
37263 transitionCallbacks = options.unstable_transitionCallbacks;
37264 }
37265
37266 {
37267 if (options.formState !== undefined) {
37268 formState = options.formState;
37269 }
37270 }
37271 }
37272
37273 var root = createHydrationContainer(initialChildren, null, container, ConcurrentRoot, hydrationCallbacks, isStrictMode, concurrentUpdatesByDefaultOverride, identifierPrefix, onUncaughtError, onCaughtError, onRecoverableError, transitionCallbacks, formState);
37274 markContainerAsRoot(root.current, container); // This can't be a comment node since hydration doesn't work on comment nodes anyway.
37275
37276 listenToAllSupportedEvents(container); // $FlowFixMe[invalid-constructor] Flow no longer supports calling new on functions
37277
37278 return new ReactDOMHydrationRoot(root);
37279}
37280
37281function warnIfReactDOMContainerInDEV(container) {
37282 {
37283 if (isContainerMarkedAsRoot(container)) {
37284 if (container._reactRootContainer) {
37285 error('You are calling ReactDOMClient.createRoot() on a container that was previously ' + 'passed to ReactDOM.render(). This is not supported.');
37286 } else {
37287 error('You are calling ReactDOMClient.createRoot() on a container that ' + 'has already been passed to createRoot() before. Instead, call ' + 'root.render() on the existing root instead if you want to update it.');
37288 }
37289 }
37290 }
37291}
37292
37293{
37294 if (typeof Map !== 'function' || // $FlowFixMe[prop-missing] Flow incorrectly thinks Map has no prototype
37295 Map.prototype == null || typeof Map.prototype.forEach !== 'function' || typeof Set !== 'function' || // $FlowFixMe[prop-missing] Flow incorrectly thinks Set has no prototype
37296 Set.prototype == null || typeof Set.prototype.clear !== 'function' || typeof Set.prototype.forEach !== 'function') {
37297 error('React depends on Map and Set built-in types. Make sure that you load a ' + 'polyfill in older browsers. https://react.dev/link/react-polyfills');
37298 }
37299}
37300
37301function findDOMNode(componentOrElement) {
37302 return findHostInstance(componentOrElement);
37303} // Expose findDOMNode on internals
37304
37305
37306ReactDOMSharedInternals.findDOMNode = findDOMNode;
37307var foundDevTools = injectIntoDevTools({
37308 findFiberByHostInstance: getClosestInstanceFromNode,
37309 bundleType: 1 ,
37310 version: ReactVersion,
37311 rendererPackageName: 'react-dom'
37312});
37313
37314{
37315 if (!foundDevTools && canUseDOM && window.top === window.self) {
37316 // If we're in Chrome or Firefox, provide a download link if not installed.
37317 if (navigator.userAgent.indexOf('Chrome') > -1 && navigator.userAgent.indexOf('Edge') === -1 || navigator.userAgent.indexOf('Firefox') > -1) {
37318 var protocol = window.location.protocol; // Don't warn in exotic cases like chrome-extension://.
37319
37320 if (/^(https?|file):$/.test(protocol)) {
37321 // eslint-disable-next-line react-internal/no-production-logging
37322 console.info('%cDownload the React DevTools ' + 'for a better development experience: ' + 'https://react.dev/link/react-devtools' + (protocol === 'file:' ? '\nYou might need to use a local HTTP server (instead of file://): ' + 'https://react.dev/link/react-devtools-faq' : ''), 'font-weight:bold');
37323 }
37324 }
37325 }
37326}
37327
37328exports.createRoot = createRoot;
37329exports.hydrateRoot = hydrateRoot;
37330exports.version = ReactVersion;
37331 /* global __REACT_DEVTOOLS_GLOBAL_HOOK__ */
37332if (
37333 typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ !== 'undefined' &&
37334 typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop ===
37335 'function'
37336) {
37337 __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop(new Error());
37338}
37339
37340 })();
37341}