From 1a31a814f16838e2c9edfce0d244264c43184f86 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Markb=C3=A5ge?= Date: Thu, 6 Nov 2025 16:02:06 -0500 Subject: [PATCH] Escape View Transition Name Strings as base64 (#35060) This is an alternative to #35059. If the name needs escaping, then instead of escaping it, we just use a base64 name. This wouldn't allow you to match on an escaped name in your own CSS like you should be able to if browsers worked properly. But at least it would provide matching name in current browsers which is probably sufficient if you're using auto-generated names. This also covers some cases where `CSS.escape()` isn't sufficient anyway like when the name ends in a dot. --- .../react-dom-bindings/src/client/ReactFiberConfigDOM.js | 7 ++++++- .../ReactDOMFizzInstructionSetInlineCodeStrings.js | 2 +- .../ReactDOMFizzInstructionSetShared.js | 7 ++++++- scripts/flow/environment.js | 4 ++++ 4 files changed, 17 insertions(+), 3 deletions(-) diff --git a/packages/react-dom-bindings/src/client/ReactFiberConfigDOM.js b/packages/react-dom-bindings/src/client/ReactFiberConfigDOM.js index bbecbb6635..e4c45ccc4c 100644 --- a/packages/react-dom-bindings/src/client/ReactFiberConfigDOM.js +++ b/packages/react-dom-bindings/src/client/ReactFiberConfigDOM.js @@ -1435,8 +1435,13 @@ export function applyViewTransitionName( className: ?string, ): void { instance = ((instance: any): HTMLElement); + // If the name isn't valid CSS identifier, base64 encode the name instead. + // This doesn't let you select it in custom CSS selectors but it does work in current + // browsers. + const escapedName = + CSS.escape(name) !== name ? 'r-' + btoa(name).replace(/=/g, '') : name; // $FlowFixMe[prop-missing] - instance.style.viewTransitionName = name; + instance.style.viewTransitionName = escapedName; if (className != null) { // $FlowFixMe[prop-missing] instance.style.viewTransitionClass = className; diff --git a/packages/react-dom-bindings/src/server/fizz-instruction-set/ReactDOMFizzInstructionSetInlineCodeStrings.js b/packages/react-dom-bindings/src/server/fizz-instruction-set/ReactDOMFizzInstructionSetInlineCodeStrings.js index 4e7fb4b73f..cac2283236 100644 --- a/packages/react-dom-bindings/src/server/fizz-instruction-set/ReactDOMFizzInstructionSetInlineCodeStrings.js +++ b/packages/react-dom-bindings/src/server/fizz-instruction-set/ReactDOMFizzInstructionSetInlineCodeStrings.js @@ -8,7 +8,7 @@ export const clientRenderBoundary = export const completeBoundary = '$RB=[];$RV=function(a){$RT=performance.now();for(var b=0;ba&&2E3q&&2E3q&&2E3; } } + +declare class CSS { + static escape(str: string): string; +}