diff --git a/doc/rule-descriptions.md b/doc/rule-descriptions.md index 4889dabc1b..d089e96484 100644 --- a/doc/rule-descriptions.md +++ b/doc/rule-descriptions.md @@ -35,7 +35,7 @@ | [blink](https://dequeuniversity.com/rules/axe/4.4/blink?application=RuleDescription) | Ensures <blink> elements are not used | Serious | cat.time-and-media, wcag2a, wcag222, section508, section508.22.j | failure | | | [button-name](https://dequeuniversity.com/rules/axe/4.4/button-name?application=RuleDescription) | Ensures buttons have discernible text | Critical | cat.name-role-value, wcag2a, wcag412, section508, section508.22.a, ACT | failure, needs review | [97a4e1](https://act-rules.github.io/rules/97a4e1), [m6b1q3](https://act-rules.github.io/rules/m6b1q3) | | [bypass](https://dequeuniversity.com/rules/axe/4.4/bypass?application=RuleDescription) | Ensures each page has at least one mechanism for a user to bypass navigation and jump straight to the content | Serious | cat.keyboard, wcag2a, wcag241, section508, section508.22.o | needs review | [cf77f2](https://act-rules.github.io/rules/cf77f2), [047fe0](https://act-rules.github.io/rules/047fe0), [b40fd1](https://act-rules.github.io/rules/b40fd1), [3e12e1](https://act-rules.github.io/rules/3e12e1), [ye5d6e](https://act-rules.github.io/rules/ye5d6e) | -| [color-contrast](https://dequeuniversity.com/rules/axe/4.4/color-contrast?application=RuleDescription) | Ensures the contrast between foreground and background colors meets WCAG 2 AA contrast ratio thresholds | Serious | cat.color, wcag2aa, wcag143, ACT | failure, needs review | [afw4f7](https://act-rules.github.io/rules/afw4f7) | +| [color-contrast](https://dequeuniversity.com/rules/axe/4.4/color-contrast?application=RuleDescription) | Ensures the contrast between foreground and background colors meets WCAG 2 AA contrast ratio thresholds | Serious | cat.color, wcag2aa, wcag143, ACT | failure, needs review | [afw4f7](https://act-rules.github.io/rules/afw4f7), [09o5cg](https://act-rules.github.io/rules/09o5cg) | | [definition-list](https://dequeuniversity.com/rules/axe/4.4/definition-list?application=RuleDescription) | Ensures <dl> elements are structured correctly | Serious | cat.structure, wcag2a, wcag131 | failure | | | [dlitem](https://dequeuniversity.com/rules/axe/4.4/dlitem?application=RuleDescription) | Ensures <dt> and <dd> elements are contained by a <dl> | Serious | cat.structure, wcag2a, wcag131 | failure | | | [document-title](https://dequeuniversity.com/rules/axe/4.4/document-title?application=RuleDescription) | Ensures each HTML document contains a non-empty <title> element | Serious | cat.text-alternatives, wcag2a, wcag242, ACT | failure | [2779a5](https://act-rules.github.io/rules/2779a5) | diff --git a/lib/checks/color/color-contrast-enhanced.json b/lib/checks/color/color-contrast-enhanced.json index d2de46c476..8da5f2a8db 100644 --- a/lib/checks/color/color-contrast-enhanced.json +++ b/lib/checks/color/color-contrast-enhanced.json @@ -10,10 +10,12 @@ "largeTextPt": 18, "contrastRatio": { "normal": { - "expected": 7 + "expected": 7, + "minThreshold": 4.5 }, "large": { - "expected": 4.5 + "expected": 4.5, + "minThreshold": 3 } }, "pseudoSizeThreshold": 0.25, diff --git a/lib/checks/color/color-contrast-evaluate.js b/lib/checks/color/color-contrast-evaluate.js index 5895a6250e..dae20aae4b 100644 --- a/lib/checks/color/color-contrast-evaluate.js +++ b/lib/checks/color/color-contrast-evaluate.js @@ -102,8 +102,8 @@ export default function colorContrastEvaluate(node, options, virtualNode) { // ratio is outside range if ( - (typeof minThreshold === 'number' && contrast < minThreshold) || - (typeof maxThreshold === 'number' && contrast > maxThreshold) + (typeof minThreshold === 'number' && (typeof contrast !== 'number' || contrast < minThreshold)) || + (typeof maxThreshold === 'number' && (typeof contrast !== 'number' || contrast > maxThreshold)) ) { this.data({ contrastRatio: contrast }); return true; diff --git a/lib/commons/color/get-background-color.js b/lib/commons/color/get-background-color.js index 499511b770..0c8c00c7d2 100644 --- a/lib/commons/color/get-background-color.js +++ b/lib/commons/color/get-background-color.js @@ -7,6 +7,7 @@ import flattenColors from './flatten-colors'; import flattenShadowColors from './flatten-shadow-colors'; import getTextShadowColors from './get-text-shadow-colors'; import visuallyContains from '../dom/visually-contains'; +import { getNodeFromTree } from '../../core/utils'; /** * Returns background color for element @@ -25,6 +26,27 @@ export default function getBackgroundColor( bgElms = [], shadowOutlineEmMax = 0.1 ) { + const vNode = getNodeFromTree(elm); + const bgColorCache = vNode._cache.getBackgroundColor; + + if (bgColorCache) { + bgElms.push(...bgColorCache.bgElms); + incompleteData.set('bgColor', bgColorCache.incompleteData); + return bgColorCache.bgColor; + } + + const bgColor = _getBackgroundColor(elm, bgElms, shadowOutlineEmMax); + + vNode._cache.getBackgroundColor = { + bgColor, + bgElms, + incompleteData: incompleteData.get('bgColor') + }; + + return bgColor; +} + +function _getBackgroundColor(elm, bgElms, shadowOutlineEmMax) { let bgColors = getTextShadowColors(elm, { minRatio: shadowOutlineEmMax }); if (bgColors.length) { bgColors = [{ color: bgColors.reduce(flattenShadowColors) }]; diff --git a/lib/rules/color-contrast.json b/lib/rules/color-contrast.json index 59aa07ef64..ab0287ab3e 100644 --- a/lib/rules/color-contrast.json +++ b/lib/rules/color-contrast.json @@ -3,7 +3,7 @@ "matches": "color-contrast-matches", "excludeHidden": false, "tags": ["cat.color", "wcag2aa", "wcag143", "ACT"], - "actIds": ["afw4f7"], + "actIds": ["afw4f7", "09o5cg"], "metadata": { "description": "Ensures the contrast between foreground and background colors meets WCAG 2 AA contrast ratio thresholds", "help": "Elements must have sufficient color contrast" diff --git a/test/act-rules/text-contrast-enhanced-09o5cg.spec.js b/test/act-rules/text-contrast-enhanced-09o5cg.spec.js index 4dd28e1304..8a0657d9b0 100644 --- a/test/act-rules/text-contrast-enhanced-09o5cg.spec.js +++ b/test/act-rules/text-contrast-enhanced-09o5cg.spec.js @@ -1,5 +1,5 @@ require('./act-runner.js')({ id: '09o5cg', title: 'Text has enhanced contrast', - axeRules: ['color-contrast-enhanced'] + axeRules: ['color-contrast', 'color-contrast-enhanced'] }); diff --git a/test/checks/color/color-contrast.js b/test/checks/color/color-contrast.js index e1edfd4f7e..d5ae1deea3 100644 --- a/test/checks/color/color-contrast.js +++ b/test/checks/color/color-contrast.js @@ -723,6 +723,25 @@ describe('color-contrast', function () { assert.deepEqual(checkContext._relatedNodes, []); }); + it('should not report incomplete when options.contrastRatio.normal.minThreshold is set', function () { + var params = checkSetup( + ` +
+ Some text in English +
`, + { + contrastRatio: { + normal: { + minThreshold: 3 + } + } + } + ); + + assert.isTrue(contrastEvaluate.apply(checkContext, params)); + assert.isUndefined(checkContext._data.messageKey); + }); + it('should support options.contrastRatio.normal.maxThreshold', function () { var params = checkSetup( '+ Some text in English +
`, + { + contrastRatio: { + normal: { + maxThreshold: 2 + } + } + } + ); + + assert.isTrue(contrastEvaluate.apply(checkContext, params)); + assert.isUndefined(checkContext._data.messageKey); + }); + it('should support options.contrastRatio.large.expected', function () { var params = checkSetup( '+ Some text in English +
`, + { + contrastRatio: { + large: { + minThreshold: 2 + } + } + } + ); + + assert.isTrue(contrastEvaluate.apply(checkContext, params)); + assert.isUndefined(checkContext._data.messageKey); + }); + it('should support options.contrastRatio.large.maxThreshold', function () { var params = checkSetup( '+ Some text in English +
`, + { + contrastRatio: { + large: { + maxThreshold: 2 + } + } + } + ); + + assert.isTrue(contrastEvaluate.apply(checkContext, params)); + assert.isUndefined(checkContext._data.messageKey); + }); + it('should ignore pseudo element with options.ignorePseudo', function () { var params = checkSetup( '' +