diff --git a/modules/@angular/compiler/src/template_parser/template_parser.ts b/modules/@angular/compiler/src/template_parser/template_parser.ts index 9442ca5b1f..e87bb2769b 100644 --- a/modules/@angular/compiler/src/template_parser/template_parser.ts +++ b/modules/@angular/compiler/src/template_parser/template_parser.ts @@ -39,14 +39,15 @@ import {PreparsedElementType, preparseElement} from './template_preparser'; // Group 4 = "ref-/#" // Group 5 = "on-" // Group 6 = "bindon-" -// Group 7 = "animate-/@" +// Group 7 = "@" // Group 8 = the identifier after "bind-", "var-/#", or "on-" // Group 9 = identifier inside [()] // Group 10 = identifier inside [] // Group 11 = identifier inside () const BIND_NAME_REGEXP = - /^(?:(?:(?:(bind-)|(var-)|(let-)|(ref-|#)|(on-)|(bindon-)|(animate-|@))(.+))|\[\(([^\)]+)\)\]|\[([^\]]+)\]|\(([^\)]+)\))$/; + /^(?:(?:(?:(bind-)|(var-)|(let-)|(ref-|#)|(on-)|(bindon-)|(@))(.+))|\[\(([^\)]+)\)\]|\[([^\]]+)\]|\(([^\)]+)\))$/; +const ANIMATE_PROP_PREFIX = 'animate-'; const TEMPLATE_ELEMENT = 'template'; const TEMPLATE_ATTR = 'template'; const TEMPLATE_ATTR_PREFIX = '*'; @@ -540,8 +541,8 @@ class TemplateParseVisitor implements html.Visitor { } else if (isPresent(bindParts[7])) { // match: animate-name if (attrName[0] == '@' && isPresent(attrValue) && attrValue.length > 0) { this._reportError( - `Assigning animation triggers via @prop="exp" attributes with an expression is deprecated. Use property bindings (e.g. [@prop]="exp") instead!`, - attr.sourceSpan, ParseErrorLevel.WARNING); + `Assigning animation triggers via @prop="exp" attributes with an expression is invalid. Use property bindings (e.g. [@prop]="exp") or use an attribute without a value \(e.g. @prop\) instead.`, + attr.sourceSpan, ParseErrorLevel.FATAL); } this._parseAnimation( bindParts[8], attrValue, attr.sourceSpan, targetMatchableAttrs, targetAnimationProps); @@ -598,9 +599,18 @@ class TemplateParseVisitor implements html.Visitor { name: string, expression: string, sourceSpan: ParseSourceSpan, targetMatchableAttrs: string[][], targetProps: BoundElementOrDirectiveProperty[], targetAnimationProps: BoundElementPropertyAst[]) { - if (name[0] == '@') { + const animatePropLength = ANIMATE_PROP_PREFIX.length; + var isAnimationProp = name[0] == '@'; + var animationPrefixLength = 1; + if (name.substring(0, animatePropLength) == ANIMATE_PROP_PREFIX) { + isAnimationProp = true; + animationPrefixLength = animatePropLength; + } + + if (isAnimationProp) { this._parseAnimation( - name.substr(1), expression, sourceSpan, targetMatchableAttrs, targetAnimationProps); + name.substr(animationPrefixLength), expression, sourceSpan, targetMatchableAttrs, + targetAnimationProps); } else { this._parsePropertyAst( name, this._parseBinding(expression, sourceSpan), sourceSpan, targetMatchableAttrs, @@ -809,11 +819,10 @@ class TemplateParseVisitor implements html.Visitor { boundPropertyName = partValue.substr(1); bindingType = PropertyBindingType.Animation; securityContext = SecurityContext.NONE; - // DEPRECATED: remove this if statement post RC5 if (boundPropertyName[0] == '@') { this._reportError( - `Assigning animation triggers within host data as attributes such as "@prop": "exp" is deprecated. Use host bindings (e.g. "[@prop]": "exp") instead!`, - sourceSpan, ParseErrorLevel.WARNING); + `Assigning animation triggers within host data as attributes such as "@prop": "exp" is invalid. Use host bindings (e.g. "[@prop]": "exp") instead.`, + sourceSpan, ParseErrorLevel.FATAL); boundPropertyName = boundPropertyName.substr(1); } } else { diff --git a/modules/@angular/compiler/test/template_parser/template_parser_spec.ts b/modules/@angular/compiler/test/template_parser/template_parser_spec.ts index cb23d00b4c..2f2abffc5f 100644 --- a/modules/@angular/compiler/test/template_parser/template_parser_spec.ts +++ b/modules/@angular/compiler/test/template_parser/template_parser_spec.ts @@ -284,44 +284,36 @@ Can't bind to 'invalidProp' since it isn't a known property of 'my-component'. ]); }); - it('should parse bound properties via animate- and not report them as attributes', () => { - expect(humanizeTplAst(parse('
', []))).toEqual([ - [ElementAst, 'div'], - [BoundElementPropertyAst, PropertyBindingType.Animation, 'something', 'value2', null] - ]); - }); - - // DEPRECATED: remove this spec post RC5 - it('should parse bound properties via @ and not report them as attributes and also report a deprecation warning', + it('should parse bound properties via bind-animate- and not report them as animation properties', () => { - expect(humanizeTplAst(parse('
', []))).toEqual([ + expect(humanizeTplAst(parse('
', []))).toEqual([ [ElementAst, 'div'], [ BoundElementPropertyAst, PropertyBindingType.Animation, 'something', 'value2', null ] ]); - - expect(console.warnings).toEqual([[ - 'Template parse warnings:', - `Assigning animation triggers via @prop="exp" attributes with an expression is deprecated. Use property bindings (e.g. [@prop]="exp") instead! ("
]@something="value2">"): TestComp@0:5` - ].join('\n')]); }); - // DEPRECATED: remove this spec post RC5 - it('should issue a warning when host attributes contain a non property-bound animation trigger', + it('should throw an error when parsing detects non-bound properties via @ that contain a value', () => { - var dirA = CompileDirectiveMetadata.create({ - selector: 'div', - type: new CompileTypeMetadata({moduleUrl: someModuleUrl, name: 'DirA'}), - host: {'@prop': 'expr'} - }); + expect(() => { parse('
', []); }) + .toThrowError( + /Assigning animation triggers via @prop="exp" attributes with an expression is invalid. Use property bindings \(e.g. \[@prop\]="exp"\) or use an attribute without a value \(e.g. @prop\) instead. \("
\]@something="value2">"\): TestComp@0:5/); + }); - humanizeTplAst(parse('
', [dirA])); + it('should throw an error when host attributes contain a non property-bound animation trigger', + () => { + expect(() => { + var dirA = CompileDirectiveMetadata.create({ + selector: 'div', + type: new CompileTypeMetadata({moduleUrl: someModuleUrl, name: 'DirA'}), + host: {'@prop': 'expr'} + }); - expect(console.warnings).toEqual([[ - 'Template parse warnings:', - `Assigning animation triggers within host data as attributes such as "@prop": "exp" is deprecated. Use host bindings (e.g. "[@prop]": "exp") instead! ("[ERROR ->]
"): TestComp@0:0, Directive DirA` - ].join('\n')]); + humanizeTplAst(parse('
', [dirA])); + }) + .toThrowError( + /Assigning animation triggers within host data as attributes such as "@prop": "exp" is invalid. Use host bindings \(e.g. "\[@prop\]": "exp"\) instead. \("\[ERROR ->\]
<\/div>"\): TestComp@0:0, Directive DirA/); }); it('should not issue a warning when host attributes contain a valid property-bound animation trigger',