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

Side by Side Diff: chrome/browser/instant/instant_loader.cc

Issue 11824050: InstantExtended: Committed NTP (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Cleanup. Created 7 years, 11 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 2012 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/instant/instant_loader.h"
6
7 #include "chrome/browser/content_settings/tab_specific_content_settings.h"
8 #include "chrome/browser/extensions/api/web_navigation/web_navigation_api.h"
9 #include "chrome/browser/favicon/favicon_tab_helper.h"
10 #include "chrome/browser/history/history_tab_helper.h"
11 #include "chrome/browser/instant/instant_controller.h"
12 #include "chrome/browser/safe_browsing/safe_browsing_tab_observer.h"
13 #include "chrome/browser/ui/blocked_content/blocked_content_tab_helper.h"
14 #include "chrome/browser/ui/search/search_tab_helper.h"
15 #include "chrome/browser/ui/tab_contents/core_tab_helper.h"
16 #include "chrome/browser/ui/tab_contents/core_tab_helper_delegate.h"
17 #include "chrome/browser/ui/web_contents_modal_dialog_manager.h"
18 #include "chrome/browser/ui/web_contents_modal_dialog_manager_delegate.h"
19 #include "content/public/browser/notification_source.h"
20 #include "content/public/browser/notification_types.h"
21 #include "content/public/browser/render_widget_host_view.h"
22 #include "content/public/browser/web_contents_delegate.h"
23 #include "content/public/browser/web_contents_view.h"
24 #include "ipc/ipc_message.h"
25
26 namespace {
27
28 int kUserDataKey;
29
30 class InstantLoaderUserData : public base::SupportsUserData::Data {
31 public:
32 explicit InstantLoaderUserData(InstantLoader* loader) : loader_(loader) {}
33
34 InstantLoader* loader() const { return loader_; }
35
36 private:
37 ~InstantLoaderUserData() {}
38
39 InstantLoader* const loader_;
40
41 DISALLOW_COPY_AND_ASSIGN(InstantLoaderUserData);
42 };
43
44 }
45
46 // WebContentsDelegateImpl -----------------------------------------------------
47
48 class InstantLoader::WebContentsDelegateImpl
49 : public WebContentsModalDialogManagerDelegate,
50 public CoreTabHelperDelegate,
51 public content::WebContentsDelegate {
52 public:
53 explicit WebContentsDelegateImpl(InstantLoader* loader);
54
55 private:
56 // Overridden from WebContentsModalDialogManagerDelegate:
57 virtual bool ShouldFocusWebContentsModalDialog() OVERRIDE;
58
59 // Overridden from CoreTabHelperDelegate:
60 virtual void SwapTabContents(content::WebContents* old_contents,
61 content::WebContents* new_contents) OVERRIDE;
62
63 // Overridden from content::WebContentsDelegate:
64 virtual bool ShouldSuppressDialogs() OVERRIDE;
65 virtual bool ShouldFocusPageAfterCrash() OVERRIDE;
66 virtual void LostCapture() OVERRIDE;
67 virtual void WebContentsFocused(content::WebContents* contents) OVERRIDE;
68 virtual bool CanDownload(content::RenderViewHost* render_view_host,
69 int request_id,
70 const std::string& request_method) OVERRIDE;
71 virtual void HandleMouseDown() OVERRIDE;
72 virtual void HandleMouseUp() OVERRIDE;
73 virtual void HandlePointerActivate() OVERRIDE;
74 virtual void HandleGestureEnd() OVERRIDE;
75 virtual void DragEnded() OVERRIDE;
76 virtual bool OnGoToEntryOffset(int offset) OVERRIDE;
77 virtual content::WebContents* OpenURLFromTab(
78 content::WebContents* source,
79 const content::OpenURLParams& params) OVERRIDE;
80
81 void MaybeCommitFromPointerRelease();
82
83 InstantLoader* const loader_;
84
85 DISALLOW_COPY_AND_ASSIGN(WebContentsDelegateImpl);
86 };
87
88 InstantLoader::WebContentsDelegateImpl::WebContentsDelegateImpl(
89 InstantLoader* loader)
90 : loader_(loader) {
91 }
92
93 bool InstantLoader::WebContentsDelegateImpl::ShouldFocusWebContentsModalDialog(
94 ) {
95 // Return false so that web contents modal dialogs are not initially
96 // focused. If we did otherwise the preview would prematurely get committed
97 // when focus goes to the dialog.
98 return false;
99 }
100
101 void InstantLoader::WebContentsDelegateImpl::SwapTabContents(
102 content::WebContents* old_contents,
103 content::WebContents* new_contents) {
104 // If this is being called, something is swapping in to loader's |contents_|
105 // before we've added it to the tab strip.
106 loader_->ReplacePreviewContents(old_contents, new_contents);
107 }
108
109 bool InstantLoader::WebContentsDelegateImpl::ShouldSuppressDialogs() {
110 // Any message shown during Instant cancels Instant, so we suppress them.
111 return true;
112 }
113
114 bool InstantLoader::WebContentsDelegateImpl::ShouldFocusPageAfterCrash() {
115 return false;
116 }
117
118 void InstantLoader::WebContentsDelegateImpl::LostCapture() {
119 MaybeCommitFromPointerRelease();
120 }
121
122 void InstantLoader::WebContentsDelegateImpl::WebContentsFocused(
123 content::WebContents* /* contents */) {
124 // The preview is getting focus. Equivalent to it being clicked.
125 bool tmp = loader_->is_pointer_down_from_activate_;
126 loader_->is_pointer_down_from_activate_ = true;
127 loader_->controller_->InstantLoaderContentsFocused();
128 loader_->is_pointer_down_from_activate_ = tmp;
129 }
130
131 bool InstantLoader::WebContentsDelegateImpl::CanDownload(
132 content::RenderViewHost* /* render_view_host */,
133 int /* request_id */,
134 const std::string& /* request_method */) {
135 // Downloads are disabled.
136 return false;
137 }
138
139 void InstantLoader::WebContentsDelegateImpl::HandleMouseDown() {
140 loader_->is_pointer_down_from_activate_ = true;
141 }
142
143 void InstantLoader::WebContentsDelegateImpl::HandleMouseUp() {
144 MaybeCommitFromPointerRelease();
145 }
146
147 void InstantLoader::WebContentsDelegateImpl::HandlePointerActivate() {
148 loader_->is_pointer_down_from_activate_ = true;
149 }
150
151 void InstantLoader::WebContentsDelegateImpl::HandleGestureEnd() {
152 MaybeCommitFromPointerRelease();
153 }
154
155 void InstantLoader::WebContentsDelegateImpl::DragEnded() {
156 // If the user drags, we won't get a mouse up (at least on Linux). Commit the
157 // Instant result when the drag ends, so that during the drag the page won't
158 // move around.
159 MaybeCommitFromPointerRelease();
160 }
161
162 bool InstantLoader::WebContentsDelegateImpl::OnGoToEntryOffset(int offset) {
163 return false;
164 }
165
166 content::WebContents* InstantLoader::WebContentsDelegateImpl::OpenURLFromTab(
167 content::WebContents* source,
168 const content::OpenURLParams& params) {
169 content::WebContents* preview = loader_->contents_.get();
170 if (loader_->controller_->CommitIfPossible(INSTANT_COMMIT_NAVIGATED))
171 return preview->GetDelegate()->OpenURLFromTab(source, params);
172 return NULL;
173 }
174
175 void InstantLoader::WebContentsDelegateImpl::MaybeCommitFromPointerRelease() {
176 if (loader_->is_pointer_down_from_activate_) {
177 loader_->is_pointer_down_from_activate_ = false;
178 loader_->controller_->CommitIfPossible(INSTANT_COMMIT_FOCUS_LOST);
179 }
180 }
181
182 // InstantLoader ---------------------------------------------------------------
183
184 // static
185 InstantLoader* InstantLoader::FromWebContents(
186 const content::WebContents* web_contents) {
187 InstantLoaderUserData* data = static_cast<InstantLoaderUserData*>(
188 web_contents->GetUserData(&kUserDataKey));
189 return data ? data->loader() : NULL;
190 }
191
192 InstantLoader::InstantLoader(InstantController* controller,
193 const std::string& instant_url)
194 : client_(ALLOW_THIS_IN_INITIALIZER_LIST(this)),
195 controller_(controller),
196 delegate_(new WebContentsDelegateImpl(
197 ALLOW_THIS_IN_INITIALIZER_LIST(this))),
198 instant_url_(instant_url),
199 supports_instant_(false),
200 is_pointer_down_from_activate_(false) {
201 }
202
203 InstantLoader::~InstantLoader() {
204 }
205
206 void InstantLoader::InitContents(const content::WebContents* active_tab) {
207 content::WebContents::CreateParams create_params(
208 active_tab->GetBrowserContext());
209 if (active_tab)
210 create_params.initial_size = active_tab->GetView()->GetContainerSize();
211 contents_.reset(content::WebContents::CreateWithSessionStorage(
212 create_params,
213 active_tab->GetController().GetSessionStorageNamespaceMap()));
214 SetupPreviewContents();
215
216 // This HTTP header and value are set on loads that originate from Instant.
217 const char kInstantHeader[] = "X-Purpose: Instant";
218 DVLOG(1) << "LoadURL: " << instant_url_;
219 contents_->GetController().LoadURL(GURL(instant_url_), content::Referrer(),
220 content::PAGE_TRANSITION_GENERATED, kInstantHeader);
221 contents_->WasHidden();
222 }
223
224 content::WebContents* InstantLoader::ReleaseContents() {
225 CleanupPreviewContents();
226 return contents_.release();
227 }
228
229 void InstantLoader::DidNavigate(
230 const history::HistoryAddPageArgs& add_page_args) {
231 last_navigation_ = add_page_args;
232 }
233
234 bool InstantLoader::IsUsingLocalPreview() const {
235 return instant_url_ == InstantController::kLocalOmniboxPopupURL;
236 }
237
238 void InstantLoader::Update(const string16& text,
239 size_t selection_start,
240 size_t selection_end,
241 bool verbatim) {
242 last_navigation_ = history::HistoryAddPageArgs();
243 client_.Update(text, selection_start, selection_end, verbatim);
244 }
245
246 void InstantLoader::Submit(const string16& text) {
247 client_.Submit(text);
248 }
249
250 void InstantLoader::Cancel(const string16& text) {
251 client_.Cancel(text);
252 }
253
254 void InstantLoader::SetPopupBounds(const gfx::Rect& bounds) {
255 client_.SetPopupBounds(bounds);
256 }
257
258 void InstantLoader::SetMarginSize(int start, int end) {
259 client_.SetMarginSize(start, end);
260 }
261
262 void InstantLoader::SendAutocompleteResults(
263 const std::vector<InstantAutocompleteResult>& results) {
264 client_.SendAutocompleteResults(results);
265 }
266
267 void InstantLoader::UpOrDownKeyPressed(int count) {
268 client_.UpOrDownKeyPressed(count);
269 }
270
271 void InstantLoader::SearchModeChanged(const chrome::search::Mode& mode) {
272 client_.SearchModeChanged(mode);
273 }
274
275 void InstantLoader::SendThemeBackgroundInfo(
276 const ThemeBackgroundInfo& theme_info) {
277 client_.SendThemeBackgroundInfo(theme_info);
278 }
279
280 void InstantLoader::SendThemeAreaHeight(int height) {
281 client_.SendThemeAreaHeight(height);
282 }
283
284 void InstantLoader::SetDisplayInstantResults(bool display_instant_results) {
285 client_.SetDisplayInstantResults(display_instant_results);
286 }
287
288 void InstantLoader::KeyCaptureChanged(bool is_key_capture_enabled) {
289 client_.KeyCaptureChanged(is_key_capture_enabled);
290 }
291
292 void InstantLoader::SetSuggestions(
293 const std::vector<InstantSuggestion>& suggestions) {
294 InstantSupportDetermined(true);
295 controller_->SetSuggestions(contents(), suggestions);
296 }
297
298 void InstantLoader::InstantSupportDetermined(bool supports_instant) {
299 // If we had already determined that the page supports Instant, nothing to do.
300 if (supports_instant_)
301 return;
302
303 supports_instant_ = supports_instant;
304 controller_->InstantSupportDetermined(contents(), supports_instant);
305 }
306
307 void InstantLoader::ShowInstantPreview(InstantShownReason reason,
308 int height,
309 InstantSizeUnits units) {
310 InstantSupportDetermined(true);
311 controller_->ShowInstantPreview(reason, height, units);
312 }
313
314 void InstantLoader::StartCapturingKeyStrokes() {
315 InstantSupportDetermined(true);
316 controller_->StartCapturingKeyStrokes();
317 }
318
319 void InstantLoader::StopCapturingKeyStrokes() {
320 InstantSupportDetermined(true);
321 controller_->StopCapturingKeyStrokes();
322 }
323
324 void InstantLoader::RenderViewGone() {
325 controller_->InstantLoaderRenderViewGone();
326 }
327
328 void InstantLoader::AboutToNavigateMainFrame(const GURL& url) {
329 controller_->InstantLoaderAboutToNavigateMainFrame(url);
330 }
331
332 void InstantLoader::NavigateToURL(const GURL& url,
333 content::PageTransition transition) {
334 InstantSupportDetermined(true);
335 controller_->NavigateToURL(url, transition);
336 }
337
338 void InstantLoader::Observe(int type,
339 const content::NotificationSource& source,
340 const content::NotificationDetails& details) {
341 #if defined(OS_MACOSX)
342 if (type == content::NOTIFICATION_RENDER_VIEW_HOST_CHANGED) {
343 if (content::RenderWidgetHostView* rwhv =
344 contents_->GetRenderWidgetHostView())
345 rwhv->SetTakesFocusOnlyOnMouseDown(true);
346 return;
347 }
348 NOTREACHED();
349 #endif
350 }
351
352 void InstantLoader::SetupPreviewContents() {
353 client_.SetContents(contents());
354 contents_->SetUserData(&kUserDataKey, new InstantLoaderUserData(this));
355 contents_->SetDelegate(delegate_.get());
356
357 // Set up various tab helpers. The rest will get attached when (if) the
358 // contents is added to the tab strip.
359
360 // Tab helpers to control popups.
361 BlockedContentTabHelper::CreateForWebContents(contents());
362 BlockedContentTabHelper::FromWebContents(contents())->
363 SetAllContentsBlocked(true);
364 TabSpecificContentSettings::CreateForWebContents(contents());
365 TabSpecificContentSettings::FromWebContents(contents())->
366 SetPopupsBlocked(true);
367
368 // A manager to control web contents modal dialogs.
369 WebContentsModalDialogManager::CreateForWebContents(contents());
370 WebContentsModalDialogManager::FromWebContents(contents())->
371 set_delegate(delegate_.get());
372
373 // A tab helper to catch prerender content swapping shenanigans.
374 CoreTabHelper::CreateForWebContents(contents());
375 CoreTabHelper::FromWebContents(contents())->set_delegate(delegate_.get());
376
377 // Tab helpers used when committing a preview.
378 chrome::search::SearchTabHelper::CreateForWebContents(contents());
379 HistoryTabHelper::CreateForWebContents(contents());
380
381 // Observers.
382 extensions::WebNavigationTabObserver::CreateForWebContents(contents());
383
384 // Favicons, required by the Task Manager.
385 FaviconTabHelper::CreateForWebContents(contents());
386
387 // And some flat-out paranoia.
388 safe_browsing::SafeBrowsingTabObserver::CreateForWebContents(contents());
389
390 #if defined(OS_MACOSX)
391 // If |contents_| doesn't yet have a RWHV, SetTakesFocusOnlyOnMouseDown() will
392 // be called later, when NOTIFICATION_RENDER_VIEW_HOST_CHANGED is received.
393 if (content::RenderWidgetHostView* rwhv =
394 contents_->GetRenderWidgetHostView())
395 rwhv->SetTakesFocusOnlyOnMouseDown(true);
396 registrar_.Add(this, content::NOTIFICATION_RENDER_VIEW_HOST_CHANGED,
397 content::Source<content::NavigationController>(
398 &contents_->GetController()));
399 #endif
400 }
401
402 void InstantLoader::CleanupPreviewContents() {
403 client_.SetContents(NULL);
404 contents_->RemoveUserData(&kUserDataKey);
405 contents_->SetDelegate(NULL);
406
407 // Undo tab helper work done in SetupPreviewContents().
408
409 BlockedContentTabHelper::FromWebContents(contents())->
410 SetAllContentsBlocked(false);
411 TabSpecificContentSettings::FromWebContents(contents())->
412 SetPopupsBlocked(false);
413
414 WebContentsModalDialogManager::FromWebContents(contents())->
415 set_delegate(NULL);
416
417 CoreTabHelper::FromWebContents(contents())->set_delegate(NULL);
418
419 #if defined(OS_MACOSX)
420 if (content::RenderWidgetHostView* rwhv =
421 contents_->GetRenderWidgetHostView())
422 rwhv->SetTakesFocusOnlyOnMouseDown(false);
423 registrar_.Remove(this, content::NOTIFICATION_RENDER_VIEW_HOST_CHANGED,
424 content::Source<content::NavigationController>(
425 &contents_->GetController()));
426 #endif
427 }
428
429 void InstantLoader::ReplacePreviewContents(content::WebContents* old_contents,
430 content::WebContents* new_contents) {
431 DCHECK_EQ(old_contents, contents());
432 CleanupPreviewContents();
433 // We release here without deleting so that the caller still has the
434 // responsibility for deleting the WebContents.
435 ignore_result(contents_.release());
436 contents_.reset(new_contents);
437 SetupPreviewContents();
438 controller_->SwappedWebContents();
439 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698