diff options
author | Christian Strømme <[email protected]> | 2022-06-14 20:18:24 +0200 |
---|---|---|
committer | Christian Strømme <[email protected]> | 2022-10-27 14:29:10 +0200 |
commit | be675d3721ff2eba5f9357086d595276989a9b95 (patch) | |
tree | 126b3fe00fa5d5b79830dd3f19b6d0e2480fba8d /src | |
parent | d7a1d393989eda6bc0207515dce0b8b4aac4b0ff (diff) |
Add settings API for QtWebView
Adds API and implementation for changing the settings of the WebView.
[ChangeLog][General] Added settings API to make it possible to
modify some of the WebView's built-in functionality.
Task-number: QTBUG-97487
Task-number: QTBUG-98549
Change-Id: Ia121175ec08c96f56fd2148b02dccbc963fff244
Reviewed-by: Qt CI Bot <[email protected]>
Reviewed-by: Michal Klocek <[email protected]>
Diffstat (limited to 'src')
-rw-r--r-- | src/jar/src/org/qtproject/qt/android/view/QtAndroidWebViewController.java | 134 | ||||
-rw-r--r-- | src/plugins/android/qandroidwebview.cpp | 53 | ||||
-rw-r--r-- | src/plugins/android/qandroidwebview_p.h | 23 | ||||
-rw-r--r-- | src/plugins/darwin/qdarwinwebview.mm | 85 | ||||
-rw-r--r-- | src/plugins/darwin/qdarwinwebview_p.h | 26 | ||||
-rw-r--r-- | src/plugins/webengine/qwebenginewebview.cpp | 79 | ||||
-rw-r--r-- | src/plugins/webengine/qwebenginewebview_p.h | 35 | ||||
-rw-r--r-- | src/quick/CMakeLists.txt | 1 | ||||
-rw-r--r-- | src/quick/qquickwebview.cpp | 10 | ||||
-rw-r--r-- | src/quick/qquickwebview_p.h | 6 | ||||
-rw-r--r-- | src/quick/qquickwebviewsettings.cpp | 104 | ||||
-rw-r--r-- | src/quick/qquickwebviewsettings_p.h | 70 | ||||
-rw-r--r-- | src/webview/qabstractwebview_p.h | 21 | ||||
-rw-r--r-- | src/webview/qwebview.cpp | 74 | ||||
-rw-r--r-- | src/webview/qwebview_p.h | 35 | ||||
-rw-r--r-- | src/webview/qwebviewfactory.cpp | 27 |
16 files changed, 778 insertions, 5 deletions
diff --git a/src/jar/src/org/qtproject/qt/android/view/QtAndroidWebViewController.java b/src/jar/src/org/qtproject/qt/android/view/QtAndroidWebViewController.java index 7a8b505..369e2a1 100644 --- a/src/jar/src/org/qtproject/qt/android/view/QtAndroidWebViewController.java +++ b/src/jar/src/org/qtproject/qt/android/view/QtAndroidWebViewController.java @@ -226,6 +226,140 @@ public class QtAndroidWebViewController } } + // Settings + public void setLocalStorageEnabled(boolean enabled) + { + m_activity.runOnUiThread(new Runnable() { + @Override + public void run() { + WebSettings webSettings = m_webView.getSettings(); + webSettings.setDatabaseEnabled(enabled); + webSettings.setDomStorageEnabled(enabled); + } + }); + } + + public boolean isLocalStorageEnabled() + { + final boolean[] enabled = {true}; + final Semaphore sem = new Semaphore(0); + m_activity.runOnUiThread(new Runnable() { + @Override + public void run() { + WebSettings webSettings = m_webView.getSettings(); + enabled[0] = webSettings.getDatabaseEnabled() && webSettings.getDomStorageEnabled(); + sem.release(); + } + }); + + try { + sem.tryAcquire(BLOCKING_TIMEOUT, TimeUnit.MILLISECONDS); + } catch (Exception e) { + e.printStackTrace(); + } + + return enabled[0]; + } + + public void setJavaScriptEnabled(boolean enabled) + { + m_activity.runOnUiThread(new Runnable() { + @Override + public void run() { + WebSettings webSettings = m_webView.getSettings(); + webSettings.setJavaScriptEnabled(enabled); + } + }); + } + + public boolean isJavaScriptEnabled() + { + final boolean[] enabled = {true}; + final Semaphore sem = new Semaphore(0); + m_activity.runOnUiThread(new Runnable() { + @Override + public void run() { + WebSettings webSettings = m_webView.getSettings(); + enabled[0] = webSettings.getJavaScriptEnabled(); + sem.release(); + } + }); + + try { + sem.tryAcquire(BLOCKING_TIMEOUT, TimeUnit.MILLISECONDS); + } catch (Exception e) { + e.printStackTrace(); + } + + return enabled[0]; + } + + public void setAllowFileAccessFromFileURLs(boolean enabled) + { + m_activity.runOnUiThread(new Runnable() { + @Override + public void run() { + WebSettings webSettings = m_webView.getSettings(); + webSettings.setAllowFileAccessFromFileURLs(enabled); + } + }); + } + + public boolean isAllowFileAccessFromFileURLsEnabled() + { + final boolean[] enabled = {true}; + final Semaphore sem = new Semaphore(0); + m_activity.runOnUiThread(new Runnable() { + @Override + public void run() { + WebSettings webSettings = m_webView.getSettings(); + enabled[0] = webSettings.getAllowFileAccessFromFileURLs(); + sem.release(); + } + }); + + try { + sem.tryAcquire(BLOCKING_TIMEOUT, TimeUnit.MILLISECONDS); + } catch (Exception e) { + e.printStackTrace(); + } + + return enabled[0]; + } + + public void setAllowFileAccess(boolean enabled) + { + m_activity.runOnUiThread(new Runnable() { + @Override + public void run() { + WebSettings webSettings = m_webView.getSettings(); + webSettings.setAllowFileAccess(enabled); + } + }); + } + + public boolean isAllowFileAccessEnabled() + { + final boolean[] enabled = {true}; + final Semaphore sem = new Semaphore(0); + m_activity.runOnUiThread(new Runnable() { + @Override + public void run() { + WebSettings webSettings = m_webView.getSettings(); + enabled[0] = webSettings.getAllowFileAccess(); + sem.release(); + } + }); + + try { + sem.tryAcquire(BLOCKING_TIMEOUT, TimeUnit.MILLISECONDS); + } catch (Exception e) { + e.printStackTrace(); + } + + return enabled[0]; + } + public String getUserAgent() { final String[] ua = {""}; diff --git a/src/plugins/android/qandroidwebview.cpp b/src/plugins/android/qandroidwebview.cpp index f2c33aa..5e13c08 100644 --- a/src/plugins/android/qandroidwebview.cpp +++ b/src/plugins/android/qandroidwebview.cpp @@ -17,6 +17,53 @@ QT_BEGIN_NAMESPACE +QAndroidWebViewSettingsPrivate::QAndroidWebViewSettingsPrivate(QJniObject viewController, QObject *p) + : QAbstractWebViewSettings(p) + , m_viewController(viewController) +{ + +} + +bool QAndroidWebViewSettingsPrivate::localStorageEnabled() const +{ + return m_viewController.callMethod<jboolean>("isLocalStorageEnabled"); +} + +bool QAndroidWebViewSettingsPrivate::javascriptEnabled() const +{ + return m_viewController.callMethod<jboolean>("isJavaScriptEnabled"); +} + +bool QAndroidWebViewSettingsPrivate::localContentCanAccessFileUrls() const +{ + return m_viewController.callMethod<jboolean>("isAllowFileAccessFromFileURLsEnabled"); +} + +bool QAndroidWebViewSettingsPrivate::allowFileAccess() const +{ + return m_viewController.callMethod<jboolean>("isAllowFileAccessEnabled"); +} + +void QAndroidWebViewSettingsPrivate::setLocalContentCanAccessFileUrls(bool enabled) +{ + m_viewController.callMethod<void>("setAllowFileAccessFromFileURLs", "(Z)V", enabled); +} + +void QAndroidWebViewSettingsPrivate::setJavascriptEnabled(bool enabled) +{ + m_viewController.callMethod<void>("setJavaScriptEnabled", "(Z)V", enabled); +} + +void QAndroidWebViewSettingsPrivate::setLocalStorageEnabled(bool enabled) +{ + m_viewController.callMethod<void>("setLocalStorageEnabled", "(Z)V", enabled); +} + +void QAndroidWebViewSettingsPrivate::setAllowFileAccess(bool enabled) +{ + m_viewController.callMethod<void>("setAllowFileAccess", "(Z)V", enabled); +} + static const char qtAndroidWebViewControllerClass[] = "org/qtproject/qt/android/view/QtAndroidWebViewController"; //static bool favIcon(JNIEnv *env, jobject icon, QImage *image) @@ -51,6 +98,7 @@ QAndroidWebViewPrivate::QAndroidWebViewPrivate(QObject *p) m_id); m_webView = m_viewController.callObjectMethod("getWebView", "()Landroid/webkit/WebView;"); + m_settings = new QAndroidWebViewSettingsPrivate(m_viewController, this); m_window = QWindow::fromWinId(reinterpret_cast<WId>(m_webView.object())); g_webViews->insert(m_id, this); @@ -176,6 +224,11 @@ void QAndroidWebViewPrivate::runJavaScriptPrivate(const QString &script, callbackId); } +QAbstractWebViewSettings *QAndroidWebViewPrivate::getSettings() const +{ + return m_settings; +} + void QAndroidWebViewPrivate::setCookie(const QString &domain, const QString &name, const QString &value) { QNativeInterface::QAndroidApplication::runOnAndroidMainThread([=]() { diff --git a/src/plugins/android/qandroidwebview_p.h b/src/plugins/android/qandroidwebview_p.h index a36c7ef..aa75900 100644 --- a/src/plugins/android/qandroidwebview_p.h +++ b/src/plugins/android/qandroidwebview_p.h @@ -24,6 +24,27 @@ QT_BEGIN_NAMESPACE +class QAndroidWebViewSettingsPrivate : public QAbstractWebViewSettings +{ + Q_OBJECT +public: + explicit QAndroidWebViewSettingsPrivate(QJniObject viewController, QObject *p = nullptr); + + bool localStorageEnabled() const; + bool javascriptEnabled() const; + bool localContentCanAccessFileUrls() const; + bool allowFileAccess() const; + +public Q_SLOTS: + void setLocalContentCanAccessFileUrls(bool enabled); + void setJavascriptEnabled(bool enabled); + void setLocalStorageEnabled(bool enabled); + void setAllowFileAccess(bool enabled); + +private: + QJniObject m_viewController; +}; + class QAndroidWebViewPrivate : public QAbstractWebView { Q_OBJECT @@ -60,6 +81,7 @@ public Q_SLOTS: protected: void runJavaScriptPrivate(const QString& script, int callbackId) override; + QAbstractWebViewSettings *getSettings() const override; private Q_SLOTS: void onApplicationStateChanged(Qt::ApplicationState state); @@ -70,6 +92,7 @@ private: QWindow *m_window; QJniObject m_viewController; QJniObject m_webView; + QAndroidWebViewSettingsPrivate *m_settings; }; QT_END_NAMESPACE diff --git a/src/plugins/darwin/qdarwinwebview.mm b/src/plugins/darwin/qdarwinwebview.mm index 1cc2e72..d4d6d9a 100644 --- a/src/plugins/darwin/qdarwinwebview.mm +++ b/src/plugins/darwin/qdarwinwebview.mm @@ -240,6 +240,74 @@ decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction QT_BEGIN_NAMESPACE +QDarwinWebViewSettingsPrivate::QDarwinWebViewSettingsPrivate(WKWebViewConfiguration *conf, QObject *p) + : QAbstractWebViewSettings(p) + , m_conf(conf) +{ + +} + +bool QDarwinWebViewSettingsPrivate::localStorageEnabled() const +{ + return m_conf.websiteDataStore.persistent; +} + +bool QDarwinWebViewSettingsPrivate::javascriptEnabled() const +{ + // Deprecated + bool isJsEnabled = false; +#if QT_MACOS_IOS_PLATFORM_SDK_EQUAL_OR_ABOVE(110000, 140000) + if (__builtin_available(macOS 11.0, iOS 14.0, *)) + isJsEnabled = m_conf.defaultWebpagePreferences.allowsContentJavaScript; +#else + isJsEnabled = m_conf.preferences.javaScriptEnabled; +#endif + return isJsEnabled; +} + +bool QDarwinWebViewSettingsPrivate::localContentCanAccessFileUrls() const +{ + return m_localContentCanAccessFileUrls; +} + +bool QDarwinWebViewSettingsPrivate::allowFileAccess() const +{ + return m_allowFileAccess; +} + +void QDarwinWebViewSettingsPrivate::setLocalContentCanAccessFileUrls(bool enabled) +{ + // This will be checked in QDarwinWebViewPrivate::setUrl() + m_localContentCanAccessFileUrls = enabled; +} + +void QDarwinWebViewSettingsPrivate::setJavascriptEnabled(bool enabled) +{ +#if QT_MACOS_IOS_PLATFORM_SDK_EQUAL_OR_ABOVE(110000, 140000) + if (__builtin_available(macOS 11.0, iOS 14.0, *)) + m_conf.defaultWebpagePreferences.allowsContentJavaScript = enabled; +#else + m_conf.preferences.javaScriptEnabled = enabled; +#endif +} + +void QDarwinWebViewSettingsPrivate::setLocalStorageEnabled(bool enabled) +{ + if (enabled == localStorageEnabled()) + return; + + if (enabled) + m_conf.websiteDataStore = [WKWebsiteDataStore defaultDataStore]; + else + m_conf.websiteDataStore = [WKWebsiteDataStore nonPersistentDataStore]; +} + +void QDarwinWebViewSettingsPrivate::setAllowFileAccess(bool enabled) +{ + // This will be checked in QDarwinWebViewPrivate::setUrl() + m_allowFileAccess = enabled; +} + QDarwinWebViewPrivate::QDarwinWebViewPrivate(QObject *p) : QAbstractWebView(p) , wkWebView(nil) @@ -254,6 +322,8 @@ QDarwinWebViewPrivate::QDarwinWebViewPrivate(QObject *p) options:NSKeyValueObservingOptions(NSKeyValueObservingOptionNew) context:nil]; + + m_settings = new QDarwinWebViewSettingsPrivate(wkWebView.configuration, this); #ifdef Q_OS_IOS m_recognizer = [[QIOSNativeViewSelectedRecognizer alloc] initWithQWindowControllerItem:this]; [wkWebView addGestureRecognizer:m_recognizer]; @@ -284,8 +354,12 @@ void QDarwinWebViewPrivate::setUrl(const QUrl &url) if (url.isLocalFile()) { // We need to pass local files via loadFileURL and the read access should cover // the directory that the file is in, to facilitate loading referenced images etc - [wkWebView loadFileURL:url.toNSURL() - allowingReadAccessToURL:QUrl(url.toString(QUrl::RemoveFilename)).toNSURL()]; + if (m_settings->allowFileAccess()) { + if (m_settings->localContentCanAccessFileUrls()) + [wkWebView loadFileURL:url.toNSURL() allowingReadAccessToURL:QUrl(url.toString(QUrl::RemoveFilename)).toNSURL()]; + else + [wkWebView loadRequest:[NSURLRequest requestWithURL:url.toNSURL()]]; + } } else { [wkWebView loadRequest:[NSURLRequest requestWithURL:url.toNSURL()]]; } @@ -541,4 +615,11 @@ void QDarwinWebViewPrivate::setHttpUserAgent(const QString &userAgent) Q_EMIT httpUserAgentChanged(userAgent); } + + +QAbstractWebViewSettings *QDarwinWebViewPrivate::getSettings() const +{ + return m_settings; +} + QT_END_NAMESPACE diff --git a/src/plugins/darwin/qdarwinwebview_p.h b/src/plugins/darwin/qdarwinwebview_p.h index 8013945..6625431 100644 --- a/src/plugins/darwin/qdarwinwebview_p.h +++ b/src/plugins/darwin/qdarwinwebview_p.h @@ -35,6 +35,7 @@ Q_FORWARD_DECLARE_OBJC_CLASS(WKWebView); Q_FORWARD_DECLARE_OBJC_CLASS(WKNavigation); +Q_FORWARD_DECLARE_OBJC_CLASS(WKWebViewConfiguration); #ifdef Q_OS_IOS Q_FORWARD_DECLARE_OBJC_CLASS(UIGestureRecognizer); @@ -42,6 +43,29 @@ Q_FORWARD_DECLARE_OBJC_CLASS(UIGestureRecognizer); QT_BEGIN_NAMESPACE +class QDarwinWebViewSettingsPrivate : public QAbstractWebViewSettings +{ + Q_OBJECT +public: + explicit QDarwinWebViewSettingsPrivate(WKWebViewConfiguration *conf, QObject *p = nullptr); + + bool localStorageEnabled() const; + bool javascriptEnabled() const; + bool localContentCanAccessFileUrls() const; + bool allowFileAccess() const; + +public Q_SLOTS: + void setLocalContentCanAccessFileUrls(bool enabled); + void setJavascriptEnabled(bool enabled); + void setLocalStorageEnabled(bool enabled); + void setAllowFileAccess(bool enabled); + +private: + WKWebViewConfiguration *m_conf = nullptr; + bool m_allowFileAccess = false; + bool m_localContentCanAccessFileUrls = false; +}; + class QDarwinWebViewPrivate : public QAbstractWebView { Q_OBJECT @@ -66,6 +90,7 @@ public: void setVisible(bool visible) override; void setFocus(bool focus) override; void updatePolish() override; + QAbstractWebViewSettings *getSettings() const override; public Q_SLOTS: void goBack() override; @@ -84,6 +109,7 @@ protected: public: WKWebView *wkWebView; WKNavigation *wkNavigation; + QDarwinWebViewSettingsPrivate *m_settings = nullptr; #ifdef Q_OS_IOS UIGestureRecognizer *m_recognizer; #endif diff --git a/src/plugins/webengine/qwebenginewebview.cpp b/src/plugins/webengine/qwebenginewebview.cpp index 065849b..958761d 100644 --- a/src/plugins/webengine/qwebenginewebview.cpp +++ b/src/plugins/webengine/qwebenginewebview.cpp @@ -19,7 +19,6 @@ #include <QtQuick/qquickitem.h> #include <QtWebEngineQuick/private/qquickwebengineview_p.h> -#include <QtWebEngineQuick/private/qquickwebenginesettings_p.h> #include <QtWebEngineCore/qwebengineloadinginfo.h> #include <QWebEngineCookieStore> @@ -37,6 +36,7 @@ static QByteArray qmlSource() QWebEngineWebViewPrivate::QWebEngineWebViewPrivate(QObject *p) : QAbstractWebView(p), m_profile(nullptr) { + m_settings = new QWebEngineWebViewSettingsPrivate(this); m_webEngineView.m_parent = this; m_cookieStore.m_webEngineViewPtr = &m_webEngineView; } @@ -157,6 +157,11 @@ void QWebEngineWebViewPrivate::setFocus(bool focus) m_webEngineView->forceActiveFocus(); } +QAbstractWebViewSettings *QWebEngineWebViewPrivate::getSettings() const +{ + return m_settings; +} + int QWebEngineWebViewPrivate::loadProgress() const { return m_webEngineView->loadProgress(); @@ -267,7 +272,12 @@ void QWebEngineWebViewPrivate::QQuickWebEngineViewPtr::init() const Q_ASSERT(webEngineView); QQuickWebEngineProfile *profile = webEngineView->profile(); Q_ASSERT(profile); + QQuickWebEngineSettings *settings = webEngineView->settings(); + Q_ASSERT(settings); m_parent->m_profile = profile; + if (!m_parent->m_settings) + m_parent->m_settings = new QWebEngineWebViewSettingsPrivate(m_parent); + m_parent->m_settings->init(settings); webEngineView->settings()->setErrorPageEnabled(false); // When the httpUserAgent is set as a property then it will be set before // init() is called @@ -303,4 +313,71 @@ void QWebEngineWebViewPrivate::QWebEngineCookieStorePtr::init() const } } +QWebEngineWebViewSettingsPrivate::QWebEngineWebViewSettingsPrivate(QWebEngineWebViewPrivate *p) + : QAbstractWebViewSettings(p) +{ + +} + +bool QWebEngineWebViewSettingsPrivate::localStorageEnabled() const +{ + return m_settings ? m_settings->localStorageEnabled() : m_localStorageEnabled; +} +bool QWebEngineWebViewSettingsPrivate::javascriptEnabled() const +{ + return m_settings ? m_settings->javascriptEnabled() : m_javaScriptEnabled; +} +bool QWebEngineWebViewSettingsPrivate::localContentCanAccessFileUrls() const +{ + return m_settings ? m_settings->localContentCanAccessFileUrls() : m_localContentCanAccessFileUrlsEnabled; +} +bool QWebEngineWebViewSettingsPrivate::allowFileAccess() const +{ + return m_allowFileAccessEnabled; +} +void QWebEngineWebViewSettingsPrivate::setLocalContentCanAccessFileUrls(bool enabled) +{ + if (m_settings) + m_settings->setLocalContentCanAccessFileUrls(enabled); + + m_localContentCanAccessFileUrlsEnabled = enabled; +} +void QWebEngineWebViewSettingsPrivate::setJavascriptEnabled(bool enabled) +{ + if (m_settings) + m_settings->setJavascriptEnabled(enabled); + + m_javaScriptEnabled = enabled; +} +void QWebEngineWebViewSettingsPrivate::setLocalStorageEnabled(bool enabled) +{ + // This separation is a bit different on the mobile platforms, so for now + // we'll interpret this property to also affect the "off the record" profile setting. + if (auto webview = qobject_cast<QWebEngineWebViewPrivate *>(parent())) { + if (webview->m_profile) + webview->m_profile->setOffTheRecord(enabled); + } + + if (m_settings) + m_settings->setLocalStorageEnabled(enabled); + + m_localStorageEnabled = enabled; +} +void QWebEngineWebViewSettingsPrivate::setAllowFileAccess(bool enabled) +{ + Q_UNUSED(enabled); +} + +void QWebEngineWebViewSettingsPrivate::init(QQuickWebEngineSettings *settings) +{ + m_settings = settings; + + if (m_settings) { + // Sync any values already set. + setLocalContentCanAccessFileUrls(m_localContentCanAccessFileUrlsEnabled); + setJavascriptEnabled(m_javaScriptEnabled); + setLocalStorageEnabled(m_localStorageEnabled); + } +} + QT_END_NAMESPACE diff --git a/src/plugins/webengine/qwebenginewebview_p.h b/src/plugins/webengine/qwebenginewebview_p.h index 4d6cc6f..6fd52cf 100644 --- a/src/plugins/webengine/qwebenginewebview_p.h +++ b/src/plugins/webengine/qwebenginewebview_p.h @@ -23,12 +23,41 @@ #include <private/qabstractwebview_p.h> #include <QtWebEngineQuick/QQuickWebEngineProfile> +#include <QtWebEngineQuick/private/qquickwebenginesettings_p.h> QT_BEGIN_NAMESPACE class QQuickWebEngineView; class QWebEngineLoadingInfo; class QNetworkCookie; +class QWebEngineWebViewPrivate; + +class QWebEngineWebViewSettingsPrivate : public QAbstractWebViewSettings +{ + Q_OBJECT +public: + explicit QWebEngineWebViewSettingsPrivate(QWebEngineWebViewPrivate *p = nullptr); + + bool localStorageEnabled() const; + bool javascriptEnabled() const; + bool localContentCanAccessFileUrls() const; + bool allowFileAccess() const; + +public Q_SLOTS: + void setLocalContentCanAccessFileUrls(bool enabled); + void setJavascriptEnabled(bool enabled); + void setLocalStorageEnabled(bool enabled); + void setAllowFileAccess(bool enabled); + + void init(QQuickWebEngineSettings *settings); + +private: + QPointer<QQuickWebEngineSettings> m_settings; + bool m_localStorageEnabled = true; + bool m_javaScriptEnabled = true; + bool m_localContentCanAccessFileUrlsEnabled = true; + bool m_allowFileAccessEnabled = true; +}; class QWebEngineWebViewPrivate : public QAbstractWebView { @@ -53,6 +82,7 @@ public: void setVisibility(QWindow::Visibility visibility) override; void setVisible(bool visible) override; void setFocus(bool focus) override; + QAbstractWebViewSettings *getSettings() const override; public Q_SLOTS: void goBack() override; @@ -79,7 +109,10 @@ protected: void runJavaScriptPrivate(const QString& script, int callbackId) override; private: - QQuickWebEngineProfile *m_profile; + friend class QWebEngineWebViewSettingsPrivate; + + QQuickWebEngineProfile *m_profile = nullptr; + mutable QWebEngineWebViewSettingsPrivate *m_settings = nullptr; QString m_httpUserAgent; struct QQuickWebEngineViewPtr { diff --git a/src/quick/CMakeLists.txt b/src/quick/CMakeLists.txt index fca90e4..09c1653 100644 --- a/src/quick/CMakeLists.txt +++ b/src/quick/CMakeLists.txt @@ -18,6 +18,7 @@ qt_internal_add_qml_module(WebViewQuick qquickwebview.cpp qquickwebview_p.h qquickwebviewloadrequest.cpp qquickwebviewloadrequest_p.h qtwebviewquickglobal_p.h + qquickwebviewsettings.cpp qquickwebviewsettings_p.h PUBLIC_LIBRARIES # TODO: QTBUG-86533 workaround, PUBLIC_LIBRARIES should be moved to LIBRARIES. Qt::Quick Qt::QmlModels diff --git a/src/quick/qquickwebview.cpp b/src/quick/qquickwebview.cpp index 0b41232..6718682 100644 --- a/src/quick/qquickwebview.cpp +++ b/src/quick/qquickwebview.cpp @@ -3,6 +3,7 @@ #include "qquickwebview_p.h" #include "qquickwebviewloadrequest_p.h" +#include "qquickwebviewsettings_p.h" #include <QtWebView/private/qwebviewloadrequest_p.h> #include <QtQml/qqmlengine.h> #include <QtCore/qmutex.h> @@ -58,7 +59,9 @@ Q_GLOBAL_STATIC(CallbackStorage, callbacks) */ QQuickWebView::QQuickWebView(QQuickItem *parent) - : QQuickViewController(parent), m_webView(new QWebView(this)) + : QQuickViewController(parent) + , m_webView(new QWebView(this)) + , m_settings(new QQuickWebViewSettings(m_webView->getSettings(), this)) { setView(m_webView); connect(m_webView, &QWebView::titleChanged, this, &QQuickWebView::titleChanged); @@ -370,3 +373,8 @@ QJSValue QQuickWebView::takeCallback(int id) { return callbacks->takeCallback(id); } + +QQuickWebViewSettings *QQuickWebView::settings() const +{ + return m_settings; +} diff --git a/src/quick/qquickwebview_p.h b/src/quick/qquickwebview_p.h index 439a545..a6f7b6e 100644 --- a/src/quick/qquickwebview_p.h +++ b/src/quick/qquickwebview_p.h @@ -21,12 +21,14 @@ #include <QtWebView/private/qwebview_p.h> #include <QtQml/qqmlregistration.h> Q_MOC_INCLUDE(<QtWebViewQuick/private/qquickwebviewloadrequest_p.h>) +Q_MOC_INCLUDE(<QtWebViewQuick/private/qquickwebviewsettings_p.h>) Q_MOC_INCLUDE(<QtWebView/private/qwebviewloadrequest_p.h>) QT_BEGIN_NAMESPACE class QQuickWebViewLoadRequest; class QWebViewLoadRequestPrivate; +class QQuickWebViewSettings; class Q_WEBVIEWQUICK_EXPORT QQuickWebView : public QQuickViewController, public QWebViewInterface { @@ -39,6 +41,7 @@ class Q_WEBVIEWQUICK_EXPORT QQuickWebView : public QQuickViewController, public Q_PROPERTY(QString title READ title NOTIFY titleChanged FINAL) Q_PROPERTY(bool canGoBack READ canGoBack NOTIFY loadingChanged FINAL) Q_PROPERTY(bool canGoForward READ canGoForward NOTIFY loadingChanged FINAL) + Q_PROPERTY(QQuickWebViewSettings *settings READ settings CONSTANT FINAL REVISION(6, 5)) Q_ENUMS(LoadStatus) QML_NAMED_ELEMENT(WebView) QML_ADDED_IN_VERSION(1, 0) @@ -65,6 +68,8 @@ public: bool canGoForward() const override; QWebView &webView() const { return *m_webView; }; + QQuickWebViewSettings *settings() const; + public Q_SLOTS: void goBack() override; void goForward() override; @@ -100,6 +105,7 @@ private: static QJSValue takeCallback(int id); QWebView *m_webView; + QQuickWebViewSettings *m_settings; }; QT_END_NAMESPACE diff --git a/src/quick/qquickwebviewsettings.cpp b/src/quick/qquickwebviewsettings.cpp new file mode 100644 index 0000000..4859bb0 --- /dev/null +++ b/src/quick/qquickwebviewsettings.cpp @@ -0,0 +1,104 @@ +// Copyright (C) 2022 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +#include "qquickwebviewsettings_p.h" + +#include <QtWebView/private/qwebview_p.h> + +QT_BEGIN_NAMESPACE + +/*! + \qmltype WebViewSettings + //! \instantiates QQuickWebViewSettings + \inqmlmodule QtWebView + \since QtWebView 6.5 + \brief Allows configuration of browser properties and attributes. + + The WebViewSettings type can be used to configure browser properties and generic + attributes, such as JavaScript support, file access and local storage features. + This type is uncreatable, but the default settings for all web views can be accessed by using + the \l [QML] {WebView::settings}{WebView.settings} property. + + The default values are left as set by the different platforms. +*/ + +QQuickWebViewSettings::QQuickWebViewSettings(QWebViewSettings *webviewsettings, QObject *p) + : QObject(p) + , d(webviewsettings) +{ + connect(d, &QWebViewSettings::localStorageEnabledChanged, + this, &QQuickWebViewSettings::localStorageEnabledChanged); + connect(d, &QWebViewSettings::javaScriptEnabledChanged, + this, &QQuickWebViewSettings::javaScriptEnabledChanged); + connect(d, &QWebViewSettings::localContentCanAccessFileUrlsChanged, + this, &QQuickWebViewSettings::localContentCanAccessFileUrlsChanged); + connect(d, &QWebViewSettings::allowFileAccessChanged, + this, &QQuickWebViewSettings::allowFileAccessChanged); +} + +QQuickWebViewSettings::~QQuickWebViewSettings() +{ + +} + +/*! + \qmlproperty bool WebViewSettings::localStorageEnabled + + Enables support for the HTML 5 local storage feature. +*/ +bool QQuickWebViewSettings::localStorageEnabled() const +{ + return d->localStorageEnabled(); +} + +void QQuickWebViewSettings::setLocalStorageEnabled(bool enabled) +{ + d->setLocalStorageEnabled(enabled); +} + +/*! + \qmlproperty bool WebViewSettings::javascriptEnabled + + Enables the running of JavaScript programs. +*/ +bool QQuickWebViewSettings::javaScriptEnabled() const +{ + return d->javaScriptEnabled(); +} + +void QQuickWebViewSettings::setJavaScriptEnabled(bool enabled) +{ + d->setJavaScriptEnabled(enabled); +} + +/*! + \qmlproperty bool WebViewSettings::localContentCanAccessFileUrls + + Allows locally loaded documents to access other local URLs. +*/ +bool QQuickWebViewSettings::localContentCanAccessFileUrls() const +{ + return d->localContentCanAccessFileUrls(); +} + +void QQuickWebViewSettings::setLocalContentCanAccessFileUrls(bool enabled) +{ + d->setLocalContentCanAccessFileUrls(enabled); +} + +/*! + \qmlproperty bool WebViewSettings::allowFileAccess + + Enables the WebView to load file URLs. +*/ +bool QQuickWebViewSettings::allowFileAccess() const +{ + return d->allowFileAccess(); +} + +void QQuickWebViewSettings::setAllowFileAccess(bool enabled) +{ + d->setAllowFileAccess(enabled); +} + +QT_END_NAMESPACE diff --git a/src/quick/qquickwebviewsettings_p.h b/src/quick/qquickwebviewsettings_p.h new file mode 100644 index 0000000..dda6f70 --- /dev/null +++ b/src/quick/qquickwebviewsettings_p.h @@ -0,0 +1,70 @@ +// Copyright (C) 2022 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +#ifndef QQUICKWEBVIEWSETTINGS_H +#define QQUICKWEBVIEWSETTINGS_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtWebViewQuick/private/qtwebviewquickglobal_p.h> +#include <QObject> +#include <QtQmlIntegration/qqmlintegration.h> +#include <QtWebView/private/qwebview_p.h> +#include <QtCore/qpointer.h> + +QT_BEGIN_NAMESPACE + +class QWebView; +class QWebViewSettings; + +class Q_WEBVIEWQUICK_EXPORT QQuickWebViewSettings : public QObject +{ + Q_OBJECT + Q_PROPERTY(bool localStorageEnabled READ localStorageEnabled WRITE setLocalStorageEnabled NOTIFY localStorageEnabledChanged) + Q_PROPERTY(bool javaScriptEnabled READ javaScriptEnabled WRITE setJavaScriptEnabled NOTIFY javaScriptEnabledChanged) + Q_PROPERTY(bool allowFileAccess READ allowFileAccess WRITE setAllowFileAccess NOTIFY allowFileAccessChanged) + Q_PROPERTY(bool localContentCanAccessFileUrls READ localContentCanAccessFileUrls WRITE setLocalContentCanAccessFileUrls NOTIFY localContentCanAccessFileUrlsChanged) + QML_NAMED_ELEMENT(WebViewSettings) + QML_ADDED_IN_VERSION(6, 5) + QML_UNCREATABLE("") + +public: + ~QQuickWebViewSettings() override; + + bool localStorageEnabled() const; + bool javaScriptEnabled() const; + bool localContentCanAccessFileUrls() const; + bool allowFileAccess() const; + +public Q_SLOTS: + void setLocalStorageEnabled(bool enabled); + void setJavaScriptEnabled(bool enabled); + void setAllowFileAccess(bool enabled); + void setLocalContentCanAccessFileUrls(bool enabled); + +Q_SIGNALS: + void localStorageEnabledChanged(); + void javaScriptEnabledChanged(); + void allowFileAccessChanged(); + void localContentCanAccessFileUrlsChanged(); + +private: + friend class QQuickWebView; + + explicit QQuickWebViewSettings(QWebViewSettings *webviewsettings, QObject *p = nullptr); + QPointer<QWebViewSettings> d; + bool m_allowFileAccess; +}; + +QT_END_NAMESPACE + +#endif // QQUICKWEBVIEWSETTINGS_H diff --git a/src/webview/qabstractwebview_p.h b/src/webview/qabstractwebview_p.h index b3fd1e5..7814906 100644 --- a/src/webview/qabstractwebview_p.h +++ b/src/webview/qabstractwebview_p.h @@ -23,6 +23,24 @@ QT_BEGIN_NAMESPACE class QWebView; class QWebViewLoadRequestPrivate; +class Q_WEBVIEW_EXPORT QAbstractWebViewSettings : public QObject +{ + Q_OBJECT +public: + virtual bool localStorageEnabled() const = 0; + virtual bool javascriptEnabled() const = 0; + virtual bool localContentCanAccessFileUrls() const = 0; + virtual bool allowFileAccess() const = 0; + + virtual void setLocalContentCanAccessFileUrls(bool) = 0; + virtual void setJavascriptEnabled(bool) = 0; + virtual void setLocalStorageEnabled(bool) = 0; + virtual void setAllowFileAccess(bool) = 0; + +protected: + explicit QAbstractWebViewSettings(QObject *p = nullptr) : QObject(p) {} +}; + class Q_WEBVIEW_EXPORT QAbstractWebView : public QObject , public QWebViewInterface @@ -30,6 +48,9 @@ class Q_WEBVIEW_EXPORT QAbstractWebView { Q_OBJECT +public: + virtual QAbstractWebViewSettings *getSettings() const = 0; + Q_SIGNALS: void titleChanged(const QString &title); void urlChanged(const QUrl &url); diff --git a/src/webview/qwebview.cpp b/src/webview/qwebview.cpp index 6ef0aeb..fa3bbd3 100644 --- a/src/webview/qwebview.cpp +++ b/src/webview/qwebview.cpp @@ -12,6 +12,7 @@ QT_BEGIN_NAMESPACE QWebView::QWebView(QObject *p) : QObject(p) , d(QWebViewFactory::createWebView()) + , m_settings(new QWebViewSettings(d->getSettings())) , m_progress(0) { d->setParent(this); @@ -134,6 +135,12 @@ void QWebView::setFocus(bool focus) void QWebView::updatePolish() { d->updatePolish(); + +} + +QWebViewSettings *QWebView::getSettings() const +{ + return m_settings; } void QWebView::loadHtml(const QString &html, const QUrl &baseUrl) @@ -211,4 +218,71 @@ void QWebView::init() d->init(); } +QWebViewSettings::QWebViewSettings(QAbstractWebViewSettings *settings) + : d(settings) +{ + Q_ASSERT(settings != nullptr); +} + +QWebViewSettings::~QWebViewSettings() +{ + +} + +bool QWebViewSettings::localStorageEnabled() const +{ + return d->localStorageEnabled(); +} + +void QWebViewSettings::setLocalStorageEnabled(bool enabled) +{ + if (d->localStorageEnabled() == enabled) + return; + + d->setLocalStorageEnabled(enabled); + emit localStorageEnabledChanged(); +} + +bool QWebViewSettings::javaScriptEnabled() const +{ + return d->javascriptEnabled(); +} + +void QWebViewSettings::setJavaScriptEnabled(bool enabled) +{ + if (d->javascriptEnabled() == enabled) + return; + + d->setJavascriptEnabled(enabled); + emit javaScriptEnabledChanged(); +} + +void QWebViewSettings::setAllowFileAccess(bool enabled) +{ + if (d->allowFileAccess() == enabled) + return; + + d->setAllowFileAccess(enabled); + emit allowFileAccessChanged(); +} + +bool QWebViewSettings::allowFileAccess() const +{ + return d->allowFileAccess(); +} + +bool QWebViewSettings::localContentCanAccessFileUrls() const +{ + return d->localContentCanAccessFileUrls(); +} + +void QWebViewSettings::setLocalContentCanAccessFileUrls(bool enabled) +{ + if (d->localContentCanAccessFileUrls() == enabled) + return; + + d->setLocalContentCanAccessFileUrls(enabled); + emit localContentCanAccessFileUrlsChanged(); +} + QT_END_NAMESPACE diff --git a/src/webview/qwebview_p.h b/src/webview/qwebview_p.h index 36230d8..b561b42 100644 --- a/src/webview/qwebview_p.h +++ b/src/webview/qwebview_p.h @@ -27,6 +27,39 @@ QT_BEGIN_NAMESPACE class QWebViewLoadRequestPrivate; +class Q_WEBVIEW_EXPORT QWebViewSettings : public QObject +{ + Q_OBJECT + Q_PROPERTY(bool localStorageEnabled READ localStorageEnabled WRITE setLocalStorageEnabled NOTIFY localStorageEnabledChanged) + Q_PROPERTY(bool javaScriptEnabled READ javaScriptEnabled WRITE setJavaScriptEnabled NOTIFY javaScriptEnabledChanged) + Q_PROPERTY(bool allowFileAccess READ allowFileAccess WRITE setAllowFileAccess NOTIFY allowFileAccessChanged) + Q_PROPERTY(bool localContentCanAccessFileUrls READ localContentCanAccessFileUrls WRITE setLocalContentCanAccessFileUrls NOTIFY localContentCanAccessFileUrlsChanged) + +public: + explicit QWebViewSettings(QAbstractWebViewSettings *webview); + ~QWebViewSettings() override; + + bool localStorageEnabled() const; + bool javaScriptEnabled() const; + bool allowFileAccess() const; + bool localContentCanAccessFileUrls() const; + +public Q_SLOTS: + void setLocalStorageEnabled(bool enabled); + void setJavaScriptEnabled(bool enabled); + void setAllowFileAccess(bool enabled); + void setLocalContentCanAccessFileUrls(bool enabled); + +signals: + void localStorageEnabledChanged(); + void javaScriptEnabledChanged(); + void allowFileAccessChanged(); + void localContentCanAccessFileUrlsChanged(); + +private: + QPointer<QAbstractWebViewSettings> d; +}; + class Q_WEBVIEW_EXPORT QWebView : public QObject , public QWebViewInterface @@ -61,6 +94,7 @@ public: void setVisible(bool visible) override; void setFocus(bool focus) override; void updatePolish() override; + QWebViewSettings *getSettings() const; public Q_SLOTS: void goBack() override; @@ -101,6 +135,7 @@ private: friend class QQuickWebView; QAbstractWebView *d; + QWebViewSettings *m_settings; // provisional data int m_progress; diff --git a/src/webview/qwebviewfactory.cpp b/src/webview/qwebviewfactory.cpp index d6468cb..12f054c 100644 --- a/src/webview/qwebviewfactory.cpp +++ b/src/webview/qwebviewfactory.cpp @@ -22,9 +22,27 @@ static QString getPluginName() return name; } +class QNullWebViewSettings : public QAbstractWebViewSettings +{ +public: + explicit QNullWebViewSettings(QObject *p) : QAbstractWebViewSettings(p) {} + bool localStorageEnabled() const override { return false; } + bool javascriptEnabled() const override { return false; } + bool localContentCanAccessFileUrls() const override { return false; } + bool allowFileAccess() const override { return false; } + void setLocalContentCanAccessFileUrls(bool) override {} + void setJavascriptEnabled(bool) override {} + void setLocalStorageEnabled(bool) override {} + void setAllowFileAccess(bool) override {} +}; + class QNullWebView : public QAbstractWebView { public: + explicit QNullWebView(QObject *p = nullptr) + : QAbstractWebView(p) + , m_settings(new QNullWebViewSettings(this)) + {} void setParentView(QObject *view) override { Q_UNUSED(view); } QObject *parentView() const override { return nullptr; } void setGeometry(const QRect &geometry) override { Q_UNUSED(geometry); } @@ -53,6 +71,15 @@ public: void deleteCookie(const QString &domain, const QString &name) override { Q_UNUSED(domain); Q_UNUSED(name); } void deleteAllCookies() override {} + +protected: + QAbstractWebViewSettings *getSettings() const override + { + return m_settings; + } + +private: + QNullWebViewSettings *m_settings = nullptr; }; QAbstractWebView *QWebViewFactory::createWebView() |