OLD | NEW |
(Empty) | |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 cr.define('downloads', function() { |
| 6 /** |
| 7 * Provides an implementation for a single column grid. |
| 8 * @constructor |
| 9 * @extends {cr.ui.FocusRow} |
| 10 */ |
| 11 function FocusRow() {} |
| 12 |
| 13 /** |
| 14 * Decorates |focusRow| so that it can be treated as a FocusRow. |
| 15 * @param {Element} focusRow The element that has all the columns represented |
| 16 * by |itemView|. |
| 17 * @param {!downloads.ItemView} itemView The item view this row cares about. |
| 18 * @param {Node} boundary Focus events are ignored outside of this node. |
| 19 */ |
| 20 FocusRow.decorate = function(focusRow, itemView, boundary) { |
| 21 focusRow.__proto__ = FocusRow.prototype; |
| 22 focusRow.decorate(boundary); |
| 23 |
| 24 // Add all clickable elements as a row into the grid. |
| 25 focusRow.addElementIfFocusable_(itemView.fileLink, 'name'); |
| 26 focusRow.addElementIfFocusable_(itemView.srcUrl, 'url'); |
| 27 focusRow.addElementIfFocusable_(itemView.show, 'show'); |
| 28 focusRow.addElementIfFocusable_(itemView.retry, 'retry'); |
| 29 focusRow.addElementIfFocusable_(itemView.pause, 'pause'); |
| 30 focusRow.addElementIfFocusable_(itemView.resume, 'resume'); |
| 31 focusRow.addElementIfFocusable_(itemView.safeRemove, 'remove'); |
| 32 focusRow.addElementIfFocusable_(itemView.cancel, 'cancel'); |
| 33 focusRow.addElementIfFocusable_(itemView.restore, 'save'); |
| 34 focusRow.addElementIfFocusable_(itemView.save, 'save'); |
| 35 focusRow.addElementIfFocusable_(itemView.dangerRemove, 'discard'); |
| 36 focusRow.addElementIfFocusable_(itemView.discard, 'discard'); |
| 37 focusRow.addElementIfFocusable_(itemView.controlledBy, 'extension'); |
| 38 }; |
| 39 |
| 40 FocusRow.prototype = { |
| 41 __proto__: cr.ui.FocusRow.prototype, |
| 42 |
| 43 /** @override */ |
| 44 getEquivalentElement: function(element) { |
| 45 if (this.focusableElements.indexOf(element) > -1) |
| 46 return assert(element); |
| 47 |
| 48 // All elements default to another element with the same type. |
| 49 var columnType = element.getAttribute('column-type'); |
| 50 var equivalent = this.querySelector('[column-type=' + columnType + ']'); |
| 51 |
| 52 if (this.focusableElements.indexOf(equivalent) < 0) { |
| 53 var equivalentTypes = |
| 54 ['show', 'retry', 'pause', 'resume', 'remove', 'cancel']; |
| 55 if (equivalentTypes.indexOf(columnType) != -1) { |
| 56 var allTypes = equivalentTypes.map(function(type) { |
| 57 return '[column-type=' + type + ']:not([hidden])'; |
| 58 }).join(', '); |
| 59 equivalent = this.querySelector(allTypes); |
| 60 } |
| 61 } |
| 62 |
| 63 // Return the first focusable element if no equivalent element is found. |
| 64 return assert(equivalent || this.focusableElements[0]); |
| 65 }, |
| 66 |
| 67 /** |
| 68 * @param {Element} element The element that should be added. |
| 69 * @param {string} type The column type to use for the element. |
| 70 * @private |
| 71 */ |
| 72 addElementIfFocusable_: function(element, type) { |
| 73 if (this.shouldFocus_(element)) { |
| 74 this.addFocusableElement(element); |
| 75 element.setAttribute('column-type', type); |
| 76 } |
| 77 }, |
| 78 |
| 79 /** |
| 80 * Determines if element should be focusable. |
| 81 * @param {Element} element |
| 82 * @return {boolean} |
| 83 * @private |
| 84 */ |
| 85 shouldFocus_: function(element) { |
| 86 if (!element) |
| 87 return false; |
| 88 |
| 89 // Hidden elements are not focusable. |
| 90 var style = window.getComputedStyle(element); |
| 91 if (style.visibility == 'hidden' || style.display == 'none') |
| 92 return false; |
| 93 |
| 94 // Verify all ancestors are focusable. |
| 95 return !element.parentElement || this.shouldFocus_(element.parentElement); |
| 96 }, |
| 97 }; |
| 98 |
| 99 return {FocusRow: FocusRow}; |
| 100 }); |
OLD | NEW |