Make WordPress Core

Changeset 9421


Ignore:
Timestamp:
10/30/2008 11:13:53 PM (16 years ago)
Author:
ryan
Message:

SWFUpload 2.2.0 beta 2 with Flash 10 support. Props filosofo. see #6979

Location:
trunk/wp-includes
Files:
3 added
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/wp-includes/js/swfupload/handlers.js

    r8998 r9421  
    206206}
    207207
     208function swfuploadPreLoad() {
     209    return true;
     210}
     211
     212function swfuploadLoadFailed() {
     213    return true;
     214}
     215
    208216function uploadError(fileObj, error_code, message) {
    209217    // first the file specific error
  • trunk/wp-includes/js/swfupload/plugins/swfupload.cookies.js

    r8057 r9421  
    99var SWFUpload;
    1010if (typeof(SWFUpload) === "function") {
    11     SWFUpload.prototype.initSettings = function (old_initSettings) {
    12         return function (init_settings) {
    13             if (typeof(old_initSettings) === "function") {
    14                 old_initSettings.call(this, init_settings);
     11    SWFUpload.prototype.initSettings = function (oldInitSettings) {
     12        return function () {
     13            if (typeof(oldInitSettings) === "function") {
     14                oldInitSettings.call(this);
    1515            }
    1616           
     
    1919    }(SWFUpload.prototype.initSettings);
    2020   
    21     // refreshes the post_params and updates SWFUpload.  The send_to_flash parameters is optional and defaults to True
    22     SWFUpload.prototype.refreshCookies = function (send_to_flash) {
    23         if (send_to_flash !== false) send_to_flash = true;
     21    // refreshes the post_params and updates SWFUpload.  The sendToFlash parameters is optional and defaults to True
     22    SWFUpload.prototype.refreshCookies = function (sendToFlash) {
     23        if (sendToFlash === undefined) {
     24            sendToFlash = true;
     25        }
     26        sendToFlash = !!sendToFlash;
    2427       
    2528        // Get the post_params object
    26         var post_params = this.getSetting("post_params");
     29        var postParams = this.settings.post_params;
    2730       
    2831        // Get the cookies
    29         var i, cookie_array = document.cookie.split(';'), ca_length = cookie_array.length, c, eq_index, name, value;
    30         for(i = 0; i < ca_length; i++) {
    31             c = cookie_array[i];
     32        var i, cookieArray = document.cookie.split(';'), caLength = cookieArray.length, c, eqIndex, name, value;
     33        for (i = 0; i < caLength; i++) {
     34            c = cookieArray[i];
    3235           
    3336            // Left Trim spaces
    34             while (c.charAt(0) == " ") {
     37            while (c.charAt(0) === " ") {
    3538                c = c.substring(1, c.length);
    3639            }
    37             eq_index = c.indexOf("=");
    38             if (eq_index > 0) {
    39                 name = c.substring(0, eq_index);
    40                 value = c.substring(eq_index+1);
    41                 post_params[name] = value;
     40            eqIndex = c.indexOf("=");
     41            if (eqIndex > 0) {
     42                name = c.substring(0, eqIndex);
     43                value = c.substring(eqIndex + 1);
     44                postParams[name] = value;
    4245            }
    4346        }
    4447       
    45         if (send_to_flash) {
    46             this.setPostParams(post_params);
     48        if (sendToFlash) {
     49            this.setPostParams(postParams);
    4750        }
    4851    };
  • trunk/wp-includes/js/swfupload/plugins/swfupload.queue.js

    r8057 r9421  
    33   
    44    Features:
    5         cancelQueue method for cancelling the entire queue.
    6         All queued files are uploaded when startUpload() is called.
    7         If false is returned from uploadComplete then the queue upload is stopped.  If false is not returned (strict comparison) then the queue upload is continued.
     5        *Adds a cancelQueue() method for cancelling the entire queue.
     6        *All queued files are uploaded when startUpload() is called.
     7        *If false is returned from uploadComplete then the queue upload is stopped.
     8         If false is not returned (strict comparison) then the queue upload is continued.
     9        *Adds a QueueComplete event that is fired when all the queued files have finished uploading.
     10         Set the event handler with the queue_complete_handler setting.
    811       
    912    */
     
    1316    SWFUpload.queue = {};
    1417   
    15     SWFUpload.prototype.initSettings = function (old_initSettings) {
    16         return function (init_settings) {
    17             if (typeof(old_initSettings) === "function") {
    18                 old_initSettings.call(this, init_settings);
     18    SWFUpload.prototype.initSettings = (function (oldInitSettings) {
     19        return function () {
     20            if (typeof(oldInitSettings) === "function") {
     21                oldInitSettings.call(this);
    1922            }
    2023           
    2124            this.customSettings.queue_cancelled_flag = false;
     25            this.customSettings.queue_upload_count = 0;
    2226           
    23             this.addSetting("user_upload_complete_handler", init_settings.upload_complete_handler, SWFUpload.uploadComplete);
    24             this.uploadComplete_handler = SWFUpload.queue.uploadComplete;
     27            this.settings.user_upload_complete_handler = this.settings.upload_complete_handler;
     28            this.settings.upload_complete_handler = SWFUpload.queue.uploadCompleteHandler;
     29           
     30            this.settings.queue_complete_handler = this.settings.queue_complete_handler || null;
    2531        };
    26     }(SWFUpload.prototype.initSettings);
     32    })(SWFUpload.prototype.initSettings);
     33
     34    SWFUpload.prototype.startUpload = function (fileID) {
     35        this.customSettings.queue_cancelled_flag = false;
     36        this.callFlash("StartUpload", false, [fileID]);
     37    };
    2738
    2839    SWFUpload.prototype.cancelQueue = function () {
     40        this.customSettings.queue_cancelled_flag = true;
     41        this.stopUpload();
     42       
    2943        var stats = this.getStats();
    30         this.customSettings.queue_cancelled_flag = false;
    31 
    32         if (stats.in_progress > 0) {
    33             this.customSettings.queue_cancelled_flag = true;
    34         }
    35        
    36         while(stats.files_queued > 0) {
     44        while (stats.files_queued > 0) {
    3745            this.cancelUpload();
    3846            stats = this.getStats();
     
    4048    };
    4149   
    42     SWFUpload.queue.uploadComplete = function (file) {
    43         var user_upload_complete_handler = this.getSetting("user_upload_complete_handler");
    44         var continue_upload = true;
     50    SWFUpload.queue.uploadCompleteHandler = function (file) {
     51        var user_upload_complete_handler = this.settings.user_upload_complete_handler;
     52        var continueUpload;
     53       
     54        if (file.filestatus === SWFUpload.FILE_STATUS.COMPLETE) {
     55            this.customSettings.queue_upload_count++;
     56        }
     57
    4558        if (typeof(user_upload_complete_handler) === "function") {
    46             continue_upload = (user_upload_complete_handler.call(this, file) === false) ? false : true;
     59            continueUpload = (user_upload_complete_handler.call(this, file) === false) ? false : true;
     60        } else {
     61            continueUpload = true;
    4762        }
    4863       
    49         if (continue_upload) {
     64        if (continueUpload) {
    5065            var stats = this.getStats();
    5166            if (stats.files_queued > 0 && this.customSettings.queue_cancelled_flag === false) {
    5267                this.startUpload();
     68            } else if (this.customSettings.queue_cancelled_flag === false) {
     69                this.queueEvent("queue_complete_handler", [this.customSettings.queue_upload_count]);
     70                this.customSettings.queue_upload_count = 0;
    5371            } else {
    5472                this.customSettings.queue_cancelled_flag = false;
     73                this.customSettings.queue_upload_count = 0;
    5574            }
    5675        }
  • trunk/wp-includes/js/swfupload/swfupload.js

    r8057 r9421  
    11/**
    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:
     2 * SWFUpload: http://www.swfupload.org, http://swfupload.googlecode.com
     3 *
     4 * mmSWFUpload 1.0: Flash upload dialog - http://profandesign.se/swfupload/,  http://www.vinterwebb.se/
     5 *
     6 * SWFUpload is (c) 2006-2007 Lars Huring, Olov Nilzén and Mammon Media and is released under the MIT License:
    57 * http://www.opensource.org/licenses/mit-license.php
    68 *
    7  * See Changelog.txt for version history
     9 * SWFUpload 2 is (c) 2007-2008 Jake Roberts and is released under the MIT License:
     10 * http://www.opensource.org/licenses/mit-license.php
    811 *
    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.
    1612 */
    1713
    1814
    19 /* *********** */
    20 /* Constructor */
    21 /* *********** */
    22 
    23 var SWFUpload = function (init_settings) {
    24     this.initSWFUpload(init_settings);
    25 };
    26 
    27 SWFUpload.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 
     15/* ******************* */
     16/* Constructor & Init  */
     17/* ******************* */
     18var SWFUpload;
     19
     20if (SWFUpload == undefined) {
     21    SWFUpload = function (settings) {
     22        this.initSWFUpload(settings);
     23    };
     24}
     25
     26SWFUpload.prototype.initSWFUpload = function (settings) {
    3627    try {
    3728        this.customSettings = {};   // A container where developers can place their own settings associated with this instance.
    38         this.settings = {};
     29        this.settings = settings;
    3930        this.eventQueue = [];
    4031        this.movieName = "SWFUpload_" + SWFUpload.movieCount++;
     
    4536
    4637        // Load the settings.  Load the Flash movie.
    47         this.initSettings(init_settings);
     38        this.initSettings();
    4839        this.loadFlash();
    49 
    5040        this.displayDebugInfo();
    51 
    52     } catch (ex2) {
    53         this.debug(ex2);
    54     }
    55 }
     41    } catch (ex) {
     42        delete SWFUpload.instances[this.movieName];
     43        throw ex;
     44    }
     45};
    5646
    5747/* *************** */
    58 /* Static thingies */
     48/* Static Members */
    5949/* *************** */
    6050SWFUpload.instances = {};
    6151SWFUpload.movieCount = 0;
     52SWFUpload.version = "2.2.0 Beta 2";
    6253SWFUpload.QUEUE_ERROR = {
    6354    QUEUE_LIMIT_EXCEEDED            : -100,
     
    8576    CANCELLED    : -5
    8677};
    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 
    94 SWFUpload.prototype.initSettings = function (init_settings) {
     78SWFUpload.BUTTON_ACTION = {
     79    SELECT_FILE  : -100,
     80    SELECT_FILES : -110,
     81    START_UPLOAD : -120
     82};
     83SWFUpload.CURSOR = {
     84    ARROW : -1,
     85    HAND : -2
     86};
     87SWFUpload.WINDOW_MODE = {
     88    WINDOW : "window",
     89    TRANSPARENT : "transparent",
     90    OPAQUE : "opaque"
     91};
     92
     93/* ******************** */
     94/* Instance Members  */
     95/* ******************** */
     96
     97// Private: initSettings ensures that all the
     98// settings are set, getting a default value if one was not assigned.
     99SWFUpload.prototype.initSettings = function () {
     100    this.ensureDefault = function (settingName, defaultValue) {
     101        this.settings[settingName] = (this.settings[settingName] == undefined) ? defaultValue : this.settings[settingName];
     102    };
     103   
    95104    // 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 
     105    this.ensureDefault("upload_url", "");
     106    this.ensureDefault("file_post_name", "Filedata");
     107    this.ensureDefault("post_params", {});
     108    this.ensureDefault("use_query_string", false);
     109    this.ensureDefault("requeue_on_error", false);
     110    this.ensureDefault("http_success", []);
     111   
    100112    // 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");
     113    this.ensureDefault("file_types", "*.*");
     114    this.ensureDefault("file_types_description", "All Files");
     115    this.ensureDefault("file_size_limit", 0);   // Default zero means "unlimited"
     116    this.ensureDefault("file_upload_limit", 0);
     117    this.ensureDefault("file_queue_limit", 0);
    106118
    107119    // 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 
     120    this.ensureDefault("flash_url", "swfupload.swf");
     121    this.ensureDefault("prevent_swf_caching", true);
     122   
     123    // Button Settings
     124    this.ensureDefault("button_image_url", "");
     125    this.ensureDefault("button_width", 1);
     126    this.ensureDefault("button_height", 1);
     127    this.ensureDefault("button_text", "");
     128    this.ensureDefault("button_text_style", "color: #000000; font-size: 16pt;");
     129    this.ensureDefault("button_text_top_padding", 0);
     130    this.ensureDefault("button_text_left_padding", 0);
     131    this.ensureDefault("button_action", SWFUpload.BUTTON_ACTION.SELECT_FILES);
     132    this.ensureDefault("button_disabled", false);
     133    this.ensureDefault("button_placeholder_id", null);
     134    this.ensureDefault("button_cursor", SWFUpload.CURSOR.ARROW);
     135    this.ensureDefault("button_window_mode", SWFUpload.WINDOW_MODE.WINDOW);
     136   
    113137    // Debug Settings
    114     this.addSetting("debug_enabled", init_settings.debug,  false);
    115 
     138    this.ensureDefault("debug", false);
     139    this.settings.debug_enabled = this.settings.debug;  // Here to maintain v2 API
     140   
    116141    // 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);
     142    this.settings.return_upload_start_handler = this.returnUploadStart;
     143    this.ensureDefault("swfupload_loaded_handler", null);
     144    this.ensureDefault("file_dialog_start_handler", null);
     145    this.ensureDefault("file_queued_handler", null);
     146    this.ensureDefault("file_queue_error_handler", null);
     147    this.ensureDefault("file_dialog_complete_handler", null);
     148   
     149    this.ensureDefault("upload_start_handler", null);
     150    this.ensureDefault("upload_progress_handler", null);
     151    this.ensureDefault("upload_error_handler", null);
     152    this.ensureDefault("upload_success_handler", null);
     153    this.ensureDefault("upload_complete_handler", null);
     154   
     155    this.ensureDefault("debug_handler", this.debugMessage);
     156
     157    this.ensureDefault("custom_settings", {});
    132158
    133159    // 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".
     160    this.customSettings = this.settings.custom_settings;
     161   
     162    // Update the flash url if needed
     163    if (this.settings.prevent_swf_caching) {
     164        this.settings.flash_url = this.settings.flash_url + "?swfuploadrnd=" + Math.floor(Math.random() * 999999999);
     165    }
     166   
     167    delete this.ensureDefault;
     168};
     169
    140170SWFUpload.prototype.loadFlash = function () {
    141     var html, target_element, container;
     171    if (this.settings.button_placeholder_id !== "") {
     172        this.replaceWithFlash();
     173    } else {
     174        this.appendFlash();
     175    }
     176};
     177
     178// Private: appendFlash gets the HTML tag for the Flash
     179// It then appends the flash to the body
     180SWFUpload.prototype.appendFlash = function () {
     181    var targetElement, container;
    142182
    143183    // Make sure an element with the ID we are going to use doesn't already exist
    144184    if (document.getElementById(this.movieName) !== null) {
    145         return false;
     185        throw "ID " + this.movieName + " is already in use. The Flash Object could not be added";
    146186    }
    147187
    148188    // 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;
     189    targetElement = document.getElementsByTagName("body")[0];
     190
     191    if (targetElement == undefined) {
     192        throw "Could not find the 'body' element.";
    157193    }
    158194
    159195    // Append the container and load the flash
    160196    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);
     197    container.style.width = "1px";
     198    container.style.height = "1px";
     199    container.style.overflow = "hidden";
     200
     201    targetElement.appendChild(container);
    165202    container.innerHTML = this.getFlashHTML();  // Using innerHTML is non-standard but the only sensible way to dynamically add Flash in IE (and maybe other browsers)
    166203};
    167204
    168 // Generates the embed/object tags needed to embed the flash in to the document
     205// Private: replaceWithFlash replaces the button_placeholder element with the flash movie.
     206SWFUpload.prototype.replaceWithFlash = function () {
     207    var targetElement, tempParent;
     208
     209    // Make sure an element with the ID we are going to use doesn't already exist
     210    if (document.getElementById(this.movieName) !== null) {
     211        throw "ID " + this.movieName + " is already in use. The Flash Object could not be added";
     212    }
     213
     214    // Get the element where we will be placing the flash movie
     215    targetElement = document.getElementById(this.settings.button_placeholder_id);
     216
     217    if (targetElement == undefined) {
     218        throw "Could not find the placeholder element.";
     219    }
     220
     221    // Append the container and load the flash
     222    tempParent = document.createElement("div");
     223    tempParent.innerHTML = this.getFlashHTML(); // Using innerHTML is non-standard but the only sensible way to dynamically add Flash in IE (and maybe other browsers)
     224    targetElement.parentNode.replaceChild(tempParent.firstChild, targetElement);
     225
     226};
     227
     228// Private: getFlashHTML generates the object tag needed to embed the flash in to the document
    169229SWFUpload.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.
     230    // Flash Satay object syntax: http://www.alistapart.com/articles/flashsatay
     231    return ['<object id="', this.movieName, '" type="application/x-shockwave-flash" data="', this.settings.flash_url, '" width="', this.settings.button_width, '" height="', this.settings.button_height, '" class="swfupload">',
     232                '<param name="wmode" value="', this.settings.button_window_mode , '" />',
     233                '<param name="movie" value="', this.settings.flash_url, '" />',
     234                '<param name="quality" value="high" />',
     235                '<param name="menu" value="false" />',
     236                '<param name="allowScriptAccess" value="always" />',
     237                '<param name="flashvars" value="' + this.getFlashVars() + '" />',
     238                '</object>'].join("");
     239};
     240
     241// Private: getFlashVars builds the parameter string that will be passed
     242// to flash in the flashvars param.
    203243SWFUpload.prototype.getFlashVars = function () {
    204244    // Build a string from the post param object
    205     var param_string = this.buildParamString();
    206 
     245    var paramString = this.buildParamString();
     246    var httpSuccessString = this.settings.http_success.join(",");
     247   
    207248    // 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 
     249    return ["movieName=", encodeURIComponent(this.movieName),
     250            "&amp;uploadURL=", encodeURIComponent(this.settings.upload_url),
     251            "&amp;useQueryString=", encodeURIComponent(this.settings.use_query_string),
     252            "&amp;requeueOnError=", encodeURIComponent(this.settings.requeue_on_error),
     253            "&amp;httpSuccess=", encodeURIComponent(httpSuccessString),
     254            "&amp;params=", encodeURIComponent(paramString),
     255            "&amp;filePostName=", encodeURIComponent(this.settings.file_post_name),
     256            "&amp;fileTypes=", encodeURIComponent(this.settings.file_types),
     257            "&amp;fileTypesDescription=", encodeURIComponent(this.settings.file_types_description),
     258            "&amp;fileSizeLimit=", encodeURIComponent(this.settings.file_size_limit),
     259            "&amp;fileUploadLimit=", encodeURIComponent(this.settings.file_upload_limit),
     260            "&amp;fileQueueLimit=", encodeURIComponent(this.settings.file_queue_limit),
     261            "&amp;debugEnabled=", encodeURIComponent(this.settings.debug_enabled),
     262            "&amp;buttonImageURL=", encodeURIComponent(this.settings.button_image_url),
     263            "&amp;buttonWidth=", encodeURIComponent(this.settings.button_width),
     264            "&amp;buttonHeight=", encodeURIComponent(this.settings.button_height),
     265            "&amp;buttonText=", encodeURIComponent(this.settings.button_text),
     266            "&amp;buttonTextTopPadding=", encodeURIComponent(this.settings.button_text_top_padding),
     267            "&amp;buttonTextLeftPadding=", encodeURIComponent(this.settings.button_text_left_padding),
     268            "&amp;buttonTextStyle=", encodeURIComponent(this.settings.button_text_style),
     269            "&amp;buttonAction=", encodeURIComponent(this.settings.button_action),
     270            "&amp;buttonDisabled=", encodeURIComponent(this.settings.button_disabled),
     271            "&amp;buttonCursor=", encodeURIComponent(this.settings.button_cursor)
     272        ].join("");
     273};
     274
     275// Public: getMovieElement retrieves the DOM reference to the Flash element added by SWFUpload
     276// The element is cached after the first lookup
    223277SWFUpload.prototype.getMovieElement = function () {
    224     if (typeof(this.movieElement) === "undefined" || this.movieElement === null) {
     278    if (this.movieElement == undefined) {
    225279        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 
     280    }
     281
     282    if (this.movieElement === null) {
     283        throw "Could not find Flash element";
     284    }
     285   
    236286    return this.movieElement;
    237287};
    238288
     289// Private: buildParamString takes the name/value pairs in the post_params setting object
     290// and joins them up in to a string formatted "name=value&amp;name=value"
    239291SWFUpload.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]));
     292    var postParams = this.settings.post_params;
     293    var paramStringPairs = [];
     294
     295    if (typeof(postParams) === "object") {
     296        for (var name in postParams) {
     297            if (postParams.hasOwnProperty(name)) {
     298                paramStringPairs.push(encodeURIComponent(name.toString()) + "=" + encodeURIComponent(postParams[name].toString()));
     299            }
     300        }
     301    }
     302
     303    return paramStringPairs.join("&amp;");
     304};
     305
     306// Public: Used to remove a SWFUpload instance from the page. This method strives to remove
     307// all references to the SWF, and other objects so memory is properly freed.
     308// Returns true if everything was destroyed. Returns a false if a failure occurs leaving SWFUpload in an inconsistant state.
     309SWFUpload.prototype.destroy = function () {
     310    try {
     311        // Make sure Flash is done before we try to remove it
     312        this.stopUpload();
     313       
     314        // Remove the SWFUpload DOM nodes
     315        var movieElement = null;
     316        try {
     317            movieElement = this.getMovieElement();
     318        } catch (ex) {
     319        }
     320       
     321        if (movieElement != undefined && movieElement.parentNode != undefined && typeof movieElement.parentNode.removeChild === "function") {
     322            var container = movieElement.parentNode;
     323            if (container != undefined) {
     324                container.removeChild(movieElement);
     325                if (container.parentNode != undefined && typeof container.parentNode.removeChild === "function") {
     326                    container.parentNode.removeChild(container);
    250327                }
    251328            }
    252329        }
    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.
     330       
     331        // Destroy references
     332        SWFUpload.instances[this.movieName] = null;
     333        delete SWFUpload.instances[this.movieName];
     334
     335        delete this.movieElement;
     336        delete this.settings;
     337        delete this.customSettings;
     338        delete this.eventQueue;
     339        delete this.movieName;
     340       
     341        delete window[this.movieName];
     342       
     343        return true;
     344    } catch (ex1) {
     345        return false;
     346    }
     347};
     348
     349// Public: displayDebugInfo prints out settings and configuration
     350// information about this SWFUpload instance.
     351// This function (and any references to it) can be deleted when placing
     352// SWFUpload in production.
     353SWFUpload.prototype.displayDebugInfo = function () {
     354    this.debug(
     355        [
     356            "---SWFUpload Instance Info---\n",
     357            "Version: ", SWFUpload.version, "\n",
     358            "Movie Name: ", this.movieName, "\n",
     359            "Settings:\n",
     360            "\t", "upload_url:               ", this.settings.upload_url, "\n",
     361            "\t", "flash_url:                ", this.settings.flash_url, "\n",
     362            "\t", "use_query_string:         ", this.settings.use_query_string.toString(), "\n",
     363            "\t", "requeue_on_error:         ", this.settings.requeue_on_error.toString(), "\n",
     364            "\t", "http_success:             ", this.settings.http_success.join(", "), "\n",
     365            "\t", "file_post_name:           ", this.settings.file_post_name, "\n",
     366            "\t", "post_params:              ", this.settings.post_params.toString(), "\n",
     367            "\t", "file_types:               ", this.settings.file_types, "\n",
     368            "\t", "file_types_description:   ", this.settings.file_types_description, "\n",
     369            "\t", "file_size_limit:          ", this.settings.file_size_limit, "\n",
     370            "\t", "file_upload_limit:        ", this.settings.file_upload_limit, "\n",
     371            "\t", "file_queue_limit:         ", this.settings.file_queue_limit, "\n",
     372            "\t", "debug:                    ", this.settings.debug.toString(), "\n",
     373
     374            "\t", "prevent_swf_caching:      ", this.settings.prevent_swf_caching.toString(), "\n",
     375
     376            "\t", "button_placeholder_id:    ", this.settings.button_placeholder_id.toString(), "\n",
     377            "\t", "button_image_url:         ", this.settings.button_image_url.toString(), "\n",
     378            "\t", "button_width:             ", this.settings.button_width.toString(), "\n",
     379            "\t", "button_height:            ", this.settings.button_height.toString(), "\n",
     380            "\t", "button_text:              ", this.settings.button_text.toString(), "\n",
     381            "\t", "button_text_style:        ", this.settings.button_text_style.toString(), "\n",
     382            "\t", "button_text_top_padding:  ", this.settings.button_text_top_padding.toString(), "\n",
     383            "\t", "button_text_left_padding: ", this.settings.button_text_left_padding.toString(), "\n",
     384            "\t", "button_action:            ", this.settings.button_action.toString(), "\n",
     385            "\t", "button_disabled:          ", this.settings.button_disabled.toString(), "\n",
     386
     387            "\t", "custom_settings:          ", this.settings.custom_settings.toString(), "\n",
     388            "Event Handlers:\n",
     389            "\t", "swfupload_loaded_handler assigned:  ", (typeof this.settings.swfupload_loaded_handler === "function").toString(), "\n",
     390            "\t", "file_dialog_start_handler assigned: ", (typeof this.settings.file_dialog_start_handler === "function").toString(), "\n",
     391            "\t", "file_queued_handler assigned:       ", (typeof this.settings.file_queued_handler === "function").toString(), "\n",
     392            "\t", "file_queue_error_handler assigned:  ", (typeof this.settings.file_queue_error_handler === "function").toString(), "\n",
     393            "\t", "upload_start_handler assigned:      ", (typeof this.settings.upload_start_handler === "function").toString(), "\n",
     394            "\t", "upload_progress_handler assigned:   ", (typeof this.settings.upload_progress_handler === "function").toString(), "\n",
     395            "\t", "upload_error_handler assigned:      ", (typeof this.settings.upload_error_handler === "function").toString(), "\n",
     396            "\t", "upload_success_handler assigned:    ", (typeof this.settings.upload_success_handler === "function").toString(), "\n",
     397            "\t", "upload_complete_handler assigned:   ", (typeof this.settings.upload_complete_handler === "function").toString(), "\n",
     398            "\t", "debug_handler assigned:             ", (typeof this.settings.debug_handler === "function").toString(), "\n"
     399        ].join("")
     400    );
     401};
     402
     403/* Note: addSetting and getSetting are no longer used by SWFUpload but are included
     404    the maintain v2 API compatibility
     405*/
     406// Public: (Deprecated) addSetting adds a setting value. If the value given is undefined or null then the default_value is used.
    259407SWFUpload.prototype.addSetting = function (name, value, default_value) {
    260     if (typeof(value) === "undefined" || value === null) {
    261         this.settings[name] = default_value;
     408    if (value == undefined) {
     409        return (this.settings[name] = default_value);
     410    } else {
     411        return (this.settings[name] = value);
     412    }
     413};
     414
     415// Public: (Deprecated) getSetting gets a setting. Returns an empty string if the setting was not found.
     416SWFUpload.prototype.getSetting = function (name) {
     417    if (this.settings[name] != undefined) {
     418        return this.settings[name];
     419    }
     420
     421    return "";
     422};
     423
     424
     425
     426// Private: callFlash handles function calls made to the Flash element.
     427// Calls are made with a setTimeout for some functions to work around
     428// bugs in the ExternalInterface library.
     429SWFUpload.prototype.callFlash = function (functionName, argumentArray) {
     430    argumentArray = argumentArray || [];
     431   
     432    var movieElement = this.getMovieElement();
     433    var returnValue;
     434
     435    if (typeof movieElement[functionName] === "function") {
     436        // We have to go through all this if/else stuff because the Flash functions don't have apply() and only accept the exact number of arguments.
     437        if (argumentArray.length === 0) {
     438            returnValue = movieElement[functionName]();
     439        } else if (argumentArray.length === 1) {
     440            returnValue = movieElement[functionName](argumentArray[0]);
     441        } else if (argumentArray.length === 2) {
     442            returnValue = movieElement[functionName](argumentArray[0], argumentArray[1]);
     443        } else if (argumentArray.length === 3) {
     444            returnValue = movieElement[functionName](argumentArray[0], argumentArray[1], argumentArray[2]);
     445        } else {
     446            throw "Too many arguments";
     447        }
     448       
     449        // Unescape file post param values
     450        if (returnValue != undefined && typeof returnValue.post === "object") {
     451            returnValue = this.unescapeFilePostParams(returnValue);
     452        }
     453       
     454        return returnValue;
    262455    } 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.
    270 SWFUpload.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.
    280 SWFUpload.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.
    291 SWFUpload.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 };
    303 SWFUpload.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 };
     456        throw "Invalid function name: " + functionName;
     457    }
     458};
     459
    325460
    326461/* *****************************
     
    330465   ***************************** */
    331466
     467// Public: selectFile causes a File Selection Dialog window to appear.  This
     468// dialog only allows 1 file to be selected. WARNING: this function does not work in Flash Player 10
    332469SWFUpload.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 
     470    this.callFlash("SelectFile");
     471};
     472
     473// Public: selectFiles causes a File Selection Dialog window to appear/ This
     474// dialog allows the user to select any number of files
     475// Flash Bug Warning: Flash limits the number of selectable files based on the combined length of the file names.
     476// If the selection name length is too long the dialog will fail in an unpredictable manner.  There is no work-around
     477// for this bug.  WARNING: this function does not work in Flash Player 10
    347478SWFUpload.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  */
    367 SWFUpload.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 */
    388 SWFUpload.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.
     479    this.callFlash("SelectFiles");
     480};
     481
     482
     483// Public: startUpload starts uploading the first file in the queue unless
     484// the optional parameter 'fileID' specifies the ID
     485SWFUpload.prototype.startUpload = function (fileID) {
     486    this.callFlash("StartUpload", [fileID]);
     487};
     488
     489// Public: cancelUpload cancels any queued file.  The fileID parameter may be the file ID or index.
     490// If you do not specify a fileID the current uploading file or first file in the queue is cancelled.
     491// If you do not want the uploadError event to trigger you can specify false for the triggerErrorEvent parameter.
     492SWFUpload.prototype.cancelUpload = function (fileID, triggerErrorEvent) {
     493    if (triggerErrorEvent !== false) {
     494        triggerErrorEvent = true;
     495    }
     496    this.callFlash("CancelUpload", [fileID, triggerErrorEvent]);
     497};
     498
     499// Public: stopUpload stops the current upload and requeues the file at the beginning of the queue.
     500// If nothing is currently uploading then nothing happens.
    404501SWFUpload.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 
     502    this.callFlash("StopUpload");
    417503};
    418504
    419505/* ************************
    420506 * 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 */
     507 *   These methods change the SWFUpload settings.
     508 *   SWFUpload settings should not be changed directly on the settings object
     509 *   since many of the settings need to be passed to Flash in order to take
     510 *   effect.
     511 * *********************** */
     512
     513// Public: getStats gets the file statistics object.
    436514SWFUpload.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();
     515    return this.callFlash("GetStats");
     516};
     517
     518// Public: setStats changes the SWFUpload statistics.  You shouldn't need to
     519// change the statistics but you can.  Changing the statistics does not
     520// affect SWFUpload accept for the successful_uploads count which is used
     521// by the upload_limit setting to determine how many files the user may upload.
     522SWFUpload.prototype.setStats = function (statsObject) {
     523    this.callFlash("SetStats", [statsObject]);
     524};
     525
     526// Public: getFile retrieves a File object by ID or Index.  If the file is
     527// not found then 'null' is returned.
     528SWFUpload.prototype.getFile = function (fileID) {
     529    if (typeof(fileID) === "number") {
     530        return this.callFlash("GetFileByIndex", [fileID]);
     531    } else {
     532        return this.callFlash("GetFile", [fileID]);
     533    }
     534};
     535
     536// Public: addFileParam sets a name/value pair that will be posted with the
     537// file specified by the Files ID.  If the name already exists then the
     538// exiting value will be overwritten.
     539SWFUpload.prototype.addFileParam = function (fileID, name, value) {
     540    return this.callFlash("AddFileParam", [fileID, name, value]);
     541};
     542
     543// Public: removeFileParam removes a previously set (by addFileParam) name/value
     544// pair from the specified file.
     545SWFUpload.prototype.removeFileParam = function (fileID, name) {
     546    this.callFlash("RemoveFileParam", [fileID, name]);
     547};
     548
     549// Public: setUploadUrl changes the upload_url setting.
     550SWFUpload.prototype.setUploadURL = function (url) {
     551    this.settings.upload_url = url.toString();
     552    this.callFlash("SetUploadURL", [url]);
     553};
     554
     555// Public: setPostParams changes the post_params setting
     556SWFUpload.prototype.setPostParams = function (paramsObject) {
     557    this.settings.post_params = paramsObject;
     558    this.callFlash("SetPostParams", [paramsObject]);
     559};
     560
     561// Public: addPostParam adds post name/value pair.  Each name can have only one value.
     562SWFUpload.prototype.addPostParam = function (name, value) {
     563    this.settings.post_params[name] = value;
     564    this.callFlash("SetPostParams", [this.settings.post_params]);
     565};
     566
     567// Public: removePostParam deletes post name/value pair.
     568SWFUpload.prototype.removePostParam = function (name) {
     569    delete this.settings.post_params[name];
     570    this.callFlash("SetPostParams", [this.settings.post_params]);
     571};
     572
     573// Public: setFileTypes changes the file_types setting and the file_types_description setting
     574SWFUpload.prototype.setFileTypes = function (types, description) {
     575    this.settings.file_types = types;
     576    this.settings.file_types_description = description;
     577    this.callFlash("SetFileTypes", [types, description]);
     578};
     579
     580// Public: setFileSizeLimit changes the file_size_limit setting
     581SWFUpload.prototype.setFileSizeLimit = function (fileSizeLimit) {
     582    this.settings.file_size_limit = fileSizeLimit;
     583    this.callFlash("SetFileSizeLimit", [fileSizeLimit]);
     584};
     585
     586// Public: setFileUploadLimit changes the file_upload_limit setting
     587SWFUpload.prototype.setFileUploadLimit = function (fileUploadLimit) {
     588    this.settings.file_upload_limit = fileUploadLimit;
     589    this.callFlash("SetFileUploadLimit", [fileUploadLimit]);
     590};
     591
     592// Public: setFileQueueLimit changes the file_queue_limit setting
     593SWFUpload.prototype.setFileQueueLimit = function (fileQueueLimit) {
     594    this.settings.file_queue_limit = fileQueueLimit;
     595    this.callFlash("SetFileQueueLimit", [fileQueueLimit]);
     596};
     597
     598// Public: setFilePostName changes the file_post_name setting
     599SWFUpload.prototype.setFilePostName = function (filePostName) {
     600    this.settings.file_post_name = filePostName;
     601    this.callFlash("SetFilePostName", [filePostName]);
     602};
     603
     604// Public: setUseQueryString changes the use_query_string setting
     605SWFUpload.prototype.setUseQueryString = function (useQueryString) {
     606    this.settings.use_query_string = useQueryString;
     607    this.callFlash("SetUseQueryString", [useQueryString]);
     608};
     609
     610// Public: setRequeueOnError changes the requeue_on_error setting
     611SWFUpload.prototype.setRequeueOnError = function (requeueOnError) {
     612    this.settings.requeue_on_error = requeueOnError;
     613    this.callFlash("SetRequeueOnError", [requeueOnError]);
     614};
     615
     616// Public: setHTTPSuccess changes the http_success setting
     617SWFUpload.prototype.setHTTPSuccess = function (http_status_codes) {
     618    if (typeof http_status_codes === "string") {
     619        http_status_codes = http_status_codes.replace(" ", "").split(",");
     620    }
     621   
     622    this.settings.http_success = http_status_codes;
     623    this.callFlash("SetHTTPSuccess", [http_status_codes]);
     624};
     625
     626
     627// Public: setDebugEnabled changes the debug_enabled setting
     628SWFUpload.prototype.setDebugEnabled = function (debugEnabled) {
     629    this.settings.debug_enabled = debugEnabled;
     630    this.callFlash("SetDebugEnabled", [debugEnabled]);
     631};
     632
     633// Public: setButtonImageURL loads a button image sprite
     634SWFUpload.prototype.setButtonImageURL = function (buttonImageURL) {
     635    if (buttonImageURL == undefined) {
     636        buttonImageURL = "";
     637    }
     638   
     639    this.settings.button_image_url = buttonImageURL;
     640    this.callFlash("SetButtonImageURL", [buttonImageURL]);
     641};
     642
     643// Public: setButtonDimensions resizes the Flash Movie and button
     644SWFUpload.prototype.setButtonDimensions = function (width, height) {
     645    this.settings.button_width = width;
     646    this.settings.button_height = height;
     647   
     648    var movie = this.getMovieElement();
     649    if (movie != undefined) {
     650        movie.style.width = width + "px";
     651        movie.style.height = height + "px";
     652    }
     653   
     654    this.callFlash("SetButtonDimensions", [width, height]);
     655};
     656// Public: setButtonText Changes the text overlaid on the button
     657SWFUpload.prototype.setButtonText = function (html) {
     658    this.settings.button_text = html;
     659    this.callFlash("SetButtonText", [html]);
     660};
     661// Public: setButtonTextPadding changes the top and left padding of the text overlay
     662SWFUpload.prototype.setButtonTextPadding = function (left, top) {
     663    this.settings.button_text_top_padding = top;
     664    this.settings.button_text_left_padding = left;
     665    this.callFlash("SetButtonTextPadding", [left, top]);
     666};
     667
     668// Public: setButtonTextStyle changes the CSS used to style the HTML/Text overlaid on the button
     669SWFUpload.prototype.setButtonTextStyle = function (css) {
     670    this.settings.button_text_style = css;
     671    this.callFlash("SetButtonTextStyle", [css]);
     672};
     673// Public: setButtonDisabled disables/enables the button
     674SWFUpload.prototype.setButtonDisabled = function (isDisabled) {
     675    this.settings.button_disabled = isDisabled;
     676    this.callFlash("SetButtonDisabled", [isDisabled]);
     677};
     678// Public: setButtonAction sets the action that occurs when the button is clicked
     679SWFUpload.prototype.setButtonAction = function (buttonAction) {
     680    this.settings.button_action = buttonAction;
     681    this.callFlash("SetButtonAction", [buttonAction]);
     682};
     683
     684// Public: setButtonCursor changes the mouse cursor displayed when hovering over the button
     685SWFUpload.prototype.setButtonCursor = function (cursor) {
     686    this.settings.button_cursor = cursor;
     687    this.callFlash("SetButtonCursor", [cursor]);
     688};
     689
     690/* *******************************
     691    Flash Event Interfaces
     692    These functions are used by Flash to trigger the various
     693    events.
     694   
     695    All these functions a Private.
     696   
     697    Because the ExternalInterface library is buggy the event calls
     698    are added to a queue and the queue then executed by a setTimeout.
     699    This ensures that events are executed in a determinate order and that
     700    the ExternalInterface bugs are avoided.
     701******************************* */
     702
     703SWFUpload.prototype.queueEvent = function (handlerName, argumentArray) {
     704    // Warning: Don't call this.debug inside here or you'll create an infinite loop
     705   
     706    if (argumentArray == undefined) {
     707        argumentArray = [];
     708    } else if (!(argumentArray instanceof Array)) {
     709        argumentArray = [argumentArray];
     710    }
     711   
     712    var self = this;
     713    if (typeof this.settings[handlerName] === "function") {
     714        // Queue the event
     715        this.eventQueue.push(function () {
     716            this.settings[handlerName].apply(this, argumentArray);
     717        });
     718       
     719        // Execute the next queued event
     720        setTimeout(function () {
     721            self.executeNextEvent();
     722        }, 0);
     723       
     724    } else if (this.settings[handlerName] !== null) {
     725        throw "Event handler " + handlerName + " is unknown or is not a function";
     726    }
     727};
     728
     729// Private: Causes the next event in the queue to be executed.  Since events are queued using a setTimeout
     730// we must queue them in order to garentee that they are executed in order.
     731SWFUpload.prototype.executeNextEvent = function () {
     732    // Warning: Don't call this.debug inside here or you'll create an infinite loop
     733
     734    var  f = this.eventQueue ? this.eventQueue.shift() : null;
     735    if (typeof(f) === "function") {
     736        f.apply(this);
     737    }
     738};
     739
     740// Private: unescapeFileParams is part of a workaround for a flash bug where objects passed through ExternalInterface cannot have
     741// properties that contain characters that are not valid for JavaScript identifiers. To work around this
     742// the Flash Component escapes the parameter names and we must unescape again before passing them along.
     743SWFUpload.prototype.unescapeFilePostParams = function (file) {
     744    var reg = /[$]([0-9a-f]{4})/i;
     745    var unescapedPost = {};
     746    var uk;
     747
     748    if (file != undefined) {
     749        for (var k in file.post) {
     750            if (file.post.hasOwnProperty(k)) {
     751                uk = k;
     752                var match;
     753                while ((match = reg.exec(uk)) !== null) {
     754                    uk = uk.replace(match[0], String.fromCharCode(parseInt("0x" + match[1], 16)));
     755                }
     756                unescapedPost[uk] = file.post[k];
     757            }
    441758        }
    442         catch (ex) {
    443             this.debug("Could not call GetStats");
    444         }
    445     } else {
    446         this.debug("Could not find Flash element");
    447     }
    448 };
    449 SWFUpload.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 
    463 SWFUpload.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 
    477 SWFUpload.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 
    504 SWFUpload.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 
    518 SWFUpload.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 
    533 SWFUpload.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 
    548 SWFUpload.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 
    563 SWFUpload.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 
    579 SWFUpload.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 
    594 SWFUpload.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 
    609 SWFUpload.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 
    624 SWFUpload.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 
    639 SWFUpload.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 */
     759
     760        file.post = unescapedPost;
     761    }
     762
     763    return file;
     764};
     765
    664766SWFUpload.prototype.flashReady = function () {
    665767    // 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 */
    687 SWFUpload.prototype.executeNextEvent = function () {
    688     var  f = this.eventQueue.shift();
    689     if (typeof(f) === "function") {
    690         f();
    691     }
    692 }
     768    var movieElement = this.getMovieElement();
     769    if (typeof movieElement.StartUpload !== "function") {
     770        throw "ExternalInterface methods failed to initialize.";
     771    }
     772
     773    // Fix IE Flash/Form bug
     774    if (window[this.movieName] == undefined) {
     775        window[this.movieName] = movieElement;
     776    }
     777   
     778    this.queueEvent("swfupload_loaded_handler");
     779};
     780
    693781
    694782/* This is a chance to do something before the browse window opens */
    695783SWFUpload.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     }
     784    this.queueEvent("file_dialog_start_handler");
    703785};
    704786
     
    706788/* Called when a file is successfully added to the queue. */
    707789SWFUpload.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     }
     790    file = this.unescapeFilePostParams(file);
     791    this.queueEvent("file_queued_handler", file);
    715792};
    716793
    717794
    718795/* Handle errors that occur when an attempt to queue a file fails. */
    719 SWFUpload.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     }
     796SWFUpload.prototype.fileQueueError = function (file, errorCode, message) {
     797    file = this.unescapeFilePostParams(file);
     798    this.queueEvent("file_queue_error_handler", [file, errorCode, message]);
    727799};
    728800
    729801/* Called after the file dialog has closed and the selected files have been queued.
    730802    You could call startUpload here if you want the queued files to begin uploading immediately. */
    731 SWFUpload.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     */
     803SWFUpload.prototype.fileDialogComplete = function (numFilesSelected, numFilesQueued) {
     804    this.queueEvent("file_dialog_complete_handler", [numFilesSelected, numFilesQueued]);
     805};
     806
    746807SWFUpload.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 */
    761 SWFUpload.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. */
    778 SWFUpload.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. */
    791 SWFUpload.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
    802 status 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
    804 upload will become 'stuck'. */
    805 SWFUpload.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. */
     808    file = this.unescapeFilePostParams(file);
     809    this.queueEvent("return_upload_start_handler", file);
     810};
     811
     812SWFUpload.prototype.returnUploadStart = function (file) {
     813    var returnValue;
     814    if (typeof this.settings.upload_start_handler === "function") {
     815        file = this.unescapeFilePostParams(file);
     816        returnValue = this.settings.upload_start_handler.call(this, file);
     817    } else if (this.settings.upload_start_handler != undefined) {
     818        throw "upload_start_handler must be a function";
     819    }
     820
     821    // Convert undefined to true so if nothing is returned from the upload_start_handler it is
     822    // interpretted as 'true'.
     823    if (returnValue === undefined) {
     824        returnValue = true;
     825    }
     826   
     827    returnValue = !!returnValue;
     828   
     829    this.callFlash("ReturnUploadStart", [returnValue]);
     830};
     831
     832
     833
     834SWFUpload.prototype.uploadProgress = function (file, bytesComplete, bytesTotal) {
     835    file = this.unescapeFilePostParams(file);
     836    this.queueEvent("upload_progress_handler", [file, bytesComplete, bytesTotal]);
     837};
     838
     839SWFUpload.prototype.uploadError = function (file, errorCode, message) {
     840    file = this.unescapeFilePostParams(file);
     841    this.queueEvent("upload_error_handler", [file, errorCode, message]);
     842};
     843
     844SWFUpload.prototype.uploadSuccess = function (file, serverData) {
     845    file = this.unescapeFilePostParams(file);
     846    this.queueEvent("upload_success_handler", [file, serverData]);
     847};
     848
    817849SWFUpload.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     }
     850    file = this.unescapeFilePostParams(file);
     851    this.queueEvent("upload_complete_handler", file);
    825852};
    826853
     
    828855   internal debug console.  You can override this event and have messages written where you want. */
    829856SWFUpload.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 */
    854 SWFUpload.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. */
    868 SWFUpload.swfUploadLoaded = function () {
    869 };
    870 
    871 /* This is a chance to do something before the browse window opens */
    872 SWFUpload.fileDialogStart = function () {
    873 };
    874 
    875 
    876 /* Called when a file is successfully added to the queue. */
    877 SWFUpload.fileQueued = function (file) {
    878 };
    879 
    880 
    881 /* Handle errors that occur when an attempt to queue a file fails. */
    882 SWFUpload.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. */
    907 SWFUpload.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 */
    919 SWFUpload.uploadStart = function (file) {
    920     return true;
    921 };
    922 
    923 // Called during upload as the file progresses
    924 SWFUpload.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
    929 server is available in server_data.  The upload script must return some text or uploadSuccess will not fire (neither will uploadComplete). */
    930 SWFUpload.uploadSuccess = function (file, server_data) {
    931     this.debug("Upload Success: " + file.id + ", Server: " + server_data);
    932 };
    933 
    934 /* This is called last.  The file is uploaded or an error occurred and SWFUpload is ready to make the next upload.
    935     If you want to automatically start the next file just call startUpload from here.
    936 */
    937 SWFUpload.uploadComplete = function (file) {
    938     this.debug("Upload Complete: " + file.id);
    939 };
    940 
    941 // Called by SWFUpload JavaScript and Flash functions when debug is enabled.
    942 // Override this method in your settings to call your own debug message handler
    943 SWFUpload.debug = function (message) {
    944     if (this.getSetting("debug_enabled")) {
    945         this.debugMessage(message);
    946     }
    947 };
    948 
    949 /* Called when an upload occurs during upload.  For HTTP errors 'message' will contain the HTTP STATUS CODE */
    950 SWFUpload.uploadError = function (file, errcode, msg) {
    951     try {
    952         switch (errcode) {
    953         case SWFUpload.UPLOAD_ERROR.SPECIFIED_FILE_ID_NOT_FOUND:
    954             this.debug("Error Code: File ID specified for upload was not found, Message: " + msg);
    955             break;
    956         case SWFUpload.UPLOAD_ERROR.HTTP_ERROR:
    957             this.debug("Error Code: HTTP Error, File name: " + file.name + ", Message: " + msg);
    958             break;
    959         case SWFUpload.UPLOAD_ERROR.MISSING_UPLOAD_URL:
    960             this.debug("Error Code: No backend file, File name: " + file.name + ", Message: " + msg);
    961             break;
    962         case SWFUpload.UPLOAD_ERROR.IO_ERROR:
    963             this.debug("Error Code: IO Error, File name: " + file.name + ", Message: " + msg);
    964             break;
    965         case SWFUpload.UPLOAD_ERROR.SECURITY_ERROR:
    966             this.debug("Error Code: Security Error, File name: " + file.name + ", Message: " + msg);
    967             break;
    968         case SWFUpload.UPLOAD_ERROR.UPLOAD_LIMIT_EXCEEDED:
    969             this.debug("Error Code: Upload limit reached, File name: " + file.name + ", File size: " + file.size + ", Message: " + msg);
    970             break;
    971         case SWFUpload.UPLOAD_ERROR.UPLOAD_FAILED:
    972             this.debug("Error Code: Upload Initialization exception, File name: " + file.name + ", File size: " + file.size + ", Message: " + msg);
    973             break;
    974         case SWFUpload.UPLOAD_ERROR.FILE_VALIDATION_FAILED:
    975             this.debug("Error Code: uploadStart callback returned false, File name: " + file.name + ", File size: " + file.size + ", Message: " + msg);
    976             break;
    977         case SWFUpload.UPLOAD_ERROR.FILE_CANCELLED:
    978             this.debug("Error Code: The file upload was cancelled, File name: " + file.name + ", File size: " + file.size + ", Message: " + msg);
    979             break;
    980         case SWFUpload.UPLOAD_ERROR.UPLOAD_STOPPED:
    981             this.debug("Error Code: The file upload was stopped, File name: " + file.name + ", File size: " + file.size + ", Message: " + msg);
    982             break;
    983         default:
    984             this.debug("Error Code: Unhandled error occured. Errorcode: " + errcode);
    985         }
    986     } catch (ex) {
    987         this.debug(ex);
    988     }
    989 };
    990 
     857    this.queueEvent("debug_handler", message);
     858};
    991859
    992860
     
    999867    The console is automatically scrolled as messages appear.
    1000868   
    1001     You can override this console (to use FireBug's console for instance) by setting the debug event method to your own function
    1002     that handles the debug message
    1003    ********************************** */
     869    If you are using your own debug handler or when you deploy to production and
     870    have debug disabled you can remove these functions to reduce the file size
     871    and complexity.
     872********************************** */
     873   
     874// Private: debugMessage is the default debug_handler.  If you want to print debug messages
     875// call the debug() function.  When overriding the function your own function should
     876// check to see if the debug setting is true before outputting debug information.
    1004877SWFUpload.prototype.debugMessage = function (message) {
    1005     var exception_message, exception_values;
    1006 
    1007     if (typeof(message) === "object" && typeof(message.name) === "string" && typeof(message.message) === "string") {
    1008         exception_message = "";
    1009         exception_values = [];
    1010         for (var key in message) {
    1011             exception_values.push(key + ": " + message[key]);
     878    if (this.settings.debug) {
     879        var exceptionMessage, exceptionValues = [];
     880
     881        // Check for an exception object and print it nicely
     882        if (typeof message === "object" && typeof message.name === "string" && typeof message.message === "string") {
     883            for (var key in message) {
     884                if (message.hasOwnProperty(key)) {
     885                    exceptionValues.push(key + ": " + message[key]);
     886                }
     887            }
     888            exceptionMessage = exceptionValues.join("\n") || "";
     889            exceptionValues = exceptionMessage.split("\n");
     890            exceptionMessage = "EXCEPTION: " + exceptionValues.join("\nEXCEPTION: ");
     891            SWFUpload.Console.writeLine(exceptionMessage);
     892        } else {
     893            SWFUpload.Console.writeLine(message);
    1012894        }
    1013         exception_message = exception_values.join("\n");
    1014         exception_values = exception_message.split("\n");
    1015         exception_message = "EXCEPTION: " + exception_values.join("\nEXCEPTION: ");
    1016         SWFUpload.Console.writeLine(exception_message);
    1017     } else {
    1018         SWFUpload.Console.writeLine(message);
    1019895    }
    1020896};
  • trunk/wp-includes/script-loader.php

    r9412 r9421  
    105105    $scripts->add( 'swfupload', '/wp-includes/js/swfupload/swfupload.js', false, '2.0.2-20080430');
    106106    $scripts->add( 'swfupload-degrade', '/wp-includes/js/swfupload/plugins/swfupload.graceful_degradation.js', array('swfupload'), '2.0.2');
     107    $scripts->add( 'swfupload-swfobject', '/wp-includes/js/swfupload/plugins/swfupload.swfobject.js', array('swfupload'), '2.0.2');
    107108    $scripts->localize( 'swfupload-degrade', 'uploadDegradeOptions', array(
    108109        'is_lighttpd_before_150' => is_lighttpd_before_150(),
Note: See TracChangeset for help on using the changeset viewer.