From 7b66b63e2590cfecbee1d81d4f011b5b2049633b Mon Sep 17 00:00:00 2001 From: Sean Date: Wed, 15 Jul 2015 21:24:53 +0100 Subject: [PATCH] 2.0.2 release --- README.md | 2 +- bower.json | 2 +- changes.md | 6 ++++++ dist/angular-locker.min.js | 2 +- dist/angular-locker.min.js.map | 2 +- package.json | 2 +- 6 files changed, 11 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 35e7e3e..55e8e43 100644 --- a/README.md +++ b/README.md @@ -49,7 +49,7 @@ http://www.jsdelivr.com/#!angular.locker Simply download the zip file [HERE](https://github.com/tymondesigns/angular-locker/archive/master.zip) and include `dist/angular-locker.min.js` in your project. -1.66 kB Minified & gzipped. +1.64 kB Minified & gzipped.

Usage

diff --git a/bower.json b/bower.json index 0123d8d..98a6523 100644 --- a/bower.json +++ b/bower.json @@ -1,6 +1,6 @@ { "name": "angular-locker", - "version": "2.0.1", + "version": "2.0.2", "homepage": "https://github.com/tymondesigns/angular-locker", "authors": [ "Sean Tymon " diff --git a/changes.md b/changes.md index 1853777..a940e3b 100644 --- a/changes.md +++ b/changes.md @@ -1,3 +1,9 @@ +### 2.0.2 + +##### Fixes + +- Fixed issue with multiple sequential calls to same driver - see #22 + ### 2.0.1 ##### Fixes diff --git a/dist/angular-locker.min.js b/dist/angular-locker.min.js index cb8551f..a0ab695 100644 --- a/dist/angular-locker.min.js +++ b/dist/angular-locker.min.js @@ -1,3 +1,3 @@ -/*! angular-locker v2.0.1 | (c) 2015 @tymondesigns | https://github.com/tymondesigns/angular-locker */ +/*! angular-locker v2.0.2 | (c) 2015 @tymondesigns | https://github.com/tymondesigns/angular-locker */ !function(t,e){"function"==typeof define&&define.amd?define(function(){return e(t.angular)}):"object"==typeof exports?module.exports=e(t.angular||window&&window.angular):e(t.angular)}(this,function(t){"use strict";t.module("angular-locker",[]).provider("locker",function(){var e=function(e,r){return t.isFunction(e)?e(r):e},r=function(e){return t.isDefined(e)&&null!==e},i=function(t){throw new Error("[angular-locker] "+t)},s={driver:"local",namespace:"locker",eventsEnabled:!0,separator:".",extend:{}};return{defaults:function(e){return r(e)?void t.forEach(e,function(t,e){s.hasOwnProperty(e)&&(s[e]=t)}):s},$get:["$window","$rootScope","$parse",function(n,o,h){function u(s){this._options=s,this._registeredDrivers=t.extend({local:n.localStorage,session:n.sessionStorage},s.extend),this._resolveDriver=function(t){return this._registeredDrivers.hasOwnProperty(t)||i('The driver "'+t+'" was not found.'),this._registeredDrivers[t]},this._driver=this._resolveDriver(s.driver),this._namespace=s.namespace,this._separator=s.separator,this._watchers={},this._checkSupport=function(t){if(!r(this._supported)){var e="l";try{this._resolveDriver(t||s.driver).setItem(e,e),this._resolveDriver(t||s.driver).removeItem(e),this._supported=!0}catch(i){this._supported=!1}}return this._supported},this._getPrefix=function(t){return this._namespace?this._namespace+this._separator+t:t},this._serialize=function(e){try{return t.toJson(e)}catch(r){return e}},this._unserialize=function(e){try{return t.fromJson(e)}catch(r){return e}},this._event=function(e,r){this._options.eventsEnabled&&o.$emit(e,t.extend(r,{driver:this._options.driver,namespace:this._namespace}))},this._setItem=function(e,r){this._checkSupport()||i('The browser does not support the "'+s.driver+'" driver');try{var n=this._getItem(e);this._driver.setItem(this._getPrefix(e),this._serialize(r)),this._exists(e)&&!t.equals(n,r)?this._event("locker.item.updated",{key:e,oldValue:n,newValue:r}):this._event("locker.item.added",{key:e,value:r})}catch(o){i(-1!==["QUOTA_EXCEEDED_ERR","NS_ERROR_DOM_QUOTA_REACHED","QuotaExceededError"].indexOf(o.name)?"The browser storage quota has been exceeded":'Could not add item with key "'+e+'"')}},this._getItem=function(t){return this._checkSupport()||i('The browser does not support the "'+s.driver+'" driver'),this._unserialize(this._driver.getItem(this._getPrefix(t)))},this._exists=function(t){return this._checkSupport()||i('The browser does not support the "'+s.driver+'" driver'),this._driver.hasOwnProperty(this._getPrefix(e(t)))},this._removeItem=function(t){return this._checkSupport()||i('The browser does not support the "'+s.driver+'" driver'),this._exists(t)?(this._driver.removeItem(this._getPrefix(t)),this._event("locker.item.forgotten",{key:t}),!0):!1}}return u.prototype={put:function(i,s,n){if(!r(i))return!1;if(i=e(i),t.isObject(i))t.forEach(i,function(t,e){this._setItem(e,r(t)?t:n)},this);else{if(!r(s))return!1;var o=this._getItem(i);this._setItem(i,e(s,r(o)?o:n))}return this},add:function(t,e,r){return this.has(t)?!1:(this.put(t,e,r),!0)},get:function(e,r){if(t.isArray(e)){var i={};return t.forEach(e,function(t){this.has(t)&&(i[t]=this._getItem(t))},this),i}return this.has(e)?this._getItem(e):2===arguments.length?r:void 0},has:function(t){return this._exists(t)},forget:function(r){return r=e(r),t.isArray(r)?r.map(this._removeItem,this):this._removeItem(r),this},pull:function(t,e){var r=this.get(t,e);return this.forget(t),r},all:function(){var e={};return t.forEach(this._driver,function(t,r){if(this._namespace){var i=this._namespace+this._separator;0===r.indexOf(i)&&(r=r.substring(i.length))}this.has(r)&&(e[r]=this.get(r))},this),e},keys:function(){return Object.keys(this.all())},clean:function(){return this.forget(this.keys())},empty:function(){return this._driver.clear(),this},count:function(){return this.keys().length},bind:function(e,i,s){r(e.$eval(i))||(h(i).assign(e,this.get(i,s)),this.add(i,s));var n=this;return this._watchers[i+e.$id]=e.$watch(i,function(t){n.put(i,t)},t.isObject(e[i])),this},unbind:function(t,e){h(e).assign(t,void 0),this.forget(e);var r=e+t.$id;return this._watchers[r]&&(this._watchers[r](),delete this._watchers[r]),this},driver:function(e){return this.instance(t.extend(this._options,{driver:e}))},getDriver:function(){return this._driver},namespace:function(e){return this.instance(t.extend(this._options,{namespace:e}))},getNamespace:function(){return this._namespace},supported:function(t){return this._checkSupport(t)},instance:function(t){return new u(t)}},new u(s)}]}})}); //# sourceMappingURL=angular-locker.min.js.map \ No newline at end of file diff --git a/dist/angular-locker.min.js.map b/dist/angular-locker.min.js.map index 4f089ad..3415660 100644 --- a/dist/angular-locker.min.js.map +++ b/dist/angular-locker.min.js.map @@ -1,2 +1,2 @@ -/*! angular-locker v2.0.1 | (c) 2015 @tymondesigns | https://github.com/tymondesigns/angular-locker */ +/*! angular-locker v2.0.2 | (c) 2015 @tymondesigns | https://github.com/tymondesigns/angular-locker */ {"version":3,"sources":["angular-locker.min.js"],"names":["root","factory","define","amd","angular","exports","module","window","this","provider","_value","value","param","isFunction","_defined","isDefined","_error","msg","Error","defaults","driver","namespace","eventsEnabled","separator","extend","forEach","val","key","hasOwnProperty","$get","$window","$rootScope","$parse","Locker","options","_options","_registeredDrivers","local","localStorage","session","sessionStorage","_resolveDriver","_driver","_namespace","_separator","_watchers","_checkSupport","_supported","l","setItem","removeItem","e","_getPrefix","_serialize","toJson","_unserialize","fromJson","_event","name","payload","$emit","_setItem","oldVal","_getItem","_exists","equals","oldValue","newValue","indexOf","getItem","_removeItem","prototype","put","def","isObject","add","has","get","isArray","items","k","arguments","length","forget","map","pull","all","prefix","substring","keys","Object","clean","empty","clear","count","bind","$scope","$eval","assign","self","$id","$watch","newVal","unbind","watchId","instance","getDriver","getNamespace","supported"],"mappings":"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","file":"angular-locker.min.js","sourcesContent":["/**\n * angular-locker\n *\n * A simple & configurable abstraction for local/session storage in angular projects.\n *\n * @link https://github.com/tymondesigns/angular-locker\n * @author Sean Tymon @tymondesigns\n * @license MIT License, http://www.opensource.org/licenses/MIT\n */\n\n(function (root, factory) {\n if (typeof define === 'function' && define.amd) {\n define(function () {\n return factory(root.angular);\n });\n } else if (typeof exports === 'object') {\n module.exports = factory(root.angular || (window && window.angular));\n } else {\n factory(root.angular);\n }\n})(this, function (angular) {\n\n 'use strict';\n\n angular.module('angular-locker', [])\n\n .provider('locker', function () {\n\n /**\n * If value is a function then execute, otherwise return\n *\n * @private\n *\n * @param {Mixed} value The value to execute or return\n * @param {Mixed} param The parameter to pass to function if applicable\n *\n * @return {Mixed}\n */\n var _value = function (value, param) {\n return angular.isFunction(value) ? value(param) : value;\n };\n\n /**\n * Determine whether a value is defined and not null\n *\n * @private\n *\n * @param {Mixed} value The value to check\n *\n * @return {Boolean}\n */\n var _defined = function (value) {\n return angular.isDefined(value) && value !== null;\n };\n\n /**\n * Trigger an error\n *\n * @private\n * @throws {Error}\n *\n * @param {String} msg The error message\n */\n var _error = function (msg) {\n throw new Error('[angular-locker] ' + msg);\n };\n\n /**\n * Set the defaults\n *\n * @private\n *\n * @type {Object}\n */\n var defaults = {\n driver: 'local',\n namespace: 'locker',\n eventsEnabled: true,\n separator: '.',\n extend: {}\n };\n\n return {\n\n /**\n * Allow the defaults to be specified via the `lockerProvider`\n *\n * @param {Object} value The defaults to override\n */\n defaults: function (value) {\n if (! _defined(value)) return defaults;\n\n angular.forEach(value, function (val, key) {\n if (defaults.hasOwnProperty(key)) defaults[key] = val;\n });\n },\n\n /**\n * The locker service\n */\n $get: ['$window', '$rootScope', '$parse', function ($window, $rootScope, $parse) {\n\n /**\n * Define the Locker class\n *\n * @public\n * @constructor\n *\n * @param {Object} options The config options to initialize with\n */\n function Locker (options) {\n\n /**\n * The config options\n *\n * @private\n *\n * @type {Object}\n */\n this._options = options;\n\n /**\n * Out of the box drivers\n *\n * @private\n *\n * @type {Object}\n */\n this._registeredDrivers = angular.extend({\n local: $window.localStorage,\n session: $window.sessionStorage\n }, options.extend);\n\n /**\n * Get the Storage instance from the key\n *\n * @private\n *\n * @param {String} driver The storage driver identifier\n *\n * @return {Storage}\n */\n this._resolveDriver = function (driver) {\n if (! this._registeredDrivers.hasOwnProperty(driver)) {\n _error('The driver \"' + driver + '\" was not found.');\n }\n\n return this._registeredDrivers[driver];\n };\n\n /**\n * The driver instance\n *\n * @private\n *\n * @type {Storage}\n */\n this._driver = this._resolveDriver(options.driver);\n\n /**\n * The namespace value\n *\n * @private\n *\n * @type {String}\n */\n this._namespace = options.namespace;\n\n /**\n * Separates the namespace from the keys\n *\n * @private\n *\n * @type {String}\n */\n this._separator = options.separator;\n\n /**\n * Store the watchers here so we can un-register them later\n *\n * @private\n *\n * @type {Object}\n */\n this._watchers = {};\n\n /**\n * Check browser support\n *\n * @private\n * @see github.com/Modernizr/Modernizr/blob/master/feature-detects/storage/localstorage.js#L38-L47\n *\n * @param {String} driver The driver to check support with\n *\n * @return {Boolean}\n */\n this._checkSupport = function (driver) {\n if (! _defined(this._supported)) {\n var l = 'l';\n try {\n this._resolveDriver(driver || options.driver).setItem(l, l);\n this._resolveDriver(driver || options.driver).removeItem(l);\n this._supported = true;\n } catch (e) {\n this._supported = false;\n }\n }\n\n return this._supported;\n };\n\n /**\n * Build the storage key from the namspace\n *\n * @private\n *\n * @param {String} key The key to build the prefix with\n *\n * @return {String}\n */\n this._getPrefix = function (key) {\n if (! this._namespace) return key;\n\n return this._namespace + this._separator + key;\n };\n\n /**\n * Try to encode value as json, or just return the value upon failure\n *\n * @private\n *\n * @param {Mixed} value The value to serialize\n *\n * @return {Mixed}\n */\n this._serialize = function (value) {\n try {\n return angular.toJson(value);\n } catch (e) {\n return value;\n }\n };\n\n /**\n * Try to parse value as json, if it fails then it probably isn't json\n * so just return it\n *\n * @private\n *\n * @param {String} value The value to unserialize\n *\n * @return {Mixed}\n */\n this._unserialize = function (value) {\n try {\n return angular.fromJson(value);\n } catch (e) {\n return value;\n }\n };\n\n /**\n * Trigger an event\n *\n * @private\n *\n * @param {String} name The name of the event to trigger\n * @param {Object} payload The data to pass along with event\n */\n this._event = function (name, payload) {\n if (this._options.eventsEnabled) {\n $rootScope.$emit(name, angular.extend(payload, {\n driver: this._options.driver,\n namespace: this._namespace,\n }));\n }\n };\n\n /**\n * Add to storage\n *\n * @private\n * @throws {Error} if browser support fails\n *\n * @param {String} key The key to add\n * @param {Mixed} value The value to add\n */\n this._setItem = function (key, value) {\n if (! this._checkSupport()) {\n _error('The browser does not support the \"' + options.driver + '\" driver');\n }\n\n try {\n var oldVal = this._getItem(key);\n this._driver.setItem(this._getPrefix(key), this._serialize(value));\n if (this._exists(key) && ! angular.equals(oldVal, value)) {\n this._event('locker.item.updated', { key: key, oldValue: oldVal, newValue: value });\n } else {\n this._event('locker.item.added', { key: key, value: value });\n }\n } catch (e) {\n if (['QUOTA_EXCEEDED_ERR',\n 'NS_ERROR_DOM_QUOTA_REACHED',\n 'QuotaExceededError'].indexOf(e.name) !== -1) {\n _error('The browser storage quota has been exceeded');\n } else {\n _error('Could not add item with key \"' + key + '\"');\n }\n }\n };\n\n /**\n * Get from storage\n *\n * @private\n * @throws {Error} if browser support fails\n *\n * @param {String} key The key to get\n *\n * @return {Mixed}\n */\n this._getItem = function (key) {\n if (! this._checkSupport()) {\n _error('The browser does not support the \"' + options.driver + '\" driver');\n }\n\n return this._unserialize(this._driver.getItem(this._getPrefix(key)));\n };\n\n /**\n * Exists in storage\n *\n * @private\n * @throws {Error} if browser support fails\n *\n * @param {String} key The key to check for existence\n *\n * @return {Boolean}\n */\n this._exists = function (key) {\n if (! this._checkSupport()) {\n _error('The browser does not support the \"' + options.driver + '\" driver');\n }\n\n return this._driver.hasOwnProperty(this._getPrefix(_value(key)));\n };\n\n /**\n * Remove from storage\n *\n * @private\n * @throws {Error} if browser support fails\n *\n * @param {String} key The key to remove\n *\n * @return {Boolean}\n */\n this._removeItem = function (key) {\n if (! this._checkSupport()) {\n _error('The browser does not support the \"' + options.driver + '\" driver');\n }\n\n if (! this._exists(key)) return false;\n\n this._driver.removeItem(this._getPrefix(key));\n this._event('locker.item.forgotten', { key: key });\n\n return true;\n };\n }\n\n /**\n * Define the public api\n *\n * @public\n *\n * @type {Object}\n */\n Locker.prototype = {\n\n /**\n * Add a new item to storage (even if it already exists)\n *\n * @public\n *\n * @param {Mixed} key The key to add\n * @param {Mixed} value The value to add\n * @param {Mixed} def The default to pass to function if doesn't already exist\n *\n * @return {Locker|Boolean}\n */\n put: function (key, value, def) {\n if (! _defined(key)) return false;\n key = _value(key);\n\n if (angular.isObject(key)) {\n angular.forEach(key, function (value, key) {\n this._setItem(key, _defined(value) ? value : def);\n }, this);\n } else {\n if (! _defined(value)) return false;\n var val = this._getItem(key);\n this._setItem(key, _value(value, _defined(val) ? val : def));\n }\n\n return this;\n },\n\n /**\n * Add an item to storage if it doesn't already exist\n *\n * @public\n *\n * @param {Mixed} key The key to add\n * @param {Mixed} value The value to add\n * @param {Mixed} def The default to pass to function if doesn't already exist\n *\n * @return {Boolean}\n */\n add: function (key, value, def) {\n if (! this.has(key)) {\n this.put(key, value, def);\n return true;\n }\n\n return false;\n },\n\n /**\n * Retrieve the specified item from storage\n *\n * @public\n *\n * @param {String|Array} key The key to get\n * @param {Mixed} def The default value if it does not exist\n *\n * @return {Mixed}\n */\n get: function (key, def) {\n if (angular.isArray(key)) {\n var items = {};\n angular.forEach(key, function (k) {\n if (this.has(k)) items[k] = this._getItem(k);\n }, this);\n\n return items;\n }\n\n if (! this.has(key)) return arguments.length === 2 ? def : void 0;\n\n return this._getItem(key);\n },\n\n /**\n * Determine whether the item exists in storage\n *\n * @public\n *\n * @param {String|Function} key - The key to remove\n *\n * @return {Boolean}\n */\n has: function (key) {\n return this._exists(key);\n },\n\n /**\n * Remove specified item(s) from storage\n *\n * @public\n *\n * @param {String|Array} key The key or array of keys to remove\n *\n * @return {Object}\n */\n forget: function (key) {\n key = _value(key);\n\n if (angular.isArray(key)) {\n key.map(this._removeItem, this);\n } else {\n this._removeItem(key);\n }\n\n return this;\n },\n\n /**\n * Retrieve the specified item from storage and then remove it\n *\n * @public\n *\n * @param {String|Array} key The key to pull from storage\n * @param {Mixed} def The default value if it does not exist\n *\n * @return {Mixed}\n */\n pull: function (key, def) {\n var value = this.get(key, def);\n this.forget(key);\n\n return value;\n },\n\n /**\n * Return all items in storage within the current namespace/driver\n *\n * @public\n *\n * @return {Object}\n */\n all: function () {\n var items = {};\n angular.forEach(this._driver, function (value, key) {\n if (this._namespace) {\n var prefix = this._namespace + this._separator;\n if (key.indexOf(prefix) === 0) key = key.substring(prefix.length);\n }\n if (this.has(key)) items[key] = this.get(key);\n }, this);\n\n return items;\n },\n\n /**\n * Get the storage keys as an array\n *\n * @public\n *\n * @return {Array}\n */\n keys: function () {\n return Object.keys(this.all());\n },\n\n /**\n * Remove all items set within the current namespace/driver\n *\n * @public\n *\n * @return {Locker}\n */\n clean: function () {\n return this.forget(this.keys());\n },\n\n /**\n * Empty the current storage driver completely. careful now.\n *\n * @public\n *\n * @return {Locker}\n */\n empty: function () {\n this._driver.clear();\n\n return this;\n },\n\n /**\n * Get the total number of items within the current namespace\n *\n * @public\n *\n * @return {Integer}\n */\n count: function () {\n return this.keys().length;\n },\n\n /**\n * Bind a storage key to a $scope property\n *\n * @public\n *\n * @param {Object} $scope The angular $scope object\n * @param {String} key The key in storage to bind to\n * @param {Mixed} def The default value to initially bind\n *\n * @return {Locker}\n */\n bind: function ($scope, key, def) {\n if (! _defined( $scope.$eval(key) )) {\n $parse(key).assign($scope, this.get(key, def));\n this.add(key, def);\n }\n\n var self = this;\n this._watchers[key + $scope.$id] = $scope.$watch(key, function (newVal) {\n self.put(key, newVal);\n }, angular.isObject($scope[key]));\n\n return this;\n },\n\n /**\n * Unbind a storage key from a $scope property\n *\n * @public\n *\n * @param {Object} $scope The angular $scope object\n * @param {String} key The key to remove from bindings\n *\n * @return {Locker}\n */\n unbind: function ($scope, key) {\n $parse(key).assign($scope, void 0);\n this.forget(key);\n\n var watchId = key + $scope.$id;\n\n if (this._watchers[watchId]) {\n // execute the de-registration function\n this._watchers[watchId]();\n delete this._watchers[watchId];\n }\n\n return this;\n },\n\n /**\n * Set the storage driver on a new instance to enable overriding defaults\n *\n * @public\n *\n * @param {String} driver The driver to switch to\n *\n * @return {Locker}\n */\n driver: function (driver) {\n return this.instance(angular.extend(this._options, { driver: driver }));\n },\n\n /**\n * Get the currently set driver\n *\n * @public\n *\n * @return {Storage}\n */\n getDriver: function () {\n return this._driver;\n },\n\n /**\n * Set the namespace on a new instance to enable overriding defaults\n *\n * @public\n *\n * @param {String} namespace The namespace to switch to\n *\n * @return {Locker}\n */\n namespace: function (namespace) {\n return this.instance(angular.extend(this._options, { namespace: namespace }));\n },\n\n /**\n * Get the currently set namespace\n *\n * @public\n *\n * @return {String}\n */\n getNamespace: function () {\n return this._namespace;\n },\n\n /**\n * Check browser support\n *\n * @public\n * @see github.com/Modernizr/Modernizr/blob/master/feature-detects/storage/localstorage.js#L38-L47\n *\n * @param {String} driver The driver to check support with\n *\n * @return {Boolean}\n */\n supported: function (driver) {\n return this._checkSupport(driver);\n },\n\n /**\n * Get a new instance of Locker\n *\n * @public\n *\n * @param {Object} options The config options to instantiate with\n *\n * @return {Locker}\n */\n instance: function (options) {\n return new Locker(options);\n }\n };\n\n // return the default instance\n return new Locker(defaults);\n }]\n };\n\n });\n\n});\n"],"sourceRoot":"/source/"} \ No newline at end of file diff --git a/package.json b/package.json index 08cfbfe..e397a47 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "angular-locker", - "version": "2.0.1", + "version": "2.0.2", "description": "A simple & configurable abstraction for local/session storage in angular projects", "author": "@tymondesigns", "license": "MIT",