├── MIT-LICENCE ├── README └── src ├── domcached-0.1-prototype.js └── domcached-0.1-jquery.js /MIT-LICENCE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2009 Andris Reinman 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 11 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 12 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 13 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 14 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 15 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 16 | SOFTWARE. -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | DOMCached is a simple wrapper library for the use of DOM Storage provided by the modern browsers. The library is designed after the hugely popular memcached caching system, providing similar "caching" options in JavaScript in the form of local storage. 2 | 3 | While the original DOM Storage provides only methods to save and read string values, DOMCached can input and output any JSON compatible objects. DOMCached includes also support for namespaces and data expiring. 4 | 5 | DOMCached comes in two versions - as a module which requires Prototype (prototypejs.org) and in the form of a jQuery plugin. When using DOMCached as the jQuery plugin, then jquery-json plugin is also needed, since jQuery doesn't provide methods to decode/encode JSON strings. 6 | 7 | (c) 2009 Andris Reinman, FlyCom 8 | www.andrisreinman.com 9 | 10 | DOMCached is freely distributable under the terms of a MIT-style license. 11 | For details and documentation, see the DOMCached web site: http://www.domcached.com/ 12 | -------------------------------------------------------------------------------- /src/domcached-0.1-prototype.js: -------------------------------------------------------------------------------- 1 | /** 2 | * ==DOMCached local storage library, version 0.1c== 3 | * DOMCached is a simple wrapper library for the use of DOM Storage provided by the modern browsers. 4 | * This library is designed after the hugely popular "memcached" caching system, providing similar 5 | * "caching" options in JavaScript in the form of local storage. 6 | * 7 | * While the original DOM Storage provides only methods to save and read string values, DOMCached 8 | * can input and output any JSON compatible objects. DOMCached includes also support for namespaces 9 | * and data expiring. 10 | * 11 | * (c) 2009 Andris Reinman, FlyCom 12 | * www.andrisreinman.com 13 | * 14 | * DOMCached is freely distributable under the terms of a MIT-style license. 15 | * For details, see the DOMCached web site: http://www.domcached.com/ 16 | * 17 | * NB! DOMCached requires Prototype (prototypejs.org) to convert from/to JSON strings and also for ') 61 | $('elm_domcached').load("domcached"); 62 | try{ 63 | var data = $('elm_domcached').getAttribute("domcached") 64 | }catch(E){var data = "{}"} 65 | this.storage_service = {dom_storage:{}} 66 | if(data && data.length){ 67 | this.storage_service.dom_storage = data; 68 | } 69 | }else 70 | return; 71 | } 72 | if("dom_storage" in this.storage_service && this.storage_service.dom_storage){ 73 | try{ 74 | this.storage = String(this.storage_service.dom_storage).evalJSON(); 75 | }catch(E){this.storage_service.dom_storage = "{}";} 76 | }else{ 77 | this.storage_service.dom_storage = "{}"; 78 | } 79 | }, 80 | 81 | /** 82 | * This functions provides the "save" mechanism to store the DOMCached.storage object to the DOM Storage 83 | * @returns undefined 84 | */ 85 | save:function(){ 86 | if(this.storage_service){ 87 | try{ 88 | this.storage_service.dom_storage = Object.toJSON(this.storage); 89 | }catch(E){/* probably cache is full, nothing is saved this way*/} 90 | // If userData is used as the storage engine, additional 91 | if($('elm_domcached')){ 92 | try{ 93 | $('elm_domcached').setAttribute("domcached",this.storage_service.dom_storage) 94 | $('elm_domcached').save("domcached") 95 | }catch(E){/* probably cache is full, nothing is saved this way*/} 96 | } 97 | } 98 | }, 99 | 100 | /** 101 | * Sets a key's value, regardless of previous contents in cache. 102 | * @param {String} key - Key to set. If this value is not set or not a string an exception is raised. 103 | * @param value - Value to set. This can be any value that is JSON compatible (Numbers, Strings, Objects etc.). 104 | * @param {number} time - Optional expiration time, either relative number of seconds from current time, or an absolute Unix epoch time in milliseconds. 105 | * @param {String} namespace - An optional namespace for the key. This must be string, otherwise an exception is raised. 106 | * @returns the used value 107 | */ 108 | set: function(key, value, time, namespace){ 109 | namespace = namespace || 'default'; 110 | time = time || false; 111 | if(time && time<(new Date()).getTime()){ 112 | time = (new Date()).getTime()+Math.ceil(time) 113 | } 114 | if(!key || (typeof key != "string" && typeof key != "number")){ 115 | throw new TypeError('Key name must be string or numeric'); 116 | } 117 | if(typeof namespace != "string" && typeof namespace != "number"){ 118 | throw new TypeError('Namespace name must be string or numeric'); 119 | } 120 | if(!this.storage[namespace]){ 121 | this.storage[namespace] = {} 122 | } 123 | this.storage[namespace][key] = {value: value, time: time}; 124 | this.save(); 125 | return value || true; 126 | }, 127 | /** 128 | * Looks up a key in cache 129 | * @param {String} key - Key to look up. If this value is not string an exception is raised. 130 | * @param {String} namespace - An optional namespace for the key. This must be string, otherwise an exception is raised. 131 | * @returns the key value or if not found 132 | */ 133 | get: function(key, namespace){ 134 | namespace = namespace || 'default'; 135 | if(typeof namespace != "string" && typeof namespace != "number"){ 136 | throw new TypeError('Namespace name must be string or numeric'); 137 | } 138 | if(this.storage[namespace] && 139 | this.storage[namespace][key] && 140 | (!this.storage[namespace][key].time || 141 | this.storage[namespace][key].time<(new Date()).getTime())){ 142 | return this.storage[namespace][key].value; 143 | } 144 | return null; 145 | }, 146 | /** 147 | * Deletes a key from cache. 148 | * @param {String} key - Key to delete. If this value is not string an exception is raised. 149 | * @param {String} namespace - An optional namespace for the key. This must be string, otherwise an exception is raised. 150 | * @returns true 151 | */ 152 | 'delete': function(key, namespace){ 153 | namespace = namespace || 'default'; 154 | if(typeof namespace != "string" && typeof namespace != "number"){ 155 | throw new TypeError('Namespace name must be string or numeric'); 156 | } 157 | if(this.storage[namespace] && this.storage[namespace][key]){ 158 | delete this.storage[namespace][key]; 159 | for(var i in delete this.storage[namespace]){ 160 | if(this.storage[namespace].hasOwnProperty(i)){ 161 | this.save(); 162 | return true; 163 | } 164 | } 165 | delete this.storage[namespace]; 166 | this.save(); 167 | return true; 168 | } 169 | }, 170 | 171 | /** 172 | * Sets a key's value, if and only if the item is not already in cache. 173 | * @param {String} key - Key to set. If this value is not set or not a string an exception is raised. 174 | * @param value - Value to set. This can be any value that is JSON compatible (Numbers, Strings, Objects etc.). 175 | * @param {number} time - Optional expiration time, either relative number of seconds from current time, or an absolute Unix epoch time in milliseconds. 176 | * @param {String} namespace - An optional namespace for the key. This must be string, otherwise an exception is raised. 177 | * @returns the used value or false if the key was already used 178 | */ 179 | add: function(key, value, time, namespace){ 180 | namespace = namespace || 'default'; 181 | time = time || false; 182 | if(time && time<(new Date()).getTime()){ 183 | time = (new Date()).getTime()+Math.ceil(time) 184 | } 185 | if(!key || (typeof key != "string" && typeof key != "number")){ 186 | throw new TypeError('Key name must be string or numeric'); 187 | } 188 | if(typeof namespace != "string" && typeof namespace != "number"){ 189 | throw new TypeError('Namespace name must be string or numeric'); 190 | } 191 | if(!this.storage[namespace]){ 192 | this.storage[namespace] = {} 193 | } 194 | if(this.storage[namespace].hasOwnProperty(key)){ 195 | return false; 196 | } 197 | this.storage[namespace][key] = {value: value, time: time}; 198 | this.save(); 199 | return value || true; 200 | }, 201 | 202 | /** 203 | * Replaces a key's value, failing if item isn't already in cache. 204 | * @param {String} key - Key to set. If this value is not set or not a string an exception is raised. 205 | * @param value - Value to set. This can be any value that is JSON compatible (Numbers, Strings, Objects etc.). 206 | * @param {number} time - Optional expiration time, either relative number of seconds from current time, or an absolute Unix epoch time in milliseconds. 207 | * @param {String} namespace - An optional namespace for the key. This must be string, otherwise an exception is raised. 208 | * @returns the used value or false if the key was already used 209 | */ 210 | replace: function(key, value, time, namespace){ 211 | namespace = namespace || 'default'; 212 | time = time || false; 213 | if(time && time<(new Date()).getTime()){ 214 | time = (new Date()).getTime()+time 215 | } 216 | if(!key || (typeof key != "string" && typeof key != "number")){ 217 | throw new TypeError('Key name must be string or numeric'); 218 | } 219 | if(typeof namespace != "string" && typeof namespace != "number"){ 220 | throw new TypeError('Namespace name must be string or numeric'); 221 | } 222 | if(!this.storage[namespace]){ 223 | this.storage[namespace] = {} 224 | } 225 | if(!this.storage[namespace].hasOwnProperty(key)){ 226 | return false; 227 | } 228 | this.storage[namespace][key] = {value: value, time: time}; 229 | this.save(); 230 | return value || true; 231 | }, 232 | 233 | /** 234 | * Automically increments a key's value. 235 | * @param {String} key - Key to increment. If this value is not set or not a string an exception is raised. 236 | * @param {Number} delta - Numric value to increment key by, defaulting to 1. 237 | * @param {String} namespace - An optional namespace for the key. This must be string, otherwise an exception is raised. 238 | * @param {Number} initial_value - An initial value to be used if the key does not yet exist in the cache. Ignored if the key already exists. 239 | * @returns the new value 240 | */ 241 | incr: function(key, delta, namespace, initial_value){ 242 | namespace = namespace || 'default'; 243 | delta = delta || 1; 244 | initial_value = initial_value || 0; 245 | time = time || false; 246 | if(time && time<(new Date()).getTime()){ 247 | time = (new Date()).getTime()+time 248 | } 249 | if(!key || (typeof key != "string" && typeof key != "number")){ 250 | throw new TypeError('Key name must be string or numeric'); 251 | } 252 | if(typeof namespace != "string" && typeof namespace != "number"){ 253 | throw new TypeError('Namespace name must be string or numeric'); 254 | } 255 | if(typeof delta != "number"){ 256 | throw new TypeError('Delta value must be number'); 257 | } 258 | if(!this.storage[namespace]){ 259 | this.storage[namespace] = {} 260 | } 261 | if(!this.storage[namespace].hasOwnProperty(key) || typeof this.storage[namespace][key] != "number"){ 262 | this.storage[namespace][key].value = initial_value; 263 | this.save(); 264 | return initial_value; 265 | } 266 | this.storage[namespace][key].value += delta 267 | this.save(); 268 | return value || true; 269 | }, 270 | 271 | /** 272 | * Automically decrements a key's value. 273 | * @param {String} key - Key to decrement. If this value is not set or not a string an exception is raised. 274 | * @param {Number} delta - Numric value to decrement key by, defaulting to 1. 275 | * @param {String} namespace - An optional namespace for the key. This must be string, otherwise an exception is raised. 276 | * @param {Number} initial_value - An initial value to be used if the key does not yet exist in the cache. Ignored if the key already exists. 277 | * @returns the new value 278 | */ 279 | decr: function(key, delta, namespace, initial_value){ 280 | namespace = namespace || 'default'; 281 | delta = delta || 1; 282 | initial_value = initial_value || 0; 283 | time = time || false; 284 | if(time && time<(new Date()).getTime()){ 285 | time = (new Date()).getTime()+time 286 | } 287 | if(!key || (typeof key != "string" && typeof key != "number")){ 288 | throw new TypeError('Key name must be string or numeric'); 289 | } 290 | if(typeof namespace != "string" && typeof namespace != "number"){ 291 | throw new TypeError('Namespace name must be string or numeric'); 292 | } 293 | if(typeof delta != "number"){ 294 | throw new TypeError('Delta value must be number'); 295 | } 296 | if(!this.storage[namespace]){ 297 | this.storage[namespace] = {} 298 | } 299 | if(!this.storage[namespace].hasOwnProperty(key) || typeof this.storage[namespace][key] != "number"){ 300 | this.storage[namespace][key].value = initial_value; 301 | this.save(); 302 | return initial_value; 303 | } 304 | this.storage[namespace][key].value -= delta 305 | this.save(); 306 | return value || true; 307 | }, 308 | 309 | /** 310 | * Deletes everything in cache. 311 | * @returns true 312 | */ 313 | flush_all: function(){ 314 | this.storage = {} 315 | this.save() 316 | return true; 317 | } 318 | } 319 | 320 | /* Initialization */ 321 | DOMCached.init(); 322 | -------------------------------------------------------------------------------- /src/domcached-0.1-jquery.js: -------------------------------------------------------------------------------- 1 | /** 2 | * ==DOMCached local storage library, version 0.1c-jquery== 3 | * DOMCached is a simple wrapper library for the use of DOM Storage provided by the modern browsers. 4 | * This library is designed after the hugely popular "memcached" caching system, providing similar 5 | * "caching" options in JavaScript in the form of local storage. 6 | * 7 | * While the original DOM Storage provides only methods to save and read string values, DOMCached 8 | * can input and output any JSON compatible objects. DOMCached includes also support for namespaces 9 | * and data expiring. 10 | * 11 | * (c) 2009 Andris Reinman, FlyCom 12 | * www.andrisreinman.com 13 | * 14 | * DOMCached is freely distributable under the terms of a MIT-style license. 15 | * For details, see the DOMCached web site: http://www.domcached.com/ 16 | * 17 | * NB! DOMCached requires jquery-json (http://code.google.com/p/jquery-json/) 18 | * to convert from/to JSON strings. 19 | * 20 | **/ 21 | 22 | /** 23 | * Usage: 24 | * if(!(key = $.DOMCached.get("key", "my_ns"))){ 25 | * key = load_data_from_server() 26 | * $.DOMCached.set("key","value", false, "my_ns"); 27 | * } 28 | */ 29 | 30 | (function($) { 31 | 32 | $.DOMCached = { 33 | /* Version number */ 34 | version: "0.1c-jquery", 35 | 36 | /* 37 | * This is the object, that holds the cached values 38 | * @param {Object} storage 39 | */ 40 | storage: {}, 41 | 42 | /* 43 | * This is the object, that holds the actual storage object (localStorage or globalStorage['domain']) 44 | * @param {Object} storage 45 | */ 46 | storage_service: false, 47 | 48 | /** 49 | * Initialization function. Detects if the browser supports DOM Storage and behaves accordingly 50 | * @returns undefined 51 | */ 52 | init: function(){ 53 | if("localStorage" in window){ 54 | this.storage_service = localStorage; 55 | }else if("globalStorage" in window){ 56 | this.storage_service = globalStorage[document.domain]; 57 | }else{ 58 | /* If the browser is IE7 or older, use userData behavior as a storage instead */ 59 | if("addBehavior" in document.createElement('div')){ 60 | // add a link element to the header, this will be the storage element 61 | document.write(''); 62 | $('#elm_domcached')[0].load("domcached"); 63 | try{ 64 | var data = $('#elm_domcached')[0].getAttribute("domcached"); 65 | }catch(E){var data = "{}"} 66 | this.storage_service = {dom_storage:{}}; 67 | if(data && data.length){ 68 | this.storage_service.dom_storage = data; 69 | } 70 | }else{ 71 | return; 72 | } 73 | } 74 | if("dom_storage" in this.storage_service && this.storage_service.dom_storage){ 75 | try{ 76 | this.storage = $.evalJSON(this.storage_service.dom_storage); 77 | }catch(E){this.storage_service.dom_storage = "{}";} 78 | }else{ 79 | this.storage_service.dom_storage = "{}"; 80 | } 81 | }, 82 | 83 | /** 84 | * This functions provides the "save" mechanism to store the DOMCached.storage object to the DOM Storage 85 | * @returns undefined 86 | */ 87 | save:function(){ 88 | if(this.storage_service){ 89 | try{ 90 | this.storage_service.dom_storage = $.toJSON(this.storage); 91 | }catch(E){/* probably cache is full, nothing is saved this way*/} 92 | // If userData is used as the storage engine, additional 93 | if($('elm_domcached')){ 94 | try{ 95 | $('#elm_domcached')[0].setAttribute("domcached",this.storage_service.dom_storage); 96 | $('#elm_domcached')[0].save("domcached"); 97 | }catch(E){/* probably cache is full, nothing is saved this way*/} 98 | } 99 | } 100 | }, 101 | 102 | /** 103 | * Sets a key's value, regardless of previous contents in cache. 104 | * @param {String} key - Key to set. If this value is not set or not a string an exception is raised. 105 | * @param value - Value to set. This can be any value that is JSON compatible (Numbers, Strings, Objects etc.). 106 | * @param {number} time - Optional expiration time, either relative number of seconds from current time, or an absolute Unix epoch time in milliseconds. 107 | * @param {String} namespace - An optional namespace for the key. This must be string, otherwise an exception is raised. 108 | * @returns the used value 109 | */ 110 | set: function(key, value, time, namespace){ 111 | namespace = namespace || 'default'; 112 | time = time || false; 113 | if(time && time<(new Date()).getTime()){ 114 | time = (new Date()).getTime()+Math.ceil(time); 115 | } 116 | if(!key || (typeof key != "string" && typeof key != "number")){ 117 | throw new TypeError('Key name must be string or numeric'); 118 | } 119 | if(typeof namespace != "string" && typeof namespace != "number"){ 120 | throw new TypeError('Namespace name must be string or numeric'); 121 | } 122 | if(!this.storage[namespace]){ 123 | this.storage[namespace] = {} 124 | } 125 | this.storage[namespace][key] = {value: value, time: time}; 126 | this.save(); 127 | return value || true; 128 | }, 129 | /** 130 | * Looks up a key in cache 131 | * @param {String} key - Key to look up. If this value is not string an exception is raised. 132 | * @param {String} namespace - An optional namespace for the key. This must be string, otherwise an exception is raised. 133 | * @returns the key value or if not found 134 | */ 135 | get: function(key, namespace){ 136 | namespace = namespace || 'default'; 137 | if(typeof namespace != "string" && typeof namespace != "number"){ 138 | throw new TypeError('Namespace name must be string or numeric'); 139 | } 140 | if(this.storage[namespace] && this.storage[namespace][key]){ 141 | if (this.storage[namespace][key].time && 142 | this.storage[namespace][key].time<(new Date()).getTime()){ 143 | this.deleteKey(key, namespace); 144 | return null; 145 | } 146 | return this.storage[namespace][key].value; 147 | } 148 | return null; 149 | }, 150 | /** 151 | * Deletes a key from cache. 152 | * @param {String} key - Key to delete. If this value is not string an exception is raised. 153 | * @param {String} namespace - An optional namespace for the key. This must be string, otherwise an exception is raised. 154 | * @returns true 155 | */ 156 | 'delete': function(key, namespace){ 157 | return this.deleteKey(key, namespace); 158 | }, 159 | deleteKey: function(key, namespace){ 160 | namespace = namespace || 'default'; 161 | if(typeof namespace != "string" && typeof namespace != "number"){ 162 | throw new TypeError('Namespace name must be string or numeric'); 163 | } 164 | if(this.storage[namespace] && this.storage[namespace][key]){ 165 | delete this.storage[namespace][key]; 166 | for(var i in this.storage[namespace]){ 167 | if(this.storage[namespace].hasOwnProperty(i)){ 168 | this.save(); 169 | return true; 170 | } 171 | } 172 | delete this.storage[namespace]; 173 | this.save(); 174 | return true; 175 | } 176 | }, 177 | 178 | /** 179 | * Sets a key's value, if and only if the item is not already in cache. 180 | * @param {String} key - Key to set. If this value is not set or not a string an exception is raised. 181 | * @param value - Value to set. This can be any value that is JSON compatible (Numbers, Strings, Objects etc.). 182 | * @param {number} time - Optional expiration time, either relative number of seconds from current time, or an absolute Unix epoch time in milliseconds. 183 | * @param {String} namespace - An optional namespace for the key. This must be string, otherwise an exception is raised. 184 | * @returns the used value or false if the key was already used 185 | */ 186 | add: function(key, value, time, namespace){ 187 | namespace = namespace || 'default'; 188 | time = time || false; 189 | if(time && time<(new Date()).getTime()){ 190 | time = (new Date()).getTime()+Math.ceil(time) 191 | } 192 | if(!key || (typeof key != "string" && typeof key != "number")){ 193 | throw new TypeError('Key name must be string or numeric'); 194 | } 195 | if(typeof namespace != "string" && typeof namespace != "number"){ 196 | throw new TypeError('Namespace name must be string or numeric'); 197 | } 198 | if(!this.storage[namespace]){ 199 | this.storage[namespace] = {} 200 | } 201 | if(this.storage[namespace].hasOwnProperty(key)){ 202 | return false; 203 | } 204 | this.storage[namespace][key] = {value: value, time: time}; 205 | this.save(); 206 | return value || true; 207 | }, 208 | 209 | /** 210 | * Replaces a key's value, failing if item isn't already in cache. 211 | * @param {String} key - Key to set. If this value is not set or not a string an exception is raised. 212 | * @param value - Value to set. This can be any value that is JSON compatible (Numbers, Strings, Objects etc.). 213 | * @param {number} time - Optional expiration time, either relative number of seconds from current time, or an absolute Unix epoch time in milliseconds. 214 | * @param {String} namespace - An optional namespace for the key. This must be string, otherwise an exception is raised. 215 | * @returns the used value or false if the key was already used 216 | */ 217 | replace: function(key, value, time, namespace){ 218 | namespace = namespace || 'default'; 219 | time = time || false; 220 | if(time && time<(new Date()).getTime()){ 221 | time = (new Date()).getTime()+time 222 | } 223 | if(!key || (typeof key != "string" && typeof key != "number")){ 224 | throw new TypeError('Key name must be string or numeric'); 225 | } 226 | if(typeof namespace != "string" && typeof namespace != "number"){ 227 | throw new TypeError('Namespace name must be string or numeric'); 228 | } 229 | if(!this.storage[namespace]){ 230 | this.storage[namespace] = {} 231 | } 232 | if(!this.storage[namespace].hasOwnProperty(key)){ 233 | return false; 234 | } 235 | this.storage[namespace][key] = {value: value, time: time}; 236 | this.save(); 237 | return value || true; 238 | }, 239 | 240 | /** 241 | * Automically increments a key's value. 242 | * @param {String} key - Key to increment. If this value is not set or not a string an exception is raised. 243 | * @param {Number} delta - Numric value to increment key by, defaulting to 1. 244 | * @param {String} namespace - An optional namespace for the key. This must be string, otherwise an exception is raised. 245 | * @param {Number} initial_value - An initial value to be used if the key does not yet exist in the cache. Ignored if the key already exists. 246 | * @returns the new value 247 | */ 248 | incr: function(key, delta, namespace, initial_value){ 249 | namespace = namespace || 'default'; 250 | delta = delta || 1; 251 | initial_value = initial_value || 0; 252 | time = time || false; 253 | if(time && time<(new Date()).getTime()){ 254 | time = (new Date()).getTime()+time 255 | } 256 | if(!key || (typeof key != "string" && typeof key != "number")){ 257 | throw new TypeError('Key name must be string or numeric'); 258 | } 259 | if(typeof namespace != "string" && typeof namespace != "number"){ 260 | throw new TypeError('Namespace name must be string or numeric'); 261 | } 262 | if(typeof delta != "number"){ 263 | throw new TypeError('Delta value must be number'); 264 | } 265 | if(!this.storage[namespace]){ 266 | this.storage[namespace] = {} 267 | } 268 | if(!this.storage[namespace].hasOwnProperty(key) || typeof this.storage[namespace][key] != "number"){ 269 | this.storage[namespace][key].value = initial_value; 270 | this.save(); 271 | return initial_value; 272 | } 273 | this.storage[namespace][key].value += delta 274 | this.save(); 275 | return value || true; 276 | }, 277 | 278 | /** 279 | * Automically decrements a key's value. 280 | * @param {String} key - Key to decrement. If this value is not set or not a string an exception is raised. 281 | * @param {Number} delta - Numric value to decrement key by, defaulting to 1. 282 | * @param {String} namespace - An optional namespace for the key. This must be string, otherwise an exception is raised. 283 | * @param {Number} initial_value - An initial value to be used if the key does not yet exist in the cache. Ignored if the key already exists. 284 | * @returns the new value 285 | */ 286 | decr: function(key, delta, namespace, initial_value){ 287 | namespace = namespace || 'default'; 288 | delta = delta || 1; 289 | initial_value = initial_value || 0; 290 | time = time || false; 291 | if(time && time<(new Date()).getTime()){ 292 | time = (new Date()).getTime()+time 293 | } 294 | if(!key || (typeof key != "string" && typeof key != "number")){ 295 | throw new TypeError('Key name must be string or numeric'); 296 | } 297 | if(typeof namespace != "string" && typeof namespace != "number"){ 298 | throw new TypeError('Namespace name must be string or numeric'); 299 | } 300 | if(typeof delta != "number"){ 301 | throw new TypeError('Delta value must be number'); 302 | } 303 | if(!this.storage[namespace]){ 304 | this.storage[namespace] = {} 305 | } 306 | if(!this.storage[namespace].hasOwnProperty(key) || typeof this.storage[namespace][key] != "number"){ 307 | this.storage[namespace][key].value = initial_value; 308 | this.save(); 309 | return initial_value; 310 | } 311 | this.storage[namespace][key].value -= delta 312 | this.save(); 313 | return value || true; 314 | }, 315 | 316 | /** 317 | * Deletes everything in cache. 318 | * @returns true 319 | */ 320 | flush_all: function(){ 321 | this.storage = {} 322 | this.save() 323 | return true; 324 | } 325 | } 326 | 327 | /* Initialization */ 328 | $.DOMCached.init(); 329 | })(jQuery); --------------------------------------------------------------------------------