diff --git a/index.bs b/index.bs index 267287d..8ac640e 100644 --- a/index.bs +++ b/index.bs @@ -432,6 +432,10 @@ interface FileSystemFileHandle : FileSystemHandle { Promise createWritable(optional FileSystemCreateWritableOptions options = {}); [Exposed=DedicatedWorker] Promise createSyncAccessHandle(); + + Promise move(USVString newEntryName); + Promise move(FileSystemDirectoryHandle destinationDirectory); + Promise move(FileSystemDirectoryHandle destinationDirectory, USVString newEntryName); }; @@ -662,6 +666,241 @@ The createSyncAccessHandle() method s +### The {{FileSystemFileHandle/move(destinationDirectory, newEntryName)|move()}} method ### {#api-filesystemhandle-move} + +
+ : await fileHhandle| . {{FileSystemFileHandle/move(newEntryName)|move}}({ {{USVString}}: |newEntryName|}) + :: Renames the [=file system entry=] [=locate an entry|locatable=] by + |fileHandle|'s [=FileSystemHandle/locator=] to |newEntryName|. + + : await |fileHandle| . {{FileSystemFileHandle/move(destinationDirectory)|move}}({ {{FileSystemDirectoryHandle}}: |destinationDirectory|}) + :: Moves the [=file system entry=] [=locate an entry|locatable=] by + |fileHandle|'s [=FileSystemHandle/locator=] to the [=directory entry=] + [=locate an entry|locatable=] by |destinationDirectory|'s + [=FileSystemHandle/locator=], while keeping its existing name. + + If the [=file system locator/root|roots=] of the respective + [=FileSystemHandle/locator|locators=] of |destinationDirectory| and + |fileHandle| are not the same, this operation might abort or fail + non-atomically. + + : await |fileHandle| . {{FileSystemFileHandle/move(destinationDirectory, newEntryName)|move}}({ {{FileSystemDirectoryHandle}}: |destinationDirectory|, {{USVString}}: |newEntryName|}) + :: Moves the [=file system entry=] [=locate an entry|locatable=] by + |fileHandle|'s [=FileSystemHandle/locator=] to the [=directory entry=] + [=locate an entry|locatable=] by |destinationDirectory|'s + [=FileSystemHandle/locator=], as well as renaming to |newEntryName|. + + If the [=file system locator/root|roots=] of the respective + [=FileSystemHandle/locator|locators=] of |destinationDirectory| and + |fileHandle| are not the same, this operation might abort or fail + non-atomically. +
+ +
+The move(|destinationDirectory|) +method steps are to [=FileSystemFileHandle/move=] [=this=] +given [=this=]'s {{FileSystemHandle/name}} and |destinationDirectory|. + +
+ +
+The move(|newEntryName|) +method steps are to [=FileSystemFileHandle/move=] [=this=] +given |newEntryName|. + +
+ +
+The move(|destinationDirectory|, |newEntryName|) +method steps are to [=FileSystemFileHandle/move=] [=this=] +given |newEntryName| and |destinationDirectory|. + +
+ +
+ +To move a {{FileSystemFileHandle}} |handle| +given a {{USVString}} |newEntryName| and an optional +{{FileSystemDirectoryHandle}} |destinationDirectory|: + +1. Let |result| be [=a new promise=]. +1. Let |locator| be |handle|'s [=FileSystemHandle/locator=]. +1. Let |global| be |handle|'s [=relevant global object=]. +1. Let |isInABucketFileSystem| be true if + |handle| [=FileSystemHandle/is in a bucket file system=]; + otherwise false. +1. [=Enqueue the following steps=] to the [=file system queue=]: + 1. If |newEntryName| is not a [=valid file name=], + [=queue a storage task=] with |global| to [=/reject=] |result| + with a {{TypeError}} and abort these steps. + + 1. Let |entry| be the result of [=locating an entry=] given |locator|. + 1. Let |accessResult| be the result of running |entry|'s + [=file system entry/request access=] given "`readwrite`". + 1. If |accessResult|'s [=file system access result/permission state=] + is not "{{PermissionState/granted}}", [=queue a storage task=] with + |global| to [=/reject=] |result| with a {{DOMException}} of + |accessResult|'s [=file system access result/error name=] and + abort these steps. + + 1. If |destinationDirectory| was given: + 1. Let |destinationDirectoryLocator| be + |destinationDirectory|'s [=FileSystemHandle/locator=]. + 1. Let |destinationDirectoryEntry| be the result of [=locating an entry=] + given |destinationDirectoryLocator|. + + 1. Let |destinationDirectoryAccessResult| be the result of running + |destinationDirectoryEntry|'s + [=file system entry/request access=] given "`readwrite`". + 1. If |destinationDirectoryAccessResult|'s + [=file system access result/permission state=] + is not "{{PermissionState/granted}}", [=queue a storage task=] with + |global| to [=/reject=] |result| with a {{DOMException}} of + |accessResult|'s [=file system access result/error name=] and + abort these steps. + + 1. If |destinationDirectoryLocator|'s [=file system locator/root=] is not + |locator|'s [=file system locator/root=], [=queue a storage task=] with + |global| to [=/reject=] |result| with an + "{{NotSupportedError}}" {{DOMException}} and abort these steps. + + Issue(114): Decide which moves across file systems, if any, should be + supported, or if this should be left up to individual user-agent + implementations. + + 1. Let |destinationPath| be the result of [=list/clone|cloning=] + |destinationDirectoryLocator|'s [=file system locator/path=] and + [=list/append|appending=] |newEntryName|. + 1. Otherwise: + 1. Let |destinationPath| be the result of [=list/clone|cloning=] + |locator|'s [=file system locator/path=], [=list/remove|removing=] + the last [=list/item=], and [=list/append|appending=] |newEntryName|. + + 1. Let |destinationLocator| be a [=/file system locator=] whose + [=file system locator/kind=] is |locator|'s [=file system locator/kind=], + [=file system locator/root=] is |locator|'s [=file system locator/root=], and + [=file system locator/path=] is |destinationPath|. + + 1. Let |destinationEntry| be the result of [=locating an entry=] + given |destinationLocator|. + + 1. If |destinationDirectory| was not given and + |destinationLocator| is not [=the same entry as=] |locator|: + 1. Let |destinationAccessResult| be the result of running + |destinationEntry|'s [=file system entry/request access=] + given "`readwrite`". + + Issue(101): Make sure this still makes sense once access check algorithms + are no longer associated with an entry. + 1. Otherwise: + 1. Let |destinationAccessResult| be |destinationDirectoryAccessResult|. + + 1. If |destinationAccessResult|'s + [=file system access result/permission state=] is not + "{{PermissionState/granted}}": + 1. If |destinationEntry| is not null, [=queue a storage task=] with + |global| to [=/reject=] |result| with a {{DOMException}} of + |destinationAccessResult|'s [=file system access result/error name=] and + abort these steps. + + Note: This prevents overwriting an existing file or directory which the + website does not have access to. To prevent overwriting a file which + the site can access, use of the + Web Locks API is encouraged. + + Issue(46): Make it easier to generate a uniquely-identifying string for + a {{FileSystemHandle}}. + + 1. Let |settingsGlobal| be |handle|'s [=relevant settings object=]'s + [=environment settings object/global object=]. + 1. If |settingsGlobal| does not have [=transient activation=], + [=queue a storage task=] with |global| to [=/reject=] |result| + with a "{{NotAllowedError}}" {{DOMException}}. + + 1. If |entry| is null, [=queue a storage task=] with |global| to [=/reject=] + |result| with a "{{NotFoundError}}" {{DOMException}} and abort these steps. + 1. If |destinationDirectory| was given and |destinationDirectoryEntry| + is null, [=queue a storage task=] with |global| to [=/reject=] |result| + with a "{{NotFoundError}}" {{DOMException}} and abort these steps. + + 1. Let |lockResult| be the result of [=file entry/lock/take|taking a lock=] + with "`exclusive`" on |entry|. + 1. Let |destinationLockResult| be "`not taken`". + + 1. If |destinationEntry| is not null: + 1. Set |destinationLockResult| to the result of + [=file entry/lock/take|taking a lock=] with "`exclusive`" + on |destinationEntry|. + + Issue: Consider whether it should be possible to lock a + [=/file system entry=] which does not (yet) exist. + + 1. [=Queue a storage task=] with |global| to run these steps: + 1. If |lockResult| is "`failure`", [=/reject=] |result| with a + "{{NoModificationAllowedError}}" {{DOMException}} and abort these steps. + 1. If |destinationLockResult| is "`failure`", [=/reject=] |result| with a + "{{NoModificationAllowedError}}" {{DOMException}} and abort these steps. + + 1. If |destinationLocator| is [=the same entry as=] |locator|, + [=enqueue the following steps=] to the [=file system queue=]: + 1. [=file entry/lock/release|Release the lock=] on |entry|. + 1. [=Queue a storage task=] with |global| to + [=/resolve=] |result| with `undefined` and abort these steps. + + 1. If |isInABucketFileSystem| is false, run [=implementation-defined=] + malware scans and safe browsing checks. If these checks fail, [=/reject=] + |result| with an "{{AbortError}}" {{DOMException}} and abort these steps. + + 1. Let |sourceQueryAccess| be |entry|'s [=file system entry/query access=]. + 1. Let |sourceRequestAccess| be |entry|'s [=file system entry/request access=]. + + 1. If |destinationDirectory| was given: + 1. [=set/Append=] |entry| to |destinationDirectoryEntry|'s + [=directory entry/children=]. + + 1. Attempt to move |entry| to |destinationEntry| in the underlying file + system. If that throws an exception, [=/reject=] |result| with that + exception and abort these steps. + + Note: In some cases, moving a file or directory can fail non-atomically. + A file move might result in a partially-written |destinationEntry|. + A directory move might result in only some files or sub-folders being + copied to |destinationEntry|, and some containing files might themselves + fail to be moved atomically. In both cases, |entry| will only be removed + from the underlying file system if all contents were successfully moved + to |destinationEntry|. + + 1. If |destinationDirectory| was given: + 1. If |entry|'s [=file system entry/parent=] is not null, + [=set/remove=] |entry| from |entry|'s [=file system entry/parent=]'s + [=directory entry/children=]. + + 1. Set |handle|'s [=FileSystemHandle/locator=] to |destinationLocator|. + + Note: This does not update other {{FileSystemHandle}}s with the same + [=FileSystemHandle/locator=]. Each of these handles will presumably no + longer [=locate an entry=], unless a new entry is created at the respective + location. + + 1. Set |destinationEntry|'s [=file system entry/query access=] to + |sourceQueryAccess|. + 1. Set |destinationEntry|'s [=file system entry/request access=] to + |sourceRequestAccess|. + + Issue(101): Make sure this still makes sense once access check + algorithms are no longer associated with an entry. + + 1. [=Enqueue the following steps=] to the [=file system queue=]: + 1. [=file entry/lock/release|Release the lock=] on |entry|. + 1. If |destinationLockResult| is "`success`", + [=file entry/lock/release|release the lock=] on |destinationEntry|. + 1. [=Queue a storage task=] with |global| to + [=/resolve=] |result| with `undefined`. + +1. Return |result|. + +
+ ## The {{FileSystemDirectoryHandle}} interface ## {#api-filesystemdirectoryhandle}