@@ -285,9 +285,11 @@ export function EnrichedMathItemMixin<N, T, D, B extends Constructor<AbstractMat
285285 const node = this . typesetRoot ;
286286 if ( speech && options . enableSpeech ) {
287287 adaptor . setAttribute ( node , 'aria-label' , speech as string ) ;
288+ this . root . attributes . set ( 'aria-label' , speech ) ;
288289 }
289290 if ( braille && options . enableBraille ) {
290291 adaptor . setAttribute ( node , 'aria-braillelabel' , braille as string ) ;
292+ this . root . attributes . set ( 'aria-braillelabel' , braille ) ;
291293 }
292294 for ( const child of adaptor . childNodes ( node ) as N [ ] ) {
293295 adaptor . setAttribute ( child , 'aria-hidden' , 'true' ) ;
@@ -379,6 +381,7 @@ export function EnrichedMathDocumentMixin<N, T, D, B extends MathDocumentConstru
379381 attachSpeech : [ STATE . ATTACHSPEECH ]
380382 } ) ,
381383 speechTiming : {
384+ asynchronous : true , // true to allow screen updates while adding speech, false to not
382385 initial : 100 , // initial delay until starting to add speech
383386 threshold : 250 , // time (in milliseconds) to process speech before letting screen update
384387 intermediate : 10 // delay after processing speech reaches the threshold
@@ -440,25 +443,46 @@ export function EnrichedMathDocumentMixin<N, T, D, B extends MathDocumentConstru
440443 public attachSpeech ( ) {
441444 if ( ! this . processed . isSet ( 'attach-speech' ) ) {
442445 if ( this . options . enableSpeech || this . options . enableBraille ) {
443- if ( this . speechTimeout ) {
444- clearTimeout ( this . speechTimeout ) ;
445- this . speechTimeout = 0 ;
446- this . attachSpeechDone ( ) ;
446+ if ( this . options . speechTiming . asynchronous ) {
447+ this . attachSpeechAsync ( ) ;
448+ } else {
449+ this . attachSpeechSync ( ) ;
447450 }
448- this . awaitingSpeech = Array . from ( this . math ) ;
449- this . renderPromises . push ( new Promise < void > ( ( ok , _fail ) => {
450- this . attachSpeechDone = ok ;
451- } ) ) ;
452- this . speechTimeout = setTimeout (
453- ( ) => this . attachSpeechLoop ( ) ,
454- this . options . speechTiming . initial
455- ) ;
456451 }
457452 this . processed . set ( 'attach-speech' ) ;
458453 }
459454 return this ;
460455 }
461456
457+ /**
458+ * Add speech synchronously (e.g., for use in node applications on the server)
459+ */
460+ protected attachSpeechSync ( ) {
461+ for ( const math of this . math ) {
462+ ( math as EnrichedMathItem < N , T , D > ) . attachSpeech ( this ) ;
463+ }
464+ }
465+
466+ /**
467+ * Add speech in small chunks, allowing screen updates in between
468+ * (e.g., helpful with lazy typesetting)
469+ */
470+ protected attachSpeechAsync ( ) {
471+ if ( this . speechTimeout ) {
472+ clearTimeout ( this . speechTimeout ) ;
473+ this . speechTimeout = 0 ;
474+ this . attachSpeechDone ( ) ;
475+ }
476+ this . awaitingSpeech = Array . from ( this . math ) ;
477+ this . renderPromises . push ( new Promise < void > ( ( ok , _fail ) => {
478+ this . attachSpeechDone = ok ;
479+ } ) ) ;
480+ this . speechTimeout = setTimeout (
481+ ( ) => this . attachSpeechLoop ( ) ,
482+ this . options . speechTiming . initial
483+ ) ;
484+ }
485+
462486 /**
463487 * Loops through math items to attach speech until the timeout threshold is reached.
464488 */
0 commit comments