File tree Expand file tree Collapse file tree 3 files changed +55
-6
lines changed Expand file tree Collapse file tree 3 files changed +55
-6
lines changed Original file line number Diff line number Diff line change
1
+ ---
2
+ " dom-accessibility-api " : patch
3
+ ---
4
+
5
+ Fix a case of maximum call stack size exceeded when a node referenced itself in ` aria-labelledby ` .
Original file line number Diff line number Diff line change @@ -407,6 +407,39 @@ test.each([
407
407
"a logo" ,
408
408
] ,
409
409
[ ` <input type="radio" data-test title="crazy"/>` , "crazy" ] ,
410
+ [
411
+ `
412
+ <h2 id="lorem-heading">
413
+ Lorem ipsum
414
+ <a data-test aria-labelledby="lorem-heading" href="#lorem-heading" tabindex="-1">
415
+ <svg></svg>
416
+ </a>
417
+ </h2>
418
+ ` ,
419
+ "Lorem ipsum" ,
420
+ ] ,
421
+ [
422
+ `
423
+ <label for="toggle-button" id="label" value="full">
424
+ <button
425
+ data-test
426
+ aria-expanded="false"
427
+ aria-haspopup="listbox"
428
+ aria-labelledby="label toggle-button"
429
+ id="toggle-button"
430
+ type="button"
431
+ >
432
+ <span>
433
+ Full Refund
434
+ </span>
435
+ </button>
436
+ <div>
437
+ Refund Type
438
+ </div>
439
+ </label>
440
+ ` ,
441
+ "Full Refund Refund Type" ,
442
+ ] ,
410
443
] ) ( `misc #%#` , ( markup , expectedAccessibleName ) => {
411
444
expect ( markup ) . toRenderIntoDocumentAccessibleName ( expectedAccessibleName ) ;
412
445
} ) ;
Original file line number Diff line number Diff line change @@ -575,23 +575,34 @@ export function computeTextAlternative(
575
575
}
576
576
577
577
// 2B
578
- const labelElements = queryIdRefs ( current , "aria-labelledby" ) ;
578
+ const labelAttributeNode = isElement ( current )
579
+ ? current . getAttributeNode ( "aria-labelledby" )
580
+ : null ;
581
+ // TODO: Do we generally need to block query IdRefs of attributes we have already consulted?
582
+ const labelElements =
583
+ labelAttributeNode !== null && ! consultedNodes . has ( labelAttributeNode )
584
+ ? queryIdRefs ( current , "aria-labelledby" )
585
+ : [ ] ;
579
586
if (
580
587
compute === "name" &&
581
588
! context . isReferenced &&
582
589
labelElements . length > 0
583
590
) {
591
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- Can't be null here otherwise labelElements would be empty
592
+ consultedNodes . add ( labelAttributeNode ! ) ;
593
+
584
594
return labelElements
585
- . map ( ( element ) =>
586
- computeTextAlternative ( element , {
595
+ . map ( ( element ) => {
596
+ // TODO: Chrome will consider repeated values i.e. use a node multiple times while we'll bail out in computeTextAlternative.
597
+ return computeTextAlternative ( element , {
587
598
isEmbeddedInLabel : context . isEmbeddedInLabel ,
588
599
isReferenced : true ,
589
- // thais isn't recursion as specified, otherwise we would skip
600
+ // this isn't recursion as specified, otherwise we would skip
590
601
// `aria-label` in
591
602
// <input id="myself" aria-label="foo" aria-labelledby="myself"
592
603
recursion : false ,
593
- } )
594
- )
604
+ } ) ;
605
+ } )
595
606
. join ( " " ) ;
596
607
}
597
608
You can’t perform that action at this time.
0 commit comments