diff --git a/ui/StatusQ/CMakeLists.txt b/ui/StatusQ/CMakeLists.txt index 23e5a21af4..60655c38c4 100644 --- a/ui/StatusQ/CMakeLists.txt +++ b/ui/StatusQ/CMakeLists.txt @@ -408,6 +408,10 @@ target_link_libraries(StatusQ PRIVATE if(NOT (IOS OR ANDROID)) find_package(Qt${QT_VERSION_MAJOR} COMPONENTS WebEngineQuick QUIET) if(TARGET Qt::WebEngineQuick) + target_sources(StatusQ PRIVATE + include/StatusQ/browserprofileutils.h + src/browserprofileutils.cpp + ) target_link_libraries(StatusQ PRIVATE Qt::WebEngineQuick) target_compile_definitions(StatusQ PRIVATE STATUSQ_HAS_QTWEBENGINE=1) endif() diff --git a/ui/StatusQ/include/StatusQ/browserprofileutils.h b/ui/StatusQ/include/StatusQ/browserprofileutils.h new file mode 100644 index 0000000000..81dd7c9bbc --- /dev/null +++ b/ui/StatusQ/include/StatusQ/browserprofileutils.h @@ -0,0 +1,22 @@ +#pragma once + +#include + +// Desktop-only helper exposing WebEngineProfile clearing that the QML +// WebEngineProfile type does not expose (cookie store). Registered only when +// StatusQ is built with Qt WebEngine (STATUSQ_HAS_QTWEBENGINE). +class BrowserProfileUtils : public QObject +{ + Q_OBJECT + +public: + explicit BrowserProfileUtils(QObject *parent = nullptr); + + // Clears profile-wide browsing data: HTTP cache and all cookies. + // `profile` must be a QML WebEngineProfile (QQuickWebEngineProfile); + // no-op with a warning otherwise. The profile's clearHttpCacheCompleted + // signal still fires, so QML can drive completion/reload handling. + // Note: global DOM storage / visited links are not clearable via Qt's + // public API and are therefore left untouched. + Q_INVOKABLE void clearBrowsingData(QObject *profile); +}; diff --git a/ui/StatusQ/src/browserprofileutils.cpp b/ui/StatusQ/src/browserprofileutils.cpp new file mode 100644 index 0000000000..cc938382a3 --- /dev/null +++ b/ui/StatusQ/src/browserprofileutils.cpp @@ -0,0 +1,26 @@ +#include "StatusQ/browserprofileutils.h" + +#include +#include + +#include + +BrowserProfileUtils::BrowserProfileUtils(QObject *parent) + : QObject(parent) +{ +} + +void BrowserProfileUtils::clearBrowsingData(QObject *profile) +{ + auto *webProfile = qobject_cast(profile); + if (!webProfile) { + qWarning("BrowserProfileUtils::clearBrowsingData: expected a WebEngineProfile"); + return; + } + + if (auto *cookieStore = webProfile->cookieStore()) + cookieStore->deleteAllCookies(); + + // Async; the profile emits clearHttpCacheCompleted when done. + webProfile->clearHttpCache(); +} diff --git a/ui/StatusQ/src/typesregistration.cpp b/ui/StatusQ/src/typesregistration.cpp index b70a7e82af..57dccbe9a0 100644 --- a/ui/StatusQ/src/typesregistration.cpp +++ b/ui/StatusQ/src/typesregistration.cpp @@ -34,6 +34,10 @@ #include "MobileWebView/mobilewebviewbackend.h" #endif +#if defined(STATUSQ_HAS_QTWEBENGINE) +#include "StatusQ/browserprofileutils.h" +#endif + // Forward declare platform-specific registration functions // These are implemented in the respective platform files #if defined(Q_OS_IOS) || defined(Q_OS_ANDROID) || defined(Q_OS_MACOS) @@ -161,6 +165,13 @@ void registerStatusQTypes() { #if defined(STATUSQ_HAS_MOBILEWEBVIEW) qmlRegisterType("StatusQ.CustomWebView", 1, 0, "MobileWebViewBackend"); #endif + +#if defined(STATUSQ_HAS_QTWEBENGINE) + qmlRegisterSingletonType( + "StatusQ.Internal", 0, 1, "BrowserProfileUtils", [](QQmlEngine*, QJSEngine*) { + return new BrowserProfileUtils; + }); +#endif // Register NativeSwipeHandler + NativeIndicator (native on iOS/Android/macOS) #if defined(Q_OS_IOS) || defined(Q_OS_ANDROID) || defined(Q_OS_MACOS) registerNativeSwipeHandlerItemType(); diff --git a/ui/app/AppLayouts/Browser/BrowserLayout.qml b/ui/app/AppLayouts/Browser/BrowserLayout.qml index dff71640d8..ce164181bd 100644 --- a/ui/app/AppLayouts/Browser/BrowserLayout.qml +++ b/ui/app/AppLayouts/Browser/BrowserLayout.qml @@ -689,11 +689,11 @@ StatusSectionLayout { incognitoMode: _internal.currentTabIncognito zoomFactor: _internal.currentWebView?.zoomFactor ?? 1 browserSettings: localAccountSensitiveSettings - clearingCache: _internal.currentWebView?.clearing ?? false + clearingBrowsingData: _internal.currentWebView?.clearing ?? false clearSiteDataSupported: _internal.currentWebView?.clearSiteDataSupported ?? true onForceReload: webViewContext.forceReloadCurrent() onClearSiteData: webViewContext.clearSiteDataCurrent() - onClearCache: webViewContext.clearCacheCurrent() + onClearBrowsingData: webViewContext.clearBrowsingDataCurrent() onAddNewTab: _internal.addNewEmptyTab() onAddNewDownloadTab: _internal.addNewDownloadTab() onGoIncognito: (checked) => root.applyIncognitoMode(checked) @@ -736,7 +736,7 @@ StatusSectionLayout { clearing: _internal.currentWebView?.clearing ?? false onForceReload: webViewContext.forceReloadCurrent() onClearSiteData: webViewContext.clearSiteDataCurrent() - onClearCache: webViewContext.clearCacheCurrent() + onClearBrowsingData: webViewContext.clearBrowsingDataCurrent() onGoIncognito: checked => root.applyIncognitoMode(checked) onSettingsRequested: Global.changeAppSectionBySectionType(Constants.appSection.profile, Constants.settingsSubsection.browserSettings) diff --git a/ui/app/AppLayouts/Browser/adapters/AbstractWebView.qml b/ui/app/AppLayouts/Browser/adapters/AbstractWebView.qml index 84fb27ce8a..7dcfee6251 100644 --- a/ui/app/AppLayouts/Browser/adapters/AbstractWebView.qml +++ b/ui/app/AppLayouts/Browser/adapters/AbstractWebView.qml @@ -122,7 +122,7 @@ Item { function clearSiteData() { console.warn("AbstractWebView: clearSiteData not implemented") } // Clear browsing data (profile-wide cache, cookies, DOM storage), then reload. - function clearCache() { console.warn("AbstractWebView: clearCache not implemented") } + function clearBrowsingData() { console.warn("AbstractWebView: clearBrowsingData not implemented") } function findText(text, flags) {} function showFindPanel() {} diff --git a/ui/app/AppLayouts/Browser/adapters/LazyWebViewAdapter.qml b/ui/app/AppLayouts/Browser/adapters/LazyWebViewAdapter.qml index 277e2fb6e2..bee862f349 100644 --- a/ui/app/AppLayouts/Browser/adapters/LazyWebViewAdapter.qml +++ b/ui/app/AppLayouts/Browser/adapters/LazyWebViewAdapter.qml @@ -101,10 +101,10 @@ AbstractWebView { if (loader.item) loader.item.clearSiteData() } - function clearCache() { + function clearBrowsingData() { ensureLoaded() if (loader.item) - loader.item.clearCache() + loader.item.clearBrowsingData() } function findText(text, flags){ if (loader.item) loader.item.findText(text, flags) } function showFindPanel() { if (loader.item) loader.item.showFindPanel() } diff --git a/ui/app/AppLayouts/Browser/adapters/MobileWebViewAdapter.qml b/ui/app/AppLayouts/Browser/adapters/MobileWebViewAdapter.qml index ed9a72e71b..cb12f08b99 100644 --- a/ui/app/AppLayouts/Browser/adapters/MobileWebViewAdapter.qml +++ b/ui/app/AppLayouts/Browser/adapters/MobileWebViewAdapter.qml @@ -117,7 +117,7 @@ AbstractWebView { // Profile-wide "clear browsing data": HTTP cache + cookies + DOM storage. // Reloads the current view once clearProfileDataCompleted fires. - function clearCache() { + function clearBrowsingData() { backend.clearProfileData() } diff --git a/ui/app/AppLayouts/Browser/adapters/WebViewAdapter.qml b/ui/app/AppLayouts/Browser/adapters/WebViewAdapter.qml index f27fece3c1..c48824422c 100644 --- a/ui/app/AppLayouts/Browser/adapters/WebViewAdapter.qml +++ b/ui/app/AppLayouts/Browser/adapters/WebViewAdapter.qml @@ -3,6 +3,7 @@ import QtQml import QtWebEngine import StatusQ.Core.Theme +import StatusQ.Internal import AppLayouts.Browser.views @@ -51,20 +52,23 @@ AbstractWebView { function clearSiteData() { webView.runJavaScript("window.StatusSiteUtils && window.StatusSiteUtils.clearSiteDataAndReload()") } - // Profile-wide "clear browsing data": HTTP cache, cookies and visited links. - function clearCache() { + // Profile-wide "clear browsing data": HTTP cache + cookies, via the native + // BrowserProfileUtils (the QML WebEngineProfile exposes no cookie API). + // Global DOM storage isn't clearable via Qt's public API, so it's left as-is + // (unlike mobile's clearProfileData). The profile's clearHttpCacheCompleted + // drives _finishClearBrowsingData(); start the fallback timer first so `clearing` + // can never stick if the call fails. + function clearBrowsingData() { if (root.clearing || !root.profile) return root.clearing = true - root.profile.cookieStore.deleteAllCookies() - root.profile.clearAllVisitedLinks() - root.profile.clearHttpCache() // async; completion drives _finishClearCache() - _clearCacheFallbackTimer.restart() + _clearBrowsingDataFallbackTimer.restart() + BrowserProfileUtils.clearBrowsingData(root.profile) } - function _finishClearCache() { + function _finishClearBrowsingData() { if (!root.clearing) return - _clearCacheFallbackTimer.stop() + _clearBrowsingDataFallbackTimer.stop() root.clearing = false webView.reload() } @@ -232,15 +236,15 @@ AbstractWebView { return root.downloadRequested(download) } - function onClearHttpCacheCompleted() { root._finishClearCache() } + function onClearHttpCacheCompleted() { root._finishClearBrowsingData() } } // Fallback in case clearHttpCacheCompleted doesn't fire (e.g. empty cache). Timer { - id: _clearCacheFallbackTimer + id: _clearBrowsingDataFallbackTimer interval: 1000 repeat: false - onTriggered: root._finishClearCache() + onTriggered: root._finishClearBrowsingData() } WebEngineView { diff --git a/ui/app/AppLayouts/Browser/popups/BrowserSettingsMenu.qml b/ui/app/AppLayouts/Browser/popups/BrowserSettingsMenu.qml index 39c32b3b62..03917be8fb 100644 --- a/ui/app/AppLayouts/Browser/popups/BrowserSettingsMenu.qml +++ b/ui/app/AppLayouts/Browser/popups/BrowserSettingsMenu.qml @@ -27,9 +27,9 @@ StatusMenu { signal launchBrowserSettings() signal forceReload() signal clearSiteData() - signal clearCache() + signal clearBrowsingData() - property bool clearingCache: false + property bool clearingBrowsingData: false property bool clearSiteDataSupported: true background: Rectangle { @@ -158,16 +158,16 @@ StatusMenu { } StatusMenuItem { - text: root.clearingCache ? qsTr("Clearing cache...") : qsTr("Clear cache") + text: root.clearingBrowsingData ? qsTr("Clearing browsing data...") : qsTr("Clear browsing data") icon.name: "broom" icon.color: Theme.palette.primaryColor1 - enabled: !root.clearingCache + enabled: !root.clearingBrowsingData visibleOnDisabled: true - onTriggered: clearCache() + onTriggered: clearBrowsingData() StatusToolTip { visible: parent.hovered - text: qsTr("Clears cached files, cookies, and history for the entire browser. Browsing is paused until it is done.") + text: qsTr("Clears the cache and cookies for the entire browser. Browsing is paused until it is done.") } } diff --git a/ui/app/AppLayouts/Browser/popups/MobileSettingsMenu.qml b/ui/app/AppLayouts/Browser/popups/MobileSettingsMenu.qml index addbf58b39..456652c53d 100644 --- a/ui/app/AppLayouts/Browser/popups/MobileSettingsMenu.qml +++ b/ui/app/AppLayouts/Browser/popups/MobileSettingsMenu.qml @@ -30,7 +30,7 @@ StatusDialog { signal resetZoomFactor signal forceReload signal clearSiteData - signal clearCache + signal clearBrowsingData signal settingsRequested title: qsTr("Browser") @@ -123,11 +123,11 @@ StatusDialog { } } SettingsListItem { - title: root.clearing ? qsTr("Clearing cache...") : qsTr("Clear cache") + title: root.clearing ? qsTr("Clearing browsing data...") : qsTr("Clear browsing data") asset.name: "broom" enabled: !root.clearing onClicked: { - root.clearCache() + root.clearBrowsingData() root.close() } } diff --git a/ui/app/AppLayouts/Browser/webview/BrowserWebViewContext.qml b/ui/app/AppLayouts/Browser/webview/BrowserWebViewContext.qml index 74f899f31d..39feaf9dc7 100644 --- a/ui/app/AppLayouts/Browser/webview/BrowserWebViewContext.qml +++ b/ui/app/AppLayouts/Browser/webview/BrowserWebViewContext.qml @@ -206,10 +206,10 @@ QtObject { currentWebView.clearSiteData() } - function clearCacheCurrent() { + function clearBrowsingDataCurrent() { if (!currentWebView) return - currentWebView.clearCache() + currentWebView.clearBrowsingData() } function findTextCurrent(text, backward = false) { diff --git a/ui/i18n/qml_base_en.ts b/ui/i18n/qml_base_en.ts index 5c5182faed..0139eadd33 100644 --- a/ui/i18n/qml_base_en.ts +++ b/ui/i18n/qml_base_en.ts @@ -2582,6 +2582,10 @@ Do you wish to override the security check and continue? Developer Tools + + Force reload + + Clear site data @@ -2591,15 +2595,15 @@ Do you wish to override the security check and continue? - Clearing cache... + Clearing browsing data... - Clear cache + Clear browsing data - Clears cached files, cookies, and history for the entire browser. Browsing is paused until it is done. + Clears the cache and cookies for the entire browser. Browsing is paused until it is done. @@ -11315,6 +11319,22 @@ to load Zoom Fit + + Force reload + + + + Clear site data + + + + Clearing browsing data... + + + + Clear browsing data + + Settings diff --git a/ui/i18n/qml_cs.ts b/ui/i18n/qml_cs.ts index dc0a28c4ed..31ee80932a 100644 --- a/ui/i18n/qml_cs.ts +++ b/ui/i18n/qml_cs.ts @@ -2591,6 +2591,10 @@ Přejete si obejít bezpečnostní kontrolu a pokračovat? Developer Tools Vývojářské nástroje + + Force reload + + Clear site data Vyčistit data stránky @@ -2600,16 +2604,16 @@ Přejete si obejít bezpečnostní kontrolu a pokračovat? Použijte k obnovení aktuální stránky, pokud se nenačítá nebo nefunfuje správně. - Clearing cache... - Čistí se cache... + Clearing browsing data... + - Clear cache - Vyčistit cache + Clear browsing data + - Clears cached files, cookies, and history for the entire browser. Browsing is paused until it is done. - Vyčistí soubory, cookies a historii celého prohlížeče. Prohlížení je pozastaveno, dokud není hotovo. + Clears the cache and cookies for the entire browser. Browsing is paused until it is done. + Settings @@ -11382,6 +11386,22 @@ selhalo Zoom Fit Přizpůsobit velikost + + Force reload + + + + Clear site data + Vyčistit data stránky + + + Clearing browsing data... + + + + Clear browsing data + + Settings Nastavení diff --git a/ui/i18n/qml_es.ts b/ui/i18n/qml_es.ts index 93f6c67673..3a044d7945 100644 --- a/ui/i18n/qml_es.ts +++ b/ui/i18n/qml_es.ts @@ -2588,6 +2588,10 @@ Do you wish to override the security check and continue? Developer Tools Herramientas de desarrollo + + Force reload + + Clear site data @@ -2597,15 +2601,15 @@ Do you wish to override the security check and continue? - Clearing cache... + Clearing browsing data... - Clear cache + Clear browsing data - Clears cached files, cookies, and history for the entire browser. Browsing is paused until it is done. + Clears the cache and cookies for the entire browser. Browsing is paused until it is done. @@ -11328,6 +11332,22 @@ al cargar Zoom Fit Ajustar zoom + + Force reload + + + + Clear site data + + + + Clearing browsing data... + + + + Clear browsing data + + Settings Ajustes diff --git a/ui/i18n/qml_ko.ts b/ui/i18n/qml_ko.ts index 0bb7bf4541..cf39de8c72 100644 --- a/ui/i18n/qml_ko.ts +++ b/ui/i18n/qml_ko.ts @@ -2572,6 +2572,10 @@ Do you wish to override the security check and continue? Developer Tools 개발자 도구 + + Force reload + + Clear site data @@ -2581,15 +2585,15 @@ Do you wish to override the security check and continue? - Clearing cache... + Clearing browsing data... - Clear cache + Clear browsing data - Clears cached files, cookies, and history for the entire browser. Browsing is paused until it is done. + Clears the cache and cookies for the entire browser. Browsing is paused until it is done. @@ -11275,6 +11279,22 @@ to load Zoom Fit 맞춤 확대 + + Force reload + + + + Clear site data + + + + Clearing browsing data... + + + + Clear browsing data + + Settings 설정