diff --git a/src/printer.js b/src/printer.js index 8854fb801..c30bbd3c3 100644 --- a/src/printer.js +++ b/src/printer.js @@ -3705,7 +3705,7 @@ function printJSXChildren(path, options, print, jsxWhitespace) { children.push(""); words.shift(); if (/\n/.test(words[0])) { - children.push(softline); + children.push(hardline); } else { children.push(jsxWhitespace); } @@ -3734,7 +3734,7 @@ function printJSXChildren(path, options, print, jsxWhitespace) { if (endWhitespace !== undefined) { if (/\n/.test(endWhitespace)) { - children.push(softline); + children.push(hardline); } else { children.push(jsxWhitespace); } @@ -3773,25 +3773,17 @@ function printJSXChildren(path, options, print, jsxWhitespace) { const printedChild = print(childPath); children.push(printedChild); - const isBrTag = - child.type === "JSXElement" && child.openingElement.name.name === "br"; - if (isBrTag) { - // Forcing a hardline after a `
` tag gives much better text - // layout. - children.push(hardline); - return; - } - const next = n.children[i + 1]; - const followedByMeaningfulText = next && isMeaningfulJSXText(next); + const directlyFollowedByMeaningfulText = + next && isMeaningfulJSXText(next) && !/^[ \n\r\t]/.test(rawText(next)); const followedByJSXWhitespace = next && isJSXWhitespaceExpression(next); - if (followedByMeaningfulText || followedByJSXWhitespace) { + if (directlyFollowedByMeaningfulText || followedByJSXWhitespace) { // Potentially this could be a softline as well. // See the comment above about the Facebook translation pipeline as // to why this is an empty string. children.push(""); } else { - children.push(softline); + children.push(hardline); } } }, "children"); @@ -3873,64 +3865,47 @@ function printJSXElement(path, options, print) { // to get the correct output. for (let i = children.length - 2; i >= 0; i--) { const isPairOfEmptyStrings = children[i] === "" && children[i + 1] === ""; - const isSoftlineFollowedByJSXWhitespace = - children[i] === softline && + const isPairOfHardlines = + children[i] === hardline && + children[i + 1] === "" && + children[i + 2] === hardline; + const isLineFollowedByJSXWhitespace = + (children[i] === softline || children[i] === hardline) && children[i + 1] === "" && children[i + 2] === jsxWhitespace; - const isJSXWhitespaceFollowedBySoftline = + const isJSXWhitespaceFollowedByLine = children[i] === jsxWhitespace && children[i + 1] === "" && - children[i + 2] === softline; - const isEmptyFollowedByHardline = - children[i] === "" && children[i + 1] === hardline; + (children[i + 2] === softline || children[i + 2] === hardline); + if ( + (isPairOfHardlines && containsText) || isPairOfEmptyStrings || - isSoftlineFollowedByJSXWhitespace || - (isEmptyFollowedByHardline && containsText) + isLineFollowedByJSXWhitespace ) { children.splice(i, 2); - } else if (isJSXWhitespaceFollowedBySoftline) { + } else if (isJSXWhitespaceFollowedByLine) { children.splice(i + 1, 2); } } - // Trim trailing lines (or empty strings), recording if there was a hardline - let numTrailingHard = 0; + // Trim trailing lines (or empty strings) while ( children.length && (isLineNext(util.getLast(children)) || isEmpty(util.getLast(children))) ) { - if (willBreak(util.getLast(children))) { - ++numTrailingHard; - forcedBreak = true; - } children.pop(); } - // allow one extra newline - if (numTrailingHard > 1) { - children.push(""); - children.push(hardline); - } - // Trim leading lines (or empty strings), recording if there was a hardline - let numLeadingHard = 0; + // Trim leading lines (or empty strings) while ( children.length && (isLineNext(children[0]) || isEmpty(children[0])) && (isLineNext(children[1]) || isEmpty(children[1])) ) { - if (willBreak(children[0]) || willBreak(children[1])) { - ++numLeadingHard; - forcedBreak = true; - } children.shift(); children.shift(); } - // allow one extra newline - if (numLeadingHard > 1) { - children.unshift(hardline); - children.unshift(""); - } // Tweak how we format children if outputting this element over multiple lines. // Also detect whether we will force this element to output over multiple lines. diff --git a/tests/flow/more_react/__snapshots__/jsfmt.spec.js.snap b/tests/flow/more_react/__snapshots__/jsfmt.spec.js.snap index 59e7f0b30..cc7b54dae 100644 --- a/tests/flow/more_react/__snapshots__/jsfmt.spec.js.snap +++ b/tests/flow/more_react/__snapshots__/jsfmt.spec.js.snap @@ -99,7 +99,8 @@ var App = React.createClass({ return (
- {foo(x, y)}{foo(z, x)} // error, since z: number + {foo(x, y)} + {foo(z, x)} // error, since z: number
); } diff --git a/tests/jsx-newlines/__snapshots__/jsfmt.spec.js.snap b/tests/jsx-newlines/__snapshots__/jsfmt.spec.js.snap index e829913f9..9828d2bfe 100644 --- a/tests/jsx-newlines/__snapshots__/jsfmt.spec.js.snap +++ b/tests/jsx-newlines/__snapshots__/jsfmt.spec.js.snap @@ -117,7 +117,10 @@ newlines_elems_spaced = ( newlines_mixed = (
- hitherehow are youare you fine today? + hi + there + how are you + are you fine today?
); @@ -126,7 +129,10 @@ newlines_elems = (
- hi
+ hi +
+ +
); diff --git a/tests/jsx-significant-space/__snapshots__/jsfmt.spec.js.snap b/tests/jsx-significant-space/__snapshots__/jsfmt.spec.js.snap index fb1a11782..3e5052638 100644 --- a/tests/jsx-significant-space/__snapshots__/jsfmt.spec.js.snap +++ b/tests/jsx-significant-space/__snapshots__/jsfmt.spec.js.snap @@ -189,8 +189,7 @@ not_broken_end = ( not_broken_begin = (
-
- {" "}long text long text long text long text long text long text long text +
long text long text long text long text long text long text long text long texturl long text long text
); diff --git a/tests/jsx-stateless-arrow-fn/__snapshots__/jsfmt.spec.js.snap b/tests/jsx-stateless-arrow-fn/__snapshots__/jsfmt.spec.js.snap index 14f6aebd5..64ad21a02 100644 --- a/tests/jsx-stateless-arrow-fn/__snapshots__/jsfmt.spec.js.snap +++ b/tests/jsx-stateless-arrow-fn/__snapshots__/jsfmt.spec.js.snap @@ -135,8 +135,9 @@ const render6 = ({ styles }) => const render7 = () =>
- Dont break each elem onto its own line.
{" "} -
+ + Dont break each elem onto its own line. +
; const render7A = () => diff --git a/tests/jsx-text-wrap/__snapshots__/jsfmt.spec.js.snap b/tests/jsx-text-wrap/__snapshots__/jsfmt.spec.js.snap index 1832f9ca3..1360e9d31 100644 --- a/tests/jsx-text-wrap/__snapshots__/jsfmt.spec.js.snap +++ b/tests/jsx-text-wrap/__snapshots__/jsfmt.spec.js.snap @@ -253,7 +253,8 @@ expression_does_not_break = // FIXME br_triggers_expression_break = -

text text text text text text text text text text text {this.props.type}
+

+ text text text text text text text text text text text {this.props.type}
jsx_whitespace_after_tag =
@@ -271,6 +272,33 @@ x =
{" "} HRS
+ +x = +
+

Message

+ Hello, I'm a simple message. +
+ +x = +
+ Hello, I'm a simple message. +

Message

+
+ +x = +
+
+
+
+
+ Line {startRange.row + 1}:{startRange.column + 1} - {endRange.row + 1}:{endRange.column + 1}{caller} +
+
+
+
+
+ + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Wrapping text x = ( @@ -303,7 +331,9 @@ x = ( // Wrapping tags x = ( @@ -329,7 +359,8 @@ x = ( x = (
before{stuff}after{stuff}after{stuff}after{stuff}after{stuff}after{stuff} - {stuff}{stuff}after{stuff}after + {stuff} + {stuff}after{stuff}after
); @@ -387,7 +418,9 @@ x = ( x = (
-
First
Second
Third
+
First
+ Second +
Third
); @@ -532,7 +565,8 @@ no_text_one_tag_per_line = ( with_text_fill_line = (
- Text + Text +
); @@ -546,22 +580,21 @@ line_after_br = ( line_after_br_2 = (
- A
- B
- C + A
B
C
); br_followed_by_whitespace = (
-
- {" "}text +
text
); dont_preserve_blank_lines_when_jsx_contains_text = (
-
Zeroth
First
Second +
Zeroth
+
First
+ Second
); @@ -615,4 +648,34 @@ x = (
); +x = ( +
+

Message

+ Hello, I'm a simple message. +
+); + +x = ( +
+ Hello, I'm a simple message. +

Message

+
+); + +x = ( +
+
+
+
+
+ Line {startRange.row + 1}:{startRange.column + 1} -{" "} + {endRange.row + 1}:{endRange.column + 1} + {caller} +
+
+
+
+
+); + `; diff --git a/tests/jsx-text-wrap/test.js b/tests/jsx-text-wrap/test.js index eb449a093..5c5dc434a 100644 --- a/tests/jsx-text-wrap/test.js +++ b/tests/jsx-text-wrap/test.js @@ -250,7 +250,8 @@ expression_does_not_break = // FIXME br_triggers_expression_break = -

text text text text text text text text text text text {this.props.type}
+

+ text text text text text text text text text text text {this.props.type}
jsx_whitespace_after_tag =
@@ -268,3 +269,30 @@ x =
{" "} HRS
+ +x = +
+

Message

+ Hello, I'm a simple message. +
+ +x = +
+ Hello, I'm a simple message. +

Message

+
+ +x = +
+
+
+
+
+ Line {startRange.row + 1}:{startRange.column + 1} - {endRange.row + 1}:{endRange.column + 1}{caller} +
+
+
+
+
+ +