summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--configure.pri8
-rw-r--r--dist/changes-5.13.089
-rw-r--r--mkspecs/features/functions.prf9
m---------src/3rdparty0
-rw-r--r--src/core/config/functions.pri8
-rw-r--r--src/core/config/linux.pri6
-rw-r--r--src/core/config/windows.pri8
-rw-r--r--src/core/core_module.pro2
-rw-r--r--src/core/net/network_delegate_qt.cpp10
-rw-r--r--src/core/net/url_request_notification.cpp13
-rw-r--r--src/core/web_engine_context.cpp32
-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
19 files changed, 393 insertions, 57 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/dist/changes-5.13.0 b/dist/changes-5.13.0
new file mode 100644
index 000000000..6370cc9ed
--- /dev/null
+++ b/dist/changes-5.13.0
@@ -0,0 +1,89 @@
+Qt 5.13 introduces many new features and improvements as well as bugfixes
+over the 5.12.x series. For more details, refer to the online documentation
+included in this distribution. The documentation is also available online:
+
+https://doc.qt.io/qt-5/index.html
+
+The Qt version 5.13 series is binary compatible with the 5.12.x series.
+Applications compiled for 5.12 will continue to run with 5.13.
+
+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.
+
+****************************************************************************
+* General *
+****************************************************************************
+
+Behavioral Changes
+------------------
+
+ - [QTBUG-74586] Qt WebEngine will assume that the resources and the icu
+ data files are in the same directory when deploying the application.
+
+
+Chromium Snapshot
+-----------------
+
+ - Updated the Chromium version to 73.0.3683.105
+ - Applied security fixes from Chrome up to version 74.0.3729.108
+
+
+Platforms
+---------
+
+ - [QTBUG-71126] A single-threaded GPU mode has been implemented, enabling
+ WebGL and hardware acceleration with OpenGL drivers with buggy
+ multithreading, such as ANGLE on Windows and Nouveau on Linux.
+ - Windows: Qt WebEngine can now be build with both MSVC 2017 and clang_cl.
+
+
+****************************************************************************
+* Libraries *
+****************************************************************************
+
+Qt WebEngineCore
+----------------
+
+ - [QTBUG-50556] The PDF Viewer extension has been implemented and enabled,
+ so that PDFs can now be viewed directly in Qt WebEngine.
+ - [QTBUG-50995] Support for Web Notifications API for end-user
+ notifications through QWebEngineNotification.
+ - [QTBUG-58232] Will now use credentials from QNetworkProxy if set.
+ - [QTBUG-69844] Added QWebEngineUrlRequestJob::requestHeaders() to read
+ extra HTTP headers set on a URL request.
+ - [QTBUG-71229] Will now parse Chrome command-line switches for initial
+ proxy settings.
+ - [QTBUG-75539] Will now parse --auth-server-whitelist switch.
+ - Added in-memory client cert store for installing application specific
+ client certificates.
+
+
+Qt WebEngine (QML)
+------------------
+
+ - [QTBUG-66262][QTBUG-72176] Added property to set the default download
+ location in QQuickWebEngineProfile.
+ - Added WebEngineSettings.pdfViewerEnabled to control if the internal PDF
+ viewer is enabled.
+
+
+Qt WebEngineWidgets
+-------------------
+
+ - [QTBUG-66262][QTBUG-72176] Added methods to set the default download
+ location in QWebEngineProfile.
+ - [QTBUG-58059][QTBUG-71164] A profile can now be designated to download
+ OCSP records and thus enable OCSP verification on Linux.
+ - Added QWebEngineProfile::setUrlRequestInterceptor, similar to
+ setRequestInterceptor except it operates on the UI-thread. The old
+ QWebEngineProfile::setRequestInterceptor is deprecated for not being
+ thread-safe.
+ - Added QWebEnginePage::setUrlRequestInterceptor, similar to the same call on
+ profile except it operates on a per-page basis.
+ - Added QWebEngineSettings::PdfViewerEnabled to control if the internal PDF
+ viewer is enabled.
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/3rdparty b/src/3rdparty
-Subproject 82d848eb4fe3aae8c72a91b2d30c91b407ac559
+Subproject 7e110d51ae0f456e2bb8e273f52107d22196e47
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/config/windows.pri b/src/core/config/windows.pri
index 429e4e45f..385faeed0 100644
--- a/src/core/config/windows.pri
+++ b/src/core/config/windows.pri
@@ -8,9 +8,6 @@ gn_args += \
win_linker_timing=true \
com_init_check_hook_disabled=true
-use_lld_linker: gn_args += use_lld=true
-else: gn_args += use_lld=false
-
clang_cl {
clang_full_path = $$system_path($$which($${QMAKE_CXX}))
# Remove the "\bin\clang-cl.exe" part:
@@ -18,10 +15,11 @@ clang_cl {
clang_prefix = $$join(clang_dir,,,"\..")
gn_args += \
is_clang=true \
+ use_ldd=true \
clang_use_chrome_plugins=false \
- clang_base_path=$$system_quote($$system_path($$clean_path($$clang_prefix)))
+ clang_base_path=\"$$system_path($$clean_path($$clang_prefix))\"
} else {
- gn_args += is_clang=false
+ gn_args += is_clang=false use_lld=false
}
isDeveloperBuild() {
diff --git a/src/core/core_module.pro b/src/core/core_module.pro
index e2fa3494d..f9f72176f 100644
--- a/src/core/core_module.pro
+++ b/src/core/core_module.pro
@@ -60,7 +60,7 @@ osx {
# Remove unused functions and data in debug non-developer builds, because the binaries will
# be smaller in the shipped packages.
QMAKE_LFLAGS += /OPT:REF
- } else:CONFIG(debug, debug|release) {
+ } else:CONFIG(debug, debug|release):!clang_cl {
# Make sure to override qtbase's QMAKE_LFLAGS_DEBUG option in debug developer builds,
# because qmake chooses and overrides the option when it gets appended to QMAKE_LFLAGS in
# qtbase\mkspecs\features\default_post.prf, regardless of what Chromium passes back from GN.
diff --git a/src/core/net/network_delegate_qt.cpp b/src/core/net/network_delegate_qt.cpp
index e0e3a6c16..f283df1d1 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/core/web_engine_context.cpp b/src/core/web_engine_context.cpp
index 33cc723f5..a3a5881bf 100644
--- a/src/core/web_engine_context.cpp
+++ b/src/core/web_engine_context.cpp
@@ -363,7 +363,15 @@ ProxyAuthentication WebEngineContext::qProxyNetworkAuthentication(QString host,
const static char kChromiumFlagsEnv[] = "QTWEBENGINE_CHROMIUM_FLAGS";
const static char kDisableSandboxEnv[] = "QTWEBENGINE_DISABLE_SANDBOX";
-static void appendToFeatureSwitch(base::CommandLine *commandLine, const char *featureSwitch, const char *feature)
+static void appendToFeatureList(std::string &featureList, const char *feature)
+{
+ if (featureList.empty())
+ featureList = feature;
+ else
+ featureList = featureList + "," + feature;
+}
+
+static void appendToFeatureSwitch(base::CommandLine *commandLine, const char *featureSwitch, std::string feature)
{
if (!commandLine->HasSwitch(featureSwitch)) {
commandLine->AppendSwitchASCII(featureSwitch, feature);
@@ -475,35 +483,41 @@ WebEngineContext::WebEngineContext()
if (isDesktopGLOrSoftware || isGLES2Context)
parsedCommandLine->AppendSwitch(switches::kDisableES3GLContext);
#endif
+
+ std::string disableFeatures;
+ std::string enableFeatures;
// Needed to allow navigations within pages that were set using setHtml(). One example is
// tst_QWebEnginePage::acceptNavigationRequest.
// This is deprecated behavior, and will be removed in a future Chromium version, as per
// upstream Chromium commit ba52f56207a4b9d70b34880fbff2352e71a06422.
- appendToFeatureSwitch(parsedCommandLine, switches::kEnableFeatures, features::kAllowContentInitiatedDataUrlNavigations.name);
+ appendToFeatureList(enableFeatures, features::kAllowContentInitiatedDataUrlNavigations.name);
// Surface synchronization breaks our current graphics integration (since 65)
- appendToFeatureSwitch(parsedCommandLine, switches::kDisableFeatures, features::kEnableSurfaceSynchronization.name);
+ appendToFeatureList(disableFeatures, features::kEnableSurfaceSynchronization.name);
// Viz Display Compositor is enabled by default since 73. Doesn't work for us (also implies SurfaceSynchronization)
- appendToFeatureSwitch(parsedCommandLine, switches::kDisableFeatures, features::kVizDisplayCompositor.name);
+ appendToFeatureList(disableFeatures, features::kVizDisplayCompositor.name);
// The video-capture service is not functioning at this moment (since 69)
- appendToFeatureSwitch(parsedCommandLine, switches::kDisableFeatures, features::kMojoVideoCapture.name);
+ appendToFeatureList(disableFeatures, features::kMojoVideoCapture.name);
// Breaks WebEngineNewViewRequest.userInitiated API (since 73)
- appendToFeatureSwitch(parsedCommandLine, switches::kDisableFeatures, features::kUserActivationV2.name);
+ appendToFeatureList(disableFeatures, features::kUserActivationV2.name);
- appendToFeatureSwitch(parsedCommandLine, switches::kDisableFeatures, features::kBackgroundFetch.name);
+ appendToFeatureList(disableFeatures, features::kBackgroundFetch.name);
#if QT_CONFIG(webengine_printing_and_pdf)
- appendToFeatureSwitch(parsedCommandLine, switches::kDisableFeatures, printing::features::kUsePdfCompositorServiceForPrint.name);
+ appendToFeatureList(disableFeatures, printing::features::kUsePdfCompositorServiceForPrint.name);
#endif
if (useEmbeddedSwitches) {
// embedded switches are based on the switches for Android, see content/browser/android/content_startup_flags.cc
- appendToFeatureSwitch(parsedCommandLine, switches::kEnableFeatures, features::kOverlayScrollbar.name);
+ appendToFeatureList(enableFeatures, features::kOverlayScrollbar.name);
if (!parsedCommandLine->HasSwitch(switches::kDisablePinch))
parsedCommandLine->AppendSwitch(switches::kEnablePinch);
parsedCommandLine->AppendSwitch(switches::kEnableViewport);
parsedCommandLine->AppendSwitch(switches::kMainFrameResizesAreOrientationChanges);
parsedCommandLine->AppendSwitch(cc::switches::kDisableCompositedAntialiasing);
}
+
+ appendToFeatureSwitch(parsedCommandLine, switches::kDisableFeatures, disableFeatures);
+ appendToFeatureSwitch(parsedCommandLine, switches::kEnableFeatures, enableFeatures);
base::FeatureList::InitializeInstance(
parsedCommandLine->GetSwitchValueASCII(switches::kEnableFeatures),
parsedCommandLine->GetSwitchValueASCII(switches::kDisableFeatures));
diff --git a/src/webengine/api/qquickwebenginedownloaditem.cpp b/src/webengine/api/qquickwebenginedownloaditem.cpp
index d5f6a3ef1..2b3e50a72 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
@@ -442,6 +444,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 9095fac65..4215f493f 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 ec088762e..6df131066 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 354019a8d..e33f9f37f 100644
--- a/src/webenginewidgets/doc/src/qwebenginepage_lgpl.qdoc
+++ b/src/webenginewidgets/doc/src/qwebenginepage_lgpl.qdoc
@@ -773,6 +773,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 ab576135f..02b46bc6b 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);
@@ -1128,5 +1129,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 985d3edf7..8718892ac 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());
}