Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Merged
6 changes: 6 additions & 0 deletions .changes/fix-clear-residual-listeners.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"tauri": patch:bug
---

Adds the `unlisten_all_js` method to struct `Webview` and calls it in on_page_load_handler when the corresponding webview window is refreshed.
This will only clean up all `js_listeners` for the window that was refreshed, and will not affect other windows.
6 changes: 6 additions & 0 deletions core/tauri/src/event/listener.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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>(
&self,
event: &str,
Expand Down
29 changes: 19 additions & 10 deletions core/tauri/src/webview/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 manager = manager.manager_owned();
pending
.on_page_load_handler
.replace(Box::new(move |url, event| {
if let Some(w) = manager.get_webview(&label) {
on_page_load_handler(w, PageLoadPayload { url: &url, event });
let label_ = pending.label.clone();
let manager_ = manager.manager_owned();
pending
.on_page_load_handler
.replace(Box::new(move |url, event| {
if let Some(w) = manager_.get_webview(&label_) {
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,
Expand Down Expand Up @@ -1317,6 +1320,12 @@ fn main() {
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<()> {
self.eval(&crate::event::emit_js_script(
self.manager().listeners().function_name(),
Expand Down
Loading