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

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

Issue 11824050: InstantExtended: Committed NTP (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebase. 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
1 // Copyright 2012 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/instant/instant_controller.h" 5 #include "chrome/browser/instant/instant_controller.h"
6 6
7 #include "base/command_line.h" 7 #include "base/command_line.h"
8 #include "base/metrics/histogram.h" 8 #include "base/metrics/histogram.h"
9 #include "base/string_util.h" 9 #include "base/string_util.h"
10 #include "base/utf_string_conversions.h" 10 #include "base/utf_string_conversions.h"
11 #include "chrome/browser/autocomplete/autocomplete_provider.h" 11 #include "chrome/browser/autocomplete/autocomplete_provider.h"
12 #include "chrome/browser/google/google_util.h" 12 #include "chrome/browser/google/google_util.h"
13 #include "chrome/browser/history/history.h" 13 #include "chrome/browser/history/history.h"
14 #include "chrome/browser/history/history_service_factory.h" 14 #include "chrome/browser/history/history_service_factory.h"
15 #include "chrome/browser/history/history_tab_helper.h" 15 #include "chrome/browser/history/history_tab_helper.h"
16 #include "chrome/browser/instant/instant_loader.h" 16 #include "chrome/browser/instant/instant_ntp.h"
17 #include "chrome/browser/instant/instant_overlay.h"
17 #include "chrome/browser/instant/instant_tab.h" 18 #include "chrome/browser/instant/instant_tab.h"
18 #include "chrome/browser/platform_util.h" 19 #include "chrome/browser/platform_util.h"
19 #include "chrome/browser/search_engines/template_url_service.h" 20 #include "chrome/browser/search_engines/template_url_service.h"
20 #include "chrome/browser/search_engines/template_url_service_factory.h" 21 #include "chrome/browser/search_engines/template_url_service_factory.h"
21 #include "chrome/browser/ui/browser_instant_controller.h" 22 #include "chrome/browser/ui/browser_instant_controller.h"
22 #include "chrome/browser/ui/search/search_tab_helper.h" 23 #include "chrome/browser/ui/search/search_tab_helper.h"
23 #include "chrome/common/chrome_notification_types.h" 24 #include "chrome/common/chrome_notification_types.h"
24 #include "chrome/common/chrome_switches.h" 25 #include "chrome/common/chrome_switches.h"
25 #include "content/public/browser/navigation_entry.h" 26 #include "content/public/browser/navigation_entry.h"
26 #include "content/public/browser/notification_service.h" 27 #include "content/public/browser/notification_service.h"
(...skipping 12 matching lines...) Expand all
39 // page about the new omnibox bounds, in cases where the bounds shrink. This is 40 // page about the new omnibox bounds, in cases where the bounds shrink. This is
40 // to avoid the page jumping up/down very fast in response to bounds changes. 41 // to avoid the page jumping up/down very fast in response to bounds changes.
41 const int kUpdateBoundsDelayMS = 1000; 42 const int kUpdateBoundsDelayMS = 1000;
42 43
43 // The maximum number of times we'll load a non-Instant-supporting search engine 44 // The maximum number of times we'll load a non-Instant-supporting search engine
44 // before we give up and blacklist it for the rest of the browsing session. 45 // before we give up and blacklist it for the rest of the browsing session.
45 const int kMaxInstantSupportFailures = 10; 46 const int kMaxInstantSupportFailures = 10;
46 47
47 // If an Instant page has not been used in these many milliseconds, it is 48 // If an Instant page has not been used in these many milliseconds, it is
48 // reloaded so that the page does not become stale. 49 // reloaded so that the page does not become stale.
49 const int kStaleLoaderTimeoutMS = 3 * 3600 * 1000; 50 const int kStalePageTimeoutMS = 3 * 3600 * 1000;
50 51
51 // For reporting events of interest. 52 // For reporting events of interest.
52 enum InstantControllerEvent { 53 enum InstantControllerEvent {
53 INSTANT_CONTROLLER_EVENT_URL_ADDED_TO_BLACKLIST = 0, 54 INSTANT_CONTROLLER_EVENT_URL_ADDED_TO_BLACKLIST = 0,
54 INSTANT_CONTROLLER_EVENT_URL_REMOVED_FROM_BLACKLIST = 1, 55 INSTANT_CONTROLLER_EVENT_URL_REMOVED_FROM_BLACKLIST = 1,
55 INSTANT_CONTROLLER_EVENT_URL_BLOCKED_BY_BLACKLIST = 2, 56 INSTANT_CONTROLLER_EVENT_URL_BLOCKED_BY_BLACKLIST = 2,
56 INSTANT_CONTROLLER_EVENT_MAX = 3, 57 INSTANT_CONTROLLER_EVENT_MAX = 3,
57 }; 58 };
58 59
59 void RecordEventHistogram(InstantControllerEvent event) { 60 void RecordEventHistogram(InstantControllerEvent event) {
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
152 return true; 153 return true;
153 } 154 }
154 155
155 return false; 156 return false;
156 } 157 }
157 158
158 bool IsFullHeight(const InstantModel& model) { 159 bool IsFullHeight(const InstantModel& model) {
159 return model.height() == 100 && model.height_units() == INSTANT_SIZE_PERCENT; 160 return model.height() == 100 && model.height_units() == INSTANT_SIZE_PERCENT;
160 } 161 }
161 162
163 bool ContentsFrom(const InstantPage* page,
164 const content::WebContents* contents) {
165 return page && (page->contents() == contents);
166 }
167
162 } // namespace 168 } // namespace
163 169
164 // static 170 // static
165 const char* InstantController::kLocalOmniboxPopupURL = 171 const char* InstantController::kLocalOmniboxPopupURL =
166 "chrome://local-omnibox-popup/local-omnibox-popup.html"; 172 "chrome://local-omnibox-popup/local-omnibox-popup.html";
167 173
168 InstantController::InstantController(chrome::BrowserInstantController* browser, 174 InstantController::InstantController(chrome::BrowserInstantController* browser,
169 bool extended_enabled, 175 bool extended_enabled,
170 bool use_local_preview_only) 176 bool use_local_preview_only)
171 : browser_(browser), 177 : browser_(browser),
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
208 << is_keyword_search; 214 << is_keyword_search;
209 215
210 // TODO(dhollowa): Complete keyword match UI. For now just hide suggestions. 216 // TODO(dhollowa): Complete keyword match UI. For now just hide suggestions.
211 // http://crbug.com/153932. Note, this early escape is happens prior to the 217 // http://crbug.com/153932. Note, this early escape is happens prior to the
212 // DCHECKs below because |user_text| and |full_text| have different semantics 218 // DCHECKs below because |user_text| and |full_text| have different semantics
213 // when keyword search is in effect. 219 // when keyword search is in effect.
214 if (is_keyword_search) { 220 if (is_keyword_search) {
215 if (instant_tab_) 221 if (instant_tab_)
216 instant_tab_->Update(string16(), 0, 0, true); 222 instant_tab_->Update(string16(), 0, 0, true);
217 else 223 else
218 HideLoader(); 224 HideOverlay();
219 last_match_was_search_ = false; 225 last_match_was_search_ = false;
220 return false; 226 return false;
221 } 227 }
222 228
223 // If the popup is open, the user has to be typing. 229 // If the popup is open, the user has to be typing.
224 DCHECK(!omnibox_popup_is_open || user_input_in_progress); 230 DCHECK(!omnibox_popup_is_open || user_input_in_progress);
225 231
226 // If the popup is closed, there should be no inline autocompletion. 232 // If the popup is closed, there should be no inline autocompletion.
227 DCHECK(omnibox_popup_is_open || user_text.empty() || user_text == full_text) 233 DCHECK(omnibox_popup_is_open || user_text.empty() || user_text == full_text)
228 << user_text << "|" << full_text; 234 << user_text << "|" << full_text;
229 235
230 // If there's no text in the omnibox, the user can't have typed any. 236 // If there's no text in the omnibox, the user can't have typed any.
231 DCHECK(!full_text.empty() || user_text.empty()) << user_text; 237 DCHECK(!full_text.empty() || user_text.empty()) << user_text;
232 238
233 // If the user isn't typing, and the popup is closed, there can't be any 239 // If the user isn't typing, and the popup is closed, there can't be any
234 // user-typed text. 240 // user-typed text.
235 DCHECK(user_input_in_progress || omnibox_popup_is_open || user_text.empty()) 241 DCHECK(user_input_in_progress || omnibox_popup_is_open || user_text.empty())
236 << user_text; 242 << user_text;
237 243
238 // The preview is being clicked and will commit soon. Don't change anything. 244 // The preview is being clicked and will commit soon. Don't change anything.
239 // TODO(sreeram): Add a browser test for this. 245 // TODO(sreeram): Add a browser test for this.
240 if (loader_ && loader_->is_pointer_down_from_activate()) 246 if (overlay_ && overlay_->is_pointer_down_from_activate())
241 return false; 247 return false;
242 248
243 // In non-extended mode, SearchModeChanged() is never called, so fake it. The 249 // In non-extended mode, SearchModeChanged() is never called, so fake it. The
244 // mode is set to "disallow suggestions" here, so that if one of the early 250 // mode is set to "disallow suggestions" here, so that if one of the early
245 // "return false" conditions is hit, suggestions will be disallowed. If the 251 // "return false" conditions is hit, suggestions will be disallowed. If the
246 // query is sent to the loader, the mode is set to "allow" further below. 252 // query is sent to the overlay, the mode is set to "allow" further below.
247 if (!extended_enabled_) 253 if (!extended_enabled_)
248 search_mode_.mode = chrome::search::Mode::MODE_DEFAULT; 254 search_mode_.mode = chrome::search::Mode::MODE_DEFAULT;
249 255
250 last_match_was_search_ = AutocompleteMatch::IsSearchType(match.type) && 256 last_match_was_search_ = AutocompleteMatch::IsSearchType(match.type) &&
251 !user_text.empty(); 257 !user_text.empty();
252 258
253 if (!ResetLoaderForMatch(match)) { 259 if (!ResetOverlayForMatch(match)) {
254 HideLoader(); 260 HideOverlay();
255 return false; 261 return false;
256 } 262 }
257 263
258 if (extended_enabled_) { 264 if (extended_enabled_) {
259 if (!omnibox_popup_is_open) { 265 if (!omnibox_popup_is_open) {
260 if (!user_input_in_progress) { 266 if (!user_input_in_progress) {
261 // If the user isn't typing and the omnibox popup is closed, it means a 267 // If the user isn't typing and the omnibox popup is closed, it means a
262 // regular navigation, tab-switch or the user hitting Escape. 268 // regular navigation, tab-switch or the user hitting Escape.
263 if (instant_tab_) { 269 if (instant_tab_) {
264 // The user is on a search results page. It may be showing results for 270 // The user is on a search results page. It may be showing results for
265 // a partial query the user typed before they hit Escape. Send the 271 // a partial query the user typed before they hit Escape. Send the
266 // omnibox text to the page to restore the original results. 272 // omnibox text to the page to restore the original results.
267 // 273 //
268 // In a tab switch, |instant_tab_| won't have updated yet, so it may 274 // In a tab switch, |instant_tab_| won't have updated yet, so it may
269 // be pointing to the previous tab (which was a search results page). 275 // be pointing to the previous tab (which was a search results page).
270 // Ensure we don't send the omnibox text to a random webpage (the new 276 // Ensure we don't send the omnibox text to a random webpage (the new
271 // tab), by comparing the old and new WebContents. 277 // tab), by comparing the old and new WebContents.
272 if (escape_pressed && 278 if (escape_pressed &&
273 instant_tab_->contents() == browser_->GetActiveWebContents()) { 279 instant_tab_->contents() == browser_->GetActiveWebContents()) {
274 instant_tab_->Submit(full_text); 280 instant_tab_->Submit(full_text);
275 } 281 }
276 } else if (!full_text.empty()) { 282 } else if (!full_text.empty()) {
277 // If |full_text| is empty, the user is on the NTP. The preview may 283 // If |full_text| is empty, the user is on the NTP. The preview may
278 // be showing custom NTP content; hide only if that's not the case. 284 // be showing custom NTP content; hide only if that's not the case.
279 HideLoader(); 285 HideOverlay();
280 } 286 }
281 } else if (full_text.empty()) { 287 } else if (full_text.empty()) {
282 // The user is typing, and backspaced away all omnibox text. Clear 288 // The user is typing, and backspaced away all omnibox text. Clear
283 // |last_omnibox_text_| so that we don't attempt to set suggestions. 289 // |last_omnibox_text_| so that we don't attempt to set suggestions.
284 last_omnibox_text_.clear(); 290 last_omnibox_text_.clear();
285 last_suggestion_ = InstantSuggestion(); 291 last_suggestion_ = InstantSuggestion();
286 if (instant_tab_) { 292 if (instant_tab_) {
287 // On a search results page, tell it to clear old results. 293 // On a search results page, tell it to clear old results.
288 instant_tab_->Update(string16(), 0, 0, true); 294 instant_tab_->Update(string16(), 0, 0, true);
289 } else if (search_mode_.is_origin_ntp()) { 295 } else if (search_mode_.is_origin_ntp()) {
290 // On the NTP, tell the preview to clear old results. Don't hide the 296 // On the NTP, tell the preview to clear old results. Don't hide the
291 // preview so it can show a blank page or logo if it wants. 297 // preview so it can show a blank page or logo if it wants.
292 loader_->Update(string16(), 0, 0, true); 298 overlay_->Update(string16(), 0, 0, true);
293 } else { 299 } else {
294 HideLoader(); 300 HideOverlay();
295 } 301 }
296 } else { 302 } else {
297 // The user switched to a tab with partial text already in the omnibox. 303 // The user switched to a tab with partial text already in the omnibox.
298 HideLoader(); 304 HideOverlay();
299 305
300 // The new tab may or may not be a search results page; we don't know 306 // The new tab may or may not be a search results page; we don't know
301 // since SearchModeChanged() hasn't been called yet. If it later turns 307 // since SearchModeChanged() hasn't been called yet. If it later turns
302 // out to be, we should store |full_text| now, so that if the user hits 308 // out to be, we should store |full_text| now, so that if the user hits
303 // Enter, we'll send the correct query to instant_tab_->Submit(). If the 309 // Enter, we'll send the correct query to instant_tab_->Submit(). If the
304 // partial text is not a query (|last_match_was_search_| is false), we 310 // partial text is not a query (|last_match_was_search_| is false), we
305 // won't Submit(), so no need to worry about that. 311 // won't Submit(), so no need to worry about that.
306 last_omnibox_text_ = full_text; 312 last_omnibox_text_ = full_text;
307 last_suggestion_ = InstantSuggestion(); 313 last_suggestion_ = InstantSuggestion();
308 } 314 }
309 return false; 315 return false;
310 } else if (full_text.empty()) { 316 } else if (full_text.empty()) {
311 // The user typed a solitary "?". Same as the backspace case above. 317 // The user typed a solitary "?". Same as the backspace case above.
312 last_omnibox_text_.clear(); 318 last_omnibox_text_.clear();
313 last_suggestion_ = InstantSuggestion(); 319 last_suggestion_ = InstantSuggestion();
314 if (instant_tab_) 320 if (instant_tab_)
315 instant_tab_->Update(string16(), 0, 0, true); 321 instant_tab_->Update(string16(), 0, 0, true);
316 else if (search_mode_.is_origin_ntp()) 322 else if (search_mode_.is_origin_ntp())
317 loader_->Update(string16(), 0, 0, true); 323 overlay_->Update(string16(), 0, 0, true);
318 else 324 else
319 HideLoader(); 325 HideOverlay();
320 return false; 326 return false;
321 } 327 }
322 } else if (!omnibox_popup_is_open || full_text.empty()) { 328 } else if (!omnibox_popup_is_open || full_text.empty()) {
323 // In the non-extended case, hide the preview as long as the user isn't 329 // In the non-extended case, hide the preview as long as the user isn't
324 // actively typing a non-empty query. 330 // actively typing a non-empty query.
325 HideLoader(); 331 HideOverlay();
326 return false; 332 return false;
327 } 333 }
328 334
329 last_omnibox_text_has_inline_autocompletion_ = user_text != full_text; 335 last_omnibox_text_has_inline_autocompletion_ = user_text != full_text;
330 336
331 // If the user continues typing the same query as the suggested text is 337 // If the user continues typing the same query as the suggested text is
332 // showing, reuse the suggestion (but only for INSTANT_COMPLETE_NEVER). 338 // showing, reuse the suggestion (but only for INSTANT_COMPLETE_NEVER).
333 bool reused_suggestion = false; 339 bool reused_suggestion = false;
334 if (last_suggestion_.behavior == INSTANT_COMPLETE_NEVER && 340 if (last_suggestion_.behavior == INSTANT_COMPLETE_NEVER &&
335 !last_omnibox_text_has_inline_autocompletion_) { 341 !last_omnibox_text_has_inline_autocompletion_) {
(...skipping 23 matching lines...) Expand all
359 365
360 last_transition_type_ = match.transition; 366 last_transition_type_ = match.transition;
361 url_for_history_ = match.destination_url; 367 url_for_history_ = match.destination_url;
362 368
363 // Allow search suggestions. In extended mode, SearchModeChanged() will set 369 // Allow search suggestions. In extended mode, SearchModeChanged() will set
364 // this, but it's not called in non-extended mode, so fake it. 370 // this, but it's not called in non-extended mode, so fake it.
365 if (!extended_enabled_) 371 if (!extended_enabled_)
366 search_mode_.mode = chrome::search::Mode::MODE_SEARCH_SUGGESTIONS; 372 search_mode_.mode = chrome::search::Mode::MODE_SEARCH_SUGGESTIONS;
367 373
368 if (instant_tab_) { 374 if (instant_tab_) {
369 instant_tab_->Update(user_text, selection_start, selection_end, verbatim); 375 instant_tab_->Update(user_text, selection_start,
376 selection_end, verbatim);
370 } else { 377 } else {
371 if (first_interaction_time_.is_null()) 378 if (first_interaction_time_.is_null())
372 first_interaction_time_ = base::Time::Now(); 379 first_interaction_time_ = base::Time::Now();
373 allow_preview_to_show_search_suggestions_ = true; 380 allow_preview_to_show_search_suggestions_ = true;
374 loader_->Update(extended_enabled_ ? user_text : full_text, 381 overlay_->Update(extended_enabled_ ? user_text : full_text,
375 selection_start, selection_end, verbatim); 382 selection_start, selection_end, verbatim);
376 } 383 }
377 384
378 content::NotificationService::current()->Notify( 385 content::NotificationService::current()->Notify(
379 chrome::NOTIFICATION_INSTANT_CONTROLLER_UPDATED, 386 chrome::NOTIFICATION_INSTANT_CONTROLLER_UPDATED,
380 content::Source<InstantController>(this), 387 content::Source<InstantController>(this),
381 content::NotificationService::NoDetails()); 388 content::NotificationService::NoDetails());
382 389
383 // We don't have new suggestions yet, but we can either reuse the existing 390 // We don't have new suggestions yet, but we can either reuse the existing
384 // suggestion or reset the existing "gray text". 391 // suggestion or reset the existing "gray text".
385 browser_->SetInstantSuggestion(last_suggestion_); 392 browser_->SetInstantSuggestion(last_suggestion_);
386 393
387 return true; 394 return true;
388 } 395 }
389 396
397 content::WebContents* InstantController::ReleaseNTPContents() {
398 if (!extended_enabled_ || !ntp_)
dhollowa 2013/01/22 22:34:58 Should this be a DCHECK? Should the caller be ask
samarth 2013/01/25 21:08:40 There are legitimate cases where this can happen (
399 return NULL;
400
401 content::WebContents* ntp_contents = ntp_->ReleaseContents();
402 ntp_.reset();
403 ResetNTP();
404 return ntp_contents;
405 }
406
390 // TODO(tonyg): This method only fires when the omnibox bounds change. It also 407 // TODO(tonyg): This method only fires when the omnibox bounds change. It also
391 // needs to fire when the preview bounds change (e.g.: open/close info bar). 408 // needs to fire when the preview bounds change (e.g.: open/close info bar).
392 void InstantController::SetPopupBounds(const gfx::Rect& bounds) { 409 void InstantController::SetPopupBounds(const gfx::Rect& bounds) {
393 if (!extended_enabled_ && !instant_enabled_) 410 if (!extended_enabled_ && !instant_enabled_)
394 return; 411 return;
395 412
396 if (popup_bounds_ == bounds) 413 if (popup_bounds_ == bounds)
397 return; 414 return;
398 415
399 popup_bounds_ = bounds; 416 popup_bounds_ = bounds;
400 if (popup_bounds_.height() > last_popup_bounds_.height()) { 417 if (popup_bounds_.height() > last_popup_bounds_.height()) {
401 update_bounds_timer_.Stop(); 418 update_bounds_timer_.Stop();
402 SendPopupBoundsToPage(); 419 SendPopupBoundsToPage();
403 } else if (!update_bounds_timer_.IsRunning()) { 420 } else if (!update_bounds_timer_.IsRunning()) {
404 update_bounds_timer_.Start(FROM_HERE, 421 update_bounds_timer_.Start(FROM_HERE,
405 base::TimeDelta::FromMilliseconds(kUpdateBoundsDelayMS), this, 422 base::TimeDelta::FromMilliseconds(kUpdateBoundsDelayMS), this,
406 &InstantController::SendPopupBoundsToPage); 423 &InstantController::SendPopupBoundsToPage);
407 } 424 }
408 } 425 }
409 426
410 void InstantController::SetMarginSize(int start, int end) { 427 void InstantController::SetMarginSize(int start, int end) {
411 if (!extended_enabled_ || (start_margin_ == start && end_margin_ == end)) 428 if (!extended_enabled_ || (start_margin_ == start && end_margin_ == end))
412 return; 429 return;
413 430
414 start_margin_ = start; 431 start_margin_ = start;
415 end_margin_ = end; 432 end_margin_ = end;
416 if (loader_) 433 if (overlay_)
417 loader_->SetMarginSize(start_margin_, end_margin_); 434 overlay_->SetMarginSize(start_margin_, end_margin_);
435 if (ntp_)
436 ntp_->SetMarginSize(start_margin_, end_margin_);
418 if (instant_tab_) 437 if (instant_tab_)
419 instant_tab_->SetMarginSize(start_margin_, end_margin_); 438 instant_tab_->SetMarginSize(start_margin_, end_margin_);
420 } 439 }
421 440
422 void InstantController::HandleAutocompleteResults( 441 void InstantController::HandleAutocompleteResults(
423 const std::vector<AutocompleteProvider*>& providers) { 442 const std::vector<AutocompleteProvider*>& providers) {
424 if (!extended_enabled_) 443 if (!extended_enabled_)
425 return; 444 return;
426 445
427 if (!instant_tab_ && !loader_) 446 if (!instant_tab_ && !overlay_)
428 return; 447 return;
429 448
430 DVLOG(1) << "AutocompleteResults:"; 449 DVLOG(1) << "AutocompleteResults:";
431 std::vector<InstantAutocompleteResult> results; 450 std::vector<InstantAutocompleteResult> results;
432 for (ACProviders::const_iterator provider = providers.begin(); 451 for (ACProviders::const_iterator provider = providers.begin();
433 provider != providers.end(); ++provider) { 452 provider != providers.end(); ++provider) {
434 for (ACMatches::const_iterator match = (*provider)->matches().begin(); 453 for (ACMatches::const_iterator match = (*provider)->matches().begin();
435 match != (*provider)->matches().end(); ++match) { 454 match != (*provider)->matches().end(); ++match) {
436 InstantAutocompleteResult result; 455 InstantAutocompleteResult result;
437 result.provider = UTF8ToUTF16((*provider)->GetName()); 456 result.provider = UTF8ToUTF16((*provider)->GetName());
438 result.type = UTF8ToUTF16(AutocompleteMatch::TypeToString(match->type)); 457 result.type = UTF8ToUTF16(AutocompleteMatch::TypeToString(match->type));
439 result.description = match->description; 458 result.description = match->description;
440 result.destination_url = UTF8ToUTF16(match->destination_url.spec()); 459 result.destination_url = UTF8ToUTF16(match->destination_url.spec());
441 result.transition = match->transition; 460 result.transition = match->transition;
442 result.relevance = match->relevance; 461 result.relevance = match->relevance;
443 DVLOG(1) << " " << result.relevance << " " << result.type << " " 462 DVLOG(1) << " " << result.relevance << " " << result.type << " "
444 << result.provider << " " << result.destination_url << " '" 463 << result.provider << " " << result.destination_url << " '"
445 << result.description << "' " << result.transition; 464 << result.description << "' " << result.transition;
446 results.push_back(result); 465 results.push_back(result);
447 } 466 }
448 } 467 }
449 468
450 if (instant_tab_) 469 if (instant_tab_)
451 instant_tab_->SendAutocompleteResults(results); 470 instant_tab_->SendAutocompleteResults(results);
452 else 471 else
453 loader_->SendAutocompleteResults(results); 472 overlay_->SendAutocompleteResults(results);
454 } 473 }
455 474
456 bool InstantController::OnUpOrDownKeyPressed(int count) { 475 bool InstantController::OnUpOrDownKeyPressed(int count) {
457 if (!extended_enabled_) 476 if (!extended_enabled_)
458 return false; 477 return false;
459 478
460 if (!instant_tab_ && !loader_) 479 if (!instant_tab_ && !overlay_)
461 return false; 480 return false;
462 481
463 if (instant_tab_) 482 if (instant_tab_)
464 instant_tab_->UpOrDownKeyPressed(count); 483 instant_tab_->UpOrDownKeyPressed(count);
465 else 484 else
466 loader_->UpOrDownKeyPressed(count); 485 overlay_->UpOrDownKeyPressed(count);
467 486
468 return true; 487 return true;
469 } 488 }
470 489
471 content::WebContents* InstantController::GetPreviewContents() const { 490 content::WebContents* InstantController::GetPreviewContents() const {
472 return loader_ ? loader_->contents() : NULL; 491 return overlay_ ? overlay_->contents() : NULL;
473 } 492 }
474 493
475 bool InstantController::IsPreviewingSearchResults() const { 494 bool InstantController::IsPreviewingSearchResults() const {
476 return model_.mode().is_search_suggestions() && IsFullHeight(model_) && 495 return model_.mode().is_search_suggestions() && IsFullHeight(model_) &&
477 (last_match_was_search_ || 496 (last_match_was_search_ ||
478 last_suggestion_.behavior == INSTANT_COMPLETE_NEVER); 497 last_suggestion_.behavior == INSTANT_COMPLETE_NEVER);
479 } 498 }
480 499
481 bool InstantController::CommitIfPossible(InstantCommitType type) { 500 bool InstantController::CommitIfPossible(InstantCommitType type) {
482 if (!extended_enabled_ && !instant_enabled_) 501 if (!extended_enabled_ && !instant_enabled_)
(...skipping 14 matching lines...) Expand all
497 return true; 516 return true;
498 } 517 }
499 return false; 518 return false;
500 } 519 }
501 520
502 if (!IsPreviewingSearchResults() && type != INSTANT_COMMIT_NAVIGATED) 521 if (!IsPreviewingSearchResults() && type != INSTANT_COMMIT_NAVIGATED)
503 return false; 522 return false;
504 523
505 // There may re-entrance here, from the call to browser_->CommitInstant below, 524 // There may re-entrance here, from the call to browser_->CommitInstant below,
506 // which can cause a TabDeactivated notification which gets back here. 525 // which can cause a TabDeactivated notification which gets back here.
507 // In this case, loader_->ReleaseContents() was called already. 526 // In this case, overlay_->ReleaseContents() was called already.
508 if (!GetPreviewContents()) 527 if (!GetPreviewContents())
509 return false; 528 return false;
510 529
511 // Never commit the local omnibox. 530 // Never commit the local omnibox.
512 if (loader_->IsUsingLocalPreview()) 531 if (overlay_->IsUsingLocalPreview())
513 return false; 532 return false;
514 533
515 if (type == INSTANT_COMMIT_FOCUS_LOST) 534 if (type == INSTANT_COMMIT_FOCUS_LOST)
516 loader_->Cancel(last_omnibox_text_); 535 overlay_->Cancel(last_omnibox_text_);
517 else if (type != INSTANT_COMMIT_NAVIGATED && 536 else if (type != INSTANT_COMMIT_NAVIGATED &&
518 type != INSTANT_COMMIT_CLICKED_QUERY_SUGGESTION) 537 type != INSTANT_COMMIT_CLICKED_QUERY_SUGGESTION)
519 loader_->Submit(last_omnibox_text_); 538 overlay_->Submit(last_omnibox_text_);
520 539
521 content::WebContents* preview = loader_->ReleaseContents(); 540 content::WebContents* preview = overlay_->ReleaseContents();
522 541
523 if (extended_enabled_) { 542 if (extended_enabled_) {
524 // Consider what's happening: 543 // Consider what's happening:
525 // 1. The user has typed a query in the omnibox and committed it (either 544 // 1. The user has typed a query in the omnibox and committed it (either
526 // by pressing Enter or clicking on the preview). 545 // by pressing Enter or clicking on the preview).
527 // 2. We commit the preview to the tab strip, and tell the page. 546 // 2. We commit the preview to the tab strip, and tell the page.
528 // 3. The page will update the URL hash fragment with the query terms. 547 // 3. The page will update the URL hash fragment with the query terms.
529 // After steps 1 and 3, the omnibox will show the query terms. However, if 548 // After steps 1 and 3, the omnibox will show the query terms. However, if
530 // the URL we are committing at step 2 doesn't already have query terms, it 549 // the URL we are committing at step 2 doesn't already have query terms, it
531 // will flash for a brief moment as a plain URL. So, avoid that flicker by 550 // will flash for a brief moment as a plain URL. So, avoid that flicker by
(...skipping 17 matching lines...) Expand all
549 net::EscapeQueryParamValue(query, true))); 568 net::EscapeQueryParamValue(query, true)));
550 chrome::search::SearchTabHelper::FromWebContents(preview)-> 569 chrome::search::SearchTabHelper::FromWebContents(preview)->
551 NavigationEntryUpdated(); 570 NavigationEntryUpdated();
552 } 571 }
553 } 572 }
554 573
555 // If the preview page has navigated since the last Update(), we need to add 574 // If the preview page has navigated since the last Update(), we need to add
556 // the navigation to history ourselves. Else, the page will navigate after 575 // the navigation to history ourselves. Else, the page will navigate after
557 // commit, and it will be added to history in the usual manner. 576 // commit, and it will be added to history in the usual manner.
558 const history::HistoryAddPageArgs& last_navigation = 577 const history::HistoryAddPageArgs& last_navigation =
559 loader_->last_navigation(); 578 overlay_->last_navigation();
560 if (!last_navigation.url.is_empty()) { 579 if (!last_navigation.url.is_empty()) {
561 content::NavigationEntry* entry = preview->GetController().GetActiveEntry(); 580 content::NavigationEntry* entry = preview->GetController().GetActiveEntry();
562 581
563 // The last navigation should be the same as the active entry if the loader 582 // The last navigation should be the same as the active entry if the overlay
564 // is in search mode. During navigation, the active entry could have 583 // is in search mode. During navigation, the active entry could have
565 // changed since DidCommitProvisionalLoadForFrame is called after the entry 584 // changed since DidCommitProvisionalLoadForFrame is called after the entry
566 // is changed. 585 // is changed.
567 // TODO(shishir): Should we commit the last navigation for 586 // TODO(shishir): Should we commit the last navigation for
568 // INSTANT_COMMIT_NAVIGATED. 587 // INSTANT_COMMIT_NAVIGATED.
569 DCHECK(type == INSTANT_COMMIT_NAVIGATED || 588 DCHECK(type == INSTANT_COMMIT_NAVIGATED ||
570 last_navigation.url == entry->GetURL()); 589 last_navigation.url == entry->GetURL());
571 590
572 // Add the page to history. 591 // Add the page to history.
573 HistoryTabHelper* history_tab_helper = 592 HistoryTabHelper* history_tab_helper =
(...skipping 25 matching lines...) Expand all
599 } 618 }
600 619
601 // Browser takes ownership of the preview. 620 // Browser takes ownership of the preview.
602 browser_->CommitInstant(preview, type == INSTANT_COMMIT_PRESSED_ALT_ENTER); 621 browser_->CommitInstant(preview, type == INSTANT_COMMIT_PRESSED_ALT_ENTER);
603 622
604 content::NotificationService::current()->Notify( 623 content::NotificationService::current()->Notify(
605 chrome::NOTIFICATION_INSTANT_COMMITTED, 624 chrome::NOTIFICATION_INSTANT_COMMITTED,
606 content::Source<content::WebContents>(preview), 625 content::Source<content::WebContents>(preview),
607 content::NotificationService::NoDetails()); 626 content::NotificationService::NoDetails());
608 627
609 // Hide explicitly. See comments in HideLoader() for why. 628 // Hide explicitly. See comments in HideOverlay() for why.
610 model_.SetPreviewState(chrome::search::Mode(), 0, INSTANT_SIZE_PERCENT); 629 model_.SetPreviewState(chrome::search::Mode(), 0, INSTANT_SIZE_PERCENT);
611 630
612 // Delay deletion as we could've gotten here from an InstantLoader method. 631 // Delay deletion as we could've gotten here from an InstantOverlay method.
613 MessageLoop::current()->DeleteSoon(FROM_HERE, loader_.release()); 632 MessageLoop::current()->DeleteSoon(FROM_HERE, overlay_.release());
614 633
615 // Try to create another loader immediately so that it is ready for the next 634 // Try to create another overlay immediately so that it is ready for the next
616 // user interaction. 635 // user interaction.
617 CreateDefaultLoader(); 636 CreateDefaultOverlay();
618 637
619 return true; 638 return true;
620 } 639 }
621 640
622 void InstantController::OmniboxFocusChanged( 641 void InstantController::OmniboxFocusChanged(
623 OmniboxFocusState state, 642 OmniboxFocusState state,
624 OmniboxFocusChangeReason reason, 643 OmniboxFocusChangeReason reason,
625 gfx::NativeView view_gaining_focus) { 644 gfx::NativeView view_gaining_focus) {
626 DVLOG(1) << "OmniboxFocusChanged: " << omnibox_focus_state_ << " to " 645 DVLOG(1) << "OmniboxFocusChanged: " << omnibox_focus_state_ << " to "
627 << state << " for reason " << reason; 646 << state << " for reason " << reason;
628 647
629 OmniboxFocusState old_focus_state = omnibox_focus_state_; 648 OmniboxFocusState old_focus_state = omnibox_focus_state_;
630 omnibox_focus_state_ = state; 649 omnibox_focus_state_ = state;
631 if (!extended_enabled_ && !instant_enabled_) 650 if (!extended_enabled_ && !instant_enabled_)
632 return; 651 return;
633 652
634 // Tell the page if the key capture mode changed unless the focus state 653 // Tell the page if the key capture mode changed unless the focus state
635 // changed because of TYPING. This is because in that case, the browser hasn't 654 // changed because of TYPING. This is because in that case, the browser hasn't
636 // really stopped capturing key strokes. 655 // really stopped capturing key strokes.
637 // 656 //
638 // (More practically, if we don't do this check, the page would receive 657 // (More practically, if we don't do this check, the page would receive
639 // onkeycapturechange before the corresponding onchange, and the page would 658 // onkeycapturechange before the corresponding onchange, and the page would
640 // have no way of telling whether the keycapturechange happened because of 659 // have no way of telling whether the keycapturechange happened because of
641 // some actual user action or just because they started typing.) 660 // some actual user action or just because they started typing.)
642 if (extended_enabled_ && GetPreviewContents() && 661 if (extended_enabled_ && GetPreviewContents() &&
643 reason != OMNIBOX_FOCUS_CHANGE_TYPING) 662 reason != OMNIBOX_FOCUS_CHANGE_TYPING) {
644 loader_->KeyCaptureChanged(omnibox_focus_state_ == OMNIBOX_FOCUS_INVISIBLE); 663 const bool is_key_capture_enabled =
664 omnibox_focus_state_ == OMNIBOX_FOCUS_INVISIBLE;
665 if (overlay_)
666 overlay_->KeyCaptureChanged(is_key_capture_enabled);
667 if (instant_tab_)
668 instant_tab_->KeyCaptureChanged(is_key_capture_enabled);
669 }
645 670
646 // If focus went from outside the omnibox to the omnibox, preload the default 671 // If focus went from outside the omnibox to the omnibox, preload the default
647 // search engine, in anticipation of the user typing a query. If the reverse 672 // search engine, in anticipation of the user typing a query. If the reverse
648 // happened, commit or discard the preview. 673 // happened, commit or discard the preview.
649 if (state != OMNIBOX_FOCUS_NONE && old_focus_state == OMNIBOX_FOCUS_NONE) 674 if (state != OMNIBOX_FOCUS_NONE && old_focus_state == OMNIBOX_FOCUS_NONE)
650 CreateDefaultLoader(); 675 CreateDefaultOverlay();
651 else if (state == OMNIBOX_FOCUS_NONE && old_focus_state != OMNIBOX_FOCUS_NONE) 676 else if (state == OMNIBOX_FOCUS_NONE && old_focus_state != OMNIBOX_FOCUS_NONE)
652 OmniboxLostFocus(view_gaining_focus); 677 OmniboxLostFocus(view_gaining_focus);
653 } 678 }
654 679
655 void InstantController::SearchModeChanged( 680 void InstantController::SearchModeChanged(
656 const chrome::search::Mode& old_mode, 681 const chrome::search::Mode& old_mode,
657 const chrome::search::Mode& new_mode) { 682 const chrome::search::Mode& new_mode) {
658 if (!extended_enabled_) 683 if (!extended_enabled_)
659 return; 684 return;
660 685
661 DVLOG(1) << "SearchModeChanged: [origin:mode] " << old_mode.origin << ":" 686 DVLOG(1) << "SearchModeChanged: [origin:mode] " << old_mode.origin << ":"
662 << old_mode.mode << " to " << new_mode.origin << ":" 687 << old_mode.mode << " to " << new_mode.origin << ":"
663 << new_mode.mode; 688 << new_mode.mode;
664 689
665 search_mode_ = new_mode; 690 search_mode_ = new_mode;
666 if (!new_mode.is_search_suggestions()) 691 if (!new_mode.is_search_suggestions())
667 HideLoader(); 692 HideOverlay();
668 693
669 if (loader_) 694 if (overlay_)
670 loader_->SearchModeChanged(new_mode); 695 overlay_->SearchModeChanged(new_mode);
671 696
672 ResetInstantTab(); 697 ResetInstantTab();
673 } 698 }
674 699
675 void InstantController::ActiveTabChanged() { 700 void InstantController::ActiveTabChanged() {
676 if (!extended_enabled_ && !instant_enabled_) 701 if (!extended_enabled_ && !instant_enabled_)
677 return; 702 return;
678 703
679 DVLOG(1) << "ActiveTabChanged"; 704 DVLOG(1) << "ActiveTabChanged";
680 705
681 // When switching tabs, always hide the preview, except if it's showing NTP 706 // When switching tabs, always hide the preview.
682 // content, and the new tab is also an NTP. 707 HideOverlay();
683 if (!search_mode_.is_ntp() || !model_.mode().is_ntp())
684 HideLoader();
685 708
686 if (extended_enabled_) 709 if (extended_enabled_)
687 ResetInstantTab(); 710 ResetInstantTab();
688 } 711 }
689 712
690 void InstantController::TabDeactivated(content::WebContents* contents) { 713 void InstantController::TabDeactivated(content::WebContents* contents) {
691 DVLOG(1) << "TabDeactivated"; 714 DVLOG(1) << "TabDeactivated";
692 if (extended_enabled_ && !contents->IsBeingDestroyed()) 715 if (extended_enabled_ && !contents->IsBeingDestroyed())
693 CommitIfPossible(INSTANT_COMMIT_FOCUS_LOST); 716 CommitIfPossible(INSTANT_COMMIT_FOCUS_LOST);
694 } 717 }
695 718
696 void InstantController::SetInstantEnabled(bool instant_enabled) { 719 void InstantController::SetInstantEnabled(bool instant_enabled) {
697 DVLOG(1) << "SetInstantEnabled: " << instant_enabled; 720 DVLOG(1) << "SetInstantEnabled: " << instant_enabled;
698 instant_enabled_ = instant_enabled; 721 instant_enabled_ = instant_enabled;
699 HideInternal(); 722 HideInternal();
700 loader_.reset(); 723 overlay_.reset();
701 if (extended_enabled_ || instant_enabled_) 724 if (extended_enabled_ || instant_enabled_)
702 CreateDefaultLoader(); 725 CreateDefaultOverlay();
726 if (extended_enabled_)
727 ResetNTP();
703 if (instant_tab_) 728 if (instant_tab_)
704 instant_tab_->SetDisplayInstantResults(instant_enabled_); 729 instant_tab_->SetDisplayInstantResults(instant_enabled_);
705 } 730 }
706 731
707 void InstantController::ThemeChanged(const ThemeBackgroundInfo& theme_info) { 732 void InstantController::ThemeChanged(const ThemeBackgroundInfo& theme_info) {
708 if (!extended_enabled_) 733 if (!extended_enabled_)
709 return; 734 return;
710 735
711 if (loader_) 736 if (overlay_)
712 loader_->SendThemeBackgroundInfo(theme_info); 737 overlay_->SendThemeBackgroundInfo(theme_info);
738 if (ntp_)
739 ntp_->SendThemeBackgroundInfo(theme_info);
713 } 740 }
714 741
715 void InstantController::ThemeAreaHeightChanged(int height) { 742 void InstantController::ThemeAreaHeightChanged(int height) {
716 if (!extended_enabled_) 743 if (!extended_enabled_)
717 return; 744 return;
718 745
719 if (loader_) 746 if (overlay_)
720 loader_->SendThemeAreaHeight(height); 747 overlay_->SendThemeAreaHeight(height);
748 if (ntp_)
749 ntp_->SendThemeAreaHeight(height);
750 }
751
752 void InstantController::InstantSupportDetermined(
753 const content::WebContents* contents,
754 bool supports_instant) {
755 if (ContentsFrom(instant_tab_.get(), contents)) {
756 if (!supports_instant)
757 MessageLoop::current()->DeleteSoon(FROM_HERE, instant_tab_.release());
758 } else if (ContentsFrom(ntp_.get(), contents)) {
759 if (supports_instant) {
760 RemoveFromBlacklist(ntp_->instant_url());
761 } else {
762 AddToBlacklist(ntp_->instant_url());
763 delete ntp_->ReleaseContents();
dhollowa 2013/01/22 22:34:58 This deletion logic looks similar to :773, :789, :
samarth 2013/01/25 21:08:40 Done.
764 ntp_.reset();
765 ResetNTP();
766 }
767 } else if (ContentsFrom(overlay_.get(), contents)) {
768 if (supports_instant) {
769 RemoveFromBlacklist(overlay_->instant_url());
770 } else {
771 AddToBlacklist(overlay_->instant_url());
772 HideInternal();
773 delete overlay_->ReleaseContents();
774 overlay_.reset();
775 CreateDefaultOverlay();
776 }
777 content::NotificationService::current()->Notify(
778 chrome::NOTIFICATION_INSTANT_SUPPORT_DETERMINED,
779 content::Source<InstantController>(this),
780 content::NotificationService::NoDetails());
781 }
782 }
783
784 void InstantController::InstantPageRenderViewGone(
785 const content::WebContents* contents) {
786 if (ContentsFrom(overlay_.get(), contents)) {
787 AddToBlacklist(overlay_->instant_url());
788 HideInternal();
789 delete overlay_->ReleaseContents();
790 overlay_.reset();
791 CreateDefaultOverlay();
792 } else if (ContentsFrom(ntp_.get(), contents)) {
793 AddToBlacklist(ntp_->instant_url());
794 delete ntp_->ReleaseContents();
795 ntp_.reset();
796 ResetNTP();
797 }
798 }
799
800 void InstantController::InstantPageAboutToNavigateMainFrame(
801 const content::WebContents* contents,
802 const GURL& url) {
803 if (!ContentsFrom(overlay_.get(), contents))
804 return;
805
806 // If the page does not yet support instant, we allow redirects and other
807 // navigations to go through since the instant URL can redirect - e.g. to
808 // country specific pages.
809 if (!overlay_->supports_instant())
810 return;
811
812 GURL instant_url(overlay_->instant_url());
813
814 // If we are navigating to the instant URL, do nothing.
815 if (url == instant_url)
816 return;
817
818 // Commit the navigation if either:
819 // - The page is in NTP mode (so it could only navigate on a user click) or
820 // - The page is not in NTP mode and we are navigating to a URL with a
821 // different host or path than the instant URL. This enables the instant
822 // page when it is showing search results to change the query parameters
823 // and fragments of the URL without it navigating.
824 if (model_.mode().is_ntp() ||
825 (url.host() != instant_url.host() || url.path() != instant_url.path())) {
826 CommitIfPossible(INSTANT_COMMIT_NAVIGATED);
827 }
721 } 828 }
722 829
723 void InstantController::SetSuggestions( 830 void InstantController::SetSuggestions(
724 const content::WebContents* contents, 831 const content::WebContents* contents,
725 const std::vector<InstantSuggestion>& suggestions) { 832 const std::vector<InstantSuggestion>& suggestions) {
726 DVLOG(1) << "SetSuggestions"; 833 DVLOG(1) << "SetSuggestions";
727 834
728 // Ignore if the message is from an unexpected source. 835 // Ignore if the message is from an unexpected source.
729 if (instant_tab_) { 836 if (ContentsFrom(ntp_.get(), contents))
730 if (instant_tab_->contents() != contents)
731 return;
732 } else if (!loader_ || loader_->contents() != contents ||
733 !allow_preview_to_show_search_suggestions_) {
734 return; 837 return;
735 } 838 if (instant_tab_ && !ContentsFrom(instant_tab_.get(), contents))
839 return;
840 if (ContentsFrom(overlay_.get(), contents) &&
841 !allow_preview_to_show_search_suggestions_)
842 return;
736 843
737 InstantSuggestion suggestion; 844 InstantSuggestion suggestion;
738 if (!suggestions.empty()) 845 if (!suggestions.empty())
739 suggestion = suggestions[0]; 846 suggestion = suggestions[0];
740 847
741 if (instant_tab_ && search_mode_.is_search_results() && 848 if (instant_tab_ && search_mode_.is_search_results() &&
742 suggestion.behavior == INSTANT_COMPLETE_REPLACE) { 849 suggestion.behavior == INSTANT_COMPLETE_REPLACE) {
743 // This means a committed page in state search called setValue(). We should 850 // This means a committed page in state search called setValue(). We should
744 // update the omnibox to reflect what the search page says. 851 // update the omnibox to reflect what the search page says.
745 browser_->SetInstantSuggestion(suggestion); 852 browser_->SetInstantSuggestion(suggestion);
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
802 last_suggestion_ = suggestion; 909 last_suggestion_ = suggestion;
803 DVLOG(1) << "SetInstantSuggestion: text='" << suggestion.text << "'" 910 DVLOG(1) << "SetInstantSuggestion: text='" << suggestion.text << "'"
804 << " behavior=" << suggestion.behavior << " type=" 911 << " behavior=" << suggestion.behavior << " type="
805 << suggestion.type; 912 << suggestion.type;
806 browser_->SetInstantSuggestion(suggestion); 913 browser_->SetInstantSuggestion(suggestion);
807 } else { 914 } else {
808 last_suggestion_ = InstantSuggestion(); 915 last_suggestion_ = InstantSuggestion();
809 } 916 }
810 } 917 }
811 918
812 // Extended mode pages will call ShowLoader() when they are ready. 919 // Extended mode pages will call ShowOverlay() when they are ready.
813 if (!extended_enabled_) 920 if (!extended_enabled_)
814 ShowLoader(INSTANT_SHOWN_QUERY_SUGGESTIONS, 100, INSTANT_SIZE_PERCENT); 921 ShowOverlay(INSTANT_SHOWN_QUERY_SUGGESTIONS, 100, INSTANT_SIZE_PERCENT);
815 } 922 }
816 923
817 void InstantController::InstantSupportDetermined( 924 void InstantController::ShowInstantPreview(const content::WebContents* contents,
818 const content::WebContents* contents, 925 InstantShownReason reason,
819 bool supports_instant) { 926 int height,
820 if (instant_tab_ && instant_tab_->contents() == contents) { 927 InstantSizeUnits units) {
821 if (!supports_instant) 928 if (extended_enabled_ && ContentsFrom(overlay_.get(), contents))
822 MessageLoop::current()->DeleteSoon(FROM_HERE, instant_tab_.release()); 929 ShowOverlay(reason, height, units);
930 }
931
932 void InstantController::StartCapturingKeyStrokes(
933 const content::WebContents* contents) {
934 if (!extended_enabled_)
823 return; 935 return;
824 }
825 936
826 if (loader_ && loader_->contents() == contents) { 937 // Only honor the call if it comes from an active InstantTab or from an
827 if (supports_instant) { 938 // InstantOverlay that is being shown.
828 if (blacklisted_urls_.erase(loader_->instant_url())) { 939 if (ContentsFrom(instant_tab_.get(), contents) ||
829 RecordEventHistogram( 940 (ContentsFrom(overlay_.get(), contents) && !model_.mode().is_default())) {
830 INSTANT_CONTROLLER_EVENT_URL_REMOVED_FROM_BLACKLIST); 941 browser_->FocusOmniboxInvisibly();
831 }
832 } else {
833 ++blacklisted_urls_[loader_->instant_url()];
834 RecordEventHistogram(INSTANT_CONTROLLER_EVENT_URL_ADDED_TO_BLACKLIST);
835 HideInternal();
836 delete loader_->ReleaseContents();
837 MessageLoop::current()->DeleteSoon(FROM_HERE, loader_.release());
838 CreateDefaultLoader();
839 }
840 content::NotificationService::current()->Notify(
841 chrome::NOTIFICATION_INSTANT_SUPPORT_DETERMINED,
842 content::Source<InstantController>(this),
843 content::NotificationService::NoDetails());
844 } 942 }
845 } 943 }
846 944
847 void InstantController::ShowInstantPreview(InstantShownReason reason, 945 void InstantController::StopCapturingKeyStrokes(
848 int height, 946 content::WebContents* contents) {
849 InstantSizeUnits units) { 947 // Nothing to do if omnibox doesn't have invisible focus.
850 if (extended_enabled_) 948 if (!extended_enabled_ || omnibox_focus_state_ != OMNIBOX_FOCUS_INVISIBLE)
851 ShowLoader(reason, height, units); 949 return;
950
951 // Only honor the call if it comes from an active InstantTab or from an
952 // InstantOverlay that is being shown.
953 if (ContentsFrom(instant_tab_.get(), contents) ||
954 (ContentsFrom(overlay_.get(), contents) && !model_.mode().is_default())) {
955 contents->Focus();
956 }
852 } 957 }
853 958
854 void InstantController::StartCapturingKeyStrokes() { 959 void InstantController::NavigateToURL(const content::WebContents* contents,
855 // Ignore unless the loader is active and on the NTP. 960 const GURL& url,
856 if (extended_enabled_ && !instant_tab_ && model_.mode().is_ntp()) 961 content::PageTransition transition) {
857 browser_->FocusOmniboxInvisibly(); 962 // TODO(samarth): handle case where contents are no longer "active" (e.g. user
963 // has switched tabs).
964 if (!extended_enabled_)
965 return;
966 if (overlay_)
967 HideOverlay();
968 browser_->OpenURLInCurrentTab(url, transition);
858 } 969 }
859 970
860 void InstantController::StopCapturingKeyStrokes() { 971 void InstantController::OnStalePage(const content::WebContents* contents) {
861 // Ignore unless the loader is active and on the NTP, and the omnibox has 972 if (ContentsFrom(ntp_.get(), contents)) {
862 // invisible focus. 973 if (ntp_->is_stale()) {
863 if (extended_enabled_ && !instant_tab_ && model_.mode().is_ntp() && 974 ntp_.reset();
864 omnibox_focus_state_ == OMNIBOX_FOCUS_INVISIBLE) 975 ResetNTP();
865 loader_->contents()->Focus(); 976 }
977 } else if (ContentsFrom(overlay_.get(), contents)) {
978 OnStaleOverlay();
979 }
866 } 980 }
867 981
868 void InstantController::SwappedWebContents() { 982 void InstantController::InstantPageSwappedContents(
869 model_.SetPreviewContents(GetPreviewContents()); 983 content::WebContents* new_contents) {
984 if (ContentsFrom(overlay_.get(), new_contents))
985 model_.SetPreviewContents(new_contents);
870 } 986 }
871 987
872 void InstantController::InstantLoaderContentsFocused() { 988 void InstantController::InstantPageFocused(
989 const content::WebContents* contents) {
873 #if defined(USE_AURA) 990 #if defined(USE_AURA)
874 // On aura the omnibox only receives a focus lost if we initiate the focus 991 if (ContentsFrom(overlay_.get(), contents)) {
875 // change. This does that. 992 // On aura the omnibox only receives a focus lost if we initiate the focus
876 if (!model_.mode().is_default()) 993 // change. This does that.
877 browser_->InstantPreviewFocused(); 994 if (!model_.mode().is_default())
995 browser_->InstantPreviewFocused();
996 }
878 #endif 997 #endif
879 } 998 }
880 999
881 void InstantController::InstantLoaderRenderViewGone() { 1000 void InstantController::InstantPageClicked(
882 ++blacklisted_urls_[loader_->instant_url()]; 1001 const content::WebContents* contents) {
883 HideInternal(); 1002 if (ContentsFrom(overlay_.get(), contents))
884 delete loader_->ReleaseContents(); 1003 CommitIfPossible(INSTANT_COMMIT_FOCUS_LOST);
885 // Delay deletion as we have gotten here from an InstantLoader method.
886 MessageLoop::current()->DeleteSoon(FROM_HERE, loader_.release());
887 CreateDefaultLoader();
888 } 1004 }
889 1005
890 void InstantController::InstantLoaderAboutToNavigateMainFrame(const GURL& url) { 1006 bool InstantController::InstantPageAboutToOpenURL(
891 // If the page does not yet support instant, we allow redirects and other 1007 const content::WebContents* contents) {
892 // navigations to go through since the instant URL can redirect - e.g. to 1008 // Allow navigation to continue if we can commit the overlay.
893 // country specific pages. 1009 return ContentsFrom(overlay_.get(), contents) &&
894 if (!loader_->supports_instant()) 1010 CommitIfPossible(INSTANT_COMMIT_NAVIGATED);
895 return;
896
897 GURL instant_url(loader_->instant_url());
898
899 // If we are navigating to the instant URL, do nothing.
900 if (url == instant_url)
901 return;
902
903 // Commit the navigation if either:
904 // - The page is in NTP mode (so it could only navigate on a user click) or
905 // - The page is not in NTP mode and we are navigating to a URL with a
906 // different host or path than the instant URL. This enables the instant
907 // page when it is showing search results to change the query parameters
908 // and fragments of the URL without it navigating.
909 if (model_.mode().is_ntp() ||
910 (url.host() != instant_url.host() || url.path() != instant_url.path())) {
911 CommitIfPossible(INSTANT_COMMIT_NAVIGATED);
912 }
913 } 1011 }
914 1012
915 void InstantController::OmniboxLostFocus(gfx::NativeView view_gaining_focus) { 1013 void InstantController::OmniboxLostFocus(gfx::NativeView view_gaining_focus) {
916 // If the preview is showing custom NTP content, don't hide it, commit it 1014 // If the preview is showing custom NTP content, don't hide it, commit it
917 // (no matter where the user clicked) or try to recreate it. 1015 // (no matter where the user clicked) or try to recreate it.
918 if (model_.mode().is_ntp()) 1016 if (model_.mode().is_ntp())
919 return; 1017 return;
920 1018
921 // If the preview is not showing at all, recreate it if it's stale. 1019 // If the preview is not showing at all, recreate it if it's stale.
922 if (model_.mode().is_default()) { 1020 if (model_.mode().is_default()) {
923 OnStaleLoader(); 1021 OnStaleOverlay();
924 return; 1022 return;
925 } 1023 }
926 1024
927 // The preview is showing search suggestions. If GetPreviewContents() is NULL, 1025 // The preview is showing search suggestions. If GetPreviewContents() is NULL,
928 // we are in the commit path. Don't do anything. 1026 // we are in the commit path. Don't do anything.
929 if (!GetPreviewContents()) 1027 if (!GetPreviewContents())
930 return; 1028 return;
931 1029
932 #if defined(OS_MACOSX) 1030 #if defined(OS_MACOSX)
933 // TODO(sreeram): See if Mac really needs this special treatment. 1031 // TODO(sreeram): See if Mac really needs this special treatment.
934 if (!loader_->is_pointer_down_from_activate()) 1032 if (!overlay_->is_pointer_down_from_activate())
935 HideLoader(); 1033 HideOverlay();
936 #else 1034 #else
937 if (IsViewInContents(GetViewGainingFocus(view_gaining_focus), 1035 if (IsViewInContents(GetViewGainingFocus(view_gaining_focus),
938 loader_->contents())) 1036 overlay_->contents()))
939 CommitIfPossible(INSTANT_COMMIT_FOCUS_LOST); 1037 CommitIfPossible(INSTANT_COMMIT_FOCUS_LOST);
940 else 1038 else
941 HideLoader(); 1039 HideOverlay();
942 #endif 1040 #endif
943 } 1041 }
944 1042
945 void InstantController::NavigateToURL(const GURL& url, 1043 void InstantController::OnStaleOverlay() {
946 content::PageTransition transition) { 1044 // The local popup is never stale.
947 if (!extended_enabled_) 1045 if (overlay_ && overlay_->IsUsingLocalPreview())
948 return; 1046 return;
949 if (loader_) 1047
950 HideLoader(); 1048 // If the preview is showing or the omnibox has focus, don't delete the
951 browser_->OpenURLInCurrentTab(url, transition); 1049 // overlay. It will get refreshed the next time the preview is hidden or the
1050 // omnibox loses focus.
1051 if ((!overlay_ || overlay_->is_stale()) &&
1052 omnibox_focus_state_ == OMNIBOX_FOCUS_NONE &&
1053 model_.mode().is_default()) {
1054 overlay_.reset();
1055 CreateDefaultOverlay();
1056 }
952 } 1057 }
953 1058
954 bool InstantController::ResetLoader(const TemplateURL* template_url, 1059 bool InstantController::ResetNTP() {
955 const content::WebContents* active_tab, 1060 const TemplateURL* template_url = TemplateURLServiceFactory::GetForProfile(
956 bool fallback_to_local) { 1061 browser_->profile())->GetDefaultSearchProvider();
1062 std::string instant_url;
1063 if (!GetInstantURL(template_url, &instant_url))
1064 return false;
1065
1066 ntp_.reset(new InstantNTP(this, instant_url));
1067 ntp_->InitContents(browser_->profile(), browser_->GetActiveWebContents());
1068
1069 // Ensure the searchbox API has the correct initial state.
1070 if (extended_enabled_) {
1071 browser_->UpdateThemeInfoForPreview();
1072 ntp_->SetDisplayInstantResults(instant_enabled_);
1073 ntp_->SetMarginSize(start_margin_, end_margin_);
1074 }
1075 return true;
1076 }
1077
1078 bool InstantController::ResetOverlay(const TemplateURL* template_url,
1079 const content::WebContents* active_tab,
1080 bool fallback_to_local) {
957 std::string instant_url; 1081 std::string instant_url;
958 if (!GetInstantURL(template_url, &instant_url)) { 1082 if (!GetInstantURL(template_url, &instant_url)) {
959 if (!fallback_to_local || !extended_enabled_) 1083 if (!fallback_to_local || !extended_enabled_)
960 return false; 1084 return false;
961 1085
962 // If we are in extended mode, fallback to the local popup. 1086 // If we are in extended mode, fallback to the local popup.
963 instant_url = kLocalOmniboxPopupURL; 1087 instant_url = kLocalOmniboxPopupURL;
964 } 1088 }
965 1089
966 if (loader_ && loader_->instant_url() == instant_url) 1090 if (overlay_ && overlay_->instant_url() == instant_url)
967 return true; 1091 return true;
968 1092
969 HideInternal(); 1093 HideInternal();
970 loader_.reset(new InstantLoader(this, instant_url)); 1094 overlay_.reset(new InstantOverlay(this, instant_url));
971 loader_->InitContents(active_tab); 1095 overlay_->InitContents(browser_->profile(), active_tab);
972 1096
973 // Ensure the searchbox API has the correct initial state. 1097 // Ensure the searchbox API has the correct initial state.
974 if (extended_enabled_) { 1098 if (extended_enabled_) {
975 browser_->UpdateThemeInfoForPreview(); 1099 browser_->UpdateThemeInfoForPreview();
976 loader_->SetDisplayInstantResults(instant_enabled_); 1100 overlay_->SetDisplayInstantResults(instant_enabled_);
977 loader_->SearchModeChanged(search_mode_); 1101 overlay_->SearchModeChanged(search_mode_);
978 loader_->KeyCaptureChanged(omnibox_focus_state_ == OMNIBOX_FOCUS_INVISIBLE); 1102 overlay_->KeyCaptureChanged(
979 loader_->SetMarginSize(start_margin_, end_margin_); 1103 omnibox_focus_state_ == OMNIBOX_FOCUS_INVISIBLE);
1104 overlay_->SetMarginSize(start_margin_, end_margin_);
980 } 1105 }
981 1106
982 // Restart the stale loader timer.
983 stale_loader_timer_.Start(FROM_HERE,
984 base::TimeDelta::FromMilliseconds(kStaleLoaderTimeoutMS), this,
985 &InstantController::OnStaleLoader);
986
987 return true; 1107 return true;
988 } 1108 }
989 1109
990 bool InstantController::CreateDefaultLoader() { 1110 bool InstantController::CreateDefaultOverlay() {
991 // If there's no active tab, the browser is closing. 1111 // If there's no active tab, the browser is opening or closing.
992 const content::WebContents* active_tab = browser_->GetActiveWebContents(); 1112 const content::WebContents* active_tab = browser_->GetActiveWebContents();
993 if (!active_tab) 1113 if (!active_tab)
994 return false; 1114 return false;
995 1115
996 const TemplateURL* template_url = TemplateURLServiceFactory::GetForProfile( 1116 const TemplateURL* template_url = TemplateURLServiceFactory::GetForProfile(
997 Profile::FromBrowserContext(active_tab->GetBrowserContext()))-> 1117 Profile::FromBrowserContext(active_tab->GetBrowserContext()))->
998 GetDefaultSearchProvider(); 1118 GetDefaultSearchProvider();
999 1119
1000 return ResetLoader(template_url, active_tab, true); 1120 return ResetOverlay(template_url, active_tab, true);
1001 } 1121 }
1002 1122
1003 void InstantController::OnStaleLoader() { 1123 bool InstantController::ResetOverlayForMatch(const AutocompleteMatch& match) {
1004 // The local popup is never stale. 1124 // If we are on a search results page, we'll use that instead of a overlay.
1005 if (loader_ && loader_->IsUsingLocalPreview())
1006 return;
1007
1008 // If the preview is showing or the omnibox has focus, don't delete the
1009 // loader. It will get refreshed the next time the preview is hidden or the
1010 // omnibox loses focus.
1011 if (!stale_loader_timer_.IsRunning() &&
1012 omnibox_focus_state_ == OMNIBOX_FOCUS_NONE &&
1013 model_.mode().is_default()) {
1014 loader_.reset();
1015 CreateDefaultLoader();
1016 }
1017 }
1018
1019 void InstantController::ResetInstantTab() {
1020 // Do not wire up the InstantTab if instant should only use local previews, to
1021 // prevent it from sending data to the page.
1022 if (search_mode_.is_origin_search() && !use_local_preview_only_) {
1023 content::WebContents* active_tab = browser_->GetActiveWebContents();
1024 if (!instant_tab_ || active_tab != instant_tab_->contents()) {
1025 instant_tab_.reset(new InstantTab(this, active_tab));
1026 instant_tab_->Init();
1027 instant_tab_->SetDisplayInstantResults(instant_enabled_);
1028 instant_tab_->SetMarginSize(start_margin_, end_margin_);
1029 }
1030
1031 // Hide the |loader_| since we are now using |instant_tab_| instead.
1032 HideLoader();
1033 } else {
1034 instant_tab_.reset();
1035 }
1036 }
1037
1038 bool InstantController::ResetLoaderForMatch(const AutocompleteMatch& match) {
1039 // If we are on a search results page, we'll use that instead of a loader.
1040 // TODO(sreeram): If |instant_tab_|'s URL is not the same as the instant_url 1125 // TODO(sreeram): If |instant_tab_|'s URL is not the same as the instant_url
1041 // of |match|, we shouldn't use the committed tab. 1126 // of |match|, we shouldn't use the committed tab.
1042 if (instant_tab_) 1127 if (instant_tab_)
1043 return true; 1128 return true;
1044 1129
1045 // If there's no active tab, the browser is closing. 1130 // If there's no active tab, the browser is closing.
1046 const content::WebContents* active_tab = browser_->GetActiveWebContents(); 1131 const content::WebContents* active_tab = browser_->GetActiveWebContents();
1047 if (!active_tab) 1132 if (!active_tab)
1048 return false; 1133 return false;
1049 1134
1050 // Try to create a loader for the instant_url in the TemplateURL of |match|. 1135 // Try to create a overlay for the instant_url in the TemplateURL of |match|.
1051 // Do not fallback to the local preview because if the keyword specific 1136 // Do not fallback to the local preview because if the keyword specific
1052 // instant URL fails, we want to first try the default instant URL which 1137 // instant URL fails, we want to first try the default instant URL which
1053 // happens in the CreateDefaultLoader call below. 1138 // happens in the CreateDefaultOverlay call below.
1054 const TemplateURL* template_url = match.GetTemplateURL( 1139 const TemplateURL* template_url = match.GetTemplateURL(
1055 Profile::FromBrowserContext(active_tab->GetBrowserContext()), false); 1140 Profile::FromBrowserContext(active_tab->GetBrowserContext()), false);
1056 if (ResetLoader(template_url, active_tab, false)) 1141 if (ResetOverlay(template_url, active_tab, false))
1057 return true; 1142 return true;
1058 1143
1059 // In non-extended mode, stop if we couldn't get a loader for the |match|. 1144 // In non-extended mode, stop if we couldn't get a overlay for the |match|.
1060 if (!extended_enabled_) 1145 if (!extended_enabled_)
1061 return false; 1146 return false;
1062 1147
1063 // If the match is a query, it is for a non-Instant search engine; stop. 1148 // If the match is a query, it is for a non-Instant search engine; stop.
1064 if (last_match_was_search_) 1149 if (last_match_was_search_)
1065 return false; 1150 return false;
1066 1151
1067 // The match is a URL, or a blank query. Try the default search engine. 1152 // The match is a URL, or a blank query. Try the default search engine.
1068 return CreateDefaultLoader(); 1153 return CreateDefaultOverlay();
1069 } 1154 }
1070 1155
1071 void InstantController::HideLoader() { 1156 void InstantController::ResetInstantTab() {
1157 // Do not wire up the InstantTab if instant should only use local previews, to
1158 // prevent it from sending data to the page.
1159 if (!search_mode_.is_origin_default() && !use_local_preview_only_) {
1160 content::WebContents* active_tab = browser_->GetActiveWebContents();
1161 if (!instant_tab_ || active_tab != instant_tab_->contents()) {
1162 instant_tab_.reset(new InstantTab(this));
1163 instant_tab_->Init(active_tab);
1164 instant_tab_->SetDisplayInstantResults(instant_enabled_);
1165 instant_tab_->SetMarginSize(start_margin_, end_margin_);
1166 instant_tab_->KeyCaptureChanged(
1167 omnibox_focus_state_ == OMNIBOX_FOCUS_INVISIBLE);
1168 }
1169
1170 // Hide the |overlay_| since we are now using |instant_tab_| instead.
1171 HideOverlay();
1172 } else {
1173 instant_tab_.reset();
1174 }
1175 }
1176
1177 void InstantController::HideOverlay() {
1072 HideInternal(); 1178 HideInternal();
1073 OnStaleLoader(); 1179 OnStaleOverlay();
1074 } 1180 }
1075 1181
1076 void InstantController::HideInternal() { 1182 void InstantController::HideInternal() {
1077 DVLOG(1) << "Hide"; 1183 DVLOG(1) << "Hide";
1078 1184
1079 // If GetPreviewContents() returns NULL, either we're already in the desired 1185 // If GetPreviewContents() returns NULL, either we're already in the desired
1080 // MODE_DEFAULT state, or we're in the commit path. For the latter, don't 1186 // MODE_DEFAULT state, or we're in the commit path. For the latter, don't
1081 // change the state just yet; else we may hide the preview unnecessarily. 1187 // change the state just yet; else we may hide the preview unnecessarily.
1082 // Instead, the state will be set correctly after the commit is done. 1188 // Instead, the state will be set correctly after the commit is done.
1083 if (GetPreviewContents()) { 1189 if (GetPreviewContents()) {
1084 model_.SetPreviewState(chrome::search::Mode(), 0, INSTANT_SIZE_PERCENT); 1190 model_.SetPreviewState(chrome::search::Mode(), 0, INSTANT_SIZE_PERCENT);
1085 allow_preview_to_show_search_suggestions_ = false; 1191 allow_preview_to_show_search_suggestions_ = false;
1086 1192
1087 // Send a message asking the preview to clear out old results. 1193 // Send a message asking the preview to clear out old results.
1088 loader_->Update(string16(), 0, 0, true); 1194 overlay_->Update(string16(), 0, 0, true);
1089 } 1195 }
1090 1196
1091 // Clear the first interaction timestamp for later use. 1197 // Clear the first interaction timestamp for later use.
1092 first_interaction_time_ = base::Time(); 1198 first_interaction_time_ = base::Time();
1093 } 1199 }
1094 1200
1095 void InstantController::ShowLoader(InstantShownReason reason, 1201 void InstantController::ShowOverlay(InstantShownReason reason,
1096 int height, 1202 int height,
1097 InstantSizeUnits units) { 1203 InstantSizeUnits units) {
1098 // If we are on a committed search results page, the |loader_| is not in use. 1204 // If we are on a committed search results page, the |overlay_| is not in use.
1099 if (instant_tab_) 1205 if (instant_tab_)
1100 return; 1206 return;
1101 1207
1102 DVLOG(1) << "Show: reason=" << reason << " height=" << height << " units=" 1208 DVLOG(1) << "Show: reason=" << reason << " height=" << height << " units="
1103 << units; 1209 << units;
1104 1210
1105 // Must be on NTP to show NTP content. 1211 // INSTANT_SHOWN_CUSTOM_NTP_CONTENT is no longer supported.
1106 if (reason == INSTANT_SHOWN_CUSTOM_NTP_CONTENT && !search_mode_.is_ntp()) 1212 // TODO(samarth): remove once the server has been updated.
1213 if (reason == INSTANT_SHOWN_CUSTOM_NTP_CONTENT)
1107 return; 1214 return;
1108 1215
1109 // Must have updated omnibox after the last HideLoader() to show suggestions. 1216 // Must have updated omnibox after the last HideOverlay() to show suggestions.
1110 if ((reason == INSTANT_SHOWN_QUERY_SUGGESTIONS || 1217 if ((reason == INSTANT_SHOWN_QUERY_SUGGESTIONS ||
1111 reason == INSTANT_SHOWN_CLICKED_QUERY_SUGGESTION) && 1218 reason == INSTANT_SHOWN_CLICKED_QUERY_SUGGESTION) &&
1112 !allow_preview_to_show_search_suggestions_) 1219 !allow_preview_to_show_search_suggestions_)
1113 return; 1220 return;
1114 1221
1115 // The page is trying to hide itself. Hide explicitly (i.e., don't use 1222 // The page is trying to hide itself. Hide explicitly (i.e., don't use
1116 // HideLoader()) so that it can change its mind. 1223 // HideOverlay()) so that it can change its mind.
1117 if (height == 0) { 1224 if (height == 0) {
1118 model_.SetPreviewState(chrome::search::Mode(), 0, INSTANT_SIZE_PERCENT); 1225 model_.SetPreviewState(chrome::search::Mode(), 0, INSTANT_SIZE_PERCENT);
1119 return; 1226 return;
1120 } 1227 }
1121 1228
1122 // If the preview is being shown for the first time since the user started 1229 // If the preview is being shown for the first time since the user started
1123 // typing, record a histogram value. 1230 // typing, record a histogram value.
1124 if (!first_interaction_time_.is_null() && model_.mode().is_default()) { 1231 if (!first_interaction_time_.is_null() && model_.mode().is_default()) {
1125 base::TimeDelta delta = base::Time::Now() - first_interaction_time_; 1232 base::TimeDelta delta = base::Time::Now() - first_interaction_time_;
1126 UMA_HISTOGRAM_TIMES("Instant.TimeToFirstShow", delta); 1233 UMA_HISTOGRAM_TIMES("Instant.TimeToFirstShow", delta);
1127 } 1234 }
1128 1235
1129 // Show at 100% height except in the following cases: 1236 // Show at 100% height except in the following cases:
1130 // - The local omnibox popup is being loaded. 1237 // - The local omnibox popup is being loaded.
1131 // - Instant is disabled. The page needs to be able to show only a dropdown. 1238 // - Instant is disabled. The page needs to be able to show only a dropdown.
1132 // - The page wants to show custom NTP content. 1239 // - The page wants to show custom NTP content.
1133 // - The page is over a website other than search or an NTP, and is not 1240 // - The page is over a website other than search or an NTP, and is not
1134 // already showing at 100% height. 1241 // already showing at 100% height.
1135 if (loader_->IsUsingLocalPreview() || !instant_enabled_ || 1242 if (overlay_->IsUsingLocalPreview() || !instant_enabled_ ||
1136 reason == INSTANT_SHOWN_CUSTOM_NTP_CONTENT || 1243 reason == INSTANT_SHOWN_CUSTOM_NTP_CONTENT ||
1137 (search_mode_.is_origin_default() && !IsFullHeight(model_))) 1244 (search_mode_.is_origin_default() && !IsFullHeight(model_)))
1138 model_.SetPreviewState(search_mode_, height, units); 1245 model_.SetPreviewState(search_mode_, height, units);
1139 else 1246 else
1140 model_.SetPreviewState(search_mode_, 100, INSTANT_SIZE_PERCENT); 1247 model_.SetPreviewState(search_mode_, 100, INSTANT_SIZE_PERCENT);
1141 1248
1142 // If the user clicked on a query suggestion, also go ahead and commit the 1249 // If the user clicked on a query suggestion, also go ahead and commit the
1143 // overlay. This is necessary because if the overlay was partially visible 1250 // overlay. This is necessary because if the overlay was partially visible
1144 // when the suggestion was clicked, the click itself would not commit the 1251 // when the suggestion was clicked, the click itself would not commit the
1145 // overlay (because we're not full height). 1252 // overlay (because we're not full height).
1146 if (reason == INSTANT_SHOWN_CLICKED_QUERY_SUGGESTION) 1253 if (reason == INSTANT_SHOWN_CLICKED_QUERY_SUGGESTION)
1147 CommitIfPossible(INSTANT_COMMIT_CLICKED_QUERY_SUGGESTION); 1254 CommitIfPossible(INSTANT_COMMIT_CLICKED_QUERY_SUGGESTION);
1148 } 1255 }
1149 1256
1150 void InstantController::SendPopupBoundsToPage() { 1257 void InstantController::SendPopupBoundsToPage() {
1151 if (last_popup_bounds_ == popup_bounds_ || !loader_ || 1258 if (last_popup_bounds_ == popup_bounds_ || !overlay_ ||
1152 loader_->is_pointer_down_from_activate()) 1259 overlay_->is_pointer_down_from_activate())
1153 return; 1260 return;
1154 1261
1155 last_popup_bounds_ = popup_bounds_; 1262 last_popup_bounds_ = popup_bounds_;
1156 gfx::Rect preview_bounds = browser_->GetInstantBounds(); 1263 gfx::Rect preview_bounds = browser_->GetInstantBounds();
1157 gfx::Rect intersection = gfx::IntersectRects(popup_bounds_, preview_bounds); 1264 gfx::Rect intersection = gfx::IntersectRects(popup_bounds_, preview_bounds);
1158 1265
1159 // Translate into window coordinates. 1266 // Translate into window coordinates.
1160 if (!intersection.IsEmpty()) { 1267 if (!intersection.IsEmpty()) {
1161 intersection.Offset(-preview_bounds.origin().x(), 1268 intersection.Offset(-preview_bounds.origin().x(),
1162 -preview_bounds.origin().y()); 1269 -preview_bounds.origin().y());
1163 } 1270 }
1164 1271
1165 // In the current Chrome UI, these must always be true so they sanity check 1272 // In the current Chrome UI, these must always be true so they sanity check
1166 // the above operations. In a future UI, these may be removed or adjusted. 1273 // the above operations. In a future UI, these may be removed or adjusted.
1167 // There is no point in sanity-checking |intersection.y()| because the omnibox 1274 // There is no point in sanity-checking |intersection.y()| because the omnibox
1168 // can be placed anywhere vertically relative to the preview (for example, in 1275 // can be placed anywhere vertically relative to the preview (for example, in
1169 // Mac fullscreen mode, the omnibox is fully enclosed by the preview bounds). 1276 // Mac fullscreen mode, the omnibox is fully enclosed by the preview bounds).
1170 DCHECK_LE(0, intersection.x()); 1277 DCHECK_LE(0, intersection.x());
1171 DCHECK_LE(0, intersection.width()); 1278 DCHECK_LE(0, intersection.width());
1172 DCHECK_LE(0, intersection.height()); 1279 DCHECK_LE(0, intersection.height());
1173 1280
1174 loader_->SetPopupBounds(intersection); 1281 overlay_->SetPopupBounds(intersection);
1175 } 1282 }
1176 1283
1177 bool InstantController::GetInstantURL(const TemplateURL* template_url, 1284 bool InstantController::GetInstantURL(const TemplateURL* template_url,
1178 std::string* instant_url) const { 1285 std::string* instant_url) const {
1179 if (extended_enabled_ && use_local_preview_only_) { 1286 if (extended_enabled_ && use_local_preview_only_) {
1180 *instant_url = kLocalOmniboxPopupURL; 1287 *instant_url = kLocalOmniboxPopupURL;
1181 return true; 1288 return true;
1182 } 1289 }
1183 1290
1184 CommandLine* command_line = CommandLine::ForCurrentProcess(); 1291 CommandLine* command_line = CommandLine::ForCurrentProcess();
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
1236 std::map<std::string, int>::const_iterator iter = 1343 std::map<std::string, int>::const_iterator iter =
1237 blacklisted_urls_.find(*instant_url); 1344 blacklisted_urls_.find(*instant_url);
1238 if (iter != blacklisted_urls_.end() && 1345 if (iter != blacklisted_urls_.end() &&
1239 iter->second > kMaxInstantSupportFailures) { 1346 iter->second > kMaxInstantSupportFailures) {
1240 RecordEventHistogram(INSTANT_CONTROLLER_EVENT_URL_BLOCKED_BY_BLACKLIST); 1347 RecordEventHistogram(INSTANT_CONTROLLER_EVENT_URL_BLOCKED_BY_BLACKLIST);
1241 return false; 1348 return false;
1242 } 1349 }
1243 1350
1244 return true; 1351 return true;
1245 } 1352 }
1353
1354 void InstantController::AddToBlacklist(const std::string& url) {
1355 ++blacklisted_urls_[url];
1356 RecordEventHistogram(INSTANT_CONTROLLER_EVENT_URL_ADDED_TO_BLACKLIST);
1357 }
1358
1359 void InstantController::RemoveFromBlacklist(const std::string& url) {
1360 if (blacklisted_urls_.erase(url)) {
1361 RecordEventHistogram(INSTANT_CONTROLLER_EVENT_URL_REMOVED_FROM_BLACKLIST);
1362 }
1363 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698