@@ -199,20 +199,7 @@ export class FileSystemDrive implements Contents.IDrive {
199
199
200
200
async rename ( oldPath : string , newPath : string ) : Promise < Contents . IModel > {
201
201
// Best effort, we are lacking proper APIs for renaming
202
- const toCopy = await this . get ( oldPath ) ;
203
- const newName = PathExt . basename ( newPath ) ;
204
-
205
- const copy : Partial < Contents . IModel > = {
206
- name : newName ,
207
- path : newPath ,
208
- content : toCopy . content ,
209
- format : toCopy . format ,
210
- mimetype : toCopy . mimetype ,
211
- type : toCopy . type ,
212
- writable : toCopy . writable
213
- } ;
214
-
215
- await this . save ( newPath , copy ) ;
202
+ await this . doCopy ( oldPath , newPath ) ;
216
203
217
204
await this . delete ( oldPath ) ;
218
205
@@ -272,17 +259,7 @@ export class FileSystemDrive implements Contents.IDrive {
272
259
273
260
const newPath = PathExt . join ( toLocalDir , newName ) ;
274
261
275
- const copy : Partial < Contents . IModel > = {
276
- name : newName ,
277
- path : newPath ,
278
- content : toCopy . content ,
279
- format : toCopy . format ,
280
- mimetype : toCopy . mimetype ,
281
- type : toCopy . type ,
282
- writable : toCopy . writable
283
- } ;
284
-
285
- await this . save ( newPath , copy ) ;
262
+ await this . doCopy ( path , newPath ) ;
286
263
287
264
return this . get ( newPath ) ;
288
265
}
@@ -321,7 +298,6 @@ export class FileSystemDrive implements Contents.IDrive {
321
298
}
322
299
323
300
let parentHandle = root ;
324
- // If saving a file that is not under root, we need the right directory handle
325
301
for ( const subPath of path . split ( '/' ) . slice ( 0 , - 1 ) ) {
326
302
parentHandle = await parentHandle . getDirectoryHandle ( subPath ) ;
327
303
}
@@ -396,6 +372,48 @@ export class FileSystemDrive implements Contents.IDrive {
396
372
} ;
397
373
}
398
374
375
+ private async doCopy ( oldPath : string , newPath : string ) : Promise < void > {
376
+ // Best effort, we are lacking proper APIs for copying
377
+ const oldParentHandle = await this . getParentHandle ( oldPath ) ;
378
+
379
+ const oldLocalPath = PathExt . basename ( oldPath ) ;
380
+
381
+ let oldHandle : FileSystemDirectoryHandle | FileSystemFileHandle ;
382
+
383
+ if ( oldLocalPath ) {
384
+ oldHandle = await this . getHandle ( oldParentHandle , oldLocalPath ) ;
385
+ } else {
386
+ oldHandle = oldParentHandle ;
387
+ }
388
+
389
+ const newParentHandle = await this . getParentHandle ( newPath ) ;
390
+
391
+ const newLocalPath = PathExt . basename ( newPath ) ;
392
+
393
+ if ( oldHandle . kind === 'directory' ) {
394
+ // If it's a directory, create directory, then doCopy for the directory content
395
+ await newParentHandle . getDirectoryHandle ( newLocalPath , { create : true } ) ;
396
+
397
+ for await ( const content of oldHandle . values ( ) ) {
398
+ await this . doCopy (
399
+ PathExt . join ( oldPath , content . name ) ,
400
+ PathExt . join ( newPath , content . name )
401
+ ) ;
402
+ }
403
+ } else {
404
+ // If it's a file, copy the file content
405
+ const newFileHandle = await newParentHandle . getFileHandle ( newLocalPath , {
406
+ create : true
407
+ } ) ;
408
+
409
+ const writable = await newFileHandle . createWritable ( { } ) ;
410
+ const file = await oldHandle . getFile ( ) ;
411
+ const data = await file . arrayBuffer ( ) ;
412
+ writable . write ( data ) ;
413
+ await writable . close ( ) ;
414
+ }
415
+ }
416
+
399
417
private _isDisposed = false ;
400
418
private _fileChanged = new Signal < Contents . IDrive , Contents . IChangedArgs > (
401
419
this
0 commit comments