Add workaround for some ChromeOS devices unable to download HTML files (#357, #383)

This commit is contained in:
Thomas Weber committed 2022-05-11 17:52:35 -05:00
1 parent 6cc78add57
commit d307d48a82
6 files changed
+87 -20

No files matched your search

+8
View File
@@ -467,6 +467,14 @@
"placeholder": {
"string": "Downloads will appear here",
"context": "Placeholder that appears when no project has been packaged yet so there is nothing to download"
},
"useWorkaround": {
"string": "Click here if download link doesn't work",
"context": "Buttons that appears when downloading certain file types on certain systems to work around system bugs that prevent downloading files."
},
"workaroundInProgress": {
"string": "Zipping...",
"context": "Message that appears when button to work around system download bugs is clicked as the process may take a few seconds."
}
},
"fileInput": {
+64 -9
View File
@@ -1,21 +1,76 @@
<script>
import Section from './Section.svelte';
import {_} from '../locales';
import {getJSZip} from '../packager/packager';
import downloadURL from './download-url';
import {isChromeOS} from './environment';
export let name;
export let url;
export let byteLength;
export let blob;
let zipping;
const useAlternativeDownloadToBypassChromeOSBugs = async () => {
// We've had a lot of bug reports about people on Chrome OS devices not being able to download
// HTML files but being able to download zip files just fine. We're pretty sure that's not our
// fault so we have to work around it (I want to blame whatever surveillance extensions
// they're being forced to install).
zipping = true;
try {
const JSZip = await getJSZip();
const zip = new JSZip();
zip.file(name, blob);
const zippedBlob = await zip.generateAsync({
type: 'blob',
compression: 'DEFLATE'
});
const newFileName = name.replace(/\.html$/, '.zip');
const blobURL = URL.createObjectURL(zippedBlob);
downloadURL(newFileName, blobURL);
URL.revokeObjectURL(blobURL);
} catch (e) {
console.error(e);
}
zipping = false;
};
</script>
{#if name && url && byteLength}
<style>
.alternative {
font-size: smaller;
}
</style>
{#if url}
<Section center>
<p>
<a href={url} download={name}>
{$_('downloads.link')
.replace('{size}', `${(byteLength / 1000 / 1000).toFixed(2)}MB`)
.replace('{filename}', name)}
</a>
</p>
<div>
<p>
<a href={url} download={name}>
{$_('downloads.link')
.replace('{size}', `${(blob.size / 1000 / 1000).toFixed(2)}MB`)
.replace('{filename}', name)}
</a>
</p>
{#if isChromeOS && name.endsWith('.html')}
<p class="alternative">
<button
on:click={useAlternativeDownloadToBypassChromeOSBugs}
disabled={zipping}
>
{#if zipping}
{$_('downloads.workaroundInProgress')}
{:else}
{$_('downloads.useWorkaround')}
{/if}
</button>
</p>
{/if}
</div>
</Section>
{:else}
<Section caption>
+2 -10
View File
@@ -16,6 +16,7 @@
import deepClone from './deep-clone';
import Packager from '../packager/web/export';
import Task from './task';
import downloadURL from './download-url';
export let projectData;
export let title;
@@ -96,15 +97,6 @@
image.src = url;
};
const downloadURL = (filename, url) => {
const link = document.createElement('a');
link.download = filename;
link.href = url;
document.body.appendChild(link);
link.click();
link.remove();
};
const runPackager = async (task, options) => {
const packager = new Packager();
packager.options = options;
@@ -872,5 +864,5 @@
<Downloads
name={result ? result.filename : null}
url={result ? result.url : null}
byteLength={result ? result.blob.size : null}
blob={result ? result.blob : null}
/>
+10
View File
@@ -0,0 +1,10 @@
const downloadURL = (filename, url) => {
const link = document.createElement('a');
link.download = filename;
link.href = url;
document.body.appendChild(link);
link.click();
link.remove();
};
export default downloadURL;
+2
View File
@@ -3,6 +3,8 @@ export const isSupported = typeof TextDecoder === 'function';
export const isSafari = navigator.vendor === 'Apple Computer, Inc.';
export const isChromeOS = navigator.userAgent.includes('CrOS');
export const isStandalone = !!process.env.STANDALONE;
export const version = process.env.VERSION;
+1 -1
View File
@@ -29,7 +29,7 @@ const removeUnnecessaryEmptyLines = (string) => string.split('\n')
})
.join('\n');
const getJSZip = async () => (await import(/* webpackChunkName: "jszip" */ 'jszip')).default;
export const getJSZip = async () => (await import(/* webpackChunkName: "jszip" */ 'jszip')).default;
const setFileFast = (zip, path, data) => {
zip.files[path] = data;