| 
									
										
										
										
											2016-04-12 09:40:37 -07:00
										 |  |  | import { | 
					
						
							|  |  |  |   ListWrapper, | 
					
						
							|  |  |  |   MapWrapper, | 
					
						
							|  |  |  |   Map, | 
					
						
							|  |  |  |   StringMapWrapper, | 
					
						
							| 
									
										
										
										
											2016-01-06 14:13:44 -08:00
										 |  |  |   isListLikeIterable, | 
					
						
							|  |  |  |   areIterablesEqual | 
					
						
							| 
									
										
										
										
											2016-04-12 09:40:37 -07:00
										 |  |  | } from 'angular2/src/facade/collection'; | 
					
						
							| 
									
										
										
										
											2015-05-20 09:48:15 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-06 14:13:44 -08:00
										 |  |  | import {Injector} from 'angular2/src/core/di'; | 
					
						
							|  |  |  | import {AppElement} from './element'; | 
					
						
							| 
									
										
										
										
											2016-04-12 09:40:37 -07:00
										 |  |  | import { | 
					
						
							| 
									
										
										
										
											2016-01-06 14:13:44 -08:00
										 |  |  |   assertionsEnabled, | 
					
						
							| 
									
										
										
										
											2016-04-12 09:40:37 -07:00
										 |  |  |   isPresent, | 
					
						
							|  |  |  |   isBlank, | 
					
						
							|  |  |  |   Type, | 
					
						
							|  |  |  |   isArray, | 
					
						
							|  |  |  |   isNumber, | 
					
						
							|  |  |  |   CONST, | 
					
						
							| 
									
										
										
										
											2016-01-06 14:13:44 -08:00
										 |  |  |   CONST_EXPR, | 
					
						
							|  |  |  |   stringify, | 
					
						
							| 
									
										
										
										
											2016-04-13 17:05:17 -07:00
										 |  |  |   isPrimitive, | 
					
						
							|  |  |  |   isString | 
					
						
							| 
									
										
										
										
											2016-04-12 09:40:37 -07:00
										 |  |  | } from 'angular2/src/facade/lang'; | 
					
						
							| 
									
										
										
										
											2016-01-06 14:13:44 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  | import {ObservableWrapper} from 'angular2/src/facade/async'; | 
					
						
							|  |  |  | import {Renderer, RootRenderer, RenderComponentType} from 'angular2/src/core/render/api'; | 
					
						
							| 
									
										
										
										
											2016-04-13 17:05:17 -07:00
										 |  |  | import {ViewRef_} from './view_ref'; | 
					
						
							| 
									
										
										
										
											2015-04-24 17:53:06 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-02 10:35:51 -08:00
										 |  |  | import {ViewType} from './view_type'; | 
					
						
							| 
									
										
										
										
											2016-01-06 14:13:44 -08:00
										 |  |  | import { | 
					
						
							| 
									
										
										
										
											2016-04-18 13:24:42 -07:00
										 |  |  |   ViewUtils, | 
					
						
							| 
									
										
										
										
											2016-01-06 14:13:44 -08:00
										 |  |  |   flattenNestedViewRenderNodes, | 
					
						
							|  |  |  |   ensureSlotCount, | 
					
						
							|  |  |  |   arrayLooseIdentical, | 
					
						
							|  |  |  |   mapLooseIdentical | 
					
						
							|  |  |  | } from './view_utils'; | 
					
						
							|  |  |  | import { | 
					
						
							|  |  |  |   ChangeDetectorRef, | 
					
						
							|  |  |  |   ChangeDetectionStrategy, | 
					
						
							|  |  |  |   ChangeDetectorState, | 
					
						
							|  |  |  |   isDefaultChangeDetectionStrategy, | 
					
						
							|  |  |  |   devModeEqual | 
					
						
							|  |  |  | } from 'angular2/src/core/change_detection/change_detection'; | 
					
						
							|  |  |  | import {wtfCreateScope, wtfLeave, WtfScopeFn} from '../profile/profile'; | 
					
						
							|  |  |  | import { | 
					
						
							|  |  |  |   ExpressionChangedAfterItHasBeenCheckedException, | 
					
						
							|  |  |  |   ViewDestroyedException, | 
					
						
							|  |  |  |   ViewWrappedException | 
					
						
							|  |  |  | } from './exceptions'; | 
					
						
							|  |  |  | import {StaticNodeDebugInfo, DebugContext} from './debug_context'; | 
					
						
							|  |  |  | import {ElementInjector} from './element_injector'; | 
					
						
							| 
									
										
										
										
											2015-07-28 12:43:41 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-06 14:13:44 -08:00
										 |  |  | var _scope_check: WtfScopeFn = wtfCreateScope(`AppView#check(ascii id)`); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-21 15:13:01 -08:00
										 |  |  | /** | 
					
						
							| 
									
										
										
										
											2015-07-07 08:15:58 +02:00
										 |  |  |  * Cost of making objects: http://jsperf.com/instantiate-size-of-object
 | 
					
						
							| 
									
										
										
										
											2015-03-31 22:47:11 +00:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2014-10-10 20:44:55 -07:00
										 |  |  |  */ | 
					
						
							| 
									
										
										
										
											2016-01-06 14:13:44 -08:00
										 |  |  | export abstract class AppView<T> { | 
					
						
							| 
									
										
										
										
											2016-04-28 14:00:31 -07:00
										 |  |  |   ref: ViewRef_<T>; | 
					
						
							| 
									
										
										
										
											2015-12-02 10:35:51 -08:00
										 |  |  |   rootNodesOrAppElements: any[]; | 
					
						
							|  |  |  |   allNodes: any[]; | 
					
						
							|  |  |  |   disposables: Function[]; | 
					
						
							| 
									
										
										
										
											2016-01-06 14:13:44 -08:00
										 |  |  |   subscriptions: any[]; | 
					
						
							|  |  |  |   contentChildren: AppView<any>[] = []; | 
					
						
							|  |  |  |   viewChildren: AppView<any>[] = []; | 
					
						
							|  |  |  |   renderParent: AppView<any>; | 
					
						
							| 
									
										
										
										
											2016-04-13 17:05:17 -07:00
										 |  |  |   viewContainerElement: AppElement = null; | 
					
						
							| 
									
										
										
										
											2016-01-06 14:13:44 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   // The names of the below fields must be kept in sync with codegen_name_util.ts or
 | 
					
						
							|  |  |  |   // change detection will fail.
 | 
					
						
							|  |  |  |   cdState: ChangeDetectorState = ChangeDetectorState.NeverChecked; | 
					
						
							| 
									
										
										
										
											2015-06-24 13:46:39 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-06 14:13:44 -08:00
										 |  |  |   projectableNodes: Array<any | any[]>; | 
					
						
							| 
									
										
										
										
											2015-01-02 14:23:59 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-06 14:13:44 -08:00
										 |  |  |   destroyed: boolean = false; | 
					
						
							| 
									
										
										
										
											2015-12-02 10:35:51 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-06 14:13:44 -08:00
										 |  |  |   renderer: Renderer; | 
					
						
							| 
									
										
										
										
											2015-12-02 10:35:51 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-06 14:13:44 -08:00
										 |  |  |   private _currentDebugContext: DebugContext = null; | 
					
						
							| 
									
										
										
										
											2015-12-02 10:35:51 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-13 17:05:17 -07:00
										 |  |  |   private _hasExternalHostElement: boolean; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-28 14:00:31 -07:00
										 |  |  |   public context: T; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-06 14:13:44 -08:00
										 |  |  |   constructor(public clazz: any, public componentType: RenderComponentType, public type: ViewType, | 
					
						
							| 
									
										
										
										
											2016-04-28 14:00:31 -07:00
										 |  |  |               public viewUtils: ViewUtils, public parentInjector: Injector, | 
					
						
							|  |  |  |               public declarationAppElement: AppElement, public cdMode: ChangeDetectionStrategy, | 
					
						
							| 
									
										
										
										
											2016-04-22 15:33:32 -07:00
										 |  |  |               public staticNodeDebugInfos: StaticNodeDebugInfo[]) { | 
					
						
							| 
									
										
										
										
											2015-10-06 06:53:39 -07:00
										 |  |  |     this.ref = new ViewRef_(this); | 
					
						
							| 
									
										
										
										
											2016-01-06 14:13:44 -08:00
										 |  |  |     if (type === ViewType.COMPONENT || type === ViewType.HOST) { | 
					
						
							| 
									
										
										
										
											2016-04-18 13:24:42 -07:00
										 |  |  |       this.renderer = viewUtils.renderComponent(componentType); | 
					
						
							| 
									
										
										
										
											2016-01-06 14:13:44 -08:00
										 |  |  |     } else { | 
					
						
							|  |  |  |       this.renderer = declarationAppElement.parentView.renderer; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-28 14:00:31 -07:00
										 |  |  |   create(context: T, givenProjectableNodes: Array<any | any[]>, | 
					
						
							|  |  |  |          rootSelectorOrNode: string | any): AppElement { | 
					
						
							|  |  |  |     this.context = context; | 
					
						
							| 
									
										
										
										
											2016-01-06 14:13:44 -08:00
										 |  |  |     var projectableNodes; | 
					
						
							|  |  |  |     switch (this.type) { | 
					
						
							| 
									
										
										
										
											2015-12-02 10:35:51 -08:00
										 |  |  |       case ViewType.COMPONENT: | 
					
						
							| 
									
										
										
										
											2016-01-06 14:13:44 -08:00
										 |  |  |         projectableNodes = ensureSlotCount(givenProjectableNodes, this.componentType.slotCount); | 
					
						
							| 
									
										
										
										
											2015-12-02 10:35:51 -08:00
										 |  |  |         break; | 
					
						
							|  |  |  |       case ViewType.EMBEDDED: | 
					
						
							| 
									
										
										
										
											2016-01-06 14:13:44 -08:00
										 |  |  |         projectableNodes = this.declarationAppElement.parentView.projectableNodes; | 
					
						
							| 
									
										
										
										
											2015-12-02 10:35:51 -08:00
										 |  |  |         break; | 
					
						
							|  |  |  |       case ViewType.HOST: | 
					
						
							| 
									
										
										
										
											2016-01-06 14:13:44 -08:00
										 |  |  |         // Note: Don't ensure the slot count for the projectableNodes as we store
 | 
					
						
							|  |  |  |         // them only for the contained component view (which will later check the slot count...)
 | 
					
						
							|  |  |  |         projectableNodes = givenProjectableNodes; | 
					
						
							| 
									
										
										
										
											2015-12-02 10:35:51 -08:00
										 |  |  |         break; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2016-04-13 17:05:17 -07:00
										 |  |  |     this._hasExternalHostElement = isPresent(rootSelectorOrNode); | 
					
						
							| 
									
										
										
										
											2016-01-06 14:13:44 -08:00
										 |  |  |     this.projectableNodes = projectableNodes; | 
					
						
							|  |  |  |     if (this.debugMode) { | 
					
						
							|  |  |  |       this._resetDebug(); | 
					
						
							|  |  |  |       try { | 
					
						
							| 
									
										
										
										
											2016-04-13 17:05:17 -07:00
										 |  |  |         return this.createInternal(rootSelectorOrNode); | 
					
						
							| 
									
										
										
										
											2016-01-06 14:13:44 -08:00
										 |  |  |       } catch (e) { | 
					
						
							|  |  |  |         this._rethrowWithContext(e, e.stack); | 
					
						
							|  |  |  |         throw e; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } else { | 
					
						
							| 
									
										
										
										
											2016-04-13 17:05:17 -07:00
										 |  |  |       return this.createInternal(rootSelectorOrNode); | 
					
						
							| 
									
										
										
										
											2016-01-06 14:13:44 -08:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2015-12-02 10:35:51 -08:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2015-06-24 13:46:39 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-06 14:13:44 -08:00
										 |  |  |   /** | 
					
						
							| 
									
										
										
										
											2016-04-18 13:24:42 -07:00
										 |  |  |    * Overwritten by implementations. | 
					
						
							|  |  |  |    * Returns the AppElement for the host element for ViewType.HOST. | 
					
						
							| 
									
										
										
										
											2016-01-06 14:13:44 -08:00
										 |  |  |    */ | 
					
						
							| 
									
										
										
										
											2016-04-13 17:05:17 -07:00
										 |  |  |   createInternal(rootSelectorOrNode: string | any): AppElement { return null; } | 
					
						
							| 
									
										
										
										
											2016-01-06 14:13:44 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-18 13:24:42 -07:00
										 |  |  |   init(rootNodesOrAppElements: any[], allNodes: any[], disposables: Function[], | 
					
						
							|  |  |  |        subscriptions: any[]) { | 
					
						
							| 
									
										
										
										
											2015-12-02 10:35:51 -08:00
										 |  |  |     this.rootNodesOrAppElements = rootNodesOrAppElements; | 
					
						
							|  |  |  |     this.allNodes = allNodes; | 
					
						
							|  |  |  |     this.disposables = disposables; | 
					
						
							| 
									
										
										
										
											2016-01-06 14:13:44 -08:00
										 |  |  |     this.subscriptions = subscriptions; | 
					
						
							|  |  |  |     if (this.type === ViewType.COMPONENT) { | 
					
						
							| 
									
										
										
										
											2015-12-02 10:35:51 -08:00
										 |  |  |       // Note: the render nodes have been attached to their host element
 | 
					
						
							|  |  |  |       // in the ViewFactory already.
 | 
					
						
							| 
									
										
										
										
											2016-01-06 14:13:44 -08:00
										 |  |  |       this.declarationAppElement.parentView.viewChildren.push(this); | 
					
						
							|  |  |  |       this.renderParent = this.declarationAppElement.parentView; | 
					
						
							|  |  |  |       this.dirtyParentQueriesInternal(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-13 17:05:17 -07:00
										 |  |  |   selectOrCreateHostElement(elementName: string, rootSelectorOrNode: string | any, | 
					
						
							|  |  |  |                             debugCtx: DebugContext): any { | 
					
						
							|  |  |  |     var hostElement; | 
					
						
							|  |  |  |     if (isPresent(rootSelectorOrNode)) { | 
					
						
							|  |  |  |       hostElement = this.renderer.selectRootElement(rootSelectorOrNode, debugCtx); | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |       hostElement = this.renderer.createElement(null, elementName, debugCtx); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return hostElement; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2016-01-06 14:13:44 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   injectorGet(token: any, nodeIndex: number, notFoundResult: any): any { | 
					
						
							|  |  |  |     if (this.debugMode) { | 
					
						
							|  |  |  |       this._resetDebug(); | 
					
						
							|  |  |  |       try { | 
					
						
							|  |  |  |         return this.injectorGetInternal(token, nodeIndex, notFoundResult); | 
					
						
							|  |  |  |       } catch (e) { | 
					
						
							|  |  |  |         this._rethrowWithContext(e, e.stack); | 
					
						
							|  |  |  |         throw e; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |       return this.injectorGetInternal(token, nodeIndex, notFoundResult); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /** | 
					
						
							|  |  |  |    * Overwritten by implementations | 
					
						
							|  |  |  |    */ | 
					
						
							|  |  |  |   injectorGetInternal(token: any, nodeIndex: number, notFoundResult: any): any { | 
					
						
							|  |  |  |     return notFoundResult; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   injector(nodeIndex: number): Injector { | 
					
						
							|  |  |  |     if (isPresent(nodeIndex)) { | 
					
						
							|  |  |  |       return new ElementInjector(this, nodeIndex); | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |       return this.parentInjector; | 
					
						
							| 
									
										
										
										
											2015-12-02 10:35:51 -08:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2014-12-01 18:41:55 -08:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-02 10:35:51 -08:00
										 |  |  |   destroy() { | 
					
						
							| 
									
										
										
										
											2016-04-13 17:05:17 -07:00
										 |  |  |     if (this._hasExternalHostElement) { | 
					
						
							|  |  |  |       this.renderer.detachView(this.flatRootNodes); | 
					
						
							|  |  |  |     } else if (isPresent(this.viewContainerElement)) { | 
					
						
							|  |  |  |       this.viewContainerElement.detachView(this.viewContainerElement.nestedViews.indexOf(this)); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     this._destroyRecurse(); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   private _destroyRecurse() { | 
					
						
							| 
									
										
										
										
											2015-12-02 10:35:51 -08:00
										 |  |  |     if (this.destroyed) { | 
					
						
							| 
									
										
										
										
											2016-01-06 14:13:44 -08:00
										 |  |  |       return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     var children = this.contentChildren; | 
					
						
							|  |  |  |     for (var i = 0; i < children.length; i++) { | 
					
						
							| 
									
										
										
										
											2016-04-13 17:05:17 -07:00
										 |  |  |       children[i]._destroyRecurse(); | 
					
						
							| 
									
										
										
										
											2016-01-06 14:13:44 -08:00
										 |  |  |     } | 
					
						
							|  |  |  |     children = this.viewChildren; | 
					
						
							|  |  |  |     for (var i = 0; i < children.length; i++) { | 
					
						
							| 
									
										
										
										
											2016-04-13 17:05:17 -07:00
										 |  |  |       children[i]._destroyRecurse(); | 
					
						
							| 
									
										
										
										
											2016-01-06 14:13:44 -08:00
										 |  |  |     } | 
					
						
							|  |  |  |     if (this.debugMode) { | 
					
						
							|  |  |  |       this._resetDebug(); | 
					
						
							|  |  |  |       try { | 
					
						
							|  |  |  |         this._destroyLocal(); | 
					
						
							|  |  |  |       } catch (e) { | 
					
						
							|  |  |  |         this._rethrowWithContext(e, e.stack); | 
					
						
							|  |  |  |         throw e; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |       this._destroyLocal(); | 
					
						
							| 
									
										
										
										
											2015-12-02 10:35:51 -08:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2014-12-01 18:41:55 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-02 10:35:51 -08:00
										 |  |  |     this.destroyed = true; | 
					
						
							| 
									
										
										
										
											2016-01-06 14:13:44 -08:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   private _destroyLocal() { | 
					
						
							| 
									
										
										
										
											2015-12-02 10:35:51 -08:00
										 |  |  |     var hostElement = | 
					
						
							| 
									
										
										
										
											2016-01-06 14:13:44 -08:00
										 |  |  |         this.type === ViewType.COMPONENT ? this.declarationAppElement.nativeElement : null; | 
					
						
							| 
									
										
										
										
											2015-12-02 10:35:51 -08:00
										 |  |  |     for (var i = 0; i < this.disposables.length; i++) { | 
					
						
							|  |  |  |       this.disposables[i](); | 
					
						
							| 
									
										
										
										
											2014-12-01 18:41:55 -08:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2016-01-06 14:13:44 -08:00
										 |  |  |     for (var i = 0; i < this.subscriptions.length; i++) { | 
					
						
							|  |  |  |       ObservableWrapper.dispose(this.subscriptions[i]); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     this.destroyInternal(); | 
					
						
							| 
									
										
										
										
											2016-04-13 17:05:17 -07:00
										 |  |  |     if (this._hasExternalHostElement) { | 
					
						
							|  |  |  |       this.renderer.detachView(this.flatRootNodes); | 
					
						
							|  |  |  |     } else if (isPresent(this.viewContainerElement)) { | 
					
						
							|  |  |  |       this.viewContainerElement.detachView(this.viewContainerElement.nestedViews.indexOf(this)); | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |       this.dirtyParentQueriesInternal(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     this.renderer.destroyView(hostElement, this.allNodes); | 
					
						
							| 
									
										
										
										
											2014-12-01 18:41:55 -08:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-06 14:13:44 -08:00
										 |  |  |   /** | 
					
						
							|  |  |  |    * Overwritten by implementations | 
					
						
							|  |  |  |    */ | 
					
						
							|  |  |  |   destroyInternal(): void {} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   get debugMode(): boolean { return isPresent(this.staticNodeDebugInfos); } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   get changeDetectorRef(): ChangeDetectorRef { return this.ref; } | 
					
						
							| 
									
										
										
										
											2014-12-01 18:41:55 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-22 15:33:32 -07:00
										 |  |  |   get parent(): AppView<any> { | 
					
						
							|  |  |  |     return isPresent(this.declarationAppElement) ? this.declarationAppElement.parentView : null; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-02 10:35:51 -08:00
										 |  |  |   get flatRootNodes(): any[] { return flattenNestedViewRenderNodes(this.rootNodesOrAppElements); } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-06 14:13:44 -08:00
										 |  |  |   get lastRootNode(): any { | 
					
						
							|  |  |  |     var lastNode = this.rootNodesOrAppElements.length > 0 ? | 
					
						
							|  |  |  |                        this.rootNodesOrAppElements[this.rootNodesOrAppElements.length - 1] : | 
					
						
							|  |  |  |                        null; | 
					
						
							|  |  |  |     return _findLastRenderNode(lastNode); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /** | 
					
						
							|  |  |  |    * Overwritten by implementations | 
					
						
							|  |  |  |    */ | 
					
						
							|  |  |  |   dirtyParentQueriesInternal(): void {} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   addRenderContentChild(view: AppView<any>): void { | 
					
						
							|  |  |  |     this.contentChildren.push(view); | 
					
						
							|  |  |  |     view.renderParent = this; | 
					
						
							|  |  |  |     view.dirtyParentQueriesInternal(); | 
					
						
							| 
									
										
										
										
											2015-03-10 10:03:26 +01:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-06 14:13:44 -08:00
										 |  |  |   removeContentChild(view: AppView<any>): void { | 
					
						
							|  |  |  |     ListWrapper.remove(this.contentChildren, view); | 
					
						
							|  |  |  |     view.dirtyParentQueriesInternal(); | 
					
						
							|  |  |  |     view.renderParent = null; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   detectChanges(throwOnChange: boolean): void { | 
					
						
							|  |  |  |     var s = _scope_check(this.clazz); | 
					
						
							|  |  |  |     if (this.cdMode === ChangeDetectionStrategy.Detached || | 
					
						
							|  |  |  |         this.cdMode === ChangeDetectionStrategy.Checked || | 
					
						
							|  |  |  |         this.cdState === ChangeDetectorState.Errored) | 
					
						
							|  |  |  |       return; | 
					
						
							|  |  |  |     if (this.destroyed) { | 
					
						
							|  |  |  |       this.throwDestroyedError('detectChanges'); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     if (this.debugMode) { | 
					
						
							|  |  |  |       this._resetDebug(); | 
					
						
							|  |  |  |       try { | 
					
						
							|  |  |  |         this.detectChangesInternal(throwOnChange); | 
					
						
							|  |  |  |       } catch (e) { | 
					
						
							|  |  |  |         this._rethrowWithContext(e, e.stack); | 
					
						
							|  |  |  |         throw e; | 
					
						
							| 
									
										
										
										
											2015-06-24 13:46:39 -07:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2016-01-06 14:13:44 -08:00
										 |  |  |     } else { | 
					
						
							|  |  |  |       this.detectChangesInternal(throwOnChange); | 
					
						
							| 
									
										
										
										
											2015-04-07 20:54:20 -07:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2016-01-06 14:13:44 -08:00
										 |  |  |     if (this.cdMode === ChangeDetectionStrategy.CheckOnce) | 
					
						
							|  |  |  |       this.cdMode = ChangeDetectionStrategy.Checked; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     this.cdState = ChangeDetectorState.CheckedBefore; | 
					
						
							|  |  |  |     wtfLeave(s); | 
					
						
							| 
									
										
										
										
											2015-04-07 20:54:20 -07:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2015-04-09 21:20:11 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-06 14:13:44 -08:00
										 |  |  |   /** | 
					
						
							|  |  |  |    * Overwritten by implementations | 
					
						
							|  |  |  |    */ | 
					
						
							|  |  |  |   detectChangesInternal(throwOnChange: boolean): void { | 
					
						
							|  |  |  |     this.detectContentChildrenChanges(throwOnChange); | 
					
						
							|  |  |  |     this.detectViewChildrenChanges(throwOnChange); | 
					
						
							| 
									
										
										
										
											2015-08-20 15:11:12 -07:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-06 14:13:44 -08:00
										 |  |  |   detectContentChildrenChanges(throwOnChange: boolean) { | 
					
						
							|  |  |  |     for (var i = 0; i < this.contentChildren.length; ++i) { | 
					
						
							|  |  |  |       this.contentChildren[i].detectChanges(throwOnChange); | 
					
						
							| 
									
										
										
										
											2015-06-12 09:45:31 -07:00
										 |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-06 14:13:44 -08:00
										 |  |  |   detectViewChildrenChanges(throwOnChange: boolean) { | 
					
						
							|  |  |  |     for (var i = 0; i < this.viewChildren.length; ++i) { | 
					
						
							|  |  |  |       this.viewChildren[i].detectChanges(throwOnChange); | 
					
						
							| 
									
										
										
										
											2015-08-18 21:51:28 -07:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2015-08-28 18:11:04 -07:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-13 17:05:17 -07:00
										 |  |  |   addToContentChildren(renderAppElement: AppElement): void { | 
					
						
							|  |  |  |     renderAppElement.parentView.contentChildren.push(this); | 
					
						
							|  |  |  |     this.viewContainerElement = renderAppElement; | 
					
						
							|  |  |  |     this.dirtyParentQueriesInternal(); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   removeFromContentChildren(renderAppElement: AppElement): void { | 
					
						
							|  |  |  |     ListWrapper.remove(renderAppElement.parentView.contentChildren, this); | 
					
						
							|  |  |  |     this.dirtyParentQueriesInternal(); | 
					
						
							|  |  |  |     this.viewContainerElement = null; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-06 14:13:44 -08:00
										 |  |  |   markAsCheckOnce(): void { this.cdMode = ChangeDetectionStrategy.CheckOnce; } | 
					
						
							| 
									
										
										
										
											2015-06-24 13:46:39 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-06 14:13:44 -08:00
										 |  |  |   markPathToRootAsCheckOnce(): void { | 
					
						
							|  |  |  |     var c: AppView<any> = this; | 
					
						
							|  |  |  |     while (isPresent(c) && c.cdMode !== ChangeDetectionStrategy.Detached) { | 
					
						
							|  |  |  |       if (c.cdMode === ChangeDetectionStrategy.Checked) { | 
					
						
							|  |  |  |         c.cdMode = ChangeDetectionStrategy.CheckOnce; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       c = c.renderParent; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2014-12-02 17:09:46 -08:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2014-09-28 16:29:11 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-06 14:13:44 -08:00
										 |  |  |   private _resetDebug() { this._currentDebugContext = null; } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   debug(nodeIndex: number, rowNum: number, colNum: number): DebugContext { | 
					
						
							|  |  |  |     return this._currentDebugContext = new DebugContext(this, nodeIndex, rowNum, colNum); | 
					
						
							| 
									
										
										
										
											2015-07-23 18:01:34 -07:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-06 14:13:44 -08:00
										 |  |  |   private _rethrowWithContext(e: any, stack: any) { | 
					
						
							|  |  |  |     if (!(e instanceof ViewWrappedException)) { | 
					
						
							|  |  |  |       if (!(e instanceof ExpressionChangedAfterItHasBeenCheckedException)) { | 
					
						
							|  |  |  |         this.cdState = ChangeDetectorState.Errored; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       if (isPresent(this._currentDebugContext)) { | 
					
						
							|  |  |  |         throw new ViewWrappedException(e, stack, this._currentDebugContext); | 
					
						
							| 
									
										
										
										
											2015-12-02 10:35:51 -08:00
										 |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2015-07-27 15:47:42 -07:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2015-12-02 10:35:51 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-06 14:13:44 -08:00
										 |  |  |   eventHandler(cb: Function): Function { | 
					
						
							|  |  |  |     if (this.debugMode) { | 
					
						
							|  |  |  |       return (event) => { | 
					
						
							|  |  |  |         this._resetDebug(); | 
					
						
							|  |  |  |         try { | 
					
						
							|  |  |  |           return cb(event); | 
					
						
							|  |  |  |         } catch (e) { | 
					
						
							|  |  |  |           this._rethrowWithContext(e, e.stack); | 
					
						
							|  |  |  |           throw e; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       }; | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |       return cb; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2015-07-27 15:47:42 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-06 14:13:44 -08:00
										 |  |  |   throwDestroyedError(details: string): void { throw new ViewDestroyedException(details); } | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2015-12-02 10:35:51 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-06 14:13:44 -08:00
										 |  |  | function _findLastRenderNode(node: any): any { | 
					
						
							| 
									
										
										
										
											2016-02-03 16:35:38 -08:00
										 |  |  |   var lastNode; | 
					
						
							|  |  |  |   if (node instanceof AppElement) { | 
					
						
							|  |  |  |     var appEl = <AppElement>node; | 
					
						
							|  |  |  |     lastNode = appEl.nativeElement; | 
					
						
							|  |  |  |     if (isPresent(appEl.nestedViews)) { | 
					
						
							|  |  |  |       // Note: Views might have no root nodes at all!
 | 
					
						
							|  |  |  |       for (var i = appEl.nestedViews.length - 1; i >= 0; i--) { | 
					
						
							|  |  |  |         var nestedView = appEl.nestedViews[i]; | 
					
						
							|  |  |  |         if (nestedView.rootNodesOrAppElements.length > 0) { | 
					
						
							| 
									
										
										
										
											2016-01-06 14:13:44 -08:00
										 |  |  |           lastNode = _findLastRenderNode( | 
					
						
							| 
									
										
										
										
											2016-02-03 16:35:38 -08:00
										 |  |  |               nestedView.rootNodesOrAppElements[nestedView.rootNodesOrAppElements.length - 1]); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } else { | 
					
						
							|  |  |  |     lastNode = node; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   return lastNode; | 
					
						
							|  |  |  | } |