Skip to content

Commit 730d074

Browse files
author
nerv
committed
Added: Canceling uploading for modern browsers (Issue nervgh#28, part 1)
1 parent f715a0b commit 730d074

File tree

12 files changed

+159
-55
lines changed

12 files changed

+159
-55
lines changed

README.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,8 @@ When files are selected or dropped into the component, one or more filters are a
6060
- **getNotUploadedItems** `function() { return [Array]; }`: Return an array of all pending items on the queue
6161
- **uploadItem** `function( value ) {`: Uploads an item, where `value` is a queue element `Item` or index
6262
- **uploadAll** `function() {`: Upload all pending items on the queue
63+
- **cancelItem** `function( value ) {`: Cancels uploading of item, where `value` is a queue element `Item` or index
64+
- **cancelAll** `function() {`: Cancels all current uploads
6365

6466
### The Item API:
6567

@@ -77,13 +79,15 @@ When files are selected or dropped into the component, one or more filters are a
7779
- **isUploading** `{Boolean}`: `true` if the file is being uploaded
7880
- **isUploaded** `{Boolean}`: `true` if the file was uploaded
7981
- **isSuccess** `{Boolean}`: `true` if the file was uploaded successfully
82+
- **isCancel** `{Boolean}` : `true` if uploading was canceled
8083
- **isError** `{Boolean}` - `true` if occurred error while file uploading
8184
- **uploader** `{Object}`: Reference to the parent `Uploader` object for this file
8285

8386
#### Methods
8487

8588
- **remove** `function() {`: Remove this file from the queue
8689
- **upload** `function() {`: Upload this file
90+
- **cancel** `function() {`: Cancels uploading of this file
8791

8892
## Filters
8993

@@ -126,6 +130,7 @@ function( item ) {
126130
- **changedqueue** `function( event, [item|items] ) {`: When the queue has changed as a result of adding or removing elements
127131
- **progress** `function( event, item, progress ) {`: On file upload progress
128132
- **success** `function( event, xhr, item, response ) {`: On file successfully uploaded
133+
- **cancel** `function( event, xhr, item ) {` - On cancel uploading
129134
- **error** `function( event, xhr, item[, response ]) {`: On upload error
130135
- **complete** `function( event, xhr, item, response ) {`: On file upload complete (independently of the sucess of the operation)
131136
- **progressall** `function( event, progress ) {`: On upload queue progress
@@ -208,6 +213,8 @@ uploader.queue.push({
208213
- **getNotUploadedItems** `function() { return [Array]; }` - возвращает массив не загруженных элементов
209214
- **uploadItem** `function( value ) {` - где _value_ элемент очереди или его индекс [Item|Index]
210215
- **uploadAll** `function() {` - загружает все незагруженные элементы
216+
- **cancelItem** `function( value ) {` - где _value_ элемент очереди или его индекс [Item|Index]
217+
- **cancelAll** `function() {` - отменяет все текущие загрузки
211218

212219
### Элемент очереди API:
213220

@@ -225,13 +232,15 @@ uploader.queue.push({
225232
- **isUploading** `{Boolean}` - файл в процессе загрузки
226233
- **isUploaded** `{Boolean}` - файл загружен
227234
- **isSuccess** `{Boolean}` - файл успешно загружен
235+
- **isCancel** `{Boolean}` - загрузка файла была отменена
228236
- **isError** `{Boolean}` - при загрузке файла произошла ошибка
229237
- **uploader** `{Object}` - ссылка на загрузчик
230238

231239
#### Методы
232240

233241
- **remove** `function() {` - удаляет элемент
234242
- **upload** `function() {` - загружает элемент
243+
- **cancel** `function() {` - отменяет загрузку элемента
235244

236245
## Фильтры
237246

@@ -273,6 +282,7 @@ function( item ) {
273282
- **changedqueue** `function( event, [item|items] ) {` - очередь изменена
274283
- **progress** `function( event, item, progress ) {` - прогресс загрузки файла
275284
- **success** `function( event, xhr, item, response ) {` - файл успешно загружен
285+
- **cancel** `function( event, xhr, item ) {` - отменяет загрузку файла
276286
- **error** `function( event, xhr, item[, response ]) {` - ошибка при загрузке
277287
- **complete** `function( event, xhr, item, response ) {` - файл загружен
278288
- **progressall** `function( event, progress ) {` - прогресс загрузки очереди

angular-file-upload.js

Lines changed: 65 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,14 @@
1010
/**
1111
* The angular file upload module
1212
* @author: nerv
13-
* @version: 0.2.9.7, 2013-12-31
13+
* @version: 0.2.9.8, 2013-12-31
1414
*/
1515
var app = angular.module('angularFileUpload', []);
1616

1717
/**
1818
* The angular file upload module
1919
* @author: nerv
20-
* @version: 0.2.9.7, 2013-12-31
20+
* @version: 0.2.9.8, 2013-12-31
2121
*/
2222

2323
// It is attached to an element that catches the event drop file
@@ -57,7 +57,7 @@ app.directive('ngFileDrop', [ '$fileUploader', function ($fileUploader) {
5757
/**
5858
* The angular file upload module
5959
* @author: nerv
60-
* @version: 0.2.9.7, 2013-12-31
60+
* @version: 0.2.9.8, 2013-12-31
6161
*/
6262

6363
// It is attached to an element which will be assigned to a class "ng-file-over" or ng-file-over="className"
@@ -78,7 +78,7 @@ app.directive('ngFileOver', function () {
7878
/**
7979
* The angular file upload module
8080
* @author: nerv
81-
* @version: 0.2.9.7, 2013-12-31
81+
* @version: 0.2.9.8, 2013-12-31
8282
*/
8383

8484
// It is attached to <input type="file"> element like <ng-file-select="options">
@@ -99,7 +99,7 @@ app.directive('ngFileSelect', [ '$fileUploader', function ($fileUploader) {
9999
/**
100100
* The angular file upload module
101101
* @author: nerv
102-
* @version: 0.2.9.7, 2013-12-31
102+
* @version: 0.2.9.8, 2013-12-31
103103
*/
104104

105105
app.factory('$fileUploader', [ '$compile', '$rootScope', '$http', '$window', function ($compile, $rootScope, $http, $window) {
@@ -134,6 +134,7 @@ app.factory('$fileUploader', [ '$compile', '$rootScope', '$http', '$window', fun
134134
this.bind('beforeupload', Item.prototype._beforeupload);
135135
this.bind('in:progress', Item.prototype._progress);
136136
this.bind('in:success', Item.prototype._success);
137+
this.bind('in:cancel', Item.prototype._cancel);
137138
this.bind('in:error', Item.prototype._error);
138139
this.bind('in:complete', Item.prototype._complete);
139140
this.bind('changedqueue', this._changedQueue);
@@ -220,8 +221,10 @@ app.factory('$fileUploader', [ '$compile', '$rootScope', '$http', '$window', fun
220221
* @param {Item|Number} value
221222
*/
222223
removeFromQueue: function (value) {
223-
var index = angular.isObject(value) ? this.getIndexOfItem(value) : value;
224-
var item = this.queue.splice(index, 1)[ 0 ];
224+
var index = this.getIndexOfItem(value);
225+
var item = this.queue[ index ];
226+
item.isUploading && item.cancel();
227+
this.queue.splice(index, 1);
225228
item._destroyForm();
226229
this.trigger('changedqueue', item);
227230
},
@@ -231,6 +234,7 @@ app.factory('$fileUploader', [ '$compile', '$rootScope', '$http', '$window', fun
231234
*/
232235
clearQueue: function () {
233236
this.queue.forEach(function (item) {
237+
item.isUploading && item.cancel();
234238
item._destroyForm();
235239
}, this);
236240
this.queue.length = 0;
@@ -239,11 +243,11 @@ app.factory('$fileUploader', [ '$compile', '$rootScope', '$http', '$window', fun
239243

240244
/**
241245
* Returns a index of item from the queue
242-
* @param item
246+
* @param {Item|Number} value
243247
* @returns {Number}
244248
*/
245-
getIndexOfItem: function (item) {
246-
return this.queue.indexOf(item);
249+
getIndexOfItem: function (value) {
250+
return angular.isObject(value) ? this.queue.indexOf(value) : value;
247251
},
248252

249253
/**
@@ -271,11 +275,11 @@ app.factory('$fileUploader', [ '$compile', '$rootScope', '$http', '$window', fun
271275
},
272276

273277
/**
274-
* Upload a item from the queue
278+
* Uploads a item from the queue
275279
* @param {Item|Number} value
276280
*/
277281
uploadItem: function (value) {
278-
var index = angular.isObject(value) ? this.getIndexOfItem(value) : value;
282+
var index = this.getIndexOfItem(value);
279283
var item = this.queue[ index ];
280284
var transport = item._hasForm() ? '_iframeTransport' : '_xhrTransport';
281285

@@ -290,6 +294,24 @@ app.factory('$fileUploader', [ '$compile', '$rootScope', '$http', '$window', fun
290294
this[ transport ](item);
291295
},
292296

297+
298+
/**
299+
* Cancels uploading of item from the queue
300+
* @param {Item|Number} value
301+
*/
302+
cancelItem: function(value) {
303+
var index = this.getIndexOfItem(value);
304+
var item = this.queue[ index ];
305+
306+
if (item._hasForm()) {
307+
// TODO: old browsers
308+
} else {
309+
item._xhr && item._xhr.abort();
310+
delete item._xhr;
311+
}
312+
},
313+
314+
293315
/**
294316
* Uploads all not uploaded items of queue
295317
*/
@@ -305,6 +327,16 @@ app.factory('$fileUploader', [ '$compile', '$rootScope', '$http', '$window', fun
305327
},
306328

307329

330+
/**
331+
* Cancels all uploads
332+
*/
333+
cancelAll: function() {
334+
this.getNotUploadedItems().forEach(function(item) {
335+
item.cancel();
336+
});
337+
},
338+
339+
308340
/**
309341
* Returns the total progress
310342
* @param {Number} [value]
@@ -340,7 +372,7 @@ app.factory('$fileUploader', [ '$compile', '$rootScope', '$http', '$window', fun
340372
var item = this.getReadyItems()[ 0 ];
341373
this.isUploading = false;
342374

343-
if ( angular.isDefined(item) ) {
375+
if (angular.isDefined(item)) {
344376
this.uploadItem(item);
345377
return;
346378
}
@@ -362,7 +394,7 @@ app.factory('$fileUploader', [ '$compile', '$rootScope', '$http', '$window', fun
362394
* The XMLHttpRequest transport
363395
*/
364396
_xhrTransport: function (item) {
365-
var xhr = new XMLHttpRequest();
397+
var xhr = item._xhr = new XMLHttpRequest();
366398
var form = new FormData();
367399
var that = this;
368400

@@ -394,6 +426,7 @@ app.factory('$fileUploader', [ '$compile', '$rootScope', '$http', '$window', fun
394426
};
395427

396428
xhr.onabort = function () {
429+
that.trigger('in:cancel', xhr, item);
397430
that.trigger('in:complete', xhr, item);
398431
};
399432

@@ -499,6 +532,7 @@ app.factory('$fileUploader', [ '$compile', '$rootScope', '$http', '$window', fun
499532
isUploading: false,
500533
isUploaded: false,
501534
isSuccess: false,
535+
isCancel: false,
502536
isError: false,
503537
progress: null,
504538
index: null
@@ -512,6 +546,9 @@ app.factory('$fileUploader', [ '$compile', '$rootScope', '$http', '$window', fun
512546
upload: function () {
513547
this.uploader.uploadItem(this);
514548
},
549+
cancel: function() {
550+
this.uploader.cancelItem(this);
551+
},
515552
_hasForm: function() {
516553
return !!(this.file && this.file._form);
517554
},
@@ -523,6 +560,7 @@ app.factory('$fileUploader', [ '$compile', '$rootScope', '$http', '$window', fun
523560
item.isUploading = true;
524561
item.isUploaded = false;
525562
item.isSuccess = false;
563+
item.isCancel = false;
526564
item.isError = false;
527565
item.progress = null;
528566
},
@@ -535,30 +573,35 @@ app.factory('$fileUploader', [ '$compile', '$rootScope', '$http', '$window', fun
535573
item.isUploading = false;
536574
item.isUploaded = true;
537575
item.isSuccess = true;
576+
item.isCancel = false;
538577
item.isError = false;
539578
item.progress = 100;
540579
item.index = null;
541580
item.uploader.trigger('success', xhr, item, response);
542581
},
582+
_cancel: function(event, xhr, item) {
583+
item.isReady = false;
584+
item.isUploading = false;
585+
item.isUploaded = false;
586+
item.isSuccess = false;
587+
item.isCancel = true;
588+
item.isError = false;
589+
item.progress = 0;
590+
item.index = null;
591+
item.uploader.trigger('cancel', xhr, item);
592+
},
543593
_error: function (event, xhr, item, response) {
544594
item.isReady = false;
545595
item.isUploading = false;
546596
item.isUploaded = true;
547597
item.isSuccess = false;
598+
item.isCancel = false;
548599
item.isError = true;
549600
item.progress = 100;
550601
item.index = null;
551602
item.uploader.trigger('error', xhr, item, response);
552603
},
553604
_complete: function (event, xhr, item, response) {
554-
var status = item.uploader._isSuccessCode(xhr.status);
555-
item.isReady = false;
556-
item.isUploading = false;
557-
item.isUploaded = true;
558-
item.isSuccess = status;
559-
item.isError = !status;
560-
item.progress = 100;
561-
item.index = null;
562605
item.uploader.trigger('complete', xhr, item, response);
563606
item.removeAfterUpload && item.remove();
564607
}

0 commit comments

Comments
 (0)