aria-api 0.4.7 → 0.6.0
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/LICENSE +1 -1
- package/README.md +4 -4
- package/dist/aria.js +367 -170
- package/lib/atree.js +24 -24
- package/lib/attrs.js +47 -28
- package/lib/constants.js +218 -48
- package/lib/name.js +66 -56
- package/lib/query.js +12 -14
- package/package.json +3 -3
package/lib/atree.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
|
|
1
|
+
const attrs = require('./attrs');
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
const _getOwner = function(node, owners) {
|
|
4
4
|
if (node.nodeType === node.ELEMENT_NODE && node.id) {
|
|
5
|
-
|
|
5
|
+
const selector = '[aria-owns~="' + CSS.escape(node.id) + '"]';
|
|
6
6
|
if (owners) {
|
|
7
|
-
for (
|
|
7
|
+
for (const owner of owners) {
|
|
8
8
|
if (owner.matches(selector)) {
|
|
9
9
|
return owner;
|
|
10
10
|
}
|
|
@@ -15,12 +15,12 @@ var _getOwner = function(node, owners) {
|
|
|
15
15
|
}
|
|
16
16
|
};
|
|
17
17
|
|
|
18
|
-
|
|
18
|
+
const _getParentNode = function(node, owners) {
|
|
19
19
|
return _getOwner(node, owners) || node.parentNode;
|
|
20
20
|
};
|
|
21
21
|
|
|
22
|
-
|
|
23
|
-
|
|
22
|
+
const detectLoop = function(node, owners) {
|
|
23
|
+
const seen = [node];
|
|
24
24
|
while ((node = _getParentNode(node, owners))) {
|
|
25
25
|
if (seen.includes(node)) {
|
|
26
26
|
return true;
|
|
@@ -29,35 +29,35 @@ var detectLoop = function(node, owners) {
|
|
|
29
29
|
}
|
|
30
30
|
};
|
|
31
31
|
|
|
32
|
-
|
|
33
|
-
|
|
32
|
+
const getOwner = function(node, owners) {
|
|
33
|
+
const owner = _getOwner(node, owners);
|
|
34
34
|
if (owner && !detectLoop(node, owners)) {
|
|
35
35
|
return owner;
|
|
36
36
|
}
|
|
37
37
|
};
|
|
38
38
|
|
|
39
|
-
|
|
39
|
+
const getParentNode = function(node, owners) {
|
|
40
40
|
return getOwner(node, owners) || node.parentNode;
|
|
41
41
|
};
|
|
42
42
|
|
|
43
|
-
|
|
43
|
+
const isHidden = function(node) {
|
|
44
44
|
return node.nodeType === node.ELEMENT_NODE && attrs.getAttribute(node, 'hidden');
|
|
45
45
|
};
|
|
46
46
|
|
|
47
|
-
|
|
48
|
-
|
|
47
|
+
const getChildNodes = function(node, owners) {
|
|
48
|
+
const childNodes = [];
|
|
49
49
|
|
|
50
|
-
for (
|
|
51
|
-
|
|
50
|
+
for (let i = 0; i < node.childNodes.length; i++) {
|
|
51
|
+
const child = node.childNodes[i];
|
|
52
52
|
if (!getOwner(child, owners) && !isHidden(child)) {
|
|
53
53
|
childNodes.push(child);
|
|
54
54
|
}
|
|
55
55
|
}
|
|
56
56
|
|
|
57
57
|
if (node.nodeType === node.ELEMENT_NODE) {
|
|
58
|
-
|
|
59
|
-
for (
|
|
60
|
-
|
|
58
|
+
const owns = attrs.getAttribute(node, 'owns') || [];
|
|
59
|
+
for (let i = 0; i < owns.length; i++) {
|
|
60
|
+
const child = document.getElementById(owns[i]);
|
|
61
61
|
// double check with getOwner for consistency
|
|
62
62
|
if (child && getOwner(child, owners) === node && !isHidden(child)) {
|
|
63
63
|
childNodes.push(child);
|
|
@@ -68,18 +68,18 @@ var getChildNodes = function(node, owners) {
|
|
|
68
68
|
return childNodes;
|
|
69
69
|
};
|
|
70
70
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
71
|
+
const walk = function(root, fn) {
|
|
72
|
+
const owners = document.querySelectorAll('[aria-owns]');
|
|
73
|
+
let queue = [root];
|
|
74
74
|
while (queue.length) {
|
|
75
|
-
|
|
75
|
+
const item = queue.shift();
|
|
76
76
|
fn(item);
|
|
77
77
|
queue = getChildNodes(item, owners).concat(queue);
|
|
78
78
|
}
|
|
79
79
|
};
|
|
80
80
|
|
|
81
|
-
|
|
82
|
-
|
|
81
|
+
const searchUp = function(node, test) {
|
|
82
|
+
const candidate = getParentNode(node);
|
|
83
83
|
if (candidate) {
|
|
84
84
|
if (test(candidate)) {
|
|
85
85
|
return candidate;
|
package/lib/attrs.js
CHANGED
|
@@ -1,37 +1,56 @@
|
|
|
1
|
-
|
|
1
|
+
const constants = require('./constants.js');
|
|
2
|
+
|
|
3
|
+
var unique = function(arr) {
|
|
4
|
+
return arr.filter((a, i) => arr.indexOf(a) === i);
|
|
5
|
+
};
|
|
6
|
+
|
|
7
|
+
var flatten = function(arr) {
|
|
8
|
+
return [].concat.apply([], arr);
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
var normalizeRoles = function(roles, includeAbstract) {
|
|
12
|
+
return unique(roles
|
|
13
|
+
.map(r => constants.aliases[r] || r)
|
|
14
|
+
.filter(r => constants.roles[r])
|
|
15
|
+
.filter(r => includeAbstract || !constants.roles[r].abstract)
|
|
16
|
+
);
|
|
17
|
+
};
|
|
2
18
|
|
|
3
19
|
// candidates can be passed for performance optimization
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
20
|
+
const getRole = function(el, candidates) {
|
|
21
|
+
// TODO: filter out any invalid roles (e.g. name or context required)
|
|
22
|
+
const roles = normalizeRoles(
|
|
23
|
+
(el.getAttribute('role') || '').toLowerCase().split(/\s+/)
|
|
24
|
+
);
|
|
25
|
+
|
|
26
|
+
if (roles.length > 1 && candidates) {
|
|
27
|
+
return [roles, candidates];
|
|
28
|
+
} else if (roles.length) {
|
|
29
|
+
for (const role of roles) {
|
|
30
|
+
if (!candidates || candidates.includes(role)) {
|
|
31
|
+
return role;
|
|
32
|
+
}
|
|
11
33
|
}
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
if (r) {
|
|
17
|
-
var selector = (r.selectors || []).join(',');
|
|
18
|
-
if (selector && el.matches(selector)) {
|
|
34
|
+
} else {
|
|
35
|
+
for (const role of (candidates || Object.keys(constants.roles))) {
|
|
36
|
+
const r = constants.roles[role];
|
|
37
|
+
if (!r.abstract && r.selectors && el.matches(r.selectors.join(','))) {
|
|
19
38
|
return role;
|
|
20
39
|
}
|
|
21
40
|
}
|
|
22
41
|
}
|
|
23
42
|
};
|
|
24
43
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
return
|
|
28
|
-
})
|
|
29
|
-
return !!getRole(el,
|
|
44
|
+
const hasRole = function(el, roles) {
|
|
45
|
+
const subRoles = normalizeRoles(roles, true).map(role => {
|
|
46
|
+
return constants.roles[role].subRoles || [role];
|
|
47
|
+
});
|
|
48
|
+
return !!getRole(el, unique(flatten(subRoles)));
|
|
30
49
|
};
|
|
31
50
|
|
|
32
|
-
|
|
51
|
+
const getAttribute = function(el, key) {
|
|
33
52
|
if (constants.attributeStrongMapping.hasOwnProperty(key)) {
|
|
34
|
-
|
|
53
|
+
const value = el[constants.attributeStrongMapping[key]];
|
|
35
54
|
if (value) {
|
|
36
55
|
return value;
|
|
37
56
|
}
|
|
@@ -48,14 +67,14 @@ var getAttribute = function(el, key) {
|
|
|
48
67
|
if (el.matches('details:not([open]) > :not(summary)')) {
|
|
49
68
|
return true;
|
|
50
69
|
}
|
|
51
|
-
|
|
70
|
+
const style = window.getComputedStyle(el);
|
|
52
71
|
if (style.display === 'none' || style.visibility === 'hidden') {
|
|
53
72
|
return true;
|
|
54
73
|
}
|
|
55
74
|
}
|
|
56
75
|
|
|
57
|
-
|
|
58
|
-
|
|
76
|
+
const type = constants.attributes[key];
|
|
77
|
+
const raw = el.getAttribute('aria-' + key);
|
|
59
78
|
|
|
60
79
|
if (raw) {
|
|
61
80
|
if (type === 'bool') {
|
|
@@ -84,7 +103,7 @@ var getAttribute = function(el, key) {
|
|
|
84
103
|
// list -> aria-controls
|
|
85
104
|
|
|
86
105
|
if (key === 'level') {
|
|
87
|
-
for (
|
|
106
|
+
for (let i = 1; i <= 6; i++) {
|
|
88
107
|
if (el.tagName.toLowerCase() === 'h' + i) {
|
|
89
108
|
return i;
|
|
90
109
|
}
|
|
@@ -94,8 +113,8 @@ var getAttribute = function(el, key) {
|
|
|
94
113
|
}
|
|
95
114
|
|
|
96
115
|
if (key in constants.attrsWithDefaults) {
|
|
97
|
-
|
|
98
|
-
|
|
116
|
+
const role = getRole(el);
|
|
117
|
+
const defaults = constants.roles[role].defaults;
|
|
99
118
|
if (defaults && defaults.hasOwnProperty(key)) {
|
|
100
119
|
return defaults[key];
|
|
101
120
|
}
|