|
1 | 1 | /*
|
2 |
| - * jQuery File Upload Plugin 5.13 |
| 2 | + * jQuery File Upload Plugin 5.16.1 |
3 | 3 | * https://github.com/blueimp/jQuery-File-Upload
|
4 | 4 | *
|
5 | 5 | * Copyright 2010, Sebastian Tschan
|
|
447 | 447 | if (options.type !== 'POST' && options.type !== 'PUT') {
|
448 | 448 | options.type = 'POST';
|
449 | 449 | }
|
| 450 | + if (!options.formAcceptCharset) { |
| 451 | + options.formAcceptCharset = options.form.attr('accept-charset'); |
| 452 | + } |
450 | 453 | },
|
451 | 454 |
|
452 | 455 | _getAJAXSettings: function (data) {
|
|
663 | 666 | options.limitConcurrentUploads > that._sending) {
|
664 | 667 | // Start the next queued upload,
|
665 | 668 | // that has not been aborted:
|
666 |
| - var nextSlot = that._slots.shift(); |
| 669 | + var nextSlot = that._slots.shift(), |
| 670 | + isPending; |
667 | 671 | while (nextSlot) {
|
668 |
| - if (!nextSlot.isRejected()) { |
| 672 | + // jQuery 1.6 doesn't provide .state(), |
| 673 | + // while jQuery 1.8+ removed .isRejected(): |
| 674 | + isPending = nextSlot.state ? |
| 675 | + nextSlot.state() === 'pending' : |
| 676 | + !nextSlot.isRejected(); |
| 677 | + if (isPending) { |
669 | 678 | nextSlot.resolve();
|
670 | 679 | break;
|
671 | 680 | }
|
|
693 | 702 | var args = [undefined, 'abort', 'abort'];
|
694 | 703 | if (!jqXHR) {
|
695 | 704 | if (slot) {
|
696 |
| - slot.rejectWith(args); |
| 705 | + slot.rejectWith(pipe, args); |
697 | 706 | }
|
698 | 707 | return send(false, args);
|
699 | 708 | }
|
|
748 | 757 | return result;
|
749 | 758 | },
|
750 | 759 |
|
751 |
| - // File Normalization for Gecko 1.9.1 (Firefox 3.5) support: |
752 |
| - _normalizeFile: function (index, file) { |
753 |
| - if (file.name === undefined && file.size === undefined) { |
754 |
| - file.name = file.fileName; |
755 |
| - file.size = file.fileSize; |
756 |
| - } |
757 |
| - }, |
758 |
| - |
759 | 760 | _replaceFileInput: function (input) {
|
760 | 761 | var inputClone = input.clone(true);
|
761 | 762 | $('<form></form>').append(inputClone)[0].reset();
|
|
780 | 781 | }
|
781 | 782 | },
|
782 | 783 |
|
| 784 | + _handleFileTreeEntry: function (entry, path) { |
| 785 | + var that = this, |
| 786 | + dfd = $.Deferred(), |
| 787 | + errorHandler = function () { |
| 788 | + dfd.reject(); |
| 789 | + }, |
| 790 | + dirReader; |
| 791 | + path = path || ''; |
| 792 | + if (entry.isFile) { |
| 793 | + entry.file(function (file) { |
| 794 | + file.relativePath = path; |
| 795 | + dfd.resolve(file); |
| 796 | + }, errorHandler); |
| 797 | + } else if (entry.isDirectory) { |
| 798 | + dirReader = entry.createReader(); |
| 799 | + dirReader.readEntries(function (entries) { |
| 800 | + that._handleFileTreeEntries( |
| 801 | + entries, |
| 802 | + path + entry.name + '/' |
| 803 | + ).done(function (files) { |
| 804 | + dfd.resolve(files); |
| 805 | + }).fail(errorHandler); |
| 806 | + }, errorHandler); |
| 807 | + } else { |
| 808 | + errorHandler(); |
| 809 | + } |
| 810 | + return dfd.promise(); |
| 811 | + }, |
| 812 | + |
| 813 | + _handleFileTreeEntries: function (entries, path) { |
| 814 | + var that = this; |
| 815 | + return $.when.apply( |
| 816 | + $, |
| 817 | + $.map(entries, function (entry) { |
| 818 | + return that._handleFileTreeEntry(entry, path); |
| 819 | + }) |
| 820 | + ).pipe(function () { |
| 821 | + return Array.prototype.concat.apply( |
| 822 | + [], |
| 823 | + arguments |
| 824 | + ); |
| 825 | + }); |
| 826 | + }, |
| 827 | + |
| 828 | + _getDroppedFiles: function (dataTransfer) { |
| 829 | + dataTransfer = dataTransfer || {}; |
| 830 | + var items = dataTransfer.items; |
| 831 | + if (items && items.length && (items[0].webkitGetAsEntry || |
| 832 | + items[0].getAsEntry)) { |
| 833 | + return this._handleFileTreeEntries( |
| 834 | + $.map(items, function (item) { |
| 835 | + if (item.webkitGetAsEntry) { |
| 836 | + return item.webkitGetAsEntry(); |
| 837 | + } |
| 838 | + return item.getAsEntry(); |
| 839 | + }) |
| 840 | + ); |
| 841 | + } |
| 842 | + return $.Deferred().resolve( |
| 843 | + $.makeArray(dataTransfer.files) |
| 844 | + ).promise(); |
| 845 | + }, |
| 846 | + |
783 | 847 | _getFileInputFiles: function (fileInput) {
|
784 | 848 | fileInput = $(fileInput);
|
785 |
| - var files = $.each($.makeArray(fileInput.prop('files')), this._normalizeFile), |
| 849 | + var entries = fileInput.prop('webkitEntries') || |
| 850 | + fileInput.prop('entries'), |
| 851 | + files, |
786 | 852 | value;
|
| 853 | + if (entries) { |
| 854 | + return this._handleFileTreeEntries(entries); |
| 855 | + } |
| 856 | + files = $.makeArray(fileInput.prop('files')); |
787 | 857 | if (!files.length) {
|
788 | 858 | value = fileInput.prop('value');
|
789 | 859 | if (!value) {
|
790 |
| - return []; |
| 860 | + return $.Deferred().reject([]).promise(); |
791 | 861 | }
|
792 | 862 | // If the files property is not available, the browser does not
|
793 | 863 | // support the File API and we add a pseudo File object with
|
794 | 864 | // the input value as name with path information removed:
|
795 | 865 | files = [{name: value.replace(/^.*\\/, '')}];
|
796 | 866 | }
|
797 |
| - return files; |
| 867 | + return $.Deferred().resolve(files).promise(); |
798 | 868 | },
|
799 | 869 |
|
800 | 870 | _onChange: function (e) {
|
|
803 | 873 | fileInput: $(e.target),
|
804 | 874 | form: $(e.target.form)
|
805 | 875 | };
|
806 |
| - data.files = that._getFileInputFiles(data.fileInput); |
807 |
| - if (that.options.replaceFileInput) { |
808 |
| - that._replaceFileInput(data.fileInput); |
809 |
| - } |
810 |
| - if (that._trigger('change', e, data) === false || |
811 |
| - that._onAdd(e, data) === false) { |
812 |
| - return false; |
813 |
| - } |
| 876 | + that._getFileInputFiles(data.fileInput).always(function (files) { |
| 877 | + data.files = files; |
| 878 | + if (that.options.replaceFileInput) { |
| 879 | + that._replaceFileInput(data.fileInput); |
| 880 | + } |
| 881 | + if (that._trigger('change', e, data) !== false) { |
| 882 | + that._onAdd(e, data); |
| 883 | + } |
| 884 | + }); |
814 | 885 | },
|
815 | 886 |
|
816 | 887 | _onPaste: function (e) {
|
|
831 | 902 | },
|
832 | 903 |
|
833 | 904 | _onDrop: function (e) {
|
| 905 | + e.preventDefault(); |
834 | 906 | var that = e.data.fileupload,
|
835 | 907 | dataTransfer = e.dataTransfer = e.originalEvent.dataTransfer,
|
836 |
| - data = { |
837 |
| - files: $.each( |
838 |
| - $.makeArray(dataTransfer && dataTransfer.files), |
839 |
| - that._normalizeFile |
840 |
| - ) |
841 |
| - }; |
842 |
| - if (that._trigger('drop', e, data) === false || |
843 |
| - that._onAdd(e, data) === false) { |
844 |
| - return false; |
845 |
| - } |
846 |
| - e.preventDefault(); |
| 908 | + data = {}; |
| 909 | + that._getDroppedFiles(dataTransfer).always(function (files) { |
| 910 | + data.files = files; |
| 911 | + if (that._trigger('drop', e, data) !== false) { |
| 912 | + that._onAdd(e, data); |
| 913 | + } |
| 914 | + }); |
847 | 915 | },
|
848 | 916 |
|
849 | 917 | _onDragOver: function (e) {
|
|
937 | 1005 | // must have a files property and can contain additional options:
|
938 | 1006 | // .fileupload('add', {files: filesList});
|
939 | 1007 | add: function (data) {
|
| 1008 | + var that = this; |
940 | 1009 | if (!data || this.options.disabled) {
|
941 | 1010 | return;
|
942 | 1011 | }
|
943 | 1012 | if (data.fileInput && !data.files) {
|
944 |
| - data.files = this._getFileInputFiles(data.fileInput); |
| 1013 | + this._getFileInputFiles(data.fileInput).always(function (files) { |
| 1014 | + data.files = files; |
| 1015 | + that._onAdd(null, data); |
| 1016 | + }); |
945 | 1017 | } else {
|
946 |
| - data.files = $.each($.makeArray(data.files), this._normalizeFile); |
| 1018 | + data.files = $.makeArray(data.files); |
| 1019 | + this._onAdd(null, data); |
947 | 1020 | }
|
948 |
| - this._onAdd(null, data); |
949 | 1021 | },
|
950 | 1022 |
|
951 | 1023 | // This method is exposed to the widget API and allows sending files
|
952 | 1024 | // using the fileupload API. The data parameter accepts an object which
|
953 |
| - // must have a files property and can contain additional options: |
| 1025 | + // must have a files or fileInput property and can contain additional options: |
954 | 1026 | // .fileupload('send', {files: filesList});
|
955 | 1027 | // The method returns a Promise object for the file upload call.
|
956 | 1028 | send: function (data) {
|
957 | 1029 | if (data && !this.options.disabled) {
|
958 | 1030 | if (data.fileInput && !data.files) {
|
959 |
| - data.files = this._getFileInputFiles(data.fileInput); |
960 |
| - } else { |
961 |
| - data.files = $.each($.makeArray(data.files), this._normalizeFile); |
| 1031 | + var that = this, |
| 1032 | + dfd = $.Deferred(), |
| 1033 | + promise = dfd.promise(), |
| 1034 | + jqXHR, |
| 1035 | + aborted; |
| 1036 | + promise.abort = function () { |
| 1037 | + aborted = true; |
| 1038 | + if (jqXHR) { |
| 1039 | + return jqXHR.abort(); |
| 1040 | + } |
| 1041 | + dfd.reject(null, 'abort', 'abort'); |
| 1042 | + return promise; |
| 1043 | + }; |
| 1044 | + this._getFileInputFiles(data.fileInput).always( |
| 1045 | + function (files) { |
| 1046 | + if (aborted) { |
| 1047 | + return; |
| 1048 | + } |
| 1049 | + data.files = files; |
| 1050 | + jqXHR = that._onSend(null, data).then( |
| 1051 | + function (result, textStatus, jqXHR) { |
| 1052 | + dfd.resolve(result, textStatus, jqXHR); |
| 1053 | + }, |
| 1054 | + function (jqXHR, textStatus, errorThrown) { |
| 1055 | + dfd.reject(jqXHR, textStatus, errorThrown); |
| 1056 | + } |
| 1057 | + ); |
| 1058 | + } |
| 1059 | + ); |
| 1060 | + return this._enhancePromise(promise); |
962 | 1061 | }
|
| 1062 | + data.files = $.makeArray(data.files); |
963 | 1063 | if (data.files.length) {
|
964 | 1064 | return this._onSend(null, data);
|
965 | 1065 | }
|
|
0 commit comments