redmine_dmsf/assets/javascripts/plupload/plupload.browserplus.js
vit.jonas@gmail.com 02c8da4011 Merged development branch
* updated Plupload to 1.4.3.2
* Plupload tuned
* upload controls set according to settings
* added setting for max number of uploaded files at once
* incremented version info


git-svn-id: http://redmine-dmsf.googlecode.com/svn/trunk/redmine_dmsf@22 5e329b0b-a2ee-ea63-e329-299493fc886d
2011-05-08 16:54:58 +00:00

338 lines
9.4 KiB
JavaScript

/**
* plupload.browserplus.js
*
* Copyright 2009, Moxiecode Systems AB
* Released under GPL License.
*
* License: http://www.plupload.com/license
* Contributing: http://www.plupload.com/contributing
*/
// JSLint defined globals
/*global plupload:false, BrowserPlus:false, window:false */
(function(plupload) {
/**
* Yahoo BrowserPlus implementation. This runtime supports these features: dragdrop, jpgresize, pngresize.
*
* @static
* @class plupload.runtimes.BrowserPlus
* @extends plupload.Runtime
*/
plupload.runtimes.BrowserPlus = plupload.addRuntime("browserplus", {
/**
* Returns a list of supported features for the runtime.
*
* @return {Object} Name/value object with supported features.
*/
getFeatures : function() {
return {
dragdrop : true,
jpgresize : true,
pngresize : true,
chunks : true,
progress: true,
multipart: true
};
},
/**
* Initializes the browserplus runtime.
*
* @method init
* @param {plupload.Uploader} uploader Uploader instance that needs to be initialized.
* @param {function} callback Callback to execute when the runtime initializes or fails to initialize. If it succeeds an object with a parameter name success will be set to true.
*/
init : function(uploader, callback) {
var browserPlus = window.BrowserPlus, browserPlusFiles = {}, settings = uploader.settings, resize = settings.resize;
function addSelectedFiles(native_files) {
var files, i, selectedFiles = [], file, id;
// Add the native files and setup plupload files
for (i = 0; i < native_files.length; i++) {
file = native_files[i];
id = plupload.guid();
browserPlusFiles[id] = file;
selectedFiles.push(new plupload.File(id, file.name, file.size));
}
// Any files selected fire event
if (i) {
uploader.trigger("FilesAdded", selectedFiles);
}
}
// Setup event listeners if browserplus was initialized
function setup() {
// Add drop handler
uploader.bind("PostInit", function() {
var dropTargetElm, dropElmId = settings.drop_element,
dropTargetId = uploader.id + '_droptarget',
dropElm = document.getElementById(dropElmId),
lastState;
// Enable/disable drop support for the drop target
// this is needed to resolve IE bubbeling issues and make it possible to drag/drop
// files into gears runtimes on the same page
function addDropHandler(id, end_callback) {
// Add drop target and listener
browserPlus.DragAndDrop.AddDropTarget({id : id}, function(res) {
browserPlus.DragAndDrop.AttachCallbacks({
id : id,
hover : function(res) {
if (!res && end_callback) {
end_callback();
}
},
drop : function(res) {
if (end_callback) {
end_callback();
}
addSelectedFiles(res);
}
}, function() {
});
});
}
function hide() {
document.getElementById(dropTargetId).style.top = '-1000px';
}
if (dropElm) {
// Since IE has issues with bubbeling when it comes to the drop of files
// we need to do this hack where we show a drop target div element while dropping
if (document.attachEvent && (/MSIE/gi).test(navigator.userAgent)) {
// Create drop target
dropTargetElm = document.createElement('div');
dropTargetElm.setAttribute('id', dropTargetId);
plupload.extend(dropTargetElm.style, {
position : 'absolute',
top : '-1000px',
background : 'red',
filter : 'alpha(opacity=0)',
opacity : 0
});
document.body.appendChild(dropTargetElm);
plupload.addEvent(dropElm, 'dragenter', function(e) {
var dropElm, dropElmPos;
dropElm = document.getElementById(dropElmId);
dropElmPos = plupload.getPos(dropElm);
plupload.extend(document.getElementById(dropTargetId).style, {
top : dropElmPos.y + 'px',
left : dropElmPos.x + 'px',
width : dropElm.offsetWidth + 'px',
height : dropElm.offsetHeight + 'px'
});
});
addDropHandler(dropTargetId, hide);
} else {
addDropHandler(dropElmId);
}
}
plupload.addEvent(document.getElementById(settings.browse_button), 'click', function(e) {
var mimeTypes = [], i, a, filters = settings.filters, ext;
e.preventDefault();
// Convert extensions to mimetypes
for (i = 0; i < filters.length; i++) {
ext = filters[i].extensions.split(',');
for (a = 0; a < ext.length; a++) {
mimeTypes.push(plupload.mimeTypes[ext[a]]);
}
}
browserPlus.FileBrowse.OpenBrowseDialog({
mimeTypes : mimeTypes
}, function(res) {
if (res.success) {
addSelectedFiles(res.value);
}
});
});
// Prevent IE leaks
dropElm = dropTargetElm = null;
});
uploader.bind("UploadFile", function(up, file) {
var nativeFile = browserPlusFiles[file.id], reqParams = {},
chunkSize = up.settings.chunk_size, loadProgress, chunkStack = [];
function uploadFile(chunk, chunks) {
var chunkFile;
// Stop upload if file is maked as failed
if (file.status == plupload.FAILED) {
return;
}
reqParams.name = file.target_name || file.name;
// Only send chunk parameters if chunk size is defined
if (chunkSize) {
reqParams.chunk = "" + chunk;
reqParams.chunks = "" + chunks;
}
chunkFile = chunkStack.shift();
browserPlus.Uploader.upload({
url : up.settings.url,
files : {file : chunkFile},
cookies : document.cookies,
postvars : plupload.extend(reqParams, up.settings.multipart_params),
progressCallback : function(res) {
var i, loaded = 0;
// since more than 1 chunk can be sent at a time, keep track of how many bytes
// of each chunk was sent
loadProgress[chunk] = parseInt(res.filePercent * chunkFile.size / 100, 10);
for (i = 0; i < loadProgress.length; i++) {
loaded += loadProgress[i];
}
file.loaded = loaded;
up.trigger('UploadProgress', file);
}
}, function(res) {
var httpStatus, chunkArgs;
if (res.success) {
httpStatus = res.value.statusCode;
if (chunkSize) {
up.trigger('ChunkUploaded', file, {
chunk : chunk,
chunks : chunks,
response : res.value.body,
status : httpStatus
});
}
if (chunkStack.length > 0) {
// More chunks to be uploaded
uploadFile(++chunk, chunks);
} else {
file.status = plupload.DONE;
up.trigger('FileUploaded', file, {
response : res.value.body,
status : httpStatus
});
// Is error status
if (httpStatus >= 400) {
up.trigger('Error', {
code : plupload.HTTP_ERROR,
message : plupload.translate('HTTP Error.'),
file : file,
status : httpStatus
});
}
}
} else {
up.trigger('Error', {
code : plupload.GENERIC_ERROR,
message : plupload.translate('Generic Error.'),
file : file,
details : res.error
});
}
});
}
function chunkAndUploadFile(native_file) {
file.size = native_file.size;
if (chunkSize) {
browserPlus.FileAccess.chunk({file : native_file, chunkSize : chunkSize}, function(cr) {
if (cr.success) {
var chunks = cr.value, len = chunks.length;
loadProgress = Array(len);
for (var i = 0; i < len; i++) {
loadProgress[i] = 0;
chunkStack.push(chunks[i]);
}
uploadFile(0, len);
}
});
} else {
loadProgress = Array(1);
chunkStack.push(native_file);
uploadFile(0, 1);
}
}
// Resize image if it's a supported format and resize is enabled
if (resize && /\.(png|jpg|jpeg)$/i.test(file.name)) {
BrowserPlus.ImageAlter.transform({
file : nativeFile,
quality : resize.quality || 90,
actions : [{
scale : {
maxwidth : resize.width,
maxheight : resize.height
}
}]
}, function(res) {
if (res.success) {
chunkAndUploadFile(res.value.file);
}
});
} else {
chunkAndUploadFile(nativeFile);
}
});
callback({success : true});
}
// Check for browserplus object
if (browserPlus) {
browserPlus.init(function(res) {
var services = [
{service: "Uploader", version: "3"},
{service: "DragAndDrop", version: "1"},
{service: "FileBrowse", version: "1"},
{service: "FileAccess", version: "2"}
];
if (resize) {
services.push({service : 'ImageAlter', version : "4"});
}
if (res.success) {
browserPlus.require({
services : services
}, function(sres) {
if (sres.success) {
setup();
} else {
callback();
}
});
} else {
callback();
}
});
} else {
callback();
}
}
});
})(plupload);