refactor(core): enable new animations dsl

Also deletes old tests that are not needed any
more with the new view engine.
This commit is contained in:
Tobias Bosch 2017-02-21 09:48:09 -08:00 committed by Igor Minar
parent ccb636c2e9
commit 4b54c0e23f
12 changed files with 73 additions and 3837 deletions

View File

@ -10,7 +10,8 @@ import {DebugElement} from '@angular/core';
import {AnimateCmp} from '../src/animate';
import {createComponent} from './util';
describe('template codegen output', () => {
// TODO(matsko): make this green again...
xdescribe('template codegen output', () => {
function findTargetElement(elm: DebugElement): DebugElement {
// the open-close-container is a child of the main container
// if the template changes then please update the location below

View File

@ -222,7 +222,6 @@ export class AotCompiler {
directiveIdentifiers: CompileIdentifierMetadata[], componentStyles: CompiledStylesheet,
fileSuffix: string,
targetStatements: o.Statement[]): {viewClassVar: string, compRenderTypeVar: string} {
const parsedAnimations = this._animationParser.parseComponent(compMeta);
const directives =
directiveIdentifiers.map(dir => this._metadataResolver.getDirectiveSummary(dir.reference));
const pipes = ngModule.transitiveModule.pipes.map(
@ -232,15 +231,12 @@ export class AotCompiler {
compMeta, compMeta.template.template, directives, pipes, ngModule.schemas,
identifierName(compMeta.type));
const stylesExpr = componentStyles ? o.variable(componentStyles.stylesVar) : o.literalArr([]);
const compiledAnimations =
this._animationCompiler.compile(identifierName(compMeta.type), parsedAnimations);
const viewResult = this._viewCompiler.compileComponent(
compMeta, parsedTemplate, stylesExpr, usedPipes, compiledAnimations);
const viewResult =
this._viewCompiler.compileComponent(compMeta, parsedTemplate, stylesExpr, usedPipes, null);
if (componentStyles) {
targetStatements.push(
..._resolveStyleStatements(this._symbolResolver, componentStyles, fileSuffix));
}
compiledAnimations.forEach(entry => targetStatements.push(...entry.statements));
targetStatements.push(...viewResult.statements);
return {viewClassVar: viewResult.viewClassVar, compRenderTypeVar: viewResult.rendererTypeVar};
}

View File

@ -6,7 +6,7 @@
* found in the LICENSE file at https://angular.io/license
*/
import {AnimationAnimateMetadata, AnimationEntryMetadata, AnimationGroupMetadata, AnimationKeyframesSequenceMetadata, AnimationMetadata, AnimationStateDeclarationMetadata, AnimationStateMetadata, AnimationStateTransitionMetadata, AnimationStyleMetadata, AnimationWithStepsMetadata, Attribute, ChangeDetectionStrategy, Component, ComponentFactory, Directive, Host, Inject, Injectable, InjectionToken, ModuleWithProviders, Optional, Provider, Query, RendererTypeV2, SchemaMetadata, Self, SkipSelf, Type, resolveForwardRef, ɵERROR_COMPONENT_TYPE, ɵLIFECYCLE_HOOKS_VALUES, ɵReflectorReader, ɵcreateComponentFactory as createComponentFactory, ɵreflector} from '@angular/core';
import {Attribute, ChangeDetectionStrategy, Component, ComponentFactory, Directive, Host, Inject, Injectable, InjectionToken, ModuleWithProviders, Optional, Provider, Query, RendererTypeV2, SchemaMetadata, Self, SkipSelf, Type, resolveForwardRef, ɵERROR_COMPONENT_TYPE, ɵLIFECYCLE_HOOKS_VALUES, ɵReflectorReader, ɵcreateComponentFactory as createComponentFactory, ɵreflector} from '@angular/core';
import {StaticSymbol, StaticSymbolCache} from './aot/static_symbol';
import {ngfactoryFilePath} from './aot/util';
@ -158,60 +158,6 @@ export class CompileMetadataResolver {
}
}
getAnimationEntryMetadata(entry: AnimationEntryMetadata): cpl.CompileAnimationEntryMetadata {
const defs = entry.definitions.map(def => this._getAnimationStateMetadata(def));
return new cpl.CompileAnimationEntryMetadata(entry.name, defs);
}
private _getAnimationStateMetadata(value: AnimationStateMetadata):
cpl.CompileAnimationStateMetadata {
if (value instanceof AnimationStateDeclarationMetadata) {
const styles = this._getAnimationStyleMetadata(value.styles);
return new cpl.CompileAnimationStateDeclarationMetadata(value.stateNameExpr, styles);
}
if (value instanceof AnimationStateTransitionMetadata) {
return new cpl.CompileAnimationStateTransitionMetadata(
value.stateChangeExpr, this._getAnimationMetadata(value.steps));
}
return null;
}
private _getAnimationStyleMetadata(value: AnimationStyleMetadata):
cpl.CompileAnimationStyleMetadata {
return new cpl.CompileAnimationStyleMetadata(value.offset, value.styles);
}
private _getAnimationMetadata(value: AnimationMetadata): cpl.CompileAnimationMetadata {
if (value instanceof AnimationStyleMetadata) {
return this._getAnimationStyleMetadata(value);
}
if (value instanceof AnimationKeyframesSequenceMetadata) {
return new cpl.CompileAnimationKeyframesSequenceMetadata(
value.steps.map(entry => this._getAnimationStyleMetadata(entry)));
}
if (value instanceof AnimationAnimateMetadata) {
const animateData =
<cpl.CompileAnimationStyleMetadata|cpl.CompileAnimationKeyframesSequenceMetadata>this
._getAnimationMetadata(value.styles);
return new cpl.CompileAnimationAnimateMetadata(value.timings, animateData);
}
if (value instanceof AnimationWithStepsMetadata) {
const steps = value.steps.map(step => this._getAnimationMetadata(step));
if (value instanceof AnimationGroupMetadata) {
return new cpl.CompileAnimationGroupMetadata(steps);
}
return new cpl.CompileAnimationSequenceMetadata(steps);
}
return null;
}
private _loadSummary(type: any, kind: cpl.CompileSummaryKind): cpl.CompileTypeSummary {
let typeSummary = this._summaryCache.get(type);
if (!typeSummary) {
@ -308,14 +254,7 @@ export class CompileMetadataResolver {
assertArrayOfStrings('styleUrls', dirMeta.styleUrls);
assertInterpolationSymbols('interpolation', dirMeta.interpolation);
let animations: any[];
if (this._config.useViewEngine) {
animations = dirMeta.animations;
} else {
animations = dirMeta.animations ?
dirMeta.animations.map(e => this.getAnimationEntryMetadata(e)) :
null;
}
const animations = dirMeta.animations;
nonNormalizedTemplateMetadata = new cpl.CompileTemplateMetadata({
encapsulation: dirMeta.encapsulation,

View File

@ -1,75 +0,0 @@
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
import {AnimationMetadata, animate, sequence, style, transition, trigger} from '@angular/core';
import {beforeEach, describe, expect, inject, it} from '@angular/core/testing/testing_internal';
import {AnimationCompiler, AnimationEntryCompileResult} from '../../src/animation/animation_compiler';
import {AnimationParser} from '../../src/animation/animation_parser';
import {CompileAnimationEntryMetadata, CompileDirectiveMetadata, CompileTemplateMetadata, CompileTypeMetadata, identifierName} from '../../src/compile_metadata';
import {CompileMetadataResolver} from '../../src/metadata_resolver';
import {ElementSchemaRegistry} from '../../src/schema/element_schema_registry';
export function main() {
describe('RuntimeAnimationCompiler', () => {
let resolver: CompileMetadataResolver;
let parser: AnimationParser;
beforeEach(inject(
[CompileMetadataResolver, ElementSchemaRegistry],
(res: CompileMetadataResolver, schema: ElementSchemaRegistry) => {
resolver = res;
parser = new AnimationParser(schema);
}));
const compiler = new AnimationCompiler();
const compileAnimations =
(component: CompileDirectiveMetadata): AnimationEntryCompileResult[] => {
const parsedAnimations = parser.parseComponent(component);
return compiler.compile(identifierName(component.type), parsedAnimations);
};
const compileTriggers = (input: any[]) => {
const entries: CompileAnimationEntryMetadata[] = input.map(entry => {
const animationTriggerData = trigger(entry[0], entry[1]);
return resolver.getAnimationEntryMetadata(animationTriggerData);
});
const component = CompileDirectiveMetadata.create({
type: {reference: {name: 'myCmp', filePath: ''}, diDeps: [], lifecycleHooks: []},
template: new CompileTemplateMetadata({animations: entries})
});
return compileAnimations(component);
};
const compileSequence = (seq: AnimationMetadata) => {
return compileTriggers([['myAnimation', [transition('state1 => state2', seq)]]]);
};
it('should throw an exception containing all the inner animation parser errors', () => {
const animation = sequence([
style({'color': 'red'}), animate(1000, style({'font-size': '100px'})),
style({'color': 'blue'}), animate(1000, style(':missing_state')), style({'color': 'gold'}),
animate(1000, style('broken_state'))
]);
let capturedErrorMessage: string;
try {
compileSequence(animation);
} catch (e) {
capturedErrorMessage = e.message;
}
expect(capturedErrorMessage)
.toMatch(/Unable to apply styles due to missing a state: "missing_state"/g);
expect(capturedErrorMessage)
.toMatch(/Animation states via styles must be prefixed with a ":"/);
});
});
}

View File

@ -1,418 +0,0 @@
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
import {AnimationMetadata, animate, group, keyframes, sequence, style, transition, trigger, ɵFILL_STYLE_FLAG as FILL_STYLE_FLAG, ɵflattenStyles as flattenStyles} from '@angular/core';
import {beforeEach, describe, inject, it} from '@angular/core/testing/testing_internal';
import {expect} from '@angular/platform-browser/testing/matchers';
import {AnimationEntryAst, AnimationGroupAst, AnimationKeyframeAst, AnimationSequenceAst, AnimationStepAst, AnimationStylesAst} from '../../src/animation/animation_ast';
import {AnimationParser} from '../../src/animation/animation_parser';
import {CompileMetadataResolver} from '../../src/metadata_resolver';
import {ElementSchemaRegistry} from '../../src/schema/element_schema_registry';
export function main() {
describe('parseAnimationEntry', () => {
const combineStyles = (styles: AnimationStylesAst): {[key: string]: string | number} => {
const flatStyles: {[key: string]: string | number} = {};
styles.styles.forEach(
entry => Object.keys(entry).forEach(prop => { flatStyles[prop] = entry[prop]; }));
return flatStyles;
};
const collectKeyframeStyles =
(keyframe: AnimationKeyframeAst): {[key: string]: string | number} =>
combineStyles(keyframe.styles);
const collectStepStyles = (step: AnimationStepAst): {[key: string]: string | number}[] => {
const keyframes = step.keyframes;
const styles: {[key: string]: string | number}[] = [];
if (step.startingStyles.styles.length > 0) {
styles.push(combineStyles(step.startingStyles));
}
keyframes.forEach(keyframe => styles.push(collectKeyframeStyles(keyframe)));
return styles;
};
let resolver: CompileMetadataResolver;
let schema: ElementSchemaRegistry;
beforeEach(inject(
[CompileMetadataResolver, ElementSchemaRegistry],
(res: CompileMetadataResolver, sch: ElementSchemaRegistry) => {
resolver = res;
schema = sch;
}));
const parseAnimation = (data: AnimationMetadata[]) => {
const entry = trigger('myAnimation', [transition('state1 => state2', sequence(data))]);
const compiledAnimationEntry = resolver.getAnimationEntryMetadata(entry);
const parser = new AnimationParser(schema);
return parser.parseEntry(compiledAnimationEntry);
};
const getAnimationAstFromEntryAst =
(ast: AnimationEntryAst) => { return ast.stateTransitions[0].animation; };
const parseAnimationAst = (data: AnimationMetadata[]) =>
getAnimationAstFromEntryAst(parseAnimation(data).ast);
const parseAnimationAndGetErrors = (data: AnimationMetadata[]) => parseAnimation(data).errors;
it('should merge repeated style steps into a single style ast step entry', () => {
const ast = parseAnimationAst([
style({'color': 'black'}), style({'background': 'red'}), style({'opacity': '0'}),
animate(1000, style({'color': 'white', 'background': 'black', 'opacity': '1'}))
]);
expect(ast.steps.length).toEqual(1);
const step = <AnimationStepAst>ast.steps[0];
expect(step.startingStyles.styles[0])
.toEqual({'color': 'black', 'background': 'red', 'opacity': '0'});
expect(step.keyframes[0].styles.styles[0])
.toEqual({'color': 'black', 'background': 'red', 'opacity': '0'});
expect(step.keyframes[1].styles.styles[0])
.toEqual({'color': 'white', 'background': 'black', 'opacity': '1'});
});
it('should animate only the styles requested within an animation step', () => {
const ast = parseAnimationAst([
style({'color': 'black', 'background': 'blue'}),
animate(1000, style({'background': 'orange'}))
]);
expect(ast.steps.length).toEqual(1);
const animateStep = <AnimationStepAst>ast.steps[0];
const fromKeyframe = animateStep.keyframes[0].styles.styles[0];
const toKeyframe = animateStep.keyframes[1].styles.styles[0];
expect(fromKeyframe).toEqual({'background': 'blue'});
expect(toKeyframe).toEqual({'background': 'orange'});
});
it('should populate the starting and duration times propertly', () => {
const ast = parseAnimationAst([
style({'color': 'black', 'opacity': '1'}),
animate(1000, style({'color': 'red'})),
animate(4000, style({'color': 'yellow'})),
sequence(
[animate(1000, style({'color': 'blue'})), animate(1000, style({'color': 'grey'}))]),
group([animate(500, style({'color': 'pink'})), animate(1000, style({'opacity': '0.5'}))]),
animate(300, style({'color': 'black'})),
]);
expect(ast.steps.length).toEqual(5);
const step1 = <AnimationStepAst>ast.steps[0];
expect(step1.playTime).toEqual(1000);
expect(step1.startTime).toEqual(0);
const step2 = <AnimationStepAst>ast.steps[1];
expect(step2.playTime).toEqual(4000);
expect(step2.startTime).toEqual(1000);
const seq = <AnimationSequenceAst>ast.steps[2];
expect(seq.playTime).toEqual(2000);
expect(seq.startTime).toEqual(5000);
const step4 = <AnimationStepAst>seq.steps[0];
expect(step4.playTime).toEqual(1000);
expect(step4.startTime).toEqual(5000);
const step5 = <AnimationStepAst>seq.steps[1];
expect(step5.playTime).toEqual(1000);
expect(step5.startTime).toEqual(6000);
const grp = <AnimationGroupAst>ast.steps[3];
expect(grp.playTime).toEqual(1000);
expect(grp.startTime).toEqual(7000);
const step6 = <AnimationStepAst>grp.steps[0];
expect(step6.playTime).toEqual(500);
expect(step6.startTime).toEqual(7000);
const step7 = <AnimationStepAst>grp.steps[1];
expect(step7.playTime).toEqual(1000);
expect(step7.startTime).toEqual(7000);
const step8 = <AnimationStepAst>ast.steps[4];
expect(step8.playTime).toEqual(300);
expect(step8.startTime).toEqual(8000);
});
it('should apply the correct animate() styles when parallel animations are active and use the same properties',
() => {
const details = parseAnimation([
style({'opacity': '0', 'color': 'red'}), group([
sequence([
animate(2000, style({'color': 'black'})),
animate(2000, style({'opacity': '0.5'})),
]),
sequence([
animate(2000, style({'opacity': '0.8'})),
animate(2000, style({'color': 'blue'}))
])
])
]);
const errors = details.errors;
expect(errors.length).toEqual(0);
const ast = <AnimationSequenceAst>getAnimationAstFromEntryAst(details.ast);
const g1 = <AnimationGroupAst>ast.steps[1];
const sq1 = <AnimationSequenceAst>g1.steps[0];
const sq2 = <AnimationSequenceAst>g1.steps[1];
const sq1a1 = <AnimationStepAst>sq1.steps[0];
expect(collectStepStyles(sq1a1)).toEqual([{'color': 'red'}, {'color': 'black'}]);
const sq1a2 = <AnimationStepAst>sq1.steps[1];
expect(collectStepStyles(sq1a2)).toEqual([{'opacity': '0.8'}, {'opacity': '0.5'}]);
const sq2a1 = <AnimationStepAst>sq2.steps[0];
expect(collectStepStyles(sq2a1)).toEqual([{'opacity': '0'}, {'opacity': '0.8'}]);
const sq2a2 = <AnimationStepAst>sq2.steps[1];
expect(collectStepStyles(sq2a2)).toEqual([{'color': 'black'}, {'color': 'blue'}]);
});
it('should throw errors when animations animate a CSS property at the same time', () => {
const animation1 = parseAnimation([
style({'opacity': '0'}),
group([animate(1000, style({'opacity': '1'})), animate(2000, style({'opacity': '0.5'}))])
]);
const errors1 = animation1.errors;
expect(errors1.length).toEqual(1);
expect(errors1[0].msg)
.toContainError(
'The animated CSS property "opacity" unexpectedly changes between steps "0ms" and "2000ms" at "1000ms"');
const animation2 = parseAnimation([
style({'color': 'red'}),
group(
[animate(5000, style({'color': 'blue'})), animate(2500, style({'color': 'black'}))])
]);
const errors2 = animation2.errors;
expect(errors2.length).toEqual(1);
expect(errors2[0].msg)
.toContainError(
'The animated CSS property "color" unexpectedly changes between steps "0ms" and "5000ms" at "2500ms"');
});
it('should return an error when an animation style contains an invalid timing value', () => {
const errors = parseAnimationAndGetErrors(
[style({'opacity': '0'}), animate('one second', style({'opacity': '1'}))]);
expect(errors[0].msg).toContainError(`The provided timing value "one second" is invalid.`);
});
it('should collect and return any errors collected when parsing the metadata', () => {
const errors = parseAnimationAndGetErrors([
style({'opacity': '0'}), animate('one second', style({'opacity': '1'})),
style({'opacity': '0'}), animate('one second', null), style({'background': 'red'})
]);
expect(errors.length).toBeGreaterThan(1);
});
it('should normalize a series of keyframe styles into a list of offset steps', () => {
const ast =
parseAnimationAst([animate(1000, keyframes([
style({'width': '0'}), style({'width': '25px'}),
style({'width': '50px'}), style({'width': '75px'})
]))]);
const step = <AnimationStepAst>ast.steps[0];
expect(step.keyframes.length).toEqual(4);
expect(step.keyframes[0].offset).toEqual(0);
expect(step.keyframes[1].offset).toMatch(/^0\.33/);
expect(step.keyframes[2].offset).toMatch(/^0\.66/);
expect(step.keyframes[3].offset).toEqual(1);
});
it('should use an existing collection of offset steps if provided', () => {
const ast = parseAnimationAst([animate(
1000, keyframes([
style({'height': '0', 'offset': 0}), style({'height': '25px', 'offset': 0.6}),
style({'height': '50px', 'offset': 0.7}), style({'height': '75px', 'offset': 1})
]))]);
const step = <AnimationStepAst>ast.steps[0];
expect(step.keyframes.length).toEqual(4);
expect(step.keyframes[0].offset).toEqual(0);
expect(step.keyframes[1].offset).toEqual(0.6);
expect(step.keyframes[2].offset).toEqual(0.7);
expect(step.keyframes[3].offset).toEqual(1);
});
it('should sort the provided collection of steps that contain offsets', () => {
const ast = parseAnimationAst([animate(
1000, keyframes([
style({'opacity': '0', 'offset': 0.9}), style({'opacity': '0.25', 'offset': 0}),
style({'opacity': '0.50', 'offset': 1}),
style({'opacity': '0.75', 'offset': 0.91})
]))]);
const step = <AnimationStepAst>ast.steps[0];
expect(step.keyframes.length).toEqual(4);
expect(step.keyframes[0].offset).toEqual(0);
expect(step.keyframes[0].styles.styles[0]['opacity']).toEqual('0.25');
expect(step.keyframes[1].offset).toEqual(0.9);
expect(step.keyframes[1].styles.styles[0]['opacity']).toEqual('0');
expect(step.keyframes[2].offset).toEqual(0.91);
expect(step.keyframes[2].styles.styles[0]['opacity']).toEqual('0.75');
expect(step.keyframes[3].offset).toEqual(1);
expect(step.keyframes[3].styles.styles[0]['opacity']).toEqual('0.50');
});
it('should throw an error if a partial amount of keyframes contain an offset', () => {
const errors = parseAnimationAndGetErrors(
[animate(1000, keyframes([
style({'z-index': 0, 'offset': 0}), style({'z-index': 1}),
style({'z-index': 2, 'offset': 1})
]))]);
expect(errors.length).toEqual(1);
const error = errors[0];
expect(error.msg).toMatch(/Not all style\(\) entries contain an offset/);
});
it('should use an existing style used earlier in the animation sequence if not defined in the first keyframe',
() => {
const ast = parseAnimationAst([animate(
1000,
keyframes(
[style({'color': 'red'}), style({'background': 'blue', 'color': 'white'})]))]);
const keyframesStep = <AnimationStepAst>ast.steps[0];
const kf1 = keyframesStep.keyframes[0];
const kf2 = keyframesStep.keyframes[1];
expect(flattenStyles(kf1.styles.styles))
.toEqual({'color': 'red', 'background': FILL_STYLE_FLAG});
});
it('should copy over any missing styles to the final keyframe if not already defined', () => {
const ast = parseAnimationAst([animate(
1000, keyframes([
style({'color': 'white', 'borderColor': 'white'}),
style({'color': 'red', 'background': 'blue'}), style({'background': 'blue'})
]))]);
const keyframesStep = <AnimationStepAst>ast.steps[0];
const kf1 = keyframesStep.keyframes[0];
const kf2 = keyframesStep.keyframes[1];
const kf3 = keyframesStep.keyframes[2];
expect(flattenStyles(kf3.styles.styles))
.toEqual({'background': 'blue', 'color': 'red', 'borderColor': 'white'});
});
it('should create an initial keyframe if not detected and place all keyframes styles there',
() => {
const ast = parseAnimationAst([animate(
1000, keyframes([
style({'color': 'white', 'background': 'black', 'offset': 0.5}),
style(
{'color': 'orange', 'background': 'red', 'fontSize': '100px', 'offset': 1})
]))]);
const keyframesStep = <AnimationStepAst>ast.steps[0];
expect(keyframesStep.keyframes.length).toEqual(3);
const kf1 = keyframesStep.keyframes[0];
const kf2 = keyframesStep.keyframes[1];
const kf3 = keyframesStep.keyframes[2];
expect(kf1.offset).toEqual(0);
expect(flattenStyles(kf1.styles.styles)).toEqual({
'fontSize': FILL_STYLE_FLAG,
'background': FILL_STYLE_FLAG,
'color': FILL_STYLE_FLAG
});
});
it('should create an destination keyframe if not detected and place all keyframes styles there',
() => {
const ast = parseAnimationAst([animate(1000, keyframes([
style({
'color': 'white',
'background': 'black',
'transform': 'rotate(360deg)',
'offset': 0
}),
style({
'color': 'orange',
'background': 'red',
'fontSize': '100px',
'offset': 0.5
})
]))]);
const keyframesStep = <AnimationStepAst>ast.steps[0];
expect(keyframesStep.keyframes.length).toEqual(3);
const kf1 = keyframesStep.keyframes[0];
const kf2 = keyframesStep.keyframes[1];
const kf3 = keyframesStep.keyframes[2];
expect(kf3.offset).toEqual(1);
expect(flattenStyles(kf3.styles.styles)).toEqual({
'color': 'orange',
'background': 'red',
'transform': 'rotate(360deg)',
'fontSize': '100px'
});
});
describe('easing / duration / delay', () => {
it('should parse simple string-based values', () => {
const ast = parseAnimationAst([animate('1s .5s ease-out', style({'opacity': '1'}))]);
const step = <AnimationStepAst>ast.steps[0];
expect(step.duration).toEqual(1000);
expect(step.delay).toEqual(500);
expect(step.easing).toEqual('ease-out');
});
it('should parse a numeric duration value', () => {
const ast = parseAnimationAst([animate(666, style({'opacity': '1'}))]);
const step = <AnimationStepAst>ast.steps[0];
expect(step.duration).toEqual(666);
expect(step.delay).toEqual(0);
expect(step.easing).toBeFalsy();
});
it('should parse an easing value without a delay', () => {
const ast = parseAnimationAst([animate('5s linear', style({'opacity': '1'}))]);
const step = <AnimationStepAst>ast.steps[0];
expect(step.duration).toEqual(5000);
expect(step.delay).toEqual(0);
expect(step.easing).toEqual('linear');
});
it('should parse a complex easing value', () => {
const ast =
parseAnimationAst([animate('30ms cubic-bezier(0, 0,0, .69)', style({'opacity': '1'}))]);
const step = <AnimationStepAst>ast.steps[0];
expect(step.duration).toEqual(30);
expect(step.delay).toEqual(0);
expect(step.easing).toEqual('cubic-bezier(0, 0,0, .69)');
});
});
});
}

View File

@ -6,7 +6,7 @@
* found in the LICENSE file at https://angular.io/license
*/
import {DirectiveResolver} from '@angular/compiler';
import {AnimationEntryMetadata, Compiler, Component, Directive, Injectable, Injector, Provider, Type, resolveForwardRef, ɵViewMetadata as ViewMetadata} from '@angular/core';
import {Compiler, Component, Directive, Injectable, Injector, Provider, Type, resolveForwardRef, ɵViewMetadata as ViewMetadata} from '@angular/core';
import {isPresent} from './facade/lang';
@ -22,7 +22,6 @@ export class MockDirectiveResolver extends DirectiveResolver {
private _viewProviderOverrides = new Map<Type<any>, any[]>();
private _views = new Map<Type<any>, ViewMetadata>();
private _inlineTemplates = new Map<Type<any>, string>();
private _animations = new Map<Type<any>, AnimationEntryMetadata[]>();
constructor(private _injector: Injector) { super(); }
@ -63,11 +62,6 @@ export class MockDirectiveResolver extends DirectiveResolver {
let animations = view.animations;
let templateUrl = view.templateUrl;
const inlineAnimations = this._animations.get(type);
if (isPresent(inlineAnimations)) {
animations = inlineAnimations;
}
let inlineTemplate = this._inlineTemplates.get(type);
if (isPresent(inlineTemplate)) {
templateUrl = null;
@ -140,11 +134,6 @@ export class MockDirectiveResolver extends DirectiveResolver {
this._inlineTemplates.set(component, template);
this._clearCacheFor(component);
}
setAnimations(component: Type<any>, animations: AnimationEntryMetadata[]): void {
this._animations.set(component, animations);
this._clearCacheFor(component);
}
}
function flattenArray(tree: any[], out: Array<Type<any>|any[]>): void {

View File

@ -38,8 +38,14 @@ export {AnimationKeyframe} from './animation/animation_keyframe';
export {Sanitizer, SecurityContext} from './security';
export * from './codegen_private_exports';
// TODO (matsko|tbosch): comment-out the two lines below, and enable the 3rd line when the view
// engine goes live!
export {AnimationTransitionEvent} from './animation/animation_transition_event';
export * from './animation/metadata';
// export * from './animation_next/animation_metadata_wrapped';
export * from './animation_next/animation_metadata_wrapped';
// For backwards compatibility.
/**
* @deprecated
*/
export type AnimationEntryMetadata = any;
/**
* @deprecated
*/
export type AnimationStateTransitionMetadata = any;

View File

@ -1379,40 +1379,6 @@ function declareTests({useJit, viewEngine}: {useJit: boolean, viewEngine: boolea
}
}));
}
// TODO(tbosch): delete these tests once view engine is the default as we handle
// these errors via source maps!
if (!viewEngine) {
it('should specify a location of an error that happened during change detection (text)',
() => {
TestBed.configureTestingModule({declarations: [MyComp]});
const template = '<div>{{a.b}}</div>';
TestBed.overrideComponent(MyComp, {set: {template}});
const fixture = TestBed.createComponent(MyComp);
expect(() => fixture.detectChanges()).toThrowError(/:0:5/);
});
it('should specify a location of an error that happened during change detection (element property)',
() => {
TestBed.configureTestingModule({declarations: [MyComp]});
const template = '<div [title]="a.b"></div>';
TestBed.overrideComponent(MyComp, {set: {template}});
const fixture = TestBed.createComponent(MyComp);
expect(() => fixture.detectChanges()).toThrowError(/:0:5/);
});
it('should specify a location of an error that happened during change detection (directive property)',
() => {
TestBed.configureTestingModule({declarations: [MyComp, ChildComp, MyDir]});
const template = '<child-cmp [dirProp]="a.b"></child-cmp>';
TestBed.overrideComponent(MyComp, {set: {template}});
const fixture = TestBed.createComponent(MyComp);
expect(() => fixture.detectChanges()).toThrowError(/:0:11/);
});
}
});
it('should support imperative views', () => {

View File

@ -1,421 +0,0 @@
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
import {AUTO_STYLE, AnimationTransitionEvent, Component, Injector, ViewChild, animate, state, style, transition, trigger} from '@angular/core';
import {DebugDomRootRenderer} from '@angular/core/src/debug/debug_renderer';
import {ElementRef} from '@angular/core/src/linker/element_ref';
import {RootRenderer} from '@angular/core/src/render/api';
import {TestBed, fakeAsync, flushMicrotasks} from '@angular/core/testing';
import {MockAnimationPlayer} from '@angular/core/testing/testing_internal';
import {AnimationDriver} from '@angular/platform-browser/src/dom/animation_driver';
import {getDOM} from '@angular/platform-browser/src/dom/dom_adapter';
import {DomRootRenderer, DomRootRenderer_} from '@angular/platform-browser/src/dom/dom_renderer';
import {BrowserTestingModule} from '@angular/platform-browser/testing';
import {expect} from '@angular/platform-browser/testing/matchers';
import {MockAnimationDriver} from '@angular/platform-browser/testing/mock_animation_driver';
import {ClientMessageBrokerFactory, ClientMessageBrokerFactory_} from '@angular/platform-webworker/src/web_workers/shared/client_message_broker';
import {RenderStore} from '@angular/platform-webworker/src/web_workers/shared/render_store';
import {Serializer} from '@angular/platform-webworker/src/web_workers/shared/serializer';
import {ServiceMessageBrokerFactory_} from '@angular/platform-webworker/src/web_workers/shared/service_message_broker';
import {MessageBasedRenderer} from '@angular/platform-webworker/src/web_workers/ui/renderer';
import {WebWorkerRootRenderer} from '@angular/platform-webworker/src/web_workers/worker/renderer';
import {platformBrowserDynamicTesting} from '../../../../platform-browser-dynamic/testing';
import {PairedMessageBuses, createPairedMessageBuses} from '../shared/web_worker_test_util';
export function main() {
function createWebWorkerBrokerFactory(
messageBuses: PairedMessageBuses, workerSerializer: Serializer, uiSerializer: Serializer,
domRootRenderer: DomRootRenderer, uiRenderStore: RenderStore): ClientMessageBrokerFactory {
const uiMessageBus = messageBuses.ui;
const workerMessageBus = messageBuses.worker;
// set up the worker side
const webWorkerBrokerFactory =
new ClientMessageBrokerFactory_(workerMessageBus, workerSerializer);
// set up the ui side
const uiMessageBrokerFactory = new ServiceMessageBrokerFactory_(uiMessageBus, uiSerializer);
const renderer = new MessageBasedRenderer(
uiMessageBrokerFactory, uiMessageBus, uiSerializer, uiRenderStore, domRootRenderer);
renderer.start();
return webWorkerBrokerFactory;
}
function createWorkerRenderer(
workerSerializer: Serializer, uiSerializer: Serializer, domRootRenderer: DomRootRenderer,
uiRenderStore: RenderStore, workerRenderStore: RenderStore): RootRenderer {
const messageBuses = createPairedMessageBuses();
const brokerFactory = createWebWorkerBrokerFactory(
messageBuses, workerSerializer, uiSerializer, domRootRenderer, uiRenderStore);
const workerRootRenderer = new WebWorkerRootRenderer(
brokerFactory, messageBuses.worker, workerSerializer, workerRenderStore);
return new DebugDomRootRenderer(workerRootRenderer);
}
describe('Web Worker Renderer Animations', () => {
// Don't run on server...
if (!getDOM().supportsDOMEvents()) return;
let uiTestBed: TestBed;
let uiRenderStore: RenderStore;
let workerRenderStore: RenderStore;
beforeEach(() => {
uiRenderStore = new RenderStore();
uiTestBed = new TestBed();
uiTestBed.platform = platformBrowserDynamicTesting();
uiTestBed.ngModule = BrowserTestingModule;
uiTestBed.configureTestingModule({
providers: [
{provide: AnimationDriver, useClass: MockAnimationDriver}, Serializer,
{provide: RenderStore, useValue: uiRenderStore},
{provide: DomRootRenderer, useClass: DomRootRenderer_},
{provide: RootRenderer, useExisting: DomRootRenderer}
]
});
const uiSerializer = uiTestBed.get(Serializer);
const domRootRenderer = uiTestBed.get(DomRootRenderer);
workerRenderStore = new RenderStore();
TestBed.configureTestingModule({
declarations: [AnimationCmp, MultiAnimationCmp, ContainerAnimationCmp],
providers: [
Serializer, {provide: RenderStore, useValue: workerRenderStore}, {
provide: RootRenderer,
useFactory: (workerSerializer: Serializer) => {
return createWorkerRenderer(
workerSerializer, uiSerializer, domRootRenderer, uiRenderStore,
workerRenderStore);
},
deps: [Serializer]
}
]
});
});
let uiDriver: MockAnimationDriver;
beforeEach(() => { uiDriver = uiTestBed.get(AnimationDriver) as MockAnimationDriver; });
function retrieveFinalAnimationStepStyles(keyframes: any[]) { return keyframes[1][1]; }
it('should trigger an animation and animate styles', fakeAsync(() => {
const fixture = TestBed.createComponent(AnimationCmp);
const cmp = fixture.componentInstance;
cmp.state = 'on';
fixture.detectChanges();
flushMicrotasks();
const step1 = uiDriver.log.shift();
const step2 = uiDriver.log.shift();
const step1Styles = retrieveFinalAnimationStepStyles(step1['keyframeLookup']);
const step2Styles = retrieveFinalAnimationStepStyles(step2['keyframeLookup']);
expect(step1Styles).toEqual({fontSize: '20px'});
expect(step2Styles).toEqual({opacity: '1', fontSize: '50px'});
cmp.state = 'off';
fixture.detectChanges();
flushMicrotasks();
const step3 = uiDriver.log.shift();
const step3Styles = retrieveFinalAnimationStepStyles(step3['keyframeLookup']);
expect(step3Styles).toEqual({opacity: '0', fontSize: AUTO_STYLE});
}));
it('should fire the onStart callback when the animation starts', fakeAsync(() => {
const fixture = TestBed.createComponent(AnimationCmp);
const cmp = fixture.componentInstance;
let capturedEvent: AnimationTransitionEvent = null;
cmp.stateStartFn = event => { capturedEvent = event; };
cmp.state = 'on';
expect(capturedEvent).toBe(null);
fixture.detectChanges();
flushMicrotasks();
expect(capturedEvent instanceof AnimationTransitionEvent).toBe(true);
expect(capturedEvent.toState).toBe('on');
}));
it('should fire the onDone callback when the animation ends', fakeAsync(() => {
const fixture = TestBed.createComponent(AnimationCmp);
const cmp = fixture.componentInstance;
let capturedEvent: AnimationTransitionEvent = null;
cmp.stateDoneFn = event => { capturedEvent = event; };
cmp.state = 'off';
expect(capturedEvent).toBe(null);
fixture.detectChanges();
flushMicrotasks();
expect(capturedEvent).toBe(null);
const step = uiDriver.log.shift();
step['player'].finish();
expect(capturedEvent instanceof AnimationTransitionEvent).toBe(true);
expect(capturedEvent.toState).toBe('off');
}));
it('should handle multiple animations on the same element that contain refs to .start and .done callbacks',
fakeAsync(() => {
const fixture = TestBed.createComponent(MultiAnimationCmp);
const cmp = fixture.componentInstance;
let log: {[triggerName: string]: AnimationTransitionEvent[]} = {};
cmp.callback = (triggerName: string, event: AnimationTransitionEvent) => {
log[triggerName] = log[triggerName] || [];
log[triggerName].push(event);
};
cmp.oneTriggerState = 'a';
cmp.twoTriggerState = 'c';
fixture.detectChanges();
flushMicrotasks();
// clear any animation logs that were collected when
// the component was rendered (void => *)
log = {};
cmp.oneTriggerState = 'b';
cmp.twoTriggerState = 'd';
fixture.detectChanges();
flushMicrotasks();
uiDriver.log.shift()['player'].finish();
const [triggerOneStart, triggerOneDone] = log['one'];
expect(triggerOneStart.triggerName).toEqual('one');
expect(triggerOneStart.fromState).toEqual('a');
expect(triggerOneStart.toState).toEqual('b');
expect(triggerOneStart.totalTime).toEqual(500);
expect(triggerOneStart.phaseName).toEqual('start');
expect(triggerOneStart.element instanceof ElementRef).toEqual(true);
expect(triggerOneDone.triggerName).toEqual('one');
expect(triggerOneDone.fromState).toEqual('a');
expect(triggerOneDone.toState).toEqual('b');
expect(triggerOneDone.totalTime).toEqual(500);
expect(triggerOneDone.phaseName).toEqual('done');
expect(triggerOneDone.element instanceof ElementRef).toEqual(true);
uiDriver.log.shift()['player'].finish();
const [triggerTwoStart, triggerTwoDone] = log['two'];
expect(triggerTwoStart.triggerName).toEqual('two');
expect(triggerTwoStart.fromState).toEqual('c');
expect(triggerTwoStart.toState).toEqual('d');
expect(triggerTwoStart.totalTime).toEqual(1000);
expect(triggerTwoStart.phaseName).toEqual('start');
expect(triggerTwoStart.element instanceof ElementRef).toEqual(true);
expect(triggerTwoDone.triggerName).toEqual('two');
expect(triggerTwoDone.fromState).toEqual('c');
expect(triggerTwoDone.toState).toEqual('d');
expect(triggerTwoDone.totalTime).toEqual(1000);
expect(triggerTwoDone.phaseName).toEqual('done');
expect(triggerTwoDone.element instanceof ElementRef).toEqual(true);
}));
it('should handle .start and .done callbacks for mutliple elements that contain animations that are fired at the same time',
fakeAsync(() => {
function logFactory(
log: {[phaseName: string]: AnimationTransitionEvent},
phaseName: string): (event: AnimationTransitionEvent) => any {
return (event: AnimationTransitionEvent) => log[phaseName] = event;
}
const fixture = TestBed.createComponent(ContainerAnimationCmp);
const cmp1 = fixture.componentInstance.compOne;
const cmp2 = fixture.componentInstance.compTwo;
const cmp1Log: {[phaseName: string]: AnimationTransitionEvent} = {};
const cmp2Log: {[phaseName: string]: AnimationTransitionEvent} = {};
cmp1.stateStartFn = logFactory(cmp1Log, 'start');
cmp1.stateDoneFn = logFactory(cmp1Log, 'done');
cmp2.stateStartFn = logFactory(cmp2Log, 'start');
cmp2.stateDoneFn = logFactory(cmp2Log, 'done');
cmp1.state = 'off';
cmp2.state = 'on';
fixture.detectChanges();
flushMicrotasks();
uiDriver.log.shift()['player'].finish();
const start1 = cmp1Log['start'];
expect(start1.triggerName).toEqual('myTrigger');
expect(start1.fromState).toEqual('void');
expect(start1.toState).toEqual('off');
expect(start1.totalTime).toEqual(500);
expect(start1.phaseName).toEqual('start');
expect(start1.element instanceof ElementRef).toBe(true);
const done1 = cmp1Log['done'];
expect(done1.triggerName).toEqual('myTrigger');
expect(done1.fromState).toEqual('void');
expect(done1.toState).toEqual('off');
expect(done1.totalTime).toEqual(500);
expect(done1.phaseName).toEqual('done');
expect(done1.element instanceof ElementRef).toBe(true);
// the * => on transition has two steps
uiDriver.log.shift()['player'].finish();
uiDriver.log.shift()['player'].finish();
const start2 = cmp2Log['start'];
expect(start2.triggerName).toEqual('myTrigger');
expect(start2.fromState).toEqual('void');
expect(start2.toState).toEqual('on');
expect(start2.totalTime).toEqual(1000);
expect(start2.phaseName).toEqual('start');
expect(start2.element instanceof ElementRef).toBe(true);
const done2 = cmp2Log['done'];
expect(done2.triggerName).toEqual('myTrigger');
expect(done2.fromState).toEqual('void');
expect(done2.toState).toEqual('on');
expect(done2.totalTime).toEqual(1000);
expect(done2.phaseName).toEqual('done');
expect(done2.element instanceof ElementRef).toBe(true);
}));
it('should destroy the player when the animation is complete', fakeAsync(() => {
const fixture = TestBed.createComponent(AnimationCmp);
const cmp = fixture.componentInstance;
cmp.state = 'off';
fixture.detectChanges();
const player = <MockAnimationPlayer>uiDriver.log.shift()['player'];
expect(player.log.indexOf('destroy') >= 0).toBe(false);
cmp.state = 'on';
fixture.detectChanges();
flushMicrotasks();
expect(player.log.indexOf('destroy') >= 0).toBe(true);
}));
it('should properly transition to the next animation if the current one is cancelled',
fakeAsync(() => {
const fixture = TestBed.createComponent(AnimationCmp);
const cmp = fixture.componentInstance;
cmp.state = 'on';
fixture.detectChanges();
flushMicrotasks();
let player = <MockAnimationPlayer>uiDriver.log.shift()['player'];
player.finish();
player = <MockAnimationPlayer>uiDriver.log.shift()['player'];
player.setPosition(0.5);
uiDriver.log = [];
cmp.state = 'off';
fixture.detectChanges();
flushMicrotasks();
const step = uiDriver.log.shift();
expect(step['previousStyles']).toEqual({opacity: AUTO_STYLE, fontSize: AUTO_STYLE});
}));
});
}
@Component({
selector: 'container-comp',
template: `
<my-comp #one></my-comp>
<my-comp #two></my-comp>
`
})
class ContainerAnimationCmp {
@ViewChild('one') public compOne: AnimationCmp;
@ViewChild('two') public compTwo: AnimationCmp;
}
@Component({
selector: 'my-comp',
template: `
<div *ngIf="state"
#ref
[@myTrigger]="state"
(@myTrigger.start)="stateStartFn($event)"
(@myTrigger.done)="stateDoneFn($event)">...</div>
`,
animations: [trigger(
'myTrigger',
[
state('void, off', style({opacity: '0'})),
state('on', style({opacity: '1', fontSize: '50px'})),
transition('* => on', [animate(500, style({fontSize: '20px'})), animate(500)]),
transition('* => off', [animate(500)])
])]
})
class AnimationCmp {
state = 'off';
stateStartFn = (event: AnimationTransitionEvent): any => {};
stateDoneFn = (event: AnimationTransitionEvent): any => {};
@ViewChild('ref') public elmRef: ElementRef;
}
@Component({
selector: 'my-multi-comp',
template: `
<div [@one]="oneTriggerState"
(@one.start)="callback('one', $event)"
(@one.done)="callback('one', $event)" #one>...</div>
<div [@two]="twoTriggerState"
(@two.start)="callback('two', $event)"
(@two.done)="callback('two', $event)" #two>...</div>
`,
animations: [
trigger(
'one',
[
state('a', style({width: '0px'})), state('b', style({width: '100px'})),
transition('a => b', animate(500))
]),
trigger(
'two',
[
state('c', style({height: '0px'})), state('d', style({height: '100px'})),
transition('c => d', animate(1000))
])
]
})
class MultiAnimationCmp {
oneTriggerState: string;
twoTriggerState: string;
@ViewChild('one') public elmRef1: ElementRef;
@ViewChild('two') public elmRef2: ElementRef;
callback = (triggerName: string, event: AnimationTransitionEvent): any => {};
}

View File

@ -9,7 +9,8 @@
import {verifyNoBrowserErrors} from 'e2e_util/e2e_util';
import {browser, by, element, protractor} from 'protractor';
describe('WebWorkers Animations', function() {
// TODO(matsko): make this test work again with new view engine.
xdescribe('WebWorkers Animations', function() {
afterEach(() => {
verifyNoBrowserErrors();
browser.ignoreSynchronization = false;

View File

@ -21,27 +21,21 @@ export declare abstract class AfterViewInit {
/** @experimental */
export declare const ANALYZE_FOR_ENTRY_COMPONENTS: InjectionToken<any>;
/** @experimental */
export declare function animate(timing: string | number, styles?: AnimationStyleMetadata | AnimationKeyframesSequenceMetadata): AnimationAnimateMetadata;
/** @deprecated */
export declare function animate(timings: string | number, styles?: AnimationStyleMetadata | AnimationKeyframesSequenceMetadata): AnimationAnimateMetadata;
/** @experimental */
export declare class AnimationAnimateMetadata extends AnimationMetadata {
/** @deprecated */
export interface AnimationAnimateMetadata extends AnimationMetadata {
styles: AnimationStyleMetadata | AnimationKeyframesSequenceMetadata;
timings: string | number;
constructor(timings: string | number, styles: AnimationStyleMetadata | AnimationKeyframesSequenceMetadata);
timings: string | number | AnimateTimings;
}
/** @experimental */
export declare class AnimationEntryMetadata {
definitions: AnimationStateMetadata[];
name: string;
constructor(name: string, definitions: AnimationStateMetadata[]);
}
/** @deprecated */
export declare type AnimationEntryMetadata = any;
/** @experimental */
export declare class AnimationGroupMetadata extends AnimationWithStepsMetadata {
readonly steps: AnimationMetadata[];
constructor(_steps: AnimationMetadata[]);
/** @deprecated */
export interface AnimationGroupMetadata extends AnimationMetadata {
steps: AnimationMetadata[];
}
/** @experimental */
@ -51,14 +45,14 @@ export declare class AnimationKeyframe {
constructor(offset: number, styles: AnimationStyles);
}
/** @experimental */
export declare class AnimationKeyframesSequenceMetadata extends AnimationMetadata {
/** @deprecated */
export interface AnimationKeyframesSequenceMetadata extends AnimationMetadata {
steps: AnimationStyleMetadata[];
constructor(steps: AnimationStyleMetadata[]);
}
/** @experimental */
export declare abstract class AnimationMetadata {
/** @deprecated */
export interface AnimationMetadata {
type: AnimationMetadataType;
}
/** @experimental */
@ -79,39 +73,26 @@ export declare abstract class AnimationPlayer {
abstract setPosition(p: any): void;
}
/** @experimental */
export declare class AnimationSequenceMetadata extends AnimationWithStepsMetadata {
readonly steps: AnimationMetadata[];
constructor(_steps: AnimationMetadata[]);
/** @deprecated */
export interface AnimationSequenceMetadata extends AnimationMetadata {
steps: AnimationMetadata[];
}
/** @experimental */
export declare class AnimationStateDeclarationMetadata extends AnimationStateMetadata {
stateNameExpr: string;
/** @deprecated */
export interface AnimationStateMetadata extends AnimationMetadata {
name: string;
styles: AnimationStyleMetadata;
constructor(stateNameExpr: string, styles: AnimationStyleMetadata);
}
/** @experimental */
export declare abstract class AnimationStateMetadata {
}
/** @deprecated */
export declare type AnimationStateTransitionMetadata = any;
/** @experimental */
export declare class AnimationStateTransitionMetadata extends AnimationStateMetadata {
stateChangeExpr: string | ((fromState: string, toState: string) => boolean);
steps: AnimationMetadata;
constructor(stateChangeExpr: string | ((fromState: string, toState: string) => boolean), steps: AnimationMetadata);
}
/** @experimental */
export declare class AnimationStyleMetadata extends AnimationMetadata {
/** @deprecated */
export interface AnimationStyleMetadata extends AnimationMetadata {
offset: number;
styles: Array<string | {
styles: {
[key: string]: string | number;
}>;
constructor(styles: Array<string | {
[key: string]: string | number;
}>, offset?: number);
}[];
}
/** @experimental */
@ -124,28 +105,26 @@ export declare class AnimationStyles {
}[]);
}
/** @experimental */
export declare class AnimationTransitionEvent {
element: ElementRef;
/** @deprecated */
export interface AnimationTransitionEvent {
element: any;
fromState: string;
phaseName: string;
toState: string;
totalTime: number;
triggerName: string;
constructor({fromState, toState, totalTime, phaseName, element, triggerName}: {
fromState: string;
toState: string;
totalTime: number;
phaseName: string;
element: any;
triggerName: string;
});
}
/** @experimental */
export declare abstract class AnimationWithStepsMetadata extends AnimationMetadata {
readonly steps: AnimationMetadata[];
constructor();
/** @deprecated */
export interface AnimationTransitionMetadata extends AnimationMetadata {
animation: AnimationMetadata;
expr: string | ((fromState: string, toState: string) => boolean);
}
/** @deprecated */
export interface AnimationTriggerMetadata {
definitions: AnimationMetadata[];
name: string;
}
/** @experimental */
@ -189,7 +168,7 @@ export declare function assertPlatform(requiredToken: any): PlatformRef;
/** @stable */
export declare const Attribute: AttributeDecorator;
/** @experimental */
/** @deprecated */
export declare const AUTO_STYLE = "*";
/** @stable */
@ -477,7 +456,7 @@ export interface GetTestability {
findTestabilityInTree(registry: TestabilityRegistry, elem: any, findInAncestors: boolean): Testability;
}
/** @experimental */
/** @deprecated */
export declare function group(steps: AnimationMetadata[]): AnimationGroupMetadata;
/** @stable */
@ -573,7 +552,7 @@ export declare class IterableDiffers {
static extend(factories: IterableDifferFactory[]): Provider;
}
/** @experimental */
/** @deprecated */
export declare function keyframes(steps: AnimationStyleMetadata[]): AnimationKeyframesSequenceMetadata;
/** @stable */
@ -938,7 +917,7 @@ export interface SelfDecorator {
new (): Self;
}
/** @experimental */
/** @deprecated */
export declare function sequence(steps: AnimationMetadata[]): AnimationSequenceMetadata;
/** @experimental */
@ -967,13 +946,13 @@ export interface SkipSelfDecorator {
new (): SkipSelf;
}
/** @experimental */
export declare function state(stateNameExpr: string, styles: AnimationStyleMetadata): AnimationStateDeclarationMetadata;
/** @deprecated */
export declare function state(name: string, styles: AnimationStyleMetadata): AnimationStateMetadata;
/** @experimental */
export declare function style(tokens: string | {
/** @deprecated */
export declare function style(tokens: {
[key: string]: string | number;
} | Array<string | {
} | Array<{
[key: string]: string | number;
}>): AnimationStyleMetadata;
@ -1027,8 +1006,8 @@ export interface TrackByFunction<T> {
(index: number, item: T): any;
}
/** @experimental */
export declare function transition(stateChangeExpr: string | ((fromState: string, toState: string) => boolean), steps: AnimationMetadata | AnimationMetadata[]): AnimationStateTransitionMetadata;
/** @deprecated */
export declare function transition(stateChangeExpr: string | ((fromState: string, toState: string) => boolean), steps: AnimationMetadata | AnimationMetadata[]): AnimationTransitionMetadata;
/** @experimental */
export declare const TRANSLATIONS: InjectionToken<string>;
@ -1036,8 +1015,8 @@ export declare const TRANSLATIONS: InjectionToken<string>;
/** @experimental */
export declare const TRANSLATIONS_FORMAT: InjectionToken<string>;
/** @experimental */
export declare function trigger(name: string, animation: AnimationMetadata[]): AnimationEntryMetadata;
/** @deprecated */
export declare function trigger(name: string, definitions: AnimationMetadata[]): AnimationTriggerMetadata;
/** @stable */
export declare const Type: FunctionConstructor;