Skip to content

Commit 5a3589d

Browse files
committed
feat(tpl): support drag drop directories for uploading
1 parent 522dde2 commit 5a3589d

File tree

2 files changed

+197
-35
lines changed

2 files changed

+197
-35
lines changed

src/tpl/asset/main.js

Lines changed: 109 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -401,6 +401,11 @@
401401
return;
402402
}
403403

404+
var btnSubmit = form.querySelector('.submit') || form.querySelector('input[type=submit]');
405+
if (!btnSubmit) {
406+
return;
407+
}
408+
404409
var uploadType = document.body.querySelector('.upload-type');
405410
if (!uploadType) {
406411
return;
@@ -544,11 +549,6 @@
544549
return;
545550
}
546551

547-
var btnSubmit = form.querySelector('.submit') || form.querySelector('input[type=submit]');
548-
if (!btnSubmit) {
549-
return;
550-
}
551-
552552
var elProgress = btnSubmit.querySelector('.progress');
553553

554554
function onComplete() {
@@ -578,11 +578,16 @@
578578
var formName = fileInput.name;
579579
var parts = new FormData();
580580
files.forEach(function (file) {
581-
if (file.webkitRelativePath) {
582-
parts.append(formName, file, file.webkitRelativePath);
583-
} else {
584-
parts.append(formName, file);
581+
var relativePath
582+
if (file.file) {
583+
// unwrap object {file, relativePath}
584+
relativePath = file.relativePath;
585+
file = file.file;
586+
} else if (file.webkitRelativePath) {
587+
relativePath = file.webkitRelativePath
585588
}
589+
590+
parts.append(formName, file, relativePath);
586591
});
587592

588593
var xhr = new XMLHttpRequest();
@@ -628,6 +633,58 @@
628633
}
629634
}
630635

636+
function getFilesFromEntries(entries, onDone) {
637+
var files = [];
638+
var len = entries.length;
639+
var cb = 0;
640+
641+
function increaseCb() {
642+
cb++;
643+
if (cb === len) {
644+
onDone(files);
645+
}
646+
}
647+
648+
entries.forEach(function (entry) {
649+
if (entry.isFile) {
650+
var relativePath = entry.fullPath.substring(entry.fullPath.indexOf('/') + 1)
651+
entry.file(function (file) {
652+
files.push({file: file, relativePath: relativePath});
653+
increaseCb();
654+
}, function (err) {
655+
console && console.error(err);
656+
increaseCb();
657+
});
658+
} else {
659+
var reader = entry.createReader();
660+
reader.readEntries(function (subEntries) {
661+
if (subEntries.length) {
662+
getFilesFromEntries(subEntries, function (subFiles) {
663+
Array.prototype.push.apply(files, subFiles);
664+
increaseCb();
665+
}, function (err) {
666+
console && console.error(err);
667+
increaseCb();
668+
});
669+
} else {
670+
increaseCb();
671+
}
672+
});
673+
}
674+
});
675+
}
676+
677+
function getFilesFromItems(items, onDone) {
678+
var files = [];
679+
680+
var entries = [];
681+
for (var i = 0, len = items.length; i < len; i++) {
682+
var entry = items[i].webkitGetAsEntry();
683+
entries.push(entry);
684+
}
685+
getFilesFromEntries(entries, onDone);
686+
}
687+
631688
function onDrop(e) {
632689
e.stopPropagation();
633690
e.preventDefault();
@@ -638,27 +695,54 @@
638695
return;
639696
}
640697

