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

Side by Side Diff: chrome/browser/ui/webui/print_preview/print_preview_distiller.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: Refactoring following the proposals in the reviews 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 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 <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 PrintPreviewDistiller::WebContentsDelegateImpl
36 : public content::WebContentsDelegate,
37 public content::NotificationObserver,
38 public content::WebContentsObserver {
39 public:
40 explicit WebContentsDelegateImpl(
41 PrintPreviewDistiller* print_preview_distiller,
42 scoped_ptr<base::DictionaryValue> settings)
43 : print_preview_distiller_(print_preview_distiller),
44 settings_(settings.release()) {
Vitaly Buka (NO REVIEWS) 2015/07/20 20:45:33 settings.Pass()
arjunpatel 2015/07/21 17:25:00 Acknowledged.
45 print_preview_distiller_->GetWebContents()->SetDelegate(this);
Vitaly Buka (NO REVIEWS) 2015/07/20 20:45:32 base class has web_contents() getter please use we
arjunpatel 2015/07/21 17:25:00 Acknowledged.
46
47 content::WebContentsObserver::Observe(
Vitaly Buka (NO REVIEWS) 2015/07/20 20:45:33 Please use fallowing constructor instead of conten
arjunpatel 2015/07/21 17:25:00 Acknowledged.
48 print_preview_distiller_->GetWebContents());
49
50 // Close ourselves when the application is shutting down.
51 notification_registrar_.Add(this, chrome::NOTIFICATION_APP_TERMINATING,
52 content::NotificationService::AllSources());
53
54 // Register to inform new RenderViews that we're rendering.
55 notification_registrar_.Add(
56 this, content::NOTIFICATION_WEB_CONTENTS_RENDER_VIEW_HOST_CREATED,
57 content::Source<WebContents>(
58 print_preview_distiller_->GetWebContents()));
59 }
60
61 ~WebContentsDelegateImpl() {
62 print_preview_distiller_->GetWebContents()->SetDelegate(NULL);
63 content::WebContentsObserver::Observe(NULL);
64 }
65
66 // content::WebContentsDelegate implementation.
67 WebContents* OpenURLFromTab(WebContents* source,
68 const OpenURLParams& params) override {
69 print_preview_distiller_->Abort();
70 return nullptr;
71 }
72
73 void CloseContents(content::WebContents* contents) override {
74 print_preview_distiller_->Abort();
75 }
76
77 void CanDownload(const GURL& url,
78 const std::string& request_method,
79 const base::Callback<void(bool)>& callback) override {
80 print_preview_distiller_->Abort();
81 // Cancel the download.
82 callback.Run(false);
83 }
84
85 bool ShouldCreateWebContents(
86 WebContents* web_contents,
87 int route_id,
88 int main_frame_route_id,
89 WindowContainerType window_container_type,
90 const base::string16& frame_name,
91 const GURL& target_url,
92 const std::string& partition_id,
93 SessionStorageNamespace* session_storage_namespace) override {
94 // Since we don't want to permit child windows that would have a
95 // window.opener property, terminate rendering.
96 print_preview_distiller_->Abort();
97 // Cancel the popup.
98 return false;
99 }
100
101 bool OnGoToEntryOffset(int offset) override {
102 // This isn't allowed because the history merge operation
103 // does not work if there are renderer issued challenges.
104 // TODO(cbentzel): Cancel in this case? May not need to do
105 // since render-issued offset navigations are not guaranteed,
106 // but indicates that the page cares about the history.
107 return false;
108 }
109
110 bool ShouldSuppressDialogs(WebContents* source) override {
111 // We still want to show the user the message when they navigate to this
112 // page, so cancel this render.
113 print_preview_distiller_->Abort();
114 // Always suppress JavaScript messages if they're triggered by a page being
115 // rendered.
116 return true;
117 }
118
119 void RegisterProtocolHandler(WebContents* web_contents,
120 const std::string& protocol,
121 const GURL& url,
122 bool user_gesture) override {
123 print_preview_distiller_->Abort();
124 }
125
126 void RenderFrameCreated(content::RenderFrameHost* render_frame_host) {
127 // When a new RenderFrame is created for a distilled rendering
128 // WebContents, tell the new RenderFrame it's being used for
129 // prerendering before any navigations occur. Note that this is
130 // always triggered before the first navigation, so there's no
131 // need to send the message just after the WebContents is created.
132 render_frame_host->Send(new PrerenderMsg_SetIsPrerendering(
133 render_frame_host->GetRoutingID(), true));
134 }
135
136 void DidFinishLoad(content::RenderFrameHost* render_frame_host,
137 const GURL& validated_url) {
138 // Ask the page to trigger an anchor navigation once the distilled
139 // contents are added to the page.
140 web_contents()->GetMainFrame()->ExecuteJavaScript(
141 base::UTF8ToUTF16("setNavigateOnInitialContentLoad(true);"));
142 }
143
144 void DidNavigateMainFrame(const content::LoadCommittedDetails& details,
145 const content::FrameNavigateParams& params) {
146 // The second content loads signals that the distilled contents have
147 // been delivered to the page via inline JavaScript execution.
148 DCHECK(print_preview_distiller_->GetWebContents());
Vitaly Buka (NO REVIEWS) 2015/07/20 20:45:33 DCHECK(print_preview_distiller_->GetWebContents())
arjunpatel 2015/07/21 17:25:00 Acknowledged.
149 if (print_preview_distiller_->GetWebContents()
150 ->GetController()
151 .GetEntryCount() > 1) {
152 DCHECK(settings_);
Vitaly Buka (NO REVIEWS) 2015/07/20 20:45:33 same here
arjunpatel 2015/07/21 17:25:00 Acknowledged.
153 RenderViewHost* rvh =
154 print_preview_distiller_->GetWebContents()->GetRenderViewHost();
155 rvh->Send(new PrintMsg_InitiatePrintPreview(rvh->GetRoutingID(), false));
156 rvh->Send(new PrintMsg_PrintPreview(rvh->GetRoutingID(), *settings_));
157 }
158 }
159
160 void DidGetRedirectForResourceRequest(
161 content::RenderFrameHost* render_frame_host,
162 const content::ResourceRedirectDetails& details) {
163 // Redirects are unsupported for distilled content renderers.
164 print_preview_distiller_->Abort();
165 }
166
167 void RenderProcessGone(base::TerminationStatus status) {
168 print_preview_distiller_->Abort();
169 }
170
171 void Observe(int type,
172 const content::NotificationSource& source,
173 const content::NotificationDetails& details) {
174 switch (type) {
175 // TODO(davidben): Try to remove this in favor of relying on
176 // FINAL_STATUS_PROFILE_DESTROYED.
177 case chrome::NOTIFICATION_APP_TERMINATING:
178 print_preview_distiller_->Abort();
179 return;
180
181 case content::NOTIFICATION_WEB_CONTENTS_RENDER_VIEW_HOST_CREATED: {
182 if (print_preview_distiller_->GetWebContents()) {
183 DCHECK_EQ(content::Source<WebContents>(source).ptr(),
184 print_preview_distiller_->GetWebContents());
185
186 // Make sure the size of the RenderViewHost has been passed to the new
187 // RenderView. Otherwise, the size may not be sent until the
188 // RenderViewReady event makes it from the render process to the UI
189 // thread of the browser process. When the RenderView receives its
190 // size, is also sets itself to be visible, which would then break the
191 // visibility API.
192 content::Details<RenderViewHost> new_render_view_host(details);
193 new_render_view_host->WasResized();
194 print_preview_distiller_->GetWebContents()->WasHidden();
195 }
196 break;
197 }
198
199 default:
200 NOTREACHED() << "Unexpected notification sent.";
201 break;
202 }
203 }
204
205 private:
206 PrintPreviewDistiller* print_preview_distiller_;
Vitaly Buka (NO REVIEWS) 2015/07/20 20:45:33 = nullptr
arjunpatel 2015/07/21 17:25:00 Acknowledged.
207 scoped_ptr<base::DictionaryValue> settings_;
208 content::NotificationRegistrar notification_registrar_;
209 };
210
211 PrintPreviewDistiller::PrintPreviewDistiller(
212 WebContents* source_web_contents,
213 PrintPreviewUI* print_preview_ui,
214 scoped_ptr<base::DictionaryValue> settings) {
Vitaly Buka (NO REVIEWS) 2015/07/20 20:45:33 Could you bind outside this class and pass callbac
arjunpatel 2015/07/21 17:25:00 Acknowledged.
215 DCHECK(print_preview_ui);
Vitaly Buka (NO REVIEWS) 2015/07/20 20:45:33 DCHECK only if code around is unaffected by unexpe
arjunpatel 2015/07/21 17:25:00 Acknowledged.
216 on_failed_callback_ = base::Bind(&PrintPreviewUI::OnPrintPreviewFailed,
217 print_preview_ui->GetWeakPtr());
218
219 content::SessionStorageNamespace* session_storage_namespace =
220 source_web_contents->GetController().GetDefaultSessionStorageNamespace();
221 CreateDestinationWebContents(session_storage_namespace, source_web_contents,
222 settings.Pass());
223
224 DCHECK(web_contents_);
225 ::DistillAndView(source_web_contents, web_contents_.get());
226 }
227
228 void PrintPreviewDistiller::CreateDestinationWebContents(
229 SessionStorageNamespace* session_storage_namespace,
230 WebContents* source_web_contents,
231 scoped_ptr<base::DictionaryValue> settings) {
232 DCHECK(web_contents_.get() == NULL);
Vitaly Buka (NO REVIEWS) 2015/07/20 20:45:33 if possible DCHECK(!web_contents_) if not, then DC
arjunpatel 2015/07/21 17:25:00 Acknowledged.
233
234 web_contents_.reset(
235 CreateWebContents(session_storage_namespace, source_web_contents));
236 TabHelpers::AttachTabHelpers(web_contents_.get());
237
238 web_contents_delegate_.reset(
239 new WebContentsDelegateImpl(this, settings.Pass()));
240
241 // Set the size of the distilled WebContents.
242 ResizeWebContents(web_contents_.get(), gfx::Size(1, 1));
243
244 printing::PrintPreviewDialogController* dialog_controller =
245 printing::PrintPreviewDialogController::GetInstance();
246 if (!dialog_controller) {
Vitaly Buka (NO REVIEWS) 2015/07/20 20:45:33 you should drop {} here for consistency
arjunpatel 2015/07/21 17:25:00 Acknowledged.
247 return;
248 }
249
250 dialog_controller->AddProxyDialogForWebContents(web_contents_.get(),
251 source_web_contents);
252 }
253
254 PrintPreviewDistiller::~PrintPreviewDistiller() {
255 if (web_contents_) {
256 printing::PrintPreviewDialogController* dialog_controller =
257 printing::PrintPreviewDialogController::GetInstance();
258 if (!dialog_controller)
259 return;
260
261 dialog_controller->RemoveProxyDialogForWebContents(web_contents_.get());
262 }
263 }
264
265 WebContents* PrintPreviewDistiller::CreateWebContents(
266 SessionStorageNamespace* session_storage_namespace,
267 WebContents* source_web_contents) {
268 // TODO(ajwong): Remove the temporary map once prerendering is aware of
269 // multiple session storage namespaces per tab.
270 content::SessionStorageNamespaceMap session_storage_namespace_map;
271 Profile* profile =
272 Profile::FromBrowserContext(source_web_contents->GetBrowserContext());
273 session_storage_namespace_map[std::string()] = session_storage_namespace;
274 return WebContents::CreateWithSessionStorage(
275 WebContents::CreateParams(profile), session_storage_namespace_map);
276 }
277
278 void PrintPreviewDistiller::Abort() {
279 on_failed_callback_.Run();
280 }
281
282 WebContents* PrintPreviewDistiller::GetWebContents() {
283 return web_contents_.get();
284 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698