1. Introduction
This section is non-normative.
This API enables developers to build powerful apps that interact with other (non-Web) apps on the user’s device via the device’s file system. Prominent examples of applications where users expect this functionality are IDEs, photo and video editors, text editors, and more. After a user grants a web app access, this API allows the app to read or save changes directly to files and folders on the user’s device. Beyond reading and writing files, this API provides the ability to open a directory and enumerate its contents. Additionally, web apps can use this API to store references to files and directories they’ve been given access to, allowing the web apps to later regain access to the same content without requiring the user to select the same file again.
This API is similar to <input type=file>
and <input type=file webkitdirectory>
[entries-api]
in that user interaction happens through file and directory picker dialogs.
Unlike those APIs, this API is currently purely a javascript API, and
does not integrate with forms and/or input elements.
This API extends the API in [FS], which specifies a bucket file system which websites can get access to without having to first prompt the user for access.
2. Files and Directories
2.1. Concepts
A valid suffix code point is a code point that is ASCII alphanumeric, U+002B (+), or U+002E (.).
Note: These code points were chosen to support most pre-existing file formats. The vast
majority of file extensions are purely alphanumeric, but compound extensions (such as
.tar.gz) and extensions such as .c++ for C++ source code are also fairly common,
hence the inclusion of + and . as allowed code points.
2.2. Permissions
The "file-system" powerful feature’s
permission-related algorithms and types are defined as follows:
- permission descriptor type
-
FileSystemPermissionDescriptor, defined as:enum {FileSystemPermissionMode ,"read" };"readwrite" dictionary :FileSystemPermissionDescriptor PermissionDescriptor {required FileSystemHandle ;handle FileSystemPermissionMode = "read"; };mode - permission state constraints
-
To determine permission state constraints for a
FileSystemPermissionDescriptordesc, run these steps:-
Let entry be desc["
handle"]'s entry. -
If entry represents a file system entry in a bucket file system, this descriptor’s permission state must always be "
granted". -
Otherwise, if entry’s parent is not null, this descriptor’s permission state must be equal to the permission state for a descriptor with the same
mode, and ahandlerepresenting entry’s parent. -
Otherwise, if desc["
mode"] is "readwrite":-
Let read state be the permission state for a descriptor with the same
handle, but whosemodeis "read". -
If read state is not "
granted", this descriptor’s permission state must be equal to read state.
-
-
Make these checks no longer associated with an entry. [whatwg/fs Issue #101]
- permission request algorithm
-
Given a
FileSystemPermissionDescriptordesc and aPermissionStatusstatus, run these steps:-
Run the default permission query algorithm on desc and status.
-
Let settings be desc["
handle"]'s relevant settings object. -
Let global be settings’s global object.
-
If global is not a
Window, then throw a "SecurityError"DOMException. -
If global does not have transient activation, then throw a "
SecurityError"DOMException. -
If settings’s origin is not same origin with settings’s top-level origin, then throw a "
SecurityError"DOMException. -
Run the default permission query algorithm on desc and status.
Ideally this user activation requirement would be defined upstream. [WICG/permissions-request Issue #2]
-
FileSystemHandle handle and a FileSystemPermissionMode mode, run these steps:
-
Let desc be a
FileSystemPermissionDescriptor. -
Set desc["
name"] to "file-system". -
Set desc["
handle"] to handle. -
Set desc["
mode"] to mode. -
Return desc’s permission state.
FileSystemHandle handle and a FileSystemPermissionMode mode, run these steps:
-
Let desc be a
FileSystemPermissionDescriptor. -
Set desc["
name"] to "file-system". -
Set desc["
handle"] to handle. -
Set desc["
mode"] to mode. -
Let status be the result of running create a PermissionStatus for desc.
-
Run the permission request algorithm for the "
file-system" feature, given desc and status. -
Return desc’s permission state.
Currently FileSystemPermissionMode can only be
"read" or "readwrite".
In the future we might want to add a "write" mode as well to support write-only
handles. [Issue #119]
2.3. The FileSystemHandle interface
dictionary {FileSystemHandlePermissionDescriptor FileSystemPermissionMode = "read"; }; [mode Exposed =(Window ,Worker ),SecureContext ,Serializable ]partial interface FileSystemHandle {Promise <PermissionState >queryPermission (optional FileSystemHandlePermissionDescriptor = {});descriptor Promise <PermissionState >requestPermission (optional FileSystemHandlePermissionDescriptor = {}); };descriptor
2.3.1. The queryPermission() method
- status = await handle .
queryPermission({mode: "read" })- status = await handle .
queryPermission()- status = (await navigator.
permissions.query({name: "file-system",handle: handle })).state - status = await handle .
-
Queries the current state of the read permission of this handle. If this returns "
prompt" the website will have to callrequestPermission()before any operations on the handle can be done. If this returns "denied" any operations will reject.Usually handles returned by the local file system handle factories will initially return "
granted" for their read permission state, however other than through the user revoking permission, a handle retrieved from IndexedDB is also likely to return "prompt". - status = await handle .
queryPermission({mode: "readwrite" })- status = (await navigator.
permissions.query({name: "file-system",handle: handle,mode: "readwrite" }).state - status = (await navigator.
-
Queries the current state of the write permission of this handle. If this returns "
prompt", attempting to modify the file or directory this handle represents will require user activation and will result in a confirmation prompt being shown to the user. However if the state of the read permission of this handle is also "prompt" the website will need to callrequestPermission(). There is no automatic prompting for read access when attempting to read from a file or directory.
The integration with the permissions API’s query() method is not yet implemented in Chrome.
queryPermission(descriptor) method, when invoked, must run these steps:
-
Let result be a new promise.
-
Run the following steps in parallel:
-
Let state be the result of querying file system permission given this and descriptor["
mode"]. -
Resolve result with state.
-
-
Return result.
2.3.2. The requestPermission() method
- status = await handle .
requestPermission({mode: "read" })- status = await handle .
requestPermission() - status = await handle .
-
If the state of the read permission of this handle is anything other than "
prompt", this will return that state directly. If it is "prompt" however, user activation is needed and this will show a confirmation prompt to the user. The new read permission state is then returned, depending on the user’s response to the prompt. - status = await handle .
requestPermission({mode: "readwrite" })