| 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(jhawkins): Use hidden instead of showInline* and display:none. | 5 // TODO(jhawkins): Use hidden instead of showInline* and display:none. |
| 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 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 82 * Class to hold all the information about the visible downloads. | 82 * Class to hold all the information about the visible downloads. |
| 83 * @constructor | 83 * @constructor |
| 84 */ | 84 */ |
| 85 function Downloads() { | 85 function Downloads() { |
| 86 /** | 86 /** |
| 87 * @type {!Object.<string, Download>} | 87 * @type {!Object.<string, Download>} |
| 88 * @private | 88 * @private |
| 89 */ | 89 */ |
| 90 this.downloads_ = {}; | 90 this.downloads_ = {}; |
| 91 this.node_ = $('downloads-display'); | 91 this.node_ = $('downloads-display'); |
| 92 this.noDownloadsOrResults_ = $('no-downloads-or-results'); |
| 92 this.summary_ = $('downloads-summary-text'); | 93 this.summary_ = $('downloads-summary-text'); |
| 93 this.searchText_ = ''; | 94 this.searchText_ = ''; |
| 94 | 95 |
| 95 // Keep track of the dates of the newest and oldest downloads so that we | 96 // Keep track of the dates of the newest and oldest downloads so that we |
| 96 // know where to insert them. | 97 // know where to insert them. |
| 97 this.newestTime_ = -1; | 98 this.newestTime_ = -1; |
| 98 | 99 |
| 99 // Icon load request queue. | 100 // Icon load request queue. |
| 100 this.iconLoadQueue_ = []; | 101 this.iconLoadQueue_ = []; |
| 101 this.isIconLoading_ = false; | 102 this.isIconLoading_ = false; |
| 102 | 103 |
| 103 this.progressForeground1_ = new Image(); | 104 this.progressForeground1_ = new Image(); |
| 104 this.progressForeground1_.src = | 105 this.progressForeground1_.src = |
| 105 'chrome://theme/IDR_DOWNLOAD_PROGRESS_FOREGROUND_32@1x'; | 106 'chrome://theme/IDR_DOWNLOAD_PROGRESS_FOREGROUND_32@1x'; |
| 106 this.progressForeground2_ = new Image(); | 107 this.progressForeground2_ = new Image(); |
| 107 this.progressForeground2_.src = | 108 this.progressForeground2_.src = |
| 108 'chrome://theme/IDR_DOWNLOAD_PROGRESS_FOREGROUND_32@2x'; | 109 'chrome://theme/IDR_DOWNLOAD_PROGRESS_FOREGROUND_32@2x'; |
| 109 | 110 |
| 110 window.addEventListener('keydown', this.onKeyDown_.bind(this)); | 111 window.addEventListener('keydown', this.onKeyDown_.bind(this)); |
| 112 |
| 113 this.onDownloadListChanged_(); |
| 111 } | 114 } |
| 112 | 115 |
| 113 /** | 116 /** |
| 114 * Called when a download has been updated or added. | 117 * Called when a download has been updated or added. |
| 115 * @param {BackendDownloadObject} download A backend download object | 118 * @param {BackendDownloadObject} download A backend download object |
| 116 */ | 119 */ |
| 117 Downloads.prototype.updated = function(download) { | 120 Downloads.prototype.updated = function(download) { |
| 118 var id = download.id; | 121 var id = download.id; |
| 119 if (!!this.downloads_[id]) { | 122 if (!!this.downloads_[id]) { |
| 120 this.downloads_[id].update(download); | 123 this.downloads_[id].update(download); |
| 121 } else { | 124 } else { |
| 122 this.downloads_[id] = new Download(download); | 125 this.downloads_[id] = new Download(download); |
| 123 // We get downloads in display order, so we don't have to worry about | 126 // We get downloads in display order, so we don't have to worry about |
| 124 // maintaining correct order - we can assume that any downloads not in | 127 // maintaining correct order - we can assume that any downloads not in |
| 125 // display order are new ones and so we can add them to the top of the | 128 // display order are new ones and so we can add them to the top of the |
| 126 // list. | 129 // list. |
| 127 if (download.started > this.newestTime_) { | 130 if (download.started > this.newestTime_) { |
| 128 this.node_.insertBefore(this.downloads_[id].node, this.node_.firstChild); | 131 this.node_.insertBefore(this.downloads_[id].node, this.node_.firstChild); |
| 129 this.newestTime_ = download.started; | 132 this.newestTime_ = download.started; |
| 130 } else { | 133 } else { |
| 131 this.node_.appendChild(this.downloads_[id].node); | 134 this.node_.appendChild(this.downloads_[id].node); |
| 132 } | 135 } |
| 133 } | 136 } |
| 134 // Download.prototype.update may change its nodeSince_ and nodeDate_, so | 137 // Download.prototype.update may change its nodeSince_ and nodeDate_, so |
| 135 // update all the date displays. | 138 // update all the date displays. |
| 136 // TODO(benjhayden) Only do this if its nodeSince_ or nodeDate_ actually did | 139 // TODO(benjhayden) Only do this if its nodeSince_ or nodeDate_ actually did |
| 137 // change since this may touch 150 elements and Downloads.prototype.updated | 140 // change since this may touch 150 elements and Downloads.prototype.updated |
| 138 // may be called 150 times. | 141 // may be called 150 times. |
| 139 this.updateDateDisplay_(); | 142 this.onDownloadListChanged_(); |
| 140 }; | 143 }; |
| 141 | 144 |
| 142 /** | 145 /** |
| 143 * Set our display search text. | 146 * Set our display search text. |
| 144 * @param {string} searchText The string we're searching for. | 147 * @param {string} searchText The string we're searching for. |
| 145 */ | 148 */ |
| 146 Downloads.prototype.setSearchText = function(searchText) { | 149 Downloads.prototype.setSearchText = function(searchText) { |
| 147 this.searchText_ = searchText; | 150 this.searchText_ = searchText; |
| 148 }; | 151 }; |
| 149 | 152 |
| 150 /** | 153 /** |
| 151 * Update the summary block above the results | 154 * Update the summary block above the results |
| 152 */ | 155 */ |
| 153 Downloads.prototype.updateSummary = function() { | 156 Downloads.prototype.updateSummary = function() { |
| 154 if (this.searchText_) { | 157 if (this.searchText_) { |
| 155 this.summary_.textContent = loadTimeData.getStringF('searchresultsfor', | 158 this.summary_.textContent = loadTimeData.getStringF('searchresultsfor', |
| 156 this.searchText_); | 159 this.searchText_); |
| 157 } else { | 160 } else { |
| 158 this.summary_.textContent = ''; | 161 this.summary_.textContent = ''; |
| 159 } | 162 } |
| 160 | |
| 161 var hasDownloads = false; | |
| 162 for (var i in this.downloads_) { | |
| 163 hasDownloads = true; | |
| 164 break; | |
| 165 } | |
| 166 }; | 163 }; |
| 167 | 164 |
| 168 /** | 165 /** |
| 169 * Returns the number of downloads in the model. Used by tests. | 166 * Returns the number of downloads in the model. Used by tests. |
| 170 * @return {number} Returns the number of downloads shown on the page. | 167 * @return {number} Returns the number of downloads shown on the page. |
| 171 */ | 168 */ |
| 172 Downloads.prototype.size = function() { | 169 Downloads.prototype.size = function() { |
| 173 return Object.keys(this.downloads_).length; | 170 return Object.keys(this.downloads_).length; |
| 174 }; | 171 }; |
| 175 | 172 |
| 176 /** | 173 /** |
| 177 * Update the date visibility in our nodes so that no date is | 174 * Called whenever the downloads lists items have changed (either by being |
| 178 * repeated. | 175 * updated, added, or removed). |
| 179 * @private | 176 * @private |
| 180 */ | 177 */ |
| 181 Downloads.prototype.updateDateDisplay_ = function() { | 178 Downloads.prototype.onDownloadListChanged_ = function() { |
| 179 // Update the date visibility in our nodes so that no date is repeated. |
| 182 var dateContainers = document.getElementsByClassName('date-container'); | 180 var dateContainers = document.getElementsByClassName('date-container'); |
| 183 var displayed = {}; | 181 var displayed = {}; |
| 184 for (var i = 0, container; container = dateContainers[i]; i++) { | 182 for (var i = 0, container; container = dateContainers[i]; i++) { |
| 185 var dateString = container.getElementsByClassName('date')[0].innerHTML; | 183 var dateString = container.getElementsByClassName('date')[0].innerHTML; |
| 186 if (!!displayed[dateString]) { | 184 if (!!displayed[dateString]) { |
| 187 container.style.display = 'none'; | 185 container.style.display = 'none'; |
| 188 } else { | 186 } else { |
| 189 displayed[dateString] = true; | 187 displayed[dateString] = true; |
| 190 container.style.display = 'block'; | 188 container.style.display = 'block'; |
| 191 } | 189 } |
| 192 } | 190 } |
| 191 |
| 192 this.noDownloadsOrResults_.textContent = loadTimeData.getString( |
| 193 this.searchText_ ? 'no_search_results' : 'no_downloads'); |
| 194 |
| 195 var hasDownloads = this.size() > 0; |
| 196 this.node_.hidden = !hasDownloads; |
| 197 this.noDownloadsOrResults_.hidden = hasDownloads; |
| 193 }; | 198 }; |
| 194 | 199 |
| 195 /** | 200 /** |
| 196 * Remove a download. | 201 * Remove a download. |
| 197 * @param {string} id The id of the download to remove. | 202 * @param {string} id The id of the download to remove. |
| 198 */ | 203 */ |
| 199 Downloads.prototype.remove = function(id) { | 204 Downloads.prototype.remove = function(id) { |
| 200 this.node_.removeChild(this.downloads_[id].node); | 205 this.node_.removeChild(this.downloads_[id].node); |
| 201 delete this.downloads_[id]; | 206 delete this.downloads_[id]; |
| 202 this.updateDateDisplay_(); | 207 this.onDownloadListChanged_(); |
| 203 }; | 208 }; |
| 204 | 209 |
| 205 /** | 210 /** |
| 206 * Clear all downloads and reset us back to a null state. | 211 * Clear all downloads and reset us back to a null state. |
| 207 */ | 212 */ |
| 208 Downloads.prototype.clear = function() { | 213 Downloads.prototype.clear = function() { |
| 209 for (var id in this.downloads_) { | 214 for (var id in this.downloads_) { |
| 210 this.downloads_[id].clear(); | 215 this.downloads_[id].clear(); |
| 211 this.remove(id); | 216 this.remove(id); |
| 212 } | 217 } |
| (...skipping 764 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 977 if (Date.now() - start > 50) { | 982 if (Date.now() - start > 50) { |
| 978 clearTimeout(resultsTimeout); | 983 clearTimeout(resultsTimeout); |
| 979 resultsTimeout = setTimeout(tryDownloadUpdatedPeriodically, 5); | 984 resultsTimeout = setTimeout(tryDownloadUpdatedPeriodically, 5); |
| 980 break; | 985 break; |
| 981 } | 986 } |
| 982 } | 987 } |
| 983 } | 988 } |
| 984 | 989 |
| 985 // Add handlers to HTML elements. | 990 // Add handlers to HTML elements. |
| 986 window.addEventListener('DOMContentLoaded', load); | 991 window.addEventListener('DOMContentLoaded', load); |
| OLD | NEW |