Subversion Repositories Applications.papyrus

Rev

Details | Last modification | View Log | RSS feed

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