@@ -58,12 +58,21 @@ Zone.prototype = {
5858 } ,
5959
6060 bind : function ( fn ) {
61+ this . enqueueTask ( fn ) ;
6162 var zone = this . fork ( ) ;
6263 return function zoneBoundFn ( ) {
6364 return zone . run ( fn , this , arguments ) ;
6465 } ;
6566 } ,
6667
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+
6776 run : function run ( fn , applyTo , applyWith ) {
6877 applyWith = applyWith || [ ] ;
6978
@@ -90,18 +99,72 @@ Zone.prototype = {
9099
91100 beforeTask : function ( ) { } ,
92101 onZoneCreated : function ( ) { } ,
93- afterTask : function ( ) { }
102+ afterTask : function ( ) { } ,
103+ enqueueTask : function ( ) { } ,
104+ dequeueTask : function ( ) { }
94105} ;
95106
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 ) {
97155 fnNames . forEach ( function ( name ) {
98156 var delegate = obj [ name ] ;
157+
99158 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 ) ;
102165 } ;
103166
104- obj [ name ] = function marker ( ) {
167+ obj [ name ] = function ( ) {
105168 return zone [ name ] . apply ( this , arguments ) ;
106169 } ;
107170 }
@@ -128,6 +191,16 @@ Zone.bindArguments = function (args) {
128191 return args ;
129192} ;
130193
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+
131204Zone . patchableFn = function ( obj , fnNames ) {
132205 fnNames . forEach ( function ( name ) {
133206 var delegate = obj [ name ] ;
@@ -206,17 +279,24 @@ Zone.patchEventTargetMethods = function (obj) {
206279 var removeDelegate = obj . removeEventListener ;
207280 obj . removeEventListener = function ( eventName , fn ) {
208281 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 ;
210285 } ;
211286} ;
212287
213288Zone . 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 , [
217296 'requestAnimationFrame' ,
218297 'webkitRequestAnimationFrame'
219298 ] ) ;
299+
220300 Zone . patchableFn ( window , [ 'alert' , 'prompt' ] ) ;
221301
222302 // patched properties depend on addEventListener, so this needs to come first
@@ -316,7 +396,7 @@ Zone.patchViaCapturingAllTheEvents = function () {
316396 } ) ;
317397} ;
318398
319- // TODO: wrap some native API
399+ // wrap some native API on `window`
320400Zone . patchClass = function ( className ) {
321401 var OriginalClass = window [ className ] ;
322402 if ( ! OriginalClass ) {
0 commit comments