_common.js 48 KB

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