fix(compiler): handle invalid host bindings and events (#11101)
This commit is contained in:
parent
0a053a4cd5
commit
f25c97671a
|
@ -13,7 +13,7 @@ import {CompileDirectiveMetadata, CompilePipeMetadata, CompileTokenMetadata, rem
|
||||||
import {AST, ASTWithSource, BindingPipe, EmptyExpr, Interpolation, ParserError, RecursiveAstVisitor, TemplateBinding} from '../expression_parser/ast';
|
import {AST, ASTWithSource, BindingPipe, EmptyExpr, Interpolation, ParserError, RecursiveAstVisitor, TemplateBinding} from '../expression_parser/ast';
|
||||||
import {Parser} from '../expression_parser/parser';
|
import {Parser} from '../expression_parser/parser';
|
||||||
import {ListWrapper, SetWrapper, StringMapWrapper} from '../facade/collection';
|
import {ListWrapper, SetWrapper, StringMapWrapper} from '../facade/collection';
|
||||||
import {isBlank, isPresent} from '../facade/lang';
|
import {isBlank, isPresent, isString} from '../facade/lang';
|
||||||
import {HtmlParser} from '../i18n/html_parser';
|
import {HtmlParser} from '../i18n/html_parser';
|
||||||
import {Identifiers, identifierToken} from '../identifiers';
|
import {Identifiers, identifierToken} from '../identifiers';
|
||||||
import * as html from '../ml_parser/ast';
|
import * as html from '../ml_parser/ast';
|
||||||
|
@ -746,9 +746,15 @@ class TemplateParseVisitor implements html.Visitor {
|
||||||
targetPropertyAsts: BoundElementPropertyAst[]) {
|
targetPropertyAsts: BoundElementPropertyAst[]) {
|
||||||
if (isPresent(hostProps)) {
|
if (isPresent(hostProps)) {
|
||||||
StringMapWrapper.forEach(hostProps, (expression: string, propName: string) => {
|
StringMapWrapper.forEach(hostProps, (expression: string, propName: string) => {
|
||||||
const exprAst = this._parseBinding(expression, sourceSpan);
|
if (isString(expression)) {
|
||||||
targetPropertyAsts.push(
|
const exprAst = this._parseBinding(expression, sourceSpan);
|
||||||
this._createElementPropertyAst(elementName, propName, exprAst, sourceSpan));
|
targetPropertyAsts.push(
|
||||||
|
this._createElementPropertyAst(elementName, propName, exprAst, sourceSpan));
|
||||||
|
} else {
|
||||||
|
this._reportError(
|
||||||
|
`Value of the host property binding "${propName}" needs to be a string representing an expression but got "${expression}" (${typeof expression})`,
|
||||||
|
sourceSpan);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -758,7 +764,13 @@ class TemplateParseVisitor implements html.Visitor {
|
||||||
targetEventAsts: BoundEventAst[]) {
|
targetEventAsts: BoundEventAst[]) {
|
||||||
if (isPresent(hostListeners)) {
|
if (isPresent(hostListeners)) {
|
||||||
StringMapWrapper.forEach(hostListeners, (expression: string, propName: string) => {
|
StringMapWrapper.forEach(hostListeners, (expression: string, propName: string) => {
|
||||||
this._parseEvent(propName, expression, sourceSpan, [], targetEventAsts);
|
if (isString(expression)) {
|
||||||
|
this._parseEvent(propName, expression, sourceSpan, [], targetEventAsts);
|
||||||
|
} else {
|
||||||
|
this._reportError(
|
||||||
|
`Value of the host listener "${propName}" needs to be a string representing an expression but got "${expression}" (${typeof expression})`,
|
||||||
|
sourceSpan);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -313,6 +313,30 @@ Can't bind to 'invalidProp' since it isn't a known property of 'my-component'.
|
||||||
expect(console.warnings.length).toEqual(0);
|
expect(console.warnings.length).toEqual(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should throw descriptive error when a host binding is not a string expression', () => {
|
||||||
|
var dirA = CompileDirectiveMetadata.create({
|
||||||
|
selector: 'broken',
|
||||||
|
type: new CompileTypeMetadata({moduleUrl: someModuleUrl, name: 'DirA'}),
|
||||||
|
host: {'[class.foo]': null}
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(() => { parse('<broken></broken>', [dirA]); })
|
||||||
|
.toThrowError(
|
||||||
|
`Template parse errors:\nValue of the host property binding "class.foo" needs to be a string representing an expression but got "null" (object) ("[ERROR ->]<broken></broken>"): TestComp@0:0, Directive DirA`);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should throw descriptive error when a host event is not a string expression', () => {
|
||||||
|
var dirA = CompileDirectiveMetadata.create({
|
||||||
|
selector: 'broken',
|
||||||
|
type: new CompileTypeMetadata({moduleUrl: someModuleUrl, name: 'DirA'}),
|
||||||
|
host: {'(click)': null}
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(() => { parse('<broken></broken>', [dirA]); })
|
||||||
|
.toThrowError(
|
||||||
|
`Template parse errors:\nValue of the host listener "click" needs to be a string representing an expression but got "null" (object) ("[ERROR ->]<broken></broken>"): TestComp@0:0, Directive DirA`);
|
||||||
|
});
|
||||||
|
|
||||||
it('should not issue a warning when an animation property is bound without an expression',
|
it('should not issue a warning when an animation property is bound without an expression',
|
||||||
() => {
|
() => {
|
||||||
humanizeTplAst(parse('<div @something>', []));
|
humanizeTplAst(parse('<div @something>', []));
|
||||||
|
|
Loading…
Reference in New Issue