-
Notifications
You must be signed in to change notification settings - Fork 2.3k
/
DownloadLink.svelte
90 lines (78 loc) 路 2.11 KB
/
DownloadLink.svelte
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
<script lang="ts">
import type { HTMLAnchorAttributes } from "svelte/elements";
import { createEventDispatcher } from "svelte";
interface DownloadLinkAttributes
extends Omit<HTMLAnchorAttributes, "target"> {
download: NonNullable<HTMLAnchorAttributes["download"]>;
}
type $$Props = DownloadLinkAttributes;
import { getWorkerProxyContext } from "./context";
import { should_proxy_wasm_src } from "./file-url";
import { getHeaderValue } from "../src/http";
export let href: DownloadLinkAttributes["href"] = undefined;
export let download: DownloadLinkAttributes["download"];
const dispatch = createEventDispatcher();
let is_downloading = false;
const worker_proxy = getWorkerProxyContext();
async function wasm_click_handler(): Promise<void> {
if (is_downloading) {
return;
}
dispatch("click");
if (href == null) {
throw new Error("href is not defined.");
}
if (worker_proxy == null) {
throw new Error("Wasm worker proxy is not available.");
}
const url = new URL(href, window.location.href);
const path = url.pathname;
is_downloading = true;
worker_proxy
.httpRequest({
method: "GET",
path,
headers: {},
query_string: ""
})
.then((response) => {
if (response.status !== 200) {
throw new Error(`Failed to get file ${path} from the Wasm worker.`);
}
const blob = new Blob([response.body], {
type: getHeaderValue(response.headers, "content-type")
});
const blobUrl = URL.createObjectURL(blob);
const link = document.createElement("a");
link.href = blobUrl;
link.download = download;
link.click();
URL.revokeObjectURL(blobUrl);
})
.finally(() => {
is_downloading = false;
});
}
</script>
{#if worker_proxy && should_proxy_wasm_src(href)}
{#if is_downloading}
<slot />
{:else}
<a {...$$restProps} {href} on:click|preventDefault={wasm_click_handler}>
<slot />
</a>
{/if}
{:else}
<a
{href}
target={typeof window !== "undefined" && window.__is_colab__
? "_blank"
: null}
rel="noopener noreferrer"
{download}
{...$$restProps}
on:click={dispatch.bind(null, "click")}
>
<slot />
</a>
{/if}