PageRenderTime 20ms CodeModel.GetById 30ms RepoModel.GetById 0ms app.codeStats 0ms

/ZendFramework/externals/dojo/dojox/storage/Storage.as

https://bitbucket.org/Dal-Papa/is-340-publish-base
ActionScript | 402 lines | 322 code | 35 blank | 45 comment | 22 complexity | 0d27ab0c54acf102538bb063c6af67e7 MD5 | raw file
  1. import DojoExternalInterface;
  2. class Storage{
  3. public static var SUCCESS = "success";
  4. public static var FAILED = "failed";
  5. public static var PENDING = "pending";
  6. // Wait the following number of milliseconds before flushing
  7. public static var FLUSH_DELAY_DEFAULT = 500;
  8. public var flush_delay;
  9. public var so;
  10. public var timer;
  11. private var _NAMESPACE_KEY = "allNamespaces";
  12. public function Storage(){
  13. flush_delay = Storage.FLUSH_DELAY_DEFAULT;
  14. DojoExternalInterface.initialize();
  15. DojoExternalInterface.addCallback("put", this, put);
  16. DojoExternalInterface.addCallback("putMultiple", this, putMultiple);
  17. DojoExternalInterface.addCallback("get", this, get);
  18. DojoExternalInterface.addCallback("getMultiple", this, getMultiple);
  19. DojoExternalInterface.addCallback("showSettings", this, showSettings);
  20. DojoExternalInterface.addCallback("clear", this, clear);
  21. DojoExternalInterface.addCallback("getKeys", this, getKeys);
  22. DojoExternalInterface.addCallback("getNamespaces", this, getNamespaces);
  23. DojoExternalInterface.addCallback("remove", this, remove);
  24. DojoExternalInterface.addCallback("removeMultiple", this, removeMultiple);
  25. DojoExternalInterface.addCallback("flush", this, flush);
  26. DojoExternalInterface.addCallback("setFlushDelay", this, setFlushDelay);
  27. DojoExternalInterface.addCallback("getFlushDelay", this, getFlushDelay);
  28. DojoExternalInterface.loaded();
  29. // preload the System Settings finished button movie for offline
  30. // access so it is in the cache
  31. _root.createEmptyMovieClip("_settingsBackground", 1);
  32. _root._settingsBackground.loadMovie(DojoExternalInterface.dojoPath
  33. + "../dojox/storage/storage_dialog.swf");
  34. }
  35. // FIXME: Whoever added this Flush code did not document why it
  36. // exists. Please also put your name and a bug number so I know
  37. // who to contact. -- Brad Neuberg
  38. // Set a new value for the flush delay timer.
  39. // Possible values:
  40. // 0 : Perform the flush synchronously after each "put" request
  41. // > 0 : Wait until 'newDelay' ms have passed without any "put" request to flush
  42. // -1 : Do not automatically flush
  43. public function setFlushDelay(newDelay){
  44. flush_delay = Number(newDelay);
  45. }
  46. public function getFlushDelay(){
  47. return String(flush_delay);
  48. }
  49. public function flush(namespace){
  50. if(timer){
  51. _global.clearTimeout(timer);
  52. delete timer;
  53. }
  54. var so = SharedObject.getLocal(namespace);
  55. var flushResults = so.flush();
  56. // return results of this command to JavaScript
  57. var statusResults;
  58. if(flushResults == true){
  59. statusResults = Storage.SUCCESS;
  60. }else if(flushResults == "pending"){
  61. statusResults = Storage.PENDING;
  62. }else{
  63. statusResults = Storage.FAILED;
  64. }
  65. DojoExternalInterface.call("dojox.storage._onStatus", statusResults,
  66. null, namespace);
  67. }
  68. public function put(keyName, keyValue, namespace){
  69. // Get the SharedObject for these values and save it
  70. so = SharedObject.getLocal(namespace);
  71. // Save the key and value
  72. so.data[keyName] = keyValue;
  73. // Save the namespace
  74. // FIXME: Tie this into the flush/no-flush stuff below; right now
  75. // we immediately write out this namespace. -- Brad Neuberg
  76. addNamespace(namespace, keyName);
  77. // Do all the flush/no-flush stuff
  78. var keyNames = new Array();
  79. keyNames[0] = keyName;
  80. postWrite(so, keyNames, namespace);
  81. }
  82. public function putMultiple(metaKey, metaValue, metaLengths, namespace){
  83. // Get the SharedObject for these values and save it
  84. so = SharedObject.getLocal(namespace);
  85. // Create array of keys and value lengths
  86. var keys = metaKey.split(",");
  87. var lengths = metaLengths.split(",");
  88. // Loop through the array and write the values
  89. for(var i = 0; i < keys.length; i++){
  90. so.data[keys[i]] = metaValue.slice(0,lengths[i]);
  91. metaValue = metaValue.slice(lengths[i]);
  92. }
  93. // Save the namespace
  94. // FIXME: Tie this into the flush/no-flush stuff below; right now
  95. // we immediately write out this namespace. -- Brad Neuberg
  96. addNamespace(namespace, null);
  97. // Do all the flush/no-flush stuff
  98. postWrite(so, keys, namespace);
  99. }
  100. public function postWrite(so, keyNames, namespace){
  101. // TODO: Review all this 'handler' stuff. In particular, the flush
  102. // could now be with keys pending from several different requests, not
  103. // only the ones passed in this method call
  104. // prepare a storage status handler
  105. var self = this;
  106. so.onStatus = function(infoObject:Object){
  107. //trace("onStatus, infoObject="+infoObject.code);
  108. // delete the data value if the request was denied
  109. if(infoObject.code == "SharedObject.Flush.Failed"){
  110. for(var i=0;i<keyNames.length;i++){
  111. delete self.so.data[keyNames[i]];
  112. }
  113. }
  114. var statusResults;
  115. if(infoObject.code == "SharedObject.Flush.Failed"){
  116. statusResults = Storage.FAILED;
  117. }else if(infoObject.code == "SharedObject.Flush.Pending"){
  118. statusResults = Storage.PENDING;
  119. }else if(infoObject.code == "SharedObject.Flush.Success"){
  120. // if we have succeeded saving our value, see if we
  121. // need to update our list of namespaces
  122. if(self.hasNamespace(namespace) == true){
  123. statusResults = Storage.SUCCESS;
  124. }else{
  125. // we have a new namespace we must store
  126. self.addNamespace(namespace, keyNames[0]);
  127. return;
  128. }
  129. }
  130. //trace("onStatus, statusResults="+statusResults);
  131. // give the status results to JavaScript
  132. DojoExternalInterface.call("dojox.storage._onStatus", statusResults,
  133. keyNames[0], namespace);
  134. }
  135. // Clear any pending flush timers
  136. if(timer){
  137. _global.clearTimeout(timer);
  138. }
  139. // If we have a flush delay set, set a timer for its execution
  140. if(flush_delay > 0){
  141. timer = _global.setTimeout(flush, flush_delay, namespace);
  142. // With a flush_delay value of 0, execute the flush request synchronously
  143. }else if(flush_delay == 0){
  144. flush(namespace);
  145. }
  146. // Otherwise just don't flush - will be probably be flushed manually
  147. }
  148. public function get(keyName, namespace){
  149. // Get the SharedObject for these values and save it
  150. so = SharedObject.getLocal(namespace);
  151. var results = so.data[keyName];
  152. return results;
  153. }
  154. // Returns an array with the contents of each key value on the metaKeys array
  155. public function getMultiple(metaKeys, namespace){
  156. // get the storage object
  157. so = SharedObject.getLocal(namespace);
  158. // Create array of keys to read
  159. var keys = metaKeys.split(",");
  160. var results = new Array();
  161. // Read from storage into results array
  162. for(var i = 0;i < keys.length;i++){
  163. var val = so.data[keys[i]];
  164. val = val.split("\\").join("\\\\");
  165. val = val.split('"').join('\\"');
  166. results.push( val);
  167. }
  168. // Make the results array into a string
  169. var metaResults = '["' + results.join('","') + '"]';
  170. return metaResults;
  171. }
  172. public function showSettings(){
  173. // Show the configuration options for the Flash player, opened to the
  174. // section for local storage controls (pane 1)
  175. System.showSettings(1);
  176. // there is no way we can intercept when the Close button is pressed, allowing us
  177. // to hide the Flash dialog. Instead, we need to load a movie in the
  178. // background that we can show a close button on.
  179. _root.createEmptyMovieClip("_settingsBackground", 1);
  180. _root._settingsBackground.loadMovie(DojoExternalInterface.dojoPath
  181. + "../dojox/storage/storage_dialog.swf");
  182. }
  183. public function clear(namespace){
  184. so = SharedObject.getLocal(namespace);
  185. so.clear();
  186. so.flush();
  187. // remove this namespace entry now
  188. removeNamespace(namespace);
  189. }
  190. public function getKeys(namespace) : String{
  191. // Returns a list of the available keys in this namespace
  192. // get the storage object
  193. so = SharedObject.getLocal(namespace);
  194. // get all of the keys
  195. var results = [];
  196. for(var i in so.data){
  197. results.push(i);
  198. }
  199. // remove our key that records our list of namespaces
  200. for(var i = 0; i < results.length; i++){
  201. if(results[i] == _NAMESPACE_KEY){
  202. results.splice(i, 1);
  203. break;
  204. }
  205. }
  206. // a bug in ExternalInterface transforms Arrays into
  207. // Strings, so we can't use those here! -- BradNeuberg
  208. results = results.join(",");
  209. return results;
  210. }
  211. public function getNamespaces() : String{
  212. var allNamespaces = SharedObject.getLocal(_NAMESPACE_KEY);
  213. var results = [];
  214. for(var i in allNamespaces.data){
  215. results.push(i);
  216. }
  217. // a bug in ExternalInterface transforms Arrays into
  218. // Strings, so we can use those here! -- BradNeuberg
  219. results = results.join(",");
  220. return results;
  221. }
  222. public function remove(keyName, namespace){
  223. // Removes a key
  224. // get the storage object
  225. so = SharedObject.getLocal(namespace);
  226. // delete this value
  227. delete so.data[keyName];
  228. // save the changes
  229. so.flush();
  230. // see if we are the last entry for this namespace
  231. var availableKeys = getKeys(namespace);
  232. if(availableKeys == ""){
  233. // we are empty
  234. removeNamespace(namespace);
  235. }
  236. }
  237. // Removes all the values for each keys on the metaKeys array
  238. public function removeMultiple(metaKeys, namespace){
  239. // get the storage object
  240. so = SharedObject.getLocal(namespace);
  241. // Create array of keys to read
  242. var keys = metaKeys.split(",");
  243. var results = new Array();
  244. // Delete elements
  245. for(var i=0;i<keys.length;i++){
  246. delete so.data[keys[i]];
  247. }
  248. // see if there are no more entries for this namespace
  249. var availableKeys = getKeys(namespace);
  250. if(availableKeys == ""){
  251. // we are empty
  252. removeNamespace(namespace);
  253. }
  254. }
  255. private function hasNamespace(namespace):Boolean{
  256. // Get the SharedObject for the namespace list
  257. var allNamespaces = SharedObject.getLocal(_NAMESPACE_KEY);
  258. var results = false;
  259. for(var i in allNamespaces.data){
  260. if(i == namespace){
  261. results = true;
  262. break;
  263. }
  264. }
  265. return results;
  266. }
  267. // FIXME: This code has gotten ugly -- refactor
  268. private function addNamespace(namespace, keyName){
  269. if(hasNamespace(namespace) == true){
  270. return;
  271. }
  272. // Get the SharedObject for the namespace list
  273. var allNamespaces = SharedObject.getLocal(_NAMESPACE_KEY);
  274. // prepare a storage status handler if the keyName is
  275. // not null
  276. if(keyName != null && typeof keyName != "undefined"){
  277. var self = this;
  278. allNamespaces.onStatus = function(infoObject:Object){
  279. // delete the data value if the request was denied
  280. if(infoObject.code == "SharedObject.Flush.Failed"){
  281. delete self.so.data[keyName];
  282. }
  283. var statusResults;
  284. if(infoObject.code == "SharedObject.Flush.Failed"){
  285. statusResults = Storage.FAILED;
  286. }else if(infoObject.code == "SharedObject.Flush.Pending"){
  287. statusResults = Storage.PENDING;
  288. }else if(infoObject.code == "SharedObject.Flush.Success"){
  289. statusResults = Storage.SUCCESS;
  290. }
  291. // give the status results to JavaScript
  292. DojoExternalInterface.call("dojox.storage._onStatus", statusResults,
  293. keyName, namespace);
  294. }
  295. }
  296. // save the namespace list
  297. allNamespaces.data[namespace] = true;
  298. var flushResults = allNamespaces.flush();
  299. // return results of this command to JavaScript
  300. if(keyName != null && typeof keyName != "undefined"){
  301. var statusResults;
  302. if(flushResults == true){
  303. statusResults = Storage.SUCCESS;
  304. }else if(flushResults == "pending"){
  305. statusResults = Storage.PENDING;
  306. }else{
  307. statusResults = Storage.FAILED;
  308. }
  309. DojoExternalInterface.call("dojox.storage._onStatus", statusResults,
  310. keyName, namespace);
  311. }
  312. }
  313. // FIXME: This code has gotten ugly -- refactor
  314. private function removeNamespace(namespace){
  315. if(hasNamespace(namespace) == false){
  316. return;
  317. }
  318. // try to save the namespace list; don't have a return
  319. // callback; if we fail on this, the worst that will happen
  320. // is that we have a spurious namespace entry
  321. var allNamespaces = SharedObject.getLocal(_NAMESPACE_KEY);
  322. delete allNamespaces.data[namespace];
  323. allNamespaces.flush();
  324. }
  325. static function main(mc){
  326. _root.app = new Storage();
  327. }
  328. }