fix(ivy): allow HTML comments to be present inside <ng-content> (#28849)

Prior to this change presence of HTML comments inside <ng-content> caused compiler to throw an error that <ng-content> is not empty. Now HTML comments are not considered as a meaningful content, thus no error is thrown. This behavior is now aligned in Ivy/VE.

PR Close #28849
This commit is contained in:
Andrew Kushnir 2019-02-19 18:28:00 -08:00 committed by Igor Minar
parent df627e65df
commit 95d9aa22ef
2 changed files with 27 additions and 1 deletions

View File

@ -1834,6 +1834,26 @@ describe('ngtsc behavioral tests', () => {
expect(jsContents).toContain('ɵsetClassMetadata(TestPipe, '); expect(jsContents).toContain('ɵsetClassMetadata(TestPipe, ');
}); });
it('should not throw in case whitespaces and HTML comments are present inside <ng-content>',
() => {
env.tsconfig();
env.write('test.ts', `
import {Component} from '@angular/core';
@Component({
selector: 'cmp-a',
template: \`
<ng-content>
<!-- Some comments -->
</ng-content>
\`,
})
class CmpA {}
`);
const errors = env.driveDiagnostics();
expect(errors.length).toBe(0);
});
it('should compile a template using multiple directives with the same selector', () => { it('should compile a template using multiple directives with the same selector', () => {
env.tsconfig(); env.tsconfig();
env.write('test.ts', ` env.write('test.ts', `

View File

@ -156,7 +156,9 @@ class HtmlAstToIvyAst implements html.Visitor {
let parsedElement: t.Node|undefined; let parsedElement: t.Node|undefined;
if (preparsedElement.type === PreparsedElementType.NG_CONTENT) { if (preparsedElement.type === PreparsedElementType.NG_CONTENT) {
// `<ng-content>` // `<ng-content>`
if (element.children && !element.children.every(isEmptyTextNode)) { if (element.children &&
!element.children.every(
(node: html.Node) => isEmptyTextNode(node) || isCommentNode(node))) {
this.reportError(`<ng-content> element cannot have content.`, element.sourceSpan); this.reportError(`<ng-content> element cannot have content.`, element.sourceSpan);
} }
const selector = preparsedElement.selectAttr; const selector = preparsedElement.selectAttr;
@ -413,3 +415,7 @@ function addEvents(events: ParsedEvent[], boundEvents: t.BoundEvent[]) {
function isEmptyTextNode(node: html.Node): boolean { function isEmptyTextNode(node: html.Node): boolean {
return node instanceof html.Text && node.value.trim().length == 0; return node instanceof html.Text && node.value.trim().length == 0;
} }
function isCommentNode(node: html.Node): boolean {
return node instanceof html.Comment;
}