@@ -501,9 +501,6 @@ namespace ts.formatting {
501
501
else if ( SmartIndenter . argumentStartsOnSameLineAsPreviousArgument ( parent , node , startLine , sourceFile ) ) {
502
502
return { indentation : parentDynamicIndentation . getIndentation ( ) , delta } ;
503
503
}
504
- else if ( SmartIndenter . isJSXClosingWithMultiLineText ( parent , node , startLine , sourceFile ) ) {
505
- return { indentation : parentDynamicIndentation . getIndentation ( ) , delta } ;
506
- }
507
504
else {
508
505
return { indentation : parentDynamicIndentation . getIndentation ( ) + parentDynamicIndentation . getDelta ( node ) , delta } ;
509
506
}
@@ -652,6 +649,11 @@ namespace ts.formatting {
652
649
if ( tokenInfo . token . end > node . end ) {
653
650
break ;
654
651
}
652
+ if ( node . kind === SyntaxKind . JsxText ) {
653
+ // Intentation rules for jsx text are handled by `indentMultilineCommentOrJsxText` inside `processChildNode`; just fastforward past it here
654
+ formattingScanner . advance ( ) ;
655
+ continue ;
656
+ }
655
657
consumeTokenAndAdvanceScanner ( tokenInfo , node , nodeDynamicIndentation , node ) ;
656
658
}
657
659
@@ -741,7 +743,20 @@ namespace ts.formatting {
741
743
processNode ( child , childContextNode , childStartLine , undecoratedChildStartLine , childIndentation . indentation , childIndentation . delta ) ;
742
744
if ( child . kind === SyntaxKind . JsxText ) {
743
745
const range : TextRange = { pos : child . getStart ( ) , end : child . getEnd ( ) } ;
744
- indentMultilineCommentOrJsxText ( range , childIndentation . indentation , /*firstLineIsIndented*/ true , /*indentFinalLine*/ false ) ;
746
+ if ( range . pos !== range . end ) { // don't indent zero-width jsx text
747
+ const siblings = parent . getChildren ( sourceFile ) ;
748
+ const currentNode = find ( siblings , arg => arg . pos === child . pos ) ;
749
+ const currentIndex = siblings . indexOf ( currentNode ! ) ;
750
+ const previousNode = siblings [ currentIndex - 1 ] ;
751
+ if ( previousNode ) {
752
+ // The jsx text needs no indentation whatsoever if it ends on the same line the previous sibling ends on
753
+ if ( sourceFile . getLineAndCharacterOfPosition ( range . end ) . line !== sourceFile . getLineAndCharacterOfPosition ( previousNode . end ) . line ) {
754
+ // The first line is (already) "indented" if the text starts on the same line as the previous sibling element ends on
755
+ const firstLineIsIndented = sourceFile . getLineAndCharacterOfPosition ( range . pos ) . line === sourceFile . getLineAndCharacterOfPosition ( previousNode . end ) . line ;
756
+ indentMultilineCommentOrJsxText ( range , childIndentation . indentation , firstLineIsIndented , /*indentFinalLine*/ false , /*jsxStyle*/ true ) ;
757
+ }
758
+ }
759
+ }
745
760
}
746
761
747
762
childContextNode = node ;
@@ -1041,7 +1056,7 @@ namespace ts.formatting {
1041
1056
return indentationString !== sourceFile . text . substr ( startLinePosition , indentationString . length ) ;
1042
1057
}
1043
1058
1044
- function indentMultilineCommentOrJsxText ( commentRange : TextRange , indentation : number , firstLineIsIndented : boolean , indentFinalLine = true ) {
1059
+ function indentMultilineCommentOrJsxText ( commentRange : TextRange , indentation : number , firstLineIsIndented : boolean , indentFinalLine = true , jsxTextStyleIndent ?: boolean ) {
1045
1060
// split comment in lines
1046
1061
let startLine = sourceFile . getLineAndCharacterOfPosition ( commentRange . pos ) . line ;
1047
1062
const endLine = sourceFile . getLineAndCharacterOfPosition ( commentRange . end ) . line ;
@@ -1072,7 +1087,7 @@ namespace ts.formatting {
1072
1087
const nonWhitespaceColumnInFirstPart =
1073
1088
SmartIndenter . findFirstNonWhitespaceCharacterAndColumn ( startLinePos , parts [ 0 ] . pos , sourceFile , options ) ;
1074
1089
1075
- if ( indentation === nonWhitespaceColumnInFirstPart . column ) {
1090
+ if ( indentation === nonWhitespaceColumnInFirstPart . column && ! jsxTextStyleIndent ) {
1076
1091
return ;
1077
1092
}
1078
1093
@@ -1083,14 +1098,19 @@ namespace ts.formatting {
1083
1098
}
1084
1099
1085
1100
// shift all parts on the delta size
1086
- const delta = indentation - nonWhitespaceColumnInFirstPart . column ;
1101
+ let delta = indentation - nonWhitespaceColumnInFirstPart . column ;
1087
1102
for ( let i = startIndex ; i < parts . length ; i ++ , startLine ++ ) {
1088
1103
const startLinePos = getStartPositionOfLine ( startLine , sourceFile ) ;
1089
1104
const nonWhitespaceCharacterAndColumn =
1090
1105
i === 0
1091
1106
? nonWhitespaceColumnInFirstPart
1092
1107
: SmartIndenter . findFirstNonWhitespaceCharacterAndColumn ( parts [ i ] . pos , parts [ i ] . end , sourceFile , options ) ;
1093
-
1108
+ if ( jsxTextStyleIndent ) {
1109
+ // skip adding indentation to blank lines
1110
+ if ( isLineBreak ( sourceFile . text . charCodeAt ( getStartPositionOfLine ( startLine , sourceFile ) ) ) ) continue ;
1111
+ // reset delta on every line
1112
+ delta = indentation - nonWhitespaceCharacterAndColumn . column ;
1113
+ }
1094
1114
const newIndentation = nonWhitespaceCharacterAndColumn . column + delta ;
1095
1115
if ( newIndentation > 0 ) {
1096
1116
const indentationString = getIndentationString ( newIndentation , options ) ;
0 commit comments