angular2
Version:
Angular 2 - a web framework for modern web apps
155 lines (154 loc) • 7.12 kB
JavaScript
import { isPresent, isBlank } from 'angular2/src/facade/lang';
import { ListWrapper } from 'angular2/src/facade/collection';
import * as o from '../output/output_ast';
import { EventHandlerVars } from './constants';
import { CompileQuery, createQueryList, addQueryToTokenMap } from './compile_query';
import { CompileMethod } from './compile_method';
import { CompilePipe } from './compile_pipe';
import { ViewType } from 'angular2/src/core/linker/view_type';
import { CompileIdentifierMetadata, CompileTokenMap } from '../compile_metadata';
import { getViewFactoryName, getPropertyInView, createPureProxy } from './util';
export class CompileView {
constructor(component, genConfig, pipeMetas, styles, viewIndex, declarationElement, templateVariableBindings) {
this.component = component;
this.genConfig = genConfig;
this.pipeMetas = pipeMetas;
this.styles = styles;
this.viewIndex = viewIndex;
this.declarationElement = declarationElement;
this.templateVariableBindings = templateVariableBindings;
this.nodes = [];
// root nodes or AppElements for ViewContainers
this.rootNodesOrAppElements = [];
this.bindings = [];
this.classStatements = [];
this.eventHandlerMethods = [];
this.fields = [];
this.getters = [];
this.disposables = [];
this.subscriptions = [];
this.purePipes = new Map();
this.pipes = [];
this.locals = new Map();
this.literalArrayCount = 0;
this.literalMapCount = 0;
this.pipeCount = 0;
this.createMethod = new CompileMethod(this);
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);
this.detectChangesRenderPropertiesMethod = new CompileMethod(this);
this.afterContentLifecycleCallbacksMethod = new CompileMethod(this);
this.afterViewLifecycleCallbacksMethod = new CompileMethod(this);
this.destroyMethod = new CompileMethod(this);
this.viewType = getViewType(component, viewIndex);
this.className = `_View_${component.type.name}${viewIndex}`;
this.classType = o.importType(new CompileIdentifierMetadata({ name: this.className }));
this.viewFactory = o.variable(getViewFactoryName(component, viewIndex));
if (this.viewType === ViewType.COMPONENT || this.viewType === ViewType.HOST) {
this.componentView = this;
}
else {
this.componentView = this.declarationElement.view.componentView;
}
var viewQueries = new CompileTokenMap();
if (this.viewType === ViewType.COMPONENT) {
var directiveInstance = o.THIS_EXPR.prop('context');
ListWrapper.forEachWithIndex(this.component.viewQueries, (queryMeta, queryIndex) => {
var propName = `_viewQuery_${queryMeta.selectors[0].name}_${queryIndex}`;
var queryList = createQueryList(queryMeta, directiveInstance, propName, this);
var query = new CompileQuery(queryMeta, queryList, directiveInstance, this);
addQueryToTokenMap(viewQueries, query);
});
var constructorViewQueryCount = 0;
this.component.type.diDeps.forEach((dep) => {
if (isPresent(dep.viewQuery)) {
var queryList = o.THIS_EXPR.prop('declarationAppElement')
.prop('componentConstructorViewQueries')
.key(o.literal(constructorViewQueryCount++));
var query = new CompileQuery(dep.viewQuery, queryList, null, this);
addQueryToTokenMap(viewQueries, query);
}
});
}
this.viewQueries = viewQueries;
templateVariableBindings.forEach((entry) => {
this.locals.set(entry[1], o.THIS_EXPR.prop('locals').key(o.literal(entry[0])));
});
if (!this.declarationElement.isNull()) {
this.declarationElement.setEmbeddedView(this);
}
}
callPipe(name, input, args) {
var compView = this.componentView;
var pipe = compView.purePipes.get(name);
if (isBlank(pipe)) {
pipe = new CompilePipe(compView, name);
if (pipe.pure) {
compView.purePipes.set(name, pipe);
}
compView.pipes.push(pipe);
}
return pipe.call(this, [input].concat(args));
}
getLocal(name) {
if (name == EventHandlerVars.event.name) {
return EventHandlerVars.event;
}
var currView = this;
var result = currView.locals.get(name);
while (isBlank(result) && isPresent(currView.declarationElement.view)) {
currView = currView.declarationElement.view;
result = currView.locals.get(name);
}
if (isPresent(result)) {
return getPropertyInView(result, this, currView);
}
else {
return null;
}
}
createLiteralArray(values) {
var proxyExpr = o.THIS_EXPR.prop(`_arr_${this.literalArrayCount++}`);
var proxyParams = [];
var proxyReturnEntries = [];
for (var i = 0; i < values.length; i++) {
var paramName = `p${i}`;
proxyParams.push(new o.FnParam(paramName));
proxyReturnEntries.push(o.variable(paramName));
}
createPureProxy(o.fn(proxyParams, [new o.ReturnStatement(o.literalArr(proxyReturnEntries))]), values.length, proxyExpr, this);
return proxyExpr.callFn(values);
}
createLiteralMap(entries) {
var proxyExpr = o.THIS_EXPR.prop(`_map_${this.literalMapCount++}`);
var proxyParams = [];
var proxyReturnEntries = [];
var values = [];
for (var i = 0; i < entries.length; i++) {
var paramName = `p${i}`;
proxyParams.push(new o.FnParam(paramName));
proxyReturnEntries.push([entries[i][0], o.variable(paramName)]);
values.push(entries[i][1]);
}
createPureProxy(o.fn(proxyParams, [new o.ReturnStatement(o.literalMap(proxyReturnEntries))]), entries.length, proxyExpr, this);
return proxyExpr.callFn(values);
}
afterNodes() {
this.pipes.forEach((pipe) => pipe.create());
this.viewQueries.values().forEach((queries) => queries.forEach((query) => query.afterChildren(this.updateViewQueriesMethod)));
}
}
function getViewType(component, embeddedTemplateIndex) {
if (embeddedTemplateIndex > 0) {
return ViewType.EMBEDDED;
}
else if (component.type.isHost) {
return ViewType.HOST;
}
else {
return ViewType.COMPONENT;
}
}