use wasm_bindgen::prelude::*;
use wasm_bindgen::JsCast;
use web_sys::{Document, Element, HtmlInputElement, HtmlTextAreaElement, Storage, Window};
pub(crate) fn window() -> Result<Window, JsValue> {
web_sys::window().ok_or_else(|| JsValue::from_str("no window — wrong execution context"))
}
pub(crate) fn document() -> Result<Document, JsValue> {
window()?
.document()
.ok_or_else(|| JsValue::from_str("no document — wrong execution context"))
}
pub(crate) fn session_storage() -> Result<Option<Storage>, JsValue> {
Ok(window()?.session_storage()?)
}
pub(crate) fn by_id(id: &str) -> Option<Element> {
document().ok()?.get_element_by_id(id)
}
pub(crate) fn input_by_id(id: &str) -> Option<HtmlInputElement> {
by_id(id)?.dyn_into::<HtmlInputElement>().ok()
}
pub(crate) fn textarea_by_id(id: &str) -> Option<HtmlTextAreaElement> {
by_id(id)?.dyn_into::<HtmlTextAreaElement>().ok()
}
pub(crate) fn swap_inner(id: &str, html: &str) {
if let Some(el) = by_id(id) {
el.set_inner_html(html);
}
}
pub(crate) fn swap_outer(id: &str, html: &str) {
if let Some(el) = by_id(id) {
el.set_outer_html(html);
}
}
pub(crate) fn append_html(id: &str, html: &str) {
if let Some(el) = by_id(id) {
let _ = el.insert_adjacent_html("beforeend", html);
}
}
pub(crate) fn scroll_to_bottom(id: &str) {
if let Some(el) = by_id(id) {
el.set_scroll_top(el.scroll_height());
}
}
pub(crate) fn scroll_to_bottom_soon(id: &str) {
scroll_to_bottom(id);
let Ok(win) = window() else { return };
for delay in [60, 350] {
let id = id.to_string();
let cb = Closure::once_into_js(move || scroll_to_bottom(&id));
let _ = win.set_timeout_with_callback_and_timeout_and_arguments_0(
cb.unchecked_ref(),
delay,
);
}
}
pub(crate) fn set_status(message: &str, is_error: bool) {
if let Some(el) = by_id("status") {
el.set_text_content(Some(message));
let cls = el.class_name();
let cleaned: Vec<&str> = cls.split_whitespace().filter(|c| *c != "err").collect();
let mut new_cls = cleaned.join(" ");
if is_error {
if !new_cls.is_empty() {
new_cls.push(' ');
}
new_cls.push_str("err");
}
el.set_class_name(&new_cls);
}
}