1
1
/*** Directives and services for responding to idle users in AngularJS
2
2
* @author Mike Grabski <me@mikegrabski.com>
3
- * @version v1.1.0
3
+ * @version v1.1.1
4
4
* @link https://github.com/HackedByChinese/ng-idle.git
5
5
* @license MIT
6
6
*/
@@ -275,12 +275,28 @@ angular.module('ngIdle.idle', ['ngIdle.keepalive', 'ngIdle.localStorage'])
275
275
}
276
276
} ;
277
277
278
- $document . find ( 'body' ) . on ( options . interrupt , function ( ) {
279
- svc . interrupt ( ) ;
278
+ $document . find ( 'html' ) . on ( options . interrupt , function ( event ) {
279
+ if ( event . type === 'mousemove' && event . originalEvent && event . originalEvent . movementX === 0 && event . originalEvent . movementY === 0 ) {
280
+ return ; // Fix for Chrome desktop notifications, triggering mousemove event.
281
+ }
282
+
283
+ /*
284
+ note:
285
+ webkit fires fake mousemove events when the user has done nothing, so the idle will never time out while the cursor is over the webpage
286
+ Original webkit bug report which caused this issue:
287
+ https://bugs.webkit.org/show_bug.cgi?id=17052
288
+ Chromium bug reports for issue:
289
+ https://code.google.com/p/chromium/issues/detail?id=5598
290
+ https://code.google.com/p/chromium/issues/detail?id=241476
291
+ https://code.google.com/p/chromium/issues/detail?id=317007
292
+ */
293
+ if ( event . type !== 'mousemove' || angular . isUndefined ( event . movementX ) || ( event . movementX || event . movementY ) ) {
294
+ svc . interrupt ( ) ;
295
+ }
280
296
} ) ;
281
297
282
298
var wrap = function ( event ) {
283
- if ( event . key === 'ngIdle.expiry' && event . newValue !== event . oldValue ) {
299
+ if ( event . key === 'ngIdle.expiry' && event . newValue && event . newValue !== event . oldValue ) {
284
300
var val = angular . fromJson ( event . newValue ) ;
285
301
if ( val . id === id ) return ;
286
302
svc . interrupt ( true ) ;
@@ -322,66 +338,79 @@ angular.module('ngIdle.countdown', ['ngIdle.idle'])
322
338
} ] ) ;
323
339
324
340
angular . module ( 'ngIdle.title' , [ ] )
325
- . factory ( 'Title' , [ '$document' , '$interpolate' , function ( $document , $interpolate ) {
341
+ . provider ( 'Title' , function ( ) {
342
+ var options = {
343
+ enabled : true
344
+ } ;
345
+
346
+ var setEnabled = this . enabled = function ( enabled ) {
347
+ options . enabled = enabled === true ;
348
+ } ;
326
349
327
350
function padLeft ( nr , n , str ) {
328
351
return new Array ( n - String ( nr ) . length + 1 ) . join ( str || '0' ) + nr ;
329
352
}
330
353
331
- var state = {
332
- original : null ,
333
- idle : '{{minutes}}:{{seconds}} until your session times out!' ,
334
- timedout : 'Your session has expired.'
335
- } ;
336
-
337
- return {
338
- original : function ( val ) {
339
- if ( angular . isUndefined ( val ) ) return state . original ;
340
-
341
- state . original = val ;
342
- } ,
343
- store : function ( overwrite ) {
344
- if ( overwrite || ! state . original ) state . original = this . value ( ) ;
345
- } ,
346
- value : function ( val ) {
347
- if ( angular . isUndefined ( val ) ) return $document [ 0 ] . title ;
348
-
349
- $document [ 0 ] . title = val ;
350
- } ,
351
- idleMessage : function ( val ) {
352
- if ( angular . isUndefined ( val ) ) return state . idle ;
353
-
354
- state . idle = val ;
355
- } ,
356
- timedOutMessage : function ( val ) {
357
- if ( angular . isUndefined ( val ) ) return state . timedout ;
358
-
359
- state . timedout = val ;
360
- } ,
361
- setAsIdle : function ( countdown ) {
362
- this . store ( ) ;
363
-
364
- var remaining = { totalSeconds : countdown } ;
365
- remaining . minutes = Math . floor ( countdown / 60 ) ;
366
- remaining . seconds = padLeft ( countdown - remaining . minutes * 60 , 2 ) ;
367
-
368
- this . value ( $interpolate ( this . idleMessage ( ) ) ( remaining ) ) ;
369
- } ,
370
- setAsTimedOut : function ( ) {
371
- this . store ( ) ;
354
+ this . $get = [ '$document' , '$interpolate' , function ( $document , $interpolate ) {
355
+ var state = {
356
+ original : null ,
357
+ idle : '{{minutes}}:{{seconds}} until your session times out!' ,
358
+ timedout : 'Your session has expired.'
359
+ } ;
372
360
373
- this . value ( this . timedOutMessage ( ) ) ;
374
- } ,
375
- restore : function ( ) {
376
- if ( this . original ( ) ) this . value ( this . original ( ) ) ;
377
- }
378
- } ;
379
- } ] )
361
+ return {
362
+ setEnabled : setEnabled ,
363
+ isEnabled : function ( ) {
364
+ return options . enabled ;
365
+ } ,
366
+ original : function ( val ) {
367
+ if ( angular . isUndefined ( val ) ) return state . original ;
368
+
369
+ state . original = val ;
370
+ } ,
371
+ store : function ( overwrite ) {
372
+ if ( overwrite || ! state . original ) state . original = this . value ( ) ;
373
+ } ,
374
+ value : function ( val ) {
375
+ if ( angular . isUndefined ( val ) ) return $document [ 0 ] . title ;
376
+
377
+ $document [ 0 ] . title = val ;
378
+ } ,
379
+ idleMessage : function ( val ) {
380
+ if ( angular . isUndefined ( val ) ) return state . idle ;
381
+
382
+ state . idle = val ;
383
+ } ,
384
+ timedOutMessage : function ( val ) {
385
+ if ( angular . isUndefined ( val ) ) return state . timedout ;
386
+
387
+ state . timedout = val ;
388
+ } ,
389
+ setAsIdle : function ( countdown ) {
390
+ this . store ( ) ;
391
+
392
+ var remaining = { totalSeconds : countdown } ;
393
+ remaining . minutes = Math . floor ( countdown / 60 ) ;
394
+ remaining . seconds = padLeft ( countdown - remaining . minutes * 60 , 2 ) ;
395
+
396
+ this . value ( $interpolate ( this . idleMessage ( ) ) ( remaining ) ) ;
397
+ } ,
398
+ setAsTimedOut : function ( ) {
399
+ this . store ( ) ;
400
+
401
+ this . value ( this . timedOutMessage ( ) ) ;
402
+ } ,
403
+ restore : function ( ) {
404
+ if ( this . original ( ) ) this . value ( this . original ( ) ) ;
405
+ }
406
+ } ;
407
+ } ] ;
408
+ } )
380
409
. directive ( 'title' , [ 'Title' , function ( Title ) {
381
410
return {
382
411
restrict : 'E' ,
383
412
link : function ( $scope , $element , $attr ) {
384
- if ( $attr . idleDisabled ) return ;
413
+ if ( ! Title . isEnabled ( ) || $attr . idleDisabled ) return ;
385
414
386
415
Title . store ( true ) ;
387
416
@@ -405,9 +434,50 @@ angular.module('ngIdle.title', [])
405
434
} ] ) ;
406
435
407
436
angular . module ( 'ngIdle.localStorage' , [ ] )
408
- . service ( 'IdleLocalStorage' , [ '$window' , function ( $window ) {
409
- var storage = $window . localStorage ;
410
-
437
+ . service ( 'IdleStorageAccessor' , [ '$window' , function ( $window ) {
438
+ return {
439
+ get : function ( ) {
440
+ return $window . localStorage ;
441
+ }
442
+ }
443
+ } ] )
444
+ . service ( 'IdleLocalStorage' , [ 'IdleStorageAccessor' , function ( IdleStorageAccessor ) {
445
+ function AlternativeStorage ( ) {
446
+ var storageMap = { } ;
447
+
448
+ this . setItem = function ( key , value ) {
449
+ storageMap [ key ] = value ;
450
+ } ;
451
+
452
+ this . getItem = function ( key ) {
453
+ if ( typeof storageMap [ key ] !== 'undefined' ) {
454
+ return storageMap [ key ] ;
455
+ }
456
+ return null ;
457
+ } ;
458
+
459
+ this . removeItem = function ( key ) {
460
+ storageMap [ key ] = undefined ;
461
+ } ;
462
+ }
463
+
464
+ function getStorage ( ) {
465
+ try {
466
+ var s = IdleStorageAccessor . get ( ) ;
467
+ s . setItem ( 'ngIdleStorage' , '' ) ;
468
+ s . removeItem ( 'ngIdleStorage' ) ;
469
+
470
+ return s ;
471
+ } catch ( err ) {
472
+ return new AlternativeStorage ( ) ;
473
+ }
474
+ }
475
+
476
+ // Safari, in Private Browsing Mode, looks like it supports localStorage but all calls to setItem
477
+ // throw QuotaExceededError. We're going to detect this and just silently drop any calls to setItem
478
+ // to avoid the entire page breaking, without having to do a check at each usage of Storage.
479
+ var storage = getStorage ( ) ;
480
+
411
481
return {
412
482
set : function ( key , value ) {
413
483
storage . setItem ( 'ngIdle.' + key , angular . toJson ( value ) ) ;
@@ -417,8 +487,11 @@ angular.module('ngIdle.localStorage', [])
417
487
} ,
418
488
remove : function ( key ) {
419
489
storage . removeItem ( 'ngIdle.' + key ) ;
490
+ } ,
491
+ _wrapped : function ( ) {
492
+ return storage ;
420
493
}
421
494
} ;
422
- } ] ) ;
495
+ } ] ) ;
423
496
424
497
} ) ( window , window . angular ) ;
0 commit comments