- commit
- b13f37b1176869471a322557d36eee9e78d9793e
- parent
- 8af9bdb6042d92f405942772006196e264f4c989
- Author
- Tobias Bengfort <tobias.bengfort@posteo.de>
- Date
- 2023-01-12 19:07
bump version to 0.4.7
Diffstat
| M | CHANGES.md | 6 | ++++++ |
| M | dist/aria.js | 128 | ++++++++++++++++++++++++++++++++----------------------------- |
| M | package.json | 2 | +- |
3 files changed, 74 insertions, 62 deletions
diff --git a/CHANGES.md b/CHANGES.md
@@ -1,3 +1,9 @@ -1 1 0.4.7 (2023-01-12) -1 2 ------------------ -1 3 -1 4 - internal refactoring and performance improvements -1 5 -1 6 1 7 0.4.6 (2023-01-08) 2 8 ------------------ 3 9
diff --git a/dist/aria.js b/dist/aria.js
@@ -21,52 +21,56 @@ module.exports = {
21 21 },{"./lib/atree.js":2,"./lib/name.js":5,"./lib/query.js":6}],2:[function(require,module,exports){
22 22 var attrs = require('./attrs');
23 23
24 -1 var _getOwner = function(node) {
-1 24 var _getOwner = function(node, owners) {
25 25 if (node.nodeType === node.ELEMENT_NODE && node.id) {
26 -1 var owner = document.querySelector('[aria-owns~="' + CSS.escape(node.id) + '"]');
27 -1 if (owner) {
28 -1 return owner;
-1 26 var selector = '[aria-owns~="' + CSS.escape(node.id) + '"]';
-1 27 if (owners) {
-1 28 for (var owner of owners) {
-1 29 if (owner.matches(selector)) {
-1 30 return owner;
-1 31 }
-1 32 }
-1 33 } else {
-1 34 return document.querySelector(selector);
29 35 }
30 36 }
31 37 };
32 38
33 -1 var _getParentNode = function(node) {
34 -1 return _getOwner(node) || node.parentNode;
-1 39 var _getParentNode = function(node, owners) {
-1 40 return _getOwner(node, owners) || node.parentNode;
35 41 };
36 42
37 -1 var detectLoop = function(node) {
38 -1 var seen = [node]
39 -1 while ((node = _getParentNode(node))) {
-1 43 var detectLoop = function(node, owners) {
-1 44 var seen = [node];
-1 45 while ((node = _getParentNode(node, owners))) {
40 46 if (seen.includes(node)) {
41 47 return true;
42 48 }
43 -1 seen.push(node)
-1 49 seen.push(node);
44 50 }
45 51 };
46 52
47 -1 var getOwner = function(node) {
48 -1 if (node.nodeType === node.ELEMENT_NODE && node.id) {
49 -1 var owner = document.querySelector('[aria-owns~="' + CSS.escape(node.id) + '"]');
50 -1 if (owner && !detectLoop(node)) {
51 -1 return owner;
52 -1 }
-1 53 var getOwner = function(node, owners) {
-1 54 var owner = _getOwner(node, owners);
-1 55 if (owner && !detectLoop(node, owners)) {
-1 56 return owner;
53 57 }
54 58 };
55 59
56 -1 var getParentNode = function(node) {
57 -1 return getOwner(node) || node.parentNode;
-1 60 var getParentNode = function(node, owners) {
-1 61 return getOwner(node, owners) || node.parentNode;
58 62 };
59 63
60 64 var isHidden = function(node) {
61 65 return node.nodeType === node.ELEMENT_NODE && attrs.getAttribute(node, 'hidden');
62 66 };
63 67
64 -1 var getChildNodes = function(node) {
-1 68 var getChildNodes = function(node, owners) {
65 69 var childNodes = [];
66 70
67 71 for (var i = 0; i < node.childNodes.length; i++) {
68 72 var child = node.childNodes[i];
69 -1 if (!getOwner(child) && !isHidden(child)) {
-1 73 if (!getOwner(child, owners) && !isHidden(child)) {
70 74 childNodes.push(child);
71 75 }
72 76 }
@@ -76,7 +80,7 @@ var getChildNodes = function(node) {
76 80 for (var i = 0; i < owns.length; i++) {
77 81 var child = document.getElementById(owns[i]);
78 82 // double check with getOwner for consistency
79 -1 if (child && getOwner(child) === node && !isHidden(child)) {
-1 83 if (child && getOwner(child, owners) === node && !isHidden(child)) {
80 84 childNodes.push(child);
81 85 }
82 86 }
@@ -86,10 +90,13 @@ var getChildNodes = function(node) {
86 90 };
87 91
88 92 var walk = function(root, fn) {
89 -1 fn(root);
90 -1 getChildNodes(root).forEach(function(child) {
91 -1 walk(child, fn);
92 -1 });
-1 93 var owners = document.querySelectorAll('[aria-owns]');
-1 94 var queue = [root];
-1 95 while (queue.length) {
-1 96 var item = queue.shift();
-1 97 fn(item);
-1 98 queue = getChildNodes(item, owners).concat(queue);
-1 99 }
93 100 };
94 101
95 102 var searchUp = function(node, test) {
@@ -116,35 +123,30 @@ var constants = require('./constants.js');
116 123 // candidates can be passed for performance optimization
117 124 var getRole = function(el, candidates) {
118 125 if (el.hasAttribute('role')) {
119 -1 return el.getAttribute('role');
120 -1 }
121 -1 for (var role in constants.roles) {
122 -1 var selector = (constants.roles[role].selectors || []).join(',');
123 -1 if (selector && (!candidates || candidates.includes(role)) && el.matches(selector)) {
-1 126 var role = el.getAttribute('role');
-1 127 if (!candidates || candidates.includes(role)) {
124 128 return role;
-1 129 } else {
-1 130 return;
125 131 }
126 132 }
127 -1
128 -1 if (!candidates ||
129 -1 candidates.includes('banner') ||
130 -1 candidates.includes('contentinfo')) {
131 -1 if (!el.matches(constants.scoped)) {
132 -1 if (el.matches('header')) {
133 -1 return 'banner';
134 -1 }
135 -1 if (el.matches('footer')) {
136 -1 return 'contentinfo';
-1 133 var roles = candidates ? candidates : Object.keys(constants.roles);
-1 134 for (var role of roles) {
-1 135 var r = constants.roles[role];
-1 136 if (r) {
-1 137 var selector = (r.selectors || []).join(',');
-1 138 if (selector && el.matches(selector)) {
-1 139 return role;
137 140 }
138 141 }
139 142 }
140 143 };
141 144
142 145 var hasRole = function(el, roles) {
143 -1 var candidates = [].concat.apply([], roles.map(function(role) {
-1 146 var candidates = [].concat.apply([], roles.map(role => {
144 147 return (constants.roles[role] || {}).subRoles || [role];
145 148 }));
146 -1 var actual = getRole(el, candidates);
147 -1 return candidates.includes(actual);
-1 149 return !!getRole(el, candidates);
148 150 };
149 151
150 152 var getAttribute = function(el, key) {
@@ -299,6 +301,14 @@ exports.attributeWeakMapping = {
299 301 'selected': 'selected',
300 302 };
301 303
-1 304 var scoped = [
-1 305 'main *',
-1 306 // https://www.w3.org/TR/html/dom.html#sectioning-content-2
-1 307 'article *', 'aside *', 'nav *', 'section *',
-1 308 // https://www.w3.org/TR/html/sections.html#sectioning-roots
-1 309 'blockquote *', 'details *', 'dialog *', 'fieldset *', 'figure *', 'td *',
-1 310 ].join(',');
-1 311
302 312 // https://www.w3.org/TR/html-aam-1.0/#html-element-role-mappings
303 313 // https://www.w3.org/TR/wai-aria/roles
304 314 exports.roles = {
@@ -312,6 +322,9 @@ exports.roles = {
312 322 article: {
313 323 selectors: ['article'],
314 324 },
-1 325 banner: {
-1 326 selectors: ['header:not(' + scoped + ')'],
-1 327 },
315 328 button: {
316 329 selectors: [
317 330 'button',
@@ -366,6 +379,9 @@ exports.roles = {
366 379 composite: {
367 380 childRoles: ['grid', 'select', 'spinbutton', 'tablist'],
368 381 },
-1 382 contentinfo: {
-1 383 selectors: ['footer:not(' + scoped + ')'],
-1 384 },
369 385 definition: {
370 386 selectors: ['dd'],
371 387 },
@@ -731,22 +747,14 @@ exports.roles = {
731 747 },
732 748 };
733 749
734 -1 exports.scoped = [
735 -1 'main *',
736 -1 // https://www.w3.org/TR/html/dom.html#sectioning-content-2
737 -1 'article *', 'aside *', 'nav *', 'section *',
738 -1 // https://www.w3.org/TR/html/sections.html#sectioning-roots
739 -1 'blockquote *', 'details *', 'dialog *', 'fieldset *', 'figure *', 'td *',
740 -1 ].join(',');
741 -1
742 750 var getSubRoles = function(role) {
743 751 var children = (exports.roles[role] || {}).childRoles || [];
744 752 var descendents = children.map(getSubRoles);
745 753
746 754 var result = [role];
747 755
748 -1 descendents.forEach(function(list) {
749 -1 list.forEach(function(r) {
-1 756 descendents.forEach(list => {
-1 757 list.forEach(r => {
750 758 if (!result.includes(r)) {
751 759 result.push(r);
752 760 }
@@ -858,7 +866,7 @@ var getName = function(el, recursive, visited, directReference) {
858 866 // B
859 867 if (!recursive && el.matches('[aria-labelledby]')) {
860 868 var ids = el.getAttribute('aria-labelledby').split(/\s+/);
861 -1 var strings = ids.map(function(id) {
-1 869 var strings = ids.map(id => {
862 870 var label = document.getElementById(id);
863 871 return label ? getName(label, true, visited, true) : '';
864 872 });
@@ -873,7 +881,7 @@ var getName = function(el, recursive, visited, directReference) {
873 881
874 882 // D
875 883 if (!ret.trim() && !recursive && el.labels) {
876 -1 var strings = Array.prototype.map.call(el.labels, function(label) {
-1 884 var strings = Array.prototype.map.call(el.labels, label => {
877 885 return getName(label, true, visited);
878 886 });
879 887 ret = strings.join(' ');
@@ -959,7 +967,7 @@ var getDescription = function(el) {
959 967
960 968 if (el.matches('[aria-describedby]')) {
961 969 var ids = el.getAttribute('aria-describedby').split(/\s+/);
962 -1 var strings = ids.map(function(id) {
-1 970 var strings = ids.map(id => {
963 971 var label = document.getElementById(id);
964 972 return label ? getName(label, true) : '';
965 973 });
@@ -1009,7 +1017,7 @@ var _querySelector = function(all) {
1009 1017 return function(root, role) {
1010 1018 var results = [];
1011 1019 try {
1012 -1 atree.walk(root, function(node) {
-1 1020 atree.walk(root, node => {
1013 1021 if (node.nodeType === node.ELEMENT_NODE) {
1014 1022 // FIXME: skip hidden elements
1015 1023 if (matches(node, role)) {
@@ -1030,7 +1038,7 @@ var _querySelector = function(all) {
1030 1038 };
1031 1039
1032 1040 var closest = function(el, selector) {
1033 -1 return atree.searchUp(el, function(candidate) {
-1 1041 return atree.searchUp(el, candidate => {
1034 1042 if (candidate.nodeType === candidate.ELEMENT_NODE) {
1035 1043 return matches(candidate, selector);
1036 1044 }
@@ -1038,9 +1046,7 @@ var closest = function(el, selector) {
1038 1046 };
1039 1047
1040 1048 module.exports = {
1041 -1 getRole: function(el) {
1042 -1 return attrs.getRole(el);
1043 -1 },
-1 1049 getRole: el => attrs.getRole(el),
1044 1050 getAttribute: attrs.getAttribute,
1045 1051 matches: matches,
1046 1052 querySelector: _querySelector(),
diff --git a/package.json b/package.json
@@ -1,6 +1,6 @@ 1 1 { 2 2 "name": "aria-api",3 -1 "version": "0.4.6",-1 3 "version": "0.4.7", 4 4 "description": "Access ARIA information from JavaScript", 5 5 "main": "index.js", 6 6 "keywords": [