Pin Chrome's shortcut to the Win10 Start menu on install and OS upgrade.
[chromium-blink-merge.git] / chrome / browser / resources / md_downloads / manager.js
blob065290d2558067425fec16a78087f81cb7821561
1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 cr.define('downloads', function() {
6   var Manager = Polymer({
7     is: 'downloads-manager',
9     created: function() {
10       /** @private {!downloads.ActionService} */
11       this.actionService_ = new downloads.ActionService;
12     },
14     properties: {
15       hasDownloads_: {
16         type: Boolean,
17         value: false,
18       },
19     },
21     /**
22      * @return {number} A guess at how many items could be visible at once.
23      * @private
24      */
25     guesstimateNumberOfVisibleItems_: function() {
26       var toolbarHeight = this.$.toolbar.offsetHeight;
27       return Math.floor((window.innerHeight - toolbarHeight) / 46) + 1;
28     },
30     /**
31      * @param {Event} e
32      * @private
33      */
34     onCanExecute_: function(e) {
35       e = /** @type {cr.ui.CanExecuteEvent} */(e);
36       switch (e.command.id) {
37         case 'undo-command':
38           e.canExecute = this.$.toolbar.canUndo();
39           break;
40         case 'clear-all-command':
41           e.canExecute = true;
42           break;
43       }
44     },
46     /**
47      * @param {Event} e
48      * @private
49      */
50     onCommand_: function(e) {
51       if (e.command.id == 'clear-all-command')
52         this.actionService_.clearAll();
53       else if (e.command.id == 'undo-command')
54         this.actionService_.undo();
55     },
57     /** @private */
58     onLoad_: function() {
59       this.$.toolbar.setActionService(this.actionService_);
61       cr.ui.decorate('command', cr.ui.Command);
62       document.addEventListener('canExecute', this.onCanExecute_.bind(this));
63       document.addEventListener('command', this.onCommand_.bind(this));
65       // Shows all downloads.
66       this.actionService_.search('');
67     },
69     /**
70      * @return {number} The number of downloads shown on the page.
71      * @private
72      */
73     size_: function() {
74       return this.items_.length;
75     },
77     /**
78      * Called when all items need to be updated.
79      * @param {!Array<!downloads.Data>} list A list of new download data.
80      * @private
81      */
82     updateAll_: function(list) {
83       var oldIdMap = this.idMap_ || {};
85       /** @private {!Object<!downloads.ItemView>} */
86       this.idMap_ = {};
88       /** @private {!Array<!downloads.ItemView>} */
89       this.items_ = [];
91       if (!this.iconLoader_) {
92         var guesstimate = Math.max(this.guesstimateNumberOfVisibleItems_(), 1);
93         /** @private {downloads.ThrottledIconLoader} */
94         this.iconLoader_ = new downloads.ThrottledIconLoader(guesstimate);
95       }
97       for (var i = 0; i < list.length; ++i) {
98         var data = list[i];
99         var id = data.id;
101         // Re-use old items when possible (saves work, preserves focus).
102         var item = oldIdMap[id] ||
103             new downloads.ItemView(this.iconLoader_, this.actionService_);
105         this.idMap_[id] = item;  // Associated by ID for fast lookup.
106         this.items_.push(item);  // Add to sorted list for order.
108         // Render |item| but don't actually add to the DOM yet. |this.items_|
109         // must be fully created to be able to find the right spot to insert.
110         item.update(data);
112         // Collapse redundant dates.
113         var prev = list[i - 1];
114         item.hideDate = !!prev && prev.date_string == data.date_string;
116         delete oldIdMap[id];
117       }
119       // Remove stale, previously rendered items from the DOM.
120       for (var id in oldIdMap) {
121         if (oldIdMap[id].parentNode)
122           oldIdMap[id].parentNode.removeChild(oldIdMap[id]);
123         delete oldIdMap[id];
124       }
126       for (var i = 0; i < this.items_.length; ++i) {
127         var item = this.items_[i];
128         if (item.parentNode)  // Already in the DOM; skip.
129           continue;
131         var before = null;
132         // Find the next rendered item after this one, and insert before it.
133         for (var j = i + 1; !before && j < this.items_.length; ++j) {
134           if (this.items_[j].parentNode)
135             before = this.items_[j];
136         }
137         // If |before| is null, |item| will just get added at the end.
138         this.$['downloads-list'].insertBefore(item, before);
139       }
141       this.hasDownloads_ = this.size_() > 0;
143       if (loadTimeData.getBoolean('allowDeletingHistory'))
144         this.$.toolbar.canClearAll = this.hasDownloads_;
145     },
147     /**
148      * @param {!downloads.Data} data
149      * @private
150      */
151     updateItem_: function(data) {
152       this.idMap_[data.id].update(data);
153     },
154   });
156   Manager.size = function() {
157     return document.querySelector('downloads-manager').size_();
158   };
160   Manager.updateAll = function(list) {
161     document.querySelector('downloads-manager').updateAll_(list);
162   };
164   Manager.updateItem = function(item) {
165     document.querySelector('downloads-manager').updateItem_(item);
166   };
168   Manager.onLoad = function() {
169     document.querySelector('downloads-manager').onLoad_();
170   };
172   return {Manager: Manager};
175 window.addEventListener('load', downloads.Manager.onLoad);