fix(event): clear residual js listeners (#8916 ) (#8930)

* fix clear residual listeners tauri-apps#8916

* Comment out `println` on successful removal of `js_listeners`

* follow review changes.

* remvoe uneeded result

* Update fix-clear-residual-listeners.md
This commit is contained in:
canxin 2024-02-29 02:26:27 +08:00 committed by GitHub
parent f5f3ed5f6f
commit e4463f0814
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 30 additions and 10 deletions

View File

@ -0,0 +1,5 @@
---
"tauri": patch:bug
---
Clear JS event listeneres on page load, which fixes zombie listeners when the page reloads.

View File

@ -271,6 +271,12 @@ impl Listeners {
} }
} }
pub(crate) fn unlisten_all_js(&self, webview_label: &str) {
let inner_listeners = self.inner.as_ref();
let mut js_listeners = inner_listeners.js_event_listeners.lock().unwrap();
js_listeners.remove(webview_label);
}
pub(crate) fn has_js_listener<F: Fn(&EventTarget) -> bool>( pub(crate) fn has_js_listener<F: Fn(&EventTarget) -> bool>(
&self, &self,
event: &str, event: &str,

View File

@ -568,17 +568,20 @@ tauri::Builder::default()
})); }));
} }
if let Some(on_page_load_handler) = self.on_page_load_handler.take() { let label_ = pending.label.clone();
let label = pending.label.clone(); let manager_ = manager.manager_owned();
let manager = manager.manager_owned();
pending pending
.on_page_load_handler .on_page_load_handler
.replace(Box::new(move |url, event| { .replace(Box::new(move |url, event| {
if let Some(w) = manager.get_webview(&label) { if let Some(w) = manager_.get_webview(&label_) {
on_page_load_handler(w, PageLoadPayload { url: &url, event }); if let PageLoadEvent::Finished = event {
w.unlisten_all_js();
}
if let Some(handler) = self.on_page_load_handler.as_ref() {
handler(w, PageLoadPayload { url: &url, event });
}
} }
})); }));
}
manager.manager().webview.prepare_webview( manager.manager().webview.prepare_webview(
manager, manager,
@ -1317,6 +1320,12 @@ fn main() {
Ok(()) Ok(())
} }
/// Unregister all JS event listeners.
pub(crate) fn unlisten_all_js(&self) {
let listeners = self.manager().listeners();
listeners.unlisten_all_js(self.label());
}
pub(crate) fn emit_js(&self, emit_args: &EmitArgs, target: &EventTarget) -> crate::Result<()> { pub(crate) fn emit_js(&self, emit_args: &EmitArgs, target: &EventTarget) -> crate::Result<()> {
self.eval(&crate::event::emit_js_script( self.eval(&crate::event::emit_js_script(
self.manager().listeners().function_name(), self.manager().listeners().function_name(),