@@ -30,7 +30,7 @@ import {MathML} from '../input/mathml.js';
3030import { SerializedMmlVisitor } from '../core/MmlTree/SerializedMmlVisitor.js' ;
3131import { OptionList , expandable } from '../util/Options.js' ;
3232import { Sre } from './sre.js' ;
33- import { buildSpeech , Timing } from './speech/SpeechUtil.js' ;
33+ import { buildSpeech } from './speech/SpeechUtil.js' ;
3434import { GeneratorPool } from './speech/GeneratorPool.js' ;
3535
3636/*==========================================================================*/
@@ -45,12 +45,12 @@ export type Constructor<T> = new(...args: any[]) => T;
4545/**
4646 * Add STATE value for being enriched (after COMPILED and before TYPESET)
4747 */
48- newState ( 'ENRICHED' , 30 ) ;
48+ newState ( 'ENRICHED' , STATE . COMPILED + 10 ) ;
4949
5050/**
51- * Add STATE value for adding speech (after TYPESET )
51+ * Add STATE value for adding speech (after INSERTED )
5252 */
53- newState ( 'ATTACHSPEECH' , 205 ) ;
53+ newState ( 'ATTACHSPEECH' , STATE . INSERTED + 10 ) ;
5454
5555/*==========================================================================*/
5656
@@ -242,7 +242,7 @@ export function EnrichedMathItemMixin<N, T, D, B extends Constructor<AbstractMat
242242 *
243243 * @return {[string, string] } Pair comprising speech and braille.
244244 */
245- private existingSpeech ( ) : [ string , string ] {
245+ protected existingSpeech ( ) : [ string , string ] {
246246 const attributes = this . root . attributes ;
247247 let speech = attributes . get ( 'aria-label' ) as string ;
248248 if ( ! speech ) {
@@ -378,6 +378,11 @@ export function EnrichedMathDocumentMixin<N, T, D, B extends MathDocumentConstru
378378 enrich : [ STATE . ENRICHED ] ,
379379 attachSpeech : [ STATE . ATTACHSPEECH ]
380380 } ) ,
381+ speechTiming : {
382+ initial : 100 , // initial delay until starting to add speech
383+ threshold : 250 , // time (in milliseconds) to process speech before letting screen update
384+ intermediate : 10 // delay after processing speech reaches the threshold
385+ } ,
381386 sre : expandable ( {
382387 speech : 'none' , // by default no speech is included
383388 locale : 'en' , // switch the locale
@@ -391,6 +396,16 @@ export function EnrichedMathDocumentMixin<N, T, D, B extends MathDocumentConstru
391396 } )
392397 } ;
393398
399+ /**
400+ * The list of MathItems that need to be processed for speech
401+ */
402+ protected awaitingSpeech : MathItem < N , T , D > [ ] ;
403+
404+ /**
405+ * The identifier from setTimeout for the next speech loop
406+ */
407+ protected speechTimeout : number = 0 ;
408+
394409 /**
395410 * Enrich the MathItem class used for this MathDocument, and create the
396411 * temporary MathItem used for enrchment
@@ -414,47 +429,41 @@ export function EnrichedMathDocumentMixin<N, T, D, B extends MathDocumentConstru
414429 ) ;
415430 }
416431
417- private DELAY : number = Timing . INITIAL ;
418- private awaitingSpeech : MathItem < N , T , D > [ ] = [ ] ;
419-
420432 /**
421433 * Attach speech from a MathItem to a node
422434 */
423435 public attachSpeech ( ) {
424436 if ( ! this . processed . isSet ( 'attach-speech' ) ) {
425437 if ( this . options . enableSpeech || this . options . enableBraille ) {
438+ if ( this . speechTimeout ) {
439+ clearTimeout ( this . speechTimeout ) ;
440+ this . speechTimeout = 0 ;
441+ }
426442 this . awaitingSpeech = Array . from ( this . math ) ;
427- this . attachSpeechStart ( ) ;
443+ this . speechTimeout = setTimeout (
444+ ( ) => this . attachSpeechLoop ( ) ,
445+ this . options . speechTiming . initial
446+ ) ;
428447 }
429- }
430- return this ;
431- }
432-
433- /**
434- * Start attaching speech to nodes.
435- */
436- private attachSpeechStart ( ) {
437- if ( this . awaitingSpeech . length ) {
438- setTimeout (
439- ( ) => this . attachSpeechLoop ( ) ,
440- this . DELAY ) ;
441- } else {
442448 this . processed . set ( 'attach-speech' ) ;
443449 }
450+ return this ;
444451 }
445452
446453 /**
447454 * Loops through math items to attach speech until the timeout threshold is reached.
448455 */
449- private attachSpeechLoop ( ) {
456+ protected attachSpeechLoop ( ) {
457+ const timing = this . options . speechTiming ;
458+ const awaitingSpeech = this . awaitingSpeech ;
450459 const timeStart = new Date ( ) . getTime ( ) ;
451- const timeEnd = timeStart + Timing . THRESHOLD ;
452- while ( this . awaitingSpeech . length && new Date ( ) . getTime ( ) < timeEnd ) {
453- const math = this . awaitingSpeech . shift ( ) ;
460+ const timeEnd = timeStart + timing . threshold ;
461+ do {
462+ const math = awaitingSpeech . shift ( ) ;
454463 ( math as EnrichedMathItem < N , T , D > ) . attachSpeech ( this ) ;
455- }
456- this . DELAY = Timing . INTERMEDIATE ;
457- this . attachSpeechStart ( ) ;
464+ } while ( awaitingSpeech . length && new Date ( ) . getTime ( ) < timeEnd ) ;
465+ this . speechTimeout = awaitingSpeech . length ?
466+ setTimeout ( ( ) => this . attachSpeechLoop ( ) , timing . intermediate ) : 0 ;
458467 }
459468
460469 /**
0 commit comments