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
|
use std::path::PathBuf;
use std::{io, io::Write};
use web_sys::js_sys::Array;
use web_sys::wasm_bindgen::{JsCast, JsValue};
use web_sys::{Blob, BlobPropertyBag, HtmlAnchorElement, HtmlCanvasElement, Url};
pub fn get_canvas_element() -> Option<HtmlCanvasElement> {
let document = web_sys::window()?.document()?;
let canvas = document.get_element_by_id("nodetoy")?;
canvas.dyn_into::<HtmlCanvasElement>().ok()
}
pub struct DownloadFile {
data: Vec<u8>,
filename: PathBuf,
options: BlobPropertyBag,
}
impl DownloadFile {
pub fn new(filename: PathBuf, mime_type: &str) -> Self {
let options = BlobPropertyBag::new();
options.set_type(mime_type);
Self {
data: Vec::new(),
filename,
options,
}
}
pub fn save(&self) -> Result<(), JsValue> {
let string = unsafe { str::from_utf8_unchecked(&self.data) };
let parts = Array::of1(&JsValue::from_str(string));
let blob = Blob::new_with_str_sequence_and_options(&parts, &self.options)?;
let url = Url::create_object_url_with_blob(&blob)?;
let document = web_sys::window().unwrap().document().unwrap();
let a: HtmlAnchorElement = document.create_element("a")?.dyn_into()?;
a.set_href(&url);
a.set_download(&self.filename.as_os_str().to_string_lossy());
a.click();
Url::revoke_object_url(&url)?;
Ok(())
}
}
impl Write for DownloadFile {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
self.data.write(buf)
}
fn flush(&mut self) -> io::Result<()> {
self.data.flush()
}
}
impl Drop for DownloadFile {
fn drop(&mut self) {
self.save().unwrap()
}
}
|