import {isPresent} from 'angular2/src/facade/lang'; import {List, ListWrapper} from 'angular2/src/facade/collection'; import {ChangeDetectorRef} from './change_detector_ref'; import {ChangeDetector} from './interfaces'; import {CHECK_ALWAYS, CHECK_ONCE, CHECKED, DETACHED, ON_PUSH} from './constants'; export class AbstractChangeDetector extends ChangeDetector { lightDomChildren:List; shadowDomChildren:List; parent:ChangeDetector; mode:string; ref:ChangeDetectorRef; constructor() { super(); this.lightDomChildren = []; this.shadowDomChildren = []; this.ref = new ChangeDetectorRef(this); this.mode = null; } addChild(cd:ChangeDetector) { ListWrapper.push(this.lightDomChildren, cd); cd.parent = this; } removeChild(cd:ChangeDetector) { ListWrapper.remove(this.lightDomChildren, cd); } addShadowDomChild(cd:ChangeDetector) { ListWrapper.push(this.shadowDomChildren, cd); cd.parent = this; } removeShadowDomChild(cd:ChangeDetector) { ListWrapper.remove(this.shadowDomChildren, cd); } remove() { this.parent.removeChild(this); } detectChanges() { this._detectChanges(false); } checkNoChanges() { this._detectChanges(true); } _detectChanges(throwOnChange:boolean) { if (this.mode === DETACHED || this.mode === CHECKED) return; this.detectChangesInRecords(throwOnChange); this._detectChangesInLightDomChildren(throwOnChange); this.callOnAllChangesDone(); this._detectChangesInShadowDomChildren(throwOnChange); if (this.mode === CHECK_ONCE) this.mode = CHECKED; } detectChangesInRecords(throwOnChange:boolean){} callOnAllChangesDone(){} _detectChangesInLightDomChildren(throwOnChange:boolean) { var c = this.lightDomChildren; for(var i = 0; i < c.length; ++i) { c[i]._detectChanges(throwOnChange); } } _detectChangesInShadowDomChildren(throwOnChange:boolean) { var c = this.shadowDomChildren; for(var i = 0; i < c.length; ++i) { c[i]._detectChanges(throwOnChange); } } markAsCheckOnce() { this.mode = CHECK_ONCE; } markPathToRootAsCheckOnce() { var c = this; while(isPresent(c) && c.mode != DETACHED) { if (c.mode === CHECKED) c.mode = CHECK_ONCE; c = c.parent; } } }