| 
									
										
										
										
											2016-06-23 09:47:54 -07:00
										 |  |  | /** | 
					
						
							|  |  |  |  * @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
 | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2016-08-22 17:18:25 -07:00
										 |  |  | import {AnimationOutput} from '../../core_private'; | 
					
						
							| 
									
										
										
										
											2016-08-02 15:53:34 -07:00
										 |  |  | import {ListWrapper} from '../facade/collection'; | 
					
						
							| 
									
										
										
										
											2016-08-02 01:37:42 -07:00
										 |  |  | import {identifierToken} from '../identifiers'; | 
					
						
							| 
									
										
										
										
											2016-08-02 15:53:34 -07:00
										 |  |  | import {AttrAst, BoundDirectivePropertyAst, BoundElementPropertyAst, BoundEventAst, BoundTextAst, DirectiveAst, ElementAst, EmbeddedTemplateAst, NgContentAst, ReferenceAst, TemplateAst, TemplateAstVisitor, TextAst, VariableAst, templateVisitAll} from '../template_parser/template_ast'; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import {CompileElement, CompileNode} from './compile_element'; | 
					
						
							|  |  |  | import {CompileView} from './compile_view'; | 
					
						
							| 
									
										
										
										
											2016-08-22 17:18:25 -07:00
										 |  |  | import {CompileElementAnimationOutput, CompileEventListener, bindAnimationOutputs, bindDirectiveOutputs, bindRenderOutputs, collectEventListeners} from './event_binder'; | 
					
						
							| 
									
										
										
										
											2016-08-02 15:53:34 -07:00
										 |  |  | import {bindDirectiveAfterContentLifecycleCallbacks, bindDirectiveAfterViewLifecycleCallbacks, bindDirectiveDetectChangesLifecycleCallbacks, bindInjectableDestroyLifecycleCallbacks, bindPipeDestroyLifecycleCallbacks} from './lifecycle_binder'; | 
					
						
							|  |  |  | import {bindDirectiveHostProps, bindDirectiveInputs, bindRenderInputs, bindRenderText} from './property_binder'; | 
					
						
							| 
									
										
										
										
											2016-01-06 14:13:44 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-22 17:18:25 -07:00
										 |  |  | export function bindView( | 
					
						
							|  |  |  |     view: CompileView, parsedTemplate: TemplateAst[], animationOutputs: AnimationOutput[]): void { | 
					
						
							|  |  |  |   var visitor = new ViewBinderVisitor(view, animationOutputs); | 
					
						
							| 
									
										
										
										
											2016-01-06 14:13:44 -08:00
										 |  |  |   templateVisitAll(visitor, parsedTemplate); | 
					
						
							| 
									
										
										
										
											2016-04-22 15:33:32 -07:00
										 |  |  |   view.pipes.forEach( | 
					
						
							|  |  |  |       (pipe) => { bindPipeDestroyLifecycleCallbacks(pipe.meta, pipe.instance, pipe.view); }); | 
					
						
							| 
									
										
										
										
											2016-01-06 14:13:44 -08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class ViewBinderVisitor implements TemplateAstVisitor { | 
					
						
							|  |  |  |   private _nodeIndex: number = 0; | 
					
						
							| 
									
										
										
										
											2016-08-22 17:18:25 -07:00
										 |  |  |   private _animationOutputsMap: {[key: string]: AnimationOutput} = {}; | 
					
						
							| 
									
										
										
										
											2016-01-06 14:13:44 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-22 17:18:25 -07:00
										 |  |  |   constructor(public view: CompileView, animationOutputs: AnimationOutput[]) { | 
					
						
							|  |  |  |     animationOutputs.forEach( | 
					
						
							|  |  |  |         entry => { this._animationOutputsMap[entry.fullPropertyName] = entry; }); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2016-01-06 14:13:44 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   visitBoundText(ast: BoundTextAst, parent: CompileElement): any { | 
					
						
							|  |  |  |     var node = this.view.nodes[this._nodeIndex++]; | 
					
						
							|  |  |  |     bindRenderText(ast, node, this.view); | 
					
						
							|  |  |  |     return null; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   visitText(ast: TextAst, parent: CompileElement): any { | 
					
						
							|  |  |  |     this._nodeIndex++; | 
					
						
							|  |  |  |     return null; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   visitNgContent(ast: NgContentAst, parent: CompileElement): any { return null; } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   visitElement(ast: ElementAst, parent: CompileElement): any { | 
					
						
							|  |  |  |     var compileElement = <CompileElement>this.view.nodes[this._nodeIndex++]; | 
					
						
							| 
									
										
										
										
											2016-08-22 17:18:25 -07:00
										 |  |  |     var eventListeners: CompileEventListener[] = []; | 
					
						
							|  |  |  |     var animationEventListeners: CompileElementAnimationOutput[] = []; | 
					
						
							|  |  |  |     collectEventListeners(ast.outputs, ast.directives, compileElement).forEach(entry => { | 
					
						
							|  |  |  |       // TODO: figure out how to abstract this `if` statement elsewhere
 | 
					
						
							|  |  |  |       if (entry.eventName[0] == '@') { | 
					
						
							|  |  |  |         let animationOutputName = entry.eventName.substr(1); | 
					
						
							|  |  |  |         let output = this._animationOutputsMap[animationOutputName]; | 
					
						
							|  |  |  |         // no need to report an error here since the parser will
 | 
					
						
							|  |  |  |         // have caught the missing animation trigger definition
 | 
					
						
							|  |  |  |         if (output) { | 
					
						
							|  |  |  |           animationEventListeners.push(new CompileElementAnimationOutput(entry, output)); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       } else { | 
					
						
							|  |  |  |         eventListeners.push(entry); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  |     bindAnimationOutputs(animationEventListeners); | 
					
						
							| 
									
										
										
										
											2016-01-06 14:13:44 -08:00
										 |  |  |     bindRenderInputs(ast.inputs, compileElement); | 
					
						
							|  |  |  |     bindRenderOutputs(eventListeners); | 
					
						
							| 
									
										
										
										
											2016-08-02 01:37:42 -07:00
										 |  |  |     ast.directives.forEach((directiveAst) => { | 
					
						
							| 
									
										
										
										
											2016-08-29 08:52:25 -07:00
										 |  |  |       var directiveInstance = compileElement.instances.get(directiveAst.directive.type.reference); | 
					
						
							| 
									
										
										
										
											2016-01-06 14:13:44 -08:00
										 |  |  |       bindDirectiveInputs(directiveAst, directiveInstance, compileElement); | 
					
						
							|  |  |  |       bindDirectiveDetectChangesLifecycleCallbacks(directiveAst, directiveInstance, compileElement); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       bindDirectiveHostProps(directiveAst, directiveInstance, compileElement); | 
					
						
							|  |  |  |       bindDirectiveOutputs(directiveAst, directiveInstance, eventListeners); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  |     templateVisitAll(this, ast.children, compileElement); | 
					
						
							|  |  |  |     // afterContent and afterView lifecycles need to be called bottom up
 | 
					
						
							|  |  |  |     // so that children are notified before parents
 | 
					
						
							| 
									
										
										
										
											2016-08-02 01:37:42 -07:00
										 |  |  |     ast.directives.forEach((directiveAst) => { | 
					
						
							| 
									
										
										
										
											2016-08-29 08:52:25 -07:00
										 |  |  |       var directiveInstance = compileElement.instances.get(directiveAst.directive.type.reference); | 
					
						
							| 
									
										
										
										
											2016-06-08 16:38:52 -07:00
										 |  |  |       bindDirectiveAfterContentLifecycleCallbacks( | 
					
						
							|  |  |  |           directiveAst.directive, directiveInstance, compileElement); | 
					
						
							|  |  |  |       bindDirectiveAfterViewLifecycleCallbacks( | 
					
						
							|  |  |  |           directiveAst.directive, directiveInstance, compileElement); | 
					
						
							| 
									
										
										
										
											2016-08-02 01:37:42 -07:00
										 |  |  |     }); | 
					
						
							|  |  |  |     ast.providers.forEach((providerAst) => { | 
					
						
							| 
									
										
										
										
											2016-08-29 08:52:25 -07:00
										 |  |  |       var providerInstance = compileElement.instances.get(providerAst.token.reference); | 
					
						
							| 
									
										
										
										
											2016-08-02 01:37:42 -07:00
										 |  |  |       bindInjectableDestroyLifecycleCallbacks(providerAst, providerInstance, compileElement); | 
					
						
							| 
									
										
										
										
											2016-01-06 14:13:44 -08:00
										 |  |  |     }); | 
					
						
							|  |  |  |     return null; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   visitEmbeddedTemplate(ast: EmbeddedTemplateAst, parent: CompileElement): any { | 
					
						
							|  |  |  |     var compileElement = <CompileElement>this.view.nodes[this._nodeIndex++]; | 
					
						
							|  |  |  |     var eventListeners = collectEventListeners(ast.outputs, ast.directives, compileElement); | 
					
						
							| 
									
										
										
										
											2016-08-02 01:37:42 -07:00
										 |  |  |     ast.directives.forEach((directiveAst) => { | 
					
						
							| 
									
										
										
										
											2016-08-29 08:52:25 -07:00
										 |  |  |       var directiveInstance = compileElement.instances.get(directiveAst.directive.type.reference); | 
					
						
							| 
									
										
										
										
											2016-01-06 14:13:44 -08:00
										 |  |  |       bindDirectiveInputs(directiveAst, directiveInstance, compileElement); | 
					
						
							|  |  |  |       bindDirectiveDetectChangesLifecycleCallbacks(directiveAst, directiveInstance, compileElement); | 
					
						
							|  |  |  |       bindDirectiveOutputs(directiveAst, directiveInstance, eventListeners); | 
					
						
							| 
									
										
										
										
											2016-06-08 16:38:52 -07:00
										 |  |  |       bindDirectiveAfterContentLifecycleCallbacks( | 
					
						
							|  |  |  |           directiveAst.directive, directiveInstance, compileElement); | 
					
						
							|  |  |  |       bindDirectiveAfterViewLifecycleCallbacks( | 
					
						
							|  |  |  |           directiveAst.directive, directiveInstance, compileElement); | 
					
						
							| 
									
										
										
										
											2016-08-02 01:37:42 -07:00
										 |  |  |     }); | 
					
						
							|  |  |  |     ast.providers.forEach((providerAst) => { | 
					
						
							| 
									
										
										
										
											2016-08-29 08:52:25 -07:00
										 |  |  |       var providerInstance = compileElement.instances.get(providerAst.token.reference); | 
					
						
							| 
									
										
										
										
											2016-08-02 01:37:42 -07:00
										 |  |  |       bindInjectableDestroyLifecycleCallbacks(providerAst, providerInstance, compileElement); | 
					
						
							| 
									
										
										
										
											2016-01-06 14:13:44 -08:00
										 |  |  |     }); | 
					
						
							| 
									
										
										
										
											2016-08-22 17:18:25 -07:00
										 |  |  |     bindView(compileElement.embeddedView, ast.children, []); | 
					
						
							| 
									
										
										
										
											2016-01-06 14:13:44 -08:00
										 |  |  |     return null; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   visitAttr(ast: AttrAst, ctx: any): any { return null; } | 
					
						
							|  |  |  |   visitDirective(ast: DirectiveAst, ctx: any): any { return null; } | 
					
						
							|  |  |  |   visitEvent(ast: BoundEventAst, eventTargetAndNames: Map<string, BoundEventAst>): any { | 
					
						
							|  |  |  |     return null; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-25 19:52:24 -07:00
										 |  |  |   visitReference(ast: ReferenceAst, ctx: any): any { return null; } | 
					
						
							| 
									
										
										
										
											2016-01-06 14:13:44 -08:00
										 |  |  |   visitVariable(ast: VariableAst, ctx: any): any { return null; } | 
					
						
							|  |  |  |   visitDirectiveProperty(ast: BoundDirectivePropertyAst, context: any): any { return null; } | 
					
						
							|  |  |  |   visitElementProperty(ast: BoundElementPropertyAst, context: any): any { return null; } | 
					
						
							|  |  |  | } |