source: Dev/branches/rest-dojo-ui/client/dojox/embed/Flash.js @ 256

Last change on this file since 256 was 256, checked in by hendrikvanantwerpen, 13 years ago

Reworked project structure based on REST interaction and Dojo library. As
soon as this is stable, the old jQueryUI branch can be removed (it's
kept for reference).

File size: 15.4 KB
Line 
1define(["dojo"], function(dojo) {
2
3        /*******************************************************
4                dojox.embed.Flash
5
6                Base functionality to insert a flash movie into
7                a document on the fly.
8
9                Usage:
10                var movie=new dojox.embed.Flash({ args }, containerNode);
11         ******************************************************/
12
13        dojo.getObject("embed", true, dojox);
14
15        var fMarkup, fVersion;
16        var minimumVersion = 9; // anything below this will throw an error (may overwrite)
17        var keyBase = "dojox-embed-flash-", keyCount=0;
18        var _baseKwArgs = {
19                expressInstall: false,
20                width: 320,
21                height: 240,
22                swLiveConnect: "true",
23                allowScriptAccess: "sameDomain",
24                allowNetworking:"all",
25                style: null,
26                redirect: null
27        };
28
29        function prep(kwArgs){
30                kwArgs = dojo.delegate(_baseKwArgs, kwArgs);
31
32                if(!("path" in kwArgs)){
33                        console.error("dojox.embed.Flash(ctor):: no path reference to a Flash movie was provided.");
34                        return null;
35                }
36
37                if(!("id" in kwArgs)){
38                        kwArgs.id = (keyBase + keyCount++);
39                }
40                return kwArgs;
41        }
42
43        if(dojo.isIE){
44                fMarkup = function(kwArgs){
45                        kwArgs = prep(kwArgs);
46                        if(!kwArgs){ return null; }
47
48                        var p;
49                        var path = kwArgs.path;
50                        if(kwArgs.vars){
51                                var a = [];
52                                for(p in kwArgs.vars){
53                                        a.push(p + '=' + kwArgs.vars[p]);
54                                }
55                                kwArgs.params.FlashVars = a.join("&");
56                                delete kwArgs.vars;
57                        }
58                        var s = '<object id="' + kwArgs.id + '" '
59                                + 'classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" '
60                                + 'width="' + kwArgs.width + '" '
61                                + 'height="' + kwArgs.height + '"'
62                                + ((kwArgs.style)?' style="' + kwArgs.style + '"':'')
63                                + '>'
64                                + '<param name="movie" value="' + path + '" />';
65                        if(kwArgs.params){
66                                for(p in kwArgs.params){
67                                        s += '<param name="' + p + '" value="' + kwArgs.params[p] + '" />';
68                                }
69                        }
70                        s += '</object>';
71                        return { id: kwArgs.id, markup: s };
72                };
73
74                fVersion = (function(){
75                        var testVersion = 10, testObj = null;
76                        while(!testObj && testVersion > 7){
77                                try {
78                                        testObj = new ActiveXObject("ShockwaveFlash.ShockwaveFlash." + testVersion--);
79                                }catch(e){ }
80                        }
81                        if(testObj){
82                                var v = testObj.GetVariable("$version").split(" ")[1].split(",");
83                                return {
84                                        major: (v[0]!=null) ? parseInt(v[0]) : 0,
85                                        minor: (v[1]!=null) ? parseInt(v[1]) : 0,
86                                        rev: (v[2]!=null) ? parseInt(v[2]) : 0
87                                };
88                        }
89                        return { major: 0, minor: 0, rev: 0 };
90                })();
91
92                //      attach some cleanup for IE, thanks to deconcept :)
93                dojo.addOnUnload(function(){
94                        var dummy = function(){};
95                        var objs = dojo.query("object").
96                                reverse().
97                                style("display", "none").
98                                forEach(function(i){
99                                        for(var p in i){
100                                                if((p != "FlashVars") && dojo.isFunction(i[p])){
101                                                        try{
102                                                                i[p] = dummy;
103                                                        }catch(e){}
104                                                }
105                                        }
106                                });
107                });
108
109        } else {
110                //      *** Sane browsers branch ******************************************************************
111                fMarkup = function(kwArgs){
112                        kwArgs = prep(kwArgs);
113                        if(!kwArgs){ return null; }
114
115                        var p;
116                        var path = kwArgs.path;
117                        if(kwArgs.vars){
118                                var a = [];
119                                for(p in kwArgs.vars){
120                                        a.push(p + '=' + kwArgs.vars[p]);
121                                }
122                                kwArgs.params.flashVars = a.join("&");
123                                delete kwArgs.vars;
124                        }
125                        var s = '<embed type="application/x-shockwave-flash" '
126                                + 'src="' + path + '" '
127                                + 'id="' + kwArgs.id + '" '
128                                + 'width="' + kwArgs.width + '" '
129                                + 'height="' + kwArgs.height + '"'
130                                + ((kwArgs.style)?' style="' + kwArgs.style + '" ':'')
131
132                                + 'pluginspage="' + window.location.protocol + '//www.adobe.com/go/getflashplayer" ';
133                        if(kwArgs.params){
134                                for(p in kwArgs.params){
135                                        s += ' ' + p + '="' + kwArgs.params[p] + '"';
136                                }
137                        }
138                        s += ' />';
139                        return { id: kwArgs.id, markup: s };
140                };
141
142                fVersion=(function(){
143                        var plugin = navigator.plugins["Shockwave Flash"];
144                        if(plugin && plugin.description){
145                                var v = plugin.description.replace(/([a-zA-Z]|\s)+/, "").replace(/(\s+r|\s+b[0-9]+)/, ".").split(".");
146                                return {
147                                        major: (v[0]!=null) ? parseInt(v[0]) : 0,
148                                        minor: (v[1]!=null) ? parseInt(v[1]) : 0,
149                                        rev: (v[2]!=null) ? parseInt(v[2]) : 0
150                                };
151                        }
152                        return { major: 0, minor: 0, rev: 0 };
153                })();
154        }
155
156
157/*=====
158dojox.embed.__flashArgs = function(path, id, width, height, style, params, vars, expressInstall, redirect){
159        //      path: String
160        //              The URL of the movie to embed.
161        //      id: String?
162        //              A unique key that will be used as the id of the created markup.  If you don't
163        //              provide this, a unique key will be generated.
164        //      width: Number?
165        //              The width of the embedded movie; the default value is 320px.
166        //      height: Number?
167        //              The height of the embedded movie; the default value is 240px
168        //      minimumVersion: Number ?
169        //              The minimum targeted version of the Flash Player (defaults to 9)
170        //      style: String?
171        //              Any CSS style information (i.e. style="background-color:transparent") you want
172        //              to define on the markup.
173        //      params: Object?
174        //              A set of key/value pairs that you want to define in the resultant markup.
175        //      vars: Object?
176        //              A set of key/value pairs that the Flash movie will interpret as FlashVars.
177        //      expressInstall: Boolean?
178        //              Whether or not to include any kind of expressInstall info. Default is false.
179        //      redirect: String?
180        //              A url to redirect the browser to if the current Flash version is not supported.
181        this.id=id;
182        this.path=path;
183        this.width=width;
184        this.minimumVersion=minimumVersion;
185        this.height=height;
186        this.style=style;
187        this.params=params;
188        this.vars=vars;
189        this.expressInstall=expressInstall;
190        this.redirect=redirect;
191}
192=====*/
193
194        //      the main entry point
195        dojox.embed.Flash = function(/*dojox.embed.__flashArgs*/ kwArgs, /*DOMNode*/ node){
196                //      summary:
197                //              Create a wrapper object around a Flash movie; this is the DojoX equivilent
198                //              to SWFObject.
199                //
200                //      description:
201                //              Creates a wrapper object around a Flash movie.  Wrapper object will
202                //              insert the movie reference in node; when the browser first starts
203                //              grabbing the movie, onReady will be fired; when the movie has finished
204                //              loading, it will fire onLoad.
205                //
206                //              If your movie uses ExternalInterface, you should use the onLoad event
207                //              to do any kind of proxy setup (see dojox.embed.Flash.proxy); this seems
208                //              to be the only consistent time calling EI methods are stable (since the
209                //              Flash movie will shoot several methods into the window object before
210                //              EI callbacks can be used properly).
211                //
212                //      kwArgs: dojox.embed.__flashArgs
213                //              The various arguments that will be used to help define the Flash movie.
214                //      node: DomNode
215                //              The node where the embed object will be placed
216                //
217                //      example:
218                //              Embed a flash movie in a document using the new operator, and get a reference to it.
219                //      |       var movie = new dojox.embed.Flash({
220                //      |               path: "path/to/my/movie.swf",
221                //      |               width: 400,
222                //      |               height: 300
223                //      |       }, myWrapperNode, "testLoaded");
224                //
225                //      example:
226                //              Embed a flash movie in a document without using the new operator.
227                //      |       var movie = dojox.embed.Flash({
228                //      |               path: "path/to/my/movie.swf",
229                //      |               width: 400,
230                //      |               height: 300,
231                //      |               style: "position:absolute;top:0;left:0"
232                //      |       }, myWrapperNode, "testLoaded");
233                //
234                // File can only be run from a server, due to SWF dependency.
235                if(location.href.toLowerCase().indexOf("file://")>-1){
236                        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.");
237                }
238
239                //      available: Number
240                //              If there is a flash player available, and if so what version.
241                this.available = dojox.embed.Flash.available;
242
243                //      minimumVersion: Number
244                //              The minimum version of Flash required to run this movie.
245                this.minimumVersion = kwArgs.minimumVersion || minimumVersion;
246
247                //      id: String
248                //              The id of the DOMNode to be used for this movie.  Can be used with dojo.byId to get a reference.
249                this.id = null;
250
251                //      movie: FlashObject
252                //              A reference to the movie itself.
253                this.movie = null;
254
255                //      domNode: DOMNode
256                //              A reference to the DOMNode that contains this movie.
257                this.domNode = null;
258                if(node){
259                        node = dojo.byId(node);
260                }
261                // setTimeout Fixes #8743 - creating double SWFs
262                // also allows time for code to attach to onError
263                setTimeout(dojo.hitch(this, function(){
264                        if(kwArgs.expressInstall || this.available && this.available >= this.minimumVersion){
265                                if(kwArgs && node){
266                                        this.init(kwArgs, node);
267                                }else{
268                                        this.onError("embed.Flash was not provided with the proper arguments.");
269                                }
270                        }else{
271                                if(!this.available){
272                                        this.onError("Flash is not installed.");
273                                }else{
274                                        this.onError("Flash version detected: "+this.available+" is out of date. Minimum required: "+this.minimumVersion);
275                                }
276                        }
277                }), 100);
278        };
279
280        dojo.extend(dojox.embed.Flash, {
281                onReady: function(/*HTMLObject*/ movie){
282                        //      summary:
283                        //              Stub function for you to attach to when the movie reference is first
284                        //              pushed into the document.
285                },
286                onLoad: function(/*HTMLObject*/ movie){
287                        //      summary:
288                        //              Stub function for you to attach to when the movie has finished downloading
289                        //              and is ready to be manipulated.
290                },
291                onError: function(msg){
292
293                },
294                _onload: function(){
295                        // summary:
296                        //      Internal. Cleans up before calling onLoad.
297                        clearInterval(this._poller);
298                        delete this._poller;
299                        delete this._pollCount;
300                        delete this._pollMax;
301                        this.onLoad(this.movie);
302                },
303                init: function(/*dojox.embed.__flashArgs*/ kwArgs, /*DOMNode?*/ node){
304                        //      summary
305                        //              Initialize (i.e. place and load) the movie based on kwArgs.
306                        this.destroy();         //      ensure we are clean first.
307                        node = dojo.byId(node || this.domNode);
308                        if(!node){ throw new Error("dojox.embed.Flash: no domNode reference has been passed."); }
309
310                        // vars to help determine load status
311                        var p = 0, testLoaded=false;
312                        this._poller = null; this._pollCount = 0; this._pollMax = 15; this.pollTime = 100;
313
314                        if(dojox.embed.Flash.initialized){
315
316                                this.id = dojox.embed.Flash.place(kwArgs, node);
317                                this.domNode = node;
318
319                                setTimeout(dojo.hitch(this, function(){
320                                        this.movie = this.byId(this.id, kwArgs.doc);
321                                        this.onReady(this.movie);
322
323                                        this._poller = setInterval(dojo.hitch(this, function(){
324
325                                                // catch errors if not quite ready.
326                                                try{
327                                                        p = this.movie.PercentLoaded();
328                                                }catch(e){
329                                                        console.warn("this.movie.PercentLoaded() failed", e, this.movie);
330                                                }
331
332                                                if(p == 100){
333                                                        // if percent = 100, movie is fully loaded and we're communicating
334                                                        this._onload();
335
336                                                }else if(p==0 && this._pollCount++ > this._pollMax){
337                                                        // after several attempts, we're not past zero.
338                                                        clearInterval(this._poller);
339                                                        throw new Error("Building SWF failed.");
340                                                }
341                                        }), this.pollTime);
342                                }), 1);
343                        }
344                },
345                _destroy: function(){
346                        //      summary
347                        //              Kill the movie and reset all the properties of this object.
348                        try{
349                                this.domNode.removeChild(this.movie);
350                        }catch(e){}
351                        this.id = this.movie = this.domNode = null;
352                },
353                destroy: function(){
354                        //      summary
355                        //              Public interface for destroying all the properties in this object.
356                        //              Will also clean all proxied methods.
357                        if(!this.movie){ return; }
358
359                        //      remove any proxy functions
360                        var test = dojo.delegate({
361                                id: true,
362                                movie: true,
363                                domNode: true,
364                                onReady: true,
365                                onLoad: true
366                        });
367                        for(var p in this){
368                                if(!test[p]){
369                                        delete this[p];
370                                }
371                        }
372
373                        //      poll the movie
374                        if(this._poller){
375                                //      wait until onLoad to destroy
376                                dojo.connect(this, "onLoad", this, "_destroy");
377                        } else {
378                                this._destroy();
379                        }
380                },
381                byId: function (movieName, doc){
382                        //      summary:
383                        //              Gets Flash movie by id.
384                        //      description:
385                        //              Probably includes methods for outdated
386                        //              browsers, but this should catch all cases.
387                        // arguments:
388                        //              movieName: String
389                        //                      The name of the SWF
390                        //              doc: Object
391                        //                      The document, if not current window
392                        //                      (not fully supported)
393                        //      example:
394                        //      | var movie = dojox.embed.Flash.byId("myId");
395                        //
396                        doc = doc || document;
397                        if(doc.embeds[movieName]){
398                                return doc.embeds[movieName];
399                        }
400                        if(doc[movieName]){
401                                return doc[movieName];
402                        }
403                        if(window[movieName]){
404                                return window[movieName];
405                        }
406                        if(document[movieName]){
407                                return document[movieName];
408                        }
409                        return null;
410                }
411        });
412
413        //      expose information through the constructor function itself.
414        dojo.mixin(dojox.embed.Flash, {
415                //      summary:
416                //              A singleton object used internally to get information
417                //              about the Flash player available in a browser, and
418                //              as the factory for generating and placing markup in a
419                //              document.
420                //
421                //      minSupported: Number
422                //              The minimum supported version of the Flash Player, defaults to 8.
423                //      available: Number
424                //              Used as both a detection (i.e. if(dojox.embed.Flash.available){ })
425                //              and as a variable holding the major version of the player installed.
426                //      supported: Boolean
427                //              Whether or not the Flash Player installed is supported by dojox.embed.
428                //      version: Object
429                //              The version of the installed Flash Player; takes the form of
430                //              { major, minor, rev }.  To get the major version, you'd do this:
431                //              var v=dojox.embed.Flash.version.major;
432                //      initialized: Boolean
433                //              Whether or not the Flash engine is available for use.
434                //      onInitialize: Function
435                //              A stub you can connect to if you are looking to fire code when the
436                //              engine becomes available.  A note: DO NOT use this event to
437                //              place a movie in a document; it will usually fire before DOMContentLoaded
438                //              is fired, and you will get an error.  Use dojo.addOnLoad instead.
439                minSupported : 8,
440                available: fVersion.major,
441                supported: (fVersion.major >= fVersion.required),
442                minimumRequired: fVersion.required,
443                version: fVersion,
444                initialized: false,
445                onInitialize: function(){
446                        dojox.embed.Flash.initialized = true;
447                },
448                __ie_markup__: function(kwArgs){
449                        return fMarkup(kwArgs);
450                },
451                proxy: function(/*dojox.embed.Flash*/ obj, /*Array|String*/ methods){
452                        //      summary:
453                        //              Create the set of passed methods on the dojox.embed.Flash object
454                        //              so that you can call that object directly, as opposed to having to
455                        //              delve into the internal movie to do this.  Intended to make working
456                        //              with Flash movies that use ExternalInterface much easier to use.
457                        //
458                        //      example:
459                        //              Create "setMessage" and "getMessage" methods on foo.
460                        //      |       var foo = new dojox.embed.Flash(args, someNode);
461                        //      |       dojo.connect(foo, "onLoad", dojo.hitch(foo, function(){
462                        //      |               dojox.embed.Flash.proxy(this, [ "setMessage", "getMessage" ]);
463                        //      |               this.setMessage("dojox.embed.Flash.proxy is pretty cool...");
464                        //      |               console.log(this.getMessage());
465                        //      |       }));
466                        dojo.forEach((dojo.isArray(methods) ? methods : [ methods ]), function(item){
467                                this[item] = dojo.hitch(this, function(){
468                                        return (function(){
469                                                return eval(this.movie.CallFunction(
470                                                        '<invoke name="' + item + '" returntype="javascript">'
471                                                        + '<arguments>'
472                                                        + dojo.map(arguments, function(item){
473                                                                // FIXME:
474                                                                //              investigate if __flash__toXML will
475                                                                //              accept direct application via map()
476                                                                //              (e.g., does it ignore args past the
477                                                                //              first? or does it blow up?)
478                                                                return __flash__toXML(item);
479                                                        }).join("")
480                                                        + '</arguments>'
481                                                        + '</invoke>'
482                                                ));
483                                        }).apply(this, arguments||[]);
484                                });
485                        }, obj);
486                }
487        });
488
489        dojox.embed.Flash.place = function(kwArgs, node){
490                var o = fMarkup(kwArgs);
491                node = dojo.byId(node);
492                if(!node){
493                        node = dojo.doc.createElement("div");
494                        node.id = o.id+"-container";
495                        dojo.body().appendChild(node);
496                }
497                if(o){
498                        node.innerHTML = o.markup;
499                        return o.id;
500                }
501                return null;
502        }
503        dojox.embed.Flash.onInitialize();
504
505        return dojox.embed.Flash;
506});
Note: See TracBrowser for help on using the repository browser.