/** * 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(/