Skip to content

Change vdom bootstrapping to occur before the initial orders are processed. #235

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 10 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
201 changes: 140 additions & 61 deletions src/dom_types.rs

Large diffs are not rendered by default.

18 changes: 9 additions & 9 deletions src/events.rs
Original file line number Diff line number Diff line change
Expand Up @@ -319,7 +319,7 @@ pub fn input_ev<Ms, T: ToString + Copy>(

/// Create an event that passes a `web_sys::KeyboardEvent`, allowing easy access
/// to items like `key_code`() and key().
pub fn keyboard_ev<Ms: Clone, T: ToString + Copy>(
pub fn keyboard_ev<Ms, T: ToString + Copy>(
trigger: T,
handler: impl FnOnce(web_sys::KeyboardEvent) -> Ms + 'static + Clone,
) -> Listener<Ms> {
Expand All @@ -335,7 +335,7 @@ pub fn keyboard_ev<Ms: Clone, T: ToString + Copy>(
}

/// See `keyboard_ev`
pub fn mouse_ev<Ms: Clone, T: ToString + Copy>(
pub fn mouse_ev<Ms, T: ToString + Copy>(
trigger: T,
handler: impl FnOnce(web_sys::MouseEvent) -> Ms + 'static + Clone,
) -> Listener<Ms> {
Expand Down Expand Up @@ -381,28 +381,28 @@ pub fn raw_ev<Ms, T: ToString + Copy>(
)
}

// TODO: Remove seemingly arbitrary `Clone` bound here.
/// Create an event that passes no data, other than it occurred. Foregoes using a closure,
/// in favor of pointing to a message directly.
pub fn simple_ev<Ms: Clone, T>(trigger: T, message: Ms) -> Listener<Ms>
where
Ms: Clone + 'static,
Ms: 'static,
T: ToString + Copy,
{
let msg_closure = message.clone();
let handler = || msg_closure;
let closure = move |_| handler.clone()();
let stored_msg = message.clone();
let closure = move |_| message.clone();
Listener::new(
&trigger.to_string(),
Some(Box::new(closure)),
Some(Category::Simple),
Some(message),
Some(stored_msg),
)
}

/// Create an event that passes a `web_sys::CustomEvent`, allowing easy access
/// to detail() and then trigger update
#[deprecated]
pub fn trigger_update_ev<Ms: Clone>(
pub fn trigger_update_ev<Ms>(
handler: impl FnOnce(web_sys::CustomEvent) -> Ms + 'static + Clone,
) -> Listener<Ms> {
let closure = move |event: web_sys::Event| {
Expand Down Expand Up @@ -431,7 +431,7 @@ pub(crate) fn fmt_hook_fn<T>(h: &Option<T>) -> &'static str {

/// Trigger update function from outside of App
#[deprecated]
pub fn trigger_update_handler<Ms: Clone + DeserializeOwned>() -> Listener<Ms> {
pub fn trigger_update_handler<Ms: DeserializeOwned>() -> Listener<Ms> {
trigger_update_ev(|ev| {
ev.detail()
.into_serde()
Expand Down
3 changes: 1 addition & 2 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ mod websys_bridge;

/// Create an element flagged in a way that it will not be rendered. Useful
/// in ternary operations.
pub fn empty<Ms: Clone>() -> dom_types::Node<Ms> {
pub const fn empty<Ms>() -> dom_types::Node<Ms> {
dom_types::Node::Empty
}

Expand Down Expand Up @@ -133,7 +133,6 @@ pub mod tests {
}
}

#[derive(Clone)]
enum Msg {
Increment,
}
Expand Down
31 changes: 12 additions & 19 deletions src/orders.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ use std::{collections::VecDeque, convert::identity, rc::Rc};

// ------ Orders ------

pub trait Orders<Ms: 'static + Clone, GMs = ()> {
type AppMs: 'static + Clone;
pub trait Orders<Ms: 'static, GMs = ()> {
type AppMs: 'static;
type Mdl: 'static;
type ElC: View<Self::AppMs> + 'static;

Expand All @@ -19,7 +19,7 @@ pub trait Orders<Ms: 'static + Clone, GMs = ()> {
/// child::update(child_msg, &mut model.child, &mut orders.proxy(Msg::Child));
///}
/// ```
fn proxy<ChildMs: 'static + Clone>(
fn proxy<ChildMs: 'static>(
&mut self,
f: impl FnOnce(ChildMs) -> Ms + 'static + Clone,
) -> OrdersProxy<ChildMs, Self::AppMs, Self::Mdl, Self::ElC, GMs>;
Expand Down Expand Up @@ -80,13 +80,13 @@ pub trait Orders<Ms: 'static + Clone, GMs = ()> {
// ------ OrdersContainer ------

#[allow(clippy::module_name_repetitions)]
pub struct OrdersContainer<Ms: 'static + Clone, Mdl: 'static, ElC: View<Ms>, GMs = ()> {
pub struct OrdersContainer<Ms: 'static, Mdl: 'static, ElC: View<Ms>, GMs = ()> {
pub(crate) should_render: ShouldRender,
pub(crate) effects: VecDeque<Effect<Ms, GMs>>,
app: App<Ms, Mdl, ElC, GMs>,
}

impl<Ms: Clone, Mdl, ElC: View<Ms>, GMs> OrdersContainer<Ms, Mdl, ElC, GMs> {
impl<Ms, Mdl, ElC: View<Ms>, GMs> OrdersContainer<Ms, Mdl, ElC, GMs> {
pub fn new(app: App<Ms, Mdl, ElC, GMs>) -> Self {
Self {
should_render: ShouldRender::Render,
Expand All @@ -96,15 +96,15 @@ impl<Ms: Clone, Mdl, ElC: View<Ms>, GMs> OrdersContainer<Ms, Mdl, ElC, GMs> {
}
}

impl<Ms: 'static + Clone, Mdl, ElC: View<Ms> + 'static, GMs> Orders<Ms, GMs>
impl<Ms: 'static, Mdl, ElC: View<Ms> + 'static, GMs> Orders<Ms, GMs>
for OrdersContainer<Ms, Mdl, ElC, GMs>
{
type AppMs = Ms;
type Mdl = Mdl;
type ElC = ElC;

#[allow(clippy::redundant_closure)]
fn proxy<ChildMs: 'static + Clone>(
fn proxy<ChildMs: 'static>(
&mut self,
f: impl FnOnce(ChildMs) -> Ms + 'static + Clone,
) -> OrdersProxy<ChildMs, Ms, Mdl, ElC, GMs> {
Expand Down Expand Up @@ -167,19 +167,12 @@ impl<Ms: 'static + Clone, Mdl, ElC: View<Ms> + 'static, GMs> Orders<Ms, GMs>
// ------ OrdersProxy ------

#[allow(clippy::module_name_repetitions)]
pub struct OrdersProxy<
'a,
Ms: Clone,
AppMs: 'static + Clone,
Mdl: 'static,
ElC: View<AppMs>,
GMs: 'static = (),
> {
pub struct OrdersProxy<'a, Ms, AppMs: 'static, Mdl: 'static, ElC: View<AppMs>, GMs: 'static = ()> {
orders_container: &'a mut OrdersContainer<AppMs, Mdl, ElC, GMs>,
f: Rc<dyn Fn(Ms) -> AppMs>,
}

impl<'a, Ms: 'static + Clone, AppMs: 'static + Clone, Mdl, ElC: View<AppMs>, GMs>
impl<'a, Ms: 'static, AppMs: 'static, Mdl, ElC: View<AppMs>, GMs>
OrdersProxy<'a, Ms, AppMs, Mdl, ElC, GMs>
{
pub fn new(
Expand All @@ -193,14 +186,14 @@ impl<'a, Ms: 'static + Clone, AppMs: 'static + Clone, Mdl, ElC: View<AppMs>, GMs
}
}

impl<'a, Ms: 'static + Clone, AppMs: 'static + Clone, Mdl, ElC: View<AppMs> + 'static, GMs>
Orders<Ms, GMs> for OrdersProxy<'a, Ms, AppMs, Mdl, ElC, GMs>
impl<'a, Ms: 'static, AppMs: 'static, Mdl, ElC: View<AppMs> + 'static, GMs> Orders<Ms, GMs>
for OrdersProxy<'a, Ms, AppMs, Mdl, ElC, GMs>
{
type AppMs = AppMs;
type Mdl = Mdl;
type ElC = ElC;

fn proxy<ChildMs: 'static + Clone>(
fn proxy<ChildMs: 'static>(
&mut self,
f: impl FnOnce(ChildMs) -> Ms + 'static + Clone,
) -> OrdersProxy<ChildMs, AppMs, Mdl, ElC, GMs> {
Expand Down
24 changes: 10 additions & 14 deletions src/patch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use web_sys::{Document, Window};

/// Recursively attach all event-listeners. Run this after creating elements.
/// The associated `web_sys` nodes must be assigned prior to running this.
pub(crate) fn attach_listeners<Ms: Clone>(el: &mut El<Ms>, mailbox: &Mailbox<Ms>) {
pub(crate) fn attach_listeners<Ms>(el: &mut El<Ms>, mailbox: &Mailbox<Ms>) {
if let Some(el_ws) = el.node_ws.as_ref() {
for listener in &mut el.listeners {
listener.attach(el_ws, mailbox.clone());
Expand All @@ -26,7 +26,7 @@ pub(crate) fn attach_listeners<Ms: Clone>(el: &mut El<Ms>, mailbox: &Mailbox<Ms>
}

/// Recursively detach event-listeners. Run this before patching.
pub(crate) fn detach_listeners<Ms: Clone>(el: &mut El<Ms>) {
pub(crate) fn detach_listeners<Ms>(el: &mut El<Ms>) {
if let Some(el_ws) = el.node_ws.as_ref() {
for listener in &mut el.listeners {
listener.detach(el_ws);
Expand All @@ -41,7 +41,7 @@ pub(crate) fn detach_listeners<Ms: Clone>(el: &mut El<Ms>) {

/// We reattach all listeners, as with normal Els, since we have no
/// way of diffing them.
pub(crate) fn setup_window_listeners<Ms: Clone>(
pub(crate) fn setup_window_listeners<Ms>(
window: &Window,
old: &mut Vec<Listener<Ms>>,
new: &mut Vec<Listener<Ms>>,
Expand All @@ -57,11 +57,7 @@ pub(crate) fn setup_window_listeners<Ms: Clone>(
}

/// Remove a node from the vdom and `web_sys` DOM.
pub(crate) fn remove_node<Ms: Clone>(
node: &web_sys::Node,
parent: &web_sys::Node,
el_vdom: &mut El<Ms>,
) {
pub(crate) fn remove_node<Ms>(node: &web_sys::Node, parent: &web_sys::Node, el_vdom: &mut El<Ms>) {
websys_bridge::remove_node(node, parent);

if let Some(unmount_actions) = &mut el_vdom.hooks.will_unmount {
Expand All @@ -76,7 +72,7 @@ pub(crate) fn remove_node<Ms: Clone>(
/// model; don't let them get out of sync from typing or other events, which can occur if a change
/// doesn't trigger a re-render, or if something else modifies them using a side effect.
/// Handle controlled inputs: Ie force sync with the model.
fn setup_input_listener<Ms: Clone>(el: &mut El<Ms>)
fn setup_input_listener<Ms>(el: &mut El<Ms>)
where
Ms: 'static,
{
Expand All @@ -103,7 +99,7 @@ where
}

/// Recursively sets up input listeners
pub(crate) fn setup_input_listeners<Ms: Clone>(el_vdom: &mut El<Ms>)
pub(crate) fn setup_input_listeners<Ms>(el_vdom: &mut El<Ms>)
where
Ms: 'static,
{
Expand All @@ -115,7 +111,7 @@ where
}
}

fn patch_el<'a, Ms: Clone, Mdl, ElC: View<Ms>, GMs>(
fn patch_el<'a, Ms, Mdl, ElC: View<Ms>, GMs>(
document: &Document,
mut old: El<Ms>,
new: &'a mut El<Ms>,
Expand Down Expand Up @@ -197,7 +193,7 @@ fn patch_el<'a, Ms: Clone, Mdl, ElC: View<Ms>, GMs>(
new.node_ws.as_ref()
}

pub(crate) fn patch_els<'a, Ms: Clone, Mdl, ElC, GMs, OI, NI>(
pub(crate) fn patch_els<'a, Ms, Mdl, ElC, GMs, OI, NI>(
document: &Document,
mailbox: &Mailbox<Ms>,
app: &App<Ms, Mdl, ElC, GMs>,
Expand Down Expand Up @@ -282,7 +278,7 @@ pub(crate) fn patch_els<'a, Ms: Clone, Mdl, ElC, GMs, OI, NI>(
}

// Reduces code repetition
fn add_el_helper<Ms: Clone>(
fn add_el_helper<Ms>(
new: &mut El<Ms>,
parent: &web_sys::Node,
next_node: Option<web_sys::Node>,
Expand All @@ -306,7 +302,7 @@ fn add_el_helper<Ms: Clone>(

/// Routes patching through different channels, depending on the Node variant
/// of old and new.
pub(crate) fn patch<'a, Ms: Clone, Mdl, ElC: View<Ms>, GMs>(
pub(crate) fn patch<'a, Ms, Mdl, ElC: View<Ms>, GMs>(
document: &Document,
old: Node<Ms>,
new: &'a mut Node<Ms>,
Expand Down
2 changes: 1 addition & 1 deletion src/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,7 @@ pub fn error<T: std::fmt::Debug>(object: T) -> T {
#[deprecated]
pub fn update<Ms>(msg: Ms)
where
Ms: Clone + 'static + serde::Serialize,
Ms: 'static + serde::Serialize,
{
let msg_as_js_value = wasm_bindgen::JsValue::from_serde(&msg)
.expect("Error: TriggerUpdate - can't serialize given msg!");
Expand Down
Loading