summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKari Oikarinen <kari.oikarinen@qt.io>2019-01-08 08:19:22 +0200
committerKari Oikarinen <kari.oikarinen@qt.io>2019-01-08 08:19:22 +0200
commit846320f5877aafb9c7b319da6c972786805d9c30 (patch)
treeb4bda9f9b27ee311fc7f75de3843a828da23c340
parent35b97b92968505793b162ccfdada65e25690f711 (diff)
parent5c85e0748b6c321d9988d126903fed85f311f5e7 (diff)
Merge 5.12 into 5.12.1
-rw-r--r--.qmake.conf2
-rw-r--r--dist/changes-5.11.366
-rw-r--r--examples/webenginewidgets/minimal/doc/src/minimal.qdoc14
-rw-r--r--src/core/api/qwebengineurlrequestinfo.cpp3
-rw-r--r--src/core/api/qwebengineurlscheme.cpp6
-rw-r--r--src/core/api/qwebengineurlschemehandler.cpp43
-rw-r--r--src/core/browser_main_parts_qt.cpp4
-rw-r--r--src/core/download_manager_delegate_qt.cpp16
-rw-r--r--src/core/net/network_delegate_qt.cpp14
-rw-r--r--src/core/profile_adapter.cpp4
-rw-r--r--src/core/profile_io_data_qt.cpp11
-rw-r--r--src/core/profile_io_data_qt.h5
-rw-r--r--src/core/web_engine_context.cpp6
-rw-r--r--src/core/web_engine_context.h6
-rw-r--r--src/core/web_event_factory.cpp114
-rw-r--r--src/webengine/api/qquickwebengineaction.cpp2
-rw-r--r--src/webengine/api/qquickwebengineprofile.cpp9
-rw-r--r--src/webengine/doc/src/qtwebengine-platform-notes.qdoc2
-rw-r--r--src/webenginewidgets/api/qwebengineprofile.cpp8
-rw-r--r--tests/auto/core/qwebengineurlrequestinterceptor/resources/favicon.html7
-rw-r--r--tests/auto/core/qwebengineurlrequestinterceptor/resources/fontawesome.woffbin0 -> 6724 bytes
-rw-r--r--tests/auto/core/qwebengineurlrequestinterceptor/resources/icons/favicon.pngbin0 -> 3961 bytes
-rw-r--r--tests/auto/core/qwebengineurlrequestinterceptor/resources/iframe.html6
-rw-r--r--tests/auto/core/qwebengineurlrequestinterceptor/resources/iframe2.html6
-rw-r--r--tests/auto/core/qwebengineurlrequestinterceptor/resources/iframe3.html5
-rw-r--r--tests/auto/core/qwebengineurlrequestinterceptor/resources/image.html5
-rw-r--r--tests/auto/core/qwebengineurlrequestinterceptor/resources/image_in_iframe.html5
-rw-r--r--tests/auto/core/qwebengineurlrequestinterceptor/resources/media.html7
-rw-r--r--tests/auto/core/qwebengineurlrequestinterceptor/resources/media.mp4bin0 -> 1493 bytes
-rw-r--r--tests/auto/core/qwebengineurlrequestinterceptor/resources/media_in_iframe.html5
-rw-r--r--tests/auto/core/qwebengineurlrequestinterceptor/resources/resource.html9
-rw-r--r--tests/auto/core/qwebengineurlrequestinterceptor/resources/resource_in_iframe.html5
-rw-r--r--tests/auto/core/qwebengineurlrequestinterceptor/resources/script.js3
-rw-r--r--tests/auto/core/qwebengineurlrequestinterceptor/resources/style.css7
-rw-r--r--tests/auto/core/qwebengineurlrequestinterceptor/tst_qwebengineurlrequestinterceptor.cpp244
-rw-r--r--tests/auto/core/qwebengineurlrequestinterceptor/tst_qwebengineurlrequestinterceptor.qrc25
-rw-r--r--tests/auto/core/tests.pri2
-rw-r--r--tests/auto/quick/qquickwebengineview/tst_qquickwebengineview.cpp4
38 files changed, 593 insertions, 87 deletions
diff --git a/.qmake.conf b/.qmake.conf
index c9888ee8b..7ae0b8594 100644
--- a/.qmake.conf
+++ b/.qmake.conf
@@ -5,4 +5,4 @@ QTWEBENGINE_OUT_ROOT = $$shadowed($$PWD)
load(qt_build_config)
CONFIG += warning_clean
-MODULE_VERSION = 5.12.0
+MODULE_VERSION = 5.12.1
diff --git a/dist/changes-5.11.3 b/dist/changes-5.11.3
new file mode 100644
index 000000000..562003a49
--- /dev/null
+++ b/dist/changes-5.11.3
@@ -0,0 +1,66 @@
+Qt 5.11.3 is a bug-fix release. It maintains both forward and backward
+compatibility (source and binary) with Qt 5.11.0 through 5.11.2.
+
+For more details, refer to the online documentation included in this
+distribution. The documentation is also available online:
+
+http://doc.qt.io/qt-5/index.html
+
+The Qt version 5.11 series is binary compatible with the 5.10.x series.
+Applications compiled for 5.10 will continue to run with 5.11.
+
+Some of the changes listed in this file include issue tracking numbers
+corresponding to tasks in the Qt Bug Tracker:
+
+https://bugreports.qt.io/
+
+Each of these identifiers can be entered in the bug tracker to obtain more
+information about a particular change.
+
+****************************************************************************
+* Qt 5.11.3 Changes *
+****************************************************************************
+
+Chromium
+--------
+
+ - Security fixes from Chromium up to version 70.0.3538.102, including:
+ * CVE-2018-16066
+ * CVE-2018-16067
+ * CVE-2018-16068
+ * CVE-2018-16070
+ * CVE-2018-16071
+ * CVE-2018-16072
+ * CVE-2018-16073
+ * CVE-2018-16074
+ * CVE-2018-16076
+ * CVE-2018-16077
+ * CVE-2018-16083
+ * CVE-2018-16085
+ * CVE-2018-17462
+ * CVE-2018-17466
+ * CVE-2018-17468
+ * CVE-2018-17468
+ * CVE-2018-17469
+ * CVE-2018-17470
+ * CVE-2018-17471
+ * CVE-2018-17473
+ * CVE-2018-17474
+ * CVE-2018-17476
+ * CVE-2018-17478
+
+General
+-------
+
+ * [QTBUG-69281, QTBUG-71128] Fixed asserts and crashes in proxy (.pac) file handling.
+ * [QTBUG-70062] Fixed rendering on late 2013 Mac Pros.
+ * [QTBUG-71393] Fixed issue with some cookies being incorrectly marked as thirdParty.
+
+Build
+-----
+
+ * [QTBUG-70981] macOS: Fixed build on macOS 10.14.
+ * [QTBUG-71033] Fixed configure check for minimum freetype version.
+ * [QTBUG-71295] Fixed building without webrtc but with pepper plugins.
+ * We are now explicitly setting arm_arch when compiling for ARM.
+ * Windows: Added configure check that we are using a 64 bit compiler.
diff --git a/examples/webenginewidgets/minimal/doc/src/minimal.qdoc b/examples/webenginewidgets/minimal/doc/src/minimal.qdoc
index 477ff521b..d0b25c4b8 100644
--- a/examples/webenginewidgets/minimal/doc/src/minimal.qdoc
+++ b/examples/webenginewidgets/minimal/doc/src/minimal.qdoc
@@ -42,6 +42,15 @@
\section1 The Code
+ We first define a \c commandLineUrlArgument function that returns the URL to open.
+ This is either the first positional argument given on the command line, or
+ \c https://www.qt.io as a fallback.
+
+ \quotefromfile webenginewidgets/minimal/main.cpp
+ \skipto #include
+
+ \printto int main
+
In the \c main function we first set the
\l{QCoreApplication::organizationName} property. This affects the locations
where Qt WebEngine stores persistent and cached data (see also
@@ -52,14 +61,11 @@
view automatically scale on high-dpi displays.
Next, we instantiate a QApplication and a QWebEngineView. The URL
- to load is taken from the command-line in \c commandLineUrlArgument and
+ to load is taken from \c commandLineUrlArgument and
loaded by calling \l QWebEngineView::setUrl. The view widget is
given a reasonable default size, and shown.
Finally, QApplication::exec() launches the main event loop.
- \quotefromfile webenginewidgets/minimal/main.cpp
- \skipto #include
-
\printuntil }
\section1 Requirements
diff --git a/src/core/api/qwebengineurlrequestinfo.cpp b/src/core/api/qwebengineurlrequestinfo.cpp
index 2bb870071..ea9081fc1 100644
--- a/src/core/api/qwebengineurlrequestinfo.cpp
+++ b/src/core/api/qwebengineurlrequestinfo.cpp
@@ -120,6 +120,9 @@ ASSERT_ENUMS_MATCH(QtWebEngineCore::WebContentsAdapterClient::OtherNavigation, Q
\a info contains the information about the URL request and will track internally
whether its members have been altered.
+
+ \warning All method calls to the profile on the main thread will block until
+ execution of this function is finished.
*/
diff --git a/src/core/api/qwebengineurlscheme.cpp b/src/core/api/qwebengineurlscheme.cpp
index f36f3335b..d63599163 100644
--- a/src/core/api/qwebengineurlscheme.cpp
+++ b/src/core/api/qwebengineurlscheme.cpp
@@ -84,8 +84,10 @@ public:
URLs.
Custom URL schemes must be configured early at application startup, before
- creating any Qt WebEngine classes. The configuration applies globally to all
- profiles.
+ creating any Qt WebEngine classes. In general this means the schemes need to be configured before
+ a QGuiApplication or QApplication instance is created.
+
+ Every registered scheme configuration applies globally to all profiles.
\code
int main(int argc, char **argv)
diff --git a/src/core/api/qwebengineurlschemehandler.cpp b/src/core/api/qwebengineurlschemehandler.cpp
index 94b85c42b..6f06b2c6e 100644
--- a/src/core/api/qwebengineurlschemehandler.cpp
+++ b/src/core/api/qwebengineurlschemehandler.cpp
@@ -48,12 +48,51 @@ QT_BEGIN_NAMESPACE
\brief The QWebEngineUrlSchemeHandler is a base class for handling custom URL schemes.
\since 5.6
- To implement a custom URL scheme for QtWebEngine, you must write a class derived from this class,
- and reimplement requestStarted(). Then install it via QWebEngineProfile::installUrlSchemeHandler()
+ To implement a custom URL scheme for QtWebEngine, you first have to create an instance of
+ QWebEngineUrlScheme and register it using QWebEngineUrlScheme::registerScheme().
+
+ \note Make sure that you create and register the scheme object \e before the QGuiApplication
+ or QApplication object is instantiated.
+
+ Then you must create a class derived from QWebEngineUrlSchemeHandler,
+ and reimplement the requestStarted() method.
+
+ Finally, install the scheme handler object via QWebEngineProfile::installUrlSchemeHandler()
or QQuickWebEngineProfile::installUrlSchemeHandler().
+ \code
+
+ class MySchemeHandler : public QWebEngineUrlSchemeHandler
+ {
+ public:
+ MySchemeHandler(QObject *parent = nullptr);
+ void requestStarted(QWebEngineUrlRequestJob *request)
+ {
+ // ....
+ }
+ };
+
+ int main(int argc, char **argv)
+ {
+ QWebEngineUrlScheme scheme("myscheme");
+ scheme.setSyntax(QWebEngineUrlScheme::Syntax::HostAndPort);
+ scheme.setDefaultPort(2345);
+ scheme.setFlags(QWebEngineUrlScheme::SecureScheme);
+ QWebEngineUrlScheme::registerScheme(scheme);
+
+ // ...
+ QApplication app(argc, argv);
+ // ...
+
+ // installUrlSchemeHandler does not take ownership of the handler.
+ MySchemeHandler *handler = new MySchemeHandler(parent);
+ QWebEngineProfile::defaultProfile()->installUrlSchemeHandler("myscheme", handler);
+ }
+ \endcode
+
\inmodule QtWebEngineCore
+ \sa {QWebEngineUrlScheme}, {WebEngine Widgets WebUI Example}
*/
/*!
diff --git a/src/core/browser_main_parts_qt.cpp b/src/core/browser_main_parts_qt.cpp
index dbd123586..8f39386d4 100644
--- a/src/core/browser_main_parts_qt.cpp
+++ b/src/core/browser_main_parts_qt.cpp
@@ -204,9 +204,9 @@ void BrowserMainPartsQt::PreMainMessageLoopStart()
void BrowserMainPartsQt::PostMainMessageLoopRun()
{
- // The BrowserContext's destructor uses the MessageLoop so it should be deleted
+ // The ProfileQt's destructor uses the MessageLoop so it should be deleted
// right before the RenderProcessHostImpl's destructor destroys it.
- WebEngineContext::current()->destroyBrowserContext();
+ WebEngineContext::current()->destroyProfileAdapter();
}
int BrowserMainPartsQt::PreCreateThreads()
diff --git a/src/core/download_manager_delegate_qt.cpp b/src/core/download_manager_delegate_qt.cpp
index 9fe233577..abf4a2a95 100644
--- a/src/core/download_manager_delegate_qt.cpp
+++ b/src/core/download_manager_delegate_qt.cpp
@@ -39,6 +39,8 @@
#include "download_manager_delegate_qt.h"
+#include "base/files/file_util.h"
+#include "base/time/time_to_iso8601.h"
#include "content/public/browser/download_item_utils.h"
#include "content/public/browser/download_manager.h"
#include "content/public/browser/save_page_type.h"
@@ -156,15 +158,13 @@ bool DownloadManagerDelegateQt::DetermineDownloadTarget(download::DownloadItem*
QFileInfo suggestedFile(defaultDownloadDirectory.absoluteFilePath(suggestedFilename));
QString suggestedFilePath = suggestedFile.absoluteFilePath();
- QString tmpFileBase = QString("%1%2%3").arg(suggestedFile.absolutePath()).arg(QDir::separator()).arg(suggestedFile.baseName());
+ base::FilePath tmpFilePath(toFilePathString(suggestedFilePath));
- for (int i = 1; QFileInfo::exists(suggestedFilePath); ++i) {
- suggestedFilePath = QString("%1(%2).%3").arg(tmpFileBase).arg(i).arg(suggestedFile.completeSuffix());
- if (i >= 99) {
- suggestedFilePath = suggestedFile.absoluteFilePath();
- break;
- }
- }
+ int uniquifier = base::GetUniquePathNumber(tmpFilePath, base::FilePath::StringType());
+ if (uniquifier > 0)
+ suggestedFilePath = toQt(tmpFilePath.InsertBeforeExtensionASCII(base::StringPrintf(" (%d)", uniquifier)).AsUTF8Unsafe());
+ else if (uniquifier == -1)
+ suggestedFilePath = toQt(tmpFilePath.InsertBeforeExtensionASCII(base::StringPrintf(" - %s", base::TimeToISO8601(item->GetStartTime()).c_str())).AsUTF8Unsafe());
item->AddObserver(this);
QList<ProfileAdapterClient*> clients = m_profileAdapter->clients();
diff --git a/src/core/net/network_delegate_qt.cpp b/src/core/net/network_delegate_qt.cpp
index 551302291..37309931e 100644
--- a/src/core/net/network_delegate_qt.cpp
+++ b/src/core/net/network_delegate_qt.cpp
@@ -225,15 +225,22 @@ int NetworkDelegateQt::OnBeforeURLRequest(net::URLRequest *request, net::Complet
const QUrl qUrl = toQt(request->url());
- QWebEngineUrlRequestInterceptor* interceptor = m_profileIOData->requestInterceptor();
+ QUrl firstPartyUrl = QUrl();
+ if (resourceType == content::ResourceType::RESOURCE_TYPE_SUB_FRAME)
+ firstPartyUrl = toQt(request->first_party_url());
+ else
+ firstPartyUrl = toQt(request->site_for_cookies());
+
+ QWebEngineUrlRequestInterceptor* interceptor = m_profileIOData->acquireInterceptor();
if (interceptor) {
QWebEngineUrlRequestInfoPrivate *infoPrivate = new QWebEngineUrlRequestInfoPrivate(toQt(resourceType),
toQt(navigationType),
qUrl,
- toQt(request->site_for_cookies()),
+ firstPartyUrl,
QByteArray::fromStdString(request->method()));
QWebEngineUrlRequestInfo requestInfo(infoPrivate);
interceptor->interceptRequest(requestInfo);
+ m_profileIOData->releaseInterceptor();
if (requestInfo.changed()) {
int result = infoPrivate->shouldBlockRequest ? net::ERR_BLOCKED_BY_CLIENT : net::OK;
@@ -249,7 +256,8 @@ int NetworkDelegateQt::OnBeforeURLRequest(net::URLRequest *request, net::Complet
if (result != net::OK)
return result;
}
- }
+ } else
+ m_profileIOData->releaseInterceptor();
if (!resourceInfo)
return net::OK;
diff --git a/src/core/profile_adapter.cpp b/src/core/profile_adapter.cpp
index 86b16fd2c..800fcb401 100644
--- a/src/core/profile_adapter.cpp
+++ b/src/core/profile_adapter.cpp
@@ -82,7 +82,7 @@ ProfileAdapter::ProfileAdapter(const QString &storageName):
, m_visitedLinksPolicy(TrackVisitedLinksOnDisk)
, m_httpCacheMaxSize(0)
{
- WebEngineContext::current()->addBrowserContext(this);
+ WebEngineContext::current()->addProfileAdapter(this);
// creation of profile requires webengine context
m_profile.reset(new ProfileQt(this));
content::BrowserContext::Initialize(m_profile.data(), toFilePath(dataPath()));
@@ -92,7 +92,7 @@ ProfileAdapter::ProfileAdapter(const QString &storageName):
ProfileAdapter::~ProfileAdapter()
{
- WebEngineContext::current()->removeBrowserContext(this);
+ WebEngineContext::current()->removeProfileAdapter(this);
if (m_downloadManagerDelegate) {
m_profile->GetDownloadManager(m_profile.data())->Shutdown();
m_downloadManagerDelegate.reset();
diff --git a/src/core/profile_io_data_qt.cpp b/src/core/profile_io_data_qt.cpp
index 0a0d242a3..7783f1ae7 100644
--- a/src/core/profile_io_data_qt.cpp
+++ b/src/core/profile_io_data_qt.cpp
@@ -690,14 +690,17 @@ void ProfileIODataQt::updateRequestInterceptor()
// We in this case do not need to regenerate any Chromium classes.
}
-QWebEngineUrlRequestInterceptor *ProfileIODataQt::requestInterceptor()
+QWebEngineUrlRequestInterceptor *ProfileIODataQt::acquireInterceptor()
{
- // used in NetworkDelegateQt::OnBeforeURLRequest
- Q_ASSERT(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
- QMutexLocker lock(&m_mutex);
+ m_mutex.lock();
return m_requestInterceptor;
}
+void ProfileIODataQt::releaseInterceptor()
+{
+ m_mutex.unlock();
+}
+
bool ProfileIODataQt::canSetCookie(const QUrl &firstPartyUrl, const QByteArray &cookieLine, const QUrl &url) const
{
return m_cookieDelegate->canSetCookie(firstPartyUrl,cookieLine, url);
diff --git a/src/core/profile_io_data_qt.h b/src/core/profile_io_data_qt.h
index 6961e2ad2..5b416861c 100644
--- a/src/core/profile_io_data_qt.h
+++ b/src/core/profile_io_data_qt.h
@@ -89,10 +89,13 @@ public:
void generateUserAgent();
void generateJobFactory();
void regenerateJobFactory();
- QWebEngineUrlRequestInterceptor *requestInterceptor();
bool canSetCookie(const QUrl &firstPartyUrl, const QByteArray &cookieLine, const QUrl &url) const;
bool canGetCookies(const QUrl &firstPartyUrl, const QUrl &url) const;
+ // Used in NetworkDelegateQt::OnBeforeURLRequest.
+ QWebEngineUrlRequestInterceptor *acquireInterceptor();
+ void releaseInterceptor();
+
void setRequestContextData(content::ProtocolHandlerMap *protocolHandlers,
content::URLRequestInterceptorScopedVector request_interceptors);
void setFullConfiguration(); // runs on ui thread
diff --git a/src/core/web_engine_context.cpp b/src/core/web_engine_context.cpp
index 1361ebbed..aee5be42f 100644
--- a/src/core/web_engine_context.cpp
+++ b/src/core/web_engine_context.cpp
@@ -183,13 +183,13 @@ bool usingSoftwareDynamicGL()
scoped_refptr<QtWebEngineCore::WebEngineContext> WebEngineContext::m_handle;
bool WebEngineContext::m_destroyed = false;
-void WebEngineContext::destroyBrowserContext()
+void WebEngineContext::destroyProfileAdapter()
{
if (m_defaultProfileAdapter)
qWarning("PostMainMessageLoopRun is done, but global profile still exists !");
}
-void WebEngineContext::addBrowserContext(ProfileAdapter *profileAdapter)
+void WebEngineContext::addProfileAdapter(ProfileAdapter *profileAdapter)
{
Q_ASSERT(!m_profileAdapters.contains(profileAdapter));
const QString path = profileAdapter->dataPath();
@@ -205,7 +205,7 @@ void WebEngineContext::addBrowserContext(ProfileAdapter *profileAdapter)
m_profileAdapters.append(profileAdapter);
}
-void WebEngineContext::removeBrowserContext(ProfileAdapter *profileAdapter)
+void WebEngineContext::removeProfileAdapter(ProfileAdapter *profileAdapter)
{
m_profileAdapters.removeAll(profileAdapter);
}
diff --git a/src/core/web_engine_context.h b/src/core/web_engine_context.h
index ce71984d4..604c85a61 100644
--- a/src/core/web_engine_context.h
+++ b/src/core/web_engine_context.h
@@ -82,9 +82,9 @@ public:
#if QT_CONFIG(webengine_printing_and_pdf)
printing::PrintJobManager* getPrintJobManager();
#endif
- void destroyBrowserContext();
- void addBrowserContext(ProfileAdapter *profileAdapter);
- void removeBrowserContext(ProfileAdapter *profileAdapter);
+ void destroyProfileAdapter();
+ void addProfileAdapter(ProfileAdapter *profileAdapter);
+ void removeProfileAdapter(ProfileAdapter *profileAdapter);
void destroy();
private:
diff --git a/src/core/web_event_factory.cpp b/src/core/web_event_factory.cpp
index a45f7048b..fc6287dd9 100644
--- a/src/core/web_event_factory.cpp
+++ b/src/core/web_event_factory.cpp
@@ -101,7 +101,7 @@ static KeyboardDriver keyboardDriverImpl()
if (platformName == QLatin1Literal("xcb") || platformName == QLatin1Literal("wayland"))
return KeyboardDriver::Xkb;
-#if QT_CONFIG(libinput) && QT_CONFIG(xkbcommon_evdev)
+#if QT_CONFIG(libinput) && QT_CONFIG(xkbcommon)
// Based on QEglFSIntegration::createInputHandlers and QLibInputKeyboard::processKey.
if (platformName == QLatin1Literal("eglfs") && !qEnvironmentVariableIntValue("QT_QPA_EGLFS_NO_LIBINPUT"))
return KeyboardDriver::Xkb;
@@ -927,6 +927,74 @@ static ui::DomKey domKeyForQtKey(int qtKey)
case Qt::Key_Zenkaku_Hankaku:
return ui::DomKey::ZENKAKU_HANKAKU;
+ // Dead keys (ui/events/keycodes/keyboard_code_conversion_xkb.cc)
+ case Qt::Key_Dead_Grave:
+ return ui::DomKey::DeadKeyFromCombiningCharacter(0x0300);
+ case Qt::Key_Dead_Acute:
+ return ui::DomKey::DeadKeyFromCombiningCharacter(0x0301);
+ case Qt::Key_Dead_Circumflex:
+ return ui::DomKey::DeadKeyFromCombiningCharacter(0x0302);
+ case Qt::Key_Dead_Tilde:
+ return ui::DomKey::DeadKeyFromCombiningCharacter(0x0303);
+ case Qt::Key_Dead_Macron:
+ return ui::DomKey::DeadKeyFromCombiningCharacter(0x0304);
+ case Qt::Key_Dead_Breve:
+ return ui::DomKey::DeadKeyFromCombiningCharacter(0x0306);
+ case Qt::Key_Dead_Abovedot:
+ return ui::DomKey::DeadKeyFromCombiningCharacter(0x0307);
+ case Qt::Key_Dead_Diaeresis:
+ return ui::DomKey::DeadKeyFromCombiningCharacter(0x0308);
+ case Qt::Key_Dead_Abovering:
+ return ui::DomKey::DeadKeyFromCombiningCharacter(0x030A);
+ case Qt::Key_Dead_Doubleacute:
+ return ui::DomKey::DeadKeyFromCombiningCharacter(0x030B);
+ case Qt::Key_Dead_Caron:
+ return ui::DomKey::DeadKeyFromCombiningCharacter(0x030C);
+ case Qt::Key_Dead_Cedilla:
+ return ui::DomKey::DeadKeyFromCombiningCharacter(0x0327);
+ case Qt::Key_Dead_Ogonek:
+ return ui::DomKey::DeadKeyFromCombiningCharacter(0x0328);
+ case Qt::Key_Dead_Iota:
+ return ui::DomKey::DeadKeyFromCombiningCharacter(0x0345);
+ case Qt::Key_Dead_Voiced_Sound:
+ return ui::DomKey::DeadKeyFromCombiningCharacter(0x3099);
+ case Qt::Key_Dead_Semivoiced_Sound:
+ return ui::DomKey::DeadKeyFromCombiningCharacter(0x309A);
+ case Qt::Key_Dead_Belowdot:
+ return ui::DomKey::DeadKeyFromCombiningCharacter(0x0323);
+ case Qt::Key_Dead_Hook:
+ return ui::DomKey::DeadKeyFromCombiningCharacter(0x0309);
+ case Qt::Key_Dead_Horn:
+ return ui::DomKey::DeadKeyFromCombiningCharacter(0x031B);
+ case Qt::Key_Dead_Stroke:
+ return ui::DomKey::DeadKeyFromCombiningCharacter(0x0338);
+ case Qt::Key_Dead_Abovecomma:
+ return ui::DomKey::DeadKeyFromCombiningCharacter(0x0313);
+ case Qt::Key_Dead_Abovereversedcomma:
+ return ui::DomKey::DeadKeyFromCombiningCharacter(0x0314);
+ case Qt::Key_Dead_Doublegrave:
+ return ui::DomKey::DeadKeyFromCombiningCharacter(0x030F);
+ case Qt::Key_Dead_Belowring:
+ return ui::DomKey::DeadKeyFromCombiningCharacter(0x0325);
+ case Qt::Key_Dead_Belowmacron:
+ return ui::DomKey::DeadKeyFromCombiningCharacter(0x0331);
+ case Qt::Key_Dead_Belowcircumflex:
+ return ui::DomKey::DeadKeyFromCombiningCharacter(0x032D);
+ case Qt::Key_Dead_Belowtilde:
+ return ui::DomKey::DeadKeyFromCombiningCharacter(0x0330);
+ case Qt::Key_Dead_Belowbreve:
+ return ui::DomKey::DeadKeyFromCombiningCharacter(0x032E);
+ case Qt::Key_Dead_Belowdiaeresis:
+ return ui::DomKey::DeadKeyFromCombiningCharacter(0x0324);
+ case Qt::Key_Dead_Invertedbreve:
+ return ui::DomKey::DeadKeyFromCombiningCharacter(0x0311);
+ case Qt::Key_Dead_Belowcomma:
+ return ui::DomKey::DeadKeyFromCombiningCharacter(0x0326);
+ case Qt::Key_Dead_Currency:
+ return ui::DomKey::DeadKeyFromCombiningCharacter(0x00A4);
+ case Qt::Key_Dead_Greek:
+ return ui::DomKey::DeadKeyFromCombiningCharacter(0x037E);
+
// General-Purpose Function Keys
case Qt::Key_F1:
return ui::DomKey::F1;
@@ -1138,19 +1206,6 @@ static ui::DomKey domKeyForQtKey(int qtKey)
}
}
-static inline base::TimeTicks currentTimeForEvent(const QEvent *event)
-{
- Q_ASSERT(event);
-
- if (event->type() != QEvent::Leave) {
- const QInputEvent *inputEvent = static_cast<const QInputEvent *>(event);
- if (inputEvent->timestamp())
- return base::TimeTicks::FromInternalValue(inputEvent->timestamp() * 1000);
- }
-
- return base::TimeTicks::Now();
-}
-
template<class T>
static WebMouseEvent::Button mouseButtonForEvent(T *event)
{
@@ -1307,7 +1362,7 @@ WebMouseEvent WebEventFactory::toWebMouseEvent(QMouseEvent *ev, double dpiScale)
mouseButtonForEvent<QMouseEvent>(ev),
0,
modifiersForEvent(ev),
- currentTimeForEvent(ev));
+ base::TimeTicks::Now());
webKitEvent.pointer_type = WebPointerProperties::PointerType::kMouse;
@@ -1317,7 +1372,7 @@ WebMouseEvent WebEventFactory::toWebMouseEvent(QMouseEvent *ev, double dpiScale)
WebMouseEvent WebEventFactory::toWebMouseEvent(QHoverEvent *ev, double dpiScale)
{
WebMouseEvent webKitEvent;
- webKitEvent.SetTimeStamp(currentTimeForEvent(ev));
+ webKitEvent.SetTimeStamp(base::TimeTicks::Now());
webKitEvent.SetModifiers(modifiersForEvent(ev));
webKitEvent.SetType(webEventTypeForEvent(ev));
@@ -1338,7 +1393,7 @@ WebMouseEvent WebEventFactory::toWebMouseEvent(QTabletEvent *ev, double dpiScale
mouseButtonForEvent<QTabletEvent>(ev),
0,
modifiersForEvent(ev),
- currentTimeForEvent(ev));
+ base::TimeTicks::Now());
webKitEvent.force = ev->pressure();
webKitEvent.tilt_x = ev->xTilt();
@@ -1355,7 +1410,7 @@ WebMouseEvent WebEventFactory::toWebMouseEvent(QEvent *ev)
Q_ASSERT(ev->type() == QEvent::Leave || ev->type() == QEvent::HoverLeave);
WebMouseEvent webKitEvent;
- webKitEvent.SetTimeStamp(currentTimeForEvent(ev));
+ webKitEvent.SetTimeStamp(base::TimeTicks::Now());
webKitEvent.SetType(WebInputEvent::kMouseLeave);
return webKitEvent;
}
@@ -1364,7 +1419,7 @@ WebMouseEvent WebEventFactory::toWebMouseEvent(QEvent *ev)
WebGestureEvent WebEventFactory::toWebGestureEvent(QNativeGestureEvent *ev, double dpiScale)
{
WebGestureEvent webKitEvent;
- webKitEvent.SetTimeStamp(currentTimeForEvent(ev));
+ webKitEvent.SetTimeStamp(base::TimeTicks::Now());
webKitEvent.SetModifiers(modifiersForEvent(ev));
webKitEvent.SetPositionInWidget(WebFloatPoint(ev->localPos().x() / dpiScale,
@@ -1434,7 +1489,7 @@ blink::WebMouseWheelEvent WebEventFactory::toWebWheelEvent(QWheelEvent *ev, doub
WebMouseWheelEvent webEvent;
webEvent.SetType(webEventTypeForEvent(ev));
webEvent.SetModifiers(modifiersForEvent(ev));
- webEvent.SetTimeStamp(currentTimeForEvent(ev));
+ webEvent.SetTimeStamp(base::TimeTicks::Now());
webEvent.SetPositionInWidget(ev->x() / dpiScale, ev->y() / dpiScale);
webEvent.SetPositionInScreen(ev->globalX(), ev->globalY());
@@ -1464,7 +1519,7 @@ bool WebEventFactory::coalesceWebWheelEvent(blink::WebMouseWheelEvent &webEvent,
return false;
#endif
- webEvent.SetTimeStamp(currentTimeForEvent(ev));
+ webEvent.SetTimeStamp(base::TimeTicks::Now());
webEvent.SetPositionInWidget(ev->x() / dpiScale, ev->y() / dpiScale);
webEvent.SetPositionInScreen(ev->globalX(), ev->globalY());
@@ -1478,7 +1533,7 @@ bool WebEventFactory::coalesceWebWheelEvent(blink::WebMouseWheelEvent &webEvent,
content::NativeWebKeyboardEvent WebEventFactory::toWebKeyboardEvent(QKeyEvent *ev)
{
content::NativeWebKeyboardEvent webKitEvent(reinterpret_cast<gfx::NativeEvent>(ev));
- webKitEvent.SetTimeStamp(currentTimeForEvent(ev));
+ webKitEvent.SetTimeStamp(base::TimeTicks::Now());
webKitEvent.SetModifiers(modifiersForEvent(ev));
webKitEvent.SetType(webEventTypeForEvent(ev));
@@ -1502,17 +1557,20 @@ content::NativeWebKeyboardEvent WebEventFactory::toWebKeyboardEvent(QKeyEvent *e
// The dom_code field should contain the USB keycode of the *physical* key
// that was pressed. Physical meaning independent of layout and modifiers.
- //
// Since this information is not available from QKeyEvent in portable form,
- // we try to compute it from the native key code. If there's no native key
- // code available either, then we assume a US layout and convert it from
- // windows_key_code. The result will be incorrect on non-US layouts.
+ // we try to compute it from the native key code.
if (webKitEvent.native_key_code)
webKitEvent.dom_code = static_cast<int>(
ui::KeycodeConverter::NativeKeycodeToDomCode(webKitEvent.native_key_code));
- else
+
+ // The dom_code and windows_key_code can be converted to each other. The
+ // result will be incorrect on non-US layouts.
+ if (!webKitEvent.dom_code && webKitEvent.windows_key_code)
webKitEvent.dom_code = static_cast<int>(
- ui::UsLayoutKeyboardCodeToDomCode(static_cast<ui::KeyboardCode>(webKitEvent.windows_key_code)));
+ ui::UsLayoutKeyboardCodeToDomCode(static_cast<ui::KeyboardCode>(webKitEvent.windows_key_code)));
+ else if (webKitEvent.dom_code && !webKitEvent.windows_key_code)
+ webKitEvent.windows_key_code =
+ ui::DomCodeToUsLayoutKeyboardCode(static_cast<ui::DomCode>(webKitEvent.dom_code));
const ushort* text = qtText.utf16();
size_t textSize = std::min(sizeof(webKitEvent.text), size_t(qtText.length() * 2));
diff --git a/src/webengine/api/qquickwebengineaction.cpp b/src/webengine/api/qquickwebengineaction.cpp
index f5b780ea6..69a05f29b 100644
--- a/src/webengine/api/qquickwebengineaction.cpp
+++ b/src/webengine/api/qquickwebengineaction.cpp
@@ -50,7 +50,7 @@ QT_BEGIN_NAMESPACE
\inqmlmodule QtWebEngine
\since QtWebEngine 1.8
- \brief An action that represents a \l WebEngineView::WebAction
+ \brief An action that represents a \l WebEngineView::WebAction.
A WebEngineAction is returned by the \l WebEngineView::action()
method. It provides information about the action, such as
diff --git a/src/webengine/api/qquickwebengineprofile.cpp b/src/webengine/api/qquickwebengineprofile.cpp
index ed2600e49..ddc71602b 100644
--- a/src/webengine/api/qquickwebengineprofile.cpp
+++ b/src/webengine/api/qquickwebengineprofile.cpp
@@ -53,6 +53,8 @@
#include "renderer_host/user_resource_controller_host.h"
#include "web_engine_settings.h"
+#include <QtWebEngineCore/qwebengineurlscheme.h>
+
using QtWebEngineCore::ProfileAdapter;
QT_BEGIN_NAMESPACE
@@ -857,7 +859,7 @@ static bool checkInternalScheme(const QByteArray &scheme)
/*!
Registers a handler \a handler for custom URL scheme \a scheme in the profile.
- It is recommended to first register the scheme with \l
+ It is necessary to first register the scheme with \l
QWebEngineUrlScheme::registerScheme at application startup.
*/
void QQuickWebEngineProfile::installUrlSchemeHandler(const QByteArray &scheme, QWebEngineUrlSchemeHandler *handler)
@@ -875,6 +877,11 @@ void QQuickWebEngineProfile::installUrlSchemeHandler(const QByteArray &scheme, Q
qWarning("URL scheme handler already installed for the scheme: %s", scheme.constData());
return;
}
+
+ if (QWebEngineUrlScheme::schemeByName(canonicalScheme) == QWebEngineUrlScheme())
+ qWarning("Please register the custom scheme '%s' via QWebEngineUrlScheme::registerScheme() "
+ "before installing the custom scheme handler.", scheme.constData());
+
d->profileAdapter()->addCustomUrlSchemeHandler(canonicalScheme, handler);
connect(handler, SIGNAL(_q_destroyedUrlSchemeHandler(QWebEngineUrlSchemeHandler*)), this, SLOT(destroyedUrlSchemeHandler(QWebEngineUrlSchemeHandler*)));
}
diff --git a/src/webengine/doc/src/qtwebengine-platform-notes.qdoc b/src/webengine/doc/src/qtwebengine-platform-notes.qdoc
index 59429ec5a..0b2aebfce 100644
--- a/src/webengine/doc/src/qtwebengine-platform-notes.qdoc
+++ b/src/webengine/doc/src/qtwebengine-platform-notes.qdoc
@@ -41,7 +41,7 @@
\list
\li \l{Qt for Windows - Requirements}
\li \l{Qt for X11 Requirements}
- \li \l{Qt for macOS - Requirements}
+ \li \l{Qt for macOS - Building from Source}
\endlist
In addition, the following tools are required for building the \l {Qt WebEngine} module:
diff --git a/src/webenginewidgets/api/qwebengineprofile.cpp b/src/webenginewidgets/api/qwebengineprofile.cpp
index 537cf41fd..03ce5e0bc 100644
--- a/src/webenginewidgets/api/qwebengineprofile.cpp
+++ b/src/webenginewidgets/api/qwebengineprofile.cpp
@@ -52,6 +52,7 @@
#include "visited_links_manager_qt.h"
#include "web_engine_settings.h"
+#include <QtWebEngineCore/qwebengineurlscheme.h>
QT_BEGIN_NAMESPACE
@@ -688,7 +689,7 @@ static bool checkInternalScheme(const QByteArray &scheme)
Registers a handler \a handler for custom URL scheme \a scheme in the profile.
- It is recommended to first register the scheme with \l
+ It is necessary to first register the scheme with \l
QWebEngineUrlScheme::registerScheme at application startup.
*/
void QWebEngineProfile::installUrlSchemeHandler(const QByteArray &scheme, QWebEngineUrlSchemeHandler *handler)
@@ -706,6 +707,11 @@ void QWebEngineProfile::installUrlSchemeHandler(const QByteArray &scheme, QWebEn
qWarning("URL scheme handler already installed for the scheme: %s", scheme.constData());
return;
}
+
+ if (QWebEngineUrlScheme::schemeByName(canonicalScheme) == QWebEngineUrlScheme())
+ qWarning("Please register the custom scheme '%s' via QWebEngineUrlScheme::registerScheme() "
+ "before installing the custom scheme handler.", scheme.constData());
+
d->profileAdapter()->addCustomUrlSchemeHandler(canonicalScheme, handler);
connect(handler, SIGNAL(_q_destroyedUrlSchemeHandler(QWebEngineUrlSchemeHandler*)), this, SLOT(destroyedUrlSchemeHandler(QWebEngineUrlSchemeHandler*)));
}
diff --git a/tests/auto/core/qwebengineurlrequestinterceptor/resources/favicon.html b/tests/auto/core/qwebengineurlrequestinterceptor/resources/favicon.html
new file mode 100644
index 000000000..5251d6ef7
--- /dev/null
+++ b/tests/auto/core/qwebengineurlrequestinterceptor/resources/favicon.html
@@ -0,0 +1,7 @@
+<html>
+<head>
+<link type="image/png" href="icons/favicon.png" sizes="48x48" rel="icon" />
+</head>
+<body>
+</body>
+</html>
diff --git a/tests/auto/core/qwebengineurlrequestinterceptor/resources/fontawesome.woff b/tests/auto/core/qwebengineurlrequestinterceptor/resources/fontawesome.woff
new file mode 100644
index 000000000..239b9c94e
--- /dev/null
+++ b/tests/auto/core/qwebengineurlrequestinterceptor/resources/fontawesome.woff
Binary files differ
diff --git a/tests/auto/core/qwebengineurlrequestinterceptor/resources/icons/favicon.png b/tests/auto/core/qwebengineurlrequestinterceptor/resources/icons/favicon.png
new file mode 100644
index 000000000..35717cca5
--- /dev/null
+++ b/tests/auto/core/qwebengineurlrequestinterceptor/resources/icons/favicon.png
Binary files differ
diff --git a/tests/auto/core/qwebengineurlrequestinterceptor/resources/iframe.html b/tests/auto/core/qwebengineurlrequestinterceptor/resources/iframe.html
new file mode 100644
index 000000000..f17027c7a
--- /dev/null
+++ b/tests/auto/core/qwebengineurlrequestinterceptor/resources/iframe.html
@@ -0,0 +1,6 @@
+<html>
+<body>
+<p>top</p>
+<iframe src="iframe2.html" width="80%" height="30%"/>
+</body>
+</html>
diff --git a/tests/auto/core/qwebengineurlrequestinterceptor/resources/iframe2.html b/tests/auto/core/qwebengineurlrequestinterceptor/resources/iframe2.html
new file mode 100644
index 000000000..758a44a2c
--- /dev/null
+++ b/tests/auto/core/qwebengineurlrequestinterceptor/resources/iframe2.html
@@ -0,0 +1,6 @@
+<html>
+<body>
+<p>another iframe</p>
+<iframe src="iframe3.html" width="80%" height="30%"></iframe>
+</body>
+</html>
diff --git a/tests/auto/core/qwebengineurlrequestinterceptor/resources/iframe3.html b/tests/auto/core/qwebengineurlrequestinterceptor/resources/iframe3.html
new file mode 100644
index 000000000..ed6ac5b94
--- /dev/null
+++ b/tests/auto/core/qwebengineurlrequestinterceptor/resources/iframe3.html
@@ -0,0 +1,5 @@
+<html>
+<body>
+<p>inner</p>
+</body>
+</html>
diff --git a/tests/auto/core/qwebengineurlrequestinterceptor/resources/image.html b/tests/auto/core/qwebengineurlrequestinterceptor/resources/image.html
new file mode 100644
index 000000000..b82e6aab2
--- /dev/null
+++ b/tests/auto/core/qwebengineurlrequestinterceptor/resources/image.html
@@ -0,0 +1,5 @@
+<html>
+<body>
+<img src="icons/favicon.png">
+</body>
+</html>
diff --git a/tests/auto/core/qwebengineurlrequestinterceptor/resources/image_in_iframe.html b/tests/auto/core/qwebengineurlrequestinterceptor/resources/image_in_iframe.html
new file mode 100644
index 000000000..2a3ac117c
--- /dev/null
+++ b/tests/auto/core/qwebengineurlrequestinterceptor/resources/image_in_iframe.html
@@ -0,0 +1,5 @@
+<html>
+<body>
+<iframe src="image.html"></iframe>
+</body>
+</html>
diff --git a/tests/auto/core/qwebengineurlrequestinterceptor/resources/media.html b/tests/auto/core/qwebengineurlrequestinterceptor/resources/media.html
new file mode 100644
index 000000000..fd478a679
--- /dev/null
+++ b/tests/auto/core/qwebengineurlrequestinterceptor/resources/media.html
@@ -0,0 +1,7 @@
+<html>
+<body>
+<video width="320" height="240" controls="">
+ <source src="media.mp4" type="video/mp4">
+</video>
+</body>
+</html>
diff --git a/tests/auto/core/qwebengineurlrequestinterceptor/resources/media.mp4 b/tests/auto/core/qwebengineurlrequestinterceptor/resources/media.mp4
new file mode 100644
index 000000000..1431e98dd
--- /dev/null
+++ b/tests/auto/core/qwebengineurlrequestinterceptor/resources/media.mp4
Binary files differ
diff --git a/tests/auto/core/qwebengineurlrequestinterceptor/resources/media_in_iframe.html b/tests/auto/core/qwebengineurlrequestinterceptor/resources/media_in_iframe.html
new file mode 100644
index 000000000..39e9bd9bb
--- /dev/null
+++ b/tests/auto/core/qwebengineurlrequestinterceptor/resources/media_in_iframe.html
@@ -0,0 +1,5 @@
+<html>
+<body>
+<iframe src="media.html"></iframe>
+</body>
+</html>
diff --git a/tests/auto/core/qwebengineurlrequestinterceptor/resources/resource.html b/tests/auto/core/qwebengineurlrequestinterceptor/resources/resource.html
new file mode 100644
index 000000000..040acee00
--- /dev/null
+++ b/tests/auto/core/qwebengineurlrequestinterceptor/resources/resource.html
@@ -0,0 +1,9 @@
+<html>
+<head>
+<link rel='stylesheet' href='style.css' type='text/css' />
+<script src="script.js"></script>
+</head>
+<body>
+<p>some text</p>
+</body>
+</html
diff --git a/tests/auto/core/qwebengineurlrequestinterceptor/resources/resource_in_iframe.html b/tests/auto/core/qwebengineurlrequestinterceptor/resources/resource_in_iframe.html
new file mode 100644
index 000000000..573182668
--- /dev/null
+++ b/tests/auto/core/qwebengineurlrequestinterceptor/resources/resource_in_iframe.html
@@ -0,0 +1,5 @@
+<html>
+<body>
+<iframe src="resource.html"></iframe>
+</body>
+</html>
diff --git a/tests/auto/core/qwebengineurlrequestinterceptor/resources/script.js b/tests/auto/core/qwebengineurlrequestinterceptor/resources/script.js
new file mode 100644
index 000000000..e6e0e8e7d
--- /dev/null
+++ b/tests/auto/core/qwebengineurlrequestinterceptor/resources/script.js
@@ -0,0 +1,3 @@
+var request = new XMLHttpRequest();
+request.open('GET', 'test', /* async = */ false);
+request.send();
diff --git a/tests/auto/core/qwebengineurlrequestinterceptor/resources/style.css b/tests/auto/core/qwebengineurlrequestinterceptor/resources/style.css
new file mode 100644
index 000000000..5ed3811e2
--- /dev/null
+++ b/tests/auto/core/qwebengineurlrequestinterceptor/resources/style.css
@@ -0,0 +1,7 @@
+@font-face {
+ font-family: fontawesome;
+ src: url(fontawesome.woff);
+}
+p {
+ font-family: fontawesome;
+}
diff --git a/tests/auto/core/qwebengineurlrequestinterceptor/tst_qwebengineurlrequestinterceptor.cpp b/tests/auto/core/qwebengineurlrequestinterceptor/tst_qwebengineurlrequestinterceptor.cpp
index 50a3e6ff6..23bf88417 100644
--- a/tests/auto/core/qwebengineurlrequestinterceptor/tst_qwebengineurlrequestinterceptor.cpp
+++ b/tests/auto/core/qwebengineurlrequestinterceptor/tst_qwebengineurlrequestinterceptor.cpp
@@ -28,6 +28,7 @@
#include "../../widgets/util.h"
#include <QtTest/QtTest>
+#include <QtWebEngineCore/qwebengineurlrequestinfo.h>
#include <QtWebEngineCore/qwebengineurlrequestinterceptor.h>
#include <QtWebEngineWidgets/qwebenginepage.h>
#include <QtWebEngineWidgets/qwebengineprofile.h>
@@ -53,6 +54,11 @@ private Q_SLOTS:
void requestedUrl();
void setUrlSameUrl();
void firstPartyUrl();
+ void firstPartyUrlNestedIframes_data();
+ void firstPartyUrlNestedIframes();
+ void requestInterceptorByResourceType_data();
+ void requestInterceptorByResourceType();
+ void firstPartyUrlHttp();
};
tst_QWebEngineUrlRequestInterceptor::tst_QWebEngineUrlRequestInterceptor()
@@ -79,11 +85,22 @@ void tst_QWebEngineUrlRequestInterceptor::cleanupTestCase()
{
}
+struct RequestInfo {
+ RequestInfo(QWebEngineUrlRequestInfo &info)
+ : requestUrl(info.requestUrl())
+ , firstPartyUrl(info.firstPartyUrl())
+ , resourceType(info.resourceType())
+ {}
+
+ QUrl requestUrl;
+ QUrl firstPartyUrl;
+ int resourceType;
+};
+
class TestRequestInterceptor : public QWebEngineUrlRequestInterceptor
{
public:
- QList<QUrl> observedUrls;
- QList<QUrl> firstPartyUrls;
+ QList<RequestInfo> requestInfos;
bool shouldIntercept;
void interceptRequest(QWebEngineUrlRequestInfo &info) override
@@ -95,9 +112,51 @@ public:
if (shouldIntercept && info.requestUrl().toString().endsWith(QLatin1String("__placeholder__")))
info.redirect(QUrl("qrc:///resources/content.html"));
- observedUrls.append(info.requestUrl());
- firstPartyUrls.append(info.firstPartyUrl());
+ requestInfos.append(info);
+ }
+
+ bool shouldSkipRequest(const RequestInfo &requestInfo)
+ {
+ if (requestInfo.resourceType == QWebEngineUrlRequestInfo::ResourceTypeMainFrame ||
+ requestInfo.resourceType == QWebEngineUrlRequestInfo::ResourceTypeSubFrame)
+ return false;
+
+ // Skip import documents and sandboxed documents.
+ // See Document::SiteForCookies() in chromium/third_party/blink/renderer/core/dom/document.cc.
+ //
+ // TODO: Change this to empty URL during the next chromium update:
+ // https://chromium-review.googlesource.com/c/chromium/src/+/1213082/
+ return requestInfo.firstPartyUrl == QUrl("data:,");
+ }
+
+ QList<RequestInfo> getUrlRequestForType(QWebEngineUrlRequestInfo::ResourceType type)
+ {
+ QList<RequestInfo> infos;
+
+ foreach (auto requestInfo, requestInfos) {
+ if (shouldSkipRequest(requestInfo))
+ continue;
+
+ if (type == requestInfo.resourceType)
+ infos.append(requestInfo);
+ }
+
+ return infos;
+ }
+
+ bool hasUrlRequestForType(QWebEngineUrlRequestInfo::ResourceType type)
+ {
+ foreach (auto requestInfo, requestInfos) {
+ if (shouldSkipRequest(requestInfo))
+ continue;
+
+ if (type == requestInfo.resourceType)
+ return true;
+ }
+
+ return false;
}
+
TestRequestInterceptor(bool intercept)
: shouldIntercept(intercept)
{
@@ -135,7 +194,7 @@ void tst_QWebEngineUrlRequestInterceptor::interceptRequest()
// The redirection for __placeholder__ should succeed.
QVERIFY(success.toBool());
loadSpy.clear();
- QCOMPARE(interceptor.observedUrls.count(), 4);
+ QCOMPARE(interceptor.requestInfos.count(), 4);
// Make sure that registering an observer does not modify the request.
TestRequestInterceptor observer(/* intercept */ false);
@@ -145,7 +204,7 @@ void tst_QWebEngineUrlRequestInterceptor::interceptRequest()
success = loadSpy.takeFirst().takeFirst();
// Since we do not intercept, loading an invalid path should not succeed.
QVERIFY(!success.toBool());
- QCOMPARE(observer.observedUrls.count(), 1);
+ QCOMPARE(observer.requestInfos.count(), 1);
}
class LocalhostContentProvider : public QWebEngineUrlRequestInterceptor
@@ -203,19 +262,19 @@ void tst_QWebEngineUrlRequestInterceptor::requestedUrl()
page.setUrl(QUrl("qrc:///resources/__placeholder__"));
QVERIFY(spy.wait());
QTRY_COMPARE(spy.count(), 1);
- QCOMPARE(interceptor.observedUrls.at(0), QUrl("qrc:///resources/content.html"));
+ QCOMPARE(interceptor.requestInfos.at(0).requestUrl, QUrl("qrc:///resources/content.html"));
QCOMPARE(page.requestedUrl(), QUrl("qrc:///resources/__placeholder__"));
QCOMPARE(page.url(), QUrl("qrc:///resources/content.html"));
page.setUrl(QUrl("qrc:/non-existent.html"));
QTRY_COMPARE(spy.count(), 2);
- QCOMPARE(interceptor.observedUrls.at(2), QUrl("qrc:/non-existent.html"));
+ QCOMPARE(interceptor.requestInfos.at(2).requestUrl, QUrl("qrc:/non-existent.html"));
QCOMPARE(page.requestedUrl(), QUrl("qrc:///resources/__placeholder__"));
QCOMPARE(page.url(), QUrl("qrc:///resources/content.html"));
page.setUrl(QUrl("http://abcdef.abcdef"));
QTRY_COMPARE_WITH_TIMEOUT(spy.count(), 3, 12000);
- QCOMPARE(interceptor.observedUrls.at(3), QUrl("http://abcdef.abcdef/"));
+ QCOMPARE(interceptor.requestInfos.at(3).requestUrl, QUrl("http://abcdef.abcdef/"));
QCOMPARE(page.requestedUrl(), QUrl("qrc:///resources/__placeholder__"));
QCOMPARE(page.url(), QUrl("qrc:///resources/content.html"));
}
@@ -262,12 +321,171 @@ void tst_QWebEngineUrlRequestInterceptor::firstPartyUrl()
page.setUrl(QUrl("qrc:///resources/firstparty.html"));
QVERIFY(spy.wait());
- QCOMPARE(interceptor.observedUrls.at(0), QUrl("qrc:///resources/firstparty.html"));
- QCOMPARE(interceptor.observedUrls.at(1), QUrl("qrc:///resources/content.html"));
- QCOMPARE(interceptor.firstPartyUrls.at(0), QUrl("qrc:///resources/firstparty.html"));
- QCOMPARE(interceptor.firstPartyUrls.at(1), QUrl("qrc:///resources/firstparty.html"));
+ QCOMPARE(interceptor.requestInfos.at(0).requestUrl, QUrl("qrc:///resources/firstparty.html"));
+ QCOMPARE(interceptor.requestInfos.at(1).requestUrl, QUrl("qrc:///resources/content.html"));
+ QCOMPARE(interceptor.requestInfos.at(0).firstPartyUrl, QUrl("qrc:///resources/firstparty.html"));
+ QCOMPARE(interceptor.requestInfos.at(1).firstPartyUrl, QUrl("qrc:///resources/firstparty.html"));
QCOMPARE(spy.count(), 1);
}
+void tst_QWebEngineUrlRequestInterceptor::firstPartyUrlNestedIframes_data()
+{
+ QUrl url = QUrl::fromLocalFile(TESTS_SOURCE_DIR + QLatin1String("qwebengineurlrequestinterceptor/resources/iframe.html"));
+
+ QTest::addColumn<QUrl>("requestUrl");
+ QTest::newRow("file") << url;
+ QTest::newRow("qrc") << QUrl("qrc:///resources/iframe.html");
+}
+
+void tst_QWebEngineUrlRequestInterceptor::firstPartyUrlNestedIframes()
+{
+ QFETCH(QUrl, requestUrl);
+
+ if (requestUrl.scheme() == "file" && !QDir(TESTS_SOURCE_DIR).exists())
+ W_QSKIP(QString("This test requires access to resources found in '%1'").arg(TESTS_SOURCE_DIR).toLatin1().constData(), SkipAll);
+
+ QString adjustedUrl = requestUrl.adjusted(QUrl::RemoveFilename).toString();
+
+ QWebEngineProfile profile;
+ TestRequestInterceptor interceptor(/* intercept */ false);
+ profile.setRequestInterceptor(&interceptor);
+
+ QWebEnginePage page(&profile);
+ QSignalSpy loadSpy(&page, SIGNAL(loadFinished(bool)));
+ page.setUrl(requestUrl);
+ QTRY_COMPARE(loadSpy.count(), 1);
+
+ RequestInfo info = interceptor.requestInfos.at(0);
+ QCOMPARE(info.requestUrl, requestUrl);
+ QCOMPARE(info.firstPartyUrl, requestUrl);
+ QCOMPARE(info.resourceType, QWebEngineUrlRequestInfo::ResourceTypeMainFrame);
+
+ info = interceptor.requestInfos.at(1);
+ QCOMPARE(info.requestUrl, QUrl(adjustedUrl + "iframe2.html"));
+ QCOMPARE(info.firstPartyUrl, requestUrl);
+ QCOMPARE(info.resourceType, QWebEngineUrlRequestInfo::ResourceTypeSubFrame);
+
+ info = interceptor.requestInfos.at(2);
+ QCOMPARE(info.requestUrl, QUrl(adjustedUrl + "iframe3.html"));
+ QCOMPARE(info.firstPartyUrl, requestUrl);
+ QCOMPARE(info.resourceType, QWebEngineUrlRequestInfo::ResourceTypeSubFrame);
+}
+
+void tst_QWebEngineUrlRequestInterceptor::requestInterceptorByResourceType_data()
+{
+ QUrl firstPartyUrl = QUrl::fromLocalFile(TESTS_SOURCE_DIR + QLatin1String("qwebengineurlrequestinterceptor/resources/resource_in_iframe.html"));
+ QUrl styleRequestUrl = QUrl::fromLocalFile(TESTS_SOURCE_DIR + QLatin1String("qwebengineurlrequestinterceptor/resources/style.css"));
+ QUrl scriptRequestUrl = QUrl::fromLocalFile(TESTS_SOURCE_DIR + QLatin1String("qwebengineurlrequestinterceptor/resources/script.js"));
+ QUrl fontRequestUrl = QUrl::fromLocalFile(TESTS_SOURCE_DIR + QLatin1String("qwebengineurlrequestinterceptor/resources/fontawesome.woff"));
+ QUrl xhrRequestUrl = QUrl::fromLocalFile(TESTS_SOURCE_DIR + QLatin1String("qwebengineurlrequestinterceptor/resources/test"));
+ QUrl imageFirstPartyUrl = QUrl::fromLocalFile(TESTS_SOURCE_DIR + QLatin1String("qwebengineurlrequestinterceptor/resources/image_in_iframe.html"));
+ QUrl imageRequestUrl = QUrl::fromLocalFile(TESTS_SOURCE_DIR + QLatin1String("qwebengineurlrequestinterceptor/resources/icons/favicon.png"));
+ QUrl mediaFirstPartyUrl = QUrl::fromLocalFile(TESTS_SOURCE_DIR + QLatin1String("qwebengineurlrequestinterceptor/resources/media_in_iframe.html"));
+ QUrl mediaRequestUrl = QUrl::fromLocalFile(TESTS_SOURCE_DIR + QLatin1String("qwebengineurlrequestinterceptor/resources/media.mp4"));
+ QUrl faviconFirstPartyUrl = QUrl::fromLocalFile(TESTS_SOURCE_DIR + QLatin1String("qwebengineurlrequestinterceptor/resources/favicon.html"));
+ QUrl faviconRequestUrl = QUrl::fromLocalFile(TESTS_SOURCE_DIR + QLatin1String("qwebengineurlrequestinterceptor/resources/icons/favicon.png"));
+
+ QTest::addColumn<QUrl>("requestUrl");
+ QTest::addColumn<QUrl>("firstPartyUrl");
+ QTest::addColumn<int>("resourceType");
+
+ QTest::newRow("StyleSheet") << styleRequestUrl << firstPartyUrl << static_cast<int>(QWebEngineUrlRequestInfo::ResourceTypeStylesheet);
+ QTest::newRow("Script") << scriptRequestUrl << firstPartyUrl << static_cast<int>(QWebEngineUrlRequestInfo::ResourceTypeScript);
+ QTest::newRow("Image") << imageRequestUrl << imageFirstPartyUrl << static_cast<int>(QWebEngineUrlRequestInfo::ResourceTypeImage);
+ QTest::newRow("FontResource") << fontRequestUrl << firstPartyUrl << static_cast<int>(QWebEngineUrlRequestInfo::ResourceTypeFontResource);
+ QTest::newRow("Media") << mediaRequestUrl << mediaFirstPartyUrl << static_cast<int>(QWebEngineUrlRequestInfo::ResourceTypeMedia);
+ QTest::newRow("Favicon") << faviconRequestUrl << faviconFirstPartyUrl << static_cast<int>(QWebEngineUrlRequestInfo::ResourceTypeFavicon);
+ QTest::newRow("Xhr") << xhrRequestUrl << firstPartyUrl << static_cast<int>(QWebEngineUrlRequestInfo::ResourceTypeXhr);
+}
+
+void tst_QWebEngineUrlRequestInterceptor::requestInterceptorByResourceType()
+{
+ if (!QDir(TESTS_SOURCE_DIR).exists())
+ W_QSKIP(QString("This test requires access to resources found in '%1'").arg(TESTS_SOURCE_DIR).toLatin1().constData(), SkipAll);
+
+ QFETCH(QUrl, requestUrl);
+ QFETCH(QUrl, firstPartyUrl);
+ QFETCH(int, resourceType);
+
+ QWebEngineProfile profile;
+ TestRequestInterceptor interceptor(/* intercept */ false);
+ profile.setRequestInterceptor(&interceptor);
+
+ QWebEnginePage page(&profile);
+ QSignalSpy loadSpy(&page, SIGNAL(loadFinished(bool)));
+ page.setUrl(firstPartyUrl);
+ QTRY_COMPARE(loadSpy.count(), 1);
+
+ QTRY_COMPARE(interceptor.getUrlRequestForType(static_cast<QWebEngineUrlRequestInfo::ResourceType>(resourceType)).count(), 1);
+ QList<RequestInfo> infos = interceptor.getUrlRequestForType(static_cast<QWebEngineUrlRequestInfo::ResourceType>(resourceType));
+ QCOMPARE(infos.at(0).requestUrl, requestUrl);
+ QCOMPARE(infos.at(0).firstPartyUrl, firstPartyUrl);
+ QCOMPARE(infos.at(0).resourceType, resourceType);
+}
+
+void tst_QWebEngineUrlRequestInterceptor::firstPartyUrlHttp()
+{
+ QWebEngineProfile profile;
+ TestRequestInterceptor interceptor(/* intercept */ false);
+ profile.setRequestInterceptor(&interceptor);
+
+ QWebEnginePage page(&profile);
+ QSignalSpy loadSpy(&page, SIGNAL(loadFinished(bool)));
+ QUrl firstPartyUrl = QUrl("https://www.w3schools.com/tags/tryit.asp?filename=tryhtml5_video");
+ page.setUrl(QUrl(firstPartyUrl));
+ if (!loadSpy.wait(15000) || !loadSpy.at(0).at(0).toBool())
+ QSKIP("Couldn't load page from network, skipping test.");
+
+ QList<RequestInfo> infos;
+
+ // SubFrame
+ QTRY_VERIFY(interceptor.hasUrlRequestForType(QWebEngineUrlRequestInfo::ResourceTypeSubFrame));
+ infos = interceptor.getUrlRequestForType(QWebEngineUrlRequestInfo::ResourceTypeSubFrame);
+ foreach (auto info, infos)
+ QCOMPARE(info.firstPartyUrl, firstPartyUrl);
+
+ // Stylesheet
+ QTRY_VERIFY(interceptor.hasUrlRequestForType(QWebEngineUrlRequestInfo::ResourceTypeStylesheet));
+ infos = interceptor.getUrlRequestForType(QWebEngineUrlRequestInfo::ResourceTypeStylesheet);
+ foreach (auto info, infos)
+ QCOMPARE(info.firstPartyUrl, firstPartyUrl);
+
+ // Script
+ QTRY_VERIFY(interceptor.hasUrlRequestForType(QWebEngineUrlRequestInfo::ResourceTypeScript));
+ infos = interceptor.getUrlRequestForType(QWebEngineUrlRequestInfo::ResourceTypeScript);
+ foreach (auto info, infos)
+ QCOMPARE(info.firstPartyUrl, firstPartyUrl);
+
+ // Image
+ QTRY_VERIFY(interceptor.hasUrlRequestForType(QWebEngineUrlRequestInfo::ResourceTypeImage));
+ infos = interceptor.getUrlRequestForType(QWebEngineUrlRequestInfo::ResourceTypeImage);
+ foreach (auto info, infos)
+ QCOMPARE(info.firstPartyUrl, firstPartyUrl);
+
+ // FontResource
+ QTRY_VERIFY(interceptor.hasUrlRequestForType(QWebEngineUrlRequestInfo::ResourceTypeFontResource));
+ infos = interceptor.getUrlRequestForType(QWebEngineUrlRequestInfo::ResourceTypeFontResource);
+ foreach (auto info, infos)
+ QCOMPARE(info.firstPartyUrl, firstPartyUrl);
+
+ // Media
+ QTRY_VERIFY(interceptor.hasUrlRequestForType(QWebEngineUrlRequestInfo::ResourceTypeMedia));
+ infos = interceptor.getUrlRequestForType(QWebEngineUrlRequestInfo::ResourceTypeMedia);
+ foreach (auto info, infos)
+ QCOMPARE(info.firstPartyUrl, firstPartyUrl);
+
+ // Favicon
+ QTRY_VERIFY(interceptor.hasUrlRequestForType(QWebEngineUrlRequestInfo::ResourceTypeFavicon));
+ infos = interceptor.getUrlRequestForType(QWebEngineUrlRequestInfo::ResourceTypeFavicon);
+ foreach (auto info, infos)
+ QCOMPARE(info.firstPartyUrl, firstPartyUrl);
+
+ // XMLHttpRequest
+ QTRY_VERIFY(interceptor.hasUrlRequestForType(QWebEngineUrlRequestInfo::ResourceTypeXhr));
+ infos = interceptor.getUrlRequestForType(QWebEngineUrlRequestInfo::ResourceTypeXhr);
+ foreach (auto info, infos)
+ QCOMPARE(info.firstPartyUrl, firstPartyUrl);
+}
+
QTEST_MAIN(tst_QWebEngineUrlRequestInterceptor)
#include "tst_qwebengineurlrequestinterceptor.moc"
diff --git a/tests/auto/core/qwebengineurlrequestinterceptor/tst_qwebengineurlrequestinterceptor.qrc b/tests/auto/core/qwebengineurlrequestinterceptor/tst_qwebengineurlrequestinterceptor.qrc
index ca045e7fc..13dbb134e 100644
--- a/tests/auto/core/qwebengineurlrequestinterceptor/tst_qwebengineurlrequestinterceptor.qrc
+++ b/tests/auto/core/qwebengineurlrequestinterceptor/tst_qwebengineurlrequestinterceptor.qrc
@@ -1,7 +1,22 @@
<!DOCTYPE RCC><RCC version="1.0">
-<qresource>
- <file>resources/index.html</file>
- <file>resources/content.html</file>
- <file>resources/firstparty.html</file>
-</qresource>
+ <qresource prefix="/">
+ <file>resources/content.html</file>
+ <file>resources/favicon.html</file>
+ <file>resources/firstparty.html</file>
+ <file>resources/fontawesome.woff</file>
+ <file>resources/iframe.html</file>
+ <file>resources/iframe2.html</file>
+ <file>resources/iframe3.html</file>
+ <file>resources/image.html</file>
+ <file>resources/image_in_iframe.html</file>
+ <file>resources/index.html</file>
+ <file>resources/media.html</file>
+ <file>resources/media.mp4</file>
+ <file>resources/media_in_iframe.html</file>
+ <file>resources/resource.html</file>
+ <file>resources/resource_in_iframe.html</file>
+ <file>resources/script.js</file>
+ <file>resources/style.css</file>
+ <file>resources/icons/favicon.png</file>
+ </qresource>
</RCC>
diff --git a/tests/auto/core/tests.pri b/tests/auto/core/tests.pri
index 885cf60d4..59d6c0865 100644
--- a/tests/auto/core/tests.pri
+++ b/tests/auto/core/tests.pri
@@ -12,4 +12,6 @@ exists($$_PRO_FILE_PWD_/$${TARGET}.qrc): RESOURCES += $${TARGET}.qrc
QT += testlib network webenginewidgets widgets
+# This define is used by some tests to look up resources in the source tree
+DEFINES += TESTS_SOURCE_DIR=\\\"$$PWD/\\\"
include(../embed_info_plist.pri)
diff --git a/tests/auto/quick/qquickwebengineview/tst_qquickwebengineview.cpp b/tests/auto/quick/qquickwebengineview/tst_qquickwebengineview.cpp
index 29df3444c..40a3bff5e 100644
--- a/tests/auto/quick/qquickwebengineview/tst_qquickwebengineview.cpp
+++ b/tests/auto/quick/qquickwebengineview/tst_qquickwebengineview.cpp
@@ -484,8 +484,8 @@ struct InputMethodInfo
, selectedText(selectedText)
{}
- const int cursorPosition;
- const int anchorPosition;
+ int cursorPosition;
+ int anchorPosition;
QString surroundingText;
QString selectedText;
};