refactor(animations): ensure animation input/outputs are managed within the template parser (#11782)
Closes #11782 Closes #11601 Related #11707
This commit is contained in:

committed by
Rado Kirov

parent
45ad13560b
commit
f1b6c6efa1
@ -10,7 +10,8 @@ import {AnimationMetadata, animate, group, sequence, style, transition, trigger}
|
||||
import {AsyncTestCompleter, beforeEach, beforeEachProviders, ddescribe, describe, expect, iit, inject, it, xdescribe, xit} from '@angular/core/testing/testing_internal';
|
||||
|
||||
import {StringMapWrapper} from '../../../platform-browser-dynamic/src/facade/collection';
|
||||
import {AnimationCompiler, CompiledAnimationTriggerResult} from '../../src/animation/animation_compiler';
|
||||
import {AnimationCompiler, AnimationEntryCompileResult} from '../../src/animation/animation_compiler';
|
||||
import {AnimationParser} from '../../src/animation/animation_parser';
|
||||
import {CompileAnimationEntryMetadata, CompileDirectiveMetadata, CompileTemplateMetadata, CompileTypeMetadata} from '../../src/compile_metadata';
|
||||
import {CompileMetadataResolver} from '../../src/metadata_resolver';
|
||||
|
||||
@ -20,12 +21,13 @@ export function main() {
|
||||
beforeEach(
|
||||
inject([CompileMetadataResolver], (res: CompileMetadataResolver) => { resolver = res; }));
|
||||
|
||||
var compiler = new AnimationCompiler();
|
||||
const parser = new AnimationParser();
|
||||
const compiler = new AnimationCompiler();
|
||||
|
||||
var compileAnimations =
|
||||
(component: CompileDirectiveMetadata): CompiledAnimationTriggerResult => {
|
||||
var result = compiler.compileComponent(component, []);
|
||||
return result.triggers[0];
|
||||
(component: CompileDirectiveMetadata): AnimationEntryCompileResult[] => {
|
||||
const parsedAnimations = parser.parseComponent(component);
|
||||
return compiler.compile(component.type.name, parsedAnimations);
|
||||
};
|
||||
|
||||
var compileTriggers = (input: any[]) => {
|
||||
@ -66,14 +68,5 @@ export function main() {
|
||||
expect(capturedErrorMessage)
|
||||
.toMatch(/Animation states via styles must be prefixed with a ":"/);
|
||||
});
|
||||
|
||||
it('should throw an error when two or more animation triggers contain the same name', () => {
|
||||
var t1Data: any[] = [];
|
||||
var t2Data: any[] = [];
|
||||
|
||||
expect(() => {
|
||||
compileTriggers([['myTrigger', t1Data], ['myTrigger', t2Data]]);
|
||||
}).toThrowError(/The animation trigger "myTrigger" has already been registered on "myCmp"/);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
@ -11,7 +11,8 @@ import {AsyncTestCompleter, beforeEach, beforeEachProviders, ddescribe, describe
|
||||
import {expect} from '@angular/platform-browser/testing/matchers';
|
||||
|
||||
import {AnimationAst, AnimationEntryAst, AnimationGroupAst, AnimationKeyframeAst, AnimationSequenceAst, AnimationStateTransitionAst, AnimationStepAst, AnimationStylesAst} from '../../src/animation/animation_ast';
|
||||
import {parseAnimationEntry} from '../../src/animation/animation_parser';
|
||||
import {AnimationParser} from '../../src/animation/animation_parser';
|
||||
import {CompileDirectiveMetadata, CompileTemplateMetadata, CompileTypeMetadata} from '../../src/compile_metadata';
|
||||
import {StringMapWrapper} from '../../src/facade/collection';
|
||||
import {CompileMetadataResolver} from '../../src/metadata_resolver';
|
||||
import {FILL_STYLE_FLAG, flattenStyles} from '../private_import_core';
|
||||
@ -46,9 +47,10 @@ export function main() {
|
||||
inject([CompileMetadataResolver], (res: CompileMetadataResolver) => { resolver = res; }));
|
||||
|
||||
var parseAnimation = (data: AnimationMetadata[]) => {
|
||||
var entry = trigger('myAnimation', [transition('state1 => state2', sequence(data))]);
|
||||
var compiledAnimationEntry = resolver.getAnimationEntryMetadata(entry);
|
||||
return parseAnimationEntry(compiledAnimationEntry);
|
||||
const entry = trigger('myAnimation', [transition('state1 => state2', sequence(data))]);
|
||||
const compiledAnimationEntry = resolver.getAnimationEntryMetadata(entry);
|
||||
const parser = new AnimationParser();
|
||||
return parser.parseEntry(compiledAnimationEntry);
|
||||
};
|
||||
|
||||
var getAnimationAstFromEntryAst =
|
||||
|
@ -6,7 +6,7 @@
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {CompileDiDependencyMetadata, CompileDirectiveMetadata, CompilePipeMetadata, CompileProviderMetadata, CompileQueryMetadata, CompileTemplateMetadata, CompileTokenMetadata, CompileTypeMetadata} from '@angular/compiler/src/compile_metadata';
|
||||
import {CompileAnimationEntryMetadata, CompileDiDependencyMetadata, CompileDirectiveMetadata, CompilePipeMetadata, CompileProviderMetadata, CompileQueryMetadata, CompileTemplateMetadata, CompileTokenMetadata, CompileTypeMetadata} from '@angular/compiler/src/compile_metadata';
|
||||
import {DomElementSchemaRegistry} from '@angular/compiler/src/schema/dom_element_schema_registry';
|
||||
import {ElementSchemaRegistry} from '@angular/compiler/src/schema/element_schema_registry';
|
||||
import {AttrAst, BoundDirectivePropertyAst, BoundElementPropertyAst, BoundEventAst, BoundTextAst, DirectiveAst, ElementAst, EmbeddedTemplateAst, NgContentAst, PropertyBindingType, ProviderAstType, ReferenceAst, TemplateAst, TemplateAstVisitor, TextAst, VariableAst, templateVisitAll} from '@angular/compiler/src/template_parser/template_ast';
|
||||
@ -16,7 +16,6 @@ import {SchemaMetadata, SecurityContext, Type} from '@angular/core';
|
||||
import {Console} from '@angular/core/src/console';
|
||||
import {TestBed} from '@angular/core/testing';
|
||||
import {afterEach, beforeEach, beforeEachProviders, ddescribe, describe, expect, iit, inject, it, xit} from '@angular/core/testing/testing_internal';
|
||||
|
||||
import {Identifiers, identifierToken, resolveIdentifierToken} from '../../src/identifiers';
|
||||
import {DEFAULT_INTERPOLATION_CONFIG, InterpolationConfig} from '../../src/ml_parser/interpolation_config';
|
||||
import {MockSchemaRegistry} from '../../testing/index';
|
||||
@ -32,9 +31,9 @@ const MOCK_SCHEMA_REGISTRY = [{
|
||||
|
||||
export function main() {
|
||||
var ngIf: CompileDirectiveMetadata;
|
||||
var parse:
|
||||
(template: string, directives: CompileDirectiveMetadata[], pipes?: CompilePipeMetadata[]) =>
|
||||
TemplateAst[];
|
||||
var parse: (
|
||||
template: string, directives: CompileDirectiveMetadata[], pipes?: CompilePipeMetadata[],
|
||||
schemas?: SchemaMetadata[]) => TemplateAst[];
|
||||
var console: ArrayConsole;
|
||||
|
||||
function commonBeforeEach() {
|
||||
@ -43,14 +42,18 @@ export function main() {
|
||||
TestBed.configureCompiler({providers: [{provide: Console, useValue: console}]});
|
||||
});
|
||||
beforeEach(inject([TemplateParser], (parser: TemplateParser) => {
|
||||
var someAnimation = new CompileAnimationEntryMetadata('someAnimation', []);
|
||||
var someTemplate = new CompileTemplateMetadata({animations: [someAnimation]});
|
||||
var component = CompileDirectiveMetadata.create({
|
||||
selector: 'root',
|
||||
template: someTemplate,
|
||||
type: new CompileTypeMetadata(
|
||||
{moduleUrl: someModuleUrl, name: 'Root', reference: {} as Type<any>}),
|
||||
isComponent: true
|
||||
});
|
||||
ngIf = CompileDirectiveMetadata.create({
|
||||
selector: '[ngIf]',
|
||||
template: someTemplate,
|
||||
type: new CompileTypeMetadata(
|
||||
{moduleUrl: someModuleUrl, name: 'NgIf', reference: {} as Type<any>}),
|
||||
inputs: ['ngIf']
|
||||
@ -302,27 +305,31 @@ Can't bind to 'invalidProp' since it isn't a known property of 'my-component'.
|
||||
]);
|
||||
});
|
||||
|
||||
it('should parse bound properties via bind-animate- and not report them as animation properties',
|
||||
it('should parse bound properties via bind-animate- and not report them as attributes',
|
||||
() => {
|
||||
expect(humanizeTplAst(parse('<div bind-animate-something="value2">', []))).toEqual([
|
||||
[ElementAst, 'div'],
|
||||
[
|
||||
BoundElementPropertyAst, PropertyBindingType.Animation, 'something', 'value2', null
|
||||
]
|
||||
]);
|
||||
expect(humanizeTplAst(parse('<div bind-animate-someAnimation="value2">', [], [], [])))
|
||||
.toEqual([
|
||||
[ElementAst, 'div'],
|
||||
[
|
||||
BoundElementPropertyAst, PropertyBindingType.Animation, 'someAnimation',
|
||||
'value2', null
|
||||
]
|
||||
]);
|
||||
});
|
||||
|
||||
it('should throw an error when parsing detects non-bound properties via @ that contain a value',
|
||||
() => {
|
||||
expect(() => { parse('<div @something="value2">', []); })
|
||||
expect(() => { parse('<div @someAnimation="value2">', [], [], []); })
|
||||
.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. \("<div \[ERROR ->\]@something="value2">"\): TestComp@0:5/);
|
||||
/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. \("<div \[ERROR ->\]@someAnimation="value2">"\): TestComp@0:5/);
|
||||
});
|
||||
|
||||
it('should not issue a warning when host attributes contain a valid property-bound animation trigger',
|
||||
() => {
|
||||
const animationEntries = [new CompileAnimationEntryMetadata('prop', [])];
|
||||
var dirA = CompileDirectiveMetadata.create({
|
||||
selector: 'div',
|
||||
template: new CompileTemplateMetadata({animations: animationEntries}),
|
||||
type: new CompileTypeMetadata(
|
||||
{moduleUrl: someModuleUrl, name: 'DirA', reference: {} as Type<any>}),
|
||||
host: {'[@prop]': 'expr'}
|
||||
@ -360,14 +367,17 @@ Can't bind to 'invalidProp' since it isn't a known property of 'my-component'.
|
||||
|
||||
it('should not issue a warning when an animation property is bound without an expression',
|
||||
() => {
|
||||
humanizeTplAst(parse('<div @something>', []));
|
||||
humanizeTplAst(parse('<div @someAnimation>', [], [], []));
|
||||
expect(console.warnings.length).toEqual(0);
|
||||
});
|
||||
|
||||
it('should parse bound properties via [@] and not report them as attributes', () => {
|
||||
expect(humanizeTplAst(parse('<div [@something]="value2">', []))).toEqual([
|
||||
expect(humanizeTplAst(parse('<div [@someAnimation]="value2">', [], [], []))).toEqual([
|
||||
[ElementAst, 'div'],
|
||||
[BoundElementPropertyAst, PropertyBindingType.Animation, 'something', 'value2', null]
|
||||
[
|
||||
BoundElementPropertyAst, PropertyBindingType.Animation, 'someAnimation', 'value2',
|
||||
null
|
||||
]
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
Reference in New Issue
Block a user