diff --git a/.changes/clear-browsing-data-api.md b/.changes/clear-browsing-data-api.md new file mode 100644 index 000000000..4d48e8bbc --- /dev/null +++ b/.changes/clear-browsing-data-api.md @@ -0,0 +1,5 @@ +--- +"wry": "patch" +--- + +Add `Webview::clear_browsing_data` method. diff --git a/src/webview/android/kotlin/RustWebView.kt b/src/webview/android/kotlin/RustWebView.kt index 574e79c6f..7b0de021a 100644 --- a/src/webview/android/kotlin/RustWebView.kt +++ b/src/webview/android/kotlin/RustWebView.kt @@ -33,6 +33,18 @@ class RustWebView(context: Context): WebView(context) { } } + fun clearAllBrowsingData() { + try { + super.context.deleteDatabase("webviewCache.db"); + super.context.deleteDatabase("webview.db"); + super.clearCache(true); + super.clearHistory(); + super.clearFormData(); + } catch (ignore: Exception) { + Logger.error("Unable to create temporary media capture file: " + ex.message) + } + } + fun setAutoPlay(enable: Boolean) { post { val settings = super.getSettings() diff --git a/src/webview/android/main_pipe.rs b/src/webview/android/main_pipe.rs index bfd37879b..af572953e 100644 --- a/src/webview/android/main_pipe.rs +++ b/src/webview/android/main_pipe.rs @@ -212,6 +212,11 @@ impl MainPipe<'_> { load_url(env, webview.as_obj(), url, headers, false)?; } } + WebViewMessage::ClearAllBrowsingData => { + if let Some(webview) = &self.webview { + env.call_method(webview, "clearAllBrowsingData", "()V", &[])?; + } + } } } Ok(()) @@ -273,6 +278,7 @@ pub(crate) enum WebViewMessage { GetUrl(Sender), Jni(Box), LoadUrl(String, Option), + ClearAllBrowsingData, } pub(crate) struct CreateWebViewAttributes { diff --git a/src/webview/android/mod.rs b/src/webview/android/mod.rs index 4d4062346..bc8281c76 100644 --- a/src/webview/android/mod.rs +++ b/src/webview/android/mod.rs @@ -340,6 +340,11 @@ impl InnerWebView { pub fn load_url_with_headers(&self, url: &str, headers: http::HeaderMap) { MainPipe::send(WebViewMessage::LoadUrl(url.to_string(), Some(headers))); } + + pub fn clear_all_browsing_data(&self) -> Result<()> { + MainPipe::send(WebViewMessage::ClearAllBrowsingData); + Ok(()) + } } #[derive(Clone, Copy)] diff --git a/src/webview/mod.rs b/src/webview/mod.rs index 495e55d2d..05e244a5b 100644 --- a/src/webview/mod.rs +++ b/src/webview/mod.rs @@ -926,13 +926,20 @@ impl WebView { self.webview.set_background_color(background_color) } + /// Navigate to the specified url pub fn load_url(&self, url: &str) { self.webview.load_url(url) } + /// Navigate to the specified url using the specified headers pub fn load_url_with_headers(&self, url: &str, headers: http::HeaderMap) { self.webview.load_url_with_headers(url, headers) } + + /// Clear all browsing data + pub fn clear_all_browsing_data(&self) -> Result<()> { + self.webview.clear_all_browsing_data() + } } /// An event enumeration sent to [`FileDropHandler`]. diff --git a/src/webview/webkitgtk/mod.rs b/src/webview/webkitgtk/mod.rs index 1f07333ed..6065e4138 100644 --- a/src/webview/webkitgtk/mod.rs +++ b/src/webview/webkitgtk/mod.rs @@ -522,6 +522,23 @@ impl InnerWebView { self.webview.load_request(&req); } + + pub fn clear_all_browsing_data(&self) -> Result<()> { + if let Some(context) = WebViewExt::context(&*self.webview) { + use webkit2gtk::WebContextExt; + if let Some(data_manger) = context.website_data_manager() { + webkit2gtk::WebsiteDataManagerExtManual::clear( + &data_manger, + webkit2gtk::WebsiteDataTypes::ALL, + glib::TimeSpan::from_seconds(0), + None::<&Cancellable>, + |_| {}, + ); + } + } + + Ok(()) + } } pub fn platform_webview_version() -> Result { diff --git a/src/webview/webview2/mod.rs b/src/webview/webview2/mod.rs index 0f76ae486..8ac073aba 100644 --- a/src/webview/webview2/mod.rs +++ b/src/webview/webview2/mod.rs @@ -882,6 +882,22 @@ window.addEventListener('mousemove', (e) => window.chrome.webview.postMessage('_ load_url_with_headers(&self.webview, &self.env, url, headers); } + pub fn clear_all_browsing_data(&self) -> Result<()> { + let handler = ClearBrowsingDataCompletedHandler::create(Box::new(move |_| Ok(()))); + unsafe { + self + .webview + .cast::() + .map_err(|e| Error::WebView2Error(webview2_com::Error::WindowsError(e)))? + .Profile() + .map_err(|e| Error::WebView2Error(webview2_com::Error::WindowsError(e)))? + .cast::() + .map_err(|e| Error::WebView2Error(webview2_com::Error::WindowsError(e)))? + .ClearBrowsingDataAll(&handler) + .map_err(|e| Error::WebView2Error(webview2_com::Error::WindowsError(e))) + } + } + pub fn set_theme(&self, theme: Theme) { set_theme(&self.webview, theme); } diff --git a/src/webview/wkwebview/mod.rs b/src/webview/wkwebview/mod.rs index 4bebab431..cd4e0c354 100644 --- a/src/webview/wkwebview/mod.rs +++ b/src/webview/wkwebview/mod.rs @@ -918,6 +918,18 @@ r#"Object.defineProperty(window, 'ipc', { self.navigate_to_url(url, Some(headers)) } + pub fn clear_all_browsing_data(&self) -> Result<()> { + unsafe { + let config: id = msg_send![self.webview, configuration]; + let store: id = msg_send![config, websiteDataStore]; + let all_data_types: id = msg_send![class!(WKWebsiteDataStore), allWebsiteDataTypes]; + let date: id = msg_send![class!(NSDate), dateWithTimeIntervalSince1970: 0.0]; + let handler = block::ConcreteBlock::new(|| {}); + let _: () = msg_send![store, removeDataOfTypes:all_data_types modifiedSince:date completionHandler:handler]; + } + Ok(()) + } + fn navigate_to_url(&self, url: &str, headers: Option) { // Safety: objc runtime calls are unsafe unsafe {