1'use strict'; 2 3(function() { 4 5 /** 6 * @ngdoc overview 7 * @name ngStorage 8 */ 9 10 angular.module('ngStorage', []). 11 12 provider('$localStorage', _storageProvider('localStorage')). 13 provider('$localStorageGlobal', _storageProvider('localStorageGlobal')). 14 15 provider('$sessionStorage', _storageProvider('sessionStorage')). 16 provider('$sessionStorageGlobal', _storageProvider('sessionStorageGlobal')); 17 18 function _storageProvider(storageType) { 19 // Add storage type to dispatch handling of the 'storage' events. 20 if (storageType==="localStorageGlobal" || storageType==="sessionStorageGlobal") { 21 var providerPrefix = 'global' + '-'; 22 } else { 23 var providerPrefix = 'ngStorage-' + storageType + '-'; 24 } 25 26 27 return { 28 setPrefix: function(value) { 29 if (angular.isString(value)) { 30 providerPrefix = value; 31 } 32 }, 33 $get: [ 34 '$rootScope', 35 '$window', 36 '$timeout', 37 '$log', 38 function( 39 $rootScope, 40 $window, 41 $timeout, 42 $log 43 ) { 44 45 function getStorageImpl(storageType) { 46 47 if (storageType === 'localStorageGlobal') { 48 var storageImpl = $window['localStorage']; 49 } else if (storageType === 'sessionStorageGlobal') { 50 var storageImpl = $window['sessionStorage']; 51 } else { 52 var storageImpl = $window[storageType]; 53 } 54 55 56 57 // When Safari (OS X or iOS) is in private browsing mode, it appears as though localStorage 58 // is available, but trying to call .setItem throws an exception below: 59 // "QUOTA_EXCEEDED_ERR: DOM Exception 22: An attempt was made to add something to storage that exceeded the quota." 60 if (storageImpl && (storageType === 'localStorage' || storageType === 'localStorageGlobal') ) { 61 var key = '__' + Math.round(Math.random() * 1e7); 62 63 try { 64 storageImpl.setItem(key, key); 65 storageImpl.removeItem(key); 66 } 67 catch (err) { 68 storageImpl = undefined; 69 } 70 } 71 72 if (!storageImpl && storageType !== 'localStorageGlobal' && storageType !== 'sessionStorageGlobal' ) { 73 $log.warn('This browser does not support Web Storage!'); 74 } 75 76 // Specifique TBS : Les Item préfixés par TBSGLOBAL sont egalement pris en compte 77 78 79 80 return storageImpl; 81 } 82 83 // Capture current prefix in a local variable in case the provider is used twice with different prefixes. 84 var prefix = providerPrefix, 85 prefixLen = prefix.length, 86 webStorageFallback = { 87 setItem: function() {}, 88 getItem: function() {}, 89 removeItem: function() {}, 90 clear: function() {}, 91 key: function() {}, 92 length: 0 93 }, 94 // #9: Assign a placeholder object if Web Storage is unavailable to prevent breaking the entire AngularJS app 95 webStorage = (getStorageImpl(storageType) || webStorageFallback), 96 $storage = { 97 $supported: function() { return (webStorage && webStorage !== webStorageFallback); }, 98 $default: function(items) { 99 for (var k in items) { 100 angular.isDefined($storage[k]) || ($storage[k] = items[k]); 101 } 102 103 return $storage; 104 }, 105 $reset: function(items) { 106 for (var k in $storage) { 107 '$' === k[0] || (delete $storage[k] && webStorage.removeItem(prefix + k)); 108 } 109 110 return $storage.$default(items); 111 } 112 }, 113 _last$storage, 114 _debounce; 115 116 for (var i = 0, k; i < webStorage.length; i++) { 117 // #8, #10: `webStorage.key(i)` may be an empty string (or throw an exception in IE9 if `webStorage` is empty) 118 k = webStorage.key(i); 119 if(k !== null && k !== undefined && prefix === k.slice(0, prefixLen)){ 120 $storage[k.slice(prefixLen)] = angular.fromJson(webStorage.getItem(k)); 121 } 122 } 123 124 125 _last$storage = angular.copy($storage); 126 127 $rootScope.$watch(function() { 128 _debounce || (_debounce = $timeout(function() { 129 _debounce = null; 130 131 if (!angular.equals($storage, _last$storage)) { 132 133 angular.forEach($storage, function(v, k) { 134 angular.isDefined(v) && '$' !== k[0] && webStorage.setItem(prefix + k, angular.toJson(v)); 135 136 delete _last$storage[k]; 137 }); 138 139 for (var k in _last$storage) { 140 webStorage.removeItem(prefix + k); 141 } 142 143 _last$storage = angular.copy($storage); 144 } 145 }, 100, false)); 146 }); 147 148 // #6: Use `$window.addEventListener` instead of `angular.element` to avoid the jQuery-specific `event.originalEvent` 149 $window.addEventListener && $window.addEventListener('storage', function(event) { 150 151 if (prefix === event.key.slice(0, prefixLen)) { 152 event.newValue ? $storage[event.key.slice(prefixLen)] = angular.fromJson(event.
152newValue) : delete $storage[event.key.slice(prefixLen)]; 153 _last$storage = angular.copy($storage); 154 155 $rootScope.$apply(); 156 } 157 }); 158 159 160 return $storage; 161 } 162 ] 163 } 164 } 165 166})();
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.