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

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

Added Dojo 1.9.3 release.

File size: 5.2 KB
Line 
1dojo.provide("dojox.storage.LocalStorageProvider");
2
3dojo.require("dojox.storage.Provider");
4dojo.require("dojox.storage.manager");
5
6dojo.declare(
7        "dojox.storage.LocalStorageProvider",
8        [dojox.storage.Provider],
9        {
10                store: null,
11
12                initialize: function(){
13
14                        this.store = localStorage;
15
16                        this.initialized = true;
17                        dojox.storage.manager.loaded();
18                },
19
20                isAvailable: function(){ /*Boolean*/
21                        return typeof localStorage != 'undefined';
22                },
23
24                put: function(  /*string*/ key,
25                                                /*object*/ value,
26                                                /*function*/ resultsHandler,
27                                                /*string?*/ namespace){
28
29                        // TODO: Use the events as specified in http://dev.w3.org/html5/webstorage/#the-storage-event ?
30                        //      Currently, the storage event is not reliable around browsers.
31
32                        this._assertIsValidKey(key);
33
34                        namespace = namespace||this.DEFAULT_NAMESPACE;
35                        this._assertIsValidNamespace(namespace);
36
37                        var fullKey = this.getFullKey(key,namespace);
38
39                        // prepending a prefix to a string value
40                        // will result in that prefix not being
41                        // usable as a value, so we better use
42                        // toJson() always.
43                        value = dojo.toJson(value);
44
45                        try { // ua may raise an QUOTA_EXCEEDED_ERR exception
46                                this.store.setItem(fullKey,value);
47
48                                if(resultsHandler){
49                                        resultsHandler(this.SUCCESS, key, null, namespace);
50                                }
51                        } catch(e) {
52                                if(resultsHandler){
53                                        resultsHandler(this.FAILED, key, e.toString(), namespace);
54                                }
55                        }
56                },
57
58                get: function(/*string*/ key, /*string?*/ namespace){ /*Object*/
59                        this._assertIsValidKey(key);
60
61                        namespace = namespace||this.DEFAULT_NAMESPACE;
62                        this._assertIsValidNamespace(namespace);
63
64                        // get our full key name, which is namespace + key
65                        key = this.getFullKey(key, namespace);
66
67                        return dojo.fromJson(this.store.getItem(key));
68                },
69
70                getKeys: function(/*string?*/ namespace){ /*Array*/
71                        namespace = namespace||this.DEFAULT_NAMESPACE;
72                        this._assertIsValidNamespace(namespace);
73
74                        namespace = '__'+namespace+'_'
75
76                        var keys = [];
77                        for(var i = 0; i < this.store.length; i++){
78                                var currentKey = this.store.key(i);
79                                if(this._beginsWith(currentKey,namespace)){
80                                        currentKey = currentKey.substring(namespace.length);
81                                        keys.push(currentKey);
82                                }
83                        }
84
85                        return keys;
86                },
87
88                clear: function(/*string?*/ namespace){
89                        // Um, well, the 'specs' in Provider.js say that if
90                        // no namespace is given, this method should nuke
91                        // the *complete* storage. As other components might
92                        // be using localStorage too, this might not be a
93                        // good idea, so this method won't do it.
94
95                        namespace = namespace||this.DEFAULT_NAMESPACE;
96                        this._assertIsValidNamespace(namespace);
97
98                        namespace = '__'+namespace+'_';
99
100                        var keys = [];
101                        for(var i = 0; i < this.store.length; i++){
102                                if(this._beginsWith(this.store.key(i),namespace)){
103                                        keys.push(this.store.key(i));
104                                }
105                        }
106
107                        dojo.forEach(keys, dojo.hitch(this.store, "removeItem"));
108                },
109
110                remove: function(/*string*/ key, /*string?*/ namespace){
111                        namespace = namespace||this.DEFAULT_NAMESPACE;
112                        this._assertIsValidNamespace(namespace);
113
114                        this.store.removeItem(this.getFullKey(key, namespace));
115                },
116
117                getNamespaces: function(){ /*string[]*/
118                        // There must be a better way than
119                        // to execute a regex on *every*
120                        // item in the store.
121
122                        var results = [ this.DEFAULT_NAMESPACE];
123
124                        var found = {};
125                        found[this.DEFAULT_NAMESPACE] = true;
126                        var tester = /^__([^_]*)_/;
127
128                        for(var i = 0; i < this.store.length; i++){
129                                var currentKey = this.store.key(i);
130                                if(tester.test(currentKey) == true){
131                                        var currentNS = currentKey.match(tester)[1];
132                                        if(typeof found[currentNS] == "undefined"){
133                                                found[currentNS] = true;
134                                                results.push(currentNS);
135                                        }
136                                }
137                        }
138
139                        return results;
140                },
141
142                isPermanent: function(){ /*Boolean*/
143                        return true;
144                },
145
146                getMaximumSize: function(){ /* mixed */
147                        return dojox.storage.SIZE_NO_LIMIT;
148                },
149
150                hasSettingsUI: function(){ /*Boolean*/
151                        return false;
152                },
153
154                isValidKey: function(/*string*/ keyName){ /*Boolean*/
155                        if(keyName === null || keyName === undefined){
156                                return false;
157                        }
158
159                        return /^[0-9A-Za-z_-]*$/.test(keyName);
160                },
161
162                isValidNamespace: function(/*string*/ keyName){ /*Boolean*/
163                        // we *must* prevent namespaces from having
164                        // underscores - else lookup of namespaces
165                        // via RegEx (e.g. in getNamespaces ) would
166                        // return wrong results.
167                        //
168                        // The only way around this would be to
169                        // disallow underscores in keys.
170
171                        if(keyName === null || keyName === undefined){
172                                return false;
173                        }
174
175                        return /^[0-9A-Za-z-]*$/.test(keyName);
176                },
177
178                getFullKey: function(key, namespace){
179                        // checks for valid namespace and
180                        // key are already performed.
181                        return "__" + namespace + "_" + key;
182                },
183
184                _beginsWith: function(/* string */ haystack, /* string */ needle) {
185                        if(needle.length > haystack.length) {
186                                return false;
187                        }
188                        return haystack.substring(0,needle.length) === needle;
189                },
190
191                _assertIsValidNamespace: function(/* string */ namespace){
192                        if(this.isValidNamespace(namespace) === false){
193                                throw new Error("Invalid namespace given: " + namespace);
194                        }
195                },
196
197                _assertIsValidKey: function(/* string */ key){
198                        if(this.isValidKey(key) === false){
199                                throw new Error("Invalid key given: " + key);
200                        }
201                }
202        }
203);
204
205dojox.storage.manager.register("dojox.storage.LocalStorageProvider", new dojox.storage.LocalStorageProvider());
Note: See TracBrowser for help on using the repository browser.