1- const background = document . getElementById ( 'background' ) ;
2- const muteIndicator = document . getElementById ( 'mute-indicator' ) ;
3- const indicatorText = muteIndicator ?. querySelector ( '.indicator-text' ) ?? null ;
4- const aiCircle = document . querySelector ( '[data-role="ai"]' ) ;
5- const userCircle = document . querySelector ( '[data-role="user"]' ) ;
6- const backgroundUrls = document . getElementById ( 'background-urls' ) ;
1+ let background = null ;
2+ let muteIndicator = null ;
3+ let indicatorText = null ;
4+ let aiCircle = null ;
5+ let userCircle = null ;
6+ let backgroundUrls = null ;
7+
8+ let domListenersRegistered = false ;
9+
10+ function cacheDomReferences ( ) {
11+ background = document . getElementById ( 'background' ) ;
12+ muteIndicator = document . getElementById ( 'mute-indicator' ) ;
13+ indicatorText = muteIndicator ?. querySelector ( '.indicator-text' ) ?? null ;
14+ aiCircle = document . querySelector ( '[data-role="ai"]' ) ;
15+ userCircle = document . querySelector ( '[data-role="user"]' ) ;
16+ backgroundUrls = document . getElementById ( 'background-urls' ) ;
17+ }
18+
19+ function registerDomEventListeners ( ) {
20+ if ( domListenersRegistered ) {
21+ return ;
22+ }
23+
24+ muteIndicator ?. addEventListener ( 'click' , handleMuteToggle ) ;
25+
26+ document . addEventListener ( 'click' , handleDocumentClick ) ;
27+ document . addEventListener ( 'keydown' , handleDocumentKeydown ) ;
28+
29+ domListenersRegistered = true ;
30+ }
731
832let currentImageModel = 'flux' ;
933let chatHistory = [ ] ;
@@ -49,12 +73,20 @@ function resolveAssetPath(relativePath) {
4973 }
5074}
5175
52- window . addEventListener ( 'load' , async ( ) => {
76+ async function bootstrap ( ) {
77+ cacheDomReferences ( ) ;
78+ registerDomEventListeners ( ) ;
5379 await loadSystemPrompt ( ) ;
5480 setupSpeechRecognition ( ) ;
5581 updateMuteIndicator ( ) ;
5682 await initializeVoiceControl ( ) ;
57- } ) ;
83+ }
84+
85+ if ( document . readyState === 'complete' ) {
86+ bootstrap ( ) ;
87+ } else {
88+ window . addEventListener ( 'load' , bootstrap ) ;
89+ }
5890
5991function setCircleState ( circle , { speaking = false , listening = false , error = false , label = '' } = { } ) {
6092 if ( ! circle ) {
@@ -386,17 +418,15 @@ function handleMuteToggle(event) {
386418 }
387419}
388420
389- muteIndicator ?. addEventListener ( 'click' , handleMuteToggle ) ;
390-
391- document . addEventListener ( 'click' , ( event ) => {
421+ function handleDocumentClick ( event ) {
392422 if ( muteIndicator ?. contains ( event . target ) ) {
393423 return ;
394424 }
395425
396426 handleMuteToggle ( event ) ;
397- } ) ;
427+ }
398428
399- document . addEventListener ( 'keydown' , ( event ) => {
429+ function handleDocumentKeydown ( event ) {
400430 if ( event . key !== 'Enter' && event . key !== ' ' ) {
401431 return ;
402432 }
@@ -407,7 +437,7 @@ document.addEventListener('keydown', (event) => {
407437
408438 event . preventDefault ( ) ;
409439 handleMuteToggle ( event ) ;
410- } ) ;
440+ }
411441
412442let speakingFallbackTimeout = null ;
413443
0 commit comments