123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386 |
- 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 flushing
- public 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 flush
- public 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 JavaScript
- 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, null);
- }
- // FIXME: This code has gotten ugly -- refactor
- public function put(keyName, keyValue, namespace){
- // Get the SharedObject for these values and save it
- so = SharedObject.getLocal(namespace);
-
- // Save the key and value
- so.data[keyName] = keyValue;
- // Do all the flush/no-flush stuff
- var 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 it
- so = SharedObject.getLocal(namespace);
-
- // Create array of keys and value lengths
- var keys = metaKey.split(",");
- var lengths = metaLengths.split(",");
-
- // Loop through the array and write the values
- for(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 stuff
- postWrite( 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 handler
- var self = this;
- so.onStatus = function(infoObject:Object){
- //getURL("javascript:console.debug('FLASH: onStatus, infoObject="+infoObject.code+"')");
-
- // delete the data value if the request was denied
- if(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 namespaces
- if(self.hasNamespace(namespace) == true){
- statusResults = Storage.SUCCESS;
- }else{
- // we have a new namespace we must store
- self.addNamespace(namespace, keyNames[0]);
- return;
- }
- }
- //getURL("javascript:console.debug('FLASH: onStatus, statusResults="+statusResults+"')");
-
- // give the status results to JavaScript
- DojoExternalInterface.call("dojox.storage._onStatus", null, statusResults, keyNames[0]);
- }
-
- // Clear any pending flush timers
- if(timer){
- //getURL("javascript:dojo.debug('FLASH: clearing timer')");
- _global.clearTimeout( timer);
- }
-
- // If we have a flush delay set, set a timer for its execution
- if(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 it
- so = SharedObject.getLocal(namespace);
- var results = so.data[keyName];
-
- return results;
- }
-
- // Returns an array with the contents of each key value on the metaKeys array
- public function getMultiple(metaKeys, namespace){
-
- // get the storage object
- so = SharedObject.getLocal(namespace);
-
- // Create array of keys to read
- var keys = metaKeys.split(",");
- var results = new Array();
-
- // Read from storage into results array
- for(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 string
- var 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 now
- removeNamespace(namespace);
- }
-
- public function getKeys(namespace){
- // Returns a list of the available keys in this namespace
-
- // get the storage object
- so = SharedObject.getLocal(namespace);
-
- // get all of the keys
- var results = new Array();
- for(var i in so.data){
- results.push(i);
- }
-
- // remove our key that records our list of namespaces
- for(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 string
- results = 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 object
- so = SharedObject.getLocal(namespace);
-
- // delete this value
- delete so.data[keyName];
-
- // save the changes
- so.flush();
-
- // see if we are the last entry for this namespace
- var availableKeys = getKeys(namespace);
- if(availableKeys == ""){
- // we are empty
- removeNamespace(namespace);
- }
- }
-
- // Removes all the values for each keys on the metaKeys array
- public function removeMultiple(metaKeys, namespace){
-
- // get the storage object
- so = SharedObject.getLocal(namespace);
-
- // Create array of keys to read
- var keys = metaKeys.split(",");
- var results = new Array();
- // Delete elements
- for(var i=0;i<keys.length;i++){
- delete so.data[keys[i]];
- }
- // see if there are no more entries for this namespace
- var availableKeys = getKeys(namespace);
- if(availableKeys == ""){
- // we are empty
- removeNamespace(namespace);
- }
- }
-
- private function hasNamespace(namespace):Boolean{
- // Get the SharedObject for the namespace list
- var 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 -- refactor
- private function addNamespace(namespace, keyName){
- if(hasNamespace(namespace) == true){
- return;
- }
-
- // Get the SharedObject for the namespace list
- var allNamespaces = SharedObject.getLocal(_NAMESPACE_KEY);
-
- // prepare a storage status handler if the keyName is
- // not null
- if(keyName != null && typeof keyName != "undefined"){
- var self = this;
- allNamespaces.onStatus = function(infoObject:Object){
- // delete the data value if the request was denied
- if(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 JavaScript
- DojoExternalInterface.call("dojox.storage._onStatus", null, statusResults, keyName);
- }
- }
-
- // save the namespace list
- allNamespaces.data[namespace] = true;
- var flushResults = allNamespaces.flush();
-
- // return results of this command to JavaScript
- if(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 -- refactor
- private 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 entry
- var 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();
- }
- }
|