mirror of
https://github.com/leptos-rs/leptos
synced 2024-11-10 06:44:17 +00:00
make RemoveEventHandler a concrete type
This commit is contained in:
parent
9de6c5bb4a
commit
598c59b9c2
4 changed files with 31 additions and 15 deletions
|
@ -93,13 +93,13 @@ impl<E, T, R> From<E> for Targeted<E, T, R> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn on<E, R, F>(event: E, cb: F) -> On<E, F, R>
|
||||
pub fn on<E, F, R>(event: E, cb: F) -> On<E, F, R>
|
||||
where
|
||||
F: FnMut(E::EventType) + 'static,
|
||||
E: EventDescriptor + Send + 'static,
|
||||
E::EventType: 'static,
|
||||
R: DomRenderer,
|
||||
E::EventType: From<R::Event>,
|
||||
R: DomRenderer,
|
||||
{
|
||||
On {
|
||||
event,
|
||||
|
@ -212,7 +212,7 @@ where
|
|||
{
|
||||
const MIN_LENGTH: usize = 0;
|
||||
// a function that can be called once to remove the event listener
|
||||
type State = (R::Element, Option<Box<dyn FnOnce(&R::Element)>>);
|
||||
type State = (R::Element, Option<RemoveEventHandler<R::Element>>);
|
||||
type Cloneable = On<E, SharedEventCallback<E::EventType>, R>;
|
||||
type CloneableOwned = On<E, SharedEventCallback<E::EventType>, R>;
|
||||
|
||||
|
@ -247,7 +247,7 @@ where
|
|||
fn rebuild(self, state: &mut Self::State) {
|
||||
let (el, prev_cleanup) = state;
|
||||
if let Some(prev) = prev_cleanup.take() {
|
||||
prev(el);
|
||||
(prev.into_inner())(el);
|
||||
}
|
||||
*prev_cleanup = Some(self.attach(el));
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use super::{CastFrom, DomRenderer, Renderer};
|
||||
use super::{CastFrom, DomRenderer, RemoveEventHandler, Renderer};
|
||||
use crate::{
|
||||
dom::{document, window},
|
||||
ok_or_debug, or_debug,
|
||||
|
@ -125,7 +125,7 @@ impl DomRenderer for Dom {
|
|||
el: &Self::Element,
|
||||
name: &str,
|
||||
cb: Box<dyn FnMut(Self::Event)>,
|
||||
) -> Box<dyn FnOnce(&Self::Element) + Send> {
|
||||
) -> RemoveEventHandler<Self::Element> {
|
||||
let cb = wasm_bindgen::closure::Closure::wrap(cb);
|
||||
let name = intern(name);
|
||||
or_debug!(
|
||||
|
@ -138,10 +138,10 @@ impl DomRenderer for Dom {
|
|||
);
|
||||
|
||||
// return the remover
|
||||
Box::new({
|
||||
RemoveEventHandler::new({
|
||||
let name = name.to_owned();
|
||||
let cb = send_wrapper::SendWrapper::new(cb);
|
||||
move |el| {
|
||||
move |el: &Self::Element| {
|
||||
or_debug!(
|
||||
el.remove_event_listener_with_callback(
|
||||
intern(&name),
|
||||
|
@ -171,7 +171,7 @@ impl DomRenderer for Dom {
|
|||
name: Cow<'static, str>,
|
||||
delegation_key: Cow<'static, str>,
|
||||
cb: Box<dyn FnMut(Self::Event)>,
|
||||
) -> Box<dyn FnOnce(&Self::Element) + Send> {
|
||||
) -> RemoveEventHandler<Self::Element> {
|
||||
let cb = Closure::wrap(cb);
|
||||
let key = intern(&delegation_key);
|
||||
or_debug!(
|
||||
|
@ -249,10 +249,10 @@ impl DomRenderer for Dom {
|
|||
});
|
||||
|
||||
// return the remover
|
||||
Box::new({
|
||||
RemoveEventHandler::new({
|
||||
let key = key.to_owned();
|
||||
let cb = send_wrapper::SendWrapper::new(cb);
|
||||
move |el| {
|
||||
move |el: &Self::Element| {
|
||||
drop(cb.take());
|
||||
or_debug!(
|
||||
js_sys::Reflect::delete_property(
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
//!
|
||||
//! Do not use this for anything real.
|
||||
|
||||
use super::{CastFrom, DomRenderer, Renderer};
|
||||
use super::{CastFrom, DomRenderer, RemoveEventHandler, Renderer};
|
||||
use crate::{
|
||||
html::element::{CreateElement, ElementType},
|
||||
view::Mountable,
|
||||
|
@ -225,7 +225,7 @@ impl DomRenderer for MockDom {
|
|||
el: &Self::Element,
|
||||
name: &str,
|
||||
cb: Box<dyn FnMut(Self::Event)>,
|
||||
) -> Box<dyn FnOnce(&Self::Element) + Send> {
|
||||
) -> RemoveEventHandler<Self::Element> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
|
@ -234,7 +234,7 @@ impl DomRenderer for MockDom {
|
|||
name: Cow<'static, str>,
|
||||
delegation_key: Cow<'static, str>,
|
||||
cb: Box<dyn FnMut(Self::Event)>,
|
||||
) -> Box<dyn FnOnce(&Self::Element) + Send> {
|
||||
) -> RemoveEventHandler<Self::Element> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
|
|
|
@ -127,7 +127,23 @@ pub trait Renderer: Send + Sized + Debug + 'static {
|
|||
}
|
||||
|
||||
/// A function that can be called to remove an event handler from an element after it has been added.
|
||||
pub type RemoveEventHandler<T> = Box<dyn FnOnce(&T) + Send>;
|
||||
#[must_use = "This will invalidate the event handler when it is dropped. You \
|
||||
should store it in some other data structure to clean it up \
|
||||
later to avoid dropping it immediately, or leak it with \
|
||||
std::mem::forget() to never drop it."]
|
||||
pub struct RemoveEventHandler<T>(Box<dyn FnOnce(&T) + Send + Sync>);
|
||||
|
||||
impl<T> RemoveEventHandler<T> {
|
||||
/// Creates a new container with a function that will be called when it is dropped.
|
||||
pub(crate) fn new(remove: impl FnOnce(&T) + Send + Sync + 'static) -> Self {
|
||||
Self(Box::new(remove))
|
||||
}
|
||||
|
||||
pub(crate) fn into_inner(self) -> Box<dyn FnOnce(&T) + Send + Sync> {
|
||||
self.0
|
||||
}
|
||||
}
|
||||
|
||||
/// Additional rendering behavior that applies only to DOM nodes.
|
||||
pub trait DomRenderer: Renderer {
|
||||
/// Generic event type, from which any specific event can be converted.
|
||||
|
|
Loading…
Reference in a new issue