aria-api 0.2.7 → 0.4.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +20 -3
- package/dist/aria.js +799 -473
- package/index.js +4 -0
- package/lib/atree.js +90 -0
- package/lib/attrs.js +115 -0
- package/lib/constants.js +471 -253
- package/lib/name.js +31 -65
- package/lib/query.js +26 -121
- package/package.json +5 -4
- package/CHANGES.md +0 -102
- package/dist/aria.min.js +0 -1
- package/lib/util.js +0 -28
package/dist/aria.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.aria = f()}})(function(){var define,module,exports;return (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){
|
|
2
2
|
var query = require('./lib/query.js');
|
|
3
3
|
var name = require('./lib/name.js');
|
|
4
|
+
var atree = require('./lib/atree.js');
|
|
4
5
|
|
|
5
6
|
module.exports = {
|
|
6
7
|
getRole: query.getRole,
|
|
@@ -12,70 +13,275 @@ module.exports = {
|
|
|
12
13
|
querySelector: query.querySelector,
|
|
13
14
|
querySelectorAll: query.querySelectorAll,
|
|
14
15
|
closest: query.closest,
|
|
16
|
+
|
|
17
|
+
getParentNode: atree.getParentNode,
|
|
18
|
+
getChildNodes: atree.getChildNodes,
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
},{"./lib/atree.js":2,"./lib/name.js":5,"./lib/query.js":6}],2:[function(require,module,exports){
|
|
22
|
+
var attrs = require('./attrs');
|
|
23
|
+
|
|
24
|
+
var _getOwner = function(node) {
|
|
25
|
+
if (node.nodeType === node.ELEMENT_NODE && node.id) {
|
|
26
|
+
var owner = document.querySelector('[aria-owns~="' + CSS.escape(node.id) + '"]');
|
|
27
|
+
if (owner) {
|
|
28
|
+
return owner;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
var _getParentNode = function(node) {
|
|
34
|
+
return _getOwner(node) || node.parentNode;
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
var detectLoop = function(node) {
|
|
38
|
+
var tmp = _getParentNode(node);
|
|
39
|
+
while (tmp) {
|
|
40
|
+
if (tmp === node) {
|
|
41
|
+
return true;
|
|
42
|
+
}
|
|
43
|
+
tmp = _getParentNode(tmp);
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
var getOwner = function(node) {
|
|
48
|
+
if (node.nodeType === node.ELEMENT_NODE && node.id) {
|
|
49
|
+
var owner = document.querySelector('[aria-owns~="' + CSS.escape(node.id) + '"]');
|
|
50
|
+
if (owner && !detectLoop(node)) {
|
|
51
|
+
return owner;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
var getParentNode = function(node) {
|
|
57
|
+
return getOwner(node) || node.parentNode;
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
var isHidden = function(node) {
|
|
61
|
+
return node.nodeType === node.ELEMENT_NODE && attrs.getAttribute(node, 'hidden');
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
var getChildNodes = function(node) {
|
|
65
|
+
var childNodes = [];
|
|
66
|
+
|
|
67
|
+
for (var i = 0; i < node.childNodes.length; i++) {
|
|
68
|
+
var child = node.childNodes[i];
|
|
69
|
+
if (!getOwner(child) && !isHidden(child)) {
|
|
70
|
+
childNodes.push(child);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
if (node.nodeType === node.ELEMENT_NODE) {
|
|
75
|
+
var owns = attrs.getAttribute(node, 'owns') || [];
|
|
76
|
+
for (var i = 0; i < owns.length; i++) {
|
|
77
|
+
var child = document.getElementById(owns[i]);
|
|
78
|
+
// double check with getOwner for consistency
|
|
79
|
+
if (child && getOwner(child) === node && !isHidden(child)) {
|
|
80
|
+
childNodes.push(child);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
return childNodes;
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
var walk = function(root, fn) {
|
|
89
|
+
fn(root);
|
|
90
|
+
getChildNodes(root).forEach(function(child) {
|
|
91
|
+
walk(child, fn);
|
|
92
|
+
});
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
var searchUp = function(node, test) {
|
|
96
|
+
var candidate = getParentNode(node);
|
|
97
|
+
if (candidate) {
|
|
98
|
+
if (test(candidate)) {
|
|
99
|
+
return candidate;
|
|
100
|
+
} else {
|
|
101
|
+
return searchUp(candidate, test);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
module.exports = {
|
|
107
|
+
'getParentNode': getParentNode,
|
|
108
|
+
'getChildNodes': getChildNodes,
|
|
109
|
+
'walk': walk,
|
|
110
|
+
'searchUp': searchUp,
|
|
111
|
+
};
|
|
112
|
+
|
|
113
|
+
},{"./attrs":3}],3:[function(require,module,exports){
|
|
114
|
+
var constants = require('./constants.js');
|
|
115
|
+
|
|
116
|
+
// candidates can be passed for performance optimization
|
|
117
|
+
var getRole = function(el, candidates) {
|
|
118
|
+
if (el.hasAttribute('role')) {
|
|
119
|
+
return el.getAttribute('role');
|
|
120
|
+
}
|
|
121
|
+
for (var role in constants.roles) {
|
|
122
|
+
var selector = (constants.roles[role].selectors || []).join(',');
|
|
123
|
+
if (selector && (!candidates || candidates.includes(role)) && el.matches(selector)) {
|
|
124
|
+
return role;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
if (!candidates ||
|
|
129
|
+
candidates.includes('banner') ||
|
|
130
|
+
candidates.includes('contentinfo')) {
|
|
131
|
+
if (!el.matches(constants.scoped)) {
|
|
132
|
+
if (el.matches('header')) {
|
|
133
|
+
return 'banner';
|
|
134
|
+
}
|
|
135
|
+
if (el.matches('footer')) {
|
|
136
|
+
return 'contentinfo';
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
};
|
|
141
|
+
|
|
142
|
+
var hasRole = function(el, roles) {
|
|
143
|
+
var candidates = [].concat.apply([], roles.map(function(role) {
|
|
144
|
+
return (constants.roles[role] || {}).subRoles || [role];
|
|
145
|
+
}));
|
|
146
|
+
var actual = getRole(el, candidates);
|
|
147
|
+
return candidates.includes(actual);
|
|
148
|
+
};
|
|
149
|
+
|
|
150
|
+
var getAttribute = function(el, key) {
|
|
151
|
+
if (constants.attributeStrongMapping.hasOwnProperty(key)) {
|
|
152
|
+
var value = el[constants.attributeStrongMapping[key]];
|
|
153
|
+
if (value) {
|
|
154
|
+
return value;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
if (key === 'readonly' && el.contentEditable) {
|
|
158
|
+
return false;
|
|
159
|
+
} else if (key === 'invalid' && el.checkValidity) {
|
|
160
|
+
return !el.checkValidity();
|
|
161
|
+
} else if (key === 'hidden') {
|
|
162
|
+
// workaround for chromium
|
|
163
|
+
if (el.matches('noscript')) {
|
|
164
|
+
return true;
|
|
165
|
+
}
|
|
166
|
+
var style = window.getComputedStyle(el);
|
|
167
|
+
if (style.display === 'none' || style.visibility === 'hidden') {
|
|
168
|
+
return true;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
var type = constants.attributes[key];
|
|
173
|
+
var raw = el.getAttribute('aria-' + key);
|
|
174
|
+
|
|
175
|
+
if (raw) {
|
|
176
|
+
if (type === 'bool') {
|
|
177
|
+
return raw === 'true';
|
|
178
|
+
} else if (type === 'tristate') {
|
|
179
|
+
return raw === 'true' ? true : raw === 'false' ? false : 'mixed';
|
|
180
|
+
} else if (type === 'bool-undefined') {
|
|
181
|
+
return raw === 'true' ? true : raw === 'false' ? false : undefined;
|
|
182
|
+
} else if (type === 'id-list') {
|
|
183
|
+
return raw.split(/\s+/);
|
|
184
|
+
} else if (type === 'integer') {
|
|
185
|
+
return parseInt(raw, 10);
|
|
186
|
+
} else if (type === 'number') {
|
|
187
|
+
return parseFloat(raw);
|
|
188
|
+
} else if (type === 'token-list') {
|
|
189
|
+
return raw.split(/\s+/);
|
|
190
|
+
} else {
|
|
191
|
+
return raw;
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
// TODO
|
|
196
|
+
// autocomplete
|
|
197
|
+
// contextmenu -> aria-haspopup
|
|
198
|
+
// indeterminate -> aria-checked="mixed"
|
|
199
|
+
// list -> aria-controls
|
|
200
|
+
|
|
201
|
+
if (key === 'level') {
|
|
202
|
+
for (var i = 1; i <= 6; i++) {
|
|
203
|
+
if (el.tagName.toLowerCase() === 'h' + i) {
|
|
204
|
+
return i;
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
} else if (constants.attributeWeakMapping.hasOwnProperty(key)) {
|
|
208
|
+
return el[constants.attributeWeakMapping[key]];
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
if (key in constants.attrsWithDefaults) {
|
|
212
|
+
var role = getRole(el);
|
|
213
|
+
var defaults = (constants.roles[role] || {}).defaults;
|
|
214
|
+
if (defaults && defaults.hasOwnProperty(key)) {
|
|
215
|
+
return defaults[key];
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
if (type === 'bool' || type === 'tristate') {
|
|
220
|
+
return false;
|
|
221
|
+
}
|
|
222
|
+
};
|
|
223
|
+
|
|
224
|
+
module.exports = {
|
|
225
|
+
getRole: getRole,
|
|
226
|
+
hasRole: hasRole,
|
|
227
|
+
getAttribute: getAttribute,
|
|
15
228
|
};
|
|
16
229
|
|
|
17
|
-
},{"./
|
|
230
|
+
},{"./constants.js":4}],4:[function(require,module,exports){
|
|
231
|
+
// https://www.w3.org/TR/wai-aria/#state_prop_def
|
|
18
232
|
exports.attributes = {
|
|
19
|
-
|
|
233
|
+
'activedescendant': 'id',
|
|
234
|
+
'atomic': 'bool',
|
|
20
235
|
'autocomplete': 'token',
|
|
236
|
+
'busy': 'bool',
|
|
21
237
|
'checked': 'tristate',
|
|
238
|
+
'colcount': 'int',
|
|
239
|
+
'colindex': 'int',
|
|
240
|
+
'colspan': 'int',
|
|
241
|
+
'controls': 'id-list',
|
|
22
242
|
'current': 'token',
|
|
243
|
+
'describedby': 'id-list',
|
|
244
|
+
'details': 'id',
|
|
23
245
|
'disabled': 'bool',
|
|
246
|
+
'dropeffect': 'token-list',
|
|
247
|
+
'errormessage': 'id',
|
|
24
248
|
'expanded': 'bool-undefined',
|
|
249
|
+
'flowto': 'id-list',
|
|
250
|
+
'grabbed': 'bool-undefined',
|
|
25
251
|
'haspopup': 'token',
|
|
26
|
-
'hidden': 'bool',
|
|
252
|
+
'hidden': 'bool-undefined',
|
|
27
253
|
'invalid': 'token',
|
|
28
254
|
'keyshortcuts': 'string',
|
|
29
255
|
'label': 'string',
|
|
256
|
+
'labelledby': 'id-list',
|
|
30
257
|
'level': 'int',
|
|
258
|
+
'live': 'token',
|
|
31
259
|
'modal': 'bool',
|
|
32
260
|
'multiline': 'bool',
|
|
33
261
|
'multiselectable': 'bool',
|
|
34
262
|
'orientation': 'token',
|
|
263
|
+
'owns': 'id-list',
|
|
35
264
|
'placeholder': 'string',
|
|
265
|
+
'posinset': 'int',
|
|
36
266
|
'pressed': 'tristate',
|
|
37
267
|
'readonly': 'bool',
|
|
268
|
+
'relevant': 'token-list',
|
|
38
269
|
'required': 'bool',
|
|
39
270
|
'roledescription': 'string',
|
|
40
|
-
'selected': 'bool-undefined',
|
|
41
|
-
'valuemax': 'number',
|
|
42
|
-
'valuemin': 'number',
|
|
43
|
-
'valuenow': 'number',
|
|
44
|
-
'valuetext': 'string',
|
|
45
|
-
|
|
46
|
-
// live
|
|
47
|
-
'atomic': 'bool',
|
|
48
|
-
'busy': 'bool',
|
|
49
|
-
'live': 'token',
|
|
50
|
-
'relevant': 'token-list',
|
|
51
|
-
|
|
52
|
-
// dragndrop
|
|
53
|
-
'dropeffect': 'token-list',
|
|
54
|
-
'grabbed': 'bool-undefined',
|
|
55
|
-
|
|
56
|
-
// relationship
|
|
57
|
-
'activedescendant': 'id',
|
|
58
|
-
'colcount': 'int',
|
|
59
|
-
'colindex': 'int',
|
|
60
|
-
'colspan': 'int',
|
|
61
|
-
'controls': 'id-list',
|
|
62
|
-
'describedby': 'id-list',
|
|
63
|
-
'details': 'id',
|
|
64
|
-
'errormessage': 'id',
|
|
65
|
-
'flowto': 'id-list',
|
|
66
|
-
'labelledby': 'id-list',
|
|
67
|
-
'owns': 'id-list',
|
|
68
|
-
'posinset': 'int',
|
|
69
271
|
'rowcount': 'int',
|
|
70
272
|
'rowindex': 'int',
|
|
71
273
|
'rowspan': 'int',
|
|
274
|
+
'selected': 'bool-undefined',
|
|
72
275
|
'setsize': 'int',
|
|
73
276
|
'sort': 'token',
|
|
277
|
+
'valuemax': 'number',
|
|
278
|
+
'valuemin': 'number',
|
|
279
|
+
'valuenow': 'number',
|
|
280
|
+
'valuetext': 'string',
|
|
74
281
|
};
|
|
75
282
|
|
|
76
283
|
exports.attributeStrongMapping = {
|
|
77
284
|
'disabled': 'disabled',
|
|
78
|
-
'hidden': 'hidden',
|
|
79
285
|
'placeholder': 'placeholder',
|
|
80
286
|
'readonly': 'readOnly',
|
|
81
287
|
'required': 'required',
|
|
@@ -90,209 +296,506 @@ exports.attributeWeakMapping = {
|
|
|
90
296
|
'selected': 'selected',
|
|
91
297
|
};
|
|
92
298
|
|
|
93
|
-
// https://www.w3.org/TR/html-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
'
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
299
|
+
// https://www.w3.org/TR/html-aam-1.0/#html-element-role-mappings
|
|
300
|
+
// https://www.w3.org/TR/wai-aria/roles
|
|
301
|
+
exports.roles = {
|
|
302
|
+
alert: {
|
|
303
|
+
childRoles: ['alertdialog'],
|
|
304
|
+
defaults: {
|
|
305
|
+
'live': 'assertive',
|
|
306
|
+
'atomic': true,
|
|
307
|
+
},
|
|
308
|
+
},
|
|
309
|
+
article: {
|
|
310
|
+
selectors: ['article'],
|
|
311
|
+
},
|
|
312
|
+
blockquote: {
|
|
313
|
+
selectors: ['blockquote'],
|
|
314
|
+
},
|
|
315
|
+
button: {
|
|
316
|
+
selectors: [
|
|
317
|
+
'button',
|
|
318
|
+
'input[type="button"]',
|
|
319
|
+
'input[type="image"]',
|
|
320
|
+
'input[type="reset"]',
|
|
321
|
+
'input[type="submit"]',
|
|
322
|
+
'summary',
|
|
323
|
+
],
|
|
324
|
+
nameFromContents: true,
|
|
325
|
+
},
|
|
326
|
+
caption: {
|
|
327
|
+
selectors: ['caption'], // not sure about figcaption, ARIA and HTML-AAM differ
|
|
328
|
+
},
|
|
329
|
+
cell: {
|
|
330
|
+
selectors: ['td'],
|
|
331
|
+
childRoles: ['gridcell', 'rowheader'],
|
|
332
|
+
nameFromContents: true,
|
|
333
|
+
},
|
|
334
|
+
checkbox: {
|
|
335
|
+
selectors: ['input[type="checkbox"]'],
|
|
336
|
+
childRoles: ['switch'],
|
|
337
|
+
nameFromContents: true,
|
|
338
|
+
},
|
|
339
|
+
code: {
|
|
340
|
+
selectors: ['code'],
|
|
341
|
+
},
|
|
342
|
+
columnheader: {
|
|
343
|
+
selectors: ['th[scope="col"]'],
|
|
344
|
+
nameFromContents: true,
|
|
345
|
+
},
|
|
346
|
+
combobox: {
|
|
347
|
+
selectors: [
|
|
107
348
|
'input:not([type])[list]',
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
'
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
349
|
+
'input[type="email"][list]',
|
|
350
|
+
'input[type="search"][list]',
|
|
351
|
+
'input[type="tel"][list]',
|
|
352
|
+
'input[type="text"][list]',
|
|
353
|
+
'input[type="url"][list]',
|
|
354
|
+
'select:not([size]):not([multiple])',
|
|
355
|
+
'select[size="0"]:not([multiple])',
|
|
356
|
+
'select[size="1"]:not([multiple])',
|
|
357
|
+
],
|
|
358
|
+
defaults: {
|
|
359
|
+
'haspopup': 'listbox',
|
|
360
|
+
},
|
|
361
|
+
},
|
|
362
|
+
command: {
|
|
363
|
+
childRoles: ['button', 'link', 'menuitem'],
|
|
364
|
+
},
|
|
365
|
+
complementary: {
|
|
366
|
+
selectors: ['aside'],
|
|
367
|
+
},
|
|
368
|
+
composite: {
|
|
369
|
+
childRoles: ['grid', 'select', 'spinbutton', 'tablist'],
|
|
370
|
+
},
|
|
371
|
+
definition: {
|
|
372
|
+
selectors: ['dd'],
|
|
373
|
+
},
|
|
374
|
+
deletion: {
|
|
375
|
+
selectors: ['del'],
|
|
376
|
+
},
|
|
377
|
+
dialog: {
|
|
378
|
+
selectors: ['dialog'],
|
|
379
|
+
childRoles: ['alertdialog'],
|
|
380
|
+
},
|
|
381
|
+
'doc-backlink': {
|
|
382
|
+
nameFromContents: true,
|
|
383
|
+
},
|
|
384
|
+
'doc-biblioref': {
|
|
385
|
+
nameFromContents: true,
|
|
386
|
+
},
|
|
387
|
+
'doc-glossref': {
|
|
388
|
+
nameFromContents: true,
|
|
389
|
+
},
|
|
390
|
+
'doc-noteref': {
|
|
391
|
+
nameFromContents: true,
|
|
392
|
+
},
|
|
393
|
+
'doc-pagebreak': {
|
|
394
|
+
nameFromContents: true,
|
|
395
|
+
},
|
|
396
|
+
'doc-subtitle': {
|
|
397
|
+
nameFromContents: true,
|
|
398
|
+
},
|
|
399
|
+
document: {
|
|
400
|
+
selector: ['html'],
|
|
401
|
+
childRoles: ['article', 'graphics-document'],
|
|
402
|
+
},
|
|
403
|
+
emphasis: {
|
|
404
|
+
selectors: ['em'],
|
|
405
|
+
},
|
|
406
|
+
figure: {
|
|
407
|
+
selectors: ['figure'],
|
|
408
|
+
childRoles: ['doc-example'],
|
|
409
|
+
},
|
|
410
|
+
form: {
|
|
411
|
+
selectors: ['form[aria-label]', 'form[aria-labelledby]', 'form[title]'],
|
|
412
|
+
},
|
|
413
|
+
generic: {
|
|
414
|
+
selectors: [
|
|
415
|
+
'body',
|
|
416
|
+
'div',
|
|
417
|
+
'form:not([aria-label]):not([aria-labelledby]):not([title])',
|
|
418
|
+
'hgroup',
|
|
419
|
+
'span',
|
|
420
|
+
],
|
|
421
|
+
},
|
|
422
|
+
grid: {
|
|
423
|
+
childRoles: ['treegrid'],
|
|
424
|
+
},
|
|
425
|
+
gridcell: {
|
|
426
|
+
childRoles: ['columnheader', 'rowheader'],
|
|
427
|
+
nameFromContents: true,
|
|
428
|
+
},
|
|
429
|
+
group: {
|
|
430
|
+
selectors: ['details', 'fieldset', 'optgroup'],
|
|
431
|
+
childRoles: ['row', 'select', 'toolbar', 'graphics-object'],
|
|
432
|
+
},
|
|
433
|
+
heading: {
|
|
434
|
+
selectors: ['h1', 'h2', 'h3', 'h4', 'h5', 'h6'],
|
|
435
|
+
nameFromContents: true,
|
|
436
|
+
},
|
|
437
|
+
img: {
|
|
438
|
+
selectors: ['img:not([alt=""])', 'graphics-symbol'],
|
|
439
|
+
childRoles: ['doc-cover'],
|
|
440
|
+
},
|
|
441
|
+
input: {
|
|
442
|
+
childRoles: ['checkbox', 'combobox', 'option', 'radio', 'slider', 'spinbutton', 'textbox'],
|
|
443
|
+
},
|
|
444
|
+
insertion: {
|
|
445
|
+
selectors: ['ins'],
|
|
446
|
+
},
|
|
447
|
+
landmark: {
|
|
448
|
+
childRoles: [
|
|
449
|
+
'banner',
|
|
450
|
+
'complementary',
|
|
451
|
+
'contentinfo',
|
|
452
|
+
'doc-acknowledgments',
|
|
453
|
+
'doc-afterword',
|
|
454
|
+
'doc-appendix',
|
|
455
|
+
'doc-bibliography',
|
|
456
|
+
'doc-chapter',
|
|
457
|
+
'doc-conclusion',
|
|
458
|
+
'doc-credits',
|
|
459
|
+
'doc-endnotes',
|
|
460
|
+
'doc-epilogue',
|
|
461
|
+
'doc-errata',
|
|
462
|
+
'doc-foreword',
|
|
463
|
+
'doc-glossary',
|
|
464
|
+
'doc-introduction',
|
|
465
|
+
'doc-part',
|
|
466
|
+
'doc-preface',
|
|
467
|
+
'doc-prologue',
|
|
468
|
+
'form',
|
|
469
|
+
'main',
|
|
470
|
+
'navigation',
|
|
471
|
+
'region',
|
|
472
|
+
'search',
|
|
473
|
+
],
|
|
474
|
+
},
|
|
475
|
+
link: {
|
|
476
|
+
selectors: ['a[href]', 'area[href]', 'link[href]'],
|
|
477
|
+
childRoles: ['doc-backlink', 'doc-biblioref', 'doc-glossref', 'doc-noteref'],
|
|
478
|
+
nameFromContents: true,
|
|
479
|
+
},
|
|
480
|
+
list: {
|
|
481
|
+
selectors: ['ol', 'ul', 'menu'],
|
|
482
|
+
childRoles: ['directory', 'feed'],
|
|
483
|
+
},
|
|
484
|
+
listbox: {
|
|
485
|
+
selectors: [
|
|
486
|
+
'datalist',
|
|
487
|
+
'select[multiple]',
|
|
488
|
+
'select[size]:not([size="0"]):not([size="1"])',
|
|
489
|
+
],
|
|
490
|
+
defaults: {
|
|
491
|
+
'orientation': 'vertical',
|
|
492
|
+
},
|
|
493
|
+
},
|
|
494
|
+
listitem: {
|
|
495
|
+
selectors: ['ul > li', 'ol > li', 'menu > li'],
|
|
496
|
+
childRoles: ['treeitem'],
|
|
497
|
+
},
|
|
498
|
+
log: {
|
|
499
|
+
defaults: {
|
|
500
|
+
'live': 'polite',
|
|
501
|
+
},
|
|
502
|
+
},
|
|
503
|
+
main: {
|
|
504
|
+
selectors: ['main'],
|
|
505
|
+
},
|
|
506
|
+
math: {
|
|
507
|
+
selectors: ['math'],
|
|
508
|
+
},
|
|
509
|
+
meter: {
|
|
510
|
+
selectors: ['meter'],
|
|
511
|
+
defaults: {
|
|
512
|
+
'valuemin': 0,
|
|
513
|
+
'valuemax': 100,
|
|
514
|
+
},
|
|
515
|
+
},
|
|
516
|
+
menu: {
|
|
517
|
+
childRoles: ['menubar'],
|
|
518
|
+
defaults: {
|
|
519
|
+
'orientation': 'vertical',
|
|
520
|
+
},
|
|
521
|
+
},
|
|
522
|
+
menubar: {
|
|
523
|
+
defaults: {
|
|
524
|
+
'orientation': 'horizontal',
|
|
525
|
+
},
|
|
526
|
+
},
|
|
527
|
+
menuitem: {
|
|
528
|
+
selectors: ['menuitem[type="command"]'],
|
|
529
|
+
childRoles: ['menuitemcheckbox'],
|
|
530
|
+
nameFromContents: true,
|
|
531
|
+
},
|
|
532
|
+
menuitemcheckbox: {
|
|
533
|
+
selectors: ['menuitem[type="checkbox"]'],
|
|
534
|
+
childRoles: ['menuitemradio'],
|
|
535
|
+
nameFromContents: true,
|
|
536
|
+
},
|
|
537
|
+
menuitemradio: {
|
|
538
|
+
selectors: ['menuitem[type="radio"]'],
|
|
539
|
+
nameFromContents: true,
|
|
540
|
+
},
|
|
541
|
+
navigation: {
|
|
542
|
+
selectors: ['nav'],
|
|
543
|
+
childRoles: ['doc-index', 'doc-pagelist', 'doc-toc'],
|
|
544
|
+
},
|
|
545
|
+
note: {
|
|
546
|
+
childRoles: ['doc-notice', 'doc-tip'],
|
|
547
|
+
},
|
|
548
|
+
option: {
|
|
549
|
+
selectors: ['option'],
|
|
550
|
+
childRoles: ['treeitem'],
|
|
551
|
+
nameFromContents: true,
|
|
552
|
+
defaults: {
|
|
553
|
+
'selected': 'false',
|
|
554
|
+
},
|
|
555
|
+
},
|
|
556
|
+
paragraph: {
|
|
557
|
+
selectors: ['p'],
|
|
558
|
+
},
|
|
559
|
+
progressbar: {
|
|
560
|
+
selectors: ['progress'],
|
|
561
|
+
defaults: {
|
|
562
|
+
'valuemin': 0,
|
|
563
|
+
'valuemax': 100,
|
|
564
|
+
},
|
|
565
|
+
},
|
|
566
|
+
radio: {
|
|
567
|
+
selectors: ['input[type="radio"]'],
|
|
568
|
+
nameFromContents: true,
|
|
569
|
+
},
|
|
570
|
+
range: {
|
|
571
|
+
childRoles: ['meter', 'progressbar', 'scrollbar', 'slider', 'spinbutton'],
|
|
572
|
+
},
|
|
573
|
+
region: {
|
|
574
|
+
selectors: ['section[aria-label]', 'section[aria-labelledby]', 'section[title]'],
|
|
575
|
+
},
|
|
576
|
+
roletype: {
|
|
577
|
+
childRoles: ['structure', 'widget', 'window'],
|
|
578
|
+
},
|
|
579
|
+
row: {
|
|
580
|
+
selectors: ['tr'],
|
|
581
|
+
nameFromContents: true,
|
|
582
|
+
},
|
|
583
|
+
rowgroup: {
|
|
584
|
+
selectors: ['tbody', 'thead', 'tfoot'],
|
|
585
|
+
},
|
|
586
|
+
rowheader: {
|
|
587
|
+
selectors: ['th[scope="row"]'],
|
|
588
|
+
nameFromContents: true,
|
|
589
|
+
},
|
|
590
|
+
scrollbar: {
|
|
591
|
+
defaults: {
|
|
592
|
+
'orientation': 'vertical',
|
|
593
|
+
'valuemin': 0,
|
|
594
|
+
'valuemax': 100,
|
|
595
|
+
// FIXME: halfway between actual valuemin and valuemax
|
|
596
|
+
'valuenow': 50,
|
|
597
|
+
},
|
|
598
|
+
},
|
|
599
|
+
searchbox: {
|
|
600
|
+
selectors: ['input[type="search"]:not([list])'],
|
|
601
|
+
},
|
|
602
|
+
section: {
|
|
603
|
+
childRoles: [
|
|
604
|
+
'alert',
|
|
605
|
+
'blockquote',
|
|
606
|
+
'caption',
|
|
607
|
+
'cell',
|
|
608
|
+
'code',
|
|
609
|
+
'definition',
|
|
610
|
+
'deletion',
|
|
611
|
+
'doc-abstract',
|
|
612
|
+
'doc-colophon',
|
|
613
|
+
'doc-credit',
|
|
614
|
+
'doc-dedication',
|
|
615
|
+
'doc-epigraph',
|
|
616
|
+
'doc-footnote',
|
|
617
|
+
'doc-pagefooter',
|
|
618
|
+
'doc-pageheader',
|
|
619
|
+
'doc-pullquote',
|
|
620
|
+
'doc-qna',
|
|
621
|
+
'emphasis',
|
|
622
|
+
'figure',
|
|
623
|
+
'group',
|
|
624
|
+
'img',
|
|
625
|
+
'insertion',
|
|
626
|
+
'landmark',
|
|
627
|
+
'list',
|
|
628
|
+
'listitem',
|
|
629
|
+
'log',
|
|
630
|
+
'marquee',
|
|
631
|
+
'math',
|
|
632
|
+
'note',
|
|
633
|
+
'paragraph',
|
|
634
|
+
'status',
|
|
635
|
+
'strong',
|
|
636
|
+
'subscript',
|
|
637
|
+
'superscript',
|
|
638
|
+
'table',
|
|
639
|
+
'tabpanel',
|
|
640
|
+
'term',
|
|
641
|
+
'time',
|
|
642
|
+
'tooltip',
|
|
643
|
+
],
|
|
644
|
+
},
|
|
645
|
+
sectionhead: {
|
|
646
|
+
childRoles: [
|
|
647
|
+
'columnheader',
|
|
648
|
+
'doc-subtitle',
|
|
649
|
+
'heading',
|
|
650
|
+
'rowheader',
|
|
651
|
+
'tab',
|
|
652
|
+
],
|
|
653
|
+
nameFromContents: true,
|
|
654
|
+
},
|
|
655
|
+
select: {
|
|
656
|
+
childRoles: ['listbox', 'menu', 'radiogroup', 'tree'],
|
|
657
|
+
},
|
|
658
|
+
separator: {
|
|
659
|
+
// assume not focussable because <hr> is not
|
|
660
|
+
selectors: ['hr'],
|
|
661
|
+
childRoles: ['doc-pagebreak'],
|
|
662
|
+
defaults: {
|
|
663
|
+
'orientation': 'horizontal',
|
|
664
|
+
},
|
|
665
|
+
},
|
|
666
|
+
slider: {
|
|
667
|
+
selectors: ['input[type="range"]'],
|
|
668
|
+
defaults: {
|
|
669
|
+
'orientation': 'horizontal',
|
|
670
|
+
'valuemin': 0,
|
|
671
|
+
'valuemax': 100,
|
|
672
|
+
// FIXME: halfway between actual valuemin and valuemax
|
|
673
|
+
'valuenow': 50,
|
|
674
|
+
},
|
|
675
|
+
},
|
|
676
|
+
spinbutton: {
|
|
677
|
+
selectors: ['input[type="number"]'],
|
|
678
|
+
defaults: {
|
|
679
|
+
// FIXME: no valuemin/valuemax/valuenow
|
|
680
|
+
},
|
|
681
|
+
},
|
|
682
|
+
status: {
|
|
683
|
+
selectors: ['output'],
|
|
684
|
+
childRoles: ['timer'],
|
|
685
|
+
defaults: {
|
|
686
|
+
'live': 'polite',
|
|
687
|
+
'atomic': true,
|
|
688
|
+
},
|
|
689
|
+
},
|
|
690
|
+
strong: {
|
|
691
|
+
selectors: ['strong'],
|
|
692
|
+
},
|
|
693
|
+
structure: {
|
|
694
|
+
childRoles: [
|
|
695
|
+
'application',
|
|
696
|
+
'document',
|
|
697
|
+
'none',
|
|
698
|
+
'generic',
|
|
699
|
+
'presentation',
|
|
700
|
+
'range',
|
|
701
|
+
'rowgroup',
|
|
702
|
+
'section',
|
|
703
|
+
'sectionhead',
|
|
704
|
+
'separator',
|
|
705
|
+
],
|
|
706
|
+
},
|
|
707
|
+
subscript: {
|
|
708
|
+
selectors: ['sub'],
|
|
709
|
+
},
|
|
710
|
+
superscript: {
|
|
711
|
+
selectors: ['sup'],
|
|
712
|
+
},
|
|
713
|
+
switch: {
|
|
714
|
+
nameFromContents: true,
|
|
715
|
+
},
|
|
716
|
+
tab: {
|
|
717
|
+
nameFromContents: true,
|
|
718
|
+
defaults: {
|
|
719
|
+
'selected': false,
|
|
720
|
+
},
|
|
721
|
+
},
|
|
722
|
+
table: {
|
|
723
|
+
selectors: ['table'],
|
|
724
|
+
childRoles: ['grid'],
|
|
725
|
+
},
|
|
726
|
+
tablist: {
|
|
727
|
+
defaults: {
|
|
728
|
+
'orientation': 'horizontal',
|
|
729
|
+
},
|
|
730
|
+
},
|
|
731
|
+
term: {
|
|
732
|
+
selectors: ['dfn', 'dt'],
|
|
733
|
+
},
|
|
734
|
+
textbox: {
|
|
735
|
+
selectors: [
|
|
736
|
+
'input:not([type]):not([list])',
|
|
737
|
+
'input[type="email"]:not([list])',
|
|
738
|
+
'input[type="tel"]:not([list])',
|
|
739
|
+
'input[type="text"]:not([list])',
|
|
740
|
+
'input[type="url"]:not([list])',
|
|
741
|
+
'textarea',
|
|
742
|
+
],
|
|
743
|
+
childRoles: ['searchbox'],
|
|
744
|
+
},
|
|
745
|
+
time: {
|
|
746
|
+
selectors: ['time'],
|
|
747
|
+
},
|
|
748
|
+
toolbar: {
|
|
749
|
+
defaults: {
|
|
750
|
+
'orientation': 'horizontal',
|
|
751
|
+
},
|
|
752
|
+
},
|
|
753
|
+
tooltip: {
|
|
754
|
+
nameFromContents: true,
|
|
755
|
+
},
|
|
756
|
+
tree: {
|
|
757
|
+
childRoles: ['treegrid'],
|
|
758
|
+
defaults: {
|
|
759
|
+
'orientation': 'vertical',
|
|
760
|
+
},
|
|
761
|
+
},
|
|
762
|
+
treeitem: {
|
|
763
|
+
nameFromContents: true,
|
|
764
|
+
},
|
|
765
|
+
widget: {
|
|
766
|
+
childRoles: [
|
|
767
|
+
'command',
|
|
768
|
+
'composite',
|
|
769
|
+
'gridcell',
|
|
770
|
+
'input',
|
|
771
|
+
'progressbar',
|
|
772
|
+
'row',
|
|
773
|
+
'scrollbar',
|
|
774
|
+
'tab',
|
|
775
|
+
],
|
|
776
|
+
},
|
|
777
|
+
window: {
|
|
778
|
+
childRoles: ['dialog'],
|
|
779
|
+
},
|
|
165
780
|
};
|
|
166
781
|
|
|
167
782
|
exports.scoped = [
|
|
168
|
-
'
|
|
783
|
+
'main *',
|
|
784
|
+
// https://www.w3.org/TR/html/dom.html#sectioning-content-2
|
|
785
|
+
'article *', 'aside *', 'nav *', 'section *',
|
|
786
|
+
// https://www.w3.org/TR/html/sections.html#sectioning-roots
|
|
787
|
+
'blockquote *', 'details *', 'dialog *', 'fieldset *', 'figure *', 'td *',
|
|
169
788
|
].join(',');
|
|
170
789
|
|
|
171
|
-
// https://www.w3.org/TR/wai-aria/roles
|
|
172
|
-
var subRoles = {
|
|
173
|
-
cell: ['gridcell', 'rowheader'],
|
|
174
|
-
command: ['button', 'link', 'menuitem'],
|
|
175
|
-
composite: ['grid', 'select', 'spinbutton', 'tablist'],
|
|
176
|
-
img: ['doc-cover'],
|
|
177
|
-
input: ['checkbox', 'option', 'radio', 'slider', 'spinbutton', 'textbox'],
|
|
178
|
-
landmark: [
|
|
179
|
-
'banner',
|
|
180
|
-
'complementary',
|
|
181
|
-
'contentinfo',
|
|
182
|
-
'doc-acknowledgments',
|
|
183
|
-
'doc-afterword',
|
|
184
|
-
'doc-appendix',
|
|
185
|
-
'doc-bibliography',
|
|
186
|
-
'doc-chapter',
|
|
187
|
-
'doc-conclusion',
|
|
188
|
-
'doc-credits',
|
|
189
|
-
'doc-endnotes',
|
|
190
|
-
'doc-epilogue',
|
|
191
|
-
'doc-errata',
|
|
192
|
-
'doc-foreword',
|
|
193
|
-
'doc-glossary',
|
|
194
|
-
'doc-introduction',
|
|
195
|
-
'doc-part',
|
|
196
|
-
'doc-preface',
|
|
197
|
-
'doc-prologue',
|
|
198
|
-
'form',
|
|
199
|
-
'main',
|
|
200
|
-
'navigation',
|
|
201
|
-
'region',
|
|
202
|
-
'search',
|
|
203
|
-
],
|
|
204
|
-
range: ['progressbar', 'scrollbar', 'slider', 'spinbutton'],
|
|
205
|
-
roletype: ['structure', 'widget', 'window'],
|
|
206
|
-
section: [
|
|
207
|
-
'alert',
|
|
208
|
-
'cell',
|
|
209
|
-
'definition',
|
|
210
|
-
'doc-abstract',
|
|
211
|
-
'doc-colophon',
|
|
212
|
-
'doc-credit',
|
|
213
|
-
'doc-dedication',
|
|
214
|
-
'doc-epigraph',
|
|
215
|
-
'doc-example',
|
|
216
|
-
'doc-footnote',
|
|
217
|
-
'doc-qna',
|
|
218
|
-
'figure',
|
|
219
|
-
'group',
|
|
220
|
-
'img',
|
|
221
|
-
'landmark',
|
|
222
|
-
'list',
|
|
223
|
-
'listitem',
|
|
224
|
-
'log',
|
|
225
|
-
'marquee',
|
|
226
|
-
'math',
|
|
227
|
-
'note',
|
|
228
|
-
'status',
|
|
229
|
-
'table',
|
|
230
|
-
'tabpanel',
|
|
231
|
-
'term',
|
|
232
|
-
'tooltip',
|
|
233
|
-
],
|
|
234
|
-
sectionhead: [
|
|
235
|
-
'columnheader',
|
|
236
|
-
'doc-subtitle',
|
|
237
|
-
'heading',
|
|
238
|
-
'rowheader',
|
|
239
|
-
'tab',
|
|
240
|
-
],
|
|
241
|
-
select: ['combobox', 'listbox', 'menu', 'radiogroup', 'tree'],
|
|
242
|
-
separator: ['doc-pagebreak'],
|
|
243
|
-
structure: [
|
|
244
|
-
'application',
|
|
245
|
-
'document',
|
|
246
|
-
'none',
|
|
247
|
-
'presentation',
|
|
248
|
-
'rowgroup',
|
|
249
|
-
'section',
|
|
250
|
-
'sectionhead',
|
|
251
|
-
'separator',
|
|
252
|
-
],
|
|
253
|
-
table: ['grid'],
|
|
254
|
-
textbox: ['searchbox'],
|
|
255
|
-
widget: [
|
|
256
|
-
'command',
|
|
257
|
-
'composite',
|
|
258
|
-
'gridcell',
|
|
259
|
-
'input',
|
|
260
|
-
'range',
|
|
261
|
-
'row',
|
|
262
|
-
'separator',
|
|
263
|
-
'tab',
|
|
264
|
-
],
|
|
265
|
-
window: ['dialog'],
|
|
266
|
-
alert: ['alertdialog'],
|
|
267
|
-
checkbox: ['menuitemcheckbox', 'switch'],
|
|
268
|
-
dialog: ['alertdialog'],
|
|
269
|
-
gridcell: ['columnheader', 'rowheader'],
|
|
270
|
-
menuitem: ['menuitemcheckbox'],
|
|
271
|
-
menuitemcheckbox: ['menuitemradio'],
|
|
272
|
-
option: ['treeitem'],
|
|
273
|
-
radio: ['menuitemradio'],
|
|
274
|
-
status: ['timer'],
|
|
275
|
-
grid: ['treegrid'],
|
|
276
|
-
menu: ['menubar'],
|
|
277
|
-
tree: ['treegrid'],
|
|
278
|
-
document: ['article', 'graphics-document'],
|
|
279
|
-
group: ['row', 'select', 'toolbar', 'graphics-object'],
|
|
280
|
-
link: ['doc-backlink', 'doc-biblioref', 'doc-glossref', 'doc-noteref'],
|
|
281
|
-
list: ['directory', 'feed'],
|
|
282
|
-
listitem: ['doc-biblioentry', 'doc-endnote', 'treeitem'],
|
|
283
|
-
navigation: ['doc-index', 'doc-pagelist', 'doc-toc'],
|
|
284
|
-
note: ['doc-notice', 'doc-tip'],
|
|
285
|
-
};
|
|
286
|
-
|
|
287
790
|
var getSubRoles = function(role) {
|
|
288
|
-
var children =
|
|
791
|
+
var children = (exports.roles[role] || {}).childRoles || [];
|
|
289
792
|
var descendents = children.map(getSubRoles);
|
|
290
793
|
|
|
291
794
|
var result = [role];
|
|
292
795
|
|
|
293
796
|
descendents.forEach(function(list) {
|
|
294
797
|
list.forEach(function(r) {
|
|
295
|
-
if (result.
|
|
798
|
+
if (!result.includes(r)) {
|
|
296
799
|
result.push(r);
|
|
297
800
|
}
|
|
298
801
|
});
|
|
@@ -301,38 +804,20 @@ var getSubRoles = function(role) {
|
|
|
301
804
|
return result;
|
|
302
805
|
};
|
|
303
806
|
|
|
304
|
-
exports.
|
|
305
|
-
for (var role in subRoles) {
|
|
306
|
-
exports.subRoles[role] = getSubRoles(role);
|
|
307
|
-
}
|
|
308
|
-
exports.subRoles['none'] = ['none', 'presentation'];
|
|
309
|
-
exports.subRoles['presentation'] = ['presentation', 'none'];
|
|
807
|
+
exports.attrsWithDefaults = [];
|
|
310
808
|
|
|
311
|
-
exports.
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
'menuitemcheckbox',
|
|
324
|
-
'menuitemradio',
|
|
325
|
-
'option',
|
|
326
|
-
'radio',
|
|
327
|
-
'row',
|
|
328
|
-
'rowgroup',
|
|
329
|
-
'rowheader',
|
|
330
|
-
'sectionhead',
|
|
331
|
-
'tab',
|
|
332
|
-
'tooltip',
|
|
333
|
-
'treeitem',
|
|
334
|
-
'switch',
|
|
335
|
-
];
|
|
809
|
+
for (var role in exports.roles) {
|
|
810
|
+
exports.roles[role].subRoles = getSubRoles(role);
|
|
811
|
+
for (var key in exports.roles[role].defaults) {
|
|
812
|
+
if (!exports.attrsWithDefaults.includes(key)) {
|
|
813
|
+
exports.attrsWithDefaults.push(key);
|
|
814
|
+
}
|
|
815
|
+
}
|
|
816
|
+
}
|
|
817
|
+
exports.roles['none'] = exports.roles['none'] || {};
|
|
818
|
+
exports.roles['none'].subRoles = ['none', 'presentation'];
|
|
819
|
+
exports.roles['presentation'] = exports.roles['presentation'] || {};
|
|
820
|
+
exports.roles['presentation'].subRoles = ['presentation', 'none'];
|
|
336
821
|
|
|
337
822
|
exports.nameFromDescendant = {
|
|
338
823
|
'figure': 'figcaption',
|
|
@@ -357,10 +842,10 @@ exports.labelable = [
|
|
|
357
842
|
'textarea',
|
|
358
843
|
];
|
|
359
844
|
|
|
360
|
-
},{}],
|
|
845
|
+
},{}],5:[function(require,module,exports){
|
|
361
846
|
var constants = require('./constants.js');
|
|
847
|
+
var atree = require('./atree.js');
|
|
362
848
|
var query = require('./query.js');
|
|
363
|
-
var util = require('./util.js');
|
|
364
849
|
|
|
365
850
|
var getPseudoContent = function(node, selector) {
|
|
366
851
|
var styles = window.getComputedStyle(node, selector);
|
|
@@ -380,24 +865,8 @@ var getPseudoContent = function(node, selector) {
|
|
|
380
865
|
}
|
|
381
866
|
};
|
|
382
867
|
|
|
383
|
-
var getContent = function(root,
|
|
384
|
-
var children =
|
|
385
|
-
|
|
386
|
-
for (var i = 0; i < root.childNodes.length; i++) {
|
|
387
|
-
var node = root.childNodes[i];
|
|
388
|
-
if (!node.id || !document.querySelector('[aria-owns~="' + node.id + '"]')) {
|
|
389
|
-
children.push(node);
|
|
390
|
-
}
|
|
391
|
-
}
|
|
392
|
-
|
|
393
|
-
var owns = query.getAttribute(root, 'owns') || [];
|
|
394
|
-
for (var i = 0; i < owns.length; i++) {
|
|
395
|
-
var child = document.getElementById(owns[i]);
|
|
396
|
-
if (child && child !== root && owned.indexOf(child.id) === -1) {
|
|
397
|
-
children.push(child);
|
|
398
|
-
owned.push(child.id);
|
|
399
|
-
}
|
|
400
|
-
}
|
|
868
|
+
var getContent = function(root, visited) {
|
|
869
|
+
var children = atree.getChildNodes(root);
|
|
401
870
|
|
|
402
871
|
var ret = '';
|
|
403
872
|
for (var i = 0; i < children.length; i++) {
|
|
@@ -410,9 +879,9 @@ var getContent = function(root, referenced, owned) {
|
|
|
410
879
|
} else if (window.getComputedStyle(node).display.substr(0, 6) === 'inline' &&
|
|
411
880
|
node.tagName.toLowerCase() !== 'input' &&
|
|
412
881
|
node.tagName.toLowerCase() !== 'img') { // https://github.com/w3c/accname/issues/3
|
|
413
|
-
ret += getName(node, true,
|
|
882
|
+
ret += getName(node, true, visited);
|
|
414
883
|
} else {
|
|
415
|
-
ret += ' ' + getName(node, true,
|
|
884
|
+
ret += ' ' + getName(node, true, visited) + ' ';
|
|
416
885
|
}
|
|
417
886
|
}
|
|
418
887
|
}
|
|
@@ -422,7 +891,7 @@ var getContent = function(root, referenced, owned) {
|
|
|
422
891
|
|
|
423
892
|
var allowNameFromContent = function(el) {
|
|
424
893
|
var role = query.getRole(el);
|
|
425
|
-
return role
|
|
894
|
+
return (constants.roles[role] || {}).nameFromContents;
|
|
426
895
|
};
|
|
427
896
|
|
|
428
897
|
var isLabelable = function(el) {
|
|
@@ -430,58 +899,46 @@ var isLabelable = function(el) {
|
|
|
430
899
|
return el.matches(selector);
|
|
431
900
|
};
|
|
432
901
|
|
|
433
|
-
// Control.labels is part of the standard, but not supported in most browsers
|
|
434
|
-
var getLabelNodes = function(element) {
|
|
435
|
-
var labels = [];
|
|
436
|
-
var labelable = constants.labelable.join(',');
|
|
437
|
-
util.walkDOM(document.body, function(node) {
|
|
438
|
-
if (node.tagName && node.tagName.toLowerCase() === 'label') {
|
|
439
|
-
if (node.getAttribute('for')) {
|
|
440
|
-
if (element.id && node.getAttribute('for') === element.id) {
|
|
441
|
-
labels.push(node);
|
|
442
|
-
}
|
|
443
|
-
} else if (node.querySelector(labelable) === element) {
|
|
444
|
-
labels.push(node);
|
|
445
|
-
}
|
|
446
|
-
}
|
|
447
|
-
});
|
|
448
|
-
return labels;
|
|
449
|
-
};
|
|
450
|
-
|
|
451
902
|
var isInLabelForOtherWidget = function(el) {
|
|
452
903
|
var label = el.parentElement.closest('label');
|
|
453
|
-
|
|
454
|
-
return label && ownLabels.indexOf(label) === -1;
|
|
904
|
+
return label && !Array.prototype.includes.call(el.labels, label);
|
|
455
905
|
};
|
|
456
906
|
|
|
457
|
-
var getName = function(el, recursive,
|
|
907
|
+
var getName = function(el, recursive, visited, directReference) {
|
|
458
908
|
var ret = '';
|
|
459
|
-
var owned = owned || [];
|
|
460
909
|
|
|
461
|
-
|
|
462
|
-
if (
|
|
463
|
-
|
|
910
|
+
visited = visited || [];
|
|
911
|
+
if (visited.includes(el)) {
|
|
912
|
+
if (!directReference) {
|
|
913
|
+
return '';
|
|
914
|
+
}
|
|
915
|
+
} else {
|
|
916
|
+
visited.push(el);
|
|
464
917
|
}
|
|
465
918
|
|
|
919
|
+
// A
|
|
920
|
+
// handled in atree
|
|
921
|
+
|
|
466
922
|
// B
|
|
467
923
|
if (!recursive && el.matches('[aria-labelledby]')) {
|
|
468
924
|
var ids = el.getAttribute('aria-labelledby').split(/\s+/);
|
|
469
925
|
var strings = ids.map(function(id) {
|
|
470
926
|
var label = document.getElementById(id);
|
|
471
|
-
return label ? getName(label, true,
|
|
927
|
+
return label ? getName(label, true, visited, true) : '';
|
|
472
928
|
});
|
|
473
929
|
ret = strings.join(' ');
|
|
474
930
|
}
|
|
475
931
|
|
|
476
932
|
// C
|
|
477
933
|
if (!ret.trim() && el.matches('[aria-label]')) {
|
|
934
|
+
// FIXME: may skip to 2E
|
|
478
935
|
ret = el.getAttribute('aria-label');
|
|
479
936
|
}
|
|
480
937
|
|
|
481
938
|
// D
|
|
482
939
|
if (!ret.trim() && !recursive && isLabelable(el)) {
|
|
483
|
-
var strings =
|
|
484
|
-
return getName(label, true,
|
|
940
|
+
var strings = Array.prototype.map.call(el.labels, function(label) {
|
|
941
|
+
return getName(label, true, visited);
|
|
485
942
|
});
|
|
486
943
|
ret = strings.join(' ');
|
|
487
944
|
}
|
|
@@ -499,7 +956,7 @@ var getName = function(el, recursive, referenced, owned) {
|
|
|
499
956
|
if (el.matches(selector)) {
|
|
500
957
|
var descendant = el.querySelector(constants.nameFromDescendant[selector]);
|
|
501
958
|
if (descendant) {
|
|
502
|
-
ret = getName(descendant, true,
|
|
959
|
+
ret = getName(descendant, true, visited);
|
|
503
960
|
}
|
|
504
961
|
}
|
|
505
962
|
}
|
|
@@ -513,7 +970,7 @@ var getName = function(el, recursive, referenced, owned) {
|
|
|
513
970
|
} else if (query.matches(el, 'combobox,listbox')) {
|
|
514
971
|
var selected = query.querySelector(el, ':selected') || query.querySelector(el, 'option');
|
|
515
972
|
if (selected) {
|
|
516
|
-
ret = getName(selected, recursive,
|
|
973
|
+
ret = getName(selected, recursive, visited);
|
|
517
974
|
} else {
|
|
518
975
|
ret = el.value || '';
|
|
519
976
|
}
|
|
@@ -526,18 +983,9 @@ var getName = function(el, recursive, referenced, owned) {
|
|
|
526
983
|
// F
|
|
527
984
|
// FIXME: menu is not mentioned in the spec
|
|
528
985
|
if (!ret.trim() && (recursive || allowNameFromContent(el) || el.closest('label')) && !query.matches(el, 'menu')) {
|
|
529
|
-
ret = getContent(el,
|
|
530
|
-
}
|
|
531
|
-
|
|
532
|
-
// TODO: G
|
|
533
|
-
// TODO: H
|
|
534
|
-
|
|
535
|
-
// FIXME: not mentioned in the spec
|
|
536
|
-
if (!ret.trim() && query.matches(el, 'presentation')) {
|
|
537
|
-
return getContent(el, referenced, owned);
|
|
986
|
+
ret = getContent(el, visited);
|
|
538
987
|
}
|
|
539
988
|
|
|
540
|
-
// FIXME: not mentioned in the spec
|
|
541
989
|
if (!ret.trim()) {
|
|
542
990
|
for (var selector in constants.nameDefaults) {
|
|
543
991
|
if (el.matches(selector)) {
|
|
@@ -546,8 +994,12 @@ var getName = function(el, recursive, referenced, owned) {
|
|
|
546
994
|
}
|
|
547
995
|
}
|
|
548
996
|
|
|
997
|
+
// G/H
|
|
998
|
+
// handled in getContent
|
|
999
|
+
|
|
549
1000
|
// I
|
|
550
|
-
|
|
1001
|
+
// FIXME: presentation not mentioned in the spec
|
|
1002
|
+
if (!ret.trim() && !query.matches(el, 'presentation')) {
|
|
551
1003
|
ret = el.title || '';
|
|
552
1004
|
}
|
|
553
1005
|
|
|
@@ -562,13 +1014,12 @@ var getNameTrimmed = function(el) {
|
|
|
562
1014
|
|
|
563
1015
|
var getDescription = function(el) {
|
|
564
1016
|
var ret = '';
|
|
565
|
-
var owned = [];
|
|
566
1017
|
|
|
567
1018
|
if (el.matches('[aria-describedby]')) {
|
|
568
1019
|
var ids = el.getAttribute('aria-describedby').split(/\s+/);
|
|
569
1020
|
var strings = ids.map(function(id) {
|
|
570
1021
|
var label = document.getElementById(id);
|
|
571
|
-
return label ? getName(label, true
|
|
1022
|
+
return label ? getName(label, true) : '';
|
|
572
1023
|
});
|
|
573
1024
|
ret = strings.join(' ');
|
|
574
1025
|
} else if (el.title) {
|
|
@@ -591,194 +1042,69 @@ module.exports = {
|
|
|
591
1042
|
getDescription: getDescription,
|
|
592
1043
|
};
|
|
593
1044
|
|
|
594
|
-
},{"./
|
|
595
|
-
var
|
|
596
|
-
var
|
|
597
|
-
|
|
598
|
-
var getSubRoles = function(roles) {
|
|
599
|
-
return [].concat.apply([], roles.map(function(role) {
|
|
600
|
-
return constants.subRoles[role] || [role];
|
|
601
|
-
}));
|
|
602
|
-
};
|
|
603
|
-
|
|
604
|
-
// candidates can be passed for performance optimization
|
|
605
|
-
var _getRole = function(el, candidates) {
|
|
606
|
-
if (el.hasAttribute('role')) {
|
|
607
|
-
return el.getAttribute('role');
|
|
608
|
-
}
|
|
609
|
-
for (var role in constants.extraSelectors) {
|
|
610
|
-
var selector = constants.extraSelectors[role].join(',');
|
|
611
|
-
if ((!candidates || candidates.indexOf(role) !== -1) && el.matches(selector)) {
|
|
612
|
-
return role;
|
|
613
|
-
}
|
|
614
|
-
}
|
|
615
|
-
|
|
616
|
-
if (!candidates ||
|
|
617
|
-
candidates.indexOf('banner') !== -1 ||
|
|
618
|
-
candidates.indexOf('contentinfo') !== -1) {
|
|
619
|
-
var scoped = el.matches(constants.scoped);
|
|
620
|
-
|
|
621
|
-
if (el.matches('header') && !scoped) {
|
|
622
|
-
return 'banner';
|
|
623
|
-
}
|
|
624
|
-
if (el.matches('footer') && !scoped) {
|
|
625
|
-
return 'contentinfo';
|
|
626
|
-
}
|
|
627
|
-
}
|
|
628
|
-
};
|
|
629
|
-
|
|
630
|
-
var getAttribute = function(el, key, _hiddenRoot) {
|
|
631
|
-
if (key === 'hidden' && el === _hiddenRoot) { // used for name calculation
|
|
632
|
-
return false;
|
|
633
|
-
}
|
|
634
|
-
|
|
635
|
-
if (constants.attributeStrongMapping.hasOwnProperty(key)) {
|
|
636
|
-
var value = el[constants.attributeStrongMapping[key]];
|
|
637
|
-
if (value) {
|
|
638
|
-
return value;
|
|
639
|
-
}
|
|
640
|
-
}
|
|
641
|
-
if (key === 'readonly' && el.contentEditable) {
|
|
642
|
-
return false;
|
|
643
|
-
} else if (key === 'invalid' && el.checkValidity) {
|
|
644
|
-
return !el.checkValidity();
|
|
645
|
-
} else if (key === 'hidden') {
|
|
646
|
-
var style = window.getComputedStyle(el);
|
|
647
|
-
if (style.display === 'none' || style.visibility === 'hidden') {
|
|
648
|
-
return true;
|
|
649
|
-
}
|
|
650
|
-
}
|
|
651
|
-
|
|
652
|
-
var type = constants.attributes[key];
|
|
653
|
-
var raw = el.getAttribute('aria-' + key);
|
|
654
|
-
|
|
655
|
-
if (raw) {
|
|
656
|
-
if (type === 'bool') {
|
|
657
|
-
return raw === 'true';
|
|
658
|
-
} else if (type === 'tristate') {
|
|
659
|
-
return raw === 'true' ? true : raw === 'false' ? false : 'mixed';
|
|
660
|
-
} else if (type === 'bool-undefined') {
|
|
661
|
-
return raw === 'true' ? true : raw === 'false' ? false : undefined;
|
|
662
|
-
} else if (type === 'id-list') {
|
|
663
|
-
return raw.split(/\s+/);
|
|
664
|
-
} else if (type === 'integer') {
|
|
665
|
-
return parseInt(raw);
|
|
666
|
-
} else if (type === 'number') {
|
|
667
|
-
return parseFloat(raw);
|
|
668
|
-
} else if (type === 'token-list') {
|
|
669
|
-
return raw.split(/\s+/);
|
|
670
|
-
} else {
|
|
671
|
-
return raw;
|
|
672
|
-
}
|
|
673
|
-
}
|
|
674
|
-
|
|
675
|
-
// TODO
|
|
676
|
-
// autocomplete
|
|
677
|
-
// contextmenu -> aria-haspopup
|
|
678
|
-
// indeterminate -> aria-checked="mixed"
|
|
679
|
-
// list -> aria-controls
|
|
1045
|
+
},{"./atree.js":2,"./constants.js":4,"./query.js":6}],6:[function(require,module,exports){
|
|
1046
|
+
var attrs = require('./attrs.js');
|
|
1047
|
+
var atree = require('./atree.js');
|
|
680
1048
|
|
|
681
|
-
if (key === 'level') {
|
|
682
|
-
for (var i = 1; i <= 6; i++) {
|
|
683
|
-
if (el.tagName.toLowerCase() === 'h' + i) {
|
|
684
|
-
return i;
|
|
685
|
-
}
|
|
686
|
-
}
|
|
687
|
-
} else if (key === 'hidden') {
|
|
688
|
-
if (el.clientHeight === 0) { // rough check for performance
|
|
689
|
-
return el.parentNode && getAttribute(el.parentNode, 'hidden', _hiddenRoot);
|
|
690
|
-
}
|
|
691
|
-
} else if (constants.attributeWeakMapping.hasOwnProperty(key)) {
|
|
692
|
-
return el[constants.attributeWeakMapping[key]];
|
|
693
|
-
}
|
|
694
|
-
|
|
695
|
-
if (type === 'bool' || type === 'tristate') {
|
|
696
|
-
return false;
|
|
697
|
-
}
|
|
698
|
-
};
|
|
699
1049
|
|
|
700
1050
|
var matches = function(el, selector) {
|
|
701
1051
|
var actual;
|
|
702
1052
|
|
|
703
1053
|
if (selector.substr(0, 1) === ':') {
|
|
704
1054
|
var attr = selector.substr(1);
|
|
705
|
-
return getAttribute(el, attr);
|
|
1055
|
+
return attrs.getAttribute(el, attr);
|
|
706
1056
|
} else if (selector.substr(0, 1) === '[') {
|
|
707
1057
|
var match = /\[([a-z]+)="(.*)"\]/.exec(selector);
|
|
708
|
-
actual = getAttribute(el, match[1]);
|
|
1058
|
+
actual = attrs.getAttribute(el, match[1]);
|
|
709
1059
|
var rawValue = match[2];
|
|
710
|
-
return actual.toString()
|
|
1060
|
+
return actual.toString() === rawValue;
|
|
711
1061
|
} else {
|
|
712
|
-
|
|
713
|
-
actual = _getRole(el, candidates);
|
|
714
|
-
return candidates.indexOf(actual) !== -1;
|
|
1062
|
+
return attrs.hasRole(el, selector.split(','));
|
|
715
1063
|
}
|
|
716
1064
|
};
|
|
717
1065
|
|
|
718
1066
|
var _querySelector = function(all) {
|
|
719
1067
|
return function(root, role) {
|
|
720
1068
|
var results = [];
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
1069
|
+
try {
|
|
1070
|
+
atree.walk(root, function(node) {
|
|
1071
|
+
if (node.nodeType === node.ELEMENT_NODE) {
|
|
1072
|
+
// FIXME: skip hidden elements
|
|
1073
|
+
if (matches(node, role)) {
|
|
1074
|
+
results.push(node);
|
|
1075
|
+
if (!all) {
|
|
1076
|
+
throw 'StopIteration';
|
|
1077
|
+
}
|
|
728
1078
|
}
|
|
729
1079
|
}
|
|
1080
|
+
});
|
|
1081
|
+
} catch (e) {
|
|
1082
|
+
if (e !== 'StopIteration') {
|
|
1083
|
+
throw e;
|
|
730
1084
|
}
|
|
731
|
-
}
|
|
1085
|
+
}
|
|
732
1086
|
return all ? results : results[0];
|
|
733
1087
|
};
|
|
734
1088
|
};
|
|
735
1089
|
|
|
736
1090
|
var closest = function(el, selector) {
|
|
737
|
-
return
|
|
738
|
-
|
|
1091
|
+
return atree.searchUp(el, function(candidate) {
|
|
1092
|
+
if (candidate.nodeType === candidate.ELEMENT_NODE) {
|
|
1093
|
+
return matches(candidate, selector);
|
|
1094
|
+
}
|
|
739
1095
|
});
|
|
740
1096
|
};
|
|
741
1097
|
|
|
742
1098
|
module.exports = {
|
|
743
1099
|
getRole: function(el) {
|
|
744
|
-
return
|
|
1100
|
+
return attrs.getRole(el);
|
|
745
1101
|
},
|
|
746
|
-
getAttribute: getAttribute,
|
|
1102
|
+
getAttribute: attrs.getAttribute,
|
|
747
1103
|
matches: matches,
|
|
748
1104
|
querySelector: _querySelector(),
|
|
749
1105
|
querySelectorAll: _querySelector(true),
|
|
750
1106
|
closest: closest,
|
|
751
1107
|
};
|
|
752
1108
|
|
|
753
|
-
},{"./
|
|
754
|
-
var walkDOM = function(root, fn) {
|
|
755
|
-
if (fn(root) === false) {
|
|
756
|
-
return false;
|
|
757
|
-
}
|
|
758
|
-
var node = root.firstChild;
|
|
759
|
-
while (node) {
|
|
760
|
-
if (walkDOM(node, fn) === false) {
|
|
761
|
-
return false;
|
|
762
|
-
}
|
|
763
|
-
node = node.nextSibling;
|
|
764
|
-
}
|
|
765
|
-
};
|
|
766
|
-
|
|
767
|
-
var searchUp = function(el, test) {
|
|
768
|
-
var candidate = el.parentElement;
|
|
769
|
-
if (candidate) {
|
|
770
|
-
if (test(candidate)) {
|
|
771
|
-
return candidate;
|
|
772
|
-
} else {
|
|
773
|
-
return searchUp(candidate, test);
|
|
774
|
-
}
|
|
775
|
-
}
|
|
776
|
-
};
|
|
777
|
-
|
|
778
|
-
module.exports = {
|
|
779
|
-
walkDOM: walkDOM,
|
|
780
|
-
searchUp: searchUp,
|
|
781
|
-
};
|
|
782
|
-
|
|
783
|
-
},{}]},{},[1])(1)
|
|
1109
|
+
},{"./atree.js":2,"./attrs.js":3}]},{},[1])(1)
|
|
784
1110
|
});
|