@@ -13,9 +13,9 @@ import { apiExtractText } from './api'
1313
1414let isProcessing = false
1515
16- let btnSubmit : HTMLButtonElement
17- let textarea : HTMLTextAreaElement
18- let footer : HTMLDivElement
16+ let btnSubmit : HTMLButtonElement | null | undefined
17+ let textarea : HTMLTextAreaElement | null
18+ let chatGptFooter : HTMLDivElement | null
1919
2020
2121function renderSlashCommandsMenu ( ) {
@@ -24,7 +24,7 @@ function renderSlashCommandsMenu() {
2424 if ( div ) div . remove ( )
2525
2626 div = document . createElement ( 'wcg-slash-commands-menu' )
27- const textareaParentParent = textarea . parentElement ?. parentElement
27+ const textareaParentParent = textarea ? .parentElement ?. parentElement
2828
2929 textareaParentParent ?. insertBefore ( div , textareaParentParent . firstChild )
3030 render ( < SlashCommandsMenu textarea = { textarea } /> , div )
@@ -58,6 +58,8 @@ async function processQuery(query: string, userConfig: UserConfig) {
5858
5959async function handleSubmit ( query : string ) {
6060
61+ if ( ! textarea ) return
62+
6163 const userConfig = await getUserConfig ( )
6264
6365 if ( ! userConfig . webAccess ) {
@@ -81,21 +83,27 @@ async function handleSubmit(query: string) {
8183}
8284
8385async function onSubmit ( event : MouseEvent | KeyboardEvent ) {
86+
87+ if ( ! textarea ) return
88+
8489 const isKeyEvent = event instanceof KeyboardEvent
8590
8691 if ( isKeyEvent && event . shiftKey && event . key === 'Enter' ) return
8792
8893 if ( isKeyEvent && event . key === 'Enter' && event . isComposing ) return
8994
9095 if ( ! isProcessing && ( event . type === "click" || ( isKeyEvent && event . key === 'Enter' ) ) ) {
91- const query = textarea . value . trim ( )
96+ const query = textarea ? .value . trim ( )
9297
93- if ( query === "" ) return
98+ // if query is empty or undefined, return
99+ if ( ! query ) return
94100
95101 textarea . value = ""
96102
97103 const isPartialCommand = slashCommands . some ( command => command . name . startsWith ( query ) && query . length <= command . name . length )
98- if ( isPartialCommand ) return
104+ if ( isPartialCommand ) {
105+ return
106+ }
99107
100108 isProcessing = true
101109 await handleSubmit ( query )
@@ -104,14 +112,14 @@ async function onSubmit(event: MouseEvent | KeyboardEvent) {
104112}
105113
106114function pressEnter ( ) {
107- textarea . focus ( )
115+ textarea ? .focus ( )
108116 const enterEvent = new KeyboardEvent ( 'keydown' , {
109117 bubbles : true ,
110118 cancelable : true ,
111119 key : 'Enter' ,
112120 code : 'Enter'
113121 } )
114- textarea . dispatchEvent ( enterEvent )
122+ textarea ? .dispatchEvent ( enterEvent )
115123}
116124
117125function showErrorMessage ( error : Error ) {
@@ -124,59 +132,93 @@ function showErrorMessage(error: Error) {
124132
125133async function updateUI ( ) {
126134
127- if ( getWebChatGPTToolbar ( ) ) return
135+ formChild = document . querySelector ( 'form' ) ?. children [ 0 ] as HTMLElement
136+ textarea = getTextArea ( )
137+ // console.info("UpdateUI textarea: ", textarea)
138+
139+ const toolbar = getWebChatGPTToolbar ( )
140+ if ( ! textarea ) {
141+ toolbar ?. remove ( )
142+ return
143+ }
144+
145+ if ( toolbar ) return
146+
147+ console . info ( "WebChatGPT: Updating UI" )
128148
129149 btnSubmit = getSubmitButton ( )
130- textarea = getTextArea ( )
131- footer = getFooter ( )
150+ btnSubmit ?. addEventListener ( "click" , onSubmit )
132151
133- if ( textarea && btnSubmit ) {
152+ textarea ?. addEventListener ( "keydown" , onSubmit )
134153
135- textarea . addEventListener ( "keydown" , onSubmit )
136- btnSubmit . addEventListener ( "click" , onSubmit )
154+ await renderToolbar ( )
137155
138- const textareaParentParent = textarea . parentElement ?. parentElement
139- if ( textareaParentParent && textareaParentParent . parentElement ) {
140- textareaParentParent . style . flexDirection = 'column'
141- textareaParentParent . parentElement . style . flexDirection = 'column'
142- textareaParentParent . parentElement . style . gap = '0px'
143- textareaParentParent . parentElement . style . marginBottom = '0.5em'
144- }
156+ renderSlashCommandsMenu ( )
145157
146- try {
147- const { shadowRootDiv, shadowRoot } = await createShadowRoot ( 'content-scripts/mainUI.css' )
148- shadowRootDiv . classList . add ( 'wcg-toolbar' )
149- textareaParentParent ?. appendChild ( shadowRootDiv )
150- render ( < Toolbar textarea = { textarea } /> , shadowRoot )
151- } catch ( e ) {
152- if ( e instanceof Error ) {
153- showErrorMessage ( Error ( `Error loading WebChatGPT toolbar: ${ e . message } . Please reload the page (F5).` ) ) ;
154- console . error ( e )
155- }
156- }
157- // textarea.parentElement.style.flexDirection = 'row'
158+ // textarea.parentElement.style.flexDirection = 'row'
158159
159- renderSlashCommandsMenu ( )
160+ chatGptFooter = getFooter ( )
161+ if ( chatGptFooter ) {
162+ const lastChild = chatGptFooter . lastElementChild as HTMLElement
163+ if ( lastChild ) lastChild . style . padding = '0 0 0.5em 0'
160164 }
165+ }
161166
162- if ( footer ) {
163- const lastChild = footer . lastElementChild as HTMLElement
164- if ( lastChild )
165- lastChild . style . padding = '0 0 0.5em 0'
167+ async function renderToolbar ( ) {
168+
169+ try {
170+ const textareaParentParent = textarea ?. parentElement ?. parentElement
171+ // const textareaParentParent = formChild
172+ // if (textareaParentParent && textareaParentParent.parentElement) {
173+ // textareaParentParent.style.flexDirection = 'column'
174+ // textareaParentParent.parentElement.style.flexDirection = 'column'
175+ // textareaParentParent.parentElement.style.gap = '0px'
176+ // textareaParentParent.parentElement.style.marginBottom = '0.5em'
177+ // }
178+
179+ const { shadowRootDiv, shadowRoot } = await createShadowRoot ( 'content-scripts/mainUI.css' )
180+ shadowRootDiv . classList . add ( 'wcg-toolbar' )
181+ textareaParentParent ?. appendChild ( shadowRootDiv )
182+ render ( < Toolbar textarea = { textarea } /> , shadowRoot )
183+
184+ } catch ( e ) {
185+ if ( e instanceof Error ) {
186+ showErrorMessage ( Error ( `Error loading WebChatGPT toolbar: ${ e . message } . Please reload the page (F5).` ) )
187+ }
166188 }
167189}
168190
169- const rootEl = getRootElement ( )
170- window . onload = function ( ) {
171- updateUI ( )
191+ const form = document . querySelector ( 'form' )
192+ const formParent = form ?. parentElement
172193
194+ const rootEl = getRootElement ( )
195+ let formChild = document . querySelector ( 'form' ) ?. children [ 0 ] as HTMLElement
196+ const mutationObserver = new MutationObserver ( ( ) => {
173197 try {
174- new MutationObserver ( ( ) => {
175- updateUI ( )
176- } ) . observe ( rootEl , { childList : true } )
198+ updateUI ( )
177199 } catch ( e ) {
178200 if ( e instanceof Error ) {
179201 showErrorMessage ( e )
180202 }
181203 }
204+ } )
205+
206+ window . onload = function ( ) {
207+ updateUI ( )
208+
209+ if ( formChild ) {
210+ mutationObserver . observe ( formChild , { childList : true } )
211+ }
212+
213+ if ( rootEl ) {
214+ mutationObserver . observe ( rootEl , { childList : true } )
215+ }
216+
217+ if ( formParent ) {
218+ mutationObserver . observe ( formParent , { childList : true } )
219+ }
220+ }
221+
222+ window . onunload = function ( ) {
223+ mutationObserver . disconnect ( )
182224}
0 commit comments