/**
* The FlashProxy object is what proxies function calls between JavaScript and Flash.
* It handles all argument serialization issues.
**/
var FlashProxy = Class.create();
FlashProxy.prototype = {
/**
* Instantiates a new FlashProxy object. Pass in a uniqueID and the name (including the path)
* of the Flash proxy SWF. The ID is the same ID that needs to be passed into your Flash content as lcId.
**/
initialize: function(uid, proxySwfName) {
this.uid = uid;
this.proxySwfName = proxySwfName;
this.flashSerializer = new FlashSerializer(false);
},
/**
* Call a function in your Flash content. Arguments should be:
* 1. ActionScript function name to call,
* 2. any number of additional arguments of type object,
* array, string, number, boolean, date, null, or undefined.
**/
call: function() {
if(arguments.length == 0) {
throw new Exception("Flash Proxy Exception", "The first argument should be the function name followed by any number of additional arguments.");
}
var qs = 'lcId=' + escape(this.uid) + '&functionName=' + escape(arguments[0]);
if(arguments.length > 1) {
var justArgs = new Array();
for(var i = 1; i < arguments.length; ++i) {
justArgs.push(arguments[i]);
}
qs += ('&' + this.flashSerializer.serialize(justArgs));
}
var divName = '_flash_proxy_' + this.uid;
if(!document.getElementById(divName)) {
var newTarget = document.createElement("div");
newTarget.id = divName;
newTarget.setAttribute('style', 'position: absolute; top: 0px; left: 0px;');
document.body.appendChild(newTarget);
} else {
document.getElementById(divName).innerHTML = "";
}
var swfo = new SWFObject(this.proxySwfName + '?' + qs, 'FlashProxy', '1', '1', '6');
swfo.write(divName);
},
/**
* This is the function that proxies function calls from Flash to JavaScript.
* It is called implicitly.
**/
callJS: function() {
var functionToCall = eval(arguments[0]);
var argArray = new Array();
for(var i = 1; i < arguments.length; ++i) {
argArray.push(arguments[i]);
}
functionToCall.apply(functionToCall, argArray);
}
}
/**
* The FlashSerializer serializes JavaScript variables of types object, array, string,
* number, date, boolean, null or undefined into XML.
**/
var FlashSerializer = Class.create();
FlashSerializer.prototype = {
/**
* Create a new instance of the FlashSerializer.
* useCdata: Whether strings should be treated as character data. If false, strings are simply XML encoded.
**/
initialize: function(useCdata) {
this.useCdata = useCdata;
},
/**
* Serialize an array into a format that can be deserialized in Flash. Supported data types are object,
* array, string, number, date, boolean, null, and undefined. Returns a string of serialized data.
**/
serialize: function(args) {
var qs = new String();
for(var i = 0; i < args.length; ++i) {
switch(typeof(args[i])) {
case 'undefined':
qs += 't'+(i)+'=undf';
break;
case 'string':
qs += 't'+(i)+'=str&d'+(i)+'='+escape(args[i]);
break;
case 'number':
qs += 't'+(i)+'=num&d'+(i)+'='+escape(args[i]);
break;
case 'boolean':
qs += 't'+(i)+'=bool&d'+(i)+'='+escape(args[i]);
break;
case 'object':
if (args[i] == null) {
qs += 't'+(i)+'=null';
} else if (args[i] instanceof Date) {
qs += 't'+(i)+'=date&d'+(i)+'='+escape(args[i].getTime());
} else { // array or object
try {
qs += 't'+(i)+'=xser&d'+(i)+'='+escape(this._serializeXML(args[i]));
}
catch (exception) {
throw new Exception("FlashSerializationException", "The following error occurred during complex object serialization: " + exception.getMessage());
}
}
break;
default:
throw new Exception("FlashSerializationException", "You can only serialize strings, numbers, booleans, dates, objects, arrays, nulls, and undefined.");
}
if(i != (args.length - 1)) {
qs += '&';
}
}
return qs;
},
/**
* Private
**/
_serializeXML: function(obj) {
var doc = new Object();
doc.xml = '';
this._serializeNode(obj, doc, null);
doc.xml += '';
return doc.xml;
},
/**
* Private
**/
_serializeNode: function(obj, doc, name) {
switch(typeof(obj)) {
case 'undefined':
doc.xml += '';
break;
case 'string':
doc.xml += ''+this._escapeXml(obj)+'';
break;
case 'number':
doc.xml += ''+obj+'';
break;
case 'boolean':
doc.xml += '';
break;
case 'object':
if(obj == null) {
doc.xml += '';
} else if(obj instanceof Date) {
doc.xml += ''+obj.getTime()+'';
} else if(obj instanceof Array) {
doc.xml += '';
for(var i = 0; i < obj.length; ++i) {
this._serializeNode(obj[i], doc, null);
}
doc.xml += '';
} else {
doc.xml += '';
for(var n in obj) {
if(typeof(obj[n]) == 'function') {
continue;
}
this._serializeNode(obj[n], doc, n);
}
doc.xml += '';
}
break;
default:
throw new Exception("FlashSerializationException", "You can only serialize strings, numbers, booleans, objects, dates, arrays, nulls and undefined");
break;
}
},
/**
* Private
**/
_addName: function(name) {
if(name != null) {
return ' name="'+name+'"';
}
return '';
},
/**
* Private
**/
_escapeXml: function(str) {
if(this.useCdata) {
return '';
} else {
return str.replace(/&/g,'&').replace(/