]>
git.wh0rd.org - tt-rss.git/blob - lib/dijit/a11y.js.uncompressed.js
2 "dojo/_base/array", // array.forEach array.map
3 "dojo/_base/config", // defaultDuration
4 "dojo/_base/declare", // declare
5 "dojo/dom", // dom.byId
6 "dojo/dom-attr", // domAttr.attr domAttr.has
7 "dojo/dom-style", // style.style
8 "dojo/sniff", // has("ie")
9 "./main" // for exporting methods to dijit namespace
10 ], function(array
, config
, declare
, dom
, domAttr
, domStyle
, has
, dijit
){
15 var shown
= (dijit
._isElementShown = function(/*Element*/ elem
){
16 var s
= domStyle
.get(elem
);
17 return (s
.visibility
!= "hidden")
18 && (s
.visibility
!= "collapsed")
19 && (s
.display
!= "none")
20 && (domAttr
.get(elem
, "type") != "hidden");
23 dijit
.hasDefaultTabStop = function(/*Element*/ elem
){
25 // Tests if element is tab-navigable even without an explicit tabIndex setting
27 // No explicit tabIndex setting, need to investigate node type
28 switch(elem
.nodeName
.toLowerCase()){
30 // An <a> w/out a tabindex is only navigable if it has an href
31 return domAttr
.has(elem
, "href");
38 // These are navigable by default
41 // If it's an editor <iframe> then it's tab navigable.
45 var contentDocument
= elem
.contentDocument
;
46 if("designMode" in contentDocument
&& contentDocument
.designMode
== "on"){
49 body
= contentDocument
.body
;
51 // contentWindow.document isn't accessible within IE7/8
52 // if the iframe.src points to a foreign url and this
53 // page contains an element, that could get focus
55 body
= elem
.contentWindow
.document
.body
;
60 return body
&& (body
.contentEditable
== 'true' ||
61 (body
.firstChild
&& body
.firstChild
.contentEditable
== 'true'));
63 return elem
.contentEditable
== 'true';
67 var isTabNavigable
= (dijit
.isTabNavigable = function(/*Element*/ elem
){
69 // Tests if an element is tab-navigable
71 // TODO: convert (and rename method) to return effective tabIndex; will save time in _getTabNavigable()
72 if(domAttr
.get(elem
, "disabled")){
74 }else if(domAttr
.has(elem
, "tabIndex")){
75 // Explicit tab index setting
76 return domAttr
.get(elem
, "tabIndex") >= 0; // boolean
78 // No explicit tabIndex setting, so depends on node type
79 return dijit
.hasDefaultTabStop(elem
);
83 dijit
._getTabNavigable = function(/*DOMNode*/ root
){
85 // Finds descendants of the specified root node.
87 // Finds the following descendants of the specified root node:
89 // - the first tab-navigable element in document order
90 // without a tabIndex or with tabIndex="0"
91 // - the last tab-navigable element in document order
92 // without a tabIndex or with tabIndex="0"
93 // - the first element in document order with the lowest
94 // positive tabIndex value
95 // - the last element in document order with the highest
96 // positive tabIndex value
97 var first
, last
, lowest
, lowestTabindex
, highest
, highestTabindex
, radioSelected
= {};
99 function radioName(node
){
100 // If this element is part of a radio button group, return the name for that group.
101 return node
&& node
.tagName
.toLowerCase() == "input" &&
102 node
.type
&& node
.type
.toLowerCase() == "radio" &&
103 node
.name
&& node
.name
.toLowerCase();
106 var walkTree = function(/*DOMNode*/ parent
){
107 for(var child
= parent
.firstChild
; child
; child
= child
.nextSibling
){
108 // Skip text elements, hidden elements, and also non-HTML elements (those in custom namespaces) in IE,
109 // since show() invokes getAttribute("type"), which crash on VML nodes in IE.
110 if(child
.nodeType
!= 1 || (has("ie") <= 9 && child
.scopeName
!== "HTML") || !shown(child
)){
114 if(isTabNavigable(child
)){
115 var tabindex
= +domAttr
.get(child
, "tabIndex"); // + to convert string --> number
116 if(!domAttr
.has(child
, "tabIndex") || tabindex
== 0){
121 }else if(tabindex
> 0){
122 if(!lowest
|| tabindex
< lowestTabindex
){
123 lowestTabindex
= tabindex
;
126 if(!highest
|| tabindex
>= highestTabindex
){
127 highestTabindex
= tabindex
;
131 var rn
= radioName(child
);
132 if(domAttr
.get(child
, "checked") && rn
){
133 radioSelected
[rn
] = child
;
136 if(child
.nodeName
.toUpperCase() != 'SELECT'){
145 // substitute checked radio button for unchecked one, if there is a checked one with the same name.
146 return radioSelected
[radioName(node
)] || node
;
149 return { first
: rs(first
), last
: rs(last
), lowest
: rs(lowest
), highest
: rs(highest
) };
151 dijit
.getFirstInTabbingOrder = function(/*String|DOMNode*/ root
, /*Document?*/ doc
){
153 // Finds the descendant of the specified root node
154 // that is first in the tabbing order
155 var elems
= dijit
._getTabNavigable(dom
.byId(root
, doc
));
156 return elems
.lowest
? elems
.lowest
: elems
.first
; // DomNode
159 dijit
.getLastInTabbingOrder = function(/*String|DOMNode*/ root
, /*Document?*/ doc
){
161 // Finds the descendant of the specified root node
162 // that is last in the tabbing order
163 var elems
= dijit
._getTabNavigable(dom
.byId(root
, doc
));
164 return elems
.last
? elems
.last
: elems
.highest
; // DomNode
169 // Accessibility utility functions (keyboard, tab stops, etc.)
171 hasDefaultTabStop
: dijit
.hasDefaultTabStop
,
172 isTabNavigable
: dijit
.isTabNavigable
,
173 _getTabNavigable
: dijit
._getTabNavigable
,
174 getFirstInTabbingOrder
: dijit
.getFirstInTabbingOrder
,
175 getLastInTabbingOrder
: dijit
.getLastInTabbingOrder