diff --git a/iron-focusables-helper.html b/iron-focusables-helper.html
index 65335f8..30c1780 100644
--- a/iron-focusables-helper.html
+++ b/iron-focusables-helper.html
@@ -27,8 +27,10 @@
var result = [];
// If there is at least one element with tabindex > 0, we need to sort
// the final array by tabindex.
- var maxTabIndex = this._findTabbableNodes(node, result);
- maxTabIndex > 0 && result.sort(this._tabIndexSort);
+ var needsSortByTabIndex = this._findTabbableNodes(node, result);
+ if (needsSortByTabIndex) {
+ result.sort(this._tabIndexSort);
+ }
return result;
},
@@ -94,33 +96,44 @@
/**
* Searches for nodes that are tabbable and adds them to the `result` array.
- * Returns the maximum tabindex of the added nodes.
- * @param {!Node} node The starting point for the search; it's added if tabbable.
+ * Returns if the `result` array needs to be sorted by tabindex.
+ * @param {!Node} node The starting point for the search; added to `result`
+ * if tabbable.
* @param {!Array} result
- * @return {Number}
+ * @return {boolean}
* @private
*/
_findTabbableNodes: function(node, result) {
- var maxTabIndex = 0;
// Skip #text nodes. If not visible, no need to explore children.
- if (node.nodeType !== 3 && this._isVisible(node)) {
- var tabIndex = this._normalizedTabIndex(node);
- if (tabIndex >= 0) {
- result.push(node);
- maxTabIndex = tabIndex;
- }
- var children;
- if (node.localName === 'content') {
- children = Polymer.dom(node).getDistributedNodes();
- } else {
- // Use shadow root if possible, will check for distributed nodes.
- children = Polymer.dom(node.root || node).children;
- }
- for (var i = 0; i < children.length; i++) {
- maxTabIndex = Math.max(this._findTabbableNodes(children[i], result), maxTabIndex);
- }
+ if (node.nodeType === 3 || !this._isVisible(node)) {
+ return false;
+ }
+ var tabIndex = this._normalizedTabIndex(node);
+
+ // TODO(valdrin) uncomment this when delegatesFocus is implemented.
+ // if delegatesFocus and tabindex = -1, should skip its children.
+ // if (tabIndex < 0 && node.delegatesFocus) {
+ // return false;
+ // }
+
+ var needsSortByTabIndex = tabIndex > 0;
+ if (tabIndex >= 0) {
+ result.push(node);
+ }
+
+ var children;
+ if (node.localName === 'content') {
+ children = Polymer.dom(node).getDistributedNodes();
+ } else {
+ // Use shadow root if possible, will check for distributed nodes.
+ children = Polymer.dom(node.root || node).children;
+ }
+ for (var i = 0; i < children.length; i++) {
+ // Ensure method is always invoked to collect tabbable children.
+ var needsSort = this._findTabbableNodes(children[i], result);
+ needsSortByTabIndex = needsSortByTabIndex || needsSort;
}
- return maxTabIndex;
+ return needsSortByTabIndex;
},
/**