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

Side by Side Diff: chrome/browser/ui/webui/print_preview/hidden_web_contents.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: Update AUTHORS file to reflect the correct HP name used in the CLA Created 5 years, 7 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) 2014 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/hidden_web_contents.h"
6
7 #include <string>
8
9 #include "chrome/browser/chrome_notification_types.h"
10 #include "chrome/browser/profiles/profile.h"
11 #include "chrome/browser/ui/tab_helpers.h"
12 #include "chrome/browser/ui/web_contents_sizer.h"
13 #include "chrome/common/prerender_messages.h"
14 #include "content/public/browser/browser_thread.h"
15 #include "content/public/browser/notification_service.h"
16 #include "content/public/browser/render_frame_host.h"
17 #include "content/public/browser/render_process_host.h"
18 #include "content/public/browser/render_view_host.h"
19 #include "content/public/browser/session_storage_namespace.h"
20 #include "content/public/browser/web_contents.h"
21 #include "content/public/browser/web_contents_delegate.h"
22
23 using content::OpenURLParams;
24 using content::RenderViewHost;
25 using content::SessionStorageNamespace;
26 using content::WebContents;
27
28 class HiddenWebContents::WebContentsDelegateImpl
29 : public content::WebContentsDelegate {
30 public:
31 explicit WebContentsDelegateImpl(HiddenWebContents* hidden_web_contents)
32 : hidden_web_contents_(hidden_web_contents) {
33 }
34
35 // content::WebContentsDelegate implementation:
36 WebContents* OpenURLFromTab(WebContents* source,
37 const OpenURLParams& params) override {
38 // |OpenURLFromTab| is typically called when a frame performs a navigation
39 // that requires the browser to perform the transition instead of WebKit.
40 // Examples include rendering a site that redirects to an app URL,
41 // or if --enable-strict-site-isolation is specified and the rendered
42 // frame redirects to a different origin.
43 hidden_web_contents_->Destroy();
44 return NULL;
45 }
46
47 void CloseContents(content::WebContents* contents) override {
48 hidden_web_contents_->Destroy();
49 }
50
51 void CanDownload(RenderViewHost* render_view_host,
52 const GURL& url,
53 const std::string& request_method,
54 const base::Callback<void(bool)>& callback) override {
55 hidden_web_contents_->Destroy();
56 // Cancel the download.
57 callback.Run(false);
58 }
59
60 bool ShouldCreateWebContents(
61 WebContents* web_contents,
62 int route_id,
63 int main_frame_route_id,
64 WindowContainerType window_container_type,
65 const base::string16& frame_name,
66 const GURL& target_url,
67 const std::string& partition_id,
68 SessionStorageNamespace* session_storage_namespace) override {
69 // Since we don't want to permit child windows that would have a
70 // window.opener property, terminate rendering.
71 hidden_web_contents_->Destroy();
72 // Cancel the popup.
73 return false;
74 }
75
76 bool OnGoToEntryOffset(int offset) override {
77 // This isn't allowed because the history merge operation
78 // does not work if there are renderer issued challenges.
79 // TODO(cbentzel): Cancel in this case? May not need to do
80 // since render-issued offset navigations are not guaranteed,
81 // but indicates that the page cares about the history.
82 return false;
83 }
84
85 bool ShouldSuppressDialogs(WebContents* source) override {
86 // We still want to show the user the message when they navigate to this
87 // page, so cancel this render.
88 hidden_web_contents_->Destroy();
89 // Always suppress JavaScript messages if they're triggered by a page being
90 // rendered.
91 return true;
92 }
93
94 void RegisterProtocolHandler(WebContents* web_contents,
95 const std::string& protocol,
96 const GURL& url,
97 bool user_gesture) override {
98 hidden_web_contents_->Destroy();
99 }
100
101 gfx::Size GetSizeForNewRenderView(WebContents* web_contents) const override {
102 // Have to set the size of the RenderView on initialization to be sure it is
103 // set before the RenderView is hidden on all platforms (esp. Android).
104 return hidden_web_contents_->size_;
105 }
106
107 private:
108 HiddenWebContents* hidden_web_contents_;
109 };
110
111 void HiddenWebContents::Observer::OnFinishedLoad(
112 HiddenWebContents* contents) {
113 }
114
115 HiddenWebContents::Observer::Observer() {
116 }
117
118 HiddenWebContents::Observer::~Observer() {
119 }
120
121 HiddenWebContents::HiddenWebContents(
122 Profile* profile,
123 const GURL& url)
124 : rendering_has_started_(false),
125 session_storage_namespace_id_(-1),
126 url_(url),
127 profile_(profile),
128 has_stopped_loading_(false),
129 has_finished_loading_(false),
130 rendering_has_been_cancelled_(false) {
131 }
132
133 // static
134 bool HiddenWebContents::IsValidUrl(const GURL& url) {
135 return url.SchemeIs("chrome-distiller");
136 }
137
138 void HiddenWebContents::StartRendering(
139 const gfx::Size& size,
140 SessionStorageNamespace* session_storage_namespace) {
141 DCHECK(profile_ != NULL);
142 DCHECK(!size.IsEmpty());
143 DCHECK(!rendering_has_started_);
144 DCHECK(web_contents_.get() == NULL);
145 DCHECK(size_.IsEmpty());
146
147 if (!HiddenWebContents::IsValidUrl(url_)) {
148 Destroy();
149 return;
150 }
151
152 session_storage_namespace_id_ = session_storage_namespace->id();
153 size_ = size;
154
155 rendering_has_started_ = true;
156
157 web_contents_.reset(CreateWebContents(session_storage_namespace));
158 TabHelpers::AttachTabHelpers(web_contents_.get());
159 content::WebContentsObserver::Observe(web_contents_.get());
160
161 web_contents_delegate_.reset(new WebContentsDelegateImpl(this));
162 web_contents_.get()->SetDelegate(web_contents_delegate_.get());
163
164 // Set the size of the hidden WebContents.
165 ResizeWebContents(web_contents_.get(), size_);
166
167 // Close ourselves when the application is shutting down.
168 notification_registrar_.Add(this, chrome::NOTIFICATION_APP_TERMINATING,
169 content::NotificationService::AllSources());
170
171 // Register to inform new RenderViews that we're rendering.
172 notification_registrar_.Add(
173 this, content::NOTIFICATION_WEB_CONTENTS_RENDER_VIEW_HOST_CREATED,
174 content::Source<WebContents>(web_contents_.get()));
175
176 content::NavigationController::LoadURLParams load_url_params(url_);
177 load_url_params.transition_type = ui::PAGE_TRANSITION_LINK;
178 web_contents_.get()->GetController().LoadURLWithParams(load_url_params);
179 }
180
181 HiddenWebContents::~HiddenWebContents() {
182 if (web_contents_.get()) {
183 web_contents_->SetDelegate(NULL);
184 content::WebContentsObserver::Observe(NULL);
185 }
186 }
187
188 void HiddenWebContents::AddObserver(Observer* observer) {
189 observer_list_.AddObserver(observer);
190 }
191
192 void HiddenWebContents::RemoveObserver(Observer* observer) {
193 observer_list_.RemoveObserver(observer);
194 }
195
196 void HiddenWebContents::Observe(int type,
197 const content::NotificationSource& source,
198 const content::NotificationDetails& details) {
199 switch (type) {
200 // TODO(davidben): Try to remove this in favor of relying on
201 // FINAL_STATUS_PROFILE_DESTROYED.
202 case chrome::NOTIFICATION_APP_TERMINATING:
203 Destroy();
204 return;
205
206 case content::NOTIFICATION_WEB_CONTENTS_RENDER_VIEW_HOST_CREATED: {
207 if (web_contents_.get()) {
208 DCHECK_EQ(content::Source<WebContents>(source).ptr(),
209 web_contents_.get());
210
211 // Make sure the size of the RenderViewHost has been passed to the new
212 // RenderView. Otherwise, the size may not be sent until the
213 // RenderViewReady event makes it from the render process to the UI
214 // thread of the browser process. When the RenderView receives its
215 // size, is also sets itself to be visible, which would then break the
216 // visibility API.
217 content::Details<RenderViewHost> new_render_view_host(details);
218 new_render_view_host->WasResized();
219 web_contents_->WasHidden();
220 }
221 break;
222 }
223
224 default:
225 NOTREACHED() << "Unexpected notification sent.";
226 break;
227 }
228 }
229
230 WebContents* HiddenWebContents::CreateWebContents(
231 SessionStorageNamespace* session_storage_namespace) {
232 // TODO(ajwong): Remove the temporary map once prerendering is aware of
233 // multiple session storage namespaces per tab.
234 content::SessionStorageNamespaceMap session_storage_namespace_map;
235 session_storage_namespace_map[std::string()] = session_storage_namespace;
236 return WebContents::CreateWithSessionStorage(
237 WebContents::CreateParams(profile_), session_storage_namespace_map);
238 }
239
240 void HiddenWebContents::NotifyFail() {
241 FOR_EACH_OBSERVER(Observer, observer_list_, OnFail(this));
242 observer_list_.Clear();
243 }
244
245 void HiddenWebContents::NotifyFinishedLoad() {
246 FOR_EACH_OBSERVER(Observer, observer_list_, OnFinishedLoad(this));
247 }
248
249 void HiddenWebContents::RenderProcessGone(base::TerminationStatus status) {
250 Destroy();
251 }
252
253 void HiddenWebContents::RenderFrameCreated(
254 content::RenderFrameHost* render_frame_host) {
255 // When a new RenderFrame is created for a hidden rendering WebContents, tell
256 // the new RenderFrame it's being used for prerendering before any
257 // navigations occur. Note that this is always triggered before the first
258 // navigation, so there's no need to send the message just after the
259 // WebContents is created.
260 render_frame_host->Send(new PrerenderMsg_SetIsPrerendering(
261 render_frame_host->GetRoutingID(), true));
262 }
263
264 void HiddenWebContents::DidStopLoading() {
265 has_stopped_loading_ = true;
266 }
267
268 void HiddenWebContents::DocumentLoadedInFrame(
269 content::RenderFrameHost* render_frame_host) {
270 }
271
272 void HiddenWebContents::DidStartProvisionalLoadForFrame(
273 content::RenderFrameHost* render_frame_host,
274 const GURL& validated_url,
275 bool is_error_page,
276 bool is_iframe_srcdoc) {
277 if (!render_frame_host->GetParent()) {
278 // Usually, this event fires if the user clicks or enters a new URL.
279 // Neither of these can happen in the case of an hidden renderer.
280 // So the cause is: Some JavaScript caused a new URL to be loaded. In that
281 // case, the spinner would start again in the browser, so we must reset
282 // has_stopped_loading_ so that the spinner won't be stopped.
283 has_stopped_loading_ = false;
284 has_finished_loading_ = false;
285 }
286 }
287
288 void HiddenWebContents::DidFinishLoad(
289 content::RenderFrameHost* render_frame_host,
290 const GURL& validated_url) {
291 if (!render_frame_host->GetParent())
292 has_finished_loading_ = true;
293 NotifyFinishedLoad();
294 }
295
296 void HiddenWebContents::DidNavigateMainFrame(
297 const content::LoadCommittedDetails& details,
298 const content::FrameNavigateParams& params) {
299 // If the render made a second navigation entry, abort the render. This
300 // avoids having to correctly implement a complex history merging case (this
301 // interacts with location.replace) and correctly synchronize with the
302 // renderer. The final status may be monitored to see we need to revisit this
303 // decision. This does not affect client redirects as those do not push new
304 // history entries. (Calls to location.replace, navigations before onload, and
305 // <meta http-equiv=refresh> with timeouts under 1 second do not create
306 // entries in Blink.)
307 if (web_contents_->GetController().GetEntryCount() > 1)
308 Destroy();
309 }
310
311 void HiddenWebContents::DidGetRedirectForResourceRequest(
312 content::RenderFrameHost* render_frame_host,
313 const content::ResourceRedirectDetails& details) {
314 // Redirects are unsupported for hidden renderers.
315 Destroy();
316 }
317
318 void HiddenWebContents::Destroy() {
319 if (rendering_has_been_cancelled_)
320 return;
321
322 rendering_has_been_cancelled_ = true;
323 NotifyFail();
324 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698