- commit
- 90aff05a50a6221c35af0612b6c007e59821c4a5
- parent
- 2d62a3c5026da87acff5455b430a723687485d81
- Author
- Tobias Bengfort <tobias.bengfort@posteo.de>
- Date
- 2024-11-01 12:18
Merge branch 'esm'
Diffstat
| M | Makefile | 2 | +- |
| M | index.js | 22 | ++++------------------ |
| M | lib/atree.js | 17 | +++++------------ |
| M | lib/attrs.js | 20 | +++++++++----------- |
| M | lib/constants.js | 28 | ++++++++++++++-------------- |
| M | lib/name.js | 46 | +++++++++++++++++++++------------------------- |
| M | lib/query.js | 19 | ++++++------------- |
| M | package.json | 2 | +- |
8 files changed, 61 insertions, 95 deletions
diff --git a/Makefile b/Makefile
@@ -1,6 +1,6 @@ 1 1 dist/aria.js: index.js lib/*.js 2 2 mkdir -p dist3 -1 npx browserify $< -o $@ -s aria-1 3 rollup $< -o $@ -f umd -n aria 4 4 5 5 wpt-master: 6 6 wget https://github.com/web-platform-tests/wpt/archive/refs/heads/master.zip -O wpt-master.zip
diff --git a/index.js b/index.js
@@ -1,18 +1,4 @@1 -1 var query = require('./lib/query.js');2 -1 var name = require('./lib/name.js');3 -1 var atree = require('./lib/atree.js');4 -15 -1 module.exports = {6 -1 getRole: query.getRole,7 -1 getAttribute: query.getAttribute,8 -1 getName: name.getName,9 -1 getDescription: name.getDescription,10 -111 -1 matches: query.matches,12 -1 querySelector: query.querySelector,13 -1 querySelectorAll: query.querySelectorAll,14 -1 closest: query.closest,15 -116 -1 getParentNode: atree.getParentNode,17 -1 getChildNodes: atree.getChildNodes,18 -1 };-1 1 export { getParentNode, getChildNodes } from './lib/atree.js'; -1 2 export { getRole, getAttribute } from './lib/attrs.js'; -1 3 export { matches, querySelector, querySelectorAll, closest } from './lib/query.js'; -1 4 export { getName, getDescription } from './lib/name.js';
diff --git a/lib/atree.js b/lib/atree.js
@@ -1,4 +1,4 @@1 -1 const attrs = require('./attrs');-1 1 import * as attrs from './attrs'; 2 2 3 3 const _getOwner = function(node, owners) { 4 4 if (node.nodeType === node.ELEMENT_NODE && node.id) { @@ -36,7 +36,7 @@ const getOwner = function(node, owners) { 36 36 } 37 37 }; 38 3839 -1 const getParentNode = function(node, owners) {-1 39 export const getParentNode = function(node, owners) { 40 40 return getOwner(node, owners) || node.parentNode; 41 41 }; 42 42 @@ -44,7 +44,7 @@ const isHidden = function(node) { 44 44 return node.nodeType === node.ELEMENT_NODE && attrs.getAttribute(node, 'hidden'); 45 45 }; 46 4647 -1 const getChildNodes = function(node, owners) {-1 47 export const getChildNodes = function(node, owners) { 48 48 const childNodes = []; 49 49 50 50 for (let i = 0; i < node.childNodes.length; i++) { @@ -68,7 +68,7 @@ const getChildNodes = function(node, owners) { 68 68 return childNodes; 69 69 }; 70 7071 -1 const walk = function(root, fn) {-1 71 export const walk = function(root, fn) { 72 72 const owners = document.querySelectorAll('[aria-owns]'); 73 73 let queue = [root]; 74 74 while (queue.length) { @@ -78,7 +78,7 @@ const walk = function(root, fn) { 78 78 } 79 79 }; 80 8081 -1 const searchUp = function(node, test) {-1 81 export const searchUp = function(node, test) { 82 82 const candidate = getParentNode(node); 83 83 if (candidate) { 84 84 if (test(candidate)) { @@ -88,10 +88,3 @@ const searchUp = function(node, test) { 88 88 } 89 89 } 90 90 };91 -192 -1 module.exports = {93 -1 'getParentNode': getParentNode,94 -1 'getChildNodes': getChildNodes,95 -1 'walk': walk,96 -1 'searchUp': searchUp,97 -1 };
diff --git a/lib/attrs.js b/lib/attrs.js
@@ -1,4 +1,4 @@1 -1 const constants = require('./constants.js');-1 1 import * as constants from './constants.js'; 2 2 3 3 var unique = function(arr) { 4 4 return arr.filter((a, i) => arr.indexOf(a) === i); @@ -17,7 +17,7 @@ var normalizeRoles = function(roles, includeAbstract) { 17 17 }; 18 18 19 19 // candidates can be passed for performance optimization20 -1 const getRole = function(el, candidates) {-1 20 const getRoleRaw = function(el, candidates) { 21 21 // TODO: filter out any invalid roles (e.g. name or context required) 22 22 const roles = normalizeRoles( 23 23 (el.getAttribute('role') || '').toLowerCase().split(/\s+/) @@ -41,14 +41,18 @@ const getRole = function(el, candidates) { 41 41 } 42 42 }; 43 4344 -1 const hasRole = function(el, roles) {-1 44 export const getRole = function(el) { -1 45 return getRoleRaw(el); -1 46 }; -1 47 -1 48 export const hasRole = function(el, roles) { 45 49 const subRoles = normalizeRoles(roles, true).map(role => { 46 50 return constants.roles[role].subRoles || [role]; 47 51 });48 -1 return !!getRole(el, unique(flatten(subRoles)));-1 52 return !!getRoleRaw(el, unique(flatten(subRoles))); 49 53 }; 50 5451 -1 const getAttribute = function(el, key) {-1 55 export const getAttribute = function(el, key) { 52 56 if (constants.attributeStrongMapping.hasOwnProperty(key)) { 53 57 const value = el[constants.attributeStrongMapping[key]]; 54 58 if (value) { @@ -124,9 +128,3 @@ const getAttribute = function(el, key) { 124 128 return false; 125 129 } 126 130 };127 -1128 -1 module.exports = {129 -1 getRole: getRole,130 -1 hasRole: hasRole,131 -1 getAttribute: getAttribute,132 -1 };
diff --git a/lib/constants.js b/lib/constants.js
@@ -1,5 +1,5 @@ 1 1 // https://www.w3.org/TR/wai-aria/#state_prop_def2 -1 exports.attributes = {-1 2 export const attributes = { 3 3 'activedescendant': 'id', 4 4 'atomic': 'bool', 5 5 'autocomplete': 'token', @@ -55,14 +55,14 @@ exports.attributes = { 55 55 'valuetext': 'string', 56 56 }; 57 5758 -1 exports.attributeStrongMapping = {-1 58 export const attributeStrongMapping = { 59 59 'disabled': 'disabled', 60 60 'placeholder': 'placeholder', 61 61 'readonly': 'readOnly', 62 62 'required': 'required', 63 63 }; 64 6465 -1 exports.attributeWeakMapping = {-1 65 export const attributeWeakMapping = { 66 66 'checked': 'checked', 67 67 'colspan': 'colSpan', 68 68 'expanded': 'open', @@ -89,7 +89,7 @@ const svgSelectors = function(selector) { 89 89 90 90 // https://www.w3.org/TR/html-aam-1.0/#html-element-role-mappings 91 91 // https://www.w3.org/TR/wai-aria/roles92 -1 exports.roles = {-1 92 export const roles = { 93 93 alert: { 94 94 childRoles: ['alertdialog'], 95 95 defaults: { @@ -732,7 +732,7 @@ exports.roles = { 732 732 }; 733 733 734 734 const getSubRoles = function(role) {735 -1 const children = (exports.roles[role]).childRoles || [];-1 735 const children = (roles[role]).childRoles || []; 736 736 const descendents = children.map(getSubRoles); 737 737 738 738 const result = [role]; @@ -748,30 +748,30 @@ const getSubRoles = function(role) { 748 748 return result; 749 749 }; 750 750751 -1 exports.attrsWithDefaults = [];-1 751 export const attrsWithDefaults = []; 752 752753 -1 for (const role in exports.roles) {754 -1 exports.roles[role].subRoles = getSubRoles(role);755 -1 for (const key in exports.roles[role].defaults) {756 -1 if (!exports.attrsWithDefaults.includes(key)) {757 -1 exports.attrsWithDefaults.push(key);-1 753 for (const role in roles) { -1 754 roles[role].subRoles = getSubRoles(role); -1 755 for (const key in roles[role].defaults) { -1 756 if (!attrsWithDefaults.includes(key)) { -1 757 attrsWithDefaults.push(key); 758 758 } 759 759 } 760 760 } 761 761762 -1 exports.aliases = {-1 762 export const aliases = { 763 763 'presentation': 'none', 764 764 'directory': 'list', 765 765 'img': 'image', 766 766 }; 767 767768 -1 exports.nameFromDescendant = {-1 768 export const nameFromDescendant = { 769 769 'figure': 'figcaption', 770 770 'table': 'caption', 771 771 'fieldset': 'legend', 772 772 }; 773 773774 -1 exports.nameDefaults = {-1 774 export const nameDefaults = { 775 775 'input[type="submit"]': 'Submit', 776 776 'input[type="reset"]': 'Reset', 777 777 'summary': 'Details',
diff --git a/lib/name.js b/lib/name.js
@@ -1,6 +1,7 @@1 -1 const constants = require('./constants.js');2 -1 const atree = require('./atree.js');3 -1 const query = require('./query.js');-1 1 import * as constants from './constants.js'; -1 2 import * as atree from './atree.js'; -1 3 import * as attrs from './attrs.js'; -1 4 import * as query from './query.js'; 4 5 5 6 const addSpaces = function(text, el, pseudoSelector) { 6 7 // https://github.com/w3c/accname/issues/3 @@ -16,17 +17,17 @@ const getPseudoContent = function(el, pseudoSelector) { 16 17 17 18 let match; 18 19 while (tail.length) {19 -1 if (match = tail.match(/^"([^"]*)"/)) {-1 20 if ((match = tail.match(/^"([^"]*)"/))) { 20 21 ret.push(match[1]);21 -1 } else if (match = tail.match(/^([a-z-]+)\(([^)]*)\)/)) {-1 22 } else if ((match = tail.match(/^([a-z-]+)\(([^)]*)\)/))) { 22 23 if (match[1] === 'attr') { 23 24 ret.push(el.getAttribute(match[2]) || ''); 24 25 }25 -1 } else if (match = tail.match(/^([a-z-]+)/)) {-1 26 } else if ((match = tail.match(/^([a-z-]+)/))) { 26 27 if (match[1] === 'open-quote' || match[1] === 'close-quote') { 27 28 ret.push('"'); 28 29 }29 -1 } else if (match = tail.match(/^\//)) {-1 30 } else if ((match = tail.match(/^\//))) { 30 31 ret = []; 31 32 } else { 32 33 // invalid content, ignore @@ -50,7 +51,7 @@ const getContent = function(root, ongoingLabelledBy, visited) { 50 51 if (node.tagName.toLowerCase() === 'br') { 51 52 ret += '\n'; 52 53 } else {53 -1 ret += getName(node, true, ongoingLabelledBy, visited);-1 54 ret += getNameRaw(node, true, ongoingLabelledBy, visited); 54 55 } 55 56 } 56 57 } @@ -59,13 +60,13 @@ const getContent = function(root, ongoingLabelledBy, visited) { 59 60 }; 60 61 61 62 const allowNameFromContent = function(el) {62 -1 const role = query.getRole(el);-1 63 const role = attrs.getRole(el); 63 64 if (role) { 64 65 return constants.roles[role].nameFromContents; 65 66 } 66 67 }; 67 6868 -1 const getName = function(el, recursive, ongoingLabelledBy, visited, directReference) {-1 69 const getNameRaw = function(el, recursive, ongoingLabelledBy, visited, directReference) { 69 70 let ret = ''; 70 71 71 72 visited = visited || []; @@ -85,7 +86,7 @@ const getName = function(el, recursive, ongoingLabelledBy, visited, directRefere 85 86 const ids = el.getAttribute('aria-labelledby').split(/\s+/); 86 87 const strings = ids.map(id => { 87 88 const label = document.getElementById(id);88 -1 return label ? getName(label, true, true, visited, true) : '';-1 89 return label ? getNameRaw(label, true, true, visited, true) : ''; 89 90 }); 90 91 ret = strings.join(' '); 91 92 } @@ -97,12 +98,12 @@ const getName = function(el, recursive, ongoingLabelledBy, visited, directRefere 97 98 } else if (query.matches(el, 'combobox,listbox')) { 98 99 const selected = query.querySelector(el, ':selected') || query.querySelector(el, 'option'); 99 100 if (selected) {100 -1 ret = getName(selected, recursive, ongoingLabelledBy, visited);-1 101 ret = getNameRaw(selected, recursive, ongoingLabelledBy, visited); 101 102 } else { 102 103 ret = el.value || ''; 103 104 } 104 105 } else if (query.matches(el, 'range')) {105 -1 ret = '' + (query.getAttribute(el, 'valuetext') || query.getAttribute(el, 'valuenow') || el.value);-1 106 ret = '' + (attrs.getAttribute(el, 'valuetext') || attrs.getAttribute(el, 'valuenow') || el.value); 106 107 } 107 108 } 108 109 @@ -115,7 +116,7 @@ const getName = function(el, recursive, ongoingLabelledBy, visited, directRefere 115 116 // D 116 117 if (!ret.trim() && !recursive && el.labels) { 117 118 const strings = Array.prototype.map.call(el.labels, label => {118 -1 return getName(label, true, ongoingLabelledBy, visited);-1 119 return getNameRaw(label, true, ongoingLabelledBy, visited); 119 120 }); 120 121 ret = strings.join(' '); 121 122 } @@ -130,7 +131,7 @@ const getName = function(el, recursive, ongoingLabelledBy, visited, directRefere 130 131 if (el.matches(selector)) { 131 132 const descendant = el.querySelector(constants.nameFromDescendant[selector]); 132 133 if (descendant) {133 -1 ret = getName(descendant, true, ongoingLabelledBy, visited);-1 134 ret = getNameRaw(descendant, true, ongoingLabelledBy, visited); 134 135 } 135 136 } 136 137 } @@ -182,21 +183,21 @@ const getName = function(el, recursive, ongoingLabelledBy, visited, directRefere 182 183 return addSpaces(before + ret + after, el); 183 184 }; 184 185185 -1 const getNameTrimmed = function(el) {186 -1 return getName(el)-1 186 export const getName = function(el) { -1 187 return getNameRaw(el) 187 188 .replace(/[ \n\r\t\f]+/g, ' ') 188 189 .replace(/^ /, '') 189 190 .replace(/ $/, ''); 190 191 }; 191 192192 -1 const getDescription = function(el) {-1 193 export const getDescription = function(el) { 193 194 let ret = ''; 194 195 195 196 if (el.matches('[aria-describedby]')) { 196 197 const ids = el.getAttribute('aria-describedby').split(/\s+/); 197 198 const strings = ids.map(id => { 198 199 const label = document.getElementById(id);199 -1 return label ? getName(label, true, true) : '';-1 200 return label ? getNameRaw(label, true, true) : ''; 200 201 }); 201 202 ret = strings.join(' '); 202 203 } else if (el.matches('[aria-description]')) { @@ -215,14 +216,9 @@ const getDescription = function(el) { 215 216 216 217 ret = (ret || '').trim().replace(/\s+/g, ' '); 217 218218 -1 if (ret === getNameTrimmed(el)) {-1 219 if (ret === getName(el)) { 219 220 ret = ''; 220 221 } 221 222 222 223 return ret; 223 224 };224 -1225 -1 module.exports = {226 -1 getName: getNameTrimmed,227 -1 getDescription: getDescription,228 -1 };
diff --git a/lib/query.js b/lib/query.js
@@ -1,8 +1,7 @@1 -1 const attrs = require('./attrs.js');2 -1 const atree = require('./atree.js');-1 1 import * as attrs from './attrs.js'; -1 2 import * as atree from './atree.js'; 3 34 -15 -1 const matches = function(el, selector) {-1 4 export const matches = function(el, selector) { 6 5 if (selector.substr(0, 1) === ':') { 7 6 const attr = selector.substr(1); 8 7 return attrs.getAttribute(el, attr); @@ -40,7 +39,7 @@ const _querySelector = function(all) { 40 39 }; 41 40 }; 42 4143 -1 const closest = function(el, selector) {-1 42 export const closest = function(el, selector) { 44 43 return atree.searchUp(el, candidate => { 45 44 if (candidate.nodeType === candidate.ELEMENT_NODE) { 46 45 return matches(candidate, selector); @@ -48,11 +47,5 @@ const closest = function(el, selector) { 48 47 }); 49 48 }; 50 4951 -1 module.exports = {52 -1 getRole: el => attrs.getRole(el),53 -1 getAttribute: attrs.getAttribute,54 -1 matches: matches,55 -1 querySelector: _querySelector(),56 -1 querySelectorAll: _querySelector(true),57 -1 closest: closest,58 -1 };-1 50 export const querySelector = _querySelector(); -1 51 export const querySelectorAll = _querySelector(true);
diff --git a/package.json b/package.json
@@ -2,7 +2,7 @@ 2 2 "name": "aria-api", 3 3 "version": "0.7.0", 4 4 "description": "Access ARIA information from JavaScript",5 -1 "main": "index.js",-1 5 "module": "index.js", 6 6 "keywords": [ 7 7 "aria", 8 8 "accessibility",