@@ -40,6 +40,7 @@ var CHANGES_LOCAL = "changes";
4040var LOCALS_ACCESSOR = "this.locals" ;
4141var MODE_ACCESSOR = "this.mode" ;
4242var TEMP_LOCAL = "temp" ;
43+ var CURRENT_PROTO = "currentProto" ;
4344
4445function typeTemplate ( type :string , cons :string , detectChanges :string ,
4546 notifyOnAllChangesDone :string , setContext :string ) :string {
@@ -113,58 +114,55 @@ function onAllChangesDoneTemplate(index:number):string {
113114}
114115
115116
116- function bodyTemplate ( localDefinitions :string , changeDefinitions :string , records :string ) :string {
117+ function detectChangesBodyTemplate ( localDefinitions :string , changeDefinitions :string , records :string ) :string {
117118 return `
118119${ localDefinitions }
119120${ changeDefinitions }
120121var ${ TEMP_LOCAL } ;
121122var ${ CHANGE_LOCAL } ;
123+ var ${ CURRENT_PROTO } ;
122124var ${ CHANGES_LOCAL } = null;
123125
124126context = ${ CONTEXT_ACCESSOR } ;
125127${ records }
126128` ;
127129}
128130
129- function notifyTemplate ( index :number ) :string {
130- return `
131- if (${ CHANGES_LOCAL } && ${ CHANGES_LOCAL } .length > 0) {
132- if(throwOnChange) ${ UTIL } .throwOnChange(${ PROTOS_ACCESSOR } [${ index } ], ${ CHANGES_LOCAL } [0]);
133- ${ DISPATCHER_ACCESSOR } .onRecordChange(${ PROTOS_ACCESSOR } [${ index } ].directiveMemento, ${ CHANGES_LOCAL } );
134- ${ CHANGES_LOCAL } = null;
135- }
136- ` ;
137- }
138-
139- function pipeCheckTemplate ( context :string , bindingPropagationConfig :string , pipe :string , pipeType :string ,
140- value :string , change :string , addRecord :string , notify :string ) :string {
131+ function pipeCheckTemplate ( protoIndex :number , context :string , bindingPropagationConfig :string , pipe :string , pipeType :string ,
132+ oldValue :string , newValue :string , change :string , invokeMementoAndAddChange :string ,
133+ addToChanges , lastInDirective :string ) :string {
141134 return `
135+ ${ CURRENT_PROTO } = ${ PROTOS_ACCESSOR } [${ protoIndex } ];
142136if (${ pipe } === ${ UTIL } .unitialized()) {
143137 ${ pipe } = ${ PIPE_REGISTRY_ACCESSOR } .get('${ pipeType } ', ${ context } , ${ bindingPropagationConfig } );
144138} else if (!${ pipe } .supports(${ context } )) {
145139 ${ pipe } .onDestroy();
146140 ${ pipe } = ${ PIPE_REGISTRY_ACCESSOR } .get('${ pipeType } ', ${ context } , ${ bindingPropagationConfig } );
147141}
148142
149- ${ CHANGE_LOCAL } = ${ pipe } .transform(${ context } );
150- if (! ${ UTIL } .noChangeMarker(${ CHANGE_LOCAL } )) {
151- ${ value } = ${ CHANGE_LOCAL } ;
143+ ${ newValue } = ${ pipe } .transform(${ context } );
144+ if (! ${ UTIL } .noChangeMarker(${ newValue } )) {
152145 ${ change } = true;
153- ${ addRecord }
146+ ${ invokeMementoAndAddChange }
147+ ${ addToChanges }
148+ ${ oldValue } = ${ newValue } ;
154149}
155- ${ notify }
150+ ${ lastInDirective }
156151` ;
157152}
158153
159- function referenceCheckTemplate ( assignment , newValue , oldValue , change , addRecord , notify ) {
154+ function referenceCheckTemplate ( protoIndex :number , assignment :string , oldValue :string , newValue :string , change :string ,
155+ invokeMementoAndAddChange :string , addToChanges :string , lastInDirective :string ) :string {
160156 return `
157+ ${ CURRENT_PROTO } = ${ PROTOS_ACCESSOR } [${ protoIndex } ];
161158${ assignment }
162159if (${ newValue } !== ${ oldValue } || (${ newValue } !== ${ newValue } ) && (${ oldValue } !== ${ oldValue } )) {
163160 ${ change } = true;
164- ${ addRecord }
161+ ${ invokeMementoAndAddChange }
162+ ${ addToChanges }
165163 ${ oldValue } = ${ newValue } ;
166164}
167- ${ notify }
165+ ${ lastInDirective }
168166` ;
169167}
170168
@@ -193,9 +191,25 @@ if (${cond}) {
193191` ;
194192}
195193
196- function addSimpleChangeRecordTemplate ( protoIndex :number , oldValue :string , newValue :string ) {
197- return `${ CHANGES_LOCAL } = ${ UTIL } .addRecord(${ CHANGES_LOCAL } ,
198- ${ UTIL } .simpleChangeRecord(${ PROTOS_ACCESSOR } [${ protoIndex } ].bindingMemento, ${ oldValue } , ${ newValue } ));` ;
194+ function addToChangesTemplate ( oldValue :string , newValue :string ) :string {
195+ return `${ CHANGES_LOCAL } = ${ UTIL } .addChange(${ CHANGES_LOCAL } , ${ CURRENT_PROTO } .bindingMemento, ${ UTIL } .simpleChange(${ oldValue } , ${ newValue } ));` ;
196+ }
197+
198+ function invokeBindingMemento ( oldValue :string , newValue :string ) :string {
199+ return `
200+ if(throwOnChange) ${ UTIL } .throwOnChange(${ CURRENT_PROTO } , ${ UTIL } .simpleChange(${ oldValue } , ${ newValue } ));
201+
202+ ${ DISPATCHER_ACCESSOR } .invokeMementoFor(${ CURRENT_PROTO } .bindingMemento, ${ newValue } );
203+ ` ;
204+ }
205+
206+ function lastInDirectiveTemplate ( protoIndex :number ) :string {
207+ return `
208+ if (${ CHANGES_LOCAL } ) {
209+ ${ DISPATCHER_ACCESSOR } .onChange(${ PROTOS_ACCESSOR } [${ protoIndex } ].directiveMemento, ${ CHANGES_LOCAL } );
210+ }
211+ ${ CHANGES_LOCAL } = null;
212+ ` ;
199213}
200214
201215
@@ -277,7 +291,7 @@ export class ChangeDetectorJITGenerator {
277291 }
278292
279293 genDetectChanges ( ) :string {
280- var body = this . genBody ( ) ;
294+ var body = this . genDetectChangesBody ( ) ;
281295 return detectChangesTemplate ( this . typeName , body ) ;
282296 }
283297
@@ -295,9 +309,9 @@ export class ChangeDetectorJITGenerator {
295309 return callOnAllChangesDoneTemplate ( this . typeName , notifications . join ( ";\n" ) ) ;
296310 }
297311
298- genBody ( ) :string {
312+ genDetectChangesBody ( ) :string {
299313 var rec = this . records . map ( ( r ) => this . genRecord ( r ) ) . join ( "\n" ) ;
300- return bodyTemplate ( this . genLocalDefinitions ( ) , this . genChangeDefinitions ( ) , rec ) ;
314+ return detectChangesBodyTemplate ( this . genLocalDefinitions ( ) , this . genChangeDefinitions ( ) , rec ) ;
301315 }
302316
303317 genLocalDefinitions ( ) :string {
@@ -318,27 +332,33 @@ export class ChangeDetectorJITGenerator {
318332
319333 genPipeCheck ( r :ProtoRecord ) :string {
320334 var context = this . localNames [ r . contextIndex ] ;
321- var pipe = this . pipeNames [ r . selfIndex ] ;
322- var newValue = this . localNames [ r . selfIndex ] ;
323335 var oldValue = this . fieldNames [ r . selfIndex ] ;
336+ var newValue = this . localNames [ r . selfIndex ] ;
324337 var change = this . changeNames [ r . selfIndex ] ;
338+
339+ var pipe = this . pipeNames [ r . selfIndex ] ;
325340 var bpc = r . mode === RECORD_TYPE_BINDING_PIPE ? "this.bindingPropagationConfig" : "null" ;
326341
327- var addRecord = addSimpleChangeRecordTemplate ( r . selfIndex - 1 , oldValue , newValue ) ;
328- var notify = this . genNotify ( r ) ;
342+ var invokeMemento = this . getInvokeMementoAndAddChangeTemplate ( r ) ;
343+ var addToChanges = this . genAddToChanges ( r ) ;
344+ var lastInDirective = this . genLastInDirective ( r ) ;
329345
330- return pipeCheckTemplate ( context , bpc , pipe , r . name , newValue , change , addRecord , notify ) ;
346+ return pipeCheckTemplate ( r . selfIndex - 1 , context , bpc , pipe , r . name , oldValue , newValue , change ,
347+ invokeMemento , addToChanges , lastInDirective ) ;
331348 }
332349
333350 genReferenceCheck ( r :ProtoRecord ) :string {
334- var newValue = this . localNames [ r . selfIndex ] ;
335351 var oldValue = this . fieldNames [ r . selfIndex ] ;
352+ var newValue = this . localNames [ r . selfIndex ] ;
336353 var change = this . changeNames [ r . selfIndex ] ;
337354 var assignment = this . genUpdateCurrentValue ( r ) ;
338- var addRecord = addSimpleChangeRecordTemplate ( r . selfIndex - 1 , oldValue , newValue ) ;
339- var notify = this . genNotify ( r ) ;
340355
341- var check = referenceCheckTemplate ( assignment , newValue , oldValue , change , r . lastInBinding ? addRecord : '' , notify ) ;
356+ var invokeMemento = this . getInvokeMementoAndAddChangeTemplate ( r ) ;
357+ var addToChanges = this . genAddToChanges ( r ) ;
358+ var lastInDirective = this . genLastInDirective ( r ) ;
359+
360+ var check = referenceCheckTemplate ( r . selfIndex - 1 , assignment , oldValue , newValue , change ,
361+ invokeMemento , addToChanges , lastInDirective ) ;
342362 if ( r . isPureFunction ( ) ) {
343363 return this . ifChangedGuard ( r , check ) ;
344364 } else {
@@ -405,8 +425,22 @@ export class ChangeDetectorJITGenerator {
405425 return JSON . stringify ( value ) ;
406426 }
407427
408- genNotify ( r ) :string {
409- return r . lastInDirective ? notifyTemplate ( r . selfIndex - 1 ) : '' ;
428+ getInvokeMementoAndAddChangeTemplate ( r :ProtoRecord ) :string {
429+ var newValue = this . localNames [ r . selfIndex ] ;
430+ var oldValue = this . fieldNames [ r . selfIndex ] ;
431+ return r . lastInBinding ? invokeBindingMemento ( oldValue , newValue ) : "" ;
432+ }
433+
434+ genAddToChanges ( r :ProtoRecord ) :string {
435+ var newValue = this . localNames [ r . selfIndex ] ;
436+ var oldValue = this . fieldNames [ r . selfIndex ] ;
437+ var callOnChange = r . directiveMemento && r . directiveMemento . callOnChange ;
438+ return callOnChange ? addToChangesTemplate ( oldValue , newValue ) : "";
439+ }
440+
441+ genLastInDirective ( r :ProtoRecord ) :string {
442+ var callOnChange = r . directiveMemento && r . directiveMemento . callOnChange ;
443+ return r . lastInDirective && callOnChange ? lastInDirectiveTemplate ( r . selfIndex - 1 ) : '' ;
410444 }
411445
412446 genArgs ( r :ProtoRecord ) :string {
0 commit comments