Slides
Slides
A TOUR OF
WEB
CAPABILITIES
MAXIMILIANO FIRTMAN
MAXIMILIANO FIRTMAN
MOBILE+WEB DEVELOPER
HTML since 1996
JavaScript since 1998
AUTHOR
Authored 13 books and +70 courses
Published +150 webapps
@FIRT﹒FIRT.DEV
web.dev/learn/pwa
3
What we'll cover
13
Basic Capabilities
(that we won't cover today)
Core Fetch
WebAssembly
WebSocket
WebRTC
Network Information
Device Memory
WebOTP
Web Crypto
Storage Web Storage
Capabilities IndexedDB
Cache Storage
FileSystem Access
UI Web Components
Capabilities CSS
2D Canvas
WebGL
Pointer Lock
Screen Capture
Basic PWA Service Workers
Icon Installation
Background Page Visibility
Background Fetch
Media Session
Security Web Authentication
Capabilities Passkeys
Credential Management
Permissions and Security
• Some permissions:
Permissions • Are harmless
and Security • Have no cost
• Involves a cost
Permissions-Policy: geolocation=()
Permissions Policy
You can define multiple policies at once of with multiple HTTP headers
Permissions-Policy: bluetooth=()
/
/
-
/
/
w
-
w
w
Permissions API
Permissions API
It let us query about current permission state.
It's CHAOS.
• Gyroscope
• Magnetometer
• Proximity
• Light Sensor
• Sensor API
Sensors API
We use a constructor (different per sensor and ability) and then we query
for data changes. ✳ Not available on iPhone and iPad
magSensor.addEventListener("reading", (e) {
console.log(`Magnetic f eld along the X-axis ${magSensor.x}`);
console.log(`Magnetic f eld along the Y-axis ${magSensor.y}`);
console.log(`Magnetic f eld along the Z-axis ${magSensor.z}`);
});
magSensor.addEventListener("error", (event) {
console.log(event.error.name, event.error.message);
});
magSensor.start();
i
i
i
=
>
=
>
Sensors
Classic Sensors API
Still available on all mobile devices; including iOS and iPadOS. It's a set
of events on the window object: devicemotion and device orientation
addEventListener("devicemotion", (event) {
const x = event.accelerationIncludingGravity.x;
const y = event.accelerationIncludingGravity.y;
const z = event.accelerationIncludingGravity.z;
});
addEventListener("deviceorientation", (event) {
const rotateDegrees = event.alpha; alpha: rotation around z axis
const leftToRight = event.gamma; gamma: left to right
const frontToBack = event.beta; beta: front back motion
});
/
/
/
/
/
/
=
>
=
>
-
Classic Sensors API
On iOS and iPadOS from 13.0 you must request permission with a non-
standard API on a user gesture.
if ('requestPermission' in DeviceMotionEvent) {
const response = await DeviceMotionEvent.requestPermission();
"granted", "denied"
}
/
/
Geolocation API
• How does it work?
Geolocation
• Provider-agnostic
API • It needs user's permission
https:// rt.dev/ios-14/#geolocation-changes
fi
Screen Orientation
Screen Orientation
It let us know the current orientation (green) and lock it to one specific
(light green).
screen.addEventListener("orientationchange", () {
console.log(`The orientation of the screen is: ${screen.orientation}`);
});
• Drag: touchmove
navigator.virtualKeyboard.overlaysContent = true;
navigator.virtualKeyboard.show();
navigator.virtualKeyboard.hide();
navigator.virtualKeyboard.addEventListener('geometrychanged',
e {})
=
>
Virtual Keyboard API for CSS
There are also new environmental variables
window.addEventListener('gamepadconnected', event {
const buttons = e.gamepad.buttons;
});
=
>
Web HID
Deck version 2023.01.a
devices.forEach((device) {
console.log(`HID ${device}`);
});
:
=
>
Gamepad API
You need to first connect your Gamepad to the device (USB or
Bluetooth) and query it in a requestAnimationFrame loop
window.addEventListener('gamepadconnected', event {
const buttons = e.gamepad.buttons;
});
=
>
Speech, Voice and Camera
Speech Recognition
Speech Recognition API
It allows us to listen for user's voice and get a text transcript.
It works only after a user gesture and microphone permission
recognition.addEventListener("result", event {
if (event.type "result") {
event.results.forEach( result {
const conf dence = result.conf dence*100;
const text = result.transcript;
});
}
})
=
=
i
=
>
i
=
>
Speech Synthesis
Speech Synthesis API
We can make the web app speak in the standard speaker based
on a text transcript. It uses synthesis voices from the OS.
speechSynthesis.speak(utterance);
66
Shape Detection
Barcode Detector
This is an experimental API working on Chrome for Android only
await navigator.xr.requestSession('immersive-vr');
await navigator.xr.requestSession('immersive-ar');
await navigator.xr.requestSession('inline');
AR Quick Look
It works only on iOS and iPadOS
wakeLock.addEventListener('release', () => {
// it was released
});
wakeLock.release();
External Hardware and Devices
Web Bluetooth
With this API we can:
Web
1- Scan BLE devices
Bluetooth
2- Scan services available
2- 3D Audio
Sending
ssocket = new SonicSocket({alphabet: '0123456789'});
ssocket.send(‘31415');
Receiving
sserver = new SonicServer({alphabet: '0123456789'});
sserver.on('message', function(message) {
Expect message to be '31415'.
console.log(message);
});
sserver.start()
/
/
/
/
/
/
Live demo
Web MIDI
• It's a low-level API
Web MIDI
• Connect to music devices, such as
synthesizers, keyboards, guitars, drum
machines and also lightning systems
• Send and receive MIDI messages
Web MIDI
navigator.requestMIDIAccess({sysex: false})
.then(onMIDISuccess, onMIDIFailure);
function onMIDISuccess(midi) {
Const inputs = midi.inputs.values();
for (var input=…) {
input.value.addEventListener(“midimessage”,
function(event) {
event.data has the bytes
});
}
}
/
/
Web Serial
• It's a low-level API
Web Serial
• Communicate with serial devices
connected to a user's computer via USB,
Bluetooth, or other serial connections.
• Built on top of the existing serial protocol,
which is widely supported by devices and
operating systems.
• It requires user permission before allowing
web applications to access serial devices.
• Sending and receiving data, controlling
settings, and detecting device
disconnection.
Web USB
• It's a low-level API; targeted to device vendors
Web USB mainly
• The device should not be registered by the OS
yet with a driver
• Communication with USB devices connected
to a user's computer.
• Read and write data directly to and from USB
devices, without the need for custom drivers
or proprietary software.
• It requires user permission before allowing
web applications to access USB devices.
• Configuring device settings, updating
firmware, and accessing device data.
Vibration
Vibration API
It doesn't work on many browsers :(
window.navigator.vibrate(300);
console.log(battery.level*100);
battery.addEventListener("chargingchange", () {}
battery.addEventListener("levelchange", () {}
battery.addEventListener("chargingtimechange", () {}
battery.addEventListener("dischargingtimechange", () {}
=
>
=
>
=
>
=
>
Idle Detection
Idle Detection
idleDetector.addEventListener("change", () {
const userState = idleDetector.userState;
const screenState = idleDetector.screenState;
});
await idleDetector.start();
}
=
=
=
>
Web NFC
• Near Field Communication
Web NFC • Access to Tap to Pay, Tap to Share, etc.
ndef.addEventListener("readingerror", () {
log("Error reading this tag");
});
window.moveTo(16, 16);
window.resizeTo(800, 600);
window.open("", "_blank", "");
112
Multi-Screen Windows Placement API
We can move windows again!
screenDetails.addEventListener('screenschange', e() {
=
>
Windows Controls Overlay
In the Web App Manifest we can express a new display mode
"display_override": ["window-controls-overlay"]
115
File Handler
File Handler
In the Web App Manifest we can express our intentions
"f le_handlers": [
{
"action": "/readcsv",
"accept": {
"text/csv": [".csv"]
},
"icons": [
],
"launch_type": "single client"
}
]
i
/
/
.
.
.
-
File Handler
In JavaScript then we can check on the launch queue if there are
files to process
launchQueue.setConsumer( launchParams {
Nothing to do when the queue is empty
if (!launchParams.f les.length) return;
{
"protocol_handlers": [
{
"protocol": "web frontendmasters",
"url": "/watch?argument=%s"
},
}
+
Protocol Handler
We can now use it in a standard link
navigator.share({
title: 'f rt.dev',
text: 'Content for web devs about PWAs',
url: 'https: f rt.dev',
optional f les array available
})
/
/
i
/
/
i
i
Web Share Target
We can express in the Web App Manifest our intentions
"share_target": {
"action": "/receiving share/",
"method": "GET",
"params": {
"id": "id",
"text": "contents",
}
}
-
Contact Picker API
Contact Picker
We can read contacts from user's database
domElement.requestFullscreen();
=
>
Payment Request
The browser is the intermediary
Payment
Merchant (website)
Request
User
Payment Processor
From developers.google.com
Get Installed Related Apps
We need to know the native app's
package ID, typically in the form of:
com.domain.app-name
Get Installed Related Apps
We start with the Web App Manifest
"related_applications": [
{
"platform": "play",
"id": "com.myapp.pwa",
"url": "https://play.google.com/store/apps/details?
id=com.myapp.pwa",
}
Get Installed Related Apps
Then we can use the API
<meta name="apple-itunes-app"
content="app-id=com.myapp.pwa">
Smart App Banner
For iOS and iPadOS we only have a meta tag for AppStore apps
<meta name="apple-itunes-app"
content="app-id=com.myapp.pwa">
<meta name="apple-itunes-app"
content="app-id=com.myapp.pwa,app-argument=myapp.com/deep/link">
<meta name="apple-itunes-app"
content="app-clip-bundle-id=com.myapp.pwa.clip">
App Badging
It lets us alert the user that there is new
App Badging content or pending tasks in our app
if ('setAppBadge' in navigator) {
navigator.setAppBadge(24)
}
if ('clearAppBadge' in navigator) {
navigator.clearAppBadge()
}
App Shortcuts
Menu items that will appear on icon
App launcher's
Shortcuts contextual menu (right click or long press)
"shortcuts": [{
"name": "Open a Second Action",
"short_name": "Second",
"description": "",
"url": "/second-action",
"icons": [{
"src": "/icons/second.png",
"sizes": "192x192",
"type": "image/png"
}]
}]
Experimental EyeDropper
Capabilities WebGPU
Compute Pressure
Popover
Web Transport
What we've covered