Properly escape JSXText (#329)

It's annoying that there's a bug inside of the flow parser, I raised it internally. While this is getting fixed, we can workaround it. This now makes babylon properly escape JSXText.
master
Christopher Chedeau 2017-01-19 08:30:35 -08:00 committed by James Long
parent bb9d288dbb
commit ed0023012d
5 changed files with 44 additions and 8 deletions

View File

@ -2056,11 +2056,20 @@ function printJSXChildren(path, options, print) {
const isLiteral = namedTypes.Literal.check(child);
if (isLiteral && typeof child.value === "string") {
if (/\S/.test(child.value)) {
const beginBreak = child.value.match(/^\s*\n/);
const endBreak = child.value.match(/\n\s*$/);
const beginSpace = child.value.match(/^\s+/);
const endSpace = child.value.match(/\s+$/);
// There's a bug in the flow parser where it doesn't unescape the
// value field. To workaround this, we can use rawValue which is
// correctly escaped (since it parsed).
// We really want to use value and re-escape it ourself when possible
// though.
const value = options.useFlowParser ?
child.raw :
util.htmlEscapeInsideAngleBracket(child.value);
if (/\S/.test(value)) {
const beginBreak = value.match(/^\s*\n/);
const endBreak = value.match(/\n\s*$/);
const beginSpace = value.match(/^\s+/);
const endSpace = value.match(/\s+$/);
if (beginBreak) {
children.push(hardline);
@ -2068,7 +2077,7 @@ function printJSXChildren(path, options, print) {
children.push(jsxWhitespace);
}
children.push(child.value.replace(/^\s+|\s+$/g, ""));
children.push(value.replace(/^\s+|\s+$/g, ""));
if (endBreak) {
children.push(hardline);
@ -2076,10 +2085,10 @@ function printJSXChildren(path, options, print) {
if (endSpace) children.push(jsxWhitespace);
children.push(softline);
}
} else if (/\n/.test(child.value)) {
} else if (/\n/.test(value)) {
// TODO: add another hardline if >1 newline appeared. (also above)
children.push(hardline);
} else if (/\s/.test(child.value)) {
} else if (/\s/.test(value)) {
// whitespace-only without newlines,
// eg; a single space separating two elements
children.push(jsxWhitespace);

View File

@ -222,6 +222,17 @@ function htmlEscapeInsideDoubleQuote(str) {
}
util.htmlEscapeInsideDoubleQuote = htmlEscapeInsideDoubleQuote;
// http://stackoverflow.com/a/7124052
function htmlEscapeInsideAngleBracket(str) {
return str.replace(/</g, "&lt;").replace(/>/g, "&gt;");
// Intentionally disable the following since it is safe inside of a
// angle bracket context
// .replace(/&/g, '&amp;')
// .replace(/"/g, '&quot;')
// .replace(/'/g, '&#39;')
}
util.htmlEscapeInsideAngleBracket = htmlEscapeInsideAngleBracket;
var PRECEDENCE = {};
[
[ "||" ],

View File

@ -0,0 +1,13 @@
exports[`test escape.js 1`] = `
"<div>&lt;</div>
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<div>&lt;</div>;
"
`;
exports[`test escape.js 2`] = `
"<div>&lt;</div>
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<div>&lt;</div>;
"
`;

View File

@ -0,0 +1 @@
<div>&lt;</div>

View File

@ -0,0 +1,2 @@
run_spec(__dirname);
run_spec(__dirname, {useFlowParser: false});