]> git.wh0rd.org - tt-rss.git/blob - lib/dijit/a11y.js.uncompressed.js
modify dojo rebuild script to remove uncompressed files
[tt-rss.git] / lib / dijit / a11y.js.uncompressed.js
1 define("dijit/a11y", [
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){
11
12 // module:
13 // dijit/a11y
14
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");
21 });
22
23 dijit.hasDefaultTabStop = function(/*Element*/ elem){
24 // summary:
25 // Tests if element is tab-navigable even without an explicit tabIndex setting
26
27 // No explicit tabIndex setting, need to investigate node type
28 switch(elem.nodeName.toLowerCase()){
29 case "a":
30 // An <a> w/out a tabindex is only navigable if it has an href
31 return domAttr.has(elem, "href");
32 case "area":
33 case "button":
34 case "input":
35 case "object":
36 case "select":
37 case "textarea":
38 // These are navigable by default
39 return true;
40 case "iframe":
41 // If it's an editor <iframe> then it's tab navigable.
42 var body;
43 try{
44 // non-IE
45 var contentDocument = elem.contentDocument;
46 if("designMode" in contentDocument && contentDocument.designMode == "on"){
47 return true;
48 }
49 body = contentDocument.body;
50 }catch(e1){
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
54 try{
55 body = elem.contentWindow.document.body;
56 }catch(e2){
57 return false;
58 }
59 }
60 return body && (body.contentEditable == 'true' ||
61 (body.firstChild && body.firstChild.contentEditable == 'true'));
62 default:
63 return elem.contentEditable == 'true';
64 }
65 };
66
67 var isTabNavigable = (dijit.isTabNavigable = function(/*Element*/ elem){
68 // summary:
69 // Tests if an element is tab-navigable
70
71 // TODO: convert (and rename method) to return effective tabIndex; will save time in _getTabNavigable()
72 if(domAttr.get(elem, "disabled")){
73 return false;
74 }else if(domAttr.has(elem, "tabIndex")){
75 // Explicit tab index setting
76 return domAttr.get(elem, "tabIndex") >= 0; // boolean
77 }else{
78 // No explicit tabIndex setting, so depends on node type
79 return dijit.hasDefaultTabStop(elem);
80 }
81 });
82
83 dijit._getTabNavigable = function(/*DOMNode*/ root){
84 // summary:
85 // Finds descendants of the specified root node.
86 // description:
87 // Finds the following descendants of the specified root node:
88 //
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 = {};
98
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();
104 }
105
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)){
111 continue;
112 }
113
114 if(isTabNavigable(child)){
115 var tabindex = +domAttr.get(child, "tabIndex"); // + to convert string --> number
116 if(!domAttr.has(child, "tabIndex") || tabindex == 0){
117 if(!first){
118 first = child;
119 }
120 last = child;
121 }else if(tabindex > 0){
122 if(!lowest || tabindex < lowestTabindex){
123 lowestTabindex = tabindex;
124 lowest = child;
125 }
126 if(!highest || tabindex >= highestTabindex){
127 highestTabindex = tabindex;
128 highest = child;
129 }
130 }
131 var rn = radioName(child);
132 if(domAttr.get(child, "checked") && rn){
133 radioSelected[rn] = child;
134 }
135 }
136 if(child.nodeName.toUpperCase() != 'SELECT'){
137 walkTree(child);
138 }
139 }
140 };
141 if(shown(root)){
142 walkTree(root);
143 }
144 function rs(node){
145 // substitute checked radio button for unchecked one, if there is a checked one with the same name.
146 return radioSelected[radioName(node)] || node;
147 }
148
149 return { first: rs(first), last: rs(last), lowest: rs(lowest), highest: rs(highest) };
150 };
151 dijit.getFirstInTabbingOrder = function(/*String|DOMNode*/ root, /*Document?*/ doc){
152 // summary:
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
157 };
158
159 dijit.getLastInTabbingOrder = function(/*String|DOMNode*/ root, /*Document?*/ doc){
160 // summary:
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
165 };
166
167 return {
168 // summary:
169 // Accessibility utility functions (keyboard, tab stops, etc.)
170
171 hasDefaultTabStop: dijit.hasDefaultTabStop,
172 isTabNavigable: dijit.isTabNavigable,
173 _getTabNavigable: dijit._getTabNavigable,
174 getFirstInTabbingOrder: dijit.getFirstInTabbingOrder,
175 getLastInTabbingOrder: dijit.getLastInTabbingOrder
176 };
177 });