Compare commits

..

No commits in common. 'master' and '0.1.2' have entirely different histories.

1
.gitignore vendored

@ -5,4 +5,3 @@ bower_components
npm-debug.log
*.swp
.idea
coverage

@ -5,5 +5,4 @@ before_script:
- 'npm install -g grunt-cli'
- 'npm install -g bower'
- 'bower install'
script: grunt test
after_script: "npm install coveralls@2.10.0 && cat ./coverage/*/lcov.info | coveralls"
script: grunt test

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

@ -1,8 +1,8 @@
Angular Local Storage
Copyright 2015 Gregory Pike
Copyright 2013 Gregory Pike
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

@ -1,19 +1,12 @@
angular-local-storage
=====================
**Note to myself: Used for an other project, do not delete.**
An Angular module that gives you access to the browsers local storage, **v0.1.5**
An Angular module that gives you access to the browsers local storage, **v0.1.2**
[![NPM version][npm-image]][npm-url]
[![Build status][travis-image]][travis-url]
[![Test coverage][coveralls-image]][coveralls-url]
[![Dependency Status][david-image]][david-url]
[![License][license-image]][license-url]
[![Downloads][downloads-image]][downloads-url]
[![Build Status](https://secure.travis-ci.org/grevory/angular-local-storage.png?branch=master)](https://travis-ci.org/grevory/)
##Table of contents:
- [Get Started](#get-started)
- [Development](#development)
- [Configuration](#configuration)
- [setPrefix](#setprefix)
- [setStorageType](#setstoragetype)
@ -33,7 +26,6 @@ An Angular module that gives you access to the browsers local storage, **v0.1.5*
- [deriveKey](#derivekey)
- [length](#length)
- [cookie](#cookie)
- [isSupported](#cookieissupported)
- [set](#cookieset)
- [get](#cookieget)
- [remove](#cookieremove)
@ -106,7 +98,7 @@ myApp.config(function (localStorageServiceProvider) {
});
```
###setStorageCookieDomain
Set the cookie domain, since this runs inside a the `config()` block, only providers and constants can be injected. As a result, `$location` service can't be used here, use a hardcoded string or `window.location`.<br/>
Set for cookie domain<br/>
**No default value**
```js
myApp.config(function (localStorageServiceProvider) {
@ -114,9 +106,6 @@ myApp.config(function (localStorageServiceProvider) {
.setStorageCookieDomain('<domain>');
});
```
For local testing (when you are testing on localhost) set the domain to an empty string ''. Setting the domain to 'localhost' will not work on all browsers (eg. Chrome) since some browsers only allow you to set domain cookies for registry controlled domains, i.e. something ending in .com or so, but not IPs **or intranet hostnames** like localhost. </br>
###setNotify
Send signals for each of the following actions:<br/>
**setItem** , default: `true`<br/>
@ -139,7 +128,7 @@ myApp.config(function (localStorageServiceProvider) {
```
##API Documentation
##isSupported
Checks if the browser support the current storage type(e.g: `localStorage`, `sessionStorage`).
Checks if the browser support the current storage type(e.g: `localStorage`, `sessionStorage`).
**Returns:** `Boolean`
```js
myApp.controller('MainCtrl', function($scope, localStorageService) {
@ -167,7 +156,7 @@ If local storage is not supported, use cookies instead.<br/>
myApp.controller('MainCtrl', function($scope, localStorageService) {
//...
function submit(key, val) {
return localStorageService.set(key, val);
return localStorageService.set(key, value);
}
//...
});
@ -228,35 +217,26 @@ myApp.controller('MainCtrl', function($scope, localStorageService) {
###bind
Bind $scope key to localStorageService.
**Usage:** `localStorageService.bind(scope, property, value[optional], key[optional])`
***key:*** The corresponding key used in local storage
***key:*** The corresponding key used in local storage
**Returns:** deregistration function for this listener.
```js
myApp.controller('MainCtrl', function($scope, localStorageService) {
//...
localStorageService.set('property', 'oldValue');
$scope.unbind = localStorageService.bind($scope, 'property');
var unbind = localStorageService.bind($scope, 'property');
//Test Changes
$scope.update = function(val) {
$scope.property = val;
$timeout(function() {
alert("localStorage value: " + localStorageService.get('property'));
});
}
$scope.property = 'newValue1';
console.log(localStorageService.get('property')) // newValue1;
//unbind watcher
unbind();
$scope.property = 'newValue2';
console.log(localStorageService.get('property')) // newValue1;
//...
});
```
```html
<div ng-controller="MainCtrl">
<p>{{property}}</p>
<input type="text" ng-model="lsValue"/>
<button ng-click="update(lsValue)">update</button>
<button ng-click="unbind()">unbind</button>
</div>
```
###deriveKey
Return the derive key
Return the derive key
**Returns** `String`
```js
myApp.controller('MainCtrl', function($scope, localStorageService) {
@ -268,7 +248,7 @@ myApp.controller('MainCtrl', function($scope, localStorageService) {
});
```
###length
Return localStorageService.length, ignore keys that not owned.
Return localStorageService.length, ignore keys that not owned.
**Returns** `Number`
```js
myApp.controller('MainCtrl', function($scope, localStorageService) {
@ -279,18 +259,6 @@ myApp.controller('MainCtrl', function($scope, localStorageService) {
```
##Cookie
Deal with browser's cookies directly.
##cookie.isSupported
Checks if cookies are enabled in the browser.
**Returns:** `Boolean`
```js
myApp.controller('MainCtrl', function($scope, localStorageService) {
//...
if(localStorageService.cookie.isSupported) {
//...
}
//...
});
```
###cookie.set
Directly adds a value to cookies.<br/>
**Note:** Typically used as a fallback if local storage is not supported.<br/>
@ -299,7 +267,7 @@ Directly adds a value to cookies.<br/>
myApp.controller('MainCtrl', function($scope, localStorageService) {
//...
function submit(key, val) {
return localStorageService.cookie.set(key, val);
return localStorageService.cookie.set(key, value);
}
//...
});
@ -328,9 +296,8 @@ myApp.controller('MainCtrl', function($scope, localStorageService) {
//...
});
```
###cookie.clearAll
###clearAll
Remove all data for this app from cookie.<br/>
**Returns:** `Boolean`
```js
myApp.controller('MainCtrl', function($scope, localStorageService) {
//...
@ -343,36 +310,22 @@ myApp.controller('MainCtrl', function($scope, localStorageService) {
Check out the full demo at http://gregpike.net/demos/angular-local-storage/demo.html
##Development:
* Don't forget about tests.
* If you planning add some feature please create issue before.
Clone the project:
```sh
```bash
$ git clone https://github.com/<your-repo>/angular-local-storage.git
$ npm install
$ bower install
```
Run the tests:
```sh
```bash
$ grunt test
```
**Deploy:**<br/>
Run the build task, update version before(bower,package)
```sh
```bash
$ grunt dist
$ git tag 0.*.*
$ git push origin master --tags
```
[npm-image]: https://img.shields.io/npm/v/angular-local-storage.svg?style=flat-square
[npm-url]: https://npmjs.org/package/angular-local-storage
[travis-image]: https://img.shields.io/travis/grevory/angular-local-storage.svg?style=flat-square
[travis-url]: https://travis-ci.org/grevory/angular-local-storage
[coveralls-image]: https://img.shields.io/coveralls/grevory/angular-local-storage.svg?style=flat-square
[coveralls-url]: https://coveralls.io/r/grevory/angular-local-storage
[david-image]: http://img.shields.io/david/grevory/angular-local-storage.svg?style=flat-square
[david-url]: https://david-dm.org/grevory/angular-local-storage
[license-image]: http://img.shields.io/npm/l/angular-local-storage.svg?style=flat-square
[license-url]: LICENSE
[downloads-image]: http://img.shields.io/npm/dm/angular-local-storage.svg?style=flat-square
[downloads-url]: https://npmjs.org/package/angular-local-storage

@ -1,6 +1,6 @@
{
"name": "angular-local-storage",
"version": "0.1.5",
"version": "0.1.2",
"homepage": "http://gregpike.net/demos/angular-local-storage/demo.html",
"authors": [
"grevory <greg@gregpike.ca>"

@ -1,13 +1,13 @@
'use strict';
window.angular.module('demoModule', ['LocalStorageModule'])
.config(function(localStorageServiceProvider){
angular.module('demoModule', ['LocalStorageModule'])
.config(['localStorageServiceProvider', function(localStorageServiceProvider){
localStorageServiceProvider.setPrefix('demoPrefix');
// localStorageServiceProvider.setStorageCookieDomain('example.com');
// localStorageServiceProvider.setStorageType('sessionStorage');
})
.controller('DemoCtrl',
}])
.controller('DemoCtrl', [
'$scope',
'localStorageService',
function($scope, localStorageService) {
$scope.localStorageDemo = localStorageService.get('localStorageDemo');
$scope.$watch('localStorageDemo', function(value){
localStorageService.set('localStorageDemo',value);
@ -23,13 +23,5 @@ window.angular.module('demoModule', ['LocalStorageModule'])
if (!localStorageService.isSupported) {
$scope.storageType = 'Cookie';
}
$scope.$watch(function(){
return localStorageService.get('localStorageDemo');
}, function(value){
$scope.localStorageDemo = value;
});
$scope.clearAll = localStorageService.clearAll;
}
);
]);

@ -1,17 +1,18 @@
<!doctype html>
<html lang="en">
<meta charset="utf-8">
<title>Demo of Angular Local Storage Module</title>
<meta name="description" content="Demo of Angular Local Storage Module">
<meta name="author" content="Gregory Pike">
<!-- Always force latest IE rendering engine (even in intranet) & Chrome Frame -->
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<!-- Place favicon.ico and apple-touch-icon.png in the root of your domain and delete these references -->
<!--[if IE]><![endif]--><!-- Used to speed CSS loading -->
<link rel="stylesheet" href="http://necolas.github.com/normalize.css/2.0.1/normalize.css">
<link href="http://netdna.bootstrapcdn.com/twitter-bootstrap/2.1.1/css/bootstrap-combined.min.css" rel="stylesheet">
<link href="http://google-code-prettify.googlecode.com/svn/trunk/src/prettify.css" rel="stylesheet">
<link href="demo-style.css" rel="stylesheet">
<!--[if lt IE 9]>
<script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
@ -29,18 +30,16 @@
</div>
<div class="hero-unit">
<h1>Give it a try</h1>
<div ng-controller="DemoCtrl">
<p><input type="text" ng-model="localStorageDemo" placeholder="Start typing..."></p>
<blockquote class="well" ng-show="localStorageDemoValue">
<p ng-bind="localStorageDemoValue"></p>
<p>{{localStorageDemoValue}}</p>
<small>{{storageType}} value</small>
</blockquote>
<p><button ng-click="clearAll()">Clear All</button></p>
</div>
<p>The Angular Local Storage Module is meant to be a plug-and-play Angular module for accessing the browsers Local Storage API.</p>
@ -145,11 +144,11 @@ var YourCtrl = function($scope, localStorageService, ...) {
</div>
<!-- END DEMO -->
<!-- JAVASCRIPT -->
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.1/angular.min.js"></script>
<script src="http://google-code-prettify.googlecode.com/svn/trunk/src/prettify.js"></script>
<script src="https://rawgit.com/grevory/angular-local-storage/master/dist/angular-local-storage.min.js"></script>
<script src="../dist/angular-local-storage.min.js"></script>
<script src="demo-app.js"></script>
</body>
</html>

@ -1,6 +1,6 @@
/**
* An Angular module that gives you access to the browsers local storage
* @version v0.1.5 - 2015-01-22
* @version v0.1.2 - 2014-10-10
* @link https://github.com/grevory/angular-local-storage
* @author grevory <greg@gregpike.ca>
* @license MIT License, http://www.opensource.org/licenses/MIT
@ -30,7 +30,7 @@ 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
// e.g. localStorageServiceProvider.setPrefix('yourAppName');
// e.g. localStorageServiceProvider.setPrefix('youAppName');
// With provider you can use config as this:
// myApp.config(function (localStorageServiceProvider) {
// localStorageServiceProvider.prefix = 'yourAppName';
@ -57,13 +57,11 @@ angularLocalStorage.provider('localStorageService', function() {
// 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;
this.storageType = storageType;
};
// Setter for cookie config
@ -72,13 +70,11 @@ angularLocalStorage.provider('localStorageService', function() {
expiry: exp,
path: path
};
return this;
};
// Setter for cookie domain
this.setStorageCookieDomain = function(domain) {
this.cookie.domain = domain;
return this;
};
// Setter for notification config
@ -88,7 +84,6 @@ angularLocalStorage.provider('localStorageService', function() {
setItem: itemSet,
removeItem: itemRemove
};
return this;
};
this.$get = ['$rootScope', '$window', '$document', '$parse', function($rootScope, $window, $document, $parse) {
@ -291,16 +286,16 @@ angularLocalStorage.provider('localStorageService', function() {
};
// Checks the browser to see if cookies are supported
var browserSupportsCookies = (function() {
var browserSupportsCookies = function() {
try {
return $window.navigator.cookieEnabled ||
return 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 is local storage is not available in the browser
@ -313,7 +308,7 @@ angularLocalStorage.provider('localStorageService', function() {
value = toJson(value);
}
if (!browserSupportsCookies) {
if (!browserSupportsCookies()) {
$rootScope.$broadcast('LocalStorageModule.notification.error', 'COOKIES_NOT_SUPPORTED');
return false;
}
@ -349,7 +344,7 @@ angularLocalStorage.provider('localStorageService', function() {
// Directly get a value from a cookie
// Example use: localStorageService.cookie.get('library'); // returns 'angular'
var getFromCookies = function (key) {
if (!browserSupportsCookies) {
if (!browserSupportsCookies()) {
$rootScope.$broadcast('LocalStorageModule.notification.error', 'COOKIES_NOT_SUPPORTED');
return false;
}
@ -399,8 +394,11 @@ angularLocalStorage.provider('localStorageService', function() {
// 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) {
lsKey = lsKey || key;
var bindToScope = function(scope, scopeKey, def, lsKey) {
if (!lsKey) {
lsKey = scopeKey;
}
var value = getFromLocalStorage(lsKey);
if (value === null && isDefined(def)) {
@ -409,11 +407,11 @@ angularLocalStorage.provider('localStorageService', function() {
value = extend(def, value);
}
$parse(key).assign(scope, value);
$parse(scopeKey).assign(scope, value);
return scope.$watch(key, function(newVal) {
return scope.$watchCollection(scopeKey, function(newVal) {
addToLocalStorage(lsKey, newVal);
}, isObject(scope[key]));
});
};
// Return localStorageService.length
@ -433,7 +431,6 @@ angularLocalStorage.provider('localStorageService', function() {
isSupported: browserSupportsLocalStorage,
getStorageType: getStorageType,
set: addToLocalStorage,
put: addToLocalStorage,
add: addToLocalStorage, //DEPRECATED
get: getFromLocalStorage,
keys: getKeysForLocalStorage,
@ -443,7 +440,6 @@ angularLocalStorage.provider('localStorageService', function() {
deriveKey: deriveQualifiedKey,
length: lengthOfLocalStorage,
cookie: {
isSupported: browserSupportsCookies,
set: addToCookies,
add: addToCookies, //DEPRECATED
get: getFromCookies,

@ -1,7 +1,7 @@
/**
* An Angular module that gives you access to the browsers local storage
* @version v0.1.5 - 2015-01-22
* @version v0.1.2 - 2014-10-10
* @link https://github.com/grevory/angular-local-storage
* @author grevory <greg@gregpike.ca>
* @license MIT License, http://www.opensource.org/licenses/MIT
*/!function(a,b){"use strict";function c(a){return/^-?\d+\.?\d*$/.test(a.replace(/["']/g,""))}var d=b.isDefined,e=b.isUndefined,f=b.isNumber,g=b.isObject,h=b.isArray,i=b.extend,j=b.toJson,k=b.fromJson,l=b.module("LocalStorageModule",[]);l.provider("localStorageService",function(){this.prefix="ls",this.storageType="localStorage",this.cookie={expiry:30,path:"/"},this.notify={setItem:!0,removeItem:!1},this.setPrefix=function(a){return this.prefix=a,this},this.setStorageType=function(a){return this.storageType=a,this},this.setStorageCookie=function(a,b){return this.cookie={expiry:a,path:b},this},this.setStorageCookieDomain=function(a){return this.cookie.domain=a,this},this.setNotify=function(a,b){return this.notify={setItem:a,removeItem:b},this},this.$get=["$rootScope","$window","$document","$parse",function(a,b,l,m){var n,o=this,p=o.prefix,q=o.cookie,r=o.notify,s=o.storageType;l?l[0]&&(l=l[0]):l=document,"."!==p.substr(-1)&&(p=p?p+".":"");var t=function(a){return p+a},u=function(){try{var c=s in b&&null!==b[s],d=t("__"+Math.round(1e7*Math.random()));return c&&(n=b[s],n.setItem(d,""),n.removeItem(d)),c}catch(e){return s="cookie",a.$broadcast("LocalStorageModule.notification.error",e.message),!1}}(),v=function(b,c){if(e(c)?c=null:(g(c)||h(c)||f(+c||c))&&(c=j(c)),!u||"cookie"===o.storageType)return u||a.$broadcast("LocalStorageModule.notification.warning","LOCAL_STORAGE_NOT_SUPPORTED"),r.setItem&&a.$broadcast("LocalStorageModule.notification.setitem",{key:b,newvalue:c,storageType:"cookie"}),B(b,c);try{(g(c)||h(c))&&(c=j(c)),n&&n.setItem(t(b),c),r.setItem&&a.$broadcast("LocalStorageModule.notification.setitem",{key:b,newvalue:c,storageType:o.storageType})}catch(d){return a.$broadcast("LocalStorageModule.notification.error",d.message),B(b,c)}return!0},w=function(b){if(!u||"cookie"===o.storageType)return u||a.$broadcast("LocalStorageModule.notification.warning","LOCAL_STORAGE_NOT_SUPPORTED"),C(b);var d=n?n.getItem(t(b)):null;return d&&"null"!==d?"{"===d.charAt(0)||"["===d.charAt(0)||c(d)?k(d):d:null},x=function(b){if(!u||"cookie"===o.storageType)return u||a.$broadcast("LocalStorageModule.notification.warning","LOCAL_STORAGE_NOT_SUPPORTED"),r.removeItem&&a.$broadcast("LocalStorageModule.notification.removeitem",{key:b,storageType:"cookie"}),D(b);try{n.removeItem(t(b)),r.removeItem&&a.$broadcast("LocalStorageModule.notification.removeitem",{key:b,storageType:o.storageType})}catch(c){return a.$broadcast("LocalStorageModule.notification.error",c.message),D(b)}return!0},y=function(){if(!u)return a.$broadcast("LocalStorageModule.notification.warning","LOCAL_STORAGE_NOT_SUPPORTED"),!1;var b=p.length,c=[];for(var d in n)if(d.substr(0,b)===p)try{c.push(d.substr(b))}catch(e){return a.$broadcast("LocalStorageModule.notification.error",e.Description),[]}return c},z=function(b){b=b||"";var c=p.slice(0,-1),d=new RegExp(c+"."+b);if(!u||"cookie"===o.storageType)return u||a.$broadcast("LocalStorageModule.notification.warning","LOCAL_STORAGE_NOT_SUPPORTED"),E();var e=p.length;for(var f in n)if(d.test(f))try{x(f.substr(e))}catch(g){return a.$broadcast("LocalStorageModule.notification.error",g.message),E()}return!0},A=function(){try{return b.navigator.cookieEnabled||"cookie"in l&&(l.cookie.length>0||(l.cookie="test").indexOf.call(l.cookie,"test")>-1)}catch(c){return a.$broadcast("LocalStorageModule.notification.error",c.message),!1}}(),B=function(b,c){if(e(c))return!1;if((h(c)||g(c))&&(c=j(c)),!A)return a.$broadcast("LocalStorageModule.notification.error","COOKIES_NOT_SUPPORTED"),!1;try{var d="",f=new Date,i="";if(null===c?(f.setTime(f.getTime()+-864e5),d="; expires="+f.toGMTString(),c=""):0!==q.expiry&&(f.setTime(f.getTime()+24*q.expiry*60*60*1e3),d="; expires="+f.toGMTString()),b){var k="; path="+q.path;q.domain&&(i="; domain="+q.domain),l.cookie=t(b)+"="+encodeURIComponent(c)+d+k+i}}catch(m){return a.$broadcast("LocalStorageModule.notification.error",m.message),!1}return!0},C=function(b){if(!A)return a.$broadcast("LocalStorageModule.notification.error","COOKIES_NOT_SUPPORTED"),!1;for(var c=l.cookie&&l.cookie.split(";")||[],d=0;d<c.length;d++){for(var e=c[d];" "===e.charAt(0);)e=e.substring(1,e.length);if(0===e.indexOf(t(b)+"=")){var f=decodeURIComponent(e.substring(p.length+b.length+1,e.length));try{var g=JSON.parse(f);return k(g)}catch(h){return f}}}return null},D=function(a){B(a,null)},E=function(){for(var a=null,b=p.length,c=l.cookie.split(";"),d=0;d<c.length;d++){for(a=c[d];" "===a.charAt(0);)a=a.substring(1,a.length);var e=a.substring(b,a.indexOf("="));D(e)}},F=function(){return s},G=function(a,b,c,e){e=e||b;var f=w(e);return null===f&&d(c)?f=c:g(f)&&g(c)&&(f=i(c,f)),m(b).assign(a,f),a.$watch(b,function(a){v(e,a)},g(a[b]))},H=function(){for(var a=0,c=b[s],d=0;d<c.length;d++)0===c.key(d).indexOf(p)&&a++;return a};return{isSupported:u,getStorageType:F,set:v,put:v,add:v,get:w,keys:y,remove:x,clearAll:z,bind:G,deriveKey:t,length:H,cookie:{isSupported:A,set:B,add:B,get:C,remove:D,clearAll:E}}}]})}(window,window.angular);
*/!function(a,b){"use strict";function c(a){return/^-?\d+\.?\d*$/.test(a.replace(/["']/g,""))}var d=b.isDefined,e=b.isUndefined,f=b.isNumber,g=b.isObject,h=b.isArray,i=b.extend,j=b.toJson,k=b.fromJson,l=b.module("LocalStorageModule",[]);l.provider("localStorageService",function(){this.prefix="ls",this.storageType="localStorage",this.cookie={expiry:30,path:"/"},this.notify={setItem:!0,removeItem:!1},this.setPrefix=function(a){this.prefix=a},this.setStorageType=function(a){this.storageType=a},this.setStorageCookie=function(a,b){this.cookie={expiry:a,path:b}},this.setStorageCookieDomain=function(a){this.cookie.domain=a},this.setNotify=function(a,b){this.notify={setItem:a,removeItem:b}},this.$get=["$rootScope","$window","$document","$parse",function(a,b,l,m){var n,o=this,p=o.prefix,q=o.cookie,r=o.notify,s=o.storageType;l?l[0]&&(l=l[0]):l=document,"."!==p.substr(-1)&&(p=p?p+".":"");var t=function(a){return p+a},u=function(){try{var c=s in b&&null!==b[s],d=t("__"+Math.round(1e7*Math.random()));return c&&(n=b[s],n.setItem(d,""),n.removeItem(d)),c}catch(e){return s="cookie",a.$broadcast("LocalStorageModule.notification.error",e.message),!1}}(),v=function(b,c){if(e(c)?c=null:(g(c)||h(c)||f(+c||c))&&(c=j(c)),!u||"cookie"===o.storageType)return u||a.$broadcast("LocalStorageModule.notification.warning","LOCAL_STORAGE_NOT_SUPPORTED"),r.setItem&&a.$broadcast("LocalStorageModule.notification.setitem",{key:b,newvalue:c,storageType:"cookie"}),B(b,c);try{(g(c)||h(c))&&(c=j(c)),n&&n.setItem(t(b),c),r.setItem&&a.$broadcast("LocalStorageModule.notification.setitem",{key:b,newvalue:c,storageType:o.storageType})}catch(d){return a.$broadcast("LocalStorageModule.notification.error",d.message),B(b,c)}return!0},w=function(b){if(!u||"cookie"===o.storageType)return u||a.$broadcast("LocalStorageModule.notification.warning","LOCAL_STORAGE_NOT_SUPPORTED"),C(b);var d=n?n.getItem(t(b)):null;return d&&"null"!==d?"{"===d.charAt(0)||"["===d.charAt(0)||c(d)?k(d):d:null},x=function(b){if(!u||"cookie"===o.storageType)return u||a.$broadcast("LocalStorageModule.notification.warning","LOCAL_STORAGE_NOT_SUPPORTED"),r.removeItem&&a.$broadcast("LocalStorageModule.notification.removeitem",{key:b,storageType:"cookie"}),D(b);try{n.removeItem(t(b)),r.removeItem&&a.$broadcast("LocalStorageModule.notification.removeitem",{key:b,storageType:o.storageType})}catch(c){return a.$broadcast("LocalStorageModule.notification.error",c.message),D(b)}return!0},y=function(){if(!u)return a.$broadcast("LocalStorageModule.notification.warning","LOCAL_STORAGE_NOT_SUPPORTED"),!1;var b=p.length,c=[];for(var d in n)if(d.substr(0,b)===p)try{c.push(d.substr(b))}catch(e){return a.$broadcast("LocalStorageModule.notification.error",e.Description),[]}return c},z=function(b){b=b||"";var c=p.slice(0,-1),d=new RegExp(c+"."+b);if(!u||"cookie"===o.storageType)return u||a.$broadcast("LocalStorageModule.notification.warning","LOCAL_STORAGE_NOT_SUPPORTED"),E();var e=p.length;for(var f in n)if(d.test(f))try{x(f.substr(e))}catch(g){return a.$broadcast("LocalStorageModule.notification.error",g.message),E()}return!0},A=function(){try{return navigator.cookieEnabled||"cookie"in l&&(l.cookie.length>0||(l.cookie="test").indexOf.call(l.cookie,"test")>-1)}catch(b){return a.$broadcast("LocalStorageModule.notification.error",b.message),!1}},B=function(b,c){if(e(c))return!1;if((h(c)||g(c))&&(c=j(c)),!A())return a.$broadcast("LocalStorageModule.notification.error","COOKIES_NOT_SUPPORTED"),!1;try{var d="",f=new Date,i="";if(null===c?(f.setTime(f.getTime()+-864e5),d="; expires="+f.toGMTString(),c=""):0!==q.expiry&&(f.setTime(f.getTime()+24*q.expiry*60*60*1e3),d="; expires="+f.toGMTString()),b){var k="; path="+q.path;q.domain&&(i="; domain="+q.domain),l.cookie=t(b)+"="+encodeURIComponent(c)+d+k+i}}catch(m){return a.$broadcast("LocalStorageModule.notification.error",m.message),!1}return!0},C=function(b){if(!A())return a.$broadcast("LocalStorageModule.notification.error","COOKIES_NOT_SUPPORTED"),!1;for(var c=l.cookie&&l.cookie.split(";")||[],d=0;d<c.length;d++){for(var e=c[d];" "===e.charAt(0);)e=e.substring(1,e.length);if(0===e.indexOf(t(b)+"=")){var f=decodeURIComponent(e.substring(p.length+b.length+1,e.length));try{var g=JSON.parse(f);return k(g)}catch(h){return f}}}return null},D=function(a){B(a,null)},E=function(){for(var a=null,b=p.length,c=l.cookie.split(";"),d=0;d<c.length;d++){for(a=c[d];" "===a.charAt(0);)a=a.substring(1,a.length);var e=a.substring(b,a.indexOf("="));D(e)}},F=function(){return s},G=function(a,b,c,e){e||(e=b);var f=w(e);return null===f&&d(c)?f=c:g(f)&&g(c)&&(f=i(c,f)),m(b).assign(a,f),a.$watchCollection(b,function(a){v(e,a)})},H=function(){for(var a=0,c=b[s],d=0;d<c.length;d++)0===c.key(d).indexOf(p)&&a++;return a};return{isSupported:u,getStorageType:F,set:v,add:v,get:w,keys:y,remove:x,clearAll:z,bind:G,deriveKey:t,length:H,cookie:{set:B,add:B,get:C,remove:D,clearAll:E}}}]})}(window,window.angular);

@ -1,9 +1,9 @@
{
"name": "angular-local-storage",
"version": "0.1.5",
"version": "0.1.2",
"description": "An Angular module that gives you access to the browsers local storage",
"homepage": "https://github.com/grevory/angular-local-storage",
"main": "./dist/angular-local-storage.js",
"main": "angular-local-storage.js",
"scripts": {
"test": "grunt test"
},
@ -22,17 +22,15 @@
"url": "https://github.com/grevory/angular-local-storage/issues"
},
"devDependencies": {
"time-grunt": "~0.2.9",
"load-grunt-tasks": "~0.3.0",
"grunt-contrib-jshint": "~0.8.0",
"grunt": "~0.4.2",
"grunt-cli": "~0.1.9",
"grunt-contrib-concat": "*",
"grunt-contrib-jshint": "~0.8.0",
"grunt-contrib-uglify": "*",
"grunt-karma": "latest",
"karma": "~0.12.16",
"karma-jasmine": "~0.1.5",
"karma-coverage": "^0.2.6",
"karma-phantomjs-launcher": "~0.1.4",
"load-grunt-tasks": "~0.3.0",
"time-grunt": "~0.2.9"
"grunt-contrib-concat": "*",
"karma": "~0.10",
"grunt-karma": "~0.6.2",
"karma-jasmine": "*"
}
}

@ -3,7 +3,7 @@ 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
// e.g. localStorageServiceProvider.setPrefix('yourAppName');
// e.g. localStorageServiceProvider.setPrefix('youAppName');
// With provider you can use config as this:
// myApp.config(function (localStorageServiceProvider) {
// localStorageServiceProvider.prefix = 'yourAppName';
@ -30,13 +30,11 @@ angularLocalStorage.provider('localStorageService', function() {
// 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;
this.storageType = storageType;
};
// Setter for cookie config
@ -45,13 +43,11 @@ angularLocalStorage.provider('localStorageService', function() {
expiry: exp,
path: path
};
return this;
};
// Setter for cookie domain
this.setStorageCookieDomain = function(domain) {
this.cookie.domain = domain;
return this;
};
// Setter for notification config
@ -61,7 +57,6 @@ angularLocalStorage.provider('localStorageService', function() {
setItem: itemSet,
removeItem: itemRemove
};
return this;
};
this.$get = ['$rootScope', '$window', '$document', '$parse', function($rootScope, $window, $document, $parse) {
@ -264,16 +259,16 @@ angularLocalStorage.provider('localStorageService', function() {
};
// Checks the browser to see if cookies are supported
var browserSupportsCookies = (function() {
var browserSupportsCookies = function() {
try {
return $window.navigator.cookieEnabled ||
return 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 is local storage is not available in the browser
@ -286,7 +281,7 @@ angularLocalStorage.provider('localStorageService', function() {
value = toJson(value);
}
if (!browserSupportsCookies) {
if (!browserSupportsCookies()) {
$rootScope.$broadcast('LocalStorageModule.notification.error', 'COOKIES_NOT_SUPPORTED');
return false;
}
@ -322,7 +317,7 @@ angularLocalStorage.provider('localStorageService', function() {
// Directly get a value from a cookie
// Example use: localStorageService.cookie.get('library'); // returns 'angular'
var getFromCookies = function (key) {
if (!browserSupportsCookies) {
if (!browserSupportsCookies()) {
$rootScope.$broadcast('LocalStorageModule.notification.error', 'COOKIES_NOT_SUPPORTED');
return false;
}
@ -372,8 +367,11 @@ angularLocalStorage.provider('localStorageService', function() {
// 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) {
lsKey = lsKey || key;
var bindToScope = function(scope, scopeKey, def, lsKey) {
if (!lsKey) {
lsKey = scopeKey;
}
var value = getFromLocalStorage(lsKey);
if (value === null && isDefined(def)) {
@ -382,11 +380,11 @@ angularLocalStorage.provider('localStorageService', function() {
value = extend(def, value);
}
$parse(key).assign(scope, value);
$parse(scopeKey).assign(scope, value);
return scope.$watch(key, function(newVal) {
return scope.$watchCollection(scopeKey, function(newVal) {
addToLocalStorage(lsKey, newVal);
}, isObject(scope[key]));
});
};
// Return localStorageService.length
@ -406,7 +404,6 @@ angularLocalStorage.provider('localStorageService', function() {
isSupported: browserSupportsLocalStorage,
getStorageType: getStorageType,
set: addToLocalStorage,
put: addToLocalStorage,
add: addToLocalStorage, //DEPRECATED
get: getFromLocalStorage,
keys: getKeysForLocalStorage,
@ -416,7 +413,6 @@ angularLocalStorage.provider('localStorageService', function() {
deriveKey: deriveQualifiedKey,
length: lengthOfLocalStorage,
cookie: {
isSupported: browserSupportsCookies,
set: addToCookies,
add: addToCookies, //DEPRECATED
get: getFromCookies,

@ -22,27 +22,19 @@ module.exports = function(config) {
// - Safari (only Mac)
// - PhantomJS
// - IE (only Windows)
browsers: ['PhantomJS'],
browsers: ['Chrome'],
// list of files / patterns to load in the browser
files: [
bower + 'angular/angular.js',
bower + 'angular-mocks/angular-mocks.js',
'src/*.js',
'test/mock/*.js',
'test/spec/**/*.js'
],
// testing framework to use (jasmine/mocha/qunit/...)
frameworks: ['jasmine'],
// Which plugins to enable
plugins: [
'karma-phantomjs-launcher',
'karma-jasmine',
'karma-coverage'
],
// level of logging
// possible values: LOG_DISABLE || LOG_ERROR || LOG_WARN || LOG_INFO || LOG_DEBUG
logLevel: config.LOG_INFO,
@ -52,19 +44,6 @@ module.exports = function(config) {
// Continuous Integration mode
// if true, it capture browsers, run tests and exit
singleRun: true,
reporters: ['progress', 'coverage'],
// preprocessors
preprocessors: {
'src/*.js': ['coverage']
},
// configure the reporter
coverageReporter: {
type : 'lcov',
dir : 'coverage/'
}
singleRun: true
});
};

@ -1,42 +0,0 @@
'use strict';
//Mock localStorage
function localStorageMock() {
var storage = {};
Object.defineProperties(storage, {
setItem: {
value: function(key, value) {
storage[key] = value || '';
},
enumerable: false,
writable: true
},
getItem: {
value: function(key) {
return storage[key];
},
enumerable: false,
writable: true
},
removeItem: {
value: function(key) {
delete storage[key];
},
enumerable: false,
writable: true
},
length: {
get: function() {
return Object.keys(storage).length;
},
enumerable: false
},
key: {
value: function(i) {
var aKeys = Object.keys(storage);
return aKeys[i] || null;
},
enumerable: false
}
});
return storage;
}

@ -3,6 +3,30 @@
describe('localStorageService', function() {
var elmSpy;
//Mock
function localStorageMock() {
var keys = {};
return {
setItem: function(key, value) {
keys[key] = value || '';
},
getItem: function(key) {
return keys[key];
},
removeItem: function(key) {
delete keys[key];
},
get length() {
return Object.keys(keys).length;
},
key: function(i) {
var aKeys = Object.keys(keys);
return aKeys[i] || null;
}
};
}
//Actions
function getItem(key) {
return function($window, localStorageService) {
@ -18,14 +42,6 @@ describe('localStorageService', function() {
};
}
function addItemWithPut(key, value) {
return function($window, localStorageService) {
elmSpy = spyOn($window.localStorage, 'setItem').andCallThrough();
localStorageService.put(key, value);
};
}
function removeItem(key) {
return function($window, localStorageService) {
elmSpy = spyOn($window.localStorage, 'removeItem').andCallThrough();
@ -70,12 +86,6 @@ describe('localStorageService', function() {
};
}
function expectCookieSupporting(expected) {
return function(localStorageService) {
expect(localStorageService.cookie.isSupported).toEqual(expected);
};
}
function expectDomain(domain) {
return function($document, localStorageService) {
localStorageService.set('foo','bar'); //Should trigger first time
@ -145,17 +155,6 @@ describe('localStorageService', function() {
expectAdding('ls.foo', 'bar')
));
it('should add key to localeStorage null if value not provided', inject(
addItem('foo'),
expectAdding('ls.foo', null)
));
it('should add key to localStorage using put method', inject(
addItemWithPut('key', 777),
expectAdding('ls.key', angular.toJson(777)),
expectMatching('key', 777)
));
it('should support to set custom prefix', function() {
module(setPrefix('myApp'));
inject(
@ -164,19 +163,6 @@ describe('localStorageService', function() {
);
});
it('should be able to chain functions in the config phase', function() {
module(function(localStorageServiceProvider) {
localStorageServiceProvider
.setPrefix('chain')
.setNotify(false, true)
.setStorageType('session');
});
inject(function(localStorageService) {
expect(localStorageService.deriveKey('foo')).toEqual('chain.foo');
expect(localStorageService.getStorageType()).toEqual('session');
});
});
it('should be able to return the derive key', function() {
module(setPrefix('myApp'));
inject(function(localStorageService) {
@ -231,7 +217,7 @@ describe('localStorageService', function() {
addItem('key', '777'),
expectAdding('ls.key', angular.toJson('777')),
expectMatching('key', '777')
);
)
});
it('should be able to get items', inject(
@ -280,17 +266,6 @@ describe('localStorageService', function() {
});
});
it('should be able to notify/broadcasting if set', function() {
module(setNotify(true, true));
inject(function($rootScope, localStorageService) {
var spy = spyOn($rootScope, '$broadcast');
localStorageService.set('a8m', 'foobar');
localStorageService.remove('a8m', 'foobar');
expect(spy.callCount).toEqual(2);
});
});
it('should be able to bind to scope', inject(function($rootScope, localStorageService) {
localStorageService.set('property', 'oldValue');
@ -345,23 +320,6 @@ describe('localStorageService', function() {
expect($rootScope.property).toEqual(localStorageService.get('lsProperty'));
}));
it('should $watch with deep comparison only for objects', inject(function($rootScope, localStorageService) {
var mocks = [{}, [], 'string', 90, false];
var expectation = [true, true, false, false, false];
var results = [];
spyOn($rootScope, '$watch').andCallFake(function(key, func, eq) {
results.push(eq);
});
mocks.forEach(function(elm, i) {
localStorageService.set('mock' + i, elm);
localStorageService.bind($rootScope, 'mock' + i);
});
expect(results).toEqual(expectation);
}));
it('should be able to return it\'s owned keys amount', inject(
function(localStorageService, $window) {
@ -371,33 +329,6 @@ describe('localStorageService', function() {
}
expect(localStorageService.length()).toEqual(10);
expect($window.localStorage.length).toEqual(20);
}));
it('should be able to clear all owned keys from storage',inject(function($window, localStorageService) {
for(var i = 0; i < 10; i++) {
localStorageService.set('key' + i, 'val' + i);
$window.localStorage.setItem('key' + i, 'val' + i);
}
localStorageService.clearAll();
//remove only owned keys
for(var l = 0; l < 10; l++) {
expect(localStorageService.get('key' + l)).toEqual(null);
expect($window.localStorage.getItem('key' + l)).toEqual('val' + l);
}
}));
it('should return array of all owned keys', inject(function($window, localStorageService) {
//set keys
for(var i = 0; i < 10; i++) {
//localStorageService
localStorageService.set('ownKey' + i, 'val' + i);
//window.localStorage
$window.localStorage.setItem('windowKey' + i, 'val' + i);
}
localStorageService.keys().forEach(function(el, i) {
expect(el).toEqual('ownKey' + i);
});
}));
//sessionStorage
@ -450,10 +381,7 @@ describe('localStorageService', function() {
beforeEach(module('LocalStorageModule', function($provide) {
$provide.value('$window', {
localStorage: false,
sessionStorage: false,
navigator: {
cookieEnabled: true
}
sessionStorage: false
});
$provide.value('$document', {
cookie: ''
@ -464,10 +392,6 @@ describe('localStorageService', function() {
expectSupporting(false)
));
it('cookie.isSupported should be true if cookies are enabled', inject(
expectCookieSupporting(true)
));
it('fallback storage type should be cookie', inject(
expectStorageTyping('cookie')
));
@ -511,32 +435,6 @@ describe('localStorageService', function() {
expect(localStorageService.cookie.get('cookieKey')).toEqual(['foo', 'bar']);
}));
it('should be able to clear all owned keys from cookie', inject(function(localStorageService, $document) {
localStorageService.set('ownKey1', 1);
$document.cookie = 'username=John Doe';
localStorageService.clearAll();
expect(localStorageService.get('ownKey1')).toEqual(null);
expect($document.cookie).not.toEqual('');
}));
it('should be broadcast on adding item', function() {
module(setNotify(true, false));
inject(function($rootScope, localStorageService) {
var spy = spyOn($rootScope, '$broadcast');
localStorageService.set('a8m', 'foobar');
expect(spy).toHaveBeenCalled();
});
});
it('should be broadcast on removing item', function() {
module(setNotify(false, true));
inject(function($rootScope, localStorageService) {
var spy = spyOn($rootScope, '$broadcast');
localStorageService.remove('a8m', 'foobar');
expect(spy).toHaveBeenCalled();
});
});
Date.prototype.addDays = function(days) {
var date = new Date(this.getTime());
date.setDate(date.getDate() + days);
@ -544,22 +442,4 @@ describe('localStorageService', function() {
};
});
//cookie disabled
describe('No Cookie', function() {
beforeEach(module('LocalStorageModule', function($provide) {
$provide.value('$window', {
navigator: {
cookieEnabled: false
}
});
$provide.value('$document', {
});
}));
it('cookie.isSupported should be false if cookies are disabled', inject(
expectCookieSupporting(false)
));
});
});