@@ -15,168 +15,181 @@ import {eventTargetPatch} from './event-target';
15
15
import { propertyDescriptorPatch } from './property-descriptor' ;
16
16
import { registerElementPatch } from './register-element' ;
17
17
18
- const set = 'set' ;
19
- const clear = 'clear' ;
20
- const blockingMethods = [ 'alert' , 'prompt' , 'confirm' ] ;
21
- const _global : any =
22
- typeof window !== 'undefined' && window || typeof self !== 'undefined' && self || global ;
23
-
24
- patchTimer ( _global , set , clear , 'Timeout' ) ;
25
- patchTimer ( _global , set , clear , 'Interval' ) ;
26
- patchTimer ( _global , set , clear , 'Immediate' ) ;
27
- patchTimer ( _global , 'request' , 'cancel' , 'AnimationFrame' ) ;
28
- patchTimer ( _global , 'mozRequest' , 'mozCancel' , 'AnimationFrame' ) ;
29
- patchTimer ( _global , 'webkitRequest' , 'webkitCancel' , 'AnimationFrame' ) ;
30
-
31
- for ( let i = 0 ; i < blockingMethods . length ; i ++ ) {
32
- const name = blockingMethods [ i ] ;
33
- patchMethod ( _global , name , ( delegate , symbol , name ) => {
34
- return function ( s : any , args : any [ ] ) {
35
- return Zone . current . run ( delegate , _global , args , name ) ;
36
- } ;
37
- } ) ;
38
- }
39
-
40
- eventTargetPatch ( _global ) ;
41
- // patch XMLHttpRequestEventTarget's addEventListener/removeEventListener
42
- const XMLHttpRequestEventTarget = ( _global as any ) [ 'XMLHttpRequestEventTarget' ] ;
43
- if ( XMLHttpRequestEventTarget && XMLHttpRequestEventTarget . prototype ) {
44
- patchEventTargetMethods ( XMLHttpRequestEventTarget . prototype ) ;
45
- }
46
- propertyDescriptorPatch ( _global ) ;
47
- patchClass ( 'MutationObserver' ) ;
48
- patchClass ( 'WebKitMutationObserver' ) ;
49
- patchClass ( 'FileReader' ) ;
50
- propertyPatch ( ) ;
51
- registerElementPatch ( _global ) ;
52
-
53
- // Treat XMLHTTPRequest as a macrotask.
54
- patchXHR ( _global ) ;
55
-
56
- const XHR_TASK = zoneSymbol ( 'xhrTask' ) ;
57
- const XHR_SYNC = zoneSymbol ( 'xhrSync' ) ;
58
- const XHR_LISTENER = zoneSymbol ( 'xhrListener' ) ;
59
- const XHR_SCHEDULED = zoneSymbol ( 'xhrScheduled' ) ;
60
-
61
- interface XHROptions extends TaskData {
62
- target : any ;
63
- args : any [ ] ;
64
- aborted : boolean ;
65
- }
66
-
67
- function patchXHR ( window : any ) {
68
- function findPendingTask ( target : any ) {
69
- const pendingTask : Task = target [ XHR_TASK ] ;
70
- return pendingTask ;
18
+ Zone . __load_patch ( 'timers' , ( global : any , Zone : ZoneType , api : _ZonePrivate ) => {
19
+ const set = 'set' ;
20
+ const clear = 'clear' ;
21
+ patchTimer ( global , set , clear , 'Timeout' ) ;
22
+ patchTimer ( global , set , clear , 'Interval' ) ;
23
+ patchTimer ( global , set , clear , 'Immediate' ) ;
24
+ patchTimer ( global , 'request' , 'cancel' , 'AnimationFrame' ) ;
25
+ patchTimer ( global , 'mozRequest' , 'mozCancel' , 'AnimationFrame' ) ;
26
+ patchTimer ( global , 'webkitRequest' , 'webkitCancel' , 'AnimationFrame' ) ;
27
+ } ) ;
28
+
29
+ Zone . __load_patch ( 'blocking' , ( global : any , Zone : ZoneType , api : _ZonePrivate ) => {
30
+ const blockingMethods = [ 'alert' , 'prompt' , 'confirm' ] ;
31
+ for ( let i = 0 ; i < blockingMethods . length ; i ++ ) {
32
+ const name = blockingMethods [ i ] ;
33
+ patchMethod ( global , name , ( delegate , symbol , name ) => {
34
+ return function ( s : any , args : any [ ] ) {
35
+ return Zone . current . run ( delegate , global , args , name ) ;
36
+ } ;
37
+ } ) ;
38
+ }
39
+ } ) ;
40
+
41
+ Zone . __load_patch ( 'EventTarget' , ( global : any , Zone : ZoneType , api : _ZonePrivate ) => {
42
+ eventTargetPatch ( global ) ;
43
+ // patch XMLHttpRequestEventTarget's addEventListener/removeEventListener
44
+ const XMLHttpRequestEventTarget = ( global as any ) [ 'XMLHttpRequestEventTarget' ] ;
45
+ if ( XMLHttpRequestEventTarget && XMLHttpRequestEventTarget . prototype ) {
46
+ patchEventTargetMethods ( XMLHttpRequestEventTarget . prototype ) ;
47
+ }
48
+ propertyDescriptorPatch ( global ) ;
49
+ patchClass ( 'MutationObserver' ) ;
50
+ patchClass ( 'WebKitMutationObserver' ) ;
51
+ patchClass ( 'FileReader' ) ;
52
+ propertyPatch ( ) ;
53
+ registerElementPatch ( global ) ;
54
+ } ) ;
55
+
56
+ Zone . __load_patch ( 'XHR' , ( global : any , Zone : ZoneType , api : _ZonePrivate ) => {
57
+ // Treat XMLHTTPRequest as a macrotask.
58
+ patchXHR ( global ) ;
59
+
60
+ const XHR_TASK = zoneSymbol ( 'xhrTask' ) ;
61
+ const XHR_SYNC = zoneSymbol ( 'xhrSync' ) ;
62
+ const XHR_LISTENER = zoneSymbol ( 'xhrListener' ) ;
63
+ const XHR_SCHEDULED = zoneSymbol ( 'xhrScheduled' ) ;
64
+
65
+ interface XHROptions extends TaskData {
66
+ target : any ;
67
+ args : any [ ] ;
68
+ aborted : boolean ;
71
69
}
72
70
73
- function scheduleTask ( task : Task ) {
74
- ( XMLHttpRequest as any ) [ XHR_SCHEDULED ] = false ;
75
- const data = < XHROptions > task . data ;
76
- // remove existing event listener
77
- const listener = data . target [ XHR_LISTENER ] ;
78
- if ( listener ) {
79
- data . target . removeEventListener ( 'readystatechange' , listener ) ;
71
+ function patchXHR ( window : any ) {
72
+ function findPendingTask ( target : any ) {
73
+ const pendingTask : Task = target [ XHR_TASK ] ;
74
+ return pendingTask ;
80
75
}
81
- const newListener = data . target [ XHR_LISTENER ] = ( ) => {
82
- if ( data . target . readyState === data . target . DONE ) {
83
- // sometimes on some browsers XMLHttpRequest will fire onreadystatechange with
84
- // readyState=4 multiple times, so we need to check task state here
85
- if ( ! data . aborted && ( XMLHttpRequest as any ) [ XHR_SCHEDULED ] && task . state === 'scheduled' ) {
86
- task . invoke ( ) ;
87
- }
76
+
77
+ function scheduleTask ( task : Task ) {
78
+ ( XMLHttpRequest as any ) [ XHR_SCHEDULED ] = false ;
79
+ const data = < XHROptions > task . data ;
80
+ // remove existing event listener
81
+ const listener = data . target [ XHR_LISTENER ] ;
82
+ if ( listener ) {
83
+ data . target . removeEventListener ( 'readystatechange' , listener ) ;
88
84
}
89
- } ;
90
- data . target . addEventListener ( 'readystatechange' , newListener ) ;
85
+ const newListener = data . target [ XHR_LISTENER ] = ( ) => {
86
+ if ( data . target . readyState === data . target . DONE ) {
87
+ // sometimes on some browsers XMLHttpRequest will fire onreadystatechange with
88
+ // readyState=4 multiple times, so we need to check task state here
89
+ if ( ! data . aborted && ( XMLHttpRequest as any ) [ XHR_SCHEDULED ] &&
90
+ task . state === 'scheduled' ) {
91
+ task . invoke ( ) ;
92
+ }
93
+ }
94
+ } ;
95
+ data . target . addEventListener ( 'readystatechange' , newListener ) ;
91
96
92
- const storedTask : Task = data . target [ XHR_TASK ] ;
93
- if ( ! storedTask ) {
94
- data . target [ XHR_TASK ] = task ;
97
+ const storedTask : Task = data . target [ XHR_TASK ] ;
98
+ if ( ! storedTask ) {
99
+ data . target [ XHR_TASK ] = task ;
100
+ }
101
+ sendNative . apply ( data . target , data . args ) ;
102
+ ( XMLHttpRequest as any ) [ XHR_SCHEDULED ] = true ;
103
+ return task ;
95
104
}
96
- sendNative . apply ( data . target , data . args ) ;
97
- ( XMLHttpRequest as any ) [ XHR_SCHEDULED ] = true ;
98
- return task ;
99
- }
100
105
101
- function placeholderCallback ( ) { }
106
+ function placeholderCallback ( ) { }
102
107
103
- function clearTask ( task : Task ) {
104
- const data = < XHROptions > task . data ;
105
- // Note - ideally, we would call data.target.removeEventListener here, but it's too late
106
- // to prevent it from firing. So instead, we store info for the event listener.
107
- data . aborted = true ;
108
- return abortNative . apply ( data . target , data . args ) ;
109
- }
110
-
111
- const openNative : Function =
112
- patchMethod ( window . XMLHttpRequest . prototype , 'open' , ( ) => function ( self : any , args : any [ ] ) {
113
- self [ XHR_SYNC ] = args [ 2 ] == false ;
114
- return openNative . apply ( self , args ) ;
115
- } ) ;
116
-
117
- const sendNative : Function =
118
- patchMethod ( window . XMLHttpRequest . prototype , 'send' , ( ) => function ( self : any , args : any [ ] ) {
119
- const zone = Zone . current ;
120
- if ( self [ XHR_SYNC ] ) {
121
- // if the XHR is sync there is no task to schedule, just execute the code.
122
- return sendNative . apply ( self , args ) ;
123
- } else {
124
- const options : XHROptions =
125
- { target : self , isPeriodic : false , delay : null , args : args , aborted : false } ;
126
- return zone . scheduleMacroTask (
127
- 'XMLHttpRequest.send' , placeholderCallback , options , scheduleTask , clearTask ) ;
128
- }
129
- } ) ;
108
+ function clearTask ( task : Task ) {
109
+ const data = < XHROptions > task . data ;
110
+ // Note - ideally, we would call data.target.removeEventListener here, but it's too late
111
+ // to prevent it from firing. So instead, we store info for the event listener.
112
+ data . aborted = true ;
113
+ return abortNative . apply ( data . target , data . args ) ;
114
+ }
130
115
131
- const abortNative = patchMethod (
132
- window . XMLHttpRequest . prototype , 'abort' ,
133
- ( delegate : Function ) => function ( self : any , args : any [ ] ) {
134
- const task : Task = findPendingTask ( self ) ;
135
- if ( task && typeof task . type == 'string' ) {
136
- // If the XHR has already completed, do nothing.
137
- // If the XHR has already been aborted, do nothing.
138
- // Fix #569, call abort multiple times before done will cause
139
- // macroTask task count be negative number
140
- if ( task . cancelFn == null || ( task . data && ( < XHROptions > task . data ) . aborted ) ) {
141
- return ;
116
+ const openNative : Function = patchMethod (
117
+ window . XMLHttpRequest . prototype , 'open' , ( ) => function ( self : any , args : any [ ] ) {
118
+ self [ XHR_SYNC ] = args [ 2 ] == false ;
119
+ return openNative . apply ( self , args ) ;
120
+ } ) ;
121
+
122
+ const sendNative : Function = patchMethod (
123
+ window . XMLHttpRequest . prototype , 'send' , ( ) => function ( self : any , args : any [ ] ) {
124
+ const zone = Zone . current ;
125
+ if ( self [ XHR_SYNC ] ) {
126
+ // if the XHR is sync there is no task to schedule, just execute the code.
127
+ return sendNative . apply ( self , args ) ;
128
+ } else {
129
+ const options : XHROptions =
130
+ { target : self , isPeriodic : false , delay : null , args : args , aborted : false } ;
131
+ return zone . scheduleMacroTask (
132
+ 'XMLHttpRequest.send' , placeholderCallback , options , scheduleTask , clearTask ) ;
142
133
}
143
- task . zone . cancelTask ( task ) ;
134
+ } ) ;
135
+
136
+ const abortNative = patchMethod (
137
+ window . XMLHttpRequest . prototype , 'abort' ,
138
+ ( delegate : Function ) => function ( self : any , args : any [ ] ) {
139
+ const task : Task = findPendingTask ( self ) ;
140
+ if ( task && typeof task . type == 'string' ) {
141
+ // If the XHR has already completed, do nothing.
142
+ // If the XHR has already been aborted, do nothing.
143
+ // Fix #569, call abort multiple times before done will cause
144
+ // macroTask task count be negative number
145
+ if ( task . cancelFn == null || ( task . data && ( < XHROptions > task . data ) . aborted ) ) {
146
+ return ;
147
+ }
148
+ task . zone . cancelTask ( task ) ;
149
+ }
150
+ // Otherwise, we are trying to abort an XHR which has not yet been sent, so there is no
151
+ // task
152
+ // to cancel. Do nothing.
153
+ } ) ;
154
+ }
155
+ } ) ;
156
+
157
+ Zone . __load_patch ( 'geo' , ( global : any , Zone : ZoneType , api : _ZonePrivate ) => {
158
+ /// GEO_LOCATION
159
+ if ( global [ 'navigator' ] && global [ 'navigator' ] . geolocation ) {
160
+ patchPrototype ( global [ 'navigator' ] . geolocation , [ 'getCurrentPosition' , 'watchPosition' ] ) ;
161
+ }
162
+ } ) ;
163
+
164
+ Zone . __load_patch ( 'toString' , ( global : any , Zone : ZoneType , api : _ZonePrivate ) => {
165
+ // patch Func.prototype.toString to let them look like native
166
+ patchFuncToString ( ) ;
167
+ // patch Object.prototype.toString to let them look like native
168
+ patchObjectToString ( ) ;
169
+ } ) ;
170
+
171
+ Zone . __load_patch ( 'promiseRejectionHandler' , ( global : any , Zone : ZoneType , api : _ZonePrivate ) => {
172
+ // handle unhandled promise rejection
173
+ function findPromiseRejectionHandler ( evtName : string ) {
174
+ return function ( e : any ) {
175
+ const eventTasks = findEventTask ( global , evtName ) ;
176
+ eventTasks . forEach ( eventTask => {
177
+ // windows has added unhandledrejection event listener
178
+ // trigger the event listener
179
+ const PromiseRejectionEvent = global [ 'PromiseRejectionEvent' ] ;
180
+ if ( PromiseRejectionEvent ) {
181
+ const evt = new PromiseRejectionEvent ( evtName , { promise : e . promise , reason : e . rejection } ) ;
182
+ eventTask . invoke ( evt ) ;
144
183
}
145
- // Otherwise, we are trying to abort an XHR which has not yet been sent, so there is no task
146
- // to cancel. Do nothing.
147
184
} ) ;
148
- }
149
-
150
- /// GEO_LOCATION
151
- if ( _global [ 'navigator' ] && _global [ 'navigator' ] . geolocation ) {
152
- patchPrototype ( _global [ 'navigator' ] . geolocation , [ 'getCurrentPosition' , 'watchPosition' ] ) ;
153
- }
154
-
155
- // patch Func.prototype.toString to let them look like native
156
- patchFuncToString ( ) ;
157
- // patch Object.prototype.toString to let them look like native
158
- patchObjectToString ( ) ;
159
-
160
- // handle unhandled promise rejection
161
- function findPromiseRejectionHandler ( evtName : string ) {
162
- return function ( e : any ) {
163
- const eventTasks = findEventTask ( _global , evtName ) ;
164
- eventTasks . forEach ( eventTask => {
165
- // windows has added unhandledrejection event listener
166
- // trigger the event listener
167
- const PromiseRejectionEvent = _global [ 'PromiseRejectionEvent' ] ;
168
- if ( PromiseRejectionEvent ) {
169
- const evt = new PromiseRejectionEvent ( evtName , { promise : e . promise , reason : e . rejection } ) ;
170
- eventTask . invoke ( evt ) ;
171
- }
172
- } ) ;
173
- } ;
174
- }
185
+ } ;
186
+ }
175
187
176
- if ( _global [ 'PromiseRejectionEvent' ] ) {
177
- ( Zone as any ) [ zoneSymbol ( 'unhandledPromiseRejectionHandler' ) ] =
178
- findPromiseRejectionHandler ( 'unhandledrejection' ) ;
188
+ if ( global [ 'PromiseRejectionEvent' ] ) {
189
+ ( Zone as any ) [ zoneSymbol ( 'unhandledPromiseRejectionHandler' ) ] =
190
+ findPromiseRejectionHandler ( 'unhandledrejection' ) ;
179
191
180
- ( Zone as any ) [ zoneSymbol ( 'rejectionHandledHandler' ) ] =
181
- findPromiseRejectionHandler ( 'rejectionhandled' ) ;
182
- }
192
+ ( Zone as any ) [ zoneSymbol ( 'rejectionHandledHandler' ) ] =
193
+ findPromiseRejectionHandler ( 'rejectionhandled' ) ;
194
+ }
195
+ } ) ;
0 commit comments