1- import { getNodeFromTree , memoize } from '../../core/utils' ;
1+ import { getNodeFromTree } from '../../core/utils' ;
22import { sanitize } from '../text' ;
33import { getIntersectionRect , getRectCenter , isPointInRect } from '../math' ;
44import getOverflowHiddenAncestors from './get-overflow-hidden-ancestors' ;
@@ -11,53 +11,70 @@ import cache from '../../core/base/cache';
1111 * @instance
1212 * @param {Element } node
1313 */
14- const getVisibleChildTextRects = memoize (
15- function getVisibleChildTextRectsMemoized ( node ) {
16- const vNode = getNodeFromTree ( node ) ;
17- const nodeRect = vNode . boundingClientRect ;
18- const clientRects = [ ] ;
19- const overflowHiddenNodes = getOverflowHiddenAncestors ( vNode ) ;
14+ const getVisibleChildTextRects = ( node , options = { } ) => {
15+ const {
16+ checkTextRectOutsideNodeBoundingRect = false ,
17+ includeOutsideBounds = true ,
18+ includeOverflowHidden = false ,
19+ checkNoVisibleRectsIdentified = false
20+ } = options ;
21+ const vNode = getNodeFromTree ( node ) ;
22+ const nodeRect = vNode . boundingClientRect ;
23+ const clientRects = [ ] ;
24+ const overflowHiddenNodes = getOverflowHiddenAncestors ( vNode ) ;
2025
21- node . childNodes . forEach ( textNode => {
22- if ( textNode . nodeType !== 3 || sanitize ( textNode . nodeValue ) === '' ) {
23- return ;
24- }
25-
26- const contentRects = getContentRects ( textNode ) ;
27- if ( isOutsideNodeBounds ( contentRects , nodeRect ) && ! cache . get ( 'ruleId' ) ) {
28- return ;
29- }
30-
31- clientRects . push ( ...filterHiddenRects ( contentRects , overflowHiddenNodes ) ) ;
32- } ) ;
26+ node . childNodes . forEach ( textNode => {
27+ if ( textNode . nodeType !== 3 || sanitize ( textNode . nodeValue ) === '' ) {
28+ return ;
29+ }
3330
34- // a11y-engine-domforge change
31+ const contentRects = getContentRects ( textNode ) ;
3532 if (
36- clientRects . length <= 0 &&
37- cache . get ( 'ruleId' ) &&
38- cache . get ( 'ruleId' ) === 'resize-2x-zoom'
33+ includeOutsideBounds &&
34+ isOutsideNodeBounds (
35+ contentRects ,
36+ nodeRect ,
37+ checkTextRectOutsideNodeBoundingRect
38+ ) &&
39+ ( ! cache . get ( 'ruleId' ) || cache . get ( 'ruleId' ) === 'reflow-4x-zoom-scroll' )
3940 ) {
40- return [ ] ;
41+ return ;
4142 }
42- /**
43- * if all text rects are larger than the bounds of the node,
44- * or goes outside of the bounds of the node, we need to use
45- * the nodes bounding rect so we stay within the bounds of the
46- * element.
47- *
48- * @see https://github.com/dequelabs/axe-core/issues/2178
49- * @see https://github.com/dequelabs/axe-core/issues/2483
50- * @see https://github.com/dequelabs/axe-core/issues/2681
51- *
52- * also need to resize the nodeRect to fit within the bounds of any overflow: hidden ancestors.
53- *
54- * @see https://github.com/dequelabs/axe-core/issues/4253
55- */
56- return clientRects . length
57- ? clientRects
58- : filterHiddenRects ( [ nodeRect ] , overflowHiddenNodes ) ;
43+
44+ clientRects . push (
45+ ...filterHiddenRects (
46+ contentRects ,
47+ includeOverflowHidden ? [ ] : overflowHiddenNodes
48+ )
49+ ) ;
50+ } ) ;
51+
52+ // a11y-engine-domforge change
53+ if (
54+ clientRects . length <= 0 &&
55+ ( ( cache . get ( 'ruleId' ) && cache . get ( 'ruleId' ) === 'resize-2x-zoom' ) ||
56+ checkNoVisibleRectsIdentified )
57+ ) {
58+ return [ ] ;
5959 }
60- ) ;
60+ /**
61+ * if all text rects are larger than the bounds of the node,
62+ * or goes outside of the bounds of the node, we need to use
63+ * the nodes bounding rect so we stay within the bounds of the
64+ * element.
65+ *
66+ * @see https://github.com/dequelabs/axe-core/issues/2178
67+ * @see https://github.com/dequelabs/axe-core/issues/2483
68+ * @see https://github.com/dequelabs/axe-core/issues/2681
69+ *
70+ * also need to resize the nodeRect to fit within the bounds of any overflow: hidden ancestors.
71+ *
72+ * @see https://github.com/dequelabs/axe-core/issues/4253
73+ */
74+ return clientRects . length
75+ ? clientRects
76+ : filterHiddenRects ( [ nodeRect ] , overflowHiddenNodes ) ;
77+ } ;
6178export default getVisibleChildTextRects ;
6279
6380function getContentRects ( node ) {
@@ -72,10 +89,20 @@ function getContentRects(node) {
7289 * when determining the rect stack we will also use the midpoint
7390 * of the text rect to determine out of bounds
7491 */
75- function isOutsideNodeBounds ( rects , nodeRect ) {
92+ function isOutsideNodeBounds (
93+ rects ,
94+ nodeRect ,
95+ checkTextRectOutsideNodeBoundingRect = false
96+ ) {
7697 return rects . some ( rect => {
7798 const centerPoint = getRectCenter ( rect ) ;
78- return ! isPointInRect ( centerPoint , nodeRect ) ;
99+ if ( checkTextRectOutsideNodeBoundingRect ) {
100+ return (
101+ ! isPointInRect ( centerPoint , nodeRect ) || rect . right > nodeRect . right
102+ ) ;
103+ } else {
104+ return ! isPointInRect ( centerPoint , nodeRect ) ;
105+ }
79106 } ) ;
80107}
81108
0 commit comments