@@ -28,7 +28,11 @@ function Browser(window, document, $log, $sniffer) {
2828 history = window . history ,
2929 setTimeout = window . setTimeout ,
3030 clearTimeout = window . clearTimeout ,
31- pendingDeferIds = { } ;
31+ setInterval = window . setInterval ,
32+ clearInterval = window . clearInterval ,
33+ pendingDeferIds = { } ,
34+ currentIntervalIds = { } ,
35+ active = true ;
3236
3337 self . isMock = false ;
3438
@@ -79,6 +83,15 @@ function Browser(window, document, $log, $sniffer) {
7983 }
8084 } ;
8185
86+ self . shutdown = function ( ) {
87+ active = false ;
88+ forEach ( currentIntervalIds , function ( ignore , intervalId ) {
89+ delete currentIntervalIds [ intervalId ] ;
90+ clearInterval ( + intervalId ) ;
91+ } ) ;
92+ jqLite ( window ) . off ( 'hashchange popstate' , cacheStateAndFireUrlChange ) ;
93+ } ;
94+
8295 //////////////////////////////////////////////////////////////
8396 // URL API
8497 //////////////////////////////////////////////////////////////
@@ -270,16 +283,6 @@ function Browser(window, document, $log, $sniffer) {
270283 return callback ;
271284 } ;
272285
273- /**
274- * @private
275- * Remove popstate and hashchange handler from window.
276- *
277- * NOTE: this api is intended for use only by $rootScope.
278- */
279- self . $$applicationDestroyed = function ( ) {
280- jqLite ( window ) . off ( 'hashchange popstate' , cacheStateAndFireUrlChange ) ;
281- } ;
282-
283286 /**
284287 * Checks whether the url has changed outside of Angular.
285288 * Needs to be exported to be able to check for changes that have been done in sync,
@@ -321,12 +324,16 @@ function Browser(window, document, $log, $sniffer) {
321324 */
322325 self . defer = function ( fn , delay ) {
323326 var timeoutId ;
324- outstandingRequestCount ++ ;
325- timeoutId = setTimeout ( function ( ) {
326- delete pendingDeferIds [ timeoutId ] ;
327- completeOutstandingRequest ( fn ) ;
328- } , delay || 0 ) ;
329- pendingDeferIds [ timeoutId ] = true ;
327+ if ( active ) {
328+ outstandingRequestCount ++ ;
329+ timeoutId = setTimeout ( function ( ) {
330+ delete pendingDeferIds [ timeoutId ] ;
331+ completeOutstandingRequest ( fn ) ;
332+ } , delay || 0 ) ;
333+ pendingDeferIds [ timeoutId ] = true ;
334+ } else {
335+ timeoutId = 0 ;
336+ }
330337 return timeoutId ;
331338 } ;
332339
@@ -351,11 +358,57 @@ function Browser(window, document, $log, $sniffer) {
351358 return false ;
352359 } ;
353360
361+
362+ /**
363+ * @name $browser#interval
364+ * @param {function() } fn A function, who's execution should be executed.
365+ * @param {number= } interval in milliseconds on how often to execute the function.
366+ * @returns {* } IntervalId that can be used to cancel the task via `$browser.interval.cancel()`.
367+ *
368+ * @description
369+ * Executes a fn asynchronously via `setInterval(fn, interval)`.
370+ *
371+ */
372+ self . interval = function ( fn , interval ) {
373+ var intervalId ;
374+ if ( active ) {
375+ intervalId = setInterval ( fn , interval ) ;
376+ currentIntervalIds [ intervalId ] = true ;
377+ } else {
378+ intervalId = 0 ;
379+ }
380+ return intervalId ;
381+ } ;
382+
383+
384+ /**
385+ * @name $browser#interval.cancel
386+ *
387+ * @description
388+ * Cancels a interval task identified with `intervalId`.
389+ *
390+ * @param {* } intervalId Token returned by the `$browser.interval` function.
391+ * @returns {boolean } Returns `true` if the task was successfully canceled, and
392+ * `false` if the task was already canceled.
393+ */
394+ self . interval . cancel = function ( intervalId ) {
395+ if ( currentIntervalIds [ intervalId ] ) {
396+ delete currentIntervalIds [ intervalId ] ;
397+ clearInterval ( intervalId ) ;
398+ return true ;
399+ }
400+ return false ;
401+ } ;
354402}
355403
356- function $BrowserProvider ( ) {
404+ function $BrowserProvider ( $shutdownProvider ) {
405+ var browser ;
406+
407+ $shutdownProvider . register ( function ( ) { if ( browser ) { browser . shutdown ( ) ; } } ) ;
357408 this . $get = [ '$window' , '$log' , '$sniffer' , '$document' ,
358409 function ( $window , $log , $sniffer , $document ) {
359- return new Browser ( $window , $document , $log , $sniffer ) ;
410+ return browser = new Browser ( $window , $document , $log , $sniffer ) ;
360411 } ] ;
361412}
413+
414+ $BrowserProvider . $inject = [ '$shutdownProvider' ] ;
0 commit comments