Skip to content

Commit b9e8a2c

Browse files
committed
Added drop event listener to document node.
Improved handling of multiple File Upload instances, which can even be used with the same namespace setting. Fixed issues where the dropZone was not properly reduced on file(s) drop (e.g. Firefox does not trigger the dragleave event on file drop).
1 parent 491d955 commit b9e8a2c

File tree

2 files changed

+68
-122
lines changed

2 files changed

+68
-122
lines changed

jquery.fileupload-ui.js

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* jQuery File Upload User Interface Plugin 3.0
2+
* jQuery File Upload User Interface Plugin 3.1
33
*
44
* Copyright 2010, Sebastian Tschan, AQUANTUM
55
* Licensed under the MIT license:
@@ -16,7 +16,7 @@
1616

1717
var UploadHandler = function (dropZone, options) {
1818
var uploadHandler = this,
19-
dragLeaveTimeout,
19+
dragOverTimeout,
2020
isDropZoneEnlarged;
2121

2222
this.progressSelector = '.file_upload_progress div';
@@ -193,28 +193,26 @@
193193
};
194194

195195
this.onDocumentDragEnter = function (event) {
196-
setTimeout(function () {
197-
if (dragLeaveTimeout) {
198-
clearTimeout(dragLeaveTimeout);
199-
}
200-
}, 50);
201196
uploadHandler.dropZoneEnlarge();
202197
};
203198

