第 1 页,共 25 页

Progressive Web Apps

Capable

第 2 页,共 25 页

The Powerful Web

第 3 页,共 25 页

What can you do on the web today that you couldn’t 3 years ago?

第 4 页,共 25 页

第 5 页,共 25 页

Web Capabilities Project (Fugu)

Make web apps as capable as Android, iOS, or desktop apps by exposing their capabilities to the web while maintaining the web’s core tenets of security, privacy, and trust.

第 6 页,共 25 页

Track Capabilities

goo.gle/fugu-api-tracker

第 7 页,共 25 页

Request a Capability

webwewant.fyi

第 8 页,共 25 页

Trying Upcoming Features

第 9 页,共 25 页

Origin Trials

talks.page.link/origin-trials

第 10 页,共 25 页

Enabling an�Origin Trial

  • Choose an Origin Trial

第 11 页,共 25 页

Enabling an�Origin Trial

  • Choose an Origin Trial
  • Register a Domain

第 12 页,共 25 页

Enabling an�Origin Trial

  • Choose an Origin Trial
  • Register a Domain
  • Get a Token

第 13 页,共 25 页

Enabling an�Origin Trial

  • Choose an Origin Trial
  • Register a Domain
  • Get a Token
  • Add Token to HTML <head>

<head>

<!-- ... -->

<!-- Origin Trial Meta Tag -->

<meta http-equiv="origin-trial" content="ApZNhqyvruqAWlyPv…dHJ1ZX0=" />

<!-- ... -->

</head>

第 14 页,共 25 页

Empowering Your PWA

第 15 页,共 25 页

Empowering your PWA - File System Access

  • Open files and folders directly
  • Save changes back to your files
  • Make new files and folders

第 16 页,共 25 页

File System Access - Opening a File

// Have the user select a file

const [ handler ] = await window.showOpenFilePicker();

// Get the File object from the handler

const file = await handler.getFile();

// Also available, slice(), stream(), arrayBuffer()

const content = await file.text();

第 17 页,共 25 页

File System Access - Saving Changes

// Make a writable stream from the handler

const writable = await handler.createWritable();

// Write the contents of the file to the stream.

await writable.write(contents);

// Close the file and write the contents to disk.

await writable.close();

第 18 页,共 25 页

Empowering your PWA - File Handling API

  • Register as a file handler
  • Open files directly into your PWA

第 19 页,共 25 页

File Handling - Receiving Files

launchQueue.setConsumer((launchParams) => {

// Nothing to do when the queue is empty.

if (!launchParams.files.length) return;

for (const handler of launchParams.files) {

// Handle the file.

}

});

第 20 页,共 25 页

Empowering your PWA - Multi-Screen Window Placement

  • Open a presentation on an external monitor
  • Restore an opened window’s position on the screen it was on
  • Favor screens that support touch

第 21 页,共 25 页

Multi-Screen - Getting Screen Info

// Request an interface with a FrozenArray of live Screen-inheriting objects.

const screensInterface = await window.getScreens();

screensInterface.screens[0].isPrimary; // e.g. true

screensInterface.screens[0].isInternal; // e.g. true

screensInterface.screens[0].pointerTypes; // e.g. ["touch"]

screensInterface.screens[0].label; // e.g. 'Samsung Electric Company 28"'

// Access the live object corresponding to the current `window.screen`.

// The object is updated on cross-screen window placements or device changes.

screensInterface.currentScreen;

screensInterface.addEventListener('change', function() {

// NOTE: Does not fire on changes to attributes of individual Screens.

const screenCount = screensInterface.screens.length;

const currentScreen screensInterface.currentScreen.id;

});

第 22 页,共 25 页

Empowering your PWA - Screen Wake Lock

  • Stop your screen from falling asleep!

第 23 页,共 25 页

Screen Wake Lock

// Request a screen wake lock

const wakeLock = await navigator.wakeLock.request();

// Listen for wake lock release

wakeLock.addEventListener('release', () => {

console.log(`Screen Wake Lock released: ${wakeLock.released}`);

});

// Manually release the wake lock

wakeLock.release();

第 24 页,共 25 页

Try It Out - 45 Minutes

https://workshops.page.link/pwa05--empowering-your-pwa

第 25 页,共 25 页

wakeLock.release();