DojoExternalInterface.as 5.3 KB

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