98 lines
		
	
	
		
			3.8 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
		
		
			
		
	
	
			98 lines
		
	
	
		
			3.8 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
|  | /** | ||
|  |  * @license | ||
|  |  * Copyright Google Inc. All Rights Reserved. | ||
|  |  * | ||
|  |  * Use of this source code is governed by an MIT-style license that can be | ||
|  |  * found in the LICENSE file at https://angular.io/license
 | ||
|  |  */ | ||
|  | import {AnimationMetadata, AnimationPlayer, AnimationTriggerMetadata} from '@angular/animations'; | ||
|  | 
 | ||
|  | import {AnimationEngine} from '../animation_engine'; | ||
|  | import {TriggerAst} from '../dsl/animation_ast'; | ||
|  | import {buildAnimationAst} from '../dsl/animation_ast_builder'; | ||
|  | import {AnimationTrigger, buildTrigger} from '../dsl/animation_trigger'; | ||
|  | import {AnimationStyleNormalizer} from '../dsl/style_normalization/animation_style_normalizer'; | ||
|  | 
 | ||
|  | import {AnimationDriver} from './animation_driver'; | ||
|  | import {parseTimelineCommand} from './shared'; | ||
|  | import {TimelineAnimationEngine} from './timeline_animation_engine'; | ||
|  | import {TransitionAnimationEngine} from './transition_animation_engine'; | ||
|  | 
 | ||
|  | export class DomAnimationEngine implements AnimationEngine { | ||
|  |   private _transitionEngine: TransitionAnimationEngine; | ||
|  |   private _timelineEngine: TimelineAnimationEngine; | ||
|  | 
 | ||
|  |   private _triggerCache: {[key: string]: AnimationTrigger} = {}; | ||
|  | 
 | ||
|  |   // this method is designed to be overridden by the code that uses this engine
 | ||
|  |   public onRemovalComplete = (element: any, context: any) => {}; | ||
|  | 
 | ||
|  |   constructor(driver: AnimationDriver, normalizer: AnimationStyleNormalizer) { | ||
|  |     this._transitionEngine = new TransitionAnimationEngine(driver, normalizer); | ||
|  |     this._timelineEngine = new TimelineAnimationEngine(driver, normalizer); | ||
|  | 
 | ||
|  |     this._transitionEngine.onRemovalComplete = | ||
|  |         (element: any, context: any) => { this.onRemovalComplete(element, context); } | ||
|  |   } | ||
|  | 
 | ||
|  |   registerTrigger( | ||
|  |       componentId: string, namespaceId: string, hostElement: any, name: string, | ||
|  |       metadata: AnimationTriggerMetadata): void { | ||
|  |     const cacheKey = componentId + '-' + name; | ||
|  |     let trigger = this._triggerCache[cacheKey]; | ||
|  |     if (!trigger) { | ||
|  |       const errors: any[] = []; | ||
|  |       const ast = buildAnimationAst(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 - ")}`); | ||
|  |       } | ||
|  |       trigger = buildTrigger(name, ast); | ||
|  |       this._triggerCache[cacheKey] = trigger; | ||
|  |     } | ||
|  | 
 | ||
|  |     this._transitionEngine.register(namespaceId, hostElement, name, trigger); | ||
|  |   } | ||
|  | 
 | ||
|  |   destroy(namespaceId: string, context: any) { | ||
|  |     this._transitionEngine.destroy(namespaceId, context); | ||
|  |   } | ||
|  | 
 | ||
|  |   onInsert(namespaceId: string, element: any, parent: any, insertBefore: boolean): void { | ||
|  |     this._transitionEngine.insertNode(namespaceId, element, parent, insertBefore); | ||
|  |   } | ||
|  | 
 | ||
|  |   onRemove(namespaceId: string, element: any, context: any): void { | ||
|  |     this._transitionEngine.removeNode(namespaceId, element, context); | ||
|  |   } | ||
|  | 
 | ||
|  |   setProperty(namespaceId: string, element: any, property: string, value: any): boolean { | ||
|  |     // @@property
 | ||
|  |     if (property.charAt(0) == '@') { | ||
|  |       const [id, action] = parseTimelineCommand(property); | ||
|  |       const args = value as any[]; | ||
|  |       this._timelineEngine.command(id, element, action, args); | ||
|  |       return false; | ||
|  |     } | ||
|  |     return this._transitionEngine.trigger(namespaceId, element, property, value); | ||
|  |   } | ||
|  | 
 | ||
|  |   listen( | ||
|  |       namespaceId: string, element: any, eventName: string, eventPhase: string, | ||
|  |       callback: (event: any) => any): () => any { | ||
|  |     // @@listen
 | ||
|  |     if (eventName.charAt(0) == '@') { | ||
|  |       const [id, action] = parseTimelineCommand(eventName); | ||
|  |       return this._timelineEngine.listen(id, element, action, callback); | ||
|  |     } | ||
|  |     return this._transitionEngine.listen(namespaceId, element, eventName, eventPhase, callback); | ||
|  |   } | ||
|  | 
 | ||
|  |   flush(): void { this._transitionEngine.flush(); } | ||
|  | 
 | ||
|  |   get players(): AnimationPlayer[] { | ||
|  |     return (this._transitionEngine.players as AnimationPlayer[]) | ||
|  |         .concat(this._timelineEngine.players as AnimationPlayer[]); | ||
|  |   } | ||
|  | } |