From 4b5504d4d93152894024c58e040b61f03caaa837 Mon Sep 17 00:00:00 2001 From: Szabolcs David Date: Tue, 11 Jan 2022 14:53:00 +0100 Subject: Fix printing PDF files MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Delegate printing task down to the guest WebContents if any is present. Also update PrintWebViewHelperDelegateQt to find the plugin element properly for printing. Task-number: QTBUG-98941 Change-Id: I81004a2275e0870a17565af527b1450472afb24b Reviewed-by: Michael BrĂ¼ning (cherry picked from commit 455efe7ef204c6cd8de72b9b1f922f1681f58589) Reviewed-by: Allan Sandfeld Jensen --- .../renderer/print_web_view_helper_delegate_qt.cpp | 25 ++++++++++++---- src/core/web_contents_adapter.cpp | 33 ++++++++++++++-------- src/core/web_contents_adapter.h | 1 + 3 files changed, 43 insertions(+), 16 deletions(-) diff --git a/src/core/renderer/print_web_view_helper_delegate_qt.cpp b/src/core/renderer/print_web_view_helper_delegate_qt.cpp index beae6ecfa..5dcfaafd6 100644 --- a/src/core/renderer/print_web_view_helper_delegate_qt.cpp +++ b/src/core/renderer/print_web_view_helper_delegate_qt.cpp @@ -43,11 +43,17 @@ #include "content/public/renderer/render_frame.h" #include "content/public/renderer/render_view.h" +#include "extensions/buildflags/buildflags.h" #include "extensions/common/constants.h" #include "third_party/blink/public/web/web_document.h" #include "third_party/blink/public/web/web_element.h" #include "third_party/blink/public/web/web_local_frame.h" +#if BUILDFLAG(ENABLE_EXTENSIONS) +#include "chrome/common/webui_url_constants.h" +#include "extensions/common/constants.h" +#endif // BUILDFLAG(ENABLE_EXTENSIONS) + #include "print_web_view_helper_delegate_qt.h" #include "web_engine_library_info.h" @@ -56,14 +62,23 @@ PrintWebViewHelperDelegateQt::~PrintWebViewHelperDelegateQt() {} blink::WebElement PrintWebViewHelperDelegateQt::GetPdfElement(blink::WebLocalFrame *frame) { +#if BUILDFLAG(ENABLE_EXTENSIONS) GURL url = frame->GetDocument().Url(); - if (url.SchemeIs(extensions::kExtensionScheme) && url.host() == extension_misc::kPdfExtensionId) { + bool inside_print_preview = url.GetOrigin() == chrome::kChromeUIPrintURL; + bool inside_pdf_extension = url.SchemeIs(extensions::kExtensionScheme) && + url.host_piece() == extension_misc::kPdfExtensionId; + if (inside_print_preview || inside_pdf_extension) { // with id="plugin" is created in - // chrome/browser/resources/pdf/pdf.js. - auto plugin_element = frame->GetDocument().GetElementById("plugin"); - CHECK(!plugin_element.IsNull()); - return plugin_element; + // chrome/browser/resources/pdf/pdf_viewer_base.js. + auto viewer_element = frame->GetDocument().GetElementById("viewer"); + if (!viewer_element.IsNull() && !viewer_element.ShadowRoot().IsNull()) { + auto plugin_element = viewer_element.ShadowRoot().QuerySelector("#plugin"); + if (!plugin_element.IsNull()) + return plugin_element; + } + NOTREACHED(); } +#endif // BUILDFLAG(ENABLE_EXTENSIONS) return blink::WebElement(); } diff --git a/src/core/web_contents_adapter.cpp b/src/core/web_contents_adapter.cpp index 2cd48907b..5b81bd3fc 100644 --- a/src/core/web_contents_adapter.cpp +++ b/src/core/web_contents_adapter.cpp @@ -1332,10 +1332,13 @@ void WebContentsAdapter::printToPDF(const QPageLayout &pageLayout, const QString PrintViewManagerQt::PrintToPDFFileCallback callback = base::Bind(&callbackOnPdfSavingFinished, m_adapterClient, filePath); - PrintViewManagerQt::FromWebContents(m_webContents.get())->PrintToPDFFileWithCallback(pageLayout, - true, - filePath, - callback); + content::WebContents *webContents = m_webContents.get(); + if (content::WebContents *guest = guestWebContents()) + webContents = guest; + PrintViewManagerQt::FromWebContents(webContents)->PrintToPDFFileWithCallback(pageLayout, + true, + filePath, + callback); #endif // QT_CONFIG(webengine_printing_and_pdf) } @@ -1348,10 +1351,13 @@ quint64 WebContentsAdapter::printToPDFCallbackResult(const QPageLayout &pageLayo PrintViewManagerQt::PrintToPDFCallback callback = base::Bind(&callbackOnPrintingFinished, m_adapterClient, m_nextRequestId); - PrintViewManagerQt::FromWebContents(m_webContents.get())->PrintToPDFWithCallback(pageLayout, - colorMode, - useCustomMargins, - callback); + content::WebContents *webContents = m_webContents.get(); + if (content::WebContents *guest = guestWebContents()) + webContents = guest; + PrintViewManagerQt::FromWebContents(webContents)->PrintToPDFWithCallback(pageLayout, + colorMode, + useCustomMargins, + callback); return m_nextRequestId++; #else Q_UNUSED(pageLayout); @@ -1444,6 +1450,12 @@ content::WebContents *WebContentsAdapter::webContents() const return m_webContents.get(); } +content::WebContents *WebContentsAdapter::guestWebContents() const +{ + std::vector innerWebContents = m_webContents->GetInnerWebContents(); + return !innerWebContents.empty() ? innerWebContents[0] : nullptr; +} + #if QT_CONFIG(webengine_webchannel) QWebChannel *WebContentsAdapter::webChannel() const { @@ -1551,9 +1563,8 @@ void WebContentsAdapter::startDragging(QObject *dragSource, const content::DropD // dropping data into them. We don't even try to support dropping into PDF input fields, // since it's not working in Chrome right now. content::WebContents *targetWebContents = m_webContents.get(); - std::vector innerWebContents = m_webContents->GetInnerWebContents(); - if (!innerWebContents.empty()) - targetWebContents = innerWebContents[0]; + if (content::WebContents *guest = guestWebContents()) + targetWebContents = guest; content::RenderViewHost *rvh = targetWebContents->GetRenderViewHost(); if (rvh) { diff --git a/src/core/web_contents_adapter.h b/src/core/web_contents_adapter.h index 78dda6060..ba02a0418 100644 --- a/src/core/web_contents_adapter.h +++ b/src/core/web_contents_adapter.h @@ -242,6 +242,7 @@ public: // meant to be used within WebEngineCore only void initialize(content::SiteInstance *site); content::WebContents *webContents() const; + content::WebContents *guestWebContents() const; void updateRecommendedState(); void setRequestInterceptor(QWebEngineUrlRequestInterceptor *interceptor); QWebEngineUrlRequestInterceptor* requestInterceptor() const; -- cgit v1.2.3