From 4c3a00c7bd6de68b2795be37113a59d804d0a313 Mon Sep 17 00:00:00 2001 From: Steven Lambert <2433219+straker@users.noreply.github.com> Date: Fri, 6 Jan 2023 08:56:50 -0700 Subject: [PATCH] fix(color-contrast): correctly compute color contrast of elements (#3847) * fix(color-contrast): correctly compute color contrast of elements * Update lib/commons/dom/create-grid.js Co-authored-by: Wilco Fiers Co-authored-by: Wilco Fiers --- lib/commons/dom/create-grid.js | 9 ++++++++- test/checks/color/color-contrast.js | 23 +++++++++++++++++++++++ test/commons/dom/get-element-stack.js | 20 ++++++++++++++++++++ 3 files changed, 51 insertions(+), 1 deletion(-) diff --git a/lib/commons/dom/create-grid.js b/lib/commons/dom/create-grid.js index f4c0278502..509fbba5f9 100644 --- a/lib/commons/dom/create-grid.js +++ b/lib/commons/dom/create-grid.js @@ -54,10 +54,17 @@ export default function createGrid( while (node) { let vNode = getNodeFromTree(node); + if (vNode && vNode.parent) { + parentVNode = vNode.parent; + } + // elements with an assigned slot need to be a child of the slot element + else if (node.assignedSlot) { + parentVNode = getNodeFromTree(node.assignedSlot); + } // an svg in IE11 does not have a parentElement but instead has a // parentNode. but parentNode could be a shadow root so we need to // verify it's in the tree first - if (node.parentElement) { + else if (node.parentElement) { parentVNode = getNodeFromTree(node.parentElement); } else if (node.parentNode && getNodeFromTree(node.parentNode)) { parentVNode = getNodeFromTree(node.parentNode); diff --git a/test/checks/color/color-contrast.js b/test/checks/color/color-contrast.js index d5ae1deea3..d6f5fcb627 100644 --- a/test/checks/color/color-contrast.js +++ b/test/checks/color/color-contrast.js @@ -906,6 +906,29 @@ describe('color-contrast', function () { } ); + (shadowSupported ? it : xit)('handles elements', () => { + fixture.innerHTML = + '

Slotted text

'; + const container = fixture.querySelector('#container'); + const shadow = container.attachShadow({ mode: 'open' }); + + shadow.innerHTML = + '
'; + const shadowContainer = shadow.querySelector('#shadowContainer'); + axe.testUtils.flatTreeSetup(fixture); + + const target = fixture.querySelector('#target'); + const vNode = axe.utils.getNodeFromTree(target); + const result = contrastEvaluate.call( + checkContext, + vNode.actualNode, + null, + vNode + ); + assert.isFalse(result); + assert.deepEqual(checkContext._relatedNodes, [shadowContainer]); + }); + describe('with text-shadow', function () { it('passes if thin text shadows have sufficient contrast with the text', function () { var params = checkSetup( diff --git a/test/commons/dom/get-element-stack.js b/test/commons/dom/get-element-stack.js index 4a2d3f1baa..fb33e7f2da 100644 --- a/test/commons/dom/get-element-stack.js +++ b/test/commons/dom/get-element-stack.js @@ -570,6 +570,26 @@ describe('dom.getElementStack', function () { ]); } ); + + (shadowSupported ? it : xit)('should sort elements', () => { + fixture.innerHTML = + '

Slotted text

'; + const container = fixture.querySelector('#container'); + const shadow = container.attachShadow({ mode: 'open' }); + + shadow.innerHTML = + '
'; + axe.testUtils.flatTreeSetup(fixture); + + const target = fixture.querySelector('#target'); + const stack = mapToIDs(getElementStack(target)); + assert.deepEqual(stack, [ + 'target', + 'shadowContainer', + 'container', + 'fixture' + ]); + }); }); describe('scroll regions', function () {