From 6ad778d27b47a98fb473c16d3ed4f788fb2ad9c4 Mon Sep 17 00:00:00 2001 From: Bruno Windels Date: Thu, 4 Mar 2021 21:51:29 +0100 Subject: [PATCH] support file downloads on iOS through data: uris --- assets/download-sandbox.html | 32 ++++++++++++++++++++++++++++---- src/platform/web/Platform.js | 2 +- src/platform/web/dom/download.js | 23 +++++++++++++++++++++-- 3 files changed, 50 insertions(+), 7 deletions(-) diff --git a/assets/download-sandbox.html b/assets/download-sandbox.html index f484a4b7..245b4bf8 100644 --- a/assets/download-sandbox.html +++ b/assets/download-sandbox.html @@ -7,16 +7,40 @@ Download diff --git a/src/platform/web/Platform.js b/src/platform/web/Platform.js index b3b6bccf..565aefe3 100644 --- a/src/platform/web/Platform.js +++ b/src/platform/web/Platform.js @@ -150,7 +150,7 @@ export class Platform { if (navigator.msSaveBlob) { navigator.msSaveBlob(blobHandle.nativeBlob, filename); } else { - downloadInIframe(this._container, this._paths.downloadSandbox, blobHandle.nativeBlob, filename); + downloadInIframe(this._container, this._paths.downloadSandbox, blobHandle, filename); } } diff --git a/src/platform/web/dom/download.js b/src/platform/web/dom/download.js index 77a7933b..41d3c29d 100644 --- a/src/platform/web/dom/download.js +++ b/src/platform/web/dom/download.js @@ -14,7 +14,10 @@ See the License for the specific language governing permissions and limitations under the License. */ -export async function downloadInIframe(container, iframeSrc, blob, filename) { +// From https://stackoverflow.com/questions/9038625/detect-if-device-is-ios/9039885 +const isIOS = /iPad|iPhone|iPod/.test(navigator.platform) || (navigator.platform === 'MacIntel' && navigator.maxTouchPoints > 1) && !window.MSStream; + +export async function downloadInIframe(container, iframeSrc, blobHandle, filename) { let iframe = container.querySelector("iframe.downloadSandbox"); if (!iframe) { iframe = document.createElement("iframe"); @@ -33,5 +36,21 @@ export async function downloadInIframe(container, iframeSrc, blob, filename) { }); detach(); } - iframe.contentWindow.postMessage({type: "download", blob: blob, filename: filename}, "*"); + if (isIOS) { + // iOS can't read a blob in a sandboxed iframe, + // see https://github.com/vector-im/hydrogen-web/issues/244 + const buffer = await blobHandle.readAsBuffer(); + iframe.contentWindow.postMessage({ + type: "downloadBuffer", + buffer, + mimeType: blobHandle.mimeType, + filename: filename + }, "*"); + } else { + iframe.contentWindow.postMessage({ + type: "downloadBlob", + blob: blobHandle.nativeBlob, + filename: filename + }, "*"); + } }