@@ -10,6 +10,7 @@ import {
1010 imageRender ,
1111 imageToExternalHTML ,
1212} from '@blocknote/core' ;
13+ import { t } from 'i18next' ;
1314
1415type ImageBlockConfig = typeof imageBlockConfig ;
1516
@@ -25,10 +26,73 @@ export const accessibleImageRender = (
2526 const dom = imageRenderComputed . dom ;
2627 const imgSelector = dom . querySelector ( 'img' ) ;
2728
28- imgSelector ?. setAttribute ( 'alt' , '' ) ;
29- imgSelector ?. setAttribute ( 'role' , 'presentation' ) ;
30- imgSelector ?. setAttribute ( 'aria-hidden' , 'true' ) ;
31- imgSelector ?. setAttribute ( 'tabindex' , '-1' ) ;
29+ const withCaption =
30+ block . props . caption && dom . querySelector ( '.bn-file-caption' ) ;
31+
32+ const accessibleImageWithCaption = ( ) => {
33+ imgSelector ?. setAttribute ( 'alt' , block . props . caption ) ;
34+ imgSelector ?. removeAttribute ( 'aria-hidden' ) ;
35+ imgSelector ?. setAttribute ( 'tabindex' , '0' ) ;
36+
37+ // Fix RGAA 1.9.1: Convert to figure/figcaption structure if caption exists
38+ const captionElement = dom . querySelector ( '.bn-file-caption' ) ;
39+
40+ if ( captionElement ) {
41+ const figureElement = document . createElement ( 'figure' ) ;
42+
43+ // Copy all attributes from the original div
44+ figureElement . className = dom . className ;
45+ const styleAttr = dom . getAttribute ( 'style' ) ;
46+ if ( styleAttr ) {
47+ figureElement . setAttribute ( 'style' , styleAttr ) ;
48+ }
49+ figureElement . style . setProperty ( 'margin' , '0' ) ;
50+
51+ Array . from ( dom . children ) . forEach ( ( child ) => {
52+ figureElement . appendChild ( child . cloneNode ( true ) ) ;
53+ } ) ;
54+
55+ // Replace the <p> caption with <figcaption>
56+ const figcaptionElement = document . createElement ( 'figcaption' ) ;
57+ const originalCaption = figureElement . querySelector ( '.bn-file-caption' ) ;
58+ if ( originalCaption ) {
59+ figcaptionElement . className = originalCaption . className ;
60+ figcaptionElement . textContent = originalCaption . textContent ;
61+ originalCaption . parentNode ?. replaceChild (
62+ figcaptionElement ,
63+ originalCaption ,
64+ ) ;
65+
66+ // Add explicit role and aria-label for better screen reader support
67+ figureElement . setAttribute ( 'role' , 'img' ) ;
68+ figureElement . setAttribute (
69+ 'aria-label' ,
70+ t ( `Image: {{title}}` , { title : figcaptionElement . textContent } ) ,
71+ ) ;
72+ }
73+
74+ // Return the figure element as the new dom
75+ return {
76+ ...imageRenderComputed ,
77+ dom : figureElement ,
78+ } ;
79+ }
80+ } ;
81+
82+ const accessibleImage = ( ) => {
83+ imgSelector ?. setAttribute ( 'alt' , '' ) ;
84+ imgSelector ?. setAttribute ( 'role' , 'presentation' ) ;
85+ imgSelector ?. setAttribute ( 'aria-hidden' , 'true' ) ;
86+ imgSelector ?. setAttribute ( 'tabindex' , '-1' ) ;
87+ } ;
88+
89+ // Set accessibility attributes for the image
90+ const result = withCaption ? accessibleImageWithCaption ( ) : accessibleImage ( ) ;
91+
92+ // Return the result if accessibleImageWithCaption created a figure, otherwise return original
93+ if ( result ) {
94+ return result ;
95+ }
3296
3397 return {
3498 ...imageRenderComputed ,
0 commit comments