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

Side by Side Diff: chrome/browser/resources/md_history/history_list.js

Issue 1641543002: MD History: Refactored design for displaying history information (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@second_patch
Patch Set: Rebased tests + added some more Created 4 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 unified diff | Download patch
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 Polymer({ 5 Polymer({
6 is: 'history-card-manager', 6 is: 'history-list',
7 7
8 properties: { 8 properties: {
9 // An array of objects sorted in reverse chronological order. 9 // An array of history entries in reverse chronological order.
10 // Each object has a date and the history items belonging to that date. 10 historyData: {
11 historyDataByDay_: {
12 type: Array, 11 type: Array,
13 value: function() { return []; } 12 value: function() { return []; }
14 }, 13 },
15 14
16 // The time of access of the last element of historyDataByDay_. 15 // The time in seconds of the last history item in historyData.
calamity 2016/02/12 02:50:22 // The time of access of the last history item in
yingran 2016/02/12 03:30:32 Done.
17 lastVisitedTime: { 16 lastVisitedTime: {
18 type: Number, 17 type: Number,
19 value: 0 18 value: 0
20 }, 19 },
21 20
22 menuOpen: { 21 menuOpen: {
23 type: Boolean, 22 type: Boolean,
24 value: false, 23 value: false,
25 reflectToAttribute: true 24 reflectToAttribute: true
26 }, 25 },
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
63 this.menuIdentifier = e.detail.accessTime; 62 this.menuIdentifier = e.detail.accessTime;
64 63
65 cr.ui.positionPopupAtPoint(e.detail.x + this.X_OFFSET_, e.detail.y, menu, 64 cr.ui.positionPopupAtPoint(e.detail.x + this.X_OFFSET_, e.detail.y, menu,
66 cr.ui.AnchorType.BEFORE); 65 cr.ui.AnchorType.BEFORE);
67 66
68 menu.focus(); 67 menu.focus();
69 } 68 }
70 }, 69 },
71 70
72 /** 71 /**
73 * Split the newly updated history results into history items sorted via day 72 * Adds the newly updated history results into historyData. Adds new fields
74 * accessed. 73 * for each result.
75 * @param {!Array<!HistoryEntry>} results The new history results. 74 * @param {!Array<!HistoryEntry>} historyResults The new history results.
76 */ 75 */
77 addNewResults: function(results) { 76 addNewResults: function(historyResults) {
78 if (results.length == 0) 77 if (historyResults.length == 0)
79 return; 78 return;
80 79
81 var dateSortedData = []; 80 // Creates a copy of historyResults to prevent accidentally modifying this
82 var historyItems = []; 81 // field.
82 var results = historyResults.slice();
83
83 var currentDate = results[0].dateRelativeDay; 84 var currentDate = results[0].dateRelativeDay;
84 85
85 for (var i = 0; i < results.length; i++) { 86 // Resets the last history item for the currentDate if new history results
86 if (!currentDate) 87 // for currentDate is loaded.
87 continue; 88 var lastHistoryItem = this.historyData[this.historyData.length - 1];
88 89 if (lastHistoryItem && lastHistoryItem.isLastItem &&
89 results[i].selected = false; 90 lastHistoryItem.dateRelativeDay == currentDate) {
90 if (results[i].dateRelativeDay != currentDate) { 91 this.set('historyData.' + parseInt(this.historyData.length - 1) +
calamity 2016/02/12 02:50:22 Remove parseInt
yingran 2016/02/12 03:30:32 Done.
91 this.appendHistoryData_(currentDate, historyItems); 92 '.isLastItem', false);
92 currentDate = results[i].dateRelativeDay;
93 historyItems = [];
94 }
95 historyItems.push(results[i]);
96 } 93 }
97 94
98 if (currentDate) 95 for (var i = 0; i < results.length; i++) {
99 this.appendHistoryData_(currentDate, historyItems); 96 // Sets the default values for these fields to prevent undefined types.
97 results[i].selected = false;
98 results[i].isLastItem = false;
99 results[i].isFirstItem = false;
100 100
101 this.lastVisitedTime = historyItems[historyItems.length - 1].time; 101 if (results[i].dateRelativeDay != currentDate) {
102 results[i - 1].isLastItem = true;
103 results[i].isFirstItem = true;
104 currentDate = results[i].dateRelativeDay;
105 }
106 results[i].needsTimeGap = this.needsTimeGap_(results, i);
calamity 2016/02/12 02:50:22 Move this above the if block. It's weird for it to
yingran 2016/02/12 03:30:32 Done.
107 }
108 results[i - 1].isLastItem = true;
109
110 // If it's the first time we get data, the first item will always be the
111 // first card.
112 if (this.historyData.length == 0)
113 results[0].isFirstItem = true;
114
115 // Adds results to the beginning of the historyData array.
116 results.unshift('historyData');
117 this.push.apply(this, results);
118
119 this.lastVisitedTime = this.historyData[this.historyData.length - 1].time;
102 }, 120 },
103 121
104 /** 122 /**
105 * Cycle through each entry in historyDataByDay_ and set all items to be 123 * Cycle through each entry in historyData and set all items to be
106 * unselected. 124 * unselected.
107 * @param {number} overallItemCount The number of items selected. 125 * @param {number} overallItemCount The number of checkboxes selected.
108 */ 126 */
109 unselectAllItems: function(overallItemCount) { 127 unselectAllItems: function(overallItemCount) {
110 var historyCardData = this.historyDataByDay_; 128 for (var i = 0; i < this.historyData.length; i++) {
111 129 if (this.historyData[i].selected) {
112 for (var i = 0; i < historyCardData.length; i++) { 130 this.set('historyData.' + i + '.selected', false);
113 var items = historyCardData[i].historyItems; 131 overallItemCount--;
114 for (var j = 0; j < items.length; j++) { 132 if (overallItemCount == 0)
115 if (items[j].selected) { 133 break;
116 this.set('historyDataByDay_.' + i + '.historyItems.' + j +
117 '.selected', false);
118 overallItemCount--;
119 if (overallItemCount == 0)
120 return;
121 }
122 } 134 }
123 } 135 }
124 }, 136 },
125 137
126 /** 138 /**
127 * Remove all selected items from the overall array so that they are also 139 * Remove all selected items from the overall array so that they are also
128 * removed from view. Make sure that the card length and positioning is 140 * removed from view. Make sure that the card length and positioning is
129 * updated accordingly. 141 * updated accordingly.
130 * @param {number} overallItemCount The number of items selected. 142 * @param {number} overallItemCount The number of items selected.
131 */ 143 */
132 removeDeletedHistory: function(overallItemCount) { 144 removeDeletedHistory: function(overallItemCount) {
133 for (var i = 0; i < this.historyDataByDay_.length; i++) { 145 for (var i = this.historyData.length - 1; i >= 0; i--) {
134 var items = this.historyDataByDay_[i].historyItems; 146 if (!this.historyData[i].selected)
135 var itemDeletedFromCard = false; 147 continue;
136 148
137 for (var j = items.length - 1; j >= 0; j--) { 149 // TODO: Change to using computed properties to recompute the first and
138 if (!items[j].selected) 150 // last cards.
139 continue;
140 151
141 this.splice('historyDataByDay_.' + i + '.historyItems', j, 1); 152 // Resets the first history item.
142 itemDeletedFromCard = true; 153 if (this.historyData[i].isFirstItem &&
143 overallItemCount--; 154 parseInt(i + 1) < this.historyData.length &&
144 if (overallItemCount == 0) { 155 this.historyData[i].dateRelativeDay ==
145 this.removeEmptyCards_(); 156 this.historyData[i + 1].dateRelativeDay) {
146 // If the last card has been removed don't try to update its size. 157 this.set('historyData.' + parseInt(i + 1) + '.isFirstItem', true);
calamity 2016/02/12 02:50:23 I don't think these parseInts are necessary either
yingran 2016/02/12 03:30:32 Done.
147 if (i < this.historyDataByDay_.length)
148 this.$['infinite-list'].updateSizeForItem(i);
149 return;
150 }
151 } 158 }
152 if (itemDeletedFromCard) 159
153 this.$['infinite-list'].updateSizeForItem(i); 160 // Resets the last history item.
161 if (this.historyData[i].isLastItem && i > 0 &&
162 this.historyData[i].dateRelativeDay ==
163 this.historyData[i - 1].dateRelativeDay) {
164 this.set('historyData.' + parseInt(i - 1) + '.isLastItem', true);
165 }
166
167 // Makes sure that the time gap separators are preserved.
168 if (this.historyData[i].needsTimeGap && i > 0)
169 this.set('historyData.' + parseInt(i - 1) + '.needsTimeGap', true);
170
calamity 2016/02/12 02:50:23 Missed the deletion after case for time gaps here.
yingran 2016/02/12 03:30:32 Done.
171 // Removes the selected item from historyData.
172 this.splice('historyData', i, 1);
173
174 overallItemCount--;
175 if (overallItemCount == 0)
176 break;
154 } 177 }
155 }, 178 },
156 179
157 /**
158 * If a day has had all the history it contains removed, remove this day from
159 * the array.
160 * @private
161 */
162 removeEmptyCards_: function() {
163 var historyCards = this.historyDataByDay_;
164 for (var i = historyCards.length - 1; i >= 0; i--) {
165 if (historyCards[i].historyItems.length == 0) {
166 this.splice('historyDataByDay_', i, 1);
167 }
168 }
169 },
170
171 /**
172 * Adds the given items into historyDataByDay_. Adds items to the last
173 * existing day if the date matches, creates a new element otherwise.
174 * @param {string} date The date of the history items.
175 * @param {!Array<!HistoryEntry>} historyItems The list of history items for
176 * the current date.
177 * @private
178 */
179 appendHistoryData_: function(date, historyItems) {
180 var lastDay = this.historyDataByDay_.length - 1;
181 if (lastDay > 0 && date == this.historyDataByDay_[lastDay].date) {
182 this.set('historyDataByDay_.' + lastDay + '.historyItems',
183 this.historyDataByDay_[lastDay].historyItems.concat(historyItems));
184 } else {
185 this.push('historyDataByDay_', {
186 date: date,
187 historyItems: historyItems
188 });
189 }
190 },
191
192 /** 180 /**
193 * Based on which items are selected, collect an array of the info required 181 * Based on which items are selected, collect an array of the info required
194 * for chrome.send('removeHistory', ...). 182 * for chrome.send('removeHistory', ...).
195 * @param {number} count The number of items that are selected. 183 * @param {number} count The number of items that are selected.
196 * @return {Array<HistoryEntry>} toBeRemoved An array of objects which contain 184 * @return {Array<HistoryEntry>} toBeRemoved An array of objects which contain
197 * information on which history-items should be deleted. 185 * information on which history-items should be deleted.
198 */ 186 */
199 getSelectedItems: function(count) { 187 getSelectedItems: function(count) {
200 var toBeRemoved = []; 188 var toBeRemoved = [];
201 for (var i = 0; i < this.historyDataByDay_.length; i++) { 189 for (var i = 0; i < this.historyData.length; i++) {
202 var items = this.historyDataByDay_[i].historyItems; 190 if (this.historyData[i].selected) {
203 for (var j = 0; j < items.length; j++) { 191 toBeRemoved.push({
204 if (items[j].selected) { 192 url: this.historyData[i].url,
193 timestamps: this.historyData[i].allTimestamps
194 });
205 195
206 toBeRemoved.push({ 196 count--;
207 url: items[j].url, 197 if (count == 0)
208 timestamps: items[j].allTimestamps 198 return toBeRemoved;
209 });
210
211 count--;
212 if (count == 0)
213 return toBeRemoved;
214 }
215 } 199 }
216 } 200 }
calamity 2016/02/12 02:50:23 Put return toBeRemoved back here and change the ot
yingran 2016/02/12 03:30:32 Done.
217 return toBeRemoved;
218 }, 201 },
219 202
220 /** 203 /**
221 * Called when the card manager is scrolled. 204 * Called when the card manager is scrolled.
222 * @private 205 * @private
223 */ 206 */
224 scrollHandler_: function() { 207 scrollHandler_: function() {
225 // Close overflow menu on scroll. 208 // Close overflow menu on scroll.
226 this.closeMenu(); 209 this.closeMenu();
227 210
228 // Requests the next list of results when the scrollbar is near the bottom 211 // Requests the next list of results when the scrollbar is near the bottom
229 // of the window. 212 // of the window.
230 var scrollOffset = 10; 213 var scrollOffset = 10;
231 var scrollElem = this.$['infinite-list']; 214 var scrollElem = this.$['infinite-list'];
232 215
233 if (scrollElem.scrollHeight <= 216 if (scrollElem.scrollHeight <=
234 scrollElem.scrollTop + scrollElem.clientHeight + scrollOffset) { 217 scrollElem.scrollTop + scrollElem.clientHeight + scrollOffset) {
235 chrome.send('queryHistory', 218 chrome.send('queryHistory',
236 ['', 0, 0, this.lastVisitedTime, RESULTS_PER_PAGE]); 219 ['', 0, 0, this.lastVisitedTime, RESULTS_PER_PAGE]);
237 } 220 }
221 },
222
223 /**
224 * Check whether the time difference between the given history item and the
225 * next one is large enough for a spacer to be required.
226 * @param {Array<HistoryEntry>} results A list of history results.
227 * @param {number} index The index number of the first item being compared.
228 * @return {boolean} Whether or not time gap separator is required.
229 * @private
230 */
231 needsTimeGap_: function(results, index) {
232 var currentItem = results[index];
233 var nextItem = results[index + 1];
234
235 if (index + 1 >= results.length)
236 return false;
237
238 return currentItem.time - nextItem.time > BROWSING_GAP_TIME &&
239 currentItem.dateRelativeDay == nextItem.dateRelativeDay;
238 } 240 }
239 }); 241 });
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698