Merge pull request #83 from nextcloud/file-drop-highlight
File drop highlight
This commit is contained in:
commit
d9be370b86
|
@ -68,9 +68,23 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.app-files #app-content {
|
.app-files #app-content {
|
||||||
|
transition: background-color 0.3s ease;
|
||||||
overflow-x: hidden;
|
overflow-x: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.file-drag, .file-drag #filestable tbody tr, .file-drag #filestable tbody tr:hover {
|
||||||
|
transition: background-color 0.3s ease!important;
|
||||||
|
background-color: rgb(179, 230, 255)!important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.app-files #app-content.dir-drop, .file-drag #filestable tbody tr, .file-drag #filestable tbody tr:hover{
|
||||||
|
background-color: rgba(0, 0, 0, 0)!important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.app-files #app-content.dir-drop #filestable tbody tr.dropping-to-dir{
|
||||||
|
background-color: rgb(179, 230, 255)!important;
|
||||||
|
}
|
||||||
|
|
||||||
/* icons for sidebar */
|
/* icons for sidebar */
|
||||||
.nav-icon-files {
|
.nav-icon-files {
|
||||||
background-image: url('../img/folder.svg');
|
background-image: url('../img/folder.svg');
|
||||||
|
@ -113,6 +127,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
#filestable tbody tr {
|
#filestable tbody tr {
|
||||||
|
transition: background-color 0.3s ease;
|
||||||
background-color: #fff;
|
background-color: #fff;
|
||||||
height: 40px;
|
height: 40px;
|
||||||
}
|
}
|
||||||
|
@ -125,6 +140,7 @@
|
||||||
#filestable tbody tr.selected,
|
#filestable tbody tr.selected,
|
||||||
#filestable tbody tr.searchresult,
|
#filestable tbody tr.searchresult,
|
||||||
table tr.mouseOver td {
|
table tr.mouseOver td {
|
||||||
|
transition: background-color 0.3s ease;
|
||||||
background-color: #f8f8f8;
|
background-color: #f8f8f8;
|
||||||
}
|
}
|
||||||
tbody a { color:#000; }
|
tbody a { color:#000; }
|
||||||
|
|
|
@ -1,5 +1,9 @@
|
||||||
@media only screen and (max-width: 768px) {
|
@media only screen and (max-width: 768px) {
|
||||||
|
|
||||||
|
.app-files #app-content.dir-drop{
|
||||||
|
background-color: rgba(255, 255, 255, 1)!important;
|
||||||
|
}
|
||||||
|
|
||||||
/* don’t require a minimum width for files table */
|
/* don’t require a minimum width for files table */
|
||||||
#body-user #filestable {
|
#body-user #filestable {
|
||||||
min-width: initial !important;
|
min-width: initial !important;
|
||||||
|
|
|
@ -273,7 +273,7 @@ OC.Upload = {
|
||||||
var self = this;
|
var self = this;
|
||||||
if ( $('#file_upload_start').exists() ) {
|
if ( $('#file_upload_start').exists() ) {
|
||||||
var file_upload_param = {
|
var file_upload_param = {
|
||||||
dropZone: $('#content'), // restrict dropZone to content div
|
dropZone: $('#app-content'), // restrict dropZone to app-content div
|
||||||
pasteZone: null,
|
pasteZone: null,
|
||||||
autoUpload: false,
|
autoUpload: false,
|
||||||
sequentialUploads: true,
|
sequentialUploads: true,
|
||||||
|
@ -494,7 +494,7 @@ OC.Upload = {
|
||||||
* @param {object} e
|
* @param {object} e
|
||||||
* @param {object} data
|
* @param {object} data
|
||||||
*/
|
*/
|
||||||
done:function(e, data) {
|
done: function(e, data) {
|
||||||
OC.Upload.log('done', e, data);
|
OC.Upload.log('done', e, data);
|
||||||
// handle different responses (json or body from iframe for ie)
|
// handle different responses (json or body from iframe for ie)
|
||||||
var response;
|
var response;
|
||||||
|
@ -667,7 +667,29 @@ OC.Upload = {
|
||||||
OC.Upload._hideProgressBar();
|
OC.Upload._hideProgressBar();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
fileupload.on('fileuploaddragover', function(e){
|
||||||
|
$('#app-content').addClass('file-drag');
|
||||||
|
|
||||||
|
var filerow = $(e.delegatedEvent.target).closest('tr');
|
||||||
|
|
||||||
|
if(!filerow.hasClass('dropping-to-dir')){
|
||||||
|
$('.dropping-to-dir').removeClass('dropping-to-dir');
|
||||||
|
$('.dir-drop').removeClass('dir-drop');
|
||||||
|
$('.icon-filetype-folder-drag-accept').removeClass('icon-filetype-folder-drag-accept');
|
||||||
|
}
|
||||||
|
|
||||||
|
if(filerow.attr('data-type') === 'dir'){
|
||||||
|
$('#app-content').addClass('dir-drop');
|
||||||
|
filerow.addClass('dropping-to-dir');
|
||||||
|
filerow.find('.thumbnail').addClass('icon-filetype-folder-drag-accept');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
fileupload.on('fileuploaddragleave fileuploaddrop', function (){
|
||||||
|
$('#app-content').removeClass('file-drag');
|
||||||
|
$('.dropping-to-dir').removeClass('dropping-to-dir');
|
||||||
|
$('.dir-drop').removeClass('dir-drop');
|
||||||
|
$('.icon-filetype-folder-drag-accept').removeClass('icon-filetype-folder-drag-accept');
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
// for all browsers that don't support the progress bar
|
// for all browsers that don't support the progress bar
|
||||||
// IE 8 & 9
|
// IE 8 & 9
|
||||||
|
|
|
@ -2514,12 +2514,13 @@
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
// handle upload events
|
// handle upload events
|
||||||
var fileUploadStart = this.$el.find('#file_upload_start');
|
var fileUploadStart = this.$el;
|
||||||
|
var delegatedElement = '#file_upload_start';
|
||||||
|
|
||||||
// detect the progress bar resize
|
// detect the progress bar resize
|
||||||
fileUploadStart.on('resized', this._onResize);
|
fileUploadStart.on('resized', this._onResize);
|
||||||
|
|
||||||
fileUploadStart.on('fileuploaddrop', function(e, data) {
|
fileUploadStart.on('fileuploaddrop', delegatedElement, function(e, data) {
|
||||||
OC.Upload.log('filelist handle fileuploaddrop', e, data);
|
OC.Upload.log('filelist handle fileuploaddrop', e, data);
|
||||||
|
|
||||||
if (self.$el.hasClass('hidden')) {
|
if (self.$el.hasClass('hidden')) {
|
||||||
|
@ -2527,7 +2528,8 @@
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
var dropTarget = $(e.originalEvent.target);
|
var dropTarget = $(e.delegatedEvent.target);
|
||||||
|
|
||||||
// check if dropped inside this container and not another one
|
// check if dropped inside this container and not another one
|
||||||
if (dropTarget.length
|
if (dropTarget.length
|
||||||
&& !self.$el.is(dropTarget) // dropped on list directly
|
&& !self.$el.is(dropTarget) // dropped on list directly
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* jQuery File Upload Plugin 5.32.2
|
* jQuery File Upload Plugin 9.12.5
|
||||||
* https://github.com/blueimp/jQuery-File-Upload
|
* https://github.com/blueimp/jQuery-File-Upload
|
||||||
*
|
*
|
||||||
* Copyright 2010, Sebastian Tschan
|
* Copyright 2010, Sebastian Tschan
|
||||||
|
@ -9,10 +9,10 @@
|
||||||
* http://www.opensource.org/licenses/MIT
|
* http://www.opensource.org/licenses/MIT
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*jslint nomen: true, unparam: true, regexp: true */
|
/* jshint nomen:false */
|
||||||
/*global define, window, document, location, File, Blob, FormData */
|
/* global define, require, window, document, location, Blob, FormData */
|
||||||
|
|
||||||
(function (factory) {
|
;(function (factory) {
|
||||||
'use strict';
|
'use strict';
|
||||||
if (typeof define === 'function' && define.amd) {
|
if (typeof define === 'function' && define.amd) {
|
||||||
// Register as an anonymous AMD module:
|
// Register as an anonymous AMD module:
|
||||||
|
@ -20,6 +20,12 @@
|
||||||
'jquery',
|
'jquery',
|
||||||
'jquery.ui.widget'
|
'jquery.ui.widget'
|
||||||
], factory);
|
], factory);
|
||||||
|
} else if (typeof exports === 'object') {
|
||||||
|
// Node/CommonJS:
|
||||||
|
factory(
|
||||||
|
require('jquery'),
|
||||||
|
require('./vendor/jquery.ui.widget')
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
// Browser globals:
|
// Browser globals:
|
||||||
factory(window.jQuery);
|
factory(window.jQuery);
|
||||||
|
@ -40,15 +46,36 @@
|
||||||
$('<input type="file">').prop('disabled'));
|
$('<input type="file">').prop('disabled'));
|
||||||
|
|
||||||
// The FileReader API is not actually used, but works as feature detection,
|
// The FileReader API is not actually used, but works as feature detection,
|
||||||
// as e.g. Safari supports XHR file uploads via the FormData API,
|
// as some Safari versions (5?) support XHR file uploads via the FormData API,
|
||||||
// but not non-multipart XHR file uploads:
|
// but not non-multipart XHR file uploads.
|
||||||
$.support.xhrFileUpload = !!(window.XMLHttpRequestUpload && window.FileReader);
|
// window.XMLHttpRequestUpload is not available on IE10, so we check for
|
||||||
|
// window.ProgressEvent instead to detect XHR2 file upload capability:
|
||||||
|
$.support.xhrFileUpload = !!(window.ProgressEvent && window.FileReader);
|
||||||
$.support.xhrFormDataFileUpload = !!window.FormData;
|
$.support.xhrFormDataFileUpload = !!window.FormData;
|
||||||
|
|
||||||
// Detect support for Blob slicing (required for chunked uploads):
|
// Detect support for Blob slicing (required for chunked uploads):
|
||||||
$.support.blobSlice = window.Blob && (Blob.prototype.slice ||
|
$.support.blobSlice = window.Blob && (Blob.prototype.slice ||
|
||||||
Blob.prototype.webkitSlice || Blob.prototype.mozSlice);
|
Blob.prototype.webkitSlice || Blob.prototype.mozSlice);
|
||||||
|
|
||||||
|
// Helper function to create drag handlers for dragover/dragenter/dragleave:
|
||||||
|
function getDragHandler(type) {
|
||||||
|
var isDragOver = type === 'dragover';
|
||||||
|
return function (e) {
|
||||||
|
e.dataTransfer = e.originalEvent && e.originalEvent.dataTransfer;
|
||||||
|
var dataTransfer = e.dataTransfer;
|
||||||
|
if (dataTransfer && $.inArray('Files', dataTransfer.types) !== -1 &&
|
||||||
|
this._trigger(
|
||||||
|
type,
|
||||||
|
$.Event(type, {delegatedEvent: e})
|
||||||
|
) !== false) {
|
||||||
|
e.preventDefault();
|
||||||
|
if (isDragOver) {
|
||||||
|
dataTransfer.dropEffect = 'copy';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
// The fileupload widget listens for change events on file input fields defined
|
// The fileupload widget listens for change events on file input fields defined
|
||||||
// via fileInput setting and paste or drop events of the given dropZone.
|
// via fileInput setting and paste or drop events of the given dropZone.
|
||||||
// In addition to the default jQuery Widget methods, the fileupload widget
|
// In addition to the default jQuery Widget methods, the fileupload widget
|
||||||
|
@ -63,9 +90,9 @@
|
||||||
// The drop target element(s), by the default the complete document.
|
// The drop target element(s), by the default the complete document.
|
||||||
// Set to null to disable drag & drop support:
|
// Set to null to disable drag & drop support:
|
||||||
dropZone: $(document),
|
dropZone: $(document),
|
||||||
// The paste target element(s), by the default the complete document.
|
// The paste target element(s), by the default undefined.
|
||||||
// Set to null to disable paste support:
|
// Set to a DOM node or jQuery object to enable file pasting:
|
||||||
pasteZone: $(document),
|
pasteZone: undefined,
|
||||||
// The file input field(s), that are listened to for change events.
|
// The file input field(s), that are listened to for change events.
|
||||||
// If undefined, it is set to the file input fields inside
|
// If undefined, it is set to the file input fields inside
|
||||||
// of the widget element on plugin initialization.
|
// of the widget element on plugin initialization.
|
||||||
|
@ -88,6 +115,14 @@
|
||||||
// To limit the number of files uploaded with one XHR request,
|
// To limit the number of files uploaded with one XHR request,
|
||||||
// set the following option to an integer greater than 0:
|
// set the following option to an integer greater than 0:
|
||||||
limitMultiFileUploads: undefined,
|
limitMultiFileUploads: undefined,
|
||||||
|
// The following option limits the number of files uploaded with one
|
||||||
|
// XHR request to keep the request size under or equal to the defined
|
||||||
|
// limit in bytes:
|
||||||
|
limitMultiFileUploadSize: undefined,
|
||||||
|
// Multipart file uploads add a number of bytes to each uploaded file,
|
||||||
|
// therefore the following option adds an overhead for each file used
|
||||||
|
// in the limitMultiFileUploadSize configuration:
|
||||||
|
limitMultiFileUploadSizeOverhead: 512,
|
||||||
// Set the following option to true to issue all file upload requests
|
// Set the following option to true to issue all file upload requests
|
||||||
// in a sequential order:
|
// in a sequential order:
|
||||||
sequentialUploads: false,
|
sequentialUploads: false,
|
||||||
|
@ -174,6 +209,9 @@
|
||||||
// handlers using jQuery's Deferred callbacks:
|
// handlers using jQuery's Deferred callbacks:
|
||||||
// data.submit().done(func).fail(func).always(func);
|
// data.submit().done(func).fail(func).always(func);
|
||||||
add: function (e, data) {
|
add: function (e, data) {
|
||||||
|
if (e.isDefaultPrevented()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
if (data.autoUpload || (data.autoUpload !== false &&
|
if (data.autoUpload || (data.autoUpload !== false &&
|
||||||
$(this).fileupload('option', 'autoUpload'))) {
|
$(this).fileupload('option', 'autoUpload'))) {
|
||||||
data.process().done(function () {
|
data.process().done(function () {
|
||||||
|
@ -239,7 +277,8 @@
|
||||||
// The following are jQuery ajax settings required for the file uploads:
|
// The following are jQuery ajax settings required for the file uploads:
|
||||||
processData: false,
|
processData: false,
|
||||||
contentType: false,
|
contentType: false,
|
||||||
cache: false
|
cache: false,
|
||||||
|
timeout: 0
|
||||||
},
|
},
|
||||||
|
|
||||||
// A list of options that require reinitializing event listeners and/or
|
// A list of options that require reinitializing event listeners and/or
|
||||||
|
@ -280,7 +319,7 @@
|
||||||
|
|
||||||
_getFormData: function (options) {
|
_getFormData: function (options) {
|
||||||
var formData;
|
var formData;
|
||||||
if (typeof options.formData === 'function') {
|
if ($.type(options.formData) === 'function') {
|
||||||
return options.formData(options.form);
|
return options.formData(options.form);
|
||||||
}
|
}
|
||||||
if ($.isArray(options.formData)) {
|
if ($.isArray(options.formData)) {
|
||||||
|
@ -360,10 +399,18 @@
|
||||||
// Trigger a custom progress event with a total data property set
|
// Trigger a custom progress event with a total data property set
|
||||||
// to the file size(s) of the current upload and a loaded data
|
// to the file size(s) of the current upload and a loaded data
|
||||||
// property calculated accordingly:
|
// property calculated accordingly:
|
||||||
this._trigger('progress', e, data);
|
this._trigger(
|
||||||
|
'progress',
|
||||||
|
$.Event('progress', {delegatedEvent: e}),
|
||||||
|
data
|
||||||
|
);
|
||||||
// Trigger a global progress event for all current file uploads,
|
// Trigger a global progress event for all current file uploads,
|
||||||
// including ajax calls queued for sequential file uploads:
|
// including ajax calls queued for sequential file uploads:
|
||||||
this._trigger('progressall', e, this._progress);
|
this._trigger(
|
||||||
|
'progressall',
|
||||||
|
$.Event('progressall', {delegatedEvent: e}),
|
||||||
|
this._progress
|
||||||
|
);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -398,8 +445,9 @@
|
||||||
file = options.files[0],
|
file = options.files[0],
|
||||||
// Ignore non-multipart setting if not supported:
|
// Ignore non-multipart setting if not supported:
|
||||||
multipart = options.multipart || !$.support.xhrFileUpload,
|
multipart = options.multipart || !$.support.xhrFileUpload,
|
||||||
paramName = options.paramName[0];
|
paramName = $.type(options.paramName) === 'array' ?
|
||||||
options.headers = options.headers || {};
|
options.paramName[0] : options.paramName;
|
||||||
|
options.headers = $.extend({}, options.headers);
|
||||||
if (options.contentRange) {
|
if (options.contentRange) {
|
||||||
options.headers['Content-Range'] = options.contentRange;
|
options.headers['Content-Range'] = options.contentRange;
|
||||||
}
|
}
|
||||||
|
@ -408,7 +456,7 @@
|
||||||
encodeURI(file.name) + '"';
|
encodeURI(file.name) + '"';
|
||||||
}
|
}
|
||||||
if (!multipart) {
|
if (!multipart) {
|
||||||
options.contentType = file.type;
|
options.contentType = file.type || 'application/octet-stream';
|
||||||
options.data = options.blob || file;
|
options.data = options.blob || file;
|
||||||
} else if ($.support.xhrFormDataFileUpload) {
|
} else if ($.support.xhrFormDataFileUpload) {
|
||||||
if (options.postMessage) {
|
if (options.postMessage) {
|
||||||
|
@ -425,7 +473,8 @@
|
||||||
} else {
|
} else {
|
||||||
$.each(options.files, function (index, file) {
|
$.each(options.files, function (index, file) {
|
||||||
formData.push({
|
formData.push({
|
||||||
name: options.paramName[index] || paramName,
|
name: ($.type(options.paramName) === 'array' &&
|
||||||
|
options.paramName[index]) || paramName,
|
||||||
value: file
|
value: file
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -448,9 +497,10 @@
|
||||||
if (that._isInstanceOf('File', file) ||
|
if (that._isInstanceOf('File', file) ||
|
||||||
that._isInstanceOf('Blob', file)) {
|
that._isInstanceOf('Blob', file)) {
|
||||||
formData.append(
|
formData.append(
|
||||||
options.paramName[index] || paramName,
|
($.type(options.paramName) === 'array' &&
|
||||||
|
options.paramName[index]) || paramName,
|
||||||
file,
|
file,
|
||||||
file.name
|
file.uploadName || file.name
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -534,8 +584,10 @@
|
||||||
options.url = options.form.prop('action') || location.href;
|
options.url = options.form.prop('action') || location.href;
|
||||||
}
|
}
|
||||||
// The HTTP request method must be "POST" or "PUT":
|
// The HTTP request method must be "POST" or "PUT":
|
||||||
options.type = (options.type || options.form.prop('method') || '')
|
options.type = (options.type ||
|
||||||
.toUpperCase();
|
($.type(options.form.prop('method')) === 'string' &&
|
||||||
|
options.form.prop('method')) || ''
|
||||||
|
).toUpperCase();
|
||||||
if (options.type !== 'POST' && options.type !== 'PUT' &&
|
if (options.type !== 'POST' && options.type !== 'PUT' &&
|
||||||
options.type !== 'PATCH') {
|
options.type !== 'PATCH') {
|
||||||
options.type = 'POST';
|
options.type = 'POST';
|
||||||
|
@ -594,22 +646,32 @@
|
||||||
// Adds convenience methods to the data callback argument:
|
// Adds convenience methods to the data callback argument:
|
||||||
_addConvenienceMethods: function (e, data) {
|
_addConvenienceMethods: function (e, data) {
|
||||||
var that = this,
|
var that = this,
|
||||||
getPromise = function (data) {
|
getPromise = function (args) {
|
||||||
return $.Deferred().resolveWith(that, [data]).promise();
|
return $.Deferred().resolveWith(that, args).promise();
|
||||||
};
|
};
|
||||||
data.process = function (resolveFunc, rejectFunc) {
|
data.process = function (resolveFunc, rejectFunc) {
|
||||||
if (resolveFunc || rejectFunc) {
|
if (resolveFunc || rejectFunc) {
|
||||||
data._processQueue = this._processQueue =
|
data._processQueue = this._processQueue =
|
||||||
(this._processQueue || getPromise(this))
|
(this._processQueue || getPromise([this])).then(
|
||||||
.pipe(resolveFunc, rejectFunc);
|
function () {
|
||||||
|
if (data.errorThrown) {
|
||||||
|
return $.Deferred()
|
||||||
|
.rejectWith(that, [data]).promise();
|
||||||
|
}
|
||||||
|
return getPromise(arguments);
|
||||||
|
}
|
||||||
|
).then(resolveFunc, rejectFunc);
|
||||||
}
|
}
|
||||||
return this._processQueue || getPromise(this);
|
return this._processQueue || getPromise([this]);
|
||||||
};
|
};
|
||||||
data.submit = function () {
|
data.submit = function () {
|
||||||
if (this.state() !== 'pending') {
|
if (this.state() !== 'pending') {
|
||||||
data.jqXHR = this.jqXHR =
|
data.jqXHR = this.jqXHR =
|
||||||
(that._trigger('submit', e, this) !== false) &&
|
(that._trigger(
|
||||||
that._onSend(e, this);
|
'submit',
|
||||||
|
$.Event('submit', {delegatedEvent: e}),
|
||||||
|
this
|
||||||
|
) !== false) && that._onSend(e, this);
|
||||||
}
|
}
|
||||||
return this.jqXHR || that._getXHRPromise();
|
return this.jqXHR || that._getXHRPromise();
|
||||||
};
|
};
|
||||||
|
@ -617,7 +679,9 @@
|
||||||
if (this.jqXHR) {
|
if (this.jqXHR) {
|
||||||
return this.jqXHR.abort();
|
return this.jqXHR.abort();
|
||||||
}
|
}
|
||||||
return that._getXHRPromise();
|
this.errorThrown = 'abort';
|
||||||
|
that._trigger('fail', null, this);
|
||||||
|
return that._getXHRPromise(false);
|
||||||
};
|
};
|
||||||
data.state = function () {
|
data.state = function () {
|
||||||
if (this.jqXHR) {
|
if (this.jqXHR) {
|
||||||
|
@ -627,6 +691,10 @@
|
||||||
return that._getDeferredState(this._processQueue);
|
return that._getDeferredState(this._processQueue);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
data.processing = function () {
|
||||||
|
return !this.jqXHR && this._processQueue && that
|
||||||
|
._getDeferredState(this._processQueue) === 'pending';
|
||||||
|
};
|
||||||
data.progress = function () {
|
data.progress = function () {
|
||||||
return this._progress;
|
return this._progress;
|
||||||
};
|
};
|
||||||
|
@ -829,7 +897,11 @@
|
||||||
// Set timer for bitrate progress calculation:
|
// Set timer for bitrate progress calculation:
|
||||||
options._bitrateTimer = new that._BitrateTimer();
|
options._bitrateTimer = new that._BitrateTimer();
|
||||||
jqXHR = jqXHR || (
|
jqXHR = jqXHR || (
|
||||||
((aborted || that._trigger('send', e, options) === false) &&
|
((aborted || that._trigger(
|
||||||
|
'send',
|
||||||
|
$.Event('send', {delegatedEvent: e}),
|
||||||
|
options
|
||||||
|
) === false) &&
|
||||||
that._getXHRPromise(false, options.context, aborted)) ||
|
that._getXHRPromise(false, options.context, aborted)) ||
|
||||||
that._chunkedUpload(options) || $.ajax(options)
|
that._chunkedUpload(options) || $.ajax(options)
|
||||||
).done(function (result, textStatus, jqXHR) {
|
).done(function (result, textStatus, jqXHR) {
|
||||||
|
@ -873,9 +945,9 @@
|
||||||
if (this.options.limitConcurrentUploads > 1) {
|
if (this.options.limitConcurrentUploads > 1) {
|
||||||
slot = $.Deferred();
|
slot = $.Deferred();
|
||||||
this._slots.push(slot);
|
this._slots.push(slot);
|
||||||
pipe = slot.pipe(send);
|
pipe = slot.then(send);
|
||||||
} else {
|
} else {
|
||||||
this._sequence = this._sequence.pipe(send, send);
|
this._sequence = this._sequence.then(send, send);
|
||||||
pipe = this._sequence;
|
pipe = this._sequence;
|
||||||
}
|
}
|
||||||
// Return the piped Promise object, enhanced with an abort method,
|
// Return the piped Promise object, enhanced with an abort method,
|
||||||
|
@ -900,50 +972,93 @@
|
||||||
var that = this,
|
var that = this,
|
||||||
result = true,
|
result = true,
|
||||||
options = $.extend({}, this.options, data),
|
options = $.extend({}, this.options, data),
|
||||||
|
files = data.files,
|
||||||
|
filesLength = files.length,
|
||||||
limit = options.limitMultiFileUploads,
|
limit = options.limitMultiFileUploads,
|
||||||
|
limitSize = options.limitMultiFileUploadSize,
|
||||||
|
overhead = options.limitMultiFileUploadSizeOverhead,
|
||||||
|
batchSize = 0,
|
||||||
paramName = this._getParamName(options),
|
paramName = this._getParamName(options),
|
||||||
paramNameSet,
|
paramNameSet,
|
||||||
paramNameSlice,
|
paramNameSlice,
|
||||||
fileSet,
|
fileSet,
|
||||||
i;
|
i,
|
||||||
if (!(options.singleFileUploads || limit) ||
|
j = 0;
|
||||||
|
if (!filesLength) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (limitSize && files[0].size === undefined) {
|
||||||
|
limitSize = undefined;
|
||||||
|
}
|
||||||
|
if (!(options.singleFileUploads || limit || limitSize) ||
|
||||||
!this._isXHRUpload(options)) {
|
!this._isXHRUpload(options)) {
|
||||||
fileSet = [data.files];
|
fileSet = [files];
|
||||||
paramNameSet = [paramName];
|
paramNameSet = [paramName];
|
||||||
} else if (!options.singleFileUploads && limit) {
|
} else if (!(options.singleFileUploads || limitSize) && limit) {
|
||||||
fileSet = [];
|
fileSet = [];
|
||||||
paramNameSet = [];
|
paramNameSet = [];
|
||||||
for (i = 0; i < data.files.length; i += limit) {
|
for (i = 0; i < filesLength; i += limit) {
|
||||||
fileSet.push(data.files.slice(i, i + limit));
|
fileSet.push(files.slice(i, i + limit));
|
||||||
paramNameSlice = paramName.slice(i, i + limit);
|
paramNameSlice = paramName.slice(i, i + limit);
|
||||||
if (!paramNameSlice.length) {
|
if (!paramNameSlice.length) {
|
||||||
paramNameSlice = paramName;
|
paramNameSlice = paramName;
|
||||||
}
|
}
|
||||||
paramNameSet.push(paramNameSlice);
|
paramNameSet.push(paramNameSlice);
|
||||||
}
|
}
|
||||||
|
} else if (!options.singleFileUploads && limitSize) {
|
||||||
|
fileSet = [];
|
||||||
|
paramNameSet = [];
|
||||||
|
for (i = 0; i < filesLength; i = i + 1) {
|
||||||
|
batchSize += files[i].size + overhead;
|
||||||
|
if (i + 1 === filesLength ||
|
||||||
|
((batchSize + files[i + 1].size + overhead) > limitSize) ||
|
||||||
|
(limit && i + 1 - j >= limit)) {
|
||||||
|
fileSet.push(files.slice(j, i + 1));
|
||||||
|
paramNameSlice = paramName.slice(j, i + 1);
|
||||||
|
if (!paramNameSlice.length) {
|
||||||
|
paramNameSlice = paramName;
|
||||||
|
}
|
||||||
|
paramNameSet.push(paramNameSlice);
|
||||||
|
j = i + 1;
|
||||||
|
batchSize = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
paramNameSet = paramName;
|
paramNameSet = paramName;
|
||||||
}
|
}
|
||||||
data.originalFiles = data.files;
|
data.originalFiles = files;
|
||||||
$.each(fileSet || data.files, function (index, element) {
|
$.each(fileSet || files, function (index, element) {
|
||||||
var newData = $.extend({}, data);
|
var newData = $.extend({}, data);
|
||||||
newData.files = fileSet ? element : [element];
|
newData.files = fileSet ? element : [element];
|
||||||
newData.paramName = paramNameSet[index];
|
newData.paramName = paramNameSet[index];
|
||||||
that._initResponseObject(newData);
|
that._initResponseObject(newData);
|
||||||
that._initProgressObject(newData);
|
that._initProgressObject(newData);
|
||||||
that._addConvenienceMethods(e, newData);
|
that._addConvenienceMethods(e, newData);
|
||||||
result = that._trigger('add', e, newData);
|
result = that._trigger(
|
||||||
|
'add',
|
||||||
|
$.Event('add', {delegatedEvent: e}),
|
||||||
|
newData
|
||||||
|
);
|
||||||
return result;
|
return result;
|
||||||
});
|
});
|
||||||
return result;
|
return result;
|
||||||
},
|
},
|
||||||
|
|
||||||
_replaceFileInput: function (input) {
|
_replaceFileInput: function (data) {
|
||||||
var inputClone = input.clone(true);
|
var input = data.fileInput,
|
||||||
|
inputClone = input.clone(true),
|
||||||
|
restoreFocus = input.is(document.activeElement);
|
||||||
|
// Add a reference for the new cloned file input to the data argument:
|
||||||
|
data.fileInputClone = inputClone;
|
||||||
$('<form></form>').append(inputClone)[0].reset();
|
$('<form></form>').append(inputClone)[0].reset();
|
||||||
// Detaching allows to insert the fileInput on another form
|
// Detaching allows to insert the fileInput on another form
|
||||||
// without losing the file input value:
|
// without loosing the file input value:
|
||||||
input.after(inputClone).detach();
|
input.after(inputClone).detach();
|
||||||
|
// If the fileInput had focus before it was detached,
|
||||||
|
// restore focus to the inputClone.
|
||||||
|
if (restoreFocus) {
|
||||||
|
inputClone.focus();
|
||||||
|
}
|
||||||
// Avoid memory leaks with the detached file input:
|
// Avoid memory leaks with the detached file input:
|
||||||
$.cleanData(input.unbind('remove'));
|
$.cleanData(input.unbind('remove'));
|
||||||
// Replace the original file input element in the fileInput
|
// Replace the original file input element in the fileInput
|
||||||
|
@ -975,7 +1090,25 @@
|
||||||
// to be returned together in one set:
|
// to be returned together in one set:
|
||||||
dfd.resolve([e]);
|
dfd.resolve([e]);
|
||||||
},
|
},
|
||||||
dirReader;
|
successHandler = function (entries) {
|
||||||
|
that._handleFileTreeEntries(
|
||||||
|
entries,
|
||||||
|
path + entry.name + '/'
|
||||||
|
).done(function (files) {
|
||||||
|
dfd.resolve(files);
|
||||||
|
}).fail(errorHandler);
|
||||||
|
},
|
||||||
|
readEntries = function () {
|
||||||
|
dirReader.readEntries(function (results) {
|
||||||
|
if (!results.length) {
|
||||||
|
successHandler(entries);
|
||||||
|
} else {
|
||||||
|
entries = entries.concat(results);
|
||||||
|
readEntries();
|
||||||
|
}
|
||||||
|
}, errorHandler);
|
||||||
|
},
|
||||||
|
dirReader, entries = [];
|
||||||
path = path || '';
|
path = path || '';
|
||||||
if (entry.isFile) {
|
if (entry.isFile) {
|
||||||
if (entry._file) {
|
if (entry._file) {
|
||||||
|
@ -990,14 +1123,7 @@
|
||||||
}
|
}
|
||||||
} else if (entry.isDirectory) {
|
} else if (entry.isDirectory) {
|
||||||
dirReader = entry.createReader();
|
dirReader = entry.createReader();
|
||||||
dirReader.readEntries(function (entries) {
|
readEntries();
|
||||||
that._handleFileTreeEntries(
|
|
||||||
entries,
|
|
||||||
path + entry.name + '/'
|
|
||||||
).done(function (files) {
|
|
||||||
dfd.resolve(files);
|
|
||||||
}).fail(errorHandler);
|
|
||||||
}, errorHandler);
|
|
||||||
} else {
|
} else {
|
||||||
// Return an empy list for file system items
|
// Return an empy list for file system items
|
||||||
// other than files or directories:
|
// other than files or directories:
|
||||||
|
@ -1013,7 +1139,7 @@
|
||||||
$.map(entries, function (entry) {
|
$.map(entries, function (entry) {
|
||||||
return that._handleFileTreeEntry(entry, path);
|
return that._handleFileTreeEntry(entry, path);
|
||||||
})
|
})
|
||||||
).pipe(function () {
|
).then(function () {
|
||||||
return Array.prototype.concat.apply(
|
return Array.prototype.concat.apply(
|
||||||
[],
|
[],
|
||||||
arguments
|
arguments
|
||||||
|
@ -1082,7 +1208,7 @@
|
||||||
return $.when.apply(
|
return $.when.apply(
|
||||||
$,
|
$,
|
||||||
$.map(fileInput, this._getSingleFileInputFiles)
|
$.map(fileInput, this._getSingleFileInputFiles)
|
||||||
).pipe(function () {
|
).then(function () {
|
||||||
return Array.prototype.concat.apply(
|
return Array.prototype.concat.apply(
|
||||||
[],
|
[],
|
||||||
arguments
|
arguments
|
||||||
|
@ -1099,9 +1225,13 @@
|
||||||
this._getFileInputFiles(data.fileInput).always(function (files) {
|
this._getFileInputFiles(data.fileInput).always(function (files) {
|
||||||
data.files = files;
|
data.files = files;
|
||||||
if (that.options.replaceFileInput) {
|
if (that.options.replaceFileInput) {
|
||||||
that._replaceFileInput(data.fileInput);
|
that._replaceFileInput(data);
|
||||||
}
|
}
|
||||||
if (that._trigger('change', e, data) !== false) {
|
if (that._trigger(
|
||||||
|
'change',
|
||||||
|
$.Event('change', {delegatedEvent: e}),
|
||||||
|
data
|
||||||
|
) !== false) {
|
||||||
that._onAdd(e, data);
|
that._onAdd(e, data);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -1118,9 +1248,12 @@
|
||||||
data.files.push(file);
|
data.files.push(file);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
if (this._trigger('paste', e, data) === false ||
|
if (this._trigger(
|
||||||
this._onAdd(e, data) === false) {
|
'paste',
|
||||||
return false;
|
$.Event('paste', {delegatedEvent: e}),
|
||||||
|
data
|
||||||
|
) !== false) {
|
||||||
|
this._onAdd(e, data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -1134,32 +1267,32 @@
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
this._getDroppedFiles(dataTransfer).always(function (files) {
|
this._getDroppedFiles(dataTransfer).always(function (files) {
|
||||||
data.files = files;
|
data.files = files;
|
||||||
if (that._trigger('drop', e, data) !== false) {
|
if (that._trigger(
|
||||||
|
'drop',
|
||||||
|
$.Event('drop', {delegatedEvent: e}),
|
||||||
|
data
|
||||||
|
) !== false) {
|
||||||
that._onAdd(e, data);
|
that._onAdd(e, data);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
_onDragOver: function (e) {
|
_onDragOver: getDragHandler('dragover'),
|
||||||
e.dataTransfer = e.originalEvent && e.originalEvent.dataTransfer;
|
|
||||||
var dataTransfer = e.dataTransfer;
|
_onDragEnter: getDragHandler('dragenter'),
|
||||||
if (dataTransfer) {
|
|
||||||
if (this._trigger('dragover', e) === false) {
|
_onDragLeave: getDragHandler('dragleave'),
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if ($.inArray('Files', dataTransfer.types) !== -1) {
|
|
||||||
dataTransfer.dropEffect = 'copy';
|
|
||||||
e.preventDefault();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
_initEventHandlers: function () {
|
_initEventHandlers: function () {
|
||||||
if (this._isXHRUpload(this.options)) {
|
if (this._isXHRUpload(this.options)) {
|
||||||
this._on(this.options.dropZone, {
|
this._on(this.options.dropZone, {
|
||||||
dragover: this._onDragOver,
|
dragover: this._onDragOver,
|
||||||
drop: this._onDrop
|
drop: this._onDrop,
|
||||||
|
// event.preventDefault() on dragenter is required for IE10+:
|
||||||
|
dragenter: this._onDragEnter,
|
||||||
|
// dragleave is not required, but added for completeness:
|
||||||
|
dragleave: this._onDragLeave
|
||||||
});
|
});
|
||||||
this._on(this.options.pasteZone, {
|
this._on(this.options.pasteZone, {
|
||||||
paste: this._onPaste
|
paste: this._onPaste
|
||||||
|
@ -1173,7 +1306,7 @@
|
||||||
},
|
},
|
||||||
|
|
||||||
_destroyEventHandlers: function () {
|
_destroyEventHandlers: function () {
|
||||||
this._off(this.options.dropZone, 'dragover drop');
|
this._off(this.options.dropZone, 'dragenter dragleave dragover drop');
|
||||||
this._off(this.options.pasteZone, 'paste');
|
this._off(this.options.pasteZone, 'paste');
|
||||||
this._off(this.options.fileInput, 'change');
|
this._off(this.options.fileInput, 'change');
|
||||||
},
|
},
|
||||||
|
@ -1220,15 +1353,25 @@
|
||||||
|
|
||||||
_initDataAttributes: function () {
|
_initDataAttributes: function () {
|
||||||
var that = this,
|
var that = this,
|
||||||
options = this.options;
|
options = this.options,
|
||||||
|
data = this.element.data();
|
||||||
// Initialize options set via HTML5 data-attributes:
|
// Initialize options set via HTML5 data-attributes:
|
||||||
$.each(
|
$.each(
|
||||||
$(this.element[0].cloneNode(false)).data(),
|
this.element[0].attributes,
|
||||||
function (key, value) {
|
function (index, attr) {
|
||||||
if (that._isRegExpOption(key, value)) {
|
var key = attr.name.toLowerCase(),
|
||||||
value = that._getRegExp(value);
|
value;
|
||||||
|
if (/^data-/.test(key)) {
|
||||||
|
// Convert hyphen-ated key to camelCase:
|
||||||
|
key = key.slice(5).replace(/-[a-z]/g, function (str) {
|
||||||
|
return str.charAt(1).toUpperCase();
|
||||||
|
});
|
||||||
|
value = data[key];
|
||||||
|
if (that._isRegExpOption(key, value)) {
|
||||||
|
value = that._getRegExp(value);
|
||||||
|
}
|
||||||
|
options[key] = value;
|
||||||
}
|
}
|
||||||
options[key] = value;
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
@ -1308,7 +1451,8 @@
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
data.files = files;
|
data.files = files;
|
||||||
jqXHR = that._onSend(null, data).then(
|
jqXHR = that._onSend(null, data);
|
||||||
|
jqXHR.then(
|
||||||
function (result, textStatus, jqXHR) {
|
function (result, textStatus, jqXHR) {
|
||||||
dfd.resolve(result, textStatus, jqXHR);
|
dfd.resolve(result, textStatus, jqXHR);
|
||||||
},
|
},
|
||||||
|
|
|
@ -353,6 +353,10 @@ img.icon-loading-small-dark, object.icon-loading-small-dark, video.icon-loading-
|
||||||
background-image: url('../img/filetypes/folder.svg');
|
background-image: url('../img/filetypes/folder.svg');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.icon-filetype-folder-drag-accept {
|
||||||
|
background-image: url('../img/filetypes/folder-drag-accept.svg')!important;
|
||||||
|
}
|
||||||
|
|
||||||
.icon-home {
|
.icon-home {
|
||||||
background-image: url('../img/places/home.svg');
|
background-image: url('../img/places/home.svg');
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue