chinedufn / percy

Build frontend browser apps with Rust + WebAssembly. Supports server side rendering.
https://chinedufn.github.io/percy/
Apache License 2.0
2.26k stars 84 forks source link

Intercept relative path links in the example #102

Open chinedufn opened 5 years ago

chinedufn commented 5 years ago

Clicking on links that have relative paths such as <a href="/login"></a> would then change routes without needing to add onclick handlers for such a common case.

So basically this ... just with comments (pulled from one of my projects)

        let onclick = 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();

                    store.borrow_mut().msg(&Msg::SetPath(link_url.pathname()));
                }
            }
        };
        let onclick = Closure::wrap(Box::new(onclick) as Box<FnMut(_)>);
        web_sys::window()
            .unwrap()
            .add_event_listener_with_callback("click", onclick.as_ref().unchecked_ref())
            .unwrap();
        onclick.forget();
chinedufn commented 5 years ago

Can do it around here

https://github.com/chinedufn/percy/blob/master/examples/isomorphic/client/src/lib.rs#L71

chinedufn commented 5 years ago

@cryptoquick you might find this useful. Basically lets you write your URLs as

html! { <a href="/some/path">Some Relative Path Link</a> }

and the route changes / page re-renders automatically.

I'm finding it much nicer than previously needing to call .msg() everything I wanted a new route ...