fix(compiler): allow WS as `<ng-content>` content (#12225)
This commit is contained in:
parent
17e3410d98
commit
df1718d624
|
@ -428,10 +428,8 @@ class TemplateParseVisitor implements html.Visitor {
|
||||||
let parsedElement: TemplateAst;
|
let parsedElement: TemplateAst;
|
||||||
|
|
||||||
if (preparsedElement.type === PreparsedElementType.NG_CONTENT) {
|
if (preparsedElement.type === PreparsedElementType.NG_CONTENT) {
|
||||||
if (isPresent(element.children) && element.children.length > 0) {
|
if (element.children && !element.children.every(_isEmptyTextNode)) {
|
||||||
this._reportError(
|
this._reportError(`<ng-content> element cannot have content.`, element.sourceSpan);
|
||||||
`<ng-content> element cannot have content. <ng-content> must be immediately followed by </ng-content>`,
|
|
||||||
element.sourceSpan);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
parsedElement = new NgContentAst(
|
parsedElement = new NgContentAst(
|
||||||
|
@ -1201,3 +1199,7 @@ export class PipeCollector extends RecursiveAstVisitor {
|
||||||
function _isAnimationLabel(name: string): boolean {
|
function _isAnimationLabel(name: string): boolean {
|
||||||
return name[0] == '@';
|
return name[0] == '@';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function _isEmptyTextNode(node: html.Node): boolean {
|
||||||
|
return node instanceof html.Text && node.value.trim().length == 0;
|
||||||
|
}
|
|
@ -274,12 +274,17 @@ export function main() {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should parse ngContent', () => {
|
it('should parse ngContent', () => {
|
||||||
var parsed = parse('<ng-content select="a">', []);
|
const parsed = parse('<ng-content select="a"></ng-content>', []);
|
||||||
|
expect(humanizeTplAst(parsed)).toEqual([[NgContentAst]]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should parse ngContent when it contains WS only', () => {
|
||||||
|
const parsed = parse('<ng-content select="a"> \n </ng-content>', []);
|
||||||
expect(humanizeTplAst(parsed)).toEqual([[NgContentAst]]);
|
expect(humanizeTplAst(parsed)).toEqual([[NgContentAst]]);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should parse ngContent regardless the namespace', () => {
|
it('should parse ngContent regardless the namespace', () => {
|
||||||
var parsed = parse('<svg><ng-content></ng-content></svg>', []);
|
const parsed = parse('<svg><ng-content></ng-content></svg>', []);
|
||||||
expect(humanizeTplAst(parsed)).toEqual([
|
expect(humanizeTplAst(parsed)).toEqual([
|
||||||
[ElementAst, ':svg:svg'],
|
[ElementAst, ':svg:svg'],
|
||||||
[NgContentAst],
|
[NgContentAst],
|
||||||
|
@ -1418,10 +1423,11 @@ Reference "#a" is defined several times ("<div #a></div><div [ERROR ->]#a></div>
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('error cases', () => {
|
describe('error cases', () => {
|
||||||
it('should report when ng-content has content', () => {
|
it('should report when ng-content has non WS content', () => {
|
||||||
expect(() => parse('<ng-content>content</ng-content>', []))
|
expect(() => parse('<ng-content>content</ng-content>', []))
|
||||||
.toThrowError(`Template parse errors:
|
.toThrowError(
|
||||||
<ng-content> element cannot have content. <ng-content> must be immediately followed by </ng-content> ("[ERROR ->]<ng-content>content</ng-content>"): TestComp@0:0`);
|
`Template parse errors:\n` +
|
||||||
|
`<ng-content> element cannot have content. ("[ERROR ->]<ng-content>content</ng-content>"): TestComp@0:0`);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should treat *attr on a template element as valid',
|
it('should treat *attr on a template element as valid',
|
||||||
|
|
Loading…
Reference in New Issue