@ -27,6 +27,8 @@ import {CompilerConfig} from '../config';
|
||||
import {CompileBinding} from './compile_binding';
|
||||
import {Identifiers} from '../identifiers';
|
||||
|
||||
import {CompiledAnimation} from '../animation/animation_compiler';
|
||||
|
||||
export class CompileView implements NameResolver {
|
||||
public viewType: ViewType;
|
||||
public viewQueries: CompileTokenMap<CompileQuery[]>;
|
||||
@ -48,6 +50,7 @@ export class CompileView implements NameResolver {
|
||||
public afterContentLifecycleCallbacksMethod: CompileMethod;
|
||||
public afterViewLifecycleCallbacksMethod: CompileMethod;
|
||||
public destroyMethod: CompileMethod;
|
||||
public detachMethod: CompileMethod;
|
||||
public eventHandlerMethods: o.ClassMethod[] = [];
|
||||
|
||||
public fields: o.ClassField[] = [];
|
||||
@ -66,13 +69,17 @@ export class CompileView implements NameResolver {
|
||||
public literalArrayCount = 0;
|
||||
public literalMapCount = 0;
|
||||
public pipeCount = 0;
|
||||
public animations = new Map<string, CompiledAnimation>();
|
||||
|
||||
public componentContext: o.Expression;
|
||||
|
||||
constructor(public component: CompileDirectiveMetadata, public genConfig: CompilerConfig,
|
||||
public pipeMetas: CompilePipeMetadata[], public styles: o.Expression,
|
||||
public pipeMetas: CompilePipeMetadata[],
|
||||
public styles: o.Expression,
|
||||
animations: CompiledAnimation[],
|
||||
public viewIndex: number, public declarationElement: CompileElement,
|
||||
public templateVariableBindings: string[][]) {
|
||||
animations.forEach(entry => this.animations.set(entry.name, entry));
|
||||
this.createMethod = new CompileMethod(this);
|
||||
this.injectorGetMethod = new CompileMethod(this);
|
||||
this.updateContentQueriesMethod = new CompileMethod(this);
|
||||
@ -84,6 +91,7 @@ export class CompileView implements NameResolver {
|
||||
this.afterContentLifecycleCallbacksMethod = new CompileMethod(this);
|
||||
this.afterViewLifecycleCallbacksMethod = new CompileMethod(this);
|
||||
this.destroyMethod = new CompileMethod(this);
|
||||
this.detachMethod = new CompileMethod(this);
|
||||
|
||||
this.viewType = getViewType(component, viewIndex);
|
||||
this.className = `_View_${component.type.name}${viewIndex}`;
|
||||
|
@ -1,5 +1,5 @@
|
||||
import {SecurityContext} from '../../core_private';
|
||||
import {LifecycleHooks, isDefaultChangeDetectionStrategy} from '../../core_private';
|
||||
import {EMPTY_STATE as EMPTY_ANIMATION_STATE, LifecycleHooks, isDefaultChangeDetectionStrategy} from '../../core_private';
|
||||
|
||||
import {isBlank, isPresent} from '../../src/facade/lang';
|
||||
|
||||
@ -24,6 +24,7 @@ import {camelCaseToDashCase} from '../util';
|
||||
import {convertCdExpressionToIr} from './expression_converter';
|
||||
|
||||
import {CompileBinding} from './compile_binding';
|
||||
import {BaseException} from '@angular/core';
|
||||
|
||||
|
||||
function createBindFieldExpr(exprIndex: number): o.ReadPropExpr {
|
||||
@ -95,36 +96,92 @@ function bindAndWriteToRenderer(boundProps: BoundElementPropertyAst[], context:
|
||||
var fieldExpr = createBindFieldExpr(bindingIndex);
|
||||
var currValExpr = createCurrValueExpr(bindingIndex);
|
||||
var renderMethod: string;
|
||||
var oldRenderValue: o.Expression = sanitizedValue(boundProp, fieldExpr);
|
||||
var renderValue: o.Expression = sanitizedValue(boundProp, currValExpr);
|
||||
var updateStmts = [];
|
||||
switch (boundProp.type) {
|
||||
case PropertyBindingType.Property:
|
||||
renderMethod = 'setElementProperty';
|
||||
if (view.genConfig.logBindingUpdate) {
|
||||
updateStmts.push(logBindingUpdateStmt(renderNode, boundProp.name, currValExpr));
|
||||
updateStmts.push(logBindingUpdateStmt(renderNode, boundProp.name, renderValue));
|
||||
}
|
||||
updateStmts.push(
|
||||
o.THIS_EXPR.prop('renderer')
|
||||
.callMethod('setElementProperty', [renderNode, o.literal(boundProp.name), renderValue])
|
||||
.toStmt()
|
||||
);
|
||||
break;
|
||||
case PropertyBindingType.Attribute:
|
||||
renderMethod = 'setElementAttribute';
|
||||
renderValue =
|
||||
renderValue.isBlank().conditional(o.NULL_EXPR, renderValue.callMethod('toString', []));
|
||||
renderValue = renderValue.isBlank().conditional(o.NULL_EXPR, renderValue.callMethod('toString', []));
|
||||
updateStmts.push(
|
||||
o.THIS_EXPR.prop('renderer')
|
||||
.callMethod('setElementAttribute', [renderNode, o.literal(boundProp.name), renderValue])
|
||||
.toStmt()
|
||||
);
|
||||
break;
|
||||
case PropertyBindingType.Class:
|
||||
renderMethod = 'setElementClass';
|
||||
updateStmts.push(
|
||||
o.THIS_EXPR.prop('renderer')
|
||||
.callMethod('setElementClass', [renderNode, o.literal(boundProp.name), renderValue])
|
||||
.toStmt()
|
||||
);
|
||||
break;
|
||||
case PropertyBindingType.Style:
|
||||
renderMethod = 'setElementStyle';
|
||||
var strValue: o.Expression = renderValue.callMethod('toString', []);
|
||||
if (isPresent(boundProp.unit)) {
|
||||
strValue = strValue.plus(o.literal(boundProp.unit));
|
||||
}
|
||||
renderValue = renderValue.isBlank().conditional(o.NULL_EXPR, strValue);
|
||||
updateStmts.push(
|
||||
o.THIS_EXPR.prop('renderer')
|
||||
.callMethod('setElementStyle', [renderNode, o.literal(boundProp.name), renderValue])
|
||||
.toStmt()
|
||||
);
|
||||
break;
|
||||
case PropertyBindingType.Animation:
|
||||
var animationName = boundProp.name;
|
||||
var animation = view.componentView.animations.get(animationName);
|
||||
if (!isPresent(animation)) {
|
||||
throw new BaseException(`Internal Error: couldn't find an animation entry for ${boundProp.name}`);
|
||||
}
|
||||
|
||||
// it's important to normalize the void value as `void` explicitly
|
||||
// so that the styles data can be obtained from the stringmap
|
||||
var emptyStateValue = o.literal(EMPTY_ANIMATION_STATE);
|
||||
|
||||
// void => ...
|
||||
var oldRenderVar = o.variable('oldRenderVar');
|
||||
updateStmts.push(oldRenderVar.set(oldRenderValue).toDeclStmt());
|
||||
updateStmts.push(
|
||||
new o.IfStmt(oldRenderVar.equals(o.importExpr(Identifiers.uninitialized)), [
|
||||
oldRenderVar.set(emptyStateValue).toStmt()
|
||||
]));
|
||||
|
||||
// ... => void
|
||||
var newRenderVar = o.variable('newRenderVar');
|
||||
updateStmts.push(newRenderVar.set(renderValue).toDeclStmt());
|
||||
updateStmts.push(
|
||||
new o.IfStmt(newRenderVar.equals(o.importExpr(Identifiers.uninitialized)), [
|
||||
newRenderVar.set(emptyStateValue).toStmt()
|
||||
]));
|
||||
|
||||
updateStmts.push(
|
||||
animation.fnVariable.callFn([
|
||||
o.THIS_EXPR,
|
||||
renderNode,
|
||||
oldRenderVar,
|
||||
newRenderVar
|
||||
]).toStmt());
|
||||
|
||||
view.detachMethod.addStmt(
|
||||
animation.fnVariable.callFn([
|
||||
o.THIS_EXPR,
|
||||
renderNode,
|
||||
oldRenderValue,
|
||||
emptyStateValue
|
||||
]).toStmt());
|
||||
|
||||
break;
|
||||
}
|
||||
updateStmts.push(
|
||||
o.THIS_EXPR.prop('renderer')
|
||||
.callMethod(renderMethod, [renderNode, o.literal(boundProp.name), renderValue])
|
||||
.toStmt());
|
||||
|
||||
bind(view, currValExpr, fieldExpr, boundProp.value, context, updateStmts,
|
||||
view.detectChangesRenderPropertiesMethod);
|
||||
|
@ -45,6 +45,8 @@ import {
|
||||
CompileTokenMetadata
|
||||
} from '../compile_metadata';
|
||||
|
||||
import {AnimationCompiler} from '../animation/animation_compiler';
|
||||
|
||||
const IMPLICIT_TEMPLATE_VAR = '\$implicit';
|
||||
const CLASS_ATTR = 'class';
|
||||
const STYLE_ATTR = 'style';
|
||||
@ -79,6 +81,8 @@ export function finishView(view: CompileView, targetStatements: o.Statement[]) {
|
||||
class ViewBuilderVisitor implements TemplateAstVisitor {
|
||||
nestedViewCount: number = 0;
|
||||
|
||||
private _animationCompiler = new AnimationCompiler();
|
||||
|
||||
constructor(public view: CompileView, public targetDependencies: ViewCompileDependency[]) {}
|
||||
|
||||
private _isRootNode(parent: CompileElement): boolean { return parent.view !== this.view; }
|
||||
@ -270,9 +274,11 @@ class ViewBuilderVisitor implements TemplateAstVisitor {
|
||||
ast.providers, ast.hasViewContainer, true, ast.references);
|
||||
this.view.nodes.push(compileElement);
|
||||
|
||||
var compiledAnimations = this._animationCompiler.compileComponent(this.view.component);
|
||||
|
||||
this.nestedViewCount++;
|
||||
var embeddedView = new CompileView(
|
||||
this.view.component, this.view.genConfig, this.view.pipeMetas, o.NULL_EXPR,
|
||||
this.view.component, this.view.genConfig, this.view.pipeMetas, o.NULL_EXPR, compiledAnimations,
|
||||
this.view.viewIndex + this.nestedViewCount, compileElement, templateVariableBindings);
|
||||
this.nestedViewCount += buildView(embeddedView, ast.children, this.targetDependencies);
|
||||
|
||||
@ -423,7 +429,8 @@ function createViewClass(view: CompileView, renderCompTypeVar: o.ReadVarExpr,
|
||||
[new o.FnParam(DetectChangesVars.throwOnChange.name, o.BOOL_TYPE)],
|
||||
generateDetectChangesMethod(view)),
|
||||
new o.ClassMethod('dirtyParentQueriesInternal', [], view.dirtyParentQueriesMethod.finish()),
|
||||
new o.ClassMethod('destroyInternal', [], view.destroyMethod.finish())
|
||||
new o.ClassMethod('destroyInternal', [], view.destroyMethod.finish()),
|
||||
new o.ClassMethod('detachInternal', [], view.detachMethod.finish())
|
||||
].concat(view.eventHandlerMethods);
|
||||
var superClass = view.genConfig.genDebugInfo ? Identifiers.DebugAppView : Identifiers.AppView;
|
||||
var viewClass = new o.ClassStmt(view.className, o.importExpr(superClass, [getContextType(view)]),
|
||||
|
@ -8,6 +8,8 @@ import {CompileDirectiveMetadata, CompilePipeMetadata} from '../compile_metadata
|
||||
import {TemplateAst} from '../template_ast';
|
||||
import {CompilerConfig} from '../config';
|
||||
|
||||
import {AnimationCompiler} from '../animation/animation_compiler';
|
||||
|
||||
export class ViewCompileResult {
|
||||
constructor(public statements: o.Statement[], public viewFactoryVar: string,
|
||||
public dependencies: ViewCompileDependency[]) {}
|
||||
@ -15,13 +17,19 @@ export class ViewCompileResult {
|
||||
|
||||
@Injectable()
|
||||
export class ViewCompiler {
|
||||
private _animationCompiler = new AnimationCompiler();
|
||||
constructor(private _genConfig: CompilerConfig) {}
|
||||
|
||||
compileComponent(component: CompileDirectiveMetadata, template: TemplateAst[],
|
||||
styles: o.Expression, pipes: CompilePipeMetadata[]): ViewCompileResult {
|
||||
var statements = [];
|
||||
var dependencies = [];
|
||||
var view = new CompileView(component, this._genConfig, pipes, styles, 0,
|
||||
var compiledAnimations = this._animationCompiler.compileComponent(component);
|
||||
var statements = [];
|
||||
compiledAnimations.map(entry => {
|
||||
statements.push(entry.statesMapStatement);
|
||||
statements.push(entry.fnStatement);
|
||||
});
|
||||
var view = new CompileView(component, this._genConfig, pipes, styles, compiledAnimations, 0,
|
||||
CompileElement.createNull(), []);
|
||||
buildView(view, template, dependencies);
|
||||
// Need to separate binding from creation to be able to refer to
|
||||
|
Reference in New Issue
Block a user