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

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

Issue 2272553002: MD WebUI: Use arrow keys for navigation in cr-shared-menu, close on tab (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Expand tests Created 4 years, 2 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 Polymer({ 1 Polymer({
2 is: 'iron-collapse', 2 is: 'iron-collapse',
3 behaviors: [ Polymer.IronResizableBehavior ], 3 behaviors: [ Polymer.IronResizableBehavior ],
4 properties: { 4 properties: {
5 horizontal: { 5 horizontal: {
6 type: Boolean, 6 type: Boolean,
7 value: false, 7 value: false,
8 observer: '_horizontalChanged' 8 observer: '_horizontalChanged'
9 }, 9 },
10 opened: { 10 opened: {
(...skipping 1796 matching lines...) Expand 10 before | Expand all | Expand 10 after
1807 var node = config.node; 1807 var node = config.node;
1808 this._effect = new KeyframeEffect(node, [ { 1808 this._effect = new KeyframeEffect(node, [ {
1809 opacity: '1' 1809 opacity: '1'
1810 }, { 1810 }, {
1811 opacity: '0' 1811 opacity: '0'
1812 } ], this.timingFromConfig(config)); 1812 } ], this.timingFromConfig(config));
1813 return this._effect; 1813 return this._effect;
1814 } 1814 }
1815 }); 1815 });
1816 1816
1817 Polymer.IronMenuBehaviorImpl = {
1818 properties: {
1819 focusedItem: {
1820 observer: '_focusedItemChanged',
1821 readOnly: true,
1822 type: Object
1823 },
1824 attrForItemTitle: {
1825 type: String
1826 }
1827 },
1828 hostAttributes: {
1829 role: 'menu',
1830 tabindex: '0'
1831 },
1832 observers: [ '_updateMultiselectable(multi)' ],
1833 listeners: {
1834 focus: '_onFocus',
1835 keydown: '_onKeydown',
1836 'iron-items-changed': '_onIronItemsChanged'
1837 },
1838 keyBindings: {
1839 up: '_onUpKey',
1840 down: '_onDownKey',
1841 esc: '_onEscKey',
1842 'shift+tab:keydown': '_onShiftTabDown'
1843 },
1844 attached: function() {
1845 this._resetTabindices();
1846 },
1847 select: function(value) {
1848 if (this._defaultFocusAsync) {
1849 this.cancelAsync(this._defaultFocusAsync);
1850 this._defaultFocusAsync = null;
1851 }
1852 var item = this._valueToItem(value);
1853 if (item && item.hasAttribute('disabled')) return;
1854 this._setFocusedItem(item);
1855 Polymer.IronMultiSelectableBehaviorImpl.select.apply(this, arguments);
1856 },
1857 _resetTabindices: function() {
1858 var selectedItem = this.multi ? this.selectedItems && this.selectedItems[0] : this.selectedItem;
1859 this.items.forEach(function(item) {
1860 item.setAttribute('tabindex', item === selectedItem ? '0' : '-1');
1861 }, this);
1862 },
1863 _updateMultiselectable: function(multi) {
1864 if (multi) {
1865 this.setAttribute('aria-multiselectable', 'true');
1866 } else {
1867 this.removeAttribute('aria-multiselectable');
1868 }
1869 },
1870 _focusWithKeyboardEvent: function(event) {
1871 for (var i = 0, item; item = this.items[i]; i++) {
1872 var attr = this.attrForItemTitle || 'textContent';
1873 var title = item[attr] || item.getAttribute(attr);
1874 if (!item.hasAttribute('disabled') && title && title.trim().charAt(0).toLo werCase() === String.fromCharCode(event.keyCode).toLowerCase()) {
1875 this._setFocusedItem(item);
1876 break;
1877 }
1878 }
1879 },
1880 _focusPrevious: function() {
1881 var length = this.items.length;
1882 var curFocusIndex = Number(this.indexOf(this.focusedItem));
1883 for (var i = 1; i < length + 1; i++) {
1884 var item = this.items[(curFocusIndex - i + length) % length];
1885 if (!item.hasAttribute('disabled')) {
1886 var owner = Polymer.dom(item).getOwnerRoot() || document;
1887 this._setFocusedItem(item);
1888 if (Polymer.dom(owner).activeElement == item) {
1889 return;
1890 }
1891 }
1892 }
1893 },
1894 _focusNext: function() {
1895 var length = this.items.length;
1896 var curFocusIndex = Number(this.indexOf(this.focusedItem));
1897 for (var i = 1; i < length + 1; i++) {
1898 var item = this.items[(curFocusIndex + i) % length];
1899 if (!item.hasAttribute('disabled')) {
1900 var owner = Polymer.dom(item).getOwnerRoot() || document;
1901 this._setFocusedItem(item);
1902 if (Polymer.dom(owner).activeElement == item) {
1903 return;
1904 }
1905 }
1906 }
1907 },
1908 _applySelection: function(item, isSelected) {
1909 if (isSelected) {
1910 item.setAttribute('aria-selected', 'true');
1911 } else {
1912 item.removeAttribute('aria-selected');
1913 }
1914 Polymer.IronSelectableBehavior._applySelection.apply(this, arguments);
1915 },
1916 _focusedItemChanged: function(focusedItem, old) {
1917 old && old.setAttribute('tabindex', '-1');
1918 if (focusedItem) {
1919 focusedItem.setAttribute('tabindex', '0');
1920 focusedItem.focus();
1921 }
1922 },
1923 _onIronItemsChanged: function(event) {
1924 if (event.detail.addedNodes.length) {
1925 this._resetTabindices();
1926 }
1927 },
1928 _onShiftTabDown: function(event) {
1929 var oldTabIndex = this.getAttribute('tabindex');
1930 Polymer.IronMenuBehaviorImpl._shiftTabPressed = true;
1931 this._setFocusedItem(null);
1932 this.setAttribute('tabindex', '-1');
1933 this.async(function() {
1934 this.setAttribute('tabindex', oldTabIndex);
1935 Polymer.IronMenuBehaviorImpl._shiftTabPressed = false;
1936 }, 1);
1937 },
1938 _onFocus: function(event) {
1939 if (Polymer.IronMenuBehaviorImpl._shiftTabPressed) {
1940 return;
1941 }
1942 var rootTarget = Polymer.dom(event).rootTarget;
1943 if (rootTarget !== this && typeof rootTarget.tabIndex !== "undefined" && !th is.isLightDescendant(rootTarget)) {
1944 return;
1945 }
1946 this._defaultFocusAsync = this.async(function() {
1947 var selectedItem = this.multi ? this.selectedItems && this.selectedItems[0 ] : this.selectedItem;
1948 this._setFocusedItem(null);
1949 if (selectedItem) {
1950 this._setFocusedItem(selectedItem);
1951 } else if (this.items[0]) {
1952 this._focusNext();
1953 }
1954 });
1955 },
1956 _onUpKey: function(event) {
1957 this._focusPrevious();
1958 event.detail.keyboardEvent.preventDefault();
1959 },
1960 _onDownKey: function(event) {
1961 this._focusNext();
1962 event.detail.keyboardEvent.preventDefault();
1963 },
1964 _onEscKey: function(event) {
1965 this.focusedItem.blur();
1966 },
1967 _onKeydown: function(event) {
1968 if (!this.keyboardEventMatchesKeys(event, 'up down esc')) {
1969 this._focusWithKeyboardEvent(event);
1970 }
1971 event.stopPropagation();
1972 },
1973 _activateHandler: function(event) {
1974 Polymer.IronSelectableBehavior._activateHandler.call(this, event);
1975 event.stopPropagation();
1976 }
1977 };
1978
1979 Polymer.IronMenuBehaviorImpl._shiftTabPressed = false;
1980
1981 Polymer.IronMenuBehavior = [ Polymer.IronMultiSelectableBehavior, Polymer.IronA1 1yKeysBehavior, Polymer.IronMenuBehaviorImpl ];
1982
1983 (function() {
1984 Polymer({
1985 is: 'paper-listbox',
1986 behaviors: [ Polymer.IronMenuBehavior ],
1987 hostAttributes: {
1988 role: 'listbox'
1989 }
1990 });
1991 })();
1992
1817 Polymer({ 1993 Polymer({
1818 is: 'paper-menu-grow-height-animation', 1994 is: 'paper-menu-grow-height-animation',
1819 behaviors: [ Polymer.NeonAnimationBehavior ], 1995 behaviors: [ Polymer.NeonAnimationBehavior ],
1820 configure: function(config) { 1996 configure: function(config) {
1821 var node = config.node; 1997 var node = config.node;
1822 var rect = node.getBoundingClientRect(); 1998 var rect = node.getBoundingClientRect();
1823 var height = rect.height; 1999 var height = rect.height;
1824 this._effect = new KeyframeEffect(node, [ { 2000 this._effect = new KeyframeEffect(node, [ {
1825 height: height / 2 + 'px' 2001 height: height / 2 + 'px'
1826 }, { 2002 }, {
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
1882 } 2058 }
1883 }); 2059 });
1884 2060
1885 // Copyright 2016 The Chromium Authors. All rights reserved. 2061 // Copyright 2016 The Chromium Authors. All rights reserved.
1886 // Use of this source code is governed by a BSD-style license that can be 2062 // Use of this source code is governed by a BSD-style license that can be
1887 // found in the LICENSE file. 2063 // found in the LICENSE file.
1888 var SLIDE_CUBIC_BEZIER = 'cubic-bezier(0.3, 0.95, 0.5, 1)'; 2064 var SLIDE_CUBIC_BEZIER = 'cubic-bezier(0.3, 0.95, 0.5, 1)';
1889 2065
1890 Polymer({ 2066 Polymer({
1891 is: 'cr-shared-menu', 2067 is: 'cr-shared-menu',
1892 behaviors: [ Polymer.IronA11yKeysBehavior ],
1893 properties: { 2068 properties: {
1894 menuOpen: { 2069 menuOpen: {
1895 type: Boolean, 2070 type: Boolean,
1896 observer: 'menuOpenChanged_', 2071 observer: 'menuOpenChanged_',
1897 value: false, 2072 value: false,
1898 notify: true 2073 notify: true
1899 }, 2074 },
1900 itemData: { 2075 itemData: {
1901 type: Object, 2076 type: Object,
1902 value: null 2077 value: null
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
1938 value: function() { 2113 value: function() {
1939 return [ { 2114 return [ {
1940 name: 'fade-out-animation', 2115 name: 'fade-out-animation',
1941 timing: { 2116 timing: {
1942 duration: 150 2117 duration: 150
1943 } 2118 }
1944 } ]; 2119 } ];
1945 } 2120 }
1946 } 2121 }
1947 }, 2122 },
1948 keyBindings: {
1949 tab: 'onTabPressed_'
1950 },
1951 listeners: { 2123 listeners: {
1952 'dropdown.iron-overlay-canceled': 'onOverlayCanceled_' 2124 'dropdown.iron-overlay-canceled': 'onOverlayCanceled_'
1953 }, 2125 },
1954 lastAnchor_: null, 2126 lastAnchor_: null,
1955 firstFocus_: null,
1956 lastFocus_: null,
1957 attached: function() { 2127 attached: function() {
1958 window.addEventListener('resize', this.closeMenu.bind(this)); 2128 window.addEventListener('resize', this.closeMenu.bind(this));
2129 this.$.menu.addEventListener('keydown', this.onCaptureKeyDown_.bind(this), t rue);
1959 }, 2130 },
1960 closeMenu: function() { 2131 closeMenu: function() {
1961 if (this.root.activeElement == null) { 2132 if (this.root.activeElement == null) {
1962 this.$.dropdown.restoreFocusOnClose = false; 2133 this.$.dropdown.restoreFocusOnClose = false;
1963 } 2134 }
1964 this.menuOpen = false; 2135 this.menuOpen = false;
1965 }, 2136 },
1966 openMenu: function(anchor, opt_itemData) { 2137 openMenu: function(anchor, opt_itemData) {
1967 if (this.lastAnchor_ == anchor && this.menuOpen) return; 2138 if (this.lastAnchor_ == anchor && this.menuOpen) return;
1968 if (this.menuOpen) this.closeMenu(); 2139 if (this.menuOpen) this.closeMenu();
1969 this.itemData = opt_itemData || null; 2140 this.itemData = opt_itemData || null;
1970 this.lastAnchor_ = anchor; 2141 this.lastAnchor_ = anchor;
1971 this.$.dropdown.restoreFocusOnClose = true; 2142 this.$.dropdown.restoreFocusOnClose = true;
1972 var focusableChildren = Polymer.dom(this).querySelectorAll('[tabindex]:not([ disabled]):not([hidden]),' + 'button:not([disabled]):not([hidden])'); 2143 this.$.menu.selected = -1;
1973 if (focusableChildren.length > 0) {
1974 this.$.dropdown.focusTarget = focusableChildren[0];
1975 this.firstFocus_ = focusableChildren[0];
1976 this.lastFocus_ = focusableChildren[focusableChildren.length - 1];
1977 }
1978 this.$.dropdown.positionTarget = anchor; 2144 this.$.dropdown.positionTarget = anchor;
1979 this.menuOpen = true; 2145 this.menuOpen = true;
1980 }, 2146 },
1981 toggleMenu: function(anchor, opt_itemData) { 2147 toggleMenu: function(anchor, opt_itemData) {
1982 if (anchor == this.lastAnchor_ && this.menuOpen) this.closeMenu(); else this .openMenu(anchor, opt_itemData); 2148 if (anchor == this.lastAnchor_ && this.menuOpen) this.closeMenu(); else this .openMenu(anchor, opt_itemData);
1983 }, 2149 },
1984 onTabPressed_: function(e) { 2150 onCaptureKeyDown_: function(e) {
1985 if (!this.firstFocus_ || !this.lastFocus_) return; 2151 if (Polymer.IronA11yKeysBehavior.keyboardEventMatchesKeys(e, 'tab')) {
1986 var toFocus; 2152 this.$.dropdown.restoreFocusOnClose = false;
1987 var keyEvent = e.detail.keyboardEvent; 2153 this.lastAnchor_.focus();
1988 if (keyEvent.shiftKey && keyEvent.target == this.firstFocus_) toFocus = this .lastFocus_; else if (!keyEvent.shiftKey && keyEvent.target == this.lastFocus_) toFocus = this.firstFocus_; 2154 this.closeMenu();
1989 if (!toFocus) return; 2155 }
1990 e.preventDefault();
1991 toFocus.focus();
1992 }, 2156 },
1993 menuOpenChanged_: function() { 2157 menuOpenChanged_: function() {
1994 if (!this.menuOpen) { 2158 if (!this.menuOpen) {
1995 this.itemData = null; 2159 this.itemData = null;
1996 this.lastAnchor_ = null; 2160 this.lastAnchor_ = null;
1997 } 2161 }
1998 }, 2162 },
1999 onOverlayCanceled_: function(e) { 2163 onOverlayCanceled_: function(e) {
2000 if (e.detail.type == 'tap') this.$.dropdown.restoreFocusOnClose = false; 2164 if (e.detail.type == 'tap') this.$.dropdown.restoreFocusOnClose = false;
2001 } 2165 }
(...skipping 780 matching lines...) Expand 10 before | Expand all | Expand 10 after
2782 return; 2946 return;
2783 } 2947 }
2784 if (event.target === anchor) { 2948 if (event.target === anchor) {
2785 return; 2949 return;
2786 } 2950 }
2787 anchor.click(); 2951 anchor.click();
2788 } 2952 }
2789 } 2953 }
2790 }); 2954 });
2791 2955
2792 Polymer.IronMenuBehaviorImpl = {
2793 properties: {
2794 focusedItem: {
2795 observer: '_focusedItemChanged',
2796 readOnly: true,
2797 type: Object
2798 },
2799 attrForItemTitle: {
2800 type: String
2801 }
2802 },
2803 hostAttributes: {
2804 role: 'menu',
2805 tabindex: '0'
2806 },
2807 observers: [ '_updateMultiselectable(multi)' ],
2808 listeners: {
2809 focus: '_onFocus',
2810 keydown: '_onKeydown',
2811 'iron-items-changed': '_onIronItemsChanged'
2812 },
2813 keyBindings: {
2814 up: '_onUpKey',
2815 down: '_onDownKey',
2816 esc: '_onEscKey',
2817 'shift+tab:keydown': '_onShiftTabDown'
2818 },
2819 attached: function() {
2820 this._resetTabindices();
2821 },
2822 select: function(value) {
2823 if (this._defaultFocusAsync) {
2824 this.cancelAsync(this._defaultFocusAsync);
2825 this._defaultFocusAsync = null;
2826 }
2827 var item = this._valueToItem(value);
2828 if (item && item.hasAttribute('disabled')) return;
2829 this._setFocusedItem(item);
2830 Polymer.IronMultiSelectableBehaviorImpl.select.apply(this, arguments);
2831 },
2832 _resetTabindices: function() {
2833 var selectedItem = this.multi ? this.selectedItems && this.selectedItems[0] : this.selectedItem;
2834 this.items.forEach(function(item) {
2835 item.setAttribute('tabindex', item === selectedItem ? '0' : '-1');
2836 }, this);
2837 },
2838 _updateMultiselectable: function(multi) {
2839 if (multi) {
2840 this.setAttribute('aria-multiselectable', 'true');
2841 } else {
2842 this.removeAttribute('aria-multiselectable');
2843 }
2844 },
2845 _focusWithKeyboardEvent: function(event) {
2846 for (var i = 0, item; item = this.items[i]; i++) {
2847 var attr = this.attrForItemTitle || 'textContent';
2848 var title = item[attr] || item.getAttribute(attr);
2849 if (!item.hasAttribute('disabled') && title && title.trim().charAt(0).toLo werCase() === String.fromCharCode(event.keyCode).toLowerCase()) {
2850 this._setFocusedItem(item);
2851 break;
2852 }
2853 }
2854 },
2855 _focusPrevious: function() {
2856 var length = this.items.length;
2857 var curFocusIndex = Number(this.indexOf(this.focusedItem));
2858 for (var i = 1; i < length + 1; i++) {
2859 var item = this.items[(curFocusIndex - i + length) % length];
2860 if (!item.hasAttribute('disabled')) {
2861 var owner = Polymer.dom(item).getOwnerRoot() || document;
2862 this._setFocusedItem(item);
2863 if (Polymer.dom(owner).activeElement == item) {
2864 return;
2865 }
2866 }
2867 }
2868 },
2869 _focusNext: function() {
2870 var length = this.items.length;
2871 var curFocusIndex = Number(this.indexOf(this.focusedItem));
2872 for (var i = 1; i < length + 1; i++) {
2873 var item = this.items[(curFocusIndex + i) % length];
2874 if (!item.hasAttribute('disabled')) {
2875 var owner = Polymer.dom(item).getOwnerRoot() || document;
2876 this._setFocusedItem(item);
2877 if (Polymer.dom(owner).activeElement == item) {
2878 return;
2879 }
2880 }
2881 }
2882 },
2883 _applySelection: function(item, isSelected) {
2884 if (isSelected) {
2885 item.setAttribute('aria-selected', 'true');
2886 } else {
2887 item.removeAttribute('aria-selected');
2888 }
2889 Polymer.IronSelectableBehavior._applySelection.apply(this, arguments);
2890 },
2891 _focusedItemChanged: function(focusedItem, old) {
2892 old && old.setAttribute('tabindex', '-1');
2893 if (focusedItem) {
2894 focusedItem.setAttribute('tabindex', '0');
2895 focusedItem.focus();
2896 }
2897 },
2898 _onIronItemsChanged: function(event) {
2899 if (event.detail.addedNodes.length) {
2900 this._resetTabindices();
2901 }
2902 },
2903 _onShiftTabDown: function(event) {
2904 var oldTabIndex = this.getAttribute('tabindex');
2905 Polymer.IronMenuBehaviorImpl._shiftTabPressed = true;
2906 this._setFocusedItem(null);
2907 this.setAttribute('tabindex', '-1');
2908 this.async(function() {
2909 this.setAttribute('tabindex', oldTabIndex);
2910 Polymer.IronMenuBehaviorImpl._shiftTabPressed = false;
2911 }, 1);
2912 },
2913 _onFocus: function(event) {
2914 if (Polymer.IronMenuBehaviorImpl._shiftTabPressed) {
2915 return;
2916 }
2917 var rootTarget = Polymer.dom(event).rootTarget;
2918 if (rootTarget !== this && typeof rootTarget.tabIndex !== "undefined" && !th is.isLightDescendant(rootTarget)) {
2919 return;
2920 }
2921 this._defaultFocusAsync = this.async(function() {
2922 var selectedItem = this.multi ? this.selectedItems && this.selectedItems[0 ] : this.selectedItem;
2923 this._setFocusedItem(null);
2924 if (selectedItem) {
2925 this._setFocusedItem(selectedItem);
2926 } else if (this.items[0]) {
2927 this._focusNext();
2928 }
2929 });
2930 },
2931 _onUpKey: function(event) {
2932 this._focusPrevious();
2933 event.detail.keyboardEvent.preventDefault();
2934 },
2935 _onDownKey: function(event) {
2936 this._focusNext();
2937 event.detail.keyboardEvent.preventDefault();
2938 },
2939 _onEscKey: function(event) {
2940 this.focusedItem.blur();
2941 },
2942 _onKeydown: function(event) {
2943 if (!this.keyboardEventMatchesKeys(event, 'up down esc')) {
2944 this._focusWithKeyboardEvent(event);
2945 }
2946 event.stopPropagation();
2947 },
2948 _activateHandler: function(event) {
2949 Polymer.IronSelectableBehavior._activateHandler.call(this, event);
2950 event.stopPropagation();
2951 }
2952 };
2953
2954 Polymer.IronMenuBehaviorImpl._shiftTabPressed = false;
2955
2956 Polymer.IronMenuBehavior = [ Polymer.IronMultiSelectableBehavior, Polymer.IronA1 1yKeysBehavior, Polymer.IronMenuBehaviorImpl ];
2957
2958 Polymer.IronMenubarBehaviorImpl = { 2956 Polymer.IronMenubarBehaviorImpl = {
2959 hostAttributes: { 2957 hostAttributes: {
2960 role: 'menubar' 2958 role: 'menubar'
2961 }, 2959 },
2962 keyBindings: { 2960 keyBindings: {
2963 left: '_onLeftKey', 2961 left: '_onLeftKey',
2964 right: '_onRightKey' 2962 right: '_onRightKey'
2965 }, 2963 },
2966 _onUpKey: function(event) { 2964 _onUpKey: function(event) {
2967 this.focusedItem.click(); 2965 this.focusedItem.click();
(...skipping 314 matching lines...) Expand 10 before | Expand all | Expand 10 after
3282 var cl = this.$.selectionBar.classList; 3280 var cl = this.$.selectionBar.classList;
3283 if (cl.contains('expand')) { 3281 if (cl.contains('expand')) {
3284 cl.remove('expand'); 3282 cl.remove('expand');
3285 cl.add('contract'); 3283 cl.add('contract');
3286 this._positionBar(this._pos.width, this._pos.left); 3284 this._positionBar(this._pos.width, this._pos.left);
3287 } else if (cl.contains('contract')) { 3285 } else if (cl.contains('contract')) {
3288 cl.remove('contract'); 3286 cl.remove('contract');
3289 } 3287 }
3290 } 3288 }
3291 }); 3289 });
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698