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 {Parser} from '../expression_parser/parser';
|
||||
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 {Identifiers, identifierToken} from '../identifiers';
|
||||
import * as html from '../ml_parser/ast';
|
||||
|
@ -746,9 +746,15 @@ class TemplateParseVisitor implements html.Visitor {
|
|||
targetPropertyAsts: BoundElementPropertyAst[]) {
|
||||
if (isPresent(hostProps)) {
|
||||
StringMapWrapper.forEach(hostProps, (expression: string, propName: string) => {
|
||||
const exprAst = this._parseBinding(expression, sourceSpan);
|
||||
targetPropertyAsts.push(
|
||||
this._createElementPropertyAst(elementName, propName, exprAst, sourceSpan));
|
||||
if (isString(expression)) {
|
||||
const exprAst = this._parseBinding(expression, 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[]) {
|
||||
if (isPresent(hostListeners)) {
|
||||
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);
|
||||
});
|
||||
|
||||
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',
|
||||
() => {
|
||||
humanizeTplAst(parse('<div @something>', []));
|
||||
|
|
Loading…
Reference in New Issue