1
1
import 'reflect-metadata' ;
2
2
import { singleton , container } from 'tsyringe' ;
3
-
3
+ import cloneDeep from 'lodash/cloneDeep' ;
4
4
import { Component } from 'mo/react' ;
5
5
import {
6
6
EditorModel ,
@@ -104,8 +104,11 @@ export class EditorService
104
104
} ) ;
105
105
}
106
106
107
- public isOpened ( tabId : string ) : boolean {
108
- const { groups = [ ] } = this . state ;
107
+ public isOpened (
108
+ tabId : string ,
109
+ filterGroups ?: IEditorGroup < any , any > [ ]
110
+ ) : boolean {
111
+ const groups = filterGroups || this . state . groups || [ ] ;
109
112
return groups . some ( ( group ) => this . getTabById ( tabId , group ) ) ;
110
113
}
111
114
@@ -207,6 +210,8 @@ export class EditorService
207
210
const nextGroups = [ ...groups ] ;
208
211
const nextGroup = nextGroups [ groupIndex ] ;
209
212
const tabIndex = nextGroup . data ! . findIndex ( searchById ( tabId ) ) ;
213
+
214
+ const tab = cloneDeep ( nextGroup . data ! [ tabIndex ] ) ;
210
215
if ( tabIndex === - 1 ) return ;
211
216
212
217
if ( nextGroup . data ! . length === 1 && tabIndex === 0 ) {
@@ -215,14 +220,19 @@ export class EditorService
215
220
const activeGroup =
216
221
nextGroups [ groupIndex + 1 ] || nextGroups [ groupIndex - 1 ] ;
217
222
218
- // the model of closed tab should be disposed after closing
219
- this . disposeModel ( nextGroup . data ! [ tabIndex ] ) ;
220
223
nextGroups . splice ( groupIndex , 1 ) ;
221
224
222
- this . setState ( {
223
- groups : nextGroups ,
224
- current : nextGroups ?. length === 0 ? undefined : activeGroup ,
225
- } ) ;
225
+ this . setState (
226
+ {
227
+ groups : nextGroups ,
228
+ current : nextGroups ?. length === 0 ? undefined : activeGroup ,
229
+ } ,
230
+ ( ) => {
231
+ const isOpened = this . isOpened ( tabId ) ;
232
+ // the model of closed tab should be disposed after closing
233
+ ! isOpened && this . disposeModel ( tab ) ;
234
+ }
235
+ ) ;
226
236
return ;
227
237
}
228
238
@@ -235,15 +245,19 @@ export class EditorService
235
245
nextGroup . activeTab = nextTab ?. id ;
236
246
}
237
247
238
- this . disposeModel ( nextGroup . data ! [ tabIndex ] ) ;
239
-
240
248
nextGroup . data ! . splice ( tabIndex , 1 ) ;
241
249
nextGroups [ groupIndex ] = nextGroup ;
242
250
243
- this . setState ( {
244
- current : nextGroup ,
245
- groups : nextGroups ,
246
- } ) ;
251
+ this . setState (
252
+ {
253
+ current : nextGroup ,
254
+ groups : nextGroups ,
255
+ } ,
256
+ ( ) => {
257
+ const isOpened = this . isOpened ( tabId ) ;
258
+ ! isOpened && this . disposeModel ( tab ) ;
259
+ }
260
+ ) ;
247
261
}
248
262
249
263
public closeOthers ( tab : IEditorTab , groupId : number ) {
@@ -258,14 +272,23 @@ export class EditorService
258
272
259
273
const updateTabs = nextTabData ! . filter ( searchById ( tabId ) ) ;
260
274
// tab data is unlikely to be large enough to affect exec time, so we filter twice for maintainability
261
- const removedTabs = nextTabData ! . filter ( ( item ) => item . id !== tabId ) ;
262
-
263
- this . disposeModel ( removedTabs ) ;
275
+ const removedTabs = cloneDeep (
276
+ nextTabData ! . filter (
277
+ ( item ) =>
278
+ item . id !== tabId &&
279
+ ! this . isOpened (
280
+ item . id ! ,
281
+ nextGroups . filter ( ( g ) => g . id !== groupId )
282
+ )
283
+ )
284
+ ) ;
264
285
265
286
this . updateGroup ( groupId , {
266
287
data : updateTabs ,
267
288
} ) ;
268
289
this . setActive ( groupId , tabId ! ) ;
290
+
291
+ this . disposeModel ( removedTabs ) ;
269
292
}
270
293
271
294
public closeToRight ( tab : IEditorTab , groupId : number ) {
@@ -282,14 +305,21 @@ export class EditorService
282
305
if ( tabIndex <= - 1 ) return ;
283
306
284
307
const updateTabs = nextTabData ?. slice ( 0 , tabIndex + 1 ) ;
285
- const removedTabs = nextTabData ?. slice ( tabIndex + 1 ) ;
286
-
287
- removedTabs && this . disposeModel ( removedTabs ) ;
308
+ const removedTabs = cloneDeep (
309
+ nextTabData ?. slice ( tabIndex + 1 ) . filter (
310
+ ( item ) =>
311
+ ! this . isOpened (
312
+ item . id ! ,
313
+ nextGroups . filter ( ( g ) => g . id !== groupId )
314
+ )
315
+ )
316
+ ) ;
288
317
289
318
this . updateGroup ( groupId , {
290
319
data : updateTabs ,
291
320
} ) ;
292
321
this . setActive ( groupId , tabId ! ) ;
322
+ this . disposeModel ( removedTabs || [ ] ) ;
293
323
}
294
324
295
325
public closeToLeft ( tab : IEditorTab , groupId : number ) {
@@ -306,14 +336,21 @@ export class EditorService
306
336
if ( tabIndex <= - 1 ) return ;
307
337
308
338
const updateTabs = nextTabData ?. slice ( tabIndex , nextTabData . length ) ;
309
- const removedTabs = nextTabData ?. slice ( 0 , tabIndex ) ;
310
-
311
- this . disposeModel ( removedTabs || [ ] ) ;
339
+ const removedTabs = cloneDeep (
340
+ nextTabData ?. slice ( 0 , tabIndex ) . filter (
341
+ ( item ) =>
342
+ ! this . isOpened (
343
+ item . id ! ,
344
+ nextGroups . filter ( ( g ) => g . id !== groupId )
345
+ )
346
+ )
347
+ ) ;
312
348
313
349
this . updateGroup ( groupId , {
314
350
data : updateTabs ,
315
351
} ) ;
316
352
this . setActive ( groupId , tabId ! ) ;
353
+ this . disposeModel ( removedTabs || [ ] ) ;
317
354
}
318
355
319
356
public getGroupById ( groupId : number ) : IEditorGroup | undefined {
@@ -426,19 +463,29 @@ export class EditorService
426
463
const nextGroups = [ ...groups ] ;
427
464
let nextCurrentGroup = current ;
428
465
429
- // dispose all models in specific group
430
- this . disposeModel ( nextGroups [ groupIndex ] . data || [ ] ) ;
466
+ const removedGroup = nextGroups . splice ( groupIndex , 1 ) ;
431
467
432
- nextGroups . splice ( groupIndex , 1 ) ;
468
+ const removed = cloneDeep (
469
+ removedGroup [ 0 ] . data ?. filter (
470
+ ( item ) => ! this . isOpened ( item . id ! , nextGroups )
471
+ ) || [ ]
472
+ ) ;
433
473
434
474
if ( current && current . id === groupId ) {
435
- nextCurrentGroup = groups [ groupIndex - 1 ] ;
475
+ nextCurrentGroup =
476
+ groups [ groupIndex + 1 ] || groups [ groupIndex - 1 ] ;
436
477
}
437
478
438
- this . setState ( {
439
- groups : nextGroups ,
440
- current : nextCurrentGroup ,
441
- } ) ;
479
+ this . setState (
480
+ {
481
+ groups : nextGroups ,
482
+ current : nextCurrentGroup ,
483
+ } ,
484
+ ( ) => {
485
+ // dispose all models in specific group
486
+ this . disposeModel ( removed ) ;
487
+ }
488
+ ) ;
442
489
}
443
490
}
444
491
0 commit comments