From 63c8bb8d76e903f2a56d80a04728d39bb661b9fc Mon Sep 17 00:00:00 2001 From: Bharat Mediratta Date: Tue, 17 Mar 2009 06:00:21 +0000 Subject: [PATCH] Updated lib/swfupload to SWFUpload v2.2.0 Beta 5 --- lib/swfupload/swfupload.js | 202 +++++++++++++++++-------------- lib/swfupload/swfupload.queue.js | 49 +++++--- lib/swfupload/swfupload.swf | Bin 11931 -> 12419 bytes 3 files changed, 144 insertions(+), 107 deletions(-) diff --git a/lib/swfupload/swfupload.js b/lib/swfupload/swfupload.js index 849cf28e..7a6f6567 100644 --- a/lib/swfupload/swfupload.js +++ b/lib/swfupload/swfupload.js @@ -31,6 +31,7 @@ SWFUpload.prototype.initSWFUpload = function (settings) { this.movieName = "SWFUpload_" + SWFUpload.movieCount++; this.movieElement = null; + // Setup global control tracking SWFUpload.instances[this.movieName] = this; @@ -49,7 +50,7 @@ SWFUpload.prototype.initSWFUpload = function (settings) { /* *************** */ SWFUpload.instances = {}; SWFUpload.movieCount = 0; -SWFUpload.version = "2.2.0 Beta 2"; +SWFUpload.version = "2.2.0 Beta 5 2008-01-29"; SWFUpload.QUEUE_ERROR = { QUEUE_LIMIT_EXCEEDED : -100, FILE_EXCEEDS_SIZE_LIMIT : -110, @@ -130,7 +131,7 @@ SWFUpload.prototype.initSettings = function () { this.ensureDefault("button_text_left_padding", 0); this.ensureDefault("button_action", SWFUpload.BUTTON_ACTION.SELECT_FILES); this.ensureDefault("button_disabled", false); - this.ensureDefault("button_placeholder_id", null); + this.ensureDefault("button_placeholder_id", ""); this.ensureDefault("button_cursor", SWFUpload.CURSOR.ARROW); this.ensureDefault("button_window_mode", SWFUpload.WINDOW_MODE.WINDOW); @@ -160,50 +161,15 @@ SWFUpload.prototype.initSettings = function () { this.customSettings = this.settings.custom_settings; // Update the flash url if needed - if (this.settings.prevent_swf_caching) { - this.settings.flash_url = this.settings.flash_url + "?swfuploadrnd=" + Math.floor(Math.random() * 999999999); + if (!!this.settings.prevent_swf_caching) { + this.settings.flash_url = this.settings.flash_url + (this.settings.flash_url.indexOf("?") < 0 ? "?" : "&") + "preventswfcaching=" + new Date().getTime(); } delete this.ensureDefault; }; +// Private: loadFlash replaces the button_placeholder element with the flash movie. SWFUpload.prototype.loadFlash = function () { - if (this.settings.button_placeholder_id !== "") { - this.replaceWithFlash(); - } else { - this.appendFlash(); - } -}; - -// Private: appendFlash gets the HTML tag for the Flash -// It then appends the flash to the body -SWFUpload.prototype.appendFlash = function () { - var targetElement, container; - - // Make sure an element with the ID we are going to use doesn't already exist - if (document.getElementById(this.movieName) !== null) { - throw "ID " + this.movieName + " is already in use. The Flash Object could not be added"; - } - - // Get the body tag where we will be adding the flash movie - targetElement = document.getElementsByTagName("body")[0]; - - if (targetElement == undefined) { - throw "Could not find the 'body' element."; - } - - // Append the container and load the flash - container = document.createElement("div"); - container.style.width = "1px"; - container.style.height = "1px"; - container.style.overflow = "hidden"; - - targetElement.appendChild(container); - container.innerHTML = this.getFlashHTML(); // Using innerHTML is non-standard but the only sensible way to dynamically add Flash in IE (and maybe other browsers) -}; - -// Private: replaceWithFlash replaces the button_placeholder element with the flash movie. -SWFUpload.prototype.replaceWithFlash = function () { var targetElement, tempParent; // Make sure an element with the ID we are going to use doesn't already exist @@ -215,7 +181,7 @@ SWFUpload.prototype.replaceWithFlash = function () { targetElement = document.getElementById(this.settings.button_placeholder_id); if (targetElement == undefined) { - throw "Could not find the placeholder element."; + throw "Could not find the placeholder element: " + this.settings.button_placeholder_id; } // Append the container and load the flash @@ -223,13 +189,18 @@ SWFUpload.prototype.replaceWithFlash = function () { tempParent.innerHTML = this.getFlashHTML(); // Using innerHTML is non-standard but the only sensible way to dynamically add Flash in IE (and maybe other browsers) targetElement.parentNode.replaceChild(tempParent.firstChild, targetElement); + // Fix IE Flash/Form bug + if (window[this.movieName] == undefined) { + window[this.movieName] = this.getMovieElement(); + } + }; // Private: getFlashHTML generates the object tag needed to embed the flash in to the document SWFUpload.prototype.getFlashHTML = function () { // Flash Satay object syntax: http://www.alistapart.com/articles/flashsatay return ['', - '', + '', '', '', '', @@ -306,46 +277,54 @@ SWFUpload.prototype.buildParamString = function () { // Public: Used to remove a SWFUpload instance from the page. This method strives to remove // all references to the SWF, and other objects so memory is properly freed. // Returns true if everything was destroyed. Returns a false if a failure occurs leaving SWFUpload in an inconsistant state. +// Credits: Major improvements provided by steffen SWFUpload.prototype.destroy = function () { try { // Make sure Flash is done before we try to remove it - this.stopUpload(); + this.cancelUpload(null, false); + // Remove the SWFUpload DOM nodes var movieElement = null; - try { - movieElement = this.getMovieElement(); - } catch (ex) { - } + movieElement = this.getMovieElement(); - if (movieElement != undefined && movieElement.parentNode != undefined && typeof movieElement.parentNode.removeChild === "function") { - var container = movieElement.parentNode; - if (container != undefined) { - container.removeChild(movieElement); - if (container.parentNode != undefined && typeof container.parentNode.removeChild === "function") { - container.parentNode.removeChild(container); - } + if (movieElement && typeof(movieElement.CallFunction) === "unknown") { // We only want to do this in IE + // Loop through all the movie's properties and remove all function references (DOM/JS IE 6/7 memory leak workaround) + for (var i in movieElement) { + try { + if (typeof(movieElement[i]) === "function") { + movieElement[i] = null; + } + } catch (ex1) {} } + + // Remove the Movie Element from the page + try { + movieElement.parentNode.removeChild(movieElement); + } catch (ex) {} } - // Destroy references + // Remove IE form fix reference + window[this.movieName] = null; + + // Destroy other references SWFUpload.instances[this.movieName] = null; delete SWFUpload.instances[this.movieName]; - delete this.movieElement; - delete this.settings; - delete this.customSettings; - delete this.eventQueue; - delete this.movieName; + this.movieElement = null; + this.settings = null; + this.customSettings = null; + this.eventQueue = null; + this.movieName = null; - delete window[this.movieName]; return true; - } catch (ex1) { + } catch (ex2) { return false; } }; + // Public: displayDebugInfo prints out settings and configuration // information about this SWFUpload instance. // This function (and any references to it) can be deleted when placing @@ -430,31 +409,22 @@ SWFUpload.prototype.callFlash = function (functionName, argumentArray) { argumentArray = argumentArray || []; var movieElement = this.getMovieElement(); - var returnValue; + var returnValue, returnString; - if (typeof movieElement[functionName] === "function") { - // 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. - if (argumentArray.length === 0) { - returnValue = movieElement[functionName](); - } else if (argumentArray.length === 1) { - returnValue = movieElement[functionName](argumentArray[0]); - } else if (argumentArray.length === 2) { - returnValue = movieElement[functionName](argumentArray[0], argumentArray[1]); - } else if (argumentArray.length === 3) { - returnValue = movieElement[functionName](argumentArray[0], argumentArray[1], argumentArray[2]); - } else { - throw "Too many arguments"; - } - - // Unescape file post param values - if (returnValue != undefined && typeof returnValue.post === "object") { - returnValue = this.unescapeFilePostParams(returnValue); - } - - return returnValue; - } else { - throw "Invalid function name: " + functionName; + // Flash's method if calling ExternalInterface methods (code adapted from MooTools). + try { + returnString = movieElement.CallFunction('' + __flash__argumentsToXML(argumentArray, 0) + ''); + returnValue = eval(returnString); + } catch (ex) { + throw "Call to " + functionName + " failed"; } + + // Unescape file post param values + if (returnValue != undefined && typeof returnValue.post === "object") { + returnValue = this.unescapeFilePostParams(returnValue); + } + + return returnValue; }; @@ -464,17 +434,19 @@ SWFUpload.prototype.callFlash = function (functionName, argumentArray) { to operate SWFUpload ***************************** */ +// WARNING: this function does not work in Flash Player 10 // Public: selectFile causes a File Selection Dialog window to appear. This -// dialog only allows 1 file to be selected. WARNING: this function does not work in Flash Player 10 +// dialog only allows 1 file to be selected. SWFUpload.prototype.selectFile = function () { this.callFlash("SelectFile"); }; +// WARNING: this function does not work in Flash Player 10 // Public: selectFiles causes a File Selection Dialog window to appear/ This // dialog allows the user to select any number of files // Flash Bug Warning: Flash limits the number of selectable files based on the combined length of the file names. // If the selection name length is too long the dialog will fail in an unpredictable manner. There is no work-around -// for this bug. WARNING: this function does not work in Flash Player 10 +// for this bug. SWFUpload.prototype.selectFiles = function () { this.callFlash("SelectFiles"); }; @@ -763,21 +735,65 @@ SWFUpload.prototype.unescapeFilePostParams = function (file) { return file; }; +// Private: Called by Flash to see if JS can call in to Flash (test if External Interface is working) +SWFUpload.prototype.testExternalInterface = function () { + try { + return this.callFlash("TestExternalInterface"); + } catch (ex) { + return false; + } +}; + +// Private: This event is called by Flash when it has finished loading. Don't modify this. +// Use the swfupload_loaded_handler event setting to execute custom code when SWFUpload has loaded. SWFUpload.prototype.flashReady = function () { // Check that the movie element is loaded correctly with its ExternalInterface methods defined var movieElement = this.getMovieElement(); - if (typeof movieElement.StartUpload !== "function") { - throw "ExternalInterface methods failed to initialize."; + + if (!movieElement) { + this.debug("Flash called back ready but the flash movie can't be found."); + return; } - // Fix IE Flash/Form bug - if (window[this.movieName] == undefined) { - window[this.movieName] = movieElement; - } + this.cleanUp(movieElement); this.queueEvent("swfupload_loaded_handler"); }; +// Private: removes Flash added fuctions to the DOM node to prevent memory leaks in IE. +// This function is called by Flash each time the ExternalInterface functions are created. +SWFUpload.prototype.cleanUp = function (movieElement) { + // Pro-actively unhook all the Flash functions + try { + if (this.movieElement && typeof(movieElement.CallFunction) === "unknown") { // We only want to do this in IE + this.debug("Removing Flash functions hooks (this should only run in IE and should prevent memory leaks)"); + for (var key in movieElement) { + try { + if (typeof(movieElement[key]) === "function") { + movieElement[key] = null; + } + } catch (ex) { + } + } + } + } catch (ex1) { + + } + + // Fix Flashes own cleanup code so if the SWFMovie was removed from the page + // it doesn't display errors. + window["__flash__removeCallback"] = function (instance, name) { + try { + if (instance) { + instance[name] = null; + } + } catch (flashEx) { + + } + }; + +}; + /* This is a chance to do something before the browse window opens */ SWFUpload.prototype.fileDialogStart = function () { diff --git a/lib/swfupload/swfupload.queue.js b/lib/swfupload/swfupload.queue.js index b04d87ac..69e619da 100644 --- a/lib/swfupload/swfupload.queue.js +++ b/lib/swfupload/swfupload.queue.js @@ -21,23 +21,27 @@ if (typeof(SWFUpload) === "function") { oldInitSettings.call(this); } - this.customSettings.queue_cancelled_flag = false; - this.customSettings.queue_upload_count = 0; + this.queueSettings = {}; - this.settings.user_upload_complete_handler = this.settings.upload_complete_handler; + this.queueSettings.queue_cancelled_flag = false; + this.queueSettings.queue_upload_count = 0; + + this.queueSettings.user_upload_complete_handler = this.settings.upload_complete_handler; + this.queueSettings.user_upload_start_handler = this.settings.upload_start_handler; this.settings.upload_complete_handler = SWFUpload.queue.uploadCompleteHandler; + this.settings.upload_start_handler = SWFUpload.queue.uploadStartHandler; this.settings.queue_complete_handler = this.settings.queue_complete_handler || null; }; })(SWFUpload.prototype.initSettings); SWFUpload.prototype.startUpload = function (fileID) { - this.customSettings.queue_cancelled_flag = false; - this.callFlash("StartUpload", false, [fileID]); + this.queueSettings.queue_cancelled_flag = false; + this.callFlash("StartUpload", [fileID]); }; SWFUpload.prototype.cancelQueue = function () { - this.customSettings.queue_cancelled_flag = true; + this.queueSettings.queue_cancelled_flag = true; this.stopUpload(); var stats = this.getStats(); @@ -47,30 +51,47 @@ if (typeof(SWFUpload) === "function") { } }; + SWFUpload.queue.uploadStartHandler = function (file) { + var returnValue; + if (typeof(this.queueSettings.user_upload_start_handler) === "function") { + returnValue = this.queueSettings.user_upload_start_handler.call(this, file); + } + + // To prevent upload a real "FALSE" value must be returned, otherwise default to a real "TRUE" value. + returnValue = (returnValue === false) ? false : true; + + this.queueSettings.queue_cancelled_flag = !returnValue; + + return returnValue; + }; + SWFUpload.queue.uploadCompleteHandler = function (file) { - var user_upload_complete_handler = this.settings.user_upload_complete_handler; + var user_upload_complete_handler = this.queueSettings.user_upload_complete_handler; var continueUpload; if (file.filestatus === SWFUpload.FILE_STATUS.COMPLETE) { - this.customSettings.queue_upload_count++; + this.queueSettings.queue_upload_count++; } if (typeof(user_upload_complete_handler) === "function") { continueUpload = (user_upload_complete_handler.call(this, file) === false) ? false : true; + } else if (file.filestatus === SWFUpload.FILE_STATUS.QUEUED) { + // If the file was stopped and re-queued don't restart the upload + continueUpload = false; } else { continueUpload = true; } if (continueUpload) { var stats = this.getStats(); - if (stats.files_queued > 0 && this.customSettings.queue_cancelled_flag === false) { + if (stats.files_queued > 0 && this.queueSettings.queue_cancelled_flag === false) { this.startUpload(); - } else if (this.customSettings.queue_cancelled_flag === false) { - this.queueEvent("queue_complete_handler", [this.customSettings.queue_upload_count]); - this.customSettings.queue_upload_count = 0; + } else if (this.queueSettings.queue_cancelled_flag === false) { + this.queueEvent("queue_complete_handler", [this.queueSettings.queue_upload_count]); + this.queueSettings.queue_upload_count = 0; } else { - this.customSettings.queue_cancelled_flag = false; - this.customSettings.queue_upload_count = 0; + this.queueSettings.queue_cancelled_flag = false; + this.queueSettings.queue_upload_count = 0; } } }; diff --git a/lib/swfupload/swfupload.swf b/lib/swfupload/swfupload.swf index a627b19b1d88a1ccd6e90f81eee9d19bf511890f..3fed93564944021dd9e08fb65dc637e043824519 100644 GIT binary patch literal 12419 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