588 lines
		
	
	
		
			21 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
		
		
			
		
	
	
			588 lines
		
	
	
		
			21 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
|  | /** | ||
|  |  * An Angular module that gives you access to the browsers local storage | ||
|  |  * @version v0.6.0 - 2017-05-18 | ||
|  |  * @link https://github.com/grevory/angular-local-storage
 | ||
|  |  * @author grevory <greg@gregpike.ca> | ||
|  |  * @license MIT License, http://www.opensource.org/licenses/MIT
 | ||
|  |  */ | ||
|  | (function (window, angular) { | ||
|  | var isDefined = angular.isDefined, | ||
|  |   isUndefined = angular.isUndefined, | ||
|  |   isNumber = angular.isNumber, | ||
|  |   isObject = angular.isObject, | ||
|  |   isArray = angular.isArray, | ||
|  |   isString = angular.isString, | ||
|  |   extend = angular.extend, | ||
|  |   toJson = angular.toJson; | ||
|  | 
 | ||
|  | angular | ||
|  |   .module('LocalStorageModule', []) | ||
|  |   .provider('localStorageService', function() { | ||
|  |     // You should set a prefix to avoid overwriting any local storage variables from the rest of your app
 | ||
|  |     // e.g. localStorageServiceProvider.setPrefix('yourAppName');
 | ||
|  |     // With provider you can use config as this:
 | ||
|  |     // myApp.config(function (localStorageServiceProvider) {
 | ||
|  |     //    localStorageServiceProvider.prefix = 'yourAppName';
 | ||
|  |     // });
 | ||
|  |     this.prefix = 'ls'; | ||
|  | 
 | ||
|  |     // You could change web storage type localstorage or sessionStorage
 | ||
|  |     this.storageType = 'localStorage'; | ||
|  | 
 | ||
|  |     // Cookie options (usually in case of fallback)
 | ||
|  |     // expiry = Number of days before cookies expire // 0 = Does not expire
 | ||
|  |     // path = The web path the cookie represents
 | ||
|  |     // secure = Wether the cookies should be secure (i.e only sent on HTTPS requests)
 | ||
|  |     this.cookie = { | ||
|  |       expiry: 30, | ||
|  |       path: '/', | ||
|  |       secure: false | ||
|  |     }; | ||
|  | 
 | ||
|  |     // Decides wether we should default to cookies if localstorage is not supported.
 | ||
|  |     this.defaultToCookie = true; | ||
|  | 
 | ||
|  |     // Send signals for each of the following actions?
 | ||
|  |     this.notify = { | ||
|  |       setItem: true, | ||
|  |       removeItem: false | ||
|  |     }; | ||
|  | 
 | ||
|  |     // Setter for the prefix
 | ||
|  |     this.setPrefix = function(prefix) { | ||
|  |       this.prefix = prefix; | ||
|  |       return this; | ||
|  |     }; | ||
|  | 
 | ||
|  |     // Setter for the storageType
 | ||
|  |     this.setStorageType = function(storageType) { | ||
|  |       this.storageType = storageType; | ||
|  |       return this; | ||
|  |     }; | ||
|  |     // Setter for defaultToCookie value, default is true.
 | ||
|  |     this.setDefaultToCookie = function (shouldDefault) { | ||
|  |       this.defaultToCookie = !!shouldDefault; // Double-not to make sure it's a bool value.
 | ||
|  |       return this; | ||
|  |     }; | ||
|  |     // Setter for cookie config
 | ||
|  |     this.setStorageCookie = function(exp, path, secure) { | ||
|  |       this.cookie.expiry = exp; | ||
|  |       this.cookie.path = path; | ||
|  |       this.cookie.secure = secure; | ||
|  |       return this; | ||
|  |     }; | ||
|  | 
 | ||
|  |     // Setter for cookie domain
 | ||
|  |     this.setStorageCookieDomain = function(domain) { | ||
|  |       this.cookie.domain = domain; | ||
|  |       return this; | ||
|  |     }; | ||
|  | 
 | ||
|  |     // Setter for notification config
 | ||
|  |     // itemSet & itemRemove should be booleans
 | ||
|  |     this.setNotify = function(itemSet, itemRemove) { | ||
|  |       this.notify = { | ||
|  |         setItem: itemSet, | ||
|  |         removeItem: itemRemove | ||
|  |       }; | ||
|  |       return this; | ||
|  |     }; | ||
|  | 
 | ||
|  |     this.$get = ['$rootScope', '$window', '$document', '$parse','$timeout', function($rootScope, $window, $document, $parse, $timeout) { | ||
|  |       var self = this; | ||
|  |       var prefix = self.prefix; | ||
|  |       var cookie = self.cookie; | ||
|  |       var notify = self.notify; | ||
|  |       var storageType = self.storageType; | ||
|  |       var webStorage; | ||
|  | 
 | ||
|  |       // When Angular's $document is not available
 | ||
|  |       if (!$document) { | ||
|  |         $document = document; | ||
|  |       } else if ($document[0]) { | ||
|  |         $document = $document[0]; | ||
|  |       } | ||
|  | 
 | ||
|  |       // If there is a prefix set in the config lets use that with an appended period for readability
 | ||
|  |       if (prefix.substr(-1) !== '.') { | ||
|  |         prefix = !!prefix ? prefix + '.' : ''; | ||
|  |       } | ||
|  |       var deriveQualifiedKey = function(key) { | ||
|  |         return prefix + key; | ||
|  |       }; | ||
|  | 
 | ||
|  |       // Removes prefix from the key.
 | ||
|  |       var underiveQualifiedKey = function (key) { | ||
|  |         return key.replace(new RegExp('^' + prefix, 'g'), ''); | ||
|  |       }; | ||
|  | 
 | ||
|  |       // Check if the key is within our prefix namespace.
 | ||
|  |       var isKeyPrefixOurs = function (key) { | ||
|  |         return key.indexOf(prefix) === 0; | ||
|  |       }; | ||
|  | 
 | ||
|  |       // Checks the browser to see if local storage is supported
 | ||
|  |       var checkSupport = function () { | ||
|  |         try { | ||
|  |           var supported = (storageType in $window && $window[storageType] !== null); | ||
|  | 
 | ||
|  |           // When Safari (OS X or iOS) is in private browsing mode, it appears as though localStorage
 | ||
|  |           // is available, but trying to call .setItem throws an exception.
 | ||
|  |           //
 | ||
|  |           // "QUOTA_EXCEEDED_ERR: DOM Exception 22: An attempt was made to add something to storage
 | ||
|  |           // that exceeded the quota."
 | ||
|  |           var key = deriveQualifiedKey('__' + Math.round(Math.random() * 1e7)); | ||
|  |           if (supported) { | ||
|  |             webStorage = $window[storageType]; | ||
|  |             webStorage.setItem(key, ''); | ||
|  |             webStorage.removeItem(key); | ||
|  |           } | ||
|  | 
 | ||
|  |           return supported; | ||
|  |         } catch (e) { | ||
|  |           // Only change storageType to cookies if defaulting is enabled.
 | ||
|  |           if (self.defaultToCookie) | ||
|  |             storageType = 'cookie'; | ||
|  |           $rootScope.$broadcast('LocalStorageModule.notification.error', e.message); | ||
|  |           return false; | ||
|  |         } | ||
|  |       }; | ||
|  |       var browserSupportsLocalStorage = checkSupport(); | ||
|  | 
 | ||
|  |       // Directly adds a value to local storage
 | ||
|  |       // If local storage is not available in the browser use cookies
 | ||
|  |       // Example use: localStorageService.add('library','angular');
 | ||
|  |       var addToLocalStorage = function (key, value, type) { | ||
|  |         var previousType = getStorageType(); | ||
|  | 
 | ||
|  |         try { | ||
|  |           setStorageType(type); | ||
|  | 
 | ||
|  |           // Let's convert undefined values to null to get the value consistent
 | ||
|  |           if (isUndefined(value)) { | ||
|  |             value = null; | ||
|  |           } else { | ||
|  |             value = toJson(value); | ||
|  |           } | ||
|  | 
 | ||
|  |           // If this browser does not support local storage use cookies
 | ||
|  |           if (!browserSupportsLocalStorage && self.defaultToCookie || self.storageType === 'cookie') { | ||
|  |             if (!browserSupportsLocalStorage) { | ||
|  |               $rootScope.$broadcast('LocalStorageModule.notification.warning', 'LOCAL_STORAGE_NOT_SUPPORTED'); | ||
|  |             } | ||
|  | 
 | ||
|  |             if (notify.setItem) { | ||
|  |               $rootScope.$broadcast('LocalStorageModule.notification.setitem', {key: key, newvalue: value, storageType: 'cookie'}); | ||
|  |             } | ||
|  |             return addToCookies(key, value); | ||
|  |           } | ||
|  | 
 | ||
|  |           try { | ||
|  |             if (webStorage) { | ||
|  |               webStorage.setItem(deriveQualifiedKey(key), value); | ||
|  |             } | ||
|  |             if (notify.setItem) { | ||
|  |               $rootScope.$broadcast('LocalStorageModule.notification.setitem', {key: key, newvalue: value, storageType: self.storageType}); | ||
|  |             } | ||
|  |           } catch (e) { | ||
|  |             $rootScope.$broadcast('LocalStorageModule.notification.error', e.message); | ||
|  |             return addToCookies(key, value); | ||
|  |           } | ||
|  |           return true; | ||
|  |         } finally { | ||
|  |           setStorageType(previousType); | ||
|  |         } | ||
|  |       }; | ||
|  | 
 | ||
|  |       // Directly get a value from local storage
 | ||
|  |       // Example use: localStorageService.get('library'); // returns 'angular'
 | ||
|  |       var getFromLocalStorage = function (key, type) { | ||
|  |         var previousType = getStorageType(); | ||
|  | 
 | ||
|  |         try { | ||
|  |           setStorageType(type); | ||
|  | 
 | ||
|  |           if (!browserSupportsLocalStorage && self.defaultToCookie  || self.storageType === 'cookie') { | ||
|  |             if (!browserSupportsLocalStorage) { | ||
|  |               $rootScope.$broadcast('LocalStorageModule.notification.warning', 'LOCAL_STORAGE_NOT_SUPPORTED'); | ||
|  |             } | ||
|  | 
 | ||
|  |             return getFromCookies(key); | ||
|  |           } | ||
|  | 
 | ||
|  |           var item = webStorage ? webStorage.getItem(deriveQualifiedKey(key)) : null; | ||
|  |           // angular.toJson will convert null to 'null', so a proper conversion is needed
 | ||
|  |           // FIXME not a perfect solution, since a valid 'null' string can't be stored
 | ||
|  |           if (!item || item === 'null') { | ||
|  |             return null; | ||
|  |           } | ||
|  | 
 | ||
|  |           try { | ||
|  |             return JSON.parse(item); | ||
|  |           } catch (e) { | ||
|  |             return item; | ||
|  |           } | ||
|  |         } finally { | ||
|  |           setStorageType(previousType); | ||
|  |         } | ||
|  |       }; | ||
|  | 
 | ||
|  |       // Remove an item from local storage
 | ||
|  |       // Example use: localStorageService.remove('library'); // removes the key/value pair of library='angular'
 | ||
|  |       //
 | ||
|  |       // This is var-arg removal, check the last argument to see if it is a storageType
 | ||
|  |       // and set type accordingly before removing.
 | ||
|  |       //
 | ||
|  |       var removeFromLocalStorage = function () { | ||
|  |         var previousType = getStorageType(); | ||
|  | 
 | ||
|  |         try { | ||
|  |           // can't pop on arguments, so we do this
 | ||
|  |           var consumed = 0; | ||
|  |           if (arguments.length >= 1 && | ||
|  |               (arguments[arguments.length - 1] === 'localStorage' || | ||
|  |                arguments[arguments.length - 1] === 'sessionStorage')) { | ||
|  |             consumed = 1; | ||
|  |             setStorageType(arguments[arguments.length - 1]); | ||
|  |           } | ||
|  | 
 | ||
|  |           var i, key; | ||
|  |           for (i = 0; i < arguments.length - consumed; i++) { | ||
|  |             key = arguments[i]; | ||
|  |             if (!browserSupportsLocalStorage && self.defaultToCookie || self.storageType === 'cookie') { | ||
|  |               if (!browserSupportsLocalStorage) { | ||
|  |                 $rootScope.$broadcast('LocalStorageModule.notification.warning', 'LOCAL_STORAGE_NOT_SUPPORTED'); | ||
|  |               } | ||
|  | 
 | ||
|  |               if (notify.removeItem) { | ||
|  |                 $rootScope.$broadcast('LocalStorageModule.notification.removeitem', {key: key, storageType: 'cookie'}); | ||
|  |               } | ||
|  |               removeFromCookies(key); | ||
|  |             } | ||
|  |             else { | ||
|  |               try { | ||
|  |                 webStorage.removeItem(deriveQualifiedKey(key)); | ||
|  |                 if (notify.removeItem) { | ||
|  |                   $rootScope.$broadcast('LocalStorageModule.notification.removeitem', { | ||
|  |                     key: key, | ||
|  |                     storageType: self.storageType | ||
|  |                   }); | ||
|  |                 } | ||
|  |               } catch (e) { | ||
|  |                 $rootScope.$broadcast('LocalStorageModule.notification.error', e.message); | ||
|  |                 removeFromCookies(key); | ||
|  |               } | ||
|  |             } | ||
|  |           } | ||
|  |         } finally { | ||
|  |           setStorageType(previousType); | ||
|  |         } | ||
|  |       }; | ||
|  | 
 | ||
|  |       // Return array of keys for local storage
 | ||
|  |       // Example use: var keys = localStorageService.keys()
 | ||
|  |       var getKeysForLocalStorage = function (type) { | ||
|  |         var previousType = getStorageType(); | ||
|  | 
 | ||
|  |         try { | ||
|  |           setStorageType(type); | ||
|  | 
 | ||
|  |           if (!browserSupportsLocalStorage) { | ||
|  |             $rootScope.$broadcast('LocalStorageModule.notification.warning', 'LOCAL_STORAGE_NOT_SUPPORTED'); | ||
|  |             return []; | ||
|  |           } | ||
|  | 
 | ||
|  |           var prefixLength = prefix.length; | ||
|  |           var keys = []; | ||
|  |           for (var key in webStorage) { | ||
|  |             // Only return keys that are for this app
 | ||
|  |             if (key.substr(0, prefixLength) === prefix) { | ||
|  |               try { | ||
|  |                 keys.push(key.substr(prefixLength)); | ||
|  |               } catch (e) { | ||
|  |                 $rootScope.$broadcast('LocalStorageModule.notification.error', e.Description); | ||
|  |                 return []; | ||
|  |               } | ||
|  |             } | ||
|  |           } | ||
|  | 
 | ||
|  |           return keys; | ||
|  |         } finally { | ||
|  |           setStorageType(previousType); | ||
|  |         } | ||
|  |       }; | ||
|  | 
 | ||
|  |       // Remove all data for this app from local storage
 | ||
|  |       // Also optionally takes a regular expression string and removes the matching key-value pairs
 | ||
|  |       // Example use: localStorageService.clearAll();
 | ||
|  |       // Should be used mostly for development purposes
 | ||
|  |       var clearAllFromLocalStorage = function (regularExpression, type) { | ||
|  |         var previousType = getStorageType(); | ||
|  | 
 | ||
|  |         try { | ||
|  |           setStorageType(type); | ||
|  | 
 | ||
|  |           // Setting both regular expressions independently
 | ||
|  |           // Empty strings result in catchall RegExp
 | ||
|  |           var prefixRegex = !!prefix ? new RegExp('^' + prefix) : new RegExp(); | ||
|  |           var testRegex = !!regularExpression ? new RegExp(regularExpression) : new RegExp(); | ||
|  | 
 | ||
|  |           if (!browserSupportsLocalStorage && self.defaultToCookie  || self.storageType === 'cookie') { | ||
|  |             if (!browserSupportsLocalStorage) { | ||
|  |               $rootScope.$broadcast('LocalStorageModule.notification.warning', 'LOCAL_STORAGE_NOT_SUPPORTED'); | ||
|  |             } | ||
|  |             return clearAllFromCookies(); | ||
|  |           } | ||
|  |           if (!browserSupportsLocalStorage && !self.defaultToCookie) | ||
|  |             return false; | ||
|  |           var prefixLength = prefix.length; | ||
|  | 
 | ||
|  |           for (var key in webStorage) { | ||
|  |             // Only remove items that are for this app and match the regular expression
 | ||
|  |             if (prefixRegex.test(key) && testRegex.test(key.substr(prefixLength))) { | ||
|  |               try { | ||
|  |                 removeFromLocalStorage(key.substr(prefixLength)); | ||
|  |               } catch (e) { | ||
|  |                 $rootScope.$broadcast('LocalStorageModule.notification.error', e.message); | ||
|  |                 return clearAllFromCookies(); | ||
|  |               } | ||
|  |             } | ||
|  |           } | ||
|  | 
 | ||
|  |           return true; | ||
|  |         } finally { | ||
|  |           setStorageType(previousType); | ||
|  |         } | ||
|  |       }; | ||
|  | 
 | ||
|  |       // Checks the browser to see if cookies are supported
 | ||
|  |       var browserSupportsCookies = (function() { | ||
|  |         try { | ||
|  |           return $window.navigator.cookieEnabled || | ||
|  |           ("cookie" in $document && ($document.cookie.length > 0 || | ||
|  |             ($document.cookie = "test").indexOf.call($document.cookie, "test") > -1)); | ||
|  |           } catch (e) { | ||
|  |             $rootScope.$broadcast('LocalStorageModule.notification.error', e.message); | ||
|  |             return false; | ||
|  |           } | ||
|  |         }()); | ||
|  | 
 | ||
|  |         // Directly adds a value to cookies
 | ||
|  |         // Typically used as a fallback if local storage is not available in the browser
 | ||
|  |         // Example use: localStorageService.cookie.add('library','angular');
 | ||
|  |         var addToCookies = function (key, value, daysToExpiry, secure) { | ||
|  | 
 | ||
|  |           if (isUndefined(value)) { | ||
|  |             return false; | ||
|  |           } else if(isArray(value) || isObject(value)) { | ||
|  |             value = toJson(value); | ||
|  |           } | ||
|  | 
 | ||
|  |           if (!browserSupportsCookies) { | ||
|  |             $rootScope.$broadcast('LocalStorageModule.notification.error', 'COOKIES_NOT_SUPPORTED'); | ||
|  |             return false; | ||
|  |           } | ||
|  | 
 | ||
|  |           try { | ||
|  |             var expiry = '', | ||
|  |             expiryDate = new Date(), | ||
|  |             cookieDomain = ''; | ||
|  | 
 | ||
|  |             if (value === null) { | ||
|  |               // Mark that the cookie has expired one day ago
 | ||
|  |               expiryDate.setTime(expiryDate.getTime() + (-1 * 24 * 60 * 60 * 1000)); | ||
|  |               expiry = "; expires=" + expiryDate.toGMTString(); | ||
|  |               value = ''; | ||
|  |             } else if (isNumber(daysToExpiry) && daysToExpiry !== 0) { | ||
|  |               expiryDate.setTime(expiryDate.getTime() + (daysToExpiry * 24 * 60 * 60 * 1000)); | ||
|  |               expiry = "; expires=" + expiryDate.toGMTString(); | ||
|  |             } else if (cookie.expiry !== 0) { | ||
|  |               expiryDate.setTime(expiryDate.getTime() + (cookie.expiry * 24 * 60 * 60 * 1000)); | ||
|  |               expiry = "; expires=" + expiryDate.toGMTString(); | ||
|  |             } | ||
|  |             if (!!key) { | ||
|  |               var cookiePath = "; path=" + cookie.path; | ||
|  |               if (cookie.domain) { | ||
|  |                 cookieDomain = "; domain=" + cookie.domain; | ||
|  |               } | ||
|  |               /* Providing the secure parameter always takes precedence over config | ||
|  |                * (allows developer to mix and match secure + non-secure) */ | ||
|  |               if (typeof secure === 'boolean') { | ||
|  |                   if (secure === true) { | ||
|  |                       /* We've explicitly specified secure, | ||
|  |                        * add the secure attribute to the cookie (after domain) */ | ||
|  |                       cookieDomain += "; secure"; | ||
|  |                   } | ||
|  |                   // else - secure has been supplied but isn't true - so don't set secure flag, regardless of what config says
 | ||
|  |               } | ||
|  |               else if (cookie.secure === true) { | ||
|  |                   // secure parameter wasn't specified, get default from config
 | ||
|  |                   cookieDomain += "; secure"; | ||
|  |               } | ||
|  |               $document.cookie = deriveQualifiedKey(key) + "=" + encodeURIComponent(value) + expiry + cookiePath + cookieDomain; | ||
|  |             } | ||
|  |           } catch (e) { | ||
|  |             $rootScope.$broadcast('LocalStorageModule.notification.error', e.message); | ||
|  |             return false; | ||
|  |           } | ||
|  |           return true; | ||
|  |         }; | ||
|  | 
 | ||
|  |         // Directly get a value from a cookie
 | ||
|  |         // Example use: localStorageService.cookie.get('library'); // returns 'angular'
 | ||
|  |         var getFromCookies = function (key) { | ||
|  |           if (!browserSupportsCookies) { | ||
|  |             $rootScope.$broadcast('LocalStorageModule.notification.error', 'COOKIES_NOT_SUPPORTED'); | ||
|  |             return false; | ||
|  |           } | ||
|  | 
 | ||
|  |           var cookies = $document.cookie && $document.cookie.split(';') || []; | ||
|  |           for(var i=0; i < cookies.length; i++) { | ||
|  |             var thisCookie = cookies[i]; | ||
|  |             while (thisCookie.charAt(0) === ' ') { | ||
|  |               thisCookie = thisCookie.substring(1,thisCookie.length); | ||
|  |             } | ||
|  |             if (thisCookie.indexOf(deriveQualifiedKey(key) + '=') === 0) { | ||
|  |               var storedValues = decodeURIComponent(thisCookie.substring(prefix.length + key.length + 1, thisCookie.length)); | ||
|  |               try { | ||
|  |                 var parsedValue = JSON.parse(storedValues); | ||
|  |                 return typeof(parsedValue) === 'number' ? storedValues : parsedValue; | ||
|  |               } catch(e) { | ||
|  |                 return storedValues; | ||
|  |               } | ||
|  |             } | ||
|  |           } | ||
|  |           return null; | ||
|  |         }; | ||
|  | 
 | ||
|  |         var removeFromCookies = function (key) { | ||
|  |           addToCookies(key,null); | ||
|  |         }; | ||
|  | 
 | ||
|  |         var clearAllFromCookies = function () { | ||
|  |           var thisCookie = null; | ||
|  |           var prefixLength = prefix.length; | ||
|  |           var cookies = $document.cookie.split(';'); | ||
|  |           for(var i = 0; i < cookies.length; i++) { | ||
|  |             thisCookie = cookies[i]; | ||
|  | 
 | ||
|  |             while (thisCookie.charAt(0) === ' ') { | ||
|  |               thisCookie = thisCookie.substring(1, thisCookie.length); | ||
|  |             } | ||
|  | 
 | ||
|  |             var key = thisCookie.substring(prefixLength, thisCookie.indexOf('=')); | ||
|  |             removeFromCookies(key); | ||
|  |           } | ||
|  |         }; | ||
|  | 
 | ||
|  |         var getStorageType = function() { | ||
|  |           return storageType; | ||
|  |         }; | ||
|  | 
 | ||
|  |         var setStorageType = function(type) { | ||
|  |           if (type && storageType !== type) { | ||
|  |             storageType = type; | ||
|  |             browserSupportsLocalStorage = checkSupport(); | ||
|  |           } | ||
|  |           return browserSupportsLocalStorage; | ||
|  |         }; | ||
|  | 
 | ||
|  |         // Add a listener on scope variable to save its changes to local storage
 | ||
|  |         // Return a function which when called cancels binding
 | ||
|  |         var bindToScope = function(scope, key, def, lsKey, type) { | ||
|  |           lsKey = lsKey || key; | ||
|  |           var value = getFromLocalStorage(lsKey, type); | ||
|  | 
 | ||
|  |           if (value === null && isDefined(def)) { | ||
|  |             value = def; | ||
|  |           } else if (isObject(value) && isObject(def)) { | ||
|  |             value = extend(value, def); | ||
|  |           } | ||
|  | 
 | ||
|  |           $parse(key).assign(scope, value); | ||
|  | 
 | ||
|  |           return scope.$watch(key, function(newVal) { | ||
|  |             addToLocalStorage(lsKey, newVal, type); | ||
|  |           }, isObject(scope[key])); | ||
|  |         }; | ||
|  | 
 | ||
|  |         // Add listener to local storage, for update callbacks.
 | ||
|  |         if (browserSupportsLocalStorage) { | ||
|  |             if ($window.addEventListener) { | ||
|  |                 $window.addEventListener("storage", handleStorageChangeCallback, false); | ||
|  |                 $rootScope.$on('$destroy', function() { | ||
|  |                     $window.removeEventListener("storage", handleStorageChangeCallback); | ||
|  |                 }); | ||
|  |             } else if($window.attachEvent){ | ||
|  |                 // attachEvent and detachEvent are proprietary to IE v6-10
 | ||
|  |                 $window.attachEvent("onstorage", handleStorageChangeCallback); | ||
|  |                 $rootScope.$on('$destroy', function() { | ||
|  |                     $window.detachEvent("onstorage", handleStorageChangeCallback); | ||
|  |                 }); | ||
|  |             } | ||
|  |         } | ||
|  | 
 | ||
|  |         // Callback handler for storage changed.
 | ||
|  |         function handleStorageChangeCallback(e) { | ||
|  |             if (!e) { e = $window.event; } | ||
|  |             if (notify.setItem) { | ||
|  |                 if (isString(e.key) && isKeyPrefixOurs(e.key)) { | ||
|  |                     var key = underiveQualifiedKey(e.key); | ||
|  |                     // Use timeout, to avoid using $rootScope.$apply.
 | ||
|  |                     $timeout(function () { | ||
|  |                         $rootScope.$broadcast('LocalStorageModule.notification.changed', { key: key, newvalue: e.newValue, storageType: self.storageType }); | ||
|  |                     }); | ||
|  |                 } | ||
|  |             } | ||
|  |         } | ||
|  | 
 | ||
|  |         // Return localStorageService.length
 | ||
|  |         // ignore keys that not owned
 | ||
|  |         var lengthOfLocalStorage = function(type) { | ||
|  |           var previousType = getStorageType(); | ||
|  | 
 | ||
|  |           try { | ||
|  |             setStorageType(type); | ||
|  | 
 | ||
|  |             var count = 0; | ||
|  |             var storage = $window[storageType]; | ||
|  |             for(var i = 0; i < storage.length; i++) { | ||
|  |               if(storage.key(i).indexOf(prefix) === 0 ) { | ||
|  |                 count++; | ||
|  |               } | ||
|  |             } | ||
|  | 
 | ||
|  |             return count; | ||
|  |           } finally { | ||
|  |             setStorageType(previousType); | ||
|  |           } | ||
|  |         }; | ||
|  | 
 | ||
|  |         return { | ||
|  |           isSupported: browserSupportsLocalStorage, | ||
|  |           getStorageType: getStorageType, | ||
|  |           setStorageType: setStorageType, | ||
|  |           set: addToLocalStorage, | ||
|  |           add: addToLocalStorage, //DEPRECATED
 | ||
|  |           get: getFromLocalStorage, | ||
|  |           keys: getKeysForLocalStorage, | ||
|  |           remove: removeFromLocalStorage, | ||
|  |           clearAll: clearAllFromLocalStorage, | ||
|  |           bind: bindToScope, | ||
|  |           deriveKey: deriveQualifiedKey, | ||
|  |           underiveKey: underiveQualifiedKey, | ||
|  |           length: lengthOfLocalStorage, | ||
|  |           defaultToCookie: this.defaultToCookie, | ||
|  |           cookie: { | ||
|  |             isSupported: browserSupportsCookies, | ||
|  |             set: addToCookies, | ||
|  |             add: addToCookies, //DEPRECATED
 | ||
|  |             get: getFromCookies, | ||
|  |             remove: removeFromCookies, | ||
|  |             clearAll: clearAllFromCookies | ||
|  |           } | ||
|  |         }; | ||
|  |       }]; | ||
|  |   }); | ||
|  | })(window, window.angular); |