Blame | Last modification | View Log | RSS feed
/**An implementation of Flash 8's ExternalInterface that works with Flash 6and which is source-compatible with Flash 8.@author Brad Neuberg, bkn3@columbia.edu*/class DojoExternalInterface{public static var available:Boolean;public static var dojoPath = "";public static var _fscommandReady = false;public static var _callbacks = new Array();public static function initialize(){//getURL("javascript:console.debug('FLASH:DojoExternalInterface initialize')");// FIXME: Set available variable by testing for capabilitiesDojoExternalInterface.available = true;// extract the dojo base pathDojoExternalInterface.dojoPath = DojoExternalInterface.getDojoPath();//getURL("javascript:console.debug('FLASH:dojoPath="+DojoExternalInterface.dojoPath+"')");// Sometimes, on IE, the fscommand infrastructure can take a few hundred// milliseconds the first time a page loads. Set a timer to keep checking// to make sure we can issue fscommands; otherwise, our calls to fscommand// for setCallback() and loaded() will just "disappear"_root.fscommandReady = false;var fsChecker = function(){// issue a test fscommandfscommand("fscommandReady");// JavaScript should set _root.fscommandReady if it got the callif(_root.fscommandReady == "true"){DojoExternalInterface._fscommandReady = true;clearInterval(_root.fsTimer);}};_root.fsTimer = setInterval(fsChecker, 100);}public static function addCallback(methodName:String, instance:Object,method:Function) : Boolean{// A variable that indicates whether the call below succeeded_root._succeeded = null;// Callbacks are registered with the JavaScript side as follows.// On the Flash side, we maintain a lookup table that associates// the methodName with the actual instance and method that are// associated with this method.// Using fscommand, we send over the action "addCallback", with the// argument being the methodName to add, such as "foobar".// The JavaScript takes these values and registers the existence of// this callback point.// precede the method name with a _ character in case it starts// with a number_callbacks["_" + methodName] = {_instance: instance, _method: method};_callbacks[_callbacks.length] = methodName;// The API for ExternalInterface says we have to make sure the call// succeeded; check to see if there is a value// for _succeeded, which is set by the JavaScript sideif(_root._succeeded == null){return false;}else{return true;}}public static function call(methodName:String,resultsCallback:Function) : Void{// FIXME: support full JSON serialization// First, we pack up all of the arguments to this call and set them// as Flash variables, which the JavaScript side will unpack using// plugin.GetVariable(). We set the number of arguments as "_numArgs",// and add each argument as a variable, such as "_1", "_2", etc., starting// from 0.// We then execute an fscommand with the action "call" and the// argument being the method name. JavaScript takes the method name,// retrieves the arguments using GetVariable, executes the method,// and then places the return result in a Flash variable// named "_returnResult"._root._numArgs = arguments.length - 2;for(var i = 2; i < arguments.length; i++){var argIndex = i - 2;_root["_" + argIndex] = arguments[i];}_root._returnResult = undefined;fscommand("call", methodName);// immediately return if the caller is not waiting for return resultsif(resultsCallback == undefined || resultsCallback == null){return;}// check at regular intervals for return resultsvar resultsChecker = function(){if((typeof _root._returnResult != "undefined")&&(_root._returnResult != "undefined")){clearInterval(_root._callbackID);resultsCallback.call(null, _root._returnResult);}};_root._callbackID = setInterval(resultsChecker, 100);}/**Called by Flash to indicate to JavaScript that we are ready to haveour Flash functions called. Calling loaded()will fire the dojox.flash.loaded() event, so that JavaScript can know thatFlash has finished loading and adding its callbacks, and can begin tointeract with the Flash file.*/public static function loaded(){//getURL("javascript:console.debug('FLASH:loaded')");// one more step: see if fscommands are ready to be executed; if not,// set an interval that will keep running until fscommands are ready;// make sure the gateway is loaded as wellvar execLoaded = function(){if(DojoExternalInterface._fscommandReady == true){clearInterval(_root.loadedInterval);// initialize the small Flash file that helps gateway JS to Flash// callsDojoExternalInterface._initializeFlashRunner();}};if(_fscommandReady == true){execLoaded();}else{_root.loadedInterval = setInterval(execLoaded, 50);}}/**Handles and executes a JavaScript to Flash method call. Used byinitializeFlashRunner.*/public static function _handleJSCall(){// get our parametersvar numArgs = parseInt(_root._numArgs);var jsArgs = new Array();for(var i = 0; i < numArgs; i++){var currentValue = _root["_" + i];jsArgs.push(currentValue);}// get our function namevar functionName = _root._functionName;// now get the actual instance and method object to execute on,// using our lookup table that was constructed by calls to// addCallback on initializationvar instance = _callbacks["_" + functionName]._instance;var method = _callbacks["_" + functionName]._method;// execute itvar results = method.apply(instance, jsArgs);// return the results_root._returnResult = results;}/** Called by the flash6_gateway.swf to indicate that it is loaded. */public static function _gatewayReady(){for(var i = 0; i < _callbacks.length; i++){fscommand("addCallback", _callbacks[i]);}call("dojox.flash.loaded");}/**When JavaScript wants to communicate with Flash it simply setsthe Flash variable "_execute" to true; this method creates theinternal Movie Clip, called the Flash Runner, that makes thismagic happen.*/public static function _initializeFlashRunner(){// figure out where our Flash movie isvar swfLoc = DojoExternalInterface.dojoPath + "flash6_gateway.swf";// load our gateway helper file_root.createEmptyMovieClip("_flashRunner", 5000);_root._flashRunner._lockroot = true;_root._flashRunner.loadMovie(swfLoc);}private static function getDojoPath(){var url = _root._url;var start = url.indexOf("baseRelativePath=") + "baseRelativePath=".length;var path = url.substring(start);var end = path.indexOf("&");if(end != -1){path = path.substring(0, end);}return path;}}// vim:ts=4:noet:tw=0: