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; }
|
|
|
|
}
|