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

Side by Side Diff: chrome/browser/ui/webui/print_preview/print_preview_distiller.cc

Issue 2108833002: Remove Simplify Page option from Print Preview (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Mark histogram entries as unused Created 4 years, 5 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 unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "chrome/browser/ui/webui/print_preview/print_preview_distiller.h"
6
7 #include <stdint.h>
8 #include <string>
9 #include <utility>
10
11 #include "base/command_line.h"
12 #include "base/feature_list.h"
13 #include "base/strings/utf_string_conversions.h"
14 #include "chrome/browser/chrome_notification_types.h"
15 #include "chrome/browser/dom_distiller/tab_utils.h"
16 #include "chrome/browser/printing/print_preview_dialog_controller.h"
17 #include "chrome/browser/printing/print_preview_message_handler.h"
18 #include "chrome/browser/profiles/profile.h"
19 #include "chrome/browser/ui/web_contents_sizer.h"
20 #include "chrome/common/chrome_switches.h"
21 #include "chrome/common/prerender_messages.h"
22 #include "components/dom_distiller/content/browser/distiller_javascript_utils.h"
23 #include "components/printing/common/print_messages.h"
24 #include "content/public/browser/navigation_details.h"
25 #include "content/public/browser/notification_service.h"
26 #include "content/public/browser/render_frame_host.h"
27 #include "content/public/browser/render_process_host.h"
28 #include "content/public/browser/render_view_host.h"
29 #include "content/public/browser/render_widget_host.h"
30 #include "content/public/browser/resource_request_details.h"
31 #include "content/public/browser/session_storage_namespace.h"
32 #include "content/public/browser/web_contents.h"
33 #include "content/public/browser/web_contents_delegate.h"
34 #include "content/public/browser/web_contents_observer.h"
35
36 using content::OpenURLParams;
37 using content::RenderViewHost;
38 using content::SessionStorageNamespace;
39 using content::WebContents;
40
41 class PrintPreviewDistiller::WebContentsDelegateImpl
42 : public content::WebContentsDelegate,
43 public content::NotificationObserver,
44 public content::WebContentsObserver {
45 public:
46 explicit WebContentsDelegateImpl(
47 WebContents* web_contents,
48 std::unique_ptr<base::DictionaryValue> settings,
49 const base::Closure on_failed_callback)
50 : content::WebContentsObserver(web_contents),
51 settings_(std::move(settings)),
52 on_failed_callback_(on_failed_callback) {
53 web_contents->SetDelegate(this);
54
55 // Close ourselves when the application is shutting down.
56 notification_registrar_.Add(this, chrome::NOTIFICATION_APP_TERMINATING,
57 content::NotificationService::AllSources());
58
59 // Register to inform new RenderViews that we're rendering.
60 notification_registrar_.Add(
61 this, content::NOTIFICATION_WEB_CONTENTS_RENDER_VIEW_HOST_CREATED,
62 content::Source<WebContents>(web_contents));
63 }
64
65 ~WebContentsDelegateImpl() override { web_contents()->SetDelegate(nullptr); }
66
67 // content::WebContentsDelegate implementation.
68 WebContents* OpenURLFromTab(WebContents* source,
69 const OpenURLParams& params) override {
70 on_failed_callback_.Run();
71 return nullptr;
72 }
73
74 void CloseContents(content::WebContents* contents) override {
75 on_failed_callback_.Run();
76 }
77
78 void CanDownload(const GURL& url,
79 const std::string& request_method,
80 const base::Callback<void(bool)>& callback) override {
81 on_failed_callback_.Run();
82 // Cancel the download.
83 callback.Run(false);
84 }
85
86 bool ShouldCreateWebContents(
87 WebContents* web_contents,
88 int32_t route_id,
89 int32_t main_frame_route_id,
90 int32_t main_frame_widget_route_id,
91 WindowContainerType window_container_type,
92 const std::string& frame_name,
93 const GURL& target_url,
94 const std::string& partition_id,
95 SessionStorageNamespace* session_storage_namespace) override {
96 // Since we don't want to permit child windows that would have a
97 // window.opener property, terminate rendering.
98 on_failed_callback_.Run();
99 // Cancel the popup.
100 return false;
101 }
102
103 bool OnGoToEntryOffset(int offset) override {
104 // This isn't allowed because the history merge operation
105 // does not work if there are renderer issued challenges.
106 // TODO(cbentzel): Cancel in this case? May not need to do
107 // since render-issued offset navigations are not guaranteed,
108 // but indicates that the page cares about the history.
109 return false;
110 }
111
112 bool ShouldSuppressDialogs(WebContents* source) override {
113 // We still want to show the user the message when they navigate to this
114 // page, so cancel this render.
115 on_failed_callback_.Run();
116 // Always suppress JavaScript messages if they're triggered by a page being
117 // rendered.
118 return true;
119 }
120
121 void RegisterProtocolHandler(WebContents* web_contents,
122 const std::string& protocol,
123 const GURL& url,
124 bool user_gesture) override {
125 on_failed_callback_.Run();
126 }
127
128 void RenderFrameCreated(
129 content::RenderFrameHost* render_frame_host) override {
130 // When a new RenderFrame is created for a distilled rendering
131 // WebContents, tell the new RenderFrame it's being used for
132 // prerendering before any navigations occur. Note that this is
133 // always triggered before the first navigation, so there's no
134 // need to send the message just after the WebContents is created.
135 render_frame_host->Send(new PrerenderMsg_SetIsPrerendering(
136 render_frame_host->GetRoutingID(), true));
137 }
138
139 void DidFinishLoad(content::RenderFrameHost* render_frame_host,
140 const GURL& validated_url) override {
141 // Notify distiller that print preview is using it.
142 dom_distiller::RunIsolatedJavaScript(
143 web_contents()->GetMainFrame(),
144 "var isPrintPreviewDistiller = true;");
145 }
146
147 void DoPrintPreview() {
148 RenderViewHost* rvh = web_contents()->GetRenderViewHost();
149 rvh->Send(new PrintMsg_InitiatePrintPreview(rvh->GetRoutingID(), false));
150 rvh->Send(new PrintMsg_PrintPreview(rvh->GetRoutingID(), *settings_));
151 }
152
153 void DidGetRedirectForResourceRequest(
154 content::RenderFrameHost* render_frame_host,
155 const content::ResourceRedirectDetails& details) override {
156 if (details.resource_type != content::RESOURCE_TYPE_MAIN_FRAME)
157 return;
158 // Redirects are unsupported for distilled content renderers.
159 on_failed_callback_.Run();
160 }
161
162 void RenderProcessGone(base::TerminationStatus status) override {
163 on_failed_callback_.Run();
164 }
165
166 void DidNavigateMainFrame(
167 const content::LoadCommittedDetails& details,
168 const content::FrameNavigateParams& params) override {
169 // Wait until we are done distilling the article and the target
170 // WebContents is ready for printing.
171 // The navigation to notify print preview that content is on the page will
172 // be an in-page navigation.
173 if (!details.is_in_page)
174 return;
175 // TODO(mvendra, wychen): resources (images, web fonts) are not necessarily
176 // ready at this point - so deferring the call to
177 // DoPrintPreview could be warranted
178 DoPrintPreview();
179 }
180
181 void Observe(int type,
182 const content::NotificationSource& source,
183 const content::NotificationDetails& details) override {
184 switch (type) {
185 // TODO(davidben): Try to remove this in favor of relying on
186 // FINAL_STATUS_PROFILE_DESTROYED.
187 case chrome::NOTIFICATION_APP_TERMINATING:
188 on_failed_callback_.Run();
189 return;
190
191 case content::NOTIFICATION_WEB_CONTENTS_RENDER_VIEW_HOST_CREATED: {
192 if (web_contents()) {
193 DCHECK_EQ(content::Source<WebContents>(source).ptr(), web_contents());
194
195 // Make sure the size of the RenderViewHost has been passed to the new
196 // RenderView. Otherwise, the size may not be sent until the
197 // RenderViewReady event makes it from the render process to the UI
198 // thread of the browser process. When the RenderView receives its
199 // size, is also sets itself to be visible, which would then break the
200 // visibility API.
201 content::Details<RenderViewHost> new_render_view_host(details);
202 new_render_view_host->GetWidget()->WasResized();
203 web_contents()->WasHidden();
204 }
205 break;
206 }
207
208 default:
209 NOTREACHED() << "Unexpected notification sent.";
210 break;
211 }
212 }
213
214 private:
215 std::unique_ptr<base::DictionaryValue> settings_;
216 content::NotificationRegistrar notification_registrar_;
217
218 // The callback called when the preview failed.
219 base::Closure on_failed_callback_;
220 };
221
222 const base::Feature PrintPreviewDistiller::kFeature = {
223 "PrintPreviewDistiller", base::FEATURE_ENABLED_BY_DEFAULT,
224 };
225
226 bool PrintPreviewDistiller::IsEnabled() {
227 return base::FeatureList::IsEnabled(kFeature);
228 }
229
230 PrintPreviewDistiller::PrintPreviewDistiller(
231 WebContents* source_web_contents,
232 const base::Closure on_failed_callback,
233 std::unique_ptr<base::DictionaryValue> settings) {
234 content::SessionStorageNamespace* session_storage_namespace =
235 source_web_contents->GetController().GetDefaultSessionStorageNamespace();
236 CreateDestinationWebContents(session_storage_namespace, source_web_contents,
237 std::move(settings), on_failed_callback);
238
239 DCHECK(web_contents_);
240 ::DistillAndView(source_web_contents, web_contents_.get());
241 }
242
243 void PrintPreviewDistiller::CreateDestinationWebContents(
244 SessionStorageNamespace* session_storage_namespace,
245 WebContents* source_web_contents,
246 std::unique_ptr<base::DictionaryValue> settings,
247 const base::Closure on_failed_callback) {
248 DCHECK(!web_contents_);
249
250 web_contents_.reset(
251 CreateWebContents(session_storage_namespace, source_web_contents));
252
253 printing::PrintPreviewMessageHandler::CreateForWebContents(
254 web_contents_.get());
255
256 web_contents_delegate_.reset(new WebContentsDelegateImpl(
257 web_contents_.get(), std::move(settings), on_failed_callback));
258
259 // Set the size of the distilled WebContents.
260 ResizeWebContents(web_contents_.get(), gfx::Size(1, 1));
261
262 printing::PrintPreviewDialogController* dialog_controller =
263 printing::PrintPreviewDialogController::GetInstance();
264 if (!dialog_controller)
265 return;
266
267 dialog_controller->AddProxyDialogForWebContents(web_contents_.get(),
268 source_web_contents);
269 }
270
271 PrintPreviewDistiller::~PrintPreviewDistiller() {
272 DCHECK(web_contents_);
273
274 printing::PrintPreviewDialogController* dialog_controller =
275 printing::PrintPreviewDialogController::GetInstance();
276 if (!dialog_controller)
277 return;
278
279 dialog_controller->RemoveProxyDialogForWebContents(web_contents_.get());
280 }
281
282 WebContents* PrintPreviewDistiller::CreateWebContents(
283 SessionStorageNamespace* session_storage_namespace,
284 WebContents* source_web_contents) {
285 // TODO(ajwong): Remove the temporary map once prerendering is aware of
286 // multiple session storage namespaces per tab.
287 content::SessionStorageNamespaceMap session_storage_namespace_map;
288 Profile* profile =
289 Profile::FromBrowserContext(source_web_contents->GetBrowserContext());
290 session_storage_namespace_map[std::string()] = session_storage_namespace;
291 return WebContents::CreateWithSessionStorage(
292 WebContents::CreateParams(profile), session_storage_namespace_map);
293 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698