jquery.fileupload-rails 0.1.2 → 1.0.0.alpha
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitmodules +3 -0
- data/Rakefile +40 -1
- data/Readme.md +8 -2
- data/dependencies.json +4 -0
- data/jquery.fileupload-rails.gemspec +1 -0
- data/lib/jquery.fileupload-rails/version.rb +1 -1
- data/vendor/assets/javascripts/jquery.fileupload.js +232 -60
- data/vendor/assets/javascripts/jquery.iframe-transport.js +2 -1
- metadata +24 -11
- data/vendor/assets/javascripts/jquery.fileupload-fp.js +0 -219
- data/vendor/assets/javascripts/jquery.fileupload-ip.js +0 -160
- data/vendor/assets/javascripts/jquery.fileupload-ui.js +0 -702
- data/vendor/assets/javascripts/jquery.postmessage-transport.js +0 -117
- data/vendor/assets/javascripts/jquery.xdr-transport.js +0 -85
- data/vendor/assets/stylesheets/jquery.fileupload-ui.css +0 -84
data/.gitmodules
ADDED
data/Rakefile
CHANGED
@@ -1 +1,40 @@
|
|
1
|
-
require
|
1
|
+
require 'json'
|
2
|
+
require 'bundler/gem_tasks'
|
3
|
+
|
4
|
+
DEPENDENCY_HASH = JSON.load(File.read('dependencies.json'))
|
5
|
+
PROJECT_NAME = "jQuery-File-Upload"
|
6
|
+
|
7
|
+
task :submodule do
|
8
|
+
sh 'git submodule update --init' unless File.exist?("#{PROJECT_NAME}/README.md")
|
9
|
+
end
|
10
|
+
|
11
|
+
desc "Remove the vendor directory"
|
12
|
+
task :clean do
|
13
|
+
rm_rf 'vendor'
|
14
|
+
end
|
15
|
+
|
16
|
+
desc "Generate the JavaScript assets"
|
17
|
+
task :javascripts => :submodule do
|
18
|
+
target_dir = "vendor/assets/javascripts"
|
19
|
+
mkdir_p target_dir
|
20
|
+
Rake.rake_output_message 'Generating javascripts'
|
21
|
+
DEPENDENCY_HASH.each do |name, dep_modules|
|
22
|
+
path = "#{PROJECT_NAME}/js/#{name}.js"
|
23
|
+
File.open("#{target_dir}/#{name}.js", "w") do |out|
|
24
|
+
dep_modules.each do |mod|
|
25
|
+
out.write("//= require #{mod}\n")
|
26
|
+
end
|
27
|
+
out.write("\n") unless dep_modules.empty?
|
28
|
+
source_code = File.read(path)
|
29
|
+
out.write(source_code)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
desc "Clean and then generate everything (default)"
|
35
|
+
task :assets => [:clean, :javascripts]
|
36
|
+
|
37
|
+
task :build => :assets
|
38
|
+
|
39
|
+
task :default => :assets
|
40
|
+
|
data/Readme.md
CHANGED
@@ -9,6 +9,12 @@ This is a simple gem package for this plugin.
|
|
9
9
|
|
10
10
|
## Changelog
|
11
11
|
|
12
|
+
1.0.0.alpha. Core 5.17.2, added jquery-ui-rails dependency.
|
13
|
+
|
14
|
+
Now rake task generates assets from official repo and adds dependencies automatically.
|
15
|
+
That means you can just require jquery.fileupload, no extra requires needed.
|
16
|
+
UI stuff is removed temporarily.
|
17
|
+
|
12
18
|
0.1.2. Fixed CSS that makes SASS 3.2 raise an error on rake assets:precompile
|
13
19
|
|
14
20
|
0.1.1. Core 5.11.2, UI 6.9.1, minor gemspec change.
|
@@ -19,8 +25,8 @@ This is a simple gem package for this plugin.
|
|
19
25
|
|
20
26
|
## Todo
|
21
27
|
|
22
|
-
*
|
28
|
+
* Import UI js/css/images in rake task too. Need to fix relative paths to images. See [jquery-ui-rails][2].
|
23
29
|
* Add example usage in Rails here.
|
24
|
-
* Add script to automate updating the library from [the official repo][1].
|
25
30
|
|
26
31
|
[1]: https://github.com/blueimp/jQuery-File-Upload
|
32
|
+
[2]: https://github.com/joliss/jquery-ui-rails
|
data/dependencies.json
ADDED
@@ -1,5 +1,8 @@
|
|
1
|
+
//= require jquery.ui.widget
|
2
|
+
//= require jquery.iframe-transport
|
3
|
+
|
1
4
|
/*
|
2
|
-
* jQuery File Upload Plugin 5.
|
5
|
+
* jQuery File Upload Plugin 5.17.2
|
3
6
|
* https://github.com/blueimp/jQuery-File-Upload
|
4
7
|
*
|
5
8
|
* Copyright 2010, Sebastian Tschan
|
@@ -44,17 +47,20 @@
|
|
44
47
|
$.widget('blueimp.fileupload', {
|
45
48
|
|
46
49
|
options: {
|
47
|
-
// The namespace used for event handler binding on the
|
48
|
-
//
|
50
|
+
// The namespace used for event handler binding on the fileInput,
|
51
|
+
// dropZone and pasteZone document nodes.
|
49
52
|
// If not set, the name of the widget ("fileupload") is used.
|
50
53
|
namespace: undefined,
|
51
|
-
// The drop target
|
52
|
-
// Set to null
|
54
|
+
// The drop target element(s), by the default the complete document.
|
55
|
+
// Set to null to disable drag & drop support:
|
53
56
|
dropZone: $(document),
|
54
|
-
// The
|
57
|
+
// The paste target element(s), by the default the complete document.
|
58
|
+
// Set to null to disable paste support:
|
59
|
+
pasteZone: $(document),
|
60
|
+
// The file input field(s), that are listened to for change events.
|
55
61
|
// If undefined, it is set to the file input fields inside
|
56
62
|
// of the widget element on plugin initialization.
|
57
|
-
// Set to null
|
63
|
+
// Set to null to disable the change listener.
|
58
64
|
fileInput: undefined,
|
59
65
|
// By default, the file input field is replaced with a clone after
|
60
66
|
// each input field change event. This is required for iframe transport
|
@@ -159,13 +165,13 @@
|
|
159
165
|
// start: function (e) {}, // .bind('fileuploadstart', func);
|
160
166
|
// Callback for uploads stop, equivalent to the global ajaxStop event:
|
161
167
|
// stop: function (e) {}, // .bind('fileuploadstop', func);
|
162
|
-
// Callback for change events of the fileInput
|
168
|
+
// Callback for change events of the fileInput(s):
|
163
169
|
// change: function (e, data) {}, // .bind('fileuploadchange', func);
|
164
|
-
// Callback for paste events to the
|
170
|
+
// Callback for paste events to the pasteZone(s):
|
165
171
|
// paste: function (e, data) {}, // .bind('fileuploadpaste', func);
|
166
|
-
// Callback for drop events of the dropZone
|
172
|
+
// Callback for drop events of the dropZone(s):
|
167
173
|
// drop: function (e, data) {}, // .bind('fileuploaddrop', func);
|
168
|
-
// Callback for dragover events of the dropZone
|
174
|
+
// Callback for dragover events of the dropZone(s):
|
169
175
|
// dragover: function (e) {}, // .bind('fileuploaddragover', func);
|
170
176
|
|
171
177
|
// The plugin options are used as settings object for the ajax calls.
|
@@ -178,8 +184,9 @@
|
|
178
184
|
// A list of options that require a refresh after assigning a new value:
|
179
185
|
_refreshOptionsList: [
|
180
186
|
'namespace',
|
181
|
-
'dropZone',
|
182
187
|
'fileInput',
|
188
|
+
'dropZone',
|
189
|
+
'pasteZone',
|
183
190
|
'multipart',
|
184
191
|
'forceIframeTransport'
|
185
192
|
],
|
@@ -436,6 +443,11 @@
|
|
436
443
|
// associated form, if available:
|
437
444
|
if (!options.form || !options.form.length) {
|
438
445
|
options.form = $(options.fileInput.prop('form'));
|
446
|
+
// If the given file input doesn't have an associated form,
|
447
|
+
// use the default widget file input's form:
|
448
|
+
if (!options.form.length) {
|
449
|
+
options.form = $(this.options.fileInput.prop('form'));
|
450
|
+
}
|
439
451
|
}
|
440
452
|
options.paramName = this._getParamName(options);
|
441
453
|
if (!options.url) {
|
@@ -447,6 +459,9 @@
|
|
447
459
|
if (options.type !== 'POST' && options.type !== 'PUT') {
|
448
460
|
options.type = 'POST';
|
449
461
|
}
|
462
|
+
if (!options.formAcceptCharset) {
|
463
|
+
options.formAcceptCharset = options.form.attr('accept-charset');
|
464
|
+
}
|
450
465
|
},
|
451
466
|
|
452
467
|
_getAJAXSettings: function (data) {
|
@@ -530,6 +545,10 @@
|
|
530
545
|
ub + i * mcs,
|
531
546
|
ub + (i + 1) * mcs
|
532
547
|
);
|
548
|
+
// Expose the chunk index:
|
549
|
+
o.chunkIndex = i;
|
550
|
+
// Expose the number of chunks:
|
551
|
+
o.chunksNumber = n;
|
533
552
|
// Store the current chunk size, as the blob itself
|
534
553
|
// will be dereferenced after data processing:
|
535
554
|
o.chunkSize = o.blob.size;
|
@@ -659,9 +678,15 @@
|
|
659
678
|
options.limitConcurrentUploads > that._sending) {
|
660
679
|
// Start the next queued upload,
|
661
680
|
// that has not been aborted:
|
662
|
-
var nextSlot = that._slots.shift()
|
681
|
+
var nextSlot = that._slots.shift(),
|
682
|
+
isPending;
|
663
683
|
while (nextSlot) {
|
664
|
-
|
684
|
+
// jQuery 1.6 doesn't provide .state(),
|
685
|
+
// while jQuery 1.8+ removed .isRejected():
|
686
|
+
isPending = nextSlot.state ?
|
687
|
+
nextSlot.state() === 'pending' :
|
688
|
+
!nextSlot.isRejected();
|
689
|
+
if (isPending) {
|
665
690
|
nextSlot.resolve();
|
666
691
|
break;
|
667
692
|
}
|
@@ -689,7 +714,7 @@
|
|
689
714
|
var args = [undefined, 'abort', 'abort'];
|
690
715
|
if (!jqXHR) {
|
691
716
|
if (slot) {
|
692
|
-
slot.rejectWith(args);
|
717
|
+
slot.rejectWith(pipe, args);
|
693
718
|
}
|
694
719
|
return send(false, args);
|
695
720
|
}
|
@@ -744,14 +769,6 @@
|
|
744
769
|
return result;
|
745
770
|
},
|
746
771
|
|
747
|
-
// File Normalization for Gecko 1.9.1 (Firefox 3.5) support:
|
748
|
-
_normalizeFile: function (index, file) {
|
749
|
-
if (file.name === undefined && file.size === undefined) {
|
750
|
-
file.name = file.fileName;
|
751
|
-
file.size = file.fileSize;
|
752
|
-
}
|
753
|
-
},
|
754
|
-
|
755
772
|
_replaceFileInput: function (input) {
|
756
773
|
var inputClone = input.clone(true);
|
757
774
|
$('<form></form>').append(inputClone)[0].reset();
|
@@ -761,7 +778,7 @@
|
|
761
778
|
// Avoid memory leaks with the detached file input:
|
762
779
|
$.cleanData(input.unbind('remove'));
|
763
780
|
// Replace the original file input element in the fileInput
|
764
|
-
//
|
781
|
+
// elements set with the clone, which has been copied including
|
765
782
|
// event handlers:
|
766
783
|
this.options.fileInput = this.options.fileInput.map(function (i, el) {
|
767
784
|
if (el === input[0]) {
|
@@ -776,26 +793,131 @@
|
|
776
793
|
}
|
777
794
|
},
|
778
795
|
|
796
|
+
_handleFileTreeEntry: function (entry, path) {
|
797
|
+
var that = this,
|
798
|
+
dfd = $.Deferred(),
|
799
|
+
errorHandler = function (e) {
|
800
|
+
if (e && !e.entry) {
|
801
|
+
e.entry = entry;
|
802
|
+
}
|
803
|
+
// Since $.when returns immediately if one
|
804
|
+
// Deferred is rejected, we use resolve instead.
|
805
|
+
// This allows valid files and invalid items
|
806
|
+
// to be returned together in one set:
|
807
|
+
dfd.resolve([e]);
|
808
|
+
},
|
809
|
+
dirReader;
|
810
|
+
path = path || '';
|
811
|
+
if (entry.isFile) {
|
812
|
+
entry.file(function (file) {
|
813
|
+
file.relativePath = path;
|
814
|
+
dfd.resolve(file);
|
815
|
+
}, errorHandler);
|
816
|
+
} else if (entry.isDirectory) {
|
817
|
+
dirReader = entry.createReader();
|
818
|
+
dirReader.readEntries(function (entries) {
|
819
|
+
that._handleFileTreeEntries(
|
820
|
+
entries,
|
821
|
+
path + entry.name + '/'
|
822
|
+
).done(function (files) {
|
823
|
+
dfd.resolve(files);
|
824
|
+
}).fail(errorHandler);
|
825
|
+
}, errorHandler);
|
826
|
+
} else {
|
827
|
+
// Return an empy list for file system items
|
828
|
+
// other than files or directories:
|
829
|
+
dfd.resolve([]);
|
830
|
+
}
|
831
|
+
return dfd.promise();
|
832
|
+
},
|
833
|
+
|
834
|
+
_handleFileTreeEntries: function (entries, path) {
|
835
|
+
var that = this;
|
836
|
+
return $.when.apply(
|
837
|
+
$,
|
838
|
+
$.map(entries, function (entry) {
|
839
|
+
return that._handleFileTreeEntry(entry, path);
|
840
|
+
})
|
841
|
+
).pipe(function () {
|
842
|
+
return Array.prototype.concat.apply(
|
843
|
+
[],
|
844
|
+
arguments
|
845
|
+
);
|
846
|
+
});
|
847
|
+
},
|
848
|
+
|
849
|
+
_getDroppedFiles: function (dataTransfer) {
|
850
|
+
dataTransfer = dataTransfer || {};
|
851
|
+
var items = dataTransfer.items;
|
852
|
+
if (items && items.length && (items[0].webkitGetAsEntry ||
|
853
|
+
items[0].getAsEntry)) {
|
854
|
+
return this._handleFileTreeEntries(
|
855
|
+
$.map(items, function (item) {
|
856
|
+
if (item.webkitGetAsEntry) {
|
857
|
+
return item.webkitGetAsEntry();
|
858
|
+
}
|
859
|
+
return item.getAsEntry();
|
860
|
+
})
|
861
|
+
);
|
862
|
+
}
|
863
|
+
return $.Deferred().resolve(
|
864
|
+
$.makeArray(dataTransfer.files)
|
865
|
+
).promise();
|
866
|
+
},
|
867
|
+
|
868
|
+
_getSingleFileInputFiles: function (fileInput) {
|
869
|
+
fileInput = $(fileInput);
|
870
|
+
var entries = fileInput.prop('webkitEntries') ||
|
871
|
+
fileInput.prop('entries'),
|
872
|
+
files,
|
873
|
+
value;
|
874
|
+
if (entries && entries.length) {
|
875
|
+
return this._handleFileTreeEntries(entries);
|
876
|
+
}
|
877
|
+
files = $.makeArray(fileInput.prop('files'));
|
878
|
+
if (!files.length) {
|
879
|
+
value = fileInput.prop('value');
|
880
|
+
if (!value) {
|
881
|
+
return $.Deferred().resolve([]).promise();
|
882
|
+
}
|
883
|
+
// If the files property is not available, the browser does not
|
884
|
+
// support the File API and we add a pseudo File object with
|
885
|
+
// the input value as name with path information removed:
|
886
|
+
files = [{name: value.replace(/^.*\\/, '')}];
|
887
|
+
}
|
888
|
+
return $.Deferred().resolve(files).promise();
|
889
|
+
},
|
890
|
+
|
891
|
+
_getFileInputFiles: function (fileInput) {
|
892
|
+
if (!(fileInput instanceof $) || fileInput.length === 1) {
|
893
|
+
return this._getSingleFileInputFiles(fileInput);
|
894
|
+
}
|
895
|
+
return $.when.apply(
|
896
|
+
$,
|
897
|
+
$.map(fileInput, this._getSingleFileInputFiles)
|
898
|
+
).pipe(function () {
|
899
|
+
return Array.prototype.concat.apply(
|
900
|
+
[],
|
901
|
+
arguments
|
902
|
+
);
|
903
|
+
});
|
904
|
+
},
|
905
|
+
|
779
906
|
_onChange: function (e) {
|
780
907
|
var that = e.data.fileupload,
|
781
908
|
data = {
|
782
|
-
files: $.each($.makeArray(e.target.files), that._normalizeFile),
|
783
909
|
fileInput: $(e.target),
|
784
910
|
form: $(e.target.form)
|
785
911
|
};
|
786
|
-
|
787
|
-
|
788
|
-
|
789
|
-
|
790
|
-
|
791
|
-
|
792
|
-
|
793
|
-
|
794
|
-
}
|
795
|
-
if (that._trigger('change', e, data) === false ||
|
796
|
-
that._onAdd(e, data) === false) {
|
797
|
-
return false;
|
798
|
-
}
|
912
|
+
that._getFileInputFiles(data.fileInput).always(function (files) {
|
913
|
+
data.files = files;
|
914
|
+
if (that.options.replaceFileInput) {
|
915
|
+
that._replaceFileInput(data.fileInput);
|
916
|
+
}
|
917
|
+
if (that._trigger('change', e, data) !== false) {
|
918
|
+
that._onAdd(e, data);
|
919
|
+
}
|
920
|
+
});
|
799
921
|
},
|
800
922
|
|
801
923
|
_onPaste: function (e) {
|
@@ -816,19 +938,16 @@
|
|
816
938
|
},
|
817
939
|
|
818
940
|
_onDrop: function (e) {
|
941
|
+
e.preventDefault();
|
819
942
|
var that = e.data.fileupload,
|
820
943
|
dataTransfer = e.dataTransfer = e.originalEvent.dataTransfer,
|
821
|
-
data = {
|
822
|
-
|
823
|
-
|
824
|
-
|
825
|
-
)
|
826
|
-
}
|
827
|
-
|
828
|
-
that._onAdd(e, data) === false) {
|
829
|
-
return false;
|
830
|
-
}
|
831
|
-
e.preventDefault();
|
944
|
+
data = {};
|
945
|
+
that._getDroppedFiles(dataTransfer).always(function (files) {
|
946
|
+
data.files = files;
|
947
|
+
if (that._trigger('drop', e, data) !== false) {
|
948
|
+
that._onAdd(e, data);
|
949
|
+
}
|
950
|
+
});
|
832
951
|
},
|
833
952
|
|
834
953
|
_onDragOver: function (e) {
|
@@ -838,7 +957,7 @@
|
|
838
957
|
return false;
|
839
958
|
}
|
840
959
|
if (dataTransfer) {
|
841
|
-
dataTransfer.dropEffect =
|
960
|
+
dataTransfer.dropEffect = 'copy';
|
842
961
|
}
|
843
962
|
e.preventDefault();
|
844
963
|
},
|
@@ -848,7 +967,8 @@
|
|
848
967
|
if (this._isXHRUpload(this.options)) {
|
849
968
|
this.options.dropZone
|
850
969
|
.bind('dragover.' + ns, {fileupload: this}, this._onDragOver)
|
851
|
-
.bind('drop.' + ns, {fileupload: this}, this._onDrop)
|
970
|
+
.bind('drop.' + ns, {fileupload: this}, this._onDrop);
|
971
|
+
this.options.pasteZone
|
852
972
|
.bind('paste.' + ns, {fileupload: this}, this._onPaste);
|
853
973
|
}
|
854
974
|
this.options.fileInput
|
@@ -859,7 +979,8 @@
|
|
859
979
|
var ns = this.options.namespace;
|
860
980
|
this.options.dropZone
|
861
981
|
.unbind('dragover.' + ns, this._onDragOver)
|
862
|
-
.unbind('drop.' + ns, this._onDrop)
|
982
|
+
.unbind('drop.' + ns, this._onDrop);
|
983
|
+
this.options.pasteZone
|
863
984
|
.unbind('paste.' + ns, this._onPaste);
|
864
985
|
this.options.fileInput
|
865
986
|
.unbind('change.' + ns, this._onChange);
|
@@ -880,14 +1001,17 @@
|
|
880
1001
|
_initSpecialOptions: function () {
|
881
1002
|
var options = this.options;
|
882
1003
|
if (options.fileInput === undefined) {
|
883
|
-
options.fileInput = this.element.is('input
|
884
|
-
this.element : this.element.find('input
|
1004
|
+
options.fileInput = this.element.is('input[type="file"]') ?
|
1005
|
+
this.element : this.element.find('input[type="file"]');
|
885
1006
|
} else if (!(options.fileInput instanceof $)) {
|
886
1007
|
options.fileInput = $(options.fileInput);
|
887
1008
|
}
|
888
1009
|
if (!(options.dropZone instanceof $)) {
|
889
1010
|
options.dropZone = $(options.dropZone);
|
890
1011
|
}
|
1012
|
+
if (!(options.pasteZone instanceof $)) {
|
1013
|
+
options.pasteZone = $(options.pasteZone);
|
1014
|
+
}
|
891
1015
|
},
|
892
1016
|
|
893
1017
|
_create: function () {
|
@@ -908,12 +1032,20 @@
|
|
908
1032
|
},
|
909
1033
|
|
910
1034
|
enable: function () {
|
1035
|
+
var wasDisabled = false;
|
1036
|
+
if (this.options.disabled) {
|
1037
|
+
wasDisabled = true;
|
1038
|
+
}
|
911
1039
|
$.Widget.prototype.enable.call(this);
|
912
|
-
|
1040
|
+
if (wasDisabled) {
|
1041
|
+
this._initEventHandlers();
|
1042
|
+
}
|
913
1043
|
},
|
914
1044
|
|
915
1045
|
disable: function () {
|
916
|
-
this.
|
1046
|
+
if (!this.options.disabled) {
|
1047
|
+
this._destroyEventHandlers();
|
1048
|
+
}
|
917
1049
|
$.Widget.prototype.disable.call(this);
|
918
1050
|
},
|
919
1051
|
|
@@ -922,21 +1054,61 @@
|
|
922
1054
|
// must have a files property and can contain additional options:
|
923
1055
|
// .fileupload('add', {files: filesList});
|
924
1056
|
add: function (data) {
|
1057
|
+
var that = this;
|
925
1058
|
if (!data || this.options.disabled) {
|
926
1059
|
return;
|
927
1060
|
}
|
928
|
-
data.
|
929
|
-
|
1061
|
+
if (data.fileInput && !data.files) {
|
1062
|
+
this._getFileInputFiles(data.fileInput).always(function (files) {
|
1063
|
+
data.files = files;
|
1064
|
+
that._onAdd(null, data);
|
1065
|
+
});
|
1066
|
+
} else {
|
1067
|
+
data.files = $.makeArray(data.files);
|
1068
|
+
this._onAdd(null, data);
|
1069
|
+
}
|
930
1070
|
},
|
931
1071
|
|
932
1072
|
// This method is exposed to the widget API and allows sending files
|
933
1073
|
// using the fileupload API. The data parameter accepts an object which
|
934
|
-
// must have a files property and can contain additional options:
|
1074
|
+
// must have a files or fileInput property and can contain additional options:
|
935
1075
|
// .fileupload('send', {files: filesList});
|
936
1076
|
// The method returns a Promise object for the file upload call.
|
937
1077
|
send: function (data) {
|
938
1078
|
if (data && !this.options.disabled) {
|
939
|
-
data.
|
1079
|
+
if (data.fileInput && !data.files) {
|
1080
|
+
var that = this,
|
1081
|
+
dfd = $.Deferred(),
|
1082
|
+
promise = dfd.promise(),
|
1083
|
+
jqXHR,
|
1084
|
+
aborted;
|
1085
|
+
promise.abort = function () {
|
1086
|
+
aborted = true;
|
1087
|
+
if (jqXHR) {
|
1088
|
+
return jqXHR.abort();
|
1089
|
+
}
|
1090
|
+
dfd.reject(null, 'abort', 'abort');
|
1091
|
+
return promise;
|
1092
|
+
};
|
1093
|
+
this._getFileInputFiles(data.fileInput).always(
|
1094
|
+
function (files) {
|
1095
|
+
if (aborted) {
|
1096
|
+
return;
|
1097
|
+
}
|
1098
|
+
data.files = files;
|
1099
|
+
jqXHR = that._onSend(null, data).then(
|
1100
|
+
function (result, textStatus, jqXHR) {
|
1101
|
+
dfd.resolve(result, textStatus, jqXHR);
|
1102
|
+
},
|
1103
|
+
function (jqXHR, textStatus, errorThrown) {
|
1104
|
+
dfd.reject(jqXHR, textStatus, errorThrown);
|
1105
|
+
}
|
1106
|
+
);
|
1107
|
+
}
|
1108
|
+
);
|
1109
|
+
return this._enhancePromise(promise);
|
1110
|
+
}
|
1111
|
+
data.files = $.makeArray(data.files);
|
940
1112
|
if (data.files.length) {
|
941
1113
|
return this._onSend(null, data);
|
942
1114
|
}
|