diff options
Diffstat (limited to 'includes/js/dojox/storage/WhatWGStorageProvider.js')
-rw-r--r-- | includes/js/dojox/storage/WhatWGStorageProvider.js | 278 |
1 files changed, 278 insertions, 0 deletions
diff --git a/includes/js/dojox/storage/WhatWGStorageProvider.js b/includes/js/dojox/storage/WhatWGStorageProvider.js new file mode 100644 index 0000000..4bd4c22 --- /dev/null +++ b/includes/js/dojox/storage/WhatWGStorageProvider.js @@ -0,0 +1,278 @@ +if(!dojo._hasResource["dojox.storage.WhatWGStorageProvider"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code. +dojo._hasResource["dojox.storage.WhatWGStorageProvider"] = true; +dojo.provide("dojox.storage.WhatWGStorageProvider"); +dojo.require("dojox.storage.Provider"); +dojo.require("dojox.storage.manager"); + +dojo.declare("dojox.storage.WhatWGStorageProvider", [ dojox.storage.Provider ], { + // summary: + // Storage provider that uses WHAT Working Group features in Firefox 2 + // to achieve permanent storage. + // description: + // The WHAT WG storage API is documented at + // http://www.whatwg.org/specs/web-apps/current-work/#scs-client-side + // + // You can disable this storage provider with the following djConfig + // variable: + // var djConfig = { disableWhatWGStorage: true }; + // + // Authors of this storage provider- + // JB Boisseau, jb.boisseau@eutech-ssii.com + // Brad Neuberg, bkn3@columbia.edu + + initialized: false, + + _domain: null, + _available: null, + _statusHandler: null, + _allNamespaces: null, + _storageEventListener: null, + + initialize: function(){ + if(dojo.config["disableWhatWGStorage"] == true){ + return; + } + + // get current domain + // see: https://bugzilla.mozilla.org/show_bug.cgi?id=357323 + this._domain = (location.hostname == "localhost") ? "localhost.localdomain" : location.hostname; + // console.debug(this._domain); + + // indicate that this storage provider is now loaded + this.initialized = true; + dojox.storage.manager.loaded(); + }, + + isAvailable: function(){ + try{ + // see: https://bugzilla.mozilla.org/show_bug.cgi?id=357323 + var myStorage = globalStorage[((location.hostname == "localhost") ? "localhost.localdomain" : location.hostname)]; + }catch(e){ + this._available = false; + return this._available; + } + + this._available = true; + return this._available; + }, + + put: function(key, value, resultsHandler, namespace){ + if(this.isValidKey(key) == false){ + throw new Error("Invalid key given: " + key); + } + namespace = namespace||this.DEFAULT_NAMESPACE; + + // get our full key name, which is namespace + key + key = this.getFullKey(key, namespace); + + this._statusHandler = resultsHandler; + + // serialize the value; + // handle strings differently so they have better performance + if(dojo.isString(value)){ + value = "string:" + value; + }else{ + value = dojo.toJson(value); + } + + // register for successful storage events. + var storageListener = dojo.hitch(this, function(evt){ + // remove any old storage event listener we might have added + // to the window on old put() requests; Firefox has a bug + // where it can occassionaly go into infinite loops calling + // our storage event listener over and over -- this is a + // workaround + // FIXME: Simplify this into a test case and submit it + // to Firefox + window.removeEventListener("storage", storageListener, false); + + // indicate we succeeded + if(resultsHandler){ + resultsHandler.call(null, this.SUCCESS, key); + } + }); + + window.addEventListener("storage", storageListener, false); + + // try to store the value + try{ + var myStorage = globalStorage[this._domain]; + myStorage.setItem(key, value); + }catch(e){ + // indicate we failed + this._statusHandler.call(null, this.FAILED, key, e.toString()); + } + }, + + get: function(key, namespace){ + if(this.isValidKey(key) == false){ + throw new Error("Invalid key given: " + key); + } + namespace = namespace||this.DEFAULT_NAMESPACE; + + // get our full key name, which is namespace + key + key = this.getFullKey(key, namespace); + + // sometimes, even if a key doesn't exist, Firefox + // will return a blank string instead of a null -- + // this _might_ be due to having underscores in the + // keyname, but I am not sure. + + // FIXME: Simplify this bug into a testcase and + // submit it to Firefox + var myStorage = globalStorage[this._domain]; + var results = myStorage.getItem(key); + + if(results == null || results == ""){ + return null; + } + + results = results.value; + + // destringify the content back into a + // real JavaScript object; + // handle strings differently so they have better performance + if(dojo.isString(results) && (/^string:/.test(results))){ + results = results.substring("string:".length); + }else{ + results = dojo.fromJson(results); + } + + return results; + }, + + getNamespaces: function(){ + var results = [ this.DEFAULT_NAMESPACE ]; + + // simply enumerate through our array and save any string + // that starts with __ + var found = {}; + var myStorage = globalStorage[this._domain]; + var tester = /^__([^_]*)_/; + for(var i = 0; i < myStorage.length; i++){ + var currentKey = myStorage.key(i); + if(tester.test(currentKey) == true){ + var currentNS = currentKey.match(tester)[1]; + // have we seen this namespace before? + if(typeof found[currentNS] == "undefined"){ + found[currentNS] = true; + results.push(currentNS); + } + } + } + + return results; + }, + + getKeys: function(namespace){ + namespace = namespace||this.DEFAULT_NAMESPACE; + + if(this.isValidKey(namespace) == false){ + throw new Error("Invalid namespace given: " + namespace); + } + + // create a regular expression to test the beginning + // of our key names to see if they match our namespace; + // if it is the default namespace then test for the presence + // of no namespace for compatibility with older versions + // of dojox.storage + var namespaceTester; + if(namespace == this.DEFAULT_NAMESPACE){ + namespaceTester = new RegExp("^([^_]{2}.*)$"); + }else{ + namespaceTester = new RegExp("^__" + namespace + "_(.*)$"); + } + + var myStorage = globalStorage[this._domain]; + var keysArray = []; + for(var i = 0; i < myStorage.length; i++){ + var currentKey = myStorage.key(i); + if(namespaceTester.test(currentKey) == true){ + // strip off the namespace portion + currentKey = currentKey.match(namespaceTester)[1]; + keysArray.push(currentKey); + } + } + + return keysArray; + }, + + clear: function(namespace){ + namespace = namespace||this.DEFAULT_NAMESPACE; + + if(this.isValidKey(namespace) == false){ + throw new Error("Invalid namespace given: " + namespace); + } + + // create a regular expression to test the beginning + // of our key names to see if they match our namespace; + // if it is the default namespace then test for the presence + // of no namespace for compatibility with older versions + // of dojox.storage + var namespaceTester; + if(namespace == this.DEFAULT_NAMESPACE){ + namespaceTester = new RegExp("^[^_]{2}"); + }else{ + namespaceTester = new RegExp("^__" + namespace + "_"); + } + + var myStorage = globalStorage[this._domain]; + var keys = []; + for(var i = 0; i < myStorage.length; i++){ + if(namespaceTester.test(myStorage.key(i)) == true){ + keys[keys.length] = myStorage.key(i); + } + } + + dojo.forEach(keys, dojo.hitch(myStorage, "removeItem")); + }, + + remove: function(key, namespace){ + // get our full key name, which is namespace + key + key = this.getFullKey(key, namespace); + + var myStorage = globalStorage[this._domain]; + myStorage.removeItem(key); + }, + + isPermanent: function(){ + return true; + }, + + getMaximumSize: function(){ + return this.SIZE_NO_LIMIT; + }, + + hasSettingsUI: function(){ + return false; + }, + + showSettingsUI: function(){ + throw new Error(this.declaredClass + " does not support a storage settings user-interface"); + }, + + hideSettingsUI: function(){ + throw new Error(this.declaredClass + " does not support a storage settings user-interface"); + }, + + getFullKey: function(key, namespace){ + namespace = namespace||this.DEFAULT_NAMESPACE; + + if(this.isValidKey(namespace) == false){ + throw new Error("Invalid namespace given: " + namespace); + } + + // don't append a namespace string for the default namespace, + // for compatibility with older versions of dojox.storage + if(namespace == this.DEFAULT_NAMESPACE){ + return key; + }else{ + return "__" + namespace + "_" + key; + } + } +}); + +dojox.storage.manager.register("dojox.storage.WhatWGStorageProvider", + new dojox.storage.WhatWGStorageProvider()); + +} |