summaryrefslogtreecommitdiffstats
path: root/src/core/printing/pdf_stream_delegate_qt.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/printing/pdf_stream_delegate_qt.cpp')
-rw-r--r--src/core/printing/pdf_stream_delegate_qt.cpp99
1 files changed, 99 insertions, 0 deletions
diff --git a/src/core/printing/pdf_stream_delegate_qt.cpp b/src/core/printing/pdf_stream_delegate_qt.cpp
new file mode 100644
index 000000000..8677c82bd
--- /dev/null
+++ b/src/core/printing/pdf_stream_delegate_qt.cpp
@@ -0,0 +1,99 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+// based on chrome/browser/pdf/chrome_pdf_stream_delegate.cc:
+
+#include "pdf_stream_delegate_qt.h"
+
+#include "base/no_destructor.h"
+#include "chrome/grit/pdf_resources.h"
+#include "content/public/browser/document_user_data.h"
+#include "content/public/browser/navigation_handle.h"
+#include "extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest.h"
+#include "extensions/common/constants.h"
+#include "ui/base/resource/resource_bundle.h"
+
+// Associates a `pdf::PdfStreamDelegate::StreamInfo` with the PDF extension's
+// or Print Preview's `blink::Document`.
+// `ChromePdfStreamDelegate::MapToOriginalUrl()` initializes this in
+// `PdfNavigationThrottle`, and then `ChromePdfStreamDelegate::GetStreamInfo()`
+// returns the stashed result to `PdfURLLoaderRequestInterceptor`.
+class StreamInfoHelper : public content::DocumentUserData<StreamInfoHelper>
+{
+public:
+ absl::optional<pdf::PdfStreamDelegate::StreamInfo> TakeStreamInfo()
+ { return std::move(stream_info_); }
+
+private:
+ friend class content::DocumentUserData<StreamInfoHelper>;
+ DOCUMENT_USER_DATA_KEY_DECL();
+
+ StreamInfoHelper(content::RenderFrameHost* embedder_frame,
+ pdf::PdfStreamDelegate::StreamInfo stream_info)
+ : content::DocumentUserData<StreamInfoHelper>(embedder_frame),
+ stream_info_(std::move(stream_info)) {}
+
+ absl::optional<pdf::PdfStreamDelegate::StreamInfo> stream_info_;
+};
+
+DOCUMENT_USER_DATA_KEY_IMPL(StreamInfoHelper);
+
+PdfStreamDelegateQt::PdfStreamDelegateQt() = default;
+PdfStreamDelegateQt::~PdfStreamDelegateQt() = default;
+
+absl::optional<GURL> PdfStreamDelegateQt::MapToOriginalUrl(content::NavigationHandle &navigation_handle)
+{
+ content::RenderFrameHost *embedder_frame = navigation_handle.GetParentFrame();
+ StreamInfoHelper *helper = StreamInfoHelper::GetForCurrentDocument(embedder_frame);
+ if (helper) {
+ // PDF viewer and Print Preview only do this once per WebContents.
+ return absl::nullopt;
+ }
+
+ GURL original_url;
+ StreamInfo info;
+
+ content::WebContents* contents = navigation_handle.GetWebContents();
+ extensions::MimeHandlerViewGuest *guest =
+ extensions::MimeHandlerViewGuest::FromWebContents(contents);
+ if (guest) {
+ base::WeakPtr<extensions::StreamContainer> stream = guest->GetStreamWeakPtr();
+ if (!stream || stream->extension_id() != extension_misc::kPdfExtensionId ||
+ stream->stream_url() != navigation_handle.GetURL() ||
+ !stream->pdf_plugin_attributes()) {
+ return absl::nullopt;
+ }
+
+ original_url = stream->original_url();
+ info.background_color = base::checked_cast<SkColor>(stream->pdf_plugin_attributes()->background_color);
+ info.full_frame = !stream->embedded();
+ info.allow_javascript = stream->pdf_plugin_attributes()->allow_javascript;
+ } else {
+ return absl::nullopt;
+ }
+
+ static const base::NoDestructor<std::string> injected_script(
+ ui::ResourceBundle::GetSharedInstance().LoadDataResourceString(
+ IDR_PDF_PDF_INTERNAL_PLUGIN_WRAPPER_ROLLUP_JS));
+
+ info.stream_url = navigation_handle.GetURL();
+ info.original_url = original_url;
+ info.injected_script = injected_script.get();
+ StreamInfoHelper::CreateForCurrentDocument(embedder_frame, std::move(info));
+ return original_url;
+}
+
+absl::optional<pdf::PdfStreamDelegate::StreamInfo>
+PdfStreamDelegateQt::GetStreamInfo(content::RenderFrameHost* embedder_frame)
+{
+ if (!embedder_frame)
+ return absl::nullopt;
+
+ StreamInfoHelper *helper = StreamInfoHelper::GetForCurrentDocument(embedder_frame);
+ if (!helper)
+ return absl::nullopt;
+
+ // Only the call immediately following `MapToOriginalUrl()` requires a valid
+ // `StreamInfo`; subsequent calls should just get nothing.
+ return helper->TakeStreamInfo();
+}