OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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> |
OLD | NEW |