diff options
-rw-r--r-- | examples/webenginewidgets/simplebrowser/tabwidget.cpp | 4 | ||||
m--------- | src/3rdparty | 0 | ||||
-rw-r--r-- | src/core/api/qwebengineurlrequestinfo.h | 4 | ||||
-rw-r--r-- | src/core/content_browser_client_qt.cpp | 45 | ||||
-rw-r--r-- | src/core/core_module.pro | 6 | ||||
-rw-r--r-- | src/core/devtools_frontend_qt.cpp | 2 | ||||
-rw-r--r-- | src/core/download_manager_delegate_qt.cpp | 7 | ||||
-rw-r--r-- | src/core/extensions/component_extension_resource_manager_qt.cpp | 25 | ||||
-rw-r--r-- | src/core/extensions/component_extension_resource_manager_qt.h | 3 | ||||
-rw-r--r-- | src/core/profile_io_data_qt.h | 1 | ||||
-rw-r--r-- | src/core/web_engine_settings.cpp | 27 | ||||
-rw-r--r-- | tests/auto/widgets/qwebenginedownloadrequest/tst_qwebenginedownloadrequest.cpp | 47 |
12 files changed, 141 insertions, 30 deletions
diff --git a/examples/webenginewidgets/simplebrowser/tabwidget.cpp b/examples/webenginewidgets/simplebrowser/tabwidget.cpp index e5a3d4d28..b706a3ab7 100644 --- a/examples/webenginewidgets/simplebrowser/tabwidget.cpp +++ b/examples/webenginewidgets/simplebrowser/tabwidget.cpp @@ -196,7 +196,9 @@ void TabWidget::setupView(WebView *webView) }); connect(webPage, &QWebEnginePage::windowCloseRequested, [this, webView]() { int index = indexOf(webView); - if (index >= 0) + if (webView->page()->inspectedPage()) + window()->close(); + else if (index >= 0) closeTab(index); }); connect(webView, &WebView::devToolsRequested, this, &TabWidget::devToolsRequested); diff --git a/src/3rdparty b/src/3rdparty -Subproject 3b1e8320c3e93dc41211ccd66cfd26fa7eec18c +Subproject f9845463789f5dc3e8e3858280f23700bcb5ed5 diff --git a/src/core/api/qwebengineurlrequestinfo.h b/src/core/api/qwebengineurlrequestinfo.h index 21e44d2f1..7c12f1861 100644 --- a/src/core/api/qwebengineurlrequestinfo.h +++ b/src/core/api/qwebengineurlrequestinfo.h @@ -47,8 +47,6 @@ namespace QtWebEngineCore { class InterceptedRequest; -class NetworkDelegateQt; -class URLRequestNotification; } // namespace QtWebEngineCore QT_BEGIN_NAMESPACE @@ -109,8 +107,6 @@ public: void setHttpHeader(const QByteArray &name, const QByteArray &value); private: - friend class QtWebEngineCore::NetworkDelegateQt; - friend class QtWebEngineCore::URLRequestNotification; friend class QtWebEngineCore::InterceptedRequest; Q_DISABLE_COPY(QWebEngineUrlRequestInfo) Q_DECLARE_PRIVATE(QWebEngineUrlRequestInfo) diff --git a/src/core/content_browser_client_qt.cpp b/src/core/content_browser_client_qt.cpp index 426c3beb2..0c1c8b111 100644 --- a/src/core/content_browser_client_qt.cpp +++ b/src/core/content_browser_client_qt.cpp @@ -162,9 +162,12 @@ #if BUILDFLAG(ENABLE_EXTENSIONS) #include "content/public/browser/file_url_loader.h" +#include "extensions/browser/api/mime_handler_private/mime_handler_private.h" #include "extensions/browser/extension_message_filter.h" #include "extensions/browser/extension_registry.h" +#include "extensions/browser/extension_registry.h" #include "extensions/browser/guest_view/extensions_guest_view_message_filter.h" +#include "extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest.h" #include "extensions/browser/url_loader_factory_manager.h" #include "extensions/common/constants.h" @@ -489,6 +492,32 @@ static void BindNetworkHintsHandler(content::RenderFrameHost *frame_host, network_hints::SimpleNetworkHintsHandlerImpl::Create(frame_host, std::move(receiver)); } +#if BUILDFLAG(ENABLE_EXTENSIONS) +static void BindMimeHandlerService(content::RenderFrameHost *frame_host, + mojo::PendingReceiver<extensions::mime_handler::MimeHandlerService> + receiver) { + auto *web_contents = content::WebContents::FromRenderFrameHost(frame_host); + if (!web_contents) + return; + auto *guest_view = extensions::MimeHandlerViewGuest::FromWebContents(web_contents); + if (!guest_view) + return; + extensions::MimeHandlerServiceImpl::Create(guest_view->GetStreamWeakPtr(), std::move(receiver)); +} + +static void BindBeforeUnloadControl(content::RenderFrameHost *frame_host, + mojo::PendingReceiver<extensions::mime_handler::BeforeUnloadControl> + receiver) { + auto *web_contents = content::WebContents::FromRenderFrameHost(frame_host); + if (!web_contents) + return; + auto *guest_view = extensions::MimeHandlerViewGuest::FromWebContents(web_contents); + if (!guest_view) + return; + guest_view->FuseBeforeUnloadControl(std::move(receiver)); +} +#endif + void ContentBrowserClientQt::RegisterBrowserInterfaceBindersForFrame( content::RenderFrameHost *render_frame_host, mojo::BinderMapWithContext<content::RenderFrameHost *> *map) @@ -496,6 +525,22 @@ void ContentBrowserClientQt::RegisterBrowserInterfaceBindersForFrame( Q_UNUSED(render_frame_host); map->Add<blink::mojom::InsecureInputService>(base::BindRepeating(&ServiceDriver::BindInsecureInputService)); map->Add<network_hints::mojom::NetworkHintsHandler>(base::BindRepeating(&BindNetworkHintsHandler)); +#if BUILDFLAG(ENABLE_EXTENSIONS) + map->Add<extensions::mime_handler::MimeHandlerService>(base::BindRepeating(&BindMimeHandlerService)); + map->Add<extensions::mime_handler::BeforeUnloadControl>(base::BindRepeating(&BindBeforeUnloadControl)); + const GURL &site = render_frame_host->GetSiteInstance()->GetSiteURL(); + if (!site.SchemeIs(extensions::kExtensionScheme)) + return; + content::BrowserContext *browser_context = render_frame_host->GetProcess()->GetBrowserContext(); + auto *extension = extensions::ExtensionRegistry::Get(browser_context) + ->enabled_extensions() + .GetByID(site.host()); + if (!extension) + return; + extensions::ExtensionsBrowserClient::Get()->RegisterBrowserInterfaceBindersForFrame(map, + render_frame_host, + extension); +#endif } void ContentBrowserClientQt::ExposeInterfacesToRenderer(service_manager::BinderRegistry *registry, diff --git a/src/core/core_module.pro b/src/core/core_module.pro index 733e40534..520b452f7 100644 --- a/src/core/core_module.pro +++ b/src/core/core_module.pro @@ -42,8 +42,10 @@ QMAKE_INFO_PLIST = Info_mac.plist CONFIG -= bsymbolic_functions linux { - QMAKE_LINK="ulimit -n 4096 && $$QMAKE_LINK" - QMAKE_LINK_SHLIB="ulimit -n 4096 && $$QMAKE_LINK_SHLIB" + !ccache:!use_gold_linker:!use_lld_linker { + QMAKE_LINK="ulimit -n 4096 && $$QMAKE_LINK" + QMAKE_LINK_SHLIB="ulimit -n 4096 && $$QMAKE_LINK_SHLIB" + } qtConfig(separate_debug_info): QMAKE_POST_LINK="cd $(DESTDIR) && $(STRIP) --strip-unneeded $(TARGET)" } diff --git a/src/core/devtools_frontend_qt.cpp b/src/core/devtools_frontend_qt.cpp index 028f5f0d3..71d51190a 100644 --- a/src/core/devtools_frontend_qt.cpp +++ b/src/core/devtools_frontend_qt.cpp @@ -529,6 +529,8 @@ void DevToolsFrontendQt::HandleMessageFromDevToolsFrontend(const std::string &me return; } else if (method == "bringToFront") { Activate(); + } else if (method == "closeWindow") { + web_contents()->Close(); } else { VLOG(1) << "Unimplemented devtools method: " << message; return; diff --git a/src/core/download_manager_delegate_qt.cpp b/src/core/download_manager_delegate_qt.cpp index b3abf6bdd..b7b744603 100644 --- a/src/core/download_manager_delegate_qt.cpp +++ b/src/core/download_manager_delegate_qt.cpp @@ -150,8 +150,11 @@ bool DownloadManagerDelegateQt::DetermineDownloadTarget(download::DownloadItem * if (suggestedFilename.isEmpty()) suggestedFilename = toQt(item->GetTargetFilePath().AsUTF8Unsafe()); - if (suggestedFilename.isEmpty()) - suggestedFilename = QUrl::fromPercentEncoding(toQByteArray(item->GetURL().ExtractFileName())); + if (suggestedFilename.isEmpty()) { + GURL itemUrl = item->GetURL(); + if (!itemUrl.SchemeIs("about") && !itemUrl.SchemeIs("data")) + suggestedFilename = QUrl::fromPercentEncoding(toQByteArray(itemUrl.ExtractFileName())); + } if (suggestedFilename.isEmpty()) { suggestedFilename = QStringLiteral("qwe_download"); diff --git a/src/core/extensions/component_extension_resource_manager_qt.cpp b/src/core/extensions/component_extension_resource_manager_qt.cpp index 1f58de151..fb6bb5950 100644 --- a/src/core/extensions/component_extension_resource_manager_qt.cpp +++ b/src/core/extensions/component_extension_resource_manager_qt.cpp @@ -44,12 +44,19 @@ #include "component_extension_resource_manager_qt.h" +#include "base/check.h" #include "base/logging.h" #include "base/path_service.h" #include "base/stl_util.h" #include "base/values.h" - #include "chrome/grit/component_extension_resources_map.h" +#include "content/public/browser/browser_thread.h" +#include "extensions/common/constants.h" +#include "pdf/buildflags.h" + +#if BUILDFLAG(ENABLE_PDF) +#include "qtwebengine/browser/pdf/pdf_extension_util.h" +#endif // BUILDFLAG(ENABLE_PDF) namespace extensions { @@ -57,6 +64,16 @@ ComponentExtensionResourceManagerQt::ComponentExtensionResourceManagerQt() { AddComponentResourceEntries(kComponentExtensionResources, kComponentExtensionResourcesSize); + +#if BUILDFLAG(ENABLE_PDF) + base::Value dict(base::Value::Type::DICTIONARY); + pdf_extension_util::AddStrings(pdf_extension_util::PdfViewerContext::kPdfViewer, &dict); + pdf_extension_util::AddAdditionalData(&dict); + + ui::TemplateReplacements pdf_viewer_replacements; + ui::TemplateReplacementsFromDictionaryValue(base::Value::AsDictionaryValue(dict), &pdf_viewer_replacements); + template_replacements_[extension_misc::kPdfExtensionId] = std::move(pdf_viewer_replacements); +#endif } ComponentExtensionResourceManagerQt::~ComponentExtensionResourceManagerQt() {} @@ -85,9 +102,11 @@ bool ComponentExtensionResourceManagerQt::IsComponentExtensionResource(const bas return false; } -const ui::TemplateReplacements *ComponentExtensionResourceManagerQt::GetTemplateReplacementsForExtension(const std::string &) const +const ui::TemplateReplacements *ComponentExtensionResourceManagerQt::GetTemplateReplacementsForExtension(const std::string &extension_id) const { - return nullptr; + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); + auto it = template_replacements_.find(extension_id); + return it != template_replacements_.end() ? &it->second : nullptr; } void ComponentExtensionResourceManagerQt::AddComponentResourceEntries(const GritResourceMap *entries, size_t size) diff --git a/src/core/extensions/component_extension_resource_manager_qt.h b/src/core/extensions/component_extension_resource_manager_qt.h index 992e9f87c..6131e91aa 100644 --- a/src/core/extensions/component_extension_resource_manager_qt.h +++ b/src/core/extensions/component_extension_resource_manager_qt.h @@ -73,6 +73,9 @@ private: // IsComponentExtensionResource. std::map<base::FilePath, int> path_to_resource_id_; + // A map from an extension ID to its i18n template replacements. + std::map<std::string, ui::TemplateReplacements> template_replacements_; + DISALLOW_COPY_AND_ASSIGN(ComponentExtensionResourceManagerQt); }; diff --git a/src/core/profile_io_data_qt.h b/src/core/profile_io_data_qt.h index f2a6a7822..3f8205159 100644 --- a/src/core/profile_io_data_qt.h +++ b/src/core/profile_io_data_qt.h @@ -97,7 +97,6 @@ public: bool canGetCookies(const QUrl &firstPartyUrl, const QUrl &url) const; - // Used in NetworkDelegateQt::OnBeforeURLRequest. void setFullConfiguration(); // runs on ui thread void resetNetworkContext(); // runs on ui thread void clearHttpCache(); // runs on ui thread diff --git a/src/core/web_engine_settings.cpp b/src/core/web_engine_settings.cpp index 218053e47..d7feb0e41 100644 --- a/src/core/web_engine_settings.cpp +++ b/src/core/web_engine_settings.cpp @@ -425,23 +425,16 @@ void WebEngineSettings::applySettingsToWebPreferences(blink::web_pref::WebPrefer // Set the theme colors. Based on chrome_content_browser_client.cc: const ui::NativeTheme *webTheme = ui::NativeTheme::GetInstanceForWeb(); - // WebPreferences::preferred_color_scheme was deleted in Chromium 80, but it - // will make a comeback in Chromium 82... - // - // See also: https://chromium-review.googlesource.com/c/chromium/src/+/2079192 - // - // if (webTheme) { - // switch (webTheme->GetPreferredColorScheme()) { - // case ui::NativeTheme::PreferredColorScheme::kDark: - // prefs->preferred_color_scheme = blink::PreferredColorScheme::kDark; - // break; - // case ui::NativeTheme::PreferredColorScheme::kLight: - // prefs->preferred_color_scheme = blink::PreferredColorScheme::kLight; - // break; - // case ui::NativeTheme::PreferredColorScheme::kNoPreference: - // prefs->preferred_color_scheme = blink::PreferredColorScheme::kNoPreference; - // } - // } + if (webTheme) { + switch (webTheme->GetPreferredColorScheme()) { + case ui::NativeTheme::PreferredColorScheme::kDark: + prefs->preferred_color_scheme = blink::PreferredColorScheme::kDark; + break; + case ui::NativeTheme::PreferredColorScheme::kLight: + prefs->preferred_color_scheme = blink::PreferredColorScheme::kLight; + break; + } + } // Apply native CaptionStyle parameters. base::Optional<ui::CaptionStyle> style; diff --git a/tests/auto/widgets/qwebenginedownloadrequest/tst_qwebenginedownloadrequest.cpp b/tests/auto/widgets/qwebenginedownloadrequest/tst_qwebenginedownloadrequest.cpp index 3c3f1054d..545f062c1 100644 --- a/tests/auto/widgets/qwebenginedownloadrequest/tst_qwebenginedownloadrequest.cpp +++ b/tests/auto/widgets/qwebenginedownloadrequest/tst_qwebenginedownloadrequest.cpp @@ -81,6 +81,8 @@ private Q_SLOTS: void downloadToReadOnlyDir(); void downloadToDirectoryWithFileName_data(); void downloadToDirectoryWithFileName(); + void downloadDataUrls_data(); + void downloadDataUrls(); private: void saveLink(QPoint linkPos); @@ -1249,5 +1251,50 @@ void tst_QWebEngineDownloadRequest::downloadToDirectoryWithFileName() QCOMPARE(downloadedSuggestedFileName, fileName); } +void tst_QWebEngineDownloadRequest::downloadDataUrls_data() +{ + QTest::addColumn<QByteArray>("htmlData"); + QTest::addColumn<QString>("expectedFileName"); + QTest::newRow("data url without slash") << QByteArrayLiteral("<html><head><meta charset=\"utf-8\"></head><body><a href=\"data:application/gzip;base64,dGVzdA==\">data URL without slash</a><br/></body></html>") << QStringLiteral("qwe_download.gz") ; + QTest::newRow("data url with slash") << QByteArrayLiteral("<html><head><meta charset=\"utf-8\"></head><body><a href=\"data:application/gzip;base64,dGVzcnI/dGVzdA==\">data URL with filename</a><br/></body></html>") << QStringLiteral("qwe_download.gz") ; + QTest::newRow("data url with download tag") << QByteArrayLiteral("<html><head><meta charset=\"utf-8\"></head><body><a href=\"data:application/gzip;base64,dGVzdA/IHRlc3Q=\" download=\"filename.gz\">data URL with filename</a><br/></body></html>") << QStringLiteral("filename.gz") ; + +} + +void tst_QWebEngineDownloadRequest::downloadDataUrls() +{ + QFETCH(QByteArray, htmlData); + QFETCH(QString, expectedFileName); + // Set up HTTP server + ScopedConnection sc1 = connect(m_server, &HttpServer::newRequest, [&](HttpReqRep *rr) { + if (rr->requestMethod() == "GET" && rr->requestPath() == "/") { + rr->setResponseHeader(QByteArrayLiteral("content-type"), QByteArrayLiteral("text/html")); + rr->setResponseBody(htmlData); + rr->sendResponse(); + } + }); + + // Set up profile and download handler + QTemporaryDir tmpDir; + QVERIFY(tmpDir.isValid()); + m_profile->setDownloadPath(tmpDir.path()); + + int downloadRequestCount = 0; + ScopedConnection sc2 = connect(m_profile, &QWebEngineProfile::downloadRequested, [&](QWebEngineDownloadRequest *item) { + QCOMPARE(item->state(), QWebEngineDownloadRequest::DownloadRequested); + QCOMPARE(item->downloadFileName(), expectedFileName); + downloadRequestCount++; + }); + + QSignalSpy loadSpy(m_page, &QWebEnginePage::loadFinished); + m_view->load(m_server->url()); + QTRY_COMPARE(loadSpy.count(), 1); + QCOMPARE(loadSpy.takeFirst().value(0).toBool(), true); + + // Trigger download + simulateUserAction(QPoint(10, 10), UserAction::ClickLink); + QTRY_COMPARE(downloadRequestCount, 1); +} + QTEST_MAIN(tst_QWebEngineDownloadRequest) #include "tst_qwebenginedownloadrequest.moc" |