[JSX] jsx-whitespace breaks with parent (fixes #622) (#626)

master
Alex Rattray 2017-02-07 10:47:34 -08:00 committed by James Long
parent 79d537a3b0
commit 91d4f400a4
4 changed files with 104 additions and 41 deletions

View File

@ -2270,12 +2270,9 @@ function isEmptyJSXElement(node) {
//
// For another, leading, trailing, and lone whitespace all need to
// turn themselves into the rather ugly `{' '}` when breaking.
function printJSXChildren(path, options, print) {
function printJSXChildren(path, options, print, jsxWhitespace) {
const n = path.getValue();
const children = [];
const jsxWhitespace = options.singleQuote
? ifBreak("{' '}", " ")
: ifBreak('{" "}', " ");
// using `map` instead of `each` because it provides `i`
path.map(
@ -2385,7 +2382,10 @@ function printJSXElement(path, options, print) {
return openingLines;
}
const children = printJSXChildren(path, options, print);
const jsxWhitespace = options.singleQuote
? ifBreak("{' '}", " ")
: ifBreak('{" "}', " ");
const children = printJSXChildren(path, options, print, jsxWhitespace);
let forcedBreak = false;
// Trim trailing lines, recording if there was a hardline
@ -2417,46 +2417,47 @@ function printJSXElement(path, options, print) {
}
// Group by line, recording if there was a hardline.
let childrenGroupedByLine;
if (children.length === 1) {
if (!forcedBreak && willBreak(children[0])) {
forcedBreak = true;
let groups = [[]]; // Initialize the first line's group
children.forEach((child, i) => {
// leading and trailing JSX whitespace don't go into a group
if (child === jsxWhitespace) {
if (i === 0) {
groups.unshift(child);
return;
} else if (i === children.length - 1) {
groups.push(child);
return;
}
}
// Don't wrap a single child in a group as there is no need, and a
// lone JSX whitespace doesn't work otherwise because the group
// will be printed in flat mode, and we need to print `{' '}` in
// break mode.
childrenGroupedByLine = [concat([hardline, children[0]])];
} else {
// Prefill leading newline, and initialize the first line's group
let groups = [[]];
children.forEach((child, i) => {
let prev = children[i - 1];
if (prev && willBreak(prev)) {
forcedBreak = true;
let prev = children[i - 1];
if (prev && willBreak(prev)) {
forcedBreak = true;
// On a new line, so create a new group and put this element
// in it.
groups.push([child]);
} else {
// Not on a newline, so add this element to the current group.
util.getLast(groups).push(child);
}
// On a new line, so create a new group and put this element in it.
groups.push([child]);
} else {
// Not on a newline, so add this element to the current group.
util.getLast(groups).push(child);
}
// Ensure we record hardline of last element.
if (!forcedBreak && i === children.length - 1) {
if (willBreak(child)) forcedBreak = true;
}
});
// Ensure we record hardline of last element.
if (!forcedBreak && i === children.length - 1) {
if (willBreak(child)) forcedBreak = true;
}
});
childrenGroupedByLine = [
hardline,
// Conditional groups suppress break propagation; we want output
// hard lines without breaking up the entire jsx element.
concat(groups.map(contents => conditionalGroup([concat(contents)])))
];
}
const childrenGroupedByLine = [
hardline,
// Conditional groups suppress break propagation; we want to output
// hard lines without breaking up the entire jsx element.
// Note that leading and trailing JSX Whitespace don't go into a group.
concat(groups.map(contents =>
Array.isArray(contents)
? conditionalGroup([concat(contents)])
: contents
))
];
const closingLines = path.call(print, "closingElement");

View File

@ -126,7 +126,7 @@ var App = require(\"App.react\");
var app = (
<App y={42}>
// error, y: number but foo expects string in App.react
{\" \"}// error, y: number but foo expects string in App.react
Some text.
</App>
);

View File

@ -48,6 +48,21 @@ nest_plz =
<div></div>
</div>
</div>
regression_not_transformed_1 =
<span> <Icon icon=\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\" /></span>;
regression_not_transformed_2 =
<span><Icon icon=\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\" /> </span>;
similar_1 =
<span> <Icon icon=\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\" /></span>;
similar_2 =
<span><Icon icon=\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\" /> </span>;
similar_3 =
<span><Icon icon=\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\" /> <Icon icon=\"\" /></span>;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
after = (
<span>
@ -113,5 +128,37 @@ nest_plz = (
</div>
</div>
);
regression_not_transformed_1 = (
<span>
{\" \"}<Icon icon=\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\" />
</span>
);
regression_not_transformed_2 = (
<span>
<Icon icon=\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\" />{\" \"}
</span>
);
similar_1 = (
<span>
{\" \"}
<Icon icon=\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\" />
</span>
);
similar_2 = (
<span>
<Icon icon=\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\" />
{\" \"}
</span>
);
similar_3 = (
<span>
<Icon icon=\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\" /> <Icon icon=\"\" />
</span>
);
"
`;

View File

@ -47,3 +47,18 @@ nest_plz =
<div></div>
</div>
</div>
regression_not_transformed_1 =
<span> <Icon icon="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" /></span>;
regression_not_transformed_2 =
<span><Icon icon="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" /> </span>;
similar_1 =
<span> <Icon icon="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" /></span>;
similar_2 =
<span><Icon icon="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" /> </span>;
similar_3 =
<span><Icon icon="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" /> <Icon icon="" /></span>;