@@ -39,7 +39,7 @@ import { hideHinter } from './hinter';
39
39
import getFileMode from './utils' ;
40
40
import tidyCode from './tidier' ;
41
41
import useCodeMirror from './codemirror' ;
42
- import usePrevious from '../../../../utils/usePrevious ' ;
42
+ import { useEffectWithComparison } from '../../hooks/custom-hooks ' ;
43
43
44
44
function Editor ( {
45
45
provideController,
@@ -76,7 +76,6 @@ function Editor({
76
76
const [ currentLine , setCurrentLine ] = useState ( 1 ) ;
77
77
const beep = useRef ( ) ;
78
78
const docs = useRef ( ) ;
79
- const previous = usePrevious ( { file, unsavedChanges, consoleEvents } ) ;
80
79
81
80
const updateLintingMessageAccessibility = debounce ( ( annotations ) => {
82
81
clearLintMessage ( ) ;
@@ -116,6 +115,15 @@ function Editor({
116
115
setCurrentLine
117
116
} ) ;
118
117
118
+ // Lets the parent component access file content-specific functionality...
119
+ // TODO(connie) - Revisit the logic here, can we wrap this in useCallback or something?
120
+ provideController ( {
121
+ tidyCode : ( ) => tidyCode ( cmInstance . current ) ,
122
+ showFind,
123
+ showReplace,
124
+ getContent
125
+ } ) ;
126
+
119
127
const initializeDocuments = ( ) => {
120
128
docs . current = { } ;
121
129
files . forEach ( ( currentFile ) => {
@@ -152,87 +160,88 @@ function Editor({
152
160
initializeDocuments ( ) ;
153
161
} , [ files ] ) ;
154
162
155
- useEffect ( ( ) => {
156
- const fileMode = getFileMode ( file . name ) ;
157
- if ( fileMode === 'javascript' ) {
158
- // Define the new Emmet configuration based on the file mode
159
- const emmetConfig = {
160
- preview : [ 'html' ] ,
161
- markTagPairs : false ,
162
- autoRenameTags : true
163
- } ;
164
- cmInstance . current . setOption ( 'emmet' , emmetConfig ) ;
165
- }
166
- const oldDoc = cmInstance . current . swapDoc ( docs . current [ file . id ] ) ;
167
- if ( previous ?. file ) {
168
- docs . current [ previous . file . id ] = oldDoc ;
169
- }
170
- cmInstance . current . focus ( ) ;
171
-
172
- if ( ! previous ?. unsavedChanges ) {
173
- setTimeout ( ( ) => setUnsavedChanges ( false ) , 400 ) ;
174
- }
163
+ useEffectWithComparison (
164
+ ( _ , prevProps ) => {
165
+ const fileMode = getFileMode ( file . name ) ;
166
+ if ( fileMode === 'javascript' ) {
167
+ // Define the new Emmet configuration based on the file mode
168
+ const emmetConfig = {
169
+ preview : [ 'html' ] ,
170
+ markTagPairs : false ,
171
+ autoRenameTags : true
172
+ } ;
173
+ cmInstance . current . setOption ( 'emmet' , emmetConfig ) ;
174
+ }
175
+ const oldDoc = cmInstance . current . swapDoc ( docs . current [ file . id ] ) ;
176
+ if ( prevProps ?. file ) {
177
+ docs . current [ prevProps . file . id ] = oldDoc ;
178
+ }
179
+ cmInstance . current . focus ( ) ;
175
180
176
- for ( let i = 0 ; i < cmInstance . current . lineCount ( ) ; i += 1 ) {
177
- cmInstance . current . removeLineClass ( i , 'background' , 'line-runtime-error' ) ;
178
- }
181
+ if ( ! prevProps ?. unsavedChanges ) {
182
+ setTimeout ( ( ) => setUnsavedChanges ( false ) , 400 ) ;
183
+ }
179
184
180
- // I think we only need to re-provide this if the content changes? idk
181
- // TODO(connie) - Revisit the logic here
182
- provideController ( {
183
- tidyCode : ( ) => tidyCode ( cmInstance . current ) ,
184
- showFind,
185
- showReplace,
186
- getContent
187
- } ) ;
188
- } , [ file . id ] ) ;
185
+ for ( let i = 0 ; i < cmInstance . current . lineCount ( ) ; i += 1 ) {
186
+ cmInstance . current . removeLineClass (
187
+ i ,
188
+ 'background' ,
189
+ 'line-runtime-error'
190
+ ) ;
191
+ }
192
+ } ,
193
+ [ file . id ]
194
+ ) ;
189
195
190
196
useEffect ( ( ) => {
191
197
// close the hinter window once the preference is turned off
192
198
if ( ! autocompleteHinter ) hideHinter ( cmInstance . current ) ;
193
199
} , [ autocompleteHinter ] ) ;
194
200
195
201
// TODO: Should this be watching more deps?
196
- useEffect ( ( ) => {
197
- if ( runtimeErrorWarningVisible ) {
198
- if ( previous && consoleEvents . length !== previous . consoleEvents . length ) {
199
- consoleEvents . forEach ( ( consoleEvent ) => {
200
- if ( consoleEvent . method === 'error' ) {
201
- // It doesn't work if you create a new Error, but this works
202
- // LOL
203
- const errorObj = { stack : consoleEvent . data [ 0 ] . toString ( ) } ;
204
- StackTrace . fromError ( errorObj ) . then ( ( stackLines ) => {
205
- expandConsole ( ) ;
206
- const line = stackLines . find (
207
- ( l ) => l . fileName && l . fileName . startsWith ( '/' )
208
- ) ;
209
- if ( ! line ) return ;
210
- const fileNameArray = line . fileName . split ( '/' ) ;
211
- const fileName = fileNameArray . slice ( - 1 ) [ 0 ] ;
212
- const filePath = fileNameArray . slice ( 0 , - 1 ) . join ( '/' ) ;
213
- const fileWithError = files . find (
214
- ( f ) => f . name === fileName && f . filePath === filePath
215
- ) ;
216
- setSelectedFile ( fileWithError . id ) ;
217
- cmInstance . current . addLineClass (
218
- line . lineNumber - 1 ,
219
- 'background' ,
220
- 'line-runtime-error'
221
- ) ;
222
- } ) ;
202
+ useEffectWithComparison (
203
+ ( _ , prevProps ) => {
204
+ if ( runtimeErrorWarningVisible ) {
205
+ if ( consoleEvents . length !== prevProps . consoleEvents . length ) {
206
+ consoleEvents . forEach ( ( consoleEvent ) => {
207
+ if ( consoleEvent . method === 'error' ) {
208
+ // It doesn't work if you create a new Error, but this works
209
+ // LOL
210
+ const errorObj = { stack : consoleEvent . data [ 0 ] . toString ( ) } ;
211
+ StackTrace . fromError ( errorObj ) . then ( ( stackLines ) => {
212
+ expandConsole ( ) ;
213
+ const line = stackLines . find (
214
+ ( l ) => l . fileName && l . fileName . startsWith ( '/' )
215
+ ) ;
216
+ if ( ! line ) return ;
217
+ const fileNameArray = line . fileName . split ( '/' ) ;
218
+ const fileName = fileNameArray . slice ( - 1 ) [ 0 ] ;
219
+ const filePath = fileNameArray . slice ( 0 , - 1 ) . join ( '/' ) ;
220
+ const fileWithError = files . find (
221
+ ( f ) => f . name === fileName && f . filePath === filePath
222
+ ) ;
223
+ setSelectedFile ( fileWithError . id ) ;
224
+ cmInstance . current . addLineClass (
225
+ line . lineNumber - 1 ,
226
+ 'background' ,
227
+ 'line-runtime-error'
228
+ ) ;
229
+ } ) ;
230
+ }
231
+ } ) ;
232
+ } else {
233
+ for ( let i = 0 ; i < cmInstance . current . lineCount ( ) ; i += 1 ) {
234
+ cmInstance . current . removeLineClass (
235
+ i ,
236
+ 'background' ,
237
+ 'line-runtime-error'
238
+ ) ;
223
239
}
224
- } ) ;
225
- } else {
226
- for ( let i = 0 ; i < cmInstance . current . lineCount ( ) ; i += 1 ) {
227
- cmInstance . current . removeLineClass (
228
- i ,
229
- 'background' ,
230
- 'line-runtime-error'
231
- ) ;
232
240
}
233
241
}
234
- }
235
- } , [ consoleEvents , runtimeErrorWarningVisible ] ) ;
242
+ } ,
243
+ [ consoleEvents , runtimeErrorWarningVisible ]
244
+ ) ;
236
245
237
246
const editorSectionClass = classNames ( {
238
247
editor : true ,
0 commit comments