mirror of
https://github.com/facebook/react.git
synced 2026-02-21 19:31:52 +00:00
[compiler:codegen] Wrap non-ascii characters in JsxExpressionContainer
This PR extends the previous logic added in #29141 to also account for
other kinds of non-ascii characters such as `\n`. Because these control
characters are individual special characters (and not 2 characters `\`
and `n`) we match based on unicode which was already being checked for
non-Latin characters.
This allows control characters to continue to be compiled equivalently
to its original source if it was provided in a JsxExpressionContainer.
However note that this PR does not convert JSX attributes that are
StringLiterals to JsxExpressionContainer, to preserve the original
source code as it was written.
Alternatively we could always emit a JsxExpressionContainer if it was
used in the source and not try to down level it to some other node
kind. But since we already do this I opted to keep this behavior.
Partially addresses #29648.
ghstack-source-id: ecc61c9f0b
Pull Request resolved: https://github.com/facebook/react/pull/29997
This commit is contained in:
@@ -43,6 +43,12 @@ module.exports = {
|
|||||||
|
|
||||||
"multiline-comment-style": ["error", "starred-block"],
|
"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",
|
"@typescript-eslint/no-empty-function": "off",
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -82,7 +88,7 @@ module.exports = {
|
|||||||
],
|
],
|
||||||
"@typescript-eslint/array-type": ["error", { default: "generic" }],
|
"@typescript-eslint/array-type": ["error", { default: "generic" }],
|
||||||
"@typescript-eslint/triple-slash-reference": "off",
|
"@typescript-eslint/triple-slash-reference": "off",
|
||||||
"@typescript-eslint/no-var-requires": "off"
|
"@typescript-eslint/no-var-requires": "off",
|
||||||
},
|
},
|
||||||
parser: "@typescript-eslint/parser",
|
parser: "@typescript-eslint/parser",
|
||||||
plugins: ["@typescript-eslint"],
|
plugins: ["@typescript-eslint"],
|
||||||
|
|||||||
@@ -2157,10 +2157,18 @@ function codegenInstructionValue(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Due to a bug in earlier Babel versions, JSX string attributes with double quotes or with unicode characters
|
* Due to a bug in earlier Babel versions, JSX string attributes with double quotes, unicode characters, or special
|
||||||
* may be escaped unnecessarily. To avoid trigger this Babel bug, we use a JsxExpressionContainer for such strings.
|
* 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(
|
function codegenJsxAttribute(
|
||||||
cx: Context,
|
cx: Context,
|
||||||
attribute: JsxAttribute
|
attribute: JsxAttribute
|
||||||
|
|||||||
@@ -0,0 +1,77 @@
|
|||||||
|
|
||||||
|
## Input
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
function Component() {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<Text value={"\n"} />
|
||||||
|
<Text value={"A\tE"} />
|
||||||
|
<Text value={"나은"} />
|
||||||
|
<Text value={"Lauren"} />
|
||||||
|
<Text value={"சத்யா"} />
|
||||||
|
<Text value={"Sathya"} />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function Text({ value }) {
|
||||||
|
return <span>{value}</span>;
|
||||||
|
}
|
||||||
|
|
||||||
|
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 = (
|
||||||
|
<div>
|
||||||
|
<Text value={"\n"} />
|
||||||
|
<Text value={"A\tE"} />
|
||||||
|
<Text value={"\uB098\uC740"} />
|
||||||
|
<Text value="Lauren" />
|
||||||
|
<Text value={"\u0B9A\u0BA4\u0BCD\u0BAF\u0BBE"} />
|
||||||
|
<Text value="Sathya" />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
$[0] = t0;
|
||||||
|
} else {
|
||||||
|
t0 = $[0];
|
||||||
|
}
|
||||||
|
return t0;
|
||||||
|
}
|
||||||
|
|
||||||
|
function Text(t0) {
|
||||||
|
const $ = _c(2);
|
||||||
|
const { value } = t0;
|
||||||
|
let t1;
|
||||||
|
if ($[0] !== value) {
|
||||||
|
t1 = <span>{value}</span>;
|
||||||
|
$[0] = value;
|
||||||
|
$[1] = t1;
|
||||||
|
} else {
|
||||||
|
t1 = $[1];
|
||||||
|
}
|
||||||
|
return t1;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const FIXTURE_ENTRYPOINT = {
|
||||||
|
fn: Component,
|
||||||
|
params: [{}],
|
||||||
|
};
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
### Eval output
|
||||||
|
(kind: ok) <div><span>
|
||||||
|
</span><span>A E</span><span>나은</span><span>Lauren</span><span>சத்யா</span><span>Sathya</span></div>
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
function Component() {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<Text value={"\n"} />
|
||||||
|
<Text value={"A\tE"} />
|
||||||
|
<Text value={"나은"} />
|
||||||
|
<Text value={"Lauren"} />
|
||||||
|
<Text value={"சத்யா"} />
|
||||||
|
<Text value={"Sathya"} />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function Text({ value }) {
|
||||||
|
return <span>{value}</span>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const FIXTURE_ENTRYPOINT = {
|
||||||
|
fn: Component,
|
||||||
|
params: [{}],
|
||||||
|
};
|
||||||
Reference in New Issue
Block a user