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

Side by Side 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, 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 (c) 2015 The Chromium Authors. All rights reserved.
Vitaly Buka (NO REVIEWS) 2015/07/13 07:00:31 we use "// Copyright 2015" now
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/hidden_print_preview.h"
6
7 #include <string>
8
9 #include "base/strings/utf_string_conversions.h"
10 #include "chrome/browser/chrome_notification_types.h"
11 #include "chrome/browser/dom_distiller/tab_utils.h"
12 #include "chrome/browser/printing/print_preview_dialog_controller.h"
13 #include "chrome/browser/printing/print_preview_message_handler.h"
14 #include "chrome/browser/profiles/profile.h"
15 #include "chrome/browser/ui/tab_helpers.h"
16 #include "chrome/browser/ui/web_contents_sizer.h"
17 #include "chrome/browser/ui/webui/print_preview/print_preview_ui.h"
18 #include "chrome/common/prerender_messages.h"
19 #include "components/printing/common/print_messages.h"
20 #include "content/public/browser/browser_thread.h"
21 #include "content/public/browser/notification_service.h"
22 #include "content/public/browser/render_frame_host.h"
23 #include "content/public/browser/render_process_host.h"
24 #include "content/public/browser/render_view_host.h"
25 #include "content/public/browser/session_storage_namespace.h"
26 #include "content/public/browser/web_contents.h"
27 #include "content/public/browser/web_contents_delegate.h"
28
29 using content::BrowserThread;
30 using content::OpenURLParams;
31 using content::RenderViewHost;
32 using content::SessionStorageNamespace;
33 using content::WebContents;
34
35 class HiddenPrintPreview::WebContentsDelegateImpl
36 : public content::WebContentsDelegate {
37 public:
38 explicit WebContentsDelegateImpl(HiddenPrintPreview* hidden_print_preview)
39 : hidden_print_preview_(hidden_print_preview) {
40 }
41
42 // content::WebContentsDelegate implementation:
43 WebContents* OpenURLFromTab(WebContents* source,
44 const OpenURLParams& params) override {
45 // |OpenURLFromTab| is typically called when a frame performs a navigation
46 // that requires the browser to perform the transition instead of WebKit.
47 // 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
48 // or if --enable-strict-site-isolation is specified and the rendered
49 // frame redirects to a different origin.
50 hidden_print_preview_->Destroy();
51 return NULL;
Vitaly Buka (NO REVIEWS) 2015/07/13 07:00:31 nullptr
52 }
53
54 void CloseContents(content::WebContents* contents) override {
55 hidden_print_preview_->Destroy();
56 }
57
58 void CanDownload(const GURL& url,
59 const std::string& request_method,
60 const base::Callback<void(bool)>& callback) override {
61 hidden_print_preview_->Destroy();
62 // Cancel the download.
63 callback.Run(false);
64 }
65
66 bool ShouldCreateWebContents(
67 WebContents* web_contents,
68 int route_id,
69 int main_frame_route_id,
70 WindowContainerType window_container_type,
71 const base::string16& frame_name,
72 const GURL& target_url,
73 const std::string& partition_id,
74 SessionStorageNamespace* session_storage_namespace) override {
75 // Since we don't want to permit child windows that would have a
76 // window.opener property, terminate rendering.
77 hidden_print_preview_->Destroy();
78 // Cancel the popup.
79 return false;
80 }
81
82 bool OnGoToEntryOffset(int offset) override {
83 // This isn't allowed because the history merge operation
84 // does not work if there are renderer issued challenges.
85 // TODO(cbentzel): Cancel in this case? May not need to do
86 // since render-issued offset navigations are not guaranteed,
87 // but indicates that the page cares about the history.
88 return false;
89 }
90
91 bool ShouldSuppressDialogs(WebContents* source) override {
92 // We still want to show the user the message when they navigate to this
93 // page, so cancel this render.
94 hidden_print_preview_->Destroy();
95 // Always suppress JavaScript messages if they're triggered by a page being
96 // rendered.
97 return true;
98 }
99
100 void RegisterProtocolHandler(WebContents* web_contents,
101 const std::string& protocol,
102 const GURL& url,
103 bool user_gesture) override {
104 hidden_print_preview_->Destroy();
105 }
106
107 gfx::Size GetSizeForNewRenderView(WebContents* web_contents) const override {
108 // Have to set the size of the RenderView on initialization to be sure it is
109 // set before the RenderView is hidden on all platforms (esp. Android).
110 return hidden_print_preview_->size_;
111 }
112
113 private:
114 HiddenPrintPreview* hidden_print_preview_;
115 };
116
117 HiddenPrintPreview::HiddenPrintPreview(
118 WebContents* target_web_contents,
119 PrintPreviewUI* print_preview_ui,
120 scoped_ptr<base::DictionaryValue> settings)
121 : session_storage_namespace_id_(-1),
Vitaly Buka (NO REVIEWS) 2015/07/13 07:00:31 session_storage_namespace_id_ is not used
122 profile_(Profile::FromBrowserContext(
Vitaly Buka (NO REVIEWS) 2015/07/13 07:00:30 don't need profile_ member, you can call FromBrows
123 target_web_contents->GetBrowserContext())),
124 target_web_contents_(target_web_contents),
Vitaly Buka (NO REVIEWS) 2015/07/13 07:00:31 target_web_contents -> source_web_contents
125 settings_(settings.release()),
126 print_preview_ui_(print_preview_ui) {
127 content::SessionStorageNamespace* session_storage_namespace =
128 target_web_contents_->GetController().GetDefaultSessionStorageNamespace();
129 StartRendering(gfx::Size(1, 1), session_storage_namespace);
130
131 DCHECK(web_contents_);
132 ::DistillAndView(target_web_contents_, web_contents_.get());
133 }
134
135 void HiddenPrintPreview::StartRendering(
Vitaly Buka (NO REVIEWS) 2015/07/13 07:00:30 StartRendering starts nothing. Probably should be
136 const gfx::Size& size,
137 SessionStorageNamespace* session_storage_namespace) {
138 DCHECK(profile_ != NULL);
139 DCHECK(!size.IsEmpty());
140 DCHECK(web_contents_.get() == NULL);
141 DCHECK(size_.IsEmpty());
142
143 session_storage_namespace_id_ = session_storage_namespace->id();
144 size_ = size;
145
146 web_contents_.reset(CreateWebContents(session_storage_namespace));
147 TabHelpers::AttachTabHelpers(web_contents_.get());
148 content::WebContentsObserver::Observe(web_contents_.get());
149
150 web_contents_delegate_.reset(new WebContentsDelegateImpl(this));
151 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/
152
153 // Set the size of the hidden WebContents.
154 ResizeWebContents(web_contents_.get(), size_);
155
156 // Close ourselves when the application is shutting down.
157 notification_registrar_.Add(this, chrome::NOTIFICATION_APP_TERMINATING,
158 content::NotificationService::AllSources());
159
160 // Register to inform new RenderViews that we're rendering.
161 notification_registrar_.Add(
162 this, content::NOTIFICATION_WEB_CONTENTS_RENDER_VIEW_HOST_CREATED,
163 content::Source<WebContents>(web_contents_.get()));
164 }
165
166 HiddenPrintPreview::~HiddenPrintPreview() {
167 if (web_contents_.get()) {
Vitaly Buka (NO REVIEWS) 2015/07/13 07:00:30 just "if (web_contents_)" and everywhere else
168 web_contents_->SetDelegate(NULL);
169 content::WebContentsObserver::Observe(NULL);
Vitaly Buka (NO REVIEWS) 2015/07/13 07:00:30 Probably WebContentsDelegateImpl should be a WebCo
170
171 printing::PrintPreviewDialogController* dialog_controller =
172 printing::PrintPreviewDialogController::GetInstance();
173 if (!dialog_controller)
174 return;
175
176 dialog_controller->RemoveProxyDialogForWebContents(web_contents_.get());
177 }
178 }
179
180 void HiddenPrintPreview::Observe(int type,
181 const content::NotificationSource& source,
182 const content::NotificationDetails& details) {
183 switch (type) {
184 // TODO(davidben): Try to remove this in favor of relying on
185 // FINAL_STATUS_PROFILE_DESTROYED.
186 case chrome::NOTIFICATION_APP_TERMINATING:
187 Destroy();
188 return;
189
190 case content::NOTIFICATION_WEB_CONTENTS_RENDER_VIEW_HOST_CREATED: {
191 if (web_contents_.get()) {
192 DCHECK_EQ(content::Source<WebContents>(source).ptr(),
193 web_contents_.get());
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->WasResized();
203 web_contents_->WasHidden();
204 }
205 break;
206 }
207
208 default:
209 NOTREACHED() << "Unexpected notification sent.";
210 break;
211 }
212 }
213
214 WebContents* HiddenPrintPreview::CreateWebContents(
215 SessionStorageNamespace* session_storage_namespace) {
216 // TODO(ajwong): Remove the temporary map once prerendering is aware of
217 // multiple session storage namespaces per tab.
218 content::SessionStorageNamespaceMap session_storage_namespace_map;
219 session_storage_namespace_map[std::string()] = session_storage_namespace;
220 return WebContents::CreateWithSessionStorage(
221 WebContents::CreateParams(profile_), session_storage_namespace_map);
222 }
223
224 void HiddenPrintPreview::RenderProcessGone(base::TerminationStatus status) {
225 Destroy();
226 }
227
228 void HiddenPrintPreview::RenderFrameCreated(
229 content::RenderFrameHost* render_frame_host) {
230 // When a new RenderFrame is created for a hidden rendering WebContents, tell
231 // the new RenderFrame it's being used for prerendering before any
232 // navigations occur. Note that this is always triggered before the first
233 // navigation, so there's no need to send the message just after the
234 // WebContents is created.
235 render_frame_host->Send(new PrerenderMsg_SetIsPrerendering(
236 render_frame_host->GetRoutingID(), true));
237 }
238
239 void HiddenPrintPreview::DidStopLoading() {
Vitaly Buka (NO REVIEWS) 2015/07/13 07:00:30 Please remove these three. base class already has
240 }
241
242 void HiddenPrintPreview::DocumentLoadedInFrame(
243 content::RenderFrameHost* render_frame_host) {
244 }
245
246 void HiddenPrintPreview::DidStartProvisionalLoadForFrame(
247 content::RenderFrameHost* render_frame_host,
248 const GURL& validated_url,
249 bool is_error_page,
250 bool is_iframe_srcdoc) {
251 }
252
253 void HiddenPrintPreview::DidFinishLoad(
254 content::RenderFrameHost* render_frame_host,
255 const GURL& validated_url) {
256 // Ask the page to trigger an anchor navigation once the distilled
257 // contents are added to the page.
258 web_contents()->GetMainFrame()->ExecuteJavaScript(
259 base::UTF8ToUTF16("setNavigateOnInitialContentLoad(true);"));
260 }
261
262 void HiddenPrintPreview::DidNavigateMainFrame(
263 const content::LoadCommittedDetails& details,
264 const content::FrameNavigateParams& params) {
265 // The second content loads signals that the distilled contents have
266 // been delivered to the page via inline JavaScript execution.
267 if (web_contents_->GetController().GetEntryCount() > 1) {
268 DCHECK(web_contents_);
269
270 printing::PrintPreviewDialogController* dialog_controller =
271 printing::PrintPreviewDialogController::GetInstance();
272 if (!dialog_controller) {
273 return;
274 }
275 dialog_controller->AddProxyDialogForWebContents(
Vitaly Buka (NO REVIEWS) 2015/07/13 07:00:30 why Add here and not when contents created?
276 web_contents_.get(), target_web_contents_);
277
278 DCHECK(settings_);
279 RenderViewHost* rvh = web_contents_->GetRenderViewHost();
280 rvh->Send(new PrintMsg_InitiatePrintPreview(rvh->GetRoutingID(), false));
281 rvh->Send(new PrintMsg_PrintPreview(rvh->GetRoutingID(), *settings_));
282 }
283 }
284
285 void HiddenPrintPreview::DidGetRedirectForResourceRequest(
286 content::RenderFrameHost* render_frame_host,
287 const content::ResourceRedirectDetails& details) {
288 // Redirects are unsupported for hidden renderers.
289 Destroy();
290 }
291
292 void HiddenPrintPreview::Destroy() {
Vitaly Buka (NO REVIEWS) 2015/07/13 07:00:30 Destroy -> Fail or Abort
293 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
294 return;
295
296 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
297 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698