/** * @license React * react-dom.development.js * * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ 'use strict'; if (process.env.NODE_ENV !== "production") { (function() { 'use strict'; /* global __REACT_DEVTOOLS_GLOBAL_HOOK__ */ if ( typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ !== 'undefined' && typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart === 'function' ) { __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart(new Error()); } var React = require("next/dist/compiled/react-experimental"); var Scheduler = require("next/dist/compiled/scheduler-experimental"); var Internals = { usingClientEntryPoint: false, Events: null, Dispatcher: { current: null } }; var ReactSharedInternals = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED; var suppressWarning = false; function setSuppressWarning(newSuppressWarning) { { suppressWarning = newSuppressWarning; } } // In DEV, calls to console.warn and console.error get replaced // by calls to these methods by a Babel plugin. // // In PROD (or in packages without access to React internals), // they are left as they are instead. function warn(format) { { if (!suppressWarning) { for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { args[_key - 1] = arguments[_key]; } printWarning('warn', format, args); } } } function error(format) { { if (!suppressWarning) { for (var _len2 = arguments.length, args = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) { args[_key2 - 1] = arguments[_key2]; } printWarning('error', format, args); } } } function printWarning(level, format, args) { // When changing this logic, you might want to also // update consoleWithStackDev.www.js as well. { var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame; var stack = ReactDebugCurrentFrame.getStackAddendum(); if (stack !== '') { format += '%s'; args = args.concat([stack]); } // eslint-disable-next-line react-internal/safe-string-coercion var argsWithFormat = args.map(function (item) { return String(item); }); // Careful: RN currently depends on this prefix argsWithFormat.unshift('Warning: ' + format); // We intentionally don't use spread (or .apply) directly because it // breaks IE9: https://github.com/facebook/react/issues/13610 // eslint-disable-next-line react-internal/no-production-logging Function.prototype.apply.call(console[level], console, argsWithFormat); } } var assign = Object.assign; // ----------------------------------------------------------------------------- // Killswitch // // Flags that exist solely to turn off a change in case it causes a regression // when it rolls out to prod. We should remove these as soon as possible. // ----------------------------------------------------------------------------- // ----------------------------------------------------------------------------- // Land or remove (moderate effort) // // Flags that can be probably deleted or landed, but might require extra effort // like migrating internal callers or performance testing. // ----------------------------------------------------------------------------- // TODO: Finish rolling out in www var enableClientRenderFallbackOnTextMismatch = true; // Not sure if www still uses this. We don't have a replacement but whatever we // Slated for removal in the future (significant effort) // // These are experiments that didn't work out, and never shipped, but we can't // delete from the codebase until we migrate internal callers. // ----------------------------------------------------------------------------- // Add a callback property to suspense to notify which promises are currently // in the update queue. This allows reporting and tracing of what is causing // the user to see a loading state. // // Also allows hydration callbacks to fire when a dehydrated boundary gets // hydrated or deleted. // // This will eventually be replaced by the Transition Tracing proposal. var enableSuspenseCallback = false; // Experimental Scope support. var enableFormActions = true; var enableLazyContextPropagation = false; // FB-only usage. The new API has different semantics. var enableLegacyHidden = false; // Enables unstable_avoidThisFallback feature in Fiber var enableHostSingletons = true; var enableAsyncActions = true; var alwaysThrottleRetries = true; // ----------------------------------------------------------------------------- // Chopping Block // // Planned feature deprecations and breaking changes. Sorted roughly in order of // when we plan to enable them. // ----------------------------------------------------------------------------- // This flag enables Strict Effects by default. We're not turning this on until // after 18 because it requires migration work. Recommendation is to use // to gradually upgrade components. // If TRUE, trees rendered with createRoot will be StrictEffectsMode. // If FALSE, these trees will be StrictLegacyMode. var createRootStrictEffectsByDefault = false; // React DOM Chopping Block // // Similar to main Chopping Block but only flags related to React DOM. These are // grouped because we will likely batch all of them into a single major release. // ----------------------------------------------------------------------------- // Disable support for comment nodes as React DOM containers. Already disabled // in open source, but www codebase still relies on it. Need to remove. var disableCommentsAsDOMContainers = true; // Disable javascript: URL strings in href for XSS protection. var disableIEWorkarounds = true; // Filter certain DOM attributes (e.g. src, href) if their values are empty // Debugging and DevTools // ----------------------------------------------------------------------------- // Adds user timing marks for e.g. state updates, suspense, and work loop stuff, // for an experimental timeline tool. var enableSchedulingProfiler = true; // Helps identify side effects in render-phase lifecycle hooks and setState var enableProfilerTimer = true; // Record durations for commit and passive effects phases. var enableProfilerCommitHooks = true; // Phase param passed to onRender callback differentiates between an "update" and a "cascading-update". var enableProfilerNestedUpdatePhase = true; // Adds verbose console logging for e.g. state updates, suspense, and work loop var ReactCurrentDispatcher$3 = ReactSharedInternals.ReactCurrentDispatcher; // Since the "not pending" value is always the same, we can reuse the // same object across all transitions. var sharedNotPendingObject = { pending: false, data: null, method: null, action: null }; var NotPending = Object.freeze(sharedNotPendingObject) ; function resolveDispatcher() { // Copied from react/src/ReactHooks.js. It's the same thing but in a // different package. var dispatcher = ReactCurrentDispatcher$3.current; { if (dispatcher === null) { 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://reactjs.org/link/invalid-hook-call for tips about how to debug and fix this problem.'); } } // Will result in a null access error if accessed outside render phase. We // intentionally don't throw our own error because this is in a hot path. // Also helps ensure this is inlined. return dispatcher; } function useFormStatus() { { var dispatcher = resolveDispatcher(); // $FlowFixMe[not-a-function] We know this exists because of the feature check above. return dispatcher.useHostTransitionStatus(); } } function useFormState(action, initialState, permalink) { { var dispatcher = resolveDispatcher(); // $FlowFixMe[not-a-function] This is unstable, thus optional return dispatcher.useFormState(action, initialState, permalink); } } var valueStack = []; var fiberStack; { fiberStack = []; } var index = -1; function createCursor(defaultValue) { return { current: defaultValue }; } function pop(cursor, fiber) { if (index < 0) { { error('Unexpected pop.'); } return; } { if (fiber !== fiberStack[index]) { error('Unexpected Fiber popped.'); } } cursor.current = valueStack[index]; valueStack[index] = null; { fiberStack[index] = null; } index--; } function push(cursor, value, fiber) { index++; valueStack[index] = cursor.current; { fiberStack[index] = fiber; } cursor.current = value; } // ATTENTION // When adding new symbols to this file, // Please consider also adding to 'react-devtools-shared/src/backend/ReactSymbols' // The Symbol used to tag the ReactElement-like types. var REACT_ELEMENT_TYPE = Symbol.for('react.element'); var REACT_PORTAL_TYPE = Symbol.for('react.portal'); var REACT_FRAGMENT_TYPE = Symbol.for('react.fragment'); var REACT_STRICT_MODE_TYPE = Symbol.for('react.strict_mode'); var REACT_PROFILER_TYPE = Symbol.for('react.profiler'); var REACT_PROVIDER_TYPE = Symbol.for('react.provider'); var REACT_CONTEXT_TYPE = Symbol.for('react.context'); var REACT_SERVER_CONTEXT_TYPE = Symbol.for('react.server_context'); var REACT_FORWARD_REF_TYPE = Symbol.for('react.forward_ref'); var REACT_SUSPENSE_TYPE = Symbol.for('react.suspense'); var REACT_SUSPENSE_LIST_TYPE = Symbol.for('react.suspense_list'); var REACT_MEMO_TYPE = Symbol.for('react.memo'); var REACT_LAZY_TYPE = Symbol.for('react.lazy'); var REACT_SCOPE_TYPE = Symbol.for('react.scope'); var REACT_DEBUG_TRACING_MODE_TYPE = Symbol.for('react.debug_trace_mode'); var REACT_OFFSCREEN_TYPE = Symbol.for('react.offscreen'); var REACT_LEGACY_HIDDEN_TYPE = Symbol.for('react.legacy_hidden'); var REACT_CACHE_TYPE = Symbol.for('react.cache'); var REACT_TRACING_MARKER_TYPE = Symbol.for('react.tracing_marker'); var REACT_SERVER_CONTEXT_DEFAULT_VALUE_NOT_LOADED = Symbol.for('react.default_value'); var REACT_MEMO_CACHE_SENTINEL = Symbol.for('react.memo_cache_sentinel'); var REACT_POSTPONE_TYPE = Symbol.for('react.postpone'); var MAYBE_ITERATOR_SYMBOL = Symbol.iterator; var FAUX_ITERATOR_SYMBOL = '@@iterator'; function getIteratorFn(maybeIterable) { if (maybeIterable === null || typeof maybeIterable !== 'object') { return null; } var maybeIterator = MAYBE_ITERATOR_SYMBOL && maybeIterable[MAYBE_ITERATOR_SYMBOL] || maybeIterable[FAUX_ITERATOR_SYMBOL]; if (typeof maybeIterator === 'function') { return maybeIterator; } return null; } var contextStackCursor$1 = createCursor(null); var contextFiberStackCursor = createCursor(null); var rootInstanceStackCursor = createCursor(null); // Represents the nearest host transition provider (in React DOM, a
) // NOTE: Since forms cannot be nested, and this feature is only implemented by // React DOM, we don't technically need this to be a stack. It could be a single // module variable instead. var hostTransitionProviderCursor = createCursor(null); // TODO: This should initialize to NotPendingTransition, a constant // imported from the fiber config. However, because of a cycle in the module // graph, that value isn't defined during this module's initialization. I can't // think of a way to work around this without moving that value out of the // fiber config. For now, the "no provider" case is handled when reading, // inside useHostTransitionStatus. var HostTransitionContext = { $$typeof: REACT_CONTEXT_TYPE, _currentValue: null, _currentValue2: null, _threadCount: 0, Provider: null, Consumer: null, _defaultValue: null, _globalName: null }; function requiredContext(c) { { if (c === null) { error('Expected host context to exist. This error is likely caused by a bug ' + 'in React. Please file an issue.'); } } return c; } function getCurrentRootHostContainer() { return rootInstanceStackCursor.current; } function getRootHostContainer() { var rootInstance = requiredContext(rootInstanceStackCursor.current); return rootInstance; } function pushHostContainer(fiber, nextRootInstance) { // Push current root instance onto the stack; // This allows us to reset root when portals are popped. push(rootInstanceStackCursor, nextRootInstance, fiber); // Track the context and the Fiber that provided it. // This enables us to pop only Fibers that provide unique contexts. push(contextFiberStackCursor, fiber, fiber); // Finally, we need to push the host context to the stack. // However, we can't just call getRootHostContext() and push it because // we'd have a different number of entries on the stack depending on // whether getRootHostContext() throws somewhere in renderer code or not. // So we push an empty value first. This lets us safely unwind on errors. push(contextStackCursor$1, null, fiber); var nextRootContext = getRootHostContext(nextRootInstance); // Now that we know this function doesn't throw, replace it. pop(contextStackCursor$1, fiber); push(contextStackCursor$1, nextRootContext, fiber); } function popHostContainer(fiber) { pop(contextStackCursor$1, fiber); pop(contextFiberStackCursor, fiber); pop(rootInstanceStackCursor, fiber); } function getHostContext() { var context = requiredContext(contextStackCursor$1.current); return context; } function pushHostContext(fiber) { { var stateHook = fiber.memoizedState; if (stateHook !== null) { // Only provide context if this fiber has been upgraded by a host // transition. We use the same optimization for regular host context below. push(hostTransitionProviderCursor, fiber, fiber); } } var context = requiredContext(contextStackCursor$1.current); var nextContext = getChildHostContext(context, fiber.type); // Don't push this Fiber's context unless it's unique. if (context !== nextContext) { // Track the context and the Fiber that provided it. // This enables us to pop only Fibers that provide unique contexts. push(contextFiberStackCursor, fiber, fiber); push(contextStackCursor$1, nextContext, fiber); } } function popHostContext(fiber) { if (contextFiberStackCursor.current === fiber) { // Do not pop unless this Fiber provided the current context. // pushHostContext() only pushes Fibers that provide unique contexts. pop(contextStackCursor$1, fiber); pop(contextFiberStackCursor, fiber); } { if (hostTransitionProviderCursor.current === fiber) { // Do not pop unless this Fiber provided the current context. This is mostly // a performance optimization, but conveniently it also prevents a potential // data race where a host provider is upgraded (i.e. memoizedState becomes // non-null) during a concurrent event. This is a bit of a flaw in the way // we upgrade host components, but because we're accounting for it here, it // should be fine. pop(hostTransitionProviderCursor, fiber); // When popping the transition provider, we reset the context value back // to `null`. We can do this because you're not allowd to nest forms. If // we allowed for multiple nested host transition providers, then we'd // need to reset this to the parent provider's status. { HostTransitionContext._currentValue = null; } } } } var NoFlags$1 = /* */ 0; var PerformedWork = /* */ 1; var Placement = /* */ 2; var DidCapture = /* */ 128; var Hydrating = /* */ 4096; // You can change the rest (and add more). var Update = /* */ 4; /* Skipped value: 0b0000000000000000000000001000; */ var ChildDeletion = /* */ 16; var ContentReset = /* */ 32; var Callback = /* */ 64; /* Used by DidCapture: 0b0000000000000000000010000000; */ var ForceClientRender = /* */ 256; var Ref = /* */ 512; var Snapshot = /* */ 1024; var Passive$1 = /* */ 2048; /* Used by Hydrating: 0b0000000000000001000000000000; */ var Visibility = /* */ 8192; var StoreConsistency = /* */ 16384; // It's OK to reuse these bits because these flags are mutually exclusive for // different fiber types. We should really be doing this for as many flags as // possible, because we're about to run out of bits. var ScheduleRetry = StoreConsistency; var ShouldSuspendCommit = Visibility; var LifecycleEffectMask = Passive$1 | Update | Callback | Ref | Snapshot | StoreConsistency; // Union of all commit flags (flags with the lifetime of a particular commit) var HostEffectMask = /* */ 32767; // These are not really side effects, but we still reuse this field. var Incomplete = /* */ 32768; var ShouldCapture = /* */ 65536; var ForceUpdateForLegacySuspense = /* */ 131072; var Forked = /* */ 1048576; // Static tags describe aspects of a fiber that are not specific to a render, // e.g. a fiber uses a passive effect (even if there are no updates on this particular render). // This enables us to defer more work in the unmount case, // since we can defer traversing the tree during layout to look for Passive effects, // and instead rely on the static flag as a signal that there may be cleanup work. var RefStatic = /* */ 2097152; var LayoutStatic = /* */ 4194304; var PassiveStatic = /* */ 8388608; var MaySuspendCommit = /* */ 16777216; // Flag used to identify newly inserted fibers. It isn't reset after commit unlike `Placement`. var PlacementDEV = /* */ 33554432; var MountLayoutDev = /* */ 67108864; var MountPassiveDev = /* */ 134217728; // Groups of flags that are used in the commit phase to skip over trees that // don't contain effects, by checking subtreeFlags. var BeforeMutationMask = // TODO: Remove Update flag from before mutation phase by re-landing Visibility // flag logic (see #20043) Update | Snapshot | (0); var MutationMask = Placement | Update | ChildDeletion | ContentReset | Ref | Hydrating | Visibility; var LayoutMask = Update | Callback | Ref | Visibility; // TODO: Split into PassiveMountMask and PassiveUnmountMask var PassiveMask = Passive$1 | Visibility | ChildDeletion; // Union of tags that don't get reset on clones. // This allows certain concepts to persist without recalculating them, // e.g. whether a subtree contains passive effects or portals. var StaticMask = LayoutStatic | PassiveStatic | RefStatic | MaySuspendCommit; // This module only exists as an ESM wrapper around the external CommonJS var scheduleCallback$3 = Scheduler.unstable_scheduleCallback; var cancelCallback$1 = Scheduler.unstable_cancelCallback; var shouldYield = Scheduler.unstable_shouldYield; var requestPaint = Scheduler.unstable_requestPaint; var now$1 = Scheduler.unstable_now; var getCurrentPriorityLevel = Scheduler.unstable_getCurrentPriorityLevel; var ImmediatePriority = Scheduler.unstable_ImmediatePriority; var UserBlockingPriority = Scheduler.unstable_UserBlockingPriority; var NormalPriority$1 = Scheduler.unstable_NormalPriority; var LowPriority = Scheduler.unstable_LowPriority; var IdlePriority = Scheduler.unstable_IdlePriority; // this doesn't actually exist on the scheduler, but it *does* // on scheduler/unstable_mock, which we'll need for internal testing var log$1 = Scheduler.log; var unstable_setDisableYieldValue = Scheduler.unstable_setDisableYieldValue; // Helpers to patch console.logs to avoid logging during side-effect free // replaying on render function. This currently only patches the object // lazily which won't cover if the log function was extracted eagerly. // We could also eagerly patch the method. var disabledDepth = 0; var prevLog; var prevInfo; var prevWarn; var prevError; var prevGroup; var prevGroupCollapsed; var prevGroupEnd; function disabledLog() {} disabledLog.__reactDisabledLog = true; function disableLogs() { { if (disabledDepth === 0) { /* eslint-disable react-internal/no-production-logging */ prevLog = console.log; prevInfo = console.info; prevWarn = console.warn; prevError = console.error; prevGroup = console.group; prevGroupCollapsed = console.groupCollapsed; prevGroupEnd = console.groupEnd; // https://github.com/facebook/react/issues/19099 var props = { configurable: true, enumerable: true, value: disabledLog, writable: true }; // $FlowFixMe[cannot-write] Flow thinks console is immutable. Object.defineProperties(console, { info: props, log: props, warn: props, error: props, group: props, groupCollapsed: props, groupEnd: props }); /* eslint-enable react-internal/no-production-logging */ } disabledDepth++; } } function reenableLogs() { { disabledDepth--; if (disabledDepth === 0) { /* eslint-disable react-internal/no-production-logging */ var props = { configurable: true, enumerable: true, writable: true }; // $FlowFixMe[cannot-write] Flow thinks console is immutable. Object.defineProperties(console, { log: assign({}, props, { value: prevLog }), info: assign({}, props, { value: prevInfo }), warn: assign({}, props, { value: prevWarn }), error: assign({}, props, { value: prevError }), group: assign({}, props, { value: prevGroup }), groupCollapsed: assign({}, props, { value: prevGroupCollapsed }), groupEnd: assign({}, props, { value: prevGroupEnd }) }); /* eslint-enable react-internal/no-production-logging */ } if (disabledDepth < 0) { error('disabledDepth fell below zero. ' + 'This is a bug in React. Please file an issue.'); } } } var rendererID = null; var injectedHook = null; var injectedProfilingHooks = null; var hasLoggedError = false; var isDevToolsPresent = typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ !== 'undefined'; function injectInternals(internals) { if (typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ === 'undefined') { // No DevTools return false; } var hook = __REACT_DEVTOOLS_GLOBAL_HOOK__; if (hook.isDisabled) { // This isn't a real property on the hook, but it can be set to opt out // of DevTools integration and associated warnings and logs. // https://github.com/facebook/react/issues/3877 return true; } if (!hook.supportsFiber) { { 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://reactjs.org/link/react-devtools'); } // DevTools exists, even though it doesn't support Fiber. return true; } try { if (enableSchedulingProfiler) { // Conditionally inject these hooks only if Timeline profiler is supported by this build. // This gives DevTools a way to feature detect that isn't tied to version number // (since profiling and timeline are controlled by different feature flags). internals = assign({}, internals, { getLaneLabelMap: getLaneLabelMap, injectProfilingHooks: injectProfilingHooks }); } rendererID = hook.inject(internals); // We have successfully injected, so now it is safe to set up hooks. injectedHook = hook; } catch (err) { // Catch all errors because it is unsafe to throw during initialization. { error('React instrumentation encountered an error: %s.', err); } } if (hook.checkDCE) { // This is the real DevTools. return true; } else { // This is likely a hook installed by Fast Refresh runtime. return false; } } function onScheduleRoot(root, children) { { if (injectedHook && typeof injectedHook.onScheduleFiberRoot === 'function') { try { injectedHook.onScheduleFiberRoot(rendererID, root, children); } catch (err) { if (!hasLoggedError) { hasLoggedError = true; error('React instrumentation encountered an error: %s', err); } } } } } function onCommitRoot$1(root, eventPriority) { if (injectedHook && typeof injectedHook.onCommitFiberRoot === 'function') { try { var didError = (root.current.flags & DidCapture) === DidCapture; if (enableProfilerTimer) { var schedulerPriority; switch (eventPriority) { case DiscreteEventPriority: schedulerPriority = ImmediatePriority; break; case ContinuousEventPriority: schedulerPriority = UserBlockingPriority; break; case DefaultEventPriority: schedulerPriority = NormalPriority$1; break; case IdleEventPriority: schedulerPriority = IdlePriority; break; default: schedulerPriority = NormalPriority$1; break; } injectedHook.onCommitFiberRoot(rendererID, root, schedulerPriority, didError); } } catch (err) { { if (!hasLoggedError) { hasLoggedError = true; error('React instrumentation encountered an error: %s', err); } } } } } function onPostCommitRoot(root) { if (injectedHook && typeof injectedHook.onPostCommitFiberRoot === 'function') { try { injectedHook.onPostCommitFiberRoot(rendererID, root); } catch (err) { { if (!hasLoggedError) { hasLoggedError = true; error('React instrumentation encountered an error: %s', err); } } } } } function onCommitUnmount(fiber) { if (injectedHook && typeof injectedHook.onCommitFiberUnmount === 'function') { try { injectedHook.onCommitFiberUnmount(rendererID, fiber); } catch (err) { { if (!hasLoggedError) { hasLoggedError = true; error('React instrumentation encountered an error: %s', err); } } } } } function setIsStrictModeForDevtools(newIsStrictMode) { { if (typeof log$1 === 'function') { // We're in a test because Scheduler.log only exists // in SchedulerMock. To reduce the noise in strict mode tests, // suppress warnings and disable scheduler yielding during the double render unstable_setDisableYieldValue(newIsStrictMode); setSuppressWarning(newIsStrictMode); } if (injectedHook && typeof injectedHook.setStrictMode === 'function') { try { injectedHook.setStrictMode(rendererID, newIsStrictMode); } catch (err) { { if (!hasLoggedError) { hasLoggedError = true; error('React instrumentation encountered an error: %s', err); } } } } } } // Profiler API hooks function injectProfilingHooks(profilingHooks) { injectedProfilingHooks = profilingHooks; } function getLaneLabelMap() { { var map = new Map(); var lane = 1; for (var index = 0; index < TotalLanes; index++) { var label = getLabelForLane(lane); map.set(lane, label); lane *= 2; } return map; } } function markCommitStarted(lanes) { { if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markCommitStarted === 'function') { injectedProfilingHooks.markCommitStarted(lanes); } } } function markCommitStopped() { { if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markCommitStopped === 'function') { injectedProfilingHooks.markCommitStopped(); } } } function markComponentRenderStarted(fiber) { { if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markComponentRenderStarted === 'function') { injectedProfilingHooks.markComponentRenderStarted(fiber); } } } function markComponentRenderStopped() { { if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markComponentRenderStopped === 'function') { injectedProfilingHooks.markComponentRenderStopped(); } } } function markComponentPassiveEffectMountStarted(fiber) { { if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markComponentPassiveEffectMountStarted === 'function') { injectedProfilingHooks.markComponentPassiveEffectMountStarted(fiber); } } } function markComponentPassiveEffectMountStopped() { { if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markComponentPassiveEffectMountStopped === 'function') { injectedProfilingHooks.markComponentPassiveEffectMountStopped(); } } } function markComponentPassiveEffectUnmountStarted(fiber) { { if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markComponentPassiveEffectUnmountStarted === 'function') { injectedProfilingHooks.markComponentPassiveEffectUnmountStarted(fiber); } } } function markComponentPassiveEffectUnmountStopped() { { if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markComponentPassiveEffectUnmountStopped === 'function') { injectedProfilingHooks.markComponentPassiveEffectUnmountStopped(); } } } function markComponentLayoutEffectMountStarted(fiber) { { if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markComponentLayoutEffectMountStarted === 'function') { injectedProfilingHooks.markComponentLayoutEffectMountStarted(fiber); } } } function markComponentLayoutEffectMountStopped() { { if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markComponentLayoutEffectMountStopped === 'function') { injectedProfilingHooks.markComponentLayoutEffectMountStopped(); } } } function markComponentLayoutEffectUnmountStarted(fiber) { { if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markComponentLayoutEffectUnmountStarted === 'function') { injectedProfilingHooks.markComponentLayoutEffectUnmountStarted(fiber); } } } function markComponentLayoutEffectUnmountStopped() { { if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markComponentLayoutEffectUnmountStopped === 'function') { injectedProfilingHooks.markComponentLayoutEffectUnmountStopped(); } } } function markComponentErrored(fiber, thrownValue, lanes) { { if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markComponentErrored === 'function') { injectedProfilingHooks.markComponentErrored(fiber, thrownValue, lanes); } } } function markComponentSuspended(fiber, wakeable, lanes) { { if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markComponentSuspended === 'function') { injectedProfilingHooks.markComponentSuspended(fiber, wakeable, lanes); } } } function markLayoutEffectsStarted(lanes) { { if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markLayoutEffectsStarted === 'function') { injectedProfilingHooks.markLayoutEffectsStarted(lanes); } } } function markLayoutEffectsStopped() { { if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markLayoutEffectsStopped === 'function') { injectedProfilingHooks.markLayoutEffectsStopped(); } } } function markPassiveEffectsStarted(lanes) { { if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markPassiveEffectsStarted === 'function') { injectedProfilingHooks.markPassiveEffectsStarted(lanes); } } } function markPassiveEffectsStopped() { { if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markPassiveEffectsStopped === 'function') { injectedProfilingHooks.markPassiveEffectsStopped(); } } } function markRenderStarted(lanes) { { if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markRenderStarted === 'function') { injectedProfilingHooks.markRenderStarted(lanes); } } } function markRenderYielded() { { if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markRenderYielded === 'function') { injectedProfilingHooks.markRenderYielded(); } } } function markRenderStopped() { { if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markRenderStopped === 'function') { injectedProfilingHooks.markRenderStopped(); } } } function markRenderScheduled(lane) { { if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markRenderScheduled === 'function') { injectedProfilingHooks.markRenderScheduled(lane); } } } function markForceUpdateScheduled(fiber, lane) { { if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markForceUpdateScheduled === 'function') { injectedProfilingHooks.markForceUpdateScheduled(fiber, lane); } } } function markStateUpdateScheduled(fiber, lane) { { if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markStateUpdateScheduled === 'function') { injectedProfilingHooks.markStateUpdateScheduled(fiber, lane); } } } var NoMode = /* */ 0; // TODO: Remove ConcurrentMode by reading from the root tag instead var ConcurrentMode = /* */ 1; var ProfileMode = /* */ 2; var StrictLegacyMode = /* */ 8; var StrictEffectsMode = /* */ 16; var NoStrictPassiveEffectsMode = /* */ 64; // TODO: This is pretty well supported by browsers. Maybe we can drop it. var clz32 = Math.clz32 ? Math.clz32 : clz32Fallback; // Count leading zeros. // Based on: // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/clz32 var log = Math.log; var LN2 = Math.LN2; function clz32Fallback(x) { var asUint = x >>> 0; if (asUint === 0) { return 32; } return 31 - (log(asUint) / LN2 | 0) | 0; } // If those values are changed that package should be rebuilt and redeployed. var TotalLanes = 31; var NoLanes = /* */ 0; var NoLane = /* */ 0; var SyncHydrationLane = /* */ 1; var SyncLane = /* */ 2; var InputContinuousHydrationLane = /* */ 4; var InputContinuousLane = /* */ 8; var DefaultHydrationLane = /* */ 16; var DefaultLane = /* */ 32; var SyncUpdateLanes = SyncLane | InputContinuousLane | DefaultLane ; var TransitionHydrationLane = /* */ 64; var TransitionLanes = /* */ 8388480; var TransitionLane1 = /* */ 128; var TransitionLane2 = /* */ 256; var TransitionLane3 = /* */ 512; var TransitionLane4 = /* */ 1024; var TransitionLane5 = /* */ 2048; var TransitionLane6 = /* */ 4096; var TransitionLane7 = /* */ 8192; var TransitionLane8 = /* */ 16384; var TransitionLane9 = /* */ 32768; var TransitionLane10 = /* */ 65536; var TransitionLane11 = /* */ 131072; var TransitionLane12 = /* */ 262144; var TransitionLane13 = /* */ 524288; var TransitionLane14 = /* */ 1048576; var TransitionLane15 = /* */ 2097152; var TransitionLane16 = /* */ 4194304; var RetryLanes = /* */ 125829120; var RetryLane1 = /* */ 8388608; var RetryLane2 = /* */ 16777216; var RetryLane3 = /* */ 33554432; var RetryLane4 = /* */ 67108864; var SomeRetryLane = RetryLane1; var SelectiveHydrationLane = /* */ 134217728; var NonIdleLanes = /* */ 268435455; var IdleHydrationLane = /* */ 268435456; var IdleLane = /* */ 536870912; var OffscreenLane = /* */ 1073741824; // Any lane that might schedule an update. This is used to detect infinite // update loops, so it doesn't include hydration lanes or retries. var UpdateLanes = SyncLane | InputContinuousLane | DefaultLane | TransitionLanes; // This function is used for the experimental timeline (react-devtools-timeline) // It should be kept in sync with the Lanes values above. function getLabelForLane(lane) { { if (lane & SyncHydrationLane) { return 'SyncHydrationLane'; } if (lane & SyncLane) { return 'Sync'; } if (lane & InputContinuousHydrationLane) { return 'InputContinuousHydration'; } if (lane & InputContinuousLane) { return 'InputContinuous'; } if (lane & DefaultHydrationLane) { return 'DefaultHydration'; } if (lane & DefaultLane) { return 'Default'; } if (lane & TransitionHydrationLane) { return 'TransitionHydration'; } if (lane & TransitionLanes) { return 'Transition'; } if (lane & RetryLanes) { return 'Retry'; } if (lane & SelectiveHydrationLane) { return 'SelectiveHydration'; } if (lane & IdleHydrationLane) { return 'IdleHydration'; } if (lane & IdleLane) { return 'Idle'; } if (lane & OffscreenLane) { return 'Offscreen'; } } } var NoTimestamp = -1; var nextTransitionLane = TransitionLane1; var nextRetryLane = RetryLane1; function getHighestPriorityLanes(lanes) { { var pendingSyncLanes = lanes & SyncUpdateLanes; if (pendingSyncLanes !== 0) { return pendingSyncLanes; } } switch (getHighestPriorityLane(lanes)) { case SyncHydrationLane: return SyncHydrationLane; case SyncLane: return SyncLane; case InputContinuousHydrationLane: return InputContinuousHydrationLane; case InputContinuousLane: return InputContinuousLane; case DefaultHydrationLane: return DefaultHydrationLane; case DefaultLane: return DefaultLane; case TransitionHydrationLane: return TransitionHydrationLane; case TransitionLane1: case TransitionLane2: case TransitionLane3: case TransitionLane4: case TransitionLane5: case TransitionLane6: case TransitionLane7: case TransitionLane8: case TransitionLane9: case TransitionLane10: case TransitionLane11: case TransitionLane12: case TransitionLane13: case TransitionLane14: case TransitionLane15: case TransitionLane16: return lanes & TransitionLanes; case RetryLane1: case RetryLane2: case RetryLane3: case RetryLane4: return lanes & RetryLanes; case SelectiveHydrationLane: return SelectiveHydrationLane; case IdleHydrationLane: return IdleHydrationLane; case IdleLane: return IdleLane; case OffscreenLane: return OffscreenLane; default: { error('Should have found matching lanes. This is a bug in React.'); } // This shouldn't be reachable, but as a fallback, return the entire bitmask. return lanes; } } function getNextLanes(root, wipLanes) { // Early bailout if there's no pending work left. var pendingLanes = root.pendingLanes; if (pendingLanes === NoLanes) { return NoLanes; } var nextLanes = NoLanes; var suspendedLanes = root.suspendedLanes; var pingedLanes = root.pingedLanes; // Do not work on any idle work until all the non-idle work has finished, // even if the work is suspended. var nonIdlePendingLanes = pendingLanes & NonIdleLanes; if (nonIdlePendingLanes !== NoLanes) { var nonIdleUnblockedLanes = nonIdlePendingLanes & ~suspendedLanes; if (nonIdleUnblockedLanes !== NoLanes) { nextLanes = getHighestPriorityLanes(nonIdleUnblockedLanes); } else { var nonIdlePingedLanes = nonIdlePendingLanes & pingedLanes; if (nonIdlePingedLanes !== NoLanes) { nextLanes = getHighestPriorityLanes(nonIdlePingedLanes); } } } else { // The only remaining work is Idle. var unblockedLanes = pendingLanes & ~suspendedLanes; if (unblockedLanes !== NoLanes) { nextLanes = getHighestPriorityLanes(unblockedLanes); } else { if (pingedLanes !== NoLanes) { nextLanes = getHighestPriorityLanes(pingedLanes); } } } if (nextLanes === NoLanes) { // This should only be reachable if we're suspended // TODO: Consider warning in this path if a fallback timer is not scheduled. return NoLanes; } // If we're already in the middle of a render, switching lanes will interrupt // it and we'll lose our progress. We should only do this if the new lanes are // higher priority. if (wipLanes !== NoLanes && wipLanes !== nextLanes && // If we already suspended with a delay, then interrupting is fine. Don't // bother waiting until the root is complete. (wipLanes & suspendedLanes) === NoLanes) { var nextLane = getHighestPriorityLane(nextLanes); var wipLane = getHighestPriorityLane(wipLanes); if ( // Tests whether the next lane is equal or lower priority than the wip // one. This works because the bits decrease in priority as you go left. nextLane >= wipLane || // Default priority updates should not interrupt transition updates. The // only difference between default updates and transition updates is that // default updates do not support refresh transitions. nextLane === DefaultLane && (wipLane & TransitionLanes) !== NoLanes) { // Keep working on the existing in-progress tree. Do not interrupt. return wipLanes; } } if ((nextLanes & InputContinuousLane) !== NoLanes) { // When updates are sync by default, we entangle continuous priority updates // and default updates, so they render in the same batch. The only reason // they use separate lanes is because continuous updates should interrupt // transitions, but default updates should not. nextLanes |= pendingLanes & DefaultLane; } // Check for entangled lanes and add them to the batch. // // A lane is said to be entangled with another when it's not allowed to render // in a batch that does not also include the other lane. Typically we do this // when multiple updates have the same source, and we only want to respond to // the most recent event from that source. // // Note that we apply entanglements *after* checking for partial work above. // This means that if a lane is entangled during an interleaved event while // it's already rendering, we won't interrupt it. This is intentional, since // entanglement is usually "best effort": we'll try our best to render the // lanes in the same batch, but it's not worth throwing out partially // completed work in order to do it. // TODO: Reconsider this. The counter-argument is that the partial work // represents an intermediate state, which we don't want to show to the user. // And by spending extra time finishing it, we're increasing the amount of // time it takes to show the final state, which is what they are actually // waiting for. // // For those exceptions where entanglement is semantically important, // we should ensure that there is no partial work at the // time we apply the entanglement. var entangledLanes = root.entangledLanes; if (entangledLanes !== NoLanes) { var entanglements = root.entanglements; var lanes = nextLanes & entangledLanes; while (lanes > 0) { var index = pickArbitraryLaneIndex(lanes); var lane = 1 << index; nextLanes |= entanglements[index]; lanes &= ~lane; } } return nextLanes; } function computeExpirationTime(lane, currentTime) { switch (lane) { case SyncHydrationLane: case SyncLane: case InputContinuousHydrationLane: case InputContinuousLane: // User interactions should expire slightly more quickly. // // NOTE: This is set to the corresponding constant as in Scheduler.js. // When we made it larger, a product metric in www regressed, suggesting // there's a user interaction that's being starved by a series of // synchronous updates. If that theory is correct, the proper solution is // to fix the starvation. However, this scenario supports the idea that // expiration times are an important safeguard when starvation // does happen. return currentTime + 250; case DefaultHydrationLane: case DefaultLane: case TransitionHydrationLane: case TransitionLane1: case TransitionLane2: case TransitionLane3: case TransitionLane4: case TransitionLane5: case TransitionLane6: case TransitionLane7: case TransitionLane8: case TransitionLane9: case TransitionLane10: case TransitionLane11: case TransitionLane12: case TransitionLane13: case TransitionLane14: case TransitionLane15: case TransitionLane16: return currentTime + 5000; case RetryLane1: case RetryLane2: case RetryLane3: case RetryLane4: // TODO: Retries should be allowed to expire if they are CPU bound for // too long, but when I made this change it caused a spike in browser // crashes. There must be some other underlying bug; not super urgent but // ideally should figure out why and fix it. Unfortunately we don't have // a repro for the crashes, only detected via production metrics. return NoTimestamp; case SelectiveHydrationLane: case IdleHydrationLane: case IdleLane: case OffscreenLane: // Anything idle priority or lower should never expire. return NoTimestamp; default: { error('Should have found matching lanes. This is a bug in React.'); } return NoTimestamp; } } function markStarvedLanesAsExpired(root, currentTime) { // TODO: This gets called every time we yield. We can optimize by storing // the earliest expiration time on the root. Then use that to quickly bail out // of this function. var pendingLanes = root.pendingLanes; var suspendedLanes = root.suspendedLanes; var pingedLanes = root.pingedLanes; var expirationTimes = root.expirationTimes; // Iterate through the pending lanes and check if we've reached their // expiration time. If so, we'll assume the update is being starved and mark // it as expired to force it to finish. // // We exclude retry lanes because those must always be time sliced, in order // to unwrap uncached promises. // TODO: Write a test for this var lanes = pendingLanes & ~RetryLanes; while (lanes > 0) { var index = pickArbitraryLaneIndex(lanes); var lane = 1 << index; var expirationTime = expirationTimes[index]; if (expirationTime === NoTimestamp) { // Found a pending lane with no expiration time. If it's not suspended, or // if it's pinged, assume it's CPU-bound. Compute a new expiration time // using the current time. if ((lane & suspendedLanes) === NoLanes || (lane & pingedLanes) !== NoLanes) { // Assumes timestamps are monotonically increasing. expirationTimes[index] = computeExpirationTime(lane, currentTime); } } else if (expirationTime <= currentTime) { // This lane expired root.expiredLanes |= lane; } lanes &= ~lane; } } // This returns the highest priority pending lanes regardless of whether they // are suspended. function getHighestPriorityPendingLanes(root) { return getHighestPriorityLanes(root.pendingLanes); } function getLanesToRetrySynchronouslyOnError(root, originallyAttemptedLanes) { if (root.errorRecoveryDisabledLanes & originallyAttemptedLanes) { // The error recovery mechanism is disabled until these lanes are cleared. return NoLanes; } var everythingButOffscreen = root.pendingLanes & ~OffscreenLane; if (everythingButOffscreen !== NoLanes) { return everythingButOffscreen; } if (everythingButOffscreen & OffscreenLane) { return OffscreenLane; } return NoLanes; } function includesSyncLane(lanes) { return (lanes & (SyncLane | SyncHydrationLane)) !== NoLanes; } function includesNonIdleWork(lanes) { return (lanes & NonIdleLanes) !== NoLanes; } function includesOnlyRetries(lanes) { return (lanes & RetryLanes) === lanes; } function includesOnlyNonUrgentLanes(lanes) { // TODO: Should hydration lanes be included here? This function is only // used in `updateDeferredValueImpl`. var UrgentLanes = SyncLane | InputContinuousLane | DefaultLane; return (lanes & UrgentLanes) === NoLanes; } function includesOnlyTransitions(lanes) { return (lanes & TransitionLanes) === lanes; } function includesBlockingLane(root, lanes) { var SyncDefaultLanes = InputContinuousHydrationLane | InputContinuousLane | DefaultHydrationLane | DefaultLane; return (lanes & SyncDefaultLanes) !== NoLanes; } function includesExpiredLane(root, lanes) { // This is a separate check from includesBlockingLane because a lane can // expire after a render has already started. return (lanes & root.expiredLanes) !== NoLanes; } function isTransitionLane(lane) { return (lane & TransitionLanes) !== NoLanes; } function claimNextTransitionLane() { // Cycle through the lanes, assigning each new transition to the next lane. // In most cases, this means every transition gets its own lane, until we // run out of lanes and cycle back to the beginning. var lane = nextTransitionLane; nextTransitionLane <<= 1; if ((nextTransitionLane & TransitionLanes) === NoLanes) { nextTransitionLane = TransitionLane1; } return lane; } function claimNextRetryLane() { var lane = nextRetryLane; nextRetryLane <<= 1; if ((nextRetryLane & RetryLanes) === NoLanes) { nextRetryLane = RetryLane1; } return lane; } function getHighestPriorityLane(lanes) { return lanes & -lanes; } function pickArbitraryLane(lanes) { // This wrapper function gets inlined. Only exists so to communicate that it // doesn't matter which bit is selected; you can pick any bit without // affecting the algorithms where its used. Here I'm using // getHighestPriorityLane because it requires the fewest operations. return getHighestPriorityLane(lanes); } function pickArbitraryLaneIndex(lanes) { return 31 - clz32(lanes); } function laneToIndex(lane) { return pickArbitraryLaneIndex(lane); } function includesSomeLane(a, b) { return (a & b) !== NoLanes; } function isSubsetOfLanes(set, subset) { return (set & subset) === subset; } function mergeLanes(a, b) { return a | b; } function removeLanes(set, subset) { return set & ~subset; } function intersectLanes(a, b) { return a & b; } // Seems redundant, but it changes the type from a single lane (used for // updates) to a group of lanes (used for flushing work). function laneToLanes(lane) { return lane; } function higherPriorityLane(a, b) { // This works because the bit ranges decrease in priority as you go left. return a !== NoLane && a < b ? a : b; } function createLaneMap(initial) { // Intentionally pushing one by one. // https://v8.dev/blog/elements-kinds#avoid-creating-holes var laneMap = []; for (var i = 0; i < TotalLanes; i++) { laneMap.push(initial); } return laneMap; } function markRootUpdated(root, updateLane) { root.pendingLanes |= updateLane; // If there are any suspended transitions, it's possible this new update // could unblock them. Clear the suspended lanes so that we can try rendering // them again. // // TODO: We really only need to unsuspend only lanes that are in the // `subtreeLanes` of the updated fiber, or the update lanes of the return // path. This would exclude suspended updates in an unrelated sibling tree, // since there's no way for this update to unblock it. // // We don't do this if the incoming update is idle, because we never process // idle updates until after all the regular updates have finished; there's no // way it could unblock a transition. if (updateLane !== IdleLane) { root.suspendedLanes = NoLanes; root.pingedLanes = NoLanes; } } function markRootSuspended$1(root, suspendedLanes) { root.suspendedLanes |= suspendedLanes; root.pingedLanes &= ~suspendedLanes; // The suspended lanes are no longer CPU-bound. Clear their expiration times. var expirationTimes = root.expirationTimes; var lanes = suspendedLanes; while (lanes > 0) { var index = pickArbitraryLaneIndex(lanes); var lane = 1 << index; expirationTimes[index] = NoTimestamp; lanes &= ~lane; } } function markRootPinged(root, pingedLanes) { root.pingedLanes |= root.suspendedLanes & pingedLanes; } function markRootFinished(root, remainingLanes) { var noLongerPendingLanes = root.pendingLanes & ~remainingLanes; root.pendingLanes = remainingLanes; // Let's try everything again root.suspendedLanes = NoLanes; root.pingedLanes = NoLanes; root.expiredLanes &= remainingLanes; root.entangledLanes &= remainingLanes; root.errorRecoveryDisabledLanes &= remainingLanes; root.shellSuspendCounter = 0; var entanglements = root.entanglements; var expirationTimes = root.expirationTimes; var hiddenUpdates = root.hiddenUpdates; // Clear the lanes that no longer have pending work var lanes = noLongerPendingLanes; while (lanes > 0) { var index = pickArbitraryLaneIndex(lanes); var lane = 1 << index; entanglements[index] = NoLanes; expirationTimes[index] = NoTimestamp; var hiddenUpdatesForLane = hiddenUpdates[index]; if (hiddenUpdatesForLane !== null) { hiddenUpdates[index] = null; // "Hidden" updates are updates that were made to a hidden component. They // have special logic associated with them because they may be entangled // with updates that occur outside that tree. But once the outer tree // commits, they behave like regular updates. for (var i = 0; i < hiddenUpdatesForLane.length; i++) { var update = hiddenUpdatesForLane[i]; if (update !== null) { update.lane &= ~OffscreenLane; } } } lanes &= ~lane; } } function markRootEntangled(root, entangledLanes) { // In addition to entangling each of the given lanes with each other, we also // have to consider _transitive_ entanglements. For each lane that is already // entangled with *any* of the given lanes, that lane is now transitively // entangled with *all* the given lanes. // // Translated: If C is entangled with A, then entangling A with B also // entangles C with B. // // If this is hard to grasp, it might help to intentionally break this // function and look at the tests that fail in ReactTransition-test.js. Try // commenting out one of the conditions below. var rootEntangledLanes = root.entangledLanes |= entangledLanes; var entanglements = root.entanglements; var lanes = rootEntangledLanes; while (lanes) { var index = pickArbitraryLaneIndex(lanes); var lane = 1 << index; if ( // Is this one of the newly entangled lanes? lane & entangledLanes | // Is this lane transitively entangled with the newly entangled lanes? entanglements[index] & entangledLanes) { entanglements[index] |= entangledLanes; } lanes &= ~lane; } } function markHiddenUpdate(root, update, lane) { var index = laneToIndex(lane); var hiddenUpdates = root.hiddenUpdates; var hiddenUpdatesForLane = hiddenUpdates[index]; if (hiddenUpdatesForLane === null) { hiddenUpdates[index] = [update]; } else { hiddenUpdatesForLane.push(update); } update.lane = lane | OffscreenLane; } function getBumpedLaneForHydration(root, renderLanes) { var renderLane = getHighestPriorityLane(renderLanes); var lane; if ((renderLane & SyncUpdateLanes) !== NoLane) { lane = SyncHydrationLane; } else { switch (renderLane) { case SyncLane: lane = SyncHydrationLane; break; case InputContinuousLane: lane = InputContinuousHydrationLane; break; case DefaultLane: lane = DefaultHydrationLane; break; case TransitionLane1: case TransitionLane2: case TransitionLane3: case TransitionLane4: case TransitionLane5: case TransitionLane6: case TransitionLane7: case TransitionLane8: case TransitionLane9: case TransitionLane10: case TransitionLane11: case TransitionLane12: case TransitionLane13: case TransitionLane14: case TransitionLane15: case TransitionLane16: case RetryLane1: case RetryLane2: case RetryLane3: case RetryLane4: lane = TransitionHydrationLane; break; case IdleLane: lane = IdleHydrationLane; break; default: // Everything else is already either a hydration lane, or shouldn't // be retried at a hydration lane. lane = NoLane; break; } } // Check if the lane we chose is suspended. If so, that indicates that we // already attempted and failed to hydrate at that level. Also check if we're // already rendering that lane, which is rare but could happen. if ((lane & (root.suspendedLanes | renderLanes)) !== NoLane) { // Give up trying to hydrate and fall back to client render. return NoLane; } return lane; } function addFiberToLanesMap(root, fiber, lanes) { if (!isDevToolsPresent) { return; } var pendingUpdatersLaneMap = root.pendingUpdatersLaneMap; while (lanes > 0) { var index = laneToIndex(lanes); var lane = 1 << index; var updaters = pendingUpdatersLaneMap[index]; updaters.add(fiber); lanes &= ~lane; } } function movePendingFibersToMemoized(root, lanes) { if (!isDevToolsPresent) { return; } var pendingUpdatersLaneMap = root.pendingUpdatersLaneMap; var memoizedUpdaters = root.memoizedUpdaters; while (lanes > 0) { var index = laneToIndex(lanes); var lane = 1 << index; var updaters = pendingUpdatersLaneMap[index]; if (updaters.size > 0) { updaters.forEach(function (fiber) { var alternate = fiber.alternate; if (alternate === null || !memoizedUpdaters.has(alternate)) { memoizedUpdaters.add(fiber); } }); updaters.clear(); } lanes &= ~lane; } } function getTransitionsForLanes(root, lanes) { { return null; } } var DiscreteEventPriority = SyncLane; var ContinuousEventPriority = InputContinuousLane; var DefaultEventPriority = DefaultLane; var IdleEventPriority = IdleLane; var currentUpdatePriority = NoLane; function getCurrentUpdatePriority() { return currentUpdatePriority; } function setCurrentUpdatePriority(newPriority) { currentUpdatePriority = newPriority; } function runWithPriority(priority, fn) { var previousPriority = currentUpdatePriority; try { currentUpdatePriority = priority; return fn(); } finally { currentUpdatePriority = previousPriority; } } function higherEventPriority(a, b) { return a !== 0 && a < b ? a : b; } function lowerEventPriority(a, b) { return a === 0 || a > b ? a : b; } function isHigherEventPriority(a, b) { return a !== 0 && a < b; } function lanesToEventPriority(lanes) { var lane = getHighestPriorityLane(lanes); if (!isHigherEventPriority(DiscreteEventPriority, lane)) { return DiscreteEventPriority; } if (!isHigherEventPriority(ContinuousEventPriority, lane)) { return ContinuousEventPriority; } if (includesNonIdleWork(lane)) { return DefaultEventPriority; } return IdleEventPriority; } // $FlowFixMe[method-unbinding] var hasOwnProperty = Object.prototype.hasOwnProperty; /* * The `'' + value` pattern (used in perf-sensitive code) throws for Symbol * and Temporal.* types. See https://github.com/facebook/react/pull/22064. * * The functions in this module will throw an easier-to-understand, * easier-to-debug exception with a clear errors message message explaining the * problem. (Instead of a confusing exception thrown inside the implementation * of the `value` object). */ // $FlowFixMe[incompatible-return] only called in DEV, so void return is not possible. function typeName(value) { { // toStringTag is needed for namespaced types like Temporal.Instant var hasToStringTag = typeof Symbol === 'function' && Symbol.toStringTag; var type = hasToStringTag && value[Symbol.toStringTag] || value.constructor.name || 'Object'; // $FlowFixMe[incompatible-return] return type; } } // $FlowFixMe[incompatible-return] only called in DEV, so void return is not possible. function willCoercionThrow(value) { { try { testStringCoercion(value); return false; } catch (e) { return true; } } } function testStringCoercion(value) { // If you ended up here by following an exception call stack, here's what's // happened: you supplied an object or symbol value to React (as a prop, key, // DOM attribute, CSS property, string ref, etc.) and when React tried to // coerce it to a string using `'' + value`, an exception was thrown. // // The most common types that will cause this exception are `Symbol` instances // and Temporal objects like `Temporal.Instant`. But any object that has a // `valueOf` or `[Symbol.toPrimitive]` method that throws will also cause this // exception. (Library authors do this to prevent users from using built-in // numeric operators like `+` or comparison operators like `>=` because custom // methods are needed to perform accurate arithmetic or comparison.) // // To fix the problem, coerce this object or symbol value to a string before // passing it to React. The most reliable way is usually `String(value)`. // // To find which value is throwing, check the browser or debugger console. // Before this exception was thrown, there should be `console.error` output // that shows the type (Symbol, Temporal.PlainDate, etc.) that caused the // problem and how that type was used: key, atrribute, input value prop, etc. // In most cases, this console output also shows the component and its // ancestor components where the exception happened. // // eslint-disable-next-line react-internal/safe-string-coercion return '' + value; } function checkAttributeStringCoercion(value, attributeName) { { if (willCoercionThrow(value)) { error('The provided `%s` attribute is an unsupported type %s.' + ' This value must be coerced to a string before before using it here.', attributeName, typeName(value)); return testStringCoercion(value); // throw (to help callers find troubleshooting comments) } } } function checkKeyStringCoercion(value) { { if (willCoercionThrow(value)) { error('The provided key is an unsupported type %s.' + ' This value must be coerced to a string before before using it here.', typeName(value)); return testStringCoercion(value); // throw (to help callers find troubleshooting comments) } } } function checkPropStringCoercion(value, propName) { { if (willCoercionThrow(value)) { error('The provided `%s` prop is an unsupported type %s.' + ' This value must be coerced to a string before before using it here.', propName, typeName(value)); return testStringCoercion(value); // throw (to help callers find troubleshooting comments) } } } function checkCSSPropertyStringCoercion(value, propName) { { if (willCoercionThrow(value)) { error('The provided `%s` CSS property is an unsupported type %s.' + ' This value must be coerced to a string before before using it here.', propName, typeName(value)); return testStringCoercion(value); // throw (to help callers find troubleshooting comments) } } } function checkHtmlStringCoercion(value) { { if (willCoercionThrow(value)) { error('The provided HTML markup uses a value of unsupported type %s.' + ' This value must be coerced to a string before before using it here.', typeName(value)); return testStringCoercion(value); // throw (to help callers find troubleshooting comments) } } } function checkFormFieldValueStringCoercion(value) { { if (willCoercionThrow(value)) { error('Form field values (value, checked, defaultValue, or defaultChecked props)' + ' must be strings, not %s.' + ' This value must be coerced to a string before before using it here.', typeName(value)); return testStringCoercion(value); // throw (to help callers find troubleshooting comments) } } } var FunctionComponent = 0; var ClassComponent = 1; var IndeterminateComponent = 2; // Before we know whether it is function or class var HostRoot = 3; // Root of a host tree. Could be nested inside another node. var HostPortal = 4; // A subtree. Could be an entry point to a different renderer. var HostComponent = 5; var HostText = 6; var Fragment = 7; var Mode = 8; var ContextConsumer = 9; var ContextProvider = 10; var ForwardRef = 11; var Profiler = 12; var SuspenseComponent = 13; var MemoComponent = 14; var SimpleMemoComponent = 15; var LazyComponent = 16; var IncompleteClassComponent = 17; var DehydratedFragment = 18; var SuspenseListComponent = 19; var ScopeComponent = 21; var OffscreenComponent = 22; var LegacyHiddenComponent = 23; var CacheComponent = 24; var TracingMarkerComponent = 25; var HostHoistable = 26; var HostSingleton = 27; var randomKey = Math.random().toString(36).slice(2); var internalInstanceKey = '__reactFiber$' + randomKey; var internalPropsKey = '__reactProps$' + randomKey; var internalContainerInstanceKey = '__reactContainer$' + randomKey; var internalEventHandlersKey = '__reactEvents$' + randomKey; var internalEventHandlerListenersKey = '__reactListeners$' + randomKey; var internalEventHandlesSetKey = '__reactHandles$' + randomKey; var internalRootNodeResourcesKey = '__reactResources$' + randomKey; var internalHoistableMarker = '__reactMarker$' + randomKey; function detachDeletedInstance(node) { // TODO: This function is only called on host components. I don't think all of // these fields are relevant. delete node[internalInstanceKey]; delete node[internalPropsKey]; delete node[internalEventHandlersKey]; delete node[internalEventHandlerListenersKey]; delete node[internalEventHandlesSetKey]; } function precacheFiberNode(hostInst, node) { node[internalInstanceKey] = hostInst; } function markContainerAsRoot(hostRoot, node) { // $FlowFixMe[prop-missing] node[internalContainerInstanceKey] = hostRoot; } function unmarkContainerAsRoot(node) { // $FlowFixMe[prop-missing] node[internalContainerInstanceKey] = null; } function isContainerMarkedAsRoot(node) { // $FlowFixMe[prop-missing] return !!node[internalContainerInstanceKey]; } // Given a DOM node, return the closest HostComponent or HostText fiber ancestor. // If the target node is part of a hydrated or not yet rendered subtree, then // this may also return a SuspenseComponent or HostRoot to indicate that. // Conceptually the HostRoot fiber is a child of the Container node. So if you // pass the Container node as the targetNode, you will not actually get the // HostRoot back. To get to the HostRoot, you need to pass a child of it. // The same thing applies to Suspense boundaries. function getClosestInstanceFromNode(targetNode) { var targetInst = targetNode[internalInstanceKey]; if (targetInst) { // Don't return HostRoot or SuspenseComponent here. return targetInst; } // If the direct event target isn't a React owned DOM node, we need to look // to see if one of its parents is a React owned DOM node. var parentNode = targetNode.parentNode; while (parentNode) { // We'll check if this is a container root that could include // React nodes in the future. We need to check this first because // if we're a child of a dehydrated container, we need to first // find that inner container before moving on to finding the parent // instance. Note that we don't check this field on the targetNode // itself because the fibers are conceptually between the container // node and the first child. It isn't surrounding the container node. // If it's not a container, we check if it's an instance. targetInst = parentNode[internalContainerInstanceKey] || parentNode[internalInstanceKey]; if (targetInst) { // Since this wasn't the direct target of the event, we might have // stepped past dehydrated DOM nodes to get here. However they could // also have been non-React nodes. We need to answer which one. // If we the instance doesn't have any children, then there can't be // a nested suspense boundary within it. So we can use this as a fast // bailout. Most of the time, when people add non-React children to // the tree, it is using a ref to a child-less DOM node. // Normally we'd only need to check one of the fibers because if it // has ever gone from having children to deleting them or vice versa // it would have deleted the dehydrated boundary nested inside already. // However, since the HostRoot starts out with an alternate it might // have one on the alternate so we need to check in case this was a // root. var alternate = targetInst.alternate; if (targetInst.child !== null || alternate !== null && alternate.child !== null) { // Next we need to figure out if the node that skipped past is // nested within a dehydrated boundary and if so, which one. var suspenseInstance = getParentSuspenseInstance(targetNode); while (suspenseInstance !== null) { // We found a suspense instance. That means that we haven't // hydrated it yet. Even though we leave the comments in the // DOM after hydrating, and there are boundaries in the DOM // that could already be hydrated, we wouldn't have found them // through this pass since if the target is hydrated it would // have had an internalInstanceKey on it. // Let's get the fiber associated with the SuspenseComponent // as the deepest instance. // $FlowFixMe[prop-missing] var targetSuspenseInst = suspenseInstance[internalInstanceKey]; if (targetSuspenseInst) { return targetSuspenseInst; } // If we don't find a Fiber on the comment, it might be because // we haven't gotten to hydrate it yet. There might still be a // parent boundary that hasn't above this one so we need to find // the outer most that is known. suspenseInstance = getParentSuspenseInstance(suspenseInstance); // If we don't find one, then that should mean that the parent // host component also hasn't hydrated yet. We can return it // below since it will bail out on the isMounted check later. } } return targetInst; } targetNode = parentNode; parentNode = targetNode.parentNode; } return null; } /** * Given a DOM node, return the ReactDOMComponent or ReactDOMTextComponent * instance, or null if the node was not rendered by this React. */ function getInstanceFromNode(node) { var inst = node[internalInstanceKey] || node[internalContainerInstanceKey]; if (inst) { var tag = inst.tag; if (tag === HostComponent || tag === HostText || tag === SuspenseComponent || (tag === HostHoistable ) || (tag === HostSingleton ) || tag === HostRoot) { return inst; } else { return null; } } return null; } /** * Given a ReactDOMComponent or ReactDOMTextComponent, return the corresponding * DOM node. */ function getNodeFromInstance(inst) { var tag = inst.tag; if (tag === HostComponent || (tag === HostHoistable ) || (tag === HostSingleton ) || tag === HostText) { // In Fiber this, is just the state node right now. We assume it will be // a host component or host text. return inst.stateNode; } // Without this first invariant, passing a non-DOM-component triggers the next // invariant for a missing parent, which is super confusing. throw new Error('getNodeFromInstance: Invalid argument.'); } function getFiberCurrentPropsFromNode(node) { return node[internalPropsKey] || null; } function updateFiberProps(node, props) { node[internalPropsKey] = props; } function getEventListenerSet(node) { var elementListenerSet = node[internalEventHandlersKey]; if (elementListenerSet === undefined) { elementListenerSet = node[internalEventHandlersKey] = new Set(); } return elementListenerSet; } function getResourcesFromRoot(root) { var resources = root[internalRootNodeResourcesKey]; if (!resources) { resources = root[internalRootNodeResourcesKey] = { hoistableStyles: new Map(), hoistableScripts: new Map() }; } return resources; } function isMarkedHoistable(node) { return !!node[internalHoistableMarker]; } function markNodeAsHoistable(node) { node[internalHoistableMarker] = true; } function isOwnedInstance(node) { return !!(node[internalHoistableMarker] || node[internalInstanceKey]); } var allNativeEvents = new Set(); /** * Mapping from registration name to event name */ var registrationNameDependencies = {}; /** * Mapping from lowercase registration names to the properly cased version, * used to warn in the case of missing event handlers. Available * only in __DEV__. * @type {Object} */ var possibleRegistrationNames = {} ; // Trust the developer to only use possibleRegistrationNames in true function registerTwoPhaseEvent(registrationName, dependencies) { registerDirectEvent(registrationName, dependencies); registerDirectEvent(registrationName + 'Capture', dependencies); } function registerDirectEvent(registrationName, dependencies) { { if (registrationNameDependencies[registrationName]) { error('EventRegistry: More than one plugin attempted to publish the same ' + 'registration name, `%s`.', registrationName); } } registrationNameDependencies[registrationName] = dependencies; { var lowerCasedName = registrationName.toLowerCase(); possibleRegistrationNames[lowerCasedName] = registrationName; if (registrationName === 'onDoubleClick') { possibleRegistrationNames.ondblclick = registrationName; } } for (var i = 0; i < dependencies.length; i++) { allNativeEvents.add(dependencies[i]); } } var canUseDOM = !!(typeof window !== 'undefined' && typeof window.document !== 'undefined' && typeof window.document.createElement !== 'undefined'); var hasReadOnlyValue = { button: true, checkbox: true, image: true, hidden: true, radio: true, reset: true, submit: true }; function checkControlledValueProps(tagName, props) { { if (!(hasReadOnlyValue[props.type] || props.onChange || props.onInput || props.readOnly || props.disabled || props.value == null)) { 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`.'); } if (!(props.onChange || props.readOnly || props.disabled || props.checked == null)) { 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`.'); } } } /* eslint-disable max-len */ var ATTRIBUTE_NAME_START_CHAR = ":A-Z_a-z\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02FF\\u0370-\\u037D\\u037F-\\u1FFF\\u200C-\\u200D\\u2070-\\u218F\\u2C00-\\u2FEF\\u3001-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFFD"; /* eslint-enable max-len */ var ATTRIBUTE_NAME_CHAR = ATTRIBUTE_NAME_START_CHAR + "\\-.0-9\\u00B7\\u0300-\\u036F\\u203F-\\u2040"; var VALID_ATTRIBUTE_NAME_REGEX = new RegExp('^[' + ATTRIBUTE_NAME_START_CHAR + '][' + ATTRIBUTE_NAME_CHAR + ']*$'); var illegalAttributeNameCache = {}; var validatedAttributeNameCache = {}; function isAttributeNameSafe(attributeName) { if (hasOwnProperty.call(validatedAttributeNameCache, attributeName)) { return true; } if (hasOwnProperty.call(illegalAttributeNameCache, attributeName)) { return false; } if (VALID_ATTRIBUTE_NAME_REGEX.test(attributeName)) { validatedAttributeNameCache[attributeName] = true; return true; } illegalAttributeNameCache[attributeName] = true; { error('Invalid attribute name: `%s`', attributeName); } return false; } /** * Get the value for a attribute on a node. Only used in DEV for SSR validation. * The third argument is used as a hint of what the expected value is. Some * attributes have multiple equivalent values. */ function getValueForAttribute(node, name, expected) { { if (!isAttributeNameSafe(name)) { return; } if (!node.hasAttribute(name)) { // shouldRemoveAttribute switch (typeof expected) { case 'function': case 'symbol': // eslint-disable-line return expected; case 'boolean': { var prefix = name.toLowerCase().slice(0, 5); if (prefix !== 'data-' && prefix !== 'aria-') { return expected; } } } return expected === undefined ? undefined : null; } var value = node.getAttribute(name); { checkAttributeStringCoercion(expected, name); } if (value === '' + expected) { return expected; } return value; } } function getValueForAttributeOnCustomComponent(node, name, expected) { { if (!isAttributeNameSafe(name)) { return; } if (!node.hasAttribute(name)) { // shouldRemoveAttribute switch (typeof expected) { case 'symbol': case 'object': // Symbols and objects are ignored when they're emitted so // it would be expected that they end up not having an attribute. return expected; case 'function': { return expected; } case 'boolean': { if (expected === false) { return expected; } } } return expected === undefined ? undefined : null; } var value = node.getAttribute(name); { if (value === '' && expected === true) { return true; } } { checkAttributeStringCoercion(expected, name); } if (value === '' + expected) { return expected; } return value; } } function setValueForAttribute(node, name, value) { if (isAttributeNameSafe(name)) { // If the prop isn't in the special list, treat it as a simple attribute. // shouldRemoveAttribute if (value === null) { node.removeAttribute(name); return; } switch (typeof value) { case 'undefined': case 'function': case 'symbol': // eslint-disable-line node.removeAttribute(name); return; case 'boolean': { var prefix = name.toLowerCase().slice(0, 5); if (prefix !== 'data-' && prefix !== 'aria-') { node.removeAttribute(name); return; } } } { checkAttributeStringCoercion(value, name); } node.setAttribute(name, '' + value); } } function setValueForKnownAttribute(node, name, value) { if (value === null) { node.removeAttribute(name); return; } switch (typeof value) { case 'undefined': case 'function': case 'symbol': case 'boolean': { node.removeAttribute(name); return; } } { checkAttributeStringCoercion(value, name); } node.setAttribute(name, '' + value); } function setValueForNamespacedAttribute(node, namespace, name, value) { if (value === null) { node.removeAttribute(name); return; } switch (typeof value) { case 'undefined': case 'function': case 'symbol': case 'boolean': { node.removeAttribute(name); return; } } { checkAttributeStringCoercion(value, name); } node.setAttributeNS(namespace, name, '' + value); } function setValueForPropertyOnCustomComponent(node, name, value) { if (name[0] === 'o' && name[1] === 'n') { var useCapture = name.endsWith('Capture'); var eventName = name.slice(2, useCapture ? name.length - 7 : undefined); var prevProps = getFiberCurrentPropsFromNode(node); var prevValue = prevProps != null ? prevProps[name] : null; if (typeof prevValue === 'function') { node.removeEventListener(eventName, prevValue, useCapture); } if (typeof value === 'function') { if (typeof prevValue !== 'function' && prevValue !== null) { // If we previously assigned a non-function type into this node, then // remove it when switching to event listener mode. if (name in node) { node[name] = null; } else if (node.hasAttribute(name)) { node.removeAttribute(name); } } // $FlowFixMe[incompatible-cast] value can't be casted to EventListener. node.addEventListener(eventName, value, useCapture); return; } } if (name in node) { node[name] = value; return; } if (value === true) { node.setAttribute(name, ''); return; } // From here, it's the same as any attribute setValueForAttribute(node, name, value); } var ReactCurrentDispatcher$2 = ReactSharedInternals.ReactCurrentDispatcher; var prefix; function describeBuiltInComponentFrame(name, source, ownerFn) { { if (prefix === undefined) { // Extract the VM specific prefix used by each line. try { throw Error(); } catch (x) { var match = x.stack.trim().match(/\n( *(at )?)/); prefix = match && match[1] || ''; } } // We use the prefix to ensure our stacks line up with native stack frames. return '\n' + prefix + name; } } var reentry = false; var componentFrameCache; { var PossiblyWeakMap$1 = typeof WeakMap === 'function' ? WeakMap : Map; componentFrameCache = new PossiblyWeakMap$1(); } function describeNativeComponentFrame(fn, construct) { // If something asked for a stack inside a fake render, it should get ignored. if (!fn || reentry) { return ''; } { var frame = componentFrameCache.get(fn); if (frame !== undefined) { return frame; } } var control; reentry = true; var previousPrepareStackTrace = Error.prepareStackTrace; // $FlowFixMe[incompatible-type] It does accept undefined. Error.prepareStackTrace = undefined; var previousDispatcher; { previousDispatcher = ReactCurrentDispatcher$2.current; // Set the dispatcher in DEV because this might be call in the render function // for warnings. ReactCurrentDispatcher$2.current = null; disableLogs(); } try { // This should throw. if (construct) { // Something should be setting the props in the constructor. var Fake = function () { throw Error(); }; // $FlowFixMe[prop-missing] Object.defineProperty(Fake.prototype, 'props', { set: function () { // We use a throwing setter instead of frozen or non-writable props // because that won't throw in a non-strict mode function. throw Error(); } }); if (typeof Reflect === 'object' && Reflect.construct) { // We construct a different control for this case to include any extra // frames added by the construct call. try { Reflect.construct(Fake, []); } catch (x) { control = x; } Reflect.construct(fn, [], Fake); } else { try { Fake.call(); } catch (x) { control = x; } // $FlowFixMe[prop-missing] found when upgrading Flow fn.call(Fake.prototype); } } else { try { throw Error(); } catch (x) { control = x; } // TODO(luna): This will currently only throw if the function component // tries to access React/ReactDOM/props. We should probably make this throw // in simple components too var maybePromise = fn(); // If the function component returns a promise, it's likely an async // component, which we don't yet support. Attach a noop catch handler to // silence the error. // TODO: Implement component stacks for async client components? if (maybePromise && typeof maybePromise.catch === 'function') { maybePromise.catch(function () {}); } } } catch (sample) { // This is inlined manually because closure doesn't do it for us. if (sample && control && typeof sample.stack === 'string') { // This extracts the first frame from the sample that isn't also in the control. // Skipping one frame that we assume is the frame that calls the two. var sampleLines = sample.stack.split('\n'); var controlLines = control.stack.split('\n'); var s = sampleLines.length - 1; var c = controlLines.length - 1; while (s >= 1 && c >= 0 && sampleLines[s] !== controlLines[c]) { // We expect at least one stack frame to be shared. // Typically this will be the root most one. However, stack frames may be // cut off due to maximum stack limits. In this case, one maybe cut off // earlier than the other. We assume that the sample is longer or the same // and there for cut off earlier. So we should find the root most frame in // the sample somewhere in the control. c--; } for (; s >= 1 && c >= 0; s--, c--) { // Next we find the first one that isn't the same which should be the // frame that called our sample function and the control. if (sampleLines[s] !== controlLines[c]) { // In V8, the first line is describing the message but other VMs don't. // If we're about to return the first line, and the control is also on the same // line, that's a pretty good indicator that our sample threw at same line as // the control. I.e. before we entered the sample frame. So we ignore this result. // This can happen if you passed a class to function component, or non-function. if (s !== 1 || c !== 1) { do { s--; c--; // We may still have similar intermediate frames from the construct call. // The next one that isn't the same should be our match though. if (c < 0 || sampleLines[s] !== controlLines[c]) { // V8 adds a "new" prefix for native classes. Let's remove it to make it prettier. var _frame = '\n' + sampleLines[s].replace(' at new ', ' at '); // If our component frame is labeled "" // but we have a user-provided "displayName" // splice it in to make the stack more readable. if (fn.displayName && _frame.includes('')) { _frame = _frame.replace('', fn.displayName); } { if (typeof fn === 'function') { componentFrameCache.set(fn, _frame); } } // Return the line we found. return _frame; } } while (s >= 1 && c >= 0); } break; } } } } finally { reentry = false; { ReactCurrentDispatcher$2.current = previousDispatcher; reenableLogs(); } Error.prepareStackTrace = previousPrepareStackTrace; } // Fallback to just using the name if we couldn't make it throw. var name = fn ? fn.displayName || fn.name : ''; var syntheticFrame = name ? describeBuiltInComponentFrame(name) : ''; { if (typeof fn === 'function') { componentFrameCache.set(fn, syntheticFrame); } } return syntheticFrame; } function describeClassComponentFrame(ctor, source, ownerFn) { { return describeNativeComponentFrame(ctor, true); } } function describeFunctionComponentFrame(fn, source, ownerFn) { { return describeNativeComponentFrame(fn, false); } } function shouldConstruct$1(Component) { var prototype = Component.prototype; return !!(prototype && prototype.isReactComponent); } function describeUnknownElementTypeFrameInDEV(type, source, ownerFn) { if (type == null) { return ''; } if (typeof type === 'function') { { return describeNativeComponentFrame(type, shouldConstruct$1(type)); } } if (typeof type === 'string') { return describeBuiltInComponentFrame(type); } switch (type) { case REACT_SUSPENSE_TYPE: return describeBuiltInComponentFrame('Suspense'); case REACT_SUSPENSE_LIST_TYPE: return describeBuiltInComponentFrame('SuspenseList'); } if (typeof type === 'object') { switch (type.$$typeof) { case REACT_FORWARD_REF_TYPE: return describeFunctionComponentFrame(type.render); case REACT_MEMO_TYPE: // Memo may contain any component type so we recursively resolve it. return describeUnknownElementTypeFrameInDEV(type.type, source, ownerFn); case REACT_LAZY_TYPE: { var lazyComponent = type; var payload = lazyComponent._payload; var init = lazyComponent._init; try { // Lazy may contain any component type so we recursively resolve it. return describeUnknownElementTypeFrameInDEV(init(payload), source, ownerFn); } catch (x) {} } } } return ''; } function describeFiber(fiber) { switch (fiber.tag) { case HostHoistable: case HostSingleton: case HostComponent: return describeBuiltInComponentFrame(fiber.type); case LazyComponent: return describeBuiltInComponentFrame('Lazy'); case SuspenseComponent: return describeBuiltInComponentFrame('Suspense'); case SuspenseListComponent: return describeBuiltInComponentFrame('SuspenseList'); case FunctionComponent: case IndeterminateComponent: case SimpleMemoComponent: return describeFunctionComponentFrame(fiber.type); case ForwardRef: return describeFunctionComponentFrame(fiber.type.render); case ClassComponent: return describeClassComponentFrame(fiber.type); default: return ''; } } function getStackByFiberInDevAndProd(workInProgress) { try { var info = ''; var node = workInProgress; do { info += describeFiber(node); // $FlowFixMe[incompatible-type] we bail out when we get a null node = node.return; } while (node); return info; } catch (x) { return '\nError generating stack: ' + x.message + '\n' + x.stack; } } function getWrappedName$1(outerType, innerType, wrapperName) { var displayName = outerType.displayName; if (displayName) { return displayName; } var functionName = innerType.displayName || innerType.name || ''; return functionName !== '' ? wrapperName + "(" + functionName + ")" : wrapperName; } // Keep in sync with react-reconciler/getComponentNameFromFiber function getContextName$1(type) { return type.displayName || 'Context'; } // Note that the reconciler package should generally prefer to use getComponentNameFromFiber() instead. function getComponentNameFromType(type) { if (type == null) { // Host root, text node or just invalid type. return null; } { if (typeof type.tag === 'number') { error('Received an unexpected object in getComponentNameFromType(). ' + 'This is likely a bug in React. Please file an issue.'); } } if (typeof type === 'function') { return type.displayName || type.name || null; } if (typeof type === 'string') { return type; } switch (type) { case REACT_FRAGMENT_TYPE: return 'Fragment'; case REACT_PORTAL_TYPE: return 'Portal'; case REACT_PROFILER_TYPE: return 'Profiler'; case REACT_STRICT_MODE_TYPE: return 'StrictMode'; case REACT_SUSPENSE_TYPE: return 'Suspense'; case REACT_SUSPENSE_LIST_TYPE: return 'SuspenseList'; case REACT_CACHE_TYPE: { return 'Cache'; } } if (typeof type === 'object') { switch (type.$$typeof) { case REACT_CONTEXT_TYPE: var context = type; return getContextName$1(context) + '.Consumer'; case REACT_PROVIDER_TYPE: var provider = type; return getContextName$1(provider._context) + '.Provider'; case REACT_FORWARD_REF_TYPE: return getWrappedName$1(type, type.render, 'ForwardRef'); case REACT_MEMO_TYPE: var outerName = type.displayName || null; if (outerName !== null) { return outerName; } return getComponentNameFromType(type.type) || 'Memo'; case REACT_LAZY_TYPE: { var lazyComponent = type; var payload = lazyComponent._payload; var init = lazyComponent._init; try { return getComponentNameFromType(init(payload)); } catch (x) { return null; } } case REACT_SERVER_CONTEXT_TYPE: { var context2 = type; return (context2.displayName || context2._globalName) + '.Provider'; } } } return null; } function getWrappedName(outerType, innerType, wrapperName) { var functionName = innerType.displayName || innerType.name || ''; return outerType.displayName || (functionName !== '' ? wrapperName + "(" + functionName + ")" : wrapperName); } // Keep in sync with shared/getComponentNameFromType function getContextName(type) { return type.displayName || 'Context'; } function getComponentNameFromFiber(fiber) { var tag = fiber.tag, type = fiber.type; switch (tag) { case CacheComponent: return 'Cache'; case ContextConsumer: var context = type; return getContextName(context) + '.Consumer'; case ContextProvider: var provider = type; return getContextName(provider._context) + '.Provider'; case DehydratedFragment: return 'DehydratedFragment'; case ForwardRef: return getWrappedName(type, type.render, 'ForwardRef'); case Fragment: return 'Fragment'; case HostHoistable: case HostSingleton: case HostComponent: // Host component type is the display name (e.g. "div", "View") return type; case HostPortal: return 'Portal'; case HostRoot: return 'Root'; case HostText: return 'Text'; case LazyComponent: // Name comes from the type in this case; we don't have a tag. return getComponentNameFromType(type); case Mode: if (type === REACT_STRICT_MODE_TYPE) { // Don't be less specific than shared/getComponentNameFromType return 'StrictMode'; } return 'Mode'; case OffscreenComponent: return 'Offscreen'; case Profiler: return 'Profiler'; case ScopeComponent: return 'Scope'; case SuspenseComponent: return 'Suspense'; case SuspenseListComponent: return 'SuspenseList'; case TracingMarkerComponent: return 'TracingMarker'; // The display name for this tags come from the user-provided type: case ClassComponent: case FunctionComponent: case IncompleteClassComponent: case IndeterminateComponent: case MemoComponent: case SimpleMemoComponent: if (typeof type === 'function') { return type.displayName || type.name || null; } if (typeof type === 'string') { return type; } break; } return null; } var ReactDebugCurrentFrame$1 = ReactSharedInternals.ReactDebugCurrentFrame; var current = null; var isRendering = false; function getCurrentFiberOwnerNameInDevOrNull() { { if (current === null) { return null; } var owner = current._debugOwner; if (owner !== null && typeof owner !== 'undefined') { return getComponentNameFromFiber(owner); } } return null; } function getCurrentFiberStackInDev() { { if (current === null) { return ''; } // Safe because if current fiber exists, we are reconciling, // and it is guaranteed to be the work-in-progress version. return getStackByFiberInDevAndProd(current); } } function resetCurrentFiber() { { ReactDebugCurrentFrame$1.getCurrentStack = null; current = null; isRendering = false; } } function setCurrentFiber(fiber) { { ReactDebugCurrentFrame$1.getCurrentStack = fiber === null ? null : getCurrentFiberStackInDev; current = fiber; isRendering = false; } } function getCurrentFiber() { { return current; } } function setIsRendering(rendering) { { isRendering = rendering; } } // around this limitation, we use an opaque type that can only be obtained by // passing the value through getToStringValue first. function toString(value) { // The coercion safety check is performed in getToStringValue(). // eslint-disable-next-line react-internal/safe-string-coercion return '' + value; } function getToStringValue(value) { switch (typeof value) { case 'boolean': case 'number': case 'string': case 'undefined': return value; case 'object': { checkFormFieldValueStringCoercion(value); } return value; default: // function, symbol are assigned as empty strings return ''; } } function isCheckable(elem) { var type = elem.type; var nodeName = elem.nodeName; return nodeName && nodeName.toLowerCase() === 'input' && (type === 'checkbox' || type === 'radio'); } function getTracker(node) { return node._valueTracker; } function detachTracker(node) { node._valueTracker = null; } function getValueFromNode(node) { var value = ''; if (!node) { return value; } if (isCheckable(node)) { value = node.checked ? 'true' : 'false'; } else { value = node.value; } return value; } function trackValueOnNode(node) { var valueField = isCheckable(node) ? 'checked' : 'value'; var descriptor = Object.getOwnPropertyDescriptor(node.constructor.prototype, valueField); { checkFormFieldValueStringCoercion(node[valueField]); } var currentValue = '' + node[valueField]; // if someone has already defined a value or Safari, then bail // and don't track value will cause over reporting of changes, // but it's better then a hard failure // (needed for certain tests that spyOn input values and Safari) if (node.hasOwnProperty(valueField) || typeof descriptor === 'undefined' || typeof descriptor.get !== 'function' || typeof descriptor.set !== 'function') { return; } var get = descriptor.get, set = descriptor.set; Object.defineProperty(node, valueField, { configurable: true, // $FlowFixMe[missing-this-annot] get: function () { return get.call(this); }, // $FlowFixMe[missing-local-annot] // $FlowFixMe[missing-this-annot] set: function (value) { { checkFormFieldValueStringCoercion(value); } currentValue = '' + value; set.call(this, value); } }); // We could've passed this the first time // but it triggers a bug in IE11 and Edge 14/15. // Calling defineProperty() again should be equivalent. // https://github.com/facebook/react/issues/11768 Object.defineProperty(node, valueField, { enumerable: descriptor.enumerable }); var tracker = { getValue: function () { return currentValue; }, setValue: function (value) { { checkFormFieldValueStringCoercion(value); } currentValue = '' + value; }, stopTracking: function () { detachTracker(node); delete node[valueField]; } }; return tracker; } function track(node) { if (getTracker(node)) { return; } node._valueTracker = trackValueOnNode(node); } function updateValueIfChanged(node) { if (!node) { return false; } var tracker = getTracker(node); // if there is no tracker at this point it's unlikely // that trying again will succeed if (!tracker) { return true; } var lastValue = tracker.getValue(); var nextValue = getValueFromNode(node); if (nextValue !== lastValue) { tracker.setValue(nextValue); return true; } return false; } function getActiveElement(doc) { doc = doc || (typeof document !== 'undefined' ? document : undefined); if (typeof doc === 'undefined') { return null; } try { return doc.activeElement || doc.body; } catch (e) { return doc.body; } } // When passing user input into querySelector(All) the embedded string must not alter // the semantics of the query. This escape function is safe to use when we know the // provided value is going to be wrapped in double quotes as part of an attribute selector // Do not use it anywhere else // we escape double quotes and backslashes var escapeSelectorAttributeValueInsideDoubleQuotesRegex = /[\n\"\\]/g; function escapeSelectorAttributeValueInsideDoubleQuotes(value) { return value.replace(escapeSelectorAttributeValueInsideDoubleQuotesRegex, function (ch) { return '\\' + ch.charCodeAt(0).toString(16) + ' '; }); } var didWarnValueDefaultValue$1 = false; var didWarnCheckedDefaultChecked = false; /** * Implements an host component that allows setting these optional * props: `checked`, `value`, `defaultChecked`, and `defaultValue`. * * If `checked` or `value` are not supplied (or null/undefined), user actions * that affect the checked state or value will trigger updates to the element. * * If they are supplied (and not null/undefined), the rendered element will not * trigger updates to the element. Instead, the props must change in order for * the rendered element to be updated. * * The rendered element will be initialized as unchecked (or `defaultChecked`) * with an empty value (or `defaultValue`). * * See http://www.w3.org/TR/2012/WD-html5-20121025/the-input-element.html */ function validateInputProps(element, props) { { // Normally we check for undefined and null the same, but explicitly specifying both // properties, at all is probably worth warning for. We could move this either direction // and just make it ok to pass null or just check hasOwnProperty. if (props.checked !== undefined && props.defaultChecked !== undefined && !didWarnCheckedDefaultChecked) { 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://reactjs.org/link/controlled-components', getCurrentFiberOwnerNameInDevOrNull() || 'A component', props.type); didWarnCheckedDefaultChecked = true; } if (props.value !== undefined && props.defaultValue !== undefined && !didWarnValueDefaultValue$1) { 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://reactjs.org/link/controlled-components', getCurrentFiberOwnerNameInDevOrNull() || 'A component', props.type); didWarnValueDefaultValue$1 = true; } } } function updateInput(element, value, defaultValue, lastDefaultValue, checked, defaultChecked, type, name) { var node = element; // Temporarily disconnect the input from any radio buttons. // Changing the type or name as the same time as changing the checked value // needs to be atomically applied. We can only ensure that by disconnecting // the name while do the mutations and then reapply the name after that's done. node.name = ''; if (type != null && typeof type !== 'function' && typeof type !== 'symbol' && typeof type !== 'boolean') { { checkAttributeStringCoercion(type, 'type'); } node.type = type; } else { node.removeAttribute('type'); } if (value != null) { if (type === 'number') { if ( // $FlowFixMe[incompatible-type] value === 0 && node.value === '' || // We explicitly want to coerce to number here if possible. // eslint-disable-next-line node.value != value) { node.value = toString(getToStringValue(value)); } } else if (node.value !== toString(getToStringValue(value))) { node.value = toString(getToStringValue(value)); } } else if (type === 'submit' || type === 'reset') { // Submit/reset inputs need the attribute removed completely to avoid // blank-text buttons. node.removeAttribute('value'); } { // When syncing the value attribute, the value comes from a cascade of // properties: // 1. The value React property // 2. The defaultValue React property // 3. Otherwise there should be no change if (value != null) { setDefaultValue(node, type, getToStringValue(value)); } else if (defaultValue != null) { setDefaultValue(node, type, getToStringValue(defaultValue)); } else if (lastDefaultValue != null) { node.removeAttribute('value'); } } { // When syncing the checked attribute, it only changes when it needs // to be removed, such as transitioning from a checkbox into a text input if (checked == null && defaultChecked != null) { node.defaultChecked = !!defaultChecked; } } if (checked != null && node.checked !== !!checked) { node.checked = checked; } if (name != null && typeof name !== 'function' && typeof name !== 'symbol' && typeof name !== 'boolean') { { checkAttributeStringCoercion(name, 'name'); } node.name = toString(getToStringValue(name)); } else { node.removeAttribute('name'); } } function initInput(element, value, defaultValue, checked, defaultChecked, type, name, isHydrating) { var node = element; if (type != null && typeof type !== 'function' && typeof type !== 'symbol' && typeof type !== 'boolean') { { checkAttributeStringCoercion(type, 'type'); } node.type = type; } if (value != null || defaultValue != null) { var isButton = type === 'submit' || type === 'reset'; // Avoid setting value attribute on submit/reset inputs as it overrides the // default value provided by the browser. See: #12872 if (isButton && (value === undefined || value === null)) { return; } var defaultValueStr = defaultValue != null ? toString(getToStringValue(defaultValue)) : ''; var initialValue = value != null ? toString(getToStringValue(value)) : defaultValueStr; // Do not assign value if it is already set. This prevents user text input // from being lost during SSR hydration. if (!isHydrating) { { // When syncing the value attribute, the value property should use // the wrapperState._initialValue property. This uses: // // 1. The value React property when present // 2. The defaultValue React property when present // 3. An empty string if (initialValue !== node.value) { node.value = initialValue; } } } { // Otherwise, the value attribute is synchronized to the property, // so we assign defaultValue to the same thing as the value property // assignment step above. node.defaultValue = initialValue; } } // Normally, we'd just do `node.checked = node.checked` upon initial mount, less this bug // this is needed to work around a chrome bug where setting defaultChecked // will sometimes influence the value of checked (even after detachment). // Reference: https://bugs.chromium.org/p/chromium/issues/detail?id=608416 // We need to temporarily unset name to avoid disrupting radio button groups. var checkedOrDefault = checked != null ? checked : defaultChecked; // TODO: This 'function' or 'symbol' check isn't replicated in other places // so this semantic is inconsistent. var initialChecked = typeof checkedOrDefault !== 'function' && typeof checkedOrDefault !== 'symbol' && !!checkedOrDefault; // The checked property never gets assigned. It must be manually set. // We don't want to do this when hydrating so that existing user input isn't // modified // TODO: I'm pretty sure this is a bug because initialValueTracking won't be // correct for the hydration case then. if (!isHydrating) { node.checked = !!initialChecked; } { // When syncing the checked attribute, both the checked property and // attribute are assigned at the same time using defaultChecked. This uses: // // 1. The checked React property when present // 2. The defaultChecked React property when present // 3. Otherwise, false node.defaultChecked = !node.defaultChecked; node.defaultChecked = !!initialChecked; } // Name needs to be set at the end so that it applies atomically to connected radio buttons. if (name != null && typeof name !== 'function' && typeof name !== 'symbol' && typeof name !== 'boolean') { { checkAttributeStringCoercion(name, 'name'); } node.name = name; } } function restoreControlledInputState(element, props) { var rootNode = element; updateInput(rootNode, props.value, props.defaultValue, props.defaultValue, props.checked, props.defaultChecked, props.type, props.name); var name = props.name; if (props.type === 'radio' && name != null) { var queryRoot = rootNode; while (queryRoot.parentNode) { queryRoot = queryRoot.parentNode; } // If `rootNode.form` was non-null, then we could try `form.elements`, // but that sometimes behaves strangely in IE8. We could also try using // `form.getElementsByName`, but that will only return direct children // and won't include inputs that use the HTML5 `form=` attribute. Since // the input might not even be in a form. It might not even be in the // document. Let's just use the local `querySelectorAll` to ensure we don't // miss anything. { checkAttributeStringCoercion(name, 'name'); } var group = queryRoot.querySelectorAll('input[name="' + escapeSelectorAttributeValueInsideDoubleQuotes('' + name) + '"][type="radio"]'); for (var i = 0; i < group.length; i++) { var otherNode = group[i]; if (otherNode === rootNode || otherNode.form !== rootNode.form) { continue; } // This will throw if radio buttons rendered by different copies of React // and the same name are rendered into the same form (same as #1939). // That's probably okay; we don't support it just as we don't support // mixing React radio buttons with non-React ones. var otherProps = getFiberCurrentPropsFromNode(otherNode); if (!otherProps) { throw new Error('ReactDOMInput: Mixing React and non-React radio inputs with the ' + 'same `name` is not supported.'); } // If this is a controlled radio button group, forcing the input that // was previously checked to update will cause it to be come re-checked // as appropriate. updateInput(otherNode, otherProps.value, otherProps.defaultValue, otherProps.defaultValue, otherProps.checked, otherProps.defaultChecked, otherProps.type, otherProps.name); } // If any updateInput() call set .checked to true, an input in this group // (often, `rootNode` itself) may have become unchecked for (var _i = 0; _i < group.length; _i++) { var _otherNode = group[_i]; if (_otherNode.form !== rootNode.form) { continue; } updateValueIfChanged(_otherNode); } } } // In Chrome, assigning defaultValue to certain input types triggers input validation. // For number inputs, the display value loses trailing decimal points. For email inputs, // Chrome raises "The specified value is not a valid email address". // // Here we check to see if the defaultValue has actually changed, avoiding these problems // when the user is inputting text // // https://github.com/facebook/react/issues/7253 function setDefaultValue(node, type, value) { if ( // Focused number inputs synchronize on blur. See ChangeEventPlugin.js type !== 'number' || getActiveElement(node.ownerDocument) !== node) { if (node.defaultValue !== toString(value)) { node.defaultValue = toString(value); } } } var didWarnSelectedSetOnOption = false; var didWarnInvalidChild = false; var didWarnInvalidInnerHTML = false; /** * Implements an