root / trunk / web / dojo / dojox / flash / DojoExternalInterface.as
History | View | Annotate | Download (5.31 KB)
1 |
/** |
---|---|
2 |
A wrapper around Flash 8's ExternalInterface; this is needed |
3 |
because ExternalInterface has a number of serialization bugs that we |
4 |
need to correct for. |
5 |
|
6 |
@author Brad Neuberg |
7 |
*/ |
8 |
|
9 |
import flash.external.ExternalInterface; |
10 |
|
11 |
class DojoExternalInterface{ |
12 |
public static var available:Boolean; |
13 |
public static var dojoPath = ""; |
14 |
|
15 |
public static function initialize(){ |
16 |
//trace("DojoExternalInterface.initialize"); |
17 |
|
18 |
// extract the dojo base path |
19 |
DojoExternalInterface.dojoPath = DojoExternalInterface.getDojoPath(); |
20 |
|
21 |
// see if we need to do an express install |
22 |
var install:ExpressInstall = new ExpressInstall(); |
23 |
if(install.needsUpdate){ |
24 |
install.init(); |
25 |
} |
26 |
|
27 |
// set whether communication is available |
28 |
DojoExternalInterface.available = ExternalInterface.available; |
29 |
|
30 |
// make sure we can play nice in XD settings |
31 |
System.security.allowDomain(unescape(_root.xdomain)); |
32 |
} |
33 |
|
34 |
/** Called when we are finished adding methods through addCallback. */ |
35 |
public static function done(){ |
36 |
//trace("done"); |
37 |
DojoExternalInterface.call("dojox.flash.loaded"); |
38 |
} |
39 |
|
40 |
public static function addCallback(methodName:String, instance:Object, |
41 |
method:Function):Boolean{ |
42 |
//trace("addCallback"); |
43 |
ExternalInterface.addCallback(methodName, instance, function(){ |
44 |
instance = (instance) ? instance : null; |
45 |
var params = []; |
46 |
if(arguments && arguments.length){ |
47 |
for(var i = 0; i < arguments.length; i++){ |
48 |
params[i] = DojoExternalInterface.decodeData(arguments[i]); |
49 |
} |
50 |
} |
51 |
|
52 |
var results = method.apply(instance, params); |
53 |
results = DojoExternalInterface.encodeData(results); |
54 |
|
55 |
return results; |
56 |
}); |
57 |
|
58 |
// tell JavaScript about DojoExternalInterface new method so we can create a proxy |
59 |
ExternalInterface.call("dojox.flash.comm._addExternalInterfaceCallback", |
60 |
methodName); |
61 |
|
62 |
return true; |
63 |
} |
64 |
|
65 |
public static function call(methodName:String):Void{ |
66 |
// we might have any number of optional arguments, so we have to |
67 |
// pass them in dynamically; strip out the results callback |
68 |
var parameters = new Array(); |
69 |
for(var i = 0; i < arguments.length; i++){ |
70 |
parameters.push(arguments[i]); |
71 |
} |
72 |
|
73 |
// FIXME: Should we be encoding or decoding the data to get |
74 |
// around Flash's serialization bugs? |
75 |
|
76 |
var results = ExternalInterface.call.apply(ExternalInterface, parameters); |
77 |
|
78 |
return results; |
79 |
} |
80 |
|
81 |
/** |
82 |
Called by Flash to indicate to JavaScript that we are ready to have |
83 |
our Flash functions called. Calling loaded() |
84 |
will fire the dojox.flash.loaded() event, so that JavaScript can know that |
85 |
Flash has finished loading and adding its callbacks, and can begin to |
86 |
interact with the Flash file. |
87 |
*/ |
88 |
public static function loaded(){ |
89 |
DojoExternalInterface.call("dojox.flash.loaded"); |
90 |
} |
91 |
|
92 |
/** |
93 |
Utility trace implementation that prints out to console.debug. |
94 |
*/ |
95 |
public static function trace(msg){ |
96 |
DojoExternalInterface.call("console.debug", "FLASH: " + msg); |
97 |
} |
98 |
|
99 |
private static function decodeData(data):String{ |
100 |
if(!data || typeof data != "string"){ |
101 |
return data; |
102 |
} |
103 |
|
104 |
// JAC: Using unicode character 0001 to store instead of Unicode null |
105 |
// which causes trouble |
106 |
data = replaceStr(data, "&custom_null;", "\u0001"); |
107 |
|
108 |
// we have to use custom encodings for certain characters when passing |
109 |
// them over; for example, passing a backslash over as //// from JavaScript |
110 |
// to Flash doesn't work |
111 |
data = replaceStr(data, "&custom_backslash;", "\\"); |
112 |
|
113 |
return data; |
114 |
} |
115 |
|
116 |
private static function encodeData(data):String{ |
117 |
if(!data || typeof data != "string"){ |
118 |
return data; |
119 |
} |
120 |
|
121 |
// double encode all entity values, or they will be mis-decoded |
122 |
// by Flash when returned |
123 |
data = replaceStr(data, "&", "&"); |
124 |
|
125 |
// certain XMLish characters break Flash's wire serialization for |
126 |
// ExternalInterface; encode these into a custom encoding, rather than |
127 |
// the standard entity encoding, because otherwise we won't be able to |
128 |
// differentiate between our own encoding and any entity characters |
129 |
// that are being used in the string itself |
130 |
data = replaceStr(data, '<', '&custom_lt;'); |
131 |
data = replaceStr(data, '>', '&custom_gt;'); |
132 |
|
133 |
// needed for IE |
134 |
data = replaceStr(data, '\\', '&custom_backslash;'); |
135 |
data = replaceStr(data, "\u0001", "&custom_null;"); |
136 |
|
137 |
// encode control characters and JavaScript delimiters |
138 |
data = replaceStr(data, "\n", "\\n"); |
139 |
data = replaceStr(data, "\r", "\\r"); |
140 |
data = replaceStr(data, "\f", "\\f"); |
141 |
data = replaceStr(data, "'", "\\'"); |
142 |
data = replaceStr(data, '"', '\"'); |
143 |
|
144 |
return data; |
145 |
} |
146 |
|
147 |
/** |
148 |
Flash ActionScript has no String.replace method or support for |
149 |
Regular Expressions! We roll our own very simple one. |
150 |
*/ |
151 |
public static function replaceStr(inputStr:String, replaceThis:String, |
152 |
withThis:String):String{ |
153 |
var splitStr = inputStr.split(replaceThis); |
154 |
if(!splitStr){ |
155 |
return inputStr; |
156 |
} |
157 |
|
158 |
inputStr = splitStr.join(withThis); |
159 |
return inputStr; |
160 |
} |
161 |
|
162 |
private static function getDojoPath(){ |
163 |
var url = _root._url; |
164 |
var start = url.indexOf("baseUrl=") + "baseUrl=".length; |
165 |
var path = url.substring(start); |
166 |
var end = path.indexOf("&"); |
167 |
if(end != -1){ |
168 |
path = path.substring(0, end); |
169 |
} |
170 |
|
171 |
// some browsers append a junk string at the end: '%20'%20quality= |
172 |
if(path.indexOf("'%20'%20quality=") != -1){ |
173 |
path = path.substring(0, path.indexOf("'%20'%20quality=")); |
174 |
} |
175 |
return unescape(path); |
176 |
} |
177 |
} |