OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 // TODO(hcarmona): This file is big: it may be good to split it up. | 5 // TODO(hcarmona): This file is big: it may be good to split it up. |
6 | 6 |
7 /** | 7 /** |
8 * The type of the download object. The definition is based on | 8 * The type of the download object. The definition is based on |
9 * chrome/browser/ui/webui/downloads_dom_handler.cc:CreateDownloadItemValue() | 9 * chrome/browser/ui/webui/downloads_dom_handler.cc:CreateDownloadItemValue() |
10 * @typedef {{by_ext_id: (string|undefined), | 10 * @typedef {{by_ext_id: (string|undefined), |
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
165 /** | 165 /** |
166 * @type {!Object<string, Download>} | 166 * @type {!Object<string, Download>} |
167 * @private | 167 * @private |
168 */ | 168 */ |
169 this.downloads_ = {}; | 169 this.downloads_ = {}; |
170 this.node_ = $('downloads-display'); | 170 this.node_ = $('downloads-display'); |
171 this.summary_ = $('downloads-summary-text'); | 171 this.summary_ = $('downloads-summary-text'); |
172 this.searchText_ = ''; | 172 this.searchText_ = ''; |
173 this.focusGrid_ = new cr.ui.FocusGrid(); | 173 this.focusGrid_ = new cr.ui.FocusGrid(); |
174 | 174 |
175 // Keep track of the dates of the newest and oldest downloads so that we | |
176 // know where to insert them. | |
177 this.newestTime_ = -1; | |
178 | |
179 // Icon load request queue. | 175 // Icon load request queue. |
180 this.iconLoadQueue_ = []; | 176 this.iconLoadQueue_ = []; |
181 this.isIconLoading_ = false; | 177 this.isIconLoading_ = false; |
182 | 178 |
183 this.progressForeground1_ = new Image(); | 179 this.progressForeground1_ = new Image(); |
184 this.progressForeground1_.src = | 180 this.progressForeground1_.src = |
185 'chrome://theme/IDR_DOWNLOAD_PROGRESS_FOREGROUND_32@1x'; | 181 'chrome://theme/IDR_DOWNLOAD_PROGRESS_FOREGROUND_32@1x'; |
186 this.progressForeground2_ = new Image(); | 182 this.progressForeground2_ = new Image(); |
187 this.progressForeground2_.src = | 183 this.progressForeground2_.src = |
188 'chrome://theme/IDR_DOWNLOAD_PROGRESS_FOREGROUND_32@2x'; | 184 'chrome://theme/IDR_DOWNLOAD_PROGRESS_FOREGROUND_32@2x'; |
189 | 185 |
190 cr.ui.decorate('command', cr.ui.Command); | 186 cr.ui.decorate('command', cr.ui.Command); |
191 document.addEventListener('canExecute', this.onCanExecute_.bind(this)); | 187 document.addEventListener('canExecute', this.onCanExecute_.bind(this)); |
192 document.addEventListener('command', this.onCommand_.bind(this)); | 188 document.addEventListener('command', this.onCommand_.bind(this)); |
193 } | 189 } |
194 | 190 |
195 /** | 191 /** |
196 * Called when a download has been updated or added. | 192 * Called when a download has been updated or added. |
197 * @param {DownloadItem} download Information about a download. | 193 * @param {DownloadItem} download Information about a download. |
198 */ | 194 */ |
199 Downloads.prototype.updated = function(download) { | 195 Downloads.prototype.updated = function(download) { |
200 var id = download.id; | 196 var id = download.id; |
201 if (this.downloads_[id]) { | 197 if (this.downloads_[id]) { |
202 this.downloads_[id].update(download); | 198 this.downloads_[id].update(download); |
203 } else { | 199 } else { |
204 this.downloads_[id] = new Download(download); | 200 this.downloads_[id] = new Download(download); |
205 // We get downloads in display order, so we don't have to worry about | 201 |
206 // maintaining correct order - we can assume that any downloads not in | 202 // Sort downloads by start time and insert the new one in the right place. |
207 // display order are new ones and so we can add them to the top of the | 203 var startSorted = []; |
208 // list. | 204 for (var sortedId in this.downloads_) { |
209 if (download.started > this.newestTime_) { | 205 startSorted.push(this.downloads_[sortedId]); |
210 this.node_.insertBefore(this.downloads_[id].node, this.node_.firstChild); | |
211 this.newestTime_ = download.started; | |
212 } else { | |
213 this.node_.appendChild(this.downloads_[id].node); | |
214 } | 206 } |
207 startSorted.sort(function(d1, d2) { return d2.started_ - d1.started_; }); | |
208 | |
209 var indexOfNewDownload = startSorted.indexOf(this.downloads_[id]); | |
210 var before = startSorted[indexOfNewDownload + 1]; | |
211 | |
212 // If !before, insertBefore() acts like appendChild() and adds at the end. | |
213 this.node_.insertBefore(this.downloads_[id].node, before && before.node); | |
Dan Beam
2015/03/03 19:31:05
i could possibly do this:
if (startSorted.lengt
asanka
2015/03/03 20:45:56
Yeah. For undo operations that affect multiple dow
Dan Beam
2015/03/04 00:46:20
the problem with rebuilding DOM is that it messes
| |
215 } | 214 } |
215 | |
216 // Download.prototype.update may change its nodeSince_ and nodeDate_, so | 216 // Download.prototype.update may change its nodeSince_ and nodeDate_, so |
217 // update all the date displays. | 217 // update all the date displays. |
218 // TODO(benjhayden) Only do this if its nodeSince_ or nodeDate_ actually did | 218 // TODO(benjhayden) Only do this if its nodeSince_ or nodeDate_ actually did |
219 // change since this may touch 150 elements and Downloads.prototype.updated | 219 // change since this may touch 150 elements and Downloads.prototype.updated |
220 // may be called 150 times. | 220 // may be called 150 times. |
221 this.onDownloadListChanged_(); | 221 this.onDownloadListChanged_(); |
222 }; | 222 }; |
223 | 223 |
224 /** | 224 /** |
225 * Set our display search text. | 225 * Set our display search text. |
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
366 if (!this.isIconLoading_) | 366 if (!this.isIconLoading_) |
367 loadNext(); | 367 loadNext(); |
368 }; | 368 }; |
369 | 369 |
370 /** | 370 /** |
371 * Returns whether the displayed list needs to be updated or not. | 371 * Returns whether the displayed list needs to be updated or not. |
372 * @param {Array} downloads Array of download nodes. | 372 * @param {Array} downloads Array of download nodes. |
373 * @return {boolean} Returns true if the displayed list is to be updated. | 373 * @return {boolean} Returns true if the displayed list is to be updated. |
374 */ | 374 */ |
375 Downloads.prototype.isUpdateNeeded = function(downloads) { | 375 Downloads.prototype.isUpdateNeeded = function(downloads) { |
376 var size = 0; | 376 if (this.size() != downloads.length) |
377 for (var i in this.downloads_) | |
378 size++; | |
379 if (size != downloads.length) | |
380 return true; | 377 return true; |
381 // Since there are the same number of items in the incoming list as | 378 // Since there are the same number of items in the incoming list as |
382 // |this.downloads_|, there won't be any removed downloads without some | 379 // |this.downloads_|, there won't be any removed downloads without some |
383 // downloads having been inserted. So check only for new downloads in | 380 // downloads having been inserted. So check only for new downloads in |
384 // deciding whether to update. | 381 // deciding whether to update. |
385 for (var i = 0; i < downloads.length; i++) { | 382 for (var i = 0; i < downloads.length; i++) { |
386 if (!this.downloads_[downloads[i].id]) | 383 if (!this.downloads_[downloads[i].id]) |
387 return true; | 384 return true; |
388 } | 385 } |
389 return false; | 386 return false; |
(...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
626 /** | 623 /** |
627 * Updates the download to reflect new data. | 624 * Updates the download to reflect new data. |
628 * @param {DownloadItem} download Updated info about this download. | 625 * @param {DownloadItem} download Updated info about this download. |
629 */ | 626 */ |
630 Download.prototype.update = function(download) { | 627 Download.prototype.update = function(download) { |
631 this.id_ = download.id; | 628 this.id_ = download.id; |
632 this.filePath_ = download.file_path; | 629 this.filePath_ = download.file_path; |
633 this.fileUrl_ = download.file_url; | 630 this.fileUrl_ = download.file_url; |
634 this.fileName_ = download.file_name; | 631 this.fileName_ = download.file_name; |
635 this.url_ = download.url; | 632 this.url_ = download.url; |
633 this.started_ = download.started; | |
636 this.state_ = download.state; | 634 this.state_ = download.state; |
637 this.fileExternallyRemoved_ = download.file_externally_removed; | 635 this.fileExternallyRemoved_ = download.file_externally_removed; |
638 this.dangerType_ = download.danger_type; | 636 this.dangerType_ = download.danger_type; |
639 this.lastReasonDescription_ = download.last_reason_text; | 637 this.lastReasonDescription_ = download.last_reason_text; |
640 this.byExtensionId_ = download.by_ext_id; | 638 this.byExtensionId_ = download.by_ext_id; |
641 this.byExtensionName_ = download.by_ext_name; | 639 this.byExtensionName_ = download.by_ext_name; |
642 | 640 |
643 this.since_ = download.since_string; | 641 this.since_ = download.since_string; |
644 this.date_ = download.date_string; | 642 this.date_ = download.date_string; |
645 | 643 |
(...skipping 423 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1069 if (Date.now() - start > 50) { | 1067 if (Date.now() - start > 50) { |
1070 clearTimeout(resultsTimeout); | 1068 clearTimeout(resultsTimeout); |
1071 resultsTimeout = setTimeout(tryDownloadUpdatedPeriodically, 5); | 1069 resultsTimeout = setTimeout(tryDownloadUpdatedPeriodically, 5); |
1072 break; | 1070 break; |
1073 } | 1071 } |
1074 } | 1072 } |
1075 } | 1073 } |
1076 | 1074 |
1077 // Add handlers to HTML elements. | 1075 // Add handlers to HTML elements. |
1078 window.addEventListener('DOMContentLoaded', load); | 1076 window.addEventListener('DOMContentLoaded', load); |
OLD | NEW |