manager.js 8.6 KB

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