use js_sys::Reflect;
use wasm_bindgen::closure::Closure;
use wasm_bindgen::JsCast;
use web_sys::Url;
pub fn intercept_relative_links<F: FnMut(String) -> () + 'static>(mut on_anchor_tag_click: F) {
let on_anchor_click = move |event: web_sys::Event| {
let target = event
.target()
.unwrap()
.dyn_into::<web_sys::Element>()
.unwrap();
let tag_name = target.tag_name();
let tag_name = tag_name.as_str();
if tag_name.to_lowercase() == "a" {
let link = Reflect::get(&target, &"href".into())
.unwrap()
.as_string()
.unwrap();
let link_url = Url::new(link.as_str()).unwrap();
if link_url.hostname() == hostname() && link_url.port() == port() {
event.prevent_default();
on_anchor_tag_click(link_url.pathname())
}
}
};
let on_anchor_click = Closure::wrap(Box::new(on_anchor_click) as Box<dyn FnMut(_)>);
window()
.add_event_listener_with_callback("click", on_anchor_click.as_ref().unchecked_ref())
.unwrap();
on_anchor_click.forget();
}
pub fn set_onpopstate_handler<F: FnMut(String) -> () + 'static>(mut on_new_path: F) {
let on_popstate = move |_: web_sys::Event| {
let location = location();
let path = location.pathname().unwrap() + &location.search().unwrap();
on_new_path(path)
};
let on_popstate = Box::new(on_popstate) as Box<dyn FnMut(_)>;
let on_popstate = Closure::wrap(on_popstate);
window().set_onpopstate(Some(on_popstate.as_ref().unchecked_ref()));
on_popstate.forget();
}
fn window() -> web_sys::Window {
web_sys::window().unwrap()
}
fn document() -> web_sys::Document {
window().document().unwrap()
}
fn location() -> web_sys::Location {
document().location().unwrap()
}
fn hostname() -> String {
location().hostname().unwrap()
}
fn port() -> String {
location().port().unwrap()
}