Chromium Code Reviews| Index: ui/webui/resources/js/cr/ui/focus_row.js |
| diff --git a/ui/webui/resources/js/cr/ui/focus_row.js b/ui/webui/resources/js/cr/ui/focus_row.js |
| index 26c4c5567e2b673f24b19574c2b35afe6c69263f..317076dbebaf18afc60a016a67b1f02226e94871 100644 |
| --- a/ui/webui/resources/js/cr/ui/focus_row.js |
| +++ b/ui/webui/resources/js/cr/ui/focus_row.js |
| @@ -88,6 +88,20 @@ cr.define('cr.ui', function() { |
| onMousedown: assertNotReached, |
| }; |
| + /** |
| + * Determines if element should be focusable. |
| + * @param {!Element} element |
| + */ |
| + FocusRow.isFocusable = function(element) { |
|
Dan Beam
2014/12/22 23:19:59
why is this public? and static?
hcarmona
2015/01/13 00:04:40
Made private and moved to the downloads page to be
|
| + var style = window.getComputedStyle(element); |
|
Dan Beam
2014/12/22 23:19:59
getComputedStyle already takes the entire hierarch
hcarmona
2015/01/13 00:04:41
This doesn't work for display because display:none
|
| + if (style.visibility == 'hidden' || style.display == 'none') |
|
Dan Beam
2014/12/22 23:19:59
what about tabindex < 0?
hcarmona
2015/01/13 00:04:41
This will be used to update the tabIndex. All elem
|
| + return false; |
| + |
| + if (element.parentElement) |
|
Dan Beam
2014/12/22 23:19:59
this can also be null when the element's not in th
hcarmona
2015/01/13 00:04:40
Done.
|
| + return FocusRow.isFocusable(element.parentElement); |
| + return true; |
| + }; |
| + |
| /** @interface */ |
| FocusRow.Observer = function() {}; |
| @@ -109,16 +123,24 @@ cr.define('cr.ui', function() { |
| get activeIndex() { |
| return this.activeIndex_; |
| }, |
| + |
| + /** |
| + * Set the active index and update focusability. An index out of range will |
| + * make all items not focusable if the row was previously focused. |
| + */ |
| set activeIndex(index) { |
| var wasActive = this.items[this.activeIndex_]; |
| - if (wasActive) |
| - wasActive.tabIndex = -1; |
| - this.items.forEach(function(item) { assert(item.tabIndex == -1); }); |
| - this.activeIndex_ = index; |
| + if (this.items[index]) { |
| + this.items.forEach(function(item) { |
| + if (FocusRow.isFocusable(item)) |
| + item.tabIndex = 0; |
| + }.bind(this)); |
|
Dan Beam
2014/12/22 23:19:59
pass in a thisArg instead of .bind()ing
hcarmona
2015/01/13 00:04:41
bind is left over from previous code. Removed it.
|
| + } |
| + else if (wasActive) |
|
dmazzoni
2014/12/22 23:14:07
Formatting nit: the "else" should be on the same l
Dan Beam
2014/12/22 23:19:59
} else if (...) {
hcarmona
2015/01/13 00:04:41
Done.
hcarmona
2015/01/13 00:04:41
Done.
|
| + this.items.forEach(function(item) { item.tabIndex = -1; }); |
| - if (this.items[index]) |
| - this.items[index].tabIndex = 0; |
| + this.activeIndex_ = index; |
| if (!this.observer_) |
| return; |
| @@ -133,13 +155,52 @@ cr.define('cr.ui', function() { |
| this.observer_.onDeactivate(this); |
| }, |
| + /** @private */ |
| + previousIndex_: 0, |
|
Dan Beam
2014/12/22 23:19:59
not very explanatory here...
hcarmona
2015/01/13 00:04:40
Code changed so this is no longer necessary.
|
| + |
| /** |
| * Focuses the item at |index|. |
|
dmazzoni
2014/12/22 23:14:07
Update these docs?
hcarmona
2015/01/13 00:04:41
Code changed so this is no longer necessary.
|
| * @param {number} index An index to focus. Must be between 0 and |
| * this.items.length - 1. |
| */ |
| focusIndex: function(index) { |
|
Dan Beam
2014/12/22 23:19:59
change from index to ID like bondd@ did in setting
hcarmona
2015/01/13 00:04:41
Done.
|
| + if (!FocusRow.isFocusable(this.items[index])) { |
| + // Find first focusable element smaller than the invalid index. |
| + var smallIndex = index; |
| + for (smallIndex; smallIndex >= 0; --smallIndex) { |
| + if (FocusRow.isFocusable(this.items[smallIndex])) |
| + break; |
| + } |
| + |
| + // Find first focusable element larger than the invalid index. |
| + var largeIndex = index; |
| + for (largeIndex; largeIndex < this.items.length; ++largeIndex) { |
| + if (FocusRow.isFocusable(this.items[largeIndex])) |
| + break; |
| + } |
| + |
| + if (smallIndex > -1 && largeIndex < this.items.length) { |
| + // Can focus in either direction. Give preference to the direction |
| + // away from previousIndex_. |
| + if (this.previousIndex_ > index) |
| + index = smallIndex; |
| + else |
| + index = largeIndex; |
| + } else if (smallIndex > -1) { |
| + // Can only focus smaller. |
| + index = smallIndex; |
| + } else if (largeIndex < this.items.length) { |
| + // Can only focus larger. |
| + index = largeIndex; |
| + } else { |
| + // This code path shouldn't be executed because it means we have a row |
| + // with nothing focusable. |
| + assert(false); |
|
Dan Beam
2014/12/22 23:19:59
assertNotReached()
hcarmona
2015/01/13 00:04:41
Done.
|
| + } |
| + } |
| + |
| this.items[index].focus(); |
| + this.previousIndex_ = index; |
|
Dan Beam
2014/12/22 23:19:59
previouslyFocusedIndex_?
hcarmona
2015/01/13 00:04:41
Code has changed and this is different now.
|
| }, |
| /** Call this to clean up event handling before dereferencing. */ |