mirror of
https://github.com/zebrajr/react.git
synced 2025-12-06 12:20:20 +01:00
Prevent errors from comment node roots with enableViewTransition (#33205)
We have many cases internally where the `containerInstance` resolves to a comment node. `restoreRootViewTransitionName` is called when `enableViewTransition` is on, even without introducing a `<ViewTransition />`. So that means it can crash pages because `containerInstance.style` is `undefined` just by turning on the flag. This skips cancel/restore of root view transition name if a comment node is the root.
This commit is contained in:
parent
2388481283
commit
3710c4d4f9
|
|
@ -1549,6 +1549,19 @@ export function cancelRootViewTransitionName(rootContainer: Container): void {
|
||||||
rootContainer.nodeType === DOCUMENT_NODE
|
rootContainer.nodeType === DOCUMENT_NODE
|
||||||
? (rootContainer: any).documentElement
|
? (rootContainer: any).documentElement
|
||||||
: rootContainer.ownerDocument.documentElement;
|
: rootContainer.ownerDocument.documentElement;
|
||||||
|
|
||||||
|
if (
|
||||||
|
!disableCommentsAsDOMContainers &&
|
||||||
|
rootContainer.nodeType === COMMENT_NODE
|
||||||
|
) {
|
||||||
|
if (__DEV__) {
|
||||||
|
console.warn(
|
||||||
|
'Cannot cancel root view transition on a comment node. All view transitions will be globally scoped.',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (
|
if (
|
||||||
documentElement !== null &&
|
documentElement !== null &&
|
||||||
// $FlowFixMe[prop-missing]
|
// $FlowFixMe[prop-missing]
|
||||||
|
|
@ -1593,8 +1606,16 @@ export function restoreRootViewTransitionName(rootContainer: Container): void {
|
||||||
// clone the whole document outside of the React too.
|
// clone the whole document outside of the React too.
|
||||||
containerInstance = (rootContainer: any);
|
containerInstance = (rootContainer: any);
|
||||||
}
|
}
|
||||||
// $FlowFixMe[prop-missing]
|
if (
|
||||||
if (containerInstance.style.viewTransitionName === 'root') {
|
!disableCommentsAsDOMContainers &&
|
||||||
|
containerInstance.nodeType === COMMENT_NODE
|
||||||
|
) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (
|
||||||
|
// $FlowFixMe[prop-missing]
|
||||||
|
containerInstance.style.viewTransitionName === 'root'
|
||||||
|
) {
|
||||||
// If we moved the root view transition name to the container in a gesture
|
// If we moved the root view transition name to the container in a gesture
|
||||||
// we need to restore it now.
|
// we need to restore it now.
|
||||||
containerInstance.style.viewTransitionName = '';
|
containerInstance.style.viewTransitionName = '';
|
||||||
|
|
@ -1708,6 +1729,13 @@ export function cloneRootViewTransitionContainer(
|
||||||
containerInstance = (rootContainer: any).body;
|
containerInstance = (rootContainer: any).body;
|
||||||
} else if (rootContainer.nodeName === 'HTML') {
|
} else if (rootContainer.nodeName === 'HTML') {
|
||||||
containerInstance = (rootContainer.ownerDocument.body: any);
|
containerInstance = (rootContainer.ownerDocument.body: any);
|
||||||
|
} else if (
|
||||||
|
!disableCommentsAsDOMContainers &&
|
||||||
|
rootContainer.nodeType === COMMENT_NODE
|
||||||
|
) {
|
||||||
|
throw new Error(
|
||||||
|
'Cannot use a startGestureTransition() with a comment node root.',
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
// If the container is not the whole document, then we ideally should probably
|
// If the container is not the whole document, then we ideally should probably
|
||||||
// clone the whole document outside of the React too.
|
// clone the whole document outside of the React too.
|
||||||
|
|
|
||||||
|
|
@ -306,6 +306,7 @@ export let shouldFireAfterActiveInstanceBlur: boolean = false;
|
||||||
let viewTransitionContextChanged: boolean = false;
|
let viewTransitionContextChanged: boolean = false;
|
||||||
let inUpdateViewTransition: boolean = false;
|
let inUpdateViewTransition: boolean = false;
|
||||||
let rootViewTransitionAffected: boolean = false;
|
let rootViewTransitionAffected: boolean = false;
|
||||||
|
let rootViewTransitionNameCanceled: boolean = false;
|
||||||
|
|
||||||
function isHydratingParent(current: Fiber, finishedWork: Fiber): boolean {
|
function isHydratingParent(current: Fiber, finishedWork: Fiber): boolean {
|
||||||
if (finishedWork.tag === ActivityComponent) {
|
if (finishedWork.tag === ActivityComponent) {
|
||||||
|
|
@ -2737,6 +2738,7 @@ function commitAfterMutationEffectsOnFiber(
|
||||||
switch (finishedWork.tag) {
|
switch (finishedWork.tag) {
|
||||||
case HostRoot: {
|
case HostRoot: {
|
||||||
viewTransitionContextChanged = false;
|
viewTransitionContextChanged = false;
|
||||||
|
rootViewTransitionNameCanceled = false;
|
||||||
pushViewTransitionCancelableScope();
|
pushViewTransitionCancelableScope();
|
||||||
recursivelyTraverseAfterMutationEffects(root, finishedWork, lanes);
|
recursivelyTraverseAfterMutationEffects(root, finishedWork, lanes);
|
||||||
if (!viewTransitionContextChanged && !rootViewTransitionAffected) {
|
if (!viewTransitionContextChanged && !rootViewTransitionAffected) {
|
||||||
|
|
@ -2755,6 +2757,7 @@ function commitAfterMutationEffectsOnFiber(
|
||||||
}
|
}
|
||||||
// We also cancel the root itself.
|
// We also cancel the root itself.
|
||||||
cancelRootViewTransitionName(root.containerInfo);
|
cancelRootViewTransitionName(root.containerInfo);
|
||||||
|
rootViewTransitionNameCanceled = true;
|
||||||
}
|
}
|
||||||
popViewTransitionCancelableScope(null);
|
popViewTransitionCancelableScope(null);
|
||||||
break;
|
break;
|
||||||
|
|
@ -3613,7 +3616,7 @@ function commitPassiveMountOnFiber(
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isViewTransitionEligible) {
|
if (isViewTransitionEligible) {
|
||||||
if (supportsMutation) {
|
if (supportsMutation && rootViewTransitionNameCanceled) {
|
||||||
restoreRootViewTransitionName(finishedRoot.containerInfo);
|
restoreRootViewTransitionName(finishedRoot.containerInfo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -544,5 +544,6 @@
|
||||||
"556": "Expected prepareToHydrateHostActivityInstance() to never be called. This error is likely caused by a bug in React. Please file an issue.",
|
"556": "Expected prepareToHydrateHostActivityInstance() to never be called. This error is likely caused by a bug in React. Please file an issue.",
|
||||||
"557": "Expected to have a hydrated activity instance. This error is likely caused by a bug in React. Please file an issue.",
|
"557": "Expected to have a hydrated activity instance. This error is likely caused by a bug in React. Please file an issue.",
|
||||||
"558": "Client rendering an Activity suspended it again. This is a bug in React.",
|
"558": "Client rendering an Activity suspended it again. This is a bug in React.",
|
||||||
"559": "Expected to find a host node. This is a bug in React."
|
"559": "Expected to find a host node. This is a bug in React.",
|
||||||
|
"560": "Cannot use a startGestureTransition() with a comment node root."
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user