aboutsummaryrefslogtreecommitdiff
path: root/includes/js/dojox/flash
diff options
context:
space:
mode:
Diffstat (limited to 'includes/js/dojox/flash')
-rw-r--r--includes/js/dojox/flash/DojoExternalInterface.as168
-rw-r--r--includes/js/dojox/flash/ExpressInstall.as71
-rw-r--r--includes/js/dojox/flash/README31
-rw-r--r--includes/js/dojox/flash/_base.js762
-rw-r--r--includes/js/dojox/flash/tests/TestFlash.as36
-rw-r--r--includes/js/dojox/flash/tests/TestFlash.swfbin0 -> 1863 bytes
-rw-r--r--includes/js/dojox/flash/tests/buildFlashTest.sh4
-rw-r--r--includes/js/dojox/flash/tests/test_flash.html15
-rw-r--r--includes/js/dojox/flash/tests/test_flash.js155
9 files changed, 1242 insertions, 0 deletions
diff --git a/includes/js/dojox/flash/DojoExternalInterface.as b/includes/js/dojox/flash/DojoExternalInterface.as
new file mode 100644
index 0000000..d857968
--- /dev/null
+++ b/includes/js/dojox/flash/DojoExternalInterface.as
@@ -0,0 +1,168 @@
+/**
+ A wrapper around Flash 8's ExternalInterface; this is needed
+ because ExternalInterface has a number of serialization bugs that we
+ need to correct for.
+
+ @author Brad Neuberg
+*/
+
+import flash.external.ExternalInterface;
+
+class DojoExternalInterface{
+ public static var available:Boolean;
+ public static var dojoPath = "";
+
+ public static function initialize(){
+ //trace("DojoExternalInterface.initialize");
+
+ // extract the dojo base path
+ DojoExternalInterface.dojoPath = DojoExternalInterface.getDojoPath();
+
+ // see if we need to do an express install
+ var install:ExpressInstall = new ExpressInstall();
+ if(install.needsUpdate){
+ install.init();
+ }
+
+ // set whether communication is available
+ DojoExternalInterface.available = ExternalInterface.available;
+ }
+
+ /** Called when we are finished adding methods through addCallback. */
+ public static function done(){
+ //trace("done");
+ DojoExternalInterface.call("dojox.flash.loaded");
+ }
+
+ public static function addCallback(methodName:String, instance:Object,
+ method:Function):Boolean{
+ //trace("addCallback");
+ ExternalInterface.addCallback(methodName, instance, function(){
+ instance = (instance) ? instance : null;
+ var params = [];
+ if(arguments && arguments.length){
+ for(var i = 0; i < arguments.length; i++){
+ params[i] = DojoExternalInterface.decodeData(arguments[i]);
+ }
+ }
+
+ var results = method.apply(instance, params);
+ results = DojoExternalInterface.encodeData(results);
+
+ return results;
+ });
+
+ // tell JavaScript about DojoExternalInterface new method so we can create a proxy
+ ExternalInterface.call("dojox.flash.comm._addExternalInterfaceCallback",
+ methodName);
+
+ return true;
+ }
+
+ public static function call(methodName:String):Void{
+ // we might have any number of optional arguments, so we have to
+ // pass them in dynamically; strip out the results callback
+ var parameters = new Array();
+ for(var i = 0; i < arguments.length; i++){
+ parameters.push(arguments[i]);
+ }
+
+ // FIXME: Should we be encoding or decoding the data to get
+ // around Flash's serialization bugs?
+
+ var results = ExternalInterface.call.apply(ExternalInterface, parameters);
+
+ return results;
+ }
+
+ /**
+ Called by Flash to indicate to JavaScript that we are ready to have
+ our Flash functions called. Calling loaded()
+ will fire the dojox.flash.loaded() event, so that JavaScript can know that
+ Flash has finished loading and adding its callbacks, and can begin to
+ interact with the Flash file.
+ */
+ public static function loaded(){
+ DojoExternalInterface.call("dojox.flash.loaded");
+ }
+
+ /**
+ Utility trace implementation that prints out to console.debug.
+ */
+ public static function trace(msg){
+ DojoExternalInterface.call("console.debug", "FLASH: " + msg);
+ }
+
+ private static function decodeData(data):String{
+ if(!data || typeof data != "string"){
+ return data;
+ }
+
+ // we have to use custom encodings for certain characters when passing
+ // them over; for example, passing a backslash over as //// from JavaScript
+ // to Flash doesn't work
+ data = replaceStr(data, "&custom_backslash;", "\\");
+
+ data = replaceStr(data, "\\\'", "\'");
+ data = replaceStr(data, "\\\"", "\"");
+
+ return data;
+ }
+
+ private static function encodeData(data):String{
+ if(!data || typeof data != "string"){
+ return data;
+ }
+
+ // certain XMLish characters break Flash's wire serialization for
+ // ExternalInterface; encode these into a custom encoding, rather than
+ // the standard entity encoding, because otherwise we won't be able to
+ // differentiate between our own encoding and any entity characters
+ // that are being used in the string itself
+ data = replaceStr(data, '<', '&custom_lt;');
+ data = replaceStr(data, '>', '&custom_gt;');
+
+ // needed for IE
+ data = replaceStr(data, '\\', '&custom_backslash;');
+
+ // encode control characters and JavaScript delimiters
+ data = replaceStr(data, "\n", "\\n");
+ data = replaceStr(data, "\r", "\\r");
+ data = replaceStr(data, "\f", "\\f");
+ data = replaceStr(data, "'", "\\'");
+ data = replaceStr(data, '"', '\"');
+
+ return data;
+ }
+
+ /**
+ Flash ActionScript has no String.replace method or support for
+ Regular Expressions! We roll our own very simple one.
+ */
+ public static function replaceStr(inputStr:String, replaceThis:String,
+ withThis:String):String{
+ var splitStr = inputStr.split(replaceThis);
+ if(!splitStr){
+ return inputStr;
+ }
+
+ inputStr = splitStr.join(withThis);
+ return inputStr;
+ }
+
+ private static function getDojoPath(){
+ var url = _root._url;
+ var start = url.indexOf("baseUrl=") + "baseUrl=".length;
+ var path = url.substring(start);
+ var end = path.indexOf("&");
+ if(end != -1){
+ path = path.substring(0, end);
+ }
+
+ // some browsers append a junk string at the end: '%20'%20quality=
+ if(path.indexOf("'%20'%20quality=") != -1){
+ path = path.substring(0, path.indexOf("'%20'%20quality="));
+ }
+ return path;
+ }
+}
diff --git a/includes/js/dojox/flash/ExpressInstall.as b/includes/js/dojox/flash/ExpressInstall.as
new file mode 100644
index 0000000..1801171
--- /dev/null
+++ b/includes/js/dojox/flash/ExpressInstall.as
@@ -0,0 +1,71 @@
+/**
+ * Based on the expressinstall.as class created by Geoff Stearns as part
+ * of the FlashObject library.
+ *
+ * Use this file to invoke the Macromedia Flash Player Express Install functionality
+ * This file is intended for use with the FlashObject embed script. You can download FlashObject
+ * and this file at the following URL: http://blog.deconcept.com/flashobject/
+ *
+ * Usage:
+ * var ExpressInstall = new ExpressInstall();
+ *
+ * // test to see if install is needed:
+ * if (ExpressInstall.needsUpdate) { // returns true if update is needed
+ * ExpressInstall.init(); // starts the update
+ * }
+ *
+ * NOTE: Your Flash movie must be at least 214px by 137px in order to use ExpressInstall.
+ *
+ */
+
+class ExpressInstall{
+ public var needsUpdate:Boolean;
+ private var updater:MovieClip;
+ private var hold:MovieClip;
+
+ public function ExpressInstall(){
+ // does the user need to update?
+ this.needsUpdate = (_root.MMplayerType == undefined) ? false : true;
+ }
+
+ public function init():Void{
+ this.loadUpdater();
+ }
+
+ public function loadUpdater():Void{
+ System.security.allowDomain("fpdownload.macromedia.com");
+
+ // hope that nothing is at a depth of 10000000, you can change this depth if needed, but you want
+ // it to be on top of your content if you have any stuff on the first frame
+ this.updater = _root.createEmptyMovieClip("expressInstallHolder", 10000000);
+
+ // register the callback so we know if they cancel or there is an error
+ var _self = this;
+ this.updater.installStatus = _self.onInstallStatus;
+ this.hold = this.updater.createEmptyMovieClip("hold", 1);
+
+ // can't use movieClipLoader because it has to work in 6.0.65
+ this.updater.onEnterFrame = function():Void {
+ if(typeof this.hold.startUpdate == 'function'){
+ _self.initUpdater();
+ this.onEnterFrame = null;
+ }
+ }
+
+ var cacheBuster:Number = Math.random();
+
+ this.hold.loadMovie("http://fpdownload.macromedia.com/pub/flashplayer/"
+ +"update/current/swf/autoUpdater.swf?"+ cacheBuster);
+ }
+
+ private function initUpdater():Void{
+ this.hold.redirectURL = _root.MMredirectURL;
+ this.hold.MMplayerType = _root.MMplayerType;
+ this.hold.MMdoctitle = _root.MMdoctitle;
+ this.hold.startUpdate();
+ }
+
+ public function onInstallStatus(msg):Void{
+ getURL("javascript:dojox.flash.install._onInstallStatus('"+msg+"')");
+ }
+}
diff --git a/includes/js/dojox/flash/README b/includes/js/dojox/flash/README
new file mode 100644
index 0000000..e01f3be
--- /dev/null
+++ b/includes/js/dojox/flash/README
@@ -0,0 +1,31 @@
+-------------------------------------------------------------------------------
+dojox.flash
+-------------------------------------------------------------------------------
+Version 0.4
+Release date: MM/DD/YYYY
+-------------------------------------------------------------------------------
+Project state: experimental (currently broken)
+-------------------------------------------------------------------------------
+Project authors
+ Brad Neuberg (BradNeuberg@dojotoolkit.org)
+ Alex Russell (alex@dojotoolkit.org, only handled minor porting issues)
+-------------------------------------------------------------------------------
+Project description
+
+Infrastructure for high-performance Flash/JS communication
+-------------------------------------------------------------------------------
+Dependencies:
+
+MTASC for creating builds
+-------------------------------------------------------------------------------
+Documentation
+
+TODOC
+-------------------------------------------------------------------------------
+Installation instructions
+
+Not intended as a stand-alone module.
+-------------------------------------------------------------------------------
+Additional Notes
+
+TODOC
diff --git a/includes/js/dojox/flash/_base.js b/includes/js/dojox/flash/_base.js
new file mode 100644
index 0000000..5a372dd
--- /dev/null
+++ b/includes/js/dojox/flash/_base.js
@@ -0,0 +1,762 @@
+if(!dojo._hasResource["dojox.flash._base"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.flash._base"] = true;
+dojo.provide("dojox.flash._base");
+
+// for dijit.getViewport(), needed by dojox.flash.Embed.center()
+dojo.require("dijit._base.place");
+
+dojox.flash = function(){
+ // summary:
+ // The goal of dojox.flash is to make it easy to extend Flash's capabilities
+ // into an Ajax/DHTML environment.
+ //
+ // dojox.flash provides an easy object for interacting with the Flash plugin.
+ // This object provides methods to determine the current version of the Flash
+ // plugin (dojox.flash.info); write out the necessary markup to
+ // dynamically insert a Flash object into the page (dojox.flash.Embed; and
+ // do dynamic installation and upgrading of the current Flash plugin in
+ // use (dojox.flash.Install). If you want to call methods on the Flash object
+ // embedded into the page it is your responsibility to use Flash's ExternalInterface
+ // API and get a reference to the Flash object yourself.
+ //
+ // To use dojox.flash, you must first wait until Flash is finished loading
+ // and initializing before you attempt communication or interaction.
+ // To know when Flash is finished use dojo.connect:
+ //
+ // dojo.connect(dojox.flash, "loaded", myInstance, "myCallback");
+ //
+ // Then, while the page is still loading provide the file name:
+ //
+ // dojox.flash.setSwf(dojo.moduleUrl("dojox", "_storage/storage.swf"));
+ //
+ // If no SWF files are specified, then Flash is not initialized.
+ //
+ // Your Flash must use Flash's ExternalInterface to expose Flash methods and
+ // to call JavaScript.
+ //
+ // setSwf can take an optional 'visible' attribute to control whether
+ // the Flash object is visible or not on the page; the default is visible:
+ //
+ // dojox.flash.setSwf(dojo.moduleUrl("dojox", "_storage/storage.swf"),
+ // false);
+ //
+ // Once finished, you can query Flash version information:
+ //
+ // dojox.flash.info.version
+ //
+ // Or can communicate with Flash methods that were exposed:
+ //
+ // var f = dojox.flash.get();
+ // var results = f.sayHello("Some Message");
+ //
+ // Your Flash files should use DojoExternalInterface.as to register methods;
+ // this file wraps Flash's normal ExternalInterface but correct various
+ // serialization bugs that ExternalInterface has.
+ //
+ // Note that dojox.flash is not meant to be a generic Flash embedding
+ // mechanism; it is as generic as necessary to make Dojo Storage's
+ // Flash Storage Provider as clean and modular as possible. If you want
+ // a generic Flash embed mechanism see SWFObject
+ // (http://blog.deconcept.com/swfobject/).
+ //
+ // Notes:
+ // Note that dojox.flash can currently only work with one Flash object
+ // on the page; it does not yet support multiple Flash objects on
+ // the same page.
+ //
+ // Your code can detect whether the Flash player is installing or having
+ // its version revved in two ways. First, if dojox.flash detects that
+ // Flash installation needs to occur, it sets dojox.flash.info.installing
+ // to true. Second, you can detect if installation is necessary with the
+ // following callback:
+ //
+ // dojo.connect(dojox.flash, "installing", myInstance, "myCallback");
+ //
+ // You can use this callback to delay further actions that might need Flash;
+ // when installation is finished the full page will be refreshed and the
+ // user will be placed back on your page with Flash installed.
+ //
+ // -------------------
+ // Todo/Known Issues
+ // -------------------
+ // * On Internet Explorer, after doing a basic install, the page is
+ // not refreshed or does not detect that Flash is now available. The way
+ // to fix this is to create a custom small Flash file that is pointed to
+ // during installation; when it is finished loading, it does a callback
+ // that says that Flash installation is complete on IE, and we can proceed
+ // to initialize the dojox.flash subsystem.
+ // * Things aren't super tested for sending complex objects to Flash
+ // methods, since Dojo Storage only needs strings
+ //
+ // Author- Brad Neuberg, http://codinginparadise.org
+}
+
+dojox.flash = {
+ ready: false,
+ url: null,
+
+ _visible: true,
+ _loadedListeners: new Array(),
+ _installingListeners: new Array(),
+
+ setSwf: function(/* String */ url, /* boolean? */ visible){
+ // summary: Sets the SWF files and versions we are using.
+ // url: String
+ // The URL to this Flash file.
+ // visible: boolean?
+ // Whether the Flash file is visible or not. If it is not visible we hide it off the
+ // screen. This defaults to true (i.e. the Flash file is visible).
+ this.url = url;
+
+ if(typeof visible != "undefined"){
+ this._visible = visible;
+ }
+
+ // initialize ourselves
+ this._initialize();
+ },
+
+ addLoadedListener: function(/* Function */ listener){
+ // summary:
+ // Adds a listener to know when Flash is finished loading.
+ // Useful if you don't want a dependency on dojo.event.
+ // listener: Function
+ // A function that will be called when Flash is done loading.
+
+ this._loadedListeners.push(listener);
+ },
+
+ addInstallingListener: function(/* Function */ listener){
+ // summary:
+ // Adds a listener to know if Flash is being installed.
+ // Useful if you don't want a dependency on dojo.event.
+ // listener: Function
+ // A function that will be called if Flash is being
+ // installed
+
+ this._installingListeners.push(listener);
+ },
+
+ loaded: function(){
+ // summary: Called back when the Flash subsystem is finished loading.
+ // description:
+ // A callback when the Flash subsystem is finished loading and can be
+ // worked with. To be notified when Flash is finished loading, add a
+ // loaded listener:
+ //
+ // dojox.flash.addLoadedListener(loadedListener);
+
+ dojox.flash.ready = true;
+ if(dojox.flash._loadedListeners.length > 0){
+ for(var i = 0;i < dojox.flash._loadedListeners.length; i++){
+ dojox.flash._loadedListeners[i].call(null);
+ }
+ }
+ },
+
+ installing: function(){
+ // summary: Called if Flash is being installed.
+ // description:
+ // A callback to know if Flash is currently being installed or
+ // having its version revved. To be notified if Flash is installing, connect
+ // your callback to this method using the following:
+ //
+ // dojo.event.connect(dojox.flash, "installing", myInstance, "myCallback");
+
+ if(dojox.flash._installingListeners.length > 0){
+ for(var i = 0; i < dojox.flash._installingListeners.length; i++){
+ dojox.flash._installingListeners[i].call(null);
+ }
+ }
+ },
+
+ // Initializes dojox.flash.
+ _initialize: function(){
+ //console.debug("dojox.flash._initialize");
+ // see if we need to rev or install Flash on this platform
+ var installer = new dojox.flash.Install();
+ dojox.flash.installer = installer;
+
+ if(installer.needed() == true){
+ installer.install();
+ }else{
+ // write the flash object into the page
+ dojox.flash.obj = new dojox.flash.Embed(this._visible);
+ dojox.flash.obj.write();
+
+ // setup the communicator
+ dojox.flash.comm = new dojox.flash.Communicator();
+ }
+ }
+};
+
+
+dojox.flash.Info = function(){
+ // summary: A class that helps us determine whether Flash is available.
+ // description:
+ // A class that helps us determine whether Flash is available,
+ // it's major and minor versions, and what Flash version features should
+ // be used for Flash/JavaScript communication. Parts of this code
+ // are adapted from the automatic Flash plugin detection code autogenerated
+ // by the Macromedia Flash 8 authoring environment.
+ //
+ // An instance of this class can be accessed on dojox.flash.info after
+ // the page is finished loading.
+ //
+ // This constructor must be called before the page is finished loading.
+
+ // Visual basic helper required to detect Flash Player ActiveX control
+ // version information on Internet Explorer
+ if(dojo.isIE){
+ document.write([
+ '<script language="VBScript" type="text/vbscript"\>',
+ 'Function VBGetSwfVer(i)',
+ ' on error resume next',
+ ' Dim swControl, swVersion',
+ ' swVersion = 0',
+ ' set swControl = CreateObject("ShockwaveFlash.ShockwaveFlash." + CStr(i))',
+ ' if (IsObject(swControl)) then',
+ ' swVersion = swControl.GetVariable("$version")',
+ ' end if',
+ ' VBGetSwfVer = swVersion',
+ 'End Function',
+ '</script\>'].join("\r\n"));
+ }
+
+ this._detectVersion();
+}
+
+dojox.flash.Info.prototype = {
+ // version: String
+ // The full version string, such as "8r22".
+ version: -1,
+
+ // versionMajor, versionMinor, versionRevision: String
+ // The major, minor, and revisions of the plugin. For example, if the
+ // plugin is 8r22, then the major version is 8, the minor version is 0,
+ // and the revision is 22.
+ versionMajor: -1,
+ versionMinor: -1,
+ versionRevision: -1,
+
+ // capable: Boolean
+ // Whether this platform has Flash already installed.
+ capable: false,
+
+ // installing: Boolean
+ // Set if we are in the middle of a Flash installation session.
+ installing: false,
+
+ isVersionOrAbove: function(
+ /* int */ reqMajorVer,
+ /* int */ reqMinorVer,
+ /* int */ reqVer){ /* Boolean */
+ // summary:
+ // Asserts that this environment has the given major, minor, and revision
+ // numbers for the Flash player.
+ // description:
+ // Asserts that this environment has the given major, minor, and revision
+ // numbers for the Flash player.
+ //
+ // Example- To test for Flash Player 7r14:
+ //
+ // dojox.flash.info.isVersionOrAbove(7, 0, 14)
+ // returns:
+ // Returns true if the player is equal
+ // or above the given version, false otherwise.
+
+ // make the revision a decimal (i.e. transform revision 14 into
+ // 0.14
+ reqVer = parseFloat("." + reqVer);
+
+ if(this.versionMajor >= reqMajorVer && this.versionMinor >= reqMinorVer
+ && this.versionRevision >= reqVer){
+ return true;
+ }else{
+ return false;
+ }
+ },
+
+ _detectVersion: function(){
+ var versionStr;
+
+ // loop backwards through the versions until we find the newest version
+ for(var testVersion = 25; testVersion > 0; testVersion--){
+ if(dojo.isIE){
+ versionStr = VBGetSwfVer(testVersion);
+ }else{
+ versionStr = this._JSFlashInfo(testVersion);
+ }
+
+ if(versionStr == -1 ){
+ this.capable = false;
+ return;
+ }else if(versionStr != 0){
+ var versionArray;
+ if(dojo.isIE){
+ var tempArray = versionStr.split(" ");
+ var tempString = tempArray[1];
+ versionArray = tempString.split(",");
+ }else{
+ versionArray = versionStr.split(".");
+ }
+
+ this.versionMajor = versionArray[0];
+ this.versionMinor = versionArray[1];
+ this.versionRevision = versionArray[2];
+
+ // 7.0r24 == 7.24
+ var versionString = this.versionMajor + "." + this.versionRevision;
+ this.version = parseFloat(versionString);
+
+ this.capable = true;
+
+ break;
+ }
+ }
+ },
+
+ // JavaScript helper required to detect Flash Player PlugIn version
+ // information. Internet Explorer uses a corresponding Visual Basic
+ // version to interact with the Flash ActiveX control.
+ _JSFlashInfo: function(testVersion){
+ // NS/Opera version >= 3 check for Flash plugin in plugin array
+ if(navigator.plugins != null && navigator.plugins.length > 0){
+ if(navigator.plugins["Shockwave Flash 2.0"] ||
+ navigator.plugins["Shockwave Flash"]){
+ var swVer2 = navigator.plugins["Shockwave Flash 2.0"] ? " 2.0" : "";
+ var flashDescription = navigator.plugins["Shockwave Flash" + swVer2].description;
+ var descArray = flashDescription.split(" ");
+ var tempArrayMajor = descArray[2].split(".");
+ var versionMajor = tempArrayMajor[0];
+ var versionMinor = tempArrayMajor[1];
+ if(descArray[3] != ""){
+ var tempArrayMinor = descArray[3].split("r");
+ }else{
+ var tempArrayMinor = descArray[4].split("r");
+ }
+ var versionRevision = tempArrayMinor[1] > 0 ? tempArrayMinor[1] : 0;
+ var version = versionMajor + "." + versionMinor + "."
+ + versionRevision;
+
+ return version;
+ }
+ }
+
+ return -1;
+ }
+};
+
+dojox.flash.Embed = function(visible){
+ // summary: A class that is used to write out the Flash object into the page.
+ // description:
+ // Writes out the necessary tags to embed a Flash file into the page. Note that
+ // these tags are written out as the page is loaded using document.write, so
+ // you must call this class before the page has finished loading.
+
+ this._visible = visible;
+}
+
+dojox.flash.Embed.prototype = {
+ // width: int
+ // The width of this Flash applet. The default is the minimal width
+ // necessary to show the Flash settings dialog. Current value is
+ // 215 pixels.
+ width: 215,
+
+ // height: int
+ // The height of this Flash applet. The default is the minimal height
+ // necessary to show the Flash settings dialog. Current value is
+ // 138 pixels.
+ height: 138,
+
+ // id: String
+ // The id of the Flash object. Current value is 'flashObject'.
+ id: "flashObject",
+
+ // Controls whether this is a visible Flash applet or not.
+ _visible: true,
+
+ protocol: function(){
+ switch(window.location.protocol){
+ case "https:":
+ return "https";
+ break;
+ default:
+ return "http";
+ break;
+ }
+ },
+
+ write: function(/* Boolean? */ doExpressInstall){
+ // summary: Writes the Flash into the page.
+ // description:
+ // This must be called before the page
+ // is finished loading.
+ // doExpressInstall: Boolean
+ // Whether to write out Express Install
+ // information. Optional value; defaults to false.
+
+ // determine our container div's styling
+ var containerStyle = "";
+ containerStyle += ("width: " + this.width + "px; ");
+ containerStyle += ("height: " + this.height + "px; ");
+ if(!this._visible){
+ containerStyle += "position: absolute; z-index: 10000; top: -1000px; left: -1000px; ";
+ }
+
+ // figure out the SWF file to get and how to write out the correct HTML
+ // for this Flash version
+ var objectHTML;
+ var swfloc = dojox.flash.url;
+ var swflocObject = swfloc;
+ var swflocEmbed = swfloc;
+ var dojoUrl = dojo.baseUrl;
+ if(doExpressInstall){
+ // the location to redirect to after installing
+ var redirectURL = escape(window.location);
+ document.title = document.title.slice(0, 47) + " - Flash Player Installation";
+ var docTitle = escape(document.title);
+ swflocObject += "?MMredirectURL=" + redirectURL
+ + "&MMplayerType=ActiveX"
+ + "&MMdoctitle=" + docTitle
+ + "&baseUrl=" + escape(dojoUrl);
+ swflocEmbed += "?MMredirectURL=" + redirectURL
+ + "&MMplayerType=PlugIn"
+ + "&baseUrl=" + escape(dojoUrl);
+ }else{
+ // IE/Flash has an evil bug that shows up some time: if we load the
+ // Flash and it isn't in the cache, ExternalInterface works fine --
+ // however, the second time when its loaded from the cache a timing
+ // bug can keep ExternalInterface from working. The trick below
+ // simply invalidates the Flash object in the cache all the time to
+ // keep it loading fresh. -- Brad Neuberg
+ swflocObject += "?cachebust=" + new Date().getTime();
+ }
+
+ if(swflocEmbed.indexOf("?") == -1){
+ swflocEmbed += '?baseUrl='+escape(dojoUrl);
+ }else{
+ swflocEmbed += '&baseUrl='+escape(dojoUrl);
+ }
+
+ objectHTML =
+ '<object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" '
+ + 'codebase="'
+ + this.protocol()
+ + '://fpdownload.macromedia.com/pub/shockwave/cabs/flash/'
+ + 'swflash.cab#version=8,0,0,0"\n '
+ + 'width="' + this.width + '"\n '
+ + 'height="' + this.height + '"\n '
+ + 'id="' + this.id + '"\n '
+ + 'name="' + this.id + '"\n '
+ + 'align="middle">\n '
+ + '<param name="allowScriptAccess" value="sameDomain"></param>\n '
+ + '<param name="movie" value="' + swflocObject + '"></param>\n '
+ + '<param name="quality" value="high"></param>\n '
+ + '<param name="bgcolor" value="#ffffff"></param>\n '
+ + '<embed src="' + swflocEmbed + '" '
+ + 'quality="high" '
+ + 'bgcolor="#ffffff" '
+ + 'width="' + this.width + '" '
+ + 'height="' + this.height + '" '
+ + 'id="' + this.id + 'Embed' + '" '
+ + 'name="' + this.id + '" '
+ + 'swLiveConnect="true" '
+ + 'align="middle" '
+ + 'allowScriptAccess="sameDomain" '
+ + 'type="application/x-shockwave-flash" '
+ + 'pluginspage="'
+ + this.protocol()
+ +'://www.macromedia.com/go/getflashplayer" '
+ + '></embed>\n'
+ + '</object>\n';
+
+ // using same mechanism on all browsers now to write out
+ // Flash object into page
+
+ // document.write no longer works correctly
+ // due to Eolas patent workaround in IE;
+ // nothing happens (i.e. object doesn't
+ // go into page if we use it)
+ dojo.connect(dojo, "loaded", dojo.hitch(this, function(){
+ var div = document.createElement("div");
+ div.setAttribute("id", this.id + "Container");
+ div.setAttribute("style", containerStyle);
+ div.innerHTML = objectHTML;
+
+ var body = document.getElementsByTagName("body");
+ if(!body || !body.length){
+ throw new Error("No body tag for this page");
+ }
+ body = body[0];
+ body.appendChild(div);
+ }));
+ },
+
+ get: function(){ /* Object */
+ // summary: Gets the Flash object DOM node.
+ if(dojo.isIE || dojo.isSafari){
+ return document.getElementById(this.id);
+ }else{
+ // different IDs on OBJECT and EMBED tags or
+ // else Firefox will return wrong one and
+ // communication won't work;
+ // also, document.getElementById() returns a
+ // plugin but ExternalInterface calls don't
+ // work on it so we have to use
+ // document[id] instead
+ return document[this.id + "Embed"];
+ }
+ },
+
+ setVisible: function(/* Boolean */ visible){
+ //console.debug("setVisible, visible="+visible);
+
+ // summary: Sets the visibility of this Flash object.
+ var container = dojo.byId(this.id + "Container");
+ if(visible == true){
+ container.style.position = "absolute"; // IE -- Brad Neuberg
+ container.style.visibility = "visible";
+ }else{
+ container.style.position = "absolute";
+ container.style.x = "-1000px";
+ container.style.y = "-1000px";
+ container.style.visibility = "hidden";
+ }
+ },
+
+ center: function(){
+ // summary: Centers the flash applet on the page.
+
+ var elementWidth = this.width;
+ var elementHeight = this.height;
+
+ var viewport = dijit.getViewport();
+
+ // compute the centered position
+ var x = viewport.l + (viewport.w - elementWidth) / 2;
+ var y = viewport.t + (viewport.h - elementHeight) / 2;
+
+ // set the centered position
+ var container = dojo.byId(this.id + "Container");
+ container.style.top = y + "px";
+ container.style.left = x + "px";
+ }
+};
+
+
+dojox.flash.Communicator = function(){
+ // summary:
+ // A class that is used to communicate between Flash and JavaScript.
+ // description:
+ // This class helps mediate Flash and JavaScript communication. Internally
+ // it uses Flash 8's ExternalInterface API, but adds functionality to fix
+ // various encoding bugs that ExternalInterface has.
+}
+
+dojox.flash.Communicator.prototype = {
+ // Registers the existence of a Flash method that we can call with
+ // JavaScript, using Flash 8's ExternalInterface.
+ _addExternalInterfaceCallback: function(methodName){
+ var wrapperCall = dojo.hitch(this, function(){
+ // some browsers don't like us changing values in the 'arguments' array, so
+ // make a fresh copy of it
+ var methodArgs = new Array(arguments.length);
+ for(var i = 0; i < arguments.length; i++){
+ methodArgs[i] = this._encodeData(arguments[i]);
+ }
+
+ var results = this._execFlash(methodName, methodArgs);
+ results = this._decodeData(results);
+
+ return results;
+ });
+
+ this[methodName] = wrapperCall;
+ },
+
+ // Encodes our data to get around ExternalInterface bugs that are still
+ // present even in Flash 9.
+ _encodeData: function(data){
+ if(!data || typeof data != "string"){
+ return data;
+ }
+
+ // double encode all entity values, or they will be mis-decoded
+ // by Flash when returned
+ var entityRE = /\&([^;]*)\;/g;
+ data = data.replace(entityRE, "&amp;$1;");
+
+ // entity encode XML-ish characters, or Flash's broken XML serializer
+ // breaks
+ data = data.replace(/</g, "&lt;");
+ data = data.replace(/>/g, "&gt;");
+
+ // transforming \ into \\ doesn't work; just use a custom encoding
+ data = data.replace("\\", "&custom_backslash;");
+
+ data = data.replace(/\0/g, "\\0"); // null character
+ data = data.replace(/\"/g, "&quot;");
+
+ return data;
+ },
+
+ // Decodes our data to get around ExternalInterface bugs that are still
+ // present even in Flash 9.
+ _decodeData: function(data){
+ // wierdly enough, Flash sometimes returns the result as an
+ // 'object' that is actually an array, rather than as a String;
+ // detect this by looking for a length property; for IE
+ // we also make sure that we aren't dealing with a typeof string
+ // since string objects have length property there
+ if(data && data.length && typeof data != "string"){
+ data = data[0];
+ }
+
+ if(!data || typeof data != "string"){
+ return data;
+ }
+
+ // certain XMLish characters break Flash's wire serialization for
+ // ExternalInterface; these are encoded on the
+ // DojoExternalInterface side into a custom encoding, rather than
+ // the standard entity encoding, because otherwise we won't be able to
+ // differentiate between our own encoding and any entity characters
+ // that are being used in the string itself
+ data = data.replace(/\&custom_lt\;/g, "<");
+ data = data.replace(/\&custom_gt\;/g, ">");
+ data = data.replace(/\&custom_backslash\;/g, '\\');
+
+ // needed for IE; \0 is the NULL character
+ data = data.replace(/\\0/g, "\0");
+
+ return data;
+ },
+
+ // Executes a Flash method; called from the JavaScript wrapper proxy we
+ // create on dojox.flash.comm.
+ _execFlash: function(methodName, methodArgs){
+ var plugin = dojox.flash.obj.get();
+ methodArgs = (methodArgs) ? methodArgs : [];
+
+ // encode arguments that are strings
+ for(var i = 0; i < methodArgs; i++){
+ if(typeof methodArgs[i] == "string"){
+ methodArgs[i] = this._encodeData(methodArgs[i]);
+ }
+ }
+
+ // we use this gnarly hack below instead of
+ // plugin[methodName] for two reasons:
+ // 1) plugin[methodName] has no call() method, which
+ // means we can't pass in multiple arguments dynamically
+ // to a Flash method -- we can only have one
+ // 2) On IE plugin[methodName] returns undefined --
+ // plugin[methodName] used to work on IE when we
+ // used document.write but doesn't now that
+ // we use dynamic DOM insertion of the Flash object
+ // -- Brad Neuberg
+ var flashExec = function(){
+ return eval(plugin.CallFunction(
+ "<invoke name=\"" + methodName
+ + "\" returntype=\"javascript\">"
+ + __flash__argumentsToXML(methodArgs, 0)
+ + "</invoke>"));
+ };
+ var results = flashExec.call(methodArgs);
+
+ if(typeof results == "string"){
+ results = this._decodeData(results);
+ }
+
+ return results;
+ }
+}
+
+// FIXME: dojo.declare()-ify this
+
+// TODO: I did not test the Install code when I refactored Dojo Flash from 0.4 to
+// 1.0, so am not sure if it works. If Flash is not present I now prefer
+// that Gears is installed instead of Flash because GearsStorageProvider is
+// much easier to work with than Flash's hacky ExternalInteface.
+// -- Brad Neuberg
+dojox.flash.Install = function(){
+ // summary: Helps install Flash plugin if needed.
+ // description:
+ // Figures out the best way to automatically install the Flash plugin
+ // for this browser and platform. Also determines if installation or
+ // revving of the current plugin is needed on this platform.
+}
+
+dojox.flash.Install.prototype = {
+ needed: function(){ /* Boolean */
+ // summary:
+ // Determines if installation or revving of the current plugin is
+ // needed.
+
+ // do we even have flash?
+ if(dojox.flash.info.capable == false){
+ return true;
+ }
+
+ // Must have ExternalInterface which came in Flash 8
+ if(!dojox.flash.info.isVersionOrAbove(8, 0, 0)){
+ return true;
+ }
+
+ // otherwise we don't need installation
+ return false;
+ },
+
+ install: function(){
+ // summary: Performs installation or revving of the Flash plugin.
+
+ // indicate that we are installing
+ dojox.flash.info.installing = true;
+ dojox.flash.installing();
+
+ if(dojox.flash.info.capable == false){ // we have no Flash at all
+ // write out a simple Flash object to force the browser to prompt
+ // the user to install things
+ var installObj = new dojox.flash.Embed(false);
+ installObj.write(); // write out HTML for Flash
+ }else if(dojox.flash.info.isVersionOrAbove(6, 0, 65)){ // Express Install
+ var installObj = new dojox.flash.Embed(false);
+ installObj.write(true); // write out HTML for Flash 8 version+
+ installObj.setVisible(true);
+ installObj.center();
+ }else{ // older Flash install than version 6r65
+ alert("This content requires a more recent version of the Macromedia "
+ +" Flash Player.");
+ window.location.href = + dojox.flash.Embed.protocol() +
+ "://www.macromedia.com/go/getflashplayer";
+ }
+ },
+
+ // Called when the Express Install is either finished, failed, or was
+ // rejected by the user.
+ _onInstallStatus: function(msg){
+ if (msg == "Download.Complete"){
+ // Installation is complete.
+ dojox.flash._initialize();
+ }else if(msg == "Download.Cancelled"){
+ alert("This content requires a more recent version of the Macromedia "
+ +" Flash Player.");
+ window.location.href = dojox.flash.Embed.protocol() +
+ "://www.macromedia.com/go/getflashplayer";
+ }else if (msg == "Download.Failed"){
+ // The end user failed to download the installer due to a network failure
+ alert("There was an error downloading the Flash Player update. "
+ + "Please try again later, or visit macromedia.com to download "
+ + "the latest version of the Flash plugin.");
+ }
+ }
+}
+
+// find out if Flash is installed
+dojox.flash.info = new dojox.flash.Info();
+
+// vim:ts=4:noet:tw=0:
+
+}
diff --git a/includes/js/dojox/flash/tests/TestFlash.as b/includes/js/dojox/flash/tests/TestFlash.as
new file mode 100644
index 0000000..d7be64f
--- /dev/null
+++ b/includes/js/dojox/flash/tests/TestFlash.as
@@ -0,0 +1,36 @@
+import DojoExternalInterface;
+import ExpressInstall;
+
+class TestFlash{
+ private var message:String;
+
+ public function TestFlash(){
+ }
+
+ public static function main(){
+ //getURL("javascript:alert('main')");
+ trace("main");
+ DojoExternalInterface.initialize();
+
+ var test = new TestFlash();
+ DojoExternalInterface.addCallback("setMessage", test, test.setMessage);
+ DojoExternalInterface.addCallback("getMessage", test, test.getMessage);
+ DojoExternalInterface.addCallback("multipleValues",
+ test, test.multipleValues);
+
+ DojoExternalInterface.done();
+ }
+
+ public function setMessage(message:String):Void{
+ this.message = message;
+ }
+
+ public function getMessage():String{
+ return this.message;
+ }
+
+ public function multipleValues(key:String, value:String,
+ namespace:String):String{
+ return namespace + key + value;
+ }
+} \ No newline at end of file
diff --git a/includes/js/dojox/flash/tests/TestFlash.swf b/includes/js/dojox/flash/tests/TestFlash.swf
new file mode 100644
index 0000000..cfd3f8d
--- /dev/null
+++ b/includes/js/dojox/flash/tests/TestFlash.swf
Binary files differ
diff --git a/includes/js/dojox/flash/tests/buildFlashTest.sh b/includes/js/dojox/flash/tests/buildFlashTest.sh
new file mode 100644
index 0000000..a73d20c
--- /dev/null
+++ b/includes/js/dojox/flash/tests/buildFlashTest.sh
@@ -0,0 +1,4 @@
+#!/bin/sh
+# TODO: FIXME: Get rid of this and hook it into Dojo's general build script
+# You must have mtasc to run this
+mtasc -trace DojoExternalInterface.trace -main -cp .. -swf TestFlash.swf -version 8 -header 215:138:10 TestFlash.as \ No newline at end of file
diff --git a/includes/js/dojox/flash/tests/test_flash.html b/includes/js/dojox/flash/tests/test_flash.html
new file mode 100644
index 0000000..5e09f45
--- /dev/null
+++ b/includes/js/dojox/flash/tests/test_flash.html
@@ -0,0 +1,15 @@
+<html>
+ <head>
+ <script src="../../../dojo/dojo.js" djConfig="isDebug: true"></script>
+
+ <script src="test_flash.js"></script>
+ </head>
+
+ <body>
+ <h1>Test Dojox Flash</h1>
+
+ <p>For detailed test output see Firebug console (if Firefox).
+ This test should be run on Firefox, Internet Explorer, and Safari
+ to confirm that Dojox Flash is working correctly.</p>
+ </body>
+</html> \ No newline at end of file
diff --git a/includes/js/dojox/flash/tests/test_flash.js b/includes/js/dojox/flash/tests/test_flash.js
new file mode 100644
index 0000000..1b26eb2
--- /dev/null
+++ b/includes/js/dojox/flash/tests/test_flash.js
@@ -0,0 +1,155 @@
+// TODO: FIXME: Refactor this to use D.O.H. instead of its own assertions
+
+dojo.require("dojox.flash");
+
+var flashLoaded = false;
+var pageLoaded = false;
+var testXML = testBook = null;
+
+function flashReady(){
+ console.debug("flashReady");
+ flashLoaded = true;
+
+ if(isReady()){
+ run();
+ }
+}
+
+function pageReady(){
+ console.debug("pageReady");
+ pageLoaded = true;
+
+ loadResources();
+
+ if(isReady()){
+ run();
+ }
+}
+
+function isReady(){
+ return testXML && testBook && pageLoaded && flashLoaded;
+}
+
+function loadResources(){
+ console.debug("Trying to load resources");
+
+ var d = dojo.xhrGet({
+ url: "../../storage/tests/resources/testXML.xml",
+ handleAs: "text"
+ });
+
+ d.addCallback(function(results){
+ console.debug("testXML loaded");
+ testXML = results;
+ if(isReady()){
+ run();
+ }
+ });
+
+ d.addErrback(function(error){
+ console.debug("Unable to load testXML.xml: " + error);
+ });
+
+ d = dojo.xhrGet({
+ url: "../../storage/tests/resources/testBook.txt",
+ handleAs: "text"
+ });
+
+ d.addCallback(function(results){
+ console.debug("testBook loaded");
+ testBook = results;
+ if(isReady()){
+ run();
+ }
+ });
+
+ d.addErrback(function(error){
+ console.debug("Unable to load testXML.xml: " + error);
+ });
+}
+
+function run(){
+ console.debug("run");
+ try{
+ var correct, actual;
+
+ console.debug("Setting simple message...");
+ correct = "hello world";
+ dojox.flash.comm.setMessage(correct);
+ actual = dojox.flash.comm.getMessage();
+ assert(correct, actual, "Setting/getting simple message did not work");
+
+ console.debug("Setting message with evil characters...");
+ // our correct and actual values get tricky when we have double back
+ // slashes; do a trick so that they can be compared easier
+ var doubleSlash = "\\";
+ doubleSlash = doubleSlash.charAt(0);
+ correct = "hello world\n\n\nasdfasdf!@#$@#%^[]{}&amp;<xml>" + doubleSlash
+ + "<div>$%^&%^&*^&()<><><>,./;\0\r\f\'][`~=\"+-]MORE!\n\rLESS";
+ dojox.flash.comm.setMessage(correct);
+ actual = dojox.flash.comm.getMessage();
+ assert(correct, actual, "Setting/getting message with evil characters did not work");
+
+ console.debug("Setting testXML...");
+ correct = testXML;
+ dojox.flash.comm.setMessage(correct);
+ actual = dojox.flash.comm.getMessage();
+ assert(correct, actual, "Setting/getting testXML did not work");
+
+ console.debug("Setting testBook(~300K)...");
+ correct = testBook;
+ dojox.flash.comm.setMessage(correct);
+ actual = dojox.flash.comm.getMessage();
+ assert(correct, actual, "Setting/getting testBook did not work");
+
+ console.debug("Setting testBook 3 times (~900K)...");
+ correct = testBook + testBook + testBook;
+ dojox.flash.comm.setMessage(correct);
+ actual = dojox.flash.comm.getMessage();
+ assert(correct, actual, "Setting/getting testBook X 3 did not work");
+
+ console.debug("Setting JSON...");
+ var obj = {type: "car", color: "red", model: "Ford", year: "2008",
+ features: ["A/C", "automatic", "4-wheel drive"]};
+ correct = dojo.toJson(obj, true);
+ dojox.flash.comm.setMessage(correct);
+ actual = dojox.flash.comm.getMessage();
+ assert(correct, actual, "Setting/getting JSON did not work");
+
+ console.debug("Calling method that takes multiple values...");
+ actual = dojox.flash.comm.multipleValues("key", "value", "namespace");
+ assert("namespacekeyvalue", actual, "Setting/getting multiple values did not work");
+
+ var allPassed = document.createElement("p");
+ allPassed.style.backgroundColor = "green";
+ allPassed.style.color = "white";
+ allPassed.style.fontSize = "24pt";
+ allPassed.appendChild(document.createTextNode("All tests passed"));
+ var body = document.getElementsByTagName("body")[0];
+ body.appendChild(allPassed);
+ }catch(e){
+ console.debug(e.message || e);
+ }
+}
+
+function assert(correct, actual, msg){
+ //alert("correct="+correct+",\n\nactual="+actual);
+ if(correct != actual){
+ var failed = document.createElement("p");
+ failed.style.backgroundColor = "red";
+ failed.style.color = "white";
+ failed.style.fontSize = "24pt";
+ failed.appendChild(document.createTextNode("Test failed: " + msg));
+ var body = document.getElementsByTagName("body")[0];
+ body.appendChild(failed);
+
+ throw new Error("ASSERTION FAILED: " + msg);
+ }else{
+ console.debug("Assertion passed");
+ }
+}
+
+console.debug("adding listeners...");
+dojox.flash.addLoadedListener(flashReady);
+dojox.flash.setSwf("TestFlash.swf", true);
+dojo.connect(dojo, "loaded", pageReady);