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