From 3f6ef8dad6f6169599fb30164741cfe3607a3166 Mon Sep 17 00:00:00 2001 From: Utkarsh Chaudhary Date: Thu, 26 Dec 2024 17:20:40 +0530 Subject: [PATCH 1/5] Added changes in get-visible-child-text-child --- .../dom/get-visible-child-text-rects.js | 43 ++++++++++++++++--- 1 file changed, 36 insertions(+), 7 deletions(-) diff --git a/lib/commons/dom/get-visible-child-text-rects.js b/lib/commons/dom/get-visible-child-text-rects.js index 2cd01773..2d42e676 100644 --- a/lib/commons/dom/get-visible-child-text-rects.js +++ b/lib/commons/dom/get-visible-child-text-rects.js @@ -12,7 +12,12 @@ import cache from '../../core/base/cache'; * @param {Element} node */ const getVisibleChildTextRects = memoize( - function getVisibleChildTextRectsMemoized(node) { + function getVisibleChildTextRectsMemoized( + node, + checkTextRectOutsideNodeBoundingRect = false, + checkIsOutsideNodeBounds = true, + includeOverflowHiddenRect = false + ) { const vNode = getNodeFromTree(node); const nodeRect = vNode.boundingClientRect; const clientRects = []; @@ -24,18 +29,34 @@ const getVisibleChildTextRects = memoize( } const contentRects = getContentRects(textNode); - if (isOutsideNodeBounds(contentRects, nodeRect) && !cache.get('ruleId')) { - return; + if (checkIsOutsideNodeBounds) { + if ( + isOutsideNodeBounds( + contentRects, + nodeRect, + checkTextRectOutsideNodeBoundingRect + ) && + !cache.get('ruleId') + ) { + return; + } } - clientRects.push(...filterHiddenRects(contentRects, overflowHiddenNodes)); + if (includeOverflowHiddenRect) { + clientRects.push( + ...filterHiddenRects(contentRects, overflowHiddenNodes) + ); + } else { + clientRects.push(...filterHiddenRects(contentRects, [])); + } }); // a11y-engine-domforge change if ( clientRects.length <= 0 && cache.get('ruleId') && - cache.get('ruleId') === 'resize-2x-zoom' + cache.get('ruleId') === 'resize-2x-zoom' && + checkIsOutsideNodeBounds ) { return []; } @@ -72,10 +93,18 @@ function getContentRects(node) { * when determining the rect stack we will also use the midpoint * of the text rect to determine out of bounds */ -function isOutsideNodeBounds(rects, nodeRect) { +function isOutsideNodeBounds( + rects, + nodeRect, + checkTextRectOutsideNodeBoundingRect = false +) { return rects.some(rect => { const centerPoint = getRectCenter(rect); - return !isPointInRect(centerPoint, nodeRect); + if (checkTextRectOutsideNodeBoundingRect) { + !isPointInRect(centerPoint, nodeRect) || rect.right > nodeRect.right; + } else { + return !isPointInRect(centerPoint, nodeRect); + } }); } From df562e00fea770c68d13f4ef29555f51f4d27a67 Mon Sep 17 00:00:00 2001 From: Utkarsh Chaudhary Date: Thu, 26 Dec 2024 18:12:26 +0530 Subject: [PATCH 2/5] Added changes in get-visible-child-text-child --- lib/commons/dom/get-visible-child-text-rects.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/commons/dom/get-visible-child-text-rects.js b/lib/commons/dom/get-visible-child-text-rects.js index 2d42e676..15c30952 100644 --- a/lib/commons/dom/get-visible-child-text-rects.js +++ b/lib/commons/dom/get-visible-child-text-rects.js @@ -43,11 +43,11 @@ const getVisibleChildTextRects = memoize( } if (includeOverflowHiddenRect) { + clientRects.push(...filterHiddenRects(contentRects, [])); + } else { clientRects.push( ...filterHiddenRects(contentRects, overflowHiddenNodes) ); - } else { - clientRects.push(...filterHiddenRects(contentRects, [])); } }); From 24e0c6e4c44054c8e762d8ba594711e8981cd70d Mon Sep 17 00:00:00 2001 From: Utkarsh Chaudhary Date: Fri, 10 Jan 2025 13:50:54 +0530 Subject: [PATCH 3/5] Added logic for reflow in get-overflow-ancestors --- .../dom/get-overflow-hidden-ancestors.js | 12 +- .../dom/get-visible-child-text-rects.js | 124 +++++++++--------- 2 files changed, 69 insertions(+), 67 deletions(-) diff --git a/lib/commons/dom/get-overflow-hidden-ancestors.js b/lib/commons/dom/get-overflow-hidden-ancestors.js index 8ace4290..15178170 100644 --- a/lib/commons/dom/get-overflow-hidden-ancestors.js +++ b/lib/commons/dom/get-overflow-hidden-ancestors.js @@ -27,10 +27,14 @@ const getOverflowHiddenAncestors = memoize( ) { ancestors.push(vNode); } - } else { - if (overflow === 'hidden' || overflow.includes('clip')) { - ancestors.push(vNode); - } + } else if ( + cache.get('ruleId') && + cache.get('ruleId') === 'reflow' && + overflow.includes('hidden') + ) { + ancestors.push(vNode); + } else if (overflow === 'hidden' || overflow.includes('clip')) { + ancestors.push(vNode); } return ancestors.concat(getOverflowHiddenAncestors(vNode.parent)); diff --git a/lib/commons/dom/get-visible-child-text-rects.js b/lib/commons/dom/get-visible-child-text-rects.js index 15c30952..bb39e8de 100644 --- a/lib/commons/dom/get-visible-child-text-rects.js +++ b/lib/commons/dom/get-visible-child-text-rects.js @@ -1,4 +1,4 @@ -import { getNodeFromTree, memoize } from '../../core/utils'; +import { getNodeFromTree } from '../../core/utils'; import { sanitize } from '../text'; import { getIntersectionRect, getRectCenter, isPointInRect } from '../math'; import getOverflowHiddenAncestors from './get-overflow-hidden-ancestors'; @@ -11,74 +11,70 @@ import cache from '../../core/base/cache'; * @instance * @param {Element} node */ -const getVisibleChildTextRects = memoize( - function getVisibleChildTextRectsMemoized( - node, +const getVisibleChildTextRects = (node, options = {}) => { + const { checkTextRectOutsideNodeBoundingRect = false, - checkIsOutsideNodeBounds = true, - includeOverflowHiddenRect = false - ) { - const vNode = getNodeFromTree(node); - const nodeRect = vNode.boundingClientRect; - const clientRects = []; - const overflowHiddenNodes = getOverflowHiddenAncestors(vNode); - - node.childNodes.forEach(textNode => { - if (textNode.nodeType !== 3 || sanitize(textNode.nodeValue) === '') { - return; - } - - const contentRects = getContentRects(textNode); - if (checkIsOutsideNodeBounds) { - if ( - isOutsideNodeBounds( - contentRects, - nodeRect, - checkTextRectOutsideNodeBoundingRect - ) && - !cache.get('ruleId') - ) { - return; - } - } + includeOutsideBounds = true, + includeOverflowHidden = false, + checkNoVisibleRectsIdentified = false + } = options; + const vNode = getNodeFromTree(node); + const nodeRect = vNode.boundingClientRect; + const clientRects = []; + const overflowHiddenNodes = getOverflowHiddenAncestors(vNode); - if (includeOverflowHiddenRect) { - clientRects.push(...filterHiddenRects(contentRects, [])); - } else { - clientRects.push( - ...filterHiddenRects(contentRects, overflowHiddenNodes) - ); - } - }); + node.childNodes.forEach(textNode => { + if (textNode.nodeType !== 3 || sanitize(textNode.nodeValue) === '') { + return; + } - // a11y-engine-domforge change + const contentRects = getContentRects(textNode); if ( - clientRects.length <= 0 && - cache.get('ruleId') && - cache.get('ruleId') === 'resize-2x-zoom' && - checkIsOutsideNodeBounds + includeOutsideBounds && + isOutsideNodeBounds( + contentRects, + nodeRect, + checkTextRectOutsideNodeBoundingRect + ) && + !cache.get('ruleId') ) { - return []; + return; } - /** - * if all text rects are larger than the bounds of the node, - * or goes outside of the bounds of the node, we need to use - * the nodes bounding rect so we stay within the bounds of the - * element. - * - * @see https://github.com/dequelabs/axe-core/issues/2178 - * @see https://github.com/dequelabs/axe-core/issues/2483 - * @see https://github.com/dequelabs/axe-core/issues/2681 - * - * also need to resize the nodeRect to fit within the bounds of any overflow: hidden ancestors. - * - * @see https://github.com/dequelabs/axe-core/issues/4253 - */ - return clientRects.length - ? clientRects - : filterHiddenRects([nodeRect], overflowHiddenNodes); + + clientRects.push( + ...filterHiddenRects( + contentRects, + includeOverflowHidden ? [] : overflowHiddenNodes + ) + ); + }); + + // a11y-engine-domforge change + if ( + clientRects.length <= 0 && + ((cache.get('ruleId') && cache.get('ruleId') === 'resize-2x-zoom') || + checkNoVisibleRectsIdentified) + ) { + return []; } -); + /** + * if all text rects are larger than the bounds of the node, + * or goes outside of the bounds of the node, we need to use + * the nodes bounding rect so we stay within the bounds of the + * element. + * + * @see https://github.com/dequelabs/axe-core/issues/2178 + * @see https://github.com/dequelabs/axe-core/issues/2483 + * @see https://github.com/dequelabs/axe-core/issues/2681 + * + * also need to resize the nodeRect to fit within the bounds of any overflow: hidden ancestors. + * + * @see https://github.com/dequelabs/axe-core/issues/4253 + */ + return clientRects.length + ? clientRects + : filterHiddenRects([nodeRect], overflowHiddenNodes); +}; export default getVisibleChildTextRects; function getContentRects(node) { @@ -101,7 +97,9 @@ function isOutsideNodeBounds( return rects.some(rect => { const centerPoint = getRectCenter(rect); if (checkTextRectOutsideNodeBoundingRect) { - !isPointInRect(centerPoint, nodeRect) || rect.right > nodeRect.right; + return ( + !isPointInRect(centerPoint, nodeRect) || rect.right > nodeRect.right + ); } else { return !isPointInRect(centerPoint, nodeRect); } From e16093396ea73ba2a1263904845f1316b10e6560 Mon Sep 17 00:00:00 2001 From: Utkarsh Chaudhary Date: Fri, 10 Jan 2025 17:51:36 +0530 Subject: [PATCH 4/5] Added logic for reflow in get-overflow-ancestors --- lib/commons/dom/get-visible-child-text-rects.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/commons/dom/get-visible-child-text-rects.js b/lib/commons/dom/get-visible-child-text-rects.js index bb39e8de..fad26ec3 100644 --- a/lib/commons/dom/get-visible-child-text-rects.js +++ b/lib/commons/dom/get-visible-child-text-rects.js @@ -36,7 +36,7 @@ const getVisibleChildTextRects = (node, options = {}) => { nodeRect, checkTextRectOutsideNodeBoundingRect ) && - !cache.get('ruleId') + (!cache.get('ruleId') || cache.get('ruleId') === 'reflow') ) { return; } From 92534cef7a583ab3d4c56330d0fdbeff742b06ae Mon Sep 17 00:00:00 2001 From: Utkarsh Chaudhary Date: Wed, 15 Jan 2025 17:10:04 +0530 Subject: [PATCH 5/5] Added logic for reflow in get-overflow-ancestors --- lib/commons/dom/get-overflow-hidden-ancestors.js | 2 +- lib/commons/dom/get-visible-child-text-rects.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/commons/dom/get-overflow-hidden-ancestors.js b/lib/commons/dom/get-overflow-hidden-ancestors.js index 15178170..b68432d3 100644 --- a/lib/commons/dom/get-overflow-hidden-ancestors.js +++ b/lib/commons/dom/get-overflow-hidden-ancestors.js @@ -29,7 +29,7 @@ const getOverflowHiddenAncestors = memoize( } } else if ( cache.get('ruleId') && - cache.get('ruleId') === 'reflow' && + cache.get('ruleId') === 'reflow-4x-zoom-scroll' && overflow.includes('hidden') ) { ancestors.push(vNode); diff --git a/lib/commons/dom/get-visible-child-text-rects.js b/lib/commons/dom/get-visible-child-text-rects.js index fad26ec3..7a949442 100644 --- a/lib/commons/dom/get-visible-child-text-rects.js +++ b/lib/commons/dom/get-visible-child-text-rects.js @@ -36,7 +36,7 @@ const getVisibleChildTextRects = (node, options = {}) => { nodeRect, checkTextRectOutsideNodeBoundingRect ) && - (!cache.get('ruleId') || cache.get('ruleId') === 'reflow') + (!cache.get('ruleId') || cache.get('ruleId') === 'reflow-4x-zoom-scroll') ) { return; }