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

Unified Diff: chrome/browser/resources/md_downloads/crisper.js

Issue 1428833005: MD Downloads: track downloads in C++, dispatch discrete JS updates (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: merge Created 5 years 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 side-by-side diff with in-line comments
Download patch
Index: chrome/browser/resources/md_downloads/crisper.js
diff --git a/chrome/browser/resources/md_downloads/crisper.js b/chrome/browser/resources/md_downloads/crisper.js
index da4452387f9851bc529b874c8665cd0736bb3498..ee13e9ccc5999ff5cc0467850c70ed2c6112fb24 100644
--- a/chrome/browser/resources/md_downloads/crisper.js
+++ b/chrome/browser/resources/md_downloads/crisper.js
@@ -1531,6 +1531,27 @@ cr.define('downloads', function() {
/** @constructor */
function ActionService() {}
+ /**
+ * @param {string} s
+ * @return {string} |s| without whitespace at the beginning or end.
+ */
+ function trim(s) { return s.trim(); }
+
+ /**
+ * @param {string|undefined} value
+ * @return {boolean} Whether |value| is truthy.
+ */
+ function truthy(value) { return !!value; }
+
+ /**
+ * @param {string} searchText Input typed by the user into a search box.
+ * @return {Array<string>} A list of terms extracted from |searchText|.
+ */
+ ActionService.splitTerms = function(searchText) {
+ // Split quoted terms (e.g., 'The "lazy" dog' => ['The', 'lazy', 'dog']).
+ return searchText.split(/"([^"]*)"/).map(trim).filter(truthy);
+ };
+
ActionService.prototype = {
/** @param {string} id ID of the download to cancel. */
cancel: chromeSendWithId('cancel'),
@@ -1557,12 +1578,15 @@ cr.define('downloads', function() {
/** @param {string} id ID of the download that the user started dragging. */
drag: chromeSendWithId('drag'),
+ /** @private {boolean} */
+ isSearching_: false,
+
/**
* @return {boolean} Whether the user is currently searching for downloads
* (i.e. has a non-empty search term).
*/
isSearching: function() {
- return this.searchText_.length > 0;
+ return this.isSearching_;
},
/** Opens the current local destination for downloads. */
@@ -1595,9 +1619,10 @@ cr.define('downloads', function() {
this.searchText_ = searchText;
- // Split quoted terms (e.g., 'The "lazy" dog' => ['The', 'lazy', 'dog']).
- function trim(s) { return s.trim(); }
- chrome.send('getDownloads', searchText.split(/"([^"]*)"/).map(trim));
+ var terms = ActionService.splitTerms(searchText);
+ this.isSearching_ = terms.length > 0;
+
+ chrome.send('getDownloads', terms);
},
/**
@@ -16937,12 +16962,13 @@ cr.define('downloads', function() {
properties: {
hasDownloads_: {
+ observer: 'hasDownloadsChanged_',
type: Boolean,
- value: false,
},
items_: {
type: Array,
+ value: function() { return []; },
},
},
@@ -16950,6 +16976,46 @@ cr.define('downloads', function() {
loading: true,
},
+ observers: [
+ 'itemsChanged_(items_.*)',
+ ],
+
+ /** @private */
+ clearAll_: function() {
+ this.set('items_', []);
+ },
+
+ /** @private */
+ hasDownloadsChanged_: function() {
+ if (loadTimeData.getBoolean('allowDeletingHistory'))
+ this.$.toolbar.downloadsShowing = this.hasDownloads_;
+
+ if (this.hasDownloads_) {
+ this.$['downloads-list'].fire('iron-resize');
+ } else {
+ var isSearching = downloads.ActionService.getInstance().isSearching();
+ var messageToShow = isSearching ? 'noSearchResults' : 'noDownloads';
+ this.$['no-downloads'].querySelector('span').textContent =
+ loadTimeData.getString(messageToShow);
+ }
+ },
+
+ /**
+ * @param {number} index
+ * @param {!Array<!downloads.Data>} list
+ * @private
+ */
+ insertItems_: function(index, list) {
+ this.splice.apply(this, ['items_', index, 0].concat(list));
+ this.updateHideDates_(index, index + list.length);
+ this.removeAttribute('loading');
+ },
+
+ /** @private */
+ itemsChanged_: function() {
+ this.hasDownloads_ = this.items_.length > 0;
+ },
+
/**
* @param {Event} e
* @private
@@ -16988,78 +17054,65 @@ cr.define('downloads', function() {
},
/**
- * @return {number} The number of downloads shown on the page.
+ * @param {number} index
* @private
*/
- size_: function() {
- return this.items_.length;
+ removeItem_: function(index) {
+ this.splice('items_', index, 1);
+ this.updateHideDates_(index, index);
},
/**
- * Called when all items need to be updated.
- * @param {!Array<!downloads.Data>} list A list of new download data.
+ * @param {number} start
+ * @param {number} end
* @private
*/
- updateAll_: function(list) {
- /** @private {!Object<number>} */
- this.idToIndex_ = {};
-
- for (var i = 0; i < list.length; ++i) {
- var data = list[i];
-
- this.idToIndex_[data.id] = data.index = i;
-
- var prev = list[i - 1];
- data.hideDate = !!prev && prev.date_string == data.date_string;
+ updateHideDates_: function(start, end) {
+ for (var i = start; i <= end; ++i) {
+ var current = this.items_[i];
+ if (!current)
+ continue;
+ var prev = this.items_[i - 1];
+ current.hideDate = !!prev && prev.date_string == current.date_string;
}
-
- // 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) {
- var isSearching = downloads.ActionService.getInstance().isSearching();
- var messageToShow = isSearching ? 'noSearchResults' : 'noDownloads';
- this.$['no-downloads'].querySelector('span').textContent =
- loadTimeData.getString(messageToShow);
- }
- this.hasDownloads_ = hasDownloads;
-
- if (loadTimeData.getBoolean('allowDeletingHistory'))
- this.$.toolbar.downloadsShowing = this.hasDownloads_;
-
- this.removeAttribute('loading');
},
/**
+ * @param {number} index
* @param {!downloads.Data} data
* @private
*/
- updateItem_: function(data) {
- var index = this.idToIndex_[data.id];
+ updateItem_: function(index, data) {
this.set('items_.' + index, data);
+ this.updateHideDates_(index, index);
this.$['downloads-list'].updateSizeForItem(index);
},
});
- Manager.size = function() {
- return document.querySelector('downloads-manager').size_();
+ Manager.clearAll = function() {
+ Manager.get().clearAll_();
};
- Manager.updateAll = function(list) {
- document.querySelector('downloads-manager').updateAll_(list);
+ /** @return {!downloads.Manager} */
+ Manager.get = function() {
+ return /** @type {!downloads.Manager} */(
+ queryRequiredElement('downloads-manager'));
};
- Manager.updateItem = function(item) {
- document.querySelector('downloads-manager').updateItem_(item);
+ Manager.insertItems = function(index, list) {
+ Manager.get().insertItems_(index, list);
};
Manager.onLoad = function() {
- document.querySelector('downloads-manager').onLoad_();
+ Manager.get().onLoad_();
+ };
+
+ Manager.removeItem = function(index) {
+ Manager.get().removeItem_(index);
+ };
+
+ Manager.updateItem = function(index, data) {
+ Manager.get().updateItem_(index, data);
};
return {Manager: Manager};

Powered by Google App Engine
This is Rietveld 408576698