 Any sufficiently advanced technology is indistinguishable from magic. Unless you understand it. My name is Thomas Diner. I work in developer relations at Google. And in this talk, I will look at some of the new Fugu APIs and how they improve core user journeys in the Excalibur PWA. So you can take inspiration from these ideas and apply them to your own apps. I want to start this talk with a story. On January 1st, 2020, Christopher Shidow, a software engineer at Facebook, tweeted about a small drawing app he had started to work on. With this tool, you could draw boxes and arrows that feel cartoony and hand-drawn. The next day, you could also draw ellipses and text, as well as select objects and move them around. On January 3, the app had gotten its name, Excalibur. And like with every good site project, buying the domain name was one of Christopher's first acts. By now, you could use colors and export the whole drawing as a PNG. On January 15, Christopher put out a blog post that drew a lot of attention on Twitter, including mine. The post started off with some impressive stats. 12k unique active users, 1.5k stars on GitHub, 26 contributors. For a project that started a mere two weeks ago, that's not bad at all. But a thing that truly sparked my interest was further down in the post. Christopher wrote that he tried something new this time, giving everyone who landed a pull request unconditional commit access. The same day of reading the blog post, I had a pull request up that added file system access API support to Excalibur, fixing a feature request that someone had filed. My pull request was merged a day later, and from there on, I had full commit access. Needless to say, I didn't abuse my power. Nor did anybody else, from the 149 contributors so far. Today, Excalibur is a full-fledged, installable, progressive web app with offline support, a stunning dark mode, and yes, the ability to open and save files thanks to the file system access API. So this marks the end of my How I Came to Excalibur story. But before I dive into some of Excalibur's amazing feature, I have the pleasure to introduce Panayotes. Panayotes Liberides, on the internet simply known as Lippis, is the most prolific contributor to Excalibur. I asked Lippis what motivates him to dedicate so much of his time to Excalibur. Like everyone else, I learned about the project from Christopher's tweet. My first contribution was to add the OpenColor library, the colors that are still part of the Excalibur today. As the project grew and we had quite many requests, my next big contribution was to build a backend for storing drawings so users could share them. But what really drives me to contribute is that whoever tried Excalibur is looking to find excuses to use it again. I fully agree with Lippis. Whoever tried Excalibur is looking to find excuses to use it again. I want to show you now how you can use Excalibur in practice. I'm not a great artist, but the Google I.O. logo is simple enough. So let me give it a try. A box is the I. A line can be the slash. And the O is a circle. I hold down Shift so I get a perfect circle. Let me move the slash a little so it looks better. Now some color for the I and the O. Blue is good. Maybe a different filth style. All solid or crosshatch. Nah, that sure looks good. It's not perfect, but that's the idea of Excalibur. So let me save it. I click the Save icon and enter a file name in the File Saved dialog. In Chrome, I browse it as a positive file system access API. This is not a download, but a true save operation where I can choose the location and name of the file. And where, if I make edits, I can just save them to the same file. Let me change the logo and make the I red. If I now click Save again, my modifications are saved to the same file as before. As a proof, let me clear the canvas and reopen the file. As you can see, the modified red-blue logo is there again. On browsers that currently don't support the file system access API, each save operation is in download. So when I make changes, I end up with multiple files with an incrementing number in the file name that fill up my downloads folder, but despite this downside, I can still save the file. So what's the secret? How can opening and saving work on different browsers that may or may not support the file system access API? Opening a file in Excalidor happens in a function called LoadFromChasing which in turn calls a function FileOpen. The FileOpen function comes from a small library I wrote called BrowserFSAccess that we use in Excalidor. This library provides file system access through the file system access API with a legacy folder so it can be used in any browser. Let me first show you the implementation of when the API is supported. After negotiating the accepted mine types and file extendance, the central piece is calling the FileSystemAccessAPI function ShowOpenFilePicker. This function returns an array of files or a single file dependent on whether multiple files are selected. All that's left then is to put the file handle on the file object so it can be retrieved again. The for black implementation relies on an input element of type file. After the two be accepted mine types and extensions negotiation, the next step is to programmatically click the input element so the file open dialog shows. On change, that is when the user has selected one or multiple files, the promise resolves. Now to saving. In Excalidor, saving happens in a function called SaveAsJSON. It first serializes the Excalidor elements array to JSON, converts the JSON to a blob and then calls a function called FileSave. This function is likewise provided by the browser FSAccessLibrary. Again, let me first look at the implementation for browsers with FileSystemAccess API support. The first couple of lines look a little involved, but all they do is negotiate the mine types and file extensions. When I've saved before and already have a file handle, no save dialog needs to be shown. But if this is the first save, a file dialog gets displayed and the app gets a file handle back for future use. The rest is then just writing to the file which happens through a valuable stream. If I decide to ignore an already existing file handle, I can implement a SaveAs feature to create a new file based on an existing file. To show this, let me open an existing file make some modifications and then not override the existing file but create a new file by using the SaveAs feature to leave the original file intact. The implementation for browsers that don't support the FileSystemAccess API is short since all it does is create an anchor element with the download attribute whose value is the desired file name and a blob URL as its href attribute value. The anchor element then gets clicked programmatically. To prevent memory leaks, the blob URL needs to be removed after use. As this is just a download, no file save dialog gets shown ever and all files land in the default downloads folder. One of my favorite system integrations on desktop is DragonDrop. In Excalibur, when a drop in Excalibur file onto the application, it opens right away and I can start editing. On browsers that support the FileSystemAccess API, I can then even immediately save my changes. No need to go through a file save dialog since the required file handle has been obtained from the DragonDrop operation. The secret for making this happen is by calling getAsFileSystemHandle on the data transfer item when the FileSystemAccess API is supported. I then pass this file handle to load from blob, which you may remember from a couple of slides ago. So many things you can do with files. Opening, saving, over-saving, dragging, dropping. My colleague Pete and I have documented all these tricks and more in our article at web.dev.slash FileSystemAccess. So you can catch up in case all this meant a little too fast. Another system integration currently in Android, Chrome OS and Windows is through the web share target API. Here I am in the files app and my downloads folder. I can see two files, one of them with a nondescript name untitled and a timestamp. To check what it contains, I click on the three dots, then share and one of the options that appears is Excalibur. When I tap the icon, I can then see that the file just contains the IO logo again. One thing you can do with files that I haven't talked about yet is double-click them. What typically happens when you double-click a file is that the app that's associated with a file's MIME type opens. For example, for DogX, this would be Microsoft Word. Excalibur used to have an Electron version of the app that supported such file type associations, so when you double-click an Excalibur file, the Excalibur Electron app would open. Lippis, we have already met before, was both the creator and the deprecator of the Excalibur Electron app. I asked him why he felt it was possible to deprecate the Electron version. People have been asking for an Electron app since the beginning, mainly because they wanted to open files by double-clicking. We also intend to put the app in the app stores. In parallel, someone suggested creating a PWA instead, so we just did both. Luckily, we introduced a project for Google APIs like File System Access, Clipboard Access, File Handling and more. With the sole click, you can install the app on your desktop or mobile without the extra weight of Electron. It's an easy decision to deprecate the Electron version, concentrate just on the web app and make it the best possible PWA. On top, we are now able to publish PWS in the Play Store and the Microsoft Store. That's huge. So, I could say Excalibur Electron was not deprecated because Electron is bad, not at all, but because the web has become good enough. I like this. When I say the web has become good enough, it's because it features like the upcoming File Handling. This is a regular MacOS Big Sur installation. Now check out what happens when I right-click an Excalibur file. I can choose to open it with Excalibur, to install PWA. Of course, double-clicking would work, too. It's just less dramatic to demonstrate in a screencast. So, how does this work? The first step is to make the file types my application can handle known to the operating system. I do this in a new field called File Handlers in the Web App Manifest. Its value is an array of objects with an action and an accept property. The action determines the URL path the operating system launches your app. An accept object are key value pairs of mine types and the associated file extensions. The next step is to handle the file when the application launches. This happens in a launch queue interface where you need to set a consumer by calling well setConsumer. The parameter to this function is an asynchronous function that receives the launch parents. This launch parents object has a field called files that gets me an array that I still work with. I only care for the first one and from this file handle I get a block that will then pass to our old friend loadFromBlock. Again, if this went too fast you can read more about the file handling API in my article at web.dev slash file handling. You can enable file handling by setting the experimental web platform features flag. It's scheduled to land in Chrome later this year. Another cool feature of Excalibur is the clipboard integration. I can copy my entire drawing into the clipboard maybe adding a watermark if I feel like and then paste it into another app. This is a web version of the Windows 95 paid app by the way. The way this works is surprisingly simple. All I need is to canvas as a block which is then right onto the clipboard by passing a one element array with a clipboard item with a block to the navigator clipboard write function. For more information on what you can do with the clipboard API see Jason's in my article at web.dev slash async clipboard. Did you know that Excalibur also has a collaborative mode? Different people can work together on the same document. To start a new session I click on the live collaboration button and then start a session. I can share the session URL with my collaborators easily thanks to the web share API that Excalibur has integrated. I've simulated a collaboration session locally by working on the Google IO logo on my Pixelbook, my Pixel 3a phone and my iPad Pro. You can see the changes I make on one device are reflected on all other devices. I can even see all curses move around. The Pixelbook's cursor moves steadily since it's controlled by a trackpad. But the Pixel 3a phone's cursor and the iPad Pro's tablet cursor jump around since I control these devices by tapping with my finger. To improve the real-time collaboration experience there's even an idle detection system running. The cursor of the iPad Pro shows a green dot when I use it. The dot turns black when I switch to a different browser tab or app. And when I index Scalibur app by just not doing anything, the cursor shows me as idle symbolized by the three Zs. Having readers of our publications might be inclined to think that idle detection is realized through the idle detection API, an early-stage proposal that's been worked on in the context of Project Fugu. Spoiler alert, it's not. When we had an implementation based on this API in Excalibur in the end we decided to go for a more traditional approach based on measuring point movement and page visibility. We found feedback on why the idle detection API wasn't solving the use-case we had. All Project Fugu APIs are being developed in the open so everyone can chime in and have their voice heard. Talking of which, I asked Lippis one last question regarding what he thinks is missing from the web platform that holds back Excalibur. The file system access API is great, but you know what? Most files that I care about these days live in my draw box or Google Drive, not on my hard disk. I wish the file system access API would include an abstraction layer for remote file system providers like draw box or Google to integrate with and the developers could code against. Users could then relax and note that their files are safe with the cloud provided they trust. I fully agree with Lippis. I live in the cloud too. Here's hoping that this will be implemented soon. Wow, we've seen a lot of really great API integrations in Excalibur. File system, file handling, clipboard, web share and web share target. But here is one more thing. Up until now, I could only ever edit one document at a given time. Not anymore. Please enjoy for the first time an early version of tapped application mode in Excalibur. This is how it looks like. I have an existing file open and installed Excalibur PWA that's running in standalone mode. Now, I open a new tab in standalone window. This is not a regular browser tab, but a PWA tab. In this new tab, I can then open a secondary file and work on them independently from the same app window. Tapped application mode is in its early stages and not everything is set in stone. If you're interested, be sure to read up on the current status of this feature in my article at web.dev slash tap application mode. To stay in the loop on this and other features, be sure to watch our Fuga API tracker. We're super excited to push the web forward and allow you to do more on the web platform. Here's to an ever-improving Excalibur and here's to all the amazing applications that you will build. Go start creating at Excalibur.com. I can't wait to see some of the APIs that I've shown today pop up in your apps. My name is Tom. You can find me as Tomiak on Twitter and the Internet in general. Thank you very much for watching and enjoy the rest of Google I.O.