build: reformat repo to new clang@1.4.0 (#36613)

PR Close #36613
This commit is contained in:
Joey Perrott
2020-04-13 16:40:21 -07:00
committed by atscott
parent 5e80e7e216
commit 698b0288be
1160 changed files with 31667 additions and 24000 deletions

View File

@ -22,7 +22,7 @@ export class Animation {
const errors: any[] = [];
const ast = buildAnimationAst(_driver, input, errors);
if (errors.length) {
const errorMessage = `animation validation failed:\n${errors.join("\n")}`;
const errorMessage = `animation validation failed:\n${errors.join('\n')}`;
throw new Error(errorMessage);
}
this._animationAst = ast;
@ -42,7 +42,7 @@ export class Animation {
this._driver, element, this._animationAst, ENTER_CLASSNAME, LEAVE_CLASSNAME, start, dest,
options, subInstructions, errors);
if (errors.length) {
const errorMessage = `animation building failed:\n${errors.join("\n")}`;
const errorMessage = `animation building failed:\n${errors.join('\n')}`;
throw new Error(errorMessage);
}
return result;

View File

@ -74,7 +74,9 @@ export interface StyleAst extends Ast<AnimationMetadataType.Style> {
isEmptyStep?: boolean;
}
export interface KeyframesAst extends Ast<AnimationMetadataType.Keyframes> { styles: StyleAst[]; }
export interface KeyframesAst extends Ast<AnimationMetadataType.Keyframes> {
styles: StyleAst[];
}
export interface ReferenceAst extends Ast<AnimationMetadataType.Reference> {
animation: Ast<AnimationMetadataType>;

View File

@ -5,11 +5,11 @@
* 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, AnimateTimings, AnimationAnimateChildMetadata, AnimationAnimateMetadata, AnimationAnimateRefMetadata, AnimationGroupMetadata, AnimationKeyframesSequenceMetadata, AnimationMetadata, AnimationMetadataType, AnimationOptions, AnimationQueryMetadata, AnimationQueryOptions, AnimationReferenceMetadata, AnimationSequenceMetadata, AnimationStaggerMetadata, AnimationStateMetadata, AnimationStyleMetadata, AnimationTransitionMetadata, AnimationTriggerMetadata, style, ɵStyleData} from '@angular/animations';
import {AnimateTimings, AnimationAnimateChildMetadata, AnimationAnimateMetadata, AnimationAnimateRefMetadata, AnimationGroupMetadata, AnimationKeyframesSequenceMetadata, AnimationMetadata, AnimationMetadataType, AnimationOptions, AnimationQueryMetadata, AnimationQueryOptions, AnimationReferenceMetadata, AnimationSequenceMetadata, AnimationStaggerMetadata, AnimationStateMetadata, AnimationStyleMetadata, AnimationTransitionMetadata, AnimationTriggerMetadata, AUTO_STYLE, style, ɵStyleData} from '@angular/animations';
import {AnimationDriver} from '../render/animation_driver';
import {getOrSetAsInMap} from '../render/shared';
import {ENTER_SELECTOR, LEAVE_SELECTOR, NG_ANIMATING_SELECTOR, NG_TRIGGER_SELECTOR, SUBSTITUTION_EXPR_START, copyObj, extractStyleParams, iteratorToArray, normalizeAnimationEntry, resolveTiming, validateStyleParams, visitDslNode} from '../util';
import {copyObj, ENTER_SELECTOR, extractStyleParams, iteratorToArray, LEAVE_SELECTOR, NG_ANIMATING_SELECTOR, NG_TRIGGER_SELECTOR, normalizeAnimationEntry, resolveTiming, SUBSTITUTION_EXPR_START, validateStyleParams, visitDslNode} from '../util';
import {AnimateAst, AnimateChildAst, AnimateRefAst, Ast, DynamicTimingAst, GroupAst, KeyframesAst, QueryAst, ReferenceAst, SequenceAst, StaggerAst, StateAst, StyleAst, TimingAst, TransitionAst, TriggerAst} from './animation_ast';
import {AnimationDslVisitor} from './animation_dsl_visitor';
@ -55,7 +55,7 @@ const SELF_TOKEN_REGEX = new RegExp(`\s*${SELF_TOKEN}\s*,?`, 'g');
* Otherwise an error will be thrown.
*/
export function buildAnimationAst(
driver: AnimationDriver, metadata: AnimationMetadata | AnimationMetadata[],
driver: AnimationDriver, metadata: AnimationMetadata|AnimationMetadata[],
errors: any[]): Ast<AnimationMetadataType> {
return new AnimationAstBuilderVisitor(driver).build(metadata, errors);
}
@ -114,7 +114,11 @@ export class AnimationAstBuilderVisitor implements AnimationDslVisitor {
return {
type: AnimationMetadataType.Trigger,
name: metadata.name, states, transitions, queryCount, depCount,
name: metadata.name,
states,
transitions,
queryCount,
depCount,
options: null
};
}
@ -139,8 +143,10 @@ export class AnimationAstBuilderVisitor implements AnimationDslVisitor {
});
if (missingSubs.size) {
const missingSubsArr = iteratorToArray(missingSubs.values());
context.errors.push(
`state("${metadata.name}", ...) must define default values for all the following style substitutions: ${missingSubsArr.join(', ')}`);
context.errors.push(`state("${
metadata
.name}", ...) must define default values for all the following style substitutions: ${
missingSubsArr.join(', ')}`);
}
}
@ -210,7 +216,7 @@ export class AnimationAstBuilderVisitor implements AnimationDslVisitor {
let isEmpty = false;
if (!styleMetadata) {
isEmpty = true;
const newStyleData: {[prop: string]: string | number} = {};
const newStyleData: {[prop: string]: string|number} = {};
if (timingAst.easing) {
newStyleData['easing'] = timingAst.easing;
}
@ -239,9 +245,9 @@ export class AnimationAstBuilderVisitor implements AnimationDslVisitor {
private _makeStyleAst(metadata: AnimationStyleMetadata, context: AnimationAstBuilderContext):
StyleAst {
const styles: (ɵStyleData | string)[] = [];
const styles: (ɵStyleData|string)[] = [];
if (Array.isArray(metadata.styles)) {
(metadata.styles as(ɵStyleData | string)[]).forEach(styleTuple => {
(metadata.styles as (ɵStyleData | string)[]).forEach(styleTuple => {
if (typeof styleTuple == 'string') {
if (styleTuple == AUTO_STYLE) {
styles.push(styleTuple);
@ -282,7 +288,8 @@ export class AnimationAstBuilderVisitor implements AnimationDslVisitor {
type: AnimationMetadataType.Style,
styles,
easing: collectedEasing,
offset: metadata.offset, containsDynamicStyles,
offset: metadata.offset,
containsDynamicStyles,
options: null
};
}
@ -300,19 +307,22 @@ export class AnimationAstBuilderVisitor implements AnimationDslVisitor {
Object.keys(tuple).forEach(prop => {
if (!this._driver.validateStyleProperty(prop)) {
context.errors.push(
`The provided animation property "${prop}" is not a supported CSS property for animations`);
context.errors.push(`The provided animation property "${
prop}" is not a supported CSS property for animations`);
return;
}
const collectedStyles = context.collectedStyles[context.currentQuerySelector !];
const collectedStyles = context.collectedStyles[context.currentQuerySelector!];
const collectedEntry = collectedStyles[prop];
let updateCollectedStyle = true;
if (collectedEntry) {
if (startTime != endTime && startTime >= collectedEntry.startTime &&
endTime <= collectedEntry.endTime) {
context.errors.push(
`The CSS property "${prop}" that exists between the times of "${collectedEntry.startTime}ms" and "${collectedEntry.endTime}ms" is also being animated in a parallel animation between the times of "${startTime}ms" and "${endTime}ms"`);
context.errors.push(`The CSS property "${prop}" that exists between the times of "${
collectedEntry.startTime}ms" and "${
collectedEntry
.endTime}ms" is also being animated in a parallel animation between the times of "${
startTime}ms" and "${endTime}ms"`);
updateCollectedStyle = false;
}
@ -383,7 +393,7 @@ export class AnimationAstBuilderVisitor implements AnimationDslVisitor {
const limit = length - 1;
const currentTime = context.currentTime;
const currentAnimateTimings = context.currentAnimateTimings !;
const currentAnimateTimings = context.currentAnimateTimings!;
const animateDuration = currentAnimateTimings.duration;
keyframes.forEach((kf, i) => {
const offset = generatedOffset > 0 ? (i == limit ? 1 : (generatedOffset * i)) : offsets[i];
@ -427,7 +437,7 @@ export class AnimationAstBuilderVisitor implements AnimationDslVisitor {
}
visitQuery(metadata: AnimationQueryMetadata, context: AnimationAstBuilderContext): QueryAst {
const parentSelector = context.currentQuerySelector !;
const parentSelector = context.currentQuerySelector!;
const options = (metadata.options || {}) as AnimationQueryOptions;
context.queryCount++;
@ -445,7 +455,9 @@ export class AnimationAstBuilderVisitor implements AnimationDslVisitor {
type: AnimationMetadataType.Query,
selector,
limit: options.limit || 0,
optional: !!options.optional, includeSelf, animation,
optional: !!options.optional,
includeSelf,
animation,
originalSelector: metadata.selector,
options: normalizeAnimationOptions(metadata.options)
};
@ -462,7 +474,8 @@ export class AnimationAstBuilderVisitor implements AnimationDslVisitor {
return {
type: AnimationMetadataType.Stagger,
animation: visitDslNode(this, normalizeAnimationEntry(metadata.animation), context), timings,
animation: visitDslNode(this, normalizeAnimationEntry(metadata.animation), context),
timings,
options: null
};
}
@ -483,7 +496,7 @@ function normalizeSelector(selector: string): [string, boolean] {
}
function normalizeParams(obj: {[key: string]: any} | any): {[key: string]: any}|null {
function normalizeParams(obj: {[key: string]: any}|any): {[key: string]: any}|null {
return obj ? copyObj(obj) : null;
}
@ -504,7 +517,7 @@ export class AnimationAstBuilderContext {
constructor(public errors: any[]) {}
}
function consumeOffset(styles: ɵStyleData | string | (ɵStyleData | string)[]): number|null {
function consumeOffset(styles: ɵStyleData|string|(ɵStyleData | string)[]): number|null {
if (typeof styles == 'string') return null;
let offset: number|null = null;
@ -529,7 +542,7 @@ function isObject(value: any): boolean {
return !Array.isArray(value) && typeof value == 'object';
}
function constructTimingAst(value: string | number | AnimateTimings, errors: any[]) {
function constructTimingAst(value: string|number|AnimateTimings, errors: any[]) {
let timings: AnimateTimings|null = null;
if (value.hasOwnProperty('duration')) {
timings = value as AnimateTimings;
@ -551,11 +564,11 @@ function constructTimingAst(value: string | number | AnimateTimings, errors: any
return makeTimingAst(timings.duration, timings.delay, timings.easing);
}
function normalizeAnimationOptions(options: AnimationOptions | null): AnimationOptions {
function normalizeAnimationOptions(options: AnimationOptions|null): AnimationOptions {
if (options) {
options = copyObj(options);
if (options['params']) {
options['params'] = normalizeParams(options['params']) !;
options['params'] = normalizeParams(options['params'])!;
}
} else {
options = {};
@ -563,6 +576,6 @@ function normalizeAnimationOptions(options: AnimationOptions | null): AnimationO
return options;
}
function makeTimingAst(duration: number, delay: number, easing: string | null): TimingAst {
function makeTimingAst(duration: number, delay: number, easing: string|null): TimingAst {
return {duration, delay, easing};
}

View File

@ -5,7 +5,7 @@
* 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, AnimateChildOptions, AnimateTimings, AnimationMetadataType, AnimationOptions, AnimationQueryOptions, ɵPRE_STYLE as PRE_STYLE, ɵStyleData} from '@angular/animations';
import {AnimateChildOptions, AnimateTimings, AnimationMetadataType, AnimationOptions, AnimationQueryOptions, AUTO_STYLE, ɵPRE_STYLE as PRE_STYLE, ɵStyleData} from '@angular/animations';
import {AnimationDriver} from '../render/animation_driver';
import {copyObj, copyStyles, interpolateParams, iteratorToArray, resolveTiming, resolveTimingValue, visitDslNode} from '../util';
@ -301,7 +301,7 @@ export class AnimationTimelineBuilderVisitor implements AstVisitor {
visitStyle(ast: StyleAst, context: AnimationTimelineContext) {
const timeline = context.currentTimeline;
const timings = context.currentAnimateTimings !;
const timings = context.currentAnimateTimings!;
// this is a special case for when a style() call
// directly follows an animate() call (but not inside of an animate() call)
@ -320,8 +320,8 @@ export class AnimationTimelineBuilderVisitor implements AstVisitor {
}
visitKeyframes(ast: KeyframesAst, context: AnimationTimelineContext) {
const currentAnimateTimings = context.currentAnimateTimings !;
const startTime = (context.currentTimeline !).duration;
const currentAnimateTimings = context.currentAnimateTimings!;
const startTime = (context.currentTimeline!).duration;
const duration = currentAnimateTimings.duration;
const innerContext = context.createSubContext();
const innerTimeline = innerContext.currentTimeline;
@ -351,8 +351,9 @@ export class AnimationTimelineBuilderVisitor implements AstVisitor {
const options = (ast.options || {}) as AnimationQueryOptions;
const delay = options.delay ? resolveTimingValue(options.delay) : 0;
if (delay && (context.previousNode.type === AnimationMetadataType.Style ||
(startTime == 0 && context.currentTimeline.getCurrentStyleProperties().length))) {
if (delay &&
(context.previousNode.type === AnimationMetadataType.Style ||
(startTime == 0 && context.currentTimeline.getCurrentStyleProperties().length))) {
context.currentTimeline.snapshotCurrentStyles();
context.previousNode = DEFAULT_NOOP_PREVIOUS_NODE;
}
@ -365,7 +366,6 @@ export class AnimationTimelineBuilderVisitor implements AstVisitor {
context.currentQueryTotal = elms.length;
let sameElementTimeline: TimelineBuilder|null = null;
elms.forEach((element, i) => {
context.currentQueryIndex = i;
const innerContext = context.createSubContext(ast.options, element);
if (delay) {
@ -400,7 +400,7 @@ export class AnimationTimelineBuilderVisitor implements AstVisitor {
}
visitStagger(ast: StaggerAst, context: AnimationTimelineContext) {
const parentContext = context.parentContext !;
const parentContext = context.parentContext!;
const tl = context.currentTimeline;
const timings = ast.timings;
const duration = Math.abs(timings.duration);
@ -460,7 +460,9 @@ export class AnimationTimelineContext {
timelines.push(this.currentTimeline);
}
get params() { return this.options.params; }
get params() {
return this.options.params;
}
updateOptions(options: AnimationOptions|null, skipIfExists?: boolean) {
if (!options) return;
@ -479,7 +481,7 @@ export class AnimationTimelineContext {
const newParams = newOptions.params;
if (newParams) {
let paramsToUpdate: {[name: string]: any} = optionsToUpdate.params !;
let paramsToUpdate: {[name: string]: any} = optionsToUpdate.params!;
if (!paramsToUpdate) {
paramsToUpdate = this.options.params = {};
}
@ -498,7 +500,9 @@ export class AnimationTimelineContext {
const oldParams = this.options.params;
if (oldParams) {
const params: {[name: string]: any} = options['params'] = {};
Object.keys(oldParams).forEach(name => { params[name] = oldParams[name]; });
Object.keys(oldParams).forEach(name => {
params[name] = oldParams[name];
});
}
}
return options;
@ -576,8 +580,8 @@ export class AnimationTimelineContext {
}
if (!optional && results.length == 0) {
errors.push(
`\`query("${originalSelector}")\` returned zero elements. (Use \`query("${originalSelector}", { optional: true })\` if you wish to allow this.)`);
errors.push(`\`query("${originalSelector}")\` returned zero elements. (Use \`query("${
originalSelector}", { optional: true })\` if you wish to allow this.)`);
}
return results;
}
@ -587,7 +591,7 @@ export class AnimationTimelineContext {
export class TimelineBuilder {
public duration: number = 0;
// TODO(issue/24571): remove '!'.
public easing !: string | null;
public easing!: string|null;
private _previousKeyframe: ɵStyleData = {};
private _currentKeyframe: ɵStyleData = {};
private _keyframes = new Map<number, ɵStyleData>();
@ -606,7 +610,7 @@ export class TimelineBuilder {
}
this._localTimelineStyles = Object.create(this._backFill, {});
this._globalTimelineStyles = this._elementTimelineStylesLookup.get(element) !;
this._globalTimelineStyles = this._elementTimelineStylesLookup.get(element)!;
if (!this._globalTimelineStyles) {
this._globalTimelineStyles = this._localTimelineStyles;
this._elementTimelineStylesLookup.set(element, this._localTimelineStyles);
@ -625,9 +629,13 @@ export class TimelineBuilder {
}
}
getCurrentStyleProperties(): string[] { return Object.keys(this._currentKeyframe); }
getCurrentStyleProperties(): string[] {
return Object.keys(this._currentKeyframe);
}
get currentTime() { return this.startTime + this.duration; }
get currentTime() {
return this.startTime + this.duration;
}
delayNextStep(delay: number) {
// in the event that a style() step is placed right before a stagger()
@ -656,7 +664,7 @@ export class TimelineBuilder {
if (this._currentKeyframe) {
this._previousKeyframe = this._currentKeyframe;
}
this._currentKeyframe = this._keyframes.get(this.duration) !;
this._currentKeyframe = this._keyframes.get(this.duration)!;
if (!this._currentKeyframe) {
this._currentKeyframe = Object.create(this._backFill, {});
this._keyframes.set(this.duration, this._currentKeyframe);
@ -680,7 +688,9 @@ export class TimelineBuilder {
this._styleSummary[prop] = {time: this.currentTime, value};
}
allowOnlyTimelineStyles() { return this._currentEmptyStepKeyframe !== this._currentKeyframe; }
allowOnlyTimelineStyles() {
return this._currentEmptyStepKeyframe !== this._currentKeyframe;
}
applyEmptyStep(easing: string|null) {
if (easing) {
@ -748,7 +758,9 @@ export class TimelineBuilder {
});
}
getFinalKeyframe() { return this._keyframes.get(this.duration); }
getFinalKeyframe() {
return this._keyframes.get(this.duration);
}
get properties() {
const properties: string[] = [];
@ -820,7 +832,9 @@ class SubTimelineBuilder extends TimelineBuilder {
this.timings = {duration: timings.duration, delay: timings.delay, easing: timings.easing};
}
containsAnimation(): boolean { return this.keyframes.length > 1; }
containsAnimation(): boolean {
return this.keyframes.length > 1;
}
buildKeyframes(): AnimationTimelineInstruction {
let keyframes = this.keyframes;
@ -883,13 +897,15 @@ function roundOffset(offset: number, decimalPoints = 3): number {
return Math.round(offset * mult) / mult;
}
function flattenStyles(input: (ɵStyleData | string)[], allStyles: ɵStyleData) {
function flattenStyles(input: (ɵStyleData|string)[], allStyles: ɵStyleData) {
const styles: ɵStyleData = {};
let allProperties: string[];
input.forEach(token => {
if (token === '*') {
allProperties = allProperties || Object.keys(allStyles);
allProperties.forEach(prop => { styles[prop] = AUTO_STYLE; });
allProperties.forEach(prop => {
styles[prop] = AUTO_STYLE;
});
} else {
copyStyles(token as ɵStyleData, false, styles);
}

View File

@ -23,7 +23,7 @@ export interface AnimationTimelineInstruction extends AnimationEngineInstruction
export function createTimelineInstruction(
element: any, keyframes: ɵStyleData[], preStyleProps: string[], postStyleProps: string[],
duration: number, delay: number, easing: string | null = null,
duration: number, delay: number, easing: string|null = null,
subTimeline: boolean = false): AnimationTimelineInstruction {
return {
type: AnimationTransitionInstructionType.TimelineAnimation,
@ -33,6 +33,8 @@ export function createTimelineInstruction(
postStyleProps,
duration,
delay,
totalTime: duration + delay, easing, subTimeline
totalTime: duration + delay,
easing,
subTimeline
};
}

View File

@ -10,7 +10,7 @@ export declare type TransitionMatcherFn =
(fromState: any, toState: any, element: any, params: {[key: string]: any}) => boolean;
export function parseTransitionExpr(
transitionValue: string | TransitionMatcherFn, errors: string[]): TransitionMatcherFn[] {
transitionValue: string|TransitionMatcherFn, errors: string[]): TransitionMatcherFn[] {
const expressions: TransitionMatcherFn[] = [];
if (typeof transitionValue == 'string') {
transitionValue.split(/\s*,\s*/).forEach(

View File

@ -55,13 +55,16 @@ export class AnimationTransitionFactory {
const animationOptions = {params: {...transitionAnimationParams, ...nextAnimationParams}};
const timelines = skipAstBuild ? [] : buildAnimationTimelines(
driver, element, this.ast.animation, enterClassName,
leaveClassName, currentStateStyles, nextStateStyles,
animationOptions, subInstructions, errors);
const timelines = skipAstBuild ?
[] :
buildAnimationTimelines(
driver, element, this.ast.animation, enterClassName, leaveClassName, currentStateStyles,
nextStateStyles, animationOptions, subInstructions, errors);
let totalTime = 0;
timelines.forEach(tl => { totalTime = Math.max(tl.duration + tl.delay, totalTime); });
timelines.forEach(tl => {
totalTime = Math.max(tl.duration + tl.delay, totalTime);
});
if (errors.length) {
return createTransitionInstruction(

View File

@ -22,8 +22,8 @@ export function buildTrigger(name: string, ast: TriggerAst): AnimationTrigger {
}
/**
* @publicApi
*/
* @publicApi
*/
export class AnimationTrigger {
public transitionFactories: AnimationTransitionFactory[] = [];
public fallbackTransition: AnimationTransitionFactory;
@ -45,7 +45,9 @@ export class AnimationTrigger {
this.fallbackTransition = createFallbackTransition(name, this.states);
}
get containsQueries() { return this.ast.queryCount > 0; }
get containsQueries() {
return this.ast.queryCount > 0;
}
matchTransition(currentState: any, nextState: any, element: any, params: {[key: string]: any}):
AnimationTransitionFactory|null {

View File

@ -28,7 +28,11 @@ export class ElementInstructionMap {
existingInstructions.push(...instructions);
}
has(element: any): boolean { return this._map.has(element); }
has(element: any): boolean {
return this._map.has(element);
}
clear() { this._map.clear(); }
clear() {
this._map.clear();
}
}

View File

@ -20,7 +20,9 @@ export abstract class AnimationStyleNormalizer {
* @publicApi
*/
export class NoopAnimationStyleNormalizer {
normalizePropertyName(propertyName: string, errors: string[]): string { return propertyName; }
normalizePropertyName(propertyName: string, errors: string[]): string {
return propertyName;
}
normalizeStyleValue(
userProvidedProperty: string, normalizedProperty: string, value: string|number,

View File

@ -13,6 +13,6 @@ export {AnimationEngine as ɵAnimationEngine} from './render/animation_engine_ne
export {CssKeyframesDriver as ɵCssKeyframesDriver} from './render/css_keyframes/css_keyframes_driver';
export {CssKeyframesPlayer as ɵCssKeyframesPlayer} from './render/css_keyframes/css_keyframes_player';
export {containsElement as ɵcontainsElement, invokeQuery as ɵinvokeQuery, matchesElement as ɵmatchesElement, validateStyleProperty as ɵvalidateStyleProperty} from './render/shared';
export {WebAnimationsDriver as ɵWebAnimationsDriver, supportsWebAnimations as ɵsupportsWebAnimations} from './render/web_animations/web_animations_driver';
export {supportsWebAnimations as ɵsupportsWebAnimations, WebAnimationsDriver as ɵWebAnimationsDriver} from './render/web_animations/web_animations_driver';
export {WebAnimationsPlayer as ɵWebAnimationsPlayer} from './render/web_animations/web_animations_player';
export {allowPreviousPlayerStylesMerge as ɵallowPreviousPlayerStylesMerge} from './util';

View File

@ -15,13 +15,17 @@ import {containsElement, invokeQuery, matchesElement, validateStyleProperty} fro
*/
@Injectable()
export class NoopAnimationDriver implements AnimationDriver {
validateStyleProperty(prop: string): boolean { return validateStyleProperty(prop); }
validateStyleProperty(prop: string): boolean {
return validateStyleProperty(prop);
}
matchesElement(element: any, selector: string): boolean {
return matchesElement(element, selector);
}
containsElement(elm1: any, elm2: any): boolean { return containsElement(elm1, elm2); }
containsElement(elm1: any, elm2: any): boolean {
return containsElement(elm1, elm2);
}
query(element: any, selector: string, multi: boolean): any[] {
return invokeQuery(element, selector, multi);
@ -32,7 +36,7 @@ export class NoopAnimationDriver implements AnimationDriver {
}
animate(
element: any, keyframes: {[key: string]: string | number}[], duration: number, delay: number,
element: any, keyframes: {[key: string]: string|number}[], duration: number, delay: number,
easing: string, previousPlayers: any[] = [],
scrubberAccessRequested?: boolean): AnimationPlayer {
return new NoopAnimationPlayer(duration, delay);
@ -56,6 +60,6 @@ export abstract class AnimationDriver {
abstract computeStyle(element: any, prop: string, defaultValue?: string): string;
abstract animate(
element: any, keyframes: {[key: string]: string | number}[], duration: number, delay: number,
element: any, keyframes: {[key: string]: string|number}[], duration: number, delay: number,
easing?: string|null, previousPlayers?: any[], scrubberAccessRequested?: boolean): any;
}

View File

@ -5,6 +5,11 @@
* 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
*/
export const enum AnimationTransitionInstructionType {TransitionAnimation, TimelineAnimation}
export const enum AnimationTransitionInstructionType {
TransitionAnimation,
TimelineAnimation
}
export interface AnimationEngineInstruction { type: AnimationTransitionInstructionType; }
export interface AnimationEngineInstruction {
type: AnimationTransitionInstructionType;
}

View File

@ -45,8 +45,8 @@ export class AnimationEngine {
const ast =
buildAnimationAst(this._driver, metadata as AnimationMetadata, errors) as TriggerAst;
if (errors.length) {
throw new Error(
`The animation trigger "${name}" has failed to build due to the following errors:\n - ${errors.join("\n - ")}`);
throw new Error(`The animation trigger "${
name}" has failed to build due to the following errors:\n - ${errors.join('\n - ')}`);
}
trigger = buildTrigger(name, ast);
this._triggerCache[cacheKey] = trigger;
@ -95,12 +95,16 @@ export class AnimationEngine {
return this._transitionEngine.listen(namespaceId, element, eventName, eventPhase, callback);
}
flush(microtaskId: number = -1): void { this._transitionEngine.flush(microtaskId); }
flush(microtaskId: number = -1): void {
this._transitionEngine.flush(microtaskId);
}
get players(): AnimationPlayer[] {
return (this._transitionEngine.players as AnimationPlayer[])
.concat(this._timelineEngine.players as AnimationPlayer[]);
}
whenRenderingDone(): Promise<any> { return this._transitionEngine.whenRenderingDone(); }
whenRenderingDone(): Promise<any> {
return this._transitionEngine.whenRenderingDone();
}
}

View File

@ -23,13 +23,17 @@ export class CssKeyframesDriver implements AnimationDriver {
private readonly _head: any = document.querySelector('head');
private _warningIssued = false;
validateStyleProperty(prop: string): boolean { return validateStyleProperty(prop); }
validateStyleProperty(prop: string): boolean {
return validateStyleProperty(prop);
}
matchesElement(element: any, selector: string): boolean {
return matchesElement(element, selector);
}
containsElement(elm1: any, elm2: any): boolean { return containsElement(elm1, elm2); }
containsElement(elm1: any, elm2: any): boolean {
return containsElement(elm1, elm2);
}
query(element: any, selector: string, multi: boolean): any[] {
return invokeQuery(element, selector, multi);
@ -104,7 +108,7 @@ export class CssKeyframesDriver implements AnimationDriver {
const animationName = `${KEYFRAMES_NAME_PREFIX}${this._count++}`;
const kfElm = this.buildKeyframeElement(element, animationName, keyframes);
document.querySelector('head') !.appendChild(kfElm);
document.querySelector('head')!.appendChild(kfElm);
const specialStyles = packageNonAnimatableStyles(element, keyframes);
const player = new CssKeyframesPlayer(
@ -124,8 +128,8 @@ export class CssKeyframesDriver implements AnimationDriver {
}
}
function flattenKeyframesIntoStyles(
keyframes: null | {[key: string]: any} | {[key: string]: any}[]): {[key: string]: any} {
function flattenKeyframesIntoStyles(keyframes: null|{[key: string]: any}|
{[key: string]: any}[]): {[key: string]: any} {
let flatKeyframes: {[key: string]: any} = {};
if (keyframes) {
const kfs = Array.isArray(keyframes) ? keyframes : [keyframes];

View File

@ -14,7 +14,12 @@ import {ElementAnimationStyleHandler} from './element_animation_style_handler';
const DEFAULT_FILL_MODE = 'forwards';
const DEFAULT_EASING = 'linear';
export const enum AnimatorControlState {INITIALIZED = 1, STARTED = 2, FINISHED = 3, DESTROYED = 4}
export const enum AnimatorControlState {
INITIALIZED = 1,
STARTED = 2,
FINISHED = 3,
DESTROYED = 4
}
export class CssKeyframesPlayer implements AnimationPlayer {
private _onDoneFns: Function[] = [];
@ -23,10 +28,10 @@ export class CssKeyframesPlayer implements AnimationPlayer {
private _started = false;
// TODO(issue/24571): remove '!'.
private _styler !: ElementAnimationStyleHandler;
private _styler!: ElementAnimationStyleHandler;
// TODO(issue/24571): remove '!'.
public parentPlayer !: AnimationPlayer;
public parentPlayer!: AnimationPlayer;
public readonly totalTime: number;
public readonly easing: string;
public currentSnapshot: {[key: string]: string} = {};
@ -34,7 +39,7 @@ export class CssKeyframesPlayer implements AnimationPlayer {
private _state: AnimatorControlState = 0;
constructor(
public readonly element: any, public readonly keyframes: {[key: string]: string | number}[],
public readonly element: any, public readonly keyframes: {[key: string]: string|number}[],
public readonly animationName: string, private readonly _duration: number,
private readonly _delay: number, easing: string,
private readonly _finalStyles: {[key: string]: any},
@ -44,11 +49,17 @@ export class CssKeyframesPlayer implements AnimationPlayer {
this._buildStyler();
}
onStart(fn: () => void): void { this._onStartFns.push(fn); }
onStart(fn: () => void): void {
this._onStartFns.push(fn);
}
onDone(fn: () => void): void { this._onDoneFns.push(fn); }
onDone(fn: () => void): void {
this._onDoneFns.push(fn);
}
onDestroy(fn: () => void): void { this._onDestroyFns.push(fn); }
onDestroy(fn: () => void): void {
this._onDestroyFns.push(fn);
}
destroy() {
this.init();
@ -86,11 +97,17 @@ export class CssKeyframesPlayer implements AnimationPlayer {
this._flushDoneFns();
}
setPosition(value: number) { this._styler.setPosition(value); }
setPosition(value: number) {
this._styler.setPosition(value);
}
getPosition(): number { return this._styler.getPosition(); }
getPosition(): number {
return this._styler.getPosition();
}
hasStarted(): boolean { return this._state >= AnimatorControlState.STARTED; }
hasStarted(): boolean {
return this._state >= AnimatorControlState.STARTED;
}
init(): void {
if (this._state >= AnimatorControlState.INITIALIZED) return;
this._state = AnimatorControlState.INITIALIZED;

View File

@ -22,7 +22,7 @@ export class DirectStylePlayer extends NoopAnimationPlayer {
if (this.__initialized || !this._startingStyles) return;
this.__initialized = true;
Object.keys(this._styles).forEach(prop => {
this._startingStyles ![prop] = this.element.style[prop];
this._startingStyles![prop] = this.element.style[prop];
});
super.init();
}
@ -38,7 +38,7 @@ export class DirectStylePlayer extends NoopAnimationPlayer {
destroy() {
if (!this._startingStyles) return;
Object.keys(this._startingStyles).forEach(prop => {
const value = this._startingStyles ![prop];
const value = this._startingStyles![prop];
if (value) {
this.element.style.setProperty(prop, value);
} else {

View File

@ -28,14 +28,19 @@ export class ElementAnimationStyleHandler {
apply() {
applyKeyframeAnimation(
this._element,
`${this._duration}ms ${this._easing} ${this._delay}ms 1 normal ${this._fillMode} ${this._name}`);
`${this._duration}ms ${this._easing} ${this._delay}ms 1 normal ${this._fillMode} ${
this._name}`);
addRemoveAnimationEvent(this._element, this._eventFn, false);
this._startTime = Date.now();
}
pause() { playPauseAnimation(this._element, this._name, 'paused'); }
pause() {
playPauseAnimation(this._element, this._name, 'paused');
}
resume() { playPauseAnimation(this._element, this._name, 'running'); }
resume() {
playPauseAnimation(this._element, this._name, 'running');
}
setPosition(position: number) {
const index = findIndexForAnimation(this._element, this._name);
@ -43,7 +48,9 @@ export class ElementAnimationStyleHandler {
setAnimationStyle(this._element, 'Delay', `-${this._position}ms`, index);
}
getPosition() { return this._position; }
getPosition() {
return this._position;
}
private _handleCallback(event: any) {
const timestamp = event._ngTestManualTimestamp || Date.now();
@ -70,7 +77,7 @@ export class ElementAnimationStyleHandler {
}
}
function playPauseAnimation(element: any, name: string, status: 'running' | 'paused') {
function playPauseAnimation(element: any, name: string, status: 'running'|'paused') {
const index = findIndexForAnimation(element, name);
setAnimationStyle(element, 'PlayState', status, index);
}

View File

@ -5,7 +5,7 @@
* 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, AnimationEvent, AnimationPlayer, NoopAnimationPlayer, ɵAnimationGroupPlayer, ɵPRE_STYLE as PRE_STYLE, ɵStyleData} from '@angular/animations';
import {AnimationEvent, AnimationPlayer, AUTO_STYLE, NoopAnimationPlayer, ɵAnimationGroupPlayer, ɵPRE_STYLE as PRE_STYLE, ɵStyleData} from '@angular/animations';
import {AnimationStyleNormalizer} from '../../src/dsl/style_normalization/animation_style_normalizer';
import {AnimationDriver} from '../../src/render/animation_driver';
@ -89,7 +89,7 @@ export function normalizeKeyframes(
}
export function listenOnPlayer(
player: AnimationPlayer, eventName: string, event: AnimationEvent | undefined,
player: AnimationPlayer, eventName: string, event: AnimationEvent|undefined,
callback: (event: any) => any) {
switch (eventName) {
case 'start':
@ -125,7 +125,7 @@ export function makeAnimationEvent(
}
export function getOrSetAsInMap(
map: Map<any, any>| {[key: string]: any}, key: any, defaultValue: any) {
map: Map<any, any>|{[key: string]: any}, key: any, defaultValue: any) {
let value: any;
if (map instanceof Map) {
value = map.get(key);
@ -161,7 +161,9 @@ let _query: (element: any, selector: string, multi: boolean) => any[] =
const _isNode = isNode();
if (_isNode || typeof Element !== 'undefined') {
// this is well supported in all browsers
_contains = (elm1: any, elm2: any) => { return elm1.contains(elm2) as boolean; };
_contains = (elm1: any, elm2: any) => {
return elm1.contains(elm2) as boolean;
};
_matches = (() => {
if (_isNode || Element.prototype.matches) {
@ -203,15 +205,15 @@ let _IS_WEBKIT = false;
export function validateStyleProperty(prop: string): boolean {
if (!_CACHED_BODY) {
_CACHED_BODY = getBodyNode() || {};
_IS_WEBKIT = _CACHED_BODY !.style ? ('WebkitAppearance' in _CACHED_BODY !.style) : false;
_IS_WEBKIT = _CACHED_BODY!.style ? ('WebkitAppearance' in _CACHED_BODY!.style) : false;
}
let result = true;
if (_CACHED_BODY !.style && !containsVendorPrefix(prop)) {
result = prop in _CACHED_BODY !.style;
if (_CACHED_BODY!.style && !containsVendorPrefix(prop)) {
result = prop in _CACHED_BODY!.style;
if (!result && _IS_WEBKIT) {
const camelProp = 'Webkit' + prop.charAt(0).toUpperCase() + prop.substr(1);
result = camelProp in _CACHED_BODY !.style;
result = camelProp in _CACHED_BODY!.style;
}
}

View File

@ -19,7 +19,7 @@ import {eraseStyles, setStyles} from '../util';
* @returns an instance of `SpecialCasedStyles` if any special styles are detected otherwise `null`
*/
export function packageNonAnimatableStyles(
element: any, styles: {[key: string]: any} | {[key: string]: any}[]): SpecialCasedStyles|null {
element: any, styles: {[key: string]: any}|{[key: string]: any}[]): SpecialCasedStyles|null {
let startStyles: {[key: string]: any}|null = null;
let endStyles: {[key: string]: any}|null = null;
if (Array.isArray(styles) && styles.length) {
@ -47,7 +47,7 @@ export class SpecialCasedStyles {
static initialStylesByElement = new WeakMap<any, {[key: string]: any}>();
private _state = SpecialCasedStylesState.Pending;
private _initialStyles !: {[key: string]: any};
private _initialStyles!: {[key: string]: any};
constructor(
private _element: any, private _startStyles: {[key: string]: any}|null,

View File

@ -5,7 +5,7 @@
* 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, AnimationMetadata, AnimationMetadataType, AnimationOptions, AnimationPlayer, ɵStyleData} from '@angular/animations';
import {AnimationMetadata, AnimationMetadataType, AnimationOptions, AnimationPlayer, AUTO_STYLE, ɵStyleData} from '@angular/animations';
import {Ast} from '../dsl/animation_ast';
import {buildAnimationAst} from '../dsl/animation_ast_builder';
@ -34,7 +34,7 @@ export class TimelineAnimationEngine {
const ast = buildAnimationAst(this._driver, metadata, errors);
if (errors.length) {
throw new Error(
`Unable to build the animation due to the following errors: ${errors.join("\n")}`);
`Unable to build the animation due to the following errors: ${errors.join('\n')}`);
} else {
this._animations[id] = ast;
}
@ -71,12 +71,13 @@ export class TimelineAnimationEngine {
if (errors.length) {
throw new Error(
`Unable to create the animation due to the following errors: ${errors.join("\n")}`);
`Unable to create the animation due to the following errors: ${errors.join('\n')}`);
}
autoStylesMap.forEach((styles, element) => {
Object.keys(styles).forEach(
prop => { styles[prop] = this._driver.computeStyle(element, prop, AUTO_STYLE); });
Object.keys(styles).forEach(prop => {
styles[prop] = this._driver.computeStyle(element, prop, AUTO_STYLE);
});
});
const players = instructions.map(i => {

View File

@ -5,7 +5,7 @@
* 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, AnimationOptions, AnimationPlayer, NoopAnimationPlayer, ɵAnimationGroupPlayer as AnimationGroupPlayer, ɵPRE_STYLE as PRE_STYLE, ɵStyleData} from '@angular/animations';
import {AnimationOptions, AnimationPlayer, AUTO_STYLE, NoopAnimationPlayer, ɵAnimationGroupPlayer as AnimationGroupPlayer, ɵPRE_STYLE as PRE_STYLE, ɵStyleData} from '@angular/animations';
import {AnimationTimelineInstruction} from '../dsl/animation_timeline_instruction';
import {AnimationTransitionFactory} from '../dsl/animation_transition_factory';
@ -13,7 +13,7 @@ import {AnimationTransitionInstruction} from '../dsl/animation_transition_instru
import {AnimationTrigger} from '../dsl/animation_trigger';
import {ElementInstructionMap} from '../dsl/element_instruction_map';
import {AnimationStyleNormalizer} from '../dsl/style_normalization/animation_style_normalizer';
import {ENTER_CLASSNAME, LEAVE_CLASSNAME, NG_ANIMATING_CLASSNAME, NG_ANIMATING_SELECTOR, NG_TRIGGER_CLASSNAME, NG_TRIGGER_SELECTOR, copyObj, eraseStyles, iteratorToArray, setStyles} from '../util';
import {copyObj, ENTER_CLASSNAME, eraseStyles, iteratorToArray, LEAVE_CLASSNAME, NG_ANIMATING_CLASSNAME, NG_ANIMATING_SELECTOR, NG_TRIGGER_CLASSNAME, NG_TRIGGER_SELECTOR, setStyles} from '../util';
import {AnimationDriver} from './animation_driver';
import {getOrSetAsInMap, listenOnPlayer, makeAnimationEvent, normalizeKeyframes, optimizeGroupPlayer} from './shared';
@ -71,7 +71,9 @@ export class StateValue {
public value: string;
public options: AnimationOptions;
get params(): {[key: string]: any} { return this.options.params as{[key: string]: any}; }
get params(): {[key: string]: any} {
return this.options.params as {[key: string]: any};
}
constructor(input: any, public namespaceId: string = '') {
const isObj = input && input.hasOwnProperty('value');
@ -92,7 +94,7 @@ export class StateValue {
absorbOptions(options: AnimationOptions) {
const newParams = options.params;
if (newParams) {
const oldParams = this.options.params !;
const oldParams = this.options.params!;
Object.keys(newParams).forEach(prop => {
if (oldParams[prop] == null) {
oldParams[prop] = newParams[prop];
@ -263,7 +265,9 @@ export class AnimationTransitionNamespace {
if (!isFallbackTransition) {
addClass(element, QUEUED_CLASSNAME);
player.onStart(() => { removeClass(element, QUEUED_CLASSNAME); });
player.onStart(() => {
removeClass(element, QUEUED_CLASSNAME);
});
}
player.onDone(() => {
@ -290,11 +294,14 @@ export class AnimationTransitionNamespace {
deregister(name: string) {
delete this._triggers[name];
this._engine.statesByElement.forEach((stateMap, element) => { delete stateMap[name]; });
this._engine.statesByElement.forEach((stateMap, element) => {
delete stateMap[name];
});
this._elementListeners.forEach((listeners, element) => {
this._elementListeners.set(
element, listeners.filter(entry => { return entry.name != name; }));
this._elementListeners.set(element, listeners.filter(entry => {
return entry.name != name;
}));
});
}
@ -372,7 +379,7 @@ export class AnimationTransitionNamespace {
const trigger = this._triggers[triggerName];
const transition = trigger.fallbackTransition;
const elementStates = this._engine.statesByElement.get(element) !;
const elementStates = this._engine.statesByElement.get(element)!;
const fromState = elementStates[triggerName] || DEFAULT_STATE_VALUE;
const toState = new StateValue(VOID_VALUE);
const player = new TransitionAnimationPlayer(this.id, triggerName, element);
@ -448,7 +455,9 @@ export class AnimationTransitionNamespace {
}
}
insertNode(element: any, parent: any): void { addClass(element, this._hostClassName); }
insertNode(element: any, parent: any): void {
addClass(element, this._hostClassName);
}
drainQueuedTransitions(microtaskId: number): QueueInstruction[] {
const instructions: QueueInstruction[] = [];
@ -538,7 +547,9 @@ export class TransitionAnimationEngine {
public onRemovalComplete = (element: any, context: any) => {};
/** @internal */
_onRemovalComplete(element: any, context: any) { this.onRemovalComplete(element, context); }
_onRemovalComplete(element: any, context: any) {
this.onRemovalComplete(element, context);
}
constructor(
public bodyNode: any, public driver: AnimationDriver,
@ -631,7 +642,9 @@ export class TransitionAnimationEngine {
this.afterFlushAnimationsDone(() => ns.destroy(context));
}
private _fetchNamespace(id: string) { return this._namespaceLookup[id]; }
private _fetchNamespace(id: string) {
return this._namespaceLookup[id];
}
fetchNamespacesByElement(element: any): Set<AnimationTransitionNamespace> {
// normally there should only be one namespace per element, however
@ -704,7 +717,9 @@ export class TransitionAnimationEngine {
}
}
collectEnterElement(element: any) { this.collectedEnterElements.push(element); }
collectEnterElement(element: any) {
this.collectedEnterElements.push(element);
}
markElementAsDisabled(element: any, value: boolean) {
if (value) {
@ -740,11 +755,8 @@ export class TransitionAnimationEngine {
markElementAsRemoved(namespaceId: string, element: any, hasAnimation?: boolean, context?: any) {
this.collectedLeaveElements.push(element);
element[REMOVAL_FLAG] = {
namespaceId,
setForRemoval: context, hasAnimation,
removedBeforeQueried: false
};
element[REMOVAL_FLAG] =
{namespaceId, setForRemoval: context, hasAnimation, removedBeforeQueried: false};
}
listen(
@ -876,7 +888,9 @@ export class TransitionAnimationEngine {
this._whenQuietFns = [];
if (players.length) {
optimizeGroupPlayer(players).onDone(() => { quietFns.forEach(fn => fn()); });
optimizeGroupPlayer(players).onDone(() => {
quietFns.forEach(fn => fn());
});
} else {
quietFns.forEach(fn => fn());
}
@ -950,16 +964,18 @@ export class TransitionAnimationEngine {
cleanupFns.push(() => {
enterNodeMap.forEach((nodes, root) => {
const className = enterNodeMapIds.get(root) !;
const className = enterNodeMapIds.get(root)!;
nodes.forEach(node => removeClass(node, className));
});
leaveNodeMap.forEach((nodes, root) => {
const className = leaveNodeMapIds.get(root) !;
const className = leaveNodeMapIds.get(root)!;
nodes.forEach(node => removeClass(node, className));
});
allLeaveNodes.forEach(element => { this.processLeaveNode(element); });
allLeaveNodes.forEach(element => {
this.processLeaveNode(element);
});
});
const allPlayers: TransitionAnimationPlayer[] = [];
@ -981,10 +997,10 @@ export class TransitionAnimationEngine {
}
const nodeIsOrphaned = !bodyNode || !this.driver.containsElement(bodyNode, element);
const leaveClassName = leaveNodeMapIds.get(element) !;
const enterClassName = enterNodeMapIds.get(element) !;
const leaveClassName = leaveNodeMapIds.get(element)!;
const enterClassName = enterNodeMapIds.get(element)!;
const instruction = this._buildInstruction(
entry, subTimelines, enterClassName, leaveClassName, nodeIsOrphaned) !;
entry, subTimelines, enterClassName, leaveClassName, nodeIsOrphaned)!;
if (instruction.errors && instruction.errors.length) {
erroneousTransitions.push(instruction);
return;
@ -1029,7 +1045,7 @@ export class TransitionAnimationEngine {
instruction.preStyleProps.forEach((stringMap, element) => {
const props = Object.keys(stringMap);
if (props.length) {
let setVal: Set<string> = allPreStyleElements.get(element) !;
let setVal: Set<string> = allPreStyleElements.get(element)!;
if (!setVal) {
allPreStyleElements.set(element, setVal = new Set<string>());
}
@ -1039,7 +1055,7 @@ export class TransitionAnimationEngine {
instruction.postStyleProps.forEach((stringMap, element) => {
const props = Object.keys(stringMap);
let setVal: Set<string> = allPostStyleElements.get(element) !;
let setVal: Set<string> = allPostStyleElements.get(element)!;
if (!setVal) {
allPostStyleElements.set(element, setVal = new Set<string>());
}
@ -1052,7 +1068,7 @@ export class TransitionAnimationEngine {
const errors: string[] = [];
erroneousTransitions.forEach(instruction => {
errors.push(`@${instruction.triggerName} has failed due to:\n`);
instruction.errors !.forEach(error => errors.push(`- ${error}\n`));
instruction.errors!.forEach(error => errors.push(`- ${error}\n`));
});
allPlayers.forEach(player => player.destroy());
@ -1116,7 +1132,7 @@ export class TransitionAnimationEngine {
replaceNodes.forEach(node => {
const post = postStylesMap.get(node);
const pre = preStylesMap.get(node);
postStylesMap.set(node, { ...post, ...pre } as any);
postStylesMap.set(node, {...post, ...pre} as any);
});
const rootPlayers: TransitionAnimationPlayer[] = [];
@ -1274,9 +1290,13 @@ export class TransitionAnimationEngine {
return this._fetchNamespace(namespaceId).elementContainsData(element) || containsData;
}
afterFlush(callback: () => any) { this._flushFns.push(callback); }
afterFlush(callback: () => any) {
this._flushFns.push(callback);
}
afterFlushAnimationsDone(callback: () => any) { this._whenQuietFns.push(callback); }
afterFlushAnimationsDone(callback: () => any) {
this._whenQuietFns.push(callback);
}
private _getPreviousPlayers(
element: string, isQueriedElement: boolean, namespaceId?: string, triggerName?: string,
@ -1413,8 +1433,9 @@ export class TransitionAnimationEngine {
// this basically makes all of the callbacks for sub element animations
// be dependent on the upper players for when they finish
allSubElements.forEach(
element => { getOrSetAsInMap(skippedPlayersMap, element, []).push(player); });
allSubElements.forEach(element => {
getOrSetAsInMap(skippedPlayersMap, element, []).push(player);
});
return player;
}
@ -1441,7 +1462,7 @@ export class TransitionAnimationPlayer implements AnimationPlayer {
private _queuedCallbacks: {[name: string]: (() => any)[]} = {};
public readonly destroyed = false;
// TODO(issue/24571): remove '!'.
public parentPlayer !: AnimationPlayer;
public parentPlayer!: AnimationPlayer;
public markedForDestroy: boolean = false;
public disabled = false;
@ -1462,17 +1483,21 @@ export class TransitionAnimationPlayer implements AnimationPlayer {
this._queuedCallbacks = {};
this._containsRealPlayer = true;
this.overrideTotalTime(player.totalTime);
(this as{queued: boolean}).queued = false;
(this as {queued: boolean}).queued = false;
}
getRealPlayer() { return this._player; }
getRealPlayer() {
return this._player;
}
overrideTotalTime(totalTime: number) { (this as any).totalTime = totalTime; }
overrideTotalTime(totalTime: number) {
(this as any).totalTime = totalTime;
}
syncPlayerEvents(player: AnimationPlayer) {
const p = this._player as any;
if (p.triggerCallback) {
player.onStart(() => p.triggerCallback !('start'));
player.onStart(() => p.triggerCallback!('start'));
}
player.onDone(() => this.finish());
player.onDestroy(() => this.destroy());
@ -1503,24 +1528,38 @@ export class TransitionAnimationPlayer implements AnimationPlayer {
this._player.onDestroy(fn);
}
init(): void { this._player.init(); }
init(): void {
this._player.init();
}
hasStarted(): boolean { return this.queued ? false : this._player.hasStarted(); }
hasStarted(): boolean {
return this.queued ? false : this._player.hasStarted();
}
play(): void { !this.queued && this._player.play(); }
play(): void {
!this.queued && this._player.play();
}
pause(): void { !this.queued && this._player.pause(); }
pause(): void {
!this.queued && this._player.pause();
}
restart(): void { !this.queued && this._player.restart(); }
restart(): void {
!this.queued && this._player.restart();
}
finish(): void { this._player.finish(); }
finish(): void {
this._player.finish();
}
destroy(): void {
(this as{destroyed: boolean}).destroyed = true;
(this as {destroyed: boolean}).destroyed = true;
this._player.destroy();
}
reset(): void { !this.queued && this._player.reset(); }
reset(): void {
!this.queued && this._player.reset();
}
setPosition(p: any): void {
if (!this.queued) {
@ -1528,7 +1567,9 @@ export class TransitionAnimationPlayer implements AnimationPlayer {
}
}
getPosition(): number { return this.queued ? 0 : this._player.getPosition(); }
getPosition(): number {
return this.queued ? 0 : this._player.getPosition();
}
/** @internal */
triggerCallback(phaseName: string): void {
@ -1539,7 +1580,7 @@ export class TransitionAnimationPlayer implements AnimationPlayer {
}
}
function deleteOrUnsetInMap(map: Map<any, any[]>| {[key: string]: any}, key: any, value: any) {
function deleteOrUnsetInMap(map: Map<any, any[]>|{[key: string]: any}, key: any, value: any) {
let currentValues: any[]|null|undefined;
if (map instanceof Map) {
currentValues = map.get(key);
@ -1661,7 +1702,7 @@ function buildRootMap(roots: any[], nodes: any[]): Map<any, any[]> {
nodes.forEach(node => {
const root = getRoot(node);
if (root !== NULL_NODE) {
rootMap.get(root) !.push(node);
rootMap.get(root)!.push(node);
}
});
@ -1742,7 +1783,7 @@ function replacePostStylesAsPre(
let preEntry = allPreStyleElements.get(element);
if (preEntry) {
postEntry.forEach(data => preEntry !.add(data));
postEntry.forEach(data => preEntry!.add(data));
} else {
allPreStyleElements.set(element, postEntry);
}

View File

@ -19,13 +19,17 @@ export class WebAnimationsDriver implements AnimationDriver {
private _isNativeImpl = /\{\s*\[native\s+code\]\s*\}/.test(getElementAnimateFn().toString());
private _cssKeyframesDriver = new CssKeyframesDriver();
validateStyleProperty(prop: string): boolean { return validateStyleProperty(prop); }
validateStyleProperty(prop: string): boolean {
return validateStyleProperty(prop);
}
matchesElement(element: any, selector: string): boolean {
return matchesElement(element, selector);
}
containsElement(elm1: any, elm2: any): boolean { return containsElement(elm1, elm2); }
containsElement(elm1: any, elm2: any): boolean {
return containsElement(elm1, elm2);
}
query(element: any, selector: string, multi: boolean): any[] {
return invokeQuery(element, selector, multi);
@ -35,7 +39,9 @@ export class WebAnimationsDriver implements AnimationDriver {
return (window.getComputedStyle(element) as any)[prop] as string;
}
overrideWebAnimationsSupport(supported: boolean) { this._isNativeImpl = supported; }
overrideWebAnimationsSupport(supported: boolean) {
this._isNativeImpl = supported;
}
animate(
element: any, keyframes: ɵStyleData[], duration: number, delay: number, easing: string,
@ -47,7 +53,7 @@ export class WebAnimationsDriver implements AnimationDriver {
}
const fill = delay == 0 ? 'both' : 'forwards';
const playerOptions: {[key: string]: string | number} = {duration, delay, fill};
const playerOptions: {[key: string]: string|number} = {duration, delay, fill};
// we check for this to avoid having a null|undefined value be present
// for the easing (which results in an error for certain browsers #9752)
if (easing) {

View File

@ -23,18 +23,18 @@ export class WebAnimationsPlayer implements AnimationPlayer {
private _started = false;
private _destroyed = false;
// TODO(issue/24571): remove '!'.
private _finalKeyframe !: {[key: string]: string | number};
private _finalKeyframe!: {[key: string]: string|number};
// TODO(issue/24571): remove '!'.
public readonly domPlayer !: DOMAnimation;
public readonly domPlayer!: DOMAnimation;
public time = 0;
public parentPlayer: AnimationPlayer|null = null;
public currentSnapshot: {[styleName: string]: string | number} = {};
public currentSnapshot: {[styleName: string]: string|number} = {};
constructor(
public element: any, public keyframes: {[key: string]: string | number}[],
public options: {[key: string]: string | number},
public element: any, public keyframes: {[key: string]: string|number}[],
public options: {[key: string]: string|number},
private _specialStyles?: SpecialCasedStyles|null) {
this._duration = <number>options['duration'];
this._delay = <number>options['delay'] || 0;
@ -59,7 +59,7 @@ export class WebAnimationsPlayer implements AnimationPlayer {
this._initialized = true;
const keyframes = this.keyframes;
(this as{domPlayer: DOMAnimation}).domPlayer =
(this as {domPlayer: DOMAnimation}).domPlayer =
this._triggerWebAnimation(this.element, keyframes, this.options);
this._finalKeyframe = keyframes.length ? keyframes[keyframes.length - 1] : {};
this.domPlayer.addEventListener('finish', () => this._onFinish());
@ -81,11 +81,17 @@ export class WebAnimationsPlayer implements AnimationPlayer {
return element['animate'](keyframes, options) as DOMAnimation;
}
onStart(fn: () => void): void { this._onStartFns.push(fn); }
onStart(fn: () => void): void {
this._onStartFns.push(fn);
}
onDone(fn: () => void): void { this._onDoneFns.push(fn); }
onDone(fn: () => void): void {
this._onDoneFns.push(fn);
}
onDestroy(fn: () => void): void { this._onDestroyFns.push(fn); }
onDestroy(fn: () => void): void {
this._onDestroyFns.push(fn);
}
play(): void {
this._buildPlayer();
@ -132,7 +138,9 @@ export class WebAnimationsPlayer implements AnimationPlayer {
this.play();
}
hasStarted(): boolean { return this._started; }
hasStarted(): boolean {
return this._started;
}
destroy(): void {
if (!this._destroyed) {
@ -147,14 +155,20 @@ export class WebAnimationsPlayer implements AnimationPlayer {
}
}
setPosition(p: number): void { this.domPlayer.currentTime = p * this.time; }
setPosition(p: number): void {
this.domPlayer.currentTime = p * this.time;
}
getPosition(): number { return this.domPlayer.currentTime / this.time; }
getPosition(): number {
return this.domPlayer.currentTime / this.time;
}
get totalTime(): number { return this._delay + this._duration; }
get totalTime(): number {
return this._delay + this._duration;
}
beforeDestroy() {
const styles: {[key: string]: string | number} = {};
const styles: {[key: string]: string|number} = {};
if (this.hasStarted()) {
Object.keys(this._finalKeyframe).forEach(prop => {
if (prop != 'offset') {

View File

@ -23,7 +23,7 @@ export const NG_TRIGGER_SELECTOR = '.ng-trigger';
export const NG_ANIMATING_CLASSNAME = 'ng-animating';
export const NG_ANIMATING_SELECTOR = '.ng-animating';
export function resolveTimingValue(value: string | number) {
export function resolveTimingValue(value: string|number) {
if (typeof value == 'number') return value;
const matches = value.match(/^(-?[\.\d]+)(m?s)/);
@ -42,14 +42,14 @@ function _convertTimeValueToMS(value: number, unit: string): number {
}
export function resolveTiming(
timings: string | number | AnimateTimings, errors: any[], allowNegativeValues?: boolean) {
timings: string|number|AnimateTimings, errors: any[], allowNegativeValues?: boolean) {
return timings.hasOwnProperty('duration') ?
<AnimateTimings>timings :
parseTimeExpression(<string|number>timings, errors, allowNegativeValues);
}
function parseTimeExpression(
exp: string | number, errors: string[], allowNegativeValues?: boolean): AnimateTimings {
exp: string|number, errors: string[], allowNegativeValues?: boolean): AnimateTimings {
const regex = /^(-?[\.\d]+)(m?s)(?:\s+(-?[\.\d]+)(m?s))?(?:\s+([-a-z]+(?:\(.+?\))?))?$/i;
let duration: number;
let delay: number = 0;
@ -97,11 +97,13 @@ function parseTimeExpression(
export function copyObj(
obj: {[key: string]: any}, destination: {[key: string]: any} = {}): {[key: string]: any} {
Object.keys(obj).forEach(prop => { destination[prop] = obj[prop]; });
Object.keys(obj).forEach(prop => {
destination[prop] = obj[prop];
});
return destination;
}
export function normalizeStyles(styles: ɵStyleData | ɵStyleData[]): ɵStyleData {
export function normalizeStyles(styles: ɵStyleData|ɵStyleData[]): ɵStyleData {
const normalizedStyles: ɵStyleData = {};
if (Array.isArray(styles)) {
styles.forEach(data => copyStyles(data, false, normalizedStyles));
@ -186,8 +188,8 @@ export function eraseStyles(element: any, styles: ɵStyleData) {
}
}
export function normalizeAnimationEntry(steps: AnimationMetadata | AnimationMetadata[]):
AnimationMetadata {
export function normalizeAnimationEntry(steps: AnimationMetadata|
AnimationMetadata[]): AnimationMetadata {
if (Array.isArray(steps)) {
if (steps.length == 1) return steps[0];
return sequence(steps);
@ -196,7 +198,7 @@ export function normalizeAnimationEntry(steps: AnimationMetadata | AnimationMeta
}
export function validateStyleParams(
value: string | number, options: AnimationOptions, errors: any[]) {
value: string|number, options: AnimationOptions, errors: any[]) {
const params = options.params || {};
const matches = extractStyleParams(value);
if (matches.length) {
@ -211,7 +213,7 @@ export function validateStyleParams(
const PARAM_REGEX =
new RegExp(`${SUBSTITUTION_EXPR_START}\\s*(.+?)\\s*${SUBSTITUTION_EXPR_END}`, 'g');
export function extractStyleParams(value: string | number): string[] {
export function extractStyleParams(value: string|number): string[] {
let params: string[] = [];
if (typeof value === 'string') {
let match: any;
@ -224,7 +226,7 @@ export function extractStyleParams(value: string | number): string[] {
}
export function interpolateParams(
value: string | number, params: {[name: string]: any}, errors: any[]): string|number {
value: string|number, params: {[name: string]: any}, errors: any[]): string|number {
const original = value.toString();
const str = original.replace(PARAM_REGEX, (_, varName) => {
let localVal = params[varName];
@ -297,7 +299,9 @@ export function balancePreviousStylesIntoKeyframes(
// tslint:disable-next-line
for (var i = 1; i < keyframes.length; i++) {
let kf = keyframes[i];
missingStyleProps.forEach(function(prop) { kf[prop] = computeStyle(element, prop); });
missingStyleProps.forEach(function(prop) {
kf[prop] = computeStyle(element, prop);
});
}
}
}

View File

@ -5,7 +5,7 @@
* 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, AnimationMetadata, AnimationMetadataType, AnimationOptions, animate, animation, group, keyframes, query, sequence, state, style, transition, trigger, useAnimation, ɵStyleData} from '@angular/animations';
import {animate, animation, AnimationMetadata, AnimationMetadataType, AnimationOptions, AUTO_STYLE, group, keyframes, query, sequence, state, style, transition, trigger, useAnimation, ɵStyleData} from '@angular/animations';
import {Animation} from '../../src/dsl/animation';
import {buildAnimationAst} from '../../src/dsl/animation_ast_builder';
@ -35,7 +35,9 @@ function createDiv() {
rootElement.appendChild(subElement2);
});
afterEach(() => { document.body.removeChild(rootElement); });
afterEach(() => {
document.body.removeChild(rootElement);
});
describe('validation', () => {
it('should throw an error if one or more but not all keyframes() styles contain offsets',
@ -45,7 +47,9 @@ function createDiv() {
style({opacity: 1, offset: 1}),
]));
expect(() => { validateAndThrowAnimationSequence(steps); })
expect(() => {
validateAndThrowAnimationSequence(steps);
})
.toThrowError(
/Not all style\(\) steps within the declared keyframes\(\) contain offsets/);
});
@ -96,7 +100,9 @@ function createDiv() {
]))
]);
expect(() => { validateAndThrowAnimationSequence(steps); })
expect(() => {
validateAndThrowAnimationSequence(steps);
})
.toThrowError(
/The CSS property "opacity" that exists between the times of "0ms" and "2000ms" is also being animated in a parallel animation between the times of "0ms" and "1500ms"/);
});
@ -191,7 +197,9 @@ function createDiv() {
})),
];
expect(() => { validateAndThrowAnimationSequence(steps); })
expect(() => {
validateAndThrowAnimationSequence(steps);
})
.toThrowError(
/state\("final", ...\) must define default values for all the following style substitutions: one, two, three/);
@ -203,7 +211,9 @@ function createDiv() {
}),
{params: {redColor: 'maroon'}})];
expect(() => { validateAndThrowAnimationSequence(steps2); })
expect(() => {
validateAndThrowAnimationSequence(steps2);
})
.toThrowError(
/state\("panfinal", ...\) must define default values for all the following style substitutions: greyColor/);
});
@ -211,7 +221,9 @@ function createDiv() {
it('should throw an error if an invalid CSS property is used in the animation', () => {
const steps = [animate(1000, style({abc: '500px'}))];
expect(() => { validateAndThrowAnimationSequence(steps); })
expect(() => {
validateAndThrowAnimationSequence(steps);
})
.toThrowError(
/The provided animation property "abc" is not a supported CSS property for animations/);
});
@ -388,7 +400,7 @@ function createDiv() {
let players = invokeAnimationSequence(rootElement, steps);
expect(players.length).toEqual(1);
let p1 = players.pop() !;
let p1 = players.pop()!;
expect(p1.duration).toEqual(1500);
expect(p1.keyframes).toEqual([
{width: '*', offset: 0},
@ -405,7 +417,7 @@ function createDiv() {
players = invokeAnimationSequence(rootElement, steps);
expect(players.length).toEqual(1);
p1 = players.pop() !;
p1 = players.pop()!;
expect(p1.duration).toEqual(1000);
expect(p1.keyframes).toEqual([
{width: '100px', offset: 0},
@ -876,7 +888,9 @@ function createDiv() {
const steps =
[query('somethingFake', [style({opacity: 0}), animate(1000, style({opacity: 1}))])];
expect(() => { invokeAnimationSequence(rootElement, steps); })
expect(() => {
invokeAnimationSequence(rootElement, steps);
})
.toThrowError(
/`query\("somethingFake"\)` returned zero elements\. \(Use `query\("somethingFake", \{ optional: true \}\)` if you wish to allow this\.\)/);
});
@ -887,13 +901,17 @@ function createDiv() {
'somethingFake', [style({opacity: 0}), animate(1000, style({opacity: 1}))],
{optional: true})];
expect(() => { invokeAnimationSequence(rootElement, steps); }).not.toThrow();
expect(() => {
invokeAnimationSequence(rootElement, steps);
}).not.toThrow();
const steps2 = [query(
'fakeSomethings', [style({opacity: 0}), animate(1000, style({opacity: 1}))],
{optional: true})];
expect(() => { invokeAnimationSequence(rootElement, steps2); }).not.toThrow();
expect(() => {
invokeAnimationSequence(rootElement, steps2);
}).not.toThrow();
});
it('should delay the query operation if a delay option is provided', () => {
@ -1025,8 +1043,7 @@ function createDiv() {
const players = invokeAnimationSequence(rootElement, steps, {}, fromStyles, toStyles);
expect(players[0].keyframes).toEqual([
{background: 'blue', offset: 0, easing: 'ease-out'},
{background: 'red', offset: 1}
{background: 'blue', offset: 0, easing: 'ease-out'}, {background: 'red', offset: 1}
]);
});
});
@ -1042,7 +1059,7 @@ function humanizeOffsets(keyframes: ɵStyleData[], digits: number = 3): ɵStyleD
}
function invokeAnimationSequence(
element: any, steps: AnimationMetadata | AnimationMetadata[], locals: {[key: string]: any} = {},
element: any, steps: AnimationMetadata|AnimationMetadata[], locals: {[key: string]: any} = {},
startingStyles: ɵStyleData[] = [], destinationStyles: ɵStyleData[] = [],
subInstructions?: ElementInstructionMap): AnimationTimelineInstruction[] {
const driver = new MockAnimationDriver();
@ -1050,7 +1067,7 @@ function invokeAnimationSequence(
.buildTimelines(element, startingStyles, destinationStyles, locals, subInstructions);
}
function validateAndThrowAnimationSequence(steps: AnimationMetadata | AnimationMetadata[]) {
function validateAndThrowAnimationSequence(steps: AnimationMetadata|AnimationMetadata[]) {
const driver = new MockAnimationDriver();
const errors: any[] = [];
const ast = buildAnimationAst(driver, steps, errors);

View File

@ -6,7 +6,7 @@
* found in the LICENSE file at https://angular.io/license
*/
import {AnimationOptions, animate, state, style, transition} from '@angular/animations';
import {animate, AnimationOptions, state, style, transition} from '@angular/animations';
import {AnimationTransitionInstruction} from '@angular/animations/browser/src/dsl/animation_transition_instruction';
import {AnimationTrigger} from '@angular/animations/browser/src/dsl/animation_trigger';
@ -25,7 +25,9 @@ import {makeTrigger} from '../shared';
document.body.appendChild(element);
});
afterEach(() => { document.body.removeChild(element); });
afterEach(() => {
document.body.removeChild(element);
});
describe('trigger validation', () => {
it('should group errors together for an animation trigger', () => {
@ -36,8 +38,9 @@ import {makeTrigger} from '../shared';
it('should throw an error when a transition within a trigger contains an invalid expression',
() => {
expect(
() => { makeTrigger('name', [transition('somethingThatIsWrong', animate(3333))]); })
expect(() => {
makeTrigger('name', [transition('somethingThatIsWrong', animate(3333))]);
})
.toThrowError(
/- The provided transition expression "somethingThatIsWrong" is not supported/);
});
@ -78,7 +81,7 @@ import {makeTrigger} from '../shared';
const result = makeTrigger(
'name', [transition('a => b', animate(1234)), transition('b => c', animate(5678))]);
const trans = buildTransition(result, element, 'b', 'c') !;
const trans = buildTransition(result, element, 'b', 'c')!;
expect(trans.timelines.length).toEqual(1);
const timeline = trans.timelines[0];
expect(timeline.duration).toEqual(5678);
@ -90,13 +93,13 @@ import {makeTrigger} from '../shared';
transition('* => *', animate(9999))
]);
let trans = buildTransition(result, element, 'b', 'c') !;
let trans = buildTransition(result, element, 'b', 'c')!;
expect(trans.timelines[0].duration).toEqual(5678);
trans = buildTransition(result, element, 'a', 'b') !;
trans = buildTransition(result, element, 'a', 'b')!;
expect(trans.timelines[0].duration).toEqual(1234);
trans = buildTransition(result, element, 'c', 'c') !;
trans = buildTransition(result, element, 'c', 'c')!;
expect(trans.timelines[0].duration).toEqual(9999);
});
@ -110,23 +113,23 @@ import {makeTrigger} from '../shared';
it('should support bi-directional transition expressions', () => {
const result = makeTrigger('name', [transition('a <=> b', animate(2222))]);
const t1 = buildTransition(result, element, 'a', 'b') !;
const t1 = buildTransition(result, element, 'a', 'b')!;
expect(t1.timelines[0].duration).toEqual(2222);
const t2 = buildTransition(result, element, 'b', 'a') !;
const t2 = buildTransition(result, element, 'b', 'a')!;
expect(t2.timelines[0].duration).toEqual(2222);
});
it('should support multiple transition statements in one string', () => {
const result = makeTrigger('name', [transition('a => b, b => a, c => *', animate(1234))]);
const t1 = buildTransition(result, element, 'a', 'b') !;
const t1 = buildTransition(result, element, 'a', 'b')!;
expect(t1.timelines[0].duration).toEqual(1234);
const t2 = buildTransition(result, element, 'b', 'a') !;
const t2 = buildTransition(result, element, 'b', 'a')!;
expect(t2.timelines[0].duration).toEqual(1234);
const t3 = buildTransition(result, element, 'c', 'a') !;
const t3 = buildTransition(result, element, 'c', 'a')!;
expect(t3.timelines[0].duration).toEqual(1234);
});
@ -138,7 +141,7 @@ import {makeTrigger} from '../shared';
'a => b', [style({height: '{{ a }}'}), animate(1000, style({height: '{{ b }}'}))],
buildParams({a: '100px', b: '200px'}))]);
const trans = buildTransition(result, element, 'a', 'b') !;
const trans = buildTransition(result, element, 'a', 'b')!;
const keyframes = trans.timelines[0].keyframes;
expect(keyframes).toEqual([{height: '100px', offset: 0}, {height: '200px', offset: 1}]);
});
@ -153,7 +156,7 @@ import {makeTrigger} from '../shared';
buildParams({a: '100px', b: '200px'}))]);
const trans =
buildTransition(result, element, 'a', 'b', {}, buildParams({a: '300px'})) !;
buildTransition(result, element, 'a', 'b', {}, buildParams({a: '300px'}))!;
const keyframes = trans.timelines[0].keyframes;
expect(keyframes).toEqual(
@ -167,7 +170,7 @@ import {makeTrigger} from '../shared';
transition('true <=> false', animate(1234))
]);
const trans = buildTransition(result, element, false, true) !;
const trans = buildTransition(result, element, false, true)!;
expect(trans.timelines[0].duration).toEqual(1234);
});
@ -177,7 +180,7 @@ import {makeTrigger} from '../shared';
transition('1 <=> 0', animate(4567))
]);
const trans = buildTransition(result, element, false, true) !;
const trans = buildTransition(result, element, false, true)!;
expect(trans.timelines[0].duration).toEqual(4567);
});
@ -188,7 +191,7 @@ import {makeTrigger} from '../shared';
transition('1 <=> 0', animate(4567))
]);
const trans = buildTransition(result, element, false, true) !;
const trans = buildTransition(result, element, false, true)!;
expect(trans.timelines[0].keyframes).toEqual([
{offset: 0, color: 'red'}, {offset: 1, color: 'green'}
]);
@ -201,7 +204,7 @@ import {makeTrigger} from '../shared';
transition('true <=> false', animate(4567))
]);
const trans = buildTransition(result, element, false, true) !;
const trans = buildTransition(result, element, false, true)!;
expect(trans.timelines[0].keyframes).toEqual([
{offset: 0, color: 'orange'}, {offset: 1, color: 'blue'}
]);
@ -214,7 +217,7 @@ import {makeTrigger} from '../shared';
]);
expect(() => {
const trans = buildTransition(result, element, false, true) !;
const trans = buildTransition(result, element, false, true)!;
}).not.toThrow();
});
@ -222,14 +225,14 @@ import {makeTrigger} from '../shared';
it('should alias the :enter transition as void => *', () => {
const result = makeTrigger('name', [transition(':enter', animate(3333))]);
const trans = buildTransition(result, element, 'void', 'something') !;
const trans = buildTransition(result, element, 'void', 'something')!;
expect(trans.timelines[0].duration).toEqual(3333);
});
it('should alias the :leave transition as * => void', () => {
const result = makeTrigger('name', [transition(':leave', animate(3333))]);
const trans = buildTransition(result, element, 'something', 'void') !;
const trans = buildTransition(result, element, 'something', 'void')!;
expect(trans.timelines[0].duration).toEqual(3333);
});
});
@ -242,12 +245,12 @@ function buildTransition(
fromOptions?: AnimationOptions, toOptions?: AnimationOptions): AnimationTransitionInstruction|
null {
const params = toOptions && toOptions.params || {};
const trans = trigger.matchTransition(fromState, toState, element, params) !;
const trans = trigger.matchTransition(fromState, toState, element, params)!;
if (trans) {
const driver = new MockAnimationDriver();
return trans.build(
driver, element, fromState, toState, ENTER_CLASSNAME, LEAVE_CLASSNAME, fromOptions,
toOptions) !;
toOptions)!;
}
return null;
}

View File

@ -16,13 +16,13 @@ import {WebAnimationsStyleNormalizer} from '../../../src/dsl/style_normalization
expect(normalizer.normalizePropertyName('width', [])).toEqual('width');
expect(normalizer.normalizePropertyName('border-width', [])).toEqual('borderWidth');
expect(normalizer.normalizePropertyName('borderHeight', [])).toEqual('borderHeight');
expect(normalizer.normalizePropertyName('-webkit-animation', [
])).toEqual('WebkitAnimation');
expect(normalizer.normalizePropertyName('-webkit-animation', []))
.toEqual('WebkitAnimation');
});
});
describe('normalizeStyleValue', () => {
function normalize(prop: string, val: string | number): string {
function normalize(prop: string, val: string|number): string {
const errors: string[] = [];
const result = normalizer.normalizeStyleValue(prop, prop, val, errors);
if (errors.length) {

View File

@ -5,7 +5,7 @@
* 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 {TestBed, fakeAsync, flushMicrotasks} from '@angular/core/testing';
import {fakeAsync, flushMicrotasks, TestBed} from '@angular/core/testing';
import {CssKeyframesDriver} from '../../../src/render/css_keyframes/css_keyframes_driver';
import {CssKeyframesPlayer} from '../../../src/render/css_keyframes/css_keyframes_player';
@ -16,7 +16,7 @@ import {assertElementExistsInDom, createElement, findKeyframeDefinition, forceRe
const CSS_KEYFRAME_RULE_TYPE = 7;
describe('CssKeyframesDriver tests', () => {
if (isNode || typeof(window as any)['AnimationEvent'] == 'undefined') return;
if (isNode || typeof (window as any)['AnimationEvent'] == 'undefined') return;
describe('building keyframes', () => {
it('should build CSS keyframe style object containing the keyframe styles', () => {
@ -28,7 +28,7 @@ describe('CssKeyframesDriver tests', () => {
{opacity: 1, width: '200px', offset: 1},
]);
const head = document.querySelector('head') !;
const head = document.querySelector('head')!;
head.appendChild(kfElm);
forceReflow();
@ -67,7 +67,7 @@ describe('CssKeyframesDriver tests', () => {
{width: '200px', offset: 1},
]);
const head = document.querySelector('head') !;
const head = document.querySelector('head')!;
head.appendChild(kfElm);
forceReflow();
@ -261,7 +261,7 @@ describe('CssKeyframesDriver tests', () => {
player.play();
player.finish();
player.beforeDestroy !();
player.beforeDestroy!();
expect(player.currentSnapshot).toEqual({
width: '999px',
height: '999px',

View File

@ -5,7 +5,7 @@
* 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 {TestBed, fakeAsync, flushMicrotasks} from '@angular/core/testing';
import {fakeAsync, flushMicrotasks, TestBed} from '@angular/core/testing';
import {DirectStylePlayer} from '../../../src/render/css_keyframes/direct_style_player';

View File

@ -13,7 +13,7 @@ import {assertStyle, createElement, makeAnimationEvent, supportsAnimationEventCr
const EMPTY_FN = () => {};
{
describe('ElementAnimationStyleHandler', () => {
if (isNode || typeof(window as any)['AnimationEvent'] == 'undefined') return;
if (isNode || typeof (window as any)['AnimationEvent'] == 'undefined') return;
it('should add and remove an animation on to an element\'s styling', () => {
const element = createElement();

View File

@ -10,7 +10,7 @@ export function forceReflow() {
}
export function makeAnimationEvent(
startOrEnd: 'start' | 'end', animationName: string, elapsedTime: number, timestamp?: number) {
startOrEnd: 'start'|'end', animationName: string, elapsedTime: number, timestamp?: number) {
const e = new AnimationEvent('animation' + startOrEnd, {animationName, elapsedTime});
if (timestamp) {
(e as any)._ngTestManualTimestamp = timestamp;

View File

@ -5,7 +5,7 @@
* 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, style} from '@angular/animations';
import {animate, AnimationMetadata, style} from '@angular/animations';
import {AnimationStyleNormalizer, NoopAnimationStyleNormalizer} from '../../src/dsl/style_normalization/animation_style_normalizer';
import {AnimationDriver} from '../../src/render/animation_driver';
@ -14,98 +14,101 @@ import {TimelineAnimationEngine} from '../../src/render/timeline_animation_engin
import {MockAnimationDriver, MockAnimationPlayer} from '../../testing/src/mock_animation_driver';
(function() {
const defaultDriver = new MockAnimationDriver();
const defaultDriver = new MockAnimationDriver();
function makeEngine(body: any, driver?: AnimationDriver, normalizer?: AnimationStyleNormalizer) {
return new TimelineAnimationEngine(
body, driver || defaultDriver, normalizer || new NoopAnimationStyleNormalizer());
}
function makeEngine(body: any, driver?: AnimationDriver, normalizer?: AnimationStyleNormalizer) {
return new TimelineAnimationEngine(
body, driver || defaultDriver, normalizer || new NoopAnimationStyleNormalizer());
}
// these tests are only mean't to be run within the DOM
if (isNode) return;
// these tests are only mean't to be run within the DOM
if (isNode) return;
describe('TimelineAnimationEngine', () => {
let element: any;
describe('TimelineAnimationEngine', () => {
let element: any;
beforeEach(() => {
MockAnimationDriver.log = [];
element = document.createElement('div');
document.body.appendChild(element);
});
afterEach(() => document.body.removeChild(element));
it('should animate a timeline', () => {
const engine = makeEngine(getBodyNode());
const steps = [style({height: 100}), animate(1000, style({height: 0}))];
expect(MockAnimationDriver.log.length).toEqual(0);
invokeAnimation(engine, element, steps);
expect(MockAnimationDriver.log.length).toEqual(1);
});
it('should not destroy timeline-based animations after they have finished', () => {
const engine = makeEngine(getBodyNode());
const log: string[] = [];
function capture(value: string) {
return () => { log.push(value); };
}
const steps = [style({height: 0}), animate(1000, style({height: 500}))];
const player = invokeAnimation(engine, element, steps);
player.onDone(capture('done'));
player.onDestroy(capture('destroy'));
expect(log).toEqual([]);
player.finish();
expect(log).toEqual(['done']);
player.destroy();
expect(log).toEqual(['done', 'destroy']);
});
it('should normalize the style values that are animateTransitioned within an a timeline animation',
() => {
const engine =
makeEngine(getBodyNode(), defaultDriver, new SuffixNormalizer('-normalized'));
const steps = [
style({width: '333px'}),
animate(1000, style({width: '999px'})),
];
const player = invokeAnimation(engine, element, steps) as MockAnimationPlayer;
expect(player.keyframes).toEqual([
{'width-normalized': '333px-normalized', offset: 0},
{'width-normalized': '999px-normalized', offset: 1}
]);
});
it('should normalize `*` values', () => {
const driver = new SuperMockDriver();
const engine = makeEngine(getBodyNode(), driver);
const steps = [
style({width: '*'}),
animate(1000, style({width: '999px'})),
];
const player = invokeAnimation(engine, element, steps) as MockAnimationPlayer;
expect(player.keyframes).toEqual([{width: '*star*', offset: 0}, {width: '999px', offset: 1}]);
});
beforeEach(() => {
MockAnimationDriver.log = [];
element = document.createElement('div');
document.body.appendChild(element);
});
afterEach(() => document.body.removeChild(element));
it('should animate a timeline', () => {
const engine = makeEngine(getBodyNode());
const steps = [style({height: 100}), animate(1000, style({height: 0}))];
expect(MockAnimationDriver.log.length).toEqual(0);
invokeAnimation(engine, element, steps);
expect(MockAnimationDriver.log.length).toEqual(1);
});
it('should not destroy timeline-based animations after they have finished', () => {
const engine = makeEngine(getBodyNode());
const log: string[] = [];
function capture(value: string) {
return () => {
log.push(value);
};
}
const steps = [style({height: 0}), animate(1000, style({height: 500}))];
const player = invokeAnimation(engine, element, steps);
player.onDone(capture('done'));
player.onDestroy(capture('destroy'));
expect(log).toEqual([]);
player.finish();
expect(log).toEqual(['done']);
player.destroy();
expect(log).toEqual(['done', 'destroy']);
});
it('should normalize the style values that are animateTransitioned within an a timeline animation',
() => {
const engine = makeEngine(getBodyNode(), defaultDriver, new SuffixNormalizer('-normalized'));
const steps = [
style({width: '333px'}),
animate(1000, style({width: '999px'})),
];
const player = invokeAnimation(engine, element, steps) as MockAnimationPlayer;
expect(player.keyframes).toEqual([
{'width-normalized': '333px-normalized', offset: 0},
{'width-normalized': '999px-normalized', offset: 1}
]);
});
it('should normalize `*` values', () => {
const driver = new SuperMockDriver();
const engine = makeEngine(getBodyNode(), driver);
const steps = [
style({width: '*'}),
animate(1000, style({width: '999px'})),
];
const player = invokeAnimation(engine, element, steps) as MockAnimationPlayer;
expect(player.keyframes).toEqual([{width: '*star*', offset: 0}, {width: '999px', offset: 1}]);
});
});
})();
function invokeAnimation(
engine: TimelineAnimationEngine, element: any, steps: AnimationMetadata | AnimationMetadata[],
engine: TimelineAnimationEngine, element: any, steps: AnimationMetadata|AnimationMetadata[],
id: string = 'id') {
engine.register(id, steps);
return engine.create(id, element);
}
class SuffixNormalizer extends AnimationStyleNormalizer {
constructor(private _suffix: string) { super(); }
constructor(private _suffix: string) {
super();
}
normalizePropertyName(propertyName: string, errors: string[]): string {
return propertyName + this._suffix;
@ -119,5 +122,7 @@ class SuffixNormalizer extends AnimationStyleNormalizer {
}
class SuperMockDriver extends MockAnimationDriver {
computeStyle(element: any, prop: string, defaultValue?: string): string { return '*star*'; }
computeStyle(element: any, prop: string, defaultValue?: string): string {
return '*star*';
}
}

View File

@ -13,7 +13,9 @@ import {WebAnimationsPlayer} from '../../../src/render/web_animations/web_animat
let innerPlayer: MockDomAnimation|null = null;
beforeEach(() => {
element = {};
element['animate'] = () => { return innerPlayer = new MockDomAnimation(); };
element['animate'] = () => {
return innerPlayer = new MockDomAnimation();
};
});
describe('WebAnimationsPlayer tests', () => {
@ -26,7 +28,7 @@ import {WebAnimationsPlayer} from '../../../src/render/web_animations/web_animat
const player = new WebAnimationsPlayer(element, keyframes, {duration: 1000});
player.init();
const p = innerPlayer !;
const p = innerPlayer!;
expect(p.log).toEqual(['pause']);
player.play();
@ -42,7 +44,7 @@ import {WebAnimationsPlayer} from '../../../src/render/web_animations/web_animat
const player = new WebAnimationsPlayer(element, keyframes, {duration: 1000});
player.play();
const p = innerPlayer !;
const p = innerPlayer!;
expect(p.log).toEqual(['play']);
});
@ -70,10 +72,18 @@ import {WebAnimationsPlayer} from '../../../src/render/web_animations/web_animat
class MockDomAnimation implements DOMAnimation {
log: string[] = [];
cancel(): void { this.log.push('cancel'); }
play(): void { this.log.push('play'); }
pause(): void { this.log.push('pause'); }
finish(): void { this.log.push('finish'); }
cancel(): void {
this.log.push('cancel');
}
play(): void {
this.log.push('play');
}
pause(): void {
this.log.push('pause');
}
finish(): void {
this.log.push('finish');
}
onfinish: Function = () => {};
position: number = 0;
currentTime: number = 0;

View File

@ -21,8 +21,8 @@ export function makeTrigger(
const triggerAst = buildAnimationAst(driver, triggerData, errors) as TriggerAst;
if (!skipErrors && errors.length) {
const LINE_START = '\n - ';
throw new Error(
`Animation parsing for the ${name} trigger have failed:${LINE_START}${errors.join(LINE_START)}`);
throw new Error(`Animation parsing for the ${name} trigger have failed:${LINE_START}${
errors.join(LINE_START)}`);
}
return buildTrigger(name, triggerAst);
}

View File

@ -5,7 +5,7 @@
* 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, AnimationPlayer, NoopAnimationPlayer, ɵStyleData} from '@angular/animations';
import {AnimationPlayer, AUTO_STYLE, NoopAnimationPlayer, ɵStyleData} from '@angular/animations';
import {AnimationDriver, ɵallowPreviousPlayerStylesMerge as allowPreviousPlayerStylesMerge, ɵcontainsElement as containsElement, ɵinvokeQuery as invokeQuery, ɵmatchesElement as matchesElement, ɵvalidateStyleProperty as validateStyleProperty} from '@angular/animations/browser';
@ -15,13 +15,17 @@ import {AnimationDriver, ɵallowPreviousPlayerStylesMerge as allowPreviousPlayer
export class MockAnimationDriver implements AnimationDriver {
static log: AnimationPlayer[] = [];
validateStyleProperty(prop: string): boolean { return validateStyleProperty(prop); }
validateStyleProperty(prop: string): boolean {
return validateStyleProperty(prop);
}
matchesElement(element: any, selector: string): boolean {
return matchesElement(element, selector);
}
containsElement(elm1: any, elm2: any): boolean { return containsElement(elm1, elm2); }
containsElement(elm1: any, elm2: any): boolean {
return containsElement(elm1, elm2);
}
query(element: any, selector: string, multi: boolean): any[] {
return invokeQuery(element, selector, multi);
@ -32,7 +36,7 @@ export class MockAnimationDriver implements AnimationDriver {
}
animate(
element: any, keyframes: {[key: string]: string | number}[], duration: number, delay: number,
element: any, keyframes: {[key: string]: string|number}[], duration: number, delay: number,
easing: string, previousPlayers: any[] = []): MockAnimationPlayer {
const player =
new MockAnimationPlayer(element, keyframes, duration, delay, easing, previousPlayers);
@ -47,12 +51,12 @@ export class MockAnimationDriver implements AnimationDriver {
export class MockAnimationPlayer extends NoopAnimationPlayer {
private __finished = false;
private __started = false;
public previousStyles: {[key: string]: string | number} = {};
public previousStyles: {[key: string]: string|number} = {};
private _onInitFns: (() => any)[] = [];
public currentSnapshot: ɵStyleData = {};
constructor(
public element: any, public keyframes: {[key: string]: string | number}[],
public element: any, public keyframes: {[key: string]: string|number}[],
public duration: number, public delay: number, public easing: string,
public previousPlayers: any[]) {
super(duration, delay);
@ -68,7 +72,9 @@ export class MockAnimationPlayer extends NoopAnimationPlayer {
}
/* @internal */
onInit(fn: () => any) { this._onInitFns.push(fn); }
onInit(fn: () => any) {
this._onInitFns.push(fn);
}
/* @internal */
init() {
@ -95,7 +101,9 @@ export class MockAnimationPlayer extends NoopAnimationPlayer {
this.__started = true;
}
hasStarted() { return this.__started; }
hasStarted() {
return this.__started;
}
beforeDestroy() {
const captures: ɵStyleData = {};

View File

@ -9,7 +9,9 @@
/**
* Represents a set of CSS styles for use in an animation style.
*/
export interface ɵStyleData { [key: string]: string|number; }
export interface ɵStyleData {
[key: string]: string|number;
}
/**
* Represents animation-step timing parameters for an animation step.
@ -67,10 +69,10 @@ export declare interface AnimationOptions {
*/
delay?: number|string;
/**
* A set of developer-defined parameters that modify styling and timing
* when an animation action starts. An array of key-value pairs, where the provided value
* is used as a default.
*/
* A set of developer-defined parameters that modify styling and timing
* when an animation action starts. An array of key-value pairs, where the provided value
* is used as a default.
*/
params?: {[name: string]: any};
}
@ -81,7 +83,9 @@ export declare interface AnimationOptions {
*
* @publicApi
*/
export declare interface AnimateChildOptions extends AnimationOptions { duration?: number|string; }
export declare interface AnimateChildOptions extends AnimationOptions {
duration?: number|string;
}
/**
* @description Constants for the categories of parameters that can be defined for animations.
@ -171,7 +175,9 @@ export const AUTO_STYLE = '*';
*
* @publicApi
*/
export interface AnimationMetadata { type: AnimationMetadataType; }
export interface AnimationMetadata {
type: AnimationMetadataType;
}
/**
* Contains an animation trigger. Instantiated and returned by the
@ -181,8 +187,8 @@ export interface AnimationMetadata { type: AnimationMetadataType; }
*/
export interface AnimationTriggerMetadata extends AnimationMetadata {
/**
* The trigger name, used to associate it with an element. Unique within the component.
*/
* The trigger name, used to associate it with an element. Unique within the component.
*/
name: string;
/**
* An animation definition object, containing an array of state and transition declarations.
@ -654,8 +660,9 @@ export function trigger(name: string, definitions: AnimationMetadata[]): Animati
* @publicApi
*/
export function animate(
timings: string | number, styles: AnimationStyleMetadata | AnimationKeyframesSequenceMetadata |
null = null): AnimationAnimateMetadata {
timings: string|number,
styles: AnimationStyleMetadata|AnimationKeyframesSequenceMetadata|null =
null): AnimationAnimateMetadata {
return {type: AnimationMetadataType.Animate, styles, timings};
}
@ -693,7 +700,7 @@ export function animate(
* @publicApi
*/
export function group(
steps: AnimationMetadata[], options: AnimationOptions | null = null): AnimationGroupMetadata {
steps: AnimationMetadata[], options: AnimationOptions|null = null): AnimationGroupMetadata {
return {type: AnimationMetadataType.Group, steps, options};
}
@ -721,7 +728,8 @@ export function group(
* @usageNotes
* When you pass an array of steps to a
* `transition()` call, the steps run sequentially by default.
* Compare this to the `{@link animations/group group()}` call, which runs animation steps in parallel.
* Compare this to the `{@link animations/group group()}` call, which runs animation steps in
*parallel.
*
* When a sequence is used within a `{@link animations/group group()}` or a `transition()` call,
* execution continues to the next instruction only after each of the inner animation
@ -729,8 +737,8 @@ export function group(
*
* @publicApi
**/
export function sequence(steps: AnimationMetadata[], options: AnimationOptions | null = null):
AnimationSequenceMetadata {
export function sequence(
steps: AnimationMetadata[], options: AnimationOptions|null = null): AnimationSequenceMetadata {
return {type: AnimationMetadataType.Sequence, steps, options};
}
@ -773,9 +781,8 @@ export function sequence(steps: AnimationMetadata[], options: AnimationOptions |
*
* @publicApi
**/
export function style(
tokens: '*' | {[key: string]: string | number} |
Array<'*'|{[key: string]: string | number}>): AnimationStyleMetadata {
export function style(tokens: '*'|{[key: string]: string | number}|
Array<'*'|{[key: string]: string | number}>): AnimationStyleMetadata {
return {type: AnimationMetadataType.Style, styles: tokens, offset: null};
}
@ -1032,10 +1039,10 @@ export function keyframes(steps: AnimationStyleMetadata[]): AnimationKeyframesSe
* @publicApi
**/
export function transition(
stateChangeExpr: string | ((fromState: string, toState: string, element?: any,
params?: {[key: string]: any}) => boolean),
steps: AnimationMetadata | AnimationMetadata[],
options: AnimationOptions | null = null): AnimationTransitionMetadata {
stateChangeExpr: string|
((fromState: string, toState: string, element?: any, params?: {[key: string]: any}) => boolean),
steps: AnimationMetadata|AnimationMetadata[],
options: AnimationOptions|null = null): AnimationTransitionMetadata {
return {type: AnimationMetadataType.Transition, expr: stateChangeExpr, animation: steps, options};
}
@ -1085,8 +1092,8 @@ export function transition(
* @publicApi
*/
export function animation(
steps: AnimationMetadata | AnimationMetadata[],
options: AnimationOptions | null = null): AnimationReferenceMetadata {
steps: AnimationMetadata|AnimationMetadata[],
options: AnimationOptions|null = null): AnimationReferenceMetadata {
return {type: AnimationMetadataType.Reference, animation: steps, options};
}
@ -1109,7 +1116,7 @@ export function animation(
*
* @publicApi
*/
export function animateChild(options: AnimateChildOptions | null = null):
export function animateChild(options: AnimateChildOptions|null = null):
AnimationAnimateChildMetadata {
return {type: AnimationMetadataType.AnimateChild, options};
}
@ -1126,7 +1133,7 @@ export function animateChild(options: AnimateChildOptions | null = null):
*/
export function useAnimation(
animation: AnimationReferenceMetadata,
options: AnimationOptions | null = null): AnimationAnimateRefMetadata {
options: AnimationOptions|null = null): AnimationAnimateRefMetadata {
return {type: AnimationMetadataType.AnimateRef, animation, options};
}
@ -1179,7 +1186,7 @@ export function useAnimation(
* ### Usage Example
*
* The following example queries for inner elements and animates them
* individually using `animate()`.
* individually using `animate()`.
*
* ```typescript
* @Component({
@ -1218,8 +1225,8 @@ export function useAnimation(
* @publicApi
*/
export function query(
selector: string, animation: AnimationMetadata | AnimationMetadata[],
options: AnimationQueryOptions | null = null): AnimationQueryMetadata {
selector: string, animation: AnimationMetadata|AnimationMetadata[],
options: AnimationQueryOptions|null = null): AnimationQueryMetadata {
return {type: AnimationMetadataType.Query, selector, animation, options};
}
@ -1303,8 +1310,7 @@ export function query(
*
* @publicApi
*/
export function stagger(
timings: string | number,
animation: AnimationMetadata | AnimationMetadata[]): AnimationStaggerMetadata {
export function stagger(timings: string|number, animation: AnimationMetadata|AnimationMetadata[]):
AnimationStaggerMetadata {
return {type: AnimationMetadataType.Stagger, timings, animation};
}

View File

@ -13,7 +13,7 @@
*/
export {AnimationBuilder, AnimationFactory} from './animation_builder';
export {AnimationEvent} from './animation_event';
export {AUTO_STYLE, AnimateChildOptions, AnimateTimings, AnimationAnimateChildMetadata, AnimationAnimateMetadata, AnimationAnimateRefMetadata, AnimationGroupMetadata, AnimationKeyframesSequenceMetadata, AnimationMetadata, AnimationMetadataType, AnimationOptions, AnimationQueryMetadata, AnimationQueryOptions, AnimationReferenceMetadata, AnimationSequenceMetadata, AnimationStaggerMetadata, AnimationStateMetadata, AnimationStyleMetadata, AnimationTransitionMetadata, AnimationTriggerMetadata, animate, animateChild, animation, group, keyframes, query, sequence, stagger, state, style, transition, trigger, useAnimation, ɵStyleData} from './animation_metadata';
export {animate, animateChild, AnimateChildOptions, AnimateTimings, animation, AnimationAnimateChildMetadata, AnimationAnimateMetadata, AnimationAnimateRefMetadata, AnimationGroupMetadata, AnimationKeyframesSequenceMetadata, AnimationMetadata, AnimationMetadataType, AnimationOptions, AnimationQueryMetadata, AnimationQueryOptions, AnimationReferenceMetadata, AnimationSequenceMetadata, AnimationStaggerMetadata, AnimationStateMetadata, AnimationStyleMetadata, AnimationTransitionMetadata, AnimationTriggerMetadata, AUTO_STYLE, group, keyframes, query, sequence, stagger, state, style, transition, trigger, useAnimation, ɵStyleData} from './animation_metadata';
export {AnimationPlayer, NoopAnimationPlayer} from './players/animation_player';
export * from './private_export';

View File

@ -69,9 +69,13 @@ export class AnimationGroupPlayer implements AnimationPlayer {
}
}
init(): void { this.players.forEach(player => player.init()); }
init(): void {
this.players.forEach(player => player.init());
}
onStart(fn: () => void): void { this._onStartFns.push(fn); }
onStart(fn: () => void): void {
this._onStartFns.push(fn);
}
private _onStart() {
if (!this.hasStarted()) {
@ -81,11 +85,17 @@ export class AnimationGroupPlayer implements AnimationPlayer {
}
}
onDone(fn: () => void): void { this._onDoneFns.push(fn); }
onDone(fn: () => void): void {
this._onDoneFns.push(fn);
}
onDestroy(fn: () => void): void { this._onDestroyFns.push(fn); }
onDestroy(fn: () => void): void {
this._onDestroyFns.push(fn);
}
hasStarted() { return this._started; }
hasStarted() {
return this._started;
}
play() {
if (!this.parentPlayer) {
@ -95,16 +105,22 @@ export class AnimationGroupPlayer implements AnimationPlayer {
this.players.forEach(player => player.play());
}
pause(): void { this.players.forEach(player => player.pause()); }
pause(): void {
this.players.forEach(player => player.pause());
}
restart(): void { this.players.forEach(player => player.restart()); }
restart(): void {
this.players.forEach(player => player.restart());
}
finish(): void {
this._onFinish();
this.players.forEach(player => player.finish());
}
destroy(): void { this._onDestroy(); }
destroy(): void {
this._onDestroy();
}
private _onDestroy() {
if (!this._destroyed) {

View File

@ -94,11 +94,13 @@ export interface AnimationPlayer {
* Provides a callback to invoke before the animation is destroyed.
*/
beforeDestroy?: () => any;
/** @internal
/**
* @internal
* Internal
*/
triggerCallback?: (phaseName: string) => void;
/** @internal
/**
* @internal
* Internal
*/
disabled?: boolean;
@ -124,7 +126,9 @@ export class NoopAnimationPlayer implements AnimationPlayer {
private _finished = false;
public parentPlayer: AnimationPlayer|null = null;
public readonly totalTime: number;
constructor(duration: number = 0, delay: number = 0) { this.totalTime = duration + delay; }
constructor(duration: number = 0, delay: number = 0) {
this.totalTime = duration + delay;
}
private _onFinish() {
if (!this._finished) {
this._finished = true;
@ -132,10 +136,18 @@ export class NoopAnimationPlayer implements AnimationPlayer {
this._onDoneFns = [];
}
}
onStart(fn: () => void): void { this._onStartFns.push(fn); }
onDone(fn: () => void): void { this._onDoneFns.push(fn); }
onDestroy(fn: () => void): void { this._onDestroyFns.push(fn); }
hasStarted(): boolean { return this._started; }
onStart(fn: () => void): void {
this._onStartFns.push(fn);
}
onDone(fn: () => void): void {
this._onDoneFns.push(fn);
}
onDestroy(fn: () => void): void {
this._onDestroyFns.push(fn);
}
hasStarted(): boolean {
return this._started;
}
init(): void {}
play(): void {
if (!this.hasStarted()) {
@ -146,7 +158,9 @@ export class NoopAnimationPlayer implements AnimationPlayer {
}
/** @internal */
triggerMicrotask() { scheduleMicroTask(() => this._onFinish()); }
triggerMicrotask() {
scheduleMicroTask(() => this._onFinish());
}
private _onStart() {
this._onStartFns.forEach(fn => fn());
@ -155,7 +169,9 @@ export class NoopAnimationPlayer implements AnimationPlayer {
pause(): void {}
restart(): void {}
finish(): void { this._onFinish(); }
finish(): void {
this._onFinish();
}
destroy(): void {
if (!this._destroyed) {
this._destroyed = true;
@ -169,7 +185,9 @@ export class NoopAnimationPlayer implements AnimationPlayer {
}
reset(): void {}
setPosition(position: number): void {}
getPosition(): number { return 0; }
getPosition(): number {
return 0;
}
/** @internal */
triggerCallback(phaseName: string): void {

View File

@ -69,7 +69,9 @@ import {scheduleMicroTask} from '../src/util';
const log: string[] = [];
const player = new NoopAnimationPlayer();
player.onStart(() => { scheduleMicroTask(() => log.push('started')); });
player.onStart(() => {
scheduleMicroTask(() => log.push('started'));
});
player.onDone(() => log.push('done'));
expect(log).toEqual([]);