Skip to content

Instantly share code, notes, and snippets.

@andyedinborough
Created March 24, 2011 01:02
Show Gist options
  • Save andyedinborough/884366 to your computer and use it in GitHub Desktop.
Save andyedinborough/884366 to your computer and use it in GitHub Desktop.
//lifted from http://imgscalr.com/public/scripts/main.js
(function (window, document, $, tracky) {
var isEventSupported = (function () {
var TAGNAMES = {
'select': 'input',
'change': 'input',
'submit': 'form',
'reset': 'form',
'error': 'img',
'load': 'img',
'abort': 'img'
};
function isEventSupported(eventName) {
var el = document.createElement(TAGNAMES[eventName] || 'div');
eventName = 'on' + eventName;
var isSupported = (eventName in el);
if (!isSupported) {
el.setAttribute(eventName, 'return;');
isSupported = typeof el[eventName] == 'function';
}
el = null;
return isSupported;
}
return isEventSupported;
})();
var supportsDragDropFileUpload = typeof FileReader != 'undefined' && isEventSupported('dragleave') && isEventSupported('dragover') && isEventSupported('dragenter') && isEventSupported('drop');
tracky.upload = {};
tracky.upload.bind = function (detail) {
if (!supportsDragDropFileUpload) return;
detail.addClass('supports-drag-n-drop').each(function () {
this.addEventListener("dragenter", noopHandler, false);
this.addEventListener("dragleave", onDragLeave, false);
this.addEventListener("dragover", onDragOver, false);
this.addEventListener("drop", onDrop, false);
});
};
function noopHandler(evt) {
evt.stopPropagation();
evt.preventDefault();
}
function onDragOver(evt) {
$(this).addClass('dragover');
noopHandler(evt);
}
function onDragLeave(evt) {
$(this).removeClass('dragover');
}
function onDrop(evt) {
// Consume the event.
noopHandler(evt);
// Hide overlay
var detail = $(this).removeClass('dragover'),
task = detail.closest('.task'),
taskID = task.data('id');
// Get the dropped files.
var files = evt.dataTransfer.files;
// If anything is wrong with the dropped files, exit.
if (typeof files == "undefined" || files.length === 0) {
return;
}
detail.showBusyBar();
// Process each of the dropped files individually
var queuelength = files.length;
function complete() {
queuelength--;
if (queuelength <= 0) {
detail.hideBusyBar();
detail.find('.attachments').remove();
detail.find('.attachment').click();
}
}
for (var i = 0, length = files.length; i < length; i++) {
uploadFile('/task/attachment/drag-n-dropped?taskID=' + taskID, files[i], length, complete);
}
}
function uploadFile(url, file, totalFiles, complete) {
var reader = new FileReader();
// Handle errors that might occur while reading the file (before upload).
reader.onerror = function (evt) {
var message;
// REF: http://www.w3.org/TR/FileAPI/#ErrorDescriptions
switch (evt.target.error.code) {
case 1:
message = file.name + " not found.";
break;
case 2:
message = file.name + " has changed on disk, please re-try.";
break;
case 3:
messsage = "Upload cancelled.";
break;
case 4:
message = "Cannot read " + file.name + ".";
break;
case 5:
message = "File too large for browser to upload.";
break;
}
alertError(evt + ' ' + message);
};
// When the file is done loading, POST to the server.
reader.onloadend = function (evt) {
var data = evt.target.result;
// Make sure the data loaded is long enough to represent a real file.
if (data.length > 128) {
/*
* Per the Data URI spec, the only comma that appears is right after
* 'base64' and before the encoded content.
*/
var base64StartIndex = data.indexOf(',') + 1;
/*
* Make sure the index we've computed is valid, otherwise something
* is wrong and we need to forget this upload.
*/
if (base64StartIndex < data.length) {
$.ajax({
type: 'POST',
url: url,
data: data.substring(base64StartIndex),
// Just send the Base64 content in POST body
processData: false,
// No need to process
timeout: 60000,
// 1 min timeout
dataType: 'text',
// Pure Base64 char data
beforeSend: function onBeforeSend(xhr, settings) {
// Put the important file data in headers
xhr.setRequestHeader('x-file-name', file.name);
xhr.setRequestHeader('x-file-size', file.size);
xhr.setRequestHeader('x-file-type', file.type);
// Update status
//console.log('Uploading ' + file.name);
},
error: function onError(XMLHttpRequest, textStatus, errorThrown) {
//console.log(textStatus, errorThrown);
if (complete) complete.apply(XMLHttpRequest);
},
success: function onUploadComplete(response) {
//console.log(response);
if (complete) complete.apply(XMLHttpRequest);
}
});
}
}
};
// Start reading the image off disk into a Data URI format.
reader.readAsDataURL(file);
}
})(window, document, jQuery, tracky);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment