Skip to content

Commit

Permalink
feat!: remove callable
Browse files Browse the repository at this point in the history
  • Loading branch information
EqualMa committed Apr 12, 2024
1 parent bb9b5b3 commit f512d93
Show file tree
Hide file tree
Showing 10 changed files with 92 additions and 321 deletions.
7 changes: 0 additions & 7 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

26 changes: 0 additions & 26 deletions crates/frender-dom/src/behaviors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,14 +32,6 @@ pub trait HtmlElement<Renderer: ?Sized>: Element<Renderer> {
renderer: &mut Renderer,
) -> Self::OnBeforeInputPreventDefault;

/// On drop, the event listener should be removed.
type OnInputEventListenerNeverUpdated;
fn on_input_never_updated(
&mut self,
renderer: &mut Renderer,
f: impl FnMut(&dyn frender_events::event::InputEvent) + 'static,
) -> Self::OnInputEventListenerNeverUpdated;

fn as_node_ref(&self) -> &(dyn 'static + crate::node_ref::traits::HtmlElement);
}

Expand Down Expand Up @@ -122,24 +114,6 @@ impl<
Self::OnBeforeInputPreventDefault::new(node.clone(), "beforeinput")
}

type OnInputEventListenerNeverUpdated = gloo_events::EventListener;

fn on_input_never_updated(
&mut self,
renderer: &mut Renderer,
mut f: impl FnMut(&dyn frender_events::event::InputEvent) + 'static,
) -> Self::OnInputEventListenerNeverUpdated {
let node: &web_sys::Node = self.0.as_ref();

gloo_events::EventListener::new(node, "input", move |event| {
use frender_csr::event_listener::HandleEvent;
let mut f = crate::csr::web::event_listener::HandleJsCastEvent::new(
|event: &crate::csr::web::Event<web_sys::InputEvent>| f(event),
);
f.handle_event(event)
})
}

fn as_node_ref(&self) -> &(dyn 'static + crate::node_ref::traits::HtmlElement) {
AsRef::<web_sys::HtmlElement>::as_ref(&self.0)
}
Expand Down
1 change: 0 additions & 1 deletion crates/frender-events/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
callable = { version = "0.5.0", features = ["gat"] }
frender-common = { version = "0.1.0", path = "../frender-common" }
gloo = { version = "0.8.0", optional = true }
wasm-bindgen = { version = "0.2.84", optional = true }
Expand Down
13 changes: 0 additions & 13 deletions crates/frender-events/src/event_trait.rs

This file was deleted.

6 changes: 0 additions & 6 deletions crates/frender-events/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,3 @@
// TODO: move
mod event_trait;
pub use event_trait::*;

// TODO: move
pub use callable;
use frender_common::expand;

pub mod event;
Expand Down
32 changes: 20 additions & 12 deletions crates/frender-html/src/form_control/element.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use frender_events::event::Event;

use super::value::{TempAsRef, Value};
use super::value::{HandleValue, TempAsRef, Value};

pub trait FormControlElement<V: ?Sized + Value, Renderer: ?Sized>: crate::html::behaviors::HtmlElement<Renderer> {
fn set_default_value(&mut self, renderer: &mut Renderer, value: &V);
Expand All @@ -13,9 +13,22 @@ pub trait FormControlElement<V: ?Sized + Value, Renderer: ?Sized>: crate::html::

fn force_value<Val: TempAsRef<V> + 'static>(&mut self, renderer: &mut Renderer, value: Val) -> Self::ForceValue;

type OnValueChangeEventListener;
type OnValueChangeEventListener<F: HandleValue<V> + 'static>: Default;

fn on_value_change(&mut self, renderer: &mut Renderer, f: impl for<'v> FnMut(V::Passed<'v>) + 'static) -> Self::OnValueChangeEventListener;
fn on_value_change<F: HandleValue<V> + 'static>(&mut self, renderer: &mut Renderer, state: &mut Self::OnValueChangeEventListener<F>, f: F);
}

#[derive(Debug)]
pub struct HandleEventTargetFormControlValue<F: HandleValue<str>>(pub F);

impl<F: HandleValue<str>, E: ?Sized + Event> frender_dom::HandleEvent<E> for HandleEventTargetFormControlValue<F> {
fn handle_event(&mut self, e: &E) {
if let Some(v) = e.target_form_control_value() {
self.0.handle_value(v)
} else {
// TODO: warn about unexpected event target
}
}
}

#[cfg(feature = "web")]
Expand Down Expand Up @@ -46,15 +59,10 @@ impl<Renderer: ?Sized + frender_dom::csr::web::Renderer> FormControlElement<str,
frender_dom::behaviors::HtmlElement::on_before_input_prevent_default(self, renderer)
}

type OnValueChangeEventListener = <Self as frender_dom::behaviors::HtmlElement<Renderer>>::OnInputEventListenerNeverUpdated;
type OnValueChangeEventListener<F: HandleValue<str> + 'static> =
<<Self as crate::html::behaviors::HtmlElement<Renderer>>::OnInputEventListener<HandleEventTargetFormControlValue<F>> as frender_dom::EventListenerState<Self, Renderer, HandleEventTargetFormControlValue<F>>>::EventListenerStateUnpinned;

