fix(HtmlParser): ignore LF immediately following pre, textarea & listing
fixes #5630 Closes #5688
This commit is contained in:
parent
47f1d12731
commit
eb0ea931d0
@ -106,7 +106,18 @@ class TreeBuilder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private _consumeText(token: HtmlToken) {
|
private _consumeText(token: HtmlToken) {
|
||||||
this._addToParent(new HtmlTextAst(token.parts[0], token.sourceSpan));
|
let text = token.parts[0];
|
||||||
|
if (text.length > 0 && text[0] == '\n') {
|
||||||
|
let parent = this._getParentElement();
|
||||||
|
if (isPresent(parent) && parent.children.length == 0 &&
|
||||||
|
getHtmlTagDefinition(parent.name).ignoreFirstLf) {
|
||||||
|
text = text.substring(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (text.length > 0) {
|
||||||
|
this._addToParent(new HtmlTextAst(text, token.sourceSpan));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private _closeVoidElement(): void {
|
private _closeVoidElement(): void {
|
||||||
|
@ -279,15 +279,17 @@ export class HtmlTagDefinition {
|
|||||||
public implicitNamespacePrefix: string;
|
public implicitNamespacePrefix: string;
|
||||||
public contentType: HtmlTagContentType;
|
public contentType: HtmlTagContentType;
|
||||||
public isVoid: boolean;
|
public isVoid: boolean;
|
||||||
|
public ignoreFirstLf: boolean;
|
||||||
|
|
||||||
constructor({closedByChildren, requiredParents, implicitNamespacePrefix, contentType,
|
constructor({closedByChildren, requiredParents, implicitNamespacePrefix, contentType,
|
||||||
closedByParent, isVoid}: {
|
closedByParent, isVoid, ignoreFirstLf}: {
|
||||||
closedByChildren?: string[],
|
closedByChildren?: string[],
|
||||||
closedByParent?: boolean,
|
closedByParent?: boolean,
|
||||||
requiredParents?: string[],
|
requiredParents?: string[],
|
||||||
implicitNamespacePrefix?: string,
|
implicitNamespacePrefix?: string,
|
||||||
contentType?: HtmlTagContentType,
|
contentType?: HtmlTagContentType,
|
||||||
isVoid?: boolean
|
isVoid?: boolean,
|
||||||
|
ignoreFirstLf?: boolean
|
||||||
} = {}) {
|
} = {}) {
|
||||||
if (isPresent(closedByChildren) && closedByChildren.length > 0) {
|
if (isPresent(closedByChildren) && closedByChildren.length > 0) {
|
||||||
closedByChildren.forEach(tagName => this.closedByChildren[tagName] = true);
|
closedByChildren.forEach(tagName => this.closedByChildren[tagName] = true);
|
||||||
@ -301,6 +303,7 @@ export class HtmlTagDefinition {
|
|||||||
}
|
}
|
||||||
this.implicitNamespacePrefix = implicitNamespacePrefix;
|
this.implicitNamespacePrefix = implicitNamespacePrefix;
|
||||||
this.contentType = isPresent(contentType) ? contentType : HtmlTagContentType.PARSABLE_DATA;
|
this.contentType = isPresent(contentType) ? contentType : HtmlTagContentType.PARSABLE_DATA;
|
||||||
|
this.ignoreFirstLf = normalizeBool(ignoreFirstLf);
|
||||||
}
|
}
|
||||||
|
|
||||||
requireExtraParent(currentParent: string): boolean {
|
requireExtraParent(currentParent: string): boolean {
|
||||||
@ -388,10 +391,13 @@ var TAG_DEFINITIONS: {[key: string]: HtmlTagDefinition} = {
|
|||||||
'rp': new HtmlTagDefinition({closedByChildren: ['rb', 'rt', 'rtc', 'rp'], closedByParent: true}),
|
'rp': new HtmlTagDefinition({closedByChildren: ['rb', 'rt', 'rtc', 'rp'], closedByParent: true}),
|
||||||
'optgroup': new HtmlTagDefinition({closedByChildren: ['optgroup'], closedByParent: true}),
|
'optgroup': new HtmlTagDefinition({closedByChildren: ['optgroup'], closedByParent: true}),
|
||||||
'option': new HtmlTagDefinition({closedByChildren: ['option', 'optgroup'], closedByParent: true}),
|
'option': new HtmlTagDefinition({closedByChildren: ['option', 'optgroup'], closedByParent: true}),
|
||||||
|
'pre': new HtmlTagDefinition({ignoreFirstLf: true}),
|
||||||
|
'listing': new HtmlTagDefinition({ignoreFirstLf: true}),
|
||||||
'style': new HtmlTagDefinition({contentType: HtmlTagContentType.RAW_TEXT}),
|
'style': new HtmlTagDefinition({contentType: HtmlTagContentType.RAW_TEXT}),
|
||||||
'script': new HtmlTagDefinition({contentType: HtmlTagContentType.RAW_TEXT}),
|
'script': new HtmlTagDefinition({contentType: HtmlTagContentType.RAW_TEXT}),
|
||||||
'title': new HtmlTagDefinition({contentType: HtmlTagContentType.ESCAPABLE_RAW_TEXT}),
|
'title': new HtmlTagDefinition({contentType: HtmlTagContentType.ESCAPABLE_RAW_TEXT}),
|
||||||
'textarea': new HtmlTagDefinition({contentType: HtmlTagContentType.ESCAPABLE_RAW_TEXT}),
|
'textarea': new HtmlTagDefinition(
|
||||||
|
{contentType: HtmlTagContentType.ESCAPABLE_RAW_TEXT, ignoreFirstLf: true}),
|
||||||
};
|
};
|
||||||
|
|
||||||
var DEFAULT_TAG_DEFINITION = new HtmlTagDefinition();
|
var DEFAULT_TAG_DEFINITION = new HtmlTagDefinition();
|
||||||
|
@ -178,6 +178,22 @@ export function main() {
|
|||||||
expect(humanizeDom(parser.parse('<math />', 'TestComp')))
|
expect(humanizeDom(parser.parse('<math />', 'TestComp')))
|
||||||
.toEqual([[HtmlElementAst, '@math:math', 0]]);
|
.toEqual([[HtmlElementAst, '@math:math', 0]]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should ignore LF immediately after textarea, pre and listing', () => {
|
||||||
|
expect(humanizeDom(parser.parse(
|
||||||
|
'<p>\n</p><textarea>\n</textarea><pre>\n\n</pre><listing>\n\n</listing>',
|
||||||
|
'TestComp')))
|
||||||
|
.toEqual([
|
||||||
|
[HtmlElementAst, 'p', 0],
|
||||||
|
[HtmlTextAst, '\n', 1],
|
||||||
|
[HtmlElementAst, 'textarea', 0],
|
||||||
|
[HtmlElementAst, 'pre', 0],
|
||||||
|
[HtmlTextAst, '\n', 1],
|
||||||
|
[HtmlElementAst, 'listing', 0],
|
||||||
|
[HtmlTextAst, '\n', 1],
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('attributes', () => {
|
describe('attributes', () => {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user