2 A wrapper around Flash 8's ExternalInterface; this is needed
\r
3 because ExternalInterface has a number of serialization bugs that we
\r
9 import flash.external.ExternalInterface;
\r
11 class DojoExternalInterface{
\r
12 public static var available:Boolean;
\r
13 public static var dojoPath = "";
\r
15 public static function initialize(){
\r
16 //trace("DojoExternalInterface.initialize");
\r
18 // extract the dojo base path
\r
19 DojoExternalInterface.dojoPath = DojoExternalInterface.getDojoPath();
\r
21 // see if we need to do an express install
\r
22 var install:ExpressInstall = new ExpressInstall();
\r
23 if(install.needsUpdate){
\r
27 // set whether communication is available
\r
28 DojoExternalInterface.available = ExternalInterface.available;
\r
31 /** Called when we are finished adding methods through addCallback. */
\r
32 public static function done(){
\r
34 DojoExternalInterface.call("dojox.flash.loaded");
\r
37 public static function addCallback(methodName:String, instance:Object,
\r
38 method:Function):Boolean{
\r
39 //trace("addCallback");
\r
40 ExternalInterface.addCallback(methodName, instance, function(){
\r
41 instance = (instance) ? instance : null;
\r
43 if(arguments && arguments.length){
\r
44 for(var i = 0; i < arguments.length; i++){
\r
45 params[i] = DojoExternalInterface.decodeData(arguments[i]);
\r
49 var results = method.apply(instance, params);
\r
50 results = DojoExternalInterface.encodeData(results);
\r
55 // tell JavaScript about DojoExternalInterface new method so we can create a proxy
\r
56 ExternalInterface.call("dojox.flash.comm._addExternalInterfaceCallback",
\r
62 public static function call(methodName:String):Void{
\r
63 // we might have any number of optional arguments, so we have to
\r
64 // pass them in dynamically; strip out the results callback
\r
65 var parameters = new Array();
\r
66 for(var i = 0; i < arguments.length; i++){
\r
67 parameters.push(arguments[i]);
\r
70 // FIXME: Should we be encoding or decoding the data to get
\r
71 // around Flash's serialization bugs?
\r
73 var results = ExternalInterface.call.apply(ExternalInterface, parameters);
\r
79 Called by Flash to indicate to JavaScript that we are ready to have
\r
80 our Flash functions called. Calling loaded()
\r
81 will fire the dojox.flash.loaded() event, so that JavaScript can know that
\r
82 Flash has finished loading and adding its callbacks, and can begin to
\r
83 interact with the Flash file.
\r
85 public static function loaded(){
\r
86 DojoExternalInterface.call("dojox.flash.loaded");
\r
90 Utility trace implementation that prints out to console.debug.
\r
92 public static function trace(msg){
\r
93 DojoExternalInterface.call("console.debug", "FLASH: " + msg);
\r
96 private static function decodeData(data):String{
\r
97 if(!data || typeof data != "string"){
\r
101 // we have to use custom encodings for certain characters when passing
\r
102 // them over; for example, passing a backslash over as //// from JavaScript
\r
103 // to Flash doesn't work
\r
104 data = replaceStr(data, "&custom_backslash;", "\\");
\r
106 data = replaceStr(data, "\\\'", "\'");
\r
107 data = replaceStr(data, "\\\"", "\"");
\r
112 private static function encodeData(data):String{
\r
113 if(!data || typeof data != "string"){
\r
117 // certain XMLish characters break Flash's wire serialization for
\r
118 // ExternalInterface; encode these into a custom encoding, rather than
\r
119 // the standard entity encoding, because otherwise we won't be able to
\r
120 // differentiate between our own encoding and any entity characters
\r
121 // that are being used in the string itself
\r
122 data = replaceStr(data, '<', '&custom_lt;');
\r
123 data = replaceStr(data, '>', '&custom_gt;');
\r
126 data = replaceStr(data, '\\', '&custom_backslash;');
\r
128 // encode control characters and JavaScript delimiters
\r
129 data = replaceStr(data, "\n", "\\n");
\r
130 data = replaceStr(data, "\r", "\\r");
\r
131 data = replaceStr(data, "\f", "\\f");
\r
132 data = replaceStr(data, "'", "\\'");
\r
133 data = replaceStr(data, '"', '\"');
\r
139 Flash ActionScript has no String.replace method or support for
\r
140 Regular Expressions! We roll our own very simple one.
\r
142 public static function replaceStr(inputStr:String, replaceThis:String,
\r
143 withThis:String):String{
\r
144 var splitStr = inputStr.split(replaceThis);
\r
149 inputStr = splitStr.join(withThis);
\r
153 private static function getDojoPath(){
\r
154 var url = _root._url;
\r
155 var start = url.indexOf("baseUrl=") + "baseUrl=".length;
\r
156 var path = url.substring(start);
\r
157 var end = path.indexOf("&");
\r
159 path = path.substring(0, end);
\r
162 // some browsers append a junk string at the end: '%20'%20quality=
\r
163 if(path.indexOf("'%20'%20quality=") != -1){
\r
164 path = path.substring(0, path.indexOf("'%20'%20quality="));
\r