Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(208)

Side by Side Diff: chrome/browser/resources/downloads/downloads.js

Issue 722953002: downloads: add the ability to undo download removal. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: whoops Created 6 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 11 matching lines...) Expand all
22 * progress_status_text: (string|undefined), 22 * progress_status_text: (string|undefined),
23 * received: (number|undefined), 23 * received: (number|undefined),
24 * resume: boolean, 24 * resume: boolean,
25 * retry: boolean, 25 * retry: boolean,
26 * since_string: string, 26 * since_string: string,
27 * started: number, 27 * started: number,
28 * state: string, 28 * state: string,
29 * total: number, 29 * total: number,
30 * url: string}} 30 * url: string}}
31 */ 31 */
32 var BackendDownloadObject; 32 var DownloadItem;
33 33
34 /** 34 /**
35 * Sets the display style of a node. 35 * Sets the display style of a node.
36 * @param {!Element} node The target element to show or hide. 36 * @param {!Element} node The target element to show or hide.
37 * @param {boolean} isShow Should the target element be visible. 37 * @param {boolean} isShow Should the target element be visible.
38 */ 38 */
39 function showInline(node, isShow) { 39 function showInline(node, isShow) {
40 node.style.display = isShow ? 'inline' : 'none'; 40 node.style.display = isShow ? 'inline' : 'none';
41 } 41 }
42 42
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
101 this.iconLoadQueue_ = []; 101 this.iconLoadQueue_ = [];
102 this.isIconLoading_ = false; 102 this.isIconLoading_ = false;
103 103
104 this.progressForeground1_ = new Image(); 104 this.progressForeground1_ = new Image();
105 this.progressForeground1_.src = 105 this.progressForeground1_.src =
106 'chrome://theme/IDR_DOWNLOAD_PROGRESS_FOREGROUND_32@1x'; 106 'chrome://theme/IDR_DOWNLOAD_PROGRESS_FOREGROUND_32@1x';
107 this.progressForeground2_ = new Image(); 107 this.progressForeground2_ = new Image();
108 this.progressForeground2_.src = 108 this.progressForeground2_.src =
109 'chrome://theme/IDR_DOWNLOAD_PROGRESS_FOREGROUND_32@2x'; 109 'chrome://theme/IDR_DOWNLOAD_PROGRESS_FOREGROUND_32@2x';
110 110
111 window.addEventListener('keydown', this.onKeyDown_.bind(this)); 111 cr.ui.decorate('command', cr.ui.Command);
112 document.addEventListener('canExecute', this.onCanExecute_.bind(this));
113 document.addEventListener('command', this.onCommand_.bind(this));
112 114
113 this.updateResults(); 115 this.updateResults();
114 } 116 }
115 117
116 /** 118 /**
117 * Called when a download has been updated or added. 119 * Called when a download has been updated or added.
118 * @param {BackendDownloadObject} download A backend download object 120 * @param {DownloadItem} download Information about a download.
119 */ 121 */
120 Downloads.prototype.updated = function(download) { 122 Downloads.prototype.updated = function(download) {
121 var id = download.id; 123 var id = download.id;
122 if (!!this.downloads_[id]) { 124 if (this.downloads_[id]) {
123 this.downloads_[id].update(download); 125 this.downloads_[id].update(download);
124 } else { 126 } else {
125 this.downloads_[id] = new Download(download); 127 this.downloads_[id] = new Download(download);
126 // We get downloads in display order, so we don't have to worry about 128 // We get downloads in display order, so we don't have to worry about
127 // maintaining correct order - we can assume that any downloads not in 129 // maintaining correct order - we can assume that any downloads not in
128 // display order are new ones and so we can add them to the top of the 130 // display order are new ones and so we can add them to the top of the
129 // list. 131 // list.
130 if (download.started > this.newestTime_) { 132 if (download.started > this.newestTime_) {
131 this.node_.insertBefore(this.downloads_[id].node, this.node_.firstChild); 133 this.node_.insertBefore(this.downloads_[id].node, this.node_.firstChild);
132 this.newestTime_ = download.started; 134 this.newestTime_ = download.started;
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
187 * Called whenever the downloads lists items have changed (either by being 189 * Called whenever the downloads lists items have changed (either by being
188 * updated, added, or removed). 190 * updated, added, or removed).
189 * @private 191 * @private
190 */ 192 */
191 Downloads.prototype.onDownloadListChanged_ = function() { 193 Downloads.prototype.onDownloadListChanged_ = function() {
192 // Update the date visibility in our nodes so that no date is repeated. 194 // Update the date visibility in our nodes so that no date is repeated.
193 var dateContainers = document.getElementsByClassName('date-container'); 195 var dateContainers = document.getElementsByClassName('date-container');
194 var displayed = {}; 196 var displayed = {};
195 for (var i = 0, container; container = dateContainers[i]; i++) { 197 for (var i = 0, container; container = dateContainers[i]; i++) {
196 var dateString = container.getElementsByClassName('date')[0].innerHTML; 198 var dateString = container.getElementsByClassName('date')[0].innerHTML;
197 if (!!displayed[dateString]) { 199 if (displayed[dateString]) {
198 container.style.display = 'none'; 200 container.style.display = 'none';
199 } else { 201 } else {
200 displayed[dateString] = true; 202 displayed[dateString] = true;
201 container.style.display = 'block'; 203 container.style.display = 'block';
202 } 204 }
203 } 205 }
204 206
205 this.updateResults(); 207 this.updateResults();
206 }; 208 };
207 209
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
274 // downloads having been inserted. So check only for new downloads in 276 // downloads having been inserted. So check only for new downloads in
275 // deciding whether to update. 277 // deciding whether to update.
276 for (var i = 0; i < downloads.length; i++) { 278 for (var i = 0; i < downloads.length; i++) {
277 if (!this.downloads_[downloads[i].id]) 279 if (!this.downloads_[downloads[i].id])
278 return true; 280 return true;
279 } 281 }
280 return false; 282 return false;
281 }; 283 };
282 284
283 /** 285 /**
284 * Handles shortcut keys. 286 * @param {Event} e
285 * @param {Event} evt The keyboard event.
286 * @private 287 * @private
287 */ 288 */
288 Downloads.prototype.onKeyDown_ = function(evt) { 289 Downloads.prototype.onCanExecute_ = function(e) {
289 var keyEvt = /** @type {KeyboardEvent} */(evt); 290 e = /** @type {cr.ui.CanExecuteEvent} */(e);
290 if (keyEvt.keyCode == 67 && keyEvt.altKey) { // alt + c. 291 e.canExecute = document.activeElement != $('term');
292 };
293
294 /**
295 * @param {Event} e
296 * @private
297 */
298 Downloads.prototype.onCommand_ = function(e) {
299 if (e.command.id == 'undo-command')
300 chrome.send('undoRemove');
301 else if (e.command.id == 'clear-all-command')
291 clearAll(); 302 clearAll();
292 keyEvt.preventDefault();
293 }
294 }; 303 };
295 304
296 /////////////////////////////////////////////////////////////////////////////// 305 ///////////////////////////////////////////////////////////////////////////////
297 // Download 306 // Download
298 /** 307 /**
299 * A download and the DOM representation for that download. 308 * A download and the DOM representation for that download.
300 * @param {BackendDownloadObject} download A backend download object 309 * @param {DownloadItem} download Info about the download.
301 * @constructor 310 * @constructor
302 */ 311 */
303 function Download(download) { 312 function Download(download) {
304 // Create DOM 313 // Create DOM
305 this.node = createElementWithClassName( 314 this.node = createElementWithClassName(
306 'div', 'download' + (download.otr ? ' otr' : '')); 315 'div', 'download' + (download.otr ? ' otr' : ''));
307 316
308 // Dates 317 // Dates
309 this.dateContainer_ = createElementWithClassName('div', 'date-container'); 318 this.dateContainer_ = createElementWithClassName('div', 'date-container');
310 this.node.appendChild(this.dateContainer_); 319 this.node.appendChild(this.dateContainer_);
(...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after
516 525
517 // Listens for when device-pixel-ratio changes between any zoom level. 526 // Listens for when device-pixel-ratio changes between any zoom level.
518 [0.3, 0.4, 0.6, 0.7, 0.8, 0.95, 1.05, 1.2, 1.4, 1.6, 1.9, 2.2, 2.7, 3.5, 4.5 527 [0.3, 0.4, 0.6, 0.7, 0.8, 0.95, 1.05, 1.2, 1.4, 1.6, 1.9, 2.2, 2.7, 3.5, 4.5
519 ].forEach(function(scale) { 528 ].forEach(function(scale) {
520 var media = '(-webkit-min-device-pixel-ratio:' + scale + ')'; 529 var media = '(-webkit-min-device-pixel-ratio:' + scale + ')';
521 window.matchMedia(media).addListener(computeDownloadProgress); 530 window.matchMedia(media).addListener(computeDownloadProgress);
522 }); 531 });
523 532
524 /** 533 /**
525 * Updates the download to reflect new data. 534 * Updates the download to reflect new data.
526 * @param {BackendDownloadObject} download A backend download object 535 * @param {DownloadItem} download Updated info about this download.
527 */ 536 */
528 Download.prototype.update = function(download) { 537 Download.prototype.update = function(download) {
529 this.id_ = download.id; 538 this.id_ = download.id;
530 this.filePath_ = download.file_path; 539 this.filePath_ = download.file_path;
531 this.fileUrl_ = download.file_url; 540 this.fileUrl_ = download.file_url;
532 this.fileName_ = download.file_name; 541 this.fileName_ = download.file_name;
533 this.url_ = download.url; 542 this.url_ = download.url;
534 this.state_ = download.state; 543 this.state_ = download.state;
535 this.fileExternallyRemoved_ = download.file_externally_removed; 544 this.fileExternallyRemoved_ = download.file_externally_removed;
536 this.dangerType_ = download.danger_type; 545 this.dangerType_ = download.danger_type;
(...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after
776 }; 785 };
777 786
778 /** 787 /**
779 * Tells the backend to initiate a drag, allowing users to drag 788 * Tells the backend to initiate a drag, allowing users to drag
780 * files from the download page and have them appear as native file 789 * files from the download page and have them appear as native file
781 * drags. 790 * drags.
782 * @return {boolean} Returns false to prevent the default action. 791 * @return {boolean} Returns false to prevent the default action.
783 * @private 792 * @private
784 */ 793 */
785 Download.prototype.drag_ = function() { 794 Download.prototype.drag_ = function() {
786 chrome.send('drag', [this.id_.toString()]); 795 chrome.send('drag', [this.id_]);
Dan Beam 2014/11/13 02:51:16 i don't think that |this.id_| being a double (a nu
787 return false; 796 return false;
788 }; 797 };
789 798
790 /** 799 /**
791 * Tells the backend to open this file. 800 * Tells the backend to open this file.
792 * @return {boolean} Returns false to prevent the default action. 801 * @return {boolean} Returns false to prevent the default action.
793 * @private 802 * @private
794 */ 803 */
795 Download.prototype.openFile_ = function() { 804 Download.prototype.openFile_ = function() {
796 chrome.send('openFile', [this.id_.toString()]); 805 chrome.send('openFile', [this.id_]);
797 return false; 806 return false;
798 }; 807 };
799 808
800 /** 809 /**
801 * Tells the backend that the user chose to save a dangerous file. 810 * Tells the backend that the user chose to save a dangerous file.
802 * @return {boolean} Returns false to prevent the default action. 811 * @return {boolean} Returns false to prevent the default action.
803 * @private 812 * @private
804 */ 813 */
805 Download.prototype.saveDangerous_ = function() { 814 Download.prototype.saveDangerous_ = function() {
806 chrome.send('saveDangerous', [this.id_.toString()]); 815 chrome.send('saveDangerous', [this.id_]);
807 return false; 816 return false;
808 }; 817 };
809 818
810 /** 819 /**
811 * Tells the backend that the user chose to discard a dangerous file. 820 * Tells the backend that the user chose to discard a dangerous file.
812 * @return {boolean} Returns false to prevent the default action. 821 * @return {boolean} Returns false to prevent the default action.
813 * @private 822 * @private
814 */ 823 */
815 Download.prototype.discardDangerous_ = function() { 824 Download.prototype.discardDangerous_ = function() {
816 chrome.send('discardDangerous', [this.id_.toString()]); 825 chrome.send('discardDangerous', [this.id_]);
817 downloads.remove(this.id_); 826 downloads.remove(this.id_);
818 return false; 827 return false;
819 }; 828 };
820 829
821 /** 830 /**
822 * Tells the backend to show the file in explorer. 831 * Tells the backend to show the file in explorer.
823 * @return {boolean} Returns false to prevent the default action. 832 * @return {boolean} Returns false to prevent the default action.
824 * @private 833 * @private
825 */ 834 */
826 Download.prototype.show_ = function() { 835 Download.prototype.show_ = function() {
827 chrome.send('show', [this.id_.toString()]); 836 chrome.send('show', [this.id_]);
828 return false; 837 return false;
829 }; 838 };
830 839
831 /** 840 /**
832 * Tells the backend to pause this download. 841 * Tells the backend to pause this download.
833 * @return {boolean} Returns false to prevent the default action. 842 * @return {boolean} Returns false to prevent the default action.
834 * @private 843 * @private
835 */ 844 */
836 Download.prototype.pause_ = function() { 845 Download.prototype.pause_ = function() {
837 chrome.send('pause', [this.id_.toString()]); 846 chrome.send('pause', [this.id_]);
838 return false; 847 return false;
839 }; 848 };
840 849
841 /** 850 /**
842 * Tells the backend to resume this download. 851 * Tells the backend to resume this download.
843 * @return {boolean} Returns false to prevent the default action. 852 * @return {boolean} Returns false to prevent the default action.
844 * @private 853 * @private
845 */ 854 */
846 Download.prototype.resume_ = function() { 855 Download.prototype.resume_ = function() {
847 chrome.send('resume', [this.id_.toString()]); 856 chrome.send('resume', [this.id_]);
848 return false; 857 return false;
849 }; 858 };
850 859
851 /** 860 /**
852 * Tells the backend to remove this download from history and download shelf. 861 * Tells the backend to remove this download from history and download shelf.
853 * @return {boolean} Returns false to prevent the default action. 862 * @return {boolean} Returns false to prevent the default action.
854 * @private 863 * @private
855 */ 864 */
856 Download.prototype.remove_ = function() { 865 Download.prototype.remove_ = function() {
857 if (loadTimeData.getBoolean('allow_deleting_history')) { 866 if (loadTimeData.getBoolean('allow_deleting_history'))
858 chrome.send('remove', [this.id_.toString()]); 867 chrome.send('remove', [this.id_]);
859 }
860 return false; 868 return false;
861 }; 869 };
862 870
863 /** 871 /**
864 * Tells the backend to cancel this download. 872 * Tells the backend to cancel this download.
865 * @return {boolean} Returns false to prevent the default action. 873 * @return {boolean} Returns false to prevent the default action.
866 * @private 874 * @private
867 */ 875 */
868 Download.prototype.cancel_ = function() { 876 Download.prototype.cancel_ = function() {
869 chrome.send('cancel', [this.id_.toString()]); 877 chrome.send('cancel', [this.id_]);
870 return false; 878 return false;
871 }; 879 };
872 880
873 /////////////////////////////////////////////////////////////////////////////// 881 ///////////////////////////////////////////////////////////////////////////////
874 // Page: 882 // Page:
875 var downloads, resultsTimeout; 883 var downloads, resultsTimeout;
876 884
877 // TODO(benjhayden): Rename Downloads to DownloadManager, downloads to 885 // TODO(benjhayden): Rename Downloads to DownloadManager, downloads to
878 // downloadManager or theDownloadManager or DownloadManager.get() to prevent 886 // downloadManager or theDownloadManager or DownloadManager.get() to prevent
879 // confusing Downloads with Download. 887 // confusing Downloads with Download.
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
991 if (Date.now() - start > 50) { 999 if (Date.now() - start > 50) {
992 clearTimeout(resultsTimeout); 1000 clearTimeout(resultsTimeout);
993 resultsTimeout = setTimeout(tryDownloadUpdatedPeriodically, 5); 1001 resultsTimeout = setTimeout(tryDownloadUpdatedPeriodically, 5);
994 break; 1002 break;
995 } 1003 }
996 } 1004 }
997 } 1005 }
998 1006
999 // Add handlers to HTML elements. 1007 // Add handlers to HTML elements.
1000 window.addEventListener('DOMContentLoaded', load); 1008 window.addEventListener('DOMContentLoaded', load);
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698