diff options
Diffstat (limited to 'src/webengine/api')
-rw-r--r-- | src/webengine/api/qquickwebenginecontextmenurequest.cpp | 3 | ||||
-rw-r--r-- | src/webengine/api/qquickwebenginedownloaditem.cpp | 82 | ||||
-rw-r--r-- | src/webengine/api/qquickwebenginedownloaditem_p.h | 8 | ||||
-rw-r--r-- | src/webengine/api/qquickwebenginedownloaditem_p_p.h | 2 | ||||
-rw-r--r-- | src/webengine/api/qquickwebengineprofile.cpp | 35 | ||||
-rw-r--r-- | src/webengine/api/qquickwebenginesettings.cpp | 39 | ||||
-rw-r--r-- | src/webengine/api/qquickwebenginesettings_p.h | 8 | ||||
-rw-r--r-- | src/webengine/api/qquickwebenginetestsupport.cpp | 118 | ||||
-rw-r--r-- | src/webengine/api/qquickwebenginetestsupport_p.h | 41 | ||||
-rw-r--r-- | src/webengine/api/qquickwebengineview.cpp | 82 | ||||
-rw-r--r-- | src/webengine/api/qquickwebengineview_p.h | 20 | ||||
-rw-r--r-- | src/webengine/api/qquickwebengineview_p_p.h | 1 |
12 files changed, 392 insertions, 47 deletions
diff --git a/src/webengine/api/qquickwebenginecontextmenurequest.cpp b/src/webengine/api/qquickwebenginecontextmenurequest.cpp index df57442a1..c53e28d93 100644 --- a/src/webengine/api/qquickwebenginecontextmenurequest.cpp +++ b/src/webengine/api/qquickwebenginecontextmenurequest.cpp @@ -159,11 +159,12 @@ QString QQuickWebEngineContextMenuRequest::linkText() const \readonly The URL of the link if the selected web page content is a link. + It is not guaranteed to be a valid URL. */ QUrl QQuickWebEngineContextMenuRequest::linkUrl() const { - return m_data->linkUrl(); + return m_data->unfilteredLinkUrl(); } /*! diff --git a/src/webengine/api/qquickwebenginedownloaditem.cpp b/src/webengine/api/qquickwebenginedownloaditem.cpp index bc40e6771..5afb19531 100644 --- a/src/webengine/api/qquickwebenginedownloaditem.cpp +++ b/src/webengine/api/qquickwebenginedownloaditem.cpp @@ -39,6 +39,8 @@ #include "qquickwebenginedownloaditem_p.h" #include "qquickwebenginedownloaditem_p_p.h" + +#include "browser_context_adapter.h" #include "qquickwebengineprofile_p.h" using QtWebEngineCore::BrowserContextAdapterClient; @@ -103,6 +105,8 @@ QQuickWebEngineDownloadItemPrivate::QQuickWebEngineDownloadItemPrivate(QQuickWeb , interruptReason(QQuickWebEngineDownloadItem::NoReason) , totalBytes(-1) , receivedBytes(0) + , downloadFinished(false) + , downloadPaused(false) { } @@ -145,6 +149,16 @@ void QQuickWebEngineDownloadItemPrivate::update(const BrowserContextAdapterClien totalBytes = info.totalBytes; Q_EMIT q->totalBytesChanged(); } + + if (info.done != downloadFinished) { + downloadFinished = info.done; + Q_EMIT q->isFinishedChanged(); + } + + if (info.paused != downloadPaused) { + downloadPaused = info.paused; + Q_EMIT q->isPausedChanged(); + } } void QQuickWebEngineDownloadItemPrivate::updateState(QQuickWebEngineDownloadItem::DownloadState newState) @@ -199,6 +213,46 @@ void QQuickWebEngineDownloadItem::cancel() } } + +/*! + \qmlmethod void WebEngineDownloadItem::pause() + \since QtWebEngine 1.6 + + Pauses the download. +*/ + +void QQuickWebEngineDownloadItem::pause() +{ + Q_D(QQuickWebEngineDownloadItem); + + QQuickWebEngineDownloadItem::DownloadState state = d->downloadState; + + if (state != QQuickWebEngineDownloadItem::DownloadInProgress) + return; + + if (d->profile) + d->profile->d_ptr->browserContext()->pauseDownload(d->downloadId); +} + +/*! + \qmlmethod void WebEngineDownloadItem::resume() + \since QtWebEngine 1.6 + + Resumes the download if it was paused or interrupted. +*/ +void QQuickWebEngineDownloadItem::resume() +{ + Q_D(QQuickWebEngineDownloadItem); + + QQuickWebEngineDownloadItem::DownloadState state = d->downloadState; + + if (d->downloadFinished || (state != QQuickWebEngineDownloadItem::DownloadInProgress && state != QQuickWebEngineDownloadItem::DownloadInterrupted)) + return; + + if (d->profile) + d->profile->d_ptr->browserContext()->resumeDownload(d->downloadId); +} + /*! \qmlproperty int WebEngineDownloadItem::id @@ -426,6 +480,34 @@ QString QQuickWebEngineDownloadItem::interruptReasonString() const static_cast<BrowserContextAdapterClient::DownloadInterruptReason>(interruptReason())); } +/*! + \qmlproperty bool WebEngineDownloadItem::isFinished + \readonly + \since QtWebEngine 1.6 + + Whether this download is finished (completed, cancelled, or non-resumable interrupted state). + */ + +bool QQuickWebEngineDownloadItem::isFinished() const +{ + Q_D(const QQuickWebEngineDownloadItem); + return d->downloadFinished; +} + +/*! + \qmlproperty bool WebEngineDownloadItem::isPaused + \readonly + \since QtWebEngine 1.6 + + Whether this download is paused. + */ + +bool QQuickWebEngineDownloadItem::isPaused() const +{ + Q_D(const QQuickWebEngineDownloadItem); + return d->downloadPaused; +} + QQuickWebEngineDownloadItem::QQuickWebEngineDownloadItem(QQuickWebEngineDownloadItemPrivate *p, QObject *parent) : QObject(parent) , d_ptr(p) diff --git a/src/webengine/api/qquickwebenginedownloaditem_p.h b/src/webengine/api/qquickwebenginedownloaditem_p.h index 889d0bcb7..972b130aa 100644 --- a/src/webengine/api/qquickwebenginedownloaditem_p.h +++ b/src/webengine/api/qquickwebenginedownloaditem_p.h @@ -131,9 +131,13 @@ public: Q_PROPERTY(DownloadType type READ type NOTIFY typeChanged REVISION 3 FINAL) Q_PROPERTY(DownloadInterruptReason interruptReason READ interruptReason NOTIFY interruptReasonChanged REVISION 4 FINAL) Q_PROPERTY(QString interruptReasonString READ interruptReasonString NOTIFY interruptReasonChanged REVISION 4 FINAL) + Q_PROPERTY(bool isFinished READ isFinished NOTIFY isFinishedChanged REVISION 5 FINAL) + Q_PROPERTY(bool isPaused READ isPaused NOTIFY isPausedChanged REVISION 5 FINAL) Q_INVOKABLE void accept(); Q_INVOKABLE void cancel(); + Q_INVOKABLE void pause(); + Q_INVOKABLE void resume(); quint32 id() const; DownloadState state() const; @@ -147,6 +151,8 @@ public: DownloadType type() const; DownloadInterruptReason interruptReason() const; QString interruptReasonString() const; + bool isFinished() const; + bool isPaused() const; Q_SIGNALS: void stateChanged(); @@ -157,6 +163,8 @@ Q_SIGNALS: void pathChanged(); Q_REVISION(3) void typeChanged(); Q_REVISION(4) void interruptReasonChanged(); + Q_REVISION(5) void isFinishedChanged(); + Q_REVISION(5) void isPausedChanged(); private: QQuickWebEngineDownloadItem(QQuickWebEngineDownloadItemPrivate*, QObject *parent = 0); diff --git a/src/webengine/api/qquickwebenginedownloaditem_p_p.h b/src/webengine/api/qquickwebenginedownloaditem_p_p.h index 4fb609492..6b4f7c8d3 100644 --- a/src/webengine/api/qquickwebenginedownloaditem_p_p.h +++ b/src/webengine/api/qquickwebenginedownloaditem_p_p.h @@ -79,6 +79,8 @@ public: qint64 receivedBytes; QString mimeType; QString downloadPath; + bool downloadFinished; + bool downloadPaused; void update(const QtWebEngineCore::BrowserContextAdapterClient::DownloadItemInfo &info); void updateState(QQuickWebEngineDownloadItem::DownloadState newState); diff --git a/src/webengine/api/qquickwebengineprofile.cpp b/src/webengine/api/qquickwebengineprofile.cpp index 3364e4169..57ad009b7 100644 --- a/src/webengine/api/qquickwebengineprofile.cpp +++ b/src/webengine/api/qquickwebengineprofile.cpp @@ -145,7 +145,7 @@ QQuickWebEngineProfilePrivate::QQuickWebEngineProfilePrivate(QSharedPointer<Brow , m_browserContextRef(browserContext) { m_browserContextRef->addClient(this); - m_settings->d_ptr->initDefaults(browserContext->isOffTheRecord()); + m_settings->d_ptr->initDefaults(); // 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); @@ -672,34 +672,8 @@ QQuickWebEngineProfile *QQuickWebEngineProfile::defaultProfile() For example, the language \c en-US will load the \c en-US.bdic dictionary file. - Qt WebEngine checks for the \c qtwebengine_dictionaries subdirectory - first in the local directory and if it is not found, in the Qt - installation directory. - - On macOS, depending on how Qt WebEngine is configured at build time, there are two possibilities - how spellchecking data is found: - - \list - \li Hunspell dictionaries (default) - .bdic dictionaries are used, just like on other - platforms - \li Native dictionaries - the macOS spellchecking APIs are used (which means the results - will depend on the installed OS dictionaries) - \endlist - - Thus, in the macOS Hunspell case, Qt WebEngine will look in the \e qtwebengine_dictionaries - subdirectory located inside the application bundle \c Resources directory, and also in the - \c Resources directory located inside the Qt framework bundle. - - To summarize, in case of Hunspell usage, the following paths are considered: - - \list - \li QCoreApplication::applicationDirPath()/qtwebengine_dictionaries - or QCoreApplication::applicationDirPath()/../Contents/Resources/qtwebengine_dictionaries - (on macOS) - \li [QLibraryInfo::DataPath]/qtwebengine_dictionaries - or path/to/QtWebEngineCore.framework/Resources/qtwebengine_dictionaries (Qt framework - bundle on macOS) - \endlist + See the \l {Spellchecker}{Spellchecker feature documentation} for how + dictionary files are searched. For more information about how to compile \c .bdic dictionaries, see the \l{WebEngine Widgets Spellchecker Example}{Spellchecker Example}. @@ -817,7 +791,8 @@ static bool checkInternalScheme(const QByteArray &scheme) static QSet<QByteArray> internalSchemes; if (internalSchemes.isEmpty()) { internalSchemes << QByteArrayLiteral("qrc") << QByteArrayLiteral("data") << QByteArrayLiteral("blob") - << QByteArrayLiteral("http") << QByteArrayLiteral("ftp") << QByteArrayLiteral("javascript"); + << QByteArrayLiteral("http") << QByteArrayLiteral("https") << QByteArrayLiteral("ftp") + << QByteArrayLiteral("javascript"); } return internalSchemes.contains(scheme); } diff --git a/src/webengine/api/qquickwebenginesettings.cpp b/src/webengine/api/qquickwebenginesettings.cpp index ff2541376..3ce53337c 100644 --- a/src/webengine/api/qquickwebenginesettings.cpp +++ b/src/webengine/api/qquickwebenginesettings.cpp @@ -311,8 +311,7 @@ bool QQuickWebEngineSettings::touchIconsEnabled() const Focus is given to the view whenever a navigation operation occurs (load, stop, reload, reload and bypass cache, forward, backward, set content, and so on). - Enabled by default. See \l{WebEngine Recipe Browser} for an example where - this property is disabled. + Disabled by default. */ bool QQuickWebEngineSettings::focusOnNavigationEnabled() const { @@ -363,6 +362,26 @@ bool QQuickWebEngineSettings::allowGeolocationOnInsecureOrigins() const } /*! + \qmlproperty bool WebEngineSettings::allowWindowActivationFromJavaScript + \since QtWebEngine 1.6 + Allows the window.focus() method in JavaScript. Disallowed by default. +*/ +bool QQuickWebEngineSettings::allowWindowActivationFromJavaScript() const +{ + return d_ptr->testAttribute(WebEngineSettings::AllowWindowActivationFromJavaScript); +} + +/*! + \qmlproperty bool WebEngineSettings::showScrollBars + \since QtWebEngine 1.6 + Shows scroll bars. Enabled by default. +*/ +bool QQuickWebEngineSettings::showScrollBars() const +{ + return d_ptr->testAttribute(WebEngineSettings::ShowScrollBars); +} + +/*! \qmlproperty string WebEngineSettings::defaultTextEncoding \since QtWebEngine 1.2 @@ -564,6 +583,22 @@ void QQuickWebEngineSettings::setAllowGeolocationOnInsecureOrigins(bool on) Q_EMIT allowGeolocationOnInsecureOriginsChanged(); } +void QQuickWebEngineSettings::setAllowWindowActivationFromJavaScript(bool on) +{ + bool wasOn = d_ptr->testAttribute(WebEngineSettings::AllowWindowActivationFromJavaScript); + d_ptr->setAttribute(WebEngineSettings::AllowWindowActivationFromJavaScript, on); + if (wasOn != on) + Q_EMIT allowWindowActivationFromJavaScriptChanged(); +} + +void QQuickWebEngineSettings::setShowScrollBars(bool on) +{ + bool wasOn = d_ptr->testAttribute(WebEngineSettings::ShowScrollBars); + d_ptr->setAttribute(WebEngineSettings::ShowScrollBars, on); + if (wasOn != on) + Q_EMIT showScrollBarsChanged(); +} + void QQuickWebEngineSettings::setParentSettings(QQuickWebEngineSettings *parentSettings) { d_ptr->setParentSettings(parentSettings->d_ptr.data()); diff --git a/src/webengine/api/qquickwebenginesettings_p.h b/src/webengine/api/qquickwebenginesettings_p.h index 10217c678..a8b11c769 100644 --- a/src/webengine/api/qquickwebenginesettings_p.h +++ b/src/webengine/api/qquickwebenginesettings_p.h @@ -86,6 +86,8 @@ class Q_WEBENGINE_PRIVATE_EXPORT QQuickWebEngineSettings : public QObject { Q_PROPERTY(bool printElementBackgrounds READ printElementBackgrounds WRITE setPrintElementBackgrounds NOTIFY printElementBackgroundsChanged REVISION 3 FINAL) Q_PROPERTY(bool allowRunningInsecureContent READ allowRunningInsecureContent WRITE setAllowRunningInsecureContent NOTIFY allowRunningInsecureContentChanged REVISION 3 FINAL) Q_PROPERTY(bool allowGeolocationOnInsecureOrigins READ allowGeolocationOnInsecureOrigins WRITE setAllowGeolocationOnInsecureOrigins NOTIFY allowGeolocationOnInsecureOriginsChanged REVISION 4 FINAL) + Q_PROPERTY(bool allowWindowActivationFromJavaScript READ allowWindowActivationFromJavaScript WRITE setAllowWindowActivationFromJavaScript NOTIFY allowWindowActivationFromJavaScriptChanged REVISION 5 FINAL) + Q_PROPERTY(bool showScrollBars READ showScrollBars WRITE setShowScrollBars NOTIFY showScrollBarsChanged REVISION 5 FINAL) public: ~QQuickWebEngineSettings(); @@ -113,6 +115,8 @@ public: bool printElementBackgrounds() const; bool allowRunningInsecureContent() const; bool allowGeolocationOnInsecureOrigins() const; + bool allowWindowActivationFromJavaScript() const; + bool showScrollBars() const; void setAutoLoadImages(bool on); void setJavascriptEnabled(bool on); @@ -137,6 +141,8 @@ public: void setPrintElementBackgrounds(bool on); void setAllowRunningInsecureContent(bool on); void setAllowGeolocationOnInsecureOrigins(bool on); + void setAllowWindowActivationFromJavaScript(bool on); + void setShowScrollBars(bool on); signals: void autoLoadImagesChanged(); @@ -162,6 +168,8 @@ signals: Q_REVISION(3) void printElementBackgroundsChanged(); Q_REVISION(3) void allowRunningInsecureContentChanged(); Q_REVISION(4) void allowGeolocationOnInsecureOriginsChanged(); + Q_REVISION(5) void allowWindowActivationFromJavaScriptChanged(); + Q_REVISION(5) void showScrollBarsChanged(); private: explicit QQuickWebEngineSettings(QQuickWebEngineSettings *parentSettings = 0); diff --git a/src/webengine/api/qquickwebenginetestsupport.cpp b/src/webengine/api/qquickwebenginetestsupport.cpp index 46ffb06f4..b3290d3cc 100644 --- a/src/webengine/api/qquickwebenginetestsupport.cpp +++ b/src/webengine/api/qquickwebenginetestsupport.cpp @@ -40,17 +40,21 @@ #include "qquickwebenginetestsupport_p.h" #include "qquickwebengineloadrequest_p.h" +#include <QQuickWindow> +#include <QtTest/qtest.h> QT_BEGIN_NAMESPACE +namespace QTest { + int Q_TESTLIB_EXPORT defaultMouseDelay(); +} + QQuickWebEngineErrorPage::QQuickWebEngineErrorPage() { } void QQuickWebEngineErrorPage::loadFinished(bool success, const QUrl &url) { - // Loading of the error page should not fail. - Q_ASSERT(success); Q_UNUSED(success); QQuickWebEngineLoadRequest loadRequest(url, QQuickWebEngineView::LoadSucceededStatus); @@ -64,8 +68,106 @@ void QQuickWebEngineErrorPage::loadStarted(const QUrl &provisionalUrl) Q_EMIT loadingChanged(&loadRequest); } + +QQuickWebEngineTestInputContext::QQuickWebEngineTestInputContext() + : m_visible(false) +{ +} + +QQuickWebEngineTestInputContext::~QQuickWebEngineTestInputContext() +{ + release(); +} + +void QQuickWebEngineTestInputContext::create() +{ + QInputMethodPrivate *inputMethodPrivate = QInputMethodPrivate::get(qApp->inputMethod()); + inputMethodPrivate->testContext = this; +} + +void QQuickWebEngineTestInputContext::release() +{ + QInputMethodPrivate *inputMethodPrivate = QInputMethodPrivate::get(qApp->inputMethod()); + inputMethodPrivate->testContext = 0; +} + +void QQuickWebEngineTestInputContext::showInputPanel() +{ + m_visible = true; +} + +void QQuickWebEngineTestInputContext::hideInputPanel() +{ + m_visible = false; +} + +bool QQuickWebEngineTestInputContext::isInputPanelVisible() const +{ + return m_visible; +} + + +QQuickWebEngineTestEvent::QQuickWebEngineTestEvent() +{ +} + +bool QQuickWebEngineTestEvent::mouseMultiClick(QObject *item, qreal x, qreal y, int clickCount) +{ + QTEST_ASSERT(item); + + QWindow *view = eventWindow(item); + if (!view) + return false; + + for (int i = 0; i < clickCount; ++i) { + mouseEvent(QMouseEvent::MouseButtonPress, view, item, QPointF(x, y)); + mouseEvent(QMouseEvent::MouseButtonRelease, view, item, QPointF(x, y)); + } + QTest::lastMouseTimestamp += QTest::mouseDoubleClickInterval; + + return true; +} + +QWindow *QQuickWebEngineTestEvent::eventWindow(QObject *item) +{ + QWindow *window = qobject_cast<QWindow *>(item); + if (window) + return window; + + QQuickItem *quickItem = qobject_cast<QQuickItem *>(item); + if (quickItem) + return quickItem->window(); + + QQuickItem *testParentItem = qobject_cast<QQuickItem *>(parent()); + if (testParentItem) + return testParentItem->window(); + + return nullptr; +} + +void QQuickWebEngineTestEvent::mouseEvent(QEvent::Type type, QWindow *window, QObject *item, const QPointF &_pos) +{ + QTest::qWait(QTest::defaultMouseDelay()); + QTest::lastMouseTimestamp += QTest::defaultMouseDelay(); + + QPoint pos; + QQuickItem *sgitem = qobject_cast<QQuickItem *>(item); + if (sgitem) + pos = sgitem->mapToScene(_pos).toPoint(); + + QMouseEvent me(type, pos, window->mapFromGlobal(pos), Qt::LeftButton, Qt::LeftButton, 0); + me.setTimestamp(++QTest::lastMouseTimestamp); + + QSpontaneKeyEvent::setSpontaneous(&me); + if (!qApp->notify(window, &me)) + QTest::qWarn("Mouse click event not accepted by receiving window"); +} + + QQuickWebEngineTestSupport::QQuickWebEngineTestSupport() - : m_errorPage(new QQuickWebEngineErrorPage()) + : m_errorPage(new QQuickWebEngineErrorPage) + , m_testInputContext(new QQuickWebEngineTestInputContext) + , m_testEvent(new QQuickWebEngineTestEvent) { } @@ -74,6 +176,16 @@ QQuickWebEngineErrorPage *QQuickWebEngineTestSupport::errorPage() const return m_errorPage.data(); } +QQuickWebEngineTestInputContext *QQuickWebEngineTestSupport::testInputContext() const +{ + return m_testInputContext.data(); +} + +QQuickWebEngineTestEvent * QQuickWebEngineTestSupport::testEvent() const +{ + return m_testEvent.data(); +} + QT_END_NAMESPACE #include "moc_qquickwebenginetestsupport_p.cpp" diff --git a/src/webengine/api/qquickwebenginetestsupport_p.h b/src/webengine/api/qquickwebenginetestsupport_p.h index cca8d1df4..b601fb47c 100644 --- a/src/webengine/api/qquickwebenginetestsupport_p.h +++ b/src/webengine/api/qquickwebenginetestsupport_p.h @@ -51,14 +51,17 @@ // We mean it. // +#include <private/qinputmethod_p.h> #include <private/qtwebengineglobal_p.h> +#include <QEvent> #include <QObject> #include <QUrl> QT_BEGIN_NAMESPACE class QQuickWebEngineLoadRequest; +class QWindow; class Q_WEBENGINE_PRIVATE_EXPORT QQuickWebEngineErrorPage : public QObject { Q_OBJECT @@ -73,13 +76,49 @@ Q_SIGNALS: void loadingChanged(QQuickWebEngineLoadRequest *loadRequest); }; +class Q_WEBENGINE_PRIVATE_EXPORT QQuickWebEngineTestInputContext : public QPlatformInputContext { + Q_OBJECT + +public: + QQuickWebEngineTestInputContext(); + ~QQuickWebEngineTestInputContext(); + + Q_INVOKABLE void create(); + Q_INVOKABLE void release(); + + virtual void showInputPanel(); + virtual void hideInputPanel(); + virtual bool isInputPanelVisible() const; + +private: + bool m_visible; +}; + +class Q_WEBENGINE_PRIVATE_EXPORT QQuickWebEngineTestEvent : public QObject { + Q_OBJECT + +public: + QQuickWebEngineTestEvent(); + +public Q_SLOTS: + bool mouseMultiClick(QObject *item, qreal x, qreal y, int clickCount); + +private: + QWindow *eventWindow(QObject *item = 0); + void mouseEvent(QEvent::Type type, QWindow *window, QObject *item, const QPointF &_pos); +}; + class Q_WEBENGINE_PRIVATE_EXPORT QQuickWebEngineTestSupport : public QObject { Q_OBJECT Q_PROPERTY(QQuickWebEngineErrorPage *errorPage READ errorPage CONSTANT FINAL) + Q_PROPERTY(QQuickWebEngineTestInputContext *testInputContext READ testInputContext CONSTANT FINAL) + Q_PROPERTY(QQuickWebEngineTestEvent *testEvent READ testEvent CONSTANT FINAL) public: QQuickWebEngineTestSupport(); QQuickWebEngineErrorPage *errorPage() const; + QQuickWebEngineTestInputContext *testInputContext() const; + QQuickWebEngineTestEvent *testEvent() const; Q_SIGNALS: void windowCloseRejected(); @@ -87,6 +126,8 @@ Q_SIGNALS: private: QScopedPointer<QQuickWebEngineErrorPage> m_errorPage; + QScopedPointer<QQuickWebEngineTestInputContext> m_testInputContext; + QScopedPointer<QQuickWebEngineTestEvent> m_testEvent; }; QT_END_NAMESPACE diff --git a/src/webengine/api/qquickwebengineview.cpp b/src/webengine/api/qquickwebengineview.cpp index 53f4f5855..3da21fde5 100644 --- a/src/webengine/api/qquickwebengineview.cpp +++ b/src/webengine/api/qquickwebengineview.cpp @@ -138,6 +138,7 @@ QQuickWebEngineViewPrivate::QQuickWebEngineViewPrivate() , m_fullscreenMode(false) , isLoading(false) , m_activeFocusOnPress(true) + , m_validationShowing(false) , devicePixelRatio(QGuiApplication::primaryScreen()->devicePixelRatio()) , m_webChannel(0) , m_webChannelWorld(0) @@ -265,10 +266,12 @@ bool QQuickWebEngineViewPrivate::contextMenuRequested(const WebEngineContextMenu ui()->addMenuItem(item, QQuickWebEngineView::tr("Unselect")); } - if (!data.linkText().isEmpty() && data.linkUrl().isValid()) { + if (!data.linkText().isEmpty() && !data.unfilteredLinkUrl().isEmpty()) { item = new MenuItemHandler(menu); QObject::connect(item, &MenuItemHandler::triggered, [q] { q->triggerWebAction(QQuickWebEngineView::CopyLinkToClipboard); }); ui()->addMenuItem(item, QQuickWebEngineView::tr("Copy Link URL")); + } + if (!data.linkText().isEmpty() && data.linkUrl().isValid()) { item = new MenuItemHandler(menu); QObject::connect(item, &MenuItemHandler::triggered, [q] { q->triggerWebAction(QQuickWebEngineView::DownloadLinkToDisk); }); ui()->addMenuItem(item, QQuickWebEngineView::tr("Save Link")); @@ -566,6 +569,9 @@ void QQuickWebEngineViewPrivate::loadFinished(bool success, const QUrl &url, boo void QQuickWebEngineViewPrivate::focusContainer() { Q_Q(QQuickWebEngineView); + QQuickWindow *window = q->window(); + if (window) + window->requestActivate(); q->forceActiveFocus(); } @@ -585,7 +591,7 @@ void QQuickWebEngineViewPrivate::unhandledKeyEvent(QKeyEvent *event) } #endif if (q->parentItem()) - q->window()->sendEvent(q->parentItem(), event); + QCoreApplication::sendEvent(q->parentItem(), event); } void QQuickWebEngineViewPrivate::adoptNewWindow(QSharedPointer<WebContentsAdapter> newWebContents, WindowOpenDisposition disposition, bool userGesture, const QRect &, const QUrl &targetUrl) @@ -698,8 +704,13 @@ void QQuickWebEngineViewPrivate::runMediaAccessPermissionRequest(const QUrl &sec feature = QQuickWebEngineView::MediaAudioVideoCapture; else if (requestFlags.testFlag(WebContentsAdapterClient::MediaAudioCapture)) feature = QQuickWebEngineView::MediaAudioCapture; - else // WebContentsAdapterClient::MediaVideoCapture + else if (requestFlags.testFlag(WebContentsAdapterClient::MediaVideoCapture)) feature = QQuickWebEngineView::MediaVideoCapture; + else if (requestFlags.testFlag(WebContentsAdapterClient::MediaDesktopAudioCapture) && + requestFlags.testFlag(WebContentsAdapterClient::MediaDesktopVideoCapture)) + feature = QQuickWebEngineView::DesktopAudioVideoCapture; + else // if (requestFlags.testFlag(WebContentsAdapterClient::MediaDesktopVideoCapture)) + feature = QQuickWebEngineView::DesktopVideoCapture; Q_EMIT q->featurePermissionRequested(securityOrigin, feature); } @@ -867,8 +878,7 @@ QQuickWebEngineView::QQuickWebEngineView(QQuickItem *parent) Q_D(QQuickWebEngineView); d->q_ptr = this; this->setActiveFocusOnTab(true); - this->setFlags(QQuickItem::ItemIsFocusScope | QQuickItem::ItemAcceptsInputMethod - | QQuickItem::ItemAcceptsDrops); + this->setFlags(QQuickItem::ItemIsFocusScope | QQuickItem::ItemAcceptsDrops); #ifndef QT_NO_ACCESSIBILITY QQuickAccessibleAttached *accessible = QQuickAccessibleAttached::qmlAttachedProperties(this); @@ -1115,7 +1125,8 @@ void QQuickWebEngineViewPrivate::showValidationMessage(const QRect &anchor, cons Q_Q(QQuickWebEngineView); QQuickWebEngineFormValidationMessageRequest *request; request = new QQuickWebEngineFormValidationMessageRequest(QQuickWebEngineFormValidationMessageRequest::Show, - anchor,mainText,subText); + anchor,mainText,subText); + m_validationShowing = true; // mark the object for gc by creating temporary jsvalue qmlEngine(q)->newQObject(request); Q_EMIT q->formValidationMessageRequested(request); @@ -1126,8 +1137,12 @@ void QQuickWebEngineViewPrivate::showValidationMessage(const QRect &anchor, cons void QQuickWebEngineViewPrivate::hideValidationMessage() { Q_Q(QQuickWebEngineView); + // Suppress the initial hide message before any show messages (Since 61-based) + if (!m_validationShowing) + return; QQuickWebEngineFormValidationMessageRequest *request; request = new QQuickWebEngineFormValidationMessageRequest(QQuickWebEngineFormValidationMessageRequest::Hide); + m_validationShowing = false; // mark the object for gc by creating temporary jsvalue qmlEngine(q)->newQObject(request); Q_EMIT q->formValidationMessageRequested(request); @@ -1427,7 +1442,8 @@ void QQuickWebEngineView::grantFeaturePermission(const QUrl &securityOrigin, QQu { if (!d_ptr->adapter) return; - if (!granted && feature >= MediaAudioCapture && feature <= MediaAudioVideoCapture) { + if (!granted && ((feature >= MediaAudioCapture && feature <= MediaAudioVideoCapture) || + (feature >= DesktopVideoCapture && feature <= DesktopAudioVideoCapture))) { d_ptr->adapter->grantMediaAccessPermission(securityOrigin, WebContentsAdapterClient::MediaNone); return; } @@ -1445,6 +1461,16 @@ void QQuickWebEngineView::grantFeaturePermission(const QUrl &securityOrigin, QQu case Geolocation: d_ptr->adapter->runGeolocationRequestCallback(securityOrigin, granted); break; + case DesktopVideoCapture: + d_ptr->adapter->grantMediaAccessPermission(securityOrigin, WebContentsAdapterClient::MediaDesktopVideoCapture); + break; + case DesktopAudioVideoCapture: + d_ptr->adapter->grantMediaAccessPermission( + securityOrigin, + WebContentsAdapterClient::MediaRequestFlags( + WebContentsAdapterClient::MediaDesktopAudioCapture | + WebContentsAdapterClient::MediaDesktopVideoCapture)); + break; default: Q_UNREACHABLE(); } @@ -1606,14 +1632,14 @@ void QQuickWebEngineView::triggerWebAction(WebAction action) } break; case CopyLinkToClipboard: - if (d->m_contextMenuData.linkUrl().isValid()) { - QString urlString = d->m_contextMenuData.linkUrl().toString(QUrl::FullyEncoded); + if (!d->m_contextMenuData.unfilteredLinkUrl().isEmpty()) { + QString urlString = d->m_contextMenuData.unfilteredLinkUrl().toString(QUrl::FullyEncoded); QString title = d->m_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->m_contextMenuData.linkUrl()); + data->setUrls(QList<QUrl>() << d->m_contextMenuData.unfilteredLinkUrl()); qApp->clipboard()->setMimeData(data); } break; @@ -1711,6 +1737,42 @@ void QQuickWebEngineView::triggerWebAction(WebAction action) case ViewSource: d->adapter->viewSource(); break; + case ToggleBold: + runJavaScript(QStringLiteral("document.execCommand('bold');"), QQuickWebEngineScript::ApplicationWorld); + break; + case ToggleItalic: + runJavaScript(QStringLiteral("document.execCommand('italic');"), QQuickWebEngineScript::ApplicationWorld); + break; + case ToggleUnderline: + runJavaScript(QStringLiteral("document.execCommand('underline');"), QQuickWebEngineScript::ApplicationWorld); + break; + case ToggleStrikethrough: + runJavaScript(QStringLiteral("document.execCommand('strikethrough');"), QQuickWebEngineScript::ApplicationWorld); + break; + case AlignLeft: + runJavaScript(QStringLiteral("document.execCommand('justifyLeft');"), QQuickWebEngineScript::ApplicationWorld); + break; + case AlignCenter: + runJavaScript(QStringLiteral("document.execCommand('justifyCenter');"), QQuickWebEngineScript::ApplicationWorld); + break; + case AlignRight: + runJavaScript(QStringLiteral("document.execCommand('justifyRight');"), QQuickWebEngineScript::ApplicationWorld); + break; + case AlignJustified: + runJavaScript(QStringLiteral("document.execCommand('justifyFull');"), QQuickWebEngineScript::ApplicationWorld); + break; + case Indent: + runJavaScript(QStringLiteral("document.execCommand('indent');"), QQuickWebEngineScript::ApplicationWorld); + break; + case Outdent: + runJavaScript(QStringLiteral("document.execCommand('outdent');"), QQuickWebEngineScript::ApplicationWorld); + break; + case InsertOrderedList: + runJavaScript(QStringLiteral("document.execCommand('insertOrderedList');"), QQuickWebEngineScript::ApplicationWorld); + break; + case InsertUnorderedList: + runJavaScript(QStringLiteral("document.execCommand('insertUnorderedList');"), QQuickWebEngineScript::ApplicationWorld); + break; default: Q_UNREACHABLE(); } diff --git a/src/webengine/api/qquickwebengineview_p.h b/src/webengine/api/qquickwebengineview_p.h index 8112c7609..ae0523460 100644 --- a/src/webengine/api/qquickwebengineview_p.h +++ b/src/webengine/api/qquickwebengineview_p.h @@ -199,7 +199,9 @@ public: MediaAudioCapture, MediaVideoCapture, MediaAudioVideoCapture, - Geolocation + Geolocation, + DesktopVideoCapture, + DesktopAudioVideoCapture }; Q_ENUM(Feature) @@ -244,6 +246,22 @@ public: Unselect, SavePage, ViewSource, + + ToggleBold, + ToggleItalic, + ToggleUnderline, + ToggleStrikethrough, + + AlignLeft, + AlignCenter, + AlignRight, + AlignJustified, + Indent, + Outdent, + + InsertOrderedList, + InsertUnorderedList, + WebActionCount }; Q_ENUM(WebAction) diff --git a/src/webengine/api/qquickwebengineview_p_p.h b/src/webengine/api/qquickwebengineview_p_p.h index 19ecf5e1f..bd9b2909b 100644 --- a/src/webengine/api/qquickwebengineview_p_p.h +++ b/src/webengine/api/qquickwebengineview_p_p.h @@ -179,6 +179,7 @@ public: bool isLoading; bool m_activeFocusOnPress; bool m_navigationActionTriggered; + bool m_validationShowing; qreal devicePixelRatio; QMap<quint64, QJSValue> m_callbacks; QList<QSharedPointer<CertificateErrorController> > m_certificateErrorControllers; |