fn on_value_change(&mut self, renderer: &mut Renderer, mut f: impl FnMut(std::borrow::Cow<'_, str>) + 'static) -> Self::OnValueChangeEventListener {
frender_dom::behaviors::HtmlElement::on_input_never_updated(self, renderer, move |e| {
if let Some(v) = e.target_form_control_value() {
f(v)
} else {
// TODO: warn about unexpected event target
}
})
fn on_value_change<F: HandleValue<str> + 'static>(&mut self, renderer: &mut Renderer, state: &mut Self::OnValueChangeEventListener<F>, mut f: F) {
frender_dom::RegisterOrUpdate::register_or_update(std::pin::Pin::new(state), self, renderer, "input", HandleEventTargetFormControlValue(f))
}
}
76 changes: 41 additions & 35 deletions crates/frender-html/src/form_control/value.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ use std::{

use frender_common::PrimarilyBorrow;
use frender_dom::{render_state::non_reactive::NonReactiveRenderState, RenderState};
use frender_events::callable::Callable;
use frender_html_common::maybe_str::{IntoOneStringOrEmpty, MaybeStr};

use super::element::FormControlElement;
Expand All @@ -25,6 +24,16 @@ pub trait OfValue: PrimarilyBorrow<Borrowed = Self::Value> {
fn of_value(passed_value: <Self::Value as Value>::Passed<'_>) -> Self;
}

pub trait HandleValue<V: ?Sized + Value> {
fn handle_value(&mut self, v: V::Passed<'_>);
}

impl<V: ?Sized + Value, F: for<'v> FnMut(V::Passed<'v>)> HandleValue<V> for F {
fn handle_value(&mut self, v: <V as Value>::Passed<'_>) {
self(v)
}
}

impl Value for str {
type Passed<'a> = Cow<'a, str>;
}
Expand Down Expand Up @@ -203,13 +212,13 @@ impl<Val: OfValue<Value = V> + 'static, V: ?Sized + Value + PartialEq> FormContr
pub struct Controlled<
//
V: OfValue,
C: for<'a> Callable<(V,), Output = ()> + 'static + PartialEq + Clone,
C: FnMut(V) + 'static,
>(pub V, pub C);

impl<
//
V: OfValue<Value = str>,
C: for<'a> Callable<(V,), Output = ()> + 'static + PartialEq + Clone,
C: FnMut(V) + 'static,
> IntoOneStringOrEmpty for Controlled<V, C>
{
type OneStringOrEmpty = async_str_iter::borrow_str::IterBorrowStr<V>;
Expand All @@ -219,52 +228,49 @@ impl<
}
}

pub struct ControlledState<V, Cbk, EL> {
value: V,
callback: Cbk,
on_value_change_event_listener: EL,
pub struct HandleOfValue<Val, F: FnMut(Val)> {
f: F,
_v: std::marker::PhantomData<Val>,
}

impl<Val, F: FnMut(Val)> HandleOfValue<Val, F> {
fn new(f: F) -> Self {
Self { f, _v: std::marker::PhantomData }
}
}

impl<V: ?Sized + Value, Val: OfValue<Value = V>, F: FnMut(Val)> HandleValue<V> for HandleOfValue<Val, F> {
fn handle_value(&mut self, v: <V as Value>::Passed<'_>) {
(self.f)(Val::of_value(v))
}
}

impl<
//
V: ?Sized + Value + PartialEq,
Val: OfValue<Value = V>,
Cbk: for<'a> Callable<(Val,), Output = ()> + 'static + PartialEq + Clone,
Val: OfValue<Value = V> + 'static,
Cbk: FnMut(Val) + 'static,
> FormControlValue<V> for Controlled<Val, Cbk>
{
type State<E: FormControlElement<V, R> + ?Sized, R: ?Sized> = NonReactiveRenderState<Option<ControlledState<Val, Cbk, E::OnValueChangeEventListener>>>;
type State<E: FormControlElement<V, R> + ?Sized, R: ?Sized> = NonReactiveRenderState<(Option<Val>, E::OnValueChangeEventListener<HandleOfValue<Val, Cbk>>)>;

fn update_with_state<E: FormControlElement<V, R> + ?Sized, R: ?Sized>(this: Self, state: &mut Self::State<E, R>, element: &mut E, renderer: &mut R) {
let state = &mut state.0;
if let Some(state) = state {
let Self(value, cbk) = this;
let v = value.borrow();
if state.value.borrow() != v {
element.set_default_value(renderer, v);
element.set_value(renderer, v);
let (state, event_listener) = &mut state.0;
let Self(value, f) = this;

state.value = value;
}
element.on_value_change(renderer, event_listener, HandleOfValue::new(f));

if state.callback != cbk {
state.callback = cbk.clone();
state.on_value_change_event_listener = element.on_value_change(renderer, move |v| cbk.call_fn((Val::of_value(v),)));
let v = value.borrow();
if let Some(state) = state {
if Borrow::<V>::borrow(state) == v {
return;
}
} else {
let Self(value, cbk) = this;
}

{
let v = value.borrow();
element.set_default_value(renderer, v);
element.set_value(renderer, v);
}
element.set_default_value(renderer, v);
element.set_value(renderer, v);

*state = Some(ControlledState {
callback: Cbk::clone(&cbk),
on_value_change_event_listener: element.on_value_change(renderer, move |v| cbk.call_fn((Val::of_value(v),))),
value,
})
}
*state = Some(value);
}
}

Expand Down
Loading

0 comments on commit f512d93

Please sign in to comment.