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

Side by Side Diff: chrome/browser/resources/history/history.js

Issue 10391052: History: Rename Page to Visit, remove some unused code, other cleanups. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years, 7 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 | Annotate | Revision Log
« no previous file with comments | « chrome/browser/resources/history/history.html ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 <include src="../uber/uber_utils.js"> 5 <include src="../uber/uber_utils.js">
6 6
7 /////////////////////////////////////////////////////////////////////////////// 7 ///////////////////////////////////////////////////////////////////////////////
8 // Globals: 8 // Globals:
9 /** @const */ var RESULTS_PER_PAGE = 150; 9 /** @const */ var RESULTS_PER_PAGE = 150;
10 /** @const */ var MAX_SEARCH_DEPTH_MONTHS = 18; 10 /** @const */ var MAX_SEARCH_DEPTH_MONTHS = 18;
(...skipping 23 matching lines...) Expand all
34 return null; 34 return null;
35 } 35 }
36 36
37 // TODO(glen): Get rid of these global references, replace with a controller 37 // TODO(glen): Get rid of these global references, replace with a controller
38 // or just make the classes own more of the page. 38 // or just make the classes own more of the page.
39 var historyModel; 39 var historyModel;
40 var historyView; 40 var historyView;
41 var pageState; 41 var pageState;
42 var deleteQueue = []; 42 var deleteQueue = [];
43 var selectionAnchor = -1; 43 var selectionAnchor = -1;
44 var activePage = null; 44 var activeVisit = null;
45 45
46 /** @const */ var Command = cr.ui.Command; 46 /** @const */ var Command = cr.ui.Command;
47 /** @const */ var Menu = cr.ui.Menu; 47 /** @const */ var Menu = cr.ui.Menu;
48 /** @const */ var MenuButton = cr.ui.MenuButton; 48 /** @const */ var MenuButton = cr.ui.MenuButton;
49 49
50 MenuButton.createDropDownArrows(); 50 MenuButton.createDropDownArrows();
51 51
52 /////////////////////////////////////////////////////////////////////////////// 52 ///////////////////////////////////////////////////////////////////////////////
53 // Page: 53 // Visit:
54 54
55 /** 55 /**
56 * Class to hold all the information about an entry in our model. 56 * Class to hold all the information about an entry in our model.
57 * @param {Object} result An object containing the page's data. 57 * @param {Object} result An object containing the visit's data.
58 * @param {boolean} continued Whether this page is on the same day as the 58 * @param {boolean} continued Whether this visit is on the same day as the
59 * page before it 59 * visit before it.
60 * @param {HistoryModel} model The model object this entry belongs to. 60 * @param {HistoryModel} model The model object this entry belongs to.
61 * @param {Number} id The identifier for the entry. 61 * @param {Number} id The identifier for the entry.
62 * @constructor 62 * @constructor
63 */ 63 */
64 function Page(result, continued, model, id) { 64 function Visit(result, continued, model, id) {
65 this.model_ = model; 65 this.model_ = model;
66 this.title_ = result.title; 66 this.title_ = result.title;
67 this.url_ = result.url; 67 this.url_ = result.url;
68 this.domain_ = this.getDomainFromURL_(this.url_);
69 this.starred_ = result.starred; 68 this.starred_ = result.starred;
70 this.snippet_ = result.snippet || ''; 69 this.snippet_ = result.snippet || '';
71 this.id_ = id; 70 this.id_ = id;
72 71
73 this.changed = false; 72 this.changed = false;
74 73
75 this.isRendered = false; 74 this.isRendered = false;
76 75
77 // All the date information is public so that owners can compare properties of 76 // All the date information is public so that owners can compare properties of
78 // two items easily. 77 // two items easily.
79 78
80 // We get the time in seconds, but we want it in milliseconds. 79 // We get the time in seconds, but we want it in milliseconds.
81 this.time = new Date(result.time * 1000); 80 this.time = new Date(result.time * 1000);
82 81
83 // See comment in BrowsingHistoryHandler::QueryComplete - we won't always 82 // See comment in BrowsingHistoryHandler::QueryComplete - we won't always
84 // get all of these. 83 // get all of these.
85 this.dateRelativeDay = result.dateRelativeDay || ''; 84 this.dateRelativeDay = result.dateRelativeDay || '';
86 this.dateTimeOfDay = result.dateTimeOfDay || ''; 85 this.dateTimeOfDay = result.dateTimeOfDay || '';
87 this.dateShort = result.dateShort || ''; 86 this.dateShort = result.dateShort || '';
88 87
89 // Whether this is the continuation of a previous day. 88 // Whether this is the continuation of a previous day.
90 this.continued = continued; 89 this.continued = continued;
91 } 90 }
92 91
93 // Page, Public: -------------------------------------------------------------- 92 // Visit, public: -------------------------------------------------------------
94 93
95 /** 94 /**
96 * Returns a dom structure for a browse page result or a search page result. 95 * Returns a dom structure for a browse page result or a search page result.
97 * @param {boolean} searchResultFlag Indicates whether the result is a search 96 * @param {boolean} searchResultFlag Indicates whether the result is a search
98 * result or not. 97 * result or not.
99 * @return {Node} A DOM node to represent the history entry or search result. 98 * @return {Node} A DOM node to represent the history entry or search result.
100 */ 99 */
101 Page.prototype.getResultDOM = function(searchResultFlag) { 100 Visit.prototype.getResultDOM = function(searchResultFlag) {
102 var node = createElementWithClassName('li', 'entry'); 101 var node = createElementWithClassName('li', 'entry');
103 var time = createElementWithClassName('div', 'time'); 102 var time = createElementWithClassName('div', 'time');
104 var entryBox = createElementWithClassName('label', 'entry-box'); 103 var entryBox = createElementWithClassName('label', 'entry-box');
105 var domain = createElementWithClassName('div', 'domain'); 104 var domain = createElementWithClassName('div', 'domain');
106 105
107 var dropDown = createElementWithClassName('button', 'drop-down'); 106 var dropDown = createElementWithClassName('button', 'drop-down');
108 dropDown.value = 'Open action menu'; 107 dropDown.value = 'Open action menu';
109 dropDown.title = loadTimeData.getString('actionMenuDescription'); 108 dropDown.title = loadTimeData.getString('actionMenuDescription');
110 dropDown.setAttribute('menu', '#action-menu'); 109 dropDown.setAttribute('menu', '#action-menu');
111 cr.ui.decorate(dropDown, MenuButton); 110 cr.ui.decorate(dropDown, MenuButton);
112 111
113 // Checkbox is always created, but only visible on hover & when checked. 112 // Checkbox is always created, but only visible on hover & when checked.
114 var checkbox = document.createElement('input'); 113 var checkbox = document.createElement('input');
115 checkbox.type = 'checkbox'; 114 checkbox.type = 'checkbox';
116 checkbox.id = 'checkbox-' + this.id_; 115 checkbox.id = 'checkbox-' + this.id_;
117 checkbox.time = this.time.getTime(); 116 checkbox.time = this.time.getTime();
118 checkbox.addEventListener('click', checkboxClicked); 117 checkbox.addEventListener('click', checkboxClicked);
119 time.appendChild(checkbox); 118 time.appendChild(checkbox);
120 119
121 // Keep track of the drop down that triggered the menu, so we know 120 // Keep track of the drop down that triggered the menu, so we know
122 // which element to apply the command to. 121 // which element to apply the command to.
123 // TODO(dubroy): Ideally we'd use 'activate', but MenuButton swallows it. 122 // TODO(dubroy): Ideally we'd use 'activate', but MenuButton swallows it.
124 var self = this; 123 var self = this;
125 var setActivePage = function(e) { 124 var setActiveVisit = function(e) {
126 activePage = self; 125 activeVisit = self;
127 }; 126 };
128 dropDown.addEventListener('mousedown', setActivePage); 127 dropDown.addEventListener('mousedown', setActiveVisit);
129 dropDown.addEventListener('focus', setActivePage); 128 dropDown.addEventListener('focus', setActiveVisit);
130 129
131 domain.textContent = this.domain_; 130 domain.textContent = this.getDomainFromURL_(this.url_);
132 131
133 // Clicking anywhere in the entryBox will check/uncheck the checkbox. 132 // Clicking anywhere in the entryBox will check/uncheck the checkbox.
134 entryBox.setAttribute('for', checkbox.id); 133 entryBox.setAttribute('for', checkbox.id);
135 entryBox.addEventListener('mousedown', entryBoxMousedown); 134 entryBox.addEventListener('mousedown', entryBoxMousedown);
136 135
137 // Prevent clicks on the drop down from affecting the checkbox. 136 // Prevent clicks on the drop down from affecting the checkbox.
138 dropDown.addEventListener('click', function(e) { e.preventDefault(); }); 137 dropDown.addEventListener('click', function(e) { e.preventDefault(); });
139 138
140 // We use a wrapper div so that the entry contents will be shinkwrapped. 139 // We use a wrapper div so that the entry contents will be shinkwrapped.
141 entryBox.appendChild(time); 140 entryBox.appendChild(time);
(...skipping 15 matching lines...) Expand all
157 time.appendChild(document.createTextNode(this.dateShort)); 156 time.appendChild(document.createTextNode(this.dateShort));
158 var snippet = createElementWithClassName('div', 'snippet'); 157 var snippet = createElementWithClassName('div', 'snippet');
159 this.addHighlightedText_(snippet, 158 this.addHighlightedText_(snippet,
160 this.snippet_, 159 this.snippet_,
161 this.model_.getSearchText()); 160 this.model_.getSearchText());
162 node.appendChild(snippet); 161 node.appendChild(snippet);
163 } else { 162 } else {
164 time.appendChild(document.createTextNode(this.dateTimeOfDay)); 163 time.appendChild(document.createTextNode(this.dateTimeOfDay));
165 } 164 }
166 165
167 if (typeof this.domNode_ != 'undefined') {
168 console.error('Already generated node for page.');
Patrick Dubroy 2012/05/10 16:52:01 This is not actually an error -- it happens whenev
169 }
170 this.domNode_ = node; 166 this.domNode_ = node;
171 167
172 return node; 168 return node;
173 }; 169 };
174 170
175 // Page, private: ------------------------------------------------------------- 171 // Visit, private: ------------------------------------------------------------
176 172
177 /** 173 /**
178 * Extracts and returns the domain (and subdomains) from a URL. 174 * Extracts and returns the domain (and subdomains) from a URL.
179 * @param {string} url The url. 175 * @param {string} url The url.
180 * @return {string} The domain. An empty string is returned if no domain can 176 * @return {string} The domain. An empty string is returned if no domain can
181 * be found. 177 * be found.
182 * @private 178 * @private
183 */ 179 */
184 Page.prototype.getDomainFromURL_ = function(url) { 180 Visit.prototype.getDomainFromURL_ = function(url) {
185 var domain = url.replace(/^.+:\/\//, '').match(/[^/]+/); 181 var domain = url.replace(/^.+:\/\//, '').match(/[^/]+/);
186 return domain ? domain[0] : ''; 182 return domain ? domain[0] : '';
187 }; 183 };
188 184
189 /** 185 /**
190 * Add child text nodes to a node such that occurrences of the specified text is 186 * Add child text nodes to a node such that occurrences of the specified text is
191 * highlighted. 187 * highlighted.
192 * @param {Node} node The node under which new text nodes will be made as 188 * @param {Node} node The node under which new text nodes will be made as
193 * children. 189 * children.
194 * @param {string} content Text to be added beneath |node| as one or more 190 * @param {string} content Text to be added beneath |node| as one or more
195 * text nodes. 191 * text nodes.
196 * @param {string} highlightText Occurences of this text inside |content| will 192 * @param {string} highlightText Occurences of this text inside |content| will
197 * be highlighted. 193 * be highlighted.
198 * @private 194 * @private
199 */ 195 */
200 Page.prototype.addHighlightedText_ = function(node, content, highlightText) { 196 Visit.prototype.addHighlightedText_ = function(node, content, highlightText) {
201 var i = 0; 197 var i = 0;
202 if (highlightText) { 198 if (highlightText) {
203 var re = new RegExp(Page.pregQuote_(highlightText), 'gim'); 199 var re = new RegExp(Visit.pregQuote_(highlightText), 'gim');
204 var match; 200 var match;
205 while (match = re.exec(content)) { 201 while (match = re.exec(content)) {
206 if (match.index > i) 202 if (match.index > i)
207 node.appendChild(document.createTextNode(content.slice(i, 203 node.appendChild(document.createTextNode(content.slice(i,
208 match.index))); 204 match.index)));
209 i = re.lastIndex; 205 i = re.lastIndex;
210 // Mark the highlighted text in bold. 206 // Mark the highlighted text in bold.
211 var b = document.createElement('b'); 207 var b = document.createElement('b');
212 b.textContent = content.substring(match.index, i); 208 b.textContent = content.substring(match.index, i);
213 node.appendChild(b); 209 node.appendChild(b);
214 } 210 }
215 } 211 }
216 if (i < content.length) 212 if (i < content.length)
217 node.appendChild(document.createTextNode(content.slice(i))); 213 node.appendChild(document.createTextNode(content.slice(i)));
218 }; 214 };
219 215
220 /** 216 /**
221 * @return {DOMObject} DOM representation for the title block. 217 * @return {DOMObject} DOM representation for the title block.
222 * @private 218 * @private
223 */ 219 */
224 Page.prototype.getTitleDOM_ = function() { 220 Visit.prototype.getTitleDOM_ = function() {
225 var node = createElementWithClassName('div', 'title'); 221 var node = createElementWithClassName('div', 'title');
226 node.style.backgroundImage = 222 node.style.backgroundImage =
227 'url(chrome://favicon/' + encodeURIForCSS(this.url_) + ')'; 223 'url(chrome://favicon/' + encodeURIForCSS(this.url_) + ')';
228 224
229 var link = document.createElement('a'); 225 var link = document.createElement('a');
230 link.href = this.url_; 226 link.href = this.url_;
231 link.id = 'id-' + this.id_; 227 link.id = 'id-' + this.id_;
232 link.target = '_top'; 228 link.target = '_top';
233 229
234 // Add a tooltip, since it might be ellipsized. 230 // Add a tooltip, since it might be ellipsized.
235 // TODO(dubroy): Find a way to show the tooltip only when necessary. 231 // TODO(dubroy): Find a way to show the tooltip only when necessary.
236 link.title = this.title_; 232 link.title = this.title_;
237 233
238 this.addHighlightedText_(link, this.title_, this.model_.getSearchText()); 234 this.addHighlightedText_(link, this.title_, this.model_.getSearchText());
239 node.appendChild(link); 235 node.appendChild(link);
240 236
241 if (this.starred_) { 237 if (this.starred_) {
242 var star = createElementWithClassName('div', 'starred'); 238 var star = createElementWithClassName('div', 'starred');
243 node.appendChild(star); 239 node.appendChild(star);
244 star.addEventListener('click', this.starClicked_.bind(this)); 240 star.addEventListener('click', this.starClicked_.bind(this));
245 } 241 }
246 242
247 return node; 243 return node;
248 }; 244 };
249 245
250 /** 246 /**
251 * Launch a search for more history entries from the same domain. 247 * Launch a search for more history entries from the same domain.
252 * @private 248 * @private
253 */ 249 */
254 Page.prototype.showMoreFromSite_ = function() { 250 Visit.prototype.showMoreFromSite_ = function() {
255 setSearch(this.domain_); 251 setSearch(this.getDomainFromURL_(this.url_));
256 }; 252 };
257 253
258 /** 254 /**
259 * Remove a single entry from the history. 255 * Remove a single entry from the history.
260 * @private 256 * @private
261 */ 257 */
262 Page.prototype.removeFromHistory_ = function() { 258 Visit.prototype.removeFromHistory_ = function() {
263 var self = this; 259 var self = this;
264 var onSuccessCallback = function() { 260 var onSuccessCallback = function() {
265 removeEntryFromView(self.domNode_); 261 removeEntryFromView(self.domNode_);
266 }; 262 };
267 queueURLsForDeletion(this.time, [this.url_], onSuccessCallback); 263 queueURLsForDeletion(this.time, [this.url_], onSuccessCallback);
268 deleteNextInQueue(); 264 deleteNextInQueue();
269 }; 265 };
270 266
271 /** 267 /**
272 * Click event handler for the star icon that appears beside bookmarked URLs. 268 * Click event handler for the star icon that appears beside bookmarked URLs.
273 * When clicked, the bookmark is removed for that URL. 269 * When clicked, the bookmark is removed for that URL.
274 * @param {Event} event The click event. 270 * @param {Event} event The click event.
275 * @private 271 * @private
276 */ 272 */
277 Page.prototype.starClicked_ = function(event) { 273 Visit.prototype.starClicked_ = function(event) {
278 chrome.send('removeBookmark', [this.url_]); 274 chrome.send('removeBookmark', [this.url_]);
279 event.currentTarget.hidden = true; 275 event.currentTarget.hidden = true;
280 event.preventDefault(); 276 event.preventDefault();
281 }; 277 };
282 278
283 // Page, private, static: ----------------------------------------------------- 279 // Visit, private, static: ----------------------------------------------------
284 280
285 /** 281 /**
286 * Quote a string so it can be used in a regular expression. 282 * Quote a string so it can be used in a regular expression.
287 * @param {string} str The source string 283 * @param {string} str The source string
288 * @return {string} The escaped string 284 * @return {string} The escaped string
289 * @private 285 * @private
290 */ 286 */
291 Page.pregQuote_ = function(str) { 287 Visit.pregQuote_ = function(str) {
292 return str.replace(/([\\\.\+\*\?\[\^\]\$\(\)\{\}\=\!\<\>\|\:])/g, '\\$1'); 288 return str.replace(/([\\\.\+\*\?\[\^\]\$\(\)\{\}\=\!\<\>\|\:])/g, '\\$1');
293 }; 289 };
294 290
295 /////////////////////////////////////////////////////////////////////////////// 291 ///////////////////////////////////////////////////////////////////////////////
296 // HistoryModel: 292 // HistoryModel:
297 293
298 /** 294 /**
299 * Global container for history data. Future optimizations might include 295 * Global container for history data. Future optimizations might include
300 * allowing the creation of a HistoryModel for each search string, allowing 296 * allowing the creation of a HistoryModel for each search string, allowing
301 * quick flips back and forth between results. 297 * quick flips back and forth between results.
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
373 this.inFlight_ = false; 369 this.inFlight_ = false;
374 if (info.term != this.searchText_) { 370 if (info.term != this.searchText_) {
375 // If our results aren't for our current search term, they're rubbish. 371 // If our results aren't for our current search term, they're rubbish.
376 return; 372 return;
377 } 373 }
378 374
379 // Currently we assume we're getting things in date order. This needs to 375 // Currently we assume we're getting things in date order. This needs to
380 // be updated if that ever changes. 376 // be updated if that ever changes.
381 if (results) { 377 if (results) {
382 var lastURL, lastDay; 378 var lastURL, lastDay;
383 var oldLength = this.pages_.length; 379 var oldLength = this.visits_.length;
384 if (oldLength) { 380 if (oldLength) {
385 var oldPage = this.pages_[oldLength - 1]; 381 var oldVisit = this.visits_[oldLength - 1];
386 lastURL = oldPage.url; 382 lastURL = oldVisit.url;
387 lastDay = oldPage.dateRelativeDay; 383 lastDay = oldVisit.dateRelativeDay;
388 } 384 }
389 385
390 for (var i = 0, thisResult; thisResult = results[i]; i++) { 386 for (var i = 0, thisResult; thisResult = results[i]; i++) {
391 var thisURL = thisResult.url; 387 var thisURL = thisResult.url;
392 var thisDay = thisResult.dateRelativeDay; 388 var thisDay = thisResult.dateRelativeDay;
393 389
394 // Remove adjacent duplicates. 390 // Remove adjacent duplicates.
395 if (!lastURL || lastURL != thisURL) { 391 if (!lastURL || lastURL != thisURL) {
396 // Figure out if this page is in the same day as the previous page, 392 // Figure out if this visit is in the same day as the previous visit.
397 // this is used to determine how day headers should be drawn. 393 // This is used to determine how day headers should be drawn.
398 this.pages_.push(new Page(thisResult, thisDay == lastDay, this, 394 this.visits_.push(
399 this.last_id_++)); 395 new Visit(thisResult, thisDay == lastDay, this, this.last_id_++));
400 lastDay = thisDay; 396 lastDay = thisDay;
401 lastURL = thisURL; 397 lastURL = thisURL;
402 } 398 }
403 } 399 }
404 if (results.length) 400 if (results.length)
405 this.changed = true; 401 this.changed = true;
406 } 402 }
407 403
408 this.updateSearch_(info.finished); 404 this.updateSearch_(info.finished);
409 }; 405 };
410 406
411 /** 407 /**
412 * @return {Number} The number of pages in the model. 408 * @return {Number} The number of visits in the model.
413 */ 409 */
414 HistoryModel.prototype.getSize = function() { 410 HistoryModel.prototype.getSize = function() {
415 return this.pages_.length; 411 return this.visits_.length;
416 }; 412 };
417 413
418 /** 414 /**
419 * @return {boolean} Whether our history query has covered all of 415 * Get a list of visits between specified index positions.
420 * the user's history
421 */
422 HistoryModel.prototype.isComplete = function() {
423 return this.complete_;
424 };
425
426 /**
427 * Get a list of pages between specified index positions.
428 * @param {Number} start The start index 416 * @param {Number} start The start index
429 * @param {Number} end The end index 417 * @param {Number} end The end index
430 * @return {Array} A list of pages 418 * @return {Array.<Visit>} A list of visits
431 */ 419 */
432 HistoryModel.prototype.getNumberedRange = function(start, end) { 420 HistoryModel.prototype.getNumberedRange = function(start, end) {
433 if (start >= this.getSize()) 421 if (start >= this.getSize())
434 return []; 422 return [];
435 423
436 var end = end > this.getSize() ? this.getSize() : end; 424 var end = end > this.getSize() ? this.getSize() : end;
437 return this.pages_.slice(start, end); 425 return this.visits_.slice(start, end);
438 }; 426 };
439 427
440 // HistoryModel, Private: ----------------------------------------------------- 428 // HistoryModel, Private: -----------------------------------------------------
441 429
442 /** 430 /**
443 * Clear the history model. 431 * Clear the history model.
444 * @private 432 * @private
445 */ 433 */
446 HistoryModel.prototype.clearModel_ = function() { 434 HistoryModel.prototype.clearModel_ = function() {
447 this.inFlight_ = false; // Whether a query is inflight. 435 this.inFlight_ = false; // Whether a query is inflight.
448 this.searchText_ = ''; 436 this.searchText_ = '';
449 this.searchDepth_ = 0; 437 this.searchDepth_ = 0;
450 this.pages_ = []; // Date-sorted list of pages. 438 this.visits_ = []; // Date-sorted list of visits.
451 this.last_id_ = 0; 439 this.last_id_ = 0;
452 selectionAnchor = -1; 440 selectionAnchor = -1;
453 441
454 // The page that the view wants to see - we only fetch slightly past this 442 // The page that the view wants to see - we only fetch slightly past this
455 // point. If the view requests a page that we don't have data for, we try 443 // point. If the view requests a page that we don't have data for, we try
456 // to fetch it and call back when we're done. 444 // to fetch it and call back when we're done.
457 this.requestedPage_ = 0; 445 this.requestedPage_ = 0;
458 446
459 this.complete_ = false; 447 if (this.view_)
460
461 if (this.view_) {
462 this.view_.clear_(); 448 this.view_.clear_();
463 }
464 }; 449 };
465 450
466 /** 451 /**
467 * Figure out if we need to do more searches to fill the currently requested 452 * Figure out if we need to do more searches to fill the currently requested
468 * page. If we think we can fill the page, call the view and let it know 453 * page. If we think we can fill the page, call the view and let it know
469 * we're ready to show something. 454 * we're ready to show something.
470 * @param {boolean} finished Indicates if there is any more data to come. 455 * @param {boolean} finished Indicates if there is any more data to come.
471 * @private 456 * @private
472 */ 457 */
473 HistoryModel.prototype.updateSearch_ = function(finished) { 458 HistoryModel.prototype.updateSearch_ = function(finished) {
(...skipping 26 matching lines...) Expand all
500 * used. 485 * used.
501 * 486 *
502 * TODO: Fix this for when the user's clock goes across month boundaries. 487 * TODO: Fix this for when the user's clock goes across month boundaries.
503 * @param {number=} depth How many days (or months, if the search text is 488 * @param {number=} depth How many days (or months, if the search text is
504 * non-empty) back to do the search. 489 * non-empty) back to do the search.
505 * @private 490 * @private
506 */ 491 */
507 HistoryModel.prototype.getSearchResults_ = function(depth) { 492 HistoryModel.prototype.getSearchResults_ = function(depth) {
508 this.searchDepth_ = depth || 0; 493 this.searchDepth_ = depth || 0;
509 494
510 if (this.searchText_ == '') { 495 if (this.searchText_) {
496 chrome.send('searchHistory',
497 [this.searchText_, String(this.searchDepth_)]);
498 } else {
511 chrome.send('getHistory', 499 chrome.send('getHistory',
512 [String(this.searchDepth_)]); 500 [String(this.searchDepth_)]);
513 } else {
514 chrome.send('searchHistory',
515 [this.searchText_, String(this.searchDepth_)]);
516 } 501 }
517 502
518 this.inFlight_ = true; 503 this.inFlight_ = true;
519 }; 504 };
520 505
521 /** 506 /**
522 * Check to see if we have data for a given page. 507 * Check to see if we have data for a given page.
523 * @param {number} page The page number 508 * @param {number} page The page number
524 * @return {boolean} Whether we have any data for the given page. 509 * @return {boolean} Whether we have any data for the given page.
525 * @private 510 * @private
(...skipping 26 matching lines...) Expand all
552 this.editButtonTd_ = $('edit-button'); 537 this.editButtonTd_ = $('edit-button');
553 this.editingControlsDiv_ = $('editing-controls'); 538 this.editingControlsDiv_ = $('editing-controls');
554 this.resultDiv_ = $('results-display'); 539 this.resultDiv_ = $('results-display');
555 this.pageDiv_ = $('results-pagination'); 540 this.pageDiv_ = $('results-pagination');
556 this.model_ = model; 541 this.model_ = model;
557 this.pageIndex_ = 0; 542 this.pageIndex_ = 0;
558 this.lastDisplayed_ = []; 543 this.lastDisplayed_ = [];
559 544
560 this.model_.setView(this); 545 this.model_.setView(this);
561 546
562 this.currentPages_ = []; 547 this.currentVisits_ = [];
563 548
564 var self = this; 549 var self = this;
565 window.onresize = function() { 550 window.onresize = function() {
566 self.updateEntryAnchorWidth_(); 551 self.updateEntryAnchorWidth_();
567 }; 552 };
568 553
569 $('clear-browsing-data').addEventListener('click', openClearBrowsingData); 554 $('clear-browsing-data').addEventListener('click', openClearBrowsingData);
570 $('remove-selected').addEventListener('click', removeItems); 555 $('remove-selected').addEventListener('click', removeItems);
571 } 556 }
572 557
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
630 // HistoryView, private: ------------------------------------------------------ 615 // HistoryView, private: ------------------------------------------------------
631 616
632 /** 617 /**
633 * Clear the results in the view. Since we add results piecemeal, we need 618 * Clear the results in the view. Since we add results piecemeal, we need
634 * to clear them out when we switch to a new page or reload. 619 * to clear them out when we switch to a new page or reload.
635 * @private 620 * @private
636 */ 621 */
637 HistoryView.prototype.clear_ = function() { 622 HistoryView.prototype.clear_ = function() {
638 this.resultDiv_.textContent = ''; 623 this.resultDiv_.textContent = '';
639 624
640 var pages = this.currentPages_; 625 this.currentVisits_.forEach(function(visit) {
641 for (var i = 0; i < pages.length; i++) { 626 visit.isRendered = false;
642 pages[i].isRendered = false; 627 });
643 } 628 this.currentVisits_ = [];
644 this.currentPages_ = [];
645 }; 629 };
646 630
647 /** 631 /**
648 * Record that the given page has been rendered. 632 * Record that the given visit has been rendered.
649 * @param {Page} page The page that was rendered. 633 * @param {Visit} visit The visit that was rendered.
650 * @private 634 * @private
651 */ 635 */
652 HistoryView.prototype.setPageRendered_ = function(page) { 636 HistoryView.prototype.setVisitRendered_ = function(visit) {
653 page.isRendered = true; 637 visit.isRendered = true;
654 this.currentPages_.push(page); 638 this.currentVisits_.push(visit);
655 }; 639 };
656 640
657 /** 641 /**
658 * Update the page with results. 642 * Update the page with results.
659 * @private 643 * @private
660 */ 644 */
661 HistoryView.prototype.displayResults_ = function() { 645 HistoryView.prototype.displayResults_ = function() {
662 var results = this.model_.getNumberedRange( 646 var results = this.model_.getNumberedRange(
663 this.pageIndex_ * RESULTS_PER_PAGE, 647 this.pageIndex_ * RESULTS_PER_PAGE,
664 this.pageIndex_ * RESULTS_PER_PAGE + RESULTS_PER_PAGE); 648 this.pageIndex_ * RESULTS_PER_PAGE + RESULTS_PER_PAGE);
665 649
666 var searchText = this.model_.getSearchText(); 650 var searchText = this.model_.getSearchText();
667 if (searchText) { 651 if (searchText) {
668 // Add a header for the search results, if there isn't already one. 652 // Add a header for the search results, if there isn't already one.
669 if (!this.resultDiv_.querySelector('h3')) { 653 if (!this.resultDiv_.querySelector('h3')) {
670 var header = document.createElement('h3'); 654 var header = document.createElement('h3');
671 header.textContent = loadTimeData.getStringF('searchresultsfor', 655 header.textContent = loadTimeData.getStringF('searchresultsfor',
672 searchText); 656 searchText);
673 this.resultDiv_.appendChild(header); 657 this.resultDiv_.appendChild(header);
674 } 658 }
675 659
676 var searchResults = createElementWithClassName('ol', 'search-results'); 660 var searchResults = createElementWithClassName('ol', 'search-results');
677 for (var i = 0, page; page = results[i]; i++) { 661 for (var i = 0, visit; visit = results[i]; i++) {
678 if (!page.isRendered) { 662 if (!visit.isRendered) {
679 searchResults.appendChild(page.getResultDOM(true)); 663 searchResults.appendChild(visit.getResultDOM(true));
680 this.setPageRendered_(page); 664 this.setVisitRendered_(visit);
681 } 665 }
682 } 666 }
683 this.resultDiv_.appendChild(searchResults); 667 this.resultDiv_.appendChild(searchResults);
684 } else { 668 } else {
685 var resultsFragment = document.createDocumentFragment(); 669 var resultsFragment = document.createDocumentFragment();
686 var lastTime = Math.infinity; 670 var lastTime = Math.infinity;
687 var dayResults; 671 var dayResults;
688 for (var i = 0, page; page = results[i]; i++) { 672 for (var i = 0, visit; visit = results[i]; i++) {
689 if (page.isRendered) { 673 if (visit.isRendered) {
690 continue; 674 continue;
691 } 675 }
692 // Break across day boundaries and insert gaps for browsing pauses. 676 // Break across day boundaries and insert gaps for browsing pauses.
693 // Create a dayResults element to contain results for each day 677 // Create a dayResults element to contain results for each day
694 var thisTime = page.time.getTime(); 678 var thisTime = visit.time.getTime();
695 679
696 if ((i == 0 && page.continued) || !page.continued) { 680 if ((i == 0 && visit.continued) || !visit.continued) {
697 var day = createElementWithClassName('h3', 'day'); 681 var day = createElementWithClassName('h3', 'day');
698 day.appendChild(document.createTextNode(page.dateRelativeDay)); 682 day.appendChild(document.createTextNode(visit.dateRelativeDay));
699 if (i == 0 && page.continued) { 683 if (i == 0 && visit.continued) {
700 day.appendChild(document.createTextNode(' ' + 684 day.appendChild(document.createTextNode(' ' +
701 loadTimeData.getString('cont'))); 685 loadTimeData.getString('cont')));
702 } 686 }
703 687
704 // If there is an existing dayResults element, append it. 688 // If there is an existing dayResults element, append it.
705 if (dayResults) { 689 if (dayResults) {
706 resultsFragment.appendChild(dayResults); 690 resultsFragment.appendChild(dayResults);
707 } 691 }
708 resultsFragment.appendChild(day); 692 resultsFragment.appendChild(day);
709 dayResults = createElementWithClassName('ol', 'day-results'); 693 dayResults = createElementWithClassName('ol', 'day-results');
710 } else if (lastTime - thisTime > BROWSING_GAP_TIME) { 694 } else if (lastTime - thisTime > BROWSING_GAP_TIME) {
711 if (dayResults) { 695 if (dayResults) {
712 dayResults.appendChild(createElementWithClassName('li', 'gap')); 696 dayResults.appendChild(createElementWithClassName('li', 'gap'));
713 } 697 }
714 } 698 }
715 lastTime = thisTime; 699 lastTime = thisTime;
716 // Add entry. 700 // Add entry.
717 if (dayResults) { 701 if (dayResults) {
718 dayResults.appendChild(page.getResultDOM(false)); 702 dayResults.appendChild(visit.getResultDOM(false));
719 this.setPageRendered_(page); 703 this.setVisitRendered_(visit);
720 } 704 }
721 } 705 }
722 // Add final dayResults element. 706 // Add final dayResults element.
723 if (dayResults) { 707 if (dayResults) {
724 resultsFragment.appendChild(dayResults); 708 resultsFragment.appendChild(dayResults);
725 } 709 }
726 this.resultDiv_.appendChild(resultsFragment); 710 this.resultDiv_.appendChild(resultsFragment);
727 } 711 }
728 this.displayNavBar_(); 712 this.displayNavBar_();
729 this.updateEntryAnchorWidth_(); 713 this.updateEntryAnchorWidth_();
(...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after
915 899
916 // Create default view. 900 // Create default view.
917 var hashData = pageState.getHashData(); 901 var hashData = pageState.getHashData();
918 historyView.setSearch(hashData.q, hashData.p); 902 historyView.setSearch(hashData.q, hashData.p);
919 903
920 $('search-form').onsubmit = function() { 904 $('search-form').onsubmit = function() {
921 setSearch(searchField.value); 905 setSearch(searchField.value);
922 return false; 906 return false;
923 }; 907 };
924 908
925 $('remove-page').addEventListener('activate', function(e) { 909 $('remove-visit').addEventListener('activate', function(e) {
926 activePage.removeFromHistory_(); 910 activeVisit.removeFromHistory_();
927 activePage = null; 911 activeVisit = null;
928 }); 912 });
929 $('more-from-site').addEventListener('activate', function(e) { 913 $('more-from-site').addEventListener('activate', function(e) {
930 activePage.showMoreFromSite_(); 914 activeVisit.showMoreFromSite_();
931 activePage = null; 915 activeVisit = null;
932 }); 916 });
933 917
934 var title = loadTimeData.getString('title'); 918 var title = loadTimeData.getString('title');
935 uber.invokeMethodOnParent('setTitle', {title: title}); 919 uber.invokeMethodOnParent('setTitle', {title: title});
936 920
937 window.addEventListener('message', function(e) { 921 window.addEventListener('message', function(e) {
938 if (e.data.method == 'frameSelected') 922 if (e.data.method == 'frameSelected')
939 searchField.focus(); 923 searchField.focus();
940 }); 924 });
941 } 925 }
(...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after
1173 historyView.reload(); 1157 historyView.reload();
1174 } 1158 }
1175 1159
1176 // Add handlers to HTML elements. 1160 // Add handlers to HTML elements.
1177 document.addEventListener('DOMContentLoaded', load); 1161 document.addEventListener('DOMContentLoaded', load);
1178 1162
1179 // This event lets us enable and disable menu items before the menu is shown. 1163 // This event lets us enable and disable menu items before the menu is shown.
1180 document.addEventListener('canExecute', function(e) { 1164 document.addEventListener('canExecute', function(e) {
1181 e.canExecute = true; 1165 e.canExecute = true;
1182 }); 1166 });
OLDNEW
« no previous file with comments | « chrome/browser/resources/history/history.html ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698