|
746 | 746 | var classUploading = 'uploading'; |
747 | 747 | var classFailed = 'failed'; |
748 | 748 | var elUploadStatus = document.body.querySelector('.upload-status'); |
749 | | - var elProgress = elUploadStatus && elUploadStatus.querySelector('.progress'); |
750 | | - var elFailedMessage = elUploadStatus && elUploadStatus.querySelector('.warn .message'); |
| 749 | + var elProgress = elUploadStatus.querySelector('.progress'); |
| 750 | + var elFailedMessage = elUploadStatus.querySelector('.warn .message'); |
751 | 751 |
|
752 | | - function onComplete() { |
753 | | - if (elProgress) { |
754 | | - elProgress.style.width = ''; |
755 | | - } |
756 | | - } |
757 | | - |
758 | | - function onSuccess() { |
759 | | - if (batches.length) { |
760 | | - return uploadBatch(batches.shift()); // use "return" for tail call optimize |
761 | | - } else { |
762 | | - uploading = false; |
763 | | - elUploadStatus.classList.remove(classUploading); |
| 752 | + function onProgress(e) { |
| 753 | + if (e.lengthComputable) { |
| 754 | + var percent = 100 * e.loaded / e.total; |
| 755 | + elProgress.style.width = percent + '%'; |
764 | 756 | } |
765 | 757 | } |
766 | 758 |
|
767 | 759 | function onFail(e) { |
768 | 760 | elUploadStatus.classList.remove(classUploading); |
769 | 761 | elUploadStatus.classList.add(classFailed); |
770 | | - if (elFailedMessage) { |
771 | | - elFailedMessage.textContent = " - " + e.type; |
772 | | - } |
| 762 | + elFailedMessage.textContent = " - " + e.type; |
773 | 763 | batches.length = 0; |
774 | 764 | } |
775 | 765 |
|
776 | | - function onLoad() { |
777 | | - var status = this.status; |
778 | | - if (status >= 200 && status <= 299) { |
779 | | - !uploading && location.reload(); |
| 766 | + function onSuccess(e) { |
| 767 | + var status = e.target.status |
| 768 | + if (status < 200 || status >= 300) { |
| 769 | + return onFail({type: e.target.statusText || status}); |
| 770 | + } else if (batches.length) { |
| 771 | + uploadBatch(batches.shift()); |
780 | 772 | } else { |
781 | | - onFail({type: this.statusText || status}); |
782 | | - } |
783 | | - } |
784 | | - |
785 | | - function onProgress(e) { |
786 | | - if (e.lengthComputable) { |
787 | | - var percent = 100 * e.loaded / e.total; |
788 | | - elProgress.style.width = percent + '%'; |
| 773 | + uploading = false; |
| 774 | + elUploadStatus.classList.remove(classUploading); |
| 775 | + location.reload(); |
789 | 776 | } |
790 | 777 | } |
791 | 778 |
|
792 | | - function uploadProgressively(files) { |
793 | | - if (!files.length) { |
794 | | - return; |
795 | | - } |
796 | | - |
797 | | - if (uploading) { |
798 | | - batches.push(files); |
799 | | - } else { |
800 | | - uploading = true; |
801 | | - elUploadStatus.classList.remove(classFailed); |
802 | | - elUploadStatus.classList.add(classUploading); |
803 | | - uploadBatch(files); |
804 | | - } |
| 779 | + function onFinally() { |
| 780 | + elProgress.style.width = ''; |
805 | 781 | } |
806 | 782 |
|
807 | 783 | function uploadBatch(files) { |
|
824 | 800 | }); |
825 | 801 |
|
826 | 802 | var xhr = new XMLHttpRequest(); |
827 | | - xhr.addEventListener('error', onComplete); |
| 803 | + xhr.upload.addEventListener('progress', onProgress); |
828 | 804 | xhr.addEventListener('error', onFail); |
829 | | - xhr.addEventListener('abort', onComplete); |
| 805 | + xhr.addEventListener('error', onFinally); |
830 | 806 | xhr.addEventListener('abort', onFail); |
831 | | - xhr.addEventListener('load', onComplete); |
| 807 | + xhr.addEventListener('abort', onFinally); |
832 | 808 | xhr.addEventListener('load', onSuccess); |
833 | | - xhr.addEventListener('load', onLoad); |
834 | | - if (elProgress) { |
835 | | - xhr.upload.addEventListener('progress', onProgress); |
836 | | - } |
| 809 | + xhr.addEventListener('load', onFinally); |
837 | 810 |
|
838 | 811 | xhr.open(form.method, form.action); |
839 | 812 | xhr.send(parts); |
840 | 813 | } |
841 | 814 |
|
| 815 | + function uploadProgressively(files) { |
| 816 | + if (!files.length) { |
| 817 | + return; |
| 818 | + } |
| 819 | + |
| 820 | + if (uploading) { |
| 821 | + batches.push(files); |
| 822 | + } else { |
| 823 | + uploading = true; |
| 824 | + elUploadStatus.classList.remove(classFailed); |
| 825 | + elUploadStatus.classList.add(classUploading); |
| 826 | + uploadBatch(files); |
| 827 | + } |
| 828 | + } |
| 829 | + |
842 | 830 | return uploadProgressively; |
843 | 831 | } |
844 | 832 |
|
|
857 | 845 | }); |
858 | 846 | } |
859 | 847 |
|
860 | | - function enableAddDragDrop(uploadProgressively, switchToFileMode, switchToDirMode) { |
| 848 | + function enableDndUploadProgress(uploadProgressively, switchToFileMode, switchToDirMode) { |
861 | 849 | var isSelfDragging = false; |
862 | 850 | var classDragging = 'dragging'; |
863 | 851 |
|
|
870 | 858 | } |
871 | 859 |
|
872 | 860 | function onDragEnterOver(e) { |
873 | | - if (!isSelfDragging) { |
874 | | - e.stopPropagation(); |
875 | | - e.preventDefault(); |
876 | | - e.currentTarget.classList.add(classDragging); |
877 | | - } |
| 861 | + if (isSelfDragging) return; |
| 862 | + e.stopPropagation(); |
| 863 | + e.preventDefault(); |
| 864 | + e.currentTarget.classList.add(classDragging); |
878 | 865 | } |
879 | 866 |
|
880 | 867 | function onDragLeave(e) { |
881 | 868 | if (e.target === e.currentTarget) { |
882 | | - e.currentTarget.classList.remove(classDragging); |
| 869 | + e.target.classList.remove(classDragging); |
883 | 870 | } |
884 | 871 | } |
885 | 872 |
|
|
911 | 898 |
|
912 | 899 | document.body.addEventListener('dragstart', onSelfDragStart); |
913 | 900 | document.body.addEventListener('dragend', onDragEnd); |
914 | | - var dragDropEl = document.documentElement; |
915 | | - dragDropEl.addEventListener('dragenter', onDragEnterOver); |
916 | | - dragDropEl.addEventListener('dragover', onDragEnterOver); |
917 | | - dragDropEl.addEventListener('dragleave', onDragLeave); |
918 | | - dragDropEl.addEventListener('drop', onDrop); |
| 901 | + var dndTarget = document.documentElement; |
| 902 | + dndTarget.addEventListener('dragenter', onDragEnterOver); |
| 903 | + dndTarget.addEventListener('dragover', onDragEnterOver); |
| 904 | + dndTarget.addEventListener('dragleave', onDragLeave); |
| 905 | + dndTarget.addEventListener('drop', onDrop); |
919 | 906 | } |
920 | 907 |
|
921 | | - function enableAddPasteProgressively(uploadProgressively, switchToFileMode, switchToDirMode) { |
| 908 | + function enablePasteUploadProgress(uploadProgressively, switchToFileMode, switchToDirMode) { |
922 | 909 | var typeTextPlain = 'text/plain'; |
923 | 910 | var nonTextInputTypes = ['hidden', 'radio', 'checkbox', 'button', 'reset', 'submit', 'image']; |
924 | 911 |
|
925 | | - function uploadPastedFiles(files) { |
| 912 | + function uploadPastedContent(file) { |
926 | 913 | switchToFileMode(); |
927 | | - var ts = getTimeStamp(); |
928 | | - files = files.map(function (f, i) { |
929 | | - var filename = f.name; |
930 | | - var dotIndex = filename.lastIndexOf('.'); |
931 | | - if (dotIndex < 0) { |
932 | | - dotIndex = filename.length; |
933 | | - } |
934 | | - filename = filename.substring(0, dotIndex) + ts + '-' + i + filename.substring(dotIndex); |
935 | | - return { |
936 | | - file: f, |
937 | | - relativePath: filename |
938 | | - } |
939 | | - }); |
940 | | - uploadProgressively(files); |
941 | | - } |
942 | | - |
943 | | - function generatePastedFiles(data) { |
944 | | - var files; |
945 | | - var items; |
946 | | - if (data.files && data.files.length) { |
947 | | - // pasted content is image |
948 | | - files = Array.prototype.slice.call(data.files); |
949 | | - } else if (data.items && data.items.length) { |
950 | | - // pasted content is text |
951 | | - items = Array.prototype.slice.call(data.items); |
952 | | - files = items.map(function (item) { |
953 | | - return item.getAsFile(); |
954 | | - }).filter(Boolean); |
955 | | - } else { |
956 | | - files = []; |
957 | | - } |
958 | 914 |
|
959 | | - if (files.length) { |
960 | | - uploadPastedFiles(files); |
961 | | - return; |
| 915 | + var ts = getTimeStamp(); |
| 916 | + var filename = file.name; |
| 917 | + var dotIndex = filename.lastIndexOf('.'); |
| 918 | + if (dotIndex < 0) { |
| 919 | + dotIndex = filename.length; |
962 | 920 | } |
| 921 | + filename = filename.slice(0, dotIndex) + ts + filename.slice(dotIndex); |
963 | 922 |
|
964 | | - if (!items) { |
965 | | - return; |
966 | | - } |
967 | | - var plainTextFiles = 0; |
968 | | - for (var i = 0, itemsCount = items.length; i < itemsCount; i++) { |
969 | | - if (data.types[i] !== typeTextPlain) { |
970 | | - continue |
971 | | - } |
972 | | - plainTextFiles++; |
973 | | - items[i].getAsString(function (content) { |
974 | | - var file = new File([content], 'text.txt', {type: typeTextPlain}) |
975 | | - files.push(file); |
976 | | - if (files.length === plainTextFiles) { |
977 | | - uploadPastedFiles(files); |
978 | | - } |
979 | | - }); |
980 | | - } |
| 923 | + var files = [{file: file, relativePath: filename}]; |
| 924 | + uploadProgressively(files); |
981 | 925 | } |
982 | 926 |
|
983 | 927 | document.documentElement.addEventListener('paste', function (e) { |
|
987 | 931 | } else if (tagName === 'INPUT' && nonTextInputTypes.indexOf(e.target.type) < 0) { |
988 | 932 | return; |
989 | 933 | } |
990 | | - var data = e.clipboardData; |
991 | | - |
992 | | - var items = data.items; |
993 | | - if (!items.length) { |
994 | | - generatePastedFiles(data); |
995 | | - return; |
996 | | - } |
997 | 934 |
|
998 | | - itemsToFiles(items, canMkdir).then(function (result) { |
999 | | - var files = result.files; |
1000 | | - // for pasted text |
1001 | | - if (!files.length) { |
1002 | | - generatePastedFiles(data); |
1003 | | - return; |
1004 | | - } |
1005 | | - |
1006 | | - // suppose for pasted image data |
1007 | | - if (files.length === 1 && files[0].file.type === 'image/png') { |
1008 | | - files = files.map(function (fileInfo) { |
1009 | | - return fileInfo && fileInfo.file; |
| 935 | + var data = e.clipboardData; |
| 936 | + var dItems = data.items; |
| 937 | + var dFiles = data.files; |
| 938 | + |
| 939 | + if (dItems.length === 1 && dFiles.length === 1 && dFiles[0].type === 'image/png') { |
| 940 | + // image pasted |
| 941 | + uploadPastedContent(dFiles[0]); |
| 942 | + } else if (dItems.length > 0 && dFiles.length === 0) { |
| 943 | + // text pasted (with other data types in DataTransferItems |
| 944 | + var textTypeIndex = data.types.findIndex(function (t) { |
| 945 | + return t === typeTextPlain; |
| 946 | + }); |
| 947 | + var textItem = dItems[textTypeIndex]; |
| 948 | + if (textItem) { |
| 949 | + textItem.getAsString(function (content) { |
| 950 | + var file = new File([content], 'text.txt', {type: typeTextPlain}) |
| 951 | + uploadPastedContent(file); |
1010 | 952 | }); |
1011 | | - generatePastedFiles({files: files}); |
1012 | | - return; |
1013 | 953 | } |
| 954 | + } else { |
| 955 | + // actual files/directories pasted |
| 956 | + itemsToFiles(dItems, canMkdir).then(function (result) { |
| 957 | + var files = result.files; |
1014 | 958 |
|
1015 | | - // pasted real files |
1016 | | - if (result.hasDir) { |
1017 | | - switchToDirMode(); |
1018 | | - } else { |
1019 | | - switchToFileMode(); |
1020 | | - } |
1021 | | - uploadProgressively(files); |
1022 | | - }, function (err) { |
1023 | | - if (err === errLacksMkdir && typeof showUploadDirFailMessage !== strUndef) { |
1024 | | - showUploadDirFailMessage(); |
1025 | | - } |
1026 | | - }); |
| 959 | + // pasted real files |
| 960 | + if (result.hasDir) { |
| 961 | + switchToDirMode(); |
| 962 | + } else { |
| 963 | + switchToFileMode(); |
| 964 | + } |
| 965 | + uploadProgressively(files); |
| 966 | + }, function (err) { |
| 967 | + if (err === errLacksMkdir && typeof showUploadDirFailMessage !== strUndef) { |
| 968 | + showUploadDirFailMessage(); |
| 969 | + } |
| 970 | + }); |
| 971 | + } |
1027 | 972 | }); |
1028 | 973 | } |
1029 | 974 |
|
1030 | 975 | var modes = enableFileDirModeSwitch(); |
1031 | 976 | var uploadProgressively = enableUploadProgress(); |
1032 | 977 | enableFormUploadProgress(uploadProgressively); |
1033 | | - enableAddPasteProgressively(uploadProgressively, modes.switchToFileMode, modes.switchToDirMode); |
1034 | | - enableAddDragDrop(uploadProgressively, modes.switchToFileMode, modes.switchToDirMode); |
| 978 | + enableDndUploadProgress(uploadProgressively, modes.switchToFileMode, modes.switchToDirMode); |
| 979 | + enablePasteUploadProgress(uploadProgressively, modes.switchToFileMode, modes.switchToDirMode); |
1035 | 980 | } |
1036 | 981 |
|
1037 | 982 | function enableNonRefreshDelete() { |
|
0 commit comments