This week I played with the File System Access API: this feature allow you to create web apps that can interact with files on the user’s local device. After a user grants a web app access, this API allows them to read or save changes directly to files and folders on the user’s device.

I want to reproduce with Construct 3 a text editor with similar functionality to the one developed by the Google Chrome Labs (text editor). I also followed this guide: The File System Access API: simplifying access to local files.

Of course I also shared the whole thing on GitHub:

In the next days I will publish this article also on Patreon.

Let’s start:

For now, I leave out some “marginal” aspects to using the File System Access API and focus on two modules: manageFiles.js and fileSystemAccess.js. In the last you can find some functions:

  • openFile
  • write
  • saveAs
  • saveFile
  • loadFromFile
  • getNewFileHandle

openFile

For simplicity, I leave out the explanation of error handling. The entry point is window.showOpenFilePicker(). When called, it shows a file picker dialog box, and prompts the user to select a file. After they select a file, the API returns an array of file handles. An optional parameter lets you influence the behavior of the file picker, for example, by allowing the user to select multiple files, or directories, or different file types. Without any option specified, the file picker allows the user to select a single file.

I assign an array of FileSystemFileHandle to Globals.fileHandle. In this case it’s a one-element array that contains the properties and methods needed to interact with the file.

Note: I haven’t implemented yet a method to keep track of all open files, but only one. However, doing so would allow you to implement a list of recent files to use as a shortcut to open the latest files you worked on.

Now from the handle you can access the file itself via

and then you can read its contents.

write

The second function, write, allows you to save text changes directly to the file. To do this you use the FileSystemWritableFileStream interface. Then you can create the stream by calling

Now you can write the contents of the file to the stream.

At the end you can close the file and write the contents to disk: await writable.close().

Caution: Changes are not written to disk until the stream is closed.

saveAs

Everything is simpler from now on. saveAs uses getNewFileHandle() to get the name and location to save the file to. Then you can call write() to… write the file.

saveFile

saveFile is even simpler. If you are editing a file it’s call write. If you are working on a new file, it’s call saveAs.

loadFromFile

Finally loadFromFile reloads the file to the state prior to the last save.

With this I completed the basic structure. However, there is no simple way to integrate all this with our editor. To do this you need a new module: manageFiles.js.

ManageFiles.js

I only focus on two functions, insertText and getText. They both use

This code allows you to access the Construct 3 text box. The first modifies the text contained, the second reads it. This is necessary to allow C3 to correctly display the content of the element.

The following functions do nothing but call those of the FileSystemAccess module by connecting them to the actual editor.

That said, it’s time for links: