mirror of
https://github.com/leptos-rs/leptos.git
synced 2025-12-27 11:04:40 -05:00
fix: maintain send/syncness of the handle
This commit is contained in:
@@ -324,7 +324,7 @@ where
|
|||||||
let (el, prev_cleanup) = state;
|
let (el, prev_cleanup) = state;
|
||||||
if let Some(prev) = prev_cleanup.take() {
|
if let Some(prev) = prev_cleanup.take() {
|
||||||
if let Some(remove) = prev.into_inner() {
|
if let Some(remove) = prev.into_inner() {
|
||||||
remove(el);
|
remove();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*prev_cleanup = Some(if E::CAPTURE {
|
*prev_cleanup = Some(if E::CAPTURE {
|
||||||
|
|||||||
@@ -259,7 +259,7 @@ where
|
|||||||
|
|
||||||
if let Some(prev) = prev_cleanup.take() {
|
if let Some(prev) = prev_cleanup.take() {
|
||||||
if let Some(remove) = prev.into_inner() {
|
if let Some(remove) = prev.into_inner() {
|
||||||
remove(el);
|
remove();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*prev_cleanup = Some(self.attach(el));
|
*prev_cleanup = Some(self.attach(el));
|
||||||
|
|||||||
@@ -294,21 +294,22 @@ impl Dom {
|
|||||||
);
|
);
|
||||||
|
|
||||||
// return the remover
|
// return the remover
|
||||||
RemoveEventHandler::new(el.clone(), {
|
RemoveEventHandler::new({
|
||||||
let name = name.to_owned();
|
let name = name.to_owned();
|
||||||
|
let el = el.clone();
|
||||||
// safe to construct this here, because it will only run in the browser
|
// safe to construct this here, because it will only run in the browser
|
||||||
// so it will always be accessed or dropped from the main thread
|
// so it will always be accessed or dropped from the main thread
|
||||||
let cb = send_wrapper::SendWrapper::new(cb);
|
let cb = send_wrapper::SendWrapper::new(move || {
|
||||||
move |el: &Element| {
|
|
||||||
or_debug!(
|
or_debug!(
|
||||||
el.remove_event_listener_with_callback(
|
el.remove_event_listener_with_callback(
|
||||||
intern(&name),
|
intern(&name),
|
||||||
cb.as_ref().unchecked_ref()
|
cb.as_ref().unchecked_ref()
|
||||||
),
|
),
|
||||||
el,
|
&el,
|
||||||
"removeEventListener"
|
"removeEventListener"
|
||||||
)
|
)
|
||||||
}
|
});
|
||||||
|
move || cb()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -332,22 +333,23 @@ impl Dom {
|
|||||||
);
|
);
|
||||||
|
|
||||||
// return the remover
|
// return the remover
|
||||||
RemoveEventHandler::new(el.clone(), {
|
RemoveEventHandler::new({
|
||||||
let name = name.to_owned();
|
let name = name.to_owned();
|
||||||
|
let el = el.clone();
|
||||||
// safe to construct this here, because it will only run in the browser
|
// safe to construct this here, because it will only run in the browser
|
||||||
// so it will always be accessed or dropped from the main thread
|
// so it will always be accessed or dropped from the main thread
|
||||||
let cb = send_wrapper::SendWrapper::new(cb);
|
let cb = send_wrapper::SendWrapper::new(move || {
|
||||||
move |el: &Element| {
|
|
||||||
or_debug!(
|
or_debug!(
|
||||||
el.remove_event_listener_with_callback_and_bool(
|
el.remove_event_listener_with_callback_and_bool(
|
||||||
intern(&name),
|
intern(&name),
|
||||||
cb.as_ref().unchecked_ref(),
|
cb.as_ref().unchecked_ref(),
|
||||||
true
|
true
|
||||||
),
|
),
|
||||||
el,
|
&el,
|
||||||
"removeEventListener"
|
"removeEventListener"
|
||||||
)
|
)
|
||||||
}
|
});
|
||||||
|
move || cb()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -446,19 +448,21 @@ impl Dom {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// return the remover
|
// return the remover
|
||||||
RemoveEventHandler::new(el.clone(), {
|
RemoveEventHandler::new({
|
||||||
let key = key.to_owned();
|
let key = key.to_owned();
|
||||||
|
let el = el.clone();
|
||||||
// safe to construct this here, because it will only run in the browser
|
// safe to construct this here, because it will only run in the browser
|
||||||
// so it will always be accessed or dropped from the main thread
|
// so it will always be accessed or dropped from the main thread
|
||||||
let cb = send_wrapper::SendWrapper::new(cb);
|
let el_cb = send_wrapper::SendWrapper::new((el, cb));
|
||||||
move |el: &Element| {
|
move || {
|
||||||
drop(cb.take());
|
let (el, cb) = el_cb.take();
|
||||||
|
drop(cb);
|
||||||
or_debug!(
|
or_debug!(
|
||||||
js_sys::Reflect::delete_property(
|
js_sys::Reflect::delete_property(
|
||||||
el,
|
&el,
|
||||||
&JsValue::from_str(&key)
|
&JsValue::from_str(&key)
|
||||||
),
|
),
|
||||||
el,
|
&el,
|
||||||
"delete property"
|
"delete property"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
use crate::view::{Mountable, ToTemplate};
|
use crate::view::{Mountable, ToTemplate};
|
||||||
use std::{borrow::Cow, fmt::Debug};
|
use std::{borrow::Cow, fmt::Debug, marker::PhantomData};
|
||||||
use wasm_bindgen::JsValue;
|
use wasm_bindgen::JsValue;
|
||||||
|
|
||||||
/// A DOM renderer.
|
/// A DOM renderer.
|
||||||
@@ -121,29 +121,31 @@ pub trait Renderer: Send + Sized + Debug + 'static {
|
|||||||
later to avoid dropping it immediately, or leak it with \
|
later to avoid dropping it immediately, or leak it with \
|
||||||
std::mem::forget() to never drop it."]
|
std::mem::forget() to never drop it."]
|
||||||
#[allow(clippy::type_complexity)]
|
#[allow(clippy::type_complexity)]
|
||||||
pub struct RemoveEventHandler<T>(T, Option<Box<dyn FnOnce(&T) + Send + Sync>>);
|
pub struct RemoveEventHandler<T>(
|
||||||
|
Option<Box<dyn FnOnce() + Send + Sync>>,
|
||||||
|
// only here to keep the generic, removing which would be a breaking change
|
||||||
|
// TODO remove generic in 0.9
|
||||||
|
PhantomData<fn() -> T>,
|
||||||
|
);
|
||||||
|
|
||||||
impl<T> RemoveEventHandler<T> {
|
impl<T> RemoveEventHandler<T> {
|
||||||
/// Creates a new container with a function that will be called when it is dropped.
|
/// Creates a new container with a function that will be called when it is dropped.
|
||||||
pub(crate) fn new(
|
pub(crate) fn new(remove: impl FnOnce() + Send + Sync + 'static) -> Self {
|
||||||
el: T,
|
Self(Some(Box::new(remove)), PhantomData)
|
||||||
remove: impl FnOnce(&T) + Send + Sync + 'static,
|
|
||||||
) -> Self {
|
|
||||||
Self(el, Some(Box::new(remove)))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(clippy::type_complexity)]
|
#[allow(clippy::type_complexity)]
|
||||||
pub(crate) fn into_inner(
|
pub(crate) fn into_inner(
|
||||||
mut self,
|
mut self,
|
||||||
) -> Option<Box<dyn FnOnce(&T) + Send + Sync>> {
|
) -> Option<Box<dyn FnOnce() + Send + Sync>> {
|
||||||
self.1.take()
|
self.0.take()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> Drop for RemoveEventHandler<T> {
|
impl<T> Drop for RemoveEventHandler<T> {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
if let Some(cb) = self.1.take() {
|
if let Some(cb) = self.0.take() {
|
||||||
cb(&self.0)
|
cb()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user