diff options
Diffstat (limited to 'src/webengine/api')
-rw-r--r-- | src/webengine/api/qquickwebenginedownloaditem.cpp | 2 | ||||
-rw-r--r-- | src/webengine/api/qquickwebenginehistory.cpp | 102 | ||||
-rw-r--r-- | src/webengine/api/qquickwebenginenewviewrequest.cpp | 7 | ||||
-rw-r--r-- | src/webengine/api/qquickwebenginenewviewrequest_p.h | 2 | ||||
-rw-r--r-- | src/webengine/api/qquickwebengineprofile.cpp | 39 | ||||
-rw-r--r-- | src/webengine/api/qquickwebengineprofile_p.h | 8 | ||||
-rw-r--r-- | src/webengine/api/qquickwebenginesettings.cpp | 53 | ||||
-rw-r--r-- | src/webengine/api/qquickwebenginesettings_p.h | 10 | ||||
-rw-r--r-- | src/webengine/api/qquickwebenginesingleton.cpp | 36 | ||||
-rw-r--r-- | src/webengine/api/qquickwebenginetestsupport_p.h | 4 | ||||
-rw-r--r-- | src/webengine/api/qquickwebengineview.cpp | 371 | ||||
-rw-r--r-- | src/webengine/api/qquickwebengineview_p.h | 77 | ||||
-rw-r--r-- | src/webengine/api/qquickwebengineview_p_p.h | 15 | ||||
-rw-r--r-- | src/webengine/api/qtwebengineglobal.cpp | 28 |
14 files changed, 715 insertions, 39 deletions
diff --git a/src/webengine/api/qquickwebenginedownloaditem.cpp b/src/webengine/api/qquickwebenginedownloaditem.cpp index e04cff2c4..da47388ee 100644 --- a/src/webengine/api/qquickwebenginedownloaditem.cpp +++ b/src/webengine/api/qquickwebenginedownloaditem.cpp @@ -227,7 +227,7 @@ qint64 QQuickWebEngineDownloadItem::receivedBytes() const The download path can only be set in the \c WebEngineProfile.onDownloadRequested handler before the download is accepted. - \sa WebEngineProfile::downloadRequested(WebEngineDownloadItem download), WebEngineDownloadItem::accept() + \sa WebEngineProfile::downloadRequested(), accept() */ QString QQuickWebEngineDownloadItem::path() const diff --git a/src/webengine/api/qquickwebenginehistory.cpp b/src/webengine/api/qquickwebenginehistory.cpp index 9a737fbbe..175b52248 100644 --- a/src/webengine/api/qquickwebenginehistory.cpp +++ b/src/webengine/api/qquickwebenginehistory.cpp @@ -118,6 +118,26 @@ int QQuickWebEngineForwardHistoryListModelPrivate::offsetForIndex(int index) con return index + 1; } +/*! + \qmltype WebEngineHistoryListModel + \instantiates QQuickWebEngineHistoryListModel + \inqmlmodule QtWebEngine 1.1 + \since QtWebEngine 1.1 + + \brief A data model that represents the history of a web engine page. + + The WebEngineHistoryListModel type exposes the \e title, \e url, and \e offset roles. The + \e title and \e url specify the title and URL of the visited page. The \e offset specifies + the position of the page in respect to the current page (0). A positive number indicates that + the page was visited after the current page, whereas a negative number indicates that the page + was visited before the current page. + + This type is uncreatable, but it can be accessed by using the + \l{WebEngineView::navigationHistory}{WebEngineView.navigationHistory} property. + + \sa WebEngineHistory +*/ + QQuickWebEngineHistoryListModel::QQuickWebEngineHistoryListModel() : QAbstractListModel() { @@ -185,6 +205,67 @@ QQuickWebEngineHistoryPrivate::~QQuickWebEngineHistoryPrivate() { } +/*! + \qmltype WebEngineHistory + \instantiates QQuickWebEngineHistory + \inqmlmodule QtWebEngine 1.1 + \since QtWebEngine 1.1 + + \brief Provides data models that represent the history of a web engine page. + + The WebEngineHistory type can be accessed by using the + \l{WebEngineView::navigationHistory}{WebEngineView.navigationHistory} property. + + The WebEngineHistory type providess the following WebEngineHistoryListModel data model objects: + + \list + \li \c backItems, which contains the URLs of visited pages. + \li \c forwardItems, which contains the URLs of the pages that were visited after visiting + the current page. + \li \c items, which contains the URLs of the back and forward items, as well as the URL of + the current page. + \endlist + + The easiest way to use these models is to use them in a ListView as illustrated by the + following code snippet: + + \code + ListView { + id: historyItemsList + anchors.fill: parent + model: webEngineView.navigationHistory.items + delegate: + Text { + color: "black" + text: model.title + " - " + model.url + " (" + model.offset + ")" + } + } + \endcode + + The ListView shows the content of the corresponding model. The delegate is responsible for the + format of the list items. The appearance of each item of the list in the delegate can be defined + separately (it is not web engine specific). + + The model roles \e title and \e url specify the title and URL of the visited page. The \e offset + role specifies the position of the page in respect to the current page (0). A positive number + indicates that the page was visited after the current page, whereas a negative number indicates + that the page was visited before the current page. + + The data models can also be used to create a menu, as illustrated by the following code + snippet: + + \quotefromfile webengine/quicknanobrowser/browserwindow.qml + \skipto ToolBar + \printuntil onObjectRemoved + \printuntil } + \printuntil } + \printuntil } + + For the complete example, see \l{WebEngine Quick Nano Browser}. + + \sa WebEngineHistoryListModel +*/ + QQuickWebEngineHistory::QQuickWebEngineHistory(QQuickWebEngineViewPrivate *view) : d_ptr(new QQuickWebEngineHistoryPrivate(view)) { @@ -194,6 +275,13 @@ QQuickWebEngineHistory::~QQuickWebEngineHistory() { } +/*! + \qmlproperty QQuickWebEngineHistoryListModel WebEngineHistory::items + \readonly + \since QtWebEngine 1.1 + + URLs of back items, forward items, and the current item in the history. +*/ QQuickWebEngineHistoryListModel *QQuickWebEngineHistory::items() const { Q_D(const QQuickWebEngineHistory); @@ -202,6 +290,13 @@ QQuickWebEngineHistoryListModel *QQuickWebEngineHistory::items() const return d->m_navigationModel.data(); } +/*! + \qmlproperty QQuickWebEngineHistoryListModel WebEngineHistory::backItems + \readonly + \since QtWebEngine 1.1 + + URLs of visited pages. +*/ QQuickWebEngineHistoryListModel *QQuickWebEngineHistory::backItems() const { Q_D(const QQuickWebEngineHistory); @@ -210,6 +305,13 @@ QQuickWebEngineHistoryListModel *QQuickWebEngineHistory::backItems() const return d->m_backNavigationModel.data(); } +/*! + \qmlproperty QQuickWebEngineHistoryListModel WebEngineHistory::forwardItems + \readonly + \since QtWebEngine 1.1 + + URLs of the pages that were visited after visiting the current page. +*/ QQuickWebEngineHistoryListModel *QQuickWebEngineHistory::forwardItems() const { Q_D(const QQuickWebEngineHistory); diff --git a/src/webengine/api/qquickwebenginenewviewrequest.cpp b/src/webengine/api/qquickwebenginenewviewrequest.cpp index f66a44e5f..6e20c0a46 100644 --- a/src/webengine/api/qquickwebenginenewviewrequest.cpp +++ b/src/webengine/api/qquickwebenginenewviewrequest.cpp @@ -89,7 +89,7 @@ bool QQuickWebEngineNewViewRequest::isUserInitiated() const */ void QQuickWebEngineNewViewRequest::openIn(QQuickWebEngineView *view) { - if (!m_adapter) { + if (!m_adapter && !m_requestedUrl.isValid()) { qWarning("Trying to open an empty request, it was either already used or was invalidated." "\nYou must complete the request synchronously within the newViewRequested signal handler." " If a view hasn't been adopted before returning, the request will be invalidated."); @@ -100,6 +100,9 @@ void QQuickWebEngineNewViewRequest::openIn(QQuickWebEngineView *view) qWarning("Trying to open a WebEngineNewViewRequest in an invalid WebEngineView."); return; } - view->d_func()->adoptWebContents(m_adapter.data()); + if (m_adapter) + view->d_func()->adoptWebContents(m_adapter.data()); + else + view->setUrl(m_requestedUrl); m_adapter.reset(); } diff --git a/src/webengine/api/qquickwebenginenewviewrequest_p.h b/src/webengine/api/qquickwebenginenewviewrequest_p.h index f9fac13e9..b408812ba 100644 --- a/src/webengine/api/qquickwebenginenewviewrequest_p.h +++ b/src/webengine/api/qquickwebenginenewviewrequest_p.h @@ -73,6 +73,8 @@ private: QQuickWebEngineView::NewViewDestination m_destination; bool m_isUserInitiated; QExplicitlySharedDataPointer<QtWebEngineCore::WebContentsAdapter> m_adapter; + QUrl m_requestedUrl; + friend class QQuickWebEngineView; friend class QQuickWebEngineViewPrivate; }; diff --git a/src/webengine/api/qquickwebengineprofile.cpp b/src/webengine/api/qquickwebengineprofile.cpp index 68884f967..a678fe5fa 100644 --- a/src/webengine/api/qquickwebengineprofile.cpp +++ b/src/webengine/api/qquickwebengineprofile.cpp @@ -40,6 +40,7 @@ #include "qquickwebenginedownloaditem_p_p.h" #include "qquickwebengineprofile_p_p.h" #include "qquickwebenginesettings_p.h" +#include "qwebenginecookiestoreclient.h" #include <QQmlEngine> @@ -56,6 +57,9 @@ QQuickWebEngineProfilePrivate::QQuickWebEngineProfilePrivate(BrowserContextAdapt { m_browserContextRef->addClient(this); m_settings->d_ptr->initDefaults(browserContext->isOffTheRecord()); + // Fullscreen API was implemented before the supported setting, so we must + // make it default true to avoid change in default API behavior. + m_settings->d_ptr->setAttribute(QtWebEngineCore::WebEngineSettings::FullScreenSupportEnabled, true); } QQuickWebEngineProfilePrivate::~QQuickWebEngineProfilePrivate() @@ -131,10 +135,11 @@ void QQuickWebEngineProfilePrivate::downloadUpdated(const DownloadItemInfo &info \instantiates QQuickWebEngineProfile \inqmlmodule QtWebEngine 1.1 \since QtWebEngine 1.1 - \brief Contains common settings for multiple web engine views. + \brief Contains settings, scripts, and visited links common to multiple web engine views. - Contains settings and history shared by all the web engine views that belong - to the profile. + WebEngineProfile contains settings, scripts, and the list of visited links shared by all + views that belong to the profile. As such, profiles can be used to isolate views + from each other. A typical use case is a dedicated profile for a 'private browsing' mode. Each web engine view has an associated profile. Views that do not have a specific profile set share a common default one. @@ -384,6 +389,28 @@ void QQuickWebEngineProfile::setHttpCacheMaximumSize(int maximumSize) emit httpCacheMaximumSizeChanged(); } +/*! + \qmlproperty QString WebEngineProfile::httpAcceptLanguage + + The value of the Accept-Language HTTP request-header field. + + \since QtWebEngine 1.2 +*/ +QString QQuickWebEngineProfile::httpAcceptLanguage() const +{ + Q_D(const QQuickWebEngineProfile); + return d->browserContext()->httpAcceptLanguage(); +} + +void QQuickWebEngineProfile::setHttpAcceptLanguage(const QString &httpAcceptLanguage) +{ + Q_D(QQuickWebEngineProfile); + if (d->browserContext()->httpAcceptLanguage() == httpAcceptLanguage) + return; + d->browserContext()->setHttpAcceptLanguage(httpAcceptLanguage); + emit httpAcceptLanguageChanged(); +} + QQuickWebEngineProfile *QQuickWebEngineProfile::defaultProfile() { static QQuickWebEngineProfile *profile = new QQuickWebEngineProfile( @@ -392,6 +419,12 @@ QQuickWebEngineProfile *QQuickWebEngineProfile::defaultProfile() return profile; } +QWebEngineCookieStoreClient *QQuickWebEngineProfile::cookieStoreClient() const +{ + const Q_D(QQuickWebEngineProfile); + return d->browserContext()->cookieStoreClient(); +} + QQuickWebEngineSettings *QQuickWebEngineProfile::settings() const { const Q_D(QQuickWebEngineProfile); diff --git a/src/webengine/api/qquickwebengineprofile_p.h b/src/webengine/api/qquickwebengineprofile_p.h index 323721bd0..b4e0d173c 100644 --- a/src/webengine/api/qquickwebengineprofile_p.h +++ b/src/webengine/api/qquickwebengineprofile_p.h @@ -63,6 +63,7 @@ QT_BEGIN_NAMESPACE class QQuickWebEngineDownloadItem; class QQuickWebEngineProfilePrivate; class QQuickWebEngineSettings; +class QWebEngineCookieStoreClient; class Q_WEBENGINE_PRIVATE_EXPORT QQuickWebEngineProfile : public QObject { Q_OBJECT @@ -74,6 +75,7 @@ class Q_WEBENGINE_PRIVATE_EXPORT QQuickWebEngineProfile : public QObject { Q_PROPERTY(QString cachePath READ cachePath WRITE setCachePath NOTIFY cachePathChanged FINAL) Q_PROPERTY(QString httpUserAgent READ httpUserAgent WRITE setHttpUserAgent NOTIFY httpUserAgentChanged FINAL) Q_PROPERTY(HttpCacheType httpCacheType READ httpCacheType WRITE setHttpCacheType NOTIFY httpCacheTypeChanged FINAL) + Q_PROPERTY(QString httpAcceptLanguage READ httpAcceptLanguage WRITE setHttpAcceptLanguage NOTIFY httpAcceptLanguageChanged FINAL REVISION 1) Q_PROPERTY(PersistentCookiesPolicy persistentCookiesPolicy READ persistentCookiesPolicy WRITE setPersistentCookiesPolicy NOTIFY persistentCookiesPolicyChanged FINAL) Q_PROPERTY(int httpCacheMaximumSize READ httpCacheMaximumSize WRITE setHttpCacheMaximumSize NOTIFY httpCacheMaximumSizeChanged FINAL) public: @@ -115,8 +117,13 @@ public: int httpCacheMaximumSize() const; void setHttpCacheMaximumSize(int maxSize); + QString httpAcceptLanguage() const; + void setHttpAcceptLanguage(const QString &httpAcceptLanguage); + static QQuickWebEngineProfile *defaultProfile(); + Q_REVISION(1) Q_INVOKABLE QWebEngineCookieStoreClient *cookieStoreClient() const; + signals: void storageNameChanged(); void offTheRecordChanged(); @@ -126,6 +133,7 @@ signals: void httpCacheTypeChanged(); void persistentCookiesPolicyChanged(); void httpCacheMaximumSizeChanged(); + Q_REVISION(1) void httpAcceptLanguageChanged(); void downloadRequested(QQuickWebEngineDownloadItem *download); void downloadFinished(QQuickWebEngineDownloadItem *download); diff --git a/src/webengine/api/qquickwebenginesettings.cpp b/src/webengine/api/qquickwebenginesettings.cpp index 248713543..8f2e1bcf2 100644 --- a/src/webengine/api/qquickwebenginesettings.cpp +++ b/src/webengine/api/qquickwebenginesettings.cpp @@ -54,13 +54,15 @@ QQuickWebEngineSettings::QQuickWebEngineSettings(QQuickWebEngineSettings *parent \instantiates QQuickWebEngineSettings \inqmlmodule QtWebEngine \since QtWebEngine 1.1 - \brief WebEngineSettings allows configuration of browser properties and attributes. + \brief Allows configuration of browser properties and attributes. - WebEngineSettings allows configuration of browser properties and generic attributes, such as - JavaScript support, focus behavior, and access to remote content. - - Each WebEngineView can have individual settings. + The WebEngineSettings type can be used to configure browser properties and generic + attributes, such as JavaScript support, focus behavior, and access to remote content. This type + is uncreatable, but the default settings for all web engine views can be accessed by using + the \l [QML] {WebEngine::settings}{WebEngine.settings} property. + Each web engine view can have individual settings that can be accessed by using the + \l{WebEngineView::settings}{WebEngineView.settings} property. */ @@ -206,6 +208,31 @@ bool QQuickWebEngineSettings::errorPageEnabled() const } /*! + \qmlproperty bool WebEngineSettings::pluginsEnabled + + Enables support for Pepper plugins, such as the Flash player. + + Disabled by default. +*/ +bool QQuickWebEngineSettings::pluginsEnabled() const +{ + return d_ptr->testAttribute(WebEngineSettings::PluginsEnabled); +} + +/*! + \qmlproperty bool WebEngineSettings::fullscreenSupportEnabled + \since QtWebEngine 1.2 + + Tells the web engine whether fullscreen is supported in this application or not. + + Enabled by default. +*/ +bool QQuickWebEngineSettings::fullScreenSupportEnabled() const +{ + return d_ptr->testAttribute(WebEngineSettings::FullScreenSupportEnabled); +} + +/*! \qmlproperty QString WebEngineSettings::defaultTextEncoding Sets the default encoding. The value must be a string describing an encoding such as "utf-8" or @@ -309,6 +336,22 @@ void QQuickWebEngineSettings::setErrorPageEnabled(bool on) Q_EMIT errorPageEnabledChanged(); } +void QQuickWebEngineSettings::setPluginsEnabled(bool on) +{ + bool wasOn = d_ptr->testAttribute(WebEngineSettings::PluginsEnabled); + d_ptr->setAttribute(WebEngineSettings::PluginsEnabled, on); + if (wasOn != on) + Q_EMIT pluginsEnabledChanged(); +} + +void QQuickWebEngineSettings::setFullScreenSupportEnabled(bool on) +{ + bool wasOn = d_ptr->testAttribute(WebEngineSettings::FullScreenSupportEnabled); + d_ptr->setAttribute(WebEngineSettings::FullScreenSupportEnabled, on); + if (wasOn != on) + Q_EMIT fullScreenSupportEnabledChanged(); +} + void QQuickWebEngineSettings::setDefaultTextEncoding(QString encoding) { const QString oldDefaultTextEncoding = d_ptr->defaultTextEncoding(); diff --git a/src/webengine/api/qquickwebenginesettings_p.h b/src/webengine/api/qquickwebenginesettings_p.h index 213505078..030762ed3 100644 --- a/src/webengine/api/qquickwebenginesettings_p.h +++ b/src/webengine/api/qquickwebenginesettings_p.h @@ -71,6 +71,9 @@ class Q_WEBENGINE_PRIVATE_EXPORT QQuickWebEngineSettings : public QObject { Q_PROPERTY(bool localContentCanAccessFileUrls READ localContentCanAccessFileUrls WRITE setLocalContentCanAccessFileUrls NOTIFY localContentCanAccessFileUrlsChanged) Q_PROPERTY(bool hyperlinkAuditingEnabled READ hyperlinkAuditingEnabled WRITE setHyperlinkAuditingEnabled NOTIFY hyperlinkAuditingEnabledChanged) Q_PROPERTY(bool errorPageEnabled READ errorPageEnabled WRITE setErrorPageEnabled NOTIFY errorPageEnabledChanged) + Q_PROPERTY(bool pluginsEnabled READ pluginsEnabled WRITE setPluginsEnabled NOTIFY pluginsEnabledChanged) + // FIXME(QTBUG-40043): Mark fullScreenSupportEnabled with REVISION 1 + Q_PROPERTY(bool fullScreenSupportEnabled READ fullScreenSupportEnabled WRITE setFullScreenSupportEnabled NOTIFY fullScreenSupportEnabledChanged) Q_PROPERTY(QString defaultTextEncoding READ defaultTextEncoding WRITE setDefaultTextEncoding NOTIFY defaultTextEncodingChanged) public: @@ -87,6 +90,8 @@ public: bool localContentCanAccessFileUrls() const; bool hyperlinkAuditingEnabled() const; bool errorPageEnabled() const; + bool pluginsEnabled() const; + bool fullScreenSupportEnabled() const; QString defaultTextEncoding() const; void setAutoLoadImages(bool on); @@ -100,6 +105,8 @@ public: void setLocalContentCanAccessFileUrls(bool on); void setHyperlinkAuditingEnabled(bool on); void setErrorPageEnabled(bool on); + void setPluginsEnabled(bool on); + void setFullScreenSupportEnabled(bool on); void setDefaultTextEncoding(QString encoding); signals: @@ -114,6 +121,9 @@ signals: void localContentCanAccessFileUrlsChanged(); void hyperlinkAuditingEnabledChanged(); void errorPageEnabledChanged(); + void pluginsEnabledChanged(); + // FIXME(QTBUG-40043): Mark fullScreenSupportEnabledChanged with Q_REVISION(1) + void fullScreenSupportEnabledChanged(); void defaultTextEncodingChanged(); private: diff --git a/src/webengine/api/qquickwebenginesingleton.cpp b/src/webengine/api/qquickwebenginesingleton.cpp index 3f0c8cb65..7ff974eb4 100644 --- a/src/webengine/api/qquickwebenginesingleton.cpp +++ b/src/webengine/api/qquickwebenginesingleton.cpp @@ -41,11 +41,47 @@ QT_BEGIN_NAMESPACE +/*! + \qmltype WebEngine + \instantiates QQuickWebEngineSingleton + \inqmlmodule QtWebEngine 1.1 + \since QtWebEngine 1.1 + \brief Provides access to the default settings and profiles shared by all web engine views. + + The WebEngine singleton type provides access to the default profile and the default settings + shared by all web engine views. It can be used to change settings globally, as illustrated by + the following code snippet: + + \code + Component.onCompleted: { + WebEngine.settings.javaScriptEnabled = true; + } + \endcode +*/ + +/*! + \qmlproperty WebEngineSettings WebEngine::settings + \readonly + \since QtWebEngine 1.1 + + Default settings for all web engine views. + + \sa WebEngineSettings +*/ QQuickWebEngineSettings *QQuickWebEngineSingleton::settings() const { return defaultProfile()->settings(); } +/*! + \qmlproperty WebEngineProfile WebEngine::defaultProfile + \readonly + \since QtWebEngine 1.1 + + Default profile for all web engine views. + + \sa WebEngineProfile +*/ QQuickWebEngineProfile *QQuickWebEngineSingleton::defaultProfile() const { return QQuickWebEngineProfile::defaultProfile(); diff --git a/src/webengine/api/qquickwebenginetestsupport_p.h b/src/webengine/api/qquickwebenginetestsupport_p.h index 8d52dfa7c..d4b50ac2d 100644 --- a/src/webengine/api/qquickwebenginetestsupport_p.h +++ b/src/webengine/api/qquickwebenginetestsupport_p.h @@ -78,6 +78,10 @@ public: QQuickWebEngineTestSupport(); QQuickWebEngineErrorPage *errorPage() const; +Q_SIGNALS: + void validationMessageShown(const QString &mainText, const QString &subText); + void windowCloseRejected(); + private: QScopedPointer<QQuickWebEngineErrorPage> m_errorPage; }; diff --git a/src/webengine/api/qquickwebengineview.cpp b/src/webengine/api/qquickwebengineview.cpp index 6c3452a6a..52245e147 100644 --- a/src/webengine/api/qquickwebengineview.cpp +++ b/src/webengine/api/qquickwebengineview.cpp @@ -37,8 +37,10 @@ #include "qquickwebengineview_p.h" #include "qquickwebengineview_p_p.h" +#include "authentication_dialog_controller.h" #include "browser_context_adapter.h" #include "certificate_error_controller.h" +#include "file_picker_controller.h" #include "javascript_dialog_controller.h" #include "qquickwebenginehistory_p.h" #include "qquickwebenginecertificateerror_p.h" @@ -63,7 +65,9 @@ #include "web_engine_settings.h" #include "web_engine_visited_links_manager.h" +#include <QClipboard> #include <QGuiApplication> +#include <QMimeData> #include <QQmlComponent> #include <QQmlContext> #include <QQmlEngine> @@ -102,8 +106,10 @@ QQuickWebEngineViewPrivate::QQuickWebEngineViewPrivate() , loadProgress(0) , m_isFullScreen(false) , isLoading(false) + , m_activeFocusOnPress(true) , devicePixelRatio(QGuiApplication::primaryScreen()->devicePixelRatio()) , m_dpiScale(1.0) + , m_backgroundColor(Qt::white) { // The gold standard for mobile web content is 160 dpi, and the devicePixelRatio expected // is the (possibly quantized) ratio of device dpi to 160 dpi. @@ -175,31 +181,101 @@ bool QQuickWebEngineViewPrivate::contextMenuRequested(const WebEngineContextMenu if (!menu) return false; + contextMenuData = data; + // Populate our menu MenuItemHandler *item = 0; + if (!data.linkText.isEmpty() && data.linkUrl.isValid()) { + item = new MenuItemHandler(menu); + QObject::connect(item, &MenuItemHandler::triggered, [q] { q->triggerWebAction(QQuickWebEngineView::OpenLinkInThisWindow); }); + ui()->addMenuItem(item, QQuickWebEngineView::tr("Follow Link")); + } + if (data.selectedText.isEmpty()) { item = new MenuItemHandler(menu); QObject::connect(item, &MenuItemHandler::triggered, q, &QQuickWebEngineView::goBack); - ui()->addMenuItem(item, QObject::tr("Back"), QStringLiteral("go-previous"), q->canGoBack()); + ui()->addMenuItem(item, QQuickWebEngineView::tr("Back"), QStringLiteral("go-previous"), q->canGoBack()); item = new MenuItemHandler(menu); QObject::connect(item, &MenuItemHandler::triggered, q, &QQuickWebEngineView::goForward); - ui()->addMenuItem(item, QObject::tr("Forward"), QStringLiteral("go-next"), q->canGoForward()); + ui()->addMenuItem(item, QQuickWebEngineView::tr("Forward"), QStringLiteral("go-next"), q->canGoForward()); item = new MenuItemHandler(menu); QObject::connect(item, &MenuItemHandler::triggered, q, &QQuickWebEngineView::reload); - ui()->addMenuItem(item, QObject::tr("Reload"), QStringLiteral("view-refresh")); + ui()->addMenuItem(item, QQuickWebEngineView::tr("Reload"), QStringLiteral("view-refresh")); } else { - item = new CopyMenuItem(menu, data.selectedText); - ui()->addMenuItem(item, QObject::tr("Copy...")); + item = new MenuItemHandler(menu); + QObject::connect(item, &MenuItemHandler::triggered, [q] { q->triggerWebAction(QQuickWebEngineView::Copy); }); + ui()->addMenuItem(item, QQuickWebEngineView::tr("Copy")); } - if (!data.linkText.isEmpty() && data.linkUrl.isValid()) { - item = new NavigateMenuItem(menu, adapter, data.linkUrl); - ui()->addMenuItem(item, QObject::tr("Navigate to...")); - item = new CopyMenuItem(menu, data.linkUrl.toString()); - ui()->addMenuItem(item, QObject::tr("Copy link address")); + if (!contextMenuData.linkText.isEmpty() && contextMenuData.linkUrl.isValid()) { + item = new MenuItemHandler(menu); + QObject::connect(item, &MenuItemHandler::triggered, [q] { q->triggerWebAction(QQuickWebEngineView::CopyLinkToClipboard); }); + ui()->addMenuItem(item, QQuickWebEngineView::tr("Copy Link URL")); + item = new MenuItemHandler(menu); + QObject::connect(item, &MenuItemHandler::triggered, [q] { q->triggerWebAction(QQuickWebEngineView::DownloadLinkToDisk); }); + ui()->addMenuItem(item, QQuickWebEngineView::tr("Save Link")); + } + if (contextMenuData.mediaUrl.isValid()) { + switch (contextMenuData.mediaType) { + case WebEngineContextMenuData::MediaTypeImage: + item = new MenuItemHandler(menu); + QObject::connect(item, &MenuItemHandler::triggered, [q] { q->triggerWebAction(QQuickWebEngineView::CopyImageUrlToClipboard); }); + ui()->addMenuItem(item, QQuickWebEngineView::tr("Copy Image URL")); + item = new MenuItemHandler(menu); + QObject::connect(item, &MenuItemHandler::triggered, [q] { q->triggerWebAction(QQuickWebEngineView::CopyImageToClipboard); }); + ui()->addMenuItem(item, QQuickWebEngineView::tr("Copy Image")); + item = new MenuItemHandler(menu); + QObject::connect(item, &MenuItemHandler::triggered, [q] { q->triggerWebAction(QQuickWebEngineView::DownloadImageToDisk); }); + ui()->addMenuItem(item, QQuickWebEngineView::tr("Save Image")); + break; + case WebEngineContextMenuData::MediaTypeCanvas: + Q_UNREACHABLE(); // mediaUrl is invalid for canvases + break; + case WebEngineContextMenuData::MediaTypeAudio: + case WebEngineContextMenuData::MediaTypeVideo: + item = new MenuItemHandler(menu); + QObject::connect(item, &MenuItemHandler::triggered, [q] { q->triggerWebAction(QQuickWebEngineView::CopyMediaUrlToClipboard); }); + ui()->addMenuItem(item, QQuickWebEngineView::tr("Copy Media URL")); + item = new MenuItemHandler(menu); + QObject::connect(item, &MenuItemHandler::triggered, [q] { q->triggerWebAction(QQuickWebEngineView::DownloadMediaToDisk); }); + ui()->addMenuItem(item, QQuickWebEngineView::tr("Save Media")); + item = new MenuItemHandler(menu); + QObject::connect(item, &MenuItemHandler::triggered, [q] { q->triggerWebAction(QQuickWebEngineView::ToggleMediaPlayPause); }); + ui()->addMenuItem(item, QQuickWebEngineView::tr("Toggle Play/Pause")); + item = new MenuItemHandler(menu); + QObject::connect(item, &MenuItemHandler::triggered, [q] { q->triggerWebAction(QQuickWebEngineView::ToggleMediaLoop); }); + ui()->addMenuItem(item, QQuickWebEngineView::tr("Toggle Looping")); + if (contextMenuData.mediaFlags & WebEngineContextMenuData::MediaHasAudio) { + item = new MenuItemHandler(menu); + QObject::connect(item, &MenuItemHandler::triggered, [q] { q->triggerWebAction(QQuickWebEngineView::ToggleMediaMute); }); + ui()->addMenuItem(item, QQuickWebEngineView::tr("Toggle Mute")); + } + if (contextMenuData.mediaFlags & WebEngineContextMenuData::MediaCanToggleControls) { + item = new MenuItemHandler(menu); + QObject::connect(item, &MenuItemHandler::triggered, [q] { q->triggerWebAction(QQuickWebEngineView::ToggleMediaControls); }); + ui()->addMenuItem(item, QQuickWebEngineView::tr("Toggle Media Controls")); + } + break; + default: + break; + } + } else if (contextMenuData.mediaType == WebEngineContextMenuData::MediaTypeCanvas) { + item = new MenuItemHandler(menu); + QObject::connect(item, &MenuItemHandler::triggered, [q] { q->triggerWebAction(QQuickWebEngineView::CopyImageToClipboard); }); + ui()->addMenuItem(item, QQuickWebEngineView::tr("Copy Image")); + } + if (adapter->hasInspector()) { + item = new MenuItemHandler(menu); + QObject::connect(item, &MenuItemHandler::triggered, [q] { q->triggerWebAction(QQuickWebEngineView::InspectElement); }); + ui()->addMenuItem(item, QQuickWebEngineView::tr("Inspect Element")); + } + if (isFullScreenMode()) { + item = new MenuItemHandler(menu); + QObject::connect(item, &MenuItemHandler::triggered, [q] { q->triggerWebAction(QQuickWebEngineView::ExitFullScreen); }); + ui()->addMenuItem(item, QQuickWebEngineView::tr("Exit Full Screen Mode")); } // FIXME: expose the context menu data as an attached property to make this more useful @@ -251,9 +327,9 @@ void QQuickWebEngineViewPrivate::runGeolocationPermissionRequest(const QUrl &url Q_EMIT q->featurePermissionRequested(url, QQuickWebEngineView::Geolocation); } -void QQuickWebEngineViewPrivate::runFileChooser(FileChooserMode mode, const QString &defaultFileName, const QStringList &acceptedMimeTypes) +void QQuickWebEngineViewPrivate::runFileChooser(FilePickerController* controller) { - ui()->showFilePicker(mode, defaultFileName, acceptedMimeTypes, adapter); + ui()->showFilePicker(controller); } void QQuickWebEngineViewPrivate::passOnFocus(bool reverse) @@ -310,6 +386,11 @@ qreal QQuickWebEngineViewPrivate::dpiScale() const return m_dpiScale; } +QColor QQuickWebEngineViewPrivate::backgroundColor() const +{ + return m_backgroundColor; +} + void QQuickWebEngineViewPrivate::loadStarted(const QUrl &provisionalUrl, bool isErrorPage) { Q_Q(QQuickWebEngineView); @@ -423,17 +504,26 @@ void QQuickWebEngineViewPrivate::adoptNewWindow(WebContentsAdapter *newWebConten void QQuickWebEngineViewPrivate::close() { - // Not implemented yet. + Q_Q(QQuickWebEngineView); + emit q->windowCloseRequested(); } -void QQuickWebEngineViewPrivate::requestFullScreen(bool fullScreen) +void QQuickWebEngineViewPrivate::windowCloseRejected() +{ +#ifdef ENABLE_QML_TESTSUPPORT_API + if (m_testSupport) + Q_EMIT m_testSupport->windowCloseRejected(); +#endif +} + +void QQuickWebEngineViewPrivate::requestFullScreenMode(const QUrl &origin, bool fullscreen) { Q_Q(QQuickWebEngineView); - QQuickWebEngineFullScreenRequest request(this, fullScreen); + QQuickWebEngineFullScreenRequest request(this, origin, fullscreen); Q_EMIT q->fullScreenRequested(request); } -bool QQuickWebEngineViewPrivate::isFullScreen() const +bool QQuickWebEngineViewPrivate::isFullScreenMode() const { return m_isFullScreen; } @@ -444,6 +534,11 @@ void QQuickWebEngineViewPrivate::javaScriptConsoleMessage(JavaScriptConsoleMessa Q_EMIT q->javaScriptConsoleMessage(static_cast<QQuickWebEngineView::JavaScriptConsoleMessageLevel>(level), message, lineNumber, sourceID); } +void QQuickWebEngineViewPrivate::authenticationRequired(QSharedPointer<AuthenticationDialogController> controller) +{ + ui()->showDialog(controller); +} + void QQuickWebEngineViewPrivate::runMediaAccessPermissionRequest(const QUrl &securityOrigin, WebContentsAdapterClient::MediaRequestFlags requestFlags) { Q_Q(QQuickWebEngineView); @@ -581,7 +676,7 @@ QQuickWebEngineView::QQuickWebEngineView(QQuickItem *parent) Q_D(QQuickWebEngineView); d->e->q_ptr = d->q_ptr = this; this->setActiveFocusOnTab(true); - this->setFlag(QQuickItem::ItemIsFocusScope); + this->setFlags(QQuickItem::ItemIsFocusScope | QQuickItem::ItemAcceptsInputMethod); #ifndef QT_NO_ACCESSIBILITY QQuickAccessibleAttached *accessible = QQuickAccessibleAttached::qmlAttachedProperties(this); @@ -754,8 +849,23 @@ void QQuickWebEngineView::setTestSupport(QQuickWebEngineTestSupport *testSupport Q_D(QQuickWebEngineView); d->m_testSupport = testSupport; } + #endif +/*! + * \qmlproperty bool WebEngineView::activeFocusOnPress + * \since QtWebEngine 1.2 + * + * This property specifies whether the view should gain active focus when pressed. + * The default value is true. + * + */ +bool QQuickWebEngineView::activeFocusOnPress() const +{ + Q_D(const QQuickWebEngineView); + return d->m_activeFocusOnPress; +} + void QQuickWebEngineViewPrivate::didRunJavaScript(quint64 requestId, const QVariant &result) { Q_Q(QQuickWebEngineView); @@ -774,6 +884,11 @@ void QQuickWebEngineViewPrivate::didFindText(quint64 requestId, int matchCount) } void QQuickWebEngineViewPrivate::showValidationMessage(const QRect &anchor, const QString &mainText, const QString &subText) { +#ifdef ENABLE_QML_TESTSUPPORT_API + if (m_testSupport) + Q_EMIT m_testSupport->validationMessageShown(mainText, subText); +#endif + ui()->showMessageBubble(anchor, mainText, subText); } @@ -787,6 +902,14 @@ void QQuickWebEngineViewPrivate::moveValidationMessage(const QRect &anchor) ui()->moveMessageBubble(anchor); } +void QQuickWebEngineViewPrivate::renderProcessTerminated( + RenderProcessTerminationStatus terminationStatus, int exitCode) +{ + Q_Q(QQuickWebEngineView); + Q_EMIT q->renderProcessTerminated(static_cast<QQuickWebEngineView::RenderProcessTerminationStatus>( + renderProcessExitStatus(terminationStatus)), exitCode); +} + bool QQuickWebEngineView::isLoading() const { Q_D(const QQuickWebEngineView); @@ -849,6 +972,34 @@ qreal QQuickWebEngineView::zoomFactor() const return d->adapter->currentZoomFactor(); } +/*! + \qmlproperty bool WebEngineView::backgroundColor + \since QtWebEngine 1.2 + + Sets this property to change the color of the WebEngineView's background, + behing the document's body. You can set it to "transparent" or to a translucent + color to see through the document, or you can set this color to match your + web content in an hybrid app to prevent the white flashes that may appear + during loading. + + The default value is white. +*/ +QColor QQuickWebEngineView::backgroundColor() const +{ + Q_D(const QQuickWebEngineView); + return d->m_backgroundColor; +} + +void QQuickWebEngineView::setBackgroundColor(const QColor &color) +{ + Q_D(QQuickWebEngineView); + if (color == d->m_backgroundColor) + return; + d->m_backgroundColor = color; + d->ensureContentsAdapter(); + d->adapter->backgroundColorChanged(); + emit backgroundColorChanged(); +} bool QQuickWebEngineView::isFullScreen() const { @@ -943,6 +1094,16 @@ void QQuickWebEngineView::grantFeaturePermission(const QUrl &securityOrigin, QQu } } +void QQuickWebEngineView::setActiveFocusOnPress(bool arg) +{ + Q_D(QQuickWebEngineView); + if (d->m_activeFocusOnPress == arg) + return; + + d->m_activeFocusOnPress = arg; + emit activeFocusOnPressChanged(arg); +} + void QQuickWebEngineView::goBackOrForward(int offset) { Q_D(QQuickWebEngineView); @@ -988,6 +1149,171 @@ void QQuickWebEngineView::itemChange(ItemChange change, const ItemChangeData &va QQuickItem::itemChange(change, value); } +void QQuickWebEngineView::triggerWebAction(WebAction action) +{ + Q_D(QQuickWebEngineView); + switch (action) { + case Back: + d->adapter->navigateToOffset(-1); + break; + case Forward: + d->adapter->navigateToOffset(1); + break; + case Stop: + d->adapter->stop(); + break; + case Reload: + d->adapter->reload(); + break; + case ReloadAndBypassCache: + d->adapter->reloadAndBypassCache(); + break; + case Cut: + d->adapter->cut(); + break; + case Copy: + d->adapter->copy(); + break; + case Paste: + d->adapter->paste(); + break; + case Undo: + d->adapter->undo(); + break; + case Redo: + d->adapter->redo(); + break; + case SelectAll: + d->adapter->selectAll(); + break; + case PasteAndMatchStyle: + d->adapter->pasteAndMatchStyle(); + break; + case OpenLinkInThisWindow: + if (d->contextMenuData.linkUrl.isValid()) + setUrl(d->contextMenuData.linkUrl); + break; + case OpenLinkInNewWindow: + if (d->contextMenuData.linkUrl.isValid()) { + QQuickWebEngineNewViewRequest request; + request.m_requestedUrl = d->contextMenuData.linkUrl; + request.m_isUserInitiated = true; + request.m_destination = NewViewInWindow; + Q_EMIT newViewRequested(&request); + } + break; + case OpenLinkInNewTab: + if (d->contextMenuData.linkUrl.isValid()) { + QQuickWebEngineNewViewRequest request; + request.m_requestedUrl = d->contextMenuData.linkUrl; + request.m_isUserInitiated = true; + request.m_destination = NewViewInBackgroundTab; + Q_EMIT newViewRequested(&request); + } + break; + case CopyLinkToClipboard: + if (d->contextMenuData.linkUrl.isValid()) { + QString urlString = d->contextMenuData.linkUrl.toString(QUrl::FullyEncoded); + QString title = d->contextMenuData.linkText.toHtmlEscaped(); + QMimeData *data = new QMimeData(); + data->setText(urlString); + QString html = QStringLiteral("<a href=\"") + urlString + QStringLiteral("\">") + title + QStringLiteral("</a>"); + data->setHtml(html); + data->setUrls(QList<QUrl>() << d->contextMenuData.linkUrl); + qApp->clipboard()->setMimeData(data); + } + break; + case DownloadLinkToDisk: + if (d->contextMenuData.linkUrl.isValid()) + d->adapter->download(d->contextMenuData.linkUrl, d->contextMenuData.suggestedFileName); + break; + case CopyImageToClipboard: + if (d->contextMenuData.hasImageContent && + (d->contextMenuData.mediaType == WebEngineContextMenuData::MediaTypeImage || + d->contextMenuData.mediaType == WebEngineContextMenuData::MediaTypeCanvas)) + { + d->adapter->copyImageAt(d->contextMenuData.pos); + } + break; + case CopyImageUrlToClipboard: + if (d->contextMenuData.mediaUrl.isValid() && d->contextMenuData.mediaType == WebEngineContextMenuData::MediaTypeImage) { + QString urlString = d->contextMenuData.mediaUrl.toString(QUrl::FullyEncoded); + QString title = d->contextMenuData.linkText; + if (!title.isEmpty()) + title = QStringLiteral(" alt=\"%1\"").arg(title.toHtmlEscaped()); + QMimeData *data = new QMimeData(); + data->setText(urlString); + QString html = QStringLiteral("<img src=\"") + urlString + QStringLiteral("\"") + title + QStringLiteral("></img>"); + data->setHtml(html); + data->setUrls(QList<QUrl>() << d->contextMenuData.mediaUrl); + qApp->clipboard()->setMimeData(data); + } + break; + case DownloadImageToDisk: + case DownloadMediaToDisk: + if (d->contextMenuData.mediaUrl.isValid()) + d->adapter->download(d->contextMenuData.mediaUrl, d->contextMenuData.suggestedFileName); + break; + case CopyMediaUrlToClipboard: + if (d->contextMenuData.mediaUrl.isValid() && + (d->contextMenuData.mediaType == WebEngineContextMenuData::MediaTypeAudio || + d->contextMenuData.mediaType == WebEngineContextMenuData::MediaTypeVideo)) + { + QString urlString = d->contextMenuData.mediaUrl.toString(QUrl::FullyEncoded); + QMimeData *data = new QMimeData(); + data->setText(urlString); + if (d->contextMenuData.mediaType == WebEngineContextMenuData::MediaTypeAudio) + data->setHtml(QStringLiteral("<audio src=\"") + urlString + QStringLiteral("\"></audio>")); + else + data->setHtml(QStringLiteral("<video src=\"") + urlString + QStringLiteral("\"></video>")); + data->setUrls(QList<QUrl>() << d->contextMenuData.mediaUrl); + qApp->clipboard()->setMimeData(data); + } + break; + case ToggleMediaControls: + if (d->contextMenuData.mediaUrl.isValid() && d->contextMenuData.mediaFlags & WebEngineContextMenuData::MediaCanToggleControls) { + bool enable = !(d->contextMenuData.mediaFlags & WebEngineContextMenuData::MediaControls); + d->adapter->executeMediaPlayerActionAt(d->contextMenuData.pos, WebContentsAdapter::MediaPlayerControls, enable); + } + break; + case ToggleMediaLoop: + if (d->contextMenuData.mediaUrl.isValid() && + (d->contextMenuData.mediaType == WebEngineContextMenuData::MediaTypeAudio || + d->contextMenuData.mediaType == WebEngineContextMenuData::MediaTypeVideo)) + { + bool enable = !(d->contextMenuData.mediaFlags & WebEngineContextMenuData::MediaLoop); + d->adapter->executeMediaPlayerActionAt(d->contextMenuData.pos, WebContentsAdapter::MediaPlayerLoop, enable); + } + break; + case ToggleMediaPlayPause: + if (d->contextMenuData.mediaUrl.isValid() && + (d->contextMenuData.mediaType == WebEngineContextMenuData::MediaTypeAudio || + d->contextMenuData.mediaType == WebEngineContextMenuData::MediaTypeVideo)) + { + bool enable = (d->contextMenuData.mediaFlags & WebEngineContextMenuData::MediaPaused); + d->adapter->executeMediaPlayerActionAt(d->contextMenuData.pos, WebContentsAdapter::MediaPlayerPlay, enable); + } + break; + case ToggleMediaMute: + if (d->contextMenuData.mediaUrl.isValid() && d->contextMenuData.mediaFlags & WebEngineContextMenuData::MediaHasAudio) { + bool enable = (d->contextMenuData.mediaFlags & WebEngineContextMenuData::MediaMuted); + d->adapter->executeMediaPlayerActionAt(d->contextMenuData.pos, WebContentsAdapter::MediaPlayerMute, enable); + } + break; + case InspectElement: + d->adapter->inspectElementAt(d->contextMenuData.pos); + break; + case ExitFullScreen: + d->adapter->exitFullScreen(); + break; + case RequestClose: + d->adapter->requestClose(); + break; + default: + Q_UNREACHABLE(); + } +} + void QQuickWebEngineViewPrivate::userScripts_append(QQmlListProperty<QQuickWebEngineScript> *p, QQuickWebEngineScript *script) { Q_ASSERT(p && p->data); @@ -1036,8 +1362,9 @@ QQuickWebEngineFullScreenRequest::QQuickWebEngineFullScreenRequest() { } -QQuickWebEngineFullScreenRequest::QQuickWebEngineFullScreenRequest(QQuickWebEngineViewPrivate *viewPrivate, bool toggleOn) +QQuickWebEngineFullScreenRequest::QQuickWebEngineFullScreenRequest(QQuickWebEngineViewPrivate *viewPrivate, const QUrl &origin, bool toggleOn) : viewPrivate(viewPrivate) + , m_origin(origin) , m_toggleOn(toggleOn) { } @@ -1046,10 +1373,18 @@ void QQuickWebEngineFullScreenRequest::accept() { if (viewPrivate && viewPrivate->m_isFullScreen != m_toggleOn) { viewPrivate->m_isFullScreen = m_toggleOn; + viewPrivate->adapter->changedFullScreen(); Q_EMIT viewPrivate->q_ptr->isFullScreenChanged(); } } +void QQuickWebEngineFullScreenRequest::reject() +{ + if (viewPrivate) { + viewPrivate->adapter->changedFullScreen(); + } +} + QQuickWebEngineViewExperimental::QQuickWebEngineViewExperimental(QQuickWebEngineViewPrivate *viewPrivate) : q_ptr(0) , d_ptr(viewPrivate) diff --git a/src/webengine/api/qquickwebengineview_p.h b/src/webengine/api/qquickwebengineview_p.h index f85bf64ad..ddc656a58 100644 --- a/src/webengine/api/qquickwebengineview_p.h +++ b/src/webengine/api/qquickwebengineview_p.h @@ -71,19 +71,25 @@ class QQuickWebEngineTestSupport; class Q_WEBENGINE_PRIVATE_EXPORT QQuickWebEngineFullScreenRequest { Q_GADGET + Q_PROPERTY(QUrl origin READ origin) Q_PROPERTY(bool toggleOn READ toggleOn) public: QQuickWebEngineFullScreenRequest(); - QQuickWebEngineFullScreenRequest(QQuickWebEngineViewPrivate *viewPrivate, bool toggleOn); + QQuickWebEngineFullScreenRequest(QQuickWebEngineViewPrivate *viewPrivate, const QUrl &origin, bool toggleOn); Q_INVOKABLE void accept(); - bool toggleOn() { return m_toggleOn; } + Q_INVOKABLE void reject(); + QUrl origin() const { return m_origin; } + bool toggleOn() const { return m_toggleOn; } private: QQuickWebEngineViewPrivate *viewPrivate; - bool m_toggleOn; + const QUrl m_origin; + const bool m_toggleOn; }; +#define LATEST_WEBENGINEVIEW_REVISION 2 + class Q_WEBENGINE_PRIVATE_EXPORT QQuickWebEngineView : public QQuickItem { Q_OBJECT Q_PROPERTY(QUrl url READ url WRITE setUrl NOTIFY urlChanged) @@ -100,6 +106,8 @@ class Q_WEBENGINE_PRIVATE_EXPORT QQuickWebEngineView : public QQuickItem { Q_PROPERTY(QQuickWebEngineHistory *navigationHistory READ navigationHistory CONSTANT FINAL REVISION 1) Q_PROPERTY(QQmlWebChannel *webChannel READ webChannel WRITE setWebChannel NOTIFY webChannelChanged REVISION 1) Q_PROPERTY(QQmlListProperty<QQuickWebEngineScript> userScripts READ userScripts FINAL REVISION 1) + Q_PROPERTY(bool activeFocusOnPress READ activeFocusOnPress WRITE setActiveFocusOnPress NOTIFY activeFocusOnPressChanged REVISION 2) + Q_PROPERTY(QColor backgroundColor READ backgroundColor WRITE setBackgroundColor NOTIFY backgroundColorChanged REVISION 2) #ifdef ENABLE_QML_TESTSUPPORT_API Q_PROPERTY(QQuickWebEngineTestSupport *testSupport READ testSupport WRITE setTestSupport FINAL) @@ -112,7 +120,9 @@ class Q_WEBENGINE_PRIVATE_EXPORT QQuickWebEngineView : public QQuickItem { Q_ENUMS(NewViewDestination); Q_ENUMS(Feature); Q_ENUMS(JavaScriptConsoleMessageLevel); + Q_ENUMS(RenderProcessTerminationStatus); Q_FLAGS(FindFlags); + Q_ENUMS(WebAction); public: QQuickWebEngineView(QQuickItem *parent = 0); @@ -129,6 +139,8 @@ public: bool isFullScreen() const; qreal zoomFactor() const; void setZoomFactor(qreal arg); + QColor backgroundColor() const; + void setBackgroundColor(const QColor &color); QQuickWebEngineViewExperimental *experimental() const; @@ -181,6 +193,48 @@ public: Geolocation }; + enum WebAction { + NoWebAction = - 1, + Back, + Forward, + Stop, + Reload, + + Cut, + Copy, + Paste, + + Undo, + Redo, + SelectAll, + ReloadAndBypassCache, + + PasteAndMatchStyle, + + OpenLinkInThisWindow, + OpenLinkInNewWindow, + OpenLinkInNewTab, + CopyLinkToClipboard, + DownloadLinkToDisk, + + CopyImageToClipboard, + CopyImageUrlToClipboard, + DownloadImageToDisk, + + CopyMediaUrlToClipboard, + ToggleMediaControls, + ToggleMediaLoop, + ToggleMediaPlayPause, + ToggleMediaMute, + DownloadMediaToDisk, + + InspectElement, + ExitFullScreen, + RequestClose, + + WebActionCount + }; + // must match WebContentsAdapterClient::JavaScriptConsoleMessageLevel enum JavaScriptConsoleMessageLevel { InfoMessageLevel = 0, @@ -188,6 +242,14 @@ public: ErrorMessageLevel }; + // must match WebContentsAdapterClient::RenderProcessTerminationStatus + enum RenderProcessTerminationStatus { + NormalTerminationStatus = 0, + AbnormalTerminationStatus, + CrashedTerminationStatus, + KilledTerminationStatus + }; + enum FindFlag { FindBackward = 1, FindCaseSensitively = 2, @@ -211,6 +273,8 @@ public: void setTestSupport(QQuickWebEngineTestSupport *testSupport); #endif + bool activeFocusOnPress() const; + public Q_SLOTS: void runJavaScript(const QString&, const QJSValue & = QJSValue()); void loadHtml(const QString &html, const QUrl &baseUrl = QUrl()); @@ -223,6 +287,8 @@ public Q_SLOTS: Q_REVISION(1) void findText(const QString &subString, FindFlags options = 0, const QJSValue &callback = QJSValue()); Q_REVISION(1) void fullScreenCancelled(); Q_REVISION(1) void grantFeaturePermission(const QUrl &securityOrigin, Feature, bool granted); + Q_REVISION(2) void setActiveFocusOnPress(bool arg); + Q_REVISION(2) void triggerWebAction(WebAction action); Q_SIGNALS: void titleChanged(); @@ -241,7 +307,10 @@ Q_SIGNALS: Q_REVISION(1) void zoomFactorChanged(qreal arg); Q_REVISION(1) void profileChanged(); Q_REVISION(1) void webChannelChanged(); - + Q_REVISION(2) void activeFocusOnPressChanged(bool); + Q_REVISION(2) void backgroundColorChanged(); + Q_REVISION(2) void renderProcessTerminated(RenderProcessTerminationStatus terminationStatus, int exitCode); + Q_REVISION(2) void windowCloseRequested(); protected: void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry); diff --git a/src/webengine/api/qquickwebengineview_p_p.h b/src/webengine/api/qquickwebengineview_p_p.h index 60aa0d9f4..c2210850f 100644 --- a/src/webengine/api/qquickwebengineview_p_p.h +++ b/src/webengine/api/qquickwebengineview_p_p.h @@ -134,6 +134,7 @@ public: virtual void selectionChanged() Q_DECL_OVERRIDE { } virtual QRectF viewportRect() const Q_DECL_OVERRIDE; virtual qreal dpiScale() const Q_DECL_OVERRIDE; + virtual QColor backgroundColor() const Q_DECL_OVERRIDE; virtual void loadStarted(const QUrl &provisionalUrl, bool isErrorPage = false) Q_DECL_OVERRIDE; virtual void loadCommitted() Q_DECL_OVERRIDE; virtual void loadVisuallyCommitted() Q_DECL_OVERRIDE; @@ -142,19 +143,20 @@ public: virtual void unhandledKeyEvent(QKeyEvent *event) Q_DECL_OVERRIDE; virtual void adoptNewWindow(QtWebEngineCore::WebContentsAdapter *newWebContents, WindowOpenDisposition disposition, bool userGesture, const QRect &) Q_DECL_OVERRIDE; virtual void close() Q_DECL_OVERRIDE; - virtual void requestFullScreen(bool) Q_DECL_OVERRIDE; - virtual bool isFullScreen() const Q_DECL_OVERRIDE; + virtual void windowCloseRejected() Q_DECL_OVERRIDE; + virtual void requestFullScreenMode(const QUrl &origin, bool fullscreen) Q_DECL_OVERRIDE; + virtual bool isFullScreenMode() const Q_DECL_OVERRIDE; virtual bool contextMenuRequested(const QtWebEngineCore::WebEngineContextMenuData &) Q_DECL_OVERRIDE; virtual void navigationRequested(int navigationType, const QUrl &url, int &navigationRequestAction, bool isMainFrame) Q_DECL_OVERRIDE; virtual void javascriptDialog(QSharedPointer<QtWebEngineCore::JavaScriptDialogController>) Q_DECL_OVERRIDE; - virtual void runFileChooser(FileChooserMode, const QString &defaultFileName, const QStringList &acceptedMimeTypes) Q_DECL_OVERRIDE; + virtual void runFileChooser(QtWebEngineCore::FilePickerController *controller) Q_DECL_OVERRIDE; virtual void didRunJavaScript(quint64, const QVariant&) Q_DECL_OVERRIDE; virtual void didFetchDocumentMarkup(quint64, const QString&) Q_DECL_OVERRIDE { } virtual void didFetchDocumentInnerText(quint64, const QString&) Q_DECL_OVERRIDE { } virtual void didFindText(quint64, int) Q_DECL_OVERRIDE; virtual void passOnFocus(bool reverse) Q_DECL_OVERRIDE; virtual void javaScriptConsoleMessage(JavaScriptConsoleMessageLevel level, const QString& message, int lineNumber, const QString& sourceID) Q_DECL_OVERRIDE; - virtual void authenticationRequired(const QUrl&, const QString&, bool, const QString&, QString*, QString*) Q_DECL_OVERRIDE { } + virtual void authenticationRequired(QSharedPointer<QtWebEngineCore::AuthenticationDialogController>) Q_DECL_OVERRIDE; virtual void runMediaAccessPermissionRequest(const QUrl &securityOrigin, MediaRequestFlags requestFlags) Q_DECL_OVERRIDE; virtual void runMouseLockPermissionRequest(const QUrl &securityOrigin) Q_DECL_OVERRIDE; #ifndef QT_NO_ACCESSIBILITY @@ -166,6 +168,8 @@ public: virtual void showValidationMessage(const QRect &anchor, const QString &mainText, const QString &subText) Q_DECL_OVERRIDE; virtual void hideValidationMessage() Q_DECL_OVERRIDE; virtual void moveValidationMessage(const QRect &anchor) Q_DECL_OVERRIDE; + virtual void renderProcessTerminated(RenderProcessTerminationStatus terminationStatus, + int exitCode) Q_DECL_OVERRIDE; virtual QtWebEngineCore::BrowserContextAdapter *browserContextAdapter() Q_DECL_OVERRIDE; @@ -190,11 +194,13 @@ public: QQuickWebEngineTestSupport *m_testSupport; #endif QQmlComponent *contextMenuExtraItems; + QtWebEngineCore::WebEngineContextMenuData contextMenuData; QUrl explicitUrl; QUrl icon; int loadProgress; bool m_isFullScreen; bool isLoading; + bool m_activeFocusOnPress; qreal devicePixelRatio; QMap<quint64, QJSValue> m_callbacks; QList<QSharedPointer<CertificateErrorController> > m_certificateErrorControllers; @@ -203,6 +209,7 @@ private: QScopedPointer<QtWebEngineCore::UIDelegatesManager> m_uIDelegatesManager; QList<QQuickWebEngineScript *> m_userScripts; qreal m_dpiScale; + QColor m_backgroundColor; }; #ifndef QT_NO_ACCESSIBILITY diff --git a/src/webengine/api/qtwebengineglobal.cpp b/src/webengine/api/qtwebengineglobal.cpp index 1c67e710e..07561be6e 100644 --- a/src/webengine/api/qtwebengineglobal.cpp +++ b/src/webengine/api/qtwebengineglobal.cpp @@ -47,6 +47,17 @@ Q_GUI_EXPORT QOpenGLContext *qt_gl_global_share_context(); namespace QtWebEngine { +/*! + \namespace QtWebEngine + \inmodule QtWebEngine + \ingroup qtwebengine-namespaces + \keyword QtWebEngine Namespace + + \brief Helper functions for the Qt WebEngine (Qt Quick) module + + The \l[CPP]{QtWebEngine} namespace is part of the Qt WebEngine module. +*/ + static QOpenGLContext *shareContext; static void deleteShareContext() @@ -59,6 +70,16 @@ static void deleteShareContext() // QtWebEngine::initialize was introduced first and meant to be called // after the QGuiApplication creation, when AA_ShareOpenGLContexts fills // the same need but the flag has to be set earlier. + +/*! + \fn QtWebEngine::initialize() + + Sets up an OpenGL Context that can be shared between processes. This has to be done after + QGuiApplication is created, but before a Qt Quick window is created. + + This has the same effect as passing Qt::AA_ShareOpenGLContexts to the QGuiApplication + constructor. +*/ void initialize() { #ifdef Q_OS_WIN32 @@ -71,11 +92,11 @@ void initialize() QCoreApplication *app = QCoreApplication::instance(); if (!app) { - qFatal("QWebEngine(Widgets)::initialize() must be called after the construction of the application object."); + qFatal("QtWebEngine::initialize() must be called after the construction of the application object."); return; } if (app->thread() != QThread::currentThread()) { - qFatal("QWebEngine(Widgets)::initialize() must be called from the Qt gui thread."); + qFatal("QtWebEngine::initialize() must be called from the Qt gui thread."); return; } @@ -86,6 +107,9 @@ void initialize() shareContext->create(); qAddPostRoutine(deleteShareContext); qt_gl_set_global_share_context(shareContext); + + // Classes like QOpenGLWidget check for the attribute + app->setAttribute(Qt::AA_ShareOpenGLContexts); } } // namespace QtWebEngine |