/**
* SWFUpload v2.0 by Jacob Roberts, Feb 2008, http://www.swfupload.org, http://linebyline.blogspot.com
* -------- -------- -------- -------- -------- -------- -------- --------
* SWFUpload is (c) 2006 Lars Huring and Mammon Media and is released under the MIT License:
* http://www.opensource.org/licenses/mit-license.php
*
* Simplified javascript interface by Batiste Bieler. Use of jquery for simplicity.
*/
var SWFUpload = function(init_settings) {
this.init(init_settings);
};
SWFUpload.instances = {};
SWFUpload.movieCount = 0;
SWFUpload.FILE_STATUS = {
QUEUED : -1,
IN_PROGRESS: -2,
ERROR: -3,
COMPLETE: -4,
CANCELLED: -5
};
SWFUpload.prototype.init = function(init_settings) {
this.settings = {};
this.eventQueue = [];
this.movieName = "SWFUpload_" + SWFUpload.movieCount++;
// Setup global control tracking
SWFUpload.instances[this.movieName] = this;
// Load the settings. Load the Flash movie.
this.initSettings(init_settings);
this.loadFlash();
}
SWFUpload.prototype.initSettings = function(init_settings) {
// non-overrideable event handler
this.flashReady_handler = SWFUpload.flashReady;
// overrideable event handler that can receive several parameters, typicaly : file, error_code, message. Look at the flash source for more details.
possible_handlers = ['uploadReady', 'fileDialogStart', 'fileQueued', 'fileQueueError', 'fileDialogComplete', 'uploadProgress', 'uploadError', 'uploadSuccess', 'uploadComplete', 'debug']
var self = this;
var getHandler = function(name) {
if(init_settings[name])
return init_settings[name];
else if(self[name])
return self[name];
else
return function(){self.debug(handler_name+" is not implemented")};
}
var constructHandler = function(handler_name) {
var func = getHandler(handler_name);
return function(param1, param2, param3) {
setTimeout(function() {
self.eventQueue[self.eventQueue.length] = function() {
func.call(self, param1, param2, param3);
};
self.executeNextEvent();
}, 0);
}
}
for(index in possible_handlers) {
var handler_name = possible_handlers[index];
this[handler_name] = constructHandler(handler_name);
}
// Gets called when a file upload is about to be started.
this["uploadStart"] = function(file) {
var movie_element = self.getMovieElement();
self.eventQueue[self.eventQueue.length] = function() {
// true is needed here to start upload
var uploadStart = getHandler("uploadStart")(file);
movie_element.ReturnUploadStart(uploadStart);
};
setTimeout(function() { self.executeNextEvent();}, 0);
};
// Set default_value to undefined to trigger an error if the
// user need to override a value.
var add = function(param_name, default_value) {
if(!default_value && !init_settings[param_name])
self.debug("Error: " + param_name+" need to be defined in settings")
self.addSetting(param_name, init_settings[param_name], default_value);
}
// Debug setting
add("debug_enabled", false);
// File Settings
add("file_types", "*.*");
add("file_types_description", "All Files");
add("file_size_limit", "1024");
add("file_upload_limit", "0");
add("file_queue_limit", "0");
// Flash Settings
add("upload_url", undefined);
add("flash_url", undefined);
// Changing this value will break linux flash player
add("file_post_name", "FileData");
add("post_params", {});
};
SWFUpload.prototype.loadFlash = function() {
if (document.getElementById(this.movieName)) {
return false;
}
// Append the container and load the flash
var container = $('<div style="width:1px;height:1px"></div>');
container.html(this.getFlashHTML());
$('body').append(container);
};
// Generates the embed/object tags needed to embed the flash in to the document
SWFUpload.prototype.getFlashHTML = function() {
var html = "";
html +='<object id="' + this.movieName + '" data="' + this.getSetting("flash_url")+'" type="application/x-shockwave-flash" width="1" height="1">';
html +='<param name="movie" value="' + this.getSetting("flash_url") + '" />';
html +='<param name="flashvars" value="' + this.getFlashVars() +'" />';
html +='</object>';
return html;
};
/* This private method builds the parameter string that will be passed to flash. */
SWFUpload.prototype.getFlashVars = function() {
// Build a string from the post param object
var param_string = this.buildParamString();
// Build the parameter string
var html = "";
html += "movieName=" + encodeURIComponent(this.movieName);
html += "&uploadURL=" + encodeURIComponent(this.getSetting("upload_url"));
html += "¶ms=" + encodeURIComponent(param_string);
html += "&filePostName=" + encodeURIComponent(this.getSetting("file_post_name"));
html += "&fileTypes=" + encodeURIComponent(this.getSetting("file_types"));
html += "&fileTypesDescription=" + encodeURIComponent(this.getSetting("file_types_description"));
html += "&fileSizeLimit=" + encodeURIComponent(this.getSetting("file_size_limit"));
html += "&fileUploadLimit=" + encodeURIComponent(this.getSetting("file_upload_limit"));
html += "&fileQueueLimit=" + encodeURIComponent(this.getSetting("file_queue_limit"));
html += "&debugEnabled=" + encodeURIComponent(this.getSetting("debug_enabled"));
return html;
};
SWFUpload.prototype.getMovieElement = function() {
if (!this.movieElement) {
if(!document.getElementById(this.movieName)) {
this.debug("Movie is not in DOM.")
}
this.movieElement = document.getElementById(this.movieName);
}
return this.movieElement;
};
SWFUpload.prototype.buildParamString = function() {
var post_params = this.getSetting("post_params");
var param_string_pairs = [];
// Retrieve the user defined parameters
for (var name in post_params) {
param_string_pairs.push(encodeURIComponent(name) + "=" + encodeURIComponent(post_params[name]));
}
return param_string_pairs.join("&");
};
// Saves a setting. If the value given is undefined or null then the default_value is used.
SWFUpload.prototype.addSetting = function(name, value, default_value) {
if (!value)
this.settings[name] = default_value;
else
this.settings[name] = value;
return this.settings[name];
};
// Gets a setting. Returns empty string if not found.
SWFUpload.prototype.getSetting = function(name) {
if (this.settings[name])
return this.settings[name];
return "";
};
/* Flash control methods */
// helper to call movie clip functions
SWFUpload.prototype.movie_helper = function(func_name, func, file_id, name, value) {
var movie_element = this.getMovieElement();
try {
return movie_element[func_name](file_id, name, value);
}
catch(ex) {
this.debug("Could not call "+func_name);
}
};
// these functions are a little bit stupid
SWFUpload.prototype.selectFile = function() {
this.movie_helper("SelectFile");
};
SWFUpload.prototype.selectFiles = function() {
this.movie_helper("SelectFiles");
};
// Cancels a the file upload. You must specify a file_id */
SWFUpload.prototype.cancelUpload = function(file_id) {
this.movie_helper("CancelUpload", file_id);
};
// Stops the current upload. The file is re-queued. If nothing is currently uploading then nothing happens. */
SWFUpload.prototype.stopUpload = function() {
this.movie_helper("StopUpload");
};
SWFUpload.prototype.getStats = function() {
return this.movie_helper("GetStats");
};
// Start the upload. If a file_id is specified that file is uploaded. Otherwise the first file in the queue is uploaded. This call uses setTimeout since Flash will be calling back in to JavaScript
SWFUpload.prototype.startUpload = function(file_id) {
var self = this;
var movie_element = this.getMovieElement();
if (movie_element && movie_element.StartUpload) {
setTimeout(
function() {
try {
movie_element.StartUpload(file_id);
}
catch (ex) {
self.debug("Could not call StartUpload: " + ex);
}
}, 0
);
} else {
this.debug("Could not find Flash element");
}
};
SWFUpload.prototype.cancelQueue = function() {
this.stopUpload();
var stats;
do {
stats = this.getStats();
this.cancelUpload();
} while (stats.files_queued !== 0);
};
SWFUpload.prototype.getFile = function(file_id) {
if (typeof(file_id) === "number") {
return this.movie_helper("GetFileByIndex", file_id);
} else {
return this.movie_helper("GetFile", file_id);
}
};
// Internal Event Callers. These event callers ensure that your custom event handlers are called safely and in order.
// This is the callback method that the Flash movie will call when it has been loaded and is ready to go.
SWFUpload.prototype.flashReady = function() {
var movie_element = this.getMovieElement();
if (!movie_element || !movie_element.StartUpload) {
this.debug("ExternalInterface methods failed to initialize.");
return;
}
var self = this;
this.eventQueue[this.eventQueue.length] = function() {
if (self.uploadReady)
self.uploadReady();
};
setTimeout(function() { self.executeNextEvent();}, 0);
};
// Events are placed in a queue and then executed.
SWFUpload.prototype.executeNextEvent = function() {
var f = this.eventQueue.shift();
if(f)
f();
}
// Gets called when a file upload is about to be started.
SWFUpload.prototype.uploadStart = function(file) {
var self = this;
var movie_element = this.getMovieElement();
if (this.uploadStart_handler) {
this.eventQueue[this.eventQueue.length] = function() {
// true is needed here to start upload
var uploadStart = self.uploadStart_handler(file);
movie_element.ReturnUploadStart(uploadStart);
};
setTimeout(function() { self.executeNextEvent();}, 0);
} else {
this.debug("uploadStart event not defined");
}
};
// Handle errors that occur when an attempt to queue a file fails.
SWFUpload.prototype.fileQueueError = function(file, error_code, message) {
var msg = [];
msg[-100] = "Upload limit reached";
msg[-110] = "File too big";
msg[-120] = "Zero byte file";
msg[-130] = "File extension is not allowed";
var m = "Error Code: " + msg[error_code] + ", Message: " + msg;
if(file) {
m += "File name: " + file.name + ", File size: " + file.size;
}
this.debug(m);
};
SWFUpload.prototype.uploadErrorMessage = function(error_code) {
var msg = [];
msg[-200] = "HTTP Error";
msg[-210] = "No backend file";
msg[-220] = "IO Error";
msg[-230] = "Security error";
msg[-240] = "Upload limit reached";
msg[-250] = "Upload failed";
msg[-260] = "File ID specified for upload was not found";
msg[-270] = "uploadStart callback returned false";
msg[-280] = "The file upload was cancelled";
msg[-290] = "The file upload was stopped";
return msg[error_code];
}
// Called when an error occurs during upload. For HTTP errors 'message' will contain the HTTP STATUS CODE
SWFUpload.prototype.uploadError = function(file, error_code, message) {
if(!file){
var file = {'name':'None', 'size':'None'};
}
var msg = this.uploadErrorMessage(error_code);
this.debug("Error Code: "+msg[index]+", File name: " + file.name + ", File size: " + file.size + ", Message: " + msg);
};
// Override this method in your settings to call your own debug message handler
SWFUpload.prototype.debug = function(message) {
if (this.getSetting("debug_enabled")) {
this.debugMessage(message);
}
};
SWFUpload.prototype.debugMessage = function(message) {
var console = $("#swfupload-console");
if (!console[0]) {
console = $('<textarea id="swfupload-console" cols="80" rows="20"></textarea>');
$('body').append(console);
}
if (typeof(message) === "object") {
var exception_message = "";
var exception_values = [];
for (var key in message) {
exception_values.push(key + ": " + message[key]);
}
exception_message = exception_values.join("\n");
exception_values = exception_message.split("\n");
exception_message = "Exception: " + exception_values.join("\Exception: ");
console.val(console.val()+exception_message);
} else {
console.val(console.val()+message+"\n");
}
};