aria-api

access ARIA information from JavaScript
git clone https://git.ce9e.org/aria-api.git

commit
6bda87f2aab19d4d109679280413e77802fd7642
parent
e6f4579a676980047deeb5d67569a28a74261596
Author
Tobias Bengfort <tobias.bengfort@posteo.de>
Date
2023-01-12 18:11
refactor: use arrow functions for callbacks

Diffstat

M README.md 2 +-
M lib/attrs.js 2 +-
M lib/constants.js 4 ++--
M lib/name.js 6 +++---
M lib/query.js 8 +++-----
M test/test-conflict.js 16 ++++++++--------
M test/test-hidden.js 28 ++++++++++++++--------------
M test/test-loop.js 8 ++++----
M test/test-name.js 14 +++++++-------
M test/test-role.js 30 +++++++++++++++---------------

10 files changed, 58 insertions, 60 deletions


diff --git a/README.md b/README.md

@@ -20,7 +20,7 @@ browserify. There is also an UMD build included as `dist/aria.js`.
   20    20 
   21    21     var aria = require('aria-api'):
   22    22 
   23    -1     aria.querySelector('landmark').forEach(function(landmark) {
   -1    23     aria.querySelector('landmark').forEach(landmark => {
   24    24         if (!aria.matches(landmark, ':hidden')) {
   25    25             var role = aria.getRole(landmark);
   26    26             var name = aria.getName(landmark);

diff --git a/lib/attrs.js b/lib/attrs.js

@@ -14,7 +14,7 @@ var getRole = function(el, candidates) {
   14    14 };
   15    15 
   16    16 var hasRole = function(el, roles) {
   17    -1 	var candidates = [].concat.apply([], roles.map(function(role) {
   -1    17 	var candidates = [].concat.apply([], roles.map(role => {
   18    18 		return (constants.roles[role] || {}).subRoles || [role];
   19    19 	}));
   20    20 	var actual = getRole(el, candidates);

diff --git a/lib/constants.js b/lib/constants.js

@@ -518,8 +518,8 @@ var getSubRoles = function(role) {
  518   518 
  519   519 	var result = [role];
  520   520 
  521    -1 	descendents.forEach(function(list) {
  522    -1 		list.forEach(function(r) {
   -1   521 	descendents.forEach(list => {
   -1   522 		list.forEach(r => {
  523   523 			if (!result.includes(r)) {
  524   524 				result.push(r);
  525   525 			}

diff --git a/lib/name.js b/lib/name.js

@@ -72,7 +72,7 @@ var getName = function(el, recursive, visited, directReference) {
   72    72 	// B
   73    73 	if (!recursive && el.matches('[aria-labelledby]')) {
   74    74 		var ids = el.getAttribute('aria-labelledby').split(/\s+/);
   75    -1 		var strings = ids.map(function(id) {
   -1    75 		var strings = ids.map(id => {
   76    76 			var label = document.getElementById(id);
   77    77 			return label ? getName(label, true, visited, true) : '';
   78    78 		});
@@ -87,7 +87,7 @@ var getName = function(el, recursive, visited, directReference) {
   87    87 
   88    88 	// D
   89    89 	if (!ret.trim() && !recursive && el.labels) {
   90    -1 		var strings = Array.prototype.map.call(el.labels, function(label) {
   -1    90 		var strings = Array.prototype.map.call(el.labels, label => {
   91    91 			return getName(label, true, visited);
   92    92 		});
   93    93 		ret = strings.join(' ');
@@ -173,7 +173,7 @@ var getDescription = function(el) {
  173   173 
  174   174 	if (el.matches('[aria-describedby]')) {
  175   175 		var ids = el.getAttribute('aria-describedby').split(/\s+/);
  176    -1 		var strings = ids.map(function(id) {
   -1   176 		var strings = ids.map(id => {
  177   177 			var label = document.getElementById(id);
  178   178 			return label ? getName(label, true) : '';
  179   179 		});

diff --git a/lib/query.js b/lib/query.js

@@ -22,7 +22,7 @@ var _querySelector = function(all) {
   22    22 	return function(root, role) {
   23    23 		var results = [];
   24    24 		try {
   25    -1 			atree.walk(root, function(node) {
   -1    25 			atree.walk(root, node => {
   26    26 				if (node.nodeType === node.ELEMENT_NODE) {
   27    27 					// FIXME: skip hidden elements
   28    28 					if (matches(node, role)) {
@@ -43,7 +43,7 @@ var _querySelector = function(all) {
   43    43 };
   44    44 
   45    45 var closest = function(el, selector) {
   46    -1 	return atree.searchUp(el, function(candidate) {
   -1    46 	return atree.searchUp(el, candidate => {
   47    47 		if (candidate.nodeType === candidate.ELEMENT_NODE) {
   48    48 			return matches(candidate, selector);
   49    49 		}
@@ -51,9 +51,7 @@ var closest = function(el, selector) {
   51    51 };
   52    52 
   53    53 module.exports = {
   54    -1 	getRole: function(el) {
   55    -1 		return attrs.getRole(el);
   56    -1 	},
   -1    54 	getRole: el => attrs.getRole(el),
   57    55 	getAttribute: attrs.getAttribute,
   58    56 	matches: matches,
   59    57 	querySelector: _querySelector(),

diff --git a/test/test-conflict.js b/test/test-conflict.js

@@ -1,40 +1,40 @@
    1     1 // https://www.w3.org/TR/core-aam-1.1/#mapping_conflicts<Paste>
    2     2 // https://w3c.github.io/html-aria/#docconformance
    3     3 
    4    -1 describe('getAttribute()', function() {
   -1     4 describe('getAttribute()', () => {
    5     5 	var testbed;
    6     6 
    7    -1 	beforeEach(function() {
   -1     7 	beforeEach(() => {
    8     8 		testbed = document.createElement('div');
    9     9 		// make sure styles are actually computed
   10    10 		document.body.appendChild(testbed);
   11    11 	});
   12    12 
   13    -1 	afterEach(function() {
   -1    13 	afterEach(() => {
   14    14 		document.body.removeChild(testbed);
   15    15 	});
   16    16 
   17    -1 	['disabled', 'required', 'readonly', 'hidden'].forEach(function(key) {
   18    -1 		it('should ignore aria-' + key + ' on conflict with ' + key, function() {
   -1    17 	['disabled', 'required', 'readonly', 'hidden'].forEach(key => {
   -1    18 		it('should ignore aria-' + key + ' on conflict with ' + key, () => {
   19    19 			testbed.innerHTML = '<input class="test" ' + key + ' aria-' + key + '="false" />';
   20    20 			var el = testbed.querySelector('.test');
   21    21 			expect(aria.getAttribute(el, key)).toBe(true);
   22    22 		});
   23    23 	});
   24    24 
   25    -1 	it('should ignore aria-placeholder on conflict with placeholder', function() {
   -1    25 	it('should ignore aria-placeholder on conflict with placeholder', () => {
   26    26 		testbed.innerHTML = '<input class="test" placeholder="native" aria-placeholder="aria" />';
   27    27 		var el = testbed.querySelector('.test');
   28    28 		expect(aria.getAttribute(el, 'placeholder')).toBe('native');
   29    29 	});
   30    30 
   31    -1 	it('should ignore aria-readonly on conflict with contenteditable', function() {
   -1    31 	it('should ignore aria-readonly on conflict with contenteditable', () => {
   32    32 		testbed.innerHTML = '<input class="test" contenteditable aria-readonly="true" />';
   33    33 		var el = testbed.querySelector('.test');
   34    34 		expect(aria.getAttribute(el, 'readonly')).toBe(false);
   35    35 	});
   36    36 
   37    -1 	it('should ignore aria-invalid on conflict', function() {
   -1    37 	it('should ignore aria-invalid on conflict', () => {
   38    38 		testbed.innerHTML = '<input class="test" required aria-invalid="false" />';
   39    39 		var el = testbed.querySelector('.test');
   40    40 		expect(aria.getAttribute(el, 'invalid')).toBe(true);

diff --git a/test/test-hidden.js b/test/test-hidden.js

@@ -1,77 +1,77 @@
    1    -1 describe('getAttribute(el, "hidden")', function() {
   -1     1 describe('getAttribute(el, "hidden")', () => {
    2     2 	var testbed;
    3     3 
    4    -1 	beforeEach(function() {
   -1     4 	beforeEach(() => {
    5     5 		testbed = document.createElement('div');
    6     6 		// make sure styles are actually computed
    7     7 		document.body.appendChild(testbed);
    8     8 	});
    9     9 
   10    -1 	afterEach(function() {
   -1    10 	afterEach(() => {
   11    11 		document.body.removeChild(testbed);
   12    12 	});
   13    13 
   14    -1 	it('is true on display: none', function() {
   -1    14 	it('is true on display: none', () => {
   15    15 		testbed.innerHTML = '<div class="test" style="display: none">test</div>';
   16    16 		var el = testbed.querySelector('.test');
   17    17 		expect(aria.getAttribute(el, 'hidden')).toBe(true);
   18    18 	});
   19    19 
   20    -1 	it('is undefined on display: none on parent', function() {
   -1    20 	it('is undefined on display: none on parent', () => {
   21    21 		testbed.innerHTML = '<div style="display: none"><div class="test">test</div></div>';
   22    22 		var el = testbed.querySelector('.test');
   23    23 		expect(aria.getAttribute(el, 'hidden')).toBe(undefined);
   24    24 	});
   25    25 
   26    -1 	it('is true on visibility: hidden', function() {
   -1    26 	it('is true on visibility: hidden', () => {
   27    27 		testbed.innerHTML = '<div class="test" style="visibility: hidden">test</div>';
   28    28 		var el = testbed.querySelector('.test');
   29    29 		expect(aria.getAttribute(el, 'hidden')).toBe(true);
   30    30 	});
   31    31 
   32    -1 	it('is true on visibility: hidden on parent', function() {
   -1    32 	it('is true on visibility: hidden on parent', () => {
   33    33 		testbed.innerHTML = '<div style="visibility: hidden"><div class="test">test</div></div>';
   34    34 		var el = testbed.querySelector('.test');
   35    35 		expect(aria.getAttribute(el, 'hidden')).toBe(true);
   36    36 	});
   37    37 
   38    -1 	it('is undefined on overwritten visibility: hidden on parent', function() {
   -1    38 	it('is undefined on overwritten visibility: hidden on parent', () => {
   39    39 		testbed.innerHTML = '<div style="visibility: hidden"><div class="test" style="visibility: visible">test</div></div>';
   40    40 		var el = testbed.querySelector('.test');
   41    41 		expect(aria.getAttribute(el, 'hidden')).toBe(undefined);
   42    42 	});
   43    43 
   44    -1 	it('is true on hidden attribute', function() {
   -1    44 	it('is true on hidden attribute', () => {
   45    45 		testbed.innerHTML = '<div class="test" hidden>test</div>';
   46    46 		var el = testbed.querySelector('.test');
   47    47 		expect(aria.getAttribute(el, 'hidden')).toBe(true);
   48    48 	});
   49    49 
   50    -1 	it('is undefined on hidden attribute on parent', function() {
   -1    50 	it('is undefined on hidden attribute on parent', () => {
   51    51 		testbed.innerHTML = '<div hidden><div class="test">test</div></div>';
   52    52 		var el = testbed.querySelector('.test');
   53    53 		expect(aria.getAttribute(el, 'hidden')).toBe(undefined);
   54    54 	});
   55    55 
   56    -1 	it('is undefined on visually overwritten hidden attribute', function() {
   -1    56 	it('is undefined on visually overwritten hidden attribute', () => {
   57    57 		testbed.innerHTML = '<div class="test" style="display: block" hidden>test</div>';
   58    58 		var el = testbed.querySelector('.test');
   59    59 		expect(aria.getAttribute(el, 'hidden')).toBe(undefined);
   60    60 	});
   61    61 
   62    -1 	it('is true on children of <details>', function() {
   -1    62 	it('is true on children of <details>', () => {
   63    63 		testbed.innerHTML = '<details><summary>foo</summary><div class="test">test</div></details>';
   64    64 		var el = testbed.querySelector('.test');
   65    65 		expect(aria.getAttribute(el, 'hidden')).toBe(true);
   66    66 	});
   67    67 
   68    -1 	it('is undefined on children of <details open>', function() {
   -1    68 	it('is undefined on children of <details open>', () => {
   69    69 		testbed.innerHTML = '<details open><summary>foo</summary><div class="test">test</div></details>';
   70    70 		var el = testbed.querySelector('.test');
   71    71 		expect(aria.getAttribute(el, 'hidden')).toBe(undefined);
   72    72 	});
   73    73 
   74    -1 	it('is undefined on <summary>', function() {
   -1    74 	it('is undefined on <summary>', () => {
   75    75 		testbed.innerHTML = '<details><summary class="test">foo</summary><div>test</div></details>';
   76    76 		var el = testbed.querySelector('.test');
   77    77 		expect(aria.getAttribute(el, 'hidden')).toBe(undefined);

diff --git a/test/test-loop.js b/test/test-loop.js

@@ -1,17 +1,17 @@
    1    -1 describe('detectLoop()', function() {
   -1     1 describe('detectLoop()', () => {
    2     2 	var testbed;
    3     3 
    4    -1 	beforeEach(function() {
   -1     4 	beforeEach(() => {
    5     5 		testbed = document.createElement('div');
    6     6 		// make sure styles are actually computed
    7     7 		document.body.appendChild(testbed);
    8     8 	});
    9     9 
   10    -1 	afterEach(function() {
   -1    10 	afterEach(() => {
   11    11 		document.body.removeChild(testbed);
   12    12 	});
   13    13 
   14    -1 	it('detects loops', function() {
   -1    14 	it('detects loops', () => {
   15    15 		testbed.innerHTML = '<span id="a"><a id="test" href="#" aria-owns="b">test</a><a href="#" aria-owns="a"></a></span><span id="b"><a href="#" aria-owns="a"></a></span>';
   16    16 		var element = document.querySelector('#test');
   17    17 		expect(aria.getName(element)).toBe('test');

diff --git a/test/test-name.js b/test/test-name.js

@@ -1,21 +1,21 @@
    1    -1 describe('getName / getDescription', function() {
   -1     1 describe('getName / getDescription', () => {
    2     2 	var testbed = document.createElement('div');
    3     3 	var known_failing = [
    4     4 		'Name test case 660',
    5     5 		'Name test case 659',
    6     6 	];
    7     7 
    8    -1 	before(function() {
   -1     8 	before(() => {
    9     9 		document.body.appendChild(testbed);
   10    10 	});
   11    11 
   12    -1 	after(function() {
   -1    12 	after(() => {
   13    13 		document.body.removeChild(testbed);
   14    14 	});
   15    15 
   16    -1 	window.wpt.accname.forEach(function(test) {
   -1    16 	window.wpt.accname.forEach(test => {
   17    17 		var _it = known_failing.includes(test.title) ? xit : it;
   18    -1 		_it(test.title, function() {
   -1    18 		_it(test.title, () => {
   19    19 			testbed.innerHTML = test.html;
   20    20 			var element = document.querySelector('#test');
   21    21 
@@ -28,13 +28,13 @@ describe('getName / getDescription', function() {
   28    28 		});
   29    29 	});
   30    30 
   31    -1 	it('ingores <noscript>', function() {
   -1    31 	it('ingores <noscript>', () => {
   32    32 		testbed.innerHTML = '<a id="test" href="#">test <noscript>moo</noscript></a>';
   33    33 		var element = document.querySelector('#test');
   34    34 		expect(aria.getName(element)).toBe('test');
   35    35 	});
   36    36 
   37    -1 	it('ignores <img alt="">', function() {
   -1    37 	it('ignores <img alt="">', () => {
   38    38 		testbed.innerHTML = '<img id="test" alt="" title="title">'
   39    39 		var element = document.querySelector('#test');
   40    40 		expect(aria.getName(element)).toBe('');

diff --git a/test/test-role.js b/test/test-role.js

@@ -19,22 +19,22 @@ var LANDMARKS = '<header>banner</header>\n' +
   19    19 	'</div>';
   20    20 
   21    21 
   22    -1 describe('query', function() {
   -1    22 describe('query', () => {
   23    23 	var testbed;
   24    24 
   25    -1 	beforeEach(function() {
   -1    25 	beforeEach(() => {
   26    26 		testbed = document.createElement('div');
   27    27 		// make sure styles are actually computed
   28    28 		document.body.appendChild(testbed);
   29    29 	});
   30    30 
   31    -1 	afterEach(function() {
   -1    31 	afterEach(() => {
   32    32 		document.body.removeChild(testbed);
   33    33 	});
   34    34 
   35    -1 	describe('getRole', function() {
   36    -1 		describe('links', function() {
   37    -1 			it('link', function() {
   -1    35 	describe('getRole', () => {
   -1    36 		describe('links', () => {
   -1    37 			it('link', () => {
   38    38 				testbed.innerHTML = LINK;
   39    39 				for (var i = 0; i < testbed.children.length; i++) {
   40    40 					var actual = aria.getRole(testbed.children[i]);
@@ -42,7 +42,7 @@ describe('query', function() {
   42    42 				}
   43    43 			});
   44    44 
   45    -1 			it('nolink', function() {
   -1    45 			it('nolink', () => {
   46    46 				testbed.innerHTML = NOLINK;
   47    47 				for (var i = 0; i < testbed.children.length; i++) {
   48    48 					var actual = aria.getRole(testbed.children[i]);
@@ -51,7 +51,7 @@ describe('query', function() {
   51    51 			});
   52    52 		});
   53    53 
   54    -1 		it('landmarks', function() {
   -1    54 		it('landmarks', () => {
   55    55 			testbed.innerHTML = LANDMARKS;
   56    56 			var actual = aria.querySelectorAll(testbed, 'landmark').map(aria.getRole);
   57    57 			expect(actual).toEqual([
@@ -64,8 +64,8 @@ describe('query', function() {
   64    64 		});
   65    65 	});
   66    66 
   67    -1 	describe('closest', function() {
   68    -1 		it('landmarks', function() {
   -1    67 	describe('closest', () => {
   -1    68 		it('landmarks', () => {
   69    69 			testbed.innerHTML = LANDMARKS;
   70    70 			var el = testbed.querySelector('main header');
   71    71 			var actual = aria.closest(el, 'landmark');
@@ -74,7 +74,7 @@ describe('query', function() {
   74    74 			expect(actual.tagName.toLowerCase()).toEqual('main');
   75    75 		});
   76    76 
   77    -1 		it('no match', function() {
   -1    77 		it('no match', () => {
   78    78 			testbed.innerHTML = LANDMARKS;
   79    79 			var el = testbed.querySelector('main header');
   80    80 			var actual = aria.closest(el, 'table');
@@ -83,8 +83,8 @@ describe('query', function() {
   83    83 		});
   84    84 	});
   85    85 
   86    -1 	describe('querySelectorAll', function() {
   87    -1 		it('comma-separated roles', function() {
   -1    86 	describe('querySelectorAll', () => {
   -1    87 		it('comma-separated roles', () => {
   88    88 			testbed.innerHTML = LANDMARKS;
   89    89 			var actual1 = aria.querySelectorAll(testbed, 'banner,main');
   90    90 			expect(actual1.length).toEqual(2);
@@ -93,13 +93,13 @@ describe('query', function() {
   93    93 			expect(actual2.length).toEqual(3);
   94    94 		});
   95    95 
   96    -1 		it('does treat none as alias of presentation', function() {
   -1    96 		it('does treat none as alias of presentation', () => {
   97    97 			testbed.innerHTML = '<a role="presentation"></a><a role="none"></a>';
   98    98 			var actual = aria.querySelectorAll(testbed, 'presentation');
   99    99 			expect(actual.length).toEqual(2);
  100   100 		});
  101   101 
  102    -1 		it('does treat presentation as alias of none', function() {
   -1   102 		it('does treat presentation as alias of none', () => {
  103   103 			testbed.innerHTML = '<a role="presentation"></a><a role="none"></a>';
  104   104 			var actual = aria.querySelectorAll(testbed, 'none');
  105   105 			expect(actual.length).toEqual(2);