Updated lib/swfupload to SWFUpload v2.2.0 Beta 5

This commit is contained in:
Bharat Mediratta
2009-03-17 06:00:21 +00:00
parent 920804bd47
commit 63c8bb8d76
3 changed files with 144 additions and 107 deletions
+109 -93
View File
@@ -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 ['<object id="', this.movieName, '" type="application/x-shockwave-flash" data="', this.settings.flash_url, '" width="', this.settings.button_width, '" height="', this.settings.button_height, '" class="swfupload">',
'<param name="wmode" value="', this.settings.button_window_mode , '" />',
'<param name="wmode" value="', this.settings.button_window_mode, '" />',
'<param name="movie" value="', this.settings.flash_url, '" />',
'<param name="quality" value="high" />',
'<param name="menu" value="false" />',
@@ -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('<invoke name="' + functionName + '" returntype="javascript">' + __flash__argumentsToXML(argumentArray, 0) + '</invoke>');
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 () {
+35 -14
View File
@@ -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;
}
}
};
Binary file not shown.