source: Dev/trunk/src/client/dojox/storage/WhatWGStorageProvider.js

Last change on this file was 483, checked in by hendrikvanantwerpen, 11 years ago

Added Dojo 1.9.3 release.

File size: 7.5 KB
Line 
1dojo.provide("dojox.storage.WhatWGStorageProvider");
2dojo.require("dojox.storage.Provider");
3dojo.require("dojox.storage.manager");
4
5dojo.declare("dojox.storage.WhatWGStorageProvider", [ dojox.storage.Provider ], {
6        // summary:
7        //              Storage provider that uses WHAT Working Group features in Firefox 2
8        //              to achieve permanent storage.
9        // description:
10        //              The WHAT WG storage API is documented at
11        //              http://www.whatwg.org/specs/web-apps/current-work/#scs-client-side
12        //
13        //              You can disable this storage provider with the following djConfig variable:
14        // |    var djConfig = { disableWhatWGStorage: true };
15        //
16        //              Authors of this storage provider:
17        //
18        //              - JB Boisseau, jb.boisseau@eutech-ssii.com
19        //              - Brad Neuberg, bkn3@columbia.edu
20
21        initialized: false,
22       
23        _domain: null,
24        _available: null,
25        _statusHandler: null,
26        _allNamespaces: null,
27        _storageEventListener: null,
28       
29        initialize: function(){
30                if(dojo.config["disableWhatWGStorage"] == true){
31                        return;
32                }
33               
34                // get current domain
35                this._domain = location.hostname;
36                // console.debug(this._domain);
37               
38                // indicate that this storage provider is now loaded
39                this.initialized = true;
40                dojox.storage.manager.loaded();
41        },
42       
43        isAvailable: function(){
44                try{
45                        var myStorage = globalStorage[location.hostname];
46                }catch(e){
47                        this._available = false;
48                        return this._available;
49                }
50               
51                this._available = true;
52                return this._available;
53        },
54
55        put: function(key, value, resultsHandler, namespace){
56                if(this.isValidKey(key) == false){
57                        throw new Error("Invalid key given: " + key);
58                }
59                namespace = namespace||this.DEFAULT_NAMESPACE;
60               
61                // get our full key name, which is namespace + key
62                key = this.getFullKey(key, namespace);
63               
64                this._statusHandler = resultsHandler;
65               
66                // serialize the value;
67                // handle strings differently so they have better performance
68                if(dojo.isString(value)){
69                        value = "string:" + value;
70                }else{
71                        value = dojo.toJson(value);
72                }
73               
74                // register for successful storage events.
75                var storageListener = dojo.hitch(this, function(evt){
76                        // remove any old storage event listener we might have added
77                        // to the window on old put() requests; Firefox has a bug
78                        // where it can occassionaly go into infinite loops calling
79                        // our storage event listener over and over -- this is a
80                        // workaround
81                        // FIXME: Simplify this into a test case and submit it
82                        // to Firefox
83                        window.removeEventListener("storage", storageListener, false);
84                       
85                        // indicate we succeeded
86                        if(resultsHandler){
87                                resultsHandler.call(null, this.SUCCESS, key, null, namespace);
88                        }
89                });
90               
91                window.addEventListener("storage", storageListener, false);
92               
93                // try to store the value
94                try{
95                        var myStorage = globalStorage[this._domain];
96                        myStorage.setItem(key, value);
97                }catch(e){
98                        // indicate we failed
99                        this._statusHandler.call(null, this.FAILED, key, e.toString(), namespace);
100                }
101        },
102
103        get: function(key, namespace){
104                if(this.isValidKey(key) == false){
105                        throw new Error("Invalid key given: " + key);
106                }
107                namespace = namespace||this.DEFAULT_NAMESPACE;
108               
109                // get our full key name, which is namespace + key
110                key = this.getFullKey(key, namespace);
111               
112                // sometimes, even if a key doesn't exist, Firefox
113                // will return a blank string instead of a null --
114                // this _might_ be due to having underscores in the
115                // keyname, but I am not sure.
116               
117                // FIXME: Simplify this bug into a testcase and
118                // submit it to Firefox
119                var myStorage = globalStorage[this._domain];
120                var results = myStorage.getItem(key);
121               
122                if(results == null || results == ""){
123                        return null;
124                }
125               
126                results = results.value;
127               
128                // destringify the content back into a
129                // real JavaScript object;
130                // handle strings differently so they have better performance
131                if(dojo.isString(results) && (/^string:/.test(results))){
132                        results = results.substring("string:".length);
133                }else{
134                        results = dojo.fromJson(results);
135                }
136               
137                return results;
138        },
139       
140        getNamespaces: function(){
141                var results = [ this.DEFAULT_NAMESPACE ];
142               
143                // simply enumerate through our array and save any string
144                // that starts with __
145                var found = {};
146                var myStorage = globalStorage[this._domain];
147                var tester = /^__([^_]*)_/;
148                for(var i = 0; i < myStorage.length; i++){
149                        var currentKey = myStorage.key(i);
150                        if(tester.test(currentKey) == true){
151                                var currentNS = currentKey.match(tester)[1];
152                                // have we seen this namespace before?
153                                if(typeof found[currentNS] == "undefined"){
154                                        found[currentNS] = true;
155                                        results.push(currentNS);
156                                }
157                        }
158                }
159               
160                return results;
161        },
162
163        getKeys: function(namespace){
164                namespace = namespace||this.DEFAULT_NAMESPACE;
165               
166                if(this.isValidKey(namespace) == false){
167                        throw new Error("Invalid namespace given: " + namespace);
168                }
169               
170                // create a regular expression to test the beginning
171                // of our key names to see if they match our namespace;
172                // if it is the default namespace then test for the presence
173                // of no namespace for compatibility with older versions
174                // of dojox.storage
175                var namespaceTester;
176                if(namespace == this.DEFAULT_NAMESPACE){
177                        namespaceTester = new RegExp("^([^_]{2}.*)$");
178                }else{
179                        namespaceTester = new RegExp("^__" + namespace + "_(.*)$");
180                }
181               
182                var myStorage = globalStorage[this._domain];
183                var keysArray = [];
184                for(var i = 0; i < myStorage.length; i++){
185                        var currentKey = myStorage.key(i);
186                        if(namespaceTester.test(currentKey) == true){
187                                // strip off the namespace portion
188                                currentKey = currentKey.match(namespaceTester)[1];
189                                keysArray.push(currentKey);
190                        }
191                }
192               
193                return keysArray;
194        },
195
196        clear: function(namespace){
197                namespace = namespace||this.DEFAULT_NAMESPACE;
198               
199                if(this.isValidKey(namespace) == false){
200                        throw new Error("Invalid namespace given: " + namespace);
201                }
202               
203                // create a regular expression to test the beginning
204                // of our key names to see if they match our namespace;
205                // if it is the default namespace then test for the presence
206                // of no namespace for compatibility with older versions
207                // of dojox.storage
208                var namespaceTester;
209                if(namespace == this.DEFAULT_NAMESPACE){
210                        namespaceTester = new RegExp("^[^_]{2}");
211                }else{
212                        namespaceTester = new RegExp("^__" + namespace + "_");
213                }
214               
215                var myStorage = globalStorage[this._domain];
216                var keys = [];
217                for(var i = 0; i < myStorage.length; i++){
218                        if(namespaceTester.test(myStorage.key(i)) == true){
219                                keys[keys.length] = myStorage.key(i);
220                        }
221                }
222               
223                dojo.forEach(keys, dojo.hitch(myStorage, "removeItem"));
224        },
225       
226        remove: function(key, namespace){
227                // get our full key name, which is namespace + key
228                key = this.getFullKey(key, namespace);
229               
230                var myStorage = globalStorage[this._domain];
231                myStorage.removeItem(key);
232        },
233       
234        isPermanent: function(){
235                return true;
236        },
237
238        getMaximumSize: function(){
239                return this.SIZE_NO_LIMIT;
240        },
241
242        hasSettingsUI: function(){
243                return false;
244        },
245       
246        showSettingsUI: function(){
247                throw new Error(this.declaredClass + " does not support a storage settings user-interface");
248        },
249       
250        hideSettingsUI: function(){
251                throw new Error(this.declaredClass + " does not support a storage settings user-interface");
252        },
253       
254        getFullKey: function(key, namespace){
255                namespace = namespace||this.DEFAULT_NAMESPACE;
256               
257                if(this.isValidKey(namespace) == false){
258                        throw new Error("Invalid namespace given: " + namespace);
259                }
260               
261                // don't append a namespace string for the default namespace,
262                // for compatibility with older versions of dojox.storage
263                if(namespace == this.DEFAULT_NAMESPACE){
264                        return key;
265                }else{
266                        return "__" + namespace + "_" + key;
267                }
268        }
269});
270
271dojox.storage.manager.register("dojox.storage.WhatWGStorageProvider",
272                                                                new dojox.storage.WhatWGStorageProvider());
Note: See TracBrowser for help on using the repository browser.