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 |