--- /dev/null
+/**\r
+ * SWFUpload v2.0 by Jacob Roberts, Nov 2007, http://www.swfupload.org, http://linebyline.blogspot.com\r
+ * -------- -------- -------- -------- -------- -------- -------- --------\r
+ * SWFUpload is (c) 2006 Lars Huring and Mammon Media and is released under the MIT License:\r
+ * http://www.opensource.org/licenses/mit-license.php\r
+ *\r
+ * See Changelog.txt for version history\r
+ *\r
+ * Development Notes:\r
+ * * This version of SWFUpload requires Flash Player 9.0.28 and should autodetect the correct flash version.\r
+ * * In Linux Flash Player 9 setting the post file variable name does not work. It is always set to "Filedata".\r
+ * * There is a lot of repeated code that could be refactored to single functions. Feel free.\r
+ * * It's dangerous to do "circular calls" between Flash and JavaScript. I've taken steps to try to work around issues\r
+ * by having the event calls pipe through setTimeout. However you should still avoid calling in to Flash from\r
+ * within the event handler methods. Especially the "startUpload" event since it cannot use the setTimeout hack.\r
+ */\r
+\r
+\r
+/* *********** */\r
+/* Constructor */\r
+/* *********** */\r
+\r
+var SWFUpload = function (init_settings) {\r
+ this.initSWFUpload(init_settings);\r
+};\r
+\r
+SWFUpload.prototype.initSWFUpload = function (init_settings) {\r
+ // Remove background flicker in IE (read this: http://misterpixel.blogspot.com/2006/09/forensic-analysis-of-ie6.html)\r
+ // This doesn't have anything to do with SWFUpload but can help your UI behave better in IE.\r
+ try {\r
+ document.execCommand('BackgroundImageCache', false, true);\r
+ } catch (ex1) {\r
+ }\r
+\r
+\r
+ try {\r
+ this.customSettings = {}; // A container where developers can place their own settings associated with this instance.\r
+ this.settings = {};\r
+ this.eventQueue = [];\r
+ this.movieName = "SWFUpload_" + SWFUpload.movieCount++;\r
+ this.movieElement = null;\r
+\r
+ // Setup global control tracking\r
+ SWFUpload.instances[this.movieName] = this;\r
+\r
+ // Load the settings. Load the Flash movie.\r
+ this.initSettings(init_settings);\r
+ this.loadFlash();\r
+\r
+ this.displayDebugInfo();\r
+\r
+ } catch (ex2) {\r
+ this.debug(ex2);\r
+ }\r
+}\r
+\r
+/* *************** */\r
+/* Static thingies */\r
+/* *************** */\r
+SWFUpload.instances = {};\r
+SWFUpload.movieCount = 0;\r
+SWFUpload.QUEUE_ERROR = {\r
+ QUEUE_LIMIT_EXCEEDED : -100,\r
+ FILE_EXCEEDS_SIZE_LIMIT : -110,\r
+ ZERO_BYTE_FILE : -120,\r
+ INVALID_FILETYPE : -130\r
+};\r
+SWFUpload.UPLOAD_ERROR = {\r
+ HTTP_ERROR : -200,\r
+ MISSING_UPLOAD_URL : -210,\r
+ IO_ERROR : -220,\r
+ SECURITY_ERROR : -230,\r
+ UPLOAD_LIMIT_EXCEEDED : -240,\r
+ UPLOAD_FAILED : -250,\r
+ SPECIFIED_FILE_ID_NOT_FOUND : -260,\r
+ FILE_VALIDATION_FAILED : -270,\r
+ FILE_CANCELLED : -280,\r
+ UPLOAD_STOPPED : -290\r
+};\r
+SWFUpload.FILE_STATUS = {\r
+ QUEUED : -1,\r
+ IN_PROGRESS : -2,\r
+ ERROR : -3,\r
+ COMPLETE : -4,\r
+ CANCELLED : -5\r
+};\r
+\r
+\r
+/* ***************** */\r
+/* Instance Thingies */\r
+/* ***************** */\r
+// init is a private method that ensures that all the object settings are set, getting a default value if one was not assigned.\r
+\r
+SWFUpload.prototype.initSettings = function (init_settings) {\r
+ // Upload backend settings\r
+ this.addSetting("upload_url", init_settings.upload_url, "");\r
+ this.addSetting("file_post_name", init_settings.file_post_name, "Filedata");\r
+ this.addSetting("post_params", init_settings.post_params, {});\r
+\r
+ // File Settings\r
+ this.addSetting("file_types", init_settings.file_types, "*.*");\r
+ this.addSetting("file_types_description", init_settings.file_types_description, "All Files");\r
+ this.addSetting("file_size_limit", init_settings.file_size_limit, "1024");\r
+ this.addSetting("file_upload_limit", init_settings.file_upload_limit, "0");\r
+ this.addSetting("file_queue_limit", init_settings.file_queue_limit, "0");\r
+\r
+ // Flash Settings\r
+ this.addSetting("flash_url", init_settings.flash_url, "swfupload.swf");\r
+ this.addSetting("flash_width", init_settings.flash_width, "1px");\r
+ this.addSetting("flash_height", init_settings.flash_height, "1px");\r
+ this.addSetting("flash_color", init_settings.flash_color, "#FFFFFF");\r
+\r
+ // Debug Settings\r
+ this.addSetting("debug_enabled", init_settings.debug, false);\r
+\r
+ // Event Handlers\r
+ this.flashReady_handler = SWFUpload.flashReady; // This is a non-overrideable event handler\r
+ this.swfUploadLoaded_handler = this.retrieveSetting(init_settings.swfupload_loaded_handler, SWFUpload.swfUploadLoaded);\r
+ \r
+ this.fileDialogStart_handler = this.retrieveSetting(init_settings.file_dialog_start_handler, SWFUpload.fileDialogStart);\r
+ this.fileQueued_handler = this.retrieveSetting(init_settings.file_queued_handler, SWFUpload.fileQueued);\r
+ this.fileQueueError_handler = this.retrieveSetting(init_settings.file_queue_error_handler, SWFUpload.fileQueueError);\r
+ this.fileDialogComplete_handler = this.retrieveSetting(init_settings.file_dialog_complete_handler, SWFUpload.fileDialogComplete);\r
+ \r
+ this.uploadStart_handler = this.retrieveSetting(init_settings.upload_start_handler, SWFUpload.uploadStart);\r
+ this.uploadProgress_handler = this.retrieveSetting(init_settings.upload_progress_handler, SWFUpload.uploadProgress);\r
+ this.uploadError_handler = this.retrieveSetting(init_settings.upload_error_handler, SWFUpload.uploadError);\r
+ this.uploadSuccess_handler = this.retrieveSetting(init_settings.upload_success_handler, SWFUpload.uploadSuccess);\r
+ this.uploadComplete_handler = this.retrieveSetting(init_settings.upload_complete_handler, SWFUpload.uploadComplete);\r
+\r
+ this.debug_handler = this.retrieveSetting(init_settings.debug_handler, SWFUpload.debug);\r
+\r
+ // Other settings\r
+ this.customSettings = this.retrieveSetting(init_settings.custom_settings, {});\r
+};\r
+\r
+// loadFlash is a private method that generates the HTML tag for the Flash\r
+// It then adds the flash to the "target" or to the body and stores a\r
+// reference to the flash element in "movieElement".\r
+SWFUpload.prototype.loadFlash = function () {\r
+ var html, target_element, container;\r
+\r
+ // Make sure an element with the ID we are going to use doesn't already exist\r
+ if (document.getElementById(this.movieName) !== null) {\r
+ return false;\r
+ }\r
+\r
+ // Get the body tag where we will be adding the flash movie\r
+ try {\r
+ target_element = document.getElementsByTagName("body")[0];\r
+ if (typeof(target_element) === "undefined" || target_element === null) {\r
+ this.debug('Could not find the BODY element. SWFUpload failed to load.');\r
+ return false;\r
+ }\r
+ } catch (ex) {\r
+ return false;\r
+ }\r
+\r
+ // Append the container and load the flash\r
+ container = document.createElement("div");\r
+ container.style.width = this.getSetting("flash_width");\r
+ container.style.height = this.getSetting("flash_height");\r
+\r
+ target_element.appendChild(container);\r
+ container.innerHTML = this.getFlashHTML(); // Using innerHTML is non-standard but the only sensible way to dynamically add Flash in IE (and maybe other browsers)\r
+};\r
+\r
+// Generates the embed/object tags needed to embed the flash in to the document\r
+SWFUpload.prototype.getFlashHTML = function () {\r
+ var html = "";\r
+\r
+ // Create Mozilla Embed HTML\r
+ if (navigator.plugins && navigator.mimeTypes && navigator.mimeTypes.length) {\r
+ // Build the basic embed html\r
+ html = '<embed type="application/x-shockwave-flash" src="' + this.getSetting("flash_url") + '" width="' + this.getSetting("flash_width") + '" height="' + this.getSetting("flash_height") + '"';\r
+ html += ' id="' + this.movieName + '" name="' + this.movieName + '" ';\r
+ html += 'bgcolor="' + this.getSetting("flash_color") + '" quality="high" menu="false" flashvars="';\r
+\r
+ html += this.getFlashVars();\r
+\r
+ html += '" />';\r
+\r
+ // Create IE Object HTML\r
+ } else {\r
+\r
+ // Build the basic Object tag\r
+ html = '<object id="' + this.movieName + '" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" width="' + this.getSetting("flash_width") + '" height="' + this.getSetting("flash_height") + '">';\r
+ html += '<param name="movie" value="' + this.getSetting("flash_url") + '">';\r
+\r
+ html += '<param name="bgcolor" value="' + this.getSetting("flash_color") + '" />';\r
+ html += '<param name="quality" value="high" />';\r
+ html += '<param name="menu" value="false" />';\r
+\r
+ html += '<param name="flashvars" value="' + this.getFlashVars() + '" />';\r
+ html += '</object>';\r
+ }\r
+\r
+ return html;\r
+};\r
+\r
+// This private method builds the parameter string that will be passed\r
+// to flash.\r
+SWFUpload.prototype.getFlashVars = function () {\r
+ // Build a string from the post param object\r
+ var param_string = this.buildParamString();\r
+\r
+ // Build the parameter string\r
+ var html = "";\r
+ html += "movieName=" + encodeURIComponent(this.movieName);\r
+ html += "&uploadURL=" + encodeURIComponent(this.getSetting("upload_url"));\r
+ html += "¶ms=" + encodeURIComponent(param_string);\r
+ html += "&filePostName=" + encodeURIComponent(this.getSetting("file_post_name"));\r
+ html += "&fileTypes=" + encodeURIComponent(this.getSetting("file_types"));\r
+ html += "&fileTypesDescription=" + encodeURIComponent(this.getSetting("file_types_description"));\r
+ html += "&fileSizeLimit=" + encodeURIComponent(this.getSetting("file_size_limit"));\r
+ html += "&fileUploadLimit=" + encodeURIComponent(this.getSetting("file_upload_limit"));\r
+ html += "&fileQueueLimit=" + encodeURIComponent(this.getSetting("file_queue_limit"));\r
+ html += "&debugEnabled=" + encodeURIComponent(this.getSetting("debug_enabled"));\r
+\r
+ return html;\r
+};\r
+\r
+SWFUpload.prototype.getMovieElement = function () {\r
+ if (typeof(this.movieElement) === "undefined" || this.movieElement === null) {\r
+ this.movieElement = document.getElementById(this.movieName);\r
+\r
+ // 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)\r
+ // Removed because Revision 6 always adds the flash to the body (inside a containing div)\r
+ // 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\r
+ // and run this code to make the form's ID available from the window object so Flash and JavaScript can communicate.\r
+ //if (typeof(window[this.movieName]) === "undefined" || window[this.moveName] !== this.movieElement) {\r
+ // window[this.movieName] = this.movieElement;\r
+ //}\r
+ }\r
+\r
+ return this.movieElement;\r
+};\r
+\r
+SWFUpload.prototype.buildParamString = function () {\r
+ var post_params = this.getSetting("post_params");\r
+ var param_string_pairs = [];\r
+ var i, value, name;\r
+\r
+ // Retrieve the user defined parameters\r
+ if (typeof(post_params) === "object") {\r
+ for (name in post_params) {\r
+ if (post_params.hasOwnProperty(name)) {\r
+ if (typeof(post_params[name]) === "string") {\r
+ param_string_pairs.push(encodeURIComponent(name) + "=" + encodeURIComponent(post_params[name]));\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+ return param_string_pairs.join("&");\r
+};\r
+\r
+// Saves a setting. If the value given is undefined or null then the default_value is used.\r
+SWFUpload.prototype.addSetting = function (name, value, default_value) {\r
+ if (typeof(value) === "undefined" || value === null) {\r
+ this.settings[name] = default_value;\r
+ } else {\r
+ this.settings[name] = value;\r
+ }\r
+\r
+ return this.settings[name];\r
+};\r
+\r
+// Gets a setting. Returns empty string if not found.\r
+SWFUpload.prototype.getSetting = function (name) {\r
+ if (typeof(this.settings[name]) === "undefined") {\r
+ return "";\r
+ } else {\r
+ return this.settings[name];\r
+ }\r
+};\r
+\r
+// Gets a setting, if the setting is undefined then return the default value\r
+// This does not affect or use the interal setting object.\r
+SWFUpload.prototype.retrieveSetting = function (value, default_value) {\r
+ if (typeof(value) === "undefined" || value === null) {\r
+ return default_value;\r
+ } else {\r
+ return value;\r
+ }\r
+};\r
+\r
+\r
+// It loops through all the settings and displays\r
+// them in the debug Console.\r
+SWFUpload.prototype.displayDebugInfo = function () {\r
+ var key, debug_message = "";\r
+\r
+ debug_message += "----- SWFUPLOAD SETTINGS ----\nID: " + this.moveName + "\n";\r
+\r
+ debug_message += this.outputObject(this.settings);\r
+\r
+ debug_message += "----- SWFUPLOAD SETTINGS END ----\n";\r
+ debug_message += "\n";\r
+\r
+ this.debug(debug_message);\r
+};\r
+SWFUpload.prototype.outputObject = function (object, prefix) {\r
+ var output = "", key;\r
+\r
+ if (typeof(prefix) !== "string") {\r
+ prefix = "";\r
+ }\r
+ if (typeof(object) !== "object") {\r
+ return "";\r
+ }\r
+\r
+ for (key in object) {\r
+ if (object.hasOwnProperty(key)) {\r
+ if (typeof(object[key]) === "object") {\r
+ output += (prefix + key + ": { \n" + this.outputObject(object[key], "\t" + prefix) + prefix + "}" + "\n");\r
+ } else {\r
+ output += (prefix + key + ": " + object[key] + "\n");\r
+ }\r
+ }\r
+ }\r
+\r
+ return output;\r
+};\r
+\r
+/* *****************************\r
+ -- Flash control methods --\r
+ Your UI should use these\r
+ to operate SWFUpload\r
+ ***************************** */\r
+\r
+SWFUpload.prototype.selectFile = function () {\r
+ var movie_element = this.getMovieElement();\r
+ if (movie_element !== null && typeof(movie_element.SelectFile) === "function") {\r
+ try {\r
+ movie_element.SelectFile();\r
+ }\r
+ catch (ex) {\r
+ this.debug("Could not call SelectFile: " + ex);\r
+ }\r
+ } else {\r
+ this.debug("Could not find Flash element");\r
+ }\r
+\r
+};\r
+\r
+SWFUpload.prototype.selectFiles = function () {\r
+ var movie_element = this.getMovieElement();\r
+ if (movie_element !== null && typeof(movie_element.SelectFiles) === "function") {\r
+ try {\r
+ movie_element.SelectFiles();\r
+ }\r
+ catch (ex) {\r
+ this.debug("Could not call SelectFiles: " + ex);\r
+ }\r
+ } else {\r
+ this.debug("Could not find Flash element");\r
+ }\r
+\r
+};\r
+\r
+\r
+/* Start the upload. If a file_id is specified that file is uploaded. Otherwise the first\r
+ * file in the queue is uploaded. If no files are in the queue then nothing happens.\r
+ * This call uses setTimeout since Flash will be calling back in to JavaScript\r
+ */\r
+SWFUpload.prototype.startUpload = function (file_id) {\r
+ var self = this;\r
+ var movie_element = this.getMovieElement();\r
+ if (movie_element !== null && typeof(movie_element.StartUpload) === "function") {\r
+ setTimeout(\r
+ function () {\r
+ try {\r
+ movie_element.StartUpload(file_id);\r
+ }\r
+ catch (ex) {\r
+ self.debug("Could not call StartUpload: " + ex);\r
+ }\r
+ }, 0\r
+ );\r
+ } else {\r
+ this.debug("Could not find Flash element");\r
+ }\r
+\r
+};\r
+\r
+/* Cancels a the file upload. You must specify a file_id */\r
+SWFUpload.prototype.cancelUpload = function (file_id) {\r
+ var movie_element = this.getMovieElement();\r
+ if (movie_element !== null && typeof(movie_element.CancelUpload) === "function") {\r
+ try {\r
+ movie_element.CancelUpload(file_id);\r
+ }\r
+ catch (ex) {\r
+ this.debug("Could not call CancelUpload: " + ex);\r
+ }\r
+ } else {\r
+ this.debug("Could not find Flash element");\r
+ }\r
+\r
+};\r
+\r
+// Stops the current upload. The file is re-queued. If nothing is currently uploading then nothing happens.\r
+SWFUpload.prototype.stopUpload = function () {\r
+ var movie_element = this.getMovieElement();\r
+ if (movie_element !== null && typeof(movie_element.StopUpload) === "function") {\r
+ try {\r
+ movie_element.StopUpload();\r
+ }\r
+ catch (ex) {\r
+ this.debug("Could not call StopUpload: " + ex);\r
+ }\r
+ } else {\r
+ this.debug("Could not find Flash element");\r
+ }\r
+\r
+};\r
+\r
+/* ************************\r
+ * Settings methods\r
+ * These methods change the settings inside SWFUpload\r
+ * They shouldn't need to be called in a setTimeout since they\r
+ * should not call back from Flash to JavaScript (except perhaps in a Debug call)\r
+ * and some need to return data so setTimeout won't work.\r
+ */\r
+\r
+/* Gets the file statistics object. It looks like this (where n = number):\r
+ {\r
+ files_queued: n,\r
+ complete_uploads: n,\r
+ upload_errors: n,\r
+ uploads_cancelled: n,\r
+ queue_errors: n\r
+ }\r
+*/\r
+SWFUpload.prototype.getStats = function () {\r
+ var movie_element = this.getMovieElement();\r
+ if (movie_element !== null && typeof(movie_element.GetStats) === "function") {\r
+ try {\r
+ return movie_element.GetStats();\r
+ }\r
+ catch (ex) {\r
+ this.debug("Could not call GetStats");\r
+ }\r
+ } else {\r
+ this.debug("Could not find Flash element");\r
+ }\r
+};\r
+SWFUpload.prototype.setStats = function (stats_object) {\r
+ var movie_element = this.getMovieElement();\r
+ if (movie_element !== null && typeof(movie_element.SetStats) === "function") {\r
+ try {\r
+ movie_element.SetStats(stats_object);\r
+ }\r
+ catch (ex) {\r
+ this.debug("Could not call SetStats");\r
+ }\r
+ } else {\r
+ this.debug("Could not find Flash element");\r
+ }\r
+};\r
+\r
+SWFUpload.prototype.setCredentials = function(name, password) {\r
+ var movie_element = this.getMovieElement();\r
+ if (movie_element !== null && typeof(movie_element.SetCredentials) === "function") {\r
+ try {\r
+ return movie_element.SetCredentials(name, password);\r
+ }\r
+ catch (ex) {\r
+ this.debug("Could not call SetCredentials");\r
+ }\r
+ } else {\r
+ this.debug("Could not find Flash element");\r
+ }\r
+};\r
+\r
+SWFUpload.prototype.getFile = function (file_id) {\r
+ var movie_element = this.getMovieElement();\r
+ if (typeof(file_id) === "number") {\r
+ if (movie_element !== null && typeof(movie_element.GetFileByIndex) === "function") {\r
+ try {\r
+ return movie_element.GetFileByIndex(file_id);\r
+ }\r
+ catch (ex) {\r
+ this.debug("Could not call GetFileByIndex");\r
+ }\r
+ } else {\r
+ this.debug("Could not find Flash element");\r
+ }\r
+ } else {\r
+ if (movie_element !== null && typeof(movie_element.GetFile) === "function") {\r
+ try {\r
+ return movie_element.GetFile(file_id);\r
+ }\r
+ catch (ex) {\r
+ this.debug("Could not call GetFile");\r
+ }\r
+ } else {\r
+ this.debug("Could not find Flash element");\r
+ }\r
+ }\r
+};\r
+\r
+SWFUpload.prototype.addFileParam = function (file_id, name, value) {\r
+ var movie_element = this.getMovieElement();\r
+ if (movie_element !== null && typeof(movie_element.AddFileParam) === "function") {\r
+ try {\r
+ return movie_element.AddFileParam(file_id, name, value);\r
+ }\r
+ catch (ex) {\r
+ this.debug("Could not call AddFileParam");\r
+ }\r
+ } else {\r
+ this.debug("Could not find Flash element");\r
+ }\r
+};\r
+\r
+SWFUpload.prototype.removeFileParam = function (file_id, name) {\r
+ var movie_element = this.getMovieElement();\r
+ if (movie_element !== null && typeof(movie_element.RemoveFileParam) === "function") {\r
+ try {\r
+ return movie_element.RemoveFileParam(file_id, name);\r
+ }\r
+ catch (ex) {\r
+ this.debug("Could not call AddFileParam");\r
+ }\r
+ } else {\r
+ this.debug("Could not find Flash element");\r
+ }\r
+\r
+};\r
+\r
+SWFUpload.prototype.setUploadURL = function (url) {\r
+ var movie_element = this.getMovieElement();\r
+ if (movie_element !== null && typeof(movie_element.SetUploadURL) === "function") {\r
+ try {\r
+ this.addSetting("upload_url", url);\r
+ movie_element.SetUploadURL(this.getSetting("upload_url"));\r
+ }\r
+ catch (ex) {\r
+ this.debug("Could not call SetUploadURL");\r
+ }\r
+ } else {\r
+ this.debug("Could not find Flash element in setUploadURL");\r
+ }\r
+};\r
+\r
+SWFUpload.prototype.setPostParams = function (param_object) {\r
+ var movie_element = this.getMovieElement();\r
+ if (movie_element !== null && typeof(movie_element.SetPostParams) === "function") {\r
+ try {\r
+ this.addSetting("post_params", param_object);\r
+ movie_element.SetPostParams(this.getSetting("post_params"));\r
+ }\r
+ catch (ex) {\r
+ this.debug("Could not call SetPostParams");\r
+ }\r
+ } else {\r
+ this.debug("Could not find Flash element in SetPostParams");\r
+ }\r
+};\r
+\r
+SWFUpload.prototype.setFileTypes = function (types, description) {\r
+ var movie_element = this.getMovieElement();\r
+ if (movie_element !== null && typeof(movie_element.SetFileTypes) === "function") {\r
+ try {\r
+ this.addSetting("file_types", types);\r
+ this.addSetting("file_types_description", description);\r
+ movie_element.SetFileTypes(this.getSetting("file_types"), this.getSetting("file_types_description"));\r
+ }\r
+ catch (ex) {\r
+ this.debug("Could not call SetFileTypes");\r
+ }\r
+ } else {\r
+ this.debug("Could not find Flash element in SetFileTypes");\r
+ }\r
+};\r
+\r
+SWFUpload.prototype.setFileSizeLimit = function (file_size_limit) {\r
+ var movie_element = this.getMovieElement();\r
+ if (movie_element !== null && typeof(movie_element.SetFileSizeLimit) === "function") {\r
+ try {\r
+ this.addSetting("file_size_limit", file_size_limit);\r
+ movie_element.SetFileSizeLimit(this.getSetting("file_size_limit"));\r
+ }\r
+ catch (ex) {\r
+ this.debug("Could not call SetFileSizeLimit");\r
+ }\r
+ } else {\r
+ this.debug("Could not find Flash element in SetFileSizeLimit");\r
+ }\r
+};\r
+\r
+SWFUpload.prototype.setFileUploadLimit = function (file_upload_limit) {\r
+ var movie_element = this.getMovieElement();\r
+ if (movie_element !== null && typeof(movie_element.SetFileUploadLimit) === "function") {\r
+ try {\r
+ this.addSetting("file_upload_limit", file_upload_limit);\r
+ movie_element.SetFileUploadLimit(this.getSetting("file_upload_limit"));\r
+ }\r
+ catch (ex) {\r
+ this.debug("Could not call SetFileUploadLimit");\r
+ }\r
+ } else {\r
+ this.debug("Could not find Flash element in SetFileUploadLimit");\r
+ }\r
+};\r
+\r
+SWFUpload.prototype.setFileQueueLimit = function (file_queue_limit) {\r
+ var movie_element = this.getMovieElement();\r
+ if (movie_element !== null && typeof(movie_element.SetFileQueueLimit) === "function") {\r
+ try {\r
+ this.addSetting("file_queue_limit", file_queue_limit);\r
+ movie_element.SetFileQueueLimit(this.getSetting("file_queue_limit"));\r
+ }\r
+ catch (ex) {\r
+ this.debug("Could not call SetFileQueueLimit");\r
+ }\r
+ } else {\r
+ this.debug("Could not find Flash element in SetFileQueueLimit");\r
+ }\r
+};\r
+\r
+SWFUpload.prototype.setFilePostName = function (file_post_name) {\r
+ var movie_element = this.getMovieElement();\r
+ if (movie_element !== null && typeof(movie_element.SetFilePostName) === "function") {\r
+ try {\r
+ this.addSetting("file_post_name", file_post_name);\r
+ movie_element.SetFilePostName(this.getSetting("file_post_name"));\r
+ }\r
+ catch (ex) {\r
+ this.debug("Could not call SetFilePostName");\r
+ }\r
+ } else {\r
+ this.debug("Could not find Flash element in SetFilePostName");\r
+ }\r
+};\r
+\r
+SWFUpload.prototype.setDebugEnabled = function (debug_enabled) {\r
+ var movie_element = this.getMovieElement();\r
+ if (movie_element !== null && typeof(movie_element.SetDebugEnabled) === "function") {\r
+ try {\r
+ this.addSetting("debug_enabled", debug_enabled);\r
+ movie_element.SetDebugEnabled(this.getSetting("debug_enabled"));\r
+ }\r
+ catch (ex) {\r
+ this.debug("Could not call SetDebugEnabled");\r
+ }\r
+ } else {\r
+ this.debug("Could not find Flash element in SetDebugEnabled");\r
+ }\r
+};\r
+\r
+/* *******************************\r
+ Internal Event Callers\r
+ Don't override these! These event callers ensure that your custom event handlers\r
+ are called safely and in order.\r
+******************************* */\r
+\r
+/* This is the callback method that the Flash movie will call when it has been loaded and is ready to go.\r
+ Calling this or showUI() "manually" will bypass the Flash Detection built in to SWFUpload.\r
+ Use a ui_function setting if you want to control the UI loading after the flash has loaded.\r
+*/\r
+SWFUpload.prototype.flashReady = function () {\r
+ // Check that the movie element is loaded correctly with its ExternalInterface methods defined\r
+ var movie_element = this.getMovieElement();\r
+ if (movie_element === null || typeof(movie_element.StartUpload) !== "function") {\r
+ this.debug("ExternalInterface methods failed to initialize.");\r
+ return;\r
+ }\r
+ \r
+ var self = this;\r
+ if (typeof(self.flashReady_handler) === "function") {\r
+ this.eventQueue[this.eventQueue.length] = function() { self.flashReady_handler(); };\r
+ setTimeout(function () { self.executeNextEvent();}, 0);\r
+ } else {\r
+ this.debug("flashReady_handler event not defined");\r
+ }\r
+};\r
+\r
+/*\r
+ Event Queue. Rather can call events directly from Flash they events are\r
+ are placed in a queue and then executed. This ensures that each event is\r
+ executed in the order it was called which is not guarenteed when calling\r
+ setTimeout. Out of order events was especially problematic in Safari.\r
+*/\r
+SWFUpload.prototype.executeNextEvent = function () {\r
+ var f = this.eventQueue.shift();\r
+ if (typeof(f) === "function") {\r
+ f();\r
+ }\r
+}\r
+\r
+/* This is a chance to do something before the browse window opens */\r
+SWFUpload.prototype.fileDialogStart = function () {\r
+ var self = this;\r
+ if (typeof(self.fileDialogStart_handler) === "function") {\r
+ this.eventQueue[this.eventQueue.length] = function() { self.fileDialogStart_handler(); };\r
+ setTimeout(function () { self.executeNextEvent();}, 0);\r
+ } else {\r
+ this.debug("fileDialogStart event not defined");\r
+ }\r
+};\r
+\r
+\r
+/* Called when a file is successfully added to the queue. */\r
+SWFUpload.prototype.fileQueued = function (file) {\r
+ var self = this;\r
+ if (typeof(self.fileQueued_handler) === "function") {\r
+ this.eventQueue[this.eventQueue.length] = function() { self.fileQueued_handler(file); };\r
+ setTimeout(function () { self.executeNextEvent();}, 0);\r
+ } else {\r
+ this.debug("fileQueued event not defined");\r
+ }\r
+};\r
+\r
+\r
+/* Handle errors that occur when an attempt to queue a file fails. */\r
+SWFUpload.prototype.fileQueueError = function (file, error_code, message) {\r
+ var self = this;\r
+ if (typeof(self.fileQueueError_handler) === "function") {\r
+ this.eventQueue[this.eventQueue.length] = function() { self.fileQueueError_handler(file, error_code, message); };\r
+ setTimeout(function () { self.executeNextEvent();}, 0);\r
+ } else {\r
+ this.debug("fileQueueError event not defined");\r
+ }\r
+};\r
+\r
+/* Called after the file dialog has closed and the selected files have been queued.\r
+ You could call startUpload here if you want the queued files to begin uploading immediately. */\r
+SWFUpload.prototype.fileDialogComplete = function (num_files_selected) {\r
+ var self = this;\r
+ if (typeof(self.fileDialogComplete_handler) === "function") {\r
+ this.eventQueue[this.eventQueue.length] = function() { self.fileDialogComplete_handler(num_files_selected); };\r
+ setTimeout(function () { self.executeNextEvent();}, 0);\r
+ } else {\r
+ this.debug("fileDialogComplete event not defined");\r
+ }\r
+};\r
+\r
+/* Gets called when a file upload is about to be started. Return true to continue the upload. Return false to stop the upload.\r
+ If you return false then uploadError and uploadComplete are called (like normal).\r
+ \r
+ This is a good place to do any file validation you need.\r
+ */\r
+SWFUpload.prototype.uploadStart = function (file) {\r
+ var self = this;\r
+ if (typeof(self.fileDialogComplete_handler) === "function") {\r
+ this.eventQueue[this.eventQueue.length] = function() { self.returnUploadStart(self.uploadStart_handler(file)); };\r
+ setTimeout(function () { self.executeNextEvent();}, 0);\r
+ } else {\r
+ this.debug("uploadStart event not defined");\r
+ }\r
+};\r
+\r
+/* Note: Internal use only. This function returns the result of uploadStart to\r
+ flash. Since returning values in the normal way can result in Flash/JS circular\r
+ call issues we split up the call in a Timeout. This is transparent from the API\r
+ point of view.\r
+*/\r
+SWFUpload.prototype.returnUploadStart = function (return_value) {\r
+ var movie_element = this.getMovieElement();\r
+ if (movie_element !== null && typeof(movie_element.ReturnUploadStart) === "function") {\r
+ try {\r
+ movie_element.ReturnUploadStart(return_value);\r
+ }\r
+ catch (ex) {\r
+ this.debug("Could not call ReturnUploadStart");\r
+ }\r
+ } else {\r
+ this.debug("Could not find Flash element in returnUploadStart");\r
+ }\r
+};\r
+\r
+\r
+\r
+/* Called during upload as the file progresses. Use this event to update your UI. */\r
+SWFUpload.prototype.uploadProgress = function (file, bytes_complete, bytes_total) {\r
+ var self = this;\r
+ if (typeof(self.uploadProgress_handler) === "function") {\r
+ this.eventQueue[this.eventQueue.length] = function() { self.uploadProgress_handler(file, bytes_complete, bytes_total); };\r
+ setTimeout(function () { self.executeNextEvent();}, 0);\r
+ } else {\r
+ this.debug("uploadProgress event not defined");\r
+ }\r
+};\r
+\r
+/* Called when an error occurs during an upload. Use error_code and the SWFUpload.UPLOAD_ERROR constants to determine\r
+ which error occurred. The uploadComplete event is called after an error code indicating that the next file is\r
+ ready for upload. For files cancelled out of order the uploadComplete event will not be called. */\r
+SWFUpload.prototype.uploadError = function (file, error_code, message) {\r
+ var self = this;\r
+ if (typeof(this.uploadError_handler) === "function") {\r
+ this.eventQueue[this.eventQueue.length] = function() { self.uploadError_handler(file, error_code, message); };\r
+ setTimeout(function () { self.executeNextEvent();}, 0);\r
+ } else {\r
+ this.debug("uploadError event not defined");\r
+ }\r
+};\r
+\r
+/* This gets called when a file finishes uploading and the server-side upload script has completed and returned a 200\r
+status code. Any text returned by the server is available in server_data.\r
+**NOTE: The upload script MUST return some text or the uploadSuccess and uploadComplete events will not fire and the\r
+upload will become 'stuck'. */\r
+SWFUpload.prototype.uploadSuccess = function (file, server_data) {\r
+ var self = this;\r
+ if (typeof(self.uploadSuccess_handler) === "function") {\r
+ this.eventQueue[this.eventQueue.length] = function() { self.uploadSuccess_handler(file, server_data); };\r
+ setTimeout(function () { self.executeNextEvent();}, 0);\r
+ } else {\r
+ this.debug("uploadSuccess event not defined");\r
+ }\r
+};\r
+\r
+/* uploadComplete is called when the file is uploaded or an error occurred and SWFUpload is ready to make the next upload.\r
+ If you want the next upload to start to automatically you can call startUpload() from this event. */\r
+SWFUpload.prototype.uploadComplete = function (file) {\r
+ var self = this;\r
+ if (typeof(self.uploadComplete_handler) === "function") {\r
+ this.eventQueue[this.eventQueue.length] = function() { self.uploadComplete_handler(file); };\r
+ setTimeout(function () { self.executeNextEvent();}, 0);\r
+ } else {\r
+ this.debug("uploadComplete event not defined");\r
+ }\r
+};\r
+\r
+/* Called by SWFUpload JavaScript and Flash functions when debug is enabled. By default it writes messages to the\r
+ internal debug console. You can override this event and have messages written where you want. */\r
+SWFUpload.prototype.debug = function (message) {\r
+ var self = this;\r
+ if (typeof(self.debug_handler) === "function") {\r
+ this.eventQueue[this.eventQueue.length] = function() { self.debug_handler(message); };\r
+ setTimeout(function () { self.executeNextEvent();}, 0);\r
+ } else {\r
+ this.eventQueue[this.eventQueue.length] = function() { self.debugMessage(message); };\r
+ setTimeout(function () { self.executeNextEvent();}, 0);\r
+ }\r
+};\r
+\r
+\r
+/* **********************************\r
+ Default Event Handlers.\r
+ These event handlers are used by default if an overriding handler is\r
+ not defined in the SWFUpload settings object.\r
+ \r
+ JS Note: even though these are defined on the SWFUpload object (rather than the prototype) they\r
+ are attached (read: copied) to a SWFUpload instance and 'this' is given the proper context.\r
+ ********************************** */\r
+\r
+/* This is a special event handler that has no override in the settings. Flash calls this when it has\r
+ been loaded by the browser and is ready for interaction. You should not override it. If you need\r
+ to do something with SWFUpload has loaded then use the swfupload_loaded_handler setting.\r
+*/\r
+SWFUpload.flashReady = function () {\r
+ try {\r
+ this.debug("Flash called back and is ready.");\r
+\r
+ if (typeof(this.swfUploadLoaded_handler) === "function") {\r
+ this.swfUploadLoaded_handler();\r
+ }\r
+ } catch (ex) {\r
+ this.debug(ex);\r
+ }\r
+};\r
+\r
+/* This is a chance to something immediately after SWFUpload has loaded.\r
+ Like, hide the default/degraded upload form and display the SWFUpload form. */\r
+SWFUpload.swfUploadLoaded = function () {\r
+};\r
+\r
+/* This is a chance to do something before the browse window opens */\r
+SWFUpload.fileDialogStart = function () {\r
+};\r
+\r
+\r
+/* Called when a file is successfully added to the queue. */\r
+SWFUpload.fileQueued = function (file) {\r
+};\r
+\r
+\r
+/* Handle errors that occur when an attempt to queue a file fails. */\r
+SWFUpload.fileQueueError = function (file, error_code, message) {\r
+ try {\r
+ switch (error_code) {\r
+ case SWFUpload.QUEUE_ERROR.FILE_EXCEEDS_SIZE_LIMIT:\r
+ this.debug("Error Code: File too big, File name: " + file.name + ", File size: " + file.size + ", Message: " + message);\r
+ break;\r
+ case SWFUpload.QUEUE_ERROR.ZERO_BYTE_FILE:\r
+ this.debug("Error Code: Zero Byte File, File name: " + file.name + ", File size: " + file.size + ", Message: " + message);\r
+ break;\r
+ case SWFUpload.QUEUE_ERROR.QUEUE_LIMIT_EXCEEDED:\r
+ this.debug("Error Code: Upload limit reached, File name: " + file.name + ", File size: " + file.size + ", Message: " + message);\r
+ break;\r
+ case SWFUpload.QUEUE_ERROR.INVALID_FILETYPE:\r
+ this.debug("Error Code: File extension is not allowed, Message: " + message);\r
+ break;\r
+ default:\r
+ this.debug("Error Code: Unhandled error occured. Errorcode: " + error_code);\r
+ }\r
+ } catch (ex) {\r
+ this.debug(ex);\r
+ }\r
+};\r
+\r
+/* Called after the file dialog has closed and the selected files have been queued.\r
+ You could call startUpload here if you want the queued files to begin uploading immediately. */\r
+SWFUpload.fileDialogComplete = function (num_files_selected) {\r
+};\r
+\r
+/* Gets called when a file upload is about to be started. Return true to continue the upload. Return false to stop the upload.\r
+ If you return false then the uploadError callback is called and then uploadComplete (like normal).\r
+ \r
+ This is a good place to do any file validation you need.\r
+ \r
+ This is the only function that cannot be called on a setTimeout because it must return a value to Flash.\r
+ You SHOULD NOT make any calls in to Flash (e.i, changing settings, getting stats, etc). Flash Player bugs prevent\r
+ calls in to Flash from working reliably.\r
+*/\r
+SWFUpload.uploadStart = function (file) {\r
+ return true;\r
+};\r
+\r
+// Called during upload as the file progresses\r
+SWFUpload.uploadProgress = function (file, bytes_complete, bytes_total) {\r
+ this.debug("File Progress: " + file.id + ", Bytes: " + bytes_complete + ". Total: " + bytes_total);\r
+};\r
+\r
+/* 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\r
+server is available in server_data. The upload script must return some text or uploadSuccess will not fire (neither will uploadComplete). */\r
+SWFUpload.uploadSuccess = function (file, server_data) {\r
+};\r
+\r
+/* This is called last. The file is uploaded or an error occurred and SWFUpload is ready to make the next upload.\r
+ If you want to automatically start the next file just call startUpload from here.\r
+*/\r
+SWFUpload.uploadComplete = function (file) {\r
+};\r
+\r
+// Called by SWFUpload JavaScript and Flash functions when debug is enabled.\r
+// Override this method in your settings to call your own debug message handler\r
+SWFUpload.debug = function (message) {\r
+ if (this.getSetting("debug_enabled")) {\r
+ this.debugMessage(message);\r
+ }\r
+};\r
+\r
+/* Called when an upload occurs during upload. For HTTP errors 'message' will contain the HTTP STATUS CODE */\r
+SWFUpload.uploadError = function (file, error_code, message) {\r
+ try {\r
+ switch (errcode) {\r
+ case SWFUpload.UPLOAD_ERROR.SPECIFIED_FILE_ID_NOT_FOUND:\r
+ this.debug("Error Code: File ID specified for upload was not found, Message: " + msg);\r
+ break;\r
+ case SWFUpload.UPLOAD_ERROR.HTTP_ERROR:\r
+ this.debug("Error Code: HTTP Error, File name: " + file.name + ", Message: " + msg);\r
+ break;\r
+ case SWFUpload.UPLOAD_ERROR.MISSING_UPLOAD_URL:\r
+ this.debug("Error Code: No backend file, File name: " + file.name + ", Message: " + msg);\r
+ break;\r
+ case SWFUpload.UPLOAD_ERROR.IO_ERROR:\r
+ this.debug("Error Code: IO Error, File name: " + file.name + ", Message: " + msg);\r
+ break;\r
+ case SWFUpload.UPLOAD_ERROR.SECURITY_ERROR:\r
+ this.debug("Error Code: Security Error, File name: " + file.name + ", Message: " + msg);\r
+ break;\r
+ case SWFUpload.UPLOAD_ERROR.UPLOAD_LIMIT_EXCEEDED:\r
+ this.debug("Error Code: Upload limit reached, File name: " + file.name + ", File size: " + file.size + ", Message: " + msg);\r
+ break;\r
+ case SWFUpload.UPLOAD_ERROR.UPLOAD_FAILED:\r
+ this.debug("Error Code: Upload Initialization exception, File name: " + file.name + ", File size: " + file.size + ", Message: " + msg);\r
+ break;\r
+ case SWFUpload.UPLOAD_ERROR.FILE_VALIDATION_FAILED:\r
+ this.debug("Error Code: uploadStart callback returned false, File name: " + file.name + ", File size: " + file.size + ", Message: " + msg);\r
+ break;\r
+ case SWFUpload.UPLOAD_ERROR.FILE_CANCELLED:\r
+ this.debug("Error Code: The file upload was cancelled, File name: " + file.name + ", File size: " + file.size + ", Message: " + msg);\r
+ break;\r
+ case SWFUpload.UPLOAD_ERROR.UPLOAD_STOPPED:\r
+ this.debug("Error Code: The file upload was stopped, File name: " + file.name + ", File size: " + file.size + ", Message: " + msg);\r
+ break;\r
+ default:\r
+ this.debug("Error Code: Unhandled error occured. Errorcode: " + errcode);\r
+ }\r
+ } catch (ex) {\r
+ this.debug(ex);\r
+ }\r
+};\r
+\r
+\r
+\r
+/* **********************************\r
+ Debug Console\r
+ The debug console is a self contained, in page location\r
+ for debug message to be sent. The Debug Console adds\r
+ itself to the body if necessary.\r
+\r
+ The console is automatically scrolled as messages appear.\r
+ \r
+ You can override this console (to use FireBug's console for instance) by setting the debug event method to your own function\r
+ that handles the debug message\r
+ ********************************** */\r
+SWFUpload.prototype.debugMessage = function (message) {\r
+ var exception_message, exception_values;\r
+\r
+ if (typeof(message) === "object" && typeof(message.name) === "string" && typeof(message.message) === "string") {\r
+ exception_message = "";\r
+ exception_values = [];\r
+ for (var key in message) {\r
+ exception_values.push(key + ": " + message[key]);\r
+ }\r
+ exception_message = exception_values.join("\n");\r
+ exception_values = exception_message.split("\n");\r
+ exception_message = "EXCEPTION: " + exception_values.join("\nEXCEPTION: ");\r
+ SWFUpload.Console.writeLine(exception_message);\r
+ } else {\r
+ SWFUpload.Console.writeLine(message);\r
+ }\r
+};\r
+\r
+SWFUpload.Console = {};\r
+SWFUpload.Console.writeLine = function (message) {\r
+/*\r
+ var console, documentForm;\r
+\r
+ try {\r
+ console = document.getElementById("SWFUpload_Console");\r
+\r
+ if (!console) {\r
+ documentForm = document.createElement("form");\r
+ document.getElementsByTagName("body")[0].appendChild(documentForm);\r
+\r
+ console = document.createElement("textarea");\r
+ console.id = "SWFUpload_Console";\r
+ console.style.fontFamily = "monospace";\r
+ console.setAttribute("wrap", "off");\r
+ console.wrap = "off";\r
+ console.style.overflow = "auto";\r
+ console.style.width = "700px";\r
+ console.style.height = "350px";\r
+ console.style.margin = "5px";\r
+ documentForm.appendChild(console);\r
+ }\r
+\r
+ console.value += message + "\n";\r
+\r
+ console.scrollTop = console.scrollHeight - console.clientHeight;\r
+ } catch (ex) {\r
+ alert("Exception: " + ex.name + " Message: " + ex.message);\r
+ }\r
+*/\r
+ console.log(message);\r
+ \r
+};\r