@@ -12,7 +12,7 @@ import { DOMUtils, showErrorMessage } from '@jupyterlab/apputils';
12
12
13
13
import { JupyterFrontEnd } from '@jupyterlab/application' ;
14
14
15
- import { Contents , ContentsManager } from '@jupyterlab/services' ;
15
+ import { Contents } from '@jupyterlab/services' ;
16
16
17
17
import { DocumentRegistry } from '@jupyterlab/docregistry' ;
18
18
@@ -85,21 +85,6 @@ export namespace DirTreeListing {
85
85
}
86
86
}
87
87
88
- /**
89
- * The namespace for the `FilterFileTreeBrowserModel` class statics.
90
- */
91
- export namespace FilterFileTreeBrowserModel {
92
- /**
93
- * An options object for initializing a file tree listing widget.
94
- */
95
- export interface IOptions extends FilterFileBrowserModel . IOptions {
96
- /**
97
- * The JupyterFrontEnd app.
98
- */
99
- app : JupyterFrontEnd ;
100
- }
101
- }
102
-
103
88
/**
104
89
* The namespace for the `FileTreeBrowser` class statics.
105
90
*/
@@ -161,7 +146,7 @@ export class FileTreeRenderer extends DirListing.Renderer {
161
146
) : void {
162
147
super . updateItemNode ( node , model , fileType , translator , hiddenColumns ) ;
163
148
164
- if ( model . type === 'directory' && this . model . isOpen ( model ) ) {
149
+ if ( model . type === 'directory' && this . model . isOpen ( model . path ) ) {
165
150
const iconContainer = DOMUtils . findElement (
166
151
node ,
167
152
'jp-DirListing-itemIcon'
@@ -222,26 +207,6 @@ export class DirTreeListing extends DirListing {
222
207
return this . _model ;
223
208
}
224
209
225
- protected async handleFileSelect ( event : MouseEvent ) : Promise < void > {
226
- super . handleFileSelect ( event ) ;
227
- const entry = this . modelForClick ( event ) ;
228
-
229
- if ( entry ) {
230
- if ( entry . type === 'directory' ) {
231
- this . model . path = '/' + entry . path ;
232
-
233
- if (
234
- this . _singleClickToUnfold &&
235
- Object . keys ( this . selection ) . length === 1
236
- ) {
237
- this . model . toggle ( entry . path ) ;
238
- }
239
- } else {
240
- this . model . path = '/' + PathExt . dirname ( entry . path ) ;
241
- }
242
- }
243
- }
244
-
245
210
private async _eventDblClick ( event : MouseEvent ) : Promise < void > {
246
211
const entry = this . modelForClick ( event ) ;
247
212
@@ -389,24 +354,56 @@ export class DirTreeListing extends DirListing {
389
354
case 'lm-drop' :
390
355
this . _eventDrop ( event as IDragEvent ) ;
391
356
break ;
357
+ case 'mousedown' :
358
+ super . handleEvent ( event ) ;
359
+ this . _changeModelPath ( event as MouseEvent ) ;
360
+ break ;
392
361
default :
393
362
super . handleEvent ( event ) ;
394
363
break ;
395
364
}
396
365
}
397
366
367
+ /**
368
+ * Change the model path on each 'mousedown' event
369
+ *
370
+ * Note: This allow to change the path to the root when the user
371
+ * is clicking on an empty space.
372
+ */
373
+ private _changeModelPath ( event : MouseEvent ) : void {
374
+ const entry = this . modelForClick ( event ) ;
375
+
376
+ if ( entry ) {
377
+ if ( entry . type === 'directory' ) {
378
+ this . model . path = '/' + entry . path ;
379
+
380
+ if (
381
+ this . _singleClickToUnfold &&
382
+ ( event . button === 0 || // State toggled on main button
383
+ ( event . button === 2 && ! this . model . isOpen ( entry . path ) ) || // State toggled on right click if folder is closed
384
+ event . type === 'click' ) // State toggled on click and double click
385
+ ) {
386
+ this . model . toggle ( entry . path ) ;
387
+ }
388
+ } else {
389
+ this . model . path = '/' + PathExt . dirname ( entry . path ) ;
390
+ }
391
+ } else {
392
+ this . model . path = this . model . rootPath ;
393
+ }
394
+ }
395
+
398
396
private _singleClickToUnfold = true ;
399
397
}
400
398
401
399
/**
402
400
* Filetree browser model with optional filter on element.
403
401
*/
404
402
export class FilterFileTreeBrowserModel extends FilterFileBrowserModel {
405
- constructor ( options : FilterFileTreeBrowserModel . IOptions ) {
403
+ constructor ( options : FilterFileBrowserModel . IOptions ) {
406
404
super ( options ) ;
407
405
408
- this . app = options . app ;
409
- this . contentManager = this . app . serviceManager . contents ;
406
+ this . contentManager = this . manager . services . contents ;
410
407
this . basePath = '.' ;
411
408
412
409
this . _savedState = options . state || null ;
@@ -523,15 +520,15 @@ export class FilterFileTreeBrowserModel extends FilterFileBrowserModel {
523
520
}
524
521
525
522
/**
526
- * Check whether a directory entry is open or not.
523
+ * Check whether a directory path is opened or not.
527
524
*
528
- * @param model - The given entry.
525
+ * @param path - The given path
529
526
*
530
- * @returns Whether the directory is open or not.
527
+ * @returns Whether the directory is opened or not.
531
528
*
532
529
*/
533
- isOpen ( model : Contents . IModel ) : boolean {
534
- return ! ! this . openState [ model . path ] ;
530
+ isOpen ( path : string ) : boolean {
531
+ return ! ! this . openState [ path ] ;
535
532
}
536
533
537
534
private async fetchContent (
@@ -555,7 +552,7 @@ export class FilterFileTreeBrowserModel extends FilterFileBrowserModel {
555
552
556
553
const isOpen =
557
554
( pathToUpdate && pathToUpdate . startsWith ( '/' + entry . path ) ) ||
558
- this . isOpen ( entry ) ;
555
+ this . isOpen ( entry . path ) ;
559
556
560
557
if ( isOpen ) {
561
558
const subEntryContent = await this . fetchContent (
@@ -602,8 +599,7 @@ export class FilterFileTreeBrowserModel extends FilterFileBrowserModel {
602
599
private _stateKey : string | null = null ;
603
600
private _path = '.' ;
604
601
private basePath : string ;
605
- private contentManager : ContentsManager ;
606
- private app : JupyterFrontEnd ;
602
+ private contentManager : Contents . IManager ;
607
603
private openState : { [ path : string ] : boolean } = { } ;
608
604
}
609
605
0 commit comments