Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1842)

Unified Diff: chrome/browser/ui/webui/print_preview/hidden_print_preview.cc

Issue 1125343004: Add a "Simplify Page" option to the print preview dialog (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Simplify version of the HiddenPrintPreview and solved issues pointed out by the last review Created 5 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/browser/ui/webui/print_preview/hidden_print_preview.cc
diff --git a/chrome/browser/ui/webui/print_preview/hidden_print_preview.cc b/chrome/browser/ui/webui/print_preview/hidden_print_preview.cc
new file mode 100644
index 0000000000000000000000000000000000000000..176f22bc971802ac450f86bc0977f360ea3d9827
--- /dev/null
+++ b/chrome/browser/ui/webui/print_preview/hidden_print_preview.cc
@@ -0,0 +1,297 @@
+// Copyright (c) 2015 The Chromium Authors. All rights reserved.
Vitaly Buka (NO REVIEWS) 2015/07/13 07:00:31 we use "// Copyright 2015" now
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/ui/webui/print_preview/hidden_print_preview.h"
+
+#include <string>
+
+#include "base/strings/utf_string_conversions.h"
+#include "chrome/browser/chrome_notification_types.h"
+#include "chrome/browser/dom_distiller/tab_utils.h"
+#include "chrome/browser/printing/print_preview_dialog_controller.h"
+#include "chrome/browser/printing/print_preview_message_handler.h"
+#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/ui/tab_helpers.h"
+#include "chrome/browser/ui/web_contents_sizer.h"
+#include "chrome/browser/ui/webui/print_preview/print_preview_ui.h"
+#include "chrome/common/prerender_messages.h"
+#include "components/printing/common/print_messages.h"
+#include "content/public/browser/browser_thread.h"
+#include "content/public/browser/notification_service.h"
+#include "content/public/browser/render_frame_host.h"
+#include "content/public/browser/render_process_host.h"
+#include "content/public/browser/render_view_host.h"
+#include "content/public/browser/session_storage_namespace.h"
+#include "content/public/browser/web_contents.h"
+#include "content/public/browser/web_contents_delegate.h"
+
+using content::BrowserThread;
+using content::OpenURLParams;
+using content::RenderViewHost;
+using content::SessionStorageNamespace;
+using content::WebContents;
+
+class HiddenPrintPreview::WebContentsDelegateImpl
+ : public content::WebContentsDelegate {
+ public:
+ explicit WebContentsDelegateImpl(HiddenPrintPreview* hidden_print_preview)
+ : hidden_print_preview_(hidden_print_preview) {
+ }
+
+ // content::WebContentsDelegate implementation:
+ WebContents* OpenURLFromTab(WebContents* source,
+ const OpenURLParams& params) override {
+ // |OpenURLFromTab| is typically called when a frame performs a navigation
+ // that requires the browser to perform the transition instead of WebKit.
+ // Examples include rendering a site that redirects to an app URL,
Vitaly Buka (NO REVIEWS) 2015/07/13 07:00:30 I am no sure how distilled web content works is na
+ // or if --enable-strict-site-isolation is specified and the rendered
+ // frame redirects to a different origin.
+ hidden_print_preview_->Destroy();
+ return NULL;
Vitaly Buka (NO REVIEWS) 2015/07/13 07:00:31 nullptr
+ }
+
+ void CloseContents(content::WebContents* contents) override {
+ hidden_print_preview_->Destroy();
+ }
+
+ void CanDownload(const GURL& url,
+ const std::string& request_method,
+ const base::Callback<void(bool)>& callback) override {
+ hidden_print_preview_->Destroy();
+ // Cancel the download.
+ callback.Run(false);
+ }
+
+ bool ShouldCreateWebContents(
+ WebContents* web_contents,
+ int route_id,
+ int main_frame_route_id,
+ WindowContainerType window_container_type,
+ const base::string16& frame_name,
+ const GURL& target_url,
+ const std::string& partition_id,
+ SessionStorageNamespace* session_storage_namespace) override {
+ // Since we don't want to permit child windows that would have a
+ // window.opener property, terminate rendering.
+ hidden_print_preview_->Destroy();
+ // Cancel the popup.
+ return false;
+ }
+
+ bool OnGoToEntryOffset(int offset) override {
+ // This isn't allowed because the history merge operation
+ // does not work if there are renderer issued challenges.
+ // TODO(cbentzel): Cancel in this case? May not need to do
+ // since render-issued offset navigations are not guaranteed,
+ // but indicates that the page cares about the history.
+ return false;
+ }
+
+ bool ShouldSuppressDialogs(WebContents* source) override {
+ // We still want to show the user the message when they navigate to this
+ // page, so cancel this render.
+ hidden_print_preview_->Destroy();
+ // Always suppress JavaScript messages if they're triggered by a page being
+ // rendered.
+ return true;
+ }
+
+ void RegisterProtocolHandler(WebContents* web_contents,
+ const std::string& protocol,
+ const GURL& url,
+ bool user_gesture) override {
+ hidden_print_preview_->Destroy();
+ }
+
+ gfx::Size GetSizeForNewRenderView(WebContents* web_contents) const override {
+ // Have to set the size of the RenderView on initialization to be sure it is
+ // set before the RenderView is hidden on all platforms (esp. Android).
+ return hidden_print_preview_->size_;
+ }
+
+ private:
+ HiddenPrintPreview* hidden_print_preview_;
+};
+
+HiddenPrintPreview::HiddenPrintPreview(
+ WebContents* target_web_contents,
+ PrintPreviewUI* print_preview_ui,
+ scoped_ptr<base::DictionaryValue> settings)
+ : session_storage_namespace_id_(-1),
Vitaly Buka (NO REVIEWS) 2015/07/13 07:00:31 session_storage_namespace_id_ is not used
+ profile_(Profile::FromBrowserContext(
Vitaly Buka (NO REVIEWS) 2015/07/13 07:00:30 don't need profile_ member, you can call FromBrows
+ target_web_contents->GetBrowserContext())),
+ target_web_contents_(target_web_contents),
Vitaly Buka (NO REVIEWS) 2015/07/13 07:00:31 target_web_contents -> source_web_contents
+ settings_(settings.release()),
+ print_preview_ui_(print_preview_ui) {
+ content::SessionStorageNamespace* session_storage_namespace =
+ target_web_contents_->GetController().GetDefaultSessionStorageNamespace();
+ StartRendering(gfx::Size(1, 1), session_storage_namespace);
+
+ DCHECK(web_contents_);
+ ::DistillAndView(target_web_contents_, web_contents_.get());
+}
+
+void HiddenPrintPreview::StartRendering(
Vitaly Buka (NO REVIEWS) 2015/07/13 07:00:30 StartRendering starts nothing. Probably should be
+ const gfx::Size& size,
+ SessionStorageNamespace* session_storage_namespace) {
+ DCHECK(profile_ != NULL);
+ DCHECK(!size.IsEmpty());
+ DCHECK(web_contents_.get() == NULL);
+ DCHECK(size_.IsEmpty());
+
+ session_storage_namespace_id_ = session_storage_namespace->id();
+ size_ = size;
+
+ web_contents_.reset(CreateWebContents(session_storage_namespace));
+ TabHelpers::AttachTabHelpers(web_contents_.get());
+ content::WebContentsObserver::Observe(web_contents_.get());
+
+ web_contents_delegate_.reset(new WebContentsDelegateImpl(this));
+ web_contents_.get()->SetDelegate(web_contents_delegate_.get());
Vitaly Buka (NO REVIEWS) 2015/07/13 07:00:31 maybe better to set/remove delgate in constructor/
+
+ // Set the size of the hidden WebContents.
+ ResizeWebContents(web_contents_.get(), size_);
+
+ // Close ourselves when the application is shutting down.
+ notification_registrar_.Add(this, chrome::NOTIFICATION_APP_TERMINATING,
+ content::NotificationService::AllSources());
+
+ // Register to inform new RenderViews that we're rendering.
+ notification_registrar_.Add(
+ this, content::NOTIFICATION_WEB_CONTENTS_RENDER_VIEW_HOST_CREATED,
+ content::Source<WebContents>(web_contents_.get()));
+}
+
+HiddenPrintPreview::~HiddenPrintPreview() {
+ if (web_contents_.get()) {
Vitaly Buka (NO REVIEWS) 2015/07/13 07:00:30 just "if (web_contents_)" and everywhere else
+ web_contents_->SetDelegate(NULL);
+ content::WebContentsObserver::Observe(NULL);
Vitaly Buka (NO REVIEWS) 2015/07/13 07:00:30 Probably WebContentsDelegateImpl should be a WebCo
+
+ printing::PrintPreviewDialogController* dialog_controller =
+ printing::PrintPreviewDialogController::GetInstance();
+ if (!dialog_controller)
+ return;
+
+ dialog_controller->RemoveProxyDialogForWebContents(web_contents_.get());
+ }
+}
+
+void HiddenPrintPreview::Observe(int type,
+ const content::NotificationSource& source,
+ const content::NotificationDetails& details) {
+ switch (type) {
+ // TODO(davidben): Try to remove this in favor of relying on
+ // FINAL_STATUS_PROFILE_DESTROYED.
+ case chrome::NOTIFICATION_APP_TERMINATING:
+ Destroy();
+ return;
+
+ case content::NOTIFICATION_WEB_CONTENTS_RENDER_VIEW_HOST_CREATED: {
+ if (web_contents_.get()) {
+ DCHECK_EQ(content::Source<WebContents>(source).ptr(),
+ web_contents_.get());
+
+ // Make sure the size of the RenderViewHost has been passed to the new
+ // RenderView. Otherwise, the size may not be sent until the
+ // RenderViewReady event makes it from the render process to the UI
+ // thread of the browser process. When the RenderView receives its
+ // size, is also sets itself to be visible, which would then break the
+ // visibility API.
+ content::Details<RenderViewHost> new_render_view_host(details);
+ new_render_view_host->WasResized();
+ web_contents_->WasHidden();
+ }
+ break;
+ }
+
+ default:
+ NOTREACHED() << "Unexpected notification sent.";
+ break;
+ }
+}
+
+WebContents* HiddenPrintPreview::CreateWebContents(
+ SessionStorageNamespace* session_storage_namespace) {
+ // TODO(ajwong): Remove the temporary map once prerendering is aware of
+ // multiple session storage namespaces per tab.
+ content::SessionStorageNamespaceMap session_storage_namespace_map;
+ session_storage_namespace_map[std::string()] = session_storage_namespace;
+ return WebContents::CreateWithSessionStorage(
+ WebContents::CreateParams(profile_), session_storage_namespace_map);
+}
+
+void HiddenPrintPreview::RenderProcessGone(base::TerminationStatus status) {
+ Destroy();
+}
+
+void HiddenPrintPreview::RenderFrameCreated(
+ content::RenderFrameHost* render_frame_host) {
+ // When a new RenderFrame is created for a hidden rendering WebContents, tell
+ // the new RenderFrame it's being used for prerendering before any
+ // navigations occur. Note that this is always triggered before the first
+ // navigation, so there's no need to send the message just after the
+ // WebContents is created.
+ render_frame_host->Send(new PrerenderMsg_SetIsPrerendering(
+ render_frame_host->GetRoutingID(), true));
+}
+
+void HiddenPrintPreview::DidStopLoading() {
Vitaly Buka (NO REVIEWS) 2015/07/13 07:00:30 Please remove these three. base class already has
+}
+
+void HiddenPrintPreview::DocumentLoadedInFrame(
+ content::RenderFrameHost* render_frame_host) {
+}
+
+void HiddenPrintPreview::DidStartProvisionalLoadForFrame(
+ content::RenderFrameHost* render_frame_host,
+ const GURL& validated_url,
+ bool is_error_page,
+ bool is_iframe_srcdoc) {
+}
+
+void HiddenPrintPreview::DidFinishLoad(
+ content::RenderFrameHost* render_frame_host,
+ const GURL& validated_url) {
+ // Ask the page to trigger an anchor navigation once the distilled
+ // contents are added to the page.
+ web_contents()->GetMainFrame()->ExecuteJavaScript(
+ base::UTF8ToUTF16("setNavigateOnInitialContentLoad(true);"));
+}
+
+void HiddenPrintPreview::DidNavigateMainFrame(
+ const content::LoadCommittedDetails& details,
+ const content::FrameNavigateParams& params) {
+ // The second content loads signals that the distilled contents have
+ // been delivered to the page via inline JavaScript execution.
+ if (web_contents_->GetController().GetEntryCount() > 1) {
+ DCHECK(web_contents_);
+
+ printing::PrintPreviewDialogController* dialog_controller =
+ printing::PrintPreviewDialogController::GetInstance();
+ if (!dialog_controller) {
+ return;
+ }
+ dialog_controller->AddProxyDialogForWebContents(
Vitaly Buka (NO REVIEWS) 2015/07/13 07:00:30 why Add here and not when contents created?
+ web_contents_.get(), target_web_contents_);
+
+ DCHECK(settings_);
+ RenderViewHost* rvh = web_contents_->GetRenderViewHost();
+ rvh->Send(new PrintMsg_InitiatePrintPreview(rvh->GetRoutingID(), false));
+ rvh->Send(new PrintMsg_PrintPreview(rvh->GetRoutingID(), *settings_));
+ }
+}
+
+void HiddenPrintPreview::DidGetRedirectForResourceRequest(
+ content::RenderFrameHost* render_frame_host,
+ const content::ResourceRedirectDetails& details) {
+ // Redirects are unsupported for hidden renderers.
+ Destroy();
+}
+
+void HiddenPrintPreview::Destroy() {
Vitaly Buka (NO REVIEWS) 2015/07/13 07:00:30 Destroy -> Fail or Abort
+ if (rendering_has_been_cancelled_)
Vitaly Buka (NO REVIEWS) 2015/07/13 07:00:30 I don't see who change rendering_has_been_cancelle
+ return;
+
+ print_preview_ui_->OnPrintPreviewFailed();
Vitaly Buka (NO REVIEWS) 2015/07/13 07:00:30 I don't see other use of print_preview_ui_ here Ca
+}

Powered by Google App Engine
This is Rietveld 408576698