Compare commits

...

139 Commits

Author SHA1 Message Date
Chakib Benziane
aaf4d75d44 Update README.md 2015-10-17 14:45:56 +02:00
Chakib Benziane
2bb247b9f7 Update README.md 2015-10-17 14:44:56 +02:00
Chakib Benziane
1b05f4ec63 update build 2015-01-22 12:37:05 +01:00
Chakib Benziane
85585772e0 Jshint fixes 2015-01-22 12:36:18 +01:00
Chakib Benziane
f08babe2b0 Fix tests 2015-01-22 12:33:15 +01:00
Chakib Benziane
15ad8a603e behave like cacheFactory, add put method 2015-01-22 12:20:56 +01:00
Ariel Mashraki
a07d51c3e7 docs(README.md): cookie.clearAll hash/title 2015-01-07 22:34:59 +02:00
Ariel Mashraki
99764b1dc8 docs(README.md): expand cookie.clearAll 2015-01-07 22:33:22 +02:00
Ariel Mashraki
4ca796cddc Merge pull request #182 from ilovemygameboy/patch-2
Update README.md
2015-01-06 18:34:27 +02:00
Ben Sinther
144e73c581 Update README.md
Parameter called val, but set function uses value. Same as #179.
2015-01-06 17:11:52 +01:00
Ariel Mashraki
afd4abc9fb fix(LICENSE): update copyright year 2015-01-01 00:51:48 +02:00
Ariel Mashraki
71e71fc3c0 fix(README.md): add \n just for aesthetic 2014-12-22 18:33:50 +02:00
Ariel Mashraki
83c8f8aabf Merge pull request #180 from eddiemonge/demo
docs(demo): better example and clearAll
2014-12-16 23:33:46 +02:00
Eddie Monge
0f4db7979b docs(demo): better example and clearAll
* Adds a clearAll button to clear the stored values
 * Does not wipe out the stored value on page load
 * Some web updates to the template
 * Use Github hosted version of plugin
 * Removes annotated code (ng-annotated or another tool should be used
 * to get rid of human error)

