Blame | Last modification | View Log | RSS feed
import DojoExternalInterface;class Storage {public static var SUCCESS = "success";public static var FAILED = "failed";public static var PENDING = "pending";// Wait the following number of milliseconds before flushingpublic static var FLUSH_DELAY_DEFAULT = 500;public var flush_delay;public var so;public var timer;private var _NAMESPACE_KEY = "allNamespaces";public function Storage(){flush_delay = Storage.FLUSH_DELAY_DEFAULT;//getURL("javascript:console.debug('FLASH:Storage constructor')");DojoExternalInterface.initialize();DojoExternalInterface.addCallback("put", this, put);DojoExternalInterface.addCallback("putMultiple", this, putMultiple);DojoExternalInterface.addCallback("get", this, get);DojoExternalInterface.addCallback("getMultiple", this, getMultiple);DojoExternalInterface.addCallback("showSettings", this, showSettings);DojoExternalInterface.addCallback("clear", this, clear);DojoExternalInterface.addCallback("getKeys", this, getKeys);DojoExternalInterface.addCallback("getNamespaces", this, getNamespaces);DojoExternalInterface.addCallback("remove", this, remove);DojoExternalInterface.addCallback("removeMultiple", this, removeMultiple);DojoExternalInterface.addCallback("flush", this, flush);DojoExternalInterface.addCallback("setFlushDelay", this, setFlushDelay);DojoExternalInterface.addCallback("getFlushDelay", this, getFlushDelay);DojoExternalInterface.loaded();// preload the System Settings finished button movie for offline// access so it is in the cache_root.createEmptyMovieClip("_settingsBackground", 1);// getURL("javascript:alert('"+DojoExternalInterface.dojoPath+"');");_root._settingsBackground.loadMovie(DojoExternalInterface.dojoPath + "storage_dialog.swf");}// Set a new value for the flush delay timer.// Possible values:// 0 : Perform the flush synchronously after each "put" request// > 0 : Wait until 'newDelay' ms have passed without any "put" request to flush// -1 : Do not automatically flushpublic function setFlushDelay(newDelay){flush_delay = Number(newDelay);}public function getFlushDelay(){return String(flush_delay);}public function flush(namespace){if(timer){_global.clearTimeout(timer);delete timer;}var so = SharedObject.getLocal(namespace);//var st = (new Date()).getTime();var flushResults = so.flush();//var end = (new Date()).getTime();//getURL("javascript:dojo.debug('FLASH: flush - not a word game - took " + (end - st) + "ms')");// return results of this command to JavaScriptvar statusResults;if(flushResults == true){statusResults = Storage.SUCCESS;}else if(flushResults == "pending"){statusResults = Storage.PENDING;}else{statusResults = Storage.FAILED;}DojoExternalInterface.call("dojox.storage._onStatus", null, statusResults, null);}// FIXME: This code has gotten ugly -- refactorpublic function put(keyName, keyValue, namespace){// Get the SharedObject for these values and save itso = SharedObject.getLocal(namespace);// Save the key and valueso.data[keyName] = keyValue;// Do all the flush/no-flush stuffvar keyNames = new Array(); keyNames[0] = keyName;postWrite( so, keyNames, namespace);}public function putMultiple(metaKey, metaValue, metaLengths, namespace){// Get the SharedObject for these values and save itso = SharedObject.getLocal(namespace);// Create array of keys and value lengthsvar keys = metaKey.split(",");var lengths = metaLengths.split(",");// Loop through the array and write the valuesfor(var i=0;i<keys.length;i++){so.data[keys[i]] = metaValue.slice(0,lengths[i]);metaValue = metaValue.slice(lengths[i]);}// Do all the flush/no-flush stuffpostWrite( so, keys, namespace);}public function postWrite( so, keyNames, namespace){// TODO: Review all this 'handler' stuff. In particular, the flush could now be with keys pending// from several different requests, not only the ones passed in this method call// prepare a storage status handlervar self = this;so.onStatus = function(infoObject:Object){//getURL("javascript:console.debug('FLASH: onStatus, infoObject="+infoObject.code+"')");// delete the data value if the request was deniedif(infoObject.code == "SharedObject.Flush.Failed"){for(var i=0;i<keyNames.length;i++){delete self.so.data[keyNames[i]];}}var statusResults;if(infoObject.code == "SharedObject.Flush.Failed"){statusResults = Storage.FAILED;}else if(infoObject.code == "SharedObject.Flush.Pending"){statusResults = Storage.PENDING;}else if(infoObject.code == "SharedObject.Flush.Success"){// if we have succeeded saving our value, see if we// need to update our list of namespacesif(self.hasNamespace(namespace) == true){statusResults = Storage.SUCCESS;}else{// we have a new namespace we must storeself.addNamespace(namespace, keyNames[0]);return;}}//getURL("javascript:console.debug('FLASH: onStatus, statusResults="+statusResults+"')");// give the status results to JavaScriptDojoExternalInterface.call("dojox.storage._onStatus", null, statusResults, keyNames[0]);}// Clear any pending flush timersif(timer){//getURL("javascript:dojo.debug('FLASH: clearing timer')");_global.clearTimeout( timer);}// If we have a flush delay set, set a timer for its executionif(flush_delay > 0){timer = _global.setTimeout( flush, flush_delay, namespace);// With a flush_delay value of 0, execute the flush request synchronously}else if(flush_delay == 0){//getURL("javascript:dojo.debug('FLASH: calling flush now')");flush(namespace);}// Otherwise just don't flush - will be probably be flushed manually}public function get(keyName, namespace){// Get the SharedObject for these values and save itso = SharedObject.getLocal(namespace);var results = so.data[keyName];return results;}// Returns an array with the contents of each key value on the metaKeys arraypublic function getMultiple(metaKeys, namespace){// get the storage objectso = SharedObject.getLocal(namespace);// Create array of keys to readvar keys = metaKeys.split(",");var results = new Array();// Read from storage into results arrayfor(var i=0;i<keys.length;i++){var val = so.data[keys[i]];val = val.split("\\").join("\\\\");val = val.split('"').join('\\"');results.push( val);}// Make the results array into a stringvar metaResults = '["' + results.join('","') + '"]';return metaResults;}public function showSettings(){// Show the configuration options for the Flash player, opened to the// section for local storage controls (pane 1)System.showSettings(1);// there is no way we can intercept when the Close button is pressed, allowing us// to hide the Flash dialog. Instead, we need to load a movie in the// background that we can show a close button on._root.createEmptyMovieClip("_settingsBackground", 1);_root._settingsBackground.loadMovie(DojoExternalInterface.dojoPath + "storage_dialog.swf");}public function clear(namespace){so = SharedObject.getLocal(namespace);so.clear();so.flush();// remove this namespace entry nowremoveNamespace(namespace);}public function getKeys(namespace){// Returns a list of the available keys in this namespace// get the storage objectso = SharedObject.getLocal(namespace);// get all of the keysvar results = new Array();for(var i in so.data){results.push(i);}// remove our key that records our list of namespacesfor(var i = 0; i < results.length; i++){if(results[i] == _NAMESPACE_KEY){results.splice(i, 1);break;}}// join the keys together in a comma seperated stringresults = results.join(",");return results;}public function getNamespaces(){var allNamespaces = SharedObject.getLocal(_NAMESPACE_KEY);var results = new Array();for(var i in allNamespaces.data){results.push(i);}return results.join(",");}public function remove(keyName, namespace){// Removes a key// get the storage objectso = SharedObject.getLocal(namespace);// delete this valuedelete so.data[keyName];// save the changesso.flush();// see if we are the last entry for this namespacevar availableKeys = getKeys(namespace);if(availableKeys == ""){// we are emptyremoveNamespace(namespace);}}// Removes all the values for each keys on the metaKeys arraypublic function removeMultiple(metaKeys, namespace){// get the storage objectso = SharedObject.getLocal(namespace);// Create array of keys to readvar keys = metaKeys.split(",");var results = new Array();// Delete elementsfor(var i=0;i<keys.length;i++){delete so.data[keys[i]];}// see if there are no more entries for this namespacevar availableKeys = getKeys(namespace);if(availableKeys == ""){// we are emptyremoveNamespace(namespace);}}private function hasNamespace(namespace):Boolean{// Get the SharedObject for the namespace listvar allNamespaces = SharedObject.getLocal(_NAMESPACE_KEY);var results = false;for(var i in allNamespaces.data){if(i == namespace){results = true;break;}}return results;}// FIXME: This code has gotten ugly -- refactorprivate function addNamespace(namespace, keyName){if(hasNamespace(namespace) == true){return;}// Get the SharedObject for the namespace listvar allNamespaces = SharedObject.getLocal(_NAMESPACE_KEY);// prepare a storage status handler if the keyName is// not nullif(keyName != null && typeof keyName != "undefined"){var self = this;allNamespaces.onStatus = function(infoObject:Object){// delete the data value if the request was deniedif(infoObject.code == "SharedObject.Flush.Failed"){delete self.so.data[keyName];}var statusResults;if(infoObject.code == "SharedObject.Flush.Failed"){statusResults = Storage.FAILED;}else if(infoObject.code == "SharedObject.Flush.Pending"){statusResults = Storage.PENDING;}else if(infoObject.code == "SharedObject.Flush.Success"){statusResults = Storage.SUCCESS;}// give the status results to JavaScriptDojoExternalInterface.call("dojox.storage._onStatus", null, statusResults, keyName);}}// save the namespace listallNamespaces.data[namespace] = true;var flushResults = allNamespaces.flush();// return results of this command to JavaScriptif(keyName != null && typeof keyName != "undefined"){var statusResults;if(flushResults == true){statusResults = Storage.SUCCESS;}else if(flushResults == "pending"){statusResults = Storage.PENDING;}else{statusResults = Storage.FAILED;}DojoExternalInterface.call("dojox.storage._onStatus", null, statusResults, keyName);}}// FIXME: This code has gotten ugly -- refactorprivate function removeNamespace(namespace){if(hasNamespace(namespace) == false){return;}// try to save the namespace list; don't have a return// callback; if we fail on this, the worst that will happen// is that we have a spurious namespace entryvar allNamespaces = SharedObject.getLocal(_NAMESPACE_KEY);delete allNamespaces.data[namespace];allNamespaces.flush();}static function main(mc){//getURL("javascript:console.debug('FLASH: storage loaded')");_root.app = new Storage();}}