PageRenderTime 28ms CodeModel.GetById 19ms RepoModel.GetById 1ms app.codeStats 0ms

/java/server/test/org/openqa/selenium/tests/html/dojo-0.4.0-mini/src/flash.js

https://bitbucket.org/jaiew/patched-chrome-driver
JavaScript | 1230 lines | 553 code | 123 blank | 554 comment | 112 complexity | 7a3f610c937e6b53e75f89663e5ef7cf MD5 | raw file
Possible License(s): BSD-3-Clause, AGPL-1.0, Apache-2.0
  1. /*
  2. Copyright (c) 2004-2006, The Dojo Foundation
  3. All Rights Reserved.
  4. Licensed under the Academic Free License version 2.1 or above OR the
  5. modified BSD license. For more information on Dojo licensing, see:
  6. http://dojotoolkit.org/community/licensing.shtml
  7. */
  8. dojo.provide("dojo.flash");
  9. dojo.require("dojo.string.*");
  10. dojo.require("dojo.uri.*");
  11. dojo.require("dojo.html.common");
  12. /**
  13. The goal of dojo.flash is to make it easy to extend Flash's capabilities
  14. into an AJAX/DHTML environment. Robust, performant, reliable
  15. JavaScript/Flash communication is harder than most realize when they
  16. delve into the topic, especially if you want it
  17. to work on Internet Explorer, Firefox, and Safari, and to be able to
  18. push around hundreds of K of information quickly. Dojo.flash makes it
  19. possible to support these platforms; you have to jump through a few
  20. hoops to get its capabilites, but if you are a library writer
  21. who wants to bring Flash's storage or streaming sockets ability into
  22. DHTML, for example, then dojo.flash is perfect for you.
  23. Dojo.flash provides an easy object for interacting with the Flash plugin.
  24. This object provides methods to determine the current version of the Flash
  25. plugin (dojo.flash.info); execute Flash instance methods
  26. independent of the Flash version
  27. being used (dojo.flash.comm); write out the necessary markup to
  28. dynamically insert a Flash object into the page (dojo.flash.Embed; and
  29. do dynamic installation and upgrading of the current Flash plugin in
  30. use (dojo.flash.Install).
  31. To use dojo.flash, you must first wait until Flash is finished loading
  32. and initializing before you attempt communication or interaction.
  33. To know when Flash is finished use dojo.event.connect:
  34. dojo.event.connect(dojo.flash, "loaded", myInstance, "myCallback");
  35. Then, while the page is still loading provide the file name
  36. and the major version of Flash that will be used for Flash/JavaScript
  37. communication (see "Flash Communication" below for information on the
  38. different kinds of Flash/JavaScript communication supported and how they
  39. depend on the version of Flash installed):
  40. dojo.flash.setSwf({flash6: "src/storage/storage_flash6.swf",
  41. flash8: "src/storage/storage_flash8.swf"});
  42. This will cause dojo.flash to pick the best way of communicating
  43. between Flash and JavaScript based on the platform.
  44. If no SWF files are specified, then Flash is not initialized.
  45. Your Flash must use DojoExternalInterface to expose Flash methods and
  46. to call JavaScript; see "Flash Communication" below for details.
  47. setSwf can take an optional 'visible' attribute to control whether
  48. the Flash object is visible or not on the page; the default is visible:
  49. dojo.flash.setSwf({flash6: "src/storage/storage_flash6.swf",
  50. flash8: "src/storage/storage_flash8.swf",
  51. visible: false});
  52. Once finished, you can query Flash version information:
  53. dojo.flash.info.version
  54. Or can communicate with Flash methods that were exposed:
  55. var results = dojo.flash.comm.sayHello("Some Message");
  56. Only string values are currently supported for both arguments and
  57. for return results. Everything will be cast to a string on both
  58. the JavaScript and Flash sides.
  59. -------------------
  60. Flash Communication
  61. -------------------
  62. dojo.flash allows Flash/JavaScript communication in
  63. a way that can pass large amounts of data back and forth reliably and
  64. very fast. The dojo.flash
  65. framework encapsulates the specific way in which this communication occurs,
  66. presenting a common interface to JavaScript irrespective of the underlying
  67. Flash version.
  68. There are currently three major ways to do Flash/JavaScript communication
  69. in the Flash community:
  70. 1) Flash 6+ - Uses Flash methods, such as SetVariable and TCallLabel,
  71. and the fscommand handler to do communication. Strengths: Very fast,
  72. mature, and can send extremely large amounts of data; can do
  73. synchronous method calls. Problems: Does not work on Safari; works on
  74. Firefox/Mac OS X only if Flash 8 plugin is installed; cryptic to work with.
  75. 2) Flash 8+ - Uses ExternalInterface, which provides a way for Flash
  76. methods to register themselves for callbacks from JavaScript, and a way
  77. for Flash to call JavaScript. Strengths: Works on Safari; elegant to
  78. work with; can do synchronous method calls. Problems: Extremely buggy
  79. (fails if there are new lines in the data, for example); performance
  80. degrades drastically in O(n^2) time as data grows; locks up the browser while
  81. it is communicating; does not work in Internet Explorer if Flash
  82. object is dynamically added to page with document.writeln, DOM methods,
  83. or innerHTML.
  84. 3) Flash 6+ - Uses two seperate Flash applets, one that we
  85. create over and over, passing input data into it using the PARAM tag,
  86. which then uses a Flash LocalConnection to pass the data to the main Flash
  87. applet; communication back to Flash is accomplished using a getURL
  88. call with a javascript protocol handler, such as "javascript:myMethod()".
  89. Strengths: the most cross browser, cross platform pre-Flash 8 method
  90. of Flash communication known; works on Safari. Problems: Timing issues;
  91. clunky and complicated; slow; can only send very small amounts of
  92. data (several K); all method calls are asynchronous.
  93. dojo.flash.comm uses only the first two methods. This framework
  94. was created primarily for dojo.storage, which needs to pass very large
  95. amounts of data synchronously and reliably across the Flash/JavaScript
  96. boundary. We use the first method, the Flash 6 method, on all platforms
  97. that support it, while using the Flash 8 ExternalInterface method
  98. only on Safari with some special code to help correct ExternalInterface's
  99. bugs.
  100. Since dojo.flash needs to have two versions of the Flash
  101. file it wants to generate, a Flash 6 and a Flash 8 version to gain
  102. true cross-browser compatibility, several tools are provided to ease
  103. development on the Flash side.
  104. In your Flash file, if you want to expose Flash methods that can be
  105. called, use the DojoExternalInterface class to register methods. This
  106. class is an exact API clone of the standard ExternalInterface class, but
  107. can work in Flash 6+ browsers. Under the covers it uses the best
  108. mechanism to do communication:
  109. class HelloWorld{
  110. function HelloWorld(){
  111. // Initialize the DojoExternalInterface class
  112. DojoExternalInterface.initialize();
  113. // Expose your methods
  114. DojoExternalInterface.addCallback("sayHello", this, this.sayHello);
  115. // Tell JavaScript that you are ready to have method calls
  116. DojoExternalInterface.loaded();
  117. // Call some JavaScript
  118. var resultsReady = function(results){
  119. trace("Received the following results from JavaScript: " + results);
  120. }
  121. DojoExternalInterface.call("someJavaScriptMethod", resultsReady,
  122. someParameter);
  123. }
  124. function sayHello(){ ... }
  125. static main(){ ... }
  126. }
  127. DojoExternalInterface adds two new functions to the ExternalInterface
  128. API: initialize() and loaded(). initialize() must be called before
  129. any addCallback() or call() methods are run, and loaded() must be
  130. called after you are finished adding your callbacks. Calling loaded()
  131. will fire the dojo.flash.loaded() event, so that JavaScript can know that
  132. Flash has finished loading and adding its callbacks, and can begin to
  133. interact with the Flash file.
  134. To generate your SWF files, use the ant task
  135. "buildFlash". You must have the open source Motion Twin ActionScript
  136. compiler (mtasc) installed and in your path to use the "buildFlash"
  137. ant task; download and install mtasc from http://www.mtasc.org/.
  138. buildFlash usage:
  139. ant buildFlash -Ddojo.flash.file=../tests/flash/HelloWorld.as
  140. where "dojo.flash.file" is the relative path to your Flash
  141. ActionScript file.
  142. This will generate two SWF files, one ending in _flash6.swf and the other
  143. ending in _flash8.swf in the same directory as your ActionScript method:
  144. HelloWorld_flash6.swf
  145. HelloWorld_flash8.swf
  146. Initialize dojo.flash with the filename and Flash communication version to
  147. use during page load; see the documentation for dojo.flash for details:
  148. dojo.flash.setSwf({flash6: "tests/flash/HelloWorld_flash6.swf",
  149. flash8: "tests/flash/HelloWorld_flash8.swf"});
  150. Now, your Flash methods can be called from JavaScript as if they are native
  151. Flash methods, mirrored exactly on the JavaScript side:
  152. dojo.flash.comm.sayHello();
  153. Only Strings are supported being passed back and forth currently.
  154. JavaScript to Flash communication is synchronous; i.e., results are returned
  155. directly from the method call:
  156. var results = dojo.flash.comm.sayHello();
  157. Flash to JavaScript communication is asynchronous due to limitations in
  158. the underlying technologies; you must use a results callback to handle
  159. results returned by JavaScript in your Flash AS files:
  160. var resultsReady = function(results){
  161. trace("Received the following results from JavaScript: " + results);
  162. }
  163. DojoExternalInterface.call("someJavaScriptMethod", resultsReady);
  164. -------------------
  165. Notes
  166. -------------------
  167. If you have both Flash 6 and Flash 8 versions of your file:
  168. dojo.flash.setSwf({flash6: "tests/flash/HelloWorld_flash6.swf",
  169. flash8: "tests/flash/HelloWorld_flash8.swf"});
  170. but want to force the browser to use a certain version of Flash for
  171. all platforms (for testing, for example), use the djConfig
  172. variable 'forceFlashComm' with the version number to force:
  173. var djConfig = { forceFlashComm: 6 };
  174. Two values are currently supported, 6 and 8, for the two styles of
  175. communication described above. Just because you force dojo.flash
  176. to use a particular communication style is no guarantee that it will
  177. work; for example, Flash 8 communication doesn't work in Internet
  178. Explorer due to bugs in Flash, and Flash 6 communication does not work
  179. in Safari. It is best to let dojo.flash determine the best communication
  180. mechanism, and to use the value above only for debugging the dojo.flash
  181. framework itself.
  182. Also note that dojo.flash can currently only work with one Flash object
  183. on the page; it and the API do not yet support multiple Flash objects on
  184. the same page.
  185. We use some special tricks to get decent, linear performance
  186. out of Flash 8's ExternalInterface on Safari; see the blog
  187. post
  188. http://codinginparadise.org/weblog/2006/02/how-to-speed-up-flash-8s.html
  189. for details.
  190. Your code can detect whether the Flash player is installing or having
  191. its version revved in two ways. First, if dojo.flash detects that
  192. Flash installation needs to occur, it sets dojo.flash.info.installing
  193. to true. Second, you can detect if installation is necessary with the
  194. following callback:
  195. dojo.event.connect(dojo.flash, "installing", myInstance, "myCallback");
  196. You can use this callback to delay further actions that might need Flash;
  197. when installation is finished the full page will be refreshed and the
  198. user will be placed back on your page with Flash installed.
  199. Two utility methods exist if you want to add loading and installing
  200. listeners without creating dependencies on dojo.event; these are
  201. 'addLoadingListener' and 'addInstallingListener'.
  202. -------------------
  203. Todo/Known Issues
  204. -------------------
  205. There are several tasks I was not able to do, or did not need to fix
  206. to get dojo.storage out:
  207. * When using Flash 8 communication, Flash method calls to JavaScript
  208. are not working properly; serialization might also be broken for certain
  209. invalid characters when it is Flash invoking JavaScript methods.
  210. The Flash side needs to have more sophisticated serialization/
  211. deserialization mechanisms like JavaScript currently has. The
  212. test_flash2.html unit tests should also be updated to have much more
  213. sophisticated Flash to JavaScript unit tests, including large
  214. amounts of data.
  215. * On Internet Explorer, after doing a basic install, the page is
  216. not refreshed or does not detect that Flash is now available. The way
  217. to fix this is to create a custom small Flash file that is pointed to
  218. during installation; when it is finished loading, it does a callback
  219. that says that Flash installation is complete on IE, and we can proceed
  220. to initialize the dojo.flash subsystem.
  221. @author Brad Neuberg, bkn3@columbia.edu
  222. */
  223. dojo.flash = {
  224. flash6_version: null,
  225. flash8_version: null,
  226. ready: false,
  227. _visible: true,
  228. _loadedListeners: new Array(),
  229. _installingListeners: new Array(),
  230. /** Sets the SWF files and versions we are using. */
  231. setSwf: function(fileInfo){
  232. //dojo.debug("setSwf");
  233. if(fileInfo == null || dojo.lang.isUndefined(fileInfo)){
  234. return;
  235. }
  236. if(fileInfo.flash6 != null && !dojo.lang.isUndefined(fileInfo.flash6)){
  237. this.flash6_version = fileInfo.flash6;
  238. }
  239. if(fileInfo.flash8 != null && !dojo.lang.isUndefined(fileInfo.flash8)){
  240. this.flash8_version = fileInfo.flash8;
  241. }
  242. if(!dojo.lang.isUndefined(fileInfo.visible)){
  243. this._visible = fileInfo.visible;
  244. }
  245. // initialize ourselves
  246. this._initialize();
  247. },
  248. /** Returns whether we are using Flash 6 for communication on this platform. */
  249. useFlash6: function(){
  250. if(this.flash6_version == null){
  251. return false;
  252. }else if (this.flash6_version != null && dojo.flash.info.commVersion == 6){
  253. // if we have a flash 6 version of this SWF, and this browser supports
  254. // communicating using Flash 6 features...
  255. return true;
  256. }else{
  257. return false;
  258. }
  259. },
  260. /** Returns whether we are using Flash 8 for communication on this platform. */
  261. useFlash8: function(){
  262. if(this.flash8_version == null){
  263. return false;
  264. }else if (this.flash8_version != null && dojo.flash.info.commVersion == 8){
  265. // if we have a flash 8 version of this SWF, and this browser supports
  266. // communicating using Flash 8 features...
  267. return true;
  268. }else{
  269. return false;
  270. }
  271. },
  272. /** Adds a listener to know when Flash is finished loading.
  273. Useful if you don't want a dependency on dojo.event. */
  274. addLoadedListener: function(listener){
  275. this._loadedListeners.push(listener);
  276. },
  277. /** Adds a listener to know if Flash is being installed.
  278. Useful if you don't want a dependency on dojo.event. */
  279. addInstallingListener: function(listener){
  280. this._installingListeners.push(listener);
  281. },
  282. /**
  283. A callback when the Flash subsystem is finished loading and can be
  284. worked with. To be notified when Flash is finished loading, connect
  285. your callback to this method using the following:
  286. dojo.event.connect(dojo.flash, "loaded", myInstance, "myCallback");
  287. */
  288. loaded: function(){
  289. //dojo.debug("dojo.flash.loaded");
  290. dojo.flash.ready = true;
  291. if(dojo.flash._loadedListeners.length > 0){
  292. for(var i = 0;i < dojo.flash._loadedListeners.length; i++){
  293. dojo.flash._loadedListeners[i].call(null);
  294. }
  295. }
  296. },
  297. /**
  298. A callback to know if Flash is currently being installed or
  299. having its version revved. To be notified if Flash is installing, connect
  300. your callback to this method using the following:
  301. dojo.event.connect(dojo.flash, "installing", myInstance, "myCallback");
  302. */
  303. installing: function(){
  304. //dojo.debug("installing");
  305. if(dojo.flash._installingListeners.length > 0){
  306. for(var i = 0; i < dojo.flash._installingListeners.length; i++){
  307. dojo.flash._installingListeners[i].call(null);
  308. }
  309. }
  310. },
  311. /** Initializes dojo.flash. */
  312. _initialize: function(){
  313. //dojo.debug("dojo.flash._initialize");
  314. // see if we need to rev or install Flash on this platform
  315. var installer = new dojo.flash.Install();
  316. dojo.flash.installer = installer;
  317. if(installer.needed() == true){
  318. installer.install();
  319. }else{
  320. //dojo.debug("Writing object out");
  321. // write the flash object into the page
  322. dojo.flash.obj = new dojo.flash.Embed(this._visible);
  323. dojo.flash.obj.write(dojo.flash.info.commVersion);
  324. // initialize the way we do Flash/JavaScript communication
  325. dojo.flash.comm = new dojo.flash.Communicator();
  326. }
  327. }
  328. };
  329. /**
  330. A class that helps us determine whether Flash is available,
  331. it's major and minor versions, and what Flash version features should
  332. be used for Flash/JavaScript communication. Parts of this code
  333. are adapted from the automatic Flash plugin detection code autogenerated
  334. by the Macromedia Flash 8 authoring environment.
  335. An instance of this class can be accessed on dojo.flash.info after
  336. the page is finished loading.
  337. This constructor must be called before the page is finished loading.
  338. */
  339. dojo.flash.Info = function(){
  340. // Visual basic helper required to detect Flash Player ActiveX control
  341. // version information on Internet Explorer
  342. if(dojo.render.html.ie){
  343. document.writeln('<script language="VBScript" type="text/vbscript"\>');
  344. document.writeln('Function VBGetSwfVer(i)');
  345. document.writeln(' on error resume next');
  346. document.writeln(' Dim swControl, swVersion');
  347. document.writeln(' swVersion = 0');
  348. document.writeln(' set swControl = CreateObject("ShockwaveFlash.ShockwaveFlash." + CStr(i))');
  349. document.writeln(' if (IsObject(swControl)) then');
  350. document.writeln(' swVersion = swControl.GetVariable("$version")');
  351. document.writeln(' end if');
  352. document.writeln(' VBGetSwfVer = swVersion');
  353. document.writeln('End Function');
  354. document.writeln('</script\>');
  355. }
  356. this._detectVersion();
  357. this._detectCommunicationVersion();
  358. }
  359. dojo.flash.Info.prototype = {
  360. /** The full version string, such as "8r22". */
  361. version: -1,
  362. /**
  363. The major, minor, and revisions of the plugin. For example, if the
  364. plugin is 8r22, then the major version is 8, the minor version is 0,
  365. and the revision is 22.
  366. */
  367. versionMajor: -1,
  368. versionMinor: -1,
  369. versionRevision: -1,
  370. /** Whether this platform has Flash already installed. */
  371. capable: false,
  372. /**
  373. The major version number for how our Flash and JavaScript communicate.
  374. This can currently be the following values:
  375. 6 - We use a combination of the Flash plugin methods, such as SetVariable
  376. and TCallLabel, along with fscommands, to do communication.
  377. 8 - We use the ExternalInterface API.
  378. -1 - For some reason neither method is supported, and no communication
  379. is possible.
  380. */
  381. commVersion: 6,
  382. /** Set if we are in the middle of a Flash installation session. */
  383. installing: false,
  384. /**
  385. Asserts that this environment has the given major, minor, and revision
  386. numbers for the Flash player. Returns true if the player is equal
  387. or above the given version, false otherwise.
  388. Example: To test for Flash Player 7r14:
  389. dojo.flash.info.isVersionOrAbove(7, 0, 14)
  390. */
  391. isVersionOrAbove: function(reqMajorVer, reqMinorVer, reqVer){
  392. // make the revision a decimal (i.e. transform revision 14 into
  393. // 0.14
  394. reqVer = parseFloat("." + reqVer);
  395. if(this.versionMajor >= reqMajorVer && this.versionMinor >= reqMinorVer
  396. && this.versionRevision >= reqVer){
  397. return true;
  398. }else{
  399. return false;
  400. }
  401. },
  402. _detectVersion: function(){
  403. var versionStr;
  404. // loop backwards through the versions until we find the newest version
  405. for(var testVersion = 25; testVersion > 0; testVersion--){
  406. if(dojo.render.html.ie){
  407. versionStr = VBGetSwfVer(testVersion);
  408. }else{
  409. versionStr = this._JSFlashInfo(testVersion);
  410. }
  411. if(versionStr == -1 ){
  412. this.capable = false;
  413. return;
  414. }else if(versionStr != 0){
  415. var versionArray;
  416. if(dojo.render.html.ie){
  417. var tempArray = versionStr.split(" ");
  418. var tempString = tempArray[1];
  419. versionArray = tempString.split(",");
  420. }else{
  421. versionArray = versionStr.split(".");
  422. }
  423. this.versionMajor = versionArray[0];
  424. this.versionMinor = versionArray[1];
  425. this.versionRevision = versionArray[2];
  426. // 7.0r24 == 7.24
  427. var versionString = this.versionMajor + "." + this.versionRevision;
  428. this.version = parseFloat(versionString);
  429. this.capable = true;
  430. break;
  431. }
  432. }
  433. },
  434. /**
  435. JavaScript helper required to detect Flash Player PlugIn version
  436. information. Internet Explorer uses a corresponding Visual Basic
  437. version to interact with the Flash ActiveX control.
  438. */
  439. _JSFlashInfo: function(testVersion){
  440. // NS/Opera version >= 3 check for Flash plugin in plugin array
  441. if(navigator.plugins != null && navigator.plugins.length > 0){
  442. if(navigator.plugins["Shockwave Flash 2.0"] ||
  443. navigator.plugins["Shockwave Flash"]){
  444. var swVer2 = navigator.plugins["Shockwave Flash 2.0"] ? " 2.0" : "";
  445. var flashDescription = navigator.plugins["Shockwave Flash" + swVer2].description;
  446. var descArray = flashDescription.split(" ");
  447. var tempArrayMajor = descArray[2].split(".");
  448. var versionMajor = tempArrayMajor[0];
  449. var versionMinor = tempArrayMajor[1];
  450. if(descArray[3] != ""){
  451. var tempArrayMinor = descArray[3].split("r");
  452. }else{
  453. var tempArrayMinor = descArray[4].split("r");
  454. }
  455. var versionRevision = tempArrayMinor[1] > 0 ? tempArrayMinor[1] : 0;
  456. var version = versionMajor + "." + versionMinor + "."
  457. + versionRevision;
  458. return version;
  459. }
  460. }
  461. return -1;
  462. },
  463. /**
  464. Detects the mechanisms that should be used for Flash/JavaScript
  465. communication, setting 'commVersion' to either 6 or 8. If the value is
  466. 6, we use Flash Plugin 6+ features, such as GetVariable, TCallLabel,
  467. and fscommand, to do Flash/JavaScript communication; if the value is
  468. 8, we use the ExternalInterface API for communication.
  469. */
  470. _detectCommunicationVersion: function(){
  471. if(this.capable == false){
  472. this.commVersion = null;
  473. return;
  474. }
  475. // detect if the user has over-ridden the default flash version
  476. if (typeof djConfig["forceFlashComm"] != "undefined" &&
  477. typeof djConfig["forceFlashComm"] != null){
  478. this.commVersion = djConfig["forceFlashComm"];
  479. return;
  480. }
  481. // we prefer Flash 6 features over Flash 8, because they are much faster
  482. // and much less buggy
  483. // at this point, we don't have a flash file to detect features on,
  484. // so we need to instead look at the browser environment we are in
  485. if(dojo.render.html.safari == true || dojo.render.html.opera == true){
  486. this.commVersion = 8;
  487. }else{
  488. this.commVersion = 6;
  489. }
  490. }
  491. };
  492. /** A class that is used to write out the Flash object into the page. */
  493. dojo.flash.Embed = function(visible){
  494. this._visible = visible;
  495. }
  496. dojo.flash.Embed.prototype = {
  497. /**
  498. The width of this Flash applet. The default is the minimal width
  499. necessary to show the Flash settings dialog.
  500. */
  501. width: 215,
  502. /**
  503. The height of this Flash applet. The default is the minimal height
  504. necessary to show the Flash settings dialog.
  505. */
  506. height: 138,
  507. /** The id of the Flash object. */
  508. id: "flashObject",
  509. /** Controls whether this is a visible Flash applet or not. */
  510. _visible: true,
  511. protocol: function(){
  512. switch(window.location.protocol){
  513. case "https:":
  514. return "https";
  515. break;
  516. default:
  517. return "http";
  518. break;
  519. }
  520. },
  521. /**
  522. Writes the Flash into the page. This must be called before the page
  523. is finished loading.
  524. @param flashVer The Flash version to write.
  525. @param doExpressInstall Whether to write out Express Install
  526. information. Optional value; defaults to false.
  527. */
  528. write: function(flashVer, doExpressInstall){
  529. //dojo.debug("write");
  530. if(dojo.lang.isUndefined(doExpressInstall)){
  531. doExpressInstall = false;
  532. }
  533. // determine our container div's styling
  534. var containerStyle = new dojo.string.Builder();
  535. containerStyle.append("width: " + this.width + "px; ");
  536. containerStyle.append("height: " + this.height + "px; ");
  537. if(this._visible == false){
  538. containerStyle.append("position: absolute; ");
  539. containerStyle.append("z-index: 10000; ");
  540. containerStyle.append("top: -1000px; ");
  541. containerStyle.append("left: -1000px; ");
  542. }
  543. containerStyle = containerStyle.toString();
  544. // figure out the SWF file to get and how to write out the correct HTML
  545. // for this Flash version
  546. var objectHTML;
  547. var swfloc;
  548. // Flash 6
  549. if(flashVer == 6){
  550. swfloc = dojo.flash.flash6_version;
  551. var dojoPath = djConfig.baseRelativePath;
  552. swfloc = swfloc + "?baseRelativePath=" + escape(dojoPath);
  553. objectHTML =
  554. '<embed id="' + this.id + '" src="' + swfloc + '" '
  555. + ' quality="high" bgcolor="#ffffff" '
  556. + ' width="' + this.width + '" height="' + this.height + '" '
  557. + ' name="' + this.id + '" '
  558. + ' align="middle" allowScriptAccess="sameDomain" '
  559. + ' type="application/x-shockwave-flash" swLiveConnect="true" '
  560. + ' pluginspage="'
  561. + this.protocol()
  562. + '://www.macromedia.com/go/getflashplayer">';
  563. }else{ // Flash 8
  564. swfloc = dojo.flash.flash8_version;
  565. var swflocObject = swfloc;
  566. var swflocEmbed = swfloc;
  567. var dojoPath = djConfig.baseRelativePath;
  568. if(doExpressInstall){
  569. // the location to redirect to after installing
  570. var redirectURL = escape(window.location);
  571. document.title = document.title.slice(0, 47) + " - Flash Player Installation";
  572. var docTitle = escape(document.title);
  573. swflocObject += "?MMredirectURL=" + redirectURL
  574. + "&MMplayerType=ActiveX"
  575. + "&MMdoctitle=" + docTitle
  576. + "&baseRelativePath=" + escape(dojoPath);
  577. swflocEmbed += "?MMredirectURL=" + redirectURL
  578. + "&MMplayerType=PlugIn"
  579. + "&baseRelativePath=" + escape(dojoPath);
  580. }
  581. if(swflocEmbed.indexOf("?") == -1){
  582. swflocEmbed += "?baseRelativePath="+escape(dojoPath)+"' ";
  583. }
  584. objectHTML =
  585. '<object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" '
  586. + 'codebase="'
  587. + this.protocol()
  588. + '://fpdownload.macromedia.com/pub/shockwave/cabs/flash/'
  589. + 'swflash.cab#version=8,0,0,0" '
  590. + 'width="' + this.width + '" '
  591. + 'height="' + this.height + '" '
  592. + 'id="' + this.id + '" '
  593. + 'align="middle"> '
  594. + '<param name="allowScriptAccess" value="sameDomain" /> '
  595. + '<param name="movie" value="' + swflocObject + '" /> '
  596. + '<param name="quality" value="high" /> '
  597. + '<param name="bgcolor" value="#ffffff" /> '
  598. + '<embed src="' + swflocEmbed + "' "
  599. + 'quality="high" '
  600. + 'bgcolor="#ffffff" '
  601. + 'width="' + this.width + '" '
  602. + 'height="' + this.height + '" '
  603. + 'id="' + this.id + '" '
  604. + 'name="' + this.id + '" '
  605. + 'swLiveConnect="true" '
  606. + 'align="middle" '
  607. + 'allowScriptAccess="sameDomain" '
  608. + 'type="application/x-shockwave-flash" '
  609. + 'pluginspage="'
  610. + this.protocol()
  611. +'://www.macromedia.com/go/getflashplayer" />'
  612. + '</object>';
  613. }
  614. // now write everything out
  615. objectHTML = '<div id="' + this.id + 'Container" style="' + containerStyle + '"> '
  616. + objectHTML
  617. + '</div>';
  618. document.writeln(objectHTML);
  619. },
  620. /** Gets the Flash object DOM node. */
  621. get: function(){
  622. //return (dojo.render.html.ie) ? window[this.id] : document[this.id];
  623. // more robust way to get Flash object; version above can break
  624. // communication on IE sometimes
  625. return document.getElementById(this.id);
  626. },
  627. /** Sets the visibility of this Flash object. */
  628. setVisible: function(visible){
  629. var container = dojo.byId(this.id + "Container");
  630. if(visible == true){
  631. container.style.visibility = "visible";
  632. }else{
  633. container.style.position = "absolute";
  634. container.style.x = "-1000px";
  635. container.style.y = "-1000px";
  636. container.style.visibility = "hidden";
  637. }
  638. },
  639. /** Centers the flash applet on the page. */
  640. center: function(){
  641. var elementWidth = this.width;
  642. var elementHeight = this.height;
  643. var scroll_offset = dojo.html.getScroll().offset;
  644. var viewport_size = dojo.html.getViewport();
  645. // compute the centered position
  646. var x = scroll_offset.x + (viewport_size.width - elementWidth) / 2;
  647. var y = scroll_offset.y + (viewport_size.height - elementHeight) / 2;
  648. // set the centered position
  649. var container = dojo.byId(this.id + "Container");
  650. container.style.top = y + "px";
  651. container.style.left = x + "px";
  652. }
  653. };
  654. /**
  655. A class that is used to communicate between Flash and JavaScript in
  656. a way that can pass large amounts of data back and forth reliably,
  657. very fast, and with synchronous method calls. This class encapsulates the
  658. specific way in which this communication occurs,
  659. presenting a common interface to JavaScript irrespective of the underlying
  660. Flash version.
  661. */
  662. dojo.flash.Communicator = function(){
  663. if(dojo.flash.useFlash6()){
  664. this._writeFlash6();
  665. }else if (dojo.flash.useFlash8()){
  666. this._writeFlash8();
  667. }
  668. }
  669. dojo.flash.Communicator.prototype = {
  670. _writeFlash6: function(){
  671. var id = dojo.flash.obj.id;
  672. // global function needed for Flash 6 callback;
  673. // we write it out as a script tag because the VBScript hook for IE
  674. // callbacks does not work properly if this function is evalled() from
  675. // within the Dojo system
  676. document.writeln('<script language="JavaScript">');
  677. document.writeln(' function ' + id + '_DoFSCommand(command, args){ ');
  678. document.writeln(' dojo.flash.comm._handleFSCommand(command, args); ');
  679. document.writeln('}');
  680. document.writeln('</script>');
  681. // hook for Internet Explorer to receive FSCommands from Flash
  682. if(dojo.render.html.ie){
  683. document.writeln('<SCRIPT LANGUAGE=VBScript\> ');
  684. document.writeln('on error resume next ');
  685. document.writeln('Sub ' + id + '_FSCommand(ByVal command, ByVal args)');
  686. document.writeln(' call ' + id + '_DoFSCommand(command, args)');
  687. document.writeln('end sub');
  688. document.writeln('</SCRIPT\> ');
  689. }
  690. },
  691. _writeFlash8: function(){
  692. // nothing needs to be written out for Flash 8 communication;
  693. // happens automatically
  694. },
  695. /** Flash 6 communication. */
  696. /** Handles fscommand's from Flash to JavaScript. Flash 6 communication. */
  697. _handleFSCommand: function(command, args){
  698. //dojo.debug("fscommand, command="+command+", args="+args);
  699. // Flash 8 on Mac/Firefox precedes all commands with the string "FSCommand:";
  700. // strip it off if it is present
  701. if(command != null && !dojo.lang.isUndefined(command)
  702. && /^FSCommand:(.*)/.test(command) == true){
  703. command = command.match(/^FSCommand:(.*)/)[1];
  704. }
  705. if(command == "addCallback"){ // add Flash method for JavaScript callback
  706. this._fscommandAddCallback(command, args);
  707. }else if(command == "call"){ // Flash to JavaScript method call
  708. this._fscommandCall(command, args);
  709. }else if(command == "fscommandReady"){ // see if fscommands are ready
  710. this._fscommandReady();
  711. }
  712. },
  713. /** Handles registering a callable Flash function. Flash 6 communication. */
  714. _fscommandAddCallback: function(command, args){
  715. var functionName = args;
  716. // do a trick, where we link this function name to our wrapper
  717. // function, _call, that does the actual JavaScript to Flash call
  718. var callFunc = function(){
  719. return dojo.flash.comm._call(functionName, arguments);
  720. };
  721. dojo.flash.comm[functionName] = callFunc;
  722. // indicate that the call was successful
  723. dojo.flash.obj.get().SetVariable("_succeeded", true);
  724. },
  725. /** Handles Flash calling a JavaScript function. Flash 6 communication. */
  726. _fscommandCall: function(command, args){
  727. var plugin = dojo.flash.obj.get();
  728. var functionName = args;
  729. // get the number of arguments to this method call and build them up
  730. var numArgs = parseInt(plugin.GetVariable("_numArgs"));
  731. var flashArgs = new Array();
  732. for(var i = 0; i < numArgs; i++){
  733. var currentArg = plugin.GetVariable("_" + i);
  734. flashArgs.push(currentArg);
  735. }
  736. // get the function instance; we technically support more capabilities
  737. // than ExternalInterface, which can only call global functions; if
  738. // the method name has a dot in it, such as "dojo.flash.loaded", we
  739. // eval it so that the method gets run against an instance
  740. var runMe;
  741. if(functionName.indexOf(".") == -1){ // global function
  742. runMe = window[functionName];
  743. }else{
  744. // instance function
  745. runMe = eval(functionName);
  746. }
  747. // make the call and get the results
  748. var results = null;
  749. if(!dojo.lang.isUndefined(runMe) && runMe != null){
  750. results = runMe.apply(null, flashArgs);
  751. }
  752. // return the results to flash
  753. plugin.SetVariable("_returnResult", results);
  754. },
  755. /** Reports that fscommands are ready to run if executed from Flash. */
  756. _fscommandReady: function(){
  757. var plugin = dojo.flash.obj.get();
  758. plugin.SetVariable("fscommandReady", "true");
  759. },
  760. /**
  761. The actual function that will execute a JavaScript to Flash call; used
  762. by the Flash 6 communication method.
  763. */
  764. _call: function(functionName, args){
  765. // we do JavaScript to Flash method calls by setting a Flash variable
  766. // "_functionName" with the function name; "_numArgs" with the number
  767. // of arguments; and "_0", "_1", etc for each numbered argument. Flash
  768. // reads these, executes the function call, and returns the result
  769. // in "_returnResult"
  770. var plugin = dojo.flash.obj.get();
  771. plugin.SetVariable("_functionName", functionName);
  772. plugin.SetVariable("_numArgs", args.length);
  773. for(var i = 0; i < args.length; i++){
  774. // unlike Flash 8's ExternalInterface, Flash 6 has no problem with
  775. // any special characters _except_ for the null character \0; double
  776. // encode this so the Flash side never sees it, but we can get it
  777. // back if the value comes back to JavaScript
  778. var value = args[i];
  779. value = value.replace(/\0/g, "\\0");
  780. plugin.SetVariable("_" + i, value);
  781. }
  782. // now tell Flash to execute this method using the Flash Runner
  783. plugin.TCallLabel("/_flashRunner", "execute");
  784. // get the results
  785. var results = plugin.GetVariable("_returnResult");
  786. // we double encoded all null characters as //0 because Flash breaks
  787. // if they are present; turn the //0 back into /0
  788. results = results.replace(/\\0/g, "\0");
  789. return results;
  790. },
  791. /** Flash 8 communication. */
  792. /**
  793. Registers the existence of a Flash method that we can call with
  794. JavaScript, using Flash 8's ExternalInterface.
  795. */
  796. _addExternalInterfaceCallback: function(methodName){
  797. var wrapperCall = function(){
  798. // some browsers don't like us changing values in the 'arguments' array, so
  799. // make a fresh copy of it
  800. var methodArgs = new Array(arguments.length);
  801. for(var i = 0; i < arguments.length; i++){
  802. methodArgs[i] = arguments[i];
  803. }
  804. return dojo.flash.comm._execFlash(methodName, methodArgs);
  805. };
  806. dojo.flash.comm[methodName] = wrapperCall;
  807. },
  808. /**
  809. Encodes our data to get around ExternalInterface bugs.
  810. Flash 8 communication.
  811. */
  812. _encodeData: function(data){
  813. // double encode all entity values, or they will be mis-decoded
  814. // by Flash when returned
  815. var entityRE = /\&([^;]*)\;/g;
  816. data = data.replace(entityRE, "&amp;$1;");
  817. // entity encode XML-ish characters, or Flash's broken XML serializer
  818. // breaks
  819. data = data.replace(/</g, "&lt;");
  820. data = data.replace(/>/g, "&gt;");
  821. // transforming \ into \\ doesn't work; just use a custom encoding
  822. data = data.replace("\\", "&custom_backslash;&custom_backslash;");
  823. data = data.replace(/\n/g, "\\n");
  824. data = data.replace(/\r/g, "\\r");
  825. data = data.replace(/\f/g, "\\f");
  826. data = data.replace(/\0/g, "\\0"); // null character
  827. data = data.replace(/\'/g, "\\\'");
  828. data = data.replace(/\"/g, '\\\"');
  829. return data;
  830. },
  831. /**
  832. Decodes our data to get around ExternalInterface bugs.
  833. Flash 8 communication.
  834. */
  835. _decodeData: function(data){
  836. if(data == null || typeof data == "undefined"){
  837. return data;
  838. }
  839. // certain XMLish characters break Flash's wire serialization for
  840. // ExternalInterface; these are encoded on the
  841. // DojoExternalInterface side into a custom encoding, rather than
  842. // the standard entity encoding, because otherwise we won't be able to
  843. // differentiate between our own encoding and any entity characters
  844. // that are being used in the string itself
  845. data = data.replace(/\&custom_lt\;/g, "<");
  846. data = data.replace(/\&custom_gt\;/g, ">");
  847. // Unfortunately, Flash returns us our String with special characters
  848. // like newlines broken into seperate characters. So if \n represents
  849. // a new line, Flash returns it as "\" and "n". This means the character
  850. // is _not_ a newline. This forces us to eval() the string to cause
  851. // escaped characters to turn into their real special character values.
  852. data = eval('"' + data + '"');
  853. return data;
  854. },
  855. /**
  856. Sends our method arguments over to Flash in chunks in order to
  857. have ExternalInterface's performance not be O(n^2).
  858. Flash 8 communication.
  859. */
  860. _chunkArgumentData: function(value, argIndex){
  861. var plugin = dojo.flash.obj.get();
  862. // cut up the string into pieces, and push over each piece one
  863. // at a time
  864. var numSegments = Math.ceil(value.length / 1024);
  865. for(var i = 0; i < numSegments; i++){
  866. var startCut = i * 1024;
  867. var endCut = i * 1024 + 1024;
  868. if(i == (numSegments - 1)){
  869. endCut = i * 1024 + value.length;
  870. }
  871. var piece = value.substring(startCut, endCut);
  872. // encode each piece seperately, rather than the entire
  873. // argument data, because ocassionally a special
  874. // character, such as an entity like &foobar;, will fall between
  875. // piece boundaries, and we _don't_ want to encode that value if
  876. // it falls between boundaries, or else we will end up with incorrect
  877. // data when we patch the pieces back together on the other side
  878. piece = this._encodeData(piece);
  879. // directly use the underlying CallFunction method used by
  880. // ExternalInterface, which is vastly faster for large strings
  881. // and lets us bypass some Flash serialization bugs
  882. plugin.CallFunction('<invoke name="chunkArgumentData" '
  883. + 'returntype="javascript">'
  884. + '<arguments>'
  885. + '<string>' + piece + '</string>'
  886. + '<number>' + argIndex + '</number>'
  887. + '</arguments>'
  888. + '</invoke>');
  889. }
  890. },
  891. /**
  892. Gets our method return data in chunks for better performance.
  893. Flash 8 communication.
  894. */
  895. _chunkReturnData: function(){
  896. var plugin = dojo.flash.obj.get();
  897. var numSegments = plugin.getReturnLength();
  898. var resultsArray = new Array();
  899. for(var i = 0; i < numSegments; i++){
  900. // directly use the underlying CallFunction method used by
  901. // ExternalInterface, which is vastly faster for large strings
  902. var piece =
  903. plugin.CallFunction('<invoke name="chunkReturnData" '
  904. + 'returntype="javascript">'
  905. + '<arguments>'
  906. + '<number>' + i + '</number>'
  907. + '</arguments>'
  908. + '</invoke>');
  909. // remove any leading or trailing JavaScript delimiters, which surround
  910. // our String when it comes back from Flash since we bypass Flash's
  911. // deserialization routines by directly calling CallFunction on the
  912. // plugin
  913. if(piece == '""' || piece == "''"){
  914. piece = "";
  915. }else{
  916. piece = piece.substring(1, piece.length-1);
  917. }
  918. resultsArray.push(piece);
  919. }
  920. var results = resultsArray.join("");
  921. return results;
  922. },
  923. /**
  924. Executes a Flash method; called from the JavaScript wrapper proxy we
  925. create on dojo.flash.comm.
  926. Flash 8 communication.
  927. */
  928. _execFlash: function(methodName, methodArgs){
  929. var plugin = dojo.flash.obj.get();
  930. // begin Flash method execution
  931. plugin.startExec();
  932. // set the number of arguments
  933. plugin.setNumberArguments(methodArgs.length);
  934. // chunk and send over each argument
  935. for(var i = 0; i < methodArgs.length; i++){
  936. this._chunkArgumentData(methodArgs[i], i);
  937. }
  938. // execute the method
  939. plugin.exec(methodName);
  940. // get the return result
  941. var results = this._chunkReturnData();
  942. // decode the results
  943. results = this._decodeData(results);
  944. // reset everything
  945. plugin.endExec();
  946. return results;
  947. }
  948. }
  949. /**
  950. Figures out the best way to automatically install the Flash plugin
  951. for this browser and platform. Also determines if installation or
  952. revving of the current plugin is needed on this platform.
  953. */
  954. dojo.flash.Install = function(){
  955. }
  956. dojo.flash.Install.prototype = {
  957. /**
  958. Determines if installation or revving of the current plugin is
  959. needed.
  960. */
  961. needed: function(){
  962. // do we even have flash?
  963. if(dojo.flash.info.capable == false){
  964. return true;
  965. }
  966. // are we on the Mac? Safari needs Flash version 8 to do Flash 8
  967. // communication, while Firefox/Mac needs Flash 8 to fix bugs it has
  968. // with Flash 6 communication
  969. if(dojo.render.os.mac == true && !dojo.flash.info.isVersionOrAbove(8, 0, 0)){
  970. return true;
  971. }
  972. // other platforms need at least Flash 6 or above
  973. if(!dojo.flash.info.isVersionOrAbove(6, 0, 0)){
  974. return true;
  975. }
  976. // otherwise we don't need installation
  977. return false;
  978. },
  979. /** Performs installation or revving of the Flash plugin. */
  980. install: function(){
  981. //dojo.debug("install");
  982. // indicate that we are installing
  983. dojo.flash.info.installing = true;
  984. dojo.flash.installing();
  985. if(dojo.flash.info.capable == false){ // we have no Flash at all
  986. //dojo.debug("Completely new install");
  987. // write out a simple Flash object to force the browser to prompt
  988. // the user to install things
  989. var installObj = new dojo.flash.Embed(false);
  990. installObj.write(8); // write out HTML for Flash 8 version+
  991. }else if(dojo.flash.info.isVersionOrAbove(6, 0, 65)){ // Express Install
  992. //dojo.debug("Express install");
  993. var installObj = new dojo.flash.Embed(false);
  994. installObj.write(8, true); // write out HTML for Flash 8 version+
  995. installObj.setVisible(true);
  996. installObj.center();
  997. }else{ // older Flash install than version 6r65
  998. alert("This content requires a more recent version of the Macromedia "
  999. +" Flash Player.");
  1000. window.location.href = + dojo.flash.Embed.protocol() +
  1001. "://www.macromedia.com/go/getflashplayer";
  1002. }
  1003. },
  1004. /**
  1005. Called when the Express Install is either finished, failed, or was
  1006. rejected by the user.
  1007. */
  1008. _onInstallStatus: function(msg){
  1009. if (msg == "Download.Complete"){
  1010. // Installation is complete.
  1011. dojo.flash._initialize();
  1012. }else if(msg == "Download.Cancelled"){
  1013. alert("This content requires a more recent version of the Macromedia "
  1014. +" Flash Player.");
  1015. window.location.href = dojo.flash.Embed.protocol() +
  1016. "://www.macromedia.com/go/getflashplayer";
  1017. }else if (msg == "Download.Failed"){
  1018. // The end user failed to download the installer due to a network failure
  1019. alert("There was an error downloading the Flash Player update. "
  1020. + "Please try again later, or visit macromedia.com to download "
  1021. + "the latest version of the Flash plugin.");
  1022. }
  1023. }
  1024. }
  1025. // find out if Flash is installed
  1026. dojo.flash.info = new dojo.flash.Info();
  1027. // vim:ts=4:noet:tw=0: