Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
56 commits
Select commit Hold shift + click to select a range
f89c13b
chore: merge master into develop (#4382)
straker Mar 25, 2024
105016c
fix(invalidrole): allow upper and mixed case role names (#4358)
lsprr Apr 1, 2024
4788bf8
fix(aria-allowed-role): add gridcell, separator, slider and treeitem …
msereniti Apr 5, 2024
c215a9d
fix(label-content-name-mismatch): better dismiss and wysiwyg symbolic…
gaiety-deque Apr 9, 2024
9ecf596
chore: bump chromedriver from 122.0.4 to 123.0.1 (#4391)
dependabot[bot] Apr 10, 2024
44e39ec
chore: bump the npm-low-risk group with 11 updates (#4403)
dependabot[bot] Apr 10, 2024
5c318f3
fix: fix building axe-core translation files with region locales (#4396)
straker Apr 10, 2024
0cd9d71
fix(label-content-name-mismatch): fewer blocklists, handle all single…
gaiety-deque Apr 11, 2024
9ed16e6
fix(label-content-name-mismatch): refactor isHumanInterpretable, test…
gaiety-deque Apr 11, 2024
30d8388
fix(label-content-name-mismatch): 0 for all single char, cjk & x test…
gaiety-deque Apr 11, 2024
c4aa062
fix(label-content-name-mismatch): simpler non-digit check, test added
gaiety-deque Apr 11, 2024
56e139a
fix(label-content-name-mismatch): better dismiss and wysiwyg symbolic…
gaiety-deque Apr 15, 2024
2940f6e
fix(isVisibleOnScreen): account for position: absolute elements insid…
straker Apr 15, 2024
75b0c11
build: pass `posix` option to build in windows (#4409)
michael-siek Apr 15, 2024
ace25cd
fix(region): img alt='' ignored by region rule
gaiety-deque Apr 16, 2024
7c810e2
fix(region): replaces tabs for spaces in prior commit
gaiety-deque Apr 16, 2024
551ba24
fix(aria-valid-attr-value): aria-controls & aria-haspopup incomplete
gaiety-deque Apr 19, 2024
08ddcbc
chore: Update local de.json (#4408)
EvilKarter Apr 22, 2024
69f778b
fix(aria-roles): correct abstract roles (types) for aria-roles
gaiety-deque Apr 22, 2024
ffe37f6
fix(aria-roles): table with role application is structure
gaiety-deque Apr 22, 2024
aa1aa20
fix(aria-roles): inline widgets consider composite type
gaiety-deque Apr 22, 2024
a823712
fix(aria-valid-attr-value): more thorough test coverage
gaiety-deque Apr 23, 2024
3a90bb7
fix(target-size): pass for element that has nearby elements that are …
straker Apr 23, 2024
6091367
fix(target-size): ignore descendant elements in shadow dom (#4410)
straker Apr 23, 2024
fd59e8d
Merge branch 'develop' into aria-role-abstract-corrections
gaiety-deque Apr 23, 2024
a55740f
docs: add readme to locales dir to note _template is generated (#4425)
straker Apr 24, 2024
61cbf30
docs: update required develop node version to 18 (#4424)
straker Apr 24, 2024
2d185f6
fix(aria-roles): address pr comments
gaiety-deque Apr 25, 2024
417e6b1
fix(aria-roles): reverted test change as well
gaiety-deque Apr 25, 2024
facd65f
fix(aria-roles): exception for focus-order-semantics
gaiety-deque Apr 25, 2024
bfa95ae
fix(aria-roles): updated locales
gaiety-deque Apr 25, 2024
29e7e2a
revert(color-contrast): revert upgrade to colorjs.io v0.5.0 to work w…
straker Apr 25, 2024
5c5ede0
chore: set up vscode config to attach to test:debug (#4430)
dbjorge Apr 26, 2024
ef1e09d
fix(aria-valid-attr-value): aria-controls & aria-haspopup incomplete …
gaiety-deque Apr 29, 2024
a07c488
Revert "fix(aria-roles): exception for focus-order-semantics"
gaiety-deque Apr 29, 2024
f11c03f
fix(aria-roles): support window role in valid-scrollable-semantics
gaiety-deque Apr 29, 2024
d856316
fix(aria-roles): window roles and marque/timer expectations in focus-…
gaiety-deque Apr 29, 2024
dc966d3
Revert "fix(aria-roles): updated locales"
gaiety-deque Apr 29, 2024
9b15ae0
fix(aria-roles): log and status allowed in focus-order-semantics
gaiety-deque Apr 29, 2024
eac8223
chore(i18n): Fix typo in locales/ja.json (#4426)
ymrl Apr 29, 2024
5594d8f
fix(aria-roles): target-size tests consider changed aria roles
gaiety-deque Apr 29, 2024
70b6ddb
Merge branch 'develop' into region-rule-ignores-decorative-image
gaiety-deque Apr 30, 2024
f914665
add suggested isShallowlyHidden instead of presentational
gaiety-deque Apr 30, 2024
be633af
rely on getRole instead of adding hasGlobalAttr and focusable unecess…
gaiety-deque Apr 30, 2024
d515329
additional test for overwritten role with nested child content
gaiety-deque Apr 30, 2024
7ac6392
fix(aria-allowed-attr): allow meter role allowed aria-* attributes on…
straker May 1, 2024
19bde94
fix(aria-roles): correct abstract roles (types) for aria-roles (#4421)
gaiety-deque May 2, 2024
bc6dc71
Merge branch 'develop' into region-rule-ignores-decorative-image
gaiety-deque May 2, 2024
b29a90d
Update lib/checks/navigation/region-evaluate.js
gaiety-deque May 2, 2024
53782f2
additional test coverage
gaiety-deque May 2, 2024
8938496
targeted test failure cases
gaiety-deque May 2, 2024
738e9e2
Update test/integration/full/region/region-pass.html
gaiety-deque May 3, 2024
f8c918d
fix(region): Decorative images ignored by region rule (#4412)
gaiety-deque May 3, 2024
821b864
chore(release): 4.9.1
attest-team-ci May 6, 2024
a2b8da3
Update changelog
WilcoFiers May 6, 2024
0f2b8ac
chore(changelog): Update for 4.9.1
WilcoFiers May 6, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 26 additions & 2 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,13 +59,37 @@ module.exports = {
selector: 'MemberExpression[property.name=tagName]',
message: "Don't use node.tagName, use node.nodeName instead."
},
// node.attributes can be clobbered so is unsafe to use
// @see https://github.com/dequelabs/axe-core/pull/1432
{
// node.attributes can be clobbered so is unsafe to use
// @see https://github.com/dequelabs/axe-core/pull/1432
// node.attributes
selector:
'MemberExpression[object.name=node][property.name=attributes]',
message:
"Don't use node.attributes, use node.hasAttributes() or axe.utils.getNodeAttributes(node) instead."
},
{
// vNode.actualNode.attributes
selector:
'MemberExpression[object.property.name=actualNode][property.name=attributes]',
message:
"Don't use node.attributes, use node.hasAttributes() or axe.utils.getNodeAttributes(node) instead."
},
// node.contains doesn't work with shadow dom
// @see https://github.com/dequelabs/axe-core/issues/4194
{
// node.contains()
selector:
'CallExpression[callee.object.name=node][callee.property.name=contains]',
message:
"Don't use node.contains(node2) as it doesn't work across shadow DOM. Use axe.utils.contains(node, node2) instead."
},
{
// vNode.actualNode.contains()
selector:
'CallExpression[callee.object.property.name=actualNode][callee.property.name=contains]',
message:
"Don't use node.contains(node2) as it doesn't work across shadow DOM. Use axe.utils.contains(node, node2) instead."
}
]
},
Expand Down
18 changes: 18 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"version": "0.2.0",
"configurations": [
{
"type": "chrome",
"request": "attach",
"name": "Attach to Karma test:debug",
"address": "localhost",
"port": 9765, // keep in sync with debugPort in karma.conf.js
"webRoot": "${workspaceFolder}",
"sourceMaps": true,
"sourceMapPathOverrides": {
"*": "${webRoot}/*",
"base/*": "${webRoot}/*"
}
}
]
}
17 changes: 17 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,23 @@

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.9.1](https://github.com/dequelabs/axe-core/compare/v4.9.0...v4.9.1) (2024-05-06)

### Bug Fixes

- Prevent errors when loading axe in a page with prototype.js
- **aria-allowed-attr:** allow meter role allowed aria-\* attributes on meter element ([#4435](https://github.com/dequelabs/axe-core/issues/4435)) ([7ac6392](https://github.com/dequelabs/axe-core/commit/7ac63921e7fab21f3359dcfc8affa7585bc9c25b))
- **aria-allowed-role:** add gridcell, separator, slider and treeitem to allowed roles of button element ([#4398](https://github.com/dequelabs/axe-core/issues/4398)) ([4788bf8](https://github.com/dequelabs/axe-core/commit/4788bf8d6fd963d7b017dad950b122ffcea8d151))
- **aria-roles:** correct abstract roles (types) for aria-roles([#4421](https://github.com/dequelabs/axe-core/pull/4421))
- **aria-valid-attr-value:** aria-controls & aria-haspopup incomplete ([#4418](https://github.com/dequelabs/axe-core/pull/4418))
- fix building axe-core translation files with region locales ([#4396](https://github.com/dequelabs/axe-core/issues/4396)) ([5c318f3](https://github.com/dequelabs/axe-core/commit/5c318f3537056be5779cb53374bc6f4785947c91)), closes [#4388](https://github.com/dequelabs/axe-core/issues/4388)
- **invalidrole:** allow upper and mixed case role names ([#4358](https://github.com/dequelabs/axe-core/issues/4358)) ([105016c](https://github.com/dequelabs/axe-core/commit/105016cfe9d82876cfed2ff5c656a7842c5b3761)), closes [#2695](https://github.com/dequelabs/axe-core/issues/2695)
- **isVisibleOnScreen:** account for position: absolute elements inside overflow container ([#4405](https://github.com/dequelabs/axe-core/issues/4405)) ([2940f6e](https://github.com/dequelabs/axe-core/commit/2940f6ee36ba52d8cf089be2a3c8e7c516c81dd6)), closes [#4016](https://github.com/dequelabs/axe-core/issues/4016)
- **label-content-name-mismatch:** better dismiss and wysiwyg symbolic text characters ([#4402](https://github.com/dequelabs/axe-core/issues/4402))
- **region:** Decorative images ignored by region rule ([#4412](https://github.com/dequelabs/axe-core/pull/4412))
- **target-size:** ignore descendant elements in shadow dom ([#4410](https://github.com/dequelabs/axe-core/issues/4410)) ([6091367](https://github.com/dequelabs/axe-core/commit/6091367a20f70e536fc7e8d77eae4fa7232bc7c0))
- **target-size:** pass for element that has nearby elements that are obscured ([#4422](https://github.com/dequelabs/axe-core/issues/4422)) ([3a90bb7](https://github.com/dequelabs/axe-core/commit/3a90bb70c8db087b2f03cc30a4aee756995c311c)), closes [#4387](https://github.com/dequelabs/axe-core/issues/4387)

## [4.9.0](https://github.com/dequelabs/axe-core/compare/v4.8.4...v4.9.0) (2024-03-25)

### Features
Expand Down
2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ If you need to debug the unit tests in a browser, you can run:
npm run test:debug
```

This will start the Karma server and open up the Chrome browser. Click the `Debug` button to start debugging the tests. You can also navigate to the listed URL in your browser of choice to debug tests using that browser.
This will start the Karma server and open up the Chrome browser. Click the `Debug` button to start debugging the tests. You can either use that browser's debugger or attach an external debugger on port 9765; [a VS Code launch profile](./.vscode/launch.json) is provided. You can also navigate to the listed URL in your browser of choice to debug tests using that browser.

Because the amount of tests is so large, it's recommended to debug only a specific set of unit tests rather than the whole test suite. You can use the `testDirs` argument when using the debug command and pass a specific test directory. The test directory names are the same as those used for `test:unit:*`:

Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -103,9 +103,9 @@ or equivalently:

This will create a new build for axe, called `axe.<lang>.js` and `axe.<lang>.min.js`. If you want to build all localized versions, simply pass in `--all-lang` instead. If you want to build multiple localized versions (but not all of them), you can pass in a comma-separated list of languages to the `--lang` flag, like `--lang=nl,ja`.

To create a new translation for axe, start by running `grunt translate --lang=<langcode>`. This will create a json file fin the `./locales` directory, with the default English text in it for you to translate. Alternatively, you could copy `./locales/_template.json`. We welcome any localization for axe-core. For details on how to contribute, see the Contributing section below. For details on the message syntax, see [Check Message Template](/doc/check-message-template.md).
To create a new translation for axe, start by running `grunt translate --lang=<langcode>`. This will create a json file in the `./locales` directory, with the default English text in it for you to translate. Alternatively, you could copy `./locales/_template.json`. We welcome any localization for axe-core. For details on how to contribute, see the Contributing section below. For details on the message syntax, see [Check Message Template](/doc/check-message-template.md).

To update existing translation file, re-run `grunt translate --lang=<langcode>`. This will add new messages used in English and remove messages which were not used in English.
To update an existing translation file, re-run `grunt translate --lang=<langcode>`. This will add new messages used in English and remove messages which were not used in English.

Additionally, locale can be applied at runtime by passing a `locale` object to `axe.configure()`. The locale object must be of the same shape as existing locales in the `./locales` directory. For example:

Expand Down
2 changes: 1 addition & 1 deletion bower.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "axe-core",
"version": "4.9.0",
"version": "4.9.1",
"deprecated": true,
"contributors": [
{
Expand Down
15 changes: 12 additions & 3 deletions build/rule-generator/questions.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,10 @@ const validateGetRuleName = async input => {
throw new Error(`RULE name conflicts with an existing rule's filename.`);
}
// 3) ensure no rule id overlaps
const ruleSpecs = await glob(`${directories.rules}/**/*.json`);
const ruleSpecs = await glob(`${directories.rules}/**/*.json`, {
posix: true,
absolute: true
});
const axeRulesIds = ruleSpecs.reduce((out, specPath) => {
const spec = require(specPath);
out.push(spec.id);
Expand Down Expand Up @@ -62,7 +65,10 @@ const validateGetCheckName = async input => {
);
}
// 2) ensure no check filename overlaps
const checkSpecs = await glob(`${directories.checks}/**/*.json`);
const checkSpecs = await glob(`${directories.checks}/**/*.json`, {
posix: true,
absolute: true
});
// cannot use `fs.existsSync` here, as we do not know which category of checks to look under
const axeChecksFileNames = checkSpecs.map(
f => f.replace('.json', '').split('/').reverse()[0]
Expand All @@ -71,7 +77,10 @@ const validateGetCheckName = async input => {
throw new Error('CHECK name conflicts with an existing filename.');
}
// 3) ensure no check id overlaps
const ruleSpecs = await glob(`${directories.rules}/**/*.json`);
const ruleSpecs = await glob(`${directories.rules}/**/*.json`, {
posix: true,
absolute: true
});
const axe = require(directories.axePath);
const axeChecksIds = ruleSpecs.reduce((out, specPath) => {
const spec = require(specPath);
Expand Down
8 changes: 5 additions & 3 deletions build/tasks/configure.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,11 @@ module.exports = function (grunt) {
});

this.files.forEach(function (file) {
const match = file.dest.auto.match(/\.([a-z]{2,3})\.js/);
if (match) {
options.locale = match[1];
// locale will always be the 2nd to last part of the
// filename and in the format of "<name>.<locale>.js"
const parts = file.dest.auto.split('.');
if (parts.length > 2) {
options.locale = parts[parts.length - 2];
}

buildRules(grunt, options, null, function (result) {
Expand Down
2 changes: 1 addition & 1 deletion build/tasks/metadata-function-map.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ module.exports = function (grunt) {
'// This file is automatically generated using build/tasks/metadata-function-map.js\n';

src.forEach(globPath => {
glob.sync(globPath).forEach(filePath => {
glob.sync(globPath, { posix: true }).forEach(filePath => {
const relativePath = path.relative(
path.dirname(file.dest),
filePath
Expand Down
4 changes: 2 additions & 2 deletions doc/developer-guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ Axe 3.0 supports open Shadow DOM: see our virtual DOM APIs and test utilities fo

### Environment Pre-requisites

1. You must have NodeJS version 12 or higher installed.
1. You must have NodeJS version 18 or higher installed.
1. Install npm development dependencies. In the root folder of your axe-core repository, run `npm install`

### Building axe.js
Expand Down Expand Up @@ -71,7 +71,7 @@ There are also a set of tests that are not considered unit tests that you can ru

Additionally, you can [watch for changes](#watching-for-changes) to files and automatically run the relevant tests.

If you need to debug a test in a non-headless browser, you can run `npm run test:debug` which will run the Karma tests in non-headless Chrome. You can also navigate to the newly opened page using any supported browser.
If you need to debug a test in a non-headless browser, you can run `npm run test:debug` which will run the Karma tests in non-headless Chrome. You can either use that browser's debugger or attach an external debugger on port 9765; [a VS Code launch profile](../.vscode/launch.json) is provided. You can also navigate to the newly opened page using any supported browser.

You can scope which set of tests to debug by passing the `testDirs` argument. Supported values are:

Expand Down
6 changes: 4 additions & 2 deletions doc/standards-object.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,9 +67,11 @@ The [`ariaRoles`](../lib/standards/aria-roles.js) object defines valid ARIA role

- `type` - string(required). [The role type](https://www.w3.org/TR/wai-aria-1.1/#roles_categorization). Valid types are:
- `abstract`
- `widget`
- `structure`
- `composite`
- `landmark`
- `structure`
- `widget`
- `window`
- `requiredContext` - array(optional). List of required parent roles.
- `requiredOwned` - array(optional). List of required owned roles.
- `requiredAttrs` - array(optional). List of required attributes.
Expand Down
15 changes: 13 additions & 2 deletions lib/checks/aria/aria-valid-attr-value-evaluate.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,23 @@ export default function ariaValidAttrValueEvaluate(node, options, virtualNode) {

const preChecks = {
// aria-controls should only check if element exists if the element
// doesn't have aria-expanded=false or aria-selected=false (tabs)
// doesn't have aria-expanded=false, aria-selected=false (tabs),
// or aria-haspopup (may load later)
// @see https://github.com/dequelabs/axe-core/issues/1463
// @see https://github.com/dequelabs/axe-core/issues/4363
'aria-controls': () => {
const hasPopup =
['false', null].includes(virtualNode.attr('aria-haspopup')) === false;

if (hasPopup) {
needsReview = `aria-controls="${virtualNode.attr('aria-controls')}"`;
messageKey = 'controlsWithinPopup';
}

return (
virtualNode.attr('aria-expanded') !== 'false' &&
virtualNode.attr('aria-selected') !== 'false'
virtualNode.attr('aria-selected') !== 'false' &&
hasPopup === false
);
},
// aria-current should mark as needs review if any value is used that is
Expand Down
3 changes: 2 additions & 1 deletion lib/checks/aria/aria-valid-attr-value.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@
"noIdShadow": "ARIA attribute element ID does not exist on the page or is a descendant of a different shadow DOM tree: ${data.needsReview}",
"ariaCurrent": "ARIA attribute value is invalid and will be treated as \"aria-current=true\": ${data.needsReview}",
"idrefs": "Unable to determine if ARIA attribute element ID exists on the page: ${data.needsReview}",
"empty": "ARIA attribute value is ignored while empty: ${data.needsReview}"
"empty": "ARIA attribute value is ignored while empty: ${data.needsReview}",
"controlsWithinPopup": "Unable to determine if aria-controls referenced ID exists on the page while using aria-haspopup: ${data.needsReview}"
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion lib/checks/aria/invalidrole-evaluate.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ import { tokenList } from '../../core/utils';
function invalidroleEvaluate(node, options, virtualNode) {
const allRoles = tokenList(virtualNode.attr('role'));
const allInvalid = allRoles.every(
role => !isValidRole(role, { allowAbstract: true })
role => !isValidRole(role.toLowerCase(), { allowAbstract: true })
);

/**
Expand Down
7 changes: 6 additions & 1 deletion lib/checks/aria/valid-scrollable-semantics-evaluate.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,21 @@ const VALID_TAG_NAMES_FOR_SCROLLABLE_REGIONS = {
* appropriate for scrollable elements found in the focus order.
*/
const VALID_ROLES_FOR_SCROLLABLE_REGIONS = {
alert: true,
alertdialog: true,
application: true,
article: true,
banner: false,
complementary: true,
contentinfo: true,
dialog: true,
form: true,
log: true,
main: true,
navigation: true,
region: true,
search: false
search: false,
status: true
};

/**
Expand Down
15 changes: 6 additions & 9 deletions lib/checks/label/label-content-name-mismatch-evaluate.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,7 @@ function labelContentNameMismatchEvaluate(node, options, virtualNode) {
const pixelThreshold = options?.pixelThreshold;
const occurrenceThreshold =
options?.occurrenceThreshold ?? options?.occuranceThreshold;

const accText = accessibleText(node).toLowerCase();
if (isHumanInterpretable(accText) < 1) {
return undefined;
}

const visibleText = sanitize(
subtreeText(virtualNode, {
subtreeDescendant: true,
Expand All @@ -55,13 +50,15 @@ function labelContentNameMismatchEvaluate(node, options, virtualNode) {
occurrenceThreshold
})
).toLowerCase();

if (!visibleText) {
return true;
}
if (isHumanInterpretable(visibleText) < 1) {
if (isStringContained(visibleText, accText)) {
return true;
}

if (
isHumanInterpretable(accText) < 1 ||
isHumanInterpretable(visibleText) < 1
) {
return undefined;
}

Expand Down
23 changes: 21 additions & 2 deletions lib/checks/mobile/target-offset-evaluate.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,27 @@ export default function targetOffsetEvaluate(node, options, vNode) {
continue;
}
// the offset code works off radius but we want our messaging to reflect diameter
const offset =
roundToSingleDecimal(getOffset(vNode, vNeighbor, minOffset / 2)) * 2;
let offset = null;
try {
offset = getOffset(vNode, vNeighbor, minOffset / 2);
} catch (err) {
if (err.message.startsWith('splitRects')) {
this.data({
messageKey: 'tooManyRects',
closestOffset: 0,
minOffset
});
return undefined;
}

throw err;
}

if (offset === null) {
continue;
}

offset = roundToSingleDecimal(offset) * 2;
if (offset + roundingMargin >= minOffset) {
continue;
}
Expand Down
3 changes: 2 additions & 1 deletion lib/checks/mobile/target-offset.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@
"fail": "Target has insufficient space to its closest neighbors. Safe clickable space has a diameter of ${data.closestOffset}px instead of at least ${data.minOffset}px.",
"incomplete": {
"default": "Element with negative tabindex has insufficient space to its closest neighbors. Safe clickable space has a diameter of ${data.closestOffset}px instead of at least ${data.minOffset}px. Is this a target?",
"nonTabbableNeighbor": "Target has insufficient space to its closest neighbors. Safe clickable space has a diameter of ${data.closestOffset}px instead of at least ${data.minOffset}px. Is the neighbor a target?"
"nonTabbableNeighbor": "Target has insufficient space to its closest neighbors. Safe clickable space has a diameter of ${data.closestOffset}px instead of at least ${data.minOffset}px. Is the neighbor a target?",
"tooManyRects": "Could not get the target size because there are too many overlapping elements"
}
}
}
Expand Down
11 changes: 6 additions & 5 deletions lib/checks/mobile/target-size-evaluate.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
rectHasMinimumSize,
hasVisualOverlap
} from '../../commons/math';
import { contains } from '../../core/utils';

/**
* Determine if an element has a minimum size, taking into account
Expand Down Expand Up @@ -131,8 +132,10 @@ function getLargestUnobscuredArea(vNode, obscuredNodes) {
const obscuringRects = obscuredNodes.map(
({ boundingClientRect: rect }) => rect
);
const unobscuredRects = splitRects(nodeRect, obscuringRects);
if (unobscuredRects.length === 0) {
let unobscuredRects;
try {
unobscuredRects = splitRects(nodeRect, obscuringRects);
} catch (err) {
return null;
}

Expand Down Expand Up @@ -185,9 +188,7 @@ function toDecimalSize(rect) {
}

function isDescendantNotInTabOrder(vAncestor, vNode) {
return (
vAncestor.actualNode.contains(vNode.actualNode) && !isInTabOrder(vNode)
);
return contains(vAncestor, vNode) && !isInTabOrder(vNode);
}

function mapActualNodes(vNodes) {
Expand Down
Loading