641-
var items = Array.prototype.slice.call(e.dataTransfer.items);
642-
if (items && items.length && items[0].webkitGetAsEntry) {
643-
for (var i = 0, len = items.length; i < len; i++) {
644-
var entry = items[i].webkitGetAsEntry();
645-
if (entry && entry.isDirectory) {
646-
return;
698+
var hasDir = false;
699+
if (e.dataTransfer.items) {
700+
var items = Array.prototype.slice.call(e.dataTransfer.items);
701+
if (items && items.length && items[0].webkitGetAsEntry) {
702+
for (var i = 0, len = items.length; i < len; i++) {
703+
var entry = items[i].webkitGetAsEntry();
704+
if (entry.isDirectory) {
705+
hasDir = true;
706+
break;
707+
}
647708
}
648709
}
649710
}
650711

651-
if (optFile && optActive !== optFile) {
652-
optFile.focus();
653-
optFile.click();
654-
}
655-
656-
fileInput.files = e.dataTransfer.files;
657-
if (uploadProgressively) {
658-
var files = Array.prototype.slice.call(e.dataTransfer.files);
659-
uploadProgressively(files);
712+
if (hasDir) {
713+
if (!optDirFile && !optInnerDirFile) {
714+
return;
715+
}
716+
if (optActive === optFile) {
717+
if (optDirFile) {
718+
optDirFile.focus();
719+
optDirFile.click();
720+
} else if (optInnerDirFile) {
721+
optInnerDirFile.focus();
722+
optInnerDirFile.click();
723+
}
724+
}
725+
if (uploadProgressively) {
726+
btnSubmit.disabled = true; // disable earlier
727+
getFilesFromItems(e.dataTransfer.items, function (files) {
728+
uploadProgressively(files);
729+
});
730+
} else {
731+
form.submit();
732+
}
660733
} else {
661-
form.submit();
734+
if (optFile && optActive !== optFile) {
735+
optFile.focus();
736+
optFile.click();
737+
}
738+
739+
fileInput.files = e.dataTransfer.files;
740+
if (uploadProgressively) {
741+
var files = Array.prototype.slice.call(e.dataTransfer.files);
742+
uploadProgressively(files);
743+
} else {
744+
form.submit();
745+
}
662746
}
663747
}
664748

src/tpl/asset/main.js.go

Lines changed: 88 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -361,6 +361,10 @@ var fileInput = form.querySelector('.file');
361361
if (!fileInput) {
362362
return;
363363
}
364+
var btnSubmit = form.querySelector('.submit') || form.querySelector('input[type=submit]');
365+
if (!btnSubmit) {
366+
return;
367+
}
364368
var uploadType = document.body.querySelector('.upload-type');
365369
if (!uploadType) {
366370
return;
@@ -483,10 +487,6 @@ function enableUploadProgress() { // also fix Safari upload filename has no path
483487
if (!FormData) {
484488
return;
485489
}
486-
var btnSubmit = form.querySelector('.submit') || form.querySelector('input[type=submit]');
487-
if (!btnSubmit) {
488-
return;
489-
}
490490
var elProgress = btnSubmit.querySelector('.progress');
491491
function onComplete() {
492492
if (elProgress) {
@@ -511,11 +511,15 @@ return;
511511
var formName = fileInput.name;
512512
var parts = new FormData();
513513
files.forEach(function (file) {
514-
if (file.webkitRelativePath) {
515-
parts.append(formName, file, file.webkitRelativePath);
516-
} else {
517-
parts.append(formName, file);
518-
}
514+
var relativePath
515+
if (file.file) {
516+
// unwrap object {file, relativePath}
517+
relativePath = file.relativePath;
518+
file = file.file;
519+
} else if (file.webkitRelativePath) {
520+
relativePath = file.webkitRelativePath
521+
}
522+
parts.append(formName, file, relativePath);
519523
});
520524
var xhr = new XMLHttpRequest();
521525
xhr.upload.addEventListener('error', onComplete);
@@ -553,6 +557,53 @@ if (e.target === e.currentTarget) {
553557
removeClass(e.currentTarget, 'dragging');
554558
}
555559
}
560+
function getFilesFromEntries(entries, onDone) {
561+
var files = [];
562+
var len = entries.length;
563+
var cb = 0;
564+
function increaseCb() {
565+
cb++;
566+
if (cb === len) {
567+
onDone(files);
568+
}
569+
}
570+
entries.forEach(function (entry) {
571+
if (entry.isFile) {
572+
var relativePath = entry.fullPath.substring(entry.fullPath.indexOf('/') + 1)
573+
entry.file(function (file) {
574+
files.push({file: file, relativePath: relativePath});
575+
increaseCb();
576+
}, function (err) {
577+
console && console.error(err);
578+
increaseCb();
579+
});
580+
} else {
581+
var reader = entry.createReader();
582+
reader.readEntries(function (subEntries) {
583+
if (subEntries.length) {
584+
getFilesFromEntries(subEntries, function (subFiles) {
585+
Array.prototype.push.apply(files, subFiles);
586+
increaseCb();
587+
}, function (err) {
588+
console && console.error(err);
589+
increaseCb();
590+
});
591+
} else {
592+
increaseCb();
593+
}
594+
});
595+
}
596+
});
597+
}
598+
function getFilesFromItems(items, onDone) {
599+
var files = [];
600+
var entries = [];
601+
for (var i = 0, len = items.length; i < len; i++) {
602+
var entry = items[i].webkitGetAsEntry();
603+
entries.push(entry);
604+
}
605+
getFilesFromEntries(entries, onDone);
606+
}
556607
function onDrop(e) {
557608
e.stopPropagation();
558609
e.preventDefault();
@@ -561,15 +612,41 @@ fileInput.value = '';
561612
if (!e.dataTransfer || !e.dataTransfer.files || !e.dataTransfer.files.length) {
562613
return;
563614
}
615+
var hasDir = false;
616+
if (e.dataTransfer.items) {
564617
var items = Array.prototype.slice.call(e.dataTransfer.items);
565618
if (items && items.length && items[0].webkitGetAsEntry) {
566619
for (var i = 0, len = items.length; i < len; i++) {
567620
var entry = items[i].webkitGetAsEntry();
568-
if (entry && entry.isDirectory) {
621+
if (entry.isDirectory) {
622+
hasDir = true;
623+
break;
624+
}
625+
}
626+
}
627+
}
628+
if (hasDir) {
629+
if (!optDirFile && !optInnerDirFile) {
569630
return;
570631
}
632+
if (optActive === optFile) {
633+
if (optDirFile) {
634+
optDirFile.focus();
635+
optDirFile.click();
636+
} else if (optInnerDirFile) {
637+
optInnerDirFile.focus();
638+
optInnerDirFile.click();
571639
}
572640
}
641+
if (uploadProgressively) {
642+
btnSubmit.disabled = true; // disable earlier
643+
getFilesFromItems(e.dataTransfer.items, function (files) {
644+
uploadProgressively(files);
645+
});
646+
} else {
647+
form.submit();
648+
}
649+
} else {
573650
if (optFile && optActive !== optFile) {
574651
optFile.focus();
575652
optFile.click();
@@ -582,6 +659,7 @@ uploadProgressively(files);
582659
form.submit();
583660
}
584661
}
662+
}
585663
upload.addEventListener('dragenter', onDragEnterOver, false);
586664
upload.addEventListener('dragover', onDragEnterOver, false);
587665
upload.addEventListener('dragleave', onDragLeave, false);

0 commit comments

Comments
 (0)