@@ -13,9 +13,9 @@ import { apiExtractText } from './api'
13
13
14
14
let isProcessing = false
15
15
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
19
19
20
20
21
21
function renderSlashCommandsMenu ( ) {
@@ -24,7 +24,7 @@ function renderSlashCommandsMenu() {
24
24
if ( div ) div . remove ( )
25
25
26
26
div = document . createElement ( 'wcg-slash-commands-menu' )
27
- const textareaParentParent = textarea . parentElement ?. parentElement
27
+ const textareaParentParent = textarea ? .parentElement ?. parentElement
28
28
29
29
textareaParentParent ?. insertBefore ( div , textareaParentParent . firstChild )
30
30
render ( < SlashCommandsMenu textarea = { textarea } /> , div )
@@ -58,6 +58,8 @@ async function processQuery(query: string, userConfig: UserConfig) {
58
58
59
59
async function handleSubmit ( query : string ) {
60
60
61
+ if ( ! textarea ) return
62
+
61
63
const userConfig = await getUserConfig ( )
62
64
63
65
if ( ! userConfig . webAccess ) {
@@ -81,21 +83,27 @@ async function handleSubmit(query: string) {
81
83
}
82
84
83
85
async function onSubmit ( event : MouseEvent | KeyboardEvent ) {
86
+
87
+ if ( ! textarea ) return
88
+
84
89
const isKeyEvent = event instanceof KeyboardEvent
85
90
86
91
if ( isKeyEvent && event . shiftKey && event . key === 'Enter' ) return
87
92
88
93
if ( isKeyEvent && event . key === 'Enter' && event . isComposing ) return
89
94
90
95
if ( ! isProcessing && ( event . type === "click" || ( isKeyEvent && event . key === 'Enter' ) ) ) {
91
- const query = textarea . value . trim ( )
96
+ const query = textarea ? .value . trim ( )
92
97
93
- if ( query === "" ) return
98
+ // if query is empty or undefined, return
99
+ if ( ! query ) return
94
100
95
101
textarea . value = ""
96
102
97
103
const isPartialCommand = slashCommands . some ( command => command . name . startsWith ( query ) && query . length <= command . name . length )
98
- if ( isPartialCommand ) return
104
+ if ( isPartialCommand ) {
105
+ return
106
+ }
99
107
100
108
isProcessing = true
101
109
await handleSubmit ( query )
@@ -104,14 +112,14 @@ async function onSubmit(event: MouseEvent | KeyboardEvent) {
104
112
}
105
113
106
114
function pressEnter ( ) {
107
- textarea . focus ( )
115
+ textarea ? .focus ( )
108
116
const enterEvent = new KeyboardEvent ( 'keydown' , {
109
117
bubbles : true ,
110
118
cancelable : true ,
111
119
key : 'Enter' ,
112
120
code : 'Enter'
113
121
} )
114
- textarea . dispatchEvent ( enterEvent )
122
+ textarea ? .dispatchEvent ( enterEvent )
115
123
}
116
124
117
125
function showErrorMessage ( error : Error ) {
@@ -124,59 +132,93 @@ function showErrorMessage(error: Error) {
124
132
125
133
async function updateUI ( ) {
126
134
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" )
128
148
129
149
btnSubmit = getSubmitButton ( )
130
- textarea = getTextArea ( )
131
- footer = getFooter ( )
150
+ btnSubmit ?. addEventListener ( "click" , onSubmit )
132
151
133
- if ( textarea && btnSubmit ) {
152
+ textarea ?. addEventListener ( "keydown" , onSubmit )
134
153
135
- textarea . addEventListener ( "keydown" , onSubmit )
136
- btnSubmit . addEventListener ( "click" , onSubmit )
154
+ await renderToolbar ( )
137
155
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 ( )
145
157
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'
158
159
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'
160
164
}
165
+ }
161
166
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
+ }
166
188
}
167
189
}
168
190
169
- const rootEl = getRootElement ( )
170
- window . onload = function ( ) {
171
- updateUI ( )
191
+ const form = document . querySelector ( 'form' )
192
+ const formParent = form ?. parentElement
172
193
194
+ const rootEl = getRootElement ( )
195
+ let formChild = document . querySelector ( 'form' ) ?. children [ 0 ] as HTMLElement
196
+ const mutationObserver = new MutationObserver ( ( ) => {
173
197
try {
174
- new MutationObserver ( ( ) => {
175
- updateUI ( )
176
- } ) . observe ( rootEl , { childList : true } )
198
+ updateUI ( )
177
199
} catch ( e ) {
178
200
if ( e instanceof Error ) {
179
201
showErrorMessage ( e )
180
202
}
181
203
}
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 ( )
182
224
}
0 commit comments