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

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

Issue 10164005: History: Fix JavaScript style issues so presubmit checks pass. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Address tbreisacher's comments. Created 8 years, 8 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 | « no previous file | chrome/browser/resources/web_dev_style/js_checker.py » ('j') | 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 var RESULTS_PER_PAGE = 150; 9 /** @const */ var RESULTS_PER_PAGE = 150;
10 var MAX_SEARCH_DEPTH_MONTHS = 18; 10 /** @const */ var MAX_SEARCH_DEPTH_MONTHS = 18;
11 11
12 // Amount of time between pageviews that we consider a 'break' in browsing, 12 // Amount of time between pageviews that we consider a 'break' in browsing,
13 // measured in milliseconds. 13 // measured in milliseconds.
14 var BROWSING_GAP_TIME = 15 * 60 * 1000; 14 /** @const */ var BROWSING_GAP_TIME = 15 * 60 * 1000;
15 15
16 function $(o) {return document.getElementById(o);} 16 function $(o) {return document.getElementById(o);}
17 17
18 function createElementWithClassName(type, className) { 18 function createElementWithClassName(type, className) {
19 var elm = document.createElement(type); 19 var elm = document.createElement(type);
20 elm.className = className; 20 elm.className = className;
21 return elm; 21 return elm;
22 } 22 }
23 23
24 // Escapes a URI as appropriate for CSS. 24 // Escapes a URI as appropriate for CSS.
25 function encodeURIForCSS(uri) { 25 function encodeURIForCSS(uri) {
26 // CSS URIs need to have '(' and ')' escaped. 26 // CSS URIs need to have '(' and ')' escaped.
27 return uri.replace(/\(/g, "\\(").replace(/\)/g, "\\)"); 27 return uri.replace(/\(/g, '\\(').replace(/\)/g, '\\)');
28 } 28 }
29 29
30 function findAncestorWithClass(node, className) { 30 function findAncestorWithClass(node, className) {
31 while ((node = node.parentNode)) { 31 while ((node = node.parentNode)) {
32 if (node.classList.contains(className)) return node; 32 if (node.classList.contains(className)) return node;
33 } 33 }
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 localStrings; 41 var localStrings;
42 var pageState; 42 var pageState;
43 var deleteQueue = []; 43 var deleteQueue = [];
44 var selectionAnchor = -1; 44 var selectionAnchor = -1;
45 var activePage = null; 45 var activePage = null;
46 46
47 const MenuButton = cr.ui.MenuButton; 47 /** @const */ var MenuButton = cr.ui.MenuButton;
48 const Command = cr.ui.Command; 48 /** @const */ var Command = cr.ui.Command;
49 const Menu = cr.ui.Menu; 49 /** @const */ var Menu = cr.ui.Menu;
50 50
51 function createDropDownBgImage(canvasName, colorSpec) { 51 function createDropDownBgImage(canvasName, colorSpec) {
52 var ctx = document.getCSSCanvasContext('2d', canvasName, 6, 4); 52 var ctx = document.getCSSCanvasContext('2d', canvasName, 6, 4);
53 ctx.fillStyle = ctx.strokeStyle = colorSpec; 53 ctx.fillStyle = ctx.strokeStyle = colorSpec;
54 ctx.beginPath(); 54 ctx.beginPath();
55 ctx.moveTo(0, 0); 55 ctx.moveTo(0, 0);
56 ctx.lineTo(6, 0); 56 ctx.lineTo(6, 0);
57 ctx.lineTo(3, 3); 57 ctx.lineTo(3, 3);
58 ctx.closePath(); 58 ctx.closePath();
59 ctx.fill(); 59 ctx.fill();
60 ctx.stroke(); 60 ctx.stroke();
61 return ctx; 61 return ctx;
62 } 62 }
63 63
64 // Create the canvases to be used as the drop down button background images. 64 // Create the canvases to be used as the drop down button background images.
65 var arrow = createDropDownBgImage('drop-down-arrow', 'rgb(192, 195, 198)'); 65 var arrow = createDropDownBgImage('drop-down-arrow', 'rgb(192, 195, 198)');
66 var hoverArrow = createDropDownBgImage('drop-down-arrow-hover', 66 var hoverArrow = createDropDownBgImage('drop-down-arrow-hover',
67 'rgb(48, 57, 66)'); 67 'rgb(48, 57, 66)');
68 var activeArrow = createDropDownBgImage('drop-down-arrow-active', 'white'); 68 var activeArrow = createDropDownBgImage('drop-down-arrow-active', 'white');
69 69
70 /////////////////////////////////////////////////////////////////////////////// 70 ///////////////////////////////////////////////////////////////////////////////
71 // Page: 71 // Page:
72
72 /** 73 /**
73 * Class to hold all the information about an entry in our model. 74 * Class to hold all the information about an entry in our model.
74 * @param {Object} result An object containing the page's data. 75 * @param {Object} result An object containing the page's data.
75 * @param {boolean} continued Whether this page is on the same day as the 76 * @param {boolean} continued Whether this page is on the same day as the
76 * page before it 77 * page before it
78 * @param {HistoryModel} model The model object this entry belongs to.
79 * @param {Number} id The identifier for the entry.
80 * @constructor
77 */ 81 */
78 function Page(result, continued, model, id) { 82 function Page(result, continued, model, id) {
79 this.model_ = model; 83 this.model_ = model;
80 this.title_ = result.title; 84 this.title_ = result.title;
81 this.url_ = result.url; 85 this.url_ = result.url;
82 this.domain_ = this.getDomainFromURL_(this.url_); 86 this.domain_ = this.getDomainFromURL_(this.url_);
83 this.starred_ = result.starred; 87 this.starred_ = result.starred;
84 this.snippet_ = result.snippet || ""; 88 this.snippet_ = result.snippet || '';
85 this.id_ = id; 89 this.id_ = id;
86 90
87 this.changed = false; 91 this.changed = false;
88 92
89 this.isRendered = false; 93 this.isRendered = false;
90 94
91 // All the date information is public so that owners can compare properties of 95 // All the date information is public so that owners can compare properties of
92 // two items easily. 96 // two items easily.
93 97
94 // We get the time in seconds, but we want it in milliseconds. 98 // We get the time in seconds, but we want it in milliseconds.
95 this.time = new Date(result.time * 1000); 99 this.time = new Date(result.time * 1000);
96 100
97 // See comment in BrowsingHistoryHandler::QueryComplete - we won't always 101 // See comment in BrowsingHistoryHandler::QueryComplete - we won't always
98 // get all of these. 102 // get all of these.
99 this.dateRelativeDay = result.dateRelativeDay || ""; 103 this.dateRelativeDay = result.dateRelativeDay || '';
100 this.dateTimeOfDay = result.dateTimeOfDay || ""; 104 this.dateTimeOfDay = result.dateTimeOfDay || '';
101 this.dateShort = result.dateShort || ""; 105 this.dateShort = result.dateShort || '';
102 106
103 // Whether this is the continuation of a previous day. 107 // Whether this is the continuation of a previous day.
104 this.continued = continued; 108 this.continued = continued;
105 } 109 }
106 110
107 // Page, Public: -------------------------------------------------------------- 111 // Page, Public: --------------------------------------------------------------
112
108 /** 113 /**
109 * Returns a dom structure for a browse page result or a search page result. 114 * Returns a dom structure for a browse page result or a search page result.
110 * @param {boolean} Flag to indicate if result is a search result. 115 * @param {boolean} searchResultFlag Indicates whether the result is a search
111 * @return {Element} The dom structure. 116 * result or not.
117 * @return {Node} A DOM node to represent the history entry or search result.
112 */ 118 */
113 Page.prototype.getResultDOM = function(searchResultFlag) { 119 Page.prototype.getResultDOM = function(searchResultFlag) {
114 var node = createElementWithClassName('li', 'entry'); 120 var node = createElementWithClassName('li', 'entry');
115 var time = createElementWithClassName('div', 'time'); 121 var time = createElementWithClassName('div', 'time');
116 var entryBox = createElementWithClassName('label', 'entry-box'); 122 var entryBox = createElementWithClassName('label', 'entry-box');
117 var domain = createElementWithClassName('div', 'domain'); 123 var domain = createElementWithClassName('div', 'domain');
118 124
119 var dropDown = createElementWithClassName('button', 'drop-down'); 125 var dropDown = createElementWithClassName('button', 'drop-down');
120 dropDown.value = 'Open action menu'; 126 dropDown.value = 'Open action menu';
121 dropDown.title = localStrings.getString('actionMenuDescription'); 127 dropDown.title = localStrings.getString('actionMenuDescription');
(...skipping 15 matching lines...) Expand all
137 var setActivePage = function(e) { 143 var setActivePage = function(e) {
138 activePage = self; 144 activePage = self;
139 }; 145 };
140 dropDown.addEventListener('mousedown', setActivePage); 146 dropDown.addEventListener('mousedown', setActivePage);
141 dropDown.addEventListener('focus', setActivePage); 147 dropDown.addEventListener('focus', setActivePage);
142 148
143 domain.textContent = this.domain_; 149 domain.textContent = this.domain_;
144 150
145 // Clicking anywhere in the entryBox will check/uncheck the checkbox. 151 // Clicking anywhere in the entryBox will check/uncheck the checkbox.
146 entryBox.setAttribute('for', checkbox.id); 152 entryBox.setAttribute('for', checkbox.id);
147 entryBox.addEventListener('mousedown', entryBoxMousedown, false); 153 entryBox.addEventListener('mousedown', entryBoxMousedown);
148 154
149 // Prevent clicks on the drop down from affecting the checkbox. 155 // Prevent clicks on the drop down from affecting the checkbox.
150 dropDown.addEventListener('click', function(e) { e.preventDefault(); }); 156 dropDown.addEventListener('click', function(e) { e.preventDefault(); });
151 157
152 // We use a wrapper div so that the entry contents will be shinkwrapped. 158 // We use a wrapper div so that the entry contents will be shinkwrapped.
153 entryBox.appendChild(time); 159 entryBox.appendChild(time);
154 entryBox.appendChild(this.getTitleDOM_()); 160 entryBox.appendChild(this.getTitleDOM_());
155 entryBox.appendChild(domain); 161 entryBox.appendChild(domain);
156 entryBox.appendChild(dropDown); 162 entryBox.appendChild(dropDown);
157 163
(...skipping 20 matching lines...) Expand all
178 184
179 if (typeof this.domNode_ != 'undefined') { 185 if (typeof this.domNode_ != 'undefined') {
180 console.error('Already generated node for page.'); 186 console.error('Already generated node for page.');
181 } 187 }
182 this.domNode_ = node; 188 this.domNode_ = node;
183 189
184 return node; 190 return node;
185 }; 191 };
186 192
187 // Page, private: ------------------------------------------------------------- 193 // Page, private: -------------------------------------------------------------
194
188 /** 195 /**
189 * Extracts and returns the domain (and subdomains) from a URL. 196 * Extracts and returns the domain (and subdomains) from a URL.
190 * @param {string} The url 197 * @param {string} url The url.
191 * @return (string) The domain. An empty string is returned if no domain can 198 * @return {string} The domain. An empty string is returned if no domain can
192 * be found. 199 * be found.
200 * @private
193 */ 201 */
194 Page.prototype.getDomainFromURL_ = function(url) { 202 Page.prototype.getDomainFromURL_ = function(url) {
195 var domain = url.replace(/^.+:\/\//, '').match(/[^/]+/); 203 var domain = url.replace(/^.+:\/\//, '').match(/[^/]+/);
196 return domain ? domain[0] : ''; 204 return domain ? domain[0] : '';
197 }; 205 };
198 206
199 /** 207 /**
200 * Add child text nodes to a node such that occurrences of the specified text is 208 * Add child text nodes to a node such that occurrences of the specified text is
201 * highlighted. 209 * highlighted.
202 * @param {Node} node The node under which new text nodes will be made as 210 * @param {Node} node The node under which new text nodes will be made as
203 * children. 211 * children.
204 * @param {string} content Text to be added beneath |node| as one or more 212 * @param {string} content Text to be added beneath |node| as one or more
205 * text nodes. 213 * text nodes.
206 * @param {string} highlightText Occurences of this text inside |content| will 214 * @param {string} highlightText Occurences of this text inside |content| will
207 * be highlighted. 215 * be highlighted.
216 * @private
208 */ 217 */
209 Page.prototype.addHighlightedText_ = function(node, content, highlightText) { 218 Page.prototype.addHighlightedText_ = function(node, content, highlightText) {
210 var i = 0; 219 var i = 0;
211 if (highlightText) { 220 if (highlightText) {
212 var re = new RegExp(Page.pregQuote_(highlightText), 'gim'); 221 var re = new RegExp(Page.pregQuote_(highlightText), 'gim');
213 var match; 222 var match;
214 while (match = re.exec(content)) { 223 while (match = re.exec(content)) {
215 if (match.index > i) 224 if (match.index > i)
216 node.appendChild(document.createTextNode(content.slice(i, 225 node.appendChild(document.createTextNode(content.slice(i,
217 match.index))); 226 match.index)));
218 i = re.lastIndex; 227 i = re.lastIndex;
219 // Mark the highlighted text in bold. 228 // Mark the highlighted text in bold.
220 var b = document.createElement('b'); 229 var b = document.createElement('b');
221 b.textContent = content.substring(match.index, i); 230 b.textContent = content.substring(match.index, i);
222 node.appendChild(b); 231 node.appendChild(b);
223 } 232 }
224 } 233 }
225 if (i < content.length) 234 if (i < content.length)
226 node.appendChild(document.createTextNode(content.slice(i))); 235 node.appendChild(document.createTextNode(content.slice(i)));
227 }; 236 };
228 237
229 /** 238 /**
230 * @return {DOMObject} DOM representation for the title block. 239 * @return {DOMObject} DOM representation for the title block.
240 * @private
231 */ 241 */
232 Page.prototype.getTitleDOM_ = function() { 242 Page.prototype.getTitleDOM_ = function() {
233 var node = createElementWithClassName('div', 'title'); 243 var node = createElementWithClassName('div', 'title');
234 node.style.backgroundImage = 244 node.style.backgroundImage =
235 'url(chrome://favicon/' + encodeURIForCSS(this.url_) + ')'; 245 'url(chrome://favicon/' + encodeURIForCSS(this.url_) + ')';
236 246
237 var link = document.createElement('a'); 247 var link = document.createElement('a');
238 link.href = this.url_; 248 link.href = this.url_;
239 link.id = "id-" + this.id_; 249 link.id = 'id-' + this.id_;
240 link.target = "_top"; 250 link.target = '_top';
241 251
242 // Add a tooltip, since it might be ellipsized. 252 // Add a tooltip, since it might be ellipsized.
243 // TODO(dubroy): Find a way to show the tooltip only when necessary. 253 // TODO(dubroy): Find a way to show the tooltip only when necessary.
244 link.title = this.title_; 254 link.title = this.title_;
245 255
246 this.addHighlightedText_(link, this.title_, this.model_.getSearchText()); 256 this.addHighlightedText_(link, this.title_, this.model_.getSearchText());
247 node.appendChild(link); 257 node.appendChild(link);
248 258
249 if (this.starred_) { 259 if (this.starred_) {
250 var star = createElementWithClassName('div', 'starred'); 260 var star = createElementWithClassName('div', 'starred');
251 node.appendChild(star); 261 node.appendChild(star);
252 star.addEventListener('click', this.starClicked_.bind(this)); 262 star.addEventListener('click', this.starClicked_.bind(this));
253 } 263 }
254 264
255 return node; 265 return node;
256 }; 266 };
257 267
258 /** 268 /**
259 * Launch a search for more history entries from the same domain. 269 * Launch a search for more history entries from the same domain.
270 * @private
260 */ 271 */
261 Page.prototype.showMoreFromSite_ = function() { 272 Page.prototype.showMoreFromSite_ = function() {
262 setSearch(this.domain_); 273 setSearch(this.domain_);
263 }; 274 };
264 275
265 /** 276 /**
266 * Remove a single entry from the history. 277 * Remove a single entry from the history.
278 * @private
267 */ 279 */
268 Page.prototype.removeFromHistory_ = function() { 280 Page.prototype.removeFromHistory_ = function() {
269 var self = this; 281 var self = this;
270 var onSuccessCallback = function() { 282 var onSuccessCallback = function() {
271 removeEntryFromView(self.domNode_); 283 removeEntryFromView(self.domNode_);
272 }; 284 };
273 queueURLsForDeletion(this.time, [this.url_], onSuccessCallback); 285 queueURLsForDeletion(this.time, [this.url_], onSuccessCallback);
274 deleteNextInQueue(); 286 deleteNextInQueue();
275 }; 287 };
276 288
277 /** 289 /**
278 * Click event handler for the star icon that appears beside bookmarked URLs. 290 * Click event handler for the star icon that appears beside bookmarked URLs.
279 * When clicked, the bookmark is removed for that URL. 291 * When clicked, the bookmark is removed for that URL.
292 * @param {Event} event The click event.
280 * @private 293 * @private
281 */ 294 */
282 Page.prototype.starClicked_ = function(event) { 295 Page.prototype.starClicked_ = function(event) {
283 chrome.send('removeBookmark', [this.url_]); 296 chrome.send('removeBookmark', [this.url_]);
284 event.currentTarget.hidden = true; 297 event.currentTarget.hidden = true;
285 event.preventDefault(); 298 event.preventDefault();
286 } 299 };
287 300
288 // Page, private, static: ----------------------------------------------------- 301 // Page, private, static: -----------------------------------------------------
289 302
290 /** 303 /**
291 * Quote a string so it can be used in a regular expression. 304 * Quote a string so it can be used in a regular expression.
292 * @param {string} str The source string 305 * @param {string} str The source string
293 * @return {string} The escaped string 306 * @return {string} The escaped string
307 * @private
294 */ 308 */
295 Page.pregQuote_ = function(str) { 309 Page.pregQuote_ = function(str) {
296 return str.replace(/([\\\.\+\*\?\[\^\]\$\(\)\{\}\=\!\<\>\|\:])/g, "\\$1"); 310 return str.replace(/([\\\.\+\*\?\[\^\]\$\(\)\{\}\=\!\<\>\|\:])/g, '\\$1');
297 }; 311 };
298 312
299 /////////////////////////////////////////////////////////////////////////////// 313 ///////////////////////////////////////////////////////////////////////////////
300 // HistoryModel: 314 // HistoryModel:
315
301 /** 316 /**
302 * Global container for history data. Future optimizations might include 317 * Global container for history data. Future optimizations might include
303 * allowing the creation of a HistoryModel for each search string, allowing 318 * allowing the creation of a HistoryModel for each search string, allowing
304 * quick flips back and forth between results. 319 * quick flips back and forth between results.
305 * 320 *
306 * The history model is based around pages, and only fetching the data to 321 * The history model is based around pages, and only fetching the data to
307 * fill the currently requested page. This is somewhat dependent on the view, 322 * fill the currently requested page. This is somewhat dependent on the view,
308 * and so future work may wish to change history model to operate on 323 * and so future work may wish to change history model to operate on
309 * timeframe (day or week) based containers. 324 * timeframe (day or week) based containers.
325 *
326 * @constructor
310 */ 327 */
311 function HistoryModel() { 328 function HistoryModel() {
312 this.clearModel_(); 329 this.clearModel_();
313 } 330 }
314 331
315 // HistoryModel, Public: ------------------------------------------------------ 332 // HistoryModel, Public: ------------------------------------------------------
333
316 /** 334 /**
317 * Sets our current view that is called when the history model changes. 335 * Sets our current view that is called when the history model changes.
318 * @param {HistoryView} view The view to set our current view to. 336 * @param {HistoryView} view The view to set our current view to.
319 */ 337 */
320 HistoryModel.prototype.setView = function(view) { 338 HistoryModel.prototype.setView = function(view) {
321 this.view_ = view; 339 this.view_ = view;
322 }; 340 };
323 341
324 /** 342 /**
325 * Start a new search - this will clear out our model. 343 * Start a new search - this will clear out our model.
(...skipping 23 matching lines...) Expand all
349 /** 367 /**
350 * @return {String} The current search text. 368 * @return {String} The current search text.
351 */ 369 */
352 HistoryModel.prototype.getSearchText = function() { 370 HistoryModel.prototype.getSearchText = function() {
353 return this.searchText_; 371 return this.searchText_;
354 }; 372 };
355 373
356 /** 374 /**
357 * Tell the model that the view will want to see the current page. When 375 * Tell the model that the view will want to see the current page. When
358 * the data becomes available, the model will call the view back. 376 * the data becomes available, the model will call the view back.
359 * @page {Number} page The page we want to view. 377 * @param {Number} page The page we want to view.
360 */ 378 */
361 HistoryModel.prototype.requestPage = function(page) { 379 HistoryModel.prototype.requestPage = function(page) {
362 this.requestedPage_ = page; 380 this.requestedPage_ = page;
363 this.changed = true; 381 this.changed = true;
364 this.updateSearch_(false); 382 this.updateSearch_(false);
365 }; 383 };
366 384
367 /** 385 /**
368 * Receiver for history query. 386 * Receiver for history query.
369 * @param {String} term The search term that the results are for. 387 * @param {Object} info An object containing information about the query.
370 * @param {Array} results A list of results 388 * @param {Array} results A list of results.
371 */ 389 */
372 HistoryModel.prototype.addResults = function(info, results) { 390 HistoryModel.prototype.addResults = function(info, results) {
373 this.inFlight_ = false; 391 this.inFlight_ = false;
374 if (info.term != this.searchText_) { 392 if (info.term != this.searchText_) {
375 // If our results aren't for our current search term, they're rubbish. 393 // If our results aren't for our current search term, they're rubbish.
376 return; 394 return;
377 } 395 }
378 396
379 // Currently we assume we're getting things in date order. This needs to 397 // Currently we assume we're getting things in date order. This needs to
380 // be updated if that ever changes. 398 // be updated if that ever changes.
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
431 */ 449 */
432 HistoryModel.prototype.getNumberedRange = function(start, end) { 450 HistoryModel.prototype.getNumberedRange = function(start, end) {
433 if (start >= this.getSize()) 451 if (start >= this.getSize())
434 return []; 452 return [];
435 453
436 var end = end > this.getSize() ? this.getSize() : end; 454 var end = end > this.getSize() ? this.getSize() : end;
437 return this.pages_.slice(start, end); 455 return this.pages_.slice(start, end);
438 }; 456 };
439 457
440 // HistoryModel, Private: ----------------------------------------------------- 458 // HistoryModel, Private: -----------------------------------------------------
459
460 /**
461 * Clear the history model.
462 * @private
463 */
441 HistoryModel.prototype.clearModel_ = function() { 464 HistoryModel.prototype.clearModel_ = function() {
442 this.inFlight_ = false; // Whether a query is inflight. 465 this.inFlight_ = false; // Whether a query is inflight.
443 this.searchText_ = ''; 466 this.searchText_ = '';
444 this.searchDepth_ = 0; 467 this.searchDepth_ = 0;
445 this.pages_ = []; // Date-sorted list of pages. 468 this.pages_ = []; // Date-sorted list of pages.
446 this.last_id_ = 0; 469 this.last_id_ = 0;
447 selectionAnchor = -1; 470 selectionAnchor = -1;
448 471
449 // The page that the view wants to see - we only fetch slightly past this 472 // The page that the view wants to see - we only fetch slightly past this
450 // point. If the view requests a page that we don't have data for, we try 473 // point. If the view requests a page that we don't have data for, we try
451 // to fetch it and call back when we're done. 474 // to fetch it and call back when we're done.
452 this.requestedPage_ = 0; 475 this.requestedPage_ = 0;
453 476
454 this.complete_ = false; 477 this.complete_ = false;
455 478
456 if (this.view_) { 479 if (this.view_) {
457 this.view_.clear_(); 480 this.view_.clear_();
458 } 481 }
459 }; 482 };
460 483
461 /** 484 /**
462 * Figure out if we need to do more searches to fill the currently requested 485 * Figure out if we need to do more searches to fill the currently requested
463 * page. If we think we can fill the page, call the view and let it know 486 * page. If we think we can fill the page, call the view and let it know
464 * we're ready to show something. 487 * we're ready to show something.
488 * @param {boolean} finished Indicates if there is any more data to come.
489 * @private
465 */ 490 */
466 HistoryModel.prototype.updateSearch_ = function(finished) { 491 HistoryModel.prototype.updateSearch_ = function(finished) {
467 if ((this.searchText_ && this.searchDepth_ >= MAX_SEARCH_DEPTH_MONTHS) || 492 if ((this.searchText_ && this.searchDepth_ >= MAX_SEARCH_DEPTH_MONTHS) ||
468 finished) { 493 finished) {
469 // We have maxed out. There will be no more data. 494 // We have maxed out. There will be no more data.
470 this.complete_ = true; 495 this.complete_ = true;
471 this.view_.onModelReady(); 496 this.view_.onModelReady();
472 this.changed = false; 497 this.changed = false;
473 } else { 498 } else {
474 // If we can't fill the requested page, ask for more data unless a request 499 // If we can't fill the requested page, ask for more data unless a request
(...skipping 11 matching lines...) Expand all
486 }; 511 };
487 512
488 /** 513 /**
489 * Get search results for a selected depth. Our history system is optimized 514 * Get search results for a selected depth. Our history system is optimized
490 * for queries that don't cross month boundaries, but an entire month's 515 * for queries that don't cross month boundaries, but an entire month's
491 * worth of data is huge. When we're in browse mode (searchText is empty) 516 * worth of data is huge. When we're in browse mode (searchText is empty)
492 * we request the data a day at a time. When we're searching, a month is 517 * we request the data a day at a time. When we're searching, a month is
493 * used. 518 * used.
494 * 519 *
495 * TODO: Fix this for when the user's clock goes across month boundaries. 520 * TODO: Fix this for when the user's clock goes across month boundaries.
496 * @param {number} opt_day How many days back to do the search. 521 * @param {number=} depth How many days (or months, if the search text is
522 * non-empty) back to do the search.
523 * @private
497 */ 524 */
498 HistoryModel.prototype.getSearchResults_ = function(depth) { 525 HistoryModel.prototype.getSearchResults_ = function(depth) {
499 this.searchDepth_ = depth || 0; 526 this.searchDepth_ = depth || 0;
500 527
501 if (this.searchText_ == "") { 528 if (this.searchText_ == '') {
502 chrome.send('getHistory', 529 chrome.send('getHistory',
503 [String(this.searchDepth_)]); 530 [String(this.searchDepth_)]);
504 } else { 531 } else {
505 chrome.send('searchHistory', 532 chrome.send('searchHistory',
506 [this.searchText_, String(this.searchDepth_)]); 533 [this.searchText_, String(this.searchDepth_)]);
507 } 534 }
508 535
509 this.inFlight_ = true; 536 this.inFlight_ = true;
510 }; 537 };
511 538
512 /** 539 /**
513 * Check to see if we have data for a given page. 540 * Check to see if we have data for a given page.
514 * @param {number} page The page number 541 * @param {number} page The page number
515 * @return {boolean} Whether we have any data for the given page. 542 * @return {boolean} Whether we have any data for the given page.
543 * @private
516 */ 544 */
517 HistoryModel.prototype.haveDataForPage_ = function(page) { 545 HistoryModel.prototype.haveDataForPage_ = function(page) {
518 return (page * RESULTS_PER_PAGE < this.getSize()); 546 return (page * RESULTS_PER_PAGE < this.getSize());
519 }; 547 };
520 548
521 /** 549 /**
522 * Check to see if we have data to fill a page. 550 * Check to see if we have data to fill a page.
523 * @param {number} page The page number. 551 * @param {number} page The page number.
524 * @return {boolean} Whether we have data to fill the page. 552 * @return {boolean} Whether we have data to fill the page.
553 * @private
525 */ 554 */
526 HistoryModel.prototype.canFillPage_ = function(page) { 555 HistoryModel.prototype.canFillPage_ = function(page) {
527 return ((page + 1) * RESULTS_PER_PAGE <= this.getSize()); 556 return ((page + 1) * RESULTS_PER_PAGE <= this.getSize());
528 }; 557 };
529 558
530 /////////////////////////////////////////////////////////////////////////////// 559 ///////////////////////////////////////////////////////////////////////////////
531 // HistoryView: 560 // HistoryView:
561
532 /** 562 /**
533 * Functions and state for populating the page with HTML. This should one-day 563 * Functions and state for populating the page with HTML. This should one-day
534 * contain the view and use event handlers, rather than pushing HTML out and 564 * contain the view and use event handlers, rather than pushing HTML out and
535 * getting called externally. 565 * getting called externally.
536 * @param {HistoryModel} model The model backing this view. 566 * @param {HistoryModel} model The model backing this view.
567 * @constructor
537 */ 568 */
538 function HistoryView(model) { 569 function HistoryView(model) {
539 this.editButtonTd_ = $('edit-button'); 570 this.editButtonTd_ = $('edit-button');
540 this.editingControlsDiv_ = $('editing-controls'); 571 this.editingControlsDiv_ = $('editing-controls');
541 this.resultDiv_ = $('results-display'); 572 this.resultDiv_ = $('results-display');
542 this.pageDiv_ = $('results-pagination'); 573 this.pageDiv_ = $('results-pagination');
543 this.model_ = model 574 this.model_ = model;
544 this.pageIndex_ = 0; 575 this.pageIndex_ = 0;
545 this.lastDisplayed_ = []; 576 this.lastDisplayed_ = [];
546 577
547 this.model_.setView(this); 578 this.model_.setView(this);
548 579
549 this.currentPages_ = []; 580 this.currentPages_ = [];
550 581
551 var self = this; 582 var self = this;
552 window.onresize = function() { 583 window.onresize = function() {
553 self.updateEntryAnchorWidth_(); 584 self.updateEntryAnchorWidth_();
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
605 HistoryView.prototype.onModelReady = function() { 636 HistoryView.prototype.onModelReady = function() {
606 this.displayResults_(); 637 this.displayResults_();
607 }; 638 };
608 639
609 /** 640 /**
610 * Enables or disables the 'Remove selected items' button as appropriate. 641 * Enables or disables the 'Remove selected items' button as appropriate.
611 */ 642 */
612 HistoryView.prototype.updateRemoveButton = function() { 643 HistoryView.prototype.updateRemoveButton = function() {
613 var anyChecked = document.querySelector('.entry input:checked') != null; 644 var anyChecked = document.querySelector('.entry input:checked') != null;
614 $('remove-selected').disabled = !anyChecked; 645 $('remove-selected').disabled = !anyChecked;
615 } 646 };
616 647
617 // HistoryView, private: ------------------------------------------------------ 648 // HistoryView, private: ------------------------------------------------------
649
618 /** 650 /**
619 * Clear the results in the view. Since we add results piecemeal, we need 651 * Clear the results in the view. Since we add results piecemeal, we need
620 * to clear them out when we switch to a new page or reload. 652 * to clear them out when we switch to a new page or reload.
653 * @private
621 */ 654 */
622 HistoryView.prototype.clear_ = function() { 655 HistoryView.prototype.clear_ = function() {
623 this.resultDiv_.textContent = ''; 656 this.resultDiv_.textContent = '';
624 657
625 var pages = this.currentPages_; 658 var pages = this.currentPages_;
626 for (var i = 0; i < pages.length; i++) { 659 for (var i = 0; i < pages.length; i++) {
627 pages[i].isRendered = false; 660 pages[i].isRendered = false;
628 } 661 }
629 this.currentPages_ = []; 662 this.currentPages_ = [];
630 }; 663 };
631 664
665 /**
666 * Record that the given page has been rendered.
667 * @param {Page} page The page that was rendered.
668 * @private
669 */
632 HistoryView.prototype.setPageRendered_ = function(page) { 670 HistoryView.prototype.setPageRendered_ = function(page) {
633 page.isRendered = true; 671 page.isRendered = true;
634 this.currentPages_.push(page); 672 this.currentPages_.push(page);
635 }; 673 };
636 674
637 /** 675 /**
638 * Update the page with results. 676 * Update the page with results.
677 * @private
639 */ 678 */
640 HistoryView.prototype.displayResults_ = function() { 679 HistoryView.prototype.displayResults_ = function() {
641 var results = this.model_.getNumberedRange( 680 var results = this.model_.getNumberedRange(
642 this.pageIndex_ * RESULTS_PER_PAGE, 681 this.pageIndex_ * RESULTS_PER_PAGE,
643 this.pageIndex_ * RESULTS_PER_PAGE + RESULTS_PER_PAGE); 682 this.pageIndex_ * RESULTS_PER_PAGE + RESULTS_PER_PAGE);
644 683
645 var searchText = this.model_.getSearchText(); 684 var searchText = this.model_.getSearchText();
646 if (searchText) { 685 if (searchText) {
647 // Add a header for the search results, if there isn't already one. 686 // Add a header for the search results, if there isn't already one.
648 if (!this.resultDiv_.querySelector('h3')) { 687 if (!this.resultDiv_.querySelector('h3')) {
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
703 resultsFragment.appendChild(dayResults); 742 resultsFragment.appendChild(dayResults);
704 } 743 }
705 this.resultDiv_.appendChild(resultsFragment); 744 this.resultDiv_.appendChild(resultsFragment);
706 } 745 }
707 this.displayNavBar_(); 746 this.displayNavBar_();
708 this.updateEntryAnchorWidth_(); 747 this.updateEntryAnchorWidth_();
709 }; 748 };
710 749
711 /** 750 /**
712 * Update the pagination tools. 751 * Update the pagination tools.
752 * @private
713 */ 753 */
714 HistoryView.prototype.displayNavBar_ = function() { 754 HistoryView.prototype.displayNavBar_ = function() {
715 this.pageDiv_.textContent = ''; 755 this.pageDiv_.textContent = '';
716 756
717 if (this.pageIndex_ > 0) { 757 if (this.pageIndex_ > 0) {
718 this.pageDiv_.appendChild( 758 this.pageDiv_.appendChild(
719 this.createPageNav_(0, localStrings.getString('newest'))); 759 this.createPageNav_(0, localStrings.getString('newest')));
720 this.pageDiv_.appendChild( 760 this.pageDiv_.appendChild(
721 this.createPageNav_(this.pageIndex_ - 1, 761 this.createPageNav_(this.pageIndex_ - 1,
722 localStrings.getString('newer'))); 762 localStrings.getString('newer')));
723 } 763 }
724 764
725 // TODO(feldstein): this causes the navbar to not show up when your first 765 // TODO(feldstein): this causes the navbar to not show up when your first
726 // page has the exact amount of results as RESULTS_PER_PAGE. 766 // page has the exact amount of results as RESULTS_PER_PAGE.
727 if (this.model_.getSize() > (this.pageIndex_ + 1) * RESULTS_PER_PAGE) { 767 if (this.model_.getSize() > (this.pageIndex_ + 1) * RESULTS_PER_PAGE) {
728 this.pageDiv_.appendChild( 768 this.pageDiv_.appendChild(
729 this.createPageNav_(this.pageIndex_ + 1, 769 this.createPageNav_(this.pageIndex_ + 1,
730 localStrings.getString('older'))); 770 localStrings.getString('older')));
731 } 771 }
732 }; 772 };
733 773
734 /** 774 /**
735 * Make a DOM object representation of a page navigation link. 775 * Make a DOM object representation of a page navigation link.
736 * @param {number} page The page index the navigation element should link to 776 * @param {number} page The page index the navigation element should link to
737 * @param {string} name The text content of the link 777 * @param {string} name The text content of the link
738 * @return {HTMLAnchorElement} the pagination link 778 * @return {HTMLAnchorElement} the pagination link
779 * @private
739 */ 780 */
740 HistoryView.prototype.createPageNav_ = function(page, name) { 781 HistoryView.prototype.createPageNav_ = function(page, name) {
741 var navButton = createElementWithClassName('button', 'link-button'); 782 var navButton = createElementWithClassName('button', 'link-button');
742 navButton.textContent = name; 783 navButton.textContent = name;
743 navButton.onclick = function() { 784 navButton.onclick = function() {
744 setPage(page); 785 setPage(page);
745 }; 786 };
746 return navButton; 787 return navButton;
747 }; 788 };
748 789
(...skipping 26 matching lines...) Expand all
775 // var anchorMaxWith = titleElement.offsetWidth; 816 // var anchorMaxWith = titleElement.offsetWidth;
776 // this.entryAnchorRule_.style.maxWidth = anchorMaxWith + 'px'; 817 // this.entryAnchorRule_.style.maxWidth = anchorMaxWith + 'px';
777 // // Adjust by the width of star plus its margin. 818 // // Adjust by the width of star plus its margin.
778 // this.entryAnchorStarredRule_.style.maxWidth = anchorMaxWith - 23 + 'px'; 819 // this.entryAnchorStarredRule_.style.maxWidth = anchorMaxWith - 23 + 'px';
779 }; 820 };
780 821
781 /////////////////////////////////////////////////////////////////////////////// 822 ///////////////////////////////////////////////////////////////////////////////
782 // State object: 823 // State object:
783 /** 824 /**
784 * An 'AJAX-history' implementation. 825 * An 'AJAX-history' implementation.
785 * @param {HistoryModel} model The model we're representing 826 * @param {HistoryModel} model The model we're representing.
786 * @param {HistoryView} view The view we're representing 827 * @param {HistoryView} view The view we're representing.
828 * @constructor
787 */ 829 */
788 function PageState(model, view) { 830 function PageState(model, view) {
789 // Enforce a singleton. 831 // Enforce a singleton.
790 if (PageState.instance) { 832 if (PageState.instance) {
791 return PageState.instance; 833 return PageState.instance;
792 } 834 }
793 835
794 this.model = model; 836 this.model = model;
795 this.view = view; 837 this.view = view;
796 838
797 if (typeof this.checker_ != 'undefined' && this.checker_) { 839 if (typeof this.checker_ != 'undefined' && this.checker_) {
798 clearInterval(this.checker_); 840 clearInterval(this.checker_);
799 } 841 }
800 842
801 // TODO(glen): Replace this with a bound method so we don't need 843 // TODO(glen): Replace this with a bound method so we don't need
802 // public model and view. 844 // public model and view.
803 this.checker_ = setInterval((function(state_obj) { 845 this.checker_ = setInterval((function(state_obj) {
804 var hashData = state_obj.getHashData(); 846 var hashData = state_obj.getHashData();
805 if (hashData.q != state_obj.model.getSearchText()) { 847 if (hashData.q != state_obj.model.getSearchText()) {
806 state_obj.view.setSearch(hashData.q, parseInt(hashData.p, 10)); 848 state_obj.view.setSearch(hashData.q, parseInt(hashData.p, 10));
807 } else if (parseInt(hashData.p, 10) != state_obj.view.getPage()) { 849 } else if (parseInt(hashData.p, 10) != state_obj.view.getPage()) {
808 state_obj.view.setPage(hashData.p); 850 state_obj.view.setPage(hashData.p);
809 } 851 }
810 }), 50, this); 852 }), 50, this);
811 } 853 }
812 854
855 /**
856 * Holds the singleton instance.
857 */
813 PageState.instance = null; 858 PageState.instance = null;
814 859
815 /** 860 /**
816 * @return {Object} An object containing parameters from our window hash. 861 * @return {Object} An object containing parameters from our window hash.
817 */ 862 */
818 PageState.prototype.getHashData = function() { 863 PageState.prototype.getHashData = function() {
819 var result = { 864 var result = {
820 e : 0, 865 e: 0,
821 q : '', 866 q: '',
822 p : 0 867 p: 0
823 }; 868 };
824 869
825 if (!window.location.hash) { 870 if (!window.location.hash) {
826 return result; 871 return result;
827 } 872 }
828 873
829 var hashSplit = window.location.hash.substr(1).split('&'); 874 var hashSplit = window.location.hash.substr(1).split('&');
830 for (var i = 0; i < hashSplit.length; i++) { 875 for (var i = 0; i < hashSplit.length; i++) {
831 var pair = hashSplit[i].split('='); 876 var pair = hashSplit[i].split('=');
832 if (pair.length > 1) { 877 if (pair.length > 1) {
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
944 // Call the native function to remove history entries. 989 // Call the native function to remove history entries.
945 // First arg is a time in seconds (passed as String) identifying the day. 990 // First arg is a time in seconds (passed as String) identifying the day.
946 // Remaining args are URLs of history entries from that day to delete. 991 // Remaining args are URLs of history entries from that day to delete.
947 var timeInSeconds = Math.floor(deleteQueue[0].date.getTime() / 1000); 992 var timeInSeconds = Math.floor(deleteQueue[0].date.getTime() / 1000);
948 chrome.send('removeURLsOnOneDay', 993 chrome.send('removeURLsOnOneDay',
949 [String(timeInSeconds)].concat(deleteQueue[0].urls)); 994 [String(timeInSeconds)].concat(deleteQueue[0].urls));
950 } 995 }
951 } 996 }
952 997
953 /** 998 /**
954 * Open the clear browsing data dialog. 999 * Click handler for the 'Clear browsing data' dialog.
1000 * @param {Event} e The click event.
955 */ 1001 */
956 function openClearBrowsingData() { 1002 function openClearBrowsingData(e) {
957 chrome.send('clearBrowsingData', []); 1003 chrome.send('clearBrowsingData');
958 return false;
959 } 1004 }
960 1005
961 /** 1006 /**
962 * Queue a set of URLs from the same day for deletion. 1007 * Queue a set of URLs from the same day for deletion.
963 * @param {Date} date A date indicating the day the URLs were visited. 1008 * @param {Date} date A date indicating the day the URLs were visited.
964 * @param {Array} urls Array of URLs from the same day to be deleted. 1009 * @param {Array} urls Array of URLs from the same day to be deleted.
965 * @param {Function} opt_callback An optional callback to be executed when 1010 * @param {Function} opt_callback An optional callback to be executed when
966 * the deletion is complete. 1011 * the deletion is complete.
967 */ 1012 */
968 function queueURLsForDeletion(date, urls, opt_callback) { 1013 function queueURLsForDeletion(date, urls, opt_callback) {
969 deleteQueue.push({ 'date': date, 'urls': urls, 'callback': opt_callback }); 1014 deleteQueue.push({ 'date': date, 'urls': urls, 'callback': opt_callback });
970 } 1015 }
971 1016
972 function reloadHistory() { 1017 function reloadHistory() {
973 historyView.reload(); 1018 historyView.reload();
974 } 1019 }
975 1020
976 /** 1021 /**
977 * Collect IDs from checked checkboxes and send to Chrome for deletion. 1022 * Click handler for the 'Remove selected items' button.
1023 * Collect IDs from the checked checkboxes and send to Chrome for deletion.
978 */ 1024 */
979 function removeItems() { 1025 function removeItems() {
980 var checked = document.querySelectorAll( 1026 var checked = document.querySelectorAll(
981 'input[type=checkbox]:checked:not([disabled])'); 1027 'input[type=checkbox]:checked:not([disabled])');
982 var urls = []; 1028 var urls = [];
983 var disabledItems = []; 1029 var disabledItems = [];
984 var queue = []; 1030 var queue = [];
985 var date = new Date(); 1031 var date = new Date();
986 1032
987 for (var i = 0; i < checked.length; i++) { 1033 for (var i = 0; i < checked.length; i++) {
(...skipping 29 matching lines...) Expand all
1017 // If the remove is cancelled, return the checkboxes to their 1063 // If the remove is cancelled, return the checkboxes to their
1018 // enabled, non-line-through state. 1064 // enabled, non-line-through state.
1019 for (var i = 0; i < disabledItems.length; i++) { 1065 for (var i = 0; i < disabledItems.length; i++) {
1020 var checkbox = disabledItems[i]; 1066 var checkbox = disabledItems[i];
1021 var link = findAncestorWithClass( 1067 var link = findAncestorWithClass(
1022 checkbox, 'entry-box').querySelector('a'); 1068 checkbox, 'entry-box').querySelector('a');
1023 checkbox.disabled = false; 1069 checkbox.disabled = false;
1024 link.classList.remove('to-be-removed'); 1070 link.classList.remove('to-be-removed');
1025 } 1071 }
1026 } 1072 }
1027 return false;
1028 } 1073 }
1029 1074
1030 /** 1075 /**
1031 * Toggle state of checkbox and handle Shift modifier. 1076 * Handler for the 'click' event on a checkbox.
1077 * @param {Event} e The click event.
1032 */ 1078 */
1033 function checkboxClicked(event) { 1079 function checkboxClicked(e) {
1034 var id = Number(this.id.slice("checkbox-".length)); 1080 var checkbox = e.currentTarget;
1081 var id = Number(checkbox.id.slice('checkbox-'.length));
1082 // Handle multi-select if shift was pressed.
1035 if (event.shiftKey && (selectionAnchor != -1)) { 1083 if (event.shiftKey && (selectionAnchor != -1)) {
1036 var checked = this.checked; 1084 var checked = checkbox.checked;
1037 // Set all checkboxes from the anchor up to the clicked checkbox to the 1085 // Set all checkboxes from the anchor up to the clicked checkbox to the
1038 // state of the clicked one. 1086 // state of the clicked one.
1039 var begin = Math.min(id, selectionAnchor); 1087 var begin = Math.min(id, selectionAnchor);
1040 var end = Math.max(id, selectionAnchor); 1088 var end = Math.max(id, selectionAnchor);
1041 for (var i = begin; i <= end; i++) { 1089 for (var i = begin; i <= end; i++) {
1042 var checkbox = document.querySelector('#checkbox-' + i); 1090 var checkbox = document.querySelector('#checkbox-' + i);
1043 if (checkbox) 1091 if (checkbox)
1044 checkbox.checked = checked; 1092 checkbox.checked = checked;
1045 } 1093 }
1046 } 1094 }
(...skipping 14 matching lines...) Expand all
1061 1109
1062 // Delete the node when the animation is complete. 1110 // Delete the node when the animation is complete.
1063 node.addEventListener('webkitTransitionEnd', function() { 1111 node.addEventListener('webkitTransitionEnd', function() {
1064 node.parentNode.removeChild(node); 1112 node.parentNode.removeChild(node);
1065 }); 1113 });
1066 } 1114 }
1067 1115
1068 /** 1116 /**
1069 * Removes a single entry from the view. Also removes gaps before and after 1117 * Removes a single entry from the view. Also removes gaps before and after
1070 * entry if necessary. 1118 * entry if necessary.
1119 * @param {Node} entry The DOM node representing the entry to be removed.
1071 */ 1120 */
1072 function removeEntryFromView(entry) { 1121 function removeEntryFromView(entry) {
1073 var nextEntry = entry.nextSibling; 1122 var nextEntry = entry.nextSibling;
1074 var previousEntry = entry.previousSibling; 1123 var previousEntry = entry.previousSibling;
1075 1124
1076 removeNode(entry); 1125 removeNode(entry);
1077 1126
1078 // if there is no previous entry, and the next entry is a gap, remove it 1127 // if there is no previous entry, and the next entry is a gap, remove it
1079 if (!previousEntry && nextEntry && nextEntry.className == 'gap') { 1128 if (!previousEntry && nextEntry && nextEntry.className == 'gap') {
1080 removeNode(nextEntry); 1129 removeNode(nextEntry);
1081 } 1130 }
1082 1131
1083 // if there is no next entry, and the previous entry is a gap, remove it 1132 // if there is no next entry, and the previous entry is a gap, remove it
1084 if (!nextEntry && previousEntry && previousEntry.className == 'gap') { 1133 if (!nextEntry && previousEntry && previousEntry.className == 'gap') {
1085 removeNode(previousEntry); 1134 removeNode(previousEntry);
1086 } 1135 }
1087 1136
1088 // if both the next and previous entries are gaps, remove one 1137 // if both the next and previous entries are gaps, remove one
1089 if (nextEntry && nextEntry.className == 'gap' && 1138 if (nextEntry && nextEntry.className == 'gap' &&
1090 previousEntry && previousEntry.className == 'gap') { 1139 previousEntry && previousEntry.className == 'gap') {
1091 removeNode(nextEntry); 1140 removeNode(nextEntry);
1092 } 1141 }
1093 } 1142 }
1094 1143
1095 /////////////////////////////////////////////////////////////////////////////// 1144 ///////////////////////////////////////////////////////////////////////////////
1096 // Chrome callbacks: 1145 // Chrome callbacks:
1146
1097 /** 1147 /**
1098 * Our history system calls this function with results from searches. 1148 * Our history system calls this function with results from searches.
1149 * @param {Object} info An object containing information about the query.
1150 * @param {Array} results A list of results.
1099 */ 1151 */
1100 function historyResult(info, results) { 1152 function historyResult(info, results) {
1101 historyModel.addResults(info, results); 1153 historyModel.addResults(info, results);
1102 } 1154 }
1103 1155
1104 /** 1156 /**
1105 * Our history system calls this function when a deletion has finished. 1157 * Our history system calls this function when a deletion has finished.
1106 */ 1158 */
1107 function deleteComplete() { 1159 function deleteComplete() {
1108 if (deleteQueue.length > 0) { 1160 if (deleteQueue.length > 0) {
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
1140 historyView.reload(); 1192 historyView.reload();
1141 } 1193 }
1142 1194
1143 // Add handlers to HTML elements. 1195 // Add handlers to HTML elements.
1144 document.addEventListener('DOMContentLoaded', load); 1196 document.addEventListener('DOMContentLoaded', load);
1145 1197
1146 // This event lets us enable and disable menu items before the menu is shown. 1198 // This event lets us enable and disable menu items before the menu is shown.
1147 document.addEventListener('canExecute', function(e) { 1199 document.addEventListener('canExecute', function(e) {
1148 e.canExecute = true; 1200 e.canExecute = true;
1149 }); 1201 });
OLDNEW
« no previous file with comments | « no previous file | chrome/browser/resources/web_dev_style/js_checker.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698