Changeset 8056

Show
Ignore:
Timestamp:
06/06/08 07:29:15 (6 months ago)
Author:
ryan
Message:

Update to swfupload 2.1.0

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/wp-includes/js/swfupload/plugins/swfupload.cookies.js

    r6659 r8056  
    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.graceful_degradation.js

    r7406 r8056  
    2020if (typeof(SWFUpload) === "function") { 
    2121    SWFUpload.gracefulDegradation = {}; 
    22     SWFUpload.prototype.initSettings = function (old_initSettings) { 
    23         return function (init_settings) { 
    24             if (typeof(old_initSettings) === "function") { 
    25                 old_initSettings.call(this, init_settings); 
     22    SWFUpload.prototype.initSettings = (function (oldInitSettings) { 
     23        return function () { 
     24            if (typeof(oldInitSettings) === "function") { 
     25                oldInitSettings.call(this); 
    2626            } 
    2727             
    28             this.addSetting("swfupload_element_id",             init_settings.swfupload_element_id,             "swfupload_container"); 
    29             this.addSetting("degraded_element_id",              init_settings.degraded_element_id,              "degraded_container"); 
    30             this.addSetting("user_swfUploadLoaded_handler",     init_settings.swfupload_loaded_handler,         SWFUpload.swfUploadLoaded); 
     28            this.ensureDefault = function (settingName, defaultValue) { 
     29                this.settings[settingName] = (this.settings[settingName] == undefined) ? defaultValue : this.settings[settingName]; 
     30            }; 
     31             
     32            this.ensureDefault("swfupload_element_id", "swfupload_container"); 
     33            this.ensureDefault("degraded_element_id", "degraded_container"); 
     34            this.settings.user_swfupload_loaded_handler = this.settings.swfupload_loaded_handler; 
    3135 
    32             this.swfUploadLoaded_handler = SWFUpload.gracefulDegradation.swfUploadLoaded; 
     36            this.settings.swfupload_loaded_handler = SWFUpload.gracefulDegradation.swfUploadLoadedHandler; 
     37             
     38            delete this.ensureDefault; 
    3339        }; 
    34     }(SWFUpload.prototype.initSettings); 
     40    })(SWFUpload.prototype.initSettings); 
    3541 
    36     SWFUpload.gracefulDegradation.swfUploadLoaded = function () { 
    37         var swfupload_container_id, swfupload_container, degraded_container_id, degraded_container, user_swfUploadLoaded_handler; 
    38         try { 
    39             if (uploadDegradeOptions.is_lighttpd_before_150) throw "Lighttpd versions earlier than 1.5.0 aren't supported!"; 
    40             swfupload_element_id = this.getSetting("swfupload_element_id"); 
    41             degraded_element_id = this.getSetting("degraded_element_id"); 
    42              
    43             // Show the UI container 
    44             swfupload_container = document.getElementById(swfupload_element_id); 
    45             if (swfupload_container !== null) { 
    46                 swfupload_container.style.display = "block"; 
     42    SWFUpload.gracefulDegradation.swfUploadLoadedHandler = function () { 
     43        var swfuploadContainerID, swfuploadContainer, degradedContainerID, degradedContainer; 
    4744 
    48                 // Now take care of hiding the degraded UI 
    49                 degraded_container = document.getElementById(degraded_element_id); 
    50                 if (degraded_container !== null) { 
    51                     degraded_container.style.display = "none"; 
    52                 } 
     45        swfuploadContainerID = this.settings.swfupload_element_id; 
     46        degradedContainerID = this.settings.degraded_element_id; 
     47         
     48        // Show the UI container 
     49        swfuploadContainer = document.getElementById(swfuploadContainerID); 
     50        if (swfuploadContainer != undefined) { 
     51            swfuploadContainer.style.display = "block"; 
     52 
     53            // Now take care of hiding the degraded UI 
     54            degradedContainer = document.getElementById(degradedContainerID); 
     55            if (degradedContainer != undefined) { 
     56                degradedContainer.style.display = "none"; 
    5357            } 
    54         } catch (ex) { 
    55             this.debug(ex); 
    5658        } 
    5759         
    58         user_swfUploadLoaded_handler = this.getSetting("user_swfUploadLoaded_handler"); 
    59         if (typeof(user_swfUploadLoaded_handler) === "function") { 
    60             user_swfUploadLoaded_handler.apply(this); 
     60        if (typeof(this.settings.user_swfupload_loaded_handler) === "function") { 
     61            this.settings.user_swfupload_loaded_handler.apply(this); 
    6162        } 
    6263    }; 
  • trunk/wp-includes/js/swfupload/plugins/swfupload.queue.js

    r6659 r8056  
    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

    r6659 r8056  
    11/** 
    2  * SWFUpload v2.0 by Jacob Roberts, Nov 2007, http://www.swfupload.org, http://linebyline.blogspot.com 
     2 * SWFUpload v2.1.0 by Jacob Roberts, Feb 2008, http://www.swfupload.org, http://swfupload.googlecode.com, http://www.swfupload.org 
    33 * -------- -------- -------- -------- -------- -------- -------- -------- 
    4  * SWFUpload is (c) 2006 Lars Huring and Mammon Media and is released under the MIT License: 
     4 * SWFUpload is (c) 2006 Lars Huring, Olov Nilz�and Mammon Media and is released under the MIT License: 
    55 * http://www.opensource.org/licenses/mit-license.php 
    66 * 
    77 * See Changelog.txt for version history 
    88 * 
    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. 
    169 */ 
    1710 
     
    2114/* *********** */ 
    2215 
    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  
     16var SWFUpload = function (settings) { 
     17    this.initSWFUpload(settings); 
     18}; 
     19 
     20SWFUpload.prototype.initSWFUpload = function (settings) { 
    3621    try { 
    3722        this.customSettings = {};   // A container where developers can place their own settings associated with this instance. 
    38         this.settings = {}
     23        this.settings = settings
    3924        this.eventQueue = []; 
    4025        this.movieName = "SWFUpload_" + SWFUpload.movieCount++; 
     
    4530 
    4631        // Load the settings.  Load the Flash movie. 
    47         this.initSettings(init_settings); 
     32        this.initSettings(); 
    4833        this.loadFlash(); 
    49  
    5034        this.displayDebugInfo(); 
    51  
    52     } catch (ex2) { 
    53         this.debug(ex2)
    54     } 
    55 } 
     35    } catch (ex) { 
     36       delete SWFUpload.instances[this.movieName]; 
     37        throw ex
     38    } 
     39}; 
    5640 
    5741/* *************** */ 
    58 /* Static thingies */ 
     42/* Static Members */ 
    5943/* *************** */ 
    6044SWFUpload.instances = {}; 
    6145SWFUpload.movieCount = 0; 
     46SWFUpload.version = "2.1.0"; 
    6247SWFUpload.QUEUE_ERROR = { 
    6348    QUEUE_LIMIT_EXCEEDED            : -100, 
     
    8772 
    8873 
    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) { 
     74/* ******************** */ 
     75/* Instance Members  */ 
     76/* ******************** */ 
     77 
     78// Private: initSettings ensures that all the 
     79// settings are set, getting a default value if one was not assigned. 
     80SWFUpload.prototype.initSettings = function () { 
     81    this.ensureDefault = function (settingName, defaultValue) { 
     82        this.settings[settingName] = (this.settings[settingName] == undefined) ? defaultValue : this.settings[settingName]; 
     83    }; 
     84     
    9585    // 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  
     86    this.ensureDefault("upload_url", ""); 
     87    this.ensureDefault("file_post_name", "Filedata"); 
     88    this.ensureDefault("post_params", {}); 
     89    this.ensureDefault("use_query_string", false); 
     90    this.ensureDefault("requeue_on_error", false); 
     91     
    10092    // 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"); 
     93    this.ensureDefault("file_types", "*.*"); 
     94    this.ensureDefault("file_types_description", "All Files"); 
     95    this.ensureDefault("file_size_limit", 0);  // Default zero means "unlimited" 
     96    this.ensureDefault("file_upload_limit", 0); 
     97    this.ensureDefault("file_queue_limit", 0); 
    10698 
    10799    // 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"); 
     100    this.ensureDefault("flash_url", "swfupload_f9.swf"); 
     101    this.ensureDefault("flash_color", "#FFFFFF"); 
    112102 
    113103    // Debug Settings 
    114     this.addSetting("debug_enabled", init_settings.debug,  false); 
    115  
     104    this.ensureDefault("debug", false); 
     105    this.settings.debug_enabled = this.settings.debug;  // Here to maintain v2 API 
     106     
    116107    // 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); 
     108    this.settings.return_upload_start_handler = this.returnUploadStart; 
     109    this.ensureDefault("swfupload_loaded_handler", null); 
     110    this.ensureDefault("file_dialog_start_handler", null); 
     111    this.ensureDefault("file_queued_handler", null); 
     112    this.ensureDefault("file_queue_error_handler", null); 
     113    this.ensureDefault("file_dialog_complete_handler", null); 
     114     
     115    this.ensureDefault("upload_start_handler", null); 
     116    this.ensureDefault("upload_progress_handler", null); 
     117    this.ensureDefault("upload_error_handler", null); 
     118    this.ensureDefault("upload_success_handler", null); 
     119    this.ensureDefault("upload_complete_handler", null); 
     120     
     121    this.ensureDefault("debug_handler", this.debugMessage); 
     122 
     123    this.ensureDefault("custom_settings", {}); 
    132124 
    133125    // 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". 
     126    this.customSettings = this.settings.custom_settings; 
     127     
     128    delete this.ensureDefault; 
     129}; 
     130 
     131// Private: loadFlash generates the HTML tag for the Flash 
     132// It then adds the flash to the body 
    140133SWFUpload.prototype.loadFlash = function () { 
    141     var html, target_element, container; 
     134    var targetElement, container; 
    142135 
    143136    // Make sure an element with the ID we are going to use doesn't already exist 
    144137    if (document.getElementById(this.movieName) !== null) { 
    145         return false
     138        throw "ID " + this.movieName + " is already in use. The Flash Object could not be added"
    146139    } 
    147140 
    148141    // 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; 
     142    targetElement = document.getElementsByTagName("body")[0]; 
     143 
     144    if (targetElement == undefined) { 
     145        throw "Could not find the 'body' element."; 
    157146    } 
    158147 
    159148    // Append the container and load the flash 
    160149    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); 
     150    container.style.width = "1px"
     151    container.style.height = "1px"
     152 
     153    targetElement.appendChild(container); 
    165154    container.innerHTML = this.getFlashHTML();  // Using innerHTML is non-standard but the only sensible way to dynamically add Flash in IE (and maybe other browsers) 
    166155}; 
    167156 
    168 // Generates the embed/object tags needed to embed the flash in to the document 
     157// Private: getFlashHTML generates the object tag needed to embed the flash in to the document 
    169158SWFUpload.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. 
     159    // Flash Satay object syntax: http://www.alistapart.com/articles/flashsatay 
     160    return ['<object id="', this.movieName, '" type="application/x-shockwave-flash" data="', this.settings.flash_url, '" width="1" height="1" style="-moz-user-focus: ignore;">', 
     161                '<param name="movie" value="', this.settings.flash_url, '" />', 
     162                '<param name="bgcolor" value="', this.settings.flash_color, '" />', 
     163                '<param name="quality" value="high" />', 
     164                '<param name="menu" value="false" />', 
     165                '<param name="allowScriptAccess" value="always" />', 
     166                '<param name="flashvars" value="' + this.getFlashVars() + '" />', 
     167                '</object>'].join(""); 
     168}; 
     169 
     170// Private: getFlashVars builds the parameter string that will be passed 
     171// to flash in the flashvars param. 
    203172SWFUpload.prototype.getFlashVars = function () { 
    204173    // Build a string from the post param object 
    205     var param_string = this.buildParamString(); 
     174    var paramString = this.buildParamString(); 
    206175 
    207176    // 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  
     177    return ["movieName=", encodeURIComponent(this.movieName), 
     178            "&amp;uploadURL=", encodeURIComponent(this.settings.upload_url), 
     179            "&amp;useQueryString=", encodeURIComponent(this.settings.use_query_string), 
     180            "&amp;requeueOnError=", encodeURIComponent(this.settings.requeue_on_error), 
     181            "&amp;params=", encodeURIComponent(paramString), 
     182            "&amp;filePostName=", encodeURIComponent(this.settings.file_post_name), 
     183            "&amp;fileTypes=", encodeURIComponent(this.settings.file_types), 
     184            "&amp;fileTypesDescription=", encodeURIComponent(this.settings.file_types_description), 
     185            "&amp;fileSizeLimit=", encodeURIComponent(this.settings.file_size_limit), 
     186            "&amp;fileUploadLimit=", encodeURIComponent(this.settings.file_upload_limit), 
     187            "&amp;fileQueueLimit=", encodeURIComponent(this.settings.file_queue_limit), 
     188            "&amp;debugEnabled=", encodeURIComponent(this.settings.debug_enabled)].join(""); 
     189}; 
     190 
     191// Public: getMovieElement retrieves the DOM reference to the Flash element added by SWFUpload 
     192// The element is cached after the first lookup 
    223193SWFUpload.prototype.getMovieElement = function () { 
    224     if (typeof(this.movieElement) === "undefined" || this.movieElement === null) { 
     194    if (this.movieElement == undefined) { 
    225195        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  
     196    } 
     197 
     198    if (this.movieElement === null) { 
     199        throw "Could not find Flash element"; 
     200    } 
     201     
    236202    return this.movieElement; 
    237203}; 
    238204 
     205// Private: buildParamString takes the name/value pairs in the post_params setting object 
     206// and joins them up in to a string formatted "name=value&amp;name=value" 
    239207SWFUpload.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])); 
     208    var postParams = this.settings.post_params; 
     209    var paramStringPairs = []; 
     210 
     211    if (typeof(postParams) === "object") { 
     212        for (var name in postParams) { 
     213            if (postParams.hasOwnProperty(name)) { 
     214                paramStringPairs.push(encodeURIComponent(name.toString()) + "=" + encodeURIComponent(postParams[name].toString())); 
     215            } 
     216        } 
     217    } 
     218 
     219    return paramStringPairs.join("&amp;"); 
     220}; 
     221 
     222// Public: Used to remove a SWFUpload instance from the page. This method strives to remove 
     223// all references to the SWF, and other objects so memory is properly freed. 
     224// Returns true if everything was destroyed. Returns a false if a failure occurs leaving SWFUpload in an inconsistant state. 
     225SWFUpload.prototype.destroy = function () { 
     226    try { 
     227        // Make sure Flash is done before we try to remove it 
     228        this.stopUpload(); 
     229         
     230        // Remove the SWFUpload DOM nodes 
     231        var movieElement = null; 
     232        try { 
     233            movieElement = this.getMovieElement(); 
     234        } catch (ex) { 
     235        } 
     236         
     237        if (movieElement != undefined && movieElement.parentNode != undefined && typeof(movieElement.parentNode.removeChild) === "function") { 
     238            var container = movieElement.parentNode; 
     239            if (container != undefined) { 
     240                container.removeChild(movieElement); 
     241                if (container.parentNode != undefined && typeof(container.parentNode.removeChild) === "function") { 
     242                    container.parentNode.removeChild(container); 
    250243                } 
    251244            } 
    252245        } 
    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. 
     246         
     247        // Destroy references 
     248        SWFUpload.instances[this.movieName] = null; 
     249        delete SWFUpload.instances[this.movieName]; 
     250 
     251        delete this.movieElement; 
     252        delete this.settings; 
     253        delete this.customSettings; 
     254        delete this.eventQueue; 
     255        delete this.movieName; 
     256         
     257        return true; 
     258    } catch (ex1) { 
     259        return false; 
     260    } 
     261}; 
     262 
     263// Public: displayDebugInfo prints out settings and configuration 
     264// information about this SWFUpload instance. 
     265// This function (and any references to it) can be deleted when placing 
     266// SWFUpload in production. 
     267SWFUpload.prototype.displayDebugInfo = function () { 
     268    this.debug( 
     269        [ 
     270            "---SWFUpload Instance Info---\n", 
     271            "Version: ", SWFUpload.version, "\n", 
     272            "Movie Name: ", this.movieName, "\n", 
     273            "Settings:\n", 
     274            "\t", "upload_url:             ", this.settings.upload_url, "\n", 
     275            "\t", "use_query_string:       ", this.settings.use_query_string.toString(), "\n", 
     276            "\t", "file_post_name:         ", this.settings.file_post_name, "\n", 
     277            "\t", "post_params:            ", this.settings.post_params.toString(), "\n", 
     278            "\t", "file_types:             ", this.settings.file_types, "\n", 
     279            "\t", "file_types_description: ", this.settings.file_types_description, "\n", 
     280            "\t", "file_size_limit:        ", this.settings.file_size_limit, "\n", 
     281            "\t", "file_upload_limit:      ", this.settings.file_upload_limit, "\n", 
     282            "\t", "file_queue_limit:       ", this.settings.file_queue_limit, "\n", 
     283            "\t", "flash_url:              ", this.settings.flash_url, "\n", 
     284            "\t", "flash_color:            ", this.settings.flash_color, "\n", 
     285            "\t", "debug:                  ", this.settings.debug.toString(), "\n", 
     286            "\t", "custom_settings:        ", this.settings.custom_settings.toString(), "\n", 
     287            "Event Handlers:\n", 
     288            "\t", "swfupload_loaded_handler assigned:  ", (typeof(this.settings.swfupload_loaded_handler) === "function").toString(), "\n", 
     289            "\t", "file_dialog_start_handler assigned: ", (typeof(this.settings.file_dialog_start_handler) === "function").toString(), "\n", 
     290            "\t", "file_queued_handler assigned:       ", (typeof(this.settings.file_queued_handler) === "function").toString(), "\n", 
     291            "\t", "file_queue_error_handler assigned:  ", (typeof(this.settings.file_queue_error_handler) === "function").toString(), "\n", 
     292            "\t", "upload_start_handler assigned:      ", (typeof(this.settings.upload_start_handler) === "function").toString(), "\n", 
     293            "\t", "upload_progress_handler assigned:   ", (typeof(this.settings.upload_progress_handler) === "function").toString(), "\n", 
     294            "\t", "upload_error_handler assigned:      ", (typeof(this.settings.upload_error_handler) === "function").toString(), "\n", 
     295            "\t", "upload_success_handler assigned:    ", (typeof(this.settings.upload_success_handler) === "function").toString(), "\n", 
     296            "\t", "upload_complete_handler assigned:   ", (typeof(this.settings.upload_complete_handler) === "function").toString(), "\n", 
     297            "\t", "debug_handler assigned:             ", (typeof(this.settings.debug_handler) === "function").toString(), "\n" 
     298        ].join("") 
     299    ); 
     300}; 
     301 
     302/* Note: addSetting and getSetting are no longer used by SWFUpload but are included 
     303    the maintain v2 API compatibility 
     304*/ 
     305// Public: (Deprecated) addSetting adds a setting value. If the value given is undefined or null then the default_value is used. 
    259306SWFUpload.prototype.addSetting = function (name, value, default_value) { 
    260     if (typeof(value) === "undefined" || value === null) { 
    261         this.settings[name] = default_value; 
    262     } else { 
    263         this.settings[name] = value; 
    264     } 
    265  
    266     return this.settings[name]; 
    267 }; 
    268  
    269 // Gets a setting.  Returns empty string if not found. 
     307    if (value == undefined) { 
     308        return (this.settings[name] = default_value); 
     309    } else { 
     310        return (this.settings[name] = value); 
     311    } 
     312}; 
     313 
     314// Public: (Deprecated) getSetting gets a setting. Returns an empty string if the setting was not found. 
    270315SWFUpload.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"); 
     316    if (this.settings[name] != undefined) { 
     317        return this.settings[name]; 
     318    } 
     319 
     320    return ""; 
     321}; 
     322 
     323 
     324 
     325// Private: callFlash handles function calls made to the Flash element. 
     326// Calls are made with a setTimeout for some functions to work around 
     327// bugs in the ExternalInterface library. 
     328SWFUpload.prototype.callFlash = function (functionName, argumentArray) { 
     329    argumentArray = argumentArray || []; 
     330     
     331    var self = this; 
     332    var callFunction = function () { 
     333        var movieElement = self.getMovieElement(); 
     334        var returnValue; 
     335        if (typeof(movieElement[functionName]) === "function") { 
     336            // 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. 
     337            if (argumentArray.length === 0) { 
     338                returnValue = movieElement[functionName](); 
     339            } else if (argumentArray.length === 1) { 
     340                returnValue = movieElement[functionName](argumentArray[0]); 
     341            } else if (argumentArray.length === 2) { 
     342                returnValue = movieElement[functionName](argumentArray[0], argumentArray[1]); 
     343            } else if (argumentArray.length === 3) { 
     344                returnValue = movieElement[functionName](argumentArray[0], argumentArray[1], argumentArray[2]); 
    317345            } else { 
    318                 output += (prefix + key + ": " + object[key] + "\n")
     346                throw "Too many arguments"
    319347            } 
     348             
     349            // Unescape file post param values 
     350            if (returnValue != undefined && typeof(returnValue.post) === "object") { 
     351                returnValue = self.unescapeFilePostParams(returnValue); 
     352            } 
     353             
     354            return returnValue; 
     355        } else { 
     356            throw "Invalid function name"; 
    320357        } 
    321     } 
    322  
    323     return output; 
    324 }; 
     358    }; 
     359     
     360    return callFunction(); 
     361}; 
     362 
    325363 
    326364/* ***************************** 
     
    330368   ***************************** */ 
    331369 
     370// Public: selectFile causes a File Selection Dialog window to appear.  This 
     371// dialog only allows 1 file to be selected. 
    332372SWFUpload.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  
     373    this.callFlash("SelectFile"); 
     374}; 
     375 
     376// Public: selectFiles causes a File Selection Dialog window to appear/ This 
     377// dialog allows the user to select any number of files 
     378// Flash Bug Warning: Flash limits the number of selectable files based on the combined length of the file names. 
     379// If the selection name length is too long the dialog will fail in an unpredictable manner.  There is no work-around 
     380// for this bug. 
    347381SWFUpload.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  
     382    this.callFlash("SelectFiles"); 
     383}; 
     384 
     385 
     386// Public: startUpload starts uploading the first file in the queue unless 
     387// the optional parameter 'fileID' specifies the ID  
     388SWFUpload.prototype.startUpload = function (fileID) { 
     389    this.callFlash("StartUpload", [fileID]); 
    385390}; 
    386391 
    387392/* 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. 
     393// Public: cancelUpload cancels any queued file.  The fileID parameter 
     394// must be specified. 
     395SWFUpload.prototype.cancelUpload = function (fileID) { 
     396    this.callFlash("CancelUpload", [fileID]); 
     397}; 
     398 
     399// Public: stopUpload stops the current upload and requeues the file at the beginning of the queue. 
     400// If nothing is currently uploading then nothing happens. 
    404401SWFUpload.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  
     402    this.callFlash("StopUpload"); 
    417403}; 
    418404 
    419405/* ************************ 
    420406 * 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 */ 
     407 *   These methods change the SWFUpl