dojox
Version:
Dojo eXtensions, a rollup of many useful sub-projects and varying states of maturity – from very stable and robust, to alpha and experimental. See individual projects contain README files for details.
205 lines (161 loc) • 5.43 kB
JavaScript
define([
"dojo/_base/declare",
"dojox/storage/Provider",
"dojox/storage/manager",
"dojo/_base/array",
"dojo/_base/lang",
"dojo/json"
], function(declare, Provider, storageManager, array, lang, JSON){
var LocalStorageProvider = declare("dojox.storage.LocalStorageProvider", [Provider], {
store: null,
initialize: function(){
this.store = localStorage;
this.initialized = true;
storageManager.loaded();
},
isAvailable: function(){ /*Boolean*/
return typeof localStorage != "undefined";
},
put: function( /*string*/ key,
/*object*/ value,
/*function*/ resultsHandler,
/*string?*/ namespace){
// TODO: Use the events as specified in http://dev.w3.org/html5/webstorage/#the-storage-event ?
// Currently, the storage event is not reliable around browsers.
this._assertIsValidKey(key);
namespace = namespace||this.DEFAULT_NAMESPACE;
this._assertIsValidNamespace(namespace);
var fullKey = this.getFullKey(key,namespace);
// prepending a prefix to a string value
// will result in that prefix not being
// usable as a value, so we better use
// toJson() always.
value = JSON.stringify(value);
try { // ua may raise an QUOTA_EXCEEDED_ERR exception
this.store.setItem(fullKey,value);
if(resultsHandler){
resultsHandler(this.SUCCESS, key, null, namespace);
}
} catch(e) {
if(resultsHandler){
resultsHandler(this.FAILED, key, e.toString(), namespace);
}
}
},
get: function(/*string*/ key, /*string?*/ namespace){ /*Object*/
this._assertIsValidKey(key);
namespace = namespace||this.DEFAULT_NAMESPACE;
this._assertIsValidNamespace(namespace);
// get our full key name, which is namespace + key
key = this.getFullKey(key, namespace);
return JSON.parse(this.store.getItem(key));
},
getKeys: function(/*string?*/ namespace){ /*Array*/
namespace = namespace||this.DEFAULT_NAMESPACE;
this._assertIsValidNamespace(namespace);
namespace = '__'+namespace+'_'
var keys = [];
for(var i = 0; i < this.store.length; i++){
var currentKey = this.store.key(i);
if(this._beginsWith(currentKey,namespace)){
currentKey = currentKey.substring(namespace.length);
keys.push(currentKey);
}
}
return keys;
},
clear: function(/*string?*/ namespace){
// Um, well, the 'specs' in Provider.js say that if
// no namespace is given, this method should nuke
// the *complete* storage. As other components might
// be using localStorage too, this might not be a
// good idea, so this method won't do it.
namespace = namespace||this.DEFAULT_NAMESPACE;
this._assertIsValidNamespace(namespace);
namespace = '__'+namespace+'_';
var keys = [];
for(var i = 0; i < this.store.length; i++){
if(this._beginsWith(this.store.key(i),namespace)){
keys.push(this.store.key(i));
}
}
array.forEach(keys, lang.hitch(this.store, "removeItem"));
},
remove: function(/*string*/ key, /*string?*/ namespace){
namespace = namespace||this.DEFAULT_NAMESPACE;
this._assertIsValidNamespace(namespace);
this.store.removeItem(this.getFullKey(key, namespace));
},
getNamespaces: function(){ /*string[]*/
// There must be a better way than
// to execute a regex on *every*
// item in the store.
var results = [ this.DEFAULT_NAMESPACE];
var found = {};
found[this.DEFAULT_NAMESPACE] = true;
var tester = /^__([^_]*)_/;
for(var i = 0; i < this.store.length; i++){
var currentKey = this.store.key(i);
if(tester.test(currentKey) == true){
var currentNS = currentKey.match(tester)[1];
if(typeof found[currentNS] == "undefined"){
found[currentNS] = true;
results.push(currentNS);
}
}
}
return results;
},
isPermanent: function(){ /*Boolean*/
return true;
},
getMaximumSize: function(){ /* mixed */
return dojox.storage.SIZE_NO_LIMIT;
},
hasSettingsUI: function(){ /*Boolean*/
return false;
},
isValidKey: function(/*string*/ keyName){ /*Boolean*/
if(keyName === null || keyName === undefined){
return false;
}
return /^[0-9A-Za-z_-]*$/.test(keyName);
},
isValidNamespace: function(/*string*/ keyName){ /*Boolean*/
// we *must* prevent namespaces from having
// underscores - else lookup of namespaces
// via RegEx (e.g. in getNamespaces ) would
// return wrong results.
//
// The only way around this would be to
// disallow underscores in keys.
if(keyName === null || keyName === undefined){
return false;
}
return /^[0-9A-Za-z-]*$/.test(keyName);
},
getFullKey: function(key, namespace){
// checks for valid namespace and
// key are already performed.
return "__" + namespace + "_" + key;
},
_beginsWith: function(/* string */ haystack, /* string */ needle) {
if(needle.length > haystack.length) {
return false;
}
return haystack.substring(0,needle.length) === needle;
},
_assertIsValidNamespace: function(/* string */ namespace){
if(this.isValidNamespace(namespace) === false){
throw new Error("Invalid namespace given: " + namespace);
}
},
_assertIsValidKey: function(/* string */ key){
if(this.isValidKey(key) === false){
throw new Error("Invalid key given: " + key);
}
}
});
storageManager.register("dojox.storage.LocalStorageProvider", new LocalStorageProvider());
return LocalStorageProvider;
});