Video Summary and Transcription
MDEdit is a tool that converts Markdown into HTML and provides a what-you-get editor. Progressive web apps offer a comparable user experience on both desktop and mobile devices. The Service Worker allows web apps to remain functional even without an internet connection. The Persistent Storage and File Handling APIs enable web apps to store data and access files on the client's device. Project Fugu provides new APIs, including the Font Access API, to bridge the gap between native apps and web applications.
1. Introduction to MDEdit and Progressive Web Apps
MDEdit is a tool that converts Markdown into HTML and provides a what-you-get editor. It wants to read files, write files, and work offline. It is a Super Web Application, bridging the gap between the browser and native applications. Progressive web apps offer a comparable user experience on both desktop and mobile devices. They should be fast, integrated, reliable, and engaging. The Web App Manifest and the Service Worker are core concepts introduced by browsers to solve these problems.
Hi, everyone. My name is Nico. I am a front-end developer from Switzerland, and here with me is MDEdit. MDEdit is a tool that converts Markdown into HTML, and it then provides a what-you-get editor that lets you, or that helps you, write HTML that will then be converted back to Markdown. In other words, it's a Markdown editor app or Markdown editor website.
I mean, MDEdit is a little bit in an identity crisis, because what is it? Is it a website? Is it an app? Is it a tool that uses HTML, CSS, and JavaScript? But it wants to do so much more. It wants to read files. It wants to write files. It wants to work offline. So it's more of a web app with super powers.
Speaking of super powers, do we have any classic DC comic fans here? Do we? Well, so maybe we are able to help my little friend. Because what is it? Is it a website? Is it an app? Is it a bird? To put it plain, it is a Super Web Application, or at least that's what they would have been called if I had been given the chance to name those things. Unfortunately, or also luckily for everyone else, Alex Russell was way before me, and he was back then working at Google, and he was thinking a lot about how to bridge the gap between the browser and native applications. And he was thinking about websites that you could grant more and more permissions. They would progressively become apps. So he coined the term progressive web apps. And maybe you have already heard a lot about progressive web apps in terms of mobile applications.
However, the web is unique in the sense that it's not tailored to one specific operating system or screen resolution, but it should work universally. Therefore, I would like to focus on some of the capabilities that also allow desktop web applications to have some superpowers. But let's start with some basics.
The underlying question for web apps running both on desktop and mobile is, what problems do they need to solve to offer a truly comparable user experience? First of all, they should be fast, because we don't want to have a loading spinner if you click on an application or on a file. It should be there immediately. It should be integrated, so it should feel like it's part of the operating system, an extension of the operating system. It should be reliable, even if we have no internet connection or bad internet connection, we should be able to use the app. And it should be engaging, so we should be able to re-engage our users, for example, using push notifications. To solve those problems, browsers had to introduce two new core concepts, the Web App Manifest and the Service Worker.
The Service Worker, sorry, the Web App Manifest is basically just a JavaScript, a JSON file that contains information about the application. We, first we need to register the manifest, it's basically one line of HTML pointing to the file, and then the file itself contains information like the title, short name, description, colors, and that's already it. So my browser, in this case, Edge, knows that we now have an installable PWA, and it offers us to install it. There are more and more capable properties that we will look into in this talk.
2. The Service Worker and Network Independence
The Service Worker is a piece of JavaScript that lives in a separate scope and is able to listen to events, interact with the site, and stay active even if the browser is closed. We can register the Service Worker and define its scope. Inside the Service Worker, we have event listeners for Install, Activate, Fetch, and Push events. The Service Worker allows our super web app to remain functional even without an internet connection, as it sits between the website and the internet and can interact with the application storage.
The second big thing is the Service Worker. So first of all, my app is a JavaScript application, so there's a lot of application logic written in JavaScript, which is cool because I really like JavaScript. Then again, as soon as we close the site, as soon as we close the browser, there's just, JavaScript is just dead. There are no things happening inside our app.js anymore, so we can't interact with it anymore.
The Service Worker is now also a piece of JavaScript, but it lives in a separate scope. It's registered between the web app and the browser, and there it is able to listen to events, to interact with the site, even if the browser is closed, so it stays there forever. It's not bound to the lifecycle of our application.
To register the Service Worker, we can call this navigator.serviceworker.register function, points to the Service Worker. It has some optional parameters like the scope, so in our case, our Service Worker controls everything, so our site and all the subfolders as well. We can also create a new Service Worker that controls specific scopes inside our application, so we could have the About Service Worker that only controls everything inside this About folder, for example.
And then, inside the Service Worker, it's just JavaScript. We do have event listeners, so whenever someone visits the page, this Install Event is fired. Then once the installation happened, we have the Activate Event. Then every request goes through the Service Worker with the Fetch Event, and also if someone tries to reach our Service Worker from some server, for example, we do have the Push Event that we can listen to. So far, so good.
But let's get back to our super web app and its superpowers. Let's start with issue number one, Super Web App and the dream of network independence. It's a beautiful day, sun is shining, our super web app tries to request some assets from the server, it makes a request to the server, comes back with the response, everything was fine. But suddenly, the internet connection is gone. Sorry, there we go. Different. The internet connection is gone, and well, Donasaur appears, certain death for all classic web applications. Not so for our super web app, because we do have the Service Worker superpower.
Now the Service Worker sits between the website and the internet, and it can also interact with the application storage. So even if the internet connection is gone, we still have a reliable source to serve our request. How can we use it? So in this case, we have our SVG, we have a fallback SVG image and we want to show the fallback SVG whenever a request to an SVG image fails. First of all, in the install event, we opened the cache, we will then put this fallback SVG into the cache. Then once we have the fetch event, we will first check whether the requested asset is actually an SVG. If that is the case, we do have the event.responseWith, which basically takes over the request. There we can then pass the request to the server.
3. Caching and Data Storage
If an image request fails, we can return the cached image. Workbox.js is a tool that helps with caching and intercepting network requests. We have options like session and local storage for storing data, but for more data, we can use IndexedDB or the Origin Private File System API.
But if it fails, if there is to catch, we can return the image that is already cached. Another example would be where we have a, let's say an offline first image cache. In that case, we want to catch all image requests. We will take over the response. We will then check whether we have that request already in cache. If that's the case, we will just return it right away. So that is just super fast. If not, we will fetch the data from the server. We will then clone the response. We can then cache the response and we will return the response. So next time we will request the same URL, it will be returned directly from cache, which is immediately.
Now there is one tool that helps us with that, that's Workbox.js. It's basically an abstraction on top of the Service Worker and the caches API. There are basically plugins for all kinds of use cases. There are also integrations for all kinds of build systems. And yeah, it just makes it super easy to use the Service Worker cache. The Service Worker cache is amazing because it allows us to cache or to directly intercept network requests on a very low level. But then again, another common problem is that we need data that is maybe stored. We need to store data inside our application logic. So that could be data generated by the application. Could be data from a REST API where we want to have a more structured way to cache those entries. And there we have multiple possibilities. We do have the session and the local storage. Both are simple key value pairs. Session storage is only for one session. Local storage persists over several sessions, but they are both quite limited in size. So we can only store around 5 megabytes. If you have more data to store, we can use, for example, the IndexedDB where we have this low level browser API that allows web applications to store and manipulate large amounts of structured data. We can even do querying and indexing on top of that data. And then we have the Origin Private File System API, which allows us to create, read, and update files in a private file system, which means that it is part of the user's file system, but it's not visible by the user or any other origin than our web application.
4. Persistent Storage and File Handling
The Persistent Storage API allows us to store data for web applications. The amount of data we can store depends on the browser and operating system. The File System Access API enables reading and writing files on the client's device. We can get a file handle through the show open file picker method or from the IndexedDB. Permissions for file handling are session-based and can be upgraded to read-write. The file handling API allows web apps to directly open files.
The other question, how reliable is data stored for a web application? So we do have the Persistent Storage API. It's an API that allows us to request permission to persistently store data for a web application.
The other big question is how much data can we store? The good thing is, at least, it always depends on the browser and the operating system, but at least on Chrome and Edge, on Windows, we can basically store as much data as we have stored, we left on our device. So if you have 500 gigabytes on our device, we can basically use 500 gigabytes of data for our web application.
Yeah, which brings us to our next issue in the series, SuperWebApps Data Dive into the File System ABIS. It has always been possible to read the blob of a file using the file input element, and after that, it was also possible to provide a download link to the file, but that's it. So no further interaction with the file system was possible. The File System Access API tries to change that. With this API, it is now possible to read files or whole directories on the client's device, and furthermore, it's also possible to write changes back directly to that file. So whenever you want to interact with a file, we now need to have a file handle.
There are basically two ways to get the content of a file. In the first scenario, we already have a file, sorry, we don't already have a file handle. So here we use this show open file picker method, which opens a file picker dialogue and allows the user to select one or more files. After that, the user sees this prompt here on the right-hand side asking for permission where we need to confirm that the web app is allowed to handle a file, and one great aspect is that those handles, they are serializable. So we can store them, for example, in the IndexedDB.
In the second scenario, we already have the handle, maybe from the IndexedDB, but permissions are only granted for one session. So once we close the app, we need to request permission again. In this case, I only need to read permission. After that, I am again able to get the file and read the content and we're good to go. After that, we also want to write content back to the file. So first of all, we need to upgrade our permissions. We now need to read write permission. We can then create a writeable, write content to the writeable, close the writeable, and that's already it. It's saved on our file. Simple as that.
Then again, do we really want to open an app, select the file inside the app, and then open the file? It's possible, but not very convenient. When we open a Word document, for example, you just double click on the icon. It opens Word with the document already opened. So why shouldn't we be able to do the same with web apps? Which leads to our third issue, the file handling revolution. The idea of the file handling API is that once a web app is installed, we can use the web app to directly open files.
5. Project Fugu and File Handling
We can use the web app as a default app for a certain file type using the file handling property. The launch queue API allows us to receive incoming files. Project Fugu is a cross-organization project to bridge the gap between native apps and web applications. It provides a list of new APIs, including the local font access API, which allows access to locally installed fonts.
We can then even use the web app as a default app for a certain file type. So when the user double clicks on the file, it will open in the web app. And this is all possible using this new file handling property in the manifest. Here we can define the file types that our app can handle. In this case, we do want to handle Markdown files together with an action that works similar to a form action, basically. It also means that we can use the same web app for different file types. For example, we could also use the same web app for text files as well, with a different or also with the same action.
Inside our application, we can then use the launch queue API to receive an incoming file. So file handling API triggers the action and the launch queue API then consumes the file. And that's already it. It's a pretty simple API for us developers, but it's extremely convenient for the user.
That was a lot of tech content for now, right? Let's get back to our DC superheroes. Does anyone know the name of this iconic trio? That's Trinity. So whenever Superman had a problem that was too big for him alone, he called Wonder Woman and Batman the train forces. In the web land, we don't have Trinity, but we have something even better. We have Project Fugu. Project Fugu is a cross-organization project mostly by Google, Microsoft and Intel to bridge the gap between native apps and web applications. So let's open issue number four, the epic kitchen battle taming the Fugu.
The name of the project is based on the Fugu fish, which is supposed to be a delicacy. I can't judge because I never tried it, but it's also extremely dangerous to prepare. So the core of the project Fugu is a list of new APIs that supposed to bring the web closer to native apps. But we also need to be careful how it's implemented and how we can use it. There are quite a lot of new APIs, for example, APIs that allows us to interact with hardware devices. There are APIs that we have already discussed, like file system access and file handling. And there's a whole bunch of new APIs. And always some of them are an origin trial. Some of them are in development. So you should check the tracker before you use them. But there's one API that was particularly useful for MD edit and that's the local font access API because the API allows us to access the user's locally installed fonts. So as you can see here on the left hand side, we can call the window query fonts, which will then show a prompt to the user asking for permission to access the fonts.
6. Using MD edit and Font Access API
If granted, you will receive an array of font objects. MD edit allows opening and editing markdown files. It can save content directly to files and be installed as an application. The font access API enables changing fonts, and MD edit can be set as the default application for opening Markdown files. Companies like VS Code are already using these APIs.
If granted, you will then receive an array of font objects. This allows me then to create a select box or the user can select a font which sets a custom CSS variable that is responsible for the markdown or the specific editor.
So for now, our heroes scratched the surface of a lot of new superpowers, but let's open issue number five, where the superhero unites all powers for some outstanding demos. First of all, I have MD edit. So there we go. What I do have in here on my local system is I have a markdown file, which I can open with editor. And as you can see, it's basically just some information about React Summit.
What I can do then is I can open that in MD edit, same file from the desktop. There we go. And I can say, for example, hello world. And I can then save content. Yes, I do want to do that. If I now open the app, you can see that it is saved directly on our file. Pretty cool, pretty convenient, but we can go even further. We can now install the application. Takes a couple of seconds. There we go. And now we can see that it's opened directly in the, let's say, the layout that we specified. I can now close it. I can now say, well, let's go here. Open that with MD edit. There we go. And we can now open the file directly with MD edit. I can now also use the font access API to, let's say, change the visivic font to, there you go, something different and so on and so forth. And last but not least, I can also say that I always want to use MD edit to open Markdown files. So whenever you can see that the icon already changed. And when I double click on that, it's open directly in MD edit, in our application. That is pretty cool. Now, in addition to my own experiments, let's close that, there are also big companies that are already using those APIs. For example, VS Code, where we have the whole Visual Studio Code experience directly in the browser.
7. Progressive Web Apps and Cross-platform Solutions
Clipjam and Adobe Invest provide video editing and Photoshop for the web. The need for write once, run everywhere has existed since the beginning of development. Java and Electron had limitations, but Progressive Web Apps offer accessible, integrated, offline solutions that are small compared to cross-platform options. Thank you for your attention!
We have Clipjam, that is a whole video editing platform directly in the browser. And even Adobe Invest, we do have Photoshop for the web. So a lot of the APIs that you've seen or a lot of the features that Photoshop provides are also available in Photoshop web.
To sum it all up, the idea to have an application that you run once and then it runs every, or that you write once and runs everywhere, has been a huge need for developers since the beginning of development, I would say. For a long time, we thought that maybe Java would be the solution. And I think write once and run everywhere was also the slogan of Java at one point, until we figured out that it sucks at creating UIs.
There's also Electron, where we have our browser, or we have the browser engine together with the application, that also means that we will ship the whole browser engine with every application we write. And we have multiple instances of, for example, Chrome installed on our device. Now we try to solve that. But then again, we do need to ship. So we do have the whole detour via the installation process. And now with Progressive Web Apps, we have solutions that are accessible via URL, that is deeply integrated with the OS. It works offline and it's just incredibly small compared to all the cross-platform solutions.
So with that, thank you so much for your attention. My slides are behind that QR code. If you have any questions, I'm happy to answer them in the Discord channel. Well, until next time, I hope you have a great time. And thanks again so much for your attention. Bye.
Comments