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