Skip to content

Commit cbb5562

Browse files
PWA file handlers demo
1 parent 6e7ce3e commit cbb5562

File tree

10 files changed

+173
-0
lines changed

10 files changed

+173
-0
lines changed

pwa-file-handlers/README.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# PWA file handlers demo
2+
3+
[➡️Open demo app here⬅️](https://microsoftedge.github.io/Demos/pwa-file-handlers/)
4+
5+
> **Note:** to test the demo app, first install it by clicking the **App available** button in the address bar of Microsoft Edge, and then open the installed app in its own window.
6+
7+
The `file_handlers` web app manifest member lets your PWA handle files like native applications.
8+
9+
See [Handle files in a PWA](https://learn.microsoft.com/microsoft-edge/progressive-web-apps/how-to/handle-files).
7 KB
Loading
25.8 KB
Loading
1.58 KB
Loading
106 KB
Loading
4.35 KB
Loading

pwa-file-handlers/index.html

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
4+
<head>
5+
<meta charset="UTF-8">
6+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
7+
<title>PWA file handlers demo</title>
8+
<link rel="manifest" href="manifest.json">
9+
<link rel="stylesheet" href="style.css">
10+
<link rel="icon" type="image/png" href="icons/icon-128.png" sizes="128x128">
11+
<meta name="application-title" content="PWA file handlers">
12+
</head>
13+
14+
<body>
15+
<header>
16+
<h1>PWA file handlers demo</h1>
17+
<p>Install this app and then open a text file from your file explorer to see the file's content displayed here.</p>
18+
<p id="filename"></p>
19+
</header>
20+
<textarea id="file-content"></textarea>
21+
22+
<script src="script.js"></script>
23+
</body>
24+
25+
</html>

pwa-file-handlers/manifest.json

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
{
2+
"name": "PWA file handlers demo",
3+
"short_name": "file-handlers",
4+
"icons": [
5+
{
6+
"src": "icons/icon-512.png",
7+
"sizes": "512x512",
8+
"type": "image/png"
9+
},
10+
{
11+
"src": "icons/icon-256.png",
12+
"sizes": "256x256",
13+
"type": "image/png"
14+
},
15+
{
16+
"src": "icons/icon-128.png",
17+
"sizes": "128x128",
18+
"type": "image/png"
19+
},
20+
{
21+
"src": "icons/icon-96.png",
22+
"sizes": "96x96",
23+
"type": "image/png"
24+
},
25+
{
26+
"src": "icons/icon-48.png",
27+
"sizes": "48x48",
28+
"type": "image/png"
29+
}
30+
],
31+
"start_url": ".",
32+
"display": "standalone",
33+
"theme_color": "#000000",
34+
"background_color": "#FFFFFF",
35+
"launch_handler": {
36+
"client_mode": "navigate-existing"
37+
},
38+
"file_handlers": [
39+
{
40+
"action": "./",
41+
"accept": {
42+
"text/*": [
43+
".txt"
44+
]
45+
}
46+
}
47+
]
48+
}

pwa-file-handlers/script.js

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
const fileContent = document.getElementById('file-content');
2+
const fileName = document.getElementById('filename');
3+
4+
if ('launchQueue' in window) {
5+
launchQueue.setConsumer(launchParams => {
6+
handleFiles(launchParams.files);
7+
});
8+
} else {
9+
console.error('PWA file_handlers is not supported!');
10+
}
11+
12+
async function handleFiles(files) {
13+
if (!files.length) {
14+
console.log('No files to handle');
15+
return;
16+
}
17+
18+
// Only handle the first text file.
19+
for (const file of files) {
20+
const blob = await file.getFile();
21+
blob.handle = file;
22+
23+
if (blob.type === "text/plain") {
24+
const text = await blob.text();
25+
26+
fileName.textContent = file.name;
27+
fileContent.value = text;
28+
break;
29+
}
30+
31+
console.log(`${file.name} is not a text file, skipping.`);
32+
}
33+
}

pwa-file-handlers/style.css

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
html,
2+
body {
3+
height: 100%;
4+
margin: 0;
5+
}
6+
7+
body {
8+
font-family: system-ui;
9+
font-size: 13pt;
10+
display: grid;
11+
grid-template-rows: auto 1fr;
12+
gap: 2rem;
13+
padding: 2rem;
14+
box-sizing: border-box;
15+
}
16+
17+
header {
18+
padding: 1rem;
19+
background: black;
20+
color: white;
21+
border-radius: .5rem;
22+
max-width: 500px;
23+
}
24+
25+
h1 {
26+
font-size: 1.2rem;
27+
}
28+
29+
h1,
30+
p {
31+
margin: 0;
32+
}
33+
34+
#filename {
35+
padding: 0.5rem .5rem .5rem 2.5rem;
36+
background: white;
37+
color: black;
38+
margin-block-start: 1rem;
39+
border-radius: .25rem;
40+
font-family: monospace;
41+
background-image: url(./icons/icon-128.png);
42+
background-repeat: no-repeat;
43+
background-position: .5rem center;
44+
background-size: 1.5rem;
45+
}
46+
47+
textarea {
48+
border-radius: .5rem;
49+
border: .5rem solid black;
50+
padding: 1rem;
51+
line-height: 1.1em;
52+
background: repeating-linear-gradient(to bottom, transparent 0 calc(1.1em - 1px), #e9f4f8 calc(1.1em - 1px) 1.1em);
53+
background-attachment: local;
54+
background-size: 100% 1.1em;
55+
font-size: 1.2rem;
56+
background-position-y: -0.2em;
57+
white-space: nowrap;
58+
}

0 commit comments

Comments
 (0)