diff --git a/compiled/facebook-www/REVISION b/compiled/facebook-www/REVISION index b206f33164190..7529a54237085 100644 --- a/compiled/facebook-www/REVISION +++ b/compiled/facebook-www/REVISION @@ -1 +1 @@ -b039be627dd7403d7d2f63a48c8d263d955ce456 +cb151849e13f46ec64570519cb93d5939fb60cab diff --git a/compiled/facebook-www/ReactDOM-dev.classic.js b/compiled/facebook-www/ReactDOM-dev.classic.js index 1bb4580fbd714..b334b9fdac6c2 100644 --- a/compiled/facebook-www/ReactDOM-dev.classic.js +++ b/compiled/facebook-www/ReactDOM-dev.classic.js @@ -30838,7 +30838,7 @@ identifierPrefix, onUncaughtError, onCaughtError, onRecoverableError, transition return root; } -var ReactVersion = '19.0.0-www-classic-6d6c2bc1'; +var ReactVersion = '19.0.0-www-classic-fa4f664d'; function createPortal$1(children, containerInfo, // TODO: figure out the API for cross-renderer implementation. implementation) { @@ -40910,201 +40910,6 @@ function getEventPriority(domEventName) { } } -function ReactDOMRoot(internalRoot) { - this._internalRoot = internalRoot; -} // $FlowFixMe[prop-missing] found when upgrading Flow - - -ReactDOMHydrationRoot.prototype.render = ReactDOMRoot.prototype.render = // $FlowFixMe[missing-this-annot] -function (children) { - var root = this._internalRoot; - - if (root === null) { - throw new Error('Cannot update an unmounted root.'); - } - - { - if (typeof arguments[1] === 'function') { - error('does not support the second callback argument. ' + 'To execute a side effect after rendering, declare it in a component body with useEffect().'); - } else if (isValidContainer(arguments[1])) { - error('You passed a container to the second argument of root.render(...). ' + "You don't need to pass it again since you already passed it to create the root."); - } else if (typeof arguments[1] !== 'undefined') { - error('You passed a second argument to root.render(...) but it only accepts ' + 'one argument.'); - } - } - - updateContainer(children, root, null, null); -}; // $FlowFixMe[prop-missing] found when upgrading Flow - - -ReactDOMHydrationRoot.prototype.unmount = ReactDOMRoot.prototype.unmount = // $FlowFixMe[missing-this-annot] -function () { - { - if (typeof arguments[0] === 'function') { - error('does not support a callback argument. ' + 'To execute a side effect after rendering, declare it in a component body with useEffect().'); - } - } - - var root = this._internalRoot; - - if (root !== null) { - this._internalRoot = null; - var container = root.containerInfo; - - { - if (isAlreadyRendering()) { - error('Attempted to synchronously unmount a root while React was already ' + 'rendering. React cannot finish unmounting the root until the ' + 'current render has completed, which may lead to a race condition.'); - } - } - - updateContainerSync(null, root, null, null); - flushSyncWork(); - unmarkContainerAsRoot(container); - } -}; - -function createRoot$1(container, options) { - if (!isValidContainer(container)) { - throw new Error('Target container is not a DOM element.'); - } - - warnIfReactDOMContainerInDEV(container); - var isStrictMode = false; - var concurrentUpdatesByDefaultOverride = false; - var identifierPrefix = ''; - var onUncaughtError = defaultOnUncaughtError; - var onCaughtError = defaultOnCaughtError; - var onRecoverableError = defaultOnRecoverableError; - var transitionCallbacks = null; - - if (options !== null && options !== undefined) { - { - if (options.hydrate) { - warn('hydrate through createRoot is deprecated. Use ReactDOMClient.hydrateRoot(container, ) instead.'); - } else { - if (typeof options === 'object' && options !== null && options.$$typeof === REACT_ELEMENT_TYPE) { - error('You passed a JSX element to createRoot. You probably meant to ' + 'call root.render instead. ' + 'Example usage:\n\n' + ' let root = createRoot(domContainer);\n' + ' root.render();'); - } - } - } - - if (options.unstable_strictMode === true) { - isStrictMode = true; - } - - if (options.unstable_concurrentUpdatesByDefault === true) { - concurrentUpdatesByDefaultOverride = true; - } - - if (options.identifierPrefix !== undefined) { - identifierPrefix = options.identifierPrefix; - } - - if (options.onUncaughtError !== undefined) { - onUncaughtError = options.onUncaughtError; - } - - if (options.onCaughtError !== undefined) { - onCaughtError = options.onCaughtError; - } - - if (options.onRecoverableError !== undefined) { - onRecoverableError = options.onRecoverableError; - } - - if (options.unstable_transitionCallbacks !== undefined) { - transitionCallbacks = options.unstable_transitionCallbacks; - } - } - - var root = createContainer(container, ConcurrentRoot, null, isStrictMode, concurrentUpdatesByDefaultOverride, identifierPrefix, onUncaughtError, onCaughtError, onRecoverableError, transitionCallbacks); - markContainerAsRoot(root.current, container); - var rootContainerElement = container.nodeType === COMMENT_NODE ? container.parentNode : container; - listenToAllSupportedEvents(rootContainerElement); // $FlowFixMe[invalid-constructor] Flow no longer supports calling new on functions - - return new ReactDOMRoot(root); -} // $FlowFixMe[missing-this-annot] - -function ReactDOMHydrationRoot(internalRoot) { - this._internalRoot = internalRoot; -} - -function scheduleHydration(target) { - if (target) { - queueExplicitHydrationTarget(target); - } -} // $FlowFixMe[prop-missing] found when upgrading Flow - - -ReactDOMHydrationRoot.prototype.unstable_scheduleHydration = scheduleHydration; -function hydrateRoot$1(container, initialChildren, options) { - if (!isValidContainer(container)) { - throw new Error('Target container is not a DOM element.'); - } - - warnIfReactDOMContainerInDEV(container); - - { - if (initialChildren === undefined) { - error('Must provide initial children as second argument to hydrateRoot. ' + 'Example usage: hydrateRoot(domContainer, )'); - } - } // For now we reuse the whole bag of options since they contain - // the hydration callbacks. - - - var hydrationCallbacks = options != null ? options : null; - var isStrictMode = false; - var concurrentUpdatesByDefaultOverride = false; - var identifierPrefix = ''; - var onUncaughtError = defaultOnUncaughtError; - var onCaughtError = defaultOnCaughtError; - var onRecoverableError = defaultOnRecoverableError; - var transitionCallbacks = null; - var formState = null; - - if (options !== null && options !== undefined) { - if (options.unstable_strictMode === true) { - isStrictMode = true; - } - - if (options.unstable_concurrentUpdatesByDefault === true) { - concurrentUpdatesByDefaultOverride = true; - } - - if (options.identifierPrefix !== undefined) { - identifierPrefix = options.identifierPrefix; - } - - if (options.onUncaughtError !== undefined) { - onUncaughtError = options.onUncaughtError; - } - - if (options.onCaughtError !== undefined) { - onCaughtError = options.onCaughtError; - } - - if (options.onRecoverableError !== undefined) { - onRecoverableError = options.onRecoverableError; - } - - if (options.unstable_transitionCallbacks !== undefined) { - transitionCallbacks = options.unstable_transitionCallbacks; - } - - { - if (options.formState !== undefined) { - formState = options.formState; - } - } - } - - var root = createHydrationContainer(initialChildren, null, container, ConcurrentRoot, hydrationCallbacks, isStrictMode, concurrentUpdatesByDefaultOverride, identifierPrefix, onUncaughtError, onCaughtError, onRecoverableError, transitionCallbacks, formState); - markContainerAsRoot(root.current, container); // This can't be a comment node since hydration doesn't work on comment nodes anyway. - - listenToAllSupportedEvents(container); // $FlowFixMe[invalid-constructor] Flow no longer supports calling new on functions - - return new ReactDOMHydrationRoot(root); -} function isValidContainer(node) { return !!(node && (node.nodeType === ELEMENT_NODE || node.nodeType === DOCUMENT_NODE || node.nodeType === DOCUMENT_FRAGMENT_NODE || node.nodeType === COMMENT_NODE && node.nodeValue === ' react-mount-point-unstable ')); } // TODO: Remove this function which also includes comment nodes. @@ -41114,18 +40919,6 @@ function isValidContainerLegacy(node) { return !!(node && (node.nodeType === ELEMENT_NODE || node.nodeType === DOCUMENT_NODE || node.nodeType === DOCUMENT_FRAGMENT_NODE || node.nodeType === COMMENT_NODE && node.nodeValue === ' react-mount-point-unstable ')); } -function warnIfReactDOMContainerInDEV(container) { - { - if (isContainerMarkedAsRoot(container)) { - if (container._reactRootContainer) { - error('You are calling ReactDOMClient.createRoot() on a container that was previously ' + 'passed to ReactDOM.render(). This is not supported.'); - } else { - error('You are calling ReactDOMClient.createRoot() on a container that ' + 'has already been passed to createRoot() before. Instead, call ' + 'root.render() on the existing root instead if you want to update it.'); - } - } - } -} - function isValidEventTarget(target) { return typeof target.addEventListener === 'function'; } @@ -41551,6 +41344,214 @@ var foundDevTools = injectIntoDevTools({ } } +function ReactDOMRoot(internalRoot) { + this._internalRoot = internalRoot; +} // $FlowFixMe[prop-missing] found when upgrading Flow + + +ReactDOMHydrationRoot.prototype.render = ReactDOMRoot.prototype.render = // $FlowFixMe[missing-this-annot] +function (children) { + var root = this._internalRoot; + + if (root === null) { + throw new Error('Cannot update an unmounted root.'); + } + + { + if (typeof arguments[1] === 'function') { + error('does not support the second callback argument. ' + 'To execute a side effect after rendering, declare it in a component body with useEffect().'); + } else if (isValidContainer(arguments[1])) { + error('You passed a container to the second argument of root.render(...). ' + "You don't need to pass it again since you already passed it to create the root."); + } else if (typeof arguments[1] !== 'undefined') { + error('You passed a second argument to root.render(...) but it only accepts ' + 'one argument.'); + } + } + + updateContainer(children, root, null, null); +}; // $FlowFixMe[prop-missing] found when upgrading Flow + + +ReactDOMHydrationRoot.prototype.unmount = ReactDOMRoot.prototype.unmount = // $FlowFixMe[missing-this-annot] +function () { + { + if (typeof arguments[0] === 'function') { + error('does not support a callback argument. ' + 'To execute a side effect after rendering, declare it in a component body with useEffect().'); + } + } + + var root = this._internalRoot; + + if (root !== null) { + this._internalRoot = null; + var container = root.containerInfo; + + { + if (isAlreadyRendering()) { + error('Attempted to synchronously unmount a root while React was already ' + 'rendering. React cannot finish unmounting the root until the ' + 'current render has completed, which may lead to a race condition.'); + } + } + + updateContainerSync(null, root, null, null); + flushSyncWork(); + unmarkContainerAsRoot(container); + } +}; + +function createRoot$1(container, options) { + if (!isValidContainer(container)) { + throw new Error('Target container is not a DOM element.'); + } + + warnIfReactDOMContainerInDEV(container); + var isStrictMode = false; + var concurrentUpdatesByDefaultOverride = false; + var identifierPrefix = ''; + var onUncaughtError = defaultOnUncaughtError; + var onCaughtError = defaultOnCaughtError; + var onRecoverableError = defaultOnRecoverableError; + var transitionCallbacks = null; + + if (options !== null && options !== undefined) { + { + if (options.hydrate) { + warn('hydrate through createRoot is deprecated. Use ReactDOMClient.hydrateRoot(container, ) instead.'); + } else { + if (typeof options === 'object' && options !== null && options.$$typeof === REACT_ELEMENT_TYPE) { + error('You passed a JSX element to createRoot. You probably meant to ' + 'call root.render instead. ' + 'Example usage:\n\n' + ' let root = createRoot(domContainer);\n' + ' root.render();'); + } + } + } + + if (options.unstable_strictMode === true) { + isStrictMode = true; + } + + if (options.unstable_concurrentUpdatesByDefault === true) { + concurrentUpdatesByDefaultOverride = true; + } + + if (options.identifierPrefix !== undefined) { + identifierPrefix = options.identifierPrefix; + } + + if (options.onUncaughtError !== undefined) { + onUncaughtError = options.onUncaughtError; + } + + if (options.onCaughtError !== undefined) { + onCaughtError = options.onCaughtError; + } + + if (options.onRecoverableError !== undefined) { + onRecoverableError = options.onRecoverableError; + } + + if (options.unstable_transitionCallbacks !== undefined) { + transitionCallbacks = options.unstable_transitionCallbacks; + } + } + + var root = createContainer(container, ConcurrentRoot, null, isStrictMode, concurrentUpdatesByDefaultOverride, identifierPrefix, onUncaughtError, onCaughtError, onRecoverableError, transitionCallbacks); + markContainerAsRoot(root.current, container); + var rootContainerElement = container.nodeType === COMMENT_NODE ? container.parentNode : container; + listenToAllSupportedEvents(rootContainerElement); // $FlowFixMe[invalid-constructor] Flow no longer supports calling new on functions + + return new ReactDOMRoot(root); +} // $FlowFixMe[missing-this-annot] + +function ReactDOMHydrationRoot(internalRoot) { + this._internalRoot = internalRoot; +} + +function scheduleHydration(target) { + if (target) { + queueExplicitHydrationTarget(target); + } +} // $FlowFixMe[prop-missing] found when upgrading Flow + + +ReactDOMHydrationRoot.prototype.unstable_scheduleHydration = scheduleHydration; +function hydrateRoot$1(container, initialChildren, options) { + if (!isValidContainer(container)) { + throw new Error('Target container is not a DOM element.'); + } + + warnIfReactDOMContainerInDEV(container); + + { + if (initialChildren === undefined) { + error('Must provide initial children as second argument to hydrateRoot. ' + 'Example usage: hydrateRoot(domContainer, )'); + } + } // For now we reuse the whole bag of options since they contain + // the hydration callbacks. + + + var hydrationCallbacks = options != null ? options : null; + var isStrictMode = false; + var concurrentUpdatesByDefaultOverride = false; + var identifierPrefix = ''; + var onUncaughtError = defaultOnUncaughtError; + var onCaughtError = defaultOnCaughtError; + var onRecoverableError = defaultOnRecoverableError; + var transitionCallbacks = null; + var formState = null; + + if (options !== null && options !== undefined) { + if (options.unstable_strictMode === true) { + isStrictMode = true; + } + + if (options.unstable_concurrentUpdatesByDefault === true) { + concurrentUpdatesByDefaultOverride = true; + } + + if (options.identifierPrefix !== undefined) { + identifierPrefix = options.identifierPrefix; + } + + if (options.onUncaughtError !== undefined) { + onUncaughtError = options.onUncaughtError; + } + + if (options.onCaughtError !== undefined) { + onCaughtError = options.onCaughtError; + } + + if (options.onRecoverableError !== undefined) { + onRecoverableError = options.onRecoverableError; + } + + if (options.unstable_transitionCallbacks !== undefined) { + transitionCallbacks = options.unstable_transitionCallbacks; + } + + { + if (options.formState !== undefined) { + formState = options.formState; + } + } + } + + var root = createHydrationContainer(initialChildren, null, container, ConcurrentRoot, hydrationCallbacks, isStrictMode, concurrentUpdatesByDefaultOverride, identifierPrefix, onUncaughtError, onCaughtError, onRecoverableError, transitionCallbacks, formState); + markContainerAsRoot(root.current, container); // This can't be a comment node since hydration doesn't work on comment nodes anyway. + + listenToAllSupportedEvents(container); // $FlowFixMe[invalid-constructor] Flow no longer supports calling new on functions + + return new ReactDOMHydrationRoot(root); +} + +function warnIfReactDOMContainerInDEV(container) { + { + if (isContainerMarkedAsRoot(container)) { + if (container._reactRootContainer) { + error('You are calling ReactDOMClient.createRoot() on a container that was previously ' + 'passed to ReactDOM.render(). This is not supported.'); + } else { + error('You are calling ReactDOMClient.createRoot() on a container that ' + 'has already been passed to createRoot() before. Instead, call ' + 'root.render() on the existing root instead if you want to update it.'); + } + } + } +} + var ReactFiberErrorDialogWWW = require('ReactFiberErrorDialog'); if (typeof ReactFiberErrorDialogWWW.showErrorDialog !== 'function') { diff --git a/compiled/facebook-www/ReactDOM-dev.modern.js b/compiled/facebook-www/ReactDOM-dev.modern.js index 0c15376dbbdd9..f9a0ebdf9bc56 100644 --- a/compiled/facebook-www/ReactDOM-dev.modern.js +++ b/compiled/facebook-www/ReactDOM-dev.modern.js @@ -28,6 +28,8 @@ if ( var Scheduler = require('scheduler'); var React = require('react'); +var assign = Object.assign; + // This refers to a WWW module. var warningWWW = require('warning'); @@ -82,6 +84,24 @@ function printWarning(level, format, args) { } } +/** + * `ReactInstanceMap` maintains a mapping from a public facing stateful + * instance (key) and the internal representation (value). This allows public + * methods to accept the user facing instance as an argument and map them back + * to internal methods. + * + * Note that this module is currently shared and assumed to be stateless. + * If this becomes an actual Map, that will break. + */ +function get(key) { + return key._reactInternals; +} +function set(key, value) { + key._reactInternals = value; +} + +var ReactSharedInternals = React.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE; + // Re-export dynamic flags from the www version. var dynamicFeatureFlags = require('ReactFeatureFlags'); @@ -116,7 +136,337 @@ var enableAsyncIterableChildren = false; var enableSuspenseCallback = true; var disableLegacyMode = true; -var assign = Object.assign; +var FunctionComponent = 0; +var ClassComponent = 1; +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 IncompleteFunctionComponent = 28; + +// 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_LEGACY_ELEMENT_TYPE = Symbol.for('react.element'); +var REACT_ELEMENT_TYPE = REACT_LEGACY_ELEMENT_TYPE; +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'); // TODO: Delete with enableRenderableContext + +var REACT_CONSUMER_TYPE = Symbol.for('react.consumer'); +var REACT_CONTEXT_TYPE = Symbol.for('react.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_TRACING_MARKER_TYPE = Symbol.for('react.tracing_marker'); +var REACT_MEMO_CACHE_SENTINEL = Symbol.for('react.memo_cache_sentinel'); +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; +} + +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'; +} + +var REACT_CLIENT_REFERENCE = Symbol.for('react.client.reference'); // 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 === 'function') { + if (type.$$typeof === REACT_CLIENT_REFERENCE) { + // TODO: Create a convention for naming client references with debug info. + return null; + } + + 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'; + // Fall through + + case REACT_TRACING_MARKER_TYPE: + if (enableTransitionTracing) { + return 'TracingMarker'; + } + + } + + if (typeof type === 'object') { + { + if (typeof type.tag === 'number') { + error('Received an unexpected object in getComponentNameFromType(). ' + 'This is likely a bug in React. Please file an issue.'); + } + } + + switch (type.$$typeof) { + case REACT_PROVIDER_TYPE: + if (enableRenderableContext) { + return null; + } else { + var provider = type; + return getContextName$1(provider._context) + '.Provider'; + } + + case REACT_CONTEXT_TYPE: + var context = type; + + if (enableRenderableContext) { + return getContextName$1(context) + '.Provider'; + } else { + return getContextName$1(context) + '.Consumer'; + } + + case REACT_CONSUMER_TYPE: + if (enableRenderableContext) { + var consumer = type; + return getContextName$1(consumer._context) + '.Consumer'; + } else { + return null; + } + + 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; + } + } + } + } + + 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 getComponentNameFromOwner(owner) { + if (typeof owner.tag === 'number') { + return getComponentNameFromFiber(owner); + } + + if (typeof owner.name === 'string') { + return owner.name; + } + + return null; +} +function getComponentNameFromFiber(fiber) { + var tag = fiber.tag, + type = fiber.type; + + switch (tag) { + case CacheComponent: + return 'Cache'; + + case ContextConsumer: + if (enableRenderableContext) { + var consumer = type; + return getContextName(consumer._context) + '.Consumer'; + } else { + var context = type; + return getContextName(context) + '.Consumer'; + } + + case ContextProvider: + if (enableRenderableContext) { + var _context = type; + return getContextName(_context) + '.Provider'; + } else { + 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 these tags come from the user-provided type: + + case IncompleteClassComponent: + case IncompleteFunctionComponent: + { + break; + } + + // Fallthrough + + case ClassComponent: + case FunctionComponent: + case MemoComponent: + case SimpleMemoComponent: + if (typeof type === 'function') { + return type.displayName || type.name || null; + } + + if (typeof type === 'string') { + return type; + } + + break; + + case LegacyHiddenComponent: + { + return 'LegacyHidden'; + } + + } + + return null; +} var NoFlags$1 = /* */ @@ -245,129 +595,450 @@ var PassiveMask = Passive$1 | Visibility | ChildDeletion; // Union of tags that 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$2 = Scheduler.log; -var unstable_setDisableYieldValue = Scheduler.unstable_setDisableYieldValue; +function getNearestMountedFiber(fiber) { + var node = fiber; + var nearestMounted = fiber; -// 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; + if (!fiber.alternate) { + // If there is no alternate, this might be a new tree that isn't inserted + // yet. If it is, then it will have a pending insertion effect on it. + var nextNode = node; -function disabledLog() {} + do { + node = nextNode; -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 + if ((node.flags & (Placement | Hydrating)) !== NoFlags$1) { + // This is an insertion or in-progress hydration. The nearest possible + // mounted fiber is the parent but we need to continue to figure out + // if that one is still mounted. + nearestMounted = node.return; + } // $FlowFixMe[incompatible-type] we bail out when we get a null - 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 */ + nextNode = node.return; + } while (nextNode); + } else { + while (node.return) { + node = node.return; } - - disabledDepth++; } + + if (node.tag === HostRoot) { + // TODO: Check if this was a nested HostRoot when used with + // renderContainerIntoSubtree. + return nearestMounted; + } // If we didn't hit the root, that means that we're in an disconnected tree + // that has been unmounted. + + + return null; } -function reenableLogs() { - { - disabledDepth--; +function getSuspenseInstanceFromFiber(fiber) { + if (fiber.tag === SuspenseComponent) { + var suspenseState = fiber.memoizedState; - 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. + if (suspenseState === null) { + var current = fiber.alternate; - 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 (current !== null) { + suspenseState = current.memoizedState; + } } - if (disabledDepth < 0) { - error('disabledDepth fell below zero. ' + 'This is a bug in React. Please file an issue.'); + if (suspenseState !== null) { + return suspenseState.dehydrated; } } + + return null; +} +function getContainerFromFiber(fiber) { + return fiber.tag === HostRoot ? fiber.stateNode.containerInfo : null; } +function isMounted(component) { + { + var owner = ReactSharedInternals.owner; -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; - } + if (owner !== null && owner.tag === ClassComponent) { + var ownerFiber = owner; + var instance = ownerFiber.stateNode; - var hook = __REACT_DEVTOOLS_GLOBAL_HOOK__; + if (!instance._warnedAboutRefsInRender) { + error('%s is accessing isMounted inside its render() function. ' + 'render() should be a pure function of props and state. It should ' + 'never access something that requires stale data from the previous ' + 'render, such as refs. Move this logic to componentDidMount and ' + 'componentDidUpdate instead.', getComponentNameFromFiber(ownerFiber) || 'A component'); + } + + instance._warnedAboutRefsInRender = true; + } + } + + var fiber = get(component); + + if (!fiber) { + return false; + } + + return getNearestMountedFiber(fiber) === fiber; +} + +function assertIsMounted(fiber) { + if (getNearestMountedFiber(fiber) !== fiber) { + throw new Error('Unable to find node on an unmounted component.'); + } +} + +function findCurrentFiberUsingSlowPath(fiber) { + var alternate = fiber.alternate; + + if (!alternate) { + // If there is no alternate, then we only need to check if it is mounted. + var nearestMounted = getNearestMountedFiber(fiber); + + if (nearestMounted === null) { + throw new Error('Unable to find node on an unmounted component.'); + } + + if (nearestMounted !== fiber) { + return null; + } + + return fiber; + } // If we have two possible branches, we'll walk backwards up to the root + // to see what path the root points to. On the way we may hit one of the + // special cases and we'll deal with them. + + + var a = fiber; + var b = alternate; + + while (true) { + var parentA = a.return; + + if (parentA === null) { + // We're at the root. + break; + } + + var parentB = parentA.alternate; + + if (parentB === null) { + // There is no alternate. This is an unusual case. Currently, it only + // happens when a Suspense component is hidden. An extra fragment fiber + // is inserted in between the Suspense fiber and its children. Skip + // over this extra fragment fiber and proceed to the next parent. + var nextParent = parentA.return; + + if (nextParent !== null) { + a = b = nextParent; + continue; + } // If there's no parent, we're at the root. + + + break; + } // If both copies of the parent fiber point to the same child, we can + // assume that the child is current. This happens when we bailout on low + // priority: the bailed out fiber's child reuses the current child. + + + if (parentA.child === parentB.child) { + var child = parentA.child; + + while (child) { + if (child === a) { + // We've determined that A is the current branch. + assertIsMounted(parentA); + return fiber; + } + + if (child === b) { + // We've determined that B is the current branch. + assertIsMounted(parentA); + return alternate; + } + + child = child.sibling; + } // We should never have an alternate for any mounting node. So the only + // way this could possibly happen is if this was unmounted, if at all. + + + throw new Error('Unable to find node on an unmounted component.'); + } + + if (a.return !== b.return) { + // The return pointer of A and the return pointer of B point to different + // fibers. We assume that return pointers never criss-cross, so A must + // belong to the child set of A.return, and B must belong to the child + // set of B.return. + a = parentA; + b = parentB; + } else { + // The return pointers point to the same fiber. We'll have to use the + // default, slow path: scan the child sets of each parent alternate to see + // which child belongs to which set. + // + // Search parent A's child set + var didFindChild = false; + var _child = parentA.child; + + while (_child) { + if (_child === a) { + didFindChild = true; + a = parentA; + b = parentB; + break; + } + + if (_child === b) { + didFindChild = true; + b = parentA; + a = parentB; + break; + } + + _child = _child.sibling; + } + + if (!didFindChild) { + // Search parent B's child set + _child = parentB.child; + + while (_child) { + if (_child === a) { + didFindChild = true; + a = parentB; + b = parentA; + break; + } + + if (_child === b) { + didFindChild = true; + b = parentB; + a = parentA; + break; + } + + _child = _child.sibling; + } + + if (!didFindChild) { + throw new Error('Child was not found in either parent set. This indicates a bug ' + 'in React related to the return pointer. Please file an issue.'); + } + } + } + + if (a.alternate !== b) { + throw new Error("Return fibers should always be each others' alternates. " + 'This error is likely caused by a bug in React. Please file an issue.'); + } + } // If the root is not a host container, we're in a disconnected tree. I.e. + // unmounted. + + + if (a.tag !== HostRoot) { + throw new Error('Unable to find node on an unmounted component.'); + } + + if (a.stateNode.current === a) { + // We've determined that A is the current branch. + return fiber; + } // Otherwise B has to be current branch. + + + return alternate; +} +function findCurrentHostFiber(parent) { + var currentParent = findCurrentFiberUsingSlowPath(parent); + return currentParent !== null ? findCurrentHostFiberImpl(currentParent) : null; +} + +function findCurrentHostFiberImpl(node) { + // Next we'll drill down this component to find the first HostComponent/Text. + var tag = node.tag; + + if (tag === HostComponent || tag === HostHoistable || tag === HostSingleton || tag === HostText) { + return node; + } + + var child = node.child; + + while (child !== null) { + var match = findCurrentHostFiberImpl(child); + + if (match !== null) { + return match; + } + + child = child.sibling; + } + + return null; +} + +function isFiberSuspenseAndTimedOut(fiber) { + var memoizedState = fiber.memoizedState; + return fiber.tag === SuspenseComponent && memoizedState !== null && memoizedState.dehydrated === null; +} +function doesFiberContain(parentFiber, childFiber) { + var node = childFiber; + var parentFiberAlternate = parentFiber.alternate; + + while (node !== null) { + if (node === parentFiber || node === parentFiberAlternate) { + return true; + } + + node = node.return; + } + + return false; +} + +// This exists to avoid circular dependency between ReactDOMEventReplaying +// and DOMPluginEventSystem. +var currentReplayingEvent = null; +function setReplayingEvent(event) { + { + if (currentReplayingEvent !== null) { + error('Expected currently replaying event to be null. This error ' + 'is likely caused by a bug in React. Please file an issue.'); + } + } + + currentReplayingEvent = event; +} +function resetReplayingEvent() { + { + if (currentReplayingEvent === null) { + error('Expected currently replaying event to not be null. This error ' + 'is likely caused by a bug in React. Please file an issue.'); + } + } + + currentReplayingEvent = null; +} +function isReplayingEvent(event) { + return event === currentReplayingEvent; +} + +// 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$2 = 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 @@ -1795,3456 +2466,2584 @@ var Internals = { findDOMNode: null }; -/** - * `ReactInstanceMap` maintains a mapping from a public facing stateful - * instance (key) and the internal representation (value). This allows public - * methods to accept the user facing instance as an argument and map them back - * to internal methods. - * - * Note that this module is currently shared and assumed to be stateless. - * If this becomes an actual Map, that will break. - */ -function get(key) { - return key._reactInternals; -} -function set(key, value) { - key._reactInternals = value; -} +// same object across all transitions. -var ReactSharedInternals = React.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE; +var sharedNotPendingObject = { + pending: false, + data: null, + method: null, + action: null +}; +var NotPending = Object.freeze(sharedNotPendingObject) ; -var FunctionComponent = 0; -var ClassComponent = 1; -var HostRoot = 3; // Root of a host tree. Could be nested inside another node. +function resolveDispatcher() { + // Copied from react/src/ReactHooks.js. It's the same thing but in a + // different package. + var dispatcher = ReactSharedInternals.H; -var HostPortal = 4; // A subtree. Could be an entry point to a different renderer. + { + 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://react.dev/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. -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 IncompleteFunctionComponent = 28; -// 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. + return dispatcher; +} -var REACT_LEGACY_ELEMENT_TYPE = Symbol.for('react.element'); -var REACT_ELEMENT_TYPE = REACT_LEGACY_ELEMENT_TYPE; -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'); // TODO: Delete with enableRenderableContext +function useFormStatus() { + { + var dispatcher = resolveDispatcher(); // $FlowFixMe[not-a-function] We know this exists because of the feature check above. -var REACT_CONSUMER_TYPE = Symbol.for('react.consumer'); -var REACT_CONTEXT_TYPE = Symbol.for('react.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_TRACING_MARKER_TYPE = Symbol.for('react.tracing_marker'); -var REACT_MEMO_CACHE_SENTINEL = Symbol.for('react.memo_cache_sentinel'); -var MAYBE_ITERATOR_SYMBOL = Symbol.iterator; -var FAUX_ITERATOR_SYMBOL = '@@iterator'; -function getIteratorFn(maybeIterable) { - if (maybeIterable === null || typeof maybeIterable !== 'object') { - return null; + return dispatcher.useHostTransitionStatus(); } +} +function useFormState(action, initialState, permalink) { + { + var dispatcher = resolveDispatcher(); // $FlowFixMe[not-a-function] This is unstable, thus optional - var maybeIterator = MAYBE_ITERATOR_SYMBOL && maybeIterable[MAYBE_ITERATOR_SYMBOL] || maybeIterable[FAUX_ITERATOR_SYMBOL]; - - if (typeof maybeIterator === 'function') { - return maybeIterator; + return dispatcher.useFormState(action, initialState, permalink); } - - return null; +} +function requestFormReset$2(form) { + Internals.d + /* ReactDOMCurrentDispatcher */ + .r( + /* requestFormReset */ + form); } -function getWrappedName$1(outerType, innerType, wrapperName) { - var displayName = outerType.displayName; - - if (displayName) { - return displayName; - } +var valueStack = []; +var fiberStack; - var functionName = innerType.displayName || innerType.name || ''; - return functionName !== '' ? wrapperName + "(" + functionName + ")" : wrapperName; -} // Keep in sync with react-reconciler/getComponentNameFromFiber +{ + fiberStack = []; +} +var index = -1; -function getContextName$1(type) { - return type.displayName || 'Context'; +function createCursor(defaultValue) { + return { + current: defaultValue + }; } -var REACT_CLIENT_REFERENCE = Symbol.for('react.client.reference'); // Note that the reconciler package should generally prefer to use getComponentNameFromFiber() instead. +function pop(cursor, fiber) { + if (index < 0) { + { + error('Unexpected pop.'); + } -function getComponentNameFromType(type) { - if (type == null) { - // Host root, text node or just invalid type. - return null; + return; } - if (typeof type === 'function') { - if (type.$$typeof === REACT_CLIENT_REFERENCE) { - // TODO: Create a convention for naming client references with debug info. - return null; + { + if (fiber !== fiberStack[index]) { + error('Unexpected Fiber popped.'); } - - return type.displayName || type.name || null; } - if (typeof type === 'string') { - return type; + cursor.current = valueStack[index]; + valueStack[index] = null; + + { + fiberStack[index] = null; } - switch (type) { - case REACT_FRAGMENT_TYPE: - return 'Fragment'; + index--; +} - case REACT_PORTAL_TYPE: - return 'Portal'; +function push(cursor, value, fiber) { + index++; + valueStack[index] = cursor.current; - case REACT_PROFILER_TYPE: - return 'Profiler'; + { + fiberStack[index] = fiber; + } - case REACT_STRICT_MODE_TYPE: - return 'StrictMode'; + cursor.current = value; +} - case REACT_SUSPENSE_TYPE: - return 'Suspense'; +var contextStackCursor = 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. - case REACT_SUSPENSE_LIST_TYPE: - return 'SuspenseList'; - // Fall through +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. - case REACT_TRACING_MARKER_TYPE: - if (enableTransitionTracing) { - return 'TracingMarker'; - } +var HostTransitionContext = { + $$typeof: REACT_CONTEXT_TYPE, + Provider: null, + Consumer: null, + _currentValue: null, + _currentValue2: null, + _threadCount: 0 +}; +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.'); + } } - if (typeof type === 'object') { - { - if (typeof type.tag === 'number') { - error('Received an unexpected object in getComponentNameFromType(). ' + 'This is likely a bug in React. Please file an issue.'); - } - } + return c; +} - switch (type.$$typeof) { - case REACT_PROVIDER_TYPE: - if (enableRenderableContext) { - return null; - } else { - var provider = type; - return getContextName$1(provider._context) + '.Provider'; - } +function getCurrentRootHostContainer() { + return rootInstanceStackCursor.current; +} - case REACT_CONTEXT_TYPE: - var context = type; +function getRootHostContainer() { + var rootInstance = requiredContext(rootInstanceStackCursor.current); + return rootInstance; +} - if (enableRenderableContext) { - return getContextName$1(context) + '.Provider'; - } else { - return getContextName$1(context) + '.Consumer'; - } +function getHostTransitionProvider() { + return hostTransitionProviderCursor.current; +} - case REACT_CONSUMER_TYPE: - if (enableRenderableContext) { - var consumer = type; - return getContextName$1(consumer._context) + '.Consumer'; - } else { - return null; - } +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. - case REACT_FORWARD_REF_TYPE: - return getWrappedName$1(type, type.render, 'ForwardRef'); + 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. - case REACT_MEMO_TYPE: - var outerName = type.displayName || null; + push(contextStackCursor, null, fiber); + var nextRootContext = getRootHostContext(nextRootInstance); // Now that we know this function doesn't throw, replace it. - if (outerName !== null) { - return outerName; - } + pop(contextStackCursor, fiber); + push(contextStackCursor, nextRootContext, fiber); +} - return getComponentNameFromType(type.type) || 'Memo'; +function popHostContainer(fiber) { + pop(contextStackCursor, fiber); + pop(contextFiberStackCursor, fiber); + pop(rootInstanceStackCursor, fiber); +} - case REACT_LAZY_TYPE: - { - var lazyComponent = type; - var payload = lazyComponent._payload; - var init = lazyComponent._init; +function getHostContext() { + var context = requiredContext(contextStackCursor.current); + return context; +} - try { - return getComponentNameFromType(init(payload)); - } catch (x) { - return null; - } - } +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); } } - return null; + var context = requiredContext(contextStackCursor.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, nextContext, fiber); + } } -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 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, 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. -function getContextName(type) { - return type.displayName || 'Context'; + { + HostTransitionContext._currentValue = null; + } + } + } } -function getComponentNameFromOwner(owner) { - if (typeof owner.tag === 'number') { - return getComponentNameFromFiber(owner); +// $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. - if (typeof owner.name === 'string') { - return owner.name; + +function willCoercionThrow(value) { + { + try { + testStringCoercion(value); + return false; + } catch (e) { + return true; + } } +} - return null; +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 getComponentNameFromFiber(fiber) { - var tag = fiber.tag, - type = fiber.type; - switch (tag) { - case CacheComponent: - return 'Cache'; +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 using it here.', attributeName, typeName(value)); - case ContextConsumer: - if (enableRenderableContext) { - var consumer = type; - return getContextName(consumer._context) + '.Consumer'; - } else { - var context = type; - return getContextName(context) + '.Consumer'; - } + 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 using it here.', typeName(value)); - case ContextProvider: - if (enableRenderableContext) { - var _context = type; - return getContextName(_context) + '.Provider'; - } else { - var provider = type; - return getContextName(provider._context) + '.Provider'; - } + 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 using it here.', propName, typeName(value)); - case DehydratedFragment: - return 'DehydratedFragment'; + 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 using it here.', typeName(value)); - case ForwardRef: - return getWrappedName(type, type.render, 'ForwardRef'); + 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 using it here.', typeName(value)); - case Fragment: - return 'Fragment'; + return testStringCoercion(value); // throw (to help callers find troubleshooting comments) + } + } +} - case HostHoistable: - case HostSingleton: - case HostComponent: - // Host component type is the display name (e.g. "div", "View") - return type; +function setCurrentUpdatePriority(newPriority, // Closure will consistently not inline this function when it has arity 1 +// however when it has arity 2 even if the second arg is omitted at every +// callsite it seems to inline it even when the internal length of the function +// is much longer. I hope this is consistent enough to rely on across builds +IntentionallyUnusedArgument) { + Internals.p + /* currentUpdatePriority */ + = newPriority; +} +function getCurrentUpdatePriority() { + return Internals.p; + /* currentUpdatePriority */ +} +function resolveUpdatePriority() { + var updatePriority = Internals.p; + /* currentUpdatePriority */ - case HostPortal: - return 'Portal'; + if (updatePriority !== NoEventPriority) { + return updatePriority; + } - case HostRoot: - return 'Root'; + var currentEvent = window.event; - case HostText: - return 'Text'; + if (currentEvent === undefined) { + return DefaultEventPriority; + } - 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 these tags come from the user-provided type: - - case IncompleteClassComponent: - case IncompleteFunctionComponent: - { - break; - } - - // Fallthrough - - case ClassComponent: - case FunctionComponent: - case MemoComponent: - case SimpleMemoComponent: - if (typeof type === 'function') { - return type.displayName || type.name || null; - } - - if (typeof type === 'string') { - return type; - } - - break; - - case LegacyHiddenComponent: - { - return 'LegacyHidden'; - } + return getEventPriority(currentEvent.type); +} +function runWithPriority(priority, fn) { + var previousPriority = getCurrentUpdatePriority(); + try { + setCurrentUpdatePriority(priority); + return fn(); + } finally { + setCurrentUpdatePriority(previousPriority); } - - return null; } -function getNearestMountedFiber(fiber) { - var node = fiber; - var nearestMounted = fiber; +var allNativeEvents = new Set(); - if (!fiber.alternate) { - // If there is no alternate, this might be a new tree that isn't inserted - // yet. If it is, then it will have a pending insertion effect on it. - var nextNode = node; +{ + allNativeEvents.add('beforeblur'); + allNativeEvents.add('afterblur'); +} +/** + * Mapping from registration name to event name + */ - do { - node = nextNode; - if ((node.flags & (Placement | Hydrating)) !== NoFlags$1) { - // This is an insertion or in-progress hydration. The nearest possible - // mounted fiber is the parent but we need to continue to figure out - // if that one is still mounted. - nearestMounted = node.return; - } // $FlowFixMe[incompatible-type] we bail out when we get a null +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 - nextNode = node.return; - } while (nextNode); - } else { - while (node.return) { - node = node.return; +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); } } - if (node.tag === HostRoot) { - // TODO: Check if this was a nested HostRoot when used with - // renderContainerIntoSubtree. - return nearestMounted; - } // If we didn't hit the root, that means that we're in an disconnected tree - // that has been unmounted. + registrationNameDependencies[registrationName] = dependencies; + + { + var lowerCasedName = registrationName.toLowerCase(); + possibleRegistrationNames[lowerCasedName] = registrationName; + if (registrationName === 'onDoubleClick') { + possibleRegistrationNames.ondblclick = registrationName; + } + } - return null; + for (var i = 0; i < dependencies.length; i++) { + allNativeEvents.add(dependencies[i]); + } } -function getSuspenseInstanceFromFiber(fiber) { - if (fiber.tag === SuspenseComponent) { - var suspenseState = fiber.memoizedState; - if (suspenseState === null) { - var current = fiber.alternate; +var canUseDOM = !!(typeof window !== 'undefined' && typeof window.document !== 'undefined' && typeof window.document.createElement !== 'undefined'); - if (current !== null) { - suspenseState = current.memoizedState; +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)) { + if (tagName === 'select') { + error('You provided a `value` prop to a form field without an ' + '`onChange` handler. This will render a read-only field. If ' + 'the field should be mutable use `defaultValue`. Otherwise, set `onChange`.'); + } else { + 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 (suspenseState !== null) { - return suspenseState.dehydrated; + 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`.'); } } - - return null; -} -function getContainerFromFiber(fiber) { - return fiber.tag === HostRoot ? fiber.stateNode.containerInfo : null; } -function isMounted(component) { - { - var owner = ReactSharedInternals.owner; - if (owner !== null && owner.tag === ClassComponent) { - var ownerFiber = owner; - var instance = ownerFiber.stateNode; +/* eslint-disable max-len */ - if (!instance._warnedAboutRefsInRender) { - error('%s is accessing isMounted inside its render() function. ' + 'render() should be a pure function of props and state. It should ' + 'never access something that requires stale data from the previous ' + 'render, such as refs. Move this logic to componentDidMount and ' + 'componentDidUpdate instead.', getComponentNameFromFiber(ownerFiber) || 'A component'); - } +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 */ - instance._warnedAboutRefsInRender = true; - } +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; } - var fiber = get(component); - - if (!fiber) { + if (hasOwnProperty.call(illegalAttributeNameCache, attributeName)) { return false; } - return getNearestMountedFiber(fiber) === fiber; -} - -function assertIsMounted(fiber) { - if (getNearestMountedFiber(fiber) !== fiber) { - throw new Error('Unable to find node on an unmounted component.'); + if (VALID_ATTRIBUTE_NAME_REGEX.test(attributeName)) { + validatedAttributeNameCache[attributeName] = true; + return true; } -} -function findCurrentFiberUsingSlowPath(fiber) { - var alternate = fiber.alternate; + illegalAttributeNameCache[attributeName] = true; - if (!alternate) { - // If there is no alternate, then we only need to check if it is mounted. - var nearestMounted = getNearestMountedFiber(fiber); + { + error('Invalid attribute name: `%s`', attributeName); + } - if (nearestMounted === null) { - throw new Error('Unable to find node on an unmounted component.'); - } + return false; +} - if (nearestMounted !== fiber) { - return null; - } +/** + * 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. + */ - return fiber; - } // If we have two possible branches, we'll walk backwards up to the root - // to see what path the root points to. On the way we may hit one of the - // special cases and we'll deal with them. +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; - var a = fiber; - var b = alternate; + case 'boolean': + { + var prefix = name.toLowerCase().slice(0, 5); - while (true) { - var parentA = a.return; + if (prefix !== 'data-' && prefix !== 'aria-') { + return expected; + } + } + } - if (parentA === null) { - // We're at the root. - break; + return expected === undefined ? undefined : null; } - var parentB = parentA.alternate; - - if (parentB === null) { - // There is no alternate. This is an unusual case. Currently, it only - // happens when a Suspense component is hidden. An extra fragment fiber - // is inserted in between the Suspense fiber and its children. Skip - // over this extra fragment fiber and proceed to the next parent. - var nextParent = parentA.return; + var value = node.getAttribute(name); - if (nextParent !== null) { - a = b = nextParent; - continue; - } // If there's no parent, we're at the root. + { + checkAttributeStringCoercion(expected, name); + } + if (value === '' + expected) { + return expected; + } - break; - } // If both copies of the parent fiber point to the same child, we can - // assume that the child is current. This happens when we bailout on low - // priority: the bailed out fiber's child reuses the current child. + 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; - if (parentA.child === parentB.child) { - var child = parentA.child; + case 'function': + return expected; - while (child) { - if (child === a) { - // We've determined that A is the current branch. - assertIsMounted(parentA); - return fiber; - } + case 'boolean': + if (expected === false) { + return expected; + } - if (child === b) { - // We've determined that B is the current branch. - assertIsMounted(parentA); - return alternate; - } + } - child = child.sibling; - } // We should never have an alternate for any mounting node. So the only - // way this could possibly happen is if this was unmounted, if at all. + return expected === undefined ? undefined : null; + } + var value = node.getAttribute(name); - throw new Error('Unable to find node on an unmounted component.'); + if (value === '' && expected === true) { + return true; } - if (a.return !== b.return) { - // The return pointer of A and the return pointer of B point to different - // fibers. We assume that return pointers never criss-cross, so A must - // belong to the child set of A.return, and B must belong to the child - // set of B.return. - a = parentA; - b = parentB; - } else { - // The return pointers point to the same fiber. We'll have to use the - // default, slow path: scan the child sets of each parent alternate to see - // which child belongs to which set. - // - // Search parent A's child set - var didFindChild = false; - var _child = parentA.child; - - while (_child) { - if (_child === a) { - didFindChild = true; - a = parentA; - b = parentB; - break; - } + { + checkAttributeStringCoercion(expected, name); + } - if (_child === b) { - didFindChild = true; - b = parentA; - a = parentB; - break; - } + if (value === '' + expected) { + return expected; + } - _child = _child.sibling; - } + 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; + } - if (!didFindChild) { - // Search parent B's child set - _child = parentB.child; + switch (typeof value) { + case 'undefined': + case 'function': + case 'symbol': + // eslint-disable-line + node.removeAttribute(name); + return; - while (_child) { - if (_child === a) { - didFindChild = true; - a = parentB; - b = parentA; - break; - } + case 'boolean': + { + var prefix = name.toLowerCase().slice(0, 5); - if (_child === b) { - didFindChild = true; - b = parentB; - a = parentA; - break; + if (prefix !== 'data-' && prefix !== 'aria-') { + node.removeAttribute(name); + return; } - - _child = _child.sibling; - } - - if (!didFindChild) { - throw new Error('Child was not found in either parent set. This indicates a bug ' + 'in React related to the return pointer. Please file an issue.'); } - } } - if (a.alternate !== b) { - throw new Error("Return fibers should always be each others' alternates. " + 'This error is likely caused by a bug in React. Please file an issue.'); + { + checkAttributeStringCoercion(value, name); } - } // If the root is not a host container, we're in a disconnected tree. I.e. - // unmounted. - - if (a.tag !== HostRoot) { - throw new Error('Unable to find node on an unmounted component.'); + node.setAttribute(name, enableTrustedTypesIntegration ? value : '' + value); + } +} +function setValueForKnownAttribute(node, name, value) { + if (value === null) { + node.removeAttribute(name); + return; } - if (a.stateNode.current === a) { - // We've determined that A is the current branch. - return fiber; - } // Otherwise B has to be current branch. + switch (typeof value) { + case 'undefined': + case 'function': + case 'symbol': + case 'boolean': + { + node.removeAttribute(name); + return; + } + } + { + checkAttributeStringCoercion(value, name); + } - return alternate; -} -function findCurrentHostFiber(parent) { - var currentParent = findCurrentFiberUsingSlowPath(parent); - return currentParent !== null ? findCurrentHostFiberImpl(currentParent) : null; + node.setAttribute(name, enableTrustedTypesIntegration ? value : '' + value); } +function setValueForNamespacedAttribute(node, namespace, name, value) { + if (value === null) { + node.removeAttribute(name); + return; + } -function findCurrentHostFiberImpl(node) { - // Next we'll drill down this component to find the first HostComponent/Text. - var tag = node.tag; - - if (tag === HostComponent || tag === HostHoistable || tag === HostSingleton || tag === HostText) { - return node; + switch (typeof value) { + case 'undefined': + case 'function': + case 'symbol': + case 'boolean': + { + node.removeAttribute(name); + return; + } } - var child = node.child; + { + checkAttributeStringCoercion(value, name); + } - while (child !== null) { - var match = findCurrentHostFiberImpl(child); + node.setAttributeNS(namespace, name, enableTrustedTypesIntegration ? value : '' + 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 (match !== null) { - return match; + if (typeof prevValue === 'function') { + node.removeEventListener(eventName, prevValue, useCapture); } - child = child.sibling; - } - - return null; -} + 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. -function isFiberSuspenseAndTimedOut(fiber) { - var memoizedState = fiber.memoizedState; - return fiber.tag === SuspenseComponent && memoizedState !== null && memoizedState.dehydrated === null; -} -function doesFiberContain(parentFiber, childFiber) { - var node = childFiber; - var parentFiberAlternate = parentFiber.alternate; - while (node !== null) { - if (node === parentFiber || node === parentFiberAlternate) { - return true; + node.addEventListener(eventName, value, useCapture); + return; } + } - node = node.return; + if (name in node) { + node[name] = value; + return; } - return false; -} - -var LegacyRoot = 0; -var ConcurrentRoot = 1; - -var isArrayImpl = Array.isArray; // eslint-disable-next-line no-redeclare - -function isArray(a) { - return isArrayImpl(a); -} - -// 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 = ReactSharedInternals.H; - - { - 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://react.dev/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. + if (value === true) { + node.setAttribute(name, ''); + return; + } // From here, it's the same as any attribute - return dispatcher; + setValueForAttribute(node, name, value); } -function useFormStatus() { +var prefix; +function describeBuiltInComponentFrame(name) { { - var dispatcher = resolveDispatcher(); // $FlowFixMe[not-a-function] We know this exists because of the feature check above. + 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 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); + return '\n' + prefix + name; } } -function requestFormReset$2(form) { - Internals.d - /* ReactDOMCurrentDispatcher */ - .r( - /* requestFormReset */ - form); +function describeDebugInfoFrame(name, env) { + return describeBuiltInComponentFrame(name + (env ? ' (' + env + ')' : '')); } - -var valueStack = []; -var fiberStack; +var reentry = false; +var componentFrameCache; { - fiberStack = []; -} - -var index = -1; - -function createCursor(defaultValue) { - return { - current: defaultValue - }; + var PossiblyWeakMap$2 = typeof WeakMap === 'function' ? WeakMap : Map; + componentFrameCache = new PossiblyWeakMap$2(); } +/** + * Leverages native browser/VM stack frames to get proper details (e.g. + * filename, line + col number) for a single component in a component stack. We + * do this by: + * (1) throwing and catching an error in the function - this will be our + * control error. + * (2) calling the component which will eventually throw an error that we'll + * catch - this will be our sample error. + * (3) diffing the control and sample error stacks to find the stack frame + * which represents our component. + */ -function pop(cursor, fiber) { - if (index < 0) { - { - error('Unexpected pop.'); - } - return; +function describeNativeComponentFrame(fn, construct) { + // If something asked for a stack inside a fake render, it should get ignored. + if (!fn || reentry) { + return ''; } { - if (fiber !== fiberStack[index]) { - error('Unexpected Fiber popped.'); + var frame = componentFrameCache.get(fn); + + if (frame !== undefined) { + return frame; } } - cursor.current = valueStack[index]; - valueStack[index] = null; + reentry = true; + var previousPrepareStackTrace = Error.prepareStackTrace; // $FlowFixMe[incompatible-type] It does accept undefined. + + Error.prepareStackTrace = undefined; + var previousDispatcher = null; { - fiberStack[index] = null; + previousDispatcher = ReactSharedInternals.H; // Set the dispatcher in DEV because this might be call in the render function + // for warnings. + + ReactSharedInternals.H = null; + disableLogs(); } + /** + * Finding a common stack frame between sample and control errors can be + * tricky given the different types and levels of stack trace truncation from + * different JS VMs. So instead we'll attempt to control what that common + * frame should be through this object method: + * Having both the sample and control errors be in the function under the + * `DescribeNativeComponentFrameRoot` property, + setting the `name` and + * `displayName` properties of the function ensures that a stack + * frame exists that has the method name `DescribeNativeComponentFrameRoot` in + * it for both control and sample stacks. + */ - index--; -} -function push(cursor, value, fiber) { - index++; - valueStack[index] = cursor.current; + var RunInRootFrame = { + DetermineComponentFrameRoot: function () { + var control; - { - fiberStack[index] = fiber; - } + try { + // This should throw. + if (construct) { + // Something should be setting the props in the constructor. + var Fake = function () { + throw Error(); + }; // $FlowFixMe[prop-missing] - cursor.current = value; -} -var contextStackCursor = 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. + 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(); + } + }); -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. + 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; + } -var HostTransitionContext = { - $$typeof: REACT_CONTEXT_TYPE, - Provider: null, - Consumer: null, - _currentValue: null, - _currentValue2: null, - _threadCount: 0 -}; + Reflect.construct(fn, [], Fake); + } else { + try { + Fake.call(); + } catch (x) { + control = x; + } // $FlowFixMe[prop-missing] found when upgrading Flow -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.'); + + 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') { + return [sample.stack, control.stack]; + } + } + + return [null, null]; } - } + }; // $FlowFixMe[prop-missing] - return c; -} + RunInRootFrame.DetermineComponentFrameRoot.displayName = 'DetermineComponentFrameRoot'; + var namePropDescriptor = Object.getOwnPropertyDescriptor(RunInRootFrame.DetermineComponentFrameRoot, 'name'); // Before ES6, the `name` property was not configurable. -function getCurrentRootHostContainer() { - return rootInstanceStackCursor.current; -} + if (namePropDescriptor && namePropDescriptor.configurable) { + // V8 utilizes a function's `name` property when generating a stack trace. + Object.defineProperty(RunInRootFrame.DetermineComponentFrameRoot, // Configurable properties can be updated even if its writable descriptor + // is set to `false`. + // $FlowFixMe[cannot-write] + 'name', { + value: 'DetermineComponentFrameRoot' + }); + } -function getRootHostContainer() { - var rootInstance = requiredContext(rootInstanceStackCursor.current); - return rootInstance; -} + try { + var _RunInRootFrame$Deter = RunInRootFrame.DetermineComponentFrameRoot(), + sampleStack = _RunInRootFrame$Deter[0], + controlStack = _RunInRootFrame$Deter[1]; -function getHostTransitionProvider() { - return hostTransitionProviderCursor.current; -} + if (sampleStack && controlStack) { + // 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 = sampleStack.split('\n'); + var controlLines = controlStack.split('\n'); + var s = 0; + var c = 0; -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. + while (s < sampleLines.length && !sampleLines[s].includes('DetermineComponentFrameRoot')) { + s++; + } - 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. + while (c < controlLines.length && !controlLines[c].includes('DetermineComponentFrameRoot')) { + c++; + } // We couldn't find our intentionally injected common root frame, attempt + // to find another common root frame by search from the bottom of the + // control stack... - push(contextStackCursor, null, fiber); - var nextRootContext = getRootHostContext(nextRootInstance); // Now that we know this function doesn't throw, replace it. - pop(contextStackCursor, fiber); - push(contextStackCursor, nextRootContext, fiber); -} + if (s === sampleLines.length || c === controlLines.length) { + s = sampleLines.length - 1; + c = controlLines.length - 1; -function popHostContainer(fiber) { - pop(contextStackCursor, fiber); - pop(contextFiberStackCursor, fiber); - pop(rootInstanceStackCursor, fiber); -} + 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--; + } + } -function getHostContext() { - var context = requiredContext(contextStackCursor.current); - return context; -} + 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. -function pushHostContext(fiber) { - { - var stateHook = fiber.memoizedState; + 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 (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.current); - var nextContext = getChildHostContext(context, fiber.type); // Don't push this Fiber's context unless it's unique. + if (fn.displayName && _frame.includes('')) { + _frame = _frame.replace('', fn.displayName); + } - 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, nextContext, fiber); - } -} + if (true) { + if (typeof fn === 'function') { + componentFrameCache.set(fn, _frame); + } + } // Return the line we found. -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, 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. + return _frame; + } + } while (s >= 1 && c >= 0); + } - { - HostTransitionContext._currentValue = null; + break; + } } } - } -} + } finally { + reentry = false; -// $FlowFixMe[method-unbinding] -var hasOwnProperty = Object.prototype.hasOwnProperty; + { + ReactSharedInternals.H = previousDispatcher; + reenableLogs(); + } -/* - * 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] + Error.prepareStackTrace = previousPrepareStackTrace; + } // Fallback to just using the name if we couldn't make it throw. - return type; - } -} // $FlowFixMe[incompatible-return] only called in DEV, so void return is not possible. + var name = fn ? fn.displayName || fn.name : ''; + var syntheticFrame = name ? describeBuiltInComponentFrame(name) : ''; -function willCoercionThrow(value) { { - try { - testStringCoercion(value); - return false; - } catch (e) { - return true; + if (typeof fn === 'function') { + componentFrameCache.set(fn, syntheticFrame); } } -} -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; + return syntheticFrame; } -function checkAttributeStringCoercion(value, attributeName) { +function describeClassComponentFrame(ctor) { { - if (willCoercionThrow(value)) { - error('The provided `%s` attribute is an unsupported type %s.' + ' This value must be coerced to a string before using it here.', attributeName, typeName(value)); - - return testStringCoercion(value); // throw (to help callers find troubleshooting comments) - } + return describeNativeComponentFrame(ctor, true); } } -function checkKeyStringCoercion(value) { +function describeFunctionComponentFrame(fn) { { - if (willCoercionThrow(value)) { - error('The provided key is an unsupported type %s.' + ' This value must be coerced to a string before using it here.', typeName(value)); - - return testStringCoercion(value); // throw (to help callers find troubleshooting comments) - } + return describeNativeComponentFrame(fn, false); } } -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 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 using it here.', typeName(value)); +function describeFiber(fiber) { + switch (fiber.tag) { + case HostHoistable: + case HostSingleton: + case HostComponent: + return describeBuiltInComponentFrame(fiber.type); - return testStringCoercion(value); // throw (to help callers find troubleshooting comments) - } + case LazyComponent: + return describeBuiltInComponentFrame('Lazy'); + + case SuspenseComponent: + return describeBuiltInComponentFrame('Suspense'); + + case SuspenseListComponent: + return describeBuiltInComponentFrame('SuspenseList'); + + case FunctionComponent: + case SimpleMemoComponent: + return describeFunctionComponentFrame(fiber.type); + + case ForwardRef: + return describeFunctionComponentFrame(fiber.type.render); + + case ClassComponent: + return describeClassComponentFrame(fiber.type); + + default: + return ''; } } -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 using it here.', typeName(value)); - - return testStringCoercion(value); // throw (to help callers find troubleshooting comments) - } - } -} - -function setCurrentUpdatePriority(newPriority, // Closure will consistently not inline this function when it has arity 1 -// however when it has arity 2 even if the second arg is omitted at every -// callsite it seems to inline it even when the internal length of the function -// is much longer. I hope this is consistent enough to rely on across builds -IntentionallyUnusedArgument) { - Internals.p - /* currentUpdatePriority */ - = newPriority; -} -function getCurrentUpdatePriority() { - return Internals.p; - /* currentUpdatePriority */ -} -function resolveUpdatePriority() { - var updatePriority = Internals.p; - /* currentUpdatePriority */ - - if (updatePriority !== NoEventPriority) { - return updatePriority; - } - - var currentEvent = window.event; - - if (currentEvent === undefined) { - return DefaultEventPriority; - } - - return getEventPriority(currentEvent.type); -} -function runWithPriority(priority, fn) { - var previousPriority = getCurrentUpdatePriority(); +function getStackByFiberInDevAndProd(workInProgress) { try { - setCurrentUpdatePriority(priority); - return fn(); - } finally { - setCurrentUpdatePriority(previousPriority); - } -} - -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); + var info = ''; + var node = workInProgress; - 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]; + do { + info += describeFiber(node); - 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. + if (true) { + // Add any Server Component stack frames in reverse order. + var debugInfo = node._debugInfo; + if (debugInfo) { + for (var i = debugInfo.length - 1; i >= 0; i--) { + var entry = debugInfo[i]; - 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. + if (typeof entry.name === 'string') { + info += describeDebugInfoFrame(entry.name, entry.env); + } + } } - } + } // $FlowFixMe[incompatible-type] we bail out when we get a null - return targetInst; - } - targetNode = parentNode; - parentNode = targetNode.parentNode; - } + node = node.return; + } while (node); - return null; + return info; + } catch (x) { + return '\nError generating stack: ' + x.message + '\n' + x.stack; + } } -/** - * Given a DOM node, return the ReactDOMComponent or ReactDOMTextComponent - * instance, or null if the node was not rendered by this React. - */ -function getInstanceFromNode$1(node) { - var inst = node[internalInstanceKey] || node[internalContainerInstanceKey]; +var current = null; +var isRendering = false; +function getCurrentFiberOwnerNameInDevOrNull() { + { + if (current === null) { + return null; + } - if (inst) { - var tag = inst.tag; + var owner = current._debugOwner; - if (tag === HostComponent || tag === HostText || tag === SuspenseComponent || tag === HostHoistable || tag === HostSingleton || tag === HostRoot) { - return inst; - } else { - return null; + if (owner != null) { + return getComponentNameFromOwner(owner); } } 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. +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. - throw new Error('getNodeFromInstance: Invalid argument.'); -} -function getFiberCurrentPropsFromNode(node) { - return node[internalPropsKey] || null; -} -function updateFiberProps(node, props) { - node[internalPropsKey] = props; + return getStackByFiberInDevAndProd(current); + } } -function getEventListenerSet(node) { - var elementListenerSet = node[internalEventHandlersKey]; - if (elementListenerSet === undefined) { - elementListenerSet = node[internalEventHandlersKey] = new Set(); +function resetCurrentFiber() { + { + ReactSharedInternals.getCurrentStack = null; + current = null; + isRendering = false; } - - return elementListenerSet; } -function getFiberFromScopeInstance(scope) { +function setCurrentFiber(fiber) { { - return scope[internalInstanceKey] || null; + ReactSharedInternals.getCurrentStack = fiber === null ? null : getCurrentFiberStackInDev; + current = fiber; + isRendering = false; } } -function setEventHandlerListeners(scope, listeners) { - scope[internalEventHandlerListenersKey] = listeners; +function getCurrentFiber() { + { + return current; + } } -function getEventHandlerListeners(scope) { - return scope[internalEventHandlerListenersKey] || null; +function setIsRendering(rendering) { + { + isRendering = rendering; + } } -function addEventHandleToTarget(target, eventHandle) { - var eventHandles = target[internalEventHandlesSetKey]; - if (eventHandles === undefined) { - eventHandles = target[internalEventHandlesSetKey] = new Set(); - } +// around this limitation, we use an opaque type that can only be obtained by +// passing the value through getToStringValue first. - eventHandles.add(eventHandle); +function toString(value) { + // The coercion safety check is performed in getToStringValue(). + // eslint-disable-next-line react-internal/safe-string-coercion + return '' + value; } -function doesTargetHaveEventHandle(target, eventHandle) { - var eventHandles = target[internalEventHandlesSetKey]; +function getToStringValue(value) { + switch (typeof value) { + case 'bigint': + case 'boolean': + case 'number': + case 'string': + case 'undefined': + return value; - if (eventHandles === undefined) { - return false; - } + case 'object': + { + checkFormFieldValueStringCoercion(value); + } - return eventHandles.has(eventHandle); -} -function getResourcesFromRoot(root) { - var resources = root[internalRootNodeResourcesKey]; + return value; - if (!resources) { - resources = root[internalRootNodeResourcesKey] = { - hoistableStyles: new Map(), - hoistableScripts: new Map() - }; + default: + // function, symbol are assigned as empty strings + return ''; } - - return resources; -} -function isMarkedHoistable(node) { - return !!node[internalHoistableMarker]; -} -function markNodeAsHoistable(node) { - node[internalHoistableMarker] = true; } -function isOwnedInstance(node) { - return !!(node[internalHoistableMarker] || node[internalInstanceKey]); + +function isCheckable(elem) { + var type = elem.type; + var nodeName = elem.nodeName; + return nodeName && nodeName.toLowerCase() === 'input' && (type === 'checkbox' || type === 'radio'); } -var allNativeEvents = new Set(); +function getTracker(node) { + return node._valueTracker; +} -{ - allNativeEvents.add('beforeblur'); - allNativeEvents.add('afterblur'); +function detachTracker(node) { + node._valueTracker = null; } -/** - * Mapping from registration name to event name - */ +function getValueFromNode(node) { + var value = ''; -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} - */ + if (!node) { + return value; + } -var possibleRegistrationNames = {} ; // Trust the developer to only use possibleRegistrationNames in true + if (isCheckable(node)) { + value = node.checked ? 'true' : 'false'; + } else { + value = node.value; + } -function registerTwoPhaseEvent(registrationName, dependencies) { - registerDirectEvent(registrationName, dependencies); - registerDirectEvent(registrationName + 'Capture', dependencies); + return value; } -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; +function trackValueOnNode(node) { + var valueField = isCheckable(node) ? 'checked' : 'value'; + var descriptor = Object.getOwnPropertyDescriptor(node.constructor.prototype, valueField); { - var lowerCasedName = registrationName.toLowerCase(); - possibleRegistrationNames[lowerCasedName] = registrationName; - - if (registrationName === 'onDoubleClick') { - possibleRegistrationNames.ondblclick = registrationName; - } + checkFormFieldValueStringCoercion(node[valueField]); } - for (var i = 0; i < dependencies.length; i++) { - allNativeEvents.add(dependencies[i]); - } -} + 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) -var canUseDOM = !!(typeof window !== 'undefined' && typeof window.document !== 'undefined' && typeof window.document.createElement !== 'undefined'); + if (node.hasOwnProperty(valueField) || typeof descriptor === 'undefined' || typeof descriptor.get !== 'function' || typeof descriptor.set !== 'function') { + return; + } -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)) { - if (tagName === 'select') { - error('You provided a `value` prop to a form field without an ' + '`onChange` handler. This will render a read-only field. If ' + 'the field should be mutable use `defaultValue`. Otherwise, set `onChange`.'); - } else { - 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`.'); + 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); } - } - 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`.'); + 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 -/* eslint-disable max-len */ + Object.defineProperty(node, valueField, { + enumerable: descriptor.enumerable + }); + var tracker = { + getValue: function () { + return currentValue; + }, + setValue: function (value) { + { + checkFormFieldValueStringCoercion(value); + } -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 */ + currentValue = '' + value; + }, + stopTracking: function () { + detachTracker(node); + delete node[valueField]; + } + }; + return tracker; +} -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; +function track(node) { + if (getTracker(node)) { + return; } - if (hasOwnProperty.call(illegalAttributeNameCache, attributeName)) { + node._valueTracker = trackValueOnNode(node); +} +function updateValueIfChanged(node) { + if (!node) { return false; } - if (VALID_ATTRIBUTE_NAME_REGEX.test(attributeName)) { - validatedAttributeNameCache[attributeName] = true; + var tracker = getTracker(node); // if there is no tracker at this point it's unlikely + // that trying again will succeed + + if (!tracker) { return true; } - illegalAttributeNameCache[attributeName] = true; + var lastValue = tracker.getValue(); + var nextValue = getValueFromNode(node); - { - error('Invalid attribute name: `%s`', attributeName); + if (nextValue !== lastValue) { + tracker.setValue(nextValue); + return true; } 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 getActiveElement(doc) { + doc = doc || (typeof document !== 'undefined' ? document : undefined); -function getValueForAttribute(node, name, expected) { - { - if (!isAttributeNameSafe(name)) { - return; - } + if (typeof doc === 'undefined') { + return null; + } - if (!node.hasAttribute(name)) { - // shouldRemoveAttribute - switch (typeof expected) { - case 'function': - case 'symbol': - // eslint-disable-line - return expected; + try { + return doc.activeElement || doc.body; + } catch (e) { + return doc.body; + } +} - case 'boolean': - { - var prefix = name.toLowerCase().slice(0, 5); +// 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) + ' '; + }); +} - if (prefix !== 'data-' && prefix !== 'aria-') { - return expected; - } - } - } - - return expected === undefined ? undefined : null; - } +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 + */ - var value = node.getAttribute(name); +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://react.dev/link/controlled-components', getCurrentFiberOwnerNameInDevOrNull() || 'A component', props.type); - { - checkAttributeStringCoercion(expected, name); + didWarnCheckedDefaultChecked = true; } - if (value === '' + expected) { - return expected; - } + 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://react.dev/link/controlled-components', getCurrentFiberOwnerNameInDevOrNull() || 'A component', props.type); - return value; + didWarnValueDefaultValue$1 = true; + } } } -function getValueForAttributeOnCustomComponent(node, name, expected) { - { - if (!isAttributeNameSafe(name)) { - return; - } +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. - 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; + node.name = ''; - case 'function': - return expected; + if (type != null && typeof type !== 'function' && typeof type !== 'symbol' && typeof type !== 'boolean') { + { + checkAttributeStringCoercion(type, 'type'); + } - case 'boolean': - if (expected === false) { - return expected; - } + 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)); } - - return expected === undefined ? undefined : null; + } 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'); + } - var value = node.getAttribute(name); + { + // 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'); + } + } - if (value === '' && expected === true) { - return true; + { + // 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) { + // Important to set this even if it's not a change in order to update input + // value tracking with radio buttons + // TODO: Should really update input value tracking for the whole radio + // button group in an effect or something (similar to #27024) + node.checked = checked && typeof checked !== 'function' && typeof checked !== 'symbol'; + } + if (name != null && typeof name !== 'function' && typeof name !== 'symbol' && typeof name !== 'boolean') { { - checkAttributeStringCoercion(expected, name); + checkAttributeStringCoercion(name, 'name'); } - if (value === '' + expected) { - return expected; + 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'); } - return value; + node.type = type; } -} -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); + + 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; } - 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); + 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 (prefix !== 'data-' && prefix !== 'aria-') { - node.removeAttribute(name); - return; - } + 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; } + } } { - checkAttributeStringCoercion(value, name); + // 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. - node.setAttribute(name, enableTrustedTypesIntegration ? value : '' + 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; - } + 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; + + if (isHydrating) { + // Detach .checked from .defaultChecked but leave user input alone + node.checked = node.checked; + } else { + node.checked = !!initialChecked; } { - checkAttributeStringCoercion(value, name); - } + // 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. - node.setAttribute(name, enableTrustedTypesIntegration ? value : '' + 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; - } - } + if (name != null && typeof name !== 'function' && typeof name !== 'symbol' && typeof name !== 'boolean') { + { + checkAttributeStringCoercion(name, 'name'); + } - { - checkAttributeStringCoercion(value, name); + node.name = name; } - - node.setAttributeNS(namespace, name, enableTrustedTypesIntegration ? value : '' + 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; +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 (typeof prevValue === 'function') { - node.removeEventListener(eventName, prevValue, useCapture); - } + if (props.type === 'radio' && name != null) { + var queryRoot = rootNode; - 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. + 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. - node.addEventListener(eventName, value, useCapture); - return; + { + checkAttributeStringCoercion(name, 'name'); } - } - if (name in node) { - node[name] = value; - return; - } + var group = queryRoot.querySelectorAll('input[name="' + escapeSelectorAttributeValueInsideDoubleQuotes('' + name) + '"][type="radio"]'); - if (value === true) { - node.setAttribute(name, ''); - return; - } // From here, it's the same as any attribute + 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. - setValueForAttribute(node, name, value); -} -var prefix; -function describeBuiltInComponentFrame(name) { - { - 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] || ''; + 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; } - } // We use the prefix to ensure our stacks line up with native stack frames. + 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 - return '\n' + prefix + name; +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); + } } } -function describeDebugInfoFrame(name, env) { - return describeBuiltInComponentFrame(name + (env ? ' (' + env + ')' : '')); -} -var reentry = false; -var componentFrameCache; -{ - var PossiblyWeakMap$2 = typeof WeakMap === 'function' ? WeakMap : Map; - componentFrameCache = new PossiblyWeakMap$2(); -} +var didWarnSelectedSetOnOption = false; +var didWarnInvalidChild = false; +var didWarnInvalidInnerHTML = false; /** - * Leverages native browser/VM stack frames to get proper details (e.g. - * filename, line + col number) for a single component in a component stack. We - * do this by: - * (1) throwing and catching an error in the function - this will be our - * control error. - * (2) calling the component which will eventually throw an error that we'll - * catch - this will be our sample error. - * (3) diffing the control and sample error stacks to find the stack frame - * which represents our component. + * Implements an