Skip to content
This repository was archived by the owner on Jan 4, 2021. It is now read-only.

Commit a7951a7

Browse files
committed
[DOC] Fix generation v1.2.2
1 parent ec0b978 commit a7951a7

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+2086
-0
lines changed
Lines changed: 220 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,220 @@
1+
<!doctype html>
2+
<!--
3+
@license
4+
Copyright (c) 2016 The Polymer Project Authors. All rights reserved.
5+
This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
6+
The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
7+
The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
8+
Code distributed by Google as part of the polymer project is also
9+
subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
10+
-->
11+
<link rel="import" href="../polymer/polymer.html">
12+
13+
<script>
14+
(function() {
15+
'use strict';
16+
17+
var p = Element.prototype;
18+
var matches = p.matches || p.matchesSelector || p.mozMatchesSelector ||
19+
p.msMatchesSelector || p.oMatchesSelector || p.webkitMatchesSelector;
20+
21+
Polymer.IronFocusablesHelper = {
22+
23+
/**
24+
* Returns a sorted array of tabbable nodes, including the root node.
25+
* It searches the tabbable nodes in the light and shadow dom of the chidren,
26+
* sorting the result by tabindex.
27+
* @param {!Node} node
28+
* @return {Array<HTMLElement>}
29+
*/
30+
getTabbableNodes: function(node) {
31+
var result = [];
32+
// If there is at least one element with tabindex > 0, we need to sort
33+
// the final array by tabindex.
34+
var needsSortByTabIndex = this._collectTabbableNodes(node, result);
35+
if (needsSortByTabIndex) {
36+
return this._sortByTabIndex(result);
37+
}
38+
return result;
39+
},
40+
41+
/**
42+
* Returns if a element is focusable.
43+
* @param {!HTMLElement} element
44+
* @return {boolean}
45+
*/
46+
isFocusable: function(element) {
47+
// From http://stackoverflow.com/a/1600194/4228703:
48+
// There isn't a definite list, it's up to the browser. The only
49+
// standard we have is DOM Level 2 HTML https://www.w3.org/TR/DOM-Level-2-HTML/html.html,
50+
// according to which the only elements that have a focus() method are
51+
// HTMLInputElement, HTMLSelectElement, HTMLTextAreaElement and
52+
// HTMLAnchorElement. This notably omits HTMLButtonElement and
53+
// HTMLAreaElement.
54+
// Referring to these tests with tabbables in different browsers
55+
// http://allyjs.io/data-tables/focusable.html
56+
57+
// Elements that cannot be focused if they have [disabled] attribute.
58+
if (matches.call(element, 'input, select, textarea, button, object')) {
59+
return matches.call(element, ':not([disabled])');
60+
}
61+
// Elements that can be focused even if they have [disabled] attribute.
62+
return matches.call(element,
63+
'a[href], area[href], iframe, [tabindex], [contentEditable]');
64+
},
65+
66+
/**
67+
* Returns if a element is tabbable. To be tabbable, a element must be
68+
* focusable, visible, and with a tabindex !== -1.
69+
* @param {!HTMLElement} element
70+
* @return {boolean}
71+
*/
72+
isTabbable: function(element) {
73+
return this.isFocusable(element) &&
74+
matches.call(element, ':not([tabindex="-1"])') &&
75+
this._isVisible(element);
76+
},
77+
78+
/**
79+
* Returns the normalized element tabindex. If not focusable, returns -1.
80+
* It checks for the attribute "tabindex" instead of the element property
81+
* `tabIndex` since browsers assign different values to it.
82+
* e.g. in Firefox `<div contenteditable>` has `tabIndex = -1`
83+
* @param {!HTMLElement} element
84+
* @return {!number}
85+
* @private
86+
*/
87+
_normalizedTabIndex: function(element) {
88+
if (this.isFocusable(element)) {
89+
var tabIndex = element.getAttribute('tabindex') || 0;
90+
return Number(tabIndex);
91+
}
92+
return -1;
93+
},
94+
95+
/**
96+
* Searches for nodes that are tabbable and adds them to the `result` array.
97+
* Returns if the `result` array needs to be sorted by tabindex.
98+
* @param {!Node} node The starting point for the search; added to `result`
99+
* if tabbable.
100+
* @param {!Array<HTMLElement>} result
101+
* @return {boolean}
102+
* @private
103+
*/
104+
_collectTabbableNodes: function(node, result) {
105+
// If not an element or not visible, no need to explore children.
106+
if (node.nodeType !== Node.ELEMENT_NODE || !this._isVisible(node)) {
107+
return false;
108+
}
109+
var element = /** @type {HTMLElement} */ (node);
110+
var tabIndex = this._normalizedTabIndex(element);
111+
var needsSortByTabIndex = tabIndex > 0;
112+
if (tabIndex >= 0) {
113+
result.push(element);
114+
}
115+
116+
// In ShadowDOM v1, tab order is affected by the order of distrubution.
117+
// E.g. getTabbableNodes(#root) in ShadowDOM v1 should return [#A, #B];
118+
// in ShadowDOM v0 tab order is not affected by the distrubution order,
119+
// in fact getTabbableNodes(#root) returns [#B, #A].
120+
// <div id="root">
121+
// <!-- shadow -->
122+
// <slot name="a">
123+
// <slot name="b">
124+
// <!-- /shadow -->
125+
// <input id="A" slot="a">
126+
// <input id="B" slot="b" tabindex="1">
127+
// </div>
128+
// TODO(valdrin) support ShadowDOM v1 when upgrading to Polymer v2.0.
129+
var children;
130+
if (element.localName === 'content') {
131+
children = Polymer.dom(element).getDistributedNodes();
132+
} else {
133+
// Use shadow root if possible, will check for distributed nodes.
134+
children = Polymer.dom(element.root || element).children;
135+
}
136+
for (var i = 0; i < children.length; i++) {
137+
// Ensure method is always invoked to collect tabbable children.
138+
var needsSort = this._collectTabbableNodes(children[i], result);
139+
needsSortByTabIndex = needsSortByTabIndex || needsSort;
140+
}
141+
return needsSortByTabIndex;
142+
},
143+
144+
/**
145+
* Returns false if the element has `visibility: hidden` or `display: none`
146+
* @param {!HTMLElement} element
147+
* @return {boolean}
148+
* @private
149+
*/
150+
_isVisible: function(element) {
151+
// Check inline style first to save a re-flow. If looks good, check also
152+
// computed style.
153+
var style = element.style;
154+
if (style.visibility !== 'hidden' && style.display !== 'none') {
155+
style = window.getComputedStyle(element);
156+
return (style.visibility !== 'hidden' && style.display !== 'none');
157+
}
158+
return false;
159+
},
160+
161+
/**
162+
* Sorts an array of tabbable elements by tabindex. Returns a new array.
163+
* @param {!Array<HTMLElement>} tabbables
164+
* @return {Array<HTMLElement>}
165+
* @private
166+
*/
167+
_sortByTabIndex: function(tabbables) {
168+
// Implement a merge sort as Array.prototype.sort does a non-stable sort
169+
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort
170+
var len = tabbables.length;
171+
if (len < 2) {
172+
return tabbables;
173+
}
174+
var pivot = Math.ceil(len / 2);
175+
var left = this._sortByTabIndex(tabbables.slice(0, pivot));
176+
var right = this._sortByTabIndex(tabbables.slice(pivot));
177+
return this._mergeSortByTabIndex(left, right);
178+
},
179+
180+
/**
181+
* Merge sort iterator, merges the two arrays into one, sorted by tab index.
182+
* @param {!Array<HTMLElement>} left
183+
* @param {!Array<HTMLElement>} right
184+
* @return {Array<HTMLElement>}
185+
* @private
186+
*/
187+
_mergeSortByTabIndex: function(left, right) {
188+
var result = [];
189+
while ((left.length > 0) && (right.length > 0)) {
190+
if (this._hasLowerTabOrder(left[0], right[0])) {
191+
result.push(right.shift());
192+
} else {
193+
result.push(left.shift());
194+
}
195+
}
196+
197+
return result.concat(left, right);
198+
},
199+
200+
/**
201+
* Returns if element `a` has lower tab order compared to element `b`
202+
* (both elements are assumed to be focusable and tabbable).
203+
* Elements with tabindex = 0 have lower tab order compared to elements
204+
* with tabindex > 0.
205+
* If both have same tabindex, it returns false.
206+
* @param {!HTMLElement} a
207+
* @param {!HTMLElement} b
208+
* @return {boolean}
209+
* @private
210+
*/
211+
_hasLowerTabOrder: function(a, b) {
212+
// Normalize tabIndexes
213+
// e.g. in Firefox `<div contenteditable>` has `tabIndex = -1`
214+
var ati = Math.max(a.tabIndex, 0);
215+
var bti = Math.max(b.tabIndex, 0);
216+
return (ati === 0 || bti === 0) ? bti > ati : ati > bti;
217+
}
218+
};
219+
})();
220+
</script>

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy