Subversion Repositories Applications.papyrus

Compare Revisions

Ignore whitespace Rev 2149 → Rev 2150

/trunk/api/js/dojo1.0/dojox/storage/Storage.as
New file
0,0 → 1,386
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();
}
}