204-
this.onDocumentDragLeave = function (event) {
205-
if (dragLeaveTimeout) {
206-
clearTimeout(dragLeaveTimeout);
199+
this.onDocumentDragOver = function (event) {
200+
if (dragOverTimeout) {
201+
clearTimeout(dragOverTimeout);
207202
}
208-
dragLeaveTimeout = setTimeout(function () {
203+
dragOverTimeout = setTimeout(function () {
209204
uploadHandler.dropZoneReduce();
210-
}, 100);
205+
}, 200);
211206
};
212207

213208
this.onDragEnter = this.onDragLeave = function (event) {
214209
dropZone.toggleClass(uploadHandler.cssClassHighlight);
215210
};
216211

217212
this.onDrop = function (event) {
213+
if (dragOverTimeout) {
214+
clearTimeout(dragOverTimeout);
215+
}
218216
if (typeof dropZone.effect === 'function') {
219217
dropZone.effect(uploadHandler.dropEffect, function () {
220218
dropZone.removeClass(uploadHandler.cssClassHighlight);

jquery.fileupload.js

Lines changed: 58 additions & 110 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* jQuery File Upload Plugin 3.0
2+
* jQuery File Upload Plugin 3.1
33
*
44
* Copyright 2010, Sebastian Tschan, AQUANTUM
55
* Licensed under the MIT license:
@@ -34,6 +34,7 @@
3434
dropZoneListeners = {},
3535
fileInputListeners = {},
3636
undef = 'undefined',
37+
func = 'function',
3738
protocolRegExp = /^http(s)?:\/\//,
3839
onInputChangeCalled,
3940

@@ -44,81 +45,66 @@
4445
},
4546

4647
initEventHandlers = function () {
47-
documentListeners['dragenter.' + settings.namespace] = function (e) {
48-
fileUpload.onDocumentDragEnter(e);
49-
};
50-
documentListeners['dragover.' + settings.namespace] = function (e) {
51-
fileUpload.onDocumentDragOver(e);
52-
};
53-
documentListeners['dragleave.' + settings.namespace] = function (e) {
54-
fileUpload.onDocumentDragLeave(e);
55-
};
48+
if (typeof settings.onDocumentDragEnter === func) {
49+
documentListeners['dragenter.' + settings.namespace] = settings.onDocumentDragEnter;
50+
}
51+
if (typeof settings.onDocumentDragLeave === func) {
52+
documentListeners['dragleave.' + settings.namespace] = settings.onDocumentDragLeave;
53+
}
54+
documentListeners['dragover.' + settings.namespace] = fileUpload.onDocumentDragOver;
55+
documentListeners['drop.' + settings.namespace] = fileUpload.onDocumentDrop;
5656
$(document).bind(documentListeners);
57-
dropZoneListeners['dragenter.' + settings.namespace] = function (e) {
58-
fileUpload.onDragEnter(e);
59-
};
60-
dropZoneListeners['dragover.' + settings.namespace] = function (e) {
61-
fileUpload.onDragOver(e);
62-
};
63-
dropZoneListeners['dragleave.' + settings.namespace] = function (e) {
64-
fileUpload.onDragLeave(e);
65-
};
66-
dropZoneListeners['drop.' + settings.namespace] = function (e) {
67-
fileUpload.onDrop(e);
68-
};
57+
if (typeof settings.onDragEnter === func) {
58+
dropZoneListeners['dragenter.' + settings.namespace] = settings.onDragEnter;
59+
}
60+
if (typeof settings.onDragLeave === func) {
61+
dropZoneListeners['dragleave.' + settings.namespace] = settings.onDragLeave;
62+
}
63+
dropZoneListeners['dragover.' + settings.namespace] = fileUpload.onDragOver;
64+
dropZoneListeners['drop.' + settings.namespace] = fileUpload.onDrop;
6965
dropZone.bind(dropZoneListeners);
70-
fileInputListeners['click.' + settings.namespace] = function (e) {
71-
fileUpload.onInputClick(e);
72-
};
73-
fileInputListeners['change.' + settings.namespace] = function (e) {
74-
fileUpload.onInputChange(e);
75-
};
66+
fileInputListeners['click.' + settings.namespace] = fileUpload.onInputClick;
67+
fileInputListeners['change.' + settings.namespace] = fileUpload.onInputChange;
7668
fileInput.bind(fileInputListeners);
7769
},
7870

7971
removeEventHandlers = function () {
80-
$.each(documentListeners, function (i, listener) {
81-
if (documentListeners.hasOwnProperty(listener)) {
82-
$(document).unbind(listener);
83-
}
72+
$.each(documentListeners, function (key, value) {
73+
$(document).unbind(key, value);
8474
});
85-
$.each(dropZoneListeners, function (i, listener) {
86-
if (dropZoneListeners.hasOwnProperty(listener)) {
87-
dropZone.unbind(listener);
88-
}
75+
$.each(dropZoneListeners, function (key, value) {
76+
dropZone.unbind(key, value);
8977
});
90-
$.each(fileInputListeners, function (i, listener) {
91-
if (fileInputListeners.hasOwnProperty(listener)) {
92-
fileInput.unbind(listener);
93-
}
78+
$.each(fileInputListeners, function (key, value) {
79+
fileInput.unbind(key, value);
9480
});
9581
},
9682

9783
initUploadEventHandlers = function (files, index, xhr, settings) {
98-
if (typeof settings.onProgress === 'function') {
84+
if (typeof settings.onProgress === func) {
9985
xhr.upload.onprogress = function (e) {
10086
settings.onProgress(e, files, index, xhr, settings);
10187
};
10288
}
103-
if (typeof settings.onLoad === 'function') {
89+
if (typeof settings.onLoad === func) {
10490
xhr.onload = function (e) {
10591
settings.onLoad(e, files, index, xhr, settings);
10692
};
10793
}
108-
if (typeof settings.onAbort === 'function') {
94+
if (typeof settings.onAbort === func) {
10995
xhr.onabort = function (e) {
11096
settings.onAbort(e, files, index, xhr, settings);
11197
};
11298
}
113-
if (typeof settings.onError === 'function') {
99+
if (typeof settings.onError === func) {
114100
xhr.onerror = function (e) {
115101
settings.onError(e, files, index, xhr, settings);
116102
};
117103
}
118104
},
119105

120106
getFormData = function (settings) {
121-
if (typeof settings.formData === 'function') {
107+
if (typeof settings.formData === func) {
122108
return settings.formData();
123109
} else if ($.isArray(settings.formData)) {
124110
return settings.formData;
@@ -216,7 +202,7 @@
216202
handleFile = function (event, files, index) {
217203
var xhr = new XMLHttpRequest(),
218204
uploadSettings = $.extend({}, settings);
219-
if (typeof settings.initUpload === 'function') {
205+
if (typeof settings.initUpload === func) {
220206
settings.initUpload(
221207
event,
222208
files,
@@ -247,14 +233,14 @@
247233
// javascript:false as iframe src prevents warning popups on HTTPS in IE6
248234
// concat is used here to prevent the "Script URL" JSLint error:
249235
iframe.unbind('load').attr('src', 'javascript'.concat(':false;'));
250-
if (typeof settings.onAbort === 'function') {
236+
if (typeof settings.onAbort === func) {
251237
settings.onAbort(e, [{name: input.value, type: null, size: null}], 0, iframe, settings);
252238
}
253239
})
254240
.unbind('load')
255241
.bind('load', function (e) {
256242
iframe.readyState = 4;
257-
if (typeof settings.onLoad === 'function') {
243+
if (typeof settings.onLoad === func) {
258244
settings.onLoad(e, [{name: input.value, type: null, size: null}], 0, iframe, settings);
259245
}
260246
});
@@ -291,7 +277,7 @@
291277
};
292278
iframe.bind('load', function () {
293279
iframe.unbind('load');
294-
if (typeof settings.initUpload === 'function') {
280+
if (typeof settings.initUpload === func) {
295281
settings.initUpload(
296282
event,
297283
[{name: input.value, type: null, size: null}],
@@ -307,76 +293,39 @@
307293
}
308294
}).appendTo(dropZone);
309295
};
310-
311-
this.onDocumentDragEnter = function (e) {
312-
if (typeof settings.onDocumentDragEnter === 'function') {
313-
if (settings.onDocumentDragEnter(e) === false) {
314-
return;
315-
}
316-
}
317-
e.preventDefault();
318-
};
319296

320297
this.onDocumentDragOver = function (e) {
321-
if (typeof settings.onDocumentDragOver === 'function') {
322-
if (settings.onDocumentDragOver(e) === false) {
323-
return;
324-
}
325-
}
326-
var dataTransfer = e.originalEvent.dataTransfer,
327-
target = e.originalEvent.target;
328-
if (dataTransfer && dropZone.get(0) !== target && !dropZone.has(target).length) {
329-
dataTransfer.dropEffect = 'none';
330-
}
331-
e.preventDefault();
332-
};
333-
334-
this.onDocumentDragLeave = function (e) {
335-
if (typeof settings.onDocumentDragLeave === 'function') {
336-
if (settings.onDocumentDragLeave(e) === false) {
337-
return;
338-
}
298+
if (typeof settings.onDocumentDragOver === func &&
299+
settings.onDocumentDragOver(e) === false) {
300+
return false;
339301
}
340302
e.preventDefault();
341303
};
342-
343-
this.onDragEnter = function (e) {
344-
if (typeof settings.onDragEnter === 'function') {
345-
if (settings.onDragEnter(e) === false) {
346-
return;
347-
}
304+
305+
this.onDocumentDrop = function (e) {
306+
if (typeof settings.onDocumentDrop === func &&
307+
settings.onDocumentDrop(e) === false) {
308+
return false;
348309
}
349310
e.preventDefault();
350311
};
351312

352313
this.onDragOver = function (e) {
353-
if (typeof settings.onDragOver === 'function') {
354-
if (settings.onDragOver(e) === false) {
355-
return;
356-
}
314+
if (typeof settings.onDragOver === func &&
315+
settings.onDragOver(e) === false) {
316+
return false;
357317
}
358318
var dataTransfer = e.originalEvent.dataTransfer;
359319
if (dataTransfer) {
360320
dataTransfer.dropEffect = dataTransfer.effectAllowed = 'copy';
361321
}
362322
e.preventDefault();
363-
e.stopPropagation();
364-
};
365-
366-
this.onDragLeave = function (e) {
367-
if (typeof settings.onDragLeave === 'function') {
368-
if (settings.onDragLeave(e) === false) {
369-
return;
370-
}
371-
}
372-
e.preventDefault();
373323
};
374324

375325
this.onDrop = function (e) {
376-
if (typeof settings.onDrop === 'function') {
377-
if (settings.onDrop(e) === false) {
378-
return;
379-
}
326+
if (typeof settings.onDrop === func &&
327+
settings.onDrop(e) === false) {
328+
return false;
380329
}
381330
var dataTransfer = e.originalEvent.dataTransfer;
382331
if (dataTransfer && dataTransfer.files && isXHRUploadCapable()) {
@@ -386,25 +335,23 @@
386335
};
387336

388337
this.onInputClick = function (e) {
389-
if (typeof settings.onInputClick === 'function') {
390-
if (settings.onInputClick(e) === false) {
391-
return;
392-
}
338+
if (typeof settings.onInputClick === func &&
339+
settings.onInputClick(e) === false) {
340+
return false;
393341
}
394342
e.target.form.reset();
395343
onInputChangeCalled = false;
396344
};
397345

398346
this.onInputChange = function (e) {
347+
if (typeof settings.onInputChange === func &&
348+
settings.onInputChange(e) === false) {
349+
return false;
350+
}
399351
if (onInputChangeCalled) {
400352
return;
401353
}
402354
onInputChangeCalled = true;
403-
if (typeof settings.onInputChange === 'function') {
404-
if (settings.onInputChange(e) === false) {
405-
return;
406-
}
407-
}
408355
if (e.target.files && isXHRUploadCapable()) {
409356
handleFiles(e, e.target.files);
410357
} else {
@@ -427,7 +374,8 @@
427374

428375
this.destroy = function () {
429376
removeEventHandlers();
430-
dropZone.removeData(settings.namespace)
377+
dropZone
378+
.removeData(settings.namespace)
431379
.removeClass(settings.cssClass);
432380
};
433381
},

0 commit comments

Comments
 (0)