Skip to content

Commit eb0ea93

Browse files
committed
fix(HtmlParser): ignore LF immediately following pre, textarea & listing
fixes angular#5630 Closes angular#5688
1 parent 47f1d12 commit eb0ea93

File tree

3 files changed

+37
-4
lines changed

3 files changed

+37
-4
lines changed

modules/angular2/src/compiler/html_parser.ts

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,18 @@ class TreeBuilder {
106106
}
107107

108108
private _consumeText(token: HtmlToken) {
109-
this._addToParent(new HtmlTextAst(token.parts[0], token.sourceSpan));
109+
let text = token.parts[0];
110+
if (text.length > 0 && text[0] == '\n') {
111+
let parent = this._getParentElement();
112+
if (isPresent(parent) && parent.children.length == 0 &&
113+
getHtmlTagDefinition(parent.name).ignoreFirstLf) {
114+
text = text.substring(1);
115+
}
116+
}
117+
118+
if (text.length > 0) {
119+
this._addToParent(new HtmlTextAst(text, token.sourceSpan));
120+
}
110121
}
111122

112123
private _closeVoidElement(): void {

modules/angular2/src/compiler/html_tags.ts

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -279,15 +279,17 @@ export class HtmlTagDefinition {
279279
public implicitNamespacePrefix: string;
280280
public contentType: HtmlTagContentType;
281281
public isVoid: boolean;
282+
public ignoreFirstLf: boolean;
282283

283284
constructor({closedByChildren, requiredParents, implicitNamespacePrefix, contentType,
284-
closedByParent, isVoid}: {
285+
closedByParent, isVoid, ignoreFirstLf}: {
285286
closedByChildren?: string[],
286287
closedByParent?: boolean,
287288
requiredParents?: string[],
288289
implicitNamespacePrefix?: string,
289290
contentType?: HtmlTagContentType,
290-
isVoid?: boolean
291+
isVoid?: boolean,
292+
ignoreFirstLf?: boolean
291293
} = {}) {
292294
if (isPresent(closedByChildren) && closedByChildren.length > 0) {
293295
closedByChildren.forEach(tagName => this.closedByChildren[tagName] = true);
@@ -301,6 +303,7 @@ export class HtmlTagDefinition {
301303
}
302304
this.implicitNamespacePrefix = implicitNamespacePrefix;
303305
this.contentType = isPresent(contentType) ? contentType : HtmlTagContentType.PARSABLE_DATA;
306+
this.ignoreFirstLf = normalizeBool(ignoreFirstLf);
304307
}
305308

306309
requireExtraParent(currentParent: string): boolean {
@@ -388,10 +391,13 @@ var TAG_DEFINITIONS: {[key: string]: HtmlTagDefinition} = {
388391
'rp': new HtmlTagDefinition({closedByChildren: ['rb', 'rt', 'rtc', 'rp'], closedByParent: true}),
389392
'optgroup': new HtmlTagDefinition({closedByChildren: ['optgroup'], closedByParent: true}),
390393
'option': new HtmlTagDefinition({closedByChildren: ['option', 'optgroup'], closedByParent: true}),
394+
'pre': new HtmlTagDefinition({ignoreFirstLf: true}),
395+
'listing': new HtmlTagDefinition({ignoreFirstLf: true}),
391396
'style': new HtmlTagDefinition({contentType: HtmlTagContentType.RAW_TEXT}),
392397
'script': new HtmlTagDefinition({contentType: HtmlTagContentType.RAW_TEXT}),
393398
'title': new HtmlTagDefinition({contentType: HtmlTagContentType.ESCAPABLE_RAW_TEXT}),
394-
'textarea': new HtmlTagDefinition({contentType: HtmlTagContentType.ESCAPABLE_RAW_TEXT}),
399+
'textarea': new HtmlTagDefinition(
400+
{contentType: HtmlTagContentType.ESCAPABLE_RAW_TEXT, ignoreFirstLf: true}),
395401
};
396402

397403
var DEFAULT_TAG_DEFINITION = new HtmlTagDefinition();

modules/angular2/test/compiler/html_parser_spec.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,22 @@ export function main() {
178178
expect(humanizeDom(parser.parse('<math />', 'TestComp')))
179179
.toEqual([[HtmlElementAst, '@math:math', 0]]);
180180
});
181+
182+
it('should ignore LF immediately after textarea, pre and listing', () => {
183+
expect(humanizeDom(parser.parse(
184+
'<p>\n</p><textarea>\n</textarea><pre>\n\n</pre><listing>\n\n</listing>',
185+
'TestComp')))
186+
.toEqual([
187+
[HtmlElementAst, 'p', 0],
188+
[HtmlTextAst, '\n', 1],
189+
[HtmlElementAst, 'textarea', 0],
190+
[HtmlElementAst, 'pre', 0],
191+
[HtmlTextAst, '\n', 1],
192+
[HtmlElementAst, 'listing', 0],
193+
[HtmlTextAst, '\n', 1],
194+
]);
195+
});
196+
181197
});
182198

183199
describe('attributes', () => {

0 commit comments

Comments
 (0)