7394552a151b688487dcd3c9e1ec0aa4ee81879c.svn-base 9.0 KB

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