summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--configure.pri8
-rw-r--r--mkspecs/features/functions.prf9
-rw-r--r--src/core/config/functions.pri8
-rw-r--r--src/core/config/linux.pri6
-rw-r--r--src/core/net/network_delegate_qt.cpp10
-rw-r--r--src/core/net/url_request_notification.cpp13
-rw-r--r--src/webengine/api/qquickwebenginedownloaditem.cpp12
-rw-r--r--src/webengine/doc/src/webengineview_lgpl.qdoc58
-rw-r--r--src/webenginewidgets/api/qwebenginedownloaditem.cpp11
-rw-r--r--src/webenginewidgets/doc/src/qwebenginepage_lgpl.qdoc5
-rw-r--r--tests/auto/core/qwebengineurlrequestinterceptor/qwebengineurlrequestinterceptor.pro1
-rw-r--r--tests/auto/core/qwebengineurlrequestinterceptor/tst_qwebengineurlrequestinterceptor.cpp43
-rw-r--r--tests/auto/widgets/qwebenginedownloaditem/tst_qwebenginedownloaditem.cpp123
-rw-r--r--tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp12
14 files changed, 277 insertions, 42 deletions
diff --git a/configure.pri b/configure.pri
index 8db31ddd3..d03d3c8e0 100644
--- a/configure.pri
+++ b/configure.pri
@@ -1,3 +1,5 @@
+include(src/core/config/functions.pri)
+
# this must be done outside any function
QTWEBENGINE_SOURCE_TREE = $$PWD
@@ -297,12 +299,12 @@ defineTest(qtConfTest_isWindowsHostCompiler64) {
# Fixme QTBUG-71772
defineTest(qtConfTest_hasThumbFlag) {
- FLAG = $$extractCFlag("-mthumb")
+ FLAG = $$qtwebengine_extractCFlag("-mthumb")
!isEmpty(FLAG): return(true)
- FLAG = $$extractCFlag("-marm")
+ FLAG = $$qtwebengine_extractCFlag("-marm")
!isEmpty(FLAG): return(false)
- MARCH = $$extractCFlag("-march=.*")
+ MARCH = $$qtwebengine_extractCFlag("-march=.*")
MARMV = $$replace(MARCH, "armv",)
!isEmpty(MARMV) {
MARMV = $$split(MARMV,)
diff --git a/mkspecs/features/functions.prf b/mkspecs/features/functions.prf
index f6aeea21a..9efa8958f 100644
--- a/mkspecs/features/functions.prf
+++ b/mkspecs/features/functions.prf
@@ -10,15 +10,6 @@ defineReplace(getChromiumSrcDir) {
return($$git_chromium_src_dir)
}
-defineReplace(extractCFlag) {
- CFLAGS = $$QMAKE_CC $$QMAKE_CFLAGS
- OPTION = $$find(CFLAGS, $$1)
- OPTION = $$split(OPTION, =)
- PARAM = $$member(OPTION, 1)
- !isEmpty(PARAM): return ($$PARAM)
- return ($$OPTION)
-}
-
defineReplace(which) {
out = $$1
win32 {
diff --git a/src/core/config/functions.pri b/src/core/config/functions.pri
new file mode 100644
index 000000000..8c11faa16
--- /dev/null
+++ b/src/core/config/functions.pri
@@ -0,0 +1,8 @@
+defineReplace(qtwebengine_extractCFlag) {
+ CFLAGS = $$QMAKE_CC $$QMAKE_CFLAGS
+ OPTION = $$find(CFLAGS, $$1)
+ OPTION = $$split(OPTION, =)
+ PARAM = $$member(OPTION, 1)
+ !isEmpty(PARAM): return ($$PARAM)
+ return ($$OPTION)
+}
diff --git a/src/core/config/linux.pri b/src/core/config/linux.pri
index fcce4c316..e45273cca 100644
--- a/src/core/config/linux.pri
+++ b/src/core/config/linux.pri
@@ -1,4 +1,10 @@
include(common.pri)
+include(functions.pri)
+
+defineReplace(extractCFlag) {
+ return($$qtwebengine_extractCFlag($$1))
+}
+
QT_FOR_CONFIG += gui-private webenginecore-private
gn_args += \
diff --git a/src/core/net/network_delegate_qt.cpp b/src/core/net/network_delegate_qt.cpp
index 31da45314..7f278fd92 100644
--- a/src/core/net/network_delegate_qt.cpp
+++ b/src/core/net/network_delegate_qt.cpp
@@ -150,8 +150,14 @@ int NetworkDelegateQt::OnBeforeURLRequest(net::URLRequest *request, net::Complet
if (!infoPrivate->extraHeaders.isEmpty()) {
auto end = infoPrivate->extraHeaders.constEnd();
- for (auto header = infoPrivate->extraHeaders.constBegin(); header != end; ++header)
- request->SetExtraRequestHeaderByName(header.key().toStdString(), header.value().toStdString(), /* overwrite */ true);
+ for (auto header = infoPrivate->extraHeaders.constBegin(); header != end; ++header) {
+ std::string h = header.key().toStdString();
+ if (base::LowerCaseEqualsASCII(h, "referer")) {
+ request->SetReferrer(header.value().toStdString());
+ } else {
+ request->SetExtraRequestHeaderByName(h, header.value().toStdString(), /* overwrite */ true);
+ }
+ }
}
if (result != net::OK)
diff --git a/src/core/net/url_request_notification.cpp b/src/core/net/url_request_notification.cpp
index 6da661cff..e37ad35bc 100644
--- a/src/core/net/url_request_notification.cpp
+++ b/src/core/net/url_request_notification.cpp
@@ -109,7 +109,8 @@ void URLRequestNotification::notify()
if (m_profileAdapter) {
QWebEngineUrlRequestInterceptor* interceptor = m_profileAdapter->requestInterceptor();
- interceptor->interceptRequest(m_requestInfo);
+ if (!interceptor->property("deprecated").toBool())
+ interceptor->interceptRequest(m_requestInfo);
}
WebContentsAdapterClient *client =
@@ -171,8 +172,14 @@ void URLRequestNotification::complete(int error)
if (!m_requestInfo.d_ptr->extraHeaders.isEmpty()) {
auto end = m_requestInfo.d_ptr->extraHeaders.constEnd();
- for (auto header = m_requestInfo.d_ptr->extraHeaders.constBegin(); header != end; ++header)
- m_request->SetExtraRequestHeaderByName(header.key().toStdString(), header.value().toStdString(), /* overwrite */ true);
+ for (auto header = m_requestInfo.d_ptr->extraHeaders.constBegin(); header != end; ++header) {
+ std::string h = header.key().toStdString();
+ if (base::LowerCaseEqualsASCII(h, "referer")) {
+ m_request->SetReferrer(header.value().toStdString());
+ } else {
+ m_request->SetExtraRequestHeaderByName(h, header.value().toStdString(), /* overwrite */ true);
+ }
+ }
}
}
diff --git a/src/webengine/api/qquickwebenginedownloaditem.cpp b/src/webengine/api/qquickwebenginedownloaditem.cpp
index cdb95fa53..7d51ed21d 100644
--- a/src/webengine/api/qquickwebenginedownloaditem.cpp
+++ b/src/webengine/api/qquickwebenginedownloaditem.cpp
@@ -43,6 +43,8 @@
#include "profile_adapter.h"
#include "qquickwebengineprofile_p.h"
+#include "QFileInfo"
+
using QtWebEngineCore::ProfileAdapterClient;
QT_BEGIN_NAMESPACE
@@ -427,6 +429,16 @@ void QQuickWebEngineDownloadItem::setPath(QString path)
return;
}
if (d->downloadPath != path) {
+ if (QFileInfo(path).fileName().isEmpty()) {
+ qWarning("The download path does not include file name.");
+ return;
+ }
+
+ if (QFileInfo(path).isDir()) {
+ qWarning("The download path matches with an already existing directory path.");
+ return;
+ }
+
d->downloadPath = path;
Q_EMIT pathChanged();
}
diff --git a/src/webengine/doc/src/webengineview_lgpl.qdoc b/src/webengine/doc/src/webengineview_lgpl.qdoc
index 3537bbd19..38c84f848 100644
--- a/src/webengine/doc/src/webengineview_lgpl.qdoc
+++ b/src/webengine/doc/src/webengineview_lgpl.qdoc
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2015 The Qt Company Ltd.
+ * Copyright (C) 2019 The Qt Company Ltd.
* Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies)
* Copyright (c) 2012 Hewlett-Packard Development Company, L.P.
*
@@ -395,6 +395,11 @@
runJavaScript("document.title", function(result) { console.log(result); });
\endcode
+ Only "plain data" can be returned from JavaScript as the result value.
+ Supported data types include all of the JSON data types as well as, for
+ example, \c{Date} and \c{ArrayBuffer}. Unsupported data types include, for
+ example, \c{Function} and \c{Promise}.
+
The script will run in the same \e world as other scripts that are
part of the loaded site.
@@ -486,7 +491,8 @@
a web engine view can be used to create a UI element that should not get focus. This can be
useful in a hybrid UI.
- \sa activeFocusOnPressChanged, WebEngineSettings::focusOnNavigationEnabled
+ \sa activeFocusOnPress, activeFocusOnPressChanged,
+ WebEngineSettings::focusOnNavigationEnabled
*/
/*!
@@ -524,7 +530,8 @@
\qmlsignal WebEngineView::certificateError(WebEngineCertificateError error)
\since QtWebEngine 1.1
- This signal is emitted when an invalid certificate error is raised while loading a given request.
+ This signal is emitted when an invalid certificate error, \a error, is
+ raised while loading a given request.
The certificate error can be handled by using the methods of the WebEngineCertificateError
type.
@@ -560,7 +567,7 @@
\qmlsignal WebEngineView::newViewRequested(WebEngineNewViewRequest request)
\since QtWebEngine 1.1
- This signal is emitted when a page load is requested to happen in a separate
+ This signal is emitted when \a request is issued to load a page in a separate
web engine view. This can either be because the current page requested it explicitly
through a JavaScript call to \c window.open, or because the user clicked on a link
while holding Shift, Ctrl, or a built-in combination that triggers the page to open
@@ -579,8 +586,8 @@
\qmlsignal WebEngineView::fullScreenRequested(FullScreenRequest request)
\since QtWebEngine 1.1
- This signal is emitted when the web page requests fullscreen mode through the
- JavaScript API.
+ This signal is emitted when the web page issues the \a request for
+ fullscreen mode through the JavaScript API.
\sa isFullScreen
*/
@@ -589,10 +596,10 @@
\qmlsignal WebEngineView::activeFocusOnPressChanged(bool activeFocusOnPress)
\since QtWebEngine 1.2
- This signal is emitted when the ability of the web engine view to get focus when clicked
- changes.
+ This signal is emitted when the value of \a activeFocusOnPress changes.
+ It specifies whether the view should gain active focus when pressed.
- \sa setActiveFocusOnPress()
+ \sa activeFocusOnPress, setActiveFocusOnPress()
*/
/*!
@@ -1109,7 +1116,8 @@
\qmlsignal WebEngineView::audioMutedChanged(bool muted)
\since QtWebEngine 1.3
- This signal is emitted when the page's audio is (un)muted using audioMuted property.
+ This signal is emitted when the value of \a muted changes. The value is
+ specified using the \l audioMuted property.
\note Not to be confused with a specific HTML5 audio / video element being muted.
\sa audioMuted, recentlyAudibleChanged
@@ -1127,10 +1135,10 @@
\qmlsignal WebEngineView::recentlyAudibleChanged(bool recentlyAudible)
\since QtWebEngine 1.3
- This signal is emitted when the page's audible state is changed, due to audio
- being played or stopped.
+ This signal is emitted when the page's audible state, specified by
+ \a recentlyAudible, is changed, due to audio being played or stopped.
- \note The signal is also emitted when the audioMuted property changes.
+ \note The signal is also emitted when the \l audioMuted property changes.
Also if the audio is paused, this signal is emitted with an approximate \b{two-second
delay}, from the moment the audio is paused.
@@ -1176,7 +1184,7 @@
PDF and returns immediately. To be informed about the result of the
request, connect to the signal pdfPrintingFinished().
- If you leave out \a pageSizeID, it defaults to \c A4. If you leave out
+ If you leave out \a pageSizeId, it defaults to \c A4. If you leave out
\a orientation, it defaults to \c Portrait.
\sa pdfPrintingFinished()
@@ -1192,7 +1200,7 @@
The \a resultCallback must take a string parameter. This string will contain the document's data upon successful printing and an empty
string otherwise.
- If you leave out \a pageSizeID, it defaults to \c A4. If you leave out
+ If you leave out \a pageSizeId, it defaults to \c A4. If you leave out
\a orientation, it defaults to \c Portrait.
*/
@@ -1207,8 +1215,8 @@
\qmlsignal WebEngineView::wasRecentlyAudibleChanged(bool wasRecentlyAudible)
\since QtWebEngine 1.3
- This signal is emitted when the page's audible state is changed, due to audio
- being played or stopped.
+ This signal is emitted when the page's audible state, specified by
+ \a wasRecentlyAudible, is changed, due to audio being played or stopped.
\note The signal is also emitted when calling the setAudioMuted method.
Also if the audio is paused, this signal is emitted with an approximate \b{2 second
@@ -1221,7 +1229,7 @@
This signal is emitted when an authentication dialog is requested.
- The request can be handled by using the methods of the AuthenticationDialogRequest
+ The \a request can be handled by using the methods of the AuthenticationDialogRequest
type.
\note Signal handlers need to call \c{request.accepted = true} to prevent a
@@ -1236,7 +1244,7 @@
This signal is emitted when a JavaScript dialog is requested.
- The request can be handled by using the methods of the JavaScriptDialogRequest
+ The \a request can be handled by using the methods of the JavaScriptDialogRequest
type.
\note Signal handlers need to call \c{request.accepted = true} to prevent a
@@ -1251,7 +1259,7 @@
This signal is emitted when a color picker dialog is requested.
- The request can be handled by using the methods of the ColorDialogRequest
+ The \a request can be handled by using the methods of the ColorDialogRequest
type.
\note Signal handlers need to call \c{request.accepted = true} to prevent a
@@ -1265,7 +1273,7 @@
This signal is emitted when a file picker dialog is requested.
- The request error can be handled by using the methods of the FileDialogRequest
+ The \a request can be handled by using the methods of the FileDialogRequest
type.
\note Signal handlers need to call \c{request.accepted = true} to prevent a
@@ -1287,7 +1295,7 @@
This signal is emitted when a context menu is requested.
- The request can be handled by using the properties of the ContextMenuRequest
+ The \a request can be handled by using the properties of the ContextMenuRequest
type.
\note Signal handlers need to call \c{request.accepted = true} to prevent a
@@ -1302,7 +1310,7 @@
\qmlsignal WebEngineView::quotaRequested(QuotaRequest request)
\since QtWebEngine 1.7
- This signal is emitted when the web page requests larger persistent storage
+ This signal is emitted when the web page issues a \a request for a larger persistent storage
than the application's current allocation in File System API. The default quota
is 0 bytes.
@@ -1361,7 +1369,7 @@
\since QtWebEngine 1.7
This signal is emitted when the web page tries to register a custom protocol
- using the \l registerProtocolHandler API.
+ by issuing a \l registerProtocolHandler \a request.
\sa RegisterProtocolHandlerRequest
*/
@@ -1457,7 +1465,7 @@
\qmlmethod WebEngineAction WebEngineView::action(WebAction action)
\since 5.12
- Returns a \l WebEngineAction for the specified \l WebAction action.
+ Returns a \l WebEngineAction for the specified \l WebAction \a action.
WebEngineView also takes care of implementing the action,
so that upon triggering the corresponding action is performed on the view.
diff --git a/src/webenginewidgets/api/qwebenginedownloaditem.cpp b/src/webenginewidgets/api/qwebenginedownloaditem.cpp
index 4575f2929..05c6956ea 100644
--- a/src/webenginewidgets/api/qwebenginedownloaditem.cpp
+++ b/src/webenginewidgets/api/qwebenginedownloaditem.cpp
@@ -43,6 +43,7 @@
#include "profile_adapter.h"
#include "qwebengineprofile_p.h"
+#include "QFileInfo"
QT_BEGIN_NAMESPACE
@@ -534,6 +535,16 @@ void QWebEngineDownloadItem::setPath(QString path)
return;
}
+ if (QFileInfo(path).fileName().isEmpty()) {
+ qWarning("The download path does not include file name.");
+ return;
+ }
+
+ if (QFileInfo(path).isDir()) {
+ qWarning("The download path matches with an already existing directory path.");
+ return;
+ }
+
d->downloadPath = path;
}
diff --git a/src/webenginewidgets/doc/src/qwebenginepage_lgpl.qdoc b/src/webenginewidgets/doc/src/qwebenginepage_lgpl.qdoc
index 6e33f8692..e63423be8 100644
--- a/src/webenginewidgets/doc/src/qwebenginepage_lgpl.qdoc
+++ b/src/webenginewidgets/doc/src/qwebenginepage_lgpl.qdoc
@@ -772,6 +772,11 @@
page.runJavaScript("document.title", [](const QVariant &v) { qDebug() << v.toString(); });
\endcode
+ Only "plain data" can be returned from JavaScript as the result value.
+ Supported data types include all of the JSON data types as well as, for
+ example, \c{Date} and \c{ArrayBuffer}. Unsupported data types include, for
+ example, \c{Function} and \c{Promise}.
+
\warning Do not execute lengthy routines in the callback function, because it might block the
rendering of the web engine page.
diff --git a/tests/auto/core/qwebengineurlrequestinterceptor/qwebengineurlrequestinterceptor.pro b/tests/auto/core/qwebengineurlrequestinterceptor/qwebengineurlrequestinterceptor.pro
index e99c7f493..9c239f1a7 100644
--- a/tests/auto/core/qwebengineurlrequestinterceptor/qwebengineurlrequestinterceptor.pro
+++ b/tests/auto/core/qwebengineurlrequestinterceptor/qwebengineurlrequestinterceptor.pro
@@ -1 +1,2 @@
include(../tests.pri)
+include(../../shared/http.pri)
diff --git a/tests/auto/core/qwebengineurlrequestinterceptor/tst_qwebengineurlrequestinterceptor.cpp b/tests/auto/core/qwebengineurlrequestinterceptor/tst_qwebengineurlrequestinterceptor.cpp
index 5629998fd..7d3ad1440 100644
--- a/tests/auto/core/qwebengineurlrequestinterceptor/tst_qwebengineurlrequestinterceptor.cpp
+++ b/tests/auto/core/qwebengineurlrequestinterceptor/tst_qwebengineurlrequestinterceptor.cpp
@@ -34,6 +34,9 @@
#include <QtWebEngineWidgets/qwebengineprofile.h>
#include <QtWebEngineWidgets/qwebenginesettings.h>
+#include <httpserver.h>
+#include <httpreqrep.h>
+
class tst_QWebEngineUrlRequestInterceptor : public QObject
{
Q_OBJECT
@@ -61,6 +64,7 @@ private Q_SLOTS:
void requestInterceptorByResourceType_data();
void requestInterceptorByResourceType();
void firstPartyUrlHttp();
+ void passRefererHeader();
};
tst_QWebEngineUrlRequestInterceptor::tst_QWebEngineUrlRequestInterceptor()
@@ -99,6 +103,9 @@ struct RequestInfo {
int resourceType;
};
+static const QByteArray kHttpHeaderReferrerValue = QByteArrayLiteral("http://somereferrer.com/");
+static const QByteArray kHttpHeaderRefererName = QByteArrayLiteral("referer");
+
class TestRequestInterceptor : public QWebEngineUrlRequestInterceptor
{
public:
@@ -115,6 +122,9 @@ public:
if (shouldIntercept && info.requestUrl().toString().endsWith(QLatin1String("__placeholder__")))
info.redirect(QUrl("qrc:///resources/content.html"));
+ // Set referrer header
+ info.setHttpHeader(kHttpHeaderRefererName, kHttpHeaderReferrerValue);
+
requestInfos.append(info);
}
@@ -510,5 +520,38 @@ void tst_QWebEngineUrlRequestInterceptor::firstPartyUrlHttp()
QCOMPARE(info.firstPartyUrl, firstPartyUrl);
}
+void tst_QWebEngineUrlRequestInterceptor::passRefererHeader()
+{
+ // Create HTTP Server to parse the request.
+ HttpServer httpServer;
+
+ if (!httpServer.start())
+ QSKIP("Failed to start http server");
+
+ bool succeeded = false;
+ connect(&httpServer, &HttpServer::newRequest, [&succeeded](HttpReqRep *rr) {
+ const QByteArray headerValue = rr->requestHeader(kHttpHeaderRefererName);
+ QCOMPARE(headerValue, kHttpHeaderReferrerValue);
+ succeeded = headerValue == kHttpHeaderReferrerValue;
+ rr->setResponseStatus(200);
+ rr->sendResponse();
+ });
+
+ QWebEngineProfile profile;
+ TestRequestInterceptor interceptor(true);
+ profile.setUrlRequestInterceptor(&interceptor);
+
+ QWebEnginePage page(&profile);
+ QSignalSpy spy(&page, SIGNAL(loadFinished(bool)));
+ QWebEngineHttpRequest httpRequest;
+ QUrl requestUrl = httpServer.url();
+ httpRequest.setUrl(requestUrl);
+ page.load(httpRequest);
+
+ QVERIFY(spy.wait());
+ (void) httpServer.stop();
+ QVERIFY(succeeded);
+}
+
QTEST_MAIN(tst_QWebEngineUrlRequestInterceptor)
#include "tst_qwebengineurlrequestinterceptor.moc"
diff --git a/tests/auto/widgets/qwebenginedownloaditem/tst_qwebenginedownloaditem.cpp b/tests/auto/widgets/qwebenginedownloaditem/tst_qwebenginedownloaditem.cpp
index 3a38c115d..bc474457a 100644
--- a/tests/auto/widgets/qwebenginedownloaditem/tst_qwebenginedownloaditem.cpp
+++ b/tests/auto/widgets/qwebenginedownloaditem/tst_qwebenginedownloaditem.cpp
@@ -77,6 +77,7 @@ private Q_SLOTS:
void downloadToDefaultLocation();
void downloadToNonExistentDir();
void downloadToReadOnlyDir();
+ void downloadPathValidation();
private:
void saveLink(QPoint linkPos);
@@ -1115,5 +1116,127 @@ void tst_QWebEngineDownloadItem::downloadToReadOnlyDir()
QFile(m_profile->downloadPath()).setPermissions(QFileDevice::WriteOwner);
}
+void tst_QWebEngineDownloadItem::downloadPathValidation()
+{
+ const QString fileName = "test.txt";
+ QString downloadPath;
+ QString originalDownloadPath;
+
+ QTemporaryDir tmpDir;
+ QVERIFY(tmpDir.isValid());
+
+ // Set up HTTP server
+ ScopedConnection sc1 = connect(m_server, &HttpServer::newRequest, [&](HttpReqRep *rr) {
+ if (rr->requestMethod() == "GET" && rr->requestPath() == ("/" + fileName)) {
+ rr->setResponseHeader(QByteArrayLiteral("content-type"), QByteArrayLiteral("application/octet-stream"));
+ rr->setResponseHeader(QByteArrayLiteral("content-disposition"), QByteArrayLiteral("attachment"));
+ rr->setResponseBody(QByteArrayLiteral("a"));
+ rr->sendResponse();
+ } else {
+ rr->setResponseStatus(404);
+ rr->sendResponse();
+ }
+ });
+
+ // Set up profile and download handler
+ QPointer<QWebEngineDownloadItem> downloadItem;
+ ScopedConnection sc2 = connect(m_profile, &QWebEngineProfile::downloadRequested, [&](QWebEngineDownloadItem *item) {
+ downloadItem = item;
+ originalDownloadPath = item->path();
+
+ item->setPath(downloadPath);
+ // TODO: Do not cancel download from 5.13. This is for not messing up system download path.
+ // Use m_profile->setDownloadPath(tmpDir.path()) at initialization.
+ if (item->path() != downloadPath)
+ item->cancel();
+ else
+ item->accept();
+
+ connect(item, &QWebEngineDownloadItem::stateChanged, [&, item](QWebEngineDownloadItem::DownloadState downloadState) {
+ if (downloadState == QWebEngineDownloadItem::DownloadInterrupted) {
+ item->cancel();
+ }
+ });
+
+ connect(item, &QWebEngineDownloadItem::finished, [&, item]() {
+ QCOMPARE(item->isFinished(), true);
+ QCOMPARE(item->totalBytes(), item->receivedBytes());
+ QVERIFY(item->receivedBytes() > 0);
+ QCOMPARE(item->page(), m_page);
+ });
+ });
+
+ QString oldPath = QDir::currentPath();
+ QDir::setCurrent(tmpDir.path());
+
+ // Set only the file name.
+ downloadItem.clear();
+ originalDownloadPath = "";
+ downloadPath = fileName;
+ m_page->setUrl(m_server->url("/" + fileName));
+ QTRY_VERIFY(downloadItem);
+ QTRY_COMPARE(downloadItem->state(), QWebEngineDownloadItem::DownloadCompleted);
+ QCOMPARE(downloadItem->interruptReason(), QWebEngineDownloadItem::NoReason);
+ QCOMPARE(downloadItem->path(), fileName);
+
+ // Set only the directory path.
+ downloadItem.clear();
+ originalDownloadPath = "";
+ downloadPath = tmpDir.path();
+ m_page->setUrl(m_server->url("/" + fileName));
+ QTRY_VERIFY(downloadItem);
+ QTRY_COMPARE(downloadItem->state(), QWebEngineDownloadItem::DownloadCancelled);
+ QCOMPARE(downloadItem->interruptReason(), QWebEngineDownloadItem::UserCanceled);
+ QCOMPARE(downloadItem->path(), originalDownloadPath);
+
+ // Set only the directory path with separator.
+ downloadItem.clear();
+ originalDownloadPath = "";
+ downloadPath = tmpDir.path() + QDir::separator();
+ m_page->setUrl(m_server->url("/" + fileName));
+ QTRY_VERIFY(downloadItem);
+ QTRY_COMPARE(downloadItem->state(), QWebEngineDownloadItem::DownloadCancelled);
+ QCOMPARE(downloadItem->interruptReason(), QWebEngineDownloadItem::UserCanceled);
+ QCOMPARE(downloadItem->path(), originalDownloadPath);
+
+ // Set only the directory with the current directory path without ending separator.
+ downloadItem.clear();
+ originalDownloadPath = "";
+ downloadPath = ".";
+ m_page->setUrl(m_server->url("/" + fileName));
+ QTRY_VERIFY(downloadItem);
+ QTRY_COMPARE(downloadItem->state(), QWebEngineDownloadItem::DownloadCancelled);
+ QCOMPARE(downloadItem->interruptReason(), QWebEngineDownloadItem::UserCanceled);
+ QCOMPARE(downloadItem->path(), originalDownloadPath);
+
+ // Set only the directory with the current directory path with ending separator.
+ downloadItem.clear();
+ originalDownloadPath = "";
+ downloadPath = "./";
+ m_page->setUrl(m_server->url("/" + fileName));
+ QTRY_VERIFY(downloadItem);
+ QTRY_COMPARE(downloadItem->state(), QWebEngineDownloadItem::DownloadCancelled);
+ QCOMPARE(downloadItem->interruptReason(), QWebEngineDownloadItem::UserCanceled);
+ QCOMPARE(downloadItem->path(), originalDownloadPath);
+
+
+
+ downloadItem.clear();
+ originalDownloadPath = "";
+ downloadPath = "...";
+ m_page->setUrl(m_server->url("/" + fileName));
+ QTRY_VERIFY(downloadItem);
+ QTRY_COMPARE(downloadItem->state(), QWebEngineDownloadItem::DownloadCancelled);
+#if !defined(Q_OS_WIN)
+ QCOMPARE(downloadItem->interruptReason(), QWebEngineDownloadItem::FileFailed);
+ QCOMPARE(downloadItem->path(), downloadPath);
+#else
+ // Windows interprets the "..." path as a valid path. It will be the current path.
+ QCOMPARE(downloadItem->interruptReason(), QWebEngineDownloadItem::UserCanceled);
+ QCOMPARE(downloadItem->path(), originalDownloadPath);
+#endif // !defined(Q_OS_WIN)
+ QDir::setCurrent(oldPath);
+}
+
QTEST_MAIN(tst_QWebEngineDownloadItem)
#include "tst_qwebenginedownloaditem.moc"
diff --git a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp
index 19f9b6df1..dd1140a4f 100644
--- a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp
+++ b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp
@@ -1656,6 +1656,18 @@ void tst_QWebEnginePage::runJavaScript()
JavaScriptCallbackUndefined callbackUndefined;
page.runJavaScript("undefined", QWebEngineCallback<const QVariant&>(callbackUndefined));
+ JavaScriptCallback callbackDate(QVariant(42.0));
+ page.runJavaScript("new Date(42000)", QWebEngineCallback<const QVariant&>(callbackDate));
+
+ JavaScriptCallback callbackBlob(QVariant(QByteArray(8, 0)));
+ page.runJavaScript("new ArrayBuffer(8)", QWebEngineCallback<const QVariant&>(callbackBlob));
+
+ JavaScriptCallbackUndefined callbackFunction;
+ page.runJavaScript("(function(){})", QWebEngineCallback<const QVariant&>(callbackFunction));
+
+ JavaScriptCallback callbackPromise(QVariant(QVariantMap{}));
+ page.runJavaScript("new Promise(function(){})", QWebEngineCallback<const QVariant&>(callbackPromise));
+
QVERIFY(watcher.wait());
}