diff --git a/compiler/.eslintrc.js b/compiler/.eslintrc.js index 996046a1300..2f68f5c3103 100644 --- a/compiler/.eslintrc.js +++ b/compiler/.eslintrc.js @@ -43,6 +43,12 @@ module.exports = { "multiline-comment-style": ["error", "starred-block"], + /** + * We sometimes need to check for control characters in regexes for things like preserving input + * strings + */ + "no-control-regex": "off", + "@typescript-eslint/no-empty-function": "off", /* @@ -82,7 +88,7 @@ module.exports = { ], "@typescript-eslint/array-type": ["error", { default: "generic" }], "@typescript-eslint/triple-slash-reference": "off", - "@typescript-eslint/no-var-requires": "off" + "@typescript-eslint/no-var-requires": "off", }, parser: "@typescript-eslint/parser", plugins: ["@typescript-eslint"], diff --git a/compiler/packages/babel-plugin-react-compiler/src/ReactiveScopes/CodegenReactiveFunction.ts b/compiler/packages/babel-plugin-react-compiler/src/ReactiveScopes/CodegenReactiveFunction.ts index 3886628c809..d6818187bb2 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/ReactiveScopes/CodegenReactiveFunction.ts +++ b/compiler/packages/babel-plugin-react-compiler/src/ReactiveScopes/CodegenReactiveFunction.ts @@ -2157,10 +2157,18 @@ function codegenInstructionValue( } /** - * Due to a bug in earlier Babel versions, JSX string attributes with double quotes or with unicode characters - * may be escaped unnecessarily. To avoid trigger this Babel bug, we use a JsxExpressionContainer for such strings. + * Due to a bug in earlier Babel versions, JSX string attributes with double quotes, unicode characters, or special + * control characters such as \n may be escaped unnecessarily. To avoid trigger this Babel bug, we use a + * JsxExpressionContainer for such strings. + * + * u0000 to u001F: C0 control codes + * u007F : Delete character + * u0080 to u009F: C1 control codes + * u00A0 to uFFFF: All non-basic Latin characters + * https://en.wikipedia.org/wiki/List_of_Unicode_characters#Control_codes */ -const STRING_REQUIRES_EXPR_CONTAINER_PATTERN = /[\u{0080}-\u{FFFF}]|"/u; +const STRING_REQUIRES_EXPR_CONTAINER_PATTERN = + /[\u{0000}-\u{001F}|\u{007F}|\u{0080}-\u{FFFF}]|"/u; function codegenJsxAttribute( cx: Context, attribute: JsxAttribute diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/jsx-string-attribute-expression-container.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/jsx-string-attribute-expression-container.expect.md new file mode 100644 index 00000000000..ad25964ed83 --- /dev/null +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/jsx-string-attribute-expression-container.expect.md @@ -0,0 +1,77 @@ + +## Input + +```javascript +function Component() { + return ( +
+ + + + + + +
+ ); +} + +function Text({ value }) { + return {value}; +} + +export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{}], +}; + +``` + +## Code + +```javascript +import { c as _c } from "react/compiler-runtime"; +function Component() { + const $ = _c(1); + let t0; + if ($[0] === Symbol.for("react.memo_cache_sentinel")) { + t0 = ( +
+ + + + + + +
+ ); + $[0] = t0; + } else { + t0 = $[0]; + } + return t0; +} + +function Text(t0) { + const $ = _c(2); + const { value } = t0; + let t1; + if ($[0] !== value) { + t1 = {value}; + $[0] = value; + $[1] = t1; + } else { + t1 = $[1]; + } + return t1; +} + +export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{}], +}; + +``` + +### Eval output +(kind: ok)
+A E나은Laurenசத்யாSathya
\ No newline at end of file diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/jsx-string-attribute-expression-container.js b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/jsx-string-attribute-expression-container.js new file mode 100644 index 00000000000..042b95f3481 --- /dev/null +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/jsx-string-attribute-expression-container.js @@ -0,0 +1,21 @@ +function Component() { + return ( +
+ + + + + + +
+ ); +} + +function Text({ value }) { + return {value}; +} + +export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{}], +};