dojo.provide("dojox.embed.Flash"); (function(){ /******************************************************* dojox.embed.Flash Base functionality to insert a flash movie into a document on the fly. Usage: var movie=new dojox.embed.Flash({ args }, containerNode); ******************************************************/ var fMarkup, fVersion; var minimumVersion = 9; // anything below this will throw an error (may overwrite) var keyBase = "dojox-embed-flash-", keyCount=0; var _baseKwArgs = { expressInstall: false, width: 320, height: 240, swLiveConnect: "true", allowScriptAccess: "sameDomain", allowNetworking:"all", style: null, redirect: null }; function prep(kwArgs){ // console.warn("KWARGS:", kwArgs) kwArgs = dojo.delegate(_baseKwArgs, kwArgs); if(!("path" in kwArgs)){ console.error("dojox.embed.Flash(ctor):: no path reference to a Flash movie was provided."); return null; } if(!("id" in kwArgs)){ kwArgs.id = (keyBase + keyCount++); } return kwArgs; } if(dojo.isIE){ fMarkup = function(kwArgs){ kwArgs = prep(kwArgs); if(!kwArgs){ return null; } var p; var path = kwArgs.path; if(kwArgs.vars){ var a = []; for(p in kwArgs.vars){ a.push(p + '=' + kwArgs.vars[p]); } path += ((path.indexOf("?") == -1) ? "?" : "&") + a.join("&"); } // FIXME: really? +'s? var s = '' + ''; if(kwArgs.params){ for(p in kwArgs.params){ s += ''; } } s += ''; return { id: kwArgs.id, markup: s }; }; fVersion = (function(){ var testVersion = 10, testObj = null; while(!testObj && testVersion > 7){ try { testObj = new ActiveXObject("ShockwaveFlash.ShockwaveFlash." + testVersion--); }catch(e){ } } if(testObj){ var v = testObj.GetVariable("$version").split(" ")[1].split(","); return { major: (v[0]!=null) ? parseInt(v[0]) : 0, minor: (v[1]!=null) ? parseInt(v[1]) : 0, rev: (v[2]!=null) ? parseInt(v[2]) : 0 }; } return { major: 0, minor: 0, rev: 0 }; })(); // attach some cleanup for IE, thanks to deconcept :) dojo.addOnUnload(function(){ var dummy = function(){}; var objs = dojo.query("object"). reverse(). style("display", "none"). forEach(function(i){ for(var p in i){ if((p != "FlashVars") && dojo.isFunction(i[p])){ try{ i[p] = dummy; }catch(e){} } } }); }); // TODO: ...and double check this fix; is IE really firing onbeforeunload with any kind of href="#" link? /* var beforeUnloadHandle = dojo.connect(dojo.global, "onbeforeunload", function(){ try{ if(__flash_unloadHandler){ __flash_unloadHandler=function(){ }; } if(__flash_savedUnloadHandler){ __flash_savedUnloadHandler=function(){ }; } } catch(e){ } dojo.disconnect(beforeUnloadHandle); }); */ } else { // *** Sane browsers branch ****************************************************************** fMarkup = function(kwArgs){ kwArgs = prep(kwArgs); if(!kwArgs){ return null; } var p; var path = kwArgs.path; if(kwArgs.vars){ var a = []; for(p in kwArgs.vars){ a.push(p + '=' + kwArgs.vars[p]); } path += ((path.indexOf("?") == -1) ? "?" : "&") + a.join("&"); } var s = '-1){ throw new Error("dojox.embed.Flash can't be run directly from a file. To instatiate the required SWF correctly it must be run from a server, like localHost."); } this.available = dojox.embed.Flash.available; this.minimumVersion = kwArgs.minimumVersion || minimumVersion; //console.log("AVAILABLE:", this); this.id = null; this.movie = null; this.domNode = null; if(node){ node = dojo.byId(node); } // setTimeout Fixes #8743 - creating double SWFs // also allows time for code to attach to onError setTimeout(dojo.hitch(this, function(){ if(this.available && this.available >= this.minimumVersion){ if(kwArgs && node){ this.init(kwArgs, node); }// FIXME: else what? }else{ if(!this.available){ this.onError("Flash is not installed."); }else{ this.onError("Flash version detected: "+this.available+" is out of date. Minimum required: "+this.minimumVersion); } } }), 100); }; dojo.extend(dojox.embed.Flash, { onReady: function(/*HTMLObject*/ movie){ // summary: // Stub function for you to attach to when the movie reference is first // pushed into the document. }, onLoad: function(/*HTMLObject*/ movie){ // summary: // Stub function for you to attach to when the movie has finished downloading // and is ready to be manipulated. }, onError: function(msg){ }, _onload: function(){ // summary: // Internal. Cleans up before calling onLoad. clearInterval(this._poller); delete this._poller; delete this._pollCount; delete this._pollMax; this.onLoad(this.movie); }, init: function(/*dojox.embed.__flashArgs*/ kwArgs, /*DOMNode?*/ node){ // summary // Initialize (i.e. place and load) the movie based on kwArgs. this.destroy(); // ensure we are clean first. node = dojo.byId(node || this.domNode); if(!node){ throw new Error("dojox.embed.Flash: no domNode reference has been passed."); } // vars to help determine load status var p = 0, testLoaded=false; this._poller = null; this._pollCount = 0; this._pollMax = 5; this.pollTime = 100; if(dojox.embed.Flash.initialized){ this.id = dojox.embed.Flash.place(kwArgs, node); this.domNode = node; setTimeout(dojo.hitch(this, function(){ this.movie = this.byId(this.id, kwArgs.doc); this.onReady(this.movie); this._poller = setInterval(dojo.hitch(this, function(){ // catch errors if not quite ready. try{ p = this.movie.PercentLoaded(); }catch(e){ /* squelch */ console.warn("this.movie.PercentLoaded() failed"); }; if(p == 100){ // if percent = 100, movie is fully loaded and we're communicating this._onload(); }else if(p==0 && this._pollCount++ > this._pollMax){ // after several attempts, we're not past zero. // FIXME: What if we get stuck on 33% or something? clearInterval(this._poller); throw new Error("Building SWF failed."); } }), this.pollTime); }), 1); } }, _destroy: function(){ // summary // Kill the movie and reset all the properties of this object. try{ this.domNode.removeChild(this.movie); }catch(e){} this.id = this.movie = this.domNode = null; }, destroy: function(){ // summary // Public interface for destroying all the properties in this object. // Will also clean all proxied methods. if(!this.movie){ return; } // remove any proxy functions var test = dojo.delegate({ id: true, movie: true, domNode: true, onReady: true, onLoad: true }); for(var p in this){ if(!test[p]){ delete this[p]; } } // pull the movie if(this._poller){ // wait until onLoad to destroy dojo.connect(this, "onLoad", this, "_destroy"); } else { this._destroy(); } }, byId: function (movieName, doc){ // summary: // Gets Flash movie by id. // description: // Probably includes methods for outdated // browsers, but this should catch all cases. // arguments: // movieName: String // The name of the SWF // doc: Object // The document, if not current window // (not fully supported) // example: // | var movie = dojox.embed.Flash.byId("myId"); // doc = doc || document; if(doc.embeds[movieName]){ return doc.embeds[movieName]; } if(doc[movieName]){ return doc[movieName]; } if(window[movieName]){ return window[movieName]; } if(document[movieName]){ return document[movieName]; } return null; } }); // expose information through the constructor function itself. dojo.mixin(dojox.embed.Flash, { // summary: // A singleton object used internally to get information // about the Flash player available in a browser, and // as the factory for generating and placing markup in a // document. // // minSupported: Number // The minimum supported version of the Flash Player, defaults to 8. // available: Number // Used as both a detection (i.e. if(dojox.embed.Flash.available){ }) // and as a variable holding the major version of the player installed. // supported: Boolean // Whether or not the Flash Player installed is supported by dojox.embed. // version: Object // The version of the installed Flash Player; takes the form of // { major, minor, rev }. To get the major version, you'd do this: // var v=dojox.embed.Flash.version.major; // initialized: Boolean // Whether or not the Flash engine is available for use. // onInitialize: Function // A stub you can connect to if you are looking to fire code when the // engine becomes available. A note: DO NOT use this event to // place a movie in a document; it will usually fire before DOMContentLoaded // is fired, and you will get an error. Use dojo.addOnLoad instead. minSupported : 8, available: fVersion.major, supported: (fVersion.major >= fVersion.required), minimumRequired: fVersion.required, version: fVersion, initialized: false, onInitialize: function(){ dojox.embed.Flash.initialized = true; }, __ie_markup__: function(kwArgs){ return fMarkup(kwArgs); }, proxy: function(/*dojox.embed.Flash*/ obj, /*Array|String*/ methods){ // summary: // Create the set of passed methods on the dojox.embed.Flash object // so that you can call that object directly, as opposed to having to // delve into the internal movie to do this. Intended to make working // with Flash movies that use ExternalInterface much easier to use. // // example: // Create "setMessage" and "getMessage" methods on foo. // | var foo = new dojox.embed.Flash(args, someNode); // | dojo.connect(foo, "onLoad", dojo.hitch(foo, function(){ // | dojox.embed.Flash.proxy(this, [ "setMessage", "getMessage" ]); // | this.setMessage("dojox.embed.Flash.proxy is pretty cool..."); // | console.log(this.getMessage()); // | })); dojo.forEach((dojo.isArray(methods) ? methods : [ methods ]), function(item){ this[item] = dojo.hitch(this, function(){ return (function(){ return eval(this.movie.CallFunction( '' + '' + dojo.map(arguments, function(item){ // FIXME: // investigate if __flash__toXML will // accept direct application via map() // (e.g., does it ignore args past the // first? or does it blow up?) return __flash__toXML(item); }).join("") + '' + '' )); }).apply(this, arguments||[]); }); }, obj); } }); if(dojo.isIE){ // Ugh! if(dojo._initFired){ var e = document.createElement("script"); e.type = "text/javascript"; e.src = dojo.moduleUrl("dojox", "embed/IE/flash.js"); document.getElementsByTagName("head")[0].appendChild(e); }else{ // we can use document.write. What a kludge. document.write('' + ''); } }else{ dojox.embed.Flash.place = function(kwArgs, node){ var o = fMarkup(kwArgs); node = dojo.byId(node); if(!node){ node = dojo.doc.createElement("div"); node.id = o.id+"-container"; dojo.body().appendChild(node); } if(o){ node.innerHTML = o.markup; return o.id; } return null; } dojox.embed.Flash.onInitialize(); } })();