1 of 16

Desiloing files on the web

Jay Harris

Eric Willigers

BlinkOn 10, April 2019

2 of 16

WebShare

  • Allows any web site to share text, a url and files�
  • Currently available in Canary

3 of 16

WebShare

const data = {

title: "...",

text: "...",

url: "...",

files: [...]

};

navigator.share(data).then(() => {

...

}).catch((err) => {

...

});

4 of 16

WebShare

5 of 16

WebShareTarget

  • Allows web applications to receive shared�text, url and/or files. �
  • Currently available in Canary.�
  • Similar to HTML forms, authors specify a target URL and field names, and method, encoding type. �
  • Incoming shares can be handled by a Service Worker.

6 of 16

WebShareTarget

"share_target": {

"action": "...",

"method": "POST",

"enctype": "multipart/form-data",

"params": {

"files": [

{

"name": "...",

"accept": ["image/*"]

}

]

}

}

7 of 16

WebShareTarget

addEventListener('fetch', (event) => {

if (event.request.method !== 'POST') return;

event.waitUntil(async function () {

const data = await event.request.formData();

...

}());

});

8 of 16

WebShareTarget

9 of 16

WebShare + WebShareTarget

10 of 16

11 of 16

The Manifest

{

"name": "Cool Text Editor",

"file_handler": {

"action": "/handle_files"

"files": [

{

"name": "text",

"accept": [".txt", "text/*"]

}

]

}

}

12 of 16

Handling the request (very early, subject to change)

// Navigation to https://my-file-handler.example/handle_files?text=file-blob:<GUIDish>

const params = new URLSearchParams(window.location.search);

const fileHandles = params

.getAll('text')

.map(f => new FileSystemFileHandle(f));

// TODO: Do stuff with file handles

13 of 16

What is this `launch` event?

Launch events should provide a single place to handle WHERE launches should happen.

14 of 16

It’s going to replace all of those?

well, hopefully not...

15 of 16

Always open things in the existing window

self.addEventListener('launch', event => {

event.waitUntil(async () => {

const allClients = await clients.matchAll();

// If there isn't one available, open a new window.

if (allClients.length === 0) {

clients.openWindow(event.request.url);

event.preventDefault();

return;

}

const client = allClients[0];

client.focus();

event.preventDefault();

}());

});

16 of 16

Questions

Forget diamonds, web standards are forever (so ask away).