@@ -58,12 +58,21 @@ Zone.prototype = {
58
58
} ,
59
59
60
60
bind : function ( fn ) {
61
+ this . enqueueTask ( fn ) ;
61
62
var zone = this . fork ( ) ;
62
63
return function zoneBoundFn ( ) {
63
64
return zone . run ( fn , this , arguments ) ;
64
65
} ;
65
66
} ,
66
67
68
+ bindOnce : function ( fn ) {
69
+ return this . bind ( function ( ) {
70
+ var result = fn . apply ( this , arguments ) ;
71
+ zone . dequeueTask ( fn ) ;
72
+ return result ;
73
+ } ) ;
74
+ } ,
75
+
67
76
run : function run ( fn , applyTo , applyWith ) {
68
77
applyWith = applyWith || [ ] ;
69
78
@@ -90,18 +99,72 @@ Zone.prototype = {
90
99
91
100
beforeTask : function ( ) { } ,
92
101
onZoneCreated : function ( ) { } ,
93
- afterTask : function ( ) { }
102
+ afterTask : function ( ) { } ,
103
+ enqueueTask : function ( ) { } ,
104
+ dequeueTask : function ( ) { }
94
105
} ;
95
106
96
- Zone . patchFn = function ( obj , fnNames ) {
107
+
108
+ Zone . patchSetClearFn = function ( obj , fnNames ) {
109
+ fnNames . map ( function ( name ) {
110
+ return name [ 0 ] . toUpperCase ( ) + name . substr ( 1 ) ;
111
+ } ) .
112
+ forEach ( function ( name ) {
113
+ var setName = 'set' + name ;
114
+ var clearName = 'clear' + name ;
115
+ var delegate = obj [ setName ] ;
116
+
117
+ if ( delegate ) {
118
+ var ids = { } ;
119
+
120
+ zone [ setName ] = function ( fn ) {
121
+ var id ;
122
+ arguments [ 0 ] = function ( ) {
123
+ delete ids [ id ] ;
124
+ return fn . apply ( this , arguments ) ;
125
+ } ;
126
+ var args = Zone . bindArgumentsOnce ( arguments ) ;
127
+ id = delegate . apply ( obj , args ) ;
128
+ ids [ id ] = true ;
129
+ return id ;
130
+ } ;
131
+
132
+ obj [ setName ] = function ( ) {
133
+ return zone [ setName ] . apply ( this , arguments ) ;
134
+ } ;
135
+
136
+ var clearDelegate = obj [ clearName ] ;
137
+
138
+ zone [ clearName ] = function ( id ) {
139
+ if ( ids [ id ] ) {
140
+ delete ids [ id ] ;
141
+ zone . dequeueTask ( ) ;
142
+ }
143
+ return clearDelegate . apply ( this , arguments ) ;
144
+ } ;
145
+
146
+ obj [ clearName ] = function ( ) {
147
+ return zone [ clearName ] . apply ( this , arguments ) ;
148
+ } ;
149
+ }
150
+ } ) ;
151
+ } ;
152
+
153
+
154
+ Zone . patchSetFn = function ( obj , fnNames ) {
97
155
fnNames . forEach ( function ( name ) {
98
156
var delegate = obj [ name ] ;
157
+
99
158
if ( delegate ) {
100
- zone [ name ] = function ( ) {
101
- return delegate . apply ( obj , Zone . bindArguments ( arguments ) ) ;
159
+ zone [ name ] = function ( fn ) {
160
+ arguments [ 0 ] = function ( ) {
161
+ return fn . apply ( this , arguments ) ;
162
+ } ;
163
+ var args = Zone . bindArgumentsOnce ( arguments ) ;
164
+ return delegate . apply ( obj , args ) ;
102
165
} ;
103
166
104
- obj [ name ] = function marker ( ) {
167
+ obj [ name ] = function ( ) {
105
168
return zone [ name ] . apply ( this , arguments ) ;
106
169
} ;
107
170
}
@@ -128,6 +191,16 @@ Zone.bindArguments = function (args) {
128
191
return args ;
129
192
} ;
130
193
194
+
195
+ Zone . bindArgumentsOnce = function ( args ) {
196
+ for ( var i = args . length - 1 ; i >= 0 ; i -- ) {
197
+ if ( typeof args [ i ] === 'function' ) {
198
+ args [ i ] = zone . bindOnce ( args [ i ] ) ;
199
+ }
200
+ }
201
+ return args ;
202
+ } ;
203
+
131
204
Zone . patchableFn = function ( obj , fnNames ) {
132
205
fnNames . forEach ( function ( name ) {
133
206
var delegate = obj [ name ] ;
@@ -206,17 +279,24 @@ Zone.patchEventTargetMethods = function (obj) {
206
279
var removeDelegate = obj . removeEventListener ;
207
280
obj . removeEventListener = function ( eventName , fn ) {
208
281
arguments [ 1 ] = arguments [ 1 ] . _bound || arguments [ 1 ] ;
209
- return removeDelegate . apply ( this , arguments ) ;
282
+ var result = removeDelegate . apply ( this , arguments ) ;
283
+ zone . dequeueTask ( fn ) ;
284
+ return result ;
210
285
} ;
211
286
} ;
212
287
213
288
Zone . patch = function patch ( ) {
214
- Zone . patchFn ( window , [
215
- 'setTimeout' ,
216
- 'setInterval' ,
289
+ Zone . patchSetClearFn ( window , [
290
+ 'timeout' ,
291
+ 'interval' ,
292
+ 'immediate'
293
+ ] ) ;
294
+
295
+ Zone . patchSetFn ( window , [
217
296
'requestAnimationFrame' ,
218
297
'webkitRequestAnimationFrame'
219
298
] ) ;
299
+
220
300
Zone . patchableFn ( window , [ 'alert' , 'prompt' ] ) ;
221
301
222
302
// patched properties depend on addEventListener, so this needs to come first
@@ -316,7 +396,7 @@ Zone.patchViaCapturingAllTheEvents = function () {
316
396
} ) ;
317
397
} ;
318
398
319
- // TODO: wrap some native API
399
+ // wrap some native API on `window`
320
400
Zone . patchClass = function ( className ) {
321
401
var OriginalClass = window [ className ] ;
322
402
if ( ! OriginalClass ) {
0 commit comments