From 0602001f3a001f2f01d1fbe21f08eba8baeeb3aa Mon Sep 17 00:00:00 2001 From: sebmarkbage Date: Tue, 26 Mar 2024 23:09:12 +0000 Subject: [PATCH] Move Hydration Warnings from the DOM Config into the Fiber reconciliation (#28476) Stacked on #28458. This doesn't actually really change the messages yet, it's just a refactor. Hydration warnings can be presented either as HTML or React JSX format. If presented as HTML it makes more sense to make that a DOM specific concept, however, I think it's actually better to present it in terms of React JSX. Most of the time the errors aren't going to be something messing with them at the HTML/HTTP layer. It's because the JS code does something different. Most of the time you're working in just React. People don't necessarily even know what the HTML form of it looks like. So this takes the approach that the warnings are presented in React JSX in their rich object form. Therefore, I'm moving the approach to yield diff data to the reconciler but it's the reconciler that's actually printing all the warnings. DiffTrain build for [4b8dfd6215bf855402ae1a94cb0ae4f467afca9a](https://github.com/facebook/react/commit/4b8dfd6215bf855402ae1a94cb0ae4f467afca9a) --- compiled/facebook-www/REVISION | 2 +- compiled/facebook-www/ReactART-dev.classic.js | 35 +- compiled/facebook-www/ReactART-dev.modern.js | 35 +- .../facebook-www/ReactART-prod.classic.js | 37 +- compiled/facebook-www/ReactART-prod.modern.js | 37 +- compiled/facebook-www/ReactDOM-dev.classic.js | 1011 ++++++++++------- compiled/facebook-www/ReactDOM-dev.modern.js | 1011 ++++++++++------- .../facebook-www/ReactDOM-prod.classic.js | 256 ++--- compiled/facebook-www/ReactDOM-prod.modern.js | 256 ++--- .../ReactDOM-profiling.classic.js | 242 ++-- .../facebook-www/ReactDOM-profiling.modern.js | 242 ++-- .../ReactDOMTesting-dev.classic.js | 1011 ++++++++++------- .../ReactDOMTesting-dev.modern.js | 1011 ++++++++++------- .../ReactDOMTesting-prod.classic.js | 256 ++--- .../ReactDOMTesting-prod.modern.js | 256 ++--- .../ReactTestRenderer-dev.classic.js | 35 +- .../ReactTestRenderer-dev.modern.js | 35 +- .../__test_utils__/ReactAllWarnings.js | 9 +- 18 files changed, 3146 insertions(+), 2631 deletions(-) diff --git a/compiled/facebook-www/REVISION b/compiled/facebook-www/REVISION index 5db8c967ddabb..d0631851c63f1 100644 --- a/compiled/facebook-www/REVISION +++ b/compiled/facebook-www/REVISION @@ -1 +1 @@ -bb66aa3cef4e42aee790200d03cf7a82659da121 +4b8dfd6215bf855402ae1a94cb0ae4f467afca9a diff --git a/compiled/facebook-www/ReactART-dev.classic.js b/compiled/facebook-www/ReactART-dev.classic.js index 7d194886a91e3..ea6315e92193d 100644 --- a/compiled/facebook-www/ReactART-dev.classic.js +++ b/compiled/facebook-www/ReactART-dev.classic.js @@ -66,7 +66,7 @@ if (__DEV__) { return self; } - var ReactVersion = "19.0.0-www-classic-ae7c23fd"; + var ReactVersion = "19.0.0-www-classic-9130e73d"; var LegacyRoot = 0; var ConcurrentRoot = 1; @@ -2617,13 +2617,14 @@ if (__DEV__) { "Please file an issue." ); } // Hydration (when unsupported) + + var supportsHydration = false; var isSuspenseInstancePending = shim$2; var isSuspenseInstanceFallback = shim$2; var getSuspenseInstanceFallbackErrorDetails = shim$2; var registerSuspenseInstanceRetry = shim$2; var clearSuspenseBoundary = shim$2; var clearSuspenseBoundaryFromContainer = shim$2; - var errorHydratingContainer = shim$2; // Renderers that don't support React Scopes // can re-export everything from this module. @@ -3593,14 +3594,6 @@ if (__DEV__) { } } - // This is imported by the event replaying implementation in React DOM. It's - // in a separate file to break a circular dependency between the renderer and - // the reconciler. - function isRootDehydrated(root) { - var currentState = root.current.memoizedState; - return currentState.isDehydrated; - } - var contextStackCursor = createCursor(null); var contextFiberStackCursor = createCursor(null); var rootInstanceStackCursor = createCursor(null); // Represents the nearest host transition provider (in React DOM, a
) @@ -25730,27 +25723,7 @@ if (__DEV__) { // back to client side render. // Before rendering again, save the errors from the previous attempt. var errorsFromFirstAttempt = workInProgressRootConcurrentErrors; - var wasRootDehydrated = isRootDehydrated(root); - - if (wasRootDehydrated) { - // The shell failed to hydrate. Set a flag to force a client rendering - // during the next attempt. To do this, we call prepareFreshStack now - // to create the root work-in-progress fiber. This is a bit weird in terms - // of factoring, because it relies on renderRootSync not calling - // prepareFreshStack again in the call below, which happens because the - // root and lanes haven't changed. - // - // TODO: I think what we should do is set ForceClientRender inside - // throwException, like we do for nested Suspense boundaries. The reason - // it's here instead is so we can switch to the synchronous work loop, too. - // Something to consider for a future refactor. - var rootWorkInProgress = prepareFreshStack(root, errorRetryLanes); - rootWorkInProgress.flags |= ForceClientRender; - - { - errorHydratingContainer(); - } - } + var wasRootDehydrated = supportsHydration; var exitStatus = renderRootSync(root, errorRetryLanes); diff --git a/compiled/facebook-www/ReactART-dev.modern.js b/compiled/facebook-www/ReactART-dev.modern.js index e8f0c1aa9f0e6..2d5527c82f67e 100644 --- a/compiled/facebook-www/ReactART-dev.modern.js +++ b/compiled/facebook-www/ReactART-dev.modern.js @@ -66,7 +66,7 @@ if (__DEV__) { return self; } - var ReactVersion = "19.0.0-www-modern-c5863941"; + var ReactVersion = "19.0.0-www-modern-937bdc18"; var LegacyRoot = 0; var ConcurrentRoot = 1; @@ -2614,13 +2614,14 @@ if (__DEV__) { "Please file an issue." ); } // Hydration (when unsupported) + + var supportsHydration = false; var isSuspenseInstancePending = shim$2; var isSuspenseInstanceFallback = shim$2; var getSuspenseInstanceFallbackErrorDetails = shim$2; var registerSuspenseInstanceRetry = shim$2; var clearSuspenseBoundary = shim$2; var clearSuspenseBoundaryFromContainer = shim$2; - var errorHydratingContainer = shim$2; // Renderers that don't support React Scopes // can re-export everything from this module. @@ -3358,14 +3359,6 @@ if (__DEV__) { } } - // This is imported by the event replaying implementation in React DOM. It's - // in a separate file to break a circular dependency between the renderer and - // the reconciler. - function isRootDehydrated(root) { - var currentState = root.current.memoizedState; - return currentState.isDehydrated; - } - var contextStackCursor = createCursor(null); var contextFiberStackCursor = createCursor(null); var rootInstanceStackCursor = createCursor(null); // Represents the nearest host transition provider (in React DOM, a ) @@ -25389,27 +25382,7 @@ if (__DEV__) { // back to client side render. // Before rendering again, save the errors from the previous attempt. var errorsFromFirstAttempt = workInProgressRootConcurrentErrors; - var wasRootDehydrated = isRootDehydrated(root); - - if (wasRootDehydrated) { - // The shell failed to hydrate. Set a flag to force a client rendering - // during the next attempt. To do this, we call prepareFreshStack now - // to create the root work-in-progress fiber. This is a bit weird in terms - // of factoring, because it relies on renderRootSync not calling - // prepareFreshStack again in the call below, which happens because the - // root and lanes haven't changed. - // - // TODO: I think what we should do is set ForceClientRender inside - // throwException, like we do for nested Suspense boundaries. The reason - // it's here instead is so we can switch to the synchronous work loop, too. - // Something to consider for a future refactor. - var rootWorkInProgress = prepareFreshStack(root, errorRetryLanes); - rootWorkInProgress.flags |= ForceClientRender; - - { - errorHydratingContainer(); - } - } + var wasRootDehydrated = supportsHydration; var exitStatus = renderRootSync(root, errorRetryLanes); diff --git a/compiled/facebook-www/ReactART-prod.classic.js b/compiled/facebook-www/ReactART-prod.classic.js index ddea119b8e9a4..c3946ddeb3655 100644 --- a/compiled/facebook-www/ReactART-prod.classic.js +++ b/compiled/facebook-www/ReactART-prod.classic.js @@ -9246,13 +9246,10 @@ function recoverFromConcurrentError( originallyAttemptedLanes, errorRetryLanes ) { - var errorsFromFirstAttempt = workInProgressRootConcurrentErrors, - JSCompiler_inline_result; - (JSCompiler_inline_result = root.current.memoizedState.isDehydrated) && - (prepareFreshStack(root, errorRetryLanes).flags |= 256); + var errorsFromFirstAttempt = workInProgressRootConcurrentErrors; errorRetryLanes = renderRootSync(root, errorRetryLanes); if (2 !== errorRetryLanes) { - if (workInProgressRootDidAttachPingListener && !JSCompiler_inline_result) + if (workInProgressRootDidAttachPingListener) return ( (root.errorRecoveryDisabledLanes |= originallyAttemptedLanes), (workInProgressRootInterleavedUpdatedLanes |= originallyAttemptedLanes), @@ -10609,19 +10606,19 @@ var slice = Array.prototype.slice, }; return Text; })(React.Component), - devToolsConfig$jscomp$inline_1132 = { + devToolsConfig$jscomp$inline_1128 = { findFiberByHostInstance: function () { return null; }, bundleType: 0, - version: "19.0.0-www-classic-3c2c0375", + version: "19.0.0-www-classic-63a4b87a", rendererPackageName: "react-art" }; -var internals$jscomp$inline_1337 = { - bundleType: devToolsConfig$jscomp$inline_1132.bundleType, - version: devToolsConfig$jscomp$inline_1132.version, - rendererPackageName: devToolsConfig$jscomp$inline_1132.rendererPackageName, - rendererConfig: devToolsConfig$jscomp$inline_1132.rendererConfig, +var internals$jscomp$inline_1333 = { + bundleType: devToolsConfig$jscomp$inline_1128.bundleType, + version: devToolsConfig$jscomp$inline_1128.version, + rendererPackageName: devToolsConfig$jscomp$inline_1128.rendererPackageName, + rendererConfig: devToolsConfig$jscomp$inline_1128.rendererConfig, overrideHookState: null, overrideHookStateDeletePath: null, overrideHookStateRenamePath: null, @@ -10638,26 +10635,26 @@ var internals$jscomp$inline_1337 = { return null === fiber ? null : fiber.stateNode; }, findFiberByHostInstance: - devToolsConfig$jscomp$inline_1132.findFiberByHostInstance || + devToolsConfig$jscomp$inline_1128.findFiberByHostInstance || emptyFindFiberByHostInstance, findHostInstancesForRefresh: null, scheduleRefresh: null, scheduleRoot: null, setRefreshHandler: null, getCurrentFiber: null, - reconcilerVersion: "19.0.0-www-classic-3c2c0375" + reconcilerVersion: "19.0.0-www-classic-63a4b87a" }; if ("undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__) { - var hook$jscomp$inline_1338 = __REACT_DEVTOOLS_GLOBAL_HOOK__; + var hook$jscomp$inline_1334 = __REACT_DEVTOOLS_GLOBAL_HOOK__; if ( - !hook$jscomp$inline_1338.isDisabled && - hook$jscomp$inline_1338.supportsFiber + !hook$jscomp$inline_1334.isDisabled && + hook$jscomp$inline_1334.supportsFiber ) try { - (rendererID = hook$jscomp$inline_1338.inject( - internals$jscomp$inline_1337 + (rendererID = hook$jscomp$inline_1334.inject( + internals$jscomp$inline_1333 )), - (injectedHook = hook$jscomp$inline_1338); + (injectedHook = hook$jscomp$inline_1334); } catch (err) {} } var Path = Mode$1.Path; diff --git a/compiled/facebook-www/ReactART-prod.modern.js b/compiled/facebook-www/ReactART-prod.modern.js index 8dec061f858d5..fc77d3146ab79 100644 --- a/compiled/facebook-www/ReactART-prod.modern.js +++ b/compiled/facebook-www/ReactART-prod.modern.js @@ -8945,13 +8945,10 @@ function recoverFromConcurrentError( originallyAttemptedLanes, errorRetryLanes ) { - var errorsFromFirstAttempt = workInProgressRootConcurrentErrors, - JSCompiler_inline_result; - (JSCompiler_inline_result = root.current.memoizedState.isDehydrated) && - (prepareFreshStack(root, errorRetryLanes).flags |= 256); + var errorsFromFirstAttempt = workInProgressRootConcurrentErrors; errorRetryLanes = renderRootSync(root, errorRetryLanes); if (2 !== errorRetryLanes) { - if (workInProgressRootDidAttachPingListener && !JSCompiler_inline_result) + if (workInProgressRootDidAttachPingListener) return ( (root.errorRecoveryDisabledLanes |= originallyAttemptedLanes), (workInProgressRootInterleavedUpdatedLanes |= originallyAttemptedLanes), @@ -10264,19 +10261,19 @@ var slice = Array.prototype.slice, }; return Text; })(React.Component), - devToolsConfig$jscomp$inline_1112 = { + devToolsConfig$jscomp$inline_1108 = { findFiberByHostInstance: function () { return null; }, bundleType: 0, - version: "19.0.0-www-modern-f6a224b8", + version: "19.0.0-www-modern-32937d9c", rendererPackageName: "react-art" }; -var internals$jscomp$inline_1317 = { - bundleType: devToolsConfig$jscomp$inline_1112.bundleType, - version: devToolsConfig$jscomp$inline_1112.version, - rendererPackageName: devToolsConfig$jscomp$inline_1112.rendererPackageName, - rendererConfig: devToolsConfig$jscomp$inline_1112.rendererConfig, +var internals$jscomp$inline_1313 = { + bundleType: devToolsConfig$jscomp$inline_1108.bundleType, + version: devToolsConfig$jscomp$inline_1108.version, + rendererPackageName: devToolsConfig$jscomp$inline_1108.rendererPackageName, + rendererConfig: devToolsConfig$jscomp$inline_1108.rendererConfig, overrideHookState: null, overrideHookStateDeletePath: null, overrideHookStateRenamePath: null, @@ -10293,26 +10290,26 @@ var internals$jscomp$inline_1317 = { return null === fiber ? null : fiber.stateNode; }, findFiberByHostInstance: - devToolsConfig$jscomp$inline_1112.findFiberByHostInstance || + devToolsConfig$jscomp$inline_1108.findFiberByHostInstance || emptyFindFiberByHostInstance, findHostInstancesForRefresh: null, scheduleRefresh: null, scheduleRoot: null, setRefreshHandler: null, getCurrentFiber: null, - reconcilerVersion: "19.0.0-www-modern-f6a224b8" + reconcilerVersion: "19.0.0-www-modern-32937d9c" }; if ("undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__) { - var hook$jscomp$inline_1318 = __REACT_DEVTOOLS_GLOBAL_HOOK__; + var hook$jscomp$inline_1314 = __REACT_DEVTOOLS_GLOBAL_HOOK__; if ( - !hook$jscomp$inline_1318.isDisabled && - hook$jscomp$inline_1318.supportsFiber + !hook$jscomp$inline_1314.isDisabled && + hook$jscomp$inline_1314.supportsFiber ) try { - (rendererID = hook$jscomp$inline_1318.inject( - internals$jscomp$inline_1317 + (rendererID = hook$jscomp$inline_1314.inject( + internals$jscomp$inline_1313 )), - (injectedHook = hook$jscomp$inline_1318); + (injectedHook = hook$jscomp$inline_1314); } catch (err) {} } var Path = Mode$1.Path; diff --git a/compiled/facebook-www/ReactDOM-dev.classic.js b/compiled/facebook-www/ReactDOM-dev.classic.js index 70bdf5cf16684..7a79d931c1730 100644 --- a/compiled/facebook-www/ReactDOM-dev.classic.js +++ b/compiled/facebook-www/ReactDOM-dev.classic.js @@ -8207,35 +8207,104 @@ if (__DEV__) { return true; } + function warnForDeletedHydratableInstance(parentType, child) { + { + var description = describeHydratableInstanceForDevWarnings(child); + + if (typeof description === "string") { + error( + 'Did not expect server HTML to contain the text node "%s" in <%s>.', + description, + parentType + ); + } else { + error( + "Did not expect server HTML to contain a <%s> in <%s>.", + description.type, + parentType + ); + } + } + } + + function warnForInsertedHydratedElement(parentType, tag) { + { + error( + "Expected server HTML to contain a matching <%s> in <%s>.", + tag, + parentType + ); + } + } + + function warnForInsertedHydratedText(parentType, text) { + { + error( + 'Expected server HTML to contain a matching text node for "%s" in <%s>.', + text, + parentType + ); + } + } + + function warnForInsertedHydratedSuspense(parentType) { + { + error( + "Expected server HTML to contain a matching <%s> in <%s>.", + "Suspense", + parentType + ); + } + } + + function errorHydratingContainer(parentContainer) { + { + // TODO: This gets logged by onRecoverableError, too, so we should be + // able to remove it. + error( + "An error occurred during hydration. The server HTML was replaced with client content." + ); + } + } + function warnUnhydratedInstance(returnFiber, instance) { { + if (didWarnInvalidHydration) { + return; + } + + didWarnInvalidHydration = true; + switch (returnFiber.tag) { case HostRoot: { - didNotHydrateInstanceWithinContainer( - returnFiber.stateNode.containerInfo, - instance - ); + var description = + describeHydratableInstanceForDevWarnings(instance); + + if (typeof description === "string") { + error( + 'Did not expect server HTML to contain the text node "%s" in the root.', + description + ); + } else { + error( + "Did not expect server HTML to contain a <%s> in the root.", + description.type + ); + } + break; } case HostSingleton: case HostComponent: { - didNotHydrateInstance( - returnFiber.type, - returnFiber.memoizedProps, - returnFiber.stateNode, - instance - ); + warnForDeletedHydratableInstance(returnFiber.type, instance); break; } case SuspenseComponent: { var suspenseState = returnFiber.memoizedState; if (suspenseState.dehydrated !== null) - didNotHydrateInstanceWithinSuspenseInstance( - suspenseState.dehydrated, - instance - ); + warnForDeletedHydratableInstance("Suspense", instance); break; } } @@ -8251,26 +8320,41 @@ if (__DEV__) { return; } + if (didWarnInvalidHydration) { + return; + } + + didWarnInvalidHydration = true; + switch (returnFiber.tag) { case HostRoot: { - var parentContainer = returnFiber.stateNode.containerInfo; - + // const parentContainer = returnFiber.stateNode.containerInfo; switch (fiber.tag) { case HostSingleton: case HostComponent: - var type = fiber.type; - didNotFindHydratableInstanceWithinContainer( - parentContainer, - type + error( + "Expected server HTML to contain a matching <%s> in the root.", + fiber.type ); + break; case HostText: var text = fiber.pendingProps; - didNotFindHydratableTextInstanceWithinContainer( - parentContainer, + + error( + 'Expected server HTML to contain a matching text node for "%s" in the root.', text ); + + break; + + case SuspenseComponent: + error( + "Expected server HTML to contain a matching <%s> in the root.", + "Suspense" + ); + break; } @@ -8279,31 +8363,25 @@ if (__DEV__) { case HostSingleton: case HostComponent: { - var parentType = returnFiber.type; - var parentProps = returnFiber.memoizedProps; - var parentInstance = returnFiber.stateNode; + var parentType = returnFiber.type; // const parentProps = returnFiber.memoizedProps; + // const parentInstance = returnFiber.stateNode; switch (fiber.tag) { case HostSingleton: case HostComponent: { - var _type = fiber.type; - didNotFindHydratableInstance( - parentType, - parentProps, - parentInstance, - _type - ); + var type = fiber.type; + warnForInsertedHydratedElement(parentType, type); break; } case HostText: { var _text = fiber.pendingProps; - didNotFindHydratableTextInstance( - parentType, - parentProps, - parentInstance, - _text - ); + warnForInsertedHydratedText(parentType, _text); + break; + } + + case SuspenseComponent: { + warnForInsertedHydratedSuspense(parentType); break; } } @@ -8312,27 +8390,25 @@ if (__DEV__) { } case SuspenseComponent: { - var suspenseState = returnFiber.memoizedState; - var _parentInstance = suspenseState.dehydrated; - if (_parentInstance !== null) - switch (fiber.tag) { - case HostSingleton: - case HostComponent: - var _type2 = fiber.type; - didNotFindHydratableInstanceWithinSuspenseInstance( - _parentInstance, - _type2 - ); - break; + // const suspenseState: SuspenseState = returnFiber.memoizedState; + // const parentInstance = suspenseState.dehydrated; + switch (fiber.tag) { + case HostSingleton: + case HostComponent: + var _type = fiber.type; + warnForInsertedHydratedElement("Suspense", _type); + break; + + case HostText: + var _text2 = fiber.pendingProps; + warnForInsertedHydratedText("Suspense", _text2); + break; + + case SuspenseComponent: + warnForInsertedHydratedSuspense("Suspense"); + break; + } - case HostText: - var _text2 = fiber.pendingProps; - didNotFindHydratableTextInstanceWithinSuspenseInstance( - _parentInstance, - _text2 - ); - break; - } break; } @@ -8527,66 +8603,152 @@ if (__DEV__) { throwOnHydrationMismatch(); return false; - } + } // Temp + + var didWarnInvalidHydration = false; function prepareToHydrateHostInstance(fiber, hostContext) { var instance = fiber.stateNode; - var shouldWarnIfMismatchDev = !didSuspendOrErrorDEV; - hydrateInstance( + + { + var shouldWarnIfMismatchDev = !didSuspendOrErrorDEV; + + if (shouldWarnIfMismatchDev) { + var differences = diffHydratedPropsForDevWarnings( + instance, + fiber.type, + fiber.memoizedProps, + hostContext + ); + + if (differences !== null) { + if (differences.children != null && !didWarnInvalidHydration) { + didWarnInvalidHydration = true; + var serverValue = differences.children; + var clientValue = fiber.memoizedProps.children; + + error( + 'Text content did not match. Server: "%s" Client: "%s"', + serverValue, + clientValue + ); + } + + for (var propName in differences) { + if (!differences.hasOwnProperty(propName)) { + continue; + } + + if (didWarnInvalidHydration) { + break; + } + + didWarnInvalidHydration = true; + var _serverValue = differences[propName]; + var _clientValue = fiber.memoizedProps[propName]; + + if (propName === "children"); + else if (_clientValue != null) { + error( + "Prop `%s` did not match. Server: %s Client: %s", + propName, + JSON.stringify(_serverValue), + JSON.stringify(_clientValue) + ); + } else { + error("Extra attribute from the server: %s", propName); + } + } + } + } + } + + var didHydrate = hydrateInstance( instance, fiber.type, fiber.memoizedProps, hostContext, - fiber, - shouldWarnIfMismatchDev + fiber ); + + if (!didHydrate) { + throw new Error("Text content does not match server-rendered HTML."); + } } function prepareToHydrateHostTextInstance(fiber) { var textInstance = fiber.stateNode; var textContent = fiber.memoizedProps; var shouldWarnIfMismatchDev = !didSuspendOrErrorDEV; - var textIsDifferent = hydrateTextInstance( - textInstance, - textContent, - fiber - ); + var parentProps = null; // We assume that prepareToHydrateHostTextInstance is called in a context where the + // hydration parent is the parent host component of this host text. - if (textIsDifferent) { - // We assume that prepareToHydrateHostTextInstance is called in a context where the - // hydration parent is the parent host component of this host text. - var returnFiber = hydrationParentFiber; + var returnFiber = hydrationParentFiber; - if (returnFiber !== null) { - switch (returnFiber.tag) { - case HostRoot: { - var parentContainer = returnFiber.stateNode.containerInfo; - didNotMatchHydratedContainerTextInstance( - parentContainer, - textInstance, - textContent, - shouldWarnIfMismatchDev - ); - break; + if (returnFiber !== null) { + switch (returnFiber.tag) { + case HostRoot: { + { + if (shouldWarnIfMismatchDev) { + var difference = diffHydratedTextForDevWarnings( + textInstance, + textContent, + parentProps + ); + + if (difference !== null && !didWarnInvalidHydration) { + didWarnInvalidHydration = true; + + error( + 'Text content did not match. Server: "%s" Client: "%s"', + difference, + textContent + ); + } + } } - case HostSingleton: - case HostComponent: { - var parentType = returnFiber.type; - var parentProps = returnFiber.memoizedProps; - var parentInstance = returnFiber.stateNode; - didNotMatchHydratedTextInstance( - parentType, - parentProps, - parentInstance, - textInstance, - textContent, - shouldWarnIfMismatchDev - ); - break; + break; + } + + case HostSingleton: + case HostComponent: { + parentProps = returnFiber.memoizedProps; + + { + if (shouldWarnIfMismatchDev) { + var _difference = diffHydratedTextForDevWarnings( + textInstance, + textContent, + parentProps + ); + + if (_difference !== null && !didWarnInvalidHydration) { + didWarnInvalidHydration = true; + + error( + 'Text content did not match. Server: "%s" Client: "%s"', + _difference, + textContent + ); + } + } } + + break; } - } + } // TODO: What if it's a SuspenseInstance? + } + + var didHydrate = hydrateTextInstance( + textInstance, + textContent, + fiber, + parentProps + ); + + if (!didHydrate) { + throw new Error("Text content does not match server-rendered HTML."); } } @@ -31289,7 +31451,7 @@ if (__DEV__) { rootWorkInProgress.flags |= ForceClientRender; { - errorHydratingContainer(root.containerInfo); + errorHydratingContainer(); } } @@ -35566,7 +35728,7 @@ if (__DEV__) { return root; } - var ReactVersion = "19.0.0-www-classic-57b2070e"; + var ReactVersion = "19.0.0-www-classic-ab1712f5"; function createPortal$1( children, @@ -40065,7 +40227,6 @@ if (__DEV__) { var didWarnControlledToUncontrolled = false; var didWarnUncontrolledToControlled = false; - var didWarnInvalidHydration = false; var didWarnFormActionType = false; var didWarnFormActionName = false; var didWarnFormActionTarget = false; @@ -40216,12 +40377,13 @@ if (__DEV__) { } } - function warnForPropDifference(propName, serverValue, clientValue) { + function warnForPropDifference( + propName, + serverValue, + clientValue, + serverDifferences + ) { { - if (didWarnInvalidHydration) { - return; - } - if (serverValue === clientValue) { return; } @@ -40235,30 +40397,22 @@ if (__DEV__) { return; } - didWarnInvalidHydration = true; - - error( - "Prop `%s` did not match. Server: %s Client: %s", - propName, - JSON.stringify(normalizedServerValue), - JSON.stringify(normalizedClientValue) - ); + serverDifferences[propName] = serverValue; } } - function warnForExtraAttributes(attributeNames) { + function warnForExtraAttributes( + domElement, + attributeNames, + serverDifferences + ) { { - if (didWarnInvalidHydration) { - return; - } - - didWarnInvalidHydration = true; - var names = []; - attributeNames.forEach(function (name) { - names.push(name); + attributeNames.forEach(function (attributeName) { + serverDifferences[attributeName] = + attributeName === "style" + ? getStylesObjectFromElement(domElement) + : domElement.getAttribute(attributeName); }); - - error("Extra attributes from the server: %s", names); } } @@ -40321,30 +40475,15 @@ if (__DEV__) { .replace(NORMALIZE_NULL_AND_REPLACEMENT_REGEX, ""); } - function checkForUnmatchedText(serverText, clientText, shouldWarnDev) { + function checkForUnmatchedText(serverText, clientText) { var normalizedClientText = normalizeMarkupForTextOrAttribute(clientText); var normalizedServerText = normalizeMarkupForTextOrAttribute(serverText); if (normalizedServerText === normalizedClientText) { - return; + return true; } - if (shouldWarnDev) { - { - if (!didWarnInvalidHydration) { - didWarnInvalidHydration = true; - - error( - 'Text content did not match. Server: "%s" Client: "%s"', - normalizedServerText, - normalizedClientText - ); - } - } - } // In concurrent roots, we throw when there's a text mismatch and revert to - // client rendering, up to the nearest Suspense boundary. - - throw new Error("Text content does not match server-rendered HTML."); + return false; } function noop$2() {} @@ -42108,19 +42247,70 @@ if (__DEV__) { } } - function diffHydratedStyles(domElement, value) { + function getPropsFromElement(domElement) { + var serverDifferences = {}; + var attributes = domElement.attributes; + + for (var i = 0; i < attributes.length; i++) { + var attr = attributes[i]; + serverDifferences[attr.name] = + attr.name.toLowerCase() === "style" + ? getStylesObjectFromElement(domElement) + : attr.value; + } + + return serverDifferences; + } + + function getStylesObjectFromElement(domElement) { + var serverValueInObjectForm = {}; + var style = domElement.style; + + for (var i = 0; i < style.length; i++) { + var styleName = style[i]; // TODO: We should use the original prop value here if it is equivalent. + // TODO: We could use the original client capitalization if the equivalent + // other capitalization exists in the DOM. + + serverValueInObjectForm[styleName] = style.getPropertyValue(styleName); + } + + return serverValueInObjectForm; + } + + function diffHydratedStyles(domElement, value, serverDifferences) { if (value != null && typeof value !== "object") { - throw new Error( - "The `style` prop expects a mapping from style properties to values, " + - "not a string. For example, style={{marginRight: spacing + 'em'}} when " + - "using JSX." - ); + { + error( + "The `style` prop expects a mapping from style properties to values, " + + "not a string. For example, style={{marginRight: spacing + 'em'}} when " + + "using JSX." + ); + } + + return; } if (canDiffStyleForHydrationWarning) { - var expectedStyle = createDangerousStringForStyles(value); + // First we compare the string form and see if it's equivalent. + // This lets us bail out on anything that used to pass in this form. + // It also lets us compare anything that's not parsed by this browser. + var clientValue = createDangerousStringForStyles(value); var serverValue = domElement.getAttribute("style"); - warnForPropDifference("style", serverValue, expectedStyle); + + if (serverValue === clientValue) { + return; + } + + var normalizedClientValue = + normalizeMarkupForTextOrAttribute(clientValue); + var normalizedServerValue = + normalizeMarkupForTextOrAttribute(serverValue); + + if (normalizedServerValue === normalizedClientValue) { + return; + } // Otherwise, we create the object from the DOM for the diff view. + + serverDifferences.style = getStylesObjectFromElement(domElement); } } @@ -42129,7 +42319,8 @@ if (__DEV__) { propKey, attributeName, value, - extraAttributes + extraAttributes, + serverDifferences ) { extraAttributes.delete(attributeName); var serverValue = domElement.getAttribute(attributeName); @@ -42164,7 +42355,7 @@ if (__DEV__) { } } - warnForPropDifference(propKey, serverValue, value); + warnForPropDifference(propKey, serverValue, value, serverDifferences); } function hydrateBooleanAttribute( @@ -42172,7 +42363,8 @@ if (__DEV__) { propKey, attributeName, value, - extraAttributes + extraAttributes, + serverDifferences ) { extraAttributes.delete(attributeName); var serverValue = domElement.getAttribute(attributeName); @@ -42204,7 +42396,7 @@ if (__DEV__) { } } - warnForPropDifference(propKey, serverValue, value); + warnForPropDifference(propKey, serverValue, value, serverDifferences); } function hydrateOverloadedBooleanAttribute( @@ -42212,7 +42404,8 @@ if (__DEV__) { propKey, attributeName, value, - extraAttributes + extraAttributes, + serverDifferences ) { extraAttributes.delete(attributeName); var serverValue = domElement.getAttribute(attributeName); @@ -42257,7 +42450,7 @@ if (__DEV__) { } } - warnForPropDifference(propKey, serverValue, value); + warnForPropDifference(propKey, serverValue, value, serverDifferences); } function hydrateBooleanishAttribute( @@ -42265,7 +42458,8 @@ if (__DEV__) { propKey, attributeName, value, - extraAttributes + extraAttributes, + serverDifferences ) { extraAttributes.delete(attributeName); var serverValue = domElement.getAttribute(attributeName); @@ -42298,7 +42492,7 @@ if (__DEV__) { } } - warnForPropDifference(propKey, serverValue, value); + warnForPropDifference(propKey, serverValue, value, serverDifferences); } function hydrateNumericAttribute( @@ -42306,7 +42500,8 @@ if (__DEV__) { propKey, attributeName, value, - extraAttributes + extraAttributes, + serverDifferences ) { extraAttributes.delete(attributeName); var serverValue = domElement.getAttribute(attributeName); @@ -42352,7 +42547,7 @@ if (__DEV__) { } } - warnForPropDifference(propKey, serverValue, value); + warnForPropDifference(propKey, serverValue, value, serverDifferences); } function hydratePositiveNumericAttribute( @@ -42360,7 +42555,8 @@ if (__DEV__) { propKey, attributeName, value, - extraAttributes + extraAttributes, + serverDifferences ) { extraAttributes.delete(attributeName); var serverValue = domElement.getAttribute(attributeName); @@ -42406,7 +42602,7 @@ if (__DEV__) { } } - warnForPropDifference(propKey, serverValue, value); + warnForPropDifference(propKey, serverValue, value, serverDifferences); } function hydrateSanitizedAttribute( @@ -42414,7 +42610,8 @@ if (__DEV__) { propKey, attributeName, value, - extraAttributes + extraAttributes, + serverDifferences ) { extraAttributes.delete(attributeName); var serverValue = domElement.getAttribute(attributeName); @@ -42451,7 +42648,7 @@ if (__DEV__) { } } - warnForPropDifference(propKey, serverValue, value); + warnForPropDifference(propKey, serverValue, value, serverDifferences); } function diffHydratedCustomComponent( @@ -42459,7 +42656,8 @@ if (__DEV__) { tag, props, hostContext, - extraAttributes + extraAttributes, + serverDifferences ) { for (var propKey in props) { if (!props.hasOwnProperty(propKey)) { @@ -42486,7 +42684,19 @@ if (__DEV__) { } // Validate that the properties correspond to their expected values. switch (propKey) { - case "children": // Checked above already + case "children": { + if (typeof value === "string" || typeof value === "number") { + warnForPropDifference( + "children", + domElement.textContent, + value, + serverDifferences + ); + } + + continue; + } + // Checked above already case "suppressContentEditableWarning": case "suppressHydrationWarning": @@ -42503,14 +42713,19 @@ if (__DEV__) { if (nextHtml != null) { var expectedHTML = normalizeHTML(domElement, nextHtml); - warnForPropDifference(propKey, serverHTML, expectedHTML); + warnForPropDifference( + propKey, + serverHTML, + expectedHTML, + serverDifferences + ); } continue; case "style": extraAttributes.delete(propKey); - diffHydratedStyles(domElement, value); + diffHydratedStyles(domElement, value, serverDifferences); continue; case "offsetParent": @@ -42543,7 +42758,12 @@ if (__DEV__) { "class", value ); - warnForPropDifference("className", serverValue, value); + warnForPropDifference( + "className", + serverValue, + value, + serverDifferences + ); continue; } @@ -42570,7 +42790,12 @@ if (__DEV__) { value ); - warnForPropDifference(propKey, _serverValue, value); + warnForPropDifference( + propKey, + _serverValue, + value, + serverDifferences + ); } } } @@ -42586,7 +42811,8 @@ if (__DEV__) { tag, props, hostContext, - extraAttributes + extraAttributes, + serverDifferences ) { for (var propKey in props) { if (!props.hasOwnProperty(propKey)) { @@ -42613,7 +42839,19 @@ if (__DEV__) { } // Validate that the properties correspond to their expected values. switch (propKey) { - case "children": // Checked above already + case "children": { + if (typeof value === "string" || typeof value === "number") { + warnForPropDifference( + "children", + domElement.textContent, + value, + serverDifferences + ); + } + + continue; + } + // Checked above already case "suppressContentEditableWarning": case "suppressHydrationWarning": @@ -42635,7 +42873,12 @@ if (__DEV__) { if (nextHtml != null) { var expectedHTML = normalizeHTML(domElement, nextHtml); - warnForPropDifference(propKey, serverHTML, expectedHTML); + + if (serverHTML !== expectedHTML) { + serverDifferences[propKey] = { + __html: serverHTML + }; + } } continue; @@ -42646,7 +42889,8 @@ if (__DEV__) { propKey, "class", value, - extraAttributes + extraAttributes, + serverDifferences ); continue; @@ -42656,33 +42900,49 @@ if (__DEV__) { propKey, "tabindex", value, - extraAttributes + extraAttributes, + serverDifferences ); continue; case "style": extraAttributes.delete(propKey); - diffHydratedStyles(domElement, value); + diffHydratedStyles(domElement, value, serverDifferences); continue; case "multiple": { extraAttributes.delete(propKey); var serverValue = domElement.multiple; - warnForPropDifference(propKey, serverValue, value); + warnForPropDifference( + propKey, + serverValue, + value, + serverDifferences + ); continue; } case "muted": { extraAttributes.delete(propKey); var _serverValue2 = domElement.muted; - warnForPropDifference(propKey, _serverValue2, value); + warnForPropDifference( + propKey, + _serverValue2, + value, + serverDifferences + ); continue; } case "autoFocus": { extraAttributes.delete("autofocus"); var _serverValue3 = domElement.autofocus; - warnForPropDifference(propKey, _serverValue3, value); + warnForPropDifference( + propKey, + _serverValue3, + value, + serverDifferences + ); continue; } @@ -42719,7 +42979,8 @@ if (__DEV__) { propKey, propKey, null, - extraAttributes + extraAttributes, + serverDifferences ); continue; } @@ -42730,7 +42991,8 @@ if (__DEV__) { propKey, propKey, value, - extraAttributes + extraAttributes, + serverDifferences ); continue; @@ -42761,7 +43023,12 @@ if (__DEV__) { continue; } else if (_serverValue4 === EXPECTED_FORM_ACTION_URL) { extraAttributes.delete(propKey.toLowerCase()); - warnForPropDifference(propKey, "function", value); + warnForPropDifference( + propKey, + "function", + value, + serverDifferences + ); continue; } @@ -42770,7 +43037,8 @@ if (__DEV__) { propKey, propKey.toLowerCase(), value, - extraAttributes + extraAttributes, + serverDifferences ); continue; } @@ -42781,7 +43049,8 @@ if (__DEV__) { propKey, "xlink:href", value, - extraAttributes + extraAttributes, + serverDifferences ); continue; @@ -42792,7 +43061,8 @@ if (__DEV__) { propKey, "contenteditable", value, - extraAttributes + extraAttributes, + serverDifferences ); continue; } @@ -42804,7 +43074,8 @@ if (__DEV__) { propKey, "spellcheck", value, - extraAttributes + extraAttributes, + serverDifferences ); continue; } @@ -42820,7 +43091,8 @@ if (__DEV__) { propKey, propKey, value, - extraAttributes + extraAttributes, + serverDifferences ); continue; } @@ -42853,7 +43125,8 @@ if (__DEV__) { propKey, propKey.toLowerCase(), value, - extraAttributes + extraAttributes, + serverDifferences ); continue; } @@ -42865,7 +43138,8 @@ if (__DEV__) { propKey, propKey, value, - extraAttributes + extraAttributes, + serverDifferences ); continue; } @@ -42879,7 +43153,8 @@ if (__DEV__) { propKey, propKey, value, - extraAttributes + extraAttributes, + serverDifferences ); continue; } @@ -42890,7 +43165,8 @@ if (__DEV__) { propKey, "rowspan", value, - extraAttributes + extraAttributes, + serverDifferences ); continue; } @@ -42901,7 +43177,8 @@ if (__DEV__) { propKey, propKey, value, - extraAttributes + extraAttributes, + serverDifferences ); continue; } @@ -42912,7 +43189,8 @@ if (__DEV__) { propKey, "x-height", value, - extraAttributes + extraAttributes, + serverDifferences ); continue; @@ -42922,7 +43200,8 @@ if (__DEV__) { propKey, "xlink:actuate", value, - extraAttributes + extraAttributes, + serverDifferences ); continue; @@ -42932,7 +43211,8 @@ if (__DEV__) { propKey, "xlink:arcrole", value, - extraAttributes + extraAttributes, + serverDifferences ); continue; @@ -42942,7 +43222,8 @@ if (__DEV__) { propKey, "xlink:role", value, - extraAttributes + extraAttributes, + serverDifferences ); continue; @@ -42952,7 +43233,8 @@ if (__DEV__) { propKey, "xlink:show", value, - extraAttributes + extraAttributes, + serverDifferences ); continue; @@ -42962,7 +43244,8 @@ if (__DEV__) { propKey, "xlink:title", value, - extraAttributes + extraAttributes, + serverDifferences ); continue; @@ -42972,7 +43255,8 @@ if (__DEV__) { propKey, "xlink:type", value, - extraAttributes + extraAttributes, + serverDifferences ); continue; @@ -42982,7 +43266,8 @@ if (__DEV__) { propKey, "xml:base", value, - extraAttributes + extraAttributes, + serverDifferences ); continue; @@ -42992,7 +43277,8 @@ if (__DEV__) { propKey, "xml:lang", value, - extraAttributes + extraAttributes, + serverDifferences ); continue; @@ -43002,7 +43288,8 @@ if (__DEV__) { propKey, "xml:space", value, - extraAttributes + extraAttributes, + serverDifferences ); continue; @@ -43030,7 +43317,8 @@ if (__DEV__) { propKey, propKey, value, - extraAttributes + extraAttributes, + serverDifferences ); continue; } @@ -43083,20 +43371,19 @@ if (__DEV__) { ); if (!isMismatchDueToBadCasing) { - warnForPropDifference(propKey, _serverValue5, value); + warnForPropDifference( + propKey, + _serverValue5, + value, + serverDifferences + ); } } } } } - function diffHydratedProperties( - domElement, - tag, - props, - shouldWarnDev, - hostContext - ) { + function hydrateProperties(domElement, tag, props, hostContext) { { validatePropertiesInDevelopment(tag, props); } // TODO: Make sure that we check isMounted before firing any of these events. @@ -43223,15 +43510,13 @@ if (__DEV__) { typeof children === "number" || (enableBigIntSupport && typeof children === "bigint") ) { - // $FlowFixMe[unsafe-addition] Flow doesn't want us to use `+` operator with string and bigint - if (domElement.textContent !== "" + children) { - if (props.suppressHydrationWarning !== true) { - checkForUnmatchedText( - domElement.textContent, - children, - shouldWarnDev - ); - } + if ( + // $FlowFixMe[unsafe-addition] Flow doesn't want us to use `+` operator with string and bigint + domElement.textContent !== "" + children && + props.suppressHydrationWarning !== true && + !checkForUnmatchedText(domElement.textContent, children) + ) { + return false; } } @@ -43248,12 +43533,17 @@ if (__DEV__) { trapClickOnNonInteractiveElement(domElement); } - if (shouldWarnDev) { + return true; + } + function diffHydratedProperties(domElement, tag, props, hostContext) { + var serverDifferences = {}; + + { var extraAttributes = new Set(); var attributes = domElement.attributes; - for (var _i = 0; _i < attributes.length; _i++) { - var name = attributes[_i].name.toLowerCase(); + for (var i = 0; i < attributes.length; i++) { + var name = attributes[i].name.toLowerCase(); switch (name) { // Controlled attributes are not validated @@ -43270,7 +43560,7 @@ if (__DEV__) { default: // Intentionally use the original name. // See discussion in https://github.com/facebook/react/pull/10676. - extraAttributes.add(attributes[_i].name); + extraAttributes.add(attributes[i].name); } } @@ -43280,7 +43570,8 @@ if (__DEV__) { tag, props, hostContext, - extraAttributes + extraAttributes, + serverDifferences ); } else { diffHydratedGenericElement( @@ -43288,7 +43579,8 @@ if (__DEV__) { tag, props, hostContext, - extraAttributes + extraAttributes, + serverDifferences ); } @@ -43296,73 +43588,49 @@ if (__DEV__) { extraAttributes.size > 0 && props.suppressHydrationWarning !== true ) { - warnForExtraAttributes(extraAttributes); + warnForExtraAttributes( + domElement, + extraAttributes, + serverDifferences + ); } } - } - function diffHydratedText(textNode, text) { - var isDifferent = textNode.nodeValue !== text; - return isDifferent; - } - function warnForDeletedHydratableElement(parentNode, child) { - { - if (didWarnInvalidHydration) { - return; - } - - didWarnInvalidHydration = true; - error( - "Did not expect server HTML to contain a <%s> in <%s>.", - child.nodeName.toLowerCase(), - parentNode.nodeName.toLowerCase() - ); + if (Object.keys(serverDifferences).length === 0) { + return null; } - } - function warnForDeletedHydratableText(parentNode, child) { - { - if (didWarnInvalidHydration) { - return; - } - - didWarnInvalidHydration = true; - error( - 'Did not expect server HTML to contain the text node "%s" in <%s>.', - child.nodeValue, - parentNode.nodeName.toLowerCase() - ); - } + return serverDifferences; } - function warnForInsertedHydratedElement(parentNode, tag, props) { - { - if (didWarnInvalidHydration) { - return; - } - - didWarnInvalidHydration = true; + function hydrateText(textNode, text, parentProps) { + var isDifferent = textNode.nodeValue !== text; - error( - "Expected server HTML to contain a matching <%s> in <%s>.", - tag, - parentNode.nodeName.toLowerCase() - ); + if ( + isDifferent && + (parentProps === null || + parentProps.suppressHydrationWarning !== true) && + !checkForUnmatchedText(textNode.nodeValue, text) + ) { + return false; } + + return true; } - function warnForInsertedHydratedText(parentNode, text) { - { - if (didWarnInvalidHydration) { - return; - } + function diffHydratedText(textNode, text) { + if (textNode.nodeValue === text) { + return null; + } - didWarnInvalidHydration = true; + var normalizedClientText = normalizeMarkupForTextOrAttribute(text); + var normalizedServerText = normalizeMarkupForTextOrAttribute( + textNode.nodeValue + ); - error( - 'Expected server HTML to contain a matching text node for "%s" in <%s>.', - text, - parentNode.nodeName.toLowerCase() - ); + if (normalizedServerText === normalizedClientText) { + return null; } + + return textNode.nodeValue; } function restoreControlledState(domElement, tag, props) { switch (tag) { @@ -44527,6 +44795,23 @@ if (__DEV__) { function getFirstHydratableChildWithinSuspenseInstance(parentInstance) { return getNextHydratable(parentInstance.nextSibling); } + function describeHydratableInstanceForDevWarnings(instance) { + // Reverse engineer a pseudo react-element from hydratable instnace + if (instance.nodeType === ELEMENT_NODE) { + // Reverse engineer a set of props that can print for dev warnings + return { + type: instance.nodeName.toLowerCase(), + props: getPropsFromElement(instance) + }; + } else if (instance.nodeType === COMMENT_NODE) { + return { + type: "Suspense", + props: {} + }; + } else { + return instance.nodeValue; + } + } function validateHydratableInstance(type, props, hostContext) { { // TODO: take namespace into account when validating. @@ -44539,14 +44824,22 @@ if (__DEV__) { type, props, hostContext, - internalInstanceHandle, - shouldWarnDev + internalInstanceHandle ) { precacheFiberNode(internalInstanceHandle, instance); // TODO: Possibly defer this until the commit phase where all the events // get attached. updateFiberProps(instance, props); - diffHydratedProperties(instance, type, props, shouldWarnDev, hostContext); + return hydrateProperties(instance, type, props); + } // Returns a Map of properties that were different on the server. + + function diffHydratedPropsForDevWarnings( + instance, + type, + props, + hostContext + ) { + return diffHydratedProperties(instance, type, props, hostContext); } function validateHydratableTextInstance(text, hostContext) { { @@ -44564,10 +44857,21 @@ if (__DEV__) { textInstance, text, internalInstanceHandle, - shouldWarnDev + parentInstanceProps ) { precacheFiberNode(internalInstanceHandle, textInstance); - return diffHydratedText(textInstance, text); + return hydrateText(textInstance, text, parentInstanceProps); + } // Returns the server text if it differs from the client. + + function diffHydratedTextForDevWarnings(textInstance, text, parentProps) { + if ( + parentProps === null || + parentProps[SUPPRESS_HYDRATION_WARNING] !== true + ) { + return diffHydratedText(textInstance, text); + } + + return null; } function hydrateSuspenseInstance(suspenseInstance, internalInstanceHandle) { precacheFiberNode(internalInstanceHandle, suspenseInstance); @@ -44647,139 +44951,6 @@ if (__DEV__) { } function shouldDeleteUnhydratedTailInstances(parentType) { return parentType !== "form" && parentType !== "button"; - } - function didNotMatchHydratedContainerTextInstance( - parentContainer, - textInstance, - text, - shouldWarnDev - ) { - checkForUnmatchedText(textInstance.nodeValue, text, shouldWarnDev); - } - function didNotMatchHydratedTextInstance( - parentType, - parentProps, - parentInstance, - textInstance, - text, - shouldWarnDev - ) { - if (parentProps[SUPPRESS_HYDRATION_WARNING] !== true) { - checkForUnmatchedText(textInstance.nodeValue, text, shouldWarnDev); - } - } - function didNotHydrateInstanceWithinContainer(parentContainer, instance) { - { - if (instance.nodeType === ELEMENT_NODE) { - warnForDeletedHydratableElement(parentContainer, instance); - } else if (instance.nodeType === COMMENT_NODE); - else { - warnForDeletedHydratableText(parentContainer, instance); - } - } - } - function didNotHydrateInstanceWithinSuspenseInstance( - parentInstance, - instance - ) { - { - // $FlowFixMe[incompatible-type]: Only Element or Document can be parent nodes. - var parentNode = parentInstance.parentNode; - - if (parentNode !== null) { - if (instance.nodeType === ELEMENT_NODE) { - warnForDeletedHydratableElement(parentNode, instance); - } else if (instance.nodeType === COMMENT_NODE); - else { - warnForDeletedHydratableText(parentNode, instance); - } - } - } - } - function didNotHydrateInstance( - parentType, - parentProps, - parentInstance, - instance - ) { - { - if (instance.nodeType === ELEMENT_NODE) { - warnForDeletedHydratableElement(parentInstance, instance); - } else if (instance.nodeType === COMMENT_NODE); - else { - warnForDeletedHydratableText(parentInstance, instance); - } - } - } - function didNotFindHydratableInstanceWithinContainer( - parentContainer, - type, - props - ) { - { - warnForInsertedHydratedElement(parentContainer, type); - } - } - function didNotFindHydratableTextInstanceWithinContainer( - parentContainer, - text - ) { - { - warnForInsertedHydratedText(parentContainer, text); - } - } - function didNotFindHydratableInstanceWithinSuspenseInstance( - parentInstance, - type, - props - ) { - { - // $FlowFixMe[incompatible-type]: Only Element or Document can be parent nodes. - var parentNode = parentInstance.parentNode; - if (parentNode !== null) - warnForInsertedHydratedElement(parentNode, type); - } - } - function didNotFindHydratableTextInstanceWithinSuspenseInstance( - parentInstance, - text - ) { - { - // $FlowFixMe[incompatible-type]: Only Element or Document can be parent nodes. - var parentNode = parentInstance.parentNode; - if (parentNode !== null) warnForInsertedHydratedText(parentNode, text); - } - } - function didNotFindHydratableInstance( - parentType, - parentProps, - parentInstance, - type, - props - ) { - { - warnForInsertedHydratedElement(parentInstance, type); - } - } - function didNotFindHydratableTextInstance( - parentType, - parentProps, - parentInstance, - text - ) { - { - warnForInsertedHydratedText(parentInstance, text); - } - } - function errorHydratingContainer(parentContainer) { - { - // TODO: This gets logged by onRecoverableError, too, so we should be - // able to remove it. - error( - "An error occurred during hydration. The server HTML was replaced with client content in <%s>.", - parentContainer.nodeName.toLowerCase() - ); - } } // ------------------- function requestPostPaintCallback(callback) { localRequestAnimationFrame(function () { diff --git a/compiled/facebook-www/ReactDOM-dev.modern.js b/compiled/facebook-www/ReactDOM-dev.modern.js index 2ec1328a0b302..83af8910c1a52 100644 --- a/compiled/facebook-www/ReactDOM-dev.modern.js +++ b/compiled/facebook-www/ReactDOM-dev.modern.js @@ -8169,35 +8169,104 @@ if (__DEV__) { return true; } + function warnForDeletedHydratableInstance(parentType, child) { + { + var description = describeHydratableInstanceForDevWarnings(child); + + if (typeof description === "string") { + error( + 'Did not expect server HTML to contain the text node "%s" in <%s>.', + description, + parentType + ); + } else { + error( + "Did not expect server HTML to contain a <%s> in <%s>.", + description.type, + parentType + ); + } + } + } + + function warnForInsertedHydratedElement(parentType, tag) { + { + error( + "Expected server HTML to contain a matching <%s> in <%s>.", + tag, + parentType + ); + } + } + + function warnForInsertedHydratedText(parentType, text) { + { + error( + 'Expected server HTML to contain a matching text node for "%s" in <%s>.', + text, + parentType + ); + } + } + + function warnForInsertedHydratedSuspense(parentType) { + { + error( + "Expected server HTML to contain a matching <%s> in <%s>.", + "Suspense", + parentType + ); + } + } + + function errorHydratingContainer(parentContainer) { + { + // TODO: This gets logged by onRecoverableError, too, so we should be + // able to remove it. + error( + "An error occurred during hydration. The server HTML was replaced with client content." + ); + } + } + function warnUnhydratedInstance(returnFiber, instance) { { + if (didWarnInvalidHydration) { + return; + } + + didWarnInvalidHydration = true; + switch (returnFiber.tag) { case HostRoot: { - didNotHydrateInstanceWithinContainer( - returnFiber.stateNode.containerInfo, - instance - ); + var description = + describeHydratableInstanceForDevWarnings(instance); + + if (typeof description === "string") { + error( + 'Did not expect server HTML to contain the text node "%s" in the root.', + description + ); + } else { + error( + "Did not expect server HTML to contain a <%s> in the root.", + description.type + ); + } + break; } case HostSingleton: case HostComponent: { - didNotHydrateInstance( - returnFiber.type, - returnFiber.memoizedProps, - returnFiber.stateNode, - instance - ); + warnForDeletedHydratableInstance(returnFiber.type, instance); break; } case SuspenseComponent: { var suspenseState = returnFiber.memoizedState; if (suspenseState.dehydrated !== null) - didNotHydrateInstanceWithinSuspenseInstance( - suspenseState.dehydrated, - instance - ); + warnForDeletedHydratableInstance("Suspense", instance); break; } } @@ -8213,26 +8282,41 @@ if (__DEV__) { return; } + if (didWarnInvalidHydration) { + return; + } + + didWarnInvalidHydration = true; + switch (returnFiber.tag) { case HostRoot: { - var parentContainer = returnFiber.stateNode.containerInfo; - + // const parentContainer = returnFiber.stateNode.containerInfo; switch (fiber.tag) { case HostSingleton: case HostComponent: - var type = fiber.type; - didNotFindHydratableInstanceWithinContainer( - parentContainer, - type + error( + "Expected server HTML to contain a matching <%s> in the root.", + fiber.type ); + break; case HostText: var text = fiber.pendingProps; - didNotFindHydratableTextInstanceWithinContainer( - parentContainer, + + error( + 'Expected server HTML to contain a matching text node for "%s" in the root.', text ); + + break; + + case SuspenseComponent: + error( + "Expected server HTML to contain a matching <%s> in the root.", + "Suspense" + ); + break; } @@ -8241,31 +8325,25 @@ if (__DEV__) { case HostSingleton: case HostComponent: { - var parentType = returnFiber.type; - var parentProps = returnFiber.memoizedProps; - var parentInstance = returnFiber.stateNode; + var parentType = returnFiber.type; // const parentProps = returnFiber.memoizedProps; + // const parentInstance = returnFiber.stateNode; switch (fiber.tag) { case HostSingleton: case HostComponent: { - var _type = fiber.type; - didNotFindHydratableInstance( - parentType, - parentProps, - parentInstance, - _type - ); + var type = fiber.type; + warnForInsertedHydratedElement(parentType, type); break; } case HostText: { var _text = fiber.pendingProps; - didNotFindHydratableTextInstance( - parentType, - parentProps, - parentInstance, - _text - ); + warnForInsertedHydratedText(parentType, _text); + break; + } + + case SuspenseComponent: { + warnForInsertedHydratedSuspense(parentType); break; } } @@ -8274,27 +8352,25 @@ if (__DEV__) { } case SuspenseComponent: { - var suspenseState = returnFiber.memoizedState; - var _parentInstance = suspenseState.dehydrated; - if (_parentInstance !== null) - switch (fiber.tag) { - case HostSingleton: - case HostComponent: - var _type2 = fiber.type; - didNotFindHydratableInstanceWithinSuspenseInstance( - _parentInstance, - _type2 - ); - break; + // const suspenseState: SuspenseState = returnFiber.memoizedState; + // const parentInstance = suspenseState.dehydrated; + switch (fiber.tag) { + case HostSingleton: + case HostComponent: + var _type = fiber.type; + warnForInsertedHydratedElement("Suspense", _type); + break; + + case HostText: + var _text2 = fiber.pendingProps; + warnForInsertedHydratedText("Suspense", _text2); + break; + + case SuspenseComponent: + warnForInsertedHydratedSuspense("Suspense"); + break; + } - case HostText: - var _text2 = fiber.pendingProps; - didNotFindHydratableTextInstanceWithinSuspenseInstance( - _parentInstance, - _text2 - ); - break; - } break; } @@ -8489,66 +8565,152 @@ if (__DEV__) { throwOnHydrationMismatch(); return false; - } + } // Temp + + var didWarnInvalidHydration = false; function prepareToHydrateHostInstance(fiber, hostContext) { var instance = fiber.stateNode; - var shouldWarnIfMismatchDev = !didSuspendOrErrorDEV; - hydrateInstance( + + { + var shouldWarnIfMismatchDev = !didSuspendOrErrorDEV; + + if (shouldWarnIfMismatchDev) { + var differences = diffHydratedPropsForDevWarnings( + instance, + fiber.type, + fiber.memoizedProps, + hostContext + ); + + if (differences !== null) { + if (differences.children != null && !didWarnInvalidHydration) { + didWarnInvalidHydration = true; + var serverValue = differences.children; + var clientValue = fiber.memoizedProps.children; + + error( + 'Text content did not match. Server: "%s" Client: "%s"', + serverValue, + clientValue + ); + } + + for (var propName in differences) { + if (!differences.hasOwnProperty(propName)) { + continue; + } + + if (didWarnInvalidHydration) { + break; + } + + didWarnInvalidHydration = true; + var _serverValue = differences[propName]; + var _clientValue = fiber.memoizedProps[propName]; + + if (propName === "children"); + else if (_clientValue != null) { + error( + "Prop `%s` did not match. Server: %s Client: %s", + propName, + JSON.stringify(_serverValue), + JSON.stringify(_clientValue) + ); + } else { + error("Extra attribute from the server: %s", propName); + } + } + } + } + } + + var didHydrate = hydrateInstance( instance, fiber.type, fiber.memoizedProps, hostContext, - fiber, - shouldWarnIfMismatchDev + fiber ); + + if (!didHydrate) { + throw new Error("Text content does not match server-rendered HTML."); + } } function prepareToHydrateHostTextInstance(fiber) { var textInstance = fiber.stateNode; var textContent = fiber.memoizedProps; var shouldWarnIfMismatchDev = !didSuspendOrErrorDEV; - var textIsDifferent = hydrateTextInstance( - textInstance, - textContent, - fiber - ); + var parentProps = null; // We assume that prepareToHydrateHostTextInstance is called in a context where the + // hydration parent is the parent host component of this host text. - if (textIsDifferent) { - // We assume that prepareToHydrateHostTextInstance is called in a context where the - // hydration parent is the parent host component of this host text. - var returnFiber = hydrationParentFiber; + var returnFiber = hydrationParentFiber; - if (returnFiber !== null) { - switch (returnFiber.tag) { - case HostRoot: { - var parentContainer = returnFiber.stateNode.containerInfo; - didNotMatchHydratedContainerTextInstance( - parentContainer, - textInstance, - textContent, - shouldWarnIfMismatchDev - ); - break; + if (returnFiber !== null) { + switch (returnFiber.tag) { + case HostRoot: { + { + if (shouldWarnIfMismatchDev) { + var difference = diffHydratedTextForDevWarnings( + textInstance, + textContent, + parentProps + ); + + if (difference !== null && !didWarnInvalidHydration) { + didWarnInvalidHydration = true; + + error( + 'Text content did not match. Server: "%s" Client: "%s"', + difference, + textContent + ); + } + } } - case HostSingleton: - case HostComponent: { - var parentType = returnFiber.type; - var parentProps = returnFiber.memoizedProps; - var parentInstance = returnFiber.stateNode; - didNotMatchHydratedTextInstance( - parentType, - parentProps, - parentInstance, - textInstance, - textContent, - shouldWarnIfMismatchDev - ); - break; + break; + } + + case HostSingleton: + case HostComponent: { + parentProps = returnFiber.memoizedProps; + + { + if (shouldWarnIfMismatchDev) { + var _difference = diffHydratedTextForDevWarnings( + textInstance, + textContent, + parentProps + ); + + if (_difference !== null && !didWarnInvalidHydration) { + didWarnInvalidHydration = true; + + error( + 'Text content did not match. Server: "%s" Client: "%s"', + _difference, + textContent + ); + } + } } + + break; } - } + } // TODO: What if it's a SuspenseInstance? + } + + var didHydrate = hydrateTextInstance( + textInstance, + textContent, + fiber, + parentProps + ); + + if (!didHydrate) { + throw new Error("Text content does not match server-rendered HTML."); } } @@ -31145,7 +31307,7 @@ if (__DEV__) { rootWorkInProgress.flags |= ForceClientRender; { - errorHydratingContainer(root.containerInfo); + errorHydratingContainer(); } } @@ -35413,7 +35575,7 @@ if (__DEV__) { return root; } - var ReactVersion = "19.0.0-www-modern-fbbbe297"; + var ReactVersion = "19.0.0-www-modern-795da624"; function createPortal$1( children, @@ -40718,7 +40880,6 @@ if (__DEV__) { var didWarnControlledToUncontrolled = false; var didWarnUncontrolledToControlled = false; - var didWarnInvalidHydration = false; var didWarnFormActionType = false; var didWarnFormActionName = false; var didWarnFormActionTarget = false; @@ -40869,12 +41030,13 @@ if (__DEV__) { } } - function warnForPropDifference(propName, serverValue, clientValue) { + function warnForPropDifference( + propName, + serverValue, + clientValue, + serverDifferences + ) { { - if (didWarnInvalidHydration) { - return; - } - if (serverValue === clientValue) { return; } @@ -40888,30 +41050,22 @@ if (__DEV__) { return; } - didWarnInvalidHydration = true; - - error( - "Prop `%s` did not match. Server: %s Client: %s", - propName, - JSON.stringify(normalizedServerValue), - JSON.stringify(normalizedClientValue) - ); + serverDifferences[propName] = serverValue; } } - function warnForExtraAttributes(attributeNames) { + function warnForExtraAttributes( + domElement, + attributeNames, + serverDifferences + ) { { - if (didWarnInvalidHydration) { - return; - } - - didWarnInvalidHydration = true; - var names = []; - attributeNames.forEach(function (name) { - names.push(name); + attributeNames.forEach(function (attributeName) { + serverDifferences[attributeName] = + attributeName === "style" + ? getStylesObjectFromElement(domElement) + : domElement.getAttribute(attributeName); }); - - error("Extra attributes from the server: %s", names); } } @@ -40974,30 +41128,15 @@ if (__DEV__) { .replace(NORMALIZE_NULL_AND_REPLACEMENT_REGEX, ""); } - function checkForUnmatchedText(serverText, clientText, shouldWarnDev) { + function checkForUnmatchedText(serverText, clientText) { var normalizedClientText = normalizeMarkupForTextOrAttribute(clientText); var normalizedServerText = normalizeMarkupForTextOrAttribute(serverText); if (normalizedServerText === normalizedClientText) { - return; + return true; } - if (shouldWarnDev) { - { - if (!didWarnInvalidHydration) { - didWarnInvalidHydration = true; - - error( - 'Text content did not match. Server: "%s" Client: "%s"', - normalizedServerText, - normalizedClientText - ); - } - } - } // In concurrent roots, we throw when there's a text mismatch and revert to - // client rendering, up to the nearest Suspense boundary. - - throw new Error("Text content does not match server-rendered HTML."); + return false; } function noop$1() {} @@ -42758,19 +42897,70 @@ if (__DEV__) { } } - function diffHydratedStyles(domElement, value) { + function getPropsFromElement(domElement) { + var serverDifferences = {}; + var attributes = domElement.attributes; + + for (var i = 0; i < attributes.length; i++) { + var attr = attributes[i]; + serverDifferences[attr.name] = + attr.name.toLowerCase() === "style" + ? getStylesObjectFromElement(domElement) + : attr.value; + } + + return serverDifferences; + } + + function getStylesObjectFromElement(domElement) { + var serverValueInObjectForm = {}; + var style = domElement.style; + + for (var i = 0; i < style.length; i++) { + var styleName = style[i]; // TODO: We should use the original prop value here if it is equivalent. + // TODO: We could use the original client capitalization if the equivalent + // other capitalization exists in the DOM. + + serverValueInObjectForm[styleName] = style.getPropertyValue(styleName); + } + + return serverValueInObjectForm; + } + + function diffHydratedStyles(domElement, value, serverDifferences) { if (value != null && typeof value !== "object") { - throw new Error( - "The `style` prop expects a mapping from style properties to values, " + - "not a string. For example, style={{marginRight: spacing + 'em'}} when " + - "using JSX." - ); + { + error( + "The `style` prop expects a mapping from style properties to values, " + + "not a string. For example, style={{marginRight: spacing + 'em'}} when " + + "using JSX." + ); + } + + return; } if (canDiffStyleForHydrationWarning) { - var expectedStyle = createDangerousStringForStyles(value); + // First we compare the string form and see if it's equivalent. + // This lets us bail out on anything that used to pass in this form. + // It also lets us compare anything that's not parsed by this browser. + var clientValue = createDangerousStringForStyles(value); var serverValue = domElement.getAttribute("style"); - warnForPropDifference("style", serverValue, expectedStyle); + + if (serverValue === clientValue) { + return; + } + + var normalizedClientValue = + normalizeMarkupForTextOrAttribute(clientValue); + var normalizedServerValue = + normalizeMarkupForTextOrAttribute(serverValue); + + if (normalizedServerValue === normalizedClientValue) { + return; + } // Otherwise, we create the object from the DOM for the diff view. + + serverDifferences.style = getStylesObjectFromElement(domElement); } } @@ -42779,7 +42969,8 @@ if (__DEV__) { propKey, attributeName, value, - extraAttributes + extraAttributes, + serverDifferences ) { extraAttributes.delete(attributeName); var serverValue = domElement.getAttribute(attributeName); @@ -42814,7 +43005,7 @@ if (__DEV__) { } } - warnForPropDifference(propKey, serverValue, value); + warnForPropDifference(propKey, serverValue, value, serverDifferences); } function hydrateBooleanAttribute( @@ -42822,7 +43013,8 @@ if (__DEV__) { propKey, attributeName, value, - extraAttributes + extraAttributes, + serverDifferences ) { extraAttributes.delete(attributeName); var serverValue = domElement.getAttribute(attributeName); @@ -42854,7 +43046,7 @@ if (__DEV__) { } } - warnForPropDifference(propKey, serverValue, value); + warnForPropDifference(propKey, serverValue, value, serverDifferences); } function hydrateOverloadedBooleanAttribute( @@ -42862,7 +43054,8 @@ if (__DEV__) { propKey, attributeName, value, - extraAttributes + extraAttributes, + serverDifferences ) { extraAttributes.delete(attributeName); var serverValue = domElement.getAttribute(attributeName); @@ -42907,7 +43100,7 @@ if (__DEV__) { } } - warnForPropDifference(propKey, serverValue, value); + warnForPropDifference(propKey, serverValue, value, serverDifferences); } function hydrateBooleanishAttribute( @@ -42915,7 +43108,8 @@ if (__DEV__) { propKey, attributeName, value, - extraAttributes + extraAttributes, + serverDifferences ) { extraAttributes.delete(attributeName); var serverValue = domElement.getAttribute(attributeName); @@ -42948,7 +43142,7 @@ if (__DEV__) { } } - warnForPropDifference(propKey, serverValue, value); + warnForPropDifference(propKey, serverValue, value, serverDifferences); } function hydrateNumericAttribute( @@ -42956,7 +43150,8 @@ if (__DEV__) { propKey, attributeName, value, - extraAttributes + extraAttributes, + serverDifferences ) { extraAttributes.delete(attributeName); var serverValue = domElement.getAttribute(attributeName); @@ -43002,7 +43197,7 @@ if (__DEV__) { } } - warnForPropDifference(propKey, serverValue, value); + warnForPropDifference(propKey, serverValue, value, serverDifferences); } function hydratePositiveNumericAttribute( @@ -43010,7 +43205,8 @@ if (__DEV__) { propKey, attributeName, value, - extraAttributes + extraAttributes, + serverDifferences ) { extraAttributes.delete(attributeName); var serverValue = domElement.getAttribute(attributeName); @@ -43056,7 +43252,7 @@ if (__DEV__) { } } - warnForPropDifference(propKey, serverValue, value); + warnForPropDifference(propKey, serverValue, value, serverDifferences); } function hydrateSanitizedAttribute( @@ -43064,7 +43260,8 @@ if (__DEV__) { propKey, attributeName, value, - extraAttributes + extraAttributes, + serverDifferences ) { extraAttributes.delete(attributeName); var serverValue = domElement.getAttribute(attributeName); @@ -43101,7 +43298,7 @@ if (__DEV__) { } } - warnForPropDifference(propKey, serverValue, value); + warnForPropDifference(propKey, serverValue, value, serverDifferences); } function diffHydratedCustomComponent( @@ -43109,7 +43306,8 @@ if (__DEV__) { tag, props, hostContext, - extraAttributes + extraAttributes, + serverDifferences ) { for (var propKey in props) { if (!props.hasOwnProperty(propKey)) { @@ -43136,7 +43334,19 @@ if (__DEV__) { } // Validate that the properties correspond to their expected values. switch (propKey) { - case "children": // Checked above already + case "children": { + if (typeof value === "string" || typeof value === "number") { + warnForPropDifference( + "children", + domElement.textContent, + value, + serverDifferences + ); + } + + continue; + } + // Checked above already case "suppressContentEditableWarning": case "suppressHydrationWarning": @@ -43153,14 +43363,19 @@ if (__DEV__) { if (nextHtml != null) { var expectedHTML = normalizeHTML(domElement, nextHtml); - warnForPropDifference(propKey, serverHTML, expectedHTML); + warnForPropDifference( + propKey, + serverHTML, + expectedHTML, + serverDifferences + ); } continue; case "style": extraAttributes.delete(propKey); - diffHydratedStyles(domElement, value); + diffHydratedStyles(domElement, value, serverDifferences); continue; case "offsetParent": @@ -43193,7 +43408,12 @@ if (__DEV__) { "class", value ); - warnForPropDifference("className", serverValue, value); + warnForPropDifference( + "className", + serverValue, + value, + serverDifferences + ); continue; } @@ -43220,7 +43440,12 @@ if (__DEV__) { value ); - warnForPropDifference(propKey, _serverValue, value); + warnForPropDifference( + propKey, + _serverValue, + value, + serverDifferences + ); } } } @@ -43236,7 +43461,8 @@ if (__DEV__) { tag, props, hostContext, - extraAttributes + extraAttributes, + serverDifferences ) { for (var propKey in props) { if (!props.hasOwnProperty(propKey)) { @@ -43263,7 +43489,19 @@ if (__DEV__) { } // Validate that the properties correspond to their expected values. switch (propKey) { - case "children": // Checked above already + case "children": { + if (typeof value === "string" || typeof value === "number") { + warnForPropDifference( + "children", + domElement.textContent, + value, + serverDifferences + ); + } + + continue; + } + // Checked above already case "suppressContentEditableWarning": case "suppressHydrationWarning": @@ -43285,7 +43523,12 @@ if (__DEV__) { if (nextHtml != null) { var expectedHTML = normalizeHTML(domElement, nextHtml); - warnForPropDifference(propKey, serverHTML, expectedHTML); + + if (serverHTML !== expectedHTML) { + serverDifferences[propKey] = { + __html: serverHTML + }; + } } continue; @@ -43296,7 +43539,8 @@ if (__DEV__) { propKey, "class", value, - extraAttributes + extraAttributes, + serverDifferences ); continue; @@ -43306,33 +43550,49 @@ if (__DEV__) { propKey, "tabindex", value, - extraAttributes + extraAttributes, + serverDifferences ); continue; case "style": extraAttributes.delete(propKey); - diffHydratedStyles(domElement, value); + diffHydratedStyles(domElement, value, serverDifferences); continue; case "multiple": { extraAttributes.delete(propKey); var serverValue = domElement.multiple; - warnForPropDifference(propKey, serverValue, value); + warnForPropDifference( + propKey, + serverValue, + value, + serverDifferences + ); continue; } case "muted": { extraAttributes.delete(propKey); var _serverValue2 = domElement.muted; - warnForPropDifference(propKey, _serverValue2, value); + warnForPropDifference( + propKey, + _serverValue2, + value, + serverDifferences + ); continue; } case "autoFocus": { extraAttributes.delete("autofocus"); var _serverValue3 = domElement.autofocus; - warnForPropDifference(propKey, _serverValue3, value); + warnForPropDifference( + propKey, + _serverValue3, + value, + serverDifferences + ); continue; } @@ -43369,7 +43629,8 @@ if (__DEV__) { propKey, propKey, null, - extraAttributes + extraAttributes, + serverDifferences ); continue; } @@ -43380,7 +43641,8 @@ if (__DEV__) { propKey, propKey, value, - extraAttributes + extraAttributes, + serverDifferences ); continue; @@ -43411,7 +43673,12 @@ if (__DEV__) { continue; } else if (_serverValue4 === EXPECTED_FORM_ACTION_URL) { extraAttributes.delete(propKey.toLowerCase()); - warnForPropDifference(propKey, "function", value); + warnForPropDifference( + propKey, + "function", + value, + serverDifferences + ); continue; } @@ -43420,7 +43687,8 @@ if (__DEV__) { propKey, propKey.toLowerCase(), value, - extraAttributes + extraAttributes, + serverDifferences ); continue; } @@ -43431,7 +43699,8 @@ if (__DEV__) { propKey, "xlink:href", value, - extraAttributes + extraAttributes, + serverDifferences ); continue; @@ -43442,7 +43711,8 @@ if (__DEV__) { propKey, "contenteditable", value, - extraAttributes + extraAttributes, + serverDifferences ); continue; } @@ -43454,7 +43724,8 @@ if (__DEV__) { propKey, "spellcheck", value, - extraAttributes + extraAttributes, + serverDifferences ); continue; } @@ -43470,7 +43741,8 @@ if (__DEV__) { propKey, propKey, value, - extraAttributes + extraAttributes, + serverDifferences ); continue; } @@ -43503,7 +43775,8 @@ if (__DEV__) { propKey, propKey.toLowerCase(), value, - extraAttributes + extraAttributes, + serverDifferences ); continue; } @@ -43515,7 +43788,8 @@ if (__DEV__) { propKey, propKey, value, - extraAttributes + extraAttributes, + serverDifferences ); continue; } @@ -43529,7 +43803,8 @@ if (__DEV__) { propKey, propKey, value, - extraAttributes + extraAttributes, + serverDifferences ); continue; } @@ -43540,7 +43815,8 @@ if (__DEV__) { propKey, "rowspan", value, - extraAttributes + extraAttributes, + serverDifferences ); continue; } @@ -43551,7 +43827,8 @@ if (__DEV__) { propKey, propKey, value, - extraAttributes + extraAttributes, + serverDifferences ); continue; } @@ -43562,7 +43839,8 @@ if (__DEV__) { propKey, "x-height", value, - extraAttributes + extraAttributes, + serverDifferences ); continue; @@ -43572,7 +43850,8 @@ if (__DEV__) { propKey, "xlink:actuate", value, - extraAttributes + extraAttributes, + serverDifferences ); continue; @@ -43582,7 +43861,8 @@ if (__DEV__) { propKey, "xlink:arcrole", value, - extraAttributes + extraAttributes, + serverDifferences ); continue; @@ -43592,7 +43872,8 @@ if (__DEV__) { propKey, "xlink:role", value, - extraAttributes + extraAttributes, + serverDifferences ); continue; @@ -43602,7 +43883,8 @@ if (__DEV__) { propKey, "xlink:show", value, - extraAttributes + extraAttributes, + serverDifferences ); continue; @@ -43612,7 +43894,8 @@ if (__DEV__) { propKey, "xlink:title", value, - extraAttributes + extraAttributes, + serverDifferences ); continue; @@ -43622,7 +43905,8 @@ if (__DEV__) { propKey, "xlink:type", value, - extraAttributes + extraAttributes, + serverDifferences ); continue; @@ -43632,7 +43916,8 @@ if (__DEV__) { propKey, "xml:base", value, - extraAttributes + extraAttributes, + serverDifferences ); continue; @@ -43642,7 +43927,8 @@ if (__DEV__) { propKey, "xml:lang", value, - extraAttributes + extraAttributes, + serverDifferences ); continue; @@ -43652,7 +43938,8 @@ if (__DEV__) { propKey, "xml:space", value, - extraAttributes + extraAttributes, + serverDifferences ); continue; @@ -43680,7 +43967,8 @@ if (__DEV__) { propKey, propKey, value, - extraAttributes + extraAttributes, + serverDifferences ); continue; } @@ -43733,20 +44021,19 @@ if (__DEV__) { ); if (!isMismatchDueToBadCasing) { - warnForPropDifference(propKey, _serverValue5, value); + warnForPropDifference( + propKey, + _serverValue5, + value, + serverDifferences + ); } } } } } - function diffHydratedProperties( - domElement, - tag, - props, - shouldWarnDev, - hostContext - ) { + function hydrateProperties(domElement, tag, props, hostContext) { { validatePropertiesInDevelopment(tag, props); } // TODO: Make sure that we check isMounted before firing any of these events. @@ -43868,15 +44155,13 @@ if (__DEV__) { typeof children === "number" || (enableBigIntSupport && typeof children === "bigint") ) { - // $FlowFixMe[unsafe-addition] Flow doesn't want us to use `+` operator with string and bigint - if (domElement.textContent !== "" + children) { - if (props.suppressHydrationWarning !== true) { - checkForUnmatchedText( - domElement.textContent, - children, - shouldWarnDev - ); - } + if ( + // $FlowFixMe[unsafe-addition] Flow doesn't want us to use `+` operator with string and bigint + domElement.textContent !== "" + children && + props.suppressHydrationWarning !== true && + !checkForUnmatchedText(domElement.textContent, children) + ) { + return false; } } @@ -43893,12 +44178,17 @@ if (__DEV__) { trapClickOnNonInteractiveElement(domElement); } - if (shouldWarnDev) { + return true; + } + function diffHydratedProperties(domElement, tag, props, hostContext) { + var serverDifferences = {}; + + { var extraAttributes = new Set(); var attributes = domElement.attributes; - for (var _i = 0; _i < attributes.length; _i++) { - var name = attributes[_i].name.toLowerCase(); + for (var i = 0; i < attributes.length; i++) { + var name = attributes[i].name.toLowerCase(); switch (name) { // Controlled attributes are not validated @@ -43915,7 +44205,7 @@ if (__DEV__) { default: // Intentionally use the original name. // See discussion in https://github.com/facebook/react/pull/10676. - extraAttributes.add(attributes[_i].name); + extraAttributes.add(attributes[i].name); } } @@ -43925,7 +44215,8 @@ if (__DEV__) { tag, props, hostContext, - extraAttributes + extraAttributes, + serverDifferences ); } else { diffHydratedGenericElement( @@ -43933,7 +44224,8 @@ if (__DEV__) { tag, props, hostContext, - extraAttributes + extraAttributes, + serverDifferences ); } @@ -43941,73 +44233,49 @@ if (__DEV__) { extraAttributes.size > 0 && props.suppressHydrationWarning !== true ) { - warnForExtraAttributes(extraAttributes); + warnForExtraAttributes( + domElement, + extraAttributes, + serverDifferences + ); } } - } - function diffHydratedText(textNode, text) { - var isDifferent = textNode.nodeValue !== text; - return isDifferent; - } - function warnForDeletedHydratableElement(parentNode, child) { - { - if (didWarnInvalidHydration) { - return; - } - - didWarnInvalidHydration = true; - error( - "Did not expect server HTML to contain a <%s> in <%s>.", - child.nodeName.toLowerCase(), - parentNode.nodeName.toLowerCase() - ); + if (Object.keys(serverDifferences).length === 0) { + return null; } - } - function warnForDeletedHydratableText(parentNode, child) { - { - if (didWarnInvalidHydration) { - return; - } - - didWarnInvalidHydration = true; - error( - 'Did not expect server HTML to contain the text node "%s" in <%s>.', - child.nodeValue, - parentNode.nodeName.toLowerCase() - ); - } + return serverDifferences; } - function warnForInsertedHydratedElement(parentNode, tag, props) { - { - if (didWarnInvalidHydration) { - return; - } - - didWarnInvalidHydration = true; + function hydrateText(textNode, text, parentProps) { + var isDifferent = textNode.nodeValue !== text; - error( - "Expected server HTML to contain a matching <%s> in <%s>.", - tag, - parentNode.nodeName.toLowerCase() - ); + if ( + isDifferent && + (parentProps === null || + parentProps.suppressHydrationWarning !== true) && + !checkForUnmatchedText(textNode.nodeValue, text) + ) { + return false; } + + return true; } - function warnForInsertedHydratedText(parentNode, text) { - { - if (didWarnInvalidHydration) { - return; - } + function diffHydratedText(textNode, text) { + if (textNode.nodeValue === text) { + return null; + } - didWarnInvalidHydration = true; + var normalizedClientText = normalizeMarkupForTextOrAttribute(text); + var normalizedServerText = normalizeMarkupForTextOrAttribute( + textNode.nodeValue + ); - error( - 'Expected server HTML to contain a matching text node for "%s" in <%s>.', - text, - parentNode.nodeName.toLowerCase() - ); + if (normalizedServerText === normalizedClientText) { + return null; } + + return textNode.nodeValue; } function restoreControlledState(domElement, tag, props) { switch (tag) { @@ -45153,6 +45421,23 @@ if (__DEV__) { function getFirstHydratableChildWithinSuspenseInstance(parentInstance) { return getNextHydratable(parentInstance.nextSibling); } + function describeHydratableInstanceForDevWarnings(instance) { + // Reverse engineer a pseudo react-element from hydratable instnace + if (instance.nodeType === ELEMENT_NODE) { + // Reverse engineer a set of props that can print for dev warnings + return { + type: instance.nodeName.toLowerCase(), + props: getPropsFromElement(instance) + }; + } else if (instance.nodeType === COMMENT_NODE) { + return { + type: "Suspense", + props: {} + }; + } else { + return instance.nodeValue; + } + } function validateHydratableInstance(type, props, hostContext) { { // TODO: take namespace into account when validating. @@ -45165,14 +45450,22 @@ if (__DEV__) { type, props, hostContext, - internalInstanceHandle, - shouldWarnDev + internalInstanceHandle ) { precacheFiberNode(internalInstanceHandle, instance); // TODO: Possibly defer this until the commit phase where all the events // get attached. updateFiberProps(instance, props); - diffHydratedProperties(instance, type, props, shouldWarnDev, hostContext); + return hydrateProperties(instance, type, props); + } // Returns a Map of properties that were different on the server. + + function diffHydratedPropsForDevWarnings( + instance, + type, + props, + hostContext + ) { + return diffHydratedProperties(instance, type, props, hostContext); } function validateHydratableTextInstance(text, hostContext) { { @@ -45190,10 +45483,21 @@ if (__DEV__) { textInstance, text, internalInstanceHandle, - shouldWarnDev + parentInstanceProps ) { precacheFiberNode(internalInstanceHandle, textInstance); - return diffHydratedText(textInstance, text); + return hydrateText(textInstance, text, parentInstanceProps); + } // Returns the server text if it differs from the client. + + function diffHydratedTextForDevWarnings(textInstance, text, parentProps) { + if ( + parentProps === null || + parentProps[SUPPRESS_HYDRATION_WARNING] !== true + ) { + return diffHydratedText(textInstance, text); + } + + return null; } function hydrateSuspenseInstance(suspenseInstance, internalInstanceHandle) { precacheFiberNode(internalInstanceHandle, suspenseInstance); @@ -45273,139 +45577,6 @@ if (__DEV__) { } function shouldDeleteUnhydratedTailInstances(parentType) { return parentType !== "form" && parentType !== "button"; - } - function didNotMatchHydratedContainerTextInstance( - parentContainer, - textInstance, - text, - shouldWarnDev - ) { - checkForUnmatchedText(textInstance.nodeValue, text, shouldWarnDev); - } - function didNotMatchHydratedTextInstance( - parentType, - parentProps, - parentInstance, - textInstance, - text, - shouldWarnDev - ) { - if (parentProps[SUPPRESS_HYDRATION_WARNING] !== true) { - checkForUnmatchedText(textInstance.nodeValue, text, shouldWarnDev); - } - } - function didNotHydrateInstanceWithinContainer(parentContainer, instance) { - { - if (instance.nodeType === ELEMENT_NODE) { - warnForDeletedHydratableElement(parentContainer, instance); - } else if (instance.nodeType === COMMENT_NODE); - else { - warnForDeletedHydratableText(parentContainer, instance); - } - } - } - function didNotHydrateInstanceWithinSuspenseInstance( - parentInstance, - instance - ) { - { - // $FlowFixMe[incompatible-type]: Only Element or Document can be parent nodes. - var parentNode = parentInstance.parentNode; - - if (parentNode !== null) { - if (instance.nodeType === ELEMENT_NODE) { - warnForDeletedHydratableElement(parentNode, instance); - } else if (instance.nodeType === COMMENT_NODE); - else { - warnForDeletedHydratableText(parentNode, instance); - } - } - } - } - function didNotHydrateInstance( - parentType, - parentProps, - parentInstance, - instance - ) { - { - if (instance.nodeType === ELEMENT_NODE) { - warnForDeletedHydratableElement(parentInstance, instance); - } else if (instance.nodeType === COMMENT_NODE); - else { - warnForDeletedHydratableText(parentInstance, instance); - } - } - } - function didNotFindHydratableInstanceWithinContainer( - parentContainer, - type, - props - ) { - { - warnForInsertedHydratedElement(parentContainer, type); - } - } - function didNotFindHydratableTextInstanceWithinContainer( - parentContainer, - text - ) { - { - warnForInsertedHydratedText(parentContainer, text); - } - } - function didNotFindHydratableInstanceWithinSuspenseInstance( - parentInstance, - type, - props - ) { - { - // $FlowFixMe[incompatible-type]: Only Element or Document can be parent nodes. - var parentNode = parentInstance.parentNode; - if (parentNode !== null) - warnForInsertedHydratedElement(parentNode, type); - } - } - function didNotFindHydratableTextInstanceWithinSuspenseInstance( - parentInstance, - text - ) { - { - // $FlowFixMe[incompatible-type]: Only Element or Document can be parent nodes. - var parentNode = parentInstance.parentNode; - if (parentNode !== null) warnForInsertedHydratedText(parentNode, text); - } - } - function didNotFindHydratableInstance( - parentType, - parentProps, - parentInstance, - type, - props - ) { - { - warnForInsertedHydratedElement(parentInstance, type); - } - } - function didNotFindHydratableTextInstance( - parentType, - parentProps, - parentInstance, - text - ) { - { - warnForInsertedHydratedText(parentInstance, text); - } - } - function errorHydratingContainer(parentContainer) { - { - // TODO: This gets logged by onRecoverableError, too, so we should be - // able to remove it. - error( - "An error occurred during hydration. The server HTML was replaced with client content in <%s>.", - parentContainer.nodeName.toLowerCase() - ); - } } // ------------------- function requestPostPaintCallback(callback) { localRequestAnimationFrame(function () { diff --git a/compiled/facebook-www/ReactDOM-prod.classic.js b/compiled/facebook-www/ReactDOM-prod.classic.js index ec771986c07d2..35f6f3c4c228c 100644 --- a/compiled/facebook-www/ReactDOM-prod.classic.js +++ b/compiled/facebook-www/ReactDOM-prod.classic.js @@ -1707,6 +1707,76 @@ var hydrationParentFiber = null, function throwOnHydrationMismatch() { throw Error(formatProdErrorMessage(418)); } +function prepareToHydrateHostInstance(fiber) { + var instance = fiber.stateNode, + type = fiber.type, + props = fiber.memoizedProps; + instance[internalInstanceKey] = fiber; + instance[internalPropsKey] = props; + switch (type) { + case "dialog": + listenToNonDelegatedEvent("cancel", instance); + listenToNonDelegatedEvent("close", instance); + break; + case "iframe": + case "object": + case "embed": + listenToNonDelegatedEvent("load", instance); + break; + case "video": + case "audio": + for (fiber = 0; fiber < mediaEventTypes.length; fiber++) + listenToNonDelegatedEvent(mediaEventTypes[fiber], instance); + break; + case "source": + listenToNonDelegatedEvent("error", instance); + break; + case "img": + case "image": + case "link": + listenToNonDelegatedEvent("error", instance); + listenToNonDelegatedEvent("load", instance); + break; + case "details": + listenToNonDelegatedEvent("toggle", instance); + break; + case "input": + listenToNonDelegatedEvent("invalid", instance); + initInput( + instance, + props.value, + props.defaultValue, + props.checked, + props.defaultChecked, + props.type, + props.name, + !0 + ); + track(instance); + break; + case "select": + listenToNonDelegatedEvent("invalid", instance); + break; + case "textarea": + listenToNonDelegatedEvent("invalid", instance), + initTextarea(instance, props.value, props.defaultValue, props.children), + track(instance); + } + fiber = props.children; + ("string" === typeof fiber || + "number" === typeof fiber || + (enableBigIntSupport && "bigint" === typeof fiber)) && + instance.textContent !== "" + fiber && + !0 !== props.suppressHydrationWarning && + !checkForUnmatchedText(instance.textContent, fiber) + ? (instance = !1) + : (null != props.onScroll && listenToNonDelegatedEvent("scroll", instance), + null != props.onScrollEnd && + listenToNonDelegatedEvent("scrollend", instance), + null != props.onClick && (instance.onclick = noop$2), + (instance = !0)); + if (!instance) throw Error(formatProdErrorMessage(425)); +} function popToNextHostParent(fiber) { for (hydrationParentFiber = fiber.return; hydrationParentFiber; ) switch (hydrationParentFiber.tag) { @@ -7784,13 +7854,7 @@ function completeWork(current, workInProgress, renderLanes) { } current = contextStackCursor$1.current; popHydrationState(workInProgress) - ? hydrateInstance( - workInProgress.stateNode, - workInProgress.type, - workInProgress.memoizedProps, - current, - workInProgress - ) + ? prepareToHydrateHostInstance(workInProgress, current) : ((current = resolveSingletonInstance( currentResource, newProps, @@ -7815,13 +7879,7 @@ function completeWork(current, workInProgress, renderLanes) { } current = contextStackCursor$1.current; if (popHydrationState(workInProgress)) - hydrateInstance( - workInProgress.stateNode, - workInProgress.type, - workInProgress.memoizedProps, - current, - workInProgress - ); + prepareToHydrateHostInstance(workInProgress, current); else { currentResource = getOwnerDocumentFromRootContainer( rootInstanceStackCursor.current @@ -7938,22 +7996,24 @@ function completeWork(current, workInProgress, renderLanes) { throw Error(formatProdErrorMessage(166)); current = rootInstanceStackCursor.current; if (popHydrationState(workInProgress)) { - if ( - ((current = workInProgress.stateNode), - (renderLanes = workInProgress.memoizedProps), - (current[internalInstanceKey] = workInProgress), - current.nodeValue !== renderLanes && - ((newProps = hydrationParentFiber), null !== newProps)) - ) - switch (newProps.tag) { - case 3: - checkForUnmatchedText(current.nodeValue, renderLanes); - break; + current = workInProgress.stateNode; + renderLanes = workInProgress.memoizedProps; + newProps = null; + currentResource = hydrationParentFiber; + if (null !== currentResource) + switch (currentResource.tag) { case 27: case 5: - !0 !== newProps.memoizedProps.suppressHydrationWarning && - checkForUnmatchedText(current.nodeValue, renderLanes); + newProps = currentResource.memoizedProps; } + current[internalInstanceKey] = workInProgress; + current = + current.nodeValue === renderLanes || + (null !== newProps && !0 === newProps.suppressHydrationWarning) || + checkForUnmatchedText(current.nodeValue, renderLanes) + ? !0 + : !1; + if (!current) throw Error(formatProdErrorMessage(425)); } else (current = getOwnerDocumentFromRootContainer(current).createTextNode( @@ -12989,14 +13049,14 @@ var isInputEventSupported = !1; if (canUseDOM) { var JSCompiler_inline_result$jscomp$344; if (canUseDOM) { - var isSupported$jscomp$inline_1514 = "oninput" in document; - if (!isSupported$jscomp$inline_1514) { - var element$jscomp$inline_1515 = document.createElement("div"); - element$jscomp$inline_1515.setAttribute("oninput", "return;"); - isSupported$jscomp$inline_1514 = - "function" === typeof element$jscomp$inline_1515.oninput; + var isSupported$jscomp$inline_1505 = "oninput" in document; + if (!isSupported$jscomp$inline_1505) { + var element$jscomp$inline_1506 = document.createElement("div"); + element$jscomp$inline_1506.setAttribute("oninput", "return;"); + isSupported$jscomp$inline_1505 = + "function" === typeof element$jscomp$inline_1506.oninput; } - JSCompiler_inline_result$jscomp$344 = isSupported$jscomp$inline_1514; + JSCompiler_inline_result$jscomp$344 = isSupported$jscomp$inline_1505; } else JSCompiler_inline_result$jscomp$344 = !1; isInputEventSupported = JSCompiler_inline_result$jscomp$344 && @@ -13371,20 +13431,20 @@ function extractEvents$1( } } for ( - var i$jscomp$inline_1555 = 0; - i$jscomp$inline_1555 < simpleEventPluginEvents.length; - i$jscomp$inline_1555++ + var i$jscomp$inline_1546 = 0; + i$jscomp$inline_1546 < simpleEventPluginEvents.length; + i$jscomp$inline_1546++ ) { - var eventName$jscomp$inline_1556 = - simpleEventPluginEvents[i$jscomp$inline_1555], - domEventName$jscomp$inline_1557 = - eventName$jscomp$inline_1556.toLowerCase(), - capitalizedEvent$jscomp$inline_1558 = - eventName$jscomp$inline_1556[0].toUpperCase() + - eventName$jscomp$inline_1556.slice(1); + var eventName$jscomp$inline_1547 = + simpleEventPluginEvents[i$jscomp$inline_1546], + domEventName$jscomp$inline_1548 = + eventName$jscomp$inline_1547.toLowerCase(), + capitalizedEvent$jscomp$inline_1549 = + eventName$jscomp$inline_1547[0].toUpperCase() + + eventName$jscomp$inline_1547.slice(1); registerSimpleEvent( - domEventName$jscomp$inline_1557, - "on" + capitalizedEvent$jscomp$inline_1558 + domEventName$jscomp$inline_1548, + "on" + capitalizedEvent$jscomp$inline_1549 ); } registerSimpleEvent(ANIMATION_END, "onAnimationEnd"); @@ -14232,8 +14292,7 @@ function normalizeMarkupForTextOrAttribute(markup) { } function checkForUnmatchedText(serverText, clientText) { clientText = normalizeMarkupForTextOrAttribute(clientText); - if (normalizeMarkupForTextOrAttribute(serverText) !== clientText) - throw Error(formatProdErrorMessage(425)); + return normalizeMarkupForTextOrAttribute(serverText) === clientText ? !0 : !1; } function noop$2() {} function setProp(domElement, tag, key, value, props, prevValue) { @@ -15431,75 +15490,6 @@ function getNextHydratable(node) { } return node; } -function hydrateInstance( - instance, - type, - props, - hostContext, - internalInstanceHandle -) { - instance[internalInstanceKey] = internalInstanceHandle; - instance[internalPropsKey] = props; - switch (type) { - case "dialog": - listenToNonDelegatedEvent("cancel", instance); - listenToNonDelegatedEvent("close", instance); - break; - case "iframe": - case "object": - case "embed": - listenToNonDelegatedEvent("load", instance); - break; - case "video": - case "audio": - for (type = 0; type < mediaEventTypes.length; type++) - listenToNonDelegatedEvent(mediaEventTypes[type], instance); - break; - case "source": - listenToNonDelegatedEvent("error", instance); - break; - case "img": - case "image": - case "link": - listenToNonDelegatedEvent("error", instance); - listenToNonDelegatedEvent("load", instance); - break; - case "details": - listenToNonDelegatedEvent("toggle", instance); - break; - case "input": - listenToNonDelegatedEvent("invalid", instance); - initInput( - instance, - props.value, - props.defaultValue, - props.checked, - props.defaultChecked, - props.type, - props.name, - !0 - ); - track(instance); - break; - case "select": - listenToNonDelegatedEvent("invalid", instance); - break; - case "textarea": - listenToNonDelegatedEvent("invalid", instance), - initTextarea(instance, props.value, props.defaultValue, props.children), - track(instance); - } - type = props.children; - ("string" === typeof type || - "number" === typeof type || - (enableBigIntSupport && "bigint" === typeof type)) && - instance.textContent !== "" + type && - !0 !== props.suppressHydrationWarning && - checkForUnmatchedText(instance.textContent, type); - null != props.onScroll && listenToNonDelegatedEvent("scroll", instance); - null != props.onScrollEnd && listenToNonDelegatedEvent("scrollend", instance); - null != props.onClick && (instance.onclick = noop$2); -} function getParentSuspenseInstance(targetInstance) { targetInstance = targetInstance.previousSibling; for (var depth = 0; targetInstance; ) { @@ -17091,17 +17081,17 @@ Internals.Events = [ restoreStateIfNeeded, batchedUpdates$1 ]; -var devToolsConfig$jscomp$inline_1778 = { +var devToolsConfig$jscomp$inline_1762 = { findFiberByHostInstance: getClosestInstanceFromNode, bundleType: 0, - version: "19.0.0-www-classic-d89e0697", + version: "19.0.0-www-classic-e05da639", rendererPackageName: "react-dom" }; -var internals$jscomp$inline_2171 = { - bundleType: devToolsConfig$jscomp$inline_1778.bundleType, - version: devToolsConfig$jscomp$inline_1778.version, - rendererPackageName: devToolsConfig$jscomp$inline_1778.rendererPackageName, - rendererConfig: devToolsConfig$jscomp$inline_1778.rendererConfig, +var internals$jscomp$inline_2147 = { + bundleType: devToolsConfig$jscomp$inline_1762.bundleType, + version: devToolsConfig$jscomp$inline_1762.version, + rendererPackageName: devToolsConfig$jscomp$inline_1762.rendererPackageName, + rendererConfig: devToolsConfig$jscomp$inline_1762.rendererConfig, overrideHookState: null, overrideHookStateDeletePath: null, overrideHookStateRenamePath: null, @@ -17117,26 +17107,26 @@ var internals$jscomp$inline_2171 = { return null === fiber ? null : fiber.stateNode; }, findFiberByHostInstance: - devToolsConfig$jscomp$inline_1778.findFiberByHostInstance || + devToolsConfig$jscomp$inline_1762.findFiberByHostInstance || emptyFindFiberByHostInstance, findHostInstancesForRefresh: null, scheduleRefresh: null, scheduleRoot: null, setRefreshHandler: null, getCurrentFiber: null, - reconcilerVersion: "19.0.0-www-classic-d89e0697" + reconcilerVersion: "19.0.0-www-classic-e05da639" }; if ("undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__) { - var hook$jscomp$inline_2172 = __REACT_DEVTOOLS_GLOBAL_HOOK__; + var hook$jscomp$inline_2148 = __REACT_DEVTOOLS_GLOBAL_HOOK__; if ( - !hook$jscomp$inline_2172.isDisabled && - hook$jscomp$inline_2172.supportsFiber + !hook$jscomp$inline_2148.isDisabled && + hook$jscomp$inline_2148.supportsFiber ) try { - (rendererID = hook$jscomp$inline_2172.inject( - internals$jscomp$inline_2171 + (rendererID = hook$jscomp$inline_2148.inject( + internals$jscomp$inline_2147 )), - (injectedHook = hook$jscomp$inline_2172); + (injectedHook = hook$jscomp$inline_2148); } catch (err) {} } assign(Internals, { @@ -17444,4 +17434,4 @@ exports.useFormState = function (action, initialState, permalink) { exports.useFormStatus = function () { return ReactCurrentDispatcher$2.current.useHostTransitionStatus(); }; -exports.version = "19.0.0-www-classic-d89e0697"; +exports.version = "19.0.0-www-classic-e05da639"; diff --git a/compiled/facebook-www/ReactDOM-prod.modern.js b/compiled/facebook-www/ReactDOM-prod.modern.js index fca1a41a8a02a..3ac49c0d8accf 100644 --- a/compiled/facebook-www/ReactDOM-prod.modern.js +++ b/compiled/facebook-www/ReactDOM-prod.modern.js @@ -1601,6 +1601,76 @@ var hydrationParentFiber = null, function throwOnHydrationMismatch() { throw Error(formatProdErrorMessage(418)); } +function prepareToHydrateHostInstance(fiber) { + var instance = fiber.stateNode, + type = fiber.type, + props = fiber.memoizedProps; + instance[internalInstanceKey] = fiber; + instance[internalPropsKey] = props; + switch (type) { + case "dialog": + listenToNonDelegatedEvent("cancel", instance); + listenToNonDelegatedEvent("close", instance); + break; + case "iframe": + case "object": + case "embed": + listenToNonDelegatedEvent("load", instance); + break; + case "video": + case "audio": + for (fiber = 0; fiber < mediaEventTypes.length; fiber++) + listenToNonDelegatedEvent(mediaEventTypes[fiber], instance); + break; + case "source": + listenToNonDelegatedEvent("error", instance); + break; + case "img": + case "image": + case "link": + listenToNonDelegatedEvent("error", instance); + listenToNonDelegatedEvent("load", instance); + break; + case "details": + listenToNonDelegatedEvent("toggle", instance); + break; + case "input": + listenToNonDelegatedEvent("invalid", instance); + initInput( + instance, + props.value, + props.defaultValue, + props.checked, + props.defaultChecked, + props.type, + props.name, + !0 + ); + track(instance); + break; + case "select": + listenToNonDelegatedEvent("invalid", instance); + break; + case "textarea": + listenToNonDelegatedEvent("invalid", instance), + initTextarea(instance, props.value, props.defaultValue), + track(instance); + } + fiber = props.children; + ("string" === typeof fiber || + "number" === typeof fiber || + (enableBigIntSupport && "bigint" === typeof fiber)) && + instance.textContent !== "" + fiber && + !0 !== props.suppressHydrationWarning && + !checkForUnmatchedText(instance.textContent, fiber) + ? (instance = !1) + : (null != props.onScroll && listenToNonDelegatedEvent("scroll", instance), + null != props.onScrollEnd && + listenToNonDelegatedEvent("scrollend", instance), + null != props.onClick && (instance.onclick = noop$1), + (instance = !0)); + if (!instance) throw Error(formatProdErrorMessage(425)); +} function popToNextHostParent(fiber) { for (hydrationParentFiber = fiber.return; hydrationParentFiber; ) switch (hydrationParentFiber.tag) { @@ -7597,13 +7667,7 @@ function completeWork(current, workInProgress, renderLanes) { } current = contextStackCursor.current; popHydrationState(workInProgress) - ? hydrateInstance( - workInProgress.stateNode, - workInProgress.type, - workInProgress.memoizedProps, - current, - workInProgress - ) + ? prepareToHydrateHostInstance(workInProgress, current) : ((current = resolveSingletonInstance( currentResource, newProps, @@ -7628,13 +7692,7 @@ function completeWork(current, workInProgress, renderLanes) { } current = contextStackCursor.current; if (popHydrationState(workInProgress)) - hydrateInstance( - workInProgress.stateNode, - workInProgress.type, - workInProgress.memoizedProps, - current, - workInProgress - ); + prepareToHydrateHostInstance(workInProgress, current); else { currentResource = getOwnerDocumentFromRootContainer( rootInstanceStackCursor.current @@ -7751,22 +7809,24 @@ function completeWork(current, workInProgress, renderLanes) { throw Error(formatProdErrorMessage(166)); current = rootInstanceStackCursor.current; if (popHydrationState(workInProgress)) { - if ( - ((current = workInProgress.stateNode), - (renderLanes = workInProgress.memoizedProps), - (current[internalInstanceKey] = workInProgress), - current.nodeValue !== renderLanes && - ((newProps = hydrationParentFiber), null !== newProps)) - ) - switch (newProps.tag) { - case 3: - checkForUnmatchedText(current.nodeValue, renderLanes); - break; + current = workInProgress.stateNode; + renderLanes = workInProgress.memoizedProps; + newProps = null; + currentResource = hydrationParentFiber; + if (null !== currentResource) + switch (currentResource.tag) { case 27: case 5: - !0 !== newProps.memoizedProps.suppressHydrationWarning && - checkForUnmatchedText(current.nodeValue, renderLanes); + newProps = currentResource.memoizedProps; } + current[internalInstanceKey] = workInProgress; + current = + current.nodeValue === renderLanes || + (null !== newProps && !0 === newProps.suppressHydrationWarning) || + checkForUnmatchedText(current.nodeValue, renderLanes) + ? !0 + : !1; + if (!current) throw Error(formatProdErrorMessage(425)); } else (current = getOwnerDocumentFromRootContainer(current).createTextNode( @@ -13356,14 +13416,14 @@ var isInputEventSupported = !1; if (canUseDOM) { var JSCompiler_inline_result$jscomp$342; if (canUseDOM) { - var isSupported$jscomp$inline_1514 = "oninput" in document; - if (!isSupported$jscomp$inline_1514) { - var element$jscomp$inline_1515 = document.createElement("div"); - element$jscomp$inline_1515.setAttribute("oninput", "return;"); - isSupported$jscomp$inline_1514 = - "function" === typeof element$jscomp$inline_1515.oninput; + var isSupported$jscomp$inline_1505 = "oninput" in document; + if (!isSupported$jscomp$inline_1505) { + var element$jscomp$inline_1506 = document.createElement("div"); + element$jscomp$inline_1506.setAttribute("oninput", "return;"); + isSupported$jscomp$inline_1505 = + "function" === typeof element$jscomp$inline_1506.oninput; } - JSCompiler_inline_result$jscomp$342 = isSupported$jscomp$inline_1514; + JSCompiler_inline_result$jscomp$342 = isSupported$jscomp$inline_1505; } else JSCompiler_inline_result$jscomp$342 = !1; isInputEventSupported = JSCompiler_inline_result$jscomp$342 && @@ -13675,20 +13735,20 @@ function registerSimpleEvent(domEventName, reactName) { registerTwoPhaseEvent(reactName, [domEventName]); } for ( - var i$jscomp$inline_1555 = 0; - i$jscomp$inline_1555 < simpleEventPluginEvents.length; - i$jscomp$inline_1555++ + var i$jscomp$inline_1546 = 0; + i$jscomp$inline_1546 < simpleEventPluginEvents.length; + i$jscomp$inline_1546++ ) { - var eventName$jscomp$inline_1556 = - simpleEventPluginEvents[i$jscomp$inline_1555], - domEventName$jscomp$inline_1557 = - eventName$jscomp$inline_1556.toLowerCase(), - capitalizedEvent$jscomp$inline_1558 = - eventName$jscomp$inline_1556[0].toUpperCase() + - eventName$jscomp$inline_1556.slice(1); + var eventName$jscomp$inline_1547 = + simpleEventPluginEvents[i$jscomp$inline_1546], + domEventName$jscomp$inline_1548 = + eventName$jscomp$inline_1547.toLowerCase(), + capitalizedEvent$jscomp$inline_1549 = + eventName$jscomp$inline_1547[0].toUpperCase() + + eventName$jscomp$inline_1547.slice(1); registerSimpleEvent( - domEventName$jscomp$inline_1557, - "on" + capitalizedEvent$jscomp$inline_1558 + domEventName$jscomp$inline_1548, + "on" + capitalizedEvent$jscomp$inline_1549 ); } registerSimpleEvent(ANIMATION_END, "onAnimationEnd"); @@ -14536,8 +14596,7 @@ function normalizeMarkupForTextOrAttribute(markup) { } function checkForUnmatchedText(serverText, clientText) { clientText = normalizeMarkupForTextOrAttribute(clientText); - if (normalizeMarkupForTextOrAttribute(serverText) !== clientText) - throw Error(formatProdErrorMessage(425)); + return normalizeMarkupForTextOrAttribute(serverText) === clientText ? !0 : !1; } function noop$1() {} function setProp(domElement, tag, key, value, props, prevValue) { @@ -15704,75 +15763,6 @@ function getNextHydratable(node) { } return node; } -function hydrateInstance( - instance, - type, - props, - hostContext, - internalInstanceHandle -) { - instance[internalInstanceKey] = internalInstanceHandle; - instance[internalPropsKey] = props; - switch (type) { - case "dialog": - listenToNonDelegatedEvent("cancel", instance); - listenToNonDelegatedEvent("close", instance); - break; - case "iframe": - case "object": - case "embed": - listenToNonDelegatedEvent("load", instance); - break; - case "video": - case "audio": - for (type = 0; type < mediaEventTypes.length; type++) - listenToNonDelegatedEvent(mediaEventTypes[type], instance); - break; - case "source": - listenToNonDelegatedEvent("error", instance); - break; - case "img": - case "image": - case "link": - listenToNonDelegatedEvent("error", instance); - listenToNonDelegatedEvent("load", instance); - break; - case "details": - listenToNonDelegatedEvent("toggle", instance); - break; - case "input": - listenToNonDelegatedEvent("invalid", instance); - initInput( - instance, - props.value, - props.defaultValue, - props.checked, - props.defaultChecked, - props.type, - props.name, - !0 - ); - track(instance); - break; - case "select": - listenToNonDelegatedEvent("invalid", instance); - break; - case "textarea": - listenToNonDelegatedEvent("invalid", instance), - initTextarea(instance, props.value, props.defaultValue), - track(instance); - } - type = props.children; - ("string" === typeof type || - "number" === typeof type || - (enableBigIntSupport && "bigint" === typeof type)) && - instance.textContent !== "" + type && - !0 !== props.suppressHydrationWarning && - checkForUnmatchedText(instance.textContent, type); - null != props.onScroll && listenToNonDelegatedEvent("scroll", instance); - null != props.onScrollEnd && listenToNonDelegatedEvent("scrollend", instance); - null != props.onClick && (instance.onclick = noop$1); -} function getParentSuspenseInstance(targetInstance) { targetInstance = targetInstance.previousSibling; for (var depth = 0; targetInstance; ) { @@ -16607,17 +16597,17 @@ Internals.Events = [ restoreStateIfNeeded, batchedUpdates$1 ]; -var devToolsConfig$jscomp$inline_1737 = { +var devToolsConfig$jscomp$inline_1721 = { findFiberByHostInstance: getClosestInstanceFromNode, bundleType: 0, - version: "19.0.0-www-modern-321f8c10", + version: "19.0.0-www-modern-646a2e2d", rendererPackageName: "react-dom" }; -var internals$jscomp$inline_2135 = { - bundleType: devToolsConfig$jscomp$inline_1737.bundleType, - version: devToolsConfig$jscomp$inline_1737.version, - rendererPackageName: devToolsConfig$jscomp$inline_1737.rendererPackageName, - rendererConfig: devToolsConfig$jscomp$inline_1737.rendererConfig, +var internals$jscomp$inline_2111 = { + bundleType: devToolsConfig$jscomp$inline_1721.bundleType, + version: devToolsConfig$jscomp$inline_1721.version, + rendererPackageName: devToolsConfig$jscomp$inline_1721.rendererPackageName, + rendererConfig: devToolsConfig$jscomp$inline_1721.rendererConfig, overrideHookState: null, overrideHookStateDeletePath: null, overrideHookStateRenamePath: null, @@ -16634,26 +16624,26 @@ var internals$jscomp$inline_2135 = { return null === fiber ? null : fiber.stateNode; }, findFiberByHostInstance: - devToolsConfig$jscomp$inline_1737.findFiberByHostInstance || + devToolsConfig$jscomp$inline_1721.findFiberByHostInstance || emptyFindFiberByHostInstance, findHostInstancesForRefresh: null, scheduleRefresh: null, scheduleRoot: null, setRefreshHandler: null, getCurrentFiber: null, - reconcilerVersion: "19.0.0-www-modern-321f8c10" + reconcilerVersion: "19.0.0-www-modern-646a2e2d" }; if ("undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__) { - var hook$jscomp$inline_2136 = __REACT_DEVTOOLS_GLOBAL_HOOK__; + var hook$jscomp$inline_2112 = __REACT_DEVTOOLS_GLOBAL_HOOK__; if ( - !hook$jscomp$inline_2136.isDisabled && - hook$jscomp$inline_2136.supportsFiber + !hook$jscomp$inline_2112.isDisabled && + hook$jscomp$inline_2112.supportsFiber ) try { - (rendererID = hook$jscomp$inline_2136.inject( - internals$jscomp$inline_2135 + (rendererID = hook$jscomp$inline_2112.inject( + internals$jscomp$inline_2111 )), - (injectedHook = hook$jscomp$inline_2136); + (injectedHook = hook$jscomp$inline_2112); } catch (err) {} } exports.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED = Internals; @@ -16900,4 +16890,4 @@ exports.useFormState = function (action, initialState, permalink) { exports.useFormStatus = function () { return ReactCurrentDispatcher$2.current.useHostTransitionStatus(); }; -exports.version = "19.0.0-www-modern-321f8c10"; +exports.version = "19.0.0-www-modern-646a2e2d"; diff --git a/compiled/facebook-www/ReactDOM-profiling.classic.js b/compiled/facebook-www/ReactDOM-profiling.classic.js index 7d8a6279a3dfd..d56172c8ccb3c 100644 --- a/compiled/facebook-www/ReactDOM-profiling.classic.js +++ b/compiled/facebook-www/ReactDOM-profiling.classic.js @@ -1843,6 +1843,76 @@ var hydrationParentFiber = null, function throwOnHydrationMismatch() { throw Error(formatProdErrorMessage(418)); } +function prepareToHydrateHostInstance(fiber) { + var instance = fiber.stateNode, + type = fiber.type, + props = fiber.memoizedProps; + instance[internalInstanceKey] = fiber; + instance[internalPropsKey] = props; + switch (type) { + case "dialog": + listenToNonDelegatedEvent("cancel", instance); + listenToNonDelegatedEvent("close", instance); + break; + case "iframe": + case "object": + case "embed": + listenToNonDelegatedEvent("load", instance); + break; + case "video": + case "audio": + for (fiber = 0; fiber < mediaEventTypes.length; fiber++) + listenToNonDelegatedEvent(mediaEventTypes[fiber], instance); + break; + case "source": + listenToNonDelegatedEvent("error", instance); + break; + case "img": + case "image": + case "link": + listenToNonDelegatedEvent("error", instance); + listenToNonDelegatedEvent("load", instance); + break; + case "details": + listenToNonDelegatedEvent("toggle", instance); + break; + case "input": + listenToNonDelegatedEvent("invalid", instance); + initInput( + instance, + props.value, + props.defaultValue, + props.checked, + props.defaultChecked, + props.type, + props.name, + !0 + ); + track(instance); + break; + case "select": + listenToNonDelegatedEvent("invalid", instance); + break; + case "textarea": + listenToNonDelegatedEvent("invalid", instance), + initTextarea(instance, props.value, props.defaultValue, props.children), + track(instance); + } + fiber = props.children; + ("string" === typeof fiber || + "number" === typeof fiber || + (enableBigIntSupport && "bigint" === typeof fiber)) && + instance.textContent !== "" + fiber && + !0 !== props.suppressHydrationWarning && + !checkForUnmatchedText(instance.textContent, fiber) + ? (instance = !1) + : (null != props.onScroll && listenToNonDelegatedEvent("scroll", instance), + null != props.onScrollEnd && + listenToNonDelegatedEvent("scrollend", instance), + null != props.onClick && (instance.onclick = noop$2), + (instance = !0)); + if (!instance) throw Error(formatProdErrorMessage(425)); +} function popToNextHostParent(fiber) { for (hydrationParentFiber = fiber.return; hydrationParentFiber; ) switch (hydrationParentFiber.tag) { @@ -8072,13 +8142,7 @@ function completeWork(current, workInProgress, renderLanes) { } current = contextStackCursor$1.current; popHydrationState(workInProgress) - ? hydrateInstance( - workInProgress.stateNode, - workInProgress.type, - workInProgress.memoizedProps, - current, - workInProgress - ) + ? prepareToHydrateHostInstance(workInProgress, current) : ((current = resolveSingletonInstance( currentResource, newProps, @@ -8103,13 +8167,7 @@ function completeWork(current, workInProgress, renderLanes) { } current = contextStackCursor$1.current; if (popHydrationState(workInProgress)) - hydrateInstance( - workInProgress.stateNode, - workInProgress.type, - workInProgress.memoizedProps, - current, - workInProgress - ); + prepareToHydrateHostInstance(workInProgress, current); else { currentResource = getOwnerDocumentFromRootContainer( rootInstanceStackCursor.current @@ -8226,22 +8284,24 @@ function completeWork(current, workInProgress, renderLanes) { throw Error(formatProdErrorMessage(166)); current = rootInstanceStackCursor.current; if (popHydrationState(workInProgress)) { - if ( - ((current = workInProgress.stateNode), - (renderLanes = workInProgress.memoizedProps), - (current[internalInstanceKey] = workInProgress), - current.nodeValue !== renderLanes && - ((newProps = hydrationParentFiber), null !== newProps)) - ) - switch (newProps.tag) { - case 3: - checkForUnmatchedText(current.nodeValue, renderLanes); - break; + current = workInProgress.stateNode; + renderLanes = workInProgress.memoizedProps; + newProps = null; + currentResource = hydrationParentFiber; + if (null !== currentResource) + switch (currentResource.tag) { case 27: case 5: - !0 !== newProps.memoizedProps.suppressHydrationWarning && - checkForUnmatchedText(current.nodeValue, renderLanes); + newProps = currentResource.memoizedProps; } + current[internalInstanceKey] = workInProgress; + current = + current.nodeValue === renderLanes || + (null !== newProps && !0 === newProps.suppressHydrationWarning) || + checkForUnmatchedText(current.nodeValue, renderLanes) + ? !0 + : !1; + if (!current) throw Error(formatProdErrorMessage(425)); } else (current = getOwnerDocumentFromRootContainer(current).createTextNode( @@ -13738,14 +13798,14 @@ var isInputEventSupported = !1; if (canUseDOM) { var JSCompiler_inline_result$jscomp$365; if (canUseDOM) { - var isSupported$jscomp$inline_1599 = "oninput" in document; - if (!isSupported$jscomp$inline_1599) { - var element$jscomp$inline_1600 = document.createElement("div"); - element$jscomp$inline_1600.setAttribute("oninput", "return;"); - isSupported$jscomp$inline_1599 = - "function" === typeof element$jscomp$inline_1600.oninput; + var isSupported$jscomp$inline_1590 = "oninput" in document; + if (!isSupported$jscomp$inline_1590) { + var element$jscomp$inline_1591 = document.createElement("div"); + element$jscomp$inline_1591.setAttribute("oninput", "return;"); + isSupported$jscomp$inline_1590 = + "function" === typeof element$jscomp$inline_1591.oninput; } - JSCompiler_inline_result$jscomp$365 = isSupported$jscomp$inline_1599; + JSCompiler_inline_result$jscomp$365 = isSupported$jscomp$inline_1590; } else JSCompiler_inline_result$jscomp$365 = !1; isInputEventSupported = JSCompiler_inline_result$jscomp$365 && @@ -14120,20 +14180,20 @@ function extractEvents$1( } } for ( - var i$jscomp$inline_1640 = 0; - i$jscomp$inline_1640 < simpleEventPluginEvents.length; - i$jscomp$inline_1640++ + var i$jscomp$inline_1631 = 0; + i$jscomp$inline_1631 < simpleEventPluginEvents.length; + i$jscomp$inline_1631++ ) { - var eventName$jscomp$inline_1641 = - simpleEventPluginEvents[i$jscomp$inline_1640], - domEventName$jscomp$inline_1642 = - eventName$jscomp$inline_1641.toLowerCase(), - capitalizedEvent$jscomp$inline_1643 = - eventName$jscomp$inline_1641[0].toUpperCase() + - eventName$jscomp$inline_1641.slice(1); + var eventName$jscomp$inline_1632 = + simpleEventPluginEvents[i$jscomp$inline_1631], + domEventName$jscomp$inline_1633 = + eventName$jscomp$inline_1632.toLowerCase(), + capitalizedEvent$jscomp$inline_1634 = + eventName$jscomp$inline_1632[0].toUpperCase() + + eventName$jscomp$inline_1632.slice(1); registerSimpleEvent( - domEventName$jscomp$inline_1642, - "on" + capitalizedEvent$jscomp$inline_1643 + domEventName$jscomp$inline_1633, + "on" + capitalizedEvent$jscomp$inline_1634 ); } registerSimpleEvent(ANIMATION_END, "onAnimationEnd"); @@ -14981,8 +15041,7 @@ function normalizeMarkupForTextOrAttribute(markup) { } function checkForUnmatchedText(serverText, clientText) { clientText = normalizeMarkupForTextOrAttribute(clientText); - if (normalizeMarkupForTextOrAttribute(serverText) !== clientText) - throw Error(formatProdErrorMessage(425)); + return normalizeMarkupForTextOrAttribute(serverText) === clientText ? !0 : !1; } function noop$2() {} function setProp(domElement, tag, key, value, props, prevValue) { @@ -16180,75 +16239,6 @@ function getNextHydratable(node) { } return node; } -function hydrateInstance( - instance, - type, - props, - hostContext, - internalInstanceHandle -) { - instance[internalInstanceKey] = internalInstanceHandle; - instance[internalPropsKey] = props; - switch (type) { - case "dialog": - listenToNonDelegatedEvent("cancel", instance); - listenToNonDelegatedEvent("close", instance); - break; - case "iframe": - case "object": - case "embed": - listenToNonDelegatedEvent("load", instance); - break; - case "video": - case "audio": - for (type = 0; type < mediaEventTypes.length; type++) - listenToNonDelegatedEvent(mediaEventTypes[type], instance); - break; - case "source": - listenToNonDelegatedEvent("error", instance); - break; - case "img": - case "image": - case "link": - listenToNonDelegatedEvent("error", instance); - listenToNonDelegatedEvent("load", instance); - break; - case "details": - listenToNonDelegatedEvent("toggle", instance); - break; - case "input": - listenToNonDelegatedEvent("invalid", instance); - initInput( - instance, - props.value, - props.defaultValue, - props.checked, - props.defaultChecked, - props.type, - props.name, - !0 - ); - track(instance); - break; - case "select": - listenToNonDelegatedEvent("invalid", instance); - break; - case "textarea": - listenToNonDelegatedEvent("invalid", instance), - initTextarea(instance, props.value, props.defaultValue, props.children), - track(instance); - } - type = props.children; - ("string" === typeof type || - "number" === typeof type || - (enableBigIntSupport && "bigint" === typeof type)) && - instance.textContent !== "" + type && - !0 !== props.suppressHydrationWarning && - checkForUnmatchedText(instance.textContent, type); - null != props.onScroll && listenToNonDelegatedEvent("scroll", instance); - null != props.onScrollEnd && listenToNonDelegatedEvent("scrollend", instance); - null != props.onClick && (instance.onclick = noop$2); -} function getParentSuspenseInstance(targetInstance) { targetInstance = targetInstance.previousSibling; for (var depth = 0; targetInstance; ) { @@ -17840,10 +17830,10 @@ Internals.Events = [ restoreStateIfNeeded, batchedUpdates$1 ]; -var devToolsConfig$jscomp$inline_1863 = { +var devToolsConfig$jscomp$inline_1847 = { findFiberByHostInstance: getClosestInstanceFromNode, bundleType: 0, - version: "19.0.0-www-classic-c032ccc7", + version: "19.0.0-www-classic-f779e472", rendererPackageName: "react-dom" }; (function (internals) { @@ -17861,10 +17851,10 @@ var devToolsConfig$jscomp$inline_1863 = { } catch (err) {} return hook.checkDCE ? !0 : !1; })({ - bundleType: devToolsConfig$jscomp$inline_1863.bundleType, - version: devToolsConfig$jscomp$inline_1863.version, - rendererPackageName: devToolsConfig$jscomp$inline_1863.rendererPackageName, - rendererConfig: devToolsConfig$jscomp$inline_1863.rendererConfig, + bundleType: devToolsConfig$jscomp$inline_1847.bundleType, + version: devToolsConfig$jscomp$inline_1847.version, + rendererPackageName: devToolsConfig$jscomp$inline_1847.rendererPackageName, + rendererConfig: devToolsConfig$jscomp$inline_1847.rendererConfig, overrideHookState: null, overrideHookStateDeletePath: null, overrideHookStateRenamePath: null, @@ -17880,14 +17870,14 @@ var devToolsConfig$jscomp$inline_1863 = { return null === fiber ? null : fiber.stateNode; }, findFiberByHostInstance: - devToolsConfig$jscomp$inline_1863.findFiberByHostInstance || + devToolsConfig$jscomp$inline_1847.findFiberByHostInstance || emptyFindFiberByHostInstance, findHostInstancesForRefresh: null, scheduleRefresh: null, scheduleRoot: null, setRefreshHandler: null, getCurrentFiber: null, - reconcilerVersion: "19.0.0-www-classic-c032ccc7" + reconcilerVersion: "19.0.0-www-classic-f779e472" }); assign(Internals, { ReactBrowserEventEmitter: { @@ -18194,7 +18184,7 @@ exports.useFormState = function (action, initialState, permalink) { exports.useFormStatus = function () { return ReactCurrentDispatcher$2.current.useHostTransitionStatus(); }; -exports.version = "19.0.0-www-classic-c032ccc7"; +exports.version = "19.0.0-www-classic-f779e472"; "undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ && "function" === typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop && diff --git a/compiled/facebook-www/ReactDOM-profiling.modern.js b/compiled/facebook-www/ReactDOM-profiling.modern.js index 5ed4d21b4b7da..0ccdc8604e1c9 100644 --- a/compiled/facebook-www/ReactDOM-profiling.modern.js +++ b/compiled/facebook-www/ReactDOM-profiling.modern.js @@ -1737,6 +1737,76 @@ var hydrationParentFiber = null, function throwOnHydrationMismatch() { throw Error(formatProdErrorMessage(418)); } +function prepareToHydrateHostInstance(fiber) { + var instance = fiber.stateNode, + type = fiber.type, + props = fiber.memoizedProps; + instance[internalInstanceKey] = fiber; + instance[internalPropsKey] = props; + switch (type) { + case "dialog": + listenToNonDelegatedEvent("cancel", instance); + listenToNonDelegatedEvent("close", instance); + break; + case "iframe": + case "object": + case "embed": + listenToNonDelegatedEvent("load", instance); + break; + case "video": + case "audio": + for (fiber = 0; fiber < mediaEventTypes.length; fiber++) + listenToNonDelegatedEvent(mediaEventTypes[fiber], instance); + break; + case "source": + listenToNonDelegatedEvent("error", instance); + break; + case "img": + case "image": + case "link": + listenToNonDelegatedEvent("error", instance); + listenToNonDelegatedEvent("load", instance); + break; + case "details": + listenToNonDelegatedEvent("toggle", instance); + break; + case "input": + listenToNonDelegatedEvent("invalid", instance); + initInput( + instance, + props.value, + props.defaultValue, + props.checked, + props.defaultChecked, + props.type, + props.name, + !0 + ); + track(instance); + break; + case "select": + listenToNonDelegatedEvent("invalid", instance); + break; + case "textarea": + listenToNonDelegatedEvent("invalid", instance), + initTextarea(instance, props.value, props.defaultValue), + track(instance); + } + fiber = props.children; + ("string" === typeof fiber || + "number" === typeof fiber || + (enableBigIntSupport && "bigint" === typeof fiber)) && + instance.textContent !== "" + fiber && + !0 !== props.suppressHydrationWarning && + !checkForUnmatchedText(instance.textContent, fiber) + ? (instance = !1) + : (null != props.onScroll && listenToNonDelegatedEvent("scroll", instance), + null != props.onScrollEnd && + listenToNonDelegatedEvent("scrollend", instance), + null != props.onClick && (instance.onclick = noop$1), + (instance = !0)); + if (!instance) throw Error(formatProdErrorMessage(425)); +} function popToNextHostParent(fiber) { for (hydrationParentFiber = fiber.return; hydrationParentFiber; ) switch (hydrationParentFiber.tag) { @@ -7879,13 +7949,7 @@ function completeWork(current, workInProgress, renderLanes) { } current = contextStackCursor.current; popHydrationState(workInProgress) - ? hydrateInstance( - workInProgress.stateNode, - workInProgress.type, - workInProgress.memoizedProps, - current, - workInProgress - ) + ? prepareToHydrateHostInstance(workInProgress, current) : ((current = resolveSingletonInstance( currentResource, newProps, @@ -7910,13 +7974,7 @@ function completeWork(current, workInProgress, renderLanes) { } current = contextStackCursor.current; if (popHydrationState(workInProgress)) - hydrateInstance( - workInProgress.stateNode, - workInProgress.type, - workInProgress.memoizedProps, - current, - workInProgress - ); + prepareToHydrateHostInstance(workInProgress, current); else { currentResource = getOwnerDocumentFromRootContainer( rootInstanceStackCursor.current @@ -8033,22 +8091,24 @@ function completeWork(current, workInProgress, renderLanes) { throw Error(formatProdErrorMessage(166)); current = rootInstanceStackCursor.current; if (popHydrationState(workInProgress)) { - if ( - ((current = workInProgress.stateNode), - (renderLanes = workInProgress.memoizedProps), - (current[internalInstanceKey] = workInProgress), - current.nodeValue !== renderLanes && - ((newProps = hydrationParentFiber), null !== newProps)) - ) - switch (newProps.tag) { - case 3: - checkForUnmatchedText(current.nodeValue, renderLanes); - break; + current = workInProgress.stateNode; + renderLanes = workInProgress.memoizedProps; + newProps = null; + currentResource = hydrationParentFiber; + if (null !== currentResource) + switch (currentResource.tag) { case 27: case 5: - !0 !== newProps.memoizedProps.suppressHydrationWarning && - checkForUnmatchedText(current.nodeValue, renderLanes); + newProps = currentResource.memoizedProps; } + current[internalInstanceKey] = workInProgress; + current = + current.nodeValue === renderLanes || + (null !== newProps && !0 === newProps.suppressHydrationWarning) || + checkForUnmatchedText(current.nodeValue, renderLanes) + ? !0 + : !1; + if (!current) throw Error(formatProdErrorMessage(425)); } else (current = getOwnerDocumentFromRootContainer(current).createTextNode( @@ -14099,14 +14159,14 @@ var isInputEventSupported = !1; if (canUseDOM) { var JSCompiler_inline_result$jscomp$363; if (canUseDOM) { - var isSupported$jscomp$inline_1599 = "oninput" in document; - if (!isSupported$jscomp$inline_1599) { - var element$jscomp$inline_1600 = document.createElement("div"); - element$jscomp$inline_1600.setAttribute("oninput", "return;"); - isSupported$jscomp$inline_1599 = - "function" === typeof element$jscomp$inline_1600.oninput; + var isSupported$jscomp$inline_1590 = "oninput" in document; + if (!isSupported$jscomp$inline_1590) { + var element$jscomp$inline_1591 = document.createElement("div"); + element$jscomp$inline_1591.setAttribute("oninput", "return;"); + isSupported$jscomp$inline_1590 = + "function" === typeof element$jscomp$inline_1591.oninput; } - JSCompiler_inline_result$jscomp$363 = isSupported$jscomp$inline_1599; + JSCompiler_inline_result$jscomp$363 = isSupported$jscomp$inline_1590; } else JSCompiler_inline_result$jscomp$363 = !1; isInputEventSupported = JSCompiler_inline_result$jscomp$363 && @@ -14418,20 +14478,20 @@ function registerSimpleEvent(domEventName, reactName) { registerTwoPhaseEvent(reactName, [domEventName]); } for ( - var i$jscomp$inline_1640 = 0; - i$jscomp$inline_1640 < simpleEventPluginEvents.length; - i$jscomp$inline_1640++ + var i$jscomp$inline_1631 = 0; + i$jscomp$inline_1631 < simpleEventPluginEvents.length; + i$jscomp$inline_1631++ ) { - var eventName$jscomp$inline_1641 = - simpleEventPluginEvents[i$jscomp$inline_1640], - domEventName$jscomp$inline_1642 = - eventName$jscomp$inline_1641.toLowerCase(), - capitalizedEvent$jscomp$inline_1643 = - eventName$jscomp$inline_1641[0].toUpperCase() + - eventName$jscomp$inline_1641.slice(1); + var eventName$jscomp$inline_1632 = + simpleEventPluginEvents[i$jscomp$inline_1631], + domEventName$jscomp$inline_1633 = + eventName$jscomp$inline_1632.toLowerCase(), + capitalizedEvent$jscomp$inline_1634 = + eventName$jscomp$inline_1632[0].toUpperCase() + + eventName$jscomp$inline_1632.slice(1); registerSimpleEvent( - domEventName$jscomp$inline_1642, - "on" + capitalizedEvent$jscomp$inline_1643 + domEventName$jscomp$inline_1633, + "on" + capitalizedEvent$jscomp$inline_1634 ); } registerSimpleEvent(ANIMATION_END, "onAnimationEnd"); @@ -15279,8 +15339,7 @@ function normalizeMarkupForTextOrAttribute(markup) { } function checkForUnmatchedText(serverText, clientText) { clientText = normalizeMarkupForTextOrAttribute(clientText); - if (normalizeMarkupForTextOrAttribute(serverText) !== clientText) - throw Error(formatProdErrorMessage(425)); + return normalizeMarkupForTextOrAttribute(serverText) === clientText ? !0 : !1; } function noop$1() {} function setProp(domElement, tag, key, value, props, prevValue) { @@ -16447,75 +16506,6 @@ function getNextHydratable(node) { } return node; } -function hydrateInstance( - instance, - type, - props, - hostContext, - internalInstanceHandle -) { - instance[internalInstanceKey] = internalInstanceHandle; - instance[internalPropsKey] = props; - switch (type) { - case "dialog": - listenToNonDelegatedEvent("cancel", instance); - listenToNonDelegatedEvent("close", instance); - break; - case "iframe": - case "object": - case "embed": - listenToNonDelegatedEvent("load", instance); - break; - case "video": - case "audio": - for (type = 0; type < mediaEventTypes.length; type++) - listenToNonDelegatedEvent(mediaEventTypes[type], instance); - break; - case "source": - listenToNonDelegatedEvent("error", instance); - break; - case "img": - case "image": - case "link": - listenToNonDelegatedEvent("error", instance); - listenToNonDelegatedEvent("load", instance); - break; - case "details": - listenToNonDelegatedEvent("toggle", instance); - break; - case "input": - listenToNonDelegatedEvent("invalid", instance); - initInput( - instance, - props.value, - props.defaultValue, - props.checked, - props.defaultChecked, - props.type, - props.name, - !0 - ); - track(instance); - break; - case "select": - listenToNonDelegatedEvent("invalid", instance); - break; - case "textarea": - listenToNonDelegatedEvent("invalid", instance), - initTextarea(instance, props.value, props.defaultValue), - track(instance); - } - type = props.children; - ("string" === typeof type || - "number" === typeof type || - (enableBigIntSupport && "bigint" === typeof type)) && - instance.textContent !== "" + type && - !0 !== props.suppressHydrationWarning && - checkForUnmatchedText(instance.textContent, type); - null != props.onScroll && listenToNonDelegatedEvent("scroll", instance); - null != props.onScrollEnd && listenToNonDelegatedEvent("scrollend", instance); - null != props.onClick && (instance.onclick = noop$1); -} function getParentSuspenseInstance(targetInstance) { targetInstance = targetInstance.previousSibling; for (var depth = 0; targetInstance; ) { @@ -17350,10 +17340,10 @@ Internals.Events = [ restoreStateIfNeeded, batchedUpdates$1 ]; -var devToolsConfig$jscomp$inline_1822 = { +var devToolsConfig$jscomp$inline_1806 = { findFiberByHostInstance: getClosestInstanceFromNode, bundleType: 0, - version: "19.0.0-www-modern-0fb5538d", + version: "19.0.0-www-modern-2e6097e8", rendererPackageName: "react-dom" }; (function (internals) { @@ -17371,10 +17361,10 @@ var devToolsConfig$jscomp$inline_1822 = { } catch (err) {} return hook.checkDCE ? !0 : !1; })({ - bundleType: devToolsConfig$jscomp$inline_1822.bundleType, - version: devToolsConfig$jscomp$inline_1822.version, - rendererPackageName: devToolsConfig$jscomp$inline_1822.rendererPackageName, - rendererConfig: devToolsConfig$jscomp$inline_1822.rendererConfig, + bundleType: devToolsConfig$jscomp$inline_1806.bundleType, + version: devToolsConfig$jscomp$inline_1806.version, + rendererPackageName: devToolsConfig$jscomp$inline_1806.rendererPackageName, + rendererConfig: devToolsConfig$jscomp$inline_1806.rendererConfig, overrideHookState: null, overrideHookStateDeletePath: null, overrideHookStateRenamePath: null, @@ -17391,14 +17381,14 @@ var devToolsConfig$jscomp$inline_1822 = { return null === fiber ? null : fiber.stateNode; }, findFiberByHostInstance: - devToolsConfig$jscomp$inline_1822.findFiberByHostInstance || + devToolsConfig$jscomp$inline_1806.findFiberByHostInstance || emptyFindFiberByHostInstance, findHostInstancesForRefresh: null, scheduleRefresh: null, scheduleRoot: null, setRefreshHandler: null, getCurrentFiber: null, - reconcilerVersion: "19.0.0-www-modern-0fb5538d" + reconcilerVersion: "19.0.0-www-modern-2e6097e8" }); exports.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED = Internals; exports.createPortal = function (children, container) { @@ -17644,7 +17634,7 @@ exports.useFormState = function (action, initialState, permalink) { exports.useFormStatus = function () { return ReactCurrentDispatcher$2.current.useHostTransitionStatus(); }; -exports.version = "19.0.0-www-modern-0fb5538d"; +exports.version = "19.0.0-www-modern-2e6097e8"; "undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ && "function" === typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop && diff --git a/compiled/facebook-www/ReactDOMTesting-dev.classic.js b/compiled/facebook-www/ReactDOMTesting-dev.classic.js index 9fd8b8e7033d6..c8f3aa65119c9 100644 --- a/compiled/facebook-www/ReactDOMTesting-dev.classic.js +++ b/compiled/facebook-www/ReactDOMTesting-dev.classic.js @@ -8344,35 +8344,104 @@ if (__DEV__) { return true; } + function warnForDeletedHydratableInstance(parentType, child) { + { + var description = describeHydratableInstanceForDevWarnings(child); + + if (typeof description === "string") { + error( + 'Did not expect server HTML to contain the text node "%s" in <%s>.', + description, + parentType + ); + } else { + error( + "Did not expect server HTML to contain a <%s> in <%s>.", + description.type, + parentType + ); + } + } + } + + function warnForInsertedHydratedElement(parentType, tag) { + { + error( + "Expected server HTML to contain a matching <%s> in <%s>.", + tag, + parentType + ); + } + } + + function warnForInsertedHydratedText(parentType, text) { + { + error( + 'Expected server HTML to contain a matching text node for "%s" in <%s>.', + text, + parentType + ); + } + } + + function warnForInsertedHydratedSuspense(parentType) { + { + error( + "Expected server HTML to contain a matching <%s> in <%s>.", + "Suspense", + parentType + ); + } + } + + function errorHydratingContainer(parentContainer) { + { + // TODO: This gets logged by onRecoverableError, too, so we should be + // able to remove it. + error( + "An error occurred during hydration. The server HTML was replaced with client content." + ); + } + } + function warnUnhydratedInstance(returnFiber, instance) { { + if (didWarnInvalidHydration) { + return; + } + + didWarnInvalidHydration = true; + switch (returnFiber.tag) { case HostRoot: { - didNotHydrateInstanceWithinContainer( - returnFiber.stateNode.containerInfo, - instance - ); + var description = + describeHydratableInstanceForDevWarnings(instance); + + if (typeof description === "string") { + error( + 'Did not expect server HTML to contain the text node "%s" in the root.', + description + ); + } else { + error( + "Did not expect server HTML to contain a <%s> in the root.", + description.type + ); + } + break; } case HostSingleton: case HostComponent: { - didNotHydrateInstance( - returnFiber.type, - returnFiber.memoizedProps, - returnFiber.stateNode, - instance - ); + warnForDeletedHydratableInstance(returnFiber.type, instance); break; } case SuspenseComponent: { var suspenseState = returnFiber.memoizedState; if (suspenseState.dehydrated !== null) - didNotHydrateInstanceWithinSuspenseInstance( - suspenseState.dehydrated, - instance - ); + warnForDeletedHydratableInstance("Suspense", instance); break; } } @@ -8388,26 +8457,41 @@ if (__DEV__) { return; } + if (didWarnInvalidHydration) { + return; + } + + didWarnInvalidHydration = true; + switch (returnFiber.tag) { case HostRoot: { - var parentContainer = returnFiber.stateNode.containerInfo; - + // const parentContainer = returnFiber.stateNode.containerInfo; switch (fiber.tag) { case HostSingleton: case HostComponent: - var type = fiber.type; - didNotFindHydratableInstanceWithinContainer( - parentContainer, - type + error( + "Expected server HTML to contain a matching <%s> in the root.", + fiber.type ); + break; case HostText: var text = fiber.pendingProps; - didNotFindHydratableTextInstanceWithinContainer( - parentContainer, + + error( + 'Expected server HTML to contain a matching text node for "%s" in the root.', text ); + + break; + + case SuspenseComponent: + error( + "Expected server HTML to contain a matching <%s> in the root.", + "Suspense" + ); + break; } @@ -8416,31 +8500,25 @@ if (__DEV__) { case HostSingleton: case HostComponent: { - var parentType = returnFiber.type; - var parentProps = returnFiber.memoizedProps; - var parentInstance = returnFiber.stateNode; + var parentType = returnFiber.type; // const parentProps = returnFiber.memoizedProps; + // const parentInstance = returnFiber.stateNode; switch (fiber.tag) { case HostSingleton: case HostComponent: { - var _type = fiber.type; - didNotFindHydratableInstance( - parentType, - parentProps, - parentInstance, - _type - ); + var type = fiber.type; + warnForInsertedHydratedElement(parentType, type); break; } case HostText: { var _text = fiber.pendingProps; - didNotFindHydratableTextInstance( - parentType, - parentProps, - parentInstance, - _text - ); + warnForInsertedHydratedText(parentType, _text); + break; + } + + case SuspenseComponent: { + warnForInsertedHydratedSuspense(parentType); break; } } @@ -8449,27 +8527,25 @@ if (__DEV__) { } case SuspenseComponent: { - var suspenseState = returnFiber.memoizedState; - var _parentInstance = suspenseState.dehydrated; - if (_parentInstance !== null) - switch (fiber.tag) { - case HostSingleton: - case HostComponent: - var _type2 = fiber.type; - didNotFindHydratableInstanceWithinSuspenseInstance( - _parentInstance, - _type2 - ); - break; + // const suspenseState: SuspenseState = returnFiber.memoizedState; + // const parentInstance = suspenseState.dehydrated; + switch (fiber.tag) { + case HostSingleton: + case HostComponent: + var _type = fiber.type; + warnForInsertedHydratedElement("Suspense", _type); + break; + + case HostText: + var _text2 = fiber.pendingProps; + warnForInsertedHydratedText("Suspense", _text2); + break; + + case SuspenseComponent: + warnForInsertedHydratedSuspense("Suspense"); + break; + } - case HostText: - var _text2 = fiber.pendingProps; - didNotFindHydratableTextInstanceWithinSuspenseInstance( - _parentInstance, - _text2 - ); - break; - } break; } @@ -8664,66 +8740,152 @@ if (__DEV__) { throwOnHydrationMismatch(); return false; - } + } // Temp + + var didWarnInvalidHydration = false; function prepareToHydrateHostInstance(fiber, hostContext) { var instance = fiber.stateNode; - var shouldWarnIfMismatchDev = !didSuspendOrErrorDEV; - hydrateInstance( + + { + var shouldWarnIfMismatchDev = !didSuspendOrErrorDEV; + + if (shouldWarnIfMismatchDev) { + var differences = diffHydratedPropsForDevWarnings( + instance, + fiber.type, + fiber.memoizedProps, + hostContext + ); + + if (differences !== null) { + if (differences.children != null && !didWarnInvalidHydration) { + didWarnInvalidHydration = true; + var serverValue = differences.children; + var clientValue = fiber.memoizedProps.children; + + error( + 'Text content did not match. Server: "%s" Client: "%s"', + serverValue, + clientValue + ); + } + + for (var propName in differences) { + if (!differences.hasOwnProperty(propName)) { + continue; + } + + if (didWarnInvalidHydration) { + break; + } + + didWarnInvalidHydration = true; + var _serverValue = differences[propName]; + var _clientValue = fiber.memoizedProps[propName]; + + if (propName === "children"); + else if (_clientValue != null) { + error( + "Prop `%s` did not match. Server: %s Client: %s", + propName, + JSON.stringify(_serverValue), + JSON.stringify(_clientValue) + ); + } else { + error("Extra attribute from the server: %s", propName); + } + } + } + } + } + + var didHydrate = hydrateInstance( instance, fiber.type, fiber.memoizedProps, hostContext, - fiber, - shouldWarnIfMismatchDev + fiber ); + + if (!didHydrate) { + throw new Error("Text content does not match server-rendered HTML."); + } } function prepareToHydrateHostTextInstance(fiber) { var textInstance = fiber.stateNode; var textContent = fiber.memoizedProps; var shouldWarnIfMismatchDev = !didSuspendOrErrorDEV; - var textIsDifferent = hydrateTextInstance( - textInstance, - textContent, - fiber - ); + var parentProps = null; // We assume that prepareToHydrateHostTextInstance is called in a context where the + // hydration parent is the parent host component of this host text. - if (textIsDifferent) { - // We assume that prepareToHydrateHostTextInstance is called in a context where the - // hydration parent is the parent host component of this host text. - var returnFiber = hydrationParentFiber; + var returnFiber = hydrationParentFiber; - if (returnFiber !== null) { - switch (returnFiber.tag) { - case HostRoot: { - var parentContainer = returnFiber.stateNode.containerInfo; - didNotMatchHydratedContainerTextInstance( - parentContainer, - textInstance, - textContent, - shouldWarnIfMismatchDev - ); - break; + if (returnFiber !== null) { + switch (returnFiber.tag) { + case HostRoot: { + { + if (shouldWarnIfMismatchDev) { + var difference = diffHydratedTextForDevWarnings( + textInstance, + textContent, + parentProps + ); + + if (difference !== null && !didWarnInvalidHydration) { + didWarnInvalidHydration = true; + + error( + 'Text content did not match. Server: "%s" Client: "%s"', + difference, + textContent + ); + } + } } - case HostSingleton: - case HostComponent: { - var parentType = returnFiber.type; - var parentProps = returnFiber.memoizedProps; - var parentInstance = returnFiber.stateNode; - didNotMatchHydratedTextInstance( - parentType, - parentProps, - parentInstance, - textInstance, - textContent, - shouldWarnIfMismatchDev - ); - break; + break; + } + + case HostSingleton: + case HostComponent: { + parentProps = returnFiber.memoizedProps; + + { + if (shouldWarnIfMismatchDev) { + var _difference = diffHydratedTextForDevWarnings( + textInstance, + textContent, + parentProps + ); + + if (_difference !== null && !didWarnInvalidHydration) { + didWarnInvalidHydration = true; + + error( + 'Text content did not match. Server: "%s" Client: "%s"', + _difference, + textContent + ); + } + } } + + break; } - } + } // TODO: What if it's a SuspenseInstance? + } + + var didHydrate = hydrateTextInstance( + textInstance, + textContent, + fiber, + parentProps + ); + + if (!didHydrate) { + throw new Error("Text content does not match server-rendered HTML."); } } @@ -31913,7 +32075,7 @@ if (__DEV__) { rootWorkInProgress.flags |= ForceClientRender; { - errorHydratingContainer(root.containerInfo); + errorHydratingContainer(); } } @@ -36190,7 +36352,7 @@ if (__DEV__) { return root; } - var ReactVersion = "19.0.0-www-classic-5624d429"; + var ReactVersion = "19.0.0-www-classic-d0976d4e"; function createPortal$1( children, @@ -40689,7 +40851,6 @@ if (__DEV__) { var didWarnControlledToUncontrolled = false; var didWarnUncontrolledToControlled = false; - var didWarnInvalidHydration = false; var didWarnFormActionType = false; var didWarnFormActionName = false; var didWarnFormActionTarget = false; @@ -40840,12 +41001,13 @@ if (__DEV__) { } } - function warnForPropDifference(propName, serverValue, clientValue) { + function warnForPropDifference( + propName, + serverValue, + clientValue, + serverDifferences + ) { { - if (didWarnInvalidHydration) { - return; - } - if (serverValue === clientValue) { return; } @@ -40859,30 +41021,22 @@ if (__DEV__) { return; } - didWarnInvalidHydration = true; - - error( - "Prop `%s` did not match. Server: %s Client: %s", - propName, - JSON.stringify(normalizedServerValue), - JSON.stringify(normalizedClientValue) - ); + serverDifferences[propName] = serverValue; } } - function warnForExtraAttributes(attributeNames) { + function warnForExtraAttributes( + domElement, + attributeNames, + serverDifferences + ) { { - if (didWarnInvalidHydration) { - return; - } - - didWarnInvalidHydration = true; - var names = []; - attributeNames.forEach(function (name) { - names.push(name); + attributeNames.forEach(function (attributeName) { + serverDifferences[attributeName] = + attributeName === "style" + ? getStylesObjectFromElement(domElement) + : domElement.getAttribute(attributeName); }); - - error("Extra attributes from the server: %s", names); } } @@ -40945,30 +41099,15 @@ if (__DEV__) { .replace(NORMALIZE_NULL_AND_REPLACEMENT_REGEX, ""); } - function checkForUnmatchedText(serverText, clientText, shouldWarnDev) { + function checkForUnmatchedText(serverText, clientText) { var normalizedClientText = normalizeMarkupForTextOrAttribute(clientText); var normalizedServerText = normalizeMarkupForTextOrAttribute(serverText); if (normalizedServerText === normalizedClientText) { - return; + return true; } - if (shouldWarnDev) { - { - if (!didWarnInvalidHydration) { - didWarnInvalidHydration = true; - - error( - 'Text content did not match. Server: "%s" Client: "%s"', - normalizedServerText, - normalizedClientText - ); - } - } - } // In concurrent roots, we throw when there's a text mismatch and revert to - // client rendering, up to the nearest Suspense boundary. - - throw new Error("Text content does not match server-rendered HTML."); + return false; } function noop$2() {} @@ -42732,19 +42871,70 @@ if (__DEV__) { } } - function diffHydratedStyles(domElement, value) { + function getPropsFromElement(domElement) { + var serverDifferences = {}; + var attributes = domElement.attributes; + + for (var i = 0; i < attributes.length; i++) { + var attr = attributes[i]; + serverDifferences[attr.name] = + attr.name.toLowerCase() === "style" + ? getStylesObjectFromElement(domElement) + : attr.value; + } + + return serverDifferences; + } + + function getStylesObjectFromElement(domElement) { + var serverValueInObjectForm = {}; + var style = domElement.style; + + for (var i = 0; i < style.length; i++) { + var styleName = style[i]; // TODO: We should use the original prop value here if it is equivalent. + // TODO: We could use the original client capitalization if the equivalent + // other capitalization exists in the DOM. + + serverValueInObjectForm[styleName] = style.getPropertyValue(styleName); + } + + return serverValueInObjectForm; + } + + function diffHydratedStyles(domElement, value, serverDifferences) { if (value != null && typeof value !== "object") { - throw new Error( - "The `style` prop expects a mapping from style properties to values, " + - "not a string. For example, style={{marginRight: spacing + 'em'}} when " + - "using JSX." - ); + { + error( + "The `style` prop expects a mapping from style properties to values, " + + "not a string. For example, style={{marginRight: spacing + 'em'}} when " + + "using JSX." + ); + } + + return; } if (canDiffStyleForHydrationWarning) { - var expectedStyle = createDangerousStringForStyles(value); + // First we compare the string form and see if it's equivalent. + // This lets us bail out on anything that used to pass in this form. + // It also lets us compare anything that's not parsed by this browser. + var clientValue = createDangerousStringForStyles(value); var serverValue = domElement.getAttribute("style"); - warnForPropDifference("style", serverValue, expectedStyle); + + if (serverValue === clientValue) { + return; + } + + var normalizedClientValue = + normalizeMarkupForTextOrAttribute(clientValue); + var normalizedServerValue = + normalizeMarkupForTextOrAttribute(serverValue); + + if (normalizedServerValue === normalizedClientValue) { + return; + } // Otherwise, we create the object from the DOM for the diff view. + + serverDifferences.style = getStylesObjectFromElement(domElement); } } @@ -42753,7 +42943,8 @@ if (__DEV__) { propKey, attributeName, value, - extraAttributes + extraAttributes, + serverDifferences ) { extraAttributes.delete(attributeName); var serverValue = domElement.getAttribute(attributeName); @@ -42788,7 +42979,7 @@ if (__DEV__) { } } - warnForPropDifference(propKey, serverValue, value); + warnForPropDifference(propKey, serverValue, value, serverDifferences); } function hydrateBooleanAttribute( @@ -42796,7 +42987,8 @@ if (__DEV__) { propKey, attributeName, value, - extraAttributes + extraAttributes, + serverDifferences ) { extraAttributes.delete(attributeName); var serverValue = domElement.getAttribute(attributeName); @@ -42828,7 +43020,7 @@ if (__DEV__) { } } - warnForPropDifference(propKey, serverValue, value); + warnForPropDifference(propKey, serverValue, value, serverDifferences); } function hydrateOverloadedBooleanAttribute( @@ -42836,7 +43028,8 @@ if (__DEV__) { propKey, attributeName, value, - extraAttributes + extraAttributes, + serverDifferences ) { extraAttributes.delete(attributeName); var serverValue = domElement.getAttribute(attributeName); @@ -42881,7 +43074,7 @@ if (__DEV__) { } } - warnForPropDifference(propKey, serverValue, value); + warnForPropDifference(propKey, serverValue, value, serverDifferences); } function hydrateBooleanishAttribute( @@ -42889,7 +43082,8 @@ if (__DEV__) { propKey, attributeName, value, - extraAttributes + extraAttributes, + serverDifferences ) { extraAttributes.delete(attributeName); var serverValue = domElement.getAttribute(attributeName); @@ -42922,7 +43116,7 @@ if (__DEV__) { } } - warnForPropDifference(propKey, serverValue, value); + warnForPropDifference(propKey, serverValue, value, serverDifferences); } function hydrateNumericAttribute( @@ -42930,7 +43124,8 @@ if (__DEV__) { propKey, attributeName, value, - extraAttributes + extraAttributes, + serverDifferences ) { extraAttributes.delete(attributeName); var serverValue = domElement.getAttribute(attributeName); @@ -42976,7 +43171,7 @@ if (__DEV__) { } } - warnForPropDifference(propKey, serverValue, value); + warnForPropDifference(propKey, serverValue, value, serverDifferences); } function hydratePositiveNumericAttribute( @@ -42984,7 +43179,8 @@ if (__DEV__) { propKey, attributeName, value, - extraAttributes + extraAttributes, + serverDifferences ) { extraAttributes.delete(attributeName); var serverValue = domElement.getAttribute(attributeName); @@ -43030,7 +43226,7 @@ if (__DEV__) { } } - warnForPropDifference(propKey, serverValue, value); + warnForPropDifference(propKey, serverValue, value, serverDifferences); } function hydrateSanitizedAttribute( @@ -43038,7 +43234,8 @@ if (__DEV__) { propKey, attributeName, value, - extraAttributes + extraAttributes, + serverDifferences ) { extraAttributes.delete(attributeName); var serverValue = domElement.getAttribute(attributeName); @@ -43075,7 +43272,7 @@ if (__DEV__) { } } - warnForPropDifference(propKey, serverValue, value); + warnForPropDifference(propKey, serverValue, value, serverDifferences); } function diffHydratedCustomComponent( @@ -43083,7 +43280,8 @@ if (__DEV__) { tag, props, hostContext, - extraAttributes + extraAttributes, + serverDifferences ) { for (var propKey in props) { if (!props.hasOwnProperty(propKey)) { @@ -43110,7 +43308,19 @@ if (__DEV__) { } // Validate that the properties correspond to their expected values. switch (propKey) { - case "children": // Checked above already + case "children": { + if (typeof value === "string" || typeof value === "number") { + warnForPropDifference( + "children", + domElement.textContent, + value, + serverDifferences + ); + } + + continue; + } + // Checked above already case "suppressContentEditableWarning": case "suppressHydrationWarning": @@ -43127,14 +43337,19 @@ if (__DEV__) { if (nextHtml != null) { var expectedHTML = normalizeHTML(domElement, nextHtml); - warnForPropDifference(propKey, serverHTML, expectedHTML); + warnForPropDifference( + propKey, + serverHTML, + expectedHTML, + serverDifferences + ); } continue; case "style": extraAttributes.delete(propKey); - diffHydratedStyles(domElement, value); + diffHydratedStyles(domElement, value, serverDifferences); continue; case "offsetParent": @@ -43167,7 +43382,12 @@ if (__DEV__) { "class", value ); - warnForPropDifference("className", serverValue, value); + warnForPropDifference( + "className", + serverValue, + value, + serverDifferences + ); continue; } @@ -43194,7 +43414,12 @@ if (__DEV__) { value ); - warnForPropDifference(propKey, _serverValue, value); + warnForPropDifference( + propKey, + _serverValue, + value, + serverDifferences + ); } } } @@ -43210,7 +43435,8 @@ if (__DEV__) { tag, props, hostContext, - extraAttributes + extraAttributes, + serverDifferences ) { for (var propKey in props) { if (!props.hasOwnProperty(propKey)) { @@ -43237,7 +43463,19 @@ if (__DEV__) { } // Validate that the properties correspond to their expected values. switch (propKey) { - case "children": // Checked above already + case "children": { + if (typeof value === "string" || typeof value === "number") { + warnForPropDifference( + "children", + domElement.textContent, + value, + serverDifferences + ); + } + + continue; + } + // Checked above already case "suppressContentEditableWarning": case "suppressHydrationWarning": @@ -43259,7 +43497,12 @@ if (__DEV__) { if (nextHtml != null) { var expectedHTML = normalizeHTML(domElement, nextHtml); - warnForPropDifference(propKey, serverHTML, expectedHTML); + + if (serverHTML !== expectedHTML) { + serverDifferences[propKey] = { + __html: serverHTML + }; + } } continue; @@ -43270,7 +43513,8 @@ if (__DEV__) { propKey, "class", value, - extraAttributes + extraAttributes, + serverDifferences ); continue; @@ -43280,33 +43524,49 @@ if (__DEV__) { propKey, "tabindex", value, - extraAttributes + extraAttributes, + serverDifferences ); continue; case "style": extraAttributes.delete(propKey); - diffHydratedStyles(domElement, value); + diffHydratedStyles(domElement, value, serverDifferences); continue; case "multiple": { extraAttributes.delete(propKey); var serverValue = domElement.multiple; - warnForPropDifference(propKey, serverValue, value); + warnForPropDifference( + propKey, + serverValue, + value, + serverDifferences + ); continue; } case "muted": { extraAttributes.delete(propKey); var _serverValue2 = domElement.muted; - warnForPropDifference(propKey, _serverValue2, value); + warnForPropDifference( + propKey, + _serverValue2, + value, + serverDifferences + ); continue; } case "autoFocus": { extraAttributes.delete("autofocus"); var _serverValue3 = domElement.autofocus; - warnForPropDifference(propKey, _serverValue3, value); + warnForPropDifference( + propKey, + _serverValue3, + value, + serverDifferences + ); continue; } @@ -43343,7 +43603,8 @@ if (__DEV__) { propKey, propKey, null, - extraAttributes + extraAttributes, + serverDifferences ); continue; } @@ -43354,7 +43615,8 @@ if (__DEV__) { propKey, propKey, value, - extraAttributes + extraAttributes, + serverDifferences ); continue; @@ -43385,7 +43647,12 @@ if (__DEV__) { continue; } else if (_serverValue4 === EXPECTED_FORM_ACTION_URL) { extraAttributes.delete(propKey.toLowerCase()); - warnForPropDifference(propKey, "function", value); + warnForPropDifference( + propKey, + "function", + value, + serverDifferences + ); continue; } @@ -43394,7 +43661,8 @@ if (__DEV__) { propKey, propKey.toLowerCase(), value, - extraAttributes + extraAttributes, + serverDifferences ); continue; } @@ -43405,7 +43673,8 @@ if (__DEV__) { propKey, "xlink:href", value, - extraAttributes + extraAttributes, + serverDifferences ); continue; @@ -43416,7 +43685,8 @@ if (__DEV__) { propKey, "contenteditable", value, - extraAttributes + extraAttributes, + serverDifferences ); continue; } @@ -43428,7 +43698,8 @@ if (__DEV__) { propKey, "spellcheck", value, - extraAttributes + extraAttributes, + serverDifferences ); continue; } @@ -43444,7 +43715,8 @@ if (__DEV__) { propKey, propKey, value, - extraAttributes + extraAttributes, + serverDifferences ); continue; } @@ -43477,7 +43749,8 @@ if (__DEV__) { propKey, propKey.toLowerCase(), value, - extraAttributes + extraAttributes, + serverDifferences ); continue; } @@ -43489,7 +43762,8 @@ if (__DEV__) { propKey, propKey, value, - extraAttributes + extraAttributes, + serverDifferences ); continue; } @@ -43503,7 +43777,8 @@ if (__DEV__) { propKey, propKey, value, - extraAttributes + extraAttributes, + serverDifferences ); continue; } @@ -43514,7 +43789,8 @@ if (__DEV__) { propKey, "rowspan", value, - extraAttributes + extraAttributes, + serverDifferences ); continue; } @@ -43525,7 +43801,8 @@ if (__DEV__) { propKey, propKey, value, - extraAttributes + extraAttributes, + serverDifferences ); continue; } @@ -43536,7 +43813,8 @@ if (__DEV__) { propKey, "x-height", value, - extraAttributes + extraAttributes, + serverDifferences ); continue; @@ -43546,7 +43824,8 @@ if (__DEV__) { propKey, "xlink:actuate", value, - extraAttributes + extraAttributes, + serverDifferences ); continue; @@ -43556,7 +43835,8 @@ if (__DEV__) { propKey, "xlink:arcrole", value, - extraAttributes + extraAttributes, + serverDifferences ); continue; @@ -43566,7 +43846,8 @@ if (__DEV__) { propKey, "xlink:role", value, - extraAttributes + extraAttributes, + serverDifferences ); continue; @@ -43576,7 +43857,8 @@ if (__DEV__) { propKey, "xlink:show", value, - extraAttributes + extraAttributes, + serverDifferences ); continue; @@ -43586,7 +43868,8 @@ if (__DEV__) { propKey, "xlink:title", value, - extraAttributes + extraAttributes, + serverDifferences ); continue; @@ -43596,7 +43879,8 @@ if (__DEV__) { propKey, "xlink:type", value, - extraAttributes + extraAttributes, + serverDifferences ); continue; @@ -43606,7 +43890,8 @@ if (__DEV__) { propKey, "xml:base", value, - extraAttributes + extraAttributes, + serverDifferences ); continue; @@ -43616,7 +43901,8 @@ if (__DEV__) { propKey, "xml:lang", value, - extraAttributes + extraAttributes, + serverDifferences ); continue; @@ -43626,7 +43912,8 @@ if (__DEV__) { propKey, "xml:space", value, - extraAttributes + extraAttributes, + serverDifferences ); continue; @@ -43654,7 +43941,8 @@ if (__DEV__) { propKey, propKey, value, - extraAttributes + extraAttributes, + serverDifferences ); continue; } @@ -43707,20 +43995,19 @@ if (__DEV__) { ); if (!isMismatchDueToBadCasing) { - warnForPropDifference(propKey, _serverValue5, value); + warnForPropDifference( + propKey, + _serverValue5, + value, + serverDifferences + ); } } } } } - function diffHydratedProperties( - domElement, - tag, - props, - shouldWarnDev, - hostContext - ) { + function hydrateProperties(domElement, tag, props, hostContext) { { validatePropertiesInDevelopment(tag, props); } // TODO: Make sure that we check isMounted before firing any of these events. @@ -43847,15 +44134,13 @@ if (__DEV__) { typeof children === "number" || (enableBigIntSupport && typeof children === "bigint") ) { - // $FlowFixMe[unsafe-addition] Flow doesn't want us to use `+` operator with string and bigint - if (domElement.textContent !== "" + children) { - if (props.suppressHydrationWarning !== true) { - checkForUnmatchedText( - domElement.textContent, - children, - shouldWarnDev - ); - } + if ( + // $FlowFixMe[unsafe-addition] Flow doesn't want us to use `+` operator with string and bigint + domElement.textContent !== "" + children && + props.suppressHydrationWarning !== true && + !checkForUnmatchedText(domElement.textContent, children) + ) { + return false; } } @@ -43872,12 +44157,17 @@ if (__DEV__) { trapClickOnNonInteractiveElement(domElement); } - if (shouldWarnDev) { + return true; + } + function diffHydratedProperties(domElement, tag, props, hostContext) { + var serverDifferences = {}; + + { var extraAttributes = new Set(); var attributes = domElement.attributes; - for (var _i = 0; _i < attributes.length; _i++) { - var name = attributes[_i].name.toLowerCase(); + for (var i = 0; i < attributes.length; i++) { + var name = attributes[i].name.toLowerCase(); switch (name) { // Controlled attributes are not validated @@ -43894,7 +44184,7 @@ if (__DEV__) { default: // Intentionally use the original name. // See discussion in https://github.com/facebook/react/pull/10676. - extraAttributes.add(attributes[_i].name); + extraAttributes.add(attributes[i].name); } } @@ -43904,7 +44194,8 @@ if (__DEV__) { tag, props, hostContext, - extraAttributes + extraAttributes, + serverDifferences ); } else { diffHydratedGenericElement( @@ -43912,7 +44203,8 @@ if (__DEV__) { tag, props, hostContext, - extraAttributes + extraAttributes, + serverDifferences ); } @@ -43920,73 +44212,49 @@ if (__DEV__) { extraAttributes.size > 0 && props.suppressHydrationWarning !== true ) { - warnForExtraAttributes(extraAttributes); + warnForExtraAttributes( + domElement, + extraAttributes, + serverDifferences + ); } } - } - function diffHydratedText(textNode, text) { - var isDifferent = textNode.nodeValue !== text; - return isDifferent; - } - function warnForDeletedHydratableElement(parentNode, child) { - { - if (didWarnInvalidHydration) { - return; - } - - didWarnInvalidHydration = true; - error( - "Did not expect server HTML to contain a <%s> in <%s>.", - child.nodeName.toLowerCase(), - parentNode.nodeName.toLowerCase() - ); + if (Object.keys(serverDifferences).length === 0) { + return null; } - } - function warnForDeletedHydratableText(parentNode, child) { - { - if (didWarnInvalidHydration) { - return; - } - - didWarnInvalidHydration = true; - error( - 'Did not expect server HTML to contain the text node "%s" in <%s>.', - child.nodeValue, - parentNode.nodeName.toLowerCase() - ); - } + return serverDifferences; } - function warnForInsertedHydratedElement(parentNode, tag, props) { - { - if (didWarnInvalidHydration) { - return; - } - - didWarnInvalidHydration = true; + function hydrateText(textNode, text, parentProps) { + var isDifferent = textNode.nodeValue !== text; - error( - "Expected server HTML to contain a matching <%s> in <%s>.", - tag, - parentNode.nodeName.toLowerCase() - ); + if ( + isDifferent && + (parentProps === null || + parentProps.suppressHydrationWarning !== true) && + !checkForUnmatchedText(textNode.nodeValue, text) + ) { + return false; } + + return true; } - function warnForInsertedHydratedText(parentNode, text) { - { - if (didWarnInvalidHydration) { - return; - } + function diffHydratedText(textNode, text) { + if (textNode.nodeValue === text) { + return null; + } - didWarnInvalidHydration = true; + var normalizedClientText = normalizeMarkupForTextOrAttribute(text); + var normalizedServerText = normalizeMarkupForTextOrAttribute( + textNode.nodeValue + ); - error( - 'Expected server HTML to contain a matching text node for "%s" in <%s>.', - text, - parentNode.nodeName.toLowerCase() - ); + if (normalizedServerText === normalizedClientText) { + return null; } + + return textNode.nodeValue; } function restoreControlledState(domElement, tag, props) { switch (tag) { @@ -45151,6 +45419,23 @@ if (__DEV__) { function getFirstHydratableChildWithinSuspenseInstance(parentInstance) { return getNextHydratable(parentInstance.nextSibling); } + function describeHydratableInstanceForDevWarnings(instance) { + // Reverse engineer a pseudo react-element from hydratable instnace + if (instance.nodeType === ELEMENT_NODE) { + // Reverse engineer a set of props that can print for dev warnings + return { + type: instance.nodeName.toLowerCase(), + props: getPropsFromElement(instance) + }; + } else if (instance.nodeType === COMMENT_NODE) { + return { + type: "Suspense", + props: {} + }; + } else { + return instance.nodeValue; + } + } function validateHydratableInstance(type, props, hostContext) { { // TODO: take namespace into account when validating. @@ -45163,14 +45448,22 @@ if (__DEV__) { type, props, hostContext, - internalInstanceHandle, - shouldWarnDev + internalInstanceHandle ) { precacheFiberNode(internalInstanceHandle, instance); // TODO: Possibly defer this until the commit phase where all the events // get attached. updateFiberProps(instance, props); - diffHydratedProperties(instance, type, props, shouldWarnDev, hostContext); + return hydrateProperties(instance, type, props); + } // Returns a Map of properties that were different on the server. + + function diffHydratedPropsForDevWarnings( + instance, + type, + props, + hostContext + ) { + return diffHydratedProperties(instance, type, props, hostContext); } function validateHydratableTextInstance(text, hostContext) { { @@ -45188,10 +45481,21 @@ if (__DEV__) { textInstance, text, internalInstanceHandle, - shouldWarnDev + parentInstanceProps ) { precacheFiberNode(internalInstanceHandle, textInstance); - return diffHydratedText(textInstance, text); + return hydrateText(textInstance, text, parentInstanceProps); + } // Returns the server text if it differs from the client. + + function diffHydratedTextForDevWarnings(textInstance, text, parentProps) { + if ( + parentProps === null || + parentProps[SUPPRESS_HYDRATION_WARNING] !== true + ) { + return diffHydratedText(textInstance, text); + } + + return null; } function hydrateSuspenseInstance(suspenseInstance, internalInstanceHandle) { precacheFiberNode(internalInstanceHandle, suspenseInstance); @@ -45271,139 +45575,6 @@ if (__DEV__) { } function shouldDeleteUnhydratedTailInstances(parentType) { return parentType !== "form" && parentType !== "button"; - } - function didNotMatchHydratedContainerTextInstance( - parentContainer, - textInstance, - text, - shouldWarnDev - ) { - checkForUnmatchedText(textInstance.nodeValue, text, shouldWarnDev); - } - function didNotMatchHydratedTextInstance( - parentType, - parentProps, - parentInstance, - textInstance, - text, - shouldWarnDev - ) { - if (parentProps[SUPPRESS_HYDRATION_WARNING] !== true) { - checkForUnmatchedText(textInstance.nodeValue, text, shouldWarnDev); - } - } - function didNotHydrateInstanceWithinContainer(parentContainer, instance) { - { - if (instance.nodeType === ELEMENT_NODE) { - warnForDeletedHydratableElement(parentContainer, instance); - } else if (instance.nodeType === COMMENT_NODE); - else { - warnForDeletedHydratableText(parentContainer, instance); - } - } - } - function didNotHydrateInstanceWithinSuspenseInstance( - parentInstance, - instance - ) { - { - // $FlowFixMe[incompatible-type]: Only Element or Document can be parent nodes. - var parentNode = parentInstance.parentNode; - - if (parentNode !== null) { - if (instance.nodeType === ELEMENT_NODE) { - warnForDeletedHydratableElement(parentNode, instance); - } else if (instance.nodeType === COMMENT_NODE); - else { - warnForDeletedHydratableText(parentNode, instance); - } - } - } - } - function didNotHydrateInstance( - parentType, - parentProps, - parentInstance, - instance - ) { - { - if (instance.nodeType === ELEMENT_NODE) { - warnForDeletedHydratableElement(parentInstance, instance); - } else if (instance.nodeType === COMMENT_NODE); - else { - warnForDeletedHydratableText(parentInstance, instance); - } - } - } - function didNotFindHydratableInstanceWithinContainer( - parentContainer, - type, - props - ) { - { - warnForInsertedHydratedElement(parentContainer, type); - } - } - function didNotFindHydratableTextInstanceWithinContainer( - parentContainer, - text - ) { - { - warnForInsertedHydratedText(parentContainer, text); - } - } - function didNotFindHydratableInstanceWithinSuspenseInstance( - parentInstance, - type, - props - ) { - { - // $FlowFixMe[incompatible-type]: Only Element or Document can be parent nodes. - var parentNode = parentInstance.parentNode; - if (parentNode !== null) - warnForInsertedHydratedElement(parentNode, type); - } - } - function didNotFindHydratableTextInstanceWithinSuspenseInstance( - parentInstance, - text - ) { - { - // $FlowFixMe[incompatible-type]: Only Element or Document can be parent nodes. - var parentNode = parentInstance.parentNode; - if (parentNode !== null) warnForInsertedHydratedText(parentNode, text); - } - } - function didNotFindHydratableInstance( - parentType, - parentProps, - parentInstance, - type, - props - ) { - { - warnForInsertedHydratedElement(parentInstance, type); - } - } - function didNotFindHydratableTextInstance( - parentType, - parentProps, - parentInstance, - text - ) { - { - warnForInsertedHydratedText(parentInstance, text); - } - } - function errorHydratingContainer(parentContainer) { - { - // TODO: This gets logged by onRecoverableError, too, so we should be - // able to remove it. - error( - "An error occurred during hydration. The server HTML was replaced with client content in <%s>.", - parentContainer.nodeName.toLowerCase() - ); - } } // ------------------- function findFiberRoot(node) { var stack = [node]; diff --git a/compiled/facebook-www/ReactDOMTesting-dev.modern.js b/compiled/facebook-www/ReactDOMTesting-dev.modern.js index 509da0d93d625..5066a5f786650 100644 --- a/compiled/facebook-www/ReactDOMTesting-dev.modern.js +++ b/compiled/facebook-www/ReactDOMTesting-dev.modern.js @@ -8306,35 +8306,104 @@ if (__DEV__) { return true; } + function warnForDeletedHydratableInstance(parentType, child) { + { + var description = describeHydratableInstanceForDevWarnings(child); + + if (typeof description === "string") { + error( + 'Did not expect server HTML to contain the text node "%s" in <%s>.', + description, + parentType + ); + } else { + error( + "Did not expect server HTML to contain a <%s> in <%s>.", + description.type, + parentType + ); + } + } + } + + function warnForInsertedHydratedElement(parentType, tag) { + { + error( + "Expected server HTML to contain a matching <%s> in <%s>.", + tag, + parentType + ); + } + } + + function warnForInsertedHydratedText(parentType, text) { + { + error( + 'Expected server HTML to contain a matching text node for "%s" in <%s>.', + text, + parentType + ); + } + } + + function warnForInsertedHydratedSuspense(parentType) { + { + error( + "Expected server HTML to contain a matching <%s> in <%s>.", + "Suspense", + parentType + ); + } + } + + function errorHydratingContainer(parentContainer) { + { + // TODO: This gets logged by onRecoverableError, too, so we should be + // able to remove it. + error( + "An error occurred during hydration. The server HTML was replaced with client content." + ); + } + } + function warnUnhydratedInstance(returnFiber, instance) { { + if (didWarnInvalidHydration) { + return; + } + + didWarnInvalidHydration = true; + switch (returnFiber.tag) { case HostRoot: { - didNotHydrateInstanceWithinContainer( - returnFiber.stateNode.containerInfo, - instance - ); + var description = + describeHydratableInstanceForDevWarnings(instance); + + if (typeof description === "string") { + error( + 'Did not expect server HTML to contain the text node "%s" in the root.', + description + ); + } else { + error( + "Did not expect server HTML to contain a <%s> in the root.", + description.type + ); + } + break; } case HostSingleton: case HostComponent: { - didNotHydrateInstance( - returnFiber.type, - returnFiber.memoizedProps, - returnFiber.stateNode, - instance - ); + warnForDeletedHydratableInstance(returnFiber.type, instance); break; } case SuspenseComponent: { var suspenseState = returnFiber.memoizedState; if (suspenseState.dehydrated !== null) - didNotHydrateInstanceWithinSuspenseInstance( - suspenseState.dehydrated, - instance - ); + warnForDeletedHydratableInstance("Suspense", instance); break; } } @@ -8350,26 +8419,41 @@ if (__DEV__) { return; } + if (didWarnInvalidHydration) { + return; + } + + didWarnInvalidHydration = true; + switch (returnFiber.tag) { case HostRoot: { - var parentContainer = returnFiber.stateNode.containerInfo; - + // const parentContainer = returnFiber.stateNode.containerInfo; switch (fiber.tag) { case HostSingleton: case HostComponent: - var type = fiber.type; - didNotFindHydratableInstanceWithinContainer( - parentContainer, - type + error( + "Expected server HTML to contain a matching <%s> in the root.", + fiber.type ); + break; case HostText: var text = fiber.pendingProps; - didNotFindHydratableTextInstanceWithinContainer( - parentContainer, + + error( + 'Expected server HTML to contain a matching text node for "%s" in the root.', text ); + + break; + + case SuspenseComponent: + error( + "Expected server HTML to contain a matching <%s> in the root.", + "Suspense" + ); + break; } @@ -8378,31 +8462,25 @@ if (__DEV__) { case HostSingleton: case HostComponent: { - var parentType = returnFiber.type; - var parentProps = returnFiber.memoizedProps; - var parentInstance = returnFiber.stateNode; + var parentType = returnFiber.type; // const parentProps = returnFiber.memoizedProps; + // const parentInstance = returnFiber.stateNode; switch (fiber.tag) { case HostSingleton: case HostComponent: { - var _type = fiber.type; - didNotFindHydratableInstance( - parentType, - parentProps, - parentInstance, - _type - ); + var type = fiber.type; + warnForInsertedHydratedElement(parentType, type); break; } case HostText: { var _text = fiber.pendingProps; - didNotFindHydratableTextInstance( - parentType, - parentProps, - parentInstance, - _text - ); + warnForInsertedHydratedText(parentType, _text); + break; + } + + case SuspenseComponent: { + warnForInsertedHydratedSuspense(parentType); break; } } @@ -8411,27 +8489,25 @@ if (__DEV__) { } case SuspenseComponent: { - var suspenseState = returnFiber.memoizedState; - var _parentInstance = suspenseState.dehydrated; - if (_parentInstance !== null) - switch (fiber.tag) { - case HostSingleton: - case HostComponent: - var _type2 = fiber.type; - didNotFindHydratableInstanceWithinSuspenseInstance( - _parentInstance, - _type2 - ); - break; + // const suspenseState: SuspenseState = returnFiber.memoizedState; + // const parentInstance = suspenseState.dehydrated; + switch (fiber.tag) { + case HostSingleton: + case HostComponent: + var _type = fiber.type; + warnForInsertedHydratedElement("Suspense", _type); + break; + + case HostText: + var _text2 = fiber.pendingProps; + warnForInsertedHydratedText("Suspense", _text2); + break; + + case SuspenseComponent: + warnForInsertedHydratedSuspense("Suspense"); + break; + } - case HostText: - var _text2 = fiber.pendingProps; - didNotFindHydratableTextInstanceWithinSuspenseInstance( - _parentInstance, - _text2 - ); - break; - } break; } @@ -8626,66 +8702,152 @@ if (__DEV__) { throwOnHydrationMismatch(); return false; - } + } // Temp + + var didWarnInvalidHydration = false; function prepareToHydrateHostInstance(fiber, hostContext) { var instance = fiber.stateNode; - var shouldWarnIfMismatchDev = !didSuspendOrErrorDEV; - hydrateInstance( + + { + var shouldWarnIfMismatchDev = !didSuspendOrErrorDEV; + + if (shouldWarnIfMismatchDev) { + var differences = diffHydratedPropsForDevWarnings( + instance, + fiber.type, + fiber.memoizedProps, + hostContext + ); + + if (differences !== null) { + if (differences.children != null && !didWarnInvalidHydration) { + didWarnInvalidHydration = true; + var serverValue = differences.children; + var clientValue = fiber.memoizedProps.children; + + error( + 'Text content did not match. Server: "%s" Client: "%s"', + serverValue, + clientValue + ); + } + + for (var propName in differences) { + if (!differences.hasOwnProperty(propName)) { + continue; + } + + if (didWarnInvalidHydration) { + break; + } + + didWarnInvalidHydration = true; + var _serverValue = differences[propName]; + var _clientValue = fiber.memoizedProps[propName]; + + if (propName === "children"); + else if (_clientValue != null) { + error( + "Prop `%s` did not match. Server: %s Client: %s", + propName, + JSON.stringify(_serverValue), + JSON.stringify(_clientValue) + ); + } else { + error("Extra attribute from the server: %s", propName); + } + } + } + } + } + + var didHydrate = hydrateInstance( instance, fiber.type, fiber.memoizedProps, hostContext, - fiber, - shouldWarnIfMismatchDev + fiber ); + + if (!didHydrate) { + throw new Error("Text content does not match server-rendered HTML."); + } } function prepareToHydrateHostTextInstance(fiber) { var textInstance = fiber.stateNode; var textContent = fiber.memoizedProps; var shouldWarnIfMismatchDev = !didSuspendOrErrorDEV; - var textIsDifferent = hydrateTextInstance( - textInstance, - textContent, - fiber - ); + var parentProps = null; // We assume that prepareToHydrateHostTextInstance is called in a context where the + // hydration parent is the parent host component of this host text. - if (textIsDifferent) { - // We assume that prepareToHydrateHostTextInstance is called in a context where the - // hydration parent is the parent host component of this host text. - var returnFiber = hydrationParentFiber; + var returnFiber = hydrationParentFiber; - if (returnFiber !== null) { - switch (returnFiber.tag) { - case HostRoot: { - var parentContainer = returnFiber.stateNode.containerInfo; - didNotMatchHydratedContainerTextInstance( - parentContainer, - textInstance, - textContent, - shouldWarnIfMismatchDev - ); - break; + if (returnFiber !== null) { + switch (returnFiber.tag) { + case HostRoot: { + { + if (shouldWarnIfMismatchDev) { + var difference = diffHydratedTextForDevWarnings( + textInstance, + textContent, + parentProps + ); + + if (difference !== null && !didWarnInvalidHydration) { + didWarnInvalidHydration = true; + + error( + 'Text content did not match. Server: "%s" Client: "%s"', + difference, + textContent + ); + } + } } - case HostSingleton: - case HostComponent: { - var parentType = returnFiber.type; - var parentProps = returnFiber.memoizedProps; - var parentInstance = returnFiber.stateNode; - didNotMatchHydratedTextInstance( - parentType, - parentProps, - parentInstance, - textInstance, - textContent, - shouldWarnIfMismatchDev - ); - break; + break; + } + + case HostSingleton: + case HostComponent: { + parentProps = returnFiber.memoizedProps; + + { + if (shouldWarnIfMismatchDev) { + var _difference = diffHydratedTextForDevWarnings( + textInstance, + textContent, + parentProps + ); + + if (_difference !== null && !didWarnInvalidHydration) { + didWarnInvalidHydration = true; + + error( + 'Text content did not match. Server: "%s" Client: "%s"', + _difference, + textContent + ); + } + } } + + break; } - } + } // TODO: What if it's a SuspenseInstance? + } + + var didHydrate = hydrateTextInstance( + textInstance, + textContent, + fiber, + parentProps + ); + + if (!didHydrate) { + throw new Error("Text content does not match server-rendered HTML."); } } @@ -31769,7 +31931,7 @@ if (__DEV__) { rootWorkInProgress.flags |= ForceClientRender; { - errorHydratingContainer(root.containerInfo); + errorHydratingContainer(); } } @@ -36037,7 +36199,7 @@ if (__DEV__) { return root; } - var ReactVersion = "19.0.0-www-modern-fda5cc55"; + var ReactVersion = "19.0.0-www-modern-6e7e6ecd"; function createPortal$1( children, @@ -41342,7 +41504,6 @@ if (__DEV__) { var didWarnControlledToUncontrolled = false; var didWarnUncontrolledToControlled = false; - var didWarnInvalidHydration = false; var didWarnFormActionType = false; var didWarnFormActionName = false; var didWarnFormActionTarget = false; @@ -41493,12 +41654,13 @@ if (__DEV__) { } } - function warnForPropDifference(propName, serverValue, clientValue) { + function warnForPropDifference( + propName, + serverValue, + clientValue, + serverDifferences + ) { { - if (didWarnInvalidHydration) { - return; - } - if (serverValue === clientValue) { return; } @@ -41512,30 +41674,22 @@ if (__DEV__) { return; } - didWarnInvalidHydration = true; - - error( - "Prop `%s` did not match. Server: %s Client: %s", - propName, - JSON.stringify(normalizedServerValue), - JSON.stringify(normalizedClientValue) - ); + serverDifferences[propName] = serverValue; } } - function warnForExtraAttributes(attributeNames) { + function warnForExtraAttributes( + domElement, + attributeNames, + serverDifferences + ) { { - if (didWarnInvalidHydration) { - return; - } - - didWarnInvalidHydration = true; - var names = []; - attributeNames.forEach(function (name) { - names.push(name); + attributeNames.forEach(function (attributeName) { + serverDifferences[attributeName] = + attributeName === "style" + ? getStylesObjectFromElement(domElement) + : domElement.getAttribute(attributeName); }); - - error("Extra attributes from the server: %s", names); } } @@ -41598,30 +41752,15 @@ if (__DEV__) { .replace(NORMALIZE_NULL_AND_REPLACEMENT_REGEX, ""); } - function checkForUnmatchedText(serverText, clientText, shouldWarnDev) { + function checkForUnmatchedText(serverText, clientText) { var normalizedClientText = normalizeMarkupForTextOrAttribute(clientText); var normalizedServerText = normalizeMarkupForTextOrAttribute(serverText); if (normalizedServerText === normalizedClientText) { - return; + return true; } - if (shouldWarnDev) { - { - if (!didWarnInvalidHydration) { - didWarnInvalidHydration = true; - - error( - 'Text content did not match. Server: "%s" Client: "%s"', - normalizedServerText, - normalizedClientText - ); - } - } - } // In concurrent roots, we throw when there's a text mismatch and revert to - // client rendering, up to the nearest Suspense boundary. - - throw new Error("Text content does not match server-rendered HTML."); + return false; } function noop$1() {} @@ -43382,19 +43521,70 @@ if (__DEV__) { } } - function diffHydratedStyles(domElement, value) { + function getPropsFromElement(domElement) { + var serverDifferences = {}; + var attributes = domElement.attributes; + + for (var i = 0; i < attributes.length; i++) { + var attr = attributes[i]; + serverDifferences[attr.name] = + attr.name.toLowerCase() === "style" + ? getStylesObjectFromElement(domElement) + : attr.value; + } + + return serverDifferences; + } + + function getStylesObjectFromElement(domElement) { + var serverValueInObjectForm = {}; + var style = domElement.style; + + for (var i = 0; i < style.length; i++) { + var styleName = style[i]; // TODO: We should use the original prop value here if it is equivalent. + // TODO: We could use the original client capitalization if the equivalent + // other capitalization exists in the DOM. + + serverValueInObjectForm[styleName] = style.getPropertyValue(styleName); + } + + return serverValueInObjectForm; + } + + function diffHydratedStyles(domElement, value, serverDifferences) { if (value != null && typeof value !== "object") { - throw new Error( - "The `style` prop expects a mapping from style properties to values, " + - "not a string. For example, style={{marginRight: spacing + 'em'}} when " + - "using JSX." - ); + { + error( + "The `style` prop expects a mapping from style properties to values, " + + "not a string. For example, style={{marginRight: spacing + 'em'}} when " + + "using JSX." + ); + } + + return; } if (canDiffStyleForHydrationWarning) { - var expectedStyle = createDangerousStringForStyles(value); + // First we compare the string form and see if it's equivalent. + // This lets us bail out on anything that used to pass in this form. + // It also lets us compare anything that's not parsed by this browser. + var clientValue = createDangerousStringForStyles(value); var serverValue = domElement.getAttribute("style"); - warnForPropDifference("style", serverValue, expectedStyle); + + if (serverValue === clientValue) { + return; + } + + var normalizedClientValue = + normalizeMarkupForTextOrAttribute(clientValue); + var normalizedServerValue = + normalizeMarkupForTextOrAttribute(serverValue); + + if (normalizedServerValue === normalizedClientValue) { + return; + } // Otherwise, we create the object from the DOM for the diff view. + + serverDifferences.style = getStylesObjectFromElement(domElement); } } @@ -43403,7 +43593,8 @@ if (__DEV__) { propKey, attributeName, value, - extraAttributes + extraAttributes, + serverDifferences ) { extraAttributes.delete(attributeName); var serverValue = domElement.getAttribute(attributeName); @@ -43438,7 +43629,7 @@ if (__DEV__) { } } - warnForPropDifference(propKey, serverValue, value); + warnForPropDifference(propKey, serverValue, value, serverDifferences); } function hydrateBooleanAttribute( @@ -43446,7 +43637,8 @@ if (__DEV__) { propKey, attributeName, value, - extraAttributes + extraAttributes, + serverDifferences ) { extraAttributes.delete(attributeName); var serverValue = domElement.getAttribute(attributeName); @@ -43478,7 +43670,7 @@ if (__DEV__) { } } - warnForPropDifference(propKey, serverValue, value); + warnForPropDifference(propKey, serverValue, value, serverDifferences); } function hydrateOverloadedBooleanAttribute( @@ -43486,7 +43678,8 @@ if (__DEV__) { propKey, attributeName, value, - extraAttributes + extraAttributes, + serverDifferences ) { extraAttributes.delete(attributeName); var serverValue = domElement.getAttribute(attributeName); @@ -43531,7 +43724,7 @@ if (__DEV__) { } } - warnForPropDifference(propKey, serverValue, value); + warnForPropDifference(propKey, serverValue, value, serverDifferences); } function hydrateBooleanishAttribute( @@ -43539,7 +43732,8 @@ if (__DEV__) { propKey, attributeName, value, - extraAttributes + extraAttributes, + serverDifferences ) { extraAttributes.delete(attributeName); var serverValue = domElement.getAttribute(attributeName); @@ -43572,7 +43766,7 @@ if (__DEV__) { } } - warnForPropDifference(propKey, serverValue, value); + warnForPropDifference(propKey, serverValue, value, serverDifferences); } function hydrateNumericAttribute( @@ -43580,7 +43774,8 @@ if (__DEV__) { propKey, attributeName, value, - extraAttributes + extraAttributes, + serverDifferences ) { extraAttributes.delete(attributeName); var serverValue = domElement.getAttribute(attributeName); @@ -43626,7 +43821,7 @@ if (__DEV__) { } } - warnForPropDifference(propKey, serverValue, value); + warnForPropDifference(propKey, serverValue, value, serverDifferences); } function hydratePositiveNumericAttribute( @@ -43634,7 +43829,8 @@ if (__DEV__) { propKey, attributeName, value, - extraAttributes + extraAttributes, + serverDifferences ) { extraAttributes.delete(attributeName); var serverValue = domElement.getAttribute(attributeName); @@ -43680,7 +43876,7 @@ if (__DEV__) { } } - warnForPropDifference(propKey, serverValue, value); + warnForPropDifference(propKey, serverValue, value, serverDifferences); } function hydrateSanitizedAttribute( @@ -43688,7 +43884,8 @@ if (__DEV__) { propKey, attributeName, value, - extraAttributes + extraAttributes, + serverDifferences ) { extraAttributes.delete(attributeName); var serverValue = domElement.getAttribute(attributeName); @@ -43725,7 +43922,7 @@ if (__DEV__) { } } - warnForPropDifference(propKey, serverValue, value); + warnForPropDifference(propKey, serverValue, value, serverDifferences); } function diffHydratedCustomComponent( @@ -43733,7 +43930,8 @@ if (__DEV__) { tag, props, hostContext, - extraAttributes + extraAttributes, + serverDifferences ) { for (var propKey in props) { if (!props.hasOwnProperty(propKey)) { @@ -43760,7 +43958,19 @@ if (__DEV__) { } // Validate that the properties correspond to their expected values. switch (propKey) { - case "children": // Checked above already + case "children": { + if (typeof value === "string" || typeof value === "number") { + warnForPropDifference( + "children", + domElement.textContent, + value, + serverDifferences + ); + } + + continue; + } + // Checked above already case "suppressContentEditableWarning": case "suppressHydrationWarning": @@ -43777,14 +43987,19 @@ if (__DEV__) { if (nextHtml != null) { var expectedHTML = normalizeHTML(domElement, nextHtml); - warnForPropDifference(propKey, serverHTML, expectedHTML); + warnForPropDifference( + propKey, + serverHTML, + expectedHTML, + serverDifferences + ); } continue; case "style": extraAttributes.delete(propKey); - diffHydratedStyles(domElement, value); + diffHydratedStyles(domElement, value, serverDifferences); continue; case "offsetParent": @@ -43817,7 +44032,12 @@ if (__DEV__) { "class", value ); - warnForPropDifference("className", serverValue, value); + warnForPropDifference( + "className", + serverValue, + value, + serverDifferences + ); continue; } @@ -43844,7 +44064,12 @@ if (__DEV__) { value ); - warnForPropDifference(propKey, _serverValue, value); + warnForPropDifference( + propKey, + _serverValue, + value, + serverDifferences + ); } } } @@ -43860,7 +44085,8 @@ if (__DEV__) { tag, props, hostContext, - extraAttributes + extraAttributes, + serverDifferences ) { for (var propKey in props) { if (!props.hasOwnProperty(propKey)) { @@ -43887,7 +44113,19 @@ if (__DEV__) { } // Validate that the properties correspond to their expected values. switch (propKey) { - case "children": // Checked above already + case "children": { + if (typeof value === "string" || typeof value === "number") { + warnForPropDifference( + "children", + domElement.textContent, + value, + serverDifferences + ); + } + + continue; + } + // Checked above already case "suppressContentEditableWarning": case "suppressHydrationWarning": @@ -43909,7 +44147,12 @@ if (__DEV__) { if (nextHtml != null) { var expectedHTML = normalizeHTML(domElement, nextHtml); - warnForPropDifference(propKey, serverHTML, expectedHTML); + + if (serverHTML !== expectedHTML) { + serverDifferences[propKey] = { + __html: serverHTML + }; + } } continue; @@ -43920,7 +44163,8 @@ if (__DEV__) { propKey, "class", value, - extraAttributes + extraAttributes, + serverDifferences ); continue; @@ -43930,33 +44174,49 @@ if (__DEV__) { propKey, "tabindex", value, - extraAttributes + extraAttributes, + serverDifferences ); continue; case "style": extraAttributes.delete(propKey); - diffHydratedStyles(domElement, value); + diffHydratedStyles(domElement, value, serverDifferences); continue; case "multiple": { extraAttributes.delete(propKey); var serverValue = domElement.multiple; - warnForPropDifference(propKey, serverValue, value); + warnForPropDifference( + propKey, + serverValue, + value, + serverDifferences + ); continue; } case "muted": { extraAttributes.delete(propKey); var _serverValue2 = domElement.muted; - warnForPropDifference(propKey, _serverValue2, value); + warnForPropDifference( + propKey, + _serverValue2, + value, + serverDifferences + ); continue; } case "autoFocus": { extraAttributes.delete("autofocus"); var _serverValue3 = domElement.autofocus; - warnForPropDifference(propKey, _serverValue3, value); + warnForPropDifference( + propKey, + _serverValue3, + value, + serverDifferences + ); continue; } @@ -43993,7 +44253,8 @@ if (__DEV__) { propKey, propKey, null, - extraAttributes + extraAttributes, + serverDifferences ); continue; } @@ -44004,7 +44265,8 @@ if (__DEV__) { propKey, propKey, value, - extraAttributes + extraAttributes, + serverDifferences ); continue; @@ -44035,7 +44297,12 @@ if (__DEV__) { continue; } else if (_serverValue4 === EXPECTED_FORM_ACTION_URL) { extraAttributes.delete(propKey.toLowerCase()); - warnForPropDifference(propKey, "function", value); + warnForPropDifference( + propKey, + "function", + value, + serverDifferences + ); continue; } @@ -44044,7 +44311,8 @@ if (__DEV__) { propKey, propKey.toLowerCase(), value, - extraAttributes + extraAttributes, + serverDifferences ); continue; } @@ -44055,7 +44323,8 @@ if (__DEV__) { propKey, "xlink:href", value, - extraAttributes + extraAttributes, + serverDifferences ); continue; @@ -44066,7 +44335,8 @@ if (__DEV__) { propKey, "contenteditable", value, - extraAttributes + extraAttributes, + serverDifferences ); continue; } @@ -44078,7 +44348,8 @@ if (__DEV__) { propKey, "spellcheck", value, - extraAttributes + extraAttributes, + serverDifferences ); continue; } @@ -44094,7 +44365,8 @@ if (__DEV__) { propKey, propKey, value, - extraAttributes + extraAttributes, + serverDifferences ); continue; } @@ -44127,7 +44399,8 @@ if (__DEV__) { propKey, propKey.toLowerCase(), value, - extraAttributes + extraAttributes, + serverDifferences ); continue; } @@ -44139,7 +44412,8 @@ if (__DEV__) { propKey, propKey, value, - extraAttributes + extraAttributes, + serverDifferences ); continue; } @@ -44153,7 +44427,8 @@ if (__DEV__) { propKey, propKey, value, - extraAttributes + extraAttributes, + serverDifferences ); continue; } @@ -44164,7 +44439,8 @@ if (__DEV__) { propKey, "rowspan", value, - extraAttributes + extraAttributes, + serverDifferences ); continue; } @@ -44175,7 +44451,8 @@ if (__DEV__) { propKey, propKey, value, - extraAttributes + extraAttributes, + serverDifferences ); continue; } @@ -44186,7 +44463,8 @@ if (__DEV__) { propKey, "x-height", value, - extraAttributes + extraAttributes, + serverDifferences ); continue; @@ -44196,7 +44474,8 @@ if (__DEV__) { propKey, "xlink:actuate", value, - extraAttributes + extraAttributes, + serverDifferences ); continue; @@ -44206,7 +44485,8 @@ if (__DEV__) { propKey, "xlink:arcrole", value, - extraAttributes + extraAttributes, + serverDifferences ); continue; @@ -44216,7 +44496,8 @@ if (__DEV__) { propKey, "xlink:role", value, - extraAttributes + extraAttributes, + serverDifferences ); continue; @@ -44226,7 +44507,8 @@ if (__DEV__) { propKey, "xlink:show", value, - extraAttributes + extraAttributes, + serverDifferences ); continue; @@ -44236,7 +44518,8 @@ if (__DEV__) { propKey, "xlink:title", value, - extraAttributes + extraAttributes, + serverDifferences ); continue; @@ -44246,7 +44529,8 @@ if (__DEV__) { propKey, "xlink:type", value, - extraAttributes + extraAttributes, + serverDifferences ); continue; @@ -44256,7 +44540,8 @@ if (__DEV__) { propKey, "xml:base", value, - extraAttributes + extraAttributes, + serverDifferences ); continue; @@ -44266,7 +44551,8 @@ if (__DEV__) { propKey, "xml:lang", value, - extraAttributes + extraAttributes, + serverDifferences ); continue; @@ -44276,7 +44562,8 @@ if (__DEV__) { propKey, "xml:space", value, - extraAttributes + extraAttributes, + serverDifferences ); continue; @@ -44304,7 +44591,8 @@ if (__DEV__) { propKey, propKey, value, - extraAttributes + extraAttributes, + serverDifferences ); continue; } @@ -44357,20 +44645,19 @@ if (__DEV__) { ); if (!isMismatchDueToBadCasing) { - warnForPropDifference(propKey, _serverValue5, value); + warnForPropDifference( + propKey, + _serverValue5, + value, + serverDifferences + ); } } } } } - function diffHydratedProperties( - domElement, - tag, - props, - shouldWarnDev, - hostContext - ) { + function hydrateProperties(domElement, tag, props, hostContext) { { validatePropertiesInDevelopment(tag, props); } // TODO: Make sure that we check isMounted before firing any of these events. @@ -44492,15 +44779,13 @@ if (__DEV__) { typeof children === "number" || (enableBigIntSupport && typeof children === "bigint") ) { - // $FlowFixMe[unsafe-addition] Flow doesn't want us to use `+` operator with string and bigint - if (domElement.textContent !== "" + children) { - if (props.suppressHydrationWarning !== true) { - checkForUnmatchedText( - domElement.textContent, - children, - shouldWarnDev - ); - } + if ( + // $FlowFixMe[unsafe-addition] Flow doesn't want us to use `+` operator with string and bigint + domElement.textContent !== "" + children && + props.suppressHydrationWarning !== true && + !checkForUnmatchedText(domElement.textContent, children) + ) { + return false; } } @@ -44517,12 +44802,17 @@ if (__DEV__) { trapClickOnNonInteractiveElement(domElement); } - if (shouldWarnDev) { + return true; + } + function diffHydratedProperties(domElement, tag, props, hostContext) { + var serverDifferences = {}; + + { var extraAttributes = new Set(); var attributes = domElement.attributes; - for (var _i = 0; _i < attributes.length; _i++) { - var name = attributes[_i].name.toLowerCase(); + for (var i = 0; i < attributes.length; i++) { + var name = attributes[i].name.toLowerCase(); switch (name) { // Controlled attributes are not validated @@ -44539,7 +44829,7 @@ if (__DEV__) { default: // Intentionally use the original name. // See discussion in https://github.com/facebook/react/pull/10676. - extraAttributes.add(attributes[_i].name); + extraAttributes.add(attributes[i].name); } } @@ -44549,7 +44839,8 @@ if (__DEV__) { tag, props, hostContext, - extraAttributes + extraAttributes, + serverDifferences ); } else { diffHydratedGenericElement( @@ -44557,7 +44848,8 @@ if (__DEV__) { tag, props, hostContext, - extraAttributes + extraAttributes, + serverDifferences ); } @@ -44565,73 +44857,49 @@ if (__DEV__) { extraAttributes.size > 0 && props.suppressHydrationWarning !== true ) { - warnForExtraAttributes(extraAttributes); + warnForExtraAttributes( + domElement, + extraAttributes, + serverDifferences + ); } } - } - function diffHydratedText(textNode, text) { - var isDifferent = textNode.nodeValue !== text; - return isDifferent; - } - function warnForDeletedHydratableElement(parentNode, child) { - { - if (didWarnInvalidHydration) { - return; - } - - didWarnInvalidHydration = true; - error( - "Did not expect server HTML to contain a <%s> in <%s>.", - child.nodeName.toLowerCase(), - parentNode.nodeName.toLowerCase() - ); + if (Object.keys(serverDifferences).length === 0) { + return null; } - } - function warnForDeletedHydratableText(parentNode, child) { - { - if (didWarnInvalidHydration) { - return; - } - - didWarnInvalidHydration = true; - error( - 'Did not expect server HTML to contain the text node "%s" in <%s>.', - child.nodeValue, - parentNode.nodeName.toLowerCase() - ); - } + return serverDifferences; } - function warnForInsertedHydratedElement(parentNode, tag, props) { - { - if (didWarnInvalidHydration) { - return; - } - - didWarnInvalidHydration = true; + function hydrateText(textNode, text, parentProps) { + var isDifferent = textNode.nodeValue !== text; - error( - "Expected server HTML to contain a matching <%s> in <%s>.", - tag, - parentNode.nodeName.toLowerCase() - ); + if ( + isDifferent && + (parentProps === null || + parentProps.suppressHydrationWarning !== true) && + !checkForUnmatchedText(textNode.nodeValue, text) + ) { + return false; } + + return true; } - function warnForInsertedHydratedText(parentNode, text) { - { - if (didWarnInvalidHydration) { - return; - } + function diffHydratedText(textNode, text) { + if (textNode.nodeValue === text) { + return null; + } - didWarnInvalidHydration = true; + var normalizedClientText = normalizeMarkupForTextOrAttribute(text); + var normalizedServerText = normalizeMarkupForTextOrAttribute( + textNode.nodeValue + ); - error( - 'Expected server HTML to contain a matching text node for "%s" in <%s>.', - text, - parentNode.nodeName.toLowerCase() - ); + if (normalizedServerText === normalizedClientText) { + return null; } + + return textNode.nodeValue; } function restoreControlledState(domElement, tag, props) { switch (tag) { @@ -45777,6 +46045,23 @@ if (__DEV__) { function getFirstHydratableChildWithinSuspenseInstance(parentInstance) { return getNextHydratable(parentInstance.nextSibling); } + function describeHydratableInstanceForDevWarnings(instance) { + // Reverse engineer a pseudo react-element from hydratable instnace + if (instance.nodeType === ELEMENT_NODE) { + // Reverse engineer a set of props that can print for dev warnings + return { + type: instance.nodeName.toLowerCase(), + props: getPropsFromElement(instance) + }; + } else if (instance.nodeType === COMMENT_NODE) { + return { + type: "Suspense", + props: {} + }; + } else { + return instance.nodeValue; + } + } function validateHydratableInstance(type, props, hostContext) { { // TODO: take namespace into account when validating. @@ -45789,14 +46074,22 @@ if (__DEV__) { type, props, hostContext, - internalInstanceHandle, - shouldWarnDev + internalInstanceHandle ) { precacheFiberNode(internalInstanceHandle, instance); // TODO: Possibly defer this until the commit phase where all the events // get attached. updateFiberProps(instance, props); - diffHydratedProperties(instance, type, props, shouldWarnDev, hostContext); + return hydrateProperties(instance, type, props); + } // Returns a Map of properties that were different on the server. + + function diffHydratedPropsForDevWarnings( + instance, + type, + props, + hostContext + ) { + return diffHydratedProperties(instance, type, props, hostContext); } function validateHydratableTextInstance(text, hostContext) { { @@ -45814,10 +46107,21 @@ if (__DEV__) { textInstance, text, internalInstanceHandle, - shouldWarnDev + parentInstanceProps ) { precacheFiberNode(internalInstanceHandle, textInstance); - return diffHydratedText(textInstance, text); + return hydrateText(textInstance, text, parentInstanceProps); + } // Returns the server text if it differs from the client. + + function diffHydratedTextForDevWarnings(textInstance, text, parentProps) { + if ( + parentProps === null || + parentProps[SUPPRESS_HYDRATION_WARNING] !== true + ) { + return diffHydratedText(textInstance, text); + } + + return null; } function hydrateSuspenseInstance(suspenseInstance, internalInstanceHandle) { precacheFiberNode(internalInstanceHandle, suspenseInstance); @@ -45897,139 +46201,6 @@ if (__DEV__) { } function shouldDeleteUnhydratedTailInstances(parentType) { return parentType !== "form" && parentType !== "button"; - } - function didNotMatchHydratedContainerTextInstance( - parentContainer, - textInstance, - text, - shouldWarnDev - ) { - checkForUnmatchedText(textInstance.nodeValue, text, shouldWarnDev); - } - function didNotMatchHydratedTextInstance( - parentType, - parentProps, - parentInstance, - textInstance, - text, - shouldWarnDev - ) { - if (parentProps[SUPPRESS_HYDRATION_WARNING] !== true) { - checkForUnmatchedText(textInstance.nodeValue, text, shouldWarnDev); - } - } - function didNotHydrateInstanceWithinContainer(parentContainer, instance) { - { - if (instance.nodeType === ELEMENT_NODE) { - warnForDeletedHydratableElement(parentContainer, instance); - } else if (instance.nodeType === COMMENT_NODE); - else { - warnForDeletedHydratableText(parentContainer, instance); - } - } - } - function didNotHydrateInstanceWithinSuspenseInstance( - parentInstance, - instance - ) { - { - // $FlowFixMe[incompatible-type]: Only Element or Document can be parent nodes. - var parentNode = parentInstance.parentNode; - - if (parentNode !== null) { - if (instance.nodeType === ELEMENT_NODE) { - warnForDeletedHydratableElement(parentNode, instance); - } else if (instance.nodeType === COMMENT_NODE); - else { - warnForDeletedHydratableText(parentNode, instance); - } - } - } - } - function didNotHydrateInstance( - parentType, - parentProps, - parentInstance, - instance - ) { - { - if (instance.nodeType === ELEMENT_NODE) { - warnForDeletedHydratableElement(parentInstance, instance); - } else if (instance.nodeType === COMMENT_NODE); - else { - warnForDeletedHydratableText(parentInstance, instance); - } - } - } - function didNotFindHydratableInstanceWithinContainer( - parentContainer, - type, - props - ) { - { - warnForInsertedHydratedElement(parentContainer, type); - } - } - function didNotFindHydratableTextInstanceWithinContainer( - parentContainer, - text - ) { - { - warnForInsertedHydratedText(parentContainer, text); - } - } - function didNotFindHydratableInstanceWithinSuspenseInstance( - parentInstance, - type, - props - ) { - { - // $FlowFixMe[incompatible-type]: Only Element or Document can be parent nodes. - var parentNode = parentInstance.parentNode; - if (parentNode !== null) - warnForInsertedHydratedElement(parentNode, type); - } - } - function didNotFindHydratableTextInstanceWithinSuspenseInstance( - parentInstance, - text - ) { - { - // $FlowFixMe[incompatible-type]: Only Element or Document can be parent nodes. - var parentNode = parentInstance.parentNode; - if (parentNode !== null) warnForInsertedHydratedText(parentNode, text); - } - } - function didNotFindHydratableInstance( - parentType, - parentProps, - parentInstance, - type, - props - ) { - { - warnForInsertedHydratedElement(parentInstance, type); - } - } - function didNotFindHydratableTextInstance( - parentType, - parentProps, - parentInstance, - text - ) { - { - warnForInsertedHydratedText(parentInstance, text); - } - } - function errorHydratingContainer(parentContainer) { - { - // TODO: This gets logged by onRecoverableError, too, so we should be - // able to remove it. - error( - "An error occurred during hydration. The server HTML was replaced with client content in <%s>.", - parentContainer.nodeName.toLowerCase() - ); - } } // ------------------- function findFiberRoot(node) { var stack = [node]; diff --git a/compiled/facebook-www/ReactDOMTesting-prod.classic.js b/compiled/facebook-www/ReactDOMTesting-prod.classic.js index 15b3db4335327..f1fa42095991f 100644 --- a/compiled/facebook-www/ReactDOMTesting-prod.classic.js +++ b/compiled/facebook-www/ReactDOMTesting-prod.classic.js @@ -1793,6 +1793,76 @@ var hydrationParentFiber = null, function throwOnHydrationMismatch() { throw Error(formatProdErrorMessage(418)); } +function prepareToHydrateHostInstance(fiber) { + var instance = fiber.stateNode, + type = fiber.type, + props = fiber.memoizedProps; + instance[internalInstanceKey] = fiber; + instance[internalPropsKey] = props; + switch (type) { + case "dialog": + listenToNonDelegatedEvent("cancel", instance); + listenToNonDelegatedEvent("close", instance); + break; + case "iframe": + case "object": + case "embed": + listenToNonDelegatedEvent("load", instance); + break; + case "video": + case "audio": + for (fiber = 0; fiber < mediaEventTypes.length; fiber++) + listenToNonDelegatedEvent(mediaEventTypes[fiber], instance); + break; + case "source": + listenToNonDelegatedEvent("error", instance); + break; + case "img": + case "image": + case "link": + listenToNonDelegatedEvent("error", instance); + listenToNonDelegatedEvent("load", instance); + break; + case "details": + listenToNonDelegatedEvent("toggle", instance); + break; + case "input": + listenToNonDelegatedEvent("invalid", instance); + initInput( + instance, + props.value, + props.defaultValue, + props.checked, + props.defaultChecked, + props.type, + props.name, + !0 + ); + track(instance); + break; + case "select": + listenToNonDelegatedEvent("invalid", instance); + break; + case "textarea": + listenToNonDelegatedEvent("invalid", instance), + initTextarea(instance, props.value, props.defaultValue, props.children), + track(instance); + } + fiber = props.children; + ("string" === typeof fiber || + "number" === typeof fiber || + (enableBigIntSupport && "bigint" === typeof fiber)) && + instance.textContent !== "" + fiber && + !0 !== props.suppressHydrationWarning && + !checkForUnmatchedText(instance.textContent, fiber) + ? (instance = !1) + : (null != props.onScroll && listenToNonDelegatedEvent("scroll", instance), + null != props.onScrollEnd && + listenToNonDelegatedEvent("scrollend", instance), + null != props.onClick && (instance.onclick = noop$2), + (instance = !0)); + if (!instance) throw Error(formatProdErrorMessage(425)); +} function popToNextHostParent(fiber) { for (hydrationParentFiber = fiber.return; hydrationParentFiber; ) switch (hydrationParentFiber.tag) { @@ -7870,13 +7940,7 @@ function completeWork(current, workInProgress, renderLanes) { } current = contextStackCursor$1.current; popHydrationState(workInProgress) - ? hydrateInstance( - workInProgress.stateNode, - workInProgress.type, - workInProgress.memoizedProps, - current, - workInProgress - ) + ? prepareToHydrateHostInstance(workInProgress, current) : ((current = resolveSingletonInstance( currentResource, newProps, @@ -7901,13 +7965,7 @@ function completeWork(current, workInProgress, renderLanes) { } current = contextStackCursor$1.current; if (popHydrationState(workInProgress)) - hydrateInstance( - workInProgress.stateNode, - workInProgress.type, - workInProgress.memoizedProps, - current, - workInProgress - ); + prepareToHydrateHostInstance(workInProgress, current); else { currentResource = getOwnerDocumentFromRootContainer( rootInstanceStackCursor.current @@ -8024,22 +8082,24 @@ function completeWork(current, workInProgress, renderLanes) { throw Error(formatProdErrorMessage(166)); current = rootInstanceStackCursor.current; if (popHydrationState(workInProgress)) { - if ( - ((current = workInProgress.stateNode), - (renderLanes = workInProgress.memoizedProps), - (current[internalInstanceKey] = workInProgress), - current.nodeValue !== renderLanes && - ((newProps = hydrationParentFiber), null !== newProps)) - ) - switch (newProps.tag) { - case 3: - checkForUnmatchedText(current.nodeValue, renderLanes); - break; + current = workInProgress.stateNode; + renderLanes = workInProgress.memoizedProps; + newProps = null; + currentResource = hydrationParentFiber; + if (null !== currentResource) + switch (currentResource.tag) { case 27: case 5: - !0 !== newProps.memoizedProps.suppressHydrationWarning && - checkForUnmatchedText(current.nodeValue, renderLanes); + newProps = currentResource.memoizedProps; } + current[internalInstanceKey] = workInProgress; + current = + current.nodeValue === renderLanes || + (null !== newProps && !0 === newProps.suppressHydrationWarning) || + checkForUnmatchedText(current.nodeValue, renderLanes) + ? !0 + : !1; + if (!current) throw Error(formatProdErrorMessage(425)); } else (current = getOwnerDocumentFromRootContainer(current).createTextNode( @@ -13261,14 +13321,14 @@ var isInputEventSupported = !1; if (canUseDOM) { var JSCompiler_inline_result$jscomp$346; if (canUseDOM) { - var isSupported$jscomp$inline_1541 = "oninput" in document; - if (!isSupported$jscomp$inline_1541) { - var element$jscomp$inline_1542 = document.createElement("div"); - element$jscomp$inline_1542.setAttribute("oninput", "return;"); - isSupported$jscomp$inline_1541 = - "function" === typeof element$jscomp$inline_1542.oninput; + var isSupported$jscomp$inline_1532 = "oninput" in document; + if (!isSupported$jscomp$inline_1532) { + var element$jscomp$inline_1533 = document.createElement("div"); + element$jscomp$inline_1533.setAttribute("oninput", "return;"); + isSupported$jscomp$inline_1532 = + "function" === typeof element$jscomp$inline_1533.oninput; } - JSCompiler_inline_result$jscomp$346 = isSupported$jscomp$inline_1541; + JSCompiler_inline_result$jscomp$346 = isSupported$jscomp$inline_1532; } else JSCompiler_inline_result$jscomp$346 = !1; isInputEventSupported = JSCompiler_inline_result$jscomp$346 && @@ -13643,20 +13703,20 @@ function extractEvents$1( } } for ( - var i$jscomp$inline_1582 = 0; - i$jscomp$inline_1582 < simpleEventPluginEvents.length; - i$jscomp$inline_1582++ + var i$jscomp$inline_1573 = 0; + i$jscomp$inline_1573 < simpleEventPluginEvents.length; + i$jscomp$inline_1573++ ) { - var eventName$jscomp$inline_1583 = - simpleEventPluginEvents[i$jscomp$inline_1582], - domEventName$jscomp$inline_1584 = - eventName$jscomp$inline_1583.toLowerCase(), - capitalizedEvent$jscomp$inline_1585 = - eventName$jscomp$inline_1583[0].toUpperCase() + - eventName$jscomp$inline_1583.slice(1); + var eventName$jscomp$inline_1574 = + simpleEventPluginEvents[i$jscomp$inline_1573], + domEventName$jscomp$inline_1575 = + eventName$jscomp$inline_1574.toLowerCase(), + capitalizedEvent$jscomp$inline_1576 = + eventName$jscomp$inline_1574[0].toUpperCase() + + eventName$jscomp$inline_1574.slice(1); registerSimpleEvent( - domEventName$jscomp$inline_1584, - "on" + capitalizedEvent$jscomp$inline_1585 + domEventName$jscomp$inline_1575, + "on" + capitalizedEvent$jscomp$inline_1576 ); } registerSimpleEvent(ANIMATION_END, "onAnimationEnd"); @@ -14504,8 +14564,7 @@ function normalizeMarkupForTextOrAttribute(markup) { } function checkForUnmatchedText(serverText, clientText) { clientText = normalizeMarkupForTextOrAttribute(clientText); - if (normalizeMarkupForTextOrAttribute(serverText) !== clientText) - throw Error(formatProdErrorMessage(425)); + return normalizeMarkupForTextOrAttribute(serverText) === clientText ? !0 : !1; } function noop$2() {} function setProp(domElement, tag, key, value, props, prevValue) { @@ -15703,75 +15762,6 @@ function getNextHydratable(node) { } return node; } -function hydrateInstance( - instance, - type, - props, - hostContext, - internalInstanceHandle -) { - instance[internalInstanceKey] = internalInstanceHandle; - instance[internalPropsKey] = props; - switch (type) { - case "dialog": - listenToNonDelegatedEvent("cancel", instance); - listenToNonDelegatedEvent("close", instance); - break; - case "iframe": - case "object": - case "embed": - listenToNonDelegatedEvent("load", instance); - break; - case "video": - case "audio": - for (type = 0; type < mediaEventTypes.length; type++) - listenToNonDelegatedEvent(mediaEventTypes[type], instance); - break; - case "source": - listenToNonDelegatedEvent("error", instance); - break; - case "img": - case "image": - case "link": - listenToNonDelegatedEvent("error", instance); - listenToNonDelegatedEvent("load", instance); - break; - case "details": - listenToNonDelegatedEvent("toggle", instance); - break; - case "input": - listenToNonDelegatedEvent("invalid", instance); - initInput( - instance, - props.value, - props.defaultValue, - props.checked, - props.defaultChecked, - props.type, - props.name, - !0 - ); - track(instance); - break; - case "select": - listenToNonDelegatedEvent("invalid", instance); - break; - case "textarea": - listenToNonDelegatedEvent("invalid", instance), - initTextarea(instance, props.value, props.defaultValue, props.children), - track(instance); - } - type = props.children; - ("string" === typeof type || - "number" === typeof type || - (enableBigIntSupport && "bigint" === typeof type)) && - instance.textContent !== "" + type && - !0 !== props.suppressHydrationWarning && - checkForUnmatchedText(instance.textContent, type); - null != props.onScroll && listenToNonDelegatedEvent("scroll", instance); - null != props.onScrollEnd && listenToNonDelegatedEvent("scrollend", instance); - null != props.onClick && (instance.onclick = noop$2); -} function getParentSuspenseInstance(targetInstance) { targetInstance = targetInstance.previousSibling; for (var depth = 0; targetInstance; ) { @@ -17420,17 +17410,17 @@ Internals.Events = [ restoreStateIfNeeded, batchedUpdates$1 ]; -var devToolsConfig$jscomp$inline_1783 = { +var devToolsConfig$jscomp$inline_1767 = { findFiberByHostInstance: getClosestInstanceFromNode, bundleType: 0, - version: "19.0.0-www-classic-9d11c499", + version: "19.0.0-www-classic-add5fde3", rendererPackageName: "react-dom" }; -var internals$jscomp$inline_2183 = { - bundleType: devToolsConfig$jscomp$inline_1783.bundleType, - version: devToolsConfig$jscomp$inline_1783.version, - rendererPackageName: devToolsConfig$jscomp$inline_1783.rendererPackageName, - rendererConfig: devToolsConfig$jscomp$inline_1783.rendererConfig, +var internals$jscomp$inline_2159 = { + bundleType: devToolsConfig$jscomp$inline_1767.bundleType, + version: devToolsConfig$jscomp$inline_1767.version, + rendererPackageName: devToolsConfig$jscomp$inline_1767.rendererPackageName, + rendererConfig: devToolsConfig$jscomp$inline_1767.rendererConfig, overrideHookState: null, overrideHookStateDeletePath: null, overrideHookStateRenamePath: null, @@ -17446,26 +17436,26 @@ var internals$jscomp$inline_2183 = { return null === fiber ? null : fiber.stateNode; }, findFiberByHostInstance: - devToolsConfig$jscomp$inline_1783.findFiberByHostInstance || + devToolsConfig$jscomp$inline_1767.findFiberByHostInstance || emptyFindFiberByHostInstance, findHostInstancesForRefresh: null, scheduleRefresh: null, scheduleRoot: null, setRefreshHandler: null, getCurrentFiber: null, - reconcilerVersion: "19.0.0-www-classic-9d11c499" + reconcilerVersion: "19.0.0-www-classic-add5fde3" }; if ("undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__) { - var hook$jscomp$inline_2184 = __REACT_DEVTOOLS_GLOBAL_HOOK__; + var hook$jscomp$inline_2160 = __REACT_DEVTOOLS_GLOBAL_HOOK__; if ( - !hook$jscomp$inline_2184.isDisabled && - hook$jscomp$inline_2184.supportsFiber + !hook$jscomp$inline_2160.isDisabled && + hook$jscomp$inline_2160.supportsFiber ) try { - (rendererID = hook$jscomp$inline_2184.inject( - internals$jscomp$inline_2183 + (rendererID = hook$jscomp$inline_2160.inject( + internals$jscomp$inline_2159 )), - (injectedHook = hook$jscomp$inline_2184); + (injectedHook = hook$jscomp$inline_2160); } catch (err) {} } assign(Internals, { @@ -17924,4 +17914,4 @@ exports.useFormState = function (action, initialState, permalink) { exports.useFormStatus = function () { return ReactCurrentDispatcher$2.current.useHostTransitionStatus(); }; -exports.version = "19.0.0-www-classic-9d11c499"; +exports.version = "19.0.0-www-classic-add5fde3"; diff --git a/compiled/facebook-www/ReactDOMTesting-prod.modern.js b/compiled/facebook-www/ReactDOMTesting-prod.modern.js index 90de7f725f867..949c83188c364 100644 --- a/compiled/facebook-www/ReactDOMTesting-prod.modern.js +++ b/compiled/facebook-www/ReactDOMTesting-prod.modern.js @@ -1748,6 +1748,76 @@ var hydrationParentFiber = null, function throwOnHydrationMismatch() { throw Error(formatProdErrorMessage(418)); } +function prepareToHydrateHostInstance(fiber) { + var instance = fiber.stateNode, + type = fiber.type, + props = fiber.memoizedProps; + instance[internalInstanceKey] = fiber; + instance[internalPropsKey] = props; + switch (type) { + case "dialog": + listenToNonDelegatedEvent("cancel", instance); + listenToNonDelegatedEvent("close", instance); + break; + case "iframe": + case "object": + case "embed": + listenToNonDelegatedEvent("load", instance); + break; + case "video": + case "audio": + for (fiber = 0; fiber < mediaEventTypes.length; fiber++) + listenToNonDelegatedEvent(mediaEventTypes[fiber], instance); + break; + case "source": + listenToNonDelegatedEvent("error", instance); + break; + case "img": + case "image": + case "link": + listenToNonDelegatedEvent("error", instance); + listenToNonDelegatedEvent("load", instance); + break; + case "details": + listenToNonDelegatedEvent("toggle", instance); + break; + case "input": + listenToNonDelegatedEvent("invalid", instance); + initInput( + instance, + props.value, + props.defaultValue, + props.checked, + props.defaultChecked, + props.type, + props.name, + !0 + ); + track(instance); + break; + case "select": + listenToNonDelegatedEvent("invalid", instance); + break; + case "textarea": + listenToNonDelegatedEvent("invalid", instance), + initTextarea(instance, props.value, props.defaultValue), + track(instance); + } + fiber = props.children; + ("string" === typeof fiber || + "number" === typeof fiber || + (enableBigIntSupport && "bigint" === typeof fiber)) && + instance.textContent !== "" + fiber && + !0 !== props.suppressHydrationWarning && + !checkForUnmatchedText(instance.textContent, fiber) + ? (instance = !1) + : (null != props.onScroll && listenToNonDelegatedEvent("scroll", instance), + null != props.onScrollEnd && + listenToNonDelegatedEvent("scrollend", instance), + null != props.onClick && (instance.onclick = noop$1), + (instance = !0)); + if (!instance) throw Error(formatProdErrorMessage(425)); +} function popToNextHostParent(fiber) { for (hydrationParentFiber = fiber.return; hydrationParentFiber; ) switch (hydrationParentFiber.tag) { @@ -7744,13 +7814,7 @@ function completeWork(current, workInProgress, renderLanes) { } current = contextStackCursor.current; popHydrationState(workInProgress) - ? hydrateInstance( - workInProgress.stateNode, - workInProgress.type, - workInProgress.memoizedProps, - current, - workInProgress - ) + ? prepareToHydrateHostInstance(workInProgress, current) : ((current = resolveSingletonInstance( currentResource, newProps, @@ -7775,13 +7839,7 @@ function completeWork(current, workInProgress, renderLanes) { } current = contextStackCursor.current; if (popHydrationState(workInProgress)) - hydrateInstance( - workInProgress.stateNode, - workInProgress.type, - workInProgress.memoizedProps, - current, - workInProgress - ); + prepareToHydrateHostInstance(workInProgress, current); else { currentResource = getOwnerDocumentFromRootContainer( rootInstanceStackCursor.current @@ -7898,22 +7956,24 @@ function completeWork(current, workInProgress, renderLanes) { throw Error(formatProdErrorMessage(166)); current = rootInstanceStackCursor.current; if (popHydrationState(workInProgress)) { - if ( - ((current = workInProgress.stateNode), - (renderLanes = workInProgress.memoizedProps), - (current[internalInstanceKey] = workInProgress), - current.nodeValue !== renderLanes && - ((newProps = hydrationParentFiber), null !== newProps)) - ) - switch (newProps.tag) { - case 3: - checkForUnmatchedText(current.nodeValue, renderLanes); - break; + current = workInProgress.stateNode; + renderLanes = workInProgress.memoizedProps; + newProps = null; + currentResource = hydrationParentFiber; + if (null !== currentResource) + switch (currentResource.tag) { case 27: case 5: - !0 !== newProps.memoizedProps.suppressHydrationWarning && - checkForUnmatchedText(current.nodeValue, renderLanes); + newProps = currentResource.memoizedProps; } + current[internalInstanceKey] = workInProgress; + current = + current.nodeValue === renderLanes || + (null !== newProps && !0 === newProps.suppressHydrationWarning) || + checkForUnmatchedText(current.nodeValue, renderLanes) + ? !0 + : !1; + if (!current) throw Error(formatProdErrorMessage(425)); } else (current = getOwnerDocumentFromRootContainer(current).createTextNode( @@ -13689,14 +13749,14 @@ var isInputEventSupported = !1; if (canUseDOM) { var JSCompiler_inline_result$jscomp$344; if (canUseDOM) { - var isSupported$jscomp$inline_1541 = "oninput" in document; - if (!isSupported$jscomp$inline_1541) { - var element$jscomp$inline_1542 = document.createElement("div"); - element$jscomp$inline_1542.setAttribute("oninput", "return;"); - isSupported$jscomp$inline_1541 = - "function" === typeof element$jscomp$inline_1542.oninput; + var isSupported$jscomp$inline_1532 = "oninput" in document; + if (!isSupported$jscomp$inline_1532) { + var element$jscomp$inline_1533 = document.createElement("div"); + element$jscomp$inline_1533.setAttribute("oninput", "return;"); + isSupported$jscomp$inline_1532 = + "function" === typeof element$jscomp$inline_1533.oninput; } - JSCompiler_inline_result$jscomp$344 = isSupported$jscomp$inline_1541; + JSCompiler_inline_result$jscomp$344 = isSupported$jscomp$inline_1532; } else JSCompiler_inline_result$jscomp$344 = !1; isInputEventSupported = JSCompiler_inline_result$jscomp$344 && @@ -14008,20 +14068,20 @@ function registerSimpleEvent(domEventName, reactName) { registerTwoPhaseEvent(reactName, [domEventName]); } for ( - var i$jscomp$inline_1582 = 0; - i$jscomp$inline_1582 < simpleEventPluginEvents.length; - i$jscomp$inline_1582++ + var i$jscomp$inline_1573 = 0; + i$jscomp$inline_1573 < simpleEventPluginEvents.length; + i$jscomp$inline_1573++ ) { - var eventName$jscomp$inline_1583 = - simpleEventPluginEvents[i$jscomp$inline_1582], - domEventName$jscomp$inline_1584 = - eventName$jscomp$inline_1583.toLowerCase(), - capitalizedEvent$jscomp$inline_1585 = - eventName$jscomp$inline_1583[0].toUpperCase() + - eventName$jscomp$inline_1583.slice(1); + var eventName$jscomp$inline_1574 = + simpleEventPluginEvents[i$jscomp$inline_1573], + domEventName$jscomp$inline_1575 = + eventName$jscomp$inline_1574.toLowerCase(), + capitalizedEvent$jscomp$inline_1576 = + eventName$jscomp$inline_1574[0].toUpperCase() + + eventName$jscomp$inline_1574.slice(1); registerSimpleEvent( - domEventName$jscomp$inline_1584, - "on" + capitalizedEvent$jscomp$inline_1585 + domEventName$jscomp$inline_1575, + "on" + capitalizedEvent$jscomp$inline_1576 ); } registerSimpleEvent(ANIMATION_END, "onAnimationEnd"); @@ -14869,8 +14929,7 @@ function normalizeMarkupForTextOrAttribute(markup) { } function checkForUnmatchedText(serverText, clientText) { clientText = normalizeMarkupForTextOrAttribute(clientText); - if (normalizeMarkupForTextOrAttribute(serverText) !== clientText) - throw Error(formatProdErrorMessage(425)); + return normalizeMarkupForTextOrAttribute(serverText) === clientText ? !0 : !1; } function noop$1() {} function setProp(domElement, tag, key, value, props, prevValue) { @@ -16037,75 +16096,6 @@ function getNextHydratable(node) { } return node; } -function hydrateInstance( - instance, - type, - props, - hostContext, - internalInstanceHandle -) { - instance[internalInstanceKey] = internalInstanceHandle; - instance[internalPropsKey] = props; - switch (type) { - case "dialog": - listenToNonDelegatedEvent("cancel", instance); - listenToNonDelegatedEvent("close", instance); - break; - case "iframe": - case "object": - case "embed": - listenToNonDelegatedEvent("load", instance); - break; - case "video": - case "audio": - for (type = 0; type < mediaEventTypes.length; type++) - listenToNonDelegatedEvent(mediaEventTypes[type], instance); - break; - case "source": - listenToNonDelegatedEvent("error", instance); - break; - case "img": - case "image": - case "link": - listenToNonDelegatedEvent("error", instance); - listenToNonDelegatedEvent("load", instance); - break; - case "details": - listenToNonDelegatedEvent("toggle", instance); - break; - case "input": - listenToNonDelegatedEvent("invalid", instance); - initInput( - instance, - props.value, - props.defaultValue, - props.checked, - props.defaultChecked, - props.type, - props.name, - !0 - ); - track(instance); - break; - case "select": - listenToNonDelegatedEvent("invalid", instance); - break; - case "textarea": - listenToNonDelegatedEvent("invalid", instance), - initTextarea(instance, props.value, props.defaultValue), - track(instance); - } - type = props.children; - ("string" === typeof type || - "number" === typeof type || - (enableBigIntSupport && "bigint" === typeof type)) && - instance.textContent !== "" + type && - !0 !== props.suppressHydrationWarning && - checkForUnmatchedText(instance.textContent, type); - null != props.onScroll && listenToNonDelegatedEvent("scroll", instance); - null != props.onScrollEnd && listenToNonDelegatedEvent("scrollend", instance); - null != props.onClick && (instance.onclick = noop$1); -} function getParentSuspenseInstance(targetInstance) { targetInstance = targetInstance.previousSibling; for (var depth = 0; targetInstance; ) { @@ -16997,17 +16987,17 @@ Internals.Events = [ restoreStateIfNeeded, batchedUpdates$1 ]; -var devToolsConfig$jscomp$inline_1742 = { +var devToolsConfig$jscomp$inline_1726 = { findFiberByHostInstance: getClosestInstanceFromNode, bundleType: 0, - version: "19.0.0-www-modern-3f5d8a58", + version: "19.0.0-www-modern-ec31e15a", rendererPackageName: "react-dom" }; -var internals$jscomp$inline_2146 = { - bundleType: devToolsConfig$jscomp$inline_1742.bundleType, - version: devToolsConfig$jscomp$inline_1742.version, - rendererPackageName: devToolsConfig$jscomp$inline_1742.rendererPackageName, - rendererConfig: devToolsConfig$jscomp$inline_1742.rendererConfig, +var internals$jscomp$inline_2122 = { + bundleType: devToolsConfig$jscomp$inline_1726.bundleType, + version: devToolsConfig$jscomp$inline_1726.version, + rendererPackageName: devToolsConfig$jscomp$inline_1726.rendererPackageName, + rendererConfig: devToolsConfig$jscomp$inline_1726.rendererConfig, overrideHookState: null, overrideHookStateDeletePath: null, overrideHookStateRenamePath: null, @@ -17024,26 +17014,26 @@ var internals$jscomp$inline_2146 = { return null === fiber ? null : fiber.stateNode; }, findFiberByHostInstance: - devToolsConfig$jscomp$inline_1742.findFiberByHostInstance || + devToolsConfig$jscomp$inline_1726.findFiberByHostInstance || emptyFindFiberByHostInstance, findHostInstancesForRefresh: null, scheduleRefresh: null, scheduleRoot: null, setRefreshHandler: null, getCurrentFiber: null, - reconcilerVersion: "19.0.0-www-modern-3f5d8a58" + reconcilerVersion: "19.0.0-www-modern-ec31e15a" }; if ("undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__) { - var hook$jscomp$inline_2147 = __REACT_DEVTOOLS_GLOBAL_HOOK__; + var hook$jscomp$inline_2123 = __REACT_DEVTOOLS_GLOBAL_HOOK__; if ( - !hook$jscomp$inline_2147.isDisabled && - hook$jscomp$inline_2147.supportsFiber + !hook$jscomp$inline_2123.isDisabled && + hook$jscomp$inline_2123.supportsFiber ) try { - (rendererID = hook$jscomp$inline_2147.inject( - internals$jscomp$inline_2146 + (rendererID = hook$jscomp$inline_2123.inject( + internals$jscomp$inline_2122 )), - (injectedHook = hook$jscomp$inline_2147); + (injectedHook = hook$jscomp$inline_2123); } catch (err) {} } exports.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED = Internals; @@ -17440,4 +17430,4 @@ exports.useFormState = function (action, initialState, permalink) { exports.useFormStatus = function () { return ReactCurrentDispatcher$2.current.useHostTransitionStatus(); }; -exports.version = "19.0.0-www-modern-3f5d8a58"; +exports.version = "19.0.0-www-modern-ec31e15a"; diff --git a/compiled/facebook-www/ReactTestRenderer-dev.classic.js b/compiled/facebook-www/ReactTestRenderer-dev.classic.js index b7acded1c688f..231e7361e45c1 100644 --- a/compiled/facebook-www/ReactTestRenderer-dev.classic.js +++ b/compiled/facebook-www/ReactTestRenderer-dev.classic.js @@ -2023,13 +2023,14 @@ if (__DEV__) { "Please file an issue." ); } // Hydration (when unsupported) + + var supportsHydration = false; var isSuspenseInstancePending = shim$1; var isSuspenseInstanceFallback = shim$1; var getSuspenseInstanceFallbackErrorDetails = shim$1; var registerSuspenseInstanceRetry = shim$1; var clearSuspenseBoundary = shim$1; var clearSuspenseBoundaryFromContainer = shim$1; - var errorHydratingContainer = shim$1; // Renderers that don't support hydration // can re-export everything from this module. @@ -2566,14 +2567,6 @@ if (__DEV__) { var objectIs = typeof Object.is === "function" ? Object.is : is; // $FlowFixMe[method-unbinding] - // This is imported by the event replaying implementation in React DOM. It's - // in a separate file to break a circular dependency between the renderer and - // the reconciler. - function isRootDehydrated(root) { - var currentState = root.current.memoizedState; - return currentState.isDehydrated; - } - var contextStackCursor = createCursor(null); var contextFiberStackCursor = createCursor(null); var rootInstanceStackCursor = createCursor(null); // Represents the nearest host transition provider (in React DOM, a ) @@ -22372,27 +22365,7 @@ if (__DEV__) { // back to client side render. // Before rendering again, save the errors from the previous attempt. var errorsFromFirstAttempt = workInProgressRootConcurrentErrors; - var wasRootDehydrated = isRootDehydrated(root); - - if (wasRootDehydrated) { - // The shell failed to hydrate. Set a flag to force a client rendering - // during the next attempt. To do this, we call prepareFreshStack now - // to create the root work-in-progress fiber. This is a bit weird in terms - // of factoring, because it relies on renderRootSync not calling - // prepareFreshStack again in the call below, which happens because the - // root and lanes haven't changed. - // - // TODO: I think what we should do is set ForceClientRender inside - // throwException, like we do for nested Suspense boundaries. The reason - // it's here instead is so we can switch to the synchronous work loop, too. - // Something to consider for a future refactor. - var rootWorkInProgress = prepareFreshStack(root, errorRetryLanes); - rootWorkInProgress.flags |= ForceClientRender; - - { - errorHydratingContainer(); - } - } + var wasRootDehydrated = supportsHydration; var exitStatus = renderRootSync(root, errorRetryLanes); @@ -26109,7 +26082,7 @@ if (__DEV__) { return root; } - var ReactVersion = "19.0.0-www-classic-ac0f08bc"; + var ReactVersion = "19.0.0-www-classic-1ccc623b"; // Might add PROFILE later. diff --git a/compiled/facebook-www/ReactTestRenderer-dev.modern.js b/compiled/facebook-www/ReactTestRenderer-dev.modern.js index b21fa01507263..d8925dab6740f 100644 --- a/compiled/facebook-www/ReactTestRenderer-dev.modern.js +++ b/compiled/facebook-www/ReactTestRenderer-dev.modern.js @@ -2023,13 +2023,14 @@ if (__DEV__) { "Please file an issue." ); } // Hydration (when unsupported) + + var supportsHydration = false; var isSuspenseInstancePending = shim$1; var isSuspenseInstanceFallback = shim$1; var getSuspenseInstanceFallbackErrorDetails = shim$1; var registerSuspenseInstanceRetry = shim$1; var clearSuspenseBoundary = shim$1; var clearSuspenseBoundaryFromContainer = shim$1; - var errorHydratingContainer = shim$1; // Renderers that don't support hydration // can re-export everything from this module. @@ -2566,14 +2567,6 @@ if (__DEV__) { var objectIs = typeof Object.is === "function" ? Object.is : is; // $FlowFixMe[method-unbinding] - // This is imported by the event replaying implementation in React DOM. It's - // in a separate file to break a circular dependency between the renderer and - // the reconciler. - function isRootDehydrated(root) { - var currentState = root.current.memoizedState; - return currentState.isDehydrated; - } - var contextStackCursor = createCursor(null); var contextFiberStackCursor = createCursor(null); var rootInstanceStackCursor = createCursor(null); // Represents the nearest host transition provider (in React DOM, a ) @@ -22372,27 +22365,7 @@ if (__DEV__) { // back to client side render. // Before rendering again, save the errors from the previous attempt. var errorsFromFirstAttempt = workInProgressRootConcurrentErrors; - var wasRootDehydrated = isRootDehydrated(root); - - if (wasRootDehydrated) { - // The shell failed to hydrate. Set a flag to force a client rendering - // during the next attempt. To do this, we call prepareFreshStack now - // to create the root work-in-progress fiber. This is a bit weird in terms - // of factoring, because it relies on renderRootSync not calling - // prepareFreshStack again in the call below, which happens because the - // root and lanes haven't changed. - // - // TODO: I think what we should do is set ForceClientRender inside - // throwException, like we do for nested Suspense boundaries. The reason - // it's here instead is so we can switch to the synchronous work loop, too. - // Something to consider for a future refactor. - var rootWorkInProgress = prepareFreshStack(root, errorRetryLanes); - rootWorkInProgress.flags |= ForceClientRender; - - { - errorHydratingContainer(); - } - } + var wasRootDehydrated = supportsHydration; var exitStatus = renderRootSync(root, errorRetryLanes); @@ -26109,7 +26082,7 @@ if (__DEV__) { return root; } - var ReactVersion = "19.0.0-www-modern-ac0f08bc"; + var ReactVersion = "19.0.0-www-modern-1ccc623b"; // Might add PROFILE later. diff --git a/compiled/facebook-www/__test_utils__/ReactAllWarnings.js b/compiled/facebook-www/__test_utils__/ReactAllWarnings.js index b3eea6897dd76..3285b6452fab5 100644 --- a/compiled/facebook-www/__test_utils__/ReactAllWarnings.js +++ b/compiled/facebook-www/__test_utils__/ReactAllWarnings.js @@ -84,7 +84,7 @@ export default [ "Accessing element.ref was removed in React 19. ref is now a regular prop. It will be removed from the JSX Element type in a future release.", "An empty string (\"\") was passed to the %s attribute. This may cause the browser to download the whole page again over the network. To fix this, either do not render the element at all or pass null to %s instead of an empty string.", "An empty string (\"\") was passed to the %s attribute. To fix this, either do not render the element at all or pass null to %s instead of an empty string.", - "An error occurred during hydration. The server HTML was replaced with client content in <%s>.", + "An error occurred during hydration. The server HTML was replaced with client content.", "An input can only specify a formAction along with type=\"submit\" or type=\"image\".", "An invalid container has been provided. This may indicate that another renderer is being used in addition to the test renderer. (For example, ReactDOM.createPortal inside of a ReactTestRenderer tree.) This is not supported.", "An optimistic state update occurred outside a transition or action. To fix, move the update to an action, or wrap with startTransition.", @@ -128,7 +128,9 @@ export default [ "Did not expect a listenToNativeEvent() call for \"%s\" in the bubble phase. This is a bug in React. Please file an issue.", "Did not expect a listenToNonDelegatedEvent() call for \"%s\". This is a bug in React. Please file an issue.", "Did not expect server HTML to contain a <%s> in <%s>.", + "Did not expect server HTML to contain a <%s> in the root.", "Did not expect server HTML to contain the text node \"%s\" in <%s>.", + "Did not expect server HTML to contain the text node \"%s\" in the root.", "Directly setting property `innerHTML` is not permitted. For more information, lookup documentation on `dangerouslySetInnerHTML`.", "Dispatching inst must not be null", "Do not call Hooks inside useEffect(...), useMemo(...), or other built-in Hooks. You can only call Hooks at the top level of your React function. For more information, see https://react.dev/link/rules-of-hooks", @@ -156,14 +158,16 @@ export default [ "Expected currently replaying event to not be null. This error is likely caused by a bug in React. Please file an issue.", "Expected host context to exist. This error is likely caused by a bug in React. Please file an issue.", "Expected server HTML to contain a matching <%s> in <%s>.", + "Expected server HTML to contain a matching <%s> in the root.", "Expected server HTML to contain a matching text node for \"%s\" in <%s>.", + "Expected server HTML to contain a matching text node for \"%s\" in the root.", "Expected the last optional `callback` argument to be a function. Instead received: %s.", "Expected to be hydrating. This is a bug in React. Please file an issue.", "Expected to find a StrictMode component in a strict mode tree. This error is likely caused by a bug in React. Please file an issue.", "Expected to find the propagation root when scheduling context work. This error is likely caused by a bug in React. Please file an issue.", "Expected useImperativeHandle() first argument to either be a ref callback or React.createRef() object. Instead received: %s.", "Expected useImperativeHandle() second argument to be a function that creates a handle. Instead received: %s.", - "Extra attributes from the server: %s", + "Extra attribute from the server: %s", "Factory.type is deprecated. Access the class directly before passing it to createFactory.", "Failed to serialize an action for progressive enhancement:\n%s", "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.", @@ -288,6 +292,7 @@ export default [ "The `%s` prop supplied to must be an array if `multiple` is true.%s", "The `aria` attribute is reserved for future use in React. Pass individual `aria-` attributes instead.", + "The `style` prop expects a mapping from style properties to values, not a string. For example, style={{marginRight: spacing + 'em'}} when using JSX.", "The `value` prop is required for the ``. Did you misspell it or forget to pass it?", "The current testing environment is not configured to support act(...)", "The final argument passed to %s changed size between renders. The order and size of this array must remain constant.\n\nPrevious: %s\nIncoming: %s",