Fixes #87
2014-12-16 13:16:55 -08:00
Ariel Mashraki
950450f637 Merge pull request #179 from ilovemygameboy/patch-1
Update README.md
2014-12-16 18:46:43 +02:00
Ben Sinther
63def516a6 Update README.md
Submit parameter is called val. But inside cookie.set it is called value.
2014-12-16 17:18:51 +01:00
Ariel Mashraki
0f28dadbd8 fix(README.md): add badges 2014-12-09 11:00:39 +02:00
Ariel Mashraki
e31b3eab5c Merge pull request #174 from subodh-malgonde/master
Improved documentation for setStorageCookieDomain
2014-12-03 11:36:21 +02:00
Subodh
df71bac63c Improved documentation for
setStorageCookieDomain.
2014-12-03 14:38:17 +05:30
Ariel Mashraki
6fe6f93783 Merge pull request #169 from LFDM/patch-1
Fix a minor typo in a comment
2014-11-11 13:59:56 +02:00
Gernot Höflechner
1e14e3efa4 Fix a minor typo in a comment 2014-11-11 12:42:28 +01:00
Ariel Mashraki
3c5e2ec435 docs(REAMME.md): version 2014-11-04 23:04:02 +02:00
Ariel Mashraki
ae0c28aba9 build(*): v0.1.5 2014-11-04 23:02:36 +02:00
Ariel Mashraki
6ae576d82e test(localStorageProvider): issue #165 2014-11-04 23:00:57 +02:00
Ariel Mashraki
e88c4f5f5f fix(localStorageProvider): issue #165 2014-11-04 23:00:35 +02:00
Ariel Mashraki
1b4fd8d451 fix(karma): add phantomjs lancher and more 2014-11-04 22:48:47 +02:00
Ariel Mashraki
9066f619d9 Merge pull request #164 from ahelmel/feature/public-cookie-is-supported
Made the private function browserSupportsCookies public, see #163.
2014-10-30 22:03:26 +02:00
Arthur Helmel
a71d928d0e made the private function browserSupportsCookies public 2014-10-30 15:16:25 +01:00
Ariel Mashraki
5fc726c19c Merge pull request #160 from ahelmel/feature/cookie-is-supported
made the function browserSupportsCookies available for public access as cookie.isSupported
2014-10-30 12:53:02 +02:00
Arthur Helmel
8223e647c9 replaced navigator with the angularjs equivalent .navigator, made the function browserSupportsCookies available for public access as cookie.isSupported and wrote tests to verify the functionality 2014-10-30 11:38:00 +01:00
Ariel Mashraki
dbd1913d9a Merge pull request #155 from brianfeister/patch-1
Explain `setStorageCookieDomain` limitation
2014-10-23 22:15:22 +03:00
Brian Feister
8e9638dccf Explain setStorageCookieDomain limitation 2014-10-23 14:53:40 -04:00
Ariel Mashraki
d85bdb5b24 fix(README.md): add coverage badge 2014-10-17 16:26:24 +03:00
Ariel Mashraki
94be1481aa fix(travis): coveralls script 2014-10-17 16:17:15 +03:00
Ariel Mashraki
af9708d43b fix(travis): add coverage 2014-10-17 16:11:42 +03:00
Ariel Mashraki
1917e5748c feat(*): add coverage 2014-10-17 16:10:37 +03:00
Ariel Mashraki
2d4b402739 test(localStorageSpec): upgrade coverage, improve mocks 2014-10-17 16:09:59 +03:00
Ariel Mashraki
52d04ad7ce build(v0.1.3): bump version 0.1.3 2014-10-14 01:36:11 +03:00
Ariel Mashraki
d4e3f76c38 fix(README.md): bind example 2014-10-13 15:27:32 +03:00
Gregory Pike
9cf1e0729d Merge pull request #146 from hermantran/master
Fix main path in package.json
2014-10-13 01:16:20 -02:30
hermantran
cdf2dd07c3 Fix main path in package.json 2014-10-12 15:23:23 -07:00
Ariel Mashraki
6fdec3ed78 fix(README.md): \n 2014-10-12 01:54:52 +03:00
Ariel Mashraki
6a3c74b43a test(localStorageSpec): test .bind with deep comparison 2014-10-12 01:49:44 +03:00
Ariel Mashraki
a425b43caa feat(localStorageService): improve .bind func, issue #144 2014-10-12 01:48:46 +03:00
Gregory Pike
aef73ba676 Updated Readme Docs 2014-10-10 19:09:02 -02:30
Ariel Mashraki
3f3cd06bae Merge branch 'den-t-master' 2014-10-10 15:52:58 +03:00
Ariel Mashraki
45fd4c9d9d fix(README.md): unbind doc 2014-10-10 15:52:23 +03:00
Ariel Mashraki
6d763a76c8 fix(README.md): docs typo 2014-10-10 10:04:50 +03:00
Ariel Mashraki
bacadf1c0f fix(README.md): .bind doc 2014-10-10 10:00:13 +03:00
Ariel Mashraki
ed422c0476 Merge pull request #143 from andion/patch-1
Fixed typo on README's bind example
2014-10-09 19:24:12 +03:00
Lucas Andión Montáns
db87118a0c Fixed typo on bind example
Use $scope instead of $rootScope
2014-10-09 18:07:00 +02:00
Ariel Mashraki
6db17f5ed9 fix(README): cookies doc 2014-10-09 14:48:37 +03:00
Ariel Mashraki
fe26708204 fix(README): getting started doc + cookies doc 2014-10-09 14:47:53 +03:00
Ariel Mashraki
ae13ec45fd fix(README): getting started doc + cookies doc 2014-10-09 14:45:57 +03:00
Ariel Mashraki
5b9cd352ec fix(README): API localStorage doc 2014-10-09 14:26:28 +03:00
Ariel Mashraki
eeec036e9e Update README.md 2014-10-09 14:06:29 +03:00
Ariel Mashraki
a10a1a7a05 Update README.md 2014-10-09 14:06:07 +03:00
Ariel Mashraki
da357b763c fix(RAEDME.md): edit configuration 2014-10-09 13:28:54 +03:00
Ariel Mashraki
f95a2420c3 Update README.md 2014-10-09 12:59:20 +03:00
Ariel Mashraki
738e5cae75 Merge pull request #141 from KevinSalter/create-changelog
feat(CHANGELOG): start a CHANGELOG for this repo
2014-10-09 10:02:00 +03:00
Den Teresh
5948d2be36 Usage example for a .bind deregistration function 2014-10-09 15:21:35 +13:00
Den Teresh
887b682815 localStorageService.bind to return a deregistration function 2014-10-09 14:59:11 +13:00
Kevin Salter
cbf90c4af3 start a CHANGELOG for this repo 2014-10-07 14:01:21 -07:00
Ariel Mashraki
36926d8cf5 fix(README.md): docs typo 2014-10-07 01:24:26 +03:00
Ariel Mashraki
97c504e7e3 fix(README.md): expand readme 2014-10-07 01:23:41 +03:00
Ariel Mashraki
a8d48ff5c7 fix(dist): build for v0.1.1 2014-10-07 01:15:20 +03:00
Ariel Mashraki
6dcc4f1a58 fix(package): update npm version 2014-10-07 01:13:50 +03:00
Ariel Mashraki
b12cc0493d fix(bower): update bower version 2014-10-07 01:13:25 +03:00
Ariel Mashraki
d2bc39f2ba refa(src/*): refactor improve things 2014-10-07 01:12:16 +03:00
Ariel Mashraki
8a4bdc248b test(localStorageSpec): test cookie dealing with objects and arrays 2014-10-07 00:49:54 +03:00
Ariel Mashraki
7493cd88e0 fix(localStorageService): fix cookie serialization(object/array) issue: #121 2014-10-07 00:49:25 +03:00
Ariel Mashraki
44575f4028 test(localStorageSpec): test serialization numbers , issue #99 2014-10-07 00:25:09 +03:00
Ariel Mashraki
fd2fc272fa fix(localStorageService): serialization numbers , issue #99 2014-10-06 23:34:51 +03:00
Gregory Pike
4b25996bac Merge pull request #138 from a8m/master
refacor PR #132 - localStorage.length issue
2014-10-03 11:24:07 -02:30
Ariel Mashraki
82b59ed1b5 test(localStorageService): test localStorage.length + imprve mock 2014-10-03 13:40:50 +03:00
Ariel Mashraki
bf33743093 refa(localStorageService): revert and refactor PR: #132 2014-10-03 13:40:07 +03:00
Gregory Pike
74457d4782 Updated version 2014-10-03 07:50:04 -02:30
Gregory Pike
4304808d6d Merge pull request #135 from stenmuchow/bower-invalid-path
fixed main path to include dist folder
2014-10-03 07:37:15 -02:30
Sten Muchow
ff25b6d895 fixed main path to include dist folder 2014-10-03 10:09:52 +02:00
Gregory Pike
0afea0e801 Merge branch 'a8m-master' 2014-10-03 01:17:57 -02:30
Gregory Pike
58da1088d8 Get tests working 2014-10-03 01:16:48 -02:30
Gregory Pike
b5c681b6f6 Attempted to reorganize module while resolving conflicts 2014-10-03 00:56:48 -02:30
Gregory Pike
e01246e356 Merge pull request #132 from ecordoba24/master
Added localStorageService.length()
2014-10-03 00:50:03 -02:30
Gregory Pike
5616a668d1 Merge pull request #129 from webjunkie01/master
Fixed an issue with cookie based storage where values were not being parsed as objects.
2014-10-03 00:49:15 -02:30
Gregory Pike
7d86e3321c Merge pull request #124 from yihangho/binding
Improve binding
2014-10-03 00:45:57 -02:30
Eugenio Cordoba
0ec19f1153 Added localStorageService.length()
Added localStorageService.length()

Number of items stored in the localStorage according to the prefix
2014-09-10 15:00:41 -05:00
Gregory Pike
b4750937fd Merge pull request #126 from osama-lionheart/master
Added package.json to bower's ignore list.
2014-09-09 18:44:56 -02:30
Guillermo Cruz
7bbbb8899b Fixed an issue with cookie based storage where values were not being parsed as objects. 2014-09-08 14:30:50 -05:00
Osama Khalil
d2c25d1e1e Added package.json to bower's ignore list. 2014-08-30 15:45:13 +03:00
Gregory Pike
76eddc4cb8 Merge pull request #122 from FelixLC/master
Readme should read localStorageService.remove(Favorite Sport)
2014-08-24 17:40:16 -02:30
Yihang Ho
0ff995d63b Update README. 2014-08-23 22:02:39 +08:00
Yihang Ho
0b8d7820e9 Able to bind to scope using different keys. 2014-08-23 21:59:34 +08:00
Yihang Ho
84a9b404b6 Bind into property of objects. 2014-08-23 21:50:46 +08:00
FelixLC
65ecddfc76 Readme should read localStorageService.remove(Favorite Sport) instead of .delete (reserved javascript word) 2014-08-20 17:07:01 +02:00
Gregory Pike
296db308bc Merge pull request #119 from FeelgoodDE/master
Cleanuped code for enforced cookie usage
2014-08-15 15:49:21 -02:30
Ariel Mashraki
61463bd73f fix(bower,package): update version 2014-08-15 20:06:45 +03:00
Ariel Mashraki
b1b426698a fix(dist): build for version v0.0.8 2014-08-15 20:05:57 +03:00
Ariel Mashraki
ea2065e51c refactor(angular-local-storage): removes wrap closure to concat task 2014-08-15 19:55:47 +03:00
Ariel Mashraki
50fb50d58c fix(demo.demo.html): update module path 2014-08-15 19:54:02 +03:00
Ariel Mashraki
38a769ea88 fix(karma.conf.js): update file src 2014-08-15 19:52:42 +03:00
Ariel Mashraki
0c86054aba feat(gruntfile): robust gruntfile 2014-08-15 19:49:49 +03:00
Ariel Mashraki
e692f70bc2 fix(package): add grunt-concat 2014-08-15 19:48:04 +03:00
Ariel Mashraki
24b6f4d1d6 refactor(src): create and remove src files to src dir 2014-08-15 19:46:09 +03:00
Sebastian Gronewold
f7753704c2 Cleanuped code for enforced cookie usage
In my last pull request I added the first support for handling of the enforced usage of cookies as storage. Now I added this support to the remove function and to the clearAll function. Also I exluded warnings that the browser does not support local storage if the user explicitely wants to use cookies.
2014-08-14 18:28:35 +02:00
Sebastian Gronewold
0b8be0935a Added PHPStorm project files to .gitignore 2014-08-14 18:23:21 +02:00
Gregory Pike
64d5beded5 Merge pull request #118 from a8m/master
fix CI build falling, and broken tests
2014-08-14 11:48:12 -02:30
Ariel Mashraki
642f1fe7fc fix(dist): uglify angular-local-storage 2014-08-14 09:02:09 +03:00
Ariel Mashraki
f05c83cd74 fix(package): update version to 0.0.7 2014-08-14 08:56:41 +03:00
Ariel Mashraki
ee19f3dac6 fix(bower): update version to 0.0.7 2014-08-14 08:56:10 +03:00
Ariel Mashraki
9e3537bfd5 fix(localStorageService): fix usage of 'this' keyword on closures 2014-08-14 08:55:24 +03:00
Gregory Pike
b29b89676d Merge pull request #117 from a8m/master
Create unit test, helpers and mocking. Issue #114
2014-08-14 02:23:01 -02:30
Gregory Pike
71747d4a5d Merge pull request #112 from kanerogers/patch-1
Add installation instructions to README.md
2014-08-14 01:03:15 -02:30
Kane Rogers
1252851e56 angular-loading-bar != angular-local-storage
Whoops!
2014-08-14 11:52:51 +10:00
Gregory Pike
a811978ce5 Updated version 2014-08-13 23:14:39 -02:30
Gregory Pike
e06726f0e4 Updated version 2014-08-13 23:14:07 -02:30
Gregory Pike
f7dd45e8e6 Merge pull request #116 from FeelgoodDE/master
Handling for explicit usage of cookie fallback
2014-08-13 23:09:54 -02:30
Gregory Pike
1437e35e58 Merge pull request #113 from kanerogers/patch-2
Add delete example to README.md
2014-08-13 23:07:41 -02:30
Gregory Pike
a42db53a7c Merge pull request #106 from rdepena/patch-1
removed references to deprecated add functions.
2014-08-13 23:04:15 -02:30
Gregory Pike
0a256f307b Merge pull request #105 from egyptianbman/patch-1
Check for document being in [0] key of $document
2014-08-13 23:03:39 -02:30
Gregory Pike
2c57fdf15e Merge pull request #103 from darrylhebbes/patch-1
Update README.md
2014-08-13 23:02:40 -02:30
Ariel Mashraki
60b3e5df94 test(localStorageService): create unit test, mocking and helpers 2014-08-13 09:39:35 +03:00
Ariel Mashraki
c66a761b3b refactor(test): remove old file test 2014-08-13 09:38:41 +03:00
Ariel Mashraki
0d94b97503 fix(karma.conf): remove unnecessary comma 2014-08-12 14:25:48 +03:00
Ariel Mashraki
18a02e5c6e test(locationStorage): create unit test file 2014-08-12 14:24:31 +03:00
Sebastian Gronewold
570d7657c4 Reverted changes... 2014-08-12 10:37:12 +00:00
Sebastian Gronewold
bbf57b78a7 Merge branch 'master' of https://github.com/FeelgoodDE/angular-local-storage 2014-08-12 10:36:50 +00:00
Sebastian Gronewold
e7c465c898 Handling for explicit usage of cookie fallback
If the user explicitely set the storage type to cookie also the
getFromLlocalStorage and addToLocalStorage method should use the cookie
fallback.
2014-08-12 10:34:35 +00:00
Sebastian Gronewold
7ef86fb4a5 Reverted changes as they have already been pull requested 2014-08-12 10:33:41 +00:00
Sebastian Gronewold
330fc3f28b Added unwrapping of the jquery encapsulated $document variable
See
http://www.bennadel.com/blog/2630-accessing-document-properties-in-angularjs.htm
2014-08-12 10:15:02 +00:00
Kane Rogers
9d050c9ebe Add delete example to README.md 2014-08-01 11:55:58 +10:00
Kane Rogers
f3ef129b28 Add installation instructions to README.md
Now I know how to install it! 😄
2014-08-01 11:51:30 +10:00
Ricardo de Peña
b1ea75c8c7 removed references to deprecated add functions.
demo documentation still refers to deprecated add functions.
2014-07-01 11:41:43 -04:00
Beshoy Girgis
7ac1e52905 Check for document being in [0] key of $document
I have a factory that calls localStorageService.cookie.clearAll() which throws an error of `TypeError: Cannot read property 'split' of undefined`.  It turns out that this error is caused by $document having document be in `$document[0]`.  The proposed update solves my issue; thanks!
2014-06-30 16:32:30 -05:00
Darryl Hebbes
12c8104c5b Update README.md
Added an example of binding to a $scope variable
2014-06-05 18:34:15 +02:00
Gregory Pike
d08649f426 Repositioned ads to make them less intrusive 2014-05-22 20:15:16 -04:00
Gregory Pike
3b2bc3a0de Added ads to the demo
Sorry guys, I need to earn a living
2014-05-22 20:04:10 -04:00
Gregory Pike
15d1fb454d Updated version 2014-05-21 02:40:47 -04:00
Gregory Pike
4389885e15 Updated dependencies 2014-05-21 01:02:42 -04:00
Gregory Pike
8cfff25b19 Uglify and update the version number 2014-05-13 00:42:20 -04:00
19 changed files with 1691 additions and 224 deletions

2
.gitignore vendored
View File

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

View File

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

8
CHANGELOG.md Normal file
View File

@ -0,0 +1,8 @@
<a name="0.1.1"></a>
# 0.1.1 (2014-10-06)
## Breaking Changes
- update your `index.html` file to reference angular-local-storage at its new
path inside the `dist` directory `/angular-local-storage/dist/angular-local-storage.js`

View File

@ -8,15 +8,45 @@ module.exports = function(grunt) {
require('time-grunt')(grunt);
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
meta: {
banner: [
'/**',
' * <%= pkg.description %>',
' * @version v<%= pkg.version %> - <%= grunt.template.today("yyyy-mm-dd") %>',
' * @link <%= pkg.homepage %>',
' * @author <%= pkg.author %>',
' * @license MIT License, http://www.opensource.org/licenses/MIT',
' */'
].join('\n')
},
dirs: {
dest: 'dist'
},
concat: {
options: {
banner: '<%= meta.banner %>' + '\n' +
'(function ( window, angular, undefined ) {' + '\n',
footer: '})( window, window.angular );'
},
dist: {
src: ['src/common.js', 'src/angular-local-storage.js'],
dest: '<%= dirs.dest %>/<%= pkg.name %>.js'
}
},
uglify: {
options: {
banner: '<%= meta.banner %>'
},
dist: {
src: ['<%= concat.dist.dest %>'],
dest: '<%= dirs.dest %>/<%= pkg.name %>.min.js'
}
},
karma: {
options: {
autowatch: true,
browsers: [
'PhantomJS'
],
configFile: 'test/karma.conf.js',
reporters: ['dots'],
singleRun: true
configFile: 'test/karma.conf.js'
},
unit: {}
},
@ -37,13 +67,6 @@ module.exports = function(grunt) {
jshintrc: 'test/.jshintrc',
}
}
},
uglify: {
dist: {
files: {
'angular-local-storage.min.js': 'angular-local-storage.js'
}
}
}
});
@ -57,6 +80,7 @@ module.exports = function(grunt) {
]);
grunt.registerTask('dist', [
'concat',
'uglify'
]);
};

