|
1 | 1 | /*
|
2 |
| - * jQuery File Upload Plugin 5.15 |
| 2 | + * jQuery File Upload Plugin 5.16 |
3 | 3 | * https://github.com/blueimp/jQuery-File-Upload
|
4 | 4 | *
|
5 | 5 | * Copyright 2010, Sebastian Tschan
|
|
696 | 696 | var args = [undefined, 'abort', 'abort'];
|
697 | 697 | if (!jqXHR) {
|
698 | 698 | if (slot) {
|
699 |
| - slot.rejectWith(args); |
| 699 | + slot.rejectWith(pipe, args); |
700 | 700 | }
|
701 | 701 | return send(false, args);
|
702 | 702 | }
|
|
775 | 775 | }
|
776 | 776 | },
|
777 | 777 |
|
| 778 | + _handleFileTreeEntry: function (entry, path) { |
| 779 | + var that = this, |
| 780 | + dfd = $.Deferred(), |
| 781 | + errorHandler = function () { |
| 782 | + dfd.reject(); |
| 783 | + }, |
| 784 | + dirReader; |
| 785 | + path = path || ''; |
| 786 | + if (entry.isFile) { |
| 787 | + entry.file(function (file) { |
| 788 | + file.relativePath = path; |
| 789 | + dfd.resolve(file); |
| 790 | + }, errorHandler); |
| 791 | + } else if (entry.isDirectory) { |
| 792 | + dirReader = entry.createReader(); |
| 793 | + dirReader.readEntries(function (entries) { |
| 794 | + that._handleFileTreeEntries( |
| 795 | + entries, |
| 796 | + path + entry.name + '/' |
| 797 | + ).done(function (files) { |
| 798 | + dfd.resolve(files); |
| 799 | + }).fail(errorHandler); |
| 800 | + }, errorHandler); |
| 801 | + } else { |
| 802 | + errorHandler(); |
| 803 | + } |
| 804 | + return dfd.promise(); |
| 805 | + }, |
| 806 | + |
| 807 | + _handleFileTreeEntries: function (entries, path) { |
| 808 | + var that = this; |
| 809 | + return $.when.apply( |
| 810 | + $, |
| 811 | + $.map(entries, function (entry) { |
| 812 | + return that._handleFileTreeEntry(entry, path); |
| 813 | + }) |
| 814 | + ).pipe(function () { |
| 815 | + return Array.prototype.concat.apply( |
| 816 | + [], |
| 817 | + arguments |
| 818 | + ); |
| 819 | + }); |
| 820 | + }, |
| 821 | + |
| 822 | + _getDroppedFiles: function (dataTransfer) { |
| 823 | + dataTransfer = dataTransfer || {}; |
| 824 | + var items = dataTransfer.items; |
| 825 | + if (items && items.length && (items[0].webkitGetAsEntry || |
| 826 | + items[0].getAsEntry)) { |
| 827 | + return this._handleFileTreeEntries( |
| 828 | + $.map(items, function (item) { |
| 829 | + if (item.webkitGetAsEntry) { |
| 830 | + return item.webkitGetAsEntry(); |
| 831 | + } |
| 832 | + return item.getAsEntry(); |
| 833 | + }) |
| 834 | + ); |
| 835 | + } |
| 836 | + return $.Deferred().resolve( |
| 837 | + $.makeArray(dataTransfer.files) |
| 838 | + ).promise(); |
| 839 | + }, |
| 840 | + |
778 | 841 | _getFileInputFiles: function (fileInput) {
|
779 | 842 | fileInput = $(fileInput);
|
780 |
| - var files = $.makeArray(fileInput.prop('files')), |
| 843 | + var entries = fileInput.prop('webkitEntries') || |
| 844 | + fileInput.prop('entries'), |
| 845 | + files, |
781 | 846 | value;
|
| 847 | + if (entries) { |
| 848 | + return this._handleFileTreeEntries(entries); |
| 849 | + } |
| 850 | + files = $.makeArray(fileInput.prop('files')); |
782 | 851 | if (!files.length) {
|
783 | 852 | value = fileInput.prop('value');
|
784 | 853 | if (!value) {
|
785 |
| - return []; |
| 854 | + return $.Deferred().reject([]).promise(); |
786 | 855 | }
|
787 | 856 | // If the files property is not available, the browser does not
|
788 | 857 | // support the File API and we add a pseudo File object with
|
789 | 858 | // the input value as name with path information removed:
|
790 | 859 | files = [{name: value.replace(/^.*\\/, '')}];
|
791 | 860 | }
|
792 |
| - return files; |
| 861 | + return $.Deferred().resolve(files).promise(); |
793 | 862 | },
|
794 | 863 |
|
795 | 864 | _onChange: function (e) {
|
|
798 | 867 | fileInput: $(e.target),
|
799 | 868 | form: $(e.target.form)
|
800 | 869 | };
|
801 |
| - data.files = that._getFileInputFiles(data.fileInput); |
802 |
| - if (that.options.replaceFileInput) { |
803 |
| - that._replaceFileInput(data.fileInput); |
804 |
| - } |
805 |
| - if (that._trigger('change', e, data) === false || |
806 |
| - that._onAdd(e, data) === false) { |
807 |
| - return false; |
808 |
| - } |
| 870 | + that._getFileInputFiles(data.fileInput).always(function (files) { |
| 871 | + data.files = files; |
| 872 | + if (that.options.replaceFileInput) { |
| 873 | + that._replaceFileInput(data.fileInput); |
| 874 | + } |
| 875 | + if (that._trigger('change', e, data) !== false) { |
| 876 | + that._onAdd(e, data); |
| 877 | + } |
| 878 | + }); |
809 | 879 | },
|
810 | 880 |
|
811 | 881 | _onPaste: function (e) {
|
|
826 | 896 | },
|
827 | 897 |
|
828 | 898 | _onDrop: function (e) {
|
| 899 | + e.preventDefault(); |
829 | 900 | var that = e.data.fileupload,
|
830 | 901 | dataTransfer = e.dataTransfer = e.originalEvent.dataTransfer,
|
831 |
| - data = { |
832 |
| - files: $.makeArray(dataTransfer && dataTransfer.files) |
833 |
| - }; |
834 |
| - if (that._trigger('drop', e, data) === false || |
835 |
| - that._onAdd(e, data) === false) { |
836 |
| - return false; |
837 |
| - } |
838 |
| - e.preventDefault(); |
| 902 | + data = {}; |
| 903 | + that._getDroppedFiles(dataTransfer).always(function (files) { |
| 904 | + data.files = files; |
| 905 | + if (that._trigger('drop', e, data) !== false) { |
| 906 | + that._onAdd(e, data); |
| 907 | + } |
| 908 | + }); |
839 | 909 | },
|
840 | 910 |
|
841 | 911 | _onDragOver: function (e) {
|
|
929 | 999 | // must have a files property and can contain additional options:
|
930 | 1000 | // .fileupload('add', {files: filesList});
|
931 | 1001 | add: function (data) {
|
| 1002 | + var that = this; |
932 | 1003 | if (!data || this.options.disabled) {
|
933 | 1004 | return;
|
934 | 1005 | }
|
935 | 1006 | if (data.fileInput && !data.files) {
|
936 |
| - data.files = this._getFileInputFiles(data.fileInput); |
| 1007 | + this._getFileInputFiles(data.fileInput).always(function (files) { |
| 1008 | + data.files = files; |
| 1009 | + that._onAdd(null, data); |
| 1010 | + }); |
937 | 1011 | } else {
|
938 | 1012 | data.files = $.makeArray(data.files);
|
| 1013 | + this._onAdd(null, data); |
939 | 1014 | }
|
940 |
| - this._onAdd(null, data); |
941 | 1015 | },
|
942 | 1016 |
|
943 | 1017 | // This method is exposed to the widget API and allows sending files
|
944 | 1018 | // using the fileupload API. The data parameter accepts an object which
|
945 |
| - // must have a files property and can contain additional options: |
| 1019 | + // must have a files or fileInput property and can contain additional options: |
946 | 1020 | // .fileupload('send', {files: filesList});
|
947 | 1021 | // The method returns a Promise object for the file upload call.
|
948 | 1022 | send: function (data) {
|
949 | 1023 | if (data && !this.options.disabled) {
|
950 | 1024 | if (data.fileInput && !data.files) {
|
951 |
| - data.files = this._getFileInputFiles(data.fileInput); |
952 |
| - } else { |
953 |
| - data.files = $.makeArray(data.files); |
| 1025 | + var that = this, |
| 1026 | + dfd = $.Deferred(), |
| 1027 | + promise = dfd.promise(), |
| 1028 | + jqXHR, |
| 1029 | + aborted; |
| 1030 | + promise.abort = function () { |
| 1031 | + aborted = true; |
| 1032 | + if (jqXHR) { |
| 1033 | + return jqXHR.abort(); |
| 1034 | + } |
| 1035 | + dfd.reject(null, 'abort', 'abort'); |
| 1036 | + return promise; |
| 1037 | + }; |
| 1038 | + this._getFileInputFiles(data.fileInput).always( |
| 1039 | + function (files) { |
| 1040 | + if (aborted) { |
| 1041 | + return; |
| 1042 | + } |
| 1043 | + data.files = files; |
| 1044 | + jqXHR = that._onSend(null, data).then( |
| 1045 | + function (result, textStatus, jqXHR) { |
| 1046 | + dfd.resolve(result, textStatus, jqXHR); |
| 1047 | + }, |
| 1048 | + function (jqXHR, textStatus, errorThrown) { |
| 1049 | + dfd.reject(jqXHR, textStatus, errorThrown); |
| 1050 | + } |
| 1051 | + ); |
| 1052 | + } |
| 1053 | + ); |
| 1054 | + return this._enhancePromise(promise); |
954 | 1055 | }
|
| 1056 | + data.files = $.makeArray(data.files); |
955 | 1057 | if (data.files.length) {
|
956 | 1058 | return this._onSend(null, data);
|
957 | 1059 | }
|
|
0 commit comments