From a56190c845cc7619a38a28685c48d8ac38108ebd Mon Sep 17 00:00:00 2001 From: Steven Lambert <2433219+straker@users.noreply.github.com> Date: Fri, 19 Jun 2020 11:10:31 -0600 Subject: [PATCH] fix(color-contrast): properly handle truncated text (#2302) * fix(color-contrast): properly handle truncated text * remove comment --- lib/commons/dom/get-text-element-stack.js | 12 ++++++++++++ test/checks/color/color-contrast.js | 8 ++++++++ test/commons/dom/get-element-stack.js | 14 ++++++++++++++ 3 files changed, 34 insertions(+) diff --git a/lib/commons/dom/get-text-element-stack.js b/lib/commons/dom/get-text-element-stack.js index f3547f7831..50b4435b4d 100644 --- a/lib/commons/dom/get-text-element-stack.js +++ b/lib/commons/dom/get-text-element-stack.js @@ -1,3 +1,4 @@ +import getElementStack from './get-element-stack'; import { createGrid, getRectStack } from './get-rect-stack'; import sanitize from '../text/sanitize'; @@ -23,6 +24,17 @@ function getTextElementStack(node) { return []; } + // if the element is using text truncation we need to get the rect of + // the element rather than look at the text node rects as they will return + // the full width of the text node before truncation (which can go off the + // screen) + // @see https://github.com/dequelabs/axe-core/issues/2178 + const whiteSpace = vNode.getComputedStylePropertyValue('white-space'); + const overflow = vNode.getComputedStylePropertyValue('overflow'); + if (whiteSpace === 'nowrap' && overflow === 'hidden') { + return [getElementStack(node)]; + } + // for code blocks that use syntax highlighting, you can get a ton of client // rects (See https://github.com/dequelabs/axe-core/issues/1985). they use // a mixture of text nodes and other nodes (which will contain their own text diff --git a/test/checks/color/color-contrast.js b/test/checks/color/color-contrast.js index facf17fb94..9afe1f2467 100644 --- a/test/checks/color/color-contrast.js +++ b/test/checks/color/color-contrast.js @@ -148,6 +148,14 @@ describe('color-contrast', function() { assert.deepEqual(checkContext._relatedNodes, []); }); + it('should return true for truncated inline elements', function() { + var params = checkSetup( + '

Text oh heyyyy Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed et sollicitudin quam. Fusce mi odio, egestas pulvinar erat eget, vehicula tempus est. Proin vitae ullamcorper velit. Donec sagittis est justo, mattis iaculis arcu facilisis id. Proin pulvinar ornare arcu a fermentum. Quisque et dignissim nulla, sit amet consectetur ipsum. Donec in libero porttitor, dapibus neque imperdiet, aliquam est. Vivamus blandit volutpat fringilla. In mi magna, mollis sit amet imperdiet eu, rutrum ut tellus. Mauris vel condimentum nibh, quis ultricies nisi. Vivamus accumsan quam mauris, id iaculis quam fringilla ac. Curabitur pulvinar dolor ac magna vehicula, non auctor ligula dignissim. Nam ac nibh porttitor, malesuada tortor varius, feugiat turpis. Mauris dapibus, tellus ut viverra porta, ipsum turpis bibendum ligula, at tempor felis ante non libero. Donec dapibus, diam sit amet posuere commodo, magna orci hendrerit ipsum, eu egestas mauris nulla ut ipsum. Sed luctus, orci in fringilla finibus, odio leo porta dolor, eu dignissim risus eros eget erat

' + ); + assert.isTrue(contrastEvaluate.apply(checkContext, params)); + assert.deepEqual(checkContext._relatedNodes, []); + }); + it('should return true for inline elements with sufficient contrast', function() { var params = checkSetup( '

Text oh heyyyy and here\'s bold text

' diff --git a/test/commons/dom/get-element-stack.js b/test/commons/dom/get-element-stack.js index 74d1d8ebdf..52b129302f 100644 --- a/test/commons/dom/get-element-stack.js +++ b/test/commons/dom/get-element-stack.js @@ -562,5 +562,19 @@ describe('dom.getElementStack', function() { var stacks = getTextElementStack(target).map(mapToIDs); assert.deepEqual(stacks, [['target', '1', 'fixture']]); }); + + it('should handle truncated text', function() { + fixture.innerHTML = + '
' + + '
' + + 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed et sollicitudin quam. Fusce mi odio, egestas pulvinar erat eget, vehicula tempus est. Proin vitae ullamcorper velit. Donec sagittis est justo, mattis iaculis arcu facilisis id. Proin pulvinar ornare arcu a fermentum. Quisque et dignissim nulla, sit amet consectetur ipsum. Donec in libero porttitor, dapibus neque imperdiet, aliquam est. Vivamus blandit volutpat fringilla. In mi magna, mollis sit amet imperdiet eu, rutrum ut tellus. Mauris vel condimentum nibh, quis ultricies nisi. Vivamus accumsan quam mauris, id iaculis quam fringilla ac. Curabitur pulvinar dolor ac magna vehicula, non auctor ligula dignissim. Nam ac nibh porttitor, malesuada tortor varius, feugiat turpis. Mauris dapibus, tellus ut viverra porta, ipsum turpis bibendum ligula, at tempor felis ante non libero. Donec dapibus, diam sit amet posuere commodo, magna orci hendrerit ipsum, eu egestas mauris nulla ut ipsum. Sed luctus, orci in fringilla finibus, odio leo porta dolor, eu dignissim risus eros eget erat.' + + 'World' + + '
' + + '
'; + axe.testUtils.flatTreeSetup(fixture); + var target = fixture.querySelector('#target'); + var stacks = getTextElementStack(target).map(mapToIDs); + assert.deepEqual(stacks, [['target', '1', 'fixture']]); + }); }); });