fine_uploader 3.1.1 → 3.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/LICENSE.txt +1 -3
- data/Vendorfile +16 -5
- data/lib/fine_uploader/version.rb +1 -1
- data/vendor/assets/javascripts/fine_uploader/ajax.requester.js +184 -0
- data/vendor/assets/javascripts/fine_uploader/button.js +62 -58
- data/vendor/assets/javascripts/fine_uploader/deletefile.ajax.requester.js +44 -0
- data/vendor/assets/javascripts/fine_uploader/dnd.js +2 -0
- data/vendor/assets/javascripts/fine_uploader/handler.base.js +164 -92
- data/vendor/assets/javascripts/fine_uploader/handler.form.js +220 -133
- data/vendor/assets/javascripts/fine_uploader/handler.xhr.js +594 -132
- data/vendor/assets/javascripts/fine_uploader/header.js +3 -4
- data/vendor/assets/javascripts/fine_uploader/iframe.xss.response.js +6 -0
- data/vendor/assets/javascripts/fine_uploader/jquery-plugin.js +13 -4
- data/vendor/assets/javascripts/fine_uploader/paste.js +49 -0
- data/vendor/assets/javascripts/fine_uploader/promise.js +45 -0
- data/vendor/assets/javascripts/fine_uploader/uploader.basic.js +547 -175
- data/vendor/assets/javascripts/fine_uploader/uploader.js +197 -42
- data/vendor/assets/javascripts/fine_uploader/util.js +117 -12
- data/vendor/assets/javascripts/fine_uploader/window.receive.message.js +32 -0
- data/vendor/assets/javascripts/fine_uploader.js +17 -0
- data/vendor/assets/stylesheets/fine_uploader.css.scss +6 -7
- metadata +9 -2
@@ -10,27 +10,40 @@ qq.FineUploaderBasic = function(o){
|
|
10
10
|
request: {
|
11
11
|
endpoint: '/server/upload',
|
12
12
|
params: {},
|
13
|
-
paramsInBody:
|
13
|
+
paramsInBody: true,
|
14
14
|
customHeaders: {},
|
15
|
-
forceMultipart:
|
16
|
-
inputName: 'qqfile'
|
15
|
+
forceMultipart: true,
|
16
|
+
inputName: 'qqfile',
|
17
|
+
uuidName: 'qquuid',
|
18
|
+
totalFileSizeName: 'qqtotalfilesize'
|
17
19
|
},
|
18
20
|
validation: {
|
19
21
|
allowedExtensions: [],
|
20
22
|
sizeLimit: 0,
|
21
23
|
minSizeLimit: 0,
|
24
|
+
itemLimit: 0,
|
22
25
|
stopOnFirstInvalidFile: true
|
23
26
|
},
|
24
27
|
callbacks: {
|
25
|
-
onSubmit: function(id,
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
28
|
+
onSubmit: function(id, name){},
|
29
|
+
onSubmitted: function(id, name){},
|
30
|
+
onComplete: function(id, name, responseJSON){},
|
31
|
+
onCancel: function(id, name){},
|
32
|
+
onUpload: function(id, name){},
|
33
|
+
onUploadChunk: function(id, name, chunkData){},
|
34
|
+
onResume: function(id, fileName, chunkData){},
|
35
|
+
onProgress: function(id, name, loaded, total){},
|
36
|
+
onError: function(id, name, reason, maybeXhr) {},
|
37
|
+
onAutoRetry: function(id, name, attemptNumber) {},
|
38
|
+
onManualRetry: function(id, name) {},
|
39
|
+
onValidateBatch: function(fileOrBlobData) {},
|
40
|
+
onValidate: function(fileOrBlobData) {},
|
41
|
+
onSubmitDelete: function(id) {},
|
42
|
+
onDelete: function(id){},
|
43
|
+
onDeleteComplete: function(id, xhr, isError){},
|
44
|
+
onPasteReceived: function(blob) {
|
45
|
+
return new qq.Promise().success();
|
46
|
+
}
|
34
47
|
},
|
35
48
|
messages: {
|
36
49
|
typeError: "{file} has an invalid extension. Valid extension(s): {extensions}.",
|
@@ -38,6 +51,8 @@ qq.FineUploaderBasic = function(o){
|
|
38
51
|
minSizeError: "{file} is too small, minimum file size is {minSizeLimit}.",
|
39
52
|
emptyError: "{file} is empty, please select files again without it.",
|
40
53
|
noFilesError: "No files to upload.",
|
54
|
+
tooManyItemsError: "Too many items ({netItems}) would be uploaded. Item limit is {itemLimit}.",
|
55
|
+
retryFailTooManyItems: "Retry failed - you have reached your file limit.",
|
41
56
|
onLeave: "The files are being uploaded, if you leave now the upload will be cancelled."
|
42
57
|
},
|
43
58
|
retry: {
|
@@ -49,6 +64,55 @@ qq.FineUploaderBasic = function(o){
|
|
49
64
|
classes: {
|
50
65
|
buttonHover: 'qq-upload-button-hover',
|
51
66
|
buttonFocus: 'qq-upload-button-focus'
|
67
|
+
},
|
68
|
+
chunking: {
|
69
|
+
enabled: false,
|
70
|
+
partSize: 2000000,
|
71
|
+
paramNames: {
|
72
|
+
partIndex: 'qqpartindex',
|
73
|
+
partByteOffset: 'qqpartbyteoffset',
|
74
|
+
chunkSize: 'qqchunksize',
|
75
|
+
totalFileSize: 'qqtotalfilesize',
|
76
|
+
totalParts: 'qqtotalparts',
|
77
|
+
filename: 'qqfilename'
|
78
|
+
}
|
79
|
+
},
|
80
|
+
resume: {
|
81
|
+
enabled: false,
|
82
|
+
id: null,
|
83
|
+
cookiesExpireIn: 7, //days
|
84
|
+
paramNames: {
|
85
|
+
resuming: "qqresume"
|
86
|
+
}
|
87
|
+
},
|
88
|
+
formatFileName: function(fileOrBlobName) {
|
89
|
+
if (fileOrBlobName.length > 33) {
|
90
|
+
fileOrBlobName = fileOrBlobName.slice(0, 19) + '...' + fileOrBlobName.slice(-14);
|
91
|
+
}
|
92
|
+
return fileOrBlobName;
|
93
|
+
},
|
94
|
+
text: {
|
95
|
+
sizeSymbols: ['kB', 'MB', 'GB', 'TB', 'PB', 'EB']
|
96
|
+
},
|
97
|
+
deleteFile : {
|
98
|
+
enabled: false,
|
99
|
+
endpoint: '/server/upload',
|
100
|
+
customHeaders: {},
|
101
|
+
params: {}
|
102
|
+
},
|
103
|
+
cors: {
|
104
|
+
expected: false,
|
105
|
+
sendCredentials: false
|
106
|
+
},
|
107
|
+
blobs: {
|
108
|
+
defaultName: 'misc_data',
|
109
|
+
paramNames: {
|
110
|
+
name: 'qqblobname'
|
111
|
+
}
|
112
|
+
},
|
113
|
+
paste: {
|
114
|
+
targetElement: null,
|
115
|
+
defaultName: 'pasted_image'
|
52
116
|
}
|
53
117
|
};
|
54
118
|
|
@@ -56,23 +120,30 @@ qq.FineUploaderBasic = function(o){
|
|
56
120
|
this._wrapCallbacks();
|
57
121
|
this._disposeSupport = new qq.DisposeSupport();
|
58
122
|
|
59
|
-
|
60
|
-
this.
|
61
|
-
|
62
|
-
this._storedFileIds = [];
|
63
|
-
|
123
|
+
this._filesInProgress = [];
|
124
|
+
this._storedIds = [];
|
64
125
|
this._autoRetries = [];
|
65
126
|
this._retryTimeouts = [];
|
66
127
|
this._preventRetries = [];
|
128
|
+
this._netFilesUploadedOrQueued = 0;
|
129
|
+
|
130
|
+
this._paramsStore = this._createParamsStore("request");
|
131
|
+
this._deleteFileParamsStore = this._createParamsStore("deleteFile");
|
67
132
|
|
68
|
-
this.
|
133
|
+
this._endpointStore = this._createEndpointStore("request");
|
134
|
+
this._deleteFileEndpointStore = this._createEndpointStore("deleteFile");
|
69
135
|
|
70
136
|
this._handler = this._createUploadHandler();
|
137
|
+
this._deleteHandler = this._createDeleteHandler();
|
71
138
|
|
72
139
|
if (this._options.button){
|
73
140
|
this._button = this._createUploadButton(this._options.button);
|
74
141
|
}
|
75
142
|
|
143
|
+
if (this._options.paste.targetElement) {
|
144
|
+
this._pasteHandler = this._createPasteHandler();
|
145
|
+
}
|
146
|
+
|
76
147
|
this._preventLeaveInProgress();
|
77
148
|
};
|
78
149
|
|
@@ -86,29 +157,52 @@ qq.FineUploaderBasic.prototype = {
|
|
86
157
|
|
87
158
|
}
|
88
159
|
},
|
89
|
-
setParams: function(params,
|
90
|
-
|
160
|
+
setParams: function(params, id) {
|
161
|
+
/*jshint eqeqeq: true, eqnull: true*/
|
162
|
+
if (id == null) {
|
91
163
|
this._options.request.params = params;
|
92
164
|
}
|
93
165
|
else {
|
94
|
-
this._paramsStore.setParams(params,
|
166
|
+
this._paramsStore.setParams(params, id);
|
167
|
+
}
|
168
|
+
},
|
169
|
+
setDeleteFileParams: function(params, id) {
|
170
|
+
/*jshint eqeqeq: true, eqnull: true*/
|
171
|
+
if (id == null) {
|
172
|
+
this._options.deleteFile.params = params;
|
173
|
+
}
|
174
|
+
else {
|
175
|
+
this._deleteFileParamsStore.setParams(params, id);
|
176
|
+
}
|
177
|
+
},
|
178
|
+
setEndpoint: function(endpoint, id) {
|
179
|
+
/*jshint eqeqeq: true, eqnull: true*/
|
180
|
+
if (id == null) {
|
181
|
+
this._options.request.endpoint = endpoint;
|
182
|
+
}
|
183
|
+
else {
|
184
|
+
this._endpointStore.setEndpoint(endpoint, id);
|
95
185
|
}
|
96
186
|
},
|
97
187
|
getInProgress: function(){
|
98
|
-
return this._filesInProgress;
|
188
|
+
return this._filesInProgress.length;
|
99
189
|
},
|
100
190
|
uploadStoredFiles: function(){
|
101
191
|
"use strict";
|
102
|
-
|
103
|
-
|
104
|
-
|
192
|
+
var idToUpload;
|
193
|
+
|
194
|
+
while(this._storedIds.length) {
|
195
|
+
idToUpload = this._storedIds.shift();
|
196
|
+
this._filesInProgress.push(idToUpload);
|
197
|
+
this._handler.upload(idToUpload);
|
105
198
|
}
|
106
199
|
},
|
107
200
|
clearStoredFiles: function(){
|
108
|
-
this.
|
201
|
+
this._storedIds = [];
|
109
202
|
},
|
110
203
|
retry: function(id) {
|
111
204
|
if (this._onBeforeManualRetry(id)) {
|
205
|
+
this._netFilesUploadedOrQueued++;
|
112
206
|
this._handler.retry(id);
|
113
207
|
return true;
|
114
208
|
}
|
@@ -116,32 +210,49 @@ qq.FineUploaderBasic.prototype = {
|
|
116
210
|
return false;
|
117
211
|
}
|
118
212
|
},
|
119
|
-
cancel: function(
|
120
|
-
this._handler.cancel(
|
213
|
+
cancel: function(id) {
|
214
|
+
this._handler.cancel(id);
|
215
|
+
},
|
216
|
+
cancelAll: function() {
|
217
|
+
var storedIdsCopy = [],
|
218
|
+
self = this;
|
219
|
+
|
220
|
+
qq.extend(storedIdsCopy, this._storedIds);
|
221
|
+
qq.each(storedIdsCopy, function(idx, storedFileId) {
|
222
|
+
self.cancel(storedFileId);
|
223
|
+
});
|
224
|
+
|
225
|
+
this._handler.cancelAll();
|
121
226
|
},
|
122
227
|
reset: function() {
|
123
228
|
this.log("Resetting uploader...");
|
124
229
|
this._handler.reset();
|
125
|
-
this._filesInProgress =
|
126
|
-
this.
|
230
|
+
this._filesInProgress = [];
|
231
|
+
this._storedIds = [];
|
127
232
|
this._autoRetries = [];
|
128
233
|
this._retryTimeouts = [];
|
129
234
|
this._preventRetries = [];
|
130
235
|
this._button.reset();
|
131
236
|
this._paramsStore.reset();
|
237
|
+
this._endpointStore.reset();
|
238
|
+
this._netFilesUploadedOrQueued = 0;
|
239
|
+
|
240
|
+
if (this._pasteHandler) {
|
241
|
+
this._pasteHandler.reset();
|
242
|
+
}
|
132
243
|
},
|
133
|
-
addFiles: function(
|
244
|
+
addFiles: function(filesBlobDataOrInputs) {
|
134
245
|
var self = this,
|
135
246
|
verifiedFilesOrInputs = [],
|
136
247
|
index, fileOrInput;
|
137
248
|
|
138
|
-
if (
|
139
|
-
if (!window.FileList || !
|
140
|
-
|
249
|
+
if (filesBlobDataOrInputs) {
|
250
|
+
if (!window.FileList || !(filesBlobDataOrInputs instanceof FileList)) {
|
251
|
+
filesBlobDataOrInputs = [].concat(filesBlobDataOrInputs);
|
141
252
|
}
|
142
253
|
|
143
|
-
for (index = 0; index <
|
144
|
-
fileOrInput =
|
254
|
+
for (index = 0; index < filesBlobDataOrInputs.length; index+=1) {
|
255
|
+
fileOrInput = filesBlobDataOrInputs[index];
|
145
256
|
|
146
257
|
if (qq.isFileOrInput(fileOrInput)) {
|
147
258
|
verifiedFilesOrInputs.push(fileOrInput);
|
@@ -152,8 +263,65 @@ qq.FineUploaderBasic.prototype = {
|
|
152
263
|
}
|
153
264
|
|
154
265
|
this.log('Processing ' + verifiedFilesOrInputs.length + ' files or inputs...');
|
155
|
-
this.
|
266
|
+
this._uploadFileOrBlobDataList(verifiedFilesOrInputs);
|
267
|
+
}
|
268
|
+
},
|
269
|
+
addBlobs: function(blobDataOrArray) {
|
270
|
+
if (blobDataOrArray) {
|
271
|
+
var blobDataArray = [].concat(blobDataOrArray),
|
272
|
+
verifiedBlobDataList = [],
|
273
|
+
self = this;
|
274
|
+
|
275
|
+
qq.each(blobDataArray, function(idx, blobData) {
|
276
|
+
if (qq.isBlob(blobData) && !qq.isFileOrInput(blobData)) {
|
277
|
+
verifiedBlobDataList.push({
|
278
|
+
blob: blobData,
|
279
|
+
name: self._options.blobs.defaultName
|
280
|
+
});
|
281
|
+
}
|
282
|
+
else if (qq.isObject(blobData) && blobData.blob && blobData.name) {
|
283
|
+
verifiedBlobDataList.push(blobData);
|
284
|
+
}
|
285
|
+
else {
|
286
|
+
self.log("addBlobs: entry at index " + idx + " is not a Blob or a BlobData object", "error");
|
287
|
+
}
|
288
|
+
});
|
289
|
+
|
290
|
+
this._uploadFileOrBlobDataList(verifiedBlobDataList);
|
156
291
|
}
|
292
|
+
else {
|
293
|
+
this.log("undefined or non-array parameter passed into addBlobs", "error");
|
294
|
+
}
|
295
|
+
},
|
296
|
+
getUuid: function(id) {
|
297
|
+
return this._handler.getUuid(id);
|
298
|
+
},
|
299
|
+
getResumableFilesData: function() {
|
300
|
+
return this._handler.getResumableFilesData();
|
301
|
+
},
|
302
|
+
getSize: function(id) {
|
303
|
+
return this._handler.getSize(id);
|
304
|
+
},
|
305
|
+
getName: function(id) {
|
306
|
+
return this._handler.getName(id);
|
307
|
+
},
|
308
|
+
getFile: function(fileOrBlobId) {
|
309
|
+
return this._handler.getFile(fileOrBlobId);
|
310
|
+
},
|
311
|
+
deleteFile: function(id) {
|
312
|
+
this._onSubmitDelete(id);
|
313
|
+
},
|
314
|
+
setDeleteFileEndpoint: function(endpoint, id) {
|
315
|
+
/*jshint eqeqeq: true, eqnull: true*/
|
316
|
+
if (id == null) {
|
317
|
+
this._options.deleteFile.endpoint = endpoint;
|
318
|
+
}
|
319
|
+
else {
|
320
|
+
this._deleteFileEndpointStore.setEndpoint(endpoint, id);
|
321
|
+
}
|
322
|
+
},
|
323
|
+
getPromissoryCallbackNames: function() {
|
324
|
+
return ["onPasteReceived"];
|
157
325
|
},
|
158
326
|
_createUploadButton: function(element){
|
159
327
|
var self = this;
|
@@ -173,52 +341,59 @@ qq.FineUploaderBasic.prototype = {
|
|
173
341
|
return button;
|
174
342
|
},
|
175
343
|
_createUploadHandler: function(){
|
176
|
-
var self = this
|
177
|
-
handlerClass;
|
178
|
-
|
179
|
-
if(qq.isXhrUploadSupported()){
|
180
|
-
handlerClass = 'UploadHandlerXhr';
|
181
|
-
} else {
|
182
|
-
handlerClass = 'UploadHandlerForm';
|
183
|
-
}
|
344
|
+
var self = this;
|
184
345
|
|
185
|
-
|
346
|
+
return new qq.UploadHandler({
|
186
347
|
debug: this._options.debug,
|
187
|
-
endpoint: this._options.request.endpoint,
|
188
348
|
forceMultipart: this._options.request.forceMultipart,
|
189
349
|
maxConnections: this._options.maxConnections,
|
190
350
|
customHeaders: this._options.request.customHeaders,
|
191
351
|
inputName: this._options.request.inputName,
|
352
|
+
uuidParamName: this._options.request.uuidName,
|
353
|
+
totalFileSizeParamName: this._options.request.totalFileSizeName,
|
354
|
+
cors: this._options.cors,
|
192
355
|
demoMode: this._options.demoMode,
|
193
|
-
log: this.log,
|
194
356
|
paramsInBody: this._options.request.paramsInBody,
|
195
357
|
paramsStore: this._paramsStore,
|
196
|
-
|
197
|
-
|
198
|
-
|
358
|
+
endpointStore: this._endpointStore,
|
359
|
+
chunking: this._options.chunking,
|
360
|
+
resume: this._options.resume,
|
361
|
+
blobs: this._options.blobs,
|
362
|
+
log: function(str, level) {
|
363
|
+
self.log(str, level);
|
199
364
|
},
|
200
|
-
|
201
|
-
self.
|
202
|
-
self._options.callbacks.
|
365
|
+
onProgress: function(id, name, loaded, total){
|
366
|
+
self._onProgress(id, name, loaded, total);
|
367
|
+
self._options.callbacks.onProgress(id, name, loaded, total);
|
203
368
|
},
|
204
|
-
|
205
|
-
self.
|
206
|
-
self._options.callbacks.
|
369
|
+
onComplete: function(id, name, result, xhr){
|
370
|
+
self._onComplete(id, name, result, xhr);
|
371
|
+
self._options.callbacks.onComplete(id, name, result);
|
207
372
|
},
|
208
|
-
|
209
|
-
self.
|
210
|
-
self._options.callbacks.
|
373
|
+
onCancel: function(id, name){
|
374
|
+
self._onCancel(id, name);
|
375
|
+
self._options.callbacks.onCancel(id, name);
|
211
376
|
},
|
212
|
-
|
377
|
+
onUpload: function(id, name){
|
378
|
+
self._onUpload(id, name);
|
379
|
+
self._options.callbacks.onUpload(id, name);
|
380
|
+
},
|
381
|
+
onUploadChunk: function(id, name, chunkData){
|
382
|
+
self._options.callbacks.onUploadChunk(id, name, chunkData);
|
383
|
+
},
|
384
|
+
onResume: function(id, name, chunkData) {
|
385
|
+
return self._options.callbacks.onResume(id, name, chunkData);
|
386
|
+
},
|
387
|
+
onAutoRetry: function(id, name, responseJSON, xhr) {
|
213
388
|
self._preventRetries[id] = responseJSON[self._options.retry.preventRetryResponseProperty];
|
214
389
|
|
215
|
-
if (self._shouldAutoRetry(id,
|
216
|
-
self._maybeParseAndSendUploadError(id,
|
217
|
-
self._options.callbacks.onAutoRetry(id,
|
218
|
-
self._onBeforeAutoRetry(id,
|
390
|
+
if (self._shouldAutoRetry(id, name, responseJSON)) {
|
391
|
+
self._maybeParseAndSendUploadError(id, name, responseJSON, xhr);
|
392
|
+
self._options.callbacks.onAutoRetry(id, name, self._autoRetries[id] + 1);
|
393
|
+
self._onBeforeAutoRetry(id, name);
|
219
394
|
|
220
395
|
self._retryTimeouts[id] = setTimeout(function() {
|
221
|
-
self._onAutoRetry(id,
|
396
|
+
self._onAutoRetry(id, name, responseJSON)
|
222
397
|
}, self._options.retry.autoAttemptDelay * 1000);
|
223
398
|
|
224
399
|
return true;
|
@@ -228,14 +403,79 @@ qq.FineUploaderBasic.prototype = {
|
|
228
403
|
}
|
229
404
|
}
|
230
405
|
});
|
406
|
+
},
|
407
|
+
_createDeleteHandler: function() {
|
408
|
+
var self = this;
|
409
|
+
|
410
|
+
return new qq.DeleteFileAjaxRequestor({
|
411
|
+
maxConnections: this._options.maxConnections,
|
412
|
+
customHeaders: this._options.deleteFile.customHeaders,
|
413
|
+
paramsStore: this._deleteFileParamsStore,
|
414
|
+
endpointStore: this._deleteFileEndpointStore,
|
415
|
+
demoMode: this._options.demoMode,
|
416
|
+
cors: this._options.cors,
|
417
|
+
log: function(str, level) {
|
418
|
+
self.log(str, level);
|
419
|
+
},
|
420
|
+
onDelete: function(id) {
|
421
|
+
self._onDelete(id);
|
422
|
+
self._options.callbacks.onDelete(id);
|
423
|
+
},
|
424
|
+
onDeleteComplete: function(id, xhr, isError) {
|
425
|
+
self._onDeleteComplete(id, xhr, isError);
|
426
|
+
self._options.callbacks.onDeleteComplete(id, xhr, isError);
|
427
|
+
}
|
428
|
+
|
429
|
+
});
|
430
|
+
},
|
431
|
+
_createPasteHandler: function() {
|
432
|
+
var self = this;
|
231
433
|
|
232
|
-
return
|
434
|
+
return new qq.PasteSupport({
|
435
|
+
targetElement: this._options.paste.targetElement,
|
436
|
+
callbacks: {
|
437
|
+
log: function(str, level) {
|
438
|
+
self.log(str, level);
|
439
|
+
},
|
440
|
+
pasteReceived: function(blob) {
|
441
|
+
var pasteReceivedCallback = self._options.callbacks.onPasteReceived,
|
442
|
+
promise = pasteReceivedCallback(blob);
|
443
|
+
|
444
|
+
if (promise.then) {
|
445
|
+
promise.then(function(successData) {
|
446
|
+
self._handlePasteSuccess(blob, successData);
|
447
|
+
}, function(failureData) {
|
448
|
+
self.log("Ignoring pasted image per paste received callback. Reason = '" + failureData + "'");
|
449
|
+
});
|
450
|
+
}
|
451
|
+
else {
|
452
|
+
self.log("Promise contract not fulfilled in pasteReceived callback handler! Ignoring pasted item.", "error");
|
453
|
+
}
|
454
|
+
}
|
455
|
+
}
|
456
|
+
});
|
457
|
+
},
|
458
|
+
_handlePasteSuccess: function(blob, extSuppliedName) {
|
459
|
+
var extension = blob.type.split("/")[1],
|
460
|
+
name = extSuppliedName;
|
461
|
+
|
462
|
+
/*jshint eqeqeq: true, eqnull: true*/
|
463
|
+
if (name == null) {
|
464
|
+
name = this._options.paste.defaultName;
|
465
|
+
}
|
466
|
+
|
467
|
+
name += '.' + extension;
|
468
|
+
|
469
|
+
this.addBlobs({
|
470
|
+
name: name,
|
471
|
+
blob: blob
|
472
|
+
});
|
233
473
|
},
|
234
474
|
_preventLeaveInProgress: function(){
|
235
475
|
var self = this;
|
236
476
|
|
237
477
|
this._disposeSupport.attach(window, 'beforeunload', function(e){
|
238
|
-
if (!self._filesInProgress){return;}
|
478
|
+
if (!self._filesInProgress.length){return;}
|
239
479
|
|
240
480
|
var e = e || window.event;
|
241
481
|
// for ie, ff
|
@@ -244,61 +484,105 @@ qq.FineUploaderBasic.prototype = {
|
|
244
484
|
return self._options.messages.onLeave;
|
245
485
|
});
|
246
486
|
},
|
247
|
-
_onSubmit: function(id,
|
487
|
+
_onSubmit: function(id, name) {
|
488
|
+
this._netFilesUploadedOrQueued++;
|
489
|
+
|
248
490
|
if (this._options.autoUpload) {
|
249
|
-
this._filesInProgress
|
491
|
+
this._filesInProgress.push(id);
|
250
492
|
}
|
251
493
|
},
|
252
|
-
_onProgress: function(id,
|
494
|
+
_onProgress: function(id, name, loaded, total){
|
253
495
|
},
|
254
|
-
_onComplete: function(id,
|
255
|
-
|
256
|
-
|
496
|
+
_onComplete: function(id, name, result, xhr) {
|
497
|
+
if (!result.success) {
|
498
|
+
this._netFilesUploadedOrQueued--;
|
499
|
+
}
|
500
|
+
|
501
|
+
this._removeFromFilesInProgress(id);
|
502
|
+
this._maybeParseAndSendUploadError(id, name, result, xhr);
|
257
503
|
},
|
258
|
-
_onCancel: function(id,
|
504
|
+
_onCancel: function(id, name){
|
505
|
+
this._netFilesUploadedOrQueued--;
|
506
|
+
|
507
|
+
this._removeFromFilesInProgress(id);
|
508
|
+
|
259
509
|
clearTimeout(this._retryTimeouts[id]);
|
260
510
|
|
261
|
-
var
|
262
|
-
if (this._options.autoUpload
|
263
|
-
this.
|
511
|
+
var storedItemIndex = qq.indexOf(this._storedIds, id);
|
512
|
+
if (!this._options.autoUpload && storedItemIndex >= 0) {
|
513
|
+
this._storedIds.splice(storedItemIndex, 1);
|
264
514
|
}
|
265
|
-
|
266
|
-
|
515
|
+
},
|
516
|
+
_isDeletePossible: function() {
|
517
|
+
return (this._options.deleteFile.enabled &&
|
518
|
+
(!this._options.cors.expected ||
|
519
|
+
(this._options.cors.expected && (qq.ie10() || !qq.ie()))
|
520
|
+
)
|
521
|
+
);
|
522
|
+
},
|
523
|
+
_onSubmitDelete: function(id) {
|
524
|
+
if (this._isDeletePossible()) {
|
525
|
+
if (this._options.callbacks.onSubmitDelete(id) !== false) {
|
526
|
+
this._deleteHandler.sendDelete(id, this.getUuid(id));
|
527
|
+
}
|
528
|
+
}
|
529
|
+
else {
|
530
|
+
this.log("Delete request ignored for ID " + id + ", delete feature is disabled or request not possible " +
|
531
|
+
"due to CORS on a user agent that does not support pre-flighting.", "warn");
|
532
|
+
return false;
|
267
533
|
}
|
268
534
|
},
|
269
|
-
|
535
|
+
_onDelete: function(fileId) {},
|
536
|
+
_onDeleteComplete: function(id, xhr, isError) {
|
537
|
+
var name = this._handler.getName(id);
|
538
|
+
|
539
|
+
if (isError) {
|
540
|
+
this.log("Delete request for '" + name + "' has failed.", "error");
|
541
|
+
this._options.callbacks.onError(id, name, "Delete request failed with response code " + xhr.status, xhr);
|
542
|
+
}
|
543
|
+
else {
|
544
|
+
this._netFilesUploadedOrQueued--;
|
545
|
+
this.log("Delete request for '" + name + "' has succeeded.");
|
546
|
+
}
|
270
547
|
},
|
548
|
+
_removeFromFilesInProgress: function(id) {
|
549
|
+
var index = qq.indexOf(this._filesInProgress, id);
|
550
|
+
if (index >= 0) {
|
551
|
+
this._filesInProgress.splice(index, 1);
|
552
|
+
}
|
553
|
+
},
|
554
|
+
_onUpload: function(id, name){},
|
271
555
|
_onInputChange: function(input){
|
272
|
-
if (
|
556
|
+
if (qq.isXhrUploadSupported()){
|
273
557
|
this.addFiles(input.files);
|
274
558
|
} else {
|
275
|
-
|
276
|
-
this.addFiles(input);
|
277
|
-
}
|
559
|
+
this.addFiles(input);
|
278
560
|
}
|
279
561
|
this._button.reset();
|
280
562
|
},
|
281
|
-
_onBeforeAutoRetry: function(id,
|
282
|
-
this.log("Waiting " + this._options.retry.autoAttemptDelay + " seconds before retrying " +
|
563
|
+
_onBeforeAutoRetry: function(id, name) {
|
564
|
+
this.log("Waiting " + this._options.retry.autoAttemptDelay + " seconds before retrying " + name + "...");
|
283
565
|
},
|
284
|
-
_onAutoRetry: function(id,
|
285
|
-
this.log("Retrying " +
|
566
|
+
_onAutoRetry: function(id, name, responseJSON) {
|
567
|
+
this.log("Retrying " + name + "...");
|
286
568
|
this._autoRetries[id]++;
|
287
569
|
this._handler.retry(id);
|
288
570
|
},
|
289
|
-
_shouldAutoRetry: function(id,
|
571
|
+
_shouldAutoRetry: function(id, name, responseJSON) {
|
290
572
|
if (!this._preventRetries[id] && this._options.retry.enableAuto) {
|
291
573
|
if (this._autoRetries[id] === undefined) {
|
292
574
|
this._autoRetries[id] = 0;
|
293
575
|
}
|
294
576
|
|
295
|
-
return this._autoRetries[id] < this._options.retry.maxAutoAttempts
|
577
|
+
return this._autoRetries[id] < this._options.retry.maxAutoAttempts;
|
296
578
|
}
|
297
579
|
|
298
580
|
return false;
|
299
581
|
},
|
300
582
|
//return false if we should not attempt the requested retry
|
301
583
|
_onBeforeManualRetry: function(id) {
|
584
|
+
var itemLimit = this._options.validation.itemLimit;
|
585
|
+
|
302
586
|
if (this._preventRetries[id]) {
|
303
587
|
this.log("Retries are forbidden for id " + id, 'warn');
|
304
588
|
return false;
|
@@ -310,8 +594,13 @@ qq.FineUploaderBasic.prototype = {
|
|
310
594
|
return false;
|
311
595
|
}
|
312
596
|
|
597
|
+
if (itemLimit > 0 && this._netFilesUploadedOrQueued+1 > itemLimit) {
|
598
|
+
this._itemError("retryFailTooManyItems", "");
|
599
|
+
return false;
|
600
|
+
}
|
601
|
+
|
313
602
|
this.log("Retrying upload for '" + fileName + "' (id: " + id + ")...");
|
314
|
-
this._filesInProgress
|
603
|
+
this._filesInProgress.push(id);
|
315
604
|
return true;
|
316
605
|
}
|
317
606
|
else {
|
@@ -319,29 +608,28 @@ qq.FineUploaderBasic.prototype = {
|
|
319
608
|
return false;
|
320
609
|
}
|
321
610
|
},
|
322
|
-
_maybeParseAndSendUploadError: function(id,
|
611
|
+
_maybeParseAndSendUploadError: function(id, name, response, xhr) {
|
323
612
|
//assuming no one will actually set the response code to something other than 200 and still set 'success' to true
|
324
613
|
if (!response.success){
|
325
614
|
if (xhr && xhr.status !== 200 && !response.error) {
|
326
|
-
this._options.callbacks.onError(id,
|
615
|
+
this._options.callbacks.onError(id, name, "XHR returned response code " + xhr.status, xhr);
|
327
616
|
}
|
328
617
|
else {
|
329
618
|
var errorReason = response.error ? response.error : "Upload failure reason unknown";
|
330
|
-
this._options.callbacks.onError(id,
|
619
|
+
this._options.callbacks.onError(id, name, errorReason, xhr);
|
331
620
|
}
|
332
621
|
}
|
333
622
|
},
|
334
|
-
|
335
|
-
var
|
336
|
-
|
337
|
-
|
338
|
-
batchInvalid = this._options.callbacks.onValidate(validationDescriptors) === false;
|
623
|
+
_uploadFileOrBlobDataList: function(fileOrBlobDataList){
|
624
|
+
var index,
|
625
|
+
validationDescriptors = this._getValidationDescriptors(fileOrBlobDataList),
|
626
|
+
batchValid = this._isBatchValid(validationDescriptors);
|
339
627
|
|
340
|
-
if (
|
341
|
-
if (
|
342
|
-
for (index = 0; index <
|
343
|
-
if (this.
|
344
|
-
this.
|
628
|
+
if (batchValid) {
|
629
|
+
if (fileOrBlobDataList.length > 0) {
|
630
|
+
for (index = 0; index < fileOrBlobDataList.length; index++){
|
631
|
+
if (this._validateFileOrBlobData(fileOrBlobDataList[index])){
|
632
|
+
this._upload(fileOrBlobDataList[index]);
|
345
633
|
} else {
|
346
634
|
if (this._options.validation.stopOnFirstInvalidFile){
|
347
635
|
return;
|
@@ -350,94 +638,141 @@ qq.FineUploaderBasic.prototype = {
|
|
350
638
|
}
|
351
639
|
}
|
352
640
|
else {
|
353
|
-
this.
|
641
|
+
this._itemError("noFilesError", "");
|
354
642
|
}
|
355
643
|
}
|
356
644
|
},
|
357
|
-
|
358
|
-
var id = this._handler.add(
|
359
|
-
var
|
645
|
+
_upload: function(blobOrFileContainer){
|
646
|
+
var id = this._handler.add(blobOrFileContainer);
|
647
|
+
var name = this._handler.getName(id);
|
648
|
+
|
649
|
+
if (this._options.callbacks.onSubmit(id, name) !== false) {
|
650
|
+
this._onSubmit(id, name);
|
651
|
+
this._options.callbacks.onSubmitted(id, name);
|
360
652
|
|
361
|
-
if (this._options.callbacks.onSubmit(id, fileName) !== false){
|
362
|
-
this._onSubmit(id, fileName);
|
363
653
|
if (this._options.autoUpload) {
|
364
654
|
this._handler.upload(id);
|
365
655
|
}
|
366
656
|
else {
|
367
|
-
this.
|
657
|
+
this._storeForLater(id);
|
368
658
|
}
|
369
659
|
}
|
370
660
|
},
|
371
|
-
|
372
|
-
this.
|
661
|
+
_storeForLater: function(id) {
|
662
|
+
this._storedIds.push(id);
|
663
|
+
},
|
664
|
+
_isBatchValid: function(validationDescriptors) {
|
665
|
+
//first, defer the check to the callback (ask the integrator)
|
666
|
+
var errorMessage,
|
667
|
+
itemLimit = this._options.validation.itemLimit,
|
668
|
+
proposedNetFilesUploadedOrQueued = this._netFilesUploadedOrQueued + validationDescriptors.length,
|
669
|
+
batchValid = this._options.callbacks.onValidateBatch(validationDescriptors) !== false;
|
670
|
+
|
671
|
+
//if the callback hasn't rejected the batch, run some internal tests on the batch next
|
672
|
+
if (batchValid) {
|
673
|
+
if (itemLimit === 0 || proposedNetFilesUploadedOrQueued <= itemLimit) {
|
674
|
+
batchValid = true;
|
675
|
+
}
|
676
|
+
else {
|
677
|
+
batchValid = false;
|
678
|
+
errorMessage = this._options.messages.tooManyItemsError
|
679
|
+
.replace(/\{netItems\}/g, proposedNetFilesUploadedOrQueued)
|
680
|
+
.replace(/\{itemLimit\}/g, itemLimit);
|
681
|
+
this._batchError(errorMessage);
|
682
|
+
}
|
683
|
+
}
|
684
|
+
|
685
|
+
return batchValid;
|
373
686
|
},
|
374
|
-
|
687
|
+
_validateFileOrBlobData: function(fileOrBlobData){
|
375
688
|
var validationDescriptor, name, size;
|
376
689
|
|
377
|
-
validationDescriptor = this._getValidationDescriptor(
|
690
|
+
validationDescriptor = this._getValidationDescriptor(fileOrBlobData);
|
378
691
|
name = validationDescriptor.name;
|
379
692
|
size = validationDescriptor.size;
|
380
693
|
|
381
|
-
if (this._options.callbacks.onValidate(
|
694
|
+
if (this._options.callbacks.onValidate(validationDescriptor) === false) {
|
382
695
|
return false;
|
383
696
|
}
|
384
697
|
|
385
|
-
if (!this._isAllowedExtension(name)){
|
386
|
-
this.
|
698
|
+
if (qq.isFileOrInput(fileOrBlobData) && !this._isAllowedExtension(name)){
|
699
|
+
this._itemError('typeError', name);
|
387
700
|
return false;
|
388
701
|
|
389
702
|
}
|
390
703
|
else if (size === 0){
|
391
|
-
this.
|
704
|
+
this._itemError('emptyError', name);
|
392
705
|
return false;
|
393
706
|
|
394
707
|
}
|
395
708
|
else if (size && this._options.validation.sizeLimit && size > this._options.validation.sizeLimit){
|
396
|
-
this.
|
709
|
+
this._itemError('sizeError', name);
|
397
710
|
return false;
|
398
711
|
|
399
712
|
}
|
400
713
|
else if (size && size < this._options.validation.minSizeLimit){
|
401
|
-
this.
|
714
|
+
this._itemError('minSizeError', name);
|
402
715
|
return false;
|
403
716
|
}
|
404
717
|
|
405
718
|
return true;
|
406
719
|
},
|
407
|
-
|
408
|
-
var message = this._options.messages[code]
|
720
|
+
_itemError: function(code, name) {
|
721
|
+
var message = this._options.messages[code],
|
722
|
+
allowedExtensions = [],
|
723
|
+
extensionsForMessage;
|
724
|
+
|
409
725
|
function r(name, replacement){ message = message.replace(name, replacement); }
|
410
726
|
|
411
|
-
|
727
|
+
qq.each(this._options.validation.allowedExtensions, function(idx, allowedExtension) {
|
728
|
+
/**
|
729
|
+
* If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the
|
730
|
+
* `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.
|
731
|
+
*/
|
732
|
+
if (qq.isString(allowedExtension)) {
|
733
|
+
allowedExtensions.push(allowedExtension);
|
734
|
+
}
|
735
|
+
});
|
736
|
+
|
737
|
+
extensionsForMessage = allowedExtensions.join(', ').toLowerCase();
|
412
738
|
|
413
|
-
r('{file}', this.
|
414
|
-
r('{extensions}',
|
739
|
+
r('{file}', this._options.formatFileName(name));
|
740
|
+
r('{extensions}', extensionsForMessage);
|
415
741
|
r('{sizeLimit}', this._formatSize(this._options.validation.sizeLimit));
|
416
742
|
r('{minSizeLimit}', this._formatSize(this._options.validation.minSizeLimit));
|
417
743
|
|
418
|
-
this._options.callbacks.onError(null,
|
744
|
+
this._options.callbacks.onError(null, name, message);
|
419
745
|
|
420
746
|
return message;
|
421
747
|
},
|
422
|
-
|
423
|
-
|
424
|
-
name = name.slice(0, 19) + '...' + name.slice(-13);
|
425
|
-
}
|
426
|
-
return name;
|
748
|
+
_batchError: function(message) {
|
749
|
+
this._options.callbacks.onError(null, null, message);
|
427
750
|
},
|
428
751
|
_isAllowedExtension: function(fileName){
|
429
|
-
var
|
430
|
-
|
431
|
-
: '';
|
432
|
-
var allowed = this._options.validation.allowedExtensions;
|
433
|
-
|
434
|
-
if (!allowed.length){return true;}
|
752
|
+
var allowed = this._options.validation.allowedExtensions,
|
753
|
+
valid = false;
|
435
754
|
|
436
|
-
|
437
|
-
|
755
|
+
if (!allowed.length) {
|
756
|
+
return true;
|
438
757
|
}
|
439
758
|
|
440
|
-
|
759
|
+
qq.each(allowed, function(idx, allowedExt) {
|
760
|
+
/**
|
761
|
+
* If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the
|
762
|
+
* `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.
|
763
|
+
*/
|
764
|
+
if (qq.isString(allowedExt)) {
|
765
|
+
/*jshint eqeqeq: true, eqnull: true*/
|
766
|
+
var extRegex = new RegExp('\\.' + allowedExt + "$", 'i');
|
767
|
+
|
768
|
+
if (fileName.match(extRegex) != null) {
|
769
|
+
valid = true;
|
770
|
+
return false;
|
771
|
+
}
|
772
|
+
}
|
773
|
+
});
|
774
|
+
|
775
|
+
return valid;
|
441
776
|
},
|
442
777
|
_formatSize: function(bytes){
|
443
778
|
var i = -1;
|
@@ -446,7 +781,7 @@ qq.FineUploaderBasic.prototype = {
|
|
446
781
|
i++;
|
447
782
|
} while (bytes > 99);
|
448
783
|
|
449
|
-
return Math.max(bytes, 0.1).toFixed(1) + [
|
784
|
+
return Math.max(bytes, 0.1).toFixed(1) + this._options.text.sizeSymbols[i];
|
450
785
|
},
|
451
786
|
_wrapCallbacks: function() {
|
452
787
|
var self, safeCallback;
|
@@ -458,9 +793,9 @@ qq.FineUploaderBasic.prototype = {
|
|
458
793
|
return callback.apply(self, args);
|
459
794
|
}
|
460
795
|
catch (exception) {
|
461
|
-
self.log("Caught exception in '" + name + "' callback - " + exception, 'error');
|
796
|
+
self.log("Caught exception in '" + name + "' callback - " + exception.message, 'error');
|
462
797
|
}
|
463
|
-
}
|
798
|
+
};
|
464
799
|
|
465
800
|
for (var prop in this._options.callbacks) {
|
466
801
|
(function() {
|
@@ -469,40 +804,50 @@ qq.FineUploaderBasic.prototype = {
|
|
469
804
|
callbackFunc = self._options.callbacks[callbackName];
|
470
805
|
self._options.callbacks[callbackName] = function() {
|
471
806
|
return safeCallback(callbackName, callbackFunc, arguments);
|
472
|
-
}
|
807
|
+
};
|
473
808
|
}());
|
474
809
|
}
|
475
810
|
},
|
476
|
-
|
811
|
+
_parseFileOrBlobDataName: function(fileOrBlobData) {
|
477
812
|
var name;
|
478
813
|
|
479
|
-
if (
|
480
|
-
|
481
|
-
|
482
|
-
|
483
|
-
|
484
|
-
|
485
|
-
|
814
|
+
if (qq.isFileOrInput(fileOrBlobData)) {
|
815
|
+
if (fileOrBlobData.value) {
|
816
|
+
// it is a file input
|
817
|
+
// get input value and remove path to normalize
|
818
|
+
name = fileOrBlobData.value.replace(/.*(\/|\\)/, "");
|
819
|
+
} else {
|
820
|
+
// fix missing properties in Safari 4 and firefox 11.0a2
|
821
|
+
name = (fileOrBlobData.fileName !== null && fileOrBlobData.fileName !== undefined) ? fileOrBlobData.fileName : fileOrBlobData.name;
|
822
|
+
}
|
823
|
+
}
|
824
|
+
else {
|
825
|
+
name = fileOrBlobData.name;
|
486
826
|
}
|
487
827
|
|
488
828
|
return name;
|
489
829
|
},
|
490
|
-
|
830
|
+
_parseFileOrBlobDataSize: function(fileOrBlobData) {
|
491
831
|
var size;
|
492
832
|
|
493
|
-
if (
|
494
|
-
|
495
|
-
|
833
|
+
if (qq.isFileOrInput(fileOrBlobData)) {
|
834
|
+
if (!fileOrBlobData.value){
|
835
|
+
// fix missing properties in Safari 4 and firefox 11.0a2
|
836
|
+
size = (fileOrBlobData.fileSize !== null && fileOrBlobData.fileSize !== undefined) ? fileOrBlobData.fileSize : fileOrBlobData.size;
|
837
|
+
}
|
838
|
+
}
|
839
|
+
else {
|
840
|
+
size = fileOrBlobData.blob.size;
|
496
841
|
}
|
497
842
|
|
498
843
|
return size;
|
499
844
|
},
|
500
|
-
_getValidationDescriptor: function(
|
845
|
+
_getValidationDescriptor: function(fileOrBlobData) {
|
501
846
|
var name, size, fileDescriptor;
|
502
847
|
|
503
848
|
fileDescriptor = {};
|
504
|
-
name = this.
|
505
|
-
size = this.
|
849
|
+
name = this._parseFileOrBlobDataName(fileOrBlobData);
|
850
|
+
size = this._parseFileOrBlobDataSize(fileOrBlobData);
|
506
851
|
|
507
852
|
fileDescriptor.name = name;
|
508
853
|
if (size) {
|
@@ -512,35 +857,35 @@ qq.FineUploaderBasic.prototype = {
|
|
512
857
|
return fileDescriptor;
|
513
858
|
},
|
514
859
|
_getValidationDescriptors: function(files) {
|
515
|
-
var
|
516
|
-
|
517
|
-
fileDescriptors = [];
|
860
|
+
var self = this,
|
861
|
+
fileDescriptors = [];
|
518
862
|
|
519
|
-
|
520
|
-
fileDescriptors.push(
|
521
|
-
}
|
863
|
+
qq.each(files, function(idx, file) {
|
864
|
+
fileDescriptors.push(self._getValidationDescriptor(file));
|
865
|
+
});
|
522
866
|
|
523
867
|
return fileDescriptors;
|
524
868
|
},
|
525
|
-
_createParamsStore: function() {
|
869
|
+
_createParamsStore: function(type) {
|
526
870
|
var paramsStore = {},
|
527
871
|
self = this;
|
528
872
|
|
529
873
|
return {
|
530
|
-
setParams: function(params,
|
874
|
+
setParams: function(params, id) {
|
531
875
|
var paramsCopy = {};
|
532
876
|
qq.extend(paramsCopy, params);
|
533
|
-
paramsStore[
|
877
|
+
paramsStore[id] = paramsCopy;
|
534
878
|
},
|
535
879
|
|
536
|
-
getParams: function(
|
880
|
+
getParams: function(id) {
|
881
|
+
/*jshint eqeqeq: true, eqnull: true*/
|
537
882
|
var paramsCopy = {};
|
538
883
|
|
539
|
-
if (
|
540
|
-
qq.extend(paramsCopy, paramsStore[
|
884
|
+
if (id != null && paramsStore[id]) {
|
885
|
+
qq.extend(paramsCopy, paramsStore[id]);
|
541
886
|
}
|
542
887
|
else {
|
543
|
-
qq.extend(paramsCopy, self._options.
|
888
|
+
qq.extend(paramsCopy, self._options[type].params);
|
544
889
|
}
|
545
890
|
|
546
891
|
return paramsCopy;
|
@@ -553,6 +898,33 @@ qq.FineUploaderBasic.prototype = {
|
|
553
898
|
reset: function() {
|
554
899
|
paramsStore = {};
|
555
900
|
}
|
556
|
-
}
|
901
|
+
};
|
902
|
+
},
|
903
|
+
_createEndpointStore: function(type) {
|
904
|
+
var endpointStore = {},
|
905
|
+
self = this;
|
906
|
+
|
907
|
+
return {
|
908
|
+
setEndpoint: function(endpoint, id) {
|
909
|
+
endpointStore[id] = endpoint;
|
910
|
+
},
|
911
|
+
|
912
|
+
getEndpoint: function(id) {
|
913
|
+
/*jshint eqeqeq: true, eqnull: true*/
|
914
|
+
if (id != null && endpointStore[id]) {
|
915
|
+
return endpointStore[id];
|
916
|
+
}
|
917
|
+
|
918
|
+
return self._options[type].endpoint;
|
919
|
+
},
|
920
|
+
|
921
|
+
remove: function(fileId) {
|
922
|
+
return delete endpointStore[fileId];
|
923
|
+
},
|
924
|
+
|
925
|
+
reset: function() {
|
926
|
+
endpointStore = {};
|
927
|
+
}
|
928
|
+
};
|
557
929
|
}
|
558
930
|
};
|