use gloo::utils::window;
use wasm_bindgen::JsValue;
use yew::prelude::*;
use super::use_event_with_window;
pub struct LocationState {
pub trigger: String,
pub state: Option<JsValue>,
pub length: u32,
pub hash: String,
pub host: String,
pub hostname: String,
pub href: String,
pub origin: String,
pub pathname: String,
pub port: String,
pub protocol: String,
pub search: String,
}
#[hook]
pub fn use_location() -> UseStateHandle<LocationState> {
let state = use_state(|| build_location("load".to_string()));
{
let state = state.clone();
use_event_with_window("popstate", move |_: Event| {
state.set(build_location("popstate".to_string()));
});
}
{
let state = state.clone();
use_event_with_window("pushstate", move |_: Event| {
state.set(build_location("pushstate".to_string()));
});
}
{
let state = state.clone();
use_event_with_window("replacestate", move |_: Event| {
state.set(build_location("replacestate".to_string()));
});
}
state
}
fn build_location(trigger: String) -> LocationState {
let location = window().location();
let history = window().history().map_or((None, 0), |history| {
(
history.state().ok(),
history.length().map_or(0, |length| length),
)
});
LocationState {
trigger,
state: history.0,
length: history.1,
hash: location.hash().unwrap_or_default(),
host: location.host().unwrap_or_default(),
hostname: location.hostname().unwrap_or_default(),
href: location.href().unwrap_or_default(),
origin: location.origin().unwrap_or_default(),
pathname: location.pathname().unwrap_or_default(),
port: location.port().unwrap_or_default(),
protocol: location.protocol().unwrap_or_default(),
search: location.search().unwrap_or_default(),
}
}