add platform method to offer saving a buffer handle

This commit is contained in:
Bruno Windels 2020-11-10 17:23:23 +01:00
parent fd950feb94
commit 4477073d6d
6 changed files with 80 additions and 0 deletions

View file

@ -0,0 +1,23 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<a id="link" href="#">Download!</a>
<script type="text/javascript">
var link = document.getElementById("link");
function download(blob, filename) {
var url = URL.createObjectURL(blob);
link.href = url;
link.download = filename;
link.click();
}
window.addEventListener("message", function(event) {
if (event.data.type === "download") {
download(event.data.blob, event.data.filename);
}
});
</script>
</body>
</html>

View file

@ -23,6 +23,7 @@
import {Platform} from "./src/platform/web/Platform.js";
main(new Platform(document.body, {
worker: "src/worker.js",
downloadSandbox: "assets/download-sandbox.html",
olm: {
wasm: "lib/olm/olm.wasm",
legacyBundle: "lib/olm/olm_legacy.js",

View file

@ -78,6 +78,10 @@ async function build({modernOnly}) {
]));
await assets.write(`worker.js`, await buildJsLegacy("src/platform/web/worker/main.js", ['src/platform/web/worker/polyfill.js']));
}
// copy over non-theme assets
const downloadSandbox = "download-sandbox.html";
let downloadSandboxHtml = await fs.readFile(path.join(projectDir, `assets/${downloadSandbox}`));
await assets.write(downloadSandbox, downloadSandboxHtml);
// creates the directories where the theme css bundles are placed in,
// and writes to assets, so the build bundles can translate them, so do it first
await copyThemeAssets(themes, assets);
@ -143,6 +147,7 @@ async function buildHtml(doc, version, globalHash, modernOnly, assets) {
});
const pathsJSON = JSON.stringify({
worker: assets.has("worker.js") ? assets.resolve(`worker.js`) : null,
downloadSandbox: assets.resolve("download-sandbox.html"),
serviceWorker: "sw.js",
olm: {
wasm: assets.resolve("olm.wasm"),
@ -234,6 +239,7 @@ function isPreCached(asset) {
asset.endsWith(".png") ||
asset.endsWith(".css") ||
asset.endsWith(".wasm") ||
asset.endsWith(".html") ||
// most environments don't need the worker
asset.endsWith(".js") && !NON_PRECACHED_JS.includes(asset);
}

View file

@ -28,6 +28,7 @@ import {Crypto} from "./dom/Crypto.js";
import {estimateStorageUsage} from "./dom/StorageEstimate.js";
import {WorkerPool} from "./dom/WorkerPool.js";
import {BufferHandle} from "./dom/BufferHandle.js";
import {downloadInIframe} from "./dom/download.js";
function addScript(src) {
return new Promise(function (resolve, reject) {
@ -133,4 +134,12 @@ export class Platform {
createBufferHandle(buffer, mimetype) {
return new BufferHandle(buffer, mimetype);
}
offerSaveBufferHandle(bufferHandle, filename) {
if (navigator.msSaveBlob) {
navigator.msSaveBlob(bufferHandle.blob, filename);
} else {
downloadInIframe(this._container, this._paths.downloadSandbox, bufferHandle.blob, filename);
}
}
}

View file

@ -0,0 +1,37 @@
/*
Copyright 2020 The Matrix.org Foundation C.I.C.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
export async function downloadInIframe(container, iframeSrc, blob, filename) {
let iframe = container.querySelector("iframe.downloadSandbox");
if (!iframe) {
iframe = document.createElement("iframe");
iframe.setAttribute("sandbox", "allow-scripts allow-downloads allow-downloads-without-user-activation");
iframe.setAttribute("src", iframeSrc);
iframe.className = "downloadSandbox";
container.appendChild(iframe);
let detach;
await new Promise((resolve, reject) => {
detach = () => {
iframe.removeEventListener("load", resolve);
iframe.removeEventListener("error", reject);
}
iframe.addEventListener("load", resolve);
iframe.addEventListener("error", reject);
});
detach();
}
iframe.contentWindow.postMessage({type: "download", blob: blob, filename: filename}, "*");
}

View file

@ -49,3 +49,7 @@ body.hydrogen {
input::-ms-clear {
display: none;
}
.hydrogen > iframe.downloadSandbox {
display: none;
}