View File

@ -1,5 +1,5 @@
Angular Local Storage
Copyright 2013 Gregory Pike
Copyright 2015 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:

395
README.md
View File

@ -1,35 +1,378 @@
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
An Angular module that gives you access to the browsers local storage, **v0.1.5**
[![Build Status](https://secure.travis-ci.org/grevory/angular-local-storage.png?branch=master)](https://travis-ci.org/grevory/)
[![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]
Example use:
##Table of contents:
- [Get Started](#get-started)
- [Development](#development)
- [Configuration](#configuration)
- [setPrefix](#setprefix)
- [setStorageType](#setstoragetype)
- [setStorageCookie](#setstoragecookie)
- [setStorageCookieDomain](#setstoragecookiedomain)
- [setNotify](#setnotify)
- [Example](#configuration-example)
- [API Documentation](#api-documentation)
- [isSupported](#issupported)
- [getStorageType](#getstoragetype)
- [set](#set)
- [get](#get)
- [keys](#keys)
- [remove](#remove)
- [clearAll](#clearall)
- [bind](#bind)
- [deriveKey](#derivekey)
- [length](#length)
- [cookie](#cookie)
- [isSupported](#cookieissupported)
- [set](#cookieset)
- [get](#cookieget)
- [remove](#cookieremove)
- [clearAll](#cookieclearall)
```javascript
angular.module('yourModule', ['LocalStorageModule'])
.controller('yourCtrl', [
'$scope',
'localStorageService',
function($scope, localStorageService) {
// Start fresh
localStorageService.clearAll();
localStorageService.set('Favorite Sport','Ultimate Frisbee');
}]);
/*
To set the prefix of your localStorage name, you can use the setPrefix method
available on the localStorageServiceProvider
*/
angular.module('yourModule', ['LocalStorageModule'])
.config(['localStorageServiceProvider', function(localStorageServiceProvider){
localStorageServiceProvider.setPrefix('newPrefix');
}]);
##Get Started
**(1)** You can install angular-local-storage using 2 different ways:<br/>
**Git:**
clone & build [this](https://github.com/grevory/angular-local-storage.git) repository<br/>
**Bower:**
```bash
$ bower install angular-local-storage
```
Check out the full demo and documentation at http://gregpike.net/demos/angular-local-storage/demo.html
**npm:**
```bash
$ npm install angular-local-storage
```
**(2)** Include `angular-local-storage.js` (or `angular-local-storage.min.js`) in your `index.html`, after including Angular itself.
To do:
- Add tests
- Expand Readme
**(3)** Add `'LocalStorageModule'` to your main module's list of dependencies.
When you're done, your setup should look similar to the following:
```html
<!doctype html>
<html ng-app="myApp">
<head>
</head>
<body>
...
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.1.5/angular.min.js"></script>
<script src="bower_components/js/angular-local-storage.min.js"></script>
...
<script>
var myApp = angular.module('myApp', ['LocalStorageModule']);
</script>
...
</body>
</html>
```
##Configuration
###setPrefix
You could set a prefix to avoid overwriting any local storage variables from the rest of your app<br/>
**Default prefix:** `ls.<your-key>`
```js
myApp.config(function (localStorageServiceProvider) {
localStorageServiceProvider
.setPrefix('yourAppName');
});
```
###setStorageType
You could change web storage type to localStorage or sessionStorage<br/>
**Default storage:** `localStorage`
```js
myApp.config(function (localStorageServiceProvider) {
localStorageServiceProvider
.setStorageType('sessionStorage');
});
```
###setStorageCookie
Set cookie options (usually in case of fallback)<br/>
**expiry:** number of days before cookies expire (0 = does not expire). **default:** `30`<br/>
**path:** the web path the cookie represents. **default:** `'/'`
```js
myApp.config(function (localStorageServiceProvider) {
localStorageServiceProvider
.setStorageCookie(45, '<path>');
});
```
###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/>
**No default value**
```js
myApp.config(function (localStorageServiceProvider) {
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/>
**removeItem** , default: `false`
```js
myApp.config(function (localStorageServiceProvider) {
localStorageServiceProvider
.setNotify(true, true);
});
```
###Configuration Example
Using all together
```js
myApp.config(function (localStorageServiceProvider) {
localStorageServiceProvider
.setPrefix('myApp')
.setStorageType('sessionStorage')
.setNotify(true, true)
});
```
##API Documentation
##isSupported
Checks if the browser support the current storage type(e.g: `localStorage`, `sessionStorage`).
**Returns:** `Boolean`
```js
myApp.controller('MainCtrl', function($scope, localStorageService) {
//...
if(localStorageService.isSupported) {
//...
}
//...
});
```
###getStorageType
**Returns:** `String`
```js
myApp.controller('MainCtrl', function($scope, localStorageService) {
//...
var storageType = localStorageService.getStorageType(); //e.g localStorage
//...
});
```
###set
Directly adds a value to local storage.<br/>
If local storage is not supported, use cookies instead.<br/>
**Returns:** `Boolean`
```js
myApp.controller('MainCtrl', function($scope, localStorageService) {
//...
function submit(key, val) {
return localStorageService.set(key, val);
}
//...
});
```
###get
Directly get a value from local storage.<br/>
If local storage is not supported, use cookies instead.<br/>
**Returns:** `value from local storage`
```js
myApp.controller('MainCtrl', function($scope, localStorageService) {
//...
function getItem(key) {
return localStorageService.get(key);
}
//...
});
```
###keys
Return array of keys for local storage, ignore keys that not owned.<br/>
**Returns:** `value from local storage`
```js
myApp.controller('MainCtrl', function($scope, localStorageService) {
//...
var lsKeys = localStorageService.keys();
//...
});
```
###remove
Remove an item from local storage by key.<br/>
If local storage is not supported, use cookies instead.<br/>
**Returns:** `Boolean`
```js
myApp.controller('MainCtrl', function($scope, localStorageService) {
//...
function removeItem(key) {
return localStorageService.remove(key);
}
//...
});
```
###clearAll
Remove all data for this app from local storage.<br/>
If local storage is not supported, use cookies instead.<br/>
**Note:** Optionally takes a regular expression string and removes matching.<br/>
**Returns:** `Boolean`
```js
myApp.controller('MainCtrl', function($scope, localStorageService) {
//...
function clearNumbers(key) {
return localStorageService.clearAll(/^\d+$/);
}
//...
function clearAll() {
return localStorageService.clearAll();
}
});
```
###bind
Bind $scope key to localStorageService.
**Usage:** `localStorageService.bind(scope, property, value[optional], key[optional])`
***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');
//Test Changes
$scope.update = function(val) {
$scope.property = val;
$timeout(function() {
alert("localStorage value: " + localStorageService.get('property'));
});
}
//...
});
```
```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
**Returns** `String`
```js
myApp.controller('MainCtrl', function($scope, localStorageService) {
//...
localStorageService.set('property', 'oldValue');
//Test Result
console.log(localStorageService.deriveKey('property')); // ls.property
//...
});
```
###length
Return localStorageService.length, ignore keys that not owned.
**Returns** `Number`
```js
myApp.controller('MainCtrl', function($scope, localStorageService) {
//...
var lsLength = localStorageService.length(); // e.g: 7
//...
});
```
##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/>
**Returns:** `Boolean`
```js
myApp.controller('MainCtrl', function($scope, localStorageService) {
//...
function submit(key, val) {
return localStorageService.cookie.set(key, val);
}
//...
});
```
###cookie.get
Directly get a value from a cookie.<br/>
**Returns:** `value from local storage`
```js
myApp.controller('MainCtrl', function($scope, localStorageService) {
//...
function getItem(key) {
return localStorageService.cookie.get(key);
}
//...
});
```
###cookie.remove
Remove directly value from a cookie.<br/>
**Returns:** `Boolean`
```js
myApp.controller('MainCtrl', function($scope, localStorageService) {
//...
function removeItem(key) {
return localStorageService.cookie.remove(key);
}
//...
});
```
###cookie.clearAll
Remove all data for this app from cookie.<br/>
**Returns:** `Boolean`
```js
myApp.controller('MainCtrl', function($scope, localStorageService) {
//...
function clearAll() {
return localStorageService.cookie.clearAll();
}
});
```
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
$ git clone https://github.com/<your-repo>/angular-local-storage.git
$ npm install
$ bower install
```
Run the tests:
```sh
$ grunt test
```
**Deploy:**<br/>
Run the build task, update version before(bower,package)
```sh
$ 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

View File

@ -1 +0,0 @@
(function(){"use strict";var a=angular.module("LocalStorageModule",[]);a.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",function(a,b,c){var d=this.prefix,e=this.cookie,f=this.notify,g=this.storageType,h=b[g];c||(c=document),"."!==d.substr(-1)&&(d=d?d+".":"");var i=function(){try{var c=g in b&&null!==b[g],e=d+"__"+Math.round(1e7*Math.random());return c&&(h.setItem(e,""),h.removeItem(e)),c}catch(f){return g="cookie",a.$broadcast("LocalStorageModule.notification.error",f.message),!1}}(),j=function(b,c){if(!i)return a.$broadcast("LocalStorageModule.notification.warning","LOCAL_STORAGE_NOT_SUPPORTED"),f.setItem&&a.$broadcast("LocalStorageModule.notification.setitem",{key:b,newvalue:c,storageType:"cookie"}),p(b,c);"undefined"==typeof c&&(c=null);try{(angular.isObject(c)||angular.isArray(c))&&(c=angular.toJson(c)),h.setItem(d+b,c),f.setItem&&a.$broadcast("LocalStorageModule.notification.setitem",{key:b,newvalue:c,storageType:this.storageType})}catch(e){return a.$broadcast("LocalStorageModule.notification.error",e.message),p(b,c)}return!0},k=function(b){if(!i)return a.$broadcast("LocalStorageModule.notification.warning","LOCAL_STORAGE_NOT_SUPPORTED"),q(b);var c=h.getItem(d+b);return c&&"null"!==c?"{"===c.charAt(0)||"["===c.charAt(0)?angular.fromJson(c):c:null},l=function(b){if(!i)return a.$broadcast("LocalStorageModule.notification.warning","LOCAL_STORAGE_NOT_SUPPORTED"),f.removeItem&&a.$broadcast("LocalStorageModule.notification.removeitem",{key:b,storageType:"cookie"}),r(b);try{h.removeItem(d+b),f.removeItem&&a.$broadcast("LocalStorageModule.notification.removeitem",{key:b,storageType:this.storageType})}catch(c){return a.$broadcast("LocalStorageModule.notification.error",c.message),r(b)}return!0},m=function(){if(!i)return a.$broadcast("LocalStorageModule.notification.warning","LOCAL_STORAGE_NOT_SUPPORTED"),!1;var b=d.length,c=[];for(var e in h)if(e.substr(0,b)===d)try{c.push(e.substr(b))}catch(f){return a.$broadcast("LocalStorageModule.notification.error",f.Description),[]}return c},n=function(b){b=b||"";var c=d.slice(0,-1),e=new RegExp(c+"."+b);if(!i)return a.$broadcast("LocalStorageModule.notification.warning","LOCAL_STORAGE_NOT_SUPPORTED"),s();var f=d.length;for(var g in h)if(e.test(g))try{l(g.substr(f))}catch(j){return a.$broadcast("LocalStorageModule.notification.error",j.message),s()}return!0},o=function(){try{return navigator.cookieEnabled||"cookie"in c&&(c.cookie.length>0||(c.cookie="test").indexOf.call(c.cookie,"test")>-1)}catch(b){return a.$broadcast("LocalStorageModule.notification.error",b.message),!1}},p=function(b,f){if("undefined"==typeof f)return!1;if(!o())return a.$broadcast("LocalStorageModule.notification.error","COOKIES_NOT_SUPPORTED"),!1;try{var g="",h=new Date,i="";if(null===f?(h.setTime(h.getTime()+-864e5),g="; expires="+h.toGMTString(),f=""):0!==e.expiry&&(h.setTime(h.getTime()+24*e.expiry*60*60*1e3),g="; expires="+h.toGMTString()),b){var j="; path="+e.path;e.domain&&(i="; domain="+e.domain),c.cookie=d+b+"="+encodeURIComponent(f)+g+j+i}}catch(k){return a.$broadcast("LocalStorageModule.notification.error",k.message),!1}return!0},q=function(b){if(!o())return a.$broadcast("LocalStorageModule.notification.error","COOKIES_NOT_SUPPORTED"),!1;for(var e=c.cookie&&c.cookie.split(";")||[],f=0;f<e.length;f++){for(var g=e[f];" "===g.charAt(0);)g=g.substring(1,g.length);if(0===g.indexOf(d+b+"="))return decodeURIComponent(g.substring(d.length+b.length+1,g.length))}return null},r=function(a){p(a,null)},s=function(){for(var a=null,b=d.length,e=c.cookie.split(";"),f=0;f<e.length;f++){for(a=e[f];" "===a.charAt(0);)a=a.substring(1,a.length);var g=a.substring(b,a.indexOf("="));r(g)}},t=function(){return g},u=function(a,b,c){var d=k(b);null===d&&angular.isDefined(c)?d=c:angular.isObject(d)&&angular.isObject(c)&&(d=angular.extend(c,d)),a[b]=d,a.$watchCollection(b,function(a){j(b,a)})};return{isSupported:i,getStorageType:t,set:j,add:j,get:k,keys:m,remove:l,clearAll:n,bind:u,cookie:{set:p,add:p,get:q,remove:r,clearAll:s}}}]})}).call(this);

View File

@ -1,23 +1,28 @@
{
"name": "angular-local-storage",
"version": "0.0.3",
"version": "0.1.5",
"homepage": "http://gregpike.net/demos/angular-local-storage/demo.html",
"authors": [
"grevory <greg@gregpike.ca>"
],
"description": "An Angular module that gives you access to the browser's local storage",
"main": "angular-local-storage.js",
"main": "./dist/angular-local-storage.js",
"keywords": [
"AngularJS",
"Local Storage"
"Angular",
"Storage",
"Local Storage",
"Session",
"Cookie"
],
"license": "MIT",
"ignore": [
"**/.*",
"src",
"node_modules",
"bower_components",
"test",
"tests"
"tests",
"Gruntfile.js"
],
"devDependencies": {
"angularjs": "*",

View File

@ -1,13 +1,13 @@
angular.module('demoModule', ['LocalStorageModule'])
.config(['localStorageServiceProvider', function(localStorageServiceProvider){
'use strict';
window.angular.module('demoModule', ['LocalStorageModule'])
.config(function(localStorageServiceProvider){
localStorageServiceProvider.setPrefix('demoPrefix');
// localStorageServiceProvider.setStorageCookieDomain('example.com');
// localStorageServiceProvider.setStorageType('sessionStorage');
}])
.controller('DemoCtrl', [
'$scope',
'localStorageService',
})
.controller('DemoCtrl',
function($scope, localStorageService) {
$scope.localStorageDemo = localStorageService.get('localStorageDemo');
$scope.$watch('localStorageDemo', function(value){
localStorageService.set('localStorageDemo',value);
@ -23,5 +23,13 @@ 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;
}
]);
);

View File

@ -1,13 +1,12 @@
<!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">
@ -37,9 +36,11 @@
<p><input type="text" ng-model="localStorageDemo" placeholder="Start typing..."></p>
<blockquote class="well" ng-show="localStorageDemoValue">
<p>{{localStorageDemoValue}}</p>
<p ng-bind="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>
@ -56,10 +57,23 @@
<h3>Usage</h3>
<!-- Sorry guys, I need to earn a living -->
<div style="float: right">
<script async src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>
<!-- ALS Leaderboard -->
<ins class="adsbygoogle"
style="display:inline-block;width:728px;height:90px"
data-ad-client="ca-pub-8242772837340688"
data-ad-slot="1586567981"></ins>
<script>
(adsbygoogle = window.adsbygoogle || []).push({});
</script>
</div>
<h6>Dependencies:</h6>
<ul>
<li><code>AngularJS</code> <small><a href="http://angularjs.org/">http://angularjs.org/</a></small></li>
<li><code>Angular Local Storage Module</code> <small><a href="../angular-local-storage.js">angular-local-storage.js</a></small></li>
<li><code>Angular Local Storage Module</code> <small><a href="../src/angular-local-storage.js">angular-local-storage.js</a></small></li>
</ul>
<h6>JS Example</h6>
@ -74,7 +88,7 @@ var YourCtrl = function($scope, localStorageService, ...) {
// Removes all local storage
localStorageService.clearAll();
// You can also play with cookies the same way
localStorageService.cookie.add('localStorageKey','I am a cookie value now');
localStorageService.cookie.set('localStorageKey','I am a cookie value now');
}</pre>
<h3>API Access</h3>
@ -96,7 +110,7 @@ var YourCtrl = function($scope, localStorageService, ...) {
<td>Boolean for success</td>
</tr>
<tr>
<td><code>add</code></td>
<td><code>set</code></td>
<td><small>key, value</small></td>
<td>Adds a key-value pair to the browser local storage</td>
<td>Boolean for success</td>
@ -121,7 +135,7 @@ var YourCtrl = function($scope, localStorageService, ...) {
</tr>
<tr>
<td><code>cookie</code></td>
<td><small>add | get | remove | clearAll</small></td>
<td><small>set | get | remove | clearAll</small></td>
<td>Each function within cookie uses the same arguments as the coresponding local storage functions</td>
<td>n/a</td>
</tr>
@ -135,7 +149,7 @@ var YourCtrl = function($scope, localStorageService, ...) {
<!-- 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="../angular-local-storage.min.js"></script>
<script src="https://rawgit.com/grevory/angular-local-storage/master/dist/angular-local-storage.min.js"></script>
<script src="demo-app.js"></script>
</body>
</html>

456
dist/angular-local-storage.js vendored Normal file
View File

@ -0,0 +1,456 @@
/**
* An Angular module that gives you access to the browsers local storage
* @version v0.1.5 - 2015-01-22
* @link https://github.com/grevory/angular-local-storage
* @author grevory <greg@gregpike.ca>
* @license MIT License, http://www.opensource.org/licenses/MIT
*/
(function ( window, angular, undefined ) {
/*jshint globalstrict:true*/
'use strict';
var isDefined = angular.isDefined,
isUndefined = angular.isUndefined,
isNumber = angular.isNumber,
isObject = angular.isObject,
isArray = angular.isArray,
extend = angular.extend,
toJson = angular.toJson,
fromJson = angular.fromJson;
// Test if string is only contains numbers
// e.g '1' => true, "'1'" => true
function isStringNumber(num) {
return /^-?\d+\.?\d*$/.test(num.replace(/["']/g, ''));
}
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');
// With provider you can use config as this:
// myApp.config(function (localStorageServiceProvider) {
// localStorageServiceProvider.prefix = 'yourAppName';
// });
this.prefix = 'ls';
// You could change web storage type localstorage or sessionStorage
this.storageType = 'localStorage';
// Cookie options (usually in case of fallback)
// expiry = Number of days before cookies expire // 0 = Does not expire
// path = The web path the cookie represents
this.cookie = {
expiry: 30,
path: '/'
};
// Send signals for each of the following actions?
this.notify = {
setItem: true,
removeItem: false
};
// Setter for the prefix
this.setPrefix = function(prefix) {
this.prefix = prefix;
return this;
};
// Setter for the storageType
this.setStorageType = function(storageType) {
this.storageType = storageType;
return this;
};
// Setter for cookie config
this.setStorageCookie = function(exp, path) {
this.cookie = {
expiry: exp,
path: path
};
return this;
};
// Setter for cookie domain
this.setStorageCookieDomain = function(domain) {
this.cookie.domain = domain;
return this;
};
// Setter for notification config
// itemSet & itemRemove should be booleans
this.setNotify = function(itemSet, itemRemove) {
this.notify = {
setItem: itemSet,
removeItem: itemRemove
};
return this;
};
this.$get = ['$rootScope', '$window', '$document', '$parse', function($rootScope, $window, $document, $parse) {
var self = this;
var prefix = self.prefix;
var cookie = self.cookie;
var notify = self.notify;
var storageType = self.storageType;
var webStorage;
// When Angular's $document is not available
if (!$document) {
$document = document;
} else if ($document[0]) {
$document = $document[0];
}
// If there is a prefix set in the config lets use that with an appended period for readability
if (prefix.substr(-1) !== '.') {
prefix = !!prefix ? prefix + '.' : '';
}
var deriveQualifiedKey = function(key) {
return prefix + key;
};
// Checks the browser to see if local storage is supported
var browserSupportsLocalStorage = (function () {
try {
var supported = (storageType in $window && $window[storageType] !== null);
// When Safari (OS X or iOS) is in private browsing mode, it appears as though localStorage
// is available, but trying to call .setItem throws an exception.
//
// "QUOTA_EXCEEDED_ERR: DOM Exception 22: An attempt was made to add something to storage
// that exceeded the quota."
var key = deriveQualifiedKey('__' + Math.round(Math.random() * 1e7));
if (supported) {
webStorage = $window[storageType];
webStorage.setItem(key, '');
webStorage.removeItem(key);
}
return supported;
} catch (e) {
storageType = 'cookie';
$rootScope.$broadcast('LocalStorageModule.notification.error', e.message);
return false;
}
}());
// Directly adds a value to local storage
// If local storage is not available in the browser use cookies
// Example use: localStorageService.add('library','angular');
var addToLocalStorage = function (key, value) {
// Let's convert undefined values to null to get the value consistent
if (isUndefined(value)) {
value = null;
} else if (isObject(value) || isArray(value) || isNumber(+value || value)) {
value = toJson(value);
}
// If this browser does not support local storage use cookies
if (!browserSupportsLocalStorage || self.storageType === 'cookie') {
if (!browserSupportsLocalStorage) {
$rootScope.$broadcast('LocalStorageModule.notification.warning', 'LOCAL_STORAGE_NOT_SUPPORTED');
}
if (notify.setItem) {
$rootScope.$broadcast('LocalStorageModule.notification.setitem', {key: key, newvalue: value, storageType: 'cookie'});
}
return addToCookies(key, value);
}
try {
if (isObject(value) || isArray(value)) {
value = toJson(value);
}
if (webStorage) {webStorage.setItem(deriveQualifiedKey(key), value)};
if (notify.setItem) {
$rootScope.$broadcast('LocalStorageModule.notification.setitem', {key: key, newvalue: value, storageType: self.storageType});
}
} catch (e) {
$rootScope.$broadcast('LocalStorageModule.notification.error', e.message);
return addToCookies(key, value);
}
return true;
};
// Directly get a value from local storage
// Example use: localStorageService.get('library'); // returns 'angular'
var getFromLocalStorage = function (key) {
if (!browserSupportsLocalStorage || self.storageType === 'cookie') {
if (!browserSupportsLocalStorage) {
$rootScope.$broadcast('LocalStorageModule.notification.warning','LOCAL_STORAGE_NOT_SUPPORTED');
}
return getFromCookies(key);
}
var item = webStorage ? webStorage.getItem(deriveQualifiedKey(key)) : null;
// angular.toJson will convert null to 'null', so a proper conversion is needed
// FIXME not a perfect solution, since a valid 'null' string can't be stored
if (!item || item === 'null') {
return null;
}
if (item.charAt(0) === "{" || item.charAt(0) === "[" || isStringNumber(item)) {
return fromJson(item);
}
return item;
};
// Remove an item from local storage
// Example use: localStorageService.remove('library'); // removes the key/value pair of library='angular'
var removeFromLocalStorage = function (key) {
if (!browserSupportsLocalStorage || self.storageType === 'cookie') {
if (!browserSupportsLocalStorage) {
$rootScope.$broadcast('LocalStorageModule.notification.warning', 'LOCAL_STORAGE_NOT_SUPPORTED');
}
if (notify.removeItem) {
$rootScope.$broadcast('LocalStorageModule.notification.removeitem', {key: key, storageType: 'cookie'});
}
return removeFromCookies(key);
}
try {
webStorage.removeItem(deriveQualifiedKey(key));
if (notify.removeItem) {
$rootScope.$broadcast('LocalStorageModule.notification.removeitem', {key: key, storageType: self.storageType});
}
} catch (e) {
$rootScope.$broadcast('LocalStorageModule.notification.error', e.message);
return removeFromCookies(key);
}
return true;
};
// Return array of keys for local storage
// Example use: var keys = localStorageService.keys()
var getKeysForLocalStorage = function () {
if (!browserSupportsLocalStorage) {
$rootScope.$broadcast('LocalStorageModule.notification.warning', 'LOCAL_STORAGE_NOT_SUPPORTED');
return false;
}
var prefixLength = prefix.length;
var keys = [];
for (var key in webStorage) {
// Only return keys that are for this app
if (key.substr(0,prefixLength) === prefix) {
try {
keys.push(key.substr(prefixLength));
} catch (e) {
$rootScope.$broadcast('LocalStorageModule.notification.error', e.Description);
return [];
}
}
}
return keys;
};
// Remove all data for this app from local storage
// Also optionally takes a regular expression string and removes the matching key-value pairs
// Example use: localStorageService.clearAll();
// Should be used mostly for development purposes
var clearAllFromLocalStorage = function (regularExpression) {
regularExpression = regularExpression || "";
//accounting for the '.' in the prefix when creating a regex
var tempPrefix = prefix.slice(0, -1);
var testRegex = new RegExp(tempPrefix + '.' + regularExpression);
if (!browserSupportsLocalStorage || self.storageType === 'cookie') {
if (!browserSupportsLocalStorage) {
$rootScope.$broadcast('LocalStorageModule.notification.warning', 'LOCAL_STORAGE_NOT_SUPPORTED');
}
return clearAllFromCookies();
}
var prefixLength = prefix.length;
for (var key in webStorage) {
// Only remove items that are for this app and match the regular expression
if (testRegex.test(key)) {
try {
removeFromLocalStorage(key.substr(prefixLength));
} catch (e) {
$rootScope.$broadcast('LocalStorageModule.notification.error',e.message);
return clearAllFromCookies();
}
}
}
return true;
};
// Checks the browser to see if cookies are supported
var browserSupportsCookies = (function() {
try {
return $window.navigator.cookieEnabled ||
("cookie" in $document && ($document.cookie.length > 0 ||
($document.cookie = "test").indexOf.call($document.cookie, "test") > -1));
} catch (e) {
$rootScope.$broadcast('LocalStorageModule.notification.error', e.message);
return false;
}
}());
// Directly adds a value to cookies
// Typically used as a fallback is local storage is not available in the browser
// Example use: localStorageService.cookie.add('library','angular');
var addToCookies = function (key, value) {
if (isUndefined(value)) {
return false;
} else if(isArray(value) || isObject(value)) {
value = toJson(value);
}
if (!browserSupportsCookies) {
$rootScope.$broadcast('LocalStorageModule.notification.error', 'COOKIES_NOT_SUPPORTED');
return false;
}
try {
var expiry = '',
expiryDate = new Date(),
cookieDomain = '';
if (value === null) {
// Mark that the cookie has expired one day ago
expiryDate.setTime(expiryDate.getTime() + (-1 * 24 * 60 * 60 * 1000));
expiry = "; expires=" + expiryDate.toGMTString();
value = '';
} else if (cookie.expiry !== 0) {
expiryDate.setTime(expiryDate.getTime() + (cookie.expiry * 24 * 60 * 60 * 1000));
expiry = "; expires=" + expiryDate.toGMTString();
}
if (!!key) {
var cookiePath = "; path=" + cookie.path;
if(cookie.domain){
cookieDomain = "; domain=" + cookie.domain;
}
$document.cookie = deriveQualifiedKey(key) + "=" + encodeURIComponent(value) + expiry + cookiePath + cookieDomain;
}
} catch (e) {
$rootScope.$broadcast('LocalStorageModule.notification.error',e.message);
return false;
}
return true;
};
// Directly get a value from a cookie
// Example use: localStorageService.cookie.get('library'); // returns 'angular'
var getFromCookies = function (key) {
if (!browserSupportsCookies) {
$rootScope.$broadcast('LocalStorageModule.notification.error', 'COOKIES_NOT_SUPPORTED');
return false;
}
var cookies = $document.cookie && $document.cookie.split(';') || [];
for(var i=0; i < cookies.length; i++) {
var thisCookie = cookies[i];
while (thisCookie.charAt(0) === ' ') {
thisCookie = thisCookie.substring(1,thisCookie.length);
}
if (thisCookie.indexOf(deriveQualifiedKey(key) + '=') === 0) {
var storedValues = decodeURIComponent(thisCookie.substring(prefix.length + key.length + 1, thisCookie.length))
try{
var obj = JSON.parse(storedValues);
return fromJson(obj)
}catch(e){
return storedValues
}
}
}
return null;
};
var removeFromCookies = function (key) {
addToCookies(key,null);
};
var clearAllFromCookies = function () {
var thisCookie = null, thisKey = null;
var prefixLength = prefix.length;
var cookies = $document.cookie.split(';');
for(var i = 0; i < cookies.length; i++) {
thisCookie = cookies[i];
while (thisCookie.charAt(0) === ' ') {
thisCookie = thisCookie.substring(1, thisCookie.length);
}
var key = thisCookie.substring(prefixLength, thisCookie.indexOf('='));
removeFromCookies(key);
}
};
var getStorageType = function() {
return storageType;
};
// 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 value = getFromLocalStorage(lsKey);
if (value === null && isDefined(def)) {
value = def;
} else if (isObject(value) && isObject(def)) {
value = extend(def, value);
}
$parse(key).assign(scope, value);
return scope.$watch(key, function(newVal) {
addToLocalStorage(lsKey, newVal);
}, isObject(scope[key]));
};
// Return localStorageService.length
// ignore keys that not owned
var lengthOfLocalStorage = function() {
var count = 0;
var storage = $window[storageType];
for(var i = 0; i < storage.length; i++) {
if(storage.key(i).indexOf(prefix) === 0 ) {
count++;
}
}
return count;
};
return {
isSupported: browserSupportsLocalStorage,
getStorageType: getStorageType,
set: addToLocalStorage,
put: addToLocalStorage,
add: addToLocalStorage, //DEPRECATED
get: getFromLocalStorage,
keys: getKeysForLocalStorage,
remove: removeFromLocalStorage,
clearAll: clearAllFromLocalStorage,
bind: bindToScope,
deriveKey: deriveQualifiedKey,
length: lengthOfLocalStorage,
cookie: {
isSupported: browserSupportsCookies,
set: addToCookies,
add: addToCookies, //DEPRECATED
get: getFromCookies,
remove: removeFromCookies,
clearAll: clearAllFromCookies
}
};
}];
});
})( window, window.angular );

7
dist/angular-local-storage.min.js vendored Normal file
View File

@ -0,0 +1,7 @@
/**
* An Angular module that gives you access to the browsers local storage
* @version v0.1.5 - 2015-01-22
* @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);

View File

@ -1,8 +1,9 @@
{
"name": "angular-local-storage",
"version": "0.0.3",
"version": "0.1.5",
"description": "An Angular module that gives you access to the browsers local storage",
"main": "angular-local-storage.js",
"homepage": "https://github.com/grevory/angular-local-storage",
"main": "./dist/angular-local-storage.js",
"scripts": {
"test": "grunt test"
},
@ -20,18 +21,18 @@
"bugs": {
"url": "https://github.com/grevory/angular-local-storage/issues"
},
"dependencies": {
"grunt": "~0.4.1",
"grunt-cli": "~0.1.9"
},
"devDependencies": {
"time-grunt": "~0.2.9",
"load-grunt-tasks": "~0.3.0",
"grunt-contrib-jshint": "~0.8.0",
"grunt": "~0.4.2",
"grunt-contrib-uglify": "~0.3.2",
"karma": "~0.10",
"grunt-karma": "~0.6.2",
"karma-jasmine": "*"
"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"
}
}

View File

@ -1,12 +1,9 @@
(function() {
/* Start angularLocalStorage */
'use strict';
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('youAppName');
// e.g. localStorageServiceProvider.setPrefix('yourAppName');
// With provider you can use config as this:
// myApp.config(function (localStorageServiceProvider) {
// localStorageServiceProvider.prefix = 'yourAppName';
@ -33,11 +30,13 @@ 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;
this.storageType = storageType;
return this;
};
// Setter for cookie config
@ -46,11 +45,13 @@ 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
@ -60,21 +61,22 @@ angularLocalStorage.provider('localStorageService', function() {
setItem: itemSet,
removeItem: itemRemove
};
return this;
};
this.$get = ['$rootScope', '$window', '$document', function($rootScope, $window, $document) {
var prefix = this.prefix;
var cookie = this.cookie;
var notify = this.notify;
var storageType = this.storageType;
this.$get = ['$rootScope', '$window', '$document', '$parse', function($rootScope, $window, $document, $parse) {
var self = this;
var prefix = self.prefix;
var cookie = self.cookie;
var notify = self.notify;
var storageType = self.storageType;
var webStorage;
// When Angular's $document is not available
if (!$document) {
$document = document;
} else if ($document[0]) {
$document = $document[0];
}
// If there is a prefix set in the config lets use that with an appended period for readability
@ -83,7 +85,7 @@ angularLocalStorage.provider('localStorageService', function() {
}
var deriveQualifiedKey = function(key) {
return prefix + key;
}
};
// Checks the browser to see if local storage is supported
var browserSupportsLocalStorage = (function () {
try {
@ -115,28 +117,32 @@ angularLocalStorage.provider('localStorageService', function() {
// If local storage is not available in the browser use cookies
// Example use: localStorageService.add('library','angular');
var addToLocalStorage = function (key, value) {
// Let's convert undefined values to null to get the value consistent
if (isUndefined(value)) {
value = null;
} else if (isObject(value) || isArray(value) || isNumber(+value || value)) {
value = toJson(value);
}
// If this browser does not support local storage use cookies
if (!browserSupportsLocalStorage) {
$rootScope.$broadcast('LocalStorageModule.notification.warning', 'LOCAL_STORAGE_NOT_SUPPORTED');
if (!browserSupportsLocalStorage || self.storageType === 'cookie') {
if (!browserSupportsLocalStorage) {
$rootScope.$broadcast('LocalStorageModule.notification.warning', 'LOCAL_STORAGE_NOT_SUPPORTED');
}
if (notify.setItem) {
$rootScope.$broadcast('LocalStorageModule.notification.setitem', {key: key, newvalue: value, storageType: 'cookie'});
}
return addToCookies(key, value);
}
// Let's convert undefined values to null to get the value consistent
if (typeof value === "undefined") {
value = null;
}
try {
if (angular.isObject(value) || angular.isArray(value)) {
value = angular.toJson(value);
if (isObject(value) || isArray(value)) {
value = toJson(value);
}
if (webStorage) {webStorage.setItem(deriveQualifiedKey(key), value)};
if (notify.setItem) {
$rootScope.$broadcast('LocalStorageModule.notification.setitem', {key: key, newvalue: value, storageType: this.storageType});
$rootScope.$broadcast('LocalStorageModule.notification.setitem', {key: key, newvalue: value, storageType: self.storageType});
}
} catch (e) {
$rootScope.$broadcast('LocalStorageModule.notification.error', e.message);
@ -149,8 +155,11 @@ angularLocalStorage.provider('localStorageService', function() {
// Example use: localStorageService.get('library'); // returns 'angular'
var getFromLocalStorage = function (key) {
if (!browserSupportsLocalStorage) {
$rootScope.$broadcast('LocalStorageModule.notification.warning','LOCAL_STORAGE_NOT_SUPPORTED');
if (!browserSupportsLocalStorage || self.storageType === 'cookie') {
if (!browserSupportsLocalStorage) {
$rootScope.$broadcast('LocalStorageModule.notification.warning','LOCAL_STORAGE_NOT_SUPPORTED');
}
return getFromCookies(key);
}
@ -161,8 +170,8 @@ angularLocalStorage.provider('localStorageService', function() {
return null;
}
if (item.charAt(0) === "{" || item.charAt(0) === "[") {
return angular.fromJson(item);
if (item.charAt(0) === "{" || item.charAt(0) === "[" || isStringNumber(item)) {
return fromJson(item);
}
return item;
@ -171,8 +180,11 @@ angularLocalStorage.provider('localStorageService', function() {
// Remove an item from local storage
// Example use: localStorageService.remove('library'); // removes the key/value pair of library='angular'
var removeFromLocalStorage = function (key) {
if (!browserSupportsLocalStorage) {
$rootScope.$broadcast('LocalStorageModule.notification.warning', 'LOCAL_STORAGE_NOT_SUPPORTED');
if (!browserSupportsLocalStorage || self.storageType === 'cookie') {
if (!browserSupportsLocalStorage) {
$rootScope.$broadcast('LocalStorageModule.notification.warning', 'LOCAL_STORAGE_NOT_SUPPORTED');
}
if (notify.removeItem) {
$rootScope.$broadcast('LocalStorageModule.notification.removeitem', {key: key, storageType: 'cookie'});
}
@ -182,7 +194,7 @@ angularLocalStorage.provider('localStorageService', function() {
try {
webStorage.removeItem(deriveQualifiedKey(key));
if (notify.removeItem) {
$rootScope.$broadcast('LocalStorageModule.notification.removeitem', {key: key, storageType: this.storageType});
$rootScope.$broadcast('LocalStorageModule.notification.removeitem', {key: key, storageType: self.storageType});
}
} catch (e) {
$rootScope.$broadcast('LocalStorageModule.notification.error', e.message);
@ -227,8 +239,11 @@ angularLocalStorage.provider('localStorageService', function() {
var tempPrefix = prefix.slice(0, -1);
var testRegex = new RegExp(tempPrefix + '.' + regularExpression);
if (!browserSupportsLocalStorage) {
$rootScope.$broadcast('LocalStorageModule.notification.warning', 'LOCAL_STORAGE_NOT_SUPPORTED');
if (!browserSupportsLocalStorage || self.storageType === 'cookie') {
if (!browserSupportsLocalStorage) {
$rootScope.$broadcast('LocalStorageModule.notification.warning', 'LOCAL_STORAGE_NOT_SUPPORTED');
}
return clearAllFromCookies();
}
@ -249,27 +264,29 @@ angularLocalStorage.provider('localStorageService', function() {
};
// Checks the browser to see if cookies are supported
var browserSupportsCookies = function() {
var browserSupportsCookies = (function() {
try {
return navigator.cookieEnabled ||
return $window.navigator.cookieEnabled ||
("cookie" in $document && ($document.cookie.length > 0 ||
($document.cookie = "test").indexOf.call($document.cookie, "test") > -1));
} catch (e) {
$rootScope.$broadcast('LocalStorageModule.notification.error', e.message);
return false;
}
};
}());
// Directly adds a value to cookies
// Typically used as a fallback is local storage is not available in the browser
// Example use: localStorageService.cookie.add('library','angular');
var addToCookies = function (key, value) {
if (typeof value === "undefined") {
if (isUndefined(value)) {
return false;
} else if(isArray(value) || isObject(value)) {
value = toJson(value);
}
if (!browserSupportsCookies()) {
if (!browserSupportsCookies) {
$rootScope.$broadcast('LocalStorageModule.notification.error', 'COOKIES_NOT_SUPPORTED');
return false;
}
@ -305,7 +322,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;
}
@ -317,7 +334,13 @@ angularLocalStorage.provider('localStorageService', function() {
thisCookie = thisCookie.substring(1,thisCookie.length);
}
if (thisCookie.indexOf(deriveQualifiedKey(key) + '=') === 0) {
return decodeURIComponent(thisCookie.substring(prefix.length + key.length + 1, thisCookie.length));
var storedValues = decodeURIComponent(thisCookie.substring(prefix.length + key.length + 1, thisCookie.length))
try{
var obj = JSON.parse(storedValues);
return fromJson(obj)
}catch(e){
return storedValues
}
}
}
return null;
@ -347,26 +370,43 @@ angularLocalStorage.provider('localStorageService', function() {
return storageType;
};
var bindToScope = function(scope, key, def) {
var value = getFromLocalStorage(key);
// 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 value = getFromLocalStorage(lsKey);
if (value === null && angular.isDefined(def)) {
if (value === null && isDefined(def)) {
value = def;
} else if (angular.isObject(value) && angular.isObject(def)) {
value = angular.extend(def, value);
} else if (isObject(value) && isObject(def)) {
value = extend(def, value);
}
scope[key] = value;
$parse(key).assign(scope, value);
scope.$watchCollection(key, function(newVal) {
addToLocalStorage(key, newVal);
});
return scope.$watch(key, function(newVal) {
addToLocalStorage(lsKey, newVal);
}, isObject(scope[key]));
};
// Return localStorageService.length
// ignore keys that not owned
var lengthOfLocalStorage = function() {
var count = 0;
var storage = $window[storageType];
for(var i = 0; i < storage.length; i++) {
if(storage.key(i).indexOf(prefix) === 0 ) {
count++;
}
}
return count;
};
return {
isSupported: browserSupportsLocalStorage,
getStorageType: getStorageType,
set: addToLocalStorage,
put: addToLocalStorage,
add: addToLocalStorage, //DEPRECATED
get: getFromLocalStorage,
keys: getKeysForLocalStorage,
@ -374,7 +414,9 @@ angularLocalStorage.provider('localStorageService', function() {
clearAll: clearAllFromLocalStorage,
bind: bindToScope,
deriveKey: deriveQualifiedKey,
length: lengthOfLocalStorage,
cookie: {
isSupported: browserSupportsCookies,
set: addToCookies,
add: addToCookies, //DEPRECATED
get: getFromCookies,
@ -384,5 +426,3 @@ angularLocalStorage.provider('localStorageService', function() {
};
}];
});
}).call(this);

18
src/common.js Normal file
View File

@ -0,0 +1,18 @@
/*jshint globalstrict:true*/
'use strict';
var isDefined = angular.isDefined,
isUndefined = angular.isUndefined,
isNumber = angular.isNumber,
isObject = angular.isObject,
isArray = angular.isArray,
extend = angular.extend,
toJson = angular.toJson,
fromJson = angular.fromJson;
// Test if string is only contains numbers
// e.g '1' => true, "'1'" => true
function isStringNumber(num) {
return /^-?\d+\.?\d*$/.test(num.replace(/["']/g, ''));
}

View File

@ -22,19 +22,27 @@ module.exports = function(config) {
// - Safari (only Mac)
// - PhantomJS
// - IE (only Windows)
browsers: ['Chrome'],
browsers: ['PhantomJS'],
// list of files / patterns to load in the browser
files: [
bower + 'angular/angular.js',
bower + 'angular-mocks/angular-mocks.js',
'angular-local-storage.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,
@ -45,5 +53,18 @@ 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/'
}
});
};

View File

@ -0,0 +1,42 @@
'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;
}

View File

@ -0,0 +1,565 @@
'use strict';
describe('localStorageService', function() {
var elmSpy;
//Actions
function getItem(key) {
return function($window, localStorageService) {
elmSpy = spyOn($window.localStorage, 'getItem').andCallThrough();
localStorageService.get(key);
};
}
function addItem(key, value) {
return function($window, localStorageService) {
elmSpy = spyOn($window.localStorage, 'setItem').andCallThrough();
localStorageService.set(key, value);
};
}
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();
localStorageService.remove(key);
};
}
//Expectations
function expectGetting(key) {
return function() {
expect(elmSpy).toHaveBeenCalledWith(key);
};
}
function expectAdding(key, value) {
return function() {
expect(elmSpy).toHaveBeenCalledWith(key, value);
};
}
function expectRemoving(key) {
return function() {
expect(elmSpy).toHaveBeenCalledWith(key);
};
}
function expectMatching(key, expected) {
return function(localStorageService) {
expect(localStorageService.get(key)).toEqual(expected);
};
}
function expectStorageTyping(type) {
return function(localStorageService) {
expect(localStorageService.getStorageType()).toEqual(type);
};
}
function expectSupporting(expected) {
return function(localStorageService) {
expect(localStorageService.isSupported).toEqual(expected);
};
}
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
expect($document.cookie.indexOf('domain=' + domain)).not.toEqual(-1);
};
}
function expectCookieConfig(exp, path) {
return function($document, localStorageService) {
localStorageService.set('foo','bar'); //Should trigger first time
// Just compare the expiry date, not the time, because of daylight savings
var expiryStringPartial = exp.substr(0, exp.indexOf(new Date().getFullYear()));
expect($document.cookie.indexOf('expires=' + expiryStringPartial)).not.toEqual(-1);
expect($document.cookie.indexOf('path=' + path)).not.toEqual(-1);
};
}
//Provider
function setPrefix(prefix) {
return function(localStorageServiceProvider) {
localStorageServiceProvider.setPrefix(prefix);
};
}
function setNotify(itemSet, itemRemove) {
return function(localStorageServiceProvider) {
localStorageServiceProvider.setNotify(itemSet, itemRemove);
};
}
function setStorage(type) {
return function(localStorageServiceProvider) {
localStorageServiceProvider.setStorageType(type);
};
}
function setCookieDomain(domain) {
return function(localStorageServiceProvider) {
localStorageServiceProvider.setStorageCookieDomain(domain);
};
}
function setStorageCookie(exp, path) {
return function(localStorageServiceProvider) {
localStorageServiceProvider.setStorageCookie(exp, path);
};
}
beforeEach(module('LocalStorageModule', function($provide) {
$provide.value('$window', {
localStorage: localStorageMock()
});
}));
it('isSupported should be true', inject(
expectSupporting(true)
));
it('typing should be "localStorage" by default, if supported', inject(
expectStorageTyping('localStorage')
));
it('should add key to localeStorage with initial prefix(ls)', inject(
addItem('foo', 'bar'),
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(
addItem('foo', 'bar'),
expectAdding('myApp.foo', 'bar')
);
});
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) {
expect(localStorageService.deriveKey('foo')).toEqual('myApp.foo');
});
});
it('should be able to set and get arrays', function() {
var values = ['foo', 'bar', 'baz'];
inject(
addItem('key', values),
expectAdding('ls.key', angular.toJson(values)),
expectMatching('key', values)
);
});
it('should be able to set and get objects', function() {
var values = { 0: 'foo', 1: 'bar', 2: 'baz' };
inject(
addItem('key', values),
expectAdding('ls.key', angular.toJson(values)),
expectMatching('key', values)
);
});
it('should be able to set and get integers', function() {
inject(
addItem('key', 777),
expectAdding('ls.key', angular.toJson(777)),
expectMatching('key', 777)
);
});
it('should be able to set and get float numbers', function() {
inject(
addItem('key', 123.123),
expectAdding('ls.key', angular.toJson(123.123)),
expectMatching('key', 123.123)
);
});
it('should be able to set and get strings', function() {
inject(
addItem('key', 'string'),
expectAdding('ls.key', 'string'),
expectMatching('key', 'string')
);
});
it('should be able to set and get numbers as a strings', function() {
inject(
addItem('key', '777'),
expectAdding('ls.key', angular.toJson('777')),
expectMatching('key', '777')
);
});
it('should be able to get items', inject(
getItem('key'),
expectGetting('ls.key')
));
it('should be able to remove items', inject(
removeItem('lorem.ipsum'),
expectRemoving('ls.lorem.ipsum')
));
it('should be able only to remove owned keys', inject(function($window, localStorageService) {
localStorageService.set('appKey', 'appValue');
$window.localStorage.setItem('appKey', 'appValue');
expect($window.localStorage.getItem('ls.appKey')).toBeDefined();
expect($window.localStorage.getItem('appKey')).toBeDefined();
localStorageService.remove('appKey');
expect($window.localStorage.getItem('ls.appKey')).not.toBeDefined();
expect($window.localStorage.getItem('appKey')).toBeDefined();
}));
it('should broadcast event on settingItem', inject(function($rootScope, localStorageService) {
var setSpy = spyOn($rootScope, '$broadcast');
localStorageService.set('Ariel', 'Mashraki');
expect(setSpy).toHaveBeenCalled();
}));
it('should not broadcast event on removingItem', inject(function($rootScope, localStorageService) {
var removeSpy = spyOn($rootScope, '$broadcast');
localStorageService.remove('Ariel', 'Mashraki');
expect(removeSpy).not.toHaveBeenCalled();
}));
it('should be able to change notify/broadcasting settings', function() {
module(setNotify(false, false));
inject(function($rootScope, localStorageService) {
var spy = spyOn($rootScope, '$broadcast');
localStorageService.set('a8m', 'foobar');
localStorageService.remove('a8m', 'foobar');
expect(spy).not.toHaveBeenCalled();
});
});
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');
localStorageService.bind($rootScope, 'property');
$rootScope.property = 'newValue';
$rootScope.$digest();
expect($rootScope.property).toEqual(localStorageService.get('property'));
}));
it('should be able to unbind from scope variable', inject(function($rootScope, localStorageService) {
localStorageService.set('property', 'oldValue');
var lsUnbind = localStorageService.bind($rootScope, 'property');
$rootScope.property = 'newValue';
$rootScope.$digest();
expect($rootScope.property).toEqual(localStorageService.get('property'));
lsUnbind();
$rootScope.property = 'anotherValue';
$rootScope.$digest();
expect($rootScope.property).not.toEqual(localStorageService.get('property'));
}));
it('should be able to bind to properties of objects', inject(function($rootScope, localStorageService) {
localStorageService.set('obj.property', 'oldValue');
localStorageService.bind($rootScope, 'obj.property');
expect($rootScope.obj.property).toEqual(localStorageService.get('obj.property'));
$rootScope.obj.property = 'newValue';
$rootScope.$digest();
expect($rootScope.obj.property).toEqual(localStorageService.get('obj.property'));
}));
it('should be able to bind to scope using different key', inject(function($rootScope, localStorageService) {
localStorageService.set('lsProperty', 'oldValue');
localStorageService.bind($rootScope, 'property', undefined, 'lsProperty');
expect($rootScope.property).toEqual(localStorageService.get('lsProperty'));
$rootScope.property = 'newValue';
$rootScope.$digest();
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) {
for(var i = 0; i < 10; i++) {
localStorageService.set('key' + i, 'val' + i);
$window.localStorage.setItem('key' + i, 'val' + i);
}
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
describe('SessionStorage', function() {
beforeEach(module('LocalStorageModule', function($provide) {
$provide.value('$window', {
sessionStorage: localStorageMock()
});
}));
it('should be able to change storage to SessionStorage', function() {
module(setStorage('sessionStorage'));
inject(function($window, localStorageService) {
var setSpy = spyOn($window.sessionStorage, 'setItem'),
getSpy = spyOn($window.sessionStorage, 'getItem'),
removeSpy = spyOn($window.sessionStorage, 'removeItem');
localStorageService.set('foo', 'bar');
localStorageService.get('foo');
localStorageService.remove('foo');
expect(setSpy).toHaveBeenCalledWith('ls.foo', 'bar');
expect(getSpy).toHaveBeenCalledWith('ls.foo');
expect(removeSpy).toHaveBeenCalledWith('ls.foo');
});
});
it('type should be sessionStorage', function() {
module(setStorage('sessionStorage'));
inject(
expectStorageTyping('sessionStorage')
);
});
it('isSupported should be true on sessionStorage mode', function() {
module(setStorage('sessionStorage'));
inject(
expectSupporting(true)
);
});
});
//cookie
describe('Cookie', function() {
beforeEach(module('LocalStorageModule', function($provide) {
$provide.value('$window', {
localStorage: false,
sessionStorage: false,
navigator: {
cookieEnabled: true
}
});
$provide.value('$document', {
cookie: ''
});
}));
it('isSupported should be false on fallback mode', inject(
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')
));
it('should be able to add to cookie domain', function() {
module(setCookieDomain('.example.org'));
inject(expectDomain('.example.org'));
});
it('should be able to config expiry and path', function() {
module(setStorageCookie(60, '/path'));
inject(expectCookieConfig(new Date().addDays(60), '/path'));
});
it('should be able to set and get cookie', inject(function(localStorageService) {
localStorageService.set('cookieKey', 'cookieValue');
expect(localStorageService.get('cookieKey')).toEqual('cookieValue');
}));
it('should be able to remove from cookie', inject(function(localStorageService) {
localStorageService.set('cookieKey', 'cookieValue');
localStorageService.remove('cookieKey');
expect(localStorageService.get('cookieKey')).toEqual('');
}));
it('should be able to set and get objects from cookie', inject(function(localStorageService) {
//use as a fallback
localStorageService.set('cookieKey', { a: { b: 1 } });
expect(localStorageService.get('cookieKey')).toEqual({ a: { b: 1 } });
//use directly
localStorageService.cookie.set('cookieKey', { a: 2 });
expect(localStorageService.cookie.get('cookieKey')).toEqual({ a: 2 });
}));
it('should be able to set and get arrays from cookie', inject(function(localStorageService) {
//use as a fallback
localStorageService.set('cookieKey', [1, 2, 3, [ 1, 2, 3 ]]);
expect(localStorageService.get('cookieKey')).toEqual([1, 2, 3, [ 1, 2, 3 ]]);
//use directly
localStorageService.cookie.set('cookieKey', ['foo', 'bar']);
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);
return date.toUTCString();
};
});
//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)
));
});
});

View File

@ -1,87 +0,0 @@
'use strict';
describe('Tests functionality of the localStorage module', function() {
var ls, p, store = [];
beforeEach(module('LocalStorageModule', function(localStorageServiceProvider) {
p = localStorageServiceProvider;
}));
beforeEach(inject(function(_localStorageService_) {
ls = _localStorageService_;
ls.clearAll();
expect(ls.keys()).toEqual([]);
}));
it('A key should be derived to <prefix>.<key>', function() {
var key = "foo";
expect(ls.deriveKey(key)).toBe("ls." + key);
});
it('Should be able to replace a key multiple times', function() {
var key = "foo",
expectedValues = [ "bar", "zoo", "aoo" ];
for (var expectedValue in expectedValues) {
ls.set(key, expectedValue);
expect(ls.get(key)).toBe(expectedValue);
expect(ls.keys()).toEqual([key]);
}
});
it('Should delete a value from my local storage', function() {
var key = "foo",
expectedValue = "bar";
ls.set(key, expectedValue);
expect(ls.get(key)).toBe(expectedValue);
expect(ls.keys()).toEqual([key]);
expect(ls.remove(key)).toBe(true);
expect(ls.get(key)).toBe(null);
expect(ls.keys()).toEqual([]);
});
it('Should add a integer value to my local storage', function() {
var key = "test",
expectedValue = 234;
ls.set(key, expectedValue);
//Since localStorage makes the value a string, we look for the '234' and not 234
expect(ls.get(key)).toBe(expectedValue.toString());
expect(ls.keys()).toEqual([key]);
});
it('Should add a String value to my local storage', function() {
var key = "foo",
expectedValue = "bar";
ls.set(key, expectedValue);
expect(ls.get(key)).toBe(expectedValue);
expect(ls.keys()).toEqual([key]);
});
it('Should add a JSON value to my local storage', function() {
var key = "test",
expectedValue = { key: 'val' };
ls.set(key, expectedValue);
var res = ls.get(key);
expect(res).toEqual(expectedValue);
expect(res.key).toBe('val');
expect(ls.keys()).toEqual([key]);
});
it('Should allow me to set a prefix', function() {
var expectedPrefix = "myPref";
p.setPrefix(expectedPrefix);
expect(p.prefix).toBe(expectedPrefix);
});
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');
});
});