axe-core 4.2.0 → 4.2.1
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/.prettierrc.json +10 -0
- package/CHANGELOG.md +11 -0
- package/README.md +1 -1
- package/axe.d.ts +1 -1
- package/axe.js +91 -55
- package/axe.min.js +2 -2
- package/bower.json +1 -1
- package/doc/check-options.md +61 -0
- package/doc/rule-descriptions.md +2 -2
- package/lib/checks/aria/aria-prohibited-attr-evaluate.js +27 -30
- package/lib/checks/aria/aria-prohibited-attr.json +18 -2
- package/lib/checks/aria/aria-required-parent-evaluate.js +14 -4
- package/lib/checks/aria/aria-required-parent.json +3 -0
- package/lib/checks/forms/autocomplete-appropriate-evaluate.js +1 -0
- package/lib/commons/standards/implicit-html-roles.js +16 -11
- package/lib/core/utils/get-standards.js +6 -0
- package/lib/core/utils/index.js +1 -0
- package/lib/rules/frame-focusable-content.json +2 -2
- package/lib/standards/aria-roles.js +1 -1
- package/locales/de.json +29 -29
- package/package.json +4 -4
- package/sri-history.json +4 -0
package/.prettierrc.json
ADDED
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,17 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
|
|
4
4
|
|
|
5
|
+
### [4.2.1](https://github.com/dequelabs/axe-core/compare/v4.2.0...v4.2.1) (2021-05-18)
|
|
6
|
+
|
|
7
|
+
### Bug Fixes
|
|
8
|
+
|
|
9
|
+
- **aria-allowed-attr:** pass aria-label on some HTML elements ([#2935](https://github.com/dequelabs/axe-core/issues/2935)) ([695aa77](https://github.com/dequelabs/axe-core/commit/695aa7751246c0e5e786a66df7808faa7a244576))
|
|
10
|
+
- treat input with no role as textbox ([#2929](https://github.com/dequelabs/axe-core/issues/2929)) ([de18030](https://github.com/dequelabs/axe-core/commit/de180307fd876cfc6a1a0bdb828818a323976c81))
|
|
11
|
+
- **autocomplete-appropriate:** pass for autocomplete=username and type=email ([#2896](https://github.com/dequelabs/axe-core/issues/2896)) ([8b478c8](https://github.com/dequelabs/axe-core/commit/8b478c82b3362fc27df8a0087c779327e6a9d6d0))
|
|
12
|
+
- **getStandards:** Read standards from utils ([#2903](https://github.com/dequelabs/axe-core/issues/2903)) ([52ad4c6](https://github.com/dequelabs/axe-core/commit/52ad4c69991e433d413846c4c9778fdd863aebeb))
|
|
13
|
+
- **required-parent:** Allow *item > group > *item nesting ([#2898](https://github.com/dequelabs/axe-core/issues/2898)) ([3acd229](https://github.com/dequelabs/axe-core/commit/3acd229b08b806ea359e7e08e37e8721cddc5290))
|
|
14
|
+
- **types:** make `evaluate` check optional ([#2902](https://github.com/dequelabs/axe-core/issues/2902)) ([75fabfe](https://github.com/dequelabs/axe-core/commit/75fabfef3adeade350902f2dd18928e44fbb7cf4))
|
|
15
|
+
|
|
5
16
|
## [4.2.0](https://github.com/dequelabs/axe-core/compare/v4.1.2...v4.2.0) (2021-04-23)
|
|
6
17
|
|
|
7
18
|
### Features
|
package/README.md
CHANGED
|
@@ -16,7 +16,7 @@ Axe is an accessibility testing engine for websites and other HTML-based user in
|
|
|
16
16
|
|
|
17
17
|
Axe-core has different types of rules, for WCAG 2.0 and 2.1 on level A and AA, as well as a number of best practices that help you identify common accessibility practices like ensuring every page has an `h1` heading, and to help you avoid "gotchas" in ARIA like where an ARIA attribute you used will get ignored.
|
|
18
18
|
|
|
19
|
-
With axe-core, you can find **
|
|
19
|
+
With axe-core, you can find **on average 57% of WCAG issues automatically**. Additionally, axe-core will return elements as "incomplete" where axe-core could not be certain, and manual review is needed. To further improve test coverage we recommend the [intelligent guided tests](https://www.youtube.com/watch?v=AtsX0dPCG_4&feature=youtu.be&ab_channel=DequeSystems) in the [axe Extension](https://www.deque.com/axe/browser-extensions/).
|
|
20
20
|
|
|
21
21
|
The complete list of rules, grouped WCAG level and best practice, can found in [doc/rule-descriptions.md](./doc/rule-descriptions.md).
|
|
22
22
|
|
package/axe.d.ts
CHANGED
package/axe.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! axe v4.2.
|
|
1
|
+
/*! axe v4.2.1
|
|
2
2
|
* Copyright (c) 2021 Deque Systems, Inc.
|
|
3
3
|
*
|
|
4
4
|
* Your use of this Source Code Form is subject to the terms of the Mozilla Public
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
return _typeof(obj);
|
|
28
28
|
}
|
|
29
29
|
var axe = axe || {};
|
|
30
|
-
axe.version = '4.2.
|
|
30
|
+
axe.version = '4.2.1';
|
|
31
31
|
if (typeof define === 'function' && define.amd) {
|
|
32
32
|
define('axe-core', [], function() {
|
|
33
33
|
return axe;
|
|
@@ -5067,6 +5067,9 @@
|
|
|
5067
5067
|
getShadowSelector: function getShadowSelector() {
|
|
5068
5068
|
return get_shadow_selector_default;
|
|
5069
5069
|
},
|
|
5070
|
+
getStandards: function getStandards() {
|
|
5071
|
+
return _getStandards;
|
|
5072
|
+
},
|
|
5070
5073
|
getStyleSheetFactory: function getStyleSheetFactory() {
|
|
5071
5074
|
return get_stylesheet_factory_default;
|
|
5072
5075
|
},
|
|
@@ -8483,7 +8486,7 @@
|
|
|
8483
8486
|
},
|
|
8484
8487
|
listitem: {
|
|
8485
8488
|
type: 'structure',
|
|
8486
|
-
requiredContext: [ 'list' ],
|
|
8489
|
+
requiredContext: [ 'list', 'group' ],
|
|
8487
8490
|
allowedAttrs: [ 'aria-level', 'aria-posinset', 'aria-setsize', 'aria-expanded' ],
|
|
8488
8491
|
superclassRole: [ 'section' ],
|
|
8489
8492
|
nameFromContent: true
|
|
@@ -10751,6 +10754,9 @@
|
|
|
10751
10754
|
return windowScroll.concat(getElmScrollRecursive(document.body));
|
|
10752
10755
|
}
|
|
10753
10756
|
var get_scroll_state_default = getScrollState;
|
|
10757
|
+
function _getStandards() {
|
|
10758
|
+
return clone_default(standards_default);
|
|
10759
|
+
}
|
|
10754
10760
|
function getStyleSheetFactory(dynamicDoc) {
|
|
10755
10761
|
if (!dynamicDoc) {
|
|
10756
10762
|
throw new Error('axe.utils.getStyleSheetFactory should be invoked with an argument');
|
|
@@ -12155,22 +12161,9 @@
|
|
|
12155
12161
|
suggestionsSourceElement = listElement && listElement.nodeName.toLowerCase() === 'datalist';
|
|
12156
12162
|
}
|
|
12157
12163
|
switch (vNode.props.type) {
|
|
12158
|
-
case 'button':
|
|
12159
|
-
case 'image':
|
|
12160
|
-
case 'reset':
|
|
12161
|
-
case 'submit':
|
|
12162
|
-
return 'button';
|
|
12163
|
-
|
|
12164
12164
|
case 'checkbox':
|
|
12165
12165
|
return 'checkbox';
|
|
12166
12166
|
|
|
12167
|
-
case 'email':
|
|
12168
|
-
case 'tel':
|
|
12169
|
-
case 'text':
|
|
12170
|
-
case 'url':
|
|
12171
|
-
case '':
|
|
12172
|
-
return !suggestionsSourceElement ? 'textbox' : 'combobox';
|
|
12173
|
-
|
|
12174
12167
|
case 'number':
|
|
12175
12168
|
return 'spinbutton';
|
|
12176
12169
|
|
|
@@ -12182,6 +12175,22 @@
|
|
|
12182
12175
|
|
|
12183
12176
|
case 'search':
|
|
12184
12177
|
return !suggestionsSourceElement ? 'searchbox' : 'combobox';
|
|
12178
|
+
|
|
12179
|
+
case 'button':
|
|
12180
|
+
case 'image':
|
|
12181
|
+
case 'reset':
|
|
12182
|
+
case 'submit':
|
|
12183
|
+
return 'button';
|
|
12184
|
+
|
|
12185
|
+
case 'text':
|
|
12186
|
+
case 'tel':
|
|
12187
|
+
case 'url':
|
|
12188
|
+
case 'email':
|
|
12189
|
+
case '':
|
|
12190
|
+
return !suggestionsSourceElement ? 'textbox' : 'combobox';
|
|
12191
|
+
|
|
12192
|
+
default:
|
|
12193
|
+
return 'textbox';
|
|
12185
12194
|
}
|
|
12186
12195
|
},
|
|
12187
12196
|
li: 'listitem',
|
|
@@ -15425,29 +15434,35 @@
|
|
|
15425
15434
|
return virtualNode.attr('aria-hidden') !== 'true';
|
|
15426
15435
|
}
|
|
15427
15436
|
var aria_hidden_body_evaluate_default = ariaHiddenBodyEvaluate;
|
|
15428
|
-
function ariaProhibitedAttrEvaluate(node
|
|
15429
|
-
var
|
|
15430
|
-
var
|
|
15431
|
-
var
|
|
15432
|
-
var
|
|
15433
|
-
|
|
15437
|
+
function ariaProhibitedAttrEvaluate(node) {
|
|
15438
|
+
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
15439
|
+
var virtualNode = arguments.length > 2 ? arguments[2] : undefined;
|
|
15440
|
+
var _options$elementsAllo = options.elementsAllowedAriaLabel, elementsAllowedAriaLabel = _options$elementsAllo === void 0 ? [] : _options$elementsAllo;
|
|
15441
|
+
var prohibitedList = listProhibitedAttrs(virtualNode, elementsAllowedAriaLabel);
|
|
15442
|
+
var prohibited = prohibitedList.filter(function(attrName) {
|
|
15443
|
+
if (!virtualNode.attrNames.includes(attrName)) {
|
|
15444
|
+
return false;
|
|
15445
|
+
}
|
|
15446
|
+
return sanitize_default(virtualNode.attr(attrName)) !== '';
|
|
15447
|
+
});
|
|
15448
|
+
if (prohibited.length === 0) {
|
|
15434
15449
|
return false;
|
|
15435
15450
|
}
|
|
15436
|
-
|
|
15437
|
-
|
|
15438
|
-
|
|
15439
|
-
|
|
15440
|
-
|
|
15441
|
-
|
|
15451
|
+
this.data(prohibited);
|
|
15452
|
+
var hasTextContent = sanitize_default(subtree_text_default(virtualNode)) !== '';
|
|
15453
|
+
return hasTextContent ? void 0 : true;
|
|
15454
|
+
}
|
|
15455
|
+
function listProhibitedAttrs(virtualNode, elementsAllowedAriaLabel) {
|
|
15456
|
+
var role = get_role_default(virtualNode);
|
|
15457
|
+
var roleSpec = standards_default.ariaRoles[role];
|
|
15458
|
+
if (roleSpec) {
|
|
15459
|
+
return roleSpec.prohibitedAttrs || [];
|
|
15442
15460
|
}
|
|
15443
|
-
|
|
15444
|
-
|
|
15445
|
-
|
|
15446
|
-
return void 0;
|
|
15447
|
-
}
|
|
15448
|
-
return true;
|
|
15461
|
+
var nodeName2 = virtualNode.props.nodeName;
|
|
15462
|
+
if (elementsAllowedAriaLabel.includes(nodeName2)) {
|
|
15463
|
+
return [];
|
|
15449
15464
|
}
|
|
15450
|
-
return
|
|
15465
|
+
return [ 'aria-label', 'aria-labelledby' ];
|
|
15451
15466
|
}
|
|
15452
15467
|
var aria_prohibited_attr_evaluate_default = ariaProhibitedAttrEvaluate;
|
|
15453
15468
|
var standards_exports = {};
|
|
@@ -15484,8 +15499,8 @@
|
|
|
15484
15499
|
required = unique_array_default(options[role], required);
|
|
15485
15500
|
}
|
|
15486
15501
|
if (role && required) {
|
|
15487
|
-
for (var
|
|
15488
|
-
var attr = required[
|
|
15502
|
+
for (var _i14 = 0, l = required.length; _i14 < l; _i14++) {
|
|
15503
|
+
var attr = required[_i14];
|
|
15489
15504
|
if (!virtualNode.attr(attr) && !(elmSpec.implicitAttrs && typeof elmSpec.implicitAttrs[attr] !== 'undefined')) {
|
|
15490
15505
|
missing.push(attr);
|
|
15491
15506
|
}
|
|
@@ -15502,8 +15517,8 @@
|
|
|
15502
15517
|
function getOwnedRoles(virtualNode, required) {
|
|
15503
15518
|
var ownedRoles = [];
|
|
15504
15519
|
var ownedElements = get_owned_virtual_default(virtualNode);
|
|
15505
|
-
var _loop4 = function _loop4(
|
|
15506
|
-
var ownedElement = ownedElements[
|
|
15520
|
+
var _loop4 = function _loop4(_i15) {
|
|
15521
|
+
var ownedElement = ownedElements[_i15];
|
|
15507
15522
|
var role = get_role_default(ownedElement, {
|
|
15508
15523
|
noPresentational: true
|
|
15509
15524
|
});
|
|
@@ -15515,8 +15530,8 @@
|
|
|
15515
15530
|
ownedRoles.push(role);
|
|
15516
15531
|
}
|
|
15517
15532
|
};
|
|
15518
|
-
for (var
|
|
15519
|
-
_loop4(
|
|
15533
|
+
for (var _i15 = 0; _i15 < ownedElements.length; _i15++) {
|
|
15534
|
+
_loop4(_i15);
|
|
15520
15535
|
}
|
|
15521
15536
|
return ownedRoles;
|
|
15522
15537
|
}
|
|
@@ -15537,8 +15552,8 @@
|
|
|
15537
15552
|
return !expandedChildRoles.includes(requiredRole) || expanded && requiredRole === popupRole;
|
|
15538
15553
|
});
|
|
15539
15554
|
}
|
|
15540
|
-
for (var
|
|
15541
|
-
var ownedRole = ownedRoles[
|
|
15555
|
+
for (var _i16 = 0; _i16 < ownedRoles.length; _i16++) {
|
|
15556
|
+
var ownedRole = ownedRoles[_i16];
|
|
15542
15557
|
if (required.includes(ownedRole)) {
|
|
15543
15558
|
required = required.filter(function(requiredRole) {
|
|
15544
15559
|
return requiredRole !== ownedRole;
|
|
@@ -15574,7 +15589,7 @@
|
|
|
15574
15589
|
return false;
|
|
15575
15590
|
}
|
|
15576
15591
|
var aria_required_children_evaluate_default = ariaRequiredChildrenEvaluate;
|
|
15577
|
-
function getMissingContext(virtualNode, reqContext, includeElement) {
|
|
15592
|
+
function getMissingContext(virtualNode, ownGroupRoles, reqContext, includeElement) {
|
|
15578
15593
|
var explicitRole2 = get_explicit_role_default(virtualNode);
|
|
15579
15594
|
if (!reqContext) {
|
|
15580
15595
|
reqContext = required_context_default(explicitRole2);
|
|
@@ -15586,6 +15601,9 @@
|
|
|
15586
15601
|
while (vNode) {
|
|
15587
15602
|
var parentRole = get_role_default(vNode);
|
|
15588
15603
|
if (reqContext.includes('group') && parentRole === 'group') {
|
|
15604
|
+
if (ownGroupRoles.includes(explicitRole2)) {
|
|
15605
|
+
reqContext.push(explicitRole2);
|
|
15606
|
+
}
|
|
15589
15607
|
vNode = vNode.parent;
|
|
15590
15608
|
continue;
|
|
15591
15609
|
}
|
|
@@ -15614,14 +15632,15 @@
|
|
|
15614
15632
|
return owners.length ? owners : null;
|
|
15615
15633
|
}
|
|
15616
15634
|
function ariaRequiredParentEvaluate(node, options, virtualNode) {
|
|
15617
|
-
var
|
|
15635
|
+
var ownGroupRoles = options && Array.isArray(options.ownGroupRoles) ? options.ownGroupRoles : [];
|
|
15636
|
+
var missingParents = getMissingContext(virtualNode, ownGroupRoles);
|
|
15618
15637
|
if (!missingParents) {
|
|
15619
15638
|
return true;
|
|
15620
15639
|
}
|
|
15621
15640
|
var owners = getAriaOwners(node);
|
|
15622
15641
|
if (owners) {
|
|
15623
|
-
for (var
|
|
15624
|
-
missingParents = getMissingContext(get_node_from_tree_default(owners[
|
|
15642
|
+
for (var _i17 = 0, l = owners.length; _i17 < l; _i17++) {
|
|
15643
|
+
missingParents = getMissingContext(get_node_from_tree_default(owners[_i17]), ownGroupRoles, missingParents, true);
|
|
15625
15644
|
if (!missingParents) {
|
|
15626
15645
|
return true;
|
|
15627
15646
|
}
|
|
@@ -16823,6 +16842,7 @@
|
|
|
16823
16842
|
var allowedTypesMap = {
|
|
16824
16843
|
bday: [ 'text', 'search', 'date' ],
|
|
16825
16844
|
email: [ 'text', 'search', 'email' ],
|
|
16845
|
+
username: [ 'text', 'search', 'email' ],
|
|
16826
16846
|
'street-address': [ 'text' ],
|
|
16827
16847
|
tel: [ 'text', 'search', 'tel' ],
|
|
16828
16848
|
'tel-country-code': [ 'text', 'search', 'tel' ],
|
|
@@ -21059,8 +21079,8 @@
|
|
|
21059
21079
|
help: 'Form field must not have multiple label elements'
|
|
21060
21080
|
},
|
|
21061
21081
|
'frame-focusable-content': {
|
|
21062
|
-
description: 'Ensures <frame> and <iframe> elements with
|
|
21063
|
-
help: 'Frames with
|
|
21082
|
+
description: 'Ensures <frame> and <iframe> elements with focusable content do not have tabindex=-1',
|
|
21083
|
+
help: 'Frames with focusable content must not have tabindex=-1'
|
|
21064
21084
|
},
|
|
21065
21085
|
'frame-tested': {
|
|
21066
21086
|
description: 'Ensures <iframe> and <frame> elements contain the axe-core script',
|
|
@@ -21340,10 +21360,10 @@
|
|
|
21340
21360
|
}
|
|
21341
21361
|
},
|
|
21342
21362
|
'aria-prohibited-attr': {
|
|
21343
|
-
impact: '
|
|
21363
|
+
impact: 'serious',
|
|
21344
21364
|
messages: {
|
|
21345
21365
|
pass: 'ARIA attribute is allowed',
|
|
21346
|
-
fail: 'ARIA attribute cannot be used: ${data.values}',
|
|
21366
|
+
fail: 'ARIA attribute cannot be used, add a role attribute or use a different element: ${data.values}',
|
|
21347
21367
|
incomplete: 'ARIA attribute is not well supported on the element and the text content will be used instead: ${data.values}'
|
|
21348
21368
|
}
|
|
21349
21369
|
},
|
|
@@ -22203,7 +22223,12 @@
|
|
|
22203
22223
|
tags: [ 'cat.aria', 'wcag2a', 'wcag412' ],
|
|
22204
22224
|
all: [],
|
|
22205
22225
|
any: [ 'aria-allowed-attr' ],
|
|
22206
|
-
none: [ 'aria-unsupported-attr',
|
|
22226
|
+
none: [ 'aria-unsupported-attr', {
|
|
22227
|
+
options: {
|
|
22228
|
+
elementsAllowedAriaLabel: [ 'audio', 'applet', 'canvas', 'dl', 'embed', 'iframe', 'input', 'label', 'meter', 'object', 'svg', 'video' ]
|
|
22229
|
+
},
|
|
22230
|
+
id: 'aria-prohibited-attr'
|
|
22231
|
+
} ]
|
|
22207
22232
|
}, {
|
|
22208
22233
|
id: 'aria-allowed-role',
|
|
22209
22234
|
excludeHidden: false,
|
|
@@ -22328,7 +22353,12 @@
|
|
|
22328
22353
|
matches: 'aria-required-parent-matches',
|
|
22329
22354
|
tags: [ 'cat.aria', 'wcag2a', 'wcag131' ],
|
|
22330
22355
|
all: [],
|
|
22331
|
-
any: [
|
|
22356
|
+
any: [ {
|
|
22357
|
+
options: {
|
|
22358
|
+
ownGroupRoles: [ 'listitem', 'treeitem' ]
|
|
22359
|
+
},
|
|
22360
|
+
id: 'aria-required-parent'
|
|
22361
|
+
} ],
|
|
22332
22362
|
none: []
|
|
22333
22363
|
}, {
|
|
22334
22364
|
id: 'aria-roledescription',
|
|
@@ -23237,7 +23267,10 @@
|
|
|
23237
23267
|
evaluate: 'aria-hidden-body-evaluate'
|
|
23238
23268
|
}, {
|
|
23239
23269
|
id: 'aria-prohibited-attr',
|
|
23240
|
-
evaluate: 'aria-prohibited-attr-evaluate'
|
|
23270
|
+
evaluate: 'aria-prohibited-attr-evaluate',
|
|
23271
|
+
options: {
|
|
23272
|
+
elementsAllowedAriaLabel: [ 'audio', 'applet', 'canvas', 'dl', 'embed', 'iframe', 'input', 'label', 'meter', 'object', 'svg', 'video' ]
|
|
23273
|
+
}
|
|
23241
23274
|
}, {
|
|
23242
23275
|
id: 'aria-required-attr',
|
|
23243
23276
|
evaluate: 'aria-required-attr-evaluate'
|
|
@@ -23249,7 +23282,10 @@
|
|
|
23249
23282
|
}
|
|
23250
23283
|
}, {
|
|
23251
23284
|
id: 'aria-required-parent',
|
|
23252
|
-
evaluate: 'aria-required-parent-evaluate'
|
|
23285
|
+
evaluate: 'aria-required-parent-evaluate',
|
|
23286
|
+
options: {
|
|
23287
|
+
ownGroupRoles: [ 'listitem', 'treeitem' ]
|
|
23288
|
+
}
|
|
23253
23289
|
}, {
|
|
23254
23290
|
id: 'aria-roledescription',
|
|
23255
23291
|
evaluate: 'aria-roledescription-evaluate',
|