diff --git a/README.md b/README.md index 95ef7b8..be58416 100644 --- a/README.md +++ b/README.md @@ -31,26 +31,28 @@ The service provides the following generic methods: It also provides the following direct APIs: `webStorage.local` -* `isSupported` -- boolean flag indicating client support status (local storage) -* `add(key, value)` -- [DEPRECATED: use `set`] add a value to storage under the specific key (local storage) -* `set(key, value)` -- add or update a value in storage under the specific key (local storage) -* `get(key)` -- return the specified value (local storage) -* `has(key)` -- checks if the given key exists (local storage) -* `key(index)` -- return the name of the nth key (local storage) -* `length()` -- returns the number of items in storage (local storage) -* `remove(key)` -- remove a key/value pair from storage (local storage) -* `clear()` -- remove all key/value pairs from storage (local storage) +* `isSupported` -- boolean flag indicating client support status (local storage) +* `add(key, value)` -- [DEPRECATED: use `set`] add a value to storage under the specific key (local storage) +* `set(key, value)` -- add or update a value in storage under the specific key (local storage) +* `get(key)` -- return the specified value (local storage) +* `has(key)` -- checks if the given key exists (local storage) +* `key(index)` -- return the name of the nth key (local storage) +* `length()` -- returns the number of items in storage (local storage) +* `remove(key)` -- remove a key/value pair from storage (local storage) +* `clear()` -- remove all key/value pairs from storage (local storage) +* `isPolyfilled(remove)` -- returns `true` if local storage is polyfilled, if `remove` is true then the polyfill is removed (local storage) `webStorage.session` -* `isSupported` -- boolean flag indicating client support status (session storage) -* `add(key, value)` -- [DEPRECATED: use `set`] add a value to storage under the specific key (session storage) -* `set(key, value)` -- add or set a value in storage under the specific key (session storage) -* `get(key)` -- return the specified value (session storage) -* `has(key)` -- checks if the given key exists (session storage) -* `key(index)` -- return the name of the nth key (session storage) -* `length()` -- returns the number of items in storage (session storage) -* `remove(key)` -- remove a key/value pair from storage (session storage) -* `clear()` -- remove all key/value pairs from storage (session storage) +* `isSupported` -- boolean flag indicating client support status (session storage) +* `add(key, value)` -- [DEPRECATED: use `set`] add a value to storage under the specific key (session storage) +* `set(key, value)` -- add or set a value in storage under the specific key (session storage) +* `get(key)` -- return the specified value (session storage) +* `has(key)` -- checks if the given key exists (session storage) +* `key(index)` -- return the name of the nth key (session storage) +* `length()` -- returns the number of items in storage (session storage) +* `remove(key)` -- remove a key/value pair from storage (session storage) +* `clear()` -- remove all key/value pairs from storage (session storage) +* `isPolyfilled(remove)` -- returns `true` if session storage is polyfilled, if `remove` is true then the polyfill is removed (session storage) `webStorage.memory` * `isSupported` -- boolean true, the in-memory storage is always supported @@ -62,15 +64,16 @@ It also provides the following direct APIs: * `length()` -- returns the number of items in storage (in-memory storage) * `remove(key)` -- remove a key/value pair from storage (in-memory storage) * `clear()` -- remove all key/value pairs from storage (in-memory storage) +* `isPolyfilled()` -- always returns `false` (in-memory storage) ## Author Fredric Rylander, https://github.com/fredricrylander/angular-webstorage ## Date -2015-08-31 +2015-09-01 ## Module Version -0.13.1 +0.14.0 ## Requirements This module was originally built for AngularJS v1.0.5. @@ -171,6 +174,12 @@ Add `webStorageModule` to your app's dependencies. Then inject `webStorage` into * v0.13.1 - Refactored some strings to var's in order to help minification. +* v0.14.0 + - Added routines to check if local and/or session storage has been + polyfilled or not. It is also possible to use the same routines to + remove the polyfill functionality. `isPolyfilled(remove)` is now + defined on `webStorage.local` and `webStorage.session`. + ## License The MIT License Copyright (c) 2013-2014 Fredric Rylander diff --git a/angular-webstorage.js b/angular-webstorage.js index 920f99a..59b32cb 100644 --- a/angular-webstorage.js +++ b/angular-webstorage.js @@ -41,26 +41,28 @@ * It also provides the following direct APIs: * * webStorage.local - * - isSupported -- boolean flag indicating client support status (local storage) - * - add(key, value) -- [DEPRECATED: use `set`] add a value to storage under the specific key (local storage) - * - set(key, value) -- add or update a value in storage under the specific key (local storage) - * - get(key) -- return the specified value (local storage) - * - has(key) -- checks if the given key exists (local storage) - * - key(index) -- return the name of the nth key (local storage) - * - length() -- returns the number of items in storage (local storage) - * - remove(key) -- remove a key/value pair from storage (local storage) - * - clear() -- remove all key/value pairs from storage (local storage) + * - isSupported -- boolean flag indicating client support status (local storage) + * - add(key, value) -- [DEPRECATED: use `set`] add a value to storage under the specific key (local storage) + * - set(key, value) -- add or update a value in storage under the specific key (local storage) + * - get(key) -- return the specified value (local storage) + * - has(key) -- checks if the given key exists (local storage) + * - key(index) -- return the name of the nth key (local storage) + * - length() -- returns the number of items in storage (local storage) + * - remove(key) -- remove a key/value pair from storage (local storage) + * - clear() -- remove all key/value pairs from storage (local storage) + * - isPolyfilled(remove) -- returns `true` if local storage is polyfilled, if `remove` is true then the polyfill is removed (local storage) * * webStorage.session - * - isSupported -- boolean flag indicating client support status (session storage) - * - add(key, value) -- [DEPRECATED: use `set`] add a value to storage under the specific key (session storage) - * - set(key, value) -- add or set a value in storage under the specific key (session storage) - * - get(key) -- return the specified value (session storage) - * - has(key) -- checks if the given key exists (session storage) - * - key(index) -- return the name of the nth key (session storage) - * - length() -- returns the number of items in storage (session storage) - * - remove(key) -- remove a key/value pair from storage (session storage) - * - clear() -- remove all key/value pairs from storage (session storage) + * - isSupported -- boolean flag indicating client support status (session storage) + * - add(key, value) -- [DEPRECATED: use `set`] add a value to storage under the specific key (session storage) + * - set(key, value) -- add or set a value in storage under the specific key (session storage) + * - get(key) -- return the specified value (session storage) + * - has(key) -- checks if the given key exists (session storage) + * - key(index) -- return the name of the nth key (session storage) + * - length() -- returns the number of items in storage (session storage) + * - remove(key) -- remove a key/value pair from storage (session storage) + * - clear() -- remove all key/value pairs from storage (session storage) + * - isPolyfilled(remove) -- returns `true` if session storage is polyfilled, if `remove` is true then the polyfill is removed (session storage) * * webStorage.memory * - isSupported -- boolean true, the in-memory storage is always supported @@ -72,6 +74,7 @@ * - length() -- returns the number of items in storage (in-memory storage) * - remove(key) -- remove a key/value pair from storage (in-memory storage) * - clear() -- remove all key/value pairs from storage (in-memory storage) + * - isPolyfilled() -- always returns `false` (in-memory storage) * * * Requirements @@ -87,8 +90,8 @@ * * * @author Fredric Rylander, https://github.com/fredricrylander/angular-webstorage - * @date 2015-08-31 - * @version 0.13.1 + * @date 2015-09-01 + * @version 0.14.0 * * @contributor Paulo Cesar (https://github.com/pocesar) * @contributor David Chang (https://github.com/hasdavidc) @@ -202,6 +205,12 @@ * * v0.13.1 * - Refactored some strings to var's in order to help minification. + * + * v0.14.0 + * - Added routines to check if local and/or session storage has been + * polyfilled or not. It is also possible to use the same routines to + * remove the polyfill functionality. `isPolyfilled(remove)` is now + * defined on `webStorage.local` and `webStorage.session`. */ /** @@ -277,6 +286,18 @@ webStorageModule.factory('webStorage', ['$rootScope', 'defaultSettings', functio */ var hasSessionStorage = testSessionStorage(); + /** + * Boolean flag indicating if local storage has been polyfilled by using cookies. + * @private + */ + var isLocalStoragePolyfilled = false; + + /** + * Boolean flag indicating if session storage has been polyfilled by using cookies. + * @private + */ + var isSessionStoragePolyfilled = false; + /** * Reference to the order of preference by which storage engines are iterated. * @see order @@ -319,7 +340,8 @@ webStorageModule.factory('webStorage', ['$rootScope', 'defaultSettings', functio key: keyInLocal, length: lengthInLocal, remove: removeFromLocal, - clear: clearLocal + clear: clearLocal, + isPolyfilled: isLocalPolyfilled, }, /** @@ -337,7 +359,8 @@ webStorageModule.factory('webStorage', ['$rootScope', 'defaultSettings', functio key: keyInSession, length: lengthInSession, remove: removeFromSession, - clear: clearSession + clear: clearSession, + isPolyfilled: isSessionPolyfilled, }, /** @@ -355,7 +378,8 @@ webStorageModule.factory('webStorage', ['$rootScope', 'defaultSettings', functio key: keyInMemory, length: lengthInMemory, remove: removeFromMemory, - clear: clearMemory + clear: clearMemory, + isPolyfilled: false } }; @@ -1089,6 +1113,7 @@ webStorageModule.factory('webStorage', ['$rootScope', 'defaultSettings', functio * @private */ function testLocalStorage() { + polyfillLocalStorage(); try { localStorage.setItem(prefix + defaultSettings.testKey, defaultSettings.testKey); localStorage.removeItem(prefix + defaultSettings.testKey); @@ -1105,6 +1130,7 @@ webStorageModule.factory('webStorage', ['$rootScope', 'defaultSettings', functio * @private */ function testSessionStorage() { + polyfillSessionStorage(); try { sessionStorage.setItem(prefix + defaultSettings.testKey, defaultSettings.testKey); sessionStorage.removeItem(prefix + defaultSettings.testKey); @@ -1125,106 +1151,155 @@ webStorageModule.factory('webStorage', ['$rootScope', 'defaultSettings', functio return false; } - return webStorage; -}]); - - -/** - * Polyfilling the localStorage and sessionStorage APIs by setting cookies - * on the document. - * - * Source from: https://developer.mozilla.org/en-US/docs/DOM/Storage - */ - -try { - /* jshint -W001 */// 'hasOwnProperty' is a really bad name. - /* jshint -W014 */// Bad line break before +. - - // Support for localStorage, compatible with old browsers, like Internet - // Explorer < 8 (tested and working even in Internet Explorer 6). - // Source From: https://developer.mozilla.org/en-US/docs/DOM/Storage - if (!window.localStorage) { - window.localStorage = { - getItem : function(sKey) { - if (!sKey || !this.hasOwnProperty(sKey)) { - return null; - } - return unescape(document.cookie.replace(new RegExp("(?:^|.*;\\s*)" - + escape(sKey).replace(/[\-\.\+\*]/g, "\\$&") - + "\\s*\\=\\s*((?:[^;](?!;))*[^;]?).*"), "$1")); - }, - key : function(nKeyId) { - return unescape(document.cookie.replace(/\s*\=(?:.(?!;))*$/, "") - .split(/\s*\=(?:[^;](?!;))*[^;]?;\s*/)[nKeyId]); - }, - setItem : function(sKey, sValue) { - if (!sKey) { - return; - } - document.cookie = escape(sKey) + "=" + escape(sValue) - + "; expires=Tue, 19 Jan 2038 03:14:07 GMT; path=/"; - this.length = document.cookie.match(/\=/g).length; - }, - length : 0, - removeItem : function(sKey) { - if (!sKey || !this.hasOwnProperty(sKey)) { - return; - } - document.cookie = escape(sKey) - + "=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/"; - this.length--; - }, - hasOwnProperty : function(sKey) { - return (new RegExp("(?:^|;\\s*)" - + escape(sKey).replace(/[\-\.\+\*]/g, "\\$&") + "\\s*\\=")) - .test(document.cookie); + /** + * Polyfilling the localStorage API by setting cookies on the document. + * @private + */ + function polyfillLocalStorage() { + try { + /* jshint -W001 */// 'hasOwnProperty' is a really bad name. + /* jshint -W014 */// Bad line break before +. + + // Support for localStorage, compatible with old browsers, like Internet + // Explorer < 8 (tested and working even in Internet Explorer 6). + // Source From: https://developer.mozilla.org/en-US/docs/DOM/Storage + if (!window.localStorage) { + window.localStorage = { + getItem : function(sKey) { + if (!sKey || !this.hasOwnProperty(sKey)) { + return null; + } + return unescape(document.cookie.replace(new RegExp("(?:^|.*;\\s*)" + + escape(sKey).replace(/[\-\.\+\*]/g, "\\$&") + + "\\s*\\=\\s*((?:[^;](?!;))*[^;]?).*"), "$1")); + }, + key : function(nKeyId) { + return unescape(document.cookie.replace(/\s*\=(?:.(?!;))*$/, "") + .split(/\s*\=(?:[^;](?!;))*[^;]?;\s*/)[nKeyId]); + }, + setItem : function(sKey, sValue) { + if (!sKey) { + return; + } + document.cookie = escape(sKey) + "=" + escape(sValue) + + "; expires=Tue, 19 Jan 2038 03:14:07 GMT; path=/"; + this.length = document.cookie.match(/\=/g).length; + }, + length : 0, + removeItem : function(sKey) { + if (!sKey || !this.hasOwnProperty(sKey)) { + return; + } + document.cookie = escape(sKey) + + "=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/"; + this.length--; + }, + hasOwnProperty : function(sKey) { + return (new RegExp("(?:^|;\\s*)" + + escape(sKey).replace(/[\-\.\+\*]/g, "\\$&") + "\\s*\\=")) + .test(document.cookie); + } + }; + window.localStorage.length = (document.cookie.match(/\=/g) || window.localStorage).length; + isLocalStoragePolyfilled = true; } - }; - window.localStorage.length = (document.cookie.match(/\=/g) || window.localStorage).length; + } catch (e) { + // Protected Mode on IE? There's really nothing to do at this stage. + } } - - // Support for sessionStorage, compatible with old browsers, like Internet - // Explorer < 8 (tested and working even in Internet Explorer 6). - // Source From: https://developer.mozilla.org/en-US/docs/DOM/Storage - if (!window.sessionStorage) { - window.sessionStorage = { - getItem : function(sKey) { - if (!sKey || !this.hasOwnProperty(sKey)) { - return null; - } - return unescape(document.cookie.replace(new RegExp("(?:^|.*;\\s*)" - + escape(sKey).replace(/[\-\.\+\*]/g, "\\$&") - + "\\s*\\=\\s*((?:[^;](?!;))*[^;]?).*"), "$1")); - }, - key : function(nKeyId) { - return unescape(document.cookie.replace(/\s*\=(?:.(?!;))*$/, "") - .split(/\s*\=(?:[^;](?!;))*[^;]?;\s*/)[nKeyId]); - }, - setItem : function(sKey, sValue) { - if (!sKey) { - return; - } - document.cookie = escape(sKey) + "=" + escape(sValue) + "; path=/"; - this.length = document.cookie.match(/\=/g).length; - }, - length : 0, - removeItem : function(sKey) { - if (!sKey || !this.hasOwnProperty(sKey)) { - return; - } - document.cookie = escape(sKey) - + "=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/"; - this.length--; - }, - hasOwnProperty : function(sKey) { - return (new RegExp("(?:^|;\\s*)" - + escape(sKey).replace(/[\-\.\+\*]/g, "\\$&") + "\\s*\\=")) - .test(document.cookie); + + /** + * Polyfilling the sessionStorage API by setting cookies on the document. + * @private + */ + function polyfillSessionStorage() { + try { + /* jshint -W001 */// 'hasOwnProperty' is a really bad name. + /* jshint -W014 */// Bad line break before +. + + // Support for sessionStorage, compatible with old browsers, like Internet + // Explorer < 8 (tested and working even in Internet Explorer 6). + // Source From: https://developer.mozilla.org/en-US/docs/DOM/Storage + if (!window.sessionStorage) { + window.sessionStorage = { + getItem : function(sKey) { + if (!sKey || !this.hasOwnProperty(sKey)) { + return null; + } + return unescape(document.cookie.replace(new RegExp("(?:^|.*;\\s*)" + + escape(sKey).replace(/[\-\.\+\*]/g, "\\$&") + + "\\s*\\=\\s*((?:[^;](?!;))*[^;]?).*"), "$1")); + }, + key : function(nKeyId) { + return unescape(document.cookie.replace(/\s*\=(?:.(?!;))*$/, "") + .split(/\s*\=(?:[^;](?!;))*[^;]?;\s*/)[nKeyId]); + }, + setItem : function(sKey, sValue) { + if (!sKey) { + return; + } + document.cookie = escape(sKey) + "=" + escape(sValue) + "; path=/"; + this.length = document.cookie.match(/\=/g).length; + }, + length : 0, + removeItem : function(sKey) { + if (!sKey || !this.hasOwnProperty(sKey)) { + return; + } + document.cookie = escape(sKey) + + "=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/"; + this.length--; + }, + hasOwnProperty : function(sKey) { + return (new RegExp("(?:^|;\\s*)" + + escape(sKey).replace(/[\-\.\+\*]/g, "\\$&") + "\\s*\\=")) + .test(document.cookie); + } + }; + window.sessionStorage.length = (document.cookie.match(/\=/g) || window.sessionStorage).length; + isSessionStoragePolyfilled = true; } - }; - window.sessionStorage.length = (document.cookie.match(/\=/g) || window.sessionStorage).length; + + } catch (e) { + // Protected Mode on IE? There's really nothing to do at this stage. + } + } + + /** + * Returns the polyfill status of local storage: `true` if local storage has been + * polyfilled, else `false`. + * + * @param {boolean} removePolyfill If `removePolyfill` is `true` and local storage + * is currently polyfilled then `window.localStorage` will be set to `null`. + * @return {boolean} `true` if local storage is polyfilled by setting cookies on + * the document, else `false`. + */ + function isLocalPolyfilled(removePolyfill) { + var oldValue = isLocalStoragePolyfilled; + if (removePolyfill === true && isLocalStoragePolyfilled) { + window.localStorage = null; + isLocalStoragePolyfilled = false; + } + return oldValue; + } + + /** + * Returns the polyfill status of session storage: `true` if session storage has been + * polyfilled, else `false`. + * + * @param {boolean} removePolyfill If `removePolyfill` is `true` and session storage + * is currently polyfilled then `window.sessionStorage` will be set to `null`. + * @return {boolean} `true` if session storage is polyfilled by setting cookies on + * the document, else `false`. + */ + function isSessionPolyfilled(removePolyfill) { + var oldValue = isSessionStoragePolyfilled; + if (removePolyfill === true && isSessionStoragePolyfilled) { + window.sessionStorage = null; + isLocalStoragePolyfilled = false; + } + return oldValue; } -} catch (e) { - // Protected Mode on IE? There's really nothing to do at this stage. -} + return webStorage; +}]); diff --git a/angular-webstorage.min.js b/angular-webstorage.min.js index d2aee04..c336315 100644 --- a/angular-webstorage.min.js +++ b/angular-webstorage.min.js @@ -1 +1 @@ -var webStorageModule=angular.module("webStorageModule",[]);webStorageModule.constant("defaultSettings",{prefix:"",order:["local","session","memory"],errorName:"webStorage.notification.error",testKey:"webStorage.test.key"}),webStorageModule.factory("webStorage",["$rootScope","defaultSettings",function(a,b){"use strict";function l(a,b){return console.warn(d),o(a,b)}function m(a,b){return console.warn(d),p(a,b)}function n(a,b){return console.warn(d),q(a,b)}function o(a,b){if(f){try{localStorage.setItem(i+a,JSON.stringify(b))}catch(c){return L(c)}return!0}return!1}function p(a,b){if(g){try{sessionStorage.setItem(i+a,JSON.stringify(b))}catch(c){return L(c)}return!0}return!1}function q(a,b){return j[a]=b,!0}function r(a){if(f)try{var b=localStorage.getItem(i+a);return b&&JSON.parse(b)}catch(c){return L(c),null}return null}function s(a){if(g)try{var b=sessionStorage.getItem(i+a);return b&&JSON.parse(b)}catch(c){return L(c),null}return null}function t(a){return a in j?j[a]:null}function u(a){return null!==r(a)}function v(a){return null!==s(a)}function w(a){return null!==t(a)}function x(a){return f?localStorage.key(a):null}function y(a){return g?sessionStorage.key(a):null}function z(a){var b=0;for(var c in j)if(j.hasOwnProperty(c)){if(a===b)return c;if(b+=1,b>a)return null}return null}function A(){return f?localStorage.length:0}function B(){return g?sessionStorage.length:0}function C(){if(Object.keys)return Object.keys(j).length;var a=0;for(var b in j)j.hasOwnProperty(b)&&(a+=1);return a}function D(a){if(f){try{localStorage.removeItem(i+a)}catch(b){return L(b)}return!0}return!1}function E(a){if(g){try{sessionStorage.removeItem(i+a)}catch(b){return L(b)}return!0}return!1}function F(a){return delete j[a],!0}function G(){if(!f)return!1;if(i){var a=i.length;try{for(var b in localStorage)b.substr(0,a)===i&&localStorage.removeItem(b)}catch(c){return L(c)}return!0}try{localStorage.clear()}catch(c){return L(c)}return!0}function H(){if(!g)return!1;if(i){var a=i.length;try{for(var b in sessionStorage)b.substr(0,a)===i&&sessionStorage.removeItem(b)}catch(c){return L(c)}return!0}try{sessionStorage.clear()}catch(c){return L(c)}return!0}function I(){return j={},!0}function J(){try{return localStorage.setItem(i+b.testKey,b.testKey),localStorage.removeItem(i+b.testKey),!0}catch(a){return!1}}function K(){try{return sessionStorage.setItem(i+b.testKey,b.testKey),sessionStorage.removeItem(i+b.testKey),!0}catch(a){return!1}}function L(b){return a.$broadcast(e,b.title+": "+b.message),!1}var c="undefined",d="angular-webstorage.js -- `add()` had been deprecated, use `set()` instead",e=b.errorName,f=J(),g=K(),h=b.order,i=b.prefix,j={},k={isSupported:f||g,local:{isSupported:f,add:l,set:o,get:r,has:u,key:x,length:A,remove:D,clear:G},session:{isSupported:g,add:m,set:p,get:s,has:v,key:y,length:B,remove:E,clear:H},memory:{isSupported:!0,add:n,set:q,get:t,has:w,key:z,length:C,remove:F,clear:I}};return k.add=function(a,b,c){return console.warn(d),k.set(a,b,c)},k.set=function(a,b,d){d=typeof d!==c?!!d:!1;for(var e=!1,f=h.length,g=0;f>g;++g){var i=k[h[g]];if(i.isSupported&&(e=i.set(a,b)||e,!d))return e}return e},k.get=function(a,b){b=typeof b!==c?!!b:!0;for(var d=h.length,e=0;d>e;++e){var f=k[h[e]];if(f.isSupported){var g=f.get(a);if(!b||null!==g)return g}}return null},k.has=function(a,b){return null!==k.get(a,b)},k.key=function(a,b){b=typeof b!==c?!!b:!0;for(var d=h.length,e=0;d>e;++e){var f=k[h[e]];if(f.isSupported){var g=f.key(a);if(!b||null!==g)return g}}return null},k.length=function(a){a=typeof a!==c?!!a:!0;for(var b=h.length,d=0;b>d;++d){var e=k[h[d]];if(e.isSupported){var f=e.length();if(!a||0!==f)return f}}return 0},k.remove=function(a,b){b=typeof b!==c?!!b:!0;for(var d=!1,e=h.length,f=0;e>f;++f){var g=k[h[f]];if(g.isSupported&&(d=g.remove(a)||d,!b))return d}return d},k.clear=function(a){a=typeof a!==c?!!a:!0;for(var b=!1,d=h.length,e=0;d>e;++e){var f=k[h[e]];if(f.isSupported&&(b=f.clear()||b,!a))return b}return b},k.errorName=function(a){var b=e;if(typeof a!==c){if("string"!=typeof a)return!1;e=a}return b},k.order=function(a){var b=angular.copy(h);if(typeof a!==c){h=[];for(var d in a)/^(local|session|memory)$/.test(a[d])&&h.push(a[d])}return b},k.prefix=function(a){var b=i;if(typeof a!==c){if("string"!=typeof a)return!1;i=a}return b},k}]);try{window.localStorage||(window.localStorage={getItem:function(a){return a&&this.hasOwnProperty(a)?unescape(document.cookie.replace(new RegExp("(?:^|.*;\\s*)"+escape(a).replace(/[\-\.\+\*]/g,"\\$&")+"\\s*\\=\\s*((?:[^;](?!;))*[^;]?).*"),"$1")):null},key:function(a){return unescape(document.cookie.replace(/\s*\=(?:.(?!;))*$/,"").split(/\s*\=(?:[^;](?!;))*[^;]?;\s*/)[a])},setItem:function(a,b){a&&(document.cookie=escape(a)+"="+escape(b)+"; expires=Tue, 19 Jan 2038 03:14:07 GMT; path=/",this.length=document.cookie.match(/\=/g).length)},length:0,removeItem:function(a){a&&this.hasOwnProperty(a)&&(document.cookie=escape(a)+"=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/",this.length--)},hasOwnProperty:function(a){return new RegExp("(?:^|;\\s*)"+escape(a).replace(/[\-\.\+\*]/g,"\\$&")+"\\s*\\=").test(document.cookie)}},window.localStorage.length=(document.cookie.match(/\=/g)||window.localStorage).length),window.sessionStorage||(window.sessionStorage={getItem:function(a){return a&&this.hasOwnProperty(a)?unescape(document.cookie.replace(new RegExp("(?:^|.*;\\s*)"+escape(a).replace(/[\-\.\+\*]/g,"\\$&")+"\\s*\\=\\s*((?:[^;](?!;))*[^;]?).*"),"$1")):null},key:function(a){return unescape(document.cookie.replace(/\s*\=(?:.(?!;))*$/,"").split(/\s*\=(?:[^;](?!;))*[^;]?;\s*/)[a])},setItem:function(a,b){a&&(document.cookie=escape(a)+"="+escape(b)+"; path=/",this.length=document.cookie.match(/\=/g).length)},length:0,removeItem:function(a){a&&this.hasOwnProperty(a)&&(document.cookie=escape(a)+"=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/",this.length--)},hasOwnProperty:function(a){return new RegExp("(?:^|;\\s*)"+escape(a).replace(/[\-\.\+\*]/g,"\\$&")+"\\s*\\=").test(document.cookie)}},window.sessionStorage.length=(document.cookie.match(/\=/g)||window.sessionStorage).length)}catch(e){} \ No newline at end of file +var webStorageModule=angular.module("webStorageModule",[]);webStorageModule.constant("defaultSettings",{prefix:"",order:["local","session","memory"],errorName:"webStorage.notification.error",testKey:"webStorage.test.key"}),webStorageModule.factory("webStorage",["$rootScope","defaultSettings",function(a,b){"use strict";function n(a,b){return console.warn(d),q(a,b)}function o(a,b){return console.warn(d),r(a,b)}function p(a,b){return console.warn(d),s(a,b)}function q(a,b){if(f){try{localStorage.setItem(k+a,JSON.stringify(b))}catch(c){return N(c)}return!0}return!1}function r(a,b){if(g){try{sessionStorage.setItem(k+a,JSON.stringify(b))}catch(c){return N(c)}return!0}return!1}function s(a,b){return l[a]=b,!0}function t(a){if(f)try{var b=localStorage.getItem(k+a);return b&&JSON.parse(b)}catch(c){return N(c),null}return null}function u(a){if(g)try{var b=sessionStorage.getItem(k+a);return b&&JSON.parse(b)}catch(c){return N(c),null}return null}function v(a){return a in l?l[a]:null}function w(a){return null!==t(a)}function x(a){return null!==u(a)}function y(a){return null!==v(a)}function z(a){return f?localStorage.key(a):null}function A(a){return g?sessionStorage.key(a):null}function B(a){var b=0;for(var c in l)if(l.hasOwnProperty(c)){if(a===b)return c;if(b+=1,b>a)return null}return null}function C(){return f?localStorage.length:0}function D(){return g?sessionStorage.length:0}function E(){if(Object.keys)return Object.keys(l).length;var a=0;for(var b in l)l.hasOwnProperty(b)&&(a+=1);return a}function F(a){if(f){try{localStorage.removeItem(k+a)}catch(b){return N(b)}return!0}return!1}function G(a){if(g){try{sessionStorage.removeItem(k+a)}catch(b){return N(b)}return!0}return!1}function H(a){return delete l[a],!0}function I(){if(!f)return!1;if(k){var a=k.length;try{for(var b in localStorage)b.substr(0,a)===k&&localStorage.removeItem(b)}catch(c){return N(c)}return!0}try{localStorage.clear()}catch(c){return N(c)}return!0}function J(){if(!g)return!1;if(k){var a=k.length;try{for(var b in sessionStorage)b.substr(0,a)===k&&sessionStorage.removeItem(b)}catch(c){return N(c)}return!0}try{sessionStorage.clear()}catch(c){return N(c)}return!0}function K(){return l={},!0}function L(){O();try{return localStorage.setItem(k+b.testKey,b.testKey),localStorage.removeItem(k+b.testKey),!0}catch(a){return!1}}function M(){P();try{return sessionStorage.setItem(k+b.testKey,b.testKey),sessionStorage.removeItem(k+b.testKey),!0}catch(a){return!1}}function N(b){return a.$broadcast(e,b.title+": "+b.message),!1}function O(){try{window.localStorage||(window.localStorage={getItem:function(a){return a&&this.hasOwnProperty(a)?unescape(document.cookie.replace(new RegExp("(?:^|.*;\\s*)"+escape(a).replace(/[\-\.\+\*]/g,"\\$&")+"\\s*\\=\\s*((?:[^;](?!;))*[^;]?).*"),"$1")):null},key:function(a){return unescape(document.cookie.replace(/\s*\=(?:.(?!;))*$/,"").split(/\s*\=(?:[^;](?!;))*[^;]?;\s*/)[a])},setItem:function(a,b){a&&(document.cookie=escape(a)+"="+escape(b)+"; expires=Tue, 19 Jan 2038 03:14:07 GMT; path=/",this.length=document.cookie.match(/\=/g).length)},length:0,removeItem:function(a){a&&this.hasOwnProperty(a)&&(document.cookie=escape(a)+"=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/",this.length--)},hasOwnProperty:function(a){return new RegExp("(?:^|;\\s*)"+escape(a).replace(/[\-\.\+\*]/g,"\\$&")+"\\s*\\=").test(document.cookie)}},window.localStorage.length=(document.cookie.match(/\=/g)||window.localStorage).length,h=!0)}catch(a){}}function P(){try{window.sessionStorage||(window.sessionStorage={getItem:function(a){return a&&this.hasOwnProperty(a)?unescape(document.cookie.replace(new RegExp("(?:^|.*;\\s*)"+escape(a).replace(/[\-\.\+\*]/g,"\\$&")+"\\s*\\=\\s*((?:[^;](?!;))*[^;]?).*"),"$1")):null},key:function(a){return unescape(document.cookie.replace(/\s*\=(?:.(?!;))*$/,"").split(/\s*\=(?:[^;](?!;))*[^;]?;\s*/)[a])},setItem:function(a,b){a&&(document.cookie=escape(a)+"="+escape(b)+"; path=/",this.length=document.cookie.match(/\=/g).length)},length:0,removeItem:function(a){a&&this.hasOwnProperty(a)&&(document.cookie=escape(a)+"=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/",this.length--)},hasOwnProperty:function(a){return new RegExp("(?:^|;\\s*)"+escape(a).replace(/[\-\.\+\*]/g,"\\$&")+"\\s*\\=").test(document.cookie)}},window.sessionStorage.length=(document.cookie.match(/\=/g)||window.sessionStorage).length,i=!0)}catch(a){}}function Q(a){var b=h;return a===!0&&h&&(window.localStorage=null,h=!1),b}function R(a){var b=i;return a===!0&&i&&(window.sessionStorage=null,h=!1),b}var c="undefined",d="angular-webstorage.js -- `add()` had been deprecated, use `set()` instead",e=b.errorName,f=L(),g=M(),h=!1,i=!1,j=b.order,k=b.prefix,l={},m={isSupported:f||g,local:{isSupported:f,add:n,set:q,get:t,has:w,key:z,length:C,remove:F,clear:I,isPolyfilled:Q},session:{isSupported:g,add:o,set:r,get:u,has:x,key:A,length:D,remove:G,clear:J,isPolyfilled:R},memory:{isSupported:!0,add:p,set:s,get:v,has:y,key:B,length:E,remove:H,clear:K,isPolyfilled:!1}};return m.add=function(a,b,c){return console.warn(d),m.set(a,b,c)},m.set=function(a,b,d){d=typeof d!==c?!!d:!1;for(var e=!1,f=j.length,g=0;f>g;++g){var h=m[j[g]];if(h.isSupported&&(e=h.set(a,b)||e,!d))return e}return e},m.get=function(a,b){b=typeof b!==c?!!b:!0;for(var d=j.length,e=0;d>e;++e){var f=m[j[e]];if(f.isSupported){var g=f.get(a);if(!b||null!==g)return g}}return null},m.has=function(a,b){return null!==m.get(a,b)},m.key=function(a,b){b=typeof b!==c?!!b:!0;for(var d=j.length,e=0;d>e;++e){var f=m[j[e]];if(f.isSupported){var g=f.key(a);if(!b||null!==g)return g}}return null},m.length=function(a){a=typeof a!==c?!!a:!0;for(var b=j.length,d=0;b>d;++d){var e=m[j[d]];if(e.isSupported){var f=e.length();if(!a||0!==f)return f}}return 0},m.remove=function(a,b){b=typeof b!==c?!!b:!0;for(var d=!1,e=j.length,f=0;e>f;++f){var g=m[j[f]];if(g.isSupported&&(d=g.remove(a)||d,!b))return d}return d},m.clear=function(a){a=typeof a!==c?!!a:!0;for(var b=!1,d=j.length,e=0;d>e;++e){var f=m[j[e]];if(f.isSupported&&(b=f.clear()||b,!a))return b}return b},m.errorName=function(a){var b=e;if(typeof a!==c){if("string"!=typeof a)return!1;e=a}return b},m.order=function(a){var b=angular.copy(j);if(typeof a!==c){j=[];for(var d in a)/^(local|session|memory)$/.test(a[d])&&j.push(a[d])}return b},m.prefix=function(a){var b=k;if(typeof a!==c){if("string"!=typeof a)return!1;k=a}return b},m}]); \ No newline at end of file