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

Side by Side Diff: chrome/browser/resources/md_history/app.crisper.js

Issue 2334553002: [MD History] Add keyboard navigation to the main history list. (Closed)
Patch Set: address comments Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 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 function PromiseResolver() { 4 function PromiseResolver() {
5 this.resolve_; 5 this.resolve_;
6 this.reject_; 6 this.reject_;
7 this.promise_ = new Promise(function(resolve, reject) { 7 this.promise_ = new Promise(function(resolve, reject) {
8 this.resolve_ = resolve; 8 this.resolve_ = resolve;
9 this.reject_ = reject; 9 this.reject_ = reject;
10 }.bind(this)); 10 }.bind(this));
(...skipping 6598 matching lines...) Expand 10 before | Expand all | Expand 10 after
6609 for (var prop in rect) { 6609 for (var prop in rect) {
6610 if (rect[prop] !== 0) return true; 6610 if (rect[prop] !== 0) return true;
6611 } 6611 }
6612 return false; 6612 return false;
6613 }, 6613 },
6614 _calcSize: function() { 6614 _calcSize: function() {
6615 return this.getBoundingClientRect()[this.dimension] + 'px'; 6615 return this.getBoundingClientRect()[this.dimension] + 'px';
6616 } 6616 }
6617 }); 6617 });
6618 6618
6619 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
6620 // Use of this source code is governed by a BSD-style license that can be
6621 // found in the LICENSE file.
6622 var EventTrackerEntry;
6623
6624 function EventTracker() {
6625 this.listeners_ = [];
6626 }
6627
6628 EventTracker.prototype = {
6629 add: function(target, eventType, listener, opt_capture) {
6630 var capture = !!opt_capture;
6631 var h = {
6632 target: target,
6633 eventType: eventType,
6634 listener: listener,
6635 capture: capture
6636 };
6637 this.listeners_.push(h);
6638 target.addEventListener(eventType, listener, capture);
6639 },
6640 remove: function(target, eventType) {
6641 this.listeners_ = this.listeners_.filter(function(h) {
6642 if (h.target == target && (!eventType || h.eventType == eventType)) {
6643 EventTracker.removeEventListener_(h);
6644 return false;
6645 }
6646 return true;
6647 });
6648 },
6649 removeAll: function() {
6650 this.listeners_.forEach(EventTracker.removeEventListener_);
6651 this.listeners_ = [];
6652 }
6653 };
6654
6655 EventTracker.removeEventListener_ = function(h) {
6656 h.target.removeEventListener(h.eventType, h.listener, h.capture);
6657 };
6658
6659 // Copyright 2014 The Chromium Authors. All rights reserved.
6660 // Use of this source code is governed by a BSD-style license that can be
6661 // found in the LICENSE file.
6662 cr.define('cr.ui', function() {
6663 function FocusRow(root, boundary, opt_delegate) {
6664 this.root = root;
6665 this.boundary_ = boundary || document.documentElement;
6666 this.delegate = opt_delegate;
6667 this.eventTracker = new EventTracker();
6668 }
6669 FocusRow.Delegate = function() {};
6670 FocusRow.Delegate.prototype = {
6671 onKeydown: assertNotReached,
6672 onFocus: assertNotReached
6673 };
6674 FocusRow.ACTIVE_CLASS = 'focus-row-active';
6675 FocusRow.isFocusable = function(element) {
6676 if (!element || element.disabled) return false;
6677 function isVisible(element) {
6678 assertInstanceof(element, Element);
6679 var style = window.getComputedStyle(element);
6680 if (style.visibility == 'hidden' || style.display == 'none') return false;
6681 var parent = element.parentNode;
6682 if (!parent) return false;
6683 if (parent == element.ownerDocument || parent instanceof DocumentFragment) return true;
6684 return isVisible(parent);
6685 }
6686 return isVisible(element);
6687 };
6688 FocusRow.prototype = {
6689 addItem: function(type, query) {
6690 assert(type);
6691 var element = this.root.querySelector(query);
6692 if (!element) return false;
6693 element.setAttribute('focus-type', type);
6694 element.tabIndex = this.isActive() ? 0 : -1;
6695 this.eventTracker.add(element, 'blur', this.onBlur_.bind(this));
6696 this.eventTracker.add(element, 'focus', this.onFocus_.bind(this));
6697 this.eventTracker.add(element, 'keydown', this.onKeydown_.bind(this));
6698 this.eventTracker.add(element, 'mousedown', this.onMousedown_.bind(this));
6699 return true;
6700 },
6701 destroy: function() {
6702 this.eventTracker.removeAll();
6703 },
6704 getCustomEquivalent: function(sampleElement) {
6705 return assert(this.getFirstFocusable());
6706 },
6707 getElements: function() {
6708 var elements = this.root.querySelectorAll('[focus-type]');
6709 return Array.prototype.slice.call(elements);
6710 },
6711 getEquivalentElement: function(sampleElement) {
6712 if (this.getFocusableElements().indexOf(sampleElement) >= 0) return sample Element;
6713 var sampleFocusType = this.getTypeForElement(sampleElement);
6714 if (sampleFocusType) {
6715 var sameType = this.getFirstFocusable(sampleFocusType);
6716 if (sameType) return sameType;
6717 }
6718 return this.getCustomEquivalent(sampleElement);
6719 },
6720 getFirstFocusable: function(opt_type) {
6721 var filter = opt_type ? '="' + opt_type + '"' : '';
6722 var elements = this.root.querySelectorAll('[focus-type' + filter + ']');
6723 for (var i = 0; i < elements.length; ++i) {
6724 if (cr.ui.FocusRow.isFocusable(elements[i])) return elements[i];
6725 }
6726 return null;
6727 },
6728 getFocusableElements: function() {
6729 return this.getElements().filter(cr.ui.FocusRow.isFocusable);
6730 },
6731 getTypeForElement: function(element) {
6732 return element.getAttribute('focus-type') || '';
6733 },
6734 isActive: function() {
6735 return this.root.classList.contains(FocusRow.ACTIVE_CLASS);
6736 },
6737 makeActive: function(active) {
6738 if (active == this.isActive()) return;
6739 this.getElements().forEach(function(element) {
6740 element.tabIndex = active ? 0 : -1;
6741 });
6742 this.root.classList.toggle(FocusRow.ACTIVE_CLASS, active);
6743 },
6744 onBlur_: function(e) {
6745 if (!this.boundary_.contains(e.relatedTarget)) return;
6746 var currentTarget = e.currentTarget;
6747 if (this.getFocusableElements().indexOf(currentTarget) >= 0) this.makeActi ve(false);
6748 },
6749 onFocus_: function(e) {
6750 if (this.delegate) this.delegate.onFocus(this, e);
6751 },
6752 onMousedown_: function(e) {
6753 if (e.button) return;
6754 if (!e.currentTarget.disabled) e.currentTarget.tabIndex = 0;
6755 },
6756 onKeydown_: function(e) {
6757 var elements = this.getFocusableElements();
6758 var currentElement = e.currentTarget;
6759 var elementIndex = elements.indexOf(currentElement);
6760 assert(elementIndex >= 0);
6761 if (this.delegate && this.delegate.onKeydown(this, e)) return;
6762 if (e.altKey || e.ctrlKey || e.metaKey || e.shiftKey) return;
6763 var index = -1;
6764 if (e.key == 'ArrowLeft') index = elementIndex + (isRTL() ? 1 : -1); else if (e.key == 'ArrowRight') index = elementIndex + (isRTL() ? -1 : 1); else if (e .key == 'Home') index = 0; else if (e.key == 'End') index = elements.length - 1;
6765 var elementToFocus = elements[index];
6766 if (elementToFocus) {
6767 this.getEquivalentElement(elementToFocus).focus();
6768 e.preventDefault();
6769 }
6770 }
6771 };
6772 return {
6773 FocusRow: FocusRow
6774 };
6775 });
6776
6619 // Copyright 2016 The Chromium Authors. All rights reserved. 6777 // Copyright 2016 The Chromium Authors. All rights reserved.
6620 // Use of this source code is governed by a BSD-style license that can be 6778 // Use of this source code is governed by a BSD-style license that can be
6621 // found in the LICENSE file. 6779 // found in the LICENSE file.
6622 cr.define('cr.icon', function() { 6780 cr.define('cr.icon', function() {
6623 function getSupportedScaleFactors() { 6781 function getSupportedScaleFactors() {
6624 var supportedScaleFactors = []; 6782 var supportedScaleFactors = [];
6625 if (!cr.isIOS) { 6783 if (!cr.isIOS) {
6626 supportedScaleFactors.push(1); 6784 supportedScaleFactors.push(1);
6627 } 6785 }
6628 if (cr.isMac || cr.isChromeOS || cr.isWindows || cr.isLinux) { 6786 if (cr.isMac || cr.isChromeOS || cr.isWindows || cr.isLinux) {
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
6689 b.textContent = titleText.substring(match.index, i); 6847 b.textContent = titleText.substring(match.index, i);
6690 this.appendChild(b); 6848 this.appendChild(b);
6691 } 6849 }
6692 if (i < titleText.length) this.appendChild(document.createTextNode(titleText .slice(i))); 6850 if (i < titleText.length) this.appendChild(document.createTextNode(titleText .slice(i)));
6693 } 6851 }
6694 }); 6852 });
6695 6853
6696 // Copyright 2015 The Chromium Authors. All rights reserved. 6854 // Copyright 2015 The Chromium Authors. All rights reserved.
6697 // Use of this source code is governed by a BSD-style license that can be 6855 // Use of this source code is governed by a BSD-style license that can be
6698 // found in the LICENSE file. 6856 // found in the LICENSE file.
6857 function HistoryFocusRow(root, boundary, delegate) {
6858 cr.ui.FocusRow.call(this, root, boundary, delegate);
6859 this.addItems();
6860 }
6861
6862 HistoryFocusRow.prototype = {
6863 __proto__: cr.ui.FocusRow.prototype,
6864 getCustomEquivalent: function(sampleElement) {
6865 var equivalent;
6866 if (this.getTypeForElement(sampleElement) == 'star') equivalent = this.getFi rstFocusable('title');
6867 return equivalent || cr.ui.FocusRow.prototype.getCustomEquivalent.call(this, sampleElement);
6868 },
6869 addItems: function() {
6870 this.destroy();
6871 assert(this.addItem('checkbox', '#checkbox'));
6872 assert(this.addItem('title', '#title'));
6873 assert(this.addItem('menu-button', '#menu-button'));
6874 this.addItem('star', '#bookmark-star');
6875 }
6876 };
6877
6699 cr.define('md_history', function() { 6878 cr.define('md_history', function() {
6879 function FocusRowDelegate(historyItemElement) {
6880 this.historyItemElement = historyItemElement;
6881 }
6882 FocusRowDelegate.prototype = {
6883 onFocus: function(row, e) {
6884 this.historyItemElement.lastFocused = e.path[0];
6885 },
6886 onKeydown: function(row, e) {
6887 if (e.key == 'Enter') e.stopPropagation();
6888 return false;
6889 }
6890 };
6700 var HistoryItem = Polymer({ 6891 var HistoryItem = Polymer({
6701 is: 'history-item', 6892 is: 'history-item',
6702 properties: { 6893 properties: {
6703 item: { 6894 item: {
6704 type: Object, 6895 type: Object,
6705 observer: 'showIcon_' 6896 observer: 'showIcon_'
6706 }, 6897 },
6707 searchTerm: { 6898 searchTerm: {
6708 type: String 6899 type: String
6709 }, 6900 },
(...skipping 17 matching lines...) Expand all
6727 type: Boolean, 6918 type: Boolean,
6728 reflectToAttribute: true 6919 reflectToAttribute: true
6729 }, 6920 },
6730 hasTimeGap: { 6921 hasTimeGap: {
6731 type: Boolean 6922 type: Boolean
6732 }, 6923 },
6733 numberOfItems: { 6924 numberOfItems: {
6734 type: Number 6925 type: Number
6735 }, 6926 },
6736 path: String, 6927 path: String,
6737 index: Number 6928 index: Number,
6929 lastFocused: {
6930 type: Object,
6931 notify: true
6932 },
6933 tabIndex: {
6934 type: Number,
6935 observer: 'tabIndexChanged_'
6936 }
6937 },
6938 row_: null,
6939 attached: function() {
6940 Polymer.RenderStatus.afterNextRender(this, function() {
6941 this.row_ = new HistoryFocusRow(this.$['sizing-container'], null, new Fo cusRowDelegate(this));
6942 this.row_.makeActive(this.tabIndex == 0);
6943 this.listen(this, 'focus', 'onFocus_');
6944 this.listen(this, 'dom-change', 'onDomChange_');
6945 });
6946 },
6947 detached: function() {
6948 this.unlisten(this, 'focus', 'onFocus_');
6949 this.unlisten(this, 'dom-change', 'onDomChange_');
6950 this.row_.destroy();
6951 },
6952 onFocus_: function() {
6953 if (this.lastFocused) this.row_.getEquivalentElement(this.lastFocused).foc us(); else this.row_.getFirstFocusable().focus();
6954 },
6955 tabIndexChanged_: function() {
6956 if (this.row_) this.row_.makeActive(this.tabIndex == 0);
6957 },
6958 onDomChange_: function() {
6959 if (this.row_) this.row_.addItems();
6738 }, 6960 },
6739 onCheckboxSelected_: function(e) { 6961 onCheckboxSelected_: function(e) {
6740 this.fire('history-checkbox-select', { 6962 this.fire('history-checkbox-select', {
6741 element: this, 6963 element: this,
6742 shiftKey: e.shiftKey 6964 shiftKey: e.shiftKey
6743 }); 6965 });
6744 e.preventDefault(); 6966 e.preventDefault();
6745 }, 6967 },
6746 onCheckboxMousedown_: function(e) { 6968 onCheckboxMousedown_: function(e) {
6747 if (e.shiftKey) e.preventDefault(); 6969 if (e.shiftKey) e.preventDefault();
(...skipping 1252 matching lines...) Expand 10 before | Expand all | Expand 10 after
8000 properties: { 8222 properties: {
8001 searchedTerm: { 8223 searchedTerm: {
8002 type: String, 8224 type: String,
8003 value: '' 8225 value: ''
8004 }, 8226 },
8005 querying: Boolean, 8227 querying: Boolean,
8006 historyData_: Array, 8228 historyData_: Array,
8007 resultLoadingDisabled_: { 8229 resultLoadingDisabled_: {
8008 type: Boolean, 8230 type: Boolean,
8009 value: false 8231 value: false
8010 } 8232 },
8233 lastFocused_: Object
8011 }, 8234 },
8012 listeners: { 8235 listeners: {
8013 scroll: 'notifyListScroll_', 8236 scroll: 'notifyListScroll_',
8014 'remove-bookmark-stars': 'removeBookmarkStars_' 8237 'remove-bookmark-stars': 'removeBookmarkStars_'
8015 }, 8238 },
8016 attached: function() { 8239 attached: function() {
8017 this.$['infinite-list'].notifyResize(); 8240 this.$['infinite-list'].notifyResize();
8018 this.$['infinite-list'].scrollTarget = this; 8241 this.$['infinite-list'].scrollTarget = this;
8019 this.$['scroll-threshold'].scrollTarget = this; 8242 this.$['scroll-threshold'].scrollTarget = this;
8020 }, 8243 },
(...skipping 676 matching lines...) Expand 10 before | Expand all | Expand 10 after
8697 8920
8698 case HistoryRange.MONTH: 8921 case HistoryRange.MONTH:
8699 histogramValue = HistoryPageViewHistogram.GROUPED_MONTH; 8922 histogramValue = HistoryPageViewHistogram.GROUPED_MONTH;
8700 break; 8923 break;
8701 } 8924 }
8702 break; 8925 break;
8703 } 8926 }
8704 md_history.BrowserService.getInstance().recordHistogram('History.HistoryPage View', histogramValue, HistoryPageViewHistogram.END); 8927 md_history.BrowserService.getInstance().recordHistogram('History.HistoryPage View', histogramValue, HistoryPageViewHistogram.END);
8705 } 8928 }
8706 }); 8929 });
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698