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-09-23 16:37:04 -04:00
|
|
|
import {AnimationEntryCompileResult} from '../animation/animation_compiler';
|
2016-11-10 16:27:53 -08:00
|
|
|
import {CompileDirectiveMetadata, CompileIdentifierMetadata, CompilePipeSummary} from '../compile_metadata';
|
2016-10-19 13:18:33 -07:00
|
|
|
import {EventHandlerVars, NameResolver} from '../compiler_util/expression_converter';
|
|
|
|
import {createPureProxy} from '../compiler_util/identifier_util';
|
2016-06-08 16:38:52 -07:00
|
|
|
import {CompilerConfig} from '../config';
|
2016-09-30 09:26:53 -07:00
|
|
|
import {isPresent} from '../facade/lang';
|
2016-08-24 17:39:49 -07:00
|
|
|
import {Identifiers, resolveIdentifier} from '../identifiers';
|
2016-01-06 14:13:44 -08:00
|
|
|
import * as o from '../output/output_ast';
|
2016-08-30 18:07:40 -07:00
|
|
|
import {ViewType} from '../private_import_core';
|
2016-06-08 16:38:52 -07:00
|
|
|
|
2016-01-06 14:13:44 -08:00
|
|
|
import {CompileElement, CompileNode} from './compile_element';
|
|
|
|
import {CompileMethod} from './compile_method';
|
2016-04-22 15:33:32 -07:00
|
|
|
import {CompilePipe} from './compile_pipe';
|
2016-06-08 16:38:52 -07:00
|
|
|
import {CompileQuery, addQueryToTokenMap, createQueryList} from './compile_query';
|
2016-11-02 08:36:23 -07:00
|
|
|
import {getPropertyInView, getViewClassName} from './util';
|
2016-05-25 12:46:22 -07:00
|
|
|
|
2016-10-31 14:41:16 -07:00
|
|
|
export enum CompileViewRootNodeType {
|
|
|
|
Node,
|
|
|
|
ViewContainer,
|
|
|
|
NgContent
|
|
|
|
}
|
|
|
|
|
|
|
|
export class CompileViewRootNode {
|
|
|
|
constructor(
|
|
|
|
public type: CompileViewRootNodeType, public expr: o.Expression,
|
|
|
|
public ngContentIndex?: number) {}
|
|
|
|
}
|
|
|
|
|
2016-10-19 13:18:33 -07:00
|
|
|
export class CompileView implements NameResolver {
|
2016-01-06 14:13:44 -08:00
|
|
|
public viewType: ViewType;
|
2016-08-29 08:52:25 -07:00
|
|
|
public viewQueries: Map<any, CompileQuery[]>;
|
2016-01-06 14:13:44 -08:00
|
|
|
|
2016-10-31 10:10:13 -07:00
|
|
|
public viewChildren: o.Expression[] = [];
|
|
|
|
|
2016-01-06 14:13:44 -08:00
|
|
|
public nodes: CompileNode[] = [];
|
2016-10-31 14:41:16 -07:00
|
|
|
|
|
|
|
public rootNodes: CompileViewRootNode[] = [];
|
|
|
|
public lastRenderNode: o.Expression = o.NULL_EXPR;
|
|
|
|
|
2016-11-01 11:12:25 -07:00
|
|
|
public viewContainers: o.Expression[] = [];
|
2016-01-06 14:13:44 -08:00
|
|
|
|
|
|
|
public createMethod: CompileMethod;
|
2016-09-01 23:24:26 +03:00
|
|
|
public animationBindingsMethod: CompileMethod;
|
2016-01-06 14:13:44 -08:00
|
|
|
public injectorGetMethod: CompileMethod;
|
|
|
|
public updateContentQueriesMethod: CompileMethod;
|
|
|
|
public dirtyParentQueriesMethod: CompileMethod;
|
|
|
|
public updateViewQueriesMethod: CompileMethod;
|
|
|
|
public detectChangesInInputsMethod: CompileMethod;
|
2016-04-20 18:10:19 -07:00
|
|
|
public detectChangesRenderPropertiesMethod: CompileMethod;
|
2016-01-06 14:13:44 -08:00
|
|
|
public afterContentLifecycleCallbacksMethod: CompileMethod;
|
|
|
|
public afterViewLifecycleCallbacksMethod: CompileMethod;
|
|
|
|
public destroyMethod: CompileMethod;
|
2016-05-25 12:46:22 -07:00
|
|
|
public detachMethod: CompileMethod;
|
2016-10-21 13:37:51 -07:00
|
|
|
public methods: o.ClassMethod[] = [];
|
2016-01-06 14:13:44 -08:00
|
|
|
|
2016-10-21 13:37:51 -07:00
|
|
|
public ctorStmts: o.Statement[] = [];
|
2016-01-06 14:13:44 -08:00
|
|
|
public fields: o.ClassField[] = [];
|
|
|
|
public getters: o.ClassGetter[] = [];
|
|
|
|
public disposables: o.Expression[] = [];
|
|
|
|
|
|
|
|
public componentView: CompileView;
|
2016-04-22 15:33:32 -07:00
|
|
|
public purePipes = new Map<string, CompilePipe>();
|
|
|
|
public pipes: CompilePipe[] = [];
|
2016-04-25 19:52:24 -07:00
|
|
|
public locals = new Map<string, o.Expression>();
|
2016-01-06 14:13:44 -08:00
|
|
|
public className: string;
|
|
|
|
public classType: o.Type;
|
2016-11-02 08:36:23 -07:00
|
|
|
public classExpr: o.ReadVarExpr;
|
2016-01-06 14:13:44 -08:00
|
|
|
|
|
|
|
public literalArrayCount = 0;
|
|
|
|
public literalMapCount = 0;
|
2016-04-22 15:33:32 -07:00
|
|
|
public pipeCount = 0;
|
2016-01-06 14:13:44 -08:00
|
|
|
|
2016-04-28 14:00:31 -07:00
|
|
|
public componentContext: o.Expression;
|
|
|
|
|
2016-06-08 16:38:52 -07:00
|
|
|
constructor(
|
|
|
|
public component: CompileDirectiveMetadata, public genConfig: CompilerConfig,
|
2016-11-10 16:27:53 -08:00
|
|
|
public pipeMetas: CompilePipeSummary[], public styles: o.Expression,
|
2016-09-23 16:37:04 -04:00
|
|
|
public animations: AnimationEntryCompileResult[], public viewIndex: number,
|
2016-06-08 16:38:52 -07:00
|
|
|
public declarationElement: CompileElement, public templateVariableBindings: string[][]) {
|
2016-01-06 14:13:44 -08:00
|
|
|
this.createMethod = new CompileMethod(this);
|
2016-09-01 23:24:26 +03:00
|
|
|
this.animationBindingsMethod = new CompileMethod(this);
|
2016-01-06 14:13:44 -08:00
|
|
|
this.injectorGetMethod = new CompileMethod(this);
|
|
|
|
this.updateContentQueriesMethod = new CompileMethod(this);
|
|
|
|
this.dirtyParentQueriesMethod = new CompileMethod(this);
|
|
|
|
this.updateViewQueriesMethod = new CompileMethod(this);
|
|
|
|
this.detectChangesInInputsMethod = new CompileMethod(this);
|
2016-04-20 18:10:19 -07:00
|
|
|
this.detectChangesRenderPropertiesMethod = new CompileMethod(this);
|
2016-01-06 14:13:44 -08:00
|
|
|
|
|
|
|
this.afterContentLifecycleCallbacksMethod = new CompileMethod(this);
|
|
|
|
this.afterViewLifecycleCallbacksMethod = new CompileMethod(this);
|
|
|
|
this.destroyMethod = new CompileMethod(this);
|
2016-05-25 12:46:22 -07:00
|
|
|
this.detachMethod = new CompileMethod(this);
|
2016-01-06 14:13:44 -08:00
|
|
|
|
|
|
|
this.viewType = getViewType(component, viewIndex);
|
2016-11-02 08:36:23 -07:00
|
|
|
this.className = getViewClassName(component, viewIndex);
|
2016-01-06 14:13:44 -08:00
|
|
|
this.classType = o.importType(new CompileIdentifierMetadata({name: this.className}));
|
2016-11-02 08:36:23 -07:00
|
|
|
this.classExpr = o.variable(this.className);
|
2016-01-06 14:13:44 -08:00
|
|
|
if (this.viewType === ViewType.COMPONENT || this.viewType === ViewType.HOST) {
|
|
|
|
this.componentView = this;
|
|
|
|
} else {
|
|
|
|
this.componentView = this.declarationElement.view.componentView;
|
|
|
|
}
|
2016-04-28 14:00:31 -07:00
|
|
|
this.componentContext =
|
|
|
|
getPropertyInView(o.THIS_EXPR.prop('context'), this, this.componentView);
|
|
|
|
|
2016-11-12 14:08:58 +01:00
|
|
|
const viewQueries = new Map<any, CompileQuery[]>();
|
2016-01-06 14:13:44 -08:00
|
|
|
if (this.viewType === ViewType.COMPONENT) {
|
2016-11-12 14:08:58 +01:00
|
|
|
const directiveInstance = o.THIS_EXPR.prop('context');
|
2016-10-21 15:14:44 -07:00
|
|
|
this.component.viewQueries.forEach((queryMeta, queryIndex) => {
|
2016-11-12 14:08:58 +01:00
|
|
|
const propName = `_viewQuery_${queryMeta.selectors[0].name}_${queryIndex}`;
|
|
|
|
const queryList = createQueryList(queryMeta, directiveInstance, propName, this);
|
|
|
|
const query = new CompileQuery(queryMeta, queryList, directiveInstance, this);
|
2016-01-06 14:13:44 -08:00
|
|
|
addQueryToTokenMap(viewQueries, query);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
this.viewQueries = viewQueries;
|
2016-04-28 14:00:31 -07:00
|
|
|
templateVariableBindings.forEach(
|
|
|
|
(entry) => { this.locals.set(entry[1], o.THIS_EXPR.prop('context').prop(entry[0])); });
|
2016-01-06 14:13:44 -08:00
|
|
|
|
|
|
|
if (!this.declarationElement.isNull()) {
|
|
|
|
this.declarationElement.setEmbeddedView(this);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-04-22 15:33:32 -07:00
|
|
|
callPipe(name: string, input: o.Expression, args: o.Expression[]): o.Expression {
|
2016-05-03 08:59:25 -07:00
|
|
|
return CompilePipe.call(this, name, [input].concat(args));
|
2016-01-06 14:13:44 -08:00
|
|
|
}
|
|
|
|
|
2016-04-25 19:52:24 -07:00
|
|
|
getLocal(name: string): o.Expression {
|
2016-01-06 14:13:44 -08:00
|
|
|
if (name == EventHandlerVars.event.name) {
|
|
|
|
return EventHandlerVars.event;
|
|
|
|
}
|
2016-11-12 14:08:58 +01:00
|
|
|
let currView: CompileView = this;
|
|
|
|
let result = currView.locals.get(name);
|
2016-09-30 09:26:53 -07:00
|
|
|
while (!result && isPresent(currView.declarationElement.view)) {
|
2016-01-06 14:13:44 -08:00
|
|
|
currView = currView.declarationElement.view;
|
2016-04-25 19:52:24 -07:00
|
|
|
result = currView.locals.get(name);
|
2016-01-06 14:13:44 -08:00
|
|
|
}
|
|
|
|
if (isPresent(result)) {
|
2016-04-22 15:33:32 -07:00
|
|
|
return getPropertyInView(result, this, currView);
|
2016-01-06 14:13:44 -08:00
|
|
|
} else {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
afterNodes() {
|
2016-11-03 16:58:27 -07:00
|
|
|
Array.from(this.viewQueries.values())
|
2016-08-29 08:52:25 -07:00
|
|
|
.forEach(
|
2016-11-03 16:58:27 -07:00
|
|
|
queries => queries.forEach(
|
|
|
|
q => q.afterChildren(this.createMethod, this.updateViewQueriesMethod)));
|
2016-01-06 14:13:44 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function getViewType(component: CompileDirectiveMetadata, embeddedTemplateIndex: number): ViewType {
|
|
|
|
if (embeddedTemplateIndex > 0) {
|
|
|
|
return ViewType.EMBEDDED;
|
2016-11-03 16:58:27 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
if (component.type.isHost) {
|
2016-01-06 14:13:44 -08:00
|
|
|
return ViewType.HOST;
|
|
|
|
}
|
2016-11-03 16:58:27 -07:00
|
|
|
|
|
|
|
return ViewType.COMPONENT;
|
2016-01-06 14:13:44 -08:00
|
|
|
}
|