root/afridex/plugins/Flutter/js/swfupload.js @ 21

Revision 21, 38.5 kB (checked in by admin, 18 years ago)
RevLine 
[21]1/**
2 * SWFUpload v2.0 by Jacob Roberts, Nov 2007, http://www.swfupload.org, http://linebyline.blogspot.com
3 * -------- -------- -------- -------- -------- -------- -------- --------
4 * SWFUpload is (c) 2006 Lars Huring and Mammon Media and is released under the MIT License:
5 * http://www.opensource.org/licenses/mit-license.php
6 *
7 * See Changelog.txt for version history
8 *
9 * Development Notes:
10 *  * This version of SWFUpload requires Flash Player 9.0.28 and should autodetect the correct flash version.
11 *  * In Linux Flash Player 9 setting the post file variable name does not work. It is always set to "Filedata".
12 *  * There is a lot of repeated code that could be refactored to single functions.  Feel free.
13 *  * It's dangerous to do "circular calls" between Flash and JavaScript. I've taken steps to try to work around issues
14 *     by having the event calls pipe through setTimeout.  However you should still avoid calling in to Flash from
15 *     within the event handler methods.  Especially the "startUpload" event since it cannot use the setTimeout hack.
16 */
17
18
19/* *********** */
20/* Constructor */
21/* *********** */
22
23var SWFUpload = function (init_settings) {
24        this.initSWFUpload(init_settings);
25};
26
27SWFUpload.prototype.initSWFUpload = function (init_settings) {
28        // Remove background flicker in IE (read this: http://misterpixel.blogspot.com/2006/09/forensic-analysis-of-ie6.html)
29        // This doesn't have anything to do with SWFUpload but can help your UI behave better in IE.
30        try {
31                document.execCommand('BackgroundImageCache', false, true);
32        } catch (ex1) {
33        }
34
35
36        try {
37                this.customSettings = {};       // A container where developers can place their own settings associated with this instance.
38                this.settings = {};
39                this.eventQueue = [];
40                this.movieName = "SWFUpload_" + SWFUpload.movieCount++;
41                this.movieElement = null;
42
43                // Setup global control tracking
44                SWFUpload.instances[this.movieName] = this;
45
46                // Load the settings.  Load the Flash movie.
47                this.initSettings(init_settings);
48                this.loadFlash();
49
50                this.displayDebugInfo();
51
52        } catch (ex2) {
53                this.debug(ex2);
54        }
55}
56
57/* *************** */
58/* Static thingies */
59/* *************** */
60SWFUpload.instances = {};
61SWFUpload.movieCount = 0;
62SWFUpload.QUEUE_ERROR = {
63        QUEUE_LIMIT_EXCEEDED                    : -100,
64        FILE_EXCEEDS_SIZE_LIMIT                 : -110,
65        ZERO_BYTE_FILE                                  : -120,
66        INVALID_FILETYPE                                : -130
67};
68SWFUpload.UPLOAD_ERROR = {
69        HTTP_ERROR                                              : -200,
70        MISSING_UPLOAD_URL                      : -210,
71        IO_ERROR                                                : -220,
72        SECURITY_ERROR                                  : -230,
73        UPLOAD_LIMIT_EXCEEDED                   : -240,
74        UPLOAD_FAILED                                   : -250,
75        SPECIFIED_FILE_ID_NOT_FOUND             : -260,
76        FILE_VALIDATION_FAILED                  : -270,
77        FILE_CANCELLED                                  : -280,
78        UPLOAD_STOPPED                                  : -290
79};
80SWFUpload.FILE_STATUS = {
81        QUEUED           : -1,
82        IN_PROGRESS      : -2,
83        ERROR            : -3,
84        COMPLETE         : -4,
85        CANCELLED        : -5
86};
87
88
89/* ***************** */
90/* Instance Thingies */
91/* ***************** */
92// init is a private method that ensures that all the object settings are set, getting a default value if one was not assigned.
93
94SWFUpload.prototype.initSettings = function (init_settings) {
95        // Upload backend settings
96        this.addSetting("upload_url",                           init_settings.upload_url,                               "");
97        this.addSetting("file_post_name",                       init_settings.file_post_name,                   "Filedata");
98        this.addSetting("post_params",                          init_settings.post_params,                              {});
99
100        // File Settings
101        this.addSetting("file_types",                           init_settings.file_types,                               "*.*");
102        this.addSetting("file_types_description",       init_settings.file_types_description,   "All Files");
103        this.addSetting("file_size_limit",                      init_settings.file_size_limit,                  "1024");
104        this.addSetting("file_upload_limit",            init_settings.file_upload_limit,                "0");
105        this.addSetting("file_queue_limit",                     init_settings.file_queue_limit,                 "0");
106
107        // Flash Settings
108        this.addSetting("flash_url",                            init_settings.flash_url,                                "swfupload.swf");
109        this.addSetting("flash_width",                          init_settings.flash_width,                              "1px");
110        this.addSetting("flash_height",                         init_settings.flash_height,                             "1px");
111        this.addSetting("flash_color",                          init_settings.flash_color,                              "#FFFFFF");
112
113        // Debug Settings
114        this.addSetting("debug_enabled", init_settings.debug,  false);
115
116        // Event Handlers
117        this.flashReady_handler         = SWFUpload.flashReady; // This is a non-overrideable event handler
118        this.swfUploadLoaded_handler    = this.retrieveSetting(init_settings.swfupload_loaded_handler,      SWFUpload.swfUploadLoaded);
119       
120        this.fileDialogStart_handler    = this.retrieveSetting(init_settings.file_dialog_start_handler,         SWFUpload.fileDialogStart);
121        this.fileQueued_handler                 = this.retrieveSetting(init_settings.file_queued_handler,                       SWFUpload.fileQueued);
122        this.fileQueueError_handler             = this.retrieveSetting(init_settings.file_queue_error_handler,          SWFUpload.fileQueueError);
123        this.fileDialogComplete_handler = this.retrieveSetting(init_settings.file_dialog_complete_handler,      SWFUpload.fileDialogComplete);
124       
125        this.uploadStart_handler                = this.retrieveSetting(init_settings.upload_start_handler,                      SWFUpload.uploadStart);
126        this.uploadProgress_handler             = this.retrieveSetting(init_settings.upload_progress_handler,           SWFUpload.uploadProgress);
127        this.uploadError_handler                = this.retrieveSetting(init_settings.upload_error_handler,                      SWFUpload.uploadError);
128        this.uploadSuccess_handler              = this.retrieveSetting(init_settings.upload_success_handler,            SWFUpload.uploadSuccess);
129        this.uploadComplete_handler             = this.retrieveSetting(init_settings.upload_complete_handler,           SWFUpload.uploadComplete);
130
131        this.debug_handler                              = this.retrieveSetting(init_settings.debug_handler,                                     SWFUpload.debug);
132
133        // Other settings
134        this.customSettings = this.retrieveSetting(init_settings.custom_settings, {});
135};
136
137// loadFlash is a private method that generates the HTML tag for the Flash
138// It then adds the flash to the "target" or to the body and stores a
139// reference to the flash element in "movieElement".
140SWFUpload.prototype.loadFlash = function () {
141        var html, target_element, container;
142
143        // Make sure an element with the ID we are going to use doesn't already exist
144        if (document.getElementById(this.movieName) !== null) {
145                return false;
146        }
147
148        // Get the body tag where we will be adding the flash movie
149        try {
150                target_element = document.getElementsByTagName("body")[0];
151                if (typeof(target_element) === "undefined" || target_element === null) {
152                        this.debug('Could not find the BODY element. SWFUpload failed to load.');
153                        return false;
154                }
155        } catch (ex) {
156                return false;
157        }
158
159        // Append the container and load the flash
160        container = document.createElement("div");
161        container.style.width = this.getSetting("flash_width");
162        container.style.height = this.getSetting("flash_height");
163
164        target_element.appendChild(container);
165        container.innerHTML = this.getFlashHTML();      // Using innerHTML is non-standard but the only sensible way to dynamically add Flash in IE (and maybe other browsers)
166};
167
168// Generates the embed/object tags needed to embed the flash in to the document
169SWFUpload.prototype.getFlashHTML = function () {
170        var html = "";
171
172        // Create Mozilla Embed HTML
173        if (navigator.plugins && navigator.mimeTypes && navigator.mimeTypes.length) {
174                // Build the basic embed html
175                html = '<embed type="application/x-shockwave-flash" src="' + this.getSetting("flash_url") + '" width="' + this.getSetting("flash_width") + '" height="' + this.getSetting("flash_height") + '"';
176                html += ' id="' + this.movieName + '" name="' + this.movieName + '" ';
177                html += 'bgcolor="' + this.getSetting("flash_color") + '" quality="high" menu="false" flashvars="';
178
179                html += this.getFlashVars();
180
181                html += '" />';
182
183                // Create IE Object HTML
184        } else {
185
186                // Build the basic Object tag
187                html = '<object id="' + this.movieName + '" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" width="' + this.getSetting("flash_width") + '" height="' + this.getSetting("flash_height") + '">';
188                html += '<param name="movie" value="' + this.getSetting("flash_url") + '">';
189
190                html += '<param name="bgcolor" value="' + this.getSetting("flash_color") + '" />';
191                html += '<param name="quality" value="high" />';
192                html += '<param name="menu" value="false" />';
193
194                html += '<param name="flashvars" value="' + this.getFlashVars() + '" />';
195                html += '</object>';
196        }
197
198        return html;
199};
200
201// This private method builds the parameter string that will be passed
202// to flash.
203SWFUpload.prototype.getFlashVars = function () {
204        // Build a string from the post param object
205        var param_string = this.buildParamString();
206
207        // Build the parameter string
208        var html = "";
209        html += "movieName=" + encodeURIComponent(this.movieName);
210        html += "&uploadURL=" + encodeURIComponent(this.getSetting("upload_url"));
211        html += "&params=" + encodeURIComponent(param_string);
212        html += "&filePostName=" + encodeURIComponent(this.getSetting("file_post_name"));
213        html += "&fileTypes=" + encodeURIComponent(this.getSetting("file_types"));
214        html += "&fileTypesDescription=" + encodeURIComponent(this.getSetting("file_types_description"));
215        html += "&fileSizeLimit=" + encodeURIComponent(this.getSetting("file_size_limit"));
216        html += "&fileUploadLimit=" + encodeURIComponent(this.getSetting("file_upload_limit"));
217        html += "&fileQueueLimit=" + encodeURIComponent(this.getSetting("file_queue_limit"));
218        html += "&debugEnabled=" + encodeURIComponent(this.getSetting("debug_enabled"));
219
220        return html;
221};
222
223SWFUpload.prototype.getMovieElement = function () {
224        if (typeof(this.movieElement) === "undefined" || this.movieElement === null) {
225                this.movieElement = document.getElementById(this.movieName);
226
227                // Fix IEs "Flash can't callback when in a form" issue (http://www.extremefx.com.ar/blog/fixing-flash-external-interface-inside-form-on-internet-explorer)
228                // Removed because Revision 6 always adds the flash to the body (inside a containing div)
229                // If you insist on adding the Flash file inside a Form then in IE you have to make you wait until the DOM is ready
230                // and run this code to make the form's ID available from the window object so Flash and JavaScript can communicate.
231                //if (typeof(window[this.movieName]) === "undefined" || window[this.moveName] !== this.movieElement) {
232                //      window[this.movieName] = this.movieElement;
233                //}
234        }
235
236        return this.movieElement;
237};
238
239SWFUpload.prototype.buildParamString = function () {
240        var post_params = this.getSetting("post_params");
241        var param_string_pairs = [];
242        var i, value, name;
243
244        // Retrieve the user defined parameters
245        if (typeof(post_params) === "object") {
246                for (name in post_params) {
247                        if (post_params.hasOwnProperty(name)) {
248                                if (typeof(post_params[name]) === "string") {
249                                        param_string_pairs.push(encodeURIComponent(name) + "=" + encodeURIComponent(post_params[name]));
250                                }
251                        }
252                }
253        }
254
255        return param_string_pairs.join("&");
256};
257
258// Saves a setting.      If the value given is undefined or null then the default_value is used.
259SWFUpload.prototype.addSetting = function (name, value, default_value) {
260        if (typeof(value) === "undefined" || value === null) {
261                this.settings[name] = default_value;
262        } else {
263                this.settings[name] = value;
264        }
265
266        return this.settings[name];
267};
268
269// Gets a setting.      Returns empty string if not found.
270SWFUpload.prototype.getSetting = function (name) {
271        if (typeof(this.settings[name]) === "undefined") {
272                return "";
273        } else {
274                return this.settings[name];
275        }
276};
277
278// Gets a setting, if the setting is undefined then return the default value
279// This does not affect or use the interal setting object.
280SWFUpload.prototype.retrieveSetting = function (value, default_value) {
281        if (typeof(value) === "undefined" || value === null) {
282                return default_value;
283        } else {
284                return value;
285        }
286};
287
288
289// It loops through all the settings and displays
290// them in the debug Console.
291SWFUpload.prototype.displayDebugInfo = function () {
292        var key, debug_message = "";
293
294        debug_message += "----- SWFUPLOAD SETTINGS     ----\nID: " + this.moveName + "\n";
295
296        debug_message += this.outputObject(this.settings);
297
298        debug_message += "----- SWFUPLOAD SETTINGS END ----\n";
299        debug_message += "\n";
300
301        this.debug(debug_message);
302};
303SWFUpload.prototype.outputObject = function (object, prefix) {
304        var output = "", key;
305
306        if (typeof(prefix) !== "string") {
307                prefix = "";
308        }
309        if (typeof(object) !== "object") {
310                return "";
311        }
312
313        for (key in object) {
314                if (object.hasOwnProperty(key)) {
315                        if (typeof(object[key]) === "object") {
316                                output += (prefix + key + ": { \n" + this.outputObject(object[key], "\t" + prefix) + prefix + "}" + "\n");
317                        } else {
318                                output += (prefix + key + ": " + object[key] + "\n");
319                        }
320                }
321        }
322
323        return output;
324};
325
326/* *****************************
327        -- Flash control methods --
328        Your UI should use these
329        to operate SWFUpload
330   ***************************** */
331
332SWFUpload.prototype.selectFile = function () {
333        var movie_element = this.getMovieElement();
334        if (movie_element !== null && typeof(movie_element.SelectFile) === "function") {
335                try {
336                        movie_element.SelectFile();
337                }
338                catch (ex) {
339                        this.debug("Could not call SelectFile: " + ex);
340                }
341        } else {
342                this.debug("Could not find Flash element");
343        }
344
345};
346
347SWFUpload.prototype.selectFiles = function () {
348        var movie_element = this.getMovieElement();
349        if (movie_element !== null && typeof(movie_element.SelectFiles) === "function") {
350                try {
351                        movie_element.SelectFiles();
352                }
353                catch (ex) {
354                        this.debug("Could not call SelectFiles: " + ex);
355                }
356        } else {
357                this.debug("Could not find Flash element");
358        }
359
360};
361
362
363/* Start the upload.  If a file_id is specified that file is uploaded. Otherwise the first
364 * file in the queue is uploaded.  If no files are in the queue then nothing happens.
365 * This call uses setTimeout since Flash will be calling back in to JavaScript
366 */
367SWFUpload.prototype.startUpload = function (file_id) {
368        var self = this;
369        var movie_element = this.getMovieElement();
370        if (movie_element !== null && typeof(movie_element.StartUpload) === "function") {
371                setTimeout(
372                        function () {
373                                try {
374                                        movie_element.StartUpload(file_id);
375                                }
376                                catch (ex) {
377                                        self.debug("Could not call StartUpload: " + ex);
378                                }
379                        }, 0
380                );
381        } else {
382                this.debug("Could not find Flash element");
383        }
384
385};
386
387/* Cancels a the file upload.  You must specify a file_id */
388SWFUpload.prototype.cancelUpload = function (file_id) {
389        var movie_element = this.getMovieElement();
390        if (movie_element !== null && typeof(movie_element.CancelUpload) === "function") {
391                try {
392                        movie_element.CancelUpload(file_id);
393                }
394                catch (ex) {
395                        this.debug("Could not call CancelUpload: " + ex);
396                }
397        } else {
398                this.debug("Could not find Flash element");
399        }
400
401};
402
403// Stops the current upload.  The file is re-queued.  If nothing is currently uploading then nothing happens.
404SWFUpload.prototype.stopUpload = function () {
405        var movie_element = this.getMovieElement();
406        if (movie_element !== null && typeof(movie_element.StopUpload) === "function") {
407                try {
408                        movie_element.StopUpload();
409                }
410                catch (ex) {
411                        this.debug("Could not call StopUpload: " + ex);
412                }
413        } else {
414                this.debug("Could not find Flash element");
415        }
416
417};
418
419/* ************************
420 * Settings methods
421 *   These methods change the settings inside SWFUpload
422 *   They shouldn't need to be called in a setTimeout since they
423 *   should not call back from Flash to JavaScript (except perhaps in a Debug call)
424 *   and some need to return data so setTimeout won't work.
425 */
426
427/* Gets the file statistics object.      It looks like this (where n = number):
428        {
429                files_queued: n,
430                complete_uploads: n,
431                upload_errors: n,
432                uploads_cancelled: n,
433                queue_errors: n
434        }
435*/
436SWFUpload.prototype.getStats = function () {
437        var movie_element = this.getMovieElement();
438        if (movie_element !== null && typeof(movie_element.GetStats) === "function") {
439                try {
440                        return movie_element.GetStats();
441                }
442                catch (ex) {
443                        this.debug("Could not call GetStats");
444                }
445        } else {
446                this.debug("Could not find Flash element");
447        }
448};
449SWFUpload.prototype.setStats = function (stats_object) {
450        var movie_element = this.getMovieElement();
451        if (movie_element !== null && typeof(movie_element.SetStats) === "function") {
452                try {
453                        movie_element.SetStats(stats_object);
454                }
455                catch (ex) {
456                        this.debug("Could not call SetStats");
457                }
458        } else {
459                this.debug("Could not find Flash element");
460        }
461};
462
463SWFUpload.prototype.setCredentials = function(name, password) {
464        var movie_element = this.getMovieElement();
465        if (movie_element !== null && typeof(movie_element.SetCredentials) === "function") {
466                try {
467                        return movie_element.SetCredentials(name, password);
468                }
469                catch (ex) {
470                        this.debug("Could not call SetCredentials");
471                }
472        } else {
473                this.debug("Could not find Flash element");
474        }
475};
476
477SWFUpload.prototype.getFile = function (file_id) {
478        var movie_element = this.getMovieElement();
479                        if (typeof(file_id) === "number") {
480                                if (movie_element !== null && typeof(movie_element.GetFileByIndex) === "function") {
481                                        try {
482                                                return movie_element.GetFileByIndex(file_id);
483                                        }
484                                        catch (ex) {
485                                                this.debug("Could not call GetFileByIndex");
486                                        }
487                                } else {
488                                        this.debug("Could not find Flash element");
489                                }
490                        } else {
491                                if (movie_element !== null && typeof(movie_element.GetFile) === "function") {
492                                        try {
493                                                return movie_element.GetFile(file_id);
494                                        }
495                                        catch (ex) {
496                                                this.debug("Could not call GetFile");
497                                        }
498                                } else {
499                                        this.debug("Could not find Flash element");
500                                }
501                        }
502};
503
504SWFUpload.prototype.addFileParam = function (file_id, name, value) {
505        var movie_element = this.getMovieElement();
506        if (movie_element !== null && typeof(movie_element.AddFileParam) === "function") {
507                try {
508                        return movie_element.AddFileParam(file_id, name, value);
509                }
510                catch (ex) {
511                        this.debug("Could not call AddFileParam");
512                }
513        } else {
514                this.debug("Could not find Flash element");
515        }
516};
517
518SWFUpload.prototype.removeFileParam = function (file_id, name) {
519        var movie_element = this.getMovieElement();
520        if (movie_element !== null && typeof(movie_element.RemoveFileParam) === "function") {
521                try {
522                        return movie_element.RemoveFileParam(file_id, name);
523                }
524                catch (ex) {
525                        this.debug("Could not call AddFileParam");
526                }
527        } else {
528                this.debug("Could not find Flash element");
529        }
530
531};
532
533SWFUpload.prototype.setUploadURL = function (url) {
534        var movie_element = this.getMovieElement();
535        if (movie_element !== null && typeof(movie_element.SetUploadURL) === "function") {
536                try {
537                        this.addSetting("upload_url", url);
538                        movie_element.SetUploadURL(this.getSetting("upload_url"));
539                }
540                catch (ex) {
541                        this.debug("Could not call SetUploadURL");
542                }
543        } else {
544                this.debug("Could not find Flash element in setUploadURL");
545        }
546};
547
548SWFUpload.prototype.setPostParams = function (param_object) {
549        var movie_element = this.getMovieElement();
550        if (movie_element !== null && typeof(movie_element.SetPostParams) === "function") {
551                try {
552                        this.addSetting("post_params", param_object);
553                        movie_element.SetPostParams(this.getSetting("post_params"));
554                }
555                catch (ex) {
556                        this.debug("Could not call SetPostParams");
557                }
558        } else {
559                this.debug("Could not find Flash element in SetPostParams");
560        }
561};
562
563SWFUpload.prototype.setFileTypes = function (types, description) {
564        var movie_element = this.getMovieElement();
565        if (movie_element !== null && typeof(movie_element.SetFileTypes) === "function") {
566                try {
567                        this.addSetting("file_types", types);
568                        this.addSetting("file_types_description", description);
569                        movie_element.SetFileTypes(this.getSetting("file_types"), this.getSetting("file_types_description"));
570                }
571                catch (ex) {
572                        this.debug("Could not call SetFileTypes");
573                }
574        } else {
575                this.debug("Could not find Flash element in SetFileTypes");
576        }
577};
578
579SWFUpload.prototype.setFileSizeLimit = function (file_size_limit) {
580        var movie_element = this.getMovieElement();
581        if (movie_element !== null && typeof(movie_element.SetFileSizeLimit) === "function") {
582                try {
583                        this.addSetting("file_size_limit", file_size_limit);
584                        movie_element.SetFileSizeLimit(this.getSetting("file_size_limit"));
585                }
586                catch (ex) {
587                        this.debug("Could not call SetFileSizeLimit");
588                }
589        } else {
590                this.debug("Could not find Flash element in SetFileSizeLimit");
591        }
592};
593
594SWFUpload.prototype.setFileUploadLimit = function (file_upload_limit) {
595        var movie_element = this.getMovieElement();
596        if (movie_element !== null && typeof(movie_element.SetFileUploadLimit) === "function") {
597                try {
598                        this.addSetting("file_upload_limit", file_upload_limit);
599                        movie_element.SetFileUploadLimit(this.getSetting("file_upload_limit"));
600                }
601                catch (ex) {
602                        this.debug("Could not call SetFileUploadLimit");
603                }
604        } else {
605                this.debug("Could not find Flash element in SetFileUploadLimit");
606        }
607};
608
609SWFUpload.prototype.setFileQueueLimit = function (file_queue_limit) {
610        var movie_element = this.getMovieElement();
611        if (movie_element !== null && typeof(movie_element.SetFileQueueLimit) === "function") {
612                try {
613                        this.addSetting("file_queue_limit", file_queue_limit);
614                        movie_element.SetFileQueueLimit(this.getSetting("file_queue_limit"));
615                }
616                catch (ex) {
617                        this.debug("Could not call SetFileQueueLimit");
618                }
619        } else {
620                this.debug("Could not find Flash element in SetFileQueueLimit");
621        }
622};
623
624SWFUpload.prototype.setFilePostName = function (file_post_name) {
625        var movie_element = this.getMovieElement();
626        if (movie_element !== null && typeof(movie_element.SetFilePostName) === "function") {
627                try {
628                        this.addSetting("file_post_name", file_post_name);
629                        movie_element.SetFilePostName(this.getSetting("file_post_name"));
630                }
631                catch (ex) {
632                        this.debug("Could not call SetFilePostName");
633                }
634        } else {
635                this.debug("Could not find Flash element in SetFilePostName");
636        }
637};
638
639SWFUpload.prototype.setDebugEnabled = function (debug_enabled) {
640        var movie_element = this.getMovieElement();
641        if (movie_element !== null && typeof(movie_element.SetDebugEnabled) === "function") {
642                try {
643                        this.addSetting("debug_enabled", debug_enabled);
644                        movie_element.SetDebugEnabled(this.getSetting("debug_enabled"));
645                }
646                catch (ex) {
647                        this.debug("Could not call SetDebugEnabled");
648                }
649        } else {
650                this.debug("Could not find Flash element in SetDebugEnabled");
651        }
652};
653
654/* *******************************
655        Internal Event Callers
656        Don't override these! These event callers ensure that your custom event handlers
657        are called safely and in order.
658******************************* */
659
660/* This is the callback method that the Flash movie will call when it has been loaded and is ready to go.
661   Calling this or showUI() "manually" will bypass the Flash Detection built in to SWFUpload.
662   Use a ui_function setting if you want to control the UI loading after the flash has loaded.
663*/
664SWFUpload.prototype.flashReady = function () {
665        // Check that the movie element is loaded correctly with its ExternalInterface methods defined
666        var movie_element = this.getMovieElement();
667        if (movie_element === null || typeof(movie_element.StartUpload) !== "function") {
668                this.debug("ExternalInterface methods failed to initialize.");
669                return;
670        }
671       
672        var self = this;
673        if (typeof(self.flashReady_handler) === "function") {
674                this.eventQueue[this.eventQueue.length] = function() { self.flashReady_handler(); };
675                setTimeout(function () { self.executeNextEvent();}, 0);
676        } else {
677                this.debug("flashReady_handler event not defined");
678        }
679};
680
681/*
682        Event Queue.  Rather can call events directly from Flash they events are
683        are placed in a queue and then executed.  This ensures that each event is
684        executed in the order it was called which is not guarenteed when calling
685        setTimeout.  Out of order events was especially problematic in Safari.
686*/
687SWFUpload.prototype.executeNextEvent = function () {
688        var  f = this.eventQueue.shift();
689        if (typeof(f) === "function") {
690                f();
691        }
692}
693
694/* This is a chance to do something before the browse window opens */
695SWFUpload.prototype.fileDialogStart = function () {
696        var self = this;
697        if (typeof(self.fileDialogStart_handler) === "function") {
698                this.eventQueue[this.eventQueue.length] = function() { self.fileDialogStart_handler(); };
699                setTimeout(function () { self.executeNextEvent();}, 0);
700        } else {
701                this.debug("fileDialogStart event not defined");
702        }
703};
704
705
706/* Called when a file is successfully added to the queue. */
707SWFUpload.prototype.fileQueued = function (file) {
708        var self = this;
709        if (typeof(self.fileQueued_handler) === "function") {
710                this.eventQueue[this.eventQueue.length] = function() { self.fileQueued_handler(file); };
711                setTimeout(function () { self.executeNextEvent();}, 0);
712        } else {
713                this.debug("fileQueued event not defined");
714        }
715};
716
717
718/* Handle errors that occur when an attempt to queue a file fails. */
719SWFUpload.prototype.fileQueueError = function (file, error_code, message) {
720        var self = this;
721        if (typeof(self.fileQueueError_handler) === "function") {
722                this.eventQueue[this.eventQueue.length] = function() {  self.fileQueueError_handler(file, error_code, message); };
723                setTimeout(function () { self.executeNextEvent();}, 0);
724        } else {
725                this.debug("fileQueueError event not defined");
726        }
727};
728
729/* Called after the file dialog has closed and the selected files have been queued.
730        You could call startUpload here if you want the queued files to begin uploading immediately. */
731SWFUpload.prototype.fileDialogComplete = function (num_files_selected) {
732        var self = this;
733        if (typeof(self.fileDialogComplete_handler) === "function") {
734                this.eventQueue[this.eventQueue.length] = function() { self.fileDialogComplete_handler(num_files_selected); };
735                setTimeout(function () { self.executeNextEvent();}, 0);
736        } else {
737                this.debug("fileDialogComplete event not defined");
738        }
739};
740
741/* Gets called when a file upload is about to be started.  Return true to continue the upload. Return false to stop the upload.
742        If you return false then uploadError and uploadComplete are called (like normal).
743       
744        This is a good place to do any file validation you need.
745        */
746SWFUpload.prototype.uploadStart = function (file) {
747        var self = this;
748        if (typeof(self.fileDialogComplete_handler) === "function") {
749                this.eventQueue[this.eventQueue.length] = function() { self.returnUploadStart(self.uploadStart_handler(file)); };
750                setTimeout(function () { self.executeNextEvent();}, 0);
751        } else {
752                this.debug("uploadStart event not defined");
753        }
754};
755
756/* Note: Internal use only.  This function returns the result of uploadStart to
757        flash.  Since returning values in the normal way can result in Flash/JS circular
758        call issues we split up the call in a Timeout.  This is transparent from the API
759        point of view.
760*/
761SWFUpload.prototype.returnUploadStart = function (return_value) {
762        var movie_element = this.getMovieElement();
763        if (movie_element !== null && typeof(movie_element.ReturnUploadStart) === "function") {
764                try {
765                        movie_element.ReturnUploadStart(return_value);
766                }
767                catch (ex) {
768                        this.debug("Could not call ReturnUploadStart");
769                }
770        } else {
771                this.debug("Could not find Flash element in returnUploadStart");
772        }
773};
774
775
776
777/* Called during upload as the file progresses. Use this event to update your UI. */
778SWFUpload.prototype.uploadProgress = function (file, bytes_complete, bytes_total) {
779        var self = this;
780        if (typeof(self.uploadProgress_handler) === "function") {
781                this.eventQueue[this.eventQueue.length] = function() { self.uploadProgress_handler(file, bytes_complete, bytes_total); };
782                setTimeout(function () { self.executeNextEvent();}, 0);
783        } else {
784                this.debug("uploadProgress event not defined");
785        }
786};
787
788/* Called when an error occurs during an upload. Use error_code and the SWFUpload.UPLOAD_ERROR constants to determine
789   which error occurred. The uploadComplete event is called after an error code indicating that the next file is
790   ready for upload.  For files cancelled out of order the uploadComplete event will not be called. */
791SWFUpload.prototype.uploadError = function (file, error_code, message) {
792        var self = this;
793        if (typeof(this.uploadError_handler) === "function") {
794                this.eventQueue[this.eventQueue.length] = function() { self.uploadError_handler(file, error_code, message); };
795                setTimeout(function () { self.executeNextEvent();}, 0);
796        } else {
797                this.debug("uploadError event not defined");
798        }
799};
800
801/* This gets called when a file finishes uploading and the server-side upload script has completed and returned a 200
802status code. Any text returned by the server is available in server_data.
803**NOTE: The upload script MUST return some text or the uploadSuccess and uploadComplete events will not fire and the
804upload will become 'stuck'. */
805SWFUpload.prototype.uploadSuccess = function (file, server_data) {
806        var self = this;
807        if (typeof(self.uploadSuccess_handler) === "function") {
808                this.eventQueue[this.eventQueue.length] = function() { self.uploadSuccess_handler(file, server_data); };
809                setTimeout(function () { self.executeNextEvent();}, 0);
810        } else {
811                this.debug("uploadSuccess event not defined");
812        }
813};
814
815/* uploadComplete is called when the file is uploaded or an error occurred and SWFUpload is ready to make the next upload.
816   If you want the next upload to start to automatically you can call startUpload() from this event. */
817SWFUpload.prototype.uploadComplete = function (file) {
818        var self = this;
819        if (typeof(self.uploadComplete_handler) === "function") {
820                this.eventQueue[this.eventQueue.length] = function() { self.uploadComplete_handler(file); };
821                setTimeout(function () { self.executeNextEvent();}, 0);
822        } else {
823                this.debug("uploadComplete event not defined");
824        }
825};
826
827/* Called by SWFUpload JavaScript and Flash functions when debug is enabled. By default it writes messages to the
828   internal debug console.  You can override this event and have messages written where you want. */
829SWFUpload.prototype.debug = function (message) {
830        var self = this;
831        if (typeof(self.debug_handler) === "function") {
832                this.eventQueue[this.eventQueue.length] = function() { self.debug_handler(message); };
833                setTimeout(function () { self.executeNextEvent();}, 0);
834        } else {
835                this.eventQueue[this.eventQueue.length] = function() { self.debugMessage(message); };
836                setTimeout(function () { self.executeNextEvent();}, 0);
837        }
838};
839
840
841/* **********************************
842        Default Event Handlers.
843        These event handlers are used by default if an overriding handler is
844        not defined in the SWFUpload settings object.
845       
846        JS Note: even though these are defined on the SWFUpload object (rather than the prototype) they
847        are attached (read: copied) to a SWFUpload instance and 'this' is given the proper context.
848   ********************************** */
849
850/* This is a special event handler that has no override in the settings.  Flash calls this when it has
851   been loaded by the browser and is ready for interaction.  You should not override it.  If you need
852   to do something with SWFUpload has loaded then use the swfupload_loaded_handler setting.
853*/
854SWFUpload.flashReady = function () {
855        try {
856                this.debug("Flash called back and is ready.");
857
858                if (typeof(this.swfUploadLoaded_handler) === "function") {
859                        this.swfUploadLoaded_handler();
860                }
861        } catch (ex) {
862                this.debug(ex);
863        }
864};
865
866/* This is a chance to something immediately after SWFUpload has loaded.
867   Like, hide the default/degraded upload form and display the SWFUpload form. */
868SWFUpload.swfUploadLoaded = function () {
869};
870
871/* This is a chance to do something before the browse window opens */
872SWFUpload.fileDialogStart = function () {
873};
874
875
876/* Called when a file is successfully added to the queue. */
877SWFUpload.fileQueued = function (file) {
878};
879
880
881/* Handle errors that occur when an attempt to queue a file fails. */
882SWFUpload.fileQueueError = function (file, error_code, message) {
883        try {
884                switch (error_code) {
885                case SWFUpload.QUEUE_ERROR.FILE_EXCEEDS_SIZE_LIMIT:
886                        this.debug("Error Code: File too big, File name: " + file.name + ", File size: " + file.size + ", Message: " + message);
887                        break;
888                case SWFUpload.QUEUE_ERROR.ZERO_BYTE_FILE:
889                        this.debug("Error Code: Zero Byte File, File name: " + file.name + ", File size: " + file.size + ", Message: " + message);
890                        break;
891                case SWFUpload.QUEUE_ERROR.QUEUE_LIMIT_EXCEEDED:
892                        this.debug("Error Code: Upload limit reached, File name: " + file.name + ", File size: " + file.size + ", Message: " + message);
893                        break;
894                case SWFUpload.QUEUE_ERROR.INVALID_FILETYPE:
895                        this.debug("Error Code: File extension is not allowed, Message: " + message);
896                        break;
897                default:
898                        this.debug("Error Code: Unhandled error occured. Errorcode: " + error_code);
899                }
900        } catch (ex) {
901                this.debug(ex);
902        }
903};
904
905/* Called after the file dialog has closed and the selected files have been queued.
906        You could call startUpload here if you want the queued files to begin uploading immediately. */
907SWFUpload.fileDialogComplete = function (num_files_selected) {
908};
909
910/* Gets called when a file upload is about to be started.  Return true to continue the upload. Return false to stop the upload.
911        If you return false then the uploadError callback is called and then uploadComplete (like normal).
912       
913        This is a good place to do any file validation you need.
914       
915        This is the only function that cannot be called on a setTimeout because it must return a value to Flash.
916        You SHOULD NOT make any calls in to Flash (e.i, changing settings, getting stats, etc).  Flash Player bugs prevent
917        calls in to Flash from working reliably.
918*/
919SWFUpload.uploadStart = function (file) {
920        return true;
921};
922
923// Called during upload as the file progresses
924SWFUpload.uploadProgress = function (file, bytes_complete, bytes_total) {
925        this.debug("File Progress: " + file.id + ", Bytes: " + bytes_complete + ". Total: " + bytes_total);
926};
927
928/* This gets called when a file finishes uploading and the upload script has completed and returned a 200 status code.  Any text returned by the
929server is available in server_data.      The upload script must return some text or uploadSuccess will not fire (neither will uploadComplete). */
930SWFUpload.uploadSuccess = function (file, server_data) {
931};
932
933/* This is called last.  The file is uploaded or an error occurred and SWFUpload is ready to make the next upload.
934        If you want to automatically start the next file just call startUpload from here.
935*/
936SWFUpload.uploadComplete = function (file) {
937};
938
939// Called by SWFUpload JavaScript and Flash functions when debug is enabled.
940// Override this method in your settings to call your own debug message handler
941SWFUpload.debug = function (message) {
942        if (this.getSetting("debug_enabled")) {
943                this.debugMessage(message);
944        }
945};
946
947/* Called when an upload occurs during upload.  For HTTP errors 'message' will contain the HTTP STATUS CODE */
948SWFUpload.uploadError = function (file, error_code, message) {
949        try {
950                switch (errcode) {
951                case SWFUpload.UPLOAD_ERROR.SPECIFIED_FILE_ID_NOT_FOUND:
952                        this.debug("Error Code: File ID specified for upload was not found, Message: " + msg);
953                        break;
954                case SWFUpload.UPLOAD_ERROR.HTTP_ERROR:
955                        this.debug("Error Code: HTTP Error, File name: " + file.name + ", Message: " + msg);
956                        break;
957                case SWFUpload.UPLOAD_ERROR.MISSING_UPLOAD_URL:
958                        this.debug("Error Code: No backend file, File name: " + file.name + ", Message: " + msg);
959                        break;
960                case SWFUpload.UPLOAD_ERROR.IO_ERROR:
961                        this.debug("Error Code: IO Error, File name: " + file.name + ", Message: " + msg);
962                        break;
963                case SWFUpload.UPLOAD_ERROR.SECURITY_ERROR:
964                        this.debug("Error Code: Security Error, File name: " + file.name + ", Message: " + msg);
965                        break;
966                case SWFUpload.UPLOAD_ERROR.UPLOAD_LIMIT_EXCEEDED:
967                        this.debug("Error Code: Upload limit reached, File name: " + file.name + ", File size: " + file.size + ", Message: " + msg);
968                        break;
969                case SWFUpload.UPLOAD_ERROR.UPLOAD_FAILED:
970                        this.debug("Error Code: Upload Initialization exception, File name: " + file.name + ", File size: " + file.size + ", Message: " + msg);
971                        break;
972                case SWFUpload.UPLOAD_ERROR.FILE_VALIDATION_FAILED:
973                        this.debug("Error Code: uploadStart callback returned false, File name: " + file.name + ", File size: " + file.size + ", Message: " + msg);
974                        break;
975                case SWFUpload.UPLOAD_ERROR.FILE_CANCELLED:
976                        this.debug("Error Code: The file upload was cancelled, File name: " + file.name + ", File size: " + file.size + ", Message: " + msg);
977                        break;
978                case SWFUpload.UPLOAD_ERROR.UPLOAD_STOPPED:
979                        this.debug("Error Code: The file upload was stopped, File name: " + file.name + ", File size: " + file.size + ", Message: " + msg);
980                        break;
981                default:
982                        this.debug("Error Code: Unhandled error occured. Errorcode: " + errcode);
983                }
984        } catch (ex) {
985                this.debug(ex);
986        }
987};
988
989
990
991/* **********************************
992        Debug Console
993        The debug console is a self contained, in page location
994        for debug message to be sent.  The Debug Console adds
995        itself to the body if necessary.
996
997        The console is automatically scrolled as messages appear.
998       
999        You can override this console (to use FireBug's console for instance) by setting the debug event method to your own function
1000        that handles the debug message
1001   ********************************** */
1002SWFUpload.prototype.debugMessage = function (message) {
1003        var exception_message, exception_values;
1004
1005        if (typeof(message) === "object" && typeof(message.name) === "string" && typeof(message.message) === "string") {
1006                exception_message = "";
1007                exception_values = [];
1008                for (var key in message) {
1009                        exception_values.push(key + ": " + message[key]);
1010                }
1011                exception_message = exception_values.join("\n");
1012                exception_values = exception_message.split("\n");
1013                exception_message = "EXCEPTION: " + exception_values.join("\nEXCEPTION: ");
1014                SWFUpload.Console.writeLine(exception_message);
1015        } else {
1016                SWFUpload.Console.writeLine(message);
1017        }
1018};
1019
1020SWFUpload.Console = {};
1021SWFUpload.Console.writeLine = function (message) {
1022        var console, documentForm;
1023
1024        try {
1025                console = document.getElementById("SWFUpload_Console");
1026
1027                if (!console) {
1028                        documentForm = document.createElement("form");
1029                        document.getElementsByTagName("body")[0].appendChild(documentForm);
1030
1031                        console = document.createElement("textarea");
1032                        console.id = "SWFUpload_Console";
1033                        console.style.fontFamily = "monospace";
1034                        console.setAttribute("wrap", "off");
1035                        console.wrap = "off";
1036                        console.style.overflow = "auto";
1037                        console.style.width = "700px";
1038                        console.style.height = "350px";
1039                        console.style.margin = "5px";
1040                        documentForm.appendChild(console);
1041                }
1042
1043                console.value += message + "\n";
1044
1045                console.scrollTop = console.scrollHeight - console.clientHeight;
1046        } catch (ex) {
1047                alert("Exception: " + ex.name + " Message: " + ex.message);
1048        }
1049};
Note: See TracBrowser for help on using the browser.