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

Unified Diff: chrome/browser/resources/md_history/history_list.js

Issue 2684693004: MD History: Remove list-container and list-behavior (Closed)
Patch Set: Rename listeners Created 3 years, 10 months 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_history/history_list.js
diff --git a/chrome/browser/resources/md_history/history_list.js b/chrome/browser/resources/md_history/history_list.js
index 38a5bd0299b42fecf80b005df7df27f1a4fe2b0d..85dafe0e0be5770d28b62ff5e73c4748cf6430ca 100644
--- a/chrome/browser/resources/md_history/history_list.js
+++ b/chrome/browser/resources/md_history/history_list.js
@@ -5,8 +5,6 @@
Polymer({
is: 'history-list',
- behaviors: [HistoryListBehavior],
-
properties: {
// The search term for the current query. Set when the query returns.
searchedTerm: {
@@ -19,17 +17,47 @@ Polymer({
value: false,
},
+ /**
+ * Indexes into historyData_ of selected items.
+ * @type {!Set<number>}
+ */
+ selectedItems: {
+ type: Object,
+ value: /** @return {!Set<string>} */ function() {
+ return new Set();
+ },
+ },
+
+ canDeleteHistory_: {
+ type: Boolean,
+ value: loadTimeData.getBoolean('allowDeletingHistory'),
+ },
+
// An array of history entries in reverse chronological order.
historyData_: Array,
lastFocused_: Object,
- querying: Boolean,
+ lastSelectedIndex: Number,
+
+ /** @type {!QueryState} */
+ queryState: Object,
+
+ /**
+ * @private {?{
+ * index: number,
+ * item: !HistoryEntry,
+ * path: string,
+ * target: !HTMLElement
+ * }}
+ */
+ actionMenuModel_: Object,
},
listeners: {
- 'remove-bookmark-stars': 'removeBookmarkStars_',
+ 'history-checkbox-select': 'onItemSelected_',
'open-menu': 'onOpenMenu_',
+ 'remove-bookmark-stars': 'onRemoveBookmarkStars_',
},
/** @override */
@@ -42,21 +70,27 @@ Polymer({
this.$['scroll-threshold'].scrollTarget = this;
},
+ /////////////////////////////////////////////////////////////////////////////
+ // Public methods:
+
/**
- * Remove bookmark star for history items with matching URLs.
- * @param {{detail: !string}} e
- * @private
+ * @param {HistoryQuery} info An object containing information about the
+ * query.
+ * @param {!Array<!HistoryEntry>} results A list of results.
*/
- removeBookmarkStars_: function(e) {
- var url = e.detail;
+ historyResult: function(info, results) {
+ this.initializeResults_(info, results);
+ this.closeMenu_();
- if (this.historyData_ === undefined)
- return;
-
- for (var i = 0; i < this.historyData_.length; i++) {
- if (this.historyData_[i].url == url)
- this.set('historyData_.' + i + '.starred', false);
+ if (info.term && !this.queryState.incremental) {
+ Polymer.IronA11yAnnouncer.requestAvailability();
+ this.fire('iron-announce', {
+ text:
+ md_history.HistoryItem.searchResultsTitle(results.length, info.term)
+ });
}
+
+ this.addNewResults(results, this.queryState.incremental, info.finished);
},
/**
@@ -94,21 +128,183 @@ Polymer({
this.resultLoadingDisabled_ = finished;
},
+ historyDeleted: function() {
+ // Do not reload the list when there are items checked.
+ if (this.getSelectedItemCount() > 0)
+ return;
+
+ // Reload the list with current search state.
+ this.fire('query-history', false);
+ },
+
+ /**
+ * Deselect each item in |selectedItems|.
+ */
+ unselectAllItems: function() {
+ this.selectedItems.forEach(function(index) {
+ this.changeSelection_(index, false);
+ }.bind(this));
+
+ assert(this.selectedItems.size == 0);
+ },
+
+ /** @return {number} */
+ getSelectedItemCount: function() {
+ return this.selectedItems.size;
+ },
+
+ /**
+ * Delete all the currently selected history items. Will prompt the user with
+ * a dialog to confirm that the deletion should be performed.
+ */
+ deleteSelectedWithPrompt: function() {
+ if (!this.canDeleteHistory_)
+ return;
+
+ var browserService = md_history.BrowserService.getInstance();
+ browserService.recordAction('RemoveSelected');
+ if (this.queryState.searchTerm != '')
+ browserService.recordAction('SearchResultRemove');
+ this.$.dialog.get().showModal();
+
+ // TODO(dbeam): remove focus flicker caused by showModal() + focus().
+ this.$$('.action-button').focus();
+ },
+
+ /////////////////////////////////////////////////////////////////////////////
+ // Private methods:
+
+ /**
+ * Set the selection status for an item at a particular index.
+ * @param {number} index
+ * @param {boolean} selected
+ * @private
+ */
+ changeSelection_: function(index, selected) {
+ this.set('historyData_.' + index + '.selected', selected);
+ if (selected)
+ this.selectedItems.add(index);
+ else
+ this.selectedItems.delete(index);
+ },
+
+ /**
+ * Performs a request to the backend to delete all selected items. If
+ * successful, removes them from the view. Does not prompt the user before
+ * deleting -- see deleteSelectedWithPrompt for a version of this method which
+ * does prompt.
+ * @private
+ */
+ deleteSelected_: function() {
+ var toBeRemoved =
+ Array.from(this.selectedItems.values()).map(function(index) {
+ return this.get('historyData_.' + index);
+ }.bind(this));
+
+ md_history.BrowserService.getInstance()
+ .deleteItems(toBeRemoved)
+ .then(function(items) {
+ this.removeItemsByIndex_(Array.from(this.selectedItems));
+ this.fire('unselect-all');
+ }.bind(this));
+ },
+
+ /**
+ * Remove all |indices| from the history list. Uses notifySplices to send a
+ * single large notification to Polymer, rather than many small notifications,
+ * which greatly improves performance.
+ * @param {!Array<number>} indices
+ * @private
+ */
+ removeItemsByIndex_: function(indices) {
+ var splices = [];
+ indices.sort(function(a, b) {
+ // Sort in reverse numerical order.
+ return b - a;
+ });
+ indices.forEach(function(index) {
+ var item = this.historyData_.splice(index, 1);
+ splices.push({
+ index: index,
+ removed: [item],
+ addedCount: 0,
+ object: this.historyData_,
+ type: 'splice'
+ });
+ }.bind(this));
+ this.notifySplices('historyData_', splices);
+ },
+
+ /**
+ * Closes the overflow menu.
+ * @private
+ */
+ closeMenu_: function() {
+ var menu = this.$.sharedMenu.getIfExists();
+ if (menu && menu.open) {
+ this.actionMenuModel_ = null;
+ menu.close();
+ }
+ },
+
+ /////////////////////////////////////////////////////////////////////////////
+ // Event listeners:
+
+ /** @private */
+ onDialogConfirmTap_: function() {
+ md_history.BrowserService.getInstance().recordAction(
+ 'ConfirmRemoveSelected');
+
+ this.deleteSelected_();
+ var dialog = assert(this.$.dialog.getIfExists());
+ dialog.close();
+ },
+
+ /** @private */
+ onDialogCancelTap_: function() {
+ md_history.BrowserService.getInstance().recordAction(
+ 'CancelRemoveSelected');
+
+ var dialog = assert(this.$.dialog.getIfExists());
+ dialog.close();
+ },
+
+ /**
+ * Remove bookmark star for history items with matching URLs.
+ * @param {{detail: !string}} e
+ * @private
+ */
+ onRemoveBookmarkStars_: function(e) {
+ var url = e.detail;
+
+ if (this.historyData_ === undefined)
+ return;
+
+ for (var i = 0; i < this.historyData_.length; i++) {
+ if (this.historyData_[i].url == url)
+ this.set('historyData_.' + i + '.starred', false);
+ }
+ },
+
/**
* Called when the page is scrolled to near the bottom of the list.
* @private
*/
- loadMoreData_: function() {
- if (this.resultLoadingDisabled_ || this.querying)
+ onScrollToBottom_: function() {
+ if (this.resultLoadingDisabled_ || this.queryState.querying)
return;
this.fire('query-history', true);
},
/**
- * Ensure that the item is visible in the scroll pane when its menu is
- * opened (it is possible to open off-screen items using keyboard shortcuts).
- * @param {Event} e
+ * Open the overflow menu and ensure that the item is visible in the scroll
+ * pane when its menu is opened (it is possible to open off-screen items using
+ * keyboard shortcuts).
+ * @param {{detail: {
+ * index: number, item: !HistoryEntry,
+ * path: string, target: !HTMLElement
+ * }}} e
* @private
*/
onOpenMenu_: function(e) {
@@ -116,9 +312,89 @@ Polymer({
var list = /** @type {IronListElement} */ (this.$['infinite-list']);
if (index < list.firstVisibleIndex || index > list.lastVisibleIndex)
list.scrollToIndex(index);
+
+ var target = e.detail.target;
+ this.actionMenuModel_ = e.detail;
+ var menu = /** @type {CrSharedMenuElement} */ this.$.sharedMenu.get();
+ menu.showAt(target);
+ },
+
+ /** @private */
+ onMoreFromSiteTap_: function() {
+ md_history.BrowserService.getInstance().recordAction(
+ 'EntryMenuShowMoreFromSite');
+
+ var menu = assert(this.$.sharedMenu.getIfExists());
+ this.fire('change-query', {search: this.actionMenuModel_.item.domain});
+ this.actionMenuModel_ = null;
+ this.closeMenu_();
+ },
+
+ /** @private */
+ onRemoveFromHistoryTap_: function() {
+ var browserService = md_history.BrowserService.getInstance();
+ browserService.recordAction('EntryMenuRemoveFromHistory');
+ var menu = assert(this.$.sharedMenu.getIfExists());
+ var itemData = this.actionMenuModel_;
+ browserService.deleteItems([itemData.item]).then(function(items) {
+ // This unselect-all resets the toolbar when deleting a selected item
+ // and clears selection state which can be invalid if items move
+ // around during deletion.
+ // TODO(tsergeant): Make this automatic based on observing list
+ // modifications.
+ this.fire('unselect-all');
+ this.removeItemsByIndex_([itemData.index]);
+
+ var index = itemData.index;
+ if (index == undefined)
+ return;
+
+ var browserService = md_history.BrowserService.getInstance();
+ browserService.recordHistogram(
+ 'HistoryPage.RemoveEntryPosition',
+ Math.min(index, UMA_MAX_BUCKET_VALUE), UMA_MAX_BUCKET_VALUE);
+ if (index <= UMA_MAX_SUBSET_BUCKET_VALUE) {
+ browserService.recordHistogram(
+ 'HistoryPage.RemoveEntryPositionSubset', index,
+ UMA_MAX_SUBSET_BUCKET_VALUE);
+ }
+ }.bind(this));
+ this.closeMenu_();
},
/**
+ * @param {Event} e
+ * @private
+ */
+ onItemSelected_: function(e) {
+ var index = e.detail.index;
+ var indices = [];
+
+ // Handle shift selection. Change the selection state of all items between
+ // |path| and |lastSelected| to the selection state of |item|.
+ if (e.detail.shiftKey && this.lastSelectedIndex != undefined) {
+ for (var i = Math.min(index, this.lastSelectedIndex);
+ i <= Math.max(index, this.lastSelectedIndex); i++) {
+ indices.push(i);
+ }
+ }
+
+ if (indices.length == 0)
+ indices.push(index);
+
+ var selected = !this.selectedItems.has(index);
+
+ indices.forEach(function(index) {
+ this.changeSelection_(index, selected);
+ }.bind(this));
+
+ this.lastSelectedIndex = index;
+ },
+
+ /////////////////////////////////////////////////////////////////////////////
+ // Template helpers:
+
+ /**
* Check whether the time difference between the given history item and the
* next one is large enough for a spacer to be required.
* @param {HistoryEntry} item
@@ -128,8 +404,17 @@ Polymer({
* @private
*/
needsTimeGap_: function(item, index, length) {
- return md_history.HistoryItem.needsTimeGap(
- this.historyData_, index, this.searchedTerm);
+ if (index >= length - 1 || length == 0)
+ return false;
+
+ var currentItem = this.historyData_[index];
+ var nextItem = this.historyData_[index + 1];
+
+ if (this.searchedTerm)
+ return currentItem.dateShort != nextItem.dateShort;
+
+ return currentItem.time - nextItem.time > BROWSING_GAP_TIME &&
+ currentItem.dateRelativeDay == nextItem.dateRelativeDay;
},
/**
@@ -165,11 +450,48 @@ Polymer({
},
/**
- * @param {number} index
+ * @param {number} historyDataLength
+ * @return {boolean}
+ * @private
+ */
+ hasResults_: function(historyDataLength) {
+ return historyDataLength > 0;
+ },
+
+ /**
+ * @param {string} searchedTerm
+ * @param {boolean} isLoading
* @return {string}
* @private
*/
- pathForItem_: function(index) {
- return 'historyData_.' + index;
+ noResultsMessage_: function(searchedTerm, isLoading) {
+ if (isLoading)
+ return '';
+
+ var messageId = searchedTerm !== '' ? 'noSearchResults' : 'noResults';
+ return loadTimeData.getString(messageId);
+ },
+
+ /**
+ * @param {HistoryQuery} info
+ * @param {!Array<HistoryEntry>} results
+ * @private
+ */
+ initializeResults_: function(info, results) {
+ if (results.length == 0)
+ return;
+
+ var currentDate = results[0].dateRelativeDay;
+
+ for (var i = 0; i < results.length; i++) {
+ // Sets the default values for these fields to prevent undefined types.
+ results[i].selected = false;
+ results[i].readableTimestamp =
+ info.term == '' ? results[i].dateTimeOfDay : results[i].dateShort;
+
+ if (results[i].dateRelativeDay != currentDate) {
+ currentDate = results[i].dateRelativeDay;
+ }
+ }
},
});
« no previous file with comments | « chrome/browser/resources/md_history/history_list.html ('k') | chrome/browser/resources/md_history/history_list_behavior.html » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698