Add cleanup code to web backend, mostly web-sys (#1715)
* web-sys: Impl. event listeners removal for canvas * web-sys: Impl. media query listeners cleanup * web: Emit WindowEvent::Destroyed after Window is dropped * web-sys: Fix unload event closure being dropped early * web: Impl. cleanup on ControlFlow::Exit - Drops the Runner, which causes the event handler closure to be dropped. - (web-sys only:) Remove event listeners from DOM. * web: Do not remove canvas from DOM when dropping Window The canvas was inserted by the user, so it should be up to the user whether the canvas should be removed. * Update changelog
This commit is contained in:
parent
1c97a310b1
commit
47e7aa4209
13 changed files with 436 additions and 162 deletions
65
src/platform_impl/web/web_sys/event_handle.rs
Normal file
65
src/platform_impl/web/web_sys/event_handle.rs
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
use wasm_bindgen::{prelude::Closure, JsCast};
|
||||
use web_sys::{AddEventListenerOptions, EventTarget};
|
||||
|
||||
pub(super) struct EventListenerHandle<T: ?Sized> {
|
||||
target: EventTarget,
|
||||
event_type: &'static str,
|
||||
listener: Closure<T>,
|
||||
}
|
||||
|
||||
impl<T: ?Sized> EventListenerHandle<T> {
|
||||
pub fn new<U>(target: &U, event_type: &'static str, listener: Closure<T>) -> Self
|
||||
where
|
||||
U: Clone + Into<EventTarget>,
|
||||
{
|
||||
let target = target.clone().into();
|
||||
target
|
||||
.add_event_listener_with_callback(event_type, listener.as_ref().unchecked_ref())
|
||||
.expect("Failed to add event listener");
|
||||
EventListenerHandle {
|
||||
target,
|
||||
event_type,
|
||||
listener,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn with_options<U>(
|
||||
target: &U,
|
||||
event_type: &'static str,
|
||||
listener: Closure<T>,
|
||||
options: &AddEventListenerOptions,
|
||||
) -> Self
|
||||
where
|
||||
U: Clone + Into<EventTarget>,
|
||||
{
|
||||
let target = target.clone().into();
|
||||
target
|
||||
.add_event_listener_with_callback_and_add_event_listener_options(
|
||||
event_type,
|
||||
listener.as_ref().unchecked_ref(),
|
||||
options,
|
||||
)
|
||||
.expect("Failed to add event listener");
|
||||
EventListenerHandle {
|
||||
target,
|
||||
event_type,
|
||||
listener,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: ?Sized> Drop for EventListenerHandle<T> {
|
||||
fn drop(&mut self) {
|
||||
self.target
|
||||
.remove_event_listener_with_callback(
|
||||
self.event_type,
|
||||
self.listener.as_ref().unchecked_ref(),
|
||||
)
|
||||
.unwrap_or_else(|e| {
|
||||
web_sys::console::error_2(
|
||||
&format!("Error removing event listener {}", self.event_type).into(),
|
||||
&e,
|
||||
)
|
||||
});
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue