use wasm_bindgen::JsValue;
use wasm_bindgen_futures::JsFuture;
fn clipboard(method: &str) -> Option<web_sys::Clipboard> {
let clipboard = web_sys::window()?.navigator().clipboard();
let value: &JsValue = clipboard.as_ref();
if value.is_undefined() || value.is_null() {
return None;
}
let callable = js_sys::Reflect::get(value, &JsValue::from_str(method))
.map(|member| member.is_function())
.unwrap_or(false);
callable.then_some(clipboard)
}
pub(crate) fn set_text(text: &str) {
let Some(clipboard) = clipboard("writeText") else {
log::warn!("clipboard: unavailable (not a secure context?) — the copy is dropped");
return;
};
let written = JsFuture::from(clipboard.write_text(text));
wasm_bindgen_futures::spawn_local(async move {
if let Err(err) = written.await {
log::warn!("clipboard: write refused ({err:?})");
}
});
}
pub(crate) fn get_text(answer: impl FnOnce(String) + 'static) {
let Some(clipboard) = clipboard("readText") else {
log::warn!("clipboard: unavailable (not a secure context?) — nothing to paste");
return;
};
let read = JsFuture::from(clipboard.read_text());
wasm_bindgen_futures::spawn_local(async move {
match read.await {
Ok(value) => match value.as_string() {
Some(text) => answer(text),
None => log::warn!("clipboard: the read did not answer with text"),
},
Err(err) => log::warn!("clipboard: read refused ({err:?})"),
}
});
}