|
17 | 17 |
|
18 | 18 | properties: {
|
19 | 19 |
|
20 |
| - // Files that are currently being uploaded |
| 20 | + /** |
| 21 | + * Files that are currently being uploaded. |
| 22 | + * It's a Map where keys are files and values are upload details. |
| 23 | + */ |
21 | 24 | uploadingFiles: {
|
22 |
| - type: Array, |
| 25 | + type: Map, |
23 | 26 | readOnly: true,
|
24 |
| - value: _ => [] |
| 27 | + value: _ => { |
| 28 | + return new Map(); |
| 29 | + } |
25 | 30 | },
|
26 | 31 |
|
| 32 | + // @optional |
27 | 33 | url: String,
|
28 | 34 |
|
| 35 | + // @optional |
29 | 36 | method: {
|
30 | 37 | type: String,
|
31 | 38 | value: 'POST',
|
32 | 39 | },
|
33 | 40 |
|
| 41 | + // @optional |
34 | 42 | headers: Object,
|
35 | 43 |
|
36 | 44 | uploading: {
|
|
40 | 48 | },
|
41 | 49 |
|
42 | 50 | // Current XMLHTTPRequest
|
43 |
| - _currentXHR: Object, |
44 |
| - |
45 |
| - _filesUploadDetail: { |
46 |
| - type: WeakMap, |
47 |
| - value: _ => { |
48 |
| - return new WeakMap(); |
49 |
| - } |
50 |
| - } |
| 51 | + _currentXHR: Object |
51 | 52 |
|
52 | 53 | },
|
53 | 54 |
|
54 | 55 | /**
|
55 | 56 | * Add a single file to the uploading queue.
|
| 57 | + * |
56 | 58 | * @param {!File}
|
57 | 59 | */
|
58 |
| - addFile(file) { |
| 60 | + addFile(file, options) { |
59 | 61 | if (!this._isFileOnQueue(file)) {
|
60 |
| - this.push('uploadingFiles', file); |
| 62 | + this.uploadingFiles.set(file, {xhrParams: options, state: 'queue'}); |
61 | 63 |
|
62 | 64 | if (!this.uploading) {
|
63 | 65 | this._uploadStart();
|
|
76 | 78 | },
|
77 | 79 |
|
78 | 80 | _resumeQueue() {
|
79 |
| - for (const file of this.uploadingFiles) { |
80 |
| - if (!this._filesUploadDetail.get(file)) { |
81 |
| - this._upload(file); |
| 81 | + for (const [file, detail] of this.uploadingFiles) { |
| 82 | + if (detail.state === 'queue') { |
| 83 | + this._uploadFile(file, detail.xhrParams); |
82 | 84 | break;
|
83 | 85 | }
|
84 | 86 | }
|
|
94 | 96 |
|
95 | 97 | this._progressOverlay = this.create('file-uploader-progress', {
|
96 | 98 | opened: true,
|
97 |
| - uploadingFiles: this.uploadingFiles, |
98 |
| - filesUploadDetail: this._filesUploadDetail |
| 99 | + uploadingFiles: this.uploadingFiles |
99 | 100 | });
|
100 | 101 |
|
101 | 102 | this._progressOverlay.addEventListener('request-cancel-upload', _ => {
|
|
105 | 106 | this._resumeQueue();
|
106 | 107 | },
|
107 | 108 |
|
108 |
| - _upload(file) { |
| 109 | + _uploadFile(file, xhrParams) { |
109 | 110 | if (!this.uploading) {
|
110 | 111 | return;
|
111 | 112 | }
|
112 | 113 |
|
113 | 114 | this._progressOverlay.currentFile = file;
|
| 115 | + const detail = this.uploadingFiles.get(file); |
114 | 116 |
|
115 |
| - this._xhr().then(response => { |
| 117 | + this._xhr(xhrParams).then(response => { |
116 | 118 | const data = {file, url: response.url};
|
117 | 119 |
|
118 |
| - this._filesUploadDetail.set(file, {state: 'uploaded'}); |
119 |
| - this.fire('file-uploaded', data); |
| 120 | + detail.state = 'uploaded'; |
| 121 | + this.fire('file-uploaded', {file, detail}); |
120 | 122 | return data;
|
121 | 123 | }).catch(error => {
|
122 |
| - this._filesUploadDetail.set(file, {state: 'failed'}); |
123 |
| - this.fire('file-upload-error', {file, error}); |
| 124 | + detail.state = 'failed'; |
| 125 | + detail.error = error; |
| 126 | + this.fire('error', {file, detail}); |
124 | 127 | throw error;
|
125 | 128 | }).then(_ => {
|
126 | 129 | this._resumeQueue();
|
|
136 | 139 | this._progressOverlay.opened = false;
|
137 | 140 | // this._progressOverlay is automatically removed when it's closed
|
138 | 141 | this._progressOverlay = null;
|
139 |
| - this._filesUploadDetail = new WeakMap(); |
140 |
| - this.uploadingFiles([]); |
| 142 | + this.uploadingFiles.clear(); |
141 | 143 | this._setUploading(false);
|
142 | 144 | },
|
143 | 145 |
|
144 | 146 | _isFileOnQueue(file) {
|
145 |
| - return this.uploadingFiles.find(f => { |
146 |
| - return f.name === file.name && f.size === file.size; |
147 |
| - }); |
| 147 | + let result = false; |
| 148 | + |
| 149 | + for (let [f, detail] of this.uploadingFiles) { |
| 150 | + if (f.name === file.name && f.size === file.size) { |
| 151 | + result = true; |
| 152 | + break; |
| 153 | + } |
| 154 | + } |
| 155 | + |
| 156 | + return result; |
148 | 157 | },
|
149 | 158 |
|
150 | 159 | _xhr({file, url = this.url, method = this.method, headers = this.headers} = {}) {
|
|
0 commit comments