@@ -154,6 +154,7 @@ interface Zone {
154154 * @returns {any } The value for the key, or `undefined` if not found.
155155 */
156156 get ( key : string ) : any ;
157+
157158 /**
158159 * Returns a Zone which defines a `key`.
159160 *
@@ -163,13 +164,15 @@ interface Zone {
163164 * @returns {Zone } The Zone which defines the `key`, `null` if not found.
164165 */
165166 getZoneWith ( key : string ) : Zone | null ;
167+
166168 /**
167169 * Used to create a child zone.
168170 *
169171 * @param zoneSpec A set of rules which the child zone should follow.
170172 * @returns {Zone } A new child zone.
171173 */
172174 fork ( zoneSpec : ZoneSpec ) : Zone ;
175+
173176 /**
174177 * Wraps a callback function in a new function which will properly restore the current zone upon
175178 * invocation.
@@ -184,6 +187,7 @@ interface Zone {
184187 * @returns {function(): * } A function which will invoke the `callback` through [Zone.runGuarded].
185188 */
186189 wrap < F extends Function > ( callback : F , source : string ) : F ;
190+
187191 /**
188192 * Invokes a function in a given zone.
189193 *
@@ -196,6 +200,7 @@ interface Zone {
196200 * @returns {any } Value from the `callback` function.
197201 */
198202 run < T > ( callback : Function , applyThis ?: any , applyArgs ?: any [ ] , source ?: string ) : T ;
203+
199204 /**
200205 * Invokes a function in a given zone and catches any exceptions.
201206 *
@@ -211,6 +216,7 @@ interface Zone {
211216 * @returns {any } Value from the `callback` function.
212217 */
213218 runGuarded < T > ( callback : Function , applyThis ?: any , applyArgs ?: any [ ] , source ?: string ) : T ;
219+
214220 /**
215221 * Execute the Task by restoring the [Zone.currentTask] in the Task's zone.
216222 *
@@ -303,7 +309,7 @@ interface ZoneType {
303309 root : Zone ;
304310
305311 /** @internal */
306- __load_patch ( name : string , fn : _PatchFn ) : void ;
312+ __load_patch ( name : string , fn : _PatchFn , preload ?: boolean ) : void ;
307313
308314 /** @internal */
309315 __symbol__ ( name : string ) : string ;
@@ -488,14 +494,22 @@ interface ZoneSpec {
488494 */
489495interface ZoneDelegate {
490496 zone : Zone ;
497+
491498 fork ( targetZone : Zone , zoneSpec : ZoneSpec ) : Zone ;
499+
492500 intercept ( targetZone : Zone , callback : Function , source : string ) : Function ;
501+
493502 invoke ( targetZone : Zone , callback : Function , applyThis ?: any , applyArgs ?: any [ ] , source ?: string ) :
494503 any ;
504+
495505 handleError ( targetZone : Zone , error : any ) : boolean ;
506+
496507 scheduleTask ( targetZone : Zone , task : Task ) : Task ;
508+
497509 invokeTask ( targetZone : Zone , task : Task , applyThis ?: any , applyArgs ?: any [ ] ) : any ;
510+
498511 cancelTask ( targetZone : Zone , task : Task ) : any ;
512+
499513 hasTask ( targetZone : Zone , isEmpty : HasTaskState ) : void ;
500514}
501515
@@ -637,12 +651,15 @@ type AmbientZoneDelegate = ZoneDelegate;
637651const Zone : ZoneType = ( function ( global : any ) {
638652 const performance : { mark ( name : string ) : void ; measure ( name : string , label : string ) : void ; } =
639653 global [ 'performance' ] ;
654+
640655 function mark ( name : string ) {
641656 performance && performance [ 'mark' ] && performance [ 'mark' ] ( name ) ;
642657 }
658+
643659 function performanceMeasure ( name : string , label : string ) {
644660 performance && performance [ 'measure' ] && performance [ 'measure' ] ( name , label ) ;
645661 }
662+
646663 mark ( 'Zone' ) ;
647664 if ( global [ 'Zone' ] ) {
648665 // if global['Zone'] already exists (maybe zone.js was already loaded or
@@ -666,7 +683,7 @@ const Zone: ZoneType = (function(global: any) {
666683 static __symbol__ : ( name : string ) => string = __symbol__ ;
667684
668685 static assertZonePatched ( ) {
669- if ( global [ 'Promise' ] !== patches [ 'ZoneAwarePromise' ] ) {
686+ if ( patchLoaded && global [ 'Promise' ] !== patchedPromise ) {
670687 throw new Error (
671688 'Zone.js has detected that ZoneAwarePromise `(window|global).Promise` ' +
672689 'has been overwritten.\n' +
@@ -692,42 +709,92 @@ const Zone: ZoneType = (function(global: any) {
692709 return _currentTask ;
693710 }
694711
695- static __load_patch ( name : string , fn : _PatchFn ) : void {
712+ static get mode ( ) : 'lazy' | 'normal' {
713+ return _mode ;
714+ }
715+
716+ static set mode ( newMode : 'lazy' | 'normal' ) {
717+ _mode = newMode ;
718+ }
719+
720+ static __load_patch ( name : string , fn : _PatchFn , preload = false ) : void {
696721 if ( patches . hasOwnProperty ( name ) ) {
697722 throw Error ( 'Already loaded patch: ' + name ) ;
698723 } else if ( ! global [ '__Zone_disable_' + name ] ) {
699724 const perfName = 'Zone:' + name ;
700725 mark ( perfName ) ;
701- if ( _mode === 'normal' ) {
726+ if ( _mode === 'normal' || preload ) {
702727 patches [ name ] = fn ( global , Zone , _api ) ;
703728 } else {
704729 patches [ name ] = function ( ) {
705- fn ( global , Zone , _api ) ;
730+ return fn ( global , Zone , _api ) ;
706731 } ;
707732 }
708733 performanceMeasure ( perfName , perfName ) ;
709734 }
710735 }
711736
712737 static __load ( ) {
713- Object . keys ( patches ) . forEach ( key => patches [ key ] ( ) ) ;
738+ if ( patchLoaded ) {
739+ return ;
740+ }
741+ Object . keys ( patches ) . forEach ( key => {
742+ const loadPatchFn = patches [ key ] ;
743+ if ( typeof loadPatchFn === 'function' ) {
744+ const r = loadPatchFn ( ) ;
745+ if ( key === 'ZoneAwarePromise' ) {
746+ patchedPromise = r ;
747+ }
748+ }
749+ } ) ;
714750 patchLoaded = true ;
715751 }
716752
717- static __register_patched_delegate ( proto : any , property : string , origin : any ) {
718- delegates . push ( { proto : proto , property : property , patched : proto [ property ] , origin : origin } ) ;
753+ static __register_patched_delegate (
754+ proto : any , property : string , origin : any , isPropertyDesc = false ) {
755+ if ( ! isPropertyDesc ) {
756+ delegates . push ( {
757+ proto : proto ,
758+ property : property ,
759+ patched : proto [ property ] ,
760+ origin : origin ,
761+ isPropertyDesc : isPropertyDesc
762+ } ) ;
763+ } else {
764+ delegates . push ( {
765+ proto : proto ,
766+ property : property ,
767+ patched : Object . getOwnPropertyDescriptor ( proto , property ) ,
768+ origin : origin ,
769+ isPropertyDesc : isPropertyDesc
770+ } ) ;
771+ }
719772 }
720773
721774 static __reloadAll ( ) {
775+ if ( patchLoaded ) {
776+ return ;
777+ }
722778 delegates . forEach ( delegate => {
723- delegate . proto [ delegate . property ] = delegate . patched ;
779+ if ( delegate . isPropertyDesc ) {
780+ Object . defineProperty ( delegate . proto , delegate . property , delegate . patched ) ;
781+ } else {
782+ delegate . proto [ delegate . property ] = delegate . patched ;
783+ }
724784 } ) ;
725785 patchLoaded = true ;
726786 }
727787
728788 static __unloadAll ( ) {
789+ if ( ! patchLoaded ) {
790+ return ;
791+ }
729792 delegates . forEach ( delegate => {
730- delegate . proto [ delegate . property ] = delegate . origin ;
793+ if ( delegate . isPropertyDesc ) {
794+ Object . defineProperty ( delegate . proto , delegate . property , delegate . origin ) ;
795+ } else {
796+ delegate . proto [ delegate . property ] = delegate . origin ;
797+ }
731798 } ) ;
732799 patchLoaded = false ;
733800 }
@@ -797,8 +864,7 @@ const Zone: ZoneType = (function(global: any) {
797864 return this . _zoneDelegate . invoke ( this , callback , applyThis , applyArgs , source ) ;
798865 } finally {
799866 _currentZoneFrame = _currentZoneFrame . parent ! ;
800- if ( _mode === 'lazy' && _currentZoneFrame . zone &&
801- _currentZoneFrame . zone . name === '<root>' ) {
867+ if ( _mode === 'lazy' && _currentZoneFrame . zone && ! _currentZoneFrame . zone . parent ) {
802868 Zone . __unloadAll ( ) ;
803869 }
804870 }
@@ -822,8 +888,7 @@ const Zone: ZoneType = (function(global: any) {
822888 }
823889 } finally {
824890 _currentZoneFrame = _currentZoneFrame . parent ! ;
825- if ( _mode === 'lazy' && _currentZoneFrame . zone &&
826- _currentZoneFrame . zone . name === '<root>' ) {
891+ if ( _mode === 'lazy' && _currentZoneFrame . zone && ! _currentZoneFrame . zone . parent ) {
827892 Zone . __unloadAll ( ) ;
828893 }
829894 }
@@ -879,8 +944,7 @@ const Zone: ZoneType = (function(global: any) {
879944 }
880945 _currentZoneFrame = _currentZoneFrame . parent ! ;
881946 _currentTask = previousTask ;
882- if ( _mode === 'lazy' && _currentZoneFrame . zone &&
883- _currentZoneFrame . zone . name === '<root>' ) {
947+ if ( _mode === 'lazy' && _currentZoneFrame . zone && ! _currentZoneFrame . zone . parent ) {
884948 Zone . __unloadAll ( ) ;
885949 }
886950 }
@@ -1330,6 +1394,8 @@ const Zone: ZoneType = (function(global: any) {
13301394 if ( ! nativeMicroTaskQueuePromise ) {
13311395 if ( global [ symbolPromise ] ) {
13321396 nativeMicroTaskQueuePromise = global [ symbolPromise ] . resolve ( 0 ) ;
1397+ } else if ( _mode === 'lazy' && patchedPromise !== global [ 'Promise' ] ) {
1398+ nativeMicroTaskQueuePromise = global [ 'Promise' ] . resolve ( 0 ) ;
13331399 }
13341400 }
13351401 if ( nativeMicroTaskQueuePromise ) {
@@ -1382,7 +1448,9 @@ const Zone: ZoneType = (function(global: any) {
13821448 eventTask : 'eventTask' = 'eventTask' ;
13831449
13841450 const patches : { [ key : string ] : any } = { } ;
1385- const delegates : { proto : any , property : string , patched : any , origin : any } [ ] = [ ] ;
1451+ let patchedPromise : any ;
1452+ const delegates :
1453+ { proto : any , property : string , patched : any , origin : any , isPropertyDesc : boolean } [ ] = [ ] ;
13861454 let patchLoaded = false ;
13871455 const _api : _ZonePrivate = {
13881456 symbol : __symbol__ ,
@@ -1409,7 +1477,7 @@ const Zone: ZoneType = (function(global: any) {
14091477 let _currentZoneFrame : _ZoneFrame = { parent : null , zone : new Zone ( null , null ) } ;
14101478 let _currentTask : Task | null = null ;
14111479 let _numberOfNestedTaskFrames = 0 ;
1412- let _mode : 'lazy' | 'normal' = 'normal' ;
1480+ let _mode : 'lazy' | 'normal' = global [ '__zone_symbol__load_mode' ] || 'normal' ;
14131481
14141482 function noop ( ) { }
14151483
0 commit comments