@@ -151,28 +151,29 @@ namespace ts {
151
151
}
152
152
}
153
153
154
- function visitJsxText ( node : JsxText ) {
155
- const text = getTextOfNode ( node , /*includeTrivia*/ true ) ;
156
- let parts : Expression [ ] ;
154
+ function visitJsxText ( node : JsxText ) : StringLiteral | undefined {
155
+ const fixed = fixupWhitespaceAndDecodeEntities ( getTextOfNode ( node , /*includeTrivia*/ true ) ) ;
156
+ return fixed !== undefined && createLiteral ( fixed ) ;
157
+ }
158
+
159
+ /**
160
+ * JSX trims whitespace at the end and beginning of lines, except that the
161
+ * start/end of a tag is considered a start/end of a line only if that line is
162
+ * on the same line as the closing tag. See examples in
163
+ * tests/cases/conformance/jsx/tsxReactEmitWhitespace.tsx
164
+ * See also https://www.w3.org/TR/html4/struct/text.html#h-9.1 and https://www.w3.org/TR/CSS2/text.html#white-space-model
165
+ */
166
+ function fixupWhitespaceAndDecodeEntities ( text : string ) : string | undefined {
167
+ let acc : string | undefined ;
157
168
let firstNonWhitespace = 0 ;
158
169
let lastNonWhitespace = - 1 ;
159
170
160
- // JSX trims whitespace at the end and beginning of lines, except that the
161
- // start/end of a tag is considered a start/end of a line only if that line is
162
- // on the same line as the closing tag. See examples in
163
- // tests/cases/conformance/jsx/tsxReactEmitWhitespace.tsx
164
171
for ( let i = 0 ; i < text . length ; i ++ ) {
165
172
const c = text . charCodeAt ( i ) ;
166
173
if ( isLineBreak ( c ) ) {
167
174
if ( firstNonWhitespace !== - 1 && ( lastNonWhitespace - firstNonWhitespace + 1 > 0 ) ) {
168
- const part = text . substr ( firstNonWhitespace , lastNonWhitespace - firstNonWhitespace + 1 ) ;
169
- if ( ! parts ) {
170
- parts = [ ] ;
171
- }
172
-
173
- // We do not escape the string here as that is handled by the printer
174
- // when it emits the literal. We do, however, need to decode JSX entities.
175
- parts . push ( createLiteral ( decodeEntities ( part ) ) ) ;
175
+ const part = decodeEntities ( text . substr ( firstNonWhitespace , lastNonWhitespace - firstNonWhitespace + 1 ) ) ;
176
+ acc = acc === undefined ? part : acc + " " + part ;
176
177
}
177
178
178
179
firstNonWhitespace = - 1 ;
@@ -186,28 +187,12 @@ namespace ts {
186
187
}
187
188
188
189
if ( firstNonWhitespace !== - 1 ) {
189
- const part = text . substr ( firstNonWhitespace ) ;
190
- if ( ! parts ) {
191
- parts = [ ] ;
192
- }
193
-
194
- // We do not escape the string here as that is handled by the printer
195
- // when it emits the literal. We do, however, need to decode JSX entities.
196
- parts . push ( createLiteral ( decodeEntities ( part ) ) ) ;
190
+ const lastPart = decodeEntities ( text . substr ( firstNonWhitespace ) ) ;
191
+ return acc ? acc + lastPart : lastPart ;
197
192
}
198
-
199
- if ( parts ) {
200
- return reduceLeft ( parts , aggregateJsxTextParts ) ;
193
+ else {
194
+ return acc ;
201
195
}
202
-
203
- return undefined ;
204
- }
205
-
206
- /**
207
- * Aggregates two expressions by interpolating them with a whitespace literal.
208
- */
209
- function aggregateJsxTextParts ( left : Expression , right : Expression ) {
210
- return createAdd ( createAdd ( left , createLiteral ( " " ) ) , right ) ;
211
196
}
212
197
213
198
/**
0 commit comments