OLD | NEW |
---|---|
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 <include src="history_focus_manager.js"> | 6 <include src="history_focus_manager.js"> |
7 | 7 |
8 /////////////////////////////////////////////////////////////////////////////// | 8 /////////////////////////////////////////////////////////////////////////////// |
9 // Globals: | 9 // Globals: |
10 /** @const */ var RESULTS_PER_PAGE = 150; | 10 /** @const */ var RESULTS_PER_PAGE = 150; |
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
180 var menu = $('action-menu'); | 180 var menu = $('action-menu'); |
181 menu.dataset.devicename = self.deviceName; | 181 menu.dataset.devicename = self.deviceName; |
182 menu.dataset.devicetype = self.deviceType; | 182 menu.dataset.devicetype = self.deviceType; |
183 }; | 183 }; |
184 domain.textContent = this.domain_; | 184 domain.textContent = this.domain_; |
185 | 185 |
186 entryBox.appendChild(time); | 186 entryBox.appendChild(time); |
187 | 187 |
188 var bookmarkSection = createElementWithClassName('div', 'bookmark-section'); | 188 var bookmarkSection = createElementWithClassName('div', 'bookmark-section'); |
189 if (this.starred_) { | 189 if (this.starred_) { |
190 bookmarkSection.title = loadTimeData.getString('removeBookmark'); | |
190 bookmarkSection.classList.add('starred'); | 191 bookmarkSection.classList.add('starred'); |
191 bookmarkSection.addEventListener('click', function f(e) { | 192 bookmarkSection.addEventListener('click', function f(e) { |
192 recordUmaAction('HistoryPage_BookmarkStarClicked'); | 193 recordUmaAction('HistoryPage_BookmarkStarClicked'); |
193 bookmarkSection.classList.remove('starred'); | 194 bookmarkSection.classList.remove('starred'); |
194 chrome.send('removeBookmark', [self.url_]); | 195 chrome.send('removeBookmark', [self.url_]); |
195 bookmarkSection.removeEventListener('click', f); | 196 bookmarkSection.removeEventListener('click', f); |
196 e.preventDefault(); | 197 e.preventDefault(); |
197 }); | 198 }); |
198 } | 199 } |
199 entryBox.appendChild(bookmarkSection); | 200 entryBox.appendChild(bookmarkSection); |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
284 }.bind(this)); | 285 }.bind(this)); |
285 }; | 286 }; |
286 | 287 |
287 /** | 288 /** |
288 * @param {boolean} isLead Whether this visit is the "lead" visit, i.e. the one | 289 * @param {boolean} isLead Whether this visit is the "lead" visit, i.e. the one |
289 * that would be focused if the entry list is tabbed to. | 290 * that would be focused if the entry list is tabbed to. |
290 */ | 291 */ |
291 Visit.prototype.setIsLead = function(isLead) { | 292 Visit.prototype.setIsLead = function(isLead) { |
292 this.domNode_.querySelector('.entry-box').classList.toggle('lead', isLead); | 293 this.domNode_.querySelector('.entry-box').classList.toggle('lead', isLead); |
293 if (!isLead) { | 294 if (!isLead) { |
294 if (this.checkBox) | 295 this.getFocusableControls_().forEach(function(control) { |
295 this.checkBox.tabIndex = -1; | 296 control.tabIndex = -1; |
296 | 297 }); |
297 this.titleLink.tabIndex = -1; | |
298 | |
299 if (this.dropDown) | |
300 this.dropDown.tabIndex = -1; | |
301 } | 298 } |
302 }; | 299 }; |
303 | 300 |
304 /** | 301 /** |
305 * @param {Element} control A control element to focus. | 302 * @param {Element} control A control element to focus. |
306 */ | 303 */ |
307 Visit.prototype.focusControl = function(control) { | 304 Visit.prototype.focusControl = function(control) { |
308 var controls = [this.titleLink]; | 305 var controls = this.getFocusableControls_(); |
309 | |
310 if (this.checkBox) | |
311 controls.push(this.checkBox); | |
312 | |
313 if (this.dropDown) | |
314 controls.push(this.dropDown); | |
315 | |
316 assert(controls.indexOf(control) >= 0); | 306 assert(controls.indexOf(control) >= 0); |
317 | 307 |
318 for (var i = 0; i < controls.length; ++i) { | 308 for (var i = 0; i < controls.length; ++i) { |
319 controls[i].tabIndex = controls[i] == control ? 0 : -1; | 309 controls[i].tabIndex = controls[i] == control ? 0 : -1; |
320 } | 310 } |
321 | 311 |
322 control.focus(); | 312 control.focus(); |
323 this.setIsLead(true); | 313 this.setIsLead(true); |
324 }; | 314 }; |
325 | 315 |
326 Object.defineProperty(Visit.prototype, 'checkBox', { | 316 Object.defineProperty(Visit.prototype, 'checkBox', { |
327 get: function() { | 317 get: function() { |
328 return this.domNode_.querySelector('input[type=checkbox]'); | 318 return this.domNode_.querySelector('input[type=checkbox]'); |
329 }, | 319 }, |
330 }); | 320 }); |
331 | 321 |
322 Object.defineProperty(Visit.prototype, 'bookmarkStar', { | |
323 get: function() { | |
324 return this.domNode_.querySelector('.bookmark-section.starred'); | |
325 }, | |
326 }); | |
327 | |
332 Object.defineProperty(Visit.prototype, 'titleLink', { | 328 Object.defineProperty(Visit.prototype, 'titleLink', { |
333 get: function() { | 329 get: function() { |
334 return this.domNode_.querySelector('.title a'); | 330 return this.domNode_.querySelector('.title a'); |
335 }, | 331 }, |
336 }); | 332 }); |
337 | 333 |
338 Object.defineProperty(Visit.prototype, 'dropDown', { | 334 Object.defineProperty(Visit.prototype, 'dropDown', { |
339 get: function() { | 335 get: function() { |
340 return this.domNode_.querySelector('button.drop-down'); | 336 return this.domNode_.querySelector('button.drop-down'); |
341 }, | 337 }, |
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
452 * Launch a search for more history entries from the same domain. | 448 * Launch a search for more history entries from the same domain. |
453 * @private | 449 * @private |
454 */ | 450 */ |
455 Visit.prototype.showMoreFromSite_ = function() { | 451 Visit.prototype.showMoreFromSite_ = function() { |
456 recordUmaAction('HistoryPage_EntryMenuShowMoreFromSite'); | 452 recordUmaAction('HistoryPage_EntryMenuShowMoreFromSite'); |
457 historyView.setSearch(this.domain_); | 453 historyView.setSearch(this.domain_); |
458 $('search-field').focus(); | 454 $('search-field').focus(); |
459 }; | 455 }; |
460 | 456 |
461 /** | 457 /** |
458 * @return {Array.<Element>} A list of focusable controls. | |
459 * @private | |
460 */ | |
461 Visit.prototype.getFocusableControls_ = function() { | |
462 var controls = []; | |
463 | |
464 if (this.checkBox) | |
465 controls.push(this.checkBox); | |
466 | |
467 if (this.bookmarkStar) | |
468 controls.push(this.bookmarkStar); | |
469 | |
470 controls.push(this.titleLink); | |
471 | |
472 if (this.dropDown) | |
473 controls.push(this.dropDown); | |
474 | |
475 return controls; | |
476 }; | |
477 | |
478 /** | |
462 * @param {Event} e A keydown event to handle. | 479 * @param {Event} e A keydown event to handle. |
463 * @private | 480 * @private |
464 */ | 481 */ |
465 Visit.prototype.handleKeydown_ = function(e) { | 482 Visit.prototype.handleKeydown_ = function(e) { |
466 var keyCode = e.keyCode; | 483 var keyCode = e.keyCode; |
467 if (keyCode == 8 || keyCode == 46) { // Delete or Backspace. | 484 if (keyCode == 8 || keyCode == 46) { // Delete or Backspace. |
468 if (!this.model_.isDeletingVisits()) | 485 if (!this.model_.isDeletingVisits()) |
469 this.removeEntryFromHistory_(e); | 486 this.removeEntryFromHistory_(e); |
470 return; | 487 return; |
471 } | 488 } |
472 | 489 |
473 var target = e.target; | 490 var target = e.target; |
474 if (target != document.activeElement || | 491 if (target != document.activeElement || !(keyCode == 37 || keyCode == 39)) { |
475 !(keyCode == 37 || keyCode == 39) || // Left or right. | 492 // Handling key code for inactive element or key wasn't left or right. |
476 (keyCode == 37 && target == this.checkBox) || | |
477 (keyCode == 39 && target == this.dropDown)) { | |
478 return; | 493 return; |
479 } | 494 } |
480 | 495 |
481 var toFocus; | 496 var controls = this.getFocusableControls_(); |
482 if (e.keyCode == 37) // Left. | 497 for (var i = 0; i < controls.length; ++i) { |
483 toFocus = target == this.dropDown ? this.titleLink : this.checkBox; | 498 if (controls[i].contains(target)) { |
484 else // Right. | 499 var toFocus = e.keyCode == 37 ? controls[i - 1] : controls[i + 1]; |
dmazzoni
2014/07/22 16:59:16
Add back a comment for 37 == "left" or use a const
Dan Beam
2014/07/22 18:10:06
Done.
| |
485 toFocus = target == this.checkBox ? this.titleLink : this.dropDown; | 500 if (toFocus) { |
486 | 501 this.focusControl(toFocus); |
487 this.focusControl(toFocus); | 502 e.preventDefault(); |
488 e.preventDefault(); | 503 } |
504 break; | |
505 } | |
506 } | |
489 }; | 507 }; |
490 | 508 |
491 /** | 509 /** |
492 * Removes a history entry on click or keydown and finds a new entry to focus. | 510 * Removes a history entry on click or keydown and finds a new entry to focus. |
493 * @param {Event} e A click or keydown event. | 511 * @param {Event} e A click or keydown event. |
494 * @private | 512 * @private |
495 */ | 513 */ |
496 Visit.prototype.removeEntryFromHistory_ = function(e) { | 514 Visit.prototype.removeEntryFromHistory_ = function(e) { |
497 this.model_.getView().onBeforeRemove(this); | 515 this.model_.getView().onBeforeRemove(this); |
498 this.removeFromHistory(); | 516 this.removeFromHistory(); |
(...skipping 1121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1620 | 1638 |
1621 /** | 1639 /** |
1622 * Swaps focus to |toBeFocused|. Assumes the another visit is currently focused. | 1640 * Swaps focus to |toBeFocused|. Assumes the another visit is currently focused. |
1623 * @param {Visit} visit A visit to focus. | 1641 * @param {Visit} visit A visit to focus. |
1624 * @private | 1642 * @private |
1625 */ | 1643 */ |
1626 HistoryView.prototype.swapFocusedVisit_ = function(visit) { | 1644 HistoryView.prototype.swapFocusedVisit_ = function(visit) { |
1627 if (!visit) | 1645 if (!visit) |
1628 return; | 1646 return; |
1629 | 1647 |
1630 var control; | |
1631 var activeVisit = findAncestorByClass(document.activeElement, 'entry').visit; | 1648 var activeVisit = findAncestorByClass(document.activeElement, 'entry').visit; |
1632 if (document.activeElement == activeVisit.checkBox) | 1649 var controls = activeVisit.getFocusableControls_(); |
1633 control = visit.checkBox; | |
1634 else if (document.activeElement == activeVisit.titleLink) | |
1635 control = visit.titleLink; | |
1636 else if (document.activeElement == activeVisit.dropDown) | |
1637 control = visit.dropDown; | |
1638 | 1650 |
1639 visit.focusControl(control); | 1651 for (var i = 0; i < controls.length; ++i) { |
1652 var control = controls[i]; | |
1653 if (!control.contains(document.activeElement)) | |
1654 continue; | |
1655 | |
1656 // Try to focus the same type of control if the new visit has it. | |
1657 if (control == activeVisit.checkBox && visit.checkBox) { | |
1658 visit.focusControl(visit.checkBox); | |
1659 } else if (control == activeVisit.bookmarkStar && visit.bookmarkStar) { | |
1660 visit.focusControl(visit.bookmarkStar); | |
1661 } else if (control == activeVisit.titleLink) { | |
1662 visit.focusControl(visit.titleLink); | |
1663 } else if (control == activeVisit.dropDown && visit.dropDown) { | |
1664 visit.focusControl(visit.dropDown); | |
1665 } else { | |
1666 // Otherwise, just focus something that might be in a similar column. | |
1667 var controlsToFocus = visit.getFocusableControls_(); | |
1668 var indexToFocus = Math.min(i, controlsToFocus.length - 1); | |
1669 visit.focusControl(controlsToFocus[indexToFocus]); | |
1670 } | |
1671 break; | |
1672 } | |
1673 | |
1640 activeVisit.setIsLead(false); | 1674 activeVisit.setIsLead(false); |
1641 }; | 1675 }; |
1642 | 1676 |
1643 /** | 1677 /** |
1644 * @param {Event} e A keydown event to handle. | 1678 * @param {Event} e A keydown event to handle. |
1645 * @private | 1679 * @private |
1646 */ | 1680 */ |
1647 HistoryView.prototype.handleKeydown_ = function(e) { | 1681 HistoryView.prototype.handleKeydown_ = function(e) { |
1648 // Only handle up or down arrows on the focused element. | 1682 // Only handle up or down arrows on the focused element. |
1649 var keyCode = e.keyCode, target = e.target; | 1683 var keyCode = e.keyCode, target = e.target; |
(...skipping 10 matching lines...) Expand all Loading... | |
1660 * @param {Event} e A mousedown event to handle. | 1694 * @param {Event} e A mousedown event to handle. |
1661 * @private | 1695 * @private |
1662 */ | 1696 */ |
1663 HistoryView.prototype.handleMousedown_ = function(e) { | 1697 HistoryView.prototype.handleMousedown_ = function(e) { |
1664 var target = e.target; | 1698 var target = e.target; |
1665 var entry = findAncestorByClass(target, 'entry'); | 1699 var entry = findAncestorByClass(target, 'entry'); |
1666 if (!entry || !entry.contains(target)) | 1700 if (!entry || !entry.contains(target)) |
1667 return; | 1701 return; |
1668 | 1702 |
1669 var visit = entry.visit; | 1703 var visit = entry.visit; |
1704 if (visit.bookmarkStar && visit.bookmarkStar.contains(target)) | |
1705 return; | |
1706 | |
1670 if (visit.titleLink.contains(target)) | 1707 if (visit.titleLink.contains(target)) |
1671 visit.focusControl(visit.titleLink); | 1708 visit.focusControl(visit.titleLink); |
1672 else if (visit.dropDown && visit.dropDown.contains(target)) | 1709 else if (visit.dropDown && visit.dropDown.contains(target)) |
1673 visit.focusControl(visit.dropDown); | 1710 visit.focusControl(visit.dropDown); |
1674 else // Focus the checkbox by default. If no checkbox, focus the title. | 1711 else // Focus the checkbox by default. If no checkbox, focus the title. |
1675 visit.focusControl(visit.checkBox || visit.titleLink); | 1712 visit.focusControl(visit.checkBox || visit.titleLink); |
1676 | 1713 |
1677 e.preventDefault(); | 1714 e.preventDefault(); |
1678 }; | 1715 }; |
1679 | 1716 |
(...skipping 610 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2290 historyView.reload(); | 2327 historyView.reload(); |
2291 } | 2328 } |
2292 | 2329 |
2293 // Add handlers to HTML elements. | 2330 // Add handlers to HTML elements. |
2294 document.addEventListener('DOMContentLoaded', load); | 2331 document.addEventListener('DOMContentLoaded', load); |
2295 | 2332 |
2296 // This event lets us enable and disable menu items before the menu is shown. | 2333 // This event lets us enable and disable menu items before the menu is shown. |
2297 document.addEventListener('canExecute', function(e) { | 2334 document.addEventListener('canExecute', function(e) { |
2298 e.canExecute = true; | 2335 e.canExecute = true; |
2299 }); | 2336 }); |
OLD | NEW |