diff options
25 files changed, 416 insertions, 27 deletions
diff --git a/examples/webenginewidgets/markdowneditor/doc/src/markdowneditor.qdoc b/examples/webenginewidgets/markdowneditor/doc/src/markdowneditor.qdoc index 44b1246b3..ddea067b7 100644 --- a/examples/webenginewidgets/markdowneditor/doc/src/markdowneditor.qdoc +++ b/examples/webenginewidgets/markdowneditor/doc/src/markdowneditor.qdoc @@ -27,7 +27,7 @@ /*! \example webenginewidgets/markdowneditor - \title Markdown Editor Example + \title WebEngine Markdown Editor Example \ingroup webengine-widgetexamples \brief Demonstrates how to integrate a web engine in a hybrid desktop application. diff --git a/examples/webenginewidgets/markdowneditor/resources/default.md b/examples/webenginewidgets/markdowneditor/resources/default.md index e5905b101..8f9c807aa 100644 --- a/examples/webenginewidgets/markdowneditor/resources/default.md +++ b/examples/webenginewidgets/markdowneditor/resources/default.md @@ -1,4 +1,4 @@ -## Markdown Editor Example +## WebEngine Markdown Editor Example This example uses [QWebEngineView](http://doc.qt.io/qt-5/qwebengineview.html) to preview text written using the [Markdown](https://en.wikipedia.org/wiki/Markdown) diff --git a/src/core/api/qwebenginecallback.h b/src/core/api/qwebenginecallback.h index a8758df7d..3bb993757 100644 --- a/src/core/api/qwebenginecallback.h +++ b/src/core/api/qwebenginecallback.h @@ -90,9 +90,11 @@ private: Q_DECLARE_SHARED(QWebEngineCallback<int>) Q_DECLARE_SHARED(QWebEngineCallback<const QByteArray &>) +#if QT_VERSION >= QT_VERSION_CHECK(5,6,0) Q_DECLARE_SHARED_NOT_MOVABLE_UNTIL_QT6(QWebEngineCallback<bool>) Q_DECLARE_SHARED_NOT_MOVABLE_UNTIL_QT6(QWebEngineCallback<const QString &>) Q_DECLARE_SHARED_NOT_MOVABLE_UNTIL_QT6(QWebEngineCallback<const QVariant &>) +#endif QT_END_NAMESPACE diff --git a/src/core/api/qwebenginecallback_p.h b/src/core/api/qwebenginecallback_p.h index 348fed464..f93e863eb 100644 --- a/src/core/api/qwebenginecallback_p.h +++ b/src/core/api/qwebenginecallback_p.h @@ -239,10 +239,12 @@ void CallbackDirectory::CallbackSharedDataPointer<T>::invokeEmpty() parent->invokeEmptyInternal(callback); } +#if QT_VERSION >= QT_VERSION_CHECK(5,6,0) #define CHECK_RELOCATABLE(x) \ Q_STATIC_ASSERT((QTypeInfoQuery<QWebEngineCallback< x > >::isRelocatable)); FOR_EACH_TYPE(CHECK_RELOCATABLE) #undef CHECK_RELOCATABLE +#endif } // namespace QtWebEngineCore diff --git a/src/core/api/qwebengineurlrequestinfo.cpp b/src/core/api/qwebengineurlrequestinfo.cpp index e53d9afb6..f229a9748 100644 --- a/src/core/api/qwebengineurlrequestinfo.cpp +++ b/src/core/api/qwebengineurlrequestinfo.cpp @@ -107,6 +107,9 @@ ASSERT_ENUMS_MATCH(QtWebEngineCore::WebContentsAdapterClient::OtherNavigation, Q it possible to intercept URL requests. This function is executed on the IO thread, and therefore running long tasks here will block networking. + \a info contains the information about the URL request and will track internally + whether its members have been altered. + \sa QWebEngineProfile::setRequestInterceptor */ diff --git a/src/core/core.pro b/src/core/core.pro index 09eee496f..a205d39a0 100644 --- a/src/core/core.pro +++ b/src/core/core.pro @@ -20,7 +20,8 @@ core_api.depends = gyp_run core_module.file = core_module.pro core_module.depends = core_api -SUBDIRS += core_gyp_generator +SUBDIRS += core_headers \ + core_gyp_generator !win32 { # gyp_configure_host.pro and gyp_configure_target.pro are phony pro files that @@ -36,6 +37,5 @@ SUBDIRS += core_gyp_generator } SUBDIRS += gyp_run \ - core_headers \ core_api \ core_module diff --git a/src/webengine/api/qquickwebenginescript.cpp b/src/webengine/api/qquickwebenginescript.cpp index a19ec1534..68ea491b3 100644 --- a/src/webengine/api/qquickwebenginescript.cpp +++ b/src/webengine/api/qquickwebenginescript.cpp @@ -45,6 +45,27 @@ using QtWebEngineCore::UserScript; +/*! + \qmltype WebEngineScript + \instantiates QQuickWebEngineScript + \inqmlmodule QtWebEngine + \since QtWebEngine 1.1 + \brief Enables the programmatic injection of scripts in the JavaScript engine. + + The WebEngineScript type enables the programmatic injection of so called \e {user scripts} in + the JavaScript engine at different points, determined by injectionPoint, during the loading of + web content. + + Scripts can be executed either in the main JavaScript \e world, along with the rest of the + JavaScript coming from the web contents, or in their own isolated world. While the DOM of the + page can be accessed from any world, JavaScript variables of a function defined in one world are + not accessible from a different one. The worldId property provides some predefined IDs for this + purpose. + + Use \l{WebEngineView::userScripts}{WebEngineView.userScripts} to access a list of scripts + attached to the web view. +*/ + QQuickWebEngineScript::QQuickWebEngineScript() : d_ptr(new QQuickWebEngineScriptPrivate) { @@ -78,6 +99,12 @@ QString QQuickWebEngineScript::toString() const return ret; } +/*! + \qmlproperty QString WebEngineScript::name + + The name of the script. Can be useful to retrieve a particular script from + \l{WebEngineView::userScripts}{WebEngineView.userScripts}. +*/ QString QQuickWebEngineScript::name() const { Q_D(const QQuickWebEngineScript); @@ -90,7 +117,7 @@ QString QQuickWebEngineScript::name() const This property holds the remote source location of the user script (if any). Unlike \l sourceCode, this property allows referring to user scripts that - are not already loaded in memory, for instance, when stored on disk. + are not already loaded in memory, for instance, when stored on disk. Setting this property will change the \l sourceCode of the script. @@ -121,20 +148,57 @@ ASSERT_ENUMS_MATCH(QQuickWebEngineScript::Deferred, UserScript::AfterLoad) ASSERT_ENUMS_MATCH(QQuickWebEngineScript::DocumentReady, UserScript::DocumentLoadFinished) ASSERT_ENUMS_MATCH(QQuickWebEngineScript::DocumentCreation, UserScript::DocumentElementCreation) +/*! + \qmlproperty enumeration WebEngineScript::injectionPoint + + The point in the loading process at which the script will be executed. + The default value is \c Deferred. + + \value DocumentCreation + The script will be executed as soon as the document is created. This is not suitable for + any DOM operation. + \value DocumentReady + The script will run as soon as the DOM is ready. This is equivalent to the + \c DOMContentLoaded event firing in JavaScript. + \value Deferred + The script will run when the page load finishes, or 500 ms after the document is ready, + whichever comes first. +*/ QQuickWebEngineScript::InjectionPoint QQuickWebEngineScript::injectionPoint() const { Q_D(const QQuickWebEngineScript); return static_cast<QQuickWebEngineScript::InjectionPoint>(d->coreScript.injectionPoint()); } - +/*! + \qmlproperty enumeration WebEngineScript::worldId + + The world ID defining which isolated world the script is executed in. + + \value MainWorld + The world used by the page's web contents. It can be useful in order to expose custom + functionality to web contents in certain scenarios. + \value ApplicationWorld + The default isolated world used for application level functionality implemented in + JavaScript. + \value UserWorld + The first isolated world to be used by scripts set by users if the application is not + making use of more worlds. As a rule of thumb, if that functionality is exposed to the + application users, each individual script should probably get its own isolated world. +*/ QQuickWebEngineScript::ScriptWorldId QQuickWebEngineScript::worldId() const { Q_D(const QQuickWebEngineScript); return static_cast<QQuickWebEngineScript::ScriptWorldId>(d->coreScript.worldId()); } +/*! + \qmlproperty int WebEngineScript::runOnSubframes + Set this property to \c true if the script is executed on every frame in the page, or \c false + if it is only ran for the main frame. + The default value is \c{false}. + */ bool QQuickWebEngineScript::runOnSubframes() const { Q_D(const QQuickWebEngineScript); diff --git a/src/webengine/doc/qtwebengine.qdocconf b/src/webengine/doc/qtwebengine.qdocconf index 02f9a9ffd..2fbdef93e 100644 --- a/src/webengine/doc/qtwebengine.qdocconf +++ b/src/webengine/doc/qtwebengine.qdocconf @@ -35,6 +35,9 @@ qhp.QtWebEngine.subprojects.examples.indexTitle = Qt WebEngine Examples qhp.QtWebEngine.subprojects.examples.selectors = doc:example qhp.QtWebEngine.subprojects.examples.sortPages = true +manifestmeta.highlighted.names += "QtWebEngine/WebEngine Markdown Editor Example" \ + "QtWebEngine/WebEngine Quick Nano Browser" + tagfile = ../../../doc/qtwebengine/qtwebengine.tags depends += qtcore \ @@ -45,6 +48,7 @@ depends += qtcore \ qtquickcontrols \ qtdoc \ qtwebchannel \ + qtwebview \ qtwidgets headerdirs += .. \ diff --git a/src/webengine/doc/src/qtwebengine-platform-notes.qdoc b/src/webengine/doc/src/qtwebengine-platform-notes.qdoc index 3e30e9606..f177c9598 100644 --- a/src/webengine/doc/src/qtwebengine-platform-notes.qdoc +++ b/src/webengine/doc/src/qtwebengine-platform-notes.qdoc @@ -116,4 +116,14 @@ be configured for use with several codecs, which rises licensing issues during distribution with the codec libraries. For some codecs, open source implementations, such as \l {OpenH264}, are available. + + \section1 Default QSurfaceFormat OpenGL Profile Support + + If a new default QSurfaceFormat with a modified OpenGL profile has to be set, it should be set + before the application instance is declared, to make sure that all created OpenGL contexts use + the same OpenGL profile. + + On OS X, if the default QSurfaceFormat is set after the application instance, the application + will exit with qFatal(), and print a message that the default QSurfaceFormat should be set + before the application instance. */ diff --git a/src/webengine/doc/src/webengineview.qdoc b/src/webengine/doc/src/webengineview.qdoc index 1d71a9cd9..0ce2f77be 100644 --- a/src/webengine/doc/src/webengineview.qdoc +++ b/src/webengine/doc/src/webengineview.qdoc @@ -227,6 +227,8 @@ \since QtWebEngine 1.1 List of script objects attached to the view. + + \sa WebEngineScript */ /*! diff --git a/src/webengine/render_widget_host_view_qt_delegate_quick.cpp b/src/webengine/render_widget_host_view_qt_delegate_quick.cpp index 508420cf8..b667bbc5c 100644 --- a/src/webengine/render_widget_host_view_qt_delegate_quick.cpp +++ b/src/webengine/render_widget_host_view_qt_delegate_quick.cpp @@ -41,6 +41,7 @@ #include <QGuiApplication> #include <QQuickPaintedItem> #include <QQuickWindow> +#include <QSurfaceFormat> #include <QVariant> #include <QWindow> #include <private/qquickwindow_p.h> @@ -60,6 +61,20 @@ RenderWidgetHostViewQtDelegateQuick::RenderWidgetHostViewQtDelegateQuick(RenderW return; setFocus(true); setActiveFocusOnTab(true); + +#ifdef Q_OS_OSX + // Check that the default QSurfaceFormat OpenGL profile matches the global OpenGL shared + // context profile, otherwise this could lead to a nasty crash. + QOpenGLContext *globalSharedContext = QOpenGLContext::globalShareContext(); + if (globalSharedContext) { + QSurfaceFormat sharedFormat = globalSharedContext->format(); + QSurfaceFormat defaultFormat = QSurfaceFormat::defaultFormat(); + if (defaultFormat.profile() != sharedFormat.profile()) { + qFatal("QWebEngine: Default QSurfaceFormat OpenGL profile does not match global shared context OpenGL profile. Please make sure you set a new QSurfaceFormat before the QtGui application instance is created."); + } + } +#endif + } void RenderWidgetHostViewQtDelegateQuick::initAsChild(WebContentsAdapterClient* container) diff --git a/src/webenginewidgets/api/qwebenginehistory.h b/src/webenginewidgets/api/qwebenginehistory.h index 3dcea9469..81dd3fb34 100644 --- a/src/webenginewidgets/api/qwebenginehistory.h +++ b/src/webenginewidgets/api/qwebenginehistory.h @@ -76,7 +76,9 @@ private: friend class QWebEngineHistoryPrivate; }; +#if QT_VERSION >= QT_VERSION_CHECK(5,6,0) Q_DECLARE_SHARED_NOT_MOVABLE_UNTIL_QT6(QWebEngineHistoryItem) +#endif class QWebEngineHistoryPrivate; class QWEBENGINEWIDGETS_EXPORT QWebEngineHistory { diff --git a/src/webenginewidgets/api/qwebenginescript.h b/src/webenginewidgets/api/qwebenginescript.h index 29126b110..a3cc66179 100644 --- a/src/webenginewidgets/api/qwebenginescript.h +++ b/src/webenginewidgets/api/qwebenginescript.h @@ -99,7 +99,9 @@ private: QSharedDataPointer<QtWebEngineCore::UserScript> d; }; +#if QT_VERSION >= QT_VERSION_CHECK(5,6,0) Q_DECLARE_SHARED_NOT_MOVABLE_UNTIL_QT6(QWebEngineScript) +#endif #ifndef QT_NO_DEBUG_STREAM QWEBENGINEWIDGETS_EXPORT QDebug operator<<(QDebug, const QWebEngineScript &); diff --git a/src/webenginewidgets/doc/src/qwebenginesettings_lgpl.qdoc b/src/webenginewidgets/doc/src/qwebenginesettings_lgpl.qdoc index 3dc23e037..df85c39fb 100644 --- a/src/webenginewidgets/doc/src/qwebenginesettings_lgpl.qdoc +++ b/src/webenginewidgets/doc/src/qwebenginesettings_lgpl.qdoc @@ -99,7 +99,14 @@ \value LocalStorageEnabled Enables support for the HTML 5 local storage feature. Enabled by default. \value LocalContentCanAccessRemoteUrls - Allows locally loaded documents to access remote URLs. Disabled by default. + Allows locally loaded documents to ignore cross-origin rules so that they can access + remote resources that would normally be blocked, because all remote resources are + considered cross-origin for a local file. Remote access that would not be blocked by + cross-origin rules is still possible when this setting is disabled (default). + Note that disabling this setting does not stop XMLHttpRequests or media elements in + local files from accessing remote content. Basically, it only stops some HTML + subresources, such as scripts, and therefore disabling this setting is not a safety + mechanism. \value XSSAuditingEnabled Monitors load requests for cross-site scripting attempts. Suspicious scripts are blocked and reported in the inspector's JavaScript console. Disabled by default, because it diff --git a/src/webenginewidgets/doc/src/qwebengineview_lgpl.qdoc b/src/webenginewidgets/doc/src/qwebengineview_lgpl.qdoc index 397b9f51b..1ec831ac2 100644 --- a/src/webenginewidgets/doc/src/qwebengineview_lgpl.qdoc +++ b/src/webenginewidgets/doc/src/qwebengineview_lgpl.qdoc @@ -76,7 +76,7 @@ new windows, such as pop-up windows, you can subclass QWebEngineView and reimplement the createWindow() function. - \sa {WebEngine Demo Browser Example}, {WebEngine Content Manipulation Example}, {Markdown Editor Example} + \sa {WebEngine Demo Browser Example}, {WebEngine Content Manipulation Example}, {WebEngine Markdown Editor Example} */ diff --git a/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.cpp b/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.cpp index 9871ecfb1..7eca835d5 100644 --- a/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.cpp +++ b/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.cpp @@ -64,9 +64,30 @@ RenderWidgetHostViewQtDelegateWidget::RenderWidgetHostViewQtDelegateWidget(Rende setFocusPolicy(Qt::StrongFocus); #if (QT_VERSION >= QT_VERSION_CHECK(5, 4, 0)) + QSurfaceFormat format; format.setDepthBufferSize(24); format.setStencilBufferSize(8); + + QOpenGLContext *globalSharedContext = QOpenGLContext::globalShareContext(); + if (globalSharedContext) { + QSurfaceFormat sharedFormat = globalSharedContext->format(); + +#ifdef Q_OS_OSX + // Check that the default QSurfaceFormat OpenGL profile matches the global OpenGL shared + // context profile, otherwise this could lead to a nasty crash. + QSurfaceFormat defaultFormat = QSurfaceFormat::defaultFormat(); + if (defaultFormat.profile() != sharedFormat.profile()) { + qFatal("QWebEngine: Default QSurfaceFormat OpenGL profile does not match global shared context OpenGL profile. Please make sure you set a new QSurfaceFormat before the QtGui application instance is created."); + } +#endif + + // Make sure the OpenGL profile of the QOpenGLWidget matches the shared context profile. + format.setMajorVersion(sharedFormat.majorVersion()); + format.setMinorVersion(sharedFormat.minorVersion()); + format.setProfile(sharedFormat.profile()); + } + setFormat(format); #endif diff --git a/tests/auto/quick/qquickwebenginedefaultsurfaceformat/qquickwebenginedefaultsurfaceformat.pro b/tests/auto/quick/qquickwebenginedefaultsurfaceformat/qquickwebenginedefaultsurfaceformat.pro new file mode 100644 index 000000000..826b47de7 --- /dev/null +++ b/tests/auto/quick/qquickwebenginedefaultsurfaceformat/qquickwebenginedefaultsurfaceformat.pro @@ -0,0 +1,6 @@ +include(../tests.pri) + +exists($${TARGET}.qrc):RESOURCES += $${TARGET}.qrc +QT_PRIVATE += webengine-private + +HEADERS += ../shared/util.h diff --git a/tests/auto/quick/qquickwebenginedefaultsurfaceformat/tst_qquickwebenginedefaultsurfaceformat.cpp b/tests/auto/quick/qquickwebenginedefaultsurfaceformat/tst_qquickwebenginedefaultsurfaceformat.cpp new file mode 100644 index 000000000..9f2060898 --- /dev/null +++ b/tests/auto/quick/qquickwebenginedefaultsurfaceformat/tst_qquickwebenginedefaultsurfaceformat.cpp @@ -0,0 +1,148 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtWebEngine module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "testwindow.h" +#include "util.h" + +#include <QGuiApplication> +#include <QtQml/QQmlEngine> +#include <QScopedPointer> +#include <QSurfaceFormat> +#include <QtTest/QtTest> +#include <QTimer> +#include <private/qquickwebengineview_p.h> + +class tst_QQuickWebEngineDefaultSurfaceFormat : public QObject +{ + Q_OBJECT + +private Q_SLOTS: + void customDefaultSurfaceFormat(); + +private: + inline void initEngineAndViewComponent(); + inline void initWindow(); + inline void deleteWindow(); + + inline QQuickWebEngineView *newWebEngineView(); + inline QQuickWebEngineView *webEngineView() const; + QUrl urlFromTestPath(const char *localFilePath); + + QQmlEngine *m_engine; + TestWindow *m_window; + QScopedPointer<QQmlComponent> m_component; +}; + +void tst_QQuickWebEngineDefaultSurfaceFormat::initEngineAndViewComponent() { + m_engine = new QQmlEngine(this); + m_component.reset(new QQmlComponent(m_engine, this)); + m_component->setData(QByteArrayLiteral("import QtQuick 2.0\n" + "import QtWebEngine 1.2\n" + "WebEngineView {}") + , QUrl()); +} + +void tst_QQuickWebEngineDefaultSurfaceFormat::initWindow() +{ + m_window = new TestWindow(newWebEngineView()); +} + +void tst_QQuickWebEngineDefaultSurfaceFormat::deleteWindow() +{ + delete m_window; +} + +QQuickWebEngineView *tst_QQuickWebEngineDefaultSurfaceFormat::newWebEngineView() +{ + QObject *viewInstance = m_component->create(); + QQuickWebEngineView *webEngineView = qobject_cast<QQuickWebEngineView*>(viewInstance); + return webEngineView; +} + +inline QQuickWebEngineView *tst_QQuickWebEngineDefaultSurfaceFormat::webEngineView() const +{ + return static_cast<QQuickWebEngineView*>(m_window->webEngineView.data()); +} + +QUrl tst_QQuickWebEngineDefaultSurfaceFormat::urlFromTestPath(const char *localFilePath) +{ + QString testSourceDirPath = QString::fromLocal8Bit(TESTS_SOURCE_DIR); + if (!testSourceDirPath.endsWith(QLatin1Char('/'))) + testSourceDirPath.append(QLatin1Char('/')); + + return QUrl::fromLocalFile(testSourceDirPath + QString::fromUtf8(localFilePath)); +} + +void tst_QQuickWebEngineDefaultSurfaceFormat::customDefaultSurfaceFormat() +{ + // Setting a new default QSurfaceFormat with a core OpenGL profile, before + // app instantiation should succeed, without abort() being called. + int argc = 1; + char *argv[] = { const_cast<char*>("tst_QQuickWebEngineDefaultSurfaceFormat") }; + + QSurfaceFormat format; + format.setVersion( 3, 3 ); + format.setProfile( QSurfaceFormat::CoreProfile ); + QSurfaceFormat::setDefaultFormat( format ); + + QGuiApplication app(argc, argv); + QtWebEngine::initialize(); + + initEngineAndViewComponent(); + initWindow(); + QQuickWebEngineView* view = webEngineView(); + view->setUrl(urlFromTestPath("html/basic_page.html")); + m_window->show(); + + QObject::connect( + view, + &QQuickWebEngineView::loadingChanged, [](QQuickWebEngineLoadRequest* request) + { + if (request->status() == QQuickWebEngineView::LoadSucceededStatus + || request->status() == QQuickWebEngineView::LoadFailedStatus) + QTimer::singleShot(100, qApp, &QCoreApplication::quit); + } + ); + + QObject::connect(qApp, &QCoreApplication::aboutToQuit, [this]() { + this->deleteWindow(); + }); + + QCOMPARE(app.exec(), 0); +} + +QTEST_APPLESS_MAIN(tst_QQuickWebEngineDefaultSurfaceFormat) +#include "tst_qquickwebenginedefaultsurfaceformat.moc" diff --git a/tests/auto/quick/quick.pro b/tests/auto/quick/quick.pro index 33821e20b..b278808f6 100644 --- a/tests/auto/quick/quick.pro +++ b/tests/auto/quick/quick.pro @@ -3,6 +3,7 @@ TEMPLATE = subdirs SUBDIRS += \ inspectorserver \ publicapi \ + qquickwebenginedefaultsurfaceformat \ qquickwebengineview \ qquickwebengineviewgraphics diff --git a/tests/auto/widgets/qwebenginedefaultsurfaceformat/qwebenginedefaultsurfaceformat.pro b/tests/auto/widgets/qwebenginedefaultsurfaceformat/qwebenginedefaultsurfaceformat.pro new file mode 100644 index 000000000..e99c7f493 --- /dev/null +++ b/tests/auto/widgets/qwebenginedefaultsurfaceformat/qwebenginedefaultsurfaceformat.pro @@ -0,0 +1 @@ +include(../tests.pri) diff --git a/tests/auto/widgets/qwebenginedefaultsurfaceformat/resources/index.html b/tests/auto/widgets/qwebenginedefaultsurfaceformat/resources/index.html new file mode 100644 index 000000000..53726e4a6 --- /dev/null +++ b/tests/auto/widgets/qwebenginedefaultsurfaceformat/resources/index.html @@ -0,0 +1,6 @@ +<html> +<head> +<title> Basic Page </title> +</head> +<h1>Basic page</h1> +</html> diff --git a/tests/auto/widgets/qwebenginedefaultsurfaceformat/tst_qwebenginedefaultsurfaceformat.cpp b/tests/auto/widgets/qwebenginedefaultsurfaceformat/tst_qwebenginedefaultsurfaceformat.cpp new file mode 100644 index 000000000..e42a8a75e --- /dev/null +++ b/tests/auto/widgets/qwebenginedefaultsurfaceformat/tst_qwebenginedefaultsurfaceformat.cpp @@ -0,0 +1,77 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtWebEngine module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <qtest.h> +#include "../util.h" + +#include <QSurfaceFormat> +#include <QTimer> +#include <qwebengineview.h> + +class tst_QWebEngineDefaultSurfaceFormat : public QObject +{ + Q_OBJECT + +private Q_SLOTS: + void customDefaultSurfaceFormat(); +}; + +void tst_QWebEngineDefaultSurfaceFormat::customDefaultSurfaceFormat() +{ + // Setting a new default QSurfaceFormat with a core OpenGL profile before + // app instantiation should succeed, without abort() being called. + int argc = 1; + char *argv[] = { const_cast<char*>("tst_QWebEngineDefaultSurfaceFormat") }; + + QSurfaceFormat format; + format.setVersion( 3, 3 ); + format.setProfile( QSurfaceFormat::CoreProfile ); + QSurfaceFormat::setDefaultFormat( format ); + + QApplication app(argc, argv); + + QWebEngineView view; + view.load(QUrl("qrc:///resources/index.html")); + view.show(); + QObject::connect(&view, &QWebEngineView::loadFinished, []() { + QTimer::singleShot(100, qApp, &QCoreApplication::quit); + }); + + QCOMPARE(app.exec(), 0); +} + +QTEST_APPLESS_MAIN(tst_QWebEngineDefaultSurfaceFormat) +#include "tst_qwebenginedefaultsurfaceformat.moc" diff --git a/tests/auto/widgets/qwebenginedefaultsurfaceformat/tst_qwebenginedefaultsurfaceformat.qrc b/tests/auto/widgets/qwebenginedefaultsurfaceformat/tst_qwebenginedefaultsurfaceformat.qrc new file mode 100644 index 000000000..3d5f1b3b2 --- /dev/null +++ b/tests/auto/widgets/qwebenginedefaultsurfaceformat/tst_qwebenginedefaultsurfaceformat.qrc @@ -0,0 +1,5 @@ +<!DOCTYPE RCC><RCC version="1.0"> +<qresource> + <file>resources/index.html</file> +</qresource> +</RCC> diff --git a/tests/auto/widgets/qwebengineprofile/tst_qwebengineprofile.cpp b/tests/auto/widgets/qwebengineprofile/tst_qwebengineprofile.cpp index 99182f155..9195a5190 100644 --- a/tests/auto/widgets/qwebengineprofile/tst_qwebengineprofile.cpp +++ b/tests/auto/widgets/qwebengineprofile/tst_qwebengineprofile.cpp @@ -39,8 +39,9 @@ #include <QtTest/QtTest> #include <QtWebEngineCore/qwebengineurlrequestjob.h> #include <QtWebEngineCore/qwebengineurlschemehandler.h> +#include <QtWebEngineWidgets/qwebengineprofile.h> +#include <QtWebEngineWidgets/qwebenginesettings.h> #include <QtWebEngineWidgets/qwebengineview.h> -#include <qwebengineprofile.h> class tst_QWebEngineProfile : public QObject { @@ -106,52 +107,61 @@ public: } }; +static bool loadSync(QWebEngineView *view, const QUrl &url, int timeout = 5000) +{ + // Ripped off QTRY_VERIFY. + QSignalSpy loadFinishedSpy(view, SIGNAL(loadFinished(bool))); + view->load(url); + if (loadFinishedSpy.isEmpty()) + QTest::qWait(0); + for (int i = 0; i < timeout; i += 50) { + if (!loadFinishedSpy.isEmpty()) + return true; + QTest::qWait(50); + } + return false; +} + void tst_QWebEngineProfile::urlSchemeHandlers() { - RedirectingUrlSchemeHandler mailtoHandler; + RedirectingUrlSchemeHandler lettertoHandler; QWebEngineProfile profile(QStringLiteral("urlSchemeHandlers")); - profile.installUrlSchemeHandler("mailto", &mailtoHandler); + profile.installUrlSchemeHandler("letterto", &lettertoHandler); QWebEngineView view; - QSignalSpy loadFinishedSpy(&view, SIGNAL(loadFinished(bool))); view.setPage(new QWebEnginePage(&profile, &view)); + view.settings()->setAttribute(QWebEngineSettings::ErrorPageEnabled, false); QString emailAddress = QStringLiteral("egon@olsen-banden.dk"); - view.load(QUrl(QStringLiteral("mailto:") + emailAddress)); - QVERIFY(loadFinishedSpy.wait()); + QVERIFY(loadSync(&view, QUrl(QStringLiteral("letterto:") + emailAddress))); QCOMPARE(toPlainTextSync(view.page()), emailAddress); // Install a gopher handler after the view has been fully initialized. ReplyingUrlSchemeHandler gopherHandler; profile.installUrlSchemeHandler("gopher", &gopherHandler); QUrl url = QUrl(QStringLiteral("gopher://olsen-banden.dk/benny")); - view.load(url); - QVERIFY(loadFinishedSpy.wait()); + QVERIFY(loadSync(&view, url)); QCOMPARE(toPlainTextSync(view.page()), url.toString()); - // Remove the mailto scheme, and check whether it is not handled anymore. - profile.removeUrlScheme("mailto"); + // Remove the letterto scheme, and check whether it is not handled anymore. + profile.removeUrlScheme("letterto"); emailAddress = QStringLiteral("kjeld@olsen-banden.dk"); - view.load(QUrl(QStringLiteral("mailto:") + emailAddress)); - QVERIFY(loadFinishedSpy.wait()); + QVERIFY(loadSync(&view, QUrl(QStringLiteral("letterto:") + emailAddress))); QVERIFY(toPlainTextSync(view.page()) != emailAddress); - // Check if gopher is still working after removing mailto. + // Check if gopher is still working after removing letterto. url = QUrl(QStringLiteral("gopher://olsen-banden.dk/yvonne")); - view.load(url); - QVERIFY(loadFinishedSpy.wait()); + QVERIFY(loadSync(&view, url)); QCOMPARE(toPlainTextSync(view.page()), url.toString()); // Does removeAll work? profile.removeAllUrlSchemeHandlers(); url = QUrl(QStringLiteral("gopher://olsen-banden.dk/harry")); - view.load(url); - QVERIFY(loadFinishedSpy.wait()); + QVERIFY(loadSync(&view, url)); QVERIFY(toPlainTextSync(view.page()) != url.toString()); // Install a handler that is owned by the view. Make sure this doesn't crash on shutdown. profile.installUrlSchemeHandler("aviancarrier", new ReplyingUrlSchemeHandler(&view)); url = QUrl(QStringLiteral("aviancarrier:inspector.mortensen@politistyrke.dk")); - view.load(url); - QVERIFY(loadFinishedSpy.wait()); + QVERIFY(loadSync(&view, url)); QCOMPARE(toPlainTextSync(view.page()), url.toString()); } diff --git a/tests/auto/widgets/widgets.pro b/tests/auto/widgets/widgets.pro index 986d5bbee..3220b1379 100644 --- a/tests/auto/widgets/widgets.pro +++ b/tests/auto/widgets/widgets.pro @@ -2,6 +2,7 @@ TEMPLATE = subdirs SUBDIRS += \ qwebengineaccessibility \ + qwebenginedefaultsurfaceformat \ qwebenginepage \ qwebenginehistory \ qwebenginehistoryinterface \ |