diff --git a/config.tests/hostcompiler/hostcompiler.pro b/config.tests/hostcompiler/hostcompiler.pro new file mode 100644 index 0000000000000000000000000000000000000000..5a80246ab0175e72050b00c3fe25f10ec52d7cd4 --- /dev/null +++ b/config.tests/hostcompiler/hostcompiler.pro @@ -0,0 +1,9 @@ +option(host_build) + +gcc:equals(QT_ARCH, "x86_64"):contains(QT_TARGET_ARCH, "arm"):!contains(QT_TARGET_ARCH, "arm64") { + QMAKE_CXXFLAGS += -m32 + QMAKE_LFLAGS += -m32 +} + +SOURCES = main.cpp + diff --git a/config.tests/hostcompiler/main.cpp b/config.tests/hostcompiler/main.cpp new file mode 100644 index 0000000000000000000000000000000000000000..96444ae8bdd0dc9ecf8cdb41b36fe2caf799867a --- /dev/null +++ b/config.tests/hostcompiler/main.cpp @@ -0,0 +1,6 @@ +#include <stdio.h> +int main() +{ + printf("This works\n"); + return 0; +} diff --git a/configure.json b/configure.json index 7ef1f5003ec6d1085087b8675ba3a1596b5314bc..c44da9854f29e5bfa62f155a2cb193d349e9a12a 100644 --- a/configure.json +++ b/configure.json @@ -21,8 +21,8 @@ "webengine-spellchecker": "boolean", "webengine-native-spellchecker": "boolean", "webengine-webrtc": "boolean", - "webengine-geolocation" : "boolean", - + "webengine-geolocation": "boolean", + "webengine-v8-snapshot": "boolean", "alsa": { "type": "boolean", "name": "webengine-alsa" }, "pulseaudio": { "type": "boolean", "name": "webengine-pulseaudio" }, "ffmpeg": { "type": "enum", "name": "webengine-system-ffmpeg", "values": { "system": "yes", "qt": "no" } }, @@ -189,6 +189,11 @@ "test": "alsa", "type": "compile" }, + "webengine-host-compiler": { + "label": "host compiler", + "test": "hostcompiler", + "type": "compile" + }, "webengine-khr": { "label": "khr", "test": "khr", @@ -223,6 +228,11 @@ "type": "detectPython2", "log": "location" }, + "webengine-host-pkg-config": { + "label": "host pkg-config", + "type": "detectHostPkgConfig", + "log": "path" + }, "webengine-gperf": { "label": "gperf", "type": "detectGperf" @@ -355,6 +365,14 @@ { "type": "varAssign", "name": "QMAKE_PYTHON2", "value": "tests.webengine-python2.location" } ] }, + "webengine-host-pkg-config": { + "label": "host-pkg-config", + "condition": "config.unix && tests.webengine-host-pkg-config", + "output": [ + "privateFeature", + { "type": "varAssign", "name": "QMAKE_PKG_CONFIG_HOST", "value": "tests.webengine-host-pkg-config.path" } + ] + }, "webengine-gperf": { "label": "gperf", "condition": "tests.webengine-gperf", @@ -383,6 +401,16 @@ "condition": "config.unix && tests.alsa", "output": [ "privateFeature" ] }, + "webengine-v8-snapshot": { + "label" : "Use v8 snapshot", + "purpuse": "Enables the v8 snapshot, for fast v8 context creation", + "output": [ "privateFeature" ] + }, + "webengine-v8-snapshot-support": { + "autoDetect": "features.webengine-v8-snapshot", + "condition": "!config.unix || !features.webengine-embedded-build || tests.webengine-host-compiler", + "output": [ "privateFeature" ] + }, "webengine-system-khr" : { "label": "khr", "condition": "config.unix && tests.webengine-khr", @@ -566,6 +594,11 @@ "type": "warning", "condition": "config.sanitizer && !tests.webengine-sanitizer && !features.webengine-sanitizer", "message": "Qt WebEngine cannot be built with the chosen sanitizer configuration. Check config.log for details or use -feature-webengine-sanitizer to force the build." + }, + { + "type": "warning", + "condition": "config.unix && !features.webengine-host-pkg-config", + "message": "host pkg-config not found" } ], @@ -582,6 +615,7 @@ "webengine-webrtc", "webengine-system-ninja", "webengine-geolocation", + "webengine-v8-snapshot", { "type": "feature", "args": "webengine-alsa", diff --git a/configure.pri b/configure.pri index 497557262ee86f6d587c6bef192b3852a6c010c8..ecf2ce4d36856c90ea81eb0354fe3fffa8a42c18 100644 --- a/configure.pri +++ b/configure.pri @@ -157,6 +157,20 @@ defineTest(qtConfTest_detectIcuuc) { return(false) } +defineTest(qtConfTest_detectHostPkgConfig) { + PKG_CONFIG = $$qtConfPkgConfig(true) + isEmpty(PKG_CONFIG) { + qtLog("Could not find host pkg-config") + return(false) + } + qtLog("Found host pkg-config: $$PKG_CONFIG") + $${1}.path = $$PKG_CONFIG + export($${1}.path) + $${1}.cache += path + export($${1}.cache) + return(true) +} + defineTest(qtConfTest_isSanitizerSupported) { sanitizer_combo_supported = true diff --git a/examples/webenginewidgets/stylesheetbrowser/doc/src/stylesheetbrowser.qdoc b/examples/webenginewidgets/stylesheetbrowser/doc/src/stylesheetbrowser.qdoc index c5506a6234a70045bf05ac9cd38e322d5f0f99e3..f1fdf85d159f8bb9d184f8c6e50f2d6bfbe8c6ce 100644 --- a/examples/webenginewidgets/stylesheetbrowser/doc/src/stylesheetbrowser.qdoc +++ b/examples/webenginewidgets/stylesheetbrowser/doc/src/stylesheetbrowser.qdoc @@ -11,8 +11,8 @@ ** accordance with the commercial license agreement provided with the ** Software or, alternatively, in accordance with the terms contained in ** a written agreement between you and The Qt Company. For licensing terms -** and conditions see http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. ** ** GNU Free Documentation License Usage ** Alternatively, this file may be used under the terms of the GNU Free @@ -20,7 +20,7 @@ ** Foundation and appearing in the file included in the packaging of ** this file. Please review the following information to ensure ** the GNU Free Documentation License version 1.3 requirements -** will be met: http://www.gnu.org/copyleft/fdl.html. +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. ** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/mkspecs/features/configure.prf b/mkspecs/features/configure.prf index 8b8fd3efe931d37ea2bffcc9e0f58a9e5783a838..f8c15465571fcde0c2d193e2bccd37331af1b2c9 100644 --- a/mkspecs/features/configure.prf +++ b/mkspecs/features/configure.prf @@ -30,6 +30,13 @@ defineTest(runConfigure) { include($$QTWEBENGINE_OUT_ROOT/qtwebengine-config.pri) QT_FOR_CONFIG += webengine-private + !qtConfig(webengine-v8-snapshot-support):qtConfig(webengine-v8-snapshot) { + skipBuild("V8 snapshot cannot be built. Most likely, the 32-bit host compiler does not work."\ + "Please make sure you have 32-bit devel environment installed, or "\ + "configure webengine with '-no-webengine-v8-snapshot'") + return(false) + } + !qtConfig(webengine-gperf) { skipBuild("Required gperf could not be found.") return(false) @@ -53,6 +60,12 @@ defineTest(runConfigure) { } linux { + + !qtConfig(webengine-host-pkg-config) { + skipBuild("Host pkg-config is required") + return(false) + } + !qtConfig(webengine-system-glibc) { skipBuild("A suitable version of libc could not be found. See: https://sourceware.org/bugzilla/show_bug.cgi?id=14898") return(false) diff --git a/mkspecs/features/functions.prf b/mkspecs/features/functions.prf index 3b9a400b1204f96dfa40305096dc66f0a6e79f9a..8564bad8adaf7798daa4959e5d8da0fff26f24c1 100644 --- a/mkspecs/features/functions.prf +++ b/mkspecs/features/functions.prf @@ -115,3 +115,18 @@ defineTest(skipBuild) { skipBuildReason = "$$skipBuildReason $${EOL}$$1" export(skipBuildReason) } + +defineReplace(pkgConfigHostExecutable) { + wrapper_name = $$OUT_PWD/pkg-config-host_wrapper.sh + wrapper_cmd = $$QMAKE_PKG_CONFIG_HOST + isEmpty(wrapper_cmd): wrapper_cmd = pkg-config + wrapper_content = \ + "$$LITERAL_HASH!/bin/sh" \ + "unset PKG_CONFIG_LIBDIR" \ + "unset PKG_CONFIG_SYSROOT_DIR" \ + "exec $$wrapper_cmd \"$@\"" + !build_pass:!write_file($$wrapper_name, wrapper_content, exe): error() + QMAKE_DISTCLEAN += $$wrapper_name + export(QMAKE_DISTCLEAN) + return($$system_quote($$system_path($$wrapper_name))) +} diff --git a/src/core/config/common.pri b/src/core/config/common.pri index 60aba490c4ed8366a24bd122e49b9bfe252f51b4..ab2a609782d3815425501a0b29d0c5e4649566c1 100644 --- a/src/core/config/common.pri +++ b/src/core/config/common.pri @@ -47,7 +47,11 @@ qtConfig(webengine-webrtc) { qtConfig(webengine-proprietary-codecs): gn_args += proprietary_codecs=true ffmpeg_branding=\"Chrome\" -!precompile_header: gn_args += disable_precompiled_headers=true +precompile_header { + gn_args += enable_precompiled_headers=true +} else { + gn_args += enable_precompiled_headers=false +} CONFIG(release, debug|release) { force_debug_info { @@ -80,3 +84,10 @@ optimize_size: gn_args += optimize_for_size=true # rtti, linking would fail at build time. sanitize_undefined: gn_args += is_ubsan=true use_rtti=true } + +qtConfig(webengine-v8-snapshot) { + gn_args += v8_use_snapshot=true +} else { + gn_args += v8_use_snapshot=false +} + diff --git a/src/core/config/linux.pri b/src/core/config/linux.pri index cdb723b7962f7bad62a834f9587f366d29714760..f4a95a03c7c63dbaadacad4e3c29f8c9a0cdf3f1 100644 --- a/src/core/config/linux.pri +++ b/src/core/config/linux.pri @@ -110,7 +110,14 @@ host_build { PKGCONFIG = $$first($$list($$pkgConfigExecutable())) gn_args += pkg_config=\"$$PKGCONFIG\" PKG_CONFIG_HOST = $$(GN_PKG_CONFIG_HOST) - isEmpty(PKG_CONFIG_HOST): PKG_CONFIG_HOST = pkg-config + pkgConfigLibDir = $$(PKG_CONFIG_LIBDIR) + pkgConfigSysrootDir = $$(PKG_CONFIG_SYSROOT_DIR) + isEmpty(PKG_CONFIG_HOST): PKG_CONFIG_HOST = $$QMAKE_PKG_CONFIG_HOST + cross_compile { + !isEmpty(pkgConfigLibDir)|!isEmpty(pkgConfigSysrootDir) { + PKG_CONFIG_HOST = $$pkgConfigHostExecutable() + } + } gn_args += host_pkg_config=\"$$PKG_CONFIG_HOST\" } diff --git a/src/core/gl_surface_qt.cpp b/src/core/gl_surface_qt.cpp index e9491eabab704b3f20eb019a22702001625f1ed2..941fbd211347f222ae0ff0825b68931116c139c6 100644 --- a/src/core/gl_surface_qt.cpp +++ b/src/core/gl_surface_qt.cpp @@ -290,7 +290,7 @@ bool GLSurfaceQtGLX::Initialize(GLSurfaceFormat format) GLX_PBUFFER_HEIGHT, m_size.height(), GLX_LARGEST_PBUFFER, False, GLX_PRESERVED_CONTENTS, False, - GLX_NONE + 0 }; m_surfaceBuffer = glXCreatePbuffer(display, static_cast<GLXFBConfig>(g_config), pbuffer_attributes); diff --git a/src/core/print_view_manager_qt.cpp b/src/core/print_view_manager_qt.cpp index 5198985d7ae5148d9af48da1bbfccd03b443f650..fef2cf51afc78d0834d65e808cabc2b2f272cdea 100644 --- a/src/core/print_view_manager_qt.cpp +++ b/src/core/print_view_manager_qt.cpp @@ -154,27 +154,37 @@ static base::DictionaryValue *createPrintSettings() return printSettings; } -static base::DictionaryValue *createPrintSettingsFromQPageLayout(const QPageLayout &pageLayout) +static base::DictionaryValue *createPrintSettingsFromQPageLayout(const QPageLayout &pageLayout, bool printToPdf) { base::DictionaryValue *printSettings = createPrintSettings(); //Set page size attributes, chromium expects these in micrometers - QSizeF pageSizeInMilimeter = pageLayout.pageSize().size(QPageSize::Millimeter); + QRectF pageSizeInMillimeter = pageLayout.pageSize().rect(QPageSize::Millimeter); + if (!printToPdf) { + // QPrinter will extend this size with its margins + QMarginsF margins = pageLayout.margins(QPageLayout::Millimeter); + pageSizeInMillimeter = pageSizeInMillimeter.marginsRemoved(margins); + } std::unique_ptr<base::DictionaryValue> sizeDict(new base::DictionaryValue); - sizeDict->SetInteger(printing::kSettingMediaSizeWidthMicrons, pageSizeInMilimeter.width() * kMicronsToMillimeter); - sizeDict->SetInteger(printing::kSettingMediaSizeHeightMicrons, pageSizeInMilimeter.height() * kMicronsToMillimeter); + sizeDict->SetInteger(printing::kSettingMediaSizeWidthMicrons, pageSizeInMillimeter.width() * kMicronsToMillimeter); + sizeDict->SetInteger(printing::kSettingMediaSizeHeightMicrons, pageSizeInMillimeter.height() * kMicronsToMillimeter); printSettings->Set(printing::kSettingMediaSize, std::move(sizeDict)); - // Apply page margins - QMargins pageMarginsInPoints = pageLayout.marginsPoints(); - std::unique_ptr<base::DictionaryValue> marginsDict(new base::DictionaryValue); - marginsDict->SetInteger(printing::kSettingMarginTop, pageMarginsInPoints.top()); - marginsDict->SetInteger(printing::kSettingMarginBottom, pageMarginsInPoints.bottom()); - marginsDict->SetInteger(printing::kSettingMarginLeft, pageMarginsInPoints.left()); - marginsDict->SetInteger(printing::kSettingMarginRight, pageMarginsInPoints.right()); - - printSettings->Set(printing::kSettingMarginsCustom, std::move(marginsDict)); - printSettings->SetInteger(printing::kSettingMarginsType, printing::CUSTOM_MARGINS); + if (printToPdf) { + // Apply page margins when printing to PDF + QMargins pageMarginsInPoints = pageLayout.marginsPoints(); + std::unique_ptr<base::DictionaryValue> marginsDict(new base::DictionaryValue); + marginsDict->SetInteger(printing::kSettingMarginTop, pageMarginsInPoints.top()); + marginsDict->SetInteger(printing::kSettingMarginBottom, pageMarginsInPoints.bottom()); + marginsDict->SetInteger(printing::kSettingMarginLeft, pageMarginsInPoints.left()); + marginsDict->SetInteger(printing::kSettingMarginRight, pageMarginsInPoints.right()); + + printSettings->Set(printing::kSettingMarginsCustom, std::move(marginsDict)); + printSettings->SetInteger(printing::kSettingMarginsType, printing::CUSTOM_MARGINS); + } else { + // QPrinter will handle margins + printSettings->SetInteger(printing::kSettingMarginsType, printing::NO_MARGINS); + } printSettings->SetBoolean(printing::kSettingLandscape, pageLayout.orientation() == QPageLayout::Landscape); @@ -244,7 +254,7 @@ bool PrintViewManagerQt::PrintToPDFInternal(const QPageLayout &pageLayout, bool if (!pageLayout.isValid()) return false; - m_printSettings.reset(createPrintSettingsFromQPageLayout(pageLayout)); + m_printSettings.reset(createPrintSettingsFromQPageLayout(pageLayout, !m_pdfOutputPath.empty())); m_printSettings->SetBoolean(printing::kSettingShouldPrintBackgrounds , web_contents()->GetRenderViewHost()->GetWebkitPreferences().should_print_backgrounds); m_printSettings->SetInteger(printing::kSettingColor, diff --git a/src/core/render_widget_host_view_qt.cpp b/src/core/render_widget_host_view_qt.cpp index 8986a34953905b09b1e77d0fe42d2494b4193b2f..4f6d6d0eaa62f61e807bb05de02c3f61ad1b00d0 100644 --- a/src/core/render_widget_host_view_qt.cpp +++ b/src/core/render_widget_host_view_qt.cpp @@ -1595,7 +1595,8 @@ void RenderWidgetHostViewQt::handlePointerEvent(T *event) if (webEvent.GetType() == blink::WebInputEvent::kMouseDown) { if (event->button() != m_clickHelper.lastPressButton || (event->timestamp() - m_clickHelper.lastPressTimestamp > static_cast<ulong>(qGuiApp->styleHints()->mouseDoubleClickInterval())) - || (event->pos() - m_clickHelper.lastPressPosition).manhattanLength() > qGuiApp->styleHints()->startDragDistance()) + || (event->pos() - m_clickHelper.lastPressPosition).manhattanLength() > qGuiApp->styleHints()->startDragDistance() + || m_clickHelper.clickCounter >= 3) m_clickHelper.clickCounter = 0; m_clickHelper.lastPressTimestamp = event->timestamp(); diff --git a/src/core/web_contents_adapter.cpp b/src/core/web_contents_adapter.cpp index f87cc115b651b8d7d33a1cf189af2a177eca9342..5b7e437bf16ac1723211c2708fe6a1d6d7569634 100644 --- a/src/core/web_contents_adapter.cpp +++ b/src/core/web_contents_adapter.cpp @@ -367,8 +367,6 @@ WebContentsAdapterPrivate::WebContentsAdapterPrivate() WebContentsAdapterPrivate::~WebContentsAdapterPrivate() { - // Destroy the WebContents first - webContents.reset(); } QSharedPointer<WebContentsAdapter> WebContentsAdapter::createFromSerializedNavigationHistory(QDataStream &input, WebContentsAdapterClient *adapterClient) diff --git a/src/core/web_contents_delegate_qt.cpp b/src/core/web_contents_delegate_qt.cpp index 5364afa94f2b7d8bbbdb8f7269cfe807d8cfc6cb..09cca943ef3fdb9f2d1d583daeddf58a136ca990 100644 --- a/src/core/web_contents_delegate_qt.cpp +++ b/src/core/web_contents_delegate_qt.cpp @@ -110,6 +110,13 @@ WebContentsDelegateQt::WebContentsDelegateQt(content::WebContents *webContents, Observe(webContents); } +WebContentsDelegateQt::~WebContentsDelegateQt() +{ + // The destruction of this object should take place before + // WebContents destruction since WebContentsAdapterClient + // might be already deleted. +} + content::WebContents *WebContentsDelegateQt::OpenURLFromTab(content::WebContents *source, const content::OpenURLParams ¶ms) { content::WebContents *target = source; diff --git a/src/core/web_contents_delegate_qt.h b/src/core/web_contents_delegate_qt.h index 7e21e4b55d8d3edb8de0176517a1150f586a8b0f..8a3331163c87fe28b0bf88c5fb53bd2215e6b6be 100644 --- a/src/core/web_contents_delegate_qt.h +++ b/src/core/web_contents_delegate_qt.h @@ -93,7 +93,7 @@ class WebContentsDelegateQt : public content::WebContentsDelegate { public: WebContentsDelegateQt(content::WebContents*, WebContentsAdapterClient *adapterClient); - ~WebContentsDelegateQt() { Q_ASSERT(m_loadingErrorFrameList.isEmpty()); } + ~WebContentsDelegateQt(); QString lastSearchedString() const { return m_lastSearchedString; } void setLastSearchedString(const QString &s) { m_lastSearchedString = s; } int lastReceivedFindReply() const { return m_lastReceivedFindReply; } diff --git a/src/webengine/api/qquickwebenginetestsupport.cpp b/src/webengine/api/qquickwebenginetestsupport.cpp index b3290d3cc2d05063c873181d8c8daf8eeacb438b..b7b86312595bcc07256ca98ad7d119868e30da51 100644 --- a/src/webengine/api/qquickwebenginetestsupport.cpp +++ b/src/webengine/api/qquickwebenginetestsupport.cpp @@ -42,6 +42,7 @@ #include "qquickwebengineloadrequest_p.h" #include <QQuickWindow> #include <QtTest/qtest.h> +#include <QtCore/QTimer> QT_BEGIN_NAMESPACE @@ -56,19 +57,20 @@ QQuickWebEngineErrorPage::QQuickWebEngineErrorPage() void QQuickWebEngineErrorPage::loadFinished(bool success, const QUrl &url) { Q_UNUSED(success); - - QQuickWebEngineLoadRequest loadRequest(url, QQuickWebEngineView::LoadSucceededStatus); - Q_EMIT loadingChanged(&loadRequest); - return; + QTimer::singleShot(0, this, [this, url]() { + QQuickWebEngineLoadRequest loadRequest(url, QQuickWebEngineView::LoadSucceededStatus); + emit loadingChanged(&loadRequest); + }); } void QQuickWebEngineErrorPage::loadStarted(const QUrl &provisionalUrl) { - QQuickWebEngineLoadRequest loadRequest(provisionalUrl, QQuickWebEngineView::LoadStartedStatus); - Q_EMIT loadingChanged(&loadRequest); + QTimer::singleShot(0, this, [this, provisionalUrl]() { + QQuickWebEngineLoadRequest loadRequest(provisionalUrl, QQuickWebEngineView::LoadStartedStatus); + emit loadingChanged(&loadRequest); + }); } - QQuickWebEngineTestInputContext::QQuickWebEngineTestInputContext() : m_visible(false) { diff --git a/src/webengine/api/qquickwebengineview.cpp b/src/webengine/api/qquickwebengineview.cpp index 1a979df00a8b44381736ed312773f82d9aa6f67a..617b999da4023e2e71d7f306920ab06887cd5e20 100644 --- a/src/webengine/api/qquickwebengineview.cpp +++ b/src/webengine/api/qquickwebengineview.cpp @@ -331,14 +331,14 @@ void QQuickWebEngineViewPrivate::iconChanged(const QUrl &url) iconUrl = faviconProvider->attach(q, url); m_history->reset(); - Q_EMIT q->iconChanged(); + QTimer::singleShot(0, q, &QQuickWebEngineView::iconChanged); } void QQuickWebEngineViewPrivate::loadProgressChanged(int progress) { Q_Q(QQuickWebEngineView); loadProgress = progress; - Q_EMIT q->loadProgressChanged(); + QTimer::singleShot(0, q, &QQuickWebEngineView::loadProgressChanged); } void QQuickWebEngineViewPrivate::didUpdateTargetURL(const QUrl &hoveredUrl) @@ -384,12 +384,10 @@ void QQuickWebEngineViewPrivate::loadStarted(const QUrl &provisionalUrl, bool is m_history->reset(); m_certificateErrorControllers.clear(); - QPointer<QQuickWebEngineView> pq(q); - QTimer::singleShot(0, [=]() - { + QTimer::singleShot(0, q, [q, provisionalUrl]() { QQuickWebEngineLoadRequest loadRequest(provisionalUrl, QQuickWebEngineView::LoadStartedStatus); - if (pq) - pq->loadingChanged(&loadRequest); + + emit q->loadingChanged(&loadRequest); }); } @@ -425,25 +423,27 @@ void QQuickWebEngineViewPrivate::loadFinished(bool success, const QUrl &url, boo isLoading = false; m_history->reset(); if (errorCode == WebEngineError::UserAbortedError) { - QQuickWebEngineLoadRequest loadRequest(url, QQuickWebEngineView::LoadStoppedStatus); - Q_EMIT q->loadingChanged(&loadRequest); + QTimer::singleShot(0, q, [q, url]() { + QQuickWebEngineLoadRequest loadRequest(url, QQuickWebEngineView::LoadStoppedStatus); + emit q->loadingChanged(&loadRequest); + }); return; } if (success) { explicitUrl = QUrl(); - QQuickWebEngineLoadRequest loadRequest(url, QQuickWebEngineView::LoadSucceededStatus); - Q_EMIT q->loadingChanged(&loadRequest); + QTimer::singleShot(0, q, [q, url]() { + QQuickWebEngineLoadRequest loadRequest(url, QQuickWebEngineView::LoadSucceededStatus); + emit q->loadingChanged(&loadRequest); + }); return; } Q_ASSERT(errorCode); - QQuickWebEngineLoadRequest loadRequest( - url, - QQuickWebEngineView::LoadFailedStatus, - errorDescription, - errorCode, - static_cast<QQuickWebEngineView::ErrorDomain>(WebEngineError::toQtErrorDomain(errorCode))); - Q_EMIT q->loadingChanged(&loadRequest); + QQuickWebEngineView::ErrorDomain errorDomain = static_cast<QQuickWebEngineView::ErrorDomain>(WebEngineError::toQtErrorDomain(errorCode)); + QTimer::singleShot(0, q, [q, url, errorDescription, errorCode, errorDomain]() { + QQuickWebEngineLoadRequest loadRequest(url, QQuickWebEngineView::LoadFailedStatus,errorDescription, errorCode, errorDomain); + emit q->loadingChanged(&loadRequest); + }); return; } diff --git a/src/webenginewidgets/api/qwebenginepage.cpp b/src/webenginewidgets/api/qwebenginepage.cpp index ddd01632984d589a295eaadbefb15e2c0019ad60..88ad7e44710a0fb115ee9db53019fe45efdaa053 100644 --- a/src/webenginewidgets/api/qwebenginepage.cpp +++ b/src/webenginewidgets/api/qwebenginepage.cpp @@ -107,8 +107,8 @@ static bool printPdfDataOnPrinter(const QByteArray& data, QPrinter& printer) return false; } - QRect printerPageRect = printer.pageRect(); - PdfiumDocumentWrapperQt pdfiumWrapper(data.constData(), data.size(), printerPageRect.size()); + QSize pageSize = printer.pageRect().size(); + PdfiumDocumentWrapperQt pdfiumWrapper(data.constData(), data.size(), pageSize); int toPage = printer.toPage(); int fromPage = printer.fromPage(); @@ -156,7 +156,8 @@ static bool printPdfDataOnPrinter(const QByteArray& data, QPrinter& printer) if (currentImage.isNull()) return false; - painter.drawImage(printerPageRect, currentImage, currentImage.rect()); + // Painting operations are automatically clipped to the bounds of the drawable part of the page. + painter.drawImage(QRect(0, 0, pageSize.width(), pageSize.height()), currentImage, currentImage.rect()); if (printedPages < pageCopies - 1) printer.newPage(); } @@ -328,7 +329,7 @@ void QWebEnginePagePrivate::loadStarted(const QUrl &provisionalUrl, bool isError return; isLoading = true; - Q_EMIT q->loadStarted(); + QTimer::singleShot(0, q, &QWebEnginePage::loadStarted); updateNavigationActions(); } @@ -346,7 +347,9 @@ void QWebEnginePagePrivate::loadFinished(bool success, const QUrl &url, bool isE if (isErrorPage) { Q_ASSERT(settings->testAttribute(QWebEngineSettings::ErrorPageEnabled)); - Q_EMIT q->loadFinished(false); + QTimer::singleShot(0, q, [q](){ + emit q->loadFinished(false); + }); return; } @@ -356,7 +359,9 @@ void QWebEnginePagePrivate::loadFinished(bool success, const QUrl &url, bool isE // Delay notifying failure until the error-page is done loading. // Error-pages are not loaded on failures due to abort. if (success || errorCode == -3 /* ERR_ABORTED*/ || !settings->testAttribute(QWebEngineSettings::ErrorPageEnabled)) { - Q_EMIT q->loadFinished(success); + QTimer::singleShot(0, q, [q, success](){ + emit q->loadFinished(success); + }); } updateNavigationActions(); } diff --git a/tests/auto/quick/qmltests/BLACKLIST b/tests/auto/quick/qmltests/BLACKLIST index b511f1a352a7c8cd086bc49e6417ba0b6691f0ea..dfafbaea456895cf5a62f1f2ccdaf2f0cfd91323 100644 --- a/tests/auto/quick/qmltests/BLACKLIST +++ b/tests/auto/quick/qmltests/BLACKLIST @@ -1,4 +1,3 @@ -osx-10.11 ci [WebViewGeopermission::test_deniedGeolocationByUser] osx diff --git a/tests/auto/quick/qmltests/data/tst_mouseClick.qml b/tests/auto/quick/qmltests/data/tst_mouseClick.qml index bd6625a90d22a393525ce0db76f0a67bb6c1a079..d81e690fd4b279dbfb5977cb563c6c91f67505fc 100644 --- a/tests/auto/quick/qmltests/data/tst_mouseClick.qml +++ b/tests/auto/quick/qmltests/data/tst_mouseClick.qml @@ -57,6 +57,10 @@ TestWebEngineView { function mouseTripleClick(item, x, y) { mouseMultiClick(item, x, y, 3); } + + function mouseQuadraClick(item, x, y) { + mouseMultiClick(item, x, y, 4); + } } @@ -109,5 +113,18 @@ TestWebEngineView { mouseClick(webEngineView, center.x, center.y); tryVerify(function() { return getTextSelection() == "" }); } + + function test_quadraClick() { + webEngineView.settings.focusOnNavigationEnabled = true; + webEngineView.loadHtml("<html><body onload='document.getElementById(\"input\").focus()'>" + + "<form><input id='input' width='150' type='text' value='The Qt Company' /></form>" + + "</body></html>"); + verify(webEngineView.waitForLoadSucceeded()); + + var center = getElementCenter("input"); + webEngineView.testSupport.mouseQuadraClick(webEngineView, center.x, center.y); + verifyElementHasFocus("input"); + tryVerify(function() { return getTextSelection() == "" }); + } } } diff --git a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp index 23c66058ed0b54aa6e5debba5c31b6f8fa3a62da..a32d96b3a9cc0440c26dbb3ee58ee1e978a2ace1 100644 --- a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp +++ b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp @@ -101,24 +101,15 @@ private Q_SLOTS: void userStyleSheet(); void userStyleSheetFromLocalFileUrl(); void userStyleSheetFromQrcUrl(); - void loadHtml5Video(); void modified(); void contextMenuCrash(); void updatePositionDependentActionsCrash(); - void createPluginWithPluginsEnabled(); - void createPluginWithPluginsDisabled(); void callbackSpyDeleted(); - void destroyPlugin_data(); - void destroyPlugin(); - void createViewlessPlugin_data(); - void createViewlessPlugin(); - void graphicsWidgetPlugin(); - void multiplePageGroupsAndLocalStorage(); + void multipleProfilesAndLocalStorage(); void cursorMovements(); void textSelection(); void textEditing(); void backActionUpdate(); - void protectBindingsRuntimeObjectsFromCollector(); void testOptionalJSObjects(); void testLocalStorageVisibility(); void testEnablePersistentStorage(); @@ -697,20 +688,6 @@ void tst_QWebEnginePage::userStyleSheetFromQrcUrl() #endif } -void tst_QWebEnginePage::loadHtml5Video() -{ -#if defined(WTF_USE_QT_MULTIMEDIA) && WTF_USE_QT_MULTIMEDIA - QByteArray url("http://does.not/exist?a=1%2Cb=2"); - m_view->setHtml("<p><video id ='video' src='" + url + "' autoplay/></p>"); - QTest::qWait(2000); - QUrl mUrl = DumpRenderTreeSupportQt::mediaContentUrlByElementId(m_page->mainFrame()->handle(), "video"); - QEXPECT_FAIL("", "https://bugs.webkit.org/show_bug.cgi?id=65452", Continue); - QCOMPARE(mUrl.toEncoded(), url); -#else - W_QSKIP("This test requires Qt Multimedia", SkipAll); -#endif -} - void tst_QWebEnginePage::modified() { #if !defined(QWEBENGINEPAGE_ISMODIFIED) @@ -817,376 +794,47 @@ void tst_QWebEnginePage::contextMenuCrash() #endif } -#if defined(QWEBENGINEPAGE_CREATEPLUGIN) -class PluginPage : public QWebEnginePage -{ -public: - PluginPage(QObject *parent = 0) - : QWebEnginePage(parent) {} - - struct CallInfo - { - CallInfo(const QString &c, const QUrl &u, - const QStringList &pn, const QStringList &pv, - QObject *r) - : classid(c), url(u), paramNames(pn), - paramValues(pv), returnValue(r) - {} - QString classid; - QUrl url; - QStringList paramNames; - QStringList paramValues; - QObject *returnValue; - }; - - QList<CallInfo> calls; - -protected: - virtual QObject *createPlugin(const QString &classid, const QUrl &url, - const QStringList ¶mNames, - const QStringList ¶mValues) - { - QObject *result = 0; - if (classid == "pushbutton") - result = new QPushButton(); -#ifndef QT_NO_INPUTDIALOG - else if (classid == "lineedit") - result = new QLineEdit(); -#endif - else if (classid == "graphicswidget") - result = new QGraphicsWidget(); - if (result) - result->setObjectName(classid); - calls.append(CallInfo(classid, url, paramNames, paramValues, result)); - return result; - } -}; - -static void createPlugin(QWebEngineView *view) -{ - QSignalSpy loadSpy(view, SIGNAL(loadFinished(bool))); - - PluginPage* newPage = new PluginPage(view); - view->setPage(newPage); - - // type has to be application/x-qt-plugin - view->setHtml(QString("<html><body><object type='application/x-foobarbaz' classid='pushbutton' id='mybutton'/></body></html>")); - QTRY_COMPARE(loadSpy.count(), 1); - QCOMPARE(newPage->calls.count(), 0); - - view->setHtml(QString("<html><body><object type='application/x-qt-plugin' classid='pushbutton' id='mybutton'/></body></html>")); - QTRY_COMPARE(loadSpy.count(), 2); - QCOMPARE(newPage->calls.count(), 1); - { - PluginPage::CallInfo ci = newPage->calls.takeFirst(); - QCOMPARE(ci.classid, QString::fromLatin1("pushbutton")); - QCOMPARE(ci.url, QUrl()); - QCOMPARE(ci.paramNames.count(), 3); - QCOMPARE(ci.paramValues.count(), 3); - QCOMPARE(ci.paramNames.at(0), QString::fromLatin1("type")); - QCOMPARE(ci.paramValues.at(0), QString::fromLatin1("application/x-qt-plugin")); - QCOMPARE(ci.paramNames.at(1), QString::fromLatin1("classid")); - QCOMPARE(ci.paramValues.at(1), QString::fromLatin1("pushbutton")); - QCOMPARE(ci.paramNames.at(2), QString::fromLatin1("id")); - QCOMPARE(ci.paramValues.at(2), QString::fromLatin1("mybutton")); - QVERIFY(ci.returnValue != 0); - QVERIFY(ci.returnValue->inherits("QPushButton")); - } - // test JS bindings - QCOMPARE(evaluateJavaScriptSync(newPage, "document.getElementById('mybutton').toString()").toString(), - QString::fromLatin1("[object HTMLObjectElement]")); - QCOMPARE(evaluateJavaScriptSync(newPage, "mybutton.toString()").toString(), - QString::fromLatin1("[object HTMLObjectElement]")); - QCOMPARE(evaluateJavaScriptSync(newPage, "typeof mybutton.objectName").toString(), - QString::fromLatin1("string")); - QCOMPARE(evaluateJavaScriptSync(newPage, "mybutton.objectName").toString(), - QString::fromLatin1("pushbutton")); - QCOMPARE(evaluateJavaScriptSync(newPage, "typeof mybutton.clicked").toString(), - QString::fromLatin1("function")); - QCOMPARE(evaluateJavaScriptSync(newPage, "mybutton.clicked.toString()").toString(), - QString::fromLatin1("function clicked() {\n [native code]\n}")); - - view->setHtml(QString("<html><body><table>" - "<tr><object type='application/x-qt-plugin' classid='lineedit' id='myedit'/></tr>" - "<tr><object type='application/x-qt-plugin' classid='pushbutton' id='mybutton'/></tr>" - "</table></body></html>"), QUrl("http://foo.bar.baz")); - QTRY_COMPARE(loadSpy.count(), 3); - QCOMPARE(newPage->calls.count(), 2); - { - PluginPage::CallInfo ci = newPage->calls.takeFirst(); - QCOMPARE(ci.classid, QString::fromLatin1("lineedit")); - QCOMPARE(ci.url, QUrl()); - QCOMPARE(ci.paramNames.count(), 3); - QCOMPARE(ci.paramValues.count(), 3); - QCOMPARE(ci.paramNames.at(0), QString::fromLatin1("type")); - QCOMPARE(ci.paramValues.at(0), QString::fromLatin1("application/x-qt-plugin")); - QCOMPARE(ci.paramNames.at(1), QString::fromLatin1("classid")); - QCOMPARE(ci.paramValues.at(1), QString::fromLatin1("lineedit")); - QCOMPARE(ci.paramNames.at(2), QString::fromLatin1("id")); - QCOMPARE(ci.paramValues.at(2), QString::fromLatin1("myedit")); - QVERIFY(ci.returnValue != 0); - QVERIFY(ci.returnValue->inherits("QLineEdit")); - } - { - PluginPage::CallInfo ci = newPage->calls.takeFirst(); - QCOMPARE(ci.classid, QString::fromLatin1("pushbutton")); - QCOMPARE(ci.url, QUrl()); - QCOMPARE(ci.paramNames.count(), 3); - QCOMPARE(ci.paramValues.count(), 3); - QCOMPARE(ci.paramNames.at(0), QString::fromLatin1("type")); - QCOMPARE(ci.paramValues.at(0), QString::fromLatin1("application/x-qt-plugin")); - QCOMPARE(ci.paramNames.at(1), QString::fromLatin1("classid")); - QCOMPARE(ci.paramValues.at(1), QString::fromLatin1("pushbutton")); - QCOMPARE(ci.paramNames.at(2), QString::fromLatin1("id")); - QCOMPARE(ci.paramValues.at(2), QString::fromLatin1("mybutton")); - QVERIFY(ci.returnValue != 0); - QVERIFY(ci.returnValue->inherits("QPushButton")); - } -} -#endif - -void tst_QWebEnginePage::graphicsWidgetPlugin() -{ -#if !defined(QWEBENGINEPAGE_CREATEPLUGIN) - QSKIP("QWEBENGINEPAGE_CREATEPLUGIN"); -#else - m_view->settings()->setAttribute(QWebEngineSettings::PluginsEnabled, true); - QGraphicsWebView webView; - - QSignalSpy loadSpy(&webView, SIGNAL(loadFinished(bool))); - - PluginPage* newPage = new PluginPage(&webView); - webView.setPage(newPage); - - // type has to be application/x-qt-plugin - webView.setHtml(QString("<html><body><object type='application/x-foobarbaz' classid='graphicswidget' id='mygraphicswidget'/></body></html>")); - QTRY_COMPARE(loadSpy.count(), 1); - QCOMPARE(newPage->calls.count(), 0); - - webView.setHtml(QString("<html><body><object type='application/x-qt-plugin' classid='graphicswidget' id='mygraphicswidget'/></body></html>")); - QTRY_COMPARE(loadSpy.count(), 2); - QCOMPARE(newPage->calls.count(), 1); - { - PluginPage::CallInfo ci = newPage->calls.takeFirst(); - QCOMPARE(ci.classid, QString::fromLatin1("graphicswidget")); - QCOMPARE(ci.url, QUrl()); - QCOMPARE(ci.paramNames.count(), 3); - QCOMPARE(ci.paramValues.count(), 3); - QCOMPARE(ci.paramNames.at(0), QString::fromLatin1("type")); - QCOMPARE(ci.paramValues.at(0), QString::fromLatin1("application/x-qt-plugin")); - QCOMPARE(ci.paramNames.at(1), QString::fromLatin1("classid")); - QCOMPARE(ci.paramValues.at(1), QString::fromLatin1("graphicswidget")); - QCOMPARE(ci.paramNames.at(2), QString::fromLatin1("id")); - QCOMPARE(ci.paramValues.at(2), QString::fromLatin1("mygraphicswidget")); - QVERIFY(ci.returnValue); - QVERIFY(ci.returnValue->inherits("QGraphicsWidget")); - } - // test JS bindings - QCOMPARE(evaluateJavaScriptSync(newPage, "document.getElementById('mygraphicswidget').toString()").toString(), - QString::fromLatin1("[object HTMLObjectElement]")); - QCOMPARE(evaluateJavaScriptSync(newPage, "mygraphicswidget.toString()").toString(), - QString::fromLatin1("[object HTMLObjectElement]")); - QCOMPARE(evaluateJavaScriptSync(newPage, "typeof mygraphicswidget.objectName").toString(), - QString::fromLatin1("string")); - QCOMPARE(evaluateJavaScriptSync(newPage, "mygraphicswidget.objectName").toString(), - QString::fromLatin1("graphicswidget")); - QCOMPARE(evaluateJavaScriptSync(newPage, "typeof mygraphicswidget.geometryChanged").toString(), - QString::fromLatin1("function")); - QCOMPARE(evaluateJavaScriptSync(newPage, "mygraphicswidget.geometryChanged.toString()").toString(), - QString::fromLatin1("function geometryChanged() {\n [native code]\n}")); -#endif -} - -void tst_QWebEnginePage::createPluginWithPluginsEnabled() +void tst_QWebEnginePage::multipleProfilesAndLocalStorage() { -#if !defined(QWEBENGINEPAGE_CREATEPLUGIN) - QSKIP("QWEBENGINEPAGE_CREATEPLUGIN"); -#else - m_view->settings()->setAttribute(QWebEngineSettings::PluginsEnabled, true); - createPlugin(m_view); -#endif -} - -void tst_QWebEnginePage::createPluginWithPluginsDisabled() -{ -#if !defined(QWEBENGINEPAGE_CREATEPLUGIN) - QSKIP("QWEBENGINEPAGE_CREATEPLUGIN"); -#else - // Qt Plugins should be loaded by QtWebEngine even when PluginsEnabled is - // false. The client decides whether a Qt plugin is enabled or not when - // it decides whether or not to instantiate it. - m_view->settings()->setAttribute(QWebEngineSettings::PluginsEnabled, false); - createPlugin(m_view); -#endif -} - -#if defined(QWEBENGINEPAGE_CREATEPLUGIN) -// Standard base class for template PluginTracerPage. In tests it is used as interface. -class PluginCounterPage : public QWebEnginePage { -public: - int m_count; - QPointer<QObject> m_widget; - QObject* m_pluginParent; - PluginCounterPage(QObject* parent = 0) - : QWebEnginePage(parent) - , m_count(0) - , m_pluginParent(0) - { - settings()->setAttribute(QWebEngineSettings::PluginsEnabled, true); - } - ~PluginCounterPage() - { - if (m_pluginParent) - m_pluginParent->deleteLater(); - } -}; - -template<class T> -class PluginTracerPage : public PluginCounterPage { -public: - PluginTracerPage(QObject* parent = 0) - : PluginCounterPage(parent) - { - // this is a dummy parent object for the created plugin - m_pluginParent = new T; - } - virtual QObject* createPlugin(const QString&, const QUrl&, const QStringList&, const QStringList&) - { - m_count++; - m_widget = new T; - // need a cast to the specific type, as QObject::setParent cannot be called, - // because it is not virtual. Instead it is necessary to call QWidget::setParent, - // which also takes a QWidget* instead of a QObject*. Therefore we need to - // upcast to T*, which is a QWidget. - static_cast<T*>(m_widget.data())->setParent(static_cast<T*>(m_pluginParent)); - return m_widget.data(); - } -}; - -class PluginFactory { -public: - enum FactoredType {QWidgetType, QGraphicsWidgetType}; - static PluginCounterPage* create(FactoredType type, QObject* parent = 0) - { - PluginCounterPage* result = 0; - switch (type) { - case QWidgetType: - result = new PluginTracerPage<QWidget>(parent); - break; - case QGraphicsWidgetType: - result = new PluginTracerPage<QGraphicsWidget>(parent); - break; - default: {/*Oops*/}; - } - return result; - } - - static void prepareTestData() + QDir dir(tmpDirPath()); + bool success = dir.mkpath("path1"); + success = success && dir.mkdir("path2"); + QVERIFY(success); { - QTest::addColumn<int>("type"); - QTest::newRow("QWidget") << (int)PluginFactory::QWidgetType; - QTest::newRow("QGraphicsWidget") << (int)PluginFactory::QGraphicsWidgetType; + QWebEngineProfile profile1("test1"); + QWebEngineProfile profile2("test2"); + profile1.settings()->setAttribute(QWebEngineSettings::LocalStorageEnabled, true); + profile2.settings()->setAttribute(QWebEngineSettings::LocalStorageEnabled, true); + profile1.setPersistentStoragePath(QDir::toNativeSeparators(tmpDirPath() + "/path1")); + profile2.setPersistentStoragePath(QDir::toNativeSeparators(tmpDirPath() + "/path2")); + + QWebEnginePage page1(&profile1, nullptr); + QWebEnginePage page2(&profile2, nullptr); + QSignalSpy loadSpy1(&page1, SIGNAL(loadFinished(bool))); + QSignalSpy loadSpy2(&page2, SIGNAL(loadFinished(bool))); + + page1.setHtml(QString("<html><body> </body></html>"), QUrl("http://wwww.example.com")); + page2.setHtml(QString("<html><body> </body></html>"), QUrl("http://wwww.example.com")); + QTRY_COMPARE(loadSpy1.count(), 1); + QTRY_COMPARE(loadSpy2.count(), 1); + + evaluateJavaScriptSync(&page1, "localStorage.setItem('test', 'value1');"); + evaluateJavaScriptSync(&page2, "localStorage.setItem('test', 'value2');"); + + page1.setHtml(QString("<html><body> </body></html>"), QUrl("http://wwww.example.com")); + page2.setHtml(QString("<html><body> </body></html>"), QUrl("http://wwww.example.com")); + QTRY_COMPARE(loadSpy1.count(), 2); + QTRY_COMPARE(loadSpy2.count(), 2); + + QVariant s1 = evaluateJavaScriptSync(&page1, "localStorage.getItem('test')"); + QCOMPARE(s1.toString(), QString("value1")); + QVariant s2 = evaluateJavaScriptSync(&page2, "localStorage.getItem('test')"); + QCOMPARE(s2.toString(), QString("value2")); } -}; -#endif - -void tst_QWebEnginePage::destroyPlugin_data() -{ -#if defined(QWEBENGINEPAGE_CREATEPLUGIN) - PluginFactory::prepareTestData(); -#endif -} - -void tst_QWebEnginePage::destroyPlugin() -{ -#if !defined(QWEBENGINEPAGE_CREATEPLUGIN) - QSKIP("QWEBENGINEPAGE_CREATEPLUGIN"); -#else - QFETCH(int, type); - PluginCounterPage* page = PluginFactory::create((PluginFactory::FactoredType)type, m_view); - m_view->setPage(page); - - // we create the plugin, so the widget should be constructed - QString content("<html><body><object type=\"application/x-qt-plugin\" classid=\"QProgressBar\"></object></body></html>"); - m_view->setHtml(content); - QVERIFY(page->m_widget); - QCOMPARE(page->m_count, 1); - - // navigate away, the plugin widget should be destructed - m_view->setHtml("<html><body>Hi</body></html>"); - QTestEventLoop::instance().enterLoop(1); - QVERIFY(!page->m_widget); -#endif -} - -void tst_QWebEnginePage::createViewlessPlugin_data() -{ -#if defined(QWEBENGINEPAGE_CREATEPLUGIN) - PluginFactory::prepareTestData(); -#endif -} - -void tst_QWebEnginePage::createViewlessPlugin() -{ -#if !defined(QWEBENGINEPAGE_CREATEPLUGIN) - QSKIP("QWEBENGINEPAGE_CREATEPLUGIN"); -#else - QFETCH(int, type); - PluginCounterPage* page = PluginFactory::create((PluginFactory::FactoredType)type); - QString content("<html><body><object type=\"application/x-qt-plugin\" classid=\"QProgressBar\"></object></body></html>"); - page->setHtml(content); - QCOMPARE(page->m_count, 1); - QVERIFY(page->m_widget); - QVERIFY(page->m_pluginParent); - QVERIFY(page->m_widget.data()->parent() == page->m_pluginParent); - delete page; -#endif -} - -void tst_QWebEnginePage::multiplePageGroupsAndLocalStorage() -{ -#if !defined(QWEBENGINESETTINGS_SETLOCALSTORAGEPATH) - QSKIP("QWEBENGINESETTINGS_SETLOCALSTORAGEPATH"); -#else - QDir dir(tmpDirPath()); - dir.mkdir("path1"); - dir.mkdir("path2"); - - QWebEngineView view1; - QWebEngineView view2; - - view1.page()->settings()->setAttribute(QWebEngineSettings::LocalStorageEnabled, true); - view1.page()->settings()->setLocalStoragePath(QDir::toNativeSeparators(tmpDirPath() + "/path1")); - DumpRenderTreeSupportQt::webPageSetGroupName(view1.page()->handle(), "group1"); - view2.page()->settings()->setAttribute(QWebEngineSettings::LocalStorageEnabled, true); - view2.page()->settings()->setLocalStoragePath(QDir::toNativeSeparators(tmpDirPath() + "/path2")); - DumpRenderTreeSupportQt::webPageSetGroupName(view2.page()->handle(), "group2"); - QCOMPARE(DumpRenderTreeSupportQt::webPageGroupName(view1.page()->handle()), QString("group1")); - QCOMPARE(DumpRenderTreeSupportQt::webPageGroupName(view2.page()->handle()), QString("group2")); - - - view1.setHtml(QString("<html><body> </body></html>"), QUrl("http://www.myexample.com")); - view2.setHtml(QString("<html><body> </body></html>"), QUrl("http://www.myexample.com")); - - evaluateJavaScriptSync(view1.page(), "localStorage.test='value1';"); - evaluateJavaScriptSync(view2.page(), "localStorage.test='value2';"); - - view1.setHtml(QString("<html><body> </body></html>"), QUrl("http://www.myexample.com")); - view2.setHtml(QString("<html><body> </body></html>"), QUrl("http://www.myexample.com")); - - QVariant s1 = evaluateJavaScriptSync(view1.page(), "localStorage.test"); - QCOMPARE(s1.toString(), QString("value1")); - - QVariant s2 = evaluateJavaScriptSync(view2.page(), "localStorage.test"); - QCOMPARE(s2.toString(), QString("value2")); - + // Avoid deleting on-disk dbs before the underlying browser-context has been asynchronously deleted QTest::qWait(1000); - - QFile::remove(QDir::toNativeSeparators(tmpDirPath() + "/path1/http_www.myexample.com_0.localstorage")); - QFile::remove(QDir::toNativeSeparators(tmpDirPath() + "/path2/http_www.myexample.com_0.localstorage")); - dir.rmdir(QDir::toNativeSeparators("./path1")); - dir.rmdir(QDir::toNativeSeparators("./path2")); -#endif + QDir(tmpDirPath() + "/path1").removeRecursively(); + QDir(tmpDirPath() + "/path2").removeRecursively(); } class CursorTrackedPage : public QWebEnginePage @@ -1660,32 +1308,6 @@ void tst_QWebEnginePage::backActionUpdate() QVERIFY(action->isEnabled()); } -void tst_QWebEnginePage::protectBindingsRuntimeObjectsFromCollector() -{ -#if !defined(QWEBENGINEPAGE_CREATEPLUGIN) - QSKIP("QWEBENGINEPAGE_CREATEPLUGIN"); -#else - QSignalSpy loadSpy(m_view, SIGNAL(loadFinished(bool))); - - PluginPage* newPage = new PluginPage(m_view); - m_view->setPage(newPage); - - m_view->settings()->setAttribute(QWebEngineSettings::PluginsEnabled, true); - - m_view->setHtml(QString("<html><body><object type='application/x-qt-plugin' classid='lineedit' id='mylineedit'/></body></html>")); - QTRY_COMPARE(loadSpy.count(), 1); - - newPage->runJavaScript("function testme(text) { var lineedit = document.getElementById('mylineedit'); lineedit.setText(text); lineedit.selectAll(); }"); - - evaluateJavaScriptSync(newPage, "testme('foo')"); - - DumpRenderTreeSupportQt::garbageCollectorCollect(); - - // don't crash! - evaluateJavaScriptSync(newPage, "testme('bar')"); -#endif -} - #if defined(QWEBENGINEPAGE_SETTINGS) static inline bool testFlag(QWebEnginePage& webPage, QWebEngineSettings::WebAttribute settingAttribute, const QString& jsObjectName, bool settingValue) { @@ -3790,8 +3412,6 @@ void tst_QWebEnginePage::setUrlWithPendingLoads() void tst_QWebEnginePage::setUrlToEmpty() { - QSKIP("FIXME: [0908/090526:FATAL:navigation_controller_impl.cc(927)] Check failed: active_entry->site_instance() == rfh->GetSiteInstance()."); - int expectedLoadFinishedCount = 0; const QUrl aboutBlank("about:blank"); const QUrl url("qrc:/resources/test2.html"); @@ -3799,7 +3419,8 @@ void tst_QWebEnginePage::setUrlToEmpty() QWebEnginePage page; QCOMPARE(page.url(), QUrl()); QCOMPARE(page.requestedUrl(), QUrl()); - QCOMPARE(baseUrlSync(&page), QUrl()); +// Chromium now returns about:blank as the base url here: +// QCOMPARE(baseUrlSync(&page), QUrl()); QSignalSpy spy(&page, SIGNAL(loadFinished(bool))); @@ -3966,8 +3587,6 @@ static QStringList collectHistoryUrls(QWebEngineHistory *history) void tst_QWebEnginePage::setUrlHistory() { - QSKIP("FIXME: [0908/090526:FATAL:navigation_controller_impl.cc(927)] Check failed: active_entry->site_instance() == rfh->GetSiteInstance()."); - const QUrl aboutBlank("about:blank"); QUrl url; int expectedLoadFinishedCount = 0; @@ -3983,10 +3602,10 @@ void tst_QWebEnginePage::setUrlHistory() // Chromium stores navigation entry for every successful loads. The load of the empty page is committed and stored as about:blank. QCOMPARE(collectHistoryUrls(m_page->history()), QStringList() << aboutBlank.toString()); - url = QUrl("http://non.existent/"); + url = QUrl("http://url.invalid/"); m_page->setUrl(url); expectedLoadFinishedCount++; - QTRY_COMPARE(spy.count(), expectedLoadFinishedCount); + QTRY_COMPARE_WITH_TIMEOUT(spy.count(), expectedLoadFinishedCount, 20000); // When error page is disabled in case of LoadFail the entry of the unavailable page is not stored. // We expect the url of the previously loaded page here. QCOMPARE(m_page->url(), aboutBlank); diff --git a/tests/auto/widgets/qwebengineprofile/tst_qwebengineprofile.cpp b/tests/auto/widgets/qwebengineprofile/tst_qwebengineprofile.cpp index 6961f3b6da3c1fa54b9a2158152d75967f0a779a..c443ee11433926fcef7ddd221b838bf8451a73a7 100644 --- a/tests/auto/widgets/qwebengineprofile/tst_qwebengineprofile.cpp +++ b/tests/auto/widgets/qwebengineprofile/tst_qwebengineprofile.cpp @@ -200,9 +200,13 @@ public: } bool isSequential() const override { return true; } qint64 bytesAvailable() const override - { return m_bytesAvailable; } + { + QMutexLocker lock(&m_mutex); + return m_bytesAvailable; + } bool atEnd() const override { + QMutexLocker lock(&m_mutex); return (m_data.size() >= 1000 && m_bytesRead >= 1000); } protected: @@ -237,7 +241,7 @@ protected: } private: - QMutex m_mutex; + mutable QMutex m_mutex{QMutex::Recursive}; QByteArray m_data; QBasicTimer m_timer; int m_bytesRead;