| Index: chrome/browser/resources/md_downloads/manager.js
|
| diff --git a/chrome/browser/resources/md_downloads/manager.js b/chrome/browser/resources/md_downloads/manager.js
|
| index 9c4c9ff294a261b85dfa8e3958a404f36c2b95f7..e4c54e41895380c33228d3d17dceff06977643f9 100644
|
| --- a/chrome/browser/resources/md_downloads/manager.js
|
| +++ b/chrome/browser/resources/md_downloads/manager.js
|
| @@ -11,15 +11,10 @@ cr.define('downloads', function() {
|
| type: Boolean,
|
| value: false,
|
| },
|
| - },
|
|
|
| - /**
|
| - * @return {number} A guess at how many items could be visible at once.
|
| - * @private
|
| - */
|
| - guesstimateNumberOfVisibleItems_: function() {
|
| - var toolbarHeight = this.$.toolbar.offsetHeight;
|
| - return Math.floor((window.innerHeight - toolbarHeight) / 46) + 1;
|
| + items_: {
|
| + type: Array,
|
| + },
|
| },
|
|
|
| /**
|
| @@ -59,33 +54,6 @@ cr.define('downloads', function() {
|
| downloads.ActionService.getInstance().search('');
|
| },
|
|
|
| - /** @private */
|
| - rebuildFocusGrid_: function() {
|
| - var activeElement = this.shadowRoot.activeElement;
|
| -
|
| - var activeItem;
|
| - if (activeElement && activeElement.tagName == 'downloads-item')
|
| - activeItem = activeElement;
|
| -
|
| - var activeControl = activeItem && activeItem.shadowRoot.activeElement;
|
| -
|
| - /** @private {!cr.ui.FocusGrid} */
|
| - this.focusGrid_ = this.focusGrid_ || new cr.ui.FocusGrid;
|
| - this.focusGrid_.destroy();
|
| -
|
| - var boundary = this.$['downloads-list'];
|
| -
|
| - this.items_.forEach(function(item) {
|
| - var focusRow = new downloads.FocusRow(item.content, boundary);
|
| - this.focusGrid_.addRow(focusRow);
|
| -
|
| - if (item == activeItem && !cr.ui.FocusRow.isFocusable(activeControl))
|
| - focusRow.getEquivalentElement(activeControl).focus();
|
| - }, this);
|
| -
|
| - this.focusGrid_.ensureRowActive();
|
| - },
|
| -
|
| /**
|
| * @return {number} The number of downloads shown on the page.
|
| * @private
|
| @@ -100,62 +68,24 @@ cr.define('downloads', function() {
|
| * @private
|
| */
|
| updateAll_: function(list) {
|
| - var oldIdMap = this.idMap_ || {};
|
| -
|
| - /** @private {!Object<!downloads.Item>} */
|
| - this.idMap_ = {};
|
| -
|
| - /** @private {!Array<!downloads.Item>} */
|
| - this.items_ = [];
|
| -
|
| - if (!this.iconLoader_) {
|
| - var guesstimate = Math.max(this.guesstimateNumberOfVisibleItems_(), 1);
|
| - /** @private {downloads.ThrottledIconLoader} */
|
| - this.iconLoader_ = new downloads.ThrottledIconLoader(guesstimate);
|
| - }
|
| + /** @private {!Object<number>} */
|
| + this.idToIndex_ = {};
|
|
|
| for (var i = 0; i < list.length; ++i) {
|
| var data = list[i];
|
| - var id = data.id;
|
|
|
| - // Re-use old items when possible (saves work, preserves focus).
|
| - var item = oldIdMap[id] || new downloads.Item(this.iconLoader_);
|
| + this.idToIndex_[data.id] = data.index = i;
|
|
|
| - this.idMap_[id] = item; // Associated by ID for fast lookup.
|
| - this.items_.push(item); // Add to sorted list for order.
|
| -
|
| - // Render |item| but don't actually add to the DOM yet. |this.items_|
|
| - // must be fully created to be able to find the right spot to insert.
|
| - item.update(data);
|
| -
|
| - // Collapse redundant dates.
|
| var prev = list[i - 1];
|
| - item.hideDate = !!prev && prev.date_string == data.date_string;
|
| -
|
| - delete oldIdMap[id];
|
| + data.hideDate = !!prev && prev.date_string == data.date_string;
|
| }
|
|
|
| - // Remove stale, previously rendered items from the DOM.
|
| - for (var id in oldIdMap) {
|
| - if (oldIdMap[id].parentNode)
|
| - oldIdMap[id].parentNode.removeChild(oldIdMap[id]);
|
| - delete oldIdMap[id];
|
| - }
|
| -
|
| - for (var i = 0; i < this.items_.length; ++i) {
|
| - var item = this.items_[i];
|
| - if (item.parentNode) // Already in the DOM; skip.
|
| - continue;
|
| -
|
| - var before = null;
|
| - // Find the next rendered item after this one, and insert before it.
|
| - for (var j = i + 1; !before && j < this.items_.length; ++j) {
|
| - if (this.items_[j].parentNode)
|
| - before = this.items_[j];
|
| - }
|
| - // If |before| is null, |item| will just get added at the end.
|
| - this.$['downloads-list'].insertBefore(item, before);
|
| - }
|
| + // TODO(dbeam): this resets the scroll position, which is a huge bummer.
|
| + // Removing something from the bottom of the list should not scroll you
|
| + // back to the top. The grand plan is to restructure how the C++ sends the
|
| + // JS data so that it only gets updates (rather than the most recent set
|
| + // of items). TL;DR - we can't ship with this bug.
|
| + this.items_ = list;
|
|
|
| var hasDownloads = this.size_() > 0;
|
| if (!hasDownloads) {
|
| @@ -170,9 +100,6 @@ cr.define('downloads', function() {
|
| this.$.toolbar.downloadsShowing = this.hasDownloads_;
|
|
|
| this.$.panel.classList.remove('loading');
|
| -
|
| - var allReady = this.items_.map(function(i) { return i.readyPromise; });
|
| - Promise.all(allReady).then(this.rebuildFocusGrid_.bind(this));
|
| },
|
|
|
| /**
|
| @@ -180,19 +107,9 @@ cr.define('downloads', function() {
|
| * @private
|
| */
|
| updateItem_: function(data) {
|
| - var item = this.idMap_[data.id];
|
| -
|
| - var activeControl = this.shadowRoot.activeElement == item ?
|
| - item.shadowRoot.activeElement : null;
|
| -
|
| - item.update(data);
|
| -
|
| - this.async(function() {
|
| - if (activeControl && !cr.ui.FocusRow.isFocusable(activeControl)) {
|
| - var focusRow = this.focusGrid_.getRowForRoot(item.content);
|
| - focusRow.getEquivalentElement(activeControl).focus();
|
| - }
|
| - }.bind(this));
|
| + var index = this.idToIndex_[data.id];
|
| + this.set('items_.' + index, data);
|
| + this.$['downloads-list'].updateSizeForItem(index);
|
| },
|
| });
|
|
|
|
|