Configured the service to a provider type for more configurability.

dev
Marques Woodson 11 years ago
parent e96a2b2435
commit 2bff9d3e3c

@ -10,13 +10,13 @@ module.exports = function(grunt) {
grunt.initConfig({ grunt.initConfig({
karma: { karma: {
options: { options: {
autowatch: false, autowatch: true,
browsers: [ browsers: [
'PhantomJS' 'PhantomJS'
], ],
configFile: 'test/karma.conf.js', configFile: 'test/karma.conf.js',
reporters: [ 'dots' ], reporters: [ 'dots' ],
singleRun: true singleRun: false
}, },
unit: {} unit: {}
}, },

@ -1,270 +1,287 @@
(function() { (function() {
/* Start angularLocalStorage */ /* Start angularLocalStorage */
'use strict';
var angularLocalStorage = angular.module('LocalStorageModule', []); var angularLocalStorage = angular.module('LocalStorageModule', []);
angularLocalStorage.provider('localStorageService', function(){
// You should set a prefix to avoid overwriting any local storage variables from the rest of your app // You should set a prefix to avoid overwriting any local storage variables from the rest of your app
// e.g. angularLocalStorage.constant('prefix', 'youAppName'); // e.g. angularLocalStorage.constant('prefix', 'youAppName');
angularLocalStorage.value('prefix', 'ls'); this.prefix = 'ls';
// Cookie options (usually in case of fallback) // Cookie options (usually in case of fallback)
// expiry = Number of days before cookies expire // 0 = Does not expire // expiry = Number of days before cookies expire // 0 = Does not expire
// path = The web path the cookie represents // path = The web path the cookie represents
angularLocalStorage.constant('cookie', { expiry:30, path: '/'}); this.cookie = {
angularLocalStorage.constant('notify', { setItem: true, removeItem: false} ); expiry: 30,
path: '/'
angularLocalStorage.service('localStorageService', [ };
'$rootScope', this.notify = {
'prefix', setItem: true,
'cookie', removeItem: false
'notify', };
function($rootScope, prefix, cookie, notify) { this.setPrefix = function(prefix){
this.prefix = prefix;
// If there is a prefix set in the config lets use that with an appended period for readability };
//var prefix = angularLocalStorage.constant; this.setStorageCookie = function(exp, path){
if (prefix.substr(-1)!=='.') { this.cookie = {
prefix = !!prefix ? prefix + '.' : ''; expiry: exp,
} path: path
};
// Checks the browser to see if local storage is supported };
var browserSupportsLocalStorage = function () { this.setNotify = function(itemSet, itemRemove){
try { this.notify = {
return ('localStorage' in window && window['localStorage'] !== null); setItem: itemSet,
} catch (e) { removeItem: itemRemove
$rootScope.$broadcast('LocalStorageModule.notification.error',e.message); };
return false; };
}
}; this.$get = ['$rootScope',function($rootScope){
var prefix = this.prefix;
// Directly adds a value to local storage // If there is a prefix set in the config lets use that with an appended period for readability
// If local storage is not available in the browser use cookies //var prefix = angularLocalStorage.constant;
// Example use: localStorageService.add('library','angular'); if (prefix.substr(-1)!=='.') {
var addToLocalStorage = function (key, value) { prefix = !!prefix ? prefix + '.' : '';
}
// If this browser does not support local storage use cookies
if (!browserSupportsLocalStorage()) { // Checks the browser to see if local storage is supported
$rootScope.$broadcast('LocalStorageModule.notification.warning','LOCAL_STORAGE_NOT_SUPPORTED'); var browserSupportsLocalStorage = function () {
if (notify.setItem) { try {
$rootScope.$broadcast('LocalStorageModule.notification.setitem', {key: key, newvalue: value, storageType: 'cookie'}); return ('localStorage' in window && window.localStorage !== null);
} } catch (e) {
return addToCookies(key, value); $rootScope.$broadcast('LocalStorageModule.notification.error',e.message);
} return false;
}
// Let's convert undefined values to null to get the value consistent };
if (typeof value == "undefined") {
value = null; // Directly adds a value to local storage
} // If local storage is not available in the browser use cookies
// Example use: localStorageService.add('library','angular');
try { var addToLocalStorage = function (key, value) {
if (angular.isObject(value) || angular.isArray(value)) {
value = angular.toJson(value); // If this browser does not support local storage use cookies
} if (!browserSupportsLocalStorage()) {
localStorage.setItem(prefix+key, value); $rootScope.$broadcast('LocalStorageModule.notification.warning','LOCAL_STORAGE_NOT_SUPPORTED');
if (notify.setItem) { if (notify.setItem) {
$rootScope.$broadcast('LocalStorageModule.notification.setitem', {key: key, newvalue: value, storageType: 'localStorage'}); $rootScope.$broadcast('LocalStorageModule.notification.setitem', {key: key, newvalue: value, storageType: 'cookie'});
} }
} catch (e) { return addToCookies(key, value);
$rootScope.$broadcast('LocalStorageModule.notification.error',e.message); }
return addToCookies(key, value);
} // Let's convert undefined values to null to get the value consistent
return true; if (typeof value === "undefined") {
}; value = null;
}
// Directly get a value from local storage
// Example use: localStorageService.get('library'); // returns 'angular' try {
var getFromLocalStorage = function (key) { if (angular.isObject(value) || angular.isArray(value)) {
if (!browserSupportsLocalStorage()) { value = angular.toJson(value);
$rootScope.$broadcast('LocalStorageModule.notification.warning','LOCAL_STORAGE_NOT_SUPPORTED'); }
return getFromCookies(key); localStorage.setItem(prefix+key, value);
} if (notify.setItem) {
$rootScope.$broadcast('LocalStorageModule.notification.setitem', {key: key, newvalue: value, storageType: 'localStorage'});
var item = localStorage.getItem(prefix+key); }
// angular.toJson will convert null to 'null', so a proper conversion is needed } catch (e) {
// FIXME not a perfect solution, since a valid 'null' string can't be stored $rootScope.$broadcast('LocalStorageModule.notification.error',e.message);
if (!item || item === 'null') return null; return addToCookies(key, value);
}
if (item.charAt(0) === "{" || item.charAt(0) === "[") { return true;
return angular.fromJson(item); };
}
return item; // Directly get a value from local storage
}; // Example use: localStorageService.get('library'); // returns 'angular'
var getFromLocalStorage = function (key) {
// Remove an item from local storage if (!browserSupportsLocalStorage()) {
// Example use: localStorageService.remove('library'); // removes the key/value pair of library='angular' $rootScope.$broadcast('LocalStorageModule.notification.warning','LOCAL_STORAGE_NOT_SUPPORTED');
var removeFromLocalStorage = function (key) { return getFromCookies(key);
if (!browserSupportsLocalStorage()) { }
$rootScope.$broadcast('LocalStorageModule.notification.warning','LOCAL_STORAGE_NOT_SUPPORTED');
if (notify.removeItem) { var item = localStorage.getItem(prefix+key);
$rootScope.$broadcast('LocalStorageModule.notification.removeitem', {key: key, storageType: 'cookie'}); // 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
return removeFromCookies(key); if (!item || item === 'null') {return null;}
}
if (item.charAt(0) === "{" || item.charAt(0) === "[") {
try { return angular.fromJson(item);
localStorage.removeItem(prefix+key); }
if (notify.removeItem) { return item;
$rootScope.$broadcast('LocalStorageModule.notification.removeitem', {key: key, storageType: 'localStorage'}); };
}
} catch (e) { // Remove an item from local storage
$rootScope.$broadcast('LocalStorageModule.notification.error',e.message); // Example use: localStorageService.remove('library'); // removes the key/value pair of library='angular'
return removeFromCookies(key); var removeFromLocalStorage = function (key) {
} if (!browserSupportsLocalStorage()) {
return true; $rootScope.$broadcast('LocalStorageModule.notification.warning','LOCAL_STORAGE_NOT_SUPPORTED');
}; if (notify.removeItem) {
$rootScope.$broadcast('LocalStorageModule.notification.removeitem', {key: key, storageType: 'cookie'});
// Return array of keys for local storage }
// Example use: var keys = localStorageService.keys() return removeFromCookies(key);
var getKeysForLocalStorage = function () { }
if (!browserSupportsLocalStorage()) { try {
$rootScope.$broadcast('LocalStorageModule.notification.warning','LOCAL_STORAGE_NOT_SUPPORTED'); localStorage.removeItem(prefix+key);
return false; if (notify.removeItem) {
} $rootScope.$broadcast('LocalStorageModule.notification.removeitem', {key: key, storageType: 'localStorage'});
}
var prefixLength = prefix.length; } catch (e) {
var keys = []; $rootScope.$broadcast('LocalStorageModule.notification.error',e.message);
for (var key in localStorage) { return removeFromCookies(key);
// Only return keys that are for this app }
if (key.substr(0,prefixLength) === prefix) { return true;
try { };
keys.push(key.substr(prefixLength));
} catch (e) { // Return array of keys for local storage
$rootScope.$broadcast('LocalStorageModule.notification.error',e.Description); // Example use: var keys = localStorageService.keys()
return []; var getKeysForLocalStorage = function () {
}
} if (!browserSupportsLocalStorage()) {
} $rootScope.$broadcast('LocalStorageModule.notification.warning','LOCAL_STORAGE_NOT_SUPPORTED');
return keys; return false;
}; }
// Remove all data for this app from local storage var prefixLength = prefix.length;
// Example use: localStorageService.clearAll(); var keys = [];
// Should be used mostly for development purposes for (var key in localStorage) {
var clearAllFromLocalStorage = function () { // Only return keys that are for this app
if (key.substr(0,prefixLength) === prefix) {
if (!browserSupportsLocalStorage()) { try {
$rootScope.$broadcast('LocalStorageModule.notification.warning','LOCAL_STORAGE_NOT_SUPPORTED'); keys.push(key.substr(prefixLength));
return clearAllFromCookies(); } catch (e) {
} $rootScope.$broadcast('LocalStorageModule.notification.error',e.Description);
return [];
var prefixLength = prefix.length; }
}
for (var key in localStorage) { }
// Only remove items that are for this app return keys;
if (key.substr(0,prefixLength) === prefix) { };
try {
removeFromLocalStorage(key.substr(prefixLength)); // Remove all data for this app from local storage
} catch (e) { // Example use: localStorageService.clearAll();
$rootScope.$broadcast('LocalStorageModule.notification.error',e.message); // Should be used mostly for development purposes
return clearAllFromCookies(); var clearAllFromLocalStorage = function () {
}
} if (!browserSupportsLocalStorage()) {
} $rootScope.$broadcast('LocalStorageModule.notification.warning','LOCAL_STORAGE_NOT_SUPPORTED');
return true; return clearAllFromCookies();
}; }
// Checks the browser to see if cookies are supported var prefixLength = prefix.length;
var browserSupportsCookies = function() {
try { for (var key in localStorage) {
return navigator.cookieEnabled || // Only remove items that are for this app
("cookie" in document && (document.cookie.length > 0 || if (key.substr(0,prefixLength) === prefix) {
(document.cookie = "test").indexOf.call(document.cookie, "test") > -1)); try {
} catch (e) { removeFromLocalStorage(key.substr(prefixLength));
$rootScope.$broadcast('LocalStorageModule.notification.error',e.message); } catch (e) {
return false; $rootScope.$broadcast('LocalStorageModule.notification.error',e.message);
} return clearAllFromCookies();
}; }
}
// Directly adds a value to cookies }
// Typically used as a fallback is local storage is not available in the browser return true;
// Example use: localStorageService.cookie.add('library','angular'); };
var addToCookies = function (key, value) {
// Checks the browser to see if cookies are supported
if (typeof value == "undefined") { var browserSupportsCookies = function() {
return false; try {
} return navigator.cookieEnabled ||
("cookie" in document && (document.cookie.length > 0 ||
if (!browserSupportsCookies()) { (document.cookie = "test").indexOf.call(document.cookie, "test") > -1));
$rootScope.$broadcast('LocalStorageModule.notification.error','COOKIES_NOT_SUPPORTED'); } catch (e) {
return false; $rootScope.$broadcast('LocalStorageModule.notification.error',e.message);
} return false;
}
try { };
var expiry = '', expiryDate = new Date();
if (value === null) { // Directly adds a value to cookies
// Mark that the cookie has expired one day ago // Typically used as a fallback is local storage is not available in the browser
expiryDate.setTime(expiryDate.getTime() + (-1 * 24*60*60*1000)); // Example use: localStorageService.cookie.add('library','angular');
expiry = "; expires="+expiryDate.toGMTString(); var addToCookies = function (key, value) {
value = ''; if (typeof value === "undefined") {
} else if (cookie.expiry !== 0) { return false;
expiryDate.setTime(expiryDate.getTime() + (cookie.expiry*24*60*60*1000)); }
expiry = "; expires="+expiryDate.toGMTString();
} if (!browserSupportsCookies()) {
if (!!key) { $rootScope.$broadcast('LocalStorageModule.notification.error','COOKIES_NOT_SUPPORTED');
document.cookie = prefix + key + "=" + encodeURIComponent(value) + expiry + "; path="+cookie.path; return false;
} }
} catch (e) {
$rootScope.$broadcast('LocalStorageModule.notification.error',e.message); try {
return false; var expiry = '', expiryDate = new Date();
} if (value === null) {
return true; // Mark that the cookie has expired one day ago
}; expiryDate.setTime(expiryDate.getTime() + (-1 * 24*60*60*1000));
expiry = "; expires="+expiryDate.toGMTString();
// Directly get a value from a cookie
// Example use: localStorageService.cookie.get('library'); // returns 'angular' value = '';
var getFromCookies = function (key) { } else if (cookie.expiry !== 0) {
if (!browserSupportsCookies()) { expiryDate.setTime(expiryDate.getTime() + (cookie.expiry*24*60*60*1000));
$rootScope.$broadcast('LocalStorageModule.notification.error','COOKIES_NOT_SUPPORTED'); expiry = "; expires="+expiryDate.toGMTString();
return false; }
} if (!!key) {
document.cookie = prefix + key + "=" + encodeURIComponent(value) + expiry + "; path="+cookie.path;
var cookies = document.cookie.split(';'); }
for(var i=0;i < cookies.length;i++) { } catch (e) {
var thisCookie = cookies[i]; $rootScope.$broadcast('LocalStorageModule.notification.error',e.message);
while (thisCookie.charAt(0)==' ') { return false;
thisCookie = thisCookie.substring(1,thisCookie.length); }
} return true;
if (thisCookie.indexOf(prefix+key+'=') === 0) { };
return decodeURIComponent(thisCookie.substring(prefix.length+key.length+1,thisCookie.length));
} // Directly get a value from a cookie
} // Example use: localStorageService.cookie.get('library'); // returns 'angular'
return null; var getFromCookies = function (key) {
}; if (!browserSupportsCookies()) {
$rootScope.$broadcast('LocalStorageModule.notification.error','COOKIES_NOT_SUPPORTED');
var removeFromCookies = function (key) { return false;
addToCookies(key,null); }
};
var cookies = document.cookie.split(';');
var clearAllFromCookies = function () { for(var i=0;i < cookies.length;i++) {
var thisCookie = null, thisKey = null; var thisCookie = cookies[i];
var prefixLength = prefix.length; while (thisCookie.charAt(0)===' ') {
var cookies = document.cookie.split(';'); thisCookie = thisCookie.substring(1,thisCookie.length);
for(var i=0;i < cookies.length;i++) { }
thisCookie = cookies[i]; if (thisCookie.indexOf(prefix+key+'=') === 0) {
while (thisCookie.charAt(0)==' ') { return decodeURIComponent(thisCookie.substring(prefix.length+key.length+1,thisCookie.length));
thisCookie = thisCookie.substring(1,thisCookie.length); }
} }
key = thisCookie.substring(prefixLength,thisCookie.indexOf('=')); return null;
removeFromCookies(key); };
}
}; var removeFromCookies = function (key) {
addToCookies(key,null);
return { };
isSupported: browserSupportsLocalStorage,
set: addToLocalStorage, var clearAllFromCookies = function () {
add: addToLocalStorage, //DEPRECATED var thisCookie = null, thisKey = null;
get: getFromLocalStorage, var prefixLength = prefix.length;
keys: getKeysForLocalStorage, var cookies = document.cookie.split(';');
remove: removeFromLocalStorage, for(var i=0;i < cookies.length;i++) {
clearAll: clearAllFromLocalStorage, thisCookie = cookies[i];
cookie: { while (thisCookie.charAt(0)===' ') {
set: addToCookies, thisCookie = thisCookie.substring(1,thisCookie.length);
add: addToCookies, //DEPRECATED }
get: getFromCookies, key = thisCookie.substring(prefixLength,thisCookie.indexOf('='));
remove: removeFromCookies, removeFromCookies(key);
clearAll: clearAllFromCookies }
} };
};
return {
}]); isSupported: browserSupportsLocalStorage,
}).call(this); set: addToLocalStorage,
add: addToLocalStorage, //DEPRECATED
get: getFromLocalStorage,
keys: getKeysForLocalStorage,
remove: removeFromLocalStorage,
clearAll: clearAllFromLocalStorage,
cookie: {
set: addToCookies,
add: addToCookies, //DEPRECATED
get: getFromCookies,
remove: removeFromCookies,
clearAll: clearAllFromCookies
}
};
}]
});
}).call(this);

@ -1,16 +1,16 @@
describe('Tests functionality of the localStorage module', function(){ describe('Tests functionality of the localStorage module', function(){
beforeEach(module('LocalStorageModule')); beforeEach(module('LocalStorageModule', function(localStorageServiceProvider){
p = localStorageServiceProvider;
}));
var ls, store = []; var ls, store = [];
beforeEach(inject(function(_localStorageService_){ beforeEach(inject(function(_localStorageService_){
ls = _localStorageService_; ls = _localStorageService_;
spyOn(ls, 'get').andCallFake(function(key){ spyOn(ls, 'get').andCallFake(function(key){
if(store[key].charAt(0) === "{" || store[key].charAt(0) === "["){ if(store[key].charAt(0) === "{" || store[key].charAt(0) === "["){
return angular.fromJson(store[key]); return angular.fromJson(store[key]);
}else{ }else{
return store[key]; return store[key];
} }
}); });
spyOn(ls, 'set').andCallFake(function(key, val){ spyOn(ls, 'set').andCallFake(function(key, val){
@ -32,6 +32,7 @@ describe('Tests functionality of the localStorage module', function(){
it("Should add a value to my local storage", function(){ it("Should add a value to my local storage", function(){
var n = 234; var n = 234;
ls.set('test', n); ls.set('test', n);
//Since localStorage makes the value a string, we look for the '234' and not 234
expect(ls.get('test')).toBe('234'); expect(ls.get('test')).toBe('234');
var obj = { key: 'val' }; var obj = { key: 'val' };
@ -40,4 +41,15 @@ describe('Tests functionality of the localStorage module', function(){
expect(res.key).toBe('val'); expect(res.key).toBe('val');
}); });
});
it('Should allow me to set a prefix', function(){
p.setPrefix("myPref");
expect(p.prefix).toBe("myPref");
});
it('Should allow me to set the cookie values', function(){
p.setStorageCookie(60, '/path');
expect(p.cookie.expiry).toBe(60);
expect(p.cookie.path).toBe('/path');
});
});