| 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};
|
|
|