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

Side by Side Diff: tracing/tracing/ui/base/tab_view.html

Issue 2374483002: [tracing] Add keyboard navigation to the tab view (Closed)
Patch Set: add switch 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
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 <!DOCTYPE html> 1 <!DOCTYPE html>
2 <!-- 2 <!--
3 Copyright (c) 2014 The Chromium Authors. All rights reserved. 3 Copyright (c) 2014 The Chromium Authors. All rights reserved.
4 Use of this source code is governed by a BSD-style license that can be 4 Use of this source code is governed by a BSD-style license that can be
5 found in the LICENSE file. 5 found in the LICENSE file.
6 --> 6 -->
7 7
8 <link rel="import" href="/tracing/base/base.html"> 8 <link rel="import" href="/tracing/base/base.html">
9 9
10 <!-- 10 <!--
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
53 display: inline-block; 53 display: inline-block;
54 border: 1px solid #ececec; 54 border: 1px solid #ececec;
55 margin: 5px 0px 0px 15px; 55 margin: 5px 0px 0px 15px;
56 padding: 3px 10px 3px 10px; 56 padding: 3px 10px 3px 10px;
57 } 57 }
58 58
59 #tabs tab label span { 59 #tabs tab label span {
60 font-weight: bold; 60 font-weight: bold;
61 } 61 }
62 62
63 #tabs:focus input[type=radio]:checked ~ label {
64 outline: dotted 1px #8e8e8e;
65 outline-offset: -2px;
66 }
67
63 #tabs input[type=radio]:checked ~ label { 68 #tabs input[type=radio]:checked ~ label {
64 background-color: white; 69 background-color: white;
65 border: 1px solid #8e8e8e; 70 border: 1px solid #8e8e8e;
66 border-bottom: 1px solid white; 71 border-bottom: 1px solid white;
67 } 72 }
68 73
69 #subView { 74 #subView {
70 flex: 1 1 auto; 75 flex: 1 1 auto;
71 overflow: auto; 76 overflow: auto;
72 } 77 }
(...skipping 30 matching lines...) Expand all
103 type: String, 108 type: String,
104 value: () => '' 109 value: () => ''
105 }, 110 },
106 selectedSubView_: Object, 111 selectedSubView_: Object,
107 subViews_: { 112 subViews_: {
108 type: Array, 113 type: Array,
109 value: () => [] 114 value: () => []
110 }, 115 },
111 tabsHidden: { 116 tabsHidden: {
112 type: Boolean, 117 type: Boolean,
113 value: false 118 value: false,
119 observer: 'tabsHiddenChanged_'
114 } 120 }
115 }, 121 },
116 122
123 ready: function() {
124 this.$.tabs.addEventListener('keydown', this.onKeyDown_.bind(this), true);
125 this.updateFocusability_();
126 },
127
117 set label(newLabel) { 128 set label(newLabel) {
118 this.set('label_', newLabel); 129 this.set('label_', newLabel);
119 }, 130 },
120 131
121 get tabs() { 132 get tabs() {
122 return this.get('subViews_'); 133 return this.get('subViews_');
123 }, 134 },
124 135
125 get selectedSubView() { 136 get selectedSubView() {
126 return this.selectedSubView_; 137 return this.selectedSubView_;
(...skipping 10 matching lines...) Expand all
137 148
138 if (subView) 149 if (subView)
139 Polymer.dom(this.$.subView).appendChild(subView); 150 Polymer.dom(this.$.subView).appendChild(subView);
140 151
141 this.fire('selected-tab-change'); 152 this.fire('selected-tab-change');
142 }, 153 },
143 154
144 clearSubViews: function() { 155 clearSubViews: function() {
145 this.splice('subViews_', 0, this.subViews_.length); 156 this.splice('subViews_', 0, this.subViews_.length);
146 this.selectedSubView = undefined; 157 this.selectedSubView = undefined;
158 this.updateFocusability_();
147 }, 159 },
148 160
149 addSubView: function(subView) { 161 addSubView: function(subView) {
150 if (!this.selectedSubView_) 162 if (!this.selectedSubView_)
151 this.selectedSubView = subView; 163 this.selectedSubView = subView;
152 164
153 this.push('subViews_', subView); 165 this.push('subViews_', subView);
166 this.updateFocusability_();
154 }, 167 },
155 168
156 resetSubViews: function(subViews) { 169 resetSubViews: function(subViews) {
157 this.splice('subViews_', 0, this.subViews_.length); 170 this.splice('subViews_', 0, this.subViews_.length);
158 if (subViews.length) { 171 if (subViews.length) {
159 for (var subView of subViews) 172 for (var subView of subViews)
160 this.push('subViews_', subView); 173 this.push('subViews_', subView);
161 this.selectedSubView = subViews[0]; 174 this.selectedSubView = subViews[0];
162 } 175 }
163 else { 176 else {
164 this.selectedSubView = undefined; 177 this.selectedSubView = undefined;
165 } 178 }
179 this.updateFocusability_();
166 }, 180 },
167 181
168 onTabChanged_: function(event) { 182 onTabChanged_: function(event) {
169 this.selectedSubView = event.model.item; 183 this.selectedSubView = event.model.item;
170 }, 184 },
171 185
172 isChecked_: function(subView) { 186 isChecked_: function(subView) {
173 return this.selectedSubView_ === subView; 187 return this.selectedSubView_ === subView;
174 }, 188 },
175 189
190 tabsHiddenChanged_: function() {
191 this.updateFocusability_();
192 },
193
194 onKeyDown_: function(e) {
195 if (this.tabsHidden || !this.selectedSubView_)
196 return;
197
198 var currentIndex = this.subViews_.indexOf(this.selectedSubView_);
199 var nextIndex = undefined;
200 switch (e.keyCode) {
201 // Arrow left.
202 case 37:
203 nextIndex = currentIndex - 1;
204 break;
205 // Arrow right.
206 case 39:
207 nextIndex = currentIndex + 1;
208 break;
209 default:
210 return;
211 }
212
213 var tab = Polymer.dom(this.root).querySelectorAll('#tabs tab')[nextIndex];
214 if (tab)
215 tab.querySelector('input').click();
216
217 e.stopPropagation();
218 e.preventDefault();
219 },
220
221 shouldBeFocusable_: function() {
222 return !this.tabsHidden && this.subViews_.length > 0;
223 },
224
225 updateFocusability_: function() {
226 if (this.shouldBeFocusable_()) {
227 Polymer.dom(this.$.tabs).setAttribute('tabindex', 0);
228 } else {
229 Polymer.dom(this.$.tabs).removeAttribute('tabindex');
230 }
231 },
232
176 computeRadioId_: function(subView) { 233 computeRadioId_: function(subView) {
177 // We can't just use the tagName as the radio's ID because there are 234 // We can't just use the tagName as the radio's ID because there are
178 // instances where a single subview type can handle multiple event types, 235 // instances where a single subview type can handle multiple event types,
179 // and thus might be present multiple times in a single tab view. In order 236 // and thus might be present multiple times in a single tab view. In order
180 // to avoid the case where we might have two tabs with the same ID, we 237 // to avoid the case where we might have two tabs with the same ID, we
181 // uniquify this ID by appending the tab's label with all spaces replaced 238 // uniquify this ID by appending the tab's label with all spaces replaced
182 // by dashes (because spaces aren't allowed in HTML IDs). 239 // by dashes (because spaces aren't allowed in HTML IDs).
183 return subView.tagName + '-' + subView.tabLabel.replace(/ /g, '-'); 240 return subView.tagName + '-' + subView.tabLabel.replace(/ /g, '-');
184 } 241 }
185 }); 242 });
186 </script> 243 </script>
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698