2150 |
mathias |
1 |
if(!dojo._hasResource["dojox.storage.manager"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
|
|
|
2 |
dojo._hasResource["dojox.storage.manager"] = true;
|
|
|
3 |
dojo.provide("dojox.storage.manager");
|
|
|
4 |
//dojo.require("dojo.AdapterRegistry");
|
|
|
5 |
// FIXME: refactor this to use an AdapterRegistry
|
|
|
6 |
|
|
|
7 |
dojox.storage.manager = new function(){
|
|
|
8 |
// summary: A singleton class in charge of the dojox.storage system
|
|
|
9 |
// description:
|
|
|
10 |
// Initializes the storage systems and figures out the best available
|
|
|
11 |
// storage options on this platform.
|
|
|
12 |
|
|
|
13 |
// currentProvider: Object
|
|
|
14 |
// The storage provider that was automagically chosen to do storage
|
|
|
15 |
// on this platform, such as dojox.storage.FlashStorageProvider.
|
|
|
16 |
this.currentProvider = null;
|
|
|
17 |
|
|
|
18 |
// available: Boolean
|
|
|
19 |
// Whether storage of some kind is available.
|
|
|
20 |
this.available = false;
|
|
|
21 |
|
|
|
22 |
this._initialized = false;
|
|
|
23 |
|
|
|
24 |
this._providers = [];
|
|
|
25 |
this._onLoadListeners = [];
|
|
|
26 |
|
|
|
27 |
this.initialize = function(){
|
|
|
28 |
// summary:
|
|
|
29 |
// Initializes the storage system and autodetects the best storage
|
|
|
30 |
// provider we can provide on this platform
|
|
|
31 |
this.autodetect();
|
|
|
32 |
};
|
|
|
33 |
|
|
|
34 |
this.register = function(/*string*/ name, /*Object*/ instance){
|
|
|
35 |
// summary:
|
|
|
36 |
// Registers the existence of a new storage provider; used by
|
|
|
37 |
// subclasses to inform the manager of their existence. The
|
|
|
38 |
// storage manager will select storage providers based on
|
|
|
39 |
// their ordering, so the order in which you call this method
|
|
|
40 |
// matters.
|
|
|
41 |
// name:
|
|
|
42 |
// The full class name of this provider, such as
|
|
|
43 |
// "dojox.storage.FlashStorageProvider".
|
|
|
44 |
// instance:
|
|
|
45 |
// An instance of this provider, which we will use to call
|
|
|
46 |
// isAvailable() on.
|
|
|
47 |
this._providers[this._providers.length] = instance; //FIXME: push?
|
|
|
48 |
this._providers[name] = instance; // FIXME: this._providers is an array, not a hash
|
|
|
49 |
};
|
|
|
50 |
|
|
|
51 |
this.setProvider = function(storageClass){
|
|
|
52 |
// summary:
|
|
|
53 |
// Instructs the storageManager to use the given storage class for
|
|
|
54 |
// all storage requests.
|
|
|
55 |
// description:
|
|
|
56 |
// Example-
|
|
|
57 |
// dojox.storage.setProvider(
|
|
|
58 |
// dojox.storage.IEStorageProvider)
|
|
|
59 |
|
|
|
60 |
};
|
|
|
61 |
|
|
|
62 |
this.autodetect = function(){
|
|
|
63 |
// summary:
|
|
|
64 |
// Autodetects the best possible persistent storage provider
|
|
|
65 |
// available on this platform.
|
|
|
66 |
|
|
|
67 |
//console.debug("dojox.storage.manager.autodetect");
|
|
|
68 |
|
|
|
69 |
if(this._initialized){ // already finished
|
|
|
70 |
//console.debug("dojox.storage.manager already initialized; returning");
|
|
|
71 |
return;
|
|
|
72 |
}
|
|
|
73 |
|
|
|
74 |
// a flag to force the storage manager to use a particular
|
|
|
75 |
// storage provider type, such as
|
|
|
76 |
// djConfig = {forceStorageProvider: "dojox.storage.WhatWGStorageProvider"};
|
|
|
77 |
var forceProvider = djConfig["forceStorageProvider"]||false;
|
|
|
78 |
|
|
|
79 |
// go through each provider, seeing if it can be used
|
|
|
80 |
var providerToUse;
|
|
|
81 |
//FIXME: use dojo.some
|
|
|
82 |
for(var i = 0; i < this._providers.length; i++){
|
|
|
83 |
providerToUse = this._providers[i];
|
|
|
84 |
if(forceProvider == providerToUse.declaredClass){
|
|
|
85 |
// still call isAvailable for this provider, since this helps some
|
|
|
86 |
// providers internally figure out if they are available
|
|
|
87 |
// FIXME: This should be refactored since it is non-intuitive
|
|
|
88 |
// that isAvailable() would initialize some state
|
|
|
89 |
providerToUse.isAvailable();
|
|
|
90 |
break;
|
|
|
91 |
}else if(providerToUse.isAvailable()){
|
|
|
92 |
break;
|
|
|
93 |
}
|
|
|
94 |
}
|
|
|
95 |
|
|
|
96 |
if(!providerToUse){ // no provider available
|
|
|
97 |
this._initialized = true;
|
|
|
98 |
this.available = false;
|
|
|
99 |
this.currentProvider = null;
|
|
|
100 |
console.warn("No storage provider found for this platform");
|
|
|
101 |
this.loaded();
|
|
|
102 |
return;
|
|
|
103 |
}
|
|
|
104 |
|
|
|
105 |
// create this provider and mix in it's properties
|
|
|
106 |
// so that developers can do dojox.storage.put rather
|
|
|
107 |
// than dojox.storage.currentProvider.put, for example
|
|
|
108 |
this.currentProvider = providerToUse;
|
|
|
109 |
dojo.mixin(dojox.storage, this.currentProvider);
|
|
|
110 |
|
|
|
111 |
// have the provider initialize itself
|
|
|
112 |
dojox.storage.initialize();
|
|
|
113 |
|
|
|
114 |
this._initialized = true;
|
|
|
115 |
this.available = true;
|
|
|
116 |
};
|
|
|
117 |
|
|
|
118 |
this.isAvailable = function(){ /*Boolean*/
|
|
|
119 |
// summary: Returns whether any storage options are available.
|
|
|
120 |
return this.available;
|
|
|
121 |
};
|
|
|
122 |
|
|
|
123 |
this.addOnLoad = function(func){ /* void */
|
|
|
124 |
// summary:
|
|
|
125 |
// Adds an onload listener to know when Dojo Offline can be used.
|
|
|
126 |
// description:
|
|
|
127 |
// Adds a listener to know when Dojo Offline can be used. This
|
|
|
128 |
// ensures that the Dojo Offline framework is loaded and that the
|
|
|
129 |
// local dojox.storage system is ready to be used. This method is
|
|
|
130 |
// useful if you don't want to have a dependency on Dojo Events
|
|
|
131 |
// when using dojox.storage.
|
|
|
132 |
// func: Function
|
|
|
133 |
// A function to call when Dojo Offline is ready to go
|
|
|
134 |
this._onLoadListeners.push(func);
|
|
|
135 |
|
|
|
136 |
if(this.isInitialized()){
|
|
|
137 |
this._fireLoaded();
|
|
|
138 |
}
|
|
|
139 |
};
|
|
|
140 |
|
|
|
141 |
this.removeOnLoad = function(func){ /* void */
|
|
|
142 |
// summary: Removes the given onLoad listener
|
|
|
143 |
for(var i = 0; i < this._onLoadListeners.length; i++){
|
|
|
144 |
if(func == this._onLoadListeners[i]){
|
|
|
145 |
this._onLoadListeners = this._onLoadListeners.splice(i, 1);
|
|
|
146 |
break;
|
|
|
147 |
}
|
|
|
148 |
}
|
|
|
149 |
};
|
|
|
150 |
|
|
|
151 |
this.isInitialized = function(){ /*Boolean*/
|
|
|
152 |
// summary:
|
|
|
153 |
// Returns whether the storage system is initialized and ready to
|
|
|
154 |
// be used.
|
|
|
155 |
|
|
|
156 |
// FIXME: This should REALLY not be in here, but it fixes a tricky
|
|
|
157 |
// Flash timing bug
|
|
|
158 |
if(this.currentProvider != null
|
|
|
159 |
&& this.currentProvider.declaredClass == "dojox.storage.FlashStorageProvider"
|
|
|
160 |
&& dojox.flash.ready == false){
|
|
|
161 |
return false;
|
|
|
162 |
}else{
|
|
|
163 |
return this._initialized;
|
|
|
164 |
}
|
|
|
165 |
};
|
|
|
166 |
|
|
|
167 |
this.supportsProvider = function(/*string*/ storageClass){ /* Boolean */
|
|
|
168 |
// summary: Determines if this platform supports the given storage provider.
|
|
|
169 |
// description:
|
|
|
170 |
// Example-
|
|
|
171 |
// dojox.storage.manager.supportsProvider(
|
|
|
172 |
// "dojox.storage.InternetExplorerStorageProvider");
|
|
|
173 |
|
|
|
174 |
// construct this class dynamically
|
|
|
175 |
try{
|
|
|
176 |
// dynamically call the given providers class level isAvailable()
|
|
|
177 |
// method
|
|
|
178 |
var provider = eval("new " + storageClass + "()");
|
|
|
179 |
var results = provider.isAvailable();
|
|
|
180 |
if(!results){ return false; }
|
|
|
181 |
return results;
|
|
|
182 |
}catch(e){
|
|
|
183 |
return false;
|
|
|
184 |
}
|
|
|
185 |
};
|
|
|
186 |
|
|
|
187 |
this.getProvider = function(){ /* Object */
|
|
|
188 |
// summary: Gets the current provider
|
|
|
189 |
return this.currentProvider;
|
|
|
190 |
};
|
|
|
191 |
|
|
|
192 |
this.loaded = function(){
|
|
|
193 |
// summary:
|
|
|
194 |
// The storage provider should call this method when it is loaded
|
|
|
195 |
// and ready to be used. Clients who will use the provider will
|
|
|
196 |
// connect to this method to know when they can use the storage
|
|
|
197 |
// system. You can either use dojo.connect to connect to this
|
|
|
198 |
// function, or can use dojox.storage.manager.addOnLoad() to add
|
|
|
199 |
// a listener that does not depend on the dojo.event package.
|
|
|
200 |
// description:
|
|
|
201 |
// Example 1-
|
|
|
202 |
// if(dojox.storage.manager.isInitialized() == false){
|
|
|
203 |
// dojo.connect(dojox.storage.manager, "loaded", TestStorage, "initialize");
|
|
|
204 |
// }else{
|
|
|
205 |
// dojo.connect(dojo, "loaded", TestStorage, "initialize");
|
|
|
206 |
// }
|
|
|
207 |
// Example 2-
|
|
|
208 |
// dojox.storage.manager.addOnLoad(someFunction);
|
|
|
209 |
|
|
|
210 |
|
|
|
211 |
// FIXME: we should just provide a Deferred for this. That way you
|
|
|
212 |
// don't care when this happens or has happened. Deferreds are in Base
|
|
|
213 |
this._fireLoaded();
|
|
|
214 |
};
|
|
|
215 |
|
|
|
216 |
this._fireLoaded = function(){
|
|
|
217 |
//console.debug("dojox.storage.manager._fireLoaded");
|
|
|
218 |
|
|
|
219 |
dojo.forEach(this._onLoadListeners, function(i){
|
|
|
220 |
try{
|
|
|
221 |
i();
|
|
|
222 |
}catch(e){ console.debug(e); }
|
|
|
223 |
});
|
|
|
224 |
};
|
|
|
225 |
|
|
|
226 |
this.getResourceList = function(){
|
|
|
227 |
// summary:
|
|
|
228 |
// Returns a list of whatever resources are necessary for storage
|
|
|
229 |
// providers to work.
|
|
|
230 |
// description:
|
|
|
231 |
// This will return all files needed by all storage providers for
|
|
|
232 |
// this particular environment type. For example, if we are in the
|
|
|
233 |
// browser environment, then this will return the hidden SWF files
|
|
|
234 |
// needed by the FlashStorageProvider, even if we don't need them
|
|
|
235 |
// for the particular browser we are working within. This is meant
|
|
|
236 |
// to faciliate Dojo Offline, which must retrieve all resources we
|
|
|
237 |
// need offline into the offline cache -- we retrieve everything
|
|
|
238 |
// needed, in case another browser that requires different storage
|
|
|
239 |
// mechanisms hits the local offline cache. For example, if we
|
|
|
240 |
// were to sync against Dojo Offline on Firefox 2, then we would
|
|
|
241 |
// not grab the FlashStorageProvider resources needed for Safari.
|
|
|
242 |
var results = [];
|
|
|
243 |
dojo.forEach(dojox.storage.manager._providers, function(currentProvider){
|
|
|
244 |
results = results.concat(currentProvider.getResourceList());
|
|
|
245 |
});
|
|
|
246 |
|
|
|
247 |
return results;
|
|
|
248 |
}
|
|
|
249 |
};
|
|
|
250 |
|
|
|
251 